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