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