xref: /netbsd-src/external/gpl3/gcc.old/dist/gcc/config/m32r/m32r.md (revision b7b7574d3bf8eeb51a1fa3977b59142ec6434a55)
1;; Machine description of the Renesas M32R cpu for GNU C compiler
2;; Copyright (C) 1996, 1997, 1998, 1999, 2001, 2003, 2004, 2005,
3;  2007, 2008, 2009 Free Software Foundation, Inc.
4
5;; This file is part of GCC.
6
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 3, or (at your
10;; option) any later version.
11
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.
16
17;; You should have received a copy of the GNU General Public License
18;; along with GCC; see the file COPYING3.  If not see
19;; <http://www.gnu.org/licenses/>.
20
21;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
22
23;; UNSPEC_VOLATILE usage
24(define_constants
25  [(UNSPECV_BLOCKAGE		0)
26   (UNSPECV_FLUSH_ICACHE	1)])
27
28;; UNSPEC usage
29(define_constants
30  [(UNSPEC_LOAD_SDA_BASE	2)
31   (UNSPEC_SET_CBIT		3)
32   (UNSPEC_PIC_LOAD_ADDR	4)
33   (UNSPEC_GET_PC		5)
34   (UNSPEC_GOTOFF		6)
35   ])
36
37;; Insn type.  Used to default other attribute values.
38(define_attr "type"
39  "int2,int4,load2,load4,load8,store2,store4,store8,shift2,shift4,mul2,div4,uncond_branch,branch,call,multi,misc"
40  (const_string "misc"))
41
42;; Length in bytes.
43(define_attr "length" ""
44  (cond [(eq_attr "type" "int2,load2,store2,shift2,mul2")
45	 (const_int 2)
46
47	 (eq_attr "type" "int4,load4,store4,shift4,div4")
48	 (const_int 4)
49
50	 (eq_attr "type" "multi")
51	 (const_int 8)
52
53	 (eq_attr "type" "uncond_branch,branch,call")
54	 (const_int 4)]
55
56	 (const_int 4)))
57
58;; The length here is the length of a single asm.  Unfortunately it might be
59;; 2 or 4 so we must allow for 4.  That's ok though.
60(define_asm_attributes
61  [(set_attr "length" "4")
62   (set_attr "type" "multi")])
63
64;; Whether an instruction is short (16-bit) or long (32-bit).
65(define_attr "insn_size" "short,long"
66  (if_then_else (eq_attr "type" "int2,load2,store2,shift2,mul2")
67		(const_string "short")
68		(const_string "long")))
69
70;; The target CPU we're compiling for.
71(define_attr "cpu" "m32r,m32r2,m32rx"
72  (cond [(ne (symbol_ref "TARGET_M32RX") (const_int 0))
73	     (const_string "m32rx")
74	 (ne (symbol_ref "TARGET_M32R2") (const_int 0))
75	     (const_string "m32r2")]
76    (const_string "m32r")))
77
78;; Defines the pipeline where an instruction can be executed on.
79;; For the M32R, a short instruction can execute one of the two pipes.
80;; For the M32Rx, the restrictions are modelled in the second
81;;  condition of this attribute definition.
82(define_attr "m32r_pipeline" "either,s,o,long"
83  (cond [(and (eq_attr "cpu" "m32r")
84	      (eq_attr "insn_size" "short"))
85	     (const_string "either")
86         (eq_attr "insn_size" "!short")
87	     (const_string "long")]
88	 (cond [(eq_attr "type" "int2")
89		   (const_string "either")
90	        (eq_attr "type" "load2,store2,shift2,uncond_branch,branch,call")
91		   (const_string "o")
92	        (eq_attr "type" "mul2")
93		   (const_string "s")]
94	 (const_string "long"))))
95
96;; ::::::::::::::::::::
97;; ::
98;; :: Pipeline description
99;; ::
100;; ::::::::::::::::::::
101
102;; This model is based on Chapter 2, Appendix 3 and Appendix 4 of the
103;; "M32R-FPU Software Manual", Revision 1.01, plus additional information
104;; obtained by our best friend and mine, Google.
105;;
106;; The pipeline is modelled as a fetch unit, and a core with a memory unit,
107;; two execution units, where "fetch" models IF and D, "memory" for MEM1
108;; and MEM2, and "EXEC" for E, E1, E2, EM, and EA.  Writeback and
109;; bypasses are not modelled.
110(define_automaton "m32r")
111
112;; We pretend there are two short (16 bits) instruction fetchers.  The
113;; "s" short fetcher cannot be reserved until the "o" short fetcher is
114;; reserved.  Some instructions reserve both the left and right fetchers.
115;; These fetch units are a hack to get GCC to better pack the instructions
116;; for the M32Rx processor, which has two execution pipes.
117;;
118;; In reality there is only one decoder, which can decode either two 16-bit
119;; instructions, or a single 32-bit instruction.
120;;
121;; Note, "fetch" models both the IF and the D pipeline stages.
122;;
123;; The m32rx core has two execution pipes.  We name them o_E and s_E.
124;; In addition, there's a memory unit.
125
126(define_cpu_unit "o_IF,s_IF,o_E,s_E,memory" "m32r")
127
128;; Prevent the s pipe from being reserved before the o pipe.
129(absence_set "s_IF" "o_IF")
130(absence_set "s_E"  "o_E")
131
132;; On the M32Rx, long instructions execute on both pipes, so reserve
133;; both fetch slots and both pipes.
134(define_reservation "long_IF" "o_IF+s_IF")
135(define_reservation "long_E" "o_E+s_E")
136
137;; ::::::::::::::::::::
138
139;; Simple instructions do 4 stages: IF D E WB.  WB is not modelled.
140;; Hence, ready latency is 1.
141(define_insn_reservation "short_left" 1
142  (and (eq_attr "m32r_pipeline" "o")
143       (and (eq_attr "insn_size" "short")
144	    (eq_attr "type" "!load2")))
145  "o_IF,o_E")
146
147(define_insn_reservation "short_right" 1
148  (and (eq_attr "m32r_pipeline" "s")
149       (and (eq_attr "insn_size" "short")
150	    (eq_attr "type" "!load2")))
151  "s_IF,s_E")
152
153(define_insn_reservation "short_either" 1
154  (and (eq_attr "m32r_pipeline" "either")
155       (and (eq_attr "insn_size" "short")
156	    (eq_attr "type" "!load2")))
157  "o_IF|s_IF,o_E|s_E")
158
159(define_insn_reservation "long_m32r" 1
160  (and (eq_attr "cpu" "m32r")
161       (and (eq_attr "insn_size" "long")
162	    (eq_attr "type" "!load4,load8")))
163  "long_IF,long_E")
164
165(define_insn_reservation "long_m32rx" 2
166  (and (eq_attr "m32r_pipeline" "long")
167       (and (eq_attr "insn_size" "long")
168	    (eq_attr "type" "!load4,load8")))
169  "long_IF,long_E")
170
171;; Load/store instructions do 6 stages: IF D E MEM1 MEM2 WB.
172;; MEM1 may require more than one cycle depending on locality.  We
173;; optimistically assume all memory is nearby, i.e. MEM1 takes only
174;; one cycle.  Hence, ready latency is 3.
175
176;; The M32Rx can do short load/store only on the left pipe.
177(define_insn_reservation "short_load_left" 3
178  (and (eq_attr "m32r_pipeline" "o")
179       (and (eq_attr "insn_size" "short")
180	    (eq_attr "type" "load2")))
181  "o_IF,o_E,memory*2")
182
183(define_insn_reservation "short_load" 3
184  (and (eq_attr "m32r_pipeline" "either")
185       (and (eq_attr "insn_size" "short")
186	    (eq_attr "type" "load2")))
187  "s_IF|o_IF,s_E|o_E,memory*2")
188
189(define_insn_reservation "long_load" 3
190  (and (eq_attr "cpu" "m32r")
191       (and (eq_attr "insn_size" "long")
192	    (eq_attr "type" "load4,load8")))
193  "long_IF,long_E,memory*2")
194
195(define_insn_reservation "long_load_m32rx" 3
196  (and (eq_attr "m32r_pipeline" "long")
197       (eq_attr "type" "load4,load8"))
198  "long_IF,long_E,memory*2")
199
200
201(include "predicates.md")
202(include "constraints.md")
203
204;; Expand prologue as RTL
205(define_expand "prologue"
206  [(const_int 1)]
207  ""
208  "
209{
210  m32r_expand_prologue ();
211  DONE;
212}")
213
214;; Expand epilogue as RTL
215(define_expand "epilogue"
216  [(return)]
217  ""
218  "
219{
220  m32r_expand_epilogue ();
221  emit_jump_insn (gen_return_normal ());
222  DONE;
223}")
224
225;; Move instructions.
226;;
227;; For QI and HI moves, the register must contain the full properly
228;; sign-extended value.  nonzero_bits assumes this [otherwise
229;; SHORT_IMMEDIATES_SIGN_EXTEND must be used, but the comment for it
230;; says it's a kludge and the .md files should be fixed instead].
231
232(define_expand "movqi"
233  [(set (match_operand:QI 0 "general_operand" "")
234	(match_operand:QI 1 "general_operand" ""))]
235  ""
236  "
237{
238  /* Fixup PIC cases.  */
239  if (flag_pic)
240    {
241      if (symbolic_operand (operands[1], QImode))
242        {
243          if (reload_in_progress || reload_completed)
244            operands[1] = m32r_legitimize_pic_address (operands[1], operands[0]);
245          else
246            operands[1] = m32r_legitimize_pic_address (operands[1], NULL_RTX);
247        }
248    }
249
250  /* Everything except mem = const or mem = mem can be done easily.
251     Objects in the small data area are handled too.  */
252
253  if (MEM_P (operands[0]))
254    operands[1] = force_reg (QImode, operands[1]);
255}")
256
257(define_insn "*movqi_insn"
258  [(set (match_operand:QI 0 "move_dest_operand" "=r,r,r,r,r,T,m")
259	(match_operand:QI 1 "move_src_operand" "r,I,JQR,T,m,r,r"))]
260  "register_operand (operands[0], QImode) || register_operand (operands[1], QImode)"
261  "@
262   mv %0,%1
263   ldi %0,%#%1
264   ldi %0,%#%1
265   ldub %0,%1
266   ldub %0,%1
267   stb %1,%0
268   stb %1,%0"
269  [(set_attr "type" "int2,int2,int4,load2,load4,store2,store4")
270   (set_attr "length" "2,2,4,2,4,2,4")])
271
272(define_expand "movhi"
273  [(set (match_operand:HI 0 "general_operand" "")
274	(match_operand:HI 1 "general_operand" ""))]
275  ""
276  "
277{
278  /* Fixup PIC cases.  */
279  if (flag_pic)
280    {
281      if (symbolic_operand (operands[1], HImode))
282        {
283          if (reload_in_progress || reload_completed)
284            operands[1] = m32r_legitimize_pic_address (operands[1], operands[0]);
285          else
286            operands[1] = m32r_legitimize_pic_address (operands[1], NULL_RTX);
287        }
288    }
289
290  /* Everything except mem = const or mem = mem can be done easily.  */
291
292  if (MEM_P (operands[0]))
293    operands[1] = force_reg (HImode, operands[1]);
294}")
295
296(define_insn "*movhi_insn"
297  [(set (match_operand:HI 0 "move_dest_operand" "=r,r,r,r,r,r,T,m")
298	(match_operand:HI 1 "move_src_operand" "r,I,JQR,K,T,m,r,r"))]
299  "register_operand (operands[0], HImode) || register_operand (operands[1], HImode)"
300  "@
301   mv %0,%1
302   ldi %0,%#%1
303   ldi %0,%#%1
304   ld24 %0,%#%1
305   lduh %0,%1
306   lduh %0,%1
307   sth %1,%0
308   sth %1,%0"
309  [(set_attr "type" "int2,int2,int4,int4,load2,load4,store2,store4")
310   (set_attr "length" "2,2,4,4,2,4,2,4")])
311
312(define_expand "movsi_push"
313  [(set (mem:SI (pre_dec:SI (match_operand:SI 0 "register_operand" "")))
314	(match_operand:SI 1 "register_operand" ""))]
315  ""
316  "")
317
318(define_expand "movsi_pop"
319  [(set (match_operand:SI 0 "register_operand" "")
320	(mem:SI (post_inc:SI (match_operand:SI 1 "register_operand" ""))))]
321  ""
322  "")
323
324(define_expand "movsi"
325  [(set (match_operand:SI 0 "general_operand" "")
326	(match_operand:SI 1 "general_operand" ""))]
327  ""
328  "
329{
330  /* Fixup PIC cases.  */
331  if (flag_pic)
332    {
333      if (symbolic_operand (operands[1], SImode))
334        {
335          if (reload_in_progress || reload_completed)
336            operands[1] = m32r_legitimize_pic_address (operands[1], operands[0]);
337          else
338            operands[1] = m32r_legitimize_pic_address (operands[1], NULL_RTX);
339        }
340    }
341
342  /* Everything except mem = const or mem = mem can be done easily.  */
343
344  if (MEM_P (operands[0]))
345    operands[1] = force_reg (SImode, operands[1]);
346
347  /* Small Data Area reference?  */
348  if (small_data_operand (operands[1], SImode))
349    {
350      emit_insn (gen_movsi_sda (operands[0], operands[1]));
351      DONE;
352    }
353
354  /* If medium or large code model, symbols have to be loaded with
355     seth/add3.  */
356  if (addr32_operand (operands[1], SImode))
357    {
358      emit_insn (gen_movsi_addr32 (operands[0], operands[1]));
359      DONE;
360    }
361}")
362
363;; ??? Do we need a const_double constraint here for large unsigned values?
364(define_insn "*movsi_insn"
365  [(set (match_operand:SI 0 "move_dest_operand" "=r,r,r,r,r,r,r,r,r,T,S,m")
366	(match_operand:SI 1 "move_src_operand" "r,I,J,MQ,L,n,T,U,m,r,r,r"))]
367  "register_operand (operands[0], SImode) || register_operand (operands[1], SImode)"
368  "*
369{
370  if (REG_P (operands[0]) || GET_CODE (operands[1]) == SUBREG)
371    {
372      switch (GET_CODE (operands[1]))
373	{
374	  default:
375	    break;
376
377	  case REG:
378	  case SUBREG:
379	    return \"mv %0,%1\";
380
381	  case MEM:
382	    if (GET_CODE (XEXP (operands[1], 0)) == POST_INC
383		&& XEXP (XEXP (operands[1], 0), 0) == stack_pointer_rtx)
384	      return \"pop %0\";
385
386	    return \"ld %0,%1\";
387
388	  case CONST_INT:
389	    if (satisfies_constraint_J (operands[1]))
390	      return \"ldi %0,%#%1\\t; %X1\";
391
392	    if (satisfies_constraint_M (operands[1]))
393	      return \"ld24 %0,%#%1\\t; %X1\";
394
395	    if (satisfies_constraint_L (operands[1]))
396	      return \"seth %0,%#%T1\\t; %X1\";
397
398	    return \"#\";
399
400	  case CONST:
401	  case SYMBOL_REF:
402	  case LABEL_REF:
403	    if (TARGET_ADDR24)
404	      return \"ld24 %0,%#%1\";
405
406	    return \"#\";
407	}
408    }
409
410  else if (MEM_P (operands[0])
411	   && (REG_P (operands[1]) || GET_CODE (operands[1]) == SUBREG))
412    {
413      if (GET_CODE (XEXP (operands[0], 0)) == PRE_DEC
414	  && XEXP (XEXP (operands[0], 0), 0) == stack_pointer_rtx)
415	return \"push %1\";
416
417      return \"st %1,%0\";
418    }
419
420  gcc_unreachable ();
421}"
422  [(set_attr "type" "int2,int2,int4,int4,int4,multi,load2,load2,load4,store2,store2,store4")
423   (set_attr "length" "2,2,4,4,4,8,2,2,4,2,2,4")])
424
425; Try to use a four byte / two byte pair for constants not loadable with
426; ldi, ld24, seth.
427
428(define_split
429 [(set (match_operand:SI 0 "register_operand" "")
430       (match_operand:SI 1 "two_insn_const_operand" ""))]
431  ""
432  [(set (match_dup 0) (match_dup 2))
433   (set (match_dup 0) (ior:SI (match_dup 0) (match_dup 3)))]
434  "
435{
436  unsigned HOST_WIDE_INT val = INTVAL (operands[1]);
437  unsigned HOST_WIDE_INT tmp;
438  int shift;
439
440  /* In all cases we will emit two instructions.  However we try to
441     use 2 byte instructions wherever possible.  We can assume the
442     constant isn't loadable with any of ldi, ld24, or seth.  */
443
444  /* See if we can load a 24-bit unsigned value and invert it.  */
445  if (UINT24_P (~ val))
446    {
447      emit_insn (gen_movsi (operands[0], GEN_INT (~ val)));
448      emit_insn (gen_one_cmplsi2 (operands[0], operands[0]));
449      DONE;
450    }
451
452  /* See if we can load a 24-bit unsigned value and shift it into place.
453     0x01fffffe is just beyond ld24's range.  */
454  for (shift = 1, tmp = 0x01fffffe;
455       shift < 8;
456       ++shift, tmp <<= 1)
457    {
458      if ((val & ~tmp) == 0)
459	{
460	  emit_insn (gen_movsi (operands[0], GEN_INT (val >> shift)));
461	  emit_insn (gen_ashlsi3 (operands[0], operands[0], GEN_INT (shift)));
462	  DONE;
463	}
464    }
465
466  /* Can't use any two byte insn, fall back to seth/or3.  Use ~0xffff instead
467     of 0xffff0000, since the later fails on a 64-bit host.  */
468  operands[2] = GEN_INT ((val) & ~0xffff);
469  operands[3] = GEN_INT ((val) & 0xffff);
470}")
471
472(define_split
473  [(set (match_operand:SI 0 "register_operand" "")
474	(match_operand:SI 1 "seth_add3_operand" ""))]
475  "TARGET_ADDR32"
476  [(set (match_dup 0)
477	(high:SI (match_dup 1)))
478   (set (match_dup 0)
479	(lo_sum:SI (match_dup 0)
480		   (match_dup 1)))]
481  "")
482
483;; Small data area support.
484;; The address of _SDA_BASE_ is loaded into a register and all objects in
485;; the small data area are indexed off that.  This is done for each reference
486;; but cse will clean things up for us.  We let the compiler choose the
487;; register to use so we needn't allocate (and maybe even fix) a special
488;; register to use.  Since the load and store insns have a 16-bit offset the
489;; total size of the data area can be 64K.  However, if the data area lives
490;; above 16M (24 bits), _SDA_BASE_ will have to be loaded with seth/add3 which
491;; would then yield 3 instructions to reference an object [though there would
492;; be no net loss if two or more objects were referenced].  The 3 insns can be
493;; reduced back to 2 if the size of the small data area were reduced to 32K
494;; [then seth + ld/st would work for any object in the area].  Doing this
495;; would require special handling of _SDA_BASE_ (its value would be
496;; (.sdata + 32K) & 0xffff0000) and reloc computations would be different
497;; [I think].  What to do about this is deferred until later and for now we
498;; require .sdata to be in the first 16M.
499
500(define_expand "movsi_sda"
501  [(set (match_dup 2)
502	(unspec:SI [(const_int 0)] UNSPEC_LOAD_SDA_BASE))
503   (set (match_operand:SI 0 "register_operand" "")
504	(lo_sum:SI (match_dup 2)
505		   (match_operand:SI 1 "small_data_operand" "")))]
506  ""
507  "
508{
509  if (reload_in_progress || reload_completed)
510    operands[2] = operands[0];
511  else
512    operands[2] = gen_reg_rtx (SImode);
513}")
514
515(define_insn "*load_sda_base_32"
516  [(set (match_operand:SI 0 "register_operand" "=r")
517	(unspec:SI [(const_int 0)] UNSPEC_LOAD_SDA_BASE))]
518  "TARGET_ADDR32"
519  "seth %0,%#shigh(_SDA_BASE_)\;add3 %0,%0,%#low(_SDA_BASE_)"
520  [(set_attr "type" "multi")
521   (set_attr "length" "8")])
522
523(define_insn "*load_sda_base"
524  [(set (match_operand:SI 0 "register_operand" "=r")
525	(unspec:SI [(const_int 0)] UNSPEC_LOAD_SDA_BASE))]
526  ""
527  "ld24 %0,#_SDA_BASE_"
528  [(set_attr "type" "int4")
529   (set_attr "length" "4")])
530
531;; 32-bit address support.
532
533(define_expand "movsi_addr32"
534  [(set (match_dup 2)
535	; addr32_operand isn't used because it's too restrictive,
536	; seth_add3_operand is more general and thus safer.
537	(high:SI (match_operand:SI 1 "seth_add3_operand" "")))
538   (set (match_operand:SI 0 "register_operand" "")
539	(lo_sum:SI (match_dup 2) (match_dup 1)))]
540  ""
541  "
542{
543  if (reload_in_progress || reload_completed)
544    operands[2] = operands[0];
545  else
546    operands[2] = gen_reg_rtx (SImode);
547}")
548
549(define_insn "set_hi_si"
550  [(set (match_operand:SI 0 "register_operand" "=r")
551	(high:SI (match_operand 1 "symbolic_operand" "")))]
552  ""
553  "seth %0,%#shigh(%1)"
554  [(set_attr "type" "int4")
555   (set_attr "length" "4")])
556
557(define_insn "lo_sum_si"
558  [(set (match_operand:SI 0 "register_operand" "=r")
559	(lo_sum:SI (match_operand:SI 1 "register_operand" "r")
560		   (match_operand:SI 2 "immediate_operand" "in")))]
561  ""
562  "add3 %0,%1,%#%B2"
563  [(set_attr "type" "int4")
564   (set_attr "length" "4")])
565
566(define_expand "movdi"
567  [(set (match_operand:DI 0 "general_operand" "")
568	(match_operand:DI 1 "general_operand" ""))]
569  ""
570  "
571{
572  /* Fixup PIC cases.  */
573  if (flag_pic)
574    {
575      if (symbolic_operand (operands[1], DImode))
576        {
577          if (reload_in_progress || reload_completed)
578            operands[1] = m32r_legitimize_pic_address (operands[1], operands[0]);
579          else
580            operands[1] = m32r_legitimize_pic_address (operands[1], NULL_RTX);
581        }
582    }
583
584  /* Everything except mem = const or mem = mem can be done easily.  */
585
586  if (MEM_P (operands[0]))
587    operands[1] = force_reg (DImode, operands[1]);
588}")
589
590(define_insn "*movdi_insn"
591  [(set (match_operand:DI 0 "move_dest_operand" "=r,r,r,r,m")
592	(match_operand:DI 1 "move_double_src_operand" "r,nG,F,m,r"))]
593  "register_operand (operands[0], DImode) || register_operand (operands[1], DImode)"
594  "#"
595  [(set_attr "type" "multi,multi,multi,load8,store8")
596   (set_attr "length" "4,4,16,6,6")])
597
598(define_split
599  [(set (match_operand:DI 0 "move_dest_operand" "")
600	(match_operand:DI 1 "move_double_src_operand" ""))]
601  "reload_completed"
602  [(match_dup 2)]
603  "operands[2] = gen_split_move_double (operands);")
604
605;; Floating point move insns.
606
607(define_expand "movsf"
608  [(set (match_operand:SF 0 "general_operand" "")
609	(match_operand:SF 1 "general_operand" ""))]
610  ""
611  "
612{
613  /* Fixup PIC cases.  */
614  if (flag_pic)
615    {
616      if (symbolic_operand (operands[1], SFmode))
617        {
618          if (reload_in_progress || reload_completed)
619            operands[1] = m32r_legitimize_pic_address (operands[1], operands[0]);
620          else
621            operands[1] = m32r_legitimize_pic_address (operands[1], NULL_RTX);
622        }
623    }
624
625  /* Everything except mem = const or mem = mem can be done easily.  */
626
627  if (MEM_P (operands[0]))
628    operands[1] = force_reg (SFmode, operands[1]);
629}")
630
631(define_insn "*movsf_insn"
632  [(set (match_operand:SF 0 "move_dest_operand" "=r,r,r,r,r,T,S,m")
633	(match_operand:SF 1 "move_src_operand" "r,F,U,S,m,r,r,r"))]
634  "register_operand (operands[0], SFmode) || register_operand (operands[1], SFmode)"
635  "@
636   mv %0,%1
637   #
638   ld %0,%1
639   ld %0,%1
640   ld %0,%1
641   st %1,%0
642   st %1,%0
643   st %1,%0"
644  ;; ??? Length of alternative 1 is either 2, 4 or 8.
645  [(set_attr "type" "int2,multi,load2,load2,load4,store2,store2,store4")
646   (set_attr "length" "2,8,2,2,4,2,2,4")])
647
648(define_split
649  [(set (match_operand:SF 0 "register_operand" "")
650	(match_operand:SF 1 "const_double_operand" ""))]
651  "reload_completed"
652  [(set (match_dup 2) (match_dup 3))]
653  "
654{
655  operands[2] = operand_subword (operands[0], 0, 0, SFmode);
656  operands[3] = operand_subword (operands[1], 0, 0, SFmode);
657}")
658
659(define_expand "movdf"
660  [(set (match_operand:DF 0 "general_operand" "")
661	(match_operand:DF 1 "general_operand" ""))]
662  ""
663  "
664{
665  /* Fixup PIC cases.  */
666  if (flag_pic)
667    {
668      if (symbolic_operand (operands[1], DFmode))
669        {
670          if (reload_in_progress || reload_completed)
671            operands[1] = m32r_legitimize_pic_address (operands[1], operands[0]);
672          else
673            operands[1] = m32r_legitimize_pic_address (operands[1], NULL_RTX);
674        }
675    }
676
677  /* Everything except mem = const or mem = mem can be done easily.  */
678
679  if (MEM_P (operands[0]))
680    operands[1] = force_reg (DFmode, operands[1]);
681}")
682
683(define_insn "*movdf_insn"
684  [(set (match_operand:DF 0 "move_dest_operand" "=r,r,r,m")
685	(match_operand:DF 1 "move_double_src_operand" "r,F,m,r"))]
686  "register_operand (operands[0], DFmode) || register_operand (operands[1], DFmode)"
687  "#"
688  [(set_attr "type" "multi,multi,load8,store8")
689   (set_attr "length" "4,16,6,6")])
690
691(define_split
692  [(set (match_operand:DF 0 "move_dest_operand" "")
693	(match_operand:DF 1 "move_double_src_operand" ""))]
694  "reload_completed"
695  [(match_dup 2)]
696  "operands[2] = gen_split_move_double (operands);")
697
698;; Zero extension instructions.
699
700(define_insn "zero_extendqihi2"
701  [(set (match_operand:HI 0 "register_operand" "=r,r,r")
702	(zero_extend:HI (match_operand:QI 1 "extend_operand" "r,T,m")))]
703  ""
704  "@
705   and3 %0,%1,%#255
706   ldub %0,%1
707   ldub %0,%1"
708  [(set_attr "type" "int4,load2,load4")
709   (set_attr "length" "4,2,4")])
710
711(define_insn "zero_extendqisi2"
712  [(set (match_operand:SI 0 "register_operand" "=r,r,r")
713	(zero_extend:SI (match_operand:QI 1 "extend_operand" "r,T,m")))]
714  ""
715  "@
716   and3 %0,%1,%#255
717   ldub %0,%1
718   ldub %0,%1"
719  [(set_attr "type" "int4,load2,load4")
720   (set_attr "length" "4,2,4")])
721
722(define_insn "zero_extendhisi2"
723  [(set (match_operand:SI 0 "register_operand" "=r,r,r")
724	(zero_extend:SI (match_operand:HI 1 "extend_operand" "r,T,m")))]
725  ""
726  "@
727   and3 %0,%1,%#65535
728   lduh %0,%1
729   lduh %0,%1"
730  [(set_attr "type" "int4,load2,load4")
731   (set_attr "length" "4,2,4")])
732
733;; Signed conversions from a smaller integer to a larger integer
734(define_insn "extendqihi2"
735  [(set (match_operand:HI 0 "register_operand" "=r,r,r")
736	(sign_extend:HI (match_operand:QI 1 "extend_operand" "0,T,m")))]
737  ""
738  "@
739    #
740    ldb %0,%1
741    ldb %0,%1"
742  [(set_attr "type" "multi,load2,load4")
743   (set_attr "length" "2,2,4")])
744
745(define_split
746  [(set (match_operand:HI 0 "register_operand" "")
747	(sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
748  "reload_completed"
749  [(match_dup 2)
750   (match_dup 3)]
751  "
752{
753  rtx op0   = gen_lowpart (SImode, operands[0]);
754  rtx shift = GEN_INT (24);
755
756  operands[2] = gen_ashlsi3 (op0, op0, shift);
757  operands[3] = gen_ashrsi3 (op0, op0, shift);
758}")
759
760(define_insn "extendqisi2"
761  [(set (match_operand:SI 0 "register_operand" "=r,r,r")
762	(sign_extend:SI (match_operand:QI 1 "extend_operand" "0,T,m")))]
763  ""
764  "@
765    #
766    ldb %0,%1
767    ldb %0,%1"
768  [(set_attr "type" "multi,load2,load4")
769   (set_attr "length" "4,2,4")])
770
771(define_split
772  [(set (match_operand:SI 0 "register_operand" "")
773	(sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
774  "reload_completed"
775  [(match_dup 2)
776   (match_dup 3)]
777  "
778{
779  rtx shift = GEN_INT (24);
780
781  operands[2] = gen_ashlsi3 (operands[0], operands[0], shift);
782  operands[3] = gen_ashrsi3 (operands[0], operands[0], shift);
783}")
784
785(define_insn "extendhisi2"
786  [(set (match_operand:SI 0 "register_operand" "=r,r,r")
787	(sign_extend:SI (match_operand:HI 1 "extend_operand" "0,T,m")))]
788  ""
789  "@
790    #
791    ldh %0,%1
792    ldh %0,%1"
793  [(set_attr "type" "multi,load2,load4")
794   (set_attr "length" "4,2,4")])
795
796(define_split
797  [(set (match_operand:SI 0 "register_operand" "")
798	(sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
799  "reload_completed"
800  [(match_dup 2)
801   (match_dup 3)]
802  "
803{
804  rtx shift = GEN_INT (16);
805
806  operands[2] = gen_ashlsi3 (operands[0], operands[0], shift);
807  operands[3] = gen_ashrsi3 (operands[0], operands[0], shift);
808}")
809
810;; Arithmetic instructions.
811
812; ??? Adding an alternative to split add3 of small constants into two
813; insns yields better instruction packing but slower code.  Adds of small
814; values is done a lot.
815
816(define_insn "addsi3"
817  [(set (match_operand:SI 0 "register_operand" "=r,r,r")
818	(plus:SI (match_operand:SI 1 "register_operand" "%0,0,r")
819		 (match_operand:SI 2 "nonmemory_operand" "r,I,J")))]
820  ""
821  "@
822   add %0,%2
823   addi %0,%#%2
824   add3 %0,%1,%#%2"
825  [(set_attr "type" "int2,int2,int4")
826   (set_attr "length" "2,2,4")])
827
828;(define_split
829;  [(set (match_operand:SI 0 "register_operand" "")
830;	(plus:SI (match_operand:SI 1 "register_operand" "")
831;		 (match_operand:SI 2 "int8_operand" "")))]
832;  "reload_completed
833;   && REGNO (operands[0]) != REGNO (operands[1])
834;   && satisfies_constraint_I (operands[2])
835;   && INTVAL (operands[2]) != 0"
836;  [(set (match_dup 0) (match_dup 1))
837;   (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))]
838;  "")
839
840(define_insn "adddi3"
841  [(set (match_operand:DI 0 "register_operand" "=r")
842	(plus:DI (match_operand:DI 1 "register_operand" "%0")
843		 (match_operand:DI 2 "register_operand" "r")))
844   (clobber (reg:CC 17))]
845  ""
846  "#"
847  [(set_attr "type" "multi")
848   (set_attr "length" "6")])
849
850;; ??? The cmp clears the condition bit.  Can we speed up somehow?
851(define_split
852  [(set (match_operand:DI 0 "register_operand" "")
853	(plus:DI (match_operand:DI 1 "register_operand" "")
854		 (match_operand:DI 2 "register_operand" "")))
855   (clobber (reg:CC 17))]
856  "reload_completed"
857  [(parallel [(set (reg:CC 17)
858		   (const_int 0))
859	      (use (match_dup 4))])
860   (parallel [(set (match_dup 4)
861		   (plus:SI (match_dup 4)
862			    (plus:SI (match_dup 5)
863				     (ne:SI (reg:CC 17) (const_int 0)))))
864	      (set (reg:CC 17)
865		   (unspec:CC [(const_int 0)] UNSPEC_SET_CBIT))])
866   (parallel [(set (match_dup 6)
867		   (plus:SI (match_dup 6)
868			    (plus:SI (match_dup 7)
869				     (ne:SI (reg:CC 17) (const_int 0)))))
870	      (set (reg:CC 17)
871		   (unspec:CC [(const_int 0)] UNSPEC_SET_CBIT))])]
872  "
873{
874  operands[4] = operand_subword (operands[0], (WORDS_BIG_ENDIAN != 0), 0, DImode);
875  operands[5] = operand_subword (operands[2], (WORDS_BIG_ENDIAN != 0), 0, DImode);
876  operands[6] = operand_subword (operands[0], (WORDS_BIG_ENDIAN == 0), 0, DImode);
877  operands[7] = operand_subword (operands[2], (WORDS_BIG_ENDIAN == 0), 0, DImode);
878}")
879
880(define_insn "*clear_c"
881  [(set (reg:CC 17)
882	(const_int 0))
883   (use (match_operand:SI 0 "register_operand" "r"))]
884  ""
885  "cmp %0,%0"
886  [(set_attr "type" "int2")
887   (set_attr "length" "2")])
888
889(define_insn "*add_carry"
890  [(set (match_operand:SI 0 "register_operand" "=r")
891	(plus:SI (match_operand:SI 1 "register_operand" "%0")
892		 (plus:SI (match_operand:SI 2 "register_operand" "r")
893			  (ne:SI (reg:CC 17) (const_int 0)))))
894   (set (reg:CC 17)
895	(unspec:CC [(const_int 0)] UNSPEC_SET_CBIT))]
896  ""
897  "addx %0,%2"
898  [(set_attr "type" "int2")
899   (set_attr "length" "2")])
900
901(define_insn "subsi3"
902  [(set (match_operand:SI 0 "register_operand" "=r")
903	(minus:SI (match_operand:SI 1 "register_operand" "0")
904		  (match_operand:SI 2 "register_operand" "r")))]
905  ""
906  "sub %0,%2"
907  [(set_attr "type" "int2")
908   (set_attr "length" "2")])
909
910(define_insn "subdi3"
911  [(set (match_operand:DI 0 "register_operand" "=r")
912	(minus:DI (match_operand:DI 1 "register_operand" "0")
913		  (match_operand:DI 2 "register_operand" "r")))
914   (clobber (reg:CC 17))]
915  ""
916  "#"
917  [(set_attr "type" "multi")
918   (set_attr "length" "6")])
919
920;; ??? The cmp clears the condition bit.  Can we speed up somehow?
921(define_split
922  [(set (match_operand:DI 0 "register_operand" "")
923	(minus:DI (match_operand:DI 1 "register_operand" "")
924		  (match_operand:DI 2 "register_operand" "")))
925   (clobber (reg:CC 17))]
926  "reload_completed"
927  [(parallel [(set (reg:CC 17)
928		   (const_int 0))
929	      (use (match_dup 4))])
930   (parallel [(set (match_dup 4)
931		   (minus:SI (match_dup 4)
932			     (minus:SI (match_dup 5)
933				       (ne:SI (reg:CC 17) (const_int 0)))))
934	      (set (reg:CC 17)
935		   (unspec:CC [(const_int 0)] UNSPEC_SET_CBIT))])
936   (parallel [(set (match_dup 6)
937		   (minus:SI (match_dup 6)
938			     (minus:SI (match_dup 7)
939				       (ne:SI (reg:CC 17) (const_int 0)))))
940	      (set (reg:CC 17)
941		   (unspec:CC [(const_int 0)] UNSPEC_SET_CBIT))])]
942  "
943{
944  operands[4] = operand_subword (operands[0], (WORDS_BIG_ENDIAN != 0), 0, DImode);
945  operands[5] = operand_subword (operands[2], (WORDS_BIG_ENDIAN != 0), 0, DImode);
946  operands[6] = operand_subword (operands[0], (WORDS_BIG_ENDIAN == 0), 0, DImode);
947  operands[7] = operand_subword (operands[2], (WORDS_BIG_ENDIAN == 0), 0, DImode);
948}")
949
950(define_insn "*sub_carry"
951  [(set (match_operand:SI 0 "register_operand" "=r")
952	(minus:SI (match_operand:SI 1 "register_operand" "%0")
953		  (minus:SI (match_operand:SI 2 "register_operand" "r")
954			    (ne:SI (reg:CC 17) (const_int 0)))))
955   (set (reg:CC 17)
956	(unspec:CC [(const_int 0)] UNSPEC_SET_CBIT))]
957  ""
958  "subx %0,%2"
959  [(set_attr "type" "int2")
960   (set_attr "length" "2")])
961
962; Multiply/Divide instructions.
963
964(define_insn "mulhisi3"
965  [(set (match_operand:SI 0 "register_operand" "=r")
966	(mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" "r"))
967		 (sign_extend:SI (match_operand:HI 2 "register_operand" "r"))))]
968  ""
969  "mullo %1,%2\;mvfacmi %0"
970  [(set_attr "type" "multi")
971   (set_attr "length" "4")])
972
973(define_insn "mulsi3"
974  [(set (match_operand:SI 0 "register_operand" "=r")
975	(mult:SI (match_operand:SI 1 "register_operand" "%0")
976		 (match_operand:SI 2 "register_operand" "r")))]
977  ""
978  "mul %0,%2"
979  [(set_attr "type" "mul2")
980   (set_attr "length" "2")])
981
982(define_insn "divsi3"
983  [(set (match_operand:SI 0 "register_operand" "=r")
984	(div:SI (match_operand:SI 1 "register_operand" "0")
985		(match_operand:SI 2 "register_operand" "r")))]
986  ""
987  "div %0,%2"
988  [(set_attr "type" "div4")
989   (set_attr "length" "4")])
990
991(define_insn "udivsi3"
992  [(set (match_operand:SI 0 "register_operand" "=r")
993	(udiv:SI (match_operand:SI 1 "register_operand" "0")
994		 (match_operand:SI 2 "register_operand" "r")))]
995  ""
996  "divu %0,%2"
997  [(set_attr "type" "div4")
998   (set_attr "length" "4")])
999
1000(define_insn "modsi3"
1001  [(set (match_operand:SI 0 "register_operand" "=r")
1002	(mod:SI (match_operand:SI 1 "register_operand" "0")
1003		(match_operand:SI 2 "register_operand" "r")))]
1004  ""
1005  "rem %0,%2"
1006  [(set_attr "type" "div4")
1007   (set_attr "length" "4")])
1008
1009(define_insn "umodsi3"
1010  [(set (match_operand:SI 0 "register_operand" "=r")
1011	(umod:SI (match_operand:SI 1 "register_operand" "0")
1012		 (match_operand:SI 2 "register_operand" "r")))]
1013  ""
1014  "remu %0,%2"
1015  [(set_attr "type" "div4")
1016   (set_attr "length" "4")])
1017
1018;; Boolean instructions.
1019;;
1020;; We don't define the DImode versions as expand_binop does a good enough job.
1021;; And if it doesn't it should be fixed.
1022
1023(define_insn "andsi3"
1024  [(set (match_operand:SI 0 "register_operand" "=r,r")
1025	(and:SI (match_operand:SI 1 "register_operand" "%0,r")
1026		(match_operand:SI 2 "reg_or_uint16_operand" "r,K")))]
1027  ""
1028  "*
1029{
1030  /* If we are worried about space, see if we can break this up into two
1031     short instructions, which might eliminate a NOP being inserted.  */
1032  if (optimize_size
1033      && m32r_not_same_reg (operands[0], operands[1])
1034      && satisfies_constraint_I (operands[2]))
1035    return \"#\";
1036
1037  else if (CONST_INT_P (operands[2]))
1038    return \"and3 %0,%1,%#%X2\";
1039
1040  return \"and %0,%2\";
1041}"
1042  [(set_attr "type" "int2,int4")
1043   (set_attr "length" "2,4")])
1044
1045(define_split
1046  [(set (match_operand:SI 0 "register_operand" "")
1047	(and:SI (match_operand:SI 1 "register_operand" "")
1048		(match_operand:SI 2 "int8_operand" "")))]
1049  "optimize_size && m32r_not_same_reg (operands[0], operands[1])"
1050  [(set (match_dup 0) (match_dup 2))
1051   (set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))]
1052  "")
1053
1054(define_insn "iorsi3"
1055  [(set (match_operand:SI 0 "register_operand" "=r,r")
1056	(ior:SI (match_operand:SI 1 "register_operand" "%0,r")
1057		(match_operand:SI 2 "reg_or_uint16_operand" "r,K")))]
1058  ""
1059  "*
1060{
1061  /* If we are worried about space, see if we can break this up into two
1062     short instructions, which might eliminate a NOP being inserted.  */
1063  if (optimize_size
1064      && m32r_not_same_reg (operands[0], operands[1])
1065      && satisfies_constraint_I (operands[2]))
1066    return \"#\";
1067
1068  else if (CONST_INT_P (operands[2]))
1069    return \"or3 %0,%1,%#%X2\";
1070
1071  return \"or %0,%2\";
1072}"
1073  [(set_attr "type" "int2,int4")
1074   (set_attr "length" "2,4")])
1075
1076(define_split
1077  [(set (match_operand:SI 0 "register_operand" "")
1078	(ior:SI (match_operand:SI 1 "register_operand" "")
1079		(match_operand:SI 2 "int8_operand" "")))]
1080  "optimize_size && m32r_not_same_reg (operands[0], operands[1])"
1081  [(set (match_dup 0) (match_dup 2))
1082   (set (match_dup 0) (ior:SI (match_dup 0) (match_dup 1)))]
1083  "")
1084
1085(define_insn "xorsi3"
1086  [(set (match_operand:SI 0 "register_operand" "=r,r")
1087	(xor:SI (match_operand:SI 1 "register_operand" "%0,r")
1088		(match_operand:SI 2 "reg_or_uint16_operand" "r,K")))]
1089  ""
1090  "*
1091{
1092  /* If we are worried about space, see if we can break this up into two
1093     short instructions, which might eliminate a NOP being inserted.  */
1094  if (optimize_size
1095      && m32r_not_same_reg (operands[0], operands[1])
1096      && satisfies_constraint_I (operands[2]))
1097    return \"#\";
1098
1099  else if (CONST_INT_P (operands[2]))
1100    return \"xor3 %0,%1,%#%X2\";
1101
1102  return \"xor %0,%2\";
1103}"
1104  [(set_attr "type" "int2,int4")
1105   (set_attr "length" "2,4")])
1106
1107(define_split
1108  [(set (match_operand:SI 0 "register_operand" "")
1109	(xor:SI (match_operand:SI 1 "register_operand" "")
1110		(match_operand:SI 2 "int8_operand" "")))]
1111  "optimize_size && m32r_not_same_reg (operands[0], operands[1])"
1112  [(set (match_dup 0) (match_dup 2))
1113   (set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))]
1114  "")
1115
1116(define_insn "negsi2"
1117  [(set (match_operand:SI 0 "register_operand" "=r")
1118	(neg:SI (match_operand:SI 1 "register_operand" "r")))]
1119  ""
1120  "neg %0,%1"
1121  [(set_attr "type" "int2")
1122   (set_attr "length" "2")])
1123
1124(define_insn "one_cmplsi2"
1125  [(set (match_operand:SI 0 "register_operand" "=r")
1126	(not:SI (match_operand:SI 1 "register_operand" "r")))]
1127  ""
1128  "not %0,%1"
1129  [(set_attr "type" "int2")
1130   (set_attr "length" "2")])
1131
1132;; Shift instructions.
1133
1134(define_insn "ashlsi3"
1135  [(set (match_operand:SI 0 "register_operand" "=r,r,r")
1136	(ashift:SI (match_operand:SI 1 "register_operand" "0,0,r")
1137		   (match_operand:SI 2 "reg_or_uint16_operand" "r,O,K")))]
1138  ""
1139  "@
1140   sll %0,%2
1141   slli %0,%#%2
1142   sll3 %0,%1,%#%2"
1143  [(set_attr "type" "shift2,shift2,shift4")
1144   (set_attr "length" "2,2,4")])
1145
1146(define_insn "ashrsi3"
1147  [(set (match_operand:SI 0 "register_operand" "=r,r,r")
1148	(ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0,r")
1149		     (match_operand:SI 2 "reg_or_uint16_operand" "r,O,K")))]
1150  ""
1151  "@
1152   sra %0,%2
1153   srai %0,%#%2
1154   sra3 %0,%1,%#%2"
1155  [(set_attr "type" "shift2,shift2,shift4")
1156   (set_attr "length" "2,2,4")])
1157
1158(define_insn "lshrsi3"
1159  [(set (match_operand:SI 0 "register_operand" "=r,r,r")
1160	(lshiftrt:SI (match_operand:SI 1 "register_operand" "0,0,r")
1161		     (match_operand:SI 2 "reg_or_uint16_operand" "r,O,K")))]
1162  ""
1163  "@
1164   srl %0,%2
1165   srli %0,%#%2
1166   srl3 %0,%1,%#%2"
1167  [(set_attr "type" "shift2,shift2,shift4")
1168   (set_attr "length" "2,2,4")])
1169
1170;; Compare instructions.
1171;; This controls RTL generation and register allocation.
1172
1173;; We generate RTL for comparisons and branches by having the cmpxx
1174;; patterns store away the operands.  Then the bcc patterns
1175;; emit RTL for both the compare and the branch.
1176;;
1177;; On the m32r it is more efficient to use the bxxz instructions and
1178;; thus merge the compare and branch into one instruction, so they are
1179;; preferred.
1180
1181(define_insn "cmp_eqsi_zero_insn"
1182  [(set (reg:CC 17)
1183        (eq:CC (match_operand:SI 0 "register_operand" "r,r")
1184               (match_operand:SI 1 "reg_or_zero_operand" "r,P")))]
1185  "TARGET_M32RX || TARGET_M32R2"
1186  "@
1187   cmpeq %0, %1
1188   cmpz  %0"
1189  [(set_attr "type" "int4")
1190   (set_attr "length" "4")])
1191
1192;; The cmp_xxx_insn patterns set the condition bit to the result of the
1193;; comparison.  There isn't a "compare equal" instruction so cmp_eqsi_insn
1194;; is quite inefficient.  However, it is rarely used.
1195
1196(define_insn "cmp_eqsi_insn"
1197  [(set (reg:CC 17)
1198        (eq:CC (match_operand:SI 0 "register_operand" "r,r")
1199               (match_operand:SI 1 "reg_or_cmp_int16_operand" "r,P")))
1200   (clobber (match_scratch:SI 2 "=&r,&r"))]
1201  ""
1202  "*
1203{
1204  if (which_alternative == 0)
1205    {
1206         return \"mv %2,%0\;sub %2,%1\;cmpui %2,#1\";
1207    }
1208  else
1209    {
1210        if (INTVAL (operands [1]) == 0)
1211          return \"cmpui %0, #1\";
1212        else if (REGNO (operands [2]) == REGNO (operands [0]))
1213          return \"addi %0,%#%N1\;cmpui %2,#1\";
1214        else
1215          return \"add3 %2,%0,%#%N1\;cmpui %2,#1\";
1216    }
1217}"
1218  [(set_attr "type" "multi,multi")
1219   (set_attr "length" "8,8")])
1220
1221(define_insn "cmp_ltsi_insn"
1222  [(set (reg:CC 17)
1223        (lt:CC (match_operand:SI 0 "register_operand" "r,r")
1224               (match_operand:SI 1 "reg_or_int16_operand" "r,J")))]
1225  ""
1226  "@
1227   cmp %0,%1
1228   cmpi %0,%#%1"
1229  [(set_attr "type" "int2,int4")
1230   (set_attr "length" "2,4")])
1231
1232(define_insn "cmp_ltusi_insn"
1233  [(set (reg:CC 17)
1234        (ltu:CC (match_operand:SI 0 "register_operand" "r,r")
1235                (match_operand:SI 1 "reg_or_int16_operand" "r,J")))]
1236  ""
1237  "@
1238   cmpu %0,%1
1239   cmpui %0,%#%1"
1240  [(set_attr "type" "int2,int4")
1241   (set_attr "length" "2,4")])
1242
1243;; These control RTL generation for conditional jump insns.
1244
1245(define_expand "cbranchsi4"
1246  ; the comparison is emitted by gen_compare if needed.
1247  [(set (pc)
1248	(if_then_else (match_operator 0 "ordered_comparison_operator"
1249		       [(match_operand:SI 1 "register_operand" "")
1250			(match_operand:SI 2 "reg_or_cmp_int16_operand" "")])
1251		      (label_ref (match_operand 3 "" ""))
1252		      (pc)))]
1253  ""
1254  "
1255{
1256  operands[0] = gen_compare (GET_CODE (operands[0]), operands[1], operands[2], FALSE);
1257  operands[1] = XEXP (operands[0], 0);
1258  operands[2] = XEXP (operands[0], 1);
1259}")
1260
1261;; Now match both normal and inverted jump.
1262
1263(define_insn "*branch_insn"
1264  [(set (pc)
1265	(if_then_else (match_operator 1 "eqne_comparison_operator"
1266				      [(reg 17) (const_int 0)])
1267		      (label_ref (match_operand 0 "" ""))
1268		      (pc)))]
1269  ""
1270  "*
1271{
1272  static char instruction[40];
1273  sprintf (instruction, \"%s%s %%l0\",
1274	   (GET_CODE (operands[1]) == NE) ? \"bc\" : \"bnc\",
1275	   (get_attr_length (insn) == 2) ? \".s\" : \"\");
1276  return instruction;
1277}"
1278  [(set_attr "type" "branch")
1279   ; cf PR gcc/28508
1280   ; We use 300/600 instead of 512,1024 to account for inaccurate insn
1281   ; lengths and insn alignments that are complex to track.
1282   ; It's not important that we be hyper-precise here.  It may be more
1283   ; important blah blah blah when the chip supports parallel execution
1284   ; blah blah blah but until then blah blah blah this is simple and
1285   ; suffices.
1286   (set (attr "length") (if_then_else (ltu (plus (minus (match_dup 0) (pc))
1287						 (const_int 300))
1288					   (const_int 600))
1289				      (const_int 2)
1290				      (const_int 4)))])
1291
1292(define_insn "*rev_branch_insn"
1293  [(set (pc)
1294	(if_then_else (match_operator 1 "eqne_comparison_operator"
1295				      [(reg 17) (const_int 0)])
1296		      (pc)
1297		      (label_ref (match_operand 0 "" ""))))]
1298  ;"REVERSIBLE_CC_MODE (GET_MODE (XEXP (operands[1], 0)))"
1299  ""
1300  "*
1301{
1302  static char instruction[40];
1303  sprintf (instruction, \"%s%s %%l0\",
1304	   (GET_CODE (operands[1]) == EQ) ? \"bc\" : \"bnc\",
1305	   (get_attr_length (insn) == 2) ? \".s\" : \"\");
1306  return instruction;
1307}"
1308  [(set_attr "type" "branch")
1309   ; cf PR gcc/28508
1310   ; We use 300/600 instead of 512,1024 to account for inaccurate insn
1311   ; lengths and insn alignments that are complex to track.
1312   ; It's not important that we be hyper-precise here.  It may be more
1313   ; important blah blah blah when the chip supports parallel execution
1314   ; blah blah blah but until then blah blah blah this is simple and
1315   ; suffices.
1316   (set (attr "length") (if_then_else (ltu (plus (minus (match_dup 0) (pc))
1317						 (const_int 300))
1318					   (const_int 600))
1319				      (const_int 2)
1320				      (const_int 4)))])
1321
1322; reg/reg compare and branch insns
1323
1324(define_insn "*reg_branch_insn"
1325  [(set (pc)
1326	(if_then_else (match_operator 1 "eqne_comparison_operator"
1327				      [(match_operand:SI 2 "register_operand" "r")
1328				       (match_operand:SI 3 "register_operand" "r")])
1329		      (label_ref (match_operand 0 "" ""))
1330		      (pc)))]
1331  ""
1332  "*
1333{
1334  /* Is branch target reachable with beq/bne?  */
1335  if (get_attr_length (insn) == 4)
1336    {
1337      if (GET_CODE (operands[1]) == EQ)
1338	return \"beq %2,%3,%l0\";
1339      else
1340	return \"bne %2,%3,%l0\";
1341    }
1342  else
1343    {
1344      if (GET_CODE (operands[1]) == EQ)
1345	return \"bne %2,%3,1f\;bra %l0\;1:\";
1346      else
1347	return \"beq %2,%3,1f\;bra %l0\;1:\";
1348    }
1349}"
1350  [(set_attr "type" "branch")
1351  ; We use 25000/50000 instead of 32768/65536 to account for slot filling
1352  ; which is complex to track and inaccurate length specs.
1353   (set (attr "length") (if_then_else (ltu (plus (minus (match_dup 0) (pc))
1354						 (const_int 25000))
1355					   (const_int 50000))
1356				      (const_int 4)
1357				      (const_int 8)))])
1358
1359(define_insn "*rev_reg_branch_insn"
1360  [(set (pc)
1361	(if_then_else (match_operator 1 "eqne_comparison_operator"
1362				      [(match_operand:SI 2 "register_operand" "r")
1363				       (match_operand:SI 3 "register_operand" "r")])
1364		      (pc)
1365		      (label_ref (match_operand 0 "" ""))))]
1366  ""
1367  "*
1368{
1369  /* Is branch target reachable with beq/bne?  */
1370  if (get_attr_length (insn) == 4)
1371    {
1372      if (GET_CODE (operands[1]) == NE)
1373	return \"beq %2,%3,%l0\";
1374      else
1375	return \"bne %2,%3,%l0\";
1376    }
1377  else
1378    {
1379      if (GET_CODE (operands[1]) == NE)
1380	return \"bne %2,%3,1f\;bra %l0\;1:\";
1381      else
1382	return \"beq %2,%3,1f\;bra %l0\;1:\";
1383    }
1384}"
1385  [(set_attr "type" "branch")
1386  ; We use 25000/50000 instead of 32768/65536 to account for slot filling
1387  ; which is complex to track and inaccurate length specs.
1388   (set (attr "length") (if_then_else (ltu (plus (minus (match_dup 0) (pc))
1389						 (const_int 25000))
1390					   (const_int 50000))
1391				      (const_int 4)
1392				      (const_int 8)))])
1393
1394; reg/zero compare and branch insns
1395
1396(define_insn "*zero_branch_insn"
1397  [(set (pc)
1398	(if_then_else (match_operator 1 "signed_comparison_operator"
1399				      [(match_operand:SI 2 "register_operand" "r")
1400				       (const_int 0)])
1401		      (label_ref (match_operand 0 "" ""))
1402		      (pc)))]
1403  ""
1404  "*
1405{
1406  const char *br,*invbr;
1407  char asmtext[40];
1408
1409  switch (GET_CODE (operands[1]))
1410    {
1411      case EQ : br = \"eq\"; invbr = \"ne\"; break;
1412      case NE : br = \"ne\"; invbr = \"eq\"; break;
1413      case LE : br = \"le\"; invbr = \"gt\"; break;
1414      case GT : br = \"gt\"; invbr = \"le\"; break;
1415      case LT : br = \"lt\"; invbr = \"ge\"; break;
1416      case GE : br = \"ge\"; invbr = \"lt\"; break;
1417
1418      default: gcc_unreachable ();
1419    }
1420
1421  /* Is branch target reachable with bxxz?  */
1422  if (get_attr_length (insn) == 4)
1423    {
1424      sprintf (asmtext, \"b%sz %%2,%%l0\", br);
1425      output_asm_insn (asmtext, operands);
1426    }
1427  else
1428    {
1429      sprintf (asmtext, \"b%sz %%2,1f\;bra %%l0\;1:\", invbr);
1430      output_asm_insn (asmtext, operands);
1431    }
1432  return \"\";
1433}"
1434  [(set_attr "type" "branch")
1435  ; We use 25000/50000 instead of 32768/65536 to account for slot filling
1436  ; which is complex to track and inaccurate length specs.
1437   (set (attr "length") (if_then_else (ltu (plus (minus (match_dup 0) (pc))
1438						 (const_int 25000))
1439					   (const_int 50000))
1440				      (const_int 4)
1441				      (const_int 8)))])
1442
1443(define_insn "*rev_zero_branch_insn"
1444  [(set (pc)
1445	(if_then_else (match_operator 1 "eqne_comparison_operator"
1446				      [(match_operand:SI 2 "register_operand" "r")
1447				       (const_int 0)])
1448		      (pc)
1449		      (label_ref (match_operand 0 "" ""))))]
1450  ""
1451  "*
1452{
1453  const char *br,*invbr;
1454  char asmtext[40];
1455
1456  switch (GET_CODE (operands[1]))
1457    {
1458      case EQ : br = \"eq\"; invbr = \"ne\"; break;
1459      case NE : br = \"ne\"; invbr = \"eq\"; break;
1460      case LE : br = \"le\"; invbr = \"gt\"; break;
1461      case GT : br = \"gt\"; invbr = \"le\"; break;
1462      case LT : br = \"lt\"; invbr = \"ge\"; break;
1463      case GE : br = \"ge\"; invbr = \"lt\"; break;
1464
1465      default: gcc_unreachable ();
1466    }
1467
1468  /* Is branch target reachable with bxxz?  */
1469  if (get_attr_length (insn) == 4)
1470    {
1471      sprintf (asmtext, \"b%sz %%2,%%l0\", invbr);
1472      output_asm_insn (asmtext, operands);
1473    }
1474  else
1475    {
1476      sprintf (asmtext, \"b%sz %%2,1f\;bra %%l0\;1:\", br);
1477      output_asm_insn (asmtext, operands);
1478    }
1479  return \"\";
1480}"
1481  [(set_attr "type" "branch")
1482  ; We use 25000/50000 instead of 32768/65536 to account for slot filling
1483  ; which is complex to track and inaccurate length specs.
1484   (set (attr "length") (if_then_else (ltu (plus (minus (match_dup 0) (pc))
1485						 (const_int 25000))
1486					   (const_int 50000))
1487				      (const_int 4)
1488				      (const_int 8)))])
1489
1490;; S<cc> operations to set a register to 1/0 based on a comparison
1491
1492(define_expand "cstoresi4"
1493  [(match_operand:SI 0 "register_operand" "")
1494   (match_operator:SI 1 "ordered_comparison_operator"
1495    [(match_operand:SI 2 "register_operand" "")
1496     (match_operand:SI 3 "reg_or_cmp_int16_operand" "")])]
1497  ""
1498  "
1499{
1500  if (GET_MODE (operands[0]) != SImode)
1501    FAIL;
1502
1503  if (!gen_cond_store (GET_CODE (operands[1]),
1504		       operands[0], operands[2], operands[3]))
1505    FAIL;
1506
1507  DONE;
1508}")
1509
1510(define_insn "seq_insn_m32rx"
1511  [(set (match_operand:SI 0 "register_operand" "=r")
1512	(eq:SI (match_operand:SI 1 "register_operand" "%r")
1513	       (match_operand:SI 2 "reg_or_zero_operand" "rP")))
1514   (clobber (reg:CC 17))]
1515  "TARGET_M32RX || TARGET_M32R2"
1516  "#"
1517  [(set_attr "type" "multi")
1518   (set_attr "length" "6")])
1519
1520(define_split
1521  [(set (match_operand:SI 0 "register_operand" "")
1522	(eq:SI (match_operand:SI 1 "register_operand" "")
1523	       (match_operand:SI 2 "reg_or_zero_operand" "")))
1524   (clobber (reg:CC 17))]
1525  "TARGET_M32RX || TARGET_M32R2"
1526  [(set (reg:CC 17)
1527	(eq:CC (match_dup 1)
1528	       (match_dup 2)))
1529   (set (match_dup 0)
1530	(ne:SI (reg:CC 17) (const_int 0)))]
1531  "")
1532
1533(define_insn "seq_zero_insn"
1534  [(set (match_operand:SI 0 "register_operand" "=r")
1535	(eq:SI (match_operand:SI 1 "register_operand" "r")
1536	       (const_int 0)))
1537   (clobber (reg:CC 17))]
1538  "TARGET_M32R"
1539  "#"
1540  [(set_attr "type" "multi")
1541   (set_attr "length" "6")])
1542
1543(define_split
1544  [(set (match_operand:SI 0 "register_operand" "")
1545	(eq:SI (match_operand:SI 1 "register_operand" "")
1546	       (const_int 0)))
1547   (clobber (reg:CC 17))]
1548  "TARGET_M32R"
1549  [(match_dup 3)]
1550  "
1551{
1552  rtx op0 = operands[0];
1553  rtx op1 = operands[1];
1554
1555  start_sequence ();
1556  emit_insn (gen_cmp_ltusi_insn (op1, const1_rtx));
1557  emit_insn (gen_movcc_insn (op0));
1558  operands[3] = get_insns ();
1559  end_sequence ();
1560}")
1561
1562(define_insn "seq_insn"
1563  [(set (match_operand:SI 0 "register_operand" "=r,r,??r,r")
1564	(eq:SI (match_operand:SI 1 "register_operand" "r,r,r,r")
1565	       (match_operand:SI 2 "reg_or_eq_int16_operand" "r,r,r,PK")))
1566   (clobber (reg:CC 17))
1567   (clobber (match_scratch:SI 3 "=1,2,&r,r"))]
1568  "TARGET_M32R"
1569  "#"
1570  [(set_attr "type" "multi")
1571   (set_attr "length" "8,8,10,10")])
1572
1573(define_split
1574  [(set (match_operand:SI 0 "register_operand" "")
1575	(eq:SI (match_operand:SI 1 "register_operand" "")
1576	       (match_operand:SI 2 "reg_or_eq_int16_operand" "")))
1577   (clobber (reg:CC 17))
1578   (clobber (match_scratch:SI 3 ""))]
1579  "TARGET_M32R && reload_completed"
1580  [(match_dup 4)]
1581  "
1582{
1583  rtx op0 = operands[0];
1584  rtx op1 = operands[1];
1585  rtx op2 = operands[2];
1586  rtx op3 = operands[3];
1587  HOST_WIDE_INT value;
1588
1589  if (REG_P (op2) && REG_P (op3)
1590      && REGNO (op2) == REGNO (op3))
1591    {
1592      op1 = operands[2];
1593      op2 = operands[1];
1594    }
1595
1596  start_sequence ();
1597  if (REG_P (op1) && REG_P (op3)
1598      && REGNO (op1) != REGNO (op3))
1599    {
1600      emit_move_insn (op3, op1);
1601      op1 = op3;
1602    }
1603
1604  if (satisfies_constraint_P (op2) && (value = INTVAL (op2)) != 0)
1605    emit_insn (gen_addsi3 (op3, op1, GEN_INT (-value)));
1606  else
1607    emit_insn (gen_xorsi3 (op3, op1, op2));
1608
1609  emit_insn (gen_cmp_ltusi_insn (op3, const1_rtx));
1610  emit_insn (gen_movcc_insn (op0));
1611  operands[4] = get_insns ();
1612  end_sequence ();
1613}")
1614
1615(define_insn "sne_zero_insn"
1616  [(set (match_operand:SI 0 "register_operand" "=r")
1617	(ne:SI (match_operand:SI 1 "register_operand" "r")
1618	       (const_int 0)))
1619   (clobber (reg:CC 17))
1620   (clobber (match_scratch:SI 2 "=&r"))]
1621  ""
1622  "#"
1623  [(set_attr "type" "multi")
1624   (set_attr "length" "6")])
1625
1626(define_split
1627  [(set (match_operand:SI 0 "register_operand" "")
1628	(ne:SI (match_operand:SI 1 "register_operand" "")
1629	       (const_int 0)))
1630   (clobber (reg:CC 17))
1631   (clobber (match_scratch:SI 2 ""))]
1632  "reload_completed"
1633  [(set (match_dup 2)
1634	(const_int 0))
1635   (set (reg:CC 17)
1636	(ltu:CC (match_dup 2)
1637		(match_dup 1)))
1638   (set (match_dup 0)
1639	(ne:SI (reg:CC 17) (const_int 0)))]
1640  "")
1641
1642(define_insn "slt_insn"
1643  [(set (match_operand:SI 0 "register_operand" "=r,r")
1644	(lt:SI (match_operand:SI 1 "register_operand" "r,r")
1645	       (match_operand:SI 2 "reg_or_int16_operand" "r,J")))
1646   (clobber (reg:CC 17))]
1647  ""
1648  "#"
1649  [(set_attr "type" "multi")
1650   (set_attr "length" "4,6")])
1651
1652(define_split
1653  [(set (match_operand:SI 0 "register_operand" "")
1654	(lt:SI (match_operand:SI 1 "register_operand" "")
1655	       (match_operand:SI 2 "reg_or_int16_operand" "")))
1656   (clobber (reg:CC 17))]
1657  ""
1658  [(set (reg:CC 17)
1659	(lt:CC (match_dup 1)
1660	       (match_dup 2)))
1661   (set (match_dup 0)
1662	(ne:SI (reg:CC 17) (const_int 0)))]
1663  "")
1664
1665(define_insn "sle_insn"
1666  [(set (match_operand:SI 0 "register_operand" "=r")
1667	(le:SI (match_operand:SI 1 "register_operand" "r")
1668	       (match_operand:SI 2 "register_operand" "r")))
1669   (clobber (reg:CC 17))]
1670  ""
1671  "#"
1672  [(set_attr "type" "multi")
1673   (set_attr "length" "8")])
1674
1675(define_split
1676  [(set (match_operand:SI 0 "register_operand" "")
1677	(le:SI (match_operand:SI 1 "register_operand" "")
1678	       (match_operand:SI 2 "register_operand" "")))
1679   (clobber (reg:CC 17))]
1680  "!optimize_size"
1681  [(set (reg:CC 17)
1682	(lt:CC (match_dup 2)
1683	       (match_dup 1)))
1684   (set (match_dup 0)
1685	(ne:SI (reg:CC 17) (const_int 0)))
1686   (set (match_dup 0)
1687	(xor:SI (match_dup 0)
1688		(const_int 1)))]
1689  "")
1690
1691;; If optimizing for space, use -(reg - 1) to invert the comparison rather than
1692;; xor reg,reg,1 which might eliminate a NOP being inserted.
1693(define_split
1694  [(set (match_operand:SI 0 "register_operand" "")
1695	(le:SI (match_operand:SI 1 "register_operand" "")
1696	       (match_operand:SI 2 "register_operand" "")))
1697   (clobber (reg:CC 17))]
1698  "optimize_size"
1699  [(set (reg:CC 17)
1700	(lt:CC (match_dup 2)
1701	       (match_dup 1)))
1702   (set (match_dup 0)
1703	(ne:SI (reg:CC 17) (const_int 0)))
1704   (set (match_dup 0)
1705	(plus:SI (match_dup 0)
1706		 (const_int -1)))
1707   (set (match_dup 0)
1708	(neg:SI (match_dup 0)))]
1709  "")
1710
1711(define_insn "sge_insn"
1712  [(set (match_operand:SI 0 "register_operand" "=r,r")
1713	(ge:SI (match_operand:SI 1 "register_operand" "r,r")
1714	       (match_operand:SI 2 "reg_or_int16_operand" "r,J")))
1715   (clobber (reg:CC 17))]
1716  ""
1717  "#"
1718  [(set_attr "type" "multi")
1719   (set_attr "length" "8,10")])
1720
1721(define_split
1722  [(set (match_operand:SI 0 "register_operand" "")
1723	(ge:SI (match_operand:SI 1 "register_operand" "")
1724	       (match_operand:SI 2 "reg_or_int16_operand" "")))
1725   (clobber (reg:CC 17))]
1726  "!optimize_size"
1727  [(set (reg:CC 17)
1728	(lt:CC (match_dup 1)
1729	       (match_dup 2)))
1730   (set (match_dup 0)
1731	(ne:SI (reg:CC 17) (const_int 0)))
1732   (set (match_dup 0)
1733	(xor:SI (match_dup 0)
1734		(const_int 1)))]
1735  "")
1736
1737;; If optimizing for space, use -(reg - 1) to invert the comparison rather than
1738;; xor reg,reg,1 which might eliminate a NOP being inserted.
1739(define_split
1740  [(set (match_operand:SI 0 "register_operand" "")
1741	(ge:SI (match_operand:SI 1 "register_operand" "")
1742	       (match_operand:SI 2 "reg_or_int16_operand" "")))
1743   (clobber (reg:CC 17))]
1744  "optimize_size"
1745  [(set (reg:CC 17)
1746	(lt:CC (match_dup 1)
1747	       (match_dup 2)))
1748   (set (match_dup 0)
1749	(ne:SI (reg:CC 17) (const_int 0)))
1750   (set (match_dup 0)
1751	(plus:SI (match_dup 0)
1752		 (const_int -1)))
1753   (set (match_dup 0)
1754	(neg:SI (match_dup 0)))]
1755  "")
1756
1757(define_insn "sltu_insn"
1758  [(set (match_operand:SI 0 "register_operand" "=r,r")
1759	(ltu:SI (match_operand:SI 1 "register_operand" "r,r")
1760		(match_operand:SI 2 "reg_or_int16_operand" "r,J")))
1761   (clobber (reg:CC 17))]
1762  ""
1763  "#"
1764  [(set_attr "type" "multi")
1765   (set_attr "length" "6,8")])
1766
1767(define_split
1768  [(set (match_operand:SI 0 "register_operand" "")
1769	(ltu:SI (match_operand:SI 1 "register_operand" "")
1770		(match_operand:SI 2 "reg_or_int16_operand" "")))
1771   (clobber (reg:CC 17))]
1772  ""
1773  [(set (reg:CC 17)
1774	(ltu:CC (match_dup 1)
1775		(match_dup 2)))
1776   (set (match_dup 0)
1777	(ne:SI (reg:CC 17) (const_int 0)))]
1778  "")
1779
1780(define_insn "sleu_insn"
1781  [(set (match_operand:SI 0 "register_operand" "=r")
1782	(leu:SI (match_operand:SI 1 "register_operand" "r")
1783		(match_operand:SI 2 "register_operand" "r")))
1784   (clobber (reg:CC 17))]
1785  ""
1786  "#"
1787  [(set_attr "type" "multi")
1788   (set_attr "length" "8")])
1789
1790(define_split
1791  [(set (match_operand:SI 0 "register_operand" "")
1792	(leu:SI (match_operand:SI 1 "register_operand" "")
1793		(match_operand:SI 2 "register_operand" "")))
1794   (clobber (reg:CC 17))]
1795  "!optimize_size"
1796  [(set (reg:CC 17)
1797	(ltu:CC (match_dup 2)
1798		(match_dup 1)))
1799   (set (match_dup 0)
1800	(ne:SI (reg:CC 17) (const_int 0)))
1801   (set (match_dup 0)
1802	(xor:SI (match_dup 0)
1803		(const_int 1)))]
1804  "")
1805
1806;; If optimizing for space, use -(reg - 1) to invert the comparison rather than
1807;; xor reg,reg,1 which might eliminate a NOP being inserted.
1808(define_split
1809  [(set (match_operand:SI 0 "register_operand" "")
1810	(leu:SI (match_operand:SI 1 "register_operand" "")
1811		(match_operand:SI 2 "register_operand" "")))
1812   (clobber (reg:CC 17))]
1813  "optimize_size"
1814  [(set (reg:CC 17)
1815	(ltu:CC (match_dup 2)
1816		(match_dup 1)))
1817   (set (match_dup 0)
1818	(ne:SI (reg:CC 17) (const_int 0)))
1819   (set (match_dup 0)
1820	(plus:SI (match_dup 0)
1821		 (const_int -1)))
1822   (set (match_dup 0)
1823	(neg:SI (match_dup 0)))]
1824  "")
1825
1826(define_insn "sgeu_insn"
1827  [(set (match_operand:SI 0 "register_operand" "=r,r")
1828	(geu:SI (match_operand:SI 1 "register_operand" "r,r")
1829		(match_operand:SI 2 "reg_or_int16_operand" "r,J")))
1830   (clobber (reg:CC 17))]
1831  ""
1832  "#"
1833  [(set_attr "type" "multi")
1834   (set_attr "length" "8,10")])
1835
1836(define_split
1837  [(set (match_operand:SI 0 "register_operand" "")
1838	(geu:SI (match_operand:SI 1 "register_operand" "")
1839		(match_operand:SI 2 "reg_or_int16_operand" "")))
1840   (clobber (reg:CC 17))]
1841  "!optimize_size"
1842  [(set (reg:CC 17)
1843	(ltu:CC (match_dup 1)
1844		(match_dup 2)))
1845   (set (match_dup 0)
1846	(ne:SI (reg:CC 17) (const_int 0)))
1847   (set (match_dup 0)
1848	(xor:SI (match_dup 0)
1849		(const_int 1)))]
1850  "")
1851
1852;; If optimizing for space, use -(reg - 1) to invert the comparison rather than
1853;; xor reg,reg,1 which might eliminate a NOP being inserted.
1854(define_split
1855  [(set (match_operand:SI 0 "register_operand" "")
1856	(geu:SI (match_operand:SI 1 "register_operand" "")
1857		(match_operand:SI 2 "reg_or_int16_operand" "")))
1858   (clobber (reg:CC 17))]
1859  "optimize_size"
1860  [(set (reg:CC 17)
1861	(ltu:CC (match_dup 1)
1862		(match_dup 2)))
1863   (set (match_dup 0)
1864	(ne:SI (reg:CC 17) (const_int 0)))
1865   (set (match_dup 0)
1866	(plus:SI (match_dup 0)
1867		 (const_int -1)))
1868   (set (match_dup 0)
1869	(neg:SI (match_dup 0)))]
1870  "")
1871
1872(define_insn "movcc_insn"
1873  [(set (match_operand:SI 0 "register_operand" "=r")
1874	(ne:SI (reg:CC 17) (const_int 0)))]
1875  ""
1876  "mvfc %0, cbr"
1877  [(set_attr "type" "misc")
1878   (set_attr "length" "2")])
1879
1880
1881;; Unconditional and other jump instructions.
1882
1883(define_insn "jump"
1884  [(set (pc) (label_ref (match_operand 0 "" "")))]
1885  ""
1886  "bra %l0"
1887  [(set_attr "type" "uncond_branch")
1888   (set (attr "length") (if_then_else (ltu (plus (minus (match_dup 0) (pc))
1889						 (const_int 400))
1890					   (const_int 800))
1891				      (const_int 2)
1892				      (const_int 4)))])
1893
1894(define_insn "indirect_jump"
1895  [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
1896  ""
1897  "jmp %a0"
1898  [(set_attr "type" "uncond_branch")
1899   (set_attr "length" "2")])
1900
1901(define_insn "return_lr"
1902  [(parallel [(return) (use (reg:SI 14))])]
1903  ""
1904  "jmp lr"
1905  [(set_attr "type" "uncond_branch")
1906   (set_attr "length" "2")])
1907
1908(define_insn "return_rte"
1909  [(return)]
1910  ""
1911  "rte"
1912  [(set_attr "type" "uncond_branch")
1913   (set_attr "length" "2")])
1914
1915(define_expand "return"
1916  [(return)]
1917  "direct_return ()"
1918  "
1919{
1920  emit_jump_insn (gen_return_lr ());
1921  DONE;
1922}")
1923
1924(define_expand "return_normal"
1925  [(return)]
1926  "!direct_return ()"
1927  "
1928{
1929  enum m32r_function_type fn_type;
1930
1931  fn_type = m32r_compute_function_type (current_function_decl);
1932  if (M32R_INTERRUPT_P (fn_type))
1933    {
1934      emit_jump_insn (gen_return_rte ());
1935      DONE;
1936    }
1937
1938  emit_jump_insn (gen_return_lr ());
1939  DONE;
1940}")
1941
1942(define_expand "tablejump"
1943  [(parallel [(set (pc) (match_operand 0 "register_operand" "r"))
1944              (use (label_ref (match_operand 1 "" "")))])]
1945  ""
1946  "
1947{
1948  /* In pic mode, our address differences are against the base of the
1949     table.  Add that base value back in; CSE ought to be able to combine
1950     the two address loads.  */
1951  if (flag_pic)
1952    {
1953      rtx tmp, tmp2;
1954
1955      tmp = gen_rtx_LABEL_REF (Pmode, operands[1]);
1956      tmp2 = operands[0];
1957      tmp = gen_rtx_PLUS (Pmode, tmp2, tmp);
1958      operands[0] = memory_address (Pmode, tmp);
1959    }
1960}")
1961
1962(define_insn "*tablejump_insn"
1963  [(set (pc) (match_operand:SI 0 "address_operand" "p"))
1964   (use (label_ref (match_operand 1 "" "")))]
1965  ""
1966  "jmp %a0"
1967  [(set_attr "type" "uncond_branch")
1968   (set_attr "length" "2")])
1969
1970(define_expand "call"
1971  ;; operands[1] is stack_size_rtx
1972  ;; operands[2] is next_arg_register
1973  [(parallel [(call (match_operand:SI 0 "call_operand" "")
1974		    (match_operand 1 "" ""))
1975	     (clobber (reg:SI 14))])]
1976  ""
1977  "
1978{
1979  if (flag_pic)
1980    crtl->uses_pic_offset_table = 1;
1981}")
1982
1983(define_insn "*call_via_reg"
1984  [(call (mem:SI (match_operand:SI 0 "register_operand" "r"))
1985	 (match_operand 1 "" ""))
1986   (clobber (reg:SI 14))]
1987  ""
1988  "jl %0"
1989  [(set_attr "type" "call")
1990   (set_attr "length" "2")])
1991
1992(define_insn "*call_via_label"
1993  [(call (mem:SI (match_operand:SI 0 "call_address_operand" ""))
1994	 (match_operand 1 "" ""))
1995   (clobber (reg:SI 14))]
1996  ""
1997  "*
1998{
1999  int call26_p = call26_operand (operands[0], FUNCTION_MODE);
2000
2001  if (! call26_p)
2002    {
2003      /* We may not be able to reach with a `bl' insn so punt and leave it to
2004	 the linker.
2005	 We do this here, rather than doing a force_reg in the define_expand
2006	 so these insns won't be separated, say by scheduling, thus simplifying
2007	 the linker.  */
2008      return \"seth r14,%T0\;add3 r14,r14,%B0\;jl r14\";
2009    }
2010  else
2011    return \"bl %0\";
2012}"
2013  [(set_attr "type" "call")
2014   (set (attr "length")
2015	(if_then_else (eq (symbol_ref "call26_operand (operands[0], FUNCTION_MODE)")
2016			  (const_int 0))
2017		      (const_int 12) ; 10 + 2 for nop filler
2018		      ; The return address must be on a 4 byte boundary so
2019		      ; there's no point in using a value of 2 here.  A 2 byte
2020		      ; insn may go in the left slot but we currently can't
2021		      ; use such knowledge.
2022		      (const_int 4)))])
2023
2024(define_expand "call_value"
2025  ;; operand 2 is stack_size_rtx
2026  ;; operand 3 is next_arg_register
2027  [(parallel [(set (match_operand 0 "register_operand" "=r")
2028		   (call (match_operand:SI 1 "call_operand" "")
2029			 (match_operand 2 "" "")))
2030	     (clobber (reg:SI 14))])]
2031  ""
2032  "
2033{
2034  if (flag_pic)
2035    crtl->uses_pic_offset_table = 1;
2036}")
2037
2038(define_insn "*call_value_via_reg"
2039  [(set (match_operand 0 "register_operand" "=r")
2040	(call (mem:SI (match_operand:SI 1 "register_operand" "r"))
2041	      (match_operand 2 "" "")))
2042   (clobber (reg:SI 14))]
2043  ""
2044  "jl %1"
2045  [(set_attr "type" "call")
2046   (set_attr "length" "2")])
2047
2048(define_insn "*call_value_via_label"
2049  [(set (match_operand 0 "register_operand" "=r")
2050	(call (mem:SI (match_operand:SI 1 "call_address_operand" ""))
2051	      (match_operand 2 "" "")))
2052   (clobber (reg:SI 14))]
2053  ""
2054  "*
2055{
2056  int call26_p = call26_operand (operands[1], FUNCTION_MODE);
2057
2058  if (flag_pic)
2059    crtl->uses_pic_offset_table = 1;
2060
2061  if (! call26_p)
2062    {
2063      /* We may not be able to reach with a `bl' insn so punt and leave it to
2064	 the linker.
2065	 We do this here, rather than doing a force_reg in the define_expand
2066	 so these insns won't be separated, say by scheduling, thus simplifying
2067	 the linker.  */
2068      return \"seth r14,%T1\;add3 r14,r14,%B1\;jl r14\";
2069    }
2070  else
2071    return \"bl %1\";
2072}"
2073  [(set_attr "type" "call")
2074   (set (attr "length")
2075	(if_then_else (eq (symbol_ref "call26_operand (operands[1], FUNCTION_MODE)")
2076			  (const_int 0))
2077		      (const_int 12) ; 10 + 2 for nop filler
2078		      ; The return address must be on a 4 byte boundary so
2079		      ; there's no point in using a value of 2 here.  A 2 byte
2080		      ; insn may go in the left slot but we currently can't
2081		      ; use such knowledge.
2082		      (const_int 4)))])
2083
2084(define_insn "nop"
2085  [(const_int 0)]
2086  ""
2087  "nop"
2088  [(set_attr "type" "int2")
2089   (set_attr "length" "2")])
2090
2091;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
2092;; all of memory.  This blocks insns from being moved across this point.
2093
2094(define_insn "blockage"
2095  [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
2096  ""
2097  "")
2098
2099;; Special pattern to flush the icache.
2100
2101(define_insn "flush_icache"
2102  [(unspec_volatile [(match_operand 0 "memory_operand" "m")]
2103		    UNSPECV_FLUSH_ICACHE)
2104   (match_operand 1 "" "")
2105   (clobber (reg:SI 17))]
2106  ""
2107  "* return \"trap %#%1 ; flush-icache\";"
2108  [(set_attr "type" "int4")
2109   (set_attr "length" "4")])
2110
2111;; Speed up fabs and provide correct sign handling for -0
2112
2113(define_insn "absdf2"
2114  [(set (match_operand:DF 0 "register_operand" "=r")
2115	(abs:DF (match_operand:DF 1 "register_operand" "0")))]
2116  ""
2117  "#"
2118  [(set_attr "type" "multi")
2119   (set_attr "length" "4")])
2120
2121(define_split
2122  [(set (match_operand:DF 0 "register_operand" "")
2123	(abs:DF (match_operand:DF 1 "register_operand" "")))]
2124  "reload_completed"
2125  [(set (match_dup 2)
2126	(ashift:SI (match_dup 2)
2127		   (const_int 1)))
2128   (set (match_dup 2)
2129	(lshiftrt:SI (match_dup 2)
2130		     (const_int 1)))]
2131  "operands[2] = gen_highpart (SImode, operands[0]);")
2132
2133(define_insn "abssf2"
2134  [(set (match_operand:SF 0 "register_operand" "=r")
2135	(abs:SF (match_operand:SF 1 "register_operand" "0")))]
2136  ""
2137  "#"
2138  [(set_attr "type" "multi")
2139   (set_attr "length" "4")])
2140
2141(define_split
2142  [(set (match_operand:SF 0 "register_operand" "")
2143	(abs:SF (match_operand:SF 1 "register_operand" "")))]
2144  "reload_completed"
2145  [(set (match_dup 2)
2146	(ashift:SI (match_dup 2)
2147		   (const_int 1)))
2148   (set (match_dup 2)
2149	(lshiftrt:SI (match_dup 2)
2150		     (const_int 1)))]
2151  "operands[2] = gen_highpart (SImode, operands[0]);")
2152
2153;; Conditional move instructions
2154;; Based on those done for the d10v
2155
2156(define_expand "movsicc"
2157  [
2158   (set (match_operand:SI 0 "register_operand" "r")
2159	(if_then_else:SI (match_operand 1 "" "")
2160			 (match_operand:SI 2 "conditional_move_operand" "O")
2161			 (match_operand:SI 3 "conditional_move_operand" "O")
2162        )
2163   )
2164  ]
2165  ""
2166  "
2167{
2168  if (! zero_and_one (operands [2], operands [3]))
2169    FAIL;
2170
2171  /* Generate the comparison that will set the carry flag.  */
2172  operands[1] = gen_compare (GET_CODE (operands[1]), XEXP (operands[1], 0),
2173			     XEXP (operands[1], 1), TRUE);
2174
2175  /* See other movsicc pattern below for reason why.  */
2176  emit_insn (gen_blockage ());
2177}")
2178
2179;; Generate the conditional instructions based on how the carry flag is examined.
2180(define_insn "*movsicc_internal"
2181  [(set (match_operand:SI 0 "register_operand" "=r")
2182	(if_then_else:SI (match_operand 1 "carry_compare_operand" "")
2183			 (match_operand:SI 2 "conditional_move_operand" "O")
2184			 (match_operand:SI 3 "conditional_move_operand" "O")
2185        )
2186   )]
2187  "zero_and_one (operands [2], operands[3])"
2188  "* return emit_cond_move (operands, insn);"
2189  [(set_attr "type" "multi")
2190   (set_attr "length" "8")
2191  ]
2192)
2193
2194
2195;; Block moves, see m32r.c for more details.
2196;; Argument 0 is the destination
2197;; Argument 1 is the source
2198;; Argument 2 is the length
2199;; Argument 3 is the alignment
2200
2201(define_expand "movmemsi"
2202  [(parallel [(set (match_operand:BLK 0 "general_operand" "")
2203		   (match_operand:BLK 1 "general_operand" ""))
2204	      (use (match_operand:SI  2 "immediate_operand" ""))
2205	      (use (match_operand:SI  3 "immediate_operand" ""))])]
2206  ""
2207  "
2208{
2209  if (operands[0])		/* Avoid unused code messages.  */
2210    {
2211     if (m32r_expand_block_move (operands))
2212       DONE;
2213     else
2214       FAIL;
2215    }
2216}")
2217
2218;; Insn generated by block moves
2219
2220(define_insn "movmemsi_internal"
2221  [(set (mem:BLK (match_operand:SI 0 "register_operand" "r"))	;; destination
2222	(mem:BLK (match_operand:SI 1 "register_operand" "r")))	;; source
2223   (use (match_operand:SI 2 "m32r_block_immediate_operand" "J"));; # bytes to move
2224   (set (match_operand:SI 3 "register_operand" "=0")
2225	(plus:SI (minus (match_dup 2) (const_int 4))
2226	         (match_dup 0)))
2227   (set (match_operand:SI 4 "register_operand" "=1")
2228	(plus:SI (match_dup 1)
2229		 (match_dup 2)))
2230   (clobber (match_scratch:SI 5 "=&r"))  ;; temp1
2231   (clobber (match_scratch:SI 6 "=&r"))] ;; temp2
2232  ""
2233  "* m32r_output_block_move (insn, operands); return \"\"; "
2234  [(set_attr "type"	"store8")
2235   (set_attr "length"	"72")]) ;; Maximum
2236
2237;; PIC
2238
2239/* When generating pic, we need to load the symbol offset into a register.
2240   So that the optimizer does not confuse this with a normal symbol load
2241   we use an unspec.  The offset will be loaded from a constant pool entry,
2242   since that is the only type of relocation we can use.  */
2243
2244(define_insn "pic_load_addr"
2245  [(set (match_operand:SI 0 "register_operand" "=r")
2246        (unspec:SI [(match_operand 1 "" "")] UNSPEC_PIC_LOAD_ADDR))]
2247  "flag_pic"
2248  "ld24 %0,%#%1"
2249  [(set_attr "type" "int4")])
2250
2251(define_insn "gotoff_load_addr"
2252  [(set (match_operand:SI 0 "register_operand" "=r")
2253        (unspec:SI [(match_operand 1 "" "")] UNSPEC_GOTOFF))]
2254  "flag_pic"
2255  "seth %0, %#shigh(%1@GOTOFF)\;add3 %0, %0, low(%1@GOTOFF)"
2256  [(set_attr "type" 	"int4")
2257   (set_attr "length"	"8")])
2258
2259;; Load program counter insns.
2260
2261(define_insn "get_pc"
2262  [(clobber (reg:SI 14))
2263   (set (match_operand 0 "register_operand" "=r,r")
2264        (unspec [(match_operand 1 "" "")] UNSPEC_GET_PC))
2265   (use (match_operand:SI 2 "immediate_operand" "W,i"))]
2266  "flag_pic"
2267  "@
2268   bl.s .+4\;seth %0,%#shigh(%1)\;add3 %0,%0,%#low(%1+4)\;add %0,lr
2269   bl.s .+4\;ld24 %0,%#%1\;add %0,lr"
2270  [(set_attr "length" "12,8")])
2271
2272(define_expand "builtin_setjmp_receiver"
2273  [(label_ref (match_operand 0 "" ""))]
2274  "flag_pic"
2275  "
2276{
2277  m32r_load_pic_register ();
2278  DONE;
2279}")
2280