This commit was manufactured by cvs2svn to create branch
[official-gcc.git] / gcc / config / h8300 / h8300.md
blob12b55dcbb0915dc4f942f3fb78b4653be1f1a45f
1 ;; GCC machine description for Renesas H8/300
2 ;; Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 ;; 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
5 ;;   Contributed by Steve Chamberlain (sac@cygnus.com),
6 ;;   Jim Wilson (wilson@cygnus.com), and Doug Evans (dje@cygnus.com).
8 ;; This file is part of GCC.
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 2, or (at your option)
13 ;; any later version.
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 ;; GNU General Public License for more details.
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING.  If not, write to
22 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
23 ;; Boston, MA 02111-1307, USA.
25 ;; We compute exact length on each instruction for most of the time.
26 ;; In some case, most notably bit operations that may involve memory
27 ;; operands, the lengths in this file are "worst case".
29 ;; On the H8/300H and H8S, adds/subs operate on the 32bit "er"
30 ;; registers.  Right now GCC doesn't expose the "e" half to the
31 ;; compiler, so using add/subs for addhi and subhi is safe.  Long
32 ;; term, we want to expose the "e" half to the compiler (gives us 8
33 ;; more 16bit registers).  At that point addhi and subhi can't use
34 ;; adds/subs.
36 ;; There's currently no way to have an insv/extzv expander for the H8/300H
37 ;; because word_mode is different for the H8/300 and H8/300H.
39 ;; Shifts/rotates by small constants should be handled by special
40 ;; patterns so we get the length and cc status correct.
42 ;; Bitfield operations no longer accept memory operands.  We need
43 ;; to add variants which operate on memory back to the MD.
45 ;; ??? Implement remaining bit ops available on the h8300
47 ;; ----------------------------------------------------------------------
48 ;; CONSTANTS
49 ;; ----------------------------------------------------------------------
51 (define_constants
52   [(UNSPEC_INCDEC       0)
53    (UNSPEC_MONITOR      1)])
55 (define_constants
56   [(R0_REG       0)
57    (SC_REG       3)
58    (FP_REG       6)
59    (SP_REG       7)
60    (MAC_REG      8)
61    (AP_REG       9)
62    (RAP_REG     10)])
64 ;; ----------------------------------------------------------------------
65 ;; ATTRIBUTES
66 ;; ----------------------------------------------------------------------
68 (define_attr "cpu" "h8300,h8300h"
69   (const (symbol_ref "cpu_type")))
71 (define_attr "type" "branch,arith"
72   (const_string "arith"))
74 ;; The size of instructions in bytes.
76 (define_attr "length" ""
77   (cond [(eq_attr "type" "branch")
78          (if_then_else (and (ge (minus (match_dup 0) (pc))
79                                 (const_int -126))
80                             (le (minus (match_dup 0) (pc))
81                                 (const_int 126)))
82                        (const_int 2)
83                        (if_then_else (and (eq_attr "cpu" "h8300h")
84                                           (and (ge (minus (pc) (match_dup 0))
85                                                    (const_int -32000))
86                                                (le (minus (pc) (match_dup 0))
87                                                    (const_int 32000))))
88                                      (const_int 4)
89                                      (const_int 6)))]
90         (const_int 200)))
92 ;; Condition code settings.
94 ;; none - insn does not affect cc
95 ;; none_0hit - insn does not affect cc but it does modify operand 0
96 ;;      This attribute is used to keep track of when operand 0 changes.
97 ;;      See the description of NOTICE_UPDATE_CC for more info.
98 ;; set_znv - insn sets z,n,v to usable values (like a tst insn); c is unknown.
99 ;; set_zn  - insn sets z,n to usable values; v,c are unknown.
100 ;; compare - compare instruction
101 ;; clobber - value of cc is unknown
103 (define_attr "cc" "none,none_0hit,set_znv,set_zn,compare,clobber"
104   (const_string "clobber"))
106 ;; Provide the maximum length of an assembly instruction in an asm
107 ;; statement.  The maximum length of 14 bytes is achieved on H8SX.
109 (define_asm_attributes
110   [(set (attr "length")
111         (cond [(ne (symbol_ref "TARGET_H8300")  (const_int 0)) (const_int 4)
112                (ne (symbol_ref "TARGET_H8300H") (const_int 0)) (const_int 10)
113                (ne (symbol_ref "TARGET_H8300S") (const_int 0)) (const_int 10)]
114               (const_int 14)))])
116 ;; ----------------------------------------------------------------------
117 ;; MOVE INSTRUCTIONS
118 ;; ----------------------------------------------------------------------
120 ;; movqi
122 (define_insn "pushqi1_h8300"
123   [(parallel [(set (reg:HI SP_REG)
124                    (plus:HI (reg:HI SP_REG) (const_int -2)))
125               (set (mem:QI (plus:HI (reg:HI SP_REG) (const_int -1)))
126                    (match_operand:QI 0 "register_operand" "r"))])]
127   "TARGET_H8300
128    && operands[0] != stack_pointer_rtx"
129   "mov.w\\t%T0,@-r7"
130   [(set_attr "length" "2")
131    (set_attr "cc" "clobber")])
133 (define_insn "pushqi1_h8300hs"
134   [(parallel [(set (reg:SI SP_REG)
135                    (plus:SI (reg:SI SP_REG) (const_int -4)))
136               (set (mem:QI (plus:SI (reg:SI SP_REG) (const_int -3)))
137                    (match_operand:QI 0 "register_operand" "r"))])]
138   "(TARGET_H8300H || TARGET_H8300S)
139    && operands[0] != stack_pointer_rtx"
140   "mov.l\\t%S0,@-er7"
141   [(set_attr "length" "4")
142    (set_attr "cc" "clobber")])
144 (define_insn "pushqi1_h8300hs_normal"
145   [(parallel [(set (reg:HI SP_REG)
146                    (plus:HI (reg:HI SP_REG) (const_int -4)))
147               (set (mem:QI (plus:HI (reg:HI SP_REG) (const_int -3)))
148                    (match_operand:QI 0 "register_operand" "r"))])]
149   "(TARGET_H8300H || TARGET_H8300S)
150    && operands[0] != stack_pointer_rtx"
151   "mov.l\\t%S0,@-er7"
152   [(set_attr "length" "4")
153    (set_attr "cc" "clobber")])
155 (define_expand "pushqi1"
156   [(use (match_operand:QI 0 "register_operand" ""))]
157   ""
158   "
160   if (TARGET_H8300)
161     emit_insn (gen_pushqi1_h8300 (operands[0]));
162   else if (!TARGET_NORMAL_MODE)
163     emit_insn (gen_pushqi1_h8300hs (operands[0]));
164   else
165     emit_insn (gen_pushqi1_h8300hs_normal (operands[0]));
166   DONE;
169 (define_insn "*movqi_h8300"
170   [(set (match_operand:QI 0 "general_operand_dst" "=r,r ,<,r,r,m")
171         (match_operand:QI 1 "general_operand_src" " I,r>,r,n,m,r"))]
172   "TARGET_H8300
173    && (register_operand (operands[0], QImode)
174        || register_operand (operands[1], QImode))"
175   "@
176    sub.b        %X0,%X0
177    mov.b        %R1,%X0
178    mov.b        %X1,%R0
179    mov.b        %R1,%X0
180    mov.b        %R1,%X0
181    mov.b        %X1,%R0"
182   [(set_attr "length" "2,2,2,2,4,4")
183    (set_attr "cc" "set_zn,set_znv,set_znv,set_znv,set_znv,set_znv")])
185 (define_insn "*movqi_h8300hs"
186   [(set (match_operand:QI 0 "general_operand_dst" "=r,r ,<,r,r,m")
187         (match_operand:QI 1 "general_operand_src" " I,r>,r,n,m,r"))]
188   "(TARGET_H8300H || TARGET_H8300S)
189    && (register_operand (operands[0], QImode)
190        || register_operand (operands[1], QImode))"
191   "@
192    sub.b        %X0,%X0
193    mov.b        %R1,%X0
194    mov.b        %X1,%R0
195    mov.b        %R1,%X0
196    mov.b        %R1,%X0
197    mov.b        %X1,%R0"
198   [(set (attr "length")
199         (symbol_ref "compute_mov_length (operands)"))
200    (set_attr "cc" "set_zn,set_znv,set_znv,clobber,set_znv,set_znv")])
202 (define_expand "movqi"
203   [(set (match_operand:QI 0 "general_operand_dst" "")
204         (match_operand:QI 1 "general_operand_src" ""))]
205   ""
206   "
208   /* One of the ops has to be in a register.  */
209   if (!register_operand (operand0, QImode)
210       && !register_operand (operand1, QImode))
211     {
212       operands[1] = copy_to_mode_reg (QImode, operand1);
213     }
216 (define_insn "movstrictqi"
217   [(set (strict_low_part
218          (match_operand:QI 0 "register_operand"    "+r,r,r,r,r"))
219          (match_operand:QI 1 "general_operand_src" " I,r,n,>,m"))]
220   ""
221   "@
222    sub.b        %X0,%X0
223    mov.b        %X1,%X0
224    mov.b        %R1,%X0
225    mov.b        %X1,%X0
226    mov.b        %R1,%X0"
227   [(set (attr "length")
228         (symbol_ref "compute_mov_length (operands)"))
229    (set_attr "cc" "set_zn,set_znv,set_znv,set_znv,set_znv")])
231 ;; movhi
233 (define_expand "pushhi1_h8300"
234   [(set (mem:HI (pre_dec:HI (reg:HI SP_REG)))
235         (match_operand:HI 0 "register_operand" ""))]
236   "TARGET_H8300
237    && operands[0] != stack_pointer_rtx"
238   "")
240 (define_insn "pushhi1_h8300hs"
241   [(parallel [(set (reg:SI SP_REG)
242                    (plus:SI (reg:SI SP_REG) (const_int -4)))
243               (set (mem:HI (plus:SI (reg:SI SP_REG) (const_int -2)))
244                    (match_operand:HI 0 "register_operand" "r"))])]
245   "(TARGET_H8300H || TARGET_H8300S)
246    && operands[0] != stack_pointer_rtx"
247   "mov.l\\t%S0,@-er7"
248   [(set_attr "length" "4")
249    (set_attr "cc" "clobber")])
251 (define_insn "pushhi1_h8300hs_normal"
252   [(parallel [(set (reg:HI SP_REG)
253                    (plus:HI (reg:HI SP_REG) (const_int -4)))
254               (set (mem:HI (plus:HI (reg:HI SP_REG) (const_int -2)))
255                    (match_operand:HI 0 "register_operand" "r"))])]
256   "(TARGET_H8300H || TARGET_H8300S)
257    && operands[0] != stack_pointer_rtx"
258   "mov.l\\t%S0,@-er7"
259   [(set_attr "length" "4")
260    (set_attr "cc" "clobber")])
262 (define_expand "pushhi1"
263   [(use (match_operand:HI 0 "register_operand" ""))]
264   ""
265   "
267   if (TARGET_H8300)
268     emit_insn (gen_pushhi1_h8300 (operands[0]));
269   else if (!TARGET_NORMAL_MODE)
270     emit_insn (gen_pushhi1_h8300hs (operands[0]));
271   else
272     emit_insn (gen_pushhi1_h8300hs_normal (operands[0]));
273   DONE;
276 (define_insn "*movhi_h8300"
277   [(set (match_operand:HI 0 "general_operand_dst" "=r,r,<,r,r,m")
278         (match_operand:HI 1 "general_operand_src" "I,r>,r,i,m,r"))]
279   "TARGET_H8300
280    && (register_operand (operands[0], HImode)
281        || register_operand (operands[1], HImode))
282    && !(GET_CODE (operands[0]) == MEM
283         && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC
284         && GET_CODE (XEXP (XEXP (operands[0], 0), 0)) == REG
285         && GET_CODE (operands[1]) == REG
286         && REGNO (XEXP (XEXP (operands[0], 0), 0)) == REGNO (operands[1]))"
287   "@
288    sub.w        %T0,%T0
289    mov.w        %T1,%T0
290    mov.w        %T1,%T0
291    mov.w        %T1,%T0
292    mov.w        %T1,%T0
293    mov.w        %T1,%T0"
294   [(set (attr "length")
295         (symbol_ref "compute_mov_length (operands)"))
296    (set_attr "cc" "set_zn,set_znv,set_znv,set_znv,set_znv,set_znv")])
298 (define_insn "*movhi_h8300hs"
299   [(set (match_operand:HI 0 "general_operand_dst" "=r,r,<,r,r,m")
300         (match_operand:HI 1 "general_operand_src" "I,r>,r,i,m,r"))]
301   "(TARGET_H8300H || TARGET_H8300S)
302    && (register_operand (operands[0], HImode)
303        || register_operand (operands[1], HImode))"
304   "@
305    sub.w        %T0,%T0
306    mov.w        %T1,%T0
307    mov.w        %T1,%T0
308    mov.w        %T1,%T0
309    mov.w        %T1,%T0
310    mov.w        %T1,%T0"
311   [(set (attr "length")
312         (symbol_ref "compute_mov_length (operands)"))
313    (set_attr "cc" "set_zn,set_znv,set_znv,set_znv,set_znv,set_znv")])
315 (define_expand "movhi"
316   [(set (match_operand:HI 0 "general_operand_dst" "")
317         (match_operand:HI 1 "general_operand_src" ""))]
318   ""
319   "
321   /* One of the ops has to be in a register.  */
322   if (!register_operand (operand1, HImode)
323       && !register_operand (operand0, HImode))
324     {
325       operands[1] = copy_to_mode_reg (HImode, operand1);
326     }
329 (define_insn "movstricthi"
330   [(set (strict_low_part
331          (match_operand:HI 0 "register_operand"    "+r,r,r,r,r"))
332          (match_operand:HI 1 "general_operand_src" " I,r,i,>,m"))]
333   ""
334   "@
335    sub.w        %T0,%T0
336    mov.w        %T1,%T0
337    mov.w        %T1,%T0
338    mov.w        %T1,%T0
339    mov.w        %T1,%T0"
340   [(set (attr "length")
341         (symbol_ref "compute_mov_length (operands)"))
342    (set_attr "cc" "set_zn,set_znv,set_znv,set_znv,set_znv")])
344 ;; movsi
346 (define_expand "movsi"
347   [(set (match_operand:SI 0 "general_operand_dst" "")
348         (match_operand:SI 1 "general_operand_src" ""))]
349   ""
350   "
352   if (TARGET_H8300)
353     {
354       if (h8300_expand_movsi (operands))
355         DONE;
356     }
357   else
358     {
359       /* One of the ops has to be in a register.  */
360       if (!register_operand (operand1, SImode)
361           && !register_operand (operand0, SImode))
362         {
363           operands[1] = copy_to_mode_reg (SImode, operand1);
364         }
365     }
368 (define_expand "movsf"
369   [(set (match_operand:SF 0 "general_operand_dst" "")
370         (match_operand:SF 1 "general_operand_src" ""))]
371   ""
372   "
374   if (TARGET_H8300)
375     {
376       if (h8300_expand_movsi (operands))
377         DONE;
378     }
379   else
380     {
381       /* One of the ops has to be in a register.  */
382       if (!register_operand (operand1, SFmode)
383           && !register_operand (operand0, SFmode))
384         {
385           operands[1] = copy_to_mode_reg (SFmode, operand1);
386         }
387     }
390 (define_insn "*movsi_h8300"
391   [(set (match_operand:SI 0 "general_operand_dst" "=r,r,r,o,<,r")
392         (match_operand:SI 1 "general_operand_src" "I,r,io,r,r,>"))]
393   "TARGET_H8300
394    && (register_operand (operands[0], SImode)
395        || register_operand (operands[1], SImode))"
396   "*
398   unsigned int rn = -1;
399   switch (which_alternative)
400     {
401     case 0:
402       return \"sub.w    %e0,%e0\;sub.w  %f0,%f0\";
403     case 1:
404       if (REGNO (operands[0]) < REGNO (operands[1]))
405         return \"mov.w  %e1,%e0\;mov.w  %f1,%f0\";
406       else
407         return \"mov.w  %f1,%f0\;mov.w  %e1,%e0\";
408     case 2:
409       /* Make sure we don't trample the register we index with.  */
410       if (GET_CODE (operands[1]) == MEM)
411         {
412           rtx inside = XEXP (operands[1], 0);
413           if (REG_P (inside))
414             {
415               rn = REGNO (inside);
416             }
417           else if (GET_CODE (inside) == PLUS)
418             {
419               rtx lhs = XEXP (inside, 0);
420               rtx rhs = XEXP (inside, 1);
421               if (REG_P (lhs)) rn = REGNO (lhs);
422               if (REG_P (rhs)) rn = REGNO (rhs);
423             }
424         }
425       if (rn == REGNO (operands[0]))
426         {
427           /* Move the second word first.  */
428           return \"mov.w        %f1,%f0\;mov.w  %e1,%e0\";
429         }
430       else
431         {
432           if (GET_CODE (operands[1]) == CONST_INT)
433             {
434               /* If either half is zero, use sub.w to clear that
435                  half.  */
436               if ((INTVAL (operands[1]) & 0xffff) == 0)
437                 return \"mov.w  %e1,%e0\;sub.w  %f0,%f0\";
438               if (((INTVAL (operands[1]) >> 16) & 0xffff) == 0)
439                 return \"sub.w  %e0,%e0\;mov.w  %f1,%f0\";
440               /* If the upper half and the lower half are the same,
441                  copy one half to the other.  */
442               if ((INTVAL (operands[1]) & 0xffff)
443                   == ((INTVAL (operands[1]) >> 16) & 0xffff))
444                 return \"mov.w\\t%e1,%e0\;mov.w\\t%e0,%f0\";
445             }
446           return \"mov.w        %e1,%e0\;mov.w  %f1,%f0\";
447         }
448     case 3:
449       return \"mov.w    %e1,%e0\;mov.w  %f1,%f0\";
450     case 4:
451       return \"mov.w    %f1,%T0\;mov.w  %e1,%T0\";
452     case 5:
453       return \"mov.w    %T1,%e0\;mov.w  %T1,%f0\";
454     default:
455       abort ();
456     }
458   [(set (attr "length")
459         (symbol_ref "compute_mov_length (operands)"))
460    (set_attr "cc" "clobber")])
462 (define_insn "*movsf_h8300"
463   [(set (match_operand:SF 0 "general_operand_dst" "=r,r,r,o,<,r")
464         (match_operand:SF 1 "general_operand_src" "G,r,io,r,r,>"))]
465   "TARGET_H8300
466    && (register_operand (operands[0], SFmode)
467        || register_operand (operands[1], SFmode))"
468   "*
470   /* Copy of the movsi stuff.  */
471   unsigned int rn = -1;
472   switch (which_alternative)
473     {
474     case 0:
475       return \"sub.w    %e0,%e0\;sub.w  %f0,%f0\";
476     case 1:
477       if (REGNO (operands[0]) < REGNO (operands[1]))
478         return \"mov.w  %e1,%e0\;mov.w  %f1,%f0\";
479       else
480         return \"mov.w  %f1,%f0\;mov.w  %e1,%e0\";
481     case 2:
482       /* Make sure we don't trample the register we index with.  */
483       if (GET_CODE (operands[1]) == MEM)
484         {
485           rtx inside = XEXP (operands[1], 0);
486           if (REG_P (inside))
487             {
488               rn = REGNO (inside);
489             }
490           else if (GET_CODE (inside) == PLUS)
491             {
492               rtx lhs = XEXP (inside, 0);
493               rtx rhs = XEXP (inside, 1);
494               if (REG_P (lhs)) rn = REGNO (lhs);
495               if (REG_P (rhs)) rn = REGNO (rhs);
496             }
497         }
498       if (rn == REGNO (operands[0]))
499         /* Move the second word first.  */
500         return \"mov.w  %f1,%f0\;mov.w  %e1,%e0\";
501       else
502         /* Move the first word first.  */
503         return \"mov.w  %e1,%e0\;mov.w  %f1,%f0\";
505     case 3:
506       return \"mov.w    %e1,%e0\;mov.w  %f1,%f0\";
507     case 4:
508       return \"mov.w    %f1,%T0\;mov.w  %e1,%T0\";
509     case 5:
510       return \"mov.w    %T1,%e0\;mov.w  %T1,%f0\";
511     default:
512       abort ();
513     }
515   [(set (attr "length")
516         (symbol_ref "compute_mov_length (operands)"))
517    (set_attr "cc" "clobber")])
519 (define_insn "*movsi_h8300hs"
520   [(set (match_operand:SI 0 "general_operand_dst" "=r,r,r,<,r,r,m,*a,*a,r")
521         (match_operand:SI 1 "general_operand_src" "I,r,i,r,>,m,r,I,r,*a"))]
522   "(TARGET_H8300S || TARGET_H8300H)
523    && (register_operand (operands[0], SImode)
524        || register_operand (operands[1], SImode))
525    && !(GET_CODE (operands[0]) == MEM
526         && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC
527         && GET_CODE (XEXP (XEXP (operands[0], 0), 0)) == REG
528         && GET_CODE (operands[1]) == REG
529         && REGNO (XEXP (XEXP (operands[0], 0), 0)) == REGNO (operands[1]))"
530   "*
532   switch (which_alternative)
533     {
534     case 0:
535       return \"sub.l    %S0,%S0\";
536     case 7:
537       return \"clrmac\";
538     case 8:
539       return \"clrmac\;ldmac %1,macl\";
540     case 9:
541       return \"stmac    macl,%0\";
542     default:
543       if (GET_CODE (operands[1]) == CONST_INT)
544         {
545           int val = INTVAL (operands[1]);
547           /* Look for constants which can be made by adding an 8-bit
548              number to zero in one of the two low bytes.  */
549           if (val == (val & 0xff))
550             {
551               operands[1] = GEN_INT ((char) val & 0xff);
552               return \"sub.l\\t%S0,%S0\;add.b\\t%1,%w0\";
553             }
555           if (val == (val & 0xff00))
556             {
557               operands[1] = GEN_INT ((char) (val >> 8) & 0xff);
558               return \"sub.l\\t%S0,%S0\;add.b\\t%1,%x0\";
559             }
561           /* Look for constants that can be obtained by subs, inc, and
562              dec to 0.  */
563           switch (val & 0xffffffff)
564             {
565             case 0xffffffff:
566               return \"sub.l\\t%S0,%S0\;subs\\t#1,%S0\";
567             case 0xfffffffe:
568               return \"sub.l\\t%S0,%S0\;subs\\t#2,%S0\";
569             case 0xfffffffc:
570               return \"sub.l\\t%S0,%S0\;subs\\t#4,%S0\";
572             case 0x0000ffff:
573               return \"sub.l\\t%S0,%S0\;dec.w\\t#1,%f0\";
574             case 0x0000fffe:
575               return \"sub.l\\t%S0,%S0\;dec.w\\t#2,%f0\";
577             case 0xffff0000:
578               return \"sub.l\\t%S0,%S0\;dec.w\\t#1,%e0\";
579             case 0xfffe0000:
580               return \"sub.l\\t%S0,%S0\;dec.w\\t#2,%e0\";
582             case 0x00010000:
583               return \"sub.l\\t%S0,%S0\;inc.w\\t#1,%e0\";
584             case 0x00020000:
585               return \"sub.l\\t%S0,%S0\;inc.w\\t#2,%e0\";
586             }
587         }
588     }
589    return \"mov.l       %S1,%S0\";
591   [(set (attr "length")
592         (symbol_ref "compute_mov_length (operands)"))
593    (set_attr "cc" "set_zn,set_znv,clobber,set_znv,set_znv,set_znv,set_znv,none_0hit,none_0hit,set_znv")])
595 (define_insn "*movsf_h8300hs"
596   [(set (match_operand:SF 0 "general_operand_dst" "=r,r,r,m,<,r")
597         (match_operand:SF 1 "general_operand_src" "G,r,im,r,r,>"))]
598   "(TARGET_H8300H || TARGET_H8300S)
599    && (register_operand (operands[0], SFmode)
600        || register_operand (operands[1], SFmode))"
601   "@
602    sub.l        %S0,%S0
603    mov.l        %S1,%S0
604    mov.l        %S1,%S0
605    mov.l        %S1,%S0
606    mov.l        %S1,%S0
607    mov.l        %S1,%S0"
608   [(set (attr "length")
609         (symbol_ref "compute_mov_length (operands)"))
610    (set_attr "cc" "set_zn,set_znv,set_znv,set_znv,set_znv,set_znv")])
612 ;; ----------------------------------------------------------------------
613 ;; TEST INSTRUCTIONS
614 ;; ----------------------------------------------------------------------
616 (define_insn ""
617   [(set (cc0) (zero_extract:HI (match_operand:QI 0 "bit_memory_operand" "r,U")
618                                (const_int 1)
619                                (match_operand 1 "const_int_operand" "n,n")))]
620   "TARGET_H8300"
621   "btst %Z1,%Y0"
622   [(set_attr "length" "2,4")
623    (set_attr "cc" "set_zn,set_zn")])
625 (define_insn ""
626   [(set (cc0) (zero_extract:HI (match_operand:HI 0 "register_operand" "r")
627                                (const_int 1)
628                                (match_operand 1 "const_int_operand" "n")))]
629   "TARGET_H8300"
630   "btst %Z1,%Y0"
631   [(set_attr "length" "2")
632    (set_attr "cc" "set_zn")])
634 (define_insn_and_split "*tst_extzv_1_n"
635   [(set (cc0)
636         (zero_extract:SI (match_operand:QI 0 "general_operand_src" "r,U,mn>")
637                          (const_int 1)
638                          (match_operand 1 "const_int_operand" "n,n,n")))
639    (clobber (match_scratch:QI 2 "=X,X,&r"))]
640   "(TARGET_H8300H || TARGET_H8300S)"
641   "@
642    btst\\t%Z1,%Y0
643    btst\\t%Z1,%Y0
644    #"
645   "&& reload_completed
646    && !EXTRA_CONSTRAINT (operands[0], 'U')"
647   [(set (match_dup 2)
648         (match_dup 0))
649    (parallel [(set (cc0) (zero_extract:SI (match_dup 2)
650                                           (const_int 1)
651                                           (match_dup 1)))
652               (clobber (scratch:QI))])]
653   ""
654   [(set_attr "length" "2,8,10")
655    (set_attr "cc" "set_zn,set_zn,set_zn")])
657 (define_insn ""
658   [(set (cc0) (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
659                                (const_int 1)
660                                (match_operand 1 "const_int_operand" "n")))]
661   "(TARGET_H8300H || TARGET_H8300S)
662    && INTVAL (operands[1]) <= 15"
663   "btst %Z1,%Y0"
664   [(set_attr "length" "2")
665    (set_attr "cc" "set_zn")])
667 (define_insn_and_split "*tstsi_upper_bit"
668   [(set (cc0)
669         (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
670                          (const_int 1)
671                          (match_operand 1 "const_int_operand" "n")))
672    (clobber (match_scratch:SI 2 "=&r"))]
673   "(TARGET_H8300H || TARGET_H8300S)
674    && INTVAL (operands[1]) >= 16"
675   "#"
676   "&& reload_completed"
677   [(set (match_dup 2)
678         (ior:SI (and:SI (match_dup 2)
679                         (const_int -65536))
680                 (lshiftrt:SI (match_dup 0)
681                              (const_int 16))))
682    (set (cc0)
683         (zero_extract:SI (match_dup 2)
684                          (const_int 1)
685                          (match_dup 3)))]
686   "operands[3] = GEN_INT (INTVAL (operands[1]) - 16);")
688 (define_insn "*tstsi_variable_bit"
689   [(set (cc0)
690         (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
691                          (const_int 1)
692                          (and:SI (match_operand:SI 1 "register_operand" "r")
693                                  (const_int 7))))]
694   "TARGET_H8300H || TARGET_H8300S"
695   "btst %w1,%w0"
696   [(set_attr "length" "2")
697    (set_attr "cc" "set_zn")])
699 (define_insn_and_split "*tstsi_variable_bit_qi"
700   [(set (cc0)
701         (zero_extract:SI (zero_extend:SI (match_operand:QI 0 "general_operand_src" "r,U,mn>"))
702                          (const_int 1)
703                          (and:SI (match_operand:SI 1 "register_operand" "r,r,r")
704                                  (const_int 7))))
705    (clobber (match_scratch:QI 2 "=X,X,&r"))]
706   "(TARGET_H8300H || TARGET_H8300S)"
707   "@
708    btst\\t%w1,%X0
709    btst\\t%w1,%X0
710    #"
711   "&& reload_completed
712    && !EXTRA_CONSTRAINT (operands[0], 'U')"
713   [(set (match_dup 2)
714         (match_dup 0))
715    (parallel [(set (cc0) (zero_extract:SI (zero_extend:SI (match_dup 2))
716                                           (const_int 1)
717                                           (and:SI (match_dup 1)
718                                                   (const_int 7))))
719               (clobber (scratch:QI))])]
720   ""
721   [(set_attr "length" "2,8,10")
722    (set_attr "cc" "set_zn,set_zn,set_zn")])
724 (define_insn "tstqi"
725   [(set (cc0) (match_operand:QI 0 "register_operand" "r"))]
726   ""
727   "mov.b        %X0,%X0"
728   [(set_attr "length" "2")
729    (set_attr "cc" "set_znv")])
731 (define_insn "tsthi"
732   [(set (cc0) (match_operand:HI 0 "register_operand" "r"))]
733   ""
734   "mov.w        %T0,%T0"
735   [(set_attr "length" "2")
736    (set_attr "cc" "set_znv")])
738 (define_insn "*tsthi_upper"
739   [(set (cc0)
740         (and:HI (match_operand:HI 0 "register_operand" "r")
741                 (const_int -256)))]
742   ""
743   "mov.b        %t0,%t0"
744   [(set_attr "length" "2")
745    (set_attr "cc" "set_znv")])
747 (define_insn "tstsi"
748   [(set (cc0) (match_operand:SI 0 "register_operand" "r"))]
749   "TARGET_H8300H || TARGET_H8300S"
750   "mov.l        %S0,%S0"
751   [(set_attr "length" "2")
752    (set_attr "cc" "set_znv")])
754 (define_insn "*tstsi_upper"
755   [(set (cc0)
756         (and:SI (match_operand:SI 0 "register_operand" "r")
757                 (const_int -65536)))]
758   ""
759   "mov.w        %e0,%e0"
760   [(set_attr "length" "2")
761    (set_attr "cc" "set_znv")])
763 (define_insn "cmpqi"
764   [(set (cc0)
765         (compare (match_operand:QI 0 "register_operand" "r")
766                  (match_operand:QI 1 "nonmemory_operand" "rn")))]
767   ""
768   "cmp.b        %X1,%X0"
769   [(set_attr "length" "2")
770    (set_attr "cc" "compare")])
772 (define_expand "cmphi"
773   [(set (cc0)
774         (compare (match_operand:HI 0 "register_operand" "")
775                  (match_operand:HI 1 "nonmemory_operand" "")))]
776   ""
777   "
779   /* Force operand1 into a register if we're compiling
780      for the H8/300.  */
781   if (GET_CODE (operands[1]) != REG && TARGET_H8300)
782     operands[1] = force_reg (HImode, operands[1]);
785 (define_insn "*cmphi_h8300"
786   [(set (cc0)
787         (compare (match_operand:HI 0 "register_operand" "r")
788                  (match_operand:HI 1 "register_operand" "r")))]
789   "TARGET_H8300"
790   "cmp.w        %T1,%T0"
791   [(set_attr "length" "2")
792    (set_attr "cc" "compare")])
794 (define_insn "*cmphi_h8300hs"
795   [(set (cc0)
796         (compare (match_operand:HI 0 "register_operand" "r,r")
797                  (match_operand:HI 1 "nonmemory_operand" "r,n")))]
798   "TARGET_H8300H || TARGET_H8300S"
799   "cmp.w        %T1,%T0"
800   [(set_attr "length" "2,4")
801    (set_attr "cc" "compare,compare")])
803 (define_insn "cmpsi"
804   [(set (cc0)
805         (compare (match_operand:SI 0 "register_operand" "r,r")
806                  (match_operand:SI 1 "nonmemory_operand" "r,i")))]
807   "TARGET_H8300H || TARGET_H8300S"
808   "cmp.l        %S1,%S0"
809   [(set_attr "length" "2,6")
810    (set_attr "cc" "compare,compare")])
812 ;; ----------------------------------------------------------------------
813 ;; ADD INSTRUCTIONS
814 ;; ----------------------------------------------------------------------
816 (define_insn "addqi3"
817   [(set (match_operand:QI 0 "register_operand" "=r")
818         (plus:QI (match_operand:QI 1 "register_operand" "%0")
819                  (match_operand:QI 2 "nonmemory_operand" "rn")))]
820   ""
821   "add.b        %X2,%X0"
822   [(set_attr "length" "2")
823    (set_attr "cc" "set_zn")])
825 (define_expand "addhi3"
826   [(set (match_operand:HI 0 "register_operand" "")
827         (plus:HI (match_operand:HI 1 "register_operand" "")
828                  (match_operand:HI 2 "nonmemory_operand" "")))]
829   ""
830   "")
832 (define_insn "*addhi3_h8300"
833   [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r")
834         (plus:HI (match_operand:HI 1 "register_operand" "%0,0,0,0,0")
835                  (match_operand:HI 2 "nonmemory_operand" "L,N,J,n,r")))]
836   "TARGET_H8300"
837   "@
838    adds %2,%T0
839    subs %G2,%T0
840    add.b        %t2,%t0
841    add.b        %s2,%s0\;addx   %t2,%t0
842    add.w        %T2,%T0"
843   [(set_attr "length" "2,2,2,4,2")
844    (set_attr "cc" "none_0hit,none_0hit,clobber,clobber,set_zn")])
846 ;; This splitter is very important to make the stack adjustment
847 ;; interrupt-safe.  The combination of add.b and addx is unsafe!
849 ;; We apply this split after the peephole2 pass so that we won't end
850 ;; up creating too many adds/subs when a scratch register is
851 ;; available, which is actually a common case because stack unrolling
852 ;; tends to happen immediately after a function call.
854 (define_split
855   [(set (match_operand:HI 0 "stack_pointer_operand" "")
856         (plus:HI (match_dup 0)
857                  (match_operand 1 "const_int_gt_2_operand" "")))]
858   "TARGET_H8300 && flow2_completed"
859   [(const_int 0)]
860   "split_adds_subs (HImode, operands); DONE;")
862 (define_peephole2
863   [(match_scratch:HI 2 "r")
864    (set (match_operand:HI 0 "stack_pointer_operand" "")
865         (plus:HI (match_dup 0)
866                  (match_operand:HI 1 "const_int_ge_8_operand" "")))]
867   "TARGET_H8300"
868   [(set (match_dup 2)
869         (match_dup 1))
870    (set (match_dup 0)
871         (plus:HI (match_dup 0)
872                  (match_dup 2)))]
873   "")
875 (define_insn "*addhi3_h8300hs"
876   [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r")
877         (plus:HI (match_operand:HI 1 "register_operand" "%0,0,0,0,0")
878                  (match_operand:HI 2 "nonmemory_operand" "L,N,J,n,r")))]
879   "TARGET_H8300H || TARGET_H8300S"
880   "@
881    adds %2,%S0
882    subs %G2,%S0
883    add.b        %t2,%t0
884    add.w        %T2,%T0
885    add.w        %T2,%T0"
886   [(set_attr "length" "2,2,2,4,2")
887    (set_attr "cc" "none_0hit,none_0hit,clobber,set_zn,set_zn")])
889 (define_insn "*addhi3_incdec"
890   [(set (match_operand:HI 0 "register_operand" "=r,r")
891         (unspec:HI [(match_operand:HI 1 "register_operand" "0,0")
892                     (match_operand:HI 2 "incdec_operand" "M,O")]
893                    UNSPEC_INCDEC))]
894   "TARGET_H8300H || TARGET_H8300S"
895   "@
896    inc.w        %2,%T0
897    dec.w        %G2,%T0"
898   [(set_attr "length" "2,2")
899    (set_attr "cc" "set_zn,set_zn")])
901 (define_split
902   [(set (match_operand:HI 0 "register_operand" "")
903         (plus:HI (match_dup 0)
904                  (match_operand:HI 1 "two_insn_adds_subs_operand" "")))]
905   ""
906   [(const_int 0)]
907   "split_adds_subs (HImode, operands); DONE;")
909 (define_expand "addsi3"
910   [(set (match_operand:SI 0 "register_operand" "")
911         (plus:SI (match_operand:SI 1 "register_operand" "")
912                  (match_operand:SI 2 "nonmemory_operand" "")))]
913   ""
914   "")
916 (define_insn "*addsi_h8300"
917   [(set (match_operand:SI 0 "register_operand" "=r,r")
918         (plus:SI (match_operand:SI 1 "register_operand" "%0,0")
919                  (match_operand:SI 2 "nonmemory_operand" "n,r")))]
920   "TARGET_H8300"
921   "* return output_plussi (operands);"
922   [(set (attr "length")
923         (symbol_ref "compute_plussi_length (operands)"))
924    (set (attr "cc")
925         (symbol_ref "compute_plussi_cc (operands)"))])
927 (define_insn "*addsi_h8300hs"
928   [(set (match_operand:SI 0 "register_operand" "=r,r")
929         (plus:SI (match_operand:SI 1 "register_operand" "%0,0")
930                  (match_operand:SI 2 "nonmemory_operand" "i,r")))]
931   "TARGET_H8300H || TARGET_H8300S"
932   "* return output_plussi (operands);"
933   [(set (attr "length")
934         (symbol_ref "compute_plussi_length (operands)"))
935    (set (attr "cc")
936         (symbol_ref "compute_plussi_cc (operands)"))])
938 (define_insn "*addsi3_incdec"
939   [(set (match_operand:SI 0 "register_operand" "=r,r")
940         (unspec:SI [(match_operand:SI 1 "register_operand" "0,0")
941                     (match_operand:SI 2 "incdec_operand" "M,O")]
942                    UNSPEC_INCDEC))]
943   "TARGET_H8300H || TARGET_H8300S"
944   "@
945    inc.l        %2,%S0
946    dec.l        %G2,%S0"
947   [(set_attr "length" "2,2")
948    (set_attr "cc" "set_zn,set_zn")])
950 (define_split
951   [(set (match_operand:SI 0 "register_operand" "")
952         (plus:SI (match_dup 0)
953                  (match_operand:SI 1 "two_insn_adds_subs_operand" "")))]
954   "TARGET_H8300H || TARGET_H8300S"
955   [(const_int 0)]
956   "split_adds_subs (SImode, operands); DONE;")
958 ;; ----------------------------------------------------------------------
959 ;; SUBTRACT INSTRUCTIONS
960 ;; ----------------------------------------------------------------------
962 (define_insn "subqi3"
963   [(set (match_operand:QI 0 "register_operand" "=r")
964         (minus:QI (match_operand:QI 1 "register_operand" "0")
965                   (match_operand:QI 2 "register_operand" "r")))]
966   ""
967   "sub.b        %X2,%X0"
968   [(set_attr "length" "2")
969    (set_attr "cc" "set_zn")])
971 (define_expand "subhi3"
972   [(set (match_operand:HI 0 "register_operand" "")
973         (minus:HI (match_operand:HI 1 "general_operand" "")
974                   (match_operand:HI 2 "nonmemory_operand" "")))]
975   ""
976   "")
978 (define_insn "*subhi3_h8300"
979   [(set (match_operand:HI 0 "register_operand" "=r,r")
980         (minus:HI (match_operand:HI 1 "general_operand" "0,0")
981                   (match_operand:HI 2 "nonmemory_operand" "r,n")))]
982   "TARGET_H8300"
983   "@
984    sub.w        %T2,%T0
985    add.b        %E2,%s0\;addx   %F2,%t0"
986   [(set_attr "length" "2,4")
987    (set_attr "cc" "set_zn,clobber")])
989 (define_insn "*subhi3_h8300hs"
990   [(set (match_operand:HI 0 "register_operand" "=r,r")
991         (minus:HI (match_operand:HI 1 "general_operand" "0,0")
992                   (match_operand:HI 2 "nonmemory_operand" "r,n")))]
993   "TARGET_H8300H || TARGET_H8300S"
994   "@
995    sub.w        %T2,%T0
996    sub.w        %T2,%T0"
997   [(set_attr "length" "2,4")
998    (set_attr "cc" "set_zn,set_zn")])
1000 (define_expand "subsi3"
1001   [(set (match_operand:SI 0 "register_operand" "")
1002         (minus:SI (match_operand:SI 1 "register_operand" "")
1003                   (match_operand:SI 2 "nonmemory_operand" "")))]
1004   ""
1005   "")
1007 (define_insn "*subsi3_h8300"
1008   [(set (match_operand:SI 0 "register_operand" "=r")
1009         (minus:SI (match_operand:SI 1 "register_operand" "0")
1010                   (match_operand:SI 2 "register_operand" "r")))]
1011   "TARGET_H8300"
1012   "sub.w        %f2,%f0\;subx   %y2,%y0\;subx   %z2,%z0"
1013   [(set_attr "length" "6")
1014    (set_attr "cc" "clobber")])
1016 (define_insn "*subsi3_h8300hs"
1017   [(set (match_operand:SI 0 "register_operand" "=r,r")
1018         (minus:SI (match_operand:SI 1 "general_operand" "0,0")
1019                   (match_operand:SI 2 "nonmemory_operand" "r,i")))]
1020   "TARGET_H8300H || TARGET_H8300S"
1021   "@
1022    sub.l        %S2,%S0
1023    sub.l        %S2,%S0"
1024   [(set_attr "length" "2,6")
1025    (set_attr "cc" "set_zn,set_zn")])
1027 ;; ----------------------------------------------------------------------
1028 ;; MULTIPLY INSTRUCTIONS
1029 ;; ----------------------------------------------------------------------
1031 ;; Note that the H8/300 can only handle umulqihi3.
1033 (define_insn "mulqihi3"
1034   [(set (match_operand:HI 0 "register_operand" "=r")
1035         (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "%0"))
1036                  (sign_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
1037   "TARGET_H8300H || TARGET_H8300S"
1038   "mulxs.b      %X2,%T0"
1039   [(set_attr "length" "4")
1040    (set_attr "cc" "set_zn")])
1042 (define_insn "mulhisi3"
1043   [(set (match_operand:SI 0 "register_operand" "=r")
1044         (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" "%0"))
1045                  (sign_extend:SI (match_operand:HI 2 "register_operand" "r"))))]
1046   "TARGET_H8300H || TARGET_H8300S"
1047   "mulxs.w      %T2,%S0"
1048   [(set_attr "length" "4")
1049    (set_attr "cc" "set_zn")])
1051 (define_insn "umulqihi3"
1052   [(set (match_operand:HI 0 "register_operand" "=r")
1053         (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "%0"))
1054                  (zero_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
1055   ""
1056   "mulxu        %X2,%T0"
1057   [(set_attr "length" "2")
1058    (set_attr "cc" "none_0hit")])
1060 (define_insn "umulhisi3"
1061   [(set (match_operand:SI 0 "register_operand" "=r")
1062         (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "%0"))
1063                  (zero_extend:SI (match_operand:HI 2 "register_operand" "r"))))]
1064   "TARGET_H8300H || TARGET_H8300S"
1065   "mulxu.w      %T2,%S0"
1066   [(set_attr "length" "2")
1067    (set_attr "cc" "none_0hit")])
1069 ;; This is a "bridge" instruction.  Combine can't cram enough insns
1070 ;; together to crate a MAC instruction directly, but it can create
1071 ;; this instruction, which then allows combine to create the real
1072 ;; MAC insn.
1074 ;; Unfortunately, if combine doesn't create a MAC instruction, this
1075 ;; insn must generate reasonably correct code.  Egad.
1076 (define_insn ""
1077   [(set (match_operand:SI 0 "register_operand" "=a")
1078         (mult:SI
1079           (sign_extend:SI
1080             (mem:HI (post_inc:SI (match_operand:SI 1 "register_operand" "r"))))
1081           (sign_extend:SI
1082             (mem:HI (post_inc:SI (match_operand:SI 2 "register_operand" "r"))))))]
1083   "TARGET_MAC"
1084   "clrmac\;mac  @%2+,@%1+"
1085   [(set_attr "length" "6")
1086    (set_attr "cc" "none_0hit")])
1088 (define_insn ""
1089   [(set (match_operand:SI 0 "register_operand" "=a")
1090         (plus:SI (mult:SI
1091           (sign_extend:SI (mem:HI
1092             (post_inc:SI (match_operand:SI 1 "register_operand" "r"))))
1093           (sign_extend:SI (mem:HI
1094             (post_inc:SI (match_operand:SI 2 "register_operand" "r")))))
1095               (match_operand:SI 3 "register_operand" "0")))]
1096   "TARGET_MAC"
1097   "mac  @%2+,@%1+"
1098   [(set_attr "length" "4")
1099    (set_attr "cc" "none_0hit")])
1101 ;; ----------------------------------------------------------------------
1102 ;; DIVIDE/MOD INSTRUCTIONS
1103 ;; ----------------------------------------------------------------------
1105 (define_insn "udivmodqi4"
1106   [(set (match_operand:QI 0 "register_operand" "=r")
1107         (truncate:QI
1108           (udiv:HI
1109             (match_operand:HI 1 "register_operand" "0")
1110             (zero_extend:HI (match_operand:QI 2 "register_operand" "r")))))
1111    (set (match_operand:QI 3 "register_operand" "=r")
1112         (truncate:QI
1113           (umod:HI
1114             (match_dup 1)
1115             (zero_extend:HI (match_dup 2)))))]
1116   ""
1117   "*
1119   if (find_reg_note (insn, REG_UNUSED, operands[3]))
1120     return \"divxu.b\\t%X2,%T0\";
1121   else
1122     return \"divxu.b\\t%X2,%T0\;mov.b\\t%t0,%s3\";
1124   [(set_attr "length" "4")
1125    (set_attr "cc" "clobber")])
1127 (define_insn "divmodqi4"
1128   [(set (match_operand:QI 0 "register_operand" "=r")
1129         (truncate:QI
1130           (div:HI
1131             (match_operand:HI 1 "register_operand" "0")
1132             (sign_extend:HI (match_operand:QI 2 "register_operand" "r")))))
1133    (set (match_operand:QI 3 "register_operand" "=r")
1134         (truncate:QI
1135           (mod:HI
1136             (match_dup 1)
1137             (sign_extend:HI (match_dup 2)))))]
1138   "TARGET_H8300H || TARGET_H8300S"
1139   "*
1141   if (find_reg_note (insn, REG_UNUSED, operands[3]))
1142     return \"divxs.b\\t%X2,%T0\";
1143   else
1144     return \"divxs.b\\t%X2,%T0\;mov.b\\t%t0,%s3\";
1146   [(set_attr "length" "6")
1147    (set_attr "cc" "clobber")])
1149 (define_insn "udivmodhi4"
1150   [(set (match_operand:HI 0 "register_operand" "=r")
1151         (truncate:HI
1152           (udiv:SI
1153             (match_operand:SI 1 "register_operand" "0")
1154             (zero_extend:SI (match_operand:HI 2 "register_operand" "r")))))
1155    (set (match_operand:HI 3 "register_operand" "=r")
1156         (truncate:HI
1157           (umod:SI
1158             (match_dup 1)
1159             (zero_extend:SI (match_dup 2)))))]
1160   "TARGET_H8300H || TARGET_H8300S"
1161   "*
1163   if (find_reg_note (insn, REG_UNUSED, operands[3]))
1164     return \"divxu.w\\t%T2,%S0\";
1165   else
1166     return \"divxu.w\\t%T2,%S0\;mov.w\\t%e0,%f3\";
1168   [(set_attr "length" "4")
1169    (set_attr "cc" "clobber")])
1171 (define_insn "divmodhi4"
1172   [(set (match_operand:HI 0 "register_operand" "=r")
1173         (truncate:HI
1174           (div:SI
1175             (match_operand:SI 1 "register_operand" "0")
1176             (sign_extend:SI (match_operand:HI 2 "register_operand" "r")))))
1177    (set (match_operand:HI 3 "register_operand" "=r")
1178         (truncate:HI
1179           (mod:SI
1180             (match_dup 1)
1181             (sign_extend:SI (match_dup 2)))))]
1182   "TARGET_H8300H || TARGET_H8300S"
1183   "*
1185   if (find_reg_note (insn, REG_UNUSED, operands[3]))
1186     return \"divxs.w\\t%T2,%S0\";
1187   else
1188     return \"divxs.w\\t%T2,%S0\;mov.w\\t%e0,%f3\";
1190   [(set_attr "length" "6")
1191    (set_attr "cc" "clobber")])
1193 ;; ----------------------------------------------------------------------
1194 ;; AND INSTRUCTIONS
1195 ;; ----------------------------------------------------------------------
1197 (define_insn "*andqi3_1"
1198   [(set (match_operand:QI 0 "bit_operand" "=r,U")
1199         (and:QI (match_operand:QI 1 "bit_operand" "%0,0")
1200                 (match_operand:QI 2 "nonmemory_operand" "rn,n")))]
1201   "register_operand (operands[0], QImode)
1202    || single_zero_operand (operands[2], QImode)"
1203   "@
1204    and  %X2,%X0
1205    bclr %W2,%R0"
1206   [(set_attr "length" "2,8")
1207    (set_attr "cc" "set_znv,none_0hit")])
1209 (define_expand "andqi3"
1210   [(set (match_operand:QI 0 "bit_operand" "")
1211         (and:QI (match_operand:QI 1 "bit_operand" "")
1212                 (match_operand:QI 2 "nonmemory_operand" "")))]
1213   ""
1214   "
1216   if (fix_bit_operand (operands, 0, AND))
1217     DONE;
1220 (define_expand "andhi3"
1221   [(set (match_operand:HI 0 "register_operand" "")
1222         (and:HI (match_operand:HI 1 "register_operand" "")
1223                 (match_operand:HI 2 "nonmemory_operand" "")))]
1224   ""
1225   "")
1227 (define_insn "*andorqi3"
1228   [(set (match_operand:QI 0 "register_operand" "=r")
1229         (ior:QI (and:QI (match_operand:QI 2 "register_operand" "r")
1230                         (match_operand:QI 3 "single_one_operand" "n"))
1231                 (match_operand:QI 1 "register_operand" "0")))]
1232   ""
1233   "bld\\t%V3,%X2\;bor\\t%V3,%X0\;bst\\t%V3,%X0"
1234   [(set_attr "length" "6")
1235    (set_attr "cc" "clobber")])
1237 (define_insn "*andorhi3"
1238   [(set (match_operand:HI 0 "register_operand" "=r")
1239         (ior:HI (and:HI (match_operand:HI 2 "register_operand" "r")
1240                         (match_operand:HI 3 "single_one_operand" "n"))
1241                 (match_operand:HI 1 "register_operand" "0")))]
1242   ""
1243   "*
1245   operands[3] = GEN_INT (INTVAL (operands[3]) & 0xffff);
1246   if (INTVAL (operands[3]) > 128)
1247     {
1248       operands[3] = GEN_INT (INTVAL (operands[3]) >> 8);
1249       return \"bld\\t%V3,%t2\;bor\\t%V3,%t0\;bst\\t%V3,%t0\";
1250     }
1251   return \"bld\\t%V3,%s2\;bor\\t%V3,%s0\;bst\\t%V3,%s0\";
1253   [(set_attr "length" "6")
1254    (set_attr "cc" "clobber")])
1256 (define_insn "*andorsi3"
1257   [(set (match_operand:SI 0 "register_operand" "=r")
1258         (ior:SI (and:SI (match_operand:SI 2 "register_operand" "r")
1259                         (match_operand:SI 3 "single_one_operand" "n"))
1260                 (match_operand:SI 1 "register_operand" "0")))]
1261   "(INTVAL (operands[3]) & 0xffff) != 0"
1262   "*
1264   operands[3] = GEN_INT (INTVAL (operands[3]) & 0xffff);
1265   if (INTVAL (operands[3]) > 128)
1266     {
1267       operands[3] = GEN_INT (INTVAL (operands[3]) >> 8);
1268       return \"bld\\t%V3,%x2\;bor\\t%V3,%x0\;bst\\t%V3,%x0\";
1269     }
1270   return \"bld\\t%V3,%w2\;bor\\t%V3,%w0\;bst\\t%V3,%w0\";
1272   [(set_attr "length" "6")
1273    (set_attr "cc" "clobber")])
1275 (define_insn "*andorsi3_shift_8"
1276   [(set (match_operand:SI 0 "register_operand" "=r")
1277         (ior:SI (and:SI (ashift:SI (match_operand:SI 2 "register_operand" "r")
1278                                    (const_int 8))
1279                         (const_int 65280))
1280                 (match_operand:SI 1 "register_operand" "0")))]
1281   ""
1282   "or.b\\t%w2,%x0"
1283   [(set_attr "length" "2")
1284    (set_attr "cc" "clobber")])
1286 (define_expand "andsi3"
1287   [(set (match_operand:SI 0 "register_operand" "")
1288         (and:SI (match_operand:SI 1 "register_operand" "")
1289                 (match_operand:SI 2 "nonmemory_operand" "")))]
1290   ""
1291   "")
1293 ;; ----------------------------------------------------------------------
1294 ;; OR INSTRUCTIONS
1295 ;; ----------------------------------------------------------------------
1297 (define_insn "*iorqi3_1"
1298   [(set (match_operand:QI 0 "bit_operand" "=r,U")
1299         (ior:QI (match_operand:QI 1 "bit_operand" "%0,0")
1300                 (match_operand:QI 2 "nonmemory_operand" "rn,n")))]
1301   "register_operand (operands[0], QImode)
1302    || single_one_operand (operands[2], QImode)"
1303   "@
1304    or\\t%X2,%X0
1305    bset\\t%V2,%R0"
1306   [(set_attr "length" "2,8")
1307    (set_attr "cc" "set_znv,none_0hit")])
1309 (define_expand "iorqi3"
1310   [(set (match_operand:QI 0 "bit_operand" "")
1311         (ior:QI (match_operand:QI 1 "bit_operand" "")
1312                 (match_operand:QI 2 "nonmemory_operand" "")))]
1313   ""
1314   "
1316   if (fix_bit_operand (operands, 1, IOR))
1317     DONE;
1320 (define_expand "iorhi3"
1321   [(set (match_operand:HI 0 "register_operand" "")
1322         (ior:HI (match_operand:HI 1 "register_operand" "")
1323                 (match_operand:HI 2 "nonmemory_operand" "")))]
1324   ""
1325   "")
1327 (define_expand "iorsi3"
1328   [(set (match_operand:SI 0 "register_operand" "")
1329         (ior:SI (match_operand:SI 1 "register_operand" "")
1330                 (match_operand:SI 2 "nonmemory_operand" "")))]
1331   ""
1332   "")
1334 ;; ----------------------------------------------------------------------
1335 ;; XOR INSTRUCTIONS
1336 ;; ----------------------------------------------------------------------
1338 (define_insn "*xorqi3_1"
1339   [(set (match_operand:QI 0 "bit_operand" "=r,U")
1340         (xor:QI (match_operand:QI 1 "bit_operand" "%0,0")
1341                 (match_operand:QI 2 "nonmemory_operand" "rn,n")))]
1342   "register_operand (operands[0], QImode)
1343    || single_one_operand (operands[2], QImode)"
1344   "@
1345    xor\\t%X2,%X0
1346    bnot\\t%V2,%R0"
1347   [(set_attr "length" "2,8")
1348    (set_attr "cc" "set_znv,none_0hit")])
1350 (define_expand "xorqi3"
1351   [(set (match_operand:QI 0 "bit_operand" "")
1352         (xor:QI (match_operand:QI 1 "bit_operand" "")
1353                 (match_operand:QI 2 "nonmemory_operand" "")))]
1354   ""
1355   "
1357   if (fix_bit_operand (operands, 1, XOR))
1358     DONE;
1361 (define_expand "xorhi3"
1362   [(set (match_operand:HI 0 "register_operand" "")
1363         (xor:HI (match_operand:HI 1 "register_operand" "")
1364                 (match_operand:HI 2 "nonmemory_operand" "")))]
1365   ""
1366   "")
1368 (define_expand "xorsi3"
1369   [(set (match_operand:SI 0 "register_operand" "")
1370         (xor:SI (match_operand:SI 1 "register_operand" "")
1371                 (match_operand:SI 2 "nonmemory_operand" "")))]
1372   ""
1373   "")
1375 ;; ----------------------------------------------------------------------
1376 ;; {AND,IOR,XOR}{HI3,SI3} PATTERNS
1377 ;; ----------------------------------------------------------------------
1379 (define_insn "*logicalhi3"
1380   [(set (match_operand:HI 0 "register_operand" "=r")
1381         (match_operator:HI 3 "bit_operator"
1382           [(match_operand:HI 1 "register_operand" "%0")
1383            (match_operand:HI 2 "nonmemory_operand" "rn")]))]
1384   ""
1385   "* return output_logical_op (HImode, operands);"
1386   [(set (attr "length")
1387         (symbol_ref "compute_logical_op_length (HImode, operands)"))
1388    (set (attr "cc")
1389         (symbol_ref "compute_logical_op_cc (HImode, operands)"))])
1391 (define_insn "*logicalsi3"
1392   [(set (match_operand:SI 0 "register_operand" "=r")
1393         (match_operator:SI 3 "bit_operator"
1394           [(match_operand:SI 1 "register_operand" "%0")
1395            (match_operand:SI 2 "nonmemory_operand" "rn")]))]
1396   ""
1397   "* return output_logical_op (SImode, operands);"
1398   [(set (attr "length")
1399         (symbol_ref "compute_logical_op_length (SImode, operands)"))
1400    (set (attr "cc")
1401         (symbol_ref "compute_logical_op_cc (SImode, operands)"))])
1403 ;; ----------------------------------------------------------------------
1404 ;; NEGATION INSTRUCTIONS
1405 ;; ----------------------------------------------------------------------
1407 (define_insn "negqi2"
1408   [(set (match_operand:QI 0 "register_operand" "=r")
1409         (neg:QI (match_operand:QI 1 "register_operand" "0")))]
1410   ""
1411   "neg  %X0"
1412   [(set_attr "length" "2")
1413    (set_attr "cc" "set_zn")])
1415 (define_expand "neghi2"
1416   [(set (match_operand:HI 0 "register_operand" "")
1417         (neg:HI (match_operand:HI 1 "register_operand" "")))]
1418   ""
1419   "
1421   if (TARGET_H8300)
1422     {
1423       emit_insn (gen_neghi2_h8300 (operands[0], operands[1]));
1424       DONE;
1425     }
1428 (define_expand "neghi2_h8300"
1429   [(set (match_dup 2)
1430         (not:HI (match_operand:HI 1 "register_operand" "")))
1431    (set (match_dup 2) (plus:HI (match_dup 2) (const_int 1)))
1432    (set (match_operand:HI 0 "register_operand" "")
1433         (match_dup 2))]
1434   ""
1435   "operands[2] = gen_reg_rtx (HImode);")
1437 (define_insn "*neghi2_h8300hs"
1438   [(set (match_operand:HI 0 "register_operand" "=r")
1439         (neg:HI (match_operand:HI 1 "register_operand" "0")))]
1440   "TARGET_H8300H || TARGET_H8300S"
1441   "neg  %T0"
1442   [(set_attr "length" "2")
1443    (set_attr "cc" "set_zn")])
1445 (define_expand "negsi2"
1446   [(set (match_operand:SI 0 "register_operand" "")
1447         (neg:SI (match_operand:SI 1 "register_operand" "")))]
1448   ""
1449   "
1451   if (TARGET_H8300)
1452     {
1453       emit_insn (gen_negsi2_h8300 (operands[0], operands[1]));
1454       DONE;
1455     }
1458 (define_expand "negsi2_h8300"
1459   [(set (match_dup 2)
1460         (not:SI (match_operand:SI 1 "register_operand" "")))
1461    (set (match_dup 2) (plus:SI (match_dup 2) (const_int 1)))
1462    (set (match_operand:SI 0 "register_operand" "")
1463         (match_dup 2))]
1464   ""
1465   "operands[2] = gen_reg_rtx (SImode);")
1467 (define_insn "*negsi2_h8300hs"
1468   [(set (match_operand:SI 0 "register_operand" "=r")
1469         (neg:SI (match_operand:SI 1 "register_operand" "0")))]
1470   "TARGET_H8300H || TARGET_H8300S"
1471   "neg  %S0"
1472   [(set_attr "length" "2")
1473    (set_attr "cc" "set_zn")])
1475 (define_expand "negsf2"
1476   [(set (match_operand:SF 0 "register_operand" "")
1477         (neg:SF (match_operand:SF 1 "register_operand" "")))]
1478   ""
1479   "")
1481 (define_insn "*negsf2_h8300"
1482   [(set (match_operand:SF 0 "register_operand" "=r")
1483         (neg:SF (match_operand:SF 1 "register_operand" "0")))]
1484   "TARGET_H8300"
1485   "xor.b\\t#128,%z0"
1486   [(set_attr "cc" "clobber")
1487    (set_attr "length" "2")])
1489 (define_insn "*negsf2_h8300hs"
1490   [(set (match_operand:SF 0 "register_operand" "=r")
1491         (neg:SF (match_operand:SF 1 "register_operand" "0")))]
1492   "TARGET_H8300H || TARGET_H8300S"
1493   "xor.w\\t#32768,%e0"
1494   [(set_attr "cc" "clobber")
1495    (set_attr "length" "4")])
1497 ;; ----------------------------------------------------------------------
1498 ;; ABSOLUTE VALUE INSTRUCTIONS
1499 ;; ----------------------------------------------------------------------
1501 (define_expand "abssf2"
1502   [(set (match_operand:SF 0 "register_operand" "")
1503         (abs:SF (match_operand:SF 1 "register_operand" "")))]
1504   ""
1505   "")
1507 (define_insn "*abssf2_h8300"
1508   [(set (match_operand:SF 0 "register_operand" "=r")
1509         (abs:SF (match_operand:SF 1 "register_operand" "0")))]
1510   "TARGET_H8300"
1511   "and.b\\t#127,%z0"
1512   [(set_attr "cc" "clobber")
1513    (set_attr "length" "2")])
1515 (define_insn "*abssf2_h8300hs"
1516   [(set (match_operand:SF 0 "register_operand" "=r")
1517         (abs:SF (match_operand:SF 1 "register_operand" "0")))]
1518   "TARGET_H8300H || TARGET_H8300S"
1519   "and.w\\t#32767,%e0"
1520   [(set_attr "cc" "clobber")
1521    (set_attr "length" "4")])
1523 ;; ----------------------------------------------------------------------
1524 ;; NOT INSTRUCTIONS
1525 ;; ----------------------------------------------------------------------
1527 (define_insn "one_cmplqi2"
1528   [(set (match_operand:QI 0 "register_operand" "=r")
1529         (not:QI (match_operand:QI 1 "register_operand" "0")))]
1530   ""
1531   "not  %X0"
1532   [(set_attr "length" "2")
1533    (set_attr "cc" "set_znv")])
1535 (define_expand "one_cmplhi2"
1536   [(set (match_operand:HI 0 "register_operand" "=r")
1537         (not:HI (match_operand:HI 1 "register_operand" "0")))]
1538   ""
1539   "")
1541 (define_insn "*one_cmplhi2_h8300"
1542   [(set (match_operand:HI 0 "register_operand" "=r")
1543         (not:HI (match_operand:HI 1 "register_operand" "0")))]
1544   "TARGET_H8300"
1545   "not  %s0\;not        %t0"
1546   [(set_attr "cc" "clobber")
1547    (set_attr "length" "4")])
1549 (define_insn "*one_cmplhi2_h8300hs"
1550   [(set (match_operand:HI 0 "register_operand" "=r")
1551         (not:HI (match_operand:HI 1 "register_operand" "0")))]
1552   "TARGET_H8300H || TARGET_H8300S"
1553   "not  %T0"
1554   [(set_attr "cc" "set_znv")
1555    (set_attr "length" "2")])
1557 (define_expand "one_cmplsi2"
1558   [(set (match_operand:SI 0 "register_operand" "=r")
1559         (not:SI (match_operand:SI 1 "register_operand" "0")))]
1560   ""
1561   "")
1563 (define_insn "*one_complsi2_h8300"
1564   [(set (match_operand:SI 0 "register_operand" "=r")
1565         (not:SI (match_operand:SI 1 "register_operand" "0")))]
1566   "TARGET_H8300"
1567   "not  %w0\;not        %x0\;not        %y0\;not        %z0"
1568   [(set_attr "cc" "clobber")
1569    (set_attr "length" "8")])
1571 (define_insn "*one_complsi2_h8300hs"
1572   [(set (match_operand:SI 0 "register_operand" "=r")
1573         (not:SI (match_operand:SI 1 "register_operand" "0")))]
1574   "TARGET_H8300H || TARGET_H8300S"
1575   "not  %S0"
1576   [(set_attr "cc" "set_znv")
1577    (set_attr "length" "2")])
1579 ;; ----------------------------------------------------------------------
1580 ;; JUMP INSTRUCTIONS
1581 ;; ----------------------------------------------------------------------
1583 ;; Conditional jump instructions
1585 (define_expand "ble"
1586   [(set (pc)
1587         (if_then_else (le (cc0)
1588                           (const_int 0))
1589                       (label_ref (match_operand 0 "" ""))
1590                       (pc)))]
1591   ""
1592   "")
1594 (define_expand "bleu"
1595   [(set (pc)
1596         (if_then_else (leu (cc0)
1597                            (const_int 0))
1598                       (label_ref (match_operand 0 "" ""))
1599                       (pc)))]
1600   ""
1601   "")
1603 (define_expand "bge"
1604   [(set (pc)
1605         (if_then_else (ge (cc0)
1606                           (const_int 0))
1607                       (label_ref (match_operand 0 "" ""))
1608                       (pc)))]
1609   ""
1610   "")
1612 (define_expand "bgeu"
1613   [(set (pc)
1614         (if_then_else (geu (cc0)
1615                            (const_int 0))
1616                       (label_ref (match_operand 0 "" ""))
1617                       (pc)))]
1618   ""
1619   "")
1621 (define_expand "blt"
1622   [(set (pc)
1623         (if_then_else (lt (cc0)
1624                           (const_int 0))
1625                       (label_ref (match_operand 0 "" ""))
1626                       (pc)))]
1627   ""
1628   "")
1630 (define_expand "bltu"
1631   [(set (pc)
1632         (if_then_else (ltu (cc0)
1633                            (const_int 0))
1634                       (label_ref (match_operand 0 "" ""))
1635                       (pc)))]
1636   ""
1637   "")
1639 (define_expand "bgt"
1640   [(set (pc)
1641         (if_then_else (gt (cc0)
1642                           (const_int 0))
1643                       (label_ref (match_operand 0 "" ""))
1644                       (pc)))]
1645   ""
1646   "")
1648 (define_expand "bgtu"
1649   [(set (pc)
1650         (if_then_else (gtu (cc0)
1651                            (const_int 0))
1652                       (label_ref (match_operand 0 "" ""))
1653                       (pc)))]
1654   ""
1655   "")
1657 (define_expand "beq"
1658   [(set (pc)
1659         (if_then_else (eq (cc0)
1660                           (const_int 0))
1661                       (label_ref (match_operand 0 "" ""))
1662                       (pc)))]
1663   ""
1664   "")
1666 (define_expand "bne"
1667   [(set (pc)
1668         (if_then_else (ne (cc0)
1669                           (const_int 0))
1670                       (label_ref (match_operand 0 "" ""))
1671                       (pc)))]
1672   ""
1673   "")
1675 (define_insn "branch_true"
1676   [(set (pc)
1677         (if_then_else (match_operator 1 "comparison_operator"
1678                                       [(cc0) (const_int 0)])
1679                       (label_ref (match_operand 0 "" ""))
1680                       (pc)))]
1681   ""
1682   "*
1684   if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0
1685       && (GET_CODE (operands[1]) == GT
1686           || GET_CODE (operands[1]) == GE
1687           || GET_CODE (operands[1]) == LE
1688           || GET_CODE (operands[1]) == LT))
1689     {
1690       cc_status.flags &= ~CC_OVERFLOW_UNUSABLE;
1691       return 0;
1692     }
1694   if (get_attr_length (insn) == 2)
1695     return \"b%j1       %l0\";
1696   else if (get_attr_length (insn) == 4)
1697     return \"b%j1       %l0:16\";
1698   else
1699     return \"b%k1       .Lh8BR%=\;jmp   @%l0\\n.Lh8BR%=:\";
1701  [(set_attr "type" "branch")
1702    (set_attr "cc" "none")])
1704 (define_insn "branch_false"
1705   [(set (pc)
1706         (if_then_else (match_operator 1 "comparison_operator"
1707                                       [(cc0) (const_int 0)])
1708                       (pc)
1709                       (label_ref (match_operand 0 "" ""))))]
1710   ""
1711   "*
1713   if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0
1714       && (GET_CODE (operands[1]) == GT
1715           || GET_CODE (operands[1]) == GE
1716           || GET_CODE (operands[1]) == LE
1717           || GET_CODE (operands[1]) == LT))
1718     {
1719       cc_status.flags &= ~CC_OVERFLOW_UNUSABLE;
1720       return 0;
1721     }
1723   if (get_attr_length (insn) == 2)
1724     return \"b%k1       %l0\";
1725   else if (get_attr_length (insn) == 4)
1726     return \"b%k1       %l0:16\";
1727   else
1728     return \"b%j1       .Lh8BR%=\;jmp   @%l0\\n.Lh8BR%=:\";
1730   [(set_attr "type" "branch")
1731    (set_attr "cc" "none")])
1733 ;; Unconditional and other jump instructions.
1735 (define_insn "jump"
1736   [(set (pc)
1737         (label_ref (match_operand 0 "" "")))]
1738   ""
1739   "*
1741   if (get_attr_length (insn) == 2)
1742     return \"bra        %l0\";
1743   else if (get_attr_length (insn) == 4)
1744     return \"bra        %l0:16\";
1745   else
1746     return \"jmp        @%l0\";
1748   [(set_attr "type" "branch")
1749    (set_attr "cc" "none")])
1751 ;; This is a define expand, because pointers may be either 16 or 32 bits.
1753 (define_expand "tablejump"
1754   [(parallel [(set (pc) (match_operand 0 "register_operand" ""))
1755               (use (label_ref (match_operand 1 "" "")))])]
1756   ""
1757   "")
1759 (define_insn "*tablejump_h8300"
1760   [(set (pc) (match_operand:HI 0 "register_operand" "r"))
1761    (use (label_ref (match_operand 1 "" "")))]
1762   "TARGET_H8300"
1763   "jmp  @%0"
1764   [(set_attr "cc" "none")
1765    (set_attr "length" "2")])
1767 (define_insn "*tablejump_h8300hs_advanced"
1768   [(set (pc) (match_operand:SI 0 "register_operand" "r"))
1769    (use (label_ref (match_operand 1 "" "")))]
1770   "(TARGET_H8300H || TARGET_H8300S) && !TARGET_NORMAL_MODE"
1771   "jmp  @%0"
1772   [(set_attr "cc" "none")
1773    (set_attr "length" "2")])
1775 (define_insn "*tablejump_h8300hs_normal"
1776   [(set (pc) (match_operand:HI 0 "register_operand" "r"))
1777    (use (label_ref (match_operand 1 "" "")))]
1778   "(TARGET_H8300H || TARGET_H8300S) && TARGET_NORMAL_MODE"
1779   "jmp @%S0"
1780   [(set_attr "cc" "none")
1781    (set_attr "length" "2")])
1783 ;; This is a define expand, because pointers may be either 16 or 32 bits.
1785 (define_expand "indirect_jump"
1786   [(set (pc) (match_operand 0 "jump_address_operand" ""))]
1787   ""
1788   "")
1790 (define_insn "*indirect_jump_h8300"
1791   [(set (pc) (match_operand:HI 0 "jump_address_operand" "Vr"))]
1792   "TARGET_H8300"
1793   "jmp  @%0"
1794   [(set_attr "cc" "none")
1795    (set_attr "length" "2")])
1797 (define_insn "*indirect_jump_h8300hs_advanced"
1798   [(set (pc) (match_operand:SI 0 "jump_address_operand" "Vr"))]
1799   "(TARGET_H8300H || TARGET_H8300S) && !TARGET_NORMAL_MODE"
1800   "jmp @%0"
1801   [(set_attr "cc" "none")
1802    (set_attr "length" "2")])
1804 (define_insn "*indirect_jump_h8300hs_normal"
1805   [(set (pc) (match_operand:HI 0 "jump_address_operand" "Vr"))]
1806   "(TARGET_H8300H || TARGET_H8300S) && TARGET_NORMAL_MODE"
1807   "jmp @%S0"
1808   [(set_attr "cc" "none")
1809    (set_attr "length" "2")])
1811 ;; Call subroutine with no return value.
1813 ;; ??? Even though we use HImode here, this works on the H8/300H and H8S.
1815 (define_insn "call"
1816   [(call (match_operand:QI 0 "call_insn_operand" "or")
1817          (match_operand:HI 1 "general_operand" "g"))]
1818   ""
1819   "*
1821   if (GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
1822       && SYMBOL_REF_FLAG (XEXP (operands[0], 0)))
1823     return \"jsr\\t@%0:8\";
1824   else
1825     return \"jsr\\t%0\";
1827   [(set_attr "cc" "clobber")
1828    (set (attr "length")
1829         (if_then_else (match_operand:QI 0 "small_call_insn_operand" "")
1830                       (const_int 2)
1831                       (const_int 4)))])
1833 ;; Call subroutine, returning value in operand 0
1834 ;; (which must be a hard register).
1836 ;; ??? Even though we use HImode here, this works on the H8/300H and H8S.
1838 (define_insn "call_value"
1839   [(set (match_operand 0 "" "=r")
1840         (call (match_operand:QI 1 "call_insn_operand" "or")
1841               (match_operand:HI 2 "general_operand" "g")))]
1842   ""
1843   "*
1845   if (GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
1846       && SYMBOL_REF_FLAG (XEXP (operands[1], 0)))
1847     return \"jsr\\t@%1:8\";
1848   else
1849     return \"jsr\\t%1\";
1851   [(set_attr "cc" "clobber")
1852    (set (attr "length")
1853         (if_then_else (match_operand:QI 0 "small_call_insn_operand" "")
1854                       (const_int 2)
1855                       (const_int 4)))])
1857 (define_insn "nop"
1858   [(const_int 0)]
1859   ""
1860   "nop"
1861   [(set_attr "cc" "none")
1862    (set_attr "length" "2")])
1864 ;; ----------------------------------------------------------------------
1865 ;; PROLOGUE/EPILOGUE-RELATED INSTRUCTIONS
1866 ;; ----------------------------------------------------------------------
1868 (define_expand "push_h8300"
1869   [(set (mem:HI (pre_dec:HI (reg:HI SP_REG)))
1870         (match_operand:HI 0 "register_operand" ""))]
1871   "TARGET_H8300"
1872   "")
1874 (define_expand "push_h8300hs_advanced"
1875   [(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
1876         (match_operand:SI 0 "register_operand" ""))]
1877   "TARGET_H8300H && TARGET_H8300S && !TARGET_NORMAL_MODE"
1878   "")
1880 (define_expand "push_h8300hs_normal"
1881   [(set (mem:SI (pre_dec:HI (reg:HI SP_REG)))
1882         (match_operand:SI 0 "register_operand" ""))]
1883   "TARGET_H8300H && TARGET_H8300S && TARGET_NORMAL_MODE"
1884   "")
1886 (define_expand "pop_h8300"
1887   [(set (match_operand:HI 0 "register_operand" "")
1888         (mem:HI (post_inc:HI (reg:HI SP_REG))))]
1889   "TARGET_H8300"
1890   "")
1892 (define_expand "pop_h8300hs_advanced"
1893   [(set (match_operand:SI 0 "register_operand" "")
1894         (mem:SI (post_inc:SI (reg:SI SP_REG))))]
1895   "TARGET_H8300H && TARGET_H8300S && !TARGET_NORMAL_MODE"
1896   "")
1898 (define_expand "pop_h8300hs_normal"
1899   [(set (match_operand:SI 0 "register_operand" "")
1900         (mem:SI (post_inc:HI (reg:HI SP_REG))))]
1901   "TARGET_H8300H && TARGET_H8300S && TARGET_NORMAL_MODE"
1902   "")
1904 (define_insn "stm_h8300s_2_advanced"
1905   [(parallel
1906      [(set (reg:SI SP_REG)
1907            (plus:SI (reg:SI SP_REG) (const_int -8)))
1908       (set (mem:SI (plus:SI (reg:SI SP_REG) (const_int -4)))
1909            (match_operand:SI 0 "register_operand" ""))
1910       (set (mem:SI (plus:SI (reg:SI SP_REG) (const_int -8)))
1911            (match_operand:SI 1 "register_operand" ""))])]
1912   "TARGET_H8300S && !TARGET_NORMAL_MODE
1913    && ((REGNO (operands[0]) == 0 && REGNO (operands[1]) == 1)
1914        || (REGNO (operands[0]) == 2 && REGNO (operands[1]) == 3)
1915        || (REGNO (operands[0]) == 4 && REGNO (operands[1]) == 5))"
1916   "stm.l\\t%S0-%S1,@-er7"
1917   [(set_attr "cc" "none")
1918    (set_attr "length" "4")])
1920 (define_insn "stm_h8300s_2_normal"
1921   [(parallel
1922      [(set (reg:HI SP_REG)
1923            (plus:HI (reg:HI SP_REG) (const_int -8)))
1924       (set (mem:SI (plus:HI (reg:HI SP_REG) (const_int -4)))
1925            (match_operand:SI 0 "register_operand" ""))
1926       (set (mem:SI (plus:HI (reg:HI SP_REG) (const_int -8)))
1927            (match_operand:SI 1 "register_operand" ""))])]
1928   "TARGET_H8300S && TARGET_NORMAL_MODE
1929    && ((REGNO (operands[0]) == 0 && REGNO (operands[1]) == 1)
1930        || (REGNO (operands[0]) == 2 && REGNO (operands[1]) == 3)
1931        || (REGNO (operands[0]) == 4 && REGNO (operands[1]) == 5))"
1932   "stm.l\\t%S0-%S1,@-er7"
1933   [(set_attr "cc" "none")
1934    (set_attr "length" "4")])
1936 (define_expand "stm_h8300s_2"
1937   [(use (match_operand:SI 0 "register_operand" ""))
1938    (use (match_operand:SI 1 "register_operand" ""))]
1939   "TARGET_H8300S
1940    && ((REGNO (operands[0]) == 0 && REGNO (operands[1]) == 1)
1941        || (REGNO (operands[0]) == 2 && REGNO (operands[1]) == 3)
1942        || (REGNO (operands[0]) == 4 && REGNO (operands[1]) == 5))"
1943   "
1945   if (!TARGET_NORMAL_MODE)
1946     emit_insn (gen_stm_h8300s_2_advanced (operands[0], operands[1]));
1947   else
1948     emit_insn (gen_stm_h8300s_2_normal (operands[0], operands[1]));
1949   DONE;
1952 (define_insn "stm_h8300s_3_advanced"
1953   [(parallel
1954      [(set (reg:SI SP_REG)
1955            (plus:SI (reg:SI SP_REG) (const_int -12)))
1956       (set (mem:SI (plus:SI (reg:SI SP_REG) (const_int -4)))
1957            (match_operand:SI 0 "register_operand" ""))
1958       (set (mem:SI (plus:SI (reg:SI SP_REG) (const_int -8)))
1959            (match_operand:SI 1 "register_operand" ""))
1960       (set (mem:SI (plus:SI (reg:SI SP_REG) (const_int -12)))
1961            (match_operand:SI 2 "register_operand" ""))])]
1962   "TARGET_H8300S && !TARGET_NORMAL_MODE
1963    && ((REGNO (operands[0]) == 0
1964         && REGNO (operands[1]) == 1
1965         && REGNO (operands[2]) == 2)
1966        || (REGNO (operands[0]) == 4
1967            && REGNO (operands[1]) == 5
1968            && REGNO (operands[2]) == 6))"
1969   "stm.l\\t%S0-%S2,@-er7"
1970   [(set_attr "cc" "none")
1971    (set_attr "length" "4")])
1973 (define_insn "stm_h8300s_3_normal"
1974   [(parallel
1975      [(set (reg:HI SP_REG)
1976            (plus:HI (reg:HI SP_REG) (const_int -12)))
1977       (set (mem:SI (plus:HI (reg:HI SP_REG) (const_int -4)))
1978            (match_operand:SI 0 "register_operand" ""))
1979       (set (mem:SI (plus:HI (reg:HI SP_REG) (const_int -8)))
1980            (match_operand:SI 1 "register_operand" ""))
1981       (set (mem:SI (plus:HI (reg:HI SP_REG) (const_int -12)))
1982            (match_operand:SI 2 "register_operand" ""))])]
1983   "TARGET_H8300S && TARGET_NORMAL_MODE
1984    && ((REGNO (operands[0]) == 0
1985         && REGNO (operands[1]) == 1
1986         && REGNO (operands[2]) == 2)
1987        || (REGNO (operands[0]) == 4
1988            && REGNO (operands[1]) == 5
1989            && REGNO (operands[2]) == 6))"
1990   "stm.l\\t%S0-%S2,@-er7"
1991   [(set_attr "cc" "none")
1992    (set_attr "length" "4")])
1994 (define_expand "stm_h8300s_3"
1995   [(use (match_operand:SI 0 "register_operand" ""))
1996    (use (match_operand:SI 1 "register_operand" ""))
1997    (use (match_operand:SI 2 "register_operand" ""))]
1998   "TARGET_H8300S
1999    && ((REGNO (operands[0]) == 0
2000         && REGNO (operands[1]) == 1
2001         && REGNO (operands[2]) == 2)
2002        || (REGNO (operands[0]) == 4
2003            && REGNO (operands[1]) == 5
2004            && REGNO (operands[2]) == 6))"
2005   "
2007   if (!TARGET_NORMAL_MODE)
2008     emit_insn (gen_stm_h8300s_3_advanced (operands[0], operands[1],
2009                                           operands[2]));
2010   else
2011     emit_insn (gen_stm_h8300s_3_normal (operands[0], operands[1],
2012                                         operands[2]));
2013   DONE;
2016 (define_insn "stm_h8300s_4_advanced"
2017   [(parallel
2018      [(set (reg:SI SP_REG)
2019            (plus:SI (reg:SI SP_REG) (const_int -16)))
2020       (set (mem:SI (plus:SI (reg:SI SP_REG) (const_int -4)))
2021            (match_operand:SI 0 "register_operand" ""))
2022       (set (mem:SI (plus:SI (reg:SI SP_REG) (const_int -8)))
2023            (match_operand:SI 1 "register_operand" ""))
2024       (set (mem:SI (plus:SI (reg:SI SP_REG) (const_int -12)))
2025            (match_operand:SI 2 "register_operand" ""))
2026       (set (mem:SI (plus:SI (reg:SI SP_REG) (const_int -16)))
2027            (match_operand:SI 3 "register_operand" ""))])]
2028   "TARGET_H8300S && !TARGET_NORMAL_MODE
2029    && REGNO (operands[0]) == 0
2030    && REGNO (operands[1]) == 1
2031    && REGNO (operands[2]) == 2
2032    && REGNO (operands[3]) == 3"
2033   "stm.l\\t%S0-%S3,@-er7"
2034   [(set_attr "cc" "none")
2035    (set_attr "length" "4")])
2037 (define_insn "stm_h8300s_4_normal"
2038   [(parallel
2039      [(set (reg:HI SP_REG)
2040            (plus:HI (reg:HI SP_REG) (const_int -16)))
2041       (set (mem:SI (plus:HI (reg:HI SP_REG) (const_int -4)))
2042            (match_operand:SI 0 "register_operand" ""))
2043       (set (mem:SI (plus:HI (reg:HI SP_REG) (const_int -8)))
2044            (match_operand:SI 1 "register_operand" ""))
2045       (set (mem:SI (plus:HI (reg:HI SP_REG) (const_int -12)))
2046            (match_operand:SI 2 "register_operand" ""))
2047       (set (mem:SI (plus:HI (reg:HI SP_REG) (const_int -16)))
2048            (match_operand:SI 3 "register_operand" ""))])]
2049   "TARGET_H8300S && TARGET_NORMAL_MODE
2050    && REGNO (operands[0]) == 0
2051    && REGNO (operands[1]) == 1
2052    && REGNO (operands[2]) == 2
2053    && REGNO (operands[3]) == 3"
2054   "stm.l\\t%S0-%S3,@-er7"
2055   [(set_attr "cc" "none")
2056    (set_attr "length" "4")])
2058 (define_expand "stm_h8300s_4"
2059   [(use (match_operand:SI 0 "register_operand" ""))
2060    (use (match_operand:SI 1 "register_operand" ""))
2061    (use (match_operand:SI 2 "register_operand" ""))
2062    (use (match_operand:SI 3 "register_operand" ""))]
2063   "TARGET_H8300S
2064    && REGNO (operands[0]) == 0
2065    && REGNO (operands[1]) == 1
2066    && REGNO (operands[2]) == 2
2067    && REGNO (operands[3]) == 3"
2068   "
2070   if (!TARGET_NORMAL_MODE)
2071     emit_insn (gen_stm_h8300s_4_advanced (operands[0], operands[1],
2072                                           operands[2], operands[3]));
2073   else
2074     emit_insn (gen_stm_h8300s_4_normal (operands[0], operands[1],
2075                                         operands[2], operands[3]));
2076   DONE;
2079 (define_insn "ldm_h8300s_2_advanced"
2080   [(parallel
2081      [(set (reg:SI SP_REG)
2082            (plus:SI (reg:SI SP_REG) (const_int 8)))
2083       (set (mem:SI (plus:SI (reg:SI SP_REG) (const_int 4)))
2084            (match_operand:SI 0 "register_operand" ""))
2085       (set (mem:SI (reg:SI SP_REG))
2086            (match_operand:SI 1 "register_operand" ""))])]
2087   "TARGET_H8300S && !TARGET_NORMAL_MODE
2088    && ((REGNO (operands[0]) == 0 && REGNO (operands[1]) == 1)
2089        || (REGNO (operands[0]) == 2 && REGNO (operands[1]) == 3)
2090        || (REGNO (operands[0]) == 4 && REGNO (operands[1]) == 5))"
2091   "ldm.l\\t@er7+,%S0-%S1"
2092   [(set_attr "cc" "none")
2093    (set_attr "length" "4")])
2095 (define_insn "ldm_h8300s_2_normal"
2096   [(parallel
2097      [(set (reg:HI SP_REG)
2098            (plus:HI (reg:HI SP_REG) (const_int 8)))
2099       (set (mem:SI (plus:HI (reg:HI SP_REG) (const_int 4)))
2100            (match_operand:SI 0 "register_operand" ""))
2101       (set (mem:SI (reg:HI SP_REG))
2102            (match_operand:SI 1 "register_operand" ""))])]
2103   "TARGET_H8300S && TARGET_NORMAL_MODE
2104    && ((REGNO (operands[0]) == 0 && REGNO (operands[1]) == 1)
2105        || (REGNO (operands[0]) == 2 && REGNO (operands[1]) == 3)
2106        || (REGNO (operands[0]) == 4 && REGNO (operands[1]) == 5))"
2107   "ldm.l\\t@er7+,%S0-%S1"
2108   [(set_attr "cc" "none")
2109    (set_attr "length" "4")])
2111 (define_expand "ldm_h8300s_2"
2112   [(use (match_operand:SI 0 "register_operand" ""))
2113    (use (match_operand:SI 1 "register_operand" ""))]
2114   "TARGET_H8300S
2115    && ((REGNO (operands[0]) == 0 && REGNO (operands[1]) == 1)
2116        || (REGNO (operands[0]) == 2 && REGNO (operands[1]) == 3)
2117        || (REGNO (operands[0]) == 4 && REGNO (operands[1]) == 5))"
2118   "
2120   if (!TARGET_NORMAL_MODE)
2121     emit_insn (gen_ldm_h8300s_2_advanced (operands[0], operands[1]));
2122   else
2123     emit_insn (gen_ldm_h8300s_2_normal (operands[0], operands[1]));
2124   DONE;
2127 (define_insn "ldm_h8300s_3_advanced"
2128   [(parallel
2129      [(set (reg:SI SP_REG)
2130            (plus:SI (reg:SI SP_REG) (const_int 12)))
2131       (set (mem:SI (plus:SI (reg:SI SP_REG) (const_int 8)))
2132            (match_operand:SI 0 "register_operand" ""))
2133       (set (mem:SI (plus:SI (reg:SI SP_REG) (const_int 4)))
2134            (match_operand:SI 1 "register_operand" ""))
2135       (set (mem:SI (reg:SI SP_REG))
2136            (match_operand:SI 2 "register_operand" ""))])]
2137   "TARGET_H8300S && !TARGET_NORMAL_MODE
2138    && ((REGNO (operands[0]) == 0
2139         && REGNO (operands[1]) == 1
2140         && REGNO (operands[2]) == 2)
2141        || (REGNO (operands[0]) == 4
2142            && REGNO (operands[1]) == 5
2143            && REGNO (operands[2]) == 6))"
2144   "ldm.l\\t@er7+,%S0-%S2"
2145   [(set_attr "cc" "none")
2146    (set_attr "length" "4")])
2148 (define_insn "ldm_h8300s_3_normal"
2149   [(parallel
2150      [(set (reg:HI SP_REG)
2151            (plus:HI (reg:HI SP_REG) (const_int 12)))
2152       (set (mem:SI (plus:HI (reg:HI SP_REG) (const_int 8)))
2153            (match_operand:SI 0 "register_operand" ""))
2154       (set (mem:SI (plus:HI (reg:HI SP_REG) (const_int 4)))
2155            (match_operand:SI 1 "register_operand" ""))
2156       (set (mem:SI (reg:HI SP_REG))
2157            (match_operand:SI 2 "register_operand" ""))])]
2158   "TARGET_H8300S && TARGET_NORMAL_MODE
2159    && ((REGNO (operands[0]) == 0
2160         && REGNO (operands[1]) == 1
2161         && REGNO (operands[2]) == 2)
2162        || (REGNO (operands[0]) == 4
2163            && REGNO (operands[1]) == 5
2164            && REGNO (operands[2]) == 6))"
2165   "ldm.l\\t@er7+,%S0-%S2"
2166   [(set_attr "cc" "none")
2167    (set_attr "length" "4")])
2169 (define_expand "ldm_h8300s_3"
2170   [(use (match_operand:SI 0 "register_operand" ""))
2171    (use (match_operand:SI 1 "register_operand" ""))
2172    (use (match_operand:SI 2 "register_operand" ""))]
2173   "TARGET_H8300S
2174    && ((REGNO (operands[0]) == 0
2175         && REGNO (operands[1]) == 1
2176         && REGNO (operands[2]) == 2)
2177        || (REGNO (operands[0]) == 4
2178            && REGNO (operands[1]) == 5
2179            && REGNO (operands[2]) == 6))"
2180   "
2182   if (!TARGET_NORMAL_MODE)
2183     emit_insn (gen_ldm_h8300s_3_advanced (operands[0], operands[1],
2184                                           operands[2]));
2185   else
2186     emit_insn (gen_ldm_h8300s_3_normal (operands[0], operands[1],
2187                                         operands[2]));
2188   DONE;
2191 (define_insn "ldm_h8300s_4_advanced"
2192   [(parallel
2193      [(set (reg:SI SP_REG)
2194            (plus:SI (reg:SI SP_REG) (const_int 16)))
2195       (set (mem:SI (plus:SI (reg:SI SP_REG) (const_int 12)))
2196            (match_operand:SI 0 "register_operand" ""))
2197       (set (mem:SI (plus:SI (reg:SI SP_REG) (const_int 8)))
2198            (match_operand:SI 1 "register_operand" ""))
2199       (set (mem:SI (plus:SI (reg:SI SP_REG) (const_int 4)))
2200            (match_operand:SI 2 "register_operand" ""))
2201       (set (mem:SI (reg:SI SP_REG))
2202            (match_operand:SI 3 "register_operand" ""))])]
2203   "TARGET_H8300S && !TARGET_NORMAL_MODE
2204    && REGNO (operands[0]) == 0
2205    && REGNO (operands[1]) == 1
2206    && REGNO (operands[2]) == 2
2207    && REGNO (operands[3]) == 3"
2208   "ldm.l\\t@er7+,%S0-%S3"
2209   [(set_attr "cc" "none")
2210    (set_attr "length" "4")])
2212 (define_insn "ldm_h8300s_4_normal"
2213   [(parallel
2214      [(set (reg:HI SP_REG)
2215            (plus:HI (reg:HI SP_REG) (const_int 16)))
2216       (set (mem:SI (plus:HI (reg:HI SP_REG) (const_int 12)))
2217            (match_operand:SI 0 "register_operand" ""))
2218       (set (mem:SI (plus:HI (reg:HI SP_REG) (const_int 8)))
2219            (match_operand:SI 1 "register_operand" ""))
2220       (set (mem:SI (plus:HI (reg:HI SP_REG) (const_int 4)))
2221            (match_operand:SI 2 "register_operand" ""))
2222       (set (mem:SI (reg:HI SP_REG))
2223            (match_operand:SI 3 "register_operand" ""))])]
2224   "TARGET_H8300S && !TARGET_NORMAL_MODE
2225    && REGNO (operands[0]) == 0
2226    && REGNO (operands[1]) == 1
2227    && REGNO (operands[2]) == 2
2228    && REGNO (operands[3]) == 3"
2229   "ldm.l\\t@er7+,%S0-%S3"
2230   [(set_attr "cc" "none")
2231    (set_attr "length" "4")])
2233 (define_expand "ldm_h8300s_4"
2234   [(use (match_operand:SI 0 "register_operand" ""))
2235    (use (match_operand:SI 1 "register_operand" ""))
2236    (use (match_operand:SI 2 "register_operand" ""))
2237    (use (match_operand:SI 3 "register_operand" ""))]
2238   "TARGET_H8300S && !TARGET_NORMAL_MODE
2239    && REGNO (operands[0]) == 0
2240    && REGNO (operands[1]) == 1
2241    && REGNO (operands[2]) == 2
2242    && REGNO (operands[3]) == 3"
2243   "
2245   if (!TARGET_NORMAL_MODE)
2246     emit_insn (gen_ldm_h8300s_4_advanced (operands[0], operands[1],
2247                                           operands[2], operands[3]));
2248   else
2249     emit_insn (gen_ldm_h8300s_4_normal (operands[0], operands[1],
2250                                         operands[2], operands[3]));
2251   DONE;
2254 (define_expand "return"
2255   [(return)]
2256   "h8300_can_use_return_insn_p ()"
2257   "")
2259 (define_insn "*return_1"
2260   [(return)]
2261   "reload_completed"
2262   "*
2264   if (h8300_current_function_interrupt_function_p ())
2265     return \"rte\";
2266   else
2267     return \"rts\";
2269   [(set_attr "cc" "none")
2270    (set_attr "length" "2")])
2272 (define_expand "prologue"
2273   [(const_int 0)]
2274   ""
2275   "h8300_expand_prologue (); DONE;")
2277 (define_expand "epilogue"
2278   [(return)]
2279   ""
2280   "h8300_expand_epilogue ();")
2282 (define_insn "monitor_prologue"
2283   [(unspec_volatile [(const_int 0)] UNSPEC_MONITOR)]
2284   ""
2285   "*
2287   if (TARGET_H8300)
2288     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\";
2289   else if (TARGET_H8300H)
2290     return \"mov.l\\ter0,@-er7\;stc\\tccr,r0l\;mov.b\\tr0l,@(4,er7)\;mov.l\\t@er7+,er0\;orc\\t#128,ccr\";
2291   else if (TARGET_H8300S)
2292     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\";
2293     abort ();
2295   [(set_attr "length" "20")
2296    (set_attr "cc" "clobber")])
2298 ;; ----------------------------------------------------------------------
2299 ;; EXTEND INSTRUCTIONS
2300 ;; ----------------------------------------------------------------------
2302 (define_expand "zero_extendqihi2"
2303   [(set (match_operand:HI 0 "register_operand" "")
2304         (zero_extend:HI (match_operand:QI 1 "general_operand_src" "")))]
2305   ""
2306   "")
2308 (define_insn "*zero_extendqihi2_h8300"
2309   [(set (match_operand:HI 0 "register_operand" "=r,r")
2310         (zero_extend:HI (match_operand:QI 1 "general_operand_src" "0,g>")))]
2311   "TARGET_H8300"
2312   "@
2313   mov.b #0,%t0
2314   #"
2315   [(set_attr "length" "2,10")
2316    (set_attr "cc" "clobber,clobber")])
2318 (define_insn "*zero_extendqihi2_h8300hs"
2319   [(set (match_operand:HI 0 "register_operand" "=r,r")
2320         (zero_extend:HI (match_operand:QI 1 "general_operand_src" "0,g>")))]
2321   "TARGET_H8300H || TARGET_H8300S"
2322   "@
2323   extu.w        %T0
2324   #"
2325   [(set_attr "length" "2,10")
2326    (set_attr "cc" "set_znv,set_znv")])
2328 ;; Split the zero extension of a general operand (actually a memory
2329 ;; operand) into a load of the operand and the actual zero extension
2330 ;; so that 1) the length will be accurate, and 2) the zero extensions
2331 ;; appearing at the end of basic blocks may be merged.
2333 (define_split
2334   [(set (match_operand:HI 0 "register_operand" "")
2335         (zero_extend:HI (match_operand:QI 1 "general_operand_src" "")))]
2336   "reload_completed"
2337   [(set (match_dup 2)
2338         (match_dup 1))
2339    (set (match_dup 0)
2340         (zero_extend:HI (match_dup 2)))]
2341   "operands[2] = gen_rtx_REG (QImode, REGNO (operands[0]));")
2343 (define_expand "zero_extendqisi2"
2344   [(set (match_operand:SI 0 "register_operand" "")
2345         (zero_extend:SI (match_operand:QI 1 "general_operand_src" "")))]
2346   ""
2347   "")
2349 (define_insn "*zero_extendqisi2_h8300"
2350   [(set (match_operand:SI 0 "register_operand" "=r,r")
2351         (zero_extend:SI (match_operand:QI 1 "general_operand_src" "0,g>")))]
2352   "TARGET_H8300"
2353   "@
2354   mov.b #0,%x0\;sub.w   %e0,%e0
2355   mov.b %R1,%w0\;mov.b  #0,%x0\;sub.w   %e0,%e0"
2356   [(set_attr "length" "4,8")
2357    (set_attr "cc" "clobber,clobber")])
2359 (define_insn "*zero_extendqisi2_h8300hs"
2360   [(set (match_operand:SI 0 "register_operand" "=r,r")
2361         (zero_extend:SI (match_operand:QI 1 "general_operand_src" "0,g>")))]
2362   "TARGET_H8300H || TARGET_H8300S"
2363   "#")
2365 (define_split
2366   [(set (match_operand:SI 0 "register_operand" "")
2367         (zero_extend:SI (match_operand:QI 1 "general_operand_src" "")))]
2368   "(TARGET_H8300H || TARGET_H8300S)
2369    && reg_overlap_mentioned_p (operands[0], operands[1])
2370    && reload_completed"
2371   [(set (match_dup 2)
2372         (match_dup 1))
2373    (set (match_dup 3)
2374         (zero_extend:HI (match_dup 2)))
2375    (set (match_dup 0)
2376         (zero_extend:SI (match_dup 3)))]
2377   "operands[2] = gen_lowpart (QImode, operands[0]);
2378    operands[3] = gen_lowpart (HImode, operands[0]);")
2380 (define_split
2381   [(set (match_operand:SI 0 "register_operand" "")
2382         (zero_extend:SI (match_operand:QI 1 "general_operand_src" "")))]
2383   "(TARGET_H8300H || TARGET_H8300S)
2384    && !reg_overlap_mentioned_p (operands[0], operands[1])
2385    && reload_completed"
2386   [(set (match_dup 0)
2387         (const_int 0))
2388    (set (strict_low_part (match_dup 2))
2389         (match_dup 1))]
2390   "operands[2] = gen_rtx_REG (QImode, REGNO (operands[0]));")
2392 (define_expand "zero_extendhisi2"
2393   [(set (match_operand:SI 0 "register_operand" "")
2394         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
2395   ""
2396   "")
2398 ;; %e prints the high part of a CONST_INT, not the low part.  Arggh.
2399 (define_insn "*zero_extendhisi2_h8300"
2400   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
2401         (zero_extend:SI (match_operand:HI 1 "general_operand_src" "0,i,g>")))]
2402   "TARGET_H8300"
2403   "@
2404   sub.w %e0,%e0
2405   mov.w %f1,%f0\;sub.w  %e0,%e0
2406   mov.w %e1,%f0\;sub.w  %e0,%e0"
2407   [(set_attr "length" "2,4,6")
2408    (set_attr "cc" "clobber,clobber,clobber")])
2410 (define_insn "*zero_extendhisi2_h8300hs"
2411   [(set (match_operand:SI 0 "register_operand" "=r")
2412         (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))]
2413   "TARGET_H8300H || TARGET_H8300S"
2414   "extu.l       %S0"
2415   [(set_attr "length" "2")
2416    (set_attr "cc" "set_znv")])
2418 (define_expand "extendqihi2"
2419   [(set (match_operand:HI 0 "register_operand" "")
2420         (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
2421   ""
2422   "")
2424 (define_insn "*extendqihi2_h8300"
2425   [(set (match_operand:HI 0 "register_operand" "=r,r")
2426         (sign_extend:HI (match_operand:QI 1 "general_operand_src" "0,g>")))]
2427   "TARGET_H8300"
2428   "@
2429   bld   #7,%s0\;subx    %t0,%t0
2430   mov.b %R1,%s0\;bld    #7,%s0\;subx    %t0,%t0"
2431   [(set_attr "length" "4,8")
2432    (set_attr "cc" "clobber,clobber")])
2434 (define_insn "*extendqihi2_h8300hs"
2435   [(set (match_operand:HI 0 "register_operand" "=r")
2436         (sign_extend:HI (match_operand:QI 1 "register_operand" "0")))]
2437   "TARGET_H8300H || TARGET_H8300S"
2438   "exts.w       %T0"
2439   [(set_attr "length" "2")
2440    (set_attr "cc" "set_znv")])
2442 (define_expand "extendqisi2"
2443   [(set (match_operand:SI 0 "register_operand" "")
2444         (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
2445   ""
2446   "")
2448 (define_insn "*extendqisi2_h8300"
2449   [(set (match_operand:SI 0 "register_operand" "")
2450         (sign_extend:SI (match_operand:QI 1 "general_operand_src" "0,g>")))]
2451   "TARGET_H8300"
2452   "@
2453   bld   #7,%w0\;subx    %x0,%x0\;subx   %y0,%y0\;subx   %z0,%z0
2454   mov.b %R1,%w0\;bld    #7,%w0\;subx    %x0,%x0\;subx   %y0,%y0\;subx   %z0,%z0"
2455   [(set_attr "length" "8,12")
2456    (set_attr "cc" "clobber,clobber")])
2458 ;; The following pattern is needed because without the pattern, the
2459 ;; combiner would split (sign_extend:SI (reg:QI)) into into two 24-bit
2460 ;; shifts, one ashift and one ashiftrt.
2462 (define_insn_and_split "*extendqisi2_h8300hs"
2463   [(set (match_operand:SI 0 "register_operand" "=r")
2464         (sign_extend:SI (match_operand:QI 1 "register_operand" "0")))]
2465   "(TARGET_H8300H || TARGET_H8300S)"
2466   "#"
2467   "&& reload_completed"
2468   [(set (match_dup 2)
2469         (sign_extend:HI (match_dup 1)))
2470    (set (match_dup 0)
2471         (sign_extend:SI (match_dup 2)))]
2472   "operands[2] = gen_rtx_REG (HImode, REGNO (operands[0]));")
2474 (define_expand "extendhisi2"
2475   [(set (match_operand:SI 0 "register_operand" "")
2476         (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
2477   ""
2478   "")
2480 (define_insn "*extendhisi2_h8300"
2481   [(set (match_operand:SI 0 "register_operand" "=r,r")
2482         (sign_extend:SI (match_operand:HI 1 "general_operand_src" "0,g>")))]
2483   "TARGET_H8300"
2484   "@
2485   bld   #7,%x0\;subx    %y0,%y0\;subx   %z0,%z0
2486   mov.w %T1,%f0\;bld    #7,%x0\;subx    %y0,%y0\;subx   %z0,%z0"
2487   [(set_attr "length" "6,10")
2488    (set_attr "cc" "clobber,clobber")])
2490 (define_insn "*extendhisi2_h8300hs"
2491   [(set (match_operand:SI 0 "register_operand" "=r")
2492         (sign_extend:SI (match_operand:HI 1 "register_operand" "0")))]
2493   "TARGET_H8300H || TARGET_H8300S"
2494   "exts.l       %S0"
2495   [(set_attr "length" "2")
2496    (set_attr "cc" "set_znv")])
2498 ;; ----------------------------------------------------------------------
2499 ;; SHIFTS
2500 ;; ----------------------------------------------------------------------
2502 ;; We make some attempt to provide real efficient shifting.  One example is
2503 ;; doing an 8 bit shift of a 16 bit value by moving a byte reg into the other
2504 ;; reg and moving 0 into the former reg.
2506 ;; We also try to achieve this in a uniform way.  IE: We don't try to achieve
2507 ;; this in both rtl and at insn emit time.  Ideally, we'd use rtl as that would
2508 ;; give the optimizer more cracks at the code.  However, we wish to do things
2509 ;; like optimizing shifting the sign bit to bit 0 by rotating the other way.
2510 ;; There is rtl to handle this (rotate + and), but the H8/300 doesn't handle
2511 ;; 16 bit rotates.  Also, if we emit complicated rtl, combine may not be able
2512 ;; to detect cases it can optimize.
2514 ;; For these and other fuzzy reasons, I've decided to go the less pretty but
2515 ;; easier "do it at insn emit time" route.
2517 ;; QI BIT SHIFTS
2519 (define_expand "ashlqi3"
2520   [(set (match_operand:QI 0 "register_operand" "")
2521         (ashift:QI (match_operand:QI 1 "register_operand" "")
2522                    (match_operand:QI 2 "nonmemory_operand" "")))]
2523   ""
2524   "expand_a_shift (QImode, ASHIFT, operands); DONE;")
2526 (define_expand "ashrqi3"
2527   [(set (match_operand:QI 0 "register_operand" "")
2528         (ashiftrt:QI (match_operand:QI 1 "register_operand" "")
2529                      (match_operand:QI 2 "nonmemory_operand" "")))]
2530   ""
2531   "expand_a_shift (QImode, ASHIFTRT, operands); DONE;")
2533 (define_expand "lshrqi3"
2534   [(set (match_operand:QI 0 "register_operand" "")
2535         (lshiftrt:QI (match_operand:QI 1 "register_operand" "")
2536                      (match_operand:QI 2 "nonmemory_operand" "")))]
2537   ""
2538   "expand_a_shift (QImode, LSHIFTRT, operands); DONE;")
2540 (define_insn "*shiftqi"
2541   [(set (match_operand:QI 0 "register_operand" "=r,r")
2542         (match_operator:QI 3 "nshift_operator"
2543                         [ (match_operand:QI 1 "register_operand" "0,0")
2544                           (match_operand:QI 2 "nonmemory_operand" "R,rn")]))
2545    (clobber (match_scratch:QI 4 "=X,&r"))]
2546   ""
2547   "* return output_a_shift (operands);"
2548   [(set (attr "length")
2549         (symbol_ref "compute_a_shift_length (insn, operands)"))
2550    (set (attr "cc")
2551         (symbol_ref "compute_a_shift_cc (insn, operands)"))])
2553 ;; HI BIT SHIFTS
2555 (define_expand "ashlhi3"
2556   [(set (match_operand:HI 0 "register_operand" "")
2557         (ashift:HI (match_operand:HI 1 "nonmemory_operand" "")
2558                    (match_operand:QI 2 "nonmemory_operand" "")))]
2559   ""
2560   "expand_a_shift (HImode, ASHIFT, operands); DONE;")
2562 (define_expand "lshrhi3"
2563   [(set (match_operand:HI 0 "register_operand" "")
2564         (lshiftrt:HI (match_operand:HI 1 "general_operand" "")
2565                      (match_operand:QI 2 "nonmemory_operand" "")))]
2566   ""
2567   "expand_a_shift (HImode, LSHIFTRT, operands); DONE;")
2569 (define_expand "ashrhi3"
2570   [(set (match_operand:HI 0 "register_operand" "")
2571         (ashiftrt:HI (match_operand:HI 1 "register_operand" "")
2572                      (match_operand:QI 2 "nonmemory_operand" "")))]
2573   ""
2574   "expand_a_shift (HImode, ASHIFTRT, operands); DONE;")
2576 (define_insn "*shifthi"
2577   [(set (match_operand:HI 0 "register_operand" "=r,r")
2578         (match_operator:HI 3 "nshift_operator"
2579                         [ (match_operand:HI 1 "register_operand" "0,0")
2580                           (match_operand:QI 2 "nonmemory_operand" "S,rn")]))
2581    (clobber (match_scratch:QI 4 "=X,&r"))]
2582   ""
2583   "* return output_a_shift (operands);"
2584   [(set (attr "length")
2585         (symbol_ref "compute_a_shift_length (insn, operands)"))
2586    (set (attr "cc")
2587         (symbol_ref "compute_a_shift_cc (insn, operands)"))])
2589 ;;  SI BIT SHIFTS
2591 (define_expand "ashlsi3"
2592   [(set (match_operand:SI 0 "register_operand" "")
2593         (ashift:SI (match_operand:SI 1 "general_operand" "")
2594                    (match_operand:QI 2 "nonmemory_operand" "")))]
2595   ""
2596   "expand_a_shift (SImode, ASHIFT, operands); DONE;")
2598 (define_expand "lshrsi3"
2599   [(set (match_operand:SI 0 "register_operand" "")
2600         (lshiftrt:SI (match_operand:SI 1 "general_operand" "")
2601                      (match_operand:QI 2 "nonmemory_operand" "")))]
2602   ""
2603   "expand_a_shift (SImode, LSHIFTRT, operands); DONE;")
2605 (define_expand "ashrsi3"
2606   [(set (match_operand:SI 0 "register_operand" "")
2607         (ashiftrt:SI (match_operand:SI 1 "general_operand" "")
2608                      (match_operand:QI 2 "nonmemory_operand" "")))]
2609   ""
2610   "expand_a_shift (SImode, ASHIFTRT, operands); DONE;")
2612 (define_insn "*shiftsi"
2613   [(set (match_operand:SI 0 "register_operand" "=r,r")
2614         (match_operator:SI 3 "nshift_operator"
2615                         [ (match_operand:SI 1 "register_operand" "0,0")
2616                           (match_operand:QI 2 "nonmemory_operand" "T,rn")]))
2617    (clobber (match_scratch:QI 4 "=X,&r"))]
2618   ""
2619   "* return output_a_shift (operands);"
2620   [(set (attr "length")
2621         (symbol_ref "compute_a_shift_length (insn, operands)"))
2622    (set (attr "cc")
2623         (symbol_ref "compute_a_shift_cc (insn, operands)"))])
2625 ;; Split a variable shift into a loop.  If the register containing
2626 ;; the shift count dies, then we just use that register.
2628 (define_split
2629   [(parallel
2630      [(set (match_operand 0 "register_operand" "")
2631            (match_operator 2 "nshift_operator"
2632              [(match_dup 0)
2633               (match_operand:QI 1 "register_operand" "")]))
2634       (clobber (match_operand:QI 3 "register_operand" ""))])]
2635   "flow2_completed
2636    && find_regno_note (insn, REG_DEAD, REGNO (operands[1]))"
2637   [(set (cc0)
2638         (match_dup 1))
2639    (set (pc)
2640         (if_then_else (le (cc0) (const_int 0))
2641                       (label_ref (match_dup 5))
2642                       (pc)))
2643    (match_dup 4)
2644    (parallel
2645      [(set (match_dup 0)
2646            (match_op_dup 2 [(match_dup 0) (const_int 1)]))
2647       (clobber (scratch:QI))])
2648    (set (match_dup 1)
2649         (plus:QI (match_dup 1) (const_int -1)))
2650    (set (cc0)
2651         (match_dup 1))
2652    (set (pc)
2653         (if_then_else (ne (cc0) (const_int 0))
2654                       (label_ref (match_dup 4))
2655                       (pc)))
2656    (match_dup 5)]
2657   "operands[4] = gen_label_rtx ();
2658    operands[5] = gen_label_rtx ();")
2660 (define_split
2661   [(parallel
2662      [(set (match_operand 0 "register_operand" "")
2663            (match_operator 2 "nshift_operator"
2664              [(match_dup 0)
2665               (match_operand:QI 1 "register_operand" "")]))
2666       (clobber (match_operand:QI 3 "register_operand" ""))])]
2667   "flow2_completed
2668    && !find_regno_note (insn, REG_DEAD, REGNO (operands[1]))"
2669   [(set (match_dup 3)
2670         (match_dup 1))
2671    (set (cc0)
2672         (match_dup 3))
2673    (set (pc)
2674         (if_then_else (le (cc0) (const_int 0))
2675                       (label_ref (match_dup 5))
2676                       (pc)))
2677    (match_dup 4)
2678    (parallel
2679      [(set (match_dup 0)
2680            (match_op_dup 2 [(match_dup 0) (const_int 1)]))
2681       (clobber (scratch:QI))])
2682    (set (match_dup 3)
2683         (plus:QI (match_dup 3) (const_int -1)))
2684    (set (cc0)
2685         (match_dup 3))
2686    (set (pc)
2687         (if_then_else (ne (cc0) (const_int 0))
2688                       (label_ref (match_dup 4))
2689                       (pc)))
2690    (match_dup 5)]
2691   "operands[4] = gen_label_rtx ();
2692    operands[5] = gen_label_rtx ();")
2694 ;; ----------------------------------------------------------------------
2695 ;; ROTATIONS
2696 ;; ----------------------------------------------------------------------
2698 (define_expand "rotlqi3"
2699   [(set (match_operand:QI 0 "register_operand" "")
2700         (rotate:QI (match_operand:QI 1 "register_operand" "")
2701                    (match_operand:QI 2 "nonmemory_operand" "")))]
2702   ""
2703   "if (expand_a_rotate (ROTATE, operands)) DONE; else FAIL;")
2705 (define_insn "*rotlqi3_1"
2706   [(set (match_operand:QI 0 "register_operand" "=r")
2707         (rotate:QI (match_operand:QI 1 "register_operand" "0")
2708                    (match_operand:QI 2 "immediate_operand" "")))]
2709   ""
2710   "* return output_a_rotate (ROTATE, operands);"
2711   [(set (attr "length")
2712         (symbol_ref "compute_a_rotate_length (operands)"))
2713    (set_attr "cc" "clobber")])
2715 (define_expand "rotlhi3"
2716   [(set (match_operand:HI 0 "register_operand" "")
2717         (rotate:HI (match_operand:HI 1 "register_operand" "")
2718                    (match_operand:QI 2 "nonmemory_operand" "")))]
2719   ""
2720   "if (expand_a_rotate (ROTATE, operands)) DONE; else FAIL;")
2722 (define_insn "*rotlhi3_1"
2723   [(set (match_operand:HI 0 "register_operand" "=r")
2724         (rotate:HI (match_operand:HI 1 "register_operand" "0")
2725                    (match_operand:QI 2 "immediate_operand" "")))]
2726   ""
2727   "* return output_a_rotate (ROTATE, operands);"
2728   [(set (attr "length")
2729         (symbol_ref "compute_a_rotate_length (operands)"))
2730    (set_attr "cc" "clobber")])
2732 (define_expand "rotlsi3"
2733   [(set (match_operand:SI 0 "register_operand" "")
2734         (rotate:SI (match_operand:SI 1 "register_operand" "")
2735                    (match_operand:QI 2 "nonmemory_operand" "")))]
2736   "TARGET_H8300H || TARGET_H8300S"
2737   "if (expand_a_rotate (ROTATE, operands)) DONE; else FAIL;")
2739 (define_insn "*rotlsi3_1"
2740   [(set (match_operand:SI 0 "register_operand" "=r")
2741         (rotate:SI (match_operand:SI 1 "register_operand" "0")
2742                    (match_operand:QI 2 "immediate_operand" "")))]
2743   "TARGET_H8300H || TARGET_H8300S"
2744   "* return output_a_rotate (ROTATE, operands);"
2745   [(set (attr "length")
2746         (symbol_ref "compute_a_rotate_length (operands)"))
2747    (set_attr "cc" "clobber")])
2749 ;; -----------------------------------------------------------------
2750 ;; BIT FIELDS
2751 ;; -----------------------------------------------------------------
2752 ;; The H8/300 has given 1/8th of its opcode space to bitfield
2753 ;; instructions so let's use them as well as we can.
2755 ;; You'll never believe all these patterns perform one basic action --
2756 ;; load a bit from the source, optionally invert the bit, then store it
2757 ;; in the destination (which is known to be zero).
2759 ;; Combine obviously need some work to better identify this situation and
2760 ;; canonicalize the form better.
2763 ;; Normal loads with a 16bit destination.
2766 (define_insn ""
2767   [(set (match_operand:HI 0 "register_operand" "=&r")
2768         (zero_extract:HI (match_operand:HI 1 "register_operand" "r")
2769                          (const_int 1)
2770                          (match_operand:HI 2 "immediate_operand" "n")))]
2771   "TARGET_H8300"
2772   "sub.w        %0,%0\;bld      %Z2,%Y1\;bst    #0,%X0"
2773   [(set_attr "cc" "clobber")
2774    (set_attr "length" "6")])
2777 ;; Inverted loads with a 16bit destination.
2780 (define_insn ""
2781   [(set (match_operand:HI 0 "register_operand" "=&r")
2782         (zero_extract:HI (xor:HI (match_operand:HI 1 "register_operand" "r")
2783                                  (match_operand:HI 3 "const_int_operand" "n"))
2784                          (const_int 1)
2785                          (match_operand:HI 2 "const_int_operand" "n")))]
2786   "TARGET_H8300
2787    && (1 << INTVAL (operands[2])) == INTVAL (operands[3])"
2788   "sub.w        %0,%0\;bild     %Z2,%Y1\;bst    #0,%X0"
2789   [(set_attr "cc" "clobber")
2790    (set_attr "length" "8")])
2793 ;; Normal loads with a 32bit destination.
2796 (define_insn "*extzv_1_r_h8300"
2797   [(set (match_operand:SI 0 "register_operand" "=&r")
2798         (zero_extract:SI (match_operand:HI 1 "register_operand" "r")
2799                          (const_int 1)
2800                          (match_operand 2 "const_int_operand" "n")))]
2801   "TARGET_H8300
2802    && INTVAL (operands[2]) < 16"
2803   "* return output_simode_bld (0, operands);"
2804   [(set_attr "cc" "clobber")
2805    (set_attr "length" "8")])
2807 (define_insn "*extzv_1_r_h8300hs"
2808   [(set (match_operand:SI 0 "register_operand" "=r,r")
2809         (zero_extract:SI (match_operand:SI 1 "register_operand" "?0,r")
2810                          (const_int 1)
2811                          (match_operand 2 "const_int_operand" "n,n")))]
2812   "(TARGET_H8300H || TARGET_H8300S)
2813    && INTVAL (operands[2]) < 16"
2814   "* return output_simode_bld (0, operands);"
2815   [(set_attr "cc" "set_znv,set_znv")
2816    (set_attr "length" "8,6")])
2819 ;; Inverted loads with a 32bit destination.
2822 (define_insn "*extzv_1_r_inv_h8300"
2823   [(set (match_operand:SI 0 "register_operand" "=&r")
2824         (zero_extract:SI (xor:HI (match_operand:HI 1 "register_operand" "r")
2825                                  (match_operand:HI 3 "const_int_operand" "n"))
2826                          (const_int 1)
2827                          (match_operand 2 "const_int_operand" "n")))]
2828   "TARGET_H8300
2829    && INTVAL (operands[2]) < 16
2830    && (1 << INTVAL (operands[2])) == INTVAL (operands[3])"
2831   "* return output_simode_bld (1, operands);"
2832   [(set_attr "cc" "clobber")
2833    (set_attr "length" "8")])
2835 (define_insn "*extzv_1_r_inv_h8300hs"
2836   [(set (match_operand:SI 0 "register_operand" "=r,r")
2837         (zero_extract:SI (xor:SI (match_operand:SI 1 "register_operand" "?0,r")
2838                                  (match_operand 3 "const_int_operand" "n,n"))
2839                          (const_int 1)
2840                          (match_operand 2 "const_int_operand" "n,n")))]
2841   "(TARGET_H8300H || TARGET_H8300S)
2842    && INTVAL (operands[2]) < 16
2843    && (1 << INTVAL (operands[2])) == INTVAL (operands[3])"
2844   "* return output_simode_bld (1, operands);"
2845   [(set_attr "cc" "set_znv,set_znv")
2846    (set_attr "length" "8,6")])
2848 (define_expand "insv"
2849   [(set (zero_extract:HI (match_operand:HI 0 "general_operand" "")
2850                          (match_operand:HI 1 "general_operand" "")
2851                          (match_operand:HI 2 "general_operand" ""))
2852         (match_operand:HI 3 "general_operand" ""))]
2853   "TARGET_H8300"
2854   "
2856   /* We only have single bit bit-field instructions.  */
2857   if (INTVAL (operands[1]) != 1)
2858     FAIL;
2860   /* For now, we don't allow memory operands.  */
2861   if (GET_CODE (operands[0]) == MEM
2862       || GET_CODE (operands[3]) == MEM)
2863     FAIL;
2866 (define_insn ""
2867   [(set (zero_extract:HI (match_operand:HI 0 "register_operand" "+r")
2868                          (const_int 1)
2869                          (match_operand:HI 1 "immediate_operand" "n"))
2870         (match_operand:HI 2 "register_operand" "r"))]
2871   ""
2872   "bld  #0,%R2\;bst     %Z1,%Y0 ; i1"
2873   [(set_attr "cc" "clobber")
2874    (set_attr "length" "4")])
2876 (define_expand "extzv"
2877   [(set (match_operand:HI 0 "register_operand" "")
2878         (zero_extract:HI (match_operand:HI 1 "bit_operand" "")
2879                          (match_operand:HI 2 "general_operand" "")
2880                          (match_operand:HI 3 "general_operand" "")))]
2881   "TARGET_H8300"
2882   "
2884   /* We only have single bit bit-field instructions.  */
2885   if (INTVAL (operands[2]) != 1)
2886     FAIL;
2888   /* For now, we don't allow memory operands.  */
2889   if (GET_CODE (operands[1]) == MEM)
2890     FAIL;
2893 ;; BAND, BOR, and BXOR patterns
2895 (define_insn ""
2896   [(set (match_operand:HI 0 "bit_operand" "=Ur")
2897         (match_operator:HI 4 "bit_operator"
2898            [(zero_extract:HI (match_operand:HI 1 "register_operand" "r")
2899                              (const_int 1)
2900                              (match_operand:HI 2 "immediate_operand" "n"))
2901             (match_operand:HI 3 "bit_operand" "0")]))]
2902   ""
2903   "bld  %Z2,%Y1\;b%c4   #0,%R0\;bst     #0,%R0; bl1"
2904   [(set_attr "cc" "clobber")
2905    (set_attr "length" "6")])
2907 (define_insn ""
2908   [(set (match_operand:HI 0 "bit_operand" "=Ur")
2909         (match_operator:HI 5 "bit_operator"
2910            [(zero_extract:HI (match_operand:HI 1 "register_operand" "r")
2911                              (const_int 1)
2912                              (match_operand:HI 2 "immediate_operand" "n"))
2913             (zero_extract:HI (match_operand:HI 3 "register_operand" "r")
2914                              (const_int 1)
2915                              (match_operand:HI 4 "immediate_operand" "n"))]))]
2916   ""
2917   "bld  %Z2,%Y1\;b%c5   %Z4,%Y3\;bst    #0,%R0; bl3"
2918   [(set_attr "cc" "clobber")
2919    (set_attr "length" "6")])
2921 ;; -----------------------------------------------------------------
2922 ;; COMBINE PATTERNS
2923 ;; -----------------------------------------------------------------
2925 ;; insv:SI
2927 (define_insn "*insv_si_1_n"
2928   [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
2929                          (const_int 1)
2930                          (match_operand:SI 1 "const_int_operand" "n"))
2931         (match_operand:SI 2 "register_operand" "r"))]
2932   "(TARGET_H8300H || TARGET_H8300S)
2933    && INTVAL (operands[1]) < 16"
2934   "bld\\t#0,%w2\;bst\\t%Z1,%Y0"
2935   [(set_attr "cc" "clobber")
2936    (set_attr "length" "4")])
2938 (define_insn "*insv_si_1_n_lshiftrt"
2939   [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
2940                          (const_int 1)
2941                          (match_operand:SI 1 "const_int_operand" "n"))
2942         (lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
2943                      (match_operand:SI 3 "const_int_operand" "n")))]
2944   "(TARGET_H8300H || TARGET_H8300S)
2945    && INTVAL (operands[1]) < 16
2946    && INTVAL (operands[3]) < 16"
2947   "bld\\t%Z3,%Y2\;bst\\t%Z1,%Y0"
2948   [(set_attr "cc" "clobber")
2949    (set_attr "length" "4")])
2951 (define_insn "*insv_si_1_n_lshiftrt_16"
2952   [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
2953                          (const_int 1)
2954                          (match_operand:SI 1 "const_int_operand" "n"))
2955         (lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
2956                      (const_int 16)))]
2957   "(TARGET_H8300H || TARGET_H8300S)
2958    && INTVAL (operands[1]) < 16"
2959   "rotr.w\\t%e2\;rotl.w\\t%e2\;bst\\t%Z1,%Y0"
2960   [(set_attr "cc" "clobber")
2961    (set_attr "length" "6")])
2963 (define_insn "*insv_si_8_8"
2964   [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
2965                          (const_int 8)
2966                          (const_int 8))
2967         (match_operand:SI 1 "register_operand" "r"))]
2968   "TARGET_H8300H || TARGET_H8300S"
2969   "mov.b\\t%w1,%x0"
2970   [(set_attr "cc" "clobber")
2971    (set_attr "length" "2")])
2973 (define_insn "*insv_si_8_8_lshiftrt_8"
2974   [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
2975                          (const_int 8)
2976                          (const_int 8))
2977         (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
2978                      (const_int 8)))]
2979   "TARGET_H8300H || TARGET_H8300S"
2980   "mov.b\\t%x1,%x0"
2981   [(set_attr "cc" "clobber")
2982    (set_attr "length" "2")])
2984 ;; extzv:SI
2986 (define_insn "*extzv_8_8"
2987   [(set (match_operand:SI 0 "register_operand" "=r,r")
2988         (zero_extract:SI (match_operand:SI 1 "register_operand" "?0,r")
2989                          (const_int 8)
2990                          (const_int 8)))]
2991   "TARGET_H8300H || TARGET_H8300S"
2992   "@
2993    mov.b\\t%x1,%w0\;extu.w\\t%f0\;extu.l\\t%S0
2994    sub.l\\t%S0,%S0\;mov.b\\t%x1,%w0"
2995   [(set_attr "cc" "set_znv,clobber")
2996    (set_attr "length" "6,4")])
2998 (define_insn "*extzv_8_16"
2999   [(set (match_operand:SI 0 "register_operand" "=r")
3000         (zero_extract:SI (match_operand:SI 1 "register_operand" "r")
3001                          (const_int 8)
3002                          (const_int 16)))]
3003   "TARGET_H8300H || TARGET_H8300S"
3004   "mov.w\\t%e1,%f0\;extu.w\\t%f0\;extu.l\\t%S0"
3005   [(set_attr "cc" "set_znv")
3006    (set_attr "length" "6")])
3008 (define_insn "*extzv_16_8"
3009   [(set (match_operand:SI 0 "register_operand" "=r")
3010         (zero_extract:SI (match_operand:SI 1 "register_operand" "r")
3011                          (const_int 16)
3012                          (const_int 8)))
3013    (clobber (match_scratch:SI 2 "=&r"))]
3014   "TARGET_H8300H"
3015   "mov.w\\t%e1,%f2\;mov.b\\t%x1,%w0\;mov.b\\t%w2,%x0\;extu.l\\t%S0"
3016   [(set_attr "length" "8")
3017    (set_attr "cc" "set_znv")])
3019 ;; Extract the exponent of a float.
3021 (define_insn_and_split "*extzv_8_23"
3022   [(set (match_operand:SI 0 "register_operand" "=r")
3023         (zero_extract:SI (match_operand:SI 1 "register_operand" "0")
3024                          (const_int 8)
3025                          (const_int 23)))]
3026   "(TARGET_H8300H || TARGET_H8300S)"
3027   "#"
3028   "&& reload_completed"
3029   [(parallel [(set (match_dup 0)
3030                    (ashift:SI (match_dup 0)
3031                               (const_int 1)))
3032               (clobber (scratch:QI))])
3033    (parallel [(set (match_dup 0)
3034                    (lshiftrt:SI (match_dup 0)
3035                                 (const_int 24)))
3036               (clobber (scratch:QI))])]
3037   "")
3039 ;; and:SI
3041 ;; ((SImode) HImode) << 15
3043 (define_insn_and_split "*twoshifts_l16_r1"
3044   [(set (match_operand:SI 0 "register_operand" "=r")
3045         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
3046                            (const_int 15))
3047                 (const_int 2147450880)))]
3048   "(TARGET_H8300H || TARGET_H8300S)"
3049   "#"
3050   "&& reload_completed"
3051   [(parallel [(set (match_dup 0)
3052                    (ashift:SI (match_dup 0)
3053                               (const_int 16)))
3054               (clobber (scratch:QI))])
3055    (parallel [(set (match_dup 0)
3056                    (lshiftrt:SI (match_dup 0)
3057                                 (const_int 1)))
3058               (clobber (scratch:QI))])]
3059   "")
3061 ;; Transform (SImode << B) & 0xffff into (SImode) (HImode << B).
3063 (define_insn_and_split "*andsi3_ashift_n_lower"
3064   [(set (match_operand:SI 0 "register_operand" "=r,r")
3065         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0,0")
3066                            (match_operand:QI 2 "const_int_operand" "S,n"))
3067                 (match_operand:SI 3 "const_int_operand" "n,n")))
3068    (clobber (match_scratch:QI 4 "=X,&r"))]
3069   "(TARGET_H8300H || TARGET_H8300S)
3070    && INTVAL (operands[2]) <= 15
3071    && INTVAL (operands[3]) == ((-1 << INTVAL (operands[2])) & 0xffff)"
3072   "#"
3073   "&& reload_completed"
3074   [(parallel [(set (match_dup 5)
3075                    (ashift:HI (match_dup 5)
3076                               (match_dup 2)))
3077               (clobber (match_dup 4))])
3078    (set (match_dup 0)
3079         (zero_extend:SI (match_dup 5)))]
3080   "operands[5] = gen_rtx_REG (HImode, REGNO (operands[0]));")
3082 ;; Accept (A >> 30) & 2 and the like.
3084 (define_insn "*andsi3_lshiftrt_n_sb"
3085   [(set (match_operand:SI 0 "register_operand" "=r")
3086         (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
3087                              (match_operand:SI 2 "const_int_operand" "n"))
3088                 (match_operand:SI 3 "single_one_operand" "n")))]
3089   "(TARGET_H8300H || TARGET_H8300S)
3090    && exact_log2 (INTVAL (operands[3])) < 16
3091    && INTVAL (operands[2]) + exact_log2 (INTVAL (operands[3])) == 31"
3092   "*
3094   operands[3] = GEN_INT (exact_log2 (INTVAL (operands[3])));
3095   return \"shll.l\\t%S0\;xor.l\\t%S0,%S0\;bst\\t%Z3,%Y0\";
3097   [(set_attr "length" "8")
3098    (set_attr "cc" "clobber")])
3100 (define_insn_and_split "*andsi3_lshiftrt_9_sb"
3101   [(set (match_operand:SI 0 "register_operand" "=r")
3102         (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
3103                              (const_int 9))
3104                 (const_int 4194304)))]
3105   "(TARGET_H8300H || TARGET_H8300S)"
3106   "#"
3107   "&& reload_completed"
3108   [(set (match_dup 0)
3109         (and:SI (lshiftrt:SI (match_dup 0)
3110                              (const_int 25))
3111                 (const_int 64)))
3112    (parallel [(set (match_dup 0)
3113                    (ashift:SI (match_dup 0)
3114                               (const_int 16)))
3115               (clobber (scratch:QI))])]
3116   "")
3118 ;; plus:SI
3120 (define_insn "*addsi3_upper"
3121   [(set (match_operand:SI 0 "register_operand" "=r")
3122         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
3123                           (const_int 65536))
3124                  (match_operand:SI 2 "register_operand" "0")))]
3125   "TARGET_H8300H || TARGET_H8300S"
3126   "add.w\\t%f1,%e0"
3127   [(set_attr "length" "2")
3128    (set_attr "cc" "clobber")])
3130 (define_insn "*addsi3_lshiftrt_16_zexthi"
3131   [(set (match_operand:SI 0 "register_operand" "=r")
3132         (plus:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
3133                               (const_int 16))
3134                  (zero_extend:SI (match_operand:HI 2 "register_operand" "0"))))]
3135   "TARGET_H8300H || TARGET_H8300S"
3136   "add.w\\t%e1,%f0\;xor.w\\t%e0,%e0\;rotxl.w\\t%e0"
3137   [(set_attr "cc" "clobber")
3138    (set_attr "length" "6")])
3140 (define_insn_and_split "*addsi3_and_r_1"
3141   [(set (match_operand:SI 0 "register_operand" "=r")
3142         (plus:SI (and:SI (match_operand:SI 1 "register_operand" "r")
3143                          (const_int 1))
3144                  (match_operand:SI 2 "register_operand" "0")))]
3145   "(TARGET_H8300H || TARGET_H8300S)"
3146   "#"
3147   "&& reload_completed"
3148   [(set (cc0)
3149         (zero_extract:SI (match_dup 1)
3150                          (const_int 1)
3151                          (const_int 0)))
3152    (set (pc)
3153         (if_then_else (eq (cc0)
3154                           (const_int 0))
3155                       (label_ref (match_dup 3))
3156                       (pc)))
3157    (set (match_dup 2)
3158         (plus:SI (match_dup 2)
3159                  (const_int 1)))
3160    (match_dup 3)]
3161   "operands[3] = gen_label_rtx ();")
3163 (define_insn_and_split "*addsi3_and_not_r_1"
3164   [(set (match_operand:SI 0 "register_operand" "=r")
3165         (plus:SI (and:SI (not:SI (match_operand:SI 1 "register_operand" "r"))
3166                          (const_int 1))
3167                  (match_operand:SI 2 "register_operand" "0")))]
3168   "(TARGET_H8300H || TARGET_H8300S)"
3169   "#"
3170   "&& reload_completed"
3171   [(set (cc0)
3172         (zero_extract:SI (match_dup 1)
3173                          (const_int 1)
3174                          (const_int 0)))
3175    (set (pc)
3176         (if_then_else (ne (cc0)
3177                           (const_int 0))
3178                       (label_ref (match_dup 3))
3179                       (pc)))
3180    (set (match_dup 2)
3181         (plus:SI (match_dup 2)
3182                  (const_int 1)))
3183    (match_dup 3)]
3184   "operands[3] = gen_label_rtx ();")
3186 ;; [ix]or:HI
3188 (define_insn "*ixorhi3_zext"
3189   [(set (match_operand:HI 0 "register_operand" "=r")
3190         (match_operator:HI 1 "iorxor_operator"
3191           [(zero_extend:HI (match_operand:QI 2 "register_operand" "r"))
3192            (match_operand:HI 3 "register_operand" "0")]))]
3193   ""
3194   "%c1.b\\t%X2,%s0"
3195   [(set_attr "cc" "clobber")
3196    (set_attr "length" "2")])
3198 ;; [ix]or:SI
3200 (define_insn "*ixorsi3_zext_qi"
3201   [(set (match_operand:SI 0 "register_operand" "=r")
3202         (match_operator:SI 1 "iorxor_operator"
3203           [(zero_extend:SI (match_operand:QI 2 "register_operand" "r"))
3204            (match_operand:SI 3 "register_operand" "0")]))]
3205   ""
3206   "%c1.b\\t%X2,%w0"
3207   [(set_attr "cc" "clobber")
3208    (set_attr "length" "2")])
3210 (define_insn "*ixorsi3_zext_hi"
3211   [(set (match_operand:SI 0 "register_operand" "=r")
3212         (match_operator:SI 1 "iorxor_operator"
3213           [(zero_extend:SI (match_operand:HI 2 "register_operand" "r"))
3214            (match_operand:SI 3 "register_operand" "0")]))]
3215   "TARGET_H8300H || TARGET_H8300S"
3216   "%c1.w\\t%T2,%f0"
3217   [(set_attr "cc" "clobber")
3218    (set_attr "length" "2")])
3220 (define_insn "*ixorsi3_ashift_16"
3221   [(set (match_operand:SI 0 "register_operand" "=r")
3222         (match_operator:SI 1 "iorxor_operator"
3223           [(ashift:SI (match_operand:SI 2 "register_operand" "r")
3224                       (const_int 16))
3225            (match_operand:SI 3 "register_operand" "0")]))]
3226   "TARGET_H8300H || TARGET_H8300S"
3227   "%c1.w\\t%f2,%e0"
3228   [(set_attr "cc" "clobber")
3229    (set_attr "length" "2")])
3231 (define_insn "*ixorsi3_lshiftrt_16"
3232   [(set (match_operand:SI 0 "register_operand" "=r")
3233         (match_operator:SI 1 "iorxor_operator"
3234           [(lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
3235                         (const_int 16))
3236            (match_operand:SI 3 "register_operand" "0")]))]
3237   "TARGET_H8300H || TARGET_H8300S"
3238   "%c1.w\\t%e2,%f0"
3239   [(set_attr "cc" "clobber")
3240    (set_attr "length" "2")])
3242 ;; ior:HI
3244 (define_insn "*iorhi3_ashift_8"
3245   [(set (match_operand:HI 0 "register_operand" "=r")
3246         (ior:HI (ashift:HI (match_operand:HI 1 "register_operand" "r")
3247                            (const_int 8))
3248                 (match_operand:HI 2 "register_operand" "0")))]
3249   ""
3250   "or.b\\t%s1,%t0"
3251   [(set_attr "cc" "clobber")
3252    (set_attr "length" "2")])
3254 (define_insn "*iorhi3_lshiftrt_8"
3255   [(set (match_operand:HI 0 "register_operand" "=r")
3256         (ior:HI (lshiftrt:HI (match_operand:HI 1 "register_operand" "r")
3257                              (const_int 8))
3258                 (match_operand:HI 2 "register_operand" "0")))]
3259   ""
3260   "or.b\\t%t1,%s0"
3261   [(set_attr "cc" "clobber")
3262    (set_attr "length" "2")])
3264 (define_insn "*iorhi3_two_qi"
3265   [(set (match_operand:HI 0 "register_operand" "=r")
3266         (ior:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "0"))
3267                 (ashift:HI (match_operand:HI 2 "register_operand" "r")
3268                            (const_int 8))))]
3269   ""
3270   "mov.b\\t%s2,%t0"
3271   [(set_attr "cc" "clobber")
3272    (set_attr "length" "2")])
3274 (define_insn "*iorhi3_two_qi_mem"
3275   [(set (match_operand:HI 0 "register_operand" "=&r")
3276         (ior:HI (zero_extend:HI (match_operand:QI 1 "memory_operand" "m"))
3277                 (ashift:HI (subreg:HI (match_operand:QI 2 "memory_operand" "m") 0)
3278                            (const_int 8))))]
3279   ""
3280   "mov.b\\t%X2,%t0\;mov.b\\t%X1,%s0"
3281   [(set_attr "cc" "clobber")
3282    (set_attr "length" "16")])
3284 (define_split
3285   [(set (match_operand:HI 0 "register_operand" "")
3286         (ior:HI (zero_extend:HI (match_operand:QI 1 "memory_operand" ""))
3287                 (ashift:HI (subreg:HI (match_operand:QI 2 "memory_operand" "") 0)
3288                            (const_int 8))))]
3289   "(TARGET_H8300H || TARGET_H8300S)
3290    && reload_completed
3291    && byte_accesses_mergeable_p (XEXP (operands[2], 0), XEXP (operands[1], 0))"
3292   [(set (match_dup 0)
3293         (match_dup 3))]
3294   "operands[3] = gen_rtx_MEM (HImode, XEXP (operands[2], 0));")
3296 ;; ior:SI
3298 (define_insn "*iorsi3_two_hi"
3299   [(set (match_operand:SI 0 "register_operand" "=r")
3300         (ior:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "0"))
3301                 (ashift:SI (match_operand:SI 2 "register_operand" "r")
3302                            (const_int 16))))]
3303   "TARGET_H8300H || TARGET_H8300S"
3304   "mov.w\\t%f2,%e0"
3305   [(set_attr "cc" "clobber")
3306    (set_attr "length" "2")])
3308 (define_insn_and_split "*iorsi3_two_qi_zext"
3309   [(set (match_operand:SI 0 "register_operand" "=&r")
3310         (ior:SI (zero_extend:SI (match_operand:QI 1 "memory_operand" "m"))
3312                 (and:SI (ashift:SI (subreg:SI (match_operand:QI 2 "memory_operand" "m") 0)
3313                                    (const_int 8))
3314                         (const_int 65280))))]
3315   "(TARGET_H8300H || TARGET_H8300S)"
3316   "#"
3317   "&& reload_completed"
3318   [(set (match_dup 3)
3319         (ior:HI (zero_extend:HI (match_dup 1))
3320                 (ashift:HI (subreg:HI (match_dup 2) 0)
3321                            (const_int 8))))
3322    (set (match_dup 0)
3323         (zero_extend:SI (match_dup 3)))]
3324   "operands[3] = gen_rtx_REG (HImode, REGNO (operands[0]));")
3326 (define_insn "*iorsi3_e2f"
3327   [(set (match_operand:SI 0 "register_operand" "=r")
3328         (ior:SI (and:SI (match_operand:SI 1 "register_operand" "0")
3329                         (const_int -65536))
3330                 (lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
3331                              (const_int 16))))]
3332   "TARGET_H8300H || TARGET_H8300S"
3333   "mov.w\\t%e2,%f0"
3334   [(set_attr "length" "2")
3335    (set_attr "cc" "clobber")])
3337 (define_insn_and_split "*iorsi3_two_qi_sext"
3338   [(set (match_operand:SI 0 "register_operand" "=r")
3339         (ior:SI (zero_extend:SI (match_operand:QI 1 "register_operand" "0"))
3340                 (ashift:SI (sign_extend:SI (match_operand:QI 2 "register_operand" "r"))
3341                            (const_int 8))))]
3342   "(TARGET_H8300H || TARGET_H8300S)"
3343   "#"
3344   "&& reload_completed"
3345   [(set (match_dup 3)
3346         (ior:HI (zero_extend:HI (match_dup 1))
3347                 (ashift:HI (match_dup 4)
3348                            (const_int 8))))
3349    (set (match_dup 0)
3350         (sign_extend:SI (match_dup 3)))]
3351   "operands[3] = gen_rtx_REG (HImode, REGNO (operands[0]));
3352    operands[4] = gen_rtx_REG (HImode, REGNO (operands[2]));")
3354 (define_insn "*iorsi3_w"
3355   [(set (match_operand:SI 0 "register_operand" "=r,&r")
3356         (ior:SI (and:SI (match_operand:SI 1 "register_operand" "0,0")
3357                         (const_int -256))
3358                 (zero_extend:SI (match_operand:QI 2 "general_operand_src" "r,g>"))))]
3359   "TARGET_H8300H || TARGET_H8300S"
3360   "mov.b\\t%X2,%w0"
3361   [(set_attr "length" "2,8")
3362    (set_attr "cc" "clobber,clobber")])
3364 (define_insn "*iorsi3_ashift_31"
3365   [(set (match_operand:SI 0 "register_operand" "=&r")
3366         (ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "r")
3367                            (const_int 31))
3368                 (match_operand:SI 2 "register_operand" "0")))]
3369   "TARGET_H8300H || TARGET_H8300S"
3370   "rotxl.l\\t%S0\;bor\\t#0,%w1\;rotxr.l\\t%S0"
3371   [(set_attr "length" "6")
3372    (set_attr "cc" "set_znv")])
3374 (define_insn "*iorsi3_and_ashift"
3375   [(set (match_operand:SI 0 "register_operand" "=r")
3376         (ior:SI (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "r")
3377                                    (match_operand:SI 2 "const_int_operand" "n"))
3378                         (match_operand:SI 3 "single_one_operand" "n"))
3379                 (match_operand:SI 4 "register_operand" "0")))]
3380   "(TARGET_H8300H || TARGET_H8300S)
3381    && (INTVAL (operands[3]) & ~0xffff) == 0"
3382   "*
3384   rtx srcpos = GEN_INT (exact_log2 (INTVAL (operands[3]))
3385                         - INTVAL (operands[2]));
3386   rtx dstpos = GEN_INT (exact_log2 (INTVAL (operands[3])));
3387   operands[2] = srcpos;
3388   operands[3] = dstpos;
3389   return \"bld\\t%Z2,%Y1\;bor\\t%Z3,%Y0\;bst\\t%Z3,%Y0\";
3391   [(set_attr "length" "6")
3392    (set_attr "cc" "clobber")])
3394 (define_insn "*iorsi3_and_lshiftrt"
3395   [(set (match_operand:SI 0 "register_operand" "=r")
3396         (ior:SI (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
3397                                      (match_operand:SI 2 "const_int_operand" "n"))
3398                         (match_operand:SI 3 "single_one_operand" "n"))
3399                 (match_operand:SI 4 "register_operand" "0")))]
3400   "(TARGET_H8300H || TARGET_H8300S)
3401    && ((INTVAL (operands[3]) << INTVAL (operands[2])) & ~0xffff) == 0"
3402   "*
3404   rtx srcpos = GEN_INT (exact_log2 (INTVAL (operands[3]))
3405                         + INTVAL (operands[2]));
3406   rtx dstpos = GEN_INT (exact_log2 (INTVAL (operands[3])));
3407   operands[2] = srcpos;
3408   operands[3] = dstpos;
3409   return \"bld\\t%Z2,%Y1\;bor\\t%Z3,%Y0\;bst\\t%Z3,%Y0\";
3411   [(set_attr "length" "6")
3412    (set_attr "cc" "clobber")])
3414 (define_insn "*iorsi3_zero_extract"
3415   [(set (match_operand:SI 0 "register_operand" "=r")
3416         (ior:SI (zero_extract:SI (match_operand:SI 1 "register_operand" "r")
3417                                  (const_int 1)
3418                                  (match_operand:SI 2 "const_int_operand" "n"))
3419                 (match_operand:SI 3 "register_operand" "0")))]
3420   "(TARGET_H8300H || TARGET_H8300S)
3421    && INTVAL (operands[2]) < 16"
3422   "bld\\t%Z2,%Y1\;bor\\t#0,%w0\;bst\\t#0,%w0"
3423   [(set_attr "length" "6")
3424    (set_attr "cc" "clobber")])
3426 (define_insn "*iorsi3_and_lshiftrt_n_sb"
3427   [(set (match_operand:SI 0 "register_operand" "=r")
3428         (ior:SI (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
3429                                      (const_int 30))
3430                         (const_int 2))
3431                 (match_operand:SI 2 "register_operand" "0")))]
3432   "(TARGET_H8300H || TARGET_H8300S)"
3433   "rotl.l\\t%S1\;rotr.l\\t%S1\;bor\\t#1,%w0\;bst\\t#1,%w0"
3434   [(set_attr "length" "8")
3435    (set_attr "cc" "clobber")])
3437 (define_insn "*iorsi3_and_lshiftrt_9_sb"
3438   [(set (match_operand:SI 0 "register_operand" "=r")
3439         (ior:SI (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
3440                                      (const_int 9))
3441                         (const_int 4194304))
3442                 (match_operand:SI 2 "register_operand" "0")))
3443    (clobber (match_scratch:HI 3 "=&r"))]
3444   "(TARGET_H8300H || TARGET_H8300S)"
3445   "*
3447   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3448     return \"shll.l\\t%S1\;xor.w\\t%T3,%T3\;bst\\t#6,%s3\;or.w\\t%T3,%e0\";
3449   else
3450     return \"rotl.l\\t%S1\;rotr.l\\t%S1\;xor.w\\t%T3,%T3\;bst\\t#6,%s3\;or.w\\t%T3,%e0\";
3452   [(set_attr "length" "10")
3453    (set_attr "cc" "clobber")])
3455 ;; Used to OR the exponent of a float.
3457 (define_insn "*iorsi3_shift"
3458   [(set (match_operand:SI 0 "register_operand" "=r")
3459         (ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "r")
3460                            (const_int 23))
3461                 (match_operand:SI 2 "register_operand" "0")))
3462    (clobber (match_scratch:SI 3 "=&r"))]
3463   "TARGET_H8300H || TARGET_H8300S"
3464   "#")
3466 (define_split
3467   [(parallel
3468     [(set (match_operand:SI 0 "register_operand" "")
3469           (ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
3470                              (const_int 23))
3471                   (match_dup 0)))
3472      (clobber (match_operand:SI 2 "register_operand" ""))])]
3473   "(TARGET_H8300H || TARGET_H8300S)
3474    && flow2_completed
3475    && find_regno_note (insn, REG_DEAD, REGNO (operands[1]))
3476    && REGNO (operands[0]) != REGNO (operands[1])"
3477   [(parallel [(set (match_dup 3)
3478                    (ashift:HI (match_dup 3)
3479                               (const_int 7)))
3480               (clobber (scratch:QI))])
3481    (set (match_dup 0)
3482         (ior:SI (ashift:SI (match_dup 1)
3483                            (const_int 16))
3484                 (match_dup 0)))]
3485   "operands[3] = gen_rtx_REG (HImode, REGNO (operands[1]));")
3487 (define_split
3488   [(parallel
3489     [(set (match_operand:SI 0 "register_operand" "")
3490           (ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
3491                              (const_int 23))
3492                   (match_dup 0)))
3493      (clobber (match_operand:SI 2 "register_operand" ""))])]
3494   "(TARGET_H8300H || TARGET_H8300S)
3495    && flow2_completed
3496    && !(find_regno_note (insn, REG_DEAD, REGNO (operands[1]))
3497         && REGNO (operands[0]) != REGNO (operands[1]))"
3498   [(set (match_dup 2)
3499         (match_dup 1))
3500    (parallel [(set (match_dup 3)
3501                    (ashift:HI (match_dup 3)
3502                               (const_int 7)))
3503               (clobber (scratch:QI))])
3504    (set (match_dup 0)
3505         (ior:SI (ashift:SI (match_dup 2)
3506                            (const_int 16))
3507                 (match_dup 0)))]
3508   "operands[3] = gen_rtx_REG (HImode, REGNO (operands[2]));")
3510 (define_insn "*iorsi2_and_1_lshiftrt_1"
3511   [(set (match_operand:SI 0 "register_operand" "=r")
3512         (ior:SI (and:SI (match_operand:SI 1 "register_operand" "0")
3513                         (const_int 1))
3514                 (lshiftrt:SI (match_dup 1)
3515                              (const_int 1))))]
3516   "TARGET_H8300H || TARGET_H8300S"
3517   "shlr.l\\t%S0\;bor\\t#0,%w0\;bst\\t#0,%w0"
3518   [(set_attr "length" "6")
3519    (set_attr "cc" "clobber")])
3521 (define_insn_and_split "*iorsi3_ashift_16_ashift_24"
3522   [(set (match_operand:SI 0 "register_operand" "=r")
3523         (ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
3524                            (const_int 16))
3525                 (ashift:SI (match_operand:SI 2 "register_operand" "r")
3526                            (const_int 24))))]
3527   "(TARGET_H8300H || TARGET_H8300S)"
3528   "#"
3529   "&& reload_completed"
3530   [(set (match_dup 3)
3531         (ior:HI (ashift:HI (match_dup 4)
3532                            (const_int 8))
3533                 (match_dup 3)))
3534    (parallel [(set (match_dup 0)
3535                    (ashift:SI (match_dup 0)
3536                               (const_int 16)))
3537               (clobber (scratch:QI))])]
3538   "operands[3] = gen_rtx_REG (HImode, REGNO (operands[0]));
3539    operands[4] = gen_rtx_REG (HImode, REGNO (operands[2]));")
3541 (define_insn_and_split "*iorsi3_ashift_16_ashift_24_mem"
3542   [(set (match_operand:SI 0 "register_operand" "=&r")
3543         (ior:SI (and:SI (ashift:SI (subreg:SI (match_operand:QI 1 "memory_operand" "m") 0)
3544                                    (const_int 16))
3545                         (const_int 16711680))
3546                 (ashift:SI (subreg:SI (match_operand:QI 2 "memory_operand" "m") 0)
3547                            (const_int 24))))]
3548   "(TARGET_H8300H || TARGET_H8300S)"
3549   "#"
3550   "&& reload_completed"
3551   [(set (match_dup 3)
3552         (ior:HI (zero_extend:HI (match_dup 1))
3553                 (ashift:HI (subreg:HI (match_dup 2) 0)
3554                            (const_int 8))))
3555    (parallel [(set (match_dup 0)
3556                    (ashift:SI (match_dup 0)
3557                               (const_int 16)))
3558               (clobber (scratch:QI))])]
3559   "operands[3] = gen_rtx_REG (HImode, REGNO (operands[0]));")
3561 ;; Used to add the exponent of a float.
3563 (define_insn "*addsi3_shift"
3564   [(set (match_operand:SI 0 "register_operand" "=r")
3565         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
3566                           (const_int 8388608))
3567                  (match_operand:SI 2 "register_operand" "0")))
3568    (clobber (match_scratch:SI 3 "=&r"))]
3569   "TARGET_H8300H || TARGET_H8300S"
3570   "#")
3572 (define_split
3573   [(parallel
3574     [(set (match_operand:SI 0 "register_operand" "")
3575           (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "")
3576                             (const_int 8388608))
3577                    (match_dup 0)))
3578      (clobber (match_operand:SI 2 "register_operand" ""))])]
3579   "(TARGET_H8300H || TARGET_H8300S)
3580    && flow2_completed
3581    && find_regno_note (insn, REG_DEAD, REGNO (operands[1]))
3582    && REGNO (operands[0]) != REGNO (operands[1])"
3583   [(parallel [(set (match_dup 3)
3584                    (ashift:HI (match_dup 3)
3585                               (const_int 7)))
3586               (clobber (scratch:QI))])
3587    (set (match_dup 0)
3588         (plus:SI (mult:SI (match_dup 1)
3589                           (const_int 65536))
3590                  (match_dup 0)))]
3591   "operands[3] = gen_rtx_REG (HImode, REGNO (operands[1]));")
3593 (define_split
3594   [(parallel
3595     [(set (match_operand:SI 0 "register_operand" "")
3596           (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "")
3597                             (const_int 8388608))
3598                    (match_dup 0)))
3599      (clobber (match_operand:SI 2 "register_operand" ""))])]
3600   "(TARGET_H8300H || TARGET_H8300S)
3601    && flow2_completed
3602    && !(find_regno_note (insn, REG_DEAD, REGNO (operands[1]))
3603         && REGNO (operands[0]) != REGNO (operands[1]))"
3604   [(set (match_dup 2)
3605         (match_dup 1))
3606    (parallel [(set (match_dup 3)
3607                    (ashift:HI (match_dup 3)
3608                               (const_int 7)))
3609               (clobber (scratch:QI))])
3610    (set (match_dup 0)
3611         (plus:SI (mult:SI (match_dup 2)
3612                           (const_int 65536))
3613                  (match_dup 0)))]
3614   "operands[3] = gen_rtx_REG (HImode, REGNO (operands[2]));")
3616 ;; ashift:SI
3618 (define_insn_and_split "*ashiftsi_sextqi_7"
3619   [(set (match_operand:SI 0 "register_operand" "=r")
3620         (ashift:SI (sign_extend:SI (match_operand:QI 1 "register_operand" "0"))
3621                    (const_int 7)))]
3622   "(TARGET_H8300H || TARGET_H8300S)"
3623   "#"
3624   "&& reload_completed"
3625   [(parallel [(set (match_dup 2)
3626                    (ashift:HI (match_dup 2)
3627                               (const_int 8)))
3628               (clobber (scratch:QI))])
3629    (set (match_dup 0)
3630         (sign_extend:SI (match_dup 2)))
3631    (parallel [(set (match_dup 0)
3632                    (ashiftrt:SI (match_dup 0)
3633                                 (const_int 1)))
3634               (clobber (scratch:QI))])]
3635   "operands[2] = gen_rtx_REG (HImode, REGNO (operands[0]));")
3637 ;; Storing a part of HImode to QImode.
3639 (define_insn ""
3640   [(set (match_operand:QI 0 "general_operand_dst" "=rm<")
3641         (subreg:QI (lshiftrt:HI (match_operand:HI 1 "register_operand" "r")
3642                                 (const_int 8)) 1))]
3643   ""
3644   "mov.b\\t%t1,%R0"
3645   [(set_attr "cc" "set_znv")
3646    (set_attr "length" "8")])
3648 ;; Storing a part of SImode to QImode.
3650 (define_insn ""
3651   [(set (match_operand:QI 0 "general_operand_dst" "=rm<")
3652         (subreg:QI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
3653                                 (const_int 8)) 3))]
3654   ""
3655   "mov.b\\t%x1,%R0"
3656   [(set_attr "cc" "set_znv")
3657    (set_attr "length" "8")])
3659 (define_insn ""
3660   [(set (match_operand:QI 0 "general_operand_dst" "=rm<")
3661         (subreg:QI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
3662                                 (const_int 16)) 3))
3663    (clobber (match_scratch:SI 2 "=&r"))]
3664   "TARGET_H8300H || TARGET_H8300S"
3665   "mov.w\\t%e1,%f2\;mov.b\\t%w2,%R0"
3666   [(set_attr "cc" "set_znv")
3667    (set_attr "length" "10")])
3669 (define_insn ""
3670   [(set (match_operand:QI 0 "general_operand_dst" "=rm<")
3671         (subreg:QI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
3672                                 (const_int 24)) 3))
3673    (clobber (match_scratch:SI 2 "=&r"))]
3674   "TARGET_H8300H || TARGET_H8300S"
3675   "mov.w\\t%e1,%f2\;mov.b\\t%x2,%R0"
3676   [(set_attr "cc" "set_znv")
3677    (set_attr "length" "10")])
3679 (define_insn_and_split ""
3680   [(set (pc)
3681         (if_then_else (eq (zero_extract:SI (subreg:SI (match_operand:QI 0 "register_operand" "") 0)
3682                                            (const_int 1)
3683                                            (const_int 7))
3684                           (const_int 0))
3685                       (label_ref (match_operand 1 "" ""))
3686                       (pc)))]
3687   ""
3688   "#"
3689   ""
3690   [(set (cc0)
3691         (match_dup 0))
3692    (set (pc)
3693         (if_then_else (ge (cc0)
3694                           (const_int 0))
3695                       (label_ref (match_dup 1))
3696                       (pc)))]
3697   "")
3699 (define_insn_and_split ""
3700   [(set (pc)
3701         (if_then_else (ne (zero_extract:SI (subreg:SI (match_operand:QI 0 "register_operand" "") 0)
3702                                            (const_int 1)
3703                                            (const_int 7))
3704                           (const_int 0))
3705                       (label_ref (match_operand 1 "" ""))
3706                       (pc)))]
3707   ""
3708   "#"
3709   ""
3710   [(set (cc0)
3711         (match_dup 0))
3712    (set (pc)
3713         (if_then_else (lt (cc0)
3714                           (const_int 0))
3715                       (label_ref (match_dup 1))
3716                       (pc)))]
3717   "")
3719 ;; -----------------------------------------------------------------
3720 ;; PEEPHOLE PATTERNS
3721 ;; -----------------------------------------------------------------
3723 ;; Convert (A >> B) & C to (A & 255) >> B if C == 255 >> B.
3725 (define_peephole2
3726   [(parallel
3727      [(set (match_operand:HI 0 "register_operand" "")
3728            (lshiftrt:HI (match_dup 0)
3729                         (match_operand:HI 1 "const_int_operand" "")))
3730       (clobber (match_operand:HI 2 "" ""))])
3731    (set (match_dup 0)
3732         (and:HI (match_dup 0)
3733                 (match_operand:HI 3 "const_int_operand" "")))]
3734   "INTVAL (operands[3]) == (255 >> INTVAL (operands[1]))"
3735   [(set (match_dup 0)
3736         (and:HI (match_dup 0)
3737                 (const_int 255)))
3738    (parallel
3739      [(set (match_dup 0)
3740            (lshiftrt:HI (match_dup 0)
3741                         (match_dup 1)))
3742       (clobber (match_dup 2))])]
3743   "")
3745 ;; Convert (A << B) & C to (A & 255) << B if C == 255 << B.
3747 (define_peephole2
3748   [(parallel
3749      [(set (match_operand:HI 0 "register_operand" "")
3750            (ashift:HI (match_dup 0)
3751                       (match_operand:HI 1 "const_int_operand" "")))
3752       (clobber (match_operand:HI 2 "" ""))])
3753    (set (match_dup 0)
3754         (and:HI (match_dup 0)
3755                 (match_operand:HI 3 "const_int_operand" "")))]
3756   "INTVAL (operands[3]) == (255 << INTVAL (operands[1]))"
3757   [(set (match_dup 0)
3758         (and:HI (match_dup 0)
3759                 (const_int 255)))
3760    (parallel
3761      [(set (match_dup 0)
3762            (ashift:HI (match_dup 0)
3763                       (match_dup 1)))
3764       (clobber (match_dup 2))])]
3765   "")
3767 ;; Convert (A >> B) & C to (A & 255) >> B if C == 255 >> B.
3769 (define_peephole2
3770   [(parallel
3771      [(set (match_operand:SI 0 "register_operand" "")
3772            (lshiftrt:SI (match_dup 0)
3773                         (match_operand:SI 1 "const_int_operand" "")))
3774       (clobber (match_operand:SI 2 "" ""))])
3775    (set (match_dup 0)
3776         (and:SI (match_dup 0)
3777                 (match_operand:SI 3 "const_int_operand" "")))]
3778   "INTVAL (operands[3]) == (255 >> INTVAL (operands[1]))"
3779   [(set (match_dup 0)
3780         (and:SI (match_dup 0)
3781                 (const_int 255)))
3782    (parallel
3783      [(set (match_dup 0)
3784            (lshiftrt:SI (match_dup 0)
3785                         (match_dup 1)))
3786       (clobber (match_dup 2))])]
3787   "")
3789 ;; Convert (A << B) & C to (A & 255) << B if C == 255 << B.
3791 (define_peephole2
3792   [(parallel
3793      [(set (match_operand:SI 0 "register_operand" "")
3794            (ashift:SI (match_dup 0)
3795                       (match_operand:SI 1 "const_int_operand" "")))
3796       (clobber (match_operand:SI 2 "" ""))])
3797    (set (match_dup 0)
3798         (and:SI (match_dup 0)
3799                 (match_operand:SI 3 "const_int_operand" "")))]
3800   "INTVAL (operands[3]) == (255 << INTVAL (operands[1]))"
3801   [(set (match_dup 0)
3802         (and:SI (match_dup 0)
3803                 (const_int 255)))
3804    (parallel
3805      [(set (match_dup 0)
3806            (ashift:SI (match_dup 0)
3807                       (match_dup 1)))
3808       (clobber (match_dup 2))])]
3809   "")
3811 ;; Convert (A >> B) & C to (A & 65535) >> B if C == 65535 >> B.
3813 (define_peephole2
3814   [(parallel
3815      [(set (match_operand:SI 0 "register_operand" "")
3816            (lshiftrt:SI (match_dup 0)
3817                         (match_operand:SI 1 "const_int_operand" "")))
3818       (clobber (match_operand:SI 2 "" ""))])
3819    (set (match_dup 0)
3820         (and:SI (match_dup 0)
3821                 (match_operand:SI 3 "const_int_operand" "")))]
3822   "INTVAL (operands[3]) == (65535 >> INTVAL (operands[1]))"
3823   [(set (match_dup 0)
3824         (and:SI (match_dup 0)
3825                 (const_int 65535)))
3826    (parallel
3827      [(set (match_dup 0)
3828            (lshiftrt:SI (match_dup 0)
3829                         (match_dup 1)))
3830       (clobber (match_dup 2))])]
3831   "")
3833 ;; Convert (A << B) & C to (A & 65535) << B if C == 65535 << B.
3835 (define_peephole2
3836   [(parallel
3837      [(set (match_operand:SI 0 "register_operand" "")
3838            (ashift:SI (match_dup 0)
3839                       (match_operand:SI 1 "const_int_operand" "")))
3840       (clobber (match_operand:SI 2 "" ""))])
3841    (set (match_dup 0)
3842         (and:SI (match_dup 0)
3843                 (match_operand:SI 3 "const_int_operand" "")))]
3844   "INTVAL (operands[3]) == (65535 << INTVAL (operands[1]))"
3845   [(set (match_dup 0)
3846         (and:SI (match_dup 0)
3847                 (const_int 65535)))
3848    (parallel
3849      [(set (match_dup 0)
3850            (ashift:SI (match_dup 0)
3851                       (match_dup 1)))
3852       (clobber (match_dup 2))])]
3853   "")
3855 ;; Convert a QImode push into an SImode push so that the
3856 ;; define_peephole2 below can cram multiple pushes into one stm.l.
3858 (define_peephole2
3859   [(parallel [(set (reg:SI SP_REG)
3860                    (plus:SI (reg:SI SP_REG) (const_int -4)))
3861               (set (mem:QI (plus:SI (reg:SI SP_REG) (const_int -3)))
3862                    (match_operand:QI 0 "register_operand" ""))])]
3863   "TARGET_H8300S && !TARGET_NORMAL_MODE"
3864   [(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
3865         (match_dup 0))]
3866   "operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]));")
3868 (define_peephole2
3869   [(parallel [(set (reg:HI SP_REG)
3870                    (plus:HI (reg:HI SP_REG) (const_int -4)))
3871               (set (mem:QI (plus:HI (reg:HI SP_REG) (const_int -3)))
3872                    (match_operand:QI 0 "register_operand" ""))])]
3873   "TARGET_H8300S && TARGET_NORMAL_MODE"
3874   [(set (mem:SI (pre_dec:HI (reg:HI SP_REG)))
3875         (match_dup 0))]
3876   "operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]));")
3878 ;; Convert a HImode push into an SImode push so that the
3879 ;; define_peephole2 below can cram multiple pushes into one stm.l.
3881 (define_peephole2
3882   [(parallel [(set (reg:SI SP_REG)
3883                    (plus:SI (reg:SI SP_REG) (const_int -4)))
3884               (set (mem:HI (plus:SI (reg:SI SP_REG) (const_int -2)))
3885                    (match_operand:HI 0 "register_operand" ""))])]
3886   "TARGET_H8300S && !TARGET_NORMAL_MODE"
3887   [(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
3888         (match_dup 0))]
3889   "operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]));")
3891 (define_peephole2
3892   [(parallel [(set (reg:HI SP_REG)
3893                    (plus:HI (reg:HI SP_REG) (const_int -4)))
3894               (set (mem:HI (plus:HI (reg:HI SP_REG) (const_int -2)))
3895                    (match_operand:HI 0 "register_operand" ""))])]
3896   "TARGET_H8300S && TARGET_NORMAL_MODE"
3897   [(set (mem:SI (pre_dec:HI (reg:HI SP_REG)))
3898         (match_dup 0))]
3899   "operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]));")
3901 ;; Cram four pushes into stm.l.
3903 (define_peephole2
3904   [(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
3905         (match_operand:SI 0 "register_operand" ""))
3906    (set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
3907         (match_operand:SI 1 "register_operand" ""))
3908    (set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
3909         (match_operand:SI 2 "register_operand" ""))
3910    (set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
3911         (match_operand:SI 3 "register_operand" ""))]
3912   "TARGET_H8300S && !TARGET_NORMAL_MODE
3913    && REGNO (operands[0]) == 0
3914    && REGNO (operands[1]) == 1
3915    && REGNO (operands[2]) == 2
3916    && REGNO (operands[3]) == 3"
3917   [(parallel [(set (reg:SI SP_REG)
3918                    (plus:SI (reg:SI SP_REG)
3919                             (const_int -16)))
3920               (set (mem:SI (plus:SI (reg:SI SP_REG) (const_int -4)))
3921                    (match_dup 0))
3922               (set (mem:SI (plus:SI (reg:SI SP_REG) (const_int -8)))
3923                    (match_dup 1))
3924               (set (mem:SI (plus:SI (reg:SI SP_REG) (const_int -12)))
3925                    (match_dup 2))
3926               (set (mem:SI (plus:SI (reg:SI SP_REG) (const_int -16)))
3927                    (match_dup 3))])]
3928   "")
3930 (define_peephole2
3931   [(set (mem:SI (pre_dec:HI (reg:HI SP_REG)))
3932         (match_operand:SI 0 "register_operand" ""))
3933    (set (mem:SI (pre_dec:HI (reg:HI SP_REG)))
3934         (match_operand:SI 1 "register_operand" ""))
3935    (set (mem:SI (pre_dec:HI (reg:HI SP_REG)))
3936         (match_operand:SI 2 "register_operand" ""))
3937    (set (mem:SI (pre_dec:HI (reg:HI SP_REG)))
3938         (match_operand:SI 3 "register_operand" ""))]
3939   "TARGET_H8300S && TARGET_NORMAL_MODE
3940    && REGNO (operands[0]) == 0
3941    && REGNO (operands[1]) == 1
3942    && REGNO (operands[2]) == 2
3943    && REGNO (operands[3]) == 3"
3944   [(parallel [(set (reg:HI SP_REG)
3945                    (plus:HI (reg:HI SP_REG)
3946                             (const_int -16)))
3947               (set (mem:SI (plus:HI (reg:HI SP_REG) (const_int -4)))
3948                    (match_dup 0))
3949               (set (mem:SI (plus:HI (reg:HI SP_REG) (const_int -8)))
3950                    (match_dup 1))
3951               (set (mem:SI (plus:HI (reg:HI SP_REG) (const_int -12)))
3952                    (match_dup 2))
3953               (set (mem:SI (plus:HI (reg:HI SP_REG) (const_int -16)))
3954                    (match_dup 3))])]
3955   "")
3957 ;; Cram three pushes into stm.l.
3959 (define_peephole2
3960   [(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
3961         (match_operand:SI 0 "register_operand" ""))
3962    (set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
3963         (match_operand:SI 1 "register_operand" ""))
3964    (set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
3965         (match_operand:SI 2 "register_operand" ""))]
3966   "TARGET_H8300S && !TARGET_NORMAL_MODE
3967    && ((REGNO (operands[0]) == 0
3968         && REGNO (operands[1]) == 1
3969         && REGNO (operands[2]) == 2)
3970        || (REGNO (operands[0]) == 4
3971            && REGNO (operands[1]) == 5
3972            && REGNO (operands[2]) == 6))"
3973   [(parallel [(set (reg:SI SP_REG)
3974                    (plus:SI (reg:SI SP_REG)
3975                             (const_int -12)))
3976               (set (mem:SI (plus:SI (reg:SI SP_REG) (const_int -4)))
3977                    (match_dup 0))
3978               (set (mem:SI (plus:SI (reg:SI SP_REG) (const_int -8)))
3979                    (match_dup 1))
3980               (set (mem:SI (plus:SI (reg:SI SP_REG) (const_int -12)))
3981                    (match_dup 2))])]
3982   "")
3984 (define_peephole2
3985   [(set (mem:SI (pre_dec:HI (reg:HI SP_REG)))
3986         (match_operand:SI 0 "register_operand" ""))
3987    (set (mem:SI (pre_dec:HI (reg:HI SP_REG)))
3988         (match_operand:SI 1 "register_operand" ""))
3989    (set (mem:SI (pre_dec:HI (reg:HI SP_REG)))
3990         (match_operand:SI 2 "register_operand" ""))]
3991   "TARGET_H8300S && TARGET_NORMAL_MODE
3992    && ((REGNO (operands[0]) == 0
3993         && REGNO (operands[1]) == 1
3994         && REGNO (operands[2]) == 2)
3995        || (REGNO (operands[0]) == 4
3996            && REGNO (operands[1]) == 5
3997            && REGNO (operands[2]) == 6))"
3998   [(parallel [(set (reg:HI SP_REG)
3999                    (plus:HI (reg:HI SP_REG)
4000                             (const_int -12)))
4001               (set (mem:SI (plus:HI (reg:HI SP_REG) (const_int -4)))
4002                    (match_dup 0))
4003               (set (mem:SI (plus:HI (reg:HI SP_REG) (const_int -8)))
4004                    (match_dup 1))
4005               (set (mem:SI (plus:HI (reg:HI SP_REG) (const_int -12)))
4006                    (match_dup 2))])]
4007   "")
4009 ;; Cram two pushes into stm.l.
4011 (define_peephole2
4012   [(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
4013         (match_operand:SI 0 "register_operand" ""))
4014    (set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
4015         (match_operand:SI 1 "register_operand" ""))]
4016   "TARGET_H8300S && !TARGET_NORMAL_MODE
4017    && ((REGNO (operands[0]) == 0 && REGNO (operands[1]) == 1)
4018        || (REGNO (operands[0]) == 2 && REGNO (operands[1]) == 3)
4019        || (REGNO (operands[0]) == 4 && REGNO (operands[1]) == 5))"
4020   [(parallel [(set (reg:SI SP_REG)
4021                    (plus:SI (reg:SI SP_REG)
4022                             (const_int -8)))
4023               (set (mem:SI (plus:SI (reg:SI SP_REG) (const_int -4)))
4024                    (match_dup 0))
4025               (set (mem:SI (plus:SI (reg:SI SP_REG) (const_int -8)))
4026                    (match_dup 1))])]
4027   "")
4029 (define_peephole2
4030   [(set (mem:SI (pre_dec:HI (reg:HI SP_REG)))
4031         (match_operand:SI 0 "register_operand" ""))
4032    (set (mem:SI (pre_dec:HI (reg:HI SP_REG)))
4033         (match_operand:SI 1 "register_operand" ""))]
4034   "TARGET_H8300S && TARGET_NORMAL_MODE
4035    && ((REGNO (operands[0]) == 0 && REGNO (operands[1]) == 1)
4036        || (REGNO (operands[0]) == 2 && REGNO (operands[1]) == 3)
4037        || (REGNO (operands[0]) == 4 && REGNO (operands[1]) == 5))"
4038   [(parallel [(set (reg:HI SP_REG)
4039                    (plus:HI (reg:HI SP_REG)
4040                             (const_int -8)))
4041               (set (mem:SI (plus:HI (reg:HI SP_REG) (const_int -4)))
4042                    (match_dup 0))
4043               (set (mem:SI (plus:HI (reg:HI SP_REG) (const_int -8)))
4044                    (match_dup 1))])]
4045   "")
4047 ;; Turn
4049 ;;   mov.w #2,r0
4050 ;;   add.w r7,r0  (6 bytes)
4052 ;; into
4054 ;;   mov.w r7,r0
4055 ;;   adds  #2,r0  (4 bytes)
4057 (define_peephole2
4058   [(set (match_operand:HI 0 "register_operand" "")
4059         (match_operand:HI 1 "const_int_operand" ""))
4060    (set (match_dup 0)
4061         (plus:HI (match_dup 0)
4062                  (match_operand:HI 2 "register_operand" "")))]
4063   "REG_P (operands[0]) && REG_P (operands[2])
4064    && REGNO (operands[0]) != REGNO (operands[2])
4065    && (CONST_OK_FOR_J (INTVAL (operands[1]))
4066        || CONST_OK_FOR_L (INTVAL (operands[1]))
4067        || CONST_OK_FOR_N (INTVAL (operands[1])))"
4068   [(set (match_dup 0)
4069         (match_dup 2))
4070    (set (match_dup 0)
4071         (plus:HI (match_dup 0)
4072                  (match_dup 1)))]
4073   "")
4075 ;; Turn
4077 ;;   sub.l  er0,er0
4078 ;;   add.b  #4,r0l
4079 ;;   add.l  er7,er0  (6 bytes)
4081 ;; into
4083 ;;   mov.l  er7,er0
4084 ;;   adds   #4,er0   (4 bytes)
4086 (define_peephole2
4087   [(set (match_operand:SI 0 "register_operand" "")
4088         (match_operand:SI 1 "const_int_operand" ""))
4089    (set (match_dup 0)
4090         (plus:SI (match_dup 0)
4091                  (match_operand:SI 2 "register_operand" "")))]
4092   "(TARGET_H8300H || TARGET_H8300S)
4093    && REG_P (operands[0]) && REG_P (operands[2])
4094    && REGNO (operands[0]) != REGNO (operands[2])
4095    && (CONST_OK_FOR_L (INTVAL (operands[1]))
4096        || CONST_OK_FOR_N (INTVAL (operands[1])))"
4097   [(set (match_dup 0)
4098         (match_dup 2))
4099    (set (match_dup 0)
4100         (plus:SI (match_dup 0)
4101                  (match_dup 1)))]
4102   "")
4104 ;; Turn
4106 ;;   mov.l er7,er0
4107 ;;   add.l #10,er0  (takes 8 bytes)
4109 ;; into
4111 ;;   sub.l er0,er0
4112 ;;   add.b #10,r0l
4113 ;;   add.l er7,er0  (takes 6 bytes)
4115 (define_peephole2
4116   [(set (match_operand:SI 0 "register_operand" "")
4117         (match_operand:SI 1 "register_operand" ""))
4118    (set (match_dup 0)
4119         (plus:SI (match_dup 0)
4120                  (match_operand:SI 2 "const_int_operand" "")))]
4121   "(TARGET_H8300H || TARGET_H8300S)
4122    && REG_P (operands[0]) && REG_P (operands[1])
4123    && REGNO (operands[0]) != REGNO (operands[1])
4124    && !CONST_OK_FOR_L (INTVAL (operands[2]))
4125    && !CONST_OK_FOR_N (INTVAL (operands[2]))
4126    && ((INTVAL (operands[2]) & 0xff) == INTVAL (operands[2])
4127        || (INTVAL (operands[2]) & 0xff00) == INTVAL (operands[2])
4128        || INTVAL (operands[2]) == 0xffff
4129        || INTVAL (operands[2]) == 0xfffe)"
4130   [(set (match_dup 0)
4131         (match_dup 2))
4132    (set (match_dup 0)
4133         (plus:SI (match_dup 0)
4134                  (match_dup 1)))]
4135   "")
4137 ;; Turn
4139 ;;   subs   #1,er4
4140 ;;   mov.w  r4,r4
4141 ;;   bne    .L2028
4143 ;; into
4145 ;;   dec.w  #1,r4
4146 ;;   bne    .L2028
4148 (define_peephole2
4149   [(set (match_operand:HI 0 "register_operand" "")
4150         (plus:HI (match_dup 0)
4151                  (match_operand 1 "incdec_operand" "")))
4152    (set (cc0)
4153         (match_dup 0))
4154    (set (pc)
4155         (if_then_else (match_operator 3 "eqne_operator"
4156                         [(cc0) (const_int 0)])
4157                       (label_ref (match_operand 2 "" ""))
4158                       (pc)))]
4159   "TARGET_H8300H || TARGET_H8300S"
4160   [(set (match_operand:HI 0 "register_operand" "")
4161         (unspec:HI [(match_dup 0)
4162                     (match_dup 1)]
4163                    UNSPEC_INCDEC))
4164    (set (cc0)
4165         (match_dup 0))
4166    (set (pc)
4167         (if_then_else (match_op_dup 3 [(cc0) (const_int 0)])
4168                       (label_ref (match_dup 2))
4169                       (pc)))]
4170   "")
4172 ;; The SImode version of the previous pattern.
4174 (define_peephole2
4175   [(set (match_operand:SI 0 "register_operand" "")
4176         (plus:SI (match_dup 0)
4177                  (match_operand 1 "incdec_operand" "")))
4178    (set (cc0)
4179         (match_dup 0))
4180    (set (pc)
4181         (if_then_else (match_operator 3 "eqne_operator"
4182                         [(cc0) (const_int 0)])
4183                       (label_ref (match_operand 2 "" ""))
4184                       (pc)))]
4185   "TARGET_H8300H || TARGET_H8300S"
4186   [(set (match_operand:SI 0 "register_operand" "")
4187         (unspec:SI [(match_dup 0)
4188                     (match_dup 1)]
4189                    UNSPEC_INCDEC))
4190    (set (cc0)
4191         (match_dup 0))
4192    (set (pc)
4193         (if_then_else (match_op_dup 3 [(cc0) (const_int 0)])
4194                       (label_ref (match_dup 2))
4195                       (pc)))]
4196   "")
4198 (define_peephole2
4199   [(parallel [(set (cc0)
4200                    (zero_extract:SI (match_operand:QI 0 "register_operand" "")
4201                                     (const_int 1)
4202                                     (const_int 7)))
4203               (clobber (scratch:QI))])
4204    (set (pc)
4205         (if_then_else (match_operator 1 "eqne_operator"
4206                         [(cc0) (const_int 0)])
4207                       (label_ref (match_operand 2 "" ""))
4208                       (pc)))]
4209   "(TARGET_H8300H || TARGET_H8300S)"
4210   [(set (cc0)
4211         (match_dup 0))
4212    (set (pc)
4213         (if_then_else (match_op_dup 3 [(cc0) (const_int 0)])
4214                       (label_ref (match_dup 2))
4215                       (pc)))]
4216   "operands[3] = ((GET_CODE (operands[1]) == EQ)
4217                   ? gen_rtx_GE (VOIDmode, cc0_rtx, const0_rtx)
4218                   : gen_rtx_LT (VOIDmode, cc0_rtx, const0_rtx));")
4220 ;; The next three peephole2's will try to transform
4222 ;;   mov.b A,r0l    (or mov.l A,er0)
4223 ;;   and.l #CST,er0
4225 ;; into
4227 ;;   sub.l er0
4228 ;;   mov.b A,r0l
4229 ;;   and.b #CST,r0l (if CST is not 255)
4231 (define_peephole2
4232   [(set (match_operand:QI 0 "register_operand" "")
4233         (match_operand:QI 1 "general_operand" ""))
4234    (set (match_operand:SI 2 "register_operand" "")
4235         (and:SI (match_dup 2)
4236                 (const_int 255)))]
4237   "(TARGET_H8300H || TARGET_H8300S)
4238    && !reg_overlap_mentioned_p (operands[2], operands[1])
4239    && REGNO (operands[0]) == REGNO (operands[2])"
4240   [(set (match_dup 2)
4241         (const_int 0))
4242    (set (strict_low_part (match_dup 0))
4243         (match_dup 1))]
4244   "")
4246 (define_peephole2
4247   [(set (match_operand:SI 0 "register_operand" "")
4248         (match_operand:SI 1 "general_operand" ""))
4249    (set (match_dup 0)
4250         (and:SI (match_dup 0)
4251                 (const_int 255)))]
4252   "(TARGET_H8300H || TARGET_H8300S)
4253    && !reg_overlap_mentioned_p (operands[0], operands[1])
4254    && !(GET_CODE (operands[1]) == MEM && MEM_VOLATILE_P (operands[1]))"
4255   [(set (match_dup 0)
4256         (const_int 0))
4257    (set (strict_low_part (match_dup 2))
4258         (match_dup 3))]
4259   "operands[2] = gen_lowpart (QImode, operands[0]);
4260    operands[3] = gen_lowpart (QImode, operands[1]);")
4262 (define_peephole2
4263   [(set (match_operand 0 "register_operand" "")
4264         (match_operand 1 "general_operand" ""))
4265    (set (match_operand:SI 2 "register_operand" "")
4266         (and:SI (match_dup 2)
4267                 (match_operand:SI 3 "const_int_qi_operand" "")))]
4268   "(TARGET_H8300H || TARGET_H8300S)
4269    && (GET_MODE (operands[0]) == QImode
4270        || GET_MODE (operands[0]) == HImode
4271        || GET_MODE (operands[0]) == SImode)
4272    && GET_MODE (operands[0]) == GET_MODE (operands[1])
4273    && REGNO (operands[0]) == REGNO (operands[2])
4274    && !reg_overlap_mentioned_p (operands[2], operands[1])
4275    && !(GET_MODE (operands[1]) != QImode
4276         && GET_CODE (operands[1]) == MEM
4277         && MEM_VOLATILE_P (operands[1]))"
4278   [(set (match_dup 2)
4279         (const_int 0))
4280    (set (strict_low_part (match_dup 4))
4281         (match_dup 5))
4282    (set (match_dup 2)
4283         (and:SI (match_dup 2)
4284                 (match_dup 6)))]
4285   "operands[4] = gen_lowpart (QImode, operands[0]);
4286    operands[5] = gen_lowpart (QImode, operands[1]);
4287    operands[6] = GEN_INT (~0xff | INTVAL (operands[3]));")
4289 (define_peephole2
4290   [(set (match_operand:SI 0 "register_operand" "")
4291         (match_operand:SI 1 "register_operand" ""))
4292    (set (match_dup 0)
4293         (and:SI (match_dup 0)
4294                 (const_int 65280)))]
4295   "(TARGET_H8300H || TARGET_H8300S)
4296    && !reg_overlap_mentioned_p (operands[0], operands[1])"
4297   [(set (match_dup 0)
4298         (const_int 0))
4299    (set (zero_extract:SI (match_dup 0)
4300                          (const_int 8)
4301                          (const_int 8))
4302         (lshiftrt:SI (match_dup 1)
4303                      (const_int 8)))]
4304   "")
4306 ;; If a load of mem:SI is followed by an AND that turns off the upper
4307 ;; half, then we can load mem:HI instead.
4309 (define_peephole2
4310   [(set (match_operand:SI 0 "register_operand" "")
4311         (match_operand:SI 1 "memory_operand" ""))
4312    (set (match_dup 0)
4313         (and:SI (match_dup 0)
4314                 (match_operand:SI 2 "const_int_operand" "")))]
4315   "(TARGET_H8300H || TARGET_H8300S)
4316    && !MEM_VOLATILE_P (operands[1])
4317    && (INTVAL (operands[2]) & ~0xffff) == 0
4318    && INTVAL (operands[2]) != 255"
4319   [(set (match_dup 3)
4320         (match_dup 4))
4321    (set (match_dup 0)
4322         (and:SI (match_dup 0)
4323                 (match_dup 2)))]
4324   "operands[3] = gen_lowpart (HImode, operands[0]);
4325    operands[4] = gen_lowpart (HImode, operands[1]);")
4327 ;; (compare (reg:HI) (const_int)) takes 4 bytes, so we try to achieve
4328 ;; the equivalent with shorter sequences.  Here is the summary.  Cases
4329 ;; are grouped for each define_peephole2.
4331 ;; reg  const_int                   use     insn
4332 ;; --------------------------------------------------------
4333 ;; dead    -2                       eq/ne   inc.l
4334 ;; dead    -1                       eq/ne   inc.l
4335 ;; dead     1                       eq/ne   dec.l
4336 ;; dead     2                       eq/ne   dec.l
4338 ;; dead     1                       geu/ltu shar.l
4339 ;; dead     3 (H8S)                 geu/ltu shar.l
4341 ;; ----   255                       geu/ltu mov.b
4343 ;; Transform
4345 ;;      cmp.w   #1,r0
4346 ;;      bne     .L1
4348 ;; into
4350 ;;      dec.w   #1,r0
4351 ;;      bne     .L1
4353 (define_peephole2
4354   [(set (cc0)
4355         (compare (match_operand:HI 0 "register_operand" "")
4356                  (match_operand:HI 1 "incdec_operand" "")))
4357    (set (pc)
4358         (if_then_else (match_operator 3 "eqne_operator"
4359                         [(cc0) (const_int 0)])
4360                       (label_ref (match_operand 2 "" ""))
4361                       (pc)))]
4362   "(TARGET_H8300H || TARGET_H8300S)
4363    && peep2_reg_dead_p (1, operands[0])"
4364   [(set (match_dup 0)
4365         (unspec:HI [(match_dup 0)
4366                     (match_dup 4)]
4367                    UNSPEC_INCDEC))
4368    (set (cc0)
4369         (match_dup 0))
4370    (set (pc)
4371         (if_then_else (match_op_dup 3 [(cc0) (const_int 0)])
4372                       (label_ref (match_dup 2))
4373                       (pc)))]
4374   "operands[4] = GEN_INT (- INTVAL (operands[1]));")
4376 ;; Transform
4378 ;;      cmp.w   #1,r0
4379 ;;      bhi     .L1
4381 ;; into
4383 ;;      shar.w  r0
4384 ;;      bne     .L1
4386 (define_peephole2
4387   [(set (cc0)
4388         (compare (match_operand:HI 0 "register_operand" "")
4389                  (match_operand:HI 1 "const_int_operand" "")))
4390    (set (pc)
4391         (if_then_else (match_operator 2 "gtle_operator"
4392                         [(cc0) (const_int 0)])
4393                       (label_ref (match_operand 3 "" ""))
4394                       (pc)))]
4395   "(TARGET_H8300H || TARGET_H8300S)
4396    && peep2_reg_dead_p (1, operands[0])
4397    && (INTVAL (operands[1]) == 1
4398         || (TARGET_H8300S && INTVAL (operands[1]) == 3))"
4399   [(parallel [(set (match_dup 0)
4400                    (ashiftrt:HI (match_dup 0)
4401                                 (match_dup 5)))
4402               (clobber (scratch:QI))])
4403    (set (cc0)
4404         (match_dup 0))
4405    (set (pc)
4406         (if_then_else (match_dup 4)
4407                       (label_ref (match_dup 3))
4408                       (pc)))]
4409   "switch (GET_CODE (operands[2]))
4410      {
4411      case GTU:
4412        operands[4] = gen_rtx_NE (VOIDmode, cc0_rtx, const0_rtx);
4413        break;
4414      case LEU:
4415        operands[4] = gen_rtx_EQ (VOIDmode, cc0_rtx, const0_rtx);
4416        break;
4417      default:
4418        operands[4] = operands[2];
4419        break;
4420      }
4421    operands[5] = GEN_INT (exact_log2 (INTVAL (operands[1]) + 1));")
4423 ;; Transform
4425 ;;      cmp.w   #255,r0
4426 ;;      bhi     .L1
4428 ;; into
4430 ;;      mov.b   r0h,r0h
4431 ;;      bne     .L1
4433 (define_peephole2
4434   [(set (cc0)
4435         (compare (match_operand:HI 0 "register_operand" "")
4436                  (const_int 255)))
4437    (set (pc)
4438         (if_then_else (match_operator 1 "gtle_operator"
4439                         [(cc0) (const_int 0)])
4440                       (label_ref (match_operand 2 "" ""))
4441                       (pc)))]
4442   "TARGET_H8300H || TARGET_H8300S"
4443   [(set (cc0)
4444         (and:HI (match_dup 0)
4445                 (const_int -256)))
4446    (set (pc)
4447         (if_then_else (match_dup 3)
4448                       (label_ref (match_dup 2))
4449                       (pc)))]
4450   "switch (GET_CODE (operands[1]))
4451      {
4452      case GTU:
4453        operands[3] = gen_rtx_NE (VOIDmode, cc0_rtx, const0_rtx);
4454        break;
4455      case LEU:
4456        operands[3] = gen_rtx_EQ (VOIDmode, cc0_rtx, const0_rtx);
4457        break;
4458      default:
4459        operands[3] = operands[1];
4460        break;
4461      }")
4463 ;; (compare (reg:SI) (const_int)) takes 6 bytes, so we try to achieve
4464 ;; the equivalent with shorter sequences.  Here is the summary.  Cases
4465 ;; are grouped for each define_peephole2.
4467 ;; reg  const_int                   use     insn
4468 ;; --------------------------------------------------------
4469 ;; live    -2                       eq/ne   copy and inc.l
4470 ;; live    -1                       eq/ne   copy and inc.l
4471 ;; live     1                       eq/ne   copy and dec.l
4472 ;; live     2                       eq/ne   copy and dec.l
4474 ;; dead    -2                       eq/ne   inc.l
4475 ;; dead    -1                       eq/ne   inc.l
4476 ;; dead     1                       eq/ne   dec.l
4477 ;; dead     2                       eq/ne   dec.l
4479 ;; dead -131072                     eq/ne   inc.w and test
4480 ;; dead  -65536                     eq/ne   inc.w and test
4481 ;; dead   65536                     eq/ne   dec.w and test
4482 ;; dead  131072                     eq/ne   dec.w and test
4484 ;; dead 0x000000?? except 1 and 2   eq/ne   xor.b and test
4485 ;; dead 0x0000??00                  eq/ne   xor.b and test
4486 ;; dead 0x0000ffff                  eq/ne   not.w and test
4488 ;; dead 0xffffff?? except -1 and -2 eq/ne   xor.b and not.l
4489 ;; dead 0xffff??ff                  eq/ne   xor.b and not.l
4490 ;; dead 0x40000000 (H8S)            eq/ne   rotl.l and dec.l
4491 ;; dead 0x80000000                  eq/ne   rotl.l and dec.l
4493 ;; live     1                       geu/ltu copy and shar.l
4494 ;; live     3 (H8S)                 geu/ltu copy and shar.l
4496 ;; dead     1                       geu/ltu shar.l
4497 ;; dead     3 (H8S)                 geu/ltu shar.l
4499 ;; dead     3 (H8/300H)             geu/ltu and.b and test
4500 ;; dead     7                       geu/ltu and.b and test
4501 ;; dead    15                       geu/ltu and.b and test
4502 ;; dead    31                       geu/ltu and.b and test
4503 ;; dead    63                       geu/ltu and.b and test
4504 ;; dead   127                       geu/ltu and.b and test
4505 ;; dead   255                       geu/ltu and.b and test
4507 ;; ---- 65535                       geu/ltu mov.w
4509 ;; For a small constant, it is cheaper to actually do the subtraction
4510 ;; and then test the register.
4512 (define_peephole2
4513   [(set (cc0)
4514         (compare (match_operand:SI 0 "register_operand" "")
4515                  (match_operand:SI 1 "incdec_operand" "")))
4516    (set (pc)
4517         (if_then_else (match_operator 3 "eqne_operator"
4518                         [(cc0) (const_int 0)])
4519                       (label_ref (match_operand 2 "" ""))
4520                       (pc)))]
4521   "(TARGET_H8300H || TARGET_H8300S)
4522    && peep2_reg_dead_p (1, operands[0])"
4523   [(set (match_dup 0)
4524         (unspec:SI [(match_dup 0)
4525                     (match_dup 4)]
4526                    UNSPEC_INCDEC))
4527    (set (cc0)
4528         (match_dup 0))
4529    (set (pc)
4530         (if_then_else (match_op_dup 3 [(cc0) (const_int 0)])
4531                       (label_ref (match_dup 2))
4532                       (pc)))]
4533   "operands[4] = GEN_INT (- INTVAL (operands[1]));")
4535 (define_peephole2
4536   [(set (cc0)
4537         (compare (match_operand:SI 0 "register_operand" "")
4538                  (match_operand:SI 1 "const_int_operand" "")))
4539    (set (pc)
4540         (if_then_else (match_operator 3 "eqne_operator"
4541                         [(cc0) (const_int 0)])
4542                       (label_ref (match_operand 2 "" ""))
4543                       (pc)))]
4544   "(TARGET_H8300H || TARGET_H8300S)
4545    && peep2_reg_dead_p (1, operands[0])
4546    && (INTVAL (operands[1]) == -131072
4547        || INTVAL (operands[1]) == -65536
4548        || INTVAL (operands[1]) == 65536
4549        || INTVAL (operands[1]) == 131072)"
4550   [(set (match_dup 0)
4551         (plus:SI (match_dup 0)
4552                  (match_dup 4)))
4553    (set (cc0)
4554         (match_dup 0))
4555    (set (pc)
4556         (if_then_else (match_op_dup 3 [(cc0) (const_int 0)])
4557                       (label_ref (match_dup 2))
4558                       (pc)))]
4559   "operands[4] = GEN_INT (- INTVAL (operands[1]));")
4561 ;; For certain (in)equality comparisons against a constant, we can
4562 ;; XOR the register with the constant, and test the register against
4563 ;; 0.
4565 (define_peephole2
4566   [(set (cc0)
4567         (compare (match_operand:SI 0 "register_operand" "")
4568                  (match_operand:SI 1 "const_int_operand" "")))
4569    (set (pc)
4570         (if_then_else (match_operator 3 "eqne_operator"
4571                         [(cc0) (const_int 0)])
4572                       (label_ref (match_operand 2 "" ""))
4573                       (pc)))]
4574   "(TARGET_H8300H || TARGET_H8300S)
4575    && peep2_reg_dead_p (1, operands[0])
4576    && ((INTVAL (operands[1]) & 0x00ff) == INTVAL (operands[1])
4577        || (INTVAL (operands[1]) & 0xff00) == INTVAL (operands[1])
4578        || INTVAL (operands[1]) == 0x0000ffff)
4579    && INTVAL (operands[1]) != 1
4580    && INTVAL (operands[1]) != 2"
4581   [(set (match_dup 0)
4582         (xor:SI (match_dup 0)
4583                 (match_dup 1)))
4584    (set (cc0)
4585         (match_dup 0))
4586    (set (pc)
4587         (if_then_else (match_op_dup 3 [(cc0) (const_int 0)])
4588                       (label_ref (match_dup 2))
4589                       (pc)))]
4590   "")
4592 (define_peephole2
4593   [(set (cc0)
4594         (compare (match_operand:SI 0 "register_operand" "")
4595                  (match_operand:SI 1 "const_int_operand" "")))
4596    (set (pc)
4597         (if_then_else (match_operator 3 "eqne_operator"
4598                         [(cc0) (const_int 0)])
4599                       (label_ref (match_operand 2 "" ""))
4600                       (pc)))]
4601   "(TARGET_H8300H || TARGET_H8300S)
4602    && peep2_reg_dead_p (1, operands[0])
4603    && ((INTVAL (operands[1]) | 0x00ff) == -1
4604         || (INTVAL (operands[1]) | 0xff00) == -1)
4605    && INTVAL (operands[1]) != -1
4606    && INTVAL (operands[1]) != -2"
4607   [(set (match_dup 0)
4608         (xor:SI (match_dup 0)
4609                 (match_dup 4)))
4610    (set (match_dup 0)
4611         (not:SI (match_dup 0)))
4612    (set (cc0)
4613         (match_dup 0))
4614    (set (pc)
4615         (if_then_else (match_op_dup 3 [(cc0) (const_int 0)])
4616                       (label_ref (match_dup 2))
4617                       (pc)))]
4618   "operands[4] = GEN_INT (INTVAL (operands[1]) ^ -1);")
4620 (define_peephole2
4621   [(set (cc0)
4622         (compare (match_operand:SI 0 "register_operand" "")
4623                  (match_operand:SI 1 "const_int_operand" "")))
4624    (set (pc)
4625         (if_then_else (match_operator 3 "eqne_operator"
4626                         [(cc0) (const_int 0)])
4627                       (label_ref (match_operand 2 "" ""))
4628                       (pc)))]
4629   "(TARGET_H8300H || TARGET_H8300S)
4630    && peep2_reg_dead_p (1, operands[0])
4631    && (INTVAL (operands[1]) == -2147483647 - 1
4632        || (TARGET_H8300S && INTVAL (operands[1]) == 1073741824))"
4633   [(set (match_dup 0)
4634         (rotate:SI (match_dup 0)
4635                    (match_dup 4)))
4636    (set (match_dup 0)
4637         (unspec:SI [(match_dup 0)
4638                     (const_int -1)]
4639                    UNSPEC_INCDEC))
4640    (set (cc0)
4641         (match_dup 0))
4642    (set (pc)
4643         (if_then_else (match_op_dup 3 [(cc0) (const_int 0)])
4644                       (label_ref (match_dup 2))
4645                       (pc)))]
4646   "operands[4] = GEN_INT (INTVAL (operands[1]) == -2147483647 - 1 ? 1 : 2);")
4648 ;; Transform
4650 ;;      cmp.l   #1,er0
4651 ;;      bhi     .L1
4653 ;; into
4655 ;;      mov.l   er0,er1
4656 ;;      shar.l  er1
4657 ;;      bne     .L1
4659 ;; We avoid this transformation if we see more than one copy of the
4660 ;; same compare insn immediately before this one.
4662 (define_peephole2
4663   [(match_scratch:SI 4 "r")
4664    (set (cc0)
4665         (compare (match_operand:SI 0 "register_operand" "")
4666                  (match_operand:SI 1 "const_int_operand" "")))
4667    (set (pc)
4668         (if_then_else (match_operator 2 "gtle_operator"
4669                         [(cc0) (const_int 0)])
4670                       (label_ref (match_operand 3 "" ""))
4671                       (pc)))]
4672   "(TARGET_H8300H || TARGET_H8300S)
4673    && !peep2_reg_dead_p (1, operands[0])
4674    && (INTVAL (operands[1]) == 1
4675         || (TARGET_H8300S && INTVAL (operands[1]) == 3))
4676    && !same_cmp_preceding_p (insn)"
4677   [(set (match_dup 4)
4678         (match_dup 0))
4679    (parallel [(set (match_dup 4)
4680                    (ashiftrt:SI (match_dup 4)
4681                                 (match_dup 6)))
4682               (clobber (scratch:QI))])
4683    (set (cc0)
4684         (match_dup 4))
4685    (set (pc)
4686         (if_then_else (match_dup 5)
4687                       (label_ref (match_dup 3))
4688                       (pc)))]
4689   "switch (GET_CODE (operands[2]))
4690      {
4691      case GTU:
4692        operands[5] = gen_rtx_NE (VOIDmode, cc0_rtx, const0_rtx);
4693        break;
4694      case LEU:
4695        operands[5] = gen_rtx_EQ (VOIDmode, cc0_rtx, const0_rtx);
4696        break;
4697      default:
4698        operands[5] = operands[2];
4699        break;
4700      }
4701    operands[6] = GEN_INT (exact_log2 (INTVAL (operands[1]) + 1));")
4703 ;; Transform
4705 ;;      cmp.l   #1,er0
4706 ;;      bhi     .L1
4708 ;; into
4710 ;;      shar.l  er0
4711 ;;      bne     .L1
4713 (define_peephole2
4714   [(set (cc0)
4715         (compare (match_operand:SI 0 "register_operand" "")
4716                  (match_operand:SI 1 "const_int_operand" "")))
4717    (set (pc)
4718         (if_then_else (match_operator 2 "gtle_operator"
4719                         [(cc0) (const_int 0)])
4720                       (label_ref (match_operand 3 "" ""))
4721                       (pc)))]
4722   "(TARGET_H8300H || TARGET_H8300S)
4723    && peep2_reg_dead_p (1, operands[0])
4724    && (INTVAL (operands[1]) == 1
4725         || (TARGET_H8300S && INTVAL (operands[1]) == 3))"
4726   [(parallel [(set (match_dup 0)
4727                    (ashiftrt:SI (match_dup 0)
4728                                 (match_dup 5)))
4729               (clobber (scratch:QI))])
4730    (set (cc0)
4731         (match_dup 0))
4732    (set (pc)
4733         (if_then_else (match_dup 4)
4734                       (label_ref (match_dup 3))
4735                       (pc)))]
4736   "switch (GET_CODE (operands[2]))
4737      {
4738      case GTU:
4739        operands[4] = gen_rtx_NE (VOIDmode, cc0_rtx, const0_rtx);
4740        break;
4741      case LEU:
4742        operands[4] = gen_rtx_EQ (VOIDmode, cc0_rtx, const0_rtx);
4743        break;
4744      default:
4745        operands[4] = operands[2];
4746        break;
4747      }
4748    operands[5] = GEN_INT (exact_log2 (INTVAL (operands[1]) + 1));")
4750 ;; Transform
4752 ;;      cmp.l   #15,er0
4753 ;;      bhi     .L1
4755 ;; into
4757 ;;      and     #240,r0l
4758 ;;      mov.l   er0,er0
4759 ;;      bne     .L1
4761 (define_peephole2
4762   [(set (cc0)
4763         (compare (match_operand:SI 0 "register_operand" "")
4764                  (match_operand:SI 1 "const_int_operand" "")))
4765    (set (pc)
4766         (if_then_else (match_operator 2 "gtle_operator"
4767                         [(cc0) (const_int 0)])
4768                       (label_ref (match_operand 3 "" ""))
4769                       (pc)))]
4770   "(TARGET_H8300H || TARGET_H8300S)
4771    && peep2_reg_dead_p (1, operands[0])
4772    && ((TARGET_H8300H && INTVAL (operands[1]) == 3)
4773        || INTVAL (operands[1]) == 7
4774        || INTVAL (operands[1]) == 15
4775        || INTVAL (operands[1]) == 31
4776        || INTVAL (operands[1]) == 63
4777        || INTVAL (operands[1]) == 127
4778        || INTVAL (operands[1]) == 255)"
4779   [(set (match_dup 0)
4780         (and:SI (match_dup 0)
4781                 (match_dup 5)))
4782    (set (cc0)
4783         (match_dup 0))
4784    (set (pc)
4785         (if_then_else (match_dup 4)
4786                       (label_ref (match_dup 3))
4787                       (pc)))]
4788   "switch (GET_CODE (operands[2]))
4789      {
4790      case GTU:
4791        operands[4] = gen_rtx_NE (VOIDmode, cc0_rtx, const0_rtx);
4792        break;
4793      case LEU:
4794        operands[4] = gen_rtx_EQ (VOIDmode, cc0_rtx, const0_rtx);
4795        break;
4796      default:
4797        operands[4] = operands[2];
4798        break;
4799      }
4800    operands[5] = GEN_INT (~INTVAL (operands[1]));")
4802 ;; Transform A <= 65535 to (A & 0xffff0000) == 0.
4804 (define_peephole2
4805   [(set (cc0)
4806         (compare (match_operand:SI 0 "register_operand" "")
4807                  (const_int 65535)))
4808    (set (pc)
4809         (if_then_else (match_operator 1 "gtle_operator"
4810                         [(cc0) (const_int 0)])
4811                       (label_ref (match_operand 2 "" ""))
4812                       (pc)))]
4813   "TARGET_H8300H || TARGET_H8300S"
4814   [(set (cc0)
4815         (and:SI (match_dup 0)
4816                 (const_int -65536)))
4817    (set (pc)
4818         (if_then_else (match_dup 3)
4819                       (label_ref (match_dup 2))
4820                       (pc)))]
4821   "switch (GET_CODE (operands[1]))
4822      {
4823      case GTU:
4824        operands[3] = gen_rtx_NE (VOIDmode, cc0_rtx, const0_rtx);
4825        break;
4826      case LEU:
4827        operands[3] = gen_rtx_EQ (VOIDmode, cc0_rtx, const0_rtx);
4828        break;
4829      default:
4830        operands[3] = operands[1];
4831        break;
4832      }")
4834 ;; For constants like -1, -2, 1, 2, it is still cheaper to make a copy
4835 ;; of the register being tested, do the subtraction on the copy, and
4836 ;; then test the copy.  We avoid this transformation if we see more
4837 ;; than one copy of the same compare insn.
4839 (define_peephole2
4840   [(match_scratch:SI 4 "r")
4841    (set (cc0)
4842         (compare (match_operand:SI 0 "register_operand" "")
4843                  (match_operand:SI 1 "incdec_operand" "")))
4844    (set (pc)
4845         (if_then_else (match_operator 3 "eqne_operator"
4846                         [(cc0) (const_int 0)])
4847                       (label_ref (match_operand 2 "" ""))
4848                       (pc)))]
4849   "(TARGET_H8300H || TARGET_H8300S)
4850    && !peep2_reg_dead_p (1, operands[0])
4851    && !same_cmp_following_p (insn)"
4852   [(set (match_dup 4)
4853         (match_dup 0))
4854    (set (match_dup 4)
4855         (unspec:SI [(match_dup 4)
4856                     (match_dup 5)]
4857                    UNSPEC_INCDEC))
4858    (set (cc0)
4859         (match_dup 4))
4860    (set (pc)
4861         (if_then_else (match_op_dup 3 [(cc0) (const_int 0)])
4862                       (label_ref (match_dup 2))
4863                       (pc)))]
4864   "operands[5] = GEN_INT (- INTVAL (operands[1]));")
4866 ;; Narrow the mode of testing if possible.
4868 (define_peephole2
4869   [(set (match_operand:HI 0 "register_operand" "")
4870         (and:HI (match_dup 0)
4871                 (match_operand:HI 1 "const_int_qi_operand" "")))
4872    (set (cc0)
4873         (match_dup 0))
4874    (set (pc)
4875         (if_then_else (match_operator 3 "eqne_operator"
4876                         [(cc0) (const_int 0)])
4877                       (label_ref (match_operand 2 "" ""))
4878                       (pc)))]
4879   "peep2_reg_dead_p (2, operands[0])"
4880   [(set (match_dup 4)
4881         (and:QI (match_dup 4)
4882                 (match_dup 5)))
4883    (set (cc0)
4884         (match_dup 4))
4885    (set (pc)
4886         (if_then_else (match_op_dup 3 [(cc0) (const_int 0)])
4887                       (label_ref (match_dup 2))
4888                       (pc)))]
4889   "operands[4] = gen_rtx_REG (QImode, REGNO (operands[0]));
4890    operands[5] = gen_int_mode (INTVAL (operands[1]), QImode);")
4892 (define_peephole2
4893   [(set (match_operand:SI 0 "register_operand" "")
4894         (and:SI (match_dup 0)
4895                 (match_operand:SI 1 "const_int_qi_operand" "")))
4896    (set (cc0)
4897         (match_dup 0))
4898    (set (pc)
4899         (if_then_else (match_operator 3 "eqne_operator"
4900                         [(cc0) (const_int 0)])
4901                       (label_ref (match_operand 2 "" ""))
4902                       (pc)))]
4903   "peep2_reg_dead_p (2, operands[0])"
4904   [(set (match_dup 4)
4905         (and:QI (match_dup 4)
4906                 (match_dup 5)))
4907    (set (cc0)
4908         (match_dup 4))
4909    (set (pc)
4910         (if_then_else (match_op_dup 3 [(cc0) (const_int 0)])
4911                       (label_ref (match_dup 2))
4912                       (pc)))]
4913   "operands[4] = gen_rtx_REG (QImode, REGNO (operands[0]));
4914    operands[5] = gen_int_mode (INTVAL (operands[1]), QImode);")
4916 (define_peephole2
4917   [(set (match_operand:SI 0 "register_operand" "")
4918         (and:SI (match_dup 0)
4919                 (match_operand:SI 1 "const_int_hi_operand" "")))
4920    (set (cc0)
4921         (match_dup 0))
4922    (set (pc)
4923         (if_then_else (match_operator 3 "eqne_operator"
4924                         [(cc0) (const_int 0)])
4925                       (label_ref (match_operand 2 "" ""))
4926                       (pc)))]
4927   "peep2_reg_dead_p (2, operands[0])"
4928   [(set (match_dup 4)
4929         (and:HI (match_dup 4)
4930                 (match_dup 5)))
4931    (set (cc0)
4932         (match_dup 4))
4933    (set (pc)
4934         (if_then_else (match_op_dup 3 [(cc0) (const_int 0)])
4935                       (label_ref (match_dup 2))
4936                       (pc)))]
4937   "operands[4] = gen_rtx_REG (HImode, REGNO (operands[0]));
4938    operands[5] = gen_int_mode (INTVAL (operands[1]), HImode);")
4940 (define_peephole2
4941   [(set (match_operand:SI 0 "register_operand" "")
4942         (and:SI (match_dup 0)
4943                 (match_operand:SI 1 "const_int_qi_operand" "")))
4944    (set (match_dup 0)
4945         (xor:SI (match_dup 0)
4946                 (match_operand:SI 2 "const_int_qi_operand" "")))
4947    (set (cc0)
4948         (match_dup 0))
4949    (set (pc)
4950         (if_then_else (match_operator 4 "eqne_operator"
4951                         [(cc0) (const_int 0)])
4952                       (label_ref (match_operand 3 "" ""))
4953                       (pc)))]
4954   "peep2_reg_dead_p (3, operands[0])
4955    && (~INTVAL (operands[1]) & INTVAL (operands[2])) == 0"
4956   [(set (match_dup 5)
4957         (and:QI (match_dup 5)
4958                 (match_dup 6)))
4959    (set (match_dup 5)
4960         (xor:QI (match_dup 5)
4961                 (match_dup 7)))
4962    (set (cc0)
4963         (match_dup 5))
4964    (set (pc)
4965         (if_then_else (match_op_dup 4 [(cc0) (const_int 0)])
4966                       (label_ref (match_dup 3))
4967                       (pc)))]
4968   "operands[5] = gen_rtx_REG (QImode, REGNO (operands[0]));
4969    operands[6] = gen_int_mode (INTVAL (operands[1]), QImode);
4970    operands[7] = gen_int_mode (INTVAL (operands[2]), QImode);")