1 ;; Machine description of the Mitsubishi M32R cpu for GNU C compiler
2 ;; Copyright (C) 1996, 1997, 1998, 1999, 2001 Free Software Foundation, Inc.
4 ;; This file is part of GCC.
6 ;; GCC is free software; you can redistribute it and/or modify
7 ;; it under the terms of the GNU General Public License as published by
8 ;; the Free Software Foundation; either version 2, or (at your option)
11 ;; GCC is distributed in the hope that it will be useful,
12 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
13 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 ;; GNU General Public License for more details.
16 ;; You should have received a copy of the GNU General Public License
17 ;; along with GCC; see the file COPYING. If not, write to
18 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
19 ;; Boston, MA 02111-1307, USA.
21 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
27 ;; 3 - setting carry in addx/subx instructions.
29 ;; Insn type. Used to default other attribute values.
31 "int2,int4,load2,load4,load8,store2,store4,store8,shift2,shift4,mul2,div4,uncond_branch,branch,call,multi,misc"
32 (const_string "misc"))
35 (define_attr "length" ""
36 (cond [(eq_attr "type" "int2,load2,store2,shift2,mul2")
39 (eq_attr "type" "int4,load4,store4,shift4,div4")
42 (eq_attr "type" "multi")
45 (eq_attr "type" "uncond_branch,branch,call")
50 ;; The length here is the length of a single asm. Unfortunately it might be
51 ;; 2 or 4 so we must allow for 4. That's ok though.
52 (define_asm_attributes
53 [(set_attr "length" "4")
54 (set_attr "type" "multi")])
57 ;; Whether an instruction is 16-bit or 32-bit
58 (define_attr "insn_size" "short,long"
59 (if_then_else (eq_attr "type" "int2,load2,store2,shift2,mul2")
60 (const_string "short")
61 (const_string "long")))
63 (define_attr "debug" "no,yes"
64 (const (symbol_ref "(TARGET_DEBUG != 0)")))
66 (define_attr "opt_size" "no,yes"
67 (const (symbol_ref "(optimize_size != 0)")))
69 (define_attr "m32r" "no,yes"
70 (const (symbol_ref "(TARGET_M32R != 0)")))
72 (define_attr "m32rx" "no,yes"
73 (const (symbol_ref "(TARGET_M32RX != 0)")))
75 (define_attr "m32r2" "no,yes"
76 (const (symbol_ref "(TARGET_M32R2 != 0)")))
78 (define_attr "m32rx_pipeline" "either,s,o,long,m32r"
79 (cond [(and (eq_attr "m32rx" "no")
80 (eq_attr "m32r2" "no"))
83 (eq_attr "insn_size" "!short")
84 (const_string "long")]
86 (cond [(eq_attr "type" "int2")
87 (const_string "either")
89 (eq_attr "type" "load2,store2,shift2,uncond_branch,branch,call")
92 (eq_attr "type" "mul2")
95 (const_string "long"))))
97 ;; ::::::::::::::::::::
101 ;; ::::::::::::::::::::
103 ;; On most RISC machines, there are instructions whose results are not
104 ;; available for a specific number of cycles. Common cases are instructions
105 ;; that load data from memory. On many machines, a pipeline stall will result
106 ;; if the data is referenced too soon after the load instruction.
108 ;; In addition, many newer microprocessors have multiple function units,
109 ;; usually one for integer and one for floating point, and often will incur
110 ;; pipeline stalls when a result that is needed is not yet ready.
112 ;; The descriptions in this section allow the specification of how much time
113 ;; must elapse between the execution of an instruction and the time when its
114 ;; result is used. It also allows specification of when the execution of an
115 ;; instruction will delay execution of similar instructions due to function
118 ;; For the purposes of the specifications in this section, a machine is divided
119 ;; into "function units", each of which execute a specific class of
120 ;; instructions in first-in-first-out order. Function units that accept one
121 ;; instruction each cycle and allow a result to be used in the succeeding
122 ;; instruction (usually via forwarding) need not be specified. Classic RISC
123 ;; microprocessors will normally have a single function unit, which we can call
124 ;; `memory'. The newer "superscalar" processors will often have function units
125 ;; for floating point operations, usually at least a floating point adder and
128 ;; Each usage of a function units by a class of insns is specified with a
129 ;; `define_function_unit' expression, which looks like this:
131 ;; (define_function_unit NAME MULTIPLICITY SIMULTANEITY TEST READY-DELAY
132 ;; ISSUE-DELAY [CONFLICT-LIST])
134 ;; NAME is a string giving the name of the function unit.
136 ;; MULTIPLICITY is an integer specifying the number of identical units in the
137 ;; processor. If more than one unit is specified, they will be scheduled
138 ;; independently. Only truly independent units should be counted; a pipelined
139 ;; unit should be specified as a single unit. (The only common example of a
140 ;; machine that has multiple function units for a single instruction class that
141 ;; are truly independent and not pipelined are the two multiply and two
142 ;; increment units of the CDC 6600.)
144 ;; SIMULTANEITY specifies the maximum number of insns that can be executing in
145 ;; each instance of the function unit simultaneously or zero if the unit is
146 ;; pipelined and has no limit.
148 ;; All `define_function_unit' definitions referring to function unit NAME must
149 ;; have the same name and values for MULTIPLICITY and SIMULTANEITY.
151 ;; TEST is an attribute test that selects the insns we are describing in this
152 ;; definition. Note that an insn may use more than one function unit and a
153 ;; function unit may be specified in more than one `define_function_unit'.
155 ;; READY-DELAY is an integer that specifies the number of cycles after which
156 ;; the result of the instruction can be used without introducing any stalls.
158 ;; ISSUE-DELAY is an integer that specifies the number of cycles after the
159 ;; instruction matching the TEST expression begins using this unit until a
160 ;; subsequent instruction can begin. A cost of N indicates an N-1 cycle delay.
161 ;; A subsequent instruction may also be delayed if an earlier instruction has a
162 ;; longer READY-DELAY value. This blocking effect is computed using the
163 ;; SIMULTANEITY, READY-DELAY, ISSUE-DELAY, and CONFLICT-LIST terms. For a
164 ;; normal non-pipelined function unit, SIMULTANEITY is one, the unit is taken
165 ;; to block for the READY-DELAY cycles of the executing insn, and smaller
166 ;; values of ISSUE-DELAY are ignored.
168 ;; CONFLICT-LIST is an optional list giving detailed conflict costs for this
169 ;; unit. If specified, it is a list of condition test expressions to be
170 ;; applied to insns chosen to execute in NAME following the particular insn
171 ;; matching TEST that is already executing in NAME. For each insn in the list,
172 ;; ISSUE-DELAY specifies the conflict cost; for insns not in the list, the cost
173 ;; is zero. If not specified, CONFLICT-LIST defaults to all instructions that
174 ;; use the function unit.
176 ;; Typical uses of this vector are where a floating point function unit can
177 ;; pipeline either single- or double-precision operations, but not both, or
178 ;; where a memory unit can pipeline loads, but not stores, etc.
180 ;; As an example, consider a classic RISC machine where the result of a load
181 ;; instruction is not available for two cycles (a single "delay" instruction is
182 ;; required) and where only one load instruction can be executed
183 ;; simultaneously. This would be specified as:
185 ;; (define_function_unit "memory" 1 1 (eq_attr "type" "load") 2 0)
187 ;; For the case of a floating point function unit that can pipeline
188 ;; either single or double precision, but not both, the following could be
191 ;; (define_function_unit "fp" 1 0
192 ;; (eq_attr "type" "sp_fp") 4 4
193 ;; [(eq_attr "type" "dp_fp")])
195 ;; (define_function_unit "fp" 1 0
196 ;; (eq_attr "type" "dp_fp") 4 4
197 ;; [(eq_attr "type" "sp_fp")])
199 ;; Note: The scheduler attempts to avoid function unit conflicts and uses all
200 ;; the specifications in the `define_function_unit' expression. It has
201 ;; recently come to our attention that these specifications may not allow
202 ;; modeling of some of the newer "superscalar" processors that have insns using
203 ;; multiple pipelined units. These insns will cause a potential conflict for
204 ;; the second unit used during their execution and there is no way of
205 ;; representing that conflict. We welcome any examples of how function unit
206 ;; conflicts work in such processors and suggestions for their representation.
208 ;; Function units of the M32R
209 ;; Units that take one cycle do not need to be specified.
211 ;; (define_function_unit {name} {multiplicity} {simultaneity} {test}
212 ;; {ready-delay} {issue-delay} [{conflict-list}])
214 ;; Hack to get GCC to better pack the instructions.
215 ;; We pretend there is a separate long function unit that conflicts with
216 ;; both the left and right 16 bit insn slots.
218 (define_function_unit "short" 2 2
219 (and (eq_attr "m32r" "yes")
220 (and (eq_attr "insn_size" "short")
221 (eq_attr "type" "!load2")))
223 [(eq_attr "insn_size" "long")])
225 (define_function_unit "short" 2 2 ;; load delay of 1 clock for mem execution + 1 clock for WB
226 (and (eq_attr "m32r" "yes")
227 (eq_attr "type" "load2"))
229 [(eq_attr "insn_size" "long")])
231 (define_function_unit "long" 1 1
232 (and (eq_attr "m32r" "yes")
233 (and (eq_attr "insn_size" "long")
234 (eq_attr "type" "!load4,load8")))
236 [(eq_attr "insn_size" "short")])
238 (define_function_unit "long" 1 1 ;; load delay of 1 clock for mem execution + 1 clock for WB
239 (and (eq_attr "m32r" "yes")
240 (and (eq_attr "insn_size" "long")
241 (eq_attr "type" "load4,load8")))
243 [(eq_attr "insn_size" "short")])
245 (define_function_unit "left" 1 1
246 (and (eq_attr "m32rx_pipeline" "o,either")
247 (eq_attr "type" "!load2"))
249 [(eq_attr "insn_size" "long")])
251 (define_function_unit "left" 1 1 ;; load delay of 1 clock for mem execution + 1 clock for WB
252 (and (eq_attr "m32rx_pipeline" "o,either")
253 (eq_attr "type" "load2"))
255 [(eq_attr "insn_size" "long")])
257 (define_function_unit "right" 1 1
258 (eq_attr "m32rx_pipeline" "s,either")
260 [(eq_attr "insn_size" "long")])
262 (define_function_unit "long" 1 1
263 (and (eq_attr "m32rx" "yes")
264 (and (eq_attr "insn_size" "long")
265 (eq_attr "type" "!load4,load8")))
267 [(eq_attr "insn_size" "short")])
269 (define_function_unit "long" 1 1 ;; load delay of 1 clock for mem execution + 1 clock for WB
270 (and (eq_attr "m32rx" "yes")
271 (and (eq_attr "insn_size" "long")
272 (eq_attr "type" "load4,load8")))
274 [(eq_attr "insn_size" "short")])
276 ;; Expand prologue as RTL
277 (define_expand "prologue"
282 m32r_expand_prologue ();
287 ;; Move instructions.
289 ;; For QI and HI moves, the register must contain the full properly
290 ;; sign-extended value. nonzero_bits assumes this [otherwise
291 ;; SHORT_IMMEDIATES_SIGN_EXTEND must be used, but the comment for it
292 ;; says it's a kludge and the .md files should be fixed instead].
294 (define_expand "movqi"
295 [(set (match_operand:QI 0 "general_operand" "")
296 (match_operand:QI 1 "general_operand" ""))]
300 /* Everything except mem = const or mem = mem can be done easily.
301 Objects in the small data area are handled too. */
303 if (GET_CODE (operands[0]) == MEM)
304 operands[1] = force_reg (QImode, operands[1]);
307 (define_insn "*movqi_insn"
308 [(set (match_operand:QI 0 "move_dest_operand" "=r,r,r,r,r,T,m")
309 (match_operand:QI 1 "move_src_operand" "r,I,JQR,T,m,r,r"))]
310 "register_operand (operands[0], QImode) || register_operand (operands[1], QImode)"
319 [(set_attr "type" "int2,int2,int4,load2,load4,store2,store4")
320 (set_attr "length" "2,2,4,2,4,2,4")])
322 (define_expand "movhi"
323 [(set (match_operand:HI 0 "general_operand" "")
324 (match_operand:HI 1 "general_operand" ""))]
328 /* Everything except mem = const or mem = mem can be done easily. */
330 if (GET_CODE (operands[0]) == MEM)
331 operands[1] = force_reg (HImode, operands[1]);
334 (define_insn "*movhi_insn"
335 [(set (match_operand:HI 0 "move_dest_operand" "=r,r,r,r,r,r,T,m")
336 (match_operand:HI 1 "move_src_operand" "r,I,JQR,K,T,m,r,r"))]
337 "register_operand (operands[0], HImode) || register_operand (operands[1], HImode)"
347 [(set_attr "type" "int2,int2,int4,int4,load2,load4,store2,store4")
348 (set_attr "length" "2,2,4,4,2,4,2,4")])
350 (define_expand "movsi_push"
351 [(set (mem:SI (pre_dec:SI (match_operand:SI 0 "register_operand" "")))
352 (match_operand:SI 1 "register_operand" ""))]
356 (define_expand "movsi_pop"
357 [(set (match_operand:SI 0 "register_operand" "")
358 (mem:SI (post_inc:SI (match_operand:SI 1 "register_operand" ""))))]
362 (define_expand "movsi"
363 [(set (match_operand:SI 0 "general_operand" "")
364 (match_operand:SI 1 "general_operand" ""))]
368 /* Everything except mem = const or mem = mem can be done easily. */
370 if (GET_CODE (operands[0]) == MEM)
371 operands[1] = force_reg (SImode, operands[1]);
373 /* Small Data Area reference? */
374 if (small_data_operand (operands[1], SImode))
376 emit_insn (gen_movsi_sda (operands[0], operands[1]));
380 /* If medium or large code model, symbols have to be loaded with
382 if (addr32_operand (operands[1], SImode))
384 emit_insn (gen_movsi_addr32 (operands[0], operands[1]));
389 ;; ??? Do we need a const_double constraint here for large unsigned values?
390 (define_insn "*movsi_insn"
391 [(set (match_operand:SI 0 "move_dest_operand" "=r,r,r,r,r,r,r,r,r,T,S,m")
392 (match_operand:SI 1 "move_src_operand" "r,I,J,MQ,L,n,T,U,m,r,r,r"))]
393 "register_operand (operands[0], SImode) || register_operand (operands[1], SImode)"
396 if (GET_CODE (operands[0]) == REG || GET_CODE (operands[1]) == SUBREG)
398 switch (GET_CODE (operands[1]))
410 if (GET_CODE (XEXP (operands[1], 0)) == POST_INC
411 && XEXP (XEXP (operands[1], 0), 0) == stack_pointer_rtx)
417 value = INTVAL (operands[1]);
419 return \"ldi %0,%#%1\\t; %X1\";
421 if (UINT24_P (value))
422 return \"ld24 %0,%#%1\\t; %X1\";
424 if (UPPER16_P (value))
425 return \"seth %0,%#%T1\\t; %X1\";
433 return \"ld24 %0,%#%1\";
439 else if (GET_CODE (operands[0]) == MEM
440 && (GET_CODE (operands[1]) == REG || GET_CODE (operands[1]) == SUBREG))
442 if (GET_CODE (XEXP (operands[0], 0)) == PRE_DEC
443 && XEXP (XEXP (operands[0], 0), 0) == stack_pointer_rtx)
451 [(set_attr "type" "int2,int2,int4,int4,int4,multi,load2,load2,load4,store2,store2,store4")
452 (set_attr "length" "2,2,4,4,4,8,2,2,4,2,2,4")])
454 ; Try to use a four byte / two byte pair for constants not loadable with
458 [(set (match_operand:SI 0 "register_operand" "")
459 (match_operand:SI 1 "two_insn_const_operand" ""))]
461 [(set (match_dup 0) (match_dup 2))
462 (set (match_dup 0) (ior:SI (match_dup 0) (match_dup 3)))]
465 unsigned HOST_WIDE_INT val = INTVAL (operands[1]);
466 unsigned HOST_WIDE_INT tmp;
469 /* In all cases we will emit two instructions. However we try to
470 use 2 byte instructions wherever possible. We can assume the
471 constant isn't loadable with any of ldi, ld24, or seth. */
473 /* See if we can load a 24 bit unsigned value and invert it. */
474 if (UINT24_P (~ val))
476 emit_insn (gen_movsi (operands[0], GEN_INT (~ val)));
477 emit_insn (gen_one_cmplsi2 (operands[0], operands[0]));
481 /* See if we can load a 24 bit unsigned value and shift it into place.
482 0x01fffffe is just beyond ld24's range. */
483 for (shift = 1, tmp = 0x01fffffe;
487 if ((val & ~tmp) == 0)
489 emit_insn (gen_movsi (operands[0], GEN_INT (val >> shift)));
490 emit_insn (gen_ashlsi3 (operands[0], operands[0], GEN_INT (shift)));
495 /* Can't use any two byte insn, fall back to seth/or3. Use ~0xffff instead
496 of 0xffff0000, since the later fails on a 64-bit host. */
497 operands[2] = GEN_INT ((val) & ~0xffff);
498 operands[3] = GEN_INT ((val) & 0xffff);
502 [(set (match_operand:SI 0 "register_operand" "")
503 (match_operand:SI 1 "seth_add3_operand" "i"))]
506 (high:SI (match_dup 1)))
508 (lo_sum:SI (match_dup 0)
512 ;; Small data area support.
513 ;; The address of _SDA_BASE_ is loaded into a register and all objects in
514 ;; the small data area are indexed off that. This is done for each reference
515 ;; but cse will clean things up for us. We let the compiler choose the
516 ;; register to use so we needn't allocate (and maybe even fix) a special
517 ;; register to use. Since the load and store insns have a 16 bit offset the
518 ;; total size of the data area can be 64K. However, if the data area lives
519 ;; above 16M (24 bits), _SDA_BASE_ will have to be loaded with seth/add3 which
520 ;; would then yield 3 instructions to reference an object [though there would
521 ;; be no net loss if two or more objects were referenced]. The 3 insns can be
522 ;; reduced back to 2 if the size of the small data area were reduced to 32K
523 ;; [then seth + ld/st would work for any object in the area]. Doing this
524 ;; would require special handling of _SDA_BASE_ (its value would be
525 ;; (.sdata + 32K) & 0xffff0000) and reloc computations would be different
526 ;; [I think]. What to do about this is deferred until later and for now we
527 ;; require .sdata to be in the first 16M.
529 (define_expand "movsi_sda"
531 (unspec [(const_int 0)] 2))
532 (set (match_operand:SI 0 "register_operand" "")
533 (lo_sum:SI (match_dup 2)
534 (match_operand:SI 1 "small_data_operand" "")))]
538 if (reload_in_progress || reload_completed)
539 operands[2] = operands[0];
541 operands[2] = gen_reg_rtx (SImode);
544 (define_insn "*load_sda_base"
545 [(set (match_operand:SI 0 "register_operand" "=r")
546 (unspec [(const_int 0)] 2))]
548 "ld24 %0,#_SDA_BASE_"
549 [(set_attr "type" "int4")
550 (set_attr "length" "4")])
552 ;; 32 bit address support.
554 (define_expand "movsi_addr32"
556 ; addr32_operand isn't used because it's too restrictive,
557 ; seth_add3_operand is more general and thus safer.
558 (high:SI (match_operand:SI 1 "seth_add3_operand" "")))
559 (set (match_operand:SI 0 "register_operand" "")
560 (lo_sum:SI (match_dup 2) (match_dup 1)))]
564 if (reload_in_progress || reload_completed)
565 operands[2] = operands[0];
567 operands[2] = gen_reg_rtx (SImode);
570 (define_insn "set_hi_si"
571 [(set (match_operand:SI 0 "register_operand" "=r")
572 (high:SI (match_operand 1 "symbolic_operand" "")))]
574 "seth %0,%#shigh(%1)"
575 [(set_attr "type" "int4")
576 (set_attr "length" "4")])
578 (define_insn "lo_sum_si"
579 [(set (match_operand:SI 0 "register_operand" "=r")
580 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
581 (match_operand:SI 2 "immediate_operand" "in")))]
584 [(set_attr "type" "int4")
585 (set_attr "length" "4")])
587 (define_expand "movdi"
588 [(set (match_operand:DI 0 "general_operand" "")
589 (match_operand:DI 1 "general_operand" ""))]
593 /* Everything except mem = const or mem = mem can be done easily. */
595 if (GET_CODE (operands[0]) == MEM)
596 operands[1] = force_reg (DImode, operands[1]);
599 (define_insn "*movdi_insn"
600 [(set (match_operand:DI 0 "move_dest_operand" "=r,r,r,r,m")
601 (match_operand:DI 1 "move_double_src_operand" "r,nG,F,m,r"))]
602 "register_operand (operands[0], DImode) || register_operand (operands[1], DImode)"
604 [(set_attr "type" "multi,multi,multi,load8,store8")
605 (set_attr "length" "4,4,16,6,6")])
608 [(set (match_operand:DI 0 "move_dest_operand" "")
609 (match_operand:DI 1 "move_double_src_operand" ""))]
612 "operands[2] = gen_split_move_double (operands);")
614 ;; Floating point move insns.
616 (define_expand "movsf"
617 [(set (match_operand:SF 0 "general_operand" "")
618 (match_operand:SF 1 "general_operand" ""))]
622 /* Everything except mem = const or mem = mem can be done easily. */
624 if (GET_CODE (operands[0]) == MEM)
625 operands[1] = force_reg (SFmode, operands[1]);
628 (define_insn "*movsf_insn"
629 [(set (match_operand:SF 0 "move_dest_operand" "=r,r,r,r,r,T,S,m")
630 (match_operand:SF 1 "move_src_operand" "r,F,U,S,m,r,r,r"))]
631 "register_operand (operands[0], SFmode) || register_operand (operands[1], SFmode)"
641 ;; ??? Length of alternative 1 is either 2, 4 or 8.
642 [(set_attr "type" "int2,multi,load2,load2,load4,store2,store2,store4")
643 (set_attr "length" "2,8,2,2,4,2,2,4")])
646 [(set (match_operand:SF 0 "register_operand" "")
647 (match_operand:SF 1 "const_double_operand" ""))]
649 [(set (match_dup 2) (match_dup 3))]
652 operands[2] = operand_subword (operands[0], 0, 0, SFmode);
653 operands[3] = operand_subword (operands[1], 0, 0, SFmode);
656 (define_expand "movdf"
657 [(set (match_operand:DF 0 "general_operand" "")
658 (match_operand:DF 1 "general_operand" ""))]
662 /* Everything except mem = const or mem = mem can be done easily. */
664 if (GET_CODE (operands[0]) == MEM)
665 operands[1] = force_reg (DFmode, operands[1]);
668 (define_insn "*movdf_insn"
669 [(set (match_operand:DF 0 "move_dest_operand" "=r,r,r,m")
670 (match_operand:DF 1 "move_double_src_operand" "r,F,m,r"))]
671 "register_operand (operands[0], DFmode) || register_operand (operands[1], DFmode)"
673 [(set_attr "type" "multi,multi,load8,store8")
674 (set_attr "length" "4,16,6,6")])
677 [(set (match_operand:DF 0 "move_dest_operand" "")
678 (match_operand:DF 1 "move_double_src_operand" ""))]
681 "operands[2] = gen_split_move_double (operands);")
683 ;; Zero extension instructions.
685 (define_insn "zero_extendqihi2"
686 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
687 (zero_extend:HI (match_operand:QI 1 "extend_operand" "r,T,m")))]
693 [(set_attr "type" "int4,load2,load4")
694 (set_attr "length" "4,2,4")])
696 (define_insn "zero_extendqisi2"
697 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
698 (zero_extend:SI (match_operand:QI 1 "extend_operand" "r,T,m")))]
704 [(set_attr "type" "int4,load2,load4")
705 (set_attr "length" "4,2,4")])
707 (define_insn "zero_extendhisi2"
708 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
709 (zero_extend:SI (match_operand:HI 1 "extend_operand" "r,T,m")))]
715 [(set_attr "type" "int4,load2,load4")
716 (set_attr "length" "4,2,4")])
718 ;; Signed conversions from a smaller integer to a larger integer
719 (define_insn "extendqihi2"
720 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
721 (sign_extend:HI (match_operand:QI 1 "extend_operand" "0,T,m")))]
727 [(set_attr "type" "multi,load2,load4")
728 (set_attr "length" "2,2,4")])
731 [(set (match_operand:HI 0 "register_operand" "")
732 (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
738 rtx op0 = gen_lowpart (SImode, operands[0]);
739 rtx shift = gen_rtx (CONST_INT, VOIDmode, 24);
741 operands[2] = gen_ashlsi3 (op0, op0, shift);
742 operands[3] = gen_ashrsi3 (op0, op0, shift);
745 (define_insn "extendqisi2"
746 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
747 (sign_extend:SI (match_operand:QI 1 "extend_operand" "0,T,m")))]
753 [(set_attr "type" "multi,load2,load4")
754 (set_attr "length" "4,2,4")])
757 [(set (match_operand:SI 0 "register_operand" "")
758 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
764 rtx op0 = gen_lowpart (SImode, operands[0]);
765 rtx shift = gen_rtx (CONST_INT, VOIDmode, 24);
767 operands[2] = gen_ashlsi3 (op0, op0, shift);
768 operands[3] = gen_ashrsi3 (op0, op0, shift);
771 (define_insn "extendhisi2"
772 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
773 (sign_extend:SI (match_operand:HI 1 "extend_operand" "0,T,m")))]
779 [(set_attr "type" "multi,load2,load4")
780 (set_attr "length" "4,2,4")])
783 [(set (match_operand:SI 0 "register_operand" "")
784 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
790 rtx op0 = gen_lowpart (SImode, operands[0]);
791 rtx shift = gen_rtx (CONST_INT, VOIDmode, 16);
793 operands[2] = gen_ashlsi3 (op0, op0, shift);
794 operands[3] = gen_ashrsi3 (op0, op0, shift);
797 ;; Arithmetic instructions.
799 ; ??? Adding an alternative to split add3 of small constants into two
800 ; insns yields better instruction packing but slower code. Adds of small
801 ; values is done a lot.
803 (define_insn "addsi3"
804 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
805 (plus:SI (match_operand:SI 1 "register_operand" "%0,0,r")
806 (match_operand:SI 2 "nonmemory_operand" "r,I,J")))]
812 [(set_attr "type" "int2,int2,int4")
813 (set_attr "length" "2,2,4")])
816 ; [(set (match_operand:SI 0 "register_operand" "")
817 ; (plus:SI (match_operand:SI 1 "register_operand" "")
818 ; (match_operand:SI 2 "int8_operand" "")))]
820 ; && REGNO (operands[0]) != REGNO (operands[1])
821 ; && INT8_P (INTVAL (operands[2]))
822 ; && INTVAL (operands[2]) != 0"
823 ; [(set (match_dup 0) (match_dup 1))
824 ; (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))]
827 (define_insn "adddi3"
828 [(set (match_operand:DI 0 "register_operand" "=r")
829 (plus:DI (match_operand:DI 1 "register_operand" "%0")
830 (match_operand:DI 2 "register_operand" "r")))
831 (clobber (reg:SI 17))]
834 [(set_attr "type" "multi")
835 (set_attr "length" "6")])
837 ;; ??? The cmp clears the condition bit. Can we speed up somehow?
839 [(set (match_operand:DI 0 "register_operand" "")
840 (plus:DI (match_operand:DI 1 "register_operand" "")
841 (match_operand:DI 2 "register_operand" "")))
842 (clobber (match_operand 3 "" ""))]
844 [(parallel [(set (match_dup 3)
846 (use (match_dup 4))])
847 (parallel [(set (match_dup 4)
848 (plus:SI (match_dup 4)
849 (plus:SI (match_dup 5)
852 (unspec [(const_int 0)] 3))])
853 (parallel [(set (match_dup 6)
854 (plus:SI (match_dup 6)
855 (plus:SI (match_dup 7)
858 (unspec [(const_int 0)] 3))])]
861 operands[4] = operand_subword (operands[0], (WORDS_BIG_ENDIAN != 0), 0, DImode);
862 operands[5] = operand_subword (operands[2], (WORDS_BIG_ENDIAN != 0), 0, DImode);
863 operands[6] = operand_subword (operands[0], (WORDS_BIG_ENDIAN == 0), 0, DImode);
864 operands[7] = operand_subword (operands[2], (WORDS_BIG_ENDIAN == 0), 0, DImode);
867 (define_insn "*clear_c"
870 (use (match_operand:SI 0 "register_operand" "r"))]
873 [(set_attr "type" "int2")
874 (set_attr "length" "2")])
876 (define_insn "*add_carry"
877 [(set (match_operand:SI 0 "register_operand" "=r")
878 (plus:SI (match_operand:SI 1 "register_operand" "%0")
879 (plus:SI (match_operand:SI 2 "register_operand" "r")
882 (unspec [(const_int 0)] 3))]
885 [(set_attr "type" "int2")
886 (set_attr "length" "2")])
888 (define_insn "subsi3"
889 [(set (match_operand:SI 0 "register_operand" "=r")
890 (minus:SI (match_operand:SI 1 "register_operand" "0")
891 (match_operand:SI 2 "register_operand" "r")))]
894 [(set_attr "type" "int2")
895 (set_attr "length" "2")])
897 (define_insn "subdi3"
898 [(set (match_operand:DI 0 "register_operand" "=r")
899 (minus:DI (match_operand:DI 1 "register_operand" "0")
900 (match_operand:DI 2 "register_operand" "r")))
901 (clobber (reg:SI 17))]
904 [(set_attr "type" "multi")
905 (set_attr "length" "6")])
907 ;; ??? The cmp clears the condition bit. Can we speed up somehow?
909 [(set (match_operand:DI 0 "register_operand" "")
910 (minus:DI (match_operand:DI 1 "register_operand" "")
911 (match_operand:DI 2 "register_operand" "")))
912 (clobber (match_operand 3 "" ""))]
914 [(parallel [(set (match_dup 3)
916 (use (match_dup 4))])
917 (parallel [(set (match_dup 4)
918 (minus:SI (match_dup 4)
919 (minus:SI (match_dup 5)
922 (unspec [(const_int 0)] 3))])
923 (parallel [(set (match_dup 6)
924 (minus:SI (match_dup 6)
925 (minus:SI (match_dup 7)
928 (unspec [(const_int 0)] 3))])]
931 operands[4] = operand_subword (operands[0], (WORDS_BIG_ENDIAN != 0), 0, DImode);
932 operands[5] = operand_subword (operands[2], (WORDS_BIG_ENDIAN != 0), 0, DImode);
933 operands[6] = operand_subword (operands[0], (WORDS_BIG_ENDIAN == 0), 0, DImode);
934 operands[7] = operand_subword (operands[2], (WORDS_BIG_ENDIAN == 0), 0, DImode);
937 (define_insn "*sub_carry"
938 [(set (match_operand:SI 0 "register_operand" "=r")
939 (minus:SI (match_operand:SI 1 "register_operand" "%0")
940 (minus:SI (match_operand:SI 2 "register_operand" "r")
943 (unspec [(const_int 0)] 3))]
946 [(set_attr "type" "int2")
947 (set_attr "length" "2")])
949 ; Multiply/Divide instructions.
951 (define_insn "mulhisi3"
952 [(set (match_operand:SI 0 "register_operand" "=r")
953 (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" "r"))
954 (sign_extend:SI (match_operand:HI 2 "register_operand" "r"))))]
956 "mullo %1,%2\;mvfacmi %0"
957 [(set_attr "type" "multi")
958 (set_attr "length" "4")])
960 (define_insn "mulsi3"
961 [(set (match_operand:SI 0 "register_operand" "=r")
962 (mult:SI (match_operand:SI 1 "register_operand" "%0")
963 (match_operand:SI 2 "register_operand" "r")))]
966 [(set_attr "type" "mul2")
967 (set_attr "length" "2")])
969 (define_insn "divsi3"
970 [(set (match_operand:SI 0 "register_operand" "=r")
971 (div:SI (match_operand:SI 1 "register_operand" "0")
972 (match_operand:SI 2 "register_operand" "r")))]
975 [(set_attr "type" "div4")
976 (set_attr "length" "4")])
978 (define_insn "udivsi3"
979 [(set (match_operand:SI 0 "register_operand" "=r")
980 (udiv:SI (match_operand:SI 1 "register_operand" "0")
981 (match_operand:SI 2 "register_operand" "r")))]
984 [(set_attr "type" "div4")
985 (set_attr "length" "4")])
987 (define_insn "modsi3"
988 [(set (match_operand:SI 0 "register_operand" "=r")
989 (mod:SI (match_operand:SI 1 "register_operand" "0")
990 (match_operand:SI 2 "register_operand" "r")))]
993 [(set_attr "type" "div4")
994 (set_attr "length" "4")])
996 (define_insn "umodsi3"
997 [(set (match_operand:SI 0 "register_operand" "=r")
998 (umod:SI (match_operand:SI 1 "register_operand" "0")
999 (match_operand:SI 2 "register_operand" "r")))]
1002 [(set_attr "type" "div4")
1003 (set_attr "length" "4")])
1005 ;; Boolean instructions.
1007 ;; We don't define the DImode versions as expand_binop does a good enough job.
1008 ;; And if it doesn't it should be fixed.
1010 (define_insn "andsi3"
1011 [(set (match_operand:SI 0 "register_operand" "=r,r")
1012 (and:SI (match_operand:SI 1 "register_operand" "%0,r")
1013 (match_operand:SI 2 "reg_or_uint16_operand" "r,K")))]
1017 /* If we are worried about space, see if we can break this up into two
1018 short instructions, which might eliminate a NOP being inserted. */
1020 && m32r_not_same_reg (operands[0], operands[1])
1021 && GET_CODE (operands[2]) == CONST_INT
1022 && INT8_P (INTVAL (operands[2])))
1025 else if (GET_CODE (operands[2]) == CONST_INT)
1026 return \"and3 %0,%1,%#%X2\";
1028 return \"and %0,%2\";
1030 [(set_attr "type" "int2,int4")
1031 (set_attr "length" "2,4")])
1034 [(set (match_operand:SI 0 "register_operand" "")
1035 (and:SI (match_operand:SI 1 "register_operand" "")
1036 (match_operand:SI 2 "int8_operand" "")))]
1037 "optimize_size && m32r_not_same_reg (operands[0], operands[1])"
1038 [(set (match_dup 0) (match_dup 2))
1039 (set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))]
1042 (define_insn "iorsi3"
1043 [(set (match_operand:SI 0 "register_operand" "=r,r")
1044 (ior:SI (match_operand:SI 1 "register_operand" "%0,r")
1045 (match_operand:SI 2 "reg_or_uint16_operand" "r,K")))]
1049 /* If we are worried about space, see if we can break this up into two
1050 short instructions, which might eliminate a NOP being inserted. */
1052 && m32r_not_same_reg (operands[0], operands[1])
1053 && GET_CODE (operands[2]) == CONST_INT
1054 && INT8_P (INTVAL (operands[2])))
1057 else if (GET_CODE (operands[2]) == CONST_INT)
1058 return \"or3 %0,%1,%#%X2\";
1060 return \"or %0,%2\";
1062 [(set_attr "type" "int2,int4")
1063 (set_attr "length" "2,4")])
1066 [(set (match_operand:SI 0 "register_operand" "")
1067 (ior:SI (match_operand:SI 1 "register_operand" "")
1068 (match_operand:SI 2 "int8_operand" "")))]
1069 "optimize_size && m32r_not_same_reg (operands[0], operands[1])"
1070 [(set (match_dup 0) (match_dup 2))
1071 (set (match_dup 0) (ior:SI (match_dup 0) (match_dup 1)))]
1074 (define_insn "xorsi3"
1075 [(set (match_operand:SI 0 "register_operand" "=r,r")
1076 (xor:SI (match_operand:SI 1 "register_operand" "%0,r")
1077 (match_operand:SI 2 "reg_or_uint16_operand" "r,K")))]
1081 /* If we are worried about space, see if we can break this up into two
1082 short instructions, which might eliminate a NOP being inserted. */
1084 && m32r_not_same_reg (operands[0], operands[1])
1085 && GET_CODE (operands[2]) == CONST_INT
1086 && INT8_P (INTVAL (operands[2])))
1089 else if (GET_CODE (operands[2]) == CONST_INT)
1090 return \"xor3 %0,%1,%#%X2\";
1092 return \"xor %0,%2\";
1094 [(set_attr "type" "int2,int4")
1095 (set_attr "length" "2,4")])
1098 [(set (match_operand:SI 0 "register_operand" "")
1099 (xor:SI (match_operand:SI 1 "register_operand" "")
1100 (match_operand:SI 2 "int8_operand" "")))]
1101 "optimize_size && m32r_not_same_reg (operands[0], operands[1])"
1102 [(set (match_dup 0) (match_dup 2))
1103 (set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))]
1106 (define_insn "negsi2"
1107 [(set (match_operand:SI 0 "register_operand" "=r")
1108 (neg:SI (match_operand:SI 1 "register_operand" "r")))]
1111 [(set_attr "type" "int2")
1112 (set_attr "length" "2")])
1114 (define_insn "one_cmplsi2"
1115 [(set (match_operand:SI 0 "register_operand" "=r")
1116 (not:SI (match_operand:SI 1 "register_operand" "r")))]
1119 [(set_attr "type" "int2")
1120 (set_attr "length" "2")])
1122 ;; Shift instructions.
1124 (define_insn "ashlsi3"
1125 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
1126 (ashift:SI (match_operand:SI 1 "register_operand" "0,0,r")
1127 (match_operand:SI 2 "reg_or_uint16_operand" "r,O,K")))]
1133 [(set_attr "type" "shift2,shift2,shift4")
1134 (set_attr "length" "2,2,4")])
1136 (define_insn "ashrsi3"
1137 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
1138 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0,r")
1139 (match_operand:SI 2 "reg_or_uint16_operand" "r,O,K")))]
1145 [(set_attr "type" "shift2,shift2,shift4")
1146 (set_attr "length" "2,2,4")])
1148 (define_insn "lshrsi3"
1149 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
1150 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0,0,r")
1151 (match_operand:SI 2 "reg_or_uint16_operand" "r,O,K")))]
1157 [(set_attr "type" "shift2,shift2,shift4")
1158 (set_attr "length" "2,2,4")])
1160 ;; Compare instructions.
1161 ;; This controls RTL generation and register allocation.
1163 ;; We generate RTL for comparisons and branches by having the cmpxx
1164 ;; patterns store away the operands. Then the bcc patterns
1165 ;; emit RTL for both the compare and the branch.
1167 ;; On the m32r it is more efficient to use the bxxz instructions and
1168 ;; thus merge the compare and branch into one instruction, so they are
1171 (define_expand "cmpsi"
1173 (compare:CC (match_operand:SI 0 "register_operand" "")
1174 (match_operand:SI 1 "reg_or_cmp_int16_operand" "")))]
1178 m32r_compare_op0 = operands[0];
1179 m32r_compare_op1 = operands[1];
1183 (define_insn "cmp_eqsi_zero_insn"
1185 (eq:SI (match_operand:SI 0 "register_operand" "r,r")
1186 (match_operand:SI 1 "reg_or_zero_operand" "r,P")))]
1187 "TARGET_M32RX || TARGET_M32R2"
1191 [(set_attr "type" "int4")
1192 (set_attr "length" "4")])
1194 ;; The cmp_xxx_insn patterns set the condition bit to the result of the
1195 ;; comparison. There isn't a "compare equal" instruction so cmp_eqsi_insn
1196 ;; is quite inefficient. However, it is rarely used.
1198 (define_insn "cmp_eqsi_insn"
1200 (eq:SI (match_operand:SI 0 "register_operand" "r,r")
1201 (match_operand:SI 1 "reg_or_cmp_int16_operand" "r,P")))
1202 (clobber (match_scratch:SI 2 "=&r,&r"))]
1206 if (which_alternative == 0)
1208 return \"mv %2,%0\;sub %2,%1\;cmpui %2,#1\";
1212 if (INTVAL (operands [1]) == 0)
1213 return \"cmpui %0, #1\";
1214 else if (REGNO (operands [2]) == REGNO (operands [0]))
1215 return \"addi %0,%#%N1\;cmpui %2,#1\";
1217 return \"add3 %2,%0,%#%N1\;cmpui %2,#1\";
1220 [(set_attr "type" "multi,multi")
1221 (set_attr "length" "8,8")])
1223 (define_insn "cmp_ltsi_insn"
1225 (lt:SI (match_operand:SI 0 "register_operand" "r,r")
1226 (match_operand:SI 1 "reg_or_int16_operand" "r,J")))]
1231 [(set_attr "type" "int2,int4")
1232 (set_attr "length" "2,4")])
1234 (define_insn "cmp_ltusi_insn"
1236 (ltu:SI (match_operand:SI 0 "register_operand" "r,r")
1237 (match_operand:SI 1 "reg_or_int16_operand" "r,J")))]
1242 [(set_attr "type" "int2,int4")
1243 (set_attr "length" "2,4")])
1246 ;; reg == small constant comparisons are best handled by putting the result
1247 ;; of the comparison in a tmp reg and then using beqz/bnez.
1248 ;; ??? The result register doesn't contain 0/STORE_FLAG_VALUE,
1249 ;; it contains 0/nonzero.
1251 (define_insn "cmp_ne_small_const_insn"
1252 [(set (match_operand:SI 0 "register_operand" "=r,r")
1253 (ne:SI (match_operand:SI 1 "register_operand" "0,r")
1254 (match_operand:SI 2 "cmp_int16_operand" "N,P")))]
1259 [(set_attr "type" "int2,int4")
1260 (set_attr "length" "2,4")])
1262 ;; These control RTL generation for conditional jump insns.
1264 (define_expand "beq"
1266 (if_then_else (match_dup 1)
1267 (label_ref (match_operand 0 "" ""))
1272 operands[1] = gen_compare (EQ, m32r_compare_op0, m32r_compare_op1, FALSE);
1275 (define_expand "bne"
1277 (if_then_else (match_dup 1)
1278 (label_ref (match_operand 0 "" ""))
1283 operands[1] = gen_compare (NE, m32r_compare_op0, m32r_compare_op1, FALSE);
1286 (define_expand "bgt"
1288 (if_then_else (match_dup 1)
1289 (label_ref (match_operand 0 "" ""))
1294 operands[1] = gen_compare (GT, m32r_compare_op0, m32r_compare_op1, FALSE);
1297 (define_expand "ble"
1299 (if_then_else (match_dup 1)
1300 (label_ref (match_operand 0 "" ""))
1305 operands[1] = gen_compare (LE, m32r_compare_op0, m32r_compare_op1, FALSE);
1308 (define_expand "bge"
1310 (if_then_else (match_dup 1)
1311 (label_ref (match_operand 0 "" ""))
1316 operands[1] = gen_compare (GE, m32r_compare_op0, m32r_compare_op1, FALSE);
1319 (define_expand "blt"
1321 (if_then_else (match_dup 1)
1322 (label_ref (match_operand 0 "" ""))
1327 operands[1] = gen_compare (LT, m32r_compare_op0, m32r_compare_op1, FALSE);
1330 (define_expand "bgtu"
1332 (if_then_else (match_dup 1)
1333 (label_ref (match_operand 0 "" ""))
1338 operands[1] = gen_compare (GTU, m32r_compare_op0, m32r_compare_op1, FALSE);
1341 (define_expand "bleu"
1343 (if_then_else (match_dup 1)
1344 (label_ref (match_operand 0 "" ""))
1349 operands[1] = gen_compare (LEU, m32r_compare_op0, m32r_compare_op1, FALSE);
1352 (define_expand "bgeu"
1354 (if_then_else (match_dup 1)
1355 (label_ref (match_operand 0 "" ""))
1360 operands[1] = gen_compare (GEU, m32r_compare_op0, m32r_compare_op1, FALSE);
1363 (define_expand "bltu"
1365 (if_then_else (match_dup 1)
1366 (label_ref (match_operand 0 "" ""))
1371 operands[1] = gen_compare (LTU, m32r_compare_op0, m32r_compare_op1, FALSE);
1374 ;; Now match both normal and inverted jump.
1376 (define_insn "*branch_insn"
1378 (if_then_else (match_operator 1 "eqne_comparison_operator"
1379 [(reg 17) (const_int 0)])
1380 (label_ref (match_operand 0 "" ""))
1385 static char instruction[40];
1386 sprintf (instruction, \"%s%s %%l0\",
1387 (GET_CODE (operands[1]) == NE) ? \"bc\" : \"bnc\",
1388 (get_attr_length (insn) == 2) ? \".s\" : \"\");
1391 [(set_attr "type" "branch")
1392 ; We use 400/800 instead of 512,1024 to account for inaccurate insn
1393 ; lengths and insn alignments that are complex to track.
1394 ; It's not important that we be hyper-precise here. It may be more
1395 ; important blah blah blah when the chip supports parallel execution
1396 ; blah blah blah but until then blah blah blah this is simple and
1398 (set (attr "length") (if_then_else (ltu (plus (minus (match_dup 0) (pc))
1404 (define_insn "*rev_branch_insn"
1406 (if_then_else (match_operator 1 "eqne_comparison_operator"
1407 [(reg 17) (const_int 0)])
1409 (label_ref (match_operand 0 "" ""))))]
1410 ;"REVERSIBLE_CC_MODE (GET_MODE (XEXP (operands[1], 0)))"
1414 static char instruction[40];
1415 sprintf (instruction, \"%s%s %%l0\",
1416 (GET_CODE (operands[1]) == EQ) ? \"bc\" : \"bnc\",
1417 (get_attr_length (insn) == 2) ? \".s\" : \"\");
1420 [(set_attr "type" "branch")
1421 ; We use 400/800 instead of 512,1024 to account for inaccurate insn
1422 ; lengths and insn alignments that are complex to track.
1423 ; It's not important that we be hyper-precise here. It may be more
1424 ; important blah blah blah when the chip supports parallel execution
1425 ; blah blah blah but until then blah blah blah this is simple and
1427 (set (attr "length") (if_then_else (ltu (plus (minus (match_dup 0) (pc))
1433 ; reg/reg compare and branch insns
1435 (define_insn "*reg_branch_insn"
1437 (if_then_else (match_operator 1 "eqne_comparison_operator"
1438 [(match_operand:SI 2 "register_operand" "r")
1439 (match_operand:SI 3 "register_operand" "r")])
1440 (label_ref (match_operand 0 "" ""))
1445 /* Is branch target reachable with beq/bne? */
1446 if (get_attr_length (insn) == 4)
1448 if (GET_CODE (operands[1]) == EQ)
1449 return \"beq %2,%3,%l0\";
1451 return \"bne %2,%3,%l0\";
1455 if (GET_CODE (operands[1]) == EQ)
1456 return \"bne %2,%3,1f\;bra %l0\;1:\";
1458 return \"beq %2,%3,1f\;bra %l0\;1:\";
1461 [(set_attr "type" "branch")
1462 ; We use 25000/50000 instead of 32768/65536 to account for slot filling
1463 ; which is complex to track and inaccurate length specs.
1464 (set (attr "length") (if_then_else (ltu (plus (minus (match_dup 0) (pc))
1470 (define_insn "*rev_reg_branch_insn"
1472 (if_then_else (match_operator 1 "eqne_comparison_operator"
1473 [(match_operand:SI 2 "register_operand" "r")
1474 (match_operand:SI 3 "register_operand" "r")])
1476 (label_ref (match_operand 0 "" ""))))]
1480 /* Is branch target reachable with beq/bne? */
1481 if (get_attr_length (insn) == 4)
1483 if (GET_CODE (operands[1]) == NE)
1484 return \"beq %2,%3,%l0\";
1486 return \"bne %2,%3,%l0\";
1490 if (GET_CODE (operands[1]) == NE)
1491 return \"bne %2,%3,1f\;bra %l0\;1:\";
1493 return \"beq %2,%3,1f\;bra %l0\;1:\";
1496 [(set_attr "type" "branch")
1497 ; We use 25000/50000 instead of 32768/65536 to account for slot filling
1498 ; which is complex to track and inaccurate length specs.
1499 (set (attr "length") (if_then_else (ltu (plus (minus (match_dup 0) (pc))
1505 ; reg/zero compare and branch insns
1507 (define_insn "*zero_branch_insn"
1509 (if_then_else (match_operator 1 "signed_comparison_operator"
1510 [(match_operand:SI 2 "register_operand" "r")
1512 (label_ref (match_operand 0 "" ""))
1517 const char *br,*invbr;
1520 switch (GET_CODE (operands[1]))
1522 case EQ : br = \"eq\"; invbr = \"ne\"; break;
1523 case NE : br = \"ne\"; invbr = \"eq\"; break;
1524 case LE : br = \"le\"; invbr = \"gt\"; break;
1525 case GT : br = \"gt\"; invbr = \"le\"; break;
1526 case LT : br = \"lt\"; invbr = \"ge\"; break;
1527 case GE : br = \"ge\"; invbr = \"lt\"; break;
1532 /* Is branch target reachable with bxxz? */
1533 if (get_attr_length (insn) == 4)
1535 sprintf (asmtext, \"b%sz %%2,%%l0\", br);
1536 output_asm_insn (asmtext, operands);
1540 sprintf (asmtext, \"b%sz %%2,1f\;bra %%l0\;1:\", invbr);
1541 output_asm_insn (asmtext, operands);
1545 [(set_attr "type" "branch")
1546 ; We use 25000/50000 instead of 32768/65536 to account for slot filling
1547 ; which is complex to track and inaccurate length specs.
1548 (set (attr "length") (if_then_else (ltu (plus (minus (match_dup 0) (pc))
1554 (define_insn "*rev_zero_branch_insn"
1556 (if_then_else (match_operator 1 "eqne_comparison_operator"
1557 [(match_operand:SI 2 "register_operand" "r")
1560 (label_ref (match_operand 0 "" ""))))]
1564 const char *br,*invbr;
1567 switch (GET_CODE (operands[1]))
1569 case EQ : br = \"eq\"; invbr = \"ne\"; break;
1570 case NE : br = \"ne\"; invbr = \"eq\"; break;
1571 case LE : br = \"le\"; invbr = \"gt\"; break;
1572 case GT : br = \"gt\"; invbr = \"le\"; break;
1573 case LT : br = \"lt\"; invbr = \"ge\"; break;
1574 case GE : br = \"ge\"; invbr = \"lt\"; break;
1579 /* Is branch target reachable with bxxz? */
1580 if (get_attr_length (insn) == 4)
1582 sprintf (asmtext, \"b%sz %%2,%%l0\", invbr);
1583 output_asm_insn (asmtext, operands);
1587 sprintf (asmtext, \"b%sz %%2,1f\;bra %%l0\;1:\", br);
1588 output_asm_insn (asmtext, operands);
1592 [(set_attr "type" "branch")
1593 ; We use 25000/50000 instead of 32768/65536 to account for slot filling
1594 ; which is complex to track and inaccurate length specs.
1595 (set (attr "length") (if_then_else (ltu (plus (minus (match_dup 0) (pc))
1601 ;; S<cc> operations to set a register to 1/0 based on a comparison
1603 (define_expand "seq"
1604 [(match_operand:SI 0 "register_operand" "")]
1608 rtx op0 = operands[0];
1609 rtx op1 = m32r_compare_op0;
1610 rtx op2 = m32r_compare_op1;
1611 enum machine_mode mode = GET_MODE (op0);
1616 if (! register_operand (op1, mode))
1617 op1 = force_reg (mode, op1);
1619 if (TARGET_M32RX || TARGET_M32R2)
1621 if (! reg_or_zero_operand (op2, mode))
1622 op2 = force_reg (mode, op2);
1624 emit_insn (gen_seq_insn_m32rx (op0, op1, op2));
1627 if (GET_CODE (op2) == CONST_INT && INTVAL (op2) == 0)
1629 emit_insn (gen_seq_zero_insn (op0, op1));
1633 if (! reg_or_eq_int16_operand (op2, mode))
1634 op2 = force_reg (mode, op2);
1636 emit_insn (gen_seq_insn (op0, op1, op2));
1640 (define_insn "seq_insn_m32rx"
1641 [(set (match_operand:SI 0 "register_operand" "=r")
1642 (eq:SI (match_operand:SI 1 "register_operand" "%r")
1643 (match_operand:SI 2 "reg_or_zero_operand" "rP")))
1644 (clobber (reg:SI 17))]
1645 "TARGET_M32RX || TARGET_M32R2"
1647 [(set_attr "type" "multi")
1648 (set_attr "length" "6")])
1651 [(set (match_operand:SI 0 "register_operand" "")
1652 (eq:SI (match_operand:SI 1 "register_operand" "")
1653 (match_operand:SI 2 "reg_or_zero_operand" "")))
1654 (clobber (reg:SI 17))]
1655 "TARGET_M32RX || TARGET_M32R2"
1657 (eq:SI (match_dup 1)
1663 (define_insn "seq_zero_insn"
1664 [(set (match_operand:SI 0 "register_operand" "=r")
1665 (eq:SI (match_operand:SI 1 "register_operand" "r")
1667 (clobber (reg:SI 17))]
1670 [(set_attr "type" "multi")
1671 (set_attr "length" "6")])
1674 [(set (match_operand:SI 0 "register_operand" "")
1675 (eq:SI (match_operand:SI 1 "register_operand" "")
1677 (clobber (reg:SI 17))]
1682 rtx op0 = operands[0];
1683 rtx op1 = operands[1];
1686 emit_insn (gen_cmp_ltusi_insn (op1, GEN_INT (1)));
1687 emit_insn (gen_movcc_insn (op0));
1688 operands[3] = get_insns ();
1692 (define_insn "seq_insn"
1693 [(set (match_operand:SI 0 "register_operand" "=r,r,??r,r")
1694 (eq:SI (match_operand:SI 1 "register_operand" "r,r,r,r")
1695 (match_operand:SI 2 "reg_or_eq_int16_operand" "r,r,r,PK")))
1696 (clobber (reg:SI 17))
1697 (clobber (match_scratch:SI 3 "=1,2,&r,r"))]
1700 [(set_attr "type" "multi")
1701 (set_attr "length" "8,8,10,10")])
1704 [(set (match_operand:SI 0 "register_operand" "")
1705 (eq:SI (match_operand:SI 1 "register_operand" "")
1706 (match_operand:SI 2 "reg_or_eq_int16_operand" "")))
1707 (clobber (reg:SI 17))
1708 (clobber (match_scratch:SI 3 ""))]
1709 "TARGET_M32R && reload_completed"
1713 rtx op0 = operands[0];
1714 rtx op1 = operands[1];
1715 rtx op2 = operands[2];
1716 rtx op3 = operands[3];
1717 HOST_WIDE_INT value;
1719 if (GET_CODE (op2) == REG && GET_CODE (op3) == REG
1720 && REGNO (op2) == REGNO (op3))
1727 if (GET_CODE (op1) == REG && GET_CODE (op3) == REG
1728 && REGNO (op1) != REGNO (op3))
1730 emit_move_insn (op3, op1);
1734 if (GET_CODE (op2) == CONST_INT && (value = INTVAL (op2)) != 0
1735 && CMP_INT16_P (value))
1736 emit_insn (gen_addsi3 (op3, op1, GEN_INT (-value)));
1738 emit_insn (gen_xorsi3 (op3, op1, op2));
1740 emit_insn (gen_cmp_ltusi_insn (op3, GEN_INT (1)));
1741 emit_insn (gen_movcc_insn (op0));
1742 operands[4] = get_insns ();
1746 (define_expand "sne"
1747 [(match_operand:SI 0 "register_operand" "")]
1751 rtx op0 = operands[0];
1752 rtx op1 = m32r_compare_op0;
1753 rtx op2 = m32r_compare_op1;
1754 enum machine_mode mode = GET_MODE (op0);
1759 if (GET_CODE (op2) != CONST_INT
1760 || (INTVAL (op2) != 0 && UINT16_P (INTVAL (op2))))
1764 if (reload_completed || reload_in_progress)
1767 reg = gen_reg_rtx (SImode);
1768 emit_insn (gen_xorsi3 (reg, op1, op2));
1771 if (! register_operand (op1, mode))
1772 op1 = force_reg (mode, op1);
1774 emit_insn (gen_sne_zero_insn (op0, op1));
1781 (define_insn "sne_zero_insn"
1782 [(set (match_operand:SI 0 "register_operand" "=r")
1783 (ne:SI (match_operand:SI 1 "register_operand" "r")
1785 (clobber (reg:SI 17))
1786 (clobber (match_scratch:SI 2 "=&r"))]
1789 [(set_attr "type" "multi")
1790 (set_attr "length" "6")])
1793 [(set (match_operand:SI 0 "register_operand" "")
1794 (ne:SI (match_operand:SI 1 "register_operand" "")
1796 (clobber (reg:SI 17))
1797 (clobber (match_scratch:SI 2 ""))]
1802 (ltu:SI (match_dup 2)
1808 (define_expand "slt"
1809 [(match_operand:SI 0 "register_operand" "")]
1813 rtx op0 = operands[0];
1814 rtx op1 = m32r_compare_op0;
1815 rtx op2 = m32r_compare_op1;
1816 enum machine_mode mode = GET_MODE (op0);
1821 if (! register_operand (op1, mode))
1822 op1 = force_reg (mode, op1);
1824 if (! reg_or_int16_operand (op2, mode))
1825 op2 = force_reg (mode, op2);
1827 emit_insn (gen_slt_insn (op0, op1, op2));
1831 (define_insn "slt_insn"
1832 [(set (match_operand:SI 0 "register_operand" "=r,r")
1833 (lt:SI (match_operand:SI 1 "register_operand" "r,r")
1834 (match_operand:SI 2 "reg_or_int16_operand" "r,J")))
1835 (clobber (reg:SI 17))]
1838 [(set_attr "type" "multi")
1839 (set_attr "length" "4,6")])
1842 [(set (match_operand:SI 0 "register_operand" "")
1843 (lt:SI (match_operand:SI 1 "register_operand" "")
1844 (match_operand:SI 2 "reg_or_int16_operand" "")))
1845 (clobber (reg:SI 17))]
1848 (lt:SI (match_dup 1)
1854 (define_expand "sle"
1855 [(match_operand:SI 0 "register_operand" "")]
1859 rtx op0 = operands[0];
1860 rtx op1 = m32r_compare_op0;
1861 rtx op2 = m32r_compare_op1;
1862 enum machine_mode mode = GET_MODE (op0);
1867 if (! register_operand (op1, mode))
1868 op1 = force_reg (mode, op1);
1870 if (GET_CODE (op2) == CONST_INT)
1872 HOST_WIDE_INT value = INTVAL (op2);
1873 if (value >= 2147483647)
1875 emit_move_insn (op0, GEN_INT (1));
1879 op2 = GEN_INT (value+1);
1880 if (value < -32768 || value >= 32767)
1881 op2 = force_reg (mode, op2);
1883 emit_insn (gen_slt_insn (op0, op1, op2));
1887 if (! register_operand (op2, mode))
1888 op2 = force_reg (mode, op2);
1890 emit_insn (gen_sle_insn (op0, op1, op2));
1894 (define_insn "sle_insn"
1895 [(set (match_operand:SI 0 "register_operand" "=r")
1896 (le:SI (match_operand:SI 1 "register_operand" "r")
1897 (match_operand:SI 2 "register_operand" "r")))
1898 (clobber (reg:SI 17))]
1901 [(set_attr "type" "multi")
1902 (set_attr "length" "8")])
1905 [(set (match_operand:SI 0 "register_operand" "")
1906 (le:SI (match_operand:SI 1 "register_operand" "")
1907 (match_operand:SI 2 "register_operand" "")))
1908 (clobber (reg:SI 17))]
1911 (lt:SI (match_dup 2)
1916 (xor:SI (match_dup 0)
1920 ;; If optimizing for space, use -(reg - 1) to invert the comparison rather than
1921 ;; xor reg,reg,1 which might eliminate a NOP being inserted.
1923 [(set (match_operand:SI 0 "register_operand" "")
1924 (le:SI (match_operand:SI 1 "register_operand" "")
1925 (match_operand:SI 2 "register_operand" "")))
1926 (clobber (reg:SI 17))]
1929 (lt:SI (match_dup 2)
1934 (plus:SI (match_dup 0)
1937 (neg:SI (match_dup 0)))]
1940 (define_expand "sgt"
1941 [(match_operand:SI 0 "register_operand" "")]
1945 rtx op0 = operands[0];
1946 rtx op1 = m32r_compare_op0;
1947 rtx op2 = m32r_compare_op1;
1948 enum machine_mode mode = GET_MODE (op0);
1953 if (! register_operand (op1, mode))
1954 op1 = force_reg (mode, op1);
1956 if (! register_operand (op2, mode))
1957 op2 = force_reg (mode, op2);
1959 emit_insn (gen_slt_insn (op0, op2, op1));
1963 (define_expand "sge"
1964 [(match_operand:SI 0 "register_operand" "")]
1968 rtx op0 = operands[0];
1969 rtx op1 = m32r_compare_op0;
1970 rtx op2 = m32r_compare_op1;
1971 enum machine_mode mode = GET_MODE (op0);
1976 if (! register_operand (op1, mode))
1977 op1 = force_reg (mode, op1);
1979 if (! reg_or_int16_operand (op2, mode))
1980 op2 = force_reg (mode, op2);
1982 emit_insn (gen_sge_insn (op0, op1, op2));
1986 (define_insn "sge_insn"
1987 [(set (match_operand:SI 0 "register_operand" "=r,r")
1988 (ge:SI (match_operand:SI 1 "register_operand" "r,r")
1989 (match_operand:SI 2 "reg_or_int16_operand" "r,J")))
1990 (clobber (reg:SI 17))]
1993 [(set_attr "type" "multi")
1994 (set_attr "length" "8,10")])
1997 [(set (match_operand:SI 0 "register_operand" "")
1998 (ge:SI (match_operand:SI 1 "register_operand" "")
1999 (match_operand:SI 2 "reg_or_int16_operand" "")))
2000 (clobber (reg:SI 17))]
2003 (lt:SI (match_dup 1)
2008 (xor:SI (match_dup 0)
2012 ;; If optimizing for space, use -(reg - 1) to invert the comparison rather than
2013 ;; xor reg,reg,1 which might eliminate a NOP being inserted.
2015 [(set (match_operand:SI 0 "register_operand" "")
2016 (ge:SI (match_operand:SI 1 "register_operand" "")
2017 (match_operand:SI 2 "reg_or_int16_operand" "")))
2018 (clobber (reg:SI 17))]
2021 (lt:SI (match_dup 1)
2026 (plus:SI (match_dup 0)
2029 (neg:SI (match_dup 0)))]
2032 (define_expand "sltu"
2033 [(match_operand:SI 0 "register_operand" "")]
2037 rtx op0 = operands[0];
2038 rtx op1 = m32r_compare_op0;
2039 rtx op2 = m32r_compare_op1;
2040 enum machine_mode mode = GET_MODE (op0);
2045 if (! register_operand (op1, mode))
2046 op1 = force_reg (mode, op1);
2048 if (! reg_or_int16_operand (op2, mode))
2049 op2 = force_reg (mode, op2);
2051 emit_insn (gen_sltu_insn (op0, op1, op2));
2055 (define_insn "sltu_insn"
2056 [(set (match_operand:SI 0 "register_operand" "=r,r")
2057 (ltu:SI (match_operand:SI 1 "register_operand" "r,r")
2058 (match_operand:SI 2 "reg_or_int16_operand" "r,J")))
2059 (clobber (reg:SI 17))]
2062 [(set_attr "type" "multi")
2063 (set_attr "length" "6,8")])
2066 [(set (match_operand:SI 0 "register_operand" "")
2067 (ltu:SI (match_operand:SI 1 "register_operand" "")
2068 (match_operand:SI 2 "reg_or_int16_operand" "")))
2069 (clobber (reg:SI 17))]
2072 (ltu:SI (match_dup 1)
2078 (define_expand "sleu"
2079 [(match_operand:SI 0 "register_operand" "")]
2083 rtx op0 = operands[0];
2084 rtx op1 = m32r_compare_op0;
2085 rtx op2 = m32r_compare_op1;
2086 enum machine_mode mode = GET_MODE (op0);
2091 if (GET_CODE (op2) == CONST_INT)
2093 HOST_WIDE_INT value = INTVAL (op2);
2094 if (value >= 2147483647)
2096 emit_move_insn (op0, GEN_INT (1));
2100 op2 = GEN_INT (value+1);
2101 if (value < 0 || value >= 32767)
2102 op2 = force_reg (mode, op2);
2104 emit_insn (gen_sltu_insn (op0, op1, op2));
2108 if (! register_operand (op2, mode))
2109 op2 = force_reg (mode, op2);
2111 emit_insn (gen_sleu_insn (op0, op1, op2));
2115 (define_insn "sleu_insn"
2116 [(set (match_operand:SI 0 "register_operand" "=r")
2117 (leu:SI (match_operand:SI 1 "register_operand" "r")
2118 (match_operand:SI 2 "register_operand" "r")))
2119 (clobber (reg:SI 17))]
2122 [(set_attr "type" "multi")
2123 (set_attr "length" "8")])
2126 [(set (match_operand:SI 0 "register_operand" "")
2127 (leu:SI (match_operand:SI 1 "register_operand" "")
2128 (match_operand:SI 2 "register_operand" "")))
2129 (clobber (reg:SI 17))]
2132 (ltu:SI (match_dup 2)
2137 (xor:SI (match_dup 0)
2141 ;; If optimizing for space, use -(reg - 1) to invert the comparison rather than
2142 ;; xor reg,reg,1 which might eliminate a NOP being inserted.
2144 [(set (match_operand:SI 0 "register_operand" "")
2145 (leu:SI (match_operand:SI 1 "register_operand" "")
2146 (match_operand:SI 2 "register_operand" "")))
2147 (clobber (reg:SI 17))]
2150 (ltu:SI (match_dup 2)
2155 (plus:SI (match_dup 0)
2158 (neg:SI (match_dup 0)))]
2161 (define_expand "sgtu"
2162 [(match_operand:SI 0 "register_operand" "")]
2166 rtx op0 = operands[0];
2167 rtx op1 = m32r_compare_op0;
2168 rtx op2 = m32r_compare_op1;
2169 enum machine_mode mode = GET_MODE (op0);
2174 if (! register_operand (op1, mode))
2175 op1 = force_reg (mode, op1);
2177 if (! register_operand (op2, mode))
2178 op2 = force_reg (mode, op2);
2180 emit_insn (gen_sltu_insn (op0, op2, op1));
2184 (define_expand "sgeu"
2185 [(match_operand:SI 0 "register_operand" "")]
2189 rtx op0 = operands[0];
2190 rtx op1 = m32r_compare_op0;
2191 rtx op2 = m32r_compare_op1;
2192 enum machine_mode mode = GET_MODE (op0);
2197 if (! register_operand (op1, mode))
2198 op1 = force_reg (mode, op1);
2200 if (! reg_or_int16_operand (op2, mode))
2201 op2 = force_reg (mode, op2);
2203 emit_insn (gen_sgeu_insn (op0, op1, op2));
2207 (define_insn "sgeu_insn"
2208 [(set (match_operand:SI 0 "register_operand" "=r,r")
2209 (geu:SI (match_operand:SI 1 "register_operand" "r,r")
2210 (match_operand:SI 2 "reg_or_int16_operand" "r,J")))
2211 (clobber (reg:SI 17))]
2214 [(set_attr "type" "multi")
2215 (set_attr "length" "8,10")])
2218 [(set (match_operand:SI 0 "register_operand" "")
2219 (geu:SI (match_operand:SI 1 "register_operand" "")
2220 (match_operand:SI 2 "reg_or_int16_operand" "")))
2221 (clobber (reg:SI 17))]
2224 (ltu:SI (match_dup 1)
2229 (xor:SI (match_dup 0)
2233 ;; If optimizing for space, use -(reg - 1) to invert the comparison rather than
2234 ;; xor reg,reg,1 which might eliminate a NOP being inserted.
2236 [(set (match_operand:SI 0 "register_operand" "")
2237 (geu:SI (match_operand:SI 1 "register_operand" "")
2238 (match_operand:SI 2 "reg_or_int16_operand" "")))
2239 (clobber (reg:SI 17))]
2242 (ltu:SI (match_dup 1)
2247 (plus:SI (match_dup 0)
2250 (neg:SI (match_dup 0)))]
2253 (define_insn "movcc_insn"
2254 [(set (match_operand:SI 0 "register_operand" "=r")
2258 [(set_attr "type" "misc")
2259 (set_attr "length" "2")])
2262 ;; Unconditional and other jump instructions.
2265 [(set (pc) (label_ref (match_operand 0 "" "")))]
2268 [(set_attr "type" "uncond_branch")
2269 (set (attr "length") (if_then_else (ltu (plus (minus (match_dup 0) (pc))
2275 (define_insn "indirect_jump"
2276 [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
2279 [(set_attr "type" "uncond_branch")
2280 (set_attr "length" "2")])
2282 (define_insn "return"
2286 [(set_attr "type" "uncond_branch")
2287 (set_attr "length" "2")])
2289 (define_insn "tablejump"
2290 [(set (pc) (match_operand:SI 0 "address_operand" "p"))
2291 (use (label_ref (match_operand 1 "" "")))]
2294 [(set_attr "type" "uncond_branch")
2295 (set_attr "length" "2")])
2297 (define_expand "call"
2298 ;; operands[1] is stack_size_rtx
2299 ;; operands[2] is next_arg_register
2300 [(parallel [(call (match_operand:SI 0 "call_operand" "")
2301 (match_operand 1 "" ""))
2302 (clobber (reg:SI 14))])]
2306 (define_insn "*call_via_reg"
2307 [(call (mem:SI (match_operand:SI 0 "register_operand" "r"))
2308 (match_operand 1 "" ""))
2309 (clobber (reg:SI 14))]
2312 [(set_attr "type" "call")
2313 (set_attr "length" "2")])
2315 (define_insn "*call_via_label"
2316 [(call (mem:SI (match_operand:SI 0 "call_address_operand" ""))
2317 (match_operand 1 "" ""))
2318 (clobber (reg:SI 14))]
2322 int call26_p = call26_operand (operands[0], FUNCTION_MODE);
2326 /* We may not be able to reach with a `bl' insn so punt and leave it to
2328 We do this here, rather than doing a force_reg in the define_expand
2329 so these insns won't be separated, say by scheduling, thus simplifying
2331 return \"seth r14,%T0\;add3 r14,r14,%B0\;jl r14\";
2336 [(set_attr "type" "call")
2337 (set (attr "length")
2338 (if_then_else (eq (symbol_ref "call26_operand (operands[0], FUNCTION_MODE)")
2340 (const_int 12) ; 10 + 2 for nop filler
2341 ; The return address must be on a 4 byte boundary so
2342 ; there's no point in using a value of 2 here. A 2 byte
2343 ; insn may go in the left slot but we currently can't
2344 ; use such knowledge.
2347 (define_expand "call_value"
2348 ;; operand 2 is stack_size_rtx
2349 ;; operand 3 is next_arg_register
2350 [(parallel [(set (match_operand 0 "register_operand" "=r")
2351 (call (match_operand:SI 1 "call_operand" "")
2352 (match_operand 2 "" "")))
2353 (clobber (reg:SI 14))])]
2357 (define_insn "*call_value_via_reg"
2358 [(set (match_operand 0 "register_operand" "=r")
2359 (call (mem:SI (match_operand:SI 1 "register_operand" "r"))
2360 (match_operand 2 "" "")))
2361 (clobber (reg:SI 14))]
2364 [(set_attr "type" "call")
2365 (set_attr "length" "2")])
2367 (define_insn "*call_value_via_label"
2368 [(set (match_operand 0 "register_operand" "=r")
2369 (call (mem:SI (match_operand:SI 1 "call_address_operand" ""))
2370 (match_operand 2 "" "")))
2371 (clobber (reg:SI 14))]
2375 int call26_p = call26_operand (operands[1], FUNCTION_MODE);
2379 /* We may not be able to reach with a `bl' insn so punt and leave it to
2381 We do this here, rather than doing a force_reg in the define_expand
2382 so these insns won't be separated, say by scheduling, thus simplifying
2384 return \"seth r14,%T1\;add3 r14,r14,%B1\;jl r14\";
2389 [(set_attr "type" "call")
2390 (set (attr "length")
2391 (if_then_else (eq (symbol_ref "call26_operand (operands[1], FUNCTION_MODE)")
2393 (const_int 12) ; 10 + 2 for nop filler
2394 ; The return address must be on a 4 byte boundary so
2395 ; there's no point in using a value of 2 here. A 2 byte
2396 ; insn may go in the left slot but we currently can't
2397 ; use such knowledge.
2404 [(set_attr "type" "int2")
2405 (set_attr "length" "2")])
2407 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
2408 ;; all of memory. This blocks insns from being moved across this point.
2410 (define_insn "blockage"
2411 [(unspec_volatile [(const_int 0)] 0)]
2415 ;; Special pattern to flush the icache.
2417 (define_insn "flush_icache"
2418 [(unspec_volatile [(match_operand 0 "memory_operand" "m")] 0)]
2420 "* return \"nop ; flush-icache\";"
2421 [(set_attr "type" "int2")
2422 (set_attr "length" "2")])
2424 ;; Speed up fabs and provide correct sign handling for -0
2426 (define_insn "absdf2"
2427 [(set (match_operand:DF 0 "register_operand" "=r")
2428 (abs:DF (match_operand:DF 1 "register_operand" "0")))]
2431 [(set_attr "type" "multi")
2432 (set_attr "length" "4")])
2435 [(set (match_operand:DF 0 "register_operand" "")
2436 (abs:DF (match_operand:DF 1 "register_operand" "")))]
2439 (ashift:SI (match_dup 2)
2442 (lshiftrt:SI (match_dup 2)
2444 "operands[2] = gen_highpart (SImode, operands[0]);")
2446 (define_insn "abssf2"
2447 [(set (match_operand:SF 0 "register_operand" "=r")
2448 (abs:SF (match_operand:SF 1 "register_operand" "0")))]
2451 [(set_attr "type" "multi")
2452 (set_attr "length" "4")])
2455 [(set (match_operand:SF 0 "register_operand" "")
2456 (abs:SF (match_operand:SF 1 "register_operand" "")))]
2459 (ashift:SI (match_dup 2)
2462 (lshiftrt:SI (match_dup 2)
2464 "operands[2] = gen_highpart (SImode, operands[0]);")
2466 ;; Conditional move instructions
2467 ;; Based on those done for the d10v
2469 (define_expand "movsicc"
2471 (set (match_operand:SI 0 "register_operand" "r")
2472 (if_then_else:SI (match_operand 1 "" "")
2473 (match_operand:SI 2 "conditional_move_operand" "O")
2474 (match_operand:SI 3 "conditional_move_operand" "O")
2481 if (! zero_and_one (operands [2], operands [3]))
2484 /* Generate the comparison that will set the carry flag. */
2485 operands[1] = gen_compare (GET_CODE (operands[1]), m32r_compare_op0,
2486 m32r_compare_op1, TRUE);
2488 /* See other movsicc pattern below for reason why. */
2489 emit_insn (gen_blockage ());
2492 ;; Generate the conditional instructions based on how the carry flag is examined.
2493 (define_insn "*movsicc_internal"
2494 [(set (match_operand:SI 0 "register_operand" "=r")
2495 (if_then_else:SI (match_operand 1 "carry_compare_operand" "")
2496 (match_operand:SI 2 "conditional_move_operand" "O")
2497 (match_operand:SI 3 "conditional_move_operand" "O")
2500 "zero_and_one (operands [2], operands[3])"
2501 "* return emit_cond_move (operands, insn);"
2502 [(set_attr "type" "multi")
2503 (set_attr "length" "8")
2508 ;; Split up troublesome insns for better scheduling.
2509 ;; FIXME: Peepholes go at the end.
2511 ;; ??? Setting the type attribute may not be useful, but for completeness
2515 [(set (mem:SI (plus:SI (match_operand:SI 0 "register_operand" "r")
2517 (match_operand:SI 1 "register_operand" "r"))]
2518 "0 && dead_or_set_p (insn, operands[0])"
2520 [(set_attr "type" "store2")
2521 (set_attr "length" "2")])
2523 ;; This case is triggered by compiling this code:
2525 ;; extern void sub(int *);
2529 ;; while (i < j) sub(&k);
2536 ;; Without the peephole the following assembler is generated for the
2537 ;; divide and subtract expressions:
2544 ;; Similar code is produced for the subtract expression. With this
2545 ;; peephole the redundant move is eliminated.
2547 ;; This optimization only works if PRESERVE_DEATH_INFO_REGNO_P is
2548 ;; defined in m32r.h
2551 [(set (match_operand:SI 0 "register_operand" "r")
2552 (match_operand:SI 1 "register_operand" "r")
2554 (set (mem:SI (plus: SI (match_operand:SI 2 "register_operand" "r")
2555 (match_operand:SI 3 "immediate_operand" "J")))
2559 "0 && dead_or_set_p (insn, operands [0])"
2561 [(set_attr "type" "store4")
2562 (set_attr "length" "4")
2566 ;; Block moves, see m32r.c for more details.
2567 ;; Argument 0 is the destination
2568 ;; Argument 1 is the source
2569 ;; Argument 2 is the length
2570 ;; Argument 3 is the alignment
2572 (define_expand "movstrsi"
2573 [(parallel [(set (match_operand:BLK 0 "general_operand" "")
2574 (match_operand:BLK 1 "general_operand" ""))
2575 (use (match_operand:SI 2 "immediate_operand" ""))
2576 (use (match_operand:SI 3 "immediate_operand" ""))])]
2580 if (operands[0]) /* avoid unused code messages */
2582 m32r_expand_block_move (operands);
2587 ;; Insn generated by block moves
2589 (define_insn "movstrsi_internal"
2590 [(set (mem:BLK (match_operand:SI 0 "register_operand" "+r")) ;; destination
2591 (mem:BLK (match_operand:SI 1 "register_operand" "+r"))) ;; source
2592 (use (match_operand:SI 2 "m32r_block_immediate_operand" "J"));; # bytes to move
2593 (set (match_dup 0) (plus:SI (match_dup 0) (minus:SI (match_dup 2) (const_int 4))))
2594 (set (match_dup 1) (plus:SI (match_dup 1) (match_dup 2)))
2595 (clobber (match_scratch:SI 3 "=&r")) ;; temp 1
2596 (clobber (match_scratch:SI 4 "=&r"))] ;; temp 2
2598 "* m32r_output_block_move (insn, operands); return \"\"; "
2599 [(set_attr "type" "store8")
2600 (set_attr "length" "72")]) ;; Maximum