constraints.md: Add "C" constraint for call insns.
[official-gcc.git] / gcc / config / h8300 / h8300.md
blob0686f25d71de857dc46a426de6463850f29382fd
1 ;; GCC machine description for Renesas H8/300
2 ;; Copyright (C) 1992-2018 Free Software Foundation, Inc.
4 ;;   Contributed by Steve Chamberlain (sac@cygnus.com),
5 ;;   Jim Wilson (wilson@cygnus.com), and Doug Evans (dje@cygnus.com).
7 ;; This file is part of GCC.
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.
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.
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/>.
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".
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.
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.
37 ;; Shifts/rotates by small constants should be handled by special
38 ;; patterns so we get the length and cc status correct.
40 ;; Bitfield operations no longer accept memory operands.  We need
41 ;; to add variants which operate on memory back to the MD.
43 ;; ??? Implement remaining bit ops available on the h8300
45 ;; ----------------------------------------------------------------------
46 ;; CONSTANTS
47 ;; ----------------------------------------------------------------------
49 (define_constants
50   [(UNSPEC_INCDEC       0)
51    (UNSPEC_MONITOR      1)])
53 (define_constants
54   [(UNSPEC_MOVMD        100)
55    (UNSPEC_STPCPY       101)])
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)])
70 ;; ----------------------------------------------------------------------
71 ;; ATTRIBUTES
72 ;; ----------------------------------------------------------------------
74 (define_attr "cpu" "h8300,h8300h"
75   (const (symbol_ref "cpu_type")))
77 (define_attr "type" "branch,arith,bitbranch,call"
78   (const_string "arith"))
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"))
83 ;; The size of instructions in bytes.
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)))
122 ;; Condition code settings.
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
133 (define_attr "cc" "none,none_0hit,set_znv,set_zn,compare,clobber"
134   (const_string "clobber"))
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.
140 (define_attr "delay_slot" "none,jump"
141   (const_string "none"))
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.
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")))
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.
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)])
165 ;; Provide the maximum length of an assembly instruction in an asm
166 ;; statement.  The maximum length of 14 bytes is achieved on H8SX.
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)))])
175 (include "predicates.md")
176 (include "constraints.md")
178 ;; ----------------------------------------------------------------------
179 ;; MACRO DEFINITIONS
180 ;; ----------------------------------------------------------------------
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.
185 (define_mode_iterator P [(HI "Pmode == HImode") (SI "Pmode == SImode")])
187 (define_mode_iterator QHI [QI HI])
189 (define_mode_iterator HSI [HI SI])
191 (define_mode_iterator QHSI [QI HI SI])
193 (define_mode_iterator QHSIF [QI HI SI SF])
195 (define_code_iterator shifts [ashift ashiftrt lshiftrt])
197 (define_code_iterator ors [ior xor])
199 ;; ----------------------------------------------------------------------
200 ;; MOVE INSTRUCTIONS
201 ;; ----------------------------------------------------------------------
203 ;; movqi
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")])
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")])
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.
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   })
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")])
266 ;; movhi
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")])
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")])
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")])
310 ;; movsi
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])"
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     }
378   [(set (attr "length")
379         (symbol_ref "compute_mov_length (operands)"))])
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])"
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]);
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             }
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             }
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";
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";
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";
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";
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")])
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")])
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")])
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.
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   })
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).
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   })
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.
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")])
534 ;; Split the above instruction if the destination register isn't er6.
535 ;; We need a sequence like:
537 ;;      mov.l   er6,@-er7
538 ;;      mov.l   <dest>,er6
539 ;;      movmd.sz
540 ;;      mov.l   er6,<dest>
541 ;;      mov.l   @er7+,er6
543 ;; where <dest> is the current destination register (operand 4).
544 ;; The fourth instruction will be deleted if <dest> dies here.
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;
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   })
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.
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   })
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.
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   })
605 ;; See comments above memcpy_internal().
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")])
621 ;; Split the above instruction if the destination isn't er6.  This works
622 ;; in the same way as the movmd splitter.
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;
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   })
643 (include "mova.md")
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))"
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";
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     }
697   [(set (attr "length")
698         (symbol_ref "compute_mov_length (operands)"))])
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")])
717 ;; ----------------------------------------------------------------------
718 ;; PUSH INSTRUCTIONS
719 ;; ----------------------------------------------------------------------
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")])
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")])
742 ;; ----------------------------------------------------------------------
743 ;; TEST INSTRUCTIONS
744 ;; ----------------------------------------------------------------------
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")])
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")])
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")])
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   })
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")])
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")])
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")])
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")])
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")])
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")])
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")])
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")])
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"
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       }
940   [(set_attr "length_table" "short_immediate,add")
941    (set_attr "cc" "compare,compare")])
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"
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     }
962   [(set_attr "length" "2,*")
963    (set_attr "length_table" "*,add")
964    (set_attr "cc" "compare,compare")])
966 ;; ----------------------------------------------------------------------
967 ;; ADD INSTRUCTIONS
968 ;; ----------------------------------------------------------------------
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   "")
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")])
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")])
1000 ;; This splitter is very important to make the stack adjustment
1001 ;; interrupt-safe.  The combination of add.b and addx is unsafe!
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.
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   })
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   "")
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")])
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")])
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")])
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   })
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"
1094   return output_plussi (operands);
1096   [(set (attr "length")
1097         (symbol_ref "compute_plussi_length (operands)"))
1098    (set (attr "cc")
1099         (symbol_ref "compute_plussi_cc (operands)"))])
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)"
1107   return output_plussi (operands);
1109   [(set (attr "length")
1110         (symbol_ref "compute_plussi_length (operands)"))
1111    (set (attr "cc")
1112         (symbol_ref "compute_plussi_cc (operands)"))])
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   })
1125 ;; ----------------------------------------------------------------------
1126 ;; SUBTRACT INSTRUCTIONS
1127 ;; ----------------------------------------------------------------------
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   })
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")])
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")])
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")])
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")])
1183 ;; ----------------------------------------------------------------------
1184 ;; MULTIPLY INSTRUCTIONS
1185 ;; ----------------------------------------------------------------------
1187 ;; Note that the H8/300 can only handle umulqihi3.
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   })
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")])
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")])
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   })
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")])
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")])
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   })
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")])
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")])
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   })
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")])
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")])
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.
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")])
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")])
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")])
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.
1349 ;; Unfortunately, if combine doesn't create a MAC instruction, this
1350 ;; insn must generate reasonably correct code.  Egad.
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")])
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")])
1377 ;; ----------------------------------------------------------------------
1378 ;; DIVIDE/MOD INSTRUCTIONS
1379 ;; ----------------------------------------------------------------------
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")])
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")])
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   ""
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";
1415   [(set_attr "length" "4")])
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"
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";
1435   [(set_attr "length" "6")])
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"
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";
1455   [(set_attr "length" "4")])
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"
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";
1475   [(set_attr "length" "6")])
1477 ;; ----------------------------------------------------------------------
1478 ;; AND INSTRUCTIONS
1479 ;; ----------------------------------------------------------------------
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")])
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   })
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")])
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")])
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")])
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   "")
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";
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       }
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       }
1586     gcc_unreachable ();
1587         
1588   }
1589   [(set_attr "length" "6")])
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")])
1601 ;; ----------------------------------------------------------------------
1602 ;; OR/XOR INSTRUCTIONS
1603 ;; ----------------------------------------------------------------------
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")])
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")])
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")])
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   "")
1644 ;; ----------------------------------------------------------------------
1645 ;; {AND,IOR,XOR}{HI3,SI3} PATTERNS
1646 ;; ----------------------------------------------------------------------
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)"))])
1660 ;; ----------------------------------------------------------------------
1661 ;; NEGATION INSTRUCTIONS
1662 ;; ----------------------------------------------------------------------
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   })
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")])
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   })
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")])
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")])
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")])
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")])
1736 ;; ----------------------------------------------------------------------
1737 ;; ABSOLUTE VALUE INSTRUCTIONS
1738 ;; ----------------------------------------------------------------------
1740 (define_expand "abssf2"
1741   [(set (match_operand:SF 0 "register_operand" "")
1742         (abs:SF (match_operand:SF 1 "register_operand" "")))]
1743   ""
1744   "")
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")])
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")])
1760 ;; ----------------------------------------------------------------------
1761 ;; NOT INSTRUCTIONS
1762 ;; ----------------------------------------------------------------------
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   "")
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")])
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")])
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")])
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")])
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")])
1808 ;; ----------------------------------------------------------------------
1809 ;; JUMP INSTRUCTIONS
1810 ;; ----------------------------------------------------------------------
1812 ;; Conditional jump instructions
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   })
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   })
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   })
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   ""
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     }
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%=:";
1877  [(set_attr "type" "branch")
1878    (set_attr "cc" "none")])
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   ""
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     }
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%=:";
1905   [(set_attr "type" "branch")
1906    (set_attr "cc" "none")])
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"
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     }
1929   [(set_attr "type" "bitbranch")
1930    (set_attr "length_table" "bitbranch")
1931    (set_attr "cc" "none")])
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"
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     }
1954   [(set_attr "type" "bitbranch")
1955    (set_attr "length_table" "bitbranch")
1956    (set_attr "cc" "none")])
1958 ;; Unconditional and other jump instructions.
1960 (define_insn "jump"
1961   [(set (pc)
1962         (label_ref (match_operand 0 "" "")))]
1963   ""
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.
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;
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";
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")])
2003 ;; This is a define expand, because pointers may be either 16 or 32 bits.
2005 (define_expand "tablejump"
2006   [(parallel [(set (pc) (match_operand 0 "register_operand" ""))
2007               (use (label_ref (match_operand 1 "" "")))])]
2008   ""
2009   "")
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")])
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")])
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")])
2035 ;; This is a define expand, because pointers may be either 16 or 32 bits.
2037 (define_expand "indirect_jump"
2038   [(set (pc) (match_operand 0 "jump_address_operand" ""))]
2039   ""
2040   "")
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")])
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")])
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")])
2063 ;; Call subroutine with no return value.
2065 ;; ??? Even though we use HImode here, this works on the H8/300H and H8S.
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   })
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   ""
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 "";
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)))])
2098 ;; Call subroutine, returning value in operand 0
2099 ;; (which must be a hard register).
2101 ;; ??? Even though we use HImode here, this works on the H8/300H and H8S.
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   })
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   ""
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 "";
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)))])
2137 (define_insn "nop"
2138   [(const_int 0)]
2139   ""
2140   "nop"
2141   [(set_attr "cc" "none")
2142    (set_attr "length" "2")])
2144 ;; ----------------------------------------------------------------------
2145 ;; PROLOGUE/EPILOGUE-RELATED INSTRUCTIONS
2146 ;; ----------------------------------------------------------------------
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   "")
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   "")
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   "")
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   "")
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   "")
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   "")
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"
2190   operands[3] = SET_DEST (XVECEXP (operands[0], 0,
2191                                    XVECLEN (operands[0], 0) - 2));
2192   return "ldm.l\t@er7+,%S1-%S3";
2194   [(set_attr "cc" "none")
2195    (set_attr "length" "4")])
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"
2203   operands[3] = SET_SRC (XVECEXP (operands[0], 0,
2204                                   XVECLEN (operands[0], 0) - 2));
2205   return "stm.l\t%S2-%S3,@-er7";
2207   [(set_attr "cc" "none")
2208    (set_attr "length" "4")])
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"
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";
2225   [(set_attr "cc" "none")
2226    (set_attr "can_delay" "no")
2227    (set_attr "length" "2")])
2229 (define_expand "return"
2230   [(return)]
2231   "h8300_can_use_return_insn_p ()"
2232   "")
2234 (define_insn "*return_1"
2235   [(return)]
2236   "reload_completed"
2238   if (h8300_current_function_interrupt_function_p ()
2239       || h8300_current_function_monitor_function_p ())
2240     return "rte";
2241   else
2242     return "rts";
2244   [(set_attr "cc" "none")
2245    (set_attr "can_delay" "no")
2246    (set_attr "length" "2")])
2248 (define_expand "prologue"
2249   [(const_int 0)]
2250   ""
2251   {
2252     h8300_expand_prologue ();
2253     DONE;
2254   })
2256 (define_expand "epilogue"
2257   [(return)]
2258   ""
2259   {
2260     h8300_expand_epilogue ();
2261     DONE;
2262   })
2264 (define_insn "monitor_prologue"
2265   [(unspec_volatile [(const_int 0)] UNSPEC_MONITOR)]
2266   ""
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 ();
2284   [(set_attr "length" "20")])
2286 ;; ----------------------------------------------------------------------
2287 ;; EXTEND INSTRUCTIONS
2288 ;; ----------------------------------------------------------------------
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   })
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")])
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")])
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.
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   })
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")])
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   "#")
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   })
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   })
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")])
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   "")
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")])
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")])
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   "")
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")])
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")])
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")])
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.
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   })
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")])
2473 (define_expand "extendhisi2"
2474   [(set (match_operand:SI 0 "register_operand" "")
2475         (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
2476   ""
2477   "")
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")])
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")])
2496 ;; ----------------------------------------------------------------------
2497 ;; SHIFTS
2498 ;; ----------------------------------------------------------------------
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.
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.
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.
2515 ;; QI BIT SHIFTS
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   })
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   })
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   })
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)"
2554   return output_h8sx_shift (operands, 'b', 'X');
2556   [(set_attr "length_table" "unary")
2557    (set_attr "cc" "set_znv")])
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   ""
2566   return output_h8sx_shift (operands, 'b', 'X');
2568   [(set_attr "length" "4")
2569    (set_attr "cc" "set_znv")])
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   ""
2579   return output_a_shift (operands);
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)"))])
2586 ;; HI BIT SHIFTS
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   })
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   })
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   })
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)"
2625   return output_h8sx_shift (operands, 'w', 'T');
2627   [(set_attr "length_table" "unary")
2628    (set_attr "cc" "set_znv")])
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   ""
2637   return output_h8sx_shift (operands, 'w', 'T');
2639   [(set_attr "length" "4")
2640    (set_attr "cc" "set_znv")])
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   ""
2650   return output_a_shift (operands);
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)"))])
2657 ;;  SI BIT SHIFTS
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   })
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   })
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   })
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)"
2696   return output_h8sx_shift (operands, 'l', 'S');
2698   [(set_attr "length_table" "unary")
2699    (set_attr "cc" "set_znv")])
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   ""
2708   return output_h8sx_shift (operands, 'l', 'S');
2710   [(set_attr "length" "4")
2711    (set_attr "cc" "set_znv")])
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   ""
2721   return output_a_shift (operands);
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)"))])
2728 ;; Split a variable shift into a loop.  If the register containing
2729 ;; the shift count dies, then we just use that register.
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   })
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   })
2793 ;; ----------------------------------------------------------------------
2794 ;; ROTATIONS
2795 ;; ----------------------------------------------------------------------
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   })
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   ""
2813   return output_a_rotate (ROTATE, operands);
2815   [(set (attr "length")
2816         (symbol_ref "compute_a_rotate_length (operands)"))])
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   })
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"
2834   return output_a_rotate (ROTATE, operands);
2836   [(set (attr "length")
2837         (symbol_ref "compute_a_rotate_length (operands)"))])
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.
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).
2849 ;; Combine obviously need some work to better identify this situation and
2850 ;; canonicalize the form better.
2853 ;; Normal loads with a 16bit destination.
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")])
2866 ;; Inverted loads with a 16bit destination.
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")])
2881 ;; Normal loads with a 32bit destination.
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"
2891   return output_simode_bld (0, operands);
2893   [(set_attr "length" "8")])
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"
2902   return output_simode_bld (0, operands);
2904   [(set_attr "cc" "set_znv,set_znv")
2905    (set_attr "length" "8,6")])
2908 ;; Inverted loads with a 32bit destination.
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])"
2920   return output_simode_bld (1, operands);
2922   [(set_attr "length" "8")])
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])"
2933   return output_simode_bld (1, operands);
2935   [(set_attr "cc" "set_znv,set_znv")
2936    (set_attr "length" "8,6")])
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       }
2987     /* We only have single bit bit-field instructions.  */
2988     if (INTVAL (operands[1]) != 1)
2989       FAIL;
2991     /* For now, we don't allow memory operands.  */
2992     if (GET_CODE (operands[0]) == MEM
2993         || GET_CODE (operands[3]) == MEM)
2994       FAIL;
2996     if (GET_CODE (operands[3]) != REG)
2997       operands[3] = force_reg (HImode, operands[3]);
2998   })
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")])
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;
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]);
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       }
3057     /* We only have single bit bit-field instructions.  */
3058     if (INTVAL (operands[2]) != 1)
3059       FAIL;
3061     /* For now, we don't allow memory operands.  */
3062     if (GET_CODE (operands[1]) == MEM)
3063       FAIL;
3064   })
3066 ;; BAND, BOR, and BXOR patterns
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")])
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")])
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"
3099   operands[2] = GEN_INT ((1 << (INTVAL (operands[2]) + INTVAL (operands[3])))
3100                          - (1 << INTVAL (operands[3])));
3101   return "bfld  %2,%1,%R0";
3103   [(set_attr "cc" "none_0hit")
3104    (set_attr "length_table" "bitfield")])
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"
3113   operands[2] = GEN_INT ((1 << (INTVAL (operands[2]) + INTVAL (operands[3])))
3114                          - (1 << INTVAL (operands[3])));
3115   return "bfst  %R1,%2,%0";
3117   [(set_attr "cc" "none_0hit")
3118    (set_attr "length_table" "bitfield")])
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   })
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   })
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   })
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")])
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")])
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")])
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")])
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")])
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")])
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")])
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")])
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")])
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")])
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")])
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")])
3343 ;; -----------------------------------------------------------------
3344 ;; COMBINE PATTERNS
3345 ;; -----------------------------------------------------------------
3347 ;; insv:SI
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")])
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")])
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")])
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")])
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")])
3399 ;; extzv:SI
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")])
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")])
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")])
3434 ;; Extract the exponent of a float.
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   "")
3454 ;; and:SI
3456 ;; ((SImode) HImode) << 15
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   "")
3476 ;; Transform (SImode << B) & 0xffff into (SImode) (HImode << B).
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   })
3500 ;; Accept (A >> 30) & 2 and the like.
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"
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";
3514   [(set_attr "length" "8")])
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   "")
3534 ;; plus:SI
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")])
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")])
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   })
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   })
3604 ;; [ix]or:HI
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")])
3615 ;; [ix]or:SI
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")])
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")])
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")])
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")])
3655 ;; ior:HI
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")])
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")])
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")])
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")])
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   })
3707 ;; ior:SI
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")])
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   })
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")])
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   })
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")])
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")])
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"
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";
3801   [(set_attr "length" "6")])
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"
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";
3819   [(set_attr "length" "6")])
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")])
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")])
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"
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";
3855   [(set_attr "length" "10")])
3857 ;; Used to OR the exponent of a float.
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   "#")
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   })
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   })
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")])
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   })
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   })
3968 ;; Used to add the exponent of a float.
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   "#")
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   })
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   })
4025 ;; ashift:SI
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   })
4048 ;; Storing a part of HImode to QImode.
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")])
4059 ;; Storing a part of SImode to QImode.
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")])
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")])
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")])
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   "")
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   "")
4130 ;; -----------------------------------------------------------------
4131 ;; PEEPHOLE PATTERNS
4132 ;; -----------------------------------------------------------------
4134 ;; Convert (A >> B) & C to (A & 255) >> B if C == 255 >> B.
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   "")
4153 ;; Convert (A << B) & C to (A & 255) << B if C == 255 << B.
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   "")
4172 ;; Convert (A >> B) & C to (A & 255) >> B if C == 255 >> B.
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   "")
4191 ;; Convert (A << B) & C to (A & 255) << B if C == 255 << B.
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   "")
4210 ;; Convert (A >> B) & C to (A & 65535) >> B if C == 65535 >> B.
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   "")
4229 ;; Convert (A << B) & C to (A & 65535) << B if C == 65535 << B.
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   "")
4248 ;; Convert a QImode push into an SImode push so that the
4249 ;; define_peephole2 below can cram multiple pushes into one stm.l.
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   })
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   })
4275 ;; Convert a HImode push into an SImode push so that the
4276 ;; define_peephole2 below can cram multiple pushes into one stm.l.
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   })
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   })
4302 ;; Cram four pushes into stm.l.
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   "")
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   "")
4360 ;; Cram three pushes into stm.l.
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   "")
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   "")
4408 ;; Cram two pushes into stm.l.
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   "")
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   "")
4446 ;; Turn
4448 ;;   mov.w #2,r0
4449 ;;   add.w r7,r0  (6 bytes)
4451 ;; into
4453 ;;   mov.w r7,r0
4454 ;;   adds  #2,r0  (4 bytes)
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   "")
4474 ;; Turn
4476 ;;   sub.l  er0,er0
4477 ;;   add.b  #4,r0l
4478 ;;   add.l  er7,er0  (6 bytes)
4480 ;; into
4482 ;;   mov.l  er7,er0
4483 ;;   adds   #4,er0   (4 bytes)
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   "")
4503 ;; Turn
4505 ;;   mov.l er7,er0
4506 ;;   add.l #10,er0  (takes 8 bytes)
4508 ;; into
4510 ;;   sub.l er0,er0
4511 ;;   add.b #10,r0l
4512 ;;   add.l er7,er0  (takes 6 bytes)
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   "")
4536 ;; Turn
4538 ;;   subs   #1,er4
4539 ;;   mov.w  r4,r4
4540 ;;   bne    .L2028
4542 ;; into
4544 ;;   dec.w  #1,r4
4545 ;;   bne    .L2028
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   "")
4571 ;; The SImode version of the previous pattern.
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   "")
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   })
4622 ;; The next three peephole2's will try to transform
4624 ;;   mov.b A,r0l    (or mov.l A,er0)
4625 ;;   and.l #CST,er0
4627 ;; into
4629 ;;   sub.l er0
4630 ;;   mov.b A,r0l
4631 ;;   and.b #CST,r0l (if CST is not 255)
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   "")
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   })
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   })
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   "")
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.
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   })
4740 ;; Convert a memory comparison to a move if there is a scratch register.
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   "")
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   "")
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   "")
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.
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
4790 ;; dead     1                       ge/lt shar.l
4791 ;; dead     3 (H8S)                 ge/lt shar.l
4793 ;; dead     1                       geu/ltu shar.l
4794 ;; dead     3 (H8S)                 geu/ltu shar.l
4796 ;; ----   255                       ge/lt mov.b
4798 ;; ----   255                       geu/ltu mov.b
4800 ;; Transform
4802 ;;      cmp.w   #1,r0
4803 ;;      bne     .L1
4805 ;; into
4807 ;;      dec.w   #1,r0
4808 ;;      bne     .L1
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   })
4836 ;; Transform
4838 ;;      cmp.w   #1,r0
4839 ;;      bgt     .L1
4841 ;; into
4843 ;;      shar.w  r0
4844 ;;      bgt     .L1
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   })
4873 ;; Transform
4875 ;;      cmp.w   #1,r0
4876 ;;      bhi     .L1
4878 ;; into
4880 ;;      shar.w  r0
4881 ;;      bne     .L1
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   })
4912 ;; Transform
4914 ;;      cmp.w   #255,r0
4915 ;;      bgt     .L1
4917 ;; into
4919 ;;      mov.b   r0h,r0h
4920 ;;      bgt     .L1
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   "")
4941 ;; Transform
4943 ;;      cmp.w   #255,r0
4944 ;;      bhi     .L1
4946 ;; into
4948 ;;      mov.b   r0h,r0h
4949 ;;      bne     .L1
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   })
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.
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
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
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
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
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
5003 ;; live     1                       ge/lt copy and shar.l
5004 ;; live     3 (H8S)                 ge/lt copy and shar.l
5006 ;; live     1                       geu/ltu copy and shar.l
5007 ;; live     3 (H8S)                 geu/ltu copy and shar.l
5009 ;; dead     1                       ge/lt shar.l
5010 ;; dead     3 (H8S)                 ge/lt shar.l
5012 ;; dead     1                       geu/ltu shar.l
5013 ;; dead     3 (H8S)                 geu/ltu shar.l
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
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
5031 ;; ---- 65535                       ge/lt mov.w
5033 ;; ---- 65535                       geu/ltu mov.w
5035 ;; Transform
5037 ;;      cmp.l   #1,er0
5038 ;;      beq     .L1
5040 ;; into
5042 ;;      dec.l   #1,er0
5043 ;;      beq     .L1
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   })
5071 ;; Transform
5073 ;;      cmp.l   #65536,er0
5074 ;;      beq     .L1
5076 ;; into
5078 ;;      dec.l   #1,e0
5079 ;;      beq     .L1
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   })
5109 ;; Transform
5111 ;;      cmp.l   #100,er0
5112 ;;      beq     .L1
5114 ;; into
5116 ;;      xor.b   #100,er0
5117 ;;      mov.l   er0,er0
5118 ;;      beq     .L1
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   "")
5148 ;; Transform
5150 ;;      cmp.l   #-100,er0
5151 ;;      beq     .L1
5153 ;; into
5155 ;;      xor.b   #99,er0
5156 ;;      not.l   er0
5157 ;;      beq     .L1
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   })
5189 ;; Transform
5191 ;;      cmp.l   #-2147483648,er0
5192 ;;      beq     .L1
5194 ;; into
5196 ;;      rotl.l  er0
5197 ;;      dec.l   #1,er0
5198 ;;      beq     .L1
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   })
5230 ;; Transform
5232 ;;      cmp.l   #1,er0
5233 ;;      bgt     .L1
5235 ;; into
5237 ;;      mov.l   er0,er1
5238 ;;      shar.l  er1
5239 ;;      bgt     .L1
5241 ;; We avoid this transformation if we see more than one copy of the
5242 ;; same compare insn immediately before this one.
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   })
5275 ;; Transform
5277 ;;      cmp.l   #1,er0
5278 ;;      bhi     .L1
5280 ;; into
5282 ;;      mov.l   er0,er1
5283 ;;      shar.l  er1
5284 ;;      bne     .L1
5286 ;; We avoid this transformation if we see more than one copy of the
5287 ;; same compare insn immediately before this one.
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   })
5322 ;; Transform
5324 ;;      cmp.l   #1,er0
5325 ;;      bgt     .L1
5327 ;; into
5329 ;;      shar.l  er0
5330 ;;      bgt     .L1
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   })
5359 ;; Transform
5361 ;;      cmp.l   #1,er0
5362 ;;      bhi     .L1
5364 ;; into
5366 ;;      shar.l  er0
5367 ;;      bne     .L1
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   })
5398 ;; Transform
5400 ;;      cmp.l   #15,er0
5401 ;;      bgt     .L1
5403 ;; into
5405 ;;      and     #240,r0l
5406 ;;      mov.l   er0,er0
5407 ;;      bgt     .L1
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   })
5440 ;; Transform
5442 ;;      cmp.l   #15,er0
5443 ;;      bhi     .L1
5445 ;; into
5447 ;;      and     #240,r0l
5448 ;;      mov.l   er0,er0
5449 ;;      bne     .L1
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   })
5484 ;; Transform
5486 ;;      cmp.l   #65535,er0
5487 ;;      bgt     .L1
5489 ;; into
5491 ;;      mov.l   e0,e0
5492 ;;      bgt     .L1
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   "")
5513 ;; Transform
5515 ;;      cmp.l   #65535,er0
5516 ;;      bhi     .L1
5518 ;; into
5520 ;;      mov.l   e0,e0
5521 ;;      bne     .L1
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   })
5545 ;; Transform
5547 ;;      cmp.l   #1,er0
5548 ;;      beq     .L1
5550 ;; into
5552 ;;      mov.l   er0,er1
5553 ;;      dec.l   #1,er1
5554 ;;      beq     .L1
5556 ;; We avoid this transformation if we see more than one copy of the
5557 ;; same compare insn.
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.
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   })
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   })
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   })
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   })
5702 ;; These triggers right at the end of allocation of locals in the
5703 ;; prologue (and possibly at other places).
5705 ;; stack adjustment of -4, generate one push
5707 ;; before : 6 bytes, 10 clocks
5708 ;; after  : 4 bytes, 10 clocks
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   "")
5722 ;; stack adjustment of -12, generate one push
5724 ;; before : 10 bytes, 14 clocks
5725 ;; after  :  8 bytes, 14 clocks
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   "")
5745 ;; Transform
5747 ;;      mov     dst,reg
5748 ;;      op      src,reg
5749 ;;      mov     reg,dst
5751 ;; into
5753 ;;      op      src,dst
5755 ;; if "reg" dies at the end of the sequence.
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   })
5779 ;; Transform
5781 ;;      mov     src,reg
5782 ;;      op      reg,dst
5784 ;; into
5786 ;;      op      src,dst
5788 ;; if "reg" dies in the second insn.
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   })
5808 ;; Transform
5810 ;;      mov     dst,reg
5811 ;;      op      reg
5812 ;;      mov     reg,dst
5814 ;; into
5816 ;;      op      dst
5818 ;; if "reg" dies at the end of the sequence.
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   })
5839 ;; Transform
5841 ;;      mov     src1,reg
5842 ;;      cmp     reg,src2
5844 ;; into
5846 ;;      cmp     src1,src2
5848 ;; if "reg" dies in the comparison.
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)))])
5864 ;; Likewise for the second operand.
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)))])
5879 ;; Combine two moves.
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))])