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