OSDN Git Service

* config/m32r/m32r.h: Add support for m32r2 processor. Including
[pf3gnuchains/gcc-fork.git] / gcc / config / m32r / m32r.md
1 ;; Machine description of the Mitsubishi M32R cpu for GNU C compiler
2 ;; Copyright (C) 1996, 1997, 1998, 1999, 2001 Free Software Foundation, Inc.
3
4 ;; This file is part of GCC.
5
6 ;; GCC is free software; you can redistribute it and/or modify
7 ;; it under the terms of the GNU General Public License as published by
8 ;; the Free Software Foundation; either version 2, or (at your option)
9 ;; any later version.
10
11 ;; GCC is distributed in the hope that it will be useful,
12 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
13 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 ;; GNU General Public License for more details.
15
16 ;; You should have received a copy of the GNU General Public License
17 ;; along with GCC; see the file COPYING.  If not, write to
18 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
19 ;; Boston, MA 02111-1307, USA.
20
21 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
22
23 ;; unspec usage
24 ;; 0 - blockage
25 ;; 1 - flush_icache
26 ;; 2 - load_sda_base
27 ;; 3 - setting carry in addx/subx instructions.
28 \f
29 ;; Insn type.  Used to default other attribute values.
30 (define_attr "type"
31   "int2,int4,load2,load4,load8,store2,store4,store8,shift2,shift4,mul2,div4,uncond_branch,branch,call,multi,misc"
32   (const_string "misc"))
33
34 ;; Length in bytes.
35 (define_attr "length" ""
36   (cond [(eq_attr "type" "int2,load2,store2,shift2,mul2")
37          (const_int 2)
38
39          (eq_attr "type" "int4,load4,store4,shift4,div4")
40          (const_int 4)
41
42          (eq_attr "type" "multi")
43          (const_int 8)
44
45          (eq_attr "type" "uncond_branch,branch,call")
46          (const_int 4)]
47
48          (const_int 4)))
49
50 ;; The length here is the length of a single asm.  Unfortunately it might be
51 ;; 2 or 4 so we must allow for 4.  That's ok though.
52 (define_asm_attributes
53   [(set_attr "length" "4")
54    (set_attr "type" "multi")])
55
56
57 ;; Whether an instruction is 16-bit or 32-bit
58 (define_attr "insn_size" "short,long"
59   (if_then_else (eq_attr "type" "int2,load2,store2,shift2,mul2")
60                 (const_string "short")
61                 (const_string "long")))
62
63 (define_attr "debug" "no,yes"
64   (const (symbol_ref "(TARGET_DEBUG != 0)")))
65
66 (define_attr "opt_size" "no,yes"
67   (const (symbol_ref "(optimize_size != 0)")))
68
69 (define_attr "m32r" "no,yes"
70   (const (symbol_ref "(TARGET_M32R != 0)")))
71
72 (define_attr "m32rx" "no,yes"
73   (const (symbol_ref "(TARGET_M32RX != 0)")))
74
75 (define_attr "m32r2" "no,yes"
76   (const (symbol_ref "(TARGET_M32R2 != 0)")))
77
78 (define_attr "m32rx_pipeline" "either,s,o,long,m32r"
79   (cond [(and (eq_attr "m32rx" "no")
80               (eq_attr "m32r2" "no"))
81          (const_string "m32r")
82
83          (eq_attr "insn_size" "!short")
84          (const_string "long")]
85
86         (cond [(eq_attr "type" "int2")
87                (const_string "either")
88
89                (eq_attr "type" "load2,store2,shift2,uncond_branch,branch,call")
90                (const_string "o")
91
92                (eq_attr "type" "mul2")
93                (const_string "s")]
94
95               (const_string "long"))))
96 \f
97 ;; ::::::::::::::::::::
98 ;; ::
99 ;; :: Function Units
100 ;; ::
101 ;; ::::::::::::::::::::
102
103 ;; On most RISC machines, there are instructions whose results are not
104 ;; available for a specific number of cycles.  Common cases are instructions
105 ;; that load data from memory.  On many machines, a pipeline stall will result
106 ;; if the data is referenced too soon after the load instruction.
107
108 ;; In addition, many newer microprocessors have multiple function units,
109 ;; usually one for integer and one for floating point, and often will incur
110 ;; pipeline stalls when a result that is needed is not yet ready.
111
112 ;; The descriptions in this section allow the specification of how much time
113 ;; must elapse between the execution of an instruction and the time when its
114 ;; result is used.  It also allows specification of when the execution of an
115 ;; instruction will delay execution of similar instructions due to function
116 ;; unit conflicts.
117
118 ;; For the purposes of the specifications in this section, a machine is divided
119 ;; into "function units", each of which execute a specific class of
120 ;; instructions in first-in-first-out order.  Function units that accept one
121 ;; instruction each cycle and allow a result to be used in the succeeding
122 ;; instruction (usually via forwarding) need not be specified.  Classic RISC
123 ;; microprocessors will normally have a single function unit, which we can call
124 ;; `memory'.  The newer "superscalar" processors will often have function units
125 ;; for floating point operations, usually at least a floating point adder and
126 ;; multiplier.
127
128 ;; Each usage of a function units by a class of insns is specified with a
129 ;; `define_function_unit' expression, which looks like this:
130
131 ;; (define_function_unit NAME MULTIPLICITY SIMULTANEITY TEST READY-DELAY
132 ;;   ISSUE-DELAY [CONFLICT-LIST])
133
134 ;; NAME is a string giving the name of the function unit.
135
136 ;; MULTIPLICITY is an integer specifying the number of identical units in the
137 ;; processor.  If more than one unit is specified, they will be scheduled
138 ;; independently.  Only truly independent units should be counted; a pipelined
139 ;; unit should be specified as a single unit.  (The only common example of a
140 ;; machine that has multiple function units for a single instruction class that
141 ;; are truly independent and not pipelined are the two multiply and two
142 ;; increment units of the CDC 6600.)
143
144 ;; SIMULTANEITY specifies the maximum number of insns that can be executing in
145 ;; each instance of the function unit simultaneously or zero if the unit is
146 ;; pipelined and has no limit.
147
148 ;; All `define_function_unit' definitions referring to function unit NAME must
149 ;; have the same name and values for MULTIPLICITY and SIMULTANEITY.
150
151 ;; TEST is an attribute test that selects the insns we are describing in this
152 ;; definition.  Note that an insn may use more than one function unit and a
153 ;; function unit may be specified in more than one `define_function_unit'.
154
155 ;; READY-DELAY is an integer that specifies the number of cycles after which
156 ;; the result of the instruction can be used without introducing any stalls.
157
158 ;; ISSUE-DELAY is an integer that specifies the number of cycles after the
159 ;; instruction matching the TEST expression begins using this unit until a
160 ;; subsequent instruction can begin.  A cost of N indicates an N-1 cycle delay.
161 ;; A subsequent instruction may also be delayed if an earlier instruction has a
162 ;; longer READY-DELAY value.  This blocking effect is computed using the
163 ;; SIMULTANEITY, READY-DELAY, ISSUE-DELAY, and CONFLICT-LIST terms.  For a
164 ;; normal non-pipelined function unit, SIMULTANEITY is one, the unit is taken
165 ;; to block for the READY-DELAY cycles of the executing insn, and smaller
166 ;; values of ISSUE-DELAY are ignored.
167
168 ;; CONFLICT-LIST is an optional list giving detailed conflict costs for this
169 ;; unit.  If specified, it is a list of condition test expressions to be
170 ;; applied to insns chosen to execute in NAME following the particular insn
171 ;; matching TEST that is already executing in NAME.  For each insn in the list,
172 ;; ISSUE-DELAY specifies the conflict cost; for insns not in the list, the cost
173 ;; is zero.  If not specified, CONFLICT-LIST defaults to all instructions that
174 ;; use the function unit.
175
176 ;; Typical uses of this vector are where a floating point function unit can
177 ;; pipeline either single- or double-precision operations, but not both, or
178 ;; where a memory unit can pipeline loads, but not stores, etc.
179
180 ;; As an example, consider a classic RISC machine where the result of a load
181 ;; instruction is not available for two cycles (a single "delay" instruction is
182 ;; required) and where only one load instruction can be executed
183 ;; simultaneously.  This would be specified as:
184
185 ;; (define_function_unit "memory" 1 1 (eq_attr "type" "load") 2 0)
186
187 ;; For the case of a floating point function unit that can pipeline
188 ;; either single or double precision, but not both, the following could be
189 ;; specified:
190 ;;
191 ;; (define_function_unit "fp" 1 0
192 ;;   (eq_attr "type" "sp_fp") 4 4
193 ;;   [(eq_attr "type" "dp_fp")])
194 ;;
195 ;; (define_function_unit "fp" 1 0
196 ;;   (eq_attr "type" "dp_fp") 4 4
197 ;;   [(eq_attr "type" "sp_fp")])
198
199 ;; Note: The scheduler attempts to avoid function unit conflicts and uses all
200 ;; the specifications in the `define_function_unit' expression.  It has
201 ;; recently come to our attention that these specifications may not allow
202 ;; modeling of some of the newer "superscalar" processors that have insns using
203 ;; multiple pipelined units.  These insns will cause a potential conflict for
204 ;; the second unit used during their execution and there is no way of
205 ;; representing that conflict.  We welcome any examples of how function unit
206 ;; conflicts work in such processors and suggestions for their representation.
207
208 ;; Function units of the M32R
209 ;; Units that take one cycle do not need to be specified.
210
211 ;; (define_function_unit {name} {multiplicity} {simultaneity} {test}
212 ;;                       {ready-delay} {issue-delay} [{conflict-list}])
213
214 ;; Hack to get GCC to better pack the instructions.
215 ;; We pretend there is a separate long function unit that conflicts with
216 ;; both the left and right 16 bit insn slots.
217
218 (define_function_unit "short" 2 2
219   (and (eq_attr "m32r" "yes")
220        (and (eq_attr "insn_size" "short")
221             (eq_attr "type" "!load2")))
222   1 0
223   [(eq_attr "insn_size" "long")])
224
225 (define_function_unit "short" 2 2       ;; load delay of 1 clock for mem execution + 1 clock for WB
226   (and (eq_attr "m32r" "yes")
227        (eq_attr "type" "load2"))
228   3 0
229   [(eq_attr "insn_size" "long")])
230
231 (define_function_unit "long" 1 1
232   (and (eq_attr "m32r" "yes")
233        (and (eq_attr "insn_size" "long")
234             (eq_attr "type" "!load4,load8")))
235   1 0
236   [(eq_attr "insn_size" "short")])
237
238 (define_function_unit "long" 1 1        ;; load delay of 1 clock for mem execution + 1 clock for WB
239   (and (eq_attr "m32r" "yes")
240        (and (eq_attr "insn_size" "long")
241             (eq_attr "type" "load4,load8")))
242   3 0
243   [(eq_attr "insn_size" "short")])
244
245 (define_function_unit "left" 1 1
246   (and (eq_attr "m32rx_pipeline" "o,either")
247        (eq_attr "type" "!load2"))
248   1 0
249   [(eq_attr "insn_size" "long")])
250
251 (define_function_unit "left" 1 1        ;; load delay of 1 clock for mem execution + 1 clock for WB
252   (and (eq_attr "m32rx_pipeline" "o,either")
253        (eq_attr "type" "load2"))
254   3 0
255   [(eq_attr "insn_size" "long")])
256
257 (define_function_unit "right" 1 1
258   (eq_attr "m32rx_pipeline" "s,either")
259   1 0
260   [(eq_attr "insn_size" "long")])
261
262 (define_function_unit "long" 1 1
263   (and (eq_attr "m32rx" "yes")
264        (and (eq_attr "insn_size" "long")
265             (eq_attr "type" "!load4,load8")))
266   2 0
267   [(eq_attr "insn_size" "short")])
268
269 (define_function_unit "long" 1 1        ;; load delay of 1 clock for mem execution + 1 clock for WB
270   (and (eq_attr "m32rx" "yes")
271        (and (eq_attr "insn_size" "long")
272             (eq_attr "type" "load4,load8")))
273   3 0
274   [(eq_attr "insn_size" "short")])
275 \f
276 ;; Expand prologue as RTL
277 (define_expand "prologue"
278   [(const_int 1)]
279   ""
280   "
281 {
282   m32r_expand_prologue ();
283   DONE;
284 }")
285
286 \f
287 ;; Move instructions.
288 ;;
289 ;; For QI and HI moves, the register must contain the full properly
290 ;; sign-extended value.  nonzero_bits assumes this [otherwise
291 ;; SHORT_IMMEDIATES_SIGN_EXTEND must be used, but the comment for it
292 ;; says it's a kludge and the .md files should be fixed instead].
293
294 (define_expand "movqi"
295   [(set (match_operand:QI 0 "general_operand" "")
296         (match_operand:QI 1 "general_operand" ""))]
297   ""
298   "
299 {
300   /* Everything except mem = const or mem = mem can be done easily.
301      Objects in the small data area are handled too.  */
302
303   if (GET_CODE (operands[0]) == MEM)
304     operands[1] = force_reg (QImode, operands[1]);
305 }")
306
307 (define_insn "*movqi_insn"
308   [(set (match_operand:QI 0 "move_dest_operand" "=r,r,r,r,r,T,m")
309         (match_operand:QI 1 "move_src_operand" "r,I,JQR,T,m,r,r"))]
310   "register_operand (operands[0], QImode) || register_operand (operands[1], QImode)"
311   "@
312    mv %0,%1
313    ldi %0,%#%1
314    ldi %0,%#%1
315    ldub %0,%1
316    ldub %0,%1
317    stb %1,%0
318    stb %1,%0"
319   [(set_attr "type" "int2,int2,int4,load2,load4,store2,store4")
320    (set_attr "length" "2,2,4,2,4,2,4")])
321
322 (define_expand "movhi"
323   [(set (match_operand:HI 0 "general_operand" "")
324         (match_operand:HI 1 "general_operand" ""))]
325   ""
326   "
327 {
328   /* Everything except mem = const or mem = mem can be done easily.  */
329
330   if (GET_CODE (operands[0]) == MEM)
331     operands[1] = force_reg (HImode, operands[1]);
332 }")
333
334 (define_insn "*movhi_insn"
335   [(set (match_operand:HI 0 "move_dest_operand" "=r,r,r,r,r,r,T,m")
336         (match_operand:HI 1 "move_src_operand" "r,I,JQR,K,T,m,r,r"))]
337   "register_operand (operands[0], HImode) || register_operand (operands[1], HImode)"
338   "@
339    mv %0,%1
340    ldi %0,%#%1
341    ldi %0,%#%1
342    ld24 %0,%#%1
343    lduh %0,%1
344    lduh %0,%1
345    sth %1,%0
346    sth %1,%0"
347   [(set_attr "type" "int2,int2,int4,int4,load2,load4,store2,store4")
348    (set_attr "length" "2,2,4,4,2,4,2,4")])
349
350 (define_expand "movsi_push"
351   [(set (mem:SI (pre_dec:SI (match_operand:SI 0 "register_operand" "")))
352         (match_operand:SI 1 "register_operand" ""))]
353   ""
354   "")
355
356 (define_expand "movsi_pop"
357   [(set (match_operand:SI 0 "register_operand" "")
358         (mem:SI (post_inc:SI (match_operand:SI 1 "register_operand" ""))))]
359   ""
360   "")
361
362 (define_expand "movsi"
363   [(set (match_operand:SI 0 "general_operand" "")
364         (match_operand:SI 1 "general_operand" ""))]
365   ""
366   "
367 {
368   /* Everything except mem = const or mem = mem can be done easily.  */
369
370   if (GET_CODE (operands[0]) == MEM)
371     operands[1] = force_reg (SImode, operands[1]);
372
373   /* Small Data Area reference?  */
374   if (small_data_operand (operands[1], SImode))
375     {
376       emit_insn (gen_movsi_sda (operands[0], operands[1]));
377       DONE;
378     }
379
380   /* If medium or large code model, symbols have to be loaded with
381      seth/add3.  */
382   if (addr32_operand (operands[1], SImode))
383     {
384       emit_insn (gen_movsi_addr32 (operands[0], operands[1]));
385       DONE;
386     }
387 }")
388
389 ;; ??? Do we need a const_double constraint here for large unsigned values?
390 (define_insn "*movsi_insn"
391   [(set (match_operand:SI 0 "move_dest_operand" "=r,r,r,r,r,r,r,r,r,T,S,m")
392         (match_operand:SI 1 "move_src_operand" "r,I,J,MQ,L,n,T,U,m,r,r,r"))]
393   "register_operand (operands[0], SImode) || register_operand (operands[1], SImode)"
394   "*
395 {
396   if (GET_CODE (operands[0]) == REG || GET_CODE (operands[1]) == SUBREG)
397     {
398       switch (GET_CODE (operands[1]))
399         {
400           HOST_WIDE_INT value;
401
402           default:
403             break;
404
405           case REG:
406           case SUBREG:
407             return \"mv %0,%1\";
408
409           case MEM:
410             if (GET_CODE (XEXP (operands[1], 0)) == POST_INC
411                 && XEXP (XEXP (operands[1], 0), 0) == stack_pointer_rtx)
412               return \"pop %0\";
413
414             return \"ld %0,%1\";
415
416           case CONST_INT:
417             value = INTVAL (operands[1]);
418             if (INT16_P (value))
419               return \"ldi %0,%#%1\\t; %X1\";
420
421             if (UINT24_P (value))
422               return \"ld24 %0,%#%1\\t; %X1\";
423
424             if (UPPER16_P (value))
425               return \"seth %0,%#%T1\\t; %X1\";
426
427             return \"#\";
428
429           case CONST:
430           case SYMBOL_REF:
431           case LABEL_REF:
432             if (TARGET_ADDR24)
433               return \"ld24 %0,%#%1\";
434
435             return \"#\";
436         }
437     }
438
439   else if (GET_CODE (operands[0]) == MEM
440            && (GET_CODE (operands[1]) == REG || GET_CODE (operands[1]) == SUBREG))
441     {
442       if (GET_CODE (XEXP (operands[0], 0)) == PRE_DEC
443           && XEXP (XEXP (operands[0], 0), 0) == stack_pointer_rtx)
444         return \"push %1\";
445
446       return \"st %1,%0\";
447     }
448
449   abort ();
450 }"
451   [(set_attr "type" "int2,int2,int4,int4,int4,multi,load2,load2,load4,store2,store2,store4")
452    (set_attr "length" "2,2,4,4,4,8,2,2,4,2,2,4")])
453
454 ; Try to use a four byte / two byte pair for constants not loadable with
455 ; ldi, ld24, seth.
456
457 (define_split
458  [(set (match_operand:SI 0 "register_operand" "")
459        (match_operand:SI 1 "two_insn_const_operand" ""))]
460   ""
461   [(set (match_dup 0) (match_dup 2))
462    (set (match_dup 0) (ior:SI (match_dup 0) (match_dup 3)))]
463   "
464 {
465   unsigned HOST_WIDE_INT val = INTVAL (operands[1]);
466   unsigned HOST_WIDE_INT tmp;
467   int shift;
468
469   /* In all cases we will emit two instructions.  However we try to
470      use 2 byte instructions wherever possible.  We can assume the
471      constant isn't loadable with any of ldi, ld24, or seth.  */
472
473   /* See if we can load a 24 bit unsigned value and invert it.  */
474   if (UINT24_P (~ val))
475     {
476       emit_insn (gen_movsi (operands[0], GEN_INT (~ val)));
477       emit_insn (gen_one_cmplsi2 (operands[0], operands[0]));
478       DONE;
479     }
480
481   /* See if we can load a 24 bit unsigned value and shift it into place.
482      0x01fffffe is just beyond ld24's range.  */
483   for (shift = 1, tmp = 0x01fffffe;
484        shift < 8;
485        ++shift, tmp <<= 1)
486     {
487       if ((val & ~tmp) == 0)
488         {
489           emit_insn (gen_movsi (operands[0], GEN_INT (val >> shift)));
490           emit_insn (gen_ashlsi3 (operands[0], operands[0], GEN_INT (shift)));
491           DONE;
492         }
493     }
494
495   /* Can't use any two byte insn, fall back to seth/or3.  Use ~0xffff instead
496      of 0xffff0000, since the later fails on a 64-bit host.  */
497   operands[2] = GEN_INT ((val) & ~0xffff);
498   operands[3] = GEN_INT ((val) & 0xffff);
499 }")
500
501 (define_split
502   [(set (match_operand:SI 0 "register_operand" "")
503         (match_operand:SI 1 "seth_add3_operand" "i"))]
504   "TARGET_ADDR32"
505   [(set (match_dup 0)
506         (high:SI (match_dup 1)))
507    (set (match_dup 0)
508         (lo_sum:SI (match_dup 0)
509                    (match_dup 1)))]
510   "")
511
512 ;; Small data area support.
513 ;; The address of _SDA_BASE_ is loaded into a register and all objects in
514 ;; the small data area are indexed off that.  This is done for each reference
515 ;; but cse will clean things up for us.  We let the compiler choose the
516 ;; register to use so we needn't allocate (and maybe even fix) a special
517 ;; register to use.  Since the load and store insns have a 16 bit offset the
518 ;; total size of the data area can be 64K.  However, if the data area lives
519 ;; above 16M (24 bits), _SDA_BASE_ will have to be loaded with seth/add3 which
520 ;; would then yield 3 instructions to reference an object [though there would
521 ;; be no net loss if two or more objects were referenced].  The 3 insns can be
522 ;; reduced back to 2 if the size of the small data area were reduced to 32K
523 ;; [then seth + ld/st would work for any object in the area].  Doing this
524 ;; would require special handling of _SDA_BASE_ (its value would be
525 ;; (.sdata + 32K) & 0xffff0000) and reloc computations would be different
526 ;; [I think].  What to do about this is deferred until later and for now we
527 ;; require .sdata to be in the first 16M.
528
529 (define_expand "movsi_sda"
530   [(set (match_dup 2)
531         (unspec [(const_int 0)] 2))
532    (set (match_operand:SI 0 "register_operand" "")
533         (lo_sum:SI (match_dup 2)
534                    (match_operand:SI 1 "small_data_operand" "")))]
535   ""
536   "
537 {
538   if (reload_in_progress || reload_completed)
539     operands[2] = operands[0];
540   else
541     operands[2] = gen_reg_rtx (SImode);
542 }")
543
544 (define_insn "*load_sda_base"
545   [(set (match_operand:SI 0 "register_operand" "=r")
546         (unspec [(const_int 0)] 2))]
547   ""
548   "ld24 %0,#_SDA_BASE_"
549   [(set_attr "type" "int4")
550    (set_attr "length" "4")])
551
552 ;; 32 bit address support.
553
554 (define_expand "movsi_addr32"
555   [(set (match_dup 2)
556         ; addr32_operand isn't used because it's too restrictive,
557         ; seth_add3_operand is more general and thus safer.
558         (high:SI (match_operand:SI 1 "seth_add3_operand" "")))
559    (set (match_operand:SI 0 "register_operand" "")
560         (lo_sum:SI (match_dup 2) (match_dup 1)))]
561   ""
562   "
563 {
564   if (reload_in_progress || reload_completed)
565     operands[2] = operands[0];
566   else
567     operands[2] = gen_reg_rtx (SImode);
568 }")
569
570 (define_insn "set_hi_si"
571   [(set (match_operand:SI 0 "register_operand" "=r")
572         (high:SI (match_operand 1 "symbolic_operand" "")))]
573   ""
574   "seth %0,%#shigh(%1)"
575   [(set_attr "type" "int4")
576    (set_attr "length" "4")])
577
578 (define_insn "lo_sum_si"
579   [(set (match_operand:SI 0 "register_operand" "=r")
580         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
581                    (match_operand:SI 2 "immediate_operand" "in")))]
582   ""
583   "add3 %0,%1,%#%B2"
584   [(set_attr "type" "int4")
585    (set_attr "length" "4")])
586
587 (define_expand "movdi"
588   [(set (match_operand:DI 0 "general_operand" "")
589         (match_operand:DI 1 "general_operand" ""))]
590   ""
591   "
592 {
593   /* Everything except mem = const or mem = mem can be done easily.  */
594
595   if (GET_CODE (operands[0]) == MEM)
596     operands[1] = force_reg (DImode, operands[1]);
597 }")
598
599 (define_insn "*movdi_insn"
600   [(set (match_operand:DI 0 "move_dest_operand" "=r,r,r,r,m")
601         (match_operand:DI 1 "move_double_src_operand" "r,nG,F,m,r"))]
602   "register_operand (operands[0], DImode) || register_operand (operands[1], DImode)"
603   "#"
604   [(set_attr "type" "multi,multi,multi,load8,store8")
605    (set_attr "length" "4,4,16,6,6")])
606
607 (define_split
608   [(set (match_operand:DI 0 "move_dest_operand" "")
609         (match_operand:DI 1 "move_double_src_operand" ""))]
610   "reload_completed"
611   [(match_dup 2)]
612   "operands[2] = gen_split_move_double (operands);")
613 \f
614 ;; Floating point move insns.
615
616 (define_expand "movsf"
617   [(set (match_operand:SF 0 "general_operand" "")
618         (match_operand:SF 1 "general_operand" ""))]
619   ""
620   "
621 {
622   /* Everything except mem = const or mem = mem can be done easily.  */
623
624   if (GET_CODE (operands[0]) == MEM)
625     operands[1] = force_reg (SFmode, operands[1]);
626 }")
627
628 (define_insn "*movsf_insn"
629   [(set (match_operand:SF 0 "move_dest_operand" "=r,r,r,r,r,T,S,m")
630         (match_operand:SF 1 "move_src_operand" "r,F,U,S,m,r,r,r"))]
631   "register_operand (operands[0], SFmode) || register_operand (operands[1], SFmode)"
632   "@
633    mv %0,%1
634    #
635    ld %0,%1
636    ld %0,%1
637    ld %0,%1
638    st %1,%0
639    st %1,%0
640    st %1,%0"
641   ;; ??? Length of alternative 1 is either 2, 4 or 8.
642   [(set_attr "type" "int2,multi,load2,load2,load4,store2,store2,store4")
643    (set_attr "length" "2,8,2,2,4,2,2,4")])
644
645 (define_split
646   [(set (match_operand:SF 0 "register_operand" "")
647         (match_operand:SF 1 "const_double_operand" ""))]
648   "reload_completed"
649   [(set (match_dup 2) (match_dup 3))]
650   "
651 {
652   operands[2] = operand_subword (operands[0], 0, 0, SFmode);
653   operands[3] = operand_subword (operands[1], 0, 0, SFmode);
654 }")
655
656 (define_expand "movdf"
657   [(set (match_operand:DF 0 "general_operand" "")
658         (match_operand:DF 1 "general_operand" ""))]
659   ""
660   "
661 {
662   /* Everything except mem = const or mem = mem can be done easily.  */
663
664   if (GET_CODE (operands[0]) == MEM)
665     operands[1] = force_reg (DFmode, operands[1]);
666 }")
667
668 (define_insn "*movdf_insn"
669   [(set (match_operand:DF 0 "move_dest_operand" "=r,r,r,m")
670         (match_operand:DF 1 "move_double_src_operand" "r,F,m,r"))]
671   "register_operand (operands[0], DFmode) || register_operand (operands[1], DFmode)"
672   "#"
673   [(set_attr "type" "multi,multi,load8,store8")
674    (set_attr "length" "4,16,6,6")])
675
676 (define_split
677   [(set (match_operand:DF 0 "move_dest_operand" "")
678         (match_operand:DF 1 "move_double_src_operand" ""))]
679   "reload_completed"
680   [(match_dup 2)]
681   "operands[2] = gen_split_move_double (operands);")
682 \f
683 ;; Zero extension instructions.
684
685 (define_insn "zero_extendqihi2"
686   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
687         (zero_extend:HI (match_operand:QI 1 "extend_operand" "r,T,m")))]
688   ""
689   "@
690    and3 %0,%1,%#255
691    ldub %0,%1
692    ldub %0,%1"
693   [(set_attr "type" "int4,load2,load4")
694    (set_attr "length" "4,2,4")])
695
696 (define_insn "zero_extendqisi2"
697   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
698         (zero_extend:SI (match_operand:QI 1 "extend_operand" "r,T,m")))]
699   ""
700   "@
701    and3 %0,%1,%#255
702    ldub %0,%1
703    ldub %0,%1"
704   [(set_attr "type" "int4,load2,load4")
705    (set_attr "length" "4,2,4")])
706
707 (define_insn "zero_extendhisi2"
708   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
709         (zero_extend:SI (match_operand:HI 1 "extend_operand" "r,T,m")))]
710   ""
711   "@
712    and3 %0,%1,%#65535
713    lduh %0,%1
714    lduh %0,%1"
715   [(set_attr "type" "int4,load2,load4")
716    (set_attr "length" "4,2,4")])
717 \f
718 ;; Signed conversions from a smaller integer to a larger integer
719 (define_insn "extendqihi2"
720   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
721         (sign_extend:HI (match_operand:QI 1 "extend_operand" "0,T,m")))]
722   ""
723   "@
724     #
725     ldb %0,%1
726     ldb %0,%1"
727   [(set_attr "type" "multi,load2,load4")
728    (set_attr "length" "2,2,4")])
729
730 (define_split
731   [(set (match_operand:HI 0 "register_operand" "")
732         (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
733   "reload_completed"
734   [(match_dup 2)
735    (match_dup 3)]
736   "
737 {
738   rtx op0   = gen_lowpart (SImode, operands[0]);
739   rtx shift = gen_rtx (CONST_INT, VOIDmode, 24);
740
741   operands[2] = gen_ashlsi3 (op0, op0, shift);
742   operands[3] = gen_ashrsi3 (op0, op0, shift);
743 }")
744
745 (define_insn "extendqisi2"
746   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
747         (sign_extend:SI (match_operand:QI 1 "extend_operand" "0,T,m")))]
748   ""
749   "@
750     #
751     ldb %0,%1
752     ldb %0,%1"
753   [(set_attr "type" "multi,load2,load4")
754    (set_attr "length" "4,2,4")])
755
756 (define_split
757   [(set (match_operand:SI 0 "register_operand" "")
758         (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
759   "reload_completed"
760   [(match_dup 2)
761    (match_dup 3)]
762   "
763 {
764   rtx op0   = gen_lowpart (SImode, operands[0]);
765   rtx shift = gen_rtx (CONST_INT, VOIDmode, 24);
766
767   operands[2] = gen_ashlsi3 (op0, op0, shift);
768   operands[3] = gen_ashrsi3 (op0, op0, shift);
769 }")
770
771 (define_insn "extendhisi2"
772   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
773         (sign_extend:SI (match_operand:HI 1 "extend_operand" "0,T,m")))]
774   ""
775   "@
776     #
777     ldh %0,%1
778     ldh %0,%1"
779   [(set_attr "type" "multi,load2,load4")
780    (set_attr "length" "4,2,4")])
781
782 (define_split
783   [(set (match_operand:SI 0 "register_operand" "")
784         (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
785   "reload_completed"
786   [(match_dup 2)
787    (match_dup 3)]
788   "
789 {
790   rtx op0   = gen_lowpart (SImode, operands[0]);
791   rtx shift = gen_rtx (CONST_INT, VOIDmode, 16);
792
793   operands[2] = gen_ashlsi3 (op0, op0, shift);
794   operands[3] = gen_ashrsi3 (op0, op0, shift);
795 }")
796 \f
797 ;; Arithmetic instructions.
798
799 ; ??? Adding an alternative to split add3 of small constants into two
800 ; insns yields better instruction packing but slower code.  Adds of small
801 ; values is done a lot.
802
803 (define_insn "addsi3"
804   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
805         (plus:SI (match_operand:SI 1 "register_operand" "%0,0,r")
806                  (match_operand:SI 2 "nonmemory_operand" "r,I,J")))]
807   ""
808   "@
809    add %0,%2
810    addi %0,%#%2
811    add3 %0,%1,%#%2"
812   [(set_attr "type" "int2,int2,int4")
813    (set_attr "length" "2,2,4")])
814
815 ;(define_split
816 ;  [(set (match_operand:SI 0 "register_operand" "")
817 ;       (plus:SI (match_operand:SI 1 "register_operand" "")
818 ;                (match_operand:SI 2 "int8_operand" "")))]
819 ;  "reload_completed
820 ;   && REGNO (operands[0]) != REGNO (operands[1])
821 ;   && INT8_P (INTVAL (operands[2]))
822 ;   && INTVAL (operands[2]) != 0"
823 ;  [(set (match_dup 0) (match_dup 1))
824 ;   (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))]
825 ;  "")
826
827 (define_insn "adddi3"
828   [(set (match_operand:DI 0 "register_operand" "=r")
829         (plus:DI (match_operand:DI 1 "register_operand" "%0")
830                  (match_operand:DI 2 "register_operand" "r")))
831    (clobber (reg:SI 17))]
832   ""
833   "#"
834   [(set_attr "type" "multi")
835    (set_attr "length" "6")])
836
837 ;; ??? The cmp clears the condition bit.  Can we speed up somehow?
838 (define_split
839   [(set (match_operand:DI 0 "register_operand" "")
840         (plus:DI (match_operand:DI 1 "register_operand" "")
841                  (match_operand:DI 2 "register_operand" "")))
842    (clobber (match_operand 3 "" ""))]
843   "reload_completed"
844   [(parallel [(set (match_dup 3)
845                    (const_int 0))
846               (use (match_dup 4))])
847    (parallel [(set (match_dup 4)
848                    (plus:SI (match_dup 4)
849                             (plus:SI (match_dup 5)
850                                      (match_dup 3))))
851               (set (match_dup 3)
852                    (unspec [(const_int 0)] 3))])
853    (parallel [(set (match_dup 6)
854                    (plus:SI (match_dup 6)
855                             (plus:SI (match_dup 7)
856                                      (match_dup 3))))
857               (set (match_dup 3)
858                    (unspec [(const_int 0)] 3))])]
859   "
860 {
861   operands[4] = operand_subword (operands[0], (WORDS_BIG_ENDIAN != 0), 0, DImode);
862   operands[5] = operand_subword (operands[2], (WORDS_BIG_ENDIAN != 0), 0, DImode);
863   operands[6] = operand_subword (operands[0], (WORDS_BIG_ENDIAN == 0), 0, DImode);
864   operands[7] = operand_subword (operands[2], (WORDS_BIG_ENDIAN == 0), 0, DImode);
865 }")
866
867 (define_insn "*clear_c"
868   [(set (reg:SI 17)
869         (const_int 0))
870    (use (match_operand:SI 0 "register_operand" "r"))]
871   ""
872   "cmp %0,%0"
873   [(set_attr "type" "int2")
874    (set_attr "length" "2")])
875
876 (define_insn "*add_carry"
877   [(set (match_operand:SI 0 "register_operand" "=r")
878         (plus:SI (match_operand:SI 1 "register_operand" "%0")
879                  (plus:SI (match_operand:SI 2 "register_operand" "r")
880                           (reg:SI 17))))
881    (set (reg:SI 17)
882         (unspec [(const_int 0)] 3))]
883   ""
884   "addx %0,%2"
885   [(set_attr "type" "int2")
886    (set_attr "length" "2")])
887
888 (define_insn "subsi3"
889   [(set (match_operand:SI 0 "register_operand" "=r")
890         (minus:SI (match_operand:SI 1 "register_operand" "0")
891                   (match_operand:SI 2 "register_operand" "r")))]
892   ""
893   "sub %0,%2"
894   [(set_attr "type" "int2")
895    (set_attr "length" "2")])
896
897 (define_insn "subdi3"
898   [(set (match_operand:DI 0 "register_operand" "=r")
899         (minus:DI (match_operand:DI 1 "register_operand" "0")
900                   (match_operand:DI 2 "register_operand" "r")))
901    (clobber (reg:SI 17))]
902   ""
903   "#"
904   [(set_attr "type" "multi")
905    (set_attr "length" "6")])
906
907 ;; ??? The cmp clears the condition bit.  Can we speed up somehow?
908 (define_split
909   [(set (match_operand:DI 0 "register_operand" "")
910         (minus:DI (match_operand:DI 1 "register_operand" "")
911                   (match_operand:DI 2 "register_operand" "")))
912    (clobber (match_operand 3 "" ""))]
913   "reload_completed"
914   [(parallel [(set (match_dup 3)
915                    (const_int 0))
916               (use (match_dup 4))])
917    (parallel [(set (match_dup 4)
918                    (minus:SI (match_dup 4)
919                              (minus:SI (match_dup 5)
920                                        (match_dup 3))))
921               (set (match_dup 3)
922                    (unspec [(const_int 0)] 3))])
923    (parallel [(set (match_dup 6)
924                    (minus:SI (match_dup 6)
925                              (minus:SI (match_dup 7)
926                                        (match_dup 3))))
927               (set (match_dup 3)
928                    (unspec [(const_int 0)] 3))])]
929   "
930 {
931   operands[4] = operand_subword (operands[0], (WORDS_BIG_ENDIAN != 0), 0, DImode);
932   operands[5] = operand_subword (operands[2], (WORDS_BIG_ENDIAN != 0), 0, DImode);
933   operands[6] = operand_subword (operands[0], (WORDS_BIG_ENDIAN == 0), 0, DImode);
934   operands[7] = operand_subword (operands[2], (WORDS_BIG_ENDIAN == 0), 0, DImode);
935 }")
936
937 (define_insn "*sub_carry"
938   [(set (match_operand:SI 0 "register_operand" "=r")
939         (minus:SI (match_operand:SI 1 "register_operand" "%0")
940                   (minus:SI (match_operand:SI 2 "register_operand" "r")
941                             (reg:SI 17))))
942    (set (reg:SI 17)
943         (unspec [(const_int 0)] 3))]
944   ""
945   "subx %0,%2"
946   [(set_attr "type" "int2")
947    (set_attr "length" "2")])
948 \f
949 ; Multiply/Divide instructions.
950
951 (define_insn "mulhisi3"
952   [(set (match_operand:SI 0 "register_operand" "=r")
953         (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" "r"))
954                  (sign_extend:SI (match_operand:HI 2 "register_operand" "r"))))]
955   ""
956   "mullo %1,%2\;mvfacmi %0"
957   [(set_attr "type" "multi")
958    (set_attr "length" "4")])
959
960 (define_insn "mulsi3"
961   [(set (match_operand:SI 0 "register_operand" "=r")
962         (mult:SI (match_operand:SI 1 "register_operand" "%0")
963                  (match_operand:SI 2 "register_operand" "r")))]
964   ""
965   "mul %0,%2"
966   [(set_attr "type" "mul2")
967    (set_attr "length" "2")])
968
969 (define_insn "divsi3"
970   [(set (match_operand:SI 0 "register_operand" "=r")
971         (div:SI (match_operand:SI 1 "register_operand" "0")
972                 (match_operand:SI 2 "register_operand" "r")))]
973   ""
974   "div %0,%2"
975   [(set_attr "type" "div4")
976    (set_attr "length" "4")])
977
978 (define_insn "udivsi3"
979   [(set (match_operand:SI 0 "register_operand" "=r")
980         (udiv:SI (match_operand:SI 1 "register_operand" "0")
981                  (match_operand:SI 2 "register_operand" "r")))]
982   ""
983   "divu %0,%2"
984   [(set_attr "type" "div4")
985    (set_attr "length" "4")])
986
987 (define_insn "modsi3"
988   [(set (match_operand:SI 0 "register_operand" "=r")
989         (mod:SI (match_operand:SI 1 "register_operand" "0")
990                 (match_operand:SI 2 "register_operand" "r")))]
991   ""
992   "rem %0,%2"
993   [(set_attr "type" "div4")
994    (set_attr "length" "4")])
995
996 (define_insn "umodsi3"
997   [(set (match_operand:SI 0 "register_operand" "=r")
998         (umod:SI (match_operand:SI 1 "register_operand" "0")
999                  (match_operand:SI 2 "register_operand" "r")))]
1000   ""
1001   "remu %0,%2"
1002   [(set_attr "type" "div4")
1003    (set_attr "length" "4")])
1004 \f
1005 ;; Boolean instructions.
1006 ;;
1007 ;; We don't define the DImode versions as expand_binop does a good enough job.
1008 ;; And if it doesn't it should be fixed.
1009
1010 (define_insn "andsi3"
1011   [(set (match_operand:SI 0 "register_operand" "=r,r")
1012         (and:SI (match_operand:SI 1 "register_operand" "%0,r")
1013                 (match_operand:SI 2 "reg_or_uint16_operand" "r,K")))]
1014   ""
1015   "*
1016 {
1017   /* If we are worried about space, see if we can break this up into two
1018      short instructions, which might eliminate a NOP being inserted.  */
1019   if (optimize_size
1020       && m32r_not_same_reg (operands[0], operands[1])
1021       && GET_CODE (operands[2]) == CONST_INT
1022       && INT8_P (INTVAL (operands[2])))
1023     return \"#\";
1024
1025   else if (GET_CODE (operands[2]) == CONST_INT)
1026     return \"and3 %0,%1,%#%X2\";
1027
1028   return \"and %0,%2\";
1029 }"
1030   [(set_attr "type" "int2,int4")
1031    (set_attr "length" "2,4")])
1032
1033 (define_split
1034   [(set (match_operand:SI 0 "register_operand" "")
1035         (and:SI (match_operand:SI 1 "register_operand" "")
1036                 (match_operand:SI 2 "int8_operand" "")))]
1037   "optimize_size && m32r_not_same_reg (operands[0], operands[1])"
1038   [(set (match_dup 0) (match_dup 2))
1039    (set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))]
1040   "")
1041
1042 (define_insn "iorsi3"
1043   [(set (match_operand:SI 0 "register_operand" "=r,r")
1044         (ior:SI (match_operand:SI 1 "register_operand" "%0,r")
1045                 (match_operand:SI 2 "reg_or_uint16_operand" "r,K")))]
1046   ""
1047   "*
1048 {
1049   /* If we are worried about space, see if we can break this up into two
1050      short instructions, which might eliminate a NOP being inserted.  */
1051   if (optimize_size
1052       && m32r_not_same_reg (operands[0], operands[1])
1053       && GET_CODE (operands[2]) == CONST_INT
1054       && INT8_P (INTVAL (operands[2])))
1055     return \"#\";
1056
1057   else if (GET_CODE (operands[2]) == CONST_INT)
1058     return \"or3 %0,%1,%#%X2\";
1059
1060   return \"or %0,%2\";
1061 }"
1062   [(set_attr "type" "int2,int4")
1063    (set_attr "length" "2,4")])
1064
1065 (define_split
1066   [(set (match_operand:SI 0 "register_operand" "")
1067         (ior:SI (match_operand:SI 1 "register_operand" "")
1068                 (match_operand:SI 2 "int8_operand" "")))]
1069   "optimize_size && m32r_not_same_reg (operands[0], operands[1])"
1070   [(set (match_dup 0) (match_dup 2))
1071    (set (match_dup 0) (ior:SI (match_dup 0) (match_dup 1)))]
1072   "")
1073
1074 (define_insn "xorsi3"
1075   [(set (match_operand:SI 0 "register_operand" "=r,r")
1076         (xor:SI (match_operand:SI 1 "register_operand" "%0,r")
1077                 (match_operand:SI 2 "reg_or_uint16_operand" "r,K")))]
1078   ""
1079   "*
1080 {
1081   /* If we are worried about space, see if we can break this up into two
1082      short instructions, which might eliminate a NOP being inserted.  */
1083   if (optimize_size
1084       && m32r_not_same_reg (operands[0], operands[1])
1085       && GET_CODE (operands[2]) == CONST_INT
1086       && INT8_P (INTVAL (operands[2])))
1087     return \"#\";
1088
1089   else if (GET_CODE (operands[2]) == CONST_INT)
1090     return \"xor3 %0,%1,%#%X2\";
1091
1092   return \"xor %0,%2\";
1093 }"
1094   [(set_attr "type" "int2,int4")
1095    (set_attr "length" "2,4")])
1096
1097 (define_split
1098   [(set (match_operand:SI 0 "register_operand" "")
1099         (xor:SI (match_operand:SI 1 "register_operand" "")
1100                 (match_operand:SI 2 "int8_operand" "")))]
1101   "optimize_size && m32r_not_same_reg (operands[0], operands[1])"
1102   [(set (match_dup 0) (match_dup 2))
1103    (set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))]
1104   "")
1105
1106 (define_insn "negsi2"
1107   [(set (match_operand:SI 0 "register_operand" "=r")
1108         (neg:SI (match_operand:SI 1 "register_operand" "r")))]
1109   ""
1110   "neg %0,%1"
1111   [(set_attr "type" "int2")
1112    (set_attr "length" "2")])
1113
1114 (define_insn "one_cmplsi2"
1115   [(set (match_operand:SI 0 "register_operand" "=r")
1116         (not:SI (match_operand:SI 1 "register_operand" "r")))]
1117   ""
1118   "not %0,%1"
1119   [(set_attr "type" "int2")
1120    (set_attr "length" "2")])
1121 \f
1122 ;; Shift instructions.
1123
1124 (define_insn "ashlsi3"
1125   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
1126         (ashift:SI (match_operand:SI 1 "register_operand" "0,0,r")
1127                    (match_operand:SI 2 "reg_or_uint16_operand" "r,O,K")))]
1128   ""
1129   "@
1130    sll %0,%2
1131    slli %0,%#%2
1132    sll3 %0,%1,%#%2"
1133   [(set_attr "type" "shift2,shift2,shift4")
1134    (set_attr "length" "2,2,4")])
1135
1136 (define_insn "ashrsi3"
1137   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
1138         (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0,r")
1139                      (match_operand:SI 2 "reg_or_uint16_operand" "r,O,K")))]
1140   ""
1141   "@
1142    sra %0,%2
1143    srai %0,%#%2
1144    sra3 %0,%1,%#%2"
1145   [(set_attr "type" "shift2,shift2,shift4")
1146    (set_attr "length" "2,2,4")])
1147
1148 (define_insn "lshrsi3"
1149   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
1150         (lshiftrt:SI (match_operand:SI 1 "register_operand" "0,0,r")
1151                      (match_operand:SI 2 "reg_or_uint16_operand" "r,O,K")))]
1152   ""
1153   "@
1154    srl %0,%2
1155    srli %0,%#%2
1156    srl3 %0,%1,%#%2"
1157   [(set_attr "type" "shift2,shift2,shift4")
1158    (set_attr "length" "2,2,4")])
1159 \f
1160 ;; Compare instructions.
1161 ;; This controls RTL generation and register allocation.
1162
1163 ;; We generate RTL for comparisons and branches by having the cmpxx 
1164 ;; patterns store away the operands.  Then the bcc patterns
1165 ;; emit RTL for both the compare and the branch.
1166 ;;
1167 ;; On the m32r it is more efficient to use the bxxz instructions and
1168 ;; thus merge the compare and branch into one instruction, so they are
1169 ;; preferred.
1170
1171 (define_expand "cmpsi"
1172   [(set (reg:SI 17)
1173         (compare:CC (match_operand:SI 0 "register_operand" "")
1174                     (match_operand:SI 1 "reg_or_cmp_int16_operand" "")))]
1175   ""
1176   "
1177 {
1178   m32r_compare_op0 = operands[0];
1179   m32r_compare_op1 = operands[1];
1180   DONE;
1181 }")
1182
1183 (define_insn "cmp_eqsi_zero_insn"
1184   [(set (reg:SI 17)
1185         (eq:SI (match_operand:SI 0 "register_operand" "r,r")
1186                (match_operand:SI 1 "reg_or_zero_operand" "r,P")))]
1187   "TARGET_M32RX || TARGET_M32R2"
1188   "@
1189    cmpeq %0, %1
1190    cmpz  %0"
1191   [(set_attr "type" "int4")
1192    (set_attr "length" "4")])
1193
1194 ;; The cmp_xxx_insn patterns set the condition bit to the result of the
1195 ;; comparison.  There isn't a "compare equal" instruction so cmp_eqsi_insn
1196 ;; is quite inefficient.  However, it is rarely used.
1197
1198 (define_insn "cmp_eqsi_insn"
1199   [(set (reg:SI 17)
1200         (eq:SI (match_operand:SI 0 "register_operand" "r,r")
1201                (match_operand:SI 1 "reg_or_cmp_int16_operand" "r,P")))
1202    (clobber (match_scratch:SI 2 "=&r,&r"))]
1203   ""
1204   "*
1205 {
1206   if (which_alternative == 0)
1207     {
1208          return \"mv %2,%0\;sub %2,%1\;cmpui %2,#1\";
1209     }
1210   else
1211     {
1212         if (INTVAL (operands [1]) == 0)
1213           return \"cmpui %0, #1\";
1214         else if (REGNO (operands [2]) == REGNO (operands [0]))
1215           return \"addi %0,%#%N1\;cmpui %2,#1\";
1216         else
1217           return \"add3 %2,%0,%#%N1\;cmpui %2,#1\";
1218     }
1219 }"
1220   [(set_attr "type" "multi,multi")
1221    (set_attr "length" "8,8")])
1222
1223 (define_insn "cmp_ltsi_insn"
1224   [(set (reg:SI 17)
1225         (lt:SI (match_operand:SI 0 "register_operand" "r,r")
1226                (match_operand:SI 1 "reg_or_int16_operand" "r,J")))]
1227   ""
1228   "@
1229    cmp %0,%1
1230    cmpi %0,%#%1"
1231   [(set_attr "type" "int2,int4")
1232    (set_attr "length" "2,4")])
1233
1234 (define_insn "cmp_ltusi_insn"
1235   [(set (reg:SI 17)
1236         (ltu:SI (match_operand:SI 0 "register_operand" "r,r")
1237                 (match_operand:SI 1 "reg_or_int16_operand" "r,J")))]
1238   ""
1239   "@
1240    cmpu %0,%1
1241    cmpui %0,%#%1"
1242   [(set_attr "type" "int2,int4")
1243    (set_attr "length" "2,4")])
1244
1245
1246 ;; reg == small constant comparisons are best handled by putting the result
1247 ;; of the comparison in a tmp reg and then using beqz/bnez.
1248 ;; ??? The result register doesn't contain 0/STORE_FLAG_VALUE,
1249 ;; it contains 0/nonzero.
1250
1251 (define_insn "cmp_ne_small_const_insn"
1252   [(set (match_operand:SI 0 "register_operand" "=r,r")
1253         (ne:SI (match_operand:SI 1 "register_operand" "0,r")
1254                (match_operand:SI 2 "cmp_int16_operand" "N,P")))]
1255   ""
1256   "@
1257    addi %0,%#%N2
1258    add3 %0,%1,%#%N2"
1259   [(set_attr "type" "int2,int4")
1260    (set_attr "length" "2,4")])
1261 \f
1262 ;; These control RTL generation for conditional jump insns.
1263
1264 (define_expand "beq"
1265   [(set (pc)
1266         (if_then_else (match_dup 1)
1267                       (label_ref (match_operand 0 "" ""))
1268                       (pc)))]
1269   ""
1270   "
1271 {
1272   operands[1] = gen_compare (EQ, m32r_compare_op0, m32r_compare_op1, FALSE);
1273 }")
1274
1275 (define_expand "bne"
1276   [(set (pc)
1277         (if_then_else (match_dup 1)
1278                       (label_ref (match_operand 0 "" ""))
1279                       (pc)))]
1280   ""
1281   "
1282 {
1283   operands[1] = gen_compare (NE, m32r_compare_op0, m32r_compare_op1, FALSE);
1284 }")
1285
1286 (define_expand "bgt"
1287   [(set (pc)
1288         (if_then_else (match_dup 1)
1289                       (label_ref (match_operand 0 "" ""))
1290                       (pc)))]
1291   ""
1292   "
1293 {
1294   operands[1] = gen_compare (GT, m32r_compare_op0, m32r_compare_op1, FALSE);
1295 }")
1296
1297 (define_expand "ble"
1298   [(set (pc)
1299         (if_then_else (match_dup 1)
1300                       (label_ref (match_operand 0 "" ""))
1301                       (pc)))]
1302   ""
1303   "
1304 {
1305   operands[1] = gen_compare (LE, m32r_compare_op0, m32r_compare_op1, FALSE);
1306 }")
1307
1308 (define_expand "bge"
1309   [(set (pc)
1310         (if_then_else (match_dup 1)
1311                       (label_ref (match_operand 0 "" ""))
1312                       (pc)))]
1313   ""
1314   "
1315 {
1316   operands[1] = gen_compare (GE, m32r_compare_op0, m32r_compare_op1, FALSE);
1317 }")
1318
1319 (define_expand "blt"
1320   [(set (pc)
1321         (if_then_else (match_dup 1)
1322                       (label_ref (match_operand 0 "" ""))
1323                       (pc)))]
1324   ""
1325   "
1326 {
1327   operands[1] = gen_compare (LT, m32r_compare_op0, m32r_compare_op1, FALSE);
1328 }")
1329
1330 (define_expand "bgtu"
1331   [(set (pc)
1332         (if_then_else (match_dup 1)
1333                       (label_ref (match_operand 0 "" ""))
1334                       (pc)))]
1335   ""
1336   "
1337 {
1338   operands[1] = gen_compare (GTU, m32r_compare_op0, m32r_compare_op1, FALSE);
1339 }")
1340
1341 (define_expand "bleu"
1342   [(set (pc)
1343         (if_then_else (match_dup 1)
1344                       (label_ref (match_operand 0 "" ""))
1345                       (pc)))]
1346   ""
1347   "
1348 {
1349   operands[1] = gen_compare (LEU, m32r_compare_op0, m32r_compare_op1, FALSE);
1350 }")
1351
1352 (define_expand "bgeu"
1353   [(set (pc)
1354         (if_then_else (match_dup 1)
1355                       (label_ref (match_operand 0 "" ""))
1356                       (pc)))]
1357   ""
1358   "
1359 {
1360   operands[1] = gen_compare (GEU, m32r_compare_op0, m32r_compare_op1, FALSE);
1361 }")
1362
1363 (define_expand "bltu"
1364   [(set (pc)
1365         (if_then_else (match_dup 1)
1366                       (label_ref (match_operand 0 "" ""))
1367                       (pc)))]
1368   ""
1369   "
1370 {
1371   operands[1] = gen_compare (LTU, m32r_compare_op0, m32r_compare_op1, FALSE);
1372 }")
1373
1374 ;; Now match both normal and inverted jump.
1375
1376 (define_insn "*branch_insn"
1377   [(set (pc)
1378         (if_then_else (match_operator 1 "eqne_comparison_operator"
1379                                       [(reg 17) (const_int 0)])
1380                       (label_ref (match_operand 0 "" ""))
1381                       (pc)))]
1382   ""
1383   "*
1384 {
1385   static char instruction[40];
1386   sprintf (instruction, \"%s%s %%l0\",
1387            (GET_CODE (operands[1]) == NE) ? \"bc\" : \"bnc\",
1388            (get_attr_length (insn) == 2) ? \".s\" : \"\");
1389   return instruction;
1390 }"
1391   [(set_attr "type" "branch")
1392    ; We use 400/800 instead of 512,1024 to account for inaccurate insn
1393    ; lengths and insn alignments that are complex to track.
1394    ; It's not important that we be hyper-precise here.  It may be more
1395    ; important blah blah blah when the chip supports parallel execution
1396    ; blah blah blah but until then blah blah blah this is simple and
1397    ; suffices.
1398    (set (attr "length") (if_then_else (ltu (plus (minus (match_dup 0) (pc))
1399                                                  (const_int 400))
1400                                            (const_int 800))
1401                                       (const_int 2)
1402                                       (const_int 4)))])
1403
1404 (define_insn "*rev_branch_insn"
1405   [(set (pc)
1406         (if_then_else (match_operator 1 "eqne_comparison_operator"
1407                                       [(reg 17) (const_int 0)])
1408                       (pc)
1409                       (label_ref (match_operand 0 "" ""))))]
1410   ;"REVERSIBLE_CC_MODE (GET_MODE (XEXP (operands[1], 0)))"
1411   ""
1412   "*
1413 {
1414   static char instruction[40];
1415   sprintf (instruction, \"%s%s %%l0\",
1416            (GET_CODE (operands[1]) == EQ) ? \"bc\" : \"bnc\",
1417            (get_attr_length (insn) == 2) ? \".s\" : \"\");
1418   return instruction;
1419 }"
1420   [(set_attr "type" "branch")
1421    ; We use 400/800 instead of 512,1024 to account for inaccurate insn
1422    ; lengths and insn alignments that are complex to track.
1423    ; It's not important that we be hyper-precise here.  It may be more
1424    ; important blah blah blah when the chip supports parallel execution
1425    ; blah blah blah but until then blah blah blah this is simple and
1426    ; suffices.
1427    (set (attr "length") (if_then_else (ltu (plus (minus (match_dup 0) (pc))
1428                                                  (const_int 400))
1429                                            (const_int 800))
1430                                       (const_int 2)
1431                                       (const_int 4)))])
1432
1433 ; reg/reg compare and branch insns
1434
1435 (define_insn "*reg_branch_insn"
1436   [(set (pc)
1437         (if_then_else (match_operator 1 "eqne_comparison_operator"
1438                                       [(match_operand:SI 2 "register_operand" "r")
1439                                        (match_operand:SI 3 "register_operand" "r")])
1440                       (label_ref (match_operand 0 "" ""))
1441                       (pc)))]
1442   ""
1443   "*
1444 {
1445   /* Is branch target reachable with beq/bne?  */
1446   if (get_attr_length (insn) == 4)
1447     {
1448       if (GET_CODE (operands[1]) == EQ)
1449         return \"beq %2,%3,%l0\";
1450       else
1451         return \"bne %2,%3,%l0\";
1452     }
1453   else
1454     {
1455       if (GET_CODE (operands[1]) == EQ)
1456         return \"bne %2,%3,1f\;bra %l0\;1:\";
1457       else
1458         return \"beq %2,%3,1f\;bra %l0\;1:\";
1459     }
1460 }"
1461   [(set_attr "type" "branch")
1462   ; We use 25000/50000 instead of 32768/65536 to account for slot filling
1463   ; which is complex to track and inaccurate length specs.
1464    (set (attr "length") (if_then_else (ltu (plus (minus (match_dup 0) (pc))
1465                                                  (const_int 25000))
1466                                            (const_int 50000))
1467                                       (const_int 4)
1468                                       (const_int 8)))])
1469
1470 (define_insn "*rev_reg_branch_insn"
1471   [(set (pc)
1472         (if_then_else (match_operator 1 "eqne_comparison_operator"
1473                                       [(match_operand:SI 2 "register_operand" "r")
1474                                        (match_operand:SI 3 "register_operand" "r")])
1475                       (pc)
1476                       (label_ref (match_operand 0 "" ""))))]
1477   ""
1478   "*
1479 {
1480   /* Is branch target reachable with beq/bne?  */
1481   if (get_attr_length (insn) == 4)
1482     {
1483       if (GET_CODE (operands[1]) == NE)
1484         return \"beq %2,%3,%l0\";
1485       else
1486         return \"bne %2,%3,%l0\";
1487     }
1488   else
1489     {
1490       if (GET_CODE (operands[1]) == NE)
1491         return \"bne %2,%3,1f\;bra %l0\;1:\";
1492       else
1493         return \"beq %2,%3,1f\;bra %l0\;1:\";
1494     }
1495 }"
1496   [(set_attr "type" "branch")
1497   ; We use 25000/50000 instead of 32768/65536 to account for slot filling
1498   ; which is complex to track and inaccurate length specs.
1499    (set (attr "length") (if_then_else (ltu (plus (minus (match_dup 0) (pc))
1500                                                  (const_int 25000))
1501                                            (const_int 50000))
1502                                       (const_int 4)
1503                                       (const_int 8)))])
1504
1505 ; reg/zero compare and branch insns
1506
1507 (define_insn "*zero_branch_insn"
1508   [(set (pc)
1509         (if_then_else (match_operator 1 "signed_comparison_operator"
1510                                       [(match_operand:SI 2 "register_operand" "r")
1511                                        (const_int 0)])
1512                       (label_ref (match_operand 0 "" ""))
1513                       (pc)))]
1514   ""
1515   "*
1516 {
1517   const char *br,*invbr;
1518   char asmtext[40];
1519
1520   switch (GET_CODE (operands[1]))
1521     {
1522       case EQ : br = \"eq\"; invbr = \"ne\"; break;
1523       case NE : br = \"ne\"; invbr = \"eq\"; break;
1524       case LE : br = \"le\"; invbr = \"gt\"; break;
1525       case GT : br = \"gt\"; invbr = \"le\"; break;
1526       case LT : br = \"lt\"; invbr = \"ge\"; break;
1527       case GE : br = \"ge\"; invbr = \"lt\"; break;
1528
1529       default: abort();
1530     }
1531
1532   /* Is branch target reachable with bxxz?  */
1533   if (get_attr_length (insn) == 4)
1534     {
1535       sprintf (asmtext, \"b%sz %%2,%%l0\", br);
1536       output_asm_insn (asmtext, operands);
1537     }
1538   else
1539     {
1540       sprintf (asmtext, \"b%sz %%2,1f\;bra %%l0\;1:\", invbr);
1541       output_asm_insn (asmtext, operands);
1542     }
1543   return \"\";
1544 }"
1545   [(set_attr "type" "branch")
1546   ; We use 25000/50000 instead of 32768/65536 to account for slot filling
1547   ; which is complex to track and inaccurate length specs.
1548    (set (attr "length") (if_then_else (ltu (plus (minus (match_dup 0) (pc))
1549                                                  (const_int 25000))
1550                                            (const_int 50000))
1551                                       (const_int 4)
1552                                       (const_int 8)))])
1553
1554 (define_insn "*rev_zero_branch_insn"
1555   [(set (pc)
1556         (if_then_else (match_operator 1 "eqne_comparison_operator"
1557                                       [(match_operand:SI 2 "register_operand" "r")
1558                                        (const_int 0)])
1559                       (pc)
1560                       (label_ref (match_operand 0 "" ""))))]
1561   ""
1562   "*
1563 {
1564   const char *br,*invbr;
1565   char asmtext[40];
1566
1567   switch (GET_CODE (operands[1]))
1568     {
1569       case EQ : br = \"eq\"; invbr = \"ne\"; break;
1570       case NE : br = \"ne\"; invbr = \"eq\"; break;
1571       case LE : br = \"le\"; invbr = \"gt\"; break;
1572       case GT : br = \"gt\"; invbr = \"le\"; break;
1573       case LT : br = \"lt\"; invbr = \"ge\"; break;
1574       case GE : br = \"ge\"; invbr = \"lt\"; break;
1575
1576       default: abort();
1577     }
1578
1579   /* Is branch target reachable with bxxz?  */
1580   if (get_attr_length (insn) == 4)
1581     {
1582       sprintf (asmtext, \"b%sz %%2,%%l0\", invbr);
1583       output_asm_insn (asmtext, operands);
1584     }
1585   else
1586     {
1587       sprintf (asmtext, \"b%sz %%2,1f\;bra %%l0\;1:\", br);
1588       output_asm_insn (asmtext, operands);
1589     }
1590   return \"\";
1591 }"
1592   [(set_attr "type" "branch")
1593   ; We use 25000/50000 instead of 32768/65536 to account for slot filling
1594   ; which is complex to track and inaccurate length specs.
1595    (set (attr "length") (if_then_else (ltu (plus (minus (match_dup 0) (pc))
1596                                                  (const_int 25000))
1597                                            (const_int 50000))
1598                                       (const_int 4)
1599                                       (const_int 8)))])
1600 \f
1601 ;; S<cc> operations to set a register to 1/0 based on a comparison
1602
1603 (define_expand "seq"
1604   [(match_operand:SI 0 "register_operand" "")]
1605   ""
1606   "
1607 {
1608   rtx op0 = operands[0];
1609   rtx op1 = m32r_compare_op0;
1610   rtx op2 = m32r_compare_op1;
1611   enum machine_mode mode = GET_MODE (op0);
1612
1613   if (mode != SImode)
1614     FAIL;
1615
1616   if (! register_operand (op1, mode))
1617     op1 = force_reg (mode, op1);
1618
1619   if (TARGET_M32RX || TARGET_M32R2)
1620     {
1621       if (! reg_or_zero_operand (op2, mode))
1622         op2 = force_reg (mode, op2);
1623
1624       emit_insn (gen_seq_insn_m32rx (op0, op1, op2));
1625       DONE;
1626     }
1627   if (GET_CODE (op2) == CONST_INT && INTVAL (op2) == 0)
1628     {
1629       emit_insn (gen_seq_zero_insn (op0, op1));
1630       DONE;
1631     }
1632
1633   if (! reg_or_eq_int16_operand (op2, mode))
1634     op2 = force_reg (mode, op2);
1635
1636   emit_insn (gen_seq_insn (op0, op1, op2));
1637   DONE;
1638 }")
1639
1640 (define_insn "seq_insn_m32rx"
1641   [(set (match_operand:SI 0 "register_operand" "=r")
1642         (eq:SI (match_operand:SI 1 "register_operand" "%r")
1643                (match_operand:SI 2 "reg_or_zero_operand" "rP")))
1644    (clobber (reg:SI 17))]
1645   "TARGET_M32RX || TARGET_M32R2"
1646   "#"
1647   [(set_attr "type" "multi")
1648    (set_attr "length" "6")])
1649
1650 (define_split
1651   [(set (match_operand:SI 0 "register_operand" "")
1652         (eq:SI (match_operand:SI 1 "register_operand" "")
1653                (match_operand:SI 2 "reg_or_zero_operand" "")))
1654    (clobber (reg:SI 17))]
1655   "TARGET_M32RX || TARGET_M32R2"
1656   [(set (reg:SI 17)
1657         (eq:SI (match_dup 1)
1658                (match_dup 2)))
1659    (set (match_dup 0)
1660         (reg:SI 17))]
1661   "")
1662
1663 (define_insn "seq_zero_insn"
1664   [(set (match_operand:SI 0 "register_operand" "=r")
1665         (eq:SI (match_operand:SI 1 "register_operand" "r")
1666                (const_int 0)))
1667    (clobber (reg:SI 17))]
1668   "TARGET_M32R"
1669   "#"
1670   [(set_attr "type" "multi")
1671    (set_attr "length" "6")])
1672
1673 (define_split
1674   [(set (match_operand:SI 0 "register_operand" "")
1675         (eq:SI (match_operand:SI 1 "register_operand" "")
1676                (const_int 0)))
1677    (clobber (reg:SI 17))]
1678   "TARGET_M32R"
1679   [(match_dup 3)]
1680   "
1681 {
1682   rtx op0 = operands[0];
1683   rtx op1 = operands[1];
1684
1685   start_sequence ();
1686   emit_insn (gen_cmp_ltusi_insn (op1, GEN_INT (1)));
1687   emit_insn (gen_movcc_insn (op0));
1688   operands[3] = get_insns ();
1689   end_sequence ();
1690 }")
1691
1692 (define_insn "seq_insn"
1693   [(set (match_operand:SI 0 "register_operand" "=r,r,??r,r")
1694         (eq:SI (match_operand:SI 1 "register_operand" "r,r,r,r")
1695                (match_operand:SI 2 "reg_or_eq_int16_operand" "r,r,r,PK")))
1696    (clobber (reg:SI 17))
1697    (clobber (match_scratch:SI 3 "=1,2,&r,r"))]
1698   "TARGET_M32R"
1699   "#"
1700   [(set_attr "type" "multi")
1701    (set_attr "length" "8,8,10,10")])
1702
1703 (define_split
1704   [(set (match_operand:SI 0 "register_operand" "")
1705         (eq:SI (match_operand:SI 1 "register_operand" "")
1706                (match_operand:SI 2 "reg_or_eq_int16_operand" "")))
1707    (clobber (reg:SI 17))
1708    (clobber (match_scratch:SI 3 ""))]
1709   "TARGET_M32R && reload_completed"
1710   [(match_dup 4)]
1711   "
1712 {
1713   rtx op0 = operands[0];
1714   rtx op1 = operands[1];
1715   rtx op2 = operands[2];
1716   rtx op3 = operands[3];
1717   HOST_WIDE_INT value;
1718
1719   if (GET_CODE (op2) == REG && GET_CODE (op3) == REG
1720       && REGNO (op2) == REGNO (op3))
1721     {
1722       op1 = operands[2];
1723       op2 = operands[1];
1724     }
1725
1726   start_sequence ();
1727   if (GET_CODE (op1) == REG && GET_CODE (op3) == REG
1728       && REGNO (op1) != REGNO (op3))
1729     {
1730       emit_move_insn (op3, op1);
1731       op1 = op3;
1732     }
1733
1734   if (GET_CODE (op2) == CONST_INT && (value = INTVAL (op2)) != 0
1735       && CMP_INT16_P (value))
1736     emit_insn (gen_addsi3 (op3, op1, GEN_INT (-value)));
1737   else
1738     emit_insn (gen_xorsi3 (op3, op1, op2));
1739
1740   emit_insn (gen_cmp_ltusi_insn (op3, GEN_INT (1)));
1741   emit_insn (gen_movcc_insn (op0));
1742   operands[4] = get_insns ();
1743   end_sequence ();
1744 }")
1745
1746 (define_expand "sne"
1747   [(match_operand:SI 0 "register_operand" "")]
1748   ""
1749   "
1750 {
1751   rtx op0 = operands[0];
1752   rtx op1 = m32r_compare_op0;
1753   rtx op2 = m32r_compare_op1;
1754   enum machine_mode mode = GET_MODE (op0);
1755
1756   if (mode != SImode)
1757     FAIL;
1758
1759   if (GET_CODE (op2) != CONST_INT
1760       || (INTVAL (op2) != 0 && UINT16_P (INTVAL (op2))))
1761     {
1762       rtx reg;
1763
1764       if (reload_completed || reload_in_progress)
1765         FAIL;
1766
1767       reg = gen_reg_rtx (SImode);
1768       emit_insn (gen_xorsi3 (reg, op1, op2));
1769       op1 = reg;
1770
1771       if (! register_operand (op1, mode))
1772         op1 = force_reg (mode, op1);
1773
1774       emit_insn (gen_sne_zero_insn (op0, op1));
1775       DONE;
1776     }
1777   else
1778     FAIL;
1779 }")
1780
1781 (define_insn "sne_zero_insn"
1782   [(set (match_operand:SI 0 "register_operand" "=r")
1783         (ne:SI (match_operand:SI 1 "register_operand" "r")
1784                (const_int 0)))
1785    (clobber (reg:SI 17))
1786    (clobber (match_scratch:SI 2 "=&r"))]
1787   ""
1788   "#"
1789   [(set_attr "type" "multi")
1790    (set_attr "length" "6")])
1791
1792 (define_split
1793   [(set (match_operand:SI 0 "register_operand" "")
1794         (ne:SI (match_operand:SI 1 "register_operand" "")
1795                (const_int 0)))
1796    (clobber (reg:SI 17))
1797    (clobber (match_scratch:SI 2 ""))]
1798   "reload_completed"
1799   [(set (match_dup 2)
1800         (const_int 0))
1801    (set (reg:SI 17)
1802         (ltu:SI (match_dup 2)
1803                 (match_dup 1)))
1804    (set (match_dup 0)
1805         (reg:SI 17))]
1806   "")
1807         
1808 (define_expand "slt"
1809   [(match_operand:SI 0 "register_operand" "")]
1810   ""
1811   "
1812 {
1813   rtx op0 = operands[0];
1814   rtx op1 = m32r_compare_op0;
1815   rtx op2 = m32r_compare_op1;
1816   enum machine_mode mode = GET_MODE (op0);
1817
1818   if (mode != SImode)
1819     FAIL;
1820
1821   if (! register_operand (op1, mode))
1822     op1 = force_reg (mode, op1);
1823
1824   if (! reg_or_int16_operand (op2, mode))
1825     op2 = force_reg (mode, op2);
1826
1827   emit_insn (gen_slt_insn (op0, op1, op2));
1828   DONE;
1829 }")
1830
1831 (define_insn "slt_insn"
1832   [(set (match_operand:SI 0 "register_operand" "=r,r")
1833         (lt:SI (match_operand:SI 1 "register_operand" "r,r")
1834                (match_operand:SI 2 "reg_or_int16_operand" "r,J")))
1835    (clobber (reg:SI 17))]
1836   ""
1837   "#"
1838   [(set_attr "type" "multi")
1839    (set_attr "length" "4,6")])
1840
1841 (define_split
1842   [(set (match_operand:SI 0 "register_operand" "")
1843         (lt:SI (match_operand:SI 1 "register_operand" "")
1844                (match_operand:SI 2 "reg_or_int16_operand" "")))
1845    (clobber (reg:SI 17))]
1846   ""
1847   [(set (reg:SI 17)
1848         (lt:SI (match_dup 1)
1849                (match_dup 2)))
1850    (set (match_dup 0)
1851         (reg:SI 17))]
1852   "")
1853
1854 (define_expand "sle"
1855   [(match_operand:SI 0 "register_operand" "")]
1856   ""
1857   "
1858 {
1859   rtx op0 = operands[0];
1860   rtx op1 = m32r_compare_op0;
1861   rtx op2 = m32r_compare_op1;
1862   enum machine_mode mode = GET_MODE (op0);
1863
1864   if (mode != SImode)
1865     FAIL;
1866
1867   if (! register_operand (op1, mode))
1868     op1 = force_reg (mode, op1);
1869
1870   if (GET_CODE (op2) == CONST_INT)
1871     {
1872       HOST_WIDE_INT value = INTVAL (op2);
1873       if (value >= 2147483647)
1874         {
1875           emit_move_insn (op0, GEN_INT (1));
1876           DONE;
1877         }
1878
1879       op2 = GEN_INT (value+1);
1880       if (value < -32768 || value >= 32767)
1881         op2 = force_reg (mode, op2);
1882
1883       emit_insn (gen_slt_insn (op0, op1, op2));
1884       DONE;
1885     }
1886
1887   if (! register_operand (op2, mode))
1888     op2 = force_reg (mode, op2);
1889
1890   emit_insn (gen_sle_insn (op0, op1, op2));
1891   DONE;
1892 }")
1893
1894 (define_insn "sle_insn"
1895   [(set (match_operand:SI 0 "register_operand" "=r")
1896         (le:SI (match_operand:SI 1 "register_operand" "r")
1897                (match_operand:SI 2 "register_operand" "r")))
1898    (clobber (reg:SI 17))]
1899   ""
1900   "#"
1901   [(set_attr "type" "multi")
1902    (set_attr "length" "8")])
1903
1904 (define_split
1905   [(set (match_operand:SI 0 "register_operand" "")
1906         (le:SI (match_operand:SI 1 "register_operand" "")
1907                (match_operand:SI 2 "register_operand" "")))
1908    (clobber (reg:SI 17))]
1909   "!optimize_size"
1910   [(set (reg:SI 17)
1911         (lt:SI (match_dup 2)
1912                (match_dup 1)))
1913    (set (match_dup 0)
1914         (reg:SI 17))
1915    (set (match_dup 0)
1916         (xor:SI (match_dup 0)
1917                 (const_int 1)))]
1918   "")
1919
1920 ;; If optimizing for space, use -(reg - 1) to invert the comparison rather than
1921 ;; xor reg,reg,1 which might eliminate a NOP being inserted.
1922 (define_split
1923   [(set (match_operand:SI 0 "register_operand" "")
1924         (le:SI (match_operand:SI 1 "register_operand" "")
1925                (match_operand:SI 2 "register_operand" "")))
1926    (clobber (reg:SI 17))]
1927   "optimize_size"
1928   [(set (reg:SI 17)
1929         (lt:SI (match_dup 2)
1930                (match_dup 1)))
1931    (set (match_dup 0)
1932         (reg:SI 17))
1933    (set (match_dup 0)
1934         (plus:SI (match_dup 0)
1935                  (const_int -1)))
1936    (set (match_dup 0)
1937         (neg:SI (match_dup 0)))]
1938   "")
1939
1940 (define_expand "sgt"
1941   [(match_operand:SI 0 "register_operand" "")]
1942   ""
1943   "
1944 {
1945   rtx op0 = operands[0];
1946   rtx op1 = m32r_compare_op0;
1947   rtx op2 = m32r_compare_op1;
1948   enum machine_mode mode = GET_MODE (op0);
1949
1950   if (mode != SImode)
1951     FAIL;
1952
1953   if (! register_operand (op1, mode))
1954     op1 = force_reg (mode, op1);
1955
1956   if (! register_operand (op2, mode))
1957     op2 = force_reg (mode, op2);
1958
1959   emit_insn (gen_slt_insn (op0, op2, op1));
1960   DONE;
1961 }")
1962
1963 (define_expand "sge"
1964   [(match_operand:SI 0 "register_operand" "")]
1965   ""
1966   "
1967 {
1968   rtx op0 = operands[0];
1969   rtx op1 = m32r_compare_op0;
1970   rtx op2 = m32r_compare_op1;
1971   enum machine_mode mode = GET_MODE (op0);
1972
1973   if (mode != SImode)
1974     FAIL;
1975
1976   if (! register_operand (op1, mode))
1977     op1 = force_reg (mode, op1);
1978
1979   if (! reg_or_int16_operand (op2, mode))
1980     op2 = force_reg (mode, op2);
1981
1982   emit_insn (gen_sge_insn (op0, op1, op2));
1983   DONE;
1984 }")
1985
1986 (define_insn "sge_insn"
1987   [(set (match_operand:SI 0 "register_operand" "=r,r")
1988         (ge:SI (match_operand:SI 1 "register_operand" "r,r")
1989                (match_operand:SI 2 "reg_or_int16_operand" "r,J")))
1990    (clobber (reg:SI 17))]
1991   ""
1992   "#"
1993   [(set_attr "type" "multi")
1994    (set_attr "length" "8,10")])
1995
1996 (define_split
1997   [(set (match_operand:SI 0 "register_operand" "")
1998         (ge:SI (match_operand:SI 1 "register_operand" "")
1999                (match_operand:SI 2 "reg_or_int16_operand" "")))
2000    (clobber (reg:SI 17))]
2001   "!optimize_size"
2002   [(set (reg:SI 17)
2003         (lt:SI (match_dup 1)
2004                (match_dup 2)))
2005    (set (match_dup 0)
2006         (reg:SI 17))
2007    (set (match_dup 0)
2008         (xor:SI (match_dup 0)
2009                 (const_int 1)))]
2010   "")
2011
2012 ;; If optimizing for space, use -(reg - 1) to invert the comparison rather than
2013 ;; xor reg,reg,1 which might eliminate a NOP being inserted.
2014 (define_split
2015   [(set (match_operand:SI 0 "register_operand" "")
2016         (ge:SI (match_operand:SI 1 "register_operand" "")
2017                (match_operand:SI 2 "reg_or_int16_operand" "")))
2018    (clobber (reg:SI 17))]
2019   "optimize_size"
2020   [(set (reg:SI 17)
2021         (lt:SI (match_dup 1)
2022                (match_dup 2)))
2023    (set (match_dup 0)
2024         (reg:SI 17))
2025    (set (match_dup 0)
2026         (plus:SI (match_dup 0)
2027                  (const_int -1)))
2028    (set (match_dup 0)
2029         (neg:SI (match_dup 0)))]
2030   "")
2031
2032 (define_expand "sltu"
2033   [(match_operand:SI 0 "register_operand" "")]
2034   ""
2035   "
2036 {
2037   rtx op0 = operands[0];
2038   rtx op1 = m32r_compare_op0;
2039   rtx op2 = m32r_compare_op1;
2040   enum machine_mode mode = GET_MODE (op0);
2041
2042   if (mode != SImode)
2043     FAIL;
2044
2045   if (! register_operand (op1, mode))
2046     op1 = force_reg (mode, op1);
2047
2048   if (! reg_or_int16_operand (op2, mode))
2049     op2 = force_reg (mode, op2);
2050
2051   emit_insn (gen_sltu_insn (op0, op1, op2));
2052   DONE;
2053 }")
2054
2055 (define_insn "sltu_insn"
2056   [(set (match_operand:SI 0 "register_operand" "=r,r")
2057         (ltu:SI (match_operand:SI 1 "register_operand" "r,r")
2058                 (match_operand:SI 2 "reg_or_int16_operand" "r,J")))
2059    (clobber (reg:SI 17))]
2060   ""
2061   "#"
2062   [(set_attr "type" "multi")
2063    (set_attr "length" "6,8")])
2064
2065 (define_split
2066   [(set (match_operand:SI 0 "register_operand" "")
2067         (ltu:SI (match_operand:SI 1 "register_operand" "")
2068                 (match_operand:SI 2 "reg_or_int16_operand" "")))
2069    (clobber (reg:SI 17))]
2070   ""
2071   [(set (reg:SI 17)
2072         (ltu:SI (match_dup 1)
2073                 (match_dup 2)))
2074    (set (match_dup 0)
2075         (reg:SI 17))]
2076   "")
2077
2078 (define_expand "sleu"
2079   [(match_operand:SI 0 "register_operand" "")]
2080   ""
2081   "
2082 {
2083   rtx op0 = operands[0];
2084   rtx op1 = m32r_compare_op0;
2085   rtx op2 = m32r_compare_op1;
2086   enum machine_mode mode = GET_MODE (op0);
2087
2088   if (mode != SImode)
2089     FAIL;
2090
2091   if (GET_CODE (op2) == CONST_INT)
2092     {
2093       HOST_WIDE_INT value = INTVAL (op2);
2094       if (value >= 2147483647)
2095         {
2096           emit_move_insn (op0, GEN_INT (1));
2097           DONE;
2098         }
2099
2100       op2 = GEN_INT (value+1);
2101       if (value < 0 || value >= 32767)
2102         op2 = force_reg (mode, op2);
2103
2104       emit_insn (gen_sltu_insn (op0, op1, op2));
2105       DONE;
2106     }
2107
2108   if (! register_operand (op2, mode))
2109     op2 = force_reg (mode, op2);
2110
2111   emit_insn (gen_sleu_insn (op0, op1, op2));
2112   DONE;
2113 }")
2114
2115 (define_insn "sleu_insn"
2116   [(set (match_operand:SI 0 "register_operand" "=r")
2117         (leu:SI (match_operand:SI 1 "register_operand" "r")
2118                 (match_operand:SI 2 "register_operand" "r")))
2119    (clobber (reg:SI 17))]
2120   ""
2121   "#"
2122   [(set_attr "type" "multi")
2123    (set_attr "length" "8")])
2124
2125 (define_split
2126   [(set (match_operand:SI 0 "register_operand" "")
2127         (leu:SI (match_operand:SI 1 "register_operand" "")
2128                 (match_operand:SI 2 "register_operand" "")))
2129    (clobber (reg:SI 17))]
2130   "!optimize_size"
2131   [(set (reg:SI 17)
2132         (ltu:SI (match_dup 2)
2133                 (match_dup 1)))
2134    (set (match_dup 0)
2135         (reg:SI 17))
2136    (set (match_dup 0)
2137         (xor:SI (match_dup 0)
2138                 (const_int 1)))]
2139   "")
2140
2141 ;; If optimizing for space, use -(reg - 1) to invert the comparison rather than
2142 ;; xor reg,reg,1 which might eliminate a NOP being inserted.
2143 (define_split
2144   [(set (match_operand:SI 0 "register_operand" "")
2145         (leu:SI (match_operand:SI 1 "register_operand" "")
2146                 (match_operand:SI 2 "register_operand" "")))
2147    (clobber (reg:SI 17))]
2148   "optimize_size"
2149   [(set (reg:SI 17)
2150         (ltu:SI (match_dup 2)
2151                 (match_dup 1)))
2152    (set (match_dup 0)
2153         (reg:SI 17))
2154    (set (match_dup 0)
2155         (plus:SI (match_dup 0)
2156                  (const_int -1)))
2157    (set (match_dup 0)
2158         (neg:SI (match_dup 0)))]
2159   "")
2160
2161 (define_expand "sgtu"
2162   [(match_operand:SI 0 "register_operand" "")]
2163   ""
2164   "
2165 {
2166   rtx op0 = operands[0];
2167   rtx op1 = m32r_compare_op0;
2168   rtx op2 = m32r_compare_op1;
2169   enum machine_mode mode = GET_MODE (op0);
2170
2171   if (mode != SImode)
2172     FAIL;
2173
2174   if (! register_operand (op1, mode))
2175     op1 = force_reg (mode, op1);
2176
2177   if (! register_operand (op2, mode))
2178     op2 = force_reg (mode, op2);
2179
2180   emit_insn (gen_sltu_insn (op0, op2, op1));
2181   DONE;
2182 }")
2183
2184 (define_expand "sgeu"
2185   [(match_operand:SI 0 "register_operand" "")]
2186   ""
2187   "
2188 {
2189   rtx op0 = operands[0];
2190   rtx op1 = m32r_compare_op0;
2191   rtx op2 = m32r_compare_op1;
2192   enum machine_mode mode = GET_MODE (op0);
2193
2194   if (mode != SImode)
2195     FAIL;
2196
2197   if (! register_operand (op1, mode))
2198     op1 = force_reg (mode, op1);
2199
2200   if (! reg_or_int16_operand (op2, mode))
2201     op2 = force_reg (mode, op2);
2202
2203   emit_insn (gen_sgeu_insn (op0, op1, op2));
2204   DONE;
2205 }")
2206
2207 (define_insn "sgeu_insn"
2208   [(set (match_operand:SI 0 "register_operand" "=r,r")
2209         (geu:SI (match_operand:SI 1 "register_operand" "r,r")
2210                 (match_operand:SI 2 "reg_or_int16_operand" "r,J")))
2211    (clobber (reg:SI 17))]
2212   ""
2213   "#"
2214   [(set_attr "type" "multi")
2215    (set_attr "length" "8,10")])
2216
2217 (define_split
2218   [(set (match_operand:SI 0 "register_operand" "")
2219         (geu:SI (match_operand:SI 1 "register_operand" "")
2220                 (match_operand:SI 2 "reg_or_int16_operand" "")))
2221    (clobber (reg:SI 17))]
2222   "!optimize_size"
2223   [(set (reg:SI 17)
2224         (ltu:SI (match_dup 1)
2225                 (match_dup 2)))
2226    (set (match_dup 0)
2227         (reg:SI 17))
2228    (set (match_dup 0)
2229         (xor:SI (match_dup 0)
2230                 (const_int 1)))]
2231   "")
2232
2233 ;; If optimizing for space, use -(reg - 1) to invert the comparison rather than
2234 ;; xor reg,reg,1 which might eliminate a NOP being inserted.
2235 (define_split
2236   [(set (match_operand:SI 0 "register_operand" "")
2237         (geu:SI (match_operand:SI 1 "register_operand" "")
2238                 (match_operand:SI 2 "reg_or_int16_operand" "")))
2239    (clobber (reg:SI 17))]
2240   "optimize_size"
2241   [(set (reg:SI 17)
2242         (ltu:SI (match_dup 1)
2243                 (match_dup 2)))
2244    (set (match_dup 0)
2245         (reg:SI 17))
2246    (set (match_dup 0)
2247         (plus:SI (match_dup 0)
2248                  (const_int -1)))
2249    (set (match_dup 0)
2250         (neg:SI (match_dup 0)))]
2251   "")
2252
2253 (define_insn "movcc_insn"
2254   [(set (match_operand:SI 0 "register_operand" "=r")
2255         (reg:SI 17))]
2256   ""
2257   "mvfc %0, cbr"
2258   [(set_attr "type" "misc")
2259    (set_attr "length" "2")])
2260
2261 \f
2262 ;; Unconditional and other jump instructions.
2263
2264 (define_insn "jump"
2265   [(set (pc) (label_ref (match_operand 0 "" "")))]
2266   ""
2267   "bra %l0"
2268   [(set_attr "type" "uncond_branch")
2269    (set (attr "length") (if_then_else (ltu (plus (minus (match_dup 0) (pc))
2270                                                  (const_int 400))
2271                                            (const_int 800))
2272                                       (const_int 2)
2273                                       (const_int 4)))])
2274
2275 (define_insn "indirect_jump"
2276   [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
2277   ""
2278   "jmp %a0"
2279   [(set_attr "type" "uncond_branch")
2280    (set_attr "length" "2")])
2281
2282 (define_insn "return"
2283   [(return)]
2284   "direct_return ()"
2285   "jmp lr"
2286   [(set_attr "type" "uncond_branch")
2287    (set_attr "length" "2")])
2288  
2289 (define_insn "tablejump"
2290   [(set (pc) (match_operand:SI 0 "address_operand" "p"))
2291    (use (label_ref (match_operand 1 "" "")))]
2292   ""
2293   "jmp %a0"
2294   [(set_attr "type" "uncond_branch")
2295    (set_attr "length" "2")])
2296
2297 (define_expand "call"
2298   ;; operands[1] is stack_size_rtx
2299   ;; operands[2] is next_arg_register
2300   [(parallel [(call (match_operand:SI 0 "call_operand" "")
2301                     (match_operand 1 "" ""))
2302              (clobber (reg:SI 14))])]
2303   ""
2304   "")
2305
2306 (define_insn "*call_via_reg"
2307   [(call (mem:SI (match_operand:SI 0 "register_operand" "r"))
2308          (match_operand 1 "" ""))
2309    (clobber (reg:SI 14))]
2310   ""
2311   "jl %0"
2312   [(set_attr "type" "call")
2313    (set_attr "length" "2")])
2314
2315 (define_insn "*call_via_label"
2316   [(call (mem:SI (match_operand:SI 0 "call_address_operand" ""))
2317          (match_operand 1 "" ""))
2318    (clobber (reg:SI 14))]
2319   ""
2320   "*
2321 {
2322   int call26_p = call26_operand (operands[0], FUNCTION_MODE);
2323
2324   if (! call26_p)
2325     {
2326       /* We may not be able to reach with a `bl' insn so punt and leave it to
2327          the linker.
2328          We do this here, rather than doing a force_reg in the define_expand
2329          so these insns won't be separated, say by scheduling, thus simplifying
2330          the linker.  */
2331       return \"seth r14,%T0\;add3 r14,r14,%B0\;jl r14\";
2332     }
2333   else
2334     return \"bl %0\";
2335 }"
2336   [(set_attr "type" "call")
2337    (set (attr "length")
2338         (if_then_else (eq (symbol_ref "call26_operand (operands[0], FUNCTION_MODE)")
2339                           (const_int 0))
2340                       (const_int 12) ; 10 + 2 for nop filler
2341                       ; The return address must be on a 4 byte boundary so
2342                       ; there's no point in using a value of 2 here.  A 2 byte
2343                       ; insn may go in the left slot but we currently can't
2344                       ; use such knowledge.
2345                       (const_int 4)))])
2346
2347 (define_expand "call_value"
2348   ;; operand 2 is stack_size_rtx
2349   ;; operand 3 is next_arg_register
2350   [(parallel [(set (match_operand 0 "register_operand" "=r")
2351                    (call (match_operand:SI 1 "call_operand" "")
2352                          (match_operand 2 "" "")))
2353              (clobber (reg:SI 14))])]
2354   ""
2355   "")
2356
2357 (define_insn "*call_value_via_reg"
2358   [(set (match_operand 0 "register_operand" "=r")
2359         (call (mem:SI (match_operand:SI 1 "register_operand" "r"))
2360               (match_operand 2 "" "")))
2361    (clobber (reg:SI 14))]
2362   ""
2363   "jl %1"
2364   [(set_attr "type" "call")
2365    (set_attr "length" "2")])
2366
2367 (define_insn "*call_value_via_label"
2368   [(set (match_operand 0 "register_operand" "=r")
2369         (call (mem:SI (match_operand:SI 1 "call_address_operand" ""))
2370               (match_operand 2 "" "")))
2371    (clobber (reg:SI 14))]
2372   ""
2373   "*
2374 {
2375   int call26_p = call26_operand (operands[1], FUNCTION_MODE);
2376
2377   if (! call26_p)
2378     {
2379       /* We may not be able to reach with a `bl' insn so punt and leave it to
2380          the linker.
2381          We do this here, rather than doing a force_reg in the define_expand
2382          so these insns won't be separated, say by scheduling, thus simplifying
2383          the linker.  */
2384       return \"seth r14,%T1\;add3 r14,r14,%B1\;jl r14\";
2385     }
2386   else
2387     return \"bl %1\";
2388 }"
2389   [(set_attr "type" "call")
2390    (set (attr "length")
2391         (if_then_else (eq (symbol_ref "call26_operand (operands[1], FUNCTION_MODE)")
2392                           (const_int 0))
2393                       (const_int 12) ; 10 + 2 for nop filler
2394                       ; The return address must be on a 4 byte boundary so
2395                       ; there's no point in using a value of 2 here.  A 2 byte
2396                       ; insn may go in the left slot but we currently can't
2397                       ; use such knowledge.
2398                       (const_int 4)))])
2399 \f
2400 (define_insn "nop"
2401   [(const_int 0)]
2402   ""
2403   "nop"
2404   [(set_attr "type" "int2")
2405    (set_attr "length" "2")])
2406
2407 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
2408 ;; all of memory.  This blocks insns from being moved across this point.
2409
2410 (define_insn "blockage"
2411   [(unspec_volatile [(const_int 0)] 0)]
2412   ""
2413   "")
2414
2415 ;; Special pattern to flush the icache.
2416
2417 (define_insn "flush_icache"
2418   [(unspec_volatile [(match_operand 0 "memory_operand" "m")] 0)]
2419   ""
2420   "* return \"nop ; flush-icache\";"
2421   [(set_attr "type" "int2")
2422    (set_attr "length" "2")])
2423 \f
2424 ;; Speed up fabs and provide correct sign handling for -0
2425
2426 (define_insn "absdf2"
2427   [(set (match_operand:DF 0 "register_operand" "=r")
2428         (abs:DF (match_operand:DF 1 "register_operand" "0")))]
2429   ""
2430   "#"
2431   [(set_attr "type" "multi")
2432    (set_attr "length" "4")])
2433
2434 (define_split
2435   [(set (match_operand:DF 0 "register_operand" "")
2436         (abs:DF (match_operand:DF 1 "register_operand" "")))]
2437   "reload_completed"
2438   [(set (match_dup 2)
2439         (ashift:SI (match_dup 2)
2440                    (const_int 1)))
2441    (set (match_dup 2)
2442         (lshiftrt:SI (match_dup 2)
2443                      (const_int 1)))]
2444   "operands[2] = gen_highpart (SImode, operands[0]);")
2445
2446 (define_insn "abssf2"
2447   [(set (match_operand:SF 0 "register_operand" "=r")
2448         (abs:SF (match_operand:SF 1 "register_operand" "0")))]
2449   ""
2450   "#"
2451   [(set_attr "type" "multi")
2452    (set_attr "length" "4")])
2453
2454 (define_split
2455   [(set (match_operand:SF 0 "register_operand" "")
2456         (abs:SF (match_operand:SF 1 "register_operand" "")))]
2457   "reload_completed"
2458   [(set (match_dup 2)
2459         (ashift:SI (match_dup 2)
2460                    (const_int 1)))
2461    (set (match_dup 2)
2462         (lshiftrt:SI (match_dup 2)
2463                      (const_int 1)))]
2464   "operands[2] = gen_highpart (SImode, operands[0]);")
2465 \f
2466 ;; Conditional move instructions
2467 ;; Based on those done for the d10v
2468
2469 (define_expand "movsicc"
2470   [
2471    (set (match_operand:SI 0 "register_operand" "r")
2472         (if_then_else:SI (match_operand 1 "" "")
2473                          (match_operand:SI 2 "conditional_move_operand" "O")
2474                          (match_operand:SI 3 "conditional_move_operand" "O")
2475         )
2476    )
2477   ]
2478   ""
2479   "
2480 {
2481   if (! zero_and_one (operands [2], operands [3]))
2482     FAIL;
2483
2484   /* Generate the comparison that will set the carry flag.  */
2485   operands[1] = gen_compare (GET_CODE (operands[1]), m32r_compare_op0,
2486                              m32r_compare_op1, TRUE);
2487
2488   /* See other movsicc pattern below for reason why.  */
2489   emit_insn (gen_blockage ());
2490 }")
2491
2492 ;; Generate the conditional instructions based on how the carry flag is examined.
2493 (define_insn "*movsicc_internal"
2494   [(set (match_operand:SI 0 "register_operand" "=r")
2495         (if_then_else:SI (match_operand 1 "carry_compare_operand" "")
2496                          (match_operand:SI 2 "conditional_move_operand" "O")
2497                          (match_operand:SI 3 "conditional_move_operand" "O")
2498         )
2499    )]
2500   "zero_and_one (operands [2], operands[3])"
2501   "* return emit_cond_move (operands, insn);"
2502   [(set_attr "type" "multi")
2503    (set_attr "length" "8")
2504   ]
2505 )
2506
2507 \f
2508 ;; Split up troublesome insns for better scheduling.
2509 ;; FIXME: Peepholes go at the end.
2510
2511 ;; ??? Setting the type attribute may not be useful, but for completeness
2512 ;; we do it.
2513
2514 (define_peephole
2515   [(set (mem:SI (plus:SI (match_operand:SI 0 "register_operand" "r")
2516                          (const_int 4)))
2517         (match_operand:SI 1 "register_operand" "r"))]
2518   "0 && dead_or_set_p (insn, operands[0])"
2519   "st %1,@+%0"
2520   [(set_attr "type" "store2")
2521    (set_attr "length" "2")])
2522
2523 ;; This case is triggered by compiling this code:
2524 ;; 
2525 ;; extern void sub(int *);
2526 ;; void main (void)
2527 ;; {
2528 ;;   int i=2,j=3,k;
2529 ;;   while (i < j)  sub(&k);
2530 ;;   i = j / k;
2531 ;;   sub(&i);
2532 ;;   i = j - k;
2533 ;;   sub(&i);
2534 ;; }
2535 ;;
2536 ;; Without the peephole the following assembler is generated for the
2537 ;; divide and subtract expressions:
2538 ;;
2539 ;;         div r5,r4     
2540 ;;         mv r4,r5      
2541 ;;         st r4,@(4,sp) 
2542 ;;         bl sub
2543 ;; 
2544 ;; Similar code is produced for the subtract expression.  With this
2545 ;; peephole the redundant move is eliminated.
2546 ;;
2547 ;; This optimization only works if PRESERVE_DEATH_INFO_REGNO_P is
2548 ;; defined in m32r.h
2549
2550 (define_peephole
2551   [(set (match_operand:SI 0 "register_operand" "r")
2552         (match_operand:SI 1 "register_operand" "r")
2553    )
2554    (set (mem:SI (plus: SI (match_operand:SI 2 "register_operand" "r")
2555                 (match_operand:SI 3 "immediate_operand" "J")))
2556         (match_dup 0)
2557    )
2558   ]
2559   "0 && dead_or_set_p (insn, operands [0])"
2560   "st %1,@(%3,%2)"
2561   [(set_attr "type" "store4")
2562    (set_attr "length" "4")
2563   ]
2564 )
2565
2566 ;; Block moves, see m32r.c for more details.
2567 ;; Argument 0 is the destination
2568 ;; Argument 1 is the source
2569 ;; Argument 2 is the length
2570 ;; Argument 3 is the alignment
2571
2572 (define_expand "movstrsi"
2573   [(parallel [(set (match_operand:BLK 0 "general_operand" "")
2574                    (match_operand:BLK 1 "general_operand" ""))
2575               (use (match_operand:SI  2 "immediate_operand" ""))
2576               (use (match_operand:SI  3 "immediate_operand" ""))])]
2577   ""
2578   "
2579 {
2580   if (operands[0])              /* avoid unused code messages */
2581     {
2582       m32r_expand_block_move (operands);
2583       DONE;
2584     }
2585 }")
2586
2587 ;; Insn generated by block moves
2588
2589 (define_insn "movstrsi_internal"
2590   [(set (mem:BLK (match_operand:SI 0 "register_operand" "+r"))  ;; destination
2591         (mem:BLK (match_operand:SI 1 "register_operand" "+r"))) ;; source
2592    (use (match_operand:SI 2 "m32r_block_immediate_operand" "J"));; # bytes to move
2593    (set (match_dup 0) (plus:SI (match_dup 0) (minus:SI (match_dup 2) (const_int 4))))
2594    (set (match_dup 1) (plus:SI (match_dup 1) (match_dup 2)))
2595    (clobber (match_scratch:SI 3 "=&r"))                         ;; temp 1
2596    (clobber (match_scratch:SI 4 "=&r"))]                        ;; temp 2
2597   ""
2598   "* m32r_output_block_move (insn, operands); return \"\"; "
2599   [(set_attr "type"     "store8")
2600    (set_attr "length"   "72")]) ;; Maximum