xref: /netbsd-src/external/gpl3/gcc.old/dist/gcc/config/h8300/h8300.md (revision 867d70fc718005c0918b8b8b2f9d7f2d52d0a0db)
1;; GCC machine description for Renesas H8/300
2;; Copyright (C) 1992-2019 Free Software Foundation, Inc.
3
4;;   Contributed by Steve Chamberlain (sac@cygnus.com),
5;;   Jim Wilson (wilson@cygnus.com), and Doug Evans (dje@cygnus.com).
6
7;; This file is part of GCC.
8
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.
13
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.
18
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/>.
22
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".
26
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.
33
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.
36
37;; Shifts/rotates by small constants should be handled by special
38;; patterns so we get the length and cc status correct.
39
40;; Bitfield operations no longer accept memory operands.  We need
41;; to add variants which operate on memory back to the MD.
42
43;; ??? Implement remaining bit ops available on the h8300
44
45;; ----------------------------------------------------------------------
46;; CONSTANTS
47;; ----------------------------------------------------------------------
48
49(define_constants
50  [(UNSPEC_INCDEC	0)
51   (UNSPEC_MONITOR	1)])
52
53(define_constants
54  [(UNSPEC_MOVMD	100)
55   (UNSPEC_STPCPY	101)])
56
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)])
69
70;; ----------------------------------------------------------------------
71;; ATTRIBUTES
72;; ----------------------------------------------------------------------
73
74(define_attr "cpu" "h8300,h8300h"
75  (const (symbol_ref "cpu_type")))
76
77(define_attr "type" "branch,arith,bitbranch,call"
78  (const_string "arith"))
79
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"))
82
83;; The size of instructions in bytes.
84
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)))
121
122;; Condition code settings.
123;;
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
132
133(define_attr "cc" "none,none_0hit,set_znv,set_zn,compare,clobber"
134  (const_string "clobber"))
135
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.
139
140(define_attr "delay_slot" "none,jump"
141  (const_string "none"))
142
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.
147
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")))
154
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.
158
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)])
164
165;; Provide the maximum length of an assembly instruction in an asm
166;; statement.  The maximum length of 14 bytes is achieved on H8SX.
167
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)))])
174
175(include "predicates.md")
176(include "constraints.md")
177
178;; ----------------------------------------------------------------------
179;; MACRO DEFINITIONS
180;; ----------------------------------------------------------------------
181
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.
184
185(define_mode_iterator P [(HI "Pmode == HImode") (SI "Pmode == SImode")])
186
187(define_mode_iterator QHI [QI HI])
188
189(define_mode_iterator HSI [HI SI])
190
191(define_mode_iterator QHSI [QI HI SI])
192
193(define_mode_iterator QHSIF [QI HI SI SF])
194
195(define_code_iterator shifts [ashift ashiftrt lshiftrt])
196
197(define_code_iterator ors [ior xor])
198
199;; ----------------------------------------------------------------------
200;; MOVE INSTRUCTIONS
201;; ----------------------------------------------------------------------
202
203;; movqi
204
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")])
220
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")])
230
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.
247
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  })
254
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")])
265
266;; movhi
267
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")])
283
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")])
297
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")])
309
310;; movsi
311
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])"
317{
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    }
377}
378  [(set (attr "length")
379	(symbol_ref "compute_mov_length (operands)"))])
380
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])"
386{
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]);
401
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	    }
409
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	    }
415
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";
426
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";
431
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";
436
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";
445}
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")])
449
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")])
465
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")])
476
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.
480
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  })
493
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).
497
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  })
513
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.
516
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")])
533
534;; Split the above instruction if the destination register isn't er6.
535;; We need a sequence like:
536;;
537;;	mov.l	er6,@-er7
538;;	mov.l	<dest>,er6
539;;	movmd.sz
540;;	mov.l	er6,<dest>
541;;	mov.l	@er7+,er6
542;;
543;; where <dest> is the current destination register (operand 4).
544;; The fourth instruction will be deleted if <dest> dies here.
545
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;
560
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  })
567
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.
571
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  })
586
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.
590
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  })
604
605;; See comments above memcpy_internal().
606
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")])
620
621;; Split the above instruction if the destination isn't er6.  This works
622;; in the same way as the movmd splitter.
623
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;
635
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  })
642
643(include "mova.md")
644
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))"
651{
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";
686
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    }
696}
697  [(set (attr "length")
698	(symbol_ref "compute_mov_length (operands)"))])
699
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")])
716
717;; ----------------------------------------------------------------------
718;; PUSH INSTRUCTIONS
719;; ----------------------------------------------------------------------
720
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")])
730
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")])
740
741
742;; ----------------------------------------------------------------------
743;; TEST INSTRUCTIONS
744;; ----------------------------------------------------------------------
745
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")])
756
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")])
781
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")])
793
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  })
818
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")])
830
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")])
858
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")])
873
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")])
883
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")])
892
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")])
902
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")])
911
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")])
920
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"
926{
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      }
939}
940  [(set_attr "length_table" "short_immediate,add")
941   (set_attr "cc" "compare,compare")])
942
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"
948{
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    }
961}
962  [(set_attr "length" "2,*")
963   (set_attr "length_table" "*,add")
964   (set_attr "cc" "compare,compare")])
965
966;; ----------------------------------------------------------------------
967;; ADD INSTRUCTIONS
968;; ----------------------------------------------------------------------
969
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  "")
976
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")])
985
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")])
999
1000;; This splitter is very important to make the stack adjustment
1001;; interrupt-safe.  The combination of add.b and addx is unsafe!
1002;;
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.
1007
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  })
1018
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  "")
1031
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")])
1045
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")])
1061
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")])
1075
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  })
1086
1087
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"
1093{
1094  return output_plussi (operands);
1095}
1096  [(set (attr "length")
1097	(symbol_ref "compute_plussi_length (operands)"))
1098   (set (attr "cc")
1099	(symbol_ref "compute_plussi_cc (operands)"))])
1100
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)"
1106{
1107  return output_plussi (operands);
1108}
1109  [(set (attr "length")
1110	(symbol_ref "compute_plussi_length (operands)"))
1111   (set (attr "cc")
1112	(symbol_ref "compute_plussi_cc (operands)"))])
1113
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  })
1124
1125;; ----------------------------------------------------------------------
1126;; SUBTRACT INSTRUCTIONS
1127;; ----------------------------------------------------------------------
1128
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  })
1138
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")])
1147
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")])
1158
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")])
1173
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")])
1181
1182
1183;; ----------------------------------------------------------------------
1184;; MULTIPLY INSTRUCTIONS
1185;; ----------------------------------------------------------------------
1186
1187;; Note that the H8/300 can only handle umulqihi3.
1188
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  })
1199
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")])
1208
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")])
1217
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  })
1228
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")])
1237
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")])
1246
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  })
1257
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")])
1266
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")])
1275
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  })
1286
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")])
1295
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")])
1304
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.
1308
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")])
1317
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")])
1330
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")])
1343
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.
1348;;
1349;; Unfortunately, if combine doesn't create a MAC instruction, this
1350;; insn must generate reasonably correct code.  Egad.
1351
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")])
1363
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")])
1376
1377;; ----------------------------------------------------------------------
1378;; DIVIDE/MOD INSTRUCTIONS
1379;; ----------------------------------------------------------------------
1380
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")])
1388
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")])
1396
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  ""
1409{
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";
1414}
1415  [(set_attr "length" "4")])
1416
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"
1429{
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";
1434}
1435  [(set_attr "length" "6")])
1436
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"
1449{
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";
1454}
1455  [(set_attr "length" "4")])
1456
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"
1469{
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";
1474}
1475  [(set_attr "length" "6")])
1476
1477;; ----------------------------------------------------------------------
1478;; AND INSTRUCTIONS
1479;; ----------------------------------------------------------------------
1480
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")])
1488
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  })
1510
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")])
1518
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")])
1531
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")])
1543
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  "")
1550
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";
1563
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      }
1574
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      }
1585
1586    gcc_unreachable ();
1587
1588  }
1589  [(set_attr "length" "6")])
1590
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")])
1600
1601;; ----------------------------------------------------------------------
1602;; OR/XOR INSTRUCTIONS
1603;; ----------------------------------------------------------------------
1604
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")])
1612
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")])
1620
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    gcc_unreachable ();
1633  }
1634  [(set_attr "length" "8,*")
1635   (set_attr "length_table" "*,logicb")
1636   (set_attr "cc" "none_0hit,set_znv")])
1637
1638(define_expand "<code><mode>3"
1639  [(set (match_operand:QHSI 0 "register_operand" "")
1640	(ors:QHSI (match_operand:QHSI 1 "register_operand" "")
1641		  (match_operand:QHSI 2 "h8300_src_operand" "")))]
1642  ""
1643  "")
1644
1645;; ----------------------------------------------------------------------
1646;; {AND,IOR,XOR}{HI3,SI3} PATTERNS
1647;; ----------------------------------------------------------------------
1648
1649(define_insn "*logical<mode>3"
1650  [(set (match_operand:HSI 0 "h8300_dst_operand" "=rQ")
1651	(match_operator:HSI 3 "bit_operator"
1652	  [(match_operand:HSI 1 "h8300_dst_operand" "%0")
1653	   (match_operand:HSI 2 "h8300_src_operand" "rQi")]))]
1654  "h8300_operands_match_p (operands)"
1655  { return output_logical_op (<MODE>mode, operands); }
1656  [(set (attr "length")
1657	(symbol_ref "compute_logical_op_length (<MODE>mode, operands)"))
1658   (set (attr "cc")
1659	(symbol_ref "compute_logical_op_cc (<MODE>mode, operands)"))])
1660
1661;; ----------------------------------------------------------------------
1662;; NEGATION INSTRUCTIONS
1663;; ----------------------------------------------------------------------
1664
1665(define_expand "neg<mode>2"
1666  [(set (match_operand:QHSIF 0 "register_operand" "")
1667	(neg:QHSIF (match_operand:QHSIF 1 "register_operand" "")))]
1668  ""
1669  {
1670    enum machine_mode mode = <MODE>mode;
1671    if (TARGET_H8300)
1672      {
1673	if (mode == QImode || mode == SFmode)
1674	  ;
1675	else if (mode == HImode)
1676	  {
1677	    emit_insn (gen_neghi2_h8300 (operands[0], operands[1]));
1678	    DONE;
1679	  }
1680	else if (mode == SImode)
1681	  {
1682	    emit_insn (gen_negsi2_h8300 (operands[0], operands[1]));
1683	    DONE;
1684	  }
1685      }
1686  })
1687
1688(define_insn "*negqi2"
1689  [(set (match_operand:QI 0 "h8300_dst_operand" "=rQ")
1690	(neg:QI (match_operand:QI 1 "h8300_dst_operand" "0")))]
1691  ""
1692  "neg	%X0"
1693  [(set_attr "length_table" "unary")
1694   (set_attr "cc" "set_zn")])
1695
1696(define_expand "neg<mode>2_h8300"
1697  [(set (match_dup 2)
1698	(not:HSI (match_operand:HSI 1 "register_operand" "")))
1699   (set (match_dup 2) (plus:HSI (match_dup 2) (const_int 1)))
1700   (set (match_operand:HSI 0 "register_operand" "")
1701	(match_dup 2))]
1702  ""
1703  {
1704    operands[2] = gen_reg_rtx (<MODE>mode);
1705  })
1706
1707(define_insn "*neghi2_h8300hs"
1708  [(set (match_operand:HI 0 "h8300_dst_operand" "=rQ")
1709	(neg:HI (match_operand:HI 1 "h8300_dst_operand" "0")))]
1710  "(TARGET_H8300H || TARGET_H8300S) && h8300_operands_match_p (operands)"
1711  "neg.w	%T0"
1712  [(set_attr "length_table" "unary")
1713   (set_attr "cc" "set_zn")])
1714
1715(define_insn "*negsi2_h8300hs"
1716  [(set (match_operand:SI 0 "h8300_dst_operand" "=rQ")
1717	(neg:SI (match_operand:SI 1 "h8300_dst_operand" "0")))]
1718  "(TARGET_H8300H || TARGET_H8300S) && h8300_operands_match_p (operands)"
1719  "neg.l	%S0"
1720  [(set_attr "length_table" "unary")
1721   (set_attr "cc" "set_zn")])
1722
1723(define_insn "*negsf2_h8300"
1724  [(set (match_operand:SF 0 "register_operand" "=r")
1725	(neg:SF (match_operand:SF 1 "register_operand" "0")))]
1726  "TARGET_H8300"
1727  "xor.b\\t#128,%z0"
1728  [(set_attr "length" "2")])
1729
1730(define_insn "*negsf2_h8300hs"
1731  [(set (match_operand:SF 0 "register_operand" "=r")
1732	(neg:SF (match_operand:SF 1 "register_operand" "0")))]
1733  "TARGET_H8300H || TARGET_H8300S"
1734  "xor.w\\t#32768,%e0"
1735  [(set_attr "length" "4")])
1736
1737;; ----------------------------------------------------------------------
1738;; ABSOLUTE VALUE INSTRUCTIONS
1739;; ----------------------------------------------------------------------
1740
1741(define_expand "abssf2"
1742  [(set (match_operand:SF 0 "register_operand" "")
1743	(abs:SF (match_operand:SF 1 "register_operand" "")))]
1744  ""
1745  "")
1746
1747(define_insn "*abssf2_h8300"
1748  [(set (match_operand:SF 0 "register_operand" "=r")
1749	(abs:SF (match_operand:SF 1 "register_operand" "0")))]
1750  "TARGET_H8300"
1751  "and.b\\t#127,%z0"
1752  [(set_attr "length" "2")])
1753
1754(define_insn "*abssf2_h8300hs"
1755  [(set (match_operand:SF 0 "register_operand" "=r")
1756	(abs:SF (match_operand:SF 1 "register_operand" "0")))]
1757  "TARGET_H8300H || TARGET_H8300S"
1758  "and.w\\t#32767,%e0"
1759  [(set_attr "length" "4")])
1760
1761;; ----------------------------------------------------------------------
1762;; NOT INSTRUCTIONS
1763;; ----------------------------------------------------------------------
1764
1765(define_expand "one_cmpl<mode>2"
1766  [(set (match_operand:QHSI 0 "register_operand" "")
1767	(not:QHSI (match_operand:QHSI 1 "register_operand" "")))]
1768  ""
1769  "")
1770
1771(define_insn "*one_cmplqi2"
1772  [(set (match_operand:QI 0 "h8300_dst_operand" "=rQ")
1773	(not:QI (match_operand:QI 1 "h8300_dst_operand" "0")))]
1774  ""
1775  "not	%X0"
1776  [(set_attr "length_table" "unary")
1777   (set_attr "cc" "set_znv")])
1778
1779(define_insn "*one_cmplhi2_h8300"
1780  [(set (match_operand:HI 0 "register_operand" "=r")
1781	(not:HI (match_operand:HI 1 "register_operand" "0")))]
1782  "TARGET_H8300"
1783  "not	%s0\;not	%t0"
1784  [(set_attr "length" "4")])
1785
1786(define_insn "*one_cmplhi2_h8300hs"
1787  [(set (match_operand:HI 0 "h8300_dst_operand" "=rQ")
1788	(not:HI (match_operand:HI 1 "h8300_dst_operand" "0")))]
1789  "(TARGET_H8300H || TARGET_H8300S) && h8300_operands_match_p (operands)"
1790  "not.w	%T0"
1791  [(set_attr "cc" "set_znv")
1792   (set_attr "length_table" "unary")])
1793
1794(define_insn "*one_cmplsi2_h8300"
1795  [(set (match_operand:SI 0 "register_operand" "=r")
1796	(not:SI (match_operand:SI 1 "register_operand" "0")))]
1797  "TARGET_H8300"
1798  "not	%w0\;not	%x0\;not	%y0\;not	%z0"
1799  [(set_attr "length" "8")])
1800
1801(define_insn "*one_cmplsi2_h8300hs"
1802  [(set (match_operand:SI 0 "h8300_dst_operand" "=rQ")
1803	(not:SI (match_operand:SI 1 "h8300_dst_operand" "0")))]
1804  "(TARGET_H8300H || TARGET_H8300S) && h8300_operands_match_p (operands)"
1805  "not.l	%S0"
1806  [(set_attr "cc" "set_znv")
1807   (set_attr "length_table" "unary")])
1808
1809;; ----------------------------------------------------------------------
1810;; JUMP INSTRUCTIONS
1811;; ----------------------------------------------------------------------
1812
1813;; Conditional jump instructions
1814
1815(define_expand "cbranchqi4"
1816  [(use (match_operator 0 "ordered_comparison_operator"
1817         [(match_operand:QI 1 "h8300_dst_operand" "")
1818          (match_operand:QI 2 "h8300_src_operand" "")]))
1819   (use (match_operand 3 ""))]
1820  ""
1821  {
1822    h8300_expand_branch (operands);
1823    DONE;
1824  })
1825
1826(define_expand "cbranchhi4"
1827  [(use (match_operator 0 "ordered_comparison_operator"
1828         [(match_operand:HI 1 "h8300_dst_operand" "")
1829          (match_operand:HI 2 "h8300_src_operand" "")]))
1830   (use (match_operand 3 ""))]
1831  ""
1832  {
1833    /* Force operand1 into a register if we're compiling
1834       for the H8/300.  */
1835    if ((GET_CODE (operands[2]) != REG && operands[2] != const0_rtx)
1836	&& TARGET_H8300)
1837      operands[2] = force_reg (HImode, operands[2]);
1838    h8300_expand_branch (operands);
1839    DONE;
1840  })
1841
1842(define_expand "cbranchsi4"
1843  [(use (match_operator 0 "ordered_comparison_operator"
1844         [(match_operand:SI 1 "h8300_dst_operand" "")
1845          (match_operand:SI 2 "h8300_src_operand" "")]))
1846   (use (match_operand 3 ""))]
1847  "TARGET_H8300H || TARGET_H8300S"
1848  {
1849    h8300_expand_branch (operands);
1850    DONE;
1851  })
1852
1853(define_insn "branch_true"
1854  [(set (pc)
1855	(if_then_else (match_operator 1 "comparison_operator"
1856		       [(cc0) (const_int 0)])
1857		      (label_ref (match_operand 0 "" ""))
1858		      (pc)))]
1859  ""
1860{
1861  if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0
1862      && (GET_CODE (operands[1]) == GT
1863	  || GET_CODE (operands[1]) == GE
1864	  || GET_CODE (operands[1]) == LE
1865	  || GET_CODE (operands[1]) == LT))
1866    {
1867      cc_status.flags &= ~CC_OVERFLOW_UNUSABLE;
1868      return 0;
1869    }
1870
1871  if (get_attr_length (insn) == 2)
1872    return "b%j1	%l0";
1873  else if (get_attr_length (insn) == 4)
1874    return "b%j1	%l0:16";
1875  else
1876    return "b%k1	.Lh8BR%=\;jmp	@%l0\\n.Lh8BR%=:";
1877}
1878 [(set_attr "type" "branch")
1879   (set_attr "cc" "none")])
1880
1881(define_insn "branch_false"
1882  [(set (pc)
1883	(if_then_else (match_operator 1 "comparison_operator"
1884		       [(cc0) (const_int 0)])
1885		      (pc)
1886		      (label_ref (match_operand 0 "" ""))))]
1887  ""
1888{
1889  if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0
1890      && (GET_CODE (operands[1]) == GT
1891	  || GET_CODE (operands[1]) == GE
1892	  || GET_CODE (operands[1]) == LE
1893	  || GET_CODE (operands[1]) == LT))
1894    {
1895      cc_status.flags &= ~CC_OVERFLOW_UNUSABLE;
1896      return 0;
1897    }
1898
1899  if (get_attr_length (insn) == 2)
1900    return "b%k1	%l0";
1901  else if (get_attr_length (insn) == 4)
1902    return "b%k1	%l0:16";
1903  else
1904    return "b%j1	.Lh8BR%=\;jmp	@%l0\\n.Lh8BR%=:";
1905}
1906  [(set_attr "type" "branch")
1907   (set_attr "cc" "none")])
1908
1909(define_insn "*brabc"
1910  [(set (pc)
1911	(if_then_else (eq (zero_extract (match_operand:QI 1 "bit_memory_operand" "WU")
1912					(const_int 1)
1913					(match_operand:QI 2 "immediate_operand" "n"))
1914			  (const_int 0))
1915		      (label_ref (match_operand 0 "" ""))
1916		      (pc)))]
1917  "TARGET_H8300SX"
1918{
1919  switch (get_attr_length (insn)
1920	  - h8300_insn_length_from_table (insn, operands))
1921    {
1922    case 2:
1923      return "bra/bc	%2,%R1,%l0";
1924    case 4:
1925      return "bra/bc	%2,%R1,%l0:16";
1926    default:
1927      return "bra/bs	%2,%R1,.Lh8BR%=\;jmp	@%l0\\n.Lh8BR%=:";
1928    }
1929}
1930  [(set_attr "type" "bitbranch")
1931   (set_attr "length_table" "bitbranch")
1932   (set_attr "cc" "none")])
1933
1934(define_insn "*brabs"
1935  [(set (pc)
1936	(if_then_else (ne (zero_extract (match_operand:QI 1 "bit_memory_operand" "WU")
1937					(const_int 1)
1938					(match_operand:QI 2 "immediate_operand" "n"))
1939			  (const_int 0))
1940		      (label_ref (match_operand 0 "" ""))
1941		      (pc)))]
1942  "TARGET_H8300SX"
1943{
1944  switch (get_attr_length (insn)
1945	  - h8300_insn_length_from_table (insn, operands))
1946    {
1947    case 2:
1948      return "bra/bs	%2,%R1,%l0";
1949    case 4:
1950      return "bra/bs	%2,%R1,%l0:16";
1951    default:
1952      return "bra/bc	%2,%R1,.Lh8BR%=\;jmp	@%l0\\n.Lh8BR%=:";
1953    }
1954}
1955  [(set_attr "type" "bitbranch")
1956   (set_attr "length_table" "bitbranch")
1957   (set_attr "cc" "none")])
1958
1959;; Unconditional and other jump instructions.
1960
1961(define_insn "jump"
1962  [(set (pc)
1963	(label_ref (match_operand 0 "" "")))]
1964  ""
1965{
1966  if (final_sequence != 0)
1967    {
1968      if (get_attr_length (insn) == 2)
1969	return "bra/s	%l0";
1970      else
1971	{
1972	  /* The branch isn't short enough to use bra/s.  Output the
1973	     branch and delay slot in their normal order.
1974
1975	     If this is a backward branch, it will now be branching two
1976	     bytes further than previously thought.  The length-based
1977	     test for bra vs. jump is very conservative though, so the
1978	     branch will still be within range.  */
1979	  rtx_sequence *seq;
1980	  int seen;
1981
1982	  seq = final_sequence;
1983	  final_sequence = 0;
1984	  final_scan_insn (seq->insn (1), asm_out_file, optimize, 1, & seen);
1985	  final_scan_insn (seq->insn (0), asm_out_file, optimize, 1, & seen);
1986	  seq->insn (1)->set_deleted ();
1987	  return "";
1988	}
1989    }
1990  else if (get_attr_length (insn) == 2)
1991    return "bra	%l0";
1992  else if (get_attr_length (insn) == 4)
1993    return "bra	%l0:16";
1994  else
1995    return "jmp	@%l0";
1996}
1997  [(set_attr "type" "branch")
1998   (set (attr "delay_slot")
1999	(if_then_else (match_test "TARGET_H8300SX")
2000		      (const_string "jump")
2001		      (const_string "none")))
2002   (set_attr "cc" "none")])
2003
2004;; This is a define expand, because pointers may be either 16 or 32 bits.
2005
2006(define_expand "tablejump"
2007  [(parallel [(set (pc) (match_operand 0 "register_operand" ""))
2008	      (use (label_ref (match_operand 1 "" "")))])]
2009  ""
2010  "")
2011
2012(define_insn "*tablejump_h8300"
2013  [(set (pc) (match_operand:HI 0 "register_operand" "r"))
2014   (use (label_ref (match_operand 1 "" "")))]
2015  "TARGET_H8300"
2016  "jmp	@%0"
2017  [(set_attr "cc" "none")
2018   (set_attr "length" "2")])
2019
2020(define_insn "*tablejump_h8300hs_advanced"
2021  [(set (pc) (match_operand:SI 0 "register_operand" "r"))
2022   (use (label_ref (match_operand 1 "" "")))]
2023  "(TARGET_H8300H || TARGET_H8300S) && !TARGET_NORMAL_MODE"
2024  "jmp	@%0"
2025  [(set_attr "cc" "none")
2026   (set_attr "length" "2")])
2027
2028(define_insn "*tablejump_h8300hs_normal"
2029  [(set (pc) (match_operand:HI 0 "register_operand" "r"))
2030   (use (label_ref (match_operand 1 "" "")))]
2031  "(TARGET_H8300H || TARGET_H8300S) && TARGET_NORMAL_MODE"
2032  "jmp @%S0"
2033  [(set_attr "cc" "none")
2034   (set_attr "length" "2")])
2035
2036;; This is a define expand, because pointers may be either 16 or 32 bits.
2037
2038(define_expand "indirect_jump"
2039  [(set (pc) (match_operand 0 "jump_address_operand" ""))]
2040  ""
2041  "")
2042
2043(define_insn "*indirect_jump_h8300"
2044  [(set (pc) (match_operand:HI 0 "jump_address_operand" "Vr"))]
2045  "TARGET_H8300"
2046  "jmp	@%0"
2047  [(set_attr "cc" "none")
2048   (set_attr "length" "2")])
2049
2050(define_insn "*indirect_jump_h8300hs_advanced"
2051  [(set (pc) (match_operand:SI 0 "jump_address_operand" "Vr"))]
2052  "(TARGET_H8300H || TARGET_H8300S) && !TARGET_NORMAL_MODE"
2053  "jmp @%0"
2054  [(set_attr "cc" "none")
2055   (set_attr "length" "2")])
2056
2057(define_insn "*indirect_jump_h8300hs_normal"
2058  [(set (pc) (match_operand:HI 0 "jump_address_operand" "Vr"))]
2059  "(TARGET_H8300H || TARGET_H8300S) && TARGET_NORMAL_MODE"
2060  "jmp @%S0"
2061  [(set_attr "cc" "none")
2062   (set_attr "length" "2")])
2063
2064;; Call subroutine with no return value.
2065
2066;; ??? Even though we use HImode here, this works on the H8/300H and H8S.
2067
2068(define_expand "call"
2069  [(call (match_operand:QI 0 "call_expander_operand" "")
2070	 (match_operand 1 "general_operand" ""))]
2071  ""
2072  {
2073    if (!register_operand (XEXP (operands[0], 0), Pmode)
2074	&& GET_CODE (XEXP (operands[0], 0)) != SYMBOL_REF)
2075      XEXP (operands[0], 0) = force_reg (Pmode, XEXP (operands[0], 0));
2076  })
2077
2078(define_insn "call_insn_<mode>"
2079  [(call (mem:QI (match_operand 0 "call_insn_operand" "Cr"))
2080	         (match_operand:P 1 "general_operand" "g"))]
2081  ""
2082{
2083  rtx xoperands[1];
2084  xoperands[0] = gen_rtx_MEM (QImode, operands[0]);
2085  gcc_assert (GET_MODE (operands[0]) == Pmode);
2086  if (GET_CODE (XEXP (xoperands[0], 0)) == SYMBOL_REF
2087      && (SYMBOL_REF_FLAGS (XEXP (xoperands[0], 0)) & SYMBOL_FLAG_FUNCVEC_FUNCTION))
2088    output_asm_insn ("jsr\\t@%0:8", xoperands);
2089  else
2090    output_asm_insn ("jsr\\t%0", xoperands);
2091  return "";
2092}
2093  [(set_attr "type" "call")
2094   (set (attr "length")
2095	(if_then_else (match_operand:QI 0 "small_call_insn_operand" "")
2096		      (const_int 2)
2097		      (const_int 4)))])
2098
2099;; Call subroutine, returning value in operand 0
2100;; (which must be a hard register).
2101
2102;; ??? Even though we use HImode here, this works on the H8/300H and H8S.
2103
2104(define_expand "call_value"
2105  [(set (match_operand 0 "" "")
2106	(call (match_operand:QI 1 "call_expander_operand" "")
2107	      (match_operand 2 "general_operand" "")))]
2108  ""
2109  {
2110    if (!register_operand (XEXP (operands[1], 0), Pmode)
2111	&& GET_CODE (XEXP (operands[1], 0)) != SYMBOL_REF)
2112      XEXP (operands[1], 0) = force_reg (Pmode, XEXP (operands[1], 0));
2113  })
2114
2115(define_insn "call_value_insn_<mode>"
2116  [(set (match_operand 0 "" "=r")
2117	(call (mem:QI (match_operand 1 "call_insn_operand" "Cr"))
2118		      (match_operand:P 2 "general_operand" "g")))]
2119  ""
2120{
2121  rtx xoperands[2];
2122  gcc_assert (GET_MODE (operands[1]) == Pmode);
2123  xoperands[0] = operands[0];
2124  xoperands[1] = gen_rtx_MEM (QImode, operands[1]);
2125  if (GET_CODE (XEXP (xoperands[1], 0)) == SYMBOL_REF
2126      && (SYMBOL_REF_FLAGS (XEXP (xoperands[1], 0)) & SYMBOL_FLAG_FUNCVEC_FUNCTION))
2127    output_asm_insn ("jsr\\t@%1:8", xoperands);
2128  else
2129    output_asm_insn ("jsr\\t%1", xoperands);
2130  return "";
2131}
2132  [(set_attr "type" "call")
2133   (set (attr "length")
2134	(if_then_else (match_operand:QI 0 "small_call_insn_operand" "")
2135		      (const_int 2)
2136		      (const_int 4)))])
2137
2138(define_insn "nop"
2139  [(const_int 0)]
2140  ""
2141  "nop"
2142  [(set_attr "cc" "none")
2143   (set_attr "length" "2")])
2144
2145;; ----------------------------------------------------------------------
2146;; PROLOGUE/EPILOGUE-RELATED INSTRUCTIONS
2147;; ----------------------------------------------------------------------
2148
2149(define_expand "push_h8300"
2150  [(set (mem:HI (pre_dec:HI (reg:HI SP_REG)))
2151        (match_operand:HI 0 "register_operand" ""))]
2152  "TARGET_H8300"
2153  "")
2154
2155(define_expand "push_h8300hs_advanced"
2156  [(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
2157        (match_operand:SI 0 "register_operand" ""))]
2158  "TARGET_H8300H && TARGET_H8300S && !TARGET_NORMAL_MODE"
2159  "")
2160
2161(define_expand "push_h8300hs_normal"
2162  [(set (mem:SI (pre_dec:HI (reg:HI SP_REG)))
2163        (match_operand:SI 0 "register_operand" ""))]
2164  "TARGET_H8300H && TARGET_H8300S && TARGET_NORMAL_MODE"
2165  "")
2166
2167(define_expand "pop_h8300"
2168  [(set (match_operand:HI 0 "register_operand" "")
2169	(mem:HI (post_inc:HI (reg:HI SP_REG))))]
2170  "TARGET_H8300"
2171  "")
2172
2173(define_expand "pop_h8300hs_advanced"
2174  [(set (match_operand:SI 0 "register_operand" "")
2175	(mem:SI (post_inc:SI (reg:SI SP_REG))))]
2176  "TARGET_H8300H && TARGET_H8300S && !TARGET_NORMAL_MODE"
2177  "")
2178
2179(define_expand "pop_h8300hs_normal"
2180  [(set (match_operand:SI 0 "register_operand" "")
2181	(mem:SI (post_inc:HI (reg:HI SP_REG))))]
2182  "TARGET_H8300H && TARGET_H8300S && TARGET_NORMAL_MODE"
2183  "")
2184
2185(define_insn "ldm_h8300sx"
2186  [(match_parallel           0 "h8300_ldm_parallel"
2187    [(set (match_operand:SI 1 "register_operand" "")
2188	  (match_operand:SI 2 "memory_operand" ""))])]
2189  "TARGET_H8300S"
2190{
2191  operands[3] = SET_DEST (XVECEXP (operands[0], 0,
2192				   XVECLEN (operands[0], 0) - 2));
2193  return "ldm.l\t@er7+,%S1-%S3";
2194}
2195  [(set_attr "cc" "none")
2196   (set_attr "length" "4")])
2197
2198(define_insn "stm_h8300sx"
2199  [(match_parallel           0 "h8300_stm_parallel"
2200    [(set (match_operand:SI 1 "memory_operand" "")
2201	  (match_operand:SI 2 "register_operand" ""))])]
2202  "TARGET_H8300S"
2203{
2204  operands[3] = SET_SRC (XVECEXP (operands[0], 0,
2205				  XVECLEN (operands[0], 0) - 2));
2206  return "stm.l\t%S2-%S3,@-er7";
2207}
2208  [(set_attr "cc" "none")
2209   (set_attr "length" "4")])
2210
2211(define_insn "return_h8sx"
2212  [(match_parallel           0 "h8300_return_parallel"
2213    [(return)
2214     (set (match_operand:SI 1 "register_operand" "")
2215	  (match_operand:SI 2 "memory_operand" ""))])]
2216  "TARGET_H8300SX"
2217{
2218  operands[3] = SET_DEST (XVECEXP (operands[0], 0,
2219				   XVECLEN (operands[0], 0) - 2));
2220  if (h8300_current_function_interrupt_function_p ()
2221      || h8300_current_function_monitor_function_p ())
2222    return "rte/l\t%S1-%S3";
2223  else
2224    return "rts/l\t%S1-%S3";
2225}
2226  [(set_attr "cc" "none")
2227   (set_attr "can_delay" "no")
2228   (set_attr "length" "2")])
2229
2230(define_expand "return"
2231  [(return)]
2232  "h8300_can_use_return_insn_p ()"
2233  "")
2234
2235(define_insn "*return_1"
2236  [(return)]
2237  "reload_completed"
2238{
2239  if (h8300_current_function_interrupt_function_p ()
2240      || h8300_current_function_monitor_function_p ())
2241    return "rte";
2242  else
2243    return "rts";
2244}
2245  [(set_attr "cc" "none")
2246   (set_attr "can_delay" "no")
2247   (set_attr "length" "2")])
2248
2249(define_expand "prologue"
2250  [(const_int 0)]
2251  ""
2252  {
2253    h8300_expand_prologue ();
2254    DONE;
2255  })
2256
2257(define_expand "epilogue"
2258  [(return)]
2259  ""
2260  {
2261    h8300_expand_epilogue ();
2262    DONE;
2263  })
2264
2265(define_insn "monitor_prologue"
2266  [(unspec_volatile [(const_int 0)] UNSPEC_MONITOR)]
2267  ""
2268{
2269  if (TARGET_H8300)
2270    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";
2271  else if (TARGET_H8300H && TARGET_NORMAL_MODE)
2272    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";
2273  else if (TARGET_H8300H)
2274    return "mov.l\\ter0,@-er7\;stc\\tccr,r0l\;mov.b\\tr0l,@(4,er7)\;mov.l\\t@er7+,er0\;orc\\t#128,ccr";
2275  else if (TARGET_H8300S && TARGET_NEXR )
2276    return "mov.l\\ter0,@-er7\;stc\tccr,r0l\;mov.b\tr0l,@(4,er7)\;mov.l\\t@er7+,er0\;orc\t#128,ccr";
2277  else if (TARGET_H8300S && TARGET_NEXR && TARGET_NORMAL_MODE)
2278    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";
2279  else if (TARGET_H8300S && TARGET_NORMAL_MODE)
2280    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";
2281  else if (TARGET_H8300S)
2282    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";
2283  gcc_unreachable ();
2284}
2285  [(set_attr "length" "20")])
2286
2287;; ----------------------------------------------------------------------
2288;; EXTEND INSTRUCTIONS
2289;; ----------------------------------------------------------------------
2290
2291(define_expand "zero_extendqi<mode>2"
2292  [(set (match_operand:HSI 0 "register_operand" "")
2293	(zero_extend:HSI (match_operand:QI 1 "general_operand_src" "")))]
2294  ""
2295  {
2296    if (TARGET_H8300SX)
2297      operands[1] = force_reg (QImode, operands[1]);
2298  })
2299
2300(define_insn "*zero_extendqihi2_h8300"
2301  [(set (match_operand:HI 0 "register_operand" "=r,r")
2302	(zero_extend:HI (match_operand:QI 1 "general_operand_src" "0,g>")))]
2303  "TARGET_H8300"
2304  "@
2305  mov.b	#0,%t0
2306  #"
2307  [(set_attr "length" "2,10")])
2308
2309(define_insn "*zero_extendqihi2_h8300hs"
2310  [(set (match_operand:HI 0 "register_operand" "=r,r")
2311	(zero_extend:HI (match_operand:QI 1 "general_operand_src" "0,g>")))]
2312  "TARGET_H8300H || TARGET_H8300S"
2313  "@
2314  extu.w	%T0
2315  #"
2316  [(set_attr "length" "2,10")
2317   (set_attr "cc" "set_znv,set_znv")])
2318
2319;; Split the zero extension of a general operand (actually a memory
2320;; operand) into a load of the operand and the actual zero extension
2321;; so that 1) the length will be accurate, and 2) the zero extensions
2322;; appearing at the end of basic blocks may be merged.
2323
2324(define_split
2325  [(set (match_operand:HI 0 "register_operand" "")
2326	(zero_extend:HI (match_operand:QI 1 "general_operand_src" "")))]
2327  "reload_completed"
2328  [(set (match_dup 2)
2329	(match_dup 1))
2330   (set (match_dup 0)
2331	(zero_extend:HI (match_dup 2)))]
2332  {
2333    operands[2] = gen_rtx_REG (QImode, REGNO (operands[0]));
2334  })
2335
2336
2337(define_insn "*zero_extendqisi2_h8300"
2338  [(set (match_operand:SI 0 "register_operand" "=r,r")
2339	(zero_extend:SI (match_operand:QI 1 "general_operand_src" "0,g>")))]
2340  "TARGET_H8300"
2341  "@
2342  mov.b	#0,%x0\;sub.w	%e0,%e0
2343  mov.b	%R1,%w0\;mov.b	#0,%x0\;sub.w	%e0,%e0"
2344  [(set_attr "length" "4,8")])
2345
2346(define_insn "*zero_extendqisi2_h8300hs"
2347  [(set (match_operand:SI 0 "register_operand" "=r,r")
2348	(zero_extend:SI (match_operand:QI 1 "general_operand_src" "0,g>")))]
2349  "(TARGET_H8300H || TARGET_H8300S) && !TARGET_H8300SX"
2350  "#")
2351
2352(define_split
2353  [(set (match_operand:SI 0 "register_operand" "")
2354	(zero_extend:SI (match_operand:QI 1 "general_operand_src" "")))]
2355  "(TARGET_H8300H || TARGET_H8300S) && !TARGET_H8300SX
2356    && reg_overlap_mentioned_p (operands[0], operands[1])
2357    && reload_completed"
2358  [(set (match_dup 2)
2359	(match_dup 1))
2360   (set (match_dup 3)
2361	(zero_extend:HI (match_dup 2)))
2362   (set (match_dup 0)
2363	(zero_extend:SI (match_dup 3)))]
2364  {
2365    operands[2] = gen_lowpart (QImode, operands[0]);
2366    operands[3] = gen_lowpart (HImode, operands[0]);
2367  })
2368
2369(define_split
2370  [(set (match_operand:SI 0 "register_operand" "")
2371	(zero_extend:SI (match_operand:QI 1 "general_operand_src" "")))]
2372  "(TARGET_H8300H || TARGET_H8300S) && !TARGET_H8300SX
2373    && !reg_overlap_mentioned_p (operands[0], operands[1])
2374    && reload_completed"
2375  [(set (match_dup 0)
2376	(const_int 0))
2377   (set (strict_low_part (match_dup 2))
2378	(match_dup 1))]
2379  {
2380    operands[2] = gen_rtx_REG (QImode, REGNO (operands[0]));
2381  })
2382
2383(define_insn "*zero_extendqisi2_h8sx"
2384  [(set (match_operand:SI 0 "register_operand" "=r")
2385	(zero_extend:SI (match_operand:QI 1 "register_operand" "0")))]
2386  "TARGET_H8300SX"
2387  "extu.l\t#2,%0"
2388  [(set_attr "length" "2")
2389   (set_attr "cc" "set_znv")])
2390
2391(define_expand "zero_extendhisi2"
2392  [(set (match_operand:SI 0 "register_operand" "")
2393	(zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
2394  ""
2395  "")
2396
2397;; %e prints the high part of a CONST_INT, not the low part.  Arggh.
2398(define_insn "*zero_extendhisi2_h8300"
2399  [(set (match_operand:SI 0 "register_operand" "=r,r,r")
2400	(zero_extend:SI (match_operand:HI 1 "general_operand_src" "0,i,g>")))]
2401  "TARGET_H8300"
2402  "@
2403  sub.w	%e0,%e0
2404  mov.w	%f1,%f0\;sub.w	%e0,%e0
2405  mov.w	%e1,%f0\;sub.w	%e0,%e0"
2406  [(set_attr "length" "2,4,6")])
2407
2408(define_insn "*zero_extendhisi2_h8300hs"
2409  [(set (match_operand:SI 0 "register_operand" "=r")
2410	(zero_extend:SI (match_operand:HI 1 "register_operand" "0")))]
2411  "TARGET_H8300H || TARGET_H8300S"
2412  "extu.l	%S0"
2413  [(set_attr "length" "2")
2414   (set_attr "cc" "set_znv")])
2415
2416(define_expand "extendqi<mode>2"
2417  [(set (match_operand:HSI 0 "register_operand" "")
2418	(sign_extend:HSI (match_operand:QI 1 "register_operand" "")))]
2419  ""
2420  "")
2421
2422(define_insn "*extendqihi2_h8300"
2423  [(set (match_operand:HI 0 "register_operand" "=r,r")
2424	(sign_extend:HI (match_operand:QI 1 "general_operand_src" "0,g>")))]
2425  "TARGET_H8300"
2426  "@
2427  bld	#7,%s0\;subx	%t0,%t0
2428  mov.b	%R1,%s0\;bld	#7,%s0\;subx	%t0,%t0"
2429  [(set_attr "length" "4,8")])
2430
2431(define_insn "*extendqihi2_h8300hs"
2432  [(set (match_operand:HI 0 "register_operand" "=r")
2433	(sign_extend:HI (match_operand:QI 1 "register_operand" "0")))]
2434  "TARGET_H8300H || TARGET_H8300S"
2435  "exts.w	%T0"
2436  [(set_attr "length" "2")
2437   (set_attr "cc" "set_znv")])
2438
2439(define_insn "*extendqisi2_h8300"
2440  [(set (match_operand:SI 0 "register_operand" "=r,r")
2441	(sign_extend:SI (match_operand:QI 1 "general_operand_src" "0,g>")))]
2442  "TARGET_H8300"
2443  "@
2444  bld	#7,%w0\;subx	%x0,%x0\;subx	%y0,%y0\;subx	%z0,%z0
2445  mov.b	%R1,%w0\;bld	#7,%w0\;subx	%x0,%x0\;subx	%y0,%y0\;subx	%z0,%z0"
2446  [(set_attr "length" "8,12")])
2447
2448;; The following pattern is needed because without the pattern, the
2449;; combiner would split (sign_extend:SI (reg:QI)) into two 24-bit
2450;; shifts, one ashift and one ashiftrt.
2451
2452(define_insn_and_split "*extendqisi2_h8300hs"
2453  [(set (match_operand:SI 0 "register_operand" "=r")
2454	(sign_extend:SI (match_operand:QI 1 "register_operand" "0")))]
2455  "(TARGET_H8300H || TARGET_H8300S) && !TARGET_H8300SX"
2456  "#"
2457  "&& reload_completed"
2458  [(set (match_dup 2)
2459	(sign_extend:HI (match_dup 1)))
2460   (set (match_dup 0)
2461	(sign_extend:SI (match_dup 2)))]
2462  {
2463    operands[2] = gen_rtx_REG (HImode, REGNO (operands[0]));
2464  })
2465
2466(define_insn "*extendqisi2_h8sx"
2467  [(set (match_operand:SI 0 "register_operand" "=r")
2468	(sign_extend:SI (match_operand:QI 1 "register_operand" "0")))]
2469  "TARGET_H8300SX"
2470  "exts.l\t#2,%0"
2471  [(set_attr "length" "2")
2472   (set_attr "cc" "set_znv")])
2473
2474(define_expand "extendhisi2"
2475  [(set (match_operand:SI 0 "register_operand" "")
2476	(sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
2477  ""
2478  "")
2479
2480(define_insn "*extendhisi2_h8300"
2481  [(set (match_operand:SI 0 "register_operand" "=r,r")
2482	(sign_extend:SI (match_operand:HI 1 "general_operand_src" "0,g>")))]
2483  "TARGET_H8300"
2484  "@
2485  bld	#7,%x0\;subx	%y0,%y0\;subx	%z0,%z0
2486  mov.w	%T1,%f0\;bld	#7,%x0\;subx	%y0,%y0\;subx	%z0,%z0"
2487  [(set_attr "length" "6,10")])
2488
2489(define_insn "*extendhisi2_h8300hs"
2490  [(set (match_operand:SI 0 "register_operand" "=r")
2491	(sign_extend:SI (match_operand:HI 1 "register_operand" "0")))]
2492  "TARGET_H8300H || TARGET_H8300S"
2493  "exts.l	%S0"
2494  [(set_attr "length" "2")
2495   (set_attr "cc" "set_znv")])
2496
2497;; ----------------------------------------------------------------------
2498;; SHIFTS
2499;; ----------------------------------------------------------------------
2500;;
2501;; We make some attempt to provide real efficient shifting.  One example is
2502;; doing an 8-bit shift of a 16-bit value by moving a byte reg into the other
2503;; reg and moving 0 into the former reg.
2504;;
2505;; We also try to achieve this in a uniform way.  IE: We don't try to achieve
2506;; this in both rtl and at insn emit time.  Ideally, we'd use rtl as that would
2507;; give the optimizer more cracks at the code.  However, we wish to do things
2508;; like optimizing shifting the sign bit to bit 0 by rotating the other way.
2509;; There is rtl to handle this (rotate + and), but the H8/300 doesn't handle
2510;; 16-bit rotates.  Also, if we emit complicated rtl, combine may not be able
2511;; to detect cases it can optimize.
2512;;
2513;; For these and other fuzzy reasons, I've decided to go the less pretty but
2514;; easier "do it at insn emit time" route.
2515
2516;; QI BIT SHIFTS
2517
2518(define_expand "ashlqi3"
2519  [(set (match_operand:QI 0 "register_operand" "")
2520	(ashift:QI (match_operand:QI 1 "register_operand" "")
2521		   (match_operand:QI 2 "nonmemory_operand" "")))]
2522  ""
2523  {
2524    if (expand_a_shift (QImode, ASHIFT, operands))
2525    DONE;
2526  })
2527
2528(define_expand "ashrqi3"
2529  [(set (match_operand:QI 0 "register_operand" "")
2530	(ashiftrt:QI (match_operand:QI 1 "register_operand" "")
2531		     (match_operand:QI 2 "nonmemory_operand" "")))]
2532  ""
2533  {
2534    if (expand_a_shift (QImode, ASHIFTRT, operands))
2535    DONE;
2536  })
2537
2538(define_expand "lshrqi3"
2539  [(set (match_operand:QI 0 "register_operand" "")
2540	(lshiftrt:QI (match_operand:QI 1 "register_operand" "")
2541		     (match_operand:QI 2 "nonmemory_operand" "")))]
2542  ""
2543  {
2544    if (expand_a_shift (QImode, LSHIFTRT, operands))
2545    DONE;
2546  })
2547
2548(define_insn ""
2549  [(set (match_operand:QI 0 "h8300_dst_operand" "=rQ")
2550	(match_operator:QI 3 "h8sx_unary_shift_operator"
2551	 [(match_operand:QI 1 "h8300_dst_operand" "0")
2552	  (match_operand:QI 2 "const_int_operand" "")]))]
2553  "h8300_operands_match_p (operands)"
2554{
2555  return output_h8sx_shift (operands, 'b', 'X');
2556}
2557  [(set_attr "length_table" "unary")
2558   (set_attr "cc" "set_znv")])
2559
2560(define_insn ""
2561  [(set (match_operand:QI 0 "register_operand" "=r")
2562	(match_operator:QI 3 "h8sx_binary_shift_operator"
2563	 [(match_operand:QI 1 "register_operand" "0")
2564	  (match_operand:QI 2 "nonmemory_operand" "r P3>X")]))]
2565  ""
2566{
2567  return output_h8sx_shift (operands, 'b', 'X');
2568}
2569  [(set_attr "length" "4")
2570   (set_attr "cc" "set_znv")])
2571
2572(define_insn "*shiftqi"
2573  [(set (match_operand:QI 0 "register_operand" "=r,r")
2574	(match_operator:QI 3 "nshift_operator"
2575	 [(match_operand:QI 1 "register_operand" "0,0")
2576	  (match_operand:QI 2 "nonmemory_operand" "R,rn")]))
2577   (clobber (match_scratch:QI 4 "=X,&r"))]
2578  ""
2579{
2580  return output_a_shift (operands);
2581}
2582  [(set (attr "length")
2583	(symbol_ref "compute_a_shift_length (insn, operands)"))
2584   (set (attr "cc")
2585	(symbol_ref "compute_a_shift_cc (insn, operands)"))])
2586
2587;; HI BIT SHIFTS
2588
2589(define_expand "ashlhi3"
2590  [(set (match_operand:HI 0 "register_operand" "")
2591	(ashift:HI (match_operand:HI 1 "register_operand" "")
2592		   (match_operand:QI 2 "nonmemory_operand" "")))]
2593  ""
2594  {
2595    if (expand_a_shift (HImode, ASHIFT, operands))
2596    DONE;
2597  })
2598
2599(define_expand "lshrhi3"
2600  [(set (match_operand:HI 0 "register_operand" "")
2601	(lshiftrt:HI (match_operand:HI 1 "register_operand" "")
2602		     (match_operand:QI 2 "nonmemory_operand" "")))]
2603  ""
2604  {
2605    if (expand_a_shift (HImode, LSHIFTRT, operands))
2606    DONE;
2607  })
2608
2609(define_expand "ashrhi3"
2610  [(set (match_operand:HI 0 "register_operand" "")
2611	(ashiftrt:HI (match_operand:HI 1 "register_operand" "")
2612		     (match_operand:QI 2 "nonmemory_operand" "")))]
2613  ""
2614  {
2615    if (expand_a_shift (HImode, ASHIFTRT, operands))
2616    DONE;
2617  })
2618
2619(define_insn ""
2620  [(set (match_operand:HI 0 "h8300_dst_operand" "=rQ")
2621	(match_operator:HI 3 "h8sx_unary_shift_operator"
2622	 [(match_operand:HI 1 "h8300_dst_operand" "0")
2623	  (match_operand:QI 2 "const_int_operand" "")]))]
2624  "h8300_operands_match_p (operands)"
2625{
2626  return output_h8sx_shift (operands, 'w', 'T');
2627}
2628  [(set_attr "length_table" "unary")
2629   (set_attr "cc" "set_znv")])
2630
2631(define_insn ""
2632  [(set (match_operand:HI 0 "register_operand" "=r")
2633	(match_operator:HI 3 "h8sx_binary_shift_operator"
2634	 [(match_operand:HI 1 "register_operand" "0")
2635	  (match_operand:QI 2 "nonmemory_operand" "r P4>X")]))]
2636  ""
2637{
2638  return output_h8sx_shift (operands, 'w', 'T');
2639}
2640  [(set_attr "length" "4")
2641   (set_attr "cc" "set_znv")])
2642
2643(define_insn "*shifthi"
2644  [(set (match_operand:HI 0 "register_operand" "=r,r")
2645	(match_operator:HI 3 "nshift_operator"
2646	 [(match_operand:HI 1 "register_operand" "0,0")
2647	  (match_operand:QI 2 "nonmemory_operand" "S,rn")]))
2648   (clobber (match_scratch:QI 4 "=X,&r"))]
2649  ""
2650{
2651  return output_a_shift (operands);
2652}
2653  [(set (attr "length")
2654	(symbol_ref "compute_a_shift_length (insn, operands)"))
2655   (set (attr "cc")
2656	(symbol_ref "compute_a_shift_cc (insn, operands)"))])
2657
2658;;  SI BIT SHIFTS
2659
2660(define_expand "ashlsi3"
2661  [(set (match_operand:SI 0 "register_operand" "")
2662	(ashift:SI (match_operand:SI 1 "register_operand" "")
2663		   (match_operand:QI 2 "nonmemory_operand" "")))]
2664  ""
2665  {
2666    if (expand_a_shift (SImode, ASHIFT, operands))
2667    DONE;
2668  })
2669
2670(define_expand "lshrsi3"
2671  [(set (match_operand:SI 0 "register_operand" "")
2672	(lshiftrt:SI (match_operand:SI 1 "register_operand" "")
2673		     (match_operand:QI 2 "nonmemory_operand" "")))]
2674  ""
2675  {
2676    if (expand_a_shift (SImode, LSHIFTRT, operands))
2677    DONE;
2678  })
2679
2680(define_expand "ashrsi3"
2681  [(set (match_operand:SI 0 "register_operand" "")
2682	(ashiftrt:SI (match_operand:SI 1 "register_operand" "")
2683		     (match_operand:QI 2 "nonmemory_operand" "")))]
2684  ""
2685  {
2686    if (expand_a_shift (SImode, ASHIFTRT, operands))
2687    DONE;
2688  })
2689
2690(define_insn ""
2691  [(set (match_operand:SI 0 "h8300_dst_operand" "=rQ")
2692	(match_operator:SI 3 "h8sx_unary_shift_operator"
2693	 [(match_operand:SI 1 "h8300_dst_operand" "0")
2694	  (match_operand:QI 2 "const_int_operand" "")]))]
2695  "h8300_operands_match_p (operands)"
2696{
2697  return output_h8sx_shift (operands, 'l', 'S');
2698}
2699  [(set_attr "length_table" "unary")
2700   (set_attr "cc" "set_znv")])
2701
2702(define_insn ""
2703  [(set (match_operand:SI 0 "register_operand" "=r")
2704	(match_operator:SI 3 "h8sx_binary_shift_operator"
2705	 [(match_operand:SI 1 "register_operand" "0")
2706	  (match_operand:QI 2 "nonmemory_operand" "r P5>X")]))]
2707  ""
2708{
2709  return output_h8sx_shift (operands, 'l', 'S');
2710}
2711  [(set_attr "length" "4")
2712   (set_attr "cc" "set_znv")])
2713
2714(define_insn "*shiftsi"
2715  [(set (match_operand:SI 0 "register_operand" "=r,r")
2716	(match_operator:SI 3 "nshift_operator"
2717	 [(match_operand:SI 1 "register_operand" "0,0")
2718	  (match_operand:QI 2 "nonmemory_operand" "T,rn")]))
2719   (clobber (match_scratch:QI 4 "=X,&r"))]
2720  ""
2721{
2722  return output_a_shift (operands);
2723}
2724  [(set (attr "length")
2725	(symbol_ref "compute_a_shift_length (insn, operands)"))
2726   (set (attr "cc")
2727	(symbol_ref "compute_a_shift_cc (insn, operands)"))])
2728
2729;; Split a variable shift into a loop.  If the register containing
2730;; the shift count dies, then we just use that register.
2731
2732(define_split
2733  [(set (match_operand 0 "register_operand" "")
2734	(match_operator 2 "nshift_operator"
2735	 [(match_dup 0)
2736	  (match_operand:QI 1 "register_operand" "")]))
2737   (clobber (match_operand:QI 3 "register_operand" ""))]
2738  "epilogue_completed
2739   && find_regno_note (insn, REG_DEAD, REGNO (operands[1]))"
2740  [(set (cc0) (compare (match_dup 1) (const_int 0)))
2741   (set (pc)
2742        (if_then_else (le (cc0) (const_int 0))
2743		      (label_ref (match_dup 5))
2744		      (pc)))
2745   (match_dup 4)
2746   (parallel
2747     [(set (match_dup 0)
2748	   (match_op_dup 2 [(match_dup 0) (const_int 1)]))
2749      (clobber (scratch:QI))])
2750   (set (match_dup 1) (plus:QI (match_dup 1) (const_int -1)))
2751   (set (cc0) (compare (match_dup 1) (const_int 0)))
2752   (set (pc)
2753        (if_then_else (ne (cc0) (const_int 0))
2754		      (label_ref (match_dup 4))
2755		      (pc)))
2756   (match_dup 5)]
2757  {
2758    operands[4] = gen_label_rtx ();
2759    operands[5] = gen_label_rtx ();
2760  })
2761
2762(define_split
2763  [(set (match_operand 0 "register_operand" "")
2764	(match_operator 2 "nshift_operator"
2765	 [(match_dup 0)
2766	  (match_operand:QI 1 "register_operand" "")]))
2767   (clobber (match_operand:QI 3 "register_operand" ""))]
2768  "epilogue_completed
2769   && !find_regno_note (insn, REG_DEAD, REGNO (operands[1]))"
2770  [(set (match_dup 3)
2771	(match_dup 1))
2772   (set (cc0) (compare (match_dup 3) (const_int 0)))
2773   (set (pc)
2774        (if_then_else (le (cc0) (const_int 0))
2775		      (label_ref (match_dup 5))
2776		      (pc)))
2777   (match_dup 4)
2778   (parallel
2779     [(set (match_dup 0)
2780	   (match_op_dup 2 [(match_dup 0) (const_int 1)]))
2781      (clobber (scratch:QI))])
2782   (set (match_dup 3) (plus:QI (match_dup 3) (const_int -1)))
2783   (set (cc0) (compare (match_dup 3) (const_int 0)))
2784   (set (pc)
2785        (if_then_else (ne (cc0) (const_int 0))
2786		      (label_ref (match_dup 4))
2787		      (pc)))
2788   (match_dup 5)]
2789  {
2790    operands[4] = gen_label_rtx ();
2791    operands[5] = gen_label_rtx ();
2792  })
2793
2794;; ----------------------------------------------------------------------
2795;; ROTATIONS
2796;; ----------------------------------------------------------------------
2797
2798(define_expand "rotl<mode>3"
2799  [(set (match_operand:QHI 0 "register_operand" "")
2800	(rotate:QHI (match_operand:QHI 1 "register_operand" "")
2801		    (match_operand:QI 2 "nonmemory_operand" "")))]
2802  ""
2803  {
2804    if (expand_a_rotate (operands))
2805    DONE;
2806  })
2807
2808(define_insn "rotl<mode>3_1"
2809  [(set (match_operand:QHI 0 "register_operand" "=r")
2810	(rotate:QHI (match_operand:QHI 1 "register_operand" "0")
2811		    (match_operand:QI 2 "immediate_operand" "")))]
2812  ""
2813{
2814  return output_a_rotate (ROTATE, operands);
2815}
2816  [(set (attr "length")
2817	(symbol_ref "compute_a_rotate_length (operands)"))])
2818
2819(define_expand "rotlsi3"
2820  [(set (match_operand:SI 0 "register_operand" "")
2821	(rotate:SI (match_operand:SI 1 "register_operand" "")
2822		   (match_operand:QI 2 "nonmemory_operand" "")))]
2823  "TARGET_H8300H || TARGET_H8300S"
2824  {
2825    if (expand_a_rotate (operands))
2826    DONE;
2827  })
2828
2829(define_insn "rotlsi3_1"
2830  [(set (match_operand:SI 0 "register_operand" "=r")
2831	(rotate:SI (match_operand:SI 1 "register_operand" "0")
2832		   (match_operand:QI 2 "immediate_operand" "")))]
2833  "TARGET_H8300H || TARGET_H8300S"
2834{
2835  return output_a_rotate (ROTATE, operands);
2836}
2837  [(set (attr "length")
2838	(symbol_ref "compute_a_rotate_length (operands)"))])
2839
2840;; -----------------------------------------------------------------
2841;; BIT FIELDS
2842;; -----------------------------------------------------------------
2843;; The H8/300 has given 1/8th of its opcode space to bitfield
2844;; instructions so let's use them as well as we can.
2845
2846;; You'll never believe all these patterns perform one basic action --
2847;; load a bit from the source, optionally invert the bit, then store it
2848;; in the destination (which is known to be zero).
2849;;
2850;; Combine obviously need some work to better identify this situation and
2851;; canonicalize the form better.
2852
2853;;
2854;; Normal loads with a 16bit destination.
2855;;
2856
2857(define_insn ""
2858  [(set (match_operand:HI 0 "register_operand" "=&r")
2859	(zero_extract:HI (match_operand:HI 1 "register_operand" "r")
2860			 (const_int 1)
2861			 (match_operand:HI 2 "immediate_operand" "n")))]
2862  "TARGET_H8300"
2863  "sub.w	%0,%0\;bld	%Z2,%Y1\;bst	#0,%X0"
2864  [(set_attr "length" "6")])
2865
2866;;
2867;; Inverted loads with a 16bit destination.
2868;;
2869
2870(define_insn ""
2871  [(set (match_operand:HI 0 "register_operand" "=&r")
2872	(zero_extract:HI (xor:HI (match_operand:HI 1 "register_operand" "r")
2873				 (match_operand:HI 3 "const_int_operand" "n"))
2874			 (const_int 1)
2875			 (match_operand:HI 2 "const_int_operand" "n")))]
2876  "(TARGET_H8300 || TARGET_H8300SX)
2877    && (1 << INTVAL (operands[2])) == INTVAL (operands[3])"
2878  "sub.w	%0,%0\;bild	%Z2,%Y1\;bst	#0,%X0"
2879  [(set_attr "length" "8")])
2880
2881;;
2882;; Normal loads with a 32bit destination.
2883;;
2884
2885(define_insn "*extzv_1_r_h8300"
2886  [(set (match_operand:SI 0 "register_operand" "=&r")
2887	(zero_extract:SI (match_operand:HI 1 "register_operand" "r")
2888			 (const_int 1)
2889			 (match_operand 2 "const_int_operand" "n")))]
2890  "TARGET_H8300 && INTVAL (operands[2]) < 16"
2891{
2892  return output_simode_bld (0, operands);
2893}
2894  [(set_attr "length" "8")])
2895
2896(define_insn "*extzv_1_r_h8300hs"
2897  [(set (match_operand:SI 0 "register_operand" "=r,r")
2898	(zero_extract:SI (match_operand:SI 1 "register_operand" "?0,r")
2899			 (const_int 1)
2900			 (match_operand 2 "const_int_operand" "n,n")))]
2901  "(TARGET_H8300H || TARGET_H8300S) && INTVAL (operands[2]) < 16"
2902{
2903  return output_simode_bld (0, operands);
2904}
2905  [(set_attr "cc" "set_znv,set_znv")
2906   (set_attr "length" "8,6")])
2907
2908;;
2909;; Inverted loads with a 32bit destination.
2910;;
2911
2912(define_insn "*extzv_1_r_inv_h8300"
2913  [(set (match_operand:SI 0 "register_operand" "=&r")
2914	(zero_extract:SI (xor:HI (match_operand:HI 1 "register_operand" "r")
2915				 (match_operand:HI 3 "const_int_operand" "n"))
2916			 (const_int 1)
2917			 (match_operand 2 "const_int_operand" "n")))]
2918  "TARGET_H8300 && INTVAL (operands[2]) < 16
2919   && (1 << INTVAL (operands[2])) == INTVAL (operands[3])"
2920{
2921  return output_simode_bld (1, operands);
2922}
2923  [(set_attr "length" "8")])
2924
2925(define_insn "*extzv_1_r_inv_h8300hs"
2926  [(set (match_operand:SI 0 "register_operand" "=r,r")
2927	(zero_extract:SI (xor:SI (match_operand:SI 1 "register_operand" "?0,r")
2928				 (match_operand 3 "const_int_operand" "n,n"))
2929			 (const_int 1)
2930			 (match_operand 2 "const_int_operand" "n,n")))]
2931  "(TARGET_H8300H || TARGET_H8300S) && INTVAL (operands[2]) < 16
2932    && (1 << INTVAL (operands[2])) == INTVAL (operands[3])"
2933{
2934  return output_simode_bld (1, operands);
2935}
2936  [(set_attr "cc" "set_znv,set_znv")
2937   (set_attr "length" "8,6")])
2938
2939(define_expand "insv"
2940  [(set (zero_extract:HI (match_operand:HI 0 "general_operand" "")
2941			 (match_operand:HI 1 "general_operand" "")
2942			 (match_operand:HI 2 "general_operand" ""))
2943	(match_operand:HI 3 "general_operand" ""))]
2944  "TARGET_H8300 || TARGET_H8300SX"
2945  {
2946    if (TARGET_H8300SX)
2947      {
2948	if (GET_CODE (operands[1]) == CONST_INT
2949	    && GET_CODE (operands[2]) == CONST_INT
2950	    && INTVAL (operands[1]) <= 8
2951	    && INTVAL (operands[2]) >= 0
2952	    && INTVAL (operands[1]) + INTVAL (operands[2]) <= 8
2953	    && memory_operand (operands[0], GET_MODE (operands[0])))
2954	  {
2955	    /* If the source operand is zero, it's better to use AND rather
2956	       than BFST.  Likewise OR if the operand is all ones.  */
2957	    if (GET_CODE (operands[3]) == CONST_INT)
2958	      {
2959		HOST_WIDE_INT mask = (1 << INTVAL (operands[1])) - 1;
2960		if ((INTVAL (operands[3]) & mask) == 0)
2961		  FAIL;
2962		if ((INTVAL (operands[3]) & mask) == mask)
2963		  FAIL;
2964	      }
2965	    if (! bit_memory_operand (operands[0], GET_MODE (operands[0])))
2966	      {
2967		if (!can_create_pseudo_p ())
2968		  FAIL;
2969		operands[0] =  replace_equiv_address (operands[0], force_reg (Pmode,
2970						      XEXP (operands[0], 0)));
2971	      }
2972	    operands[3] = gen_lowpart (QImode, operands[3]);
2973	    if (! operands[3])
2974	      FAIL;
2975	    if (! register_operand (operands[3], QImode))
2976	      {
2977		if (!can_create_pseudo_p ())
2978		  FAIL;
2979		operands[3] = force_reg (QImode, operands[3]);
2980	      }
2981	    emit_insn (gen_bfst (adjust_address (operands[0], QImode, 0),
2982						 operands[3], operands[1], operands[2]));
2983	    DONE;
2984	  }
2985	FAIL;
2986      }
2987
2988    /* We only have single bit bit-field instructions.  */
2989    if (INTVAL (operands[1]) != 1)
2990      FAIL;
2991
2992    /* For now, we don't allow memory operands.  */
2993    if (GET_CODE (operands[0]) == MEM
2994	|| GET_CODE (operands[3]) == MEM)
2995      FAIL;
2996
2997    if (GET_CODE (operands[3]) != REG)
2998      operands[3] = force_reg (HImode, operands[3]);
2999  })
3000
3001(define_insn ""
3002  [(set (zero_extract:HI (match_operand:HI 0 "register_operand" "+r")
3003			 (const_int 1)
3004			 (match_operand:HI 1 "immediate_operand" "n"))
3005	(match_operand:HI 2 "register_operand" "r"))]
3006  ""
3007  "bld	#0,%R2\;bst	%Z1,%Y0 ; i1"
3008  [(set_attr "length" "4")])
3009
3010(define_expand "extzv"
3011  [(set (match_operand:HI 0 "register_operand" "")
3012	(zero_extract:HI (match_operand:HI 1 "bit_operand" "")
3013			 (match_operand:HI 2 "general_operand" "")
3014			 (match_operand:HI 3 "general_operand" "")))]
3015  "TARGET_H8300 || TARGET_H8300SX"
3016  {
3017    if (TARGET_H8300SX)
3018      {
3019	if (GET_CODE (operands[2]) == CONST_INT
3020	    && GET_CODE (operands[3]) == CONST_INT
3021	    && INTVAL (operands[2]) <= 8
3022	    && INTVAL (operands[3]) >= 0
3023	    && INTVAL (operands[2]) + INTVAL (operands[3]) <= 8
3024	    && memory_operand (operands[1], QImode))
3025	  {
3026	    rtx temp;
3027
3028	    /* Optimize the case where we're extracting into a paradoxical
3029	       subreg.  It's only necessary to extend to the inner reg.  */
3030	    if (GET_CODE (operands[0]) == SUBREG
3031		&& subreg_lowpart_p (operands[0])
3032		&& (GET_MODE_SIZE (GET_MODE (SUBREG_REG (operands[0])))
3033		    < GET_MODE_SIZE (GET_MODE (operands[0])))
3034		&& (GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0])))
3035		    == MODE_INT))
3036	      operands[0] = SUBREG_REG (operands[0]);
3037
3038	    if (!can_create_pseudo_p ())
3039	      temp = gen_lowpart (QImode, operands[0]);
3040	    else
3041	      temp = gen_reg_rtx (QImode);
3042	    if (! temp)
3043	      FAIL;
3044            if (! bit_memory_operand (operands[1], QImode))
3045	      {
3046		if (!can_create_pseudo_p ())
3047		  FAIL;
3048		operands[1] = replace_equiv_address (operands[1],
3049						     force_reg (Pmode, XEXP (operands[1], 0)));
3050	      }
3051	    emit_insn (gen_bfld (temp, operands[1], operands[2], operands[3]));
3052	    convert_move (operands[0], temp, 1);
3053	    DONE;
3054          }
3055	FAIL;
3056      }
3057
3058    /* We only have single bit bit-field instructions.  */
3059    if (INTVAL (operands[2]) != 1)
3060      FAIL;
3061
3062    /* For now, we don't allow memory operands.  */
3063    if (GET_CODE (operands[1]) == MEM)
3064      FAIL;
3065  })
3066
3067;; BAND, BOR, and BXOR patterns
3068
3069(define_insn ""
3070  [(set (match_operand:HI 0 "bit_operand" "=Ur")
3071	(match_operator:HI 4 "bit_operator"
3072	 [(zero_extract:HI (match_operand:HI 1 "register_operand" "r")
3073			   (const_int 1)
3074			   (match_operand:HI 2 "immediate_operand" "n"))
3075	  (match_operand:HI 3 "bit_operand" "0")]))]
3076  ""
3077  "bld	%Z2,%Y1\;b%c4	#0,%R0\;bst	#0,%R0; bl1"
3078  [(set_attr "length" "6")])
3079
3080(define_insn ""
3081  [(set (match_operand:HI 0 "bit_operand" "=Ur")
3082	(match_operator:HI 5 "bit_operator"
3083	 [(zero_extract:HI (match_operand:HI 1 "register_operand" "r")
3084			   (const_int 1)
3085			   (match_operand:HI 2 "immediate_operand" "n"))
3086	  (zero_extract:HI (match_operand:HI 3 "register_operand" "r")
3087			   (const_int 1)
3088			   (match_operand:HI 4 "immediate_operand" "n"))]))]
3089  ""
3090  "bld	%Z2,%Y1\;b%c5	%Z4,%Y3\;bst	#0,%R0; bl3"
3091  [(set_attr "length" "6")])
3092
3093(define_insn "bfld"
3094  [(set (match_operand:QI 0 "register_operand" "=r")
3095	(zero_extract:QI (match_operand:QI 1 "bit_memory_operand" "WU")
3096			 (match_operand:QI 2 "immediate_operand" "n")
3097			 (match_operand:QI 3 "immediate_operand" "n")))]
3098  "TARGET_H8300SX && INTVAL (operands[2]) + INTVAL (operands[3]) <= 8"
3099{
3100  operands[2] = GEN_INT ((1 << (INTVAL (operands[2]) + INTVAL (operands[3])))
3101			 - (1 << INTVAL (operands[3])));
3102  return "bfld	%2,%1,%R0";
3103}
3104  [(set_attr "cc" "none_0hit")
3105   (set_attr "length_table" "bitfield")])
3106
3107(define_insn "bfst"
3108  [(set (zero_extract:QI (match_operand:QI 0 "bit_memory_operand" "+WU")
3109			 (match_operand:QI 2 "immediate_operand" "n")
3110			 (match_operand:QI 3 "immediate_operand" "n"))
3111	(match_operand:QI 1 "register_operand" "r"))]
3112  "TARGET_H8300SX && INTVAL (operands[2]) + INTVAL (operands[3]) <= 8"
3113{
3114  operands[2] = GEN_INT ((1 << (INTVAL (operands[2]) + INTVAL (operands[3])))
3115			 - (1 << INTVAL (operands[3])));
3116  return "bfst	%R1,%2,%0";
3117}
3118  [(set_attr "cc" "none_0hit")
3119   (set_attr "length_table" "bitfield")])
3120
3121(define_expand "cstoreqi4"
3122  [(use (match_operator 1 "eqne_operator"
3123         [(match_operand:QI 2 "h8300_dst_operand" "")
3124          (match_operand:QI 3 "h8300_src_operand" "")]))
3125   (clobber (match_operand:HI 0 "register_operand"))]
3126  "TARGET_H8300SX"
3127  {
3128    h8300_expand_store (operands);
3129    DONE;
3130  })
3131
3132(define_expand "cstorehi4"
3133  [(use (match_operator 1 "eqne_operator"
3134         [(match_operand:HI 2 "h8300_dst_operand" "")
3135          (match_operand:HI 3 "h8300_src_operand" "")]))
3136   (clobber (match_operand:HI 0 "register_operand"))]
3137  "TARGET_H8300SX"
3138  {
3139    h8300_expand_store (operands);
3140    DONE;
3141  })
3142
3143(define_expand "cstoresi4"
3144  [(use (match_operator 1 "eqne_operator"
3145         [(match_operand:SI 2 "h8300_dst_operand" "")
3146          (match_operand:SI 3 "h8300_src_operand" "")]))
3147   (clobber (match_operand:HI 0 "register_operand"))]
3148  "TARGET_H8300SX"
3149  {
3150    h8300_expand_store (operands);
3151    DONE;
3152  })
3153
3154(define_insn "*bstzhireg"
3155  [(set (match_operand:HI 0 "register_operand" "=r")
3156	(match_operator:HI 1 "eqne_operator" [(cc0) (const_int 0)]))]
3157  "TARGET_H8300SX"
3158  "mulu.w	#0,%T0\;b%k1	.Lh8BR%=\;inc.w	#1,%T0\\n.Lh8BR%=:"
3159  [(set_attr "cc" "clobber")])
3160
3161(define_insn_and_split "*cmpstz"
3162  [(set (zero_extract:QI (match_operand:QI 0 "bit_memory_operand" "+WU,WU")
3163			 (const_int 1)
3164			 (match_operand:QI 1 "immediate_operand" "n,n"))
3165	(match_operator:QI 2 "eqne_operator"
3166	 [(match_operand 3 "h8300_dst_operand" "r,rQ")
3167	  (match_operand 4 "h8300_src_operand" "I,rQi")]))]
3168  "TARGET_H8300SX
3169   && (GET_MODE (operands[3]) == GET_MODE (operands[4])
3170       || GET_CODE (operands[4]) == CONST_INT)
3171   && GET_MODE_CLASS (GET_MODE (operands[3])) == MODE_INT
3172   && GET_MODE_SIZE (GET_MODE (operands[3])) <= 4"
3173  "#"
3174  "reload_completed"
3175  [(set (cc0) (match_dup 5))
3176   (set (zero_extract:QI (match_dup 0) (const_int 1) (match_dup 1))
3177	(match_op_dup:QI 2 [(cc0) (const_int 0)]))]
3178  {
3179    operands[5] = gen_rtx_COMPARE (VOIDmode, operands[3], operands[4]);
3180  }
3181  [(set_attr "cc" "set_znv,compare")])
3182
3183(define_insn "*bstz"
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	(eq:QI (cc0) (const_int 0)))]
3188  "TARGET_H8300SX && reload_completed"
3189  "bstz	%1,%0"
3190  [(set_attr "cc" "none_0hit")
3191   (set_attr "length_table" "unary")])
3192
3193(define_insn "*bistz"
3194  [(set (zero_extract:QI (match_operand:QI 0 "bit_memory_operand" "+WU")
3195			 (const_int 1)
3196			 (match_operand:QI 1 "immediate_operand" "n"))
3197	(ne:QI (cc0) (const_int 0)))]
3198  "TARGET_H8300SX && reload_completed"
3199  "bistz	%1,%0"
3200  [(set_attr "cc" "none_0hit")
3201   (set_attr "length_table" "unary")])
3202
3203(define_insn_and_split "*cmpcondbset"
3204  [(set (match_operand:QI 0 "nonimmediate_operand" "=WU,WU")
3205	(if_then_else:QI (match_operator 1 "eqne_operator"
3206			  [(match_operand 2 "h8300_dst_operand" "r,rQ")
3207			   (match_operand 3 "h8300_src_operand" "I,rQi")])
3208			 (ior:QI (match_operand:QI 4 "bit_memory_operand" "0,0")
3209				 (match_operand:QI 5 "single_one_operand" "n,n"))
3210			 (match_dup 4)))]
3211  "TARGET_H8300SX"
3212  "#"
3213  "reload_completed"
3214  [(set (cc0) (match_dup 6))
3215   (set (match_dup 0)
3216	(if_then_else:QI (match_op_dup 1 [(cc0) (const_int 0)])
3217			 (ior:QI (match_dup 4) (match_dup 5))
3218			 (match_dup 4)))]
3219  {
3220    operands[6] = gen_rtx_COMPARE (VOIDmode, operands[2], operands[3]);
3221  }
3222  [(set_attr "cc" "set_znv,compare")])
3223
3224(define_insn "*condbset"
3225  [(set (match_operand:QI 0 "bit_memory_operand" "=WU")
3226	(if_then_else:QI (match_operator:QI 2 "eqne_operator"
3227			  [(cc0) (const_int 0)])
3228			 (ior:QI (match_operand:QI 3 "bit_memory_operand" "0")
3229				 (match_operand:QI 1 "single_one_operand" "n"))
3230			 (match_dup 3)))]
3231  "TARGET_H8300SX && reload_completed"
3232  "bset/%j2\t%V1,%0"
3233  [(set_attr "cc" "none_0hit")
3234   (set_attr "length_table" "logicb")])
3235
3236(define_insn_and_split "*cmpcondbclr"
3237  [(set (match_operand:QI 0 "nonimmediate_operand" "=WU,WU")
3238	(if_then_else:QI (match_operator 1 "eqne_operator"
3239			  [(match_operand 2 "h8300_dst_operand" "r,rQ")
3240			   (match_operand 3 "h8300_src_operand" "I,rQi")])
3241			 (and:QI (match_operand:QI 4 "bit_memory_operand" "0,0")
3242				 (match_operand:QI 5 "single_zero_operand" "n,n"))
3243			 (match_dup 4)))]
3244  "TARGET_H8300SX"
3245  "#"
3246  "reload_completed"
3247  [(set (cc0) (match_dup 6))
3248   (set (match_dup 0)
3249	(if_then_else:QI (match_op_dup 1 [(cc0) (const_int 0)])
3250			 (and:QI (match_dup 4) (match_dup 5))
3251			 (match_dup 4)))]
3252  {
3253    operands[6] = gen_rtx_COMPARE (VOIDmode, operands[2], operands[3]);
3254  }
3255  [(set_attr "cc" "set_znv,compare")])
3256
3257(define_insn "*condbclr"
3258  [(set (match_operand:QI 0 "bit_memory_operand" "=WU")
3259	(if_then_else:QI (match_operator:QI 2 "eqne_operator"
3260			  [(cc0) (const_int 0)])
3261			 (and:QI (match_operand:QI 3 "bit_memory_operand" "0")
3262				 (match_operand:QI 1 "single_zero_operand" "n"))
3263			 (match_dup 3)))]
3264  "TARGET_H8300SX && reload_completed"
3265  "bclr/%j2\t%W1,%0"
3266  [(set_attr "cc" "none_0hit")
3267   (set_attr "length_table" "logicb")])
3268
3269(define_insn_and_split "*cmpcondbsetreg"
3270  [(set (match_operand:QI 0 "nonimmediate_operand" "=WU,WU")
3271	(if_then_else:QI (match_operator 1 "eqne_operator"
3272			  [(match_operand 2 "h8300_dst_operand" "r,rQ")
3273			   (match_operand 3 "h8300_src_operand" "I,rQi")])
3274			 (ior:QI (match_operand:QI 4 "bit_memory_operand" "0,0")
3275				 (ashift:QI (const_int 1)
3276					    (match_operand:QI 5 "register_operand" "r,r")))
3277			 (match_dup 4)))]
3278  "TARGET_H8300SX"
3279  "#"
3280  "reload_completed"
3281  [(set (cc0) (match_dup 6))
3282   (set (match_dup 0)
3283	(if_then_else:QI (match_op_dup 1 [(cc0) (const_int 0)])
3284			 (ior:QI (match_dup 4)
3285				 (ashift:QI (const_int 1)
3286					    (match_operand:QI 5 "register_operand" "r,r")))
3287			 (match_dup 4)))]
3288  {
3289    operands[6] = gen_rtx_COMPARE (VOIDmode, operands[2], operands[3]);
3290  }
3291  [(set_attr "cc" "set_znv,compare")])
3292
3293(define_insn "*condbsetreg"
3294  [(set (match_operand:QI 0 "bit_memory_operand" "=WU")
3295	(if_then_else:QI (match_operator:QI 2 "eqne_operator"
3296			  [(cc0) (const_int 0)])
3297			 (ior:QI (match_operand:QI 3 "bit_memory_operand" "0")
3298				 (ashift:QI (const_int 1)
3299					    (match_operand:QI 1 "register_operand" "r")))
3300			 (match_dup 3)))]
3301  "TARGET_H8300SX && reload_completed"
3302  "bset/%j2\t%R1,%0"
3303  [(set_attr "cc" "none_0hit")
3304   (set_attr "length_table" "logicb")])
3305
3306(define_insn_and_split "*cmpcondbclrreg"
3307  [(set (match_operand:QI 0 "nonimmediate_operand" "=WU,WU")
3308	(if_then_else:QI (match_operator 1 "eqne_operator"
3309			  [(match_operand 2 "h8300_dst_operand" "r,rQ")
3310			   (match_operand 3 "h8300_src_operand" "I,rQi")])
3311			 (and:QI (match_operand:QI 4 "bit_memory_operand" "0,0")
3312				 (ashift:QI (const_int 1)
3313					    (match_operand:QI 5 "register_operand" "r,r")))
3314			 (match_dup 4)))]
3315  "TARGET_H8300SX"
3316  "#"
3317  "reload_completed"
3318  [(set (cc0) (match_dup 6))
3319   (set (match_dup 0)
3320	(if_then_else:QI (match_op_dup 1 [(cc0) (const_int 0)])
3321			 (and:QI (match_dup 4)
3322				 (ashift:QI (const_int 1)
3323					    (match_operand:QI 5 "register_operand" "r,r")))
3324			 (match_dup 4)))]
3325  {
3326    operands[6] = gen_rtx_COMPARE (VOIDmode, operands[2], operands[3]);
3327  }
3328  [(set_attr "cc" "set_znv,compare")])
3329
3330(define_insn "*condbclrreg"
3331  [(set (match_operand:QI 0 "bit_memory_operand" "=WU")
3332	(if_then_else:QI (match_operator:QI 2 "eqne_operator"
3333			  [(cc0) (const_int 0)])
3334			 (and:QI (match_operand:QI 3 "bit_memory_operand" "0")
3335				 (ashift:QI (const_int 1)
3336					    (match_operand:QI 1 "register_operand" "r")))
3337			 (match_dup 3)))]
3338  "TARGET_H8300SX && reload_completed"
3339  "bclr/%j2\t%R1,%0"
3340  [(set_attr "cc" "none_0hit")
3341   (set_attr "length_table" "logicb")])
3342
3343
3344;; -----------------------------------------------------------------
3345;; COMBINE PATTERNS
3346;; -----------------------------------------------------------------
3347
3348;; insv:SI
3349
3350(define_insn "*insv_si_1_n"
3351  [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
3352			 (const_int 1)
3353			 (match_operand:SI 1 "const_int_operand" "n"))
3354	(match_operand:SI 2 "register_operand" "r"))]
3355  "(TARGET_H8300H || TARGET_H8300S) && INTVAL (operands[1]) < 16"
3356  "bld\\t#0,%w2\;bst\\t%Z1,%Y0"
3357  [(set_attr "length" "4")])
3358
3359(define_insn "*insv_si_1_n_lshiftrt"
3360  [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
3361			 (const_int 1)
3362			 (match_operand:SI 1 "const_int_operand" "n"))
3363	(lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
3364		     (match_operand:SI 3 "const_int_operand" "n")))]
3365  "(TARGET_H8300H || TARGET_H8300S)
3366    && INTVAL (operands[1]) < 16
3367    && INTVAL (operands[3]) < 16"
3368  "bld\\t%Z3,%Y2\;bst\\t%Z1,%Y0"
3369  [(set_attr "length" "4")])
3370
3371(define_insn "*insv_si_1_n_lshiftrt_16"
3372  [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
3373			 (const_int 1)
3374			 (match_operand:SI 1 "const_int_operand" "n"))
3375	(lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
3376		     (const_int 16)))]
3377  "(TARGET_H8300H || TARGET_H8300S) && INTVAL (operands[1]) < 16"
3378  "rotr.w\\t%e2\;rotl.w\\t%e2\;bst\\t%Z1,%Y0"
3379  [(set_attr "length" "6")])
3380
3381(define_insn "*insv_si_8_8"
3382  [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
3383			 (const_int 8)
3384			 (const_int 8))
3385	(match_operand:SI 1 "register_operand" "r"))]
3386  "TARGET_H8300H || TARGET_H8300S"
3387  "mov.b\\t%w1,%x0"
3388  [(set_attr "length" "2")])
3389
3390(define_insn "*insv_si_8_8_lshiftrt_8"
3391  [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
3392			 (const_int 8)
3393			 (const_int 8))
3394	(lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
3395		     (const_int 8)))]
3396  "TARGET_H8300H || TARGET_H8300S"
3397  "mov.b\\t%x1,%x0"
3398  [(set_attr "length" "2")])
3399
3400;; extzv:SI
3401
3402(define_insn "*extzv_8_8"
3403  [(set (match_operand:SI 0 "register_operand" "=r,r")
3404	(zero_extract:SI (match_operand:SI 1 "register_operand" "?0,r")
3405			 (const_int 8)
3406			 (const_int 8)))]
3407  "TARGET_H8300H || TARGET_H8300S"
3408  "@
3409   mov.b\\t%x1,%w0\;extu.w\\t%f0\;extu.l\\t%S0
3410   sub.l\\t%S0,%S0\;mov.b\\t%x1,%w0"
3411  [(set_attr "cc" "set_znv,clobber")
3412   (set_attr "length" "6,4")])
3413
3414(define_insn "*extzv_8_16"
3415  [(set (match_operand:SI 0 "register_operand" "=r")
3416	(zero_extract:SI (match_operand:SI 1 "register_operand" "r")
3417			 (const_int 8)
3418			 (const_int 16)))]
3419  "TARGET_H8300H || TARGET_H8300S"
3420  "mov.w\\t%e1,%f0\;extu.w\\t%f0\;extu.l\\t%S0"
3421  [(set_attr "cc" "set_znv")
3422   (set_attr "length" "6")])
3423
3424(define_insn "*extzv_16_8"
3425  [(set (match_operand:SI 0 "register_operand" "=r")
3426	(zero_extract:SI (match_operand:SI 1 "register_operand" "r")
3427			 (const_int 16)
3428			 (const_int 8)))
3429   (clobber (match_scratch:SI 2 "=&r"))]
3430  "TARGET_H8300H"
3431  "mov.w\\t%e1,%f2\;mov.b\\t%x1,%w0\;mov.b\\t%w2,%x0\;extu.l\\t%S0"
3432  [(set_attr "length" "8")
3433   (set_attr "cc" "set_znv")])
3434
3435;; Extract the exponent of a float.
3436
3437(define_insn_and_split "*extzv_8_23"
3438  [(set (match_operand:SI 0 "register_operand" "=r")
3439	(zero_extract:SI (match_operand:SI 1 "register_operand" "0")
3440			 (const_int 8)
3441			 (const_int 23)))]
3442  "(TARGET_H8300H || TARGET_H8300S)"
3443  "#"
3444  "&& reload_completed"
3445  [(parallel [(set (match_dup 0)
3446		   (ashift:SI (match_dup 0)
3447			      (const_int 1)))
3448	      (clobber (scratch:QI))])
3449   (parallel [(set (match_dup 0)
3450		   (lshiftrt:SI (match_dup 0)
3451				(const_int 24)))
3452	      (clobber (scratch:QI))])]
3453  "")
3454
3455;; and:SI
3456
3457;; ((SImode) HImode) << 15
3458
3459(define_insn_and_split "*twoshifts_l16_r1"
3460  [(set (match_operand:SI 0 "register_operand" "=r")
3461	(and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
3462			   (const_int 15))
3463		(const_int 2147450880)))]
3464  "(TARGET_H8300H || TARGET_H8300S)"
3465  "#"
3466  "&& reload_completed"
3467  [(parallel [(set (match_dup 0)
3468		   (ashift:SI (match_dup 0)
3469			      (const_int 16)))
3470	      (clobber (scratch:QI))])
3471   (parallel [(set (match_dup 0)
3472		   (lshiftrt:SI (match_dup 0)
3473				(const_int 1)))
3474	      (clobber (scratch:QI))])]
3475  "")
3476
3477;; Transform (SImode << B) & 0xffff into (SImode) (HImode << B).
3478
3479(define_insn_and_split "*andsi3_ashift_n_lower"
3480  [(set (match_operand:SI 0 "register_operand" "=r,r")
3481	(and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0,0")
3482			   (match_operand:QI 2 "const_int_operand" "S,n"))
3483		(match_operand:SI 3 "const_int_operand" "n,n")))
3484   (clobber (match_scratch:QI 4 "=X,&r"))]
3485  "(TARGET_H8300H || TARGET_H8300S)
3486    && INTVAL (operands[2]) <= 15
3487    && UINTVAL (operands[3]) == ((HOST_WIDE_INT_M1U << INTVAL (operands[2]))
3488				 & 0xffff)"
3489  "#"
3490  "&& reload_completed"
3491  [(parallel [(set (match_dup 5)
3492		   (ashift:HI (match_dup 5)
3493			      (match_dup 2)))
3494	      (clobber (match_dup 4))])
3495   (set (match_dup 0)
3496	(zero_extend:SI (match_dup 5)))]
3497  {
3498    operands[5] = gen_rtx_REG (HImode, REGNO (operands[0]));
3499  })
3500
3501;; Accept (A >> 30) & 2 and the like.
3502
3503(define_insn "*andsi3_lshiftrt_n_sb"
3504  [(set (match_operand:SI 0 "register_operand" "=r")
3505	(and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
3506			     (match_operand:SI 2 "const_int_operand" "n"))
3507		(match_operand:SI 3 "single_one_operand" "n")))]
3508  "(TARGET_H8300H || TARGET_H8300S)
3509    && exact_log2 (INTVAL (operands[3])) < 16
3510    && INTVAL (operands[2]) + exact_log2 (INTVAL (operands[3])) == 31"
3511{
3512  operands[3] = GEN_INT (exact_log2 (INTVAL (operands[3])));
3513  return "shll.l\\t%S0\;xor.l\\t%S0,%S0\;bst\\t%Z3,%Y0";
3514}
3515  [(set_attr "length" "8")])
3516
3517(define_insn_and_split "*andsi3_lshiftrt_9_sb"
3518  [(set (match_operand:SI 0 "register_operand" "=r")
3519	(and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
3520			     (const_int 9))
3521		(const_int 4194304)))]
3522  "TARGET_H8300H || TARGET_H8300S"
3523  "#"
3524  "&& reload_completed"
3525  [(set (match_dup 0)
3526	(and:SI (lshiftrt:SI (match_dup 0)
3527			     (const_int 25))
3528		(const_int 64)))
3529   (parallel [(set (match_dup 0)
3530		   (ashift:SI (match_dup 0)
3531			      (const_int 16)))
3532	      (clobber (scratch:QI))])]
3533  "")
3534
3535;; plus:SI
3536
3537(define_insn "*addsi3_upper"
3538  [(set (match_operand:SI 0 "register_operand" "=r")
3539	(plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
3540			  (const_int 65536))
3541		 (match_operand:SI 2 "register_operand" "0")))]
3542  "TARGET_H8300H || TARGET_H8300S"
3543  "add.w\\t%f1,%e0"
3544  [(set_attr "length" "2")])
3545
3546(define_insn "*addsi3_lshiftrt_16_zexthi"
3547  [(set (match_operand:SI 0 "register_operand" "=r")
3548	(plus:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
3549			      (const_int 16))
3550		 (zero_extend:SI (match_operand:HI 2 "register_operand" "0"))))]
3551  "TARGET_H8300H || TARGET_H8300S"
3552  "add.w\\t%e1,%f0\;xor.w\\t%e0,%e0\;rotxl.w\\t%e0"
3553  [(set_attr "length" "6")])
3554
3555(define_insn_and_split "*addsi3_and_r_1"
3556  [(set (match_operand:SI 0 "register_operand" "=r")
3557	(plus:SI (and:SI (match_operand:SI 1 "register_operand" "r")
3558			 (const_int 1))
3559		 (match_operand:SI 2 "register_operand" "0")))]
3560  "TARGET_H8300H || TARGET_H8300S"
3561  "#"
3562  "&& reload_completed"
3563  [(set (cc0) (compare (zero_extract:SI (match_dup 1)
3564					(const_int 1)
3565					(const_int 0))
3566		       (const_int 0)))
3567   (set (pc)
3568        (if_then_else (eq (cc0)
3569			  (const_int 0))
3570		      (label_ref (match_dup 3))
3571		      (pc)))
3572   (set (match_dup 2)
3573        (plus:SI (match_dup 2)
3574		 (const_int 1)))
3575   (match_dup 3)]
3576  {
3577    operands[3] = gen_label_rtx ();
3578  })
3579
3580(define_insn_and_split "*addsi3_and_not_r_1"
3581  [(set (match_operand:SI 0 "register_operand" "=r")
3582	(plus:SI (and:SI (not:SI (match_operand:SI 1 "register_operand" "r"))
3583			 (const_int 1))
3584		 (match_operand:SI 2 "register_operand" "0")))]
3585  "TARGET_H8300H || TARGET_H8300S"
3586  "#"
3587  "&& reload_completed"
3588  [(set (cc0) (compare (zero_extract:SI (match_dup 1)
3589					(const_int 1)
3590					(const_int 0))
3591		       (const_int 0)))
3592   (set (pc)
3593        (if_then_else (ne (cc0)
3594			  (const_int 0))
3595		      (label_ref (match_dup 3))
3596		      (pc)))
3597   (set (match_dup 2)
3598        (plus:SI (match_dup 2)
3599		 (const_int 1)))
3600   (match_dup 3)]
3601  {
3602    operands[3] = gen_label_rtx ();
3603  })
3604
3605;; [ix]or:HI
3606
3607(define_insn "*ixorhi3_zext"
3608  [(set (match_operand:HI 0 "register_operand" "=r")
3609	(match_operator:HI 1 "iorxor_operator"
3610	 [(zero_extend:HI (match_operand:QI 2 "register_operand" "r"))
3611	  (match_operand:HI 3 "register_operand" "0")]))]
3612  ""
3613  "%c1.b\\t%X2,%s0"
3614  [(set_attr "length" "2")])
3615
3616;; [ix]or:SI
3617
3618(define_insn "*ixorsi3_zext_qi"
3619  [(set (match_operand:SI 0 "register_operand" "=r")
3620	(match_operator:SI 1 "iorxor_operator"
3621	 [(zero_extend:SI (match_operand:QI 2 "register_operand" "r"))
3622	  (match_operand:SI 3 "register_operand" "0")]))]
3623  ""
3624  "%c1.b\\t%X2,%w0"
3625  [(set_attr "length" "2")])
3626
3627(define_insn "*ixorsi3_zext_hi"
3628  [(set (match_operand:SI 0 "register_operand" "=r")
3629	(match_operator:SI 1 "iorxor_operator"
3630	 [(zero_extend:SI (match_operand:HI 2 "register_operand" "r"))
3631	  (match_operand:SI 3 "register_operand" "0")]))]
3632  "TARGET_H8300H || TARGET_H8300S"
3633  "%c1.w\\t%T2,%f0"
3634  [(set_attr "length" "2")])
3635
3636(define_insn "*ixorsi3_ashift_16"
3637  [(set (match_operand:SI 0 "register_operand" "=r")
3638	(match_operator:SI 1 "iorxor_operator"
3639	 [(ashift: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%f2,%e0"
3644  [(set_attr "length" "2")])
3645
3646(define_insn "*ixorsi3_lshiftrt_16"
3647  [(set (match_operand:SI 0 "register_operand" "=r")
3648	(match_operator:SI 1 "iorxor_operator"
3649	 [(lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
3650		       (const_int 16))
3651	  (match_operand:SI 3 "register_operand" "0")]))]
3652  "TARGET_H8300H || TARGET_H8300S"
3653  "%c1.w\\t%e2,%f0"
3654  [(set_attr "length" "2")])
3655
3656;; ior:HI
3657
3658(define_insn "*iorhi3_ashift_8"
3659  [(set (match_operand:HI 0 "register_operand" "=r")
3660	(ior:HI (ashift:HI (match_operand:HI 1 "register_operand" "r")
3661			   (const_int 8))
3662		(match_operand:HI 2 "register_operand" "0")))]
3663  ""
3664  "or.b\\t%s1,%t0"
3665  [(set_attr "length" "2")])
3666
3667(define_insn "*iorhi3_lshiftrt_8"
3668  [(set (match_operand:HI 0 "register_operand" "=r")
3669	(ior:HI (lshiftrt:HI (match_operand:HI 1 "register_operand" "r")
3670			     (const_int 8))
3671		(match_operand:HI 2 "register_operand" "0")))]
3672  ""
3673  "or.b\\t%t1,%s0"
3674  [(set_attr "length" "2")])
3675
3676(define_insn "*iorhi3_two_qi"
3677  [(set (match_operand:HI 0 "register_operand" "=r")
3678	(ior:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "0"))
3679		(ashift:HI (match_operand:HI 2 "register_operand" "r")
3680			   (const_int 8))))]
3681  ""
3682  "mov.b\\t%s2,%t0"
3683  [(set_attr "length" "2")])
3684
3685(define_insn "*iorhi3_two_qi_mem"
3686  [(set (match_operand:HI 0 "register_operand" "=&r")
3687	(ior:HI (zero_extend:HI (match_operand:QI 1 "memory_operand" "m"))
3688		(ashift:HI (subreg:HI (match_operand:QI 2 "memory_operand" "m") 0)
3689			   (const_int 8))))]
3690  ""
3691  "mov.b\\t%X2,%t0\;mov.b\\t%X1,%s0"
3692  [(set_attr "length" "16")])
3693
3694(define_split
3695  [(set (match_operand:HI 0 "register_operand" "")
3696	(ior:HI (zero_extend:HI (match_operand:QI 1 "memory_operand" ""))
3697		(ashift:HI (subreg:HI (match_operand:QI 2 "memory_operand" "") 0)
3698			   (const_int 8))))]
3699  "(TARGET_H8300H || TARGET_H8300S)
3700    && reload_completed
3701    && byte_accesses_mergeable_p (XEXP (operands[2], 0), XEXP (operands[1], 0))"
3702  [(set (match_dup 0)
3703	(match_dup 3))]
3704  {
3705    operands[3] = gen_rtx_MEM (HImode, XEXP (operands[2], 0));
3706  })
3707
3708;; ior:SI
3709
3710(define_insn "*iorsi3_two_hi"
3711  [(set (match_operand:SI 0 "register_operand" "=r")
3712	(ior:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "0"))
3713		(ashift:SI (match_operand:SI 2 "register_operand" "r")
3714			   (const_int 16))))]
3715  "TARGET_H8300H || TARGET_H8300S"
3716  "mov.w\\t%f2,%e0"
3717  [(set_attr "length" "2")])
3718
3719(define_insn_and_split "*iorsi3_two_qi_zext"
3720  [(set (match_operand:SI 0 "register_operand" "=&r")
3721	(ior:SI (zero_extend:SI (match_operand:QI 1 "memory_operand" "m"))
3722		(and:SI (ashift:SI (subreg:SI (match_operand:QI 2 "memory_operand" "m") 0)
3723				   (const_int 8))
3724			(const_int 65280))))]
3725  "TARGET_H8300H || TARGET_H8300S"
3726  "#"
3727  "&& reload_completed"
3728  [(set (match_dup 3)
3729	(ior:HI (zero_extend:HI (match_dup 1))
3730		(ashift:HI (subreg:HI (match_dup 2) 0)
3731			   (const_int 8))))
3732   (set (match_dup 0)
3733	(zero_extend:SI (match_dup 3)))]
3734  {
3735    operands[3] = gen_rtx_REG (HImode, REGNO (operands[0]));
3736  })
3737
3738(define_insn "*iorsi3_e2f"
3739  [(set (match_operand:SI 0 "register_operand" "=r")
3740	(ior:SI (and:SI (match_operand:SI 1 "register_operand" "0")
3741			(const_int -65536))
3742		(lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
3743			     (const_int 16))))]
3744  "TARGET_H8300H || TARGET_H8300S"
3745  "mov.w\\t%e2,%f0"
3746  [(set_attr "length" "2")])
3747
3748(define_insn_and_split "*iorsi3_two_qi_sext"
3749  [(set (match_operand:SI 0 "register_operand" "=r")
3750	(ior:SI (zero_extend:SI (match_operand:QI 1 "register_operand" "0"))
3751		(ashift:SI (sign_extend:SI (match_operand:QI 2 "register_operand" "r"))
3752			   (const_int 8))))]
3753  "TARGET_H8300H || TARGET_H8300S"
3754  "#"
3755  "&& reload_completed"
3756  [(set (match_dup 3)
3757	(ior:HI (zero_extend:HI (match_dup 1))
3758		(ashift:HI (match_dup 4)
3759			   (const_int 8))))
3760   (set (match_dup 0)
3761	(sign_extend:SI (match_dup 3)))]
3762  {
3763    operands[3] = gen_rtx_REG (HImode, REGNO (operands[0]));
3764    operands[4] = gen_rtx_REG (HImode, REGNO (operands[2]));
3765  })
3766
3767(define_insn "*iorsi3_w"
3768  [(set (match_operand:SI 0 "register_operand" "=r,&r")
3769	(ior:SI (and:SI (match_operand:SI 1 "register_operand" "0,0")
3770			(const_int -256))
3771		(zero_extend:SI (match_operand:QI 2 "general_operand_src" "r,g>"))))]
3772  "TARGET_H8300H || TARGET_H8300S"
3773  "mov.b\\t%X2,%w0"
3774  [(set_attr "length" "2,8")])
3775
3776(define_insn "*iorsi3_ashift_31"
3777  [(set (match_operand:SI 0 "register_operand" "=&r")
3778	(ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "r")
3779			   (const_int 31))
3780		(match_operand:SI 2 "register_operand" "0")))]
3781  "TARGET_H8300H || TARGET_H8300S"
3782  "rotxl.l\\t%S0\;bor\\t#0,%w1\;rotxr.l\\t%S0"
3783  [(set_attr "length" "6")
3784   (set_attr "cc" "set_znv")])
3785
3786(define_insn "*iorsi3_and_ashift"
3787  [(set (match_operand:SI 0 "register_operand" "=r")
3788	(ior:SI (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "r")
3789				   (match_operand:SI 2 "const_int_operand" "n"))
3790			(match_operand:SI 3 "single_one_operand" "n"))
3791		(match_operand:SI 4 "register_operand" "0")))]
3792  "(TARGET_H8300H || TARGET_H8300S)
3793    && (INTVAL (operands[3]) & ~0xffff) == 0"
3794{
3795  rtx srcpos = GEN_INT (exact_log2 (INTVAL (operands[3]))
3796			- INTVAL (operands[2]));
3797  rtx dstpos = GEN_INT (exact_log2 (INTVAL (operands[3])));
3798  operands[2] = srcpos;
3799  operands[3] = dstpos;
3800  return "bld\\t%Z2,%Y1\;bor\\t%Z3,%Y0\;bst\\t%Z3,%Y0";
3801}
3802  [(set_attr "length" "6")])
3803
3804(define_insn "*iorsi3_and_lshiftrt"
3805  [(set (match_operand:SI 0 "register_operand" "=r")
3806	(ior:SI (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
3807				     (match_operand:SI 2 "const_int_operand" "n"))
3808			(match_operand:SI 3 "single_one_operand" "n"))
3809		(match_operand:SI 4 "register_operand" "0")))]
3810  "(TARGET_H8300H || TARGET_H8300S)
3811    && ((INTVAL (operands[3]) << INTVAL (operands[2])) & ~0xffff) == 0"
3812{
3813  rtx srcpos = GEN_INT (exact_log2 (INTVAL (operands[3]))
3814			+ INTVAL (operands[2]));
3815  rtx dstpos = GEN_INT (exact_log2 (INTVAL (operands[3])));
3816  operands[2] = srcpos;
3817  operands[3] = dstpos;
3818  return "bld\\t%Z2,%Y1\;bor\\t%Z3,%Y0\;bst\\t%Z3,%Y0";
3819}
3820  [(set_attr "length" "6")])
3821
3822(define_insn "*iorsi3_zero_extract"
3823  [(set (match_operand:SI 0 "register_operand" "=r")
3824	(ior:SI (zero_extract:SI (match_operand:SI 1 "register_operand" "r")
3825				 (const_int 1)
3826				 (match_operand:SI 2 "const_int_operand" "n"))
3827		(match_operand:SI 3 "register_operand" "0")))]
3828  "(TARGET_H8300H || TARGET_H8300S) && INTVAL (operands[2]) < 16"
3829  "bld\\t%Z2,%Y1\;bor\\t#0,%w0\;bst\\t#0,%w0"
3830  [(set_attr "length" "6")])
3831
3832(define_insn "*iorsi3_and_lshiftrt_n_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 30))
3836			(const_int 2))
3837		(match_operand:SI 2 "register_operand" "0")))]
3838  "TARGET_H8300H || TARGET_H8300S"
3839  "rotl.l\\t%S1\;rotr.l\\t%S1\;bor\\t#1,%w0\;bst\\t#1,%w0"
3840  [(set_attr "length" "8")])
3841
3842(define_insn "*iorsi3_and_lshiftrt_9_sb"
3843  [(set (match_operand:SI 0 "register_operand" "=r")
3844	(ior:SI (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
3845				     (const_int 9))
3846			(const_int 4194304))
3847		(match_operand:SI 2 "register_operand" "0")))
3848   (clobber (match_scratch:HI 3 "=&r"))]
3849  "TARGET_H8300H || TARGET_H8300S"
3850{
3851  if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3852    return "shll.l\\t%S1\;xor.w\\t%T3,%T3\;bst\\t#6,%s3\;or.w\\t%T3,%e0";
3853  else
3854    return "rotl.l\\t%S1\;rotr.l\\t%S1\;xor.w\\t%T3,%T3\;bst\\t#6,%s3\;or.w\\t%T3,%e0";
3855}
3856  [(set_attr "length" "10")])
3857
3858;; Used to OR the exponent of a float.
3859
3860(define_insn "*iorsi3_shift"
3861  [(set (match_operand:SI 0 "register_operand" "=r")
3862	(ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "r")
3863			   (const_int 23))
3864		(match_operand:SI 2 "register_operand" "0")))
3865   (clobber (match_scratch:SI 3 "=&r"))]
3866  "TARGET_H8300H || TARGET_H8300S"
3867  "#")
3868
3869(define_split
3870  [(set (match_operand:SI 0 "register_operand" "")
3871	(ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
3872			   (const_int 23))
3873		(match_dup 0)))
3874   (clobber (match_operand:SI 2 "register_operand" ""))]
3875  "(TARGET_H8300H || TARGET_H8300S)
3876    && epilogue_completed
3877    && find_regno_note (insn, REG_DEAD, REGNO (operands[1]))
3878    && REGNO (operands[0]) != REGNO (operands[1])"
3879  [(parallel [(set (match_dup 3)
3880		   (ashift:HI (match_dup 3)
3881			      (const_int 7)))
3882	      (clobber (scratch:QI))])
3883   (set (match_dup 0)
3884	(ior:SI (ashift:SI (match_dup 1)
3885			   (const_int 16))
3886		(match_dup 0)))]
3887  {
3888    operands[3] = gen_rtx_REG (HImode, REGNO (operands[1]));
3889  })
3890
3891(define_split
3892  [(set (match_operand:SI 0 "register_operand" "")
3893	(ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
3894			   (const_int 23))
3895		(match_dup 0)))
3896   (clobber (match_operand:SI 2 "register_operand" ""))]
3897  "(TARGET_H8300H || TARGET_H8300S)
3898    && epilogue_completed
3899    && !(find_regno_note (insn, REG_DEAD, REGNO (operands[1]))
3900	 && REGNO (operands[0]) != REGNO (operands[1]))"
3901  [(set (match_dup 2)
3902	(match_dup 1))
3903   (parallel [(set (match_dup 3)
3904		   (ashift:HI (match_dup 3)
3905			      (const_int 7)))
3906	      (clobber (scratch:QI))])
3907   (set (match_dup 0)
3908	(ior:SI (ashift:SI (match_dup 2)
3909			   (const_int 16))
3910		(match_dup 0)))]
3911  {
3912    operands[3] = gen_rtx_REG (HImode, REGNO (operands[2]));
3913  })
3914
3915(define_insn "*iorsi2_and_1_lshiftrt_1"
3916  [(set (match_operand:SI 0 "register_operand" "=r")
3917	(ior:SI (and:SI (match_operand:SI 1 "register_operand" "0")
3918			(const_int 1))
3919		(lshiftrt:SI (match_dup 1)
3920			     (const_int 1))))]
3921  "TARGET_H8300H || TARGET_H8300S"
3922  "shlr.l\\t%S0\;bor\\t#0,%w0\;bst\\t#0,%w0"
3923  [(set_attr "length" "6")])
3924
3925(define_insn_and_split "*iorsi3_ashift_16_ashift_24"
3926  [(set (match_operand:SI 0 "register_operand" "=r")
3927	(ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
3928			   (const_int 16))
3929		(ashift:SI (match_operand:SI 2 "register_operand" "r")
3930			   (const_int 24))))]
3931  "TARGET_H8300H || TARGET_H8300S"
3932  "#"
3933  "&& reload_completed"
3934  [(set (match_dup 3)
3935        (ior:HI (ashift:HI (match_dup 4)
3936			   (const_int 8))
3937		(match_dup 3)))
3938   (parallel [(set (match_dup 0)
3939		   (ashift:SI (match_dup 0)
3940			      (const_int 16)))
3941	      (clobber (scratch:QI))])]
3942  {
3943    operands[3] = gen_rtx_REG (HImode, REGNO (operands[0]));
3944    operands[4] = gen_rtx_REG (HImode, REGNO (operands[2]));
3945  })
3946
3947(define_insn_and_split "*iorsi3_ashift_16_ashift_24_mem"
3948  [(set (match_operand:SI 0 "register_operand" "=&r")
3949	(ior:SI (and:SI (ashift:SI (subreg:SI (match_operand:QI 1 "memory_operand" "m") 0)
3950				   (const_int 16))
3951			(const_int 16711680))
3952		(ashift:SI (subreg:SI (match_operand:QI 2 "memory_operand" "m") 0)
3953			   (const_int 24))))]
3954  "TARGET_H8300H || TARGET_H8300S"
3955  "#"
3956  "&& reload_completed"
3957  [(set (match_dup 3)
3958        (ior:HI (zero_extend:HI (match_dup 1))
3959		(ashift:HI (subreg:HI (match_dup 2) 0)
3960			   (const_int 8))))
3961   (parallel [(set (match_dup 0)
3962		   (ashift:SI (match_dup 0)
3963			      (const_int 16)))
3964	      (clobber (scratch:QI))])]
3965  {
3966    operands[3] = gen_rtx_REG (HImode, REGNO (operands[0]));
3967  })
3968
3969;; Used to add the exponent of a float.
3970
3971(define_insn "*addsi3_shift"
3972  [(set (match_operand:SI 0 "register_operand" "=r")
3973	(plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
3974			  (const_int 8388608))
3975		 (match_operand:SI 2 "register_operand" "0")))
3976   (clobber (match_scratch:SI 3 "=&r"))]
3977  "TARGET_H8300H || TARGET_H8300S"
3978  "#")
3979
3980(define_split
3981  [(set (match_operand:SI 0 "register_operand" "")
3982	(plus:SI (mult:SI (match_operand:SI 1 "register_operand" "")
3983			  (const_int 8388608))
3984		 (match_dup 0)))
3985   (clobber (match_operand:SI 2 "register_operand" ""))]
3986  "(TARGET_H8300H || TARGET_H8300S)
3987    && epilogue_completed
3988    && find_regno_note (insn, REG_DEAD, REGNO (operands[1]))
3989    && REGNO (operands[0]) != REGNO (operands[1])"
3990  [(parallel [(set (match_dup 3)
3991		   (ashift:HI (match_dup 3)
3992			      (const_int 7)))
3993	      (clobber (scratch:QI))])
3994   (set (match_dup 0)
3995	(plus:SI (mult:SI (match_dup 1)
3996			  (const_int 65536))
3997		 (match_dup 0)))]
3998  {
3999    operands[3] = gen_rtx_REG (HImode, REGNO (operands[1]));
4000  })
4001
4002(define_split
4003  [(set (match_operand:SI 0 "register_operand" "")
4004	(plus:SI (mult:SI (match_operand:SI 1 "register_operand" "")
4005			  (const_int 8388608))
4006		 (match_dup 0)))
4007   (clobber (match_operand:SI 2 "register_operand" ""))]
4008  "(TARGET_H8300H || TARGET_H8300S)
4009    && epilogue_completed
4010    && !(find_regno_note (insn, REG_DEAD, REGNO (operands[1]))
4011	 && REGNO (operands[0]) != REGNO (operands[1]))"
4012  [(set (match_dup 2)
4013	(match_dup 1))
4014   (parallel [(set (match_dup 3)
4015		   (ashift:HI (match_dup 3)
4016			      (const_int 7)))
4017	      (clobber (scratch:QI))])
4018   (set (match_dup 0)
4019	(plus:SI (mult:SI (match_dup 2)
4020			  (const_int 65536))
4021		 (match_dup 0)))]
4022  {
4023    operands[3] = gen_rtx_REG (HImode, REGNO (operands[2]));
4024  })
4025
4026;; ashift:SI
4027
4028(define_insn_and_split "*ashiftsi_sextqi_7"
4029  [(set (match_operand:SI 0 "register_operand" "=r")
4030	(ashift:SI (sign_extend:SI (match_operand:QI 1 "register_operand" "0"))
4031		   (const_int 7)))]
4032  "TARGET_H8300H || TARGET_H8300S"
4033  "#"
4034  "&& reload_completed"
4035  [(parallel [(set (match_dup 2)
4036		   (ashift:HI (match_dup 2)
4037			      (const_int 8)))
4038	      (clobber (scratch:QI))])
4039   (set (match_dup 0)
4040	(sign_extend:SI (match_dup 2)))
4041   (parallel [(set (match_dup 0)
4042		   (ashiftrt:SI (match_dup 0)
4043				(const_int 1)))
4044	      (clobber (scratch:QI))])]
4045  {
4046    operands[2] = gen_rtx_REG (HImode, REGNO (operands[0]));
4047  })
4048
4049;; Storing a part of HImode to QImode.
4050
4051(define_insn ""
4052  [(set (match_operand:QI 0 "general_operand_dst" "=rm<")
4053	(subreg:QI (lshiftrt:HI (match_operand:HI 1 "register_operand" "r")
4054				(const_int 8)) 1))]
4055  ""
4056  "mov.b\\t%t1,%R0"
4057  [(set_attr "cc" "set_znv")
4058   (set_attr "length" "8")])
4059
4060;; Storing a part of SImode to QImode.
4061
4062(define_insn ""
4063  [(set (match_operand:QI 0 "general_operand_dst" "=rm<")
4064	(subreg:QI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
4065				(const_int 8)) 3))]
4066  ""
4067  "mov.b\\t%x1,%R0"
4068  [(set_attr "cc" "set_znv")
4069   (set_attr "length" "8")])
4070
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 16)) 3))
4075   (clobber (match_scratch:SI 2 "=&r"))]
4076  "TARGET_H8300H || TARGET_H8300S"
4077  "mov.w\\t%e1,%f2\;mov.b\\t%w2,%R0"
4078  [(set_attr "cc" "set_znv")
4079   (set_attr "length" "10")])
4080
4081(define_insn ""
4082  [(set (match_operand:QI 0 "general_operand_dst" "=rm<")
4083	(subreg:QI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
4084				(const_int 24)) 3))
4085   (clobber (match_scratch:SI 2 "=&r"))]
4086  "TARGET_H8300H || TARGET_H8300S"
4087  "mov.w\\t%e1,%f2\;mov.b\\t%x2,%R0"
4088  [(set_attr "cc" "set_znv")
4089   (set_attr "length" "10")])
4090
4091(define_insn_and_split ""
4092  [(set (pc)
4093	(if_then_else (eq (zero_extract:SI (subreg:SI (match_operand:QI 0 "register_operand" "") 0)
4094					   (const_int 1)
4095					   (const_int 7))
4096			  (const_int 0))
4097		      (label_ref (match_operand 1 "" ""))
4098		      (pc)))]
4099  ""
4100  "#"
4101  ""
4102  [(set (cc0) (compare (match_dup 0)
4103		       (const_int 0)))
4104   (set (pc)
4105	(if_then_else (ge (cc0)
4106			  (const_int 0))
4107		      (label_ref (match_dup 1))
4108		      (pc)))]
4109  "")
4110
4111(define_insn_and_split ""
4112  [(set (pc)
4113	(if_then_else (ne (zero_extract:SI (subreg:SI (match_operand:QI 0 "register_operand" "") 0)
4114					   (const_int 1)
4115					   (const_int 7))
4116			  (const_int 0))
4117		      (label_ref (match_operand 1 "" ""))
4118		      (pc)))]
4119  ""
4120  "#"
4121  ""
4122  [(set (cc0) (compare (match_dup 0)
4123		       (const_int 0)))
4124   (set (pc)
4125	(if_then_else (lt (cc0)
4126			  (const_int 0))
4127		      (label_ref (match_dup 1))
4128		      (pc)))]
4129  "")
4130
4131;; -----------------------------------------------------------------
4132;; PEEPHOLE PATTERNS
4133;; -----------------------------------------------------------------
4134
4135;; Convert (A >> B) & C to (A & 255) >> B if C == 255 >> B.
4136
4137(define_peephole2
4138  [(parallel [(set (match_operand:HI 0 "register_operand" "")
4139		   (lshiftrt:HI (match_dup 0)
4140				(match_operand:HI 1 "const_int_operand" "")))
4141	      (clobber (match_operand:HI 2 "" ""))])
4142   (set (match_dup 0)
4143	(and:HI (match_dup 0)
4144		(match_operand:HI 3 "const_int_operand" "")))]
4145  "INTVAL (operands[3]) == (255 >> INTVAL (operands[1]))"
4146  [(set (match_dup 0)
4147	(and:HI (match_dup 0)
4148		(const_int 255)))
4149   (parallel [(set (match_dup 0)
4150		   (lshiftrt:HI (match_dup 0) (match_dup 1)))
4151	      (clobber (match_dup 2))])]
4152  "")
4153
4154;; Convert (A << B) & C to (A & 255) << B if C == 255 << B.
4155
4156(define_peephole2
4157  [(parallel [(set (match_operand:HI 0 "register_operand" "")
4158		   (ashift:HI (match_dup 0)
4159			      (match_operand:HI 1 "const_int_operand" "")))
4160	      (clobber (match_operand:HI 2 "" ""))])
4161   (set (match_dup 0)
4162	(and:HI (match_dup 0)
4163		(match_operand:HI 3 "const_int_operand" "")))]
4164  "INTVAL (operands[3]) == (255 << INTVAL (operands[1]))"
4165  [(set (match_dup 0)
4166	(and:HI (match_dup 0)
4167		(const_int 255)))
4168   (parallel [(set (match_dup 0)
4169		   (ashift:HI (match_dup 0) (match_dup 1)))
4170	      (clobber (match_dup 2))])]
4171  "")
4172
4173;; Convert (A >> B) & C to (A & 255) >> B if C == 255 >> B.
4174
4175(define_peephole2
4176  [(parallel [(set (match_operand:SI 0 "register_operand" "")
4177		   (lshiftrt:SI (match_dup 0)
4178				(match_operand:SI 1 "const_int_operand" "")))
4179	      (clobber (match_operand:SI 2 "" ""))])
4180   (set (match_dup 0)
4181	(and:SI (match_dup 0)
4182		(match_operand:SI 3 "const_int_operand" "")))]
4183  "INTVAL (operands[3]) == (255 >> INTVAL (operands[1]))"
4184  [(set (match_dup 0)
4185	(and:SI (match_dup 0)
4186		(const_int 255)))
4187   (parallel [(set (match_dup 0)
4188		   (lshiftrt:SI (match_dup 0) (match_dup 1)))
4189	      (clobber (match_dup 2))])]
4190  "")
4191
4192;; Convert (A << B) & C to (A & 255) << B if C == 255 << B.
4193
4194(define_peephole2
4195  [(parallel [(set (match_operand:SI 0 "register_operand" "")
4196		   (ashift:SI (match_dup 0)
4197			      (match_operand:SI 1 "const_int_operand" "")))
4198	      (clobber (match_operand:SI 2 "" ""))])
4199   (set (match_dup 0)
4200	(and:SI (match_dup 0)
4201		(match_operand:SI 3 "const_int_operand" "")))]
4202  "INTVAL (operands[3]) == (255 << INTVAL (operands[1]))"
4203  [(set (match_dup 0)
4204	(and:SI (match_dup 0)
4205		(const_int 255)))
4206   (parallel [(set (match_dup 0)
4207		   (ashift:SI (match_dup 0) (match_dup 1)))
4208	      (clobber (match_dup 2))])]
4209  "")
4210
4211;; Convert (A >> B) & C to (A & 65535) >> B if C == 65535 >> B.
4212
4213(define_peephole2
4214  [(parallel [(set (match_operand:SI 0 "register_operand" "")
4215		   (lshiftrt:SI (match_dup 0)
4216				(match_operand:SI 1 "const_int_operand" "")))
4217	      (clobber (match_operand:SI 2 "" ""))])
4218   (set (match_dup 0)
4219	(and:SI (match_dup 0)
4220		(match_operand:SI 3 "const_int_operand" "")))]
4221  "INTVAL (operands[3]) == (65535 >> INTVAL (operands[1]))"
4222  [(set (match_dup 0)
4223	(and:SI (match_dup 0)
4224		(const_int 65535)))
4225   (parallel [(set (match_dup 0)
4226		   (lshiftrt:SI (match_dup 0) (match_dup 1)))
4227	      (clobber (match_dup 2))])]
4228  "")
4229
4230;; Convert (A << B) & C to (A & 65535) << B if C == 65535 << B.
4231
4232(define_peephole2
4233  [(parallel [(set (match_operand:SI 0 "register_operand" "")
4234		   (ashift:SI (match_dup 0)
4235			      (match_operand:SI 1 "const_int_operand" "")))
4236	      (clobber (match_operand:SI 2 "" ""))])
4237   (set (match_dup 0)
4238	(and:SI (match_dup 0)
4239		(match_operand:SI 3 "const_int_operand" "")))]
4240  "INTVAL (operands[3]) == (65535 << INTVAL (operands[1]))"
4241  [(set (match_dup 0)
4242	(and:SI (match_dup 0)
4243		(const_int 65535)))
4244   (parallel [(set (match_dup 0)
4245		   (ashift:SI (match_dup 0) (match_dup 1)))
4246	      (clobber (match_dup 2))])]
4247  "")
4248
4249;; Convert a QImode push into an SImode push so that the
4250;; define_peephole2 below can cram multiple pushes into one stm.l.
4251
4252(define_peephole2
4253  [(parallel [(set (reg:SI SP_REG)
4254                   (plus:SI (reg:SI SP_REG) (const_int -4)))
4255              (set (mem:QI (plus:SI (reg:SI SP_REG) (const_int -3)))
4256                   (match_operand:QI 0 "register_operand" ""))])]
4257  "TARGET_H8300S && !TARGET_NORMAL_MODE && REGNO (operands[0]) != SP_REG"
4258  [(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
4259	(match_dup 0))]
4260  {
4261    operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]));
4262  })
4263
4264(define_peephole2
4265  [(parallel [(set (reg:HI SP_REG)
4266                   (plus:HI (reg:HI SP_REG) (const_int -4)))
4267              (set (mem:QI (plus:HI (reg:HI SP_REG) (const_int -3)))
4268                   (match_operand:QI 0 "register_operand" ""))])]
4269  "TARGET_H8300S && TARGET_NORMAL_MODE && REGNO (operands[0]) != SP_REG"
4270  [(set (mem:SI (pre_dec:HI (reg:HI SP_REG)))
4271	(match_dup 0))]
4272  {
4273    operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]));
4274  })
4275
4276;; Convert a HImode push into an SImode push so that the
4277;; define_peephole2 below can cram multiple pushes into one stm.l.
4278
4279(define_peephole2
4280  [(parallel [(set (reg:SI SP_REG)
4281                   (plus:SI (reg:SI SP_REG) (const_int -4)))
4282              (set (mem:HI (plus:SI (reg:SI SP_REG) (const_int -2)))
4283                   (match_operand:HI 0 "register_operand" ""))])]
4284  "TARGET_H8300S && !TARGET_NORMAL_MODE && REGNO (operands[0]) != SP_REG"
4285  [(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
4286	(match_dup 0))]
4287  {
4288    operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]));
4289  })
4290
4291(define_peephole2
4292  [(parallel [(set (reg:HI SP_REG)
4293                   (plus:HI (reg:HI SP_REG) (const_int -4)))
4294              (set (mem:HI (plus:HI (reg:HI SP_REG) (const_int -2)))
4295                   (match_operand:HI 0 "register_operand" ""))])]
4296  "TARGET_H8300S && TARGET_NORMAL_MODE && REGNO (operands[0]) != SP_REG"
4297  [(set (mem:SI (pre_dec:HI (reg:HI SP_REG)))
4298	(match_dup 0))]
4299  {
4300    operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]));
4301  })
4302
4303;; Cram four pushes into stm.l.
4304
4305(define_peephole2
4306  [(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
4307	(match_operand:SI 0 "register_operand" ""))
4308   (set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
4309	(match_operand:SI 1 "register_operand" ""))
4310   (set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
4311	(match_operand:SI 2 "register_operand" ""))
4312   (set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
4313	(match_operand:SI 3 "register_operand" ""))]
4314  "TARGET_H8300S && !TARGET_NORMAL_MODE
4315   && (REGNO_REG_CLASS (REGNO (operands[3])) == GENERAL_REGS
4316       && REGNO (operands[1]) == REGNO (operands[0]) + 1
4317       && REGNO (operands[2]) == REGNO (operands[0]) + 2
4318       && REGNO (operands[3]) == REGNO (operands[0]) + 3
4319       && (TARGET_H8300SX || REGNO (operands[0]) == 0))"
4320  [(parallel [(set (mem:SI (plus:SI (reg:SI SP_REG) (const_int -4)))
4321		   (match_dup 0))
4322	      (set (mem:SI (plus:SI (reg:SI SP_REG) (const_int -8)))
4323		   (match_dup 1))
4324	      (set (mem:SI (plus:SI (reg:SI SP_REG) (const_int -12)))
4325		   (match_dup 2))
4326	      (set (mem:SI (plus:SI (reg:SI SP_REG) (const_int -16)))
4327		   (match_dup 3))
4328	      (set (reg:SI SP_REG)
4329		   (plus:SI (reg:SI SP_REG)
4330			    (const_int -16)))])]
4331  "")
4332
4333(define_peephole2
4334  [(set (mem:SI (pre_dec:HI (reg:HI SP_REG)))
4335	(match_operand:SI 0 "register_operand" ""))
4336   (set (mem:SI (pre_dec:HI (reg:HI SP_REG)))
4337	(match_operand:SI 1 "register_operand" ""))
4338   (set (mem:SI (pre_dec:HI (reg:HI SP_REG)))
4339	(match_operand:SI 2 "register_operand" ""))
4340   (set (mem:SI (pre_dec:HI (reg:HI SP_REG)))
4341	(match_operand:SI 3 "register_operand" ""))]
4342  "TARGET_H8300S && TARGET_NORMAL_MODE
4343   && (REGNO_REG_CLASS (REGNO (operands[3])) == GENERAL_REGS
4344       && REGNO (operands[1]) == REGNO (operands[0]) + 1
4345       && REGNO (operands[2]) == REGNO (operands[0]) + 2
4346       && REGNO (operands[3]) == REGNO (operands[0]) + 3
4347       && (TARGET_H8300SX || REGNO (operands[0]) == 0))"
4348  [(parallel [(set (mem:SI (plus:HI (reg:HI SP_REG) (const_int -4)))
4349		   (match_dup 0))
4350	      (set (mem:SI (plus:HI (reg:HI SP_REG) (const_int -8)))
4351		   (match_dup 1))
4352	      (set (mem:SI (plus:HI (reg:HI SP_REG) (const_int -12)))
4353		   (match_dup 2))
4354	      (set (mem:SI (plus:HI (reg:HI SP_REG) (const_int -16)))
4355		   (match_dup 3))
4356	      (set (reg:HI SP_REG)
4357		   (plus:HI (reg:HI SP_REG)
4358			    (const_int -16)))])]
4359  "")
4360
4361;; Cram three pushes into stm.l.
4362
4363(define_peephole2
4364  [(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
4365	(match_operand:SI 0 "register_operand" ""))
4366   (set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
4367	(match_operand:SI 1 "register_operand" ""))
4368   (set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
4369	(match_operand:SI 2 "register_operand" ""))]
4370  "TARGET_H8300S && !TARGET_NORMAL_MODE
4371   && (REGNO_REG_CLASS (REGNO (operands[2])) == GENERAL_REGS
4372       && REGNO (operands[1]) == REGNO (operands[0]) + 1
4373       && REGNO (operands[2]) == REGNO (operands[0]) + 2
4374       && (TARGET_H8300SX || (REGNO (operands[0]) & 3) == 0))"
4375  [(parallel [(set (mem:SI (plus:SI (reg:SI SP_REG) (const_int -4)))
4376		   (match_dup 0))
4377	      (set (mem:SI (plus:SI (reg:SI SP_REG) (const_int -8)))
4378		   (match_dup 1))
4379	      (set (mem:SI (plus:SI (reg:SI SP_REG) (const_int -12)))
4380		   (match_dup 2))
4381	      (set (reg:SI SP_REG)
4382		   (plus:SI (reg:SI SP_REG)
4383			    (const_int -12)))])]
4384  "")
4385
4386(define_peephole2
4387  [(set (mem:SI (pre_dec:HI (reg:HI SP_REG)))
4388	(match_operand:SI 0 "register_operand" ""))
4389   (set (mem:SI (pre_dec:HI (reg:HI SP_REG)))
4390	(match_operand:SI 1 "register_operand" ""))
4391   (set (mem:SI (pre_dec:HI (reg:HI SP_REG)))
4392	(match_operand:SI 2 "register_operand" ""))]
4393  "TARGET_H8300S && TARGET_NORMAL_MODE
4394   && (REGNO_REG_CLASS (REGNO (operands[2])) == GENERAL_REGS
4395       && REGNO (operands[1]) == REGNO (operands[0]) + 1
4396       && REGNO (operands[2]) == REGNO (operands[0]) + 2
4397       && (TARGET_H8300SX || (REGNO (operands[0]) & 3) == 0))"
4398  [(parallel [(set (mem:SI (plus:HI (reg:HI SP_REG) (const_int -4)))
4399		   (match_dup 0))
4400	      (set (mem:SI (plus:HI (reg:HI SP_REG) (const_int -8)))
4401		   (match_dup 1))
4402	      (set (mem:SI (plus:HI (reg:HI SP_REG) (const_int -12)))
4403		   (match_dup 2))
4404	      (set (reg:HI SP_REG)
4405		   (plus:HI (reg:HI SP_REG)
4406			    (const_int -12)))])]
4407  "")
4408
4409;; Cram two pushes into stm.l.
4410
4411(define_peephole2
4412  [(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
4413	(match_operand:SI 0 "register_operand" ""))
4414   (set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
4415	(match_operand:SI 1 "register_operand" ""))]
4416  "TARGET_H8300S && !TARGET_NORMAL_MODE
4417   && (REGNO_REG_CLASS (REGNO (operands[1])) == GENERAL_REGS
4418       && REGNO (operands[1]) == REGNO (operands[0]) + 1
4419       && (TARGET_H8300SX || (REGNO (operands[0]) & 1) == 0))"
4420  [(parallel [(set (mem:SI (plus:SI (reg:SI SP_REG) (const_int -4)))
4421		   (match_dup 0))
4422	      (set (mem:SI (plus:SI (reg:SI SP_REG) (const_int -8)))
4423		   (match_dup 1))
4424	      (set (reg:SI SP_REG)
4425		   (plus:SI (reg:SI SP_REG)
4426			    (const_int -8)))])]
4427  "")
4428
4429(define_peephole2
4430  [(set (mem:SI (pre_dec:HI (reg:HI SP_REG)))
4431	(match_operand:SI 0 "register_operand" ""))
4432   (set (mem:SI (pre_dec:HI (reg:HI SP_REG)))
4433	(match_operand:SI 1 "register_operand" ""))]
4434  "TARGET_H8300S && TARGET_NORMAL_MODE
4435   && (REGNO_REG_CLASS (REGNO (operands[1])) == GENERAL_REGS
4436       && REGNO (operands[1]) == REGNO (operands[0]) + 1
4437       && (TARGET_H8300SX || (REGNO (operands[0]) & 1) == 0))"
4438  [(parallel [(set (mem:SI (plus:HI (reg:HI SP_REG) (const_int -4)))
4439		   (match_dup 0))
4440	      (set (mem:SI (plus:HI (reg:HI SP_REG) (const_int -8)))
4441		   (match_dup 1))
4442	      (set (reg:HI SP_REG)
4443		   (plus:HI (reg:HI SP_REG)
4444			    (const_int -8)))])]
4445  "")
4446
4447;; Turn
4448;;
4449;;   mov.w #2,r0
4450;;   add.w r7,r0  (6 bytes)
4451;;
4452;; into
4453;;
4454;;   mov.w r7,r0
4455;;   adds  #2,r0  (4 bytes)
4456
4457(define_peephole2
4458  [(set (match_operand:HI 0 "register_operand" "")
4459	(match_operand:HI 1 "const_int_operand" ""))
4460   (set (match_dup 0)
4461	(plus:HI (match_dup 0)
4462		 (match_operand:HI 2 "register_operand" "")))]
4463  "REG_P (operands[0]) && REG_P (operands[2])
4464   && REGNO (operands[0]) != REGNO (operands[2])
4465   && (satisfies_constraint_J (operands[1])
4466       || satisfies_constraint_L (operands[1])
4467       || satisfies_constraint_N (operands[1]))"
4468  [(set (match_dup 0)
4469	(match_dup 2))
4470   (set (match_dup 0)
4471	(plus:HI (match_dup 0)
4472		 (match_dup 1)))]
4473  "")
4474
4475;; Turn
4476;;
4477;;   sub.l  er0,er0
4478;;   add.b  #4,r0l
4479;;   add.l  er7,er0  (6 bytes)
4480;;
4481;; into
4482;;
4483;;   mov.l  er7,er0
4484;;   adds   #4,er0   (4 bytes)
4485
4486(define_peephole2
4487  [(set (match_operand:SI 0 "register_operand" "")
4488	(match_operand:SI 1 "const_int_operand" ""))
4489   (set (match_dup 0)
4490	(plus:SI (match_dup 0)
4491		 (match_operand:SI 2 "register_operand" "")))]
4492  "(TARGET_H8300H || TARGET_H8300S)
4493    && REG_P (operands[0]) && REG_P (operands[2])
4494    && REGNO (operands[0]) != REGNO (operands[2])
4495    && (satisfies_constraint_L (operands[1])
4496	|| satisfies_constraint_N (operands[1]))"
4497  [(set (match_dup 0)
4498	(match_dup 2))
4499   (set (match_dup 0)
4500	(plus:SI (match_dup 0)
4501		 (match_dup 1)))]
4502  "")
4503
4504;; Turn
4505;;
4506;;   mov.l er7,er0
4507;;   add.l #10,er0  (takes 8 bytes)
4508;;
4509;; into
4510;;
4511;;   sub.l er0,er0
4512;;   add.b #10,r0l
4513;;   add.l er7,er0  (takes 6 bytes)
4514
4515(define_peephole2
4516  [(set (match_operand:SI 0 "register_operand" "")
4517	(match_operand:SI 1 "register_operand" ""))
4518   (set (match_dup 0)
4519	(plus:SI (match_dup 0)
4520		 (match_operand:SI 2 "const_int_operand" "")))]
4521  "(TARGET_H8300H || TARGET_H8300S)
4522    && REG_P (operands[0]) && REG_P (operands[1])
4523    && REGNO (operands[0]) != REGNO (operands[1])
4524    && !satisfies_constraint_L (operands[2])
4525    && !satisfies_constraint_N (operands[2])
4526    && ((INTVAL (operands[2]) & 0xff) == INTVAL (operands[2])
4527	|| (INTVAL (operands[2]) & 0xff00) == INTVAL (operands[2])
4528	|| INTVAL (operands[2]) == 0xffff
4529	|| INTVAL (operands[2]) == 0xfffe)"
4530  [(set (match_dup 0)
4531	(match_dup 2))
4532   (set (match_dup 0)
4533	(plus:SI (match_dup 0)
4534		 (match_dup 1)))]
4535  "")
4536
4537;; Turn
4538;;
4539;;   subs   #1,er4
4540;;   mov.w  r4,r4
4541;;   bne    .L2028
4542;;
4543;; into
4544;;
4545;;   dec.w  #1,r4
4546;;   bne    .L2028
4547
4548(define_peephole2
4549  [(set (match_operand:HI 0 "register_operand" "")
4550	(plus:HI (match_dup 0)
4551		 (match_operand 1 "incdec_operand" "")))
4552   (set (cc0) (compare (match_dup 0)
4553		       (const_int 0)))
4554   (set (pc)
4555	(if_then_else (match_operator 3 "eqne_operator"
4556		       [(cc0) (const_int 0)])
4557		      (label_ref (match_operand 2 "" ""))
4558		      (pc)))]
4559  "TARGET_H8300H || TARGET_H8300S"
4560  [(set (match_operand:HI 0 "register_operand" "")
4561	(unspec:HI [(match_dup 0)
4562		    (match_dup 1)]
4563		   UNSPEC_INCDEC))
4564   (set (cc0) (compare (match_dup 0)
4565		       (const_int 0)))
4566   (set (pc)
4567	(if_then_else (match_op_dup 3 [(cc0) (const_int 0)])
4568		      (label_ref (match_dup 2))
4569		      (pc)))]
4570  "")
4571
4572;; The SImode version of the previous pattern.
4573
4574(define_peephole2
4575  [(set (match_operand:SI 0 "register_operand" "")
4576	(plus:SI (match_dup 0)
4577		 (match_operand 1 "incdec_operand" "")))
4578   (set (cc0) (compare (match_dup 0)
4579		       (const_int 0)))
4580   (set (pc)
4581	(if_then_else (match_operator 3 "eqne_operator"
4582		       [(cc0) (const_int 0)])
4583		      (label_ref (match_operand 2 "" ""))
4584		      (pc)))]
4585  "TARGET_H8300H || TARGET_H8300S"
4586  [(set (match_operand:SI 0 "register_operand" "")
4587	(unspec:SI [(match_dup 0)
4588		    (match_dup 1)]
4589		   UNSPEC_INCDEC))
4590   (set (cc0) (compare (match_dup 0)
4591		       (const_int 0)))
4592   (set (pc)
4593	(if_then_else (match_op_dup 3 [(cc0) (const_int 0)])
4594		      (label_ref (match_dup 2))
4595		      (pc)))]
4596  "")
4597
4598(define_peephole2
4599  [(parallel [(set (cc0)
4600		   (compare (zero_extract:SI (match_operand:QI 0 "register_operand" "")
4601					     (const_int 1)
4602					     (const_int 7))
4603			    (const_int 0)))
4604	      (clobber (scratch:QI))])
4605   (set (pc)
4606	(if_then_else (match_operator 1 "eqne_operator"
4607		       [(cc0) (const_int 0)])
4608		      (label_ref (match_operand 2 "" ""))
4609		      (pc)))]
4610  "TARGET_H8300H || TARGET_H8300S"
4611  [(set (cc0) (compare (match_dup 0)
4612		       (const_int 0)))
4613   (set (pc)
4614	(if_then_else (match_op_dup 3 [(cc0) (const_int 0)])
4615		      (label_ref (match_dup 2))
4616		      (pc)))]
4617  {
4618    operands[3] = ((GET_CODE (operands[1]) == EQ)
4619		   ? gen_rtx_GE (VOIDmode, cc0_rtx, const0_rtx)
4620		   : gen_rtx_LT (VOIDmode, cc0_rtx, const0_rtx));
4621  })
4622
4623;; The next three peephole2's will try to transform
4624;;
4625;;   mov.b A,r0l    (or mov.l A,er0)
4626;;   and.l #CST,er0
4627;;
4628;; into
4629;;
4630;;   sub.l er0
4631;;   mov.b A,r0l
4632;;   and.b #CST,r0l (if CST is not 255)
4633
4634(define_peephole2
4635  [(set (match_operand:QI 0 "register_operand" "")
4636	(match_operand:QI 1 "general_operand" ""))
4637   (set (match_operand:SI 2 "register_operand" "")
4638	(and:SI (match_dup 2)
4639		(const_int 255)))]
4640  "(TARGET_H8300H || TARGET_H8300S)
4641    && !reg_overlap_mentioned_p (operands[2], operands[1])
4642    && REGNO (operands[0]) == REGNO (operands[2])"
4643  [(set (match_dup 2)
4644	(const_int 0))
4645   (set (strict_low_part (match_dup 0))
4646	(match_dup 1))]
4647  "")
4648
4649(define_peephole2
4650  [(set (match_operand:SI 0 "register_operand" "")
4651	(match_operand:SI 1 "nonimmediate_operand" ""))
4652   (set (match_dup 0)
4653	(and:SI (match_dup 0)
4654		(const_int 255)))]
4655  "(TARGET_H8300H || TARGET_H8300S)
4656    && !reg_overlap_mentioned_p (operands[0], operands[1])
4657    && !(GET_CODE (operands[1]) == MEM && !offsettable_memref_p (operands[1]))
4658    && !(GET_CODE (operands[1]) == MEM && MEM_VOLATILE_P (operands[1]))"
4659  [(set (match_dup 0)
4660	(const_int 0))
4661   (set (strict_low_part (match_dup 2))
4662	(match_dup 3))]
4663  {
4664    operands[2] = gen_lowpart (QImode, operands[0]);
4665    operands[3] = gen_lowpart (QImode, operands[1]);
4666  })
4667
4668(define_peephole2
4669  [(set (match_operand 0 "register_operand" "")
4670	(match_operand 1 "nonimmediate_operand" ""))
4671   (set (match_operand:SI 2 "register_operand" "")
4672	(and:SI (match_dup 2)
4673		(match_operand:SI 3 "const_int_qi_operand" "")))]
4674  "(TARGET_H8300H || TARGET_H8300S)
4675    && (GET_MODE (operands[0]) == QImode
4676	|| GET_MODE (operands[0]) == HImode
4677	|| GET_MODE (operands[0]) == SImode)
4678    && GET_MODE (operands[0]) == GET_MODE (operands[1])
4679    && REGNO (operands[0]) == REGNO (operands[2])
4680    && !reg_overlap_mentioned_p (operands[2], operands[1])
4681    && !(GET_MODE (operands[1]) != QImode
4682	 && GET_CODE (operands[1]) == MEM
4683	 && !offsettable_memref_p (operands[1]))
4684    && !(GET_MODE (operands[1]) != QImode
4685	 && GET_CODE (operands[1]) == MEM
4686	 && MEM_VOLATILE_P (operands[1]))"
4687  [(set (match_dup 2)
4688	(const_int 0))
4689   (set (strict_low_part (match_dup 4))
4690	(match_dup 5))
4691   (set (match_dup 2)
4692	(and:SI (match_dup 2)
4693		(match_dup 6)))]
4694  {
4695    operands[4] = gen_lowpart (QImode, operands[0]);
4696    operands[5] = gen_lowpart (QImode, operands[1]);
4697    operands[6] = GEN_INT (~0xff | INTVAL (operands[3]));
4698  })
4699
4700(define_peephole2
4701  [(set (match_operand:SI 0 "register_operand" "")
4702	(match_operand:SI 1 "register_operand" ""))
4703   (set (match_dup 0)
4704	(and:SI (match_dup 0)
4705		(const_int 65280)))]
4706  "(TARGET_H8300H || TARGET_H8300S)
4707   && !reg_overlap_mentioned_p (operands[0], operands[1])"
4708  [(set (match_dup 0)
4709	(const_int 0))
4710   (set (zero_extract:SI (match_dup 0)
4711			 (const_int 8)
4712			 (const_int 8))
4713	(lshiftrt:SI (match_dup 1)
4714		     (const_int 8)))]
4715  "")
4716
4717;; If a load of mem:SI is followed by an AND that turns off the upper
4718;; half, then we can load mem:HI instead.
4719
4720(define_peephole2
4721  [(set (match_operand:SI 0 "register_operand" "")
4722	(match_operand:SI 1 "memory_operand" ""))
4723   (set (match_dup 0)
4724	(and:SI (match_dup 0)
4725		(match_operand:SI 2 "const_int_operand" "")))]
4726  "(TARGET_H8300H || TARGET_H8300S)
4727    && !MEM_VOLATILE_P (operands[1])
4728    && offsettable_memref_p (operands[1])
4729    && (INTVAL (operands[2]) & ~0xffff) == 0
4730    && INTVAL (operands[2]) != 255"
4731  [(set (match_dup 3)
4732	(match_dup 4))
4733   (set (match_dup 0)
4734	(and:SI (match_dup 0)
4735		(match_dup 2)))]
4736  {
4737    operands[3] = gen_lowpart (HImode, operands[0]);
4738    operands[4] = gen_lowpart (HImode, operands[1]);
4739  })
4740
4741;; Convert a memory comparison to a move if there is a scratch register.
4742
4743(define_peephole2
4744  [(match_scratch:QI 1 "r")
4745   (set (cc0)
4746	(compare (match_operand:QI 0 "memory_operand" "")
4747		 (const_int 0)))]
4748  ""
4749  [(set (match_dup 1)
4750	(match_dup 0))
4751   (set (cc0) (compare (match_dup 1)
4752		       (const_int 0)))]
4753  "")
4754
4755(define_peephole2
4756  [(match_scratch:HI 1 "r")
4757   (set (cc0)
4758	(compare (match_operand:HI 0 "memory_operand" "")
4759		 (const_int 0)))]
4760  "TARGET_H8300H || TARGET_H8300S"
4761  [(set (match_dup 1)
4762	(match_dup 0))
4763   (set (cc0) (compare (match_dup 1)
4764		       (const_int 0)))]
4765  "")
4766
4767(define_peephole2
4768  [(match_scratch:SI 1 "r")
4769   (set (cc0)
4770	(compare (match_operand:SI 0 "memory_operand" "")
4771		 (const_int 0)))]
4772  "TARGET_H8300H || TARGET_H8300S"
4773  [(set (match_dup 1)
4774	(match_dup 0))
4775   (set (cc0) (compare (match_dup 1)
4776		       (const_int 0)))]
4777  "")
4778
4779
4780;; (compare (reg:HI) (const_int)) takes 4 bytes, so we try to achieve
4781;; the equivalent with shorter sequences.  Here is the summary.  Cases
4782;; are grouped for each define_peephole2.
4783;;
4784;; reg  const_int                   use     insn
4785;; --------------------------------------------------------
4786;; dead    -2                       eq/ne   inc.l
4787;; dead    -1                       eq/ne   inc.l
4788;; dead     1                       eq/ne   dec.l
4789;; dead     2                       eq/ne   dec.l
4790;;
4791;; dead     1                       ge/lt shar.l
4792;; dead     3 (H8S)                 ge/lt shar.l
4793;;
4794;; dead     1                       geu/ltu shar.l
4795;; dead     3 (H8S)                 geu/ltu shar.l
4796;;
4797;; ----   255                       ge/lt mov.b
4798;;
4799;; ----   255                       geu/ltu mov.b
4800
4801;; Transform
4802;;
4803;;	cmp.w	#1,r0
4804;;	bne	.L1
4805;;
4806;; into
4807;;
4808;;	dec.w	#1,r0
4809;;	bne	.L1
4810
4811(define_peephole2
4812  [(set (cc0)
4813	(compare (match_operand:HI 0 "register_operand" "")
4814		 (match_operand:HI 1 "incdec_operand" "")))
4815   (set (pc)
4816	(if_then_else (match_operator 3 "eqne_operator"
4817		       [(cc0) (const_int 0)])
4818		      (label_ref (match_operand 2 "" ""))
4819		      (pc)))]
4820  "(TARGET_H8300H || TARGET_H8300S)
4821    && INTVAL (operands[1]) != 0
4822    && peep2_reg_dead_p (1, operands[0])"
4823  [(set (match_dup 0)
4824	(unspec:HI [(match_dup 0)
4825		    (match_dup 4)]
4826		   UNSPEC_INCDEC))
4827   (set (cc0) (compare (match_dup 0)
4828		       (const_int 0)))
4829   (set (pc)
4830	(if_then_else (match_op_dup 3 [(cc0) (const_int 0)])
4831		      (label_ref (match_dup 2))
4832		      (pc)))]
4833  {
4834    operands[4] = GEN_INT (- INTVAL (operands[1]));
4835  })
4836
4837;; Transform
4838;;
4839;;	cmp.w	#1,r0
4840;;	bgt	.L1
4841;;
4842;; into
4843;;
4844;;	shar.w	r0
4845;;	bgt	.L1
4846
4847(define_peephole2
4848  [(set (cc0)
4849	(compare (match_operand:HI 0 "register_operand" "")
4850		 (match_operand:HI 1 "const_int_operand" "")))
4851   (set (pc)
4852	(if_then_else (match_operator 2 "gtle_operator"
4853		       [(cc0) (const_int 0)])
4854		      (label_ref (match_operand 3 "" ""))
4855		      (pc)))]
4856  "(TARGET_H8300H || TARGET_H8300S)
4857    && peep2_reg_dead_p (1, operands[0])
4858    && (INTVAL (operands[1]) == 1
4859	|| (TARGET_H8300S && INTVAL (operands[1]) == 3))"
4860  [(parallel [(set (match_dup 0)
4861		   (ashiftrt:HI (match_dup 0)
4862				(match_dup 4)))
4863	      (clobber (scratch:QI))])
4864   (set (cc0) (compare (match_dup 0)
4865		       (const_int 0)))
4866   (set (pc)
4867	(if_then_else (match_dup 2)
4868		      (label_ref (match_dup 3))
4869		      (pc)))]
4870  {
4871    operands[4] = GEN_INT (exact_log2 (INTVAL (operands[1]) + 1));
4872  })
4873
4874;; Transform
4875;;
4876;;	cmp.w	#1,r0
4877;;	bhi	.L1
4878;;
4879;; into
4880;;
4881;;	shar.w	r0
4882;;	bne	.L1
4883
4884(define_peephole2
4885  [(set (cc0)
4886	(compare (match_operand:HI 0 "register_operand" "")
4887		 (match_operand:HI 1 "const_int_operand" "")))
4888   (set (pc)
4889	(if_then_else (match_operator 2 "gtuleu_operator"
4890		       [(cc0) (const_int 0)])
4891		      (label_ref (match_operand 3 "" ""))
4892		      (pc)))]
4893  "(TARGET_H8300H || TARGET_H8300S)
4894    && peep2_reg_dead_p (1, operands[0])
4895    && (INTVAL (operands[1]) == 1
4896	|| (TARGET_H8300S && INTVAL (operands[1]) == 3))"
4897  [(parallel [(set (match_dup 0)
4898		   (ashiftrt:HI (match_dup 0)
4899				(match_dup 4)))
4900	      (clobber (scratch:QI))])
4901   (set (cc0) (compare (match_dup 0)
4902		       (const_int 0)))
4903   (set (pc)
4904	(if_then_else (match_dup 5)
4905		      (label_ref (match_dup 3))
4906		      (pc)))]
4907  {
4908    operands[4] = GEN_INT (exact_log2 (INTVAL (operands[1]) + 1));
4909    operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[2]) == GTU ? NE : EQ,
4910				  VOIDmode, cc0_rtx, const0_rtx);
4911  })
4912
4913;; Transform
4914;;
4915;;	cmp.w	#255,r0
4916;;	bgt	.L1
4917;;
4918;; into
4919;;
4920;;	mov.b	r0h,r0h
4921;;	bgt	.L1
4922
4923(define_peephole2
4924  [(set (cc0)
4925	(compare (match_operand:HI 0 "register_operand" "")
4926		 (const_int 255)))
4927   (set (pc)
4928	(if_then_else (match_operator 1 "gtle_operator"
4929		       [(cc0) (const_int 0)])
4930		      (label_ref (match_operand 2 "" ""))
4931		      (pc)))]
4932  "TARGET_H8300H || TARGET_H8300S"
4933  [(set (cc0) (compare (and:HI (match_dup 0)
4934			       (const_int -256))
4935		       (const_int 0)))
4936   (set (pc)
4937	(if_then_else (match_dup 1)
4938		      (label_ref (match_dup 2))
4939		      (pc)))]
4940  "")
4941
4942;; Transform
4943;;
4944;;	cmp.w	#255,r0
4945;;	bhi	.L1
4946;;
4947;; into
4948;;
4949;;	mov.b	r0h,r0h
4950;;	bne	.L1
4951
4952(define_peephole2
4953  [(set (cc0)
4954	(compare (match_operand:HI 0 "register_operand" "")
4955		 (const_int 255)))
4956   (set (pc)
4957	(if_then_else (match_operator 1 "gtuleu_operator"
4958		       [(cc0) (const_int 0)])
4959		      (label_ref (match_operand 2 "" ""))
4960		      (pc)))]
4961  "TARGET_H8300H || TARGET_H8300S"
4962  [(set (cc0) (compare (and:HI (match_dup 0)
4963			       (const_int -256))
4964		       (const_int 0)))
4965   (set (pc)
4966	(if_then_else (match_dup 3)
4967		      (label_ref (match_dup 2))
4968		      (pc)))]
4969  {
4970    operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[1]) == GTU ? NE : EQ,
4971				  VOIDmode, cc0_rtx, const0_rtx);
4972  })
4973
4974;; (compare (reg:SI) (const_int)) takes 6 bytes, so we try to achieve
4975;; the equivalent with shorter sequences.  Here is the summary.  Cases
4976;; are grouped for each define_peephole2.
4977;;
4978;; reg  const_int                   use     insn
4979;; --------------------------------------------------------
4980;; live    -2                       eq/ne   copy and inc.l
4981;; live    -1                       eq/ne   copy and inc.l
4982;; live     1                       eq/ne   copy and dec.l
4983;; live     2                       eq/ne   copy and dec.l
4984;;
4985;; dead    -2                       eq/ne   inc.l
4986;; dead    -1                       eq/ne   inc.l
4987;; dead     1                       eq/ne   dec.l
4988;; dead     2                       eq/ne   dec.l
4989;;
4990;; dead -131072                     eq/ne   inc.w and test
4991;; dead  -65536                     eq/ne   inc.w and test
4992;; dead   65536                     eq/ne   dec.w and test
4993;; dead  131072                     eq/ne   dec.w and test
4994;;
4995;; dead 0x000000?? except 1 and 2   eq/ne   xor.b and test
4996;; dead 0x0000??00                  eq/ne   xor.b and test
4997;; dead 0x0000ffff                  eq/ne   not.w and test
4998;;
4999;; dead 0xffffff?? except -1 and -2 eq/ne   xor.b and not.l
5000;; dead 0xffff??ff                  eq/ne   xor.b and not.l
5001;; dead 0x40000000 (H8S)            eq/ne   rotl.l and dec.l
5002;; dead 0x80000000                  eq/ne   rotl.l and dec.l
5003;;
5004;; live     1                       ge/lt copy and shar.l
5005;; live     3 (H8S)                 ge/lt copy and shar.l
5006;;
5007;; live     1                       geu/ltu copy and shar.l
5008;; live     3 (H8S)                 geu/ltu copy and shar.l
5009;;
5010;; dead     1                       ge/lt shar.l
5011;; dead     3 (H8S)                 ge/lt shar.l
5012;;
5013;; dead     1                       geu/ltu shar.l
5014;; dead     3 (H8S)                 geu/ltu shar.l
5015;;
5016;; dead     3 (H8/300H)             ge/lt and.b and test
5017;; dead     7                       ge/lt and.b and test
5018;; dead    15                       ge/lt and.b and test
5019;; dead    31                       ge/lt and.b and test
5020;; dead    63                       ge/lt and.b and test
5021;; dead   127                       ge/lt and.b and test
5022;; dead   255                       ge/lt and.b and test
5023;;
5024;; dead     3 (H8/300H)             geu/ltu and.b and test
5025;; dead     7                       geu/ltu and.b and test
5026;; dead    15                       geu/ltu and.b and test
5027;; dead    31                       geu/ltu and.b and test
5028;; dead    63                       geu/ltu and.b and test
5029;; dead   127                       geu/ltu and.b and test
5030;; dead   255                       geu/ltu and.b and test
5031;;
5032;; ---- 65535                       ge/lt mov.w
5033;;
5034;; ---- 65535                       geu/ltu mov.w
5035
5036;; Transform
5037;;
5038;;	cmp.l	#1,er0
5039;;	beq	.L1
5040;;
5041;; into
5042;;
5043;;	dec.l	#1,er0
5044;;	beq	.L1
5045
5046(define_peephole2
5047  [(set (cc0)
5048	(compare (match_operand:SI 0 "register_operand" "")
5049		 (match_operand:SI 1 "incdec_operand" "")))
5050   (set (pc)
5051	(if_then_else (match_operator 3 "eqne_operator"
5052		       [(cc0) (const_int 0)])
5053		      (label_ref (match_operand 2 "" ""))
5054		      (pc)))]
5055  "(TARGET_H8300H || TARGET_H8300S)
5056    && INTVAL (operands[1]) != 0
5057    && peep2_reg_dead_p (1, operands[0])"
5058  [(set (match_dup 0)
5059	(unspec:SI [(match_dup 0)
5060		    (match_dup 4)]
5061		   UNSPEC_INCDEC))
5062   (set (cc0) (compare (match_dup 0)
5063		       (const_int 0)))
5064   (set (pc)
5065	(if_then_else (match_op_dup 3 [(cc0) (const_int 0)])
5066		      (label_ref (match_dup 2))
5067		      (pc)))]
5068  {
5069    operands[4] = GEN_INT (- INTVAL (operands[1]));
5070  })
5071
5072;; Transform
5073;;
5074;;	cmp.l	#65536,er0
5075;;	beq	.L1
5076;;
5077;; into
5078;;
5079;;	dec.l	#1,e0
5080;;	beq	.L1
5081
5082(define_peephole2
5083  [(set (cc0)
5084	(compare (match_operand:SI 0 "register_operand" "")
5085		 (match_operand:SI 1 "const_int_operand" "")))
5086   (set (pc)
5087	(if_then_else (match_operator 3 "eqne_operator"
5088		       [(cc0) (const_int 0)])
5089		      (label_ref (match_operand 2 "" ""))
5090		      (pc)))]
5091  "(TARGET_H8300H || TARGET_H8300S)
5092    && peep2_reg_dead_p (1, operands[0])
5093    && (INTVAL (operands[1]) == -131072
5094	|| INTVAL (operands[1]) == -65536
5095	|| INTVAL (operands[1]) == 65536
5096	|| INTVAL (operands[1]) == 131072)"
5097  [(set (match_dup 0)
5098	(plus:SI (match_dup 0)
5099		 (match_dup 4)))
5100   (set (cc0) (compare (match_dup 0)
5101		       (const_int 0)))
5102   (set (pc)
5103	(if_then_else (match_op_dup 3 [(cc0) (const_int 0)])
5104		      (label_ref (match_dup 2))
5105		      (pc)))]
5106  {
5107    operands[4] = GEN_INT (- INTVAL (operands[1]));
5108  })
5109
5110;; Transform
5111;;
5112;;	cmp.l	#100,er0
5113;;	beq	.L1
5114;;
5115;; into
5116;;
5117;;	xor.b	#100,er0
5118;;	mov.l	er0,er0
5119;;	beq	.L1
5120
5121(define_peephole2
5122  [(set (cc0)
5123	(compare (match_operand:SI 0 "register_operand" "")
5124		 (match_operand:SI 1 "const_int_operand" "")))
5125   (set (pc)
5126	(if_then_else (match_operator 3 "eqne_operator"
5127		       [(cc0) (const_int 0)])
5128		      (label_ref (match_operand 2 "" ""))
5129		      (pc)))]
5130  "(TARGET_H8300H || TARGET_H8300S)
5131    && peep2_reg_dead_p (1, operands[0])
5132    && ((INTVAL (operands[1]) & 0x00ff) == INTVAL (operands[1])
5133	|| (INTVAL (operands[1]) & 0xff00) == INTVAL (operands[1])
5134	|| INTVAL (operands[1]) == 0x0000ffff)
5135    && INTVAL (operands[1]) != 0
5136    && INTVAL (operands[1]) != 1
5137    && INTVAL (operands[1]) != 2"
5138  [(set (match_dup 0)
5139	(xor:SI (match_dup 0)
5140		(match_dup 1)))
5141   (set (cc0) (compare (match_dup 0)
5142		       (const_int 0)))
5143   (set (pc)
5144	(if_then_else (match_op_dup 3 [(cc0) (const_int 0)])
5145		      (label_ref (match_dup 2))
5146		      (pc)))]
5147  "")
5148
5149;; Transform
5150;;
5151;;	cmp.l	#-100,er0
5152;;	beq	.L1
5153;;
5154;; into
5155;;
5156;;	xor.b	#99,er0
5157;;	not.l	er0
5158;;	beq	.L1
5159
5160(define_peephole2
5161  [(set (cc0)
5162	(compare (match_operand:SI 0 "register_operand" "")
5163		 (match_operand:SI 1 "const_int_operand" "")))
5164   (set (pc)
5165	(if_then_else (match_operator 3 "eqne_operator"
5166		       [(cc0) (const_int 0)])
5167		      (label_ref (match_operand 2 "" ""))
5168		      (pc)))]
5169  "(TARGET_H8300H || TARGET_H8300S)
5170    && peep2_reg_dead_p (1, operands[0])
5171    && ((INTVAL (operands[1]) | 0x00ff) == -1
5172	|| (INTVAL (operands[1]) | 0xff00) == -1)
5173    && INTVAL (operands[1]) != -1
5174    && INTVAL (operands[1]) != -2"
5175  [(set (match_dup 0)
5176	(xor:SI (match_dup 0)
5177		(match_dup 4)))
5178   (set (match_dup 0)
5179	(not:SI (match_dup 0)))
5180   (set (cc0) (compare (match_dup 0)
5181		       (const_int 0)))
5182   (set (pc)
5183	(if_then_else (match_op_dup 3 [(cc0) (const_int 0)])
5184		      (label_ref (match_dup 2))
5185		      (pc)))]
5186  {
5187    operands[4] = GEN_INT (INTVAL (operands[1]) ^ -1);
5188  })
5189
5190;; Transform
5191;;
5192;;	cmp.l	#-2147483648,er0
5193;;	beq	.L1
5194;;
5195;; into
5196;;
5197;;	rotl.l	er0
5198;;	dec.l	#1,er0
5199;;	beq	.L1
5200
5201(define_peephole2
5202  [(set (cc0)
5203	(compare (match_operand:SI 0 "register_operand" "")
5204		 (match_operand:SI 1 "const_int_operand" "")))
5205   (set (pc)
5206	(if_then_else (match_operator 3 "eqne_operator"
5207		       [(cc0) (const_int 0)])
5208		      (label_ref (match_operand 2 "" ""))
5209		      (pc)))]
5210  "(TARGET_H8300H || TARGET_H8300S)
5211    && peep2_reg_dead_p (1, operands[0])
5212    && (INTVAL (operands[1]) == -2147483647 - 1
5213	|| (TARGET_H8300S && INTVAL (operands[1]) == 1073741824))"
5214  [(set (match_dup 0)
5215	(rotate:SI (match_dup 0)
5216		   (match_dup 4)))
5217   (set (match_dup 0)
5218	(unspec:SI [(match_dup 0)
5219		    (const_int -1)]
5220		   UNSPEC_INCDEC))
5221   (set (cc0) (compare (match_dup 0)
5222		       (const_int 0)))
5223   (set (pc)
5224	(if_then_else (match_op_dup 3 [(cc0) (const_int 0)])
5225		      (label_ref (match_dup 2))
5226		      (pc)))]
5227  {
5228    operands[4] = GEN_INT (INTVAL (operands[1]) == -2147483647 - 1 ? 1 : 2);
5229  })
5230
5231;; Transform
5232;;
5233;;	cmp.l	#1,er0
5234;;	bgt	.L1
5235;;
5236;; into
5237;;
5238;;	mov.l	er0,er1
5239;;	shar.l	er1
5240;;	bgt	.L1
5241
5242;; We avoid this transformation if we see more than one copy of the
5243;; same compare insn immediately before this one.
5244
5245(define_peephole2
5246  [(match_scratch:SI 4 "r")
5247   (set (cc0)
5248	(compare (match_operand:SI 0 "register_operand" "")
5249		 (match_operand:SI 1 "const_int_operand" "")))
5250   (set (pc)
5251	(if_then_else (match_operator 2 "gtle_operator"
5252		       [(cc0) (const_int 0)])
5253		      (label_ref (match_operand 3 "" ""))
5254		      (pc)))]
5255  "(TARGET_H8300H || TARGET_H8300S)
5256    && !peep2_reg_dead_p (1, operands[0])
5257    && (INTVAL (operands[1]) == 1
5258	|| (TARGET_H8300S && INTVAL (operands[1]) == 3))
5259    && !same_cmp_preceding_p (insn)"
5260  [(set (match_dup 4)
5261	(match_dup 0))
5262   (parallel [(set (match_dup 4)
5263		   (ashiftrt:SI (match_dup 4)
5264				(match_dup 5)))
5265	      (clobber (scratch:QI))])
5266   (set (cc0) (compare (match_dup 4)
5267		       (const_int 0)))
5268   (set (pc)
5269	(if_then_else (match_dup 2)
5270		      (label_ref (match_dup 3))
5271		      (pc)))]
5272  {
5273    operands[5] = GEN_INT (exact_log2 (INTVAL (operands[1]) + 1));
5274  })
5275
5276;; Transform
5277;;
5278;;	cmp.l	#1,er0
5279;;	bhi	.L1
5280;;
5281;; into
5282;;
5283;;	mov.l	er0,er1
5284;;	shar.l	er1
5285;;	bne	.L1
5286
5287;; We avoid this transformation if we see more than one copy of the
5288;; same compare insn immediately before this one.
5289
5290(define_peephole2
5291  [(match_scratch:SI 4 "r")
5292   (set (cc0)
5293	(compare (match_operand:SI 0 "register_operand" "")
5294		 (match_operand:SI 1 "const_int_operand" "")))
5295   (set (pc)
5296	(if_then_else (match_operator 2 "gtuleu_operator"
5297		         [(cc0) (const_int 0)])
5298		      (label_ref (match_operand 3 "" ""))
5299		      (pc)))]
5300  "(TARGET_H8300H || TARGET_H8300S)
5301    && !peep2_reg_dead_p (1, operands[0])
5302    && (INTVAL (operands[1]) == 1
5303	|| (TARGET_H8300S && INTVAL (operands[1]) == 3))
5304    && !same_cmp_preceding_p (insn)"
5305  [(set (match_dup 4)
5306	(match_dup 0))
5307   (parallel [(set (match_dup 4)
5308		   (ashiftrt:SI (match_dup 4)
5309				(match_dup 5)))
5310	      (clobber (scratch:QI))])
5311   (set (cc0) (compare (match_dup 4)
5312		       (const_int 0)))
5313   (set (pc)
5314	(if_then_else (match_dup 6)
5315		      (label_ref (match_dup 3))
5316		      (pc)))]
5317  {
5318    operands[5] = GEN_INT (exact_log2 (INTVAL (operands[1]) + 1));
5319    operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[2]) == GTU ? NE : EQ,
5320				  VOIDmode, cc0_rtx, const0_rtx);
5321  })
5322
5323;; Transform
5324;;
5325;;	cmp.l	#1,er0
5326;;	bgt	.L1
5327;;
5328;; into
5329;;
5330;;	shar.l	er0
5331;;	bgt	.L1
5332
5333(define_peephole2
5334  [(set (cc0)
5335	(compare (match_operand:SI 0 "register_operand" "")
5336		 (match_operand:SI 1 "const_int_operand" "")))
5337   (set (pc)
5338	(if_then_else (match_operator 2 "gtle_operator"
5339		       [(cc0) (const_int 0)])
5340		      (label_ref (match_operand 3 "" ""))
5341		      (pc)))]
5342  "(TARGET_H8300H || TARGET_H8300S)
5343    && peep2_reg_dead_p (1, operands[0])
5344    && (INTVAL (operands[1]) == 1
5345        || (TARGET_H8300S && INTVAL (operands[1]) == 3))"
5346  [(parallel [(set (match_dup 0)
5347		   (ashiftrt:SI (match_dup 0)
5348				(match_dup 4)))
5349	      (clobber (scratch:QI))])
5350   (set (cc0) (compare (match_dup 0)
5351		       (const_int 0)))
5352   (set (pc)
5353	(if_then_else (match_dup 2)
5354		      (label_ref (match_dup 3))
5355		      (pc)))]
5356  {
5357    operands[4] = GEN_INT (exact_log2 (INTVAL (operands[1]) + 1));
5358  })
5359
5360;; Transform
5361;;
5362;;	cmp.l	#1,er0
5363;;	bhi	.L1
5364;;
5365;; into
5366;;
5367;;	shar.l	er0
5368;;	bne	.L1
5369
5370(define_peephole2
5371  [(set (cc0)
5372	(compare (match_operand:SI 0 "register_operand" "")
5373		 (match_operand:SI 1 "const_int_operand" "")))
5374   (set (pc)
5375	(if_then_else (match_operator 2 "gtuleu_operator"
5376		       [(cc0) (const_int 0)])
5377		      (label_ref (match_operand 3 "" ""))
5378		      (pc)))]
5379  "(TARGET_H8300H || TARGET_H8300S)
5380    && peep2_reg_dead_p (1, operands[0])
5381    && (INTVAL (operands[1]) == 1
5382	|| (TARGET_H8300S && INTVAL (operands[1]) == 3))"
5383  [(parallel [(set (match_dup 0)
5384		   (ashiftrt:SI (match_dup 0)
5385				(match_dup 4)))
5386	      (clobber (scratch:QI))])
5387   (set (cc0) (compare (match_dup 0)
5388		       (const_int 0)))
5389   (set (pc)
5390	(if_then_else (match_dup 5)
5391		      (label_ref (match_dup 3))
5392		      (pc)))]
5393  {
5394    operands[4] = GEN_INT (exact_log2 (INTVAL (operands[1]) + 1));
5395    operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[2]) == GTU ? NE : EQ,
5396				  VOIDmode, cc0_rtx, const0_rtx);
5397  })
5398
5399;; Transform
5400;;
5401;;	cmp.l	#15,er0
5402;;	bgt	.L1
5403;;
5404;; into
5405;;
5406;;	and	#240,r0l
5407;;	mov.l	er0,er0
5408;;	bgt	.L1
5409
5410(define_peephole2
5411  [(set (cc0)
5412	(compare (match_operand:SI 0 "register_operand" "")
5413		 (match_operand:SI 1 "const_int_operand" "")))
5414   (set (pc)
5415	(if_then_else (match_operator 2 "gtle_operator"
5416		       [(cc0) (const_int 0)])
5417		      (label_ref (match_operand 3 "" ""))
5418		      (pc)))]
5419  "(TARGET_H8300H || TARGET_H8300S)
5420    && peep2_reg_dead_p (1, operands[0])
5421    && (INTVAL (operands[1]) == 3
5422	 || INTVAL (operands[1]) == 7
5423	 || INTVAL (operands[1]) == 15
5424	 || INTVAL (operands[1]) == 31
5425	 || INTVAL (operands[1]) == 63
5426	 || INTVAL (operands[1]) == 127
5427	 || INTVAL (operands[1]) == 255)"
5428  [(set (match_dup 0)
5429	(and:SI (match_dup 0)
5430		(match_dup 4)))
5431   (set (cc0) (compare (match_dup 0)
5432		       (const_int 0)))
5433   (set (pc)
5434	(if_then_else (match_dup 2)
5435		      (label_ref (match_dup 3))
5436		      (pc)))]
5437  {
5438    operands[4] = GEN_INT (~INTVAL (operands[1]));
5439  })
5440
5441;; Transform
5442;;
5443;;	cmp.l	#15,er0
5444;;	bhi	.L1
5445;;
5446;; into
5447;;
5448;;	and	#240,r0l
5449;;	mov.l	er0,er0
5450;;	bne	.L1
5451
5452(define_peephole2
5453  [(set (cc0)
5454	(compare (match_operand:SI 0 "register_operand" "")
5455		 (match_operand:SI 1 "const_int_operand" "")))
5456   (set (pc)
5457	(if_then_else (match_operator 2 "gtuleu_operator"
5458		       [(cc0) (const_int 0)])
5459		      (label_ref (match_operand 3 "" ""))
5460		      (pc)))]
5461  "(TARGET_H8300H || TARGET_H8300S)
5462    && peep2_reg_dead_p (1, operands[0])
5463    && ((TARGET_H8300H && INTVAL (operands[1]) == 3)
5464	 || INTVAL (operands[1]) == 7
5465	 || INTVAL (operands[1]) == 15
5466	 || INTVAL (operands[1]) == 31
5467	 || INTVAL (operands[1]) == 63
5468	 || INTVAL (operands[1]) == 127
5469	 || INTVAL (operands[1]) == 255)"
5470  [(set (match_dup 0)
5471	(and:SI (match_dup 0)
5472		(match_dup 4)))
5473   (set (cc0) (compare (match_dup 0)
5474		       (const_int 0)))
5475   (set (pc)
5476	(if_then_else (match_dup 5)
5477		      (label_ref (match_dup 3))
5478		      (pc)))]
5479  {
5480    operands[4] = GEN_INT (~INTVAL (operands[1]));
5481    operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[2]) == GTU ? NE : EQ,
5482				  VOIDmode, cc0_rtx, const0_rtx);
5483  })
5484
5485;; Transform
5486;;
5487;;	cmp.l	#65535,er0
5488;;	bgt	.L1
5489;;
5490;; into
5491;;
5492;;	mov.l	e0,e0
5493;;	bgt	.L1
5494
5495(define_peephole2
5496  [(set (cc0)
5497	(compare (match_operand:SI 0 "register_operand" "")
5498		 (const_int 65535)))
5499   (set (pc)
5500	(if_then_else (match_operator 1 "gtle_operator"
5501		       [(cc0) (const_int 0)])
5502		      (label_ref (match_operand 2 "" ""))
5503		      (pc)))]
5504  "TARGET_H8300H || TARGET_H8300S"
5505  [(set (cc0) (compare (and:SI (match_dup 0)
5506			       (const_int -65536))
5507		       (const_int 0)))
5508   (set (pc)
5509	(if_then_else (match_dup 1)
5510		      (label_ref (match_dup 2))
5511		      (pc)))]
5512  "")
5513
5514;; Transform
5515;;
5516;;	cmp.l	#65535,er0
5517;;	bhi	.L1
5518;;
5519;; into
5520;;
5521;;	mov.l	e0,e0
5522;;	bne	.L1
5523
5524(define_peephole2
5525  [(set (cc0)
5526	(compare (match_operand:SI 0 "register_operand" "")
5527		 (const_int 65535)))
5528   (set (pc)
5529	(if_then_else (match_operator 1 "gtuleu_operator"
5530		       [(cc0) (const_int 0)])
5531		      (label_ref (match_operand 2 "" ""))
5532		      (pc)))]
5533  "TARGET_H8300H || TARGET_H8300S"
5534  [(set (cc0) (compare (and:SI (match_dup 0)
5535			       (const_int -65536))
5536		       (const_int 0)))
5537   (set (pc)
5538	(if_then_else (match_dup 3)
5539		      (label_ref (match_dup 2))
5540		      (pc)))]
5541  {
5542    operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[1]) == GTU ? NE : EQ,
5543				  VOIDmode, cc0_rtx, const0_rtx);
5544  })
5545
5546;; Transform
5547;;
5548;;	cmp.l	#1,er0
5549;;	beq	.L1
5550;;
5551;; into
5552;;
5553;;	mov.l	er0,er1
5554;;	dec.l	#1,er1
5555;;	beq	.L1
5556
5557;; We avoid this transformation if we see more than one copy of the
5558;; same compare insn.
5559
5560(define_peephole2
5561  [(match_scratch:SI 4 "r")
5562   (set (cc0)
5563	(compare (match_operand:SI 0 "register_operand" "")
5564		 (match_operand:SI 1 "incdec_operand" "")))
5565   (set (pc)
5566	(if_then_else (match_operator 3 "eqne_operator"
5567		       [(cc0) (const_int 0)])
5568		      (label_ref (match_operand 2 "" ""))
5569		      (pc)))]
5570  "(TARGET_H8300H || TARGET_H8300S)
5571    && INTVAL (operands[1]) != 0
5572    && !peep2_reg_dead_p (1, operands[0])
5573    && !same_cmp_following_p (insn)"
5574  [(set (match_dup 4)
5575	(match_dup 0))
5576   (set (match_dup 4)
5577	(unspec:SI [(match_dup 4)
5578		    (match_dup 5)]
5579		   UNSPEC_INCDEC))
5580   (set (cc0) (compare (match_dup 4)
5581		       (const_int 0)))
5582   (set (pc)
5583	(if_then_else (match_op_dup 3 [(cc0) (const_int 0)])
5584		      (label_ref (match_dup 2))
5585		      (pc)))]
5586  {
5587    operands[5] = GEN_INT (- INTVAL (operands[1]));
5588  })
5589;; Narrow the mode of testing if possible.
5590
5591(define_peephole2
5592  [(set (match_operand:HI 0 "register_operand" "")
5593	(and:HI (match_dup 0)
5594		(match_operand:HI 1 "const_int_qi_operand" "")))
5595   (set (cc0) (compare (match_dup 0)
5596		       (const_int 0)))
5597   (set (pc)
5598	(if_then_else (match_operator 3 "eqne_operator"
5599		       [(cc0) (const_int 0)])
5600		      (label_ref (match_operand 2 "" ""))
5601		      (pc)))]
5602  "peep2_reg_dead_p (2, operands[0])"
5603  [(set (match_dup 4)
5604	(and:QI (match_dup 4)
5605		(match_dup 5)))
5606   (set (cc0) (compare (match_dup 4)
5607		       (const_int 0)))
5608   (set (pc)
5609	(if_then_else (match_op_dup 3 [(cc0) (const_int 0)])
5610		      (label_ref (match_dup 2))
5611		      (pc)))]
5612  {
5613    operands[4] = gen_rtx_REG (QImode, REGNO (operands[0]));
5614    operands[5] = gen_int_mode (INTVAL (operands[1]), QImode);
5615  })
5616
5617(define_peephole2
5618  [(set (match_operand:SI 0 "register_operand" "")
5619	(and:SI (match_dup 0)
5620		(match_operand:SI 1 "const_int_qi_operand" "")))
5621   (set (cc0) (compare (match_dup 0)
5622		       (const_int 0)))
5623   (set (pc)
5624	(if_then_else (match_operator 3 "eqne_operator"
5625		       [(cc0) (const_int 0)])
5626		      (label_ref (match_operand 2 "" ""))
5627		      (pc)))]
5628  "peep2_reg_dead_p (2, operands[0])"
5629  [(set (match_dup 4)
5630	(and:QI (match_dup 4)
5631		(match_dup 5)))
5632   (set (cc0) (compare (match_dup 4)
5633		       (const_int 0)))
5634   (set (pc)
5635	(if_then_else (match_op_dup 3 [(cc0) (const_int 0)])
5636		      (label_ref (match_dup 2))
5637		      (pc)))]
5638  {
5639    operands[4] = gen_rtx_REG (QImode, REGNO (operands[0]));
5640    operands[5] = gen_int_mode (INTVAL (operands[1]), QImode);
5641  })
5642
5643(define_peephole2
5644  [(set (match_operand:SI 0 "register_operand" "")
5645	(and:SI (match_dup 0)
5646		(match_operand:SI 1 "const_int_hi_operand" "")))
5647   (set (cc0) (compare (match_dup 0)
5648		       (const_int 0)))
5649   (set (pc)
5650	(if_then_else (match_operator 3 "eqne_operator"
5651		       [(cc0) (const_int 0)])
5652		      (label_ref (match_operand 2 "" ""))
5653		      (pc)))]
5654  "peep2_reg_dead_p (2, operands[0])"
5655  [(set (match_dup 4)
5656	(and:HI (match_dup 4)
5657		(match_dup 5)))
5658   (set (cc0) (compare (match_dup 4)
5659		       (const_int 0)))
5660   (set (pc)
5661	(if_then_else (match_op_dup 3 [(cc0) (const_int 0)])
5662		      (label_ref (match_dup 2))
5663		      (pc)))]
5664  {
5665    operands[4] = gen_rtx_REG (HImode, REGNO (operands[0]));
5666    operands[5] = gen_int_mode (INTVAL (operands[1]), HImode);
5667  })
5668
5669(define_peephole2
5670  [(set (match_operand:SI 0 "register_operand" "")
5671	(and:SI (match_dup 0)
5672		(match_operand:SI 1 "const_int_qi_operand" "")))
5673   (set (match_dup 0)
5674	(xor:SI (match_dup 0)
5675		(match_operand:SI 2 "const_int_qi_operand" "")))
5676   (set (cc0) (compare (match_dup 0)
5677		       (const_int 0)))
5678   (set (pc)
5679	(if_then_else (match_operator 4 "eqne_operator"
5680		       [(cc0) (const_int 0)])
5681		      (label_ref (match_operand 3 "" ""))
5682		      (pc)))]
5683  "peep2_reg_dead_p (3, operands[0])
5684   && (~INTVAL (operands[1]) & INTVAL (operands[2])) == 0"
5685  [(set (match_dup 5)
5686	(and:QI (match_dup 5)
5687		(match_dup 6)))
5688   (set (match_dup 5)
5689	(xor:QI (match_dup 5)
5690		(match_dup 7)))
5691   (set (cc0) (compare (match_dup 5)
5692		       (const_int 0)))
5693   (set (pc)
5694	(if_then_else (match_op_dup 4 [(cc0) (const_int 0)])
5695		      (label_ref (match_dup 3))
5696		      (pc)))]
5697  {
5698    operands[5] = gen_rtx_REG (QImode, REGNO (operands[0]));
5699    operands[6] = gen_int_mode (INTVAL (operands[1]), QImode);
5700    operands[7] = gen_int_mode (INTVAL (operands[2]), QImode);
5701  })
5702
5703;; These triggers right at the end of allocation of locals in the
5704;; prologue (and possibly at other places).
5705
5706;; stack adjustment of -4, generate one push
5707;;
5708;; before : 6 bytes, 10 clocks
5709;; after  : 4 bytes, 10 clocks
5710
5711(define_peephole2
5712  [(set (reg:SI SP_REG)
5713	(plus:SI (reg:SI SP_REG)
5714		 (const_int -4)))
5715   (set (mem:SI (reg:SI SP_REG))
5716	(match_operand:SI 0 "register_operand" ""))]
5717  "(TARGET_H8300H || TARGET_H8300S) && !TARGET_NORMAL_MODE
5718    && REGNO (operands[0]) != SP_REG"
5719  [(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
5720	(match_dup 0))]
5721  "")
5722
5723;; stack adjustment of -12, generate one push
5724;;
5725;; before : 10 bytes, 14 clocks
5726;; after  :  8 bytes, 14 clocks
5727
5728(define_peephole2
5729  [(set (reg:SI SP_REG)
5730	(plus:SI (reg:SI SP_REG)
5731		 (const_int -12)))
5732   (set (mem:SI (reg:SI SP_REG))
5733	(match_operand:SI 0 "register_operand" ""))]
5734  "(TARGET_H8300H || TARGET_H8300S) && !TARGET_NORMAL_MODE
5735    && REGNO (operands[0]) != SP_REG"
5736  [(set (reg:SI SP_REG)
5737	(plus:SI (reg:SI SP_REG)
5738		 (const_int -4)))
5739   (set (reg:SI SP_REG)
5740	(plus:SI (reg:SI SP_REG)
5741		 (const_int -4)))
5742   (set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
5743	(match_dup 0))]
5744  "")
5745
5746;; Transform
5747;;
5748;;	mov	dst,reg
5749;;	op	src,reg
5750;;	mov	reg,dst
5751;;
5752;; into
5753;;
5754;;	op	src,dst
5755;;
5756;; if "reg" dies at the end of the sequence.
5757
5758(define_peephole2
5759  [(set (match_operand 0 "register_operand" "")
5760	(match_operand 1 "memory_operand" ""))
5761   (set (match_dup 0)
5762	(match_operator 2 "h8sx_binary_memory_operator"
5763	 [(match_dup 0)
5764	  (match_operand 3 "h8300_src_operand" "")]))
5765   (set (match_operand 4 "memory_operand" "")
5766	(match_dup 0))]
5767  "0 /* Disable because it breaks compiling fp-bit.c.  */
5768   && TARGET_H8300SX
5769   && peep2_reg_dead_p (3, operands[0])
5770   && !reg_overlap_mentioned_p (operands[0], operands[3])
5771   && !reg_overlap_mentioned_p (operands[0], operands[4])
5772   && h8sx_mergeable_memrefs_p (operands[4], operands[1])"
5773  [(set (match_dup 4)
5774	(match_dup 5))]
5775  {
5776    operands[5] = shallow_copy_rtx (operands[2]);
5777    XEXP (operands[5], 0) = operands[1];
5778  })
5779
5780;; Transform
5781;;
5782;;	mov	src,reg
5783;;	op	reg,dst
5784;;
5785;; into
5786;;
5787;;	op	src,dst
5788;;
5789;; if "reg" dies in the second insn.
5790
5791(define_peephole2
5792  [(set (match_operand 0 "register_operand" "")
5793	(match_operand 1 "h8300_src_operand" ""))
5794   (set (match_operand 2 "h8300_dst_operand" "")
5795	(match_operator 3 "h8sx_binary_memory_operator"
5796	 [(match_operand 4 "h8300_dst_operand" "")
5797	  (match_dup 0)]))]
5798  "0 /* Disable because it breaks compiling fp-bit.c.  */
5799   && TARGET_H8300SX
5800   && peep2_reg_dead_p (2, operands[0])
5801   && !reg_overlap_mentioned_p (operands[0], operands[4])"
5802  [(set (match_dup 2)
5803	(match_dup 5))]
5804  {
5805    operands[5] = shallow_copy_rtx (operands[3]);
5806    XEXP (operands[5], 1) = operands[1];
5807  })
5808
5809;; Transform
5810;;
5811;;	mov	dst,reg
5812;;	op	reg
5813;;	mov	reg,dst
5814;;
5815;; into
5816;;
5817;;	op	dst
5818;;
5819;; if "reg" dies at the end of the sequence.
5820
5821(define_peephole2
5822  [(set (match_operand 0 "register_operand" "")
5823	(match_operand 1 "memory_operand" ""))
5824   (set (match_dup 0)
5825	(match_operator 2 "h8sx_unary_memory_operator"
5826	 [(match_dup 0)]))
5827   (set (match_operand 3 "memory_operand" "")
5828	(match_dup 0))]
5829  "TARGET_H8300SX
5830   && peep2_reg_dead_p (3, operands[0])
5831   && !reg_overlap_mentioned_p (operands[0], operands[3])
5832   && h8sx_mergeable_memrefs_p (operands[3], operands[1])"
5833  [(set (match_dup 3)
5834	(match_dup 4))]
5835  {
5836    operands[4] = shallow_copy_rtx (operands[2]);
5837    XEXP (operands[4], 0) = operands[1];
5838  })
5839
5840;; Transform
5841;;
5842;;	mov	src1,reg
5843;;	cmp	reg,src2
5844;;
5845;; into
5846;;
5847;;	cmp	src1,src2
5848;;
5849;; if "reg" dies in the comparison.
5850
5851(define_peephole2
5852  [(set (match_operand 0 "register_operand" "")
5853	(match_operand 1 "h8300_dst_operand" ""))
5854   (set (cc0)
5855	(compare (match_dup 0)
5856		 (match_operand 2 "h8300_src_operand" "")))]
5857  "TARGET_H8300SX
5858   && peep2_reg_dead_p (2, operands[0])
5859   && !reg_overlap_mentioned_p (operands[0], operands[2])
5860   && operands[2] != const0_rtx"
5861  [(set (cc0)
5862	(compare (match_dup 1)
5863		 (match_dup 2)))])
5864
5865;; Likewise for the second operand.
5866
5867(define_peephole2
5868  [(set (match_operand 0 "register_operand" "")
5869	(match_operand 1 "h8300_src_operand" ""))
5870   (set (cc0)
5871	(compare (match_operand 2 "h8300_dst_operand" "")
5872		 (match_dup 0)))]
5873  "TARGET_H8300SX
5874   && peep2_reg_dead_p (2, operands[0])
5875   && !reg_overlap_mentioned_p (operands[0], operands[2])"
5876  [(set (cc0)
5877	(compare (match_dup 2)
5878		 (match_dup 1)))])
5879
5880;; Combine two moves.
5881
5882(define_peephole2
5883  [(set (match_operand 0 "register_operand" "")
5884	(match_operand 1 "h8300_src_operand" ""))
5885   (set (match_operand 2 "h8300_dst_operand" "")
5886	(match_dup 0))]
5887  "TARGET_H8300SX
5888   && peep2_reg_dead_p (2, operands[0])
5889   && !reg_overlap_mentioned_p (operands[0], operands[2])"
5890  [(set (match_dup 2)
5891	(match_dup 1))])
5892
5893
5894