* config/h8300/h8300.md (pushqi_h8300): Don't push the stack
[official-gcc.git] / gcc / config / h8300 / h8300.md
blob14e2c6c09724906ccad29e90c8c53a8c19f656ac
1 ;; GCC machine description for Hitachi H8/300
2 ;; Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 ;; 2001, 2002 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 GNU CC.
10 ;; GNU CC 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 ;; GNU CC 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 GNU CC; 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 ;; Some of the extend instructions accept a general_operand_src, which
26 ;; allows all the normal memory addressing modes.  The length computations
27 ;; don't take this into account.  The lengths in the MD file should be
28 ;; "worst case" and then be adjusted to their correct values by
29 ;; h8300_adjust_insn_length.
31 ;; On the H8/300H and H8S, adds/subs operate on the 32bit "er"
32 ;; registers.  Right now GCC doesn't expose the "e" half to the
33 ;; compiler, so using add/subs for addhi and subhi is safe.  Long
34 ;; term, we want to expose the "e" half to the compiler (gives us 8
35 ;; more 16bit registers).  At that point addhi and subhi can't use
36 ;; adds/subs.
38 ;; There's currently no way to have an insv/extzv expander for the H8/300H
39 ;; because word_mode is different for the H8/300 and H8/300H.
41 ;; Shifts/rotates by small constants should be handled by special
42 ;; patterns so we get the length and cc status correct.
44 ;; Bitfield operations no longer accept memory operands.  We need
45 ;; to add variants which operate on memory back to the MD.
47 ;; ??? Implement remaining bit ops available on the h8300
49 ;; ----------------------------------------------------------------------
50 ;; CONSTANTS
51 ;; ----------------------------------------------------------------------
53 (define_constants
54   [(SC_REG       3)
55    (FP_REG       6)
56    (SP_REG       7)
57    (MAC_REG      8)
58    (AP_REG       9)
59    (RAP_REG     10)])
61 ;; ----------------------------------------------------------------------
62 ;; ATTRIBUTES
63 ;; ----------------------------------------------------------------------
65 (define_attr "cpu" "h8300,h8300h"
66   (const (symbol_ref "cpu_type")))
68 (define_attr "type" "branch,arith"
69   (const_string "arith"))
71 ;; The size of instructions in bytes.
73 (define_attr "length" ""
74   (cond [(eq_attr "type" "branch")
75          (if_then_else (and (ge (minus (match_dup 0) (pc))
76                                 (const_int -126))
77                             (le (minus (match_dup 0) (pc))
78                                 (const_int 126)))
79                        (const_int 2)
80                        (if_then_else (and (eq_attr "cpu" "h8300h")
81                                           (and (ge (minus (pc) (match_dup 0))
82                                                    (const_int -32000))
83                                                (le (minus (pc) (match_dup 0))
84                                                    (const_int 32000))))
85                                      (const_int 4)
86                                      (const_int 6)))]
87         (const_int 200)))
89 ;; The necessity of instruction length adjustment.
91 (define_attr "adjust_length" "yes,no"
92   (cond [(eq_attr "type" "branch") (const_string "no")]
93         (const_string "yes")))
95 ;; Condition code settings.
97 ;; none - insn does not affect cc
98 ;; none_0hit - insn does not affect cc but it does modify operand 0
99 ;;      This attribute is used to keep track of when operand 0 changes.
100 ;;      See the description of NOTICE_UPDATE_CC for more info.
101 ;; set_znv - insn sets z,n,v to usable values (like a tst insn); c is unknown.
102 ;; set_zn  - insn sets z,n to usable values; v,c are unknown.
103 ;; compare - compare instruction
104 ;; clobber - value of cc is unknown
106 (define_attr "cc" "none,none_0hit,set_znv,set_zn,compare,clobber"
107   (const_string "clobber"))
109 ;; ----------------------------------------------------------------------
110 ;; MOVE INSTRUCTIONS
111 ;; ----------------------------------------------------------------------
113 ;; movqi
115 (define_insn "pushqi1_h8300"
116   [(parallel [(set (reg:HI SP_REG)
117                    (plus:HI (reg:HI SP_REG) (const_int -2)))
118               (set (mem:QI (plus:HI (reg:HI SP_REG) (const_int -1)))
119                    (match_operand:QI 0 "register_operand" "r"))])]
120   "TARGET_H8300
121    && REGNO (operands[0]) != SP_REG"
122   "mov.w\\t%T0,@-r7"
123   [(set_attr "length" "2")
124    (set_attr "cc" "clobber")])
126 (define_insn "pushqi1_h8300hs"
127   [(parallel [(set (reg:SI SP_REG)
128                    (plus:SI (reg:SI SP_REG) (const_int -4)))
129               (set (mem:QI (plus:SI (reg:SI SP_REG) (const_int -3)))
130                    (match_operand:QI 0 "register_operand" "r"))])]
131   "(TARGET_H8300H || TARGET_H8300S)
132    && REGNO (operands[0]) != SP_REG"
133   "mov.l\\t%S0,@-er7"
134   [(set_attr "length" "4")
135    (set_attr "cc" "clobber")])
137 (define_expand "pushqi1"
138   [(use (match_operand:QI 0 "register_operand" ""))]
139   ""
140   "
142   if (TARGET_H8300)
143     emit_insn (gen_pushqi1_h8300 (operands[0]));
144   else
145     emit_insn (gen_pushqi1_h8300hs (operands[0]));
146   DONE;
149 (define_insn ""
150   [(set (match_operand:QI 0 "general_operand_dst" "=r,r ,<,r,r,m")
151         (match_operand:QI 1 "general_operand_src" " I,r>,r,n,m,r"))]
152   "TARGET_H8300
153    && (register_operand (operands[0], QImode)
154        || register_operand (operands[1], QImode))"
155   "@
156    sub.b        %X0,%X0
157    mov.b        %R1,%X0
158    mov.b        %X1,%R0
159    mov.b        %R1,%X0
160    mov.b        %R1,%X0
161    mov.b        %X1,%R0"
162   [(set_attr "length" "2,2,2,2,4,4")
163    (set_attr "cc" "set_zn,set_znv,set_znv,set_znv,set_znv,set_znv")])
165 (define_insn ""
166   [(set (match_operand:QI 0 "general_operand_dst" "=r,r ,<,r,r,m")
167         (match_operand:QI 1 "general_operand_src" " I,r>,r,n,m,r"))]
168   "(TARGET_H8300H || TARGET_H8300S)
169    && (register_operand (operands[0], QImode)
170        || register_operand (operands[1], QImode))"
171   "@
172    sub.b        %X0,%X0
173    mov.b        %R1,%X0
174    mov.b        %X1,%R0
175    mov.b        %R1,%X0
176    mov.b        %R1,%X0
177    mov.b        %X1,%R0"
178   [(set_attr "length" "2,2,2,2,8,8")
179    (set_attr "cc" "set_zn,set_znv,set_znv,clobber,set_znv,set_znv")])
181 (define_expand "movqi"
182   [(set (match_operand:QI 0 "general_operand_dst" "")
183         (match_operand:QI 1 "general_operand_src" ""))]
184   ""
185   "
187   /* One of the ops has to be in a register.  */
188   if (!register_operand (operand0, QImode)
189       && !register_operand (operand1, QImode))
190     {
191       operands[1] = copy_to_mode_reg (QImode, operand1);
192     }
195 (define_insn "movstrictqi"
196   [(set (strict_low_part (match_operand:QI 0 "general_operand_dst" "+r,r,r,r"))
197                          (match_operand:QI 1 "general_operand_src" "I,r,n,m"))]
198   ""
199   "@
200    sub.b        %X0,%X0
201    mov.b        %X1,%X0
202    mov.b        %R1,%X0
203    mov.b        %R1,%X0"
204   [(set_attr_alternative "length"
205      [(const_int 2) (const_int 2) (const_int 2)
206       (if_then_else (eq_attr "cpu" "h8300") (const_int 4) (const_int 8))])
207    (set_attr "cc" "set_zn,set_znv,set_znv,set_znv")])
209 ;; movhi
211 (define_expand "pushhi1_h8300"
212   [(set (mem:HI (pre_dec:HI (reg:HI SP_REG)))
213         (match_operand:HI 0 "register_operand" ""))]
214   "TARGET_H8300
215    && REGNO (operands[0]) != SP_REG"
216   "")
218 (define_insn "pushhi1_h8300hs"
219   [(parallel [(set (reg:SI SP_REG)
220                    (plus:SI (reg:SI SP_REG) (const_int -4)))
221               (set (mem:HI (plus:SI (reg:SI SP_REG) (const_int -2)))
222                    (match_operand:HI 0 "register_operand" "r"))])]
223   "(TARGET_H8300H || TARGET_H8300S)
224    && REGNO (operands[0]) != SP_REG"
225   "mov.l\\t%S0,@-er7"
226   [(set_attr "length" "4")
227    (set_attr "cc" "clobber")])
229 (define_expand "pushhi1"
230   [(use (match_operand:HI 0 "register_operand" ""))]
231   ""
232   "
234   if (TARGET_H8300)
235     emit_insn (gen_pushhi1_h8300 (operands[0]));
236   else
237     emit_insn (gen_pushhi1_h8300hs (operands[0]));
238   DONE;
241 (define_insn ""
242   [(set (match_operand:HI 0 "general_operand_dst" "=r,r,<,r,r,m")
243         (match_operand:HI 1 "general_operand_src" "I,r>,r,i,m,r"))]
244   "TARGET_H8300
245    && (register_operand (operands[0], HImode)
246        || register_operand (operands[1], HImode))
247    && !(GET_CODE (operands[0]) == MEM
248         && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC
249         && GET_CODE (XEXP (XEXP (operands[0], 0), 0)) == REG
250         && GET_CODE (operands[1]) == REG
251         && REGNO (XEXP (XEXP (operands[0], 0), 0)) == REGNO (operands[1]))"
252   "@
253    sub.w        %T0,%T0
254    mov.w        %T1,%T0
255    mov.w        %T1,%T0
256    mov.w        %T1,%T0
257    mov.w        %T1,%T0
258    mov.w        %T1,%T0"
259   [(set_attr "length" "2,2,2,4,4,4")
260    (set_attr "cc" "set_zn,set_znv,set_znv,set_znv,set_znv,set_znv")])
262 (define_insn ""
263   [(set (match_operand:HI 0 "general_operand_dst" "=r,r,<,r,r,m")
264         (match_operand:HI 1 "general_operand_src" "I,r>,r,i,m,r"))]
265   "(TARGET_H8300H || TARGET_H8300S)
266    && (register_operand (operands[0], HImode)
267        || register_operand (operands[1], HImode))"
268   "@
269    sub.w        %T0,%T0
270    mov.w        %T1,%T0
271    mov.w        %T1,%T0
272    mov.w        %T1,%T0
273    mov.w        %T1,%T0
274    mov.w        %T1,%T0"
275   [(set_attr "length" "2,2,2,4,8,8")
276    (set_attr "cc" "set_zn,set_znv,set_znv,set_znv,set_znv,set_znv")])
278 (define_expand "movhi"
279   [(set (match_operand:HI 0 "general_operand_dst" "")
280         (match_operand:HI 1 "general_operand_src" ""))]
281   ""
282   "
284   /* One of the ops has to be in a register.  */
285   if (!register_operand (operand1, HImode)
286       && !register_operand (operand0, HImode))
287     {
288       operands[1] = copy_to_mode_reg (HImode, operand1);
289     }
292 (define_insn "movstricthi"
293   [(set (strict_low_part (match_operand:HI 0 "general_operand_dst" "+r,r,r,r"))
294                          (match_operand:HI 1 "general_operand_src" "I,r,i,m"))]
295   ""
296   "@
297    sub.w        %T0,%T0
298    mov.w        %T1,%T0
299    mov.w        %T1,%T0
300    mov.w        %T1,%T0"
301   [(set_attr_alternative "length"
302      [(const_int 2) (const_int 2) (const_int 4)
303       (if_then_else (eq_attr "cpu" "h8300") (const_int 4) (const_int 8))])
304    (set_attr "cc" "set_zn,set_znv,set_znv,set_znv")])
306 ;; movsi
308 (define_expand "movsi"
309   [(set (match_operand:SI 0 "general_operand_dst" "")
310         (match_operand:SI 1 "general_operand_src" ""))]
311   ""
312   "
314   if (TARGET_H8300)
315     {
316       if (do_movsi (operands))
317         DONE;
318     }
319   else
320     {
321       /* One of the ops has to be in a register.  */
322       if (!register_operand (operand1, SImode)
323           && !register_operand (operand0, SImode))
324         {
325           operands[1] = copy_to_mode_reg (SImode, operand1);
326         }
327     }
330 (define_expand "movsf"
331   [(set (match_operand:SF 0 "general_operand_dst" "")
332         (match_operand:SF 1 "general_operand_src" ""))]
333   ""
334   "
336   if (TARGET_H8300)
337     {
338       if (do_movsi (operands))
339         DONE;
340     }
341   else
342     {
343       /* One of the ops has to be in a register.  */
344       if (!register_operand (operand1, SFmode)
345           && !register_operand (operand0, SFmode))
346         {
347           operands[1] = copy_to_mode_reg (SFmode, operand1);
348         }
349     }
352 (define_insn "movsi_h8300"
353   [(set (match_operand:SI 0 "general_operand_dst" "=r,r,r,o,<,r")
354         (match_operand:SI 1 "general_operand_src" "I,r,io,r,r,>"))]
355   "TARGET_H8300
356    && (register_operand (operands[0], SImode)
357        || register_operand (operands[1], SImode))"
358   "*
360   unsigned int rn = -1;
361   switch (which_alternative)
362     {
363     case 0:
364       return \"sub.w    %e0,%e0\;sub.w  %f0,%f0\";
365     case 1:
366       if (REGNO (operands[0]) < REGNO (operands[1]))
367         return \"mov.w  %e1,%e0\;mov.w  %f1,%f0\";
368       else
369         return \"mov.w  %f1,%f0\;mov.w  %e1,%e0\";
370     case 2:
371       /* Make sure we don't trample the register we index with.  */
372       if (GET_CODE (operands[1]) == MEM)
373         {
374           rtx inside = XEXP (operands[1], 0);
375           if (REG_P (inside))
376             {
377               rn = REGNO (inside);
378             }
379           else if (GET_CODE (inside) == PLUS)
380             {
381               rtx lhs = XEXP (inside, 0);
382               rtx rhs = XEXP (inside, 1);
383               if (REG_P (lhs)) rn = REGNO (lhs);
384               if (REG_P (rhs)) rn = REGNO (rhs);
385             }
386         }
387       if (rn == REGNO (operands[0]))
388         {
389           /* Move the second word first.  */
390           return \"mov.w        %f1,%f0\;mov.w  %e1,%e0\";
391         }
392       else
393         {
394           /* See if either half is zero.  If so, use sub.w to clear
395              that half.  */
396           if (GET_CODE (operands[1]) == CONST_INT)
397             {
398               if ((INTVAL (operands[1]) & 0xffff) == 0)
399                 return \"mov.w  %e1,%e0\;sub.w  %f0,%f0\";
400               if (((INTVAL (operands[1]) >> 16) & 0xffff) == 0)
401                 return \"sub.w  %e0,%e0\;mov.w  %f1,%f0\";
402             }
403           return \"mov.w        %e1,%e0\;mov.w  %f1,%f0\";
404         }
405     case 3:
406       return \"mov.w    %e1,%e0\;mov.w  %f1,%f0\";
407     case 4:
408       return \"mov.w    %f1,%T0\;mov.w  %e1,%T0\";
409     case 5:
410       return \"mov.w    %T1,%e0\;mov.w  %T1,%f0\";
411     default:
412       abort ();
413     }
415   [(set_attr "length" "4,4,8,8,4,4")
416    (set_attr "cc" "clobber")])
418 (define_insn "movsf_h8300"
419   [(set (match_operand:SF 0 "general_operand_dst" "=r,r,r,o,<,r")
420         (match_operand:SF 1 "general_operand_src" "I,r,io,r,r,>"))]
421   "TARGET_H8300
422    && (register_operand (operands[0], SFmode)
423        || register_operand (operands[1], SFmode))"
424   "*
426   /* Copy of the movsi stuff.  */
427   unsigned int rn = -1;
428   switch (which_alternative)
429     {
430     case 0:
431       return \"sub.w    %e0,%e0\;sub.w  %f0,%f0\";
432     case 1:
433       if (REGNO (operands[0]) < REGNO (operands[1]))
434         return \"mov.w  %e1,%e0\;mov.w  %f1,%f0\";
435       else
436         return \"mov.w  %f1,%f0\;mov.w  %e1,%e0\";
437     case 2:
438       /* Make sure we don't trample the register we index with.  */
439       if (GET_CODE (operands[1]) == MEM)
440         {
441           rtx inside = XEXP (operands[1], 0);
442           if (REG_P (inside))
443             {
444               rn = REGNO (inside);
445             }
446           else if (GET_CODE (inside) == PLUS)
447             {
448               rtx lhs = XEXP (inside, 0);
449               rtx rhs = XEXP (inside, 1);
450               if (REG_P (lhs)) rn = REGNO (lhs);
451               if (REG_P (rhs)) rn = REGNO (rhs);
452             }
453         }
454       if (rn == REGNO (operands[0]))
455         /* Move the second word first.  */
456         return \"mov.w  %f1,%f0\;mov.w  %e1,%e0\";
457       else
458         /* Move the first word first.  */
459         return \"mov.w  %e1,%e0\;mov.w  %f1,%f0\";
461     case 3:
462       return \"mov.w    %e1,%e0\;mov.w  %f1,%f0\";
463     case 4:
464       return \"mov.w    %f1,%T0\;mov.w  %e1,%T0\";
465     case 5:
466       return \"mov.w    %T1,%e0\;mov.w  %T1,%f0\";
467     default:
468       abort ();
469     }
471   [(set_attr "length" "4,4,8,8,4,4")
472    (set_attr "cc" "clobber")])
474 (define_insn "movsi_h8300hs"
475   [(set (match_operand:SI 0 "general_operand_dst" "=r,r,r,<,r,r,m,*a,*a,r")
476         (match_operand:SI 1 "general_operand_src" "I,r,i,r,>,m,r,I,r,*a"))]
477   "(TARGET_H8300S || TARGET_H8300H)
478    && (register_operand (operands[0], SImode)
479        || register_operand (operands[1], SImode))
480    && !(GET_CODE (operands[0]) == MEM
481         && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC
482         && GET_CODE (XEXP (XEXP (operands[0], 0), 0)) == REG
483         && GET_CODE (operands[1]) == REG
484         && REGNO (XEXP (XEXP (operands[0], 0), 0)) == REGNO (operands[1]))"
485   "*
487   switch (which_alternative)
488     {
489     case 0:
490       return \"sub.l    %S0,%S0\";
491     case 7:
492       return \"clrmac\";
493     case 8:
494       return \"clrmac\;ldmac %1,macl\";
495     case 9:
496       return \"stmac    macl,%0\";
497     default:
498       if (GET_CODE (operands[1]) == CONST_INT)
499         {
500           int val = INTVAL (operands[1]);
502           /* Look for constants which can be made by adding an 8-bit
503              number to zero in one of the two low bytes.  */
504           if (val == (val & 0xff))
505             {
506               operands[1] = GEN_INT ((char) val & 0xff);
507               return \"sub.l\\t%S0,%S0\;add.b\\t%1,%w0\";
508             }
510           if (val == (val & 0xff00))
511             {
512               operands[1] = GEN_INT ((char) (val >> 8) & 0xff);
513               return \"sub.l\\t%S0,%S0\;add.b\\t%1,%x0\";
514             }
516           /* Look for constants that can be obtained by subs, inc, and
517              dec to 0.  */
518           switch (val & 0xffffffff)
519             {
520             case 0xffffffff:
521               return \"sub.l\\t%S0,%S0\;subs\\t#1,%S0\";
522             case 0xfffffffe:
523               return \"sub.l\\t%S0,%S0\;subs\\t#2,%S0\";
524             case 0xfffffffc:
525               return \"sub.l\\t%S0,%S0\;subs\\t#4,%S0\";
527             case 0x0000ffff:
528               return \"sub.l\\t%S0,%S0\;dec.w\\t#1,%f0\";
529             case 0x0000fffe:
530               return \"sub.l\\t%S0,%S0\;dec.w\\t#2,%f0\";
532             case 0xffff0000:
533               return \"sub.l\\t%S0,%S0\;dec.w\\t#1,%e0\";
534             case 0xfffe0000:
535               return \"sub.l\\t%S0,%S0\;dec.w\\t#2,%e0\";
537             case 0x00010000:
538               return \"sub.l\\t%S0,%S0\;inc.w\\t#1,%e0\";
539             case 0x00020000:
540               return \"sub.l\\t%S0,%S0\;inc.w\\t#2,%e0\";
541             }
542         }
543     }
544    return \"mov.l       %S1,%S0\";
546   [(set_attr "length" "2,2,6,4,4,10,10,2,6,4")
547    (set_attr "cc" "set_zn,set_znv,clobber,set_znv,set_znv,set_znv,set_znv,none_0hit,none_0hit,set_znv")])
549 (define_insn "movsf_h8300h"
550   [(set (match_operand:SF 0 "general_operand_dst" "=r,r,r,m,<,r")
551         (match_operand:SF 1 "general_operand_src" "I,r,im,r,r,>"))]
552   "(TARGET_H8300H || TARGET_H8300S)
553    && (register_operand (operands[0], SFmode)
554        || register_operand (operands[1], SFmode))"
555   "@
556    sub.l        %S0,%S0
557    mov.l        %S1,%S0
558    mov.l        %S1,%S0
559    mov.l        %S1,%S0
560    mov.l        %S1,%S0
561    mov.l        %S1,%S0"
562   [(set_attr "length" "2,2,10,10,4,4")
563    (set_attr "cc" "set_zn,set_znv,set_znv,set_znv,set_znv,set_znv")])
565 ;; ----------------------------------------------------------------------
566 ;; TEST INSTRUCTIONS
567 ;; ----------------------------------------------------------------------
569 (define_insn ""
570   [(set (cc0) (zero_extract:HI (match_operand:QI 0 "bit_memory_operand" "r,U")
571                                (const_int 1)
572                                (match_operand 1 "const_int_operand" "n,n")))]
573   "TARGET_H8300"
574   "btst %Z1,%Y0"
575   [(set_attr "length" "2,4")
576    (set_attr "cc" "set_zn,set_zn")])
578 (define_insn ""
579   [(set (cc0) (zero_extract:HI (match_operand:HI 0 "register_operand" "r")
580                                (const_int 1)
581                                (match_operand 1 "const_int_operand" "n")))]
582   "TARGET_H8300"
583   "btst %Z1,%Y0"
584   [(set_attr "length" "2")
585    (set_attr "cc" "set_zn")])
587 (define_insn "*tst_extzv_bitqi_1_n"
588   [(set (cc0) (zero_extract:SI (match_operand:QI 0 "bit_operand" "r,U")
589                                (const_int 1)
590                                (match_operand 1 "const_int_operand" "n,n")))]
591   "(TARGET_H8300H || TARGET_H8300S)
592    && INTVAL (operands[1]) != 7"
593   "btst %Z1,%Y0"
594   [(set_attr "length" "2,8")
595    (set_attr "cc" "set_zn,set_zn")])
597 (define_insn_and_split "*tst_extzv_memqi_1_n"
598   [(set (cc0) (zero_extract:SI (match_operand:QI 0 "memory_operand" "m")
599                                (const_int 1)
600                                (match_operand 1 "const_int_operand" "n")))
601    (clobber (match_scratch:QI 2 "=&r"))]
602   "(TARGET_H8300H || TARGET_H8300S)
603    && !EXTRA_CONSTRAINT (operands[0], 'U')
604    && INTVAL (operands[1]) != 7"
605   "#"
606   "&& reload_completed"
607   [(set (match_dup 2)
608         (match_dup 0))
609    (set (cc0) (zero_extract:SI (match_dup 2)
610                                (const_int 1)
611                                (match_dup 1)))]
612   "")
614 (define_insn ""
615   [(set (cc0) (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
616                                (const_int 1)
617                                (match_operand 1 "const_int_operand" "n")))]
618   "(TARGET_H8300H || TARGET_H8300S)
619    && INTVAL (operands[1]) <= 15"
620   "btst %Z1,%Y0"
621   [(set_attr "length" "2")
622    (set_attr "cc" "set_zn")])
624 (define_insn ""
625   [(set (cc0)
626         (and:HI (match_operand:HI 0 "register_operand" "r")
627                 (match_operand:HI 1 "single_one_operand" "n")))]
628   ""
629   "*
631   operands[1] = GEN_INT (INTVAL (operands[1]) & 0xffff);
632   if (INTVAL (operands[1]) > 128)
633     {
634       operands[1] = GEN_INT (INTVAL (operands[1]) >> 8);
635       return \"btst\\t%V1,%t0\";
636     }
637   return \"btst\\t%V1,%s0\";
639   [(set_attr "length" "2")
640    (set_attr "cc" "set_zn")])
642 (define_insn ""
643   [(set (cc0)
644         (and:SI (match_operand:SI 0 "register_operand" "r")
645                 (match_operand:SI 1 "single_one_operand" "n")))]
646   "(TARGET_H8300H || TARGET_H8300S)
647    && (INTVAL (operands[1]) & 0xffff) != 0"
648   "*
650   operands[1] = GEN_INT (INTVAL (operands[1]) & 0xffff);
651   if (INTVAL (operands[1]) > 128)
652     {
653       operands[1] = GEN_INT (INTVAL (operands[1]) >> 8);
654       return \"btst\\t%V1,%x0\";
655     }
656   return \"btst\\t%V1,%w0\";
658   [(set_attr "length" "2")
659    (set_attr "cc" "set_zn")])
661 (define_insn "tstqi"
662   [(set (cc0) (match_operand:QI 0 "register_operand" "r"))]
663   ""
664   "mov.b        %X0,%X0"
665   [(set_attr "length" "2")
666    (set_attr "cc" "set_znv")])
668 (define_insn "tsthi"
669   [(set (cc0) (match_operand:HI 0 "register_operand" "r"))]
670   ""
671   "mov.w        %T0,%T0"
672   [(set_attr "length" "2")
673    (set_attr "cc" "set_znv")])
675 (define_insn ""
676   [(set (cc0)
677         (and:HI (match_operand:HI 0 "register_operand" "r")
678                 (const_int -256)))]
679   ""
680   "mov.b        %t0,%t0"
681   [(set_attr "length" "2")
682    (set_attr "cc" "set_znv")])
684 (define_insn "tstsi"
685   [(set (cc0) (match_operand:SI 0 "register_operand" "r"))]
686   "TARGET_H8300H || TARGET_H8300S"
687   "mov.l        %S0,%S0"
688   [(set_attr "length" "2")
689    (set_attr "cc" "set_znv")])
691 (define_insn ""
692   [(set (cc0)
693         (and:SI (match_operand:SI 0 "register_operand" "r")
694                 (const_int -65536)))]
695   ""
696   "mov.w        %e0,%e0"
697   [(set_attr "length" "2")
698    (set_attr "cc" "set_znv")])
700 (define_insn "cmpqi"
701   [(set (cc0)
702         (compare:QI (match_operand:QI 0 "register_operand" "r")
703                     (match_operand:QI 1 "nonmemory_operand" "rn")))]
704   ""
705   "cmp.b        %X1,%X0"
706   [(set_attr "length" "2")
707    (set_attr "cc" "compare")])
709 (define_expand "cmphi"
710   [(set (cc0)
711         (compare:HI (match_operand:HI 0 "register_operand" "")
712                     (match_operand:HI 1 "nonmemory_operand" "")))]
713   ""
714   "
716   /* Force operand1 into a register if we're compiling
717      for the H8/300.  */
718   if (GET_CODE (operands[1]) != REG && TARGET_H8300)
719     operands[1] = force_reg (HImode, operands[1]);
722 (define_insn ""
723   [(set (cc0)
724         (compare:HI (match_operand:HI 0 "register_operand" "r")
725                     (match_operand:HI 1 "register_operand" "r")))]
726   "TARGET_H8300"
727   "cmp.w        %T1,%T0"
728   [(set_attr "length" "2")
729    (set_attr "cc" "compare")])
731 (define_insn ""
732   [(set (cc0)
733         (compare:HI (match_operand:HI 0 "register_operand" "r,r")
734                     (match_operand:HI 1 "nonmemory_operand" "r,n")))]
735   "TARGET_H8300H || TARGET_H8300S"
736   "cmp.w        %T1,%T0"
737   [(set_attr "length" "2,4")
738    (set_attr "cc" "compare,compare")])
740 (define_insn "cmpsi"
741   [(set (cc0)
742         (compare:SI (match_operand:SI 0 "register_operand" "r,r")
743                     (match_operand:SI 1 "nonmemory_operand" "r,i")))]
744   "TARGET_H8300H || TARGET_H8300S"
745   "cmp.l        %S1,%S0"
746   [(set_attr "length" "2,6")
747    (set_attr "cc" "compare,compare")])
749 ;; ----------------------------------------------------------------------
750 ;; ADD INSTRUCTIONS
751 ;; ----------------------------------------------------------------------
753 (define_insn "addqi3"
754   [(set (match_operand:QI 0 "register_operand" "=r")
755         (plus:QI (match_operand:QI 1 "register_operand" "%0")
756                  (match_operand:QI 2 "nonmemory_operand" "rn")))]
757   ""
758   "add.b        %X2,%X0"
759   [(set_attr "length" "2")
760    (set_attr "cc" "set_zn")])
762 (define_expand "addhi3"
763   [(set (match_operand:HI 0 "register_operand" "")
764         (plus:HI (match_operand:HI 1 "register_operand" "")
765                  (match_operand:HI 2 "nonmemory_operand" "")))]
766   ""
767   "")
769 (define_insn "*addhi3_h8300"
770   [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r")
771         (plus:HI (match_operand:HI 1 "register_operand" "%0,0,0,0,0")
772                  (match_operand:HI 2 "nonmemory_operand" "L,N,J,n,r")))]
773   "TARGET_H8300"
774   "@
775    adds %2,%T0
776    subs %G2,%T0
777    add.b        %t2,%t0
778    add.b        %s2,%s0\;addx   %t2,%t0
779    add.w        %T2,%T0"
780   [(set_attr "length" "2,2,2,4,2")
781    (set_attr "cc" "none_0hit,none_0hit,clobber,clobber,set_zn")])
783 (define_insn "*addhi3_h8300hs"
784   [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r")
785         (plus:HI (match_operand:HI 1 "register_operand" "%0,0,0,0,0")
786                  (match_operand:HI 2 "nonmemory_operand" "L,N,J,n,r")))]
787   "TARGET_H8300H || TARGET_H8300S"
788   "@
789    adds %2,%S0
790    subs %G2,%S0
791    add.b        %t2,%t0
792    add.w        %T2,%T0
793    add.w        %T2,%T0"
794   [(set_attr "length" "2,2,2,4,2")
795    (set_attr "cc" "none_0hit,none_0hit,clobber,set_zn,set_zn")])
797 (define_split
798   [(set (match_operand:HI 0 "register_operand" "")
799         (plus:HI (match_dup 0)
800                  (match_operand:HI 1 "two_insn_adds_subs_operand" "")))]
801   ""
802   [(const_int 0)]
803   "split_adds_subs (HImode, operands); DONE;")
805 (define_expand "addsi3"
806   [(set (match_operand:SI 0 "register_operand" "")
807         (plus:SI (match_operand:SI 1 "register_operand" "")
808                  (match_operand:SI 2 "nonmemory_operand" "")))]
809   ""
810   "")
812 (define_insn "addsi_h8300"
813   [(set (match_operand:SI 0 "register_operand" "=r,r,&r")
814         (plus:SI (match_operand:SI 1 "register_operand" "%0,0,r")
815                  (match_operand:SI 2 "nonmemory_operand" "n,r,r")))]
816   "TARGET_H8300"
817   "@
818    add  %w2,%w0\;addx   %x2,%x0\;addx   %y2,%y0\;addx   %z2,%z0
819    add.w        %f2,%f0\;addx   %y2,%y0\;addx   %z2,%z0
820    mov.w        %f1,%f0\;mov.w  %e1,%e0\;add.w  %f2,%f0\;addx   %y2,%y0\;addx   %z2,%z0"
821   [(set_attr "length" "8,6,10")
822    (set_attr "cc" "clobber")])
824 (define_insn "addsi_h8300h"
825   [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
826         (plus:SI (match_operand:SI 1 "register_operand" "%0,0,0,0")
827                  (match_operand:SI 2 "nonmemory_operand" "L,N,i,r")))]
828   "TARGET_H8300H || TARGET_H8300S"
829   "@
830    adds %2,%S0
831    subs %G2,%S0
832    add.l        %S2,%S0
833    add.l        %S2,%S0"
834   [(set_attr "length" "2,2,6,2")
835    (set_attr "cc" "none_0hit,none_0hit,set_zn,set_zn")])
837 (define_split
838   [(set (match_operand:SI 0 "register_operand" "")
839         (plus:SI (match_dup 0)
840                  (match_operand:SI 1 "two_insn_adds_subs_operand" "")))]
841   "TARGET_H8300H || TARGET_H8300S"
842   [(const_int 0)]
843   "split_adds_subs (SImode, operands); DONE;")
845 ;; ----------------------------------------------------------------------
846 ;; SUBTRACT INSTRUCTIONS
847 ;; ----------------------------------------------------------------------
849 (define_insn "subqi3"
850   [(set (match_operand:QI 0 "register_operand" "=r")
851         (minus:QI (match_operand:QI 1 "register_operand" "0")
852                   (match_operand:QI 2 "register_operand" "r")))]
853   ""
854   "sub.b        %X2,%X0"
855   [(set_attr "length" "2")
856    (set_attr "cc" "set_zn")])
858 (define_expand "subhi3"
859   [(set (match_operand:HI 0 "register_operand" "")
860         (minus:HI (match_operand:HI 1 "general_operand" "")
861                   (match_operand:HI 2 "nonmemory_operand" "")))]
862   ""
863   "")
865 (define_insn ""
866   [(set (match_operand:HI 0 "register_operand" "=r,&r")
867         (minus:HI (match_operand:HI 1 "general_operand" "0,0")
868                   (match_operand:HI 2 "nonmemory_operand" "r,n")))]
869   "TARGET_H8300"
870   "@
871    sub.w        %T2,%T0
872    add.b        %E2,%s0\;addx   %F2,%t0"
873   [(set_attr "length" "2,4")
874    (set_attr "cc" "set_zn,clobber")])
876 (define_insn ""
877   [(set (match_operand:HI 0 "register_operand" "=r,&r")
878         (minus:HI (match_operand:HI 1 "general_operand" "0,0")
879                   (match_operand:HI 2 "nonmemory_operand" "r,n")))]
880   "TARGET_H8300H || TARGET_H8300S"
881   "@
882    sub.w        %T2,%T0
883    sub.w        %T2,%T0"
884   [(set_attr "length" "2,4")
885    (set_attr "cc" "set_zn,set_zn")])
887 (define_expand "subsi3"
888   [(set (match_operand:SI 0 "register_operand" "")
889         (minus:SI (match_operand:SI 1 "register_operand" "")
890                   (match_operand:SI 2 "nonmemory_operand" "")))]
891   ""
892   "")
894 (define_insn "subsi3_h8300"
895   [(set (match_operand:SI 0 "register_operand" "=r")
896         (minus:SI (match_operand:SI 1 "register_operand" "0")
897                   (match_operand:SI 2 "register_operand" "r")))]
898   "TARGET_H8300"
899   "sub.w        %f2,%f0\;subx   %y2,%y0\;subx   %z2,%z0"
900   [(set_attr "length" "6")
901    (set_attr "cc" "clobber")])
903 (define_insn "subsi3_h8300h"
904   [(set (match_operand:SI 0 "register_operand" "=r,r")
905         (minus:SI (match_operand:SI 1 "general_operand" "0,0")
906                   (match_operand:SI 2 "nonmemory_operand" "r,i")))]
907   "TARGET_H8300H || TARGET_H8300S"
908   "@
909    sub.l        %S2,%S0
910    sub.l        %S2,%S0"
911   [(set_attr "length" "2,6")
912    (set_attr "cc" "set_zn,set_zn")])
914 ;; ----------------------------------------------------------------------
915 ;; MULTIPLY INSTRUCTIONS
916 ;; ----------------------------------------------------------------------
918 ;; Note that the H8/300 can only handle umulqihi3.
920 (define_insn "mulqihi3"
921   [(set (match_operand:HI 0 "register_operand" "=r")
922         (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "%0"))
923                  (sign_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
924   "TARGET_H8300H || TARGET_H8300S"
925   "mulxs.b      %X2,%T0"
926   [(set_attr "length" "4")
927    (set_attr "cc" "set_zn")])
929 (define_insn "mulhisi3"
930   [(set (match_operand:SI 0 "register_operand" "=r")
931         (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" "%0"))
932                  (sign_extend:SI (match_operand:HI 2 "register_operand" "r"))))]
933   "TARGET_H8300H || TARGET_H8300S"
934   "mulxs.w      %T2,%S0"
935   [(set_attr "length" "4")
936    (set_attr "cc" "set_zn")])
938 (define_insn "umulqihi3"
939   [(set (match_operand:HI 0 "register_operand" "=r")
940         (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "%0"))
941                  (zero_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
942   ""
943   "mulxu        %X2,%T0"
944   [(set_attr "length" "2")
945    (set_attr "cc" "none_0hit")])
947 (define_insn "umulhisi3"
948   [(set (match_operand:SI 0 "register_operand" "=r")
949         (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "%0"))
950                  (zero_extend:SI (match_operand:HI 2 "register_operand" "r"))))]
951   "TARGET_H8300H || TARGET_H8300S"
952   "mulxu.w      %T2,%S0"
953   [(set_attr "length" "2")
954    (set_attr "cc" "none_0hit")])
956 ;; This is a "bridge" instruction.  Combine can't cram enough insns
957 ;; together to crate a MAC instruction directly, but it can create
958 ;; this instruction, which then allows combine to create the real
959 ;; MAC insn.
961 ;; Unfortunately, if combine doesn't create a MAC instruction, this
962 ;; insn must generate reasonably correct code.  Egad.
963 (define_insn ""
964   [(set (match_operand:SI 0 "register_operand" "=a")
965         (mult:SI
966           (sign_extend:SI
967             (mem:HI (post_inc:SI (match_operand:SI 1 "register_operand" "r"))))
968           (sign_extend:SI
969             (mem:HI (post_inc:SI (match_operand:SI 2 "register_operand" "r"))))))]
970   "TARGET_MAC"
971   "clrmac\;mac  @%2+,@%1+"
972   [(set_attr "length" "6")
973    (set_attr "cc" "none_0hit")])
975 (define_insn ""
976   [(set (match_operand:SI 0 "register_operand" "=a")
977         (plus:SI (mult:SI
978           (sign_extend:SI (mem:HI
979             (post_inc:SI (match_operand:SI 1 "register_operand" "r"))))
980           (sign_extend:SI (mem:HI
981             (post_inc:SI (match_operand:SI 2 "register_operand" "r")))))
982               (match_operand:SI 3 "register_operand" "0")))]
983   "TARGET_MAC"
984   "mac  @%2+,@%1+"
985   [(set_attr "length" "4")
986    (set_attr "cc" "none_0hit")])
988 ;; ----------------------------------------------------------------------
989 ;; DIVIDE/MOD INSTRUCTIONS
990 ;; ----------------------------------------------------------------------
992 (define_insn "udivmodqi4"
993   [(set (match_operand:QI 0 "register_operand" "=r")
994         (truncate:QI
995           (udiv:HI
996             (match_operand:HI 1 "register_operand" "0")
997             (zero_extend:HI (match_operand:QI 2 "register_operand" "r")))))
998    (set (match_operand:QI 3 "register_operand" "=r")
999         (truncate:QI
1000           (umod:HI
1001             (match_dup 1)
1002             (zero_extend:HI (match_dup 2)))))]
1003   ""
1004   "*
1006   if (find_reg_note (insn, REG_UNUSED, operands[3]))
1007     return \"divxu.b\\t%X2,%T0\";
1008   else
1009     return \"divxu.b\\t%X2,%T0\;mov.b\\t%t0,%s3\";
1011   [(set_attr "length" "4")
1012    (set_attr "cc" "clobber")])
1014 (define_insn "divmodqi4"
1015   [(set (match_operand:QI 0 "register_operand" "=r")
1016         (truncate:QI
1017           (div:HI
1018             (match_operand:HI 1 "register_operand" "0")
1019             (sign_extend:HI (match_operand:QI 2 "register_operand" "r")))))
1020    (set (match_operand:QI 3 "register_operand" "=r")
1021         (truncate:QI
1022           (mod:HI
1023             (match_dup 1)
1024             (sign_extend:HI (match_dup 2)))))]
1025   "TARGET_H8300H || TARGET_H8300S"
1026   "*
1028   if (find_reg_note (insn, REG_UNUSED, operands[3]))
1029     return \"divxs.b\\t%X2,%T0\";
1030   else
1031     return \"divxs.b\\t%X2,%T0\;mov.b\\t%t0,%s3\";
1033   [(set_attr "length" "6")
1034    (set_attr "cc" "clobber")])
1036 (define_insn "udivmodhi4"
1037   [(set (match_operand:HI 0 "register_operand" "=r")
1038         (truncate:HI
1039           (udiv:SI
1040             (match_operand:SI 1 "register_operand" "0")
1041             (zero_extend:SI (match_operand:HI 2 "register_operand" "r")))))
1042    (set (match_operand:HI 3 "register_operand" "=r")
1043         (truncate:HI
1044           (umod:SI
1045             (match_dup 1)
1046             (zero_extend:SI (match_dup 2)))))]
1047   "TARGET_H8300H || TARGET_H8300S"
1048   "*
1050   if (find_reg_note (insn, REG_UNUSED, operands[3]))
1051     return \"divxu.w\\t%T2,%S0\";
1052   else
1053     return \"divxu.w\\t%T2,%S0\;mov.w\\t%e0,%f3\";
1055   [(set_attr "length" "4")
1056    (set_attr "cc" "clobber")])
1058 (define_insn "divmodhi4"
1059   [(set (match_operand:HI 0 "register_operand" "=r")
1060         (truncate:HI
1061           (div:SI
1062             (match_operand:SI 1 "register_operand" "0")
1063             (sign_extend:SI (match_operand:HI 2 "register_operand" "r")))))
1064    (set (match_operand:HI 3 "register_operand" "=r")
1065         (truncate:HI
1066           (mod:SI
1067             (match_dup 1)
1068             (sign_extend:SI (match_dup 2)))))]
1069   "TARGET_H8300H || TARGET_H8300S"
1070   "*
1072   if (find_reg_note (insn, REG_UNUSED, operands[3]))
1073     return \"divxs.w\\t%T2,%S0\";
1074   else
1075     return \"divxs.w\\t%T2,%S0\;mov.w\\t%e0,%f3\";
1077   [(set_attr "length" "6")
1078    (set_attr "cc" "clobber")])
1080 ;; ----------------------------------------------------------------------
1081 ;; AND INSTRUCTIONS
1082 ;; ----------------------------------------------------------------------
1084 (define_insn ""
1085   [(set (match_operand:QI 0 "bit_operand" "=r,U")
1086         (and:QI (match_operand:QI 1 "bit_operand" "%0,0")
1087                 (match_operand:QI 2 "nonmemory_operand" "rn,n")))]
1088   "register_operand (operands[0], QImode)
1089    || single_zero_operand (operands[2], QImode)"
1090   "@
1091    and  %X2,%X0
1092    bclr %W2,%R0"
1093   [(set_attr "length" "2,8")
1094    (set_attr "adjust_length" "no")
1095    (set_attr "cc" "set_znv,none_0hit")])
1097 (define_expand "andqi3"
1098   [(set (match_operand:QI 0 "bit_operand" "")
1099         (and:QI (match_operand:QI 1 "bit_operand" "")
1100                 (match_operand:QI 2 "nonmemory_operand" "")))]
1101   ""
1102   "
1104   if (fix_bit_operand (operands, 0, AND))
1105     DONE;
1108 (define_expand "andhi3"
1109   [(set (match_operand:HI 0 "register_operand" "")
1110         (and:HI (match_operand:HI 1 "register_operand" "")
1111                 (match_operand:HI 2 "nonmemory_operand" "")))]
1112   ""
1113   "")
1115 (define_insn "*andorqi3"
1116   [(set (match_operand:QI 0 "register_operand" "=r")
1117         (ior:QI (and:QI (match_operand:QI 2 "register_operand" "r")
1118                         (match_operand:QI 3 "single_one_operand" "n"))
1119                 (match_operand:QI 1 "register_operand" "0")))]
1120   ""
1121   "bld\\t%V3,%X2\;bor\\t%V3,%X0\;bst\\t%V3,%X0"
1122   [(set_attr "length" "6")
1123    (set_attr "cc" "clobber")])
1125 (define_insn "*andorhi3"
1126   [(set (match_operand:HI 0 "register_operand" "=r")
1127         (ior:HI (and:HI (match_operand:HI 2 "register_operand" "r")
1128                         (match_operand:HI 3 "single_one_operand" "n"))
1129                 (match_operand:HI 1 "register_operand" "0")))]
1130   ""
1131   "*
1133   operands[3] = GEN_INT (INTVAL (operands[3]) & 0xffff);
1134   if (INTVAL (operands[3]) > 128)
1135     {
1136       operands[3] = GEN_INT (INTVAL (operands[3]) >> 8);
1137       return \"bld\\t%V3,%t2\;bor\\t%V3,%t0\;bst\\t%V3,%t0\";
1138     }
1139   return \"bld\\t%V3,%s2\;bor\\t%V3,%s0\;bst\\t%V3,%s0\";
1141   [(set_attr "length" "6")
1142    (set_attr "cc" "clobber")])
1144 (define_insn "*andorsi3"
1145   [(set (match_operand:SI 0 "register_operand" "=r")
1146         (ior:SI (and:SI (match_operand:SI 2 "register_operand" "r")
1147                         (match_operand:SI 3 "single_one_operand" "n"))
1148                 (match_operand:SI 1 "register_operand" "0")))]
1149   "(INTVAL (operands[3]) & 0xffff) != 0"
1150   "*
1152   operands[3] = GEN_INT (INTVAL (operands[3]) & 0xffff);
1153   if (INTVAL (operands[3]) > 128)
1154     {
1155       operands[3] = GEN_INT (INTVAL (operands[3]) >> 8);
1156       return \"bld\\t%V3,%x2\;bor\\t%V3,%x0\;bst\\t%V3,%x0\";
1157     }
1158   return \"bld\\t%V3,%w2\;bor\\t%V3,%w0\;bst\\t%V3,%w0\";
1160   [(set_attr "length" "6")
1161    (set_attr "cc" "clobber")])
1163 (define_insn "*andorsi3_shift_8"
1164   [(set (match_operand:SI 0 "register_operand" "=r")
1165         (ior:SI (and:SI (ashift:SI (match_operand:SI 2 "register_operand" "r")
1166                                    (const_int 8))
1167                         (const_int 65280))
1168                 (match_operand:SI 1 "register_operand" "0")))]
1169   ""
1170   "or.b\\t%w2,%x0"
1171   [(set_attr "length" "2")
1172    (set_attr "cc" "clobber")])
1174 (define_expand "andsi3"
1175   [(set (match_operand:SI 0 "register_operand" "")
1176         (and:SI (match_operand:SI 1 "register_operand" "")
1177                 (match_operand:SI 2 "nonmemory_operand" "")))]
1178   ""
1179   "")
1181 ;; ----------------------------------------------------------------------
1182 ;; OR INSTRUCTIONS
1183 ;; ----------------------------------------------------------------------
1185 (define_insn ""
1186   [(set (match_operand:QI 0 "bit_operand" "=r,U")
1187         (ior:QI (match_operand:QI 1 "bit_operand" "%0,0")
1188                 (match_operand:QI 2 "nonmemory_operand" "rn,n")))]
1189   "register_operand (operands[0], QImode)
1190    || single_one_operand (operands[2], QImode)"
1191   "@
1192    or\\t%X2,%X0
1193    bset\\t%V2,%R0"
1194   [(set_attr "length" "2,8")
1195    (set_attr "adjust_length" "no")
1196    (set_attr "cc" "set_znv,none_0hit")])
1198 (define_expand "iorqi3"
1199   [(set (match_operand:QI 0 "bit_operand" "")
1200         (ior:QI (match_operand:QI 1 "bit_operand" "")
1201                 (match_operand:QI 2 "nonmemory_operand" "")))]
1202   ""
1203   "
1205   if (fix_bit_operand (operands, 1, IOR))
1206     DONE;
1209 (define_expand "iorhi3"
1210   [(set (match_operand:HI 0 "register_operand" "")
1211         (ior:HI (match_operand:HI 1 "register_operand" "")
1212                 (match_operand:HI 2 "nonmemory_operand" "")))]
1213   ""
1214   "")
1216 (define_expand "iorsi3"
1217   [(set (match_operand:SI 0 "register_operand" "")
1218         (ior:SI (match_operand:SI 1 "register_operand" "")
1219                 (match_operand:SI 2 "nonmemory_operand" "")))]
1220   ""
1221   "")
1223 ;; ----------------------------------------------------------------------
1224 ;; XOR INSTRUCTIONS
1225 ;; ----------------------------------------------------------------------
1227 (define_insn ""
1228   [(set (match_operand:QI 0 "bit_operand" "=r,U")
1229         (xor:QI (match_operand:QI 1 "bit_operand" "%0,0")
1230                 (match_operand:QI 2 "nonmemory_operand" "rn,n")))]
1231   "register_operand (operands[0], QImode)
1232    || single_one_operand (operands[2], QImode)"
1233   "@
1234    xor\\t%X2,%X0
1235    bnot\\t%V2,%R0"
1236   [(set_attr "length" "2,8")
1237    (set_attr "adjust_length" "no")
1238    (set_attr "cc" "set_znv,none_0hit")])
1240 (define_expand "xorqi3"
1241   [(set (match_operand:QI 0 "bit_operand" "")
1242         (xor:QI (match_operand:QI 1 "bit_operand" "")
1243                 (match_operand:QI 2 "nonmemory_operand" "")))]
1244   ""
1245   "
1247   if (fix_bit_operand (operands, 1, XOR))
1248     DONE;
1251 (define_expand "xorhi3"
1252   [(set (match_operand:HI 0 "register_operand" "")
1253         (xor:HI (match_operand:HI 1 "register_operand" "")
1254                 (match_operand:HI 2 "nonmemory_operand" "")))]
1255   ""
1256   "")
1258 (define_expand "xorsi3"
1259   [(set (match_operand:SI 0 "register_operand" "")
1260         (xor:SI (match_operand:SI 1 "register_operand" "")
1261                 (match_operand:SI 2 "nonmemory_operand" "")))]
1262   ""
1263   "")
1265 ;; ----------------------------------------------------------------------
1266 ;; {AND,IOR,XOR}{HI3,SI3} PATTERNS
1267 ;; ----------------------------------------------------------------------
1269 (define_insn ""
1270   [(set (match_operand:HI 0 "register_operand" "=r")
1271         (match_operator:HI 3 "bit_operator"
1272           [(match_operand:HI 1 "register_operand" "%0")
1273            (match_operand:HI 2 "nonmemory_operand" "rn")]))]
1274   ""
1275   "* return output_logical_op (HImode, operands);"
1276   [(set (attr "length")
1277         (symbol_ref "compute_logical_op_length (HImode, operands)"))
1278    (set (attr "cc")
1279         (symbol_ref "compute_logical_op_cc (HImode, operands)"))])
1281 (define_insn ""
1282   [(set (match_operand:SI 0 "register_operand" "=r")
1283         (match_operator:SI 3 "bit_operator"
1284           [(match_operand:SI 1 "register_operand" "%0")
1285            (match_operand:SI 2 "nonmemory_operand" "rn")]))]
1286   ""
1287   "* return output_logical_op (SImode, operands);"
1288   [(set (attr "length")
1289         (symbol_ref "compute_logical_op_length (SImode, operands)"))
1290    (set (attr "cc")
1291         (symbol_ref "compute_logical_op_cc (SImode, operands)"))])
1293 ;; ----------------------------------------------------------------------
1294 ;; NEGATION INSTRUCTIONS
1295 ;; ----------------------------------------------------------------------
1297 (define_insn "negqi2"
1298   [(set (match_operand:QI 0 "register_operand" "=r")
1299         (neg:QI (match_operand:QI 1 "register_operand" "0")))]
1300   ""
1301   "neg  %X0"
1302   [(set_attr "length" "2")
1303    (set_attr "cc" "set_zn")])
1305 (define_expand "neghi2"
1306   [(set (match_operand:HI 0 "register_operand" "")
1307         (neg:HI (match_operand:HI 1 "register_operand" "")))]
1308   ""
1309   "
1311   if (TARGET_H8300)
1312     {
1313       emit_insn (gen_neghi2_h8300 (operands[0], operands[1]));
1314       DONE;
1315     }
1318 (define_expand "neghi2_h8300"
1319   [(set (match_dup 2)
1320         (not:HI (match_operand:HI 1 "register_operand" "")))
1321    (set (match_dup 2) (plus:HI (match_dup 2) (const_int 1)))
1322    (set (match_operand:HI 0 "register_operand" "")
1323         (match_dup 2))]
1324   ""
1325   "operands[2] = gen_reg_rtx (HImode);")
1327 (define_insn "neghi2_h8300h"
1328   [(set (match_operand:HI 0 "register_operand" "=r")
1329         (neg:HI (match_operand:HI 1 "register_operand" "0")))]
1330   "TARGET_H8300H || TARGET_H8300S"
1331   "neg  %T0"
1332   [(set_attr "length" "2")
1333    (set_attr "cc" "set_zn")])
1335 (define_expand "negsi2"
1336   [(set (match_operand:SI 0 "register_operand" "")
1337         (neg:SI (match_operand:SI 1 "register_operand" "")))]
1338   ""
1339   "
1341   if (TARGET_H8300)
1342     {
1343       emit_insn (gen_negsi2_h8300 (operands[0], operands[1]));
1344       DONE;
1345     }
1348 (define_expand "negsi2_h8300"
1349   [(set (match_dup 2)
1350         (not:SI (match_operand:SI 1 "register_operand" "")))
1351    (set (match_dup 2) (plus:SI (match_dup 2) (const_int 1)))
1352    (set (match_operand:SI 0 "register_operand" "")
1353         (match_dup 2))]
1354   ""
1355   "operands[2] = gen_reg_rtx (SImode);")
1357 (define_insn "negsi2_h8300h"
1358   [(set (match_operand:SI 0 "register_operand" "=r")
1359         (neg:SI (match_operand:SI 1 "register_operand" "0")))]
1360   "TARGET_H8300H || TARGET_H8300S"
1361   "neg  %S0"
1362   [(set_attr "length" "2")
1363    (set_attr "cc" "set_zn")])
1365 ;; ----------------------------------------------------------------------
1366 ;; NOT INSTRUCTIONS
1367 ;; ----------------------------------------------------------------------
1369 (define_insn "one_cmplqi2"
1370   [(set (match_operand:QI 0 "register_operand" "=r")
1371         (not:QI (match_operand:QI 1 "register_operand" "0")))]
1372   ""
1373   "not  %X0"
1374   [(set_attr "length" "2")
1375    (set_attr "cc" "set_znv")])
1377 (define_expand "one_cmplhi2"
1378   [(set (match_operand:HI 0 "register_operand" "=r")
1379         (not:HI (match_operand:HI 1 "register_operand" "0")))]
1380   ""
1381   "")
1383 (define_insn ""
1384   [(set (match_operand:HI 0 "register_operand" "=r")
1385         (not:HI (match_operand:HI 1 "register_operand" "0")))]
1386   "TARGET_H8300"
1387   "not  %s0\;not        %t0"
1388   [(set_attr "cc" "clobber")
1389    (set_attr "length" "4")])
1391 (define_insn ""
1392   [(set (match_operand:HI 0 "register_operand" "=r")
1393         (not:HI (match_operand:HI 1 "register_operand" "0")))]
1394   "TARGET_H8300H || TARGET_H8300S"
1395   "not  %T0"
1396   [(set_attr "cc" "set_znv")
1397    (set_attr "length" "2")])
1399 (define_expand "one_cmplsi2"
1400   [(set (match_operand:SI 0 "register_operand" "=r")
1401         (not:SI (match_operand:SI 1 "register_operand" "0")))]
1402   ""
1403   "")
1405 (define_insn ""
1406   [(set (match_operand:SI 0 "register_operand" "=r")
1407         (not:SI (match_operand:SI 1 "register_operand" "0")))]
1408   "TARGET_H8300"
1409   "not  %w0\;not        %x0\;not        %y0\;not        %z0"
1410   [(set_attr "cc" "clobber")
1411    (set_attr "length" "8")])
1413 (define_insn ""
1414   [(set (match_operand:SI 0 "register_operand" "=r")
1415         (not:SI (match_operand:SI 1 "register_operand" "0")))]
1416   "TARGET_H8300H || TARGET_H8300S"
1417   "not  %S0"
1418   [(set_attr "cc" "set_znv")
1419    (set_attr "length" "2")])
1421 ;; ----------------------------------------------------------------------
1422 ;; JUMP INSTRUCTIONS
1423 ;; ----------------------------------------------------------------------
1425 ;; Conditional jump instructions
1427 (define_expand "ble"
1428   [(set (pc)
1429         (if_then_else (le (cc0)
1430                           (const_int 0))
1431                       (label_ref (match_operand 0 "" ""))
1432                       (pc)))]
1433   ""
1434   "")
1436 (define_expand "bleu"
1437   [(set (pc)
1438         (if_then_else (leu (cc0)
1439                            (const_int 0))
1440                       (label_ref (match_operand 0 "" ""))
1441                       (pc)))]
1442   ""
1443   "")
1445 (define_expand "bge"
1446   [(set (pc)
1447         (if_then_else (ge (cc0)
1448                           (const_int 0))
1449                       (label_ref (match_operand 0 "" ""))
1450                       (pc)))]
1451   ""
1452   "")
1454 (define_expand "bgeu"
1455   [(set (pc)
1456         (if_then_else (geu (cc0)
1457                            (const_int 0))
1458                       (label_ref (match_operand 0 "" ""))
1459                       (pc)))]
1460   ""
1461   "")
1463 (define_expand "blt"
1464   [(set (pc)
1465         (if_then_else (lt (cc0)
1466                           (const_int 0))
1467                       (label_ref (match_operand 0 "" ""))
1468                       (pc)))]
1469   ""
1470   "")
1472 (define_expand "bltu"
1473   [(set (pc)
1474         (if_then_else (ltu (cc0)
1475                            (const_int 0))
1476                       (label_ref (match_operand 0 "" ""))
1477                       (pc)))]
1478   ""
1479   "")
1481 (define_expand "bgt"
1482   [(set (pc)
1483         (if_then_else (gt (cc0)
1484                           (const_int 0))
1485                       (label_ref (match_operand 0 "" ""))
1486                       (pc)))]
1487   ""
1488   "")
1490 (define_expand "bgtu"
1491   [(set (pc)
1492         (if_then_else (gtu (cc0)
1493                            (const_int 0))
1494                       (label_ref (match_operand 0 "" ""))
1495                       (pc)))]
1496   ""
1497   "")
1499 (define_expand "beq"
1500   [(set (pc)
1501         (if_then_else (eq (cc0)
1502                           (const_int 0))
1503                       (label_ref (match_operand 0 "" ""))
1504                       (pc)))]
1505   ""
1506   "")
1508 (define_expand "bne"
1509   [(set (pc)
1510         (if_then_else (ne (cc0)
1511                           (const_int 0))
1512                       (label_ref (match_operand 0 "" ""))
1513                       (pc)))]
1514   ""
1515   "")
1517 (define_insn "branch_true"
1518   [(set (pc)
1519         (if_then_else (match_operator 1 "comparison_operator"
1520                                       [(cc0) (const_int 0)])
1521                       (label_ref (match_operand 0 "" ""))
1522                       (pc)))]
1523   ""
1524   "*
1526   if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0
1527       && (GET_CODE (operands[1]) == GT
1528           || GET_CODE (operands[1]) == GE
1529           || GET_CODE (operands[1]) == LE
1530           || GET_CODE (operands[1]) == LT))
1531     {
1532       cc_status.flags &= ~CC_OVERFLOW_UNUSABLE;
1533       return 0;
1534     }
1536   if (get_attr_length (insn) == 2)
1537     return \"b%j1       %l0\";
1538   else if (get_attr_length (insn) == 4)
1539     return \"b%j1       %l0:16\";
1540   else
1541     return \"b%k1       .Lh8BR%=\;jmp   @%l0\\n.Lh8BR%=:\";
1543  [(set_attr "type" "branch")
1544    (set_attr "cc" "none")])
1546 (define_insn "branch_false"
1547   [(set (pc)
1548         (if_then_else (match_operator 1 "comparison_operator"
1549                                       [(cc0) (const_int 0)])
1550                       (pc)
1551                       (label_ref (match_operand 0 "" ""))))]
1552   ""
1553   "*
1555   if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0
1556       && (GET_CODE (operands[1]) == GT
1557           || GET_CODE (operands[1]) == GE
1558           || GET_CODE (operands[1]) == LE
1559           || GET_CODE (operands[1]) == LT))
1560     {
1561       cc_status.flags &= ~CC_OVERFLOW_UNUSABLE;
1562       return 0;
1563     }
1565   if (get_attr_length (insn) == 2)
1566     return \"b%k1       %l0\";
1567   else if (get_attr_length (insn) == 4)
1568     return \"b%k1       %l0:16\";
1569   else
1570     return \"b%j1       .Lh8BR%=\;jmp   @%l0\\n.Lh8BR%=:\";
1572   [(set_attr "type" "branch")
1573    (set_attr "cc" "none")])
1575 ;; Unconditional and other jump instructions.
1577 (define_insn "jump"
1578   [(set (pc)
1579         (label_ref (match_operand 0 "" "")))]
1580   ""
1581   "*
1583   if (get_attr_length (insn) == 2)
1584     return \"bra        %l0\";
1585   else if (get_attr_length (insn) == 4)
1586     return \"bra        %l0:16\";
1587   else
1588     return \"jmp        @%l0\";
1590   [(set_attr "type" "branch")
1591    (set_attr "cc" "none")])
1593 ;; This is a define expand, because pointers may be either 16 or 32 bits.
1595 (define_expand "tablejump"
1596   [(parallel [(set (pc) (match_operand 0 "register_operand" ""))
1597               (use (label_ref (match_operand 1 "" "")))])]
1598   ""
1599   "")
1601 (define_insn "tablejump_h8300"
1602   [(set (pc) (match_operand:HI 0 "register_operand" "r"))
1603    (use (label_ref (match_operand 1 "" "")))]
1604   "TARGET_H8300"
1605   "jmp  @%0"
1606   [(set_attr "cc" "none")
1607    (set_attr "length" "2")])
1609 (define_insn "tablejump_h8300h"
1610   [(set (pc) (match_operand:SI 0 "register_operand" "r"))
1611    (use (label_ref (match_operand 1 "" "")))]
1612   "TARGET_H8300H || TARGET_H8300S"
1613   "jmp  @%0"
1614   [(set_attr "cc" "none")
1615    (set_attr "length" "2")])
1617 (define_insn "tablejump_normal_mode"
1618    [(set (pc) (match_operand:HI 0 "register_operand" "r"))
1619     (use (label_ref (match_operand 1 "" "")))]
1620    "(TARGET_H8300H || TARGET_H8300S) && TARGET_NORMAL_MODE"
1621    "jmp @%S0"
1622    [(set_attr "cc" "none")
1623     (set_attr "length" "2")])
1625 ;; This is a define expand, because pointers may be either 16 or 32 bits.
1627 (define_expand "indirect_jump"
1628   [(set (pc) (match_operand 0 "jump_address_operand" ""))]
1629   ""
1630   "")
1632 (define_insn "indirect_jump_h8300"
1633   [(set (pc) (match_operand:HI 0 "jump_address_operand" "Vr"))]
1634   "TARGET_H8300"
1635   "jmp  @%0"
1636   [(set_attr "cc" "none")
1637    (set_attr "length" "2")])
1639 (define_insn "indirect_jump_h8300h"
1640   [(set (pc) (match_operand:SI 0 "jump_address_operand" "Vr"))]
1641   "TARGET_H8300H || TARGET_H8300S"
1642   "jmp @%0"
1643   [(set_attr "cc" "none")
1644    (set_attr "length" "2")])
1646 (define_insn "indirect_jump_normal_mode"
1647   [(set (pc) (match_operand:HI 0 "jump_address_operand" "Vr"))]
1648   "(TARGET_H8300H || TARGET_H8300S) && TARGET_NORMAL_MODE"
1649   "jmp @%S0"
1650   [(set_attr "cc" "none")
1651    (set_attr "length" "2")])
1653 ;; Call subroutine with no return value.
1655 ;; ??? Even though we use HImode here, this works on the H8/300H and H8S.
1657 (define_insn "call"
1658   [(call (match_operand:QI 0 "call_insn_operand" "or")
1659          (match_operand:HI 1 "general_operand" "g"))]
1660   ""
1661   "*
1663   if (GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
1664       && SYMBOL_REF_FLAG (XEXP (operands[0], 0)))
1665     return \"jsr\\t@%0:8\";
1666   else
1667     return \"jsr\\t%0\";
1669   [(set_attr "cc" "clobber")
1670    (set (attr "length")
1671         (if_then_else (match_operand:QI 0 "small_call_insn_operand" "")
1672                       (const_int 4)
1673                       (const_int 8)))])
1675 ;; Call subroutine, returning value in operand 0
1676 ;; (which must be a hard register).
1678 ;; ??? Even though we use HImode here, this works on the H8/300H and H8S.
1680 (define_insn "call_value"
1681   [(set (match_operand 0 "" "=r")
1682         (call (match_operand:QI 1 "call_insn_operand" "or")
1683               (match_operand:HI 2 "general_operand" "g")))]
1684   ""
1685   "*
1687   if (GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
1688       && SYMBOL_REF_FLAG (XEXP (operands[1], 0)))
1689     return \"jsr\\t@%1:8\";
1690   else
1691     return \"jsr\\t%1\";
1693   [(set_attr "cc" "clobber")
1694    (set (attr "length")
1695         (if_then_else (match_operand:QI 0 "small_call_insn_operand" "")
1696                       (const_int 4)
1697                       (const_int 8)))])
1699 (define_insn "nop"
1700   [(const_int 0)]
1701   ""
1702   "nop"
1703   [(set_attr "cc" "none")
1704    (set_attr "length" "2")])
1706 ;; ----------------------------------------------------------------------
1707 ;; PROLOGUE/EPILOGUE-RELATED INSTRUCTIONS
1708 ;; ----------------------------------------------------------------------
1710 (define_insn "*stm_h8300s_2"
1711   [(parallel
1712      [(set (reg:SI SP_REG)
1713            (plus:SI (reg:SI SP_REG) (const_int -8)))
1714       (set (mem:SI (plus:SI (reg:SI SP_REG) (const_int -4)))
1715            (match_operand:SI 0 "register_operand" ""))
1716       (set (mem:SI (plus:SI (reg:SI SP_REG) (const_int -8)))
1717            (match_operand:SI 1 "register_operand" ""))])]
1718   "TARGET_H8300S
1719    && ((REGNO (operands[0]) == 0 && REGNO (operands[1]) == 1)
1720        || (REGNO (operands[0]) == 2 && REGNO (operands[1]) == 3)
1721        || (REGNO (operands[0]) == 4 && REGNO (operands[1]) == 5))"
1722   "stm.l\\t%S0-%S1,@-er7"
1723   [(set_attr "cc" "none")
1724    (set_attr "length" "4")])
1726 (define_insn "*stm_h8300s_3"
1727   [(parallel
1728      [(set (reg:SI SP_REG)
1729            (plus:SI (reg:SI SP_REG) (const_int -12)))
1730       (set (mem:SI (plus:SI (reg:SI SP_REG) (const_int -4)))
1731            (match_operand:SI 0 "register_operand" ""))
1732       (set (mem:SI (plus:SI (reg:SI SP_REG) (const_int -8)))
1733            (match_operand:SI 1 "register_operand" ""))
1734       (set (mem:SI (plus:SI (reg:SI SP_REG) (const_int -12)))
1735            (match_operand:SI 2 "register_operand" ""))])]
1736   "TARGET_H8300S
1737    && ((REGNO (operands[0]) == 0
1738         && REGNO (operands[1]) == 1
1739         && REGNO (operands[2]) == 2)
1740        || (REGNO (operands[0]) == 4
1741            && REGNO (operands[1]) == 5
1742            && REGNO (operands[2]) == 6))"
1743   "stm.l\\t%S0-%S2,@-er7"
1744   [(set_attr "cc" "none")
1745    (set_attr "length" "4")])
1747 (define_insn "*stm_h8300s_4"
1748   [(parallel
1749      [(set (reg:SI SP_REG)
1750            (plus:SI (reg:SI SP_REG) (const_int -16)))
1751       (set (mem:SI (plus:SI (reg:SI SP_REG) (const_int -4)))
1752            (match_operand:SI 0 "register_operand" ""))
1753       (set (mem:SI (plus:SI (reg:SI SP_REG) (const_int -8)))
1754            (match_operand:SI 1 "register_operand" ""))
1755       (set (mem:SI (plus:SI (reg:SI SP_REG) (const_int -12)))
1756            (match_operand:SI 2 "register_operand" ""))
1757       (set (mem:SI (plus:SI (reg:SI SP_REG) (const_int -16)))
1758            (match_operand:SI 3 "register_operand" ""))])]
1759   "TARGET_H8300S
1760    && REGNO (operands[0]) == 0
1761    && REGNO (operands[1]) == 1
1762    && REGNO (operands[2]) == 2
1763    && REGNO (operands[3]) == 3"
1764   "stm.l\\t%S0-%S3,@-er7"
1765   [(set_attr "cc" "none")
1766    (set_attr "length" "4")])
1768 ;; ----------------------------------------------------------------------
1769 ;; EXTEND INSTRUCTIONS
1770 ;; ----------------------------------------------------------------------
1772 (define_expand "zero_extendqihi2"
1773   [(set (match_operand:HI 0 "register_operand" "")
1774         (zero_extend:HI (match_operand:QI 1 "general_operand_src" "")))]
1775   ""
1776   "")
1778 (define_insn ""
1779   [(set (match_operand:HI 0 "register_operand" "=r,r")
1780         (zero_extend:HI (match_operand:QI 1 "general_operand_src" "0,g>")))]
1781   "TARGET_H8300"
1782   "@
1783   mov.b #0,%t0
1784   mov.b %R1,%s0\;mov.b  #0,%t0"
1785   [(set_attr "length" "2,10")
1786    (set_attr "cc" "clobber,clobber")])
1788 (define_insn ""
1789   [(set (match_operand:HI 0 "register_operand" "=r,r")
1790         (zero_extend:HI (match_operand:QI 1 "general_operand_src" "0,g>")))]
1791   "TARGET_H8300H || TARGET_H8300S"
1792   "@
1793   extu.w        %T0
1794   mov.b %R1,%s0\;extu.w %T0"
1795   [(set_attr "length" "2,10")
1796    (set_attr "cc" "set_znv,set_znv")])
1798 ;; The compiler can synthesize a H8/300H variant of this which is
1799 ;; just as efficient as one that we'd create
1800 (define_insn "zero_extendqisi2"
1801   [(set (match_operand:SI 0 "register_operand" "=r,r")
1802         (zero_extend:SI (match_operand:QI 1 "general_operand_src" "0,g>")))]
1803   "TARGET_H8300"
1804   "@
1805   mov.b #0,%x0\;sub.w   %e0,%e0
1806   mov.b %R1,%w0\;mov.b  #0,%x0\;sub.w   %e0,%e0"
1807   [(set_attr "length" "4,6")
1808    (set_attr "cc" "clobber,clobber")])
1810 (define_expand "zero_extendhisi2"
1811   [(set (match_operand:SI 0 "register_operand" "")
1812         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
1813   ""
1814   "")
1816 ;; %e prints the high part of a CONST_INT, not the low part.  Arggh.
1817 (define_insn ""
1818   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
1819         (zero_extend:SI (match_operand:HI 1 "general_operand_src" "0,i,g>")))]
1820   "TARGET_H8300"
1821   "@
1822   sub.w %e0,%e0
1823   mov.w %f1,%f0\;sub.w  %e0,%e0
1824   mov.w %e1,%f0\;sub.w  %e0,%e0"
1825   [(set_attr "length" "2,4,4")
1826    (set_attr "cc" "clobber,clobber,clobber")])
1828 (define_insn ""
1829   [(set (match_operand:SI 0 "register_operand" "=r")
1830         (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))]
1831   "TARGET_H8300H || TARGET_H8300S"
1832   "extu.l       %S0"
1833   [(set_attr "length" "2")
1834    (set_attr "cc" "set_znv")])
1836 (define_expand "extendqihi2"
1837   [(set (match_operand:HI 0 "register_operand" "")
1838         (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
1839   ""
1840   "")
1842 (define_insn ""
1843   [(set (match_operand:HI 0 "register_operand" "=r,r")
1844         (sign_extend:HI (match_operand:QI 1 "general_operand_src" "0,g>")))]
1845   "TARGET_H8300"
1846   "@
1847   bld   #7,%s0\;subx    %t0,%t0
1848   mov.b %R1,%s0\;bld    #7,%s0\;subx    %t0,%t0"
1849   [(set_attr "length" "4,8")
1850    (set_attr "cc" "clobber,clobber")])
1852 (define_insn ""
1853   [(set (match_operand:HI 0 "register_operand" "=r")
1854         (sign_extend:HI (match_operand:QI 1 "register_operand" "0")))]
1855   "TARGET_H8300H || TARGET_H8300S"
1856   "exts.w       %T0"
1857   [(set_attr "length" "2")
1858    (set_attr "cc" "set_znv")])
1860 ;; The compiler can synthesize a H8/300H variant of this which is
1861 ;; just as efficient as one that we'd create
1862 (define_insn "extendqisi2"
1863   [(set (match_operand:SI 0 "register_operand" "=r,r")
1864         (sign_extend:SI (match_operand:QI 1 "general_operand_src" "0,g>")))]
1865   "TARGET_H8300"
1866   "@
1867   bld   #7,%w0\;subx    %x0,%x0\;subx   %y0,%y0\;subx   %z0,%z0
1868   mov.b %R1,%w0\;bld    #7,%w0\;subx    %x0,%x0\;subx   %y0,%y0\;subx   %z0,%z0"
1869   [(set_attr "length" "8,10")
1870    (set_attr "cc" "clobber,clobber")])
1872 (define_expand "extendhisi2"
1873   [(set (match_operand:SI 0 "register_operand" "")
1874         (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
1875   ""
1876   "")
1878 (define_insn ""
1879   [(set (match_operand:SI 0 "register_operand" "=r,r")
1880         (sign_extend:SI (match_operand:HI 1 "general_operand_src" "0,g>")))]
1881   "TARGET_H8300"
1882   "@
1883   bld   #7,%x0\;subx    %y0,%y0\;subx   %z0,%z0
1884   mov.w %T1,%f0\;bld    #7,%x0\;subx    %y0,%y0\;subx   %z0,%z0"
1885   [(set_attr "length" "6,8")
1886    (set_attr "cc" "clobber,clobber")])
1888 (define_insn ""
1889   [(set (match_operand:SI 0 "register_operand" "=r")
1890         (sign_extend:SI (match_operand:HI 1 "register_operand" "0")))]
1891   "TARGET_H8300H || TARGET_H8300S"
1892   "exts.l       %S0"
1893   [(set_attr "length" "2")
1894    (set_attr "cc" "set_znv")])
1896 ;; ----------------------------------------------------------------------
1897 ;; SHIFTS
1898 ;; ----------------------------------------------------------------------
1900 ;; We make some attempt to provide real efficient shifting.  One example is
1901 ;; doing an 8 bit shift of a 16 bit value by moving a byte reg into the other
1902 ;; reg and moving 0 into the former reg.
1904 ;; We also try to achieve this in a uniform way.  IE: We don't try to achieve
1905 ;; this in both rtl and at insn emit time.  Ideally, we'd use rtl as that would
1906 ;; give the optimizer more cracks at the code.  However, we wish to do things
1907 ;; like optimizing shifting the sign bit to bit 0 by rotating the other way.
1908 ;; There is rtl to handle this (rotate + and), but the H8/300 doesn't handle
1909 ;; 16 bit rotates.  Also, if we emit complicated rtl, combine may not be able
1910 ;; to detect cases it can optimize.
1912 ;; For these and other fuzzy reasons, I've decided to go the less pretty but
1913 ;; easier "do it at insn emit time" route.
1915 ;; QI BIT SHIFTS
1917 (define_expand "ashlqi3"
1918   [(set (match_operand:QI 0 "register_operand" "")
1919         (ashift:QI (match_operand:QI 1 "register_operand" "")
1920                    (match_operand:QI 2 "nonmemory_operand" "")))]
1921   ""
1922   "if (expand_a_shift (QImode, ASHIFT, operands)) DONE; else FAIL;")
1924 (define_expand "ashrqi3"
1925   [(set (match_operand:QI 0 "register_operand" "")
1926         (ashiftrt:QI (match_operand:QI 1 "register_operand" "")
1927                      (match_operand:QI 2 "nonmemory_operand" "")))]
1928   ""
1929   "if (expand_a_shift (QImode, ASHIFTRT, operands)) DONE; else FAIL;")
1931 (define_expand "lshrqi3"
1932   [(set (match_operand:QI 0 "register_operand" "")
1933         (lshiftrt:QI (match_operand:QI 1 "register_operand" "")
1934                      (match_operand:QI 2 "nonmemory_operand" "")))]
1935   ""
1936   "if (expand_a_shift (QImode, LSHIFTRT, operands)) DONE; else FAIL;")
1938 (define_insn ""
1939   [(set (match_operand:QI 0 "register_operand" "=r,r")
1940         (match_operator:QI 3 "nshift_operator"
1941                         [ (match_operand:QI 1 "register_operand" "0,0")
1942                           (match_operand:QI 2 "nonmemory_operand" "R,rn")]))
1943    (clobber (match_scratch:QI 4 "=X,&r"))]
1944   ""
1945   "* return output_a_shift (operands);"
1946   [(set (attr "length")
1947         (symbol_ref "compute_a_shift_length (insn, operands)"))
1948    (set_attr "cc" "clobber")])
1950 ;; HI BIT SHIFTS
1952 (define_expand "ashlhi3"
1953   [(set (match_operand:HI 0 "register_operand" "")
1954         (ashift:HI (match_operand:HI 1 "nonmemory_operand" "")
1955                    (match_operand:QI 2 "nonmemory_operand" "")))]
1956   ""
1957   "if (expand_a_shift (HImode, ASHIFT, operands)) DONE; else FAIL;")
1959 (define_expand "lshrhi3"
1960   [(set (match_operand:HI 0 "register_operand" "")
1961         (lshiftrt:HI (match_operand:HI 1 "general_operand" "")
1962                      (match_operand:QI 2 "nonmemory_operand" "")))]
1963   ""
1964   "if (expand_a_shift (HImode, LSHIFTRT, operands)) DONE; else FAIL;")
1966 (define_expand "ashrhi3"
1967   [(set (match_operand:HI 0 "register_operand" "")
1968         (ashiftrt:HI (match_operand:HI 1 "register_operand" "")
1969                      (match_operand:QI 2 "nonmemory_operand" "")))]
1970   ""
1971   "if (expand_a_shift (HImode, ASHIFTRT, operands)) DONE; else FAIL;")
1973 (define_insn ""
1974   [(set (match_operand:HI 0 "register_operand" "=r,r")
1975         (match_operator:HI 3 "nshift_operator"
1976                         [ (match_operand:HI 1 "register_operand" "0,0")
1977                           (match_operand:QI 2 "nonmemory_operand" "S,rn")]))
1978    (clobber (match_scratch:QI 4 "=X,&r"))]
1979   ""
1980   "* return output_a_shift (operands);"
1981   [(set (attr "length")
1982         (symbol_ref "compute_a_shift_length (insn, operands)"))
1983    (set_attr "cc" "clobber")])
1985 ;;  SI BIT SHIFTS
1987 (define_expand "ashlsi3"
1988   [(set (match_operand:SI 0 "register_operand" "")
1989         (ashift:SI (match_operand:SI 1 "general_operand" "")
1990                    (match_operand:QI 2 "nonmemory_operand" "")))]
1991   ""
1992   "if (expand_a_shift (SImode, ASHIFT, operands)) DONE; else FAIL;")
1994 (define_expand "lshrsi3"
1995   [(set (match_operand:SI 0 "register_operand" "")
1996         (lshiftrt:SI (match_operand:SI 1 "general_operand" "")
1997                      (match_operand:QI 2 "nonmemory_operand" "")))]
1998   ""
1999   "if (expand_a_shift (SImode, LSHIFTRT, operands)) DONE; else FAIL;")
2001 (define_expand "ashrsi3"
2002   [(set (match_operand:SI 0 "register_operand" "")
2003         (ashiftrt:SI (match_operand:SI 1 "general_operand" "")
2004                      (match_operand:QI 2 "nonmemory_operand" "")))]
2005   ""
2006   "if (expand_a_shift (SImode, ASHIFTRT, operands)) DONE; else FAIL;")
2008 (define_insn ""
2009   [(set (match_operand:SI 0 "register_operand" "=r,r")
2010         (match_operator:SI 3 "nshift_operator"
2011                         [ (match_operand:SI 1 "register_operand" "0,0")
2012                           (match_operand:QI 2 "nonmemory_operand" "T,rn")]))
2013    (clobber (match_scratch:QI 4 "=X,&r"))]
2014   ""
2015   "* return output_a_shift (operands);"
2016   [(set (attr "length")
2017         (symbol_ref "compute_a_shift_length (insn, operands)"))
2018    (set_attr "cc" "clobber")])
2020 ;; ----------------------------------------------------------------------
2021 ;; ROTATIONS
2022 ;; ----------------------------------------------------------------------
2024 (define_expand "rotlqi3"
2025   [(set (match_operand:QI 0 "register_operand" "")
2026         (rotate:QI (match_operand:QI 1 "register_operand" "")
2027                    (match_operand:QI 2 "nonmemory_operand" "")))]
2028   ""
2029   "if (expand_a_rotate (ROTATE, operands)) DONE; else FAIL;")
2031 (define_insn "*rotlqi3_1"
2032   [(set (match_operand:QI 0 "register_operand" "=r")
2033         (rotate:QI (match_operand:QI 1 "register_operand" "0")
2034                    (match_operand:QI 2 "immediate_operand" "")))]
2035   ""
2036   "* return emit_a_rotate (ROTATE, operands);"
2037   [(set_attr "length" "20")
2038    (set_attr "cc" "clobber")])
2040 (define_expand "rotlhi3"
2041   [(set (match_operand:HI 0 "register_operand" "")
2042         (rotate:HI (match_operand:HI 1 "register_operand" "")
2043                    (match_operand:QI 2 "nonmemory_operand" "")))]
2044   ""
2045   "if (expand_a_rotate (ROTATE, operands)) DONE; else FAIL;")
2047 (define_insn "*rotlhi3_1"
2048   [(set (match_operand:HI 0 "register_operand" "=r")
2049         (rotate:HI (match_operand:HI 1 "register_operand" "0")
2050                    (match_operand:QI 2 "immediate_operand" "")))]
2051   ""
2052   "* return emit_a_rotate (ROTATE, operands);"
2053   [(set_attr "length" "20")
2054    (set_attr "cc" "clobber")])
2056 (define_expand "rotlsi3"
2057   [(set (match_operand:SI 0 "register_operand" "")
2058         (rotate:SI (match_operand:SI 1 "register_operand" "")
2059                    (match_operand:QI 2 "nonmemory_operand" "")))]
2060   "TARGET_H8300H || TARGET_H8300S"
2061   "if (expand_a_rotate (ROTATE, operands)) DONE; else FAIL;")
2063 (define_insn "*rotlsi3_1"
2064   [(set (match_operand:SI 0 "register_operand" "=r")
2065         (rotate:SI (match_operand:SI 1 "register_operand" "0")
2066                    (match_operand:QI 2 "immediate_operand" "")))]
2067   "TARGET_H8300H || TARGET_H8300S"
2068   "* return emit_a_rotate (ROTATE, operands);"
2069   [(set_attr "length" "20")
2070    (set_attr "cc" "clobber")])
2072 ;; -----------------------------------------------------------------
2073 ;; BIT FIELDS
2074 ;; -----------------------------------------------------------------
2075 ;; The H8/300 has given 1/8th of its opcode space to bitfield
2076 ;; instructions so let's use them as well as we can.
2078 ;; You'll never believe all these patterns perform one basic action --
2079 ;; load a bit from the source, optionally invert the bit, then store it
2080 ;; in the destination (which is known to be zero).
2082 ;; Combine obviously need some work to better identify this situation and
2083 ;; canonicalize the form better.
2086 ;; Normal loads with a 16bit destination.
2089 (define_insn ""
2090   [(set (match_operand:HI 0 "register_operand" "=&r")
2091         (zero_extract:HI (match_operand:HI 1 "register_operand" "r")
2092                          (const_int 1)
2093                          (match_operand:HI 2 "immediate_operand" "n")))]
2094   "TARGET_H8300"
2095   "sub.w        %0,%0\;bld      %Z2,%Y1\;bst    #0,%X0"
2096   [(set_attr "cc" "clobber")
2097    (set_attr "length" "6")])
2100 ;; Inverted loads with a 16bit destination.
2103 (define_insn ""
2104   [(set (match_operand:HI 0 "register_operand" "=&r")
2105         (zero_extract:HI (xor:HI (match_operand:HI 1 "register_operand" "r")
2106                                  (match_operand:HI 3 "const_int_operand" "n"))
2107                          (const_int 1)
2108                          (match_operand:HI 2 "const_int_operand" "n")))]
2109   "TARGET_H8300
2110    && (1 << INTVAL (operands[2])) == INTVAL (operands[3])"
2111   "sub.w        %0,%0\;bild     %Z2,%Y1\;bst    #0,%X0"
2112   [(set_attr "cc" "clobber")
2113    (set_attr "length" "8")])
2116 ;; Normal loads with a 32bit destination.
2119 (define_insn ""
2120   [(set (match_operand:SI 0 "register_operand" "=&r")
2121         (zero_extract:SI (match_operand:HI 1 "register_operand" "r")
2122                          (const_int 1)
2123                          (match_operand 2 "const_int_operand" "n")))]
2124   "TARGET_H8300
2125    && INTVAL (operands[2]) < 16"
2126   "* return output_simode_bld (0, operands);"
2127   [(set_attr "cc" "clobber")
2128    (set_attr "length" "6")])
2130 (define_insn ""
2131   [(set (match_operand:SI 0 "register_operand" "=r")
2132         (zero_extract:SI (match_operand:SI 1 "register_operand" "r")
2133                          (const_int 1)
2134                          (match_operand 2 "const_int_operand" "n")))]
2135   "(TARGET_H8300H || TARGET_H8300S)
2136    && INTVAL (operands[2]) < 16"
2137   "* return output_simode_bld (0, operands);"
2138   [(set_attr "cc" "clobber")
2139    (set_attr "length" "6")])
2142 ;; Inverted loads with a 32bit destination.
2145 (define_insn ""
2146   [(set (match_operand:SI 0 "register_operand" "=&r")
2147         (zero_extract:SI (xor:HI (match_operand:HI 1 "register_operand" "r")
2148                                  (match_operand:HI 3 "const_int_operand" "n"))
2149                          (const_int 1)
2150                          (match_operand 2 "const_int_operand" "n")))]
2151   "TARGET_H8300
2152    && INTVAL (operands[2]) < 16
2153    && (1 << INTVAL (operands[2])) == INTVAL (operands[3])"
2154   "* return output_simode_bld (1, operands);"
2155   [(set_attr "cc" "clobber")
2156    (set_attr "length" "6")])
2158 (define_insn ""
2159   [(set (match_operand:SI 0 "register_operand" "=r")
2160         (zero_extract:SI (xor:SI (match_operand:SI 1 "register_operand" "r")
2161                                  (match_operand 3 "const_int_operand" "n"))
2162                          (const_int 1)
2163                          (match_operand 2 "const_int_operand" "n")))]
2164   "(TARGET_H8300H || TARGET_H8300S)
2165    && INTVAL (operands[2]) < 16
2166    && (1 << INTVAL (operands[2])) == INTVAL (operands[3])"
2167   "* return output_simode_bld (1, operands);"
2168   [(set_attr "cc" "clobber")
2169    (set_attr "length" "6")])
2171 (define_expand "insv"
2172   [(set (zero_extract:HI (match_operand:HI 0 "general_operand" "")
2173                          (match_operand:HI 1 "general_operand" "")
2174                          (match_operand:HI 2 "general_operand" ""))
2175         (match_operand:HI 3 "general_operand" ""))]
2176   "TARGET_H8300"
2177   "
2179   /* We only have single bit bit-field instructions.  */
2180   if (INTVAL (operands[1]) != 1)
2181     FAIL;
2183   /* For now, we don't allow memory operands.  */
2184   if (GET_CODE (operands[0]) == MEM
2185       || GET_CODE (operands[3]) == MEM)
2186     FAIL;
2189 (define_insn ""
2190   [(set (zero_extract:HI (match_operand:HI 0 "register_operand" "+r")
2191                          (const_int 1)
2192                          (match_operand:HI 1 "immediate_operand" "n"))
2193         (match_operand:HI 2 "register_operand" "r"))]
2194   ""
2195   "bld  #0,%R2\;bst     %Z1,%Y0 ; i1"
2196   [(set_attr "cc" "clobber")
2197    (set_attr "length" "4")])
2199 (define_expand "extzv"
2200   [(set (match_operand:HI 0 "register_operand" "")
2201         (zero_extract:HI (match_operand:HI 1 "bit_operand" "")
2202                          (match_operand:HI 2 "general_operand" "")
2203                          (match_operand:HI 3 "general_operand" "")))]
2204   "TARGET_H8300"
2205   "
2207   /* We only have single bit bit-field instructions.  */
2208   if (INTVAL (operands[2]) != 1)
2209     FAIL;
2211   /* For now, we don't allow memory operands.  */
2212   if (GET_CODE (operands[1]) == MEM)
2213     FAIL;
2216 ;; BAND, BOR, and BXOR patterns
2218 (define_insn ""
2219   [(set (match_operand:HI 0 "bit_operand" "=Ur")
2220         (match_operator:HI 4 "bit_operator"
2221            [(zero_extract:HI (match_operand:HI 1 "register_operand" "r")
2222                              (const_int 1)
2223                              (match_operand:HI 2 "immediate_operand" "n"))
2224             (match_operand:HI 3 "bit_operand" "0")]))]
2225   ""
2226   "bld  %Z2,%Y1\;%b4    #0,%R0\;bst     #0,%R0; bl1"
2227   [(set_attr "cc" "clobber")
2228    (set_attr "length" "6")
2229    (set_attr "adjust_length" "no")])
2231 (define_insn ""
2232   [(set (match_operand:HI 0 "bit_operand" "=Ur")
2233         (match_operator:HI 5 "bit_operator"
2234            [(zero_extract:HI (match_operand:HI 1 "register_operand" "r")
2235                              (const_int 1)
2236                              (match_operand:HI 2 "immediate_operand" "n"))
2237             (zero_extract:HI (match_operand:HI 3 "register_operand" "r")
2238                              (const_int 1)
2239                              (match_operand:HI 4 "immediate_operand" "n"))]))]
2240   ""
2241   "bld  %Z2,%Y1\;%b5    %Z4,%Y3\;bst    #0,%R0; bl3"
2242   [(set_attr "cc" "clobber")
2243    (set_attr "length" "6")
2244    (set_attr "adjust_length" "no")])
2246 ;; -----------------------------------------------------------------
2247 ;; COMBINE PATTERNS
2248 ;; -----------------------------------------------------------------
2250 (define_insn "*extzv_8_8"
2251   [(set (match_operand:SI 0 "register_operand" "=r")
2252         (zero_extract:SI (match_operand:SI 1 "register_operand" "r")
2253                          (const_int 8)
2254                          (const_int 8)))]
2255   "TARGET_H8300H || TARGET_H8300S"
2256   "mov.b\\t%x1,%w0\;extu.w\\t%f0\;extu.l\\t%S0"
2257   [(set_attr "cc" "set_znv")
2258    (set_attr "length" "6")])
2260 (define_insn "*extzv_8_16"
2261   [(set (match_operand:SI 0 "register_operand" "=r")
2262         (zero_extract:SI (match_operand:SI 1 "register_operand" "r")
2263                          (const_int 8)
2264                          (const_int 16)))]
2265   "TARGET_H8300H || TARGET_H8300S"
2266   "mov.w\\t%e1,%f0\;extu.w\\t%f0\;extu.l\\t%S0"
2267   [(set_attr "cc" "set_znv")
2268    (set_attr "length" "6")])
2270 (define_insn ""
2271   [(set (match_operand:HI 0 "register_operand" "=r")
2272         (ior:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r"))
2273                 (match_operand:HI 2 "register_operand" "0")))]
2274   "REG_P (operands[0])
2275    && REG_P (operands[1])
2276    && REGNO (operands[0]) != REGNO (operands[1])"
2277   "or\\t%X1,%s0"
2278   [(set_attr "cc" "clobber")
2279    (set_attr "length" "2")])
2281 (define_insn ""
2282   [(set (match_operand:SI 0 "register_operand" "=r")
2283         (ior:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "r"))
2284                 (match_operand:SI 2 "register_operand" "0")))]
2285   "(TARGET_H8300H || TARGET_H8300S)
2286    && REG_P (operands[0])
2287    && REG_P (operands[1])
2288    && (REGNO (operands[0]) != REGNO (operands[1]))"
2289   "or.w\\t%T1,%f0"
2290   [(set_attr "cc" "clobber")
2291    (set_attr "length" "2")])
2293 (define_insn ""
2294   [(set (match_operand:SI 0 "register_operand" "=r")
2295         (ior:SI (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
2296                 (match_operand:SI 2 "register_operand" "0")))]
2297   ""
2298   "or\\t%X1,%w0"
2299   [(set_attr "cc" "clobber")
2300    (set_attr "length" "2")])
2302 (define_insn ""
2303   [(set (match_operand:HI 0 "register_operand" "=r")
2304         (xor:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r"))
2305                 (match_operand:HI 2 "register_operand" "0")))]
2306   "REG_P (operands[0])
2307    && REG_P (operands[1])
2308    && REGNO (operands[0]) != REGNO (operands[1])"
2309   "xor\\t%X1,%s0"
2310   [(set_attr "cc" "clobber")
2311    (set_attr "length" "2")])
2313 (define_insn ""
2314   [(set (match_operand:SI 0 "register_operand" "=r")
2315         (xor:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "r"))
2316                 (match_operand:SI 2 "register_operand" "0")))]
2317   "(TARGET_H8300H || TARGET_H8300S)
2318    && REG_P (operands[0])
2319    && REG_P (operands[1])
2320    && (REGNO (operands[0]) != REGNO (operands[1]))"
2321   "xor.w\\t%T1,%f0"
2322   [(set_attr "cc" "clobber")
2323    (set_attr "length" "2")])
2325 (define_insn ""
2326   [(set (match_operand:SI 0 "register_operand" "=r")
2327         (xor:SI (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
2328                 (match_operand:SI 2 "register_operand" "0")))]
2329   "REG_P (operands[0])
2330    && REG_P (operands[1])
2331    && REGNO (operands[0]) != REGNO (operands[1])"
2332   "xor\\t%X1,%w0"
2333   [(set_attr "cc" "clobber")
2334    (set_attr "length" "2")])
2336 (define_insn ""
2337   [(set (match_operand:HI 0 "register_operand" "=r")
2338         (ior:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "0"))
2339                 (ashift:HI (match_operand:HI 2 "register_operand" "r")
2340                            (const_int 8))))]
2341   "REG_P (operands[0])
2342    && REG_P (operands[2])
2343    && REGNO (operands[0]) != REGNO (operands[2])"
2344   "mov.b\\t%s2,%t0"
2345   [(set_attr "cc" "clobber")
2346    (set_attr "length" "2")])
2348 (define_insn "*iorhi_shift_8"
2349   [(set (match_operand:HI 0 "register_operand" "=r")
2350         (ior:HI (ashift:HI (match_operand:HI 1 "register_operand" "r")
2351                            (const_int 8))
2352                 (match_operand:HI 2 "register_operand" "0")))]
2353   ""
2354   "or.b\\t%s1,%t0"
2355   [(set_attr "cc" "clobber")
2356    (set_attr "length" "2")])
2358 (define_insn ""
2359   [(set (match_operand:SI 0 "register_operand" "=r")
2360         (ior:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "0"))
2361                 (ashift:SI (match_operand:SI 2 "register_operand" "r")
2362                            (const_int 16))))]
2363   "TARGET_H8300H || TARGET_H8300S"
2364   "mov.w\\t%f2,%e0"
2365   [(set_attr "cc" "clobber")
2366    (set_attr "length" "2")])
2368 (define_insn ""
2369   [(set (match_operand:SI 0 "register_operand" "=r")
2370         (ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "r")
2371                            (const_int 16))
2372                 (match_operand:SI 2 "register_operand" "0")))]
2373   "TARGET_H8300H || TARGET_H8300S"
2374   "or.w\\t%f1,%e0"
2375   [(set_attr "cc" "clobber")
2376    (set_attr "length" "2")])
2378 ;; Storing a part of HImode to QImode.
2380 (define_insn ""
2381   [(set (match_operand:QI 0 "general_operand_dst" "=rm<")
2382         (subreg:QI (lshiftrt:HI (match_operand:HI 1 "register_operand" "r")
2383                                 (const_int 8)) 1))]
2384   ""
2385   "mov.b\\t%t1,%R0"
2386   [(set_attr "cc" "set_znv")
2387    (set_attr "length" "8")])
2389 ;; Storing a part of SImode to QImode.
2391 (define_insn ""
2392   [(set (match_operand:QI 0 "general_operand_dst" "=rm<")
2393         (subreg:QI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
2394                                 (const_int 8)) 3))]
2395   ""
2396   "mov.b\\t%x1,%R0"
2397   [(set_attr "cc" "set_znv")
2398    (set_attr "length" "8")])
2400 (define_insn ""
2401   [(set (match_operand:QI 0 "general_operand_dst" "=rm<")
2402         (subreg:QI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
2403                                 (const_int 16)) 3))
2404    (clobber (match_scratch:SI 2 "=&r"))]
2405   "TARGET_H8300H || TARGET_H8300S"
2406   "mov.w\\t%e1,%f2\;mov.b\\t%w2,%R0"
2407   [(set_attr "cc" "set_znv")
2408    (set_attr "length" "10")])
2410 (define_insn ""
2411   [(set (match_operand:QI 0 "general_operand_dst" "=rm<")
2412         (subreg:QI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
2413                                 (const_int 24)) 3))
2414    (clobber (match_scratch:SI 2 "=&r"))]
2415   "TARGET_H8300H || TARGET_H8300S"
2416   "mov.w\\t%e1,%f2\;mov.b\\t%x2,%R0"
2417   [(set_attr "cc" "set_znv")
2418    (set_attr "length" "10")])
2420 (define_insn_and_split ""
2421   [(set (pc)
2422         (if_then_else (eq (zero_extract:SI (subreg:SI (match_operand:QI 0 "register_operand" "") 0)
2423                                            (const_int 1)
2424                                            (const_int 7))
2425                           (const_int 0))
2426                       (label_ref (match_operand 1 "" ""))
2427                       (pc)))]
2428   ""
2429   "#"
2430   ""
2431   [(set (cc0)
2432         (match_dup 0))
2433    (set (pc)
2434         (if_then_else (ge (cc0)
2435                           (const_int 0))
2436                       (label_ref (match_dup 1))
2437                       (pc)))]
2438   "")
2440 (define_insn_and_split ""
2441   [(set (pc)
2442         (if_then_else (ne (zero_extract:SI (subreg:SI (match_operand:QI 0 "register_operand" "") 0)
2443                                            (const_int 1)
2444                                            (const_int 7))
2445                           (const_int 0))
2446                       (label_ref (match_operand 1 "" ""))
2447                       (pc)))]
2448   ""
2449   "#"
2450   ""
2451   [(set (cc0)
2452         (match_dup 0))
2453    (set (pc)
2454         (if_then_else (lt (cc0)
2455                           (const_int 0))
2456                       (label_ref (match_dup 1))
2457                       (pc)))]
2458   "")
2460 ;; -----------------------------------------------------------------
2461 ;; PEEPHOLE PATTERNS
2462 ;; -----------------------------------------------------------------
2464 ;; Convert (A >> B) & C to (A & 255) >> B if C == 255 >> B.
2466 (define_peephole2
2467   [(parallel
2468      [(set (match_operand:HI 0 "register_operand" "")
2469            (lshiftrt:HI (match_dup 0)
2470                         (match_operand:HI 1 "const_int_operand" "")))
2471       (clobber (match_operand:HI 2 "" ""))])
2472    (set (match_dup 0)
2473         (and:HI (match_dup 0)
2474                 (match_operand:HI 3 "const_int_operand" "")))]
2475   "INTVAL (operands[3]) == (255 >> INTVAL (operands[1]))"
2476   [(set (match_dup 0)
2477         (and:HI (match_dup 0)
2478                 (const_int 255)))
2479    (parallel
2480      [(set (match_dup 0)
2481            (lshiftrt:HI (match_dup 0)
2482                         (match_dup 1)))
2483       (clobber (match_dup 2))])]
2484   "")
2486 ;; Convert (A << B) & C to (A & 255) << B if C == 255 << B.
2488 (define_peephole2
2489   [(parallel
2490      [(set (match_operand:HI 0 "register_operand" "")
2491            (ashift:HI (match_dup 0)
2492                       (match_operand:HI 1 "const_int_operand" "")))
2493       (clobber (match_operand:HI 2 "" ""))])
2494    (set (match_dup 0)
2495         (and:HI (match_dup 0)
2496                 (match_operand:HI 3 "const_int_operand" "")))]
2497   "INTVAL (operands[3]) == (255 << INTVAL (operands[1]))"
2498   [(set (match_dup 0)
2499         (and:HI (match_dup 0)
2500                 (const_int 255)))
2501    (parallel
2502      [(set (match_dup 0)
2503            (ashift:HI (match_dup 0)
2504                       (match_dup 1)))
2505       (clobber (match_dup 2))])]
2506   "")
2508 ;; Convert (A >> B) & C to (A & 255) >> B if C == 255 >> B.
2510 (define_peephole2
2511   [(parallel
2512      [(set (match_operand:SI 0 "register_operand" "")
2513            (lshiftrt:SI (match_dup 0)
2514                         (match_operand:SI 1 "const_int_operand" "")))
2515       (clobber (match_operand:SI 2 "" ""))])
2516    (set (match_dup 0)
2517         (and:SI (match_dup 0)
2518                 (match_operand:SI 3 "const_int_operand" "")))]
2519   "INTVAL (operands[3]) == (255 >> INTVAL (operands[1]))"
2520   [(set (match_dup 0)
2521         (and:SI (match_dup 0)
2522                 (const_int 255)))
2523    (parallel
2524      [(set (match_dup 0)
2525            (lshiftrt:SI (match_dup 0)
2526                         (match_dup 1)))
2527       (clobber (match_dup 2))])]
2528   "")
2530 ;; Convert (A << B) & C to (A & 255) << B if C == 255 << B.
2532 (define_peephole2
2533   [(parallel
2534      [(set (match_operand:SI 0 "register_operand" "")
2535            (ashift:SI (match_dup 0)
2536                       (match_operand:SI 1 "const_int_operand" "")))
2537       (clobber (match_operand:SI 2 "" ""))])
2538    (set (match_dup 0)
2539         (and:SI (match_dup 0)
2540                 (match_operand:SI 3 "const_int_operand" "")))]
2541   "INTVAL (operands[3]) == (255 << INTVAL (operands[1]))"
2542   [(set (match_dup 0)
2543         (and:SI (match_dup 0)
2544                 (const_int 255)))
2545    (parallel
2546      [(set (match_dup 0)
2547            (ashift:SI (match_dup 0)
2548                       (match_dup 1)))
2549       (clobber (match_dup 2))])]
2550   "")
2552 ;; Convert (A >> B) & C to (A & 65535) >> B if C == 65535 >> B.
2554 (define_peephole2
2555   [(parallel
2556      [(set (match_operand:SI 0 "register_operand" "")
2557            (lshiftrt:SI (match_dup 0)
2558                         (match_operand:SI 1 "const_int_operand" "")))
2559       (clobber (match_operand:SI 2 "" ""))])
2560    (set (match_dup 0)
2561         (and:SI (match_dup 0)
2562                 (match_operand:SI 3 "const_int_operand" "")))]
2563   "INTVAL (operands[3]) == (65535 >> INTVAL (operands[1]))"
2564   [(set (match_dup 0)
2565         (and:SI (match_dup 0)
2566                 (const_int 65535)))
2567    (parallel
2568      [(set (match_dup 0)
2569            (lshiftrt:SI (match_dup 0)
2570                         (match_dup 1)))
2571       (clobber (match_dup 2))])]
2572   "")
2574 ;; Convert (A << B) & C to (A & 65535) << B if C == 65535 << B.
2576 (define_peephole2
2577   [(parallel
2578      [(set (match_operand:SI 0 "register_operand" "")
2579            (ashift:SI (match_dup 0)
2580                       (match_operand:SI 1 "const_int_operand" "")))
2581       (clobber (match_operand:SI 2 "" ""))])
2582    (set (match_dup 0)
2583         (and:SI (match_dup 0)
2584                 (match_operand:SI 3 "const_int_operand" "")))]
2585   "INTVAL (operands[3]) == (65535 << INTVAL (operands[1]))"
2586   [(set (match_dup 0)
2587         (and:SI (match_dup 0)
2588                 (const_int 65535)))
2589    (parallel
2590      [(set (match_dup 0)
2591            (ashift:SI (match_dup 0)
2592                       (match_dup 1)))
2593       (clobber (match_dup 2))])]
2594   "")
2596 ;; Convert a QImode push into an SImode push so that the
2597 ;; define_peephole2 below can cram multiple pushes into one stm.l.
2599 (define_peephole2
2600   [(parallel [(set (reg:SI SP_REG)
2601                    (plus:SI (reg:SI SP_REG) (const_int -4)))
2602               (set (mem:QI (plus:SI (reg:SI SP_REG) (const_int -3)))
2603                    (match_operand:QI 0 "register_operand" ""))])]
2604   "TARGET_H8300S"
2605   [(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
2606         (match_dup 0))]
2607   "operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]));")
2609 ;; Convert a HImode push into an SImode push so that the
2610 ;; define_peephole2 below can cram multiple pushes into one stm.l.
2612 (define_peephole2
2613   [(parallel [(set (reg:SI SP_REG)
2614                    (plus:SI (reg:SI SP_REG) (const_int -4)))
2615               (set (mem:HI (plus:SI (reg:SI SP_REG) (const_int -2)))
2616                    (match_operand:HI 0 "register_operand" ""))])]
2617   "TARGET_H8300S"
2618   [(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
2619         (match_dup 0))]
2620   "operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]));")
2622 ;; Cram four pushes into stm.l.
2624 (define_peephole2
2625   [(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
2626         (match_operand:SI 0 "register_operand" ""))
2627    (set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
2628         (match_operand:SI 1 "register_operand" ""))
2629    (set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
2630         (match_operand:SI 2 "register_operand" ""))
2631    (set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
2632         (match_operand:SI 3 "register_operand" ""))]
2633   "TARGET_H8300S
2634    && REGNO (operands[0]) == 0
2635    && REGNO (operands[1]) == 1
2636    && REGNO (operands[2]) == 2
2637    && REGNO (operands[3]) == 3"
2638   [(parallel [(set (reg:SI SP_REG)
2639                    (plus:SI (reg:SI SP_REG)
2640                             (const_int -16)))
2641               (set (mem:SI (plus:SI (reg:SI SP_REG) (const_int -4)))
2642                    (match_dup 0))
2643               (set (mem:SI (plus:SI (reg:SI SP_REG) (const_int -8)))
2644                    (match_dup 1))
2645               (set (mem:SI (plus:SI (reg:SI SP_REG) (const_int -12)))
2646                    (match_dup 2))
2647               (set (mem:SI (plus:SI (reg:SI SP_REG) (const_int -16)))
2648                    (match_dup 3))])]
2649   "")
2651 ;; Cram three pushes into stm.l.
2653 (define_peephole2
2654   [(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
2655         (match_operand:SI 0 "register_operand" ""))
2656    (set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
2657         (match_operand:SI 1 "register_operand" ""))
2658    (set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
2659         (match_operand:SI 2 "register_operand" ""))]
2660   "TARGET_H8300S
2661    && ((REGNO (operands[0]) == 0
2662         && REGNO (operands[1]) == 1
2663         && REGNO (operands[2]) == 2)
2664        || (REGNO (operands[0]) == 4
2665            && REGNO (operands[1]) == 5
2666            && REGNO (operands[2]) == 6))"
2667   [(parallel [(set (reg:SI SP_REG)
2668                    (plus:SI (reg:SI SP_REG)
2669                             (const_int -12)))
2670               (set (mem:SI (plus:SI (reg:SI SP_REG) (const_int -4)))
2671                    (match_dup 0))
2672               (set (mem:SI (plus:SI (reg:SI SP_REG) (const_int -8)))
2673                    (match_dup 1))
2674               (set (mem:SI (plus:SI (reg:SI SP_REG) (const_int -12)))
2675                    (match_dup 2))])]
2676   "")
2678 ;; Cram two pushes into stm.l.
2680 (define_peephole2
2681   [(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
2682         (match_operand:SI 0 "register_operand" ""))
2683    (set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
2684         (match_operand:SI 1 "register_operand" ""))]
2685   "TARGET_H8300S
2686    && ((REGNO (operands[0]) == 0 && REGNO (operands[1]) == 1)
2687        || (REGNO (operands[0]) == 2 && REGNO (operands[1]) == 3)
2688        || (REGNO (operands[0]) == 4 && REGNO (operands[1]) == 5))"
2689   [(parallel [(set (reg:SI SP_REG)
2690                    (plus:SI (reg:SI SP_REG)
2691                             (const_int -8)))
2692               (set (mem:SI (plus:SI (reg:SI SP_REG) (const_int -4)))
2693                    (match_dup 0))
2694               (set (mem:SI (plus:SI (reg:SI SP_REG) (const_int -8)))
2695                    (match_dup 1))])]
2696   "")
2698 ;; Turn
2700 ;;   mov.w #2,r0
2701 ;;   add.w r7,r0  (6 bytes)
2703 ;; into
2705 ;;   mov.w r7,r0
2706 ;;   adds  #2,r0  (4 bytes)
2708 (define_peephole2
2709   [(set (match_operand:HI 0 "register_operand" "")
2710         (match_operand:HI 1 "const_int_operand" ""))
2711    (set (match_dup 0)
2712         (plus:HI (match_dup 0)
2713                  (match_operand:HI 2 "register_operand" "")))]
2714   "REG_P (operands[0]) && REG_P (operands[2])
2715    && REGNO (operands[0]) != REGNO (operands[2])
2716    && (CONST_OK_FOR_J (INTVAL (operands[1]))
2717        || CONST_OK_FOR_L (INTVAL (operands[1]))
2718        || CONST_OK_FOR_N (INTVAL (operands[1])))"
2719   [(set (match_dup 0)
2720         (match_dup 2))
2721    (set (match_dup 0)
2722         (plus:HI (match_dup 0)
2723                  (match_dup 1)))]
2724   "")
2726 ;; Turn
2728 ;;   sub.l  er0,er0
2729 ;;   add.b  #4,r0l
2730 ;;   add.l  er7,er0  (6 bytes)
2732 ;; into
2734 ;;   mov.l  er7,er0
2735 ;;   adds   #4,er0   (4 bytes)
2737 (define_peephole2
2738   [(set (match_operand:SI 0 "register_operand" "")
2739         (match_operand:SI 1 "const_int_operand" ""))
2740    (set (match_dup 0)
2741         (plus:SI (match_dup 0)
2742                  (match_operand:SI 2 "register_operand" "")))]
2743   "(TARGET_H8300H || TARGET_H8300S)
2744    && REG_P (operands[0]) && REG_P (operands[2])
2745    && REGNO (operands[0]) != REGNO (operands[2])
2746    && (CONST_OK_FOR_L (INTVAL (operands[1]))
2747        || CONST_OK_FOR_N (INTVAL (operands[1])))"
2748   [(set (match_dup 0)
2749         (match_dup 2))
2750    (set (match_dup 0)
2751         (plus:SI (match_dup 0)
2752                  (match_dup 1)))]
2753   "")
2755 ;; Turn
2757 ;;   mov.l er7,er0
2758 ;;   add.l #10,er0  (takes 8 bytes)
2760 ;; into
2762 ;;   sub.l er0,er0
2763 ;;   add.b #10,r0l
2764 ;;   add.l er7,er0  (takes 6 bytes)
2766 (define_peephole2
2767   [(set (match_operand:SI 0 "register_operand" "")
2768         (match_operand:SI 1 "register_operand" ""))
2769    (set (match_dup 0)
2770         (plus:SI (match_dup 0)
2771                  (match_operand:SI 2 "const_int_operand" "")))]
2772   "(TARGET_H8300H || TARGET_H8300S)
2773    && REG_P (operands[0]) && REG_P (operands[1])
2774    && REGNO (operands[0]) != REGNO (operands[1])
2775    && !CONST_OK_FOR_L (INTVAL (operands[2]))
2776    && !CONST_OK_FOR_N (INTVAL (operands[2]))
2777    && ((INTVAL (operands[2]) & 0xff) == INTVAL (operands[2])
2778        || (INTVAL (operands[2]) & 0xff00) == INTVAL (operands[2])
2779        || INTVAL (operands[2]) == 0xffff
2780        || INTVAL (operands[2]) == 0xfffe)"
2781   [(set (match_dup 0)
2782         (match_dup 2))
2783    (set (match_dup 0)
2784         (plus:SI (match_dup 0)
2785                  (match_dup 1)))]
2786   "")