Merge from mainline (gomp-merge-2005-02-26).
[official-gcc.git] / gcc / config / m32r / m32r.md
blob37f94e41599b8f561c7be9ab1a2759671b323505
1 ;; Machine description of the Renesas M32R cpu for GNU C compiler
2 ;; Copyright (C) 1996, 1997, 1998, 1999, 2001, 2003, 2004
3 ;  Free Software Foundation, Inc.
5 ;; This file is part of GCC.
7 ;; GCC is free software; you can redistribute it and/or modify it
8 ;; under the terms of the GNU General Public License as published
9 ;; by the Free Software Foundation; either version 2, or (at your
10 ;; option) any later version.
12 ;; GCC is distributed in the hope that it will be useful, but WITHOUT
13 ;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 ;; or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
15 ;; License for more details.
17 ;; You should have received a copy of the GNU General Public License
18 ;; along with GCC; see the file COPYING.  If not, write to
19 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
20 ;; Boston, MA 02111-1307, USA.
22 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
24 ;; UNSPEC_VOLATILE usage
25 (define_constants
26   [(UNSPECV_BLOCKAGE            0)
27    (UNSPECV_FLUSH_ICACHE        1)])
29 ;; UNSPEC usage
30 (define_constants
31   [(UNSPEC_LOAD_SDA_BASE        2)
32    (UNSPEC_SET_CBIT             3)
33    (UNSPEC_PIC_LOAD_ADDR        4)
34    (UNSPEC_GET_PC               5)
35    (UNSPEC_GOTOFF               6)
36    ])
38 ;; Insn type.  Used to default other attribute values.
39 (define_attr "type"
40   "int2,int4,load2,load4,load8,store2,store4,store8,shift2,shift4,mul2,div4,uncond_branch,branch,call,multi,misc"
41   (const_string "misc"))
43 ;; Length in bytes.
44 (define_attr "length" ""
45   (cond [(eq_attr "type" "int2,load2,store2,shift2,mul2")
46          (const_int 2)
48          (eq_attr "type" "int4,load4,store4,shift4,div4")
49          (const_int 4)
51          (eq_attr "type" "multi")
52          (const_int 8)
54          (eq_attr "type" "uncond_branch,branch,call")
55          (const_int 4)]
57          (const_int 4)))
59 ;; The length here is the length of a single asm.  Unfortunately it might be
60 ;; 2 or 4 so we must allow for 4.  That's ok though.
61 (define_asm_attributes
62   [(set_attr "length" "4")
63    (set_attr "type" "multi")])
65 ;; Whether an instruction is short (16-bit) or long (32-bit).
66 (define_attr "insn_size" "short,long"
67   (if_then_else (eq_attr "type" "int2,load2,store2,shift2,mul2")
68                 (const_string "short")
69                 (const_string "long")))
71 ;; The target CPU we're compiling for.
72 (define_attr "cpu" "m32r,m32r2,m32rx"
73   (cond [(ne (symbol_ref "TARGET_M32RX") (const_int 0))
74              (const_string "m32rx")
75          (ne (symbol_ref "TARGET_M32R2") (const_int 0))
76              (const_string "m32r2")]
77     (const_string "m32r")))
79 ;; Defines the pipeline where an instruction can be executed on.
80 ;; For the M32R, a short instruction can execute one of the two pipes.
81 ;; For the M32Rx, the restrictions are modelled in the second
82 ;;  condition of this attribute definition.
83 (define_attr "m32r_pipeline" "either,s,o,long"
84   (cond [(and (eq_attr "cpu" "m32r")
85               (eq_attr "insn_size" "short"))
86              (const_string "either")
87          (eq_attr "insn_size" "!short")
88              (const_string "long")]
89          (cond [(eq_attr "type" "int2")
90                    (const_string "either")
91                 (eq_attr "type" "load2,store2,shift2,uncond_branch,branch,call")
92                    (const_string "o")
93                 (eq_attr "type" "mul2")
94                    (const_string "s")]
95          (const_string "long"))))
97 ;; ::::::::::::::::::::
98 ;; ::
99 ;; :: Pipeline description
100 ;; ::
101 ;; ::::::::::::::::::::
103 ;; This model is based on Chapter 2, Appendix 3 and Appendix 4 of the
104 ;; "M32R-FPU Software Manual", Revision 1.01, plus additional information
105 ;; obtained by our best friend and mine, Google.
107 ;; The pipeline is modelled as a fetch unit, and a core with a memory unit,
108 ;; two execution units, where "fetch" models IF and D, "memory" for MEM1
109 ;; and MEM2, and "EXEC" for E, E1, E2, EM, and EA.  Writeback and
110 ;; bypasses are not modelled.
111 (define_automaton "m32r")
113 ;; We pretend there are two short (16 bits) instruction fetchers.  The
114 ;; "s" short fetcher cannot be reserved until the "o" short fetcher is
115 ;; reserved.  Some instructions reserve both the left and right fetchers.
116 ;; These fetch units are a hack to get GCC to better pack the instructions
117 ;; for the M32Rx processor, which has two execution pipes.
119 ;; In reality there is only one decoder, which can decode either two 16 bits
120 ;; instructions, or a single 32 bits instruction.
122 ;; Note, "fetch" models both the IF and the D pipeline stages.
124 ;; The m32rx core has two execution pipes.  We name them o_E and s_E.
125 ;; In addition, there's a memory unit.
127 (define_cpu_unit "o_IF,s_IF,o_E,s_E,memory" "m32r")
129 ;; Prevent the s pipe from being reserved before the o pipe.
130 (absence_set "s_IF" "o_IF")
131 (absence_set "s_E"  "o_E")
133 ;; On the M32Rx, long instructions execute on both pipes, so reserve
134 ;; both fetch slots and both pipes.
135 (define_reservation "long_IF" "o_IF+s_IF")
136 (define_reservation "long_E" "o_E+s_E")
138 ;; ::::::::::::::::::::
140 ;; Simple instructions do 4 stages: IF D E WB.  WB is not modelled.
141 ;; Hence, ready latency is 1.
142 (define_insn_reservation "short_left" 1
143   (and (eq_attr "m32r_pipeline" "o")
144        (and (eq_attr "insn_size" "short")
145             (eq_attr "type" "!load2")))
146   "o_IF,o_E")
148 (define_insn_reservation "short_right" 1
149   (and (eq_attr "m32r_pipeline" "s")
150        (and (eq_attr "insn_size" "short")
151             (eq_attr "type" "!load2")))
152   "s_IF,s_E")
154 (define_insn_reservation "short_either" 1
155   (and (eq_attr "m32r_pipeline" "either")
156        (and (eq_attr "insn_size" "short")
157             (eq_attr "type" "!load2")))
158   "o_IF|s_IF,o_E|s_E")
160 (define_insn_reservation "long_m32r" 1
161   (and (eq_attr "cpu" "m32r")
162        (and (eq_attr "insn_size" "long")
163             (eq_attr "type" "!load4,load8")))
164   "long_IF,long_E")
166 (define_insn_reservation "long_m32rx" 2
167   (and (eq_attr "m32r_pipeline" "long")
168        (and (eq_attr "insn_size" "long")
169             (eq_attr "type" "!load4,load8")))
170   "long_IF,long_E")
172 ;; Load/store instructions do 6 stages: IF D E MEM1 MEM2 WB.
173 ;; MEM1 may require more than one cycle depending on locality.  We
174 ;; optimistically assume all memory is nearby, i.e. MEM1 takes only
175 ;; one cycle.  Hence, ready latency is 3.
177 ;; The M32Rx can do short load/store only on the left pipe.
178 (define_insn_reservation "short_load_left" 3
179   (and (eq_attr "m32r_pipeline" "o")
180        (and (eq_attr "insn_size" "short")
181             (eq_attr "type" "load2")))
182   "o_IF,o_E,memory*2")
184 (define_insn_reservation "short_load" 3
185   (and (eq_attr "m32r_pipeline" "either")
186        (and (eq_attr "insn_size" "short")
187             (eq_attr "type" "load2")))
188   "s_IF|o_IF,s_E|o_E,memory*2")
190 (define_insn_reservation "long_load" 3
191   (and (eq_attr "cpu" "m32r")
192        (and (eq_attr "insn_size" "long")
193             (eq_attr "type" "load4,load8")))
194   "long_IF,long_E,memory*2")
196 (define_insn_reservation "long_load_m32rx" 3
197   (and (eq_attr "m32r_pipeline" "long")
198        (eq_attr "type" "load4,load8"))
199   "long_IF,long_E,memory*2")
202 ;; Expand prologue as RTL
203 (define_expand "prologue"
204   [(const_int 1)]
205   ""
206   "
208   m32r_expand_prologue ();
209   DONE;
213 ;; Move instructions.
215 ;; For QI and HI moves, the register must contain the full properly
216 ;; sign-extended value.  nonzero_bits assumes this [otherwise
217 ;; SHORT_IMMEDIATES_SIGN_EXTEND must be used, but the comment for it
218 ;; says it's a kludge and the .md files should be fixed instead].
220 (define_expand "movqi"
221   [(set (match_operand:QI 0 "general_operand" "")
222         (match_operand:QI 1 "general_operand" ""))]
223   ""
224   "
226   /* Fixup PIC cases.  */
227   if (flag_pic)
228     {
229       if (symbolic_operand (operands[1], QImode))
230         {
231           if (reload_in_progress || reload_completed)
232             operands[1] = m32r_legitimize_pic_address (operands[1], operands[0]);
233           else
234             operands[1] = m32r_legitimize_pic_address (operands[1], NULL_RTX);
235         }
236     }
238   /* Everything except mem = const or mem = mem can be done easily.
239      Objects in the small data area are handled too.  */
241   if (GET_CODE (operands[0]) == MEM)
242     operands[1] = force_reg (QImode, operands[1]);
245 (define_insn "*movqi_insn"
246   [(set (match_operand:QI 0 "move_dest_operand" "=r,r,r,r,r,T,m")
247         (match_operand:QI 1 "move_src_operand" "r,I,JQR,T,m,r,r"))]
248   "register_operand (operands[0], QImode) || register_operand (operands[1], QImode)"
249   "@
250    mv %0,%1
251    ldi %0,%#%1
252    ldi %0,%#%1
253    ldub %0,%1
254    ldub %0,%1
255    stb %1,%0
256    stb %1,%0"
257   [(set_attr "type" "int2,int2,int4,load2,load4,store2,store4")
258    (set_attr "length" "2,2,4,2,4,2,4")])
260 (define_expand "movhi"
261   [(set (match_operand:HI 0 "general_operand" "")
262         (match_operand:HI 1 "general_operand" ""))]
263   ""
264   "
266   /* Fixup PIC cases.  */
267   if (flag_pic)
268     {
269       if (symbolic_operand (operands[1], HImode))
270         {
271           if (reload_in_progress || reload_completed)
272             operands[1] = m32r_legitimize_pic_address (operands[1], operands[0]);
273           else
274             operands[1] = m32r_legitimize_pic_address (operands[1], NULL_RTX);
275         }
276     }
278   /* Everything except mem = const or mem = mem can be done easily.  */
280   if (GET_CODE (operands[0]) == MEM)
281     operands[1] = force_reg (HImode, operands[1]);
284 (define_insn "*movhi_insn"
285   [(set (match_operand:HI 0 "move_dest_operand" "=r,r,r,r,r,r,T,m")
286         (match_operand:HI 1 "move_src_operand" "r,I,JQR,K,T,m,r,r"))]
287   "register_operand (operands[0], HImode) || register_operand (operands[1], HImode)"
288   "@
289    mv %0,%1
290    ldi %0,%#%1
291    ldi %0,%#%1
292    ld24 %0,%#%1
293    lduh %0,%1
294    lduh %0,%1
295    sth %1,%0
296    sth %1,%0"
297   [(set_attr "type" "int2,int2,int4,int4,load2,load4,store2,store4")
298    (set_attr "length" "2,2,4,4,2,4,2,4")])
300 (define_expand "movsi_push"
301   [(set (mem:SI (pre_dec:SI (match_operand:SI 0 "register_operand" "")))
302         (match_operand:SI 1 "register_operand" ""))]
303   ""
304   "")
306 (define_expand "movsi_pop"
307   [(set (match_operand:SI 0 "register_operand" "")
308         (mem:SI (post_inc:SI (match_operand:SI 1 "register_operand" ""))))]
309   ""
310   "")
312 (define_expand "movsi"
313   [(set (match_operand:SI 0 "general_operand" "")
314         (match_operand:SI 1 "general_operand" ""))]
315   ""
316   "
318   /* Fixup PIC cases.  */
319   if (flag_pic)
320     {
321       if (symbolic_operand (operands[1], SImode))
322         {
323           if (reload_in_progress || reload_completed)
324             operands[1] = m32r_legitimize_pic_address (operands[1], operands[0]);
325           else
326             operands[1] = m32r_legitimize_pic_address (operands[1], NULL_RTX);
327         }
328     }
330   /* Everything except mem = const or mem = mem can be done easily.  */
332   if (GET_CODE (operands[0]) == MEM)
333     operands[1] = force_reg (SImode, operands[1]);
335   /* Small Data Area reference?  */
336   if (small_data_operand (operands[1], SImode))
337     {
338       emit_insn (gen_movsi_sda (operands[0], operands[1]));
339       DONE;
340     }
342   /* If medium or large code model, symbols have to be loaded with
343      seth/add3.  */
344   if (addr32_operand (operands[1], SImode))
345     {
346       emit_insn (gen_movsi_addr32 (operands[0], operands[1]));
347       DONE;
348     }
351 ;; ??? Do we need a const_double constraint here for large unsigned values?
352 (define_insn "*movsi_insn"
353   [(set (match_operand:SI 0 "move_dest_operand" "=r,r,r,r,r,r,r,r,r,T,S,m")
354         (match_operand:SI 1 "move_src_operand" "r,I,J,MQ,L,n,T,U,m,r,r,r"))]
355   "register_operand (operands[0], SImode) || register_operand (operands[1], SImode)"
356   "*
358   if (GET_CODE (operands[0]) == REG || GET_CODE (operands[1]) == SUBREG)
359     {
360       switch (GET_CODE (operands[1]))
361         {
362           HOST_WIDE_INT value;
364           default:
365             break;
367           case REG:
368           case SUBREG:
369             return \"mv %0,%1\";
371           case MEM:
372             if (GET_CODE (XEXP (operands[1], 0)) == POST_INC
373                 && XEXP (XEXP (operands[1], 0), 0) == stack_pointer_rtx)
374               return \"pop %0\";
376             return \"ld %0,%1\";
378           case CONST_INT:
379             value = INTVAL (operands[1]);
380             if (INT16_P (value))
381               return \"ldi %0,%#%1\\t; %X1\";
383             if (UINT24_P (value))
384               return \"ld24 %0,%#%1\\t; %X1\";
386             if (UPPER16_P (value))
387               return \"seth %0,%#%T1\\t; %X1\";
389             return \"#\";
391           case CONST:
392           case SYMBOL_REF:
393           case LABEL_REF:
394             if (TARGET_ADDR24)
395               return \"ld24 %0,%#%1\";
397             return \"#\";
398         }
399     }
401   else if (GET_CODE (operands[0]) == MEM
402            && (GET_CODE (operands[1]) == REG || GET_CODE (operands[1]) == SUBREG))
403     {
404       if (GET_CODE (XEXP (operands[0], 0)) == PRE_DEC
405           && XEXP (XEXP (operands[0], 0), 0) == stack_pointer_rtx)
406         return \"push %1\";
408       return \"st %1,%0\";
409     }
411   abort ();
413   [(set_attr "type" "int2,int2,int4,int4,int4,multi,load2,load2,load4,store2,store2,store4")
414    (set_attr "length" "2,2,4,4,4,8,2,2,4,2,2,4")])
416 ; Try to use a four byte / two byte pair for constants not loadable with
417 ; ldi, ld24, seth.
419 (define_split
420  [(set (match_operand:SI 0 "register_operand" "")
421        (match_operand:SI 1 "two_insn_const_operand" ""))]
422   ""
423   [(set (match_dup 0) (match_dup 2))
424    (set (match_dup 0) (ior:SI (match_dup 0) (match_dup 3)))]
425   "
427   unsigned HOST_WIDE_INT val = INTVAL (operands[1]);
428   unsigned HOST_WIDE_INT tmp;
429   int shift;
431   /* In all cases we will emit two instructions.  However we try to
432      use 2 byte instructions wherever possible.  We can assume the
433      constant isn't loadable with any of ldi, ld24, or seth.  */
435   /* See if we can load a 24 bit unsigned value and invert it.  */
436   if (UINT24_P (~ val))
437     {
438       emit_insn (gen_movsi (operands[0], GEN_INT (~ val)));
439       emit_insn (gen_one_cmplsi2 (operands[0], operands[0]));
440       DONE;
441     }
443   /* See if we can load a 24 bit unsigned value and shift it into place.
444      0x01fffffe is just beyond ld24's range.  */
445   for (shift = 1, tmp = 0x01fffffe;
446        shift < 8;
447        ++shift, tmp <<= 1)
448     {
449       if ((val & ~tmp) == 0)
450         {
451           emit_insn (gen_movsi (operands[0], GEN_INT (val >> shift)));
452           emit_insn (gen_ashlsi3 (operands[0], operands[0], GEN_INT (shift)));
453           DONE;
454         }
455     }
457   /* Can't use any two byte insn, fall back to seth/or3.  Use ~0xffff instead
458      of 0xffff0000, since the later fails on a 64-bit host.  */
459   operands[2] = GEN_INT ((val) & ~0xffff);
460   operands[3] = GEN_INT ((val) & 0xffff);
463 (define_split
464   [(set (match_operand:SI 0 "register_operand" "")
465         (match_operand:SI 1 "seth_add3_operand" ""))]
466   "TARGET_ADDR32"
467   [(set (match_dup 0)
468         (high:SI (match_dup 1)))
469    (set (match_dup 0)
470         (lo_sum:SI (match_dup 0)
471                    (match_dup 1)))]
472   "")
474 ;; Small data area support.
475 ;; The address of _SDA_BASE_ is loaded into a register and all objects in
476 ;; the small data area are indexed off that.  This is done for each reference
477 ;; but cse will clean things up for us.  We let the compiler choose the
478 ;; register to use so we needn't allocate (and maybe even fix) a special
479 ;; register to use.  Since the load and store insns have a 16 bit offset the
480 ;; total size of the data area can be 64K.  However, if the data area lives
481 ;; above 16M (24 bits), _SDA_BASE_ will have to be loaded with seth/add3 which
482 ;; would then yield 3 instructions to reference an object [though there would
483 ;; be no net loss if two or more objects were referenced].  The 3 insns can be
484 ;; reduced back to 2 if the size of the small data area were reduced to 32K
485 ;; [then seth + ld/st would work for any object in the area].  Doing this
486 ;; would require special handling of _SDA_BASE_ (its value would be
487 ;; (.sdata + 32K) & 0xffff0000) and reloc computations would be different
488 ;; [I think].  What to do about this is deferred until later and for now we
489 ;; require .sdata to be in the first 16M.
491 (define_expand "movsi_sda"
492   [(set (match_dup 2)
493         (unspec:SI [(const_int 0)] UNSPEC_LOAD_SDA_BASE))
494    (set (match_operand:SI 0 "register_operand" "")
495         (lo_sum:SI (match_dup 2)
496                    (match_operand:SI 1 "small_data_operand" "")))]
497   ""
498   "
500   if (reload_in_progress || reload_completed)
501     operands[2] = operands[0];
502   else
503     operands[2] = gen_reg_rtx (SImode);
506 (define_insn "*load_sda_base"
507   [(set (match_operand:SI 0 "register_operand" "=r")
508         (unspec:SI [(const_int 0)] UNSPEC_LOAD_SDA_BASE))]
509   ""
510   "ld24 %0,#_SDA_BASE_"
511   [(set_attr "type" "int4")
512    (set_attr "length" "4")])
514 ;; 32 bit address support.
516 (define_expand "movsi_addr32"
517   [(set (match_dup 2)
518         ; addr32_operand isn't used because it's too restrictive,
519         ; seth_add3_operand is more general and thus safer.
520         (high:SI (match_operand:SI 1 "seth_add3_operand" "")))
521    (set (match_operand:SI 0 "register_operand" "")
522         (lo_sum:SI (match_dup 2) (match_dup 1)))]
523   ""
524   "
526   if (reload_in_progress || reload_completed)
527     operands[2] = operands[0];
528   else
529     operands[2] = gen_reg_rtx (SImode);
532 (define_insn "set_hi_si"
533   [(set (match_operand:SI 0 "register_operand" "=r")
534         (high:SI (match_operand 1 "symbolic_operand" "")))]
535   ""
536   "seth %0,%#shigh(%1)"
537   [(set_attr "type" "int4")
538    (set_attr "length" "4")])
540 (define_insn "lo_sum_si"
541   [(set (match_operand:SI 0 "register_operand" "=r")
542         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
543                    (match_operand:SI 2 "immediate_operand" "in")))]
544   ""
545   "add3 %0,%1,%#%B2"
546   [(set_attr "type" "int4")
547    (set_attr "length" "4")])
549 (define_expand "movdi"
550   [(set (match_operand:DI 0 "general_operand" "")
551         (match_operand:DI 1 "general_operand" ""))]
552   ""
553   "
555   /* Fixup PIC cases.  */
556   if (flag_pic)
557     {
558       if (symbolic_operand (operands[1], DImode))
559         {
560           if (reload_in_progress || reload_completed)
561             operands[1] = m32r_legitimize_pic_address (operands[1], operands[0]);
562           else
563             operands[1] = m32r_legitimize_pic_address (operands[1], NULL_RTX);
564         }
565     }
567   /* Everything except mem = const or mem = mem can be done easily.  */
569   if (GET_CODE (operands[0]) == MEM)
570     operands[1] = force_reg (DImode, operands[1]);
573 (define_insn "*movdi_insn"
574   [(set (match_operand:DI 0 "move_dest_operand" "=r,r,r,r,m")
575         (match_operand:DI 1 "move_double_src_operand" "r,nG,F,m,r"))]
576   "register_operand (operands[0], DImode) || register_operand (operands[1], DImode)"
577   "#"
578   [(set_attr "type" "multi,multi,multi,load8,store8")
579    (set_attr "length" "4,4,16,6,6")])
581 (define_split
582   [(set (match_operand:DI 0 "move_dest_operand" "")
583         (match_operand:DI 1 "move_double_src_operand" ""))]
584   "reload_completed"
585   [(match_dup 2)]
586   "operands[2] = gen_split_move_double (operands);")
588 ;; Floating point move insns.
590 (define_expand "movsf"
591   [(set (match_operand:SF 0 "general_operand" "")
592         (match_operand:SF 1 "general_operand" ""))]
593   ""
594   "
596   /* Fixup PIC cases.  */
597   if (flag_pic)
598     {
599       if (symbolic_operand (operands[1], SFmode))
600         {
601           if (reload_in_progress || reload_completed)
602             operands[1] = m32r_legitimize_pic_address (operands[1], operands[0]);
603           else
604             operands[1] = m32r_legitimize_pic_address (operands[1], NULL_RTX);
605         }
606     }
608   /* Everything except mem = const or mem = mem can be done easily.  */
610   if (GET_CODE (operands[0]) == MEM)
611     operands[1] = force_reg (SFmode, operands[1]);
614 (define_insn "*movsf_insn"
615   [(set (match_operand:SF 0 "move_dest_operand" "=r,r,r,r,r,T,S,m")
616         (match_operand:SF 1 "move_src_operand" "r,F,U,S,m,r,r,r"))]
617   "register_operand (operands[0], SFmode) || register_operand (operands[1], SFmode)"
618   "@
619    mv %0,%1
620    #
621    ld %0,%1
622    ld %0,%1
623    ld %0,%1
624    st %1,%0
625    st %1,%0
626    st %1,%0"
627   ;; ??? Length of alternative 1 is either 2, 4 or 8.
628   [(set_attr "type" "int2,multi,load2,load2,load4,store2,store2,store4")
629    (set_attr "length" "2,8,2,2,4,2,2,4")])
631 (define_split
632   [(set (match_operand:SF 0 "register_operand" "")
633         (match_operand:SF 1 "const_double_operand" ""))]
634   "reload_completed"
635   [(set (match_dup 2) (match_dup 3))]
636   "
638   operands[2] = operand_subword (operands[0], 0, 0, SFmode);
639   operands[3] = operand_subword (operands[1], 0, 0, SFmode);
642 (define_expand "movdf"
643   [(set (match_operand:DF 0 "general_operand" "")
644         (match_operand:DF 1 "general_operand" ""))]
645   ""
646   "
648   /* Fixup PIC cases.  */
649   if (flag_pic)
650     {
651       if (symbolic_operand (operands[1], DFmode))
652         {
653           if (reload_in_progress || reload_completed)
654             operands[1] = m32r_legitimize_pic_address (operands[1], operands[0]);
655           else
656             operands[1] = m32r_legitimize_pic_address (operands[1], NULL_RTX);
657         }
658     }
660   /* Everything except mem = const or mem = mem can be done easily.  */
662   if (GET_CODE (operands[0]) == MEM)
663     operands[1] = force_reg (DFmode, operands[1]);
666 (define_insn "*movdf_insn"
667   [(set (match_operand:DF 0 "move_dest_operand" "=r,r,r,m")
668         (match_operand:DF 1 "move_double_src_operand" "r,F,m,r"))]
669   "register_operand (operands[0], DFmode) || register_operand (operands[1], DFmode)"
670   "#"
671   [(set_attr "type" "multi,multi,load8,store8")
672    (set_attr "length" "4,16,6,6")])
674 (define_split
675   [(set (match_operand:DF 0 "move_dest_operand" "")
676         (match_operand:DF 1 "move_double_src_operand" ""))]
677   "reload_completed"
678   [(match_dup 2)]
679   "operands[2] = gen_split_move_double (operands);")
681 ;; Zero extension instructions.
683 (define_insn "zero_extendqihi2"
684   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
685         (zero_extend:HI (match_operand:QI 1 "extend_operand" "r,T,m")))]
686   ""
687   "@
688    and3 %0,%1,%#255
689    ldub %0,%1
690    ldub %0,%1"
691   [(set_attr "type" "int4,load2,load4")
692    (set_attr "length" "4,2,4")])
694 (define_insn "zero_extendqisi2"
695   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
696         (zero_extend:SI (match_operand:QI 1 "extend_operand" "r,T,m")))]
697   ""
698   "@
699    and3 %0,%1,%#255
700    ldub %0,%1
701    ldub %0,%1"
702   [(set_attr "type" "int4,load2,load4")
703    (set_attr "length" "4,2,4")])
705 (define_insn "zero_extendhisi2"
706   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
707         (zero_extend:SI (match_operand:HI 1 "extend_operand" "r,T,m")))]
708   ""
709   "@
710    and3 %0,%1,%#65535
711    lduh %0,%1
712    lduh %0,%1"
713   [(set_attr "type" "int4,load2,load4")
714    (set_attr "length" "4,2,4")])
716 ;; Signed conversions from a smaller integer to a larger integer
717 (define_insn "extendqihi2"
718   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
719         (sign_extend:HI (match_operand:QI 1 "extend_operand" "0,T,m")))]
720   ""
721   "@
722     #
723     ldb %0,%1
724     ldb %0,%1"
725   [(set_attr "type" "multi,load2,load4")
726    (set_attr "length" "2,2,4")])
728 (define_split
729   [(set (match_operand:HI 0 "register_operand" "")
730         (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
731   "reload_completed"
732   [(match_dup 2)
733    (match_dup 3)]
734   "
736   rtx op0   = gen_lowpart (SImode, operands[0]);
737   rtx shift = GEN_INT (24);
739   operands[2] = gen_ashlsi3 (op0, op0, shift);
740   operands[3] = gen_ashrsi3 (op0, op0, shift);
743 (define_insn "extendqisi2"
744   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
745         (sign_extend:SI (match_operand:QI 1 "extend_operand" "0,T,m")))]
746   ""
747   "@
748     #
749     ldb %0,%1
750     ldb %0,%1"
751   [(set_attr "type" "multi,load2,load4")
752    (set_attr "length" "4,2,4")])
754 (define_split
755   [(set (match_operand:SI 0 "register_operand" "")
756         (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
757   "reload_completed"
758   [(match_dup 2)
759    (match_dup 3)]
760   "
762   rtx shift = GEN_INT (24);
764   operands[2] = gen_ashlsi3 (operands[0], operands[0], shift);
765   operands[3] = gen_ashrsi3 (operands[0], operands[0], shift);
768 (define_insn "extendhisi2"
769   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
770         (sign_extend:SI (match_operand:HI 1 "extend_operand" "0,T,m")))]
771   ""
772   "@
773     #
774     ldh %0,%1
775     ldh %0,%1"
776   [(set_attr "type" "multi,load2,load4")
777    (set_attr "length" "4,2,4")])
779 (define_split
780   [(set (match_operand:SI 0 "register_operand" "")
781         (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
782   "reload_completed"
783   [(match_dup 2)
784    (match_dup 3)]
785   "
787   rtx shift = GEN_INT (16);
789   operands[2] = gen_ashlsi3 (operands[0], operands[0], shift);
790   operands[3] = gen_ashrsi3 (operands[0], operands[0], shift);
793 ;; Arithmetic instructions.
795 ; ??? Adding an alternative to split add3 of small constants into two
796 ; insns yields better instruction packing but slower code.  Adds of small
797 ; values is done a lot.
799 (define_insn "addsi3"
800   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
801         (plus:SI (match_operand:SI 1 "register_operand" "%0,0,r")
802                  (match_operand:SI 2 "nonmemory_operand" "r,I,J")))]
803   ""
804   "@
805    add %0,%2
806    addi %0,%#%2
807    add3 %0,%1,%#%2"
808   [(set_attr "type" "int2,int2,int4")
809    (set_attr "length" "2,2,4")])
811 ;(define_split
812 ;  [(set (match_operand:SI 0 "register_operand" "")
813 ;       (plus:SI (match_operand:SI 1 "register_operand" "")
814 ;                (match_operand:SI 2 "int8_operand" "")))]
815 ;  "reload_completed
816 ;   && REGNO (operands[0]) != REGNO (operands[1])
817 ;   && INT8_P (INTVAL (operands[2]))
818 ;   && INTVAL (operands[2]) != 0"
819 ;  [(set (match_dup 0) (match_dup 1))
820 ;   (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))]
821 ;  "")
823 (define_insn "adddi3"
824   [(set (match_operand:DI 0 "register_operand" "=r")
825         (plus:DI (match_operand:DI 1 "register_operand" "%0")
826                  (match_operand:DI 2 "register_operand" "r")))
827    (clobber (reg:CC 17))]
828   ""
829   "#"
830   [(set_attr "type" "multi")
831    (set_attr "length" "6")])
833 ;; ??? The cmp clears the condition bit.  Can we speed up somehow?
834 (define_split
835   [(set (match_operand:DI 0 "register_operand" "")
836         (plus:DI (match_operand:DI 1 "register_operand" "")
837                  (match_operand:DI 2 "register_operand" "")))
838    (clobber (reg:CC 17))]
839   "reload_completed"
840   [(parallel [(set (reg:CC 17)
841                    (const_int 0))
842               (use (match_dup 4))])
843    (parallel [(set (match_dup 4)
844                    (plus:SI (match_dup 4)
845                             (plus:SI (match_dup 5)
846                                      (ne:SI (reg:CC 17) (const_int 0)))))
847               (set (reg:CC 17)
848                    (unspec:CC [(const_int 0)] UNSPEC_SET_CBIT))])
849    (parallel [(set (match_dup 6)
850                    (plus:SI (match_dup 6)
851                             (plus:SI (match_dup 7)
852                                      (ne:SI (reg:CC 17) (const_int 0)))))
853               (set (reg:CC 17)
854                    (unspec:CC [(const_int 0)] UNSPEC_SET_CBIT))])]
855   "
857   operands[4] = operand_subword (operands[0], (WORDS_BIG_ENDIAN != 0), 0, DImode);
858   operands[5] = operand_subword (operands[2], (WORDS_BIG_ENDIAN != 0), 0, DImode);
859   operands[6] = operand_subword (operands[0], (WORDS_BIG_ENDIAN == 0), 0, DImode);
860   operands[7] = operand_subword (operands[2], (WORDS_BIG_ENDIAN == 0), 0, DImode);
863 (define_insn "*clear_c"
864   [(set (reg:CC 17)
865         (const_int 0))
866    (use (match_operand:SI 0 "register_operand" "r"))]
867   ""
868   "cmp %0,%0"
869   [(set_attr "type" "int2")
870    (set_attr "length" "2")])
872 (define_insn "*add_carry"
873   [(set (match_operand:SI 0 "register_operand" "=r")
874         (plus:SI (match_operand:SI 1 "register_operand" "%0")
875                  (plus:SI (match_operand:SI 2 "register_operand" "r")
876                           (ne:SI (reg:CC 17) (const_int 0)))))
877    (set (reg:CC 17)
878         (unspec:CC [(const_int 0)] UNSPEC_SET_CBIT))]
879   ""
880   "addx %0,%2"
881   [(set_attr "type" "int2")
882    (set_attr "length" "2")])
884 (define_insn "subsi3"
885   [(set (match_operand:SI 0 "register_operand" "=r")
886         (minus:SI (match_operand:SI 1 "register_operand" "0")
887                   (match_operand:SI 2 "register_operand" "r")))]
888   ""
889   "sub %0,%2"
890   [(set_attr "type" "int2")
891    (set_attr "length" "2")])
893 (define_insn "subdi3"
894   [(set (match_operand:DI 0 "register_operand" "=r")
895         (minus:DI (match_operand:DI 1 "register_operand" "0")
896                   (match_operand:DI 2 "register_operand" "r")))
897    (clobber (reg:CC 17))]
898   ""
899   "#"
900   [(set_attr "type" "multi")
901    (set_attr "length" "6")])
903 ;; ??? The cmp clears the condition bit.  Can we speed up somehow?
904 (define_split
905   [(set (match_operand:DI 0 "register_operand" "")
906         (minus:DI (match_operand:DI 1 "register_operand" "")
907                   (match_operand:DI 2 "register_operand" "")))
908    (clobber (reg:CC 17))]
909   "reload_completed"
910   [(parallel [(set (reg:CC 17)
911                    (const_int 0))
912               (use (match_dup 4))])
913    (parallel [(set (match_dup 4)
914                    (minus:SI (match_dup 4)
915                              (minus:SI (match_dup 5)
916                                        (ne:SI (reg:CC 17) (const_int 0)))))
917               (set (reg:CC 17)
918                    (unspec:CC [(const_int 0)] UNSPEC_SET_CBIT))])
919    (parallel [(set (match_dup 6)
920                    (minus:SI (match_dup 6)
921                              (minus:SI (match_dup 7)
922                                        (ne:SI (reg:CC 17) (const_int 0)))))
923               (set (reg:CC 17)
924                    (unspec:CC [(const_int 0)] UNSPEC_SET_CBIT))])]
925   "
927   operands[4] = operand_subword (operands[0], (WORDS_BIG_ENDIAN != 0), 0, DImode);
928   operands[5] = operand_subword (operands[2], (WORDS_BIG_ENDIAN != 0), 0, DImode);
929   operands[6] = operand_subword (operands[0], (WORDS_BIG_ENDIAN == 0), 0, DImode);
930   operands[7] = operand_subword (operands[2], (WORDS_BIG_ENDIAN == 0), 0, DImode);
933 (define_insn "*sub_carry"
934   [(set (match_operand:SI 0 "register_operand" "=r")
935         (minus:SI (match_operand:SI 1 "register_operand" "%0")
936                   (minus:SI (match_operand:SI 2 "register_operand" "r")
937                             (ne:SI (reg:CC 17) (const_int 0)))))
938    (set (reg:CC 17)
939         (unspec:CC [(const_int 0)] UNSPEC_SET_CBIT))]
940   ""
941   "subx %0,%2"
942   [(set_attr "type" "int2")
943    (set_attr "length" "2")])
945 ; Multiply/Divide instructions.
947 (define_insn "mulhisi3"
948   [(set (match_operand:SI 0 "register_operand" "=r")
949         (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" "r"))
950                  (sign_extend:SI (match_operand:HI 2 "register_operand" "r"))))]
951   ""
952   "mullo %1,%2\;mvfacmi %0"
953   [(set_attr "type" "multi")
954    (set_attr "length" "4")])
956 (define_insn "mulsi3"
957   [(set (match_operand:SI 0 "register_operand" "=r")
958         (mult:SI (match_operand:SI 1 "register_operand" "%0")
959                  (match_operand:SI 2 "register_operand" "r")))]
960   ""
961   "mul %0,%2"
962   [(set_attr "type" "mul2")
963    (set_attr "length" "2")])
965 (define_insn "divsi3"
966   [(set (match_operand:SI 0 "register_operand" "=r")
967         (div:SI (match_operand:SI 1 "register_operand" "0")
968                 (match_operand:SI 2 "register_operand" "r")))]
969   ""
970   "div %0,%2"
971   [(set_attr "type" "div4")
972    (set_attr "length" "4")])
974 (define_insn "udivsi3"
975   [(set (match_operand:SI 0 "register_operand" "=r")
976         (udiv:SI (match_operand:SI 1 "register_operand" "0")
977                  (match_operand:SI 2 "register_operand" "r")))]
978   ""
979   "divu %0,%2"
980   [(set_attr "type" "div4")
981    (set_attr "length" "4")])
983 (define_insn "modsi3"
984   [(set (match_operand:SI 0 "register_operand" "=r")
985         (mod:SI (match_operand:SI 1 "register_operand" "0")
986                 (match_operand:SI 2 "register_operand" "r")))]
987   ""
988   "rem %0,%2"
989   [(set_attr "type" "div4")
990    (set_attr "length" "4")])
992 (define_insn "umodsi3"
993   [(set (match_operand:SI 0 "register_operand" "=r")
994         (umod:SI (match_operand:SI 1 "register_operand" "0")
995                  (match_operand:SI 2 "register_operand" "r")))]
996   ""
997   "remu %0,%2"
998   [(set_attr "type" "div4")
999    (set_attr "length" "4")])
1001 ;; Boolean instructions.
1003 ;; We don't define the DImode versions as expand_binop does a good enough job.
1004 ;; And if it doesn't it should be fixed.
1006 (define_insn "andsi3"
1007   [(set (match_operand:SI 0 "register_operand" "=r,r")
1008         (and:SI (match_operand:SI 1 "register_operand" "%0,r")
1009                 (match_operand:SI 2 "reg_or_uint16_operand" "r,K")))]
1010   ""
1011   "*
1013   /* If we are worried about space, see if we can break this up into two
1014      short instructions, which might eliminate a NOP being inserted.  */
1015   if (optimize_size
1016       && m32r_not_same_reg (operands[0], operands[1])
1017       && GET_CODE (operands[2]) == CONST_INT
1018       && INT8_P (INTVAL (operands[2])))
1019     return \"#\";
1021   else if (GET_CODE (operands[2]) == CONST_INT)
1022     return \"and3 %0,%1,%#%X2\";
1024   return \"and %0,%2\";
1026   [(set_attr "type" "int2,int4")
1027    (set_attr "length" "2,4")])
1029 (define_split
1030   [(set (match_operand:SI 0 "register_operand" "")
1031         (and:SI (match_operand:SI 1 "register_operand" "")
1032                 (match_operand:SI 2 "int8_operand" "")))]
1033   "optimize_size && m32r_not_same_reg (operands[0], operands[1])"
1034   [(set (match_dup 0) (match_dup 2))
1035    (set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))]
1036   "")
1038 (define_insn "iorsi3"
1039   [(set (match_operand:SI 0 "register_operand" "=r,r")
1040         (ior:SI (match_operand:SI 1 "register_operand" "%0,r")
1041                 (match_operand:SI 2 "reg_or_uint16_operand" "r,K")))]
1042   ""
1043   "*
1045   /* If we are worried about space, see if we can break this up into two
1046      short instructions, which might eliminate a NOP being inserted.  */
1047   if (optimize_size
1048       && m32r_not_same_reg (operands[0], operands[1])
1049       && GET_CODE (operands[2]) == CONST_INT
1050       && INT8_P (INTVAL (operands[2])))
1051     return \"#\";
1053   else if (GET_CODE (operands[2]) == CONST_INT)
1054     return \"or3 %0,%1,%#%X2\";
1056   return \"or %0,%2\";
1058   [(set_attr "type" "int2,int4")
1059    (set_attr "length" "2,4")])
1061 (define_split
1062   [(set (match_operand:SI 0 "register_operand" "")
1063         (ior:SI (match_operand:SI 1 "register_operand" "")
1064                 (match_operand:SI 2 "int8_operand" "")))]
1065   "optimize_size && m32r_not_same_reg (operands[0], operands[1])"
1066   [(set (match_dup 0) (match_dup 2))
1067    (set (match_dup 0) (ior:SI (match_dup 0) (match_dup 1)))]
1068   "")
1070 (define_insn "xorsi3"
1071   [(set (match_operand:SI 0 "register_operand" "=r,r")
1072         (xor:SI (match_operand:SI 1 "register_operand" "%0,r")
1073                 (match_operand:SI 2 "reg_or_uint16_operand" "r,K")))]
1074   ""
1075   "*
1077   /* If we are worried about space, see if we can break this up into two
1078      short instructions, which might eliminate a NOP being inserted.  */
1079   if (optimize_size
1080       && m32r_not_same_reg (operands[0], operands[1])
1081       && GET_CODE (operands[2]) == CONST_INT
1082       && INT8_P (INTVAL (operands[2])))
1083     return \"#\";
1085   else if (GET_CODE (operands[2]) == CONST_INT)
1086     return \"xor3 %0,%1,%#%X2\";
1088   return \"xor %0,%2\";
1090   [(set_attr "type" "int2,int4")
1091    (set_attr "length" "2,4")])
1093 (define_split
1094   [(set (match_operand:SI 0 "register_operand" "")
1095         (xor:SI (match_operand:SI 1 "register_operand" "")
1096                 (match_operand:SI 2 "int8_operand" "")))]
1097   "optimize_size && m32r_not_same_reg (operands[0], operands[1])"
1098   [(set (match_dup 0) (match_dup 2))
1099    (set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))]
1100   "")
1102 (define_insn "negsi2"
1103   [(set (match_operand:SI 0 "register_operand" "=r")
1104         (neg:SI (match_operand:SI 1 "register_operand" "r")))]
1105   ""
1106   "neg %0,%1"
1107   [(set_attr "type" "int2")
1108    (set_attr "length" "2")])
1110 (define_insn "one_cmplsi2"
1111   [(set (match_operand:SI 0 "register_operand" "=r")
1112         (not:SI (match_operand:SI 1 "register_operand" "r")))]
1113   ""
1114   "not %0,%1"
1115   [(set_attr "type" "int2")
1116    (set_attr "length" "2")])
1118 ;; Shift instructions.
1120 (define_insn "ashlsi3"
1121   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
1122         (ashift:SI (match_operand:SI 1 "register_operand" "0,0,r")
1123                    (match_operand:SI 2 "reg_or_uint16_operand" "r,O,K")))]
1124   ""
1125   "@
1126    sll %0,%2
1127    slli %0,%#%2
1128    sll3 %0,%1,%#%2"
1129   [(set_attr "type" "shift2,shift2,shift4")
1130    (set_attr "length" "2,2,4")])
1132 (define_insn "ashrsi3"
1133   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
1134         (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0,r")
1135                      (match_operand:SI 2 "reg_or_uint16_operand" "r,O,K")))]
1136   ""
1137   "@
1138    sra %0,%2
1139    srai %0,%#%2
1140    sra3 %0,%1,%#%2"
1141   [(set_attr "type" "shift2,shift2,shift4")
1142    (set_attr "length" "2,2,4")])
1144 (define_insn "lshrsi3"
1145   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
1146         (lshiftrt:SI (match_operand:SI 1 "register_operand" "0,0,r")
1147                      (match_operand:SI 2 "reg_or_uint16_operand" "r,O,K")))]
1148   ""
1149   "@
1150    srl %0,%2
1151    srli %0,%#%2
1152    srl3 %0,%1,%#%2"
1153   [(set_attr "type" "shift2,shift2,shift4")
1154    (set_attr "length" "2,2,4")])
1156 ;; Compare instructions.
1157 ;; This controls RTL generation and register allocation.
1159 ;; We generate RTL for comparisons and branches by having the cmpxx 
1160 ;; patterns store away the operands.  Then the bcc patterns
1161 ;; emit RTL for both the compare and the branch.
1163 ;; On the m32r it is more efficient to use the bxxz instructions and
1164 ;; thus merge the compare and branch into one instruction, so they are
1165 ;; preferred.
1167 (define_expand "cmpsi"
1168   [(set (reg:CC 17)
1169         (compare:CC (match_operand:SI 0 "register_operand" "")
1170                     (match_operand:SI 1 "reg_or_cmp_int16_operand" "")))]
1171   ""
1172   "
1174   m32r_compare_op0 = operands[0];
1175   m32r_compare_op1 = operands[1];
1176   DONE;
1179 (define_insn "cmp_eqsi_zero_insn"
1180   [(set (reg:CC 17)
1181         (eq:CC (match_operand:SI 0 "register_operand" "r,r")
1182                (match_operand:SI 1 "reg_or_zero_operand" "r,P")))]
1183   "TARGET_M32RX || TARGET_M32R2"
1184   "@
1185    cmpeq %0, %1
1186    cmpz  %0"
1187   [(set_attr "type" "int4")
1188    (set_attr "length" "4")])
1190 ;; The cmp_xxx_insn patterns set the condition bit to the result of the
1191 ;; comparison.  There isn't a "compare equal" instruction so cmp_eqsi_insn
1192 ;; is quite inefficient.  However, it is rarely used.
1194 (define_insn "cmp_eqsi_insn"
1195   [(set (reg:CC 17)
1196         (eq:CC (match_operand:SI 0 "register_operand" "r,r")
1197                (match_operand:SI 1 "reg_or_cmp_int16_operand" "r,P")))
1198    (clobber (match_scratch:SI 2 "=&r,&r"))]
1199   ""
1200   "*
1202   if (which_alternative == 0)
1203     {
1204          return \"mv %2,%0\;sub %2,%1\;cmpui %2,#1\";
1205     }
1206   else
1207     {
1208         if (INTVAL (operands [1]) == 0)
1209           return \"cmpui %0, #1\";
1210         else if (REGNO (operands [2]) == REGNO (operands [0]))
1211           return \"addi %0,%#%N1\;cmpui %2,#1\";
1212         else
1213           return \"add3 %2,%0,%#%N1\;cmpui %2,#1\";
1214     }
1216   [(set_attr "type" "multi,multi")
1217    (set_attr "length" "8,8")])
1219 (define_insn "cmp_ltsi_insn"
1220   [(set (reg:CC 17)
1221         (lt:CC (match_operand:SI 0 "register_operand" "r,r")
1222                (match_operand:SI 1 "reg_or_int16_operand" "r,J")))]
1223   ""
1224   "@
1225    cmp %0,%1
1226    cmpi %0,%#%1"
1227   [(set_attr "type" "int2,int4")
1228    (set_attr "length" "2,4")])
1230 (define_insn "cmp_ltusi_insn"
1231   [(set (reg:CC 17)
1232         (ltu:CC (match_operand:SI 0 "register_operand" "r,r")
1233                 (match_operand:SI 1 "reg_or_int16_operand" "r,J")))]
1234   ""
1235   "@
1236    cmpu %0,%1
1237    cmpui %0,%#%1"
1238   [(set_attr "type" "int2,int4")
1239    (set_attr "length" "2,4")])
1241 ;; These control RTL generation for conditional jump insns.
1243 (define_expand "beq"
1244   [(set (pc)
1245         (if_then_else (match_dup 1)
1246                       (label_ref (match_operand 0 "" ""))
1247                       (pc)))]
1248   ""
1249   "
1251   operands[1] = gen_compare (EQ, m32r_compare_op0, m32r_compare_op1, FALSE);
1254 (define_expand "bne"
1255   [(set (pc)
1256         (if_then_else (match_dup 1)
1257                       (label_ref (match_operand 0 "" ""))
1258                       (pc)))]
1259   ""
1260   "
1262   operands[1] = gen_compare (NE, m32r_compare_op0, m32r_compare_op1, FALSE);
1265 (define_expand "bgt"
1266   [(set (pc)
1267         (if_then_else (match_dup 1)
1268                       (label_ref (match_operand 0 "" ""))
1269                       (pc)))]
1270   ""
1271   "
1273   operands[1] = gen_compare (GT, m32r_compare_op0, m32r_compare_op1, FALSE);
1276 (define_expand "ble"
1277   [(set (pc)
1278         (if_then_else (match_dup 1)
1279                       (label_ref (match_operand 0 "" ""))
1280                       (pc)))]
1281   ""
1282   "
1284   operands[1] = gen_compare (LE, m32r_compare_op0, m32r_compare_op1, FALSE);
1287 (define_expand "bge"
1288   [(set (pc)
1289         (if_then_else (match_dup 1)
1290                       (label_ref (match_operand 0 "" ""))
1291                       (pc)))]
1292   ""
1293   "
1295   operands[1] = gen_compare (GE, m32r_compare_op0, m32r_compare_op1, FALSE);
1298 (define_expand "blt"
1299   [(set (pc)
1300         (if_then_else (match_dup 1)
1301                       (label_ref (match_operand 0 "" ""))
1302                       (pc)))]
1303   ""
1304   "
1306   operands[1] = gen_compare (LT, m32r_compare_op0, m32r_compare_op1, FALSE);
1309 (define_expand "bgtu"
1310   [(set (pc)
1311         (if_then_else (match_dup 1)
1312                       (label_ref (match_operand 0 "" ""))
1313                       (pc)))]
1314   ""
1315   "
1317   operands[1] = gen_compare (GTU, m32r_compare_op0, m32r_compare_op1, FALSE);
1320 (define_expand "bleu"
1321   [(set (pc)
1322         (if_then_else (match_dup 1)
1323                       (label_ref (match_operand 0 "" ""))
1324                       (pc)))]
1325   ""
1326   "
1328   operands[1] = gen_compare (LEU, m32r_compare_op0, m32r_compare_op1, FALSE);
1331 (define_expand "bgeu"
1332   [(set (pc)
1333         (if_then_else (match_dup 1)
1334                       (label_ref (match_operand 0 "" ""))
1335                       (pc)))]
1336   ""
1337   "
1339   operands[1] = gen_compare (GEU, m32r_compare_op0, m32r_compare_op1, FALSE);
1342 (define_expand "bltu"
1343   [(set (pc)
1344         (if_then_else (match_dup 1)
1345                       (label_ref (match_operand 0 "" ""))
1346                       (pc)))]
1347   ""
1348   "
1350   operands[1] = gen_compare (LTU, m32r_compare_op0, m32r_compare_op1, FALSE);
1353 ;; Now match both normal and inverted jump.
1355 (define_insn "*branch_insn"
1356   [(set (pc)
1357         (if_then_else (match_operator 1 "eqne_comparison_operator"
1358                                       [(reg 17) (const_int 0)])
1359                       (label_ref (match_operand 0 "" ""))
1360                       (pc)))]
1361   ""
1362   "*
1364   static char instruction[40];
1365   sprintf (instruction, \"%s%s %%l0\",
1366            (GET_CODE (operands[1]) == NE) ? \"bc\" : \"bnc\",
1367            (get_attr_length (insn) == 2) ? \".s\" : \"\");
1368   return instruction;
1370   [(set_attr "type" "branch")
1371    ; We use 400/800 instead of 512,1024 to account for inaccurate insn
1372    ; lengths and insn alignments that are complex to track.
1373    ; It's not important that we be hyper-precise here.  It may be more
1374    ; important blah blah blah when the chip supports parallel execution
1375    ; blah blah blah but until then blah blah blah this is simple and
1376    ; suffices.
1377    (set (attr "length") (if_then_else (ltu (plus (minus (match_dup 0) (pc))
1378                                                  (const_int 400))
1379                                            (const_int 800))
1380                                       (const_int 2)
1381                                       (const_int 4)))])
1383 (define_insn "*rev_branch_insn"
1384   [(set (pc)
1385         (if_then_else (match_operator 1 "eqne_comparison_operator"
1386                                       [(reg 17) (const_int 0)])
1387                       (pc)
1388                       (label_ref (match_operand 0 "" ""))))]
1389   ;"REVERSIBLE_CC_MODE (GET_MODE (XEXP (operands[1], 0)))"
1390   ""
1391   "*
1393   static char instruction[40];
1394   sprintf (instruction, \"%s%s %%l0\",
1395            (GET_CODE (operands[1]) == EQ) ? \"bc\" : \"bnc\",
1396            (get_attr_length (insn) == 2) ? \".s\" : \"\");
1397   return instruction;
1399   [(set_attr "type" "branch")
1400    ; We use 400/800 instead of 512,1024 to account for inaccurate insn
1401    ; lengths and insn alignments that are complex to track.
1402    ; It's not important that we be hyper-precise here.  It may be more
1403    ; important blah blah blah when the chip supports parallel execution
1404    ; blah blah blah but until then blah blah blah this is simple and
1405    ; suffices.
1406    (set (attr "length") (if_then_else (ltu (plus (minus (match_dup 0) (pc))
1407                                                  (const_int 400))
1408                                            (const_int 800))
1409                                       (const_int 2)
1410                                       (const_int 4)))])
1412 ; reg/reg compare and branch insns
1414 (define_insn "*reg_branch_insn"
1415   [(set (pc)
1416         (if_then_else (match_operator 1 "eqne_comparison_operator"
1417                                       [(match_operand:SI 2 "register_operand" "r")
1418                                        (match_operand:SI 3 "register_operand" "r")])
1419                       (label_ref (match_operand 0 "" ""))
1420                       (pc)))]
1421   ""
1422   "*
1424   /* Is branch target reachable with beq/bne?  */
1425   if (get_attr_length (insn) == 4)
1426     {
1427       if (GET_CODE (operands[1]) == EQ)
1428         return \"beq %2,%3,%l0\";
1429       else
1430         return \"bne %2,%3,%l0\";
1431     }
1432   else
1433     {
1434       if (GET_CODE (operands[1]) == EQ)
1435         return \"bne %2,%3,1f\;bra %l0\;1:\";
1436       else
1437         return \"beq %2,%3,1f\;bra %l0\;1:\";
1438     }
1440   [(set_attr "type" "branch")
1441   ; We use 25000/50000 instead of 32768/65536 to account for slot filling
1442   ; which is complex to track and inaccurate length specs.
1443    (set (attr "length") (if_then_else (ltu (plus (minus (match_dup 0) (pc))
1444                                                  (const_int 25000))
1445                                            (const_int 50000))
1446                                       (const_int 4)
1447                                       (const_int 8)))])
1449 (define_insn "*rev_reg_branch_insn"
1450   [(set (pc)
1451         (if_then_else (match_operator 1 "eqne_comparison_operator"
1452                                       [(match_operand:SI 2 "register_operand" "r")
1453                                        (match_operand:SI 3 "register_operand" "r")])
1454                       (pc)
1455                       (label_ref (match_operand 0 "" ""))))]
1456   ""
1457   "*
1459   /* Is branch target reachable with beq/bne?  */
1460   if (get_attr_length (insn) == 4)
1461     {
1462       if (GET_CODE (operands[1]) == NE)
1463         return \"beq %2,%3,%l0\";
1464       else
1465         return \"bne %2,%3,%l0\";
1466     }
1467   else
1468     {
1469       if (GET_CODE (operands[1]) == NE)
1470         return \"bne %2,%3,1f\;bra %l0\;1:\";
1471       else
1472         return \"beq %2,%3,1f\;bra %l0\;1:\";
1473     }
1475   [(set_attr "type" "branch")
1476   ; We use 25000/50000 instead of 32768/65536 to account for slot filling
1477   ; which is complex to track and inaccurate length specs.
1478    (set (attr "length") (if_then_else (ltu (plus (minus (match_dup 0) (pc))
1479                                                  (const_int 25000))
1480                                            (const_int 50000))
1481                                       (const_int 4)
1482                                       (const_int 8)))])
1484 ; reg/zero compare and branch insns
1486 (define_insn "*zero_branch_insn"
1487   [(set (pc)
1488         (if_then_else (match_operator 1 "signed_comparison_operator"
1489                                       [(match_operand:SI 2 "register_operand" "r")
1490                                        (const_int 0)])
1491                       (label_ref (match_operand 0 "" ""))
1492                       (pc)))]
1493   ""
1494   "*
1496   const char *br,*invbr;
1497   char asmtext[40];
1499   switch (GET_CODE (operands[1]))
1500     {
1501       case EQ : br = \"eq\"; invbr = \"ne\"; break;
1502       case NE : br = \"ne\"; invbr = \"eq\"; break;
1503       case LE : br = \"le\"; invbr = \"gt\"; break;
1504       case GT : br = \"gt\"; invbr = \"le\"; break;
1505       case LT : br = \"lt\"; invbr = \"ge\"; break;
1506       case GE : br = \"ge\"; invbr = \"lt\"; break;
1508       default: abort();
1509     }
1511   /* Is branch target reachable with bxxz?  */
1512   if (get_attr_length (insn) == 4)
1513     {
1514       sprintf (asmtext, \"b%sz %%2,%%l0\", br);
1515       output_asm_insn (asmtext, operands);
1516     }
1517   else
1518     {
1519       sprintf (asmtext, \"b%sz %%2,1f\;bra %%l0\;1:\", invbr);
1520       output_asm_insn (asmtext, operands);
1521     }
1522   return \"\";
1524   [(set_attr "type" "branch")
1525   ; We use 25000/50000 instead of 32768/65536 to account for slot filling
1526   ; which is complex to track and inaccurate length specs.
1527    (set (attr "length") (if_then_else (ltu (plus (minus (match_dup 0) (pc))
1528                                                  (const_int 25000))
1529                                            (const_int 50000))
1530                                       (const_int 4)
1531                                       (const_int 8)))])
1533 (define_insn "*rev_zero_branch_insn"
1534   [(set (pc)
1535         (if_then_else (match_operator 1 "eqne_comparison_operator"
1536                                       [(match_operand:SI 2 "register_operand" "r")
1537                                        (const_int 0)])
1538                       (pc)
1539                       (label_ref (match_operand 0 "" ""))))]
1540   ""
1541   "*
1543   const char *br,*invbr;
1544   char asmtext[40];
1546   switch (GET_CODE (operands[1]))
1547     {
1548       case EQ : br = \"eq\"; invbr = \"ne\"; break;
1549       case NE : br = \"ne\"; invbr = \"eq\"; break;
1550       case LE : br = \"le\"; invbr = \"gt\"; break;
1551       case GT : br = \"gt\"; invbr = \"le\"; break;
1552       case LT : br = \"lt\"; invbr = \"ge\"; break;
1553       case GE : br = \"ge\"; invbr = \"lt\"; break;
1555       default: abort();
1556     }
1558   /* Is branch target reachable with bxxz?  */
1559   if (get_attr_length (insn) == 4)
1560     {
1561       sprintf (asmtext, \"b%sz %%2,%%l0\", invbr);
1562       output_asm_insn (asmtext, operands);
1563     }
1564   else
1565     {
1566       sprintf (asmtext, \"b%sz %%2,1f\;bra %%l0\;1:\", br);
1567       output_asm_insn (asmtext, operands);
1568     }
1569   return \"\";
1571   [(set_attr "type" "branch")
1572   ; We use 25000/50000 instead of 32768/65536 to account for slot filling
1573   ; which is complex to track and inaccurate length specs.
1574    (set (attr "length") (if_then_else (ltu (plus (minus (match_dup 0) (pc))
1575                                                  (const_int 25000))
1576                                            (const_int 50000))
1577                                       (const_int 4)
1578                                       (const_int 8)))])
1580 ;; S<cc> operations to set a register to 1/0 based on a comparison
1582 (define_expand "seq"
1583   [(match_operand:SI 0 "register_operand" "")]
1584   ""
1585   "
1587   rtx op0 = operands[0];
1588   rtx op1 = m32r_compare_op0;
1589   rtx op2 = m32r_compare_op1;
1590   enum machine_mode mode = GET_MODE (op0);
1592   if (mode != SImode)
1593     FAIL;
1595   if (! register_operand (op1, mode))
1596     op1 = force_reg (mode, op1);
1598   if (TARGET_M32RX || TARGET_M32R2)
1599     {
1600       if (! reg_or_zero_operand (op2, mode))
1601         op2 = force_reg (mode, op2);
1603       emit_insn (gen_seq_insn_m32rx (op0, op1, op2));
1604       DONE;
1605     }
1606   if (GET_CODE (op2) == CONST_INT && INTVAL (op2) == 0)
1607     {
1608       emit_insn (gen_seq_zero_insn (op0, op1));
1609       DONE;
1610     }
1612   if (! reg_or_eq_int16_operand (op2, mode))
1613     op2 = force_reg (mode, op2);
1615   emit_insn (gen_seq_insn (op0, op1, op2));
1616   DONE;
1619 (define_insn "seq_insn_m32rx"
1620   [(set (match_operand:SI 0 "register_operand" "=r")
1621         (eq:SI (match_operand:SI 1 "register_operand" "%r")
1622                (match_operand:SI 2 "reg_or_zero_operand" "rP")))
1623    (clobber (reg:CC 17))]
1624   "TARGET_M32RX || TARGET_M32R2"
1625   "#"
1626   [(set_attr "type" "multi")
1627    (set_attr "length" "6")])
1629 (define_split
1630   [(set (match_operand:SI 0 "register_operand" "")
1631         (eq:SI (match_operand:SI 1 "register_operand" "")
1632                (match_operand:SI 2 "reg_or_zero_operand" "")))
1633    (clobber (reg:CC 17))]
1634   "TARGET_M32RX || TARGET_M32R2"
1635   [(set (reg:CC 17)
1636         (eq:CC (match_dup 1)
1637                (match_dup 2)))
1638    (set (match_dup 0)
1639         (ne:SI (reg:CC 17) (const_int 0)))]
1640   "")
1642 (define_insn "seq_zero_insn"
1643   [(set (match_operand:SI 0 "register_operand" "=r")
1644         (eq:SI (match_operand:SI 1 "register_operand" "r")
1645                (const_int 0)))
1646    (clobber (reg:CC 17))]
1647   "TARGET_M32R"
1648   "#"
1649   [(set_attr "type" "multi")
1650    (set_attr "length" "6")])
1652 (define_split
1653   [(set (match_operand:SI 0 "register_operand" "")
1654         (eq:SI (match_operand:SI 1 "register_operand" "")
1655                (const_int 0)))
1656    (clobber (reg:CC 17))]
1657   "TARGET_M32R"
1658   [(match_dup 3)]
1659   "
1661   rtx op0 = operands[0];
1662   rtx op1 = operands[1];
1664   start_sequence ();
1665   emit_insn (gen_cmp_ltusi_insn (op1, const1_rtx));
1666   emit_insn (gen_movcc_insn (op0));
1667   operands[3] = get_insns ();
1668   end_sequence ();
1671 (define_insn "seq_insn"
1672   [(set (match_operand:SI 0 "register_operand" "=r,r,??r,r")
1673         (eq:SI (match_operand:SI 1 "register_operand" "r,r,r,r")
1674                (match_operand:SI 2 "reg_or_eq_int16_operand" "r,r,r,PK")))
1675    (clobber (reg:CC 17))
1676    (clobber (match_scratch:SI 3 "=1,2,&r,r"))]
1677   "TARGET_M32R"
1678   "#"
1679   [(set_attr "type" "multi")
1680    (set_attr "length" "8,8,10,10")])
1682 (define_split
1683   [(set (match_operand:SI 0 "register_operand" "")
1684         (eq:SI (match_operand:SI 1 "register_operand" "")
1685                (match_operand:SI 2 "reg_or_eq_int16_operand" "")))
1686    (clobber (reg:CC 17))
1687    (clobber (match_scratch:SI 3 ""))]
1688   "TARGET_M32R && reload_completed"
1689   [(match_dup 4)]
1690   "
1692   rtx op0 = operands[0];
1693   rtx op1 = operands[1];
1694   rtx op2 = operands[2];
1695   rtx op3 = operands[3];
1696   HOST_WIDE_INT value;
1698   if (GET_CODE (op2) == REG && GET_CODE (op3) == REG
1699       && REGNO (op2) == REGNO (op3))
1700     {
1701       op1 = operands[2];
1702       op2 = operands[1];
1703     }
1705   start_sequence ();
1706   if (GET_CODE (op1) == REG && GET_CODE (op3) == REG
1707       && REGNO (op1) != REGNO (op3))
1708     {
1709       emit_move_insn (op3, op1);
1710       op1 = op3;
1711     }
1713   if (GET_CODE (op2) == CONST_INT && (value = INTVAL (op2)) != 0
1714       && CMP_INT16_P (value))
1715     emit_insn (gen_addsi3 (op3, op1, GEN_INT (-value)));
1716   else
1717     emit_insn (gen_xorsi3 (op3, op1, op2));
1719   emit_insn (gen_cmp_ltusi_insn (op3, const1_rtx));
1720   emit_insn (gen_movcc_insn (op0));
1721   operands[4] = get_insns ();
1722   end_sequence ();
1725 (define_expand "sne"
1726   [(match_operand:SI 0 "register_operand" "")]
1727   ""
1728   "
1730   rtx op0 = operands[0];
1731   rtx op1 = m32r_compare_op0;
1732   rtx op2 = m32r_compare_op1;
1733   enum machine_mode mode = GET_MODE (op0);
1735   if (mode != SImode)
1736     FAIL;
1738   if (GET_CODE (op2) != CONST_INT
1739       || (INTVAL (op2) != 0 && UINT16_P (INTVAL (op2))))
1740     {
1741       rtx reg;
1743       if (reload_completed || reload_in_progress)
1744         FAIL;
1746       reg = gen_reg_rtx (SImode);
1747       emit_insn (gen_xorsi3 (reg, op1, op2));
1748       op1 = reg;
1750       if (! register_operand (op1, mode))
1751         op1 = force_reg (mode, op1);
1753       emit_insn (gen_sne_zero_insn (op0, op1));
1754       DONE;
1755     }
1756   else
1757     FAIL;
1760 (define_insn "sne_zero_insn"
1761   [(set (match_operand:SI 0 "register_operand" "=r")
1762         (ne:SI (match_operand:SI 1 "register_operand" "r")
1763                (const_int 0)))
1764    (clobber (reg:CC 17))
1765    (clobber (match_scratch:SI 2 "=&r"))]
1766   ""
1767   "#"
1768   [(set_attr "type" "multi")
1769    (set_attr "length" "6")])
1771 (define_split
1772   [(set (match_operand:SI 0 "register_operand" "")
1773         (ne:SI (match_operand:SI 1 "register_operand" "")
1774                (const_int 0)))
1775    (clobber (reg:CC 17))
1776    (clobber (match_scratch:SI 2 ""))]
1777   "reload_completed"
1778   [(set (match_dup 2)
1779         (const_int 0))
1780    (set (reg:CC 17)
1781         (ltu:CC (match_dup 2)
1782                 (match_dup 1)))
1783    (set (match_dup 0)
1784         (ne:SI (reg:CC 17) (const_int 0)))]
1785   "")
1786         
1787 (define_expand "slt"
1788   [(match_operand:SI 0 "register_operand" "")]
1789   ""
1790   "
1792   rtx op0 = operands[0];
1793   rtx op1 = m32r_compare_op0;
1794   rtx op2 = m32r_compare_op1;
1795   enum machine_mode mode = GET_MODE (op0);
1797   if (mode != SImode)
1798     FAIL;
1800   if (! register_operand (op1, mode))
1801     op1 = force_reg (mode, op1);
1803   if (! reg_or_int16_operand (op2, mode))
1804     op2 = force_reg (mode, op2);
1806   emit_insn (gen_slt_insn (op0, op1, op2));
1807   DONE;
1810 (define_insn "slt_insn"
1811   [(set (match_operand:SI 0 "register_operand" "=r,r")
1812         (lt:SI (match_operand:SI 1 "register_operand" "r,r")
1813                (match_operand:SI 2 "reg_or_int16_operand" "r,J")))
1814    (clobber (reg:CC 17))]
1815   ""
1816   "#"
1817   [(set_attr "type" "multi")
1818    (set_attr "length" "4,6")])
1820 (define_split
1821   [(set (match_operand:SI 0 "register_operand" "")
1822         (lt:SI (match_operand:SI 1 "register_operand" "")
1823                (match_operand:SI 2 "reg_or_int16_operand" "")))
1824    (clobber (reg:CC 17))]
1825   ""
1826   [(set (reg:CC 17)
1827         (lt:CC (match_dup 1)
1828                (match_dup 2)))
1829    (set (match_dup 0)
1830         (ne:SI (reg:CC 17) (const_int 0)))]
1831   "")
1833 (define_expand "sle"
1834   [(match_operand:SI 0 "register_operand" "")]
1835   ""
1836   "
1838   rtx op0 = operands[0];
1839   rtx op1 = m32r_compare_op0;
1840   rtx op2 = m32r_compare_op1;
1841   enum machine_mode mode = GET_MODE (op0);
1843   if (mode != SImode)
1844     FAIL;
1846   if (! register_operand (op1, mode))
1847     op1 = force_reg (mode, op1);
1849   if (GET_CODE (op2) == CONST_INT)
1850     {
1851       HOST_WIDE_INT value = INTVAL (op2);
1852       if (value >= 2147483647)
1853         {
1854           emit_move_insn (op0, const1_rtx);
1855           DONE;
1856         }
1858       op2 = GEN_INT (value+1);
1859       if (value < -32768 || value >= 32767)
1860         op2 = force_reg (mode, op2);
1862       emit_insn (gen_slt_insn (op0, op1, op2));
1863       DONE;
1864     }
1866   if (! register_operand (op2, mode))
1867     op2 = force_reg (mode, op2);
1869   emit_insn (gen_sle_insn (op0, op1, op2));
1870   DONE;
1873 (define_insn "sle_insn"
1874   [(set (match_operand:SI 0 "register_operand" "=r")
1875         (le:SI (match_operand:SI 1 "register_operand" "r")
1876                (match_operand:SI 2 "register_operand" "r")))
1877    (clobber (reg:CC 17))]
1878   ""
1879   "#"
1880   [(set_attr "type" "multi")
1881    (set_attr "length" "8")])
1883 (define_split
1884   [(set (match_operand:SI 0 "register_operand" "")
1885         (le:SI (match_operand:SI 1 "register_operand" "")
1886                (match_operand:SI 2 "register_operand" "")))
1887    (clobber (reg:CC 17))]
1888   "!optimize_size"
1889   [(set (reg:CC 17)
1890         (lt:CC (match_dup 2)
1891                (match_dup 1)))
1892    (set (match_dup 0)
1893         (ne:SI (reg:CC 17) (const_int 0)))
1894    (set (match_dup 0)
1895         (xor:SI (match_dup 0)
1896                 (const_int 1)))]
1897   "")
1899 ;; If optimizing for space, use -(reg - 1) to invert the comparison rather than
1900 ;; xor reg,reg,1 which might eliminate a NOP being inserted.
1901 (define_split
1902   [(set (match_operand:SI 0 "register_operand" "")
1903         (le:SI (match_operand:SI 1 "register_operand" "")
1904                (match_operand:SI 2 "register_operand" "")))
1905    (clobber (reg:CC 17))]
1906   "optimize_size"
1907   [(set (reg:CC 17)
1908         (lt:CC (match_dup 2)
1909                (match_dup 1)))
1910    (set (match_dup 0)
1911         (ne:SI (reg:CC 17) (const_int 0)))
1912    (set (match_dup 0)
1913         (plus:SI (match_dup 0)
1914                  (const_int -1)))
1915    (set (match_dup 0)
1916         (neg:SI (match_dup 0)))]
1917   "")
1919 (define_expand "sgt"
1920   [(match_operand:SI 0 "register_operand" "")]
1921   ""
1922   "
1924   rtx op0 = operands[0];
1925   rtx op1 = m32r_compare_op0;
1926   rtx op2 = m32r_compare_op1;
1927   enum machine_mode mode = GET_MODE (op0);
1929   if (mode != SImode)
1930     FAIL;
1932   if (! register_operand (op1, mode))
1933     op1 = force_reg (mode, op1);
1935   if (! register_operand (op2, mode))
1936     op2 = force_reg (mode, op2);
1938   emit_insn (gen_slt_insn (op0, op2, op1));
1939   DONE;
1942 (define_expand "sge"
1943   [(match_operand:SI 0 "register_operand" "")]
1944   ""
1945   "
1947   rtx op0 = operands[0];
1948   rtx op1 = m32r_compare_op0;
1949   rtx op2 = m32r_compare_op1;
1950   enum machine_mode mode = GET_MODE (op0);
1952   if (mode != SImode)
1953     FAIL;
1955   if (! register_operand (op1, mode))
1956     op1 = force_reg (mode, op1);
1958   if (! reg_or_int16_operand (op2, mode))
1959     op2 = force_reg (mode, op2);
1961   emit_insn (gen_sge_insn (op0, op1, op2));
1962   DONE;
1965 (define_insn "sge_insn"
1966   [(set (match_operand:SI 0 "register_operand" "=r,r")
1967         (ge:SI (match_operand:SI 1 "register_operand" "r,r")
1968                (match_operand:SI 2 "reg_or_int16_operand" "r,J")))
1969    (clobber (reg:CC 17))]
1970   ""
1971   "#"
1972   [(set_attr "type" "multi")
1973    (set_attr "length" "8,10")])
1975 (define_split
1976   [(set (match_operand:SI 0 "register_operand" "")
1977         (ge:SI (match_operand:SI 1 "register_operand" "")
1978                (match_operand:SI 2 "reg_or_int16_operand" "")))
1979    (clobber (reg:CC 17))]
1980   "!optimize_size"
1981   [(set (reg:CC 17)
1982         (lt:CC (match_dup 1)
1983                (match_dup 2)))
1984    (set (match_dup 0)
1985         (ne:SI (reg:CC 17) (const_int 0)))
1986    (set (match_dup 0)
1987         (xor:SI (match_dup 0)
1988                 (const_int 1)))]
1989   "")
1991 ;; If optimizing for space, use -(reg - 1) to invert the comparison rather than
1992 ;; xor reg,reg,1 which might eliminate a NOP being inserted.
1993 (define_split
1994   [(set (match_operand:SI 0 "register_operand" "")
1995         (ge:SI (match_operand:SI 1 "register_operand" "")
1996                (match_operand:SI 2 "reg_or_int16_operand" "")))
1997    (clobber (reg:CC 17))]
1998   "optimize_size"
1999   [(set (reg:CC 17)
2000         (lt:CC (match_dup 1)
2001                (match_dup 2)))
2002    (set (match_dup 0)
2003         (ne:SI (reg:CC 17) (const_int 0)))
2004    (set (match_dup 0)
2005         (plus:SI (match_dup 0)
2006                  (const_int -1)))
2007    (set (match_dup 0)
2008         (neg:SI (match_dup 0)))]
2009   "")
2011 (define_expand "sltu"
2012   [(match_operand:SI 0 "register_operand" "")]
2013   ""
2014   "
2016   rtx op0 = operands[0];
2017   rtx op1 = m32r_compare_op0;
2018   rtx op2 = m32r_compare_op1;
2019   enum machine_mode mode = GET_MODE (op0);
2021   if (mode != SImode)
2022     FAIL;
2024   if (! register_operand (op1, mode))
2025     op1 = force_reg (mode, op1);
2027   if (! reg_or_int16_operand (op2, mode))
2028     op2 = force_reg (mode, op2);
2030   emit_insn (gen_sltu_insn (op0, op1, op2));
2031   DONE;
2034 (define_insn "sltu_insn"
2035   [(set (match_operand:SI 0 "register_operand" "=r,r")
2036         (ltu:SI (match_operand:SI 1 "register_operand" "r,r")
2037                 (match_operand:SI 2 "reg_or_int16_operand" "r,J")))
2038    (clobber (reg:CC 17))]
2039   ""
2040   "#"
2041   [(set_attr "type" "multi")
2042    (set_attr "length" "6,8")])
2044 (define_split
2045   [(set (match_operand:SI 0 "register_operand" "")
2046         (ltu:SI (match_operand:SI 1 "register_operand" "")
2047                 (match_operand:SI 2 "reg_or_int16_operand" "")))
2048    (clobber (reg:CC 17))]
2049   ""
2050   [(set (reg:CC 17)
2051         (ltu:CC (match_dup 1)
2052                 (match_dup 2)))
2053    (set (match_dup 0)
2054         (ne:SI (reg:CC 17) (const_int 0)))]
2055   "")
2057 (define_expand "sleu"
2058   [(match_operand:SI 0 "register_operand" "")]
2059   ""
2060   "
2062   rtx op0 = operands[0];
2063   rtx op1 = m32r_compare_op0;
2064   rtx op2 = m32r_compare_op1;
2065   enum machine_mode mode = GET_MODE (op0);
2067   if (mode != SImode)
2068     FAIL;
2070   if (GET_CODE (op2) == CONST_INT)
2071     {
2072       HOST_WIDE_INT value = INTVAL (op2);
2073       if (value >= 2147483647)
2074         {
2075           emit_move_insn (op0, const1_rtx);
2076           DONE;
2077         }
2079       op2 = GEN_INT (value+1);
2080       if (value < 0 || value >= 32767)
2081         op2 = force_reg (mode, op2);
2083       emit_insn (gen_sltu_insn (op0, op1, op2));
2084       DONE;
2085     }
2087   if (! register_operand (op2, mode))
2088     op2 = force_reg (mode, op2);
2090   emit_insn (gen_sleu_insn (op0, op1, op2));
2091   DONE;
2094 (define_insn "sleu_insn"
2095   [(set (match_operand:SI 0 "register_operand" "=r")
2096         (leu:SI (match_operand:SI 1 "register_operand" "r")
2097                 (match_operand:SI 2 "register_operand" "r")))
2098    (clobber (reg:CC 17))]
2099   ""
2100   "#"
2101   [(set_attr "type" "multi")
2102    (set_attr "length" "8")])
2104 (define_split
2105   [(set (match_operand:SI 0 "register_operand" "")
2106         (leu:SI (match_operand:SI 1 "register_operand" "")
2107                 (match_operand:SI 2 "register_operand" "")))
2108    (clobber (reg:CC 17))]
2109   "!optimize_size"
2110   [(set (reg:CC 17)
2111         (ltu:CC (match_dup 2)
2112                 (match_dup 1)))
2113    (set (match_dup 0)
2114         (ne:SI (reg:CC 17) (const_int 0)))
2115    (set (match_dup 0)
2116         (xor:SI (match_dup 0)
2117                 (const_int 1)))]
2118   "")
2120 ;; If optimizing for space, use -(reg - 1) to invert the comparison rather than
2121 ;; xor reg,reg,1 which might eliminate a NOP being inserted.
2122 (define_split
2123   [(set (match_operand:SI 0 "register_operand" "")
2124         (leu:SI (match_operand:SI 1 "register_operand" "")
2125                 (match_operand:SI 2 "register_operand" "")))
2126    (clobber (reg:CC 17))]
2127   "optimize_size"
2128   [(set (reg:CC 17)
2129         (ltu:CC (match_dup 2)
2130                 (match_dup 1)))
2131    (set (match_dup 0)
2132         (ne:SI (reg:CC 17) (const_int 0)))
2133    (set (match_dup 0)
2134         (plus:SI (match_dup 0)
2135                  (const_int -1)))
2136    (set (match_dup 0)
2137         (neg:SI (match_dup 0)))]
2138   "")
2140 (define_expand "sgtu"
2141   [(match_operand:SI 0 "register_operand" "")]
2142   ""
2143   "
2145   rtx op0 = operands[0];
2146   rtx op1 = m32r_compare_op0;
2147   rtx op2 = m32r_compare_op1;
2148   enum machine_mode mode = GET_MODE (op0);
2150   if (mode != SImode)
2151     FAIL;
2153   if (! register_operand (op1, mode))
2154     op1 = force_reg (mode, op1);
2156   if (! register_operand (op2, mode))
2157     op2 = force_reg (mode, op2);
2159   emit_insn (gen_sltu_insn (op0, op2, op1));
2160   DONE;
2163 (define_expand "sgeu"
2164   [(match_operand:SI 0 "register_operand" "")]
2165   ""
2166   "
2168   rtx op0 = operands[0];
2169   rtx op1 = m32r_compare_op0;
2170   rtx op2 = m32r_compare_op1;
2171   enum machine_mode mode = GET_MODE (op0);
2173   if (mode != SImode)
2174     FAIL;
2176   if (! register_operand (op1, mode))
2177     op1 = force_reg (mode, op1);
2179   if (! reg_or_int16_operand (op2, mode))
2180     op2 = force_reg (mode, op2);
2182   emit_insn (gen_sgeu_insn (op0, op1, op2));
2183   DONE;
2186 (define_insn "sgeu_insn"
2187   [(set (match_operand:SI 0 "register_operand" "=r,r")
2188         (geu:SI (match_operand:SI 1 "register_operand" "r,r")
2189                 (match_operand:SI 2 "reg_or_int16_operand" "r,J")))
2190    (clobber (reg:CC 17))]
2191   ""
2192   "#"
2193   [(set_attr "type" "multi")
2194    (set_attr "length" "8,10")])
2196 (define_split
2197   [(set (match_operand:SI 0 "register_operand" "")
2198         (geu:SI (match_operand:SI 1 "register_operand" "")
2199                 (match_operand:SI 2 "reg_or_int16_operand" "")))
2200    (clobber (reg:CC 17))]
2201   "!optimize_size"
2202   [(set (reg:CC 17)
2203         (ltu:CC (match_dup 1)
2204                 (match_dup 2)))
2205    (set (match_dup 0)
2206         (ne:SI (reg:CC 17) (const_int 0)))
2207    (set (match_dup 0)
2208         (xor:SI (match_dup 0)
2209                 (const_int 1)))]
2210   "")
2212 ;; If optimizing for space, use -(reg - 1) to invert the comparison rather than
2213 ;; xor reg,reg,1 which might eliminate a NOP being inserted.
2214 (define_split
2215   [(set (match_operand:SI 0 "register_operand" "")
2216         (geu:SI (match_operand:SI 1 "register_operand" "")
2217                 (match_operand:SI 2 "reg_or_int16_operand" "")))
2218    (clobber (reg:CC 17))]
2219   "optimize_size"
2220   [(set (reg:CC 17)
2221         (ltu:CC (match_dup 1)
2222                 (match_dup 2)))
2223    (set (match_dup 0)
2224         (ne:SI (reg:CC 17) (const_int 0)))
2225    (set (match_dup 0)
2226         (plus:SI (match_dup 0)
2227                  (const_int -1)))
2228    (set (match_dup 0)
2229         (neg:SI (match_dup 0)))]
2230   "")
2232 (define_insn "movcc_insn"
2233   [(set (match_operand:SI 0 "register_operand" "=r")
2234         (ne:SI (reg:CC 17) (const_int 0)))]
2235   ""
2236   "mvfc %0, cbr"
2237   [(set_attr "type" "misc")
2238    (set_attr "length" "2")])
2241 ;; Unconditional and other jump instructions.
2243 (define_insn "jump"
2244   [(set (pc) (label_ref (match_operand 0 "" "")))]
2245   ""
2246   "bra %l0"
2247   [(set_attr "type" "uncond_branch")
2248    (set (attr "length") (if_then_else (ltu (plus (minus (match_dup 0) (pc))
2249                                                  (const_int 400))
2250                                            (const_int 800))
2251                                       (const_int 2)
2252                                       (const_int 4)))])
2254 (define_insn "indirect_jump"
2255   [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
2256   ""
2257   "jmp %a0"
2258   [(set_attr "type" "uncond_branch")
2259    (set_attr "length" "2")])
2261 (define_insn "return"
2262   [(return)]
2263   "direct_return ()"
2264   "jmp lr"
2265   [(set_attr "type" "uncond_branch")
2266    (set_attr "length" "2")])
2268 (define_expand "tablejump"
2269   [(parallel [(set (pc) (match_operand 0 "register_operand" "r"))
2270               (use (label_ref (match_operand 1 "" "")))])]
2271   ""
2272   "
2274   /* In pic mode, our address differences are against the base of the
2275      table.  Add that base value back in; CSE ought to be able to combine
2276      the two address loads.  */
2277   if (flag_pic)
2278     {
2279       rtx tmp, tmp2;
2281       tmp = gen_rtx_LABEL_REF (Pmode, operands[1]);
2282       tmp2 = operands[0];
2283       tmp = gen_rtx_PLUS (Pmode, tmp2, tmp);
2284       operands[0] = memory_address (Pmode, tmp);
2285     }
2288 (define_insn "*tablejump_insn"
2289   [(set (pc) (match_operand:SI 0 "address_operand" "p"))
2290    (use (label_ref (match_operand 1 "" "")))]
2291   ""
2292   "jmp %a0"
2293   [(set_attr "type" "uncond_branch")
2294    (set_attr "length" "2")])
2296 (define_expand "call"
2297   ;; operands[1] is stack_size_rtx
2298   ;; operands[2] is next_arg_register
2299   [(parallel [(call (match_operand:SI 0 "call_operand" "")
2300                     (match_operand 1 "" ""))
2301              (clobber (reg:SI 14))])]
2302   ""
2303   "
2305   if (flag_pic)
2306     current_function_uses_pic_offset_table = 1;
2309 (define_insn "*call_via_reg"
2310   [(call (mem:SI (match_operand:SI 0 "register_operand" "r"))
2311          (match_operand 1 "" ""))
2312    (clobber (reg:SI 14))]
2313   ""
2314   "jl %0"
2315   [(set_attr "type" "call")
2316    (set_attr "length" "2")])
2318 (define_insn "*call_via_label"
2319   [(call (mem:SI (match_operand:SI 0 "call_address_operand" ""))
2320          (match_operand 1 "" ""))
2321    (clobber (reg:SI 14))]
2322   ""
2323   "*
2325   int call26_p = call26_operand (operands[0], FUNCTION_MODE);
2327   if (! call26_p)
2328     {
2329       /* We may not be able to reach with a `bl' insn so punt and leave it to
2330          the linker.
2331          We do this here, rather than doing a force_reg in the define_expand
2332          so these insns won't be separated, say by scheduling, thus simplifying
2333          the linker.  */
2334       return \"seth r14,%T0\;add3 r14,r14,%B0\;jl r14\";
2335     }
2336   else
2337     return \"bl %0\";
2339   [(set_attr "type" "call")
2340    (set (attr "length")
2341         (if_then_else (eq (symbol_ref "call26_operand (operands[0], FUNCTION_MODE)")
2342                           (const_int 0))
2343                       (const_int 12) ; 10 + 2 for nop filler
2344                       ; The return address must be on a 4 byte boundary so
2345                       ; there's no point in using a value of 2 here.  A 2 byte
2346                       ; insn may go in the left slot but we currently can't
2347                       ; use such knowledge.
2348                       (const_int 4)))])
2350 (define_expand "call_value"
2351   ;; operand 2 is stack_size_rtx
2352   ;; operand 3 is next_arg_register
2353   [(parallel [(set (match_operand 0 "register_operand" "=r")
2354                    (call (match_operand:SI 1 "call_operand" "")
2355                          (match_operand 2 "" "")))
2356              (clobber (reg:SI 14))])]
2357   ""
2358   "                                                                             
2360   if (flag_pic)
2361     current_function_uses_pic_offset_table = 1;
2364 (define_insn "*call_value_via_reg"
2365   [(set (match_operand 0 "register_operand" "=r")
2366         (call (mem:SI (match_operand:SI 1 "register_operand" "r"))
2367               (match_operand 2 "" "")))
2368    (clobber (reg:SI 14))]
2369   ""
2370   "jl %1"
2371   [(set_attr "type" "call")
2372    (set_attr "length" "2")])
2374 (define_insn "*call_value_via_label"
2375   [(set (match_operand 0 "register_operand" "=r")
2376         (call (mem:SI (match_operand:SI 1 "call_address_operand" ""))
2377               (match_operand 2 "" "")))
2378    (clobber (reg:SI 14))]
2379   ""
2380   "*
2382   int call26_p = call26_operand (operands[1], FUNCTION_MODE);
2384   if (flag_pic)
2385     current_function_uses_pic_offset_table = 1;
2387   if (! call26_p)
2388     {
2389       /* We may not be able to reach with a `bl' insn so punt and leave it to
2390          the linker.
2391          We do this here, rather than doing a force_reg in the define_expand
2392          so these insns won't be separated, say by scheduling, thus simplifying
2393          the linker.  */
2394       return \"seth r14,%T1\;add3 r14,r14,%B1\;jl r14\";
2395     }
2396   else
2397     return \"bl %1\";
2399   [(set_attr "type" "call")
2400    (set (attr "length")
2401         (if_then_else (eq (symbol_ref "call26_operand (operands[1], FUNCTION_MODE)")
2402                           (const_int 0))
2403                       (const_int 12) ; 10 + 2 for nop filler
2404                       ; The return address must be on a 4 byte boundary so
2405                       ; there's no point in using a value of 2 here.  A 2 byte
2406                       ; insn may go in the left slot but we currently can't
2407                       ; use such knowledge.
2408                       (const_int 4)))])
2410 (define_insn "nop"
2411   [(const_int 0)]
2412   ""
2413   "nop"
2414   [(set_attr "type" "int2")
2415    (set_attr "length" "2")])
2417 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
2418 ;; all of memory.  This blocks insns from being moved across this point.
2420 (define_insn "blockage"
2421   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
2422   ""
2423   "")
2425 ;; Special pattern to flush the icache.
2427 (define_insn "flush_icache"
2428   [(unspec_volatile [(match_operand 0 "memory_operand" "m")]
2429                     UNSPECV_FLUSH_ICACHE)
2430    (match_operand 1 "" "")
2431    (clobber (reg:SI 17))]
2432   ""
2433   "* return \"trap %#%1 ; flush-icache\";"
2434   [(set_attr "type" "int4")
2435    (set_attr "length" "4")])
2437 ;; Speed up fabs and provide correct sign handling for -0
2439 (define_insn "absdf2"
2440   [(set (match_operand:DF 0 "register_operand" "=r")
2441         (abs:DF (match_operand:DF 1 "register_operand" "0")))]
2442   ""
2443   "#"
2444   [(set_attr "type" "multi")
2445    (set_attr "length" "4")])
2447 (define_split
2448   [(set (match_operand:DF 0 "register_operand" "")
2449         (abs:DF (match_operand:DF 1 "register_operand" "")))]
2450   "reload_completed"
2451   [(set (match_dup 2)
2452         (ashift:SI (match_dup 2)
2453                    (const_int 1)))
2454    (set (match_dup 2)
2455         (lshiftrt:SI (match_dup 2)
2456                      (const_int 1)))]
2457   "operands[2] = gen_highpart (SImode, operands[0]);")
2459 (define_insn "abssf2"
2460   [(set (match_operand:SF 0 "register_operand" "=r")
2461         (abs:SF (match_operand:SF 1 "register_operand" "0")))]
2462   ""
2463   "#"
2464   [(set_attr "type" "multi")
2465    (set_attr "length" "4")])
2467 (define_split
2468   [(set (match_operand:SF 0 "register_operand" "")
2469         (abs:SF (match_operand:SF 1 "register_operand" "")))]
2470   "reload_completed"
2471   [(set (match_dup 2)
2472         (ashift:SI (match_dup 2)
2473                    (const_int 1)))
2474    (set (match_dup 2)
2475         (lshiftrt:SI (match_dup 2)
2476                      (const_int 1)))]
2477   "operands[2] = gen_highpart (SImode, operands[0]);")
2479 ;; Conditional move instructions
2480 ;; Based on those done for the d10v
2482 (define_expand "movsicc"
2483   [
2484    (set (match_operand:SI 0 "register_operand" "r")
2485         (if_then_else:SI (match_operand 1 "" "")
2486                          (match_operand:SI 2 "conditional_move_operand" "O")
2487                          (match_operand:SI 3 "conditional_move_operand" "O")
2488         )
2489    )
2490   ]
2491   ""
2492   "
2494   if (! zero_and_one (operands [2], operands [3]))
2495     FAIL;
2497   /* Generate the comparison that will set the carry flag.  */
2498   operands[1] = gen_compare (GET_CODE (operands[1]), m32r_compare_op0,
2499                              m32r_compare_op1, TRUE);
2501   /* See other movsicc pattern below for reason why.  */
2502   emit_insn (gen_blockage ());
2505 ;; Generate the conditional instructions based on how the carry flag is examined.
2506 (define_insn "*movsicc_internal"
2507   [(set (match_operand:SI 0 "register_operand" "=r")
2508         (if_then_else:SI (match_operand 1 "carry_compare_operand" "")
2509                          (match_operand:SI 2 "conditional_move_operand" "O")
2510                          (match_operand:SI 3 "conditional_move_operand" "O")
2511         )
2512    )]
2513   "zero_and_one (operands [2], operands[3])"
2514   "* return emit_cond_move (operands, insn);"
2515   [(set_attr "type" "multi")
2516    (set_attr "length" "8")
2517   ]
2521 ;; Block moves, see m32r.c for more details.
2522 ;; Argument 0 is the destination
2523 ;; Argument 1 is the source
2524 ;; Argument 2 is the length
2525 ;; Argument 3 is the alignment
2527 (define_expand "movmemsi"
2528   [(parallel [(set (match_operand:BLK 0 "general_operand" "")
2529                    (match_operand:BLK 1 "general_operand" ""))
2530               (use (match_operand:SI  2 "immediate_operand" ""))
2531               (use (match_operand:SI  3 "immediate_operand" ""))])]
2532   ""
2533   "
2535   if (operands[0])              /* avoid unused code messages */
2536     {
2537       m32r_expand_block_move (operands);
2538       DONE;
2539     }
2542 ;; Insn generated by block moves
2544 (define_insn "movmemsi_internal"
2545   [(set (mem:BLK (match_operand:SI 0 "register_operand" "r"))   ;; destination
2546         (mem:BLK (match_operand:SI 1 "register_operand" "r")))  ;; source
2547    (use (match_operand:SI 2 "m32r_block_immediate_operand" "J"));; # bytes to move
2548    (set (match_operand:SI 3 "register_operand" "=0")
2549         (plus:SI (match_dup 0)
2550                  (minus (match_dup 2) (const_int 4))))
2551    (set (match_operand:SI 4 "register_operand" "=1")
2552         (plus:SI (match_dup 1)
2553                  (match_dup 2)))
2554    (clobber (match_scratch:SI 5 "=&r"))  ;; temp1
2555    (clobber (match_scratch:SI 6 "=&r"))] ;; temp2
2556   ""
2557   "* m32r_output_block_move (insn, operands); return \"\"; "
2558   [(set_attr "type"     "store8")
2559    (set_attr "length"   "72")]) ;; Maximum
2561 ;; PIC
2563 /* When generating pic, we need to load the symbol offset into a register.
2564    So that the optimizer does not confuse this with a normal symbol load
2565    we use an unspec.  The offset will be loaded from a constant pool entry,
2566    since that is the only type of relocation we can use.  */
2568 (define_insn "pic_load_addr"
2569   [(set (match_operand:SI 0 "register_operand" "=r")
2570         (unspec:SI [(match_operand 1 "" "")] UNSPEC_PIC_LOAD_ADDR))]
2571   "flag_pic"
2572   "ld24 %0,%#%1"
2573   [(set_attr "type" "int4")])
2575 (define_insn "gotoff_load_addr"
2576   [(set (match_operand:SI 0 "register_operand" "=r")
2577         (unspec:SI [(match_operand 1 "" "")] UNSPEC_GOTOFF))]
2578   "flag_pic"
2579   "seth %0, %#shigh(%1@GOTOFF)\;add3 %0, %0, low(%1@GOTOFF)"
2580   [(set_attr "type"     "int4")
2581    (set_attr "length"   "8")])
2583 ;; Load program counter insns.
2585 (define_insn "get_pc"
2586   [(clobber (reg:SI 14))
2587    (set (match_operand 0 "register_operand" "=r")
2588         (unspec [(match_operand 1 "" "")] UNSPEC_GET_PC))
2589    (use (match_operand:SI 2 "immediate_operand" ""))]
2590   "flag_pic"
2591   "*
2593   if (INTVAL(operands[2]))
2594     return \"bl.s .+4\;ld24 %0,%#%1\;add %0,lr\";
2595   else
2596     return \"bl.s .+4\;seth %0,%#shigh(%1)\;add3 %0,%0,%#low(%1+4)\;add %0,lr\";}"
2597   [(set (attr "length") (if_then_else (ne (match_dup 2) (const_int 0))
2598                                       (const_int 8)
2599                                       (const_int 12)))])
2601 (define_expand "builtin_setjmp_receiver"
2602   [(label_ref (match_operand 0 "" ""))]
2603   "flag_pic"
2604   "
2606   m32r_load_pic_register ();
2607   DONE;