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