1 ;; Machine description of the Renesas M32R cpu for GNU C compiler
2 ;; Copyright (C) 1996-2024 Free Software Foundation, Inc.
4 ;; This file is part of GCC.
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.
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.
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/>.
20 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
22 ;; UNSPEC_VOLATILE usage
25 (UNSPECV_FLUSH_ICACHE 1)])
29 [(UNSPEC_LOAD_SDA_BASE 2)
31 (UNSPEC_PIC_LOAD_ADDR 4)
36 ;; Insn type. Used to default other attribute values.
38 "int2,int4,load2,load4,load8,store2,store4,store8,shift2,shift4,mul2,div4,uncond_branch,branch,call,multi,misc"
39 (const_string "misc"))
42 (define_attr "length" ""
43 (cond [(eq_attr "type" "int2,load2,store2,shift2,mul2")
46 (eq_attr "type" "int4,load4,store4,shift4,div4")
49 (eq_attr "type" "multi")
52 (eq_attr "type" "uncond_branch,branch,call")
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")])
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")))
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")))
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")
91 (eq_attr "type" "mul2")
93 (const_string "long"))))
95 ;; ::::::::::::::::::::
97 ;; :: Pipeline description
99 ;; ::::::::::::::::::::
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.
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")
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.
117 ;; In reality there is only one decoder, which can decode either two 16-bit
118 ;; instructions, or a single 32-bit instruction.
120 ;; Note, "fetch" models both the IF and the D pipeline stages.
122 ;; The m32rx core has two execution pipes. We name them o_E and s_E.
123 ;; In addition, there's a memory unit.
125 (define_cpu_unit "o_IF,s_IF,o_E,s_E,memory" "m32r")
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")
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")
136 ;; ::::::::::::::::::::
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")))
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")))
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")))
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")))
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")))
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.
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")))
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")
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")
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")
200 (include "predicates.md")
201 (include "constraints.md")
203 ;; Expand prologue as RTL
204 (define_expand "prologue"
209 m32r_expand_prologue ();
213 ;; Expand epilogue as RTL
214 (define_expand "epilogue"
219 m32r_expand_epilogue ();
220 emit_jump_insn (gen_return_normal ());
224 ;; Move instructions.
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].
231 (define_expand "movqi"
232 [(set (match_operand:QI 0 "general_operand" "")
233 (match_operand:QI 1 "general_operand" ""))]
237 /* Fixup PIC cases. */
240 if (symbolic_operand (operands[1], QImode))
242 if (reload_in_progress || reload_completed)
243 operands[1] = m32r_legitimize_pic_address (operands[1], operands[0]);
245 operands[1] = m32r_legitimize_pic_address (operands[1], NULL_RTX);
249 /* Everything except mem = const or mem = mem can be done easily.
250 Objects in the small data area are handled too. */
252 if (MEM_P (operands[0]))
253 operands[1] = force_reg (QImode, operands[1]);
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)"
268 [(set_attr "type" "int2,int2,int4,load2,load4,store2,store4")
269 (set_attr "length" "2,2,4,2,4,2,4")])
271 (define_expand "movhi"
272 [(set (match_operand:HI 0 "general_operand" "")
273 (match_operand:HI 1 "general_operand" ""))]
277 /* Fixup PIC cases. */
280 if (symbolic_operand (operands[1], HImode))
282 if (reload_in_progress || reload_completed)
283 operands[1] = m32r_legitimize_pic_address (operands[1], operands[0]);
285 operands[1] = m32r_legitimize_pic_address (operands[1], NULL_RTX);
289 /* Everything except mem = const or mem = mem can be done easily. */
291 if (MEM_P (operands[0]))
292 operands[1] = force_reg (HImode, operands[1]);
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)"
308 [(set_attr "type" "int2,int2,int4,int4,load2,load4,store2,store4")
309 (set_attr "length" "2,2,4,4,2,4,2,4")])
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" ""))]
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" ""))))]
323 (define_expand "movsi"
324 [(set (match_operand:SI 0 "general_operand" "")
325 (match_operand:SI 1 "general_operand" ""))]
329 /* Fixup PIC cases. */
332 if (symbolic_operand (operands[1], SImode))
334 if (reload_in_progress || reload_completed)
335 operands[1] = m32r_legitimize_pic_address (operands[1], operands[0]);
337 operands[1] = m32r_legitimize_pic_address (operands[1], NULL_RTX);
341 /* Everything except mem = const or mem = mem can be done easily. */
343 if (MEM_P (operands[0]))
344 operands[1] = force_reg (SImode, operands[1]);
346 /* Small Data Area reference? */
347 if (small_data_operand (operands[1], SImode))
349 emit_insn (gen_movsi_sda (operands[0], operands[1]));
353 /* If medium or large code model, symbols have to be loaded with
355 if (addr32_operand (operands[1], SImode))
357 emit_insn (gen_movsi_addr32 (operands[0], operands[1]));
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)"
369 if (REG_P (operands[0]) || GET_CODE (operands[1]) == SUBREG)
371 switch (GET_CODE (operands[1]))
381 if (GET_CODE (XEXP (operands[1], 0)) == POST_INC
382 && XEXP (XEXP (operands[1], 0), 0) == stack_pointer_rtx)
388 if (satisfies_constraint_J (operands[1]))
389 return \"ldi %0,%#%1\\t; %X1\";
391 if (satisfies_constraint_M (operands[1]))
392 return \"ld24 %0,%#%1\\t; %X1\";
394 if (satisfies_constraint_L (operands[1]))
395 return \"seth %0,%#%T1\\t; %X1\";
403 return \"ld24 %0,%#%1\";
409 else if (MEM_P (operands[0])
410 && (REG_P (operands[1]) || GET_CODE (operands[1]) == SUBREG))
412 if (GET_CODE (XEXP (operands[0], 0)) == PRE_DEC
413 && XEXP (XEXP (operands[0], 0), 0) == stack_pointer_rtx)
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")])
424 ; Try to use a four byte / two byte pair for constants not loadable with
428 [(set (match_operand:SI 0 "register_operand" "")
429 (match_operand:SI 1 "two_insn_const_operand" ""))]
431 [(set (match_dup 0) (match_dup 2))
432 (set (match_dup 0) (ior:SI (match_dup 0) (match_dup 3)))]
435 unsigned HOST_WIDE_INT val = INTVAL (operands[1]);
436 unsigned HOST_WIDE_INT tmp;
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. */
443 /* See if we can load a 24-bit unsigned value and invert it. */
444 if (UINT24_P (~ val))
446 emit_insn (gen_movsi (operands[0], GEN_INT (~ val)));
447 emit_insn (gen_one_cmplsi2 (operands[0], operands[0]));
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;
457 if ((val & ~tmp) == 0)
459 emit_insn (gen_movsi (operands[0], GEN_INT (val >> shift)));
460 emit_insn (gen_ashlsi3 (operands[0], operands[0], GEN_INT (shift)));
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);
472 [(set (match_operand:SI 0 "register_operand" "")
473 (match_operand:SI 1 "seth_add3_operand" ""))]
476 (high:SI (match_dup 1)))
478 (lo_sum:SI (match_dup 0)
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.
499 (define_expand "movsi_sda"
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" "")))]
508 if (reload_in_progress || reload_completed)
509 operands[2] = operands[0];
511 operands[2] = gen_reg_rtx (SImode);
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))]
518 "seth %0,%#shigh(_SDA_BASE_)\;add3 %0,%0,%#low(_SDA_BASE_)"
519 [(set_attr "type" "multi")
520 (set_attr "length" "8")])
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))]
526 "ld24 %0,#_SDA_BASE_"
527 [(set_attr "type" "int4")
528 (set_attr "length" "4")])
530 ;; 32-bit address support.
532 (define_expand "movsi_addr32"
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)))]
542 if (reload_in_progress || reload_completed)
543 operands[2] = operands[0];
545 operands[2] = gen_reg_rtx (SImode);
548 (define_insn "set_hi_si"
549 [(set (match_operand:SI 0 "register_operand" "=r")
550 (high:SI (match_operand 1 "symbolic_operand" "")))]
552 "seth %0,%#shigh(%1)"
553 [(set_attr "type" "int4")
554 (set_attr "length" "4")])
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")))]
562 [(set_attr "type" "int4")
563 (set_attr "length" "4")])
565 (define_expand "movdi"
566 [(set (match_operand:DI 0 "general_operand" "")
567 (match_operand:DI 1 "general_operand" ""))]
571 /* Fixup PIC cases. */
574 if (symbolic_operand (operands[1], DImode))
576 if (reload_in_progress || reload_completed)
577 operands[1] = m32r_legitimize_pic_address (operands[1], operands[0]);
579 operands[1] = m32r_legitimize_pic_address (operands[1], NULL_RTX);
583 /* Everything except mem = const or mem = mem can be done easily. */
585 if (MEM_P (operands[0]))
586 operands[1] = force_reg (DImode, operands[1]);
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)"
594 [(set_attr "type" "multi,multi,multi,load8,store8")
595 (set_attr "length" "4,4,16,6,6")])
598 [(set (match_operand:DI 0 "move_dest_operand" "")
599 (match_operand:DI 1 "move_double_src_operand" ""))]
602 "operands[2] = gen_split_move_double (operands);")
604 ;; Floating point move insns.
606 (define_expand "movsf"
607 [(set (match_operand:SF 0 "general_operand" "")
608 (match_operand:SF 1 "general_operand" ""))]
612 /* Fixup PIC cases. */
615 if (symbolic_operand (operands[1], SFmode))
617 if (reload_in_progress || reload_completed)
618 operands[1] = m32r_legitimize_pic_address (operands[1], operands[0]);
620 operands[1] = m32r_legitimize_pic_address (operands[1], NULL_RTX);
624 /* Everything except mem = const or mem = mem can be done easily. */
626 if (MEM_P (operands[0]))
627 operands[1] = force_reg (SFmode, operands[1]);
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)"
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")])
648 [(set (match_operand:SF 0 "register_operand" "")
649 (match_operand:SF 1 "const_double_operand" ""))]
651 [(set (match_dup 2) (match_dup 3))]
654 operands[2] = operand_subword (operands[0], 0, 0, SFmode);
655 operands[3] = operand_subword (operands[1], 0, 0, SFmode);
658 (define_expand "movdf"
659 [(set (match_operand:DF 0 "general_operand" "")
660 (match_operand:DF 1 "general_operand" ""))]
664 /* Fixup PIC cases. */
667 if (symbolic_operand (operands[1], DFmode))
669 if (reload_in_progress || reload_completed)
670 operands[1] = m32r_legitimize_pic_address (operands[1], operands[0]);
672 operands[1] = m32r_legitimize_pic_address (operands[1], NULL_RTX);
676 /* Everything except mem = const or mem = mem can be done easily. */
678 if (MEM_P (operands[0]))
679 operands[1] = force_reg (DFmode, operands[1]);
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)"
687 [(set_attr "type" "multi,multi,load8,store8")
688 (set_attr "length" "4,16,6,6")])
691 [(set (match_operand:DF 0 "move_dest_operand" "")
692 (match_operand:DF 1 "move_double_src_operand" ""))]
695 "operands[2] = gen_split_move_double (operands);")
697 ;; Zero extension instructions.
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")))]
707 [(set_attr "type" "int4,load2,load4")
708 (set_attr "length" "4,2,4")])
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")))]
718 [(set_attr "type" "int4,load2,load4")
719 (set_attr "length" "4,2,4")])
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")))]
729 [(set_attr "type" "int4,load2,load4")
730 (set_attr "length" "4,2,4")])
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")))]
741 [(set_attr "type" "multi,load2,load4")
742 (set_attr "length" "2,2,4")])
745 [(set (match_operand:HI 0 "register_operand" "")
746 (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
752 rtx op0 = gen_lowpart (SImode, operands[0]);
753 rtx shift = GEN_INT (24);
755 operands[2] = gen_ashlsi3 (op0, op0, shift);
756 operands[3] = gen_ashrsi3 (op0, op0, shift);
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")))]
767 [(set_attr "type" "multi,load2,load4")
768 (set_attr "length" "4,2,4")])
771 [(set (match_operand:SI 0 "register_operand" "")
772 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
778 rtx shift = GEN_INT (24);
780 operands[2] = gen_ashlsi3 (operands[0], operands[0], shift);
781 operands[3] = gen_ashrsi3 (operands[0], operands[0], shift);
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")))]
792 [(set_attr "type" "multi,load2,load4")
793 (set_attr "length" "4,2,4")])
796 [(set (match_operand:SI 0 "register_operand" "")
797 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
803 rtx shift = GEN_INT (16);
805 operands[2] = gen_ashlsi3 (operands[0], operands[0], shift);
806 operands[3] = gen_ashrsi3 (operands[0], operands[0], shift);
809 ;; Arithmetic instructions.
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.
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")))]
824 [(set_attr "type" "int2,int2,int4")
825 (set_attr "length" "2,2,4")])
828 ; [(set (match_operand:SI 0 "register_operand" "")
829 ; (plus:SI (match_operand:SI 1 "register_operand" "")
830 ; (match_operand:SI 2 "int8_operand" "")))]
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)))]
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))]
846 [(set_attr "type" "multi")
847 (set_attr "length" "6")])
849 ;; ??? The cmp clears the condition bit. Can we speed up somehow?
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))]
856 [(parallel [(set (reg:CC 17)
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)))))
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)))))
870 (unspec:CC [(const_int 0)] UNSPEC_SET_CBIT))])]
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);
879 (define_insn "*clear_c"
882 (use (match_operand:SI 0 "register_operand" "r"))]
885 [(set_attr "type" "int2")
886 (set_attr "length" "2")])
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)))))
894 (unspec:CC [(const_int 0)] UNSPEC_SET_CBIT))]
897 [(set_attr "type" "int2")
898 (set_attr "length" "2")])
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")))]
906 [(set_attr "type" "int2")
907 (set_attr "length" "2")])
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))]
916 [(set_attr "type" "multi")
917 (set_attr "length" "6")])
919 ;; ??? The cmp clears the condition bit. Can we speed up somehow?
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))]
926 [(parallel [(set (reg:CC 17)
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)))))
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)))))
940 (unspec:CC [(const_int 0)] UNSPEC_SET_CBIT))])]
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);
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)))))
955 (unspec:CC [(const_int 0)] UNSPEC_SET_CBIT))]
958 [(set_attr "type" "int2")
959 (set_attr "length" "2")])
961 ; Multiply/Divide instructions.
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"))))]
968 "mullo %1,%2\;mvfacmi %0"
969 [(set_attr "type" "multi")
970 (set_attr "length" "4")])
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")))]
978 [(set_attr "type" "mul2")
979 (set_attr "length" "2")])
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")))]
987 [(set_attr "type" "div4")
988 (set_attr "length" "4")])
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")))]
996 [(set_attr "type" "div4")
997 (set_attr "length" "4")])
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")))]
1005 [(set_attr "type" "div4")
1006 (set_attr "length" "4")])
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")))]
1014 [(set_attr "type" "div4")
1015 (set_attr "length" "4")])
1017 ;; Boolean instructions.
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.
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")))]
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. */
1032 && m32r_not_same_reg (operands[0], operands[1])
1033 && satisfies_constraint_I (operands[2]))
1036 else if (CONST_INT_P (operands[2]))
1037 return \"and3 %0,%1,%#%X2\";
1039 return \"and %0,%2\";
1041 [(set_attr "type" "int2,int4")
1042 (set_attr "length" "2,4")])
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)))]
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")))]
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. */
1063 && m32r_not_same_reg (operands[0], operands[1])
1064 && satisfies_constraint_I (operands[2]))
1067 else if (CONST_INT_P (operands[2]))
1068 return \"or3 %0,%1,%#%X2\";
1070 return \"or %0,%2\";
1072 [(set_attr "type" "int2,int4")
1073 (set_attr "length" "2,4")])
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)))]
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")))]
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. */
1094 && m32r_not_same_reg (operands[0], operands[1])
1095 && satisfies_constraint_I (operands[2]))
1098 else if (CONST_INT_P (operands[2]))
1099 return \"xor3 %0,%1,%#%X2\";
1101 return \"xor %0,%2\";
1103 [(set_attr "type" "int2,int4")
1104 (set_attr "length" "2,4")])
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)))]
1115 (define_insn "negsi2"
1116 [(set (match_operand:SI 0 "register_operand" "=r")
1117 (neg:SI (match_operand:SI 1 "register_operand" "r")))]
1120 [(set_attr "type" "int2")
1121 (set_attr "length" "2")])
1123 (define_insn "one_cmplsi2"
1124 [(set (match_operand:SI 0 "register_operand" "=r")
1125 (not:SI (match_operand:SI 1 "register_operand" "r")))]
1128 [(set_attr "type" "int2")
1129 (set_attr "length" "2")])
1131 ;; Shift instructions.
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")))]
1142 [(set_attr "type" "shift2,shift2,shift4")
1143 (set_attr "length" "2,2,4")])
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")))]
1154 [(set_attr "type" "shift2,shift2,shift4")
1155 (set_attr "length" "2,2,4")])
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")))]
1166 [(set_attr "type" "shift2,shift2,shift4")
1167 (set_attr "length" "2,2,4")])
1169 ;; Compare instructions.
1170 ;; This controls RTL generation and register allocation.
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.
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
1180 (define_insn "cmp_eqsi_zero_insn"
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"
1188 [(set_attr "type" "int4")
1189 (set_attr "length" "4")])
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.
1195 (define_insn "cmp_eqsi_insn"
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"))]
1203 if (which_alternative == 0)
1205 return \"mv %2,%0\;sub %2,%1\;cmpui %2,#1\";
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\";
1214 return \"add3 %2,%0,%#%N1\;cmpui %2,#1\";
1217 [(set_attr "type" "multi,multi")
1218 (set_attr "length" "8,8")])
1220 (define_insn "cmp_ltsi_insn"
1222 (lt:CC (match_operand:SI 0 "register_operand" "r,r")
1223 (match_operand:SI 1 "reg_or_int16_operand" "r,J")))]
1228 [(set_attr "type" "int2,int4")
1229 (set_attr "length" "2,4")])
1231 (define_insn "cmp_ltusi_insn"
1233 (ltu:CC (match_operand:SI 0 "register_operand" "r,r")
1234 (match_operand:SI 1 "reg_or_int16_operand" "r,J")))]
1239 [(set_attr "type" "int2,int4")
1240 (set_attr "length" "2,4")])
1242 ;; These control RTL generation for conditional jump insns.
1244 (define_expand "cbranchsi4"
1245 ; the comparison is emitted by gen_compare if needed.
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 "" ""))
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);
1260 ;; Now match both normal and inverted jump.
1262 (define_insn "*branch_insn"
1264 (if_then_else (match_operator 1 "eqne_comparison_operator"
1265 [(reg 17) (const_int 0)])
1266 (label_ref (match_operand 0 "" ""))
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\" : \"\");
1277 [(set_attr "type" "branch")
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
1285 (set (attr "length") (if_then_else (ltu (plus (minus (match_dup 0) (pc))
1291 (define_insn "*rev_branch_insn"
1293 (if_then_else (match_operator 1 "eqne_comparison_operator"
1294 [(reg 17) (const_int 0)])
1296 (label_ref (match_operand 0 "" ""))))]
1297 ;"REVERSIBLE_CC_MODE (GET_MODE (XEXP (operands[1], 0)))"
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\" : \"\");
1307 [(set_attr "type" "branch")
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
1315 (set (attr "length") (if_then_else (ltu (plus (minus (match_dup 0) (pc))
1321 ; reg/reg compare and branch insns
1323 (define_insn "*reg_branch_insn"
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 "" ""))
1333 /* Is branch target reachable with beq/bne? */
1334 if (get_attr_length (insn) == 4)
1336 if (GET_CODE (operands[1]) == EQ)
1337 return \"beq %2,%3,%l0\";
1339 return \"bne %2,%3,%l0\";
1343 if (GET_CODE (operands[1]) == EQ)
1344 return \"bne %2,%3,1f\;bra %l0\;1:\";
1346 return \"beq %2,%3,1f\;bra %l0\;1:\";
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))
1358 (define_insn "*rev_reg_branch_insn"
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")])
1364 (label_ref (match_operand 0 "" ""))))]
1368 /* Is branch target reachable with beq/bne? */
1369 if (get_attr_length (insn) == 4)
1371 if (GET_CODE (operands[1]) == NE)
1372 return \"beq %2,%3,%l0\";
1374 return \"bne %2,%3,%l0\";
1378 if (GET_CODE (operands[1]) == NE)
1379 return \"bne %2,%3,1f\;bra %l0\;1:\";
1381 return \"beq %2,%3,1f\;bra %l0\;1:\";
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))
1393 ; reg/zero compare and branch insns
1395 (define_insn "*zero_branch_insn"
1397 (if_then_else (match_operator 1 "signed_comparison_operator"
1398 [(match_operand:SI 2 "register_operand" "r")
1400 (label_ref (match_operand 0 "" ""))
1405 const char *br,*invbr;
1408 switch (GET_CODE (operands[1]))
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;
1417 default: gcc_unreachable ();
1420 /* Is branch target reachable with bxxz? */
1421 if (get_attr_length (insn) == 4)
1423 sprintf (asmtext, \"b%sz %%2,%%l0\", br);
1424 output_asm_insn (asmtext, operands);
1428 sprintf (asmtext, \"b%sz %%2,1f\;bra %%l0\;1:\", invbr);
1429 output_asm_insn (asmtext, operands);
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))
1442 (define_insn "*rev_zero_branch_insn"
1444 (if_then_else (match_operator 1 "eqne_comparison_operator"
1445 [(match_operand:SI 2 "register_operand" "r")
1448 (label_ref (match_operand 0 "" ""))))]
1452 const char *br,*invbr;
1455 switch (GET_CODE (operands[1]))
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;
1464 default: gcc_unreachable ();
1467 /* Is branch target reachable with bxxz? */
1468 if (get_attr_length (insn) == 4)
1470 sprintf (asmtext, \"b%sz %%2,%%l0\", invbr);
1471 output_asm_insn (asmtext, operands);
1475 sprintf (asmtext, \"b%sz %%2,1f\;bra %%l0\;1:\", br);
1476 output_asm_insn (asmtext, operands);
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))
1489 ;; S<cc> operations to set a register to 1/0 based on a comparison
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" "")])]
1499 if (GET_MODE (operands[0]) != SImode)
1502 if (!gen_cond_store (GET_CODE (operands[1]),
1503 operands[0], operands[2], operands[3]))
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"
1516 [(set_attr "type" "multi")
1517 (set_attr "length" "6")])
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"
1526 (eq:CC (match_dup 1)
1529 (ne:SI (reg:CC 17) (const_int 0)))]
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")
1536 (clobber (reg:CC 17))]
1539 [(set_attr "type" "multi")
1540 (set_attr "length" "6")])
1543 [(set (match_operand:SI 0 "register_operand" "")
1544 (eq:SI (match_operand:SI 1 "register_operand" "")
1546 (clobber (reg:CC 17))]
1551 rtx op0 = operands[0];
1552 rtx op1 = operands[1];
1555 emit_insn (gen_cmp_ltusi_insn (op1, const1_rtx));
1556 emit_insn (gen_movcc_insn (op0));
1557 operands[3] = get_insns ();
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"))]
1569 [(set_attr "type" "multi")
1570 (set_attr "length" "8,8,10,10")])
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"
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;
1588 if (REG_P (op2) && REG_P (op3)
1589 && REGNO (op2) == REGNO (op3))
1596 if (REG_P (op1) && REG_P (op3)
1597 && REGNO (op1) != REGNO (op3))
1599 emit_move_insn (op3, op1);
1603 if (satisfies_constraint_P (op2) && (value = INTVAL (op2)) != 0)
1604 emit_insn (gen_addsi3 (op3, op1, GEN_INT (-value)));
1606 emit_insn (gen_xorsi3 (op3, op1, op2));
1608 emit_insn (gen_cmp_ltusi_insn (op3, const1_rtx));
1609 emit_insn (gen_movcc_insn (op0));
1610 operands[4] = get_insns ();
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")
1618 (clobber (reg:CC 17))
1619 (clobber (match_scratch:SI 2 "=&r"))]
1622 [(set_attr "type" "multi")
1623 (set_attr "length" "6")])
1626 [(set (match_operand:SI 0 "register_operand" "")
1627 (ne:SI (match_operand:SI 1 "register_operand" "")
1629 (clobber (reg:CC 17))
1630 (clobber (match_scratch:SI 2 ""))]
1635 (ltu:CC (match_dup 2)
1638 (ne:SI (reg:CC 17) (const_int 0)))]
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))]
1648 [(set_attr "type" "multi")
1649 (set_attr "length" "4,6")])
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))]
1658 (lt:CC (match_dup 1)
1661 (ne:SI (reg:CC 17) (const_int 0)))]
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))]
1671 [(set_attr "type" "multi")
1672 (set_attr "length" "8")])
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))]
1681 (lt:CC (match_dup 2)
1684 (ne:SI (reg:CC 17) (const_int 0)))
1686 (xor:SI (match_dup 0)
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.
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))]
1699 (lt:CC (match_dup 2)
1702 (ne:SI (reg:CC 17) (const_int 0)))
1704 (plus:SI (match_dup 0)
1707 (neg:SI (match_dup 0)))]
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))]
1717 [(set_attr "type" "multi")
1718 (set_attr "length" "8,10")])
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))]
1727 (lt:CC (match_dup 1)
1730 (ne:SI (reg:CC 17) (const_int 0)))
1732 (xor:SI (match_dup 0)
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.
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))]
1745 (lt:CC (match_dup 1)
1748 (ne:SI (reg:CC 17) (const_int 0)))
1750 (plus:SI (match_dup 0)
1753 (neg:SI (match_dup 0)))]
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))]
1763 [(set_attr "type" "multi")
1764 (set_attr "length" "6,8")])
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))]
1773 (ltu:CC (match_dup 1)
1776 (ne:SI (reg:CC 17) (const_int 0)))]
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))]
1786 [(set_attr "type" "multi")
1787 (set_attr "length" "8")])
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))]
1796 (ltu:CC (match_dup 2)
1799 (ne:SI (reg:CC 17) (const_int 0)))
1801 (xor:SI (match_dup 0)
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.
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))]
1814 (ltu:CC (match_dup 2)
1817 (ne:SI (reg:CC 17) (const_int 0)))
1819 (plus:SI (match_dup 0)
1822 (neg:SI (match_dup 0)))]
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))]
1832 [(set_attr "type" "multi")
1833 (set_attr "length" "8,10")])
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))]
1842 (ltu:CC (match_dup 1)
1845 (ne:SI (reg:CC 17) (const_int 0)))
1847 (xor:SI (match_dup 0)
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.
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))]
1860 (ltu:CC (match_dup 1)
1863 (ne:SI (reg:CC 17) (const_int 0)))
1865 (plus:SI (match_dup 0)
1868 (neg:SI (match_dup 0)))]
1871 (define_insn "movcc_insn"
1872 [(set (match_operand:SI 0 "register_operand" "=r")
1873 (ne:SI (reg:CC 17) (const_int 0)))]
1876 [(set_attr "type" "misc")
1877 (set_attr "length" "2")])
1880 ;; Unconditional and other jump instructions.
1883 [(set (pc) (label_ref (match_operand 0 "" "")))]
1886 [(set_attr "type" "uncond_branch")
1887 (set (attr "length") (if_then_else (ltu (plus (minus (match_dup 0) (pc))
1893 (define_insn "indirect_jump"
1894 [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
1897 [(set_attr "type" "uncond_branch")
1898 (set_attr "length" "2")])
1900 (define_insn "return_lr"
1901 [(parallel [(return) (use (reg:SI 14))])]
1904 [(set_attr "type" "uncond_branch")
1905 (set_attr "length" "2")])
1907 (define_insn "return_rte"
1911 [(set_attr "type" "uncond_branch")
1912 (set_attr "length" "2")])
1914 (define_expand "return"
1919 emit_jump_insn (gen_return_lr ());
1923 (define_expand "return_normal"
1928 enum m32r_function_type fn_type;
1930 fn_type = m32r_compute_function_type (current_function_decl);
1931 if (M32R_INTERRUPT_P (fn_type))
1933 emit_jump_insn (gen_return_rte ());
1937 emit_jump_insn (gen_return_lr ());
1941 (define_expand "tablejump"
1942 [(parallel [(set (pc) (match_operand 0 "register_operand" "r"))
1943 (use (label_ref (match_operand 1 "" "")))])]
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. */
1954 tmp = gen_rtx_LABEL_REF (Pmode, operands[1]);
1956 tmp = gen_rtx_PLUS (Pmode, tmp2, tmp);
1957 operands[0] = memory_address (Pmode, tmp);
1961 (define_insn "*tablejump_insn"
1962 [(set (pc) (match_operand:SI 0 "address_operand" "p"))
1963 (use (label_ref (match_operand 1 "" "")))]
1966 [(set_attr "type" "uncond_branch")
1967 (set_attr "length" "2")])
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))])]
1979 crtl->uses_pic_offset_table = 1;
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))]
1988 [(set_attr "type" "call")
1989 (set_attr "length" "2")])
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))]
1998 int call26_p = call26_operand (operands[0], FUNCTION_MODE);
2002 /* We may not be able to reach with a `bl' insn so punt and leave it to
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
2007 return \"seth r14,%T0\;add3 r14,r14,%B0\;jl r14\";
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.
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))])]
2033 crtl->uses_pic_offset_table = 1;
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))]
2043 [(set_attr "type" "call")
2044 (set_attr "length" "2")])
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))]
2054 int call26_p = call26_operand (operands[1], FUNCTION_MODE);
2057 crtl->uses_pic_offset_table = 1;
2061 /* We may not be able to reach with a `bl' insn so punt and leave it to
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
2066 return \"seth r14,%T1\;add3 r14,r14,%B1\;jl r14\";
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.
2085 [(set_attr "type" "int2")
2086 (set_attr "length" "2")])
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.
2091 (define_insn "blockage"
2092 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
2096 ;; Special pattern to flush the icache.
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))]
2104 "* return \"trap %#%1 ; flush-icache\";"
2105 [(set_attr "type" "int4")
2106 (set_attr "length" "4")])
2108 ;; Speed up fabs and provide correct sign handling for -0
2110 (define_insn "absdf2"
2111 [(set (match_operand:DF 0 "register_operand" "=r")
2112 (abs:DF (match_operand:DF 1 "register_operand" "0")))]
2115 [(set_attr "type" "multi")
2116 (set_attr "length" "4")])
2119 [(set (match_operand:DF 0 "register_operand" "")
2120 (abs:DF (match_operand:DF 1 "register_operand" "")))]
2123 (ashift:SI (match_dup 2)
2126 (lshiftrt:SI (match_dup 2)
2128 "operands[2] = gen_highpart (SImode, operands[0]);")
2130 (define_insn "abssf2"
2131 [(set (match_operand:SF 0 "register_operand" "=r")
2132 (abs:SF (match_operand:SF 1 "register_operand" "0")))]
2135 [(set_attr "type" "multi")
2136 (set_attr "length" "4")])
2139 [(set (match_operand:SF 0 "register_operand" "")
2140 (abs:SF (match_operand:SF 1 "register_operand" "")))]
2143 (ashift:SI (match_dup 2)
2146 (lshiftrt:SI (match_dup 2)
2148 "operands[2] = gen_highpart (SImode, operands[0]);")
2150 ;; Conditional move instructions
2151 ;; Based on those done for the d10v
2153 (define_expand "movsicc"
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")
2165 /* FIXME: This expansion is hold over from a failed conversion of this
2166 port away from using cc0. It still relies upon the last comparison
2167 being the one that is now tested. Disabled for now in order to
2168 improve the generation of working code. */
2171 if (! zero_and_one (operands [2], operands [3]))
2174 /* Generate the comparison that will set the carry flag. */
2175 operands[1] = gen_compare (GET_CODE (operands[1]), XEXP (operands[1], 0),
2176 XEXP (operands[1], 1), TRUE);
2178 /* See other movsicc pattern below for reason why. */
2179 emit_insn (gen_blockage ());
2182 ;; Generate the conditional instructions based on how the carry flag is examined.
2183 (define_insn "*movsicc_internal"
2184 [(set (match_operand:SI 0 "register_operand" "=r")
2185 (if_then_else:SI (match_operand 1 "carry_compare_operand" "")
2186 (match_operand:SI 2 "conditional_move_operand" "O")
2187 (match_operand:SI 3 "conditional_move_operand" "O")
2190 "zero_and_one (operands [2], operands[3])"
2191 "* return emit_cond_move (operands, insn);"
2192 [(set_attr "type" "multi")
2193 (set_attr "length" "8")
2198 ;; Block moves, see m32r.cc for more details.
2199 ;; Argument 0 is the destination
2200 ;; Argument 1 is the source
2201 ;; Argument 2 is the length
2202 ;; Argument 3 is the alignment
2204 (define_expand "cpymemsi"
2205 [(parallel [(set (match_operand:BLK 0 "general_operand" "")
2206 (match_operand:BLK 1 "general_operand" ""))
2207 (use (match_operand:SI 2 "immediate_operand" ""))
2208 (use (match_operand:SI 3 "immediate_operand" ""))])]
2212 if (operands[0]) /* Avoid unused code messages. */
2214 if (m32r_expand_block_move (operands))
2221 ;; Insn generated by block moves
2223 (define_insn "cpymemsi_internal"
2224 [(set (mem:BLK (match_operand:SI 0 "register_operand" "r")) ;; destination
2225 (mem:BLK (match_operand:SI 1 "register_operand" "r"))) ;; source
2226 (use (match_operand:SI 2 "m32r_block_immediate_operand" "J"));; # bytes to move
2227 (set (match_operand:SI 3 "register_operand" "=0")
2228 (plus:SI (minus (match_dup 2) (const_int 4))
2230 (set (match_operand:SI 4 "register_operand" "=1")
2231 (plus:SI (match_dup 1)
2233 (clobber (match_scratch:SI 5 "=&r")) ;; temp1
2234 (clobber (match_scratch:SI 6 "=&r"))] ;; temp2
2236 "* m32r_output_block_move (insn, operands); return \"\"; "
2237 [(set_attr "type" "store8")
2238 (set_attr "length" "72")]) ;; Maximum
2242 /* When generating pic, we need to load the symbol offset into a register.
2243 So that the optimizer does not confuse this with a normal symbol load
2244 we use an unspec. The offset will be loaded from a constant pool entry,
2245 since that is the only type of relocation we can use. */
2247 (define_insn "pic_load_addr"
2248 [(set (match_operand:SI 0 "register_operand" "=r")
2249 (unspec:SI [(match_operand 1 "" "")] UNSPEC_PIC_LOAD_ADDR))]
2252 [(set_attr "type" "int4")])
2254 (define_insn "gotoff_load_addr"
2255 [(set (match_operand:SI 0 "register_operand" "=r")
2256 (unspec:SI [(match_operand 1 "" "")] UNSPEC_GOTOFF))]
2258 "seth %0, %#shigh(%1@GOTOFF)\;add3 %0, %0, low(%1@GOTOFF)"
2259 [(set_attr "type" "int4")
2260 (set_attr "length" "8")])
2262 ;; Load program counter insns.
2264 (define_insn "get_pc"
2265 [(clobber (reg:SI 14))
2266 (set (match_operand 0 "register_operand" "=r,r")
2267 (unspec [(match_operand 1 "" "")] UNSPEC_GET_PC))
2268 (use (match_operand:SI 2 "immediate_operand" "W,i"))]
2271 bl.s .+4\;seth %0,%#shigh(%1)\;add3 %0,%0,%#low(%1+4)\;add %0,lr
2272 bl.s .+4\;ld24 %0,%#%1\;add %0,lr"
2273 [(set_attr "length" "12,8")])
2275 (define_expand "builtin_setjmp_receiver"
2276 [(label_ref (match_operand 0 "" ""))]
2280 m32r_load_pic_register ();