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