2013-01-08 Paul Thomas <pault@gcc.gnu.org>
[official-gcc.git] / gcc / config / h8300 / h8300.md
blob01a31c2de98a567e96a409328c1473671bf1f901
1 ;; GCC machine description for Renesas H8/300
2 ;; Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 ;; 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2010, 2011, 2012
4 ;; Free Software Foundation, Inc.
6 ;;   Contributed by Steve Chamberlain (sac@cygnus.com),
7 ;;   Jim Wilson (wilson@cygnus.com), and Doug Evans (dje@cygnus.com).
9 ;; This file is part of GCC.
11 ;; GCC is free software; you can redistribute it and/or modify
12 ;; it under the terms of the GNU General Public License as published by
13 ;; the Free Software Foundation; either version 3, or (at your option)
14 ;; any later version.
16 ;; GCC is distributed in the hope that it will be useful,
17 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
18 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19 ;; GNU General Public License for more details.
21 ;; You should have received a copy of the GNU General Public License
22 ;; along with GCC; see the file COPYING3.  If not see
23 ;; <http://www.gnu.org/licenses/>.
25 ;; We compute exact length on each instruction for most of the time.
26 ;; In some case, most notably bit operations that may involve memory
27 ;; operands, the lengths in this file are "worst case".
29 ;; On the H8/300H and H8S, adds/subs operate on the 32bit "er"
30 ;; registers.  Right now GCC doesn't expose the "e" half to the
31 ;; compiler, so using add/subs for addhi and subhi is safe.  Long
32 ;; term, we want to expose the "e" half to the compiler (gives us 8
33 ;; more 16bit registers).  At that point addhi and subhi can't use
34 ;; adds/subs.
36 ;; There's currently no way to have an insv/extzv expander for the H8/300H
37 ;; because word_mode is different for the H8/300 and H8/300H.
39 ;; Shifts/rotates by small constants should be handled by special
40 ;; patterns so we get the length and cc status correct.
42 ;; Bitfield operations no longer accept memory operands.  We need
43 ;; to add variants which operate on memory back to the MD.
45 ;; ??? Implement remaining bit ops available on the h8300
47 ;; ----------------------------------------------------------------------
48 ;; CONSTANTS
49 ;; ----------------------------------------------------------------------
51 (define_constants
52   [(UNSPEC_INCDEC       0)
53    (UNSPEC_MONITOR      1)])
55 (define_constants
56   [(UNSPEC_MOVMD        100)
57    (UNSPEC_STPCPY       101)])
59 (define_constants
60   [(R0_REG       0)
61    (SC_REG       3)
62    (COUNTER_REG  4)
63    (SOURCE_REG   5)
64    (DESTINATION_REG 6)
65    (HFP_REG      6)
66    (SP_REG       7)
67    (MAC_REG      8)
68    (AP_REG       9)
69    (RAP_REG     10)
70    (FP_REG      11)])
72 ;; ----------------------------------------------------------------------
73 ;; ATTRIBUTES
74 ;; ----------------------------------------------------------------------
76 (define_attr "cpu" "h8300,h8300h"
77   (const (symbol_ref "cpu_type")))
79 (define_attr "type" "branch,arith,bitbranch,call"
80   (const_string "arith"))
82 (define_attr "length_table" "none,addb,addw,addl,logicb,movb,movw,movl,mova_zero,mova,unary,mov_imm4,short_immediate,bitfield,bitbranch"
83   (const_string "none"))
85 ;; The size of instructions in bytes.
87 (define_attr "length" ""
88   (cond [(eq_attr "type" "branch")
89          ;; In a forward delayed branch, (pc) represents the end of the
90          ;; delay sequence, not the end of the branch itself.
91          (if_then_else (and (ge (minus (match_dup 0) (pc))
92                                 (const_int -126))
93                             (le (plus (minus (match_dup 0) (pc))
94                                       (symbol_ref "DELAY_SLOT_LENGTH (insn)"))
95                                 (const_int 125)))
96                        (const_int 2)
97                        (if_then_else (and (eq_attr "cpu" "h8300h")
98                                           (and (ge (minus (pc) (match_dup 0))
99                                                    (const_int -32000))
100                                                (le (minus (pc) (match_dup 0))
101                                                    (const_int 32000))))
102                                      (const_int 4)
103                                      (const_int 6)))
104          (eq_attr "type" "bitbranch")
105          (if_then_else (and (ge (minus (match_dup 0) (pc))
106                                 (const_int -126))
107                             (le (minus (match_dup 0) (pc))
108                                 (const_int 126)))
109                        (plus (symbol_ref "h8300_insn_length_from_table (insn, operands)")
110                              (const_int 2))
111                        (if_then_else (and (eq_attr "cpu" "h8300h")
112                                           (and (ge (minus (pc) (match_dup 0))
113                                                    (const_int -32000))
114                                                (le (minus (pc) (match_dup 0))
115                                                    (const_int 32000))))
116                                      (plus (symbol_ref "h8300_insn_length_from_table (insn, operands)")
117                                            (const_int 4))
118                                      (plus (symbol_ref "h8300_insn_length_from_table (insn, operands)")
119                                            (const_int 6))))
120          (eq_attr "length_table" "!none")
121          (symbol_ref "h8300_insn_length_from_table (insn, operands)")]
122         (const_int 200)))
124 ;; Condition code settings.
126 ;; none - insn does not affect cc
127 ;; none_0hit - insn does not affect cc but it does modify operand 0
128 ;;      This attribute is used to keep track of when operand 0 changes.
129 ;;      See the description of NOTICE_UPDATE_CC for more info.
130 ;; set_znv - insn sets z,n,v to usable values (like a tst insn); c is unknown.
131 ;; set_zn  - insn sets z,n to usable values; v,c are unknown.
132 ;; compare - compare instruction
133 ;; clobber - value of cc is unknown
135 (define_attr "cc" "none,none_0hit,set_znv,set_zn,compare,clobber"
136   (const_string "clobber"))
138 ;; Type of delay slot.  NONE means the instruction has no delay slot.
139 ;; JUMP means it is an unconditional jump that (if short enough)
140 ;; could be implemented using bra/s.
142 (define_attr "delay_slot" "none,jump"
143   (const_string "none"))
145 ;; "yes" if the instruction can be put into a delay slot.  It's not
146 ;; entirely clear that jsr is not valid in delay slots, but it
147 ;; definitely doesn't have the effect of causing the called function
148 ;; to return to the target of the delayed branch.
150 (define_attr "can_delay" "no,yes"
151   (cond [(eq_attr "type" "branch,bitbranch,call")
152            (const_string "no")
153          (geu (symbol_ref "get_attr_length (insn)") (const_int 2))
154            (const_string "no")]
155         (const_string "yes")))
157 ;; Only allow jumps to have a delay slot if we think they might
158 ;; be short enough.  This is just an optimization: we don't know
159 ;; for certain whether they will be or not.
161 (define_delay (and (eq_attr "delay_slot" "jump")
162                    (eq (symbol_ref "get_attr_length (insn)") (const_int 2)))
163   [(eq_attr "can_delay" "yes")
164    (nil)
165    (nil)])
167 ;; Provide the maximum length of an assembly instruction in an asm
168 ;; statement.  The maximum length of 14 bytes is achieved on H8SX.
170 (define_asm_attributes
171   [(set (attr "length")
172         (cond [(match_test "TARGET_H8300") (const_int 4)
173                (match_test "TARGET_H8300H") (const_int 10)
174                (match_test "TARGET_H8300S") (const_int 10)]
175               (const_int 14)))])
177 (include "predicates.md")
178 (include "constraints.md")
180 ;; ----------------------------------------------------------------------
181 ;; MACRO DEFINITIONS
182 ;; ----------------------------------------------------------------------
184 ;; This mode iterator allows :P to be used for patterns that operate on
185 ;; pointer-sized quantities.  Exactly one of the two alternatives will match.
187 (define_mode_iterator P [(HI "Pmode == HImode") (SI "Pmode == SImode")])
190 ;; ----------------------------------------------------------------------
191 ;; MOVE INSTRUCTIONS
192 ;; ----------------------------------------------------------------------
194 ;; movqi
196 (define_insn "*movqi_h8300"
197   [(set (match_operand:QI 0 "general_operand_dst" "=r,r ,<,r,r,m")
198         (match_operand:QI 1 "general_operand_src" " I,r>,r,n,m,r"))]
199   "TARGET_H8300
200    && h8300_move_ok (operands[0], operands[1])"
201   "@
202    sub.b        %X0,%X0
203    mov.b        %R1,%X0
204    mov.b        %X1,%R0
205    mov.b        %R1,%X0
206    mov.b        %R1,%X0
207    mov.b        %X1,%R0"
208   [(set_attr "length" "2,2,2,2,4,4")
209    (set_attr "cc" "set_zn,set_znv,set_znv,set_znv,set_znv,set_znv")])
211 (define_insn "*movqi_h8300hs"
212   [(set (match_operand:QI 0 "general_operand_dst" "=r,r ,<,r,r,m")
213         (match_operand:QI 1 "general_operand_src" " I,r>,r,n,m,r"))]
214   "(TARGET_H8300H || TARGET_H8300S) && !TARGET_H8300SX
215     && h8300_move_ok (operands[0], operands[1])"
216   "@
217    sub.b        %X0,%X0
218    mov.b        %R1,%X0
219    mov.b        %X1,%R0
220    mov.b        %R1,%X0
221    mov.b        %R1,%X0
222    mov.b        %X1,%R0"
223   [(set (attr "length")
224         (symbol_ref "compute_mov_length (operands)"))
225    (set_attr "cc" "set_zn,set_znv,set_znv,clobber,set_znv,set_znv")])
227 (define_insn "*movqi_h8sx"
228   [(set (match_operand:QI 0 "general_operand_dst" "=Z,rQ")
229         (match_operand:QI 1 "general_operand_src" "P4>X,rQi"))]
230   "TARGET_H8300SX"
231   "@
232     mov.b       %X1:4,%X0
233     mov.b       %X1,%X0"
234   [(set_attr "length_table" "mov_imm4,movb")
235    (set_attr "cc" "set_znv")])
237 (define_expand "movqi"
238   [(set (match_operand:QI 0 "general_operand_dst" "")
239         (match_operand:QI 1 "general_operand_src" ""))]
240   ""
241   {
242     /* One of the ops has to be in a register.  */
243     if (!TARGET_H8300SX && !h8300_move_ok (operands[0], operands[1]))
244       operands[1] = copy_to_mode_reg (QImode, operands[1]);
245   })
247 (define_insn "movstrictqi"
248   [(set (strict_low_part (match_operand:QI 0 "general_operand_dst" "+r,r"))
249                          (match_operand:QI 1 "general_operand_src" "I,rmi>"))]
250   ""
251   "@
252    sub.b        %X0,%X0
253    mov.b        %X1,%X0"
254   [(set_attr "length" "2,*")
255    (set_attr "length_table" "*,movb")
256    (set_attr "cc" "set_zn,set_znv")])
258 ;; movhi
260 (define_insn "*movhi_h8300"
261   [(set (match_operand:HI 0 "general_operand_dst" "=r,r,<,r,r,m")
262         (match_operand:HI 1 "general_operand_src" "I,r>,r,i,m,r"))]
263   "TARGET_H8300
264    && h8300_move_ok (operands[0], operands[1])"
265   "@
266    sub.w        %T0,%T0
267    mov.w        %T1,%T0
268    mov.w        %T1,%T0
269    mov.w        %T1,%T0
270    mov.w        %T1,%T0
271    mov.w        %T1,%T0"
272   [(set (attr "length")
273         (symbol_ref "compute_mov_length (operands)"))
274    (set_attr "cc" "set_zn,set_znv,set_znv,set_znv,set_znv,set_znv")])
276 (define_insn "*movhi_h8300hs"
277   [(set (match_operand:HI 0 "general_operand_dst" "=r,r,<,r,r,m")
278         (match_operand:HI 1 "general_operand_src" "I,r>,r,i,m,r"))]
279   "(TARGET_H8300H || TARGET_H8300S) && !TARGET_H8300SX
280     && h8300_move_ok (operands[0], operands[1])"
281   "@
282    sub.w        %T0,%T0
283    mov.w        %T1,%T0
284    mov.w        %T1,%T0
285    mov.w        %T1,%T0
286    mov.w        %T1,%T0
287    mov.w        %T1,%T0"
288   [(set (attr "length")
289         (symbol_ref "compute_mov_length (operands)"))
290    (set_attr "cc" "set_zn,set_znv,set_znv,set_znv,set_znv,set_znv")])
292 (define_insn "*movhi_h8sx"
293   [(set (match_operand:HI 0 "general_operand_dst" "=r,r,Z,Q,rQ")
294         (match_operand:HI 1 "general_operand_src" "I,P3>X,P4>X,IP8>X,rQi"))]
295   "TARGET_H8300SX"
296   "@
297    sub.w        %T0,%T0
298    mov.w        %T1:3,%T0
299    mov.w        %T1:4,%T0
300    mov.w        %T1,%T0
301    mov.w        %T1,%T0"
302   [(set_attr "length_table" "*,*,mov_imm4,short_immediate,movw")
303    (set_attr "length" "2,2,*,*,*")
304    (set_attr "cc" "set_zn,set_znv,set_znv,set_znv,set_znv")])
306 (define_expand "movhi"
307   [(set (match_operand:HI 0 "general_operand_dst" "")
308         (match_operand:HI 1 "general_operand_src" ""))]
309   ""
310   {
311     /* One of the ops has to be in a register.  */
312     if (!h8300_move_ok (operands[0], operands[1]))
313       operands[1] = copy_to_mode_reg (HImode, operand1);
314   })
316 (define_insn "movstricthi"
317   [(set (strict_low_part (match_operand:HI 0 "general_operand_dst" "+r,r,r"))
318                          (match_operand:HI 1 "general_operand_src" "I,P3>X,rmi"))]
319   ""
320   "@
321    sub.w        %T0,%T0
322    mov.w        %T1,%T0
323    mov.w        %T1,%T0"
324   [(set_attr "length" "2,2,*")
325    (set_attr "length_table" "*,*,movw")
326    (set_attr "cc" "set_zn,set_znv,set_znv")])
328 ;; movsi
330 (define_expand "movsi"
331   [(set (match_operand:SI 0 "general_operand_dst" "")
332         (match_operand:SI 1 "general_operand_src" ""))]
333   ""
334   {
335     if (TARGET_H8300)
336       {
337         if (h8300_expand_movsi (operands))
338           DONE;
339       }
340     else if (!TARGET_H8300SX)
341       {
342         /* One of the ops has to be in a register.  */
343         if (!h8300_move_ok (operands[0], operands[1]))
344           operands[1] = copy_to_mode_reg (SImode, operand1);
345       }
346   })
348 (define_insn "*movsi_h8300"
349   [(set (match_operand:SI 0 "general_operand_dst" "=r,r,r,o,<,r")
350         (match_operand:SI 1 "general_operand_src" "I,r,io,r,r,>"))]
351   "TARGET_H8300
352    && h8300_move_ok (operands[0], operands[1])"
354   unsigned int rn = -1;
355   switch (which_alternative)
356     {
357     case 0:
358       return "sub.w     %e0,%e0\;sub.w  %f0,%f0";
359     case 1:
360       if (REGNO (operands[0]) < REGNO (operands[1]))
361         return "mov.w   %e1,%e0\;mov.w  %f1,%f0";
362       else
363         return "mov.w   %f1,%f0\;mov.w  %e1,%e0";
364     case 2:
365       /* Make sure we don't trample the register we index with.  */
366       if (GET_CODE (operands[1]) == MEM)
367         {
368           rtx inside = XEXP (operands[1], 0);
369           if (REG_P (inside))
370             {
371               rn = REGNO (inside);
372             }
373           else if (GET_CODE (inside) == PLUS)
374             {
375               rtx lhs = XEXP (inside, 0);
376               rtx rhs = XEXP (inside, 1);
377               if (REG_P (lhs)) rn = REGNO (lhs);
378               if (REG_P (rhs)) rn = REGNO (rhs);
379             }
380         }
381       if (rn == REGNO (operands[0]))
382         {
383           /* Move the second word first.  */
384           return "mov.w %f1,%f0\;mov.w  %e1,%e0";
385         }
386       else
387         {
388           if (GET_CODE (operands[1]) == CONST_INT)
389             {
390               /* If either half is zero, use sub.w to clear that
391                  half.  */
392               if ((INTVAL (operands[1]) & 0xffff) == 0)
393                 return "mov.w   %e1,%e0\;sub.w  %f0,%f0";
394               if (((INTVAL (operands[1]) >> 16) & 0xffff) == 0)
395                 return "sub.w   %e0,%e0\;mov.w  %f1,%f0";
396               /* If the upper half and the lower half are the same,
397                  copy one half to the other.  */
398               if ((INTVAL (operands[1]) & 0xffff)
399                   == ((INTVAL (operands[1]) >> 16) & 0xffff))
400                 return "mov.w\\t%e1,%e0\;mov.w\\t%e0,%f0";
401             }
402           return "mov.w %e1,%e0\;mov.w  %f1,%f0";
403         }
404     case 3:
405       return "mov.w     %e1,%e0\;mov.w  %f1,%f0";
406     case 4:
407       return "mov.w     %f1,%T0\;mov.w  %e1,%T0";
408     case 5:
409       return "mov.w     %T1,%e0\;mov.w  %T1,%f0";
410     default:
411       gcc_unreachable ();
412     }
414   [(set (attr "length")
415         (symbol_ref "compute_mov_length (operands)"))])
417 (define_insn "*movsi_h8300hs"
418   [(set (match_operand:SI 0 "general_operand_dst" "=r,r,r,<,r,r,m,*a,*a,r")
419         (match_operand:SI 1 "general_operand_src" "I,r,i,r,>,m,r,I,r,*a"))]
420   "(TARGET_H8300S || TARGET_H8300H) && !TARGET_H8300SX
421     && h8300_move_ok (operands[0], operands[1])"
423   switch (which_alternative)
424     {
425     case 0:
426       return "sub.l     %S0,%S0";
427     case 7:
428       return "clrmac";
429     case 8:
430       return "clrmac\;ldmac %1,macl";
431     case 9:
432       return "stmac     macl,%0";
433     default:
434       if (GET_CODE (operands[1]) == CONST_INT)
435         {
436           int val = INTVAL (operands[1]);
438           /* Look for constants which can be made by adding an 8-bit
439              number to zero in one of the two low bytes.  */
440           if (val == (val & 0xff))
441             {
442               operands[1] = GEN_INT ((char) val & 0xff);
443               return "sub.l\\t%S0,%S0\;add.b\\t%1,%w0";
444             }
446           if (val == (val & 0xff00))
447             {
448               operands[1] = GEN_INT ((char) (val >> 8) & 0xff);
449               return "sub.l\\t%S0,%S0\;add.b\\t%1,%x0";
450             }
452           /* Look for constants that can be obtained by subs, inc, and
453              dec to 0.  */
454           switch (val & 0xffffffff)
455             {
456             case 0xffffffff:
457               return "sub.l\\t%S0,%S0\;subs\\t#1,%S0";
458             case 0xfffffffe:
459               return "sub.l\\t%S0,%S0\;subs\\t#2,%S0";
460             case 0xfffffffc:
461               return "sub.l\\t%S0,%S0\;subs\\t#4,%S0";
463             case 0x0000ffff:
464               return "sub.l\\t%S0,%S0\;dec.w\\t#1,%f0";
465             case 0x0000fffe:
466               return "sub.l\\t%S0,%S0\;dec.w\\t#2,%f0";
468             case 0xffff0000:
469               return "sub.l\\t%S0,%S0\;dec.w\\t#1,%e0";
470             case 0xfffe0000:
471               return "sub.l\\t%S0,%S0\;dec.w\\t#2,%e0";
473             case 0x00010000:
474               return "sub.l\\t%S0,%S0\;inc.w\\t#1,%e0";
475             case 0x00020000:
476               return "sub.l\\t%S0,%S0\;inc.w\\t#2,%e0";
477             }
478         }
479     }
480    return "mov.l        %S1,%S0";
482   [(set (attr "length")
483         (symbol_ref "compute_mov_length (operands)"))
484    (set_attr "cc" "set_zn,set_znv,clobber,set_znv,set_znv,set_znv,set_znv,none_0hit,none_0hit,set_znv")])
486 (define_insn "*movsi_h8sx"
487   [(set (match_operand:SI 0 "general_operand_dst" "=r,r,Q,rQ,*a,*a,r")
488         (match_operand:SI 1 "general_operand_src" "I,P3>X,IP8>X,rQi,I,r,*a"))]
489   "TARGET_H8300SX"
490   "@
491    sub.l        %S0,%S0
492    mov.l        %S1:3,%S0
493    mov.l        %S1,%S0
494    mov.l        %S1,%S0
495    clrmac
496    clrmac\;ldmac        %1,macl
497    stmac        macl,%0"
498   [(set_attr "length_table" "*,*,short_immediate,movl,*,*,*")
499    (set_attr "length" "2,2,*,*,2,6,4")
500    (set_attr "cc" "set_zn,set_znv,set_znv,set_znv,none_0hit,none_0hit,set_znv")])
502 (define_insn "*movsf_h8sx"
503   [(set (match_operand:SF 0 "general_operand_dst" "=r,rQ")
504         (match_operand:SF 1 "general_operand_src" "G,rQi"))]
505   "TARGET_H8300SX"
506   "@
507     sub.l       %S0,%S0
508     mov.l       %S1,%S0"
509   [(set_attr "length" "2,*")
510    (set_attr "length_table" "*,movl")
511    (set_attr "cc" "set_zn,set_znv")])
513 ;; Implement block moves using movmd.  Defining movmemsi allows the full
514 ;; range of constant lengths (up to 0x40000 bytes when using movmd.l).
515 ;; See h8sx_emit_movmd for details.
517 (define_expand "movmemsi"
518   [(use (match_operand:BLK 0 "memory_operand" ""))
519    (use (match_operand:BLK 1 "memory_operand" ""))
520    (use (match_operand:SI 2 "" ""))
521    (use (match_operand:SI 3 "const_int_operand" ""))]
522   "TARGET_H8300SX"
523   {
524     if (h8sx_emit_movmd (operands[0], operands[1], operands[2], INTVAL (operands[3])))
525       DONE;
526     else
527       FAIL;
528   })
530 ;; Expander for generating movmd insns.  Operand 0 is the destination
531 ;; memory region, operand 1 is the source, operand 2 is the counter
532 ;; register and operand 3 is the chunk size (1, 2 or 4).
534 (define_expand "movmd"
535   [(parallel
536     [(set (match_operand:BLK 0 "memory_operand" "")
537           (match_operand:BLK 1 "memory_operand" ""))
538      (unspec [(match_operand:HI 2 "register_operand" "")
539               (match_operand:HI 3 "const_int_operand" "")] UNSPEC_MOVMD)
540      (clobber (match_dup 4))
541      (clobber (match_dup 5))
542      (set (match_dup 2)
543           (const_int 0))])]
544   "TARGET_H8300SX"
545   {
546     operands[4] = copy_rtx (XEXP (operands[0], 0));
547     operands[5] = copy_rtx (XEXP (operands[1], 0));
548   })
550 ;; This is a difficult instruction to reload since operand 0 must be the
551 ;; frame pointer.  See h8300_reg_class_from_letter for an explanation.
553 (define_insn "movmd_internal_normal"
554   [(set (mem:BLK (match_operand:HI 3 "register_operand" "0,r"))
555         (mem:BLK (match_operand:HI 4 "register_operand" "1,1")))
556    (unspec [(match_operand:HI 5 "register_operand" "2,2")
557             (match_operand:HI 6 "const_int_operand" "n,n")] UNSPEC_MOVMD)
558    (clobber (match_operand:HI 0 "register_operand" "=d,??D"))
559    (clobber (match_operand:HI 1 "register_operand" "=f,f"))
560    (set (match_operand:HI 2 "register_operand" "=c,c")
561         (const_int 0))]
562   "TARGET_H8300SX && TARGET_NORMAL_MODE"
563   "@
564     movmd%m6
565     #"
566   [(set_attr "length" "2,14")
567    (set_attr "can_delay" "no")
568    (set_attr "cc" "none,clobber")])
570 (define_insn "movmd_internal"
571   [(set (mem:BLK (match_operand:SI 3 "register_operand" "0,r"))
572         (mem:BLK (match_operand:SI 4 "register_operand" "1,1")))
573    (unspec [(match_operand:HI 5 "register_operand" "2,2")
574             (match_operand:HI 6 "const_int_operand" "n,n")] UNSPEC_MOVMD)
575    (clobber (match_operand:SI 0 "register_operand" "=d,??D"))
576    (clobber (match_operand:SI 1 "register_operand" "=f,f"))
577    (set (match_operand:HI 2 "register_operand" "=c,c")
578         (const_int 0))]
579   "TARGET_H8300SX && !TARGET_NORMAL_MODE"
580   "@
581     movmd%m6
582     #"
583   [(set_attr "length" "2,14")
584    (set_attr "can_delay" "no")
585    (set_attr "cc" "none,clobber")])
587 ;; Split the above instruction if the destination register isn't er6.
588 ;; We need a sequence like:
590 ;;      mov.l   er6,@-er7
591 ;;      mov.l   <dest>,er6
592 ;;      movmd.sz
593 ;;      mov.l   er6,<dest>
594 ;;      mov.l   @er7+,er6
596 ;; where <dest> is the current destination register (operand 4).
597 ;; The fourth instruction will be deleted if <dest> dies here.
599 (define_split
600   [(set (match_operand:BLK 0 "memory_operand" "")
601         (match_operand:BLK 1 "memory_operand" ""))
602    (unspec [(match_operand:HI 2 "register_operand" "")
603             (match_operand:HI 3 "const_int_operand" "")] UNSPEC_MOVMD)
604    (clobber (match_operand:HI 4 "register_operand" ""))
605    (clobber (match_operand:HI 5 "register_operand" ""))
606    (set (match_dup 2)
607         (const_int 0))]
608   "TARGET_H8300SX && TARGET_NORMAL_MODE && reload_completed
609    && REGNO (operands[4]) != DESTINATION_REG"
610   [(const_int 0)]
611   {
612     rtx dest;
614     h8300_swap_into_er6 (XEXP (operands[0], 0));
615     dest = replace_equiv_address (operands[0], hard_frame_pointer_rtx);
616     emit_insn (gen_movmd (dest, operands[1], operands[2], operands[3]));
617     h8300_swap_out_of_er6 (operands[4]);
618     DONE;
619   })
621 (define_split
622   [(set (match_operand:BLK 0 "memory_operand" "")
623         (match_operand:BLK 1 "memory_operand" ""))
624    (unspec [(match_operand:HI 2 "register_operand" "")
625             (match_operand:HI 3 "const_int_operand" "")] UNSPEC_MOVMD)
626    (clobber (match_operand:SI 4 "register_operand" ""))
627    (clobber (match_operand:SI 5 "register_operand" ""))
628    (set (match_dup 2)
629         (const_int 0))]
630   "TARGET_H8300SX && !TARGET_NORMAL_MODE && reload_completed
631    && REGNO (operands[4]) != DESTINATION_REG"
632   [(const_int 0)]
633   {
634     rtx dest;
636     h8300_swap_into_er6 (XEXP (operands[0], 0));
637     dest = replace_equiv_address (operands[0], hard_frame_pointer_rtx);
638     emit_insn (gen_movmd (dest, operands[1], operands[2], operands[3]));
639     h8300_swap_out_of_er6 (operands[4]);
640     DONE;
641   })
643 ;; Expand a call to stpcpy() using movsd.  Operand 0 should point to
644 ;; the final character, but movsd leaves it pointing to the character
645 ;; after that.
647 (define_expand "movstr"
648   [(use (match_operand 0 "register_operand" ""))
649    (use (match_operand:BLK 1 "memory_operand" ""))
650    (use (match_operand:BLK 2 "memory_operand" ""))]
651   "TARGET_H8300SX"
652   {
653     operands[1] = replace_equiv_address
654       (operands[1], copy_to_mode_reg (Pmode, XEXP (operands[1], 0)));
655     operands[2] = replace_equiv_address
656       (operands[2], copy_to_mode_reg (Pmode, XEXP (operands[2], 0)));
657     emit_insn (gen_movsd (operands[1], operands[2], gen_reg_rtx (Pmode)));
658     emit_insn (gen_add3_insn (operands[0], XEXP (operands[1], 0), constm1_rtx));
659     DONE;
660   })
662 ;; Expander for generating a movsd instruction.  Operand 0 is the
663 ;; destination string, operand 1 is the source string and operand 2
664 ;; is a scratch register.
666 (define_expand "movsd"
667   [(parallel
668     [(set (match_operand:BLK 0 "memory_operand" "")
669           (unspec:BLK [(match_operand:BLK 1 "memory_operand" "")]
670           UNSPEC_STPCPY))
671      (clobber (match_dup 3))
672      (clobber (match_dup 4))
673      (clobber (match_operand 2 "register_operand" ""))])]
674   "TARGET_H8300SX"
675   {
676     operands[3] = copy_rtx (XEXP (operands[0], 0));
677     operands[4] = copy_rtx (XEXP (operands[1], 0));
678   })
680 ;; See comments above memcpy_internal().
682 (define_insn "stpcpy_internal_normal"
683   [(set (mem:BLK (match_operand:HI 3 "register_operand" "0,r"))
684         (unspec:BLK [(mem:BLK (match_operand:HI 4 "register_operand" "1,1"))]
685         UNSPEC_STPCPY))
686    (clobber (match_operand:HI 0 "register_operand" "=d,??D"))
687    (clobber (match_operand:HI 1 "register_operand" "=f,f"))
688    (clobber (match_operand:HI 2 "register_operand" "=c,c"))]
689   "TARGET_H8300SX && TARGET_NORMAL_MODE"
690   "@
691     \n1:\tmovsd\t2f\;bra\t1b\n2:
692     #"
693   [(set_attr "length" "6,18")
694    (set_attr "cc" "none,clobber")])
696 (define_insn "stpcpy_internal"
697   [(set (mem:BLK (match_operand:SI 3 "register_operand" "0,r"))
698         (unspec:BLK [(mem:BLK (match_operand:SI 4 "register_operand" "1,1"))]
699         UNSPEC_STPCPY))
700    (clobber (match_operand:SI 0 "register_operand" "=d,??D"))
701    (clobber (match_operand:SI 1 "register_operand" "=f,f"))
702    (clobber (match_operand:SI 2 "register_operand" "=c,c"))]
703   "TARGET_H8300SX && !TARGET_NORMAL_MODE"
704   "@
705     \n1:\tmovsd\t2f\;bra\t1b\n2:
706     #"
707   [(set_attr "length" "6,18")
708    (set_attr "cc" "none,clobber")])
710 ;; Split the above instruction if the destination isn't er6.  This works
711 ;; in the same way as the movmd splitter.
713 (define_split
714   [(set (match_operand:BLK 0 "memory_operand" "")
715         (unspec:BLK [(match_operand:BLK 1 "memory_operand" "")] UNSPEC_STPCPY))
716    (clobber (match_operand:HI 2 "register_operand" ""))
717    (clobber (match_operand:HI 3 "register_operand" ""))
718    (clobber (match_operand:HI 4 "register_operand" ""))]
719   "TARGET_H8300SX && TARGET_NORMAL_MODE && reload_completed
720    && REGNO (operands[2]) != DESTINATION_REG"
721   [(const_int 0)]
722   {
723     rtx dest;
725     h8300_swap_into_er6 (XEXP (operands[0], 0));
726     dest = replace_equiv_address (operands[0], hard_frame_pointer_rtx);
727     emit_insn (gen_movsd (dest, operands[1], operands[4]));
728     h8300_swap_out_of_er6 (operands[2]);
729     DONE;
730   })
732 (define_split
733   [(set (match_operand:BLK 0 "memory_operand" "")
734         (unspec:BLK [(match_operand:BLK 1 "memory_operand" "")] UNSPEC_STPCPY))
735    (clobber (match_operand:SI 2 "register_operand" ""))
736    (clobber (match_operand:SI 3 "register_operand" ""))
737    (clobber (match_operand:SI 4 "register_operand" ""))]
738   "TARGET_H8300SX && !TARGET_NORMAL_MODE && reload_completed
739    && REGNO (operands[2]) != DESTINATION_REG"
740   [(const_int 0)]
741   {
742     rtx dest;
744     h8300_swap_into_er6 (XEXP (operands[0], 0));
745     dest = replace_equiv_address (operands[0], hard_frame_pointer_rtx);
746     emit_insn (gen_movsd (dest, operands[1], operands[4]));
747     h8300_swap_out_of_er6 (operands[2]);
748     DONE;
749   })
751 (include "mova.md")
753 (define_expand "movsf"
754   [(set (match_operand:SF 0 "general_operand_dst" "")
755         (match_operand:SF 1 "general_operand_src" ""))]
756   ""
757   {
758     if (TARGET_H8300)
759       {
760         if (h8300_expand_movsi (operands))
761           DONE;
762       }
763     else if (!TARGET_H8300SX)
764       {
765         /* One of the ops has to be in a register.  */
766         if (!register_operand (operand1, SFmode)
767             && !register_operand (operand0, SFmode))
768           {
769             operands[1] = copy_to_mode_reg (SFmode, operand1);
770           }
771       }
772   })
774 (define_insn "*movsf_h8300"
775   [(set (match_operand:SF 0 "general_operand_dst" "=r,r,r,o,<,r")
776         (match_operand:SF 1 "general_operand_src" "G,r,io,r,r,>"))]
777   "TARGET_H8300
778    && (register_operand (operands[0], SFmode)
779        || register_operand (operands[1], SFmode))"
781   /* Copy of the movsi stuff.  */
782   unsigned int rn = -1;
783   switch (which_alternative)
784     {
785     case 0:
786       return "sub.w     %e0,%e0\;sub.w  %f0,%f0";
787     case 1:
788       if (REGNO (operands[0]) < REGNO (operands[1]))
789         return "mov.w   %e1,%e0\;mov.w  %f1,%f0";
790       else
791         return "mov.w   %f1,%f0\;mov.w  %e1,%e0";
792     case 2:
793       /* Make sure we don't trample the register we index with.  */
794       if (GET_CODE (operands[1]) == MEM)
795         {
796           rtx inside = XEXP (operands[1], 0);
797           if (REG_P (inside))
798             {
799               rn = REGNO (inside);
800             }
801           else if (GET_CODE (inside) == PLUS)
802             {
803               rtx lhs = XEXP (inside, 0);
804               rtx rhs = XEXP (inside, 1);
805               if (REG_P (lhs)) rn = REGNO (lhs);
806               if (REG_P (rhs)) rn = REGNO (rhs);
807             }
808         }
809       if (rn == REGNO (operands[0]))
810         /* Move the second word first.  */
811         return "mov.w   %f1,%f0\;mov.w  %e1,%e0";
812       else
813         /* Move the first word first.  */
814         return "mov.w   %e1,%e0\;mov.w  %f1,%f0";
816     case 3:
817       return "mov.w     %e1,%e0\;mov.w  %f1,%f0";
818     case 4:
819       return "mov.w     %f1,%T0\;mov.w  %e1,%T0";
820     case 5:
821       return "mov.w     %T1,%e0\;mov.w  %T1,%f0";
822     default:
823       gcc_unreachable ();
824     }
826   [(set (attr "length")
827         (symbol_ref "compute_mov_length (operands)"))])
829 (define_insn "*movsf_h8300hs"
830   [(set (match_operand:SF 0 "general_operand_dst" "=r,r,r,m,<,r")
831         (match_operand:SF 1 "general_operand_src" "G,r,im,r,r,>"))]
832   "(TARGET_H8300H || TARGET_H8300S) && !TARGET_H8300SX
833     && (register_operand (operands[0], SFmode)
834         || register_operand (operands[1], SFmode))"
835   "@
836    sub.l        %S0,%S0
837    mov.l        %S1,%S0
838    mov.l        %S1,%S0
839    mov.l        %S1,%S0
840    mov.l        %S1,%S0
841    mov.l        %S1,%S0"
842   [(set (attr "length")
843         (symbol_ref "compute_mov_length (operands)"))
844    (set_attr "cc" "set_zn,set_znv,set_znv,set_znv,set_znv,set_znv")])
846 ;; ----------------------------------------------------------------------
847 ;; PUSH INSTRUCTIONS
848 ;; ----------------------------------------------------------------------
850 (define_insn "*pushqi1_h8300"
851   [(set (mem:QI
852         (pre_modify:HI
853           (reg:HI SP_REG)
854           (plus:HI (reg:HI SP_REG) (const_int -2))))
855         (match_operand:QI 0 "register_no_sp_elim_operand" "r"))]
856   "TARGET_H8300"
857   "mov.w\\t%T0,@-r7"
858   [(set_attr "length" "2")])
860 (define_insn "*pushqi1_h8300hs_<mode>"
861   [(set (mem:QI
862         (pre_modify:P
863           (reg:P SP_REG)
864           (plus:P (reg:P SP_REG) (const_int -4))))
865         (match_operand:QI 0 "register_no_sp_elim_operand" "r"))]
866   "TARGET_H8300H || TARGET_H8300S"
867   "mov.l\\t%S0,@-er7"
868   [(set_attr "length" "4")])
870 (define_insn "*pushhi1_h8300hs_<mode>"
871   [(set (mem:HI
872         (pre_modify:P
873           (reg:P SP_REG)
874           (plus:P (reg:P SP_REG) (const_int -4))))
875         (match_operand:HI 0 "register_no_sp_elim_operand" "r"))]
876   "TARGET_H8300H || TARGET_H8300S"
877   "mov.l\\t%S0,@-er7"
878   [(set_attr "length" "4")])
880 ;; ----------------------------------------------------------------------
881 ;; TEST INSTRUCTIONS
882 ;; ----------------------------------------------------------------------
884 (define_insn ""
885   [(set (cc0) 
886         (compare (zero_extract:QI (match_operand:QI 0 "bit_memory_operand" "r,U")
887                                   (const_int 1)
888                                   (match_operand 1 "const_int_operand" "n,n"))
889                  (const_int 0)))]
890   "TARGET_H8300"
891   "btst %Z1,%Y0"
892   [(set_attr "length" "2,4")
893    (set_attr "cc" "set_zn,set_zn")])
895 (define_insn ""
896   [(set (cc0)
897         (compare (zero_extract:HI (match_operand:HI 0 "register_operand" "r")
898                                   (const_int 1)
899                                   (match_operand 1 "const_int_operand" "n"))
900                  (const_int 0)))]
901   "TARGET_H8300"
902   "btst %Z1,%Y0"
903   [(set_attr "length" "2")
904    (set_attr "cc" "set_zn")])
906 (define_insn_and_split "*tst_extzv_1_n"
907   [(set (cc0) 
908         (compare (zero_extract:SI (match_operand:QI 0 "general_operand_src" "r,U,mn>")
909                                   (const_int 1)
910                                   (match_operand 1 "const_int_operand" "n,n,n"))
911                  (const_int 0)))
912    (clobber (match_scratch:QI 2 "=X,X,&r"))]
913   "TARGET_H8300H || TARGET_H8300S"
914   "@
915    btst\\t%Z1,%Y0
916    btst\\t%Z1,%Y0
917    #"
918   "&& reload_completed
919    && !satisfies_constraint_U (operands[0])"
920   [(set (match_dup 2)
921         (match_dup 0))
922    (parallel [(set (cc0) (compare (zero_extract:SI (match_dup 2)
923                                                    (const_int 1)
924                                                    (match_dup 1))
925                                   (const_int 0)))
926               (clobber (scratch:QI))])]
927   ""
928   [(set_attr "length" "2,8,10")
929    (set_attr "cc" "set_zn,set_zn,set_zn")])
931 (define_insn ""
932   [(set (cc0) 
933         (compare (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
934                                   (const_int 1)
935                                   (match_operand 1 "const_int_operand" "n"))
936                  (const_int 0)))]
937   "(TARGET_H8300H || TARGET_H8300S)
938     && INTVAL (operands[1]) <= 15"
939   "btst %Z1,%Y0"
940   [(set_attr "length" "2")
941    (set_attr "cc" "set_zn")])
943 (define_insn_and_split "*tstsi_upper_bit"
944   [(set (cc0) 
945         (compare (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
946                                   (const_int 1)
947                                   (match_operand 1 "const_int_operand" "n"))
948                  (const_int 0)))
949    (clobber (match_scratch:SI 2 "=&r"))]
950   "(TARGET_H8300H || TARGET_H8300S)
951     && INTVAL (operands[1]) >= 16"
952   "#"
953   "&& reload_completed"
954   [(set (match_dup 2)
955         (ior:SI (and:SI (match_dup 2)
956                         (const_int -65536))
957                 (lshiftrt:SI (match_dup 0)
958                              (const_int 16))))
959    (set (cc0)
960         (compare (zero_extract:SI (match_dup 2)
961                                   (const_int 1)
962                                   (match_dup 3))
963                  (const_int 0)))]
964   {
965     operands[3] = GEN_INT (INTVAL (operands[1]) - 16);
966   })
968 (define_insn "*tstsi_variable_bit"
969   [(set (cc0)
970         (compare (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
971                                   (const_int 1)
972                                   (and:SI (match_operand:SI 1 "register_operand" "r")
973                                           (const_int 7)))
974                  (const_int 0)))]
975   "TARGET_H8300H || TARGET_H8300S"
976   "btst %w1,%w0"
977   [(set_attr "length" "2")
978    (set_attr "cc" "set_zn")])
980 (define_insn_and_split "*tstsi_variable_bit_qi"
981   [(set (cc0)
982         (compare (zero_extract:SI (zero_extend:SI (match_operand:QI 0 "general_operand_src" "r,U,mn>"))
983                                   (const_int 1)
984                                   (and:SI (match_operand:SI 1 "register_operand" "r,r,r")
985                                           (const_int 7)))
986                  (const_int 0)))
987    (clobber (match_scratch:QI 2 "=X,X,&r"))]
988   "TARGET_H8300H || TARGET_H8300S"
989   "@
990    btst\\t%w1,%X0
991    btst\\t%w1,%X0
992    #"
993   "&& reload_completed
994    && !satisfies_constraint_U (operands[0])"
995   [(set (match_dup 2)
996         (match_dup 0))
997    (parallel [(set (cc0)
998                    (compare (zero_extract:SI (zero_extend:SI (match_dup 2))
999                                              (const_int 1)
1000                                              (and:SI (match_dup 1)
1001                                                      (const_int 7)))
1002                             (const_int 0)))
1003               (clobber (scratch:QI))])]
1004   ""
1005   [(set_attr "length" "2,8,10")
1006    (set_attr "cc" "set_zn,set_zn,set_zn")])
1008 (define_insn "*tstqi"
1009   [(set (cc0) 
1010         (compare (match_operand:QI 0 "register_operand" "r")
1011                  (const_int 0)))]
1012   ""
1013   "mov.b        %X0,%X0"
1014   [(set_attr "length" "2")
1015    (set_attr "cc" "set_znv")])
1017 (define_insn "*tsthi"
1018   [(set (cc0)
1019         (compare (match_operand:HI 0 "register_operand" "r")
1020                  (const_int 0)))]
1021   ""
1022   "mov.w        %T0,%T0"
1023   [(set_attr "length" "2")
1024    (set_attr "cc" "set_znv")])
1026 (define_insn "*tsthi_upper"
1027   [(set (cc0)
1028         (compare (and:HI (match_operand:HI 0 "register_operand" "r")
1029                          (const_int -256))
1030                  (const_int 0)))]
1031   ""
1032   "mov.b        %t0,%t0"
1033   [(set_attr "length" "2")
1034    (set_attr "cc" "set_znv")])
1036 (define_insn "*tstsi"
1037   [(set (cc0)
1038         (compare (match_operand:SI 0 "register_operand" "r")
1039                  (const_int 0)))]
1040   "TARGET_H8300H || TARGET_H8300S"
1041   "mov.l        %S0,%S0"
1042   [(set_attr "length" "2")
1043    (set_attr "cc" "set_znv")])
1045 (define_insn "*tstsi_upper"
1046   [(set (cc0)
1047         (compare (and:SI (match_operand:SI 0 "register_operand" "r")
1048                          (const_int -65536))
1049                  (const_int 0)))]
1050   ""
1051   "mov.w        %e0,%e0"
1052   [(set_attr "length" "2")
1053    (set_attr "cc" "set_znv")])
1055 (define_insn "*cmpqi"
1056   [(set (cc0)
1057         (compare (match_operand:QI 0 "h8300_dst_operand" "rQ")
1058                  (match_operand:QI 1 "h8300_src_operand" "rQi")))]
1059   ""
1060   "cmp.b        %X1,%X0"
1061   [(set_attr "length_table" "addb")
1062    (set_attr "cc" "compare")])
1064 (define_insn "*cmphi_h8300_znvc"
1065   [(set (cc0)
1066         (compare (match_operand:HI 0 "register_operand" "r")
1067                  (match_operand:HI 1 "register_operand" "r")))]
1068   "TARGET_H8300"
1069   "cmp.w        %T1,%T0"
1070   [(set_attr "length" "2")
1071    (set_attr "cc" "compare")])
1073 (define_insn "*cmphi_h8300hs_znvc"
1074   [(set (cc0)
1075         (compare (match_operand:HI 0 "h8300_dst_operand" "rU,rQ")
1076                  (match_operand:HI 1 "h8300_src_operand" "P3>X,rQi")))]
1077   "TARGET_H8300H || TARGET_H8300S"
1079   switch (which_alternative)
1080     {
1081     case 0:
1082       if (!TARGET_H8300SX)
1083         return "cmp.w   %T1,%T0";
1084       else
1085         return "cmp.w   %T1:3,%T0";
1086     case 1:
1087       return "cmp.w     %T1,%T0";
1088     default:
1089       gcc_unreachable ();
1090       }
1092   [(set_attr "length_table" "short_immediate,addw")
1093    (set_attr "cc" "compare,compare")])
1095 (define_insn "cmpsi"
1096   [(set (cc0)
1097         (compare (match_operand:SI 0 "h8300_dst_operand" "r,rQ")
1098                  (match_operand:SI 1 "h8300_src_operand" "P3>X,rQi")))]
1099   "TARGET_H8300H || TARGET_H8300S"
1101   switch (which_alternative)
1102     {
1103     case 0:
1104       if (!TARGET_H8300SX)
1105         return "cmp.l   %S1,%S0";
1106       else
1107         return "cmp.l   %S1:3,%S0";
1108     case 1:
1109       return "cmp.l     %S1,%S0";
1110     default:
1111       gcc_unreachable ();
1112     }
1114   [(set_attr "length" "2,*")
1115    (set_attr "length_table" "*,addl")
1116    (set_attr "cc" "compare,compare")])
1118 ;; ----------------------------------------------------------------------
1119 ;; ADD INSTRUCTIONS
1120 ;; ----------------------------------------------------------------------
1122 (define_expand "addqi3"
1123   [(set (match_operand:QI 0 "register_operand" "")
1124         (plus:QI (match_operand:QI 1 "register_operand" "")
1125                  (match_operand:QI 2 "h8300_src_operand" "")))]
1126   ""
1127   "")
1129 (define_insn "*addqi3"
1130   [(set (match_operand:QI 0 "h8300_dst_operand" "=rQ")
1131         (plus:QI (match_operand:QI 1 "h8300_dst_operand" "%0")
1132                  (match_operand:QI 2 "h8300_src_operand" "rQi")))]
1133   "h8300_operands_match_p (operands)"
1134   "add.b        %X2,%X0"
1135   [(set_attr "length_table" "addb")
1136    (set_attr "cc" "set_zn")])
1138 (define_expand "addhi3"
1139   [(set (match_operand:HI 0 "register_operand" "")
1140         (plus:HI (match_operand:HI 1 "register_operand" "")
1141                  (match_operand:HI 2 "h8300_src_operand" "")))]
1142   ""
1143   "")
1145 (define_insn "*addhi3_h8300"
1146   [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r")
1147         (plus:HI (match_operand:HI 1 "register_operand" "%0,0,0,0,0")
1148                  (match_operand:HI 2 "h8300_src_operand" "L,N,J,n,r")))]
1149   "TARGET_H8300"
1150   "@
1151    adds %2,%T0
1152    subs %G2,%T0
1153    add.b        %t2,%t0
1154    add.b        %s2,%s0\;addx   %t2,%t0
1155    add.w        %T2,%T0"
1156   [(set_attr "length" "2,2,2,4,2")
1157    (set_attr "cc" "none_0hit,none_0hit,clobber,clobber,set_zn")])
1159 ;; This splitter is very important to make the stack adjustment
1160 ;; interrupt-safe.  The combination of add.b and addx is unsafe!
1162 ;; We apply this split after the peephole2 pass so that we won't end
1163 ;; up creating too many adds/subs when a scratch register is
1164 ;; available, which is actually a common case because stack unrolling
1165 ;; tends to happen immediately after a function call.
1167 (define_split
1168   [(set (match_operand:HI 0 "stack_pointer_operand" "")
1169         (plus:HI (match_dup 0)
1170                  (match_operand 1 "const_int_gt_2_operand" "")))]
1171   "TARGET_H8300 && epilogue_completed"
1172   [(const_int 0)]
1173   {
1174     split_adds_subs (HImode, operands); 
1175     DONE;
1176   })
1178 (define_peephole2
1179   [(match_scratch:HI 2 "r")
1180    (set (match_operand:HI 0 "stack_pointer_operand" "")
1181         (plus:HI (match_dup 0)
1182                  (match_operand:HI 1 "const_int_ge_8_operand" "")))]
1183   "TARGET_H8300"
1184   [(set (match_dup 2)
1185         (match_dup 1))
1186    (set (match_dup 0)
1187         (plus:HI (match_dup 0)
1188                  (match_dup 2)))]
1189   "")
1191 (define_insn "*addhi3_h8300hs"
1192   [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r")
1193         (plus:HI (match_operand:HI 1 "register_operand" "%0,0,0,0,0")
1194                  (match_operand:HI 2 "h8300_src_operand" "L,N,J,n,r")))]
1195   "(TARGET_H8300H || TARGET_H8300S) && !TARGET_H8300SX"
1196   "@
1197    adds %2,%S0
1198    subs %G2,%S0
1199    add.b        %t2,%t0
1200    add.w        %T2,%T0
1201    add.w        %T2,%T0"
1202   [(set_attr "length" "2,2,2,4,2")
1203    (set_attr "cc" "none_0hit,none_0hit,clobber,set_zn,set_zn")])
1205 (define_insn "*addhi3_incdec"
1206   [(set (match_operand:HI 0 "register_operand" "=r,r")
1207         (unspec:HI [(match_operand:HI 1 "register_operand" "0,0")
1208                     (match_operand:HI 2 "incdec_operand" "M,O")]
1209                    UNSPEC_INCDEC))]
1210   "TARGET_H8300H || TARGET_H8300S"
1211   "@
1212    inc.w        %2,%T0
1213    dec.w        %G2,%T0"
1214   [(set_attr "length" "2,2")
1215    (set_attr "cc" "set_zn,set_zn")])
1217 (define_insn "*addhi3_h8sx"
1218   [(set (match_operand:HI 0 "h8300_dst_operand" "=rU,rU,r,rQ")
1219         (plus:HI (match_operand:HI 1 "h8300_dst_operand" "%0,0,0,0")
1220                  (match_operand:HI 2 "h8300_src_operand" "P3>X,P3<X,J,rQi")))]
1221   "TARGET_H8300SX && h8300_operands_match_p (operands)"
1222   "@
1223    add.w        %T2:3,%T0
1224    sub.w        %G2:3,%T0
1225    add.b        %t2,%t0
1226    add.w        %T2,%T0"
1227   [(set_attr "length_table" "short_immediate,short_immediate,*,addw")
1228    (set_attr "length" "*,*,2,*")
1229    (set_attr "cc" "set_zn")])
1231 (define_split
1232   [(set (match_operand:HI 0 "register_operand" "")
1233         (plus:HI (match_dup 0)
1234                  (match_operand:HI 1 "two_insn_adds_subs_operand" "")))]
1235   ""
1236   [(const_int 0)]
1237   {
1238     split_adds_subs (HImode, operands); 
1239     DONE;
1240   })
1242 (define_expand "addsi3"
1243   [(set (match_operand:SI 0 "register_operand" "")
1244         (plus:SI (match_operand:SI 1 "register_operand" "")
1245                  (match_operand:SI 2 "h8300_src_operand" "")))]
1246   ""
1247   "")
1249 (define_insn "*addsi_h8300"
1250   [(set (match_operand:SI 0 "register_operand" "=r,r")
1251         (plus:SI (match_operand:SI 1 "register_operand" "%0,0")
1252                  (match_operand:SI 2 "h8300_src_operand" "n,r")))]
1253   "TARGET_H8300"
1255   return output_plussi (operands);
1257   [(set (attr "length")
1258         (symbol_ref "compute_plussi_length (operands)"))
1259    (set (attr "cc")
1260         (symbol_ref "compute_plussi_cc (operands)"))])
1262 (define_insn "*addsi_h8300hs"
1263   [(set (match_operand:SI 0 "h8300_dst_operand" "=rQ,rQ")
1264         (plus:SI (match_operand:SI 1 "h8300_dst_operand" "%0,0")
1265                  (match_operand:SI 2 "h8300_src_operand" "i,rQ")))]
1266   "(TARGET_H8300H || TARGET_H8300S) && h8300_operands_match_p (operands)"
1267 {  
1268   return output_plussi (operands);
1270   [(set (attr "length")
1271         (symbol_ref "compute_plussi_length (operands)"))
1272    (set (attr "cc")
1273         (symbol_ref "compute_plussi_cc (operands)"))])
1275 (define_insn "*addsi3_incdec"
1276   [(set (match_operand:SI 0 "register_operand" "=r,r")
1277         (unspec:SI [(match_operand:SI 1 "register_operand" "0,0")
1278                     (match_operand:SI 2 "incdec_operand" "M,O")]
1279                    UNSPEC_INCDEC))]
1280   "TARGET_H8300H || TARGET_H8300S"
1281   "@
1282    inc.l        %2,%S0
1283    dec.l        %G2,%S0"
1284   [(set_attr "length" "2,2")
1285    (set_attr "cc" "set_zn,set_zn")])
1287 (define_split
1288   [(set (match_operand:SI 0 "register_operand" "")
1289         (plus:SI (match_dup 0)
1290                  (match_operand:SI 1 "two_insn_adds_subs_operand" "")))]
1291   "TARGET_H8300H || TARGET_H8300S"
1292   [(const_int 0)]
1293   {
1294     split_adds_subs (SImode, operands); 
1295     DONE;
1296   })
1298 ;; ----------------------------------------------------------------------
1299 ;; SUBTRACT INSTRUCTIONS
1300 ;; ----------------------------------------------------------------------
1302 (define_expand "subqi3"
1303   [(set (match_operand:QI 0 "register_operand" "")
1304         (minus:QI (match_operand:QI 1 "register_operand" "")
1305                   (match_operand:QI 2 "h8300_src_operand" "")))]
1306   ""
1307   "")
1309 (define_insn "*subqi3"
1310   [(set (match_operand:QI 0 "h8300_dst_operand" "=rQ")
1311         (minus:QI (match_operand:QI 1 "h8300_dst_operand" "0")
1312                   (match_operand:QI 2 "h8300_dst_operand" "rQ")))]
1313   "h8300_operands_match_p (operands)"
1314   "sub.b        %X2,%X0"
1315   [(set_attr "length_table" "addb")
1316    (set_attr "cc" "set_zn")])
1318 (define_expand "subhi3"
1319   [(set (match_operand:HI 0 "register_operand" "")
1320         (minus:HI (match_operand:HI 1 "register_operand" "")
1321                   (match_operand:HI 2 "h8300_src_operand" "")))]
1322   ""
1323   "")
1325 (define_insn "*subhi3_h8300"
1326   [(set (match_operand:HI 0 "register_operand" "=r,r")
1327         (minus:HI (match_operand:HI 1 "register_operand" "0,0")
1328                   (match_operand:HI 2 "h8300_src_operand" "r,n")))]
1329   "TARGET_H8300"
1330   "@
1331    sub.w        %T2,%T0
1332    add.b        %E2,%s0\;addx   %F2,%t0"
1333   [(set_attr "length" "2,4")
1334    (set_attr "cc" "set_zn,clobber")])
1336 (define_insn "*subhi3_h8300hs"
1337   [(set (match_operand:HI 0 "h8300_dst_operand" "=rQ,rQ")
1338         (minus:HI (match_operand:HI 1 "h8300_dst_operand" "0,0")
1339                   (match_operand:HI 2 "h8300_src_operand" "rQ,i")))]
1340   "(TARGET_H8300H || TARGET_H8300S) && h8300_operands_match_p (operands)"
1341   "@
1342    sub.w        %T2,%T0
1343    sub.w        %T2,%T0"
1344   [(set_attr "length_table" "addw")
1345    (set_attr "cc" "set_zn")])
1347 (define_expand "subsi3"
1348   [(set (match_operand:SI 0 "register_operand" "")
1349         (minus:SI (match_operand:SI 1 "register_operand" "")
1350                   (match_operand:SI 2 "h8300_src_operand" "")))]
1351   ""
1352   {
1353     if (TARGET_H8300)
1354       operands[2] = force_reg (SImode, operands[2]);
1355   })
1357 (define_insn "*subsi3_h8300"
1358   [(set (match_operand:SI 0 "register_operand" "=r")
1359         (minus:SI (match_operand:SI 1 "register_operand" "0")
1360                   (match_operand:SI 2 "register_operand" "r")))]
1361   "TARGET_H8300"
1362   "sub.w        %f2,%f0\;subx   %y2,%y0\;subx   %z2,%z0"
1363   [(set_attr "length" "6")])
1365 (define_insn "*subsi3_h8300hs"
1366   [(set (match_operand:SI 0 "h8300_dst_operand" "=rQ,rQ")
1367         (minus:SI (match_operand:SI 1 "h8300_dst_operand" "0,0")
1368                   (match_operand:SI 2 "h8300_src_operand" "rQ,i")))]
1369   "(TARGET_H8300H || TARGET_H8300S) && h8300_operands_match_p (operands)"
1370   "@
1371    sub.l        %S2,%S0
1372    sub.l        %S2,%S0"
1373   [(set_attr "length_table" "addl")
1374    (set_attr "cc" "set_zn")])
1376 ;; ----------------------------------------------------------------------
1377 ;; MULTIPLY INSTRUCTIONS
1378 ;; ----------------------------------------------------------------------
1380 ;; Note that the H8/300 can only handle umulqihi3.
1382 (define_expand "mulqihi3"
1383   [(set (match_operand:HI 0 "register_operand" "")
1384         (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" ""))
1385                  ;; intentionally-mismatched modes
1386                  (match_operand:QI 2 "reg_or_nibble_operand" "")))]
1387   "TARGET_H8300H || TARGET_H8300S"
1388   {
1389     if (GET_MODE (operands[2]) != VOIDmode)
1390       operands[2] = gen_rtx_SIGN_EXTEND (HImode, operands[2]);
1391   })
1393 (define_insn "*mulqihi3_const"
1394   [(set (match_operand:HI 0 "register_operand" "=r")
1395         (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "%0"))
1396                  (match_operand:QI 2 "nibble_operand" "IP4>X")))]
1397   "TARGET_H8300SX"
1398   "mulxs.b      %X2,%T0"
1399   [(set_attr "length" "4")
1400    (set_attr "cc" "set_zn")])
1402 (define_insn "*mulqihi3"
1403   [(set (match_operand:HI 0 "register_operand" "=r")
1404         (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "%0"))
1405                  (sign_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
1406   "TARGET_H8300H || TARGET_H8300S"
1407   "mulxs.b      %X2,%T0"
1408   [(set_attr "length" "4")
1409    (set_attr "cc" "set_zn")])
1411 (define_expand "mulhisi3"
1412   [(set (match_operand:SI 0 "register_operand" "")
1413         (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" ""))
1414                  ;; intentionally-mismatched modes
1415                  (match_operand:HI 2 "reg_or_nibble_operand" "")))]
1416   "TARGET_H8300H || TARGET_H8300S"
1417   {
1418     if (GET_MODE (operands[2]) != VOIDmode)
1419       operands[2] = gen_rtx_SIGN_EXTEND (SImode, operands[2]);
1420   })
1422 (define_insn "*mulhisi3_const"
1423   [(set (match_operand:SI 0 "register_operand" "=r")
1424         (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" "%0"))
1425                  (match_operand:SI 2 "nibble_operand" "IP4>X")))]
1426   "TARGET_H8300SX"
1427   "mulxs.w      %T2,%S0"
1428   [(set_attr "length" "4")
1429    (set_attr "cc" "set_zn")])
1431 (define_insn "*mulhisi3"
1432   [(set (match_operand:SI 0 "register_operand" "=r")
1433         (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" "%0"))
1434                  (sign_extend:SI (match_operand:HI 2 "register_operand" "r"))))]
1435   "TARGET_H8300H || TARGET_H8300S"
1436   "mulxs.w      %T2,%S0"
1437   [(set_attr "length" "4")
1438    (set_attr "cc" "set_zn")])
1440 (define_expand "umulqihi3"
1441   [(set (match_operand:HI 0 "register_operand" "")
1442         (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" ""))
1443                  ;; intentionally-mismatched modes
1444                  (match_operand:QI 2 "reg_or_nibble_operand" "")))]
1445   "TARGET_H8300H || TARGET_H8300S"
1446   {
1447     if (GET_MODE (operands[2]) != VOIDmode)
1448       operands[2] = gen_rtx_ZERO_EXTEND (HImode, operands[2]);
1449   })
1451 (define_insn "*umulqihi3_const"
1452   [(set (match_operand:HI 0 "register_operand" "=r")
1453         (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "%0"))
1454                  (match_operand:QI 2 "nibble_operand" "IP4>X")))]
1455   "TARGET_H8300SX"
1456   "mulxu.b      %X2,%T0"
1457   [(set_attr "length" "4")
1458    (set_attr "cc" "set_zn")])
1460 (define_insn "*umulqihi3"
1461   [(set (match_operand:HI 0 "register_operand" "=r")
1462         (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "%0"))
1463                  (zero_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
1464   ""
1465   "mulxu.b      %X2,%T0"
1466   [(set_attr "length" "2")
1467    (set_attr "cc" "none_0hit")])
1469 (define_expand "umulhisi3"
1470   [(set (match_operand:SI 0 "register_operand" "")
1471         (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" ""))
1472                  ;; intentionally-mismatched modes
1473                  (match_operand:HI 2 "reg_or_nibble_operand" "")))]
1474   "TARGET_H8300H || TARGET_H8300S"
1475   {
1476     if (GET_MODE (operands[2]) != VOIDmode)
1477       operands[2] = gen_rtx_ZERO_EXTEND (SImode, operands[2]);
1478   })
1480 (define_insn "*umulhisi3_const"
1481   [(set (match_operand:SI 0 "register_operand" "=r")
1482         (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "%0"))
1483                  (match_operand:SI 2 "nibble_operand" "IP4>X")))]
1484   "TARGET_H8300SX"
1485   "mulxu.w      %T2,%S0"
1486   [(set_attr "length" "4")
1487    (set_attr "cc" "set_zn")])
1489 (define_insn "*umulhisi3"
1490   [(set (match_operand:SI 0 "register_operand" "=r")
1491         (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "%0"))
1492                  (zero_extend:SI (match_operand:HI 2 "register_operand" "r"))))]
1493   "TARGET_H8300H || TARGET_H8300S"
1494   "mulxu.w      %T2,%S0"
1495   [(set_attr "length" "2")
1496    (set_attr "cc" "none_0hit")])
1498 ;; We could have used mulu.[wl] here, but mulu.[lw] is only available
1499 ;; on a H8SX with a multiplier, whereas muls.w seems to be available
1500 ;; on all H8SX variants.
1502 (define_insn "mulhi3"
1503   [(set (match_operand:HI 0 "register_operand" "=r")
1504         (mult:HI (match_operand:HI 1 "register_operand" "%0")
1505                  (match_operand:HI 2 "reg_or_nibble_operand" "r IP4>X")))]
1506   "TARGET_H8300SX"
1507   "muls.w\\t%T2,%T0"
1508   [(set_attr "length" "2")
1509    (set_attr "cc" "set_zn")])
1511 (define_insn "mulsi3"
1512   [(set (match_operand:SI 0 "register_operand" "=r")
1513         (mult:SI (match_operand:SI 1 "register_operand" "%0")
1514                  (match_operand:SI 2 "reg_or_nibble_operand" "r IP4>X")))]
1515   "TARGET_H8300SX"
1516   "muls.l\\t%S2,%S0"
1517   [(set_attr "length" "2")
1518    (set_attr "cc" "set_zn")])
1520 (define_insn "smulsi3_highpart"
1521   [(set (match_operand:SI 0 "register_operand" "=r")
1522         (truncate:SI
1523          (lshiftrt:DI
1524           (mult:DI
1525            (sign_extend:DI (match_operand:SI 1 "register_operand" "%0"))
1526            (sign_extend:DI (match_operand:SI 2 "reg_or_nibble_operand" "r IP4>X")))
1527           (const_int 32))))]
1528   "TARGET_H8300SXMUL"
1529   "muls/u.l\\t%S2,%S0"
1530   [(set_attr "length" "2")
1531    (set_attr "cc" "set_zn")])
1533 (define_insn "umulsi3_highpart"
1534   [(set (match_operand:SI 0 "register_operand" "=r")
1535         (truncate:SI
1536           (ashiftrt:DI
1537             (mult:DI
1538               (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
1539               (zero_extend:DI (match_operand:SI 2 "reg_or_nibble_operand" "r IP4>X")))
1540             (const_int 32))))]
1541   "TARGET_H8300SX"
1542   "mulu/u.l\\t%S2,%S0"
1543   [(set_attr "length" "2")
1544    (set_attr "cc" "none_0hit")])
1546 ;; This is a "bridge" instruction.  Combine can't cram enough insns
1547 ;; together to crate a MAC instruction directly, but it can create
1548 ;; this instruction, which then allows combine to create the real
1549 ;; MAC insn.
1551 ;; Unfortunately, if combine doesn't create a MAC instruction, this
1552 ;; insn must generate reasonably correct code.  Egad.
1554 (define_insn ""
1555   [(set (match_operand:SI 0 "register_operand" "=a")
1556         (mult:SI
1557           (sign_extend:SI
1558             (mem:HI (post_inc:SI (match_operand:SI 1 "register_operand" "r"))))
1559           (sign_extend:SI
1560             (mem:HI (post_inc:SI (match_operand:SI 2 "register_operand" "r"))))))]
1561   "TARGET_MAC"
1562   "clrmac\;mac  @%2+,@%1+"
1563   [(set_attr "length" "6")
1564    (set_attr "cc" "none_0hit")])
1566 (define_insn ""
1567   [(set (match_operand:SI 0 "register_operand" "=a")
1568         (plus:SI (mult:SI
1569           (sign_extend:SI (mem:HI
1570             (post_inc:SI (match_operand:SI 1 "register_operand" "r"))))
1571           (sign_extend:SI (mem:HI
1572             (post_inc:SI (match_operand:SI 2 "register_operand" "r")))))
1573               (match_operand:SI 3 "register_operand" "0")))]
1574   "TARGET_MAC"
1575   "mac  @%2+,@%1+"
1576   [(set_attr "length" "4")
1577    (set_attr "cc" "none_0hit")])
1579 ;; ----------------------------------------------------------------------
1580 ;; DIVIDE/MOD INSTRUCTIONS
1581 ;; ----------------------------------------------------------------------
1583 (define_insn "udivhi3"
1584   [(set (match_operand:HI 0 "register_operand" "=r")
1585         (udiv:HI (match_operand:HI 1 "register_operand" "0")
1586                  (match_operand:HI 2 "reg_or_nibble_operand" "r IP4>X")))]
1587   "TARGET_H8300SX"
1588   "divu.w\\t%T2,%T0"
1589   [(set_attr "length" "2")])
1590   
1591 (define_insn "divhi3"
1592   [(set (match_operand:HI 0 "register_operand" "=r")
1593         (div:HI (match_operand:HI 1 "register_operand" "0")
1594                 (match_operand:HI 2 "reg_or_nibble_operand" "r IP4>X")))]
1595   "TARGET_H8300SX"
1596   "divs.w\\t%T2,%T0"
1597   [(set_attr "length" "2")])
1598   
1599 (define_insn "udivsi3"
1600   [(set (match_operand:SI 0 "register_operand" "=r")
1601         (udiv:SI (match_operand:SI 1 "register_operand" "0")
1602                  (match_operand:SI 2 "reg_or_nibble_operand" "r IP4>X")))]
1603   "TARGET_H8300SX"
1604   "divu.l\\t%S2,%S0"
1605   [(set_attr "length" "2")])
1606   
1607 (define_insn "divsi3"
1608   [(set (match_operand:SI 0 "register_operand" "=r")
1609         (div:SI (match_operand:SI 1 "register_operand" "0")
1610                 (match_operand:SI 2 "reg_or_nibble_operand" "r IP4>X")))]
1611   "TARGET_H8300SX"
1612   "divs.l\\t%S2,%S0"
1613   [(set_attr "length" "2")])
1614   
1615 (define_insn "udivmodqi4"
1616   [(set (match_operand:QI 0 "register_operand" "=r")
1617         (truncate:QI
1618           (udiv:HI
1619             (match_operand:HI 1 "register_operand" "0")
1620             (zero_extend:HI (match_operand:QI 2 "register_operand" "r")))))
1621    (set (match_operand:QI 3 "register_operand" "=r")
1622         (truncate:QI
1623           (umod:HI
1624             (match_dup 1)
1625             (zero_extend:HI (match_dup 2)))))]
1626   ""
1628   if (find_reg_note (insn, REG_UNUSED, operands[3]))
1629     return "divxu.b\\t%X2,%T0";
1630   else
1631     return "divxu.b\\t%X2,%T0\;mov.b\\t%t0,%s3";
1633   [(set_attr "length" "4")])
1635 (define_insn "divmodqi4"
1636   [(set (match_operand:QI 0 "register_operand" "=r")
1637         (truncate:QI
1638           (div:HI
1639             (match_operand:HI 1 "register_operand" "0")
1640             (sign_extend:HI (match_operand:QI 2 "register_operand" "r")))))
1641    (set (match_operand:QI 3 "register_operand" "=r")
1642         (truncate:QI
1643           (mod:HI
1644             (match_dup 1)
1645             (sign_extend:HI (match_dup 2)))))]
1646   "TARGET_H8300H || TARGET_H8300S"
1648   if (find_reg_note (insn, REG_UNUSED, operands[3]))
1649     return "divxs.b\\t%X2,%T0";
1650   else
1651     return "divxs.b\\t%X2,%T0\;mov.b\\t%t0,%s3";
1653   [(set_attr "length" "6")])
1655 (define_insn "udivmodhi4"
1656   [(set (match_operand:HI 0 "register_operand" "=r")
1657         (truncate:HI
1658           (udiv:SI
1659             (match_operand:SI 1 "register_operand" "0")
1660             (zero_extend:SI (match_operand:HI 2 "register_operand" "r")))))
1661    (set (match_operand:HI 3 "register_operand" "=r")
1662         (truncate:HI
1663           (umod:SI
1664             (match_dup 1)
1665             (zero_extend:SI (match_dup 2)))))]
1666   "TARGET_H8300H || TARGET_H8300S"
1668   if (find_reg_note (insn, REG_UNUSED, operands[3]))
1669     return "divxu.w\\t%T2,%S0";
1670   else
1671     return "divxu.w\\t%T2,%S0\;mov.w\\t%e0,%f3";
1673   [(set_attr "length" "4")])
1675 (define_insn "divmodhi4"
1676   [(set (match_operand:HI 0 "register_operand" "=r")
1677         (truncate:HI
1678           (div:SI
1679             (match_operand:SI 1 "register_operand" "0")
1680             (sign_extend:SI (match_operand:HI 2 "register_operand" "r")))))
1681    (set (match_operand:HI 3 "register_operand" "=r")
1682         (truncate:HI
1683           (mod:SI
1684             (match_dup 1)
1685             (sign_extend:SI (match_dup 2)))))]
1686   "TARGET_H8300H || TARGET_H8300S"
1688   if (find_reg_note (insn, REG_UNUSED, operands[3]))
1689     return "divxs.w\\t%T2,%S0";
1690   else
1691     return "divxs.w\\t%T2,%S0\;mov.w\\t%e0,%f3";
1693   [(set_attr "length" "6")])
1695 ;; ----------------------------------------------------------------------
1696 ;; AND INSTRUCTIONS
1697 ;; ----------------------------------------------------------------------
1699 (define_insn "bclrqi_msx"
1700   [(set (match_operand:QI 0 "bit_register_indirect_operand" "=WU")
1701         (and:QI (match_operand:QI 1 "bit_register_indirect_operand" "%0")
1702                 (match_operand:QI 2 "single_zero_operand" "Y0")))]
1703   "TARGET_H8300SX && rtx_equal_p (operands[0], operands[1])"
1704   "bclr\\t%W2,%0"
1705   [(set_attr "length" "8")])
1707 (define_split
1708   [(set (match_operand:HI 0 "bit_register_indirect_operand" "=U")
1709         (and:HI (match_operand:HI 1 "bit_register_indirect_operand" "%0")
1710                 (match_operand:HI 2 "single_zero_operand" "Y0")))]
1711   "TARGET_H8300SX"
1712   [(set (match_dup 0)
1713         (and:QI (match_dup 1)
1714                 (match_dup 2)))]
1715   {
1716     if (abs (INTVAL (operands[2])) > 0xFF)
1717       {
1718         operands[0] = adjust_address (operands[0], QImode, 0);
1719         operands[1] = adjust_address (operands[1], QImode, 0);
1720         operands[2] = GEN_INT ((INTVAL (operands[2])) >> 8);
1721       }
1722     else
1723       {
1724         operands[0] = adjust_address (operands[0], QImode, 1);
1725         operands[1] = adjust_address (operands[1], QImode, 1);
1726       }
1727   })
1729 (define_insn "bclrhi_msx"
1730   [(set (match_operand:HI 0 "bit_register_indirect_operand" "=m")
1731         (and:HI (match_operand:HI 1 "bit_register_indirect_operand" "%0")
1732                 (match_operand:HI 2 "single_zero_operand" "Y0")))]
1733   "TARGET_H8300SX"
1734   "bclr\\t%W2,%0"
1735   [(set_attr "length" "8")])
1737 (define_insn "*andqi3_2"
1738   [(set (match_operand:QI 0 "bit_operand" "=U,rQ,r")
1739         (and:QI (match_operand:QI 1 "bit_operand" "%0,0,WU")
1740                 (match_operand:QI 2 "h8300_src_operand" "Y0,rQi,IP1>X")))]
1741   "TARGET_H8300SX"
1742   "@
1743    bclr\\t %W2,%R0
1744    and  %X2,%X0
1745    bfld %2,%1,%R0"
1746   [(set_attr "length" "8,*,8")
1747    (set_attr "length_table" "*,logicb,*")
1748    (set_attr "cc" "none_0hit,set_znv,none_0hit")])
1750 (define_insn "andqi3_1"
1751   [(set (match_operand:QI 0 "bit_operand" "=U,r")
1752         (and:QI (match_operand:QI 1 "bit_operand" "%0,0")
1753                 (match_operand:QI 2 "h8300_src_operand" "Y0,rn")))]
1754   "register_operand (operands[0], QImode)
1755    || single_zero_operand (operands[2], QImode)"
1756   "@
1757    bclr %W2,%R0
1758    and  %X2,%X0"
1759   [(set_attr "length" "2,8")
1760    (set_attr "cc" "none_0hit,set_znv")])
1762 (define_expand "andqi3"
1763   [(set (match_operand:QI 0 "register_operand" "")
1764         (and:QI (match_operand:QI 1 "register_operand" "")
1765                 (match_operand:QI 2 "h8300_src_operand" "")))]
1766   ""
1767   "")
1769 (define_expand "andhi3"
1770   [(set (match_operand:HI 0 "register_operand" "")
1771         (and:HI (match_operand:HI 1 "register_operand" "")
1772                 (match_operand:HI 2 "h8300_src_operand" "")))]
1773   ""
1774   "")
1776 (define_insn "*andorqi3"
1777   [(set (match_operand:QI 0 "register_operand" "=r")
1778         (ior:QI (and:QI (match_operand:QI 2 "register_operand" "r")
1779                         (match_operand:QI 3 "single_one_operand" "n"))
1780                 (match_operand:QI 1 "register_operand" "0")))]
1781   ""
1782   "bld\\t%V3,%X2\;bor\\t%V3,%X0\;bst\\t%V3,%X0"
1783   [(set_attr "length" "6")])
1785 (define_insn "*andorhi3"
1786   [(set (match_operand:HI 0 "register_operand" "=r")
1787         (ior:HI (and:HI (match_operand:HI 2 "register_operand" "r")
1788                         (match_operand:HI 3 "single_one_operand" "n"))
1789                 (match_operand:HI 1 "register_operand" "0")))]
1790   ""
1792   operands[3] = GEN_INT (INTVAL (operands[3]) & 0xffff);
1793   if (INTVAL (operands[3]) > 128)
1794     {
1795       operands[3] = GEN_INT (INTVAL (operands[3]) >> 8);
1796       return "bld\\t%V3,%t2\;bor\\t%V3,%t0\;bst\\t%V3,%t0";
1797     }
1798   return "bld\\t%V3,%s2\;bor\\t%V3,%s0\;bst\\t%V3,%s0";
1800   [(set_attr "length" "6")])
1802 (define_insn "*andorsi3"
1803   [(set (match_operand:SI 0 "register_operand" "=r")
1804         (ior:SI (and:SI (match_operand:SI 2 "register_operand" "r")
1805                         (match_operand:SI 3 "single_one_operand" "n"))
1806                 (match_operand:SI 1 "register_operand" "0")))]
1807   "(INTVAL (operands[3]) & 0xffff) != 0"
1809   operands[3] = GEN_INT (INTVAL (operands[3]) & 0xffff);
1810   if (INTVAL (operands[3]) > 128)
1811     {
1812       operands[3] = GEN_INT (INTVAL (operands[3]) >> 8);
1813       return "bld\\t%V3,%x2\;bor\\t%V3,%x0\;bst\\t%V3,%x0";
1814     }
1815   return "bld\\t%V3,%w2\;bor\\t%V3,%w0\;bst\\t%V3,%w0";
1817   [(set_attr "length" "6")])
1819 (define_insn "*andorsi3_shift_8"
1820   [(set (match_operand:SI 0 "register_operand" "=r")
1821         (ior:SI (and:SI (ashift:SI (match_operand:SI 2 "register_operand" "r")
1822                                    (const_int 8))
1823                         (const_int 65280))
1824                 (match_operand:SI 1 "register_operand" "0")))]
1825   ""
1826   "or.b\\t%w2,%x0"
1827   [(set_attr "length" "2")])
1829 (define_expand "andsi3"
1830   [(set (match_operand:SI 0 "register_operand" "")
1831         (and:SI (match_operand:SI 1 "register_operand" "")
1832                 (match_operand:SI 2 "h8300_src_operand" "")))]
1833   ""
1834   "")
1836 ;; ----------------------------------------------------------------------
1837 ;; OR INSTRUCTIONS
1838 ;; ----------------------------------------------------------------------
1840 (define_insn "bsetqi_msx"
1841   [(set (match_operand:QI 0 "bit_register_indirect_operand" "=WU")
1842         (ior:QI (match_operand:QI 1 "bit_register_indirect_operand" "%0")
1843                 (match_operand:QI 2 "single_one_operand" "Y2")))]
1844   "TARGET_H8300SX && rtx_equal_p (operands[0], operands[1])"
1845   "bset\\t%V2,%0"
1846   [(set_attr "length" "8")])
1848 (define_split
1849   [(set (match_operand:HI 0 "bit_register_indirect_operand" "=U")
1850         (ior:HI (match_operand:HI 1 "bit_register_indirect_operand" "%0")
1851                 (match_operand:HI 2 "single_one_operand" "Y2")))]
1852   "TARGET_H8300SX"
1853   [(set (match_dup 0)
1854         (ior:QI (match_dup 1)
1855                 (match_dup 2)))]
1856   {
1857     if (abs (INTVAL (operands[2])) > 0xFF)
1858       {
1859         operands[0] = adjust_address (operands[0], QImode, 0);
1860         operands[1] = adjust_address (operands[1], QImode, 0);
1861         operands[2] = GEN_INT ((INTVAL (operands[2])) >> 8);
1862       }
1863     else
1864       {
1865         operands[0] = adjust_address (operands[0], QImode, 1);
1866         operands[1] = adjust_address (operands[1], QImode, 1);
1867       }
1868   })
1870 (define_insn "bsethi_msx"
1871   [(set (match_operand:HI 0 "bit_register_indirect_operand" "=m")
1872         (ior:HI (match_operand:HI 1 "bit_register_indirect_operand" "%0")
1873                 (match_operand:HI 2 "single_one_operand" "Y2")))]
1874   "TARGET_H8300SX"
1875   "bset\\t%V2,%0"
1876   [(set_attr "length" "8")])
1878 (define_insn "iorqi3_1"
1879   [(set (match_operand:QI 0 "bit_operand" "=U,rQ")
1880         (ior:QI (match_operand:QI 1 "bit_operand" "%0,0")
1881                 (match_operand:QI 2 "h8300_src_operand" "Y2,rQi")))]
1882   "TARGET_H8300SX || register_operand (operands[0], QImode)
1883    || single_one_operand (operands[2], QImode)"
1884   "@
1885    bset\\t%V2,%R0
1886    or\\t%X2,%X0"
1887   [(set_attr "length" "8,*")
1888    (set_attr "length_table" "*,logicb")
1889    (set_attr "cc" "none_0hit,set_znv")])
1892 (define_expand "iorqi3"
1893   [(set (match_operand:QI 0 "register_operand" "")
1894         (ior:QI (match_operand:QI 1 "register_operand" "")
1895                 (match_operand:QI 2 "h8300_src_operand" "")))]
1896   ""
1897   "")
1899 (define_expand "iorhi3"
1900   [(set (match_operand:HI 0 "register_operand" "")
1901         (ior:HI (match_operand:HI 1 "register_operand" "")
1902                 (match_operand:HI 2 "h8300_src_operand" "")))]
1903   ""
1904   "")
1906 (define_expand "iorsi3"
1907   [(set (match_operand:SI 0 "register_operand" "")
1908         (ior:SI (match_operand:SI 1 "register_operand" "")
1909                 (match_operand:SI 2 "h8300_src_operand" "")))]
1910   ""
1911   "")
1913 ;; ----------------------------------------------------------------------
1914 ;; XOR INSTRUCTIONS
1915 ;; ----------------------------------------------------------------------
1917 (define_insn "bnotqi_msx"
1918   [(set (match_operand:QI 0 "bit_register_indirect_operand" "=WU")
1919         (xor:QI (match_operand:QI 1 "bit_register_indirect_operand" "%0")
1920                 (match_operand:QI 2 "single_one_operand" "Y2")))]
1921   "TARGET_H8300SX
1922    && rtx_equal_p (operands[0], operands[1])"
1923   "bnot\\t%V2,%0"
1924   [(set_attr "length" "8")])
1926 (define_split
1927   [(set (match_operand:HI 0 "bit_register_indirect_operand" "=U")
1928         (xor:HI (match_operand:HI 1 "bit_register_indirect_operand" "%0")
1929                 (match_operand:HI 2 "single_one_operand" "Y2")))]
1930   "TARGET_H8300SX"
1931   [(set (match_dup 0)
1932         (xor:QI (match_dup 1)
1933                 (match_dup 2)))]
1934   {
1935     if (abs (INTVAL (operands[2])) > 0xFF)
1936       {
1937         operands[0] = adjust_address (operands[0], QImode, 0);
1938         operands[1] = adjust_address (operands[1], QImode, 0);
1939         operands[2] = GEN_INT ((INTVAL (operands[2])) >> 8);
1940       }
1941     else
1942       {
1943         operands[0] = adjust_address (operands[0], QImode, 1);
1944         operands[1] = adjust_address (operands[1], QImode, 1);
1945       }
1946   })
1948 (define_insn "bnothi_msx"
1949   [(set (match_operand:HI 0 "bit_register_indirect_operand" "=m")
1950         (xor:HI (match_operand:HI 1 "bit_register_indirect_operand" "%0")
1951                 (match_operand:HI 2 "single_one_operand" "Y2")))]
1952   "TARGET_H8300SX"
1953   "bnot\\t%V2,%0"
1954   [(set_attr "length" "8")])
1956 (define_insn "xorqi3_1"
1957   [(set (match_operand:QI 0 "bit_operand" "=U,r")
1958         (xor:QI (match_operand:QI 1 "bit_operand" "%0,0")
1959                 (match_operand:QI 2 "h8300_src_operand" "Y2,rQi")))]
1960   "TARGET_H8300SX || register_operand (operands[0], QImode)
1961    || single_one_operand (operands[2], QImode)"
1962   "@
1963    bnot\\t%V2,%R0
1964    xor\\t%X2,%X0"
1965   [(set_attr "length" "8,*")
1966    (set_attr "length_table" "*,logicb")
1967    (set_attr "cc" "none_0hit,set_znv")])
1969 (define_expand "xorqi3"
1970   [(set (match_operand:QI 0 "register_operand" "")
1971         (xor:QI (match_operand:QI 1 "register_operand" "")
1972                 (match_operand:QI 2 "h8300_src_operand" "")))]
1973   ""
1974   "")
1976 (define_expand "xorhi3"
1977   [(set (match_operand:HI 0 "register_operand" "")
1978         (xor:HI (match_operand:HI 1 "register_operand" "")
1979                 (match_operand:HI 2 "h8300_src_operand" "")))]
1980   ""
1981   "")
1983 (define_expand "xorsi3"
1984   [(set (match_operand:SI 0 "register_operand" "")
1985         (xor:SI (match_operand:SI 1 "register_operand" "")
1986                 (match_operand:SI 2 "h8300_src_operand" "")))]
1987   ""
1988   "")
1990 ;; ----------------------------------------------------------------------
1991 ;; {AND,IOR,XOR}{HI3,SI3} PATTERNS
1992 ;; ----------------------------------------------------------------------
1994 ;; We need a separate pattern here because machines other than the
1995 ;; original H8300 don't have to split the 16-bit operand into a pair
1996 ;; of high/low instructions, so we can accept literal addresses, that
1997 ;; have to be loaded into a register on H8300.
1999 (define_insn "*logicalhi3_sn"
2000   [(set (match_operand:HI 0 "h8300_dst_operand" "=rQ")
2001         (match_operator:HI 3 "bit_operator"
2002          [(match_operand:HI 1 "h8300_dst_operand" "%0")
2003           (match_operand:HI 2 "h8300_src_operand" "rQi")]))]
2004   "(TARGET_H8300S || TARGET_H8300H) && h8300_operands_match_p (operands)"
2006   return output_logical_op (HImode, operands);
2008   [(set (attr "length")
2009         (symbol_ref "compute_logical_op_length (HImode, operands)"))
2010    (set (attr "cc")
2011         (symbol_ref "compute_logical_op_cc (HImode, operands)"))])
2013 (define_insn "*logicalsi3_sn"
2014   [(set (match_operand:SI 0 "h8300_dst_operand" "=rQ")
2015         (match_operator:SI 3 "bit_operator"
2016          [(match_operand:SI 1 "h8300_dst_operand" "%0")
2017           (match_operand:SI 2 "h8300_src_operand" "rQi")]))]
2018   "(TARGET_H8300S || TARGET_H8300H) && h8300_operands_match_p (operands)"
2020   return output_logical_op (SImode, operands);
2022   [(set (attr "length")
2023         (symbol_ref "compute_logical_op_length (SImode, operands)"))
2024    (set (attr "cc")
2025         (symbol_ref "compute_logical_op_cc (SImode, operands)"))])
2027 (define_insn "*logicalhi3"
2028   [(set (match_operand:HI 0 "h8300_dst_operand" "=rQ")
2029         (match_operator:HI 3 "bit_operator"
2030           [(match_operand:HI 1 "h8300_dst_operand" "%0")
2031            (match_operand:HI 2 "h8300_src_operand" "rQi")]))]
2032   "h8300_operands_match_p (operands)"
2034   return output_logical_op (HImode, operands);
2036   [(set (attr "length")
2037         (symbol_ref "compute_logical_op_length (HImode, operands)"))
2038    (set (attr "cc")
2039         (symbol_ref "compute_logical_op_cc (HImode, operands)"))])
2041 (define_insn "*logicalsi3"
2042   [(set (match_operand:SI 0 "h8300_dst_operand" "=rQ")
2043         (match_operator:SI 3 "bit_operator"
2044          [(match_operand:SI 1 "h8300_dst_operand" "%0")
2045           (match_operand:SI 2 "h8300_src_operand" "rQi")]))]
2046   "h8300_operands_match_p (operands)"
2048   return output_logical_op (SImode, operands);
2050   [(set (attr "length")
2051         (symbol_ref "compute_logical_op_length (SImode, operands)"))
2052    (set (attr "cc")
2053         (symbol_ref "compute_logical_op_cc (SImode, operands)"))])
2055 ;; ----------------------------------------------------------------------
2056 ;; NEGATION INSTRUCTIONS
2057 ;; ----------------------------------------------------------------------
2059 (define_expand "negqi2"
2060   [(set (match_operand:QI 0 "register_operand" "")
2061         (neg:QI (match_operand:QI 1 "register_operand" "")))]
2062   ""
2063   "")
2065 (define_insn "*negqi2"
2066   [(set (match_operand:QI 0 "h8300_dst_operand" "=rQ")
2067         (neg:QI (match_operand:QI 1 "h8300_dst_operand" "0")))]
2068   ""
2069   "neg  %X0"
2070   [(set_attr "length_table" "unary")
2071    (set_attr "cc" "set_zn")])
2073 (define_expand "neghi2"
2074   [(set (match_operand:HI 0 "register_operand" "")
2075         (neg:HI (match_operand:HI 1 "register_operand" "")))]
2076   ""
2077   {
2078     if (TARGET_H8300)
2079       {
2080         emit_insn (gen_neghi2_h8300 (operands[0], operands[1]));
2081         DONE;
2082       }
2083   })
2085 (define_expand "neghi2_h8300"
2086   [(set (match_dup 2)
2087         (not:HI (match_operand:HI 1 "register_operand" "")))
2088    (set (match_dup 2) (plus:HI (match_dup 2) (const_int 1)))
2089    (set (match_operand:HI 0 "register_operand" "")
2090         (match_dup 2))]
2091   ""
2092   {
2093     operands[2] = gen_reg_rtx (HImode);
2094   })
2096 (define_insn "*neghi2_h8300hs"
2097   [(set (match_operand:HI 0 "h8300_dst_operand" "=rQ")
2098         (neg:HI (match_operand:HI 1 "h8300_dst_operand" "0")))]
2099   "(TARGET_H8300H || TARGET_H8300S) && h8300_operands_match_p (operands)"
2100   "neg.w        %T0"
2101   [(set_attr "length_table" "unary")
2102    (set_attr "cc" "set_zn")])
2104 (define_expand "negsi2"
2105   [(set (match_operand:SI 0 "register_operand" "")
2106         (neg:SI (match_operand:SI 1 "register_operand" "")))]
2107   ""
2108   {
2109     if (TARGET_H8300)
2110       {
2111         emit_insn (gen_negsi2_h8300 (operands[0], operands[1]));
2112         DONE;
2113       }
2114   })
2116 (define_expand "negsi2_h8300"
2117   [(set (match_dup 2)
2118         (not:SI (match_operand:SI 1 "register_operand" "")))
2119    (set (match_dup 2) (plus:SI (match_dup 2) (const_int 1)))
2120    (set (match_operand:SI 0 "register_operand" "")
2121         (match_dup 2))]
2122   ""
2123   {
2124     operands[2] = gen_reg_rtx (SImode);
2125   })
2127 (define_insn "*negsi2_h8300hs"
2128   [(set (match_operand:SI 0 "h8300_dst_operand" "=rQ")
2129         (neg:SI (match_operand:SI 1 "h8300_dst_operand" "0")))]
2130   "(TARGET_H8300H || TARGET_H8300S) && h8300_operands_match_p (operands)"
2131   "neg.l        %S0"
2132   [(set_attr "length_table" "unary")
2133    (set_attr "cc" "set_zn")])
2135 (define_expand "negsf2"
2136   [(set (match_operand:SF 0 "register_operand" "")
2137         (neg:SF (match_operand:SF 1 "register_operand" "")))]
2138   ""
2139   "")
2141 (define_insn "*negsf2_h8300"
2142   [(set (match_operand:SF 0 "register_operand" "=r")
2143         (neg:SF (match_operand:SF 1 "register_operand" "0")))]
2144   "TARGET_H8300"
2145   "xor.b\\t#128,%z0"
2146   [(set_attr "length" "2")])
2148 (define_insn "*negsf2_h8300hs"
2149   [(set (match_operand:SF 0 "register_operand" "=r")
2150         (neg:SF (match_operand:SF 1 "register_operand" "0")))]
2151   "TARGET_H8300H || TARGET_H8300S"
2152   "xor.w\\t#32768,%e0"
2153   [(set_attr "length" "4")])
2155 ;; ----------------------------------------------------------------------
2156 ;; ABSOLUTE VALUE INSTRUCTIONS
2157 ;; ----------------------------------------------------------------------
2159 (define_expand "abssf2"
2160   [(set (match_operand:SF 0 "register_operand" "")
2161         (abs:SF (match_operand:SF 1 "register_operand" "")))]
2162   ""
2163   "")
2165 (define_insn "*abssf2_h8300"
2166   [(set (match_operand:SF 0 "register_operand" "=r")
2167         (abs:SF (match_operand:SF 1 "register_operand" "0")))]
2168   "TARGET_H8300"
2169   "and.b\\t#127,%z0"
2170   [(set_attr "length" "2")])
2172 (define_insn "*abssf2_h8300hs"
2173   [(set (match_operand:SF 0 "register_operand" "=r")
2174         (abs:SF (match_operand:SF 1 "register_operand" "0")))]
2175   "TARGET_H8300H || TARGET_H8300S"
2176   "and.w\\t#32767,%e0"
2177   [(set_attr "length" "4")])
2179 ;; ----------------------------------------------------------------------
2180 ;; NOT INSTRUCTIONS
2181 ;; ----------------------------------------------------------------------
2183 (define_expand "one_cmplqi2"
2184   [(set (match_operand:QI 0 "register_operand" "")
2185         (not:QI (match_operand:QI 1 "register_operand" "")))]
2186   ""
2187   "")
2189 (define_insn "*one_cmplqi2"
2190   [(set (match_operand:QI 0 "h8300_dst_operand" "=rQ")
2191         (not:QI (match_operand:QI 1 "h8300_dst_operand" "0")))]
2192   ""
2193   "not  %X0"
2194   [(set_attr "length_table" "unary")
2195    (set_attr "cc" "set_znv")])
2197 (define_expand "one_cmplhi2"
2198   [(set (match_operand:HI 0 "register_operand" "")
2199         (not:HI (match_operand:HI 1 "register_operand" "")))]
2200   ""
2201   "")
2203 (define_insn "*one_cmplhi2_h8300"
2204   [(set (match_operand:HI 0 "register_operand" "=r")
2205         (not:HI (match_operand:HI 1 "register_operand" "0")))]
2206   "TARGET_H8300"
2207   "not  %s0\;not        %t0"
2208   [(set_attr "length" "4")])
2210 (define_insn "*one_cmplhi2_h8300hs"
2211   [(set (match_operand:HI 0 "h8300_dst_operand" "=rQ")
2212         (not:HI (match_operand:HI 1 "h8300_dst_operand" "0")))]
2213   "(TARGET_H8300H || TARGET_H8300S) && h8300_operands_match_p (operands)"
2214   "not.w        %T0"
2215   [(set_attr "cc" "set_znv")
2216    (set_attr "length_table" "unary")])
2218 (define_expand "one_cmplsi2"
2219   [(set (match_operand:SI 0 "register_operand" "")
2220         (not:SI (match_operand:SI 1 "register_operand" "")))]
2221   ""
2222   "")
2224 (define_insn "*one_cmplsi2_h8300"
2225   [(set (match_operand:SI 0 "register_operand" "=r")
2226         (not:SI (match_operand:SI 1 "register_operand" "0")))]
2227   "TARGET_H8300"
2228   "not  %w0\;not        %x0\;not        %y0\;not        %z0"
2229   [(set_attr "length" "8")])
2231 (define_insn "*one_cmplsi2_h8300hs"
2232   [(set (match_operand:SI 0 "h8300_dst_operand" "=rQ")
2233         (not:SI (match_operand:SI 1 "h8300_dst_operand" "0")))]
2234   "(TARGET_H8300H || TARGET_H8300S) && h8300_operands_match_p (operands)"
2235   "not.l        %S0"
2236   [(set_attr "cc" "set_znv")
2237    (set_attr "length_table" "unary")])
2239 ;; ----------------------------------------------------------------------
2240 ;; JUMP INSTRUCTIONS
2241 ;; ----------------------------------------------------------------------
2243 ;; Conditional jump instructions
2245 (define_expand "cbranchqi4"
2246   [(use (match_operator 0 "ordered_comparison_operator"
2247          [(match_operand:QI 1 "h8300_dst_operand" "")
2248           (match_operand:QI 2 "h8300_src_operand" "")]))
2249    (use (match_operand 3 ""))]
2250   ""
2251   {
2252     h8300_expand_branch (operands);
2253     DONE;
2254   })
2256 (define_expand "cbranchhi4"
2257   [(use (match_operator 0 "ordered_comparison_operator"
2258          [(match_operand:HI 1 "h8300_dst_operand" "")
2259           (match_operand:HI 2 "h8300_src_operand" "")]))
2260    (use (match_operand 3 ""))]
2261   ""
2262   {
2263     /* Force operand1 into a register if we're compiling
2264        for the H8/300.  */
2265     if ((GET_CODE (operands[2]) != REG && operands[2] != const0_rtx)
2266         && TARGET_H8300)
2267       operands[2] = force_reg (HImode, operands[2]);
2268     h8300_expand_branch (operands); 
2269     DONE;
2270   })
2272 (define_expand "cbranchsi4"
2273   [(use (match_operator 0 "ordered_comparison_operator"
2274          [(match_operand:SI 1 "h8300_dst_operand" "")
2275           (match_operand:SI 2 "h8300_src_operand" "")]))
2276    (use (match_operand 3 ""))]
2277   "TARGET_H8300H || TARGET_H8300S"
2278   {
2279     h8300_expand_branch (operands);
2280     DONE;
2281   })
2283 (define_insn "branch_true"
2284   [(set (pc)
2285         (if_then_else (match_operator 1 "comparison_operator"
2286                        [(cc0) (const_int 0)])
2287                       (label_ref (match_operand 0 "" ""))
2288                       (pc)))]
2289   ""
2291   if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0
2292       && (GET_CODE (operands[1]) == GT
2293           || GET_CODE (operands[1]) == GE
2294           || GET_CODE (operands[1]) == LE
2295           || GET_CODE (operands[1]) == LT))
2296     {
2297       cc_status.flags &= ~CC_OVERFLOW_UNUSABLE;
2298       return 0;
2299     }
2301   if (get_attr_length (insn) == 2)
2302     return "b%j1        %l0";
2303   else if (get_attr_length (insn) == 4)
2304     return "b%j1        %l0:16";
2305   else
2306     return "b%k1        .Lh8BR%=\;jmp   @%l0\\n.Lh8BR%=:";
2308  [(set_attr "type" "branch")
2309    (set_attr "cc" "none")])
2311 (define_insn "branch_false"
2312   [(set (pc)
2313         (if_then_else (match_operator 1 "comparison_operator"
2314                        [(cc0) (const_int 0)])
2315                       (pc)
2316                       (label_ref (match_operand 0 "" ""))))]
2317   ""
2319   if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0
2320       && (GET_CODE (operands[1]) == GT
2321           || GET_CODE (operands[1]) == GE
2322           || GET_CODE (operands[1]) == LE
2323           || GET_CODE (operands[1]) == LT))
2324     {
2325       cc_status.flags &= ~CC_OVERFLOW_UNUSABLE;
2326       return 0;
2327     }
2329   if (get_attr_length (insn) == 2)
2330     return "b%k1        %l0";
2331   else if (get_attr_length (insn) == 4)
2332     return "b%k1        %l0:16";
2333   else
2334     return "b%j1        .Lh8BR%=\;jmp   @%l0\\n.Lh8BR%=:";
2336   [(set_attr "type" "branch")
2337    (set_attr "cc" "none")])
2339 (define_insn "*brabc"
2340   [(set (pc)
2341         (if_then_else (eq (zero_extract (match_operand:QI 1 "bit_memory_operand" "WU")
2342                                         (const_int 1)
2343                                         (match_operand:QI 2 "immediate_operand" "n"))
2344                           (const_int 0))
2345                       (label_ref (match_operand 0 "" ""))
2346                       (pc)))]
2347   "TARGET_H8300SX"
2349   switch (get_attr_length (insn)
2350           - h8300_insn_length_from_table (insn, operands))
2351     {
2352     case 2:
2353       return "bra/bc    %2,%R1,%l0";
2354     case 4:
2355       return "bra/bc    %2,%R1,%l0:16";
2356     default:
2357       return "bra/bs    %2,%R1,.Lh8BR%=\;jmp    @%l0\\n.Lh8BR%=:";
2358     }
2360   [(set_attr "type" "bitbranch")
2361    (set_attr "length_table" "bitbranch")
2362    (set_attr "cc" "none")])
2364 (define_insn "*brabs"
2365   [(set (pc)
2366         (if_then_else (ne (zero_extract (match_operand:QI 1 "bit_memory_operand" "WU")
2367                                         (const_int 1)
2368                                         (match_operand:QI 2 "immediate_operand" "n"))
2369                           (const_int 0))
2370                       (label_ref (match_operand 0 "" ""))
2371                       (pc)))]
2372   "TARGET_H8300SX"
2374   switch (get_attr_length (insn)
2375           - h8300_insn_length_from_table (insn, operands))
2376     {
2377     case 2:
2378       return "bra/bs    %2,%R1,%l0";
2379     case 4:
2380       return "bra/bs    %2,%R1,%l0:16";
2381     default:
2382       return "bra/bc    %2,%R1,.Lh8BR%=\;jmp    @%l0\\n.Lh8BR%=:";
2383     }
2385   [(set_attr "type" "bitbranch")
2386    (set_attr "length_table" "bitbranch")
2387    (set_attr "cc" "none")])
2389 ;; Unconditional and other jump instructions.
2391 (define_insn "jump"
2392   [(set (pc)
2393         (label_ref (match_operand 0 "" "")))]
2394   ""
2396   if (final_sequence != 0)
2397     {
2398       if (get_attr_length (insn) == 2)
2399         return "bra/s   %l0";
2400       else
2401         {
2402           /* The branch isn't short enough to use bra/s.  Output the
2403              branch and delay slot in their normal order.
2405              If this is a backward branch, it will now be branching two
2406              bytes further than previously thought.  The length-based
2407              test for bra vs. jump is very conservative though, so the
2408              branch will still be within range.  */
2409           rtvec vec;
2410           int seen;
2412           vec = XVEC (final_sequence, 0);
2413           final_sequence = 0;
2414           final_scan_insn (RTVEC_ELT (vec, 1), asm_out_file, optimize, 1, & seen);
2415           final_scan_insn (RTVEC_ELT (vec, 0), asm_out_file, optimize, 1, & seen);
2416           INSN_DELETED_P (RTVEC_ELT (vec, 1)) = 1;
2417           return "";
2418         }
2419     }
2420   else if (get_attr_length (insn) == 2)
2421     return "bra %l0";
2422   else if (get_attr_length (insn) == 4)
2423     return "bra %l0:16";
2424   else
2425     return "jmp @%l0";
2427   [(set_attr "type" "branch")
2428    (set (attr "delay_slot")
2429         (if_then_else (match_test "TARGET_H8300SX")
2430                       (const_string "jump")
2431                       (const_string "none")))
2432    (set_attr "cc" "none")])
2434 ;; This is a define expand, because pointers may be either 16 or 32 bits.
2436 (define_expand "tablejump"
2437   [(parallel [(set (pc) (match_operand 0 "register_operand" ""))
2438               (use (label_ref (match_operand 1 "" "")))])]
2439   ""
2440   "")
2442 (define_insn "*tablejump_h8300"
2443   [(set (pc) (match_operand:HI 0 "register_operand" "r"))
2444    (use (label_ref (match_operand 1 "" "")))]
2445   "TARGET_H8300"
2446   "jmp  @%0"
2447   [(set_attr "cc" "none")
2448    (set_attr "length" "2")])
2450 (define_insn "*tablejump_h8300hs_advanced"
2451   [(set (pc) (match_operand:SI 0 "register_operand" "r"))
2452    (use (label_ref (match_operand 1 "" "")))]
2453   "(TARGET_H8300H || TARGET_H8300S) && !TARGET_NORMAL_MODE"
2454   "jmp  @%0"
2455   [(set_attr "cc" "none")
2456    (set_attr "length" "2")])
2458 (define_insn "*tablejump_h8300hs_normal"
2459   [(set (pc) (match_operand:HI 0 "register_operand" "r"))
2460    (use (label_ref (match_operand 1 "" "")))]
2461   "(TARGET_H8300H || TARGET_H8300S) && TARGET_NORMAL_MODE"
2462   "jmp @%S0"
2463   [(set_attr "cc" "none")
2464    (set_attr "length" "2")])
2466 ;; This is a define expand, because pointers may be either 16 or 32 bits.
2468 (define_expand "indirect_jump"
2469   [(set (pc) (match_operand 0 "jump_address_operand" ""))]
2470   ""
2471   "")
2473 (define_insn "*indirect_jump_h8300"
2474   [(set (pc) (match_operand:HI 0 "jump_address_operand" "Vr"))]
2475   "TARGET_H8300"
2476   "jmp  @%0"
2477   [(set_attr "cc" "none")
2478    (set_attr "length" "2")])
2480 (define_insn "*indirect_jump_h8300hs_advanced"
2481   [(set (pc) (match_operand:SI 0 "jump_address_operand" "Vr"))]
2482   "(TARGET_H8300H || TARGET_H8300S) && !TARGET_NORMAL_MODE"
2483   "jmp @%0"
2484   [(set_attr "cc" "none")
2485    (set_attr "length" "2")])
2487 (define_insn "*indirect_jump_h8300hs_normal"
2488   [(set (pc) (match_operand:HI 0 "jump_address_operand" "Vr"))]
2489   "(TARGET_H8300H || TARGET_H8300S) && TARGET_NORMAL_MODE"
2490   "jmp @%S0"
2491   [(set_attr "cc" "none")
2492    (set_attr "length" "2")])
2494 ;; Call subroutine with no return value.
2496 ;; ??? Even though we use HImode here, this works on the H8/300H and H8S.
2498 (define_insn "call"
2499   [(call (match_operand:QI 0 "call_insn_operand" "or")
2500          (match_operand:HI 1 "general_operand" "g"))]
2501   ""
2503   if (GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
2504       && SYMBOL_REF_FLAG (XEXP (operands[0], 0)))
2505     return "jsr\\t@%0:8";
2506   else
2507     return "jsr\\t%0";
2509   [(set_attr "type" "call")
2510    (set (attr "length")
2511         (if_then_else (match_operand:QI 0 "small_call_insn_operand" "")
2512                       (const_int 2)
2513                       (const_int 4)))])
2515 ;; Call subroutine, returning value in operand 0
2516 ;; (which must be a hard register).
2518 ;; ??? Even though we use HImode here, this works on the H8/300H and H8S.
2520 (define_insn "call_value"
2521   [(set (match_operand 0 "" "=r")
2522         (call (match_operand:QI 1 "call_insn_operand" "or")
2523               (match_operand:HI 2 "general_operand" "g")))]
2524   ""
2526   if (GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2527       && SYMBOL_REF_FLAG (XEXP (operands[1], 0)))
2528     return "jsr\\t@%1:8";
2529   else
2530     return "jsr\\t%1";
2532   [(set_attr "type" "call")
2533    (set (attr "length")
2534         (if_then_else (match_operand:QI 0 "small_call_insn_operand" "")
2535                       (const_int 2)
2536                       (const_int 4)))])
2538 (define_insn "nop"
2539   [(const_int 0)]
2540   ""
2541   "nop"
2542   [(set_attr "cc" "none")
2543    (set_attr "length" "2")])
2545 ;; ----------------------------------------------------------------------
2546 ;; PROLOGUE/EPILOGUE-RELATED INSTRUCTIONS
2547 ;; ----------------------------------------------------------------------
2549 (define_expand "push_h8300"
2550   [(set (mem:HI (pre_dec:HI (reg:HI SP_REG)))
2551         (match_operand:HI 0 "register_operand" ""))]
2552   "TARGET_H8300"
2553   "")
2555 (define_expand "push_h8300hs_advanced"
2556   [(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
2557         (match_operand:SI 0 "register_operand" ""))]
2558   "TARGET_H8300H && TARGET_H8300S && !TARGET_NORMAL_MODE"
2559   "")
2561 (define_expand "push_h8300hs_normal"
2562   [(set (mem:SI (pre_dec:HI (reg:HI SP_REG)))
2563         (match_operand:SI 0 "register_operand" ""))]
2564   "TARGET_H8300H && TARGET_H8300S && TARGET_NORMAL_MODE"
2565   "")
2567 (define_expand "pop_h8300"
2568   [(set (match_operand:HI 0 "register_operand" "")
2569         (mem:HI (post_inc:HI (reg:HI SP_REG))))]
2570   "TARGET_H8300"
2571   "")
2573 (define_expand "pop_h8300hs_advanced"
2574   [(set (match_operand:SI 0 "register_operand" "")
2575         (mem:SI (post_inc:SI (reg:SI SP_REG))))]
2576   "TARGET_H8300H && TARGET_H8300S && !TARGET_NORMAL_MODE"
2577   "")
2579 (define_expand "pop_h8300hs_normal"
2580   [(set (match_operand:SI 0 "register_operand" "")
2581         (mem:SI (post_inc:HI (reg:HI SP_REG))))]
2582   "TARGET_H8300H && TARGET_H8300S && TARGET_NORMAL_MODE"
2583   "")
2585 (define_insn "ldm_h8300sx"
2586   [(match_parallel           0 "h8300_ldm_parallel"
2587     [(set (match_operand:SI 1 "register_operand" "")
2588           (match_operand:SI 2 "memory_operand" ""))])]
2589   "TARGET_H8300S"
2591   operands[3] = SET_DEST (XVECEXP (operands[0], 0,
2592                                    XVECLEN (operands[0], 0) - 2));
2593   return "ldm.l\t@er7+,%S1-%S3";
2595   [(set_attr "cc" "none")
2596    (set_attr "length" "4")])
2598 (define_insn "stm_h8300sx"
2599   [(match_parallel           0 "h8300_stm_parallel"
2600     [(set (match_operand:SI 1 "memory_operand" "")
2601           (match_operand:SI 2 "register_operand" ""))])]
2602   "TARGET_H8300S"
2604   operands[3] = SET_SRC (XVECEXP (operands[0], 0,
2605                                   XVECLEN (operands[0], 0) - 2));
2606   return "stm.l\t%S2-%S3,@-er7";
2608   [(set_attr "cc" "none")
2609    (set_attr "length" "4")])
2611 (define_insn "return_h8sx"
2612   [(match_parallel           0 "h8300_return_parallel"
2613     [(return)
2614      (set (match_operand:SI 1 "register_operand" "")
2615           (match_operand:SI 2 "memory_operand" ""))])]
2616   "TARGET_H8300SX"
2618   operands[3] = SET_DEST (XVECEXP (operands[0], 0,
2619                                    XVECLEN (operands[0], 0) - 2));
2620   if (h8300_current_function_interrupt_function_p ()
2621       || h8300_current_function_monitor_function_p ())
2622     return "rte/l\t%S1-%S3";
2623   else
2624     return "rts/l\t%S1-%S3";
2626   [(set_attr "cc" "none")
2627    (set_attr "can_delay" "no")
2628    (set_attr "length" "2")])
2630 (define_expand "return"
2631   [(return)]
2632   "h8300_can_use_return_insn_p ()"
2633   "")
2635 (define_insn "*return_1"
2636   [(return)]
2637   "reload_completed"
2639   if (h8300_current_function_interrupt_function_p ()
2640       || h8300_current_function_monitor_function_p ())
2641     return "rte";
2642   else
2643     return "rts";
2645   [(set_attr "cc" "none")
2646    (set_attr "can_delay" "no")
2647    (set_attr "length" "2")])
2649 (define_expand "prologue"
2650   [(const_int 0)]
2651   ""
2652   {
2653     h8300_expand_prologue (); 
2654     DONE;
2655   })
2657 (define_expand "epilogue"
2658   [(return)]
2659   ""
2660   {
2661     h8300_expand_epilogue (); 
2662     DONE;
2663   })
2665 (define_insn "monitor_prologue"
2666   [(unspec_volatile [(const_int 0)] UNSPEC_MONITOR)]
2667   ""
2669   if (TARGET_H8300)
2670     return "subs\\t#2,r7\;mov.w\\tr0,@-r7\;stc\\tccr,r0l\;mov.b\tr0l,@(2,r7)\;mov.w\\t@r7+,r0\;orc\t#128,ccr";
2671   else if (TARGET_H8300H && TARGET_NORMAL_MODE)
2672     return "subs\\t#2,er7\;mov.l\\ter0,@-er7\;stc\\tccr,r0l\;mov.b\\tr0l,@(4,er7)\;mov.l\\t@er7+,er0\;orc\\t#128,ccr";
2673   else if (TARGET_H8300H)
2674     return "mov.l\\ter0,@-er7\;stc\\tccr,r0l\;mov.b\\tr0l,@(4,er7)\;mov.l\\t@er7+,er0\;orc\\t#128,ccr";
2675   else if (TARGET_H8300S && TARGET_NEXR )
2676     return "mov.l\\ter0,@-er7\;stc\tccr,r0l\;mov.b\tr0l,@(4,er7)\;mov.l\\t@er7+,er0\;orc\t#128,ccr"; 
2677   else if (TARGET_H8300S && TARGET_NEXR && TARGET_NORMAL_MODE)
2678     return "subs\\t#2,er7\;mov.l\\ter0,@-er7\;stc\tccr,r0l\;mov.b\tr0l,@(4,er7)\;mov.l\\t@er7+,er0\;orc\t#128,ccr";
2679   else if (TARGET_H8300S && TARGET_NORMAL_MODE)
2680     return "subs\\t#2,er7\;stc\texr,@-er7\;mov.l\\ter0,@-er7\;stc\tccr,r0l\;mov.b\tr0l,@(6,er7)\;mov.l\\t@er7+,er0\;orc\t#128,ccr";
2681   else if (TARGET_H8300S)
2682     return "stc\texr,@-er7\;mov.l\\ter0,@-er7\;stc\tccr,r0l\;mov.b\tr0l,@(6,er7)\;mov.l\\t@er7+,er0\;orc\t#128,ccr";
2683   gcc_unreachable ();
2685   [(set_attr "length" "20")])
2687 ;; ----------------------------------------------------------------------
2688 ;; EXTEND INSTRUCTIONS
2689 ;; ----------------------------------------------------------------------
2691 (define_expand "zero_extendqihi2"
2692   [(set (match_operand:HI 0 "register_operand" "")
2693         (zero_extend:HI (match_operand:QI 1 "general_operand_src" "")))]
2694   ""
2695   "")
2697 (define_insn "*zero_extendqihi2_h8300"
2698   [(set (match_operand:HI 0 "register_operand" "=r,r")
2699         (zero_extend:HI (match_operand:QI 1 "general_operand_src" "0,g>")))]
2700   "TARGET_H8300"
2701   "@
2702   mov.b #0,%t0
2703   #"
2704   [(set_attr "length" "2,10")])
2706 (define_insn "*zero_extendqihi2_h8300hs"
2707   [(set (match_operand:HI 0 "register_operand" "=r,r")
2708         (zero_extend:HI (match_operand:QI 1 "general_operand_src" "0,g>")))]
2709   "TARGET_H8300H || TARGET_H8300S"
2710   "@
2711   extu.w        %T0
2712   #"
2713   [(set_attr "length" "2,10")
2714    (set_attr "cc" "set_znv,set_znv")])
2716 ;; Split the zero extension of a general operand (actually a memory
2717 ;; operand) into a load of the operand and the actual zero extension
2718 ;; so that 1) the length will be accurate, and 2) the zero extensions
2719 ;; appearing at the end of basic blocks may be merged.
2721 (define_split
2722   [(set (match_operand:HI 0 "register_operand" "")
2723         (zero_extend:HI (match_operand:QI 1 "general_operand_src" "")))]
2724   "reload_completed"
2725   [(set (match_dup 2)
2726         (match_dup 1))
2727    (set (match_dup 0)
2728         (zero_extend:HI (match_dup 2)))]
2729   {
2730     operands[2] = gen_rtx_REG (QImode, REGNO (operands[0]));
2731   })
2733 (define_expand "zero_extendqisi2"
2734   [(set (match_operand:SI 0 "register_operand" "")
2735         (zero_extend:SI (match_operand:QI 1 "general_operand_src" "")))]
2736   ""
2737   {
2738     if (TARGET_H8300SX)
2739       operands[1] = force_reg (QImode, operands[1]);
2740   })
2742 (define_insn "*zero_extendqisi2_h8300"
2743   [(set (match_operand:SI 0 "register_operand" "=r,r")
2744         (zero_extend:SI (match_operand:QI 1 "general_operand_src" "0,g>")))]
2745   "TARGET_H8300"
2746   "@
2747   mov.b #0,%x0\;sub.w   %e0,%e0
2748   mov.b %R1,%w0\;mov.b  #0,%x0\;sub.w   %e0,%e0"
2749   [(set_attr "length" "4,8")])
2751 (define_insn "*zero_extendqisi2_h8300hs"
2752   [(set (match_operand:SI 0 "register_operand" "=r,r")
2753         (zero_extend:SI (match_operand:QI 1 "general_operand_src" "0,g>")))]
2754   "(TARGET_H8300H || TARGET_H8300S) && !TARGET_H8300SX"
2755   "#")
2757 (define_split
2758   [(set (match_operand:SI 0 "register_operand" "")
2759         (zero_extend:SI (match_operand:QI 1 "general_operand_src" "")))]
2760   "(TARGET_H8300H || TARGET_H8300S) && !TARGET_H8300SX
2761     && reg_overlap_mentioned_p (operands[0], operands[1])
2762     && reload_completed"
2763   [(set (match_dup 2)
2764         (match_dup 1))
2765    (set (match_dup 3)
2766         (zero_extend:HI (match_dup 2)))
2767    (set (match_dup 0)
2768         (zero_extend:SI (match_dup 3)))]
2769   {
2770     operands[2] = gen_lowpart (QImode, operands[0]);
2771     operands[3] = gen_lowpart (HImode, operands[0]);
2772   })
2774 (define_split
2775   [(set (match_operand:SI 0 "register_operand" "")
2776         (zero_extend:SI (match_operand:QI 1 "general_operand_src" "")))]
2777   "(TARGET_H8300H || TARGET_H8300S) && !TARGET_H8300SX
2778     && !reg_overlap_mentioned_p (operands[0], operands[1])
2779     && reload_completed"
2780   [(set (match_dup 0)
2781         (const_int 0))
2782    (set (strict_low_part (match_dup 2))
2783         (match_dup 1))]
2784   {
2785     operands[2] = gen_rtx_REG (QImode, REGNO (operands[0]));
2786   })
2788 (define_insn "*zero_extendqisi2_h8sx"
2789   [(set (match_operand:SI 0 "register_operand" "=r")
2790         (zero_extend:SI (match_operand:QI 1 "register_operand" "0")))]
2791   "TARGET_H8300SX"
2792   "extu.l\t#2,%0"
2793   [(set_attr "length" "2")
2794    (set_attr "cc" "set_znv")])
2796 (define_expand "zero_extendhisi2"
2797   [(set (match_operand:SI 0 "register_operand" "")
2798         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
2799   ""
2800   "")
2802 ;; %e prints the high part of a CONST_INT, not the low part.  Arggh.
2803 (define_insn "*zero_extendhisi2_h8300"
2804   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
2805         (zero_extend:SI (match_operand:HI 1 "general_operand_src" "0,i,g>")))]
2806   "TARGET_H8300"
2807   "@
2808   sub.w %e0,%e0
2809   mov.w %f1,%f0\;sub.w  %e0,%e0
2810   mov.w %e1,%f0\;sub.w  %e0,%e0"
2811   [(set_attr "length" "2,4,6")])
2813 (define_insn "*zero_extendhisi2_h8300hs"
2814   [(set (match_operand:SI 0 "register_operand" "=r")
2815         (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))]
2816   "TARGET_H8300H || TARGET_H8300S"
2817   "extu.l       %S0"
2818   [(set_attr "length" "2")
2819    (set_attr "cc" "set_znv")])
2821 (define_expand "extendqihi2"
2822   [(set (match_operand:HI 0 "register_operand" "")
2823         (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
2824   ""
2825   "")
2827 (define_insn "*extendqihi2_h8300"
2828   [(set (match_operand:HI 0 "register_operand" "=r,r")
2829         (sign_extend:HI (match_operand:QI 1 "general_operand_src" "0,g>")))]
2830   "TARGET_H8300"
2831   "@
2832   bld   #7,%s0\;subx    %t0,%t0
2833   mov.b %R1,%s0\;bld    #7,%s0\;subx    %t0,%t0"
2834   [(set_attr "length" "4,8")])
2836 (define_insn "*extendqihi2_h8300hs"
2837   [(set (match_operand:HI 0 "register_operand" "=r")
2838         (sign_extend:HI (match_operand:QI 1 "register_operand" "0")))]
2839   "TARGET_H8300H || TARGET_H8300S"
2840   "exts.w       %T0"
2841   [(set_attr "length" "2")
2842    (set_attr "cc" "set_znv")])
2844 (define_expand "extendqisi2"
2845   [(set (match_operand:SI 0 "register_operand" "")
2846         (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
2847   ""
2848   "")
2850 (define_insn "*extendqisi2_h8300"
2851   [(set (match_operand:SI 0 "register_operand" "=r,r")
2852         (sign_extend:SI (match_operand:QI 1 "general_operand_src" "0,g>")))]
2853   "TARGET_H8300"
2854   "@
2855   bld   #7,%w0\;subx    %x0,%x0\;subx   %y0,%y0\;subx   %z0,%z0
2856   mov.b %R1,%w0\;bld    #7,%w0\;subx    %x0,%x0\;subx   %y0,%y0\;subx   %z0,%z0"
2857   [(set_attr "length" "8,12")])
2859 ;; The following pattern is needed because without the pattern, the
2860 ;; combiner would split (sign_extend:SI (reg:QI)) into two 24-bit
2861 ;; shifts, one ashift and one ashiftrt.
2863 (define_insn_and_split "*extendqisi2_h8300hs"
2864   [(set (match_operand:SI 0 "register_operand" "=r")
2865         (sign_extend:SI (match_operand:QI 1 "register_operand" "0")))]
2866   "(TARGET_H8300H || TARGET_H8300S) && !TARGET_H8300SX"
2867   "#"
2868   "&& reload_completed"
2869   [(set (match_dup 2)
2870         (sign_extend:HI (match_dup 1)))
2871    (set (match_dup 0)
2872         (sign_extend:SI (match_dup 2)))]
2873   {
2874     operands[2] = gen_rtx_REG (HImode, REGNO (operands[0]));
2875   })
2877 (define_insn "*extendqisi2_h8sx"
2878   [(set (match_operand:SI 0 "register_operand" "=r")
2879         (sign_extend:SI (match_operand:QI 1 "register_operand" "0")))]
2880   "TARGET_H8300SX"
2881   "exts.l\t#2,%0"
2882   [(set_attr "length" "2")
2883    (set_attr "cc" "set_znv")])
2885 (define_expand "extendhisi2"
2886   [(set (match_operand:SI 0 "register_operand" "")
2887         (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
2888   ""
2889   "")
2891 (define_insn "*extendhisi2_h8300"
2892   [(set (match_operand:SI 0 "register_operand" "=r,r")
2893         (sign_extend:SI (match_operand:HI 1 "general_operand_src" "0,g>")))]
2894   "TARGET_H8300"
2895   "@
2896   bld   #7,%x0\;subx    %y0,%y0\;subx   %z0,%z0
2897   mov.w %T1,%f0\;bld    #7,%x0\;subx    %y0,%y0\;subx   %z0,%z0"
2898   [(set_attr "length" "6,10")])
2900 (define_insn "*extendhisi2_h8300hs"
2901   [(set (match_operand:SI 0 "register_operand" "=r")
2902         (sign_extend:SI (match_operand:HI 1 "register_operand" "0")))]
2903   "TARGET_H8300H || TARGET_H8300S"
2904   "exts.l       %S0"
2905   [(set_attr "length" "2")
2906    (set_attr "cc" "set_znv")])
2908 ;; ----------------------------------------------------------------------
2909 ;; SHIFTS
2910 ;; ----------------------------------------------------------------------
2912 ;; We make some attempt to provide real efficient shifting.  One example is
2913 ;; doing an 8-bit shift of a 16-bit value by moving a byte reg into the other
2914 ;; reg and moving 0 into the former reg.
2916 ;; We also try to achieve this in a uniform way.  IE: We don't try to achieve
2917 ;; this in both rtl and at insn emit time.  Ideally, we'd use rtl as that would
2918 ;; give the optimizer more cracks at the code.  However, we wish to do things
2919 ;; like optimizing shifting the sign bit to bit 0 by rotating the other way.
2920 ;; There is rtl to handle this (rotate + and), but the H8/300 doesn't handle
2921 ;; 16-bit rotates.  Also, if we emit complicated rtl, combine may not be able
2922 ;; to detect cases it can optimize.
2924 ;; For these and other fuzzy reasons, I've decided to go the less pretty but
2925 ;; easier "do it at insn emit time" route.
2927 ;; QI BIT SHIFTS
2929 (define_expand "ashlqi3"
2930   [(set (match_operand:QI 0 "register_operand" "")
2931         (ashift:QI (match_operand:QI 1 "register_operand" "")
2932                    (match_operand:QI 2 "nonmemory_operand" "")))]
2933   ""
2934   {
2935     if (expand_a_shift (QImode, ASHIFT, operands)) 
2936     DONE;
2937   })
2939 (define_expand "ashrqi3"
2940   [(set (match_operand:QI 0 "register_operand" "")
2941         (ashiftrt:QI (match_operand:QI 1 "register_operand" "")
2942                      (match_operand:QI 2 "nonmemory_operand" "")))]
2943   ""
2944   {
2945     if (expand_a_shift (QImode, ASHIFTRT, operands)) 
2946     DONE;
2947   })
2949 (define_expand "lshrqi3"
2950   [(set (match_operand:QI 0 "register_operand" "")
2951         (lshiftrt:QI (match_operand:QI 1 "register_operand" "")
2952                      (match_operand:QI 2 "nonmemory_operand" "")))]
2953   ""
2954   {
2955     if (expand_a_shift (QImode, LSHIFTRT, operands)) 
2956     DONE;
2957   })
2959 (define_insn ""
2960   [(set (match_operand:QI 0 "h8300_dst_operand" "=rQ")
2961         (match_operator:QI 3 "h8sx_unary_shift_operator"
2962          [(match_operand:QI 1 "h8300_dst_operand" "0")
2963           (match_operand:QI 2 "const_int_operand" "")]))]
2964   "h8300_operands_match_p (operands)"
2966   return output_h8sx_shift (operands, 'b', 'X'); 
2968   [(set_attr "length_table" "unary")
2969    (set_attr "cc" "set_znv")])
2971 (define_insn ""
2972   [(set (match_operand:QI 0 "register_operand" "=r")
2973         (match_operator:QI 3 "h8sx_binary_shift_operator"
2974          [(match_operand:QI 1 "register_operand" "0")
2975           (match_operand:QI 2 "nonmemory_operand" "r P3>X")]))]
2976   ""
2978   return output_h8sx_shift (operands, 'b', 'X'); 
2980   [(set_attr "length" "4")
2981    (set_attr "cc" "set_znv")])
2983 (define_insn "*shiftqi"
2984   [(set (match_operand:QI 0 "register_operand" "=r,r")
2985         (match_operator:QI 3 "nshift_operator"
2986          [(match_operand:QI 1 "register_operand" "0,0")
2987           (match_operand:QI 2 "nonmemory_operand" "R,rn")]))
2988    (clobber (match_scratch:QI 4 "=X,&r"))]
2989   ""
2991   return output_a_shift (operands);
2993   [(set (attr "length")
2994         (symbol_ref "compute_a_shift_length (insn, operands)"))
2995    (set (attr "cc")
2996         (symbol_ref "compute_a_shift_cc (insn, operands)"))])
2998 ;; HI BIT SHIFTS
3000 (define_expand "ashlhi3"
3001   [(set (match_operand:HI 0 "register_operand" "")
3002         (ashift:HI (match_operand:HI 1 "register_operand" "")
3003                    (match_operand:QI 2 "nonmemory_operand" "")))]
3004   ""
3005   {
3006     if (expand_a_shift (HImode, ASHIFT, operands)) 
3007     DONE;
3008   })
3010 (define_expand "lshrhi3"
3011   [(set (match_operand:HI 0 "register_operand" "")
3012         (lshiftrt:HI (match_operand:HI 1 "register_operand" "")
3013                      (match_operand:QI 2 "nonmemory_operand" "")))]
3014   ""
3015   {
3016     if (expand_a_shift (HImode, LSHIFTRT, operands)) 
3017     DONE;
3018   })
3020 (define_expand "ashrhi3"
3021   [(set (match_operand:HI 0 "register_operand" "")
3022         (ashiftrt:HI (match_operand:HI 1 "register_operand" "")
3023                      (match_operand:QI 2 "nonmemory_operand" "")))]
3024   ""
3025   {
3026     if (expand_a_shift (HImode, ASHIFTRT, operands)) 
3027     DONE;
3028   })
3030 (define_insn ""
3031   [(set (match_operand:HI 0 "h8300_dst_operand" "=rQ")
3032         (match_operator:HI 3 "h8sx_unary_shift_operator"
3033          [(match_operand:HI 1 "h8300_dst_operand" "0")
3034           (match_operand:QI 2 "const_int_operand" "")]))]
3035   "h8300_operands_match_p (operands)"
3037   return output_h8sx_shift (operands, 'w', 'T'); 
3039   [(set_attr "length_table" "unary")
3040    (set_attr "cc" "set_znv")])
3042 (define_insn ""
3043   [(set (match_operand:HI 0 "register_operand" "=r")
3044         (match_operator:HI 3 "h8sx_binary_shift_operator"
3045          [(match_operand:HI 1 "register_operand" "0")
3046           (match_operand:QI 2 "nonmemory_operand" "r P4>X")]))]
3047   ""
3049   return output_h8sx_shift (operands, 'w', 'T'); 
3051   [(set_attr "length" "4")
3052    (set_attr "cc" "set_znv")])
3054 (define_insn "*shifthi"
3055   [(set (match_operand:HI 0 "register_operand" "=r,r")
3056         (match_operator:HI 3 "nshift_operator"
3057          [(match_operand:HI 1 "register_operand" "0,0")
3058           (match_operand:QI 2 "nonmemory_operand" "S,rn")]))
3059    (clobber (match_scratch:QI 4 "=X,&r"))]
3060   ""
3062   return output_a_shift (operands);
3064   [(set (attr "length")
3065         (symbol_ref "compute_a_shift_length (insn, operands)"))
3066    (set (attr "cc")
3067         (symbol_ref "compute_a_shift_cc (insn, operands)"))])
3069 ;;  SI BIT SHIFTS
3071 (define_expand "ashlsi3"
3072   [(set (match_operand:SI 0 "register_operand" "")
3073         (ashift:SI (match_operand:SI 1 "register_operand" "")
3074                    (match_operand:QI 2 "nonmemory_operand" "")))]
3075   ""
3076   {
3077     if (expand_a_shift (SImode, ASHIFT, operands)) 
3078     DONE;
3079   })
3081 (define_expand "lshrsi3"
3082   [(set (match_operand:SI 0 "register_operand" "")
3083         (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
3084                      (match_operand:QI 2 "nonmemory_operand" "")))]
3085   ""
3086   {
3087     if (expand_a_shift (SImode, LSHIFTRT, operands)) 
3088     DONE;
3089   })
3091 (define_expand "ashrsi3"
3092   [(set (match_operand:SI 0 "register_operand" "")
3093         (ashiftrt:SI (match_operand:SI 1 "register_operand" "")
3094                      (match_operand:QI 2 "nonmemory_operand" "")))]
3095   ""
3096   {
3097     if (expand_a_shift (SImode, ASHIFTRT, operands)) 
3098     DONE;
3099   })
3101 (define_insn ""
3102   [(set (match_operand:SI 0 "h8300_dst_operand" "=rQ")
3103         (match_operator:SI 3 "h8sx_unary_shift_operator"
3104          [(match_operand:SI 1 "h8300_dst_operand" "0")
3105           (match_operand:QI 2 "const_int_operand" "")]))]
3106   "h8300_operands_match_p (operands)"
3108   return output_h8sx_shift (operands, 'l', 'S'); 
3110   [(set_attr "length_table" "unary")
3111    (set_attr "cc" "set_znv")])
3113 (define_insn ""
3114   [(set (match_operand:SI 0 "register_operand" "=r")
3115         (match_operator:SI 3 "h8sx_binary_shift_operator"
3116          [(match_operand:SI 1 "register_operand" "0")
3117           (match_operand:QI 2 "nonmemory_operand" "r P5>X")]))]
3118   ""
3120   return output_h8sx_shift (operands, 'l', 'S'); 
3122   [(set_attr "length" "4")
3123    (set_attr "cc" "set_znv")])
3125 (define_insn "*shiftsi"
3126   [(set (match_operand:SI 0 "register_operand" "=r,r")
3127         (match_operator:SI 3 "nshift_operator"
3128          [(match_operand:SI 1 "register_operand" "0,0")
3129           (match_operand:QI 2 "nonmemory_operand" "T,rn")]))
3130    (clobber (match_scratch:QI 4 "=X,&r"))]
3131   ""
3133   return output_a_shift (operands);
3135   [(set (attr "length")
3136         (symbol_ref "compute_a_shift_length (insn, operands)"))
3137    (set (attr "cc")
3138         (symbol_ref "compute_a_shift_cc (insn, operands)"))])
3140 ;; Split a variable shift into a loop.  If the register containing
3141 ;; the shift count dies, then we just use that register.
3143 (define_split
3144   [(set (match_operand 0 "register_operand" "")
3145         (match_operator 2 "nshift_operator"
3146          [(match_dup 0)
3147           (match_operand:QI 1 "register_operand" "")]))
3148    (clobber (match_operand:QI 3 "register_operand" ""))]
3149   "epilogue_completed
3150    && find_regno_note (insn, REG_DEAD, REGNO (operands[1]))"
3151   [(set (cc0) (compare (match_dup 1) (const_int 0)))
3152    (set (pc)
3153         (if_then_else (le (cc0) (const_int 0))
3154                       (label_ref (match_dup 5))
3155                       (pc)))
3156    (match_dup 4)
3157    (parallel
3158      [(set (match_dup 0)
3159            (match_op_dup 2 [(match_dup 0) (const_int 1)]))
3160       (clobber (scratch:QI))])
3161    (set (match_dup 1) (plus:QI (match_dup 1) (const_int -1)))
3162    (set (cc0) (compare (match_dup 1) (const_int 0)))
3163    (set (pc)
3164         (if_then_else (ne (cc0) (const_int 0))
3165                       (label_ref (match_dup 4))
3166                       (pc)))
3167    (match_dup 5)]
3168   {
3169     operands[4] = gen_label_rtx ();
3170     operands[5] = gen_label_rtx ();
3171   })
3173 (define_split
3174   [(set (match_operand 0 "register_operand" "")
3175         (match_operator 2 "nshift_operator"
3176          [(match_dup 0)
3177           (match_operand:QI 1 "register_operand" "")]))
3178    (clobber (match_operand:QI 3 "register_operand" ""))]
3179   "epilogue_completed
3180    && !find_regno_note (insn, REG_DEAD, REGNO (operands[1]))"
3181   [(set (match_dup 3)
3182         (match_dup 1))
3183    (set (cc0) (compare (match_dup 3) (const_int 0)))
3184    (set (pc)
3185         (if_then_else (le (cc0) (const_int 0))
3186                       (label_ref (match_dup 5))
3187                       (pc)))
3188    (match_dup 4)
3189    (parallel
3190      [(set (match_dup 0)
3191            (match_op_dup 2 [(match_dup 0) (const_int 1)]))
3192       (clobber (scratch:QI))])
3193    (set (match_dup 3) (plus:QI (match_dup 3) (const_int -1)))
3194    (set (cc0) (compare (match_dup 3) (const_int 0)))
3195    (set (pc)
3196         (if_then_else (ne (cc0) (const_int 0))
3197                       (label_ref (match_dup 4))
3198                       (pc)))
3199    (match_dup 5)]
3200   {
3201     operands[4] = gen_label_rtx ();
3202     operands[5] = gen_label_rtx ();
3203   })
3205 ;; ----------------------------------------------------------------------
3206 ;; ROTATIONS
3207 ;; ----------------------------------------------------------------------
3209 (define_expand "rotlqi3"
3210   [(set (match_operand:QI 0 "register_operand" "")
3211         (rotate:QI (match_operand:QI 1 "register_operand" "")
3212                    (match_operand:QI 2 "nonmemory_operand" "")))]
3213   ""
3214   {
3215     if (expand_a_rotate (operands)) 
3216     DONE;
3217   })
3219 (define_insn "rotlqi3_1"
3220   [(set (match_operand:QI 0 "register_operand" "=r")
3221         (rotate:QI (match_operand:QI 1 "register_operand" "0")
3222                    (match_operand:QI 2 "immediate_operand" "")))]
3223   ""
3225   return output_a_rotate (ROTATE, operands);
3227   [(set (attr "length")
3228         (symbol_ref "compute_a_rotate_length (operands)"))])
3230 (define_expand "rotlhi3"
3231   [(set (match_operand:HI 0 "register_operand" "")
3232         (rotate:HI (match_operand:HI 1 "register_operand" "")
3233                    (match_operand:QI 2 "nonmemory_operand" "")))]
3234   ""
3235   {
3236     if (expand_a_rotate (operands)) 
3237     DONE;
3238   })
3240 (define_insn "rotlhi3_1"
3241   [(set (match_operand:HI 0 "register_operand" "=r")
3242         (rotate:HI (match_operand:HI 1 "register_operand" "0")
3243                    (match_operand:QI 2 "immediate_operand" "")))]
3244   ""
3246   return output_a_rotate (ROTATE, operands);
3248   [(set (attr "length")
3249         (symbol_ref "compute_a_rotate_length (operands)"))])
3251 (define_expand "rotlsi3"
3252   [(set (match_operand:SI 0 "register_operand" "")
3253         (rotate:SI (match_operand:SI 1 "register_operand" "")
3254                    (match_operand:QI 2 "nonmemory_operand" "")))]
3255   "TARGET_H8300H || TARGET_H8300S"
3256   {
3257     if (expand_a_rotate (operands)) 
3258     DONE;
3259   })
3261 (define_insn "rotlsi3_1"
3262   [(set (match_operand:SI 0 "register_operand" "=r")
3263         (rotate:SI (match_operand:SI 1 "register_operand" "0")
3264                    (match_operand:QI 2 "immediate_operand" "")))]
3265   "TARGET_H8300H || TARGET_H8300S"
3267   return output_a_rotate (ROTATE, operands);
3269   [(set (attr "length")
3270         (symbol_ref "compute_a_rotate_length (operands)"))])
3272 ;; -----------------------------------------------------------------
3273 ;; BIT FIELDS
3274 ;; -----------------------------------------------------------------
3275 ;; The H8/300 has given 1/8th of its opcode space to bitfield
3276 ;; instructions so let's use them as well as we can.
3278 ;; You'll never believe all these patterns perform one basic action --
3279 ;; load a bit from the source, optionally invert the bit, then store it
3280 ;; in the destination (which is known to be zero).
3282 ;; Combine obviously need some work to better identify this situation and
3283 ;; canonicalize the form better.
3286 ;; Normal loads with a 16bit destination.
3289 (define_insn ""
3290   [(set (match_operand:HI 0 "register_operand" "=&r")
3291         (zero_extract:HI (match_operand:HI 1 "register_operand" "r")
3292                          (const_int 1)
3293                          (match_operand:HI 2 "immediate_operand" "n")))]
3294   "TARGET_H8300"
3295   "sub.w        %0,%0\;bld      %Z2,%Y1\;bst    #0,%X0"
3296   [(set_attr "length" "6")])
3299 ;; Inverted loads with a 16bit destination.
3302 (define_insn ""
3303   [(set (match_operand:HI 0 "register_operand" "=&r")
3304         (zero_extract:HI (xor:HI (match_operand:HI 1 "register_operand" "r")
3305                                  (match_operand:HI 3 "const_int_operand" "n"))
3306                          (const_int 1)
3307                          (match_operand:HI 2 "const_int_operand" "n")))]
3308   "(TARGET_H8300 || TARGET_H8300SX)
3309     && (1 << INTVAL (operands[2])) == INTVAL (operands[3])"
3310   "sub.w        %0,%0\;bild     %Z2,%Y1\;bst    #0,%X0"
3311   [(set_attr "length" "8")])
3314 ;; Normal loads with a 32bit destination.
3317 (define_insn "*extzv_1_r_h8300"
3318   [(set (match_operand:SI 0 "register_operand" "=&r")
3319         (zero_extract:SI (match_operand:HI 1 "register_operand" "r")
3320                          (const_int 1)
3321                          (match_operand 2 "const_int_operand" "n")))]
3322   "TARGET_H8300 && INTVAL (operands[2]) < 16"
3324   return output_simode_bld (0, operands);
3326   [(set_attr "length" "8")])
3328 (define_insn "*extzv_1_r_h8300hs"
3329   [(set (match_operand:SI 0 "register_operand" "=r,r")
3330         (zero_extract:SI (match_operand:SI 1 "register_operand" "?0,r")
3331                          (const_int 1)
3332                          (match_operand 2 "const_int_operand" "n,n")))]
3333   "(TARGET_H8300H || TARGET_H8300S) && INTVAL (operands[2]) < 16"
3335   return output_simode_bld (0, operands);
3337   [(set_attr "cc" "set_znv,set_znv")
3338    (set_attr "length" "8,6")])
3341 ;; Inverted loads with a 32bit destination.
3344 (define_insn "*extzv_1_r_inv_h8300"
3345   [(set (match_operand:SI 0 "register_operand" "=&r")
3346         (zero_extract:SI (xor:HI (match_operand:HI 1 "register_operand" "r")
3347                                  (match_operand:HI 3 "const_int_operand" "n"))
3348                          (const_int 1)
3349                          (match_operand 2 "const_int_operand" "n")))]
3350   "TARGET_H8300 && INTVAL (operands[2]) < 16
3351    && (1 << INTVAL (operands[2])) == INTVAL (operands[3])"
3353   return output_simode_bld (1, operands);
3355   [(set_attr "length" "8")])
3357 (define_insn "*extzv_1_r_inv_h8300hs"
3358   [(set (match_operand:SI 0 "register_operand" "=r,r")
3359         (zero_extract:SI (xor:SI (match_operand:SI 1 "register_operand" "?0,r")
3360                                  (match_operand 3 "const_int_operand" "n,n"))
3361                          (const_int 1)
3362                          (match_operand 2 "const_int_operand" "n,n")))]
3363   "(TARGET_H8300H || TARGET_H8300S) && INTVAL (operands[2]) < 16
3364     && (1 << INTVAL (operands[2])) == INTVAL (operands[3])"
3366   return output_simode_bld (1, operands);
3368   [(set_attr "cc" "set_znv,set_znv")
3369    (set_attr "length" "8,6")])
3371 (define_expand "insv"
3372   [(set (zero_extract:HI (match_operand:HI 0 "general_operand" "")
3373                          (match_operand:HI 1 "general_operand" "")
3374                          (match_operand:HI 2 "general_operand" ""))
3375         (match_operand:HI 3 "general_operand" ""))]
3376   "TARGET_H8300 || TARGET_H8300SX"
3377   {
3378     if (TARGET_H8300SX)
3379       {
3380         if (GET_CODE (operands[1]) == CONST_INT
3381             && GET_CODE (operands[2]) == CONST_INT
3382             && INTVAL (operands[1]) <= 8
3383             && INTVAL (operands[2]) >= 0
3384             && INTVAL (operands[1]) + INTVAL (operands[2]) <= 8
3385             && memory_operand (operands[0], GET_MODE (operands[0])))
3386           {
3387             /* If the source operand is zero, it's better to use AND rather
3388                than BFST.  Likewise OR if the operand is all ones.  */
3389             if (GET_CODE (operands[3]) == CONST_INT)
3390               {
3391                 HOST_WIDE_INT mask = (1 << INTVAL (operands[1])) - 1;
3392                 if ((INTVAL (operands[3]) & mask) == 0)
3393                   FAIL;
3394                 if ((INTVAL (operands[3]) & mask) == mask)
3395                   FAIL;
3396               }
3397             if (! bit_memory_operand (operands[0], GET_MODE (operands[0])))
3398               {
3399                 if (!can_create_pseudo_p ())
3400                   FAIL;
3401                 operands[0] =  replace_equiv_address (operands[0], force_reg (Pmode,
3402                                                       XEXP (operands[0], 0)));
3403               }
3404             operands[3] = gen_lowpart (QImode, operands[3]);
3405             if (! operands[3])
3406               FAIL;
3407             if (! register_operand (operands[3], QImode))
3408               {
3409                 if (!can_create_pseudo_p ())
3410                   FAIL;
3411                 operands[3] = force_reg (QImode, operands[3]);
3412               }
3413             emit_insn (gen_bfst (adjust_address (operands[0], QImode, 0),
3414                                                  operands[3], operands[1], operands[2]));
3415             DONE;
3416           }
3417         FAIL;
3418       }
3420     /* We only have single bit bit-field instructions.  */
3421     if (INTVAL (operands[1]) != 1)
3422       FAIL;
3424     /* For now, we don't allow memory operands.  */
3425     if (GET_CODE (operands[0]) == MEM
3426         || GET_CODE (operands[3]) == MEM)
3427       FAIL;
3429     if (GET_CODE (operands[3]) != REG)
3430       operands[3] = force_reg (HImode, operands[3]);
3431   })
3433 (define_insn ""
3434   [(set (zero_extract:HI (match_operand:HI 0 "register_operand" "+r")
3435                          (const_int 1)
3436                          (match_operand:HI 1 "immediate_operand" "n"))
3437         (match_operand:HI 2 "register_operand" "r"))]
3438   ""
3439   "bld  #0,%R2\;bst     %Z1,%Y0 ; i1"
3440   [(set_attr "length" "4")])
3442 (define_expand "extzv"
3443   [(set (match_operand:HI 0 "register_operand" "")
3444         (zero_extract:HI (match_operand:HI 1 "bit_operand" "")
3445                          (match_operand:HI 2 "general_operand" "")
3446                          (match_operand:HI 3 "general_operand" "")))]
3447   "TARGET_H8300 || TARGET_H8300SX"
3448   {
3449     if (TARGET_H8300SX)
3450       {
3451         if (GET_CODE (operands[2]) == CONST_INT
3452             && GET_CODE (operands[3]) == CONST_INT
3453             && INTVAL (operands[2]) <= 8
3454             && INTVAL (operands[3]) >= 0
3455             && INTVAL (operands[2]) + INTVAL (operands[3]) <= 8
3456             && memory_operand (operands[1], QImode))
3457           {
3458             rtx temp;
3460             /* Optimize the case where we're extracting into a paradoxical
3461                subreg.  It's only necessary to extend to the inner reg.  */
3462             if (GET_CODE (operands[0]) == SUBREG
3463                 && subreg_lowpart_p (operands[0])
3464                 && (GET_MODE_SIZE (GET_MODE (SUBREG_REG (operands[0])))
3465                     < GET_MODE_SIZE (GET_MODE (operands[0])))
3466                 && (GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0])))
3467                     == MODE_INT))
3468               operands[0] = SUBREG_REG (operands[0]);
3470             if (!can_create_pseudo_p ())
3471               temp = gen_lowpart (QImode, operands[0]);
3472             else
3473               temp = gen_reg_rtx (QImode);
3474             if (! temp)
3475               FAIL;
3476             if (! bit_memory_operand (operands[1], QImode))
3477               {
3478                 if (!can_create_pseudo_p ())
3479                   FAIL;
3480                 operands[1] = replace_equiv_address (operands[1],
3481                                                      force_reg (Pmode, XEXP (operands[1], 0)));
3482               }
3483             emit_insn (gen_bfld (temp, operands[1], operands[2], operands[3]));
3484             convert_move (operands[0], temp, 1);
3485             DONE;
3486           }
3487         FAIL;
3488       }
3490     /* We only have single bit bit-field instructions.  */
3491     if (INTVAL (operands[2]) != 1)
3492       FAIL;
3494     /* For now, we don't allow memory operands.  */
3495     if (GET_CODE (operands[1]) == MEM)
3496       FAIL;
3497   })
3499 ;; BAND, BOR, and BXOR patterns
3501 (define_insn ""
3502   [(set (match_operand:HI 0 "bit_operand" "=Ur")
3503         (match_operator:HI 4 "bit_operator"
3504          [(zero_extract:HI (match_operand:HI 1 "register_operand" "r")
3505                            (const_int 1)
3506                            (match_operand:HI 2 "immediate_operand" "n"))
3507           (match_operand:HI 3 "bit_operand" "0")]))]
3508   ""
3509   "bld  %Z2,%Y1\;b%c4   #0,%R0\;bst     #0,%R0; bl1"
3510   [(set_attr "length" "6")])
3512 (define_insn ""
3513   [(set (match_operand:HI 0 "bit_operand" "=Ur")
3514         (match_operator:HI 5 "bit_operator"
3515          [(zero_extract:HI (match_operand:HI 1 "register_operand" "r")
3516                            (const_int 1)
3517                            (match_operand:HI 2 "immediate_operand" "n"))
3518           (zero_extract:HI (match_operand:HI 3 "register_operand" "r")
3519                            (const_int 1)
3520                            (match_operand:HI 4 "immediate_operand" "n"))]))]
3521   ""
3522   "bld  %Z2,%Y1\;b%c5   %Z4,%Y3\;bst    #0,%R0; bl3"
3523   [(set_attr "length" "6")])
3525 (define_insn "bfld"
3526   [(set (match_operand:QI 0 "register_operand" "=r")
3527         (zero_extract:QI (match_operand:QI 1 "bit_memory_operand" "WU")
3528                          (match_operand:QI 2 "immediate_operand" "n")
3529                          (match_operand:QI 3 "immediate_operand" "n")))]
3530   "TARGET_H8300SX && INTVAL (operands[2]) + INTVAL (operands[3]) <= 8"
3532   operands[2] = GEN_INT ((1 << (INTVAL (operands[2]) + INTVAL (operands[3])))
3533                          - (1 << INTVAL (operands[3])));
3534   return "bfld  %2,%1,%R0";
3536   [(set_attr "cc" "none_0hit")
3537    (set_attr "length_table" "bitfield")])
3539 (define_insn "bfst"
3540   [(set (zero_extract:QI (match_operand:QI 0 "bit_memory_operand" "+WU")
3541                          (match_operand:QI 2 "immediate_operand" "n")
3542                          (match_operand:QI 3 "immediate_operand" "n"))
3543         (match_operand:QI 1 "register_operand" "r"))]
3544   "TARGET_H8300SX && INTVAL (operands[2]) + INTVAL (operands[3]) <= 8"
3546   operands[2] = GEN_INT ((1 << (INTVAL (operands[2]) + INTVAL (operands[3])))
3547                          - (1 << INTVAL (operands[3])));
3548   return "bfst  %R1,%2,%0";
3550   [(set_attr "cc" "none_0hit")
3551    (set_attr "length_table" "bitfield")])
3553 (define_expand "cstoreqi4"
3554   [(use (match_operator 1 "eqne_operator"
3555          [(match_operand:QI 2 "h8300_dst_operand" "")
3556           (match_operand:QI 3 "h8300_src_operand" "")]))
3557    (clobber (match_operand:HI 0 "register_operand"))]
3558   "TARGET_H8300SX"
3559   {
3560     h8300_expand_store (operands); 
3561     DONE;
3562   })
3564 (define_expand "cstorehi4"
3565   [(use (match_operator 1 "eqne_operator"
3566          [(match_operand:HI 2 "h8300_dst_operand" "")
3567           (match_operand:HI 3 "h8300_src_operand" "")]))
3568    (clobber (match_operand:HI 0 "register_operand"))]
3569   "TARGET_H8300SX"
3570   {
3571     h8300_expand_store (operands); 
3572     DONE;
3573   })
3575 (define_expand "cstoresi4"
3576   [(use (match_operator 1 "eqne_operator"
3577          [(match_operand:SI 2 "h8300_dst_operand" "")
3578           (match_operand:SI 3 "h8300_src_operand" "")]))
3579    (clobber (match_operand:HI 0 "register_operand"))]
3580   "TARGET_H8300SX"
3581   {
3582     h8300_expand_store (operands); 
3583     DONE;
3584   })
3586 (define_insn "*bstzhireg"
3587   [(set (match_operand:HI 0 "register_operand" "=r")
3588         (match_operator:HI 1 "eqne_operator" [(cc0) (const_int 0)]))]
3589   "TARGET_H8300SX"
3590   "mulu.w       #0,%T0\;b%k1    .Lh8BR%=\;inc.w #1,%T0\\n.Lh8BR%=:"
3591   [(set_attr "cc" "clobber")])
3593 (define_insn_and_split "*cmpstz"
3594   [(set (zero_extract:QI (match_operand:QI 0 "bit_memory_operand" "+WU,+WU")
3595                          (const_int 1)
3596                          (match_operand:QI 1 "immediate_operand" "n,n"))
3597         (match_operator:QI 2 "eqne_operator"
3598          [(match_operand 3 "h8300_dst_operand" "r,rQ")
3599           (match_operand 4 "h8300_src_operand" "I,rQi")]))]
3600   "TARGET_H8300SX
3601    && (GET_MODE (operands[3]) == GET_MODE (operands[4])
3602        || GET_CODE (operands[4]) == CONST_INT)
3603    && GET_MODE_CLASS (GET_MODE (operands[3])) == MODE_INT
3604    && GET_MODE_SIZE (GET_MODE (operands[3])) <= 4"
3605   "#"
3606   "reload_completed"
3607   [(set (cc0) (match_dup 5))
3608    (set (zero_extract:QI (match_dup 0) (const_int 1) (match_dup 1))
3609         (match_op_dup:QI 2 [(cc0) (const_int 0)]))]
3610   {
3611     operands[5] = gen_rtx_COMPARE (VOIDmode, operands[3], operands[4]);
3612   }
3613   [(set_attr "cc" "set_znv,compare")])
3614    
3615 (define_insn "*bstz"
3616   [(set (zero_extract:QI (match_operand:QI 0 "bit_memory_operand" "+WU")
3617                          (const_int 1)
3618                          (match_operand:QI 1 "immediate_operand" "n"))
3619         (eq:QI (cc0) (const_int 0)))]
3620   "TARGET_H8300SX && reload_completed"
3621   "bstz %1,%0"
3622   [(set_attr "cc" "none_0hit")
3623    (set_attr "length_table" "unary")])
3625 (define_insn "*bistz"
3626   [(set (zero_extract:QI (match_operand:QI 0 "bit_memory_operand" "+WU")
3627                          (const_int 1)
3628                          (match_operand:QI 1 "immediate_operand" "n"))
3629         (ne:QI (cc0) (const_int 0)))]
3630   "TARGET_H8300SX && reload_completed"
3631   "bistz        %1,%0"
3632   [(set_attr "cc" "none_0hit")
3633    (set_attr "length_table" "unary")])
3635 (define_insn_and_split "*cmpcondbset"
3636   [(set (match_operand:QI 0 "nonimmediate_operand" "=WU,WU")
3637         (if_then_else:QI (match_operator 1 "eqne_operator"
3638                           [(match_operand 2 "h8300_dst_operand" "r,rQ")
3639                            (match_operand 3 "h8300_src_operand" "I,rQi")])
3640                          (ior:QI (match_operand:QI 4 "bit_memory_operand" "0,0")
3641                                  (match_operand:QI 5 "single_one_operand" "n,n"))
3642                          (match_dup 4)))]
3643   "TARGET_H8300SX"
3644   "#"
3645   "reload_completed"
3646   [(set (cc0) (match_dup 6))
3647    (set (match_dup 0)
3648         (if_then_else:QI (match_op_dup 1 [(cc0) (const_int 0)])
3649                          (ior:QI (match_dup 4) (match_dup 5))
3650                          (match_dup 4)))]
3651   {
3652     operands[6] = gen_rtx_COMPARE (VOIDmode, operands[2], operands[3]);
3653   }
3654   [(set_attr "cc" "set_znv,compare")])
3655    
3656 (define_insn "*condbset"
3657   [(set (match_operand:QI 0 "bit_memory_operand" "=WU")
3658         (if_then_else:QI (match_operator:QI 2 "eqne_operator"
3659                           [(cc0) (const_int 0)])
3660                          (ior:QI (match_operand:QI 3 "bit_memory_operand" "0")
3661                                  (match_operand:QI 1 "single_one_operand" "n"))
3662                          (match_dup 3)))]
3663   "TARGET_H8300SX && reload_completed"
3664   "bset/%j2\t%V1,%0"
3665   [(set_attr "cc" "none_0hit")
3666    (set_attr "length_table" "logicb")])
3668 (define_insn_and_split "*cmpcondbclr"
3669   [(set (match_operand:QI 0 "nonimmediate_operand" "=WU,WU")
3670         (if_then_else:QI (match_operator 1 "eqne_operator"
3671                           [(match_operand 2 "h8300_dst_operand" "r,rQ")
3672                            (match_operand 3 "h8300_src_operand" "I,rQi")])
3673                          (and:QI (match_operand:QI 4 "bit_memory_operand" "0,0")
3674                                  (match_operand:QI 5 "single_zero_operand" "n,n"))
3675                          (match_dup 4)))]
3676   "TARGET_H8300SX"
3677   "#"
3678   "reload_completed"
3679   [(set (cc0) (match_dup 6))
3680    (set (match_dup 0)
3681         (if_then_else:QI (match_op_dup 1 [(cc0) (const_int 0)])
3682                          (and:QI (match_dup 4) (match_dup 5))
3683                          (match_dup 4)))]
3684   {
3685     operands[6] = gen_rtx_COMPARE (VOIDmode, operands[2], operands[3]);
3686   }
3687   [(set_attr "cc" "set_znv,compare")])
3688    
3689 (define_insn "*condbclr"
3690   [(set (match_operand:QI 0 "bit_memory_operand" "=WU")
3691         (if_then_else:QI (match_operator:QI 2 "eqne_operator"
3692                           [(cc0) (const_int 0)])
3693                          (and:QI (match_operand:QI 3 "bit_memory_operand" "0")
3694                                  (match_operand:QI 1 "single_zero_operand" "n"))
3695                          (match_dup 3)))]
3696   "TARGET_H8300SX && reload_completed"
3697   "bclr/%j2\t%W1,%0"
3698   [(set_attr "cc" "none_0hit")
3699    (set_attr "length_table" "logicb")])
3701 (define_insn_and_split "*cmpcondbsetreg"
3702   [(set (match_operand:QI 0 "nonimmediate_operand" "=WU,WU")
3703         (if_then_else:QI (match_operator 1 "eqne_operator"
3704                           [(match_operand 2 "h8300_dst_operand" "r,rQ")
3705                            (match_operand 3 "h8300_src_operand" "I,rQi")])
3706                          (ior:QI (match_operand:QI 4 "bit_memory_operand" "0,0")
3707                                  (ashift:QI (const_int 1)
3708                                             (match_operand:QI 5 "register_operand" "r,r")))
3709                          (match_dup 4)))]
3710   "TARGET_H8300SX"
3711   "#"
3712   "reload_completed"
3713   [(set (cc0) (match_dup 6))
3714    (set (match_dup 0)
3715         (if_then_else:QI (match_op_dup 1 [(cc0) (const_int 0)])
3716                          (ior:QI (match_dup 4)
3717                                  (ashift:QI (const_int 1)
3718                                             (match_operand:QI 5 "register_operand" "r,r")))
3719                          (match_dup 4)))]
3720   {
3721     operands[6] = gen_rtx_COMPARE (VOIDmode, operands[2], operands[3]);
3722   }
3723   [(set_attr "cc" "set_znv,compare")])
3724    
3725 (define_insn "*condbsetreg"
3726   [(set (match_operand:QI 0 "bit_memory_operand" "=WU")
3727         (if_then_else:QI (match_operator:QI 2 "eqne_operator"
3728                           [(cc0) (const_int 0)])
3729                          (ior:QI (match_operand:QI 3 "bit_memory_operand" "0")
3730                                  (ashift:QI (const_int 1)
3731                                             (match_operand:QI 1 "register_operand" "r")))
3732                          (match_dup 3)))]
3733   "TARGET_H8300SX && reload_completed"
3734   "bset/%j2\t%R1,%0"
3735   [(set_attr "cc" "none_0hit")
3736    (set_attr "length_table" "logicb")])
3738 (define_insn_and_split "*cmpcondbclrreg"
3739   [(set (match_operand:QI 0 "nonimmediate_operand" "=WU,WU")
3740         (if_then_else:QI (match_operator 1 "eqne_operator"
3741                           [(match_operand 2 "h8300_dst_operand" "r,rQ")
3742                            (match_operand 3 "h8300_src_operand" "I,rQi")])
3743                          (and:QI (match_operand:QI 4 "bit_memory_operand" "0,0")
3744                                  (ashift:QI (const_int 1)
3745                                             (match_operand:QI 5 "register_operand" "r,r")))
3746                          (match_dup 4)))]
3747   "TARGET_H8300SX"
3748   "#"
3749   "reload_completed"
3750   [(set (cc0) (match_dup 6))
3751    (set (match_dup 0)
3752         (if_then_else:QI (match_op_dup 1 [(cc0) (const_int 0)])
3753                          (and:QI (match_dup 4)
3754                                  (ashift:QI (const_int 1)
3755                                             (match_operand:QI 5 "register_operand" "r,r")))
3756                          (match_dup 4)))]
3757   {
3758     operands[6] = gen_rtx_COMPARE (VOIDmode, operands[2], operands[3]);
3759   }
3760   [(set_attr "cc" "set_znv,compare")])
3761    
3762 (define_insn "*condbclrreg"
3763   [(set (match_operand:QI 0 "bit_memory_operand" "=WU")
3764         (if_then_else:QI (match_operator:QI 2 "eqne_operator"
3765                           [(cc0) (const_int 0)])
3766                          (and:QI (match_operand:QI 3 "bit_memory_operand" "0")
3767                                  (ashift:QI (const_int 1)
3768                                             (match_operand:QI 1 "register_operand" "r")))
3769                          (match_dup 3)))]
3770   "TARGET_H8300SX && reload_completed"
3771   "bclr/%j2\t%R1,%0"
3772   [(set_attr "cc" "none_0hit")
3773    (set_attr "length_table" "logicb")])
3776 ;; -----------------------------------------------------------------
3777 ;; COMBINE PATTERNS
3778 ;; -----------------------------------------------------------------
3780 ;; insv:SI
3782 (define_insn "*insv_si_1_n"
3783   [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
3784                          (const_int 1)
3785                          (match_operand:SI 1 "const_int_operand" "n"))
3786         (match_operand:SI 2 "register_operand" "r"))]
3787   "(TARGET_H8300H || TARGET_H8300S) && INTVAL (operands[1]) < 16"
3788   "bld\\t#0,%w2\;bst\\t%Z1,%Y0"
3789   [(set_attr "length" "4")])
3791 (define_insn "*insv_si_1_n_lshiftrt"
3792   [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
3793                          (const_int 1)
3794                          (match_operand:SI 1 "const_int_operand" "n"))
3795         (lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
3796                      (match_operand:SI 3 "const_int_operand" "n")))]
3797   "(TARGET_H8300H || TARGET_H8300S)
3798     && INTVAL (operands[1]) < 16
3799     && INTVAL (operands[3]) < 16"
3800   "bld\\t%Z3,%Y2\;bst\\t%Z1,%Y0"
3801   [(set_attr "length" "4")])
3803 (define_insn "*insv_si_1_n_lshiftrt_16"
3804   [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
3805                          (const_int 1)
3806                          (match_operand:SI 1 "const_int_operand" "n"))
3807         (lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
3808                      (const_int 16)))]
3809   "(TARGET_H8300H || TARGET_H8300S) && INTVAL (operands[1]) < 16"
3810   "rotr.w\\t%e2\;rotl.w\\t%e2\;bst\\t%Z1,%Y0"
3811   [(set_attr "length" "6")])
3813 (define_insn "*insv_si_8_8"
3814   [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
3815                          (const_int 8)
3816                          (const_int 8))
3817         (match_operand:SI 1 "register_operand" "r"))]
3818   "TARGET_H8300H || TARGET_H8300S"
3819   "mov.b\\t%w1,%x0"
3820   [(set_attr "length" "2")])
3822 (define_insn "*insv_si_8_8_lshiftrt_8"
3823   [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
3824                          (const_int 8)
3825                          (const_int 8))
3826         (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
3827                      (const_int 8)))]
3828   "TARGET_H8300H || TARGET_H8300S"
3829   "mov.b\\t%x1,%x0"
3830   [(set_attr "length" "2")])
3832 ;; extzv:SI
3834 (define_insn "*extzv_8_8"
3835   [(set (match_operand:SI 0 "register_operand" "=r,r")
3836         (zero_extract:SI (match_operand:SI 1 "register_operand" "?0,r")
3837                          (const_int 8)
3838                          (const_int 8)))]
3839   "TARGET_H8300H || TARGET_H8300S"
3840   "@
3841    mov.b\\t%x1,%w0\;extu.w\\t%f0\;extu.l\\t%S0
3842    sub.l\\t%S0,%S0\;mov.b\\t%x1,%w0"
3843   [(set_attr "cc" "set_znv,clobber")
3844    (set_attr "length" "6,4")])
3846 (define_insn "*extzv_8_16"
3847   [(set (match_operand:SI 0 "register_operand" "=r")
3848         (zero_extract:SI (match_operand:SI 1 "register_operand" "r")
3849                          (const_int 8)
3850                          (const_int 16)))]
3851   "TARGET_H8300H || TARGET_H8300S"
3852   "mov.w\\t%e1,%f0\;extu.w\\t%f0\;extu.l\\t%S0"
3853   [(set_attr "cc" "set_znv")
3854    (set_attr "length" "6")])
3856 (define_insn "*extzv_16_8"
3857   [(set (match_operand:SI 0 "register_operand" "=r")
3858         (zero_extract:SI (match_operand:SI 1 "register_operand" "r")
3859                          (const_int 16)
3860                          (const_int 8)))
3861    (clobber (match_scratch:SI 2 "=&r"))]
3862   "TARGET_H8300H"
3863   "mov.w\\t%e1,%f2\;mov.b\\t%x1,%w0\;mov.b\\t%w2,%x0\;extu.l\\t%S0"
3864   [(set_attr "length" "8")
3865    (set_attr "cc" "set_znv")])
3867 ;; Extract the exponent of a float.
3869 (define_insn_and_split "*extzv_8_23"
3870   [(set (match_operand:SI 0 "register_operand" "=r")
3871         (zero_extract:SI (match_operand:SI 1 "register_operand" "0")
3872                          (const_int 8)
3873                          (const_int 23)))]
3874   "(TARGET_H8300H || TARGET_H8300S)"
3875   "#"
3876   "&& reload_completed"
3877   [(parallel [(set (match_dup 0)
3878                    (ashift:SI (match_dup 0)
3879                               (const_int 1)))
3880               (clobber (scratch:QI))])
3881    (parallel [(set (match_dup 0)
3882                    (lshiftrt:SI (match_dup 0)
3883                                 (const_int 24)))
3884               (clobber (scratch:QI))])]
3885   "")
3887 ;; and:SI
3889 ;; ((SImode) HImode) << 15
3891 (define_insn_and_split "*twoshifts_l16_r1"
3892   [(set (match_operand:SI 0 "register_operand" "=r")
3893         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
3894                            (const_int 15))
3895                 (const_int 2147450880)))]
3896   "(TARGET_H8300H || TARGET_H8300S)"
3897   "#"
3898   "&& reload_completed"
3899   [(parallel [(set (match_dup 0)
3900                    (ashift:SI (match_dup 0)
3901                               (const_int 16)))
3902               (clobber (scratch:QI))])
3903    (parallel [(set (match_dup 0)
3904                    (lshiftrt:SI (match_dup 0)
3905                                 (const_int 1)))
3906               (clobber (scratch:QI))])]
3907   "")
3909 ;; Transform (SImode << B) & 0xffff into (SImode) (HImode << B).
3911 (define_insn_and_split "*andsi3_ashift_n_lower"
3912   [(set (match_operand:SI 0 "register_operand" "=r,r")
3913         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0,0")
3914                            (match_operand:QI 2 "const_int_operand" "S,n"))
3915                 (match_operand:SI 3 "const_int_operand" "n,n")))
3916    (clobber (match_scratch:QI 4 "=X,&r"))]
3917   "(TARGET_H8300H || TARGET_H8300S)
3918     && INTVAL (operands[2]) <= 15
3919     && INTVAL (operands[3]) == ((-1 << INTVAL (operands[2])) & 0xffff)"
3920   "#"
3921   "&& reload_completed"
3922   [(parallel [(set (match_dup 5)
3923                    (ashift:HI (match_dup 5)
3924                               (match_dup 2)))
3925               (clobber (match_dup 4))])
3926    (set (match_dup 0)
3927         (zero_extend:SI (match_dup 5)))]
3928   {
3929     operands[5] = gen_rtx_REG (HImode, REGNO (operands[0]));
3930   })
3932 ;; Accept (A >> 30) & 2 and the like.
3934 (define_insn "*andsi3_lshiftrt_n_sb"
3935   [(set (match_operand:SI 0 "register_operand" "=r")
3936         (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
3937                              (match_operand:SI 2 "const_int_operand" "n"))
3938                 (match_operand:SI 3 "single_one_operand" "n")))]
3939   "(TARGET_H8300H || TARGET_H8300S)
3940     && exact_log2 (INTVAL (operands[3])) < 16
3941     && INTVAL (operands[2]) + exact_log2 (INTVAL (operands[3])) == 31"
3943   operands[3] = GEN_INT (exact_log2 (INTVAL (operands[3])));
3944   return "shll.l\\t%S0\;xor.l\\t%S0,%S0\;bst\\t%Z3,%Y0";
3946   [(set_attr "length" "8")])
3948 (define_insn_and_split "*andsi3_lshiftrt_9_sb"
3949   [(set (match_operand:SI 0 "register_operand" "=r")
3950         (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
3951                              (const_int 9))
3952                 (const_int 4194304)))]
3953   "TARGET_H8300H || TARGET_H8300S"
3954   "#"
3955   "&& reload_completed"
3956   [(set (match_dup 0)
3957         (and:SI (lshiftrt:SI (match_dup 0)
3958                              (const_int 25))
3959                 (const_int 64)))
3960    (parallel [(set (match_dup 0)
3961                    (ashift:SI (match_dup 0)
3962                               (const_int 16)))
3963               (clobber (scratch:QI))])]
3964   "")
3966 ;; plus:SI
3968 (define_insn "*addsi3_upper"
3969   [(set (match_operand:SI 0 "register_operand" "=r")
3970         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
3971                           (const_int 65536))
3972                  (match_operand:SI 2 "register_operand" "0")))]
3973   "TARGET_H8300H || TARGET_H8300S"
3974   "add.w\\t%f1,%e0"
3975   [(set_attr "length" "2")])
3977 (define_insn "*addsi3_lshiftrt_16_zexthi"
3978   [(set (match_operand:SI 0 "register_operand" "=r")
3979         (plus:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
3980                               (const_int 16))
3981                  (zero_extend:SI (match_operand:HI 2 "register_operand" "0"))))]
3982   "TARGET_H8300H || TARGET_H8300S"
3983   "add.w\\t%e1,%f0\;xor.w\\t%e0,%e0\;rotxl.w\\t%e0"
3984   [(set_attr "length" "6")])
3986 (define_insn_and_split "*addsi3_and_r_1"
3987   [(set (match_operand:SI 0 "register_operand" "=r")
3988         (plus:SI (and:SI (match_operand:SI 1 "register_operand" "r")
3989                          (const_int 1))
3990                  (match_operand:SI 2 "register_operand" "0")))]
3991   "TARGET_H8300H || TARGET_H8300S"
3992   "#"
3993   "&& reload_completed"
3994   [(set (cc0) (compare (zero_extract:SI (match_dup 1)
3995                                         (const_int 1)
3996                                         (const_int 0))
3997                        (const_int 0)))
3998    (set (pc)
3999         (if_then_else (eq (cc0)
4000                           (const_int 0))
4001                       (label_ref (match_dup 3))
4002                       (pc)))
4003    (set (match_dup 2)
4004         (plus:SI (match_dup 2)
4005                  (const_int 1)))
4006    (match_dup 3)]
4007   {
4008     operands[3] = gen_label_rtx ();
4009   })
4011 (define_insn_and_split "*addsi3_and_not_r_1"
4012   [(set (match_operand:SI 0 "register_operand" "=r")
4013         (plus:SI (and:SI (not:SI (match_operand:SI 1 "register_operand" "r"))
4014                          (const_int 1))
4015                  (match_operand:SI 2 "register_operand" "0")))]
4016   "TARGET_H8300H || TARGET_H8300S"
4017   "#"
4018   "&& reload_completed"
4019   [(set (cc0) (compare (zero_extract:SI (match_dup 1)
4020                                         (const_int 1)
4021                                         (const_int 0))
4022                        (const_int 0)))
4023    (set (pc)
4024         (if_then_else (ne (cc0)
4025                           (const_int 0))
4026                       (label_ref (match_dup 3))
4027                       (pc)))
4028    (set (match_dup 2)
4029         (plus:SI (match_dup 2)
4030                  (const_int 1)))
4031    (match_dup 3)]
4032   {
4033     operands[3] = gen_label_rtx ();
4034   })
4036 ;; [ix]or:HI
4038 (define_insn "*ixorhi3_zext"
4039   [(set (match_operand:HI 0 "register_operand" "=r")
4040         (match_operator:HI 1 "iorxor_operator"
4041          [(zero_extend:HI (match_operand:QI 2 "register_operand" "r"))
4042           (match_operand:HI 3 "register_operand" "0")]))]
4043   ""
4044   "%c1.b\\t%X2,%s0"
4045   [(set_attr "length" "2")])
4047 ;; [ix]or:SI
4049 (define_insn "*ixorsi3_zext_qi"
4050   [(set (match_operand:SI 0 "register_operand" "=r")
4051         (match_operator:SI 1 "iorxor_operator"
4052          [(zero_extend:SI (match_operand:QI 2 "register_operand" "r"))
4053           (match_operand:SI 3 "register_operand" "0")]))]
4054   ""
4055   "%c1.b\\t%X2,%w0"
4056   [(set_attr "length" "2")])
4058 (define_insn "*ixorsi3_zext_hi"
4059   [(set (match_operand:SI 0 "register_operand" "=r")
4060         (match_operator:SI 1 "iorxor_operator"
4061          [(zero_extend:SI (match_operand:HI 2 "register_operand" "r"))
4062           (match_operand:SI 3 "register_operand" "0")]))]
4063   "TARGET_H8300H || TARGET_H8300S"
4064   "%c1.w\\t%T2,%f0"
4065   [(set_attr "length" "2")])
4067 (define_insn "*ixorsi3_ashift_16"
4068   [(set (match_operand:SI 0 "register_operand" "=r")
4069         (match_operator:SI 1 "iorxor_operator"
4070          [(ashift:SI (match_operand:SI 2 "register_operand" "r")
4071                      (const_int 16))
4072           (match_operand:SI 3 "register_operand" "0")]))]
4073   "TARGET_H8300H || TARGET_H8300S"
4074   "%c1.w\\t%f2,%e0"
4075   [(set_attr "length" "2")])
4077 (define_insn "*ixorsi3_lshiftrt_16"
4078   [(set (match_operand:SI 0 "register_operand" "=r")
4079         (match_operator:SI 1 "iorxor_operator"
4080          [(lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
4081                        (const_int 16))
4082           (match_operand:SI 3 "register_operand" "0")]))]
4083   "TARGET_H8300H || TARGET_H8300S"
4084   "%c1.w\\t%e2,%f0"
4085   [(set_attr "length" "2")])
4087 ;; ior:HI
4089 (define_insn "*iorhi3_ashift_8"
4090   [(set (match_operand:HI 0 "register_operand" "=r")
4091         (ior:HI (ashift:HI (match_operand:HI 1 "register_operand" "r")
4092                            (const_int 8))
4093                 (match_operand:HI 2 "register_operand" "0")))]
4094   ""
4095   "or.b\\t%s1,%t0"
4096   [(set_attr "length" "2")])
4098 (define_insn "*iorhi3_lshiftrt_8"
4099   [(set (match_operand:HI 0 "register_operand" "=r")
4100         (ior:HI (lshiftrt:HI (match_operand:HI 1 "register_operand" "r")
4101                              (const_int 8))
4102                 (match_operand:HI 2 "register_operand" "0")))]
4103   ""
4104   "or.b\\t%t1,%s0"
4105   [(set_attr "length" "2")])
4107 (define_insn "*iorhi3_two_qi"
4108   [(set (match_operand:HI 0 "register_operand" "=r")
4109         (ior:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "0"))
4110                 (ashift:HI (match_operand:HI 2 "register_operand" "r")
4111                            (const_int 8))))]
4112   ""
4113   "mov.b\\t%s2,%t0"
4114   [(set_attr "length" "2")])
4116 (define_insn "*iorhi3_two_qi_mem"
4117   [(set (match_operand:HI 0 "register_operand" "=&r")
4118         (ior:HI (zero_extend:HI (match_operand:QI 1 "memory_operand" "m"))
4119                 (ashift:HI (subreg:HI (match_operand:QI 2 "memory_operand" "m") 0)
4120                            (const_int 8))))]
4121   ""
4122   "mov.b\\t%X2,%t0\;mov.b\\t%X1,%s0"
4123   [(set_attr "length" "16")])
4125 (define_split
4126   [(set (match_operand:HI 0 "register_operand" "")
4127         (ior:HI (zero_extend:HI (match_operand:QI 1 "memory_operand" ""))
4128                 (ashift:HI (subreg:HI (match_operand:QI 2 "memory_operand" "") 0)
4129                            (const_int 8))))]
4130   "(TARGET_H8300H || TARGET_H8300S)
4131     && reload_completed
4132     && byte_accesses_mergeable_p (XEXP (operands[2], 0), XEXP (operands[1], 0))"
4133   [(set (match_dup 0)
4134         (match_dup 3))]
4135   {
4136     operands[3] = gen_rtx_MEM (HImode, XEXP (operands[2], 0));
4137   })
4139 ;; ior:SI
4141 (define_insn "*iorsi3_two_hi"
4142   [(set (match_operand:SI 0 "register_operand" "=r")
4143         (ior:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "0"))
4144                 (ashift:SI (match_operand:SI 2 "register_operand" "r")
4145                            (const_int 16))))]
4146   "TARGET_H8300H || TARGET_H8300S"
4147   "mov.w\\t%f2,%e0"
4148   [(set_attr "length" "2")])
4150 (define_insn_and_split "*iorsi3_two_qi_zext"
4151   [(set (match_operand:SI 0 "register_operand" "=&r")
4152         (ior:SI (zero_extend:SI (match_operand:QI 1 "memory_operand" "m"))
4153                 (and:SI (ashift:SI (subreg:SI (match_operand:QI 2 "memory_operand" "m") 0)
4154                                    (const_int 8))
4155                         (const_int 65280))))]
4156   "TARGET_H8300H || TARGET_H8300S"
4157   "#"
4158   "&& reload_completed"
4159   [(set (match_dup 3)
4160         (ior:HI (zero_extend:HI (match_dup 1))
4161                 (ashift:HI (subreg:HI (match_dup 2) 0)
4162                            (const_int 8))))
4163    (set (match_dup 0)
4164         (zero_extend:SI (match_dup 3)))]
4165   {
4166     operands[3] = gen_rtx_REG (HImode, REGNO (operands[0]));
4167   })
4169 (define_insn "*iorsi3_e2f"
4170   [(set (match_operand:SI 0 "register_operand" "=r")
4171         (ior:SI (and:SI (match_operand:SI 1 "register_operand" "0")
4172                         (const_int -65536))
4173                 (lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
4174                              (const_int 16))))]
4175   "TARGET_H8300H || TARGET_H8300S"
4176   "mov.w\\t%e2,%f0"
4177   [(set_attr "length" "2")])
4179 (define_insn_and_split "*iorsi3_two_qi_sext"
4180   [(set (match_operand:SI 0 "register_operand" "=r")
4181         (ior:SI (zero_extend:SI (match_operand:QI 1 "register_operand" "0"))
4182                 (ashift:SI (sign_extend:SI (match_operand:QI 2 "register_operand" "r"))
4183                            (const_int 8))))]
4184   "TARGET_H8300H || TARGET_H8300S"
4185   "#"
4186   "&& reload_completed"
4187   [(set (match_dup 3)
4188         (ior:HI (zero_extend:HI (match_dup 1))
4189                 (ashift:HI (match_dup 4)
4190                            (const_int 8))))
4191    (set (match_dup 0)
4192         (sign_extend:SI (match_dup 3)))]
4193   {
4194     operands[3] = gen_rtx_REG (HImode, REGNO (operands[0]));
4195     operands[4] = gen_rtx_REG (HImode, REGNO (operands[2]));
4196   })
4198 (define_insn "*iorsi3_w"
4199   [(set (match_operand:SI 0 "register_operand" "=r,&r")
4200         (ior:SI (and:SI (match_operand:SI 1 "register_operand" "0,0")
4201                         (const_int -256))
4202                 (zero_extend:SI (match_operand:QI 2 "general_operand_src" "r,g>"))))]
4203   "TARGET_H8300H || TARGET_H8300S"
4204   "mov.b\\t%X2,%w0"
4205   [(set_attr "length" "2,8")])
4207 (define_insn "*iorsi3_ashift_31"
4208   [(set (match_operand:SI 0 "register_operand" "=&r")
4209         (ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "r")
4210                            (const_int 31))
4211                 (match_operand:SI 2 "register_operand" "0")))]
4212   "TARGET_H8300H || TARGET_H8300S"
4213   "rotxl.l\\t%S0\;bor\\t#0,%w1\;rotxr.l\\t%S0"
4214   [(set_attr "length" "6")
4215    (set_attr "cc" "set_znv")])
4217 (define_insn "*iorsi3_and_ashift"
4218   [(set (match_operand:SI 0 "register_operand" "=r")
4219         (ior:SI (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "r")
4220                                    (match_operand:SI 2 "const_int_operand" "n"))
4221                         (match_operand:SI 3 "single_one_operand" "n"))
4222                 (match_operand:SI 4 "register_operand" "0")))]
4223   "(TARGET_H8300H || TARGET_H8300S)
4224     && (INTVAL (operands[3]) & ~0xffff) == 0"
4226   rtx srcpos = GEN_INT (exact_log2 (INTVAL (operands[3]))
4227                         - INTVAL (operands[2]));
4228   rtx dstpos = GEN_INT (exact_log2 (INTVAL (operands[3])));
4229   operands[2] = srcpos;
4230   operands[3] = dstpos;
4231   return "bld\\t%Z2,%Y1\;bor\\t%Z3,%Y0\;bst\\t%Z3,%Y0";
4233   [(set_attr "length" "6")])
4235 (define_insn "*iorsi3_and_lshiftrt"
4236   [(set (match_operand:SI 0 "register_operand" "=r")
4237         (ior:SI (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
4238                                      (match_operand:SI 2 "const_int_operand" "n"))
4239                         (match_operand:SI 3 "single_one_operand" "n"))
4240                 (match_operand:SI 4 "register_operand" "0")))]
4241   "(TARGET_H8300H || TARGET_H8300S)
4242     && ((INTVAL (operands[3]) << INTVAL (operands[2])) & ~0xffff) == 0"
4244   rtx srcpos = GEN_INT (exact_log2 (INTVAL (operands[3]))
4245                         + INTVAL (operands[2]));
4246   rtx dstpos = GEN_INT (exact_log2 (INTVAL (operands[3])));
4247   operands[2] = srcpos;
4248   operands[3] = dstpos;
4249   return "bld\\t%Z2,%Y1\;bor\\t%Z3,%Y0\;bst\\t%Z3,%Y0";
4251   [(set_attr "length" "6")])
4253 (define_insn "*iorsi3_zero_extract"
4254   [(set (match_operand:SI 0 "register_operand" "=r")
4255         (ior:SI (zero_extract:SI (match_operand:SI 1 "register_operand" "r")
4256                                  (const_int 1)
4257                                  (match_operand:SI 2 "const_int_operand" "n"))
4258                 (match_operand:SI 3 "register_operand" "0")))]
4259   "(TARGET_H8300H || TARGET_H8300S) && INTVAL (operands[2]) < 16"
4260   "bld\\t%Z2,%Y1\;bor\\t#0,%w0\;bst\\t#0,%w0"
4261   [(set_attr "length" "6")])
4263 (define_insn "*iorsi3_and_lshiftrt_n_sb"
4264   [(set (match_operand:SI 0 "register_operand" "=r")
4265         (ior:SI (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
4266                                      (const_int 30))
4267                         (const_int 2))
4268                 (match_operand:SI 2 "register_operand" "0")))]
4269   "TARGET_H8300H || TARGET_H8300S"
4270   "rotl.l\\t%S1\;rotr.l\\t%S1\;bor\\t#1,%w0\;bst\\t#1,%w0"
4271   [(set_attr "length" "8")])
4273 (define_insn "*iorsi3_and_lshiftrt_9_sb"
4274   [(set (match_operand:SI 0 "register_operand" "=r")
4275         (ior:SI (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
4276                                      (const_int 9))
4277                         (const_int 4194304))
4278                 (match_operand:SI 2 "register_operand" "0")))
4279    (clobber (match_scratch:HI 3 "=&r"))]
4280   "TARGET_H8300H || TARGET_H8300S"
4282   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4283     return "shll.l\\t%S1\;xor.w\\t%T3,%T3\;bst\\t#6,%s3\;or.w\\t%T3,%e0";
4284   else
4285     return "rotl.l\\t%S1\;rotr.l\\t%S1\;xor.w\\t%T3,%T3\;bst\\t#6,%s3\;or.w\\t%T3,%e0";
4287   [(set_attr "length" "10")])
4289 ;; Used to OR the exponent of a float.
4291 (define_insn "*iorsi3_shift"
4292   [(set (match_operand:SI 0 "register_operand" "=r")
4293         (ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "r")
4294                            (const_int 23))
4295                 (match_operand:SI 2 "register_operand" "0")))
4296    (clobber (match_scratch:SI 3 "=&r"))]
4297   "TARGET_H8300H || TARGET_H8300S"
4298   "#")
4300 (define_split
4301   [(set (match_operand:SI 0 "register_operand" "")
4302         (ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
4303                            (const_int 23))
4304                 (match_dup 0)))
4305    (clobber (match_operand:SI 2 "register_operand" ""))]
4306   "(TARGET_H8300H || TARGET_H8300S)
4307     && epilogue_completed
4308     && find_regno_note (insn, REG_DEAD, REGNO (operands[1]))
4309     && REGNO (operands[0]) != REGNO (operands[1])"
4310   [(parallel [(set (match_dup 3)
4311                    (ashift:HI (match_dup 3)
4312                               (const_int 7)))
4313               (clobber (scratch:QI))])
4314    (set (match_dup 0)
4315         (ior:SI (ashift:SI (match_dup 1)
4316                            (const_int 16))
4317                 (match_dup 0)))]
4318   {
4319     operands[3] = gen_rtx_REG (HImode, REGNO (operands[1]));
4320   })
4322 (define_split
4323   [(set (match_operand:SI 0 "register_operand" "")
4324         (ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
4325                            (const_int 23))
4326                 (match_dup 0)))
4327    (clobber (match_operand:SI 2 "register_operand" ""))]
4328   "(TARGET_H8300H || TARGET_H8300S)
4329     && epilogue_completed
4330     && !(find_regno_note (insn, REG_DEAD, REGNO (operands[1]))
4331          && REGNO (operands[0]) != REGNO (operands[1]))"
4332   [(set (match_dup 2)
4333         (match_dup 1))
4334    (parallel [(set (match_dup 3)
4335                    (ashift:HI (match_dup 3)
4336                               (const_int 7)))
4337               (clobber (scratch:QI))])
4338    (set (match_dup 0)
4339         (ior:SI (ashift:SI (match_dup 2)
4340                            (const_int 16))
4341                 (match_dup 0)))]
4342   {
4343     operands[3] = gen_rtx_REG (HImode, REGNO (operands[2]));
4344   })
4346 (define_insn "*iorsi2_and_1_lshiftrt_1"
4347   [(set (match_operand:SI 0 "register_operand" "=r")
4348         (ior:SI (and:SI (match_operand:SI 1 "register_operand" "0")
4349                         (const_int 1))
4350                 (lshiftrt:SI (match_dup 1)
4351                              (const_int 1))))]
4352   "TARGET_H8300H || TARGET_H8300S"
4353   "shlr.l\\t%S0\;bor\\t#0,%w0\;bst\\t#0,%w0"
4354   [(set_attr "length" "6")])
4356 (define_insn_and_split "*iorsi3_ashift_16_ashift_24"
4357   [(set (match_operand:SI 0 "register_operand" "=r")
4358         (ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
4359                            (const_int 16))
4360                 (ashift:SI (match_operand:SI 2 "register_operand" "r")
4361                            (const_int 24))))]
4362   "TARGET_H8300H || TARGET_H8300S"
4363   "#"
4364   "&& reload_completed"
4365   [(set (match_dup 3)
4366         (ior:HI (ashift:HI (match_dup 4)
4367                            (const_int 8))
4368                 (match_dup 3)))
4369    (parallel [(set (match_dup 0)
4370                    (ashift:SI (match_dup 0)
4371                               (const_int 16)))
4372               (clobber (scratch:QI))])]
4373   {
4374     operands[3] = gen_rtx_REG (HImode, REGNO (operands[0]));
4375     operands[4] = gen_rtx_REG (HImode, REGNO (operands[2]));
4376   })
4378 (define_insn_and_split "*iorsi3_ashift_16_ashift_24_mem"
4379   [(set (match_operand:SI 0 "register_operand" "=&r")
4380         (ior:SI (and:SI (ashift:SI (subreg:SI (match_operand:QI 1 "memory_operand" "m") 0)
4381                                    (const_int 16))
4382                         (const_int 16711680))
4383                 (ashift:SI (subreg:SI (match_operand:QI 2 "memory_operand" "m") 0)
4384                            (const_int 24))))]
4385   "TARGET_H8300H || TARGET_H8300S"
4386   "#"
4387   "&& reload_completed"
4388   [(set (match_dup 3)
4389         (ior:HI (zero_extend:HI (match_dup 1))
4390                 (ashift:HI (subreg:HI (match_dup 2) 0)
4391                            (const_int 8))))
4392    (parallel [(set (match_dup 0)
4393                    (ashift:SI (match_dup 0)
4394                               (const_int 16)))
4395               (clobber (scratch:QI))])]
4396   {
4397     operands[3] = gen_rtx_REG (HImode, REGNO (operands[0]));
4398   })
4400 ;; Used to add the exponent of a float.
4402 (define_insn "*addsi3_shift"
4403   [(set (match_operand:SI 0 "register_operand" "=r")
4404         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
4405                           (const_int 8388608))
4406                  (match_operand:SI 2 "register_operand" "0")))
4407    (clobber (match_scratch:SI 3 "=&r"))]
4408   "TARGET_H8300H || TARGET_H8300S"
4409   "#")
4411 (define_split
4412   [(set (match_operand:SI 0 "register_operand" "")
4413         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "")
4414                           (const_int 8388608))
4415                  (match_dup 0)))
4416    (clobber (match_operand:SI 2 "register_operand" ""))]
4417   "(TARGET_H8300H || TARGET_H8300S)
4418     && epilogue_completed
4419     && find_regno_note (insn, REG_DEAD, REGNO (operands[1]))
4420     && REGNO (operands[0]) != REGNO (operands[1])"
4421   [(parallel [(set (match_dup 3)
4422                    (ashift:HI (match_dup 3)
4423                               (const_int 7)))
4424               (clobber (scratch:QI))])
4425    (set (match_dup 0)
4426         (plus:SI (mult:SI (match_dup 1)
4427                           (const_int 65536))
4428                  (match_dup 0)))]
4429   {
4430     operands[3] = gen_rtx_REG (HImode, REGNO (operands[1]));
4431   })
4433 (define_split
4434   [(set (match_operand:SI 0 "register_operand" "")
4435         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "")
4436                           (const_int 8388608))
4437                  (match_dup 0)))
4438    (clobber (match_operand:SI 2 "register_operand" ""))]
4439   "(TARGET_H8300H || TARGET_H8300S)
4440     && epilogue_completed
4441     && !(find_regno_note (insn, REG_DEAD, REGNO (operands[1]))
4442          && REGNO (operands[0]) != REGNO (operands[1]))"
4443   [(set (match_dup 2)
4444         (match_dup 1))
4445    (parallel [(set (match_dup 3)
4446                    (ashift:HI (match_dup 3)
4447                               (const_int 7)))
4448               (clobber (scratch:QI))])
4449    (set (match_dup 0)
4450         (plus:SI (mult:SI (match_dup 2)
4451                           (const_int 65536))
4452                  (match_dup 0)))]
4453   {
4454     operands[3] = gen_rtx_REG (HImode, REGNO (operands[2]));
4455   })
4457 ;; ashift:SI
4459 (define_insn_and_split "*ashiftsi_sextqi_7"
4460   [(set (match_operand:SI 0 "register_operand" "=r")
4461         (ashift:SI (sign_extend:SI (match_operand:QI 1 "register_operand" "0"))
4462                    (const_int 7)))]
4463   "TARGET_H8300H || TARGET_H8300S"
4464   "#"
4465   "&& reload_completed"
4466   [(parallel [(set (match_dup 2)
4467                    (ashift:HI (match_dup 2)
4468                               (const_int 8)))
4469               (clobber (scratch:QI))])
4470    (set (match_dup 0)
4471         (sign_extend:SI (match_dup 2)))
4472    (parallel [(set (match_dup 0)
4473                    (ashiftrt:SI (match_dup 0)
4474                                 (const_int 1)))
4475               (clobber (scratch:QI))])]
4476   { 
4477     operands[2] = gen_rtx_REG (HImode, REGNO (operands[0]));
4478   })
4480 ;; Storing a part of HImode to QImode.
4482 (define_insn ""
4483   [(set (match_operand:QI 0 "general_operand_dst" "=rm<")
4484         (subreg:QI (lshiftrt:HI (match_operand:HI 1 "register_operand" "r")
4485                                 (const_int 8)) 1))]
4486   ""
4487   "mov.b\\t%t1,%R0"
4488   [(set_attr "cc" "set_znv")
4489    (set_attr "length" "8")])
4491 ;; Storing a part of SImode to QImode.
4493 (define_insn ""
4494   [(set (match_operand:QI 0 "general_operand_dst" "=rm<")
4495         (subreg:QI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
4496                                 (const_int 8)) 3))]
4497   ""
4498   "mov.b\\t%x1,%R0"
4499   [(set_attr "cc" "set_znv")
4500    (set_attr "length" "8")])
4502 (define_insn ""
4503   [(set (match_operand:QI 0 "general_operand_dst" "=rm<")
4504         (subreg:QI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
4505                                 (const_int 16)) 3))
4506    (clobber (match_scratch:SI 2 "=&r"))]
4507   "TARGET_H8300H || TARGET_H8300S"
4508   "mov.w\\t%e1,%f2\;mov.b\\t%w2,%R0"
4509   [(set_attr "cc" "set_znv")
4510    (set_attr "length" "10")])
4512 (define_insn ""
4513   [(set (match_operand:QI 0 "general_operand_dst" "=rm<")
4514         (subreg:QI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
4515                                 (const_int 24)) 3))
4516    (clobber (match_scratch:SI 2 "=&r"))]
4517   "TARGET_H8300H || TARGET_H8300S"
4518   "mov.w\\t%e1,%f2\;mov.b\\t%x2,%R0"
4519   [(set_attr "cc" "set_znv")
4520    (set_attr "length" "10")])
4522 (define_insn_and_split ""
4523   [(set (pc)
4524         (if_then_else (eq (zero_extract:SI (subreg:SI (match_operand:QI 0 "register_operand" "") 0)
4525                                            (const_int 1)
4526                                            (const_int 7))
4527                           (const_int 0))
4528                       (label_ref (match_operand 1 "" ""))
4529                       (pc)))]
4530   ""
4531   "#"
4532   ""
4533   [(set (cc0) (compare (match_dup 0)
4534                        (const_int 0)))
4535    (set (pc)
4536         (if_then_else (ge (cc0)
4537                           (const_int 0))
4538                       (label_ref (match_dup 1))
4539                       (pc)))]
4540   "")
4542 (define_insn_and_split ""
4543   [(set (pc)
4544         (if_then_else (ne (zero_extract:SI (subreg:SI (match_operand:QI 0 "register_operand" "") 0)
4545                                            (const_int 1)
4546                                            (const_int 7))
4547                           (const_int 0))
4548                       (label_ref (match_operand 1 "" ""))
4549                       (pc)))]
4550   ""
4551   "#"
4552   ""
4553   [(set (cc0) (compare (match_dup 0)
4554                        (const_int 0)))
4555    (set (pc)
4556         (if_then_else (lt (cc0)
4557                           (const_int 0))
4558                       (label_ref (match_dup 1))
4559                       (pc)))]
4560   "")
4562 ;; -----------------------------------------------------------------
4563 ;; PEEPHOLE PATTERNS
4564 ;; -----------------------------------------------------------------
4566 ;; Convert (A >> B) & C to (A & 255) >> B if C == 255 >> B.
4568 (define_peephole2
4569   [(parallel [(set (match_operand:HI 0 "register_operand" "")
4570                    (lshiftrt:HI (match_dup 0)
4571                                 (match_operand:HI 1 "const_int_operand" "")))
4572               (clobber (match_operand:HI 2 "" ""))])
4573    (set (match_dup 0)
4574         (and:HI (match_dup 0)
4575                 (match_operand:HI 3 "const_int_operand" "")))]
4576   "INTVAL (operands[3]) == (255 >> INTVAL (operands[1]))"
4577   [(set (match_dup 0)
4578         (and:HI (match_dup 0)
4579                 (const_int 255)))
4580    (parallel [(set (match_dup 0)
4581                    (lshiftrt:HI (match_dup 0) (match_dup 1)))
4582               (clobber (match_dup 2))])]
4583   "")
4585 ;; Convert (A << B) & C to (A & 255) << B if C == 255 << B.
4587 (define_peephole2
4588   [(parallel [(set (match_operand:HI 0 "register_operand" "")
4589                    (ashift:HI (match_dup 0)
4590                               (match_operand:HI 1 "const_int_operand" "")))
4591               (clobber (match_operand:HI 2 "" ""))])
4592    (set (match_dup 0)
4593         (and:HI (match_dup 0)
4594                 (match_operand:HI 3 "const_int_operand" "")))]
4595   "INTVAL (operands[3]) == (255 << INTVAL (operands[1]))"
4596   [(set (match_dup 0)
4597         (and:HI (match_dup 0)
4598                 (const_int 255)))
4599    (parallel [(set (match_dup 0)
4600                    (ashift:HI (match_dup 0) (match_dup 1)))
4601               (clobber (match_dup 2))])]
4602   "")
4604 ;; Convert (A >> B) & C to (A & 255) >> B if C == 255 >> B.
4606 (define_peephole2
4607   [(parallel [(set (match_operand:SI 0 "register_operand" "")
4608                    (lshiftrt:SI (match_dup 0)
4609                                 (match_operand:SI 1 "const_int_operand" "")))
4610               (clobber (match_operand:SI 2 "" ""))])
4611    (set (match_dup 0)
4612         (and:SI (match_dup 0)
4613                 (match_operand:SI 3 "const_int_operand" "")))]
4614   "INTVAL (operands[3]) == (255 >> INTVAL (operands[1]))"
4615   [(set (match_dup 0)
4616         (and:SI (match_dup 0)
4617                 (const_int 255)))
4618    (parallel [(set (match_dup 0)
4619                    (lshiftrt:SI (match_dup 0) (match_dup 1)))
4620               (clobber (match_dup 2))])]
4621   "")
4623 ;; Convert (A << B) & C to (A & 255) << B if C == 255 << B.
4625 (define_peephole2
4626   [(parallel [(set (match_operand:SI 0 "register_operand" "")
4627                    (ashift:SI (match_dup 0)
4628                               (match_operand:SI 1 "const_int_operand" "")))
4629               (clobber (match_operand:SI 2 "" ""))])
4630    (set (match_dup 0)
4631         (and:SI (match_dup 0)
4632                 (match_operand:SI 3 "const_int_operand" "")))]
4633   "INTVAL (operands[3]) == (255 << INTVAL (operands[1]))"
4634   [(set (match_dup 0)
4635         (and:SI (match_dup 0)
4636                 (const_int 255)))
4637    (parallel [(set (match_dup 0)
4638                    (ashift:SI (match_dup 0) (match_dup 1)))
4639               (clobber (match_dup 2))])]
4640   "")
4642 ;; Convert (A >> B) & C to (A & 65535) >> B if C == 65535 >> B.
4644 (define_peephole2
4645   [(parallel [(set (match_operand:SI 0 "register_operand" "")
4646                    (lshiftrt:SI (match_dup 0)
4647                                 (match_operand:SI 1 "const_int_operand" "")))
4648               (clobber (match_operand:SI 2 "" ""))])
4649    (set (match_dup 0)
4650         (and:SI (match_dup 0)
4651                 (match_operand:SI 3 "const_int_operand" "")))]
4652   "INTVAL (operands[3]) == (65535 >> INTVAL (operands[1]))"
4653   [(set (match_dup 0)
4654         (and:SI (match_dup 0)
4655                 (const_int 65535)))
4656    (parallel [(set (match_dup 0)
4657                    (lshiftrt:SI (match_dup 0) (match_dup 1)))
4658               (clobber (match_dup 2))])]
4659   "")
4661 ;; Convert (A << B) & C to (A & 65535) << B if C == 65535 << B.
4663 (define_peephole2
4664   [(parallel [(set (match_operand:SI 0 "register_operand" "")
4665                    (ashift:SI (match_dup 0)
4666                               (match_operand:SI 1 "const_int_operand" "")))
4667               (clobber (match_operand:SI 2 "" ""))])
4668    (set (match_dup 0)
4669         (and:SI (match_dup 0)
4670                 (match_operand:SI 3 "const_int_operand" "")))]
4671   "INTVAL (operands[3]) == (65535 << INTVAL (operands[1]))"
4672   [(set (match_dup 0)
4673         (and:SI (match_dup 0)
4674                 (const_int 65535)))
4675    (parallel [(set (match_dup 0)
4676                    (ashift:SI (match_dup 0) (match_dup 1)))
4677               (clobber (match_dup 2))])]
4678   "")
4680 ;; Convert a QImode push into an SImode push so that the
4681 ;; define_peephole2 below can cram multiple pushes into one stm.l.
4683 (define_peephole2
4684   [(parallel [(set (reg:SI SP_REG)
4685                    (plus:SI (reg:SI SP_REG) (const_int -4)))
4686               (set (mem:QI (plus:SI (reg:SI SP_REG) (const_int -3)))
4687                    (match_operand:QI 0 "register_operand" ""))])]
4688   "TARGET_H8300S && !TARGET_NORMAL_MODE && REGNO (operands[0]) != SP_REG"
4689   [(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
4690         (match_dup 0))]
4691   { 
4692     operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]));
4693   })
4695 (define_peephole2
4696   [(parallel [(set (reg:HI SP_REG)
4697                    (plus:HI (reg:HI SP_REG) (const_int -4)))
4698               (set (mem:QI (plus:HI (reg:HI SP_REG) (const_int -3)))
4699                    (match_operand:QI 0 "register_operand" ""))])]
4700   "TARGET_H8300S && TARGET_NORMAL_MODE && REGNO (operands[0]) != SP_REG"
4701   [(set (mem:SI (pre_dec:HI (reg:HI SP_REG)))
4702         (match_dup 0))]
4703   {
4704     operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]));
4705   })
4707 ;; Convert a HImode push into an SImode push so that the
4708 ;; define_peephole2 below can cram multiple pushes into one stm.l.
4710 (define_peephole2
4711   [(parallel [(set (reg:SI SP_REG)
4712                    (plus:SI (reg:SI SP_REG) (const_int -4)))
4713               (set (mem:HI (plus:SI (reg:SI SP_REG) (const_int -2)))
4714                    (match_operand:HI 0 "register_operand" ""))])]
4715   "TARGET_H8300S && !TARGET_NORMAL_MODE && REGNO (operands[0]) != SP_REG"
4716   [(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
4717         (match_dup 0))]
4718   {
4719     operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]));
4720   })
4722 (define_peephole2
4723   [(parallel [(set (reg:HI SP_REG)
4724                    (plus:HI (reg:HI SP_REG) (const_int -4)))
4725               (set (mem:HI (plus:HI (reg:HI SP_REG) (const_int -2)))
4726                    (match_operand:HI 0 "register_operand" ""))])]
4727   "TARGET_H8300S && TARGET_NORMAL_MODE && REGNO (operands[0]) != SP_REG"
4728   [(set (mem:SI (pre_dec:HI (reg:HI SP_REG)))
4729         (match_dup 0))]
4730   {
4731     operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]));
4732   })
4734 ;; Cram four pushes into stm.l.
4736 (define_peephole2
4737   [(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
4738         (match_operand:SI 0 "register_operand" ""))
4739    (set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
4740         (match_operand:SI 1 "register_operand" ""))
4741    (set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
4742         (match_operand:SI 2 "register_operand" ""))
4743    (set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
4744         (match_operand:SI 3 "register_operand" ""))]
4745   "TARGET_H8300S && !TARGET_NORMAL_MODE
4746    && (REGNO_REG_CLASS (REGNO (operands[3])) == GENERAL_REGS
4747        && REGNO (operands[1]) == REGNO (operands[0]) + 1
4748        && REGNO (operands[2]) == REGNO (operands[0]) + 2
4749        && REGNO (operands[3]) == REGNO (operands[0]) + 3
4750        && (TARGET_H8300SX || REGNO (operands[0]) == 0))"
4751   [(parallel [(set (mem:SI (plus:SI (reg:SI SP_REG) (const_int -4)))
4752                    (match_dup 0))
4753               (set (mem:SI (plus:SI (reg:SI SP_REG) (const_int -8)))
4754                    (match_dup 1))
4755               (set (mem:SI (plus:SI (reg:SI SP_REG) (const_int -12)))
4756                    (match_dup 2))
4757               (set (mem:SI (plus:SI (reg:SI SP_REG) (const_int -16)))
4758                    (match_dup 3))
4759               (set (reg:SI SP_REG)
4760                    (plus:SI (reg:SI SP_REG)
4761                             (const_int -16)))])]
4762   "")
4764 (define_peephole2
4765   [(set (mem:SI (pre_dec:HI (reg:HI SP_REG)))
4766         (match_operand:SI 0 "register_operand" ""))
4767    (set (mem:SI (pre_dec:HI (reg:HI SP_REG)))
4768         (match_operand:SI 1 "register_operand" ""))
4769    (set (mem:SI (pre_dec:HI (reg:HI SP_REG)))
4770         (match_operand:SI 2 "register_operand" ""))
4771    (set (mem:SI (pre_dec:HI (reg:HI SP_REG)))
4772         (match_operand:SI 3 "register_operand" ""))]
4773   "TARGET_H8300S && TARGET_NORMAL_MODE
4774    && (REGNO_REG_CLASS (REGNO (operands[3])) == GENERAL_REGS
4775        && REGNO (operands[1]) == REGNO (operands[0]) + 1
4776        && REGNO (operands[2]) == REGNO (operands[0]) + 2
4777        && REGNO (operands[3]) == REGNO (operands[0]) + 3
4778        && (TARGET_H8300SX || REGNO (operands[0]) == 0))"
4779   [(parallel [(set (mem:SI (plus:HI (reg:HI SP_REG) (const_int -4)))
4780                    (match_dup 0))
4781               (set (mem:SI (plus:HI (reg:HI SP_REG) (const_int -8)))
4782                    (match_dup 1))
4783               (set (mem:SI (plus:HI (reg:HI SP_REG) (const_int -12)))
4784                    (match_dup 2))
4785               (set (mem:SI (plus:HI (reg:HI SP_REG) (const_int -16)))
4786                    (match_dup 3))
4787               (set (reg:HI SP_REG)
4788                    (plus:HI (reg:HI SP_REG)
4789                             (const_int -16)))])]
4790   "")
4792 ;; Cram three pushes into stm.l.
4794 (define_peephole2
4795   [(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
4796         (match_operand:SI 0 "register_operand" ""))
4797    (set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
4798         (match_operand:SI 1 "register_operand" ""))
4799    (set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
4800         (match_operand:SI 2 "register_operand" ""))]
4801   "TARGET_H8300S && !TARGET_NORMAL_MODE
4802    && (REGNO_REG_CLASS (REGNO (operands[2])) == GENERAL_REGS
4803        && REGNO (operands[1]) == REGNO (operands[0]) + 1
4804        && REGNO (operands[2]) == REGNO (operands[0]) + 2
4805        && (TARGET_H8300SX || (REGNO (operands[0]) & 3) == 0))"
4806   [(parallel [(set (mem:SI (plus:SI (reg:SI SP_REG) (const_int -4)))
4807                    (match_dup 0))
4808               (set (mem:SI (plus:SI (reg:SI SP_REG) (const_int -8)))
4809                    (match_dup 1))
4810               (set (mem:SI (plus:SI (reg:SI SP_REG) (const_int -12)))
4811                    (match_dup 2))
4812               (set (reg:SI SP_REG)
4813                    (plus:SI (reg:SI SP_REG)
4814                             (const_int -12)))])]
4815   "")
4817 (define_peephole2
4818   [(set (mem:SI (pre_dec:HI (reg:HI SP_REG)))
4819         (match_operand:SI 0 "register_operand" ""))
4820    (set (mem:SI (pre_dec:HI (reg:HI SP_REG)))
4821         (match_operand:SI 1 "register_operand" ""))
4822    (set (mem:SI (pre_dec:HI (reg:HI SP_REG)))
4823         (match_operand:SI 2 "register_operand" ""))]
4824   "TARGET_H8300S && TARGET_NORMAL_MODE
4825    && (REGNO_REG_CLASS (REGNO (operands[2])) == GENERAL_REGS
4826        && REGNO (operands[1]) == REGNO (operands[0]) + 1
4827        && REGNO (operands[2]) == REGNO (operands[0]) + 2
4828        && (TARGET_H8300SX || (REGNO (operands[0]) & 3) == 0))"
4829   [(parallel [(set (mem:SI (plus:HI (reg:HI SP_REG) (const_int -4)))
4830                    (match_dup 0))
4831               (set (mem:SI (plus:HI (reg:HI SP_REG) (const_int -8)))
4832                    (match_dup 1))
4833               (set (mem:SI (plus:HI (reg:HI SP_REG) (const_int -12)))
4834                    (match_dup 2))
4835               (set (reg:HI SP_REG)
4836                    (plus:HI (reg:HI SP_REG)
4837                             (const_int -12)))])]
4838   "")
4840 ;; Cram two pushes into stm.l.
4842 (define_peephole2
4843   [(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
4844         (match_operand:SI 0 "register_operand" ""))
4845    (set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
4846         (match_operand:SI 1 "register_operand" ""))]
4847   "TARGET_H8300S && !TARGET_NORMAL_MODE
4848    && (REGNO_REG_CLASS (REGNO (operands[1])) == GENERAL_REGS
4849        && REGNO (operands[1]) == REGNO (operands[0]) + 1
4850        && (TARGET_H8300SX || (REGNO (operands[0]) & 1) == 0))"
4851   [(parallel [(set (mem:SI (plus:SI (reg:SI SP_REG) (const_int -4)))
4852                    (match_dup 0))
4853               (set (mem:SI (plus:SI (reg:SI SP_REG) (const_int -8)))
4854                    (match_dup 1))
4855               (set (reg:SI SP_REG)
4856                    (plus:SI (reg:SI SP_REG)
4857                             (const_int -8)))])]
4858   "")
4860 (define_peephole2
4861   [(set (mem:SI (pre_dec:HI (reg:HI SP_REG)))
4862         (match_operand:SI 0 "register_operand" ""))
4863    (set (mem:SI (pre_dec:HI (reg:HI SP_REG)))
4864         (match_operand:SI 1 "register_operand" ""))]
4865   "TARGET_H8300S && TARGET_NORMAL_MODE
4866    && (REGNO_REG_CLASS (REGNO (operands[1])) == GENERAL_REGS
4867        && REGNO (operands[1]) == REGNO (operands[0]) + 1
4868        && (TARGET_H8300SX || (REGNO (operands[0]) & 1) == 0))"
4869   [(parallel [(set (mem:SI (plus:HI (reg:HI SP_REG) (const_int -4)))
4870                    (match_dup 0))
4871               (set (mem:SI (plus:HI (reg:HI SP_REG) (const_int -8)))
4872                    (match_dup 1))
4873               (set (reg:HI SP_REG)
4874                    (plus:HI (reg:HI SP_REG)
4875                             (const_int -8)))])]
4876   "")
4878 ;; Turn
4880 ;;   mov.w #2,r0
4881 ;;   add.w r7,r0  (6 bytes)
4883 ;; into
4885 ;;   mov.w r7,r0
4886 ;;   adds  #2,r0  (4 bytes)
4888 (define_peephole2
4889   [(set (match_operand:HI 0 "register_operand" "")
4890         (match_operand:HI 1 "const_int_operand" ""))
4891    (set (match_dup 0)
4892         (plus:HI (match_dup 0)
4893                  (match_operand:HI 2 "register_operand" "")))]
4894   "REG_P (operands[0]) && REG_P (operands[2])
4895    && REGNO (operands[0]) != REGNO (operands[2])
4896    && (satisfies_constraint_J (operands[1])
4897        || satisfies_constraint_L (operands[1])
4898        || satisfies_constraint_N (operands[1]))"
4899   [(set (match_dup 0)
4900         (match_dup 2))
4901    (set (match_dup 0)
4902         (plus:HI (match_dup 0)
4903                  (match_dup 1)))]
4904   "")
4906 ;; Turn
4908 ;;   sub.l  er0,er0
4909 ;;   add.b  #4,r0l
4910 ;;   add.l  er7,er0  (6 bytes)
4912 ;; into
4914 ;;   mov.l  er7,er0
4915 ;;   adds   #4,er0   (4 bytes)
4917 (define_peephole2
4918   [(set (match_operand:SI 0 "register_operand" "")
4919         (match_operand:SI 1 "const_int_operand" ""))
4920    (set (match_dup 0)
4921         (plus:SI (match_dup 0)
4922                  (match_operand:SI 2 "register_operand" "")))]
4923   "(TARGET_H8300H || TARGET_H8300S)
4924     && REG_P (operands[0]) && REG_P (operands[2])
4925     && REGNO (operands[0]) != REGNO (operands[2])
4926     && (satisfies_constraint_L (operands[1])
4927         || satisfies_constraint_N (operands[1]))"
4928   [(set (match_dup 0)
4929         (match_dup 2))
4930    (set (match_dup 0)
4931         (plus:SI (match_dup 0)
4932                  (match_dup 1)))]
4933   "")
4935 ;; Turn
4937 ;;   mov.l er7,er0
4938 ;;   add.l #10,er0  (takes 8 bytes)
4940 ;; into
4942 ;;   sub.l er0,er0
4943 ;;   add.b #10,r0l
4944 ;;   add.l er7,er0  (takes 6 bytes)
4946 (define_peephole2
4947   [(set (match_operand:SI 0 "register_operand" "")
4948         (match_operand:SI 1 "register_operand" ""))
4949    (set (match_dup 0)
4950         (plus:SI (match_dup 0)
4951                  (match_operand:SI 2 "const_int_operand" "")))]
4952   "(TARGET_H8300H || TARGET_H8300S)
4953     && REG_P (operands[0]) && REG_P (operands[1])
4954     && REGNO (operands[0]) != REGNO (operands[1])
4955     && !satisfies_constraint_L (operands[2])
4956     && !satisfies_constraint_N (operands[2])
4957     && ((INTVAL (operands[2]) & 0xff) == INTVAL (operands[2])
4958         || (INTVAL (operands[2]) & 0xff00) == INTVAL (operands[2])
4959         || INTVAL (operands[2]) == 0xffff
4960         || INTVAL (operands[2]) == 0xfffe)"
4961   [(set (match_dup 0)
4962         (match_dup 2))
4963    (set (match_dup 0)
4964         (plus:SI (match_dup 0)
4965                  (match_dup 1)))]
4966   "")
4968 ;; Turn
4970 ;;   subs   #1,er4
4971 ;;   mov.w  r4,r4
4972 ;;   bne    .L2028
4974 ;; into
4976 ;;   dec.w  #1,r4
4977 ;;   bne    .L2028
4979 (define_peephole2
4980   [(set (match_operand:HI 0 "register_operand" "")
4981         (plus:HI (match_dup 0)
4982                  (match_operand 1 "incdec_operand" "")))
4983    (set (cc0) (compare (match_dup 0)
4984                        (const_int 0)))
4985    (set (pc)
4986         (if_then_else (match_operator 3 "eqne_operator"
4987                        [(cc0) (const_int 0)])
4988                       (label_ref (match_operand 2 "" ""))
4989                       (pc)))]
4990   "TARGET_H8300H || TARGET_H8300S"
4991   [(set (match_operand:HI 0 "register_operand" "")
4992         (unspec:HI [(match_dup 0)
4993                     (match_dup 1)]
4994                    UNSPEC_INCDEC))
4995    (set (cc0) (compare (match_dup 0)
4996                        (const_int 0)))
4997    (set (pc)
4998         (if_then_else (match_op_dup 3 [(cc0) (const_int 0)])
4999                       (label_ref (match_dup 2))
5000                       (pc)))]
5001   "")
5003 ;; The SImode version of the previous pattern.
5005 (define_peephole2
5006   [(set (match_operand:SI 0 "register_operand" "")
5007         (plus:SI (match_dup 0)
5008                  (match_operand 1 "incdec_operand" "")))
5009    (set (cc0) (compare (match_dup 0)
5010                        (const_int 0)))
5011    (set (pc)
5012         (if_then_else (match_operator 3 "eqne_operator"
5013                        [(cc0) (const_int 0)])
5014                       (label_ref (match_operand 2 "" ""))
5015                       (pc)))]
5016   "TARGET_H8300H || TARGET_H8300S"
5017   [(set (match_operand:SI 0 "register_operand" "")
5018         (unspec:SI [(match_dup 0)
5019                     (match_dup 1)]
5020                    UNSPEC_INCDEC))
5021    (set (cc0) (compare (match_dup 0)
5022                        (const_int 0)))
5023    (set (pc)
5024         (if_then_else (match_op_dup 3 [(cc0) (const_int 0)])
5025                       (label_ref (match_dup 2))
5026                       (pc)))]
5027   "")
5029 (define_peephole2
5030   [(parallel [(set (cc0)
5031                    (compare (zero_extract:SI (match_operand:QI 0 "register_operand" "")
5032                                              (const_int 1)
5033                                              (const_int 7))
5034                             (const_int 0)))
5035               (clobber (scratch:QI))])
5036    (set (pc)
5037         (if_then_else (match_operator 1 "eqne_operator"
5038                        [(cc0) (const_int 0)])
5039                       (label_ref (match_operand 2 "" ""))
5040                       (pc)))]
5041   "TARGET_H8300H || TARGET_H8300S"
5042   [(set (cc0) (compare (match_dup 0)
5043                        (const_int 0)))
5044    (set (pc)
5045         (if_then_else (match_op_dup 3 [(cc0) (const_int 0)])
5046                       (label_ref (match_dup 2))
5047                       (pc)))]
5048   {
5049     operands[3] = ((GET_CODE (operands[1]) == EQ)
5050                    ? gen_rtx_GE (VOIDmode, cc0_rtx, const0_rtx)
5051                    : gen_rtx_LT (VOIDmode, cc0_rtx, const0_rtx));
5052   })
5054 ;; The next three peephole2's will try to transform
5056 ;;   mov.b A,r0l    (or mov.l A,er0)
5057 ;;   and.l #CST,er0
5059 ;; into
5061 ;;   sub.l er0
5062 ;;   mov.b A,r0l
5063 ;;   and.b #CST,r0l (if CST is not 255)
5065 (define_peephole2
5066   [(set (match_operand:QI 0 "register_operand" "")
5067         (match_operand:QI 1 "general_operand" ""))
5068    (set (match_operand:SI 2 "register_operand" "")
5069         (and:SI (match_dup 2)
5070                 (const_int 255)))]
5071   "(TARGET_H8300H || TARGET_H8300S)
5072     && !reg_overlap_mentioned_p (operands[2], operands[1])
5073     && REGNO (operands[0]) == REGNO (operands[2])"
5074   [(set (match_dup 2)
5075         (const_int 0))
5076    (set (strict_low_part (match_dup 0))
5077         (match_dup 1))]
5078   "")
5080 (define_peephole2
5081   [(set (match_operand:SI 0 "register_operand" "")
5082         (match_operand:SI 1 "general_operand" ""))
5083    (set (match_dup 0)
5084         (and:SI (match_dup 0)
5085                 (const_int 255)))]
5086   "(TARGET_H8300H || TARGET_H8300S)
5087     && !reg_overlap_mentioned_p (operands[0], operands[1])
5088     && !(GET_CODE (operands[1]) == MEM && !offsettable_memref_p (operands[1]))
5089     && !(GET_CODE (operands[1]) == MEM && MEM_VOLATILE_P (operands[1]))"
5090   [(set (match_dup 0)
5091         (const_int 0))
5092    (set (strict_low_part (match_dup 2))
5093         (match_dup 3))]
5094   {
5095     operands[2] = gen_lowpart (QImode, operands[0]);
5096     operands[3] = gen_lowpart (QImode, operands[1]);
5097   })
5099 (define_peephole2
5100   [(set (match_operand 0 "register_operand" "")
5101         (match_operand 1 "general_operand" ""))
5102    (set (match_operand:SI 2 "register_operand" "")
5103         (and:SI (match_dup 2)
5104                 (match_operand:SI 3 "const_int_qi_operand" "")))]
5105   "(TARGET_H8300H || TARGET_H8300S)
5106     && (GET_MODE (operands[0]) == QImode
5107         || GET_MODE (operands[0]) == HImode
5108         || GET_MODE (operands[0]) == SImode)
5109     && GET_MODE (operands[0]) == GET_MODE (operands[1])
5110     && REGNO (operands[0]) == REGNO (operands[2])
5111     && !reg_overlap_mentioned_p (operands[2], operands[1])
5112     && !(GET_MODE (operands[1]) != QImode
5113          && GET_CODE (operands[1]) == MEM
5114          && !offsettable_memref_p (operands[1]))
5115     && !(GET_MODE (operands[1]) != QImode
5116          && GET_CODE (operands[1]) == MEM
5117          && MEM_VOLATILE_P (operands[1]))"
5118   [(set (match_dup 2)
5119         (const_int 0))
5120    (set (strict_low_part (match_dup 4))
5121         (match_dup 5))
5122    (set (match_dup 2)
5123         (and:SI (match_dup 2)
5124                 (match_dup 6)))]
5125   {
5126     operands[4] = gen_lowpart (QImode, operands[0]);
5127     operands[5] = gen_lowpart (QImode, operands[1]);
5128     operands[6] = GEN_INT (~0xff | INTVAL (operands[3]));
5129   })
5131 (define_peephole2
5132   [(set (match_operand:SI 0 "register_operand" "")
5133         (match_operand:SI 1 "register_operand" ""))
5134    (set (match_dup 0)
5135         (and:SI (match_dup 0)
5136                 (const_int 65280)))]
5137   "(TARGET_H8300H || TARGET_H8300S)
5138    && !reg_overlap_mentioned_p (operands[0], operands[1])"
5139   [(set (match_dup 0)
5140         (const_int 0))
5141    (set (zero_extract:SI (match_dup 0)
5142                          (const_int 8)
5143                          (const_int 8))
5144         (lshiftrt:SI (match_dup 1)
5145                      (const_int 8)))]
5146   "")
5148 ;; If a load of mem:SI is followed by an AND that turns off the upper
5149 ;; half, then we can load mem:HI instead.
5151 (define_peephole2
5152   [(set (match_operand:SI 0 "register_operand" "")
5153         (match_operand:SI 1 "memory_operand" ""))
5154    (set (match_dup 0)
5155         (and:SI (match_dup 0)
5156                 (match_operand:SI 2 "const_int_operand" "")))]
5157   "(TARGET_H8300H || TARGET_H8300S)
5158     && !MEM_VOLATILE_P (operands[1])
5159     && offsettable_memref_p (operands[1])
5160     && (INTVAL (operands[2]) & ~0xffff) == 0
5161     && INTVAL (operands[2]) != 255"
5162   [(set (match_dup 3)
5163         (match_dup 4))
5164    (set (match_dup 0)
5165         (and:SI (match_dup 0)
5166                 (match_dup 2)))]
5167   {
5168     operands[3] = gen_lowpart (HImode, operands[0]);
5169     operands[4] = gen_lowpart (HImode, operands[1]);
5170   })
5172 ;; Convert a memory comparison to a move if there is a scratch register.
5174 (define_peephole2
5175   [(match_scratch:QI 1 "r")
5176    (set (cc0)
5177         (compare (match_operand:QI 0 "memory_operand" "")
5178                  (const_int 0)))]
5179   ""
5180   [(set (match_dup 1)
5181         (match_dup 0))
5182    (set (cc0) (compare (match_dup 1)
5183                        (const_int 0)))]
5184   "")
5186 (define_peephole2
5187   [(match_scratch:HI 1 "r")
5188    (set (cc0)
5189         (compare (match_operand:HI 0 "memory_operand" "")
5190                  (const_int 0)))]
5191   "TARGET_H8300H || TARGET_H8300S"
5192   [(set (match_dup 1)
5193         (match_dup 0))
5194    (set (cc0) (compare (match_dup 1)
5195                        (const_int 0)))]
5196   "")
5198 (define_peephole2
5199   [(match_scratch:SI 1 "r")
5200    (set (cc0)
5201         (compare (match_operand:SI 0 "memory_operand" "")
5202                  (const_int 0)))]
5203   "TARGET_H8300H || TARGET_H8300S"
5204   [(set (match_dup 1)
5205         (match_dup 0))
5206    (set (cc0) (compare (match_dup 1)
5207                        (const_int 0)))]
5208   "")
5211 ;; (compare (reg:HI) (const_int)) takes 4 bytes, so we try to achieve
5212 ;; the equivalent with shorter sequences.  Here is the summary.  Cases
5213 ;; are grouped for each define_peephole2.
5215 ;; reg  const_int                   use     insn
5216 ;; --------------------------------------------------------
5217 ;; dead    -2                       eq/ne   inc.l
5218 ;; dead    -1                       eq/ne   inc.l
5219 ;; dead     1                       eq/ne   dec.l
5220 ;; dead     2                       eq/ne   dec.l
5222 ;; dead     1                       ge/lt shar.l
5223 ;; dead     3 (H8S)                 ge/lt shar.l
5225 ;; dead     1                       geu/ltu shar.l
5226 ;; dead     3 (H8S)                 geu/ltu shar.l
5228 ;; ----   255                       ge/lt mov.b
5230 ;; ----   255                       geu/ltu mov.b
5232 ;; Transform
5234 ;;      cmp.w   #1,r0
5235 ;;      bne     .L1
5237 ;; into
5239 ;;      dec.w   #1,r0
5240 ;;      bne     .L1
5242 (define_peephole2
5243   [(set (cc0)
5244         (compare (match_operand:HI 0 "register_operand" "")
5245                  (match_operand:HI 1 "incdec_operand" "")))
5246    (set (pc)
5247         (if_then_else (match_operator 3 "eqne_operator"
5248                        [(cc0) (const_int 0)])
5249                       (label_ref (match_operand 2 "" ""))
5250                       (pc)))]
5251   "(TARGET_H8300H || TARGET_H8300S)
5252     && INTVAL (operands[1]) != 0
5253     && peep2_reg_dead_p (1, operands[0])"
5254   [(set (match_dup 0)
5255         (unspec:HI [(match_dup 0)
5256                     (match_dup 4)]
5257                    UNSPEC_INCDEC))
5258    (set (cc0) (compare (match_dup 0)
5259                        (const_int 0)))
5260    (set (pc)
5261         (if_then_else (match_op_dup 3 [(cc0) (const_int 0)])
5262                       (label_ref (match_dup 2))
5263                       (pc)))]
5264   {
5265     operands[4] = GEN_INT (- INTVAL (operands[1]));
5266   })
5268 ;; Transform
5270 ;;      cmp.w   #1,r0
5271 ;;      bgt     .L1
5273 ;; into
5275 ;;      shar.w  r0
5276 ;;      bgt     .L1
5278 (define_peephole2
5279   [(set (cc0)
5280         (compare (match_operand:HI 0 "register_operand" "")
5281                  (match_operand:HI 1 "const_int_operand" "")))
5282    (set (pc)
5283         (if_then_else (match_operator 2 "gtle_operator"
5284                        [(cc0) (const_int 0)])
5285                       (label_ref (match_operand 3 "" ""))
5286                       (pc)))]
5287   "(TARGET_H8300H || TARGET_H8300S)
5288     && peep2_reg_dead_p (1, operands[0])
5289     && (INTVAL (operands[1]) == 1
5290         || (TARGET_H8300S && INTVAL (operands[1]) == 3))"
5291   [(parallel [(set (match_dup 0)
5292                    (ashiftrt:HI (match_dup 0)
5293                                 (match_dup 4)))
5294               (clobber (scratch:QI))])
5295    (set (cc0) (compare (match_dup 0)
5296                        (const_int 0)))
5297    (set (pc)
5298         (if_then_else (match_dup 2)
5299                       (label_ref (match_dup 3))
5300                       (pc)))]
5301   {
5302     operands[4] = GEN_INT (exact_log2 (INTVAL (operands[1]) + 1));
5303   })
5305 ;; Transform
5307 ;;      cmp.w   #1,r0
5308 ;;      bhi     .L1
5310 ;; into
5312 ;;      shar.w  r0
5313 ;;      bne     .L1
5315 (define_peephole2
5316   [(set (cc0)
5317         (compare (match_operand:HI 0 "register_operand" "")
5318                  (match_operand:HI 1 "const_int_operand" "")))
5319    (set (pc)
5320         (if_then_else (match_operator 2 "gtuleu_operator"
5321                        [(cc0) (const_int 0)])
5322                       (label_ref (match_operand 3 "" ""))
5323                       (pc)))]
5324   "(TARGET_H8300H || TARGET_H8300S)
5325     && peep2_reg_dead_p (1, operands[0])
5326     && (INTVAL (operands[1]) == 1
5327         || (TARGET_H8300S && INTVAL (operands[1]) == 3))"
5328   [(parallel [(set (match_dup 0)
5329                    (ashiftrt:HI (match_dup 0)
5330                                 (match_dup 4)))
5331               (clobber (scratch:QI))])
5332    (set (cc0) (compare (match_dup 0)
5333                        (const_int 0)))
5334    (set (pc)
5335         (if_then_else (match_dup 5)
5336                       (label_ref (match_dup 3))
5337                       (pc)))]
5338   {
5339     operands[4] = GEN_INT (exact_log2 (INTVAL (operands[1]) + 1));
5340     operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[2]) == GTU ? NE : EQ,
5341                                   VOIDmode, cc0_rtx, const0_rtx);
5342   })
5344 ;; Transform
5346 ;;      cmp.w   #255,r0
5347 ;;      bgt     .L1
5349 ;; into
5351 ;;      mov.b   r0h,r0h
5352 ;;      bgt     .L1
5354 (define_peephole2
5355   [(set (cc0)
5356         (compare (match_operand:HI 0 "register_operand" "")
5357                  (const_int 255)))
5358    (set (pc)
5359         (if_then_else (match_operator 1 "gtle_operator"
5360                        [(cc0) (const_int 0)])
5361                       (label_ref (match_operand 2 "" ""))
5362                       (pc)))]
5363   "TARGET_H8300H || TARGET_H8300S"
5364   [(set (cc0) (compare (and:HI (match_dup 0)
5365                                (const_int -256))
5366                        (const_int 0)))
5367    (set (pc)
5368         (if_then_else (match_dup 1)
5369                       (label_ref (match_dup 2))
5370                       (pc)))]
5371   "")
5373 ;; Transform
5375 ;;      cmp.w   #255,r0
5376 ;;      bhi     .L1
5378 ;; into
5380 ;;      mov.b   r0h,r0h
5381 ;;      bne     .L1
5383 (define_peephole2
5384   [(set (cc0)
5385         (compare (match_operand:HI 0 "register_operand" "")
5386                  (const_int 255)))
5387    (set (pc)
5388         (if_then_else (match_operator 1 "gtuleu_operator"
5389                        [(cc0) (const_int 0)])
5390                       (label_ref (match_operand 2 "" ""))
5391                       (pc)))]
5392   "TARGET_H8300H || TARGET_H8300S"
5393   [(set (cc0) (compare (and:HI (match_dup 0)
5394                                (const_int -256))
5395                        (const_int 0)))
5396    (set (pc)
5397         (if_then_else (match_dup 3)
5398                       (label_ref (match_dup 2))
5399                       (pc)))]
5400   {
5401     operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[1]) == GTU ? NE : EQ,
5402                                   VOIDmode, cc0_rtx, const0_rtx);
5403   })
5405 ;; (compare (reg:SI) (const_int)) takes 6 bytes, so we try to achieve
5406 ;; the equivalent with shorter sequences.  Here is the summary.  Cases
5407 ;; are grouped for each define_peephole2.
5409 ;; reg  const_int                   use     insn
5410 ;; --------------------------------------------------------
5411 ;; live    -2                       eq/ne   copy and inc.l
5412 ;; live    -1                       eq/ne   copy and inc.l
5413 ;; live     1                       eq/ne   copy and dec.l
5414 ;; live     2                       eq/ne   copy and dec.l
5416 ;; dead    -2                       eq/ne   inc.l
5417 ;; dead    -1                       eq/ne   inc.l
5418 ;; dead     1                       eq/ne   dec.l
5419 ;; dead     2                       eq/ne   dec.l
5421 ;; dead -131072                     eq/ne   inc.w and test
5422 ;; dead  -65536                     eq/ne   inc.w and test
5423 ;; dead   65536                     eq/ne   dec.w and test
5424 ;; dead  131072                     eq/ne   dec.w and test
5426 ;; dead 0x000000?? except 1 and 2   eq/ne   xor.b and test
5427 ;; dead 0x0000??00                  eq/ne   xor.b and test
5428 ;; dead 0x0000ffff                  eq/ne   not.w and test
5430 ;; dead 0xffffff?? except -1 and -2 eq/ne   xor.b and not.l
5431 ;; dead 0xffff??ff                  eq/ne   xor.b and not.l
5432 ;; dead 0x40000000 (H8S)            eq/ne   rotl.l and dec.l
5433 ;; dead 0x80000000                  eq/ne   rotl.l and dec.l
5435 ;; live     1                       ge/lt copy and shar.l
5436 ;; live     3 (H8S)                 ge/lt copy and shar.l
5438 ;; live     1                       geu/ltu copy and shar.l
5439 ;; live     3 (H8S)                 geu/ltu copy and shar.l
5441 ;; dead     1                       ge/lt shar.l
5442 ;; dead     3 (H8S)                 ge/lt shar.l
5444 ;; dead     1                       geu/ltu shar.l
5445 ;; dead     3 (H8S)                 geu/ltu shar.l
5447 ;; dead     3 (H8/300H)             ge/lt and.b and test
5448 ;; dead     7                       ge/lt and.b and test
5449 ;; dead    15                       ge/lt and.b and test
5450 ;; dead    31                       ge/lt and.b and test
5451 ;; dead    63                       ge/lt and.b and test
5452 ;; dead   127                       ge/lt and.b and test
5453 ;; dead   255                       ge/lt and.b and test
5455 ;; dead     3 (H8/300H)             geu/ltu and.b and test
5456 ;; dead     7                       geu/ltu and.b and test
5457 ;; dead    15                       geu/ltu and.b and test
5458 ;; dead    31                       geu/ltu and.b and test
5459 ;; dead    63                       geu/ltu and.b and test
5460 ;; dead   127                       geu/ltu and.b and test
5461 ;; dead   255                       geu/ltu and.b and test
5463 ;; ---- 65535                       ge/lt mov.w
5465 ;; ---- 65535                       geu/ltu mov.w
5467 ;; Transform
5469 ;;      cmp.l   #1,er0
5470 ;;      beq     .L1
5472 ;; into
5474 ;;      dec.l   #1,er0
5475 ;;      beq     .L1
5477 (define_peephole2
5478   [(set (cc0)
5479         (compare (match_operand:SI 0 "register_operand" "")
5480                  (match_operand:SI 1 "incdec_operand" "")))
5481    (set (pc)
5482         (if_then_else (match_operator 3 "eqne_operator"
5483                        [(cc0) (const_int 0)])
5484                       (label_ref (match_operand 2 "" ""))
5485                       (pc)))]
5486   "(TARGET_H8300H || TARGET_H8300S)
5487     && INTVAL (operands[1]) != 0
5488     && peep2_reg_dead_p (1, operands[0])"
5489   [(set (match_dup 0)
5490         (unspec:SI [(match_dup 0)
5491                     (match_dup 4)]
5492                    UNSPEC_INCDEC))
5493    (set (cc0) (compare (match_dup 0)
5494                        (const_int 0)))
5495    (set (pc)
5496         (if_then_else (match_op_dup 3 [(cc0) (const_int 0)])
5497                       (label_ref (match_dup 2))
5498                       (pc)))]
5499   {
5500     operands[4] = GEN_INT (- INTVAL (operands[1]));
5501   })
5503 ;; Transform
5505 ;;      cmp.l   #65536,er0
5506 ;;      beq     .L1
5508 ;; into
5510 ;;      dec.l   #1,e0
5511 ;;      beq     .L1
5513 (define_peephole2
5514   [(set (cc0)
5515         (compare (match_operand:SI 0 "register_operand" "")
5516                  (match_operand:SI 1 "const_int_operand" "")))
5517    (set (pc)
5518         (if_then_else (match_operator 3 "eqne_operator"
5519                        [(cc0) (const_int 0)])
5520                       (label_ref (match_operand 2 "" ""))
5521                       (pc)))]
5522   "(TARGET_H8300H || TARGET_H8300S)
5523     && peep2_reg_dead_p (1, operands[0])
5524     && (INTVAL (operands[1]) == -131072
5525         || INTVAL (operands[1]) == -65536
5526         || INTVAL (operands[1]) == 65536
5527         || INTVAL (operands[1]) == 131072)"
5528   [(set (match_dup 0)
5529         (plus:SI (match_dup 0)
5530                  (match_dup 4)))
5531    (set (cc0) (compare (match_dup 0)
5532                        (const_int 0)))
5533    (set (pc)
5534         (if_then_else (match_op_dup 3 [(cc0) (const_int 0)])
5535                       (label_ref (match_dup 2))
5536                       (pc)))]
5537   {
5538     operands[4] = GEN_INT (- INTVAL (operands[1]));
5539   })
5541 ;; Transform
5543 ;;      cmp.l   #100,er0
5544 ;;      beq     .L1
5546 ;; into
5548 ;;      xor.b   #100,er0
5549 ;;      mov.l   er0,er0
5550 ;;      beq     .L1
5552 (define_peephole2
5553   [(set (cc0)
5554         (compare (match_operand:SI 0 "register_operand" "")
5555                  (match_operand:SI 1 "const_int_operand" "")))
5556    (set (pc)
5557         (if_then_else (match_operator 3 "eqne_operator"
5558                        [(cc0) (const_int 0)])
5559                       (label_ref (match_operand 2 "" ""))
5560                       (pc)))]
5561   "(TARGET_H8300H || TARGET_H8300S)
5562     && peep2_reg_dead_p (1, operands[0])
5563     && ((INTVAL (operands[1]) & 0x00ff) == INTVAL (operands[1])
5564         || (INTVAL (operands[1]) & 0xff00) == INTVAL (operands[1])
5565         || INTVAL (operands[1]) == 0x0000ffff)
5566     && INTVAL (operands[1]) != 0
5567     && INTVAL (operands[1]) != 1
5568     && INTVAL (operands[1]) != 2"
5569   [(set (match_dup 0)
5570         (xor:SI (match_dup 0)
5571                 (match_dup 1)))
5572    (set (cc0) (compare (match_dup 0)
5573                        (const_int 0)))
5574    (set (pc)
5575         (if_then_else (match_op_dup 3 [(cc0) (const_int 0)])
5576                       (label_ref (match_dup 2))
5577                       (pc)))]
5578   "")
5580 ;; Transform
5582 ;;      cmp.l   #-100,er0
5583 ;;      beq     .L1
5585 ;; into
5587 ;;      xor.b   #99,er0
5588 ;;      not.l   er0
5589 ;;      beq     .L1
5591 (define_peephole2
5592   [(set (cc0)
5593         (compare (match_operand:SI 0 "register_operand" "")
5594                  (match_operand:SI 1 "const_int_operand" "")))
5595    (set (pc)
5596         (if_then_else (match_operator 3 "eqne_operator"
5597                        [(cc0) (const_int 0)])
5598                       (label_ref (match_operand 2 "" ""))
5599                       (pc)))]
5600   "(TARGET_H8300H || TARGET_H8300S)
5601     && peep2_reg_dead_p (1, operands[0])
5602     && ((INTVAL (operands[1]) | 0x00ff) == -1
5603         || (INTVAL (operands[1]) | 0xff00) == -1)
5604     && INTVAL (operands[1]) != -1
5605     && INTVAL (operands[1]) != -2"
5606   [(set (match_dup 0)
5607         (xor:SI (match_dup 0)
5608                 (match_dup 4)))
5609    (set (match_dup 0)
5610         (not:SI (match_dup 0)))
5611    (set (cc0) (compare (match_dup 0)
5612                        (const_int 0)))
5613    (set (pc)
5614         (if_then_else (match_op_dup 3 [(cc0) (const_int 0)])
5615                       (label_ref (match_dup 2))
5616                       (pc)))]
5617   {
5618     operands[4] = GEN_INT (INTVAL (operands[1]) ^ -1);
5619   })
5621 ;; Transform
5623 ;;      cmp.l   #-2147483648,er0
5624 ;;      beq     .L1
5626 ;; into
5628 ;;      rotl.l  er0
5629 ;;      dec.l   #1,er0
5630 ;;      beq     .L1
5632 (define_peephole2
5633   [(set (cc0)
5634         (compare (match_operand:SI 0 "register_operand" "")
5635                  (match_operand:SI 1 "const_int_operand" "")))
5636    (set (pc)
5637         (if_then_else (match_operator 3 "eqne_operator"
5638                        [(cc0) (const_int 0)])
5639                       (label_ref (match_operand 2 "" ""))
5640                       (pc)))]
5641   "(TARGET_H8300H || TARGET_H8300S)
5642     && peep2_reg_dead_p (1, operands[0])
5643     && (INTVAL (operands[1]) == -2147483647 - 1
5644         || (TARGET_H8300S && INTVAL (operands[1]) == 1073741824))"
5645   [(set (match_dup 0)
5646         (rotate:SI (match_dup 0)
5647                    (match_dup 4)))
5648    (set (match_dup 0)
5649         (unspec:SI [(match_dup 0)
5650                     (const_int -1)]
5651                    UNSPEC_INCDEC))
5652    (set (cc0) (compare (match_dup 0)
5653                        (const_int 0)))
5654    (set (pc)
5655         (if_then_else (match_op_dup 3 [(cc0) (const_int 0)])
5656                       (label_ref (match_dup 2))
5657                       (pc)))]
5658   {
5659     operands[4] = GEN_INT (INTVAL (operands[1]) == -2147483647 - 1 ? 1 : 2);
5660   })
5662 ;; Transform
5664 ;;      cmp.l   #1,er0
5665 ;;      bgt     .L1
5667 ;; into
5669 ;;      mov.l   er0,er1
5670 ;;      shar.l  er1
5671 ;;      bgt     .L1
5673 ;; We avoid this transformation if we see more than one copy of the
5674 ;; same compare insn immediately before this one.
5676 (define_peephole2
5677   [(match_scratch:SI 4 "r")
5678    (set (cc0)
5679         (compare (match_operand:SI 0 "register_operand" "")
5680                  (match_operand:SI 1 "const_int_operand" "")))
5681    (set (pc)
5682         (if_then_else (match_operator 2 "gtle_operator"
5683                        [(cc0) (const_int 0)])
5684                       (label_ref (match_operand 3 "" ""))
5685                       (pc)))]
5686   "(TARGET_H8300H || TARGET_H8300S)
5687     && !peep2_reg_dead_p (1, operands[0])
5688     && (INTVAL (operands[1]) == 1
5689         || (TARGET_H8300S && INTVAL (operands[1]) == 3))
5690     && !same_cmp_preceding_p (insn)"
5691   [(set (match_dup 4)
5692         (match_dup 0))
5693    (parallel [(set (match_dup 4)
5694                    (ashiftrt:SI (match_dup 4)
5695                                 (match_dup 5)))
5696               (clobber (scratch:QI))])
5697    (set (cc0) (compare (match_dup 4)
5698                        (const_int 0)))
5699    (set (pc)
5700         (if_then_else (match_dup 2)
5701                       (label_ref (match_dup 3))
5702                       (pc)))]
5703   {
5704     operands[5] = GEN_INT (exact_log2 (INTVAL (operands[1]) + 1));
5705   })
5707 ;; Transform
5709 ;;      cmp.l   #1,er0
5710 ;;      bhi     .L1
5712 ;; into
5714 ;;      mov.l   er0,er1
5715 ;;      shar.l  er1
5716 ;;      bne     .L1
5718 ;; We avoid this transformation if we see more than one copy of the
5719 ;; same compare insn immediately before this one.
5721 (define_peephole2
5722   [(match_scratch:SI 4 "r")
5723    (set (cc0)
5724         (compare (match_operand:SI 0 "register_operand" "")
5725                  (match_operand:SI 1 "const_int_operand" "")))
5726    (set (pc)
5727         (if_then_else (match_operator 2 "gtuleu_operator"
5728                          [(cc0) (const_int 0)])
5729                       (label_ref (match_operand 3 "" ""))
5730                       (pc)))]
5731   "(TARGET_H8300H || TARGET_H8300S)
5732     && !peep2_reg_dead_p (1, operands[0])
5733     && (INTVAL (operands[1]) == 1
5734         || (TARGET_H8300S && INTVAL (operands[1]) == 3))
5735     && !same_cmp_preceding_p (insn)"
5736   [(set (match_dup 4)
5737         (match_dup 0))
5738    (parallel [(set (match_dup 4)
5739                    (ashiftrt:SI (match_dup 4)
5740                                 (match_dup 5)))
5741               (clobber (scratch:QI))])
5742    (set (cc0) (compare (match_dup 4)
5743                        (const_int 0)))
5744    (set (pc)
5745         (if_then_else (match_dup 6)
5746                       (label_ref (match_dup 3))
5747                       (pc)))]
5748   {
5749     operands[5] = GEN_INT (exact_log2 (INTVAL (operands[1]) + 1));
5750     operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[2]) == GTU ? NE : EQ,
5751                                   VOIDmode, cc0_rtx, const0_rtx);
5752   })
5754 ;; Transform
5756 ;;      cmp.l   #1,er0
5757 ;;      bgt     .L1
5759 ;; into
5761 ;;      shar.l  er0
5762 ;;      bgt     .L1
5764 (define_peephole2
5765   [(set (cc0)
5766         (compare (match_operand:SI 0 "register_operand" "")
5767                  (match_operand:SI 1 "const_int_operand" "")))
5768    (set (pc)
5769         (if_then_else (match_operator 2 "gtle_operator"
5770                        [(cc0) (const_int 0)])
5771                       (label_ref (match_operand 3 "" ""))
5772                       (pc)))]
5773   "(TARGET_H8300H || TARGET_H8300S)
5774     && peep2_reg_dead_p (1, operands[0])
5775     && (INTVAL (operands[1]) == 1
5776         || (TARGET_H8300S && INTVAL (operands[1]) == 3))"
5777   [(parallel [(set (match_dup 0)
5778                    (ashiftrt:SI (match_dup 0)
5779                                 (match_dup 4)))
5780               (clobber (scratch:QI))])
5781    (set (cc0) (compare (match_dup 0)
5782                        (const_int 0)))
5783    (set (pc)
5784         (if_then_else (match_dup 2)
5785                       (label_ref (match_dup 3))
5786                       (pc)))]
5787   {
5788     operands[4] = GEN_INT (exact_log2 (INTVAL (operands[1]) + 1));
5789   })
5791 ;; Transform
5793 ;;      cmp.l   #1,er0
5794 ;;      bhi     .L1
5796 ;; into
5798 ;;      shar.l  er0
5799 ;;      bne     .L1
5801 (define_peephole2
5802   [(set (cc0)
5803         (compare (match_operand:SI 0 "register_operand" "")
5804                  (match_operand:SI 1 "const_int_operand" "")))
5805    (set (pc)
5806         (if_then_else (match_operator 2 "gtuleu_operator"
5807                        [(cc0) (const_int 0)])
5808                       (label_ref (match_operand 3 "" ""))
5809                       (pc)))]
5810   "(TARGET_H8300H || TARGET_H8300S)
5811     && peep2_reg_dead_p (1, operands[0])
5812     && (INTVAL (operands[1]) == 1
5813         || (TARGET_H8300S && INTVAL (operands[1]) == 3))"
5814   [(parallel [(set (match_dup 0)
5815                    (ashiftrt:SI (match_dup 0)
5816                                 (match_dup 4)))
5817               (clobber (scratch:QI))])
5818    (set (cc0) (compare (match_dup 0)
5819                        (const_int 0)))
5820    (set (pc)
5821         (if_then_else (match_dup 5)
5822                       (label_ref (match_dup 3))
5823                       (pc)))]
5824   {
5825     operands[4] = GEN_INT (exact_log2 (INTVAL (operands[1]) + 1));
5826     operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[2]) == GTU ? NE : EQ,
5827                                   VOIDmode, cc0_rtx, const0_rtx);
5828   })
5830 ;; Transform
5832 ;;      cmp.l   #15,er0
5833 ;;      bgt     .L1
5835 ;; into
5837 ;;      and     #240,r0l
5838 ;;      mov.l   er0,er0
5839 ;;      bgt     .L1
5841 (define_peephole2
5842   [(set (cc0)
5843         (compare (match_operand:SI 0 "register_operand" "")
5844                  (match_operand:SI 1 "const_int_operand" "")))
5845    (set (pc)
5846         (if_then_else (match_operator 2 "gtle_operator"
5847                        [(cc0) (const_int 0)])
5848                       (label_ref (match_operand 3 "" ""))
5849                       (pc)))]
5850   "(TARGET_H8300H || TARGET_H8300S)
5851     && peep2_reg_dead_p (1, operands[0])
5852     && ((TARGET_H8300H && INTVAL (operands[1]) == 3)
5853          || INTVAL (operands[1]) == 7
5854          || INTVAL (operands[1]) == 15
5855          || INTVAL (operands[1]) == 31
5856          || INTVAL (operands[1]) == 63
5857          || INTVAL (operands[1]) == 127
5858          || INTVAL (operands[1]) == 255)"
5859   [(set (match_dup 0)
5860         (and:SI (match_dup 0)
5861                 (match_dup 4)))
5862    (set (cc0) (compare (match_dup 0)
5863                        (const_int 0)))
5864    (set (pc)
5865         (if_then_else (match_dup 2)
5866                       (label_ref (match_dup 3))
5867                       (pc)))]
5868   {
5869     operands[4] = GEN_INT (~INTVAL (operands[1]));
5870   })
5872 ;; Transform
5874 ;;      cmp.l   #15,er0
5875 ;;      bhi     .L1
5877 ;; into
5879 ;;      and     #240,r0l
5880 ;;      mov.l   er0,er0
5881 ;;      bne     .L1
5883 (define_peephole2
5884   [(set (cc0)
5885         (compare (match_operand:SI 0 "register_operand" "")
5886                  (match_operand:SI 1 "const_int_operand" "")))
5887    (set (pc)
5888         (if_then_else (match_operator 2 "gtuleu_operator"
5889                        [(cc0) (const_int 0)])
5890                       (label_ref (match_operand 3 "" ""))
5891                       (pc)))]
5892   "(TARGET_H8300H || TARGET_H8300S)
5893     && peep2_reg_dead_p (1, operands[0])
5894     && ((TARGET_H8300H && INTVAL (operands[1]) == 3)
5895          || INTVAL (operands[1]) == 7
5896          || INTVAL (operands[1]) == 15
5897          || INTVAL (operands[1]) == 31
5898          || INTVAL (operands[1]) == 63
5899          || INTVAL (operands[1]) == 127
5900          || INTVAL (operands[1]) == 255)"
5901   [(set (match_dup 0)
5902         (and:SI (match_dup 0)
5903                 (match_dup 4)))
5904    (set (cc0) (compare (match_dup 0)
5905                        (const_int 0)))
5906    (set (pc)
5907         (if_then_else (match_dup 5)
5908                       (label_ref (match_dup 3))
5909                       (pc)))]
5910   {
5911     operands[4] = GEN_INT (~INTVAL (operands[1]));
5912     operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[2]) == GTU ? NE : EQ,
5913                                   VOIDmode, cc0_rtx, const0_rtx);
5914   })
5916 ;; Transform
5918 ;;      cmp.l   #65535,er0
5919 ;;      bgt     .L1
5921 ;; into
5923 ;;      mov.l   e0,e0
5924 ;;      bgt     .L1
5926 (define_peephole2
5927   [(set (cc0)
5928         (compare (match_operand:SI 0 "register_operand" "")
5929                  (const_int 65535)))
5930    (set (pc)
5931         (if_then_else (match_operator 1 "gtle_operator"
5932                        [(cc0) (const_int 0)])
5933                       (label_ref (match_operand 2 "" ""))
5934                       (pc)))]
5935   "TARGET_H8300H || TARGET_H8300S"
5936   [(set (cc0) (compare (and:SI (match_dup 0)
5937                                (const_int -65536))
5938                        (const_int 0)))
5939    (set (pc)
5940         (if_then_else (match_dup 1)
5941                       (label_ref (match_dup 2))
5942                       (pc)))]
5943   "")
5945 ;; Transform
5947 ;;      cmp.l   #65535,er0
5948 ;;      bhi     .L1
5950 ;; into
5952 ;;      mov.l   e0,e0
5953 ;;      bne     .L1
5955 (define_peephole2
5956   [(set (cc0)
5957         (compare (match_operand:SI 0 "register_operand" "")
5958                  (const_int 65535)))
5959    (set (pc)
5960         (if_then_else (match_operator 1 "gtuleu_operator"
5961                        [(cc0) (const_int 0)])
5962                       (label_ref (match_operand 2 "" ""))
5963                       (pc)))]
5964   "TARGET_H8300H || TARGET_H8300S"
5965   [(set (cc0) (compare (and:SI (match_dup 0)
5966                                (const_int -65536))
5967                        (const_int 0)))
5968    (set (pc)
5969         (if_then_else (match_dup 3)
5970                       (label_ref (match_dup 2))
5971                       (pc)))]
5972   {  
5973     operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[1]) == GTU ? NE : EQ,
5974                                   VOIDmode, cc0_rtx, const0_rtx);
5975   })
5977 ;; Transform
5979 ;;      cmp.l   #1,er0
5980 ;;      beq     .L1
5982 ;; into
5984 ;;      mov.l   er0,er1
5985 ;;      dec.l   #1,er1
5986 ;;      beq     .L1
5988 ;; We avoid this transformation if we see more than one copy of the
5989 ;; same compare insn.
5991 (define_peephole2
5992   [(match_scratch:SI 4 "r")
5993    (set (cc0)
5994         (compare (match_operand:SI 0 "register_operand" "")
5995                  (match_operand:SI 1 "incdec_operand" "")))
5996    (set (pc)
5997         (if_then_else (match_operator 3 "eqne_operator"
5998                        [(cc0) (const_int 0)])
5999                       (label_ref (match_operand 2 "" ""))
6000                       (pc)))]
6001   "(TARGET_H8300H || TARGET_H8300S)
6002     && INTVAL (operands[1]) != 0
6003     && !peep2_reg_dead_p (1, operands[0])
6004     && !same_cmp_following_p (insn)"
6005   [(set (match_dup 4)
6006         (match_dup 0))
6007    (set (match_dup 4)
6008         (unspec:SI [(match_dup 4)
6009                     (match_dup 5)]
6010                    UNSPEC_INCDEC))
6011    (set (cc0) (compare (match_dup 4)
6012                        (const_int 0)))
6013    (set (pc)
6014         (if_then_else (match_op_dup 3 [(cc0) (const_int 0)])
6015                       (label_ref (match_dup 2))
6016                       (pc)))]
6017   {
6018     operands[5] = GEN_INT (- INTVAL (operands[1]));
6019   })
6020 ;; Narrow the mode of testing if possible.
6022 (define_peephole2
6023   [(set (match_operand:HI 0 "register_operand" "")
6024         (and:HI (match_dup 0)
6025                 (match_operand:HI 1 "const_int_qi_operand" "")))
6026    (set (cc0) (compare (match_dup 0)
6027                        (const_int 0)))
6028    (set (pc)
6029         (if_then_else (match_operator 3 "eqne_operator"
6030                        [(cc0) (const_int 0)])
6031                       (label_ref (match_operand 2 "" ""))
6032                       (pc)))]
6033   "peep2_reg_dead_p (2, operands[0])"
6034   [(set (match_dup 4)
6035         (and:QI (match_dup 4)
6036                 (match_dup 5)))
6037    (set (cc0) (compare (match_dup 4)
6038                        (const_int 0)))
6039    (set (pc)
6040         (if_then_else (match_op_dup 3 [(cc0) (const_int 0)])
6041                       (label_ref (match_dup 2))
6042                       (pc)))]
6043   {
6044     operands[4] = gen_rtx_REG (QImode, REGNO (operands[0]));
6045     operands[5] = gen_int_mode (INTVAL (operands[1]), QImode);
6046   })
6048 (define_peephole2
6049   [(set (match_operand:SI 0 "register_operand" "")
6050         (and:SI (match_dup 0)
6051                 (match_operand:SI 1 "const_int_qi_operand" "")))
6052    (set (cc0) (compare (match_dup 0)
6053                        (const_int 0)))
6054    (set (pc)
6055         (if_then_else (match_operator 3 "eqne_operator"
6056                        [(cc0) (const_int 0)])
6057                       (label_ref (match_operand 2 "" ""))
6058                       (pc)))]
6059   "peep2_reg_dead_p (2, operands[0])"
6060   [(set (match_dup 4)
6061         (and:QI (match_dup 4)
6062                 (match_dup 5)))
6063    (set (cc0) (compare (match_dup 4)
6064                        (const_int 0)))
6065    (set (pc)
6066         (if_then_else (match_op_dup 3 [(cc0) (const_int 0)])
6067                       (label_ref (match_dup 2))
6068                       (pc)))]
6069   {
6070     operands[4] = gen_rtx_REG (QImode, REGNO (operands[0]));
6071     operands[5] = gen_int_mode (INTVAL (operands[1]), QImode);
6072   })
6074 (define_peephole2
6075   [(set (match_operand:SI 0 "register_operand" "")
6076         (and:SI (match_dup 0)
6077                 (match_operand:SI 1 "const_int_hi_operand" "")))
6078    (set (cc0) (compare (match_dup 0)
6079                        (const_int 0)))
6080    (set (pc)
6081         (if_then_else (match_operator 3 "eqne_operator"
6082                        [(cc0) (const_int 0)])
6083                       (label_ref (match_operand 2 "" ""))
6084                       (pc)))]
6085   "peep2_reg_dead_p (2, operands[0])"
6086   [(set (match_dup 4)
6087         (and:HI (match_dup 4)
6088                 (match_dup 5)))
6089    (set (cc0) (compare (match_dup 4)
6090                        (const_int 0)))
6091    (set (pc)
6092         (if_then_else (match_op_dup 3 [(cc0) (const_int 0)])
6093                       (label_ref (match_dup 2))
6094                       (pc)))]
6095   {
6096     operands[4] = gen_rtx_REG (HImode, REGNO (operands[0]));
6097     operands[5] = gen_int_mode (INTVAL (operands[1]), HImode);
6098   })
6100 (define_peephole2
6101   [(set (match_operand:SI 0 "register_operand" "")
6102         (and:SI (match_dup 0)
6103                 (match_operand:SI 1 "const_int_qi_operand" "")))
6104    (set (match_dup 0)
6105         (xor:SI (match_dup 0)
6106                 (match_operand:SI 2 "const_int_qi_operand" "")))
6107    (set (cc0) (compare (match_dup 0)
6108                        (const_int 0)))
6109    (set (pc)
6110         (if_then_else (match_operator 4 "eqne_operator"
6111                        [(cc0) (const_int 0)])
6112                       (label_ref (match_operand 3 "" ""))
6113                       (pc)))]
6114   "peep2_reg_dead_p (3, operands[0])
6115    && (~INTVAL (operands[1]) & INTVAL (operands[2])) == 0"
6116   [(set (match_dup 5)
6117         (and:QI (match_dup 5)
6118                 (match_dup 6)))
6119    (set (match_dup 5)
6120         (xor:QI (match_dup 5)
6121                 (match_dup 7)))
6122    (set (cc0) (compare (match_dup 5)
6123                        (const_int 0)))
6124    (set (pc)
6125         (if_then_else (match_op_dup 4 [(cc0) (const_int 0)])
6126                       (label_ref (match_dup 3))
6127                       (pc)))]
6128   {
6129     operands[5] = gen_rtx_REG (QImode, REGNO (operands[0]));
6130     operands[6] = gen_int_mode (INTVAL (operands[1]), QImode);
6131     operands[7] = gen_int_mode (INTVAL (operands[2]), QImode);
6132   })
6134 ;; These triggers right at the end of allocation of locals in the
6135 ;; prologue (and possibly at other places).
6137 ;; stack adjustment of -4, generate one push
6139 ;; before : 6 bytes, 10 clocks
6140 ;; after  : 4 bytes, 10 clocks
6142 (define_peephole2
6143   [(set (reg:SI SP_REG)
6144         (plus:SI (reg:SI SP_REG)
6145                  (const_int -4)))
6146    (set (mem:SI (reg:SI SP_REG))
6147         (match_operand:SI 0 "register_operand" ""))]
6148   "(TARGET_H8300H || TARGET_H8300S) && !TARGET_NORMAL_MODE
6149     && REGNO (operands[0]) != SP_REG"
6150   [(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
6151         (match_dup 0))]
6152   "")
6154 ;; stack adjustment of -12, generate one push
6156 ;; before : 10 bytes, 14 clocks
6157 ;; after  :  8 bytes, 14 clocks
6159 (define_peephole2
6160   [(set (reg:SI SP_REG)
6161         (plus:SI (reg:SI SP_REG)
6162                  (const_int -12)))
6163    (set (mem:SI (reg:SI SP_REG))
6164         (match_operand:SI 0 "register_operand" ""))]
6165   "(TARGET_H8300H || TARGET_H8300S) && !TARGET_NORMAL_MODE
6166     && REGNO (operands[0]) != SP_REG"
6167   [(set (reg:SI SP_REG)
6168         (plus:SI (reg:SI SP_REG)
6169                  (const_int -4)))
6170    (set (reg:SI SP_REG)
6171         (plus:SI (reg:SI SP_REG)
6172                  (const_int -4)))
6173    (set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
6174         (match_dup 0))]
6175   "")
6177 ;; Transform
6179 ;;      mov     dst,reg
6180 ;;      op      src,reg
6181 ;;      mov     reg,dst
6183 ;; into
6185 ;;      op      src,dst
6187 ;; if "reg" dies at the end of the sequence.
6189 (define_peephole2
6190   [(set (match_operand 0 "register_operand" "")
6191         (match_operand 1 "memory_operand" ""))
6192    (set (match_dup 0)
6193         (match_operator 2 "h8sx_binary_memory_operator"
6194          [(match_dup 0)
6195           (match_operand 3 "h8300_src_operand" "")]))
6196    (set (match_operand 4 "memory_operand" "")
6197         (match_dup 0))]
6198   "0 /* Disable because it breaks compiling fp-bit.c.  */
6199    && TARGET_H8300SX
6200    && peep2_reg_dead_p (3, operands[0])
6201    && !reg_overlap_mentioned_p (operands[0], operands[3])
6202    && !reg_overlap_mentioned_p (operands[0], operands[4])
6203    && h8sx_mergeable_memrefs_p (operands[4], operands[1])"
6204   [(set (match_dup 4)
6205         (match_dup 5))]
6206   {
6207     operands[5] = shallow_copy_rtx (operands[2]);
6208     XEXP (operands[5], 0) = operands[1];
6209   })
6211 ;; Transform
6213 ;;      mov     src,reg
6214 ;;      op      reg,dst
6216 ;; into
6218 ;;      op      src,dst
6220 ;; if "reg" dies in the second insn.
6222 (define_peephole2
6223   [(set (match_operand 0 "register_operand" "")
6224         (match_operand 1 "h8300_src_operand" ""))
6225    (set (match_operand 2 "h8300_dst_operand" "")
6226         (match_operator 3 "h8sx_binary_memory_operator"
6227          [(match_operand 4 "h8300_dst_operand" "")
6228           (match_dup 0)]))]
6229   "0 /* Disable because it breaks compiling fp-bit.c.  */
6230    && TARGET_H8300SX
6231    && peep2_reg_dead_p (2, operands[0])
6232    && !reg_overlap_mentioned_p (operands[0], operands[4])"
6233   [(set (match_dup 2)
6234         (match_dup 5))]
6235   {
6236     operands[5] = shallow_copy_rtx (operands[3]);
6237     XEXP (operands[5], 1) = operands[1];
6238   })
6240 ;; Transform
6242 ;;      mov     dst,reg
6243 ;;      op      reg
6244 ;;      mov     reg,dst
6246 ;; into
6248 ;;      op      dst
6250 ;; if "reg" dies at the end of the sequence.
6252 (define_peephole2
6253   [(set (match_operand 0 "register_operand" "")
6254         (match_operand 1 "memory_operand" ""))
6255    (set (match_dup 0)
6256         (match_operator 2 "h8sx_unary_memory_operator"
6257          [(match_dup 0)]))
6258    (set (match_operand 3 "memory_operand" "")
6259         (match_dup 0))]
6260   "TARGET_H8300SX
6261    && peep2_reg_dead_p (3, operands[0])
6262    && !reg_overlap_mentioned_p (operands[0], operands[3])
6263    && h8sx_mergeable_memrefs_p (operands[3], operands[1])"
6264   [(set (match_dup 3)
6265         (match_dup 4))]
6266   {
6267     operands[4] = shallow_copy_rtx (operands[2]);
6268     XEXP (operands[4], 0) = operands[1];
6269   })
6271 ;; Transform
6273 ;;      mov     src1,reg
6274 ;;      cmp     reg,src2
6276 ;; into
6278 ;;      cmp     src1,src2
6280 ;; if "reg" dies in the comparison.
6282 (define_peephole2
6283   [(set (match_operand 0 "register_operand" "")
6284         (match_operand 1 "h8300_dst_operand" ""))
6285    (set (cc0)
6286         (compare (match_dup 0)
6287                  (match_operand 2 "h8300_src_operand" "")))]
6288   "TARGET_H8300SX
6289    && peep2_reg_dead_p (2, operands[0])
6290    && !reg_overlap_mentioned_p (operands[0], operands[2])
6291    && operands[2] != const0_rtx"
6292   [(set (cc0)
6293         (compare (match_dup 1)
6294                  (match_dup 2)))])
6296 ;; Likewise for the second operand.
6298 (define_peephole2
6299   [(set (match_operand 0 "register_operand" "")
6300         (match_operand 1 "h8300_src_operand" ""))
6301    (set (cc0)
6302         (compare (match_operand 2 "h8300_dst_operand" "")
6303                  (match_dup 0)))]
6304   "TARGET_H8300SX
6305    && peep2_reg_dead_p (2, operands[0])
6306    && !reg_overlap_mentioned_p (operands[0], operands[2])"
6307   [(set (cc0)
6308         (compare (match_dup 2)
6309                  (match_dup 1)))])
6311 ;; Combine two moves.
6313 (define_peephole2
6314   [(set (match_operand 0 "register_operand" "")
6315         (match_operand 1 "h8300_src_operand" ""))
6316    (set (match_operand 2 "h8300_dst_operand" "")
6317         (match_dup 0))]
6318   "TARGET_H8300SX
6319    && peep2_reg_dead_p (2, operands[0])
6320    && !reg_overlap_mentioned_p (operands[0], operands[2])"
6321   [(set (match_dup 2)
6322         (match_dup 1))])
6323