]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/config/h8300/h8300.md
constraints.md: Add "C" constraint for call insns.
[thirdparty/gcc.git] / gcc / config / h8300 / h8300.md
1 ;; GCC machine description for Renesas H8/300
2 ;; Copyright (C) 1992-2018 Free Software Foundation, Inc.
3
4 ;; Contributed by Steve Chamberlain (sac@cygnus.com),
5 ;; Jim Wilson (wilson@cygnus.com), and Doug Evans (dje@cygnus.com).
6
7 ;; This file is part of GCC.
8
9 ;; GCC is free software; you can redistribute it and/or modify
10 ;; it under the terms of the GNU General Public License as published by
11 ;; the Free Software Foundation; either version 3, or (at your option)
12 ;; any later version.
13
14 ;; GCC is distributed in the hope that it will be useful,
15 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
16 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 ;; GNU General Public License for more details.
18
19 ;; You should have received a copy of the GNU General Public License
20 ;; along with GCC; see the file COPYING3. If not see
21 ;; <http://www.gnu.org/licenses/>.
22
23 ;; We compute exact length on each instruction for most of the time.
24 ;; In some case, most notably bit operations that may involve memory
25 ;; operands, the lengths in this file are "worst case".
26
27 ;; On the H8/300H and H8S, adds/subs operate on the 32bit "er"
28 ;; registers. Right now GCC doesn't expose the "e" half to the
29 ;; compiler, so using add/subs for addhi and subhi is safe. Long
30 ;; term, we want to expose the "e" half to the compiler (gives us 8
31 ;; more 16bit registers). At that point addhi and subhi can't use
32 ;; adds/subs.
33
34 ;; There's currently no way to have an insv/extzv expander for the H8/300H
35 ;; because word_mode is different for the H8/300 and H8/300H.
36
37 ;; Shifts/rotates by small constants should be handled by special
38 ;; patterns so we get the length and cc status correct.
39
40 ;; Bitfield operations no longer accept memory operands. We need
41 ;; to add variants which operate on memory back to the MD.
42
43 ;; ??? Implement remaining bit ops available on the h8300
44
45 ;; ----------------------------------------------------------------------
46 ;; CONSTANTS
47 ;; ----------------------------------------------------------------------
48
49 (define_constants
50 [(UNSPEC_INCDEC 0)
51 (UNSPEC_MONITOR 1)])
52
53 (define_constants
54 [(UNSPEC_MOVMD 100)
55 (UNSPEC_STPCPY 101)])
56
57 (define_constants
58 [(R0_REG 0)
59 (SC_REG 3)
60 (COUNTER_REG 4)
61 (SOURCE_REG 5)
62 (DESTINATION_REG 6)
63 (HFP_REG 6)
64 (SP_REG 7)
65 (MAC_REG 8)
66 (AP_REG 9)
67 (RAP_REG 10)
68 (FP_REG 11)])
69
70 ;; ----------------------------------------------------------------------
71 ;; ATTRIBUTES
72 ;; ----------------------------------------------------------------------
73
74 (define_attr "cpu" "h8300,h8300h"
75 (const (symbol_ref "cpu_type")))
76
77 (define_attr "type" "branch,arith,bitbranch,call"
78 (const_string "arith"))
79
80 (define_attr "length_table" "none,add,logicb,movb,movw,movl,mova_zero,mova,unary,mov_imm4,short_immediate,bitfield,bitbranch"
81 (const_string "none"))
82
83 ;; The size of instructions in bytes.
84
85 (define_attr "length" ""
86 (cond [(eq_attr "type" "branch")
87 ;; In a forward delayed branch, (pc) represents the end of the
88 ;; delay sequence, not the end of the branch itself.
89 (if_then_else (and (ge (minus (match_dup 0) (pc))
90 (const_int -126))
91 (le (plus (minus (match_dup 0) (pc))
92 (symbol_ref "DELAY_SLOT_LENGTH (insn)"))
93 (const_int 125)))
94 (const_int 2)
95 (if_then_else (and (eq_attr "cpu" "h8300h")
96 (and (ge (minus (pc) (match_dup 0))
97 (const_int -32000))
98 (le (minus (pc) (match_dup 0))
99 (const_int 32000))))
100 (const_int 4)
101 (const_int 6)))
102 (eq_attr "type" "bitbranch")
103 (if_then_else (and (ge (minus (match_dup 0) (pc))
104 (const_int -126))
105 (le (minus (match_dup 0) (pc))
106 (const_int 126)))
107 (plus (symbol_ref "h8300_insn_length_from_table (insn, operands)")
108 (const_int 2))
109 (if_then_else (and (eq_attr "cpu" "h8300h")
110 (and (ge (minus (pc) (match_dup 0))
111 (const_int -32000))
112 (le (minus (pc) (match_dup 0))
113 (const_int 32000))))
114 (plus (symbol_ref "h8300_insn_length_from_table (insn, operands)")
115 (const_int 4))
116 (plus (symbol_ref "h8300_insn_length_from_table (insn, operands)")
117 (const_int 6))))
118 (eq_attr "length_table" "!none")
119 (symbol_ref "h8300_insn_length_from_table (insn, operands)")]
120 (const_int 200)))
121
122 ;; Condition code settings.
123 ;;
124 ;; none - insn does not affect cc
125 ;; none_0hit - insn does not affect cc but it does modify operand 0
126 ;; This attribute is used to keep track of when operand 0 changes.
127 ;; See the description of NOTICE_UPDATE_CC for more info.
128 ;; set_znv - insn sets z,n,v to usable values (like a tst insn); c is unknown.
129 ;; set_zn - insn sets z,n to usable values; v,c are unknown.
130 ;; compare - compare instruction
131 ;; clobber - value of cc is unknown
132
133 (define_attr "cc" "none,none_0hit,set_znv,set_zn,compare,clobber"
134 (const_string "clobber"))
135
136 ;; Type of delay slot. NONE means the instruction has no delay slot.
137 ;; JUMP means it is an unconditional jump that (if short enough)
138 ;; could be implemented using bra/s.
139
140 (define_attr "delay_slot" "none,jump"
141 (const_string "none"))
142
143 ;; "yes" if the instruction can be put into a delay slot. It's not
144 ;; entirely clear that jsr is not valid in delay slots, but it
145 ;; definitely doesn't have the effect of causing the called function
146 ;; to return to the target of the delayed branch.
147
148 (define_attr "can_delay" "no,yes"
149 (cond [(eq_attr "type" "branch,bitbranch,call")
150 (const_string "no")
151 (geu (symbol_ref "get_attr_length (insn)") (const_int 2))
152 (const_string "no")]
153 (const_string "yes")))
154
155 ;; Only allow jumps to have a delay slot if we think they might
156 ;; be short enough. This is just an optimization: we don't know
157 ;; for certain whether they will be or not.
158
159 (define_delay (and (eq_attr "delay_slot" "jump")
160 (eq (symbol_ref "get_attr_length (insn)") (const_int 2)))
161 [(eq_attr "can_delay" "yes")
162 (nil)
163 (nil)])
164
165 ;; Provide the maximum length of an assembly instruction in an asm
166 ;; statement. The maximum length of 14 bytes is achieved on H8SX.
167
168 (define_asm_attributes
169 [(set (attr "length")
170 (cond [(match_test "TARGET_H8300") (const_int 4)
171 (match_test "TARGET_H8300H") (const_int 10)
172 (match_test "TARGET_H8300S") (const_int 10)]
173 (const_int 14)))])
174
175 (include "predicates.md")
176 (include "constraints.md")
177 \f
178 ;; ----------------------------------------------------------------------
179 ;; MACRO DEFINITIONS
180 ;; ----------------------------------------------------------------------
181
182 ;; This mode iterator allows :P to be used for patterns that operate on
183 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
184
185 (define_mode_iterator P [(HI "Pmode == HImode") (SI "Pmode == SImode")])
186
187 (define_mode_iterator QHI [QI HI])
188
189 (define_mode_iterator HSI [HI SI])
190
191 (define_mode_iterator QHSI [QI HI SI])
192
193 (define_mode_iterator QHSIF [QI HI SI SF])
194
195 (define_code_iterator shifts [ashift ashiftrt lshiftrt])
196
197 (define_code_iterator ors [ior xor])
198 \f
199 ;; ----------------------------------------------------------------------
200 ;; MOVE INSTRUCTIONS
201 ;; ----------------------------------------------------------------------
202
203 ;; movqi
204
205 (define_insn "*movqi_h8nosx"
206 [(set (match_operand:QI 0 "general_operand_dst" "=r,r ,<,r,r,m")
207 (match_operand:QI 1 "general_operand_src" " I,r>,r,n,m,r"))]
208 "(TARGET_H8300 || TARGET_H8300H || TARGET_H8300S) && !TARGET_H8300SX
209 && h8300_move_ok (operands[0], operands[1])"
210 "@
211 sub.b %X0,%X0
212 mov.b %R1,%X0
213 mov.b %X1,%R0
214 mov.b %R1,%X0
215 mov.b %R1,%X0
216 mov.b %X1,%R0"
217 [(set (attr "length")
218 (symbol_ref "compute_mov_length (operands)"))
219 (set_attr "cc" "set_zn,set_znv,set_znv,set_znv,set_znv,set_znv")])
220
221 (define_insn "*movqi_h8sx"
222 [(set (match_operand:QI 0 "general_operand_dst" "=Z,rQ")
223 (match_operand:QI 1 "general_operand_src" "P4>X,rQi"))]
224 "TARGET_H8300SX"
225 "@
226 mov.b %X1:4,%X0
227 mov.b %X1,%X0"
228 [(set_attr "length_table" "mov_imm4,movb")
229 (set_attr "cc" "set_znv")])
230
231 (define_expand "mov<mode>"
232 [(set (match_operand:QHSIF 0 "general_operand_dst" "")
233 (match_operand:QHSIF 1 "general_operand_src" ""))]
234 ""
235 {
236 enum machine_mode mode = <MODE>mode;
237 if (TARGET_H8300 && (mode == SImode || mode == SFmode))
238 {
239 /* The original H8/300 needs to split up 32 bit moves. */
240 if (h8300_expand_movsi (operands))
241 DONE;
242 }
243 else if (!TARGET_H8300SX)
244 {
245 /* Other H8 chips, except the H8/SX family can only handle a
246 single memory operand, which is checked by h8300_move_ok.
247
248 We could perhaps have h8300_move_ok handle the H8/SX better
249 and just remove the !TARGET_H8300SX conditional. */
250 if (!h8300_move_ok (operands[0], operands[1]))
251 operands[1] = copy_to_mode_reg (mode, operand1);
252 }
253 })
254
255 (define_insn "movstrictqi"
256 [(set (strict_low_part (match_operand:QI 0 "general_operand_dst" "+r,r"))
257 (match_operand:QI 1 "general_operand_src" "I,rmi>"))]
258 ""
259 "@
260 sub.b %X0,%X0
261 mov.b %X1,%X0"
262 [(set_attr "length" "2,*")
263 (set_attr "length_table" "*,movb")
264 (set_attr "cc" "set_zn,set_znv")])
265
266 ;; movhi
267
268 (define_insn "*movhi_h8nosx"
269 [(set (match_operand:HI 0 "general_operand_dst" "=r,r,<,r,r,m")
270 (match_operand:HI 1 "general_operand_src" "I,r>,r,i,m,r"))]
271 "(TARGET_H8300 || TARGET_H8300H || TARGET_H8300S) && !TARGET_H8300SX
272 && h8300_move_ok (operands[0], operands[1])"
273 "@
274 sub.w %T0,%T0
275 mov.w %T1,%T0
276 mov.w %T1,%T0
277 mov.w %T1,%T0
278 mov.w %T1,%T0
279 mov.w %T1,%T0"
280 [(set (attr "length")
281 (symbol_ref "compute_mov_length (operands)"))
282 (set_attr "cc" "set_zn,set_znv,set_znv,set_znv,set_znv,set_znv")])
283
284 (define_insn "*movhi_h8sx"
285 [(set (match_operand:HI 0 "general_operand_dst" "=r,r,Z,Q,rQ")
286 (match_operand:HI 1 "general_operand_src" "I,P3>X,P4>X,IP8>X,rQi"))]
287 "TARGET_H8300SX"
288 "@
289 sub.w %T0,%T0
290 mov.w %T1:3,%T0
291 mov.w %T1:4,%T0
292 mov.w %T1,%T0
293 mov.w %T1,%T0"
294 [(set_attr "length_table" "*,*,mov_imm4,short_immediate,movw")
295 (set_attr "length" "2,2,*,*,*")
296 (set_attr "cc" "set_zn,set_znv,set_znv,set_znv,set_znv")])
297
298 (define_insn "movstricthi"
299 [(set (strict_low_part (match_operand:HI 0 "general_operand_dst" "+r,r,r"))
300 (match_operand:HI 1 "general_operand_src" "I,P3>X,rmi"))]
301 ""
302 "@
303 sub.w %T0,%T0
304 mov.w %T1,%T0
305 mov.w %T1,%T0"
306 [(set_attr "length" "2,2,*")
307 (set_attr "length_table" "*,*,movw")
308 (set_attr "cc" "set_zn,set_znv,set_znv")])
309
310 ;; movsi
311
312 (define_insn "*movsi_h8300"
313 [(set (match_operand:SI 0 "general_operand_dst" "=r,r,r,o,<,r")
314 (match_operand:SI 1 "general_operand_src" "I,r,io,r,r,>"))]
315 "TARGET_H8300
316 && h8300_move_ok (operands[0], operands[1])"
317 {
318 unsigned int rn = -1;
319 switch (which_alternative)
320 {
321 case 0:
322 return "sub.w %e0,%e0\;sub.w %f0,%f0";
323 case 1:
324 if (REGNO (operands[0]) < REGNO (operands[1]))
325 return "mov.w %e1,%e0\;mov.w %f1,%f0";
326 else
327 return "mov.w %f1,%f0\;mov.w %e1,%e0";
328 case 2:
329 /* Make sure we don't trample the register we index with. */
330 if (GET_CODE (operands[1]) == MEM)
331 {
332 rtx inside = XEXP (operands[1], 0);
333 if (REG_P (inside))
334 {
335 rn = REGNO (inside);
336 }
337 else if (GET_CODE (inside) == PLUS)
338 {
339 rtx lhs = XEXP (inside, 0);
340 rtx rhs = XEXP (inside, 1);
341 if (REG_P (lhs)) rn = REGNO (lhs);
342 if (REG_P (rhs)) rn = REGNO (rhs);
343 }
344 }
345 if (rn == REGNO (operands[0]))
346 {
347 /* Move the second word first. */
348 return "mov.w %f1,%f0\;mov.w %e1,%e0";
349 }
350 else
351 {
352 if (GET_CODE (operands[1]) == CONST_INT)
353 {
354 /* If either half is zero, use sub.w to clear that
355 half. */
356 if ((INTVAL (operands[1]) & 0xffff) == 0)
357 return "mov.w %e1,%e0\;sub.w %f0,%f0";
358 if (((INTVAL (operands[1]) >> 16) & 0xffff) == 0)
359 return "sub.w %e0,%e0\;mov.w %f1,%f0";
360 /* If the upper half and the lower half are the same,
361 copy one half to the other. */
362 if ((INTVAL (operands[1]) & 0xffff)
363 == ((INTVAL (operands[1]) >> 16) & 0xffff))
364 return "mov.w\\t%e1,%e0\;mov.w\\t%e0,%f0";
365 }
366 return "mov.w %e1,%e0\;mov.w %f1,%f0";
367 }
368 case 3:
369 return "mov.w %e1,%e0\;mov.w %f1,%f0";
370 case 4:
371 return "mov.w %f1,%T0\;mov.w %e1,%T0";
372 case 5:
373 return "mov.w %T1,%e0\;mov.w %T1,%f0";
374 default:
375 gcc_unreachable ();
376 }
377 }
378 [(set (attr "length")
379 (symbol_ref "compute_mov_length (operands)"))])
380
381 (define_insn "*movsi_h8300hs"
382 [(set (match_operand:SI 0 "general_operand_dst" "=r,r,r,<,r,r,m,*a,*a,r")
383 (match_operand:SI 1 "general_operand_src" "I,r,i,r,>,m,r,I,r,*a"))]
384 "(TARGET_H8300S || TARGET_H8300H) && !TARGET_H8300SX
385 && h8300_move_ok (operands[0], operands[1])"
386 {
387 switch (which_alternative)
388 {
389 case 0:
390 return "sub.l %S0,%S0";
391 case 7:
392 return "clrmac";
393 case 8:
394 return "clrmac\;ldmac %1,macl";
395 case 9:
396 return "stmac macl,%0";
397 default:
398 if (GET_CODE (operands[1]) == CONST_INT)
399 {
400 int val = INTVAL (operands[1]);
401
402 /* Look for constants which can be made by adding an 8-bit
403 number to zero in one of the two low bytes. */
404 if (val == (val & 0xff))
405 {
406 operands[1] = GEN_INT ((char) val & 0xff);
407 return "sub.l\\t%S0,%S0\;add.b\\t%1,%w0";
408 }
409
410 if (val == (val & 0xff00))
411 {
412 operands[1] = GEN_INT ((char) (val >> 8) & 0xff);
413 return "sub.l\\t%S0,%S0\;add.b\\t%1,%x0";
414 }
415
416 /* Look for constants that can be obtained by subs, inc, and
417 dec to 0. */
418 switch (val & 0xffffffff)
419 {
420 case 0xffffffff:
421 return "sub.l\\t%S0,%S0\;subs\\t#1,%S0";
422 case 0xfffffffe:
423 return "sub.l\\t%S0,%S0\;subs\\t#2,%S0";
424 case 0xfffffffc:
425 return "sub.l\\t%S0,%S0\;subs\\t#4,%S0";
426
427 case 0x0000ffff:
428 return "sub.l\\t%S0,%S0\;dec.w\\t#1,%f0";
429 case 0x0000fffe:
430 return "sub.l\\t%S0,%S0\;dec.w\\t#2,%f0";
431
432 case 0xffff0000:
433 return "sub.l\\t%S0,%S0\;dec.w\\t#1,%e0";
434 case 0xfffe0000:
435 return "sub.l\\t%S0,%S0\;dec.w\\t#2,%e0";
436
437 case 0x00010000:
438 return "sub.l\\t%S0,%S0\;inc.w\\t#1,%e0";
439 case 0x00020000:
440 return "sub.l\\t%S0,%S0\;inc.w\\t#2,%e0";
441 }
442 }
443 }
444 return "mov.l %S1,%S0";
445 }
446 [(set (attr "length")
447 (symbol_ref "compute_mov_length (operands)"))
448 (set_attr "cc" "set_zn,set_znv,clobber,set_znv,set_znv,set_znv,set_znv,none_0hit,none_0hit,set_znv")])
449
450 (define_insn "*movsi_h8sx"
451 [(set (match_operand:SI 0 "general_operand_dst" "=r,r,Q,rQ,*a,*a,r")
452 (match_operand:SI 1 "general_operand_src" "I,P3>X,IP8>X,rQi,I,r,*a"))]
453 "TARGET_H8300SX"
454 "@
455 sub.l %S0,%S0
456 mov.l %S1:3,%S0
457 mov.l %S1,%S0
458 mov.l %S1,%S0
459 clrmac
460 clrmac\;ldmac %1,macl
461 stmac macl,%0"
462 [(set_attr "length_table" "*,*,short_immediate,movl,*,*,*")
463 (set_attr "length" "2,2,*,*,2,6,4")
464 (set_attr "cc" "set_zn,set_znv,set_znv,set_znv,none_0hit,none_0hit,set_znv")])
465
466 (define_insn "*movsf_h8sx"
467 [(set (match_operand:SF 0 "general_operand_dst" "=r,rQ")
468 (match_operand:SF 1 "general_operand_src" "G,rQi"))]
469 "TARGET_H8300SX"
470 "@
471 sub.l %S0,%S0
472 mov.l %S1,%S0"
473 [(set_attr "length" "2,*")
474 (set_attr "length_table" "*,movl")
475 (set_attr "cc" "set_zn,set_znv")])
476
477 ;; Implement block moves using movmd. Defining movmemsi allows the full
478 ;; range of constant lengths (up to 0x40000 bytes when using movmd.l).
479 ;; See h8sx_emit_movmd for details.
480
481 (define_expand "movmemsi"
482 [(use (match_operand:BLK 0 "memory_operand" ""))
483 (use (match_operand:BLK 1 "memory_operand" ""))
484 (use (match_operand:SI 2 "" ""))
485 (use (match_operand:SI 3 "const_int_operand" ""))]
486 "TARGET_H8300SX"
487 {
488 if (h8sx_emit_movmd (operands[0], operands[1], operands[2], INTVAL (operands[3])))
489 DONE;
490 else
491 FAIL;
492 })
493
494 ;; Expander for generating movmd insns. Operand 0 is the destination
495 ;; memory region, operand 1 is the source, operand 2 is the counter
496 ;; register and operand 3 is the chunk size (1, 2 or 4).
497
498 (define_expand "movmd"
499 [(parallel
500 [(set (match_operand:BLK 0 "memory_operand" "")
501 (match_operand:BLK 1 "memory_operand" ""))
502 (unspec [(match_operand:HI 2 "register_operand" "")
503 (match_operand:HI 3 "const_int_operand" "")] UNSPEC_MOVMD)
504 (clobber (match_dup 4))
505 (clobber (match_dup 5))
506 (set (match_dup 2)
507 (const_int 0))])]
508 "TARGET_H8300SX"
509 {
510 operands[4] = copy_rtx (XEXP (operands[0], 0));
511 operands[5] = copy_rtx (XEXP (operands[1], 0));
512 })
513
514 ;; This is a difficult instruction to reload since operand 0 must be the
515 ;; frame pointer. See h8300_reg_class_from_letter for an explanation.
516
517 (define_insn "movmd_internal_<mode>"
518 [(set (mem:BLK (match_operand:P 3 "register_operand" "0,r"))
519 (mem:BLK (match_operand:P 4 "register_operand" "1,1")))
520 (unspec [(match_operand:HI 5 "register_operand" "2,2")
521 (match_operand:HI 6 "const_int_operand" "n,n")] UNSPEC_MOVMD)
522 (clobber (match_operand:P 0 "register_operand" "=d,??D"))
523 (clobber (match_operand:P 1 "register_operand" "=f,f"))
524 (set (match_operand:HI 2 "register_operand" "=c,c")
525 (const_int 0))]
526 "TARGET_H8300SX"
527 "@
528 movmd%m6
529 #"
530 [(set_attr "length" "2,14")
531 (set_attr "can_delay" "no")
532 (set_attr "cc" "none,clobber")])
533
534 ;; Split the above instruction if the destination register isn't er6.
535 ;; We need a sequence like:
536 ;;
537 ;; mov.l er6,@-er7
538 ;; mov.l <dest>,er6
539 ;; movmd.sz
540 ;; mov.l er6,<dest>
541 ;; mov.l @er7+,er6
542 ;;
543 ;; where <dest> is the current destination register (operand 4).
544 ;; The fourth instruction will be deleted if <dest> dies here.
545
546 (define_split
547 [(set (match_operand:BLK 0 "memory_operand" "")
548 (match_operand:BLK 1 "memory_operand" ""))
549 (unspec [(match_operand:HI 2 "register_operand" "")
550 (match_operand:HI 3 "const_int_operand" "")] UNSPEC_MOVMD)
551 (clobber (match_operand:P 4 "register_operand" ""))
552 (clobber (match_operand:P 5 "register_operand" ""))
553 (set (match_dup 2)
554 (const_int 0))]
555 "TARGET_H8300SX && reload_completed
556 && REGNO (operands[4]) != DESTINATION_REG"
557 [(const_int 0)]
558 {
559 rtx dest;
560
561 h8300_swap_into_er6 (XEXP (operands[0], 0));
562 dest = replace_equiv_address (operands[0], hard_frame_pointer_rtx);
563 emit_insn (gen_movmd (dest, operands[1], operands[2], operands[3]));
564 h8300_swap_out_of_er6 (operands[4]);
565 DONE;
566 })
567
568 ;; Expand a call to stpcpy() using movsd. Operand 0 should point to
569 ;; the final character, but movsd leaves it pointing to the character
570 ;; after that.
571
572 (define_expand "movstr"
573 [(use (match_operand 0 "register_operand" ""))
574 (use (match_operand:BLK 1 "memory_operand" ""))
575 (use (match_operand:BLK 2 "memory_operand" ""))]
576 "TARGET_H8300SX"
577 {
578 operands[1] = replace_equiv_address
579 (operands[1], copy_to_mode_reg (Pmode, XEXP (operands[1], 0)));
580 operands[2] = replace_equiv_address
581 (operands[2], copy_to_mode_reg (Pmode, XEXP (operands[2], 0)));
582 emit_insn (gen_movsd (operands[1], operands[2], gen_reg_rtx (Pmode)));
583 emit_insn (gen_add3_insn (operands[0], XEXP (operands[1], 0), constm1_rtx));
584 DONE;
585 })
586
587 ;; Expander for generating a movsd instruction. Operand 0 is the
588 ;; destination string, operand 1 is the source string and operand 2
589 ;; is a scratch register.
590
591 (define_expand "movsd"
592 [(parallel
593 [(set (match_operand:BLK 0 "memory_operand" "")
594 (unspec:BLK [(match_operand:BLK 1 "memory_operand" "")]
595 UNSPEC_STPCPY))
596 (clobber (match_dup 3))
597 (clobber (match_dup 4))
598 (clobber (match_operand 2 "register_operand" ""))])]
599 "TARGET_H8300SX"
600 {
601 operands[3] = copy_rtx (XEXP (operands[0], 0));
602 operands[4] = copy_rtx (XEXP (operands[1], 0));
603 })
604
605 ;; See comments above memcpy_internal().
606
607 (define_insn "stpcpy_internal_<mode>"
608 [(set (mem:BLK (match_operand:P 3 "register_operand" "0,r"))
609 (unspec:BLK [(mem:BLK (match_operand:P 4 "register_operand" "1,1"))]
610 UNSPEC_STPCPY))
611 (clobber (match_operand:P 0 "register_operand" "=d,??D"))
612 (clobber (match_operand:P 1 "register_operand" "=f,f"))
613 (clobber (match_operand:P 2 "register_operand" "=c,c"))]
614 "TARGET_H8300SX"
615 "@
616 \n1:\tmovsd\t2f\;bra\t1b\n2:
617 #"
618 [(set_attr "length" "6,18")
619 (set_attr "cc" "none,clobber")])
620
621 ;; Split the above instruction if the destination isn't er6. This works
622 ;; in the same way as the movmd splitter.
623
624 (define_split
625 [(set (match_operand:BLK 0 "memory_operand" "")
626 (unspec:BLK [(match_operand:BLK 1 "memory_operand" "")] UNSPEC_STPCPY))
627 (clobber (match_operand:P 2 "register_operand" ""))
628 (clobber (match_operand:P 3 "register_operand" ""))
629 (clobber (match_operand:P 4 "register_operand" ""))]
630 "TARGET_H8300SX && reload_completed
631 && REGNO (operands[2]) != DESTINATION_REG"
632 [(const_int 0)]
633 {
634 rtx dest;
635
636 h8300_swap_into_er6 (XEXP (operands[0], 0));
637 dest = replace_equiv_address (operands[0], hard_frame_pointer_rtx);
638 emit_insn (gen_movsd (dest, operands[1], operands[4]));
639 h8300_swap_out_of_er6 (operands[2]);
640 DONE;
641 })
642
643 (include "mova.md")
644
645 (define_insn "*movsf_h8300"
646 [(set (match_operand:SF 0 "general_operand_dst" "=r,r,r,o,<,r")
647 (match_operand:SF 1 "general_operand_src" "G,r,io,r,r,>"))]
648 "TARGET_H8300
649 && (register_operand (operands[0], SFmode)
650 || register_operand (operands[1], SFmode))"
651 {
652 /* Copy of the movsi stuff. */
653 unsigned int rn = -1;
654 switch (which_alternative)
655 {
656 case 0:
657 return "sub.w %e0,%e0\;sub.w %f0,%f0";
658 case 1:
659 if (REGNO (operands[0]) < REGNO (operands[1]))
660 return "mov.w %e1,%e0\;mov.w %f1,%f0";
661 else
662 return "mov.w %f1,%f0\;mov.w %e1,%e0";
663 case 2:
664 /* Make sure we don't trample the register we index with. */
665 if (GET_CODE (operands[1]) == MEM)
666 {
667 rtx inside = XEXP (operands[1], 0);
668 if (REG_P (inside))
669 {
670 rn = REGNO (inside);
671 }
672 else if (GET_CODE (inside) == PLUS)
673 {
674 rtx lhs = XEXP (inside, 0);
675 rtx rhs = XEXP (inside, 1);
676 if (REG_P (lhs)) rn = REGNO (lhs);
677 if (REG_P (rhs)) rn = REGNO (rhs);
678 }
679 }
680 if (rn == REGNO (operands[0]))
681 /* Move the second word first. */
682 return "mov.w %f1,%f0\;mov.w %e1,%e0";
683 else
684 /* Move the first word first. */
685 return "mov.w %e1,%e0\;mov.w %f1,%f0";
686
687 case 3:
688 return "mov.w %e1,%e0\;mov.w %f1,%f0";
689 case 4:
690 return "mov.w %f1,%T0\;mov.w %e1,%T0";
691 case 5:
692 return "mov.w %T1,%e0\;mov.w %T1,%f0";
693 default:
694 gcc_unreachable ();
695 }
696 }
697 [(set (attr "length")
698 (symbol_ref "compute_mov_length (operands)"))])
699
700 (define_insn "*movsf_h8300hs"
701 [(set (match_operand:SF 0 "general_operand_dst" "=r,r,r,m,<,r")
702 (match_operand:SF 1 "general_operand_src" "G,r,im,r,r,>"))]
703 "(TARGET_H8300H || TARGET_H8300S) && !TARGET_H8300SX
704 && (register_operand (operands[0], SFmode)
705 || register_operand (operands[1], SFmode))"
706 "@
707 sub.l %S0,%S0
708 mov.l %S1,%S0
709 mov.l %S1,%S0
710 mov.l %S1,%S0
711 mov.l %S1,%S0
712 mov.l %S1,%S0"
713 [(set (attr "length")
714 (symbol_ref "compute_mov_length (operands)"))
715 (set_attr "cc" "set_zn,set_znv,set_znv,set_znv,set_znv,set_znv")])
716 \f
717 ;; ----------------------------------------------------------------------
718 ;; PUSH INSTRUCTIONS
719 ;; ----------------------------------------------------------------------
720
721 (define_insn "*pushqi1_h8300"
722 [(set (mem:QI
723 (pre_modify:HI
724 (reg:HI SP_REG)
725 (plus:HI (reg:HI SP_REG) (const_int -2))))
726 (match_operand:QI 0 "register_no_sp_elim_operand" "r"))]
727 "TARGET_H8300"
728 "mov.w\\t%T0,@-r7"
729 [(set_attr "length" "2")])
730
731 (define_insn "*push1_h8300hs_<mode>"
732 [(set (mem:QHI
733 (pre_modify:P
734 (reg:P SP_REG)
735 (plus:P (reg:P SP_REG) (const_int -4))))
736 (match_operand:QHI 0 "register_no_sp_elim_operand" "r"))]
737 "TARGET_H8300H || TARGET_H8300S"
738 "mov.l\\t%S0,@-er7"
739 [(set_attr "length" "4")])
740
741 \f
742 ;; ----------------------------------------------------------------------
743 ;; TEST INSTRUCTIONS
744 ;; ----------------------------------------------------------------------
745
746 (define_insn ""
747 [(set (cc0)
748 (compare (zero_extract:QI (match_operand:QI 0 "bit_memory_operand" "r,U")
749 (const_int 1)
750 (match_operand 1 "const_int_operand" "n,n"))
751 (const_int 0)))]
752 "TARGET_H8300"
753 "btst %Z1,%Y0"
754 [(set_attr "length" "2,4")
755 (set_attr "cc" "set_zn,set_zn")])
756
757 (define_insn_and_split "*tst_extzv_1_n"
758 [(set (cc0)
759 (compare (zero_extract:SI (match_operand:QI 0 "general_operand_src" "r,U,mn>")
760 (const_int 1)
761 (match_operand 1 "const_int_operand" "n,n,n"))
762 (const_int 0)))
763 (clobber (match_scratch:QI 2 "=X,X,&r"))]
764 "TARGET_H8300H || TARGET_H8300S"
765 "@
766 btst\\t%Z1,%Y0
767 btst\\t%Z1,%Y0
768 #"
769 "&& reload_completed
770 && !satisfies_constraint_U (operands[0])"
771 [(set (match_dup 2)
772 (match_dup 0))
773 (parallel [(set (cc0) (compare (zero_extract:SI (match_dup 2)
774 (const_int 1)
775 (match_dup 1))
776 (const_int 0)))
777 (clobber (scratch:QI))])]
778 ""
779 [(set_attr "length" "2,8,10")
780 (set_attr "cc" "set_zn,set_zn,set_zn")])
781
782 (define_insn ""
783 [(set (cc0)
784 (compare (zero_extract:HSI (match_operand:HSI 0 "register_operand" "r")
785 (const_int 1)
786 (match_operand 1 "const_int_operand" "n"))
787 (const_int 0)))]
788 "(TARGET_H8300 || TARGET_H8300H || TARGET_H8300S)
789 && INTVAL (operands[1]) <= 15"
790 "btst %Z1,%Y0"
791 [(set_attr "length" "2")
792 (set_attr "cc" "set_zn")])
793
794 (define_insn_and_split "*tstsi_upper_bit"
795 [(set (cc0)
796 (compare (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
797 (const_int 1)
798 (match_operand 1 "const_int_operand" "n"))
799 (const_int 0)))
800 (clobber (match_scratch:SI 2 "=&r"))]
801 "(TARGET_H8300H || TARGET_H8300S)
802 && INTVAL (operands[1]) >= 16"
803 "#"
804 "&& reload_completed"
805 [(set (match_dup 2)
806 (ior:SI (and:SI (match_dup 2)
807 (const_int -65536))
808 (lshiftrt:SI (match_dup 0)
809 (const_int 16))))
810 (set (cc0)
811 (compare (zero_extract:SI (match_dup 2)
812 (const_int 1)
813 (match_dup 3))
814 (const_int 0)))]
815 {
816 operands[3] = GEN_INT (INTVAL (operands[1]) - 16);
817 })
818
819 (define_insn "*tstsi_variable_bit"
820 [(set (cc0)
821 (compare (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
822 (const_int 1)
823 (and:SI (match_operand:SI 1 "register_operand" "r")
824 (const_int 7)))
825 (const_int 0)))]
826 "TARGET_H8300H || TARGET_H8300S"
827 "btst %w1,%w0"
828 [(set_attr "length" "2")
829 (set_attr "cc" "set_zn")])
830
831 (define_insn_and_split "*tstsi_variable_bit_qi"
832 [(set (cc0)
833 (compare (zero_extract:SI (zero_extend:SI (match_operand:QI 0 "general_operand_src" "r,U,mn>"))
834 (const_int 1)
835 (and:SI (match_operand:SI 1 "register_operand" "r,r,r")
836 (const_int 7)))
837 (const_int 0)))
838 (clobber (match_scratch:QI 2 "=X,X,&r"))]
839 "TARGET_H8300H || TARGET_H8300S"
840 "@
841 btst\\t%w1,%X0
842 btst\\t%w1,%X0
843 #"
844 "&& reload_completed
845 && !satisfies_constraint_U (operands[0])"
846 [(set (match_dup 2)
847 (match_dup 0))
848 (parallel [(set (cc0)
849 (compare (zero_extract:SI (zero_extend:SI (match_dup 2))
850 (const_int 1)
851 (and:SI (match_dup 1)
852 (const_int 7)))
853 (const_int 0)))
854 (clobber (scratch:QI))])]
855 ""
856 [(set_attr "length" "2,8,10")
857 (set_attr "cc" "set_zn,set_zn,set_zn")])
858
859 (define_insn "*tst<mode>"
860 [(set (cc0)
861 (compare (match_operand:QHI 0 "register_operand" "r")
862 (const_int 0)))]
863 ""
864 {
865 if (<MODE>mode == QImode)
866 return "mov.b %X0,%X0";
867 else if (<MODE>mode == HImode)
868 return "mov.w %T0,%T0";
869 gcc_unreachable ();
870 }
871 [(set_attr "length" "2")
872 (set_attr "cc" "set_znv")])
873
874 (define_insn "*tsthi_upper"
875 [(set (cc0)
876 (compare (and:HI (match_operand:HI 0 "register_operand" "r")
877 (const_int -256))
878 (const_int 0)))]
879 ""
880 "mov.b %t0,%t0"
881 [(set_attr "length" "2")
882 (set_attr "cc" "set_znv")])
883
884 (define_insn "*tstsi"
885 [(set (cc0)
886 (compare (match_operand:SI 0 "register_operand" "r")
887 (const_int 0)))]
888 "TARGET_H8300H || TARGET_H8300S"
889 "mov.l %S0,%S0"
890 [(set_attr "length" "2")
891 (set_attr "cc" "set_znv")])
892
893 (define_insn "*tstsi_upper"
894 [(set (cc0)
895 (compare (and:SI (match_operand:SI 0 "register_operand" "r")
896 (const_int -65536))
897 (const_int 0)))]
898 ""
899 "mov.w %e0,%e0"
900 [(set_attr "length" "2")
901 (set_attr "cc" "set_znv")])
902
903 (define_insn "*cmpqi"
904 [(set (cc0)
905 (compare (match_operand:QI 0 "h8300_dst_operand" "rQ")
906 (match_operand:QI 1 "h8300_src_operand" "rQi")))]
907 ""
908 "cmp.b %X1,%X0"
909 [(set_attr "length_table" "add")
910 (set_attr "cc" "compare")])
911
912 (define_insn "*cmphi_h8300_znvc"
913 [(set (cc0)
914 (compare (match_operand:HI 0 "register_operand" "r")
915 (match_operand:HI 1 "register_operand" "r")))]
916 "TARGET_H8300"
917 "cmp.w %T1,%T0"
918 [(set_attr "length" "2")
919 (set_attr "cc" "compare")])
920
921 (define_insn "*cmphi_h8300hs_znvc"
922 [(set (cc0)
923 (compare (match_operand:HI 0 "h8300_dst_operand" "rU,rQ")
924 (match_operand:HI 1 "h8300_src_operand" "P3>X,rQi")))]
925 "TARGET_H8300H || TARGET_H8300S"
926 {
927 switch (which_alternative)
928 {
929 case 0:
930 if (!TARGET_H8300SX)
931 return "cmp.w %T1,%T0";
932 else
933 return "cmp.w %T1:3,%T0";
934 case 1:
935 return "cmp.w %T1,%T0";
936 default:
937 gcc_unreachable ();
938 }
939 }
940 [(set_attr "length_table" "short_immediate,add")
941 (set_attr "cc" "compare,compare")])
942
943 (define_insn "cmpsi"
944 [(set (cc0)
945 (compare (match_operand:SI 0 "h8300_dst_operand" "r,rQ")
946 (match_operand:SI 1 "h8300_src_operand" "P3>X,rQi")))]
947 "TARGET_H8300H || TARGET_H8300S"
948 {
949 switch (which_alternative)
950 {
951 case 0:
952 if (!TARGET_H8300SX)
953 return "cmp.l %S1,%S0";
954 else
955 return "cmp.l %S1:3,%S0";
956 case 1:
957 return "cmp.l %S1,%S0";
958 default:
959 gcc_unreachable ();
960 }
961 }
962 [(set_attr "length" "2,*")
963 (set_attr "length_table" "*,add")
964 (set_attr "cc" "compare,compare")])
965 \f
966 ;; ----------------------------------------------------------------------
967 ;; ADD INSTRUCTIONS
968 ;; ----------------------------------------------------------------------
969
970 (define_expand "add<mode>3"
971 [(set (match_operand:QHSI 0 "register_operand" "")
972 (plus:QHSI (match_operand:QHSI 1 "register_operand" "")
973 (match_operand:QHSI 2 "h8300_src_operand" "")))]
974 ""
975 "")
976
977 (define_insn "*addqi3"
978 [(set (match_operand:QI 0 "h8300_dst_operand" "=rQ")
979 (plus:QI (match_operand:QI 1 "h8300_dst_operand" "%0")
980 (match_operand:QI 2 "h8300_src_operand" "rQi")))]
981 "h8300_operands_match_p (operands)"
982 "add.b %X2,%X0"
983 [(set_attr "length_table" "add")
984 (set_attr "cc" "set_zn")])
985
986 (define_insn "*addhi3_h8300"
987 [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r")
988 (plus:HI (match_operand:HI 1 "register_operand" "%0,0,0,0,0")
989 (match_operand:HI 2 "h8300_src_operand" "L,N,J,n,r")))]
990 "TARGET_H8300"
991 "@
992 adds %2,%T0
993 subs %G2,%T0
994 add.b %t2,%t0
995 add.b %s2,%s0\;addx %t2,%t0
996 add.w %T2,%T0"
997 [(set_attr "length" "2,2,2,4,2")
998 (set_attr "cc" "none_0hit,none_0hit,clobber,clobber,set_zn")])
999
1000 ;; This splitter is very important to make the stack adjustment
1001 ;; interrupt-safe. The combination of add.b and addx is unsafe!
1002 ;;
1003 ;; We apply this split after the peephole2 pass so that we won't end
1004 ;; up creating too many adds/subs when a scratch register is
1005 ;; available, which is actually a common case because stack unrolling
1006 ;; tends to happen immediately after a function call.
1007
1008 (define_split
1009 [(set (match_operand:HI 0 "stack_pointer_operand" "")
1010 (plus:HI (match_dup 0)
1011 (match_operand 1 "const_int_gt_2_operand" "")))]
1012 "TARGET_H8300 && epilogue_completed"
1013 [(const_int 0)]
1014 {
1015 split_adds_subs (HImode, operands);
1016 DONE;
1017 })
1018
1019 (define_peephole2
1020 [(match_scratch:HI 2 "r")
1021 (set (match_operand:HI 0 "stack_pointer_operand" "")
1022 (plus:HI (match_dup 0)
1023 (match_operand:HI 1 "const_int_ge_8_operand" "")))]
1024 "TARGET_H8300"
1025 [(set (match_dup 2)
1026 (match_dup 1))
1027 (set (match_dup 0)
1028 (plus:HI (match_dup 0)
1029 (match_dup 2)))]
1030 "")
1031
1032 (define_insn "*addhi3_h8300hs"
1033 [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r")
1034 (plus:HI (match_operand:HI 1 "register_operand" "%0,0,0,0,0")
1035 (match_operand:HI 2 "h8300_src_operand" "L,N,J,n,r")))]
1036 "(TARGET_H8300H || TARGET_H8300S) && !TARGET_H8300SX"
1037 "@
1038 adds %2,%S0
1039 subs %G2,%S0
1040 add.b %t2,%t0
1041 add.w %T2,%T0
1042 add.w %T2,%T0"
1043 [(set_attr "length" "2,2,2,4,2")
1044 (set_attr "cc" "none_0hit,none_0hit,clobber,set_zn,set_zn")])
1045
1046 (define_insn "*add<mode>3_incdec"
1047 [(set (match_operand:HSI 0 "register_operand" "=r,r")
1048 (unspec:HSI [(match_operand:HSI 1 "register_operand" "0,0")
1049 (match_operand:HSI 2 "incdec_operand" "M,O")]
1050 UNSPEC_INCDEC))]
1051 "TARGET_H8300H || TARGET_H8300S"
1052 {
1053 if (which_alternative == 0)
1054 return <MODE>mode == HImode ? "inc.w\t%2,%T0" : "inc.l\t%2,%S0";
1055 else if (which_alternative == 1)
1056 return <MODE>mode == HImode ? "dec.w\t%G2,%T0" : "dec.l\t%G2,%S0";
1057 gcc_unreachable ();
1058 }
1059 [(set_attr "length" "2,2")
1060 (set_attr "cc" "set_zn,set_zn")])
1061
1062 (define_insn "*addhi3_h8sx"
1063 [(set (match_operand:HI 0 "h8300_dst_operand" "=rU,rU,r,rQ")
1064 (plus:HI (match_operand:HI 1 "h8300_dst_operand" "%0,0,0,0")
1065 (match_operand:HI 2 "h8300_src_operand" "P3>X,P3<X,J,rQi")))]
1066 "TARGET_H8300SX && h8300_operands_match_p (operands)"
1067 "@
1068 add.w %T2:3,%T0
1069 sub.w %G2:3,%T0
1070 add.b %t2,%t0
1071 add.w %T2,%T0"
1072 [(set_attr "length_table" "short_immediate,short_immediate,*,add")
1073 (set_attr "length" "*,*,2,*")
1074 (set_attr "cc" "set_zn")])
1075
1076 (define_split
1077 [(set (match_operand:HI 0 "register_operand" "")
1078 (plus:HI (match_dup 0)
1079 (match_operand:HI 1 "two_insn_adds_subs_operand" "")))]
1080 ""
1081 [(const_int 0)]
1082 {
1083 split_adds_subs (HImode, operands);
1084 DONE;
1085 })
1086
1087
1088 (define_insn "*addsi_h8300"
1089 [(set (match_operand:SI 0 "register_operand" "=r,r")
1090 (plus:SI (match_operand:SI 1 "register_operand" "%0,0")
1091 (match_operand:SI 2 "h8300_src_operand" "n,r")))]
1092 "TARGET_H8300"
1093 {
1094 return output_plussi (operands);
1095 }
1096 [(set (attr "length")
1097 (symbol_ref "compute_plussi_length (operands)"))
1098 (set (attr "cc")
1099 (symbol_ref "compute_plussi_cc (operands)"))])
1100
1101 (define_insn "*addsi_h8300hs"
1102 [(set (match_operand:SI 0 "h8300_dst_operand" "=rQ,rQ")
1103 (plus:SI (match_operand:SI 1 "h8300_dst_operand" "%0,0")
1104 (match_operand:SI 2 "h8300_src_operand" "i,rQ")))]
1105 "(TARGET_H8300H || TARGET_H8300S) && h8300_operands_match_p (operands)"
1106 {
1107 return output_plussi (operands);
1108 }
1109 [(set (attr "length")
1110 (symbol_ref "compute_plussi_length (operands)"))
1111 (set (attr "cc")
1112 (symbol_ref "compute_plussi_cc (operands)"))])
1113
1114 (define_split
1115 [(set (match_operand:SI 0 "register_operand" "")
1116 (plus:SI (match_dup 0)
1117 (match_operand:SI 1 "two_insn_adds_subs_operand" "")))]
1118 "TARGET_H8300H || TARGET_H8300S"
1119 [(const_int 0)]
1120 {
1121 split_adds_subs (SImode, operands);
1122 DONE;
1123 })
1124
1125 ;; ----------------------------------------------------------------------
1126 ;; SUBTRACT INSTRUCTIONS
1127 ;; ----------------------------------------------------------------------
1128
1129 (define_expand "sub<mode>3"
1130 [(set (match_operand:QHSI 0 "register_operand" "")
1131 (minus:QHSI (match_operand:QHSI 1 "register_operand" "")
1132 (match_operand:QHSI 2 "h8300_src_operand" "")))]
1133 ""
1134 {
1135 if (TARGET_H8300 && <MODE>mode == SImode)
1136 operands[2] = force_reg (SImode, operands[2]);
1137 })
1138
1139 (define_insn "*subqi3"
1140 [(set (match_operand:QI 0 "h8300_dst_operand" "=rQ")
1141 (minus:QI (match_operand:QI 1 "h8300_dst_operand" "0")
1142 (match_operand:QI 2 "h8300_dst_operand" "rQ")))]
1143 "h8300_operands_match_p (operands)"
1144 "sub.b %X2,%X0"
1145 [(set_attr "length_table" "add")
1146 (set_attr "cc" "set_zn")])
1147
1148 (define_insn "*subhi3_h8300"
1149 [(set (match_operand:HI 0 "register_operand" "=r,r")
1150 (minus:HI (match_operand:HI 1 "register_operand" "0,0")
1151 (match_operand:HI 2 "h8300_src_operand" "r,n")))]
1152 "TARGET_H8300"
1153 "@
1154 sub.w %T2,%T0
1155 add.b %E2,%s0\;addx %F2,%t0"
1156 [(set_attr "length" "2,4")
1157 (set_attr "cc" "set_zn,clobber")])
1158
1159 (define_insn "*sub<mode>3_h8300hs"
1160 [(set (match_operand:HSI 0 "h8300_dst_operand" "=rQ,rQ")
1161 (minus:HSI (match_operand:HSI 1 "h8300_dst_operand" "0,0")
1162 (match_operand:HSI 2 "h8300_src_operand" "rQ,i")))]
1163 "(TARGET_H8300H || TARGET_H8300S) && h8300_operands_match_p (operands)"
1164 {
1165 if (<MODE>mode == HImode)
1166 return "sub.w %T2,%T0";
1167 else if (<MODE>mode == SImode)
1168 return "sub.l %S2,%S0";
1169 gcc_unreachable ();
1170 }
1171 [(set_attr "length_table" "add")
1172 (set_attr "cc" "set_zn")])
1173
1174 (define_insn "*subsi3_h8300"
1175 [(set (match_operand:SI 0 "register_operand" "=r")
1176 (minus:SI (match_operand:SI 1 "register_operand" "0")
1177 (match_operand:SI 2 "register_operand" "r")))]
1178 "TARGET_H8300"
1179 "sub.w %f2,%f0\;subx %y2,%y0\;subx %z2,%z0"
1180 [(set_attr "length" "6")])
1181
1182 \f
1183 ;; ----------------------------------------------------------------------
1184 ;; MULTIPLY INSTRUCTIONS
1185 ;; ----------------------------------------------------------------------
1186
1187 ;; Note that the H8/300 can only handle umulqihi3.
1188
1189 (define_expand "mulqihi3"
1190 [(set (match_operand:HI 0 "register_operand" "")
1191 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" ""))
1192 ;; intentionally-mismatched modes
1193 (match_operand:QI 2 "reg_or_nibble_operand" "")))]
1194 "TARGET_H8300H || TARGET_H8300S"
1195 {
1196 if (GET_MODE (operands[2]) != VOIDmode)
1197 operands[2] = gen_rtx_SIGN_EXTEND (HImode, operands[2]);
1198 })
1199
1200 (define_insn "*mulqihi3_const"
1201 [(set (match_operand:HI 0 "register_operand" "=r")
1202 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "%0"))
1203 (match_operand:QI 2 "nibble_operand" "IP4>X")))]
1204 "TARGET_H8300SX"
1205 "mulxs.b %X2,%T0"
1206 [(set_attr "length" "4")
1207 (set_attr "cc" "set_zn")])
1208
1209 (define_insn "*mulqihi3"
1210 [(set (match_operand:HI 0 "register_operand" "=r")
1211 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "%0"))
1212 (sign_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
1213 "TARGET_H8300H || TARGET_H8300S"
1214 "mulxs.b %X2,%T0"
1215 [(set_attr "length" "4")
1216 (set_attr "cc" "set_zn")])
1217
1218 (define_expand "mulhisi3"
1219 [(set (match_operand:SI 0 "register_operand" "")
1220 (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" ""))
1221 ;; intentionally-mismatched modes
1222 (match_operand:HI 2 "reg_or_nibble_operand" "")))]
1223 "TARGET_H8300H || TARGET_H8300S"
1224 {
1225 if (GET_MODE (operands[2]) != VOIDmode)
1226 operands[2] = gen_rtx_SIGN_EXTEND (SImode, operands[2]);
1227 })
1228
1229 (define_insn "*mulhisi3_const"
1230 [(set (match_operand:SI 0 "register_operand" "=r")
1231 (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" "%0"))
1232 (match_operand:SI 2 "nibble_operand" "IP4>X")))]
1233 "TARGET_H8300SX"
1234 "mulxs.w %T2,%S0"
1235 [(set_attr "length" "4")
1236 (set_attr "cc" "set_zn")])
1237
1238 (define_insn "*mulhisi3"
1239 [(set (match_operand:SI 0 "register_operand" "=r")
1240 (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" "%0"))
1241 (sign_extend:SI (match_operand:HI 2 "register_operand" "r"))))]
1242 "TARGET_H8300H || TARGET_H8300S"
1243 "mulxs.w %T2,%S0"
1244 [(set_attr "length" "4")
1245 (set_attr "cc" "set_zn")])
1246
1247 (define_expand "umulqihi3"
1248 [(set (match_operand:HI 0 "register_operand" "")
1249 (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" ""))
1250 ;; intentionally-mismatched modes
1251 (match_operand:QI 2 "reg_or_nibble_operand" "")))]
1252 "TARGET_H8300H || TARGET_H8300S"
1253 {
1254 if (GET_MODE (operands[2]) != VOIDmode)
1255 operands[2] = gen_rtx_ZERO_EXTEND (HImode, operands[2]);
1256 })
1257
1258 (define_insn "*umulqihi3_const"
1259 [(set (match_operand:HI 0 "register_operand" "=r")
1260 (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "%0"))
1261 (match_operand:QI 2 "nibble_operand" "IP4>X")))]
1262 "TARGET_H8300SX"
1263 "mulxu.b %X2,%T0"
1264 [(set_attr "length" "4")
1265 (set_attr "cc" "set_zn")])
1266
1267 (define_insn "*umulqihi3"
1268 [(set (match_operand:HI 0 "register_operand" "=r")
1269 (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "%0"))
1270 (zero_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
1271 ""
1272 "mulxu.b %X2,%T0"
1273 [(set_attr "length" "2")
1274 (set_attr "cc" "none_0hit")])
1275
1276 (define_expand "umulhisi3"
1277 [(set (match_operand:SI 0 "register_operand" "")
1278 (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" ""))
1279 ;; intentionally-mismatched modes
1280 (match_operand:HI 2 "reg_or_nibble_operand" "")))]
1281 "TARGET_H8300H || TARGET_H8300S"
1282 {
1283 if (GET_MODE (operands[2]) != VOIDmode)
1284 operands[2] = gen_rtx_ZERO_EXTEND (SImode, operands[2]);
1285 })
1286
1287 (define_insn "*umulhisi3_const"
1288 [(set (match_operand:SI 0 "register_operand" "=r")
1289 (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "%0"))
1290 (match_operand:SI 2 "nibble_operand" "IP4>X")))]
1291 "TARGET_H8300SX"
1292 "mulxu.w %T2,%S0"
1293 [(set_attr "length" "4")
1294 (set_attr "cc" "set_zn")])
1295
1296 (define_insn "*umulhisi3"
1297 [(set (match_operand:SI 0 "register_operand" "=r")
1298 (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "%0"))
1299 (zero_extend:SI (match_operand:HI 2 "register_operand" "r"))))]
1300 "TARGET_H8300H || TARGET_H8300S"
1301 "mulxu.w %T2,%S0"
1302 [(set_attr "length" "2")
1303 (set_attr "cc" "none_0hit")])
1304
1305 ;; We could have used mulu.[wl] here, but mulu.[lw] is only available
1306 ;; on a H8SX with a multiplier, whereas muls.w seems to be available
1307 ;; on all H8SX variants.
1308
1309 (define_insn "mul<mode>3"
1310 [(set (match_operand:HSI 0 "register_operand" "=r")
1311 (mult:HSI (match_operand:HSI 1 "register_operand" "%0")
1312 (match_operand:HSI 2 "reg_or_nibble_operand" "r IP4>X")))]
1313 "TARGET_H8300SX"
1314 { return <MODE>mode == HImode ? "muls.w\\t%T2,%T0" : "muls.l\\t%S2,%S0"; }
1315 [(set_attr "length" "2")
1316 (set_attr "cc" "set_zn")])
1317
1318 (define_insn "smulsi3_highpart"
1319 [(set (match_operand:SI 0 "register_operand" "=r")
1320 (truncate:SI
1321 (lshiftrt:DI
1322 (mult:DI
1323 (sign_extend:DI (match_operand:SI 1 "register_operand" "%0"))
1324 (sign_extend:DI (match_operand:SI 2 "reg_or_nibble_operand" "r IP4>X")))
1325 (const_int 32))))]
1326 "TARGET_H8300SXMUL"
1327 "muls/u.l\\t%S2,%S0"
1328 [(set_attr "length" "2")
1329 (set_attr "cc" "set_zn")])
1330
1331 (define_insn "umulsi3_highpart"
1332 [(set (match_operand:SI 0 "register_operand" "=r")
1333 (truncate:SI
1334 (ashiftrt:DI
1335 (mult:DI
1336 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
1337 (zero_extend:DI (match_operand:SI 2 "reg_or_nibble_operand" "r IP4>X")))
1338 (const_int 32))))]
1339 "TARGET_H8300SX"
1340 "mulu/u.l\\t%S2,%S0"
1341 [(set_attr "length" "2")
1342 (set_attr "cc" "none_0hit")])
1343
1344 ;; This is a "bridge" instruction. Combine can't cram enough insns
1345 ;; together to crate a MAC instruction directly, but it can create
1346 ;; this instruction, which then allows combine to create the real
1347 ;; MAC insn.
1348 ;;
1349 ;; Unfortunately, if combine doesn't create a MAC instruction, this
1350 ;; insn must generate reasonably correct code. Egad.
1351
1352 (define_insn ""
1353 [(set (match_operand:SI 0 "register_operand" "=a")
1354 (mult:SI
1355 (sign_extend:SI
1356 (mem:HI (post_inc:SI (match_operand:SI 1 "register_operand" "r"))))
1357 (sign_extend:SI
1358 (mem:HI (post_inc:SI (match_operand:SI 2 "register_operand" "r"))))))]
1359 "TARGET_MAC"
1360 "clrmac\;mac @%2+,@%1+"
1361 [(set_attr "length" "6")
1362 (set_attr "cc" "none_0hit")])
1363
1364 (define_insn ""
1365 [(set (match_operand:SI 0 "register_operand" "=a")
1366 (plus:SI (mult:SI
1367 (sign_extend:SI (mem:HI
1368 (post_inc:SI (match_operand:SI 1 "register_operand" "r"))))
1369 (sign_extend:SI (mem:HI
1370 (post_inc:SI (match_operand:SI 2 "register_operand" "r")))))
1371 (match_operand:SI 3 "register_operand" "0")))]
1372 "TARGET_MAC"
1373 "mac @%2+,@%1+"
1374 [(set_attr "length" "4")
1375 (set_attr "cc" "none_0hit")])
1376
1377 ;; ----------------------------------------------------------------------
1378 ;; DIVIDE/MOD INSTRUCTIONS
1379 ;; ----------------------------------------------------------------------
1380
1381 (define_insn "udiv<mode>3"
1382 [(set (match_operand:HSI 0 "register_operand" "=r")
1383 (udiv:HSI (match_operand:HSI 1 "register_operand" "0")
1384 (match_operand:HSI 2 "reg_or_nibble_operand" "r IP4>X")))]
1385 "TARGET_H8300SX"
1386 { return <MODE>mode == HImode ? "divu.w\\t%T2,%T0" : "divu.l\\t%S2,%S0"; }
1387 [(set_attr "length" "2")])
1388
1389 (define_insn "div<mode>3"
1390 [(set (match_operand:HSI 0 "register_operand" "=r")
1391 (div:HSI (match_operand:HSI 1 "register_operand" "0")
1392 (match_operand:HSI 2 "reg_or_nibble_operand" "r IP4>X")))]
1393 "TARGET_H8300SX"
1394 { return <MODE>mode == HImode ? "divs.w\\t%T2,%T0" : "divs.l\\t%S2,%S0"; }
1395 [(set_attr "length" "2")])
1396
1397 (define_insn "udivmodqi4"
1398 [(set (match_operand:QI 0 "register_operand" "=r")
1399 (truncate:QI
1400 (udiv:HI
1401 (match_operand:HI 1 "register_operand" "0")
1402 (zero_extend:HI (match_operand:QI 2 "register_operand" "r")))))
1403 (set (match_operand:QI 3 "register_operand" "=r")
1404 (truncate:QI
1405 (umod:HI
1406 (match_dup 1)
1407 (zero_extend:HI (match_dup 2)))))]
1408 ""
1409 {
1410 if (find_reg_note (insn, REG_UNUSED, operands[3]))
1411 return "divxu.b\\t%X2,%T0";
1412 else
1413 return "divxu.b\\t%X2,%T0\;mov.b\\t%t0,%s3";
1414 }
1415 [(set_attr "length" "4")])
1416
1417 (define_insn "divmodqi4"
1418 [(set (match_operand:QI 0 "register_operand" "=r")
1419 (truncate:QI
1420 (div:HI
1421 (match_operand:HI 1 "register_operand" "0")
1422 (sign_extend:HI (match_operand:QI 2 "register_operand" "r")))))
1423 (set (match_operand:QI 3 "register_operand" "=r")
1424 (truncate:QI
1425 (mod:HI
1426 (match_dup 1)
1427 (sign_extend:HI (match_dup 2)))))]
1428 "TARGET_H8300H || TARGET_H8300S"
1429 {
1430 if (find_reg_note (insn, REG_UNUSED, operands[3]))
1431 return "divxs.b\\t%X2,%T0";
1432 else
1433 return "divxs.b\\t%X2,%T0\;mov.b\\t%t0,%s3";
1434 }
1435 [(set_attr "length" "6")])
1436
1437 (define_insn "udivmodhi4"
1438 [(set (match_operand:HI 0 "register_operand" "=r")
1439 (truncate:HI
1440 (udiv:SI
1441 (match_operand:SI 1 "register_operand" "0")
1442 (zero_extend:SI (match_operand:HI 2 "register_operand" "r")))))
1443 (set (match_operand:HI 3 "register_operand" "=r")
1444 (truncate:HI
1445 (umod:SI
1446 (match_dup 1)
1447 (zero_extend:SI (match_dup 2)))))]
1448 "TARGET_H8300H || TARGET_H8300S"
1449 {
1450 if (find_reg_note (insn, REG_UNUSED, operands[3]))
1451 return "divxu.w\\t%T2,%S0";
1452 else
1453 return "divxu.w\\t%T2,%S0\;mov.w\\t%e0,%f3";
1454 }
1455 [(set_attr "length" "4")])
1456
1457 (define_insn "divmodhi4"
1458 [(set (match_operand:HI 0 "register_operand" "=r")
1459 (truncate:HI
1460 (div:SI
1461 (match_operand:SI 1 "register_operand" "0")
1462 (sign_extend:SI (match_operand:HI 2 "register_operand" "r")))))
1463 (set (match_operand:HI 3 "register_operand" "=r")
1464 (truncate:HI
1465 (mod:SI
1466 (match_dup 1)
1467 (sign_extend:SI (match_dup 2)))))]
1468 "TARGET_H8300H || TARGET_H8300S"
1469 {
1470 if (find_reg_note (insn, REG_UNUSED, operands[3]))
1471 return "divxs.w\\t%T2,%S0";
1472 else
1473 return "divxs.w\\t%T2,%S0\;mov.w\\t%e0,%f3";
1474 }
1475 [(set_attr "length" "6")])
1476 \f
1477 ;; ----------------------------------------------------------------------
1478 ;; AND INSTRUCTIONS
1479 ;; ----------------------------------------------------------------------
1480
1481 (define_insn "bclrqi_msx"
1482 [(set (match_operand:QI 0 "bit_register_indirect_operand" "=WU")
1483 (and:QI (match_operand:QI 1 "bit_register_indirect_operand" "%0")
1484 (match_operand:QI 2 "single_zero_operand" "Y0")))]
1485 "TARGET_H8300SX && rtx_equal_p (operands[0], operands[1])"
1486 "bclr\\t%W2,%0"
1487 [(set_attr "length" "8")])
1488
1489 (define_split
1490 [(set (match_operand:HI 0 "bit_register_indirect_operand")
1491 (and:HI (match_operand:HI 1 "bit_register_indirect_operand")
1492 (match_operand:HI 2 "single_zero_operand")))]
1493 "TARGET_H8300SX"
1494 [(set (match_dup 0)
1495 (and:QI (match_dup 1)
1496 (match_dup 2)))]
1497 {
1498 if (abs (INTVAL (operands[2])) > 0xFF)
1499 {
1500 operands[0] = adjust_address (operands[0], QImode, 0);
1501 operands[1] = adjust_address (operands[1], QImode, 0);
1502 operands[2] = GEN_INT ((INTVAL (operands[2])) >> 8);
1503 }
1504 else
1505 {
1506 operands[0] = adjust_address (operands[0], QImode, 1);
1507 operands[1] = adjust_address (operands[1], QImode, 1);
1508 }
1509 })
1510
1511 (define_insn "bclrhi_msx"
1512 [(set (match_operand:HI 0 "bit_register_indirect_operand" "=m")
1513 (and:HI (match_operand:HI 1 "bit_register_indirect_operand" "%0")
1514 (match_operand:HI 2 "single_zero_operand" "Y0")))]
1515 "TARGET_H8300SX"
1516 "bclr\\t%W2,%0"
1517 [(set_attr "length" "8")])
1518
1519 (define_insn "*andqi3_2"
1520 [(set (match_operand:QI 0 "bit_operand" "=U,rQ,r")
1521 (and:QI (match_operand:QI 1 "bit_operand" "%0,0,WU")
1522 (match_operand:QI 2 "h8300_src_operand" "Y0,rQi,IP1>X")))]
1523 "TARGET_H8300SX"
1524 "@
1525 bclr\\t %W2,%R0
1526 and %X2,%X0
1527 bfld %2,%1,%R0"
1528 [(set_attr "length" "8,*,8")
1529 (set_attr "length_table" "*,logicb,*")
1530 (set_attr "cc" "none_0hit,set_znv,none_0hit")])
1531
1532 (define_insn "andqi3_1"
1533 [(set (match_operand:QI 0 "bit_operand" "=U,r")
1534 (and:QI (match_operand:QI 1 "bit_operand" "%0,0")
1535 (match_operand:QI 2 "h8300_src_operand" "Y0,rn")))]
1536 "register_operand (operands[0], QImode)
1537 || single_zero_operand (operands[2], QImode)"
1538 "@
1539 bclr %W2,%R0
1540 and %X2,%X0"
1541 [(set_attr "length" "2,8")
1542 (set_attr "cc" "none_0hit,set_znv")])
1543
1544 (define_expand "and<mode>3"
1545 [(set (match_operand:QHSI 0 "register_operand" "")
1546 (and:QHSI (match_operand:QHSI 1 "register_operand" "")
1547 (match_operand:QHSI 2 "h8300_src_operand" "")))]
1548 ""
1549 "")
1550
1551 (define_insn "*andor<mode>3"
1552 [(set (match_operand:QHSI 0 "register_operand" "=r")
1553 (ior:QHSI (and:QHSI (match_operand:QHSI 2 "register_operand" "r")
1554 (match_operand:QHSI 3 "single_one_operand" "n"))
1555 (match_operand:QHSI 1 "register_operand" "0")))]
1556 "(<MODE>mode == QImode
1557 || <MODE>mode == HImode
1558 || (<MODE>mode == SImode
1559 && (INTVAL (operands[3]) & 0xffff) != 0))"
1560 {
1561 if (<MODE>mode == QImode)
1562 return "bld\\t%V3,%X2\;bor\\t%V3,%X0\;bst\\t%V3,%X0";
1563
1564 if (<MODE>mode == HImode)
1565 {
1566 operands[3] = GEN_INT (INTVAL (operands[3]) & 0xffff);
1567 if (INTVAL (operands[3]) > 128)
1568 {
1569 operands[3] = GEN_INT (INTVAL (operands[3]) >> 8);
1570 return "bld\\t%V3,%t2\;bor\\t%V3,%t0\;bst\\t%V3,%t0";
1571 }
1572 return "bld\\t%V3,%s2\;bor\\t%V3,%s0\;bst\\t%V3,%s0";
1573 }
1574
1575 if (<MODE>mode == SImode)
1576 {
1577 operands[3] = GEN_INT (INTVAL (operands[3]) & 0xffff);
1578 if (INTVAL (operands[3]) > 128)
1579 {
1580 operands[3] = GEN_INT (INTVAL (operands[3]) >> 8);
1581 return "bld\\t%V3,%x2\;bor\\t%V3,%x0\;bst\\t%V3,%x0";
1582 }
1583 return "bld\\t%V3,%w2\;bor\\t%V3,%w0\;bst\\t%V3,%w0";
1584 }
1585
1586 gcc_unreachable ();
1587
1588 }
1589 [(set_attr "length" "6")])
1590
1591 (define_insn "*andorsi3_shift_8"
1592 [(set (match_operand:SI 0 "register_operand" "=r")
1593 (ior:SI (and:SI (ashift:SI (match_operand:SI 2 "register_operand" "r")
1594 (const_int 8))
1595 (const_int 65280))
1596 (match_operand:SI 1 "register_operand" "0")))]
1597 ""
1598 "or.b\\t%w2,%x0"
1599 [(set_attr "length" "2")])
1600
1601 ;; ----------------------------------------------------------------------
1602 ;; OR/XOR INSTRUCTIONS
1603 ;; ----------------------------------------------------------------------
1604
1605 (define_insn "b<code>qi_msx"
1606 [(set (match_operand:QI 0 "bit_register_indirect_operand" "=WU")
1607 (ors:QI (match_operand:QI 1 "bit_register_indirect_operand" "%0")
1608 (match_operand:QI 2 "single_one_operand" "Y2")))]
1609 "TARGET_H8300SX && rtx_equal_p (operands[0], operands[1])"
1610 { return <CODE> == IOR ? "bset\\t%V2,%0" : "bnot\\t%V2,%0"; }
1611 [(set_attr "length" "8")])
1612
1613 (define_insn "b<code>hi_msx"
1614 [(set (match_operand:HI 0 "bit_register_indirect_operand" "=m")
1615 (ors:HI (match_operand:HI 1 "bit_register_indirect_operand" "%0")
1616 (match_operand:HI 2 "single_one_operand" "Y2")))]
1617 "TARGET_H8300SX"
1618 { return <CODE> == IOR ? "bset\\t%V2,%0" : "bnot\\t%V2,%0"; }
1619 [(set_attr "length" "8")])
1620
1621 (define_insn "<code>qi3_1"
1622 [(set (match_operand:QI 0 "bit_operand" "=U,rQ")
1623 (ors:QI (match_operand:QI 1 "bit_operand" "%0,0")
1624 (match_operand:QI 2 "h8300_src_operand" "Y2,rQi")))]
1625 "TARGET_H8300SX || register_operand (operands[0], QImode)
1626 || single_one_operand (operands[2], QImode)"
1627 {
1628 if (which_alternative == 0)
1629 return <CODE> == IOR ? "bset\\t%V2,%R0" : "bnot\\t%V2,%R0";
1630 else if (which_alternative == 1)
1631 return <CODE> == IOR ? "or\\t%X2,%X0" : "xor\\t%X2,%X0";
1632 }
1633 [(set_attr "length" "8,*")
1634 (set_attr "length_table" "*,logicb")
1635 (set_attr "cc" "none_0hit,set_znv")])
1636
1637 (define_expand "<code><mode>3"
1638 [(set (match_operand:QHSI 0 "register_operand" "")
1639 (ors:QHSI (match_operand:QHSI 1 "register_operand" "")
1640 (match_operand:QHSI 2 "h8300_src_operand" "")))]
1641 ""
1642 "")
1643
1644 ;; ----------------------------------------------------------------------
1645 ;; {AND,IOR,XOR}{HI3,SI3} PATTERNS
1646 ;; ----------------------------------------------------------------------
1647
1648 (define_insn "*logical<mode>3"
1649 [(set (match_operand:HSI 0 "h8300_dst_operand" "=rQ")
1650 (match_operator:HSI 3 "bit_operator"
1651 [(match_operand:HSI 1 "h8300_dst_operand" "%0")
1652 (match_operand:HSI 2 "h8300_src_operand" "rQi")]))]
1653 "h8300_operands_match_p (operands)"
1654 { return output_logical_op (<MODE>mode, operands); }
1655 [(set (attr "length")
1656 (symbol_ref "compute_logical_op_length (<MODE>mode, operands)"))
1657 (set (attr "cc")
1658 (symbol_ref "compute_logical_op_cc (<MODE>mode, operands)"))])
1659 \f
1660 ;; ----------------------------------------------------------------------
1661 ;; NEGATION INSTRUCTIONS
1662 ;; ----------------------------------------------------------------------
1663
1664 (define_expand "neg<mode>2"
1665 [(set (match_operand:QHSIF 0 "register_operand" "")
1666 (neg:QHSIF (match_operand:QHSIF 1 "register_operand" "")))]
1667 ""
1668 {
1669 enum machine_mode mode = <MODE>mode;
1670 if (TARGET_H8300)
1671 {
1672 if (mode == QImode || mode == SFmode)
1673 ;
1674 else if (mode == HImode)
1675 {
1676 emit_insn (gen_neghi2_h8300 (operands[0], operands[1]));
1677 DONE;
1678 }
1679 else if (mode == SImode)
1680 {
1681 emit_insn (gen_negsi2_h8300 (operands[0], operands[1]));
1682 DONE;
1683 }
1684 }
1685 })
1686
1687 (define_insn "*negqi2"
1688 [(set (match_operand:QI 0 "h8300_dst_operand" "=rQ")
1689 (neg:QI (match_operand:QI 1 "h8300_dst_operand" "0")))]
1690 ""
1691 "neg %X0"
1692 [(set_attr "length_table" "unary")
1693 (set_attr "cc" "set_zn")])
1694
1695 (define_expand "neg<mode>2_h8300"
1696 [(set (match_dup 2)
1697 (not:HSI (match_operand:HSI 1 "register_operand" "")))
1698 (set (match_dup 2) (plus:HSI (match_dup 2) (const_int 1)))
1699 (set (match_operand:HSI 0 "register_operand" "")
1700 (match_dup 2))]
1701 ""
1702 {
1703 operands[2] = gen_reg_rtx (<MODE>mode);
1704 })
1705
1706 (define_insn "*neghi2_h8300hs"
1707 [(set (match_operand:HI 0 "h8300_dst_operand" "=rQ")
1708 (neg:HI (match_operand:HI 1 "h8300_dst_operand" "0")))]
1709 "(TARGET_H8300H || TARGET_H8300S) && h8300_operands_match_p (operands)"
1710 "neg.w %T0"
1711 [(set_attr "length_table" "unary")
1712 (set_attr "cc" "set_zn")])
1713
1714 (define_insn "*negsi2_h8300hs"
1715 [(set (match_operand:SI 0 "h8300_dst_operand" "=rQ")
1716 (neg:SI (match_operand:SI 1 "h8300_dst_operand" "0")))]
1717 "(TARGET_H8300H || TARGET_H8300S) && h8300_operands_match_p (operands)"
1718 "neg.l %S0"
1719 [(set_attr "length_table" "unary")
1720 (set_attr "cc" "set_zn")])
1721
1722 (define_insn "*negsf2_h8300"
1723 [(set (match_operand:SF 0 "register_operand" "=r")
1724 (neg:SF (match_operand:SF 1 "register_operand" "0")))]
1725 "TARGET_H8300"
1726 "xor.b\\t#128,%z0"
1727 [(set_attr "length" "2")])
1728
1729 (define_insn "*negsf2_h8300hs"
1730 [(set (match_operand:SF 0 "register_operand" "=r")
1731 (neg:SF (match_operand:SF 1 "register_operand" "0")))]
1732 "TARGET_H8300H || TARGET_H8300S"
1733 "xor.w\\t#32768,%e0"
1734 [(set_attr "length" "4")])
1735 \f
1736 ;; ----------------------------------------------------------------------
1737 ;; ABSOLUTE VALUE INSTRUCTIONS
1738 ;; ----------------------------------------------------------------------
1739
1740 (define_expand "abssf2"
1741 [(set (match_operand:SF 0 "register_operand" "")
1742 (abs:SF (match_operand:SF 1 "register_operand" "")))]
1743 ""
1744 "")
1745
1746 (define_insn "*abssf2_h8300"
1747 [(set (match_operand:SF 0 "register_operand" "=r")
1748 (abs:SF (match_operand:SF 1 "register_operand" "0")))]
1749 "TARGET_H8300"
1750 "and.b\\t#127,%z0"
1751 [(set_attr "length" "2")])
1752
1753 (define_insn "*abssf2_h8300hs"
1754 [(set (match_operand:SF 0 "register_operand" "=r")
1755 (abs:SF (match_operand:SF 1 "register_operand" "0")))]
1756 "TARGET_H8300H || TARGET_H8300S"
1757 "and.w\\t#32767,%e0"
1758 [(set_attr "length" "4")])
1759 \f
1760 ;; ----------------------------------------------------------------------
1761 ;; NOT INSTRUCTIONS
1762 ;; ----------------------------------------------------------------------
1763
1764 (define_expand "one_cmpl<mode>2"
1765 [(set (match_operand:QHSI 0 "register_operand" "")
1766 (not:QHSI (match_operand:QHSI 1 "register_operand" "")))]
1767 ""
1768 "")
1769
1770 (define_insn "*one_cmplqi2"
1771 [(set (match_operand:QI 0 "h8300_dst_operand" "=rQ")
1772 (not:QI (match_operand:QI 1 "h8300_dst_operand" "0")))]
1773 ""
1774 "not %X0"
1775 [(set_attr "length_table" "unary")
1776 (set_attr "cc" "set_znv")])
1777
1778 (define_insn "*one_cmplhi2_h8300"
1779 [(set (match_operand:HI 0 "register_operand" "=r")
1780 (not:HI (match_operand:HI 1 "register_operand" "0")))]
1781 "TARGET_H8300"
1782 "not %s0\;not %t0"
1783 [(set_attr "length" "4")])
1784
1785 (define_insn "*one_cmplhi2_h8300hs"
1786 [(set (match_operand:HI 0 "h8300_dst_operand" "=rQ")
1787 (not:HI (match_operand:HI 1 "h8300_dst_operand" "0")))]
1788 "(TARGET_H8300H || TARGET_H8300S) && h8300_operands_match_p (operands)"
1789 "not.w %T0"
1790 [(set_attr "cc" "set_znv")
1791 (set_attr "length_table" "unary")])
1792
1793 (define_insn "*one_cmplsi2_h8300"
1794 [(set (match_operand:SI 0 "register_operand" "=r")
1795 (not:SI (match_operand:SI 1 "register_operand" "0")))]
1796 "TARGET_H8300"
1797 "not %w0\;not %x0\;not %y0\;not %z0"
1798 [(set_attr "length" "8")])
1799
1800 (define_insn "*one_cmplsi2_h8300hs"
1801 [(set (match_operand:SI 0 "h8300_dst_operand" "=rQ")
1802 (not:SI (match_operand:SI 1 "h8300_dst_operand" "0")))]
1803 "(TARGET_H8300H || TARGET_H8300S) && h8300_operands_match_p (operands)"
1804 "not.l %S0"
1805 [(set_attr "cc" "set_znv")
1806 (set_attr "length_table" "unary")])
1807 \f
1808 ;; ----------------------------------------------------------------------
1809 ;; JUMP INSTRUCTIONS
1810 ;; ----------------------------------------------------------------------
1811
1812 ;; Conditional jump instructions
1813
1814 (define_expand "cbranchqi4"
1815 [(use (match_operator 0 "ordered_comparison_operator"
1816 [(match_operand:QI 1 "h8300_dst_operand" "")
1817 (match_operand:QI 2 "h8300_src_operand" "")]))
1818 (use (match_operand 3 ""))]
1819 ""
1820 {
1821 h8300_expand_branch (operands);
1822 DONE;
1823 })
1824
1825 (define_expand "cbranchhi4"
1826 [(use (match_operator 0 "ordered_comparison_operator"
1827 [(match_operand:HI 1 "h8300_dst_operand" "")
1828 (match_operand:HI 2 "h8300_src_operand" "")]))
1829 (use (match_operand 3 ""))]
1830 ""
1831 {
1832 /* Force operand1 into a register if we're compiling
1833 for the H8/300. */
1834 if ((GET_CODE (operands[2]) != REG && operands[2] != const0_rtx)
1835 && TARGET_H8300)
1836 operands[2] = force_reg (HImode, operands[2]);
1837 h8300_expand_branch (operands);
1838 DONE;
1839 })
1840
1841 (define_expand "cbranchsi4"
1842 [(use (match_operator 0 "ordered_comparison_operator"
1843 [(match_operand:SI 1 "h8300_dst_operand" "")
1844 (match_operand:SI 2 "h8300_src_operand" "")]))
1845 (use (match_operand 3 ""))]
1846 "TARGET_H8300H || TARGET_H8300S"
1847 {
1848 h8300_expand_branch (operands);
1849 DONE;
1850 })
1851
1852 (define_insn "branch_true"
1853 [(set (pc)
1854 (if_then_else (match_operator 1 "comparison_operator"
1855 [(cc0) (const_int 0)])
1856 (label_ref (match_operand 0 "" ""))
1857 (pc)))]
1858 ""
1859 {
1860 if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0
1861 && (GET_CODE (operands[1]) == GT
1862 || GET_CODE (operands[1]) == GE
1863 || GET_CODE (operands[1]) == LE
1864 || GET_CODE (operands[1]) == LT))
1865 {
1866 cc_status.flags &= ~CC_OVERFLOW_UNUSABLE;
1867 return 0;
1868 }
1869
1870 if (get_attr_length (insn) == 2)
1871 return "b%j1 %l0";
1872 else if (get_attr_length (insn) == 4)
1873 return "b%j1 %l0:16";
1874 else
1875 return "b%k1 .Lh8BR%=\;jmp @%l0\\n.Lh8BR%=:";
1876 }
1877 [(set_attr "type" "branch")
1878 (set_attr "cc" "none")])
1879
1880 (define_insn "branch_false"
1881 [(set (pc)
1882 (if_then_else (match_operator 1 "comparison_operator"
1883 [(cc0) (const_int 0)])
1884 (pc)
1885 (label_ref (match_operand 0 "" ""))))]
1886 ""
1887 {
1888 if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0
1889 && (GET_CODE (operands[1]) == GT
1890 || GET_CODE (operands[1]) == GE
1891 || GET_CODE (operands[1]) == LE
1892 || GET_CODE (operands[1]) == LT))
1893 {
1894 cc_status.flags &= ~CC_OVERFLOW_UNUSABLE;
1895 return 0;
1896 }
1897
1898 if (get_attr_length (insn) == 2)
1899 return "b%k1 %l0";
1900 else if (get_attr_length (insn) == 4)
1901 return "b%k1 %l0:16";
1902 else
1903 return "b%j1 .Lh8BR%=\;jmp @%l0\\n.Lh8BR%=:";
1904 }
1905 [(set_attr "type" "branch")
1906 (set_attr "cc" "none")])
1907
1908 (define_insn "*brabc"
1909 [(set (pc)
1910 (if_then_else (eq (zero_extract (match_operand:QI 1 "bit_memory_operand" "WU")
1911 (const_int 1)
1912 (match_operand:QI 2 "immediate_operand" "n"))
1913 (const_int 0))
1914 (label_ref (match_operand 0 "" ""))
1915 (pc)))]
1916 "TARGET_H8300SX"
1917 {
1918 switch (get_attr_length (insn)
1919 - h8300_insn_length_from_table (insn, operands))
1920 {
1921 case 2:
1922 return "bra/bc %2,%R1,%l0";
1923 case 4:
1924 return "bra/bc %2,%R1,%l0:16";
1925 default:
1926 return "bra/bs %2,%R1,.Lh8BR%=\;jmp @%l0\\n.Lh8BR%=:";
1927 }
1928 }
1929 [(set_attr "type" "bitbranch")
1930 (set_attr "length_table" "bitbranch")
1931 (set_attr "cc" "none")])
1932
1933 (define_insn "*brabs"
1934 [(set (pc)
1935 (if_then_else (ne (zero_extract (match_operand:QI 1 "bit_memory_operand" "WU")
1936 (const_int 1)
1937 (match_operand:QI 2 "immediate_operand" "n"))
1938 (const_int 0))
1939 (label_ref (match_operand 0 "" ""))
1940 (pc)))]
1941 "TARGET_H8300SX"
1942 {
1943 switch (get_attr_length (insn)
1944 - h8300_insn_length_from_table (insn, operands))
1945 {
1946 case 2:
1947 return "bra/bs %2,%R1,%l0";
1948 case 4:
1949 return "bra/bs %2,%R1,%l0:16";
1950 default:
1951 return "bra/bc %2,%R1,.Lh8BR%=\;jmp @%l0\\n.Lh8BR%=:";
1952 }
1953 }
1954 [(set_attr "type" "bitbranch")
1955 (set_attr "length_table" "bitbranch")
1956 (set_attr "cc" "none")])
1957
1958 ;; Unconditional and other jump instructions.
1959
1960 (define_insn "jump"
1961 [(set (pc)
1962 (label_ref (match_operand 0 "" "")))]
1963 ""
1964 {
1965 if (final_sequence != 0)
1966 {
1967 if (get_attr_length (insn) == 2)
1968 return "bra/s %l0";
1969 else
1970 {
1971 /* The branch isn't short enough to use bra/s. Output the
1972 branch and delay slot in their normal order.
1973
1974 If this is a backward branch, it will now be branching two
1975 bytes further than previously thought. The length-based
1976 test for bra vs. jump is very conservative though, so the
1977 branch will still be within range. */
1978 rtx_sequence *seq;
1979 int seen;
1980
1981 seq = final_sequence;
1982 final_sequence = 0;
1983 final_scan_insn (seq->insn (1), asm_out_file, optimize, 1, & seen);
1984 final_scan_insn (seq->insn (0), asm_out_file, optimize, 1, & seen);
1985 seq->insn (1)->set_deleted ();
1986 return "";
1987 }
1988 }
1989 else if (get_attr_length (insn) == 2)
1990 return "bra %l0";
1991 else if (get_attr_length (insn) == 4)
1992 return "bra %l0:16";
1993 else
1994 return "jmp @%l0";
1995 }
1996 [(set_attr "type" "branch")
1997 (set (attr "delay_slot")
1998 (if_then_else (match_test "TARGET_H8300SX")
1999 (const_string "jump")
2000 (const_string "none")))
2001 (set_attr "cc" "none")])
2002
2003 ;; This is a define expand, because pointers may be either 16 or 32 bits.
2004
2005 (define_expand "tablejump"
2006 [(parallel [(set (pc) (match_operand 0 "register_operand" ""))
2007 (use (label_ref (match_operand 1 "" "")))])]
2008 ""
2009 "")
2010
2011 (define_insn "*tablejump_h8300"
2012 [(set (pc) (match_operand:HI 0 "register_operand" "r"))
2013 (use (label_ref (match_operand 1 "" "")))]
2014 "TARGET_H8300"
2015 "jmp @%0"
2016 [(set_attr "cc" "none")
2017 (set_attr "length" "2")])
2018
2019 (define_insn "*tablejump_h8300hs_advanced"
2020 [(set (pc) (match_operand:SI 0 "register_operand" "r"))
2021 (use (label_ref (match_operand 1 "" "")))]
2022 "(TARGET_H8300H || TARGET_H8300S) && !TARGET_NORMAL_MODE"
2023 "jmp @%0"
2024 [(set_attr "cc" "none")
2025 (set_attr "length" "2")])
2026
2027 (define_insn "*tablejump_h8300hs_normal"
2028 [(set (pc) (match_operand:HI 0 "register_operand" "r"))
2029 (use (label_ref (match_operand 1 "" "")))]
2030 "(TARGET_H8300H || TARGET_H8300S) && TARGET_NORMAL_MODE"
2031 "jmp @%S0"
2032 [(set_attr "cc" "none")
2033 (set_attr "length" "2")])
2034
2035 ;; This is a define expand, because pointers may be either 16 or 32 bits.
2036
2037 (define_expand "indirect_jump"
2038 [(set (pc) (match_operand 0 "jump_address_operand" ""))]
2039 ""
2040 "")
2041
2042 (define_insn "*indirect_jump_h8300"
2043 [(set (pc) (match_operand:HI 0 "jump_address_operand" "Vr"))]
2044 "TARGET_H8300"
2045 "jmp @%0"
2046 [(set_attr "cc" "none")
2047 (set_attr "length" "2")])
2048
2049 (define_insn "*indirect_jump_h8300hs_advanced"
2050 [(set (pc) (match_operand:SI 0 "jump_address_operand" "Vr"))]
2051 "(TARGET_H8300H || TARGET_H8300S) && !TARGET_NORMAL_MODE"
2052 "jmp @%0"
2053 [(set_attr "cc" "none")
2054 (set_attr "length" "2")])
2055
2056 (define_insn "*indirect_jump_h8300hs_normal"
2057 [(set (pc) (match_operand:HI 0 "jump_address_operand" "Vr"))]
2058 "(TARGET_H8300H || TARGET_H8300S) && TARGET_NORMAL_MODE"
2059 "jmp @%S0"
2060 [(set_attr "cc" "none")
2061 (set_attr "length" "2")])
2062
2063 ;; Call subroutine with no return value.
2064
2065 ;; ??? Even though we use HImode here, this works on the H8/300H and H8S.
2066
2067 (define_expand "call"
2068 [(call (match_operand:QI 0 "call_expander_operand" "")
2069 (match_operand:HI 1 "general_operand" ""))]
2070 ""
2071 {
2072 if (!register_operand (XEXP (operands[0], 0), Pmode)
2073 && GET_CODE (XEXP (operands[0], 0)) != SYMBOL_REF)
2074 XEXP (operands[0], 0) = force_reg (Pmode, XEXP (operands[0], 0));
2075 })
2076
2077 (define_insn "call_insn"
2078 [(call (mem:QI (match_operand 0 "call_insn_operand" "Cr"))
2079 (match_operand:HI 1 "general_operand" "g"))]
2080 ""
2081 {
2082 rtx xoperands[1];
2083 xoperands[0] = gen_rtx_MEM (QImode, operands[0]);
2084 gcc_assert (GET_MODE (operands[0]) == Pmode);
2085 if (GET_CODE (XEXP (xoperands[0], 0)) == SYMBOL_REF
2086 && (SYMBOL_REF_FLAGS (XEXP (xoperands[0], 0)) & SYMBOL_FLAG_FUNCVEC_FUNCTION))
2087 output_asm_insn ("jsr\\t@%0:8", xoperands);
2088 else
2089 output_asm_insn ("jsr\\t%0", xoperands);
2090 return "";
2091 }
2092 [(set_attr "type" "call")
2093 (set (attr "length")
2094 (if_then_else (match_operand:QI 0 "small_call_insn_operand" "")
2095 (const_int 2)
2096 (const_int 4)))])
2097
2098 ;; Call subroutine, returning value in operand 0
2099 ;; (which must be a hard register).
2100
2101 ;; ??? Even though we use HImode here, this works on the H8/300H and H8S.
2102
2103 (define_expand "call_value"
2104 [(set (match_operand 0 "" "")
2105 (call (match_operand:QI 1 "call_expander_operand" "")
2106 (match_operand:HI 2 "general_operand" "")))]
2107 ""
2108 {
2109 if (!register_operand (XEXP (operands[1], 0), Pmode)
2110 && GET_CODE (XEXP (operands[1], 0)) != SYMBOL_REF)
2111 XEXP (operands[1], 0) = force_reg (Pmode, XEXP (operands[1], 0));
2112 })
2113
2114 (define_insn "call_value_insn"
2115 [(set (match_operand 0 "" "=r")
2116 (call (mem:QI (match_operand 1 "call_insn_operand" "Cr"))
2117 (match_operand:HI 2 "general_operand" "g")))]
2118 ""
2119 {
2120 rtx xoperands[2];
2121 gcc_assert (GET_MODE (operands[1]) == Pmode);
2122 xoperands[0] = operands[0];
2123 xoperands[1] = gen_rtx_MEM (QImode, operands[1]);
2124 if (GET_CODE (XEXP (xoperands[1], 0)) == SYMBOL_REF
2125 && (SYMBOL_REF_FLAGS (XEXP (xoperands[1], 0)) & SYMBOL_FLAG_FUNCVEC_FUNCTION))
2126 output_asm_insn ("jsr\\t@%1:8", xoperands);
2127 else
2128 output_asm_insn ("jsr\\t%1", xoperands);
2129 return "";
2130 }
2131 [(set_attr "type" "call")
2132 (set (attr "length")
2133 (if_then_else (match_operand:QI 0 "small_call_insn_operand" "")
2134 (const_int 2)
2135 (const_int 4)))])
2136
2137 (define_insn "nop"
2138 [(const_int 0)]
2139 ""
2140 "nop"
2141 [(set_attr "cc" "none")
2142 (set_attr "length" "2")])
2143 \f
2144 ;; ----------------------------------------------------------------------
2145 ;; PROLOGUE/EPILOGUE-RELATED INSTRUCTIONS
2146 ;; ----------------------------------------------------------------------
2147
2148 (define_expand "push_h8300"
2149 [(set (mem:HI (pre_dec:HI (reg:HI SP_REG)))
2150 (match_operand:HI 0 "register_operand" ""))]
2151 "TARGET_H8300"
2152 "")
2153
2154 (define_expand "push_h8300hs_advanced"
2155 [(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
2156 (match_operand:SI 0 "register_operand" ""))]
2157 "TARGET_H8300H && TARGET_H8300S && !TARGET_NORMAL_MODE"
2158 "")
2159
2160 (define_expand "push_h8300hs_normal"
2161 [(set (mem:SI (pre_dec:HI (reg:HI SP_REG)))
2162 (match_operand:SI 0 "register_operand" ""))]
2163 "TARGET_H8300H && TARGET_H8300S && TARGET_NORMAL_MODE"
2164 "")
2165
2166 (define_expand "pop_h8300"
2167 [(set (match_operand:HI 0 "register_operand" "")
2168 (mem:HI (post_inc:HI (reg:HI SP_REG))))]
2169 "TARGET_H8300"
2170 "")
2171
2172 (define_expand "pop_h8300hs_advanced"
2173 [(set (match_operand:SI 0 "register_operand" "")
2174 (mem:SI (post_inc:SI (reg:SI SP_REG))))]
2175 "TARGET_H8300H && TARGET_H8300S && !TARGET_NORMAL_MODE"
2176 "")
2177
2178 (define_expand "pop_h8300hs_normal"
2179 [(set (match_operand:SI 0 "register_operand" "")
2180 (mem:SI (post_inc:HI (reg:HI SP_REG))))]
2181 "TARGET_H8300H && TARGET_H8300S && TARGET_NORMAL_MODE"
2182 "")
2183
2184 (define_insn "ldm_h8300sx"
2185 [(match_parallel 0 "h8300_ldm_parallel"
2186 [(set (match_operand:SI 1 "register_operand" "")
2187 (match_operand:SI 2 "memory_operand" ""))])]
2188 "TARGET_H8300S"
2189 {
2190 operands[3] = SET_DEST (XVECEXP (operands[0], 0,
2191 XVECLEN (operands[0], 0) - 2));
2192 return "ldm.l\t@er7+,%S1-%S3";
2193 }
2194 [(set_attr "cc" "none")
2195 (set_attr "length" "4")])
2196
2197 (define_insn "stm_h8300sx"
2198 [(match_parallel 0 "h8300_stm_parallel"
2199 [(set (match_operand:SI 1 "memory_operand" "")
2200 (match_operand:SI 2 "register_operand" ""))])]
2201 "TARGET_H8300S"
2202 {
2203 operands[3] = SET_SRC (XVECEXP (operands[0], 0,
2204 XVECLEN (operands[0], 0) - 2));
2205 return "stm.l\t%S2-%S3,@-er7";
2206 }
2207 [(set_attr "cc" "none")
2208 (set_attr "length" "4")])
2209
2210 (define_insn "return_h8sx"
2211 [(match_parallel 0 "h8300_return_parallel"
2212 [(return)
2213 (set (match_operand:SI 1 "register_operand" "")
2214 (match_operand:SI 2 "memory_operand" ""))])]
2215 "TARGET_H8300SX"
2216 {
2217 operands[3] = SET_DEST (XVECEXP (operands[0], 0,
2218 XVECLEN (operands[0], 0) - 2));
2219 if (h8300_current_function_interrupt_function_p ()
2220 || h8300_current_function_monitor_function_p ())
2221 return "rte/l\t%S1-%S3";
2222 else
2223 return "rts/l\t%S1-%S3";
2224 }
2225 [(set_attr "cc" "none")
2226 (set_attr "can_delay" "no")
2227 (set_attr "length" "2")])
2228
2229 (define_expand "return"
2230 [(return)]
2231 "h8300_can_use_return_insn_p ()"
2232 "")
2233
2234 (define_insn "*return_1"
2235 [(return)]
2236 "reload_completed"
2237 {
2238 if (h8300_current_function_interrupt_function_p ()
2239 || h8300_current_function_monitor_function_p ())
2240 return "rte";
2241 else
2242 return "rts";
2243 }
2244 [(set_attr "cc" "none")
2245 (set_attr "can_delay" "no")
2246 (set_attr "length" "2")])
2247
2248 (define_expand "prologue"
2249 [(const_int 0)]
2250 ""
2251 {
2252 h8300_expand_prologue ();
2253 DONE;
2254 })
2255
2256 (define_expand "epilogue"
2257 [(return)]
2258 ""
2259 {
2260 h8300_expand_epilogue ();
2261 DONE;
2262 })
2263
2264 (define_insn "monitor_prologue"
2265 [(unspec_volatile [(const_int 0)] UNSPEC_MONITOR)]
2266 ""
2267 {
2268 if (TARGET_H8300)
2269 return "subs\\t#2,r7\;mov.w\\tr0,@-r7\;stc\\tccr,r0l\;mov.b\tr0l,@(2,r7)\;mov.w\\t@r7+,r0\;orc\t#128,ccr";
2270 else if (TARGET_H8300H && TARGET_NORMAL_MODE)
2271 return "subs\\t#2,er7\;mov.l\\ter0,@-er7\;stc\\tccr,r0l\;mov.b\\tr0l,@(4,er7)\;mov.l\\t@er7+,er0\;orc\\t#128,ccr";
2272 else if (TARGET_H8300H)
2273 return "mov.l\\ter0,@-er7\;stc\\tccr,r0l\;mov.b\\tr0l,@(4,er7)\;mov.l\\t@er7+,er0\;orc\\t#128,ccr";
2274 else if (TARGET_H8300S && TARGET_NEXR )
2275 return "mov.l\\ter0,@-er7\;stc\tccr,r0l\;mov.b\tr0l,@(4,er7)\;mov.l\\t@er7+,er0\;orc\t#128,ccr";
2276 else if (TARGET_H8300S && TARGET_NEXR && TARGET_NORMAL_MODE)
2277 return "subs\\t#2,er7\;mov.l\\ter0,@-er7\;stc\tccr,r0l\;mov.b\tr0l,@(4,er7)\;mov.l\\t@er7+,er0\;orc\t#128,ccr";
2278 else if (TARGET_H8300S && TARGET_NORMAL_MODE)
2279 return "subs\\t#2,er7\;stc\texr,@-er7\;mov.l\\ter0,@-er7\;stc\tccr,r0l\;mov.b\tr0l,@(6,er7)\;mov.l\\t@er7+,er0\;orc\t#128,ccr";
2280 else if (TARGET_H8300S)
2281 return "stc\texr,@-er7\;mov.l\\ter0,@-er7\;stc\tccr,r0l\;mov.b\tr0l,@(6,er7)\;mov.l\\t@er7+,er0\;orc\t#128,ccr";
2282 gcc_unreachable ();
2283 }
2284 [(set_attr "length" "20")])
2285 \f
2286 ;; ----------------------------------------------------------------------
2287 ;; EXTEND INSTRUCTIONS
2288 ;; ----------------------------------------------------------------------
2289
2290 (define_expand "zero_extendqi<mode>2"
2291 [(set (match_operand:HSI 0 "register_operand" "")
2292 (zero_extend:HSI (match_operand:QI 1 "general_operand_src" "")))]
2293 ""
2294 {
2295 if (TARGET_H8300SX)
2296 operands[1] = force_reg (QImode, operands[1]);
2297 })
2298
2299 (define_insn "*zero_extendqihi2_h8300"
2300 [(set (match_operand:HI 0 "register_operand" "=r,r")
2301 (zero_extend:HI (match_operand:QI 1 "general_operand_src" "0,g>")))]
2302 "TARGET_H8300"
2303 "@
2304 mov.b #0,%t0
2305 #"
2306 [(set_attr "length" "2,10")])
2307
2308 (define_insn "*zero_extendqihi2_h8300hs"
2309 [(set (match_operand:HI 0 "register_operand" "=r,r")
2310 (zero_extend:HI (match_operand:QI 1 "general_operand_src" "0,g>")))]
2311 "TARGET_H8300H || TARGET_H8300S"
2312 "@
2313 extu.w %T0
2314 #"
2315 [(set_attr "length" "2,10")
2316 (set_attr "cc" "set_znv,set_znv")])
2317
2318 ;; Split the zero extension of a general operand (actually a memory
2319 ;; operand) into a load of the operand and the actual zero extension
2320 ;; so that 1) the length will be accurate, and 2) the zero extensions
2321 ;; appearing at the end of basic blocks may be merged.
2322
2323 (define_split
2324 [(set (match_operand:HI 0 "register_operand" "")
2325 (zero_extend:HI (match_operand:QI 1 "general_operand_src" "")))]
2326 "reload_completed"
2327 [(set (match_dup 2)
2328 (match_dup 1))
2329 (set (match_dup 0)
2330 (zero_extend:HI (match_dup 2)))]
2331 {
2332 operands[2] = gen_rtx_REG (QImode, REGNO (operands[0]));
2333 })
2334
2335
2336 (define_insn "*zero_extendqisi2_h8300"
2337 [(set (match_operand:SI 0 "register_operand" "=r,r")
2338 (zero_extend:SI (match_operand:QI 1 "general_operand_src" "0,g>")))]
2339 "TARGET_H8300"
2340 "@
2341 mov.b #0,%x0\;sub.w %e0,%e0
2342 mov.b %R1,%w0\;mov.b #0,%x0\;sub.w %e0,%e0"
2343 [(set_attr "length" "4,8")])
2344
2345 (define_insn "*zero_extendqisi2_h8300hs"
2346 [(set (match_operand:SI 0 "register_operand" "=r,r")
2347 (zero_extend:SI (match_operand:QI 1 "general_operand_src" "0,g>")))]
2348 "(TARGET_H8300H || TARGET_H8300S) && !TARGET_H8300SX"
2349 "#")
2350
2351 (define_split
2352 [(set (match_operand:SI 0 "register_operand" "")
2353 (zero_extend:SI (match_operand:QI 1 "general_operand_src" "")))]
2354 "(TARGET_H8300H || TARGET_H8300S) && !TARGET_H8300SX
2355 && reg_overlap_mentioned_p (operands[0], operands[1])
2356 && reload_completed"
2357 [(set (match_dup 2)
2358 (match_dup 1))
2359 (set (match_dup 3)
2360 (zero_extend:HI (match_dup 2)))
2361 (set (match_dup 0)
2362 (zero_extend:SI (match_dup 3)))]
2363 {
2364 operands[2] = gen_lowpart (QImode, operands[0]);
2365 operands[3] = gen_lowpart (HImode, operands[0]);
2366 })
2367
2368 (define_split
2369 [(set (match_operand:SI 0 "register_operand" "")
2370 (zero_extend:SI (match_operand:QI 1 "general_operand_src" "")))]
2371 "(TARGET_H8300H || TARGET_H8300S) && !TARGET_H8300SX
2372 && !reg_overlap_mentioned_p (operands[0], operands[1])
2373 && reload_completed"
2374 [(set (match_dup 0)
2375 (const_int 0))
2376 (set (strict_low_part (match_dup 2))
2377 (match_dup 1))]
2378 {
2379 operands[2] = gen_rtx_REG (QImode, REGNO (operands[0]));
2380 })
2381
2382 (define_insn "*zero_extendqisi2_h8sx"
2383 [(set (match_operand:SI 0 "register_operand" "=r")
2384 (zero_extend:SI (match_operand:QI 1 "register_operand" "0")))]
2385 "TARGET_H8300SX"
2386 "extu.l\t#2,%0"
2387 [(set_attr "length" "2")
2388 (set_attr "cc" "set_znv")])
2389
2390 (define_expand "zero_extendhisi2"
2391 [(set (match_operand:SI 0 "register_operand" "")
2392 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
2393 ""
2394 "")
2395
2396 ;; %e prints the high part of a CONST_INT, not the low part. Arggh.
2397 (define_insn "*zero_extendhisi2_h8300"
2398 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
2399 (zero_extend:SI (match_operand:HI 1 "general_operand_src" "0,i,g>")))]
2400 "TARGET_H8300"
2401 "@
2402 sub.w %e0,%e0
2403 mov.w %f1,%f0\;sub.w %e0,%e0
2404 mov.w %e1,%f0\;sub.w %e0,%e0"
2405 [(set_attr "length" "2,4,6")])
2406
2407 (define_insn "*zero_extendhisi2_h8300hs"
2408 [(set (match_operand:SI 0 "register_operand" "=r")
2409 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))]
2410 "TARGET_H8300H || TARGET_H8300S"
2411 "extu.l %S0"
2412 [(set_attr "length" "2")
2413 (set_attr "cc" "set_znv")])
2414
2415 (define_expand "extendqi<mode>2"
2416 [(set (match_operand:HSI 0 "register_operand" "")
2417 (sign_extend:HSI (match_operand:QI 1 "register_operand" "")))]
2418 ""
2419 "")
2420
2421 (define_insn "*extendqihi2_h8300"
2422 [(set (match_operand:HI 0 "register_operand" "=r,r")
2423 (sign_extend:HI (match_operand:QI 1 "general_operand_src" "0,g>")))]
2424 "TARGET_H8300"
2425 "@
2426 bld #7,%s0\;subx %t0,%t0
2427 mov.b %R1,%s0\;bld #7,%s0\;subx %t0,%t0"
2428 [(set_attr "length" "4,8")])
2429
2430 (define_insn "*extendqihi2_h8300hs"
2431 [(set (match_operand:HI 0 "register_operand" "=r")
2432 (sign_extend:HI (match_operand:QI 1 "register_operand" "0")))]
2433 "TARGET_H8300H || TARGET_H8300S"
2434 "exts.w %T0"
2435 [(set_attr "length" "2")
2436 (set_attr "cc" "set_znv")])
2437
2438 (define_insn "*extendqisi2_h8300"
2439 [(set (match_operand:SI 0 "register_operand" "=r,r")
2440 (sign_extend:SI (match_operand:QI 1 "general_operand_src" "0,g>")))]
2441 "TARGET_H8300"
2442 "@
2443 bld #7,%w0\;subx %x0,%x0\;subx %y0,%y0\;subx %z0,%z0
2444 mov.b %R1,%w0\;bld #7,%w0\;subx %x0,%x0\;subx %y0,%y0\;subx %z0,%z0"
2445 [(set_attr "length" "8,12")])
2446
2447 ;; The following pattern is needed because without the pattern, the
2448 ;; combiner would split (sign_extend:SI (reg:QI)) into two 24-bit
2449 ;; shifts, one ashift and one ashiftrt.
2450
2451 (define_insn_and_split "*extendqisi2_h8300hs"
2452 [(set (match_operand:SI 0 "register_operand" "=r")
2453 (sign_extend:SI (match_operand:QI 1 "register_operand" "0")))]
2454 "(TARGET_H8300H || TARGET_H8300S) && !TARGET_H8300SX"
2455 "#"
2456 "&& reload_completed"
2457 [(set (match_dup 2)
2458 (sign_extend:HI (match_dup 1)))
2459 (set (match_dup 0)
2460 (sign_extend:SI (match_dup 2)))]
2461 {
2462 operands[2] = gen_rtx_REG (HImode, REGNO (operands[0]));
2463 })
2464
2465 (define_insn "*extendqisi2_h8sx"
2466 [(set (match_operand:SI 0 "register_operand" "=r")
2467 (sign_extend:SI (match_operand:QI 1 "register_operand" "0")))]
2468 "TARGET_H8300SX"
2469 "exts.l\t#2,%0"
2470 [(set_attr "length" "2")
2471 (set_attr "cc" "set_znv")])
2472
2473 (define_expand "extendhisi2"
2474 [(set (match_operand:SI 0 "register_operand" "")
2475 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
2476 ""
2477 "")
2478
2479 (define_insn "*extendhisi2_h8300"
2480 [(set (match_operand:SI 0 "register_operand" "=r,r")
2481 (sign_extend:SI (match_operand:HI 1 "general_operand_src" "0,g>")))]
2482 "TARGET_H8300"
2483 "@
2484 bld #7,%x0\;subx %y0,%y0\;subx %z0,%z0
2485 mov.w %T1,%f0\;bld #7,%x0\;subx %y0,%y0\;subx %z0,%z0"
2486 [(set_attr "length" "6,10")])
2487
2488 (define_insn "*extendhisi2_h8300hs"
2489 [(set (match_operand:SI 0 "register_operand" "=r")
2490 (sign_extend:SI (match_operand:HI 1 "register_operand" "0")))]
2491 "TARGET_H8300H || TARGET_H8300S"
2492 "exts.l %S0"
2493 [(set_attr "length" "2")
2494 (set_attr "cc" "set_znv")])
2495 \f
2496 ;; ----------------------------------------------------------------------
2497 ;; SHIFTS
2498 ;; ----------------------------------------------------------------------
2499 ;;
2500 ;; We make some attempt to provide real efficient shifting. One example is
2501 ;; doing an 8-bit shift of a 16-bit value by moving a byte reg into the other
2502 ;; reg and moving 0 into the former reg.
2503 ;;
2504 ;; We also try to achieve this in a uniform way. IE: We don't try to achieve
2505 ;; this in both rtl and at insn emit time. Ideally, we'd use rtl as that would
2506 ;; give the optimizer more cracks at the code. However, we wish to do things
2507 ;; like optimizing shifting the sign bit to bit 0 by rotating the other way.
2508 ;; There is rtl to handle this (rotate + and), but the H8/300 doesn't handle
2509 ;; 16-bit rotates. Also, if we emit complicated rtl, combine may not be able
2510 ;; to detect cases it can optimize.
2511 ;;
2512 ;; For these and other fuzzy reasons, I've decided to go the less pretty but
2513 ;; easier "do it at insn emit time" route.
2514
2515 ;; QI BIT SHIFTS
2516
2517 (define_expand "ashlqi3"
2518 [(set (match_operand:QI 0 "register_operand" "")
2519 (ashift:QI (match_operand:QI 1 "register_operand" "")
2520 (match_operand:QI 2 "nonmemory_operand" "")))]
2521 ""
2522 {
2523 if (expand_a_shift (QImode, ASHIFT, operands))
2524 DONE;
2525 })
2526
2527 (define_expand "ashrqi3"
2528 [(set (match_operand:QI 0 "register_operand" "")
2529 (ashiftrt:QI (match_operand:QI 1 "register_operand" "")
2530 (match_operand:QI 2 "nonmemory_operand" "")))]
2531 ""
2532 {
2533 if (expand_a_shift (QImode, ASHIFTRT, operands))
2534 DONE;
2535 })
2536
2537 (define_expand "lshrqi3"
2538 [(set (match_operand:QI 0 "register_operand" "")
2539 (lshiftrt:QI (match_operand:QI 1 "register_operand" "")
2540 (match_operand:QI 2 "nonmemory_operand" "")))]
2541 ""
2542 {
2543 if (expand_a_shift (QImode, LSHIFTRT, operands))
2544 DONE;
2545 })
2546
2547 (define_insn ""
2548 [(set (match_operand:QI 0 "h8300_dst_operand" "=rQ")
2549 (match_operator:QI 3 "h8sx_unary_shift_operator"
2550 [(match_operand:QI 1 "h8300_dst_operand" "0")
2551 (match_operand:QI 2 "const_int_operand" "")]))]
2552 "h8300_operands_match_p (operands)"
2553 {
2554 return output_h8sx_shift (operands, 'b', 'X');
2555 }
2556 [(set_attr "length_table" "unary")
2557 (set_attr "cc" "set_znv")])
2558
2559 (define_insn ""
2560 [(set (match_operand:QI 0 "register_operand" "=r")
2561 (match_operator:QI 3 "h8sx_binary_shift_operator"
2562 [(match_operand:QI 1 "register_operand" "0")
2563 (match_operand:QI 2 "nonmemory_operand" "r P3>X")]))]
2564 ""
2565 {
2566 return output_h8sx_shift (operands, 'b', 'X');
2567 }
2568 [(set_attr "length" "4")
2569 (set_attr "cc" "set_znv")])
2570
2571 (define_insn "*shiftqi"
2572 [(set (match_operand:QI 0 "register_operand" "=r,r")
2573 (match_operator:QI 3 "nshift_operator"
2574 [(match_operand:QI 1 "register_operand" "0,0")
2575 (match_operand:QI 2 "nonmemory_operand" "R,rn")]))
2576 (clobber (match_scratch:QI 4 "=X,&r"))]
2577 ""
2578 {
2579 return output_a_shift (operands);
2580 }
2581 [(set (attr "length")
2582 (symbol_ref "compute_a_shift_length (insn, operands)"))
2583 (set (attr "cc")
2584 (symbol_ref "compute_a_shift_cc (insn, operands)"))])
2585
2586 ;; HI BIT SHIFTS
2587
2588 (define_expand "ashlhi3"
2589 [(set (match_operand:HI 0 "register_operand" "")
2590 (ashift:HI (match_operand:HI 1 "register_operand" "")
2591 (match_operand:QI 2 "nonmemory_operand" "")))]
2592 ""
2593 {
2594 if (expand_a_shift (HImode, ASHIFT, operands))
2595 DONE;
2596 })
2597
2598 (define_expand "lshrhi3"
2599 [(set (match_operand:HI 0 "register_operand" "")
2600 (lshiftrt:HI (match_operand:HI 1 "register_operand" "")
2601 (match_operand:QI 2 "nonmemory_operand" "")))]
2602 ""
2603 {
2604 if (expand_a_shift (HImode, LSHIFTRT, operands))
2605 DONE;
2606 })
2607
2608 (define_expand "ashrhi3"
2609 [(set (match_operand:HI 0 "register_operand" "")
2610 (ashiftrt:HI (match_operand:HI 1 "register_operand" "")
2611 (match_operand:QI 2 "nonmemory_operand" "")))]
2612 ""
2613 {
2614 if (expand_a_shift (HImode, ASHIFTRT, operands))
2615 DONE;
2616 })
2617
2618 (define_insn ""
2619 [(set (match_operand:HI 0 "h8300_dst_operand" "=rQ")
2620 (match_operator:HI 3 "h8sx_unary_shift_operator"
2621 [(match_operand:HI 1 "h8300_dst_operand" "0")
2622 (match_operand:QI 2 "const_int_operand" "")]))]
2623 "h8300_operands_match_p (operands)"
2624 {
2625 return output_h8sx_shift (operands, 'w', 'T');
2626 }
2627 [(set_attr "length_table" "unary")
2628 (set_attr "cc" "set_znv")])
2629
2630 (define_insn ""
2631 [(set (match_operand:HI 0 "register_operand" "=r")
2632 (match_operator:HI 3 "h8sx_binary_shift_operator"
2633 [(match_operand:HI 1 "register_operand" "0")
2634 (match_operand:QI 2 "nonmemory_operand" "r P4>X")]))]
2635 ""
2636 {
2637 return output_h8sx_shift (operands, 'w', 'T');
2638 }
2639 [(set_attr "length" "4")
2640 (set_attr "cc" "set_znv")])
2641
2642 (define_insn "*shifthi"
2643 [(set (match_operand:HI 0 "register_operand" "=r,r")
2644 (match_operator:HI 3 "nshift_operator"
2645 [(match_operand:HI 1 "register_operand" "0,0")
2646 (match_operand:QI 2 "nonmemory_operand" "S,rn")]))
2647 (clobber (match_scratch:QI 4 "=X,&r"))]
2648 ""
2649 {
2650 return output_a_shift (operands);
2651 }
2652 [(set (attr "length")
2653 (symbol_ref "compute_a_shift_length (insn, operands)"))
2654 (set (attr "cc")
2655 (symbol_ref "compute_a_shift_cc (insn, operands)"))])
2656
2657 ;; SI BIT SHIFTS
2658
2659 (define_expand "ashlsi3"
2660 [(set (match_operand:SI 0 "register_operand" "")
2661 (ashift:SI (match_operand:SI 1 "register_operand" "")
2662 (match_operand:QI 2 "nonmemory_operand" "")))]
2663 ""
2664 {
2665 if (expand_a_shift (SImode, ASHIFT, operands))
2666 DONE;
2667 })
2668
2669 (define_expand "lshrsi3"
2670 [(set (match_operand:SI 0 "register_operand" "")
2671 (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
2672 (match_operand:QI 2 "nonmemory_operand" "")))]
2673 ""
2674 {
2675 if (expand_a_shift (SImode, LSHIFTRT, operands))
2676 DONE;
2677 })
2678
2679 (define_expand "ashrsi3"
2680 [(set (match_operand:SI 0 "register_operand" "")
2681 (ashiftrt:SI (match_operand:SI 1 "register_operand" "")
2682 (match_operand:QI 2 "nonmemory_operand" "")))]
2683 ""
2684 {
2685 if (expand_a_shift (SImode, ASHIFTRT, operands))
2686 DONE;
2687 })
2688
2689 (define_insn ""
2690 [(set (match_operand:SI 0 "h8300_dst_operand" "=rQ")
2691 (match_operator:SI 3 "h8sx_unary_shift_operator"
2692 [(match_operand:SI 1 "h8300_dst_operand" "0")
2693 (match_operand:QI 2 "const_int_operand" "")]))]
2694 "h8300_operands_match_p (operands)"
2695 {
2696 return output_h8sx_shift (operands, 'l', 'S');
2697 }
2698 [(set_attr "length_table" "unary")
2699 (set_attr "cc" "set_znv")])
2700
2701 (define_insn ""
2702 [(set (match_operand:SI 0 "register_operand" "=r")
2703 (match_operator:SI 3 "h8sx_binary_shift_operator"
2704 [(match_operand:SI 1 "register_operand" "0")
2705 (match_operand:QI 2 "nonmemory_operand" "r P5>X")]))]
2706 ""
2707 {
2708 return output_h8sx_shift (operands, 'l', 'S');
2709 }
2710 [(set_attr "length" "4")
2711 (set_attr "cc" "set_znv")])
2712
2713 (define_insn "*shiftsi"
2714 [(set (match_operand:SI 0 "register_operand" "=r,r")
2715 (match_operator:SI 3 "nshift_operator"
2716 [(match_operand:SI 1 "register_operand" "0,0")
2717 (match_operand:QI 2 "nonmemory_operand" "T,rn")]))
2718 (clobber (match_scratch:QI 4 "=X,&r"))]
2719 ""
2720 {
2721 return output_a_shift (operands);
2722 }
2723 [(set (attr "length")
2724 (symbol_ref "compute_a_shift_length (insn, operands)"))
2725 (set (attr "cc")
2726 (symbol_ref "compute_a_shift_cc (insn, operands)"))])
2727
2728 ;; Split a variable shift into a loop. If the register containing
2729 ;; the shift count dies, then we just use that register.
2730
2731 (define_split
2732 [(set (match_operand 0 "register_operand" "")
2733 (match_operator 2 "nshift_operator"
2734 [(match_dup 0)
2735 (match_operand:QI 1 "register_operand" "")]))
2736 (clobber (match_operand:QI 3 "register_operand" ""))]
2737 "epilogue_completed
2738 && find_regno_note (insn, REG_DEAD, REGNO (operands[1]))"
2739 [(set (cc0) (compare (match_dup 1) (const_int 0)))
2740 (set (pc)
2741 (if_then_else (le (cc0) (const_int 0))
2742 (label_ref (match_dup 5))
2743 (pc)))
2744 (match_dup 4)
2745 (parallel
2746 [(set (match_dup 0)
2747 (match_op_dup 2 [(match_dup 0) (const_int 1)]))
2748 (clobber (scratch:QI))])
2749 (set (match_dup 1) (plus:QI (match_dup 1) (const_int -1)))
2750 (set (cc0) (compare (match_dup 1) (const_int 0)))
2751 (set (pc)
2752 (if_then_else (ne (cc0) (const_int 0))
2753 (label_ref (match_dup 4))
2754 (pc)))
2755 (match_dup 5)]
2756 {
2757 operands[4] = gen_label_rtx ();
2758 operands[5] = gen_label_rtx ();
2759 })
2760
2761 (define_split
2762 [(set (match_operand 0 "register_operand" "")
2763 (match_operator 2 "nshift_operator"
2764 [(match_dup 0)
2765 (match_operand:QI 1 "register_operand" "")]))
2766 (clobber (match_operand:QI 3 "register_operand" ""))]
2767 "epilogue_completed
2768 && !find_regno_note (insn, REG_DEAD, REGNO (operands[1]))"
2769 [(set (match_dup 3)
2770 (match_dup 1))
2771 (set (cc0) (compare (match_dup 3) (const_int 0)))
2772 (set (pc)
2773 (if_then_else (le (cc0) (const_int 0))
2774 (label_ref (match_dup 5))
2775 (pc)))
2776 (match_dup 4)
2777 (parallel
2778 [(set (match_dup 0)
2779 (match_op_dup 2 [(match_dup 0) (const_int 1)]))
2780 (clobber (scratch:QI))])
2781 (set (match_dup 3) (plus:QI (match_dup 3) (const_int -1)))
2782 (set (cc0) (compare (match_dup 3) (const_int 0)))
2783 (set (pc)
2784 (if_then_else (ne (cc0) (const_int 0))
2785 (label_ref (match_dup 4))
2786 (pc)))
2787 (match_dup 5)]
2788 {
2789 operands[4] = gen_label_rtx ();
2790 operands[5] = gen_label_rtx ();
2791 })
2792 \f
2793 ;; ----------------------------------------------------------------------
2794 ;; ROTATIONS
2795 ;; ----------------------------------------------------------------------
2796
2797 (define_expand "rotl<mode>3"
2798 [(set (match_operand:QHI 0 "register_operand" "")
2799 (rotate:QHI (match_operand:QHI 1 "register_operand" "")
2800 (match_operand:QI 2 "nonmemory_operand" "")))]
2801 ""
2802 {
2803 if (expand_a_rotate (operands))
2804 DONE;
2805 })
2806
2807 (define_insn "rotl<mode>3_1"
2808 [(set (match_operand:QHI 0 "register_operand" "=r")
2809 (rotate:QHI (match_operand:QHI 1 "register_operand" "0")
2810 (match_operand:QI 2 "immediate_operand" "")))]
2811 ""
2812 {
2813 return output_a_rotate (ROTATE, operands);
2814 }
2815 [(set (attr "length")
2816 (symbol_ref "compute_a_rotate_length (operands)"))])
2817
2818 (define_expand "rotlsi3"
2819 [(set (match_operand:SI 0 "register_operand" "")
2820 (rotate:SI (match_operand:SI 1 "register_operand" "")
2821 (match_operand:QI 2 "nonmemory_operand" "")))]
2822 "TARGET_H8300H || TARGET_H8300S"
2823 {
2824 if (expand_a_rotate (operands))
2825 DONE;
2826 })
2827
2828 (define_insn "rotlsi3_1"
2829 [(set (match_operand:SI 0 "register_operand" "=r")
2830 (rotate:SI (match_operand:SI 1 "register_operand" "0")
2831 (match_operand:QI 2 "immediate_operand" "")))]
2832 "TARGET_H8300H || TARGET_H8300S"
2833 {
2834 return output_a_rotate (ROTATE, operands);
2835 }
2836 [(set (attr "length")
2837 (symbol_ref "compute_a_rotate_length (operands)"))])
2838 \f
2839 ;; -----------------------------------------------------------------
2840 ;; BIT FIELDS
2841 ;; -----------------------------------------------------------------
2842 ;; The H8/300 has given 1/8th of its opcode space to bitfield
2843 ;; instructions so let's use them as well as we can.
2844
2845 ;; You'll never believe all these patterns perform one basic action --
2846 ;; load a bit from the source, optionally invert the bit, then store it
2847 ;; in the destination (which is known to be zero).
2848 ;;
2849 ;; Combine obviously need some work to better identify this situation and
2850 ;; canonicalize the form better.
2851
2852 ;;
2853 ;; Normal loads with a 16bit destination.
2854 ;;
2855
2856 (define_insn ""
2857 [(set (match_operand:HI 0 "register_operand" "=&r")
2858 (zero_extract:HI (match_operand:HI 1 "register_operand" "r")
2859 (const_int 1)
2860 (match_operand:HI 2 "immediate_operand" "n")))]
2861 "TARGET_H8300"
2862 "sub.w %0,%0\;bld %Z2,%Y1\;bst #0,%X0"
2863 [(set_attr "length" "6")])
2864
2865 ;;
2866 ;; Inverted loads with a 16bit destination.
2867 ;;
2868
2869 (define_insn ""
2870 [(set (match_operand:HI 0 "register_operand" "=&r")
2871 (zero_extract:HI (xor:HI (match_operand:HI 1 "register_operand" "r")
2872 (match_operand:HI 3 "const_int_operand" "n"))
2873 (const_int 1)
2874 (match_operand:HI 2 "const_int_operand" "n")))]
2875 "(TARGET_H8300 || TARGET_H8300SX)
2876 && (1 << INTVAL (operands[2])) == INTVAL (operands[3])"
2877 "sub.w %0,%0\;bild %Z2,%Y1\;bst #0,%X0"
2878 [(set_attr "length" "8")])
2879
2880 ;;
2881 ;; Normal loads with a 32bit destination.
2882 ;;
2883
2884 (define_insn "*extzv_1_r_h8300"
2885 [(set (match_operand:SI 0 "register_operand" "=&r")
2886 (zero_extract:SI (match_operand:HI 1 "register_operand" "r")
2887 (const_int 1)
2888 (match_operand 2 "const_int_operand" "n")))]
2889 "TARGET_H8300 && INTVAL (operands[2]) < 16"
2890 {
2891 return output_simode_bld (0, operands);
2892 }
2893 [(set_attr "length" "8")])
2894
2895 (define_insn "*extzv_1_r_h8300hs"
2896 [(set (match_operand:SI 0 "register_operand" "=r,r")
2897 (zero_extract:SI (match_operand:SI 1 "register_operand" "?0,r")
2898 (const_int 1)
2899 (match_operand 2 "const_int_operand" "n,n")))]
2900 "(TARGET_H8300H || TARGET_H8300S) && INTVAL (operands[2]) < 16"
2901 {
2902 return output_simode_bld (0, operands);
2903 }
2904 [(set_attr "cc" "set_znv,set_znv")
2905 (set_attr "length" "8,6")])
2906
2907 ;;
2908 ;; Inverted loads with a 32bit destination.
2909 ;;
2910
2911 (define_insn "*extzv_1_r_inv_h8300"
2912 [(set (match_operand:SI 0 "register_operand" "=&r")
2913 (zero_extract:SI (xor:HI (match_operand:HI 1 "register_operand" "r")
2914 (match_operand:HI 3 "const_int_operand" "n"))
2915 (const_int 1)
2916 (match_operand 2 "const_int_operand" "n")))]
2917 "TARGET_H8300 && INTVAL (operands[2]) < 16
2918 && (1 << INTVAL (operands[2])) == INTVAL (operands[3])"
2919 {
2920 return output_simode_bld (1, operands);
2921 }
2922 [(set_attr "length" "8")])
2923
2924 (define_insn "*extzv_1_r_inv_h8300hs"
2925 [(set (match_operand:SI 0 "register_operand" "=r,r")
2926 (zero_extract:SI (xor:SI (match_operand:SI 1 "register_operand" "?0,r")
2927 (match_operand 3 "const_int_operand" "n,n"))
2928 (const_int 1)
2929 (match_operand 2 "const_int_operand" "n,n")))]
2930 "(TARGET_H8300H || TARGET_H8300S) && INTVAL (operands[2]) < 16
2931 && (1 << INTVAL (operands[2])) == INTVAL (operands[3])"
2932 {
2933 return output_simode_bld (1, operands);
2934 }
2935 [(set_attr "cc" "set_znv,set_znv")
2936 (set_attr "length" "8,6")])
2937
2938 (define_expand "insv"
2939 [(set (zero_extract:HI (match_operand:HI 0 "general_operand" "")
2940 (match_operand:HI 1 "general_operand" "")
2941 (match_operand:HI 2 "general_operand" ""))
2942 (match_operand:HI 3 "general_operand" ""))]
2943 "TARGET_H8300 || TARGET_H8300SX"
2944 {
2945 if (TARGET_H8300SX)
2946 {
2947 if (GET_CODE (operands[1]) == CONST_INT
2948 && GET_CODE (operands[2]) == CONST_INT
2949 && INTVAL (operands[1]) <= 8
2950 && INTVAL (operands[2]) >= 0
2951 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 8
2952 && memory_operand (operands[0], GET_MODE (operands[0])))
2953 {
2954 /* If the source operand is zero, it's better to use AND rather
2955 than BFST. Likewise OR if the operand is all ones. */
2956 if (GET_CODE (operands[3]) == CONST_INT)
2957 {
2958 HOST_WIDE_INT mask = (1 << INTVAL (operands[1])) - 1;
2959 if ((INTVAL (operands[3]) & mask) == 0)
2960 FAIL;
2961 if ((INTVAL (operands[3]) & mask) == mask)
2962 FAIL;
2963 }
2964 if (! bit_memory_operand (operands[0], GET_MODE (operands[0])))
2965 {
2966 if (!can_create_pseudo_p ())
2967 FAIL;
2968 operands[0] = replace_equiv_address (operands[0], force_reg (Pmode,
2969 XEXP (operands[0], 0)));
2970 }
2971 operands[3] = gen_lowpart (QImode, operands[3]);
2972 if (! operands[3])
2973 FAIL;
2974 if (! register_operand (operands[3], QImode))
2975 {
2976 if (!can_create_pseudo_p ())
2977 FAIL;
2978 operands[3] = force_reg (QImode, operands[3]);
2979 }
2980 emit_insn (gen_bfst (adjust_address (operands[0], QImode, 0),
2981 operands[3], operands[1], operands[2]));
2982 DONE;
2983 }
2984 FAIL;
2985 }
2986
2987 /* We only have single bit bit-field instructions. */
2988 if (INTVAL (operands[1]) != 1)
2989 FAIL;
2990
2991 /* For now, we don't allow memory operands. */
2992 if (GET_CODE (operands[0]) == MEM
2993 || GET_CODE (operands[3]) == MEM)
2994 FAIL;
2995
2996 if (GET_CODE (operands[3]) != REG)
2997 operands[3] = force_reg (HImode, operands[3]);
2998 })
2999
3000 (define_insn ""
3001 [(set (zero_extract:HI (match_operand:HI 0 "register_operand" "+r")
3002 (const_int 1)
3003 (match_operand:HI 1 "immediate_operand" "n"))
3004 (match_operand:HI 2 "register_operand" "r"))]
3005 ""
3006 "bld #0,%R2\;bst %Z1,%Y0 ; i1"
3007 [(set_attr "length" "4")])
3008
3009 (define_expand "extzv"
3010 [(set (match_operand:HI 0 "register_operand" "")
3011 (zero_extract:HI (match_operand:HI 1 "bit_operand" "")
3012 (match_operand:HI 2 "general_operand" "")
3013 (match_operand:HI 3 "general_operand" "")))]
3014 "TARGET_H8300 || TARGET_H8300SX"
3015 {
3016 if (TARGET_H8300SX)
3017 {
3018 if (GET_CODE (operands[2]) == CONST_INT
3019 && GET_CODE (operands[3]) == CONST_INT
3020 && INTVAL (operands[2]) <= 8
3021 && INTVAL (operands[3]) >= 0
3022 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 8
3023 && memory_operand (operands[1], QImode))
3024 {
3025 rtx temp;
3026
3027 /* Optimize the case where we're extracting into a paradoxical
3028 subreg. It's only necessary to extend to the inner reg. */
3029 if (GET_CODE (operands[0]) == SUBREG
3030 && subreg_lowpart_p (operands[0])
3031 && (GET_MODE_SIZE (GET_MODE (SUBREG_REG (operands[0])))
3032 < GET_MODE_SIZE (GET_MODE (operands[0])))
3033 && (GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0])))
3034 == MODE_INT))
3035 operands[0] = SUBREG_REG (operands[0]);
3036
3037 if (!can_create_pseudo_p ())
3038 temp = gen_lowpart (QImode, operands[0]);
3039 else
3040 temp = gen_reg_rtx (QImode);
3041 if (! temp)
3042 FAIL;
3043 if (! bit_memory_operand (operands[1], QImode))
3044 {
3045 if (!can_create_pseudo_p ())
3046 FAIL;
3047 operands[1] = replace_equiv_address (operands[1],
3048 force_reg (Pmode, XEXP (operands[1], 0)));
3049 }
3050 emit_insn (gen_bfld (temp, operands[1], operands[2], operands[3]));
3051 convert_move (operands[0], temp, 1);
3052 DONE;
3053 }
3054 FAIL;
3055 }
3056
3057 /* We only have single bit bit-field instructions. */
3058 if (INTVAL (operands[2]) != 1)
3059 FAIL;
3060
3061 /* For now, we don't allow memory operands. */
3062 if (GET_CODE (operands[1]) == MEM)
3063 FAIL;
3064 })
3065
3066 ;; BAND, BOR, and BXOR patterns
3067
3068 (define_insn ""
3069 [(set (match_operand:HI 0 "bit_operand" "=Ur")
3070 (match_operator:HI 4 "bit_operator"
3071 [(zero_extract:HI (match_operand:HI 1 "register_operand" "r")
3072 (const_int 1)
3073 (match_operand:HI 2 "immediate_operand" "n"))
3074 (match_operand:HI 3 "bit_operand" "0")]))]
3075 ""
3076 "bld %Z2,%Y1\;b%c4 #0,%R0\;bst #0,%R0; bl1"
3077 [(set_attr "length" "6")])
3078
3079 (define_insn ""
3080 [(set (match_operand:HI 0 "bit_operand" "=Ur")
3081 (match_operator:HI 5 "bit_operator"
3082 [(zero_extract:HI (match_operand:HI 1 "register_operand" "r")
3083 (const_int 1)
3084 (match_operand:HI 2 "immediate_operand" "n"))
3085 (zero_extract:HI (match_operand:HI 3 "register_operand" "r")
3086 (const_int 1)
3087 (match_operand:HI 4 "immediate_operand" "n"))]))]
3088 ""
3089 "bld %Z2,%Y1\;b%c5 %Z4,%Y3\;bst #0,%R0; bl3"
3090 [(set_attr "length" "6")])
3091
3092 (define_insn "bfld"
3093 [(set (match_operand:QI 0 "register_operand" "=r")
3094 (zero_extract:QI (match_operand:QI 1 "bit_memory_operand" "WU")
3095 (match_operand:QI 2 "immediate_operand" "n")
3096 (match_operand:QI 3 "immediate_operand" "n")))]
3097 "TARGET_H8300SX && INTVAL (operands[2]) + INTVAL (operands[3]) <= 8"
3098 {
3099 operands[2] = GEN_INT ((1 << (INTVAL (operands[2]) + INTVAL (operands[3])))
3100 - (1 << INTVAL (operands[3])));
3101 return "bfld %2,%1,%R0";
3102 }
3103 [(set_attr "cc" "none_0hit")
3104 (set_attr "length_table" "bitfield")])
3105
3106 (define_insn "bfst"
3107 [(set (zero_extract:QI (match_operand:QI 0 "bit_memory_operand" "+WU")
3108 (match_operand:QI 2 "immediate_operand" "n")
3109 (match_operand:QI 3 "immediate_operand" "n"))
3110 (match_operand:QI 1 "register_operand" "r"))]
3111 "TARGET_H8300SX && INTVAL (operands[2]) + INTVAL (operands[3]) <= 8"
3112 {
3113 operands[2] = GEN_INT ((1 << (INTVAL (operands[2]) + INTVAL (operands[3])))
3114 - (1 << INTVAL (operands[3])));
3115 return "bfst %R1,%2,%0";
3116 }
3117 [(set_attr "cc" "none_0hit")
3118 (set_attr "length_table" "bitfield")])
3119
3120 (define_expand "cstoreqi4"
3121 [(use (match_operator 1 "eqne_operator"
3122 [(match_operand:QI 2 "h8300_dst_operand" "")
3123 (match_operand:QI 3 "h8300_src_operand" "")]))
3124 (clobber (match_operand:HI 0 "register_operand"))]
3125 "TARGET_H8300SX"
3126 {
3127 h8300_expand_store (operands);
3128 DONE;
3129 })
3130
3131 (define_expand "cstorehi4"
3132 [(use (match_operator 1 "eqne_operator"
3133 [(match_operand:HI 2 "h8300_dst_operand" "")
3134 (match_operand:HI 3 "h8300_src_operand" "")]))
3135 (clobber (match_operand:HI 0 "register_operand"))]
3136 "TARGET_H8300SX"
3137 {
3138 h8300_expand_store (operands);
3139 DONE;
3140 })
3141
3142 (define_expand "cstoresi4"
3143 [(use (match_operator 1 "eqne_operator"
3144 [(match_operand:SI 2 "h8300_dst_operand" "")
3145 (match_operand:SI 3 "h8300_src_operand" "")]))
3146 (clobber (match_operand:HI 0 "register_operand"))]
3147 "TARGET_H8300SX"
3148 {
3149 h8300_expand_store (operands);
3150 DONE;
3151 })
3152
3153 (define_insn "*bstzhireg"
3154 [(set (match_operand:HI 0 "register_operand" "=r")
3155 (match_operator:HI 1 "eqne_operator" [(cc0) (const_int 0)]))]
3156 "TARGET_H8300SX"
3157 "mulu.w #0,%T0\;b%k1 .Lh8BR%=\;inc.w #1,%T0\\n.Lh8BR%=:"
3158 [(set_attr "cc" "clobber")])
3159
3160 (define_insn_and_split "*cmpstz"
3161 [(set (zero_extract:QI (match_operand:QI 0 "bit_memory_operand" "+WU,WU")
3162 (const_int 1)
3163 (match_operand:QI 1 "immediate_operand" "n,n"))
3164 (match_operator:QI 2 "eqne_operator"
3165 [(match_operand 3 "h8300_dst_operand" "r,rQ")
3166 (match_operand 4 "h8300_src_operand" "I,rQi")]))]
3167 "TARGET_H8300SX
3168 && (GET_MODE (operands[3]) == GET_MODE (operands[4])
3169 || GET_CODE (operands[4]) == CONST_INT)
3170 && GET_MODE_CLASS (GET_MODE (operands[3])) == MODE_INT
3171 && GET_MODE_SIZE (GET_MODE (operands[3])) <= 4"
3172 "#"
3173 "reload_completed"
3174 [(set (cc0) (match_dup 5))
3175 (set (zero_extract:QI (match_dup 0) (const_int 1) (match_dup 1))
3176 (match_op_dup:QI 2 [(cc0) (const_int 0)]))]
3177 {
3178 operands[5] = gen_rtx_COMPARE (VOIDmode, operands[3], operands[4]);
3179 }
3180 [(set_attr "cc" "set_znv,compare")])
3181
3182 (define_insn "*bstz"
3183 [(set (zero_extract:QI (match_operand:QI 0 "bit_memory_operand" "+WU")
3184 (const_int 1)
3185 (match_operand:QI 1 "immediate_operand" "n"))
3186 (eq:QI (cc0) (const_int 0)))]
3187 "TARGET_H8300SX && reload_completed"
3188 "bstz %1,%0"
3189 [(set_attr "cc" "none_0hit")
3190 (set_attr "length_table" "unary")])
3191
3192 (define_insn "*bistz"
3193 [(set (zero_extract:QI (match_operand:QI 0 "bit_memory_operand" "+WU")
3194 (const_int 1)
3195 (match_operand:QI 1 "immediate_operand" "n"))
3196 (ne:QI (cc0) (const_int 0)))]
3197 "TARGET_H8300SX && reload_completed"
3198 "bistz %1,%0"
3199 [(set_attr "cc" "none_0hit")
3200 (set_attr "length_table" "unary")])
3201
3202 (define_insn_and_split "*cmpcondbset"
3203 [(set (match_operand:QI 0 "nonimmediate_operand" "=WU,WU")
3204 (if_then_else:QI (match_operator 1 "eqne_operator"
3205 [(match_operand 2 "h8300_dst_operand" "r,rQ")
3206 (match_operand 3 "h8300_src_operand" "I,rQi")])
3207 (ior:QI (match_operand:QI 4 "bit_memory_operand" "0,0")
3208 (match_operand:QI 5 "single_one_operand" "n,n"))
3209 (match_dup 4)))]
3210 "TARGET_H8300SX"
3211 "#"
3212 "reload_completed"
3213 [(set (cc0) (match_dup 6))
3214 (set (match_dup 0)
3215 (if_then_else:QI (match_op_dup 1 [(cc0) (const_int 0)])
3216 (ior:QI (match_dup 4) (match_dup 5))
3217 (match_dup 4)))]
3218 {
3219 operands[6] = gen_rtx_COMPARE (VOIDmode, operands[2], operands[3]);
3220 }
3221 [(set_attr "cc" "set_znv,compare")])
3222
3223 (define_insn "*condbset"
3224 [(set (match_operand:QI 0 "bit_memory_operand" "=WU")
3225 (if_then_else:QI (match_operator:QI 2 "eqne_operator"
3226 [(cc0) (const_int 0)])
3227 (ior:QI (match_operand:QI 3 "bit_memory_operand" "0")
3228 (match_operand:QI 1 "single_one_operand" "n"))
3229 (match_dup 3)))]
3230 "TARGET_H8300SX && reload_completed"
3231 "bset/%j2\t%V1,%0"
3232 [(set_attr "cc" "none_0hit")
3233 (set_attr "length_table" "logicb")])
3234
3235 (define_insn_and_split "*cmpcondbclr"
3236 [(set (match_operand:QI 0 "nonimmediate_operand" "=WU,WU")
3237 (if_then_else:QI (match_operator 1 "eqne_operator"
3238 [(match_operand 2 "h8300_dst_operand" "r,rQ")
3239 (match_operand 3 "h8300_src_operand" "I,rQi")])
3240 (and:QI (match_operand:QI 4 "bit_memory_operand" "0,0")
3241 (match_operand:QI 5 "single_zero_operand" "n,n"))
3242 (match_dup 4)))]
3243 "TARGET_H8300SX"
3244 "#"
3245 "reload_completed"
3246 [(set (cc0) (match_dup 6))
3247 (set (match_dup 0)
3248 (if_then_else:QI (match_op_dup 1 [(cc0) (const_int 0)])
3249 (and:QI (match_dup 4) (match_dup 5))
3250 (match_dup 4)))]
3251 {
3252 operands[6] = gen_rtx_COMPARE (VOIDmode, operands[2], operands[3]);
3253 }
3254 [(set_attr "cc" "set_znv,compare")])
3255
3256 (define_insn "*condbclr"
3257 [(set (match_operand:QI 0 "bit_memory_operand" "=WU")
3258 (if_then_else:QI (match_operator:QI 2 "eqne_operator"
3259 [(cc0) (const_int 0)])
3260 (and:QI (match_operand:QI 3 "bit_memory_operand" "0")
3261 (match_operand:QI 1 "single_zero_operand" "n"))
3262 (match_dup 3)))]
3263 "TARGET_H8300SX && reload_completed"
3264 "bclr/%j2\t%W1,%0"
3265 [(set_attr "cc" "none_0hit")
3266 (set_attr "length_table" "logicb")])
3267
3268 (define_insn_and_split "*cmpcondbsetreg"
3269 [(set (match_operand:QI 0 "nonimmediate_operand" "=WU,WU")
3270 (if_then_else:QI (match_operator 1 "eqne_operator"
3271 [(match_operand 2 "h8300_dst_operand" "r,rQ")
3272 (match_operand 3 "h8300_src_operand" "I,rQi")])
3273 (ior:QI (match_operand:QI 4 "bit_memory_operand" "0,0")
3274 (ashift:QI (const_int 1)
3275 (match_operand:QI 5 "register_operand" "r,r")))
3276 (match_dup 4)))]
3277 "TARGET_H8300SX"
3278 "#"
3279 "reload_completed"
3280 [(set (cc0) (match_dup 6))
3281 (set (match_dup 0)
3282 (if_then_else:QI (match_op_dup 1 [(cc0) (const_int 0)])
3283 (ior:QI (match_dup 4)
3284 (ashift:QI (const_int 1)
3285 (match_operand:QI 5 "register_operand" "r,r")))
3286 (match_dup 4)))]
3287 {
3288 operands[6] = gen_rtx_COMPARE (VOIDmode, operands[2], operands[3]);
3289 }
3290 [(set_attr "cc" "set_znv,compare")])
3291
3292 (define_insn "*condbsetreg"
3293 [(set (match_operand:QI 0 "bit_memory_operand" "=WU")
3294 (if_then_else:QI (match_operator:QI 2 "eqne_operator"
3295 [(cc0) (const_int 0)])
3296 (ior:QI (match_operand:QI 3 "bit_memory_operand" "0")
3297 (ashift:QI (const_int 1)
3298 (match_operand:QI 1 "register_operand" "r")))
3299 (match_dup 3)))]
3300 "TARGET_H8300SX && reload_completed"
3301 "bset/%j2\t%R1,%0"
3302 [(set_attr "cc" "none_0hit")
3303 (set_attr "length_table" "logicb")])
3304
3305 (define_insn_and_split "*cmpcondbclrreg"
3306 [(set (match_operand:QI 0 "nonimmediate_operand" "=WU,WU")
3307 (if_then_else:QI (match_operator 1 "eqne_operator"
3308 [(match_operand 2 "h8300_dst_operand" "r,rQ")
3309 (match_operand 3 "h8300_src_operand" "I,rQi")])
3310 (and:QI (match_operand:QI 4 "bit_memory_operand" "0,0")
3311 (ashift:QI (const_int 1)
3312 (match_operand:QI 5 "register_operand" "r,r")))
3313 (match_dup 4)))]
3314 "TARGET_H8300SX"
3315 "#"
3316 "reload_completed"
3317 [(set (cc0) (match_dup 6))
3318 (set (match_dup 0)
3319 (if_then_else:QI (match_op_dup 1 [(cc0) (const_int 0)])
3320 (and:QI (match_dup 4)
3321 (ashift:QI (const_int 1)
3322 (match_operand:QI 5 "register_operand" "r,r")))
3323 (match_dup 4)))]
3324 {
3325 operands[6] = gen_rtx_COMPARE (VOIDmode, operands[2], operands[3]);
3326 }
3327 [(set_attr "cc" "set_znv,compare")])
3328
3329 (define_insn "*condbclrreg"
3330 [(set (match_operand:QI 0 "bit_memory_operand" "=WU")
3331 (if_then_else:QI (match_operator:QI 2 "eqne_operator"
3332 [(cc0) (const_int 0)])
3333 (and:QI (match_operand:QI 3 "bit_memory_operand" "0")
3334 (ashift:QI (const_int 1)
3335 (match_operand:QI 1 "register_operand" "r")))
3336 (match_dup 3)))]
3337 "TARGET_H8300SX && reload_completed"
3338 "bclr/%j2\t%R1,%0"
3339 [(set_attr "cc" "none_0hit")
3340 (set_attr "length_table" "logicb")])
3341
3342 \f
3343 ;; -----------------------------------------------------------------
3344 ;; COMBINE PATTERNS
3345 ;; -----------------------------------------------------------------
3346
3347 ;; insv:SI
3348
3349 (define_insn "*insv_si_1_n"
3350 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
3351 (const_int 1)
3352 (match_operand:SI 1 "const_int_operand" "n"))
3353 (match_operand:SI 2 "register_operand" "r"))]
3354 "(TARGET_H8300H || TARGET_H8300S) && INTVAL (operands[1]) < 16"
3355 "bld\\t#0,%w2\;bst\\t%Z1,%Y0"
3356 [(set_attr "length" "4")])
3357
3358 (define_insn "*insv_si_1_n_lshiftrt"
3359 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
3360 (const_int 1)
3361 (match_operand:SI 1 "const_int_operand" "n"))
3362 (lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
3363 (match_operand:SI 3 "const_int_operand" "n")))]
3364 "(TARGET_H8300H || TARGET_H8300S)
3365 && INTVAL (operands[1]) < 16
3366 && INTVAL (operands[3]) < 16"
3367 "bld\\t%Z3,%Y2\;bst\\t%Z1,%Y0"
3368 [(set_attr "length" "4")])
3369
3370 (define_insn "*insv_si_1_n_lshiftrt_16"
3371 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
3372 (const_int 1)
3373 (match_operand:SI 1 "const_int_operand" "n"))
3374 (lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
3375 (const_int 16)))]
3376 "(TARGET_H8300H || TARGET_H8300S) && INTVAL (operands[1]) < 16"
3377 "rotr.w\\t%e2\;rotl.w\\t%e2\;bst\\t%Z1,%Y0"
3378 [(set_attr "length" "6")])
3379
3380 (define_insn "*insv_si_8_8"
3381 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
3382 (const_int 8)
3383 (const_int 8))
3384 (match_operand:SI 1 "register_operand" "r"))]
3385 "TARGET_H8300H || TARGET_H8300S"
3386 "mov.b\\t%w1,%x0"
3387 [(set_attr "length" "2")])
3388
3389 (define_insn "*insv_si_8_8_lshiftrt_8"
3390 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
3391 (const_int 8)
3392 (const_int 8))
3393 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
3394 (const_int 8)))]
3395 "TARGET_H8300H || TARGET_H8300S"
3396 "mov.b\\t%x1,%x0"
3397 [(set_attr "length" "2")])
3398
3399 ;; extzv:SI
3400
3401 (define_insn "*extzv_8_8"
3402 [(set (match_operand:SI 0 "register_operand" "=r,r")
3403 (zero_extract:SI (match_operand:SI 1 "register_operand" "?0,r")
3404 (const_int 8)
3405 (const_int 8)))]
3406 "TARGET_H8300H || TARGET_H8300S"
3407 "@
3408 mov.b\\t%x1,%w0\;extu.w\\t%f0\;extu.l\\t%S0
3409 sub.l\\t%S0,%S0\;mov.b\\t%x1,%w0"
3410 [(set_attr "cc" "set_znv,clobber")
3411 (set_attr "length" "6,4")])
3412
3413 (define_insn "*extzv_8_16"
3414 [(set (match_operand:SI 0 "register_operand" "=r")
3415 (zero_extract:SI (match_operand:SI 1 "register_operand" "r")
3416 (const_int 8)
3417 (const_int 16)))]
3418 "TARGET_H8300H || TARGET_H8300S"
3419 "mov.w\\t%e1,%f0\;extu.w\\t%f0\;extu.l\\t%S0"
3420 [(set_attr "cc" "set_znv")
3421 (set_attr "length" "6")])
3422
3423 (define_insn "*extzv_16_8"
3424 [(set (match_operand:SI 0 "register_operand" "=r")
3425 (zero_extract:SI (match_operand:SI 1 "register_operand" "r")
3426 (const_int 16)
3427 (const_int 8)))
3428 (clobber (match_scratch:SI 2 "=&r"))]
3429 "TARGET_H8300H"
3430 "mov.w\\t%e1,%f2\;mov.b\\t%x1,%w0\;mov.b\\t%w2,%x0\;extu.l\\t%S0"
3431 [(set_attr "length" "8")
3432 (set_attr "cc" "set_znv")])
3433
3434 ;; Extract the exponent of a float.
3435
3436 (define_insn_and_split "*extzv_8_23"
3437 [(set (match_operand:SI 0 "register_operand" "=r")
3438 (zero_extract:SI (match_operand:SI 1 "register_operand" "0")
3439 (const_int 8)
3440 (const_int 23)))]
3441 "(TARGET_H8300H || TARGET_H8300S)"
3442 "#"
3443 "&& reload_completed"
3444 [(parallel [(set (match_dup 0)
3445 (ashift:SI (match_dup 0)
3446 (const_int 1)))
3447 (clobber (scratch:QI))])
3448 (parallel [(set (match_dup 0)
3449 (lshiftrt:SI (match_dup 0)
3450 (const_int 24)))
3451 (clobber (scratch:QI))])]
3452 "")
3453
3454 ;; and:SI
3455
3456 ;; ((SImode) HImode) << 15
3457
3458 (define_insn_and_split "*twoshifts_l16_r1"
3459 [(set (match_operand:SI 0 "register_operand" "=r")
3460 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
3461 (const_int 15))
3462 (const_int 2147450880)))]
3463 "(TARGET_H8300H || TARGET_H8300S)"
3464 "#"
3465 "&& reload_completed"
3466 [(parallel [(set (match_dup 0)
3467 (ashift:SI (match_dup 0)
3468 (const_int 16)))
3469 (clobber (scratch:QI))])
3470 (parallel [(set (match_dup 0)
3471 (lshiftrt:SI (match_dup 0)
3472 (const_int 1)))
3473 (clobber (scratch:QI))])]
3474 "")
3475
3476 ;; Transform (SImode << B) & 0xffff into (SImode) (HImode << B).
3477
3478 (define_insn_and_split "*andsi3_ashift_n_lower"
3479 [(set (match_operand:SI 0 "register_operand" "=r,r")
3480 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0,0")
3481 (match_operand:QI 2 "const_int_operand" "S,n"))
3482 (match_operand:SI 3 "const_int_operand" "n,n")))
3483 (clobber (match_scratch:QI 4 "=X,&r"))]
3484 "(TARGET_H8300H || TARGET_H8300S)
3485 && INTVAL (operands[2]) <= 15
3486 && UINTVAL (operands[3]) == ((HOST_WIDE_INT_M1U << INTVAL (operands[2]))
3487 & 0xffff)"
3488 "#"
3489 "&& reload_completed"
3490 [(parallel [(set (match_dup 5)
3491 (ashift:HI (match_dup 5)
3492 (match_dup 2)))
3493 (clobber (match_dup 4))])
3494 (set (match_dup 0)
3495 (zero_extend:SI (match_dup 5)))]
3496 {
3497 operands[5] = gen_rtx_REG (HImode, REGNO (operands[0]));
3498 })
3499
3500 ;; Accept (A >> 30) & 2 and the like.
3501
3502 (define_insn "*andsi3_lshiftrt_n_sb"
3503 [(set (match_operand:SI 0 "register_operand" "=r")
3504 (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
3505 (match_operand:SI 2 "const_int_operand" "n"))
3506 (match_operand:SI 3 "single_one_operand" "n")))]
3507 "(TARGET_H8300H || TARGET_H8300S)
3508 && exact_log2 (INTVAL (operands[3])) < 16
3509 && INTVAL (operands[2]) + exact_log2 (INTVAL (operands[3])) == 31"
3510 {
3511 operands[3] = GEN_INT (exact_log2 (INTVAL (operands[3])));
3512 return "shll.l\\t%S0\;xor.l\\t%S0,%S0\;bst\\t%Z3,%Y0";
3513 }
3514 [(set_attr "length" "8")])
3515
3516 (define_insn_and_split "*andsi3_lshiftrt_9_sb"
3517 [(set (match_operand:SI 0 "register_operand" "=r")
3518 (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
3519 (const_int 9))
3520 (const_int 4194304)))]
3521 "TARGET_H8300H || TARGET_H8300S"
3522 "#"
3523 "&& reload_completed"
3524 [(set (match_dup 0)
3525 (and:SI (lshiftrt:SI (match_dup 0)
3526 (const_int 25))
3527 (const_int 64)))
3528 (parallel [(set (match_dup 0)
3529 (ashift:SI (match_dup 0)
3530 (const_int 16)))
3531 (clobber (scratch:QI))])]
3532 "")
3533
3534 ;; plus:SI
3535
3536 (define_insn "*addsi3_upper"
3537 [(set (match_operand:SI 0 "register_operand" "=r")
3538 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
3539 (const_int 65536))
3540 (match_operand:SI 2 "register_operand" "0")))]
3541 "TARGET_H8300H || TARGET_H8300S"
3542 "add.w\\t%f1,%e0"
3543 [(set_attr "length" "2")])
3544
3545 (define_insn "*addsi3_lshiftrt_16_zexthi"
3546 [(set (match_operand:SI 0 "register_operand" "=r")
3547 (plus:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
3548 (const_int 16))
3549 (zero_extend:SI (match_operand:HI 2 "register_operand" "0"))))]
3550 "TARGET_H8300H || TARGET_H8300S"
3551 "add.w\\t%e1,%f0\;xor.w\\t%e0,%e0\;rotxl.w\\t%e0"
3552 [(set_attr "length" "6")])
3553
3554 (define_insn_and_split "*addsi3_and_r_1"
3555 [(set (match_operand:SI 0 "register_operand" "=r")
3556 (plus:SI (and:SI (match_operand:SI 1 "register_operand" "r")
3557 (const_int 1))
3558 (match_operand:SI 2 "register_operand" "0")))]
3559 "TARGET_H8300H || TARGET_H8300S"
3560 "#"
3561 "&& reload_completed"
3562 [(set (cc0) (compare (zero_extract:SI (match_dup 1)
3563 (const_int 1)
3564 (const_int 0))
3565 (const_int 0)))
3566 (set (pc)
3567 (if_then_else (eq (cc0)
3568 (const_int 0))
3569 (label_ref (match_dup 3))
3570 (pc)))
3571 (set (match_dup 2)
3572 (plus:SI (match_dup 2)
3573 (const_int 1)))
3574 (match_dup 3)]
3575 {
3576 operands[3] = gen_label_rtx ();
3577 })
3578
3579 (define_insn_and_split "*addsi3_and_not_r_1"
3580 [(set (match_operand:SI 0 "register_operand" "=r")
3581 (plus:SI (and:SI (not:SI (match_operand:SI 1 "register_operand" "r"))
3582 (const_int 1))
3583 (match_operand:SI 2 "register_operand" "0")))]
3584 "TARGET_H8300H || TARGET_H8300S"
3585 "#"
3586 "&& reload_completed"
3587 [(set (cc0) (compare (zero_extract:SI (match_dup 1)
3588 (const_int 1)
3589 (const_int 0))
3590 (const_int 0)))
3591 (set (pc)
3592 (if_then_else (ne (cc0)
3593 (const_int 0))
3594 (label_ref (match_dup 3))
3595 (pc)))
3596 (set (match_dup 2)
3597 (plus:SI (match_dup 2)
3598 (const_int 1)))
3599 (match_dup 3)]
3600 {
3601 operands[3] = gen_label_rtx ();
3602 })
3603
3604 ;; [ix]or:HI
3605
3606 (define_insn "*ixorhi3_zext"
3607 [(set (match_operand:HI 0 "register_operand" "=r")
3608 (match_operator:HI 1 "iorxor_operator"
3609 [(zero_extend:HI (match_operand:QI 2 "register_operand" "r"))
3610 (match_operand:HI 3 "register_operand" "0")]))]
3611 ""
3612 "%c1.b\\t%X2,%s0"
3613 [(set_attr "length" "2")])
3614
3615 ;; [ix]or:SI
3616
3617 (define_insn "*ixorsi3_zext_qi"
3618 [(set (match_operand:SI 0 "register_operand" "=r")
3619 (match_operator:SI 1 "iorxor_operator"
3620 [(zero_extend:SI (match_operand:QI 2 "register_operand" "r"))
3621 (match_operand:SI 3 "register_operand" "0")]))]
3622 ""
3623 "%c1.b\\t%X2,%w0"
3624 [(set_attr "length" "2")])
3625
3626 (define_insn "*ixorsi3_zext_hi"
3627 [(set (match_operand:SI 0 "register_operand" "=r")
3628 (match_operator:SI 1 "iorxor_operator"
3629 [(zero_extend:SI (match_operand:HI 2 "register_operand" "r"))
3630 (match_operand:SI 3 "register_operand" "0")]))]
3631 "TARGET_H8300H || TARGET_H8300S"
3632 "%c1.w\\t%T2,%f0"
3633 [(set_attr "length" "2")])
3634
3635 (define_insn "*ixorsi3_ashift_16"
3636 [(set (match_operand:SI 0 "register_operand" "=r")
3637 (match_operator:SI 1 "iorxor_operator"
3638 [(ashift:SI (match_operand:SI 2 "register_operand" "r")
3639 (const_int 16))
3640 (match_operand:SI 3 "register_operand" "0")]))]
3641 "TARGET_H8300H || TARGET_H8300S"
3642 "%c1.w\\t%f2,%e0"
3643 [(set_attr "length" "2")])
3644
3645 (define_insn "*ixorsi3_lshiftrt_16"
3646 [(set (match_operand:SI 0 "register_operand" "=r")
3647 (match_operator:SI 1 "iorxor_operator"
3648 [(lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
3649 (const_int 16))
3650 (match_operand:SI 3 "register_operand" "0")]))]
3651 "TARGET_H8300H || TARGET_H8300S"
3652 "%c1.w\\t%e2,%f0"
3653 [(set_attr "length" "2")])
3654
3655 ;; ior:HI
3656
3657 (define_insn "*iorhi3_ashift_8"
3658 [(set (match_operand:HI 0 "register_operand" "=r")
3659 (ior:HI (ashift:HI (match_operand:HI 1 "register_operand" "r")
3660 (const_int 8))
3661 (match_operand:HI 2 "register_operand" "0")))]
3662 ""
3663 "or.b\\t%s1,%t0"
3664 [(set_attr "length" "2")])
3665
3666 (define_insn "*iorhi3_lshiftrt_8"
3667 [(set (match_operand:HI 0 "register_operand" "=r")
3668 (ior:HI (lshiftrt:HI (match_operand:HI 1 "register_operand" "r")
3669 (const_int 8))
3670 (match_operand:HI 2 "register_operand" "0")))]
3671 ""
3672 "or.b\\t%t1,%s0"
3673 [(set_attr "length" "2")])
3674
3675 (define_insn "*iorhi3_two_qi"
3676 [(set (match_operand:HI 0 "register_operand" "=r")
3677 (ior:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "0"))
3678 (ashift:HI (match_operand:HI 2 "register_operand" "r")
3679 (const_int 8))))]
3680 ""
3681 "mov.b\\t%s2,%t0"
3682 [(set_attr "length" "2")])
3683
3684 (define_insn "*iorhi3_two_qi_mem"
3685 [(set (match_operand:HI 0 "register_operand" "=&r")
3686 (ior:HI (zero_extend:HI (match_operand:QI 1 "memory_operand" "m"))
3687 (ashift:HI (subreg:HI (match_operand:QI 2 "memory_operand" "m") 0)
3688 (const_int 8))))]
3689 ""
3690 "mov.b\\t%X2,%t0\;mov.b\\t%X1,%s0"
3691 [(set_attr "length" "16")])
3692
3693 (define_split
3694 [(set (match_operand:HI 0 "register_operand" "")
3695 (ior:HI (zero_extend:HI (match_operand:QI 1 "memory_operand" ""))
3696 (ashift:HI (subreg:HI (match_operand:QI 2 "memory_operand" "") 0)
3697 (const_int 8))))]
3698 "(TARGET_H8300H || TARGET_H8300S)
3699 && reload_completed
3700 && byte_accesses_mergeable_p (XEXP (operands[2], 0), XEXP (operands[1], 0))"
3701 [(set (match_dup 0)
3702 (match_dup 3))]
3703 {
3704 operands[3] = gen_rtx_MEM (HImode, XEXP (operands[2], 0));
3705 })
3706
3707 ;; ior:SI
3708
3709 (define_insn "*iorsi3_two_hi"
3710 [(set (match_operand:SI 0 "register_operand" "=r")
3711 (ior:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "0"))
3712 (ashift:SI (match_operand:SI 2 "register_operand" "r")
3713 (const_int 16))))]
3714 "TARGET_H8300H || TARGET_H8300S"
3715 "mov.w\\t%f2,%e0"
3716 [(set_attr "length" "2")])
3717
3718 (define_insn_and_split "*iorsi3_two_qi_zext"
3719 [(set (match_operand:SI 0 "register_operand" "=&r")
3720 (ior:SI (zero_extend:SI (match_operand:QI 1 "memory_operand" "m"))
3721 (and:SI (ashift:SI (subreg:SI (match_operand:QI 2 "memory_operand" "m") 0)
3722 (const_int 8))
3723 (const_int 65280))))]
3724 "TARGET_H8300H || TARGET_H8300S"
3725 "#"
3726 "&& reload_completed"
3727 [(set (match_dup 3)
3728 (ior:HI (zero_extend:HI (match_dup 1))
3729 (ashift:HI (subreg:HI (match_dup 2) 0)
3730 (const_int 8))))
3731 (set (match_dup 0)
3732 (zero_extend:SI (match_dup 3)))]
3733 {
3734 operands[3] = gen_rtx_REG (HImode, REGNO (operands[0]));
3735 })
3736
3737 (define_insn "*iorsi3_e2f"
3738 [(set (match_operand:SI 0 "register_operand" "=r")
3739 (ior:SI (and:SI (match_operand:SI 1 "register_operand" "0")
3740 (const_int -65536))
3741 (lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
3742 (const_int 16))))]
3743 "TARGET_H8300H || TARGET_H8300S"
3744 "mov.w\\t%e2,%f0"
3745 [(set_attr "length" "2")])
3746
3747 (define_insn_and_split "*iorsi3_two_qi_sext"
3748 [(set (match_operand:SI 0 "register_operand" "=r")
3749 (ior:SI (zero_extend:SI (match_operand:QI 1 "register_operand" "0"))
3750 (ashift:SI (sign_extend:SI (match_operand:QI 2 "register_operand" "r"))
3751 (const_int 8))))]
3752 "TARGET_H8300H || TARGET_H8300S"
3753 "#"
3754 "&& reload_completed"
3755 [(set (match_dup 3)
3756 (ior:HI (zero_extend:HI (match_dup 1))
3757 (ashift:HI (match_dup 4)
3758 (const_int 8))))
3759 (set (match_dup 0)
3760 (sign_extend:SI (match_dup 3)))]
3761 {
3762 operands[3] = gen_rtx_REG (HImode, REGNO (operands[0]));
3763 operands[4] = gen_rtx_REG (HImode, REGNO (operands[2]));
3764 })
3765
3766 (define_insn "*iorsi3_w"
3767 [(set (match_operand:SI 0 "register_operand" "=r,&r")
3768 (ior:SI (and:SI (match_operand:SI 1 "register_operand" "0,0")
3769 (const_int -256))
3770 (zero_extend:SI (match_operand:QI 2 "general_operand_src" "r,g>"))))]
3771 "TARGET_H8300H || TARGET_H8300S"
3772 "mov.b\\t%X2,%w0"
3773 [(set_attr "length" "2,8")])
3774
3775 (define_insn "*iorsi3_ashift_31"
3776 [(set (match_operand:SI 0 "register_operand" "=&r")
3777 (ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "r")
3778 (const_int 31))
3779 (match_operand:SI 2 "register_operand" "0")))]
3780 "TARGET_H8300H || TARGET_H8300S"
3781 "rotxl.l\\t%S0\;bor\\t#0,%w1\;rotxr.l\\t%S0"
3782 [(set_attr "length" "6")
3783 (set_attr "cc" "set_znv")])
3784
3785 (define_insn "*iorsi3_and_ashift"
3786 [(set (match_operand:SI 0 "register_operand" "=r")
3787 (ior:SI (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "r")
3788 (match_operand:SI 2 "const_int_operand" "n"))
3789 (match_operand:SI 3 "single_one_operand" "n"))
3790 (match_operand:SI 4 "register_operand" "0")))]
3791 "(TARGET_H8300H || TARGET_H8300S)
3792 && (INTVAL (operands[3]) & ~0xffff) == 0"
3793 {
3794 rtx srcpos = GEN_INT (exact_log2 (INTVAL (operands[3]))
3795 - INTVAL (operands[2]));
3796 rtx dstpos = GEN_INT (exact_log2 (INTVAL (operands[3])));
3797 operands[2] = srcpos;
3798 operands[3] = dstpos;
3799 return "bld\\t%Z2,%Y1\;bor\\t%Z3,%Y0\;bst\\t%Z3,%Y0";
3800 }
3801 [(set_attr "length" "6")])
3802
3803 (define_insn "*iorsi3_and_lshiftrt"
3804 [(set (match_operand:SI 0 "register_operand" "=r")
3805 (ior:SI (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
3806 (match_operand:SI 2 "const_int_operand" "n"))
3807 (match_operand:SI 3 "single_one_operand" "n"))
3808 (match_operand:SI 4 "register_operand" "0")))]
3809 "(TARGET_H8300H || TARGET_H8300S)
3810 && ((INTVAL (operands[3]) << INTVAL (operands[2])) & ~0xffff) == 0"
3811 {
3812 rtx srcpos = GEN_INT (exact_log2 (INTVAL (operands[3]))
3813 + INTVAL (operands[2]));
3814 rtx dstpos = GEN_INT (exact_log2 (INTVAL (operands[3])));
3815 operands[2] = srcpos;
3816 operands[3] = dstpos;
3817 return "bld\\t%Z2,%Y1\;bor\\t%Z3,%Y0\;bst\\t%Z3,%Y0";
3818 }
3819 [(set_attr "length" "6")])
3820
3821 (define_insn "*iorsi3_zero_extract"
3822 [(set (match_operand:SI 0 "register_operand" "=r")
3823 (ior:SI (zero_extract:SI (match_operand:SI 1 "register_operand" "r")
3824 (const_int 1)
3825 (match_operand:SI 2 "const_int_operand" "n"))
3826 (match_operand:SI 3 "register_operand" "0")))]
3827 "(TARGET_H8300H || TARGET_H8300S) && INTVAL (operands[2]) < 16"
3828 "bld\\t%Z2,%Y1\;bor\\t#0,%w0\;bst\\t#0,%w0"
3829 [(set_attr "length" "6")])
3830
3831 (define_insn "*iorsi3_and_lshiftrt_n_sb"
3832 [(set (match_operand:SI 0 "register_operand" "=r")
3833 (ior:SI (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
3834 (const_int 30))
3835 (const_int 2))
3836 (match_operand:SI 2 "register_operand" "0")))]
3837 "TARGET_H8300H || TARGET_H8300S"
3838 "rotl.l\\t%S1\;rotr.l\\t%S1\;bor\\t#1,%w0\;bst\\t#1,%w0"
3839 [(set_attr "length" "8")])
3840
3841 (define_insn "*iorsi3_and_lshiftrt_9_sb"
3842 [(set (match_operand:SI 0 "register_operand" "=r")
3843 (ior:SI (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
3844 (const_int 9))
3845 (const_int 4194304))
3846 (match_operand:SI 2 "register_operand" "0")))
3847 (clobber (match_scratch:HI 3 "=&r"))]
3848 "TARGET_H8300H || TARGET_H8300S"
3849 {
3850 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3851 return "shll.l\\t%S1\;xor.w\\t%T3,%T3\;bst\\t#6,%s3\;or.w\\t%T3,%e0";
3852 else
3853 return "rotl.l\\t%S1\;rotr.l\\t%S1\;xor.w\\t%T3,%T3\;bst\\t#6,%s3\;or.w\\t%T3,%e0";
3854 }
3855 [(set_attr "length" "10")])
3856
3857 ;; Used to OR the exponent of a float.
3858
3859 (define_insn "*iorsi3_shift"
3860 [(set (match_operand:SI 0 "register_operand" "=r")
3861 (ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "r")
3862 (const_int 23))
3863 (match_operand:SI 2 "register_operand" "0")))
3864 (clobber (match_scratch:SI 3 "=&r"))]
3865 "TARGET_H8300H || TARGET_H8300S"
3866 "#")
3867
3868 (define_split
3869 [(set (match_operand:SI 0 "register_operand" "")
3870 (ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
3871 (const_int 23))
3872 (match_dup 0)))
3873 (clobber (match_operand:SI 2 "register_operand" ""))]
3874 "(TARGET_H8300H || TARGET_H8300S)
3875 && epilogue_completed
3876 && find_regno_note (insn, REG_DEAD, REGNO (operands[1]))
3877 && REGNO (operands[0]) != REGNO (operands[1])"
3878 [(parallel [(set (match_dup 3)
3879 (ashift:HI (match_dup 3)
3880 (const_int 7)))
3881 (clobber (scratch:QI))])
3882 (set (match_dup 0)
3883 (ior:SI (ashift:SI (match_dup 1)
3884 (const_int 16))
3885 (match_dup 0)))]
3886 {
3887 operands[3] = gen_rtx_REG (HImode, REGNO (operands[1]));
3888 })
3889
3890 (define_split
3891 [(set (match_operand:SI 0 "register_operand" "")
3892 (ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
3893 (const_int 23))
3894 (match_dup 0)))
3895 (clobber (match_operand:SI 2 "register_operand" ""))]
3896 "(TARGET_H8300H || TARGET_H8300S)
3897 && epilogue_completed
3898 && !(find_regno_note (insn, REG_DEAD, REGNO (operands[1]))
3899 && REGNO (operands[0]) != REGNO (operands[1]))"
3900 [(set (match_dup 2)
3901 (match_dup 1))
3902 (parallel [(set (match_dup 3)
3903 (ashift:HI (match_dup 3)
3904 (const_int 7)))
3905 (clobber (scratch:QI))])
3906 (set (match_dup 0)
3907 (ior:SI (ashift:SI (match_dup 2)
3908 (const_int 16))
3909 (match_dup 0)))]
3910 {
3911 operands[3] = gen_rtx_REG (HImode, REGNO (operands[2]));
3912 })
3913
3914 (define_insn "*iorsi2_and_1_lshiftrt_1"
3915 [(set (match_operand:SI 0 "register_operand" "=r")
3916 (ior:SI (and:SI (match_operand:SI 1 "register_operand" "0")
3917 (const_int 1))
3918 (lshiftrt:SI (match_dup 1)
3919 (const_int 1))))]
3920 "TARGET_H8300H || TARGET_H8300S"
3921 "shlr.l\\t%S0\;bor\\t#0,%w0\;bst\\t#0,%w0"
3922 [(set_attr "length" "6")])
3923
3924 (define_insn_and_split "*iorsi3_ashift_16_ashift_24"
3925 [(set (match_operand:SI 0 "register_operand" "=r")
3926 (ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
3927 (const_int 16))
3928 (ashift:SI (match_operand:SI 2 "register_operand" "r")
3929 (const_int 24))))]
3930 "TARGET_H8300H || TARGET_H8300S"
3931 "#"
3932 "&& reload_completed"
3933 [(set (match_dup 3)
3934 (ior:HI (ashift:HI (match_dup 4)
3935 (const_int 8))
3936 (match_dup 3)))
3937 (parallel [(set (match_dup 0)
3938 (ashift:SI (match_dup 0)
3939 (const_int 16)))
3940 (clobber (scratch:QI))])]
3941 {
3942 operands[3] = gen_rtx_REG (HImode, REGNO (operands[0]));
3943 operands[4] = gen_rtx_REG (HImode, REGNO (operands[2]));
3944 })
3945
3946 (define_insn_and_split "*iorsi3_ashift_16_ashift_24_mem"
3947 [(set (match_operand:SI 0 "register_operand" "=&r")
3948 (ior:SI (and:SI (ashift:SI (subreg:SI (match_operand:QI 1 "memory_operand" "m") 0)
3949 (const_int 16))
3950 (const_int 16711680))
3951 (ashift:SI (subreg:SI (match_operand:QI 2 "memory_operand" "m") 0)
3952 (const_int 24))))]
3953 "TARGET_H8300H || TARGET_H8300S"
3954 "#"
3955 "&& reload_completed"
3956 [(set (match_dup 3)
3957 (ior:HI (zero_extend:HI (match_dup 1))
3958 (ashift:HI (subreg:HI (match_dup 2) 0)
3959 (const_int 8))))
3960 (parallel [(set (match_dup 0)
3961 (ashift:SI (match_dup 0)
3962 (const_int 16)))
3963 (clobber (scratch:QI))])]
3964 {
3965 operands[3] = gen_rtx_REG (HImode, REGNO (operands[0]));
3966 })
3967
3968 ;; Used to add the exponent of a float.
3969
3970 (define_insn "*addsi3_shift"
3971 [(set (match_operand:SI 0 "register_operand" "=r")
3972 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
3973 (const_int 8388608))
3974 (match_operand:SI 2 "register_operand" "0")))
3975 (clobber (match_scratch:SI 3 "=&r"))]
3976 "TARGET_H8300H || TARGET_H8300S"
3977 "#")
3978
3979 (define_split
3980 [(set (match_operand:SI 0 "register_operand" "")
3981 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "")
3982 (const_int 8388608))
3983 (match_dup 0)))
3984 (clobber (match_operand:SI 2 "register_operand" ""))]
3985 "(TARGET_H8300H || TARGET_H8300S)
3986 && epilogue_completed
3987 && find_regno_note (insn, REG_DEAD, REGNO (operands[1]))
3988 && REGNO (operands[0]) != REGNO (operands[1])"
3989 [(parallel [(set (match_dup 3)
3990 (ashift:HI (match_dup 3)
3991 (const_int 7)))
3992 (clobber (scratch:QI))])
3993 (set (match_dup 0)
3994 (plus:SI (mult:SI (match_dup 1)
3995 (const_int 65536))
3996 (match_dup 0)))]
3997 {
3998 operands[3] = gen_rtx_REG (HImode, REGNO (operands[1]));
3999 })
4000
4001 (define_split
4002 [(set (match_operand:SI 0 "register_operand" "")
4003 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "")
4004 (const_int 8388608))
4005 (match_dup 0)))
4006 (clobber (match_operand:SI 2 "register_operand" ""))]
4007 "(TARGET_H8300H || TARGET_H8300S)
4008 && epilogue_completed
4009 && !(find_regno_note (insn, REG_DEAD, REGNO (operands[1]))
4010 && REGNO (operands[0]) != REGNO (operands[1]))"
4011 [(set (match_dup 2)
4012 (match_dup 1))
4013 (parallel [(set (match_dup 3)
4014 (ashift:HI (match_dup 3)
4015 (const_int 7)))
4016 (clobber (scratch:QI))])
4017 (set (match_dup 0)
4018 (plus:SI (mult:SI (match_dup 2)
4019 (const_int 65536))
4020 (match_dup 0)))]
4021 {
4022 operands[3] = gen_rtx_REG (HImode, REGNO (operands[2]));
4023 })
4024
4025 ;; ashift:SI
4026
4027 (define_insn_and_split "*ashiftsi_sextqi_7"
4028 [(set (match_operand:SI 0 "register_operand" "=r")
4029 (ashift:SI (sign_extend:SI (match_operand:QI 1 "register_operand" "0"))
4030 (const_int 7)))]
4031 "TARGET_H8300H || TARGET_H8300S"
4032 "#"
4033 "&& reload_completed"
4034 [(parallel [(set (match_dup 2)
4035 (ashift:HI (match_dup 2)
4036 (const_int 8)))
4037 (clobber (scratch:QI))])
4038 (set (match_dup 0)
4039 (sign_extend:SI (match_dup 2)))
4040 (parallel [(set (match_dup 0)
4041 (ashiftrt:SI (match_dup 0)
4042 (const_int 1)))
4043 (clobber (scratch:QI))])]
4044 {
4045 operands[2] = gen_rtx_REG (HImode, REGNO (operands[0]));
4046 })
4047
4048 ;; Storing a part of HImode to QImode.
4049
4050 (define_insn ""
4051 [(set (match_operand:QI 0 "general_operand_dst" "=rm<")
4052 (subreg:QI (lshiftrt:HI (match_operand:HI 1 "register_operand" "r")
4053 (const_int 8)) 1))]
4054 ""
4055 "mov.b\\t%t1,%R0"
4056 [(set_attr "cc" "set_znv")
4057 (set_attr "length" "8")])
4058
4059 ;; Storing a part of SImode to QImode.
4060
4061 (define_insn ""
4062 [(set (match_operand:QI 0 "general_operand_dst" "=rm<")
4063 (subreg:QI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
4064 (const_int 8)) 3))]
4065 ""
4066 "mov.b\\t%x1,%R0"
4067 [(set_attr "cc" "set_znv")
4068 (set_attr "length" "8")])
4069
4070 (define_insn ""
4071 [(set (match_operand:QI 0 "general_operand_dst" "=rm<")
4072 (subreg:QI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
4073 (const_int 16)) 3))
4074 (clobber (match_scratch:SI 2 "=&r"))]
4075 "TARGET_H8300H || TARGET_H8300S"
4076 "mov.w\\t%e1,%f2\;mov.b\\t%w2,%R0"
4077 [(set_attr "cc" "set_znv")
4078 (set_attr "length" "10")])
4079
4080 (define_insn ""
4081 [(set (match_operand:QI 0 "general_operand_dst" "=rm<")
4082 (subreg:QI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
4083 (const_int 24)) 3))
4084 (clobber (match_scratch:SI 2 "=&r"))]
4085 "TARGET_H8300H || TARGET_H8300S"
4086 "mov.w\\t%e1,%f2\;mov.b\\t%x2,%R0"
4087 [(set_attr "cc" "set_znv")
4088 (set_attr "length" "10")])
4089
4090 (define_insn_and_split ""
4091 [(set (pc)
4092 (if_then_else (eq (zero_extract:SI (subreg:SI (match_operand:QI 0 "register_operand" "") 0)
4093 (const_int 1)
4094 (const_int 7))
4095 (const_int 0))
4096 (label_ref (match_operand 1 "" ""))
4097 (pc)))]
4098 ""
4099 "#"
4100 ""
4101 [(set (cc0) (compare (match_dup 0)
4102 (const_int 0)))
4103 (set (pc)
4104 (if_then_else (ge (cc0)
4105 (const_int 0))
4106 (label_ref (match_dup 1))
4107 (pc)))]
4108 "")
4109
4110 (define_insn_and_split ""
4111 [(set (pc)
4112 (if_then_else (ne (zero_extract:SI (subreg:SI (match_operand:QI 0 "register_operand" "") 0)
4113 (const_int 1)
4114 (const_int 7))
4115 (const_int 0))
4116 (label_ref (match_operand 1 "" ""))
4117 (pc)))]
4118 ""
4119 "#"
4120 ""
4121 [(set (cc0) (compare (match_dup 0)
4122 (const_int 0)))
4123 (set (pc)
4124 (if_then_else (lt (cc0)
4125 (const_int 0))
4126 (label_ref (match_dup 1))
4127 (pc)))]
4128 "")
4129 \f
4130 ;; -----------------------------------------------------------------
4131 ;; PEEPHOLE PATTERNS
4132 ;; -----------------------------------------------------------------
4133
4134 ;; Convert (A >> B) & C to (A & 255) >> B if C == 255 >> B.
4135
4136 (define_peephole2
4137 [(parallel [(set (match_operand:HI 0 "register_operand" "")
4138 (lshiftrt:HI (match_dup 0)
4139 (match_operand:HI 1 "const_int_operand" "")))
4140 (clobber (match_operand:HI 2 "" ""))])
4141 (set (match_dup 0)
4142 (and:HI (match_dup 0)
4143 (match_operand:HI 3 "const_int_operand" "")))]
4144 "INTVAL (operands[3]) == (255 >> INTVAL (operands[1]))"
4145 [(set (match_dup 0)
4146 (and:HI (match_dup 0)
4147 (const_int 255)))
4148 (parallel [(set (match_dup 0)
4149 (lshiftrt:HI (match_dup 0) (match_dup 1)))
4150 (clobber (match_dup 2))])]
4151 "")
4152
4153 ;; Convert (A << B) & C to (A & 255) << B if C == 255 << B.
4154
4155 (define_peephole2
4156 [(parallel [(set (match_operand:HI 0 "register_operand" "")
4157 (ashift:HI (match_dup 0)
4158 (match_operand:HI 1 "const_int_operand" "")))
4159 (clobber (match_operand:HI 2 "" ""))])
4160 (set (match_dup 0)
4161 (and:HI (match_dup 0)
4162 (match_operand:HI 3 "const_int_operand" "")))]
4163 "INTVAL (operands[3]) == (255 << INTVAL (operands[1]))"
4164 [(set (match_dup 0)
4165 (and:HI (match_dup 0)
4166 (const_int 255)))
4167 (parallel [(set (match_dup 0)
4168 (ashift:HI (match_dup 0) (match_dup 1)))
4169 (clobber (match_dup 2))])]
4170 "")
4171
4172 ;; Convert (A >> B) & C to (A & 255) >> B if C == 255 >> B.
4173
4174 (define_peephole2
4175 [(parallel [(set (match_operand:SI 0 "register_operand" "")
4176 (lshiftrt:SI (match_dup 0)
4177 (match_operand:SI 1 "const_int_operand" "")))
4178 (clobber (match_operand:SI 2 "" ""))])
4179 (set (match_dup 0)
4180 (and:SI (match_dup 0)
4181 (match_operand:SI 3 "const_int_operand" "")))]
4182 "INTVAL (operands[3]) == (255 >> INTVAL (operands[1]))"
4183 [(set (match_dup 0)
4184 (and:SI (match_dup 0)
4185 (const_int 255)))
4186 (parallel [(set (match_dup 0)
4187 (lshiftrt:SI (match_dup 0) (match_dup 1)))
4188 (clobber (match_dup 2))])]
4189 "")
4190
4191 ;; Convert (A << B) & C to (A & 255) << B if C == 255 << B.
4192
4193 (define_peephole2
4194 [(parallel [(set (match_operand:SI 0 "register_operand" "")
4195 (ashift:SI (match_dup 0)
4196 (match_operand:SI 1 "const_int_operand" "")))
4197 (clobber (match_operand:SI 2 "" ""))])
4198 (set (match_dup 0)
4199 (and:SI (match_dup 0)
4200 (match_operand:SI 3 "const_int_operand" "")))]
4201 "INTVAL (operands[3]) == (255 << INTVAL (operands[1]))"
4202 [(set (match_dup 0)
4203 (and:SI (match_dup 0)
4204 (const_int 255)))
4205 (parallel [(set (match_dup 0)
4206 (ashift:SI (match_dup 0) (match_dup 1)))
4207 (clobber (match_dup 2))])]
4208 "")
4209
4210 ;; Convert (A >> B) & C to (A & 65535) >> B if C == 65535 >> B.
4211
4212 (define_peephole2
4213 [(parallel [(set (match_operand:SI 0 "register_operand" "")
4214 (lshiftrt:SI (match_dup 0)
4215 (match_operand:SI 1 "const_int_operand" "")))
4216 (clobber (match_operand:SI 2 "" ""))])
4217 (set (match_dup 0)
4218 (and:SI (match_dup 0)
4219 (match_operand:SI 3 "const_int_operand" "")))]
4220 "INTVAL (operands[3]) == (65535 >> INTVAL (operands[1]))"
4221 [(set (match_dup 0)
4222 (and:SI (match_dup 0)
4223 (const_int 65535)))
4224 (parallel [(set (match_dup 0)
4225 (lshiftrt:SI (match_dup 0) (match_dup 1)))
4226 (clobber (match_dup 2))])]
4227 "")
4228
4229 ;; Convert (A << B) & C to (A & 65535) << B if C == 65535 << B.
4230
4231 (define_peephole2
4232 [(parallel [(set (match_operand:SI 0 "register_operand" "")
4233 (ashift:SI (match_dup 0)
4234 (match_operand:SI 1 "const_int_operand" "")))
4235 (clobber (match_operand:SI 2 "" ""))])
4236 (set (match_dup 0)
4237 (and:SI (match_dup 0)
4238 (match_operand:SI 3 "const_int_operand" "")))]
4239 "INTVAL (operands[3]) == (65535 << INTVAL (operands[1]))"
4240 [(set (match_dup 0)
4241 (and:SI (match_dup 0)
4242 (const_int 65535)))
4243 (parallel [(set (match_dup 0)
4244 (ashift:SI (match_dup 0) (match_dup 1)))
4245 (clobber (match_dup 2))])]
4246 "")
4247
4248 ;; Convert a QImode push into an SImode push so that the
4249 ;; define_peephole2 below can cram multiple pushes into one stm.l.
4250
4251 (define_peephole2
4252 [(parallel [(set (reg:SI SP_REG)
4253 (plus:SI (reg:SI SP_REG) (const_int -4)))
4254 (set (mem:QI (plus:SI (reg:SI SP_REG) (const_int -3)))
4255 (match_operand:QI 0 "register_operand" ""))])]
4256 "TARGET_H8300S && !TARGET_NORMAL_MODE && REGNO (operands[0]) != SP_REG"
4257 [(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
4258 (match_dup 0))]
4259 {
4260 operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]));
4261 })
4262
4263 (define_peephole2
4264 [(parallel [(set (reg:HI SP_REG)
4265 (plus:HI (reg:HI SP_REG) (const_int -4)))
4266 (set (mem:QI (plus:HI (reg:HI SP_REG) (const_int -3)))
4267 (match_operand:QI 0 "register_operand" ""))])]
4268 "TARGET_H8300S && TARGET_NORMAL_MODE && REGNO (operands[0]) != SP_REG"
4269 [(set (mem:SI (pre_dec:HI (reg:HI SP_REG)))
4270 (match_dup 0))]
4271 {
4272 operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]));
4273 })
4274
4275 ;; Convert a HImode push into an SImode push so that the
4276 ;; define_peephole2 below can cram multiple pushes into one stm.l.
4277
4278 (define_peephole2
4279 [(parallel [(set (reg:SI SP_REG)
4280 (plus:SI (reg:SI SP_REG) (const_int -4)))
4281 (set (mem:HI (plus:SI (reg:SI SP_REG) (const_int -2)))
4282 (match_operand:HI 0 "register_operand" ""))])]
4283 "TARGET_H8300S && !TARGET_NORMAL_MODE && REGNO (operands[0]) != SP_REG"
4284 [(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
4285 (match_dup 0))]
4286 {
4287 operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]));
4288 })
4289
4290 (define_peephole2
4291 [(parallel [(set (reg:HI SP_REG)
4292 (plus:HI (reg:HI SP_REG) (const_int -4)))
4293 (set (mem:HI (plus:HI (reg:HI SP_REG) (const_int -2)))
4294 (match_operand:HI 0 "register_operand" ""))])]
4295 "TARGET_H8300S && TARGET_NORMAL_MODE && REGNO (operands[0]) != SP_REG"
4296 [(set (mem:SI (pre_dec:HI (reg:HI SP_REG)))
4297 (match_dup 0))]
4298 {
4299 operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]));
4300 })
4301
4302 ;; Cram four pushes into stm.l.
4303
4304 (define_peephole2
4305 [(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
4306 (match_operand:SI 0 "register_operand" ""))
4307 (set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
4308 (match_operand:SI 1 "register_operand" ""))
4309 (set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
4310 (match_operand:SI 2 "register_operand" ""))
4311 (set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
4312 (match_operand:SI 3 "register_operand" ""))]
4313 "TARGET_H8300S && !TARGET_NORMAL_MODE
4314 && (REGNO_REG_CLASS (REGNO (operands[3])) == GENERAL_REGS
4315 && REGNO (operands[1]) == REGNO (operands[0]) + 1
4316 && REGNO (operands[2]) == REGNO (operands[0]) + 2
4317 && REGNO (operands[3]) == REGNO (operands[0]) + 3
4318 && (TARGET_H8300SX || REGNO (operands[0]) == 0))"
4319 [(parallel [(set (mem:SI (plus:SI (reg:SI SP_REG) (const_int -4)))
4320 (match_dup 0))
4321 (set (mem:SI (plus:SI (reg:SI SP_REG) (const_int -8)))
4322 (match_dup 1))
4323 (set (mem:SI (plus:SI (reg:SI SP_REG) (const_int -12)))
4324 (match_dup 2))
4325 (set (mem:SI (plus:SI (reg:SI SP_REG) (const_int -16)))
4326 (match_dup 3))
4327 (set (reg:SI SP_REG)
4328 (plus:SI (reg:SI SP_REG)
4329 (const_int -16)))])]
4330 "")
4331
4332 (define_peephole2
4333 [(set (mem:SI (pre_dec:HI (reg:HI SP_REG)))
4334 (match_operand:SI 0 "register_operand" ""))
4335 (set (mem:SI (pre_dec:HI (reg:HI SP_REG)))
4336 (match_operand:SI 1 "register_operand" ""))
4337 (set (mem:SI (pre_dec:HI (reg:HI SP_REG)))
4338 (match_operand:SI 2 "register_operand" ""))
4339 (set (mem:SI (pre_dec:HI (reg:HI SP_REG)))
4340 (match_operand:SI 3 "register_operand" ""))]
4341 "TARGET_H8300S && TARGET_NORMAL_MODE
4342 && (REGNO_REG_CLASS (REGNO (operands[3])) == GENERAL_REGS
4343 && REGNO (operands[1]) == REGNO (operands[0]) + 1
4344 && REGNO (operands[2]) == REGNO (operands[0]) + 2
4345 && REGNO (operands[3]) == REGNO (operands[0]) + 3
4346 && (TARGET_H8300SX || REGNO (operands[0]) == 0))"
4347 [(parallel [(set (mem:SI (plus:HI (reg:HI SP_REG) (const_int -4)))
4348 (match_dup 0))
4349 (set (mem:SI (plus:HI (reg:HI SP_REG) (const_int -8)))
4350 (match_dup 1))
4351 (set (mem:SI (plus:HI (reg:HI SP_REG) (const_int -12)))
4352 (match_dup 2))
4353 (set (mem:SI (plus:HI (reg:HI SP_REG) (const_int -16)))
4354 (match_dup 3))
4355 (set (reg:HI SP_REG)
4356 (plus:HI (reg:HI SP_REG)
4357 (const_int -16)))])]
4358 "")
4359
4360 ;; Cram three pushes into stm.l.
4361
4362 (define_peephole2
4363 [(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
4364 (match_operand:SI 0 "register_operand" ""))
4365 (set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
4366 (match_operand:SI 1 "register_operand" ""))
4367 (set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
4368 (match_operand:SI 2 "register_operand" ""))]
4369 "TARGET_H8300S && !TARGET_NORMAL_MODE
4370 && (REGNO_REG_CLASS (REGNO (operands[2])) == GENERAL_REGS
4371 && REGNO (operands[1]) == REGNO (operands[0]) + 1
4372 && REGNO (operands[2]) == REGNO (operands[0]) + 2
4373 && (TARGET_H8300SX || (REGNO (operands[0]) & 3) == 0))"
4374 [(parallel [(set (mem:SI (plus:SI (reg:SI SP_REG) (const_int -4)))
4375 (match_dup 0))
4376 (set (mem:SI (plus:SI (reg:SI SP_REG) (const_int -8)))
4377 (match_dup 1))
4378 (set (mem:SI (plus:SI (reg:SI SP_REG) (const_int -12)))
4379 (match_dup 2))
4380 (set (reg:SI SP_REG)
4381 (plus:SI (reg:SI SP_REG)
4382 (const_int -12)))])]
4383 "")
4384
4385 (define_peephole2
4386 [(set (mem:SI (pre_dec:HI (reg:HI SP_REG)))
4387 (match_operand:SI 0 "register_operand" ""))
4388 (set (mem:SI (pre_dec:HI (reg:HI SP_REG)))
4389 (match_operand:SI 1 "register_operand" ""))
4390 (set (mem:SI (pre_dec:HI (reg:HI SP_REG)))
4391 (match_operand:SI 2 "register_operand" ""))]
4392 "TARGET_H8300S && TARGET_NORMAL_MODE
4393 && (REGNO_REG_CLASS (REGNO (operands[2])) == GENERAL_REGS
4394 && REGNO (operands[1]) == REGNO (operands[0]) + 1
4395 && REGNO (operands[2]) == REGNO (operands[0]) + 2
4396 && (TARGET_H8300SX || (REGNO (operands[0]) & 3) == 0))"
4397 [(parallel [(set (mem:SI (plus:HI (reg:HI SP_REG) (const_int -4)))
4398 (match_dup 0))
4399 (set (mem:SI (plus:HI (reg:HI SP_REG) (const_int -8)))
4400 (match_dup 1))
4401 (set (mem:SI (plus:HI (reg:HI SP_REG) (const_int -12)))
4402 (match_dup 2))
4403 (set (reg:HI SP_REG)
4404 (plus:HI (reg:HI SP_REG)
4405 (const_int -12)))])]
4406 "")
4407
4408 ;; Cram two pushes into stm.l.
4409
4410 (define_peephole2
4411 [(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
4412 (match_operand:SI 0 "register_operand" ""))
4413 (set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
4414 (match_operand:SI 1 "register_operand" ""))]
4415 "TARGET_H8300S && !TARGET_NORMAL_MODE
4416 && (REGNO_REG_CLASS (REGNO (operands[1])) == GENERAL_REGS
4417 && REGNO (operands[1]) == REGNO (operands[0]) + 1
4418 && (TARGET_H8300SX || (REGNO (operands[0]) & 1) == 0))"
4419 [(parallel [(set (mem:SI (plus:SI (reg:SI SP_REG) (const_int -4)))
4420 (match_dup 0))
4421 (set (mem:SI (plus:SI (reg:SI SP_REG) (const_int -8)))
4422 (match_dup 1))
4423 (set (reg:SI SP_REG)
4424 (plus:SI (reg:SI SP_REG)
4425 (const_int -8)))])]
4426 "")
4427
4428 (define_peephole2
4429 [(set (mem:SI (pre_dec:HI (reg:HI SP_REG)))
4430 (match_operand:SI 0 "register_operand" ""))
4431 (set (mem:SI (pre_dec:HI (reg:HI SP_REG)))
4432 (match_operand:SI 1 "register_operand" ""))]
4433 "TARGET_H8300S && TARGET_NORMAL_MODE
4434 && (REGNO_REG_CLASS (REGNO (operands[1])) == GENERAL_REGS
4435 && REGNO (operands[1]) == REGNO (operands[0]) + 1
4436 && (TARGET_H8300SX || (REGNO (operands[0]) & 1) == 0))"
4437 [(parallel [(set (mem:SI (plus:HI (reg:HI SP_REG) (const_int -4)))
4438 (match_dup 0))
4439 (set (mem:SI (plus:HI (reg:HI SP_REG) (const_int -8)))
4440 (match_dup 1))
4441 (set (reg:HI SP_REG)
4442 (plus:HI (reg:HI SP_REG)
4443 (const_int -8)))])]
4444 "")
4445
4446 ;; Turn
4447 ;;
4448 ;; mov.w #2,r0
4449 ;; add.w r7,r0 (6 bytes)
4450 ;;
4451 ;; into
4452 ;;
4453 ;; mov.w r7,r0
4454 ;; adds #2,r0 (4 bytes)
4455
4456 (define_peephole2
4457 [(set (match_operand:HI 0 "register_operand" "")
4458 (match_operand:HI 1 "const_int_operand" ""))
4459 (set (match_dup 0)
4460 (plus:HI (match_dup 0)
4461 (match_operand:HI 2 "register_operand" "")))]
4462 "REG_P (operands[0]) && REG_P (operands[2])
4463 && REGNO (operands[0]) != REGNO (operands[2])
4464 && (satisfies_constraint_J (operands[1])
4465 || satisfies_constraint_L (operands[1])
4466 || satisfies_constraint_N (operands[1]))"
4467 [(set (match_dup 0)
4468 (match_dup 2))
4469 (set (match_dup 0)
4470 (plus:HI (match_dup 0)
4471 (match_dup 1)))]
4472 "")
4473
4474 ;; Turn
4475 ;;
4476 ;; sub.l er0,er0
4477 ;; add.b #4,r0l
4478 ;; add.l er7,er0 (6 bytes)
4479 ;;
4480 ;; into
4481 ;;
4482 ;; mov.l er7,er0
4483 ;; adds #4,er0 (4 bytes)
4484
4485 (define_peephole2
4486 [(set (match_operand:SI 0 "register_operand" "")
4487 (match_operand:SI 1 "const_int_operand" ""))
4488 (set (match_dup 0)
4489 (plus:SI (match_dup 0)
4490 (match_operand:SI 2 "register_operand" "")))]
4491 "(TARGET_H8300H || TARGET_H8300S)
4492 && REG_P (operands[0]) && REG_P (operands[2])
4493 && REGNO (operands[0]) != REGNO (operands[2])
4494 && (satisfies_constraint_L (operands[1])
4495 || satisfies_constraint_N (operands[1]))"
4496 [(set (match_dup 0)
4497 (match_dup 2))
4498 (set (match_dup 0)
4499 (plus:SI (match_dup 0)
4500 (match_dup 1)))]
4501 "")
4502
4503 ;; Turn
4504 ;;
4505 ;; mov.l er7,er0
4506 ;; add.l #10,er0 (takes 8 bytes)
4507 ;;
4508 ;; into
4509 ;;
4510 ;; sub.l er0,er0
4511 ;; add.b #10,r0l
4512 ;; add.l er7,er0 (takes 6 bytes)
4513
4514 (define_peephole2
4515 [(set (match_operand:SI 0 "register_operand" "")
4516 (match_operand:SI 1 "register_operand" ""))
4517 (set (match_dup 0)
4518 (plus:SI (match_dup 0)
4519 (match_operand:SI 2 "const_int_operand" "")))]
4520 "(TARGET_H8300H || TARGET_H8300S)
4521 && REG_P (operands[0]) && REG_P (operands[1])
4522 && REGNO (operands[0]) != REGNO (operands[1])
4523 && !satisfies_constraint_L (operands[2])
4524 && !satisfies_constraint_N (operands[2])
4525 && ((INTVAL (operands[2]) & 0xff) == INTVAL (operands[2])
4526 || (INTVAL (operands[2]) & 0xff00) == INTVAL (operands[2])
4527 || INTVAL (operands[2]) == 0xffff
4528 || INTVAL (operands[2]) == 0xfffe)"
4529 [(set (match_dup 0)
4530 (match_dup 2))
4531 (set (match_dup 0)
4532 (plus:SI (match_dup 0)
4533 (match_dup 1)))]
4534 "")
4535
4536 ;; Turn
4537 ;;
4538 ;; subs #1,er4
4539 ;; mov.w r4,r4
4540 ;; bne .L2028
4541 ;;
4542 ;; into
4543 ;;
4544 ;; dec.w #1,r4
4545 ;; bne .L2028
4546
4547 (define_peephole2
4548 [(set (match_operand:HI 0 "register_operand" "")
4549 (plus:HI (match_dup 0)
4550 (match_operand 1 "incdec_operand" "")))
4551 (set (cc0) (compare (match_dup 0)
4552 (const_int 0)))
4553 (set (pc)
4554 (if_then_else (match_operator 3 "eqne_operator"
4555 [(cc0) (const_int 0)])
4556 (label_ref (match_operand 2 "" ""))
4557 (pc)))]
4558 "TARGET_H8300H || TARGET_H8300S"
4559 [(set (match_operand:HI 0 "register_operand" "")
4560 (unspec:HI [(match_dup 0)
4561 (match_dup 1)]
4562 UNSPEC_INCDEC))
4563 (set (cc0) (compare (match_dup 0)
4564 (const_int 0)))
4565 (set (pc)
4566 (if_then_else (match_op_dup 3 [(cc0) (const_int 0)])
4567 (label_ref (match_dup 2))
4568 (pc)))]
4569 "")
4570
4571 ;; The SImode version of the previous pattern.
4572
4573 (define_peephole2
4574 [(set (match_operand:SI 0 "register_operand" "")
4575 (plus:SI (match_dup 0)
4576 (match_operand 1 "incdec_operand" "")))
4577 (set (cc0) (compare (match_dup 0)
4578 (const_int 0)))
4579 (set (pc)
4580 (if_then_else (match_operator 3 "eqne_operator"
4581 [(cc0) (const_int 0)])
4582 (label_ref (match_operand 2 "" ""))
4583 (pc)))]
4584 "TARGET_H8300H || TARGET_H8300S"
4585 [(set (match_operand:SI 0 "register_operand" "")
4586 (unspec:SI [(match_dup 0)
4587 (match_dup 1)]
4588 UNSPEC_INCDEC))
4589 (set (cc0) (compare (match_dup 0)
4590 (const_int 0)))
4591 (set (pc)
4592 (if_then_else (match_op_dup 3 [(cc0) (const_int 0)])
4593 (label_ref (match_dup 2))
4594 (pc)))]
4595 "")
4596
4597 (define_peephole2
4598 [(parallel [(set (cc0)
4599 (compare (zero_extract:SI (match_operand:QI 0 "register_operand" "")
4600 (const_int 1)
4601 (const_int 7))
4602 (const_int 0)))
4603 (clobber (scratch:QI))])
4604 (set (pc)
4605 (if_then_else (match_operator 1 "eqne_operator"
4606 [(cc0) (const_int 0)])
4607 (label_ref (match_operand 2 "" ""))
4608 (pc)))]
4609 "TARGET_H8300H || TARGET_H8300S"
4610 [(set (cc0) (compare (match_dup 0)
4611 (const_int 0)))
4612 (set (pc)
4613 (if_then_else (match_op_dup 3 [(cc0) (const_int 0)])
4614 (label_ref (match_dup 2))
4615 (pc)))]
4616 {
4617 operands[3] = ((GET_CODE (operands[1]) == EQ)
4618 ? gen_rtx_GE (VOIDmode, cc0_rtx, const0_rtx)
4619 : gen_rtx_LT (VOIDmode, cc0_rtx, const0_rtx));
4620 })
4621
4622 ;; The next three peephole2's will try to transform
4623 ;;
4624 ;; mov.b A,r0l (or mov.l A,er0)
4625 ;; and.l #CST,er0
4626 ;;
4627 ;; into
4628 ;;
4629 ;; sub.l er0
4630 ;; mov.b A,r0l
4631 ;; and.b #CST,r0l (if CST is not 255)
4632
4633 (define_peephole2
4634 [(set (match_operand:QI 0 "register_operand" "")
4635 (match_operand:QI 1 "general_operand" ""))
4636 (set (match_operand:SI 2 "register_operand" "")
4637 (and:SI (match_dup 2)
4638 (const_int 255)))]
4639 "(TARGET_H8300H || TARGET_H8300S)
4640 && !reg_overlap_mentioned_p (operands[2], operands[1])
4641 && REGNO (operands[0]) == REGNO (operands[2])"
4642 [(set (match_dup 2)
4643 (const_int 0))
4644 (set (strict_low_part (match_dup 0))
4645 (match_dup 1))]
4646 "")
4647
4648 (define_peephole2
4649 [(set (match_operand:SI 0 "register_operand" "")
4650 (match_operand:SI 1 "general_operand" ""))
4651 (set (match_dup 0)
4652 (and:SI (match_dup 0)
4653 (const_int 255)))]
4654 "(TARGET_H8300H || TARGET_H8300S)
4655 && !reg_overlap_mentioned_p (operands[0], operands[1])
4656 && !(GET_CODE (operands[1]) == MEM && !offsettable_memref_p (operands[1]))
4657 && !(GET_CODE (operands[1]) == MEM && MEM_VOLATILE_P (operands[1]))"
4658 [(set (match_dup 0)
4659 (const_int 0))
4660 (set (strict_low_part (match_dup 2))
4661 (match_dup 3))]
4662 {
4663 operands[2] = gen_lowpart (QImode, operands[0]);
4664 operands[3] = gen_lowpart (QImode, operands[1]);
4665 })
4666
4667 (define_peephole2
4668 [(set (match_operand 0 "register_operand" "")
4669 (match_operand 1 "general_operand" ""))
4670 (set (match_operand:SI 2 "register_operand" "")
4671 (and:SI (match_dup 2)
4672 (match_operand:SI 3 "const_int_qi_operand" "")))]
4673 "(TARGET_H8300H || TARGET_H8300S)
4674 && (GET_MODE (operands[0]) == QImode
4675 || GET_MODE (operands[0]) == HImode
4676 || GET_MODE (operands[0]) == SImode)
4677 && GET_MODE (operands[0]) == GET_MODE (operands[1])
4678 && REGNO (operands[0]) == REGNO (operands[2])
4679 && !reg_overlap_mentioned_p (operands[2], operands[1])
4680 && !(GET_MODE (operands[1]) != QImode
4681 && GET_CODE (operands[1]) == MEM
4682 && !offsettable_memref_p (operands[1]))
4683 && !(GET_MODE (operands[1]) != QImode
4684 && GET_CODE (operands[1]) == MEM
4685 && MEM_VOLATILE_P (operands[1]))"
4686 [(set (match_dup 2)
4687 (const_int 0))
4688 (set (strict_low_part (match_dup 4))
4689 (match_dup 5))
4690 (set (match_dup 2)
4691 (and:SI (match_dup 2)
4692 (match_dup 6)))]
4693 {
4694 operands[4] = gen_lowpart (QImode, operands[0]);
4695 operands[5] = gen_lowpart (QImode, operands[1]);
4696 operands[6] = GEN_INT (~0xff | INTVAL (operands[3]));
4697 })
4698
4699 (define_peephole2
4700 [(set (match_operand:SI 0 "register_operand" "")
4701 (match_operand:SI 1 "register_operand" ""))
4702 (set (match_dup 0)
4703 (and:SI (match_dup 0)
4704 (const_int 65280)))]
4705 "(TARGET_H8300H || TARGET_H8300S)
4706 && !reg_overlap_mentioned_p (operands[0], operands[1])"
4707 [(set (match_dup 0)
4708 (const_int 0))
4709 (set (zero_extract:SI (match_dup 0)
4710 (const_int 8)
4711 (const_int 8))
4712 (lshiftrt:SI (match_dup 1)
4713 (const_int 8)))]
4714 "")
4715
4716 ;; If a load of mem:SI is followed by an AND that turns off the upper
4717 ;; half, then we can load mem:HI instead.
4718
4719 (define_peephole2
4720 [(set (match_operand:SI 0 "register_operand" "")
4721 (match_operand:SI 1 "memory_operand" ""))
4722 (set (match_dup 0)
4723 (and:SI (match_dup 0)
4724 (match_operand:SI 2 "const_int_operand" "")))]
4725 "(TARGET_H8300H || TARGET_H8300S)
4726 && !MEM_VOLATILE_P (operands[1])
4727 && offsettable_memref_p (operands[1])
4728 && (INTVAL (operands[2]) & ~0xffff) == 0
4729 && INTVAL (operands[2]) != 255"
4730 [(set (match_dup 3)
4731 (match_dup 4))
4732 (set (match_dup 0)
4733 (and:SI (match_dup 0)
4734 (match_dup 2)))]
4735 {
4736 operands[3] = gen_lowpart (HImode, operands[0]);
4737 operands[4] = gen_lowpart (HImode, operands[1]);
4738 })
4739
4740 ;; Convert a memory comparison to a move if there is a scratch register.
4741
4742 (define_peephole2
4743 [(match_scratch:QI 1 "r")
4744 (set (cc0)
4745 (compare (match_operand:QI 0 "memory_operand" "")
4746 (const_int 0)))]
4747 ""
4748 [(set (match_dup 1)
4749 (match_dup 0))
4750 (set (cc0) (compare (match_dup 1)
4751 (const_int 0)))]
4752 "")
4753
4754 (define_peephole2
4755 [(match_scratch:HI 1 "r")
4756 (set (cc0)
4757 (compare (match_operand:HI 0 "memory_operand" "")
4758 (const_int 0)))]
4759 "TARGET_H8300H || TARGET_H8300S"
4760 [(set (match_dup 1)
4761 (match_dup 0))
4762 (set (cc0) (compare (match_dup 1)
4763 (const_int 0)))]
4764 "")
4765
4766 (define_peephole2
4767 [(match_scratch:SI 1 "r")
4768 (set (cc0)
4769 (compare (match_operand:SI 0 "memory_operand" "")
4770 (const_int 0)))]
4771 "TARGET_H8300H || TARGET_H8300S"
4772 [(set (match_dup 1)
4773 (match_dup 0))
4774 (set (cc0) (compare (match_dup 1)
4775 (const_int 0)))]
4776 "")
4777
4778
4779 ;; (compare (reg:HI) (const_int)) takes 4 bytes, so we try to achieve
4780 ;; the equivalent with shorter sequences. Here is the summary. Cases
4781 ;; are grouped for each define_peephole2.
4782 ;;
4783 ;; reg const_int use insn
4784 ;; --------------------------------------------------------
4785 ;; dead -2 eq/ne inc.l
4786 ;; dead -1 eq/ne inc.l
4787 ;; dead 1 eq/ne dec.l
4788 ;; dead 2 eq/ne dec.l
4789 ;;
4790 ;; dead 1 ge/lt shar.l
4791 ;; dead 3 (H8S) ge/lt shar.l
4792 ;;
4793 ;; dead 1 geu/ltu shar.l
4794 ;; dead 3 (H8S) geu/ltu shar.l
4795 ;;
4796 ;; ---- 255 ge/lt mov.b
4797 ;;
4798 ;; ---- 255 geu/ltu mov.b
4799
4800 ;; Transform
4801 ;;
4802 ;; cmp.w #1,r0
4803 ;; bne .L1
4804 ;;
4805 ;; into
4806 ;;
4807 ;; dec.w #1,r0
4808 ;; bne .L1
4809
4810 (define_peephole2
4811 [(set (cc0)
4812 (compare (match_operand:HI 0 "register_operand" "")
4813 (match_operand:HI 1 "incdec_operand" "")))
4814 (set (pc)
4815 (if_then_else (match_operator 3 "eqne_operator"
4816 [(cc0) (const_int 0)])
4817 (label_ref (match_operand 2 "" ""))
4818 (pc)))]
4819 "(TARGET_H8300H || TARGET_H8300S)
4820 && INTVAL (operands[1]) != 0
4821 && peep2_reg_dead_p (1, operands[0])"
4822 [(set (match_dup 0)
4823 (unspec:HI [(match_dup 0)
4824 (match_dup 4)]
4825 UNSPEC_INCDEC))
4826 (set (cc0) (compare (match_dup 0)
4827 (const_int 0)))
4828 (set (pc)
4829 (if_then_else (match_op_dup 3 [(cc0) (const_int 0)])
4830 (label_ref (match_dup 2))
4831 (pc)))]
4832 {
4833 operands[4] = GEN_INT (- INTVAL (operands[1]));
4834 })
4835
4836 ;; Transform
4837 ;;
4838 ;; cmp.w #1,r0
4839 ;; bgt .L1
4840 ;;
4841 ;; into
4842 ;;
4843 ;; shar.w r0
4844 ;; bgt .L1
4845
4846 (define_peephole2
4847 [(set (cc0)
4848 (compare (match_operand:HI 0 "register_operand" "")
4849 (match_operand:HI 1 "const_int_operand" "")))
4850 (set (pc)
4851 (if_then_else (match_operator 2 "gtle_operator"
4852 [(cc0) (const_int 0)])
4853 (label_ref (match_operand 3 "" ""))
4854 (pc)))]
4855 "(TARGET_H8300H || TARGET_H8300S)
4856 && peep2_reg_dead_p (1, operands[0])
4857 && (INTVAL (operands[1]) == 1
4858 || (TARGET_H8300S && INTVAL (operands[1]) == 3))"
4859 [(parallel [(set (match_dup 0)
4860 (ashiftrt:HI (match_dup 0)
4861 (match_dup 4)))
4862 (clobber (scratch:QI))])
4863 (set (cc0) (compare (match_dup 0)
4864 (const_int 0)))
4865 (set (pc)
4866 (if_then_else (match_dup 2)
4867 (label_ref (match_dup 3))
4868 (pc)))]
4869 {
4870 operands[4] = GEN_INT (exact_log2 (INTVAL (operands[1]) + 1));
4871 })
4872
4873 ;; Transform
4874 ;;
4875 ;; cmp.w #1,r0
4876 ;; bhi .L1
4877 ;;
4878 ;; into
4879 ;;
4880 ;; shar.w r0
4881 ;; bne .L1
4882
4883 (define_peephole2
4884 [(set (cc0)
4885 (compare (match_operand:HI 0 "register_operand" "")
4886 (match_operand:HI 1 "const_int_operand" "")))
4887 (set (pc)
4888 (if_then_else (match_operator 2 "gtuleu_operator"
4889 [(cc0) (const_int 0)])
4890 (label_ref (match_operand 3 "" ""))
4891 (pc)))]
4892 "(TARGET_H8300H || TARGET_H8300S)
4893 && peep2_reg_dead_p (1, operands[0])
4894 && (INTVAL (operands[1]) == 1
4895 || (TARGET_H8300S && INTVAL (operands[1]) == 3))"
4896 [(parallel [(set (match_dup 0)
4897 (ashiftrt:HI (match_dup 0)
4898 (match_dup 4)))
4899 (clobber (scratch:QI))])
4900 (set (cc0) (compare (match_dup 0)
4901 (const_int 0)))
4902 (set (pc)
4903 (if_then_else (match_dup 5)
4904 (label_ref (match_dup 3))
4905 (pc)))]
4906 {
4907 operands[4] = GEN_INT (exact_log2 (INTVAL (operands[1]) + 1));
4908 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[2]) == GTU ? NE : EQ,
4909 VOIDmode, cc0_rtx, const0_rtx);
4910 })
4911
4912 ;; Transform
4913 ;;
4914 ;; cmp.w #255,r0
4915 ;; bgt .L1
4916 ;;
4917 ;; into
4918 ;;
4919 ;; mov.b r0h,r0h
4920 ;; bgt .L1
4921
4922 (define_peephole2
4923 [(set (cc0)
4924 (compare (match_operand:HI 0 "register_operand" "")
4925 (const_int 255)))
4926 (set (pc)
4927 (if_then_else (match_operator 1 "gtle_operator"
4928 [(cc0) (const_int 0)])
4929 (label_ref (match_operand 2 "" ""))
4930 (pc)))]
4931 "TARGET_H8300H || TARGET_H8300S"
4932 [(set (cc0) (compare (and:HI (match_dup 0)
4933 (const_int -256))
4934 (const_int 0)))
4935 (set (pc)
4936 (if_then_else (match_dup 1)
4937 (label_ref (match_dup 2))
4938 (pc)))]
4939 "")
4940
4941 ;; Transform
4942 ;;
4943 ;; cmp.w #255,r0
4944 ;; bhi .L1
4945 ;;
4946 ;; into
4947 ;;
4948 ;; mov.b r0h,r0h
4949 ;; bne .L1
4950
4951 (define_peephole2
4952 [(set (cc0)
4953 (compare (match_operand:HI 0 "register_operand" "")
4954 (const_int 255)))
4955 (set (pc)
4956 (if_then_else (match_operator 1 "gtuleu_operator"
4957 [(cc0) (const_int 0)])
4958 (label_ref (match_operand 2 "" ""))
4959 (pc)))]
4960 "TARGET_H8300H || TARGET_H8300S"
4961 [(set (cc0) (compare (and:HI (match_dup 0)
4962 (const_int -256))
4963 (const_int 0)))
4964 (set (pc)
4965 (if_then_else (match_dup 3)
4966 (label_ref (match_dup 2))
4967 (pc)))]
4968 {
4969 operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[1]) == GTU ? NE : EQ,
4970 VOIDmode, cc0_rtx, const0_rtx);
4971 })
4972
4973 ;; (compare (reg:SI) (const_int)) takes 6 bytes, so we try to achieve
4974 ;; the equivalent with shorter sequences. Here is the summary. Cases
4975 ;; are grouped for each define_peephole2.
4976 ;;
4977 ;; reg const_int use insn
4978 ;; --------------------------------------------------------
4979 ;; live -2 eq/ne copy and inc.l
4980 ;; live -1 eq/ne copy and inc.l
4981 ;; live 1 eq/ne copy and dec.l
4982 ;; live 2 eq/ne copy and dec.l
4983 ;;
4984 ;; dead -2 eq/ne inc.l
4985 ;; dead -1 eq/ne inc.l
4986 ;; dead 1 eq/ne dec.l
4987 ;; dead 2 eq/ne dec.l
4988 ;;
4989 ;; dead -131072 eq/ne inc.w and test
4990 ;; dead -65536 eq/ne inc.w and test
4991 ;; dead 65536 eq/ne dec.w and test
4992 ;; dead 131072 eq/ne dec.w and test
4993 ;;
4994 ;; dead 0x000000?? except 1 and 2 eq/ne xor.b and test
4995 ;; dead 0x0000??00 eq/ne xor.b and test
4996 ;; dead 0x0000ffff eq/ne not.w and test
4997 ;;
4998 ;; dead 0xffffff?? except -1 and -2 eq/ne xor.b and not.l
4999 ;; dead 0xffff??ff eq/ne xor.b and not.l
5000 ;; dead 0x40000000 (H8S) eq/ne rotl.l and dec.l
5001 ;; dead 0x80000000 eq/ne rotl.l and dec.l
5002 ;;
5003 ;; live 1 ge/lt copy and shar.l
5004 ;; live 3 (H8S) ge/lt copy and shar.l
5005 ;;
5006 ;; live 1 geu/ltu copy and shar.l
5007 ;; live 3 (H8S) geu/ltu copy and shar.l
5008 ;;
5009 ;; dead 1 ge/lt shar.l
5010 ;; dead 3 (H8S) ge/lt shar.l
5011 ;;
5012 ;; dead 1 geu/ltu shar.l
5013 ;; dead 3 (H8S) geu/ltu shar.l
5014 ;;
5015 ;; dead 3 (H8/300H) ge/lt and.b and test
5016 ;; dead 7 ge/lt and.b and test
5017 ;; dead 15 ge/lt and.b and test
5018 ;; dead 31 ge/lt and.b and test
5019 ;; dead 63 ge/lt and.b and test
5020 ;; dead 127 ge/lt and.b and test
5021 ;; dead 255 ge/lt and.b and test
5022 ;;
5023 ;; dead 3 (H8/300H) geu/ltu and.b and test
5024 ;; dead 7 geu/ltu and.b and test
5025 ;; dead 15 geu/ltu and.b and test
5026 ;; dead 31 geu/ltu and.b and test
5027 ;; dead 63 geu/ltu and.b and test
5028 ;; dead 127 geu/ltu and.b and test
5029 ;; dead 255 geu/ltu and.b and test
5030 ;;
5031 ;; ---- 65535 ge/lt mov.w
5032 ;;
5033 ;; ---- 65535 geu/ltu mov.w
5034
5035 ;; Transform
5036 ;;
5037 ;; cmp.l #1,er0
5038 ;; beq .L1
5039 ;;
5040 ;; into
5041 ;;
5042 ;; dec.l #1,er0
5043 ;; beq .L1
5044
5045 (define_peephole2
5046 [(set (cc0)
5047 (compare (match_operand:SI 0 "register_operand" "")
5048 (match_operand:SI 1 "incdec_operand" "")))
5049 (set (pc)
5050 (if_then_else (match_operator 3 "eqne_operator"
5051 [(cc0) (const_int 0)])
5052 (label_ref (match_operand 2 "" ""))
5053 (pc)))]
5054 "(TARGET_H8300H || TARGET_H8300S)
5055 && INTVAL (operands[1]) != 0
5056 && peep2_reg_dead_p (1, operands[0])"
5057 [(set (match_dup 0)
5058 (unspec:SI [(match_dup 0)
5059 (match_dup 4)]
5060 UNSPEC_INCDEC))
5061 (set (cc0) (compare (match_dup 0)
5062 (const_int 0)))
5063 (set (pc)
5064 (if_then_else (match_op_dup 3 [(cc0) (const_int 0)])
5065 (label_ref (match_dup 2))
5066 (pc)))]
5067 {
5068 operands[4] = GEN_INT (- INTVAL (operands[1]));
5069 })
5070
5071 ;; Transform
5072 ;;
5073 ;; cmp.l #65536,er0
5074 ;; beq .L1
5075 ;;
5076 ;; into
5077 ;;
5078 ;; dec.l #1,e0
5079 ;; beq .L1
5080
5081 (define_peephole2
5082 [(set (cc0)
5083 (compare (match_operand:SI 0 "register_operand" "")
5084 (match_operand:SI 1 "const_int_operand" "")))
5085 (set (pc)
5086 (if_then_else (match_operator 3 "eqne_operator"
5087 [(cc0) (const_int 0)])
5088 (label_ref (match_operand 2 "" ""))
5089 (pc)))]
5090 "(TARGET_H8300H || TARGET_H8300S)
5091 && peep2_reg_dead_p (1, operands[0])
5092 && (INTVAL (operands[1]) == -131072
5093 || INTVAL (operands[1]) == -65536
5094 || INTVAL (operands[1]) == 65536
5095 || INTVAL (operands[1]) == 131072)"
5096 [(set (match_dup 0)
5097 (plus:SI (match_dup 0)
5098 (match_dup 4)))
5099 (set (cc0) (compare (match_dup 0)
5100 (const_int 0)))
5101 (set (pc)
5102 (if_then_else (match_op_dup 3 [(cc0) (const_int 0)])
5103 (label_ref (match_dup 2))
5104 (pc)))]
5105 {
5106 operands[4] = GEN_INT (- INTVAL (operands[1]));
5107 })
5108
5109 ;; Transform
5110 ;;
5111 ;; cmp.l #100,er0
5112 ;; beq .L1
5113 ;;
5114 ;; into
5115 ;;
5116 ;; xor.b #100,er0
5117 ;; mov.l er0,er0
5118 ;; beq .L1
5119
5120 (define_peephole2
5121 [(set (cc0)
5122 (compare (match_operand:SI 0 "register_operand" "")
5123 (match_operand:SI 1 "const_int_operand" "")))
5124 (set (pc)
5125 (if_then_else (match_operator 3 "eqne_operator"
5126 [(cc0) (const_int 0)])
5127 (label_ref (match_operand 2 "" ""))
5128 (pc)))]
5129 "(TARGET_H8300H || TARGET_H8300S)
5130 && peep2_reg_dead_p (1, operands[0])
5131 && ((INTVAL (operands[1]) & 0x00ff) == INTVAL (operands[1])
5132 || (INTVAL (operands[1]) & 0xff00) == INTVAL (operands[1])
5133 || INTVAL (operands[1]) == 0x0000ffff)
5134 && INTVAL (operands[1]) != 0
5135 && INTVAL (operands[1]) != 1
5136 && INTVAL (operands[1]) != 2"
5137 [(set (match_dup 0)
5138 (xor:SI (match_dup 0)
5139 (match_dup 1)))
5140 (set (cc0) (compare (match_dup 0)
5141 (const_int 0)))
5142 (set (pc)
5143 (if_then_else (match_op_dup 3 [(cc0) (const_int 0)])
5144 (label_ref (match_dup 2))
5145 (pc)))]
5146 "")
5147
5148 ;; Transform
5149 ;;
5150 ;; cmp.l #-100,er0
5151 ;; beq .L1
5152 ;;
5153 ;; into
5154 ;;
5155 ;; xor.b #99,er0
5156 ;; not.l er0
5157 ;; beq .L1
5158
5159 (define_peephole2
5160 [(set (cc0)
5161 (compare (match_operand:SI 0 "register_operand" "")
5162 (match_operand:SI 1 "const_int_operand" "")))
5163 (set (pc)
5164 (if_then_else (match_operator 3 "eqne_operator"
5165 [(cc0) (const_int 0)])
5166 (label_ref (match_operand 2 "" ""))
5167 (pc)))]
5168 "(TARGET_H8300H || TARGET_H8300S)
5169 && peep2_reg_dead_p (1, operands[0])
5170 && ((INTVAL (operands[1]) | 0x00ff) == -1
5171 || (INTVAL (operands[1]) | 0xff00) == -1)
5172 && INTVAL (operands[1]) != -1
5173 && INTVAL (operands[1]) != -2"
5174 [(set (match_dup 0)
5175 (xor:SI (match_dup 0)
5176 (match_dup 4)))
5177 (set (match_dup 0)
5178 (not:SI (match_dup 0)))
5179 (set (cc0) (compare (match_dup 0)
5180 (const_int 0)))
5181 (set (pc)
5182 (if_then_else (match_op_dup 3 [(cc0) (const_int 0)])
5183 (label_ref (match_dup 2))
5184 (pc)))]
5185 {
5186 operands[4] = GEN_INT (INTVAL (operands[1]) ^ -1);
5187 })
5188
5189 ;; Transform
5190 ;;
5191 ;; cmp.l #-2147483648,er0
5192 ;; beq .L1
5193 ;;
5194 ;; into
5195 ;;
5196 ;; rotl.l er0
5197 ;; dec.l #1,er0
5198 ;; beq .L1
5199
5200 (define_peephole2
5201 [(set (cc0)
5202 (compare (match_operand:SI 0 "register_operand" "")
5203 (match_operand:SI 1 "const_int_operand" "")))
5204 (set (pc)
5205 (if_then_else (match_operator 3 "eqne_operator"
5206 [(cc0) (const_int 0)])
5207 (label_ref (match_operand 2 "" ""))
5208 (pc)))]
5209 "(TARGET_H8300H || TARGET_H8300S)
5210 && peep2_reg_dead_p (1, operands[0])
5211 && (INTVAL (operands[1]) == -2147483647 - 1
5212 || (TARGET_H8300S && INTVAL (operands[1]) == 1073741824))"
5213 [(set (match_dup 0)
5214 (rotate:SI (match_dup 0)
5215 (match_dup 4)))
5216 (set (match_dup 0)
5217 (unspec:SI [(match_dup 0)
5218 (const_int -1)]
5219 UNSPEC_INCDEC))
5220 (set (cc0) (compare (match_dup 0)
5221 (const_int 0)))
5222 (set (pc)
5223 (if_then_else (match_op_dup 3 [(cc0) (const_int 0)])
5224 (label_ref (match_dup 2))
5225 (pc)))]
5226 {
5227 operands[4] = GEN_INT (INTVAL (operands[1]) == -2147483647 - 1 ? 1 : 2);
5228 })
5229
5230 ;; Transform
5231 ;;
5232 ;; cmp.l #1,er0
5233 ;; bgt .L1
5234 ;;
5235 ;; into
5236 ;;
5237 ;; mov.l er0,er1
5238 ;; shar.l er1
5239 ;; bgt .L1
5240
5241 ;; We avoid this transformation if we see more than one copy of the
5242 ;; same compare insn immediately before this one.
5243
5244 (define_peephole2
5245 [(match_scratch:SI 4 "r")
5246 (set (cc0)
5247 (compare (match_operand:SI 0 "register_operand" "")
5248 (match_operand:SI 1 "const_int_operand" "")))
5249 (set (pc)
5250 (if_then_else (match_operator 2 "gtle_operator"
5251 [(cc0) (const_int 0)])
5252 (label_ref (match_operand 3 "" ""))
5253 (pc)))]
5254 "(TARGET_H8300H || TARGET_H8300S)
5255 && !peep2_reg_dead_p (1, operands[0])
5256 && (INTVAL (operands[1]) == 1
5257 || (TARGET_H8300S && INTVAL (operands[1]) == 3))
5258 && !same_cmp_preceding_p (insn)"
5259 [(set (match_dup 4)
5260 (match_dup 0))
5261 (parallel [(set (match_dup 4)
5262 (ashiftrt:SI (match_dup 4)
5263 (match_dup 5)))
5264 (clobber (scratch:QI))])
5265 (set (cc0) (compare (match_dup 4)
5266 (const_int 0)))
5267 (set (pc)
5268 (if_then_else (match_dup 2)
5269 (label_ref (match_dup 3))
5270 (pc)))]
5271 {
5272 operands[5] = GEN_INT (exact_log2 (INTVAL (operands[1]) + 1));
5273 })
5274
5275 ;; Transform
5276 ;;
5277 ;; cmp.l #1,er0
5278 ;; bhi .L1
5279 ;;
5280 ;; into
5281 ;;
5282 ;; mov.l er0,er1
5283 ;; shar.l er1
5284 ;; bne .L1
5285
5286 ;; We avoid this transformation if we see more than one copy of the
5287 ;; same compare insn immediately before this one.
5288
5289 (define_peephole2
5290 [(match_scratch:SI 4 "r")
5291 (set (cc0)
5292 (compare (match_operand:SI 0 "register_operand" "")
5293 (match_operand:SI 1 "const_int_operand" "")))
5294 (set (pc)
5295 (if_then_else (match_operator 2 "gtuleu_operator"
5296 [(cc0) (const_int 0)])
5297 (label_ref (match_operand 3 "" ""))
5298 (pc)))]
5299 "(TARGET_H8300H || TARGET_H8300S)
5300 && !peep2_reg_dead_p (1, operands[0])
5301 && (INTVAL (operands[1]) == 1
5302 || (TARGET_H8300S && INTVAL (operands[1]) == 3))
5303 && !same_cmp_preceding_p (insn)"
5304 [(set (match_dup 4)
5305 (match_dup 0))
5306 (parallel [(set (match_dup 4)
5307 (ashiftrt:SI (match_dup 4)
5308 (match_dup 5)))
5309 (clobber (scratch:QI))])
5310 (set (cc0) (compare (match_dup 4)
5311 (const_int 0)))
5312 (set (pc)
5313 (if_then_else (match_dup 6)
5314 (label_ref (match_dup 3))
5315 (pc)))]
5316 {
5317 operands[5] = GEN_INT (exact_log2 (INTVAL (operands[1]) + 1));
5318 operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[2]) == GTU ? NE : EQ,
5319 VOIDmode, cc0_rtx, const0_rtx);
5320 })
5321
5322 ;; Transform
5323 ;;
5324 ;; cmp.l #1,er0
5325 ;; bgt .L1
5326 ;;
5327 ;; into
5328 ;;
5329 ;; shar.l er0
5330 ;; bgt .L1
5331
5332 (define_peephole2
5333 [(set (cc0)
5334 (compare (match_operand:SI 0 "register_operand" "")
5335 (match_operand:SI 1 "const_int_operand" "")))
5336 (set (pc)
5337 (if_then_else (match_operator 2 "gtle_operator"
5338 [(cc0) (const_int 0)])
5339 (label_ref (match_operand 3 "" ""))
5340 (pc)))]
5341 "(TARGET_H8300H || TARGET_H8300S)
5342 && peep2_reg_dead_p (1, operands[0])
5343 && (INTVAL (operands[1]) == 1
5344 || (TARGET_H8300S && INTVAL (operands[1]) == 3))"
5345 [(parallel [(set (match_dup 0)
5346 (ashiftrt:SI (match_dup 0)
5347 (match_dup 4)))
5348 (clobber (scratch:QI))])
5349 (set (cc0) (compare (match_dup 0)
5350 (const_int 0)))
5351 (set (pc)
5352 (if_then_else (match_dup 2)
5353 (label_ref (match_dup 3))
5354 (pc)))]
5355 {
5356 operands[4] = GEN_INT (exact_log2 (INTVAL (operands[1]) + 1));
5357 })
5358
5359 ;; Transform
5360 ;;
5361 ;; cmp.l #1,er0
5362 ;; bhi .L1
5363 ;;
5364 ;; into
5365 ;;
5366 ;; shar.l er0
5367 ;; bne .L1
5368
5369 (define_peephole2
5370 [(set (cc0)
5371 (compare (match_operand:SI 0 "register_operand" "")
5372 (match_operand:SI 1 "const_int_operand" "")))
5373 (set (pc)
5374 (if_then_else (match_operator 2 "gtuleu_operator"
5375 [(cc0) (const_int 0)])
5376 (label_ref (match_operand 3 "" ""))
5377 (pc)))]
5378 "(TARGET_H8300H || TARGET_H8300S)
5379 && peep2_reg_dead_p (1, operands[0])
5380 && (INTVAL (operands[1]) == 1
5381 || (TARGET_H8300S && INTVAL (operands[1]) == 3))"
5382 [(parallel [(set (match_dup 0)
5383 (ashiftrt:SI (match_dup 0)
5384 (match_dup 4)))
5385 (clobber (scratch:QI))])
5386 (set (cc0) (compare (match_dup 0)
5387 (const_int 0)))
5388 (set (pc)
5389 (if_then_else (match_dup 5)
5390 (label_ref (match_dup 3))
5391 (pc)))]
5392 {
5393 operands[4] = GEN_INT (exact_log2 (INTVAL (operands[1]) + 1));
5394 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[2]) == GTU ? NE : EQ,
5395 VOIDmode, cc0_rtx, const0_rtx);
5396 })
5397
5398 ;; Transform
5399 ;;
5400 ;; cmp.l #15,er0
5401 ;; bgt .L1
5402 ;;
5403 ;; into
5404 ;;
5405 ;; and #240,r0l
5406 ;; mov.l er0,er0
5407 ;; bgt .L1
5408
5409 (define_peephole2
5410 [(set (cc0)
5411 (compare (match_operand:SI 0 "register_operand" "")
5412 (match_operand:SI 1 "const_int_operand" "")))
5413 (set (pc)
5414 (if_then_else (match_operator 2 "gtle_operator"
5415 [(cc0) (const_int 0)])
5416 (label_ref (match_operand 3 "" ""))
5417 (pc)))]
5418 "(TARGET_H8300H || TARGET_H8300S)
5419 && peep2_reg_dead_p (1, operands[0])
5420 && (INTVAL (operands[1]) == 3
5421 || INTVAL (operands[1]) == 7
5422 || INTVAL (operands[1]) == 15
5423 || INTVAL (operands[1]) == 31
5424 || INTVAL (operands[1]) == 63
5425 || INTVAL (operands[1]) == 127
5426 || INTVAL (operands[1]) == 255)"
5427 [(set (match_dup 0)
5428 (and:SI (match_dup 0)
5429 (match_dup 4)))
5430 (set (cc0) (compare (match_dup 0)
5431 (const_int 0)))
5432 (set (pc)
5433 (if_then_else (match_dup 2)
5434 (label_ref (match_dup 3))
5435 (pc)))]
5436 {
5437 operands[4] = GEN_INT (~INTVAL (operands[1]));
5438 })
5439
5440 ;; Transform
5441 ;;
5442 ;; cmp.l #15,er0
5443 ;; bhi .L1
5444 ;;
5445 ;; into
5446 ;;
5447 ;; and #240,r0l
5448 ;; mov.l er0,er0
5449 ;; bne .L1
5450
5451 (define_peephole2
5452 [(set (cc0)
5453 (compare (match_operand:SI 0 "register_operand" "")
5454 (match_operand:SI 1 "const_int_operand" "")))
5455 (set (pc)
5456 (if_then_else (match_operator 2 "gtuleu_operator"
5457 [(cc0) (const_int 0)])
5458 (label_ref (match_operand 3 "" ""))
5459 (pc)))]
5460 "(TARGET_H8300H || TARGET_H8300S)
5461 && peep2_reg_dead_p (1, operands[0])
5462 && ((TARGET_H8300H && INTVAL (operands[1]) == 3)
5463 || INTVAL (operands[1]) == 7
5464 || INTVAL (operands[1]) == 15
5465 || INTVAL (operands[1]) == 31
5466 || INTVAL (operands[1]) == 63
5467 || INTVAL (operands[1]) == 127
5468 || INTVAL (operands[1]) == 255)"
5469 [(set (match_dup 0)
5470 (and:SI (match_dup 0)
5471 (match_dup 4)))
5472 (set (cc0) (compare (match_dup 0)
5473 (const_int 0)))
5474 (set (pc)
5475 (if_then_else (match_dup 5)
5476 (label_ref (match_dup 3))
5477 (pc)))]
5478 {
5479 operands[4] = GEN_INT (~INTVAL (operands[1]));
5480 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[2]) == GTU ? NE : EQ,
5481 VOIDmode, cc0_rtx, const0_rtx);
5482 })
5483
5484 ;; Transform
5485 ;;
5486 ;; cmp.l #65535,er0
5487 ;; bgt .L1
5488 ;;
5489 ;; into
5490 ;;
5491 ;; mov.l e0,e0
5492 ;; bgt .L1
5493
5494 (define_peephole2
5495 [(set (cc0)
5496 (compare (match_operand:SI 0 "register_operand" "")
5497 (const_int 65535)))
5498 (set (pc)
5499 (if_then_else (match_operator 1 "gtle_operator"
5500 [(cc0) (const_int 0)])
5501 (label_ref (match_operand 2 "" ""))
5502 (pc)))]
5503 "TARGET_H8300H || TARGET_H8300S"
5504 [(set (cc0) (compare (and:SI (match_dup 0)
5505 (const_int -65536))
5506 (const_int 0)))
5507 (set (pc)
5508 (if_then_else (match_dup 1)
5509 (label_ref (match_dup 2))
5510 (pc)))]
5511 "")
5512
5513 ;; Transform
5514 ;;
5515 ;; cmp.l #65535,er0
5516 ;; bhi .L1
5517 ;;
5518 ;; into
5519 ;;
5520 ;; mov.l e0,e0
5521 ;; bne .L1
5522
5523 (define_peephole2
5524 [(set (cc0)
5525 (compare (match_operand:SI 0 "register_operand" "")
5526 (const_int 65535)))
5527 (set (pc)
5528 (if_then_else (match_operator 1 "gtuleu_operator"
5529 [(cc0) (const_int 0)])
5530 (label_ref (match_operand 2 "" ""))
5531 (pc)))]
5532 "TARGET_H8300H || TARGET_H8300S"
5533 [(set (cc0) (compare (and:SI (match_dup 0)
5534 (const_int -65536))
5535 (const_int 0)))
5536 (set (pc)
5537 (if_then_else (match_dup 3)
5538 (label_ref (match_dup 2))
5539 (pc)))]
5540 {
5541 operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[1]) == GTU ? NE : EQ,
5542 VOIDmode, cc0_rtx, const0_rtx);
5543 })
5544
5545 ;; Transform
5546 ;;
5547 ;; cmp.l #1,er0
5548 ;; beq .L1
5549 ;;
5550 ;; into
5551 ;;
5552 ;; mov.l er0,er1
5553 ;; dec.l #1,er1
5554 ;; beq .L1
5555
5556 ;; We avoid this transformation if we see more than one copy of the
5557 ;; same compare insn.
5558
5559 (define_peephole2
5560 [(match_scratch:SI 4 "r")
5561 (set (cc0)
5562 (compare (match_operand:SI 0 "register_operand" "")
5563 (match_operand:SI 1 "incdec_operand" "")))
5564 (set (pc)
5565 (if_then_else (match_operator 3 "eqne_operator"
5566 [(cc0) (const_int 0)])
5567 (label_ref (match_operand 2 "" ""))
5568 (pc)))]
5569 "(TARGET_H8300H || TARGET_H8300S)
5570 && INTVAL (operands[1]) != 0
5571 && !peep2_reg_dead_p (1, operands[0])
5572 && !same_cmp_following_p (insn)"
5573 [(set (match_dup 4)
5574 (match_dup 0))
5575 (set (match_dup 4)
5576 (unspec:SI [(match_dup 4)
5577 (match_dup 5)]
5578 UNSPEC_INCDEC))
5579 (set (cc0) (compare (match_dup 4)
5580 (const_int 0)))
5581 (set (pc)
5582 (if_then_else (match_op_dup 3 [(cc0) (const_int 0)])
5583 (label_ref (match_dup 2))
5584 (pc)))]
5585 {
5586 operands[5] = GEN_INT (- INTVAL (operands[1]));
5587 })
5588 ;; Narrow the mode of testing if possible.
5589
5590 (define_peephole2
5591 [(set (match_operand:HI 0 "register_operand" "")
5592 (and:HI (match_dup 0)
5593 (match_operand:HI 1 "const_int_qi_operand" "")))
5594 (set (cc0) (compare (match_dup 0)
5595 (const_int 0)))
5596 (set (pc)
5597 (if_then_else (match_operator 3 "eqne_operator"
5598 [(cc0) (const_int 0)])
5599 (label_ref (match_operand 2 "" ""))
5600 (pc)))]
5601 "peep2_reg_dead_p (2, operands[0])"
5602 [(set (match_dup 4)
5603 (and:QI (match_dup 4)
5604 (match_dup 5)))
5605 (set (cc0) (compare (match_dup 4)
5606 (const_int 0)))
5607 (set (pc)
5608 (if_then_else (match_op_dup 3 [(cc0) (const_int 0)])
5609 (label_ref (match_dup 2))
5610 (pc)))]
5611 {
5612 operands[4] = gen_rtx_REG (QImode, REGNO (operands[0]));
5613 operands[5] = gen_int_mode (INTVAL (operands[1]), QImode);
5614 })
5615
5616 (define_peephole2
5617 [(set (match_operand:SI 0 "register_operand" "")
5618 (and:SI (match_dup 0)
5619 (match_operand:SI 1 "const_int_qi_operand" "")))
5620 (set (cc0) (compare (match_dup 0)
5621 (const_int 0)))
5622 (set (pc)
5623 (if_then_else (match_operator 3 "eqne_operator"
5624 [(cc0) (const_int 0)])
5625 (label_ref (match_operand 2 "" ""))
5626 (pc)))]
5627 "peep2_reg_dead_p (2, operands[0])"
5628 [(set (match_dup 4)
5629 (and:QI (match_dup 4)
5630 (match_dup 5)))
5631 (set (cc0) (compare (match_dup 4)
5632 (const_int 0)))
5633 (set (pc)
5634 (if_then_else (match_op_dup 3 [(cc0) (const_int 0)])
5635 (label_ref (match_dup 2))
5636 (pc)))]
5637 {
5638 operands[4] = gen_rtx_REG (QImode, REGNO (operands[0]));
5639 operands[5] = gen_int_mode (INTVAL (operands[1]), QImode);
5640 })
5641
5642 (define_peephole2
5643 [(set (match_operand:SI 0 "register_operand" "")
5644 (and:SI (match_dup 0)
5645 (match_operand:SI 1 "const_int_hi_operand" "")))
5646 (set (cc0) (compare (match_dup 0)
5647 (const_int 0)))
5648 (set (pc)
5649 (if_then_else (match_operator 3 "eqne_operator"
5650 [(cc0) (const_int 0)])
5651 (label_ref (match_operand 2 "" ""))
5652 (pc)))]
5653 "peep2_reg_dead_p (2, operands[0])"
5654 [(set (match_dup 4)
5655 (and:HI (match_dup 4)
5656 (match_dup 5)))
5657 (set (cc0) (compare (match_dup 4)
5658 (const_int 0)))
5659 (set (pc)
5660 (if_then_else (match_op_dup 3 [(cc0) (const_int 0)])
5661 (label_ref (match_dup 2))
5662 (pc)))]
5663 {
5664 operands[4] = gen_rtx_REG (HImode, REGNO (operands[0]));
5665 operands[5] = gen_int_mode (INTVAL (operands[1]), HImode);
5666 })
5667
5668 (define_peephole2
5669 [(set (match_operand:SI 0 "register_operand" "")
5670 (and:SI (match_dup 0)
5671 (match_operand:SI 1 "const_int_qi_operand" "")))
5672 (set (match_dup 0)
5673 (xor:SI (match_dup 0)
5674 (match_operand:SI 2 "const_int_qi_operand" "")))
5675 (set (cc0) (compare (match_dup 0)
5676 (const_int 0)))
5677 (set (pc)
5678 (if_then_else (match_operator 4 "eqne_operator"
5679 [(cc0) (const_int 0)])
5680 (label_ref (match_operand 3 "" ""))
5681 (pc)))]
5682 "peep2_reg_dead_p (3, operands[0])
5683 && (~INTVAL (operands[1]) & INTVAL (operands[2])) == 0"
5684 [(set (match_dup 5)
5685 (and:QI (match_dup 5)
5686 (match_dup 6)))
5687 (set (match_dup 5)
5688 (xor:QI (match_dup 5)
5689 (match_dup 7)))
5690 (set (cc0) (compare (match_dup 5)
5691 (const_int 0)))
5692 (set (pc)
5693 (if_then_else (match_op_dup 4 [(cc0) (const_int 0)])
5694 (label_ref (match_dup 3))
5695 (pc)))]
5696 {
5697 operands[5] = gen_rtx_REG (QImode, REGNO (operands[0]));
5698 operands[6] = gen_int_mode (INTVAL (operands[1]), QImode);
5699 operands[7] = gen_int_mode (INTVAL (operands[2]), QImode);
5700 })
5701
5702 ;; These triggers right at the end of allocation of locals in the
5703 ;; prologue (and possibly at other places).
5704
5705 ;; stack adjustment of -4, generate one push
5706 ;;
5707 ;; before : 6 bytes, 10 clocks
5708 ;; after : 4 bytes, 10 clocks
5709
5710 (define_peephole2
5711 [(set (reg:SI SP_REG)
5712 (plus:SI (reg:SI SP_REG)
5713 (const_int -4)))
5714 (set (mem:SI (reg:SI SP_REG))
5715 (match_operand:SI 0 "register_operand" ""))]
5716 "(TARGET_H8300H || TARGET_H8300S) && !TARGET_NORMAL_MODE
5717 && REGNO (operands[0]) != SP_REG"
5718 [(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
5719 (match_dup 0))]
5720 "")
5721
5722 ;; stack adjustment of -12, generate one push
5723 ;;
5724 ;; before : 10 bytes, 14 clocks
5725 ;; after : 8 bytes, 14 clocks
5726
5727 (define_peephole2
5728 [(set (reg:SI SP_REG)
5729 (plus:SI (reg:SI SP_REG)
5730 (const_int -12)))
5731 (set (mem:SI (reg:SI SP_REG))
5732 (match_operand:SI 0 "register_operand" ""))]
5733 "(TARGET_H8300H || TARGET_H8300S) && !TARGET_NORMAL_MODE
5734 && REGNO (operands[0]) != SP_REG"
5735 [(set (reg:SI SP_REG)
5736 (plus:SI (reg:SI SP_REG)
5737 (const_int -4)))
5738 (set (reg:SI SP_REG)
5739 (plus:SI (reg:SI SP_REG)
5740 (const_int -4)))
5741 (set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
5742 (match_dup 0))]
5743 "")
5744
5745 ;; Transform
5746 ;;
5747 ;; mov dst,reg
5748 ;; op src,reg
5749 ;; mov reg,dst
5750 ;;
5751 ;; into
5752 ;;
5753 ;; op src,dst
5754 ;;
5755 ;; if "reg" dies at the end of the sequence.
5756
5757 (define_peephole2
5758 [(set (match_operand 0 "register_operand" "")
5759 (match_operand 1 "memory_operand" ""))
5760 (set (match_dup 0)
5761 (match_operator 2 "h8sx_binary_memory_operator"
5762 [(match_dup 0)
5763 (match_operand 3 "h8300_src_operand" "")]))
5764 (set (match_operand 4 "memory_operand" "")
5765 (match_dup 0))]
5766 "0 /* Disable because it breaks compiling fp-bit.c. */
5767 && TARGET_H8300SX
5768 && peep2_reg_dead_p (3, operands[0])
5769 && !reg_overlap_mentioned_p (operands[0], operands[3])
5770 && !reg_overlap_mentioned_p (operands[0], operands[4])
5771 && h8sx_mergeable_memrefs_p (operands[4], operands[1])"
5772 [(set (match_dup 4)
5773 (match_dup 5))]
5774 {
5775 operands[5] = shallow_copy_rtx (operands[2]);
5776 XEXP (operands[5], 0) = operands[1];
5777 })
5778
5779 ;; Transform
5780 ;;
5781 ;; mov src,reg
5782 ;; op reg,dst
5783 ;;
5784 ;; into
5785 ;;
5786 ;; op src,dst
5787 ;;
5788 ;; if "reg" dies in the second insn.
5789
5790 (define_peephole2
5791 [(set (match_operand 0 "register_operand" "")
5792 (match_operand 1 "h8300_src_operand" ""))
5793 (set (match_operand 2 "h8300_dst_operand" "")
5794 (match_operator 3 "h8sx_binary_memory_operator"
5795 [(match_operand 4 "h8300_dst_operand" "")
5796 (match_dup 0)]))]
5797 "0 /* Disable because it breaks compiling fp-bit.c. */
5798 && TARGET_H8300SX
5799 && peep2_reg_dead_p (2, operands[0])
5800 && !reg_overlap_mentioned_p (operands[0], operands[4])"
5801 [(set (match_dup 2)
5802 (match_dup 5))]
5803 {
5804 operands[5] = shallow_copy_rtx (operands[3]);
5805 XEXP (operands[5], 1) = operands[1];
5806 })
5807
5808 ;; Transform
5809 ;;
5810 ;; mov dst,reg
5811 ;; op reg
5812 ;; mov reg,dst
5813 ;;
5814 ;; into
5815 ;;
5816 ;; op dst
5817 ;;
5818 ;; if "reg" dies at the end of the sequence.
5819
5820 (define_peephole2
5821 [(set (match_operand 0 "register_operand" "")
5822 (match_operand 1 "memory_operand" ""))
5823 (set (match_dup 0)
5824 (match_operator 2 "h8sx_unary_memory_operator"
5825 [(match_dup 0)]))
5826 (set (match_operand 3 "memory_operand" "")
5827 (match_dup 0))]
5828 "TARGET_H8300SX
5829 && peep2_reg_dead_p (3, operands[0])
5830 && !reg_overlap_mentioned_p (operands[0], operands[3])
5831 && h8sx_mergeable_memrefs_p (operands[3], operands[1])"
5832 [(set (match_dup 3)
5833 (match_dup 4))]
5834 {
5835 operands[4] = shallow_copy_rtx (operands[2]);
5836 XEXP (operands[4], 0) = operands[1];
5837 })
5838
5839 ;; Transform
5840 ;;
5841 ;; mov src1,reg
5842 ;; cmp reg,src2
5843 ;;
5844 ;; into
5845 ;;
5846 ;; cmp src1,src2
5847 ;;
5848 ;; if "reg" dies in the comparison.
5849
5850 (define_peephole2
5851 [(set (match_operand 0 "register_operand" "")
5852 (match_operand 1 "h8300_dst_operand" ""))
5853 (set (cc0)
5854 (compare (match_dup 0)
5855 (match_operand 2 "h8300_src_operand" "")))]
5856 "TARGET_H8300SX
5857 && peep2_reg_dead_p (2, operands[0])
5858 && !reg_overlap_mentioned_p (operands[0], operands[2])
5859 && operands[2] != const0_rtx"
5860 [(set (cc0)
5861 (compare (match_dup 1)
5862 (match_dup 2)))])
5863
5864 ;; Likewise for the second operand.
5865
5866 (define_peephole2
5867 [(set (match_operand 0 "register_operand" "")
5868 (match_operand 1 "h8300_src_operand" ""))
5869 (set (cc0)
5870 (compare (match_operand 2 "h8300_dst_operand" "")
5871 (match_dup 0)))]
5872 "TARGET_H8300SX
5873 && peep2_reg_dead_p (2, operands[0])
5874 && !reg_overlap_mentioned_p (operands[0], operands[2])"
5875 [(set (cc0)
5876 (compare (match_dup 2)
5877 (match_dup 1)))])
5878
5879 ;; Combine two moves.
5880
5881 (define_peephole2
5882 [(set (match_operand 0 "register_operand" "")
5883 (match_operand 1 "h8300_src_operand" ""))
5884 (set (match_operand 2 "h8300_dst_operand" "")
5885 (match_dup 0))]
5886 "TARGET_H8300SX
5887 && peep2_reg_dead_p (2, operands[0])
5888 && !reg_overlap_mentioned_p (operands[0], operands[2])"
5889 [(set (match_dup 2)
5890 (match_dup 1))])
5891
5892