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