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:CCFP (match_operand:DF 0 "register_operand" "f")
372 (match_operand:DF 1 "register_operand" "f")))]
375 [(set_attr "type" "fpcmp")])
379 (compare:CCFP (match_operand:SF 0 "register_operand" "f")
380 (match_operand:SF 1 "register_operand" "f")))]
383 [(set_attr "type" "fpcmp")])
387 (compare:CCFP (match_operand:TF 0 "register_operand" "f")
388 (match_operand:TF 1 "register_operand" "f")))]
391 [(set_attr "type" "fpcmp")])
393 ;; The SEQ and SNE patterns are special because they can be done
394 ;; without any branching and do not involve a COMPARE.
397 [(set (match_operand:SI 0 "register_operand" "=r")
398 (ne:SI (match_operand:SI 1 "register_operand" "r") (const_int 0)))
399 (clobber (reg:CC 0))]
401 "subcc %%g0,%1,%%g0\;addx %%g0,0,%0"
402 [(set_attr "type" "unary")
403 (set_attr "length" "2")])
406 [(set (match_operand:SI 0 "register_operand" "=r")
407 (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
409 (clobber (reg:CC 0))]
411 "subcc %%g0,%1,%%g0\;subx %%g0,0,%0"
412 [(set_attr "type" "unary")
413 (set_attr "length" "2")])
416 [(set (match_operand:SI 0 "register_operand" "=r")
417 (eq:SI (match_operand:SI 1 "register_operand" "r") (const_int 0)))
418 (clobber (reg:CC 0))]
420 "subcc %%g0,%1,%%g0\;subx %%g0,-1,%0"
421 [(set_attr "type" "unary")
422 (set_attr "length" "2")])
425 [(set (match_operand:SI 0 "register_operand" "=r")
426 (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
428 (clobber (reg:CC 0))]
430 "subcc %%g0,%1,%%g0\;addx %%g0,-1,%0"
431 [(set_attr "type" "unary")
432 (set_attr "length" "2")])
434 ;; We can also do (x + (i == 0)) and related, so put them in.
437 [(set (match_operand:SI 0 "register_operand" "=r")
438 (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
440 (match_operand:SI 2 "register_operand" "r")))
441 (clobber (reg:CC 0))]
443 "subcc %%g0,%1,%%g0\;addx %2,0,%0"
444 [(set_attr "length" "2")])
447 [(set (match_operand:SI 0 "register_operand" "=r")
448 (minus:SI (match_operand:SI 2 "register_operand" "r")
449 (ne:SI (match_operand:SI 1 "register_operand" "r")
451 (clobber (reg:CC 0))]
453 "subcc %%g0,%1,%%g0\;subx %2,0,%0"
454 [(set_attr "length" "2")])
457 [(set (match_operand:SI 0 "register_operand" "=r")
458 (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
460 (match_operand:SI 2 "register_operand" "r")))
461 (clobber (reg:CC 0))]
463 "subcc %%g0,%1,%%g0\;subx %2,-1,%0"
464 [(set_attr "length" "2")])
467 [(set (match_operand:SI 0 "register_operand" "=r")
468 (minus:SI (match_operand:SI 2 "register_operand" "r")
469 (eq:SI (match_operand:SI 1 "register_operand" "r")
471 (clobber (reg:CC 0))]
473 "subcc %%g0,%1,%%g0\;addx %2,-1,%0"
474 [(set_attr "length" "2")])
476 ;; We can also do GEU and LTU directly, but these operate after a
480 [(set (match_operand:SI 0 "register_operand" "=r")
481 (ltu:SI (reg:CC 0) (const_int 0)))]
484 [(set_attr "type" "misc")])
487 [(set (match_operand:SI 0 "register_operand" "=r")
488 (neg:SI (ltu:SI (reg:CC 0) (const_int 0))))]
491 [(set_attr "type" "misc")])
493 ;; ??? Combine should canonicalize these next two to the same pattern.
495 [(set (match_operand:SI 0 "register_operand" "=r")
496 (minus:SI (neg:SI (ltu:SI (reg:CC 0) (const_int 0)))
497 (match_operand:SI 1 "arith_operand" "rI")))]
500 [(set_attr "type" "unary")])
503 [(set (match_operand:SI 0 "register_operand" "=r")
504 (neg:SI (plus:SI (ltu:SI (reg:CC 0) (const_int 0))
505 (match_operand:SI 1 "arith_operand" "rI"))))]
508 [(set_attr "type" "unary")])
511 [(set (match_operand:SI 0 "register_operand" "=r")
512 (geu:SI (reg:CC 0) (const_int 0)))]
515 [(set_attr "type" "misc")])
518 [(set (match_operand:SI 0 "register_operand" "=r")
519 (neg:SI (geu:SI (reg:CC 0) (const_int 0))))]
522 [(set_attr "type" "misc")])
524 ;; We can also do (x + ((unsigned) i >= 0)) and related, so put them in.
527 [(set (match_operand:SI 0 "register_operand" "=r")
528 (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 (plus:SI (ltu:SI (reg:CC 0) (const_int 0))
537 (plus:SI (match_operand:SI 1 "arith_operand" "%r")
538 (match_operand:SI 2 "arith_operand" "rI"))))]
543 [(set (match_operand:SI 0 "register_operand" "=r")
544 (minus:SI (match_operand:SI 1 "register_operand" "r")
545 (ltu:SI (reg:CC 0) (const_int 0))))]
548 [(set_attr "type" "unary")])
550 ;; ??? Combine should canonicalize these next two to the same pattern.
552 [(set (match_operand:SI 0 "register_operand" "=r")
553 (minus:SI (minus:SI (match_operand:SI 1 "register_operand" "r")
554 (match_operand:SI 2 "arith_operand" "rI"))
555 (ltu:SI (reg:CC 0) (const_int 0))))]
560 [(set (match_operand:SI 0 "register_operand" "=r")
561 (minus:SI (match_operand:SI 1 "register_operand" "r")
562 (plus:SI (ltu:SI (reg:CC 0) (const_int 0))
563 (match_operand:SI 2 "arith_operand" "rI"))))]
568 [(set (match_operand:SI 0 "register_operand" "=r")
569 (plus:SI (geu:SI (reg:CC 0) (const_int 0))
570 (match_operand:SI 1 "register_operand" "r")))]
573 [(set_attr "type" "unary")])
576 [(set (match_operand:SI 0 "register_operand" "=r")
577 (minus:SI (match_operand:SI 1 "register_operand" "r")
578 (geu:SI (reg:CC 0) (const_int 0))))]
581 [(set_attr "type" "unary")])
583 ;; Now we have the generic scc insns. These will be done using a jump.
584 ;; We have to exclude the cases above, since we will not want combine to
585 ;; turn something that does not require a jump into something that does.
587 [(set (match_operand:SI 0 "register_operand" "=r")
588 (match_operator:SI 1 "normal_comp_operator" [(reg 0) (const_int 0)]))]
590 "* return output_scc_insn (operands, insn); "
591 [(set_attr "type" "multi")
592 (set_attr "length" "3")])
594 ;; These control RTL generation for conditional jump insns
598 (if_then_else (eq (match_dup 1) (const_int 0))
599 (label_ref (match_operand 0 "" ""))
603 { operands[1] = gen_compare_reg (EQ, sparc_compare_op0, sparc_compare_op1); }")
607 (if_then_else (ne (match_dup 1) (const_int 0))
608 (label_ref (match_operand 0 "" ""))
612 { operands[1] = gen_compare_reg (NE, sparc_compare_op0, sparc_compare_op1); }")
616 (if_then_else (gt (match_dup 1) (const_int 0))
617 (label_ref (match_operand 0 "" ""))
621 { operands[1] = gen_compare_reg (GT, sparc_compare_op0, sparc_compare_op1); }")
623 (define_expand "bgtu"
625 (if_then_else (gtu (match_dup 1) (const_int 0))
626 (label_ref (match_operand 0 "" ""))
630 { operands[1] = gen_compare_reg (GTU, sparc_compare_op0, sparc_compare_op1);
635 (if_then_else (lt (match_dup 1) (const_int 0))
636 (label_ref (match_operand 0 "" ""))
640 { operands[1] = gen_compare_reg (LT, sparc_compare_op0, sparc_compare_op1); }")
642 (define_expand "bltu"
644 (if_then_else (ltu (match_dup 1) (const_int 0))
645 (label_ref (match_operand 0 "" ""))
649 { operands[1] = gen_compare_reg (LTU, sparc_compare_op0, sparc_compare_op1);
654 (if_then_else (ge (match_dup 1) (const_int 0))
655 (label_ref (match_operand 0 "" ""))
659 { operands[1] = gen_compare_reg (GE, sparc_compare_op0, sparc_compare_op1); }")
661 (define_expand "bgeu"
663 (if_then_else (geu (match_dup 1) (const_int 0))
664 (label_ref (match_operand 0 "" ""))
668 { operands[1] = gen_compare_reg (GEU, sparc_compare_op0, sparc_compare_op1);
673 (if_then_else (le (match_dup 1) (const_int 0))
674 (label_ref (match_operand 0 "" ""))
678 { operands[1] = gen_compare_reg (LE, sparc_compare_op0, sparc_compare_op1); }")
680 (define_expand "bleu"
682 (if_then_else (leu (match_dup 1) (const_int 0))
683 (label_ref (match_operand 0 "" ""))
687 { operands[1] = gen_compare_reg (LEU, sparc_compare_op0, sparc_compare_op1);
690 ;; Now match both normal and inverted jump.
694 (if_then_else (match_operator 0 "noov_compare_op"
695 [(reg 0) (const_int 0)])
696 (label_ref (match_operand 1 "" ""))
701 return output_cbranch (operands[0], 1, 0,
702 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
705 [(set_attr "type" "branch")])
709 (if_then_else (match_operator 0 "noov_compare_op"
710 [(reg 0) (const_int 0)])
712 (label_ref (match_operand 1 "" ""))))]
716 return output_cbranch (operands[0], 1, 1,
717 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
720 [(set_attr "type" "branch")])
724 (define_expand "movsi"
725 [(set (match_operand:SI 0 "general_operand" "")
726 (match_operand:SI 1 "general_operand" ""))]
730 if (emit_move_sequence (operands, SImode, 0))
734 (define_expand "reload_insi"
735 [(set (match_operand:SI 0 "register_operand" "=r")
736 (match_operand:SI 1 "general_operand" ""))
737 (clobber (match_operand:SI 2 "register_operand" "=&r"))]
741 if (emit_move_sequence (operands, SImode, operands[2]))
744 /* We don't want the clobber emitted, so handle this ourselves. */
745 emit_insn (gen_rtx (SET, VOIDmode, operands[0], operands[1]));
749 ;; We must support both 'r' and 'f' registers here, because combine may
750 ;; convert SFmode hard registers to SImode hard registers when simplifying
753 ;; We cannot combine the similar 'r' and 'f' constraints, because it causes
754 ;; problems with register allocation. Reload might try to put an integer
755 ;; in an fp register, or an fp number is an integer register.
758 [(set (match_operand:SI 0 "reg_or_nonsymb_mem_operand" "=r,r,r,f,Q,Q,rf")
759 (match_operand:SI 1 "move_operand" "rI,K,Q,!Q,rJ,!f,!fr"))]
760 "register_operand (operands[0], SImode)
761 || register_operand (operands[1], SImode)
762 || operands[1] == const0_rtx"
770 st %r1,[%%fp-4]\;ld [%%fp-4],%0"
771 [(set_attr "type" "move,move,load,load,store,store,multi")
772 (set_attr "length" "*,1,*,*,*,*,*")])
774 ;; Special pic pattern, for loading the address of a label into a register.
775 ;; It clobbers o7 because the call puts the return address (i.e. pc value)
779 [(set (match_operand:SI 0 "register_operand" "=r")
780 (match_operand:SI 1 "move_pic_label" "i"))
781 (set (reg:SI 15) (pc))]
783 "\\n1:\;call 2f\;sethi %%hi(%l1-1b),%0\\n2:\\tor %0,%%lo(%l1-1b),%0\;add %0,%%o7,%0"
784 [(set_attr "type" "multi")
785 (set_attr "length" "4")])
788 [(set (match_operand:DI 0 "register_operand" "=r")
789 (high:DI (match_operand 1 "" "")))]
793 rtx op0 = operands[0];
794 rtx op1 = operands[1];
796 if (GET_CODE (op1) == CONST_INT)
798 operands[0] = operand_subword (op0, 1, 0, DImode);
799 output_asm_insn (\"sethi %%hi(%a1),%0\", operands);
801 operands[0] = operand_subword (op0, 0, 0, DImode);
802 if (INTVAL (op1) < 0)
803 output_asm_insn (\"mov -1,%0\", operands);
805 output_asm_insn (\"mov 0,%0\", operands);
807 else if (GET_CODE (op1) == CONST_DOUBLE)
809 operands[0] = operand_subword (op0, 1, 0, DImode);
810 operands[1] = gen_rtx (CONST_INT, VOIDmode, CONST_DOUBLE_LOW (op1));
811 output_asm_insn (\"sethi %%hi(%a1),%0\", operands);
813 operands[0] = operand_subword (op0, 0, 0, DImode);
814 operands[1] = gen_rtx (CONST_INT, VOIDmode, CONST_DOUBLE_HIGH (op1));
815 output_asm_insn (singlemove_string (operands), operands);
820 [(set_attr "type" "move")
821 (set_attr "length" "2")])
823 ;; For PIC, symbol_refs are put inside unspec so that the optimizer won't
824 ;; confuse them with real addresses.
826 [(set (match_operand:SI 0 "register_operand" "=r")
827 (high:SI (unspec:SI [(match_operand 1 "" "")] 0)))]
830 [(set_attr "type" "move")
831 (set_attr "length" "1")])
834 [(set (match_operand:SI 0 "register_operand" "=r")
835 (high:SI (match_operand 1 "" "")))]
838 [(set_attr "type" "move")
839 (set_attr "length" "1")])
842 [(set (match_operand:HI 0 "register_operand" "=r")
843 (high:HI (match_operand 1 "" "")))]
846 [(set_attr "type" "move")
847 (set_attr "length" "1")])
850 [(set (match_operand:DI 0 "register_operand" "=r")
851 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
852 (match_operand:DI 2 "immediate_operand" "in")))]
856 /* Don't output a 64 bit constant, since we can't trust the assembler to
857 handle it correctly. */
858 if (GET_CODE (operands[2]) == CONST_DOUBLE)
859 operands[2] = gen_rtx (CONST_INT, VOIDmode, CONST_DOUBLE_LOW (operands[2]));
860 return \"or %R1,%%lo(%a2),%R0\";
862 ;; Need to set length for this arith insn because operand2
863 ;; is not an "arith_operand".
864 [(set_attr "length" "1")])
866 ;; For PIC, symbol_refs are put inside unspec so that the optimizer won't
867 ;; confuse them with real addresses.
869 [(set (match_operand:SI 0 "register_operand" "=r")
870 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
871 (unspec:SI [(match_operand:SI 2 "immediate_operand" "in")] 0)))]
874 ;; Need to set length for this arith insn because operand2
875 ;; is not an "arith_operand".
876 [(set_attr "length" "1")])
879 [(set (match_operand:SI 0 "register_operand" "=r")
880 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
881 (match_operand:SI 2 "immediate_operand" "in")))]
884 ;; Need to set length for this arith insn because operand2
885 ;; is not an "arith_operand".
886 [(set_attr "length" "1")])
889 [(set (mem:SI (match_operand:SI 0 "symbolic_operand" ""))
890 (match_operand:SI 1 "reg_or_0_operand" "rJ"))
891 (clobber (match_scratch:SI 2 "=&r"))]
893 "sethi %%hi(%a0),%2\;st %r1,[%2+%%lo(%a0)]"
894 [(set_attr "type" "store")
895 (set_attr "length" "2")])
897 (define_expand "movhi"
898 [(set (match_operand:HI 0 "general_operand" "")
899 (match_operand:HI 1 "general_operand" ""))]
903 if (emit_move_sequence (operands, HImode, 0))
908 [(set (match_operand:HI 0 "reg_or_nonsymb_mem_operand" "=r,r,r,Q")
909 (match_operand:HI 1 "move_operand" "rI,K,Q,rJ"))]
910 "register_operand (operands[0], HImode)
911 || register_operand (operands[1], HImode)
912 || operands[1] == const0_rtx"
918 [(set_attr "type" "move,move,load,store")
919 (set_attr "length" "*,1,*,1")])
922 [(set (match_operand:HI 0 "register_operand" "=r")
923 (lo_sum:HI (match_operand:HI 1 "register_operand" "r")
924 (match_operand 2 "immediate_operand" "in")))]
927 [(set_attr "length" "1")])
930 [(set (mem:HI (match_operand:SI 0 "symbolic_operand" ""))
931 (match_operand:HI 1 "reg_or_0_operand" "rJ"))
932 (clobber (match_scratch:SI 2 "=&r"))]
934 "sethi %%hi(%a0),%2\;sth %r1,[%2+%%lo(%a0)]"
935 [(set_attr "type" "store")
936 (set_attr "length" "2")])
938 (define_expand "movqi"
939 [(set (match_operand:QI 0 "general_operand" "")
940 (match_operand:QI 1 "general_operand" ""))]
944 if (emit_move_sequence (operands, QImode, 0))
949 [(set (match_operand:QI 0 "reg_or_nonsymb_mem_operand" "=r,r,r,Q")
950 (match_operand:QI 1 "move_operand" "rI,K,Q,rJ"))]
951 "register_operand (operands[0], QImode)
952 || register_operand (operands[1], QImode)
953 || operands[1] == const0_rtx"
959 [(set_attr "type" "move,move,load,store")
960 (set_attr "length" "*,1,*,1")])
963 [(set (match_operand:QI 0 "register_operand" "=r")
964 (subreg:QI (lo_sum:SI (match_operand:QI 1 "register_operand" "r")
965 (match_operand 2 "immediate_operand" "in")) 0))]
968 [(set_attr "length" "1")])
971 [(set (mem:QI (match_operand:SI 0 "symbolic_operand" ""))
972 (match_operand:QI 1 "reg_or_0_operand" "rJ"))
973 (clobber (match_scratch:SI 2 "=&r"))]
975 "sethi %%hi(%a0),%2\;stb %r1,[%2+%%lo(%a0)]"
976 [(set_attr "type" "store")
977 (set_attr "length" "2")])
979 ;; The definition of this insn does not really explain what it does,
980 ;; but it should suffice
981 ;; that anything generated as this insn will be recognized as one
982 ;; and that it will not successfully combine with anything.
983 (define_expand "movstrsi"
984 [(parallel [(set (mem:BLK (match_operand:BLK 0 "general_operand" ""))
985 (mem:BLK (match_operand:BLK 1 "general_operand" "")))
986 (use (match_operand:SI 2 "nonmemory_operand" ""))
987 (use (match_operand:SI 3 "immediate_operand" ""))
988 (clobber (match_dup 0))
989 (clobber (match_dup 1))
990 (clobber (match_scratch:SI 4 ""))
992 (clobber (reg:SI 1))])]
996 /* If the size isn't known, don't emit inline code. output_block_move
997 would output code that's much slower than the library function.
998 Also don't output code for large blocks. */
999 if (GET_CODE (operands[2]) != CONST_INT
1000 || GET_CODE (operands[3]) != CONST_INT
1001 || INTVAL (operands[2]) / INTVAL (operands[3]) > 16)
1004 operands[0] = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
1005 operands[1] = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
1006 operands[2] = force_not_mem (operands[2]);
1010 [(set (mem:BLK (match_operand:SI 0 "register_operand" "r"))
1011 (mem:BLK (match_operand:SI 1 "register_operand" "r")))
1012 (use (match_operand:SI 2 "nonmemory_operand" "rn"))
1013 (use (match_operand:SI 3 "immediate_operand" "i"))
1014 (clobber (match_dup 0))
1015 (clobber (match_dup 1))
1016 (clobber (match_scratch:SI 4 "=&r"))
1017 (clobber (reg:SI 0))
1018 (clobber (reg:SI 1))]
1020 "* return output_block_move (operands);"
1021 [(set_attr "type" "multi")
1022 (set_attr "length" "6")])
1024 ;; Floating point move insns
1026 ;; This pattern forces (set (reg:TF ...) (const_double ...))
1027 ;; to be reloaded by putting the constant into memory.
1028 ;; It must come before the more general movtf pattern.
1030 [(set (match_operand:TF 0 "general_operand" "=?r,f,o")
1031 (match_operand:TF 1 "" "?E,m,G"))]
1032 "GET_CODE (operands[1]) == CONST_DOUBLE"
1035 switch (which_alternative)
1038 return output_move_quad (operands);
1040 return output_fp_move_quad (operands);
1042 operands[1] = adj_offsettable_operand (operands[0], 4);
1043 operands[2] = adj_offsettable_operand (operands[0], 8);
1044 operands[3] = adj_offsettable_operand (operands[0], 12);
1045 return \"st %%g0,%0\;st %%g0,%1\;st %%g0,%2\;st %%g0,%3\";
1048 [(set_attr "type" "load,fpload,store")
1049 (set_attr "length" "5,5,5")])
1051 (define_expand "movtf"
1052 [(set (match_operand:TF 0 "general_operand" "")
1053 (match_operand:TF 1 "general_operand" ""))]
1057 if (emit_move_sequence (operands, TFmode, 0))
1062 [(set (match_operand:TF 0 "reg_or_nonsymb_mem_operand" "=f,r,Q,Q,f,&r,?f,?r")
1063 (match_operand:TF 1 "reg_or_nonsymb_mem_operand" "f,r,f,r,Q,Q,r,f"))]
1064 "register_operand (operands[0], TFmode)
1065 || register_operand (operands[1], TFmode)"
1068 if (FP_REG_P (operands[0]) || FP_REG_P (operands[1]))
1069 return output_fp_move_quad (operands);
1070 return output_move_quad (operands);
1072 [(set_attr "type" "fp,move,fpstore,store,fpload,load,multi,multi")
1073 (set_attr "length" "4,4,5,5,5,5,5,5")])
1076 [(set (mem:TF (match_operand:SI 0 "symbolic_operand" "i,i"))
1077 (match_operand:TF 1 "reg_or_0_operand" "rf,G"))
1078 (clobber (match_scratch:SI 2 "=&r,&r"))]
1082 output_asm_insn (\"sethi %%hi(%a0),%2\", operands);
1083 if (which_alternative == 0)
1084 return \"std %1,[%2+%%lo(%a0)]\;std %S1,[%2+%%lo(%a0+8)]\";
1086 return \"st %%g0,[%2+%%lo(%a0)]\;st %%g0,[%2+%%lo(%a0+4)]\; st %%g0,[%2+%%lo(%a0+8)]\;st %%g0,[%2+%%lo(%a0+12)]\";
1088 [(set_attr "type" "store")
1089 (set_attr "length" "5")])
1091 ;; This pattern forces (set (reg:DF ...) (const_double ...))
1092 ;; to be reloaded by putting the constant into memory.
1093 ;; It must come before the more general movdf pattern.
1094 ;; ??? A similar pattern for SF mode values would also be useful, but it
1095 ;; is not as easy to write.
1097 [(set (match_operand:DF 0 "general_operand" "=?r,f,o")
1098 (match_operand:DF 1 "" "?E,m,G"))]
1099 "GET_CODE (operands[1]) == CONST_DOUBLE"
1102 switch (which_alternative)
1105 return output_move_double (operands);
1107 return output_fp_move_double (operands);
1109 operands[1] = adj_offsettable_operand (operands[0], 4);
1110 return \"st %%g0,%0\;st %%g0,%1\";
1113 [(set_attr "type" "load,fpload,store")
1114 (set_attr "length" "3,3,3")])
1116 (define_expand "movdf"
1117 [(set (match_operand:DF 0 "general_operand" "")
1118 (match_operand:DF 1 "general_operand" ""))]
1122 if (emit_move_sequence (operands, DFmode, 0))
1127 [(set (match_operand:DF 0 "reg_or_nonsymb_mem_operand" "=f,r,Q,Q,f,&r,?f,?r")
1128 (match_operand:DF 1 "reg_or_nonsymb_mem_operand" "f,r,f,r,Q,Q,r,f"))]
1129 "register_operand (operands[0], DFmode)
1130 || register_operand (operands[1], DFmode)"
1133 if (FP_REG_P (operands[0]) || FP_REG_P (operands[1]))
1134 return output_fp_move_double (operands);
1135 return output_move_double (operands);
1137 [(set_attr "type" "fp,move,fpstore,store,fpload,load,multi,multi")
1138 (set_attr "length" "2,2,3,3,3,3,3,3")])
1141 [(set (mem:DF (match_operand:SI 0 "symbolic_operand" "i,i"))
1142 (match_operand:DF 1 "reg_or_0_operand" "rf,G"))
1143 (clobber (match_scratch:SI 2 "=&r,&r"))]
1147 output_asm_insn (\"sethi %%hi(%a0),%2\", operands);
1148 if (which_alternative == 0)
1149 return \"std %1,[%2+%%lo(%a0)]\";
1151 return \"st %%g0,[%2+%%lo(%a0)]\;st %%g0,[%2+%%lo(%a0+4)]\";
1153 [(set_attr "type" "store")
1154 (set_attr "length" "3")])
1156 ;; Double-word move insns.
1158 (define_expand "movdi"
1159 [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand" "")
1160 (match_operand:DI 1 "general_operand" ""))]
1164 if (emit_move_sequence (operands, DImode, 0))
1169 [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand" "=r,Q,&r,&r,?f,?f,?f,?r,?Q")
1170 (match_operand:DI 1 "general_operand" "r,r,Q,i,r,f,Q,f,f"))]
1171 "register_operand (operands[0], DImode)
1172 || register_operand (operands[1], DImode)
1173 || operands[1] == const0_rtx"
1176 if (FP_REG_P (operands[0]) || FP_REG_P (operands[1]))
1177 return output_fp_move_double (operands);
1178 return output_move_double (operands);
1180 [(set_attr "type" "move,store,load,multi,multi,fp,fpload,multi,fpstore")
1181 (set_attr "length" "2,3,3,3,3,2,3,3,3")])
1183 ;; Floating-point move insns.
1185 (define_expand "movsf"
1186 [(set (match_operand:SF 0 "general_operand" "")
1187 (match_operand:SF 1 "general_operand" ""))]
1191 if (emit_move_sequence (operands, SFmode, 0))
1196 [(set (match_operand:SF 0 "reg_or_nonsymb_mem_operand" "=f,r,rf,f,r,Q,Q")
1197 (match_operand:SF 1 "reg_or_nonsymb_mem_operand" "f,r,!rf,Q,Q,f,r"))]
1198 "register_operand (operands[0], SFmode)
1199 || register_operand (operands[1], SFmode)"
1203 st %r1,[%%fp-4]\;ld [%%fp-4],%0
1208 [(set_attr "type" "fp,move,multi,fpload,load,fpstore,store")])
1211 [(set (mem:SF (match_operand:SI 0 "symbolic_operand" "i"))
1212 (match_operand:SF 1 "reg_or_0_operand" "rfG"))
1213 (clobber (match_scratch:SI 2 "=&r"))]
1215 "sethi %%hi(%a0),%2\;st %r1,[%2+%%lo(%a0)]"
1216 [(set_attr "type" "store")
1217 (set_attr "length" "2")])
1219 ;;- zero extension instructions
1221 ;; These patterns originally accepted general_operands, however, slightly
1222 ;; better code is generated by only accepting register_operands, and then
1223 ;; letting combine generate the ldu[hb] insns.
1225 (define_expand "zero_extendhisi2"
1226 [(set (match_operand:SI 0 "register_operand" "")
1227 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
1231 rtx temp = gen_reg_rtx (SImode);
1232 rtx shift_16 = gen_rtx (CONST_INT, VOIDmode, 16);
1234 if (GET_CODE (operand1) == SUBREG)
1235 operand1 = XEXP (operand1, 0);
1237 emit_insn (gen_ashlsi3 (temp, gen_rtx (SUBREG, SImode, operand1, 0),
1239 emit_insn (gen_lshrsi3 (operand0, temp, shift_16));
1244 [(set (match_operand:SI 0 "register_operand" "=r")
1245 (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
1248 [(set_attr "type" "load")])
1250 (define_expand "zero_extendqihi2"
1251 [(set (match_operand:HI 0 "register_operand" "")
1252 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
1257 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
1258 (zero_extend:HI (match_operand:QI 1 "sparc_operand" "r,I,Q")))]
1259 "GET_CODE (operands[1]) != CONST_INT"
1264 [(set_attr "type" "unary,move,load")
1265 (set_attr "length" "1")])
1267 (define_expand "zero_extendqisi2"
1268 [(set (match_operand:SI 0 "register_operand" "")
1269 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
1274 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
1275 (zero_extend:SI (match_operand:QI 1 "sparc_operand" "r,I,Q")))]
1276 "GET_CODE (operands[1]) != CONST_INT"
1281 [(set_attr "type" "unary,move,load")
1282 (set_attr "length" "1")])
1286 (compare:CC (zero_extend:SI (match_operand:QI 0 "register_operand" "r"))
1289 "andcc %0,0xff,%%g0"
1290 [(set_attr "type" "compare")])
1294 (compare:CC (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
1296 (set (match_operand:SI 0 "register_operand" "=r")
1297 (zero_extend:SI (match_dup 1)))]
1300 [(set_attr "type" "unary")])
1302 ;;- sign extension instructions
1304 ;; These patterns originally accepted general_operands, however, slightly
1305 ;; better code is generated by only accepting register_operands, and then
1306 ;; letting combine generate the lds[hb] insns.
1308 (define_expand "extendhisi2"
1309 [(set (match_operand:SI 0 "register_operand" "")
1310 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
1314 rtx temp = gen_reg_rtx (SImode);
1315 rtx shift_16 = gen_rtx (CONST_INT, VOIDmode, 16);
1317 if (GET_CODE (operand1) == SUBREG)
1318 operand1 = XEXP (operand1, 0);
1320 emit_insn (gen_ashlsi3 (temp, gen_rtx (SUBREG, SImode, operand1, 0),
1322 emit_insn (gen_ashrsi3 (operand0, temp, shift_16));
1327 [(set (match_operand:SI 0 "register_operand" "=r")
1328 (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
1331 [(set_attr "type" "load")])
1333 (define_expand "extendqihi2"
1334 [(set (match_operand:HI 0 "register_operand" "")
1335 (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
1339 rtx temp = gen_reg_rtx (SImode);
1340 rtx shift_24 = gen_rtx (CONST_INT, VOIDmode, 24);
1342 if (GET_CODE (operand1) == SUBREG)
1343 operand1 = XEXP (operand1, 0);
1344 if (GET_CODE (operand0) == SUBREG)
1345 operand0 = XEXP (operand0, 0);
1346 emit_insn (gen_ashlsi3 (temp, gen_rtx (SUBREG, SImode, operand1, 0),
1348 if (GET_MODE (operand0) != SImode)
1349 operand0 = gen_rtx (SUBREG, SImode, operand0, 0);
1350 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
1355 [(set (match_operand:HI 0 "register_operand" "=r")
1356 (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
1359 [(set_attr "type" "load")])
1361 (define_expand "extendqisi2"
1362 [(set (match_operand:SI 0 "register_operand" "")
1363 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
1367 rtx temp = gen_reg_rtx (SImode);
1368 rtx shift_24 = gen_rtx (CONST_INT, VOIDmode, 24);
1370 if (GET_CODE (operand1) == SUBREG)
1371 operand1 = XEXP (operand1, 0);
1372 emit_insn (gen_ashlsi3 (temp, gen_rtx (SUBREG, SImode, operand1, 0),
1374 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
1379 [(set (match_operand:SI 0 "register_operand" "=r")
1380 (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
1383 [(set_attr "type" "load")])
1385 ;; Special pattern for optimizing bit-field compares. This is needed
1386 ;; because combine uses this as a canonical form.
1391 (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
1392 (match_operand:SI 1 "small_int" "n")
1393 (match_operand:SI 2 "small_int" "n"))
1395 "INTVAL (operands[2]) > 19"
1398 int len = INTVAL (operands[1]);
1399 int pos = 32 - INTVAL (operands[2]) - len;
1400 unsigned mask = ((1 << len) - 1) << pos;
1402 operands[1] = gen_rtx (CONST_INT, VOIDmode, mask);
1403 return \"andcc %0,%1,%%g0\";
1406 ;; Conversions between float, double and long double.
1408 (define_insn "extendsfdf2"
1409 [(set (match_operand:DF 0 "register_operand" "=f")
1411 (match_operand:SF 1 "register_operand" "f")))]
1414 [(set_attr "type" "fp")])
1416 (define_insn "extendsftf2"
1417 [(set (match_operand:TF 0 "register_operand" "=f")
1419 (match_operand:SF 1 "register_operand" "f")))]
1422 [(set_attr "type" "fp")])
1424 (define_insn "extenddftf2"
1425 [(set (match_operand:TF 0 "register_operand" "=f")
1427 (match_operand:DF 1 "register_operand" "f")))]
1430 [(set_attr "type" "fp")])
1432 (define_insn "truncdfsf2"
1433 [(set (match_operand:SF 0 "register_operand" "=f")
1435 (match_operand:DF 1 "register_operand" "f")))]
1438 [(set_attr "type" "fp")])
1440 (define_insn "trunctfsf2"
1441 [(set (match_operand:SF 0 "register_operand" "=f")
1443 (match_operand:TF 1 "register_operand" "f")))]
1446 [(set_attr "type" "fp")])
1448 (define_insn "trunctfdf2"
1449 [(set (match_operand:DF 0 "register_operand" "=f")
1451 (match_operand:TF 1 "register_operand" "f")))]
1454 [(set_attr "type" "fp")])
1456 ;; Conversion between fixed point and floating point.
1458 (define_insn "floatsisf2"
1459 [(set (match_operand:SF 0 "general_operand" "=f")
1460 (float:SF (match_operand:SI 1 "nonimmediate_operand" "rfm")))]
1462 "* return output_floatsisf2 (operands);"
1463 [(set_attr "type" "fp")
1464 (set_attr "length" "3")])
1466 (define_insn "floatsidf2"
1467 [(set (match_operand:DF 0 "general_operand" "=f")
1468 (float:DF (match_operand:SI 1 "nonimmediate_operand" "rfm")))]
1470 "* return output_floatsidf2 (operands);"
1471 [(set_attr "type" "fp")
1472 (set_attr "length" "3")])
1474 (define_insn "floatsitf2"
1475 [(set (match_operand:TF 0 "general_operand" "=f")
1476 (float:TF (match_operand:SI 1 "nonimmediate_operand" "rfm")))]
1478 "* return output_floatsitf2 (operands);"
1479 [(set_attr "type" "fp")
1480 (set_attr "length" "3")])
1482 ;; Convert a float to an actual integer.
1483 ;; Truncation is performed as part of the conversion.
1485 (define_insn "fix_truncsfsi2"
1486 [(set (match_operand:SI 0 "general_operand" "=rm")
1487 (fix:SI (fix:SF (match_operand:SF 1 "general_operand" "fm"))))
1488 (clobber (match_scratch:SF 2 "=&f"))]
1492 if (FP_REG_P (operands[1]))
1493 output_asm_insn (\"fstoi %1,%2\", operands);
1495 output_asm_insn (\"ld %1,%2\;fstoi %2,%2\", operands);
1496 if (GET_CODE (operands[0]) == MEM)
1497 return \"st %2,%0\";
1499 return \"st %2,[%%fp-4]\;ld [%%fp-4],%0\";
1501 [(set_attr "type" "fp")
1502 (set_attr "length" "3")])
1504 (define_insn "fix_truncdfsi2"
1505 [(set (match_operand:SI 0 "general_operand" "=rm")
1506 (fix:SI (fix:DF (match_operand:DF 1 "general_operand" "fm"))))
1507 (clobber (match_scratch:DF 2 "=&f"))]
1511 if (FP_REG_P (operands[1]))
1512 output_asm_insn (\"fdtoi %1,%2\", operands);
1516 xoperands[0] = operands[2];
1517 xoperands[1] = operands[1];
1518 output_asm_insn (output_fp_move_double (xoperands), xoperands);
1519 output_asm_insn (\"fdtoi %2,%2\", operands);
1521 if (GET_CODE (operands[0]) == MEM)
1522 return \"st %2,%0\";
1524 return \"st %2,[%%fp-4]\;ld [%%fp-4],%0\";
1526 [(set_attr "type" "fp")
1527 (set_attr "length" "3")])
1529 (define_insn "fix_trunctfsi2"
1530 [(set (match_operand:SI 0 "general_operand" "=rm")
1531 (fix:SI (fix:TF (match_operand:TF 1 "general_operand" "fm"))))
1532 (clobber (match_scratch:DF 2 "=&f"))]
1536 if (FP_REG_P (operands[1]))
1537 output_asm_insn (\"fqtoi %1,%2\", operands);
1541 xoperands[0] = operands[2];
1542 xoperands[1] = operands[1];
1543 output_asm_insn (output_fp_move_quad (xoperands), xoperands);
1544 output_asm_insn (\"fqtoi %2,%2\", operands);
1546 if (GET_CODE (operands[0]) == MEM)
1547 return \"st %2,%0\";
1549 return \"st %2,[%%fp-4]\;ld [%%fp-4],%0\";
1551 [(set_attr "type" "fp")
1552 (set_attr "length" "3")])
1554 ;; Allow combiner to combine a fix_trunctfsi2 with a floatsitf2
1555 ;; This eliminates 2 useless instructions.
1556 ;; The first one matches if the fixed result is needed. The second one
1557 ;; matches if the fixed result is not needed.
1560 [(set (match_operand:TF 0 "general_operand" "=f")
1561 (float:TF (fix:SI (fix:TF (match_operand:TF 1 "general_operand" "fm")))))
1562 (set (match_operand:SI 2 "general_operand" "=rm")
1563 (fix:SI (fix:TF (match_dup 1))))]
1567 if (FP_REG_P (operands[1]))
1568 output_asm_insn (\"fqtoi %1,%0\", operands);
1571 output_asm_insn (output_fp_move_quad (operands), operands);
1572 output_asm_insn (\"fqtoi %0,%0\", operands);
1574 if (GET_CODE (operands[2]) == MEM)
1575 return \"st %0,%2\;fitoq %0,%0\";
1577 return \"st %0,[%%fp-4]\;fitoq %0,%0\;ld [%%fp-4],%2\";
1579 [(set_attr "type" "fp")
1580 (set_attr "length" "5")])
1583 [(set (match_operand:TF 0 "general_operand" "=f")
1584 (float:TF (fix:SI (fix:TF (match_operand:TF 1 "general_operand" "fm")))))]
1588 if (FP_REG_P (operands[1]))
1589 output_asm_insn (\"fqtoi %1,%0\", operands);
1592 output_asm_insn (output_fp_move_quad (operands), operands);
1593 output_asm_insn (\"fqtoi %0,%0\", operands);
1595 return \"fitoq %0,%0\";
1597 [(set_attr "type" "fp")
1598 (set_attr "length" "3")])
1600 ;; Allow combiner to combine a fix_truncdfsi2 with a floatsidf2
1601 ;; This eliminates 2 useless instructions.
1602 ;; The first one matches if the fixed result is needed. The second one
1603 ;; matches if the fixed result is not needed.
1606 [(set (match_operand:DF 0 "general_operand" "=f")
1607 (float:DF (fix:SI (fix:DF (match_operand:DF 1 "general_operand" "fm")))))
1608 (set (match_operand:SI 2 "general_operand" "=rm")
1609 (fix:SI (fix:DF (match_dup 1))))]
1613 if (FP_REG_P (operands[1]))
1614 output_asm_insn (\"fdtoi %1,%0\", operands);
1617 output_asm_insn (output_fp_move_double (operands), operands);
1618 output_asm_insn (\"fdtoi %0,%0\", operands);
1620 if (GET_CODE (operands[2]) == MEM)
1621 return \"st %0,%2\;fitod %0,%0\";
1623 return \"st %0,[%%fp-4]\;fitod %0,%0\;ld [%%fp-4],%2\";
1625 [(set_attr "type" "fp")
1626 (set_attr "length" "5")])
1629 [(set (match_operand:DF 0 "general_operand" "=f")
1630 (float:DF (fix:SI (fix:DF (match_operand:DF 1 "general_operand" "fm")))))]
1634 if (FP_REG_P (operands[1]))
1635 output_asm_insn (\"fdtoi %1,%0\", operands);
1638 output_asm_insn (output_fp_move_double (operands), operands);
1639 output_asm_insn (\"fdtoi %0,%0\", operands);
1641 return \"fitod %0,%0\";
1643 [(set_attr "type" "fp")
1644 (set_attr "length" "3")])
1646 ;; Allow combiner to combine a fix_truncsfsi2 with a floatsisf2
1647 ;; This eliminates 2 useless instructions.
1648 ;; The first one matches if the fixed result is needed. The second one
1649 ;; matches if the fixed result is not needed.
1652 [(set (match_operand:SF 0 "general_operand" "=f")
1653 (float:SF (fix:SI (fix:SF (match_operand:SF 1 "general_operand" "fm")))))
1654 (set (match_operand:SI 2 "general_operand" "=rm")
1655 (fix:SI (fix:SF (match_dup 1))))]
1659 if (FP_REG_P (operands[1]))
1660 output_asm_insn (\"fstoi %1,%0\", operands);
1662 output_asm_insn (\"ld %1,%0\;fstoi %0,%0\", operands);
1663 if (GET_CODE (operands[2]) == MEM)
1664 return \"st %0,%2\;fitos %0,%0\";
1666 return \"st %0,[%%fp-4]\;fitos %0,%0\;ld [%%fp-4],%2\";
1668 [(set_attr "type" "fp")
1669 (set_attr "length" "5")])
1672 [(set (match_operand:SF 0 "general_operand" "=f")
1673 (float:SF (fix:SI (fix:SF (match_operand:SF 1 "general_operand" "fm")))))]
1677 if (FP_REG_P (operands[1]))
1678 output_asm_insn (\"fstoi %1,%0\", operands);
1680 output_asm_insn (\"ld %1,%0\;fstoi %0,%0\", operands);
1681 return \"fitos %0,%0\";
1683 [(set_attr "type" "fp")
1684 (set_attr "length" "3")])
1686 ;;- arithmetic instructions
1688 (define_insn "adddi3"
1689 [(set (match_operand:DI 0 "register_operand" "=r")
1690 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
1691 (match_operand:DI 2 "arith_double_operand" "rHI")))
1692 (clobber (reg:SI 0))]
1696 rtx op2 = operands[2];
1698 /* If constant is positive, upper bits zeroed, otherwise unchanged.
1699 Give the assembler a chance to pick the move instruction. */
1700 if (GET_CODE (op2) == CONST_INT)
1702 int sign = INTVAL (op2);
1704 return \"addcc %R1,%2,%R0\;addx %1,-1,%0\";
1705 return \"addcc %R1,%2,%R0\;addx %1,0,%0\";
1707 else if (GET_CODE (op2) == CONST_DOUBLE)
1709 int sign = CONST_DOUBLE_HIGH (op2);
1710 operands[2] = gen_rtx (CONST_INT, VOIDmode,
1711 CONST_DOUBLE_LOW (operands[1]));
1713 return \"addcc %R1,%2,%R0\;addx %1,-1,%0\";
1714 return \"addcc %R1,%2,%R0\;addx %1,0,%0\";
1716 return \"addcc %R1,%R2,%R0\;addx %1,%2,%0\";
1718 [(set_attr "length" "2")])
1720 (define_insn "addsi3"
1721 [(set (match_operand:SI 0 "register_operand" "=r")
1722 (plus:SI (match_operand:SI 1 "arith_operand" "%r")
1723 (match_operand:SI 2 "arith_operand" "rI")))]
1728 [(set (reg:CC_NOOV 0)
1729 (compare:CC_NOOV (plus:SI (match_operand:SI 0 "arith_operand" "%r")
1730 (match_operand:SI 1 "arith_operand" "rI"))
1734 [(set_attr "type" "compare")])
1737 [(set (reg:CC_NOOV 0)
1738 (compare:CC_NOOV (plus:SI (match_operand:SI 1 "arith_operand" "%r")
1739 (match_operand:SI 2 "arith_operand" "rI"))
1741 (set (match_operand:SI 0 "register_operand" "=r")
1742 (plus:SI (match_dup 1) (match_dup 2)))]
1746 (define_insn "subdi3"
1747 [(set (match_operand:DI 0 "register_operand" "=r")
1748 (minus:DI (match_operand:DI 1 "register_operand" "r")
1749 (match_operand:DI 2 "arith_double_operand" "rHI")))
1750 (clobber (reg:SI 0))]
1754 rtx op2 = operands[2];
1756 /* If constant is positive, upper bits zeroed, otherwise unchanged.
1757 Give the assembler a chance to pick the move instruction. */
1758 if (GET_CODE (op2) == CONST_INT)
1760 int sign = INTVAL (op2);
1762 return \"subcc %R1,%2,%R0\;subx %1,-1,%0\";
1763 return \"subcc %R1,%2,%R0\;subx %1,0,%0\";
1765 else if (GET_CODE (op2) == CONST_DOUBLE)
1767 int sign = CONST_DOUBLE_HIGH (op2);
1768 operands[2] = gen_rtx (CONST_INT, VOIDmode,
1769 CONST_DOUBLE_LOW (operands[1]));
1771 return \"subcc %R1,%2,%R0\;subx %1,-1,%0\";
1772 return \"subcc %R1,%2,%R0\;subx %1,0,%0\";
1774 return \"subcc %R1,%R2,%R0\;subx %1,%2,%0\";
1776 [(set_attr "length" "2")])
1778 (define_insn "subsi3"
1779 [(set (match_operand:SI 0 "register_operand" "=r")
1780 (minus:SI (match_operand:SI 1 "register_operand" "r")
1781 (match_operand:SI 2 "arith_operand" "rI")))]
1786 [(set (reg:CC_NOOV 0)
1787 (compare:CC_NOOV (minus:SI (match_operand:SI 0 "register_operand" "r")
1788 (match_operand:SI 1 "arith_operand" "rI"))
1792 [(set_attr "type" "compare")])
1795 [(set (reg:CC_NOOV 0)
1796 (compare:CC_NOOV (minus:SI (match_operand:SI 1 "register_operand" "r")
1797 (match_operand:SI 2 "arith_operand" "rI"))
1799 (set (match_operand:SI 0 "register_operand" "=r")
1800 (minus:SI (match_dup 1) (match_dup 2)))]
1804 ;;- and instructions
1805 ;; We define DImode `and` so with DImode `not` we can get
1806 ;; DImode `andn`. Other combinations are possible.
1808 (define_expand "anddi3"
1809 [(set (match_operand:DI 0 "register_operand" "")
1810 (and:DI (match_operand:DI 1 "arith_double_operand" "")
1811 (match_operand:DI 2 "arith_double_operand" "")))]
1816 [(set (match_operand:DI 0 "register_operand" "=r")
1817 (and:DI (match_operand:DI 1 "arith_double_operand" "%r")
1818 (match_operand:DI 2 "arith_double_operand" "rHI")))]
1822 rtx op2 = operands[2];
1824 /* If constant is positive, upper bits zeroed, otherwise unchanged.
1825 Give the assembler a chance to pick the move instruction. */
1826 if (GET_CODE (op2) == CONST_INT)
1828 int sign = INTVAL (op2);
1830 return \"mov %1,%0\;and %R1,%2,%R0\";
1831 return \"mov 0,%0\;and %R1,%2,%R0\";
1833 else if (GET_CODE (op2) == CONST_DOUBLE)
1835 int sign = CONST_DOUBLE_HIGH (op2);
1836 operands[2] = gen_rtx (CONST_INT, VOIDmode,
1837 CONST_DOUBLE_LOW (operands[1]));
1839 return \"mov %1,%0\;and %R1,%2,%R0\";
1840 return \"mov 0,%0\;and %R1,%2,%R0\";
1842 return \"and %1,%2,%0\;and %R1,%R2,%R0\";
1844 [(set_attr "length" "2")])
1846 (define_insn "andsi3"
1847 [(set (match_operand:SI 0 "register_operand" "=r")
1848 (and:SI (match_operand:SI 1 "arith_operand" "%r")
1849 (match_operand:SI 2 "arith_operand" "rI")))]
1854 [(set (match_operand:DI 0 "register_operand" "=r")
1855 (and:DI (not:DI (match_operand:DI 1 "register_operand" "r"))
1856 (match_operand:DI 2 "register_operand" "r")))]
1858 "andn %2,%1,%0\;andn %R2,%R1,%R0"
1859 [(set_attr "length" "2")])
1862 [(set (match_operand:SI 0 "register_operand" "=r")
1863 (and:SI (not:SI (match_operand:SI 1 "register_operand" "r"))
1864 (match_operand:SI 2 "register_operand" "r")))]
1868 (define_expand "iordi3"
1869 [(set (match_operand:DI 0 "register_operand" "")
1870 (ior:DI (match_operand:DI 1 "arith_double_operand" "")
1871 (match_operand:DI 2 "arith_double_operand" "")))]
1876 [(set (match_operand:DI 0 "register_operand" "=r")
1877 (ior:DI (match_operand:DI 1 "arith_double_operand" "%r")
1878 (match_operand:DI 2 "arith_double_operand" "rHI")))]
1882 rtx op2 = operands[2];
1884 /* If constant is positive, upper bits zeroed, otherwise unchanged.
1885 Give the assembler a chance to pick the move instruction. */
1886 if (GET_CODE (op2) == CONST_INT)
1888 int sign = INTVAL (op2);
1890 return \"mov -1,%0\;or %R1,%2,%R0\";
1891 return \"mov %1,%0\;or %R1,%2,%R0\";
1893 else if (GET_CODE (op2) == CONST_DOUBLE)
1895 int sign = CONST_DOUBLE_HIGH (op2);
1896 operands[2] = gen_rtx (CONST_INT, VOIDmode,
1897 CONST_DOUBLE_LOW (operands[1]));
1899 return \"mov -1,%0\;or %R1,%2,%R0\";
1900 return \"mov %1,%0\;or %R1,%2,%R0\";
1902 return \"or %1,%2,%0\;or %R1,%R2,%R0\";
1904 [(set_attr "length" "2")])
1906 (define_insn "iorsi3"
1907 [(set (match_operand:SI 0 "register_operand" "=r")
1908 (ior:SI (match_operand:SI 1 "arith_operand" "%r")
1909 (match_operand:SI 2 "arith_operand" "rI")))]
1914 [(set (match_operand:DI 0 "register_operand" "=r")
1915 (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r"))
1916 (match_operand:DI 2 "register_operand" "r")))]
1918 "orn %2,%1,%0\;orn %R2,%R1,%R0"
1919 [(set_attr "length" "2")])
1922 [(set (match_operand:SI 0 "register_operand" "=r")
1923 (ior:SI (not:SI (match_operand:SI 1 "register_operand" "r"))
1924 (match_operand:SI 2 "register_operand" "r")))]
1928 (define_expand "xordi3"
1929 [(set (match_operand:DI 0 "register_operand" "")
1930 (xor:DI (match_operand:DI 1 "arith_double_operand" "")
1931 (match_operand:DI 2 "arith_double_operand" "")))]
1936 [(set (match_operand:DI 0 "register_operand" "=r")
1937 (xor:DI (match_operand:DI 1 "arith_double_operand" "%r")
1938 (match_operand:DI 2 "arith_double_operand" "rHI")))]
1942 rtx op2 = operands[2];
1944 /* If constant is positive, upper bits zeroed, otherwise unchanged.
1945 Give the assembler a chance to pick the move instruction. */
1946 if (GET_CODE (op2) == CONST_INT)
1948 int sign = INTVAL (op2);
1950 return \"xor %1,-1,%0\;xor %R1,%2,%R0\";
1951 return \"mov %1,%0\;xor %R1,%2,%R0\";
1953 else if (GET_CODE (op2) == CONST_DOUBLE)
1955 int sign = CONST_DOUBLE_HIGH (op2);
1956 operands[2] = gen_rtx (CONST_INT, VOIDmode,
1957 CONST_DOUBLE_LOW (operands[1]));
1959 return \"xor %1,-1,%0\;xor %R1,%2,%R0\";
1960 return \"mov %1,%0\;xor %R1,%2,%R0\";
1962 return \"xor %1,%2,%0\;xor %R1,%R2,%R0\";
1964 [(set_attr "length" "2")])
1966 (define_insn "xorsi3"
1967 [(set (match_operand:SI 0 "register_operand" "=r")
1968 (xor:SI (match_operand:SI 1 "arith_operand" "%rJ")
1969 (match_operand:SI 2 "arith_operand" "rI")))]
1973 ;; xnor patterns. Note that (a ^ ~b) == (~a ^ b) == ~(a ^ b).
1974 ;; Combine now canonicalizes to the rightmost expression.
1976 [(set (match_operand:DI 0 "register_operand" "=r")
1977 (not:DI (xor:DI (match_operand:DI 1 "register_operand" "r")
1978 (match_operand:DI 2 "register_operand" "r"))))]
1980 "xnor %1,%2,%0\;xnor %R1,%R2,%R0"
1981 [(set_attr "length" "2")])
1984 [(set (match_operand:SI 0 "register_operand" "=r")
1985 (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
1986 (match_operand:SI 2 "arith_operand" "rI"))))]
1990 ;; These correspond to the above in the case where we also (or only)
1991 ;; want to set the condition code.
1996 (match_operator:SI 2 "cc_arithop"
1997 [(match_operand:SI 0 "arith_operand" "%r")
1998 (match_operand:SI 1 "arith_operand" "rI")])
2002 [(set_attr "type" "compare")])
2007 (match_operator:SI 3 "cc_arithop"
2008 [(match_operand:SI 1 "arith_operand" "%r")
2009 (match_operand:SI 2 "arith_operand" "rI")])
2011 (set (match_operand:SI 0 "register_operand" "=r")
2019 (not:SI (xor:SI (match_operand:SI 0 "reg_or_0_operand" "%rJ")
2020 (match_operand:SI 1 "arith_operand" "rI")))
2023 "xnorcc %r0,%1,%%g0"
2024 [(set_attr "type" "compare")])
2029 (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
2030 (match_operand:SI 2 "arith_operand" "rI")))
2032 (set (match_operand:SI 0 "register_operand" "=r")
2033 (not:SI (xor:SI (match_dup 1) (match_dup 2))))]
2040 (match_operator:SI 2 "cc_arithopn"
2041 [(not:SI (match_operand:SI 0 "arith_operand" "rI"))
2042 (match_operand:SI 1 "reg_or_0_operand" "rJ")])
2046 [(set_attr "type" "compare")])
2051 (match_operator:SI 3 "cc_arithopn"
2052 [(not:SI (match_operand:SI 1 "arith_operand" "rI"))
2053 (match_operand:SI 2 "reg_or_0_operand" "rJ")])
2055 (set (match_operand:SI 0 "register_operand" "=r")
2060 ;; We cannot use the "neg" pseudo insn because the Sun assembler
2061 ;; does not know how to make it work for constants.
2063 (define_insn "negdi2"
2064 [(set (match_operand:DI 0 "register_operand" "=r")
2065 (neg:DI (match_operand:DI 1 "register_operand" "r")))
2066 (clobber (reg:SI 0))]
2068 "subcc %%g0,%R1,%R0\;subx %%g0,%1,%0"
2069 [(set_attr "type" "unary")
2070 (set_attr "length" "2")])
2072 (define_insn "negsi2"
2073 [(set (match_operand:SI 0 "general_operand" "=r")
2074 (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
2077 [(set_attr "type" "unary")])
2080 [(set (reg:CC_NOOV 0)
2081 (compare:CC_NOOV (neg:SI (match_operand:SI 0 "arith_operand" "rI"))
2084 "subcc %%g0,%0,%%g0"
2085 [(set_attr "type" "compare")])
2088 [(set (reg:CC_NOOV 0)
2089 (compare:CC_NOOV (neg:SI (match_operand:SI 1 "arith_operand" "rI"))
2091 (set (match_operand:SI 0 "register_operand" "=r")
2092 (neg:SI (match_dup 1)))]
2095 [(set_attr "type" "unary")])
2097 ;; We cannot use the "not" pseudo insn because the Sun assembler
2098 ;; does not know how to make it work for constants.
2099 (define_expand "one_cmpldi2"
2100 [(set (match_operand:DI 0 "register_operand" "=r")
2101 (not:DI (match_operand:DI 1 "arith_double_operand" "rHI")))]
2106 [(set (match_operand:DI 0 "register_operand" "=r")
2107 (not:DI (match_operand:DI 1 "arith_double_operand" "rHI")))]
2111 rtx op1 = operands[1];
2113 if (GET_CODE (op1) == CONST_INT)
2115 int sign = INTVAL (op1);
2117 return \"xnor %%g0,%1,%R0\;xnor %%g0,-1,%0\";
2118 return \"xnor %%g0,%1,%R0\;xnor %%g0,0,%0\";
2120 else if (GET_CODE (op1) == CONST_DOUBLE)
2122 int sign = CONST_DOUBLE_HIGH (op1);
2123 operands[1] = gen_rtx (CONST_INT, VOIDmode,
2124 CONST_DOUBLE_LOW (operands[1]));
2126 return \"xnor %%g0,%1,%R0\;xnor %%g0,-1,%0\";
2127 return \"xnor %%g0,%1,%R0\;xnor %%g0,0,%0\";
2129 return \"xnor %%g0,%1,%0\;xnor %%g0,%R1,%R0\";
2131 [(set_attr "type" "unary")
2132 (set_attr "length" "2")])
2134 (define_insn "one_cmplsi2"
2135 [(set (match_operand:SI 0 "register_operand" "=r")
2136 (not:SI (match_operand:SI 1 "arith_operand" "rI")))]
2139 [(set_attr "type" "unary")])
2143 (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI"))
2146 "xnorcc %%g0,%0,%%g0"
2147 [(set_attr "type" "compare")])
2151 (compare:CC (not:SI (match_operand:SI 1 "arith_operand" "rI"))
2153 (set (match_operand:SI 0 "register_operand" "=r")
2154 (not:SI (match_dup 1)))]
2157 [(set_attr "type" "unary")])
2159 ;; Floating point arithmetic instructions.
2161 (define_insn "addtf3"
2162 [(set (match_operand:TF 0 "register_operand" "=f")
2163 (plus:TF (match_operand:TF 1 "register_operand" "f")
2164 (match_operand:TF 2 "register_operand" "f")))]
2167 [(set_attr "type" "fp")])
2169 (define_insn "adddf3"
2170 [(set (match_operand:DF 0 "register_operand" "=f")
2171 (plus:DF (match_operand:DF 1 "register_operand" "f")
2172 (match_operand:DF 2 "register_operand" "f")))]
2175 [(set_attr "type" "fp")])
2177 (define_insn "addsf3"
2178 [(set (match_operand:SF 0 "register_operand" "=f")
2179 (plus:SF (match_operand:SF 1 "register_operand" "f")
2180 (match_operand:SF 2 "register_operand" "f")))]
2183 [(set_attr "type" "fp")])
2185 (define_insn "subtf3"
2186 [(set (match_operand:TF 0 "register_operand" "=f")
2187 (minus:TF (match_operand:TF 1 "register_operand" "f")
2188 (match_operand:TF 2 "register_operand" "f")))]
2191 [(set_attr "type" "fp")])
2193 (define_insn "subdf3"
2194 [(set (match_operand:DF 0 "register_operand" "=f")
2195 (minus:DF (match_operand:DF 1 "register_operand" "f")
2196 (match_operand:DF 2 "register_operand" "f")))]
2199 [(set_attr "type" "fp")])
2201 (define_insn "subsf3"
2202 [(set (match_operand:SF 0 "register_operand" "=f")
2203 (minus:SF (match_operand:SF 1 "register_operand" "f")
2204 (match_operand:SF 2 "register_operand" "f")))]
2207 [(set_attr "type" "fp")])
2209 (define_insn "multf3"
2210 [(set (match_operand:TF 0 "register_operand" "=f")
2211 (mult:TF (match_operand:TF 1 "register_operand" "f")
2212 (match_operand:TF 2 "register_operand" "f")))]
2215 [(set_attr "type" "fpmul")])
2217 (define_insn "muldf3"
2218 [(set (match_operand:DF 0 "register_operand" "=f")
2219 (mult:DF (match_operand:DF 1 "register_operand" "f")
2220 (match_operand:DF 2 "register_operand" "f")))]
2223 [(set_attr "type" "fpmul")])
2225 (define_insn "mulsf3"
2226 [(set (match_operand:SF 0 "register_operand" "=f")
2227 (mult:SF (match_operand:SF 1 "register_operand" "f")
2228 (match_operand:SF 2 "register_operand" "f")))]
2231 [(set_attr "type" "fpmul")])
2233 (define_insn "divtf3"
2234 [(set (match_operand:TF 0 "register_operand" "=f")
2235 (div:TF (match_operand:TF 1 "register_operand" "f")
2236 (match_operand:TF 2 "register_operand" "f")))]
2239 [(set_attr "type" "fpdiv")])
2241 (define_insn "divdf3"
2242 [(set (match_operand:DF 0 "register_operand" "=f")
2243 (div:DF (match_operand:DF 1 "register_operand" "f")
2244 (match_operand:DF 2 "register_operand" "f")))]
2247 [(set_attr "type" "fpdiv")])
2249 (define_insn "divsf3"
2250 [(set (match_operand:SF 0 "register_operand" "=f")
2251 (div:SF (match_operand:SF 1 "register_operand" "f")
2252 (match_operand:SF 2 "register_operand" "f")))]
2255 [(set_attr "type" "fpdiv")])
2257 (define_insn "negtf2"
2258 [(set (match_operand:TF 0 "register_operand" "=f,f")
2259 (neg:TF (match_operand:TF 1 "register_operand" "0,f")))]
2263 fnegs %1,%0\;fmovs %R1,%R0\;fmovs %S1,%S0\;fmovs %T1,%T0"
2264 [(set_attr "type" "fp")
2265 (set_attr "length" "1,4")])
2267 (define_insn "negdf2"
2268 [(set (match_operand:DF 0 "register_operand" "=f,f")
2269 (neg:DF (match_operand:DF 1 "register_operand" "0,f")))]
2273 fnegs %1,%0\;fmovs %R1,%R0"
2274 [(set_attr "type" "fp")
2275 (set_attr "length" "1,2")])
2277 (define_insn "negsf2"
2278 [(set (match_operand:SF 0 "register_operand" "=f")
2279 (neg:SF (match_operand:SF 1 "register_operand" "f")))]
2282 [(set_attr "type" "fp")])
2284 (define_insn "abstf2"
2285 [(set (match_operand:TF 0 "register_operand" "=f,f")
2286 (abs:TF (match_operand:TF 1 "register_operand" "0,f")))]
2290 fabss %1,%0\;fmovs %R1,%R0\;fmovs %S1,%S0\;fmovs %T1,%T0"
2291 [(set_attr "type" "fp")
2292 (set_attr "length" "1,4")])
2294 (define_insn "absdf2"
2295 [(set (match_operand:DF 0 "register_operand" "=f,f")
2296 (abs:DF (match_operand:DF 1 "register_operand" "0,f")))]
2300 fabss %1,%0\;fmovs %R1,%R0"
2301 [(set_attr "type" "fp")
2302 (set_attr "length" "1,2")])
2304 (define_insn "abssf2"
2305 [(set (match_operand:SF 0 "register_operand" "=f")
2306 (abs:SF (match_operand:SF 1 "register_operand" "f")))]
2309 [(set_attr "type" "fp")])
2311 (define_insn "sqrttf2"
2312 [(set (match_operand:TF 0 "register_operand" "=f")
2313 (sqrt:TF (match_operand:TF 1 "register_operand" "f")))]
2316 [(set_attr "type" "fpsqrt")])
2318 (define_insn "sqrtdf2"
2319 [(set (match_operand:DF 0 "register_operand" "=f")
2320 (sqrt:DF (match_operand:DF 1 "register_operand" "f")))]
2323 [(set_attr "type" "fpsqrt")])
2325 (define_insn "sqrtsf2"
2326 [(set (match_operand:SF 0 "register_operand" "=f")
2327 (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
2330 [(set_attr "type" "fpsqrt")])
2332 ;;- arithmetic shift instructions
2334 ;; We can trivially handle shifting the constant 1 by 64 bits.
2335 ;; For other shifts we use the library routine.
2336 ;; ??? Questionable, we can do better than this can't we?
2337 (define_expand "ashldi3"
2338 [(parallel [(set (match_operand:DI 0 "register_operand" "")
2339 (ashift:DI (match_operand:DI 1 "const_double_operand" "")
2340 (match_operand:SI 2 "register_operand" "")))
2341 (clobber (reg:SI 0))])]
2345 if (GET_CODE (operands[1]) == CONST_DOUBLE
2346 && CONST_DOUBLE_HIGH (operands[1]) == 0
2347 && CONST_DOUBLE_LOW (operands[1]) == 1)
2348 operands[1] = const1_rtx;
2349 else if (operands[1] != const1_rtx)
2353 ;; ??? Questionable, we can do better than this can't we?
2355 [(set (match_operand:DI 0 "register_operand" "=&r")
2356 (ashift:DI (const_int 1)
2357 (match_operand:SI 1 "register_operand" "r")))
2358 (clobber (reg:SI 0))]
2360 "subcc %1,32,%%g0\;addx %%g0,0,%R0\;xor %R0,1,%0\;sll %R0,%1,%R0\;sll %0,%1,%0"
2361 [(set_attr "type" "multi")
2362 (set_attr "length" "5")])
2364 (define_insn "ashlsi3"
2365 [(set (match_operand:SI 0 "register_operand" "=r")
2366 (ashift:SI (match_operand:SI 1 "register_operand" "r")
2367 (match_operand:SI 2 "arith_operand" "rI")))]
2371 (define_insn "ashrsi3"
2372 [(set (match_operand:SI 0 "register_operand" "=r")
2373 (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
2374 (match_operand:SI 2 "arith_operand" "rI")))]
2378 (define_insn "lshrsi3"
2379 [(set (match_operand:SI 0 "register_operand" "=r")
2380 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
2381 (match_operand:SI 2 "arith_operand" "rI")))]
2385 ;; Unconditional and other jump instructions
2386 ;; Note that for the Sparc, by setting the annul bit on an unconditional
2387 ;; branch, the following insn is never executed. This saves us a nop,
2388 ;; but requires a debugger which can handle annulled branches.
2390 [(set (pc) (label_ref (match_operand 0 "" "")))]
2393 [(set_attr "type" "branch")])
2395 (define_expand "tablejump"
2396 [(parallel [(set (pc) (match_operand:SI 0 "register_operand" "r"))
2397 (use (label_ref (match_operand 1 "" "")))])]
2401 /* We need to use the PC value in %o7 that was set up when the address
2402 of the label was loaded into a register, so we need different RTL. */
2405 emit_insn (gen_pic_tablejump (operands[0], operands[1]));
2410 (define_insn "pic_tablejump"
2411 [(set (pc) (match_operand:SI 0 "register_operand" "r"))
2412 (use (label_ref (match_operand 1 "" "")))
2416 [(set_attr "type" "branch")])
2419 [(set (pc) (match_operand:SI 0 "address_operand" "p"))
2420 (use (label_ref (match_operand 1 "" "")))]
2423 [(set_attr "type" "branch")])
2426 [(set (pc) (label_ref (match_operand 0 "" "")))
2427 (set (reg:SI 15) (label_ref (match_dup 0)))]
2430 [(set_attr "type" "branch")])
2432 ;; This pattern recognizes the "instruction" that appears in
2433 ;; a function call that wants a structure value,
2434 ;; to inform the called function if compiled with Sun CC.
2436 ; [(match_operand:SI 0 "immediate_operand" "")]
2437 ; "GET_CODE (operands[0]) == CONST_INT && INTVAL (operands[0]) > 0"
2439 ; [(set_attr "type" "marker")])
2441 ;;- jump to subroutine
2442 (define_expand "call"
2443 ;; Note that this expression is not used for generating RTL.
2444 ;; All the RTL is generated explicitly below.
2445 [(call (match_operand:SI 0 "call_operand" "")
2446 (match_operand 3 "" "i"))]
2447 ;; operands[2] is next_arg_register
2448 ;; operands[3] is struct_value_size_rtx.
2452 rtx fn_rtx, nregs_rtx;
2454 if (GET_CODE (XEXP (operands[0], 0)) == LABEL_REF)
2456 /* This is really a PIC sequence. We want to represent
2457 it as a funny jump so it's delay slots can be filled.
2459 ??? But if this really *is* a CALL, will not it clobber the
2460 call-clobbered registers? We lose this if it is a JUMP_INSN.
2461 Why cannot we have delay slots filled if it were a CALL? */
2463 if (INTVAL (operands[3]) > 0)
2464 emit_jump_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (3,
2465 gen_rtx (SET, VOIDmode, pc_rtx,
2466 XEXP (operands[0], 0)),
2468 gen_rtx (CLOBBER, VOIDmode,
2469 gen_rtx (REG, SImode, 15)))));
2471 emit_jump_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (2,
2472 gen_rtx (SET, VOIDmode, pc_rtx,
2473 XEXP (operands[0], 0)),
2474 gen_rtx (CLOBBER, VOIDmode,
2475 gen_rtx (REG, SImode, 15)))));
2479 fn_rtx = operands[0];
2481 /* Count the number of parameter registers being used by this call.
2482 if that argument is NULL, it means we are using them all, which
2483 means 6 on the sparc. */
2486 nregs_rtx = gen_rtx (CONST_INT, VOIDmode, REGNO (operands[2]) - 8);
2488 nregs_rtx = gen_rtx (CONST_INT, VOIDmode, 6);
2490 nregs_rtx = const0_rtx;
2493 if (INTVAL (operands[3]) > 0)
2494 emit_call_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (3,
2495 gen_rtx (CALL, VOIDmode, fn_rtx, nregs_rtx),
2497 gen_rtx (CLOBBER, VOIDmode,
2498 gen_rtx (REG, SImode, 15)))));
2500 emit_call_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (2,
2501 gen_rtx (CALL, VOIDmode, fn_rtx, nregs_rtx),
2502 gen_rtx (CLOBBER, VOIDmode,
2503 gen_rtx (REG, SImode, 15)))));
2507 /* If this call wants a structure value,
2508 emit an unimp insn to let the called function know about this. */
2509 if (INTVAL (operands[3]) > 0)
2511 rtx insn = emit_insn (operands[3]);
2512 SCHED_GROUP_P (insn) = 1;
2520 [(call (mem:SI (match_operand:SI 0 "call_operand_address" "S,r"))
2521 (match_operand 1 "" ""))
2522 (clobber (reg:SI 15))]
2523 ;;- Do not use operand 1 for most machines.
2527 return \"call %a0,%1%#\";
2529 [(set_attr "type" "call")])
2531 ;; This is a call that wants a structure value.
2533 [(call (mem:SI (match_operand:SI 0 "call_operand_address" "S,r"))
2534 (match_operand 1 "" ""))
2535 (match_operand 2 "immediate_operand" "")
2536 (clobber (reg:SI 15))]
2537 ;;- Do not use operand 1 for most machines.
2538 "GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
2541 return \"call %a0,%1\;nop\;unimp %2\";
2543 [(set_attr "type" "call_no_delay_slot")])
2545 (define_expand "call_value"
2546 [(set (match_operand 0 "register_operand" "=rf")
2547 (call (match_operand:SI 1 "" "")
2548 (match_operand 4 "" "")))]
2549 ;; operand 3 is next_arg_register
2553 rtx fn_rtx, nregs_rtx;
2556 fn_rtx = operands[1];
2560 nregs_rtx = gen_rtx (CONST_INT, VOIDmode, REGNO (operands[3]) - 8);
2562 nregs_rtx = gen_rtx (CONST_INT, VOIDmode, 6);
2564 nregs_rtx = const0_rtx;
2568 gen_rtx (SET, VOIDmode, operands[0],
2569 gen_rtx (CALL, VOIDmode, fn_rtx, nregs_rtx)),
2570 gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, 15)));
2572 emit_call_insn (gen_rtx (PARALLEL, VOIDmode, vec));
2578 [(set (match_operand 0 "" "=rf")
2579 (call (mem:SI (match_operand:SI 1 "call_operand_address" "rS"))
2580 (match_operand 2 "" "")))
2581 (clobber (reg:SI 15))]
2582 ;;- Do not use operand 2 for most machines.
2586 return \"call %a1,%2%#\";
2588 [(set_attr "type" "call")])
2590 (define_insn "return"
2593 "* return output_return (operands);"
2594 [(set_attr "type" "multi")])
2601 (define_insn "indirect_jump"
2602 [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
2605 [(set_attr "type" "branch")])
2607 (define_expand "nonlocal_goto"
2608 [(match_operand:SI 0 "general_operand" "")
2609 (match_operand:SI 1 "general_operand" "")
2610 (match_operand:SI 2 "general_operand" "")
2611 (match_operand:SI 3 "" "")]
2616 /* Trap instruction to flush all the registers window. */
2617 emit_insn (gen_rtx (UNSPEC_VOLATILE, VOIDmode,
2618 gen_rtvec (1, const0_rtx), 0));
2619 /* Load the fp value for the containing fn into %fp.
2620 This is needed because operands[2] refers to %fp. */
2621 emit_move_insn (virtual_stack_vars_rtx, operands[0]);
2622 /* Find the containing function's current nonlocal goto handler,
2623 which will do any cleanups and then jump to the label. */
2624 emit_move_insn (gen_rtx (REG, SImode, 8), operands[1]);
2625 /* Restore %fp from stack pointer value for containing function.
2626 The restore insn that follows will move this to %sp,
2627 and reload the appropriate value into %fp. */
2628 emit_move_insn (frame_pointer_rtx, operands[2]);
2629 /* Put in the static chain register the nonlocal label address. */
2630 emit_move_insn (static_chain_rtx, operands[3]);
2631 /* USE of frame_pointer_rtx added for consistency; not clear if
2633 emit_insn (gen_rtx (USE, VOIDmode, frame_pointer_rtx));
2634 emit_insn (gen_rtx (USE, VOIDmode, stack_pointer_rtx));
2635 emit_insn (gen_rtx (USE, VOIDmode, static_chain_rtx));
2636 emit_insn (gen_rtx (USE, VOIDmode, gen_rtx (REG, SImode, 8)));
2637 /* Return, restoring reg window and jumping to goto handler. */
2638 emit_insn (gen_rtx (UNSPEC_VOLATILE, VOIDmode,
2639 gen_rtvec (1, const0_rtx), 1));
2643 ;; Special trap insn to flush register windows.
2645 [(unspec_volatile [(const_int 0)] 0)]
2648 [(set_attr "type" "misc")])
2651 [(unspec_volatile [(const_int 0)] 1)]
2653 "jmp %%o0+0\;restore"
2654 [(set_attr "type" "misc")
2655 (set_attr "length" "2")])
2657 ;; Split up troublesome insns for better scheduling. */
2659 ;; The following patterns are straightforward. They can be applied
2660 ;; either before or after register allocation.
2663 [(set (match_operator 0 "memop" [(match_operand:SI 1 "symbolic_operand" "")])
2664 (match_operand 2 "reg_or_0_operand" ""))
2665 (clobber (match_operand:SI 3 "register_operand" ""))]
2667 [(set (match_dup 3) (high:SI (match_dup 1)))
2668 (set (match_op_dup 0 [(lo_sum:SI (match_dup 3) (match_dup 1))])
2673 [(set (match_operator 0 "memop"
2674 [(match_operand:SI 1 "immediate_operand" "")])
2675 (match_operand 2 "general_operand" ""))
2676 (clobber (match_operand:SI 3 "register_operand" ""))]
2678 [(set (match_op_dup 0 [(match_dup 1)])
2682 operands[1] = legitimize_pic_address (operands[1], GET_MODE (operands[0]),
2687 [(set (match_operand 0 "register_operand" "")
2688 (match_operator 1 "memop"
2689 [(match_operand:SI 2 "immediate_operand" "")]))]
2692 (match_op_dup 1 [(match_dup 2)]))]
2695 operands[2] = legitimize_pic_address (operands[2], GET_MODE (operands[1]),
2699 ;; Sign- and Zero-extend operations can have symbolic memory operands.
2702 [(set (match_operand 0 "register_operand" "")
2703 (match_operator 1 "extend_op"
2704 [(match_operator 2 "memop"
2705 [(match_operand:SI 3 "immediate_operand" "")])]))]
2708 (match_op_dup 1 [(match_op_dup 2 [(match_dup 3)])]))]
2711 operands[3] = legitimize_pic_address (operands[3], GET_MODE (operands[2]),
2716 [(set (match_operand:SI 0 "register_operand" "")
2717 (match_operand:SI 1 "immediate_operand" ""))]
2718 "! flag_pic && (GET_CODE (operands[1]) == SYMBOL_REF
2719 || GET_CODE (operands[1]) == CONST
2720 || GET_CODE (operands[1]) == LABEL_REF)"
2721 [(set (match_dup 0) (high:SI (match_dup 1)))
2723 (lo_sum:SI (match_dup 0) (match_dup 1)))]
2726 ;; LABEL_REFs are not modified by `legitimize_pic_address`
2727 ;; so do not recurse infinitely in the PIC case.
2729 [(set (match_operand:SI 0 "register_operand" "")
2730 (match_operand:SI 1 "immediate_operand" ""))]
2731 "flag_pic && (GET_CODE (operands[1]) == SYMBOL_REF
2732 || GET_CODE (operands[1]) == CONST)"
2733 [(set (match_dup 0) (match_dup 1))]
2736 operands[1] = legitimize_pic_address (operands[1], Pmode, operands[0], 0);
2739 ;; These split sne/seq insns. The forms of the resulting insns are
2740 ;; somewhat bogus, but they avoid extra patterns and show data dependency.
2741 ;; Nothing will look at these in detail after splitting has occurred.
2744 [(set (match_operand:SI 0 "register_operand" "")
2745 (ne:SI (match_operand:SI 1 "register_operand" "") (const_int 0)))
2746 (clobber (reg:CC 0))]
2748 [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
2750 (set (match_dup 0) (ltu:SI (reg:CC 0) (const_int 0)))]
2754 [(set (match_operand:SI 0 "register_operand" "")
2755 (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "")
2757 (clobber (reg:CC 0))]
2759 [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
2761 (set (match_dup 0) (neg:SI (ltu:SI (reg:CC 0) (const_int 0))))]
2765 [(set (match_operand:SI 0 "register_operand" "")
2766 (eq:SI (match_operand:SI 1 "register_operand" "") (const_int 0)))
2767 (clobber (reg:CC 0))]
2769 [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
2771 (set (match_dup 0) (geu:SI (reg:CC 0) (const_int 0)))]
2775 [(set (match_operand:SI 0 "register_operand" "")
2776 (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "")
2778 (clobber (reg:CC 0))]
2780 [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
2782 (set (match_dup 0) (neg:SI (geu:SI (reg:CC 0) (const_int 0))))]
2786 [(set (match_operand:SI 0 "register_operand" "")
2787 (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "")
2789 (match_operand:SI 2 "register_operand" "")))
2790 (clobber (reg:CC 0))]
2792 [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
2794 (set (match_dup 0) (plus:SI (ltu:SI (reg:CC 0) (const_int 0))
2799 [(set (match_operand:SI 0 "register_operand" "")
2800 (minus:SI (match_operand:SI 2 "register_operand" "")
2801 (ne:SI (match_operand:SI 1 "register_operand" "")
2803 (clobber (reg:CC 0))]
2805 [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
2807 (set (match_dup 0) (minus:SI (match_dup 2)
2808 (ltu:SI (reg:CC 0) (const_int 0))))]
2812 [(set (match_operand:SI 0 "register_operand" "")
2813 (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "")
2815 (match_operand:SI 2 "register_operand" "")))
2816 (clobber (reg:CC 0))]
2818 [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
2820 (set (match_dup 0) (plus:SI (geu:SI (reg:CC 0) (const_int 0))
2825 [(set (match_operand:SI 0 "register_operand" "")
2826 (minus:SI (match_operand:SI 2 "register_operand" "")
2827 (eq:SI (match_operand:SI 1 "register_operand" "")
2829 (clobber (reg:CC 0))]
2831 [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
2833 (set (match_dup 0) (minus:SI (match_dup 2)
2834 (geu:SI (reg:CC 0) (const_int 0))))]
2837 ;; Peepholes go at the end.
2839 ;; Optimize consecutive loads or stores into ldd and std when possible.
2840 ;; The conditions in which we do this are very restricted and are
2841 ;; explained in the code for {registers,memory}_ok_for_ldd functions.
2844 [(set (match_operand:SI 0 "register_operand" "r")
2845 (match_operand:SI 1 "memory_operand" ""))
2846 (set (match_operand:SI 2 "register_operand" "r")
2847 (match_operand:SI 3 "memory_operand" ""))]
2848 "registers_ok_for_ldd (operands[0], operands[2])
2849 && ! MEM_VOLATILE_P (operands[1]) && ! MEM_VOLATILE_P (operands[3])
2850 && memory_ok_for_ldd (XEXP (operands[1], 0), XEXP (operands[3], 0))"
2854 [(set (match_operand:SI 0 "memory_operand" "")
2855 (match_operand:SI 1 "register_operand" "r"))
2856 (set (match_operand:SI 2 "memory_operand" "")
2857 (match_operand:SI 3 "register_operand" "r"))]
2858 "registers_ok_for_ldd (operands[1], operands[3])
2859 && ! MEM_VOLATILE_P (operands[0]) && ! MEM_VOLATILE_P (operands[2])
2860 && memory_ok_for_ldd (XEXP (operands[0], 0), XEXP (operands[2], 0))"
2864 [(set (match_operand:SF 0 "register_operand" "fr")
2865 (match_operand:SF 1 "memory_operand" ""))
2866 (set (match_operand:SF 2 "register_operand" "fr")
2867 (match_operand:SF 3 "memory_operand" ""))]
2868 "registers_ok_for_ldd (operands[0], operands[2])
2869 && ! MEM_VOLATILE_P (operands[1]) && ! MEM_VOLATILE_P (operands[3])
2870 && memory_ok_for_ldd (XEXP (operands[1], 0), XEXP (operands[3], 0))"
2874 [(set (match_operand:SF 0 "memory_operand" "")
2875 (match_operand:SF 1 "register_operand" "fr"))
2876 (set (match_operand:SF 2 "memory_operand" "")
2877 (match_operand:SF 3 "register_operand" "fr"))]
2878 "registers_ok_for_ldd (operands[1], operands[3])
2879 && ! MEM_VOLATILE_P (operands[0]) && ! MEM_VOLATILE_P (operands[2])
2880 && memory_ok_for_ldd (XEXP (operands[0], 0), XEXP (operands[2], 0))"
2884 [(set (match_operand:SI 0 "register_operand" "r")
2885 (match_operand:SI 1 "memory_operand" ""))
2886 (set (match_operand:SI 2 "register_operand" "r")
2887 (match_operand:SI 3 "memory_operand" ""))]
2888 "registers_ok_for_ldd (operands[2], operands[0])
2889 && ! MEM_VOLATILE_P (operands[3]) && ! MEM_VOLATILE_P (operands[1])
2890 && memory_ok_for_ldd (XEXP (operands[3], 0), XEXP (operands[1], 0))"
2894 [(set (match_operand:SI 0 "memory_operand" "")
2895 (match_operand:SI 1 "register_operand" "r"))
2896 (set (match_operand:SI 2 "memory_operand" "")
2897 (match_operand:SI 3 "register_operand" "r"))]
2898 "registers_ok_for_ldd (operands[3], operands[1])
2899 && ! MEM_VOLATILE_P (operands[2]) && ! MEM_VOLATILE_P (operands[0])
2900 && memory_ok_for_ldd (XEXP (operands[2], 0), XEXP (operands[0], 0))"
2904 [(set (match_operand:SF 0 "register_operand" "fr")
2905 (match_operand:SF 1 "memory_operand" ""))
2906 (set (match_operand:SF 2 "register_operand" "fr")
2907 (match_operand:SF 3 "memory_operand" ""))]
2908 "registers_ok_for_ldd (operands[2], operands[0])
2909 && ! MEM_VOLATILE_P (operands[3]) && ! MEM_VOLATILE_P (operands[1])
2910 && memory_ok_for_ldd (XEXP (operands[3], 0), XEXP (operands[1], 0))"
2914 [(set (match_operand:SF 0 "memory_operand" "")
2915 (match_operand:SF 1 "register_operand" "fr"))
2916 (set (match_operand:SF 2 "memory_operand" "")
2917 (match_operand:SF 3 "register_operand" "fr"))]
2918 "registers_ok_for_ldd (operands[3], operands[1])
2919 && ! MEM_VOLATILE_P (operands[2]) && ! MEM_VOLATILE_P (operands[0])
2920 && memory_ok_for_ldd (XEXP (operands[2], 0), XEXP (operands[0], 0))"
2923 ;; Optimize the case of following a reg-reg move with a test
2924 ;; of reg just moved.
2927 [(set (match_operand:SI 0 "register_operand" "=r")
2928 (match_operand:SI 1 "register_operand" "r"))
2930 (compare:CC (match_operand:SI 2 "register_operand" "r")
2932 "rtx_equal_p (operands[2], operands[0])
2933 || rtx_equal_p (operands[2], operands[1])"
2936 ;; Do {sign,zero}-extended compares somewhat more efficiently.
2937 ;; ??? Is this now the Right Way to do this? Or will SCRATCH
2938 ;; eventually have some impact here?
2941 [(set (match_operand:HI 0 "register_operand" "")
2942 (match_operand:HI 1 "memory_operand" ""))
2943 (set (match_operand:SI 2 "register_operand" "")
2944 (sign_extend:SI (match_dup 0)))
2946 (compare:CC (match_dup 2)
2949 "ldsh %1,%0\;orcc %0,%%g0,%2")
2952 [(set (match_operand:QI 0 "register_operand" "")
2953 (match_operand:QI 1 "memory_operand" ""))
2954 (set (match_operand:SI 2 "register_operand" "")
2955 (sign_extend:SI (match_dup 0)))
2957 (compare:CC (match_dup 2)
2960 "ldsb %1,%0\;orcc %0,%%g0,%2")
2963 [(set (match_operand:HI 0 "register_operand" "")
2964 (match_operand:HI 1 "memory_operand" ""))
2965 (set (match_operand:SI 2 "register_operand" "")
2966 (sign_extend:SI (match_dup 0)))]
2967 "dead_or_set_p (insn, operands[0])"
2970 warning (\"bad peephole\");
2971 if (! MEM_VOLATILE_P (operands[1]))
2973 return \"ldsh %1,%2\";
2977 [(set (match_operand:QI 0 "register_operand" "")
2978 (match_operand:QI 1 "memory_operand" ""))
2979 (set (match_operand:SI 2 "register_operand" "")
2980 (sign_extend:SI (match_dup 0)))]
2981 "dead_or_set_p (insn, operands[0])"
2984 warning (\"bad peephole\");
2985 if (! MEM_VOLATILE_P (operands[1]))
2987 return \"ldsb %1,%2\";
2990 ;; Floating-point move peepholes
2993 [(set (match_operand:SI 0 "register_operand" "=r")
2994 (lo_sum:SI (match_dup 0)
2995 (match_operand:SI 1 "immediate_operand" "i")))
2996 (set (match_operand:DF 2 "register_operand" "=fr")
2997 (mem:DF (match_dup 0)))]
2998 "RTX_UNCHANGING_P (operands[1]) && reg_unused_after (operands[0], insn)"
3001 /* Go by way of output_move_double in case the register in operand 2
3002 is not properly aligned for ldd. */
3003 operands[1] = gen_rtx (MEM, DFmode,
3004 gen_rtx (LO_SUM, SImode, operands[0], operands[1]));
3005 operands[0] = operands[2];
3006 return output_move_double (operands);
3010 [(set (match_operand:SI 0 "register_operand" "=r")
3011 (lo_sum:SI (match_dup 0)
3012 (match_operand:SI 1 "immediate_operand" "i")))
3013 (set (match_operand:SF 2 "register_operand" "=fr")
3014 (mem:SF (match_dup 0)))]
3015 "RTX_UNCHANGING_P (operands[1]) && reg_unused_after (operands[0], insn)"
3016 "ld [%0+%%lo(%a1)],%2")
3018 ;; Return peepholes. First the "normal" ones
3021 [(set (match_operand:SI 0 "restore_operand" "")
3022 (match_operand:SI 1 "arith_operand" "rI"))
3027 if (current_function_returns_struct)
3028 return \"jmp %%i7+12\;restore %%g0,%1,%Y0\";
3030 return \"ret\;restore %%g0,%1,%Y0\";
3032 [(set_attr "type" "multi")])
3035 [(set (match_operand:SI 0 "restore_operand" "")
3036 (plus:SI (match_operand:SI 1 "arith_operand" "%r")
3037 (match_operand:SI 2 "arith_operand" "rI")))
3042 if (current_function_returns_struct)
3043 return \"jmp %%i7+12\;restore %r1,%2,%Y0\";
3045 return \"ret\;restore %r1,%2,%Y0\";
3047 [(set_attr "type" "multi")])
3049 ;; Turned off because it should never match (subtracting a constant
3050 ;; is turned into addition) and because it would do the wrong thing
3051 ;; when operand 2 is -4096 (--4096 == 4096 is not a valid immediate).
3053 ;; [(set (match_operand:SI 0 "restore_operand" "")
3054 ;; (minus:SI (match_operand:SI 1 "register_operand" "r")
3055 ;; (match_operand:SI 2 "small_int" "I")))
3057 ;; "! TARGET_EPILOGUE"
3058 ;; "ret\;restore %1,-(%2),%Y0"
3059 ;; [(set_attr "type" "multi")])
3061 ;; The following pattern is only generated by delayed-branch scheduling,
3062 ;; when the insn winds up in the epilogue.
3065 (match_operand:SF 0 "register_operand" "f"))
3068 "ret\;fmovs %0,%%f0"
3069 [(set_attr "type" "multi")])
3071 ;; Now peepholes to go a call followed by a jump.
3074 [(parallel [(set (match_operand 0 "" "")
3075 (call (mem:SI (match_operand:SI 1 "call_operand_address" "S,r"))
3076 (match_operand 2 "" "")))
3077 (clobber (reg:SI 15))])
3078 (set (pc) (label_ref (match_operand 3 "" "")))]
3079 "short_branch (INSN_UID (insn), INSN_UID (operands[3]))"
3082 return \"call %a1,%2\;add %%o7,(%l3-.-4),%%o7\";
3086 [(parallel [(call (mem:SI (match_operand:SI 0 "call_operand_address" "S,r"))
3087 (match_operand 1 "" ""))
3088 (clobber (reg:SI 15))])
3089 (set (pc) (label_ref (match_operand 2 "" "")))]
3090 "short_branch (INSN_UID (insn), INSN_UID (operands[2]))"
3093 return \"call %a0,%1\;add %%o7,(%l2-.-4),%%o7\";
3097 [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
3098 (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
3100 (clobber (reg:CC 0))])
3101 (set (reg:CC 0) (compare (match_dup 0) (const_int 0)))]
3105 ;;- Local variables:
3107 ;;- comment-start: ";;- "
3108 ;;- eval: (set-syntax-table (copy-sequence (syntax-table)))
3109 ;;- eval: (modify-syntax-entry ?[ "(]")
3110 ;;- eval: (modify-syntax-entry ?] ")[")
3111 ;;- eval: (modify-syntax-entry ?{ "(}")
3112 ;;- eval: (modify-syntax-entry ?} "){")