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")
64 (UNSPEC_BUILTIN_BRK 30)
65 (UNSPEC_BUILTIN_CLRPSW 31)
66 (UNSPEC_BUILTIN_INT 32)
67 (UNSPEC_BUILTIN_MACHI 33)
68 (UNSPEC_BUILTIN_MACLO 34)
69 (UNSPEC_BUILTIN_MULHI 35)
70 (UNSPEC_BUILTIN_MULLO 36)
71 (UNSPEC_BUILTIN_MVFACHI 37)
72 (UNSPEC_BUILTIN_MVFACMI 38)
73 (UNSPEC_BUILTIN_MVFC 39)
74 (UNSPEC_BUILTIN_MVFCP 40)
75 (UNSPEC_BUILTIN_MVTACHI 41)
76 (UNSPEC_BUILTIN_MVTACLO 42)
77 (UNSPEC_BUILTIN_MVTC 43)
78 (UNSPEC_BUILTIN_MVTIPL 44)
79 (UNSPEC_BUILTIN_RACW 45)
80 (UNSPEC_BUILTIN_REVW 46)
81 (UNSPEC_BUILTIN_RMPA 47)
82 (UNSPEC_BUILTIN_ROUND 48)
83 (UNSPEC_BUILTIN_SAT 49)
84 (UNSPEC_BUILTIN_SETPSW 50)
85 (UNSPEC_BUILTIN_WAIT 51)
89 ;; Condition code settings:
90 ;; none - insn does not affect the condition code bits
91 ;; set_zs - insn sets z,s to usable values;
92 ;; set_zso - insn sets z,s,o to usable values;
93 ;; set_zsoc - insn sets z,s,o,c to usable values;
94 ;; clobber - value of cc0 is unknown
95 (define_attr "cc" "none,set_zs,set_zso,set_zsoc,clobber" (const_string "none"))
97 (define_attr "length" "" (const_int 8))
99 (include "predicates.md")
100 (include "constraints.md")
102 ;; Pipeline description.
104 ;; The RX only has a single pipeline. It has five stages (fetch,
105 ;; decode, execute, memory access, writeback) each of which normally
106 ;; takes a single CPU clock cycle.
108 ;; The timings attribute consists of two numbers, the first is the
109 ;; throughput, which is the number of cycles the instruction takes
110 ;; to execute and generate a result. The second is the latency
111 ;; which is the effective number of cycles the instruction takes to
112 ;; execute if its result is used by the following instruction. The
113 ;; latency is always greater than or equal to the throughput.
114 ;; These values were taken from tables 2.13 and 2.14 in section 2.8
115 ;; of the RX610 Group Hardware Manual v0.11
117 ;; Note - it would be nice to use strings rather than integers for
118 ;; the possible values of this attribute, so that we can have the
119 ;; gcc build mechanism check for values that are not supported by
120 ;; the reservations below. But this will not work because the code
121 ;; in rx_adjust_sched_cost() needs integers not strings.
123 (define_attr "timings" "" (const_int 11))
125 (define_automaton "pipelining")
126 (define_cpu_unit "throughput" "pipelining")
128 (define_insn_reservation "throughput__1_latency__1" 1
129 (eq_attr "timings" "11") "throughput")
130 (define_insn_reservation "throughput__1_latency__2" 2
131 (eq_attr "timings" "12") "throughput,nothing")
132 (define_insn_reservation "throughput__2_latency__2" 1
133 (eq_attr "timings" "22") "throughput*2")
134 (define_insn_reservation "throughput__3_latency__3" 1
135 (eq_attr "timings" "33") "throughput*3")
136 (define_insn_reservation "throughput__3_latency__4" 2
137 (eq_attr "timings" "34") "throughput*3,nothing")
138 (define_insn_reservation "throughput__4_latency__4" 1
139 (eq_attr "timings" "44") "throughput*4")
140 (define_insn_reservation "throughput__4_latency__5" 2
141 (eq_attr "timings" "45") "throughput*4,nothing")
142 (define_insn_reservation "throughput__5_latency__5" 1
143 (eq_attr "timings" "55") "throughput*5")
144 (define_insn_reservation "throughput__5_latency__6" 2
145 (eq_attr "timings" "56") "throughput*5,nothing")
146 (define_insn_reservation "throughput__6_latency__6" 1
147 (eq_attr "timings" "66") "throughput*6")
148 (define_insn_reservation "throughput_10_latency_10" 1
149 (eq_attr "timings" "1010") "throughput*10")
150 (define_insn_reservation "throughput_11_latency_11" 1
151 (eq_attr "timings" "1111") "throughput*11")
152 (define_insn_reservation "throughput_16_latency_16" 1
153 (eq_attr "timings" "1616") "throughput*16")
154 (define_insn_reservation "throughput_18_latency_18" 1
155 (eq_attr "timings" "1818") "throughput*18")
159 (define_expand "cbranchsi4"
160 [(set (cc0) (compare:CC (match_operand:SI 1 "register_operand")
161 (match_operand:SI 2 "rx_source_operand")))
163 (if_then_else (match_operator:SI 0 "comparison_operator"
164 [(cc0) (const_int 0)])
165 (label_ref (match_operand 3 ""))
171 (define_expand "cbranchsf4"
172 [(set (cc0) (compare:CC (match_operand:SF 1 "register_operand")
173 (match_operand:SF 2 "rx_source_operand")))
175 (if_then_else (match_operator:SI 0 "comparison_operator"
176 [(cc0) (const_int 0)])
177 (label_ref (match_operand 3 ""))
179 "ALLOW_RX_FPU_INSNS && ! flag_non_call_exceptions"
183 ;; The TST instruction is not used as it does not set the Carry flag,
184 ;; so for example, the LessThan comparison cannot be tested.
186 ;; (define_insn "tstsi"
188 ;; (match_operand:SI 0 "rx_source_operand" "r,i,Q")))]
191 ;; rx_float_compare_mode = false;
192 ;; return "tst\t%Q0";
194 ;; [(set_attr "cc" "set_zs")
195 ;; (set_attr "timings" "11,11,33")
196 ;; (set_attr "length" "3,7,6")]
200 [(set (cc0) (compare:CC
201 (match_operand:SI 0 "register_operand" "r,r,r,r,r,r,r")
202 (match_operand:SI 1 "rx_source_operand"
203 "r,Uint04,Int08,Sint16,Sint24,i,Q")))]
206 rx_float_compare_mode = false;
207 return "cmp\t%Q1, %Q0";
209 [(set_attr "cc" "set_zsoc")
210 (set_attr "timings" "11,11,11,11,11,11,33")
211 (set_attr "length" "2,2,3,4,5,6,5")]
214 ;; This pattern is disabled when -fnon-call-exceptions is active because
215 ;; it could generate a floating point exception, which would introduce an
216 ;; edge into the flow graph between this insn and the conditional branch
217 ;; insn to follow, thus breaking the cc0 relationship. Run the g++ test
218 ;; g++.dg/eh/080514-1.C to see this happen.
221 (compare:CC (match_operand:SF 0 "register_operand" "r,r,r")
222 (match_operand:SF 1 "rx_source_operand" "r,i,Q")))]
223 "ALLOW_RX_FPU_INSNS && ! flag_non_call_exceptions"
225 rx_float_compare_mode = true;
226 return "fcmp\t%1, %0";
228 [(set_attr "cc" "set_zso")
229 (set_attr "timings" "11,11,33")
230 (set_attr "length" "3,7,5")]
233 ;; Flow Control Instructions:
235 (define_expand "b<code>"
237 (if_then_else (most_cond (cc0) (const_int 0))
238 (label_ref (match_operand 0))
244 (define_insn "*conditional_branch"
246 (if_then_else (match_operator 1 "comparison_operator"
247 [(cc0) (const_int 0)])
248 (label_ref (match_operand 0 "" ""))
252 return rx_gen_cond_branch_template (operands[1], false);
254 [(set_attr "length" "8") ;; This length is wrong, but it is
255 ;; too hard to compute statically.
256 (set_attr "timings" "33") ;; The timing assumes that the branch is taken.
257 (set_attr "cc" "clobber")] ;; FIXME: This clobber is wrong.
260 (define_insn "*reveresed_conditional_branch"
262 (if_then_else (match_operator 1 "comparison_operator"
263 [(cc0) (const_int 0)])
265 (label_ref (match_operand 0 "" ""))))]
268 return rx_gen_cond_branch_template (operands[1], true);
270 [(set_attr "length" "8") ;; This length is wrong, but it is
271 ;; too hard to compute statically.
272 (set_attr "timings" "33") ;; The timing assumes that the branch is taken.
273 (set_attr "cc" "clobber")] ;; FIXME: This clobber is wrong.
277 [(set (pc) (label_ref (match_operand 0 "" "")))]
280 [(set_attr "length" "4")
281 (set_attr "timings" "33")
282 (set_attr "cc" "clobber")] ;; FIXME: This clobber is wrong.
285 (define_insn "indirect_jump"
286 [(set (pc) (match_operand:SI 0 "register_operand" "r"))]
289 [(set_attr "length" "2")
290 (set_attr "timings" "33")
291 (set_attr "cc" "clobber")] ;; FIXME: This clobber is wrong.
294 (define_insn "tablejump"
295 [(set (pc) (match_operand:SI 0 "register_operand" "r"))
296 (use (label_ref (match_operand 1 "" "")))]
298 { return flag_pic ? (TARGET_AS100_SYNTAX ? "\n?:\tbra\t%0"
302 [(set_attr "cc" "clobber") ;; FIXME: This clobber is wrong.
303 (set_attr "timings" "33")
304 (set_attr "length" "2")]
307 (define_insn "simple_return"
311 [(set_attr "length" "1")
312 (set_attr "timings" "55")]
315 (define_insn "deallocate_and_return"
316 [(set (reg:SI SP_REG)
317 (plus:SI (reg:SI SP_REG)
318 (match_operand:SI 0 "immediate_operand" "i")))
322 [(set_attr "length" "2")
323 (set_attr "timings" "55")]
326 (define_insn "pop_and_return"
327 [(match_parallel 1 "rx_rtsd_vector"
328 [(set:SI (reg:SI SP_REG)
329 (plus:SI (reg:SI SP_REG)
331 0 "const_int_operand" "n")))])]
334 rx_emit_stack_popm (operands, false);
337 [(set_attr "length" "3")
338 (set_attr "timings" "56")]
341 (define_insn "fast_interrupt_return"
342 [(unspec_volatile [(return)] UNSPEC_RTFI) ]
345 [(set_attr "length" "2")
346 (set_attr "timings" "33")]
349 (define_insn "exception_return"
350 [(unspec_volatile [(return)] UNSPEC_RTE) ]
353 [(set_attr "length" "2")
354 (set_attr "timings" "66")]
357 (define_insn "naked_return"
358 [(unspec_volatile [(return)] UNSPEC_NAKED) ]
360 "; Naked function: epilogue provided by programmer."
364 ;; Note - the following set of patterns do not use the "memory_operand"
365 ;; predicate or an "m" constraint because we do not allow symbol_refs
366 ;; or label_refs as legitmate memory addresses. This matches the
367 ;; behaviour of most of the RX instructions. Only the call/branch
368 ;; instructions are allowed to refer to symbols/labels directly.
369 ;; The call operands are in QImode because that is the value of
372 (define_expand "call"
373 [(call (match_operand:QI 0 "general_operand")
374 (match_operand:SI 1 "general_operand"))]
377 rtx dest = XEXP (operands[0], 0);
379 if (! rx_call_operand (dest, Pmode))
380 dest = force_reg (Pmode, dest);
381 emit_call_insn (gen_call_internal (dest, operands[1]));
386 (define_insn "call_internal"
387 [(call (mem:QI (match_operand:SI 0 "rx_call_operand" "r,Symbol"))
388 (match_operand:SI 1 "general_operand" "g,g"))]
393 [(set_attr "length" "2,4")
394 (set_attr "timings" "33")]
397 (define_expand "call_value"
398 [(set (match_operand 0 "register_operand")
399 (call (match_operand:QI 1 "general_operand")
400 (match_operand:SI 2 "general_operand")))]
403 rtx dest = XEXP (operands[1], 0);
405 if (! rx_call_operand (dest, Pmode))
406 dest = force_reg (Pmode, dest);
407 emit_call_insn (gen_call_value_internal (operands[0], dest, operands[2]));
412 (define_insn "call_value_internal"
413 [(set (match_operand 0 "register_operand" "=r,r")
414 (call (mem:QI (match_operand:SI 1 "rx_call_operand" "r,Symbol"))
415 (match_operand:SI 2 "general_operand" "g,g")))]
420 [(set_attr "length" "2,4")
421 (set_attr "timings" "33")]
424 ;; Note - we do not allow indirect sibcalls (with the address
425 ;; held in a register) because we cannot guarantee that the register
426 ;; chosen will be a call-used one. If it is a call-saved register,
427 ;; then the epilogue code will corrupt it by popping the saved value
429 (define_expand "sibcall"
431 [(call (mem:QI (match_operand:SI 0 "rx_symbolic_call_operand"))
432 (match_operand:SI 1 "general_operand"))
436 if (MEM_P (operands[0]))
437 operands[0] = XEXP (operands[0], 0);
441 (define_insn "sibcall_internal"
442 [(call (mem:QI (match_operand:SI 0 "rx_symbolic_call_operand" "Symbol"))
443 (match_operand:SI 1 "general_operand" "g"))
447 [(set_attr "length" "4")
448 (set_attr "timings" "33")]
451 (define_expand "sibcall_value"
453 [(set (match_operand 0 "register_operand")
454 (call (mem:QI (match_operand:SI 1 "rx_symbolic_call_operand"))
455 (match_operand:SI 2 "general_operand")))
459 if (MEM_P (operands[1]))
460 operands[1] = XEXP (operands[1], 0);
464 (define_insn "sibcall_value_internal"
465 [(set (match_operand 0 "register_operand" "=r")
466 (call (mem:QI (match_operand:SI 1 "rx_symbolic_call_operand" "Symbol"))
467 (match_operand:SI 2 "general_operand" "g")))
471 [(set_attr "length" "4")
472 (set_attr "timings" "33")]
475 ;; Function Prologue/Epilogue Instructions
477 (define_expand "prologue"
480 "rx_expand_prologue (); DONE;"
483 (define_expand "epilogue"
486 "rx_expand_epilogue (false); DONE;"
489 (define_expand "sibcall_epilogue"
492 "rx_expand_epilogue (true); DONE;"
497 ;; Note - we do not allow memory to memory moves, even though the ISA
498 ;; supports them. The reason is that the conditions on such moves are
499 ;; too restrictive, specifically the source addressing mode is limited
500 ;; by the destination addressing mode and vice versa. (For example it
501 ;; is not possible to use indexed register indirect addressing for one
502 ;; of the operands if the other operand is anything other than a register,
503 ;; but it is possible to use register relative addressing when the other
504 ;; operand also uses register relative or register indirect addressing).
506 ;; GCC does not support computing legitimate addresses based on the
507 ;; nature of other operands involved in the instruction, and reload is
508 ;; not smart enough to cope with a whole variety of different memory
509 ;; addressing constraints, so it is simpler and safer to just refuse
510 ;; to support memory to memory moves.
512 (define_expand "mov<register_modes:mode>"
513 [(set (match_operand:register_modes 0 "general_operand")
514 (match_operand:register_modes 1 "general_operand"))]
517 if (MEM_P (operand0) && MEM_P (operand1))
518 operands[1] = copy_to_mode_reg (<register_modes:MODE>mode, operand1);
522 (define_insn "*mov<register_modes:mode>_internal"
523 [(set (match_operand:register_modes
524 0 "nonimmediate_operand" "=r,r,r,r,r,r,m,Q,Q,Q,Q")
525 (match_operand:register_modes
526 1 "general_operand" "Int08,Sint16,Sint24,i,r,m,r,Int08,Sint16,Sint24,i"))]
528 { return rx_gen_move_template (operands, false); }
529 [(set_attr "length" "3,4,5,6,2,4,6,5,6,7,8")
530 (set_attr "timings" "11,11,11,11,11,12,11,11,11,11,11")]
533 (define_insn "extend<small_int_modes:mode>si2"
534 [(set (match_operand:SI 0 "register_operand" "=r,r")
535 (sign_extend:SI (match_operand:small_int_modes
536 1 "nonimmediate_operand" "r,m")))]
538 { return rx_gen_move_template (operands, false); }
539 [(set_attr "length" "2,6")
540 (set_attr "timings" "11,12")]
543 (define_insn "zero_extend<small_int_modes:mode>si2"
544 [(set (match_operand:SI 0 "register_operand" "=r,r")
545 (zero_extend:SI (match_operand:small_int_modes
546 1 "nonimmediate_operand" "r,m")))]
548 { return rx_gen_move_template (operands, true); }
549 [(set_attr "length" "2,4")
550 (set_attr "timings" "11,12")]
553 (define_insn "stack_push"
554 [(set:SI (reg:SI SP_REG)
555 (minus:SI (reg:SI SP_REG)
557 (set:SI (mem:SI (reg:SI SP_REG))
558 (match_operand:SI 0 "register_operand" "r"))]
561 [(set_attr "length" "2")]
564 (define_insn "stack_pushm"
565 [(match_parallel 1 "rx_store_multiple_vector"
566 [(set:SI (reg:SI SP_REG)
567 (minus:SI (reg:SI SP_REG)
569 0 "const_int_operand" "n")))])]
572 rx_emit_stack_pushm (operands);
575 [(set_attr "length" "2")
576 (set_attr "timings" "44")] ;; The timing is a guesstimate average timing.
579 (define_insn "stack_pop"
580 [(set:SI (match_operand:SI 0 "register_operand" "=r")
581 (mem:SI (reg:SI SP_REG)))
582 (set:SI (reg:SI SP_REG)
583 (plus:SI (reg:SI SP_REG)
587 [(set_attr "length" "2")
588 (set_attr "timings" "12")]
591 (define_insn "stack_popm"
592 [(match_parallel 1 "rx_load_multiple_vector"
593 [(set:SI (reg:SI SP_REG)
594 (plus:SI (reg:SI SP_REG)
596 0 "const_int_operand" "n")))])]
599 rx_emit_stack_popm (operands, true);
602 [(set_attr "length" "2")
603 (set_attr "timings" "45")] ;; The timing is a guesstimate average timing.
606 (define_insn "cstoresi4"
607 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,r")
609 1 "comparison_operator"
611 2 "register_operand" "r,r,r,r,r,r,r")
613 3 "rx_source_operand" "r,Uint04,Int08,Sint16,Sint24,i,Q")]))]
616 rx_float_compare_mode = false;
617 return "cmp\t%Q3, %Q2\n\tsc%B1.L\t%0";
619 [(set_attr "cc" "set_zsoc")
620 (set_attr "timings" "22,22,22,22,22,22,44")
621 (set_attr "length" "5,5,6,7,8,9,8")]
624 (define_expand "movsicc"
625 [(set (match_operand:SI 0 "register_operand")
626 (if_then_else:SI (match_operand:SI 1 "comparison_operator")
627 (match_operand:SI 2 "nonmemory_operand")
628 (match_operand:SI 3 "immediate_operand")))]
631 if (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE)
633 if (! CONST_INT_P (operands[3]))
638 (define_insn "*movsieq"
639 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
640 (if_then_else:SI (eq (match_operand:SI
641 3 "register_operand" "r,r,r")
643 4 "rx_source_operand" "riQ,riQ,riQ"))
645 1 "nonmemory_operand" "0,i,r")
647 2 "immediate_operand" "i,i,i")))]
650 cmp\t%Q4, %Q3\n\tstnz\t%2, %0
651 cmp\t%Q4, %Q3\n\tmov.l\t%2, %0\n\tstz\t%1, %0
652 cmp\t%Q4, %Q3\n\tmov.l\t%1, %0\n\tstnz\t%2, %0"
653 [(set_attr "cc" "set_zsoc")
654 (set_attr "length" "13,19,15")
655 (set_attr "timings" "22,33,33")]
658 (define_insn "*movsine"
659 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
660 (if_then_else:SI (ne (match_operand:SI 3 "register_operand" "r,r,r")
661 (match_operand:SI 4 "rx_source_operand" "riQ,riQ,riQ"))
662 (match_operand:SI 1 "nonmemory_operand" "0,i,r")
663 (match_operand:SI 2 "immediate_operand" "i,i,i")))]
666 cmp\t%Q4, %Q3\n\tstz\t%2, %0
667 cmp\t%Q4, %Q3\n\tmov.l\t%2, %0\n\tstnz\t%1, %0
668 cmp\t%Q4, %Q3\n\tmov.l\t%1, %0\n\tstz\t%2, %0"
669 [(set_attr "cc" "set_zsoc")
670 (set_attr "length" "13,19,15")
671 (set_attr "timings" "22,33,33")]
674 ;; Arithmetic Instructions
676 (define_insn "abssi2"
677 [(set (match_operand:SI 0 "register_operand" "=r,r")
678 (abs:SI (match_operand:SI 1 "register_operand" "0,r")))]
683 [(set_attr "cc" "set_zso")
684 (set_attr "length" "2,3")]
687 (define_insn "addsi3"
688 [(set (match_operand:SI 0 "register_operand"
689 "=r,r,r,r,r,r,r,r,r,r,r,r")
690 (plus:SI (match_operand:SI
692 "%0,0,0,0,0,0,r,r,r,r,r,0")
694 2 "rx_source_operand"
695 "r,Uint04,Sint08,Sint16,Sint24,i,r,Sint08,Sint16,Sint24,i,Q")))]
710 [(set_attr "cc" "set_zsoc")
711 (set_attr "timings" "11,11,11,11,11,11,11,11,11,11,11,33")
712 (set_attr "length" "2,2,3,4,5,6,3,3,4,5,6,5")]
715 (define_insn "adddi3"
716 [(set (match_operand:DI 0 "register_operand" "=r,r,r,r,r,r")
717 (plus:DI (match_operand:DI 1 "register_operand" "%0,0,0,0,0,0")
718 (match_operand:DI 2 "rx_source_operand"
719 "r,Sint08,Sint16,Sint24,i,Q")))]
721 "add\t%L2, %L0\n\tadc\t%H2, %H0"
722 [(set_attr "cc" "set_zsoc")
723 (set_attr "timings" "22,22,22,22,22,44")
724 (set_attr "length" "5,7,9,11,13,11")]
727 (define_insn "andsi3"
728 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,r,r,r")
729 (and:SI (match_operand:SI 1 "register_operand" "%0,0,0,0,0,0,r,0,Q")
731 2 "rx_source_operand"
732 "r,Uint04,Sint08,Sint16,Sint24,i,r,Q,0")))]
744 [(set_attr "cc" "set_zs")
745 (set_attr "timings" "11,11,11,11,11,11,11,33,33")
746 (set_attr "length" "2,2,3,4,5,6,3,5,5")]
749 ;; Byte swap (single 32-bit value).
750 (define_insn "bswapsi2"
751 [(set (match_operand:SI 0 "register_operand" "+r")
752 (bswap:SI (match_operand:SI 1 "register_operand" "r")))]
755 [(set_attr "length" "3")]
758 ;; Byte swap (single 16-bit value). Note - we ignore the swapping of the high 16-bits.
759 (define_insn "bswaphi2"
760 [(set (match_operand:HI 0 "register_operand" "+r")
761 (bswap:HI (match_operand:HI 1 "register_operand" "r")))]
764 [(set_attr "length" "3")]
767 (define_insn "divsi3"
768 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r")
769 (div:SI (match_operand:SI 1 "register_operand" "0,0,0,0,0,0")
771 2 "rx_source_operand" "r,Sint08,Sint16,Sint24,i,Q")))]
774 [(set_attr "cc" "clobber")
775 (set_attr "timings" "1111") ;; Strictly speaking the timing should be
776 ;; 2222, but that is a worst case sceanario.
777 (set_attr "length" "3,4,5,6,7,6")]
780 (define_insn "udivsi3"
781 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r")
782 (udiv:SI (match_operand:SI 1 "register_operand" "0,0,0,0,0,0")
784 2 "rx_source_operand" "r,Sint08,Sint16,Sint24,i,Q")))]
787 [(set_attr "cc" "clobber")
788 (set_attr "timings" "1010") ;; Strictly speaking the timing should be
789 ;; 2020, but that is a worst case sceanario.
790 (set_attr "length" "3,4,5,6,7,6")]
793 ;; Note - these patterns are suppressed in big-endian mode because they
794 ;; generate a little endian result. ie the most significant word of the
795 ;; result is placed in the higher numbered register of the destination
798 (define_insn "mulsidi3"
799 [(set (match_operand:DI 0 "register_operand" "=r,r,r,r,r,r")
800 (mult:DI (sign_extend:DI (match_operand:SI
801 1 "register_operand" "%0,0,0,0,0,0"))
802 (sign_extend:DI (match_operand:SI
803 2 "rx_source_operand"
804 "r,Sint08,Sint16,Sint24,i,Q"))))]
805 "! TARGET_BIG_ENDIAN_DATA"
813 [(set_attr "length" "3,4,5,6,7,6")
814 (set_attr "timings" "22,22,22,22,22,44")]
817 ;; See comment for mulsidi3.
818 ;; Note - the zero_extends are to distinguish this pattern from the
819 ;; mulsidi3 pattern. Immediate mode addressing is not supported
820 ;; because gcc cannot handle the expression: (zero_extend (const_int)).
821 (define_insn "umulsidi3"
822 [(set (match_operand:DI 0 "register_operand"
824 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand"
826 (zero_extend:DI (match_operand:SI 2 "rx_compare_operand"
828 "! TARGET_BIG_ENDIAN_DATA"
832 [(set_attr "length" "3,6")
833 (set_attr "timings" "22,44")]
836 (define_insn "smaxsi3"
837 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r")
838 (smax:SI (match_operand:SI 1 "register_operand" "%0,0,0,0,0,0")
839 (match_operand:SI 2 "rx_source_operand"
840 "r,Sint08,Sint16,Sint24,i,Q")))]
843 [(set_attr "length" "3,4,5,6,7,6")
844 (set_attr "timings" "11,11,11,11,11,33")]
847 (define_insn "sminsi3"
848 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r")
849 (smin:SI (match_operand:SI 1 "register_operand" "%0,0,0,0,0,0")
850 (match_operand:SI 2 "rx_source_operand"
851 "r,Sint08,Sint16,Sint24,i,Q")))]
860 [(set_attr "length" "3,4,5,6,7,6")
861 (set_attr "timings" "11,11,11,11,11,33")]
864 (define_insn "mulsi3"
865 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,r,r,r")
866 (mult:SI (match_operand:SI 1 "register_operand" "%0,0,0,0,0,0,0,Q,r")
867 (match_operand:SI 2 "rx_source_operand"
868 "r,Uint04,Sint08,Sint16,Sint24,i,Q,0,r")))]
880 [(set_attr "length" "2,2,3,4,5,6,5,5,3")
881 (set_attr "timings" "11,11,11,11,11,11,33,33,11")]
884 (define_insn "negsi2"
885 [(set (match_operand:SI 0 "register_operand" "=r,r")
886 (neg:SI (match_operand:SI 1 "register_operand" "0,r")))]
887 ;; The NEG instruction does not comply with -fwrapv semantics.
888 ;; See gcc.c-torture/execute/pr22493-1.c for an example of this.
893 [(set_attr "length" "2,3")]
896 (define_insn "one_cmplsi2"
897 [(set (match_operand:SI 0 "register_operand" "=r,r")
898 (not:SI (match_operand:SI 1 "register_operand" "0,r")))]
903 [(set_attr "cc" "set_zs")
904 (set_attr "length" "2,3")]
907 (define_insn "iorsi3"
908 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,r,r,r")
909 (ior:SI (match_operand:SI 1 "register_operand" "%0,0,0,0,0,0,r,0,Q")
910 (match_operand:SI 2 "rx_source_operand"
911 "r,Uint04,Sint08,Sint16,Sint24,i,r,Q,0")))]
923 [(set_attr "cc" "set_zs")
924 (set_attr "timings" "11,11,11,11,11,11,11,33,33")
925 (set_attr "length" "2,2,3,4,5,6,3,5,5")]
928 (define_insn "rotlsi3"
929 [(set (match_operand:SI 0 "register_operand" "=r")
930 (rotate:SI (match_operand:SI 1 "register_operand" "0")
931 (match_operand:SI 2 "rx_shift_operand" "rn")))]
934 [(set_attr "cc" "set_zs")
935 (set_attr "length" "3")]
938 (define_insn "rotrsi3"
939 [(set (match_operand:SI 0 "register_operand" "=r")
940 (rotatert:SI (match_operand:SI 1 "register_operand" "0")
941 (match_operand:SI 2 "rx_shift_operand" "rn")))]
944 [(set_attr "cc" "set_zs")
945 (set_attr "length" "3")]
948 (define_insn "ashrsi3"
949 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
950 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0,r")
951 (match_operand:SI 2 "rx_shift_operand" "r,n,n")))]
957 [(set_attr "cc" "set_zsoc")
958 (set_attr "length" "3,2,3")]
961 (define_insn "lshrsi3"
962 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
963 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0,0,r")
964 (match_operand:SI 2 "rx_shift_operand" "r,n,n")))]
970 [(set_attr "cc" "set_zsoc")
971 (set_attr "length" "3,2,3")]
974 (define_insn "ashlsi3"
975 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
976 (ashift:SI (match_operand:SI 1 "register_operand" "0,0,r")
977 (match_operand:SI 2 "rx_shift_operand" "r,n,n")))]
983 [(set_attr "cc" "set_zsoc")
984 (set_attr "length" "3,2,3")]
987 (define_insn "subsi3"
988 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r")
989 (minus:SI (match_operand:SI 1 "register_operand" "0,0,0,r,0")
990 (match_operand:SI 2 "rx_source_operand" "r,Uint04,n,r,Q")))]
998 [(set_attr "cc" "set_zsoc")
999 (set_attr "timings" "11,11,11,11,33")
1000 (set_attr "length" "2,2,6,3,5")]
1003 (define_insn "subdi3"
1004 [(set (match_operand:DI 0 "register_operand" "=r,r")
1005 (minus:DI (match_operand:DI 1 "register_operand" "0,0")
1006 (match_operand:DI 2 "rx_source_operand" "r,Q")))]
1008 "sub\t%L2, %L0\n\tsbb\t%H2, %H0"
1009 [(set_attr "cc" "set_zsoc")
1010 (set_attr "timings" "22,44")
1011 (set_attr "length" "5,11")]
1014 (define_insn "xorsi3"
1015 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r")
1016 (xor:SI (match_operand:SI 1 "register_operand" "%0,0,0,0,0,0")
1017 (match_operand:SI 2 "rx_source_operand"
1018 "r,Sint08,Sint16,Sint24,i,Q")))]
1027 [(set_attr "cc" "set_zs")
1028 (set_attr "timings" "11,11,11,11,11,33")
1029 (set_attr "length" "3,4,5,6,7,6")]
1032 ;; Floating Point Instructions
1034 (define_insn "addsf3"
1035 [(set (match_operand:SF 0 "register_operand" "=r,r,r")
1036 (plus:SF (match_operand:SF 1 "register_operand" "%0,0,0")
1037 (match_operand:SF 2 "rx_source_operand" "r,F,Q")))]
1038 "ALLOW_RX_FPU_INSNS"
1043 [(set_attr "cc" "set_zs")
1044 (set_attr "timings" "44,44,66")
1045 (set_attr "length" "3,7,5")]
1048 (define_insn "divsf3"
1049 [(set (match_operand:SF 0 "register_operand" "=r,r,r")
1050 (div:SF (match_operand:SF 1 "register_operand" "0,0,0")
1051 (match_operand:SF 2 "rx_source_operand" "r,F,Q")))]
1052 "ALLOW_RX_FPU_INSNS"
1054 [(set_attr "cc" "set_zs")
1055 (set_attr "timings" "1616,1616,1818")
1056 (set_attr "length" "3,7,5")]
1059 (define_insn "mulsf3"
1060 [(set (match_operand:SF 0 "register_operand" "=r,r,r")
1061 (mult:SF (match_operand:SF 1 "register_operand" "%0,0,0")
1062 (match_operand:SF 2 "rx_source_operand" "r,F,Q")))]
1063 "ALLOW_RX_FPU_INSNS"
1068 [(set_attr "cc" "set_zs")
1069 (set_attr "timings" "33,33,55")
1070 (set_attr "length" "3,7,5")]
1073 (define_insn "subsf3"
1074 [(set (match_operand:SF 0 "register_operand" "=r,r,r")
1075 (minus:SF (match_operand:SF 1 "register_operand" "0,0,0")
1076 (match_operand:SF 2 "rx_source_operand" "r,F,Q")))]
1077 "ALLOW_RX_FPU_INSNS"
1079 [(set_attr "cc" "set_zs")
1080 (set_attr "timings" "44,44,66")
1081 (set_attr "length" "3,7,5")]
1084 (define_insn "fix_truncsfsi2"
1085 [(set (match_operand:SI 0 "register_operand" "=r,r")
1086 (fix:SI (match_operand:SF 1 "rx_compare_operand" "r,Q")))]
1087 "ALLOW_RX_FPU_INSNS"
1089 [(set_attr "cc" "set_zs")
1090 (set_attr "timings" "22,44")
1091 (set_attr "length" "3,5")]
1094 (define_insn "floatsisf2"
1095 [(set (match_operand:SF 0 "register_operand" "=r,r")
1096 (float:SF (match_operand:SI 1 "rx_compare_operand" "r,Q")))]
1097 "ALLOW_RX_FPU_INSNS"
1099 [(set_attr "cc" "set_zs")
1100 (set_attr "timings" "22,44")
1101 (set_attr "length" "3,6")]
1104 ;; Bit manipulation instructions.
1105 ;; Note - there are two versions of each pattern because the memory
1106 ;; accessing versions use QImode whilst the register accessing
1107 ;; versions use SImode.
1108 ;; The peephole are here because the combiner only looks at a maximum
1109 ;; of three instructions at a time.
1111 (define_insn "bitset"
1112 [(set:SI (match_operand:SI 0 "register_operand" "+r")
1113 (ior:SI (match_operand:SI 1 "register_operand" "0")
1114 (ashift:SI (const_int 1)
1115 (match_operand:SI 2 "nonmemory_operand" "ri"))))]
1118 [(set_attr "length" "3")]
1121 (define_insn "bitset_in_memory"
1122 [(set:QI (match_operand:QI 0 "memory_operand" "+m")
1123 (ior:QI (match_operand:QI 1 "memory_operand" "0")
1124 (ashift:QI (const_int 1)
1125 (match_operand:QI 2 "nonmemory_operand" "ri"))))]
1128 [(set_attr "length" "3")
1129 (set_attr "timings" "34")]
1132 ;; (set (reg A) (const_int 1))
1133 ;; (set (reg A) (ashift (reg A) (reg B)))
1134 ;; (set (reg C) (ior (reg A) (reg C)))
1136 [(set:SI (match_operand:SI 0 "register_operand" "")
1138 (set:SI (match_dup 0)
1139 (ashift:SI (match_dup 0)
1140 (match_operand:SI 1 "register_operand" "")))
1141 (set:SI (match_operand:SI 2 "register_operand" "")
1142 (ior:SI (match_dup 0)
1144 "dead_or_set_p (insn, operands[0])"
1145 [(set:SI (match_dup 2)
1146 (ior:SI (match_dup 2)
1147 (ashift:SI (const_int 1)
1151 ;; (set (reg A) (const_int 1))
1152 ;; (set (reg A) (ashift (reg A) (reg B)))
1153 ;; (set (reg A) (ior (reg A) (reg C)))
1154 ;; (set (reg C) (reg A)
1156 [(set:SI (match_operand:SI 0 "register_operand" "")
1158 (set:SI (match_dup 0)
1159 (ashift:SI (match_dup 0)
1160 (match_operand:SI 1 "register_operand" "")))
1161 (set:SI (match_dup 0)
1162 (ior:SI (match_dup 0)
1163 (match_operand:SI 2 "register_operand" "")))
1164 (set:SI (match_dup 2) (match_dup 0))]
1165 "dead_or_set_p (insn, operands[0])"
1166 [(set:SI (match_dup 2)
1167 (ior:SI (match_dup 2)
1168 (ashift:SI (const_int 1)
1172 (define_insn "bitinvert"
1173 [(set:SI (match_operand:SI 0 "register_operand" "+r")
1174 (xor:SI (match_operand:SI 1 "register_operand" "0")
1175 (ashift:SI (const_int 1)
1176 (match_operand:SI 2 "nonmemory_operand" "ri"))))]
1179 [(set_attr "length" "3")]
1182 (define_insn "bitinvert_in_memory"
1183 [(set:QI (match_operand:QI 0 "memory_operand" "+m")
1184 (xor:QI (match_operand:QI 1 "register_operand" "0")
1185 (ashift:QI (const_int 1)
1186 (match_operand:QI 2 "nonmemory_operand" "ri"))))]
1189 [(set_attr "length" "5")
1190 (set_attr "timings" "33")]
1193 ;; (set (reg A) (const_int 1))
1194 ;; (set (reg A) (ashift (reg A) (reg B)))
1195 ;; (set (reg C) (xor (reg A) (reg C)))
1197 [(set:SI (match_operand:SI 0 "register_operand" "")
1199 (set:SI (match_dup 0)
1200 (ashift:SI (match_dup 0)
1201 (match_operand:SI 1 "register_operand" "")))
1202 (set:SI (match_operand:SI 2 "register_operand" "")
1203 (xor:SI (match_dup 0)
1205 "dead_or_set_p (insn, operands[0])"
1206 [(set:SI (match_dup 2)
1207 (xor:SI (match_dup 2)
1208 (ashift:SI (const_int 1)
1213 ;; (set (reg A) (const_int 1))
1214 ;; (set (reg A) (ashift (reg A) (reg B)))
1215 ;; (set (reg A) (xor (reg A) (reg C)))
1216 ;; (set (reg C) (reg A))
1218 [(set:SI (match_operand:SI 0 "register_operand" "")
1220 (set:SI (match_dup 0)
1221 (ashift:SI (match_dup 0)
1222 (match_operand:SI 1 "register_operand" "")))
1223 (set:SI (match_dup 0)
1224 (xor:SI (match_dup 0)
1225 (match_operand:SI 2 "register_operand" "")))
1226 (set:SI (match_dup 2) (match_dup 0))]
1227 "dead_or_set_p (insn, operands[0])"
1228 [(set:SI (match_dup 2)
1229 (xor:SI (match_dup 2)
1230 (ashift:SI (const_int 1)
1235 (define_insn "bitclr"
1236 [(set:SI (match_operand:SI 0 "register_operand" "+r")
1237 (and:SI (match_operand:SI 1 "register_operand" "0")
1238 (not:SI (ashift:SI (const_int 1)
1239 (match_operand:SI 2 "nonmemory_operand" "ri")))))]
1242 [(set_attr "length" "3")]
1245 (define_insn "bitclr_in_memory"
1246 [(set:QI (match_operand:QI 0 "memory_operand" "+m")
1247 (and:QI (match_operand:QI 1 "memory_operand" "0")
1248 (not:QI (ashift:QI (const_int 1)
1249 (match_operand:QI 2 "nonmemory_operand" "ri")))))]
1252 [(set_attr "length" "3")
1253 (set_attr "timings" "34")]
1256 ;; (set (reg A) (const_int -2))
1257 ;; (set (reg A) (rotate (reg A) (reg B)))
1258 ;; (set (reg C) (and (reg A) (reg C)))
1260 [(set:SI (match_operand:SI 0 "register_operand" "")
1262 (set:SI (match_dup 0)
1263 (rotate:SI (match_dup 0)
1264 (match_operand:SI 1 "register_operand" "")))
1265 (set:SI (match_operand:SI 2 "register_operand" "")
1266 (and:SI (match_dup 0)
1268 "dead_or_set_p (insn, operands[0])"
1269 [(set:SI (match_dup 2)
1270 (and:SI (match_dup 2)
1271 (not:SI (ashift:SI (const_int 1)
1275 ;; (set (reg A) (const_int -2))
1276 ;; (set (reg A) (rotate (reg A) (reg B)))
1277 ;; (set (reg A) (and (reg A) (reg C)))
1278 ;; (set (reg C) (reg A)
1280 [(set:SI (match_operand:SI 0 "register_operand" "")
1282 (set:SI (match_dup 0)
1283 (rotate:SI (match_dup 0)
1284 (match_operand:SI 1 "register_operand" "")))
1285 (set:SI (match_dup 0)
1286 (and:SI (match_dup 0)
1287 (match_operand:SI 2 "register_operand" "")))
1288 (set:SI (match_dup 2) (match_dup 0))]
1289 "dead_or_set_p (insn, operands[0])"
1290 [(set:SI (match_dup 2)
1291 (and:SI (match_dup 2)
1292 (not:SI (ashift:SI (const_int 1)
1296 (define_expand "insv"
1297 [(set:SI (zero_extract:SI (match_operand:SI
1298 0 "nonimmediate_operand") ;; Destination
1300 1 "immediate_operand") ;; # of bits to set
1302 2 "immediate_operand")) ;; Starting bit
1304 3 "immediate_operand"))] ;; Bits to insert
1307 if (rx_expand_insv (operands))
1313 ;; Atomic exchange operation.
1315 (define_insn "sync_lock_test_and_setsi"
1316 [(set:SI (match_operand:SI 0 "register_operand" "=r,r")
1317 (match_operand:SI 1 "rx_compare_operand" "=r,Q"))
1318 (set:SI (match_dup 1)
1319 (match_operand:SI 2 "register_operand" "0,0"))]
1322 [(set_attr "length" "3,6")
1323 (set_attr "timings" "22")]
1326 ;; Block move functions.
1328 (define_expand "movstr"
1329 [(set:SI (match_operand:BLK 1 "memory_operand") ;; Dest
1330 (match_operand:BLK 2 "memory_operand")) ;; Source
1331 (use (match_operand:SI 0 "register_operand")) ;; Updated Dest
1335 rtx addr1 = gen_rtx_REG (SImode, 1);
1336 rtx addr2 = gen_rtx_REG (SImode, 2);
1337 rtx len = gen_rtx_REG (SImode, 3);
1338 rtx dest_copy = gen_reg_rtx (SImode);
1340 emit_move_insn (len, GEN_INT (-1));
1341 emit_move_insn (addr1, force_operand (XEXP (operands[1], 0), NULL_RTX));
1342 emit_move_insn (addr2, force_operand (XEXP (operands[2], 0), NULL_RTX));
1343 operands[1] = replace_equiv_address_nv (operands[1], addr1);
1344 operands[2] = replace_equiv_address_nv (operands[2], addr2);
1345 emit_move_insn (dest_copy, addr1);
1346 emit_insn (gen_rx_movstr ());
1347 emit_move_insn (len, GEN_INT (-1));
1348 emit_insn (gen_rx_strend (operands[0], dest_copy));
1353 (define_insn "rx_movstr"
1354 [(set:SI (mem:BLK (reg:SI 1))
1355 (mem:BLK (reg:SI 2)))
1356 (unspec_volatile:BLK [(reg:SI 1) (reg:SI 2) (reg:SI 3)] UNSPEC_MOVSTR)
1357 (clobber (reg:SI 1))
1358 (clobber (reg:SI 2))
1359 (clobber (reg:SI 3))
1363 [(set_attr "length" "2")
1364 (set_attr "timings" "1111")] ;; The timing is a guesstimate.
1367 (define_insn "rx_strend"
1368 [(set:SI (match_operand:SI 0 "register_operand" "=r")
1369 (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "r")
1370 (reg:SI 3)] UNSPEC_STRLEN))
1371 (clobber (reg:SI 1))
1372 (clobber (reg:SI 2))
1373 (clobber (reg:SI 3))
1376 "mov\t%1, r1\n\tmov\t#0, r2\n\tsuntil.b\n\tmov\tr1, %0\n\tsub\t#1, %0"
1377 [(set_attr "length" "10")
1378 (set_attr "cc" "clobber")
1379 (set_attr "timings" "1111")] ;; The timing is a guesstimate.
1382 (define_expand "movmemsi"
1384 [(set (match_operand:BLK 0 "memory_operand") ;; Dest
1385 (match_operand:BLK 1 "memory_operand")) ;; Source
1386 (use (match_operand:SI 2 "register_operand")) ;; Length in bytes
1387 (match_operand 3 "immediate_operand") ;; Align
1388 (unspec_volatile:BLK [(reg:SI 1) (reg:SI 2) (reg:SI 3)] UNSPEC_MOVMEM)]
1392 rtx addr1 = gen_rtx_REG (SImode, 1);
1393 rtx addr2 = gen_rtx_REG (SImode, 2);
1394 rtx len = gen_rtx_REG (SImode, 3);
1396 if (REG_P (operands[0]) && (REGNO (operands[0]) == 2
1397 || REGNO (operands[0]) == 3))
1399 if (REG_P (operands[1]) && (REGNO (operands[1]) == 1
1400 || REGNO (operands[1]) == 3))
1402 if (REG_P (operands[2]) && (REGNO (operands[2]) == 1
1403 || REGNO (operands[2]) == 2))
1405 emit_move_insn (addr1, force_operand (XEXP (operands[0], 0), NULL_RTX));
1406 emit_move_insn (addr2, force_operand (XEXP (operands[1], 0), NULL_RTX));
1407 emit_move_insn (len, force_operand (operands[2], NULL_RTX));
1408 operands[0] = replace_equiv_address_nv (operands[0], addr1);
1409 operands[1] = replace_equiv_address_nv (operands[1], addr2);
1410 emit_insn (gen_rx_movmem ());
1415 (define_insn "rx_movmem"
1416 [(set (mem:BLK (reg:SI 1))
1417 (mem:BLK (reg:SI 2)))
1419 (unspec_volatile:BLK [(reg:SI 1) (reg:SI 2) (reg:SI 3)] UNSPEC_MOVMEM)
1420 (clobber (reg:SI 1))
1421 (clobber (reg:SI 2))
1422 (clobber (reg:SI 3))]
1425 [(set_attr "length" "2")
1426 (set_attr "timings" "1111")] ;; The timing is a guesstimate.
1429 (define_expand "setmemsi"
1430 [(set (match_operand:BLK 0 "memory_operand") ;; Dest
1431 (match_operand:QI 2 "nonmemory_operand")) ;; Value
1432 (use (match_operand:SI 1 "nonmemory_operand")) ;; Length
1433 (match_operand 3 "immediate_operand") ;; Align
1434 (unspec_volatile:BLK [(reg:SI 1) (reg:SI 2) (reg:SI 3)] UNSPEC_SETMEM)]
1437 rtx addr = gen_rtx_REG (SImode, 1);
1438 rtx val = gen_rtx_REG (QImode, 2);
1439 rtx len = gen_rtx_REG (SImode, 3);
1441 emit_move_insn (addr, force_operand (XEXP (operands[0], 0), NULL_RTX));
1442 emit_move_insn (len, force_operand (operands[1], NULL_RTX));
1443 emit_move_insn (val, operands[2]);
1444 emit_insn (gen_rx_setmem ());
1449 (define_insn "rx_setmem"
1450 [(set:BLK (mem:BLK (reg:SI 1)) (reg 2))
1451 (unspec_volatile:BLK [(reg:SI 1) (reg:SI 2) (reg:SI 3)] UNSPEC_SETMEM)
1452 (clobber (reg:SI 1))
1453 (clobber (reg:SI 3))]
1456 [(set_attr "length" "2")
1457 (set_attr "timings" "1111")] ;; The timing is a guesstimate.
1460 (define_expand "cmpstrnsi"
1461 [(set (match_operand:SI
1462 0 "register_operand") ;; Result
1463 (unspec_volatile:SI [(match_operand:BLK
1464 1 "memory_operand") ;; String1
1466 2 "memory_operand")] ;; String2
1468 (use (match_operand:SI
1469 3 "register_operand")) ;; Max Length
1471 4 "immediate_operand")] ;; Known Align
1474 rtx str1 = gen_rtx_REG (SImode, 1);
1475 rtx str2 = gen_rtx_REG (SImode, 2);
1476 rtx len = gen_rtx_REG (SImode, 3);
1478 emit_move_insn (str1, force_operand (XEXP (operands[1], 0), NULL_RTX));
1479 emit_move_insn (str2, force_operand (XEXP (operands[2], 0), NULL_RTX));
1480 emit_move_insn (len, force_operand (operands[3], NULL_RTX));
1482 emit_insn (gen_rx_cmpstrn (operands[0], operands[1], operands[2]));
1487 (define_expand "cmpstrsi"
1488 [(set (match_operand:SI
1489 0 "register_operand") ;; Result
1490 (unspec_volatile:SI [(match_operand:BLK
1491 1 "memory_operand") ;; String1
1493 2 "memory_operand")] ;; String2
1496 3 "immediate_operand")] ;; Known Align
1499 rtx str1 = gen_rtx_REG (SImode, 1);
1500 rtx str2 = gen_rtx_REG (SImode, 2);
1501 rtx len = gen_rtx_REG (SImode, 3);
1503 emit_move_insn (str1, force_reg (SImode, XEXP (operands[1], 0)));
1504 emit_move_insn (str2, force_reg (SImode, XEXP (operands[2], 0)));
1505 emit_move_insn (len, GEN_INT (-1));
1507 emit_insn (gen_rx_cmpstrn (operands[0], operands[1], operands[2]));
1512 (define_insn "rx_cmpstrn"
1513 [(set:SI (match_operand:SI 0 "register_operand" "=r")
1514 (unspec_volatile:SI [(reg:SI 1) (reg:SI 2) (reg:SI 3)]
1516 (use (match_operand:BLK 1 "memory_operand" "m"))
1517 (use (match_operand:BLK 2 "memory_operand" "m"))
1518 (clobber (reg:SI 1))
1519 (clobber (reg:SI 2))
1520 (clobber (reg:SI 3))]
1522 "scmpu ; Perform the string comparison
1523 mov #-1, %0 ; Set up -1 result (which cannot be created
1525 bnc ?+ ; If Carry is not set skip over
1526 scne.L %0 ; Set result based on Z flag
1529 [(set_attr "length" "9")
1530 (set_attr "timings" "1111")] ;; The timing is a guesstimate.
1533 ;; Builtin Functions
1535 ;; GCC does not have the ability to generate the following instructions
1536 ;; on its own so they are provided as builtins instead. To use them from
1537 ;; a program for example invoke them as __builtin_rx_<insn_name>. For
1540 ;; int short_byte_swap (int arg) { return __builtin_rx_revw (arg); }
1542 ;;---------- Accumulator Support ------------------------
1544 ;; Multiply & Accumulate (high)
1545 (define_insn "machi"
1546 [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
1547 (match_operand:SI 1 "register_operand" "r")]
1548 UNSPEC_BUILTIN_MACHI)]
1551 [(set_attr "length" "3")]
1554 ;; Multiply & Accumulate (low)
1555 (define_insn "maclo"
1556 [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
1557 (match_operand:SI 1 "register_operand" "r")]
1558 UNSPEC_BUILTIN_MACLO)]
1561 [(set_attr "length" "3")]
1565 (define_insn "mulhi"
1566 [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
1567 (match_operand:SI 1 "register_operand" "r")]
1568 UNSPEC_BUILTIN_MULHI)]
1571 [(set_attr "length" "3")]
1575 (define_insn "mullo"
1576 [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
1577 (match_operand:SI 1 "register_operand" "r")]
1578 UNSPEC_BUILTIN_MULLO)]
1581 [(set_attr "length" "3")]
1584 ;; Move from Accumulator (high)
1585 (define_insn "mvfachi"
1586 [(set (match_operand:SI 0 "register_operand" "=r")
1587 (unspec:SI [(const_int 0)]
1588 UNSPEC_BUILTIN_MVFACHI))]
1591 [(set_attr "length" "3")]
1594 ;; Move from Accumulator (middle)
1595 (define_insn "mvfacmi"
1596 [(set (match_operand:SI 0 "register_operand" "=r")
1597 (unspec:SI [(const_int 0)]
1598 UNSPEC_BUILTIN_MVFACMI))]
1601 [(set_attr "length" "3")]
1604 ;; Move to Accumulator (high)
1605 (define_insn "mvtachi"
1606 [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")]
1607 UNSPEC_BUILTIN_MVTACHI)]
1610 [(set_attr "length" "3")]
1613 ;; Move to Accumulator (low)
1614 (define_insn "mvtaclo"
1615 [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")]
1616 UNSPEC_BUILTIN_MVTACLO)]
1619 [(set_attr "length" "3")]
1622 ;; Round Accumulator
1624 [(unspec_volatile:SI [(match_operand:SI 0 "immediate_operand" "i")]
1625 UNSPEC_BUILTIN_RACW)]
1628 [(set_attr "length" "3")]
1631 ;; Repeat multiply and accumulate
1633 [(unspec:SI [(const_int 0) (reg:SI 1) (reg:SI 2) (reg:SI 3)
1634 (reg:SI 4) (reg:SI 5) (reg:SI 6)]
1635 UNSPEC_BUILTIN_RMPA)
1636 (clobber (reg:SI 1))
1637 (clobber (reg:SI 2))
1638 (clobber (reg:SI 3))]
1641 [(set_attr "length" "2")
1642 (set_attr "timings" "1010")]
1645 ;;---------- Arithmetic ------------------------
1647 ;; Byte swap (two 16-bit values).
1649 [(set (match_operand:SI 0 "register_operand" "+r")
1650 (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
1651 UNSPEC_BUILTIN_REVW))]
1654 [(set_attr "length" "3")]
1657 ;; Round to integer.
1658 (define_insn "lrintsf2"
1659 [(set (match_operand:SI 0 "register_operand" "=r,r")
1660 (unspec:SI [(match_operand:SF 1 "rx_compare_operand" "r,Q")]
1661 UNSPEC_BUILTIN_ROUND))]
1664 [(set_attr "cc" "set_zs")
1665 (set_attr "timings" "22,44")
1666 (set_attr "length" "3,5")]
1669 ;; Saturate to 32-bits
1671 [(set (match_operand:SI 0 "register_operand" "=r")
1672 (unspec:SI [(match_operand:SI 1 "register_operand" "0")]
1673 UNSPEC_BUILTIN_SAT))]
1676 [(set_attr "length" "2")]
1679 ;;---------- Control Registers ------------------------
1681 ;; Clear Processor Status Word
1682 (define_insn "clrpsw"
1683 [(unspec:SI [(match_operand:SI 0 "immediate_operand" "i")]
1684 UNSPEC_BUILTIN_CLRPSW)
1688 [(set_attr "length" "2")
1689 (set_attr "cc" "clobber")]
1692 ;; Set Processor Status Word
1693 (define_insn "setpsw"
1694 [(unspec:SI [(match_operand:SI 0 "immediate_operand" "i")]
1695 UNSPEC_BUILTIN_SETPSW)
1699 [(set_attr "length" "2")
1700 (set_attr "cc" "clobber")]
1703 ;; Move from control register
1705 [(set (match_operand:SI 0 "register_operand" "=r")
1706 (unspec:SI [(match_operand:SI 1 "immediate_operand" "i")]
1707 UNSPEC_BUILTIN_MVFC))]
1710 [(set_attr "length" "3")]
1713 ;; Move to control register
1715 [(unspec:SI [(match_operand:SI 0 "immediate_operand" "i,i")
1716 (match_operand:SI 1 "nonmemory_operand" "r,i")]
1717 UNSPEC_BUILTIN_MVTC)]
1720 [(set_attr "length" "3,7")]
1721 ;; Ignore possible clobbering of the comparison flags in the
1722 ;; PSW register. This is a cc0 target so any cc0 setting
1723 ;; instruction will always be paired with a cc0 user, without
1724 ;; the possibility of this instruction being placed in between
1728 ;; Move to interrupt priority level
1729 (define_insn "mvtipl"
1730 [(unspec:SI [(match_operand:SI 0 "immediate_operand" "Uint04")]
1731 UNSPEC_BUILTIN_MVTIPL)]
1734 [(set_attr "length" "3")]
1737 ;;---------- Interrupts ------------------------
1741 [(unspec_volatile [(const_int 0)]
1742 UNSPEC_BUILTIN_BRK)]
1745 [(set_attr "length" "1")
1746 (set_attr "timings" "66")]
1751 [(unspec_volatile:SI [(match_operand:SI 0 "immediate_operand" "i")]
1752 UNSPEC_BUILTIN_INT)]
1755 [(set_attr "length" "3")]
1760 [(unspec_volatile [(const_int 0)]
1761 UNSPEC_BUILTIN_WAIT)]
1764 [(set_attr "length" "2")]
1767 ;;---------- CoProcessor Support ------------------------
1769 ;; FIXME: The instructions are currently commented out because
1770 ;; the bit patterns have not been finalized, so the assembler
1771 ;; does not support them. Once they are decided and the assembler
1772 ;; supports them, enable the instructions here.
1774 ;; Move from co-processor register
1775 (define_insn "mvfcp"
1776 [(set (match_operand:SI 0 "register_operand" "=r")
1777 (unspec:SI [(match_operand:SI 1 "immediate_operand" "i")
1778 (match_operand:SI 2 "immediate_operand" "i")]
1779 UNSPEC_BUILTIN_MVFCP))]
1781 "; mvfcp\t%1, %0, %2"
1782 [(set_attr "length" "5")]
1785 ;;---------- Misc ------------------------
1787 ;; Required by cfglayout.c...
1792 [(set_attr "length" "1")]