1 ;; Machine Description for Renesas RX processors
2 ;; Copyright (C) 2008-2024 Free Software Foundation, Inc.
3 ;; Contributed by Red Hat.
5 ;; This file is part of GCC.
7 ;; GCC is free software; you can redistribute it and/or modify
8 ;; it under the terms of the GNU General Public License as published by
9 ;; the Free Software Foundation; either version 3, or (at your option)
12 ;; GCC is distributed in the hope that it will be useful,
13 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
14 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 ;; GNU General Public License for more details.
17 ;; You should have received a copy of the GNU General Public License
18 ;; along with GCC; see the file COPYING3. If not see
19 ;; <http://www.gnu.org/licenses/>.
22 ;; This code iterator is used for sign- and zero- extensions.
23 (define_mode_iterator small_int_modes [(HI "") (QI "")])
25 ;; This code iterator is used for max and min operations.
26 (define_mode_iterator int_modes [(SI "") (HI "") (QI "")])
28 ;; We do not handle DFmode here because it is either
29 ;; the same as SFmode, or if -m64bit-doubles is active
30 ;; then all operations on doubles have to be handled by
32 (define_mode_iterator register_modes
33 [(SF "") (SI "") (HI "") (QI "")])
54 (UNSPEC_BUILTIN_BRK 30)
55 (UNSPEC_BUILTIN_CLRPSW 31)
56 (UNSPEC_BUILTIN_INT 32)
57 (UNSPEC_BUILTIN_MACHI 33)
58 (UNSPEC_BUILTIN_MACLO 34)
59 (UNSPEC_BUILTIN_MULHI 35)
60 (UNSPEC_BUILTIN_MULLO 36)
61 (UNSPEC_BUILTIN_MVFACHI 37)
62 (UNSPEC_BUILTIN_MVFACMI 38)
63 (UNSPEC_BUILTIN_MVFC 39)
64 (UNSPEC_BUILTIN_MVFCP 40)
65 (UNSPEC_BUILTIN_MVTACHI 41)
66 (UNSPEC_BUILTIN_MVTACLO 42)
67 (UNSPEC_BUILTIN_MVTC 43)
68 (UNSPEC_BUILTIN_MVTIPL 44)
69 (UNSPEC_BUILTIN_RACW 45)
70 (UNSPEC_BUILTIN_REVW 46)
71 (UNSPEC_BUILTIN_RMPA 47)
72 (UNSPEC_BUILTIN_ROUND 48)
73 (UNSPEC_BUILTIN_SAT 49)
74 (UNSPEC_BUILTIN_SETPSW 50)
75 (UNSPEC_BUILTIN_WAIT 51)
91 (define_attr "length" "" (const_int 8))
93 (include "predicates.md")
94 (include "constraints.md")
96 ;; Pipeline description.
98 ;; The RX only has a single pipeline. It has five stages (fetch,
99 ;; decode, execute, memory access, writeback) each of which normally
100 ;; takes a single CPU clock cycle.
102 ;; The timings attribute consists of two numbers, the first is the
103 ;; throughput, which is the number of cycles the instruction takes
104 ;; to execute and generate a result. The second is the latency
105 ;; which is the effective number of cycles the instruction takes to
106 ;; execute if its result is used by the following instruction. The
107 ;; latency is always greater than or equal to the throughput.
108 ;; These values were taken from tables 2.13 and 2.14 in section 2.8
109 ;; of the RX610 Group Hardware Manual v0.11
111 ;; Note - it would be nice to use strings rather than integers for
112 ;; the possible values of this attribute, so that we can have the
113 ;; gcc build mechanism check for values that are not supported by
114 ;; the reservations below. But this will not work because the code
115 ;; in rx_adjust_sched_cost() needs integers not strings.
117 (define_attr "timings" "" (const_int 11))
119 (define_automaton "pipelining")
120 (define_cpu_unit "throughput" "pipelining")
122 (define_insn_reservation "throughput__1_latency__1" 1
123 (eq_attr "timings" "11") "throughput")
124 (define_insn_reservation "throughput__1_latency__2" 2
125 (eq_attr "timings" "12") "throughput,nothing")
126 (define_insn_reservation "throughput__2_latency__2" 1
127 (eq_attr "timings" "22") "throughput*2")
128 (define_insn_reservation "throughput__3_latency__3" 1
129 (eq_attr "timings" "33") "throughput*3")
130 (define_insn_reservation "throughput__3_latency__4" 2
131 (eq_attr "timings" "34") "throughput*3,nothing")
132 (define_insn_reservation "throughput__4_latency__4" 1
133 (eq_attr "timings" "44") "throughput*4")
134 (define_insn_reservation "throughput__4_latency__5" 2
135 (eq_attr "timings" "45") "throughput*4,nothing")
136 (define_insn_reservation "throughput__5_latency__5" 1
137 (eq_attr "timings" "55") "throughput*5")
138 (define_insn_reservation "throughput__5_latency__6" 2
139 (eq_attr "timings" "56") "throughput*5,nothing")
140 (define_insn_reservation "throughput__6_latency__6" 1
141 (eq_attr "timings" "66") "throughput*6")
142 (define_insn_reservation "throughput_10_latency_10" 1
143 (eq_attr "timings" "1010") "throughput*10")
144 (define_insn_reservation "throughput_11_latency_11" 1
145 (eq_attr "timings" "1111") "throughput*11")
146 (define_insn_reservation "throughput_16_latency_16" 1
147 (eq_attr "timings" "1616") "throughput*16")
148 (define_insn_reservation "throughput_18_latency_18" 1
149 (eq_attr "timings" "1818") "throughput*18")
151 ;; ----------------------------------------------------------------------------
155 ;; Note - we do not specify the two instructions necessary to perform
156 ;; a compare-and-branch in the cbranchsi4 pattern because that would
157 ;; allow the comparison to be moved away from the jump before the reload
158 ;; pass has completed. That would be problematical because reload can
159 ;; generate ADDSI3 instructions which would corrupt the PSW flags.
161 (define_expand "cbranchsi4"
164 (match_operator 0 "comparison_operator"
165 [(match_operand:SI 1 "register_operand")
166 (match_operand:SI 2 "rx_source_operand")])
167 (label_ref (match_operand 3 ""))
172 (define_insn_and_split "*cbranchsi4"
175 (match_operator 3 "comparison_operator"
176 [(match_operand:SI 0 "register_operand" "r")
177 (match_operand:SI 1 "rx_source_operand" "riQ")])
178 (match_operand 2 "label_ref_operand" "")
185 rx_split_cbranch (CCmode, GET_CODE (operands[3]),
186 operands[0], operands[1], operands[2]);
190 (define_insn "*cmpsi"
191 [(set (reg:CC CC_REG)
192 (compare:CC (match_operand:SI 0 "register_operand" "r,r,r,r,r,r,r")
193 (match_operand:SI 1 "rx_source_operand" "r,Uint04,Int08,Sint16,Sint24,i,Q")))]
196 [(set_attr "timings" "11,11,11,11,11,11,33")
197 (set_attr "length" "2,2,3,4,5,6,5")]
200 ;; Canonical method for representing TST.
201 (define_insn_and_split "*cbranchsi4_tst"
204 (match_operator 3 "rx_zs_comparison_operator"
205 [(and:SI (match_operand:SI 0 "register_operand" "r")
206 (match_operand:SI 1 "rx_source_operand" "riQ"))
208 (match_operand 2 "label_ref_operand" "")
215 rx_split_cbranch (CC_ZSmode, GET_CODE (operands[3]),
216 XEXP (operands[3], 0), XEXP (operands[3], 1),
221 ;; Various other ways that GCC codes "var & const"
222 (define_insn_and_split "*cbranchsi4_tst_ext"
225 (match_operator 4 "rx_z_comparison_operator"
227 (match_operand:SI 0 "register_operand" "r")
228 (match_operand:SI 1 "rx_constshift_operand" "")
229 (match_operand:SI 2 "rx_constshift_operand" ""))
231 (match_operand 3 "label_ref_operand" "")
242 mask <<= INTVAL (operands[1]);
244 mask <<= INTVAL (operands[2]);
245 x = gen_rtx_AND (SImode, operands[0], gen_int_mode (mask, SImode));
247 rx_split_cbranch (CC_ZSmode, GET_CODE (operands[4]),
248 x, const0_rtx, operands[3]);
252 (define_insn "*tstsi"
253 [(set (reg:CC_ZS CC_REG)
255 (and:SI (match_operand:SI 0 "register_operand" "r,r,r")
256 (match_operand:SI 1 "rx_source_operand" "r,i,Q"))
260 [(set_attr "timings" "11,11,33")
261 (set_attr "length" "3,7,6")]
264 (define_expand "cbranchsf4"
267 (match_operator 0 "rx_fp_comparison_operator"
268 [(match_operand:SF 1 "register_operand")
269 (match_operand:SF 2 "rx_source_operand")])
270 (label_ref (match_operand 3 ""))
275 (define_insn_and_split "*cbranchsf4"
278 (match_operator 3 "rx_fp_comparison_operator"
279 [(match_operand:SF 0 "register_operand" "r")
280 (match_operand:SF 1 "rx_source_operand" "rFQ")])
281 (match_operand 2 "label_ref_operand" "")
285 "&& reload_completed"
288 rx_split_cbranch (CC_Fmode, GET_CODE (operands[3]),
289 operands[0], operands[1], operands[2]);
293 (define_insn "*cmpsf"
294 [(set (reg:CC_F CC_REG)
296 (match_operand:SF 0 "register_operand" "r,r,r")
297 (match_operand:SF 1 "rx_source_operand" "r,F,Q")))]
298 "ALLOW_RX_FPU_INSNS && reload_completed"
300 [(set_attr "timings" "11,11,33")
301 (set_attr "length" "3,7,5")]
304 ;; Flow Control Instructions:
306 (define_insn "*conditional_branch"
309 (match_operator 1 "comparison_operator"
310 [(reg CC_REG) (const_int 0)])
311 (label_ref (match_operand 0 "" ""))
315 [(set_attr "length" "8") ;; This length is wrong, but it is
316 ;; too hard to compute statically.
317 (set_attr "timings" "33")] ;; The timing assumes that the branch is taken.
320 ;; ----------------------------------------------------------------------------
324 (label_ref (match_operand 0 "" "")))]
327 [(set_attr "length" "4")
328 (set_attr "timings" "33")]
331 (define_insn "indirect_jump"
333 (match_operand:SI 0 "register_operand" "r"))]
336 [(set_attr "length" "2")
337 (set_attr "timings" "33")]
340 (define_insn "tablejump"
342 (match_operand:SI 0 "register_operand" "r"))
343 (use (label_ref (match_operand 1 "" "")))]
345 { return TARGET_PID ? (TARGET_AS100_SYNTAX ? "\n?:\tbra\t%0"
349 [(set_attr "timings" "33")
350 (set_attr "length" "2")]
353 (define_expand "return"
355 "rx_can_use_simple_return ()"
356 "rx_expand_epilogue (false); DONE;"
359 (define_insn "simple_return"
363 [(set_attr "length" "1")
364 (set_attr "timings" "55")]
367 ;; Unspec used so that the constant will not be invalid
368 ;; if -mmax-constant-size has been specified.
369 (define_insn "deallocate_and_return"
370 [(set (reg:SI SP_REG)
371 (plus:SI (reg:SI SP_REG)
372 (const:SI (unspec:SI [(match_operand 0 "const_int_operand" "n")] UNSPEC_CONST))))
376 [(set_attr "length" "2")
377 (set_attr "timings" "55")]
380 (define_insn "pop_and_return"
381 [(match_parallel 1 "rx_rtsd_vector"
382 [(set (reg:SI SP_REG)
383 (plus:SI (reg:SI SP_REG)
384 (match_operand:SI 0 "const_int_operand" "n")))])
388 rx_emit_stack_popm (operands, false);
391 [(set_attr "length" "3")
392 (set_attr "timings" "56")]
395 (define_insn "fast_interrupt_return"
396 [(unspec_volatile [(return)] UNSPEC_RTFI) ]
399 [(set_attr "length" "2")
400 (set_attr "timings" "33")]
403 (define_insn "exception_return"
404 [(unspec_volatile [(return)] UNSPEC_RTE) ]
407 [(set_attr "length" "2")
408 (set_attr "timings" "66")]
411 (define_insn "naked_return"
412 [(unspec_volatile [(return)] UNSPEC_NAKED) ]
414 "; Naked function: epilogue provided by programmer."
418 ;; Note - the following set of patterns do not use the "memory_operand"
419 ;; predicate or an "m" constraint because we do not allow symbol_refs
420 ;; or label_refs as legitimate memory addresses. This matches the
421 ;; behavior of most of the RX instructions. Only the call/branch
422 ;; instructions are allowed to refer to symbols/labels directly.
423 ;; The call operands are in QImode because that is the value of
426 (define_expand "call"
427 [(call (match_operand:QI 0 "general_operand")
428 (match_operand:SI 1 "general_operand"))]
431 rtx dest = XEXP (operands[0], 0);
433 if (! rx_call_operand (dest, Pmode))
434 dest = force_reg (Pmode, dest);
435 emit_call_insn (gen_call_internal (dest));
440 (define_insn "call_internal"
441 [(call (mem:QI (match_operand:SI 0 "rx_call_operand" "r,CALL_OP_SYMBOL_REF"))
443 (clobber (reg:CC CC_REG))]
448 [(set_attr "length" "2,4")
449 (set_attr "timings" "33")]
452 (define_expand "call_value"
453 [(set (match_operand 0 "register_operand")
454 (call (match_operand:QI 1 "general_operand")
455 (match_operand:SI 2 "general_operand")))]
458 rtx dest = XEXP (operands[1], 0);
460 if (! rx_call_operand (dest, Pmode))
461 dest = force_reg (Pmode, dest);
462 emit_call_insn (gen_call_value_internal (operands[0], dest));
467 (define_insn "call_value_internal"
468 [(set (match_operand 0 "register_operand" "=r,r")
469 (call (mem:QI (match_operand:SI 1 "rx_call_operand" "r,CALL_OP_SYMBOL_REF"))
471 (clobber (reg:CC CC_REG))]
476 [(set_attr "length" "2,4")
477 (set_attr "timings" "33")]
480 ;; Note - we do not allow indirect sibcalls (with the address
481 ;; held in a register) because we cannot guarantee that the register
482 ;; chosen will be a call-used one. If it is a call-saved register,
483 ;; then the epilogue code will corrupt it by popping the saved value
485 (define_expand "sibcall"
487 [(call (mem:QI (match_operand:SI 0 "rx_symbolic_call_operand"))
488 (match_operand:SI 1 "general_operand"))
492 if (MEM_P (operands[0]))
493 operands[0] = XEXP (operands[0], 0);
494 emit_call_insn (gen_sibcall_internal (operands[0]));
499 (define_insn "sibcall_internal"
500 [(call (mem:QI (match_operand:SI 0 "rx_symbolic_call_operand" "Symbol"))
505 [(set_attr "length" "4")
506 (set_attr "timings" "33")]
509 (define_expand "sibcall_value"
511 [(set (match_operand 0 "register_operand")
512 (call (mem:QI (match_operand:SI 1 "rx_symbolic_call_operand"))
513 (match_operand:SI 2 "general_operand")))
517 if (MEM_P (operands[1]))
518 operands[1] = XEXP (operands[1], 0);
519 emit_call_insn (gen_sibcall_value_internal (operands[0], operands[1]));
524 (define_insn "sibcall_value_internal"
525 [(set (match_operand 0 "register_operand" "=r")
526 (call (mem:QI (match_operand:SI 1 "rx_symbolic_call_operand" "Symbol"))
531 [(set_attr "length" "4")
532 (set_attr "timings" "33")]
535 ;; Function Prologue/Epilogue Instructions
537 (define_expand "prologue"
540 "rx_expand_prologue (); DONE;"
543 (define_expand "epilogue"
546 "rx_expand_epilogue (false); DONE;"
549 (define_expand "sibcall_epilogue"
552 "rx_expand_epilogue (true); DONE;"
557 ;; Note - we do not allow memory to memory moves, even though the ISA
558 ;; supports them. The reason is that the conditions on such moves are
559 ;; too restrictive, specifically the source addressing mode is limited
560 ;; by the destination addressing mode and vice versa. (For example it
561 ;; is not possible to use indexed register indirect addressing for one
562 ;; of the operands if the other operand is anything other than a register,
563 ;; but it is possible to use register relative addressing when the other
564 ;; operand also uses register relative or register indirect addressing).
566 ;; GCC does not support computing legitimate addresses based on the
567 ;; nature of other operands involved in the instruction, and reload is
568 ;; not smart enough to cope with a whole variety of different memory
569 ;; addressing constraints, so it is simpler and safer to just refuse
570 ;; to support memory to memory moves.
572 (define_expand "mov<register_modes:mode>"
573 [(set (match_operand:register_modes 0 "general_operand")
574 (match_operand:register_modes 1 "general_operand"))]
577 if (MEM_P (operands[0]) && MEM_P (operands[1]))
578 operands[1] = copy_to_mode_reg (<register_modes:MODE>mode, operands[1]);
579 operands[0] = rx_maybe_pidify_operand (operands[0], 0);
580 operands[1] = rx_maybe_pidify_operand (operands[1], 0);
581 if (GET_CODE (operands[0]) != REG
582 && GET_CODE (operands[1]) == PLUS)
583 operands[1] = copy_to_mode_reg (<register_modes:MODE>mode, operands[1]);
584 if (GET_CODE (operands[1]) == PLUS && GET_MODE (operands[1]) == SImode)
586 emit_insn (gen_addsi3 (operands[0], XEXP (operands[1], 0), XEXP (operands[1], 1)));
589 if (CONST_INT_P (operand1)
590 && ! rx_is_legitimate_constant (<register_modes:MODE>mode, operand1))
595 (define_insn "*mov<register_modes:mode>_internal"
596 [(set (match_operand:register_modes
597 0 "nonimmediate_operand" "=r,r,r,r,r,r,m,Q,Q,Q,Q,r")
598 (match_operand:register_modes
599 1 "general_operand" "Int08,Sint16,Sint24,i,r,m,r,Int08,Sint16,Sint24,i,RpdaRpid"))]
601 { return rx_gen_move_template (operands, false); }
602 [(set_attr "length" "3,4,5,6,2,4,6,5,6,7,8,8")
603 (set_attr "timings" "11,11,11,11,11,12,11,11,11,11,11,11")]
606 (define_insn "extend<small_int_modes:mode>si2"
607 [(set (match_operand:SI 0 "register_operand" "=r,r")
608 (sign_extend:SI (match_operand:small_int_modes
609 1 "nonimmediate_operand" "r,m")))]
611 { return rx_gen_move_template (operands, false); }
612 [(set_attr "length" "2,6")
613 (set_attr "timings" "11,12")]
616 (define_insn "zero_extend<small_int_modes:mode>si2"
617 [(set (match_operand:SI 0 "register_operand" "=r,r")
618 (zero_extend:SI (match_operand:small_int_modes
619 1 "nonimmediate_operand" "r,m")))]
621 { return rx_gen_move_template (operands, true); }
622 [(set_attr "length" "2,4")
623 (set_attr "timings" "11,12")]
626 (define_insn "stack_push"
627 [(set (reg:SI SP_REG)
628 (minus:SI (reg:SI SP_REG)
630 (set (mem:SI (minus:SI (reg:SI SP_REG) (const_int 4)))
631 (match_operand:SI 0 "register_operand" "r"))]
634 [(set_attr "length" "2")]
637 (define_insn "stack_pushm"
638 [(match_parallel 1 "rx_store_multiple_vector"
639 [(set (reg:SI SP_REG)
640 (minus:SI (reg:SI SP_REG)
641 (match_operand:SI 0 "const_int_operand" "n")))])]
644 rx_emit_stack_pushm (operands);
647 [(set_attr "length" "2")
648 (set_attr "timings" "44")] ;; The timing is a guesstimate average timing.
651 (define_insn "stack_pop"
652 [(set (match_operand:SI 0 "register_operand" "=r")
653 (mem:SI (reg:SI SP_REG)))
655 (plus:SI (reg:SI SP_REG)
659 [(set_attr "length" "2")
660 (set_attr "timings" "12")]
663 (define_insn "stack_popm"
664 [(match_parallel 1 "rx_load_multiple_vector"
665 [(set (reg:SI SP_REG)
666 (plus:SI (reg:SI SP_REG)
667 (match_operand:SI 0 "const_int_operand" "n")))])]
670 rx_emit_stack_popm (operands, true);
673 [(set_attr "length" "2")
674 (set_attr "timings" "45")] ;; The timing is a guesstimate average timing.
677 (define_insn_and_split "cstoresi4"
678 [(set (match_operand:SI 0 "register_operand" "=r")
679 (match_operator:SI 1 "comparison_operator"
680 [(match_operand:SI 2 "register_operand" "r")
681 (match_operand:SI 3 "rx_source_operand" "riQ")]))
682 (clobber (reg:CC CC_REG))]
690 flags = gen_rtx_REG (CCmode, CC_REG);
691 x = gen_rtx_COMPARE (CCmode, operands[2], operands[3]);
692 x = gen_rtx_SET (flags, x);
695 x = gen_rtx_fmt_ee (GET_CODE (operands[1]), SImode, flags, const0_rtx);
696 x = gen_rtx_SET (operands[0], x);
702 [(set (match_operand:SI 0 "register_operand" "=r")
703 (match_operator:SI 1 "comparison_operator"
704 [(reg CC_REG) (const_int 0)]))]
707 [(set_attr "length" "3")]
710 (define_insn_and_split "cstoresf4"
711 [(set (match_operand:SI 0 "register_operand" "=r")
712 (match_operator:SI 1 "rx_fp_comparison_operator"
713 [(match_operand:SF 2 "register_operand" "r")
714 (match_operand:SF 3 "rx_source_operand" "rFQ")]))]
722 flags = gen_rtx_REG (CC_Fmode, CC_REG);
723 x = gen_rtx_COMPARE (CC_Fmode, operands[2], operands[3]);
724 x = gen_rtx_SET (flags, x);
727 x = gen_rtx_fmt_ee (GET_CODE (operands[1]), SImode, flags, const0_rtx);
728 x = gen_rtx_SET (operands[0], x);
733 (define_expand "movsicc"
735 [(set (match_operand:SI 0 "register_operand")
736 (if_then_else:SI (match_operand 1 "comparison_operator")
737 (match_operand:SI 2 "nonmemory_operand")
738 (match_operand:SI 3 "nonmemory_operand")))
739 (clobber (reg:CC CC_REG))])]
742 /* Make sure that we have an integer comparison... */
743 if (GET_MODE (XEXP (operands[1], 0)) != CCmode
744 && GET_MODE (XEXP (operands[1], 0)) != SImode)
747 /* One operand must be a constant or a register, the other must be a register. */
748 if ( ! CONSTANT_P (operands[2])
749 && ! CONSTANT_P (operands[3])
750 && ! (REG_P (operands[2]) && REG_P (operands[3])))
754 (define_insn_and_split "*movsicc"
755 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
757 (match_operator 5 "comparison_operator"
758 [(match_operand:SI 3 "register_operand" "r,r,r")
759 (match_operand:SI 4 "rx_source_operand" "riQ,riQ,riQ")])
760 (match_operand:SI 1 "nonmemory_operand" "i,ri,r")
761 (match_operand:SI 2 "nonmemory_operand" "ri,i,r")))
762 (clobber (reg:CC CC_REG))]
763 "(CONSTANT_P (operands[1]) || CONSTANT_P (operands[2]))
764 || (REG_P (operands[1]) && REG_P (operands[2]))"
766 "&& reload_completed"
769 rtx x, flags, op0, op1, op2;
770 enum rtx_code cmp_code;
772 flags = gen_rtx_REG (CCmode, CC_REG);
773 x = gen_rtx_COMPARE (CCmode, operands[3], operands[4]);
774 emit_insn (gen_rtx_SET (flags, x));
776 cmp_code = GET_CODE (operands[5]);
781 /* If OP2 is the constant, reverse the sense of the move.
782 Likewise if both operands are registers but OP1 == OP0. */
783 if ((! CONSTANT_P (operands[1]) && CONSTANT_P (operands[2]))
784 || (REG_P (operands[1]) && REG_P (operands[2])
785 && rtx_equal_p (op0, op1)))
787 x = op1, op1 = op2, op2 = x;
788 cmp_code = reverse_condition (cmp_code);
791 /* If OP2 does not match the output, copy it into place. We have allowed
792 these alternatives so that the destination can legitimately be one of
793 the comparison operands without increasing register pressure. */
794 if (! rtx_equal_p (op0, op2))
795 emit_move_insn (op0, op2);
797 x = gen_rtx_fmt_ee (cmp_code, VOIDmode, flags, const0_rtx);
798 x = gen_rtx_IF_THEN_ELSE (SImode, x, op1, op0);
799 emit_insn (gen_rtx_SET (op0, x));
804 [(set (match_operand:SI 0 "register_operand" "+r,r,r,r")
806 (match_operator 2 "rx_z_comparison_operator"
807 [(reg CC_REG) (const_int 0)])
808 (match_operand:SI 1 "immediate_operand" "Sint08,Sint16,Sint24,i")
811 && ((GET_CODE (operands[2]) == EQ) || (GET_CODE (operands[2]) == NE))"
813 if (GET_CODE (operands[2]) == EQ)
814 return "stz\t%1, %0";
816 return "stnz\t%1, %0";
818 [(set_attr "length" "4,5,6,7")]
821 (define_insn "*stcc_reg"
822 [(set (match_operand:SI 0 "register_operand" "+r,r,r,r,r,r")
824 (match_operator 2 "comparison_operator"
825 [(reg CC_REG) (const_int 0)])
826 (match_operand:SI 1 "nonmemory_operand"
827 "r,Uint04,Sint08,Sint16,Sint24,i")
831 PUT_CODE (operands[2], reverse_condition (GET_CODE (operands[2])));
832 return "b%B2 1f\n\tmov %1, %0\n1:";
834 [(set_attr "length" "3,3,4,5,6,7")]
837 ;; Arithmetic Instructions
839 (define_insn "abssi2"
840 [(set (match_operand:SI 0 "register_operand" "=r,r")
841 (abs:SI (match_operand:SI 1 "register_operand" "0,r")))
842 (clobber (reg:CC CC_REG))]
847 [(set_attr "length" "2,3")]
850 (define_insn "*abssi2_flags"
852 (compare (abs:SI (match_operand:SI 1 "register_operand" "0,r"))
854 (set (match_operand:SI 0 "register_operand" "=r,r")
855 (abs:SI (match_dup 1)))]
856 ;; Note - although the ABS instruction does set the O bit in the processor
857 ;; status word, it does not do so in a way that is comparable with the CMP
858 ;; instruction. Hence we use CC_ZSmode rather than CC_ZSOmode.
859 "reload_completed && rx_match_ccmode (insn, CC_ZSmode)"
863 [(set_attr "length" "2,3")]
866 (define_expand "addsi3"
867 [(parallel [(set (match_operand:SI 0 "register_operand" "")
868 (plus:SI (match_operand:SI 1 "register_operand" "")
869 (match_operand:SI 2 "rx_source_operand" "")))
870 (clobber (reg:CC CC_REG))])]
873 operands[0] = rx_maybe_pidify_operand (operands[0], 1);
874 operands[1] = rx_maybe_pidify_operand (operands[1], 1);
875 operands[2] = rx_maybe_pidify_operand (operands[2], 1);
879 (define_insn "addsi3_internal"
880 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,r,r,r,r,r,r,r,r")
881 (plus:SI (match_operand:SI 1 "register_operand" "%0,0,0,0,0,0,0,r,r,r,r,r,r,0")
882 (match_operand:SI 2 "rx_source_operand" "r,Uint04,NEGint4,Sint08,Sint16,Sint24,i,0,r,Sint08,Sint16,Sint24,i,Q")))
883 (clobber (reg:CC CC_REG))]
900 [(set_attr "timings" "11,11,11,11,11,11,11,11,11,11,11,11,11,33")
901 (set_attr "length" "2,2,2,3,4,5,6,2,3,3,4,5,6,5")]
904 (define_insn "*addsi3_flags"
906 (compare (plus:SI (match_operand:SI 1 "register_operand" "%0,0,0,0,0,0,0,r,r,r,r,r,r,0")
907 (match_operand:SI 2 "rx_source_operand" "r,Uint04,NEGint4,Sint08,Sint16,Sint24,i,0,r,Sint08,Sint16,Sint24,i,Q"))
909 (set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,r,r,r,r,r,r,r,r")
910 (plus:SI (match_dup 1) (match_dup 2)))]
911 "reload_completed && rx_match_ccmode (insn, CC_ZSCmode)"
927 [(set_attr "timings" "11,11,11,11,11,11,11,11,11,11,11,11,11,33")
928 (set_attr "length" "2,2,2,3,4,5,6,2,3,3,4,5,6,5")]
931 ;; A helper to expand the above with the CC_MODE filled in.
932 (define_expand "addsi3_flags"
933 [(parallel [(set (reg:CC_ZSC CC_REG)
935 (plus:SI (match_operand:SI 1 "register_operand")
936 (match_operand:SI 2 "rx_source_operand"))
938 (set (match_operand:SI 0 "register_operand")
939 (plus:SI (match_dup 1) (match_dup 2)))])]
942 (define_insn "adc_internal"
943 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r")
946 (ltu:SI (reg:CC CC_REG) (const_int 0))
947 (match_operand:SI 1 "register_operand" "%0,0,0,0,0,0"))
948 (match_operand:SI 2 "rx_source_operand" "r,Sint08,Sint16,Sint24,i,Q")))
949 (clobber (reg:CC CC_REG))]
952 [(set_attr "timings" "11,11,11,11,11,33")
953 (set_attr "length" "3,4,5,6,7,6")]
956 (define_insn "*adc_flags"
961 (ltu:SI (reg:CC CC_REG) (const_int 0))
962 (match_operand:SI 1 "register_operand" "%0,0,0,0,0,0"))
963 (match_operand:SI 2 "rx_source_operand" "r,Sint08,Sint16,Sint24,i,Q"))
965 (set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r")
968 (ltu:SI (reg:CC CC_REG) (const_int 0))
971 "reload_completed && rx_match_ccmode (insn, CC_ZSCmode)"
973 [(set_attr "timings" "11,11,11,11,11,33")
974 (set_attr "length" "3,4,5,6,7,6")]
977 ;; Peepholes to match:
978 ;; (set (reg A) (reg B))
979 ;; (set (CC) (compare:CC (reg A/reg B) (const_int 0)))
980 ;; and replace them with the addsi3_flags pattern, using an add
981 ;; of zero to copy the register and set the condition code bits.
983 [(set (match_operand:SI 0 "register_operand")
984 (match_operand:SI 1 "register_operand"))
986 (compare:CC (match_dup 0)
989 [(parallel [(set (reg:CC_ZSC CC_REG)
990 (compare:CC_ZSC (plus:SI (match_dup 1) (const_int 0))
993 (plus:SI (match_dup 1) (const_int 0))) ])]
997 [(set (match_operand:SI 0 "register_operand")
998 (match_operand:SI 1 "register_operand"))
1000 (compare:CC (match_dup 1)
1003 [(parallel [(set (reg:CC_ZSC CC_REG)
1004 (compare:CC_ZSC (plus:SI (match_dup 1) (const_int 0))
1007 (plus:SI (match_dup 1) (const_int 0)))])]
1010 (define_expand "adddi3"
1011 [(set (match_operand:DI 0 "register_operand")
1012 (plus:DI (match_operand:DI 1 "register_operand")
1013 (match_operand:DI 2 "rx_source_operand")))]
1016 rtx op0l, op0h, op1l, op1h, op2l, op2h;
1018 op0l = gen_lowpart (SImode, operands[0]);
1019 op1l = gen_lowpart (SImode, operands[1]);
1020 op2l = gen_lowpart (SImode, operands[2]);
1021 op0h = gen_highpart (SImode, operands[0]);
1022 op1h = gen_highpart (SImode, operands[1]);
1023 op2h = gen_highpart_mode (SImode, DImode, operands[2]);
1025 emit_insn (gen_adddi3_internal (op0l, op0h, op1l, op2l, op1h, op2h));
1029 (define_insn_and_split "adddi3_internal"
1030 [(set (match_operand:SI 0 "register_operand" "=&r")
1031 (plus:SI (match_operand:SI 2 "register_operand" "r")
1032 (match_operand:SI 3 "rx_source_operand" "riQ")))
1033 (set (match_operand:SI 1 "register_operand" "=r")
1036 (ltu:SI (plus:SI (match_dup 2) (match_dup 3)) (match_dup 2))
1037 (match_operand:SI 4 "register_operand" "%1"))
1038 (match_operand:SI 5 "rx_source_operand" "riQ")))
1039 (clobber (match_scratch:SI 6 "=&r"))
1040 (clobber (reg:CC CC_REG))]
1046 rtx op0l = operands[0];
1047 rtx op0h = operands[1];
1048 rtx op1l = operands[2];
1049 rtx op2l = operands[3];
1050 rtx op1h = operands[4];
1051 rtx op2h = operands[5];
1052 rtx scratch = operands[6];
1055 if (reg_overlap_mentioned_p (op0l, op1h))
1057 emit_move_insn (scratch, op0l);
1059 if (reg_overlap_mentioned_p (op0l, op2h))
1062 else if (reg_overlap_mentioned_p (op0l, op2h))
1064 emit_move_insn (scratch, op0l);
1068 if (rtx_equal_p (op0l, op1l))
1070 /* It is preferable that op0l == op1l... */
1071 else if (rtx_equal_p (op0l, op2l))
1072 x = op1l, op1l = op2l, op2l = x;
1073 /* ... but it is only a requirement if op2l == MEM. */
1074 else if (MEM_P (op2l))
1076 /* Let's hope that we still have a scratch register free. */
1077 gcc_assert (op1h != scratch);
1078 emit_move_insn (scratch, op2l);
1082 emit_insn (gen_addsi3_flags (op0l, op1l, op2l));
1084 if (rtx_equal_p (op0h, op1h))
1086 else if (rtx_equal_p (op0h, op2h))
1087 x = op1h, op1h = op2h, op2h = x;
1090 emit_move_insn (op0h, op1h);
1093 emit_insn (gen_adc_internal (op0h, op1h, op2h));
1097 (define_insn_and_split "andsi3"
1098 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,r,r,r")
1099 (and:SI (match_operand:SI 1 "register_operand" "%0,0,0,0,0,0,r,r,0")
1100 (match_operand:SI 2 "rx_source_operand" "r,Uint04,Sint08,Sint16,Sint24,i,0,r,Q")))
1101 (clobber (reg:CC CC_REG))]
1113 "&& RX_REG_P (operands[1]) && CONST_INT_P (operands[2])
1114 && pow2p_hwi (~UINTVAL (operands[2]))"
1117 /* For negated single bit constants use the bclr insn for smaller code. */
1119 if (!rx_reg_dead_or_unused_after_insn (curr_insn, CC_REG))
1122 rx_copy_reg_dead_or_unused_notes (operands[1], curr_insn,
1123 emit_insn (gen_bitclr (operands[0],
1124 GEN_INT (exact_log2 (~UINTVAL (operands[2]))),
1128 [(set_attr "timings" "11,11,11,11,11,11,11,11,33")
1129 (set_attr "length" "2,2,3,4,5,6,2,5,5")]
1132 (define_insn "*andsi3_flags"
1134 (compare (and:SI (match_operand:SI 1 "register_operand" "%0,0,0,0,0,0,r,r,0")
1135 (match_operand:SI 2 "rx_source_operand" "r,Uint04,Sint08,Sint16,Sint24,i,0,r,Q"))
1137 (set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,r,r,r")
1138 (and:SI (match_dup 1) (match_dup 2)))]
1139 "reload_completed && rx_match_ccmode (insn, CC_ZSmode)"
1150 [(set_attr "timings" "11,11,11,11,11,11,11,11,33")
1151 (set_attr "length" "2,2,3,4,5,6,2,5,5")]
1154 ;; Byte swap (single 32-bit value).
1155 (define_insn "bswapsi2"
1156 [(set (match_operand:SI 0 "register_operand" "=r")
1157 (bswap:SI (match_operand:SI 1 "register_operand" "r")))]
1160 [(set_attr "length" "3")]
1163 ;; Byte swap (single 16-bit value). Note - we ignore the swapping of the high 16-bits.
1164 (define_insn "bswaphi2"
1165 [(set (match_operand:HI 0 "register_operand" "=r")
1166 (bswap:HI (match_operand:HI 1 "register_operand" "r")))]
1169 [(set_attr "length" "3")]
1172 (define_insn "divsi3"
1173 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r")
1174 (div:SI (match_operand:SI 1 "register_operand" "0,0,0,0,0,0")
1175 (match_operand:SI 2 "rx_source_operand" "r,Sint08,Sint16,Sint24,i,Q")))
1176 (clobber (reg:CC CC_REG))]
1179 [(set_attr "timings" "1111") ;; Strictly speaking the timing should be
1180 ;; 2222, but that is a worst case sceanario.
1181 (set_attr "length" "3,4,5,6,7,6")]
1184 (define_insn "udivsi3"
1185 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r")
1186 (udiv:SI (match_operand:SI 1 "register_operand" "0,0,0,0,0,0")
1187 (match_operand:SI 2 "rx_source_operand" "r,Sint08,Sint16,Sint24,i,Q")))
1188 (clobber (reg:CC CC_REG))]
1191 [(set_attr "timings" "1010") ;; Strictly speaking the timing should be
1192 ;; 2020, but that is a worst case sceanario.
1193 (set_attr "length" "3,4,5,6,7,6")]
1196 ;; Note - these patterns are suppressed in big-endian mode because they
1197 ;; generate a little endian result. ie the most significant word of the
1198 ;; result is placed in the higher numbered register of the destination
1201 (define_insn "mulsidi3"
1202 [(set (match_operand:DI 0 "register_operand" "=r,r,r,r,r,r")
1203 (mult:DI (sign_extend:DI (match_operand:SI
1204 1 "register_operand" "%0,0,0,0,0,0"))
1205 (sign_extend:DI (match_operand:SI
1206 2 "rx_source_operand"
1207 "r,Sint08,Sint16,Sint24,i,Q"))))]
1208 "! TARGET_BIG_ENDIAN_DATA"
1210 [(set_attr "length" "3,4,5,6,7,6")
1211 (set_attr "timings" "22,22,22,22,22,44")]
1214 ;; See comment for mulsidi3.
1215 ;; Note - the zero_extends are to distinguish this pattern from the
1216 ;; mulsidi3 pattern. Immediate mode addressing is not supported
1217 ;; because gcc cannot handle the expression: (zero_extend (const_int)).
1218 (define_insn "umulsidi3"
1219 [(set (match_operand:DI 0 "register_operand" "=r,r")
1220 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0,0"))
1221 (zero_extend:DI (match_operand:SI 2 "rx_compare_operand" "r,Q"))))]
1222 "! TARGET_BIG_ENDIAN_DATA"
1224 [(set_attr "length" "3,6")
1225 (set_attr "timings" "22,44")]
1228 (define_insn "smaxsi3"
1229 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r")
1230 (smax:SI (match_operand:SI 1 "register_operand" "%0,0,0,0,0,0")
1231 (match_operand:SI 2 "rx_source_operand"
1232 "r,Sint08,Sint16,Sint24,i,Q")))]
1235 [(set_attr "length" "3,4,5,6,7,6")
1236 (set_attr "timings" "11,11,11,11,11,33")]
1239 (define_insn "sminsi3"
1240 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r")
1241 (smin:SI (match_operand:SI 1 "register_operand" "%0,0,0,0,0,0")
1242 (match_operand:SI 2 "rx_source_operand"
1243 "r,Sint08,Sint16,Sint24,i,Q")))]
1246 [(set_attr "length" "3,4,5,6,7,6")
1247 (set_attr "timings" "11,11,11,11,11,33")]
1250 (define_insn "umax<small_int_modes:mode>3_u"
1251 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r")
1252 (smax:SI (match_operand:SI 1 "register_operand" "%0,0,0,0,0,0")
1253 (zero_extend:SI (match_operand:small_int_modes 2 "rx_minmaxex_operand"
1254 "r,Sint08,Sint16,Sint24,i,Q"))))]
1257 [(set_attr "length" "3,4,5,6,7,6")
1258 (set_attr "timings" "11,11,11,11,11,33")]
1261 (define_insn "umin<small_int_modes:mode>3_ur"
1262 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r")
1263 (smin:SI (zero_extend:SI (match_operand:small_int_modes 2 "rx_minmaxex_operand"
1264 "r,Sint08,Sint16,Sint24,i,Q"))
1265 (match_operand:SI 1 "register_operand" "%0,0,0,0,0,0")))]
1268 [(set_attr "length" "3,4,5,6,7,6")
1269 (set_attr "timings" "11,11,11,11,11,33")]
1272 (define_insn "umax<small_int_modes:mode>3_ur"
1273 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r")
1274 (smax:SI (zero_extend:SI (match_operand:small_int_modes 2 "rx_minmaxex_operand"
1275 "r,Sint08,Sint16,Sint24,i,Q"))
1276 (match_operand:SI 1 "register_operand" "%0,0,0,0,0,0")))]
1279 [(set_attr "length" "3,4,5,6,7,6")
1280 (set_attr "timings" "11,11,11,11,11,33")]
1283 (define_expand "umax<small_int_modes:mode>3"
1285 (zero_extend:SI (match_operand:small_int_modes 1 "register_operand" "%0,0,0,0,0,0")))
1287 (smax:SI (match_dup 4)
1288 (match_operand:small_int_modes 2 "rx_source_operand"
1289 "r,Sint08,Sint16,Sint24,i,Q")))
1290 (set (match_operand:small_int_modes 0 "register_operand" "=r,r,r,r,r,r")
1294 "operands[3] = gen_reg_rtx (SImode);
1295 operands[4] = gen_reg_rtx (SImode);
1296 operands[5] = gen_reg_rtx (SImode);
1297 operands[6] = gen_rtx_SUBREG (GET_MODE (operands[0]), operands[3],
1298 TARGET_BIG_ENDIAN_DATA ? (GET_MODE (operands[0]) == HImode ? 2 : 3) : 0);
1299 if (GET_CODE (operands[2]) != CONST_INT)
1301 emit_move_insn (operands[5], gen_rtx_ZERO_EXTEND (SImode, operands[2]));
1302 operands[2] = operands[5];
1307 (define_expand "umin<small_int_modes:mode>3"
1309 (zero_extend:SI (match_operand:small_int_modes 1 "register_operand" "%0,0,0,0,0,0")))
1311 (smin:SI (match_dup 4)
1312 (match_operand:small_int_modes 2 "rx_source_operand"
1313 "r,Sint08,Sint16,Sint24,i,Q")))
1314 (set (match_operand:small_int_modes 0 "register_operand" "=r,r,r,r,r,r")
1318 "operands[3] = gen_reg_rtx (SImode);
1319 operands[4] = gen_reg_rtx (SImode);
1320 operands[5] = gen_reg_rtx (SImode);
1321 operands[6] = gen_rtx_SUBREG (GET_MODE (operands[0]), operands[3],
1322 TARGET_BIG_ENDIAN_DATA ? (GET_MODE (operands[0]) == HImode ? 2 : 3) : 0);
1323 if (GET_CODE (operands[2]) != CONST_INT)
1325 emit_move_insn (operands[5], gen_rtx_ZERO_EXTEND (SImode, operands[2]));
1326 operands[2] = operands[5];
1331 (define_insn "mulsi3"
1332 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,r,r,r")
1333 (mult:SI (match_operand:SI 1 "register_operand" "%0,0,0,0,0,0,0,r,r")
1334 (match_operand:SI 2 "rx_source_operand"
1335 "r,Uint04,Sint08,Sint16,Sint24,i,Q,0,r")))]
1347 [(set_attr "length" "2,2,3,4,5,6,5,2,3")
1348 (set_attr "timings" "11,11,11,11,11,11,33,11,11")]
1351 (define_insn "negsi2"
1352 [(set (match_operand:SI 0 "register_operand" "=r,r")
1353 (neg:SI (match_operand:SI 1 "register_operand" "0,r")))
1354 (clobber (reg:CC CC_REG))]
1359 [(set_attr "length" "2,3")]
1362 ;; Note that the O and C flags are not set as per a normal compare,
1363 ;; and thus are unusable in that context.
1364 (define_insn "*negsi2_flags"
1366 (compare (neg:SI (match_operand:SI 1 "register_operand" "0,r"))
1368 (set (match_operand:SI 0 "register_operand" "=r,r")
1369 (neg:SI (match_dup 1)))]
1370 "reload_completed && rx_match_ccmode (insn, CC_ZSmode)"
1374 [(set_attr "length" "2,3")]
1377 (define_insn "one_cmplsi2"
1378 [(set (match_operand:SI 0 "register_operand" "=r,r")
1379 (not:SI (match_operand:SI 1 "register_operand" "0,r")))
1380 (clobber (reg:CC CC_REG))]
1385 [(set_attr "length" "2,3")]
1388 (define_insn "*one_cmplsi2_flags"
1390 (compare (not:SI (match_operand:SI 1 "register_operand" "0,r"))
1392 (set (match_operand:SI 0 "register_operand" "=r,r")
1393 (not:SI (match_dup 1)))]
1394 "reload_completed && rx_match_ccmode (insn, CC_ZSmode)"
1398 [(set_attr "length" "2,3")]
1401 (define_insn_and_split "iorsi3"
1402 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,r,r,r")
1403 (ior:SI (match_operand:SI 1 "register_operand" "%0,0,0,0,0,0,r,r,0")
1404 (match_operand:SI 2 "rx_source_operand" "r,Uint04,Sint08,Sint16,Sint24,i,0,r,Q")))
1405 (clobber (reg:CC CC_REG))]
1417 "&& RX_REG_P (operands[1]) && CONST_INT_P (operands[2])
1418 && pow2p_hwi (UINTVAL (operands[2]))"
1421 /* For single bit constants use the bset insn for smaller code. */
1423 if (!rx_reg_dead_or_unused_after_insn (curr_insn, CC_REG))
1426 rx_copy_reg_dead_or_unused_notes (operands[1], curr_insn,
1427 emit_insn (gen_bitset (operands[0],
1428 GEN_INT (exact_log2 (UINTVAL (operands[2]))),
1432 [(set_attr "timings" "11,11,11,11,11,11,11,11,33")
1433 (set_attr "length" "2,2,3,4,5,6,2,3,5")]
1436 (define_insn "*iorsi3_flags"
1438 (compare (ior:SI (match_operand:SI 1 "register_operand" "%0,0,0,0,0,0,r,r,0")
1439 (match_operand:SI 2 "rx_source_operand" "r,Uint04,Sint08,Sint16,Sint24,i,0,r,Q"))
1441 (set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,r,r,r")
1442 (ior:SI (match_dup 1) (match_dup 2)))]
1443 "reload_completed && rx_match_ccmode (insn, CC_ZSmode)"
1454 [(set_attr "timings" "11,11,11,11,11,11,11,11,33")
1455 (set_attr "length" "2,2,3,4,5,6,2,3,5")]
1458 (define_insn "rotlsi3"
1459 [(set (match_operand:SI 0 "register_operand" "=r")
1460 (rotate:SI (match_operand:SI 1 "register_operand" "0")
1461 (match_operand:SI 2 "rx_shift_operand" "rn")))
1462 (clobber (reg:CC CC_REG))]
1465 [(set_attr "length" "3")]
1468 (define_insn "*rotlsi3_flags"
1470 (compare (rotate:SI (match_operand:SI 1 "register_operand" "0")
1471 (match_operand:SI 2 "rx_shift_operand" "rn"))
1473 (set (match_operand:SI 0 "register_operand" "=r")
1474 (rotate:SI (match_dup 1) (match_dup 2)))]
1475 "reload_completed && rx_match_ccmode (insn, CC_ZSmode)"
1477 [(set_attr "length" "3")]
1480 (define_insn "rotrsi3"
1481 [(set (match_operand:SI 0 "register_operand" "=r")
1482 (rotatert:SI (match_operand:SI 1 "register_operand" "0")
1483 (match_operand:SI 2 "rx_shift_operand" "rn")))
1484 (clobber (reg:CC CC_REG))]
1487 [(set_attr "length" "3")]
1490 (define_insn "*rotrsi3_flags"
1492 (compare (rotatert:SI (match_operand:SI 1 "register_operand" "0")
1493 (match_operand:SI 2 "rx_shift_operand" "rn"))
1495 (set (match_operand:SI 0 "register_operand" "=r")
1496 (rotatert:SI (match_dup 1) (match_dup 2)))]
1497 "reload_completed && rx_match_ccmode (insn, CC_ZSmode)"
1499 [(set_attr "length" "3")]
1502 (define_insn "ashrsi3"
1503 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
1504 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0,r")
1505 (match_operand:SI 2 "rx_shift_operand" "r,n,n")))
1506 (clobber (reg:CC CC_REG))]
1512 [(set_attr "length" "3,2,3")]
1515 (define_insn "*ashrsi3_flags"
1517 (compare (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0,r")
1518 (match_operand:SI 2 "rx_shift_operand" "r,n,n"))
1520 (set (match_operand:SI 0 "register_operand" "=r,r,r")
1521 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
1522 "reload_completed && rx_match_ccmode (insn, CC_ZSmode)"
1527 [(set_attr "length" "3,2,3")]
1530 (define_insn "lshrsi3"
1531 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
1532 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0,0,r")
1533 (match_operand:SI 2 "rx_shift_operand" "r,n,n")))
1534 (clobber (reg:CC CC_REG))]
1540 [(set_attr "length" "3,2,3")]
1543 (define_insn "*lshrsi3_flags"
1545 (compare (lshiftrt:SI (match_operand:SI 1 "register_operand" "0,0,r")
1546 (match_operand:SI 2 "rx_shift_operand" "r,n,n"))
1548 (set (match_operand:SI 0 "register_operand" "=r,r,r")
1549 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
1550 "reload_completed && rx_match_ccmode (insn, CC_ZSmode)"
1555 [(set_attr "length" "3,2,3")]
1558 (define_insn "ashlsi3"
1559 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
1560 (ashift:SI (match_operand:SI 1 "register_operand" "0,0,r")
1561 (match_operand:SI 2 "rx_shift_operand" "r,n,n")))
1562 (clobber (reg:CC CC_REG))]
1568 [(set_attr "length" "3,2,3")]
1571 (define_insn "*ashlsi3_flags"
1573 (compare (ashift:SI (match_operand:SI 1 "register_operand" "0,0,r")
1574 (match_operand:SI 2 "rx_shift_operand" "r,n,n"))
1576 (set (match_operand:SI 0 "register_operand" "=r,r,r")
1577 (ashift:SI (match_dup 1) (match_dup 2)))]
1578 "reload_completed && rx_match_ccmode (insn, CC_ZSmode)"
1583 [(set_attr "length" "3,2,3")]
1586 ;; Saturate to 32-bits
1587 (define_insn_and_split "ssaddsi3"
1588 [(set (match_operand:SI 0 "register_operand" "=r")
1589 (ss_plus:SI (match_operand:SI 1 "register_operand" "r")
1590 (match_operand:SI 2 "rx_source_operand" "riQ")))
1591 (clobber (reg:CC CC_REG))]
1595 [(parallel [(set (reg:CC_ZSC CC_REG)
1597 (plus:SI (match_dup 1) (match_dup 2))
1600 (plus:SI (match_dup 1) (match_dup 2)))])
1602 (unspec:SI [(match_dup 0) (reg:CC CC_REG)]
1603 UNSPEC_BUILTIN_SAT))]
1608 [(set (match_operand:SI 0 "register_operand" "=r")
1609 (unspec:SI [(match_operand:SI 1 "register_operand" "0")
1611 UNSPEC_BUILTIN_SAT))]
1614 [(set_attr "length" "2")]
1617 (define_insn "subsi3"
1618 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r")
1619 (minus:SI (match_operand:SI 1 "register_operand" "0,0,0,r,0")
1620 (match_operand:SI 2 "rx_source_operand" "r,Uint04,n,r,Q")))
1621 (clobber (reg:CC CC_REG))]
1629 [(set_attr "timings" "11,11,11,11,33")
1630 (set_attr "length" "2,2,6,3,5")]
1633 ;; Note that the O flag is set as if (compare op1 op2) not for
1634 ;; what is described here, (compare op0 0).
1635 (define_insn "*subsi3_flags"
1637 (compare (minus:SI (match_operand:SI 1 "register_operand" "0,0,0,r,0")
1638 (match_operand:SI 2 "rx_source_operand" "r,Uint04,n,r,Q"))
1640 (set (match_operand:SI 0 "register_operand" "=r,r,r,r,r")
1641 (minus:SI (match_dup 1) (match_dup 2)))]
1642 "reload_completed && rx_match_ccmode (insn, CC_ZSCmode)"
1649 [(set_attr "timings" "11,11,11,11,33")
1650 (set_attr "length" "2,2,6,3,5")]
1653 ;; A helper to expand the above with the CC_MODE filled in.
1654 (define_expand "subsi3_flags"
1655 [(parallel [(set (reg:CC_ZSC CC_REG)
1657 (minus:SI (match_operand:SI 1 "register_operand")
1658 (match_operand:SI 2 "rx_source_operand"))
1660 (set (match_operand:SI 0 "register_operand")
1661 (minus:SI (match_dup 1) (match_dup 2)))])]
1664 (define_insn "sbb_internal"
1665 [(set (match_operand:SI 0 "register_operand" "=r,r")
1668 (match_operand:SI 1 "register_operand" " 0,0")
1669 (match_operand:SI 2 "rx_compare_operand" " r,Q"))
1670 (geu:SI (reg:CC CC_REG) (const_int 0))))
1671 (clobber (reg:CC CC_REG))]
1674 [(set_attr "timings" "11,33")
1675 (set_attr "length" "3,6")]
1678 (define_insn "*sbb_flags"
1683 (match_operand:SI 1 "register_operand" " 0,0")
1684 (match_operand:SI 2 "rx_compare_operand" " r,Q"))
1685 (geu:SI (reg:CC CC_REG) (const_int 0)))
1687 (set (match_operand:SI 0 "register_operand" "=r,r")
1689 (minus:SI (match_dup 1) (match_dup 2))
1690 (geu:SI (reg:CC CC_REG) (const_int 0))))]
1693 [(set_attr "timings" "11,33")
1694 (set_attr "length" "3,6")]
1697 (define_expand "subdi3"
1698 [(set (match_operand:DI 0 "register_operand")
1699 (minus:DI (match_operand:DI 1 "register_operand")
1700 (match_operand:DI 2 "register_operand")))]
1703 rtx op0l, op0h, op1l, op1h, op2l, op2h;
1705 op0l = gen_lowpart (SImode, operands[0]);
1706 op1l = gen_lowpart (SImode, operands[1]);
1707 op2l = gen_lowpart (SImode, operands[2]);
1708 op0h = gen_highpart (SImode, operands[0]);
1709 op1h = gen_highpart (SImode, operands[1]);
1710 op2h = gen_highpart_mode (SImode, DImode, operands[2]);
1712 emit_insn (gen_subdi3_internal (op0l, op0h, op1l, op2l, op1h, op2h));
1716 (define_insn_and_split "subdi3_internal"
1717 [(set (match_operand:SI 0 "register_operand" "=&r,&r")
1718 (minus:SI (match_operand:SI 2 "register_operand" " 0, r")
1719 (match_operand:SI 3 "rx_compare_operand" "rQ, r")))
1720 (set (match_operand:SI 1 "register_operand" "= r, r")
1723 (match_operand:SI 4 "register_operand" " 1, 1")
1724 (match_operand:SI 5 "rx_compare_operand" " rQ,rQ"))
1725 (gtu:SI (match_dup 3) (match_dup 2))))
1726 (clobber (reg:CC CC_REG))]
1732 emit_insn (gen_subsi3_flags (operands[0], operands[2], operands[3]));
1733 emit_insn (gen_sbb_internal (operands[1], operands[4], operands[5]));
1737 (define_insn_and_split "xorsi3"
1738 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r")
1739 (xor:SI (match_operand:SI 1 "register_operand" "%0,0,0,0,0,0")
1740 (match_operand:SI 2 "rx_source_operand"
1741 "r,Sint08,Sint16,Sint24,i,Q")))
1742 (clobber (reg:CC CC_REG))]
1745 "&& RX_REG_P (operands[1]) && CONST_INT_P (operands[2])
1746 && pow2p_hwi (UINTVAL (operands[2]))"
1749 /* For single bit constants use the bnot insn for smaller code. */
1751 if (!rx_reg_dead_or_unused_after_insn (curr_insn, CC_REG))
1754 rx_copy_reg_dead_or_unused_notes (operands[1], curr_insn,
1755 emit_insn (gen_bitinvert (operands[0],
1756 GEN_INT (exact_log2 (UINTVAL (operands[2]))),
1760 [(set_attr "timings" "11,11,11,11,11,33")
1761 (set_attr "length" "3,4,5,6,7,6")]
1764 (define_insn "*xorsi3_flags"
1766 (compare (xor:SI (match_operand:SI 1 "register_operand" "%0,0,0,0,0,0")
1767 (match_operand:SI 2 "rx_source_operand"
1768 "r,Sint08,Sint16,Sint24,i,Q"))
1770 (set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r")
1771 (xor:SI (match_dup 1) (match_dup 2)))]
1772 "reload_completed && rx_match_ccmode (insn, CC_ZSmode)"
1774 [(set_attr "timings" "11,11,11,11,11,33")
1775 (set_attr "length" "3,4,5,6,7,6")]
1778 ;; A set of peepholes to catch extending loads followed by arithmetic operations.
1779 ;; We use iterators where possible to reduce the amount of typing and hence the
1780 ;; possibilities for typos.
1782 (define_code_iterator extend_types [(zero_extend "") (sign_extend "")])
1783 (define_code_attr letter [(zero_extend "R") (sign_extend "Q")])
1785 (define_code_iterator memex_commutative [(plus "") (and "") (ior "") (xor "")])
1786 (define_code_iterator memex_noncomm [(div "") (udiv "") (minus "")])
1787 (define_code_iterator memex_nocc [(smax "") (smin "") (mult "")])
1789 (define_code_attr op [(plus "add") (and "and") (div "div") (udiv "divu") (smax "max") (smin "min") (mult "mul") (ior "or") (minus "sub") (xor "xor")])
1792 [(set (match_operand:SI 0 "register_operand")
1793 (extend_types:SI (match_operand:small_int_modes 1 "rx_restricted_mem_operand")))
1794 (parallel [(set (match_operand:SI 2 "register_operand")
1795 (memex_commutative:SI (match_dup 0)
1797 (clobber (reg:CC CC_REG))])]
1798 "peep2_regno_dead_p (2, REGNO (operands[0])) && (optimize < 3 || optimize_size)"
1799 [(parallel [(set (match_dup 2)
1800 (memex_commutative:SI (match_dup 2)
1801 (extend_types:SI (match_dup 1))))
1802 (clobber (reg:CC CC_REG))])]
1806 [(set (match_operand:SI 0 "register_operand")
1807 (extend_types:SI (match_operand:small_int_modes 1 "rx_restricted_mem_operand")))
1808 (parallel [(set (match_operand:SI 2 "register_operand")
1809 (memex_commutative:SI (match_dup 2)
1811 (clobber (reg:CC CC_REG))])]
1812 "peep2_regno_dead_p (2, REGNO (operands[0])) && (optimize < 3 || optimize_size)"
1813 [(parallel [(set (match_dup 2)
1814 (memex_commutative:SI (match_dup 2)
1815 (extend_types:SI (match_dup 1))))
1816 (clobber (reg:CC CC_REG))])]
1820 [(set (match_operand:SI 0 "register_operand")
1821 (extend_types:SI (match_operand:small_int_modes 1 "rx_restricted_mem_operand")))
1822 (parallel [(set (match_operand:SI 2 "register_operand")
1823 (memex_noncomm:SI (match_dup 2)
1825 (clobber (reg:CC CC_REG))])]
1826 "peep2_regno_dead_p (2, REGNO (operands[0])) && (optimize < 3 || optimize_size)"
1827 [(parallel [(set (match_dup 2)
1828 (memex_noncomm:SI (match_dup 2)
1829 (extend_types:SI (match_dup 1))))
1830 (clobber (reg:CC CC_REG))])]
1834 [(set (match_operand:SI 0 "register_operand")
1835 (extend_types:SI (match_operand:small_int_modes 1 "rx_restricted_mem_operand")))
1836 (set (match_operand:SI 2 "register_operand")
1837 (memex_nocc:SI (match_dup 0)
1839 "peep2_regno_dead_p (2, REGNO (operands[0])) && (optimize < 3 || optimize_size)"
1841 (memex_nocc:SI (match_dup 2)
1842 (extend_types:SI (match_dup 1))))]
1846 [(set (match_operand:SI 0 "register_operand")
1847 (extend_types:SI (match_operand:small_int_modes 1 "rx_restricted_mem_operand")))
1848 (set (match_operand:SI 2 "register_operand")
1849 (memex_nocc:SI (match_dup 2)
1851 "peep2_regno_dead_p (2, REGNO (operands[0])) && (optimize < 3 || optimize_size)"
1853 (memex_nocc:SI (match_dup 2)
1854 (extend_types:SI (match_dup 1))))]
1857 (define_insn "<memex_commutative:code>si3_<extend_types:code><small_int_modes:mode>"
1858 [(set (match_operand:SI 0 "register_operand" "=r")
1859 (memex_commutative:SI (match_operand:SI 1 "register_operand" "%0")
1860 (extend_types:SI (match_operand:small_int_modes 2 "rx_restricted_mem_operand" "Q"))))
1861 (clobber (reg:CC CC_REG))]
1862 "(optimize < 3 || optimize_size)"
1863 "<memex_commutative:op>\t%<extend_types:letter>2, %0"
1864 [(set_attr "timings" "33")
1865 (set_attr "length" "5")] ;; This length is corrected in rx_adjust_insn_length
1868 (define_insn "<memex_noncomm:code>si3_<extend_types:code><small_int_modes:mode>"
1869 [(set (match_operand:SI 0 "register_operand" "=r")
1870 (memex_noncomm:SI (match_operand:SI 1 "register_operand" "0")
1871 (extend_types:SI (match_operand:small_int_modes 2 "rx_restricted_mem_operand" "Q"))))
1872 (clobber (reg:CC CC_REG))]
1873 "(optimize < 3 || optimize_size)"
1874 "<memex_noncomm:op>\t%<extend_types:letter>2, %0"
1875 [(set_attr "timings" "33")
1876 (set_attr "length" "5")] ;; This length is corrected in rx_adjust_insn_length
1879 (define_insn "<memex_nocc:code>si3_<extend_types:code><small_int_modes:mode>"
1880 [(set (match_operand:SI 0 "register_operand" "=r")
1881 (memex_nocc:SI (match_operand:SI 1 "register_operand" "%0")
1882 (extend_types:SI (match_operand:small_int_modes 2 "rx_restricted_mem_operand" "Q"))))]
1883 "(optimize < 3 || optimize_size)"
1884 "<memex_nocc:op>\t%<extend_types:letter>2, %0"
1885 [(set_attr "timings" "33")
1886 (set_attr "length" "5")] ;; This length is corrected in rx_adjust_insn_length
1890 [(set (match_operand:SI 0 "register_operand")
1891 (extend_types:SI (match_operand:small_int_modes 1 "rx_restricted_mem_operand")))
1892 (set (reg:CC CC_REG)
1893 (compare:CC (match_operand:SI 2 "register_operand")
1895 "peep2_regno_dead_p (2, REGNO (operands[0])) && (optimize < 3 || optimize_size)"
1896 [(set (reg:CC CC_REG)
1897 (compare:CC (match_dup 2)
1898 (extend_types:SI (match_dup 1))))]
1902 ;; (set (reg1) (sign_extend (mem))
1903 ;; (set (reg2) (zero_extend (reg1))
1905 ;; (set (reg2) (zero_extend (mem)))
1907 [(set (match_operand:SI 0 "register_operand")
1908 (sign_extend:SI (match_operand:small_int_modes 1 "memory_operand")))
1909 (set (match_operand:SI 2 "register_operand")
1910 (zero_extend:SI (match_operand:small_int_modes 3 "register_operand")))]
1911 "REGNO (operands[0]) == REGNO (operands[3])
1912 && (REGNO (operands[0]) == REGNO (operands[2])
1913 || peep2_regno_dead_p (2, REGNO (operands[0])))"
1915 (zero_extend:SI (match_dup 1)))]
1918 ;; Remove the redundant sign extension from:
1919 ;; (set (reg) (extend (mem)))
1920 ;; (set (reg) (extend (reg)))
1922 [(set (match_operand:SI 0 "register_operand")
1923 (extend_types:SI (match_operand:small_int_modes 1 "memory_operand")))
1925 (extend_types:SI (match_operand:small_int_modes 2 "register_operand")))]
1926 "REGNO (operands[0]) == REGNO (operands[2])"
1927 [(set (match_dup 0) (extend_types:SI (match_dup 1)))]
1930 (define_insn "comparesi3_<extend_types:code><small_int_modes:mode>"
1931 [(set (reg:CC CC_REG)
1932 (compare:CC (match_operand:SI 0 "register_operand" "r")
1933 (extend_types:SI (match_operand:small_int_modes 1 "rx_restricted_mem_operand" "Q"))))]
1934 "(optimize < 3 || optimize_size)"
1935 "cmp\t%<extend_types:letter>1, %0"
1936 [(set_attr "timings" "33")
1937 (set_attr "length" "5")] ;; This length is corrected in rx_adjust_insn_length
1940 ;; Floating Point Instructions
1942 (define_insn "addsf3"
1943 [(set (match_operand:SF 0 "register_operand" "=r,r,r")
1944 (plus:SF (match_operand:SF 1 "register_operand" "%0,0,0")
1945 (match_operand:SF 2 "rx_source_operand" "r,F,Q")))
1946 (clobber (reg:CC CC_REG))]
1947 "ALLOW_RX_FPU_INSNS"
1949 [(set_attr "timings" "44,44,66")
1950 (set_attr "length" "3,7,5")]
1953 (define_insn "divsf3"
1954 [(set (match_operand:SF 0 "register_operand" "=r,r,r")
1955 (div:SF (match_operand:SF 1 "register_operand" "0,0,0")
1956 (match_operand:SF 2 "rx_source_operand" "r,F,Q")))
1957 (clobber (reg:CC CC_REG))]
1958 "ALLOW_RX_FPU_INSNS"
1960 [(set_attr "timings" "1616,1616,1818")
1961 (set_attr "length" "3,7,5")]
1964 (define_insn "mulsf3"
1965 [(set (match_operand:SF 0 "register_operand" "=r,r,r")
1966 (mult:SF (match_operand:SF 1 "register_operand" "%0,0,0")
1967 (match_operand:SF 2 "rx_source_operand" "r,F,Q")))
1968 (clobber (reg:CC CC_REG))]
1969 "ALLOW_RX_FPU_INSNS"
1971 [(set_attr "timings" "33,33,55")
1972 (set_attr "length" "3,7,5")]
1975 (define_insn "subsf3"
1976 [(set (match_operand:SF 0 "register_operand" "=r,r,r")
1977 (minus:SF (match_operand:SF 1 "register_operand" "0,0,0")
1978 (match_operand:SF 2 "rx_source_operand" "r,F,Q")))
1979 (clobber (reg:CC CC_REG))]
1980 "ALLOW_RX_FPU_INSNS"
1982 [(set_attr "timings" "44,44,66")
1983 (set_attr "length" "3,7,5")]
1986 (define_insn "fix_truncsfsi2"
1987 [(set (match_operand:SI 0 "register_operand" "=r,r")
1988 (fix:SI (match_operand:SF 1 "rx_compare_operand" "r,Q")))
1989 (clobber (reg:CC CC_REG))]
1990 "ALLOW_RX_FPU_INSNS"
1992 [(set_attr "timings" "22,44")
1993 (set_attr "length" "3,5")]
1996 (define_insn "floatsisf2"
1997 [(set (match_operand:SF 0 "register_operand" "=r,r")
1998 (float:SF (match_operand:SI 1 "rx_compare_operand" "r,Q")))
1999 (clobber (reg:CC CC_REG))]
2000 "ALLOW_RX_FPU_INSNS"
2002 [(set_attr "timings" "22,44")
2003 (set_attr "length" "3,6")]
2006 ;; Bit manipulation instructions.
2008 ;; The *_in_memory patterns will not be matched automatically, not even with
2009 ;; combiner bridge patterns. Especially when the memory operands have a
2010 ;; displacement, the resulting patterns look too complex.
2011 ;; Instead we manually look around the matched insn to see if there is a
2012 ;; preceeding memory load and a following memory store of the modified register
2013 ;; which can be fused into the single *_in_memory insn.
2014 ;; Do that before register allocation, as it can eliminate one temporary
2015 ;; register that needs to be allocated.
2017 (define_insn_and_split "bitset"
2018 [(set (match_operand:SI 0 "register_operand" "=r")
2019 (ior:SI (ashift:SI (const_int 1)
2020 (match_operand:SI 1 "rx_shift_operand" "ri"))
2021 (match_operand:SI 2 "register_operand" "0")))]
2024 "&& can_create_pseudo_p ()"
2027 if (rx_fuse_in_memory_bitop (operands, curr_insn, &gen_bitset_in_memory))
2032 [(set_attr "length" "3")]
2035 (define_insn "bitset_in_memory"
2036 [(set (match_operand:QI 0 "rx_restricted_mem_operand" "+Q")
2037 (ior:QI (ashift:QI (const_int 1)
2038 (match_operand:QI 1 "nonmemory_operand" "ri"))
2042 [(set_attr "length" "5")
2043 (set_attr "timings" "33")]
2046 (define_insn_and_split "bitinvert"
2047 [(set (match_operand:SI 0 "register_operand" "=r")
2048 (xor:SI (ashift:SI (const_int 1)
2049 (match_operand:SI 1 "rx_shift_operand" "ri"))
2050 (match_operand:SI 2 "register_operand" "0")))]
2053 "&& can_create_pseudo_p ()"
2056 if (rx_fuse_in_memory_bitop (operands, curr_insn, &gen_bitinvert_in_memory))
2061 [(set_attr "length" "3")]
2064 (define_insn "bitinvert_in_memory"
2065 [(set (match_operand:QI 0 "rx_restricted_mem_operand" "+Q")
2066 (xor:QI (ashift:QI (const_int 1)
2067 (match_operand:QI 1 "nonmemory_operand" "ri"))
2071 [(set_attr "length" "5")
2072 (set_attr "timings" "33")]
2075 (define_insn_and_split "bitclr"
2076 [(set (match_operand:SI 0 "register_operand" "=r")
2080 (match_operand:SI 1 "rx_shift_operand" "ri")))
2081 (match_operand:SI 2 "register_operand" "0")))]
2084 "&& can_create_pseudo_p ()"
2087 if (rx_fuse_in_memory_bitop (operands, curr_insn, &gen_bitclr_in_memory))
2092 [(set_attr "length" "3")]
2095 (define_insn "bitclr_in_memory"
2096 [(set (match_operand:QI 0 "rx_restricted_mem_operand" "+Q")
2100 (match_operand:QI 1 "nonmemory_operand" "ri")))
2104 [(set_attr "length" "5")
2105 (set_attr "timings" "33")]
2108 (define_insn "*insv_imm"
2109 [(set (zero_extract:SI
2110 (match_operand:SI 0 "register_operand" "+r")
2112 (match_operand:SI 1 "rx_shift_operand" "ri"))
2113 (match_operand:SI 2 "const_int_operand" ""))]
2116 if (INTVAL (operands[2]) & 1)
2117 return "bset\t%1, %0";
2119 return "bclr\t%1, %0";
2121 [(set_attr "length" "3")]
2124 (define_insn_and_split "rx_insv_reg"
2125 [(set (zero_extract:SI
2126 (match_operand:SI 0 "register_operand" "+r")
2128 (match_operand:SI 1 "const_int_operand" ""))
2129 (match_operand:SI 2 "register_operand" "r"))
2130 (clobber (reg:CC CC_REG))]
2134 [(set (zero_extract:SI (match_dup 0) (const_int 1) (match_dup 1))
2139 /* Emit tst #1, op2. */
2140 flags = gen_rtx_REG (CC_ZSmode, CC_REG);
2141 x = gen_rtx_AND (SImode, operands[2], const1_rtx);
2142 x = gen_rtx_COMPARE (CC_ZSmode, x, const0_rtx);
2143 x = gen_rtx_SET (flags, x);
2147 operands[3] = gen_rtx_NE (SImode, flags, const0_rtx);
2150 (define_insn_and_split "*insv_cond"
2151 [(set (zero_extract:SI
2152 (match_operand:SI 0 "register_operand" "+r")
2154 (match_operand:SI 1 "const_int_operand" ""))
2155 (match_operator:SI 4 "comparison_operator"
2156 [(match_operand:SI 2 "register_operand" "r")
2157 (match_operand:SI 3 "rx_source_operand" "riQ")]))
2158 (clobber (reg:CC CC_REG))]
2162 [(set (zero_extract:SI (match_dup 0) (const_int 1) (match_dup 1))
2167 flags = gen_rtx_REG (CCmode, CC_REG);
2168 x = gen_rtx_COMPARE (CCmode, operands[2], operands[3]);
2169 x = gen_rtx_SET (flags, x);
2172 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[4]), SImode,
2176 (define_insn "*bmcc"
2177 [(set (zero_extract:SI
2178 (match_operand:SI 0 "register_operand" "+r")
2180 (match_operand:SI 1 "const_int_operand" ""))
2181 (match_operator:SI 2 "comparison_operator"
2182 [(reg CC_REG) (const_int 0)]))]
2185 [(set_attr "length" "3")]
2188 ;; Work around the fact that X=Y<0 is preferentially expanded as a shift.
2189 (define_insn_and_split "*insv_cond_lt"
2190 [(set (zero_extract:SI
2191 (match_operand:SI 0 "register_operand" "+r")
2193 (match_operand:SI 1 "const_int_operand" ""))
2194 (match_operator:SI 3 "rshift_operator"
2195 [(match_operand:SI 2 "register_operand" "r")
2197 (clobber (reg:CC CC_REG))]
2201 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 1) (match_dup 1))
2202 (lt:SI (match_dup 2) (const_int 0)))
2203 (clobber (reg:CC CC_REG))])]
2207 (define_expand "insv"
2208 [(set (zero_extract:SI
2209 (match_operand:SI 0 "register_operand") ;; Destination
2210 (match_operand:SI 1 "const_int_operand") ;; # of bits to set
2211 (match_operand:SI 2 "nonmemory_operand")) ;; Starting bit
2212 (match_operand:SI 3 "nonmemory_operand"))] ;; Bits to insert
2215 /* We only handle single-bit inserts. */
2216 if (!CONST_INT_P (operands[1]) || INTVAL (operands[1]) != 1)
2219 /* Either the bit to insert or the position must be constant. */
2220 if (CONST_INT_P (operands[3]))
2221 operands[3] = GEN_INT (INTVAL (operands[3]) & 1);
2222 else if (CONST_INT_P (operands[2]))
2224 emit_insn (gen_rx_insv_reg (operands[0], operands[2], operands[3]));
2231 ;; Atomic operations.
2233 (define_code_iterator FETCHOP [plus minus ior xor and])
2234 (define_code_iterator FETCHOP_NO_MINUS [plus ior xor and])
2236 (define_code_attr fetchop_name
2237 [(plus "add") (minus "sub") (ior "or") (xor "xor") (and "and")])
2239 (define_code_attr fetchop_name2
2240 [(plus "add") (minus "sub") (ior "ior") (xor "xor") (and "and")])
2242 (define_mode_iterator QIHI [QI HI])
2243 (define_mode_attr BW [(QI "B") (HI "W")])
2245 (define_insn "sync_lock_test_and_setsi"
2246 [(set (match_operand:SI 0 "register_operand" "=r,r")
2247 (match_operand:SI 1 "rx_compare_operand" "=r,Q"))
2249 (match_operand:SI 2 "register_operand" "0,0"))]
2252 [(set_attr "length" "3,6")
2253 (set_attr "timings" "22")]
2256 (define_expand "atomic_exchange<mode>"
2257 [(match_operand:QIHI 0 "register_operand") ;; oldval output
2258 (match_operand:QIHI 1 "rx_restricted_mem_operand") ;; memory
2259 (match_operand:QIHI 2 "register_operand") ;; newval input
2260 (match_operand:QIHI 3 "const_int_operand")] ;; memory model
2263 emit_insn (gen_xchg_mem<mode> (operands[0], operands[1], operands[2]));
2267 (define_expand "atomic_exchangesi"
2268 [(match_operand:SI 0 "register_operand") ;; oldval output
2269 (match_operand:SI 1 "rx_restricted_mem_operand") ;; memory
2270 (match_operand:SI 2 "register_operand") ;; newval input
2271 (match_operand:SI 3 "const_int_operand")] ;; memory model
2274 emit_insn (gen_sync_lock_test_and_setsi (operands[0], operands[1],
2279 (define_insn "xchg_mem<mode>"
2280 [(set (match_operand:QIHI 0 "register_operand" "=r")
2281 (match_operand:QIHI 1 "rx_compare_operand" "=Q"))
2283 (match_operand:QIHI 2 "register_operand" "0"))]
2286 [(set_attr "length" "6")
2287 (set_attr "timings" "22")]
2290 ;; read - modify - write - return old value
2291 (define_expand "atomic_fetch_<fetchop_name>si"
2292 [(set (match_operand:SI 0 "register_operand")
2293 (match_operand:SI 1 "memory_operand"))
2295 (FETCHOP:SI (match_dup 1) (match_operand:SI 2 "rx_source_operand")))
2296 (match_operand:SI 3 "const_int_operand")] ;; memory model
2300 rx_atomic_sequence seq (current_function_decl);
2302 emit_move_insn (operands[0], operands[1]);
2304 rtx tmp = gen_reg_rtx (SImode);
2305 emit_insn (gen_<fetchop_name2>si3 (tmp, operands[0], operands[2]));
2307 emit_move_insn (operands[1], tmp);
2312 (define_expand "atomic_fetch_nandsi"
2313 [(set (match_operand:SI 0 "register_operand")
2314 (match_operand:SI 1 "memory_operand"))
2316 (not:SI (and:SI (match_dup 1)
2317 (match_operand:SI 2 "rx_source_operand"))))
2318 (match_operand:SI 3 "const_int_operand")] ;; memory model
2322 rx_atomic_sequence seq (current_function_decl);
2324 emit_move_insn (operands[0], operands[1]);
2326 rtx tmp = gen_reg_rtx (SImode);
2327 emit_insn (gen_andsi3 (tmp, operands[0], operands[2]));
2328 emit_insn (gen_one_cmplsi2 (tmp, tmp));
2330 emit_move_insn (operands[1], tmp);
2335 ;; read - modify - write - return new value
2336 ;; Because subtraction is not commutative we need to specify a different
2337 ;; set of patterns for it.
2338 (define_expand "atomic_<fetchop_name>_fetchsi"
2339 [(set (match_operand:SI 0 "register_operand")
2340 (FETCHOP_NO_MINUS:SI (match_operand:SI 1 "rx_restricted_mem_operand")
2341 (match_operand:SI 2 "register_operand")))
2343 (FETCHOP_NO_MINUS:SI (match_dup 1) (match_dup 2)))
2344 (match_operand:SI 3 "const_int_operand")] ;; memory model
2348 rx_atomic_sequence seq (current_function_decl);
2350 emit_move_insn (operands[0], operands[2]);
2351 emit_insn (gen_<fetchop_name2>si3 (operands[0], operands[0], operands[1]));
2352 emit_move_insn (operands[1], operands[0]);
2357 (define_expand "atomic_sub_fetchsi"
2358 [(set (match_operand:SI 0 "register_operand")
2359 (minus:SI (match_operand:SI 1 "rx_restricted_mem_operand")
2360 (match_operand:SI 2 "rx_source_operand")))
2362 (minus:SI (match_dup 1) (match_dup 2)))
2363 (match_operand:SI 3 "const_int_operand")] ;; memory model
2367 rx_atomic_sequence seq (current_function_decl);
2369 emit_move_insn (operands[0], operands[1]);
2370 emit_insn (gen_subsi3 (operands[0], operands[0], operands[2]));
2371 emit_move_insn (operands[1], operands[0]);
2376 (define_expand "atomic_nand_fetchsi"
2377 [(set (match_operand:SI 0 "register_operand")
2378 (not:SI (and:SI (match_operand:SI 1 "rx_restricted_mem_operand")
2379 (match_operand:SI 2 "register_operand"))))
2381 (not:SI (and:SI (match_dup 1) (match_dup 2))))
2382 (match_operand:SI 3 "const_int_operand")] ;; memory model
2386 rx_atomic_sequence seq (current_function_decl);
2388 emit_move_insn (operands[0], operands[2]);
2389 emit_insn (gen_andsi3 (operands[0], operands[0], operands[1]));
2390 emit_insn (gen_one_cmplsi2 (operands[0], operands[0]));
2391 emit_move_insn (operands[1], operands[0]);
2397 ;; Block move functions.
2399 (define_expand "movstr"
2400 [(set (match_operand:BLK 1 "memory_operand") ;; Dest
2401 (match_operand:BLK 2 "memory_operand")) ;; Source
2402 (use (match_operand:SI 0 "register_operand")) ;; Updated Dest
2404 "rx_allow_string_insns"
2406 rtx addr1 = gen_rtx_REG (SImode, 1);
2407 rtx addr2 = gen_rtx_REG (SImode, 2);
2408 rtx len = gen_rtx_REG (SImode, 3);
2409 rtx dest_copy = gen_reg_rtx (SImode);
2411 emit_move_insn (len, GEN_INT (-1));
2412 emit_move_insn (addr1, force_operand (XEXP (operands[1], 0), NULL_RTX));
2413 emit_move_insn (addr2, force_operand (XEXP (operands[2], 0), NULL_RTX));
2414 operands[1] = replace_equiv_address_nv (operands[1], addr1);
2415 operands[2] = replace_equiv_address_nv (operands[2], addr2);
2416 emit_move_insn (dest_copy, addr1);
2417 emit_insn (gen_rx_movstr ());
2418 emit_move_insn (len, GEN_INT (-1));
2419 emit_insn (gen_rx_strend (operands[0], dest_copy));
2424 (define_insn "rx_movstr"
2425 [(set (mem:BLK (reg:SI 1))
2426 (mem:BLK (reg:SI 2)))
2427 (unspec_volatile:BLK [(reg:SI 1) (reg:SI 2) (reg:SI 3)] UNSPEC_MOVSTR)
2428 (clobber (reg:SI 1))
2429 (clobber (reg:SI 2))
2430 (clobber (reg:SI 3))]
2431 "rx_allow_string_insns"
2433 [(set_attr "length" "2")
2434 (set_attr "timings" "1111")] ;; The timing is a guesstimate.
2437 (define_insn "rx_strend"
2438 [(set (match_operand:SI 0 "register_operand" "=r")
2439 (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "r")
2440 (reg:SI 3)] UNSPEC_STRLEN))
2441 (clobber (reg:SI 1))
2442 (clobber (reg:SI 2))
2443 (clobber (reg:SI 3))
2444 (clobber (reg:CC CC_REG))
2446 "rx_allow_string_insns"
2447 "mov\t%1, r1\n\tmov\t#0, r2\n\tsuntil.b\n\tmov\tr1, %0\n\tsub\t#1, %0"
2448 [(set_attr "length" "10")
2449 (set_attr "timings" "1111")] ;; The timing is a guesstimate.
2452 (define_expand "cpymemsi"
2454 [(set (match_operand:BLK 0 "memory_operand") ;; Dest
2455 (match_operand:BLK 1 "memory_operand")) ;; Source
2456 (use (match_operand:SI 2 "register_operand")) ;; Length in bytes
2457 (match_operand 3 "immediate_operand") ;; Align
2458 (unspec_volatile:BLK [(reg:SI 1) (reg:SI 2) (reg:SI 3)] UNSPEC_CPYMEM)]
2460 "rx_allow_string_insns"
2462 rtx addr1 = gen_rtx_REG (SImode, 1);
2463 rtx addr2 = gen_rtx_REG (SImode, 2);
2464 rtx len = gen_rtx_REG (SImode, 3);
2466 /* Do not use when the source or destination are volatile - the SMOVF
2467 instruction will read and write in word sized blocks, which may be
2468 outside of the valid address range. */
2469 if (MEM_P (operands[0]) && MEM_VOLATILE_P (operands[0]))
2471 if (MEM_P (operands[1]) && MEM_VOLATILE_P (operands[1]))
2474 if (REG_P (operands[0]) && (REGNO (operands[0]) == 2
2475 || REGNO (operands[0]) == 3))
2477 if (REG_P (operands[1]) && (REGNO (operands[1]) == 1
2478 || REGNO (operands[1]) == 3))
2480 if (REG_P (operands[2]) && (REGNO (operands[2]) == 1
2481 || REGNO (operands[2]) == 2))
2484 emit_move_insn (addr1, force_operand (XEXP (operands[0], 0), NULL_RTX));
2485 emit_move_insn (addr2, force_operand (XEXP (operands[1], 0), NULL_RTX));
2486 emit_move_insn (len, force_operand (operands[2], NULL_RTX));
2487 operands[0] = replace_equiv_address_nv (operands[0], addr1);
2488 operands[1] = replace_equiv_address_nv (operands[1], addr2);
2489 emit_insn (gen_rx_cpymem ());
2494 (define_insn "rx_cpymem"
2495 [(set (mem:BLK (reg:SI 1))
2496 (mem:BLK (reg:SI 2)))
2498 (unspec_volatile:BLK [(reg:SI 1) (reg:SI 2) (reg:SI 3)] UNSPEC_CPYMEM)
2499 (clobber (reg:SI 1))
2500 (clobber (reg:SI 2))
2501 (clobber (reg:SI 3))]
2502 "rx_allow_string_insns"
2504 [(set_attr "length" "2")
2505 (set_attr "timings" "1111")] ;; The timing is a guesstimate.
2508 (define_expand "setmemsi"
2509 [(set (match_operand:BLK 0 "memory_operand") ;; Dest
2510 (match_operand:QI 2 "nonmemory_operand")) ;; Value
2511 (use (match_operand:SI 1 "nonmemory_operand")) ;; Length
2512 (match_operand 3 "immediate_operand") ;; Align
2513 (unspec_volatile:BLK [(reg:SI 1) (reg:SI 2) (reg:SI 3)] UNSPEC_SETMEM)]
2514 "rx_allow_string_insns"
2516 rtx addr = gen_rtx_REG (SImode, 1);
2517 rtx val = gen_rtx_REG (QImode, 2);
2518 rtx len = gen_rtx_REG (SImode, 3);
2520 emit_move_insn (addr, force_operand (XEXP (operands[0], 0), NULL_RTX));
2521 emit_move_insn (len, force_operand (operands[1], NULL_RTX));
2522 emit_move_insn (val, operands[2]);
2523 emit_insn (gen_rx_setmem ());
2528 (define_insn "rx_setmem"
2529 [(set (mem:BLK (reg:SI 1))
2530 (unspec_volatile:BLK [(reg:SI 1) (reg:SI 2) (reg:SI 3)] UNSPEC_SETMEM))
2531 (clobber (reg:SI 1))
2532 (clobber (reg:SI 3))]
2533 "rx_allow_string_insns"
2535 [(set_attr "length" "2")
2536 (set_attr "timings" "1111")] ;; The timing is a guesstimate.
2539 (define_expand "cmpstrnsi"
2540 [(set (match_operand:SI 0 "register_operand") ;; Result
2541 (unspec_volatile:SI [(match_operand:BLK 1 "memory_operand") ;; String1
2542 (match_operand:BLK 2 "memory_operand")] ;; String2
2544 (use (match_operand:SI 3 "register_operand")) ;; Max Length
2545 (match_operand:SI 4 "immediate_operand")] ;; Known Align
2546 "rx_allow_string_insns"
2548 rtx str1 = gen_rtx_REG (SImode, 1);
2549 rtx str2 = gen_rtx_REG (SImode, 2);
2550 rtx len = gen_rtx_REG (SImode, 3);
2552 emit_move_insn (str1, force_operand (XEXP (operands[1], 0), NULL_RTX));
2553 emit_move_insn (str2, force_operand (XEXP (operands[2], 0), NULL_RTX));
2554 emit_move_insn (len, operands[3]);
2556 emit_insn (gen_rx_cmpstrn (operands[0], operands[1], operands[2]));
2561 (define_expand "cmpstrsi"
2562 [(set (match_operand:SI 0 "register_operand") ;; Result
2563 (unspec_volatile:SI [(match_operand:BLK 1 "memory_operand") ;; String1
2564 (match_operand:BLK 2 "memory_operand")] ;; String2
2566 (match_operand:SI 3 "immediate_operand")] ;; Known Align
2567 "rx_allow_string_insns"
2569 rtx str1 = gen_rtx_REG (SImode, 1);
2570 rtx str2 = gen_rtx_REG (SImode, 2);
2571 rtx len = gen_rtx_REG (SImode, 3);
2573 emit_move_insn (str1, force_reg (SImode, XEXP (operands[1], 0)));
2574 emit_move_insn (str2, force_reg (SImode, XEXP (operands[2], 0)));
2575 emit_move_insn (len, GEN_INT (-1));
2577 emit_insn (gen_rx_cmpstrn (operands[0], operands[1], operands[2]));
2582 (define_insn "rx_cmpstrn"
2583 [(set (match_operand:SI 0 "register_operand" "=r")
2584 (unspec_volatile:SI [(reg:SI 1) (reg:SI 2) (reg:SI 3)]
2586 (use (match_operand:BLK 1 "memory_operand" "m"))
2587 (use (match_operand:BLK 2 "memory_operand" "m"))
2588 (clobber (reg:SI 1))
2589 (clobber (reg:SI 2))
2590 (clobber (reg:SI 3))
2591 (clobber (reg:CC CC_REG))]
2592 "rx_allow_string_insns"
2593 "scmpu ; Perform the string comparison
2594 mov #-1, %0 ; Set up -1 result (which cannot be created
2596 bnc ?+ ; If Carry is not set skip over
2597 scne.L %0 ; Set result based on Z flag
2600 [(set_attr "length" "9")
2601 (set_attr "timings" "1111")] ;; The timing is a guesstimate.
2604 ;; Builtin Functions
2606 ;; GCC does not have the ability to generate the following instructions
2607 ;; on its own so they are provided as builtins instead. To use them from
2608 ;; a program for example invoke them as __builtin_rx_<insn_name>. For
2611 ;; int short_byte_swap (int arg) { return __builtin_rx_revw (arg); }
2613 ;;---------- Accumulator Support ------------------------
2615 ;; Multiply & Accumulate (high)
2616 (define_insn "machi"
2617 [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
2618 (match_operand:SI 1 "register_operand" "r")]
2619 UNSPEC_BUILTIN_MACHI)]
2622 [(set_attr "length" "3")]
2625 ;; Multiply & Accumulate (low)
2626 (define_insn "maclo"
2627 [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
2628 (match_operand:SI 1 "register_operand" "r")]
2629 UNSPEC_BUILTIN_MACLO)]
2632 [(set_attr "length" "3")]
2636 (define_insn "mulhi"
2637 [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
2638 (match_operand:SI 1 "register_operand" "r")]
2639 UNSPEC_BUILTIN_MULHI)]
2642 [(set_attr "length" "3")]
2646 (define_insn "mullo"
2647 [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
2648 (match_operand:SI 1 "register_operand" "r")]
2649 UNSPEC_BUILTIN_MULLO)]
2652 [(set_attr "length" "3")]
2655 ;; Move from Accumulator (high)
2656 (define_insn "mvfachi"
2657 [(set (match_operand:SI 0 "register_operand" "=r")
2658 (unspec:SI [(const_int 0)]
2659 UNSPEC_BUILTIN_MVFACHI))]
2662 [(set_attr "length" "3")]
2665 ;; Move from Accumulator (middle)
2666 (define_insn "mvfacmi"
2667 [(set (match_operand:SI 0 "register_operand" "=r")
2668 (unspec:SI [(const_int 0)]
2669 UNSPEC_BUILTIN_MVFACMI))]
2672 [(set_attr "length" "3")]
2675 ;; Move to Accumulator (high)
2676 (define_insn "mvtachi"
2677 [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")]
2678 UNSPEC_BUILTIN_MVTACHI)]
2681 [(set_attr "length" "3")]
2684 ;; Move to Accumulator (low)
2685 (define_insn "mvtaclo"
2686 [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")]
2687 UNSPEC_BUILTIN_MVTACLO)]
2690 [(set_attr "length" "3")]
2693 ;; Round Accumulator
2695 [(unspec_volatile:SI [(match_operand:SI 0 "immediate_operand" "i")]
2696 UNSPEC_BUILTIN_RACW)]
2699 [(set_attr "length" "3")]
2702 ;; Repeat multiply and accumulate
2704 [(unspec:SI [(const_int 0) (reg:SI 1) (reg:SI 2) (reg:SI 3)
2705 (reg:SI 4) (reg:SI 5) (reg:SI 6)]
2706 UNSPEC_BUILTIN_RMPA)
2707 (clobber (reg:SI 1))
2708 (clobber (reg:SI 2))
2709 (clobber (reg:SI 3))]
2710 "rx_allow_string_insns"
2712 [(set_attr "length" "2")
2713 (set_attr "timings" "1010")]
2716 ;;---------- Arithmetic ------------------------
2718 ;; Byte swap (two 16-bit values).
2720 [(set (match_operand:SI 0 "register_operand" "=r")
2721 (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
2722 UNSPEC_BUILTIN_REVW))]
2725 [(set_attr "length" "3")]
2728 ;; Round to integer.
2729 (define_insn "lrintsf2"
2730 [(set (match_operand:SI 0 "register_operand" "=r,r")
2731 (unspec:SI [(match_operand:SF 1 "rx_compare_operand" "r,Q")]
2732 UNSPEC_BUILTIN_ROUND))
2733 (clobber (reg:CC CC_REG))]
2736 [(set_attr "timings" "22,44")
2737 (set_attr "length" "3,5")]
2740 ;;---------- Control Registers ------------------------
2742 ;; Clear Processor Status Word
2743 (define_insn "clrpsw"
2744 [(unspec_volatile:SI [(match_operand:SI 0 "immediate_operand" "i")]
2745 UNSPEC_BUILTIN_CLRPSW)
2746 (clobber (reg:CC CC_REG))]
2749 [(set_attr "length" "2")]
2752 ;; Set Processor Status Word
2753 (define_insn "setpsw"
2754 [(unspec_volatile:SI [(match_operand:SI 0 "immediate_operand" "i")]
2755 UNSPEC_BUILTIN_SETPSW)
2756 (clobber (reg:CC CC_REG))]
2759 [(set_attr "length" "2")]
2762 ;; Move from control register
2764 [(set (match_operand:SI 0 "register_operand" "=r")
2765 (unspec_volatile:SI [(match_operand:SI 1 "immediate_operand" "i")]
2766 UNSPEC_BUILTIN_MVFC))]
2769 [(set_attr "length" "3")]
2772 ;; Move to control register
2773 ;; This insn can be used in atomic sequences to restore the previous PSW
2774 ;; and re-enable interrupts. Because of that it always clobbers the CC_REG.
2776 [(unspec_volatile:SI [(match_operand:SI 0 "immediate_operand" "i,i")
2777 (match_operand:SI 1 "nonmemory_operand" "r,i")]
2778 UNSPEC_BUILTIN_MVTC)
2779 (clobber (reg:CC CC_REG))]
2782 [(set_attr "length" "3,7")]
2785 ;; Move to interrupt priority level
2786 (define_insn "mvtipl"
2787 [(unspec_volatile:SI [(match_operand:SI 0 "immediate_operand" "Uint04")]
2788 UNSPEC_BUILTIN_MVTIPL)]
2791 [(set_attr "length" "3")]
2794 ;;---------- Interrupts ------------------------
2798 [(unspec_volatile [(const_int 0)]
2799 UNSPEC_BUILTIN_BRK)]
2802 [(set_attr "length" "1")
2803 (set_attr "timings" "66")]
2808 [(unspec_volatile:SI [(match_operand:SI 0 "immediate_operand" "i")]
2809 UNSPEC_BUILTIN_INT)]
2812 [(set_attr "length" "3")]
2817 [(unspec_volatile [(const_int 0)]
2818 UNSPEC_BUILTIN_WAIT)]
2821 [(set_attr "length" "2")]
2824 ;;---------- CoProcessor Support ------------------------
2826 ;; FIXME: The instructions are currently commented out because
2827 ;; the bit patterns have not been finalized, so the assembler
2828 ;; does not support them. Once they are decided and the assembler
2829 ;; supports them, enable the instructions here.
2831 ;; Move from co-processor register
2832 (define_insn "mvfcp"
2833 [(set (match_operand:SI 0 "register_operand" "=r")
2834 (unspec:SI [(match_operand:SI 1 "immediate_operand" "i")
2835 (match_operand:SI 2 "immediate_operand" "i")]
2836 UNSPEC_BUILTIN_MVFCP))]
2838 "; mvfcp\t%1, %0, %2"
2839 [(set_attr "length" "5")]
2842 ;;---------- Misc ------------------------
2844 ;; Required by cfglayout.c...
2849 [(set_attr "length" "1")]
2852 (define_expand "pid_addr"
2853 [(plus:SI (match_operand:SI 0)
2854 (const:SI (unspec:SI [(match_operand:SI 1)] UNSPEC_PID_ADDR)))]
2859 (define_insn "movdi"
2860 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
2861 (match_operand:DI 1 "general_operand" "rmi"))]
2863 { return rx_gen_move_template (operands, false); }
2864 [(set_attr "length" "16")
2865 (set_attr "timings" "22")]
2868 (define_insn "movdf"
2869 [(set (match_operand:DF 0 "nonimmediate_operand" "=rm")
2870 (match_operand:DF 1 "general_operand" "rmi"))]
2872 { return rx_gen_move_template (operands, false); }
2873 [(set_attr "length" "16")
2874 (set_attr "timings" "22")]