1 ;; ----------------------------------------------------------------------
3 ;; ----------------------------------------------------------------------
5 ;; We make some attempt to provide real efficient shifting. One example is
6 ;; doing an 8-bit shift of a 16-bit value by moving a byte reg into the other
7 ;; reg and moving 0 into the former reg.
9 ;; We also try to achieve this in a uniform way. IE: We don't try to achieve
10 ;; this in both rtl and at insn emit time. Ideally, we'd use rtl as that would
11 ;; give the optimizer more cracks at the code. However, we wish to do things
12 ;; like optimizing shifting the sign bit to bit 0 by rotating the other way.
13 ;; There is rtl to handle this (rotate + and), but the H8/300 doesn't handle
14 ;; 16-bit rotates. Also, if we emit complicated rtl, combine may not be able
15 ;; to detect cases it can optimize.
17 ;; For these and other fuzzy reasons, I've decided to go the less pretty but
18 ;; easier "do it at insn emit time" route.
21 (define_expand "ashl<mode>3"
22 [(set (match_operand:QHSI 0 "register_operand" "")
23 (ashift:QHSI (match_operand:QHSI 1 "register_operand" "")
24 (match_operand:QI 2 "nonmemory_operand" "")))]
27 if (expand_a_shift (<MODE>mode, ASHIFT, operands))
31 (define_expand "ashr<mode>3"
32 [(set (match_operand:QHSI 0 "register_operand" "")
33 (ashiftrt:QHSI (match_operand:QHSI 1 "register_operand" "")
34 (match_operand:QI 2 "nonmemory_operand" "")))]
37 if (expand_a_shift (<MODE>mode, ASHIFTRT, operands))
41 (define_expand "lshr<mode>3"
42 [(set (match_operand:QHSI 0 "register_operand" "")
43 (lshiftrt:QHSI (match_operand:QHSI 1 "register_operand" "")
44 (match_operand:QI 2 "nonmemory_operand" "")))]
47 if (expand_a_shift (<MODE>mode, LSHIFTRT, operands))
51 ;; QI/HI/SI BIT SHIFTS
53 (define_insn_and_split ""
54 [(set (match_operand:QHSI 0 "h8300_dst_operand" "=rQ")
55 (match_operator:QHSI 3 "h8sx_unary_shift_operator"
56 [(match_operand:QHSI 1 "h8300_dst_operand" "0")
57 (match_operand:QI 2 "const_int_operand" "")]))]
58 "h8300_operands_match_p (operands)"
61 [(parallel [(set (match_dup 0) (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
62 (clobber (reg:CC CC_REG))])])
65 [(set (match_operand:QHSI 0 "h8300_dst_operand" "=rQ")
66 (match_operator:QHSI 3 "h8sx_unary_shift_operator"
67 [(match_operand:QHSI 1 "h8300_dst_operand" "0")
68 (match_operand:QI 2 "const_int_operand" "")]))
69 (clobber (reg:CC CC_REG))]
70 "h8300_operands_match_p (operands)"
72 if (<MODE>mode == E_QImode)
73 return output_h8sx_shift (operands, 'b', 'X');
74 if (<MODE>mode == E_HImode)
75 return output_h8sx_shift (operands, 'w', 'T');
76 if (<MODE>mode == E_SImode)
77 return output_h8sx_shift (operands, 'l', 'S');
80 [(set_attr "length_table" "unary")])
83 [(set (reg:CCZN CC_REG)
85 (match_operator:QHSI 3 "h8sx_unary_shift_operator"
86 [(match_operand:QHSI 1 "h8300_dst_operand" "0")
87 (match_operand:QI 2 "const_int_operand" "")])
89 (set (match_operand:QHSI 0 "h8300_dst_operand" "=rQ")
90 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))]
91 "h8300_operands_match_p (operands)"
93 if (<MODE>mode == E_QImode)
94 return output_h8sx_shift (operands, 'b', 'X');
95 if (<MODE>mode == E_HImode)
96 return output_h8sx_shift (operands, 'w', 'T');
97 if (<MODE>mode == E_SImode)
98 return output_h8sx_shift (operands, 'l', 'S');
101 [(set_attr "length_table" "unary")])
103 (define_insn_and_split ""
104 [(set (match_operand:QHSI 0 "register_operand" "=r")
105 (match_operator:QHSI 3 "h8sx_binary_shift_operator"
106 [(match_operand:QHSI 1 "register_operand" "0")
107 (match_operand:QI 2 "nonmemory_operand" "r P5>X")]))]
110 "&& reload_completed"
111 [(parallel [(set (match_dup 0) (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
112 (clobber (reg:CC CC_REG))])])
115 [(set (match_operand:QHSI 0 "register_operand" "=r")
116 (match_operator:QHSI 3 "h8sx_binary_shift_operator"
117 [(match_operand:QHSI 1 "register_operand" "0")
118 (match_operand:QI 2 "nonmemory_operand" "r P5>X")]))
119 (clobber (reg:CC CC_REG))]
122 if (<MODE>mode == QImode)
123 return output_h8sx_shift (operands, 'b', 'X');
124 if (<MODE>mode == HImode)
125 return output_h8sx_shift (operands, 'w', 'T');
126 if (<MODE>mode == SImode)
127 return output_h8sx_shift (operands, 'l', 'S');
130 [(set_attr "length" "4")])
133 [(set (reg:CCZN CC_REG)
135 (match_operator:QHSI 3 "h8sx_binary_shift_operator"
136 [(match_operand:QHSI 1 "register_operand" "0")
137 (match_operand:QI 2 "nonmemory_operand" "r P5>X")])
139 (set (match_operand:QHSI 0 "register_operand" "=r")
140 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))]
143 if (<MODE>mode == QImode)
144 return output_h8sx_shift (operands, 'b', 'X');
145 if (<MODE>mode == HImode)
146 return output_h8sx_shift (operands, 'w', 'T');
147 if (<MODE>mode == SImode)
148 return output_h8sx_shift (operands, 'l', 'S');
151 [(set_attr "length" "4")])
153 (define_insn_and_split "*shiftqi_noscratch"
154 [(set (match_operand:QI 0 "register_operand" "=r,r")
156 (match_operand:QI 1 "register_operand" "0,0")
157 (match_operand:QI 2 "nonmemory_operand" "R,rn")))]
158 "(GET_CODE (operands[2]) == CONST_INT
159 && !h8300_shift_needs_scratch_p (INTVAL (operands[2]), QImode,
162 "&& reload_completed"
163 [(parallel [(set (match_dup 0) (shifts:QI (match_dup 1) (match_dup 2)))
164 (clobber (reg:CC CC_REG))])])
166 (define_insn "*shiftqi_noscratch_clobber_flags"
167 [(set (match_operand:QI 0 "register_operand" "=r,r")
169 (match_operand:QI 1 "register_operand" "0,0")
170 (match_operand:QI 2 "nonmemory_operand" "R,rn")))
171 (clobber (reg:CC CC_REG))]
172 "(GET_CODE (operands[2]) == CONST_INT
173 && !h8300_shift_needs_scratch_p (INTVAL (operands[2]), QImode, <CODE>))"
175 return output_a_shift (operands, <CODE>);
177 [(set (attr "length")
178 (symbol_ref "compute_a_shift_length (operands, <CODE>)"))])
180 (define_insn "*shiftqi_noscratch_set_flags"
181 [(set (reg:CCZN CC_REG)
184 (match_operand:QI 1 "register_operand" "0,0")
185 (match_operand:QI 2 "nonmemory_operand" "R,rn"))
187 (set (match_operand:QI 0 "register_operand" "=r,r")
188 (shifts:QI (match_dup 1) (match_dup 2)))]
189 "(GET_CODE (operands[2]) == CONST_INT
190 && !h8300_shift_needs_scratch_p (INTVAL (operands[2]), QImode, <CODE>)
191 && compute_a_shift_cc (operands, <CODE>))"
193 return output_a_shift (operands, <CODE>);
195 [(set (attr "length")
196 (symbol_ref "compute_a_shift_length (operands, <CODE>)"))])
199 (define_insn_and_split "*shiftqi"
200 [(set (match_operand:QI 0 "register_operand" "=r,r")
202 (match_operand:QI 1 "register_operand" "0,0")
203 (match_operand:QI 2 "nonmemory_operand" "R,rn")))
204 (clobber (match_scratch:QI 3 "=X,&r"))]
207 "&& reload_completed"
208 [(parallel [(set (match_dup 0) (shifts:QI (match_dup 1) (match_dup 2)))
209 (clobber (match_dup 3))
210 (clobber (reg:CC CC_REG))])])
212 (define_insn "*shiftqi_clobber_flags"
213 [(set (match_operand:QI 0 "register_operand" "=r,r")
215 (match_operand:QI 1 "register_operand" "0,0")
216 (match_operand:QI 2 "nonmemory_operand" "R,rn")))
217 (clobber (match_scratch:QI 3 "=X,&r"))
218 (clobber (reg:CC CC_REG))]
221 return output_a_shift (operands, <CODE>);
223 [(set (attr "length")
224 (symbol_ref "compute_a_shift_length (operands, <CODE>)"))])
226 (define_insn_and_split "*shifthi_noscratch"
227 [(set (match_operand:HI 0 "register_operand" "=r,r")
229 (match_operand:HI 1 "register_operand" "0,0")
230 (match_operand:HI 2 "nonmemory_operand" "S,rn")))]
231 "(GET_CODE (operands[2]) == CONST_INT
232 && !h8300_shift_needs_scratch_p (INTVAL (operands[2]), HImode, <CODE>))"
234 "&& reload_completed"
235 [(parallel [(set (match_dup 0) (shifts:HI (match_dup 1) (match_dup 2)))
236 (clobber (reg:CC CC_REG))])])
238 (define_insn "*shifthi_noscratch_clobber_flags"
239 [(set (match_operand:HI 0 "register_operand" "=r,r")
241 (match_operand:HI 1 "register_operand" "0,0")
242 (match_operand:HI 2 "nonmemory_operand" "S,rn")))
243 (clobber (reg:CC CC_REG))]
244 "(GET_CODE (operands[2]) == CONST_INT
245 && !h8300_shift_needs_scratch_p (INTVAL (operands[2]), HImode, <CODE>))"
247 return output_a_shift (operands, <CODE>);
249 [(set (attr "length")
250 (symbol_ref "compute_a_shift_length (operands, <CODE>)"))])
252 (define_insn "*shifthi_noscratch_setzn"
253 [(set (reg:CCZN CC_REG)
255 (shifts:HI (match_operand:HI 1 "register_operand" "0,0")
256 (match_operand:HI 2 "nonmemory_operand" "S,rn"))
258 (set (match_operand:HI 0 "register_operand" "=r,r")
259 (shifts:HI (match_dup 1) (match_dup 2)))]
260 "(GET_CODE (operands[2]) == CONST_INT
261 && !h8300_shift_needs_scratch_p (INTVAL (operands[2]), HImode, <CODE>)
262 && compute_a_shift_cc (operands, <CODE>))"
264 return output_a_shift (operands, <CODE>);
266 [(set (attr "length")
267 (symbol_ref "compute_a_shift_length (operands, <CODE>)"))])
269 (define_insn_and_split "*shifthi"
270 [(set (match_operand:HI 0 "register_operand" "=r,r")
272 (match_operand:HI 1 "register_operand" "0,0")
273 (match_operand:QI 2 "nonmemory_operand" "S,rn")))
274 (clobber (match_scratch:QI 3 "=X,&r"))]
277 "&& reload_completed"
278 [(parallel [(set (match_dup 0) (shifts:HI (match_dup 1) (match_dup 2)))
279 (clobber (match_dup 3))
280 (clobber (reg:CC CC_REG))])])
282 (define_insn "*shifthi_clobber_flags"
283 [(set (match_operand:HI 0 "register_operand" "=r,r")
285 (match_operand:HI 1 "register_operand" "0,0")
286 (match_operand:QI 2 "nonmemory_operand" "S,rn")))
287 (clobber (match_scratch:QI 3 "=X,&r"))
288 (clobber (reg:CC CC_REG))]
291 return output_a_shift (operands, <CODE>);
293 [(set (attr "length")
294 (symbol_ref "compute_a_shift_length (operands, <CODE>)"))])
296 (define_insn_and_split "*shiftsi_noscratch"
297 [(set (match_operand:SI 0 "register_operand" "=r,r")
299 (match_operand:SI 1 "register_operand" "0,0")
300 (match_operand:QI 2 "nonmemory_operand" "T,rn")))]
301 "(GET_CODE (operands[2]) == CONST_INT
302 && !h8300_shift_needs_scratch_p (INTVAL (operands[2]), SImode, <CODE>))"
304 "&& reload_completed"
305 [(parallel [(set (match_dup 0) (shifts:SI (match_dup 1) (match_dup 2)))
306 (clobber (reg:CC CC_REG))])])
308 (define_insn "*shiftsi_noscratch_clobber_flags"
309 [(set (match_operand:SI 0 "register_operand" "=r,r")
311 (match_operand:SI 1 "register_operand" "0,0")
312 (match_operand:SI 2 "nonmemory_operand" "T,rn")))
313 (clobber (reg:CC CC_REG))]
314 "(GET_CODE (operands[2]) == CONST_INT
315 && !h8300_shift_needs_scratch_p (INTVAL (operands[2]), SImode, <CODE>))"
317 return output_a_shift (operands, <CODE>);
319 [(set (attr "length")
320 (symbol_ref "compute_a_shift_length (operands, <CODE>)"))])
322 (define_insn "*shiftsi_noscratch_cczn"
323 [(set (reg:CCZN CC_REG)
326 (match_operand:SI 1 "register_operand" "0,0")
327 (match_operand:SI 2 "nonmemory_operand" "T,rn"))
329 (set (match_operand:SI 0 "register_operand" "=r,r")
330 (shifts:SI (match_dup 1) (match_dup 2)))]
331 "(GET_CODE (operands[2]) == CONST_INT
332 && !h8300_shift_needs_scratch_p (INTVAL (operands[2]), SImode, <CODE>)
333 && compute_a_shift_cc (operands, <CODE>))"
335 return output_a_shift (operands, <CODE>);
337 [(set (attr "length")
338 (symbol_ref "compute_a_shift_length (operands, <CODE>)"))])
340 ;; Split a variable shift into a loop. If the register containing
341 ;; the shift count dies, then we just use that register.
344 (define_insn_and_split "*shiftsi"
345 [(set (match_operand:SI 0 "register_operand" "=r,r")
347 (match_operand:SI 1 "register_operand" "0,0")
348 (match_operand:QI 2 "nonmemory_operand" "T,rn")))
349 (clobber (match_scratch:QI 3 "=X,&r"))]
352 "&& reload_completed"
353 [(parallel [(set (match_dup 0) (shifts:SI (match_dup 1) (match_dup 2)))
354 (clobber (match_dup 3))
355 (clobber (reg:CC CC_REG))])])
357 (define_insn "*shiftsi_clobber_flags"
358 [(set (match_operand:SI 0 "register_operand" "=r,r")
360 (match_operand:SI 1 "register_operand" "0,0")
361 (match_operand:QI 2 "nonmemory_operand" "T,rn")))
362 (clobber (match_scratch:QI 3 "=X,&r"))
363 (clobber (reg:CC CC_REG))]
366 return output_a_shift (operands, <CODE>);
368 [(set (attr "length")
369 (symbol_ref "compute_a_shift_length (operands, <CODE>)"))])
372 [(set (match_operand 0 "register_operand" "")
373 (match_operator 2 "nshift_operator"
375 (match_operand:QI 1 "register_operand" "")]))
376 (clobber (match_operand:QI 3 "register_operand" ""))
377 (clobber (reg:CC CC_REG))]
379 && find_regno_note (insn, REG_DEAD, REGNO (operands[1]))"
380 [(set (reg:CCZN CC_REG)
381 (compare:CCZN (match_dup 1) (const_int 0)))
383 (if_then_else (le (reg:CCZN CC_REG) (const_int 0))
384 (label_ref (match_dup 5))
389 (match_op_dup 2 [(match_dup 0) (const_int 1)]))
390 (clobber (reg:CC CC_REG))])
392 [(set (reg:CCZN CC_REG)
394 (plus:QI (match_dup 1) (const_int -1))
396 (set (match_dup 1) (plus:QI (match_dup 1) (const_int -1)))])
398 (if_then_else (ne (reg:CCZN CC_REG) (const_int 0))
399 (label_ref (match_dup 4))
403 operands[4] = gen_label_rtx ();
404 operands[5] = gen_label_rtx ();
408 [(set (match_operand 0 "register_operand" "")
409 (match_operator 2 "nshift_operator"
411 (match_operand:QI 1 "register_operand" "")]))
412 (clobber (match_operand:QI 3 "register_operand" ""))
413 (clobber (reg:CC CC_REG))]
415 && !find_regno_note (insn, REG_DEAD, REGNO (operands[1]))"
417 [(set (reg:CCZN CC_REG)
418 (compare:CCZN (match_dup 1) (const_int 0)))
419 (set (match_dup 3) (match_dup 1))])
421 (if_then_else (le (reg:CCZN CC_REG) (const_int 0))
422 (label_ref (match_dup 5))
427 (match_op_dup 2 [(match_dup 0) (const_int 1)]))
428 (clobber (reg:CC CC_REG))])
430 [(set (reg:CCZN CC_REG)
432 (plus:QI (match_dup 3) (const_int -1))
434 (set (match_dup 3) (plus:QI (match_dup 3) (const_int -1)))])
436 (if_then_else (ne (reg:CCZN CC_REG) (const_int 0))
437 (label_ref (match_dup 4))
441 operands[4] = gen_label_rtx ();
442 operands[5] = gen_label_rtx ();
446 [(set (match_operand:SI 0 "register_operand")
447 (match_operator:SI 3 "nshift_operator"
448 [(match_operand:SI 1 "register_operand")
449 (match_operand:QI 2 "nonmemory_operand")]))
450 (clobber (match_scratch:QI 4))]
452 [(parallel [(set (match_dup 0) (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
453 (clobber (match_dup 4))
454 (clobber (reg:CC CC_REG))])])
457 ;; ----------------------------------------------------------------------
459 ;; ----------------------------------------------------------------------
461 (define_expand "rotl<mode>3"
462 [(set (match_operand:QHSI 0 "register_operand" "")
463 (rotate:QHSI (match_operand:QHSI 1 "register_operand" "")
464 (match_operand:QI 2 "nonmemory_operand" "")))]
467 if (expand_a_rotate (operands))
471 (define_insn_and_split "rotl<mode>3_1"
472 [(set (match_operand:QHSI 0 "register_operand" "=r")
473 (rotate:QHSI (match_operand:QHSI 1 "register_operand" "0")
474 (match_operand:QI 2 "immediate_operand" "")))]
477 "&& reload_completed"
478 [(parallel [(set (match_dup 0) (rotate:QHSI (match_dup 1) (match_dup 2)))
479 (clobber (reg:CC CC_REG))])])
481 (define_insn "rotl<mode>3_1_clobber_flags"
482 [(set (match_operand:QHSI 0 "register_operand" "=r")
483 (rotate:QHSI (match_operand:QHSI 1 "register_operand" "0")
484 (match_operand:QI 2 "immediate_operand" "")))
485 (clobber (reg:CC CC_REG))]
488 return output_a_rotate (ROTATE, operands);
490 [(set (attr "length")
491 (symbol_ref "compute_a_rotate_length (operands)"))])