1 ;; Machine Description for Renesas RX processors
2 ;; Copyright (C) 2008, 2009, 2010 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 ;; We do not handle DFmode here because it is either
26 ;; the same as SFmode, or if -m64bit-doubles is active
27 ;; then all operations on doubles have to be handled by
29 (define_mode_iterator register_modes
30 [(SF "ALLOW_RX_FPU_INSNS") (SI "") (HI "") (QI "")])
33 ;; Used to map RX condition names to GCC
34 ;; condition names for builtin instructions.
35 (define_code_iterator gcc_conds [eq ne gt ge lt le gtu geu ltu leu
37 (define_code_attr rx_conds [(eq "eq") (ne "ne") (gt "gt") (ge "ge") (lt "lt")
38 (le "le") (gtu "gtu") (geu "geu") (ltu "ltu")
39 (leu "leu") (unge "pz") (unlt "n") (uneq "o")
60 (UNSPEC_BUILTIN_BRK 30)
61 (UNSPEC_BUILTIN_CLRPSW 31)
62 (UNSPEC_BUILTIN_INT 32)
63 (UNSPEC_BUILTIN_MACHI 33)
64 (UNSPEC_BUILTIN_MACLO 34)
65 (UNSPEC_BUILTIN_MULHI 35)
66 (UNSPEC_BUILTIN_MULLO 36)
67 (UNSPEC_BUILTIN_MVFACHI 37)
68 (UNSPEC_BUILTIN_MVFACMI 38)
69 (UNSPEC_BUILTIN_MVFC 39)
70 (UNSPEC_BUILTIN_MVFCP 40)
71 (UNSPEC_BUILTIN_MVTACHI 41)
72 (UNSPEC_BUILTIN_MVTACLO 42)
73 (UNSPEC_BUILTIN_MVTC 43)
74 (UNSPEC_BUILTIN_MVTIPL 44)
75 (UNSPEC_BUILTIN_RACW 45)
76 (UNSPEC_BUILTIN_REVW 46)
77 (UNSPEC_BUILTIN_RMPA 47)
78 (UNSPEC_BUILTIN_ROUND 48)
79 (UNSPEC_BUILTIN_SAT 49)
80 (UNSPEC_BUILTIN_SETPSW 50)
81 (UNSPEC_BUILTIN_WAIT 51)
85 (define_attr "length" "" (const_int 8))
87 (include "predicates.md")
88 (include "constraints.md")
90 ;; Pipeline description.
92 ;; The RX only has a single pipeline. It has five stages (fetch,
93 ;; decode, execute, memory access, writeback) each of which normally
94 ;; takes a single CPU clock cycle.
96 ;; The timings attribute consists of two numbers, the first is the
97 ;; throughput, which is the number of cycles the instruction takes
98 ;; to execute and generate a result. The second is the latency
99 ;; which is the effective number of cycles the instruction takes to
100 ;; execute if its result is used by the following instruction. The
101 ;; latency is always greater than or equal to the throughput.
102 ;; These values were taken from tables 2.13 and 2.14 in section 2.8
103 ;; of the RX610 Group Hardware Manual v0.11
105 ;; Note - it would be nice to use strings rather than integers for
106 ;; the possible values of this attribute, so that we can have the
107 ;; gcc build mechanism check for values that are not supported by
108 ;; the reservations below. But this will not work because the code
109 ;; in rx_adjust_sched_cost() needs integers not strings.
111 (define_attr "timings" "" (const_int 11))
113 (define_automaton "pipelining")
114 (define_cpu_unit "throughput" "pipelining")
116 (define_insn_reservation "throughput__1_latency__1" 1
117 (eq_attr "timings" "11") "throughput")
118 (define_insn_reservation "throughput__1_latency__2" 2
119 (eq_attr "timings" "12") "throughput,nothing")
120 (define_insn_reservation "throughput__2_latency__2" 1
121 (eq_attr "timings" "22") "throughput*2")
122 (define_insn_reservation "throughput__3_latency__3" 1
123 (eq_attr "timings" "33") "throughput*3")
124 (define_insn_reservation "throughput__3_latency__4" 2
125 (eq_attr "timings" "34") "throughput*3,nothing")
126 (define_insn_reservation "throughput__4_latency__4" 1
127 (eq_attr "timings" "44") "throughput*4")
128 (define_insn_reservation "throughput__4_latency__5" 2
129 (eq_attr "timings" "45") "throughput*4,nothing")
130 (define_insn_reservation "throughput__5_latency__5" 1
131 (eq_attr "timings" "55") "throughput*5")
132 (define_insn_reservation "throughput__5_latency__6" 2
133 (eq_attr "timings" "56") "throughput*5,nothing")
134 (define_insn_reservation "throughput__6_latency__6" 1
135 (eq_attr "timings" "66") "throughput*6")
136 (define_insn_reservation "throughput_10_latency_10" 1
137 (eq_attr "timings" "1010") "throughput*10")
138 (define_insn_reservation "throughput_11_latency_11" 1
139 (eq_attr "timings" "1111") "throughput*11")
140 (define_insn_reservation "throughput_16_latency_16" 1
141 (eq_attr "timings" "1616") "throughput*16")
142 (define_insn_reservation "throughput_18_latency_18" 1
143 (eq_attr "timings" "1818") "throughput*18")
145 ;; ----------------------------------------------------------------------------
149 ;; Note - we do not specify the two instructions necessary to perform
150 ;; a compare-and-branch in the cbranchsi4 pattern because that would
151 ;; allow the comparison to be moved away from the jump before the reload
152 ;; pass has completed. That would be problematical because reload can
153 ;; generate ADDSI3 instructions which would corrupt the PSW flags.
155 (define_expand "cbranchsi4"
158 (match_operator 0 "comparison_operator"
159 [(match_operand:SI 1 "register_operand")
160 (match_operand:SI 2 "rx_source_operand")])
161 (label_ref (match_operand 3 ""))
166 (define_insn_and_split "*cbranchsi4"
169 (match_operator 3 "comparison_operator"
170 [(match_operand:SI 0 "register_operand" "r")
171 (match_operand:SI 1 "rx_source_operand" "riQ")])
172 (match_operand 2 "label_ref_operand" "")
179 rx_split_cbranch (CCmode, GET_CODE (operands[3]),
180 operands[0], operands[1], operands[2]);
184 (define_insn "*cmpsi"
185 [(set (reg:CC CC_REG)
186 (compare:CC (match_operand:SI 0 "register_operand" "r,r,r,r,r,r,r")
187 (match_operand:SI 1 "rx_source_operand" "r,Uint04,Int08,Sint16,Sint24,i,Q")))]
190 [(set_attr "timings" "11,11,11,11,11,11,33")
191 (set_attr "length" "2,2,3,4,5,6,5")]
194 ;; Canonical method for representing TST.
195 (define_insn_and_split "*cbranchsi4_tst"
198 (match_operator 3 "rx_zs_comparison_operator"
199 [(and:SI (match_operand:SI 0 "register_operand" "r")
200 (match_operand:SI 1 "rx_source_operand" "riQ"))
202 (match_operand 2 "label_ref_operand" "")
209 rx_split_cbranch (CC_ZSmode, GET_CODE (operands[3]),
210 XEXP (operands[3], 0), XEXP (operands[3], 1),
215 ;; Various other ways that GCC codes "var & const"
216 (define_insn_and_split "*cbranchsi4_tst_ext"
219 (match_operator 4 "rx_z_comparison_operator"
221 (match_operand:SI 0 "register_operand" "r")
222 (match_operand:SI 1 "rx_constshift_operand" "")
223 (match_operand:SI 2 "rx_constshift_operand" ""))
225 (match_operand 3 "label_ref_operand" "")
236 mask <<= INTVAL (operands[1]);
238 mask <<= INTVAL (operands[2]);
239 x = gen_rtx_AND (SImode, operands[0], gen_int_mode (mask, SImode));
241 rx_split_cbranch (CC_ZSmode, GET_CODE (operands[4]),
242 x, const0_rtx, operands[3]);
246 (define_insn "*tstsi"
247 [(set (reg:CC_ZS CC_REG)
249 (and:SI (match_operand:SI 0 "register_operand" "r,r,r")
250 (match_operand:SI 1 "rx_source_operand" "r,i,Q"))
254 [(set_attr "timings" "11,11,33")
255 (set_attr "length" "3,7,6")]
258 (define_expand "cbranchsf4"
261 (match_operator 0 "comparison_operator"
262 [(match_operand:SF 1 "register_operand")
263 (match_operand:SF 2 "register_operand")])
264 (label_ref (match_operand 3 ""))
268 enum rtx_code cmp1, cmp2;
270 /* If the comparison needs swapping of operands, do that now.
271 Do not split the comparison in two yet. */
272 if (rx_split_fp_compare (GET_CODE (operands[0]), &cmp1, &cmp2))
278 gcc_assert (cmp1 == UNORDERED);
289 operands[0] = gen_rtx_fmt_ee (cmp1, VOIDmode, op1, op2);
295 (define_insn_and_split "*cbranchsf4"
298 (match_operator 3 "rx_fp_comparison_operator"
299 [(match_operand:SF 0 "register_operand" "r")
300 (match_operand:SF 1 "rx_source_operand" "rFiQ")])
301 (match_operand 2 "label_ref_operand" "")
305 "&& reload_completed"
308 enum rtx_code cmp0, cmp1, cmp2;
309 rtx flags, lab1, lab2, over, x;
312 cmp0 = GET_CODE (operands[3]);
313 swap = rx_split_fp_compare (cmp0, &cmp1, &cmp2);
316 flags = gen_rtx_REG (CC_Fmode, CC_REG);
317 x = gen_rtx_COMPARE (CC_Fmode, operands[0], operands[1]);
318 x = gen_rtx_SET (VOIDmode, flags, x);
322 lab1 = lab2 = operands[2];
324 /* The one case of LTGT needs to be split into cmp1 && cmp2. */
327 over = gen_label_rtx ();
328 lab1 = gen_rtx_LABEL_REF (VOIDmode, over);
329 cmp1 = reverse_condition_maybe_unordered (cmp1);
332 /* Otherwise we split into cmp1 || cmp2. */
333 x = gen_rtx_fmt_ee (cmp1, VOIDmode, flags, const0_rtx);
334 x = gen_rtx_IF_THEN_ELSE (VOIDmode, x, lab1, pc_rtx);
335 x = gen_rtx_SET (VOIDmode, pc_rtx, x);
340 x = gen_rtx_fmt_ee (cmp2, VOIDmode, flags, const0_rtx);
341 x = gen_rtx_IF_THEN_ELSE (VOIDmode, x, lab2, pc_rtx);
342 x = gen_rtx_SET (VOIDmode, pc_rtx, x);
351 (define_insn "*cmpsf"
352 [(set (reg:CC_F CC_REG)
354 (match_operand:SF 0 "register_operand" "r,r,r")
355 (match_operand:SF 1 "rx_source_operand" "r,iF,Q")))]
356 "ALLOW_RX_FPU_INSNS && reload_completed"
358 [(set_attr "timings" "11,11,33")
359 (set_attr "length" "3,7,5")]
362 ;; Flow Control Instructions:
364 (define_insn "*conditional_branch"
367 (match_operator 1 "comparison_operator"
368 [(reg CC_REG) (const_int 0)])
369 (label_ref (match_operand 0 "" ""))
373 [(set_attr "length" "8") ;; This length is wrong, but it is
374 ;; too hard to compute statically.
375 (set_attr "timings" "33")] ;; The timing assumes that the branch is taken.
378 ;; ----------------------------------------------------------------------------
382 (label_ref (match_operand 0 "" "")))]
385 [(set_attr "length" "4")
386 (set_attr "timings" "33")]
389 (define_insn "indirect_jump"
391 (match_operand:SI 0 "register_operand" "r"))]
394 [(set_attr "length" "2")
395 (set_attr "timings" "33")]
398 (define_insn "tablejump"
400 (match_operand:SI 0 "register_operand" "r"))
401 (use (label_ref (match_operand 1 "" "")))]
403 { return flag_pic ? (TARGET_AS100_SYNTAX ? "\n?:\tbra\t%0"
407 [(set_attr "timings" "33")
408 (set_attr "length" "2")]
411 (define_insn "simple_return"
415 [(set_attr "length" "1")
416 (set_attr "timings" "55")]
419 (define_insn "deallocate_and_return"
420 [(set (reg:SI SP_REG)
421 (plus:SI (reg:SI SP_REG)
422 (match_operand:SI 0 "immediate_operand" "i")))
426 [(set_attr "length" "2")
427 (set_attr "timings" "55")]
430 (define_insn "pop_and_return"
431 [(match_parallel 1 "rx_rtsd_vector"
432 [(set (reg:SI SP_REG)
433 (plus:SI (reg:SI SP_REG)
434 (match_operand:SI 0 "const_int_operand" "n")))])]
437 rx_emit_stack_popm (operands, false);
440 [(set_attr "length" "3")
441 (set_attr "timings" "56")]
444 (define_insn "fast_interrupt_return"
445 [(unspec_volatile [(return)] UNSPEC_RTFI) ]
448 [(set_attr "length" "2")
449 (set_attr "timings" "33")]
452 (define_insn "exception_return"
453 [(unspec_volatile [(return)] UNSPEC_RTE) ]
456 [(set_attr "length" "2")
457 (set_attr "timings" "66")]
460 (define_insn "naked_return"
461 [(unspec_volatile [(return)] UNSPEC_NAKED) ]
463 "; Naked function: epilogue provided by programmer."
467 ;; Note - the following set of patterns do not use the "memory_operand"
468 ;; predicate or an "m" constraint because we do not allow symbol_refs
469 ;; or label_refs as legitmate memory addresses. This matches the
470 ;; behaviour of most of the RX instructions. Only the call/branch
471 ;; instructions are allowed to refer to symbols/labels directly.
472 ;; The call operands are in QImode because that is the value of
475 (define_expand "call"
476 [(call (match_operand:QI 0 "general_operand")
477 (match_operand:SI 1 "general_operand"))]
480 rtx dest = XEXP (operands[0], 0);
482 if (! rx_call_operand (dest, Pmode))
483 dest = force_reg (Pmode, dest);
484 emit_call_insn (gen_call_internal (dest, operands[1]));
489 (define_insn "call_internal"
490 [(call (mem:QI (match_operand:SI 0 "rx_call_operand" "r,Symbol"))
491 (match_operand:SI 1 "general_operand" "g,g"))
492 (clobber (reg:CC CC_REG))]
497 [(set_attr "length" "2,4")
498 (set_attr "timings" "33")]
501 (define_expand "call_value"
502 [(set (match_operand 0 "register_operand")
503 (call (match_operand:QI 1 "general_operand")
504 (match_operand:SI 2 "general_operand")))]
507 rtx dest = XEXP (operands[1], 0);
509 if (! rx_call_operand (dest, Pmode))
510 dest = force_reg (Pmode, dest);
511 emit_call_insn (gen_call_value_internal (operands[0], dest, operands[2]));
516 (define_insn "call_value_internal"
517 [(set (match_operand 0 "register_operand" "=r,r")
518 (call (mem:QI (match_operand:SI 1 "rx_call_operand" "r,Symbol"))
519 (match_operand:SI 2 "general_operand" "g,g")))
520 (clobber (reg:CC CC_REG))]
525 [(set_attr "length" "2,4")
526 (set_attr "timings" "33")]
529 ;; Note - we do not allow indirect sibcalls (with the address
530 ;; held in a register) because we cannot guarantee that the register
531 ;; chosen will be a call-used one. If it is a call-saved register,
532 ;; then the epilogue code will corrupt it by popping the saved value
534 (define_expand "sibcall"
536 [(call (mem:QI (match_operand:SI 0 "rx_symbolic_call_operand"))
537 (match_operand:SI 1 "general_operand"))
541 if (MEM_P (operands[0]))
542 operands[0] = XEXP (operands[0], 0);
546 (define_insn "sibcall_internal"
547 [(call (mem:QI (match_operand:SI 0 "rx_symbolic_call_operand" "Symbol"))
548 (match_operand:SI 1 "general_operand" "g"))
552 [(set_attr "length" "4")
553 (set_attr "timings" "33")]
556 (define_expand "sibcall_value"
558 [(set (match_operand 0 "register_operand")
559 (call (mem:QI (match_operand:SI 1 "rx_symbolic_call_operand"))
560 (match_operand:SI 2 "general_operand")))
564 if (MEM_P (operands[1]))
565 operands[1] = XEXP (operands[1], 0);
569 (define_insn "sibcall_value_internal"
570 [(set (match_operand 0 "register_operand" "=r")
571 (call (mem:QI (match_operand:SI 1 "rx_symbolic_call_operand" "Symbol"))
572 (match_operand:SI 2 "general_operand" "g")))
576 [(set_attr "length" "4")
577 (set_attr "timings" "33")]
580 ;; Function Prologue/Epilogue Instructions
582 (define_expand "prologue"
585 "rx_expand_prologue (); DONE;"
588 (define_expand "epilogue"
591 "rx_expand_epilogue (false); DONE;"
594 (define_expand "sibcall_epilogue"
597 "rx_expand_epilogue (true); DONE;"
602 ;; Note - we do not allow memory to memory moves, even though the ISA
603 ;; supports them. The reason is that the conditions on such moves are
604 ;; too restrictive, specifically the source addressing mode is limited
605 ;; by the destination addressing mode and vice versa. (For example it
606 ;; is not possible to use indexed register indirect addressing for one
607 ;; of the operands if the other operand is anything other than a register,
608 ;; but it is possible to use register relative addressing when the other
609 ;; operand also uses register relative or register indirect addressing).
611 ;; GCC does not support computing legitimate addresses based on the
612 ;; nature of other operands involved in the instruction, and reload is
613 ;; not smart enough to cope with a whole variety of different memory
614 ;; addressing constraints, so it is simpler and safer to just refuse
615 ;; to support memory to memory moves.
617 (define_expand "mov<register_modes:mode>"
618 [(set (match_operand:register_modes 0 "general_operand")
619 (match_operand:register_modes 1 "general_operand"))]
622 if (MEM_P (operand0) && MEM_P (operand1))
623 operands[1] = copy_to_mode_reg (<register_modes:MODE>mode, operand1);
627 (define_insn "*mov<register_modes:mode>_internal"
628 [(set (match_operand:register_modes
629 0 "nonimmediate_operand" "=r,r,r,r,r,r,m,Q,Q,Q,Q")
630 (match_operand:register_modes
631 1 "general_operand" "Int08,Sint16,Sint24,i,r,m,r,Int08,Sint16,Sint24,i"))]
633 { return rx_gen_move_template (operands, false); }
634 [(set_attr "length" "3,4,5,6,2,4,6,5,6,7,8")
635 (set_attr "timings" "11,11,11,11,11,12,11,11,11,11,11")]
638 (define_insn "extend<small_int_modes:mode>si2"
639 [(set (match_operand:SI 0 "register_operand" "=r,r")
640 (sign_extend:SI (match_operand:small_int_modes
641 1 "nonimmediate_operand" "r,m")))]
643 { return rx_gen_move_template (operands, false); }
644 [(set_attr "length" "2,6")
645 (set_attr "timings" "11,12")]
648 (define_insn "zero_extend<small_int_modes:mode>si2"
649 [(set (match_operand:SI 0 "register_operand" "=r,r")
650 (zero_extend:SI (match_operand:small_int_modes
651 1 "nonimmediate_operand" "r,m")))]
653 { return rx_gen_move_template (operands, true); }
654 [(set_attr "length" "2,4")
655 (set_attr "timings" "11,12")]
658 (define_insn "stack_push"
659 [(set (reg:SI SP_REG)
660 (minus:SI (reg:SI SP_REG)
662 (set (mem:SI (reg:SI SP_REG))
663 (match_operand:SI 0 "register_operand" "r"))]
666 [(set_attr "length" "2")]
669 (define_insn "stack_pushm"
670 [(match_parallel 1 "rx_store_multiple_vector"
671 [(set (reg:SI SP_REG)
672 (minus:SI (reg:SI SP_REG)
673 (match_operand:SI 0 "const_int_operand" "n")))])]
676 rx_emit_stack_pushm (operands);
679 [(set_attr "length" "2")
680 (set_attr "timings" "44")] ;; The timing is a guesstimate average timing.
683 (define_insn "stack_pop"
684 [(set (match_operand:SI 0 "register_operand" "=r")
685 (mem:SI (reg:SI SP_REG)))
687 (plus:SI (reg:SI SP_REG)
691 [(set_attr "length" "2")
692 (set_attr "timings" "12")]
695 (define_insn "stack_popm"
696 [(match_parallel 1 "rx_load_multiple_vector"
697 [(set (reg:SI SP_REG)
698 (plus:SI (reg:SI SP_REG)
699 (match_operand:SI 0 "const_int_operand" "n")))])]
702 rx_emit_stack_popm (operands, true);
705 [(set_attr "length" "2")
706 (set_attr "timings" "45")] ;; The timing is a guesstimate average timing.
709 (define_insn_and_split "cstoresi4"
710 [(set (match_operand:SI 0 "register_operand" "=r")
711 (match_operator:SI 1 "comparison_operator"
712 [(match_operand:SI 2 "register_operand" "r")
713 (match_operand:SI 3 "rx_source_operand" "riQ")]))
714 (clobber (reg:CC CC_REG))]
722 flags = gen_rtx_REG (CCmode, CC_REG);
723 x = gen_rtx_COMPARE (CCmode, operands[2], operands[3]);
724 x = gen_rtx_SET (VOIDmode, flags, x);
727 x = gen_rtx_fmt_ee (GET_CODE (operands[1]), SImode, flags, const0_rtx);
728 x = gen_rtx_SET (VOIDmode, operands[0], x);
734 [(set (match_operand:SI 0 "register_operand" "=r")
735 (match_operator:SI 1 "comparison_operator"
736 [(reg CC_REG) (const_int 0)]))]
739 [(set_attr "length" "3")]
742 (define_expand "cstoresf4"
743 [(parallel [(set (match_operand:SI 0 "register_operand" "")
744 (match_operator:SI 1 "comparison_operator"
745 [(match_operand:SF 2 "register_operand" "")
746 (match_operand:SF 3 "register_operand" "")]))
747 (clobber (match_scratch:SI 4))])]
750 enum rtx_code cmp1, cmp2;
752 /* If the comparison needs swapping of operands, do that now.
753 Do not split the comparison in two yet. */
754 if (rx_split_fp_compare (GET_CODE (operands[0]), &cmp1, &cmp2))
760 gcc_assert (cmp1 == UNORDERED);
771 operands[0] = gen_rtx_fmt_ee (cmp1, VOIDmode, op2, op3);
777 (define_insn_and_split "*cstoresf4"
778 [(set (match_operand:SI 0 "register_operand" "=r")
779 (match_operator:SI 4 "rx_fp_comparison_operator"
780 [(match_operand:SF 2 "register_operand" "r")
781 (match_operand:SF 3 "rx_source_operand" "rFiQ")]))
782 (clobber (match_scratch:SI 1 "=r"))]
788 enum rtx_code cmp0, cmp1, cmp2;
792 cmp0 = GET_CODE (operands[4]);
793 swap = rx_split_fp_compare (cmp0, &cmp1, &cmp2);
796 flags = gen_rtx_REG (CC_Fmode, CC_REG);
797 x = gen_rtx_COMPARE (CC_Fmode, operands[2], operands[3]);
798 x = gen_rtx_SET (VOIDmode, flags, x);
801 x = gen_rtx_fmt_ee (cmp1, SImode, flags, const0_rtx);
802 x = gen_rtx_SET (VOIDmode, operands[0], x);
807 /* The one case of LTGT needs to be split into ORDERED && NE. */
808 x = gen_rtx_fmt_ee (EQ, VOIDmode, flags, const0_rtx);
809 x = gen_rtx_IF_THEN_ELSE (SImode, x, const0_rtx, operands[0]);
810 x = gen_rtx_SET (VOIDmode, operands[0], x);
813 else if (cmp2 == EQ || cmp2 == NE)
815 /* Oring the two flags can be performed with a movcc operation. */
816 x = gen_rtx_fmt_ee (cmp2, VOIDmode, flags, const0_rtx);
817 x = gen_rtx_IF_THEN_ELSE (SImode, x, const1_rtx, operands[0]);
818 x = gen_rtx_SET (VOIDmode, operands[0], x);
821 else if (cmp2 != UNKNOWN)
823 /* We can't use movcc, but need to or in another compare.
824 Do this by storing the second operation into the scratch. */
825 x = gen_rtx_fmt_ee (cmp2, SImode, flags, const0_rtx);
826 x = gen_rtx_SET (VOIDmode, operands[1], x);
829 emit_insn (gen_iorsi3 (operands[0], operands[0], operands[1]));
834 (define_expand "movsicc"
836 [(set (match_operand:SI 0 "register_operand")
837 (if_then_else:SI (match_operand:SI 1 "comparison_operator")
838 (match_operand:SI 2 "nonmemory_operand")
839 (match_operand:SI 3 "nonmemory_operand")))
840 (clobber (reg:CC CC_REG))])]
843 /* ??? Support other conditions via cstore into a temporary? */
844 if (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE)
846 /* One operand must be a constant. */
847 if (!CONSTANT_P (operands[2]) && !CONSTANT_P (operands[3]))
851 (define_insn_and_split "*movsicc"
852 [(set (match_operand:SI 0 "register_operand" "=r,r")
854 (match_operator 5 "rx_z_comparison_operator"
855 [(match_operand:SI 3 "register_operand" "r,r")
856 (match_operand:SI 4 "rx_source_operand" "riQ,riQ")])
857 (match_operand:SI 1 "nonmemory_operand" "i,ri")
858 (match_operand:SI 2 "nonmemory_operand" "ri,i")))
859 (clobber (reg:CC CC_REG))]
860 "CONSTANT_P (operands[1]) || CONSTANT_P (operands[2])"
862 "&& reload_completed"
865 rtx x, flags, op0, op1, op2;
866 enum rtx_code cmp_code;
868 flags = gen_rtx_REG (CCmode, CC_REG);
869 x = gen_rtx_COMPARE (CCmode, operands[3], operands[4]);
870 emit_insn (gen_rtx_SET (VOIDmode, flags, x));
872 cmp_code = GET_CODE (operands[5]);
877 /* If OP2 is the constant, reverse the sense of the move. */
878 if (!CONSTANT_P (operands[1]))
880 x = op1, op1 = op2, op2 = x;
881 cmp_code = reverse_condition (cmp_code);
884 /* If OP2 does not match the output, copy it into place. We have allowed
885 these alternatives so that the destination can legitimately be one of
886 the comparison operands without increasing register pressure. */
887 if (!rtx_equal_p (op0, op2))
888 emit_move_insn (op0, op2);
890 x = gen_rtx_fmt_ee (cmp_code, VOIDmode, flags, const0_rtx);
891 x = gen_rtx_IF_THEN_ELSE (SImode, x, op1, op0);
892 emit_insn (gen_rtx_SET (VOIDmode, op0, x));
897 [(set (match_operand:SI 0 "register_operand" "+r,r,r,r")
899 (match_operator 2 "rx_z_comparison_operator"
900 [(reg CC_REG) (const_int 0)])
901 (match_operand:SI 1 "immediate_operand" "Sint08,Sint16,Sint24,i")
905 if (GET_CODE (operands[2]) == EQ)
906 return "stz\t%1, %0";
908 return "stnz\t%1, %0";
910 [(set_attr "length" "4,5,6,7")]
913 ;; Arithmetic Instructions
915 (define_insn "abssi2"
916 [(set (match_operand:SI 0 "register_operand" "=r,r")
917 (abs:SI (match_operand:SI 1 "register_operand" "0,r")))
918 (clobber (reg:CC CC_REG))]
923 [(set_attr "length" "2,3")]
926 (define_insn "*abssi2_flags"
927 [(set (match_operand:SI 0 "register_operand" "=r,r")
928 (abs:SI (match_operand:SI 1 "register_operand" "0,r")))
930 (compare (abs:SI (match_dup 1))
932 "reload_completed && rx_match_ccmode (insn, CC_ZSOmode)"
936 [(set_attr "length" "2,3")]
939 (define_insn "addsi3"
940 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,r,r,r,r,r,r,r,r")
941 (plus:SI (match_operand:SI 1 "register_operand" "%0,0,0,0,0,0,0,r,r,r,r,r,r,0")
942 (match_operand:SI 2 "rx_source_operand" "r,Uint04,NEGint4,Sint08,Sint16,Sint24,i,0,r,Sint08,Sint16,Sint24,i,Q")))
943 (clobber (reg:CC CC_REG))]
960 [(set_attr "timings" "11,11,11,11,11,11,11,11,11,11,11,11,11,33")
961 (set_attr "length" "2,2,2,3,4,5,6,2,3,3,4,5,6,5")]
964 (define_insn "*addsi3_flags"
965 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,r,r,r,r,r,r,r,r")
966 (plus:SI (match_operand:SI 1 "register_operand" "%0,0,0,0,0,0,0,r,r,r,r,r,r,0")
967 (match_operand:SI 2 "rx_source_operand" "r,Uint04,NEGint4,Sint08,Sint16,Sint24,i,0,r,Sint08,Sint16,Sint24,i,Q")))
969 (compare (plus:SI (match_dup 1) (match_dup 2))
971 "reload_completed && rx_match_ccmode (insn, CC_ZSCmode)"
987 [(set_attr "timings" "11,11,11,11,11,11,11,11,11,11,11,11,11,33")
988 (set_attr "length" "2,2,2,3,4,5,6,2,3,3,4,5,6,5")]
991 ;; A helper to expand the above with the CC_MODE filled in.
992 (define_expand "addsi3_flags"
993 [(parallel [(set (match_operand:SI 0 "register_operand")
994 (plus:SI (match_operand:SI 1 "register_operand")
995 (match_operand:SI 2 "rx_source_operand")))
996 (set (reg:CC_ZSC CC_REG)
997 (compare:CC_ZSC (plus:SI (match_dup 1) (match_dup 2))
1001 (define_insn "adc_internal"
1002 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r")
1005 (ltu:SI (reg:CC CC_REG) (const_int 0))
1006 (match_operand:SI 1 "register_operand" "%0,0,0,0,0,0"))
1007 (match_operand:SI 2 "rx_source_operand" "r,Sint08,Sint16,Sint24,i,Q")))
1008 (clobber (reg:CC CC_REG))]
1011 [(set_attr "timings" "11,11,11,11,11,33")
1012 (set_attr "length" "3,4,5,6,7,6")]
1015 (define_insn "*adc_flags"
1016 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r")
1019 (ltu:SI (reg:CC CC_REG) (const_int 0))
1020 (match_operand:SI 1 "register_operand" "%0,0,0,0,0,0"))
1021 (match_operand:SI 2 "rx_source_operand" "r,Sint08,Sint16,Sint24,i,Q")))
1026 (ltu:SI (reg:CC CC_REG) (const_int 0))
1030 "reload_completed && rx_match_ccmode (insn, CC_ZSCmode)"
1032 [(set_attr "timings" "11,11,11,11,11,33")
1033 (set_attr "length" "3,4,5,6,7,6")]
1036 (define_expand "adddi3"
1037 [(set (match_operand:DI 0 "register_operand" "")
1038 (plus:DI (match_operand:DI 1 "register_operand" "")
1039 (match_operand:DI 2 "rx_source_operand" "")))]
1042 rtx op0l, op0h, op1l, op1h, op2l, op2h;
1044 op0l = gen_lowpart (SImode, operands[0]);
1045 op1l = gen_lowpart (SImode, operands[1]);
1046 op2l = gen_lowpart (SImode, operands[2]);
1047 op0h = gen_highpart (SImode, operands[0]);
1048 op1h = gen_highpart (SImode, operands[1]);
1049 op2h = gen_highpart_mode (SImode, DImode, operands[2]);
1051 emit_insn (gen_adddi3_internal (op0l, op0h, op1l, op2l, op1h, op2h));
1055 (define_insn_and_split "adddi3_internal"
1056 [(set (match_operand:SI 0 "register_operand" "=r")
1057 (plus:SI (match_operand:SI 2 "register_operand" "r")
1058 (match_operand:SI 3 "rx_source_operand" "riQ")))
1059 (set (match_operand:SI 1 "register_operand" "=r")
1062 (ltu:SI (plus:SI (match_dup 2) (match_dup 3)) (match_dup 2))
1063 (match_operand:SI 4 "register_operand" "%1"))
1064 (match_operand:SI 5 "rx_source_operand" "riQ")))
1065 (clobber (match_scratch:SI 6 "=&r"))
1066 (clobber (reg:CC CC_REG))]
1072 rtx op0l = operands[0];
1073 rtx op0h = operands[1];
1074 rtx op1l = operands[2];
1075 rtx op2l = operands[3];
1076 rtx op1h = operands[4];
1077 rtx op2h = operands[5];
1078 rtx scratch = operands[6];
1081 if (reg_overlap_mentioned_p (op0l, op1h))
1083 emit_move_insn (scratch, op0l);
1085 if (reg_overlap_mentioned_p (op0l, op2h))
1088 else if (reg_overlap_mentioned_p (op0l, op2h))
1090 emit_move_insn (scratch, op0l);
1094 if (rtx_equal_p (op0l, op1l))
1096 else if (rtx_equal_p (op0l, op2l))
1097 x = op1l, op1l = op2l, op2l = x;
1098 emit_insn (gen_addsi3_flags (op0l, op1l, op2l));
1100 if (rtx_equal_p (op0h, op1h))
1102 else if (rtx_equal_p (op0h, op2h))
1103 x = op1h, op1h = op2h, op2h = x;
1106 emit_move_insn (op0h, op1h);
1109 emit_insn (gen_adc_internal (op0h, op1h, op2h));
1113 (define_insn "andsi3"
1114 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,r,r,r")
1115 (and:SI (match_operand:SI 1 "register_operand" "%0,0,0,0,0,0,r,r,0")
1116 (match_operand:SI 2 "rx_source_operand" "r,Uint04,Sint08,Sint16,Sint24,i,0,r,Q")))
1117 (clobber (reg:CC CC_REG))]
1129 [(set_attr "timings" "11,11,11,11,11,11,11,33,33")
1130 (set_attr "length" "2,2,3,4,5,6,2,5,5")]
1133 (define_insn "*andsi3_flags"
1134 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,r,r,r")
1135 (and:SI (match_operand:SI 1 "register_operand" "%0,0,0,0,0,0,r,r,0")
1136 (match_operand:SI 2 "rx_source_operand" "r,Uint04,Sint08,Sint16,Sint24,i,0,r,Q")))
1138 (compare (and:SI (match_dup 1) (match_dup 2))
1140 "reload_completed && rx_match_ccmode (insn, CC_ZSmode)"
1151 [(set_attr "timings" "11,11,11,11,11,11,11,33,33")
1152 (set_attr "length" "2,2,3,4,5,6,2,5,5")]
1155 ;; Byte swap (single 32-bit value).
1156 (define_insn "bswapsi2"
1157 [(set (match_operand:SI 0 "register_operand" "=r")
1158 (bswap:SI (match_operand:SI 1 "register_operand" "r")))]
1161 [(set_attr "length" "3")]
1164 ;; Byte swap (single 16-bit value). Note - we ignore the swapping of the high 16-bits.
1165 (define_insn "bswaphi2"
1166 [(set (match_operand:HI 0 "register_operand" "=r")
1167 (bswap:HI (match_operand:HI 1 "register_operand" "r")))]
1170 [(set_attr "length" "3")]
1173 (define_insn "divsi3"
1174 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r")
1175 (div:SI (match_operand:SI 1 "register_operand" "0,0,0,0,0,0")
1176 (match_operand:SI 2 "rx_source_operand" "r,Sint08,Sint16,Sint24,i,Q")))
1177 (clobber (reg:CC CC_REG))]
1180 [(set_attr "timings" "1111") ;; Strictly speaking the timing should be
1181 ;; 2222, but that is a worst case sceanario.
1182 (set_attr "length" "3,4,5,6,7,6")]
1185 (define_insn "udivsi3"
1186 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r")
1187 (udiv:SI (match_operand:SI 1 "register_operand" "0,0,0,0,0,0")
1188 (match_operand:SI 2 "rx_source_operand" "r,Sint08,Sint16,Sint24,i,Q")))
1189 (clobber (reg:CC CC_REG))]
1192 [(set_attr "timings" "1010") ;; Strictly speaking the timing should be
1193 ;; 2020, but that is a worst case sceanario.
1194 (set_attr "length" "3,4,5,6,7,6")]
1197 ;; Note - these patterns are suppressed in big-endian mode because they
1198 ;; generate a little endian result. ie the most significant word of the
1199 ;; result is placed in the higher numbered register of the destination
1202 (define_insn "mulsidi3"
1203 [(set (match_operand:DI 0 "register_operand" "=r,r,r,r,r,r")
1204 (mult:DI (sign_extend:DI (match_operand:SI
1205 1 "register_operand" "%0,0,0,0,0,0"))
1206 (sign_extend:DI (match_operand:SI
1207 2 "rx_source_operand"
1208 "r,Sint08,Sint16,Sint24,i,Q"))))]
1209 "! TARGET_BIG_ENDIAN_DATA"
1211 [(set_attr "length" "3,4,5,6,7,6")
1212 (set_attr "timings" "22,22,22,22,22,44")]
1215 ;; See comment for mulsidi3.
1216 ;; Note - the zero_extends are to distinguish this pattern from the
1217 ;; mulsidi3 pattern. Immediate mode addressing is not supported
1218 ;; because gcc cannot handle the expression: (zero_extend (const_int)).
1219 (define_insn "umulsidi3"
1220 [(set (match_operand:DI 0 "register_operand" "=r,r")
1221 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0,0"))
1222 (zero_extend:DI (match_operand:SI 2 "rx_compare_operand" "r,Q"))))]
1223 "! TARGET_BIG_ENDIAN_DATA"
1225 [(set_attr "length" "3,6")
1226 (set_attr "timings" "22,44")]
1229 (define_insn "smaxsi3"
1230 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r")
1231 (smax:SI (match_operand:SI 1 "register_operand" "%0,0,0,0,0,0")
1232 (match_operand:SI 2 "rx_source_operand"
1233 "r,Sint08,Sint16,Sint24,i,Q")))]
1236 [(set_attr "length" "3,4,5,6,7,6")
1237 (set_attr "timings" "11,11,11,11,11,33")]
1240 (define_insn "sminsi3"
1241 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r")
1242 (smin:SI (match_operand:SI 1 "register_operand" "%0,0,0,0,0,0")
1243 (match_operand:SI 2 "rx_source_operand"
1244 "r,Sint08,Sint16,Sint24,i,Q")))]
1247 [(set_attr "length" "3,4,5,6,7,6")
1248 (set_attr "timings" "11,11,11,11,11,33")]
1251 (define_insn "mulsi3"
1252 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,r,r,r")
1253 (mult:SI (match_operand:SI 1 "register_operand" "%0,0,0,0,0,0,0,r,r")
1254 (match_operand:SI 2 "rx_source_operand"
1255 "r,Uint04,Sint08,Sint16,Sint24,i,Q,0,r")))]
1267 [(set_attr "length" "2,2,3,4,5,6,5,2,3")
1268 (set_attr "timings" "11,11,11,11,11,11,33,11,11")]
1271 (define_insn "negsi2"
1272 [(set (match_operand:SI 0 "register_operand" "=r,r")
1273 (neg:SI (match_operand:SI 1 "register_operand" "0,r")))
1274 (clobber (reg:CC CC_REG))]
1279 [(set_attr "length" "2,3")]
1282 ;; Note that the O and C flags are not set as per a normal compare,
1283 ;; and thus are unusable in that context.
1284 (define_insn "*negsi2_flags"
1285 [(set (match_operand:SI 0 "register_operand" "=r,r")
1286 (neg:SI (match_operand:SI 1 "register_operand" "0,r")))
1288 (compare (neg:SI (match_dup 1))
1290 "reload_completed && rx_match_ccmode (insn, CC_ZSmode)"
1294 [(set_attr "length" "2,3")]
1297 (define_insn "one_cmplsi2"
1298 [(set (match_operand:SI 0 "register_operand" "=r,r")
1299 (not:SI (match_operand:SI 1 "register_operand" "0,r")))
1300 (clobber (reg:CC CC_REG))]
1305 [(set_attr "length" "2,3")]
1308 (define_insn "*one_cmplsi2_flags"
1309 [(set (match_operand:SI 0 "register_operand" "=r,r")
1310 (not:SI (match_operand:SI 1 "register_operand" "0,r")))
1312 (compare (not:SI (match_dup 1))
1314 "reload_completed && rx_match_ccmode (insn, CC_ZSmode)"
1318 [(set_attr "length" "2,3")]
1321 (define_insn "iorsi3"
1322 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,r,r,r")
1323 (ior:SI (match_operand:SI 1 "register_operand" "%0,0,0,0,0,0,r,r,0")
1324 (match_operand:SI 2 "rx_source_operand" "r,Uint04,Sint08,Sint16,Sint24,i,0,r,Q")))
1325 (clobber (reg:CC CC_REG))]
1337 [(set_attr "timings" "11,11,11,11,11,11,11,11,33")
1338 (set_attr "length" "2,2,3,4,5,6,2,3,5")]
1341 (define_insn "*iorsi3_flags"
1342 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,r,r,r")
1343 (ior:SI (match_operand:SI 1 "register_operand" "%0,0,0,0,0,0,r,r,0")
1344 (match_operand:SI 2 "rx_source_operand" "r,Uint04,Sint08,Sint16,Sint24,i,0,r,Q")))
1346 (compare (ior:SI (match_dup 1) (match_dup 2))
1348 "reload_completed && rx_match_ccmode (insn, CC_ZSmode)"
1359 [(set_attr "timings" "11,11,11,11,11,11,11,11,33")
1360 (set_attr "length" "2,2,3,4,5,6,2,3,5")]
1363 (define_insn "rotlsi3"
1364 [(set (match_operand:SI 0 "register_operand" "=r")
1365 (rotate:SI (match_operand:SI 1 "register_operand" "0")
1366 (match_operand:SI 2 "rx_shift_operand" "rn")))
1367 (clobber (reg:CC CC_REG))]
1370 [(set_attr "length" "3")]
1373 (define_insn "*rotlsi3_flags"
1374 [(set (match_operand:SI 0 "register_operand" "=r")
1375 (rotate:SI (match_operand:SI 1 "register_operand" "0")
1376 (match_operand:SI 2 "rx_shift_operand" "rn")))
1378 (compare (rotate:SI (match_dup 1) (match_dup 2))
1380 "reload_completed && rx_match_ccmode (insn, CC_ZSmode)"
1382 [(set_attr "length" "3")]
1385 (define_insn "rotrsi3"
1386 [(set (match_operand:SI 0 "register_operand" "=r")
1387 (rotatert:SI (match_operand:SI 1 "register_operand" "0")
1388 (match_operand:SI 2 "rx_shift_operand" "rn")))
1389 (clobber (reg:CC CC_REG))]
1392 [(set_attr "length" "3")]
1395 (define_insn "*rotrsi3_flags"
1396 [(set (match_operand:SI 0 "register_operand" "=r")
1397 (rotatert:SI (match_operand:SI 1 "register_operand" "0")
1398 (match_operand:SI 2 "rx_shift_operand" "rn")))
1400 (compare (rotatert:SI (match_dup 1) (match_dup 2))
1402 "reload_completed && rx_match_ccmode (insn, CC_ZSmode)"
1404 [(set_attr "length" "3")]
1407 (define_insn "ashrsi3"
1408 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
1409 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0,r")
1410 (match_operand:SI 2 "rx_shift_operand" "r,n,n")))
1411 (clobber (reg:CC CC_REG))]
1417 [(set_attr "length" "3,2,3")]
1420 (define_insn "*ashrsi3_flags"
1421 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
1422 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0,r")
1423 (match_operand:SI 2 "rx_shift_operand" "r,n,n")))
1425 (compare (ashiftrt:SI (match_dup 1) (match_dup 2))
1427 "reload_completed && rx_match_ccmode (insn, CC_ZSmode)"
1432 [(set_attr "length" "3,2,3")]
1435 (define_insn "lshrsi3"
1436 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
1437 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0,0,r")
1438 (match_operand:SI 2 "rx_shift_operand" "r,n,n")))
1439 (clobber (reg:CC CC_REG))]
1445 [(set_attr "length" "3,2,3")]
1448 (define_insn "*lshrsi3_flags"
1449 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
1450 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0,0,r")
1451 (match_operand:SI 2 "rx_shift_operand" "r,n,n")))
1453 (compare (lshiftrt:SI (match_dup 1) (match_dup 2))
1455 "reload_completed && rx_match_ccmode (insn, CC_ZSmode)"
1460 [(set_attr "length" "3,2,3")]
1463 (define_insn "ashlsi3"
1464 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
1465 (ashift:SI (match_operand:SI 1 "register_operand" "0,0,r")
1466 (match_operand:SI 2 "rx_shift_operand" "r,n,n")))
1467 (clobber (reg:CC CC_REG))]
1473 [(set_attr "length" "3,2,3")]
1476 (define_insn "*ashlsi3_flags"
1477 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
1478 (ashift:SI (match_operand:SI 1 "register_operand" "0,0,r")
1479 (match_operand:SI 2 "rx_shift_operand" "r,n,n")))
1481 (compare (ashift:SI (match_dup 1) (match_dup 2))
1483 "reload_completed && rx_match_ccmode (insn, CC_ZSmode)"
1488 [(set_attr "length" "3,2,3")]
1491 ;; Saturate to 32-bits
1492 (define_insn_and_split "ssaddsi3"
1493 [(set (match_operand:SI 0 "register_operand" "=r")
1494 (ss_plus:SI (match_operand:SI 1 "register_operand" "r")
1495 (match_operand:SI 2 "rx_source_operand" "riQ")))
1496 (clobber (reg:CC CC_REG))]
1500 [(parallel [(set (match_dup 0)
1501 (plus:SI (match_dup 1) (match_dup 2)))
1502 (set (reg:CC_ZSC CC_REG)
1504 (plus:SI (match_dup 1) (match_dup 2))
1507 (unspec:SI [(match_dup 0) (reg:CC CC_REG)]
1508 UNSPEC_BUILTIN_SAT))]
1513 [(set (match_operand:SI 0 "register_operand" "=r")
1514 (unspec:SI [(match_operand:SI 1 "register_operand" "0")
1516 UNSPEC_BUILTIN_SAT))]
1519 [(set_attr "length" "2")]
1522 (define_insn "subsi3"
1523 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r")
1524 (minus:SI (match_operand:SI 1 "register_operand" "0,0,0,r,0")
1525 (match_operand:SI 2 "rx_source_operand" "r,Uint04,n,r,Q")))
1526 (clobber (reg:CC CC_REG))]
1534 [(set_attr "timings" "11,11,11,11,33")
1535 (set_attr "length" "2,2,6,3,5")]
1538 ;; Note that the O flag is set as if (compare op1 op2) not for
1539 ;; what is described here, (compare op0 0).
1540 (define_insn "*subsi3_flags"
1541 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r")
1542 (minus:SI (match_operand:SI 1 "register_operand" "0,0,0,r,0")
1543 (match_operand:SI 2 "rx_source_operand" "r,Uint04,n,r,Q")))
1545 (compare (minus:SI (match_dup 1) (match_dup 2))
1547 "reload_completed && rx_match_ccmode (insn, CC_ZSCmode)"
1554 [(set_attr "timings" "11,11,11,11,33")
1555 (set_attr "length" "2,2,6,3,5")]
1558 ;; A helper to expand the above with the CC_MODE filled in.
1559 (define_expand "subsi3_flags"
1560 [(parallel [(set (match_operand:SI 0 "register_operand")
1561 (minus:SI (match_operand:SI 1 "register_operand")
1562 (match_operand:SI 2 "rx_source_operand")))
1563 (set (reg:CC_ZSC CC_REG)
1564 (compare:CC_ZSC (minus:SI (match_dup 1) (match_dup 2))
1568 (define_insn "sbb_internal"
1569 [(set (match_operand:SI 0 "register_operand" "=r,r")
1572 (match_operand:SI 1 "register_operand" " 0,0")
1573 (match_operand:SI 2 "rx_compare_operand" " r,Q"))
1574 (geu:SI (reg:CC CC_REG) (const_int 0))))
1575 (clobber (reg:CC CC_REG))]
1578 [(set_attr "timings" "11,33")
1579 (set_attr "length" "3,6")]
1582 (define_insn "*sbb_flags"
1583 [(set (match_operand:SI 0 "register_operand" "=r,r")
1586 (match_operand:SI 1 "register_operand" " 0,0")
1587 (match_operand:SI 2 "rx_compare_operand" " r,Q"))
1588 (geu:SI (reg:CC CC_REG) (const_int 0))))
1592 (minus:SI (match_dup 1) (match_dup 2))
1593 (geu:SI (reg:CC CC_REG) (const_int 0)))
1597 [(set_attr "timings" "11,33")
1598 (set_attr "length" "3,6")]
1601 (define_expand "subdi3"
1602 [(set (match_operand:DI 0 "register_operand" "")
1603 (minus:DI (match_operand:DI 1 "register_operand" "")
1604 (match_operand:DI 2 "rx_source_operand" "")))]
1607 rtx op0l, op0h, op1l, op1h, op2l, op2h;
1609 op0l = gen_lowpart (SImode, operands[0]);
1610 op1l = gen_lowpart (SImode, operands[1]);
1611 op2l = gen_lowpart (SImode, operands[2]);
1612 op0h = gen_highpart (SImode, operands[0]);
1613 op1h = gen_highpart (SImode, operands[1]);
1614 op2h = gen_highpart_mode (SImode, DImode, operands[2]);
1616 emit_insn (gen_subdi3_internal (op0l, op0h, op1l, op2l, op1h, op2h));
1620 (define_insn_and_split "subdi3_internal"
1621 [(set (match_operand:SI 0 "register_operand" "=&r,&r")
1622 (minus:SI (match_operand:SI 2 "register_operand" " 0, r")
1623 (match_operand:SI 3 "rx_source_operand" "rnQ, r")))
1624 (set (match_operand:SI 1 "register_operand" "= r, r")
1627 (match_operand:SI 4 "register_operand" " 1, 1")
1628 (match_operand:SI 5 "rx_compare_operand" " rQ,rQ"))
1629 (geu:SI (match_dup 2) (match_dup 3))))
1630 (clobber (reg:CC CC_REG))]
1636 emit_insn (gen_subsi3_flags (operands[0], operands[2], operands[3]));
1637 emit_insn (gen_sbb_internal (operands[1], operands[4], operands[5]));
1641 (define_insn "xorsi3"
1642 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r")
1643 (xor:SI (match_operand:SI 1 "register_operand" "%0,0,0,0,0,0")
1644 (match_operand:SI 2 "rx_source_operand"
1645 "r,Sint08,Sint16,Sint24,i,Q")))
1646 (clobber (reg:CC CC_REG))]
1649 [(set_attr "timings" "11,11,11,11,11,33")
1650 (set_attr "length" "3,4,5,6,7,6")]
1653 (define_insn "*xorsi3_flags"
1654 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r")
1655 (xor:SI (match_operand:SI 1 "register_operand" "%0,0,0,0,0,0")
1656 (match_operand:SI 2 "rx_source_operand"
1657 "r,Sint08,Sint16,Sint24,i,Q")))
1659 (compare (xor:SI (match_dup 1) (match_dup 2))
1661 "reload_completed && rx_match_ccmode (insn, CC_ZSmode)"
1663 [(set_attr "timings" "11,11,11,11,11,33")
1664 (set_attr "length" "3,4,5,6,7,6")]
1667 ;; Floating Point Instructions
1669 (define_insn "addsf3"
1670 [(set (match_operand:SF 0 "register_operand" "=r,r,r")
1671 (plus:SF (match_operand:SF 1 "register_operand" "%0,0,0")
1672 (match_operand:SF 2 "rx_source_operand" "r,F,Q")))
1673 (clobber (reg:CC CC_REG))]
1674 "ALLOW_RX_FPU_INSNS"
1676 [(set_attr "timings" "44,44,66")
1677 (set_attr "length" "3,7,5")]
1680 (define_insn "divsf3"
1681 [(set (match_operand:SF 0 "register_operand" "=r,r,r")
1682 (div:SF (match_operand:SF 1 "register_operand" "0,0,0")
1683 (match_operand:SF 2 "rx_source_operand" "r,F,Q")))
1684 (clobber (reg:CC CC_REG))]
1685 "ALLOW_RX_FPU_INSNS"
1687 [(set_attr "timings" "1616,1616,1818")
1688 (set_attr "length" "3,7,5")]
1691 (define_insn "mulsf3"
1692 [(set (match_operand:SF 0 "register_operand" "=r,r,r")
1693 (mult:SF (match_operand:SF 1 "register_operand" "%0,0,0")
1694 (match_operand:SF 2 "rx_source_operand" "r,F,Q")))
1695 (clobber (reg:CC CC_REG))]
1696 "ALLOW_RX_FPU_INSNS"
1698 [(set_attr "timings" "33,33,55")
1699 (set_attr "length" "3,7,5")]
1702 (define_insn "subsf3"
1703 [(set (match_operand:SF 0 "register_operand" "=r,r,r")
1704 (minus:SF (match_operand:SF 1 "register_operand" "0,0,0")
1705 (match_operand:SF 2 "rx_source_operand" "r,F,Q")))
1706 (clobber (reg:CC CC_REG))]
1707 "ALLOW_RX_FPU_INSNS"
1709 [(set_attr "timings" "44,44,66")
1710 (set_attr "length" "3,7,5")]
1713 (define_insn "fix_truncsfsi2"
1714 [(set (match_operand:SI 0 "register_operand" "=r,r")
1715 (fix:SI (match_operand:SF 1 "rx_compare_operand" "r,Q")))
1716 (clobber (reg:CC CC_REG))]
1717 "ALLOW_RX_FPU_INSNS"
1719 [(set_attr "timings" "22,44")
1720 (set_attr "length" "3,5")]
1723 (define_insn "floatsisf2"
1724 [(set (match_operand:SF 0 "register_operand" "=r,r")
1725 (float:SF (match_operand:SI 1 "rx_compare_operand" "r,Q")))
1726 (clobber (reg:CC CC_REG))]
1727 "ALLOW_RX_FPU_INSNS"
1729 [(set_attr "timings" "22,44")
1730 (set_attr "length" "3,6")]
1733 ;; Bit manipulation instructions.
1735 ;; ??? The *_in_memory patterns will not be matched without further help.
1736 ;; At one time we had the insv expander generate them, but I suspect that
1737 ;; in general we get better performance by exposing the register load to
1740 ;; An alternate solution would be to re-organize these patterns such
1741 ;; that allow both register and memory operands. This would allow the
1742 ;; register allocator to spill and not load the register operand. This
1743 ;; would be possible only for operations for which we have a constant
1744 ;; bit offset, so that we can adjust the address by ofs/8 and replace
1745 ;; the offset in the insn by ofs%8.
1747 (define_insn "*bitset"
1748 [(set (match_operand:SI 0 "register_operand" "=r")
1749 (ior:SI (ashift:SI (const_int 1)
1750 (match_operand:SI 1 "rx_shift_operand" "ri"))
1751 (match_operand:SI 2 "register_operand" "0")))]
1754 [(set_attr "length" "3")]
1757 (define_insn "*bitset_in_memory"
1758 [(set (match_operand:QI 0 "memory_operand" "+Q")
1759 (ior:QI (ashift:QI (const_int 1)
1760 (match_operand:QI 1 "nonmemory_operand" "ri"))
1764 [(set_attr "length" "3")
1765 (set_attr "timings" "34")]
1768 (define_insn "*bitinvert"
1769 [(set (match_operand:SI 0 "register_operand" "=r")
1770 (xor:SI (ashift:SI (const_int 1)
1771 (match_operand:SI 1 "rx_shift_operand" "ri"))
1772 (match_operand:SI 2 "register_operand" "0")))]
1775 [(set_attr "length" "3")]
1778 (define_insn "*bitinvert_in_memory"
1779 [(set (match_operand:QI 0 "memory_operand" "+Q")
1780 (xor:QI (ashift:QI (const_int 1)
1781 (match_operand:QI 1 "nonmemory_operand" "ri"))
1785 [(set_attr "length" "5")
1786 (set_attr "timings" "33")]
1789 (define_insn "*bitclr"
1790 [(set (match_operand:SI 0 "register_operand" "=r")
1794 (match_operand:SI 1 "rx_shift_operand" "ri")))
1795 (match_operand:SI 2 "register_operand" "0")))]
1798 [(set_attr "length" "3")]
1801 (define_insn "*bitclr_in_memory"
1802 [(set (match_operand:QI 0 "memory_operand" "+Q")
1806 (match_operand:QI 1 "nonmemory_operand" "ri")))
1810 [(set_attr "length" "3")
1811 (set_attr "timings" "34")]
1814 (define_insn "*insv_imm"
1815 [(set (zero_extract:SI
1816 (match_operand:SI 0 "register_operand" "+r")
1818 (match_operand:SI 1 "rx_shift_operand" "ri"))
1819 (match_operand:SI 2 "const_int_operand" ""))]
1822 if (INTVAL (operands[2]) & 1)
1823 return "bset\t%1, %0";
1825 return "bclr\t%1, %0";
1827 [(set_attr "length" "3")]
1830 (define_insn_and_split "rx_insv_reg"
1831 [(set (zero_extract:SI
1832 (match_operand:SI 0 "register_operand" "+r")
1834 (match_operand:SI 1 "const_int_operand" ""))
1835 (match_operand:SI 2 "register_operand" "r"))
1836 (clobber (reg:CC CC_REG))]
1840 [(set (zero_extract:SI (match_dup 0) (const_int 1) (match_dup 1))
1845 /* Emit tst #1, op2. */
1846 flags = gen_rtx_REG (CC_ZSmode, CC_REG);
1847 x = gen_rtx_AND (SImode, operands[2], const1_rtx);
1848 x = gen_rtx_COMPARE (CC_ZSmode, x, const0_rtx);
1849 x = gen_rtx_SET (VOIDmode, flags, x);
1853 operands[3] = gen_rtx_NE (SImode, flags, const0_rtx);
1856 (define_insn_and_split "*insv_cond"
1857 [(set (zero_extract:SI
1858 (match_operand:SI 0 "register_operand" "+r")
1860 (match_operand:SI 1 "const_int_operand" ""))
1861 (match_operator:SI 4 "comparison_operator"
1862 [(match_operand:SI 2 "register_operand" "r")
1863 (match_operand:SI 3 "rx_source_operand" "riQ")]))
1864 (clobber (reg:CC CC_REG))]
1868 [(set (zero_extract:SI (match_dup 0) (const_int 1) (match_dup 1))
1873 flags = gen_rtx_REG (CCmode, CC_REG);
1874 x = gen_rtx_COMPARE (CCmode, operands[2], operands[3]);
1875 x = gen_rtx_SET (VOIDmode, flags, x);
1878 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[4]), SImode,
1882 (define_insn "*bmcc"
1883 [(set (zero_extract:SI
1884 (match_operand:SI 0 "register_operand" "+r")
1886 (match_operand:SI 1 "const_int_operand" ""))
1887 (match_operator:SI 2 "comparison_operator"
1888 [(reg CC_REG) (const_int 0)]))]
1891 [(set_attr "length" "3")]
1894 ;; Work around the fact that X=Y<0 is preferentially expanded as a shift.
1895 (define_insn_and_split "*insv_cond_lt"
1896 [(set (zero_extract:SI
1897 (match_operand:SI 0 "register_operand" "+r")
1899 (match_operand:SI 1 "const_int_operand" ""))
1900 (match_operator:SI 3 "rshift_operator"
1901 [(match_operand:SI 2 "register_operand" "r")
1903 (clobber (reg:CC CC_REG))]
1907 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 1) (match_dup 1))
1908 (lt:SI (match_dup 2) (const_int 0)))
1909 (clobber (reg:CC CC_REG))])]
1913 (define_expand "insv"
1914 [(set (zero_extract:SI
1915 (match_operand:SI 0 "register_operand") ;; Destination
1916 (match_operand:SI 1 "const_int_operand") ;; # of bits to set
1917 (match_operand:SI 2 "nonmemory_operand")) ;; Starting bit
1918 (match_operand:SI 3 "nonmemory_operand"))] ;; Bits to insert
1921 /* We only handle single-bit inserts. */
1922 if (!CONST_INT_P (operands[1]) || INTVAL (operands[1]) != 1)
1925 /* Either the bit to insert or the position must be constant. */
1926 if (CONST_INT_P (operands[3]))
1927 operands[3] = GEN_INT (INTVAL (operands[3]) & 1);
1928 else if (CONST_INT_P (operands[2]))
1930 emit_insn (gen_rx_insv_reg (operands[0], operands[2], operands[3]));
1937 ;; Atomic exchange operation.
1939 (define_insn "sync_lock_test_and_setsi"
1940 [(set (match_operand:SI 0 "register_operand" "=r,r")
1941 (match_operand:SI 1 "rx_compare_operand" "=r,Q"))
1943 (match_operand:SI 2 "register_operand" "0,0"))]
1946 [(set_attr "length" "3,6")
1947 (set_attr "timings" "22")]
1950 ;; Block move functions.
1952 (define_expand "movstr"
1953 [(set (match_operand:BLK 1 "memory_operand") ;; Dest
1954 (match_operand:BLK 2 "memory_operand")) ;; Source
1955 (use (match_operand:SI 0 "register_operand")) ;; Updated Dest
1959 rtx addr1 = gen_rtx_REG (SImode, 1);
1960 rtx addr2 = gen_rtx_REG (SImode, 2);
1961 rtx len = gen_rtx_REG (SImode, 3);
1962 rtx dest_copy = gen_reg_rtx (SImode);
1964 emit_move_insn (len, GEN_INT (-1));
1965 emit_move_insn (addr1, force_operand (XEXP (operands[1], 0), NULL_RTX));
1966 emit_move_insn (addr2, force_operand (XEXP (operands[2], 0), NULL_RTX));
1967 operands[1] = replace_equiv_address_nv (operands[1], addr1);
1968 operands[2] = replace_equiv_address_nv (operands[2], addr2);
1969 emit_move_insn (dest_copy, addr1);
1970 emit_insn (gen_rx_movstr ());
1971 emit_move_insn (len, GEN_INT (-1));
1972 emit_insn (gen_rx_strend (operands[0], dest_copy));
1977 (define_insn "rx_movstr"
1978 [(set (mem:BLK (reg:SI 1))
1979 (mem:BLK (reg:SI 2)))
1980 (unspec_volatile:BLK [(reg:SI 1) (reg:SI 2) (reg:SI 3)] UNSPEC_MOVSTR)
1981 (clobber (reg:SI 1))
1982 (clobber (reg:SI 2))
1983 (clobber (reg:SI 3))]
1986 [(set_attr "length" "2")
1987 (set_attr "timings" "1111")] ;; The timing is a guesstimate.
1990 (define_insn "rx_strend"
1991 [(set (match_operand:SI 0 "register_operand" "=r")
1992 (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "r")
1993 (reg:SI 3)] UNSPEC_STRLEN))
1994 (clobber (reg:SI 1))
1995 (clobber (reg:SI 2))
1996 (clobber (reg:SI 3))
1997 (clobber (reg:CC CC_REG))
2000 "mov\t%1, r1\n\tmov\t#0, r2\n\tsuntil.b\n\tmov\tr1, %0\n\tsub\t#1, %0"
2001 [(set_attr "length" "10")
2002 (set_attr "timings" "1111")] ;; The timing is a guesstimate.
2005 (define_expand "movmemsi"
2007 [(set (match_operand:BLK 0 "memory_operand") ;; Dest
2008 (match_operand:BLK 1 "memory_operand")) ;; Source
2009 (use (match_operand:SI 2 "register_operand")) ;; Length in bytes
2010 (match_operand 3 "immediate_operand") ;; Align
2011 (unspec_volatile:BLK [(reg:SI 1) (reg:SI 2) (reg:SI 3)] UNSPEC_MOVMEM)]
2015 rtx addr1 = gen_rtx_REG (SImode, 1);
2016 rtx addr2 = gen_rtx_REG (SImode, 2);
2017 rtx len = gen_rtx_REG (SImode, 3);
2019 if (REG_P (operands[0]) && (REGNO (operands[0]) == 2
2020 || REGNO (operands[0]) == 3))
2022 if (REG_P (operands[1]) && (REGNO (operands[1]) == 1
2023 || REGNO (operands[1]) == 3))
2025 if (REG_P (operands[2]) && (REGNO (operands[2]) == 1
2026 || REGNO (operands[2]) == 2))
2028 emit_move_insn (addr1, force_operand (XEXP (operands[0], 0), NULL_RTX));
2029 emit_move_insn (addr2, force_operand (XEXP (operands[1], 0), NULL_RTX));
2030 emit_move_insn (len, force_operand (operands[2], NULL_RTX));
2031 operands[0] = replace_equiv_address_nv (operands[0], addr1);
2032 operands[1] = replace_equiv_address_nv (operands[1], addr2);
2033 emit_insn (gen_rx_movmem ());
2038 (define_insn "rx_movmem"
2039 [(set (mem:BLK (reg:SI 1))
2040 (mem:BLK (reg:SI 2)))
2042 (unspec_volatile:BLK [(reg:SI 1) (reg:SI 2) (reg:SI 3)] UNSPEC_MOVMEM)
2043 (clobber (reg:SI 1))
2044 (clobber (reg:SI 2))
2045 (clobber (reg:SI 3))]
2048 [(set_attr "length" "2")
2049 (set_attr "timings" "1111")] ;; The timing is a guesstimate.
2052 (define_expand "setmemsi"
2053 [(set (match_operand:BLK 0 "memory_operand") ;; Dest
2054 (match_operand:QI 2 "nonmemory_operand")) ;; Value
2055 (use (match_operand:SI 1 "nonmemory_operand")) ;; Length
2056 (match_operand 3 "immediate_operand") ;; Align
2057 (unspec_volatile:BLK [(reg:SI 1) (reg:SI 2) (reg:SI 3)] UNSPEC_SETMEM)]
2060 rtx addr = gen_rtx_REG (SImode, 1);
2061 rtx val = gen_rtx_REG (QImode, 2);
2062 rtx len = gen_rtx_REG (SImode, 3);
2064 emit_move_insn (addr, force_operand (XEXP (operands[0], 0), NULL_RTX));
2065 emit_move_insn (len, force_operand (operands[1], NULL_RTX));
2066 emit_move_insn (val, operands[2]);
2067 emit_insn (gen_rx_setmem ());
2072 (define_insn "rx_setmem"
2073 [(set (mem:BLK (reg:SI 1))
2074 (unspec_volatile:BLK [(reg:SI 1) (reg:SI 2) (reg:SI 3)] UNSPEC_SETMEM))
2075 (clobber (reg:SI 1))
2076 (clobber (reg:SI 3))]
2079 [(set_attr "length" "2")
2080 (set_attr "timings" "1111")] ;; The timing is a guesstimate.
2083 (define_expand "cmpstrnsi"
2084 [(set (match_operand:SI 0 "register_operand") ;; Result
2085 (unspec_volatile:SI [(match_operand:BLK 1 "memory_operand") ;; String1
2086 (match_operand:BLK 2 "memory_operand")] ;; String2
2088 (use (match_operand:SI 3 "register_operand")) ;; Max Length
2089 (match_operand:SI 4 "immediate_operand")] ;; Known Align
2092 rtx str1 = gen_rtx_REG (SImode, 1);
2093 rtx str2 = gen_rtx_REG (SImode, 2);
2094 rtx len = gen_rtx_REG (SImode, 3);
2096 emit_move_insn (str1, force_operand (XEXP (operands[1], 0), NULL_RTX));
2097 emit_move_insn (str2, force_operand (XEXP (operands[2], 0), NULL_RTX));
2098 emit_move_insn (len, force_operand (operands[3], NULL_RTX));
2100 emit_insn (gen_rx_cmpstrn (operands[0], operands[1], operands[2]));
2105 (define_expand "cmpstrsi"
2106 [(set (match_operand:SI 0 "register_operand") ;; Result
2107 (unspec_volatile:SI [(match_operand:BLK 1 "memory_operand") ;; String1
2108 (match_operand:BLK 2 "memory_operand")] ;; String2
2110 (match_operand:SI 3 "immediate_operand")] ;; Known Align
2113 rtx str1 = gen_rtx_REG (SImode, 1);
2114 rtx str2 = gen_rtx_REG (SImode, 2);
2115 rtx len = gen_rtx_REG (SImode, 3);
2117 emit_move_insn (str1, force_reg (SImode, XEXP (operands[1], 0)));
2118 emit_move_insn (str2, force_reg (SImode, XEXP (operands[2], 0)));
2119 emit_move_insn (len, GEN_INT (-1));
2121 emit_insn (gen_rx_cmpstrn (operands[0], operands[1], operands[2]));
2126 (define_insn "rx_cmpstrn"
2127 [(set (match_operand:SI 0 "register_operand" "=r")
2128 (unspec_volatile:SI [(reg:SI 1) (reg:SI 2) (reg:SI 3)]
2130 (use (match_operand:BLK 1 "memory_operand" "m"))
2131 (use (match_operand:BLK 2 "memory_operand" "m"))
2132 (clobber (reg:SI 1))
2133 (clobber (reg:SI 2))
2134 (clobber (reg:SI 3))
2135 (clobber (reg:CC CC_REG))]
2137 "scmpu ; Perform the string comparison
2138 mov #-1, %0 ; Set up -1 result (which cannot be created
2140 bnc ?+ ; If Carry is not set skip over
2141 scne.L %0 ; Set result based on Z flag
2144 [(set_attr "length" "9")
2145 (set_attr "timings" "1111")] ;; The timing is a guesstimate.
2148 ;; Builtin Functions
2150 ;; GCC does not have the ability to generate the following instructions
2151 ;; on its own so they are provided as builtins instead. To use them from
2152 ;; a program for example invoke them as __builtin_rx_<insn_name>. For
2155 ;; int short_byte_swap (int arg) { return __builtin_rx_revw (arg); }
2157 ;;---------- Accumulator Support ------------------------
2159 ;; Multiply & Accumulate (high)
2160 (define_insn "machi"
2161 [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
2162 (match_operand:SI 1 "register_operand" "r")]
2163 UNSPEC_BUILTIN_MACHI)]
2166 [(set_attr "length" "3")]
2169 ;; Multiply & Accumulate (low)
2170 (define_insn "maclo"
2171 [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
2172 (match_operand:SI 1 "register_operand" "r")]
2173 UNSPEC_BUILTIN_MACLO)]
2176 [(set_attr "length" "3")]
2180 (define_insn "mulhi"
2181 [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
2182 (match_operand:SI 1 "register_operand" "r")]
2183 UNSPEC_BUILTIN_MULHI)]
2186 [(set_attr "length" "3")]
2190 (define_insn "mullo"
2191 [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
2192 (match_operand:SI 1 "register_operand" "r")]
2193 UNSPEC_BUILTIN_MULLO)]
2196 [(set_attr "length" "3")]
2199 ;; Move from Accumulator (high)
2200 (define_insn "mvfachi"
2201 [(set (match_operand:SI 0 "register_operand" "=r")
2202 (unspec:SI [(const_int 0)]
2203 UNSPEC_BUILTIN_MVFACHI))]
2206 [(set_attr "length" "3")]
2209 ;; Move from Accumulator (middle)
2210 (define_insn "mvfacmi"
2211 [(set (match_operand:SI 0 "register_operand" "=r")
2212 (unspec:SI [(const_int 0)]
2213 UNSPEC_BUILTIN_MVFACMI))]
2216 [(set_attr "length" "3")]
2219 ;; Move to Accumulator (high)
2220 (define_insn "mvtachi"
2221 [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")]
2222 UNSPEC_BUILTIN_MVTACHI)]
2225 [(set_attr "length" "3")]
2228 ;; Move to Accumulator (low)
2229 (define_insn "mvtaclo"
2230 [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")]
2231 UNSPEC_BUILTIN_MVTACLO)]
2234 [(set_attr "length" "3")]
2237 ;; Round Accumulator
2239 [(unspec_volatile:SI [(match_operand:SI 0 "immediate_operand" "i")]
2240 UNSPEC_BUILTIN_RACW)]
2243 [(set_attr "length" "3")]
2246 ;; Repeat multiply and accumulate
2248 [(unspec:SI [(const_int 0) (reg:SI 1) (reg:SI 2) (reg:SI 3)
2249 (reg:SI 4) (reg:SI 5) (reg:SI 6)]
2250 UNSPEC_BUILTIN_RMPA)
2251 (clobber (reg:SI 1))
2252 (clobber (reg:SI 2))
2253 (clobber (reg:SI 3))]
2256 [(set_attr "length" "2")
2257 (set_attr "timings" "1010")]
2260 ;;---------- Arithmetic ------------------------
2262 ;; Byte swap (two 16-bit values).
2264 [(set (match_operand:SI 0 "register_operand" "=r")
2265 (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
2266 UNSPEC_BUILTIN_REVW))]
2269 [(set_attr "length" "3")]
2272 ;; Round to integer.
2273 (define_insn "lrintsf2"
2274 [(set (match_operand:SI 0 "register_operand" "=r,r")
2275 (unspec:SI [(match_operand:SF 1 "rx_compare_operand" "r,Q")]
2276 UNSPEC_BUILTIN_ROUND))
2277 (clobber (reg:CC CC_REG))]
2280 [(set_attr "timings" "22,44")
2281 (set_attr "length" "3,5")]
2284 ;;---------- Control Registers ------------------------
2286 ;; Clear Processor Status Word
2287 (define_insn "clrpsw"
2288 [(unspec_volatile:SI [(match_operand:SI 0 "immediate_operand" "i")]
2289 UNSPEC_BUILTIN_CLRPSW)
2290 (clobber (reg:CC CC_REG))]
2293 [(set_attr "length" "2")]
2296 ;; Set Processor Status Word
2297 (define_insn "setpsw"
2298 [(unspec_volatile:SI [(match_operand:SI 0 "immediate_operand" "i")]
2299 UNSPEC_BUILTIN_SETPSW)
2300 (clobber (reg:CC CC_REG))]
2303 [(set_attr "length" "2")]
2306 ;; Move from control register
2308 [(set (match_operand:SI 0 "register_operand" "=r")
2309 (unspec_volatile:SI [(match_operand:SI 1 "immediate_operand" "i")]
2310 UNSPEC_BUILTIN_MVFC))]
2313 [(set_attr "length" "3")]
2316 ;; Move to control register
2318 [(unspec_volatile:SI [(match_operand:SI 0 "immediate_operand" "i,i")
2319 (match_operand:SI 1 "nonmemory_operand" "r,i")]
2320 UNSPEC_BUILTIN_MVTC)]
2323 [(set_attr "length" "3,7")]
2324 ;; Ignore possible clobbering of the comparison flags in the
2325 ;; PSW register. This is a cc0 target so any cc0 setting
2326 ;; instruction will always be paired with a cc0 user, without
2327 ;; the possibility of this instruction being placed in between
2331 ;; Move to interrupt priority level
2332 (define_insn "mvtipl"
2333 [(unspec_volatile:SI [(match_operand:SI 0 "immediate_operand" "Uint04")]
2334 UNSPEC_BUILTIN_MVTIPL)]
2337 [(set_attr "length" "3")]
2340 ;;---------- Interrupts ------------------------
2344 [(unspec_volatile [(const_int 0)]
2345 UNSPEC_BUILTIN_BRK)]
2348 [(set_attr "length" "1")
2349 (set_attr "timings" "66")]
2354 [(unspec_volatile:SI [(match_operand:SI 0 "immediate_operand" "i")]
2355 UNSPEC_BUILTIN_INT)]
2358 [(set_attr "length" "3")]
2363 [(unspec_volatile [(const_int 0)]
2364 UNSPEC_BUILTIN_WAIT)]
2367 [(set_attr "length" "2")]
2370 ;;---------- CoProcessor Support ------------------------
2372 ;; FIXME: The instructions are currently commented out because
2373 ;; the bit patterns have not been finalized, so the assembler
2374 ;; does not support them. Once they are decided and the assembler
2375 ;; supports them, enable the instructions here.
2377 ;; Move from co-processor register
2378 (define_insn "mvfcp"
2379 [(set (match_operand:SI 0 "register_operand" "=r")
2380 (unspec:SI [(match_operand:SI 1 "immediate_operand" "i")
2381 (match_operand:SI 2 "immediate_operand" "i")]
2382 UNSPEC_BUILTIN_MVFCP))]
2384 "; mvfcp\t%1, %0, %2"
2385 [(set_attr "length" "5")]
2388 ;;---------- Misc ------------------------
2390 ;; Required by cfglayout.c...
2395 [(set_attr "length" "1")]