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 allows all branch instructions to
23 ;; be generated from a single define_expand template.
24 (define_code_iterator most_cond [eq ne gt ge lt le gtu geu ltu leu
27 ;; This code iterator is used for sign- and zero- extensions.
28 (define_mode_iterator small_int_modes [(HI "") (QI "")])
30 ;; We do not handle DFmode here because it is either
31 ;; the same as SFmode, or if -m64bit-doubles is active
32 ;; then all operations on doubles have to be handled by
34 (define_mode_iterator register_modes
35 [(SF "ALLOW_RX_FPU_INSNS") (SI "") (HI "") (QI "")])
38 ;; Used to map RX condition names to GCC
39 ;; condition names for builtin instructions.
40 (define_code_iterator gcc_conds [eq ne gt ge lt le gtu geu ltu leu
42 (define_code_attr rx_conds [(eq "eq") (ne "ne") (gt "gt") (ge "ge") (lt "lt")
43 (le "le") (gtu "gtu") (geu "geu") (ltu "ltu")
44 (leu "leu") (unge "pz") (unlt "n") (uneq "o")
65 (UNSPEC_BUILTIN_BRK 30)
66 (UNSPEC_BUILTIN_CLRPSW 31)
67 (UNSPEC_BUILTIN_INT 32)
68 (UNSPEC_BUILTIN_MACHI 33)
69 (UNSPEC_BUILTIN_MACLO 34)
70 (UNSPEC_BUILTIN_MULHI 35)
71 (UNSPEC_BUILTIN_MULLO 36)
72 (UNSPEC_BUILTIN_MVFACHI 37)
73 (UNSPEC_BUILTIN_MVFACMI 38)
74 (UNSPEC_BUILTIN_MVFC 39)
75 (UNSPEC_BUILTIN_MVFCP 40)
76 (UNSPEC_BUILTIN_MVTACHI 41)
77 (UNSPEC_BUILTIN_MVTACLO 42)
78 (UNSPEC_BUILTIN_MVTC 43)
79 (UNSPEC_BUILTIN_MVTIPL 44)
80 (UNSPEC_BUILTIN_RACW 45)
81 (UNSPEC_BUILTIN_REVW 46)
82 (UNSPEC_BUILTIN_RMPA 47)
83 (UNSPEC_BUILTIN_ROUND 48)
84 (UNSPEC_BUILTIN_SAT 49)
85 (UNSPEC_BUILTIN_SETPSW 50)
86 (UNSPEC_BUILTIN_WAIT 51)
90 (define_attr "length" "" (const_int 8))
92 (include "predicates.md")
93 (include "constraints.md")
95 ;; Pipeline description.
97 ;; The RX only has a single pipeline. It has five stages (fetch,
98 ;; decode, execute, memory access, writeback) each of which normally
99 ;; takes a single CPU clock cycle.
101 ;; The timings attribute consists of two numbers, the first is the
102 ;; throughput, which is the number of cycles the instruction takes
103 ;; to execute and generate a result. The second is the latency
104 ;; which is the effective number of cycles the instruction takes to
105 ;; execute if its result is used by the following instruction. The
106 ;; latency is always greater than or equal to the throughput.
107 ;; These values were taken from tables 2.13 and 2.14 in section 2.8
108 ;; of the RX610 Group Hardware Manual v0.11
110 ;; Note - it would be nice to use strings rather than integers for
111 ;; the possible values of this attribute, so that we can have the
112 ;; gcc build mechanism check for values that are not supported by
113 ;; the reservations below. But this will not work because the code
114 ;; in rx_adjust_sched_cost() needs integers not strings.
116 (define_attr "timings" "" (const_int 11))
118 (define_automaton "pipelining")
119 (define_cpu_unit "throughput" "pipelining")
121 (define_insn_reservation "throughput__1_latency__1" 1
122 (eq_attr "timings" "11") "throughput")
123 (define_insn_reservation "throughput__1_latency__2" 2
124 (eq_attr "timings" "12") "throughput,nothing")
125 (define_insn_reservation "throughput__2_latency__2" 1
126 (eq_attr "timings" "22") "throughput*2")
127 (define_insn_reservation "throughput__3_latency__3" 1
128 (eq_attr "timings" "33") "throughput*3")
129 (define_insn_reservation "throughput__3_latency__4" 2
130 (eq_attr "timings" "34") "throughput*3,nothing")
131 (define_insn_reservation "throughput__4_latency__4" 1
132 (eq_attr "timings" "44") "throughput*4")
133 (define_insn_reservation "throughput__4_latency__5" 2
134 (eq_attr "timings" "45") "throughput*4,nothing")
135 (define_insn_reservation "throughput__5_latency__5" 1
136 (eq_attr "timings" "55") "throughput*5")
137 (define_insn_reservation "throughput__5_latency__6" 2
138 (eq_attr "timings" "56") "throughput*5,nothing")
139 (define_insn_reservation "throughput__6_latency__6" 1
140 (eq_attr "timings" "66") "throughput*6")
141 (define_insn_reservation "throughput_10_latency_10" 1
142 (eq_attr "timings" "1010") "throughput*10")
143 (define_insn_reservation "throughput_11_latency_11" 1
144 (eq_attr "timings" "1111") "throughput*11")
145 (define_insn_reservation "throughput_16_latency_16" 1
146 (eq_attr "timings" "1616") "throughput*16")
147 (define_insn_reservation "throughput_18_latency_18" 1
148 (eq_attr "timings" "1818") "throughput*18")
152 ;; Note - we do not specify the two instructions necessary to perform
153 ;; a compare-and-branch in the cbranchsi4 pattern because that would
154 ;; allow the comparison to be moved away from the jump before the reload
155 ;; pass has completed. That would be problematical because reload can
156 ;; generate ADDSI3 instructions which would corrupt the PSW flags.
158 (define_expand "cbranchsi4"
160 (if_then_else (match_operator:SI 0 "comparison_operator"
161 [(match_operand:SI 1 "register_operand")
162 (match_operand:SI 2 "rx_source_operand")])
163 (label_ref (match_operand 3 ""))
170 (define_insn_and_split "*cbranchsi4_<code>"
172 (if_then_else (most_cond:SI (match_operand:SI 0 "register_operand" "r")
173 (match_operand:SI 1 "rx_source_operand" "riQ"))
174 (label_ref (match_operand 2 "" ""))
182 /* We contstruct the split by hand as otherwise the JUMP_LABEL
183 attribute is not set correctly on the jump insn. */
184 emit_insn (gen_cmpsi (operands[0], operands[1]));
186 emit_jump_insn (gen_conditional_branch (operands[2],
187 gen_rtx_fmt_ee (<most_cond:CODE>, CCmode,
188 gen_rtx_REG (CCmode, CC_REG), const0_rtx)));
192 (define_expand "cbranchsf4"
194 (if_then_else (match_operator:SF 0 "comparison_operator"
195 [(match_operand:SF 1 "register_operand")
196 (match_operand:SF 2 "rx_source_operand")])
197 (label_ref (match_operand 3 ""))
204 (define_insn_and_split "*cbranchsf4_<code>"
206 (if_then_else (most_cond:SF (match_operand:SF 0 "register_operand" "r")
207 (match_operand:SF 1 "rx_source_operand" "rFiQ"))
208 (label_ref (match_operand 2 "" ""))
213 "&& reload_completed"
216 /* We contstruct the split by hand as otherwise the JUMP_LABEL
217 attribute is not set correctly on the jump insn. */
218 emit_insn (gen_cmpsf (operands[0], operands[1]));
220 emit_jump_insn (gen_conditional_branch (operands[2],
221 gen_rtx_fmt_ee (<most_cond:CODE>, CCmode,
222 gen_rtx_REG (CCmode, CC_REG), const0_rtx)));
227 [(set (reg:CC_ZS CC_REG)
228 (compare:CC_ZS (and:SI (match_operand:SI 0 "register_operand" "r,r,r")
229 (match_operand:SI 1 "rx_source_operand" "r,i,Q"))
233 rx_float_compare_mode = false;
234 return "tst\t%Q1, %0";
236 [(set_attr "timings" "11,11,33")
237 (set_attr "length" "3,7,6")]
241 [(set (reg:CC CC_REG)
242 (compare:CC (match_operand:SI 0 "register_operand" "r,r,r,r,r,r,r")
243 (match_operand:SI 1 "rx_source_operand" "r,Uint04,Int08,Sint16,Sint24,i,Q")))]
246 rx_float_compare_mode = false;
247 if (rx_compare_redundant (insn))
248 return "; Compare Eliminated: cmp %Q1, %0";
249 return "cmp\t%Q1, %0";
251 [(set_attr "timings" "11,11,11,11,11,11,33")
252 (set_attr "length" "2,2,3,4,5,6,5")]
255 ;; ??? g++.dg/eh/080514-1.C to see this happen.
257 [(set (reg:CC_ZSO CC_REG)
258 (compare:CC_ZSO (match_operand:SF 0 "register_operand" "r,r,r")
259 (match_operand:SF 1 "rx_source_operand" "r,iF,Q")))]
262 rx_float_compare_mode = true;
263 return "fcmp\t%1, %0";
265 [(set_attr "timings" "11,11,33")
266 (set_attr "length" "3,7,5")]
269 ;; Flow Control Instructions:
271 (define_expand "b<code>"
273 (if_then_else (most_cond (reg:CC CC_REG) (const_int 0))
274 (label_ref (match_operand 0))
280 (define_insn "conditional_branch"
282 (if_then_else (match_operator 1 "comparison_operator"
283 [(reg:CC CC_REG) (const_int 0)])
284 (label_ref (match_operand 0 "" ""))
288 return rx_gen_cond_branch_template (operands[1], false);
290 [(set_attr "length" "8") ;; This length is wrong, but it is
291 ;; too hard to compute statically.
292 (set_attr "timings" "33")] ;; The timing assumes that the branch is taken.
295 (define_insn "*reveresed_conditional_branch"
297 (if_then_else (match_operator 1 "comparison_operator"
298 [(reg:CC CC_REG) (const_int 0)])
300 (label_ref (match_operand 0 "" ""))))]
303 return rx_gen_cond_branch_template (operands[1], true);
305 [(set_attr "length" "8") ;; This length is wrong, but it is
306 ;; too hard to compute statically.
307 (set_attr "timings" "33")] ;; The timing assumes that the branch is taken.
312 (label_ref (match_operand 0 "" "")))]
315 [(set_attr "length" "4")
316 (set_attr "timings" "33")]
319 (define_insn "indirect_jump"
321 (match_operand:SI 0 "register_operand" "r"))]
324 [(set_attr "length" "2")
325 (set_attr "timings" "33")]
328 (define_insn "tablejump"
330 (match_operand:SI 0 "register_operand" "r"))
331 (use (label_ref (match_operand 1 "" "")))]
333 { return flag_pic ? (TARGET_AS100_SYNTAX ? "\n?:\tbra\t%0"
337 [(set_attr "timings" "33")
338 (set_attr "length" "2")]
341 (define_insn "simple_return"
345 [(set_attr "length" "1")
346 (set_attr "timings" "55")]
349 (define_insn "deallocate_and_return"
350 [(set (reg:SI SP_REG)
351 (plus:SI (reg:SI SP_REG)
352 (match_operand:SI 0 "immediate_operand" "i")))
356 [(set_attr "length" "2")
357 (set_attr "timings" "55")]
360 (define_insn "pop_and_return"
361 [(match_parallel 1 "rx_rtsd_vector"
362 [(set:SI (reg:SI SP_REG)
363 (plus:SI (reg:SI SP_REG)
364 (match_operand:SI 0 "const_int_operand" "n")))])]
367 rx_emit_stack_popm (operands, false);
370 [(set_attr "length" "3")
371 (set_attr "timings" "56")]
374 (define_insn "fast_interrupt_return"
375 [(unspec_volatile [(return)] UNSPEC_RTFI) ]
378 [(set_attr "length" "2")
379 (set_attr "timings" "33")]
382 (define_insn "exception_return"
383 [(unspec_volatile [(return)] UNSPEC_RTE) ]
386 [(set_attr "length" "2")
387 (set_attr "timings" "66")]
390 (define_insn "naked_return"
391 [(unspec_volatile [(return)] UNSPEC_NAKED) ]
393 "; Naked function: epilogue provided by programmer."
397 ;; Note - the following set of patterns do not use the "memory_operand"
398 ;; predicate or an "m" constraint because we do not allow symbol_refs
399 ;; or label_refs as legitmate memory addresses. This matches the
400 ;; behaviour of most of the RX instructions. Only the call/branch
401 ;; instructions are allowed to refer to symbols/labels directly.
402 ;; The call operands are in QImode because that is the value of
405 (define_expand "call"
406 [(call (match_operand:QI 0 "general_operand")
407 (match_operand:SI 1 "general_operand"))]
410 rtx dest = XEXP (operands[0], 0);
412 if (! rx_call_operand (dest, Pmode))
413 dest = force_reg (Pmode, dest);
414 emit_call_insn (gen_call_internal (dest, operands[1]));
419 (define_insn "call_internal"
420 [(call (mem:QI (match_operand:SI 0 "rx_call_operand" "r,Symbol"))
421 (match_operand:SI 1 "general_operand" "g,g"))
422 (clobber (reg:CC CC_REG))]
427 [(set_attr "length" "2,4")
428 (set_attr "timings" "33")]
431 (define_expand "call_value"
432 [(set (match_operand 0 "register_operand")
433 (call (match_operand:QI 1 "general_operand")
434 (match_operand:SI 2 "general_operand")))]
437 rtx dest = XEXP (operands[1], 0);
439 if (! rx_call_operand (dest, Pmode))
440 dest = force_reg (Pmode, dest);
441 emit_call_insn (gen_call_value_internal (operands[0], dest, operands[2]));
446 (define_insn "call_value_internal"
447 [(set (match_operand 0 "register_operand" "=r,r")
448 (call (mem:QI (match_operand:SI 1 "rx_call_operand" "r,Symbol"))
449 (match_operand:SI 2 "general_operand" "g,g")))
450 (clobber (reg:CC CC_REG))]
455 [(set_attr "length" "2,4")
456 (set_attr "timings" "33")]
459 ;; Note - we do not allow indirect sibcalls (with the address
460 ;; held in a register) because we cannot guarantee that the register
461 ;; chosen will be a call-used one. If it is a call-saved register,
462 ;; then the epilogue code will corrupt it by popping the saved value
464 (define_expand "sibcall"
466 [(call (mem:QI (match_operand:SI 0 "rx_symbolic_call_operand"))
467 (match_operand:SI 1 "general_operand"))
471 if (MEM_P (operands[0]))
472 operands[0] = XEXP (operands[0], 0);
476 (define_insn "sibcall_internal"
477 [(call (mem:QI (match_operand:SI 0 "rx_symbolic_call_operand" "Symbol"))
478 (match_operand:SI 1 "general_operand" "g"))
482 [(set_attr "length" "4")
483 (set_attr "timings" "33")]
486 (define_expand "sibcall_value"
488 [(set (match_operand 0 "register_operand")
489 (call (mem:QI (match_operand:SI 1 "rx_symbolic_call_operand"))
490 (match_operand:SI 2 "general_operand")))
494 if (MEM_P (operands[1]))
495 operands[1] = XEXP (operands[1], 0);
499 (define_insn "sibcall_value_internal"
500 [(set (match_operand 0 "register_operand" "=r")
501 (call (mem:QI (match_operand:SI 1 "rx_symbolic_call_operand" "Symbol"))
502 (match_operand:SI 2 "general_operand" "g")))
506 [(set_attr "length" "4")
507 (set_attr "timings" "33")]
510 ;; Function Prologue/Epilogue Instructions
512 (define_expand "prologue"
515 "rx_expand_prologue (); DONE;"
518 (define_expand "epilogue"
521 "rx_expand_epilogue (false); DONE;"
524 (define_expand "sibcall_epilogue"
527 "rx_expand_epilogue (true); DONE;"
532 ;; Note - we do not allow memory to memory moves, even though the ISA
533 ;; supports them. The reason is that the conditions on such moves are
534 ;; too restrictive, specifically the source addressing mode is limited
535 ;; by the destination addressing mode and vice versa. (For example it
536 ;; is not possible to use indexed register indirect addressing for one
537 ;; of the operands if the other operand is anything other than a register,
538 ;; but it is possible to use register relative addressing when the other
539 ;; operand also uses register relative or register indirect addressing).
541 ;; GCC does not support computing legitimate addresses based on the
542 ;; nature of other operands involved in the instruction, and reload is
543 ;; not smart enough to cope with a whole variety of different memory
544 ;; addressing constraints, so it is simpler and safer to just refuse
545 ;; to support memory to memory moves.
547 (define_expand "mov<register_modes:mode>"
548 [(set (match_operand:register_modes 0 "general_operand")
549 (match_operand:register_modes 1 "general_operand"))]
552 if (MEM_P (operand0) && MEM_P (operand1))
553 operands[1] = copy_to_mode_reg (<register_modes:MODE>mode, operand1);
557 (define_insn "*mov<register_modes:mode>_internal"
558 [(set (match_operand:register_modes
559 0 "nonimmediate_operand" "=r,r,r,r,r,r,m,Q,Q,Q,Q")
560 (match_operand:register_modes
561 1 "general_operand" "Int08,Sint16,Sint24,i,r,m,r,Int08,Sint16,Sint24,i"))]
563 { return rx_gen_move_template (operands, false); }
564 [(set_attr "length" "3,4,5,6,2,4,6,5,6,7,8")
565 (set_attr "timings" "11,11,11,11,11,12,11,11,11,11,11")]
568 (define_insn "extend<small_int_modes:mode>si2"
569 [(set (match_operand:SI 0 "register_operand" "=r,r")
570 (sign_extend:SI (match_operand:small_int_modes
571 1 "nonimmediate_operand" "r,m")))]
573 { return rx_gen_move_template (operands, false); }
574 [(set_attr "length" "2,6")
575 (set_attr "timings" "11,12")]
578 (define_insn "zero_extend<small_int_modes:mode>si2"
579 [(set (match_operand:SI 0 "register_operand" "=r,r")
580 (zero_extend:SI (match_operand:small_int_modes
581 1 "nonimmediate_operand" "r,m")))]
583 { return rx_gen_move_template (operands, true); }
584 [(set_attr "length" "2,4")
585 (set_attr "timings" "11,12")]
588 (define_insn "stack_push"
589 [(set:SI (reg:SI SP_REG)
590 (minus:SI (reg:SI SP_REG)
592 (set:SI (mem:SI (reg:SI SP_REG))
593 (match_operand:SI 0 "register_operand" "r"))]
596 [(set_attr "length" "2")]
599 (define_insn "stack_pushm"
600 [(match_parallel 1 "rx_store_multiple_vector"
601 [(set:SI (reg:SI SP_REG)
602 (minus:SI (reg:SI SP_REG)
603 (match_operand:SI 0 "const_int_operand" "n")))])]
606 rx_emit_stack_pushm (operands);
609 [(set_attr "length" "2")
610 (set_attr "timings" "44")] ;; The timing is a guesstimate average timing.
613 (define_insn "stack_pop"
614 [(set:SI (match_operand:SI 0 "register_operand" "=r")
615 (mem:SI (reg:SI SP_REG)))
616 (set:SI (reg:SI SP_REG)
617 (plus:SI (reg:SI SP_REG)
621 [(set_attr "length" "2")
622 (set_attr "timings" "12")]
625 (define_insn "stack_popm"
626 [(match_parallel 1 "rx_load_multiple_vector"
627 [(set:SI (reg:SI SP_REG)
628 (plus:SI (reg:SI SP_REG)
629 (match_operand:SI 0 "const_int_operand" "n")))])]
632 rx_emit_stack_popm (operands, true);
635 [(set_attr "length" "2")
636 (set_attr "timings" "45")] ;; The timing is a guesstimate average timing.
639 ;; FIXME: Add memory destination options ?
640 (define_insn "cstoresi4"
641 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,r")
642 (match_operator:SI 1 "comparison_operator"
643 [(match_operand:SI 2 "register_operand" "r,r,r,r,r,r,r")
644 (match_operand:SI 3 "rx_source_operand" "r,Uint04,Int08,Sint16,Sint24,i,Q")]))
645 (clobber (reg:CC CC_REG))] ;; Because the cc flags are set based on comparing ops 2 & 3 not the value in op 0.
648 rx_float_compare_mode = false;
649 return "cmp\t%Q3, %Q2\n\tsc%B1.L\t%0";
651 [(set_attr "timings" "22,22,22,22,22,22,44")
652 (set_attr "length" "5,5,6,7,8,9,8")]
655 (define_expand "movsicc"
657 [(set (match_operand:SI 0 "register_operand")
658 (if_then_else:SI (match_operand:SI 1 "comparison_operator")
659 (match_operand:SI 2 "nonmemory_operand")
660 (match_operand:SI 3 "immediate_operand")))
661 (clobber (reg:CC CC_REG))])] ;; See cstoresi4
664 if (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE)
666 if (! CONST_INT_P (operands[3]))
671 (define_insn "*movsieq"
672 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
673 (if_then_else:SI (eq (match_operand:SI 3 "register_operand" "r,r,r")
674 (match_operand:SI 4 "rx_source_operand" "riQ,riQ,riQ"))
675 (match_operand:SI 1 "nonmemory_operand" "0,i,r")
676 (match_operand:SI 2 "immediate_operand" "i,i,i")))
677 (clobber (reg:CC CC_REG))] ;; See cstoresi4
680 cmp\t%Q4, %Q3\n\tstnz\t%2, %0
681 cmp\t%Q4, %Q3\n\tmov.l\t%2, %0\n\tstz\t%1, %0
682 cmp\t%Q4, %Q3\n\tmov.l\t%1, %0\n\tstnz\t%2, %0"
683 [(set_attr "length" "13,19,15")
684 (set_attr "timings" "22,33,33")]
687 (define_insn "*movsine"
688 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
689 (if_then_else:SI (ne (match_operand:SI 3 "register_operand" "r,r,r")
690 (match_operand:SI 4 "rx_source_operand" "riQ,riQ,riQ"))
691 (match_operand:SI 1 "nonmemory_operand" "0,i,r")
692 (match_operand:SI 2 "immediate_operand" "i,i,i")))
693 (clobber (reg:CC CC_REG))] ;; See cstoresi4
696 cmp\t%Q4, %Q3\n\tstz\t%2, %0
697 cmp\t%Q4, %Q3\n\tmov.l\t%2, %0\n\tstnz\t%1, %0
698 cmp\t%Q4, %Q3\n\tmov.l\t%1, %0\n\tstz\t%2, %0"
699 [(set_attr "length" "13,19,15")
700 (set_attr "timings" "22,33,33")]
703 ;; Arithmetic Instructions
705 (define_insn "abssi2"
706 [(set (match_operand:SI 0 "register_operand" "=r,r")
707 (abs:SI (match_operand:SI 1 "register_operand" "0,r")))
708 (set (reg:CC_ZSO CC_REG)
709 (compare:CC_ZSO (abs:SI (match_dup 1))
715 [(set_attr "length" "2,3")]
718 (define_insn "addsi3"
719 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,r,r,r,r,r,r,r,r")
720 (plus:SI (match_operand:SI 1 "register_operand" "%0,0,0,0,0,0,0,r,r,r,r,r,r,0")
721 (match_operand:SI 2 "rx_source_operand" "r,Uint04,NEGint4,Sint08,Sint16,Sint24,i,0,r,Sint08,Sint16,Sint24,i,Q")))
722 (set (reg:CC_ZSC CC_REG) ;; See subsi3
723 (compare:CC_ZSC (plus:SI (match_dup 1) (match_dup 2))
741 [(set_attr "timings" "11,11,11,11,11,11,11,11,11,11,11,11,11,33")
742 (set_attr "length" "2,2,2,3,4,5,6,2,3,3,4,5,6,5")]
745 (define_insn "adddi3"
746 [(set (match_operand:DI 0 "register_operand" "=r,r,r,r,r,r")
747 (plus:DI (match_operand:DI 1 "register_operand" "%0,0,0,0,0,0")
748 (match_operand:DI 2 "rx_source_operand"
749 "r,Sint08,Sint16,Sint24,i,Q")))
750 (set (reg:CC_ZSC CC_REG) ;; See subsi3
751 (compare:CC_ZSC (plus:DI (match_dup 1) (match_dup 2))
754 "add\t%L2, %L0\n\tadc\t%H2, %H0"
755 [(set_attr "timings" "22,22,22,22,22,44")
756 (set_attr "length" "5,7,9,11,13,11")]
759 (define_insn "andsi3"
760 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,r,r,r")
761 (and:SI (match_operand:SI 1 "register_operand" "%0,0,0,0,0,0,r,r,0")
762 (match_operand:SI 2 "rx_source_operand" "r,Uint04,Sint08,Sint16,Sint24,i,0,r,Q")))
763 (set (reg:CC_ZS CC_REG)
764 (compare:CC_ZS (and:SI (match_dup 1) (match_dup 2))
777 [(set_attr "timings" "11,11,11,11,11,11,11,33,33")
778 (set_attr "length" "2,2,3,4,5,6,2,5,5")]
781 ;; Byte swap (single 32-bit value).
782 (define_insn "bswapsi2"
783 [(set (match_operand:SI 0 "register_operand" "+r")
784 (bswap:SI (match_operand:SI 1 "register_operand" "r")))]
787 [(set_attr "length" "3")]
790 ;; Byte swap (single 16-bit value). Note - we ignore the swapping of the high 16-bits.
791 (define_insn "bswaphi2"
792 [(set (match_operand:HI 0 "register_operand" "+r")
793 (bswap:HI (match_operand:HI 1 "register_operand" "r")))]
796 [(set_attr "length" "3")]
799 (define_insn "divsi3"
800 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r")
801 (div:SI (match_operand:SI 1 "register_operand" "0,0,0,0,0,0")
802 (match_operand:SI 2 "rx_source_operand" "r,Sint08,Sint16,Sint24,i,Q")))
803 (clobber (reg:CC CC_REG))]
806 [(set_attr "timings" "1111") ;; Strictly speaking the timing should be
807 ;; 2222, but that is a worst case sceanario.
808 (set_attr "length" "3,4,5,6,7,6")]
811 (define_insn "udivsi3"
812 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r")
813 (udiv:SI (match_operand:SI 1 "register_operand" "0,0,0,0,0,0")
814 (match_operand:SI 2 "rx_source_operand" "r,Sint08,Sint16,Sint24,i,Q")))
815 (clobber (reg:CC CC_REG))]
818 [(set_attr "timings" "1010") ;; Strictly speaking the timing should be
819 ;; 2020, but that is a worst case sceanario.
820 (set_attr "length" "3,4,5,6,7,6")]
823 ;; Note - these patterns are suppressed in big-endian mode because they
824 ;; generate a little endian result. ie the most significant word of the
825 ;; result is placed in the higher numbered register of the destination
828 (define_insn "mulsidi3"
829 [(set (match_operand:DI 0 "register_operand" "=r,r,r,r,r,r")
830 (mult:DI (sign_extend:DI (match_operand:SI
831 1 "register_operand" "%0,0,0,0,0,0"))
832 (sign_extend:DI (match_operand:SI
833 2 "rx_source_operand"
834 "r,Sint08,Sint16,Sint24,i,Q"))))]
835 "! TARGET_BIG_ENDIAN_DATA"
837 [(set_attr "length" "3,4,5,6,7,6")
838 (set_attr "timings" "22,22,22,22,22,44")]
841 ;; See comment for mulsidi3.
842 ;; Note - the zero_extends are to distinguish this pattern from the
843 ;; mulsidi3 pattern. Immediate mode addressing is not supported
844 ;; because gcc cannot handle the expression: (zero_extend (const_int)).
845 (define_insn "umulsidi3"
846 [(set (match_operand:DI 0 "register_operand" "=r,r")
847 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0,0"))
848 (zero_extend:DI (match_operand:SI 2 "rx_compare_operand" "r,Q"))))]
849 "! TARGET_BIG_ENDIAN_DATA"
851 [(set_attr "length" "3,6")
852 (set_attr "timings" "22,44")]
855 (define_insn "smaxsi3"
856 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r")
857 (smax:SI (match_operand:SI 1 "register_operand" "%0,0,0,0,0,0")
858 (match_operand:SI 2 "rx_source_operand"
859 "r,Sint08,Sint16,Sint24,i,Q")))]
862 [(set_attr "length" "3,4,5,6,7,6")
863 (set_attr "timings" "11,11,11,11,11,33")]
866 (define_insn "sminsi3"
867 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r")
868 (smin:SI (match_operand:SI 1 "register_operand" "%0,0,0,0,0,0")
869 (match_operand:SI 2 "rx_source_operand"
870 "r,Sint08,Sint16,Sint24,i,Q")))]
873 [(set_attr "length" "3,4,5,6,7,6")
874 (set_attr "timings" "11,11,11,11,11,33")]
877 (define_insn "mulsi3"
878 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,r,r,r")
879 (mult:SI (match_operand:SI 1 "register_operand" "%0,0,0,0,0,0,0,r,r")
880 (match_operand:SI 2 "rx_source_operand"
881 "r,Uint04,Sint08,Sint16,Sint24,i,Q,0,r")))]
893 [(set_attr "length" "2,2,3,4,5,6,5,2,3")
894 (set_attr "timings" "11,11,11,11,11,11,33,11,11")]
897 (define_insn "negsi2"
898 [(set (match_operand:SI 0 "register_operand" "=r,r")
899 (neg:SI (match_operand:SI 1 "register_operand" "0,r")))
901 (compare:CC (neg:SI (match_dup 1))
903 ;; The NEG instruction does not comply with -fwrapv semantics.
904 ;; See gcc.c-torture/execute/pr22493-1.c for an example of this.
909 [(set_attr "length" "2,3")]
912 (define_insn "one_cmplsi2"
913 [(set (match_operand:SI 0 "register_operand" "=r,r")
914 (not:SI (match_operand:SI 1 "register_operand" "0,r")))
915 (set (reg:CC_ZS CC_REG)
916 (compare:CC_ZS (not:SI (match_dup 1))
922 [(set_attr "length" "2,3")]
925 (define_insn "iorsi3"
926 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,r,r,r")
927 (ior:SI (match_operand:SI 1 "register_operand" "%0,0,0,0,0,0,r,r,0")
928 (match_operand:SI 2 "rx_source_operand" "r,Uint04,Sint08,Sint16,Sint24,i,0,r,Q")))
929 (set (reg:CC_ZS CC_REG)
930 (compare:CC_ZS (ior:SI (match_dup 1) (match_dup 2))
943 [(set_attr "timings" "11,11,11,11,11,11,11,11,33")
944 (set_attr "length" "2,2,3,4,5,6,2,3,5")]
947 (define_insn "rotlsi3"
948 [(set (match_operand:SI 0 "register_operand" "=r")
949 (rotate:SI (match_operand:SI 1 "register_operand" "0")
950 (match_operand:SI 2 "rx_shift_operand" "rn")))
951 (set (reg:CC_ZS CC_REG)
952 (compare:CC_ZS (rotate:SI (match_dup 1) (match_dup 2))
956 [(set_attr "length" "3")]
959 (define_insn "rotrsi3"
960 [(set (match_operand:SI 0 "register_operand" "=r")
961 (rotatert:SI (match_operand:SI 1 "register_operand" "0")
962 (match_operand:SI 2 "rx_shift_operand" "rn")))
963 (set (reg:CC_ZS CC_REG)
964 (compare:CC_ZS (rotatert:SI (match_dup 1) (match_dup 2))
968 [(set_attr "length" "3")]
971 (define_insn "ashrsi3"
972 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
973 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0,r")
974 (match_operand:SI 2 "rx_shift_operand" "r,n,n")))
975 (set (reg:CC_ZS CC_REG)
976 (compare:CC_ZS (ashiftrt:SI (match_dup 1) (match_dup 2))
983 [(set_attr "length" "3,2,3")]
986 (define_insn "lshrsi3"
987 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
988 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0,0,r")
989 (match_operand:SI 2 "rx_shift_operand" "r,n,n")))
990 (set (reg:CC_ZS CC_REG)
991 (compare:CC_ZS (lshiftrt:SI (match_dup 1) (match_dup 2))
998 [(set_attr "length" "3,2,3")]
1001 (define_insn "ashlsi3"
1002 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
1003 (ashift:SI (match_operand:SI 1 "register_operand" "0,0,r")
1004 (match_operand:SI 2 "rx_shift_operand" "r,n,n")))
1005 (set (reg:CC_ZS CC_REG)
1006 (compare:CC_ZS (ashift:SI (match_dup 1) (match_dup 2))
1013 [(set_attr "length" "3,2,3")]
1016 (define_insn "subsi3"
1017 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r")
1018 (minus:SI (match_operand:SI 1 "register_operand" "0,0,0,r,0")
1019 (match_operand:SI 2 "rx_source_operand" "r,Uint04,n,r,Q")))
1020 (set (reg:CC_ZSC CC_REG)
1021 ;; Note - we do not acknowledge that the SUB instruction sets the Overflow
1022 ;; flag because its interpretation is different from comparing the result
1023 ;; against zero. Compile and run gcc.c-torture/execute/cmpsi-1.c to see this.
1024 (compare:CC_ZSC (minus:SI (match_dup 1) (match_dup 2))
1033 [(set_attr "timings" "11,11,11,11,33")
1034 (set_attr "length" "2,2,6,3,5")]
1037 (define_insn "subdi3"
1038 [(set (match_operand:DI 0 "register_operand" "=r,r")
1039 (minus:DI (match_operand:DI 1 "register_operand" "0,0")
1040 (match_operand:DI 2 "rx_source_operand" "r,Q")))
1041 (set (reg:CC_ZSC CC_REG) ;; See subsi3
1042 (compare:CC_ZSC (minus:DI (match_dup 1) (match_dup 2))
1045 "sub\t%L2, %L0\n\tsbb\t%H2, %H0"
1046 [(set_attr "timings" "22,44")
1047 (set_attr "length" "5,11")]
1050 (define_insn "xorsi3"
1051 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r")
1052 (xor:SI (match_operand:SI 1 "register_operand" "%0,0,0,0,0,0")
1053 (match_operand:SI 2 "rx_source_operand"
1054 "r,Sint08,Sint16,Sint24,i,Q")))
1055 (set (reg:CC_ZS CC_REG)
1056 (compare:CC_ZS (xor:SI (match_dup 1) (match_dup 2))
1060 [(set_attr "timings" "11,11,11,11,11,33")
1061 (set_attr "length" "3,4,5,6,7,6")]
1064 ;; Floating Point Instructions
1066 (define_insn "addsf3"
1067 [(set (match_operand:SF 0 "register_operand" "=r,r,r")
1068 (plus:SF (match_operand:SF 1 "register_operand" "%0,0,0")
1069 (match_operand:SF 2 "rx_source_operand" "r,F,Q")))
1070 (set (reg:CC_ZS CC_REG)
1071 (compare:CC_ZS (plus:SF (match_dup 1) (match_dup 2))
1073 "ALLOW_RX_FPU_INSNS"
1075 [(set_attr "timings" "44,44,66")
1076 (set_attr "length" "3,7,5")]
1079 (define_insn "divsf3"
1080 [(set (match_operand:SF 0 "register_operand" "=r,r,r")
1081 (div:SF (match_operand:SF 1 "register_operand" "0,0,0")
1082 (match_operand:SF 2 "rx_source_operand" "r,F,Q")))
1083 (set (reg:CC_ZS CC_REG)
1084 (compare:CC_ZS (div:SF (match_dup 1) (match_dup 2))
1086 "ALLOW_RX_FPU_INSNS"
1088 [(set_attr "timings" "1616,1616,1818")
1089 (set_attr "length" "3,7,5")]
1092 (define_insn "mulsf3"
1093 [(set (match_operand:SF 0 "register_operand" "=r,r,r")
1094 (mult:SF (match_operand:SF 1 "register_operand" "%0,0,0")
1095 (match_operand:SF 2 "rx_source_operand" "r,F,Q")))
1096 (set (reg:CC_ZS CC_REG)
1097 (compare:CC_ZS (mult:SF (match_dup 1) (match_dup 2))
1099 "ALLOW_RX_FPU_INSNS"
1101 [(set_attr "timings" "33,33,55")
1102 (set_attr "length" "3,7,5")]
1105 (define_insn "subsf3"
1106 [(set (match_operand:SF 0 "register_operand" "=r,r,r")
1107 (minus:SF (match_operand:SF 1 "register_operand" "0,0,0")
1108 (match_operand:SF 2 "rx_source_operand" "r,F,Q")))
1109 (set (reg:CC_ZS CC_REG)
1110 (compare:CC_ZS (minus:SF (match_dup 1) (match_dup 2))
1112 "ALLOW_RX_FPU_INSNS"
1114 [(set_attr "timings" "44,44,66")
1115 (set_attr "length" "3,7,5")]
1118 (define_insn "fix_truncsfsi2"
1119 [(set (match_operand:SI 0 "register_operand" "=r,r")
1120 (fix:SI (match_operand:SF 1 "rx_compare_operand" "r,Q")))
1121 (set (reg:CC_ZS CC_REG)
1122 (compare:CC_ZS (fix:SI (match_dup 1))
1124 "ALLOW_RX_FPU_INSNS"
1126 [(set_attr "timings" "22,44")
1127 (set_attr "length" "3,5")]
1130 (define_insn "floatsisf2"
1131 [(set (match_operand:SF 0 "register_operand" "=r,r")
1132 (float:SF (match_operand:SI 1 "rx_compare_operand" "r,Q")))
1133 (set (reg:CC_ZS CC_REG)
1134 (compare:CC_ZS (float:SF (match_dup 1))
1136 "ALLOW_RX_FPU_INSNS"
1138 [(set_attr "timings" "22,44")
1139 (set_attr "length" "3,6")]
1142 ;; Bit manipulation instructions.
1143 ;; Note - there are two versions of each pattern because the memory
1144 ;; accessing versions use QImode whilst the register accessing
1145 ;; versions use SImode.
1146 ;; The peephole are here because the combiner only looks at a maximum
1147 ;; of three instructions at a time.
1149 (define_insn "bitset"
1150 [(set:SI (match_operand:SI 0 "register_operand" "=r")
1151 (ior:SI (match_operand:SI 1 "register_operand" "0")
1152 (ashift:SI (const_int 1)
1153 (match_operand:SI 2 "nonmemory_operand" "ri"))))]
1156 [(set_attr "length" "3")]
1159 (define_insn "bitset_in_memory"
1160 [(set:QI (match_operand:QI 0 "memory_operand" "=m")
1161 (ior:QI (match_operand:QI 1 "memory_operand" "0")
1162 (ashift:QI (const_int 1)
1163 (match_operand:QI 2 "nonmemory_operand" "ri"))))]
1166 [(set_attr "length" "3")
1167 (set_attr "timings" "34")]
1170 ;; (set (reg A) (const_int 1))
1171 ;; (set (reg A) (ashift (reg A) (reg B)))
1172 ;; (set (reg C) (ior (reg A) (reg C)))
1174 [(set:SI (match_operand:SI 0 "register_operand" "")
1176 (set:SI (match_dup 0)
1177 (ashift:SI (match_dup 0)
1178 (match_operand:SI 1 "register_operand" "")))
1179 (set:SI (match_operand:SI 2 "register_operand" "")
1180 (ior:SI (match_dup 0)
1182 "dead_or_set_p (insn, operands[0])"
1183 [(set:SI (match_dup 2)
1184 (ior:SI (match_dup 2)
1185 (ashift:SI (const_int 1)
1189 ;; (set (reg A) (const_int 1))
1190 ;; (set (reg A) (ashift (reg A) (reg B)))
1191 ;; (set (reg A) (ior (reg A) (reg C)))
1192 ;; (set (reg C) (reg A)
1194 [(set:SI (match_operand:SI 0 "register_operand" "")
1196 (set:SI (match_dup 0)
1197 (ashift:SI (match_dup 0)
1198 (match_operand:SI 1 "register_operand" "")))
1199 (set:SI (match_dup 0)
1200 (ior:SI (match_dup 0)
1201 (match_operand:SI 2 "register_operand" "")))
1202 (set:SI (match_dup 2) (match_dup 0))]
1203 "dead_or_set_p (insn, operands[0])"
1204 [(set:SI (match_dup 2)
1205 (ior:SI (match_dup 2)
1206 (ashift:SI (const_int 1)
1210 (define_insn "bitinvert"
1211 [(set:SI (match_operand:SI 0 "register_operand" "+r")
1212 (xor:SI (match_operand:SI 1 "register_operand" "0")
1213 (ashift:SI (const_int 1)
1214 (match_operand:SI 2 "nonmemory_operand" "ri"))))]
1217 [(set_attr "length" "3")]
1220 (define_insn "bitinvert_in_memory"
1221 [(set:QI (match_operand:QI 0 "memory_operand" "+m")
1222 (xor:QI (match_operand:QI 1 "register_operand" "0")
1223 (ashift:QI (const_int 1)
1224 (match_operand:QI 2 "nonmemory_operand" "ri"))))]
1227 [(set_attr "length" "5")
1228 (set_attr "timings" "33")]
1231 ;; (set (reg A) (const_int 1))
1232 ;; (set (reg A) (ashift (reg A) (reg B)))
1233 ;; (set (reg C) (xor (reg A) (reg C)))
1235 [(set:SI (match_operand:SI 0 "register_operand" "")
1237 (set:SI (match_dup 0)
1238 (ashift:SI (match_dup 0)
1239 (match_operand:SI 1 "register_operand" "")))
1240 (set:SI (match_operand:SI 2 "register_operand" "")
1241 (xor:SI (match_dup 0)
1243 "dead_or_set_p (insn, operands[0])"
1244 [(set:SI (match_dup 2)
1245 (xor:SI (match_dup 2)
1246 (ashift:SI (const_int 1)
1251 ;; (set (reg A) (const_int 1))
1252 ;; (set (reg A) (ashift (reg A) (reg B)))
1253 ;; (set (reg A) (xor (reg A) (reg C)))
1254 ;; (set (reg C) (reg A))
1256 [(set:SI (match_operand:SI 0 "register_operand" "")
1258 (set:SI (match_dup 0)
1259 (ashift:SI (match_dup 0)
1260 (match_operand:SI 1 "register_operand" "")))
1261 (set:SI (match_dup 0)
1262 (xor:SI (match_dup 0)
1263 (match_operand:SI 2 "register_operand" "")))
1264 (set:SI (match_dup 2) (match_dup 0))]
1265 "dead_or_set_p (insn, operands[0])"
1266 [(set:SI (match_dup 2)
1267 (xor:SI (match_dup 2)
1268 (ashift:SI (const_int 1)
1273 (define_insn "bitclr"
1274 [(set:SI (match_operand:SI 0 "register_operand" "+r")
1275 (and:SI (match_operand:SI 1 "register_operand" "0")
1276 (not:SI (ashift:SI (const_int 1)
1277 (match_operand:SI 2 "nonmemory_operand" "ri")))))]
1280 [(set_attr "length" "3")]
1283 (define_insn "bitclr_in_memory"
1284 [(set:QI (match_operand:QI 0 "memory_operand" "+m")
1285 (and:QI (match_operand:QI 1 "memory_operand" "0")
1286 (not:QI (ashift:QI (const_int 1)
1287 (match_operand:QI 2 "nonmemory_operand" "ri")))))]
1290 [(set_attr "length" "3")
1291 (set_attr "timings" "34")]
1294 ;; (set (reg A) (const_int -2))
1295 ;; (set (reg A) (rotate (reg A) (reg B)))
1296 ;; (set (reg C) (and (reg A) (reg C)))
1298 [(set:SI (match_operand:SI 0 "register_operand" "")
1300 (set:SI (match_dup 0)
1301 (rotate:SI (match_dup 0)
1302 (match_operand:SI 1 "register_operand" "")))
1303 (set:SI (match_operand:SI 2 "register_operand" "")
1304 (and:SI (match_dup 0)
1306 "dead_or_set_p (insn, operands[0])"
1307 [(set:SI (match_dup 2)
1308 (and:SI (match_dup 2)
1309 (not:SI (ashift:SI (const_int 1)
1313 ;; (set (reg A) (const_int -2))
1314 ;; (set (reg A) (rotate (reg A) (reg B)))
1315 ;; (set (reg A) (and (reg A) (reg C)))
1316 ;; (set (reg C) (reg A)
1318 [(set:SI (match_operand:SI 0 "register_operand" "")
1320 (set:SI (match_dup 0)
1321 (rotate:SI (match_dup 0)
1322 (match_operand:SI 1 "register_operand" "")))
1323 (set:SI (match_dup 0)
1324 (and:SI (match_dup 0)
1325 (match_operand:SI 2 "register_operand" "")))
1326 (set:SI (match_dup 2) (match_dup 0))]
1327 "dead_or_set_p (insn, operands[0])"
1328 [(set:SI (match_dup 2)
1329 (and:SI (match_dup 2)
1330 (not:SI (ashift:SI (const_int 1)
1334 (define_expand "insv"
1335 [(set:SI (zero_extract:SI (match_operand:SI 0 "nonimmediate_operand") ;; Destination
1336 (match_operand 1 "immediate_operand") ;; # of bits to set
1337 (match_operand 2 "immediate_operand")) ;; Starting bit
1338 (match_operand 3 "immediate_operand"))] ;; Bits to insert
1341 if (rx_expand_insv (operands))
1347 ;; Atomic exchange operation.
1349 (define_insn "sync_lock_test_and_setsi"
1350 [(set:SI (match_operand:SI 0 "register_operand" "=r,r")
1351 (match_operand:SI 1 "rx_compare_operand" "=r,Q"))
1352 (set:SI (match_dup 1)
1353 (match_operand:SI 2 "register_operand" "0,0"))]
1356 [(set_attr "length" "3,6")
1357 (set_attr "timings" "22")]
1360 ;; Block move functions.
1362 (define_expand "movstr"
1363 [(set:SI (match_operand:BLK 1 "memory_operand") ;; Dest
1364 (match_operand:BLK 2 "memory_operand")) ;; Source
1365 (use (match_operand:SI 0 "register_operand")) ;; Updated Dest
1369 rtx addr1 = gen_rtx_REG (SImode, 1);
1370 rtx addr2 = gen_rtx_REG (SImode, 2);
1371 rtx len = gen_rtx_REG (SImode, 3);
1372 rtx dest_copy = gen_reg_rtx (SImode);
1374 emit_move_insn (len, GEN_INT (-1));
1375 emit_move_insn (addr1, force_operand (XEXP (operands[1], 0), NULL_RTX));
1376 emit_move_insn (addr2, force_operand (XEXP (operands[2], 0), NULL_RTX));
1377 operands[1] = replace_equiv_address_nv (operands[1], addr1);
1378 operands[2] = replace_equiv_address_nv (operands[2], addr2);
1379 emit_move_insn (dest_copy, addr1);
1380 emit_insn (gen_rx_movstr ());
1381 emit_move_insn (len, GEN_INT (-1));
1382 emit_insn (gen_rx_strend (operands[0], dest_copy));
1387 (define_insn "rx_movstr"
1388 [(set:SI (mem:BLK (reg:SI 1))
1389 (mem:BLK (reg:SI 2)))
1390 (unspec_volatile:BLK [(reg:SI 1) (reg:SI 2) (reg:SI 3)] UNSPEC_MOVSTR)
1391 (clobber (reg:SI 1))
1392 (clobber (reg:SI 2))
1393 (clobber (reg:SI 3))]
1396 [(set_attr "length" "2")
1397 (set_attr "timings" "1111")] ;; The timing is a guesstimate.
1400 (define_insn "rx_strend"
1401 [(set:SI (match_operand:SI 0 "register_operand" "=r")
1402 (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "r")
1403 (reg:SI 3)] UNSPEC_STRLEN))
1404 (clobber (reg:SI 1))
1405 (clobber (reg:SI 2))
1406 (clobber (reg:SI 3))
1407 (clobber (reg:CC CC_REG))
1410 "mov\t%1, r1\n\tmov\t#0, r2\n\tsuntil.b\n\tmov\tr1, %0\n\tsub\t#1, %0"
1411 [(set_attr "length" "10")
1412 (set_attr "timings" "1111")] ;; The timing is a guesstimate.
1415 (define_expand "movmemsi"
1417 [(set (match_operand:BLK 0 "memory_operand") ;; Dest
1418 (match_operand:BLK 1 "memory_operand")) ;; Source
1419 (use (match_operand:SI 2 "register_operand")) ;; Length in bytes
1420 (match_operand 3 "immediate_operand") ;; Align
1421 (unspec_volatile:BLK [(reg:SI 1) (reg:SI 2) (reg:SI 3)] UNSPEC_MOVMEM)]
1425 rtx addr1 = gen_rtx_REG (SImode, 1);
1426 rtx addr2 = gen_rtx_REG (SImode, 2);
1427 rtx len = gen_rtx_REG (SImode, 3);
1429 if (REG_P (operands[0]) && (REGNO (operands[0]) == 2
1430 || REGNO (operands[0]) == 3))
1432 if (REG_P (operands[1]) && (REGNO (operands[1]) == 1
1433 || REGNO (operands[1]) == 3))
1435 if (REG_P (operands[2]) && (REGNO (operands[2]) == 1
1436 || REGNO (operands[2]) == 2))
1438 emit_move_insn (addr1, force_operand (XEXP (operands[0], 0), NULL_RTX));
1439 emit_move_insn (addr2, force_operand (XEXP (operands[1], 0), NULL_RTX));
1440 emit_move_insn (len, force_operand (operands[2], NULL_RTX));
1441 operands[0] = replace_equiv_address_nv (operands[0], addr1);
1442 operands[1] = replace_equiv_address_nv (operands[1], addr2);
1443 emit_insn (gen_rx_movmem ());
1448 (define_insn "rx_movmem"
1449 [(set (mem:BLK (reg:SI 1))
1450 (mem:BLK (reg:SI 2)))
1452 (unspec_volatile:BLK [(reg:SI 1) (reg:SI 2) (reg:SI 3)] UNSPEC_MOVMEM)
1453 (clobber (reg:SI 1))
1454 (clobber (reg:SI 2))
1455 (clobber (reg:SI 3))]
1458 [(set_attr "length" "2")
1459 (set_attr "timings" "1111")] ;; The timing is a guesstimate.
1462 (define_expand "setmemsi"
1463 [(set (match_operand:BLK 0 "memory_operand") ;; Dest
1464 (match_operand:QI 2 "nonmemory_operand")) ;; Value
1465 (use (match_operand:SI 1 "nonmemory_operand")) ;; Length
1466 (match_operand 3 "immediate_operand") ;; Align
1467 (unspec_volatile:BLK [(reg:SI 1) (reg:SI 2) (reg:SI 3)] UNSPEC_SETMEM)]
1470 rtx addr = gen_rtx_REG (SImode, 1);
1471 rtx val = gen_rtx_REG (QImode, 2);
1472 rtx len = gen_rtx_REG (SImode, 3);
1474 emit_move_insn (addr, force_operand (XEXP (operands[0], 0), NULL_RTX));
1475 emit_move_insn (len, force_operand (operands[1], NULL_RTX));
1476 emit_move_insn (val, operands[2]);
1477 emit_insn (gen_rx_setmem ());
1482 (define_insn "rx_setmem"
1483 [(set:BLK (mem:BLK (reg:SI 1)) (reg 2))
1484 (unspec_volatile:BLK [(reg:SI 1) (reg:SI 2) (reg:SI 3)] UNSPEC_SETMEM)
1485 (clobber (reg:SI 1))
1486 (clobber (reg:SI 3))]
1489 [(set_attr "length" "2")
1490 (set_attr "timings" "1111")] ;; The timing is a guesstimate.
1493 (define_expand "cmpstrnsi"
1494 [(set (match_operand:SI 0 "register_operand") ;; Result
1495 (unspec_volatile:SI [(match_operand:BLK 1 "memory_operand") ;; String1
1496 (match_operand:BLK 2 "memory_operand")] ;; String2
1498 (use (match_operand:SI 3 "register_operand")) ;; Max Length
1499 (match_operand:SI 4 "immediate_operand")] ;; Known Align
1502 rtx str1 = gen_rtx_REG (SImode, 1);
1503 rtx str2 = gen_rtx_REG (SImode, 2);
1504 rtx len = gen_rtx_REG (SImode, 3);
1506 emit_move_insn (str1, force_operand (XEXP (operands[1], 0), NULL_RTX));
1507 emit_move_insn (str2, force_operand (XEXP (operands[2], 0), NULL_RTX));
1508 emit_move_insn (len, force_operand (operands[3], NULL_RTX));
1510 emit_insn (gen_rx_cmpstrn (operands[0], operands[1], operands[2]));
1515 (define_expand "cmpstrsi"
1516 [(set (match_operand:SI 0 "register_operand") ;; Result
1517 (unspec_volatile:SI [(match_operand:BLK 1 "memory_operand") ;; String1
1518 (match_operand:BLK 2 "memory_operand")] ;; String2
1520 (match_operand:SI 3 "immediate_operand")] ;; Known Align
1523 rtx str1 = gen_rtx_REG (SImode, 1);
1524 rtx str2 = gen_rtx_REG (SImode, 2);
1525 rtx len = gen_rtx_REG (SImode, 3);
1527 emit_move_insn (str1, force_reg (SImode, XEXP (operands[1], 0)));
1528 emit_move_insn (str2, force_reg (SImode, XEXP (operands[2], 0)));
1529 emit_move_insn (len, GEN_INT (-1));
1531 emit_insn (gen_rx_cmpstrn (operands[0], operands[1], operands[2]));
1536 (define_insn "rx_cmpstrn"
1537 [(set:SI (match_operand:SI 0 "register_operand" "=r")
1538 (unspec_volatile:SI [(reg:SI 1) (reg:SI 2) (reg:SI 3)]
1540 (use (match_operand:BLK 1 "memory_operand" "m"))
1541 (use (match_operand:BLK 2 "memory_operand" "m"))
1542 (clobber (reg:SI 1))
1543 (clobber (reg:SI 2))
1544 (clobber (reg:SI 3))
1545 (clobber (reg:CC CC_REG))]
1547 "scmpu ; Perform the string comparison
1548 mov #-1, %0 ; Set up -1 result (which cannot be created
1550 bnc ?+ ; If Carry is not set skip over
1551 scne.L %0 ; Set result based on Z flag
1554 [(set_attr "length" "9")
1555 (set_attr "timings" "1111")] ;; The timing is a guesstimate.
1558 ;; Builtin Functions
1560 ;; GCC does not have the ability to generate the following instructions
1561 ;; on its own so they are provided as builtins instead. To use them from
1562 ;; a program for example invoke them as __builtin_rx_<insn_name>. For
1565 ;; int short_byte_swap (int arg) { return __builtin_rx_revw (arg); }
1567 ;;---------- Accumulator Support ------------------------
1569 ;; Multiply & Accumulate (high)
1570 (define_insn "machi"
1571 [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
1572 (match_operand:SI 1 "register_operand" "r")]
1573 UNSPEC_BUILTIN_MACHI)]
1576 [(set_attr "length" "3")]
1579 ;; Multiply & Accumulate (low)
1580 (define_insn "maclo"
1581 [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
1582 (match_operand:SI 1 "register_operand" "r")]
1583 UNSPEC_BUILTIN_MACLO)]
1586 [(set_attr "length" "3")]
1590 (define_insn "mulhi"
1591 [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
1592 (match_operand:SI 1 "register_operand" "r")]
1593 UNSPEC_BUILTIN_MULHI)]
1596 [(set_attr "length" "3")]
1600 (define_insn "mullo"
1601 [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
1602 (match_operand:SI 1 "register_operand" "r")]
1603 UNSPEC_BUILTIN_MULLO)]
1606 [(set_attr "length" "3")]
1609 ;; Move from Accumulator (high)
1610 (define_insn "mvfachi"
1611 [(set (match_operand:SI 0 "register_operand" "=r")
1612 (unspec:SI [(const_int 0)]
1613 UNSPEC_BUILTIN_MVFACHI))]
1616 [(set_attr "length" "3")]
1619 ;; Move from Accumulator (middle)
1620 (define_insn "mvfacmi"
1621 [(set (match_operand:SI 0 "register_operand" "=r")
1622 (unspec:SI [(const_int 0)]
1623 UNSPEC_BUILTIN_MVFACMI))]
1626 [(set_attr "length" "3")]
1629 ;; Move to Accumulator (high)
1630 (define_insn "mvtachi"
1631 [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")]
1632 UNSPEC_BUILTIN_MVTACHI)]
1635 [(set_attr "length" "3")]
1638 ;; Move to Accumulator (low)
1639 (define_insn "mvtaclo"
1640 [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")]
1641 UNSPEC_BUILTIN_MVTACLO)]
1644 [(set_attr "length" "3")]
1647 ;; Round Accumulator
1649 [(unspec_volatile:SI [(match_operand:SI 0 "immediate_operand" "i")]
1650 UNSPEC_BUILTIN_RACW)]
1653 [(set_attr "length" "3")]
1656 ;; Repeat multiply and accumulate
1658 [(unspec:SI [(const_int 0) (reg:SI 1) (reg:SI 2) (reg:SI 3)
1659 (reg:SI 4) (reg:SI 5) (reg:SI 6)]
1660 UNSPEC_BUILTIN_RMPA)
1661 (clobber (reg:SI 1))
1662 (clobber (reg:SI 2))
1663 (clobber (reg:SI 3))]
1666 [(set_attr "length" "2")
1667 (set_attr "timings" "1010")]
1670 ;;---------- Arithmetic ------------------------
1672 ;; Byte swap (two 16-bit values).
1674 [(set (match_operand:SI 0 "register_operand" "+r")
1675 (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
1676 UNSPEC_BUILTIN_REVW))]
1679 [(set_attr "length" "3")]
1682 ;; Round to integer.
1683 (define_insn "lrintsf2"
1684 [(set (match_operand:SI 0 "register_operand" "=r,r")
1685 (unspec:SI [(match_operand:SF 1 "rx_compare_operand" "r,Q")]
1686 UNSPEC_BUILTIN_ROUND))
1687 (clobber (reg:CC CC_REG))]
1690 [(set_attr "timings" "22,44")
1691 (set_attr "length" "3,5")]
1694 ;; Saturate to 32-bits
1696 [(set (match_operand:SI 0 "register_operand" "=r")
1697 (unspec:SI [(match_operand:SI 1 "register_operand" "0")]
1698 UNSPEC_BUILTIN_SAT))]
1701 [(set_attr "length" "2")]
1704 ;;---------- Control Registers ------------------------
1706 ;; Clear Processor Status Word
1707 (define_insn "clrpsw"
1708 [(unspec:SI [(match_operand:SI 0 "immediate_operand" "i")]
1709 UNSPEC_BUILTIN_CLRPSW)
1710 (clobber (reg:CC CC_REG))]
1713 [(set_attr "length" "2")]
1716 ;; Set Processor Status Word
1717 (define_insn "setpsw"
1718 [(unspec:SI [(match_operand:SI 0 "immediate_operand" "i")]
1719 UNSPEC_BUILTIN_SETPSW)
1720 (clobber (reg:CC CC_REG))]
1723 [(set_attr "length" "2")]
1726 ;; Move from control register
1728 [(set (match_operand:SI 0 "register_operand" "=r")
1729 (unspec:SI [(match_operand:SI 1 "immediate_operand" "i")]
1730 UNSPEC_BUILTIN_MVFC))]
1733 [(set_attr "length" "3")]
1736 ;; Move to control register
1738 [(unspec:SI [(match_operand:SI 0 "immediate_operand" "i,i")
1739 (match_operand:SI 1 "nonmemory_operand" "r,i")]
1740 UNSPEC_BUILTIN_MVTC)]
1743 [(set_attr "length" "3,7")]
1744 ;; Ignore possible clobbering of the comparison flags in the
1745 ;; PSW register. This is a cc0 target so any cc0 setting
1746 ;; instruction will always be paired with a cc0 user, without
1747 ;; the possibility of this instruction being placed in between
1751 ;; Move to interrupt priority level
1752 (define_insn "mvtipl"
1753 [(unspec:SI [(match_operand:SI 0 "immediate_operand" "Uint04")]
1754 UNSPEC_BUILTIN_MVTIPL)]
1757 [(set_attr "length" "3")]
1760 ;;---------- Interrupts ------------------------
1764 [(unspec_volatile [(const_int 0)]
1765 UNSPEC_BUILTIN_BRK)]
1768 [(set_attr "length" "1")
1769 (set_attr "timings" "66")]
1774 [(unspec_volatile:SI [(match_operand:SI 0 "immediate_operand" "i")]
1775 UNSPEC_BUILTIN_INT)]
1778 [(set_attr "length" "3")]
1783 [(unspec_volatile [(const_int 0)]
1784 UNSPEC_BUILTIN_WAIT)]
1787 [(set_attr "length" "2")]
1790 ;;---------- CoProcessor Support ------------------------
1792 ;; FIXME: The instructions are currently commented out because
1793 ;; the bit patterns have not been finalized, so the assembler
1794 ;; does not support them. Once they are decided and the assembler
1795 ;; supports them, enable the instructions here.
1797 ;; Move from co-processor register
1798 (define_insn "mvfcp"
1799 [(set (match_operand:SI 0 "register_operand" "=r")
1800 (unspec:SI [(match_operand:SI 1 "immediate_operand" "i")
1801 (match_operand:SI 2 "immediate_operand" "i")]
1802 UNSPEC_BUILTIN_MVFCP))]
1804 "; mvfcp\t%1, %0, %2"
1805 [(set_attr "length" "5")]
1808 ;;---------- Misc ------------------------
1810 ;; Required by cfglayout.c...
1815 [(set_attr "length" "1")]