1 ;;- Machine description for SPARC chip for GNU C compiler
2 ;; Copyright (C) 1987, 1988, 1989, 1992 Free Software Foundation, Inc.
3 ;; Contributed by Michael Tiemann (tiemann@cygnus.com)
5 ;; This file is part of GNU CC.
7 ;; GNU CC 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 2, or (at your option)
12 ;; GNU CC 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 GNU CC; see the file COPYING. If not, write to
19 ;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
22 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
24 ;; Insn type. Used to default other attribute values.
26 ;; type "unary" insns have one input operand (1) and one output operand (0)
27 ;; type "binary" insns have two input operands (1,2) and one output (0)
28 ;; type "compare" insns have one or two input operands (0,1) and no output
29 ;; type "call_no_delay_slot" is a call followed by an unimp instruction.
32 "move,unary,binary,compare,load,store,branch,call,call_no_delay_slot,address,fpload,fpstore,fp,fpcmp,fpmul,fpdiv,fpsqrt,multi,misc"
33 (const_string "binary"))
35 ;; Set true if insn uses call-clobbered intermediate register.
36 (define_attr "use_clobbered" "false,true"
37 (if_then_else (and (eq_attr "type" "address")
38 (match_operand 0 "clobbered_register" ""))
40 (const_string "false")))
42 ;; Length (in # of insns).
43 (define_attr "length" ""
44 (cond [(eq_attr "type" "load,fpload")
45 (if_then_else (match_operand 1 "symbolic_memory_operand" "")
46 (const_int 2) (const_int 1))
48 (eq_attr "type" "store,fpstore")
49 (if_then_else (match_operand 0 "symbolic_memory_operand" "")
50 (const_int 2) (const_int 1))
52 (eq_attr "type" "address") (const_int 2)
54 (eq_attr "type" "binary")
55 (if_then_else (ior (match_operand 2 "arith_operand" "")
56 (match_operand 2 "arith_double_operand" ""))
57 (const_int 1) (const_int 3))
59 (eq_attr "type" "multi") (const_int 2)
61 (eq_attr "type" "move,unary")
62 (if_then_else (ior (match_operand 1 "arith_operand" "")
63 (match_operand 1 "arith_double_operand" ""))
64 (const_int 1) (const_int 2))]
68 (define_asm_attributes
69 [(set_attr "length" "1")
70 (set_attr "type" "multi")])
72 ;; Attributes for instruction and branch scheduling
74 (define_attr "in_call_delay" "false,true"
75 (cond [(eq_attr "type" "branch,call,call_no_delay_slot,multi")
76 (const_string "false")
77 (eq_attr "type" "load,fpload,store,fpstore")
78 (if_then_else (eq_attr "length" "1")
80 (const_string "false"))
81 (eq_attr "type" "address")
82 (if_then_else (eq_attr "use_clobbered" "false")
84 (const_string "false"))]
85 (if_then_else (eq_attr "length" "1")
87 (const_string "false"))))
89 (define_delay (eq_attr "type" "call")
90 [(eq_attr "in_call_delay" "true") (nil) (nil)])
92 ;; ??? Should implement the notion of predelay slots for floating point
93 ;; branches. This would allow us to remove the nop always inserted before
94 ;; a floating point branch.
96 (define_attr "in_branch_delay" "false,true"
97 (if_then_else (and (eq_attr "type" "!branch,call,call_no_delay_slot,multi")
98 (eq_attr "length" "1"))
100 (const_string "false")))
102 (define_delay (eq_attr "type" "branch")
103 [(eq_attr "in_branch_delay" "true")
104 (nil) (eq_attr "in_branch_delay" "true")])
106 ;; Function units of the SPARC
108 ;; (define_function_unit {name} {num-units} {n-users} {test}
109 ;; {ready-delay} {busy-delay} [{conflict-list}])
112 ;; (Noted only for documentation; units that take one cycle do not need to
115 ;; (define_function_unit "alu" 1 0
116 ;; (eq_attr "type" "unary,binary,move,address") 1 0)
118 ;; Memory with load-delay of 1 (i.e., 2 cycle load).
119 (define_function_unit "memory" 1 0 (eq_attr "type" "load,fpload") 2 0)
121 ;; SPARC has two floating-point units: the FP ALU,
122 ;; and the FP MUL/DIV/SQRT unit.
123 ;; Instruction timings on the CY7C602 are as follows
137 ;; The CY7C602 can only support 2 fp isnsn simultaneously.
138 ;; More insns cause the chip to stall.
140 (define_function_unit "fp_alu" 1 2 (eq_attr "type" "fp") 5 0)
141 (define_function_unit "fp_mul" 1 2 (eq_attr "type" "fpmul") 7 0)
142 (define_function_unit "fp_div" 1 2 (eq_attr "type" "fpdiv") 37 0)
143 (define_function_unit "fp_sqrt" 1 2 (eq_attr "type" "fpsqrt") 63 0)
145 ;; Compare instructions.
146 ;; This controls RTL generation and register allocation.
148 ;; We generate RTL for comparisons and branches by having the cmpxx
149 ;; patterns store away the operands. Then, the scc and bcc patterns
150 ;; emit RTL for both the compare and the branch.
152 ;; We do this because we want to generate different code for an sne and
153 ;; seq insn. In those cases, if the second operand of the compare is not
154 ;; const0_rtx, we want to compute the xor of the two operands and test
157 ;; We start with the DEFINE_EXPANDs, then then DEFINE_INSNs to match
158 ;; the patterns. Finally, we have the DEFINE_SPLITs for some of the scc
159 ;; insns that actually require more than one machine instruction.
161 ;; Put cmpsi first among compare insns so it matches two CONST_INT operands.
163 (define_expand "cmpsi"
165 (compare:CC (match_operand:SI 0 "register_operand" "")
166 (match_operand:SI 1 "arith_operand" "")))]
170 sparc_compare_op0 = operands[0];
171 sparc_compare_op1 = operands[1];
175 (define_expand "cmpsf"
177 (compare:CCFP (match_operand:SF 0 "register_operand" "")
178 (match_operand:SF 1 "register_operand" "")))]
182 sparc_compare_op0 = operands[0];
183 sparc_compare_op1 = operands[1];
187 (define_expand "cmpdf"
189 (compare:CCFP (match_operand:DF 0 "register_operand" "")
190 (match_operand:DF 1 "register_operand" "")))]
194 sparc_compare_op0 = operands[0];
195 sparc_compare_op1 = operands[1];
199 (define_expand "cmptf"
201 (compare:CCFP (match_operand:TF 0 "register_operand" "")
202 (match_operand:TF 1 "register_operand" "")))]
206 sparc_compare_op0 = operands[0];
207 sparc_compare_op1 = operands[1];
211 ;; Next come the scc insns. For seq, sne, sgeu, and sltu, we can do this
212 ;; without jumps using the addx/subx instructions. For the rest, we do
213 ;; branches. Seq_special and sne_special clobber the CC reg, because they
214 ;; generate addcc/subcc instructions.
216 (define_expand "seq_special"
217 [(set (match_dup 3) (xor:SI (match_operand:SI 1 "register_operand" "")
218 (match_operand:SI 2 "register_operand" "")))
219 (parallel [(set (match_operand:SI 0 "register_operand" "")
220 (eq:SI (match_dup 3) (const_int 0)))
221 (clobber (reg:CC 0))])]
224 "{ operands[3] = gen_reg_rtx (SImode); }")
226 (define_expand "sne_special"
227 [(set (match_dup 3) (xor:SI (match_operand:SI 1 "register_operand" "")
228 (match_operand:SI 2 "register_operand" "")))
229 (parallel [(set (match_operand:SI 0 "register_operand" "")
230 (ne:SI (match_dup 3) (const_int 0)))
231 (clobber (reg:CC 0))])]
233 "{ operands[3] = gen_reg_rtx (SImode); }")
236 [(set (match_operand:SI 0 "register_operand" "")
237 (eq:SI (match_dup 1) (const_int 0)))]
240 { if (GET_MODE (sparc_compare_op0) == SImode)
242 emit_insn (gen_seq_special (operands[0], sparc_compare_op0,
247 operands[1] = gen_compare_reg (EQ, sparc_compare_op0, sparc_compare_op1);
251 [(set (match_operand:SI 0 "register_operand" "")
252 (ne:SI (match_dup 1) (const_int 0)))]
255 { if (GET_MODE (sparc_compare_op0) == SImode)
257 emit_insn (gen_sne_special (operands[0], sparc_compare_op0,
262 operands[1] = gen_compare_reg (NE, sparc_compare_op0, sparc_compare_op1);
266 [(set (match_operand:SI 0 "register_operand" "")
267 (gt:SI (match_dup 1) (const_int 0)))]
270 { operands[1] = gen_compare_reg (GT, sparc_compare_op0, sparc_compare_op1); }")
273 [(set (match_operand:SI 0 "register_operand" "")
274 (lt:SI (match_dup 1) (const_int 0)))]
277 { operands[1] = gen_compare_reg (LT, sparc_compare_op0, sparc_compare_op1); }")
280 [(set (match_operand:SI 0 "register_operand" "")
281 (ge:SI (match_dup 1) (const_int 0)))]
284 { operands[1] = gen_compare_reg (GE, sparc_compare_op0, sparc_compare_op1); }")
287 [(set (match_operand:SI 0 "register_operand" "")
288 (le:SI (match_dup 1) (const_int 0)))]
291 { operands[1] = gen_compare_reg (LE, sparc_compare_op0, sparc_compare_op1); }")
293 (define_expand "sgtu"
294 [(set (match_operand:SI 0 "register_operand" "")
295 (gtu:SI (match_dup 1) (const_int 0)))]
301 /* We can do ltu easily, so if both operands are registers, swap them and
303 if ((GET_CODE (sparc_compare_op0) == REG
304 || GET_CODE (sparc_compare_op0) == SUBREG)
305 && (GET_CODE (sparc_compare_op1) == REG
306 || GET_CODE (sparc_compare_op1) == SUBREG))
308 tem = sparc_compare_op0;
309 sparc_compare_op0 = sparc_compare_op1;
310 sparc_compare_op1 = tem;
311 emit_insn (gen_sltu (operands[0]));
315 operands[1] = gen_compare_reg (LEU, sparc_compare_op0, sparc_compare_op1);
318 (define_expand "sltu"
319 [(set (match_operand:SI 0 "register_operand" "")
320 (ltu:SI (match_dup 1) (const_int 0)))]
323 { operands[1] = gen_compare_reg (LTU, sparc_compare_op0, sparc_compare_op1);
326 (define_expand "sgeu"
327 [(set (match_operand:SI 0 "register_operand" "")
328 (geu:SI (match_dup 1) (const_int 0)))]
331 { operands[1] = gen_compare_reg (GEU, sparc_compare_op0, sparc_compare_op1);
334 (define_expand "sleu"
335 [(set (match_operand:SI 0 "register_operand" "")
336 (leu:SI (match_dup 1) (const_int 0)))]
342 /* We can do geu easily, so if both operands are registers, swap them and
344 if ((GET_CODE (sparc_compare_op0) == REG
345 || GET_CODE (sparc_compare_op0) == SUBREG)
346 && (GET_CODE (sparc_compare_op1) == REG
347 || GET_CODE (sparc_compare_op1) == SUBREG))
349 tem = sparc_compare_op0;
350 sparc_compare_op0 = sparc_compare_op1;
351 sparc_compare_op1 = tem;
352 emit_insn (gen_sgeu (operands[0]));
356 operands[1] = gen_compare_reg (LEU, sparc_compare_op0, sparc_compare_op1);
359 ;; Now the DEFINE_INSNs for the compare and scc cases. First the compares.
363 (compare:CC (match_operand:SI 0 "register_operand" "rJ")
364 (match_operand:SI 1 "arith_operand" "rI")))]
367 [(set_attr "type" "compare")])
371 (compare:CCFPE (match_operand:DF 0 "register_operand" "f")
372 (match_operand:DF 1 "register_operand" "f")))]
375 [(set_attr "type" "fpcmp")])
379 (compare:CCFPE (match_operand:SF 0 "register_operand" "f")
380 (match_operand:SF 1 "register_operand" "f")))]
383 [(set_attr "type" "fpcmp")])
387 (compare:CCFPE (match_operand:TF 0 "register_operand" "f")
388 (match_operand:TF 1 "register_operand" "f")))]
391 [(set_attr "type" "fpcmp")])
395 (compare:CCFP (match_operand:DF 0 "register_operand" "f")
396 (match_operand:DF 1 "register_operand" "f")))]
399 [(set_attr "type" "fpcmp")])
403 (compare:CCFP (match_operand:SF 0 "register_operand" "f")
404 (match_operand:SF 1 "register_operand" "f")))]
407 [(set_attr "type" "fpcmp")])
411 (compare:CCFP (match_operand:TF 0 "register_operand" "f")
412 (match_operand:TF 1 "register_operand" "f")))]
415 [(set_attr "type" "fpcmp")])
417 ;; The SEQ and SNE patterns are special because they can be done
418 ;; without any branching and do not involve a COMPARE.
421 [(set (match_operand:SI 0 "register_operand" "=r")
422 (ne:SI (match_operand:SI 1 "register_operand" "r") (const_int 0)))
423 (clobber (reg:CC 0))]
425 "subcc %%g0,%1,%%g0\;addx %%g0,0,%0"
426 [(set_attr "type" "unary")
427 (set_attr "length" "2")])
430 [(set (match_operand:SI 0 "register_operand" "=r")
431 (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
433 (clobber (reg:CC 0))]
435 "subcc %%g0,%1,%%g0\;subx %%g0,0,%0"
436 [(set_attr "type" "unary")
437 (set_attr "length" "2")])
440 [(set (match_operand:SI 0 "register_operand" "=r")
441 (eq:SI (match_operand:SI 1 "register_operand" "r") (const_int 0)))
442 (clobber (reg:CC 0))]
444 "subcc %%g0,%1,%%g0\;subx %%g0,-1,%0"
445 [(set_attr "type" "unary")
446 (set_attr "length" "2")])
449 [(set (match_operand:SI 0 "register_operand" "=r")
450 (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
452 (clobber (reg:CC 0))]
454 "subcc %%g0,%1,%%g0\;addx %%g0,-1,%0"
455 [(set_attr "type" "unary")
456 (set_attr "length" "2")])
458 ;; We can also do (x + (i == 0)) and related, so put them in.
461 [(set (match_operand:SI 0 "register_operand" "=r")
462 (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
464 (match_operand:SI 2 "register_operand" "r")))
465 (clobber (reg:CC 0))]
467 "subcc %%g0,%1,%%g0\;addx %2,0,%0"
468 [(set_attr "length" "2")])
471 [(set (match_operand:SI 0 "register_operand" "=r")
472 (minus:SI (match_operand:SI 2 "register_operand" "r")
473 (ne:SI (match_operand:SI 1 "register_operand" "r")
475 (clobber (reg:CC 0))]
477 "subcc %%g0,%1,%%g0\;subx %2,0,%0"
478 [(set_attr "length" "2")])
481 [(set (match_operand:SI 0 "register_operand" "=r")
482 (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
484 (match_operand:SI 2 "register_operand" "r")))
485 (clobber (reg:CC 0))]
487 "subcc %%g0,%1,%%g0\;subx %2,-1,%0"
488 [(set_attr "length" "2")])
491 [(set (match_operand:SI 0 "register_operand" "=r")
492 (minus:SI (match_operand:SI 2 "register_operand" "r")
493 (eq:SI (match_operand:SI 1 "register_operand" "r")
495 (clobber (reg:CC 0))]
497 "subcc %%g0,%1,%%g0\;addx %2,-1,%0"
498 [(set_attr "length" "2")])
500 ;; We can also do GEU and LTU directly, but these operate after a
504 [(set (match_operand:SI 0 "register_operand" "=r")
505 (ltu:SI (reg:CC 0) (const_int 0)))]
508 [(set_attr "type" "misc")])
511 [(set (match_operand:SI 0 "register_operand" "=r")
512 (neg:SI (ltu:SI (reg:CC 0) (const_int 0))))]
515 [(set_attr "type" "misc")])
517 ;; ??? Combine should canonicalize these next two to the same pattern.
519 [(set (match_operand:SI 0 "register_operand" "=r")
520 (minus:SI (neg:SI (ltu:SI (reg:CC 0) (const_int 0)))
521 (match_operand:SI 1 "arith_operand" "rI")))]
524 [(set_attr "type" "unary")])
527 [(set (match_operand:SI 0 "register_operand" "=r")
528 (neg:SI (plus:SI (ltu:SI (reg:CC 0) (const_int 0))
529 (match_operand:SI 1 "arith_operand" "rI"))))]
532 [(set_attr "type" "unary")])
535 [(set (match_operand:SI 0 "register_operand" "=r")
536 (geu:SI (reg:CC 0) (const_int 0)))]
539 [(set_attr "type" "misc")])
542 [(set (match_operand:SI 0 "register_operand" "=r")
543 (neg:SI (geu:SI (reg:CC 0) (const_int 0))))]
546 [(set_attr "type" "misc")])
548 ;; We can also do (x + ((unsigned) i >= 0)) and related, so put them in.
551 [(set (match_operand:SI 0 "register_operand" "=r")
552 (plus:SI (ltu:SI (reg:CC 0) (const_int 0))
553 (match_operand:SI 1 "arith_operand" "rI")))]
556 [(set_attr "type" "unary")])
559 [(set (match_operand:SI 0 "register_operand" "=r")
560 (plus:SI (ltu:SI (reg:CC 0) (const_int 0))
561 (plus:SI (match_operand:SI 1 "arith_operand" "%r")
562 (match_operand:SI 2 "arith_operand" "rI"))))]
567 [(set (match_operand:SI 0 "register_operand" "=r")
568 (minus:SI (match_operand:SI 1 "register_operand" "r")
569 (ltu:SI (reg:CC 0) (const_int 0))))]
572 [(set_attr "type" "unary")])
574 ;; ??? Combine should canonicalize these next two to the same pattern.
576 [(set (match_operand:SI 0 "register_operand" "=r")
577 (minus:SI (minus:SI (match_operand:SI 1 "register_operand" "r")
578 (match_operand:SI 2 "arith_operand" "rI"))
579 (ltu:SI (reg:CC 0) (const_int 0))))]
584 [(set (match_operand:SI 0 "register_operand" "=r")
585 (minus:SI (match_operand:SI 1 "register_operand" "r")
586 (plus:SI (ltu:SI (reg:CC 0) (const_int 0))
587 (match_operand:SI 2 "arith_operand" "rI"))))]
592 [(set (match_operand:SI 0 "register_operand" "=r")
593 (plus:SI (geu:SI (reg:CC 0) (const_int 0))
594 (match_operand:SI 1 "register_operand" "r")))]
597 [(set_attr "type" "unary")])
600 [(set (match_operand:SI 0 "register_operand" "=r")
601 (minus:SI (match_operand:SI 1 "register_operand" "r")
602 (geu:SI (reg:CC 0) (const_int 0))))]
605 [(set_attr "type" "unary")])
607 ;; Now we have the generic scc insns. These will be done using a jump.
608 ;; We have to exclude the cases above, since we will not want combine to
609 ;; turn something that does not require a jump into something that does.
611 [(set (match_operand:SI 0 "register_operand" "=r")
612 (match_operator:SI 1 "normal_comp_operator" [(reg 0) (const_int 0)]))]
614 "* return output_scc_insn (operands, insn); "
615 [(set_attr "type" "multi")
616 (set_attr "length" "3")])
618 ;; These control RTL generation for conditional jump insns
622 (if_then_else (eq (match_dup 1) (const_int 0))
623 (label_ref (match_operand 0 "" ""))
627 { operands[1] = gen_compare_reg (EQ, sparc_compare_op0, sparc_compare_op1); }")
631 (if_then_else (ne (match_dup 1) (const_int 0))
632 (label_ref (match_operand 0 "" ""))
636 { operands[1] = gen_compare_reg (NE, sparc_compare_op0, sparc_compare_op1); }")
640 (if_then_else (gt (match_dup 1) (const_int 0))
641 (label_ref (match_operand 0 "" ""))
645 { operands[1] = gen_compare_reg (GT, sparc_compare_op0, sparc_compare_op1); }")
647 (define_expand "bgtu"
649 (if_then_else (gtu (match_dup 1) (const_int 0))
650 (label_ref (match_operand 0 "" ""))
654 { operands[1] = gen_compare_reg (GTU, sparc_compare_op0, sparc_compare_op1);
659 (if_then_else (lt (match_dup 1) (const_int 0))
660 (label_ref (match_operand 0 "" ""))
664 { operands[1] = gen_compare_reg (LT, sparc_compare_op0, sparc_compare_op1); }")
666 (define_expand "bltu"
668 (if_then_else (ltu (match_dup 1) (const_int 0))
669 (label_ref (match_operand 0 "" ""))
673 { operands[1] = gen_compare_reg (LTU, sparc_compare_op0, sparc_compare_op1);
678 (if_then_else (ge (match_dup 1) (const_int 0))
679 (label_ref (match_operand 0 "" ""))
683 { operands[1] = gen_compare_reg (GE, sparc_compare_op0, sparc_compare_op1); }")
685 (define_expand "bgeu"
687 (if_then_else (geu (match_dup 1) (const_int 0))
688 (label_ref (match_operand 0 "" ""))
692 { operands[1] = gen_compare_reg (GEU, sparc_compare_op0, sparc_compare_op1);
697 (if_then_else (le (match_dup 1) (const_int 0))
698 (label_ref (match_operand 0 "" ""))
702 { operands[1] = gen_compare_reg (LE, sparc_compare_op0, sparc_compare_op1); }")
704 (define_expand "bleu"
706 (if_then_else (leu (match_dup 1) (const_int 0))
707 (label_ref (match_operand 0 "" ""))
711 { operands[1] = gen_compare_reg (LEU, sparc_compare_op0, sparc_compare_op1);
714 ;; Now match both normal and inverted jump.
718 (if_then_else (match_operator 0 "noov_compare_op"
719 [(reg 0) (const_int 0)])
720 (label_ref (match_operand 1 "" ""))
725 return output_cbranch (operands[0], 1, 0,
726 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
729 [(set_attr "type" "branch")])
733 (if_then_else (match_operator 0 "noov_compare_op"
734 [(reg 0) (const_int 0)])
736 (label_ref (match_operand 1 "" ""))))]
740 return output_cbranch (operands[0], 1, 1,
741 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
744 [(set_attr "type" "branch")])
748 (define_expand "movsi"
749 [(set (match_operand:SI 0 "general_operand" "")
750 (match_operand:SI 1 "general_operand" ""))]
754 if (emit_move_sequence (operands, SImode, 0))
758 (define_expand "reload_insi"
759 [(set (match_operand:SI 0 "register_operand" "=r")
760 (match_operand:SI 1 "general_operand" ""))
761 (clobber (match_operand:SI 2 "register_operand" "=&r"))]
765 if (emit_move_sequence (operands, SImode, operands[2]))
768 /* We don't want the clobber emitted, so handle this ourselves. */
769 emit_insn (gen_rtx (SET, VOIDmode, operands[0], operands[1]));
773 ;; We must support both 'r' and 'f' registers here, because combine may
774 ;; convert SFmode hard registers to SImode hard registers when simplifying
777 ;; We cannot combine the similar 'r' and 'f' constraints, because it causes
778 ;; problems with register allocation. Reload might try to put an integer
779 ;; in an fp register, or an fp number is an integer register.
782 [(set (match_operand:SI 0 "reg_or_nonsymb_mem_operand" "=r,r,r,f,Q,Q,rf")
783 (match_operand:SI 1 "move_operand" "rI,K,Q,!Q,rJ,!f,!fr"))]
784 "register_operand (operands[0], SImode)
785 || register_operand (operands[1], SImode)
786 || operands[1] == const0_rtx"
794 st %r1,[%%fp-4]\;ld [%%fp-4],%0"
795 [(set_attr "type" "move,move,load,load,store,store,multi")
796 (set_attr "length" "*,1,*,*,*,*,*")])
798 ;; Special pic pattern, for loading the address of a label into a register.
799 ;; It clobbers o7 because the call puts the return address (i.e. pc value)
803 [(set (match_operand:SI 0 "register_operand" "=r")
804 (match_operand:SI 1 "move_pic_label" "i"))
805 (set (reg:SI 15) (pc))]
807 "\\n1:\;call 2f\;sethi %%hi(%l1-1b),%0\\n2:\\tor %0,%%lo(%l1-1b),%0\;add %0,%%o7,%0"
808 [(set_attr "type" "multi")
809 (set_attr "length" "4")])
812 [(set (match_operand:DI 0 "register_operand" "=r")
813 (high:DI (match_operand 1 "" "")))]
817 rtx op0 = operands[0];
818 rtx op1 = operands[1];
820 if (GET_CODE (op1) == CONST_INT)
822 operands[0] = operand_subword (op0, 1, 0, DImode);
823 output_asm_insn (\"sethi %%hi(%a1),%0\", operands);
825 operands[0] = operand_subword (op0, 0, 0, DImode);
826 if (INTVAL (op1) < 0)
827 output_asm_insn (\"mov -1,%0\", operands);
829 output_asm_insn (\"mov 0,%0\", operands);
831 else if (GET_CODE (op1) == CONST_DOUBLE)
833 operands[0] = operand_subword (op0, 1, 0, DImode);
834 operands[1] = gen_rtx (CONST_INT, VOIDmode, CONST_DOUBLE_LOW (op1));
835 output_asm_insn (\"sethi %%hi(%a1),%0\", operands);
837 operands[0] = operand_subword (op0, 0, 0, DImode);
838 operands[1] = gen_rtx (CONST_INT, VOIDmode, CONST_DOUBLE_HIGH (op1));
839 output_asm_insn (singlemove_string (operands), operands);
844 [(set_attr "type" "move")
845 (set_attr "length" "2")])
847 ;; For PIC, symbol_refs are put inside unspec so that the optimizer won't
848 ;; confuse them with real addresses.
850 [(set (match_operand:SI 0 "register_operand" "=r")
851 (high:SI (unspec:SI [(match_operand 1 "" "")] 0)))]
854 [(set_attr "type" "move")
855 (set_attr "length" "1")])
858 [(set (match_operand:SI 0 "register_operand" "=r")
859 (high:SI (match_operand 1 "" "")))]
862 [(set_attr "type" "move")
863 (set_attr "length" "1")])
866 [(set (match_operand:HI 0 "register_operand" "=r")
867 (high:HI (match_operand 1 "" "")))]
870 [(set_attr "type" "move")
871 (set_attr "length" "1")])
874 [(set (match_operand:DI 0 "register_operand" "=r")
875 (lo_sum:DI (match_operand:DI 1 "register_operand" "0")
876 (match_operand:DI 2 "immediate_operand" "in")))]
880 /* Don't output a 64 bit constant, since we can't trust the assembler to
881 handle it correctly. */
882 if (GET_CODE (operands[2]) == CONST_DOUBLE)
883 operands[2] = gen_rtx (CONST_INT, VOIDmode, CONST_DOUBLE_LOW (operands[2]));
884 return \"or %R1,%%lo(%a2),%R0\";
886 ;; Need to set length for this arith insn because operand2
887 ;; is not an "arith_operand".
888 [(set_attr "length" "1")])
890 ;; For PIC, symbol_refs are put inside unspec so that the optimizer won't
891 ;; confuse them with real addresses.
893 [(set (match_operand:SI 0 "register_operand" "=r")
894 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
895 (unspec:SI [(match_operand:SI 2 "immediate_operand" "in")] 0)))]
898 ;; Need to set length for this arith insn because operand2
899 ;; is not an "arith_operand".
900 [(set_attr "length" "1")])
903 [(set (match_operand:SI 0 "register_operand" "=r")
904 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
905 (match_operand:SI 2 "immediate_operand" "in")))]
908 ;; Need to set length for this arith insn because operand2
909 ;; is not an "arith_operand".
910 [(set_attr "length" "1")])
913 [(set (mem:SI (match_operand:SI 0 "symbolic_operand" ""))
914 (match_operand:SI 1 "reg_or_0_operand" "rJ"))
915 (clobber (match_scratch:SI 2 "=&r"))]
917 "sethi %%hi(%a0),%2\;st %r1,[%2+%%lo(%a0)]"
918 [(set_attr "type" "store")
919 (set_attr "length" "2")])
921 (define_expand "movhi"
922 [(set (match_operand:HI 0 "general_operand" "")
923 (match_operand:HI 1 "general_operand" ""))]
927 if (emit_move_sequence (operands, HImode, 0))
932 [(set (match_operand:HI 0 "reg_or_nonsymb_mem_operand" "=r,r,r,Q")
933 (match_operand:HI 1 "move_operand" "rI,K,Q,rJ"))]
934 "register_operand (operands[0], HImode)
935 || register_operand (operands[1], HImode)
936 || operands[1] == const0_rtx"
942 [(set_attr "type" "move,move,load,store")
943 (set_attr "length" "*,1,*,1")])
946 [(set (match_operand:HI 0 "register_operand" "=r")
947 (lo_sum:HI (match_operand:HI 1 "register_operand" "r")
948 (match_operand 2 "immediate_operand" "in")))]
951 [(set_attr "length" "1")])
954 [(set (mem:HI (match_operand:SI 0 "symbolic_operand" ""))
955 (match_operand:HI 1 "reg_or_0_operand" "rJ"))
956 (clobber (match_scratch:SI 2 "=&r"))]
958 "sethi %%hi(%a0),%2\;sth %r1,[%2+%%lo(%a0)]"
959 [(set_attr "type" "store")
960 (set_attr "length" "2")])
962 (define_expand "movqi"
963 [(set (match_operand:QI 0 "general_operand" "")
964 (match_operand:QI 1 "general_operand" ""))]
968 if (emit_move_sequence (operands, QImode, 0))
973 [(set (match_operand:QI 0 "reg_or_nonsymb_mem_operand" "=r,r,r,Q")
974 (match_operand:QI 1 "move_operand" "rI,K,Q,rJ"))]
975 "register_operand (operands[0], QImode)
976 || register_operand (operands[1], QImode)
977 || operands[1] == const0_rtx"
983 [(set_attr "type" "move,move,load,store")
984 (set_attr "length" "*,1,*,1")])
987 [(set (match_operand:QI 0 "register_operand" "=r")
988 (subreg:QI (lo_sum:SI (match_operand:QI 1 "register_operand" "r")
989 (match_operand 2 "immediate_operand" "in")) 0))]
992 [(set_attr "length" "1")])
995 [(set (mem:QI (match_operand:SI 0 "symbolic_operand" ""))
996 (match_operand:QI 1 "reg_or_0_operand" "rJ"))
997 (clobber (match_scratch:SI 2 "=&r"))]
999 "sethi %%hi(%a0),%2\;stb %r1,[%2+%%lo(%a0)]"
1000 [(set_attr "type" "store")
1001 (set_attr "length" "2")])
1003 ;; The definition of this insn does not really explain what it does,
1004 ;; but it should suffice
1005 ;; that anything generated as this insn will be recognized as one
1006 ;; and that it will not successfully combine with anything.
1007 (define_expand "movstrsi"
1008 [(parallel [(set (mem:BLK (match_operand:BLK 0 "general_operand" ""))
1009 (mem:BLK (match_operand:BLK 1 "general_operand" "")))
1010 (use (match_operand:SI 2 "nonmemory_operand" ""))
1011 (use (match_operand:SI 3 "immediate_operand" ""))
1012 (clobber (match_dup 0))
1013 (clobber (match_dup 1))
1014 (clobber (match_scratch:SI 4 ""))
1015 (clobber (reg:SI 0))
1016 (clobber (reg:SI 1))])]
1020 /* If the size isn't known, don't emit inline code. output_block_move
1021 would output code that's much slower than the library function.
1022 Also don't output code for large blocks. */
1023 if (GET_CODE (operands[2]) != CONST_INT
1024 || GET_CODE (operands[3]) != CONST_INT
1025 || INTVAL (operands[2]) / INTVAL (operands[3]) > 16)
1028 operands[0] = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
1029 operands[1] = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
1030 operands[2] = force_not_mem (operands[2]);
1034 [(set (mem:BLK (match_operand:SI 0 "register_operand" "r"))
1035 (mem:BLK (match_operand:SI 1 "register_operand" "r")))
1036 (use (match_operand:SI 2 "nonmemory_operand" "rn"))
1037 (use (match_operand:SI 3 "immediate_operand" "i"))
1038 (clobber (match_dup 0))
1039 (clobber (match_dup 1))
1040 (clobber (match_scratch:SI 4 "=&r"))
1041 (clobber (reg:SI 0))
1042 (clobber (reg:SI 1))]
1044 "* return output_block_move (operands);"
1045 [(set_attr "type" "multi")
1046 (set_attr "length" "6")])
1048 ;; Floating point move insns
1050 ;; This pattern forces (set (reg:TF ...) (const_double ...))
1051 ;; to be reloaded by putting the constant into memory.
1052 ;; It must come before the more general movtf pattern.
1054 [(set (match_operand:TF 0 "general_operand" "=?r,f,o")
1055 (match_operand:TF 1 "" "?E,m,G"))]
1056 "GET_CODE (operands[1]) == CONST_DOUBLE"
1059 switch (which_alternative)
1062 return output_move_quad (operands);
1064 return output_fp_move_quad (operands);
1066 operands[1] = adj_offsettable_operand (operands[0], 4);
1067 operands[2] = adj_offsettable_operand (operands[0], 8);
1068 operands[3] = adj_offsettable_operand (operands[0], 12);
1069 return \"st %%g0,%0\;st %%g0,%1\;st %%g0,%2\;st %%g0,%3\";
1072 [(set_attr "type" "load,fpload,store")
1073 (set_attr "length" "5,5,5")])
1075 (define_expand "movtf"
1076 [(set (match_operand:TF 0 "general_operand" "")
1077 (match_operand:TF 1 "general_operand" ""))]
1081 if (emit_move_sequence (operands, TFmode, 0))
1086 [(set (match_operand:TF 0 "reg_or_nonsymb_mem_operand" "=f,r,Q,Q,f,&r,?f,?r")
1087 (match_operand:TF 1 "reg_or_nonsymb_mem_operand" "f,r,f,r,Q,Q,r,f"))]
1088 "register_operand (operands[0], TFmode)
1089 || register_operand (operands[1], TFmode)"
1092 if (FP_REG_P (operands[0]) || FP_REG_P (operands[1]))
1093 return output_fp_move_quad (operands);
1094 return output_move_quad (operands);
1096 [(set_attr "type" "fp,move,fpstore,store,fpload,load,multi,multi")
1097 (set_attr "length" "4,4,5,5,5,5,5,5")])
1100 [(set (mem:TF (match_operand:SI 0 "symbolic_operand" "i,i"))
1101 (match_operand:TF 1 "reg_or_0_operand" "rf,G"))
1102 (clobber (match_scratch:SI 2 "=&r,&r"))]
1106 output_asm_insn (\"sethi %%hi(%a0),%2\", operands);
1107 if (which_alternative == 0)
1108 return \"std %1,[%2+%%lo(%a0)]\;std %S1,[%2+%%lo(%a0+8)]\";
1110 return \"st %%g0,[%2+%%lo(%a0)]\;st %%g0,[%2+%%lo(%a0+4)]\; st %%g0,[%2+%%lo(%a0+8)]\;st %%g0,[%2+%%lo(%a0+12)]\";
1112 [(set_attr "type" "store")
1113 (set_attr "length" "5")])
1115 ;; This pattern forces (set (reg:DF ...) (const_double ...))
1116 ;; to be reloaded by putting the constant into memory.
1117 ;; It must come before the more general movdf pattern.
1118 ;; ??? A similar pattern for SF mode values would also be useful, but it
1119 ;; is not as easy to write.
1121 [(set (match_operand:DF 0 "general_operand" "=?r,f,o")
1122 (match_operand:DF 1 "" "?E,m,G"))]
1123 "GET_CODE (operands[1]) == CONST_DOUBLE"
1126 switch (which_alternative)
1129 return output_move_double (operands);
1131 return output_fp_move_double (operands);
1133 operands[1] = adj_offsettable_operand (operands[0], 4);
1134 return \"st %%g0,%0\;st %%g0,%1\";
1137 [(set_attr "type" "load,fpload,store")
1138 (set_attr "length" "3,3,3")])
1140 (define_expand "movdf"
1141 [(set (match_operand:DF 0 "general_operand" "")
1142 (match_operand:DF 1 "general_operand" ""))]
1146 if (emit_move_sequence (operands, DFmode, 0))
1151 [(set (match_operand:DF 0 "reg_or_nonsymb_mem_operand" "=f,r,Q,Q,f,&r,?f,?r")
1152 (match_operand:DF 1 "reg_or_nonsymb_mem_operand" "f,r,f,r,Q,Q,r,f"))]
1153 "register_operand (operands[0], DFmode)
1154 || register_operand (operands[1], DFmode)"
1157 if (FP_REG_P (operands[0]) || FP_REG_P (operands[1]))
1158 return output_fp_move_double (operands);
1159 return output_move_double (operands);
1161 [(set_attr "type" "fp,move,fpstore,store,fpload,load,multi,multi")
1162 (set_attr "length" "2,2,3,3,3,3,3,3")])
1165 [(set (mem:DF (match_operand:SI 0 "symbolic_operand" "i,i"))
1166 (match_operand:DF 1 "reg_or_0_operand" "rf,G"))
1167 (clobber (match_scratch:SI 2 "=&r,&r"))]
1171 output_asm_insn (\"sethi %%hi(%a0),%2\", operands);
1172 if (which_alternative == 0)
1173 return \"std %1,[%2+%%lo(%a0)]\";
1175 return \"st %%g0,[%2+%%lo(%a0)]\;st %%g0,[%2+%%lo(%a0+4)]\";
1177 [(set_attr "type" "store")
1178 (set_attr "length" "3")])
1180 ;; Double-word move insns.
1182 (define_expand "movdi"
1183 [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand" "")
1184 (match_operand:DI 1 "general_operand" ""))]
1188 if (emit_move_sequence (operands, DImode, 0))
1193 [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand" "=r,Q,&r,&r,?f,?f,?f,?r,?Q")
1194 (match_operand:DI 1 "general_operand" "r,r,Q,i,r,f,Q,f,f"))]
1195 "register_operand (operands[0], DImode)
1196 || register_operand (operands[1], DImode)
1197 || operands[1] == const0_rtx"
1200 if (FP_REG_P (operands[0]) || FP_REG_P (operands[1]))
1201 return output_fp_move_double (operands);
1202 return output_move_double (operands);
1204 [(set_attr "type" "move,store,load,multi,multi,fp,fpload,multi,fpstore")
1205 (set_attr "length" "2,3,3,3,3,2,3,3,3")])
1207 ;; Floating-point move insns.
1209 (define_expand "movsf"
1210 [(set (match_operand:SF 0 "general_operand" "")
1211 (match_operand:SF 1 "general_operand" ""))]
1215 if (emit_move_sequence (operands, SFmode, 0))
1220 [(set (match_operand:SF 0 "reg_or_nonsymb_mem_operand" "=f,r,rf,f,r,Q,Q")
1221 (match_operand:SF 1 "reg_or_nonsymb_mem_operand" "f,r,!rf,Q,Q,f,r"))]
1222 "register_operand (operands[0], SFmode)
1223 || register_operand (operands[1], SFmode)"
1227 st %r1,[%%fp-4]\;ld [%%fp-4],%0
1232 [(set_attr "type" "fp,move,multi,fpload,load,fpstore,store")])
1235 [(set (mem:SF (match_operand:SI 0 "symbolic_operand" "i"))
1236 (match_operand:SF 1 "reg_or_0_operand" "rfG"))
1237 (clobber (match_scratch:SI 2 "=&r"))]
1239 "sethi %%hi(%a0),%2\;st %r1,[%2+%%lo(%a0)]"
1240 [(set_attr "type" "store")
1241 (set_attr "length" "2")])
1243 ;;- zero extension instructions
1245 ;; These patterns originally accepted general_operands, however, slightly
1246 ;; better code is generated by only accepting register_operands, and then
1247 ;; letting combine generate the ldu[hb] insns.
1249 (define_expand "zero_extendhisi2"
1250 [(set (match_operand:SI 0 "register_operand" "")
1251 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
1255 rtx temp = gen_reg_rtx (SImode);
1256 rtx shift_16 = gen_rtx (CONST_INT, VOIDmode, 16);
1258 if (GET_CODE (operand1) == SUBREG)
1259 operand1 = XEXP (operand1, 0);
1261 emit_insn (gen_ashlsi3 (temp, gen_rtx (SUBREG, SImode, operand1, 0),
1263 emit_insn (gen_lshrsi3 (operand0, temp, shift_16));
1268 [(set (match_operand:SI 0 "register_operand" "=r")
1269 (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
1272 [(set_attr "type" "load")])
1274 (define_expand "zero_extendqihi2"
1275 [(set (match_operand:HI 0 "register_operand" "")
1276 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
1281 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
1282 (zero_extend:HI (match_operand:QI 1 "sparc_operand" "r,I,Q")))]
1283 "GET_CODE (operands[1]) != CONST_INT"
1288 [(set_attr "type" "unary,move,load")
1289 (set_attr "length" "1")])
1291 (define_expand "zero_extendqisi2"
1292 [(set (match_operand:SI 0 "register_operand" "")
1293 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
1298 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
1299 (zero_extend:SI (match_operand:QI 1 "sparc_operand" "r,I,Q")))]
1300 "GET_CODE (operands[1]) != CONST_INT"
1305 [(set_attr "type" "unary,move,load")
1306 (set_attr "length" "1")])
1310 (compare:CC (zero_extend:SI (match_operand:QI 0 "register_operand" "r"))
1313 "andcc %0,0xff,%%g0"
1314 [(set_attr "type" "compare")])
1318 (compare:CC (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
1320 (set (match_operand:SI 0 "register_operand" "=r")
1321 (zero_extend:SI (match_dup 1)))]
1324 [(set_attr "type" "unary")])
1326 ;;- sign extension instructions
1328 ;; These patterns originally accepted general_operands, however, slightly
1329 ;; better code is generated by only accepting register_operands, and then
1330 ;; letting combine generate the lds[hb] insns.
1332 (define_expand "extendhisi2"
1333 [(set (match_operand:SI 0 "register_operand" "")
1334 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
1338 rtx temp = gen_reg_rtx (SImode);
1339 rtx shift_16 = gen_rtx (CONST_INT, VOIDmode, 16);
1341 if (GET_CODE (operand1) == SUBREG)
1342 operand1 = XEXP (operand1, 0);
1344 emit_insn (gen_ashlsi3 (temp, gen_rtx (SUBREG, SImode, operand1, 0),
1346 emit_insn (gen_ashrsi3 (operand0, temp, shift_16));
1351 [(set (match_operand:SI 0 "register_operand" "=r")
1352 (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
1355 [(set_attr "type" "load")])
1357 (define_expand "extendqihi2"
1358 [(set (match_operand:HI 0 "register_operand" "")
1359 (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
1363 rtx temp = gen_reg_rtx (SImode);
1364 rtx shift_24 = gen_rtx (CONST_INT, VOIDmode, 24);
1366 if (GET_CODE (operand1) == SUBREG)
1367 operand1 = XEXP (operand1, 0);
1368 if (GET_CODE (operand0) == SUBREG)
1369 operand0 = XEXP (operand0, 0);
1370 emit_insn (gen_ashlsi3 (temp, gen_rtx (SUBREG, SImode, operand1, 0),
1372 if (GET_MODE (operand0) != SImode)
1373 operand0 = gen_rtx (SUBREG, SImode, operand0, 0);
1374 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
1379 [(set (match_operand:HI 0 "register_operand" "=r")
1380 (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
1383 [(set_attr "type" "load")])
1385 (define_expand "extendqisi2"
1386 [(set (match_operand:SI 0 "register_operand" "")
1387 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
1391 rtx temp = gen_reg_rtx (SImode);
1392 rtx shift_24 = gen_rtx (CONST_INT, VOIDmode, 24);
1394 if (GET_CODE (operand1) == SUBREG)
1395 operand1 = XEXP (operand1, 0);
1396 emit_insn (gen_ashlsi3 (temp, gen_rtx (SUBREG, SImode, operand1, 0),
1398 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
1403 [(set (match_operand:SI 0 "register_operand" "=r")
1404 (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
1407 [(set_attr "type" "load")])
1409 ;; Special pattern for optimizing bit-field compares. This is needed
1410 ;; because combine uses this as a canonical form.
1415 (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
1416 (match_operand:SI 1 "small_int" "n")
1417 (match_operand:SI 2 "small_int" "n"))
1419 "INTVAL (operands[2]) > 19"
1422 int len = INTVAL (operands[1]);
1423 int pos = 32 - INTVAL (operands[2]) - len;
1424 unsigned mask = ((1 << len) - 1) << pos;
1426 operands[1] = gen_rtx (CONST_INT, VOIDmode, mask);
1427 return \"andcc %0,%1,%%g0\";
1430 ;; Conversions between float, double and long double.
1432 (define_insn "extendsfdf2"
1433 [(set (match_operand:DF 0 "register_operand" "=f")
1435 (match_operand:SF 1 "register_operand" "f")))]
1438 [(set_attr "type" "fp")])
1440 (define_insn "extendsftf2"
1441 [(set (match_operand:TF 0 "register_operand" "=f")
1443 (match_operand:SF 1 "register_operand" "f")))]
1446 [(set_attr "type" "fp")])
1448 (define_insn "extenddftf2"
1449 [(set (match_operand:TF 0 "register_operand" "=f")
1451 (match_operand:DF 1 "register_operand" "f")))]
1454 [(set_attr "type" "fp")])
1456 (define_insn "truncdfsf2"
1457 [(set (match_operand:SF 0 "register_operand" "=f")
1459 (match_operand:DF 1 "register_operand" "f")))]
1462 [(set_attr "type" "fp")])
1464 (define_insn "trunctfsf2"
1465 [(set (match_operand:SF 0 "register_operand" "=f")
1467 (match_operand:TF 1 "register_operand" "f")))]
1470 [(set_attr "type" "fp")])
1472 (define_insn "trunctfdf2"
1473 [(set (match_operand:DF 0 "register_operand" "=f")
1475 (match_operand:TF 1 "register_operand" "f")))]
1478 [(set_attr "type" "fp")])
1480 ;; Conversion between fixed point and floating point.
1482 (define_insn "floatsisf2"
1483 [(set (match_operand:SF 0 "general_operand" "=f")
1484 (float:SF (match_operand:SI 1 "nonimmediate_operand" "rfm")))]
1486 "* return output_floatsisf2 (operands);"
1487 [(set_attr "type" "fp")
1488 (set_attr "length" "3")])
1490 (define_insn "floatsidf2"
1491 [(set (match_operand:DF 0 "general_operand" "=f")
1492 (float:DF (match_operand:SI 1 "nonimmediate_operand" "rfm")))]
1494 "* return output_floatsidf2 (operands);"
1495 [(set_attr "type" "fp")
1496 (set_attr "length" "3")])
1498 (define_insn "floatsitf2"
1499 [(set (match_operand:TF 0 "general_operand" "=f")
1500 (float:TF (match_operand:SI 1 "nonimmediate_operand" "rfm")))]
1502 "* return output_floatsitf2 (operands);"
1503 [(set_attr "type" "fp")
1504 (set_attr "length" "3")])
1506 ;; Convert a float to an actual integer.
1507 ;; Truncation is performed as part of the conversion.
1509 (define_insn "fix_truncsfsi2"
1510 [(set (match_operand:SI 0 "general_operand" "=rm")
1511 (fix:SI (fix:SF (match_operand:SF 1 "general_operand" "fm"))))
1512 (clobber (match_scratch:SF 2 "=&f"))]
1516 if (FP_REG_P (operands[1]))
1517 output_asm_insn (\"fstoi %1,%2\", operands);
1519 output_asm_insn (\"ld %1,%2\;fstoi %2,%2\", operands);
1520 if (GET_CODE (operands[0]) == MEM)
1521 return \"st %2,%0\";
1523 return \"st %2,[%%fp-4]\;ld [%%fp-4],%0\";
1525 [(set_attr "type" "fp")
1526 (set_attr "length" "3")])
1528 (define_insn "fix_truncdfsi2"
1529 [(set (match_operand:SI 0 "general_operand" "=rm")
1530 (fix:SI (fix:DF (match_operand:DF 1 "general_operand" "fm"))))
1531 (clobber (match_scratch:DF 2 "=&f"))]
1535 if (FP_REG_P (operands[1]))
1536 output_asm_insn (\"fdtoi %1,%2\", operands);
1540 xoperands[0] = operands[2];
1541 xoperands[1] = operands[1];
1542 output_asm_insn (output_fp_move_double (xoperands), xoperands);
1543 output_asm_insn (\"fdtoi %2,%2\", operands);
1545 if (GET_CODE (operands[0]) == MEM)
1546 return \"st %2,%0\";
1548 return \"st %2,[%%fp-4]\;ld [%%fp-4],%0\";
1550 [(set_attr "type" "fp")
1551 (set_attr "length" "3")])
1553 (define_insn "fix_trunctfsi2"
1554 [(set (match_operand:SI 0 "general_operand" "=rm")
1555 (fix:SI (fix:TF (match_operand:TF 1 "general_operand" "fm"))))
1556 (clobber (match_scratch:DF 2 "=&f"))]
1560 if (FP_REG_P (operands[1]))
1561 output_asm_insn (\"fqtoi %1,%2\", operands);
1565 xoperands[0] = operands[2];
1566 xoperands[1] = operands[1];
1567 output_asm_insn (output_fp_move_quad (xoperands), xoperands);
1568 output_asm_insn (\"fqtoi %2,%2\", operands);
1570 if (GET_CODE (operands[0]) == MEM)
1571 return \"st %2,%0\";
1573 return \"st %2,[%%fp-4]\;ld [%%fp-4],%0\";
1575 [(set_attr "type" "fp")
1576 (set_attr "length" "3")])
1578 ;; Allow combiner to combine a fix_trunctfsi2 with a floatsitf2
1579 ;; This eliminates 2 useless instructions.
1580 ;; The first one matches if the fixed result is needed. The second one
1581 ;; matches if the fixed result is not needed.
1584 [(set (match_operand:TF 0 "general_operand" "=f")
1585 (float:TF (fix:SI (fix:TF (match_operand:TF 1 "general_operand" "fm")))))
1586 (set (match_operand:SI 2 "general_operand" "=rm")
1587 (fix:SI (fix:TF (match_dup 1))))]
1591 if (FP_REG_P (operands[1]))
1592 output_asm_insn (\"fqtoi %1,%0\", operands);
1595 output_asm_insn (output_fp_move_quad (operands), operands);
1596 output_asm_insn (\"fqtoi %0,%0\", operands);
1598 if (GET_CODE (operands[2]) == MEM)
1599 return \"st %0,%2\;fitoq %0,%0\";
1601 return \"st %0,[%%fp-4]\;fitoq %0,%0\;ld [%%fp-4],%2\";
1603 [(set_attr "type" "fp")
1604 (set_attr "length" "5")])
1607 [(set (match_operand:TF 0 "general_operand" "=f")
1608 (float:TF (fix:SI (fix:TF (match_operand:TF 1 "general_operand" "fm")))))]
1612 if (FP_REG_P (operands[1]))
1613 output_asm_insn (\"fqtoi %1,%0\", operands);
1616 output_asm_insn (output_fp_move_quad (operands), operands);
1617 output_asm_insn (\"fqtoi %0,%0\", operands);
1619 return \"fitoq %0,%0\";
1621 [(set_attr "type" "fp")
1622 (set_attr "length" "3")])
1624 ;; Allow combiner to combine a fix_truncdfsi2 with a floatsidf2
1625 ;; This eliminates 2 useless instructions.
1626 ;; The first one matches if the fixed result is needed. The second one
1627 ;; matches if the fixed result is not needed.
1630 [(set (match_operand:DF 0 "general_operand" "=f")
1631 (float:DF (fix:SI (fix:DF (match_operand:DF 1 "general_operand" "fm")))))
1632 (set (match_operand:SI 2 "general_operand" "=rm")
1633 (fix:SI (fix:DF (match_dup 1))))]
1637 if (FP_REG_P (operands[1]))
1638 output_asm_insn (\"fdtoi %1,%0\", operands);
1641 output_asm_insn (output_fp_move_double (operands), operands);
1642 output_asm_insn (\"fdtoi %0,%0\", operands);
1644 if (GET_CODE (operands[2]) == MEM)
1645 return \"st %0,%2\;fitod %0,%0\";
1647 return \"st %0,[%%fp-4]\;fitod %0,%0\;ld [%%fp-4],%2\";
1649 [(set_attr "type" "fp")
1650 (set_attr "length" "5")])
1653 [(set (match_operand:DF 0 "general_operand" "=f")
1654 (float:DF (fix:SI (fix:DF (match_operand:DF 1 "general_operand" "fm")))))]
1658 if (FP_REG_P (operands[1]))
1659 output_asm_insn (\"fdtoi %1,%0\", operands);
1662 output_asm_insn (output_fp_move_double (operands), operands);
1663 output_asm_insn (\"fdtoi %0,%0\", operands);
1665 return \"fitod %0,%0\";
1667 [(set_attr "type" "fp")
1668 (set_attr "length" "3")])
1670 ;; Allow combiner to combine a fix_truncsfsi2 with a floatsisf2
1671 ;; This eliminates 2 useless instructions.
1672 ;; The first one matches if the fixed result is needed. The second one
1673 ;; matches if the fixed result is not needed.
1676 [(set (match_operand:SF 0 "general_operand" "=f")
1677 (float:SF (fix:SI (fix:SF (match_operand:SF 1 "general_operand" "fm")))))
1678 (set (match_operand:SI 2 "general_operand" "=rm")
1679 (fix:SI (fix:SF (match_dup 1))))]
1683 if (FP_REG_P (operands[1]))
1684 output_asm_insn (\"fstoi %1,%0\", operands);
1686 output_asm_insn (\"ld %1,%0\;fstoi %0,%0\", operands);
1687 if (GET_CODE (operands[2]) == MEM)
1688 return \"st %0,%2\;fitos %0,%0\";
1690 return \"st %0,[%%fp-4]\;fitos %0,%0\;ld [%%fp-4],%2\";
1692 [(set_attr "type" "fp")
1693 (set_attr "length" "5")])
1696 [(set (match_operand:SF 0 "general_operand" "=f")
1697 (float:SF (fix:SI (fix:SF (match_operand:SF 1 "general_operand" "fm")))))]
1701 if (FP_REG_P (operands[1]))
1702 output_asm_insn (\"fstoi %1,%0\", operands);
1704 output_asm_insn (\"ld %1,%0\;fstoi %0,%0\", operands);
1705 return \"fitos %0,%0\";
1707 [(set_attr "type" "fp")
1708 (set_attr "length" "3")])
1710 ;;- arithmetic instructions
1712 (define_insn "adddi3"
1713 [(set (match_operand:DI 0 "register_operand" "=r")
1714 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
1715 (match_operand:DI 2 "arith_double_operand" "rHI")))
1716 (clobber (reg:SI 0))]
1720 rtx op2 = operands[2];
1722 /* If constant is positive, upper bits zeroed, otherwise unchanged.
1723 Give the assembler a chance to pick the move instruction. */
1724 if (GET_CODE (op2) == CONST_INT)
1726 int sign = INTVAL (op2);
1728 return \"addcc %R1,%2,%R0\;addx %1,-1,%0\";
1729 return \"addcc %R1,%2,%R0\;addx %1,0,%0\";
1731 else if (GET_CODE (op2) == CONST_DOUBLE)
1733 int sign = CONST_DOUBLE_HIGH (op2);
1734 operands[2] = gen_rtx (CONST_INT, VOIDmode,
1735 CONST_DOUBLE_LOW (operands[1]));
1737 return \"addcc %R1,%2,%R0\;addx %1,-1,%0\";
1738 return \"addcc %R1,%2,%R0\;addx %1,0,%0\";
1740 return \"addcc %R1,%R2,%R0\;addx %1,%2,%0\";
1742 [(set_attr "length" "2")])
1744 (define_insn "addsi3"
1745 [(set (match_operand:SI 0 "register_operand" "=r")
1746 (plus:SI (match_operand:SI 1 "arith_operand" "%r")
1747 (match_operand:SI 2 "arith_operand" "rI")))]
1752 [(set (reg:CC_NOOV 0)
1753 (compare:CC_NOOV (plus:SI (match_operand:SI 0 "arith_operand" "%r")
1754 (match_operand:SI 1 "arith_operand" "rI"))
1758 [(set_attr "type" "compare")])
1761 [(set (reg:CC_NOOV 0)
1762 (compare:CC_NOOV (plus:SI (match_operand:SI 1 "arith_operand" "%r")
1763 (match_operand:SI 2 "arith_operand" "rI"))
1765 (set (match_operand:SI 0 "register_operand" "=r")
1766 (plus:SI (match_dup 1) (match_dup 2)))]
1770 (define_insn "subdi3"
1771 [(set (match_operand:DI 0 "register_operand" "=r")
1772 (minus:DI (match_operand:DI 1 "register_operand" "r")
1773 (match_operand:DI 2 "arith_double_operand" "rHI")))
1774 (clobber (reg:SI 0))]
1778 rtx op2 = operands[2];
1780 /* If constant is positive, upper bits zeroed, otherwise unchanged.
1781 Give the assembler a chance to pick the move instruction. */
1782 if (GET_CODE (op2) == CONST_INT)
1784 int sign = INTVAL (op2);
1786 return \"subcc %R1,%2,%R0\;subx %1,-1,%0\";
1787 return \"subcc %R1,%2,%R0\;subx %1,0,%0\";
1789 else if (GET_CODE (op2) == CONST_DOUBLE)
1791 int sign = CONST_DOUBLE_HIGH (op2);
1792 operands[2] = gen_rtx (CONST_INT, VOIDmode,
1793 CONST_DOUBLE_LOW (operands[1]));
1795 return \"subcc %R1,%2,%R0\;subx %1,-1,%0\";
1796 return \"subcc %R1,%2,%R0\;subx %1,0,%0\";
1798 return \"subcc %R1,%R2,%R0\;subx %1,%2,%0\";
1800 [(set_attr "length" "2")])
1802 (define_insn "subsi3"
1803 [(set (match_operand:SI 0 "register_operand" "=r")
1804 (minus:SI (match_operand:SI 1 "register_operand" "r")
1805 (match_operand:SI 2 "arith_operand" "rI")))]
1810 [(set (reg:CC_NOOV 0)
1811 (compare:CC_NOOV (minus:SI (match_operand:SI 0 "register_operand" "r")
1812 (match_operand:SI 1 "arith_operand" "rI"))
1816 [(set_attr "type" "compare")])
1819 [(set (reg:CC_NOOV 0)
1820 (compare:CC_NOOV (minus:SI (match_operand:SI 1 "register_operand" "r")
1821 (match_operand:SI 2 "arith_operand" "rI"))
1823 (set (match_operand:SI 0 "register_operand" "=r")
1824 (minus:SI (match_dup 1) (match_dup 2)))]
1828 ;;- and instructions
1829 ;; We define DImode `and` so with DImode `not` we can get
1830 ;; DImode `andn`. Other combinations are possible.
1832 (define_expand "anddi3"
1833 [(set (match_operand:DI 0 "register_operand" "")
1834 (and:DI (match_operand:DI 1 "arith_double_operand" "")
1835 (match_operand:DI 2 "arith_double_operand" "")))]
1840 [(set (match_operand:DI 0 "register_operand" "=r")
1841 (and:DI (match_operand:DI 1 "arith_double_operand" "%r")
1842 (match_operand:DI 2 "arith_double_operand" "rHI")))]
1846 rtx op2 = operands[2];
1848 /* If constant is positive, upper bits zeroed, otherwise unchanged.
1849 Give the assembler a chance to pick the move instruction. */
1850 if (GET_CODE (op2) == CONST_INT)
1852 int sign = INTVAL (op2);
1854 return \"mov %1,%0\;and %R1,%2,%R0\";
1855 return \"mov 0,%0\;and %R1,%2,%R0\";
1857 else if (GET_CODE (op2) == CONST_DOUBLE)
1859 int sign = CONST_DOUBLE_HIGH (op2);
1860 operands[2] = gen_rtx (CONST_INT, VOIDmode,
1861 CONST_DOUBLE_LOW (operands[1]));
1863 return \"mov %1,%0\;and %R1,%2,%R0\";
1864 return \"mov 0,%0\;and %R1,%2,%R0\";
1866 return \"and %1,%2,%0\;and %R1,%R2,%R0\";
1868 [(set_attr "length" "2")])
1870 (define_insn "andsi3"
1871 [(set (match_operand:SI 0 "register_operand" "=r")
1872 (and:SI (match_operand:SI 1 "arith_operand" "%r")
1873 (match_operand:SI 2 "arith_operand" "rI")))]
1878 [(set (match_operand:DI 0 "register_operand" "=r")
1879 (and:DI (not:DI (match_operand:DI 1 "register_operand" "r"))
1880 (match_operand:DI 2 "register_operand" "r")))]
1882 "andn %2,%1,%0\;andn %R2,%R1,%R0"
1883 [(set_attr "length" "2")])
1886 [(set (match_operand:SI 0 "register_operand" "=r")
1887 (and:SI (not:SI (match_operand:SI 1 "register_operand" "r"))
1888 (match_operand:SI 2 "register_operand" "r")))]
1892 (define_expand "iordi3"
1893 [(set (match_operand:DI 0 "register_operand" "")
1894 (ior:DI (match_operand:DI 1 "arith_double_operand" "")
1895 (match_operand:DI 2 "arith_double_operand" "")))]
1900 [(set (match_operand:DI 0 "register_operand" "=r")
1901 (ior:DI (match_operand:DI 1 "arith_double_operand" "%r")
1902 (match_operand:DI 2 "arith_double_operand" "rHI")))]
1906 rtx op2 = operands[2];
1908 /* If constant is positive, upper bits zeroed, otherwise unchanged.
1909 Give the assembler a chance to pick the move instruction. */
1910 if (GET_CODE (op2) == CONST_INT)
1912 int sign = INTVAL (op2);
1914 return \"mov -1,%0\;or %R1,%2,%R0\";
1915 return \"mov %1,%0\;or %R1,%2,%R0\";
1917 else if (GET_CODE (op2) == CONST_DOUBLE)
1919 int sign = CONST_DOUBLE_HIGH (op2);
1920 operands[2] = gen_rtx (CONST_INT, VOIDmode,
1921 CONST_DOUBLE_LOW (operands[1]));
1923 return \"mov -1,%0\;or %R1,%2,%R0\";
1924 return \"mov %1,%0\;or %R1,%2,%R0\";
1926 return \"or %1,%2,%0\;or %R1,%R2,%R0\";
1928 [(set_attr "length" "2")])
1930 (define_insn "iorsi3"
1931 [(set (match_operand:SI 0 "register_operand" "=r")
1932 (ior:SI (match_operand:SI 1 "arith_operand" "%r")
1933 (match_operand:SI 2 "arith_operand" "rI")))]
1938 [(set (match_operand:DI 0 "register_operand" "=r")
1939 (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r"))
1940 (match_operand:DI 2 "register_operand" "r")))]
1942 "orn %2,%1,%0\;orn %R2,%R1,%R0"
1943 [(set_attr "length" "2")])
1946 [(set (match_operand:SI 0 "register_operand" "=r")
1947 (ior:SI (not:SI (match_operand:SI 1 "register_operand" "r"))
1948 (match_operand:SI 2 "register_operand" "r")))]
1952 (define_expand "xordi3"
1953 [(set (match_operand:DI 0 "register_operand" "")
1954 (xor:DI (match_operand:DI 1 "arith_double_operand" "")
1955 (match_operand:DI 2 "arith_double_operand" "")))]
1960 [(set (match_operand:DI 0 "register_operand" "=r")
1961 (xor:DI (match_operand:DI 1 "arith_double_operand" "%r")
1962 (match_operand:DI 2 "arith_double_operand" "rHI")))]
1966 rtx op2 = operands[2];
1968 /* If constant is positive, upper bits zeroed, otherwise unchanged.
1969 Give the assembler a chance to pick the move instruction. */
1970 if (GET_CODE (op2) == CONST_INT)
1972 int sign = INTVAL (op2);
1974 return \"xor %1,-1,%0\;xor %R1,%2,%R0\";
1975 return \"mov %1,%0\;xor %R1,%2,%R0\";
1977 else if (GET_CODE (op2) == CONST_DOUBLE)
1979 int sign = CONST_DOUBLE_HIGH (op2);
1980 operands[2] = gen_rtx (CONST_INT, VOIDmode,
1981 CONST_DOUBLE_LOW (operands[1]));
1983 return \"xor %1,-1,%0\;xor %R1,%2,%R0\";
1984 return \"mov %1,%0\;xor %R1,%2,%R0\";
1986 return \"xor %1,%2,%0\;xor %R1,%R2,%R0\";
1988 [(set_attr "length" "2")])
1990 (define_insn "xorsi3"
1991 [(set (match_operand:SI 0 "register_operand" "=r")
1992 (xor:SI (match_operand:SI 1 "arith_operand" "%rJ")
1993 (match_operand:SI 2 "arith_operand" "rI")))]
1997 ;; xnor patterns. Note that (a ^ ~b) == (~a ^ b) == ~(a ^ b).
1998 ;; Combine now canonicalizes to the rightmost expression.
2000 [(set (match_operand:DI 0 "register_operand" "=r")
2001 (not:DI (xor:DI (match_operand:DI 1 "register_operand" "r")
2002 (match_operand:DI 2 "register_operand" "r"))))]
2004 "xnor %1,%2,%0\;xnor %R1,%R2,%R0"
2005 [(set_attr "length" "2")])
2008 [(set (match_operand:SI 0 "register_operand" "=r")
2009 (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
2010 (match_operand:SI 2 "arith_operand" "rI"))))]
2014 ;; These correspond to the above in the case where we also (or only)
2015 ;; want to set the condition code.
2020 (match_operator:SI 2 "cc_arithop"
2021 [(match_operand:SI 0 "arith_operand" "%r")
2022 (match_operand:SI 1 "arith_operand" "rI")])
2026 [(set_attr "type" "compare")])
2031 (match_operator:SI 3 "cc_arithop"
2032 [(match_operand:SI 1 "arith_operand" "%r")
2033 (match_operand:SI 2 "arith_operand" "rI")])
2035 (set (match_operand:SI 0 "register_operand" "=r")
2043 (not:SI (xor:SI (match_operand:SI 0 "reg_or_0_operand" "%rJ")
2044 (match_operand:SI 1 "arith_operand" "rI")))
2047 "xnorcc %r0,%1,%%g0"
2048 [(set_attr "type" "compare")])
2053 (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
2054 (match_operand:SI 2 "arith_operand" "rI")))
2056 (set (match_operand:SI 0 "register_operand" "=r")
2057 (not:SI (xor:SI (match_dup 1) (match_dup 2))))]
2064 (match_operator:SI 2 "cc_arithopn"
2065 [(not:SI (match_operand:SI 0 "arith_operand" "rI"))
2066 (match_operand:SI 1 "reg_or_0_operand" "rJ")])
2070 [(set_attr "type" "compare")])
2075 (match_operator:SI 3 "cc_arithopn"
2076 [(not:SI (match_operand:SI 1 "arith_operand" "rI"))
2077 (match_operand:SI 2 "reg_or_0_operand" "rJ")])
2079 (set (match_operand:SI 0 "register_operand" "=r")
2084 ;; We cannot use the "neg" pseudo insn because the Sun assembler
2085 ;; does not know how to make it work for constants.
2087 (define_insn "negdi2"
2088 [(set (match_operand:DI 0 "register_operand" "=r")
2089 (neg:DI (match_operand:DI 1 "register_operand" "r")))
2090 (clobber (reg:SI 0))]
2092 "subcc %%g0,%R1,%R0\;subx %%g0,%1,%0"
2093 [(set_attr "type" "unary")
2094 (set_attr "length" "2")])
2096 (define_insn "negsi2"
2097 [(set (match_operand:SI 0 "general_operand" "=r")
2098 (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
2101 [(set_attr "type" "unary")])
2104 [(set (reg:CC_NOOV 0)
2105 (compare:CC_NOOV (neg:SI (match_operand:SI 0 "arith_operand" "rI"))
2108 "subcc %%g0,%0,%%g0"
2109 [(set_attr "type" "compare")])
2112 [(set (reg:CC_NOOV 0)
2113 (compare:CC_NOOV (neg:SI (match_operand:SI 1 "arith_operand" "rI"))
2115 (set (match_operand:SI 0 "register_operand" "=r")
2116 (neg:SI (match_dup 1)))]
2119 [(set_attr "type" "unary")])
2121 ;; We cannot use the "not" pseudo insn because the Sun assembler
2122 ;; does not know how to make it work for constants.
2123 (define_expand "one_cmpldi2"
2124 [(set (match_operand:DI 0 "register_operand" "=r")
2125 (not:DI (match_operand:DI 1 "arith_double_operand" "rHI")))]
2130 [(set (match_operand:DI 0 "register_operand" "=r")
2131 (not:DI (match_operand:DI 1 "arith_double_operand" "rHI")))]
2135 rtx op1 = operands[1];
2137 if (GET_CODE (op1) == CONST_INT)
2139 int sign = INTVAL (op1);
2141 return \"xnor %%g0,%1,%R0\;xnor %%g0,-1,%0\";
2142 return \"xnor %%g0,%1,%R0\;xnor %%g0,0,%0\";
2144 else if (GET_CODE (op1) == CONST_DOUBLE)
2146 int sign = CONST_DOUBLE_HIGH (op1);
2147 operands[1] = gen_rtx (CONST_INT, VOIDmode,
2148 CONST_DOUBLE_LOW (operands[1]));
2150 return \"xnor %%g0,%1,%R0\;xnor %%g0,-1,%0\";
2151 return \"xnor %%g0,%1,%R0\;xnor %%g0,0,%0\";
2153 return \"xnor %%g0,%1,%0\;xnor %%g0,%R1,%R0\";
2155 [(set_attr "type" "unary")
2156 (set_attr "length" "2")])
2158 (define_insn "one_cmplsi2"
2159 [(set (match_operand:SI 0 "register_operand" "=r")
2160 (not:SI (match_operand:SI 1 "arith_operand" "rI")))]
2163 [(set_attr "type" "unary")])
2167 (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI"))
2170 "xnorcc %%g0,%0,%%g0"
2171 [(set_attr "type" "compare")])
2175 (compare:CC (not:SI (match_operand:SI 1 "arith_operand" "rI"))
2177 (set (match_operand:SI 0 "register_operand" "=r")
2178 (not:SI (match_dup 1)))]
2181 [(set_attr "type" "unary")])
2183 ;; Floating point arithmetic instructions.
2185 (define_insn "addtf3"
2186 [(set (match_operand:TF 0 "register_operand" "=f")
2187 (plus:TF (match_operand:TF 1 "register_operand" "f")
2188 (match_operand:TF 2 "register_operand" "f")))]
2191 [(set_attr "type" "fp")])
2193 (define_insn "adddf3"
2194 [(set (match_operand:DF 0 "register_operand" "=f")
2195 (plus:DF (match_operand:DF 1 "register_operand" "f")
2196 (match_operand:DF 2 "register_operand" "f")))]
2199 [(set_attr "type" "fp")])
2201 (define_insn "addsf3"
2202 [(set (match_operand:SF 0 "register_operand" "=f")
2203 (plus:SF (match_operand:SF 1 "register_operand" "f")
2204 (match_operand:SF 2 "register_operand" "f")))]
2207 [(set_attr "type" "fp")])
2209 (define_insn "subtf3"
2210 [(set (match_operand:TF 0 "register_operand" "=f")
2211 (minus:TF (match_operand:TF 1 "register_operand" "f")
2212 (match_operand:TF 2 "register_operand" "f")))]
2215 [(set_attr "type" "fp")])
2217 (define_insn "subdf3"
2218 [(set (match_operand:DF 0 "register_operand" "=f")
2219 (minus:DF (match_operand:DF 1 "register_operand" "f")
2220 (match_operand:DF 2 "register_operand" "f")))]
2223 [(set_attr "type" "fp")])
2225 (define_insn "subsf3"
2226 [(set (match_operand:SF 0 "register_operand" "=f")
2227 (minus:SF (match_operand:SF 1 "register_operand" "f")
2228 (match_operand:SF 2 "register_operand" "f")))]
2231 [(set_attr "type" "fp")])
2233 (define_insn "multf3"
2234 [(set (match_operand:TF 0 "register_operand" "=f")
2235 (mult:TF (match_operand:TF 1 "register_operand" "f")
2236 (match_operand:TF 2 "register_operand" "f")))]
2239 [(set_attr "type" "fpmul")])
2241 (define_insn "muldf3"
2242 [(set (match_operand:DF 0 "register_operand" "=f")
2243 (mult:DF (match_operand:DF 1 "register_operand" "f")
2244 (match_operand:DF 2 "register_operand" "f")))]
2247 [(set_attr "type" "fpmul")])
2249 (define_insn "mulsf3"
2250 [(set (match_operand:SF 0 "register_operand" "=f")
2251 (mult:SF (match_operand:SF 1 "register_operand" "f")
2252 (match_operand:SF 2 "register_operand" "f")))]
2255 [(set_attr "type" "fpmul")])
2257 (define_insn "divtf3"
2258 [(set (match_operand:TF 0 "register_operand" "=f")
2259 (div:TF (match_operand:TF 1 "register_operand" "f")
2260 (match_operand:TF 2 "register_operand" "f")))]
2263 [(set_attr "type" "fpdiv")])
2265 (define_insn "divdf3"
2266 [(set (match_operand:DF 0 "register_operand" "=f")
2267 (div:DF (match_operand:DF 1 "register_operand" "f")
2268 (match_operand:DF 2 "register_operand" "f")))]
2271 [(set_attr "type" "fpdiv")])
2273 (define_insn "divsf3"
2274 [(set (match_operand:SF 0 "register_operand" "=f")
2275 (div:SF (match_operand:SF 1 "register_operand" "f")
2276 (match_operand:SF 2 "register_operand" "f")))]
2279 [(set_attr "type" "fpdiv")])
2281 (define_insn "negtf2"
2282 [(set (match_operand:TF 0 "register_operand" "=f,f")
2283 (neg:TF (match_operand:TF 1 "register_operand" "0,f")))]
2287 fnegs %1,%0\;fmovs %R1,%R0\;fmovs %S1,%S0\;fmovs %T1,%T0"
2288 [(set_attr "type" "fp")
2289 (set_attr "length" "1,4")])
2291 (define_insn "negdf2"
2292 [(set (match_operand:DF 0 "register_operand" "=f,f")
2293 (neg:DF (match_operand:DF 1 "register_operand" "0,f")))]
2297 fnegs %1,%0\;fmovs %R1,%R0"
2298 [(set_attr "type" "fp")
2299 (set_attr "length" "1,2")])
2301 (define_insn "negsf2"
2302 [(set (match_operand:SF 0 "register_operand" "=f")
2303 (neg:SF (match_operand:SF 1 "register_operand" "f")))]
2306 [(set_attr "type" "fp")])
2308 (define_insn "abstf2"
2309 [(set (match_operand:TF 0 "register_operand" "=f,f")
2310 (abs:TF (match_operand:TF 1 "register_operand" "0,f")))]
2314 fabss %1,%0\;fmovs %R1,%R0\;fmovs %S1,%S0\;fmovs %T1,%T0"
2315 [(set_attr "type" "fp")
2316 (set_attr "length" "1,4")])
2318 (define_insn "absdf2"
2319 [(set (match_operand:DF 0 "register_operand" "=f,f")
2320 (abs:DF (match_operand:DF 1 "register_operand" "0,f")))]
2324 fabss %1,%0\;fmovs %R1,%R0"
2325 [(set_attr "type" "fp")
2326 (set_attr "length" "1,2")])
2328 (define_insn "abssf2"
2329 [(set (match_operand:SF 0 "register_operand" "=f")
2330 (abs:SF (match_operand:SF 1 "register_operand" "f")))]
2333 [(set_attr "type" "fp")])
2335 (define_insn "sqrttf2"
2336 [(set (match_operand:TF 0 "register_operand" "=f")
2337 (sqrt:TF (match_operand:TF 1 "register_operand" "f")))]
2340 [(set_attr "type" "fpsqrt")])
2342 (define_insn "sqrtdf2"
2343 [(set (match_operand:DF 0 "register_operand" "=f")
2344 (sqrt:DF (match_operand:DF 1 "register_operand" "f")))]
2347 [(set_attr "type" "fpsqrt")])
2349 (define_insn "sqrtsf2"
2350 [(set (match_operand:SF 0 "register_operand" "=f")
2351 (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
2354 [(set_attr "type" "fpsqrt")])
2356 ;;- arithmetic shift instructions
2358 ;; We can trivially handle shifting the constant 1 by 64 bits.
2359 ;; For other shifts we use the library routine.
2360 ;; ??? Questionable, we can do better than this can't we?
2361 (define_expand "ashldi3"
2362 [(parallel [(set (match_operand:DI 0 "register_operand" "")
2363 (ashift:DI (match_operand:DI 1 "const_double_operand" "")
2364 (match_operand:SI 2 "register_operand" "")))
2365 (clobber (reg:SI 0))])]
2369 if (GET_CODE (operands[1]) == CONST_DOUBLE
2370 && CONST_DOUBLE_HIGH (operands[1]) == 0
2371 && CONST_DOUBLE_LOW (operands[1]) == 1)
2372 operands[1] = const1_rtx;
2373 else if (operands[1] != const1_rtx)
2377 ;; ??? Questionable, we can do better than this can't we?
2379 [(set (match_operand:DI 0 "register_operand" "=&r")
2380 (ashift:DI (const_int 1)
2381 (match_operand:SI 1 "register_operand" "r")))
2382 (clobber (reg:SI 0))]
2384 "subcc %1,32,%%g0\;addx %%g0,0,%R0\;xor %R0,1,%0\;sll %R0,%1,%R0\;sll %0,%1,%0"
2385 [(set_attr "type" "multi")
2386 (set_attr "length" "5")])
2388 (define_insn "ashlsi3"
2389 [(set (match_operand:SI 0 "register_operand" "=r")
2390 (ashift:SI (match_operand:SI 1 "register_operand" "r")
2391 (match_operand:SI 2 "arith_operand" "rI")))]
2395 (define_insn "ashrsi3"
2396 [(set (match_operand:SI 0 "register_operand" "=r")
2397 (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
2398 (match_operand:SI 2 "arith_operand" "rI")))]
2402 (define_insn "lshrsi3"
2403 [(set (match_operand:SI 0 "register_operand" "=r")
2404 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
2405 (match_operand:SI 2 "arith_operand" "rI")))]
2409 ;; Unconditional and other jump instructions
2410 ;; Note that for the Sparc, by setting the annul bit on an unconditional
2411 ;; branch, the following insn is never executed. This saves us a nop,
2412 ;; but requires a debugger which can handle annulled branches.
2414 [(set (pc) (label_ref (match_operand 0 "" "")))]
2417 [(set_attr "type" "branch")])
2419 (define_expand "tablejump"
2420 [(parallel [(set (pc) (match_operand:SI 0 "register_operand" "r"))
2421 (use (label_ref (match_operand 1 "" "")))])]
2425 /* We need to use the PC value in %o7 that was set up when the address
2426 of the label was loaded into a register, so we need different RTL. */
2429 emit_insn (gen_pic_tablejump (operands[0], operands[1]));
2434 (define_insn "pic_tablejump"
2435 [(set (pc) (match_operand:SI 0 "register_operand" "r"))
2436 (use (label_ref (match_operand 1 "" "")))
2440 [(set_attr "type" "branch")])
2443 [(set (pc) (match_operand:SI 0 "address_operand" "p"))
2444 (use (label_ref (match_operand 1 "" "")))]
2447 [(set_attr "type" "branch")])
2450 [(set (pc) (label_ref (match_operand 0 "" "")))
2451 (set (reg:SI 15) (label_ref (match_dup 0)))]
2454 [(set_attr "type" "branch")])
2456 ;; This pattern recognizes the "instruction" that appears in
2457 ;; a function call that wants a structure value,
2458 ;; to inform the called function if compiled with Sun CC.
2460 ; [(match_operand:SI 0 "immediate_operand" "")]
2461 ; "GET_CODE (operands[0]) == CONST_INT && INTVAL (operands[0]) > 0"
2463 ; [(set_attr "type" "marker")])
2465 ;;- jump to subroutine
2466 (define_expand "call"
2467 ;; Note that this expression is not used for generating RTL.
2468 ;; All the RTL is generated explicitly below.
2469 [(call (match_operand:SI 0 "call_operand" "")
2470 (match_operand 3 "" "i"))]
2471 ;; operands[2] is next_arg_register
2472 ;; operands[3] is struct_value_size_rtx.
2476 rtx fn_rtx, nregs_rtx;
2478 if (GET_CODE (XEXP (operands[0], 0)) == LABEL_REF)
2480 /* This is really a PIC sequence. We want to represent
2481 it as a funny jump so it's delay slots can be filled.
2483 ??? But if this really *is* a CALL, will not it clobber the
2484 call-clobbered registers? We lose this if it is a JUMP_INSN.
2485 Why cannot we have delay slots filled if it were a CALL? */
2487 if (INTVAL (operands[3]) > 0)
2488 emit_jump_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (3,
2489 gen_rtx (SET, VOIDmode, pc_rtx,
2490 XEXP (operands[0], 0)),
2492 gen_rtx (CLOBBER, VOIDmode,
2493 gen_rtx (REG, SImode, 15)))));
2495 emit_jump_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (2,
2496 gen_rtx (SET, VOIDmode, pc_rtx,
2497 XEXP (operands[0], 0)),
2498 gen_rtx (CLOBBER, VOIDmode,
2499 gen_rtx (REG, SImode, 15)))));
2503 fn_rtx = operands[0];
2505 /* Count the number of parameter registers being used by this call.
2506 if that argument is NULL, it means we are using them all, which
2507 means 6 on the sparc. */
2510 nregs_rtx = gen_rtx (CONST_INT, VOIDmode, REGNO (operands[2]) - 8);
2512 nregs_rtx = gen_rtx (CONST_INT, VOIDmode, 6);
2514 nregs_rtx = const0_rtx;
2517 if (INTVAL (operands[3]) > 0)
2518 emit_call_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (3,
2519 gen_rtx (CALL, VOIDmode, fn_rtx, nregs_rtx),
2521 gen_rtx (CLOBBER, VOIDmode,
2522 gen_rtx (REG, SImode, 15)))));
2524 emit_call_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (2,
2525 gen_rtx (CALL, VOIDmode, fn_rtx, nregs_rtx),
2526 gen_rtx (CLOBBER, VOIDmode,
2527 gen_rtx (REG, SImode, 15)))));
2531 /* If this call wants a structure value,
2532 emit an unimp insn to let the called function know about this. */
2533 if (INTVAL (operands[3]) > 0)
2535 rtx insn = emit_insn (operands[3]);
2536 SCHED_GROUP_P (insn) = 1;
2544 [(call (mem:SI (match_operand:SI 0 "call_operand_address" "S,r"))
2545 (match_operand 1 "" ""))
2546 (clobber (reg:SI 15))]
2547 ;;- Do not use operand 1 for most machines.
2551 return \"call %a0,%1%#\";
2553 [(set_attr "type" "call")])
2555 ;; This is a call that wants a structure value.
2557 [(call (mem:SI (match_operand:SI 0 "call_operand_address" "S,r"))
2558 (match_operand 1 "" ""))
2559 (match_operand 2 "immediate_operand" "")
2560 (clobber (reg:SI 15))]
2561 ;;- Do not use operand 1 for most machines.
2562 "GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
2565 return \"call %a0,%1\;nop\;unimp %2\";
2567 [(set_attr "type" "call_no_delay_slot")])
2569 (define_expand "call_value"
2570 [(set (match_operand 0 "register_operand" "=rf")
2571 (call (match_operand:SI 1 "" "")
2572 (match_operand 4 "" "")))]
2573 ;; operand 3 is next_arg_register
2577 rtx fn_rtx, nregs_rtx;
2580 fn_rtx = operands[1];
2584 nregs_rtx = gen_rtx (CONST_INT, VOIDmode, REGNO (operands[3]) - 8);
2586 nregs_rtx = gen_rtx (CONST_INT, VOIDmode, 6);
2588 nregs_rtx = const0_rtx;
2592 gen_rtx (SET, VOIDmode, operands[0],
2593 gen_rtx (CALL, VOIDmode, fn_rtx, nregs_rtx)),
2594 gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, 15)));
2596 emit_call_insn (gen_rtx (PARALLEL, VOIDmode, vec));
2602 [(set (match_operand 0 "" "=rf")
2603 (call (mem:SI (match_operand:SI 1 "call_operand_address" "rS"))
2604 (match_operand 2 "" "")))
2605 (clobber (reg:SI 15))]
2606 ;;- Do not use operand 2 for most machines.
2610 return \"call %a1,%2%#\";
2612 [(set_attr "type" "call")])
2614 (define_insn "return"
2617 "* return output_return (operands);"
2618 [(set_attr "type" "multi")])
2625 (define_insn "indirect_jump"
2626 [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
2629 [(set_attr "type" "branch")])
2631 (define_expand "nonlocal_goto"
2632 [(match_operand:SI 0 "general_operand" "")
2633 (match_operand:SI 1 "general_operand" "")
2634 (match_operand:SI 2 "general_operand" "")
2635 (match_operand:SI 3 "" "")]
2640 /* Trap instruction to flush all the registers window. */
2641 emit_insn (gen_rtx (UNSPEC_VOLATILE, VOIDmode,
2642 gen_rtvec (1, const0_rtx), 0));
2643 /* Load the fp value for the containing fn into %fp.
2644 This is needed because operands[2] refers to %fp. */
2645 emit_move_insn (virtual_stack_vars_rtx, operands[0]);
2646 /* Find the containing function's current nonlocal goto handler,
2647 which will do any cleanups and then jump to the label. */
2648 emit_move_insn (gen_rtx (REG, SImode, 8), operands[1]);
2649 /* Restore %fp from stack pointer value for containing function.
2650 The restore insn that follows will move this to %sp,
2651 and reload the appropriate value into %fp. */
2652 emit_move_insn (frame_pointer_rtx, operands[2]);
2653 /* Put in the static chain register the nonlocal label address. */
2654 emit_move_insn (static_chain_rtx, operands[3]);
2655 /* USE of frame_pointer_rtx added for consistency; not clear if
2657 emit_insn (gen_rtx (USE, VOIDmode, frame_pointer_rtx));
2658 emit_insn (gen_rtx (USE, VOIDmode, stack_pointer_rtx));
2659 emit_insn (gen_rtx (USE, VOIDmode, static_chain_rtx));
2660 emit_insn (gen_rtx (USE, VOIDmode, gen_rtx (REG, SImode, 8)));
2661 /* Return, restoring reg window and jumping to goto handler. */
2662 emit_insn (gen_rtx (UNSPEC_VOLATILE, VOIDmode,
2663 gen_rtvec (1, const0_rtx), 1));
2667 ;; Special trap insn to flush register windows.
2669 [(unspec_volatile [(const_int 0)] 0)]
2672 [(set_attr "type" "misc")])
2675 [(unspec_volatile [(const_int 0)] 1)]
2677 "jmp %%o0+0\;restore"
2678 [(set_attr "type" "misc")
2679 (set_attr "length" "2")])
2681 ;; Split up troublesome insns for better scheduling. */
2683 ;; The following patterns are straightforward. They can be applied
2684 ;; either before or after register allocation.
2687 [(set (match_operator 0 "memop" [(match_operand:SI 1 "symbolic_operand" "")])
2688 (match_operand 2 "reg_or_0_operand" ""))
2689 (clobber (match_operand:SI 3 "register_operand" ""))]
2691 [(set (match_dup 3) (high:SI (match_dup 1)))
2692 (set (match_op_dup 0 [(lo_sum:SI (match_dup 3) (match_dup 1))])
2697 [(set (match_operator 0 "memop"
2698 [(match_operand:SI 1 "immediate_operand" "")])
2699 (match_operand 2 "general_operand" ""))
2700 (clobber (match_operand:SI 3 "register_operand" ""))]
2702 [(set (match_op_dup 0 [(match_dup 1)])
2706 operands[1] = legitimize_pic_address (operands[1], GET_MODE (operands[0]),
2711 [(set (match_operand 0 "register_operand" "")
2712 (match_operator 1 "memop"
2713 [(match_operand:SI 2 "immediate_operand" "")]))]
2716 (match_op_dup 1 [(match_dup 2)]))]
2719 operands[2] = legitimize_pic_address (operands[2], GET_MODE (operands[1]),
2723 ;; Sign- and Zero-extend operations can have symbolic memory operands.
2726 [(set (match_operand 0 "register_operand" "")
2727 (match_operator 1 "extend_op"
2728 [(match_operator 2 "memop"
2729 [(match_operand:SI 3 "immediate_operand" "")])]))]
2732 (match_op_dup 1 [(match_op_dup 2 [(match_dup 3)])]))]
2735 operands[3] = legitimize_pic_address (operands[3], GET_MODE (operands[2]),
2740 [(set (match_operand:SI 0 "register_operand" "")
2741 (match_operand:SI 1 "immediate_operand" ""))]
2742 "! flag_pic && (GET_CODE (operands[1]) == SYMBOL_REF
2743 || GET_CODE (operands[1]) == CONST
2744 || GET_CODE (operands[1]) == LABEL_REF)"
2745 [(set (match_dup 0) (high:SI (match_dup 1)))
2747 (lo_sum:SI (match_dup 0) (match_dup 1)))]
2750 ;; LABEL_REFs are not modified by `legitimize_pic_address`
2751 ;; so do not recurse infinitely in the PIC case.
2753 [(set (match_operand:SI 0 "register_operand" "")
2754 (match_operand:SI 1 "immediate_operand" ""))]
2755 "flag_pic && (GET_CODE (operands[1]) == SYMBOL_REF
2756 || GET_CODE (operands[1]) == CONST)"
2757 [(set (match_dup 0) (match_dup 1))]
2760 operands[1] = legitimize_pic_address (operands[1], Pmode, operands[0], 0);
2763 ;; These split sne/seq insns. The forms of the resulting insns are
2764 ;; somewhat bogus, but they avoid extra patterns and show data dependency.
2765 ;; Nothing will look at these in detail after splitting has occurred.
2768 [(set (match_operand:SI 0 "register_operand" "")
2769 (ne:SI (match_operand:SI 1 "register_operand" "") (const_int 0)))
2770 (clobber (reg:CC 0))]
2772 [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
2774 (set (match_dup 0) (ltu:SI (reg:CC 0) (const_int 0)))]
2778 [(set (match_operand:SI 0 "register_operand" "")
2779 (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "")
2781 (clobber (reg:CC 0))]
2783 [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
2785 (set (match_dup 0) (neg:SI (ltu:SI (reg:CC 0) (const_int 0))))]
2789 [(set (match_operand:SI 0 "register_operand" "")
2790 (eq:SI (match_operand:SI 1 "register_operand" "") (const_int 0)))
2791 (clobber (reg:CC 0))]
2793 [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
2795 (set (match_dup 0) (geu:SI (reg:CC 0) (const_int 0)))]
2799 [(set (match_operand:SI 0 "register_operand" "")
2800 (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "")
2802 (clobber (reg:CC 0))]
2804 [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
2806 (set (match_dup 0) (neg:SI (geu:SI (reg:CC 0) (const_int 0))))]
2810 [(set (match_operand:SI 0 "register_operand" "")
2811 (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "")
2813 (match_operand:SI 2 "register_operand" "")))
2814 (clobber (reg:CC 0))]
2816 [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
2818 (set (match_dup 0) (plus:SI (ltu:SI (reg:CC 0) (const_int 0))
2823 [(set (match_operand:SI 0 "register_operand" "")
2824 (minus:SI (match_operand:SI 2 "register_operand" "")
2825 (ne:SI (match_operand:SI 1 "register_operand" "")
2827 (clobber (reg:CC 0))]
2829 [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
2831 (set (match_dup 0) (minus:SI (match_dup 2)
2832 (ltu:SI (reg:CC 0) (const_int 0))))]
2836 [(set (match_operand:SI 0 "register_operand" "")
2837 (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "")
2839 (match_operand:SI 2 "register_operand" "")))
2840 (clobber (reg:CC 0))]
2842 [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
2844 (set (match_dup 0) (plus:SI (geu:SI (reg:CC 0) (const_int 0))
2849 [(set (match_operand:SI 0 "register_operand" "")
2850 (minus:SI (match_operand:SI 2 "register_operand" "")
2851 (eq:SI (match_operand:SI 1 "register_operand" "")
2853 (clobber (reg:CC 0))]
2855 [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
2857 (set (match_dup 0) (minus:SI (match_dup 2)
2858 (geu:SI (reg:CC 0) (const_int 0))))]
2861 ;; Peepholes go at the end.
2863 ;; Optimize consecutive loads or stores into ldd and std when possible.
2864 ;; The conditions in which we do this are very restricted and are
2865 ;; explained in the code for {registers,memory}_ok_for_ldd functions.
2868 [(set (match_operand:SI 0 "register_operand" "r")
2869 (match_operand:SI 1 "memory_operand" ""))
2870 (set (match_operand:SI 2 "register_operand" "r")
2871 (match_operand:SI 3 "memory_operand" ""))]
2872 "registers_ok_for_ldd (operands[0], operands[2])
2873 && ! MEM_VOLATILE_P (operands[1]) && ! MEM_VOLATILE_P (operands[3])
2874 && memory_ok_for_ldd (XEXP (operands[1], 0), XEXP (operands[3], 0))"
2878 [(set (match_operand:SI 0 "memory_operand" "")
2879 (match_operand:SI 1 "register_operand" "r"))
2880 (set (match_operand:SI 2 "memory_operand" "")
2881 (match_operand:SI 3 "register_operand" "r"))]
2882 "registers_ok_for_ldd (operands[1], operands[3])
2883 && ! MEM_VOLATILE_P (operands[0]) && ! MEM_VOLATILE_P (operands[2])
2884 && memory_ok_for_ldd (XEXP (operands[0], 0), XEXP (operands[2], 0))"
2888 [(set (match_operand:SF 0 "register_operand" "fr")
2889 (match_operand:SF 1 "memory_operand" ""))
2890 (set (match_operand:SF 2 "register_operand" "fr")
2891 (match_operand:SF 3 "memory_operand" ""))]
2892 "registers_ok_for_ldd (operands[0], operands[2])
2893 && ! MEM_VOLATILE_P (operands[1]) && ! MEM_VOLATILE_P (operands[3])
2894 && memory_ok_for_ldd (XEXP (operands[1], 0), XEXP (operands[3], 0))"
2898 [(set (match_operand:SF 0 "memory_operand" "")
2899 (match_operand:SF 1 "register_operand" "fr"))
2900 (set (match_operand:SF 2 "memory_operand" "")
2901 (match_operand:SF 3 "register_operand" "fr"))]
2902 "registers_ok_for_ldd (operands[1], operands[3])
2903 && ! MEM_VOLATILE_P (operands[0]) && ! MEM_VOLATILE_P (operands[2])
2904 && memory_ok_for_ldd (XEXP (operands[0], 0), XEXP (operands[2], 0))"
2908 [(set (match_operand:SI 0 "register_operand" "r")
2909 (match_operand:SI 1 "memory_operand" ""))
2910 (set (match_operand:SI 2 "register_operand" "r")
2911 (match_operand:SI 3 "memory_operand" ""))]
2912 "registers_ok_for_ldd (operands[2], operands[0])
2913 && ! MEM_VOLATILE_P (operands[3]) && ! MEM_VOLATILE_P (operands[1])
2914 && memory_ok_for_ldd (XEXP (operands[3], 0), XEXP (operands[1], 0))"
2918 [(set (match_operand:SI 0 "memory_operand" "")
2919 (match_operand:SI 1 "register_operand" "r"))
2920 (set (match_operand:SI 2 "memory_operand" "")
2921 (match_operand:SI 3 "register_operand" "r"))]
2922 "registers_ok_for_ldd (operands[3], operands[1])
2923 && ! MEM_VOLATILE_P (operands[2]) && ! MEM_VOLATILE_P (operands[0])
2924 && memory_ok_for_ldd (XEXP (operands[2], 0), XEXP (operands[0], 0))"
2928 [(set (match_operand:SF 0 "register_operand" "fr")
2929 (match_operand:SF 1 "memory_operand" ""))
2930 (set (match_operand:SF 2 "register_operand" "fr")
2931 (match_operand:SF 3 "memory_operand" ""))]
2932 "registers_ok_for_ldd (operands[2], operands[0])
2933 && ! MEM_VOLATILE_P (operands[3]) && ! MEM_VOLATILE_P (operands[1])
2934 && memory_ok_for_ldd (XEXP (operands[3], 0), XEXP (operands[1], 0))"
2938 [(set (match_operand:SF 0 "memory_operand" "")
2939 (match_operand:SF 1 "register_operand" "fr"))
2940 (set (match_operand:SF 2 "memory_operand" "")
2941 (match_operand:SF 3 "register_operand" "fr"))]
2942 "registers_ok_for_ldd (operands[3], operands[1])
2943 && ! MEM_VOLATILE_P (operands[2]) && ! MEM_VOLATILE_P (operands[0])
2944 && memory_ok_for_ldd (XEXP (operands[2], 0), XEXP (operands[0], 0))"
2947 ;; Optimize the case of following a reg-reg move with a test
2948 ;; of reg just moved.
2951 [(set (match_operand:SI 0 "register_operand" "=r")
2952 (match_operand:SI 1 "register_operand" "r"))
2954 (compare:CC (match_operand:SI 2 "register_operand" "r")
2956 "rtx_equal_p (operands[2], operands[0])
2957 || rtx_equal_p (operands[2], operands[1])"
2960 ;; Do {sign,zero}-extended compares somewhat more efficiently.
2961 ;; ??? Is this now the Right Way to do this? Or will SCRATCH
2962 ;; eventually have some impact here?
2965 [(set (match_operand:HI 0 "register_operand" "")
2966 (match_operand:HI 1 "memory_operand" ""))
2967 (set (match_operand:SI 2 "register_operand" "")
2968 (sign_extend:SI (match_dup 0)))
2970 (compare:CC (match_dup 2)
2973 "ldsh %1,%0\;orcc %0,%%g0,%2")
2976 [(set (match_operand:QI 0 "register_operand" "")
2977 (match_operand:QI 1 "memory_operand" ""))
2978 (set (match_operand:SI 2 "register_operand" "")
2979 (sign_extend:SI (match_dup 0)))
2981 (compare:CC (match_dup 2)
2984 "ldsb %1,%0\;orcc %0,%%g0,%2")
2987 [(set (match_operand:HI 0 "register_operand" "")
2988 (match_operand:HI 1 "memory_operand" ""))
2989 (set (match_operand:SI 2 "register_operand" "")
2990 (sign_extend:SI (match_dup 0)))]
2991 "dead_or_set_p (insn, operands[0])"
2994 warning (\"bad peephole\");
2995 if (! MEM_VOLATILE_P (operands[1]))
2997 return \"ldsh %1,%2\";
3001 [(set (match_operand:QI 0 "register_operand" "")
3002 (match_operand:QI 1 "memory_operand" ""))
3003 (set (match_operand:SI 2 "register_operand" "")
3004 (sign_extend:SI (match_dup 0)))]
3005 "dead_or_set_p (insn, operands[0])"
3008 warning (\"bad peephole\");
3009 if (! MEM_VOLATILE_P (operands[1]))
3011 return \"ldsb %1,%2\";
3014 ;; Floating-point move peepholes
3017 [(set (match_operand:SI 0 "register_operand" "=r")
3018 (lo_sum:SI (match_dup 0)
3019 (match_operand:SI 1 "immediate_operand" "i")))
3020 (set (match_operand:DF 2 "register_operand" "=fr")
3021 (mem:DF (match_dup 0)))]
3022 "RTX_UNCHANGING_P (operands[1]) && reg_unused_after (operands[0], insn)"
3025 /* Go by way of output_move_double in case the register in operand 2
3026 is not properly aligned for ldd. */
3027 operands[1] = gen_rtx (MEM, DFmode,
3028 gen_rtx (LO_SUM, SImode, operands[0], operands[1]));
3029 operands[0] = operands[2];
3030 return output_move_double (operands);
3034 [(set (match_operand:SI 0 "register_operand" "=r")
3035 (lo_sum:SI (match_dup 0)
3036 (match_operand:SI 1 "immediate_operand" "i")))
3037 (set (match_operand:SF 2 "register_operand" "=fr")
3038 (mem:SF (match_dup 0)))]
3039 "RTX_UNCHANGING_P (operands[1]) && reg_unused_after (operands[0], insn)"
3040 "ld [%0+%%lo(%a1)],%2")
3042 ;; Return peepholes. First the "normal" ones
3045 [(set (match_operand:SI 0 "restore_operand" "")
3046 (match_operand:SI 1 "arith_operand" "rI"))
3051 if (current_function_returns_struct)
3052 return \"jmp %%i7+12\;restore %%g0,%1,%Y0\";
3054 return \"ret\;restore %%g0,%1,%Y0\";
3056 [(set_attr "type" "multi")])
3059 [(set (match_operand:SI 0 "restore_operand" "")
3060 (plus:SI (match_operand:SI 1 "arith_operand" "%r")
3061 (match_operand:SI 2 "arith_operand" "rI")))
3066 if (current_function_returns_struct)
3067 return \"jmp %%i7+12\;restore %r1,%2,%Y0\";
3069 return \"ret\;restore %r1,%2,%Y0\";
3071 [(set_attr "type" "multi")])
3073 ;; Turned off because it should never match (subtracting a constant
3074 ;; is turned into addition) and because it would do the wrong thing
3075 ;; when operand 2 is -4096 (--4096 == 4096 is not a valid immediate).
3077 ;; [(set (match_operand:SI 0 "restore_operand" "")
3078 ;; (minus:SI (match_operand:SI 1 "register_operand" "r")
3079 ;; (match_operand:SI 2 "small_int" "I")))
3081 ;; "! TARGET_EPILOGUE"
3082 ;; "ret\;restore %1,-(%2),%Y0"
3083 ;; [(set_attr "type" "multi")])
3085 ;; The following pattern is only generated by delayed-branch scheduling,
3086 ;; when the insn winds up in the epilogue.
3089 (match_operand:SF 0 "register_operand" "f"))
3092 "ret\;fmovs %0,%%f0"
3093 [(set_attr "type" "multi")])
3095 ;; Now peepholes to go a call followed by a jump.
3098 [(parallel [(set (match_operand 0 "" "")
3099 (call (mem:SI (match_operand:SI 1 "call_operand_address" "S,r"))
3100 (match_operand 2 "" "")))
3101 (clobber (reg:SI 15))])
3102 (set (pc) (label_ref (match_operand 3 "" "")))]
3103 "short_branch (INSN_UID (insn), INSN_UID (operands[3]))"
3106 return \"call %a1,%2\;add %%o7,(%l3-.-4),%%o7\";
3110 [(parallel [(call (mem:SI (match_operand:SI 0 "call_operand_address" "S,r"))
3111 (match_operand 1 "" ""))
3112 (clobber (reg:SI 15))])
3113 (set (pc) (label_ref (match_operand 2 "" "")))]
3114 "short_branch (INSN_UID (insn), INSN_UID (operands[2]))"
3117 return \"call %a0,%1\;add %%o7,(%l2-.-4),%%o7\";
3121 [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
3122 (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
3124 (clobber (reg:CC 0))])
3125 (set (reg:CC 0) (compare (match_dup 0) (const_int 0)))]
3129 ;;- Local variables:
3131 ;;- comment-start: ";;- "
3132 ;;- eval: (set-syntax-table (copy-sequence (syntax-table)))
3133 ;;- eval: (modify-syntax-entry ?[ "(]")
3134 ;;- eval: (modify-syntax-entry ?] ")[")
3135 ;;- eval: (modify-syntax-entry ?{ "(}")
3136 ;;- eval: (modify-syntax-entry ?} "){")