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