Add support for m32r-linux target.
[official-gcc.git] / gcc / config / m32r / m32r.md
blob5e562a7f5c08fc96568d3d628b8fa6ac80e51196
1 ;; Machine description of the Renesas M32R cpu for GNU C compiler
2 ;; Copyright (C) 1996, 1997, 1998, 1999, 2001, 2003 Free Software Foundation, Inc.
4 ;; This file is part of GCC.
6 ;; GCC is free software; you can redistribute it and/or modify it
7 ;; under the terms of the GNU General Public License as published
8 ;; by the Free Software Foundation; either version 2, or (at your
9 ;; option) any later version.
11 ;; GCC is distributed in the hope that it will be useful, but WITHOUT
12 ;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 ;; or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
14 ;; License for more details.
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.
21 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
23 ;; unspec usage
24 ;; 0 - blockage
25 ;; 1 - flush_icache
26 ;; 2 - load_sda_base
27 ;; 3 - setting carry in addx/subx instructions.
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"))
34 ;; Length in bytes.
35 (define_attr "length" ""
36   (cond [(eq_attr "type" "int2,load2,store2,shift2,mul2")
37          (const_int 2)
39          (eq_attr "type" "int4,load4,store4,shift4,div4")
40          (const_int 4)
42          (eq_attr "type" "multi")
43          (const_int 8)
45          (eq_attr "type" "uncond_branch,branch,call")
46          (const_int 4)]
48          (const_int 4)))
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")])
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")))
63 (define_attr "debug" "no,yes"
64   (const (symbol_ref "(TARGET_DEBUG != 0)")))
66 (define_attr "opt_size" "no,yes"
67   (const (symbol_ref "(optimize_size != 0)")))
69 (define_attr "m32r" "no,yes"
70   (const (symbol_ref "(TARGET_M32R != 0)")))
72 (define_attr "m32rx" "no,yes"
73   (const (symbol_ref "(TARGET_M32RX != 0)")))
75 (define_attr "m32r2" "no,yes"
76   (const (symbol_ref "(TARGET_M32R2 != 0)")))
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")
83          (eq_attr "insn_size" "!short")
84          (const_string "long")]
86         (cond [(eq_attr "type" "int2")
87                (const_string "either")
89                (eq_attr "type" "load2,store2,shift2,uncond_branch,branch,call")
90                (const_string "o")
92                (eq_attr "type" "mul2")
93                (const_string "s")]
95               (const_string "long"))))
97 ;; ::::::::::::::::::::
98 ;; ::
99 ;; :: Function Units
100 ;; ::
101 ;; ::::::::::::::::::::
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.
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.
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.
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.
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:
131 ;; (define_function_unit NAME MULTIPLICITY SIMULTANEITY TEST READY-DELAY
132 ;;   ISSUE-DELAY [CONFLICT-LIST])
134 ;; NAME is a string giving the name of the function unit.
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.)
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.
148 ;; All `define_function_unit' definitions referring to function unit NAME must
149 ;; have the same name and values for MULTIPLICITY and SIMULTANEITY.
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'.
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.
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.
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.
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.
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:
185 ;; (define_function_unit "memory" 1 1 (eq_attr "type" "load") 2 0)
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:
191 ;; (define_function_unit "fp" 1 0
192 ;;   (eq_attr "type" "sp_fp") 4 4
193 ;;   [(eq_attr "type" "dp_fp")])
195 ;; (define_function_unit "fp" 1 0
196 ;;   (eq_attr "type" "dp_fp") 4 4
197 ;;   [(eq_attr "type" "sp_fp")])
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.
208 ;; Function units of the M32R
209 ;; Units that take one cycle do not need to be specified.
211 ;; (define_function_unit {name} {multiplicity} {simultaneity} {test}
212 ;;                       {ready-delay} {issue-delay} [{conflict-list}])
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.
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")])
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")])
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")])
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")])
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")])
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")])
257 (define_function_unit "right" 1 1
258   (eq_attr "m32rx_pipeline" "s,either")
259   1 0
260   [(eq_attr "insn_size" "long")])
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")])
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")])
276 ;; Expand prologue as RTL
277 (define_expand "prologue"
278   [(const_int 1)]
279   ""
280   "
282   m32r_expand_prologue ();
283   DONE;
287 ;; Move instructions.
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].
294 (define_expand "movqi"
295   [(set (match_operand:QI 0 "general_operand" "")
296         (match_operand:QI 1 "general_operand" ""))]
297   ""
298   "
300   /* Fixup PIC cases.  */
301   if (flag_pic)
302     {
303       if (symbolic_operand (operands[1], QImode))
304         {
305           if (reload_in_progress || reload_completed)
306             operands[1] = m32r_legitimize_pic_address (operands[1], operands[0]);
307           else
308             operands[1] = m32r_legitimize_pic_address (operands[1], NULL_RTX);
309         }
310     }
312   /* Everything except mem = const or mem = mem can be done easily.
313      Objects in the small data area are handled too.  */
315   if (GET_CODE (operands[0]) == MEM)
316     operands[1] = force_reg (QImode, operands[1]);
319 (define_insn "*movqi_insn"
320   [(set (match_operand:QI 0 "move_dest_operand" "=r,r,r,r,r,T,m")
321         (match_operand:QI 1 "move_src_operand" "r,I,JQR,T,m,r,r"))]
322   "register_operand (operands[0], QImode) || register_operand (operands[1], QImode)"
323   "@
324    mv %0,%1
325    ldi %0,%#%1
326    ldi %0,%#%1
327    ldub %0,%1
328    ldub %0,%1
329    stb %1,%0
330    stb %1,%0"
331   [(set_attr "type" "int2,int2,int4,load2,load4,store2,store4")
332    (set_attr "length" "2,2,4,2,4,2,4")])
334 (define_expand "movhi"
335   [(set (match_operand:HI 0 "general_operand" "")
336         (match_operand:HI 1 "general_operand" ""))]
337   ""
338   "
340   /* Fixup PIC cases.  */
341   if (flag_pic)
342     {
343       if (symbolic_operand (operands[1], HImode))
344         {
345           if (reload_in_progress || reload_completed)
346             operands[1] = m32r_legitimize_pic_address (operands[1], operands[0]);
347           else
348             operands[1] = m32r_legitimize_pic_address (operands[1], NULL_RTX);
349         }
350     }
352   /* Everything except mem = const or mem = mem can be done easily.  */
354   if (GET_CODE (operands[0]) == MEM)
355     operands[1] = force_reg (HImode, operands[1]);
358 (define_insn "*movhi_insn"
359   [(set (match_operand:HI 0 "move_dest_operand" "=r,r,r,r,r,r,T,m")
360         (match_operand:HI 1 "move_src_operand" "r,I,JQR,K,T,m,r,r"))]
361   "register_operand (operands[0], HImode) || register_operand (operands[1], HImode)"
362   "@
363    mv %0,%1
364    ldi %0,%#%1
365    ldi %0,%#%1
366    ld24 %0,%#%1
367    lduh %0,%1
368    lduh %0,%1
369    sth %1,%0
370    sth %1,%0"
371   [(set_attr "type" "int2,int2,int4,int4,load2,load4,store2,store4")
372    (set_attr "length" "2,2,4,4,2,4,2,4")])
374 (define_expand "movsi_push"
375   [(set (mem:SI (pre_dec:SI (match_operand:SI 0 "register_operand" "")))
376         (match_operand:SI 1 "register_operand" ""))]
377   ""
378   "")
380 (define_expand "movsi_pop"
381   [(set (match_operand:SI 0 "register_operand" "")
382         (mem:SI (post_inc:SI (match_operand:SI 1 "register_operand" ""))))]
383   ""
384   "")
386 (define_expand "movsi"
387   [(set (match_operand:SI 0 "general_operand" "")
388         (match_operand:SI 1 "general_operand" ""))]
389   ""
390   "
392   /* Fixup PIC cases.  */
393   if (flag_pic)
394     {
395       if (symbolic_operand (operands[1], SImode))
396         {
397           if (reload_in_progress || reload_completed)
398             operands[1] = m32r_legitimize_pic_address (operands[1], operands[0]);
399           else
400             operands[1] = m32r_legitimize_pic_address (operands[1], NULL_RTX);
401         }
402     }
404   /* Everything except mem = const or mem = mem can be done easily.  */
406   if (GET_CODE (operands[0]) == MEM)
407     operands[1] = force_reg (SImode, operands[1]);
409   /* Small Data Area reference?  */
410   if (small_data_operand (operands[1], SImode))
411     {
412       emit_insn (gen_movsi_sda (operands[0], operands[1]));
413       DONE;
414     }
416   /* If medium or large code model, symbols have to be loaded with
417      seth/add3.  */
418   if (addr32_operand (operands[1], SImode))
419     {
420       emit_insn (gen_movsi_addr32 (operands[0], operands[1]));
421       DONE;
422     }
425 ;; ??? Do we need a const_double constraint here for large unsigned values?
426 (define_insn "*movsi_insn"
427   [(set (match_operand:SI 0 "move_dest_operand" "=r,r,r,r,r,r,r,r,r,T,S,m")
428         (match_operand:SI 1 "move_src_operand" "r,I,J,MQ,L,n,T,U,m,r,r,r"))]
429   "register_operand (operands[0], SImode) || register_operand (operands[1], SImode)"
430   "*
432   if (GET_CODE (operands[0]) == REG || GET_CODE (operands[1]) == SUBREG)
433     {
434       switch (GET_CODE (operands[1]))
435         {
436           HOST_WIDE_INT value;
438           default:
439             break;
441           case REG:
442           case SUBREG:
443             return \"mv %0,%1\";
445           case MEM:
446             if (GET_CODE (XEXP (operands[1], 0)) == POST_INC
447                 && XEXP (XEXP (operands[1], 0), 0) == stack_pointer_rtx)
448               return \"pop %0\";
450             return \"ld %0,%1\";
452           case CONST_INT:
453             value = INTVAL (operands[1]);
454             if (INT16_P (value))
455               return \"ldi %0,%#%1\\t; %X1\";
457             if (UINT24_P (value))
458               return \"ld24 %0,%#%1\\t; %X1\";
460             if (UPPER16_P (value))
461               return \"seth %0,%#%T1\\t; %X1\";
463             return \"#\";
465           case CONST:
466           case SYMBOL_REF:
467           case LABEL_REF:
468             if (TARGET_ADDR24)
469               return \"ld24 %0,%#%1\";
471             return \"#\";
472         }
473     }
475   else if (GET_CODE (operands[0]) == MEM
476            && (GET_CODE (operands[1]) == REG || GET_CODE (operands[1]) == SUBREG))
477     {
478       if (GET_CODE (XEXP (operands[0], 0)) == PRE_DEC
479           && XEXP (XEXP (operands[0], 0), 0) == stack_pointer_rtx)
480         return \"push %1\";
482       return \"st %1,%0\";
483     }
485   abort ();
487   [(set_attr "type" "int2,int2,int4,int4,int4,multi,load2,load2,load4,store2,store2,store4")
488    (set_attr "length" "2,2,4,4,4,8,2,2,4,2,2,4")])
490 ; Try to use a four byte / two byte pair for constants not loadable with
491 ; ldi, ld24, seth.
493 (define_split
494  [(set (match_operand:SI 0 "register_operand" "")
495        (match_operand:SI 1 "two_insn_const_operand" ""))]
496   ""
497   [(set (match_dup 0) (match_dup 2))
498    (set (match_dup 0) (ior:SI (match_dup 0) (match_dup 3)))]
499   "
501   unsigned HOST_WIDE_INT val = INTVAL (operands[1]);
502   unsigned HOST_WIDE_INT tmp;
503   int shift;
505   /* In all cases we will emit two instructions.  However we try to
506      use 2 byte instructions wherever possible.  We can assume the
507      constant isn't loadable with any of ldi, ld24, or seth.  */
509   /* See if we can load a 24 bit unsigned value and invert it.  */
510   if (UINT24_P (~ val))
511     {
512       emit_insn (gen_movsi (operands[0], GEN_INT (~ val)));
513       emit_insn (gen_one_cmplsi2 (operands[0], operands[0]));
514       DONE;
515     }
517   /* See if we can load a 24 bit unsigned value and shift it into place.
518      0x01fffffe is just beyond ld24's range.  */
519   for (shift = 1, tmp = 0x01fffffe;
520        shift < 8;
521        ++shift, tmp <<= 1)
522     {
523       if ((val & ~tmp) == 0)
524         {
525           emit_insn (gen_movsi (operands[0], GEN_INT (val >> shift)));
526           emit_insn (gen_ashlsi3 (operands[0], operands[0], GEN_INT (shift)));
527           DONE;
528         }
529     }
531   /* Can't use any two byte insn, fall back to seth/or3.  Use ~0xffff instead
532      of 0xffff0000, since the later fails on a 64-bit host.  */
533   operands[2] = GEN_INT ((val) & ~0xffff);
534   operands[3] = GEN_INT ((val) & 0xffff);
537 (define_split
538   [(set (match_operand:SI 0 "register_operand" "")
539         (match_operand:SI 1 "seth_add3_operand" ""))]
540   "TARGET_ADDR32"
541   [(set (match_dup 0)
542         (high:SI (match_dup 1)))
543    (set (match_dup 0)
544         (lo_sum:SI (match_dup 0)
545                    (match_dup 1)))]
546   "")
548 ;; Small data area support.
549 ;; The address of _SDA_BASE_ is loaded into a register and all objects in
550 ;; the small data area are indexed off that.  This is done for each reference
551 ;; but cse will clean things up for us.  We let the compiler choose the
552 ;; register to use so we needn't allocate (and maybe even fix) a special
553 ;; register to use.  Since the load and store insns have a 16 bit offset the
554 ;; total size of the data area can be 64K.  However, if the data area lives
555 ;; above 16M (24 bits), _SDA_BASE_ will have to be loaded with seth/add3 which
556 ;; would then yield 3 instructions to reference an object [though there would
557 ;; be no net loss if two or more objects were referenced].  The 3 insns can be
558 ;; reduced back to 2 if the size of the small data area were reduced to 32K
559 ;; [then seth + ld/st would work for any object in the area].  Doing this
560 ;; would require special handling of _SDA_BASE_ (its value would be
561 ;; (.sdata + 32K) & 0xffff0000) and reloc computations would be different
562 ;; [I think].  What to do about this is deferred until later and for now we
563 ;; require .sdata to be in the first 16M.
565 (define_expand "movsi_sda"
566   [(set (match_dup 2)
567         (unspec [(const_int 0)] 2))
568    (set (match_operand:SI 0 "register_operand" "")
569         (lo_sum:SI (match_dup 2)
570                    (match_operand:SI 1 "small_data_operand" "")))]
571   ""
572   "
574   if (reload_in_progress || reload_completed)
575     operands[2] = operands[0];
576   else
577     operands[2] = gen_reg_rtx (SImode);
580 (define_insn "*load_sda_base"
581   [(set (match_operand:SI 0 "register_operand" "=r")
582         (unspec [(const_int 0)] 2))]
583   ""
584   "ld24 %0,#_SDA_BASE_"
585   [(set_attr "type" "int4")
586    (set_attr "length" "4")])
588 ;; 32 bit address support.
590 (define_expand "movsi_addr32"
591   [(set (match_dup 2)
592         ; addr32_operand isn't used because it's too restrictive,
593         ; seth_add3_operand is more general and thus safer.
594         (high:SI (match_operand:SI 1 "seth_add3_operand" "")))
595    (set (match_operand:SI 0 "register_operand" "")
596         (lo_sum:SI (match_dup 2) (match_dup 1)))]
597   ""
598   "
600   if (reload_in_progress || reload_completed)
601     operands[2] = operands[0];
602   else
603     operands[2] = gen_reg_rtx (SImode);
606 (define_insn "set_hi_si"
607   [(set (match_operand:SI 0 "register_operand" "=r")
608         (high:SI (match_operand 1 "symbolic_operand" "")))]
609   ""
610   "seth %0,%#shigh(%1)"
611   [(set_attr "type" "int4")
612    (set_attr "length" "4")])
614 (define_insn "lo_sum_si"
615   [(set (match_operand:SI 0 "register_operand" "=r")
616         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
617                    (match_operand:SI 2 "immediate_operand" "in")))]
618   ""
619   "add3 %0,%1,%#%B2"
620   [(set_attr "type" "int4")
621    (set_attr "length" "4")])
623 (define_expand "movdi"
624   [(set (match_operand:DI 0 "general_operand" "")
625         (match_operand:DI 1 "general_operand" ""))]
626   ""
627   "
629   /* Fixup PIC cases.  */
630   if (flag_pic)
631     {
632       if (symbolic_operand (operands[1], DImode))
633         {
634           if (reload_in_progress || reload_completed)
635             operands[1] = m32r_legitimize_pic_address (operands[1], operands[0]);
636           else
637             operands[1] = m32r_legitimize_pic_address (operands[1], NULL_RTX);
638         }
639     }
641   /* Everything except mem = const or mem = mem can be done easily.  */
643   if (GET_CODE (operands[0]) == MEM)
644     operands[1] = force_reg (DImode, operands[1]);
647 (define_insn "*movdi_insn"
648   [(set (match_operand:DI 0 "move_dest_operand" "=r,r,r,r,m")
649         (match_operand:DI 1 "move_double_src_operand" "r,nG,F,m,r"))]
650   "register_operand (operands[0], DImode) || register_operand (operands[1], DImode)"
651   "#"
652   [(set_attr "type" "multi,multi,multi,load8,store8")
653    (set_attr "length" "4,4,16,6,6")])
655 (define_split
656   [(set (match_operand:DI 0 "move_dest_operand" "")
657         (match_operand:DI 1 "move_double_src_operand" ""))]
658   "reload_completed"
659   [(match_dup 2)]
660   "operands[2] = gen_split_move_double (operands);")
662 ;; Floating point move insns.
664 (define_expand "movsf"
665   [(set (match_operand:SF 0 "general_operand" "")
666         (match_operand:SF 1 "general_operand" ""))]
667   ""
668   "
670   /* Fixup PIC cases.  */
671   if (flag_pic)
672     {
673       if (symbolic_operand (operands[1], SFmode))
674         {
675           if (reload_in_progress || reload_completed)
676             operands[1] = m32r_legitimize_pic_address (operands[1], operands[0]);
677           else
678             operands[1] = m32r_legitimize_pic_address (operands[1], NULL_RTX);
679         }
680     }
682   /* Everything except mem = const or mem = mem can be done easily.  */
684   if (GET_CODE (operands[0]) == MEM)
685     operands[1] = force_reg (SFmode, operands[1]);
688 (define_insn "*movsf_insn"
689   [(set (match_operand:SF 0 "move_dest_operand" "=r,r,r,r,r,T,S,m")
690         (match_operand:SF 1 "move_src_operand" "r,F,U,S,m,r,r,r"))]
691   "register_operand (operands[0], SFmode) || register_operand (operands[1], SFmode)"
692   "@
693    mv %0,%1
694    #
695    ld %0,%1
696    ld %0,%1
697    ld %0,%1
698    st %1,%0
699    st %1,%0
700    st %1,%0"
701   ;; ??? Length of alternative 1 is either 2, 4 or 8.
702   [(set_attr "type" "int2,multi,load2,load2,load4,store2,store2,store4")
703    (set_attr "length" "2,8,2,2,4,2,2,4")])
705 (define_split
706   [(set (match_operand:SF 0 "register_operand" "")
707         (match_operand:SF 1 "const_double_operand" ""))]
708   "reload_completed"
709   [(set (match_dup 2) (match_dup 3))]
710   "
712   operands[2] = operand_subword (operands[0], 0, 0, SFmode);
713   operands[3] = operand_subword (operands[1], 0, 0, SFmode);
716 (define_expand "movdf"
717   [(set (match_operand:DF 0 "general_operand" "")
718         (match_operand:DF 1 "general_operand" ""))]
719   ""
720   "
722   /* Fixup PIC cases.  */
723   if (flag_pic)
724     {
725       if (symbolic_operand (operands[1], DFmode))
726         {
727           if (reload_in_progress || reload_completed)
728             operands[1] = m32r_legitimize_pic_address (operands[1], operands[0]);
729           else
730             operands[1] = m32r_legitimize_pic_address (operands[1], NULL_RTX);
731         }
732     }
734   /* Everything except mem = const or mem = mem can be done easily.  */
736   if (GET_CODE (operands[0]) == MEM)
737     operands[1] = force_reg (DFmode, operands[1]);
740 (define_insn "*movdf_insn"
741   [(set (match_operand:DF 0 "move_dest_operand" "=r,r,r,m")
742         (match_operand:DF 1 "move_double_src_operand" "r,F,m,r"))]
743   "register_operand (operands[0], DFmode) || register_operand (operands[1], DFmode)"
744   "#"
745   [(set_attr "type" "multi,multi,load8,store8")
746    (set_attr "length" "4,16,6,6")])
748 (define_split
749   [(set (match_operand:DF 0 "move_dest_operand" "")
750         (match_operand:DF 1 "move_double_src_operand" ""))]
751   "reload_completed"
752   [(match_dup 2)]
753   "operands[2] = gen_split_move_double (operands);")
755 ;; Zero extension instructions.
757 (define_insn "zero_extendqihi2"
758   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
759         (zero_extend:HI (match_operand:QI 1 "extend_operand" "r,T,m")))]
760   ""
761   "@
762    and3 %0,%1,%#255
763    ldub %0,%1
764    ldub %0,%1"
765   [(set_attr "type" "int4,load2,load4")
766    (set_attr "length" "4,2,4")])
768 (define_insn "zero_extendqisi2"
769   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
770         (zero_extend:SI (match_operand:QI 1 "extend_operand" "r,T,m")))]
771   ""
772   "@
773    and3 %0,%1,%#255
774    ldub %0,%1
775    ldub %0,%1"
776   [(set_attr "type" "int4,load2,load4")
777    (set_attr "length" "4,2,4")])
779 (define_insn "zero_extendhisi2"
780   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
781         (zero_extend:SI (match_operand:HI 1 "extend_operand" "r,T,m")))]
782   ""
783   "@
784    and3 %0,%1,%#65535
785    lduh %0,%1
786    lduh %0,%1"
787   [(set_attr "type" "int4,load2,load4")
788    (set_attr "length" "4,2,4")])
790 ;; Signed conversions from a smaller integer to a larger integer
791 (define_insn "extendqihi2"
792   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
793         (sign_extend:HI (match_operand:QI 1 "extend_operand" "0,T,m")))]
794   ""
795   "@
796     #
797     ldb %0,%1
798     ldb %0,%1"
799   [(set_attr "type" "multi,load2,load4")
800    (set_attr "length" "2,2,4")])
802 (define_split
803   [(set (match_operand:HI 0 "register_operand" "")
804         (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
805   "reload_completed"
806   [(match_dup 2)
807    (match_dup 3)]
808   "
810   rtx op0   = gen_lowpart (SImode, operands[0]);
811   rtx shift = gen_rtx (CONST_INT, VOIDmode, 24);
813   operands[2] = gen_ashlsi3 (op0, op0, shift);
814   operands[3] = gen_ashrsi3 (op0, op0, shift);
817 (define_insn "extendqisi2"
818   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
819         (sign_extend:SI (match_operand:QI 1 "extend_operand" "0,T,m")))]
820   ""
821   "@
822     #
823     ldb %0,%1
824     ldb %0,%1"
825   [(set_attr "type" "multi,load2,load4")
826    (set_attr "length" "4,2,4")])
828 (define_split
829   [(set (match_operand:SI 0 "register_operand" "")
830         (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
831   "reload_completed"
832   [(match_dup 2)
833    (match_dup 3)]
834   "
836   rtx op0   = gen_lowpart (SImode, operands[0]);
837   rtx shift = gen_rtx (CONST_INT, VOIDmode, 24);
839   operands[2] = gen_ashlsi3 (op0, op0, shift);
840   operands[3] = gen_ashrsi3 (op0, op0, shift);
843 (define_insn "extendhisi2"
844   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
845         (sign_extend:SI (match_operand:HI 1 "extend_operand" "0,T,m")))]
846   ""
847   "@
848     #
849     ldh %0,%1
850     ldh %0,%1"
851   [(set_attr "type" "multi,load2,load4")
852    (set_attr "length" "4,2,4")])
854 (define_split
855   [(set (match_operand:SI 0 "register_operand" "")
856         (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
857   "reload_completed"
858   [(match_dup 2)
859    (match_dup 3)]
860   "
862   rtx op0   = gen_lowpart (SImode, operands[0]);
863   rtx shift = gen_rtx (CONST_INT, VOIDmode, 16);
865   operands[2] = gen_ashlsi3 (op0, op0, shift);
866   operands[3] = gen_ashrsi3 (op0, op0, shift);
869 ;; Arithmetic instructions.
871 ; ??? Adding an alternative to split add3 of small constants into two
872 ; insns yields better instruction packing but slower code.  Adds of small
873 ; values is done a lot.
875 (define_insn "addsi3"
876   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
877         (plus:SI (match_operand:SI 1 "register_operand" "%0,0,r")
878                  (match_operand:SI 2 "nonmemory_operand" "r,I,J")))]
879   ""
880   "@
881    add %0,%2
882    addi %0,%#%2
883    add3 %0,%1,%#%2"
884   [(set_attr "type" "int2,int2,int4")
885    (set_attr "length" "2,2,4")])
887 ;(define_split
888 ;  [(set (match_operand:SI 0 "register_operand" "")
889 ;       (plus:SI (match_operand:SI 1 "register_operand" "")
890 ;                (match_operand:SI 2 "int8_operand" "")))]
891 ;  "reload_completed
892 ;   && REGNO (operands[0]) != REGNO (operands[1])
893 ;   && INT8_P (INTVAL (operands[2]))
894 ;   && INTVAL (operands[2]) != 0"
895 ;  [(set (match_dup 0) (match_dup 1))
896 ;   (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))]
897 ;  "")
899 (define_insn "adddi3"
900   [(set (match_operand:DI 0 "register_operand" "=r")
901         (plus:DI (match_operand:DI 1 "register_operand" "%0")
902                  (match_operand:DI 2 "register_operand" "r")))
903    (clobber (reg:SI 17))]
904   ""
905   "#"
906   [(set_attr "type" "multi")
907    (set_attr "length" "6")])
909 ;; ??? The cmp clears the condition bit.  Can we speed up somehow?
910 (define_split
911   [(set (match_operand:DI 0 "register_operand" "")
912         (plus:DI (match_operand:DI 1 "register_operand" "")
913                  (match_operand:DI 2 "register_operand" "")))
914    (clobber (match_operand 3 "" ""))]
915   "reload_completed"
916   [(parallel [(set (match_dup 3)
917                    (const_int 0))
918               (use (match_dup 4))])
919    (parallel [(set (match_dup 4)
920                    (plus:SI (match_dup 4)
921                             (plus:SI (match_dup 5)
922                                      (match_dup 3))))
923               (set (match_dup 3)
924                    (unspec [(const_int 0)] 3))])
925    (parallel [(set (match_dup 6)
926                    (plus:SI (match_dup 6)
927                             (plus:SI (match_dup 7)
928                                      (match_dup 3))))
929               (set (match_dup 3)
930                    (unspec [(const_int 0)] 3))])]
931   "
933   operands[4] = operand_subword (operands[0], (WORDS_BIG_ENDIAN != 0), 0, DImode);
934   operands[5] = operand_subword (operands[2], (WORDS_BIG_ENDIAN != 0), 0, DImode);
935   operands[6] = operand_subword (operands[0], (WORDS_BIG_ENDIAN == 0), 0, DImode);
936   operands[7] = operand_subword (operands[2], (WORDS_BIG_ENDIAN == 0), 0, DImode);
939 (define_insn "*clear_c"
940   [(set (reg:SI 17)
941         (const_int 0))
942    (use (match_operand:SI 0 "register_operand" "r"))]
943   ""
944   "cmp %0,%0"
945   [(set_attr "type" "int2")
946    (set_attr "length" "2")])
948 (define_insn "*add_carry"
949   [(set (match_operand:SI 0 "register_operand" "=r")
950         (plus:SI (match_operand:SI 1 "register_operand" "%0")
951                  (plus:SI (match_operand:SI 2 "register_operand" "r")
952                           (reg:SI 17))))
953    (set (reg:SI 17)
954         (unspec [(const_int 0)] 3))]
955   ""
956   "addx %0,%2"
957   [(set_attr "type" "int2")
958    (set_attr "length" "2")])
960 (define_insn "subsi3"
961   [(set (match_operand:SI 0 "register_operand" "=r")
962         (minus:SI (match_operand:SI 1 "register_operand" "0")
963                   (match_operand:SI 2 "register_operand" "r")))]
964   ""
965   "sub %0,%2"
966   [(set_attr "type" "int2")
967    (set_attr "length" "2")])
969 (define_insn "subdi3"
970   [(set (match_operand:DI 0 "register_operand" "=r")
971         (minus:DI (match_operand:DI 1 "register_operand" "0")
972                   (match_operand:DI 2 "register_operand" "r")))
973    (clobber (reg:SI 17))]
974   ""
975   "#"
976   [(set_attr "type" "multi")
977    (set_attr "length" "6")])
979 ;; ??? The cmp clears the condition bit.  Can we speed up somehow?
980 (define_split
981   [(set (match_operand:DI 0 "register_operand" "")
982         (minus:DI (match_operand:DI 1 "register_operand" "")
983                   (match_operand:DI 2 "register_operand" "")))
984    (clobber (match_operand 3 "" ""))]
985   "reload_completed"
986   [(parallel [(set (match_dup 3)
987                    (const_int 0))
988               (use (match_dup 4))])
989    (parallel [(set (match_dup 4)
990                    (minus:SI (match_dup 4)
991                              (minus:SI (match_dup 5)
992                                        (match_dup 3))))
993               (set (match_dup 3)
994                    (unspec [(const_int 0)] 3))])
995    (parallel [(set (match_dup 6)
996                    (minus:SI (match_dup 6)
997                              (minus:SI (match_dup 7)
998                                        (match_dup 3))))
999               (set (match_dup 3)
1000                    (unspec [(const_int 0)] 3))])]
1001   "
1003   operands[4] = operand_subword (operands[0], (WORDS_BIG_ENDIAN != 0), 0, DImode);
1004   operands[5] = operand_subword (operands[2], (WORDS_BIG_ENDIAN != 0), 0, DImode);
1005   operands[6] = operand_subword (operands[0], (WORDS_BIG_ENDIAN == 0), 0, DImode);
1006   operands[7] = operand_subword (operands[2], (WORDS_BIG_ENDIAN == 0), 0, DImode);
1009 (define_insn "*sub_carry"
1010   [(set (match_operand:SI 0 "register_operand" "=r")
1011         (minus:SI (match_operand:SI 1 "register_operand" "%0")
1012                   (minus:SI (match_operand:SI 2 "register_operand" "r")
1013                             (reg:SI 17))))
1014    (set (reg:SI 17)
1015         (unspec [(const_int 0)] 3))]
1016   ""
1017   "subx %0,%2"
1018   [(set_attr "type" "int2")
1019    (set_attr "length" "2")])
1021 ; Multiply/Divide instructions.
1023 (define_insn "mulhisi3"
1024   [(set (match_operand:SI 0 "register_operand" "=r")
1025         (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" "r"))
1026                  (sign_extend:SI (match_operand:HI 2 "register_operand" "r"))))]
1027   ""
1028   "mullo %1,%2\;mvfacmi %0"
1029   [(set_attr "type" "multi")
1030    (set_attr "length" "4")])
1032 (define_insn "mulsi3"
1033   [(set (match_operand:SI 0 "register_operand" "=r")
1034         (mult:SI (match_operand:SI 1 "register_operand" "%0")
1035                  (match_operand:SI 2 "register_operand" "r")))]
1036   ""
1037   "mul %0,%2"
1038   [(set_attr "type" "mul2")
1039    (set_attr "length" "2")])
1041 (define_insn "divsi3"
1042   [(set (match_operand:SI 0 "register_operand" "=r")
1043         (div:SI (match_operand:SI 1 "register_operand" "0")
1044                 (match_operand:SI 2 "register_operand" "r")))]
1045   ""
1046   "div %0,%2"
1047   [(set_attr "type" "div4")
1048    (set_attr "length" "4")])
1050 (define_insn "udivsi3"
1051   [(set (match_operand:SI 0 "register_operand" "=r")
1052         (udiv:SI (match_operand:SI 1 "register_operand" "0")
1053                  (match_operand:SI 2 "register_operand" "r")))]
1054   ""
1055   "divu %0,%2"
1056   [(set_attr "type" "div4")
1057    (set_attr "length" "4")])
1059 (define_insn "modsi3"
1060   [(set (match_operand:SI 0 "register_operand" "=r")
1061         (mod:SI (match_operand:SI 1 "register_operand" "0")
1062                 (match_operand:SI 2 "register_operand" "r")))]
1063   ""
1064   "rem %0,%2"
1065   [(set_attr "type" "div4")
1066    (set_attr "length" "4")])
1068 (define_insn "umodsi3"
1069   [(set (match_operand:SI 0 "register_operand" "=r")
1070         (umod:SI (match_operand:SI 1 "register_operand" "0")
1071                  (match_operand:SI 2 "register_operand" "r")))]
1072   ""
1073   "remu %0,%2"
1074   [(set_attr "type" "div4")
1075    (set_attr "length" "4")])
1077 ;; Boolean instructions.
1079 ;; We don't define the DImode versions as expand_binop does a good enough job.
1080 ;; And if it doesn't it should be fixed.
1082 (define_insn "andsi3"
1083   [(set (match_operand:SI 0 "register_operand" "=r,r")
1084         (and:SI (match_operand:SI 1 "register_operand" "%0,r")
1085                 (match_operand:SI 2 "reg_or_uint16_operand" "r,K")))]
1086   ""
1087   "*
1089   /* If we are worried about space, see if we can break this up into two
1090      short instructions, which might eliminate a NOP being inserted.  */
1091   if (optimize_size
1092       && m32r_not_same_reg (operands[0], operands[1])
1093       && GET_CODE (operands[2]) == CONST_INT
1094       && INT8_P (INTVAL (operands[2])))
1095     return \"#\";
1097   else if (GET_CODE (operands[2]) == CONST_INT)
1098     return \"and3 %0,%1,%#%X2\";
1100   return \"and %0,%2\";
1102   [(set_attr "type" "int2,int4")
1103    (set_attr "length" "2,4")])
1105 (define_split
1106   [(set (match_operand:SI 0 "register_operand" "")
1107         (and:SI (match_operand:SI 1 "register_operand" "")
1108                 (match_operand:SI 2 "int8_operand" "")))]
1109   "optimize_size && m32r_not_same_reg (operands[0], operands[1])"
1110   [(set (match_dup 0) (match_dup 2))
1111    (set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))]
1112   "")
1114 (define_insn "iorsi3"
1115   [(set (match_operand:SI 0 "register_operand" "=r,r")
1116         (ior:SI (match_operand:SI 1 "register_operand" "%0,r")
1117                 (match_operand:SI 2 "reg_or_uint16_operand" "r,K")))]
1118   ""
1119   "*
1121   /* If we are worried about space, see if we can break this up into two
1122      short instructions, which might eliminate a NOP being inserted.  */
1123   if (optimize_size
1124       && m32r_not_same_reg (operands[0], operands[1])
1125       && GET_CODE (operands[2]) == CONST_INT
1126       && INT8_P (INTVAL (operands[2])))
1127     return \"#\";
1129   else if (GET_CODE (operands[2]) == CONST_INT)
1130     return \"or3 %0,%1,%#%X2\";
1132   return \"or %0,%2\";
1134   [(set_attr "type" "int2,int4")
1135    (set_attr "length" "2,4")])
1137 (define_split
1138   [(set (match_operand:SI 0 "register_operand" "")
1139         (ior:SI (match_operand:SI 1 "register_operand" "")
1140                 (match_operand:SI 2 "int8_operand" "")))]
1141   "optimize_size && m32r_not_same_reg (operands[0], operands[1])"
1142   [(set (match_dup 0) (match_dup 2))
1143    (set (match_dup 0) (ior:SI (match_dup 0) (match_dup 1)))]
1144   "")
1146 (define_insn "xorsi3"
1147   [(set (match_operand:SI 0 "register_operand" "=r,r")
1148         (xor:SI (match_operand:SI 1 "register_operand" "%0,r")
1149                 (match_operand:SI 2 "reg_or_uint16_operand" "r,K")))]
1150   ""
1151   "*
1153   /* If we are worried about space, see if we can break this up into two
1154      short instructions, which might eliminate a NOP being inserted.  */
1155   if (optimize_size
1156       && m32r_not_same_reg (operands[0], operands[1])
1157       && GET_CODE (operands[2]) == CONST_INT
1158       && INT8_P (INTVAL (operands[2])))
1159     return \"#\";
1161   else if (GET_CODE (operands[2]) == CONST_INT)
1162     return \"xor3 %0,%1,%#%X2\";
1164   return \"xor %0,%2\";
1166   [(set_attr "type" "int2,int4")
1167    (set_attr "length" "2,4")])
1169 (define_split
1170   [(set (match_operand:SI 0 "register_operand" "")
1171         (xor:SI (match_operand:SI 1 "register_operand" "")
1172                 (match_operand:SI 2 "int8_operand" "")))]
1173   "optimize_size && m32r_not_same_reg (operands[0], operands[1])"
1174   [(set (match_dup 0) (match_dup 2))
1175    (set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))]
1176   "")
1178 (define_insn "negsi2"
1179   [(set (match_operand:SI 0 "register_operand" "=r")
1180         (neg:SI (match_operand:SI 1 "register_operand" "r")))]
1181   ""
1182   "neg %0,%1"
1183   [(set_attr "type" "int2")
1184    (set_attr "length" "2")])
1186 (define_insn "one_cmplsi2"
1187   [(set (match_operand:SI 0 "register_operand" "=r")
1188         (not:SI (match_operand:SI 1 "register_operand" "r")))]
1189   ""
1190   "not %0,%1"
1191   [(set_attr "type" "int2")
1192    (set_attr "length" "2")])
1194 ;; Shift instructions.
1196 (define_insn "ashlsi3"
1197   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
1198         (ashift:SI (match_operand:SI 1 "register_operand" "0,0,r")
1199                    (match_operand:SI 2 "reg_or_uint16_operand" "r,O,K")))]
1200   ""
1201   "@
1202    sll %0,%2
1203    slli %0,%#%2
1204    sll3 %0,%1,%#%2"
1205   [(set_attr "type" "shift2,shift2,shift4")
1206    (set_attr "length" "2,2,4")])
1208 (define_insn "ashrsi3"
1209   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
1210         (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0,r")
1211                      (match_operand:SI 2 "reg_or_uint16_operand" "r,O,K")))]
1212   ""
1213   "@
1214    sra %0,%2
1215    srai %0,%#%2
1216    sra3 %0,%1,%#%2"
1217   [(set_attr "type" "shift2,shift2,shift4")
1218    (set_attr "length" "2,2,4")])
1220 (define_insn "lshrsi3"
1221   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
1222         (lshiftrt:SI (match_operand:SI 1 "register_operand" "0,0,r")
1223                      (match_operand:SI 2 "reg_or_uint16_operand" "r,O,K")))]
1224   ""
1225   "@
1226    srl %0,%2
1227    srli %0,%#%2
1228    srl3 %0,%1,%#%2"
1229   [(set_attr "type" "shift2,shift2,shift4")
1230    (set_attr "length" "2,2,4")])
1232 ;; Compare instructions.
1233 ;; This controls RTL generation and register allocation.
1235 ;; We generate RTL for comparisons and branches by having the cmpxx 
1236 ;; patterns store away the operands.  Then the bcc patterns
1237 ;; emit RTL for both the compare and the branch.
1239 ;; On the m32r it is more efficient to use the bxxz instructions and
1240 ;; thus merge the compare and branch into one instruction, so they are
1241 ;; preferred.
1243 (define_expand "cmpsi"
1244   [(set (reg:SI 17)
1245         (compare:CC (match_operand:SI 0 "register_operand" "")
1246                     (match_operand:SI 1 "reg_or_cmp_int16_operand" "")))]
1247   ""
1248   "
1250   m32r_compare_op0 = operands[0];
1251   m32r_compare_op1 = operands[1];
1252   DONE;
1255 (define_insn "cmp_eqsi_zero_insn"
1256   [(set (reg:SI 17)
1257         (eq:SI (match_operand:SI 0 "register_operand" "r,r")
1258                (match_operand:SI 1 "reg_or_zero_operand" "r,P")))]
1259   "TARGET_M32RX || TARGET_M32R2"
1260   "@
1261    cmpeq %0, %1
1262    cmpz  %0"
1263   [(set_attr "type" "int4")
1264    (set_attr "length" "4")])
1266 ;; The cmp_xxx_insn patterns set the condition bit to the result of the
1267 ;; comparison.  There isn't a "compare equal" instruction so cmp_eqsi_insn
1268 ;; is quite inefficient.  However, it is rarely used.
1270 (define_insn "cmp_eqsi_insn"
1271   [(set (reg:SI 17)
1272         (eq:SI (match_operand:SI 0 "register_operand" "r,r")
1273                (match_operand:SI 1 "reg_or_cmp_int16_operand" "r,P")))
1274    (clobber (match_scratch:SI 2 "=&r,&r"))]
1275   ""
1276   "*
1278   if (which_alternative == 0)
1279     {
1280          return \"mv %2,%0\;sub %2,%1\;cmpui %2,#1\";
1281     }
1282   else
1283     {
1284         if (INTVAL (operands [1]) == 0)
1285           return \"cmpui %0, #1\";
1286         else if (REGNO (operands [2]) == REGNO (operands [0]))
1287           return \"addi %0,%#%N1\;cmpui %2,#1\";
1288         else
1289           return \"add3 %2,%0,%#%N1\;cmpui %2,#1\";
1290     }
1292   [(set_attr "type" "multi,multi")
1293    (set_attr "length" "8,8")])
1295 (define_insn "cmp_ltsi_insn"
1296   [(set (reg:SI 17)
1297         (lt:SI (match_operand:SI 0 "register_operand" "r,r")
1298                (match_operand:SI 1 "reg_or_int16_operand" "r,J")))]
1299   ""
1300   "@
1301    cmp %0,%1
1302    cmpi %0,%#%1"
1303   [(set_attr "type" "int2,int4")
1304    (set_attr "length" "2,4")])
1306 (define_insn "cmp_ltusi_insn"
1307   [(set (reg:SI 17)
1308         (ltu:SI (match_operand:SI 0 "register_operand" "r,r")
1309                 (match_operand:SI 1 "reg_or_int16_operand" "r,J")))]
1310   ""
1311   "@
1312    cmpu %0,%1
1313    cmpui %0,%#%1"
1314   [(set_attr "type" "int2,int4")
1315    (set_attr "length" "2,4")])
1317 ;; These control RTL generation for conditional jump insns.
1319 (define_expand "beq"
1320   [(set (pc)
1321         (if_then_else (match_dup 1)
1322                       (label_ref (match_operand 0 "" ""))
1323                       (pc)))]
1324   ""
1325   "
1327   operands[1] = gen_compare (EQ, m32r_compare_op0, m32r_compare_op1, FALSE);
1330 (define_expand "bne"
1331   [(set (pc)
1332         (if_then_else (match_dup 1)
1333                       (label_ref (match_operand 0 "" ""))
1334                       (pc)))]
1335   ""
1336   "
1338   operands[1] = gen_compare (NE, m32r_compare_op0, m32r_compare_op1, FALSE);
1341 (define_expand "bgt"
1342   [(set (pc)
1343         (if_then_else (match_dup 1)
1344                       (label_ref (match_operand 0 "" ""))
1345                       (pc)))]
1346   ""
1347   "
1349   operands[1] = gen_compare (GT, m32r_compare_op0, m32r_compare_op1, FALSE);
1352 (define_expand "ble"
1353   [(set (pc)
1354         (if_then_else (match_dup 1)
1355                       (label_ref (match_operand 0 "" ""))
1356                       (pc)))]
1357   ""
1358   "
1360   operands[1] = gen_compare (LE, m32r_compare_op0, m32r_compare_op1, FALSE);
1363 (define_expand "bge"
1364   [(set (pc)
1365         (if_then_else (match_dup 1)
1366                       (label_ref (match_operand 0 "" ""))
1367                       (pc)))]
1368   ""
1369   "
1371   operands[1] = gen_compare (GE, m32r_compare_op0, m32r_compare_op1, FALSE);
1374 (define_expand "blt"
1375   [(set (pc)
1376         (if_then_else (match_dup 1)
1377                       (label_ref (match_operand 0 "" ""))
1378                       (pc)))]
1379   ""
1380   "
1382   operands[1] = gen_compare (LT, m32r_compare_op0, m32r_compare_op1, FALSE);
1385 (define_expand "bgtu"
1386   [(set (pc)
1387         (if_then_else (match_dup 1)
1388                       (label_ref (match_operand 0 "" ""))
1389                       (pc)))]
1390   ""
1391   "
1393   operands[1] = gen_compare (GTU, m32r_compare_op0, m32r_compare_op1, FALSE);
1396 (define_expand "bleu"
1397   [(set (pc)
1398         (if_then_else (match_dup 1)
1399                       (label_ref (match_operand 0 "" ""))
1400                       (pc)))]
1401   ""
1402   "
1404   operands[1] = gen_compare (LEU, m32r_compare_op0, m32r_compare_op1, FALSE);
1407 (define_expand "bgeu"
1408   [(set (pc)
1409         (if_then_else (match_dup 1)
1410                       (label_ref (match_operand 0 "" ""))
1411                       (pc)))]
1412   ""
1413   "
1415   operands[1] = gen_compare (GEU, m32r_compare_op0, m32r_compare_op1, FALSE);
1418 (define_expand "bltu"
1419   [(set (pc)
1420         (if_then_else (match_dup 1)
1421                       (label_ref (match_operand 0 "" ""))
1422                       (pc)))]
1423   ""
1424   "
1426   operands[1] = gen_compare (LTU, m32r_compare_op0, m32r_compare_op1, FALSE);
1429 ;; Now match both normal and inverted jump.
1431 (define_insn "*branch_insn"
1432   [(set (pc)
1433         (if_then_else (match_operator 1 "eqne_comparison_operator"
1434                                       [(reg 17) (const_int 0)])
1435                       (label_ref (match_operand 0 "" ""))
1436                       (pc)))]
1437   ""
1438   "*
1440   static char instruction[40];
1441   sprintf (instruction, \"%s%s %%l0\",
1442            (GET_CODE (operands[1]) == NE) ? \"bc\" : \"bnc\",
1443            (get_attr_length (insn) == 2) ? \".s\" : \"\");
1444   return instruction;
1446   [(set_attr "type" "branch")
1447    ; We use 400/800 instead of 512,1024 to account for inaccurate insn
1448    ; lengths and insn alignments that are complex to track.
1449    ; It's not important that we be hyper-precise here.  It may be more
1450    ; important blah blah blah when the chip supports parallel execution
1451    ; blah blah blah but until then blah blah blah this is simple and
1452    ; suffices.
1453    (set (attr "length") (if_then_else (ltu (plus (minus (match_dup 0) (pc))
1454                                                  (const_int 400))
1455                                            (const_int 800))
1456                                       (const_int 2)
1457                                       (const_int 4)))])
1459 (define_insn "*rev_branch_insn"
1460   [(set (pc)
1461         (if_then_else (match_operator 1 "eqne_comparison_operator"
1462                                       [(reg 17) (const_int 0)])
1463                       (pc)
1464                       (label_ref (match_operand 0 "" ""))))]
1465   ;"REVERSIBLE_CC_MODE (GET_MODE (XEXP (operands[1], 0)))"
1466   ""
1467   "*
1469   static char instruction[40];
1470   sprintf (instruction, \"%s%s %%l0\",
1471            (GET_CODE (operands[1]) == EQ) ? \"bc\" : \"bnc\",
1472            (get_attr_length (insn) == 2) ? \".s\" : \"\");
1473   return instruction;
1475   [(set_attr "type" "branch")
1476    ; We use 400/800 instead of 512,1024 to account for inaccurate insn
1477    ; lengths and insn alignments that are complex to track.
1478    ; It's not important that we be hyper-precise here.  It may be more
1479    ; important blah blah blah when the chip supports parallel execution
1480    ; blah blah blah but until then blah blah blah this is simple and
1481    ; suffices.
1482    (set (attr "length") (if_then_else (ltu (plus (minus (match_dup 0) (pc))
1483                                                  (const_int 400))
1484                                            (const_int 800))
1485                                       (const_int 2)
1486                                       (const_int 4)))])
1488 ; reg/reg compare and branch insns
1490 (define_insn "*reg_branch_insn"
1491   [(set (pc)
1492         (if_then_else (match_operator 1 "eqne_comparison_operator"
1493                                       [(match_operand:SI 2 "register_operand" "r")
1494                                        (match_operand:SI 3 "register_operand" "r")])
1495                       (label_ref (match_operand 0 "" ""))
1496                       (pc)))]
1497   ""
1498   "*
1500   /* Is branch target reachable with beq/bne?  */
1501   if (get_attr_length (insn) == 4)
1502     {
1503       if (GET_CODE (operands[1]) == EQ)
1504         return \"beq %2,%3,%l0\";
1505       else
1506         return \"bne %2,%3,%l0\";
1507     }
1508   else
1509     {
1510       if (GET_CODE (operands[1]) == EQ)
1511         return \"bne %2,%3,1f\;bra %l0\;1:\";
1512       else
1513         return \"beq %2,%3,1f\;bra %l0\;1:\";
1514     }
1516   [(set_attr "type" "branch")
1517   ; We use 25000/50000 instead of 32768/65536 to account for slot filling
1518   ; which is complex to track and inaccurate length specs.
1519    (set (attr "length") (if_then_else (ltu (plus (minus (match_dup 0) (pc))
1520                                                  (const_int 25000))
1521                                            (const_int 50000))
1522                                       (const_int 4)
1523                                       (const_int 8)))])
1525 (define_insn "*rev_reg_branch_insn"
1526   [(set (pc)
1527         (if_then_else (match_operator 1 "eqne_comparison_operator"
1528                                       [(match_operand:SI 2 "register_operand" "r")
1529                                        (match_operand:SI 3 "register_operand" "r")])
1530                       (pc)
1531                       (label_ref (match_operand 0 "" ""))))]
1532   ""
1533   "*
1535   /* Is branch target reachable with beq/bne?  */
1536   if (get_attr_length (insn) == 4)
1537     {
1538       if (GET_CODE (operands[1]) == NE)
1539         return \"beq %2,%3,%l0\";
1540       else
1541         return \"bne %2,%3,%l0\";
1542     }
1543   else
1544     {
1545       if (GET_CODE (operands[1]) == NE)
1546         return \"bne %2,%3,1f\;bra %l0\;1:\";
1547       else
1548         return \"beq %2,%3,1f\;bra %l0\;1:\";
1549     }
1551   [(set_attr "type" "branch")
1552   ; We use 25000/50000 instead of 32768/65536 to account for slot filling
1553   ; which is complex to track and inaccurate length specs.
1554    (set (attr "length") (if_then_else (ltu (plus (minus (match_dup 0) (pc))
1555                                                  (const_int 25000))
1556                                            (const_int 50000))
1557                                       (const_int 4)
1558                                       (const_int 8)))])
1560 ; reg/zero compare and branch insns
1562 (define_insn "*zero_branch_insn"
1563   [(set (pc)
1564         (if_then_else (match_operator 1 "signed_comparison_operator"
1565                                       [(match_operand:SI 2 "register_operand" "r")
1566                                        (const_int 0)])
1567                       (label_ref (match_operand 0 "" ""))
1568                       (pc)))]
1569   ""
1570   "*
1572   const char *br,*invbr;
1573   char asmtext[40];
1575   switch (GET_CODE (operands[1]))
1576     {
1577       case EQ : br = \"eq\"; invbr = \"ne\"; break;
1578       case NE : br = \"ne\"; invbr = \"eq\"; break;
1579       case LE : br = \"le\"; invbr = \"gt\"; break;
1580       case GT : br = \"gt\"; invbr = \"le\"; break;
1581       case LT : br = \"lt\"; invbr = \"ge\"; break;
1582       case GE : br = \"ge\"; invbr = \"lt\"; break;
1584       default: abort();
1585     }
1587   /* Is branch target reachable with bxxz?  */
1588   if (get_attr_length (insn) == 4)
1589     {
1590       sprintf (asmtext, \"b%sz %%2,%%l0\", br);
1591       output_asm_insn (asmtext, operands);
1592     }
1593   else
1594     {
1595       sprintf (asmtext, \"b%sz %%2,1f\;bra %%l0\;1:\", invbr);
1596       output_asm_insn (asmtext, operands);
1597     }
1598   return \"\";
1600   [(set_attr "type" "branch")
1601   ; We use 25000/50000 instead of 32768/65536 to account for slot filling
1602   ; which is complex to track and inaccurate length specs.
1603    (set (attr "length") (if_then_else (ltu (plus (minus (match_dup 0) (pc))
1604                                                  (const_int 25000))
1605                                            (const_int 50000))
1606                                       (const_int 4)
1607                                       (const_int 8)))])
1609 (define_insn "*rev_zero_branch_insn"
1610   [(set (pc)
1611         (if_then_else (match_operator 1 "eqne_comparison_operator"
1612                                       [(match_operand:SI 2 "register_operand" "r")
1613                                        (const_int 0)])
1614                       (pc)
1615                       (label_ref (match_operand 0 "" ""))))]
1616   ""
1617   "*
1619   const char *br,*invbr;
1620   char asmtext[40];
1622   switch (GET_CODE (operands[1]))
1623     {
1624       case EQ : br = \"eq\"; invbr = \"ne\"; break;
1625       case NE : br = \"ne\"; invbr = \"eq\"; break;
1626       case LE : br = \"le\"; invbr = \"gt\"; break;
1627       case GT : br = \"gt\"; invbr = \"le\"; break;
1628       case LT : br = \"lt\"; invbr = \"ge\"; break;
1629       case GE : br = \"ge\"; invbr = \"lt\"; break;
1631       default: abort();
1632     }
1634   /* Is branch target reachable with bxxz?  */
1635   if (get_attr_length (insn) == 4)
1636     {
1637       sprintf (asmtext, \"b%sz %%2,%%l0\", invbr);
1638       output_asm_insn (asmtext, operands);
1639     }
1640   else
1641     {
1642       sprintf (asmtext, \"b%sz %%2,1f\;bra %%l0\;1:\", br);
1643       output_asm_insn (asmtext, operands);
1644     }
1645   return \"\";
1647   [(set_attr "type" "branch")
1648   ; We use 25000/50000 instead of 32768/65536 to account for slot filling
1649   ; which is complex to track and inaccurate length specs.
1650    (set (attr "length") (if_then_else (ltu (plus (minus (match_dup 0) (pc))
1651                                                  (const_int 25000))
1652                                            (const_int 50000))
1653                                       (const_int 4)
1654                                       (const_int 8)))])
1656 ;; S<cc> operations to set a register to 1/0 based on a comparison
1658 (define_expand "seq"
1659   [(match_operand:SI 0 "register_operand" "")]
1660   ""
1661   "
1663   rtx op0 = operands[0];
1664   rtx op1 = m32r_compare_op0;
1665   rtx op2 = m32r_compare_op1;
1666   enum machine_mode mode = GET_MODE (op0);
1668   if (mode != SImode)
1669     FAIL;
1671   if (! register_operand (op1, mode))
1672     op1 = force_reg (mode, op1);
1674   if (TARGET_M32RX || TARGET_M32R2)
1675     {
1676       if (! reg_or_zero_operand (op2, mode))
1677         op2 = force_reg (mode, op2);
1679       emit_insn (gen_seq_insn_m32rx (op0, op1, op2));
1680       DONE;
1681     }
1682   if (GET_CODE (op2) == CONST_INT && INTVAL (op2) == 0)
1683     {
1684       emit_insn (gen_seq_zero_insn (op0, op1));
1685       DONE;
1686     }
1688   if (! reg_or_eq_int16_operand (op2, mode))
1689     op2 = force_reg (mode, op2);
1691   emit_insn (gen_seq_insn (op0, op1, op2));
1692   DONE;
1695 (define_insn "seq_insn_m32rx"
1696   [(set (match_operand:SI 0 "register_operand" "=r")
1697         (eq:SI (match_operand:SI 1 "register_operand" "%r")
1698                (match_operand:SI 2 "reg_or_zero_operand" "rP")))
1699    (clobber (reg:SI 17))]
1700   "TARGET_M32RX || TARGET_M32R2"
1701   "#"
1702   [(set_attr "type" "multi")
1703    (set_attr "length" "6")])
1705 (define_split
1706   [(set (match_operand:SI 0 "register_operand" "")
1707         (eq:SI (match_operand:SI 1 "register_operand" "")
1708                (match_operand:SI 2 "reg_or_zero_operand" "")))
1709    (clobber (reg:SI 17))]
1710   "TARGET_M32RX || TARGET_M32R2"
1711   [(set (reg:SI 17)
1712         (eq:SI (match_dup 1)
1713                (match_dup 2)))
1714    (set (match_dup 0)
1715         (reg:SI 17))]
1716   "")
1718 (define_insn "seq_zero_insn"
1719   [(set (match_operand:SI 0 "register_operand" "=r")
1720         (eq:SI (match_operand:SI 1 "register_operand" "r")
1721                (const_int 0)))
1722    (clobber (reg:SI 17))]
1723   "TARGET_M32R"
1724   "#"
1725   [(set_attr "type" "multi")
1726    (set_attr "length" "6")])
1728 (define_split
1729   [(set (match_operand:SI 0 "register_operand" "")
1730         (eq:SI (match_operand:SI 1 "register_operand" "")
1731                (const_int 0)))
1732    (clobber (reg:SI 17))]
1733   "TARGET_M32R"
1734   [(match_dup 3)]
1735   "
1737   rtx op0 = operands[0];
1738   rtx op1 = operands[1];
1740   start_sequence ();
1741   emit_insn (gen_cmp_ltusi_insn (op1, GEN_INT (1)));
1742   emit_insn (gen_movcc_insn (op0));
1743   operands[3] = get_insns ();
1744   end_sequence ();
1747 (define_insn "seq_insn"
1748   [(set (match_operand:SI 0 "register_operand" "=r,r,??r,r")
1749         (eq:SI (match_operand:SI 1 "register_operand" "r,r,r,r")
1750                (match_operand:SI 2 "reg_or_eq_int16_operand" "r,r,r,PK")))
1751    (clobber (reg:SI 17))
1752    (clobber (match_scratch:SI 3 "=1,2,&r,r"))]
1753   "TARGET_M32R"
1754   "#"
1755   [(set_attr "type" "multi")
1756    (set_attr "length" "8,8,10,10")])
1758 (define_split
1759   [(set (match_operand:SI 0 "register_operand" "")
1760         (eq:SI (match_operand:SI 1 "register_operand" "")
1761                (match_operand:SI 2 "reg_or_eq_int16_operand" "")))
1762    (clobber (reg:SI 17))
1763    (clobber (match_scratch:SI 3 ""))]
1764   "TARGET_M32R && reload_completed"
1765   [(match_dup 4)]
1766   "
1768   rtx op0 = operands[0];
1769   rtx op1 = operands[1];
1770   rtx op2 = operands[2];
1771   rtx op3 = operands[3];
1772   HOST_WIDE_INT value;
1774   if (GET_CODE (op2) == REG && GET_CODE (op3) == REG
1775       && REGNO (op2) == REGNO (op3))
1776     {
1777       op1 = operands[2];
1778       op2 = operands[1];
1779     }
1781   start_sequence ();
1782   if (GET_CODE (op1) == REG && GET_CODE (op3) == REG
1783       && REGNO (op1) != REGNO (op3))
1784     {
1785       emit_move_insn (op3, op1);
1786       op1 = op3;
1787     }
1789   if (GET_CODE (op2) == CONST_INT && (value = INTVAL (op2)) != 0
1790       && CMP_INT16_P (value))
1791     emit_insn (gen_addsi3 (op3, op1, GEN_INT (-value)));
1792   else
1793     emit_insn (gen_xorsi3 (op3, op1, op2));
1795   emit_insn (gen_cmp_ltusi_insn (op3, GEN_INT (1)));
1796   emit_insn (gen_movcc_insn (op0));
1797   operands[4] = get_insns ();
1798   end_sequence ();
1801 (define_expand "sne"
1802   [(match_operand:SI 0 "register_operand" "")]
1803   ""
1804   "
1806   rtx op0 = operands[0];
1807   rtx op1 = m32r_compare_op0;
1808   rtx op2 = m32r_compare_op1;
1809   enum machine_mode mode = GET_MODE (op0);
1811   if (mode != SImode)
1812     FAIL;
1814   if (GET_CODE (op2) != CONST_INT
1815       || (INTVAL (op2) != 0 && UINT16_P (INTVAL (op2))))
1816     {
1817       rtx reg;
1819       if (reload_completed || reload_in_progress)
1820         FAIL;
1822       reg = gen_reg_rtx (SImode);
1823       emit_insn (gen_xorsi3 (reg, op1, op2));
1824       op1 = reg;
1826       if (! register_operand (op1, mode))
1827         op1 = force_reg (mode, op1);
1829       emit_insn (gen_sne_zero_insn (op0, op1));
1830       DONE;
1831     }
1832   else
1833     FAIL;
1836 (define_insn "sne_zero_insn"
1837   [(set (match_operand:SI 0 "register_operand" "=r")
1838         (ne:SI (match_operand:SI 1 "register_operand" "r")
1839                (const_int 0)))
1840    (clobber (reg:SI 17))
1841    (clobber (match_scratch:SI 2 "=&r"))]
1842   ""
1843   "#"
1844   [(set_attr "type" "multi")
1845    (set_attr "length" "6")])
1847 (define_split
1848   [(set (match_operand:SI 0 "register_operand" "")
1849         (ne:SI (match_operand:SI 1 "register_operand" "")
1850                (const_int 0)))
1851    (clobber (reg:SI 17))
1852    (clobber (match_scratch:SI 2 ""))]
1853   "reload_completed"
1854   [(set (match_dup 2)
1855         (const_int 0))
1856    (set (reg:SI 17)
1857         (ltu:SI (match_dup 2)
1858                 (match_dup 1)))
1859    (set (match_dup 0)
1860         (reg:SI 17))]
1861   "")
1862         
1863 (define_expand "slt"
1864   [(match_operand:SI 0 "register_operand" "")]
1865   ""
1866   "
1868   rtx op0 = operands[0];
1869   rtx op1 = m32r_compare_op0;
1870   rtx op2 = m32r_compare_op1;
1871   enum machine_mode mode = GET_MODE (op0);
1873   if (mode != SImode)
1874     FAIL;
1876   if (! register_operand (op1, mode))
1877     op1 = force_reg (mode, op1);
1879   if (! reg_or_int16_operand (op2, mode))
1880     op2 = force_reg (mode, op2);
1882   emit_insn (gen_slt_insn (op0, op1, op2));
1883   DONE;
1886 (define_insn "slt_insn"
1887   [(set (match_operand:SI 0 "register_operand" "=r,r")
1888         (lt:SI (match_operand:SI 1 "register_operand" "r,r")
1889                (match_operand:SI 2 "reg_or_int16_operand" "r,J")))
1890    (clobber (reg:SI 17))]
1891   ""
1892   "#"
1893   [(set_attr "type" "multi")
1894    (set_attr "length" "4,6")])
1896 (define_split
1897   [(set (match_operand:SI 0 "register_operand" "")
1898         (lt:SI (match_operand:SI 1 "register_operand" "")
1899                (match_operand:SI 2 "reg_or_int16_operand" "")))
1900    (clobber (reg:SI 17))]
1901   ""
1902   [(set (reg:SI 17)
1903         (lt:SI (match_dup 1)
1904                (match_dup 2)))
1905    (set (match_dup 0)
1906         (reg:SI 17))]
1907   "")
1909 (define_expand "sle"
1910   [(match_operand:SI 0 "register_operand" "")]
1911   ""
1912   "
1914   rtx op0 = operands[0];
1915   rtx op1 = m32r_compare_op0;
1916   rtx op2 = m32r_compare_op1;
1917   enum machine_mode mode = GET_MODE (op0);
1919   if (mode != SImode)
1920     FAIL;
1922   if (! register_operand (op1, mode))
1923     op1 = force_reg (mode, op1);
1925   if (GET_CODE (op2) == CONST_INT)
1926     {
1927       HOST_WIDE_INT value = INTVAL (op2);
1928       if (value >= 2147483647)
1929         {
1930           emit_move_insn (op0, GEN_INT (1));
1931           DONE;
1932         }
1934       op2 = GEN_INT (value+1);
1935       if (value < -32768 || value >= 32767)
1936         op2 = force_reg (mode, op2);
1938       emit_insn (gen_slt_insn (op0, op1, op2));
1939       DONE;
1940     }
1942   if (! register_operand (op2, mode))
1943     op2 = force_reg (mode, op2);
1945   emit_insn (gen_sle_insn (op0, op1, op2));
1946   DONE;
1949 (define_insn "sle_insn"
1950   [(set (match_operand:SI 0 "register_operand" "=r")
1951         (le:SI (match_operand:SI 1 "register_operand" "r")
1952                (match_operand:SI 2 "register_operand" "r")))
1953    (clobber (reg:SI 17))]
1954   ""
1955   "#"
1956   [(set_attr "type" "multi")
1957    (set_attr "length" "8")])
1959 (define_split
1960   [(set (match_operand:SI 0 "register_operand" "")
1961         (le:SI (match_operand:SI 1 "register_operand" "")
1962                (match_operand:SI 2 "register_operand" "")))
1963    (clobber (reg:SI 17))]
1964   "!optimize_size"
1965   [(set (reg:SI 17)
1966         (lt:SI (match_dup 2)
1967                (match_dup 1)))
1968    (set (match_dup 0)
1969         (reg:SI 17))
1970    (set (match_dup 0)
1971         (xor:SI (match_dup 0)
1972                 (const_int 1)))]
1973   "")
1975 ;; If optimizing for space, use -(reg - 1) to invert the comparison rather than
1976 ;; xor reg,reg,1 which might eliminate a NOP being inserted.
1977 (define_split
1978   [(set (match_operand:SI 0 "register_operand" "")
1979         (le:SI (match_operand:SI 1 "register_operand" "")
1980                (match_operand:SI 2 "register_operand" "")))
1981    (clobber (reg:SI 17))]
1982   "optimize_size"
1983   [(set (reg:SI 17)
1984         (lt:SI (match_dup 2)
1985                (match_dup 1)))
1986    (set (match_dup 0)
1987         (reg:SI 17))
1988    (set (match_dup 0)
1989         (plus:SI (match_dup 0)
1990                  (const_int -1)))
1991    (set (match_dup 0)
1992         (neg:SI (match_dup 0)))]
1993   "")
1995 (define_expand "sgt"
1996   [(match_operand:SI 0 "register_operand" "")]
1997   ""
1998   "
2000   rtx op0 = operands[0];
2001   rtx op1 = m32r_compare_op0;
2002   rtx op2 = m32r_compare_op1;
2003   enum machine_mode mode = GET_MODE (op0);
2005   if (mode != SImode)
2006     FAIL;
2008   if (! register_operand (op1, mode))
2009     op1 = force_reg (mode, op1);
2011   if (! register_operand (op2, mode))
2012     op2 = force_reg (mode, op2);
2014   emit_insn (gen_slt_insn (op0, op2, op1));
2015   DONE;
2018 (define_expand "sge"
2019   [(match_operand:SI 0 "register_operand" "")]
2020   ""
2021   "
2023   rtx op0 = operands[0];
2024   rtx op1 = m32r_compare_op0;
2025   rtx op2 = m32r_compare_op1;
2026   enum machine_mode mode = GET_MODE (op0);
2028   if (mode != SImode)
2029     FAIL;
2031   if (! register_operand (op1, mode))
2032     op1 = force_reg (mode, op1);
2034   if (! reg_or_int16_operand (op2, mode))
2035     op2 = force_reg (mode, op2);
2037   emit_insn (gen_sge_insn (op0, op1, op2));
2038   DONE;
2041 (define_insn "sge_insn"
2042   [(set (match_operand:SI 0 "register_operand" "=r,r")
2043         (ge:SI (match_operand:SI 1 "register_operand" "r,r")
2044                (match_operand:SI 2 "reg_or_int16_operand" "r,J")))
2045    (clobber (reg:SI 17))]
2046   ""
2047   "#"
2048   [(set_attr "type" "multi")
2049    (set_attr "length" "8,10")])
2051 (define_split
2052   [(set (match_operand:SI 0 "register_operand" "")
2053         (ge:SI (match_operand:SI 1 "register_operand" "")
2054                (match_operand:SI 2 "reg_or_int16_operand" "")))
2055    (clobber (reg:SI 17))]
2056   "!optimize_size"
2057   [(set (reg:SI 17)
2058         (lt:SI (match_dup 1)
2059                (match_dup 2)))
2060    (set (match_dup 0)
2061         (reg:SI 17))
2062    (set (match_dup 0)
2063         (xor:SI (match_dup 0)
2064                 (const_int 1)))]
2065   "")
2067 ;; If optimizing for space, use -(reg - 1) to invert the comparison rather than
2068 ;; xor reg,reg,1 which might eliminate a NOP being inserted.
2069 (define_split
2070   [(set (match_operand:SI 0 "register_operand" "")
2071         (ge:SI (match_operand:SI 1 "register_operand" "")
2072                (match_operand:SI 2 "reg_or_int16_operand" "")))
2073    (clobber (reg:SI 17))]
2074   "optimize_size"
2075   [(set (reg:SI 17)
2076         (lt:SI (match_dup 1)
2077                (match_dup 2)))
2078    (set (match_dup 0)
2079         (reg:SI 17))
2080    (set (match_dup 0)
2081         (plus:SI (match_dup 0)
2082                  (const_int -1)))
2083    (set (match_dup 0)
2084         (neg:SI (match_dup 0)))]
2085   "")
2087 (define_expand "sltu"
2088   [(match_operand:SI 0 "register_operand" "")]
2089   ""
2090   "
2092   rtx op0 = operands[0];
2093   rtx op1 = m32r_compare_op0;
2094   rtx op2 = m32r_compare_op1;
2095   enum machine_mode mode = GET_MODE (op0);
2097   if (mode != SImode)
2098     FAIL;
2100   if (! register_operand (op1, mode))
2101     op1 = force_reg (mode, op1);
2103   if (! reg_or_int16_operand (op2, mode))
2104     op2 = force_reg (mode, op2);
2106   emit_insn (gen_sltu_insn (op0, op1, op2));
2107   DONE;
2110 (define_insn "sltu_insn"
2111   [(set (match_operand:SI 0 "register_operand" "=r,r")
2112         (ltu:SI (match_operand:SI 1 "register_operand" "r,r")
2113                 (match_operand:SI 2 "reg_or_int16_operand" "r,J")))
2114    (clobber (reg:SI 17))]
2115   ""
2116   "#"
2117   [(set_attr "type" "multi")
2118    (set_attr "length" "6,8")])
2120 (define_split
2121   [(set (match_operand:SI 0 "register_operand" "")
2122         (ltu:SI (match_operand:SI 1 "register_operand" "")
2123                 (match_operand:SI 2 "reg_or_int16_operand" "")))
2124    (clobber (reg:SI 17))]
2125   ""
2126   [(set (reg:SI 17)
2127         (ltu:SI (match_dup 1)
2128                 (match_dup 2)))
2129    (set (match_dup 0)
2130         (reg:SI 17))]
2131   "")
2133 (define_expand "sleu"
2134   [(match_operand:SI 0 "register_operand" "")]
2135   ""
2136   "
2138   rtx op0 = operands[0];
2139   rtx op1 = m32r_compare_op0;
2140   rtx op2 = m32r_compare_op1;
2141   enum machine_mode mode = GET_MODE (op0);
2143   if (mode != SImode)
2144     FAIL;
2146   if (GET_CODE (op2) == CONST_INT)
2147     {
2148       HOST_WIDE_INT value = INTVAL (op2);
2149       if (value >= 2147483647)
2150         {
2151           emit_move_insn (op0, GEN_INT (1));
2152           DONE;
2153         }
2155       op2 = GEN_INT (value+1);
2156       if (value < 0 || value >= 32767)
2157         op2 = force_reg (mode, op2);
2159       emit_insn (gen_sltu_insn (op0, op1, op2));
2160       DONE;
2161     }
2163   if (! register_operand (op2, mode))
2164     op2 = force_reg (mode, op2);
2166   emit_insn (gen_sleu_insn (op0, op1, op2));
2167   DONE;
2170 (define_insn "sleu_insn"
2171   [(set (match_operand:SI 0 "register_operand" "=r")
2172         (leu:SI (match_operand:SI 1 "register_operand" "r")
2173                 (match_operand:SI 2 "register_operand" "r")))
2174    (clobber (reg:SI 17))]
2175   ""
2176   "#"
2177   [(set_attr "type" "multi")
2178    (set_attr "length" "8")])
2180 (define_split
2181   [(set (match_operand:SI 0 "register_operand" "")
2182         (leu:SI (match_operand:SI 1 "register_operand" "")
2183                 (match_operand:SI 2 "register_operand" "")))
2184    (clobber (reg:SI 17))]
2185   "!optimize_size"
2186   [(set (reg:SI 17)
2187         (ltu:SI (match_dup 2)
2188                 (match_dup 1)))
2189    (set (match_dup 0)
2190         (reg:SI 17))
2191    (set (match_dup 0)
2192         (xor:SI (match_dup 0)
2193                 (const_int 1)))]
2194   "")
2196 ;; If optimizing for space, use -(reg - 1) to invert the comparison rather than
2197 ;; xor reg,reg,1 which might eliminate a NOP being inserted.
2198 (define_split
2199   [(set (match_operand:SI 0 "register_operand" "")
2200         (leu:SI (match_operand:SI 1 "register_operand" "")
2201                 (match_operand:SI 2 "register_operand" "")))
2202    (clobber (reg:SI 17))]
2203   "optimize_size"
2204   [(set (reg:SI 17)
2205         (ltu:SI (match_dup 2)
2206                 (match_dup 1)))
2207    (set (match_dup 0)
2208         (reg:SI 17))
2209    (set (match_dup 0)
2210         (plus:SI (match_dup 0)
2211                  (const_int -1)))
2212    (set (match_dup 0)
2213         (neg:SI (match_dup 0)))]
2214   "")
2216 (define_expand "sgtu"
2217   [(match_operand:SI 0 "register_operand" "")]
2218   ""
2219   "
2221   rtx op0 = operands[0];
2222   rtx op1 = m32r_compare_op0;
2223   rtx op2 = m32r_compare_op1;
2224   enum machine_mode mode = GET_MODE (op0);
2226   if (mode != SImode)
2227     FAIL;
2229   if (! register_operand (op1, mode))
2230     op1 = force_reg (mode, op1);
2232   if (! register_operand (op2, mode))
2233     op2 = force_reg (mode, op2);
2235   emit_insn (gen_sltu_insn (op0, op2, op1));
2236   DONE;
2239 (define_expand "sgeu"
2240   [(match_operand:SI 0 "register_operand" "")]
2241   ""
2242   "
2244   rtx op0 = operands[0];
2245   rtx op1 = m32r_compare_op0;
2246   rtx op2 = m32r_compare_op1;
2247   enum machine_mode mode = GET_MODE (op0);
2249   if (mode != SImode)
2250     FAIL;
2252   if (! register_operand (op1, mode))
2253     op1 = force_reg (mode, op1);
2255   if (! reg_or_int16_operand (op2, mode))
2256     op2 = force_reg (mode, op2);
2258   emit_insn (gen_sgeu_insn (op0, op1, op2));
2259   DONE;
2262 (define_insn "sgeu_insn"
2263   [(set (match_operand:SI 0 "register_operand" "=r,r")
2264         (geu:SI (match_operand:SI 1 "register_operand" "r,r")
2265                 (match_operand:SI 2 "reg_or_int16_operand" "r,J")))
2266    (clobber (reg:SI 17))]
2267   ""
2268   "#"
2269   [(set_attr "type" "multi")
2270    (set_attr "length" "8,10")])
2272 (define_split
2273   [(set (match_operand:SI 0 "register_operand" "")
2274         (geu:SI (match_operand:SI 1 "register_operand" "")
2275                 (match_operand:SI 2 "reg_or_int16_operand" "")))
2276    (clobber (reg:SI 17))]
2277   "!optimize_size"
2278   [(set (reg:SI 17)
2279         (ltu:SI (match_dup 1)
2280                 (match_dup 2)))
2281    (set (match_dup 0)
2282         (reg:SI 17))
2283    (set (match_dup 0)
2284         (xor:SI (match_dup 0)
2285                 (const_int 1)))]
2286   "")
2288 ;; If optimizing for space, use -(reg - 1) to invert the comparison rather than
2289 ;; xor reg,reg,1 which might eliminate a NOP being inserted.
2290 (define_split
2291   [(set (match_operand:SI 0 "register_operand" "")
2292         (geu:SI (match_operand:SI 1 "register_operand" "")
2293                 (match_operand:SI 2 "reg_or_int16_operand" "")))
2294    (clobber (reg:SI 17))]
2295   "optimize_size"
2296   [(set (reg:SI 17)
2297         (ltu:SI (match_dup 1)
2298                 (match_dup 2)))
2299    (set (match_dup 0)
2300         (reg:SI 17))
2301    (set (match_dup 0)
2302         (plus:SI (match_dup 0)
2303                  (const_int -1)))
2304    (set (match_dup 0)
2305         (neg:SI (match_dup 0)))]
2306   "")
2308 (define_insn "movcc_insn"
2309   [(set (match_operand:SI 0 "register_operand" "=r")
2310         (reg:SI 17))]
2311   ""
2312   "mvfc %0, cbr"
2313   [(set_attr "type" "misc")
2314    (set_attr "length" "2")])
2317 ;; Unconditional and other jump instructions.
2319 (define_insn "jump"
2320   [(set (pc) (label_ref (match_operand 0 "" "")))]
2321   ""
2322   "bra %l0"
2323   [(set_attr "type" "uncond_branch")
2324    (set (attr "length") (if_then_else (ltu (plus (minus (match_dup 0) (pc))
2325                                                  (const_int 400))
2326                                            (const_int 800))
2327                                       (const_int 2)
2328                                       (const_int 4)))])
2330 (define_insn "indirect_jump"
2331   [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
2332   ""
2333   "jmp %a0"
2334   [(set_attr "type" "uncond_branch")
2335    (set_attr "length" "2")])
2337 (define_insn "return"
2338   [(return)]
2339   "direct_return ()"
2340   "jmp lr"
2341   [(set_attr "type" "uncond_branch")
2342    (set_attr "length" "2")])
2344 (define_expand "tablejump"
2345   [(parallel [(set (pc) (match_operand 0 "register_operand" "r"))
2346               (use (label_ref (match_operand 1 "" "")))])]
2347   ""
2348   "
2350   /* In pic mode, our address differences are against the base of the
2351      table.  Add that base value back in; CSE ought to be able to combine
2352      the two address loads.  */
2353   if (flag_pic)
2354     {
2355       rtx tmp, tmp2;
2357       tmp = gen_rtx_LABEL_REF (Pmode, operands[1]);
2358       tmp2 = operands[0];
2359       tmp = gen_rtx_PLUS (Pmode, tmp2, tmp);
2360       operands[0] = memory_address (Pmode, tmp);
2361     }
2364 (define_insn "*tablejump_insn"
2365   [(set (pc) (match_operand:SI 0 "address_operand" "p"))
2366    (use (label_ref (match_operand 1 "" "")))]
2367   ""
2368   "jmp %a0"
2369   [(set_attr "type" "uncond_branch")
2370    (set_attr "length" "2")])
2372 (define_expand "call"
2373   ;; operands[1] is stack_size_rtx
2374   ;; operands[2] is next_arg_register
2375   [(parallel [(call (match_operand:SI 0 "call_operand" "")
2376                     (match_operand 1 "" ""))
2377              (clobber (reg:SI 14))])]
2378   ""
2379   "
2381   if (flag_pic)
2382     current_function_uses_pic_offset_table = 1;
2385 (define_insn "*call_via_reg"
2386   [(call (mem:SI (match_operand:SI 0 "register_operand" "r"))
2387          (match_operand 1 "" ""))
2388    (clobber (reg:SI 14))]
2389   ""
2390   "jl %0"
2391   [(set_attr "type" "call")
2392    (set_attr "length" "2")])
2394 (define_insn "*call_via_label"
2395   [(call (mem:SI (match_operand:SI 0 "call_address_operand" ""))
2396          (match_operand 1 "" ""))
2397    (clobber (reg:SI 14))]
2398   ""
2399   "*
2401   int call26_p = call26_operand (operands[0], FUNCTION_MODE);
2403   if (! call26_p)
2404     {
2405       /* We may not be able to reach with a `bl' insn so punt and leave it to
2406          the linker.
2407          We do this here, rather than doing a force_reg in the define_expand
2408          so these insns won't be separated, say by scheduling, thus simplifying
2409          the linker.  */
2410       return \"seth r14,%T0\;add3 r14,r14,%B0\;jl r14\";
2411     }
2412   else
2413     return \"bl %0\";
2415   [(set_attr "type" "call")
2416    (set (attr "length")
2417         (if_then_else (eq (symbol_ref "call26_operand (operands[0], FUNCTION_MODE)")
2418                           (const_int 0))
2419                       (const_int 12) ; 10 + 2 for nop filler
2420                       ; The return address must be on a 4 byte boundary so
2421                       ; there's no point in using a value of 2 here.  A 2 byte
2422                       ; insn may go in the left slot but we currently can't
2423                       ; use such knowledge.
2424                       (const_int 4)))])
2426 (define_expand "call_value"
2427   ;; operand 2 is stack_size_rtx
2428   ;; operand 3 is next_arg_register
2429   [(parallel [(set (match_operand 0 "register_operand" "=r")
2430                    (call (match_operand:SI 1 "call_operand" "")
2431                          (match_operand 2 "" "")))
2432              (clobber (reg:SI 14))])]
2433   ""
2434   "                                                                             
2436   if (flag_pic)
2437     current_function_uses_pic_offset_table = 1;
2440 (define_insn "*call_value_via_reg"
2441   [(set (match_operand 0 "register_operand" "=r")
2442         (call (mem:SI (match_operand:SI 1 "register_operand" "r"))
2443               (match_operand 2 "" "")))
2444    (clobber (reg:SI 14))]
2445   ""
2446   "jl %1"
2447   [(set_attr "type" "call")
2448    (set_attr "length" "2")])
2450 (define_insn "*call_value_via_label"
2451   [(set (match_operand 0 "register_operand" "=r")
2452         (call (mem:SI (match_operand:SI 1 "call_address_operand" ""))
2453               (match_operand 2 "" "")))
2454    (clobber (reg:SI 14))]
2455   ""
2456   "*
2458   int call26_p = call26_operand (operands[1], FUNCTION_MODE);
2460   if (flag_pic)
2461     current_function_uses_pic_offset_table = 1;
2463   if (! call26_p)
2464     {
2465       /* We may not be able to reach with a `bl' insn so punt and leave it to
2466          the linker.
2467          We do this here, rather than doing a force_reg in the define_expand
2468          so these insns won't be separated, say by scheduling, thus simplifying
2469          the linker.  */
2470       return \"seth r14,%T1\;add3 r14,r14,%B1\;jl r14\";
2471     }
2472   else
2473     return \"bl %1\";
2475   [(set_attr "type" "call")
2476    (set (attr "length")
2477         (if_then_else (eq (symbol_ref "call26_operand (operands[1], FUNCTION_MODE)")
2478                           (const_int 0))
2479                       (const_int 12) ; 10 + 2 for nop filler
2480                       ; The return address must be on a 4 byte boundary so
2481                       ; there's no point in using a value of 2 here.  A 2 byte
2482                       ; insn may go in the left slot but we currently can't
2483                       ; use such knowledge.
2484                       (const_int 4)))])
2486 (define_insn "nop"
2487   [(const_int 0)]
2488   ""
2489   "nop"
2490   [(set_attr "type" "int2")
2491    (set_attr "length" "2")])
2493 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
2494 ;; all of memory.  This blocks insns from being moved across this point.
2496 (define_insn "blockage"
2497   [(unspec_volatile [(const_int 0)] 0)]
2498   ""
2499   "")
2501 ;; Special pattern to flush the icache.
2503 (define_insn "flush_icache"
2504   [(unspec_volatile [(match_operand 0 "memory_operand" "m")] 0)
2505    (match_operand 1 "" "")
2506    (clobber (reg:SI 17))]
2507   ""
2508   "* return \"trap %#%1 ; flush-icache\";"
2509   [(set_attr "type" "int4")
2510    (set_attr "length" "4")])
2512 ;; Speed up fabs and provide correct sign handling for -0
2514 (define_insn "absdf2"
2515   [(set (match_operand:DF 0 "register_operand" "=r")
2516         (abs:DF (match_operand:DF 1 "register_operand" "0")))]
2517   ""
2518   "#"
2519   [(set_attr "type" "multi")
2520    (set_attr "length" "4")])
2522 (define_split
2523   [(set (match_operand:DF 0 "register_operand" "")
2524         (abs:DF (match_operand:DF 1 "register_operand" "")))]
2525   "reload_completed"
2526   [(set (match_dup 2)
2527         (ashift:SI (match_dup 2)
2528                    (const_int 1)))
2529    (set (match_dup 2)
2530         (lshiftrt:SI (match_dup 2)
2531                      (const_int 1)))]
2532   "operands[2] = gen_highpart (SImode, operands[0]);")
2534 (define_insn "abssf2"
2535   [(set (match_operand:SF 0 "register_operand" "=r")
2536         (abs:SF (match_operand:SF 1 "register_operand" "0")))]
2537   ""
2538   "#"
2539   [(set_attr "type" "multi")
2540    (set_attr "length" "4")])
2542 (define_split
2543   [(set (match_operand:SF 0 "register_operand" "")
2544         (abs:SF (match_operand:SF 1 "register_operand" "")))]
2545   "reload_completed"
2546   [(set (match_dup 2)
2547         (ashift:SI (match_dup 2)
2548                    (const_int 1)))
2549    (set (match_dup 2)
2550         (lshiftrt:SI (match_dup 2)
2551                      (const_int 1)))]
2552   "operands[2] = gen_highpart (SImode, operands[0]);")
2554 ;; Conditional move instructions
2555 ;; Based on those done for the d10v
2557 (define_expand "movsicc"
2558   [
2559    (set (match_operand:SI 0 "register_operand" "r")
2560         (if_then_else:SI (match_operand 1 "" "")
2561                          (match_operand:SI 2 "conditional_move_operand" "O")
2562                          (match_operand:SI 3 "conditional_move_operand" "O")
2563         )
2564    )
2565   ]
2566   ""
2567   "
2569   if (! zero_and_one (operands [2], operands [3]))
2570     FAIL;
2572   /* Generate the comparison that will set the carry flag.  */
2573   operands[1] = gen_compare (GET_CODE (operands[1]), m32r_compare_op0,
2574                              m32r_compare_op1, TRUE);
2576   /* See other movsicc pattern below for reason why.  */
2577   emit_insn (gen_blockage ());
2580 ;; Generate the conditional instructions based on how the carry flag is examined.
2581 (define_insn "*movsicc_internal"
2582   [(set (match_operand:SI 0 "register_operand" "=r")
2583         (if_then_else:SI (match_operand 1 "carry_compare_operand" "")
2584                          (match_operand:SI 2 "conditional_move_operand" "O")
2585                          (match_operand:SI 3 "conditional_move_operand" "O")
2586         )
2587    )]
2588   "zero_and_one (operands [2], operands[3])"
2589   "* return emit_cond_move (operands, insn);"
2590   [(set_attr "type" "multi")
2591    (set_attr "length" "8")
2592   ]
2596 ;; Split up troublesome insns for better scheduling.
2597 ;; FIXME: Peepholes go at the end.
2599 ;; ??? Setting the type attribute may not be useful, but for completeness
2600 ;; we do it.
2602 (define_peephole
2603   [(set (mem:SI (plus:SI (match_operand:SI 0 "register_operand" "r")
2604                          (const_int 4)))
2605         (match_operand:SI 1 "register_operand" "r"))]
2606   "0 && dead_or_set_p (insn, operands[0])"
2607   "st %1,@+%0"
2608   [(set_attr "type" "store2")
2609    (set_attr "length" "2")])
2611 ;; This case is triggered by compiling this code:
2612 ;; 
2613 ;; extern void sub(int *);
2614 ;; void main (void)
2615 ;; {
2616 ;;   int i=2,j=3,k;
2617 ;;   while (i < j)  sub(&k);
2618 ;;   i = j / k;
2619 ;;   sub(&i);
2620 ;;   i = j - k;
2621 ;;   sub(&i);
2622 ;; }
2624 ;; Without the peephole the following assembler is generated for the
2625 ;; divide and subtract expressions:
2627 ;;         div r5,r4     
2628 ;;         mv r4,r5      
2629 ;;         st r4,@(4,sp) 
2630 ;;         bl sub
2631 ;; 
2632 ;; Similar code is produced for the subtract expression.  With this
2633 ;; peephole the redundant move is eliminated.
2635 ;; This optimization only works if PRESERVE_DEATH_INFO_REGNO_P is
2636 ;; defined in m32r.h
2638 (define_peephole
2639   [(set (match_operand:SI 0 "register_operand" "r")
2640         (match_operand:SI 1 "register_operand" "r")
2641    )
2642    (set (mem:SI (plus: SI (match_operand:SI 2 "register_operand" "r")
2643                 (match_operand:SI 3 "immediate_operand" "J")))
2644         (match_dup 0)
2645    )
2646   ]
2647   "0 && dead_or_set_p (insn, operands [0])"
2648   "st %1,@(%3,%2)"
2649   [(set_attr "type" "store4")
2650    (set_attr "length" "4")
2651   ]
2654 ;; Block moves, see m32r.c for more details.
2655 ;; Argument 0 is the destination
2656 ;; Argument 1 is the source
2657 ;; Argument 2 is the length
2658 ;; Argument 3 is the alignment
2660 (define_expand "movstrsi"
2661   [(parallel [(set (match_operand:BLK 0 "general_operand" "")
2662                    (match_operand:BLK 1 "general_operand" ""))
2663               (use (match_operand:SI  2 "immediate_operand" ""))
2664               (use (match_operand:SI  3 "immediate_operand" ""))])]
2665   ""
2666   "
2668   if (operands[0])              /* avoid unused code messages */
2669     {
2670       m32r_expand_block_move (operands);
2671       DONE;
2672     }
2675 ;; Insn generated by block moves
2677 (define_insn "movstrsi_internal"
2678   [(set (mem:BLK (match_operand:SI 0 "register_operand" "+r"))  ;; destination
2679         (mem:BLK (match_operand:SI 1 "register_operand" "+r"))) ;; source
2680    (use (match_operand:SI 2 "m32r_block_immediate_operand" "J"));; # bytes to move
2681    (set (match_dup 0) (plus:SI (match_dup 0) (minus:SI (match_dup 2) (const_int 4))))
2682    (set (match_dup 1) (plus:SI (match_dup 1) (match_dup 2)))
2683    (clobber (match_scratch:SI 3 "=&r"))                         ;; temp 1
2684    (clobber (match_scratch:SI 4 "=&r"))]                        ;; temp 2
2685   ""
2686   "* m32r_output_block_move (insn, operands); return \"\"; "
2687   [(set_attr "type"     "store8")
2688    (set_attr "length"   "72")]) ;; Maximum
2690 ;; PIC
2692 /* When generating pic, we need to load the symbol offset into a register.
2693    So that the optimizer does not confuse this with a normal symbol load
2694    we use an unspec.  The offset will be loaded from a constant pool entry,
2695    since that is the only type of relocation we can use.  */
2697 (define_insn "pic_load_addr"
2698   [(set (match_operand:SI 0 "register_operand" "=r")
2699         (unspec:SI [(match_operand 1 "" "")] 4))]
2700   "flag_pic"
2701   "ld24 %0,%#%1"
2702   [(set_attr "type" "int4")])
2704 ;; Load program counter insns.
2706 (define_insn "get_pc"
2707   [(clobber (reg:SI 14))
2708    (set (match_operand 0 "register_operand" "=r")
2709         (unspec [(match_operand 1 "" "")] 5))
2710    (use (match_operand:SI 2 "immediate_operand" ""))]
2711   "flag_pic"
2712   "*
2714   if (INTVAL(operands[2]))
2715     return \"bl.s .+4\;ld24 %0,%#%1\;add %0,lr\";
2716   else
2717     return \"bl.s .+4\;seth %0,%#shigh(%1)\;add3 %0,%0,%#low(%1+4)\;add %0,lr\";}"
2718   [(set (attr "length") (if_then_else (ne (match_dup 2) (const_int 0))
2719                                       (const_int 8)
2720                                       (const_int 12)))])
2722 (define_expand "builtin_setjmp_receiver"
2723   [(label_ref (match_operand 0 "" ""))]
2724   "flag_pic"
2725   "
2727   m32r_load_pic_register ();
2728   DONE;