1;; Machine description of the Renesas M32R cpu for GNU C compiler
2;; Copyright (C) 1996-2019 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  if (! zero_and_one (operands [2], operands [3]))
2166    FAIL;
2167
2168  /* Generate the comparison that will set the carry flag.  */
2169  operands[1] = gen_compare (GET_CODE (operands[1]), XEXP (operands[1], 0),
2170			     XEXP (operands[1], 1), TRUE);
2171
2172  /* See other movsicc pattern below for reason why.  */
2173  emit_insn (gen_blockage ());
2174}")
2175
2176;; Generate the conditional instructions based on how the carry flag is examined.
2177(define_insn "*movsicc_internal"
2178  [(set (match_operand:SI 0 "register_operand" "=r")
2179	(if_then_else:SI (match_operand 1 "carry_compare_operand" "")
2180			 (match_operand:SI 2 "conditional_move_operand" "O")
2181			 (match_operand:SI 3 "conditional_move_operand" "O")
2182        )
2183   )]
2184  "zero_and_one (operands [2], operands[3])"
2185  "* return emit_cond_move (operands, insn);"
2186  [(set_attr "type" "multi")
2187   (set_attr "length" "8")
2188  ]
2189)
2190
2191
2192;; Block moves, see m32r.c for more details.
2193;; Argument 0 is the destination
2194;; Argument 1 is the source
2195;; Argument 2 is the length
2196;; Argument 3 is the alignment
2197
2198(define_expand "movmemsi"
2199  [(parallel [(set (match_operand:BLK 0 "general_operand" "")
2200		   (match_operand:BLK 1 "general_operand" ""))
2201	      (use (match_operand:SI  2 "immediate_operand" ""))
2202	      (use (match_operand:SI  3 "immediate_operand" ""))])]
2203  ""
2204  "
2205{
2206  if (operands[0])		/* Avoid unused code messages.  */
2207    {
2208     if (m32r_expand_block_move (operands))
2209       DONE;
2210     else
2211       FAIL;
2212    }
2213}")
2214
2215;; Insn generated by block moves
2216
2217(define_insn "movmemsi_internal"
2218  [(set (mem:BLK (match_operand:SI 0 "register_operand" "r"))	;; destination
2219	(mem:BLK (match_operand:SI 1 "register_operand" "r")))	;; source
2220   (use (match_operand:SI 2 "m32r_block_immediate_operand" "J"));; # bytes to move
2221   (set (match_operand:SI 3 "register_operand" "=0")
2222	(plus:SI (minus (match_dup 2) (const_int 4))
2223	         (match_dup 0)))
2224   (set (match_operand:SI 4 "register_operand" "=1")
2225	(plus:SI (match_dup 1)
2226		 (match_dup 2)))
2227   (clobber (match_scratch:SI 5 "=&r"))  ;; temp1
2228   (clobber (match_scratch:SI 6 "=&r"))] ;; temp2
2229  ""
2230  "* m32r_output_block_move (insn, operands); return \"\"; "
2231  [(set_attr "type"	"store8")
2232   (set_attr "length"	"72")]) ;; Maximum
2233
2234;; PIC
2235
2236/* When generating pic, we need to load the symbol offset into a register.
2237   So that the optimizer does not confuse this with a normal symbol load
2238   we use an unspec.  The offset will be loaded from a constant pool entry,
2239   since that is the only type of relocation we can use.  */
2240
2241(define_insn "pic_load_addr"
2242  [(set (match_operand:SI 0 "register_operand" "=r")
2243        (unspec:SI [(match_operand 1 "" "")] UNSPEC_PIC_LOAD_ADDR))]
2244  "flag_pic"
2245  "ld24 %0,%#%1"
2246  [(set_attr "type" "int4")])
2247
2248(define_insn "gotoff_load_addr"
2249  [(set (match_operand:SI 0 "register_operand" "=r")
2250        (unspec:SI [(match_operand 1 "" "")] UNSPEC_GOTOFF))]
2251  "flag_pic"
2252  "seth %0, %#shigh(%1@GOTOFF)\;add3 %0, %0, low(%1@GOTOFF)"
2253  [(set_attr "type" 	"int4")
2254   (set_attr "length"	"8")])
2255
2256;; Load program counter insns.
2257
2258(define_insn "get_pc"
2259  [(clobber (reg:SI 14))
2260   (set (match_operand 0 "register_operand" "=r,r")
2261        (unspec [(match_operand 1 "" "")] UNSPEC_GET_PC))
2262   (use (match_operand:SI 2 "immediate_operand" "W,i"))]
2263  "flag_pic"
2264  "@
2265   bl.s .+4\;seth %0,%#shigh(%1)\;add3 %0,%0,%#low(%1+4)\;add %0,lr
2266   bl.s .+4\;ld24 %0,%#%1\;add %0,lr"
2267  [(set_attr "length" "12,8")])
2268
2269(define_expand "builtin_setjmp_receiver"
2270  [(label_ref (match_operand 0 "" ""))]
2271  "flag_pic"
2272  "
2273{
2274  m32r_load_pic_register ();
2275  DONE;
2276}")
2277