1 ;;- Machine description for SPARC chip for GNU C compiler
2 ;; Copyright (C) 1987, 1988, 1989, 1992, 1993 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,uncond_branch,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" "uncond_branch,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 ;; ??? It is OK for fill_simple_delay_slots to put load/store instructions
97 ;; in a delay slot, but it is not OK for fill_eager_delay_slots to do so.
98 ;; This is because doing so will add several pipeline stalls to the path
99 ;; that the load/store did not come from. Unfortunately, there is no way
100 ;; to prevent fill_eager_delay_slots from using load/store without completely
101 ;; disabling them. For the SPEC benchmark set, this is a serious lose,
102 ;; because it prevents us from moving back the final store of inner loops.
104 (define_attr "in_branch_delay" "false,true"
105 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,call_no_delay_slot,multi")
106 (eq_attr "length" "1"))
107 (const_string "true")
108 (const_string "false")))
110 (define_attr "in_uncond_branch_delay" "false,true"
111 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,call_no_delay_slot,multi")
112 (eq_attr "length" "1"))
113 (const_string "true")
114 (const_string "false")))
116 (define_attr "in_annul_branch_delay" "false,true"
117 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,call_no_delay_slot,multi")
118 (eq_attr "length" "1"))
119 (const_string "true")
120 (const_string "false")))
122 (define_delay (eq_attr "type" "branch")
123 [(eq_attr "in_branch_delay" "true")
124 (nil) (eq_attr "in_annul_branch_delay" "true")])
126 (define_delay (eq_attr "type" "uncond_branch")
127 [(eq_attr "in_uncond_branch_delay" "true")
130 ;; Function units of the SPARC
132 ;; (define_function_unit {name} {num-units} {n-users} {test}
133 ;; {ready-delay} {issue-delay} [{conflict-list}])
136 ;; (Noted only for documentation; units that take one cycle do not need to
139 ;; On the sparclite, integer multiply takes 1, 3, or 5 cycles depending on
142 ;; (define_function_unit "alu" 1 0
143 ;; (eq_attr "type" "unary,binary,move,address") 1 0)
145 ;; Memory with load-delay of 1 (i.e., 2 cycle load).
146 (define_function_unit "memory" 1 1 (eq_attr "type" "load,fpload") 2 0)
148 ;; SPARC has two floating-point units: the FP ALU,
149 ;; and the FP MUL/DIV/SQRT unit.
150 ;; Instruction timings on the CY7C602 are as follows
164 ;; The CY7C602 can only support 2 fp isnsn simultaneously.
165 ;; More insns cause the chip to stall.
167 (define_function_unit "fp_alu" 1 1 (eq_attr "type" "fp") 5 0)
168 (define_function_unit "fp_mds" 1 1 (eq_attr "type" "fpmul") 7 0)
169 (define_function_unit "fp_mds" 1 1 (eq_attr "type" "fpdiv") 37 0)
170 (define_function_unit "fp_mds" 1 1 (eq_attr "type" "fpsqrt") 63 0)
172 ;; Compare instructions.
173 ;; This controls RTL generation and register allocation.
175 ;; We generate RTL for comparisons and branches by having the cmpxx
176 ;; patterns store away the operands. Then, the scc and bcc patterns
177 ;; emit RTL for both the compare and the branch.
179 ;; We do this because we want to generate different code for an sne and
180 ;; seq insn. In those cases, if the second operand of the compare is not
181 ;; const0_rtx, we want to compute the xor of the two operands and test
184 ;; We start with the DEFINE_EXPANDs, then then DEFINE_INSNs to match
185 ;; the patterns. Finally, we have the DEFINE_SPLITs for some of the scc
186 ;; insns that actually require more than one machine instruction.
188 ;; Put cmpsi first among compare insns so it matches two CONST_INT operands.
190 (define_expand "cmpsi"
192 (compare:CC (match_operand:SI 0 "register_operand" "")
193 (match_operand:SI 1 "arith_operand" "")))]
197 sparc_compare_op0 = operands[0];
198 sparc_compare_op1 = operands[1];
202 (define_expand "cmpsf"
204 (compare:CCFP (match_operand:SF 0 "register_operand" "")
205 (match_operand:SF 1 "register_operand" "")))]
209 sparc_compare_op0 = operands[0];
210 sparc_compare_op1 = operands[1];
214 (define_expand "cmpdf"
216 (compare:CCFP (match_operand:DF 0 "register_operand" "")
217 (match_operand:DF 1 "register_operand" "")))]
221 sparc_compare_op0 = operands[0];
222 sparc_compare_op1 = operands[1];
226 (define_expand "cmptf"
228 (compare:CCFP (match_operand:TF 0 "register_operand" "")
229 (match_operand:TF 1 "register_operand" "")))]
233 sparc_compare_op0 = operands[0];
234 sparc_compare_op1 = operands[1];
238 ;; Next come the scc insns. For seq, sne, sgeu, and sltu, we can do this
239 ;; without jumps using the addx/subx instructions. For the rest, we do
240 ;; branches. Seq_special and sne_special clobber the CC reg, because they
241 ;; generate addcc/subcc instructions.
243 (define_expand "seq_special"
244 [(set (match_dup 3) (xor:SI (match_operand:SI 1 "register_operand" "")
245 (match_operand:SI 2 "register_operand" "")))
246 (parallel [(set (match_operand:SI 0 "register_operand" "")
247 (eq:SI (match_dup 3) (const_int 0)))
248 (clobber (reg:CC 0))])]
251 "{ operands[3] = gen_reg_rtx (SImode); }")
253 (define_expand "sne_special"
254 [(set (match_dup 3) (xor:SI (match_operand:SI 1 "register_operand" "")
255 (match_operand:SI 2 "register_operand" "")))
256 (parallel [(set (match_operand:SI 0 "register_operand" "")
257 (ne:SI (match_dup 3) (const_int 0)))
258 (clobber (reg:CC 0))])]
260 "{ operands[3] = gen_reg_rtx (SImode); }")
263 [(set (match_operand:SI 0 "register_operand" "")
264 (eq:SI (match_dup 1) (const_int 0)))]
267 { if (GET_MODE (sparc_compare_op0) == SImode)
269 emit_insn (gen_seq_special (operands[0], sparc_compare_op0,
274 operands[1] = gen_compare_reg (EQ, sparc_compare_op0, sparc_compare_op1);
278 [(set (match_operand:SI 0 "register_operand" "")
279 (ne:SI (match_dup 1) (const_int 0)))]
282 { if (GET_MODE (sparc_compare_op0) == SImode)
284 emit_insn (gen_sne_special (operands[0], sparc_compare_op0,
289 operands[1] = gen_compare_reg (NE, sparc_compare_op0, sparc_compare_op1);
293 [(set (match_operand:SI 0 "register_operand" "")
294 (gt:SI (match_dup 1) (const_int 0)))]
297 { operands[1] = gen_compare_reg (GT, sparc_compare_op0, sparc_compare_op1); }")
300 [(set (match_operand:SI 0 "register_operand" "")
301 (lt:SI (match_dup 1) (const_int 0)))]
304 { operands[1] = gen_compare_reg (LT, sparc_compare_op0, sparc_compare_op1); }")
307 [(set (match_operand:SI 0 "register_operand" "")
308 (ge:SI (match_dup 1) (const_int 0)))]
311 { operands[1] = gen_compare_reg (GE, sparc_compare_op0, sparc_compare_op1); }")
314 [(set (match_operand:SI 0 "register_operand" "")
315 (le:SI (match_dup 1) (const_int 0)))]
318 { operands[1] = gen_compare_reg (LE, sparc_compare_op0, sparc_compare_op1); }")
320 (define_expand "sgtu"
321 [(set (match_operand:SI 0 "register_operand" "")
322 (gtu:SI (match_dup 1) (const_int 0)))]
328 /* We can do ltu easily, so if both operands are registers, swap them and
330 if ((GET_CODE (sparc_compare_op0) == REG
331 || GET_CODE (sparc_compare_op0) == SUBREG)
332 && (GET_CODE (sparc_compare_op1) == REG
333 || GET_CODE (sparc_compare_op1) == SUBREG))
335 tem = sparc_compare_op0;
336 sparc_compare_op0 = sparc_compare_op1;
337 sparc_compare_op1 = tem;
338 emit_insn (gen_sltu (operands[0]));
342 operands[1] = gen_compare_reg (LEU, sparc_compare_op0, sparc_compare_op1);
345 (define_expand "sltu"
346 [(set (match_operand:SI 0 "register_operand" "")
347 (ltu:SI (match_dup 1) (const_int 0)))]
350 { operands[1] = gen_compare_reg (LTU, sparc_compare_op0, sparc_compare_op1);
353 (define_expand "sgeu"
354 [(set (match_operand:SI 0 "register_operand" "")
355 (geu:SI (match_dup 1) (const_int 0)))]
358 { operands[1] = gen_compare_reg (GEU, sparc_compare_op0, sparc_compare_op1);
361 (define_expand "sleu"
362 [(set (match_operand:SI 0 "register_operand" "")
363 (leu:SI (match_dup 1) (const_int 0)))]
369 /* We can do geu easily, so if both operands are registers, swap them and
371 if ((GET_CODE (sparc_compare_op0) == REG
372 || GET_CODE (sparc_compare_op0) == SUBREG)
373 && (GET_CODE (sparc_compare_op1) == REG
374 || GET_CODE (sparc_compare_op1) == SUBREG))
376 tem = sparc_compare_op0;
377 sparc_compare_op0 = sparc_compare_op1;
378 sparc_compare_op1 = tem;
379 emit_insn (gen_sgeu (operands[0]));
383 operands[1] = gen_compare_reg (LEU, sparc_compare_op0, sparc_compare_op1);
386 ;; Now the DEFINE_INSNs for the compare and scc cases. First the compares.
390 (compare:CC (match_operand:SI 0 "register_operand" "r")
391 (match_operand:SI 1 "arith_operand" "rI")))]
394 [(set_attr "type" "compare")])
398 (compare:CCFPE (match_operand:DF 0 "register_operand" "f")
399 (match_operand:DF 1 "register_operand" "f")))]
402 [(set_attr "type" "fpcmp")])
406 (compare:CCFPE (match_operand:SF 0 "register_operand" "f")
407 (match_operand:SF 1 "register_operand" "f")))]
410 [(set_attr "type" "fpcmp")])
414 (compare:CCFPE (match_operand:TF 0 "register_operand" "f")
415 (match_operand:TF 1 "register_operand" "f")))]
418 [(set_attr "type" "fpcmp")])
422 (compare:CCFP (match_operand:DF 0 "register_operand" "f")
423 (match_operand:DF 1 "register_operand" "f")))]
426 [(set_attr "type" "fpcmp")])
430 (compare:CCFP (match_operand:SF 0 "register_operand" "f")
431 (match_operand:SF 1 "register_operand" "f")))]
434 [(set_attr "type" "fpcmp")])
438 (compare:CCFP (match_operand:TF 0 "register_operand" "f")
439 (match_operand:TF 1 "register_operand" "f")))]
442 [(set_attr "type" "fpcmp")])
444 ;; The SEQ and SNE patterns are special because they can be done
445 ;; without any branching and do not involve a COMPARE.
448 [(set (match_operand:SI 0 "register_operand" "=r")
449 (ne:SI (match_operand:SI 1 "register_operand" "r") (const_int 0)))
450 (clobber (reg:CC 0))]
452 "subcc %%g0,%1,%%g0\;addx %%g0,0,%0"
453 [(set_attr "type" "unary")
454 (set_attr "length" "2")])
457 [(set (match_operand:SI 0 "register_operand" "=r")
458 (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
460 (clobber (reg:CC 0))]
462 "subcc %%g0,%1,%%g0\;subx %%g0,0,%0"
463 [(set_attr "type" "unary")
464 (set_attr "length" "2")])
467 [(set (match_operand:SI 0 "register_operand" "=r")
468 (eq:SI (match_operand:SI 1 "register_operand" "r") (const_int 0)))
469 (clobber (reg:CC 0))]
471 "subcc %%g0,%1,%%g0\;subx %%g0,-1,%0"
472 [(set_attr "type" "unary")
473 (set_attr "length" "2")])
476 [(set (match_operand:SI 0 "register_operand" "=r")
477 (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
479 (clobber (reg:CC 0))]
481 "subcc %%g0,%1,%%g0\;addx %%g0,-1,%0"
482 [(set_attr "type" "unary")
483 (set_attr "length" "2")])
485 ;; We can also do (x + (i == 0)) and related, so put them in.
488 [(set (match_operand:SI 0 "register_operand" "=r")
489 (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
491 (match_operand:SI 2 "register_operand" "r")))
492 (clobber (reg:CC 0))]
494 "subcc %%g0,%1,%%g0\;addx %2,0,%0"
495 [(set_attr "length" "2")])
498 [(set (match_operand:SI 0 "register_operand" "=r")
499 (minus:SI (match_operand:SI 2 "register_operand" "r")
500 (ne:SI (match_operand:SI 1 "register_operand" "r")
502 (clobber (reg:CC 0))]
504 "subcc %%g0,%1,%%g0\;subx %2,0,%0"
505 [(set_attr "length" "2")])
508 [(set (match_operand:SI 0 "register_operand" "=r")
509 (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
511 (match_operand:SI 2 "register_operand" "r")))
512 (clobber (reg:CC 0))]
514 "subcc %%g0,%1,%%g0\;subx %2,-1,%0"
515 [(set_attr "length" "2")])
518 [(set (match_operand:SI 0 "register_operand" "=r")
519 (minus:SI (match_operand:SI 2 "register_operand" "r")
520 (eq:SI (match_operand:SI 1 "register_operand" "r")
522 (clobber (reg:CC 0))]
524 "subcc %%g0,%1,%%g0\;addx %2,-1,%0"
525 [(set_attr "length" "2")])
527 ;; We can also do GEU and LTU directly, but these operate after a
531 [(set (match_operand:SI 0 "register_operand" "=r")
532 (ltu:SI (reg:CC 0) (const_int 0)))]
535 [(set_attr "type" "misc")])
538 [(set (match_operand:SI 0 "register_operand" "=r")
539 (neg:SI (ltu:SI (reg:CC 0) (const_int 0))))]
542 [(set_attr "type" "misc")])
544 ;; ??? Combine should canonicalize these next two to the same pattern.
546 [(set (match_operand:SI 0 "register_operand" "=r")
547 (minus:SI (neg:SI (ltu:SI (reg:CC 0) (const_int 0)))
548 (match_operand:SI 1 "arith_operand" "rI")))]
551 [(set_attr "type" "unary")])
554 [(set (match_operand:SI 0 "register_operand" "=r")
555 (neg:SI (plus:SI (ltu:SI (reg:CC 0) (const_int 0))
556 (match_operand:SI 1 "arith_operand" "rI"))))]
559 [(set_attr "type" "unary")])
562 [(set (match_operand:SI 0 "register_operand" "=r")
563 (geu:SI (reg:CC 0) (const_int 0)))]
566 [(set_attr "type" "misc")])
569 [(set (match_operand:SI 0 "register_operand" "=r")
570 (neg:SI (geu:SI (reg:CC 0) (const_int 0))))]
573 [(set_attr "type" "misc")])
575 ;; We can also do (x + ((unsigned) i >= 0)) and related, so put them in.
578 [(set (match_operand:SI 0 "register_operand" "=r")
579 (plus:SI (ltu:SI (reg:CC 0) (const_int 0))
580 (match_operand:SI 1 "arith_operand" "rI")))]
583 [(set_attr "type" "unary")])
586 [(set (match_operand:SI 0 "register_operand" "=r")
587 (plus:SI (ltu:SI (reg:CC 0) (const_int 0))
588 (plus:SI (match_operand:SI 1 "arith_operand" "%r")
589 (match_operand:SI 2 "arith_operand" "rI"))))]
594 [(set (match_operand:SI 0 "register_operand" "=r")
595 (minus:SI (match_operand:SI 1 "register_operand" "r")
596 (ltu:SI (reg:CC 0) (const_int 0))))]
599 [(set_attr "type" "unary")])
601 ;; ??? Combine should canonicalize these next two to the same pattern.
603 [(set (match_operand:SI 0 "register_operand" "=r")
604 (minus:SI (minus:SI (match_operand:SI 1 "register_operand" "r")
605 (match_operand:SI 2 "arith_operand" "rI"))
606 (ltu:SI (reg:CC 0) (const_int 0))))]
611 [(set (match_operand:SI 0 "register_operand" "=r")
612 (minus:SI (match_operand:SI 1 "register_operand" "r")
613 (plus:SI (ltu:SI (reg:CC 0) (const_int 0))
614 (match_operand:SI 2 "arith_operand" "rI"))))]
619 [(set (match_operand:SI 0 "register_operand" "=r")
620 (plus:SI (geu:SI (reg:CC 0) (const_int 0))
621 (match_operand:SI 1 "register_operand" "r")))]
624 [(set_attr "type" "unary")])
627 [(set (match_operand:SI 0 "register_operand" "=r")
628 (minus:SI (match_operand:SI 1 "register_operand" "r")
629 (geu:SI (reg:CC 0) (const_int 0))))]
632 [(set_attr "type" "unary")])
634 ;; Now we have the generic scc insns. These will be done using a jump.
635 ;; We have to exclude the cases above, since we will not want combine to
636 ;; turn something that does not require a jump into something that does.
638 [(set (match_operand:SI 0 "register_operand" "=r")
639 (match_operator:SI 1 "noov_compare_op" [(reg 0) (const_int 0)]))]
641 "* return output_scc_insn (operands, insn); "
642 [(set_attr "type" "multi")
643 (set_attr "length" "3")])
645 ;; These control RTL generation for conditional jump insns
649 (if_then_else (eq (match_dup 1) (const_int 0))
650 (label_ref (match_operand 0 "" ""))
654 { operands[1] = gen_compare_reg (EQ, sparc_compare_op0, sparc_compare_op1); }")
658 (if_then_else (ne (match_dup 1) (const_int 0))
659 (label_ref (match_operand 0 "" ""))
663 { operands[1] = gen_compare_reg (NE, sparc_compare_op0, sparc_compare_op1); }")
667 (if_then_else (gt (match_dup 1) (const_int 0))
668 (label_ref (match_operand 0 "" ""))
672 { operands[1] = gen_compare_reg (GT, sparc_compare_op0, sparc_compare_op1); }")
674 (define_expand "bgtu"
676 (if_then_else (gtu (match_dup 1) (const_int 0))
677 (label_ref (match_operand 0 "" ""))
681 { operands[1] = gen_compare_reg (GTU, sparc_compare_op0, sparc_compare_op1);
686 (if_then_else (lt (match_dup 1) (const_int 0))
687 (label_ref (match_operand 0 "" ""))
691 { operands[1] = gen_compare_reg (LT, sparc_compare_op0, sparc_compare_op1); }")
693 (define_expand "bltu"
695 (if_then_else (ltu (match_dup 1) (const_int 0))
696 (label_ref (match_operand 0 "" ""))
700 { operands[1] = gen_compare_reg (LTU, sparc_compare_op0, sparc_compare_op1);
705 (if_then_else (ge (match_dup 1) (const_int 0))
706 (label_ref (match_operand 0 "" ""))
710 { operands[1] = gen_compare_reg (GE, sparc_compare_op0, sparc_compare_op1); }")
712 (define_expand "bgeu"
714 (if_then_else (geu (match_dup 1) (const_int 0))
715 (label_ref (match_operand 0 "" ""))
719 { operands[1] = gen_compare_reg (GEU, sparc_compare_op0, sparc_compare_op1);
724 (if_then_else (le (match_dup 1) (const_int 0))
725 (label_ref (match_operand 0 "" ""))
729 { operands[1] = gen_compare_reg (LE, sparc_compare_op0, sparc_compare_op1); }")
731 (define_expand "bleu"
733 (if_then_else (leu (match_dup 1) (const_int 0))
734 (label_ref (match_operand 0 "" ""))
738 { operands[1] = gen_compare_reg (LEU, sparc_compare_op0, sparc_compare_op1);
741 ;; Now match both normal and inverted jump.
745 (if_then_else (match_operator 0 "noov_compare_op"
746 [(reg 0) (const_int 0)])
747 (label_ref (match_operand 1 "" ""))
752 return output_cbranch (operands[0], 1, 0,
753 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
756 [(set_attr "type" "branch")])
760 (if_then_else (match_operator 0 "noov_compare_op"
761 [(reg 0) (const_int 0)])
763 (label_ref (match_operand 1 "" ""))))]
767 return output_cbranch (operands[0], 1, 1,
768 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
771 [(set_attr "type" "branch")])
775 (define_expand "movqi"
776 [(set (match_operand:QI 0 "general_operand" "")
777 (match_operand:QI 1 "general_operand" ""))]
781 if (emit_move_sequence (operands, QImode))
786 [(set (match_operand:QI 0 "reg_or_nonsymb_mem_operand" "=r,r,r,Q")
787 (match_operand:QI 1 "move_operand" "rI,K,Q,rJ"))]
788 "register_operand (operands[0], QImode)
789 || register_operand (operands[1], QImode)
790 || operands[1] == const0_rtx"
796 [(set_attr "type" "move,move,load,store")
797 (set_attr "length" "*,1,*,1")])
800 [(set (match_operand:QI 0 "register_operand" "=r")
801 (subreg:QI (lo_sum:SI (match_operand:QI 1 "register_operand" "r")
802 (match_operand 2 "immediate_operand" "in")) 0))]
805 [(set_attr "length" "1")])
808 [(set (mem:QI (match_operand:SI 0 "symbolic_operand" ""))
809 (match_operand:QI 1 "reg_or_0_operand" "rJ"))
810 (clobber (match_scratch:SI 2 "=&r"))]
812 "sethi %%hi(%a0),%2\;stb %r1,[%2+%%lo(%a0)]"
813 [(set_attr "type" "store")
814 (set_attr "length" "2")])
816 (define_expand "movhi"
817 [(set (match_operand:HI 0 "general_operand" "")
818 (match_operand:HI 1 "general_operand" ""))]
822 if (emit_move_sequence (operands, HImode))
827 [(set (match_operand:HI 0 "reg_or_nonsymb_mem_operand" "=r,r,r,Q")
828 (match_operand:HI 1 "move_operand" "rI,K,Q,rJ"))]
829 "register_operand (operands[0], HImode)
830 || register_operand (operands[1], HImode)
831 || operands[1] == const0_rtx"
837 [(set_attr "type" "move,move,load,store")
838 (set_attr "length" "*,1,*,1")])
841 [(set (match_operand:HI 0 "register_operand" "=r")
842 (lo_sum:HI (match_operand:HI 1 "register_operand" "r")
843 (match_operand 2 "immediate_operand" "in")))]
846 [(set_attr "length" "1")])
849 [(set (mem:HI (match_operand:SI 0 "symbolic_operand" ""))
850 (match_operand:HI 1 "reg_or_0_operand" "rJ"))
851 (clobber (match_scratch:SI 2 "=&r"))]
853 "sethi %%hi(%a0),%2\;sth %r1,[%2+%%lo(%a0)]"
854 [(set_attr "type" "store")
855 (set_attr "length" "2")])
857 (define_expand "movsi"
858 [(set (match_operand:SI 0 "general_operand" "")
859 (match_operand:SI 1 "general_operand" ""))]
863 if (emit_move_sequence (operands, SImode))
867 ;; We must support both 'r' and 'f' registers here, because combine may
868 ;; convert SFmode hard registers to SImode hard registers when simplifying
871 ;; We cannot combine the similar 'r' and 'f' constraints, because it causes
872 ;; problems with register allocation. Reload might try to put an integer
873 ;; in an fp register, or an fp number is an integer register.
876 [(set (match_operand:SI 0 "reg_or_nonsymb_mem_operand" "=r,f,r,r,f,Q,Q")
877 (match_operand:SI 1 "move_operand" "rI,!f,K,Q,!Q,rJ,!f"))]
878 "register_operand (operands[0], SImode)
879 || register_operand (operands[1], SImode)
880 || operands[1] == const0_rtx"
889 [(set_attr "type" "move,fp,move,load,load,store,store")
890 (set_attr "length" "*,*,1,*,*,*,*")])
892 ;; Special pic pattern, for loading the address of a label into a register.
893 ;; It clobbers o7 because the call puts the return address (i.e. pc value)
897 [(set (match_operand:SI 0 "register_operand" "=r")
898 (match_operand:SI 1 "move_pic_label" "i"))
899 (set (reg:SI 15) (pc))]
901 "\\n1:\;call 2f\;sethi %%hi(%l1-1b),%0\\n2:\\tor %0,%%lo(%l1-1b),%0\;add %0,%%o7,%0"
902 [(set_attr "type" "multi")
903 (set_attr "length" "4")])
906 [(set (match_operand:DI 0 "register_operand" "=r")
907 (high:DI (match_operand 1 "" "")))]
911 rtx op0 = operands[0];
912 rtx op1 = operands[1];
914 if (GET_CODE (op1) == CONST_INT)
916 operands[0] = operand_subword (op0, 1, 0, DImode);
917 output_asm_insn (\"sethi %%hi(%a1),%0\", operands);
919 operands[0] = operand_subword (op0, 0, 0, DImode);
920 if (INTVAL (op1) < 0)
921 return \"mov -1,%0\";
925 else if (GET_CODE (op1) == CONST_DOUBLE)
927 operands[0] = operand_subword (op0, 1, 0, DImode);
928 operands[1] = gen_rtx (CONST_INT, VOIDmode, CONST_DOUBLE_LOW (op1));
929 output_asm_insn (\"sethi %%hi(%a1),%0\", operands);
931 operands[0] = operand_subword (op0, 0, 0, DImode);
932 operands[1] = gen_rtx (CONST_INT, VOIDmode, CONST_DOUBLE_HIGH (op1));
933 return singlemove_string (operands);
939 [(set_attr "type" "move")
940 (set_attr "length" "2")])
942 ;; For PIC, symbol_refs are put inside unspec so that the optimizer won't
943 ;; confuse them with real addresses.
945 [(set (match_operand:SI 0 "register_operand" "=r")
946 (high:SI (unspec:SI [(match_operand 1 "" "")] 0)))]
949 [(set_attr "type" "move")
950 (set_attr "length" "1")])
953 [(set (match_operand:SI 0 "register_operand" "=r")
954 (high:SI (match_operand 1 "" "")))]
957 [(set_attr "type" "move")
958 (set_attr "length" "1")])
961 [(set (match_operand:HI 0 "register_operand" "=r")
962 (high:HI (match_operand 1 "" "")))]
965 [(set_attr "type" "move")
966 (set_attr "length" "1")])
968 ;; For PIC, symbol_refs are put inside unspec so that the optimizer won't
969 ;; confuse them with real addresses.
971 [(set (match_operand:SI 0 "register_operand" "=r")
972 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
973 (unspec:SI [(match_operand:SI 2 "immediate_operand" "in")] 0)))]
976 ;; Need to set length for this arith insn because operand2
977 ;; is not an "arith_operand".
978 [(set_attr "length" "1")])
980 ;; ??? Can the next two be moved above the PIC stuff?
983 [(set (match_operand:SI 0 "register_operand" "=r")
984 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
985 (match_operand:SI 2 "immediate_operand" "in")))]
988 ;; Need to set length for this arith insn because operand2
989 ;; is not an "arith_operand".
990 [(set_attr "length" "1")])
993 [(set (mem:SI (match_operand:SI 0 "symbolic_operand" ""))
994 (match_operand:SI 1 "reg_or_0_operand" "rJ"))
995 (clobber (match_scratch:SI 2 "=&r"))]
997 "sethi %%hi(%a0),%2\;st %r1,[%2+%%lo(%a0)]"
998 [(set_attr "type" "store")
999 (set_attr "length" "2")])
1001 (define_expand "movdi"
1002 [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand" "")
1003 (match_operand:DI 1 "general_operand" ""))]
1007 if (emit_move_sequence (operands, DImode))
1012 [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand" "=r,T,U,Q,r,r,?f,?f,?Q")
1013 (match_operand:DI 1 "general_operand" "r,U,T,r,Q,i,f,Q,f"))]
1014 "register_operand (operands[0], DImode)
1015 || register_operand (operands[1], DImode)
1016 || operands[1] == const0_rtx"
1019 if (FP_REG_P (operands[0]) || FP_REG_P (operands[1]))
1020 return output_fp_move_double (operands);
1021 return output_move_double (operands);
1023 [(set_attr "type" "move,store,load,store,load,multi,fp,fpload,fpstore")
1024 (set_attr "length" "2,1,1,3,3,3,2,3,3")])
1027 [(set (match_operand:DI 0 "register_operand" "=r")
1028 (lo_sum:DI (match_operand:DI 1 "register_operand" "0")
1029 (match_operand:DI 2 "immediate_operand" "in")))]
1033 /* Don't output a 64 bit constant, since we can't trust the assembler to
1034 handle it correctly. */
1035 if (GET_CODE (operands[2]) == CONST_DOUBLE)
1036 operands[2] = gen_rtx (CONST_INT, VOIDmode, CONST_DOUBLE_LOW (operands[2]));
1037 return \"or %R1,%%lo(%a2),%R0\";
1039 ;; Need to set length for this arith insn because operand2
1040 ;; is not an "arith_operand".
1041 [(set_attr "length" "1")])
1043 ;; ??? There's no symbolic (set (mem:DI ...) ...).
1045 ;; Block move insns.
1047 ;; ??? We get better code without it. See output_block_move in sparc.c.
1049 ;; The definition of this insn does not really explain what it does,
1050 ;; but it should suffice
1051 ;; that anything generated as this insn will be recognized as one
1052 ;; and that it will not successfully combine with anything.
1053 ;(define_expand "movstrsi"
1054 ; [(parallel [(set (mem:BLK (match_operand:BLK 0 "general_operand" ""))
1055 ; (mem:BLK (match_operand:BLK 1 "general_operand" "")))
1056 ; (use (match_operand:SI 2 "nonmemory_operand" ""))
1057 ; (use (match_operand:SI 3 "immediate_operand" ""))
1058 ; (clobber (match_dup 0))
1059 ; (clobber (match_dup 1))
1060 ; (clobber (match_scratch:SI 4 ""))
1061 ; (clobber (reg:SI 0))
1062 ; (clobber (reg:SI 1))])]
1066 ; /* If the size isn't known, don't emit inline code. output_block_move
1067 ; would output code that's much slower than the library function.
1068 ; Also don't output code for large blocks. */
1069 ; if (GET_CODE (operands[2]) != CONST_INT
1070 ; || GET_CODE (operands[3]) != CONST_INT
1071 ; || INTVAL (operands[2]) / INTVAL (operands[3]) > 16)
1074 ; operands[0] = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
1075 ; operands[1] = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
1076 ; operands[2] = force_not_mem (operands[2]);
1080 ; [(set (mem:BLK (match_operand:SI 0 "register_operand" "+r"))
1081 ; (mem:BLK (match_operand:SI 1 "register_operand" "+r")))
1082 ; (use (match_operand:SI 2 "nonmemory_operand" "rn"))
1083 ; (use (match_operand:SI 3 "immediate_operand" "i"))
1084 ; (clobber (match_dup 0))
1085 ; (clobber (match_dup 1))
1086 ; (clobber (match_scratch:SI 4 "=&r"))
1087 ; (clobber (reg:SI 0))
1088 ; (clobber (reg:SI 1))]
1090 ; "* return output_block_move (operands);"
1091 ; [(set_attr "type" "multi")
1092 ; (set_attr "length" "6")])
1094 ;; Floating point move insns
1096 ;; This pattern forces (set (reg:SF ...) (const_double ...))
1097 ;; to be reloaded by putting the constant into memory.
1098 ;; It must come before the more general movsf pattern.
1100 [(set (match_operand:SF 0 "general_operand" "=?r,f,m")
1101 (match_operand:SF 1 "" "?E,m,G"))]
1102 "TARGET_FPU && GET_CODE (operands[1]) == CONST_DOUBLE"
1105 switch (which_alternative)
1108 return singlemove_string (operands);
1110 return \"ld %1,%0\";
1112 return \"st %%g0,%0\";
1115 [(set_attr "type" "load,fpload,store")
1116 (set_attr "length" "2,1,1")])
1118 (define_expand "movsf"
1119 [(set (match_operand:SF 0 "general_operand" "")
1120 (match_operand:SF 1 "general_operand" ""))]
1124 if (emit_move_sequence (operands, SFmode))
1129 [(set (match_operand:SF 0 "reg_or_nonsymb_mem_operand" "=f,r,f,r,Q,Q")
1130 (match_operand:SF 1 "reg_or_nonsymb_mem_operand" "f,r,Q,Q,f,r"))]
1132 && (register_operand (operands[0], SFmode)
1133 || register_operand (operands[1], SFmode))"
1141 [(set_attr "type" "fp,move,fpload,load,fpstore,store")])
1143 ;; Exactly the same as above, except that all `f' cases are deleted.
1144 ;; This is necessary to prevent reload from ever trying to use a `f' reg
1148 [(set (match_operand:SF 0 "reg_or_nonsymb_mem_operand" "=r,r,Q")
1149 (match_operand:SF 1 "reg_or_nonsymb_mem_operand" "r,Q,r"))]
1151 && (register_operand (operands[0], SFmode)
1152 || register_operand (operands[1], SFmode))"
1157 [(set_attr "type" "move,load,store")])
1160 [(set (mem:SF (match_operand:SI 0 "symbolic_operand" "i"))
1161 (match_operand:SF 1 "reg_or_0_operand" "rfG"))
1162 (clobber (match_scratch:SI 2 "=&r"))]
1164 "sethi %%hi(%a0),%2\;st %r1,[%2+%%lo(%a0)]"
1165 [(set_attr "type" "store")
1166 (set_attr "length" "2")])
1168 ;; This pattern forces (set (reg:DF ...) (const_double ...))
1169 ;; to be reloaded by putting the constant into memory.
1170 ;; It must come before the more general movdf pattern.
1173 [(set (match_operand:DF 0 "general_operand" "=?r,f,o")
1174 (match_operand:DF 1 "" "?E,m,G"))]
1175 "TARGET_FPU && GET_CODE (operands[1]) == CONST_DOUBLE"
1178 switch (which_alternative)
1181 return output_move_double (operands);
1183 return output_fp_move_double (operands);
1185 operands[1] = adj_offsettable_operand (operands[0], 4);
1186 return \"st %%g0,%0\;st %%g0,%1\";
1189 [(set_attr "type" "load,fpload,store")
1190 (set_attr "length" "3,3,3")])
1192 (define_expand "movdf"
1193 [(set (match_operand:DF 0 "general_operand" "")
1194 (match_operand:DF 1 "general_operand" ""))]
1198 if (emit_move_sequence (operands, DFmode))
1203 [(set (match_operand:DF 0 "reg_or_nonsymb_mem_operand" "=T,U,f,r,Q,Q,f,r")
1204 (match_operand:DF 1 "reg_or_nonsymb_mem_operand" "U,T,f,r,f,r,Q,Q"))]
1206 && (register_operand (operands[0], DFmode)
1207 || register_operand (operands[1], DFmode))"
1210 if (FP_REG_P (operands[0]) || FP_REG_P (operands[1]))
1211 return output_fp_move_double (operands);
1212 return output_move_double (operands);
1214 [(set_attr "type" "fpstore,fpload,fp,move,fpstore,store,fpload,load")
1215 (set_attr "length" "1,1,2,2,3,3,3,3")])
1217 ;; Exactly the same as above, except that all `f' cases are deleted.
1218 ;; This is necessary to prevent reload from ever trying to use a `f' reg
1222 [(set (match_operand:DF 0 "reg_or_nonsymb_mem_operand" "=T,U,r,Q,&r")
1223 (match_operand:DF 1 "reg_or_nonsymb_mem_operand" "U,T,r,r,Q"))]
1225 && (register_operand (operands[0], DFmode)
1226 || register_operand (operands[1], DFmode))"
1227 "* return output_move_double (operands);"
1228 [(set_attr "type" "store,load,move,store,load")
1229 (set_attr "length" "1,1,2,3,3")])
1232 [(set (match_operand:DF 0 "register_operand" "")
1233 (match_operand:DF 1 "register_operand" ""))]
1235 [(set (match_dup 2) (match_dup 3))
1236 (set (match_dup 4) (match_dup 5))]
1238 { operands[2] = operand_subword (operands[0], 0, 0, DFmode);
1239 operands[3] = operand_subword (operands[1], 0, 0, DFmode);
1240 operands[4] = operand_subword (operands[0], 1, 0, DFmode);
1241 operands[5] = operand_subword (operands[1], 1, 0, DFmode); }")
1244 [(set (mem:DF (match_operand:SI 0 "symbolic_operand" "i,i"))
1245 (match_operand:DF 1 "reg_or_0_operand" "rf,G"))
1246 (clobber (match_scratch:SI 2 "=&r,&r"))]
1250 output_asm_insn (\"sethi %%hi(%a0),%2\", operands);
1251 if (which_alternative == 0)
1252 return \"std %1,[%2+%%lo(%a0)]\";
1254 return \"st %%g0,[%2+%%lo(%a0)]\;st %%g0,[%2+%%lo(%a0+4)]\";
1256 [(set_attr "type" "store")
1257 (set_attr "length" "3")])
1259 ;; This pattern forces (set (reg:TF ...) (const_double ...))
1260 ;; to be reloaded by putting the constant into memory.
1261 ;; It must come before the more general movtf pattern.
1263 [(set (match_operand:TF 0 "general_operand" "=?r,f,o")
1264 (match_operand:TF 1 "" "?E,m,G"))]
1265 "TARGET_FPU && GET_CODE (operands[1]) == CONST_DOUBLE"
1268 switch (which_alternative)
1271 return output_move_quad (operands);
1273 return output_fp_move_quad (operands);
1275 operands[1] = adj_offsettable_operand (operands[0], 4);
1276 operands[2] = adj_offsettable_operand (operands[0], 8);
1277 operands[3] = adj_offsettable_operand (operands[0], 12);
1278 return \"st %%g0,%0\;st %%g0,%1\;st %%g0,%2\;st %%g0,%3\";
1281 [(set_attr "type" "load,fpload,store")
1282 (set_attr "length" "5,5,5")])
1284 (define_expand "movtf"
1285 [(set (match_operand:TF 0 "general_operand" "")
1286 (match_operand:TF 1 "general_operand" ""))]
1290 if (emit_move_sequence (operands, TFmode))
1295 [(set (match_operand:TF 0 "reg_or_nonsymb_mem_operand" "=f,r,Q,Q,f,&r")
1296 (match_operand:TF 1 "reg_or_nonsymb_mem_operand" "f,r,f,r,Q,Q"))]
1298 && (register_operand (operands[0], TFmode)
1299 || register_operand (operands[1], TFmode))"
1302 if (FP_REG_P (operands[0]) || FP_REG_P (operands[1]))
1303 return output_fp_move_quad (operands);
1304 return output_move_quad (operands);
1306 [(set_attr "type" "fp,move,fpstore,store,fpload,load")
1307 (set_attr "length" "4,4,5,5,5,5")])
1309 ;; Exactly the same as above, except that all `f' cases are deleted.
1310 ;; This is necessary to prevent reload from ever trying to use a `f' reg
1314 [(set (match_operand:TF 0 "reg_or_nonsymb_mem_operand" "=r,Q,&r")
1315 (match_operand:TF 1 "reg_or_nonsymb_mem_operand" "r,r,Q"))]
1317 && (register_operand (operands[0], TFmode)
1318 || register_operand (operands[1], TFmode))"
1321 if (FP_REG_P (operands[0]) || FP_REG_P (operands[1]))
1322 return output_fp_move_quad (operands);
1323 return output_move_quad (operands);
1325 [(set_attr "type" "move,store,load")
1326 (set_attr "length" "4,5,5")])
1329 [(set (mem:TF (match_operand:SI 0 "symbolic_operand" "i,i"))
1330 (match_operand:TF 1 "reg_or_0_operand" "rf,G"))
1331 (clobber (match_scratch:SI 2 "=&r,&r"))]
1335 output_asm_insn (\"sethi %%hi(%a0),%2\", operands);
1336 if (which_alternative == 0)
1337 return \"std %1,[%2+%%lo(%a0)]\;std %S1,[%2+%%lo(%a0+8)]\";
1339 return \"st %%g0,[%2+%%lo(%a0)]\;st %%g0,[%2+%%lo(%a0+4)]\; st %%g0,[%2+%%lo(%a0+8)]\;st %%g0,[%2+%%lo(%a0+12)]\";
1341 [(set_attr "type" "store")
1342 (set_attr "length" "5")])
1344 ;;- zero extension instructions
1346 ;; These patterns originally accepted general_operands, however, slightly
1347 ;; better code is generated by only accepting register_operands, and then
1348 ;; letting combine generate the ldu[hb] insns.
1350 (define_expand "zero_extendhisi2"
1351 [(set (match_operand:SI 0 "register_operand" "")
1352 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
1356 rtx temp = gen_reg_rtx (SImode);
1357 rtx shift_16 = gen_rtx (CONST_INT, VOIDmode, 16);
1358 int op1_subword = 0;
1360 if (GET_CODE (operand1) == SUBREG)
1362 op1_subword = SUBREG_WORD (operand1);
1363 operand1 = XEXP (operand1, 0);
1366 emit_insn (gen_ashlsi3 (temp, gen_rtx (SUBREG, SImode, operand1,
1369 emit_insn (gen_lshrsi3 (operand0, temp, shift_16));
1374 [(set (match_operand:SI 0 "register_operand" "=r")
1375 (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
1378 [(set_attr "type" "load")])
1380 (define_expand "zero_extendqihi2"
1381 [(set (match_operand:HI 0 "register_operand" "")
1382 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
1387 [(set (match_operand:HI 0 "register_operand" "=r,r")
1388 (zero_extend:HI (match_operand:QI 1 "sparc_operand" "r,Q")))]
1389 "GET_CODE (operands[1]) != CONST_INT"
1393 [(set_attr "type" "unary,load")
1394 (set_attr "length" "1")])
1396 (define_expand "zero_extendqisi2"
1397 [(set (match_operand:SI 0 "register_operand" "")
1398 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
1403 [(set (match_operand:SI 0 "register_operand" "=r,r")
1404 (zero_extend:SI (match_operand:QI 1 "sparc_operand" "r,Q")))]
1405 "GET_CODE (operands[1]) != CONST_INT"
1409 [(set_attr "type" "unary,load")
1410 (set_attr "length" "1")])
1414 (compare:CC (zero_extend:SI (match_operand:QI 0 "register_operand" "r"))
1417 "andcc %0,0xff,%%g0"
1418 [(set_attr "type" "compare")])
1422 (compare:CC (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
1424 (set (match_operand:SI 0 "register_operand" "=r")
1425 (zero_extend:SI (match_dup 1)))]
1428 [(set_attr "type" "unary")])
1430 ;; Similarly, handle SI->QI mode truncation followed by a compare.
1434 (compare:CC (subreg:QI (match_operand:SI 0 "register_operand" "r") 0)
1437 "andcc %0,0xff,%%g0"
1438 [(set_attr "type" "compare")])
1442 (compare:CC (subreg:QI (match_operand:SI 1 "register_operand" "r") 0)
1444 (set (match_operand:QI 0 "register_operand" "=r")
1448 [(set_attr "type" "unary")])
1450 ;;- sign extension instructions
1452 ;; These patterns originally accepted general_operands, however, slightly
1453 ;; better code is generated by only accepting register_operands, and then
1454 ;; letting combine generate the lds[hb] insns.
1456 (define_expand "extendhisi2"
1457 [(set (match_operand:SI 0 "register_operand" "")
1458 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
1462 rtx temp = gen_reg_rtx (SImode);
1463 rtx shift_16 = gen_rtx (CONST_INT, VOIDmode, 16);
1464 int op1_subword = 0;
1466 if (GET_CODE (operand1) == SUBREG)
1468 op1_subword = SUBREG_WORD (operand1);
1469 operand1 = XEXP (operand1, 0);
1472 emit_insn (gen_ashlsi3 (temp, gen_rtx (SUBREG, SImode, operand1,
1475 emit_insn (gen_ashrsi3 (operand0, temp, shift_16));
1480 [(set (match_operand:SI 0 "register_operand" "=r")
1481 (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
1484 [(set_attr "type" "load")])
1486 (define_expand "extendqihi2"
1487 [(set (match_operand:HI 0 "register_operand" "")
1488 (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
1492 rtx temp = gen_reg_rtx (SImode);
1493 rtx shift_24 = gen_rtx (CONST_INT, VOIDmode, 24);
1494 int op1_subword = 0;
1495 int op0_subword = 0;
1497 if (GET_CODE (operand1) == SUBREG)
1499 op1_subword = SUBREG_WORD (operand1);
1500 operand1 = XEXP (operand1, 0);
1502 if (GET_CODE (operand0) == SUBREG)
1504 op0_subword = SUBREG_WORD (operand0);
1505 operand0 = XEXP (operand0, 0);
1507 emit_insn (gen_ashlsi3 (temp, gen_rtx (SUBREG, SImode, operand1,
1510 if (GET_MODE (operand0) != SImode)
1511 operand0 = gen_rtx (SUBREG, SImode, operand0, op0_subword);
1512 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
1517 [(set (match_operand:HI 0 "register_operand" "=r")
1518 (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
1521 [(set_attr "type" "load")])
1523 (define_expand "extendqisi2"
1524 [(set (match_operand:SI 0 "register_operand" "")
1525 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
1529 rtx temp = gen_reg_rtx (SImode);
1530 rtx shift_24 = gen_rtx (CONST_INT, VOIDmode, 24);
1531 int op1_subword = 0;
1533 if (GET_CODE (operand1) == SUBREG)
1535 op1_subword = SUBREG_WORD (operand1);
1536 operand1 = XEXP (operand1, 0);
1539 emit_insn (gen_ashlsi3 (temp, gen_rtx (SUBREG, SImode, operand1,
1542 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
1547 [(set (match_operand:SI 0 "register_operand" "=r")
1548 (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
1551 [(set_attr "type" "load")])
1553 ;; Special pattern for optimizing bit-field compares. This is needed
1554 ;; because combine uses this as a canonical form.
1559 (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
1560 (match_operand:SI 1 "small_int" "n")
1561 (match_operand:SI 2 "small_int" "n"))
1563 "INTVAL (operands[2]) > 19"
1566 int len = INTVAL (operands[1]);
1567 int pos = 32 - INTVAL (operands[2]) - len;
1568 unsigned mask = ((1 << len) - 1) << pos;
1570 operands[1] = gen_rtx (CONST_INT, VOIDmode, mask);
1571 return \"andcc %0,%1,%%g0\";
1574 ;; Conversions between float, double and long double.
1576 (define_insn "extendsfdf2"
1577 [(set (match_operand:DF 0 "register_operand" "=f")
1579 (match_operand:SF 1 "register_operand" "f")))]
1582 [(set_attr "type" "fp")])
1584 (define_insn "extendsftf2"
1585 [(set (match_operand:TF 0 "register_operand" "=f")
1587 (match_operand:SF 1 "register_operand" "f")))]
1590 [(set_attr "type" "fp")])
1592 (define_insn "extenddftf2"
1593 [(set (match_operand:TF 0 "register_operand" "=f")
1595 (match_operand:DF 1 "register_operand" "f")))]
1598 [(set_attr "type" "fp")])
1600 (define_insn "truncdfsf2"
1601 [(set (match_operand:SF 0 "register_operand" "=f")
1603 (match_operand:DF 1 "register_operand" "f")))]
1606 [(set_attr "type" "fp")])
1608 (define_insn "trunctfsf2"
1609 [(set (match_operand:SF 0 "register_operand" "=f")
1611 (match_operand:TF 1 "register_operand" "f")))]
1614 [(set_attr "type" "fp")])
1616 (define_insn "trunctfdf2"
1617 [(set (match_operand:DF 0 "register_operand" "=f")
1619 (match_operand:TF 1 "register_operand" "f")))]
1622 [(set_attr "type" "fp")])
1624 ;; Conversion between fixed point and floating point.
1626 (define_insn "floatsisf2"
1627 [(set (match_operand:SF 0 "register_operand" "=f")
1628 (float:SF (match_operand:SI 1 "register_operand" "f")))]
1631 [(set_attr "type" "fp")])
1633 (define_insn "floatsidf2"
1634 [(set (match_operand:DF 0 "register_operand" "=f")
1635 (float:DF (match_operand:SI 1 "register_operand" "f")))]
1638 [(set_attr "type" "fp")])
1640 (define_insn "floatsitf2"
1641 [(set (match_operand:TF 0 "register_operand" "=f")
1642 (float:TF (match_operand:SI 1 "register_operand" "f")))]
1645 [(set_attr "type" "fp")])
1647 ;; Convert a float to an actual integer.
1648 ;; Truncation is performed as part of the conversion.
1650 (define_insn "fix_truncsfsi2"
1651 [(set (match_operand:SI 0 "register_operand" "=f")
1652 (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
1655 [(set_attr "type" "fp")])
1657 (define_insn "fix_truncdfsi2"
1658 [(set (match_operand:SI 0 "register_operand" "=f")
1659 (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "f"))))]
1662 [(set_attr "type" "fp")])
1664 (define_insn "fix_trunctfsi2"
1665 [(set (match_operand:SI 0 "register_operand" "=f")
1666 (fix:SI (fix:TF (match_operand:TF 1 "register_operand" "f"))))]
1669 [(set_attr "type" "fp")])
1671 ;;- arithmetic instructions
1673 (define_insn "adddi3"
1674 [(set (match_operand:DI 0 "register_operand" "=r")
1675 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
1676 (match_operand:DI 2 "arith_double_operand" "rHI")))
1677 (clobber (reg:SI 0))]
1681 rtx op2 = operands[2];
1683 /* If constant is positive, upper bits zeroed, otherwise unchanged.
1684 Give the assembler a chance to pick the move instruction. */
1685 if (GET_CODE (op2) == CONST_INT)
1687 int sign = INTVAL (op2);
1689 return \"addcc %R1,%2,%R0\;addx %1,-1,%0\";
1690 return \"addcc %R1,%2,%R0\;addx %1,0,%0\";
1692 else if (GET_CODE (op2) == CONST_DOUBLE)
1694 int sign = CONST_DOUBLE_HIGH (op2);
1695 operands[2] = gen_rtx (CONST_INT, VOIDmode,
1696 CONST_DOUBLE_LOW (operands[1]));
1698 return \"addcc %R1,%2,%R0\;addx %1,-1,%0\";
1699 return \"addcc %R1,%2,%R0\;addx %1,0,%0\";
1701 return \"addcc %R1,%R2,%R0\;addx %1,%2,%0\";
1703 [(set_attr "length" "2")])
1705 (define_insn "addsi3"
1706 [(set (match_operand:SI 0 "register_operand" "=r")
1707 (plus:SI (match_operand:SI 1 "arith_operand" "%r")
1708 (match_operand:SI 2 "arith_operand" "rI")))]
1713 [(set (reg:CC_NOOV 0)
1714 (compare:CC_NOOV (plus:SI (match_operand:SI 0 "arith_operand" "%r")
1715 (match_operand:SI 1 "arith_operand" "rI"))
1719 [(set_attr "type" "compare")])
1722 [(set (reg:CC_NOOV 0)
1723 (compare:CC_NOOV (plus:SI (match_operand:SI 1 "arith_operand" "%r")
1724 (match_operand:SI 2 "arith_operand" "rI"))
1726 (set (match_operand:SI 0 "register_operand" "=r")
1727 (plus:SI (match_dup 1) (match_dup 2)))]
1731 (define_insn "subdi3"
1732 [(set (match_operand:DI 0 "register_operand" "=r")
1733 (minus:DI (match_operand:DI 1 "register_operand" "r")
1734 (match_operand:DI 2 "arith_double_operand" "rHI")))
1735 (clobber (reg:SI 0))]
1739 rtx op2 = operands[2];
1741 /* If constant is positive, upper bits zeroed, otherwise unchanged.
1742 Give the assembler a chance to pick the move instruction. */
1743 if (GET_CODE (op2) == CONST_INT)
1745 int sign = INTVAL (op2);
1747 return \"subcc %R1,%2,%R0\;subx %1,-1,%0\";
1748 return \"subcc %R1,%2,%R0\;subx %1,0,%0\";
1750 else if (GET_CODE (op2) == CONST_DOUBLE)
1752 int sign = CONST_DOUBLE_HIGH (op2);
1753 operands[2] = gen_rtx (CONST_INT, VOIDmode,
1754 CONST_DOUBLE_LOW (operands[1]));
1756 return \"subcc %R1,%2,%R0\;subx %1,-1,%0\";
1757 return \"subcc %R1,%2,%R0\;subx %1,0,%0\";
1759 return \"subcc %R1,%R2,%R0\;subx %1,%2,%0\";
1761 [(set_attr "length" "2")])
1763 (define_insn "subsi3"
1764 [(set (match_operand:SI 0 "register_operand" "=r")
1765 (minus:SI (match_operand:SI 1 "register_operand" "r")
1766 (match_operand:SI 2 "arith_operand" "rI")))]
1771 [(set (reg:CC_NOOV 0)
1772 (compare:CC_NOOV (minus:SI (match_operand:SI 0 "register_operand" "r")
1773 (match_operand:SI 1 "arith_operand" "rI"))
1777 [(set_attr "type" "compare")])
1780 [(set (reg:CC_NOOV 0)
1781 (compare:CC_NOOV (minus:SI (match_operand:SI 1 "register_operand" "r")
1782 (match_operand:SI 2 "arith_operand" "rI"))
1784 (set (match_operand:SI 0 "register_operand" "=r")
1785 (minus:SI (match_dup 1) (match_dup 2)))]
1789 (define_insn "mulsi3"
1790 [(set (match_operand:SI 0 "register_operand" "=r")
1791 (mult:SI (match_operand:SI 1 "arith_operand" "%r")
1792 (match_operand:SI 2 "arith_operand" "rI")))]
1793 "TARGET_V8 || TARGET_SPARCLITE"
1796 ;; It is not known whether this will match.
1799 [(set (match_operand:SI 0 "register_operand" "=r")
1800 (mult:SI (match_operand:SI 1 "arith_operand" "%r")
1801 (match_operand:SI 2 "arith_operand" "rI")))
1802 (set (reg:CC_NOOV 0)
1803 (compare:CC_NOOV (mult:SI (match_dup 1) (match_dup 2))
1805 "TARGET_V8 || TARGET_SPARCLITE"
1808 (define_expand "mulsidi3"
1809 [(set (match_operand:DI 0 "register_operand" "")
1810 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
1811 (sign_extend:DI (match_operand:SI 2 "arith_operand" ""))))]
1812 "TARGET_V8 || TARGET_SPARCLITE"
1815 if (CONSTANT_P (operands[2]))
1817 emit_insn (gen_const_mulsidi3 (operands[0], operands[1], operands[2]));
1823 [(set (match_operand:DI 0 "register_operand" "=r")
1824 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
1825 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
1826 "TARGET_V8 || TARGET_SPARCLITE"
1827 "smul %1,%2,%R0\;rd %%y,%0"
1828 [(set_attr "length" "2")])
1830 ;; Extra pattern, because sign_extend of a constant isn't legal.
1832 (define_insn "const_mulsidi3"
1833 [(set (match_operand:DI 0 "register_operand" "=r")
1834 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
1835 (match_operand:SI 2 "small_int" "I")))]
1836 "TARGET_V8 || TARGET_SPARCLITE"
1837 "smul %1,%2,%R0\;rd %%y,%0"
1838 [(set_attr "length" "2")])
1840 (define_expand "smulsi3_highpart"
1841 [(set (match_operand:SI 0 "register_operand" "")
1843 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
1844 (sign_extend:DI (match_operand:SI 2 "arith_operand" "")))
1846 "TARGET_V8 || TARGET_SPARCLITE"
1849 if (CONSTANT_P (operands[2]))
1851 emit_insn (gen_const_smulsi3_highpart (operands[0], operands[1], operands[2]));
1857 [(set (match_operand:SI 0 "register_operand" "=r")
1859 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
1860 (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
1862 "TARGET_V8 || TARGET_SPARCLITE"
1863 "smul %1,%2,%%g0\;rd %%y,%0"
1864 [(set_attr "length" "2")])
1866 (define_insn "const_smulsi3_highpart"
1867 [(set (match_operand:SI 0 "register_operand" "=r")
1869 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
1870 (match_operand:SI 2 "register_operand" "r"))
1872 "TARGET_V8 || TARGET_SPARCLITE"
1873 "smul %1,%2,%%g0\;rd %%y,%0"
1874 [(set_attr "length" "2")])
1876 (define_expand "umulsidi3"
1877 [(set (match_operand:DI 0 "register_operand" "")
1878 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
1879 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" ""))))]
1880 "TARGET_V8 || TARGET_SPARCLITE"
1883 if (CONSTANT_P (operands[2]))
1885 emit_insn (gen_const_umulsidi3 (operands[0], operands[1], operands[2]));
1891 [(set (match_operand:DI 0 "register_operand" "=r")
1892 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
1893 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
1894 "TARGET_V8 || TARGET_SPARCLITE"
1895 "umul %1,%2,%R0\;rd %%y,%0"
1896 [(set_attr "length" "2")])
1898 ;; Extra pattern, because sign_extend of a constant isn't legal.
1900 (define_insn "const_umulsidi3"
1901 [(set (match_operand:DI 0 "register_operand" "=r")
1902 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
1903 (match_operand:SI 2 "uns_small_int" "")))]
1904 "TARGET_V8 || TARGET_SPARCLITE"
1905 "umul %1,%2,%R0\;rd %%y,%0"
1906 [(set_attr "length" "2")])
1908 (define_expand "umulsi3_highpart"
1909 [(set (match_operand:SI 0 "register_operand" "")
1911 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
1912 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" "")))
1914 "TARGET_V8 || TARGET_SPARCLITE"
1917 if (CONSTANT_P (operands[2]))
1919 emit_insn (gen_const_umulsi3_highpart (operands[0], operands[1], operands[2]));
1925 [(set (match_operand:SI 0 "register_operand" "=r")
1927 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
1928 (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
1930 "TARGET_V8 || TARGET_SPARCLITE"
1931 "umul %1,%2,%%g0\;rd %%y,%0"
1932 [(set_attr "length" "2")])
1934 (define_insn "const_umulsi3_highpart"
1935 [(set (match_operand:SI 0 "register_operand" "=r")
1937 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
1938 (match_operand:SI 2 "uns_small_int" ""))
1940 "TARGET_V8 || TARGET_SPARCLITE"
1941 "umul %1,%2,%%g0\;rd %%y,%0"
1942 [(set_attr "length" "2")])
1944 ;; The architecture specifies that there must be 3 instructions between
1945 ;; a y register write and a use of it for correct results.
1947 (define_insn "divsi3"
1948 [(set (match_operand:SI 0 "register_operand" "=r")
1949 (div:SI (match_operand:SI 1 "register_operand" "r")
1950 (match_operand:SI 2 "arith_operand" "rI")))
1951 (clobber (match_scratch:SI 3 "=&r"))]
1953 "sra %1,31,%3\;wr %%g0,%3,%%y\;nop\;nop\;nop\;sdiv %1,%2,%0"
1954 [(set_attr "length" "6")])
1956 ;; It is not known whether this will match.
1959 [(set (match_operand:SI 0 "register_operand" "=r")
1960 (div:SI (match_operand:SI 1 "register_operand" "r")
1961 (match_operand:SI 2 "arith_operand" "rI")))
1963 (compare:CC (div:SI (match_dup 1) (match_dup 2))
1965 (clobber (match_scratch:SI 3 "=&r"))]
1967 "sra %1,31,%3\;wr %%g0,%3,%%y\;nop\;nop\;nop\;sdivcc %1,%2,%0"
1968 [(set_attr "length" "6")])
1970 (define_insn "udivsi3"
1971 [(set (match_operand:SI 0 "register_operand" "=r")
1972 (udiv:SI (match_operand:SI 1 "register_operand" "r")
1973 (match_operand:SI 2 "arith_operand" "rI")))]
1975 "wr %%g0,%%g0,%%y\;nop\;nop\;nop\;udiv %1,%2,%0"
1976 [(set_attr "length" "5")])
1978 ;; It is not known whether this will match.
1981 [(set (match_operand:SI 0 "register_operand" "=r")
1982 (udiv:SI (match_operand:SI 1 "register_operand" "r")
1983 (match_operand:SI 2 "arith_operand" "rI")))
1985 (compare:CC (udiv:SI (match_dup 1) (match_dup 2))
1988 "wr %%g0,%%g0,%%y\;nop\;nop\;nop\;udivcc %1,%2,%0"
1989 [(set_attr "length" "5")])
1991 ;;- Boolean instructions
1992 ;; We define DImode `and` so with DImode `not` we can get
1993 ;; DImode `andn`. Other combinations are possible.
1995 (define_expand "anddi3"
1996 [(set (match_operand:DI 0 "register_operand" "")
1997 (and:DI (match_operand:DI 1 "arith_double_operand" "")
1998 (match_operand:DI 2 "arith_double_operand" "")))]
2003 [(set (match_operand:DI 0 "register_operand" "=r")
2004 (and:DI (match_operand:DI 1 "arith_double_operand" "%r")
2005 (match_operand:DI 2 "arith_double_operand" "rHI")))]
2009 rtx op2 = operands[2];
2011 /* If constant is positive, upper bits zeroed, otherwise unchanged.
2012 Give the assembler a chance to pick the move instruction. */
2013 if (GET_CODE (op2) == CONST_INT)
2015 int sign = INTVAL (op2);
2017 return \"mov %1,%0\;and %R1,%2,%R0\";
2018 return \"mov 0,%0\;and %R1,%2,%R0\";
2020 else if (GET_CODE (op2) == CONST_DOUBLE)
2022 int sign = CONST_DOUBLE_HIGH (op2);
2023 operands[2] = gen_rtx (CONST_INT, VOIDmode,
2024 CONST_DOUBLE_LOW (operands[1]));
2026 return \"mov %1,%0\;and %R1,%2,%R0\";
2027 return \"mov 0,%0\;and %R1,%2,%R0\";
2029 return \"and %1,%2,%0\;and %R1,%R2,%R0\";
2031 [(set_attr "length" "2")])
2033 (define_insn "andsi3"
2034 [(set (match_operand:SI 0 "register_operand" "=r")
2035 (and:SI (match_operand:SI 1 "arith_operand" "%r")
2036 (match_operand:SI 2 "arith_operand" "rI")))]
2041 [(set (match_operand:SI 0 "register_operand" "")
2042 (and:SI (match_operand:SI 1 "register_operand" "")
2043 (match_operand:SI 2 "" "")))
2044 (clobber (match_operand:SI 3 "register_operand" ""))]
2045 "GET_CODE (operands[2]) == CONST_INT
2046 && !SMALL_INT (operands[2])
2047 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
2048 [(set (match_dup 3) (match_dup 4))
2049 (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 1)))]
2052 operands[4] = gen_rtx (CONST_INT, VOIDmode, ~INTVAL (operands[2]));
2056 [(set (match_operand:DI 0 "register_operand" "=r")
2057 (and:DI (not:DI (match_operand:DI 1 "register_operand" "r"))
2058 (match_operand:DI 2 "register_operand" "r")))]
2060 "andn %2,%1,%0\;andn %R2,%R1,%R0"
2061 [(set_attr "length" "2")])
2064 [(set (match_operand:SI 0 "register_operand" "=r")
2065 (and:SI (not:SI (match_operand:SI 1 "register_operand" "r"))
2066 (match_operand:SI 2 "register_operand" "r")))]
2070 (define_expand "iordi3"
2071 [(set (match_operand:DI 0 "register_operand" "")
2072 (ior:DI (match_operand:DI 1 "arith_double_operand" "")
2073 (match_operand:DI 2 "arith_double_operand" "")))]
2078 [(set (match_operand:DI 0 "register_operand" "=r")
2079 (ior:DI (match_operand:DI 1 "arith_double_operand" "%r")
2080 (match_operand:DI 2 "arith_double_operand" "rHI")))]
2084 rtx op2 = operands[2];
2086 /* If constant is positive, upper bits zeroed, otherwise unchanged.
2087 Give the assembler a chance to pick the move instruction. */
2088 if (GET_CODE (op2) == CONST_INT)
2090 int sign = INTVAL (op2);
2092 return \"mov -1,%0\;or %R1,%2,%R0\";
2093 return \"mov %1,%0\;or %R1,%2,%R0\";
2095 else if (GET_CODE (op2) == CONST_DOUBLE)
2097 int sign = CONST_DOUBLE_HIGH (op2);
2098 operands[2] = gen_rtx (CONST_INT, VOIDmode,
2099 CONST_DOUBLE_LOW (operands[1]));
2101 return \"mov -1,%0\;or %R1,%2,%R0\";
2102 return \"mov %1,%0\;or %R1,%2,%R0\";
2104 return \"or %1,%2,%0\;or %R1,%R2,%R0\";
2106 [(set_attr "length" "2")])
2108 (define_insn "iorsi3"
2109 [(set (match_operand:SI 0 "register_operand" "=r")
2110 (ior:SI (match_operand:SI 1 "arith_operand" "%r")
2111 (match_operand:SI 2 "arith_operand" "rI")))]
2116 [(set (match_operand:SI 0 "register_operand" "")
2117 (ior:SI (match_operand:SI 1 "register_operand" "")
2118 (match_operand:SI 2 "" "")))
2119 (clobber (match_operand:SI 3 "register_operand" ""))]
2120 "GET_CODE (operands[2]) == CONST_INT
2121 && !SMALL_INT (operands[2])
2122 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
2123 [(set (match_dup 3) (match_dup 4))
2124 (set (match_dup 0) (ior:SI (not:SI (match_dup 3)) (match_dup 1)))]
2127 operands[4] = gen_rtx (CONST_INT, VOIDmode, ~INTVAL (operands[2]));
2131 [(set (match_operand:DI 0 "register_operand" "=r")
2132 (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r"))
2133 (match_operand:DI 2 "register_operand" "r")))]
2135 "orn %2,%1,%0\;orn %R2,%R1,%R0"
2136 [(set_attr "length" "2")])
2139 [(set (match_operand:SI 0 "register_operand" "=r")
2140 (ior:SI (not:SI (match_operand:SI 1 "register_operand" "r"))
2141 (match_operand:SI 2 "register_operand" "r")))]
2145 (define_expand "xordi3"
2146 [(set (match_operand:DI 0 "register_operand" "")
2147 (xor:DI (match_operand:DI 1 "arith_double_operand" "")
2148 (match_operand:DI 2 "arith_double_operand" "")))]
2153 [(set (match_operand:DI 0 "register_operand" "=r")
2154 (xor:DI (match_operand:DI 1 "arith_double_operand" "%r")
2155 (match_operand:DI 2 "arith_double_operand" "rHI")))]
2159 rtx op2 = operands[2];
2161 /* If constant is positive, upper bits zeroed, otherwise unchanged.
2162 Give the assembler a chance to pick the move instruction. */
2163 if (GET_CODE (op2) == CONST_INT)
2165 int sign = INTVAL (op2);
2167 return \"xor %1,-1,%0\;xor %R1,%2,%R0\";
2168 return \"mov %1,%0\;xor %R1,%2,%R0\";
2170 else if (GET_CODE (op2) == CONST_DOUBLE)
2172 int sign = CONST_DOUBLE_HIGH (op2);
2173 operands[2] = gen_rtx (CONST_INT, VOIDmode,
2174 CONST_DOUBLE_LOW (operands[1]));
2176 return \"xor %1,-1,%0\;xor %R1,%2,%R0\";
2177 return \"mov %1,%0\;xor %R1,%2,%R0\";
2179 return \"xor %1,%2,%0\;xor %R1,%R2,%R0\";
2181 [(set_attr "length" "2")])
2183 (define_insn "xorsi3"
2184 [(set (match_operand:SI 0 "register_operand" "=r")
2185 (xor:SI (match_operand:SI 1 "arith_operand" "%rJ")
2186 (match_operand:SI 2 "arith_operand" "rI")))]
2191 [(set (match_operand:SI 0 "register_operand" "")
2192 (xor:SI (match_operand:SI 1 "register_operand" "")
2193 (match_operand:SI 2 "" "")))
2194 (clobber (match_operand:SI 3 "register_operand" ""))]
2195 "GET_CODE (operands[2]) == CONST_INT
2196 && !SMALL_INT (operands[2])
2197 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
2198 [(set (match_dup 3) (match_dup 4))
2199 (set (match_dup 0) (not:SI (xor:SI (match_dup 3) (match_dup 1))))]
2202 operands[4] = gen_rtx (CONST_INT, VOIDmode, ~INTVAL (operands[2]));
2206 [(set (match_operand:SI 0 "register_operand" "")
2207 (not:SI (xor:SI (match_operand:SI 1 "register_operand" "")
2208 (match_operand:SI 2 "" ""))))
2209 (clobber (match_operand:SI 3 "register_operand" ""))]
2210 "GET_CODE (operands[2]) == CONST_INT
2211 && !SMALL_INT (operands[2])
2212 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
2213 [(set (match_dup 3) (match_dup 4))
2214 (set (match_dup 0) (xor:SI (match_dup 3) (match_dup 1)))]
2217 operands[4] = gen_rtx (CONST_INT, VOIDmode, ~INTVAL (operands[2]));
2220 ;; xnor patterns. Note that (a ^ ~b) == (~a ^ b) == ~(a ^ b).
2221 ;; Combine now canonicalizes to the rightmost expression.
2223 [(set (match_operand:DI 0 "register_operand" "=r")
2224 (not:DI (xor:DI (match_operand:DI 1 "register_operand" "r")
2225 (match_operand:DI 2 "register_operand" "r"))))]
2227 "xnor %1,%2,%0\;xnor %R1,%R2,%R0"
2228 [(set_attr "length" "2")])
2231 [(set (match_operand:SI 0 "register_operand" "=r")
2232 (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
2233 (match_operand:SI 2 "arith_operand" "rI"))))]
2237 ;; These correspond to the above in the case where we also (or only)
2238 ;; want to set the condition code.
2243 (match_operator:SI 2 "cc_arithop"
2244 [(match_operand:SI 0 "arith_operand" "%r")
2245 (match_operand:SI 1 "arith_operand" "rI")])
2249 [(set_attr "type" "compare")])
2254 (match_operator:SI 3 "cc_arithop"
2255 [(match_operand:SI 1 "arith_operand" "%r")
2256 (match_operand:SI 2 "arith_operand" "rI")])
2258 (set (match_operand:SI 0 "register_operand" "=r")
2266 (not:SI (xor:SI (match_operand:SI 0 "reg_or_0_operand" "%rJ")
2267 (match_operand:SI 1 "arith_operand" "rI")))
2270 "xnorcc %r0,%1,%%g0"
2271 [(set_attr "type" "compare")])
2276 (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
2277 (match_operand:SI 2 "arith_operand" "rI")))
2279 (set (match_operand:SI 0 "register_operand" "=r")
2280 (not:SI (xor:SI (match_dup 1) (match_dup 2))))]
2287 (match_operator:SI 2 "cc_arithopn"
2288 [(not:SI (match_operand:SI 0 "arith_operand" "rI"))
2289 (match_operand:SI 1 "reg_or_0_operand" "rJ")])
2293 [(set_attr "type" "compare")])
2298 (match_operator:SI 3 "cc_arithopn"
2299 [(not:SI (match_operand:SI 1 "arith_operand" "rI"))
2300 (match_operand:SI 2 "reg_or_0_operand" "rJ")])
2302 (set (match_operand:SI 0 "register_operand" "=r")
2307 ;; We cannot use the "neg" pseudo insn because the Sun assembler
2308 ;; does not know how to make it work for constants.
2310 (define_insn "negdi2"
2311 [(set (match_operand:DI 0 "register_operand" "=r")
2312 (neg:DI (match_operand:DI 1 "register_operand" "r")))
2313 (clobber (reg:SI 0))]
2315 "subcc %%g0,%R1,%R0\;subx %%g0,%1,%0"
2316 [(set_attr "type" "unary")
2317 (set_attr "length" "2")])
2319 (define_insn "negsi2"
2320 [(set (match_operand:SI 0 "general_operand" "=r")
2321 (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
2324 [(set_attr "type" "unary")])
2327 [(set (reg:CC_NOOV 0)
2328 (compare:CC_NOOV (neg:SI (match_operand:SI 0 "arith_operand" "rI"))
2331 "subcc %%g0,%0,%%g0"
2332 [(set_attr "type" "compare")])
2335 [(set (reg:CC_NOOV 0)
2336 (compare:CC_NOOV (neg:SI (match_operand:SI 1 "arith_operand" "rI"))
2338 (set (match_operand:SI 0 "register_operand" "=r")
2339 (neg:SI (match_dup 1)))]
2342 [(set_attr "type" "unary")])
2344 ;; We cannot use the "not" pseudo insn because the Sun assembler
2345 ;; does not know how to make it work for constants.
2346 (define_expand "one_cmpldi2"
2347 [(set (match_operand:DI 0 "register_operand" "=r")
2348 (not:DI (match_operand:DI 1 "arith_double_operand" "rHI")))]
2353 [(set (match_operand:DI 0 "register_operand" "=r")
2354 (not:DI (match_operand:DI 1 "arith_double_operand" "rHI")))]
2358 rtx op1 = operands[1];
2360 if (GET_CODE (op1) == CONST_INT)
2362 int sign = INTVAL (op1);
2364 return \"xnor %%g0,%1,%R0\;xnor %%g0,-1,%0\";
2365 return \"xnor %%g0,%1,%R0\;xnor %%g0,0,%0\";
2367 else if (GET_CODE (op1) == CONST_DOUBLE)
2369 int sign = CONST_DOUBLE_HIGH (op1);
2370 operands[1] = gen_rtx (CONST_INT, VOIDmode,
2371 CONST_DOUBLE_LOW (operands[1]));
2373 return \"xnor %%g0,%1,%R0\;xnor %%g0,-1,%0\";
2374 return \"xnor %%g0,%1,%R0\;xnor %%g0,0,%0\";
2376 return \"xnor %%g0,%1,%0\;xnor %%g0,%R1,%R0\";
2378 [(set_attr "type" "unary")
2379 (set_attr "length" "2")])
2381 (define_insn "one_cmplsi2"
2382 [(set (match_operand:SI 0 "register_operand" "=r")
2383 (not:SI (match_operand:SI 1 "arith_operand" "rI")))]
2386 [(set_attr "type" "unary")])
2390 (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI"))
2393 "xnorcc %%g0,%0,%%g0"
2394 [(set_attr "type" "compare")])
2398 (compare:CC (not:SI (match_operand:SI 1 "arith_operand" "rI"))
2400 (set (match_operand:SI 0 "register_operand" "=r")
2401 (not:SI (match_dup 1)))]
2404 [(set_attr "type" "unary")])
2406 ;; Floating point arithmetic instructions.
2408 (define_insn "addtf3"
2409 [(set (match_operand:TF 0 "register_operand" "=f")
2410 (plus:TF (match_operand:TF 1 "register_operand" "f")
2411 (match_operand:TF 2 "register_operand" "f")))]
2414 [(set_attr "type" "fp")])
2416 (define_insn "adddf3"
2417 [(set (match_operand:DF 0 "register_operand" "=f")
2418 (plus:DF (match_operand:DF 1 "register_operand" "f")
2419 (match_operand:DF 2 "register_operand" "f")))]
2422 [(set_attr "type" "fp")])
2424 (define_insn "addsf3"
2425 [(set (match_operand:SF 0 "register_operand" "=f")
2426 (plus:SF (match_operand:SF 1 "register_operand" "f")
2427 (match_operand:SF 2 "register_operand" "f")))]
2430 [(set_attr "type" "fp")])
2432 (define_insn "subtf3"
2433 [(set (match_operand:TF 0 "register_operand" "=f")
2434 (minus:TF (match_operand:TF 1 "register_operand" "f")
2435 (match_operand:TF 2 "register_operand" "f")))]
2438 [(set_attr "type" "fp")])
2440 (define_insn "subdf3"
2441 [(set (match_operand:DF 0 "register_operand" "=f")
2442 (minus:DF (match_operand:DF 1 "register_operand" "f")
2443 (match_operand:DF 2 "register_operand" "f")))]
2446 [(set_attr "type" "fp")])
2448 (define_insn "subsf3"
2449 [(set (match_operand:SF 0 "register_operand" "=f")
2450 (minus:SF (match_operand:SF 1 "register_operand" "f")
2451 (match_operand:SF 2 "register_operand" "f")))]
2454 [(set_attr "type" "fp")])
2456 (define_insn "multf3"
2457 [(set (match_operand:TF 0 "register_operand" "=f")
2458 (mult:TF (match_operand:TF 1 "register_operand" "f")
2459 (match_operand:TF 2 "register_operand" "f")))]
2462 [(set_attr "type" "fpmul")])
2464 (define_insn "muldf3"
2465 [(set (match_operand:DF 0 "register_operand" "=f")
2466 (mult:DF (match_operand:DF 1 "register_operand" "f")
2467 (match_operand:DF 2 "register_operand" "f")))]
2470 [(set_attr "type" "fpmul")])
2472 (define_insn "mulsf3"
2473 [(set (match_operand:SF 0 "register_operand" "=f")
2474 (mult:SF (match_operand:SF 1 "register_operand" "f")
2475 (match_operand:SF 2 "register_operand" "f")))]
2478 [(set_attr "type" "fpmul")])
2481 [(set (match_operand:DF 0 "register_operand" "=f")
2482 (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "f"))
2483 (float_extend:DF (match_operand:SF 2 "register_operand" "f"))))]
2484 "TARGET_V8 && TARGET_FPU"
2486 [(set_attr "type" "fpmul")])
2489 [(set (match_operand:TF 0 "register_operand" "=f")
2490 (mult:TF (float_extend:TF (match_operand:DF 1 "register_operand" "f"))
2491 (float_extend:TF (match_operand:DF 2 "register_operand" "f"))))]
2492 "TARGET_V8 && TARGET_FPU"
2494 [(set_attr "type" "fpmul")])
2496 (define_insn "divtf3"
2497 [(set (match_operand:TF 0 "register_operand" "=f")
2498 (div:TF (match_operand:TF 1 "register_operand" "f")
2499 (match_operand:TF 2 "register_operand" "f")))]
2502 [(set_attr "type" "fpdiv")])
2504 (define_insn "divdf3"
2505 [(set (match_operand:DF 0 "register_operand" "=f")
2506 (div:DF (match_operand:DF 1 "register_operand" "f")
2507 (match_operand:DF 2 "register_operand" "f")))]
2510 [(set_attr "type" "fpdiv")])
2512 (define_insn "divsf3"
2513 [(set (match_operand:SF 0 "register_operand" "=f")
2514 (div:SF (match_operand:SF 1 "register_operand" "f")
2515 (match_operand:SF 2 "register_operand" "f")))]
2518 [(set_attr "type" "fpdiv")])
2520 (define_insn "negtf2"
2521 [(set (match_operand:TF 0 "register_operand" "=f,f")
2522 (neg:TF (match_operand:TF 1 "register_operand" "0,f")))]
2526 fnegs %1,%0\;fmovs %R1,%R0\;fmovs %S1,%S0\;fmovs %T1,%T0"
2527 [(set_attr "type" "fp")
2528 (set_attr "length" "1,4")])
2530 (define_insn "negdf2"
2531 [(set (match_operand:DF 0 "register_operand" "=f,f")
2532 (neg:DF (match_operand:DF 1 "register_operand" "0,f")))]
2536 fnegs %1,%0\;fmovs %R1,%R0"
2537 [(set_attr "type" "fp")
2538 (set_attr "length" "1,2")])
2540 (define_insn "negsf2"
2541 [(set (match_operand:SF 0 "register_operand" "=f")
2542 (neg:SF (match_operand:SF 1 "register_operand" "f")))]
2545 [(set_attr "type" "fp")])
2547 (define_insn "abstf2"
2548 [(set (match_operand:TF 0 "register_operand" "=f,f")
2549 (abs:TF (match_operand:TF 1 "register_operand" "0,f")))]
2553 fabss %1,%0\;fmovs %R1,%R0\;fmovs %S1,%S0\;fmovs %T1,%T0"
2554 [(set_attr "type" "fp")
2555 (set_attr "length" "1,4")])
2557 (define_insn "absdf2"
2558 [(set (match_operand:DF 0 "register_operand" "=f,f")
2559 (abs:DF (match_operand:DF 1 "register_operand" "0,f")))]
2563 fabss %1,%0\;fmovs %R1,%R0"
2564 [(set_attr "type" "fp")
2565 (set_attr "length" "1,2")])
2567 (define_insn "abssf2"
2568 [(set (match_operand:SF 0 "register_operand" "=f")
2569 (abs:SF (match_operand:SF 1 "register_operand" "f")))]
2572 [(set_attr "type" "fp")])
2574 (define_insn "sqrttf2"
2575 [(set (match_operand:TF 0 "register_operand" "=f")
2576 (sqrt:TF (match_operand:TF 1 "register_operand" "f")))]
2579 [(set_attr "type" "fpsqrt")])
2581 (define_insn "sqrtdf2"
2582 [(set (match_operand:DF 0 "register_operand" "=f")
2583 (sqrt:DF (match_operand:DF 1 "register_operand" "f")))]
2586 [(set_attr "type" "fpsqrt")])
2588 (define_insn "sqrtsf2"
2589 [(set (match_operand:SF 0 "register_operand" "=f")
2590 (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
2593 [(set_attr "type" "fpsqrt")])
2595 ;;- arithmetic shift instructions
2597 (define_insn "ashlsi3"
2598 [(set (match_operand:SI 0 "register_operand" "=r")
2599 (ashift:SI (match_operand:SI 1 "register_operand" "r")
2600 (match_operand:SI 2 "arith_operand" "rI")))]
2604 if (GET_CODE (operands[2]) == CONST_INT
2605 && (unsigned) INTVAL (operands[2]) > 31)
2606 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
2608 return \"sll %1,%2,%0\";
2612 [(set (reg:CC_NOOV 0)
2613 (compare:CC_NOOV (ashift:SI (match_operand:SI 0 "register_operand" "r")
2618 [(set_attr "type" "compare")])
2621 [(set (reg:CC_NOOV 0)
2622 (compare:CC_NOOV (ashift:SI (match_operand:SI 1 "register_operand" "r")
2625 (set (match_operand:SI 0 "register_operand" "=r")
2626 (ashift:SI (match_dup 1) (const_int 1)))]
2630 (define_insn "ashrsi3"
2631 [(set (match_operand:SI 0 "register_operand" "=r")
2632 (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
2633 (match_operand:SI 2 "arith_operand" "rI")))]
2637 if (GET_CODE (operands[2]) == CONST_INT
2638 && (unsigned) INTVAL (operands[2]) > 31)
2639 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
2641 return \"sra %1,%2,%0\";
2644 (define_insn "lshrsi3"
2645 [(set (match_operand:SI 0 "register_operand" "=r")
2646 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
2647 (match_operand:SI 2 "arith_operand" "rI")))]
2651 if (GET_CODE (operands[2]) == CONST_INT
2652 && (unsigned) INTVAL (operands[2]) > 31)
2653 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
2655 return \"srl %1,%2,%0\";
2658 ;; Unconditional and other jump instructions
2659 ;; On the Sparc, by setting the annul bit on an unconditional branch, the
2660 ;; following insn is never executed. This saves us a nop. Dbx does not
2661 ;; handle such branches though, so we only use them when optimizing.
2663 [(set (pc) (label_ref (match_operand 0 "" "")))]
2666 [(set_attr "type" "uncond_branch")])
2668 (define_expand "tablejump"
2669 [(parallel [(set (pc) (match_operand:SI 0 "register_operand" "r"))
2670 (use (label_ref (match_operand 1 "" "")))])]
2674 /* We need to use the PC value in %o7 that was set up when the address
2675 of the label was loaded into a register, so we need different RTL. */
2678 emit_insn (gen_pic_tablejump (operands[0], operands[1]));
2683 (define_insn "pic_tablejump"
2684 [(set (pc) (match_operand:SI 0 "register_operand" "r"))
2685 (use (label_ref (match_operand 1 "" "")))
2689 [(set_attr "type" "uncond_branch")])
2692 [(set (pc) (match_operand:SI 0 "address_operand" "p"))
2693 (use (label_ref (match_operand 1 "" "")))]
2696 [(set_attr "type" "uncond_branch")])
2699 [(set (pc) (label_ref (match_operand 0 "" "")))
2700 (set (reg:SI 15) (label_ref (match_dup 0)))]
2703 [(set_attr "type" "uncond_branch")])
2705 ;; This pattern recognizes the "instruction" that appears in
2706 ;; a function call that wants a structure value,
2707 ;; to inform the called function if compiled with Sun CC.
2709 ; [(match_operand:SI 0 "immediate_operand" "")]
2710 ; "GET_CODE (operands[0]) == CONST_INT && INTVAL (operands[0]) > 0"
2712 ; [(set_attr "type" "marker")])
2714 ;;- jump to subroutine
2715 (define_expand "call"
2716 ;; Note that this expression is not used for generating RTL.
2717 ;; All the RTL is generated explicitly below.
2718 [(call (match_operand:SI 0 "call_operand" "")
2719 (match_operand 3 "" "i"))]
2720 ;; operands[2] is next_arg_register
2721 ;; operands[3] is struct_value_size_rtx.
2725 rtx fn_rtx, nregs_rtx;
2727 if (GET_CODE (XEXP (operands[0], 0)) == LABEL_REF)
2729 /* This is really a PIC sequence. We want to represent
2730 it as a funny jump so it's delay slots can be filled.
2732 ??? But if this really *is* a CALL, will not it clobber the
2733 call-clobbered registers? We lose this if it is a JUMP_INSN.
2734 Why cannot we have delay slots filled if it were a CALL? */
2736 if (INTVAL (operands[3]) > 0)
2737 emit_jump_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (3,
2738 gen_rtx (SET, VOIDmode, pc_rtx,
2739 XEXP (operands[0], 0)),
2741 gen_rtx (CLOBBER, VOIDmode,
2742 gen_rtx (REG, SImode, 15)))));
2744 emit_jump_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (2,
2745 gen_rtx (SET, VOIDmode, pc_rtx,
2746 XEXP (operands[0], 0)),
2747 gen_rtx (CLOBBER, VOIDmode,
2748 gen_rtx (REG, SImode, 15)))));
2752 fn_rtx = operands[0];
2754 /* Count the number of parameter registers being used by this call.
2755 if that argument is NULL, it means we are using them all, which
2756 means 6 on the sparc. */
2759 nregs_rtx = gen_rtx (CONST_INT, VOIDmode, REGNO (operands[2]) - 8);
2761 nregs_rtx = gen_rtx (CONST_INT, VOIDmode, 6);
2763 nregs_rtx = const0_rtx;
2766 if (INTVAL (operands[3]) > 0)
2767 emit_call_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (3,
2768 gen_rtx (CALL, VOIDmode, fn_rtx, nregs_rtx),
2770 gen_rtx (CLOBBER, VOIDmode,
2771 gen_rtx (REG, SImode, 15)))));
2773 emit_call_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (2,
2774 gen_rtx (CALL, VOIDmode, fn_rtx, nregs_rtx),
2775 gen_rtx (CLOBBER, VOIDmode,
2776 gen_rtx (REG, SImode, 15)))));
2780 /* If this call wants a structure value,
2781 emit an unimp insn to let the called function know about this. */
2782 if (INTVAL (operands[3]) > 0)
2784 rtx insn = emit_insn (operands[3]);
2785 SCHED_GROUP_P (insn) = 1;
2792 ;; We can't use the same pattern for these two insns, because then registers
2793 ;; in the address may not be properly reloaded.
2796 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
2797 (match_operand 1 "" ""))
2798 (clobber (reg:SI 15))]
2799 ;;- Do not use operand 1 for most machines.
2803 return \"call %a0,%1%#\";
2805 [(set_attr "type" "call")])
2808 [(call (mem:SI (match_operand:SI 0 "immediate_operand" "i"))
2809 (match_operand 1 "" ""))
2810 (clobber (reg:SI 15))]
2811 ;;- Do not use operand 1 for most machines.
2815 return \"call %a0,%1%#\";
2817 [(set_attr "type" "call")])
2819 ;; This is a call that wants a structure value.
2821 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
2822 (match_operand 1 "" ""))
2823 (match_operand 2 "immediate_operand" "")
2824 (clobber (reg:SI 15))]
2825 ;;- Do not use operand 1 for most machines.
2826 "GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
2829 return \"call %a0,%1\;nop\;unimp %2\";
2831 [(set_attr "type" "call_no_delay_slot")])
2833 ;; This is a call that wants a structure value.
2835 [(call (mem:SI (match_operand:SI 0 "immediate_operand" "i"))
2836 (match_operand 1 "" ""))
2837 (match_operand 2 "immediate_operand" "")
2838 (clobber (reg:SI 15))]
2839 ;;- Do not use operand 1 for most machines.
2840 "GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
2843 return \"call %a0,%1\;nop\;unimp %2\";
2845 [(set_attr "type" "call_no_delay_slot")])
2847 (define_expand "call_value"
2848 [(set (match_operand 0 "register_operand" "=rf")
2849 (call (match_operand:SI 1 "" "")
2850 (match_operand 4 "" "")))]
2851 ;; operand 3 is next_arg_register
2855 rtx fn_rtx, nregs_rtx;
2858 fn_rtx = operands[1];
2862 nregs_rtx = gen_rtx (CONST_INT, VOIDmode, REGNO (operands[3]) - 8);
2864 nregs_rtx = gen_rtx (CONST_INT, VOIDmode, 6);
2866 nregs_rtx = const0_rtx;
2870 gen_rtx (SET, VOIDmode, operands[0],
2871 gen_rtx (CALL, VOIDmode, fn_rtx, nregs_rtx)),
2872 gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, 15)));
2874 emit_call_insn (gen_rtx (PARALLEL, VOIDmode, vec));
2880 [(set (match_operand 0 "" "=rf")
2881 (call (mem:SI (match_operand:SI 1 "address_operand" "p"))
2882 (match_operand 2 "" "")))
2883 (clobber (reg:SI 15))]
2884 ;;- Do not use operand 2 for most machines.
2888 return \"call %a1,%2%#\";
2890 [(set_attr "type" "call")])
2893 [(set (match_operand 0 "" "=rf")
2894 (call (mem:SI (match_operand:SI 1 "immediate_operand" "i"))
2895 (match_operand 2 "" "")))
2896 (clobber (reg:SI 15))]
2897 ;;- Do not use operand 2 for most machines.
2901 return \"call %a1,%2%#\";
2903 [(set_attr "type" "call")])
2905 (define_expand "untyped_call"
2906 [(parallel [(call (match_operand:SI 0 "call_operand" "")
2908 (match_operand:BLK 1 "memory_operand" "")
2909 (match_operand 2 "" "")
2910 (clobber (reg:SI 15))])]
2914 operands[1] = change_address (operands[1], DImode, XEXP (operands[1], 0));
2917 ;; Make a call followed by two nops in case the function being called
2918 ;; returns a structure value and expects to skip an unimp instruction.
2921 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
2923 (match_operand:DI 1 "memory_operand" "o")
2924 (match_operand 2 "" "")
2925 (clobber (reg:SI 15))]
2929 operands[2] = adj_offsettable_operand (operands[1], 8);
2930 return \"call %a0,0\;nop\;nop\;std %%o0,%1\;std %%f0,%2\";
2932 [(set_attr "type" "multi")])
2934 ;; Make a call followed by two nops in case the function being called
2935 ;; returns a structure value and expects to skip an unimp instruction.
2938 [(call (mem:SI (match_operand:SI 0 "immediate_operand" "i"))
2940 (match_operand:DI 1 "memory_operand" "o")
2941 (match_operand 2 "" "")
2942 (clobber (reg:SI 15))]
2946 operands[2] = adj_offsettable_operand (operands[1], 8);
2947 return \"call %a0,0\;nop\;nop\;std %%o0,%1\;std %%f0,%2\";
2949 [(set_attr "type" "multi")])
2951 ;; Prepare to return any type including a structure value.
2953 (define_expand "untyped_return"
2954 [(match_operand:BLK 0 "memory_operand" "")
2955 (match_operand 1 "" "")]
2959 rtx valreg1 = gen_rtx (REG, DImode, 24);
2960 rtx valreg2 = gen_rtx (REG, DFmode, 32);
2961 rtx result = operands[0];
2962 rtx rtnreg = gen_rtx (REG, SImode, (leaf_function ? 15 : 31));
2963 rtx value = gen_reg_rtx (SImode);
2965 /* Fetch the instruction where we will return to and see if it's an unimp
2966 instruction (the most significant 10 bits will be zero). If so,
2967 update the return address to skip the unimp instruction. */
2968 emit_move_insn (value,
2969 gen_rtx (MEM, SImode, plus_constant (rtnreg, 8)));
2970 emit_insn (gen_lshrsi3 (value, value, GEN_INT (22)));
2971 emit_insn (gen_update_return (rtnreg, value));
2973 /* Reload the function value registers. */
2974 emit_move_insn (valreg1, change_address (result, DImode, XEXP (result, 0)));
2975 emit_move_insn (valreg2,
2976 change_address (result, DFmode,
2977 plus_constant (XEXP (result, 0), 8)));
2979 /* Put USE insns before the return. */
2980 emit_insn (gen_rtx (USE, VOIDmode, valreg1));
2981 emit_insn (gen_rtx (USE, VOIDmode, valreg2));
2983 /* Construct the return. */
2984 expand_null_return ();
2989 ;; This is a bit of a hack. We're incrementing a fixed register (%i7),
2990 ;; and parts of the compiler don't want to believe that the add is needed.
2992 (define_insn "update_return"
2993 [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
2994 (match_operand:SI 1 "register_operand" "r")] 0)]
2996 "cmp %1,0\;be,a .+8\;add %0,4,%0"
2997 [(set_attr "type" "multi")])
2999 (define_insn "return"
3002 "* return output_return (operands);"
3003 [(set_attr "type" "multi")])
3010 (define_insn "indirect_jump"
3011 [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
3014 [(set_attr "type" "uncond_branch")])
3016 (define_expand "nonlocal_goto"
3017 [(match_operand:SI 0 "general_operand" "")
3018 (match_operand:SI 1 "general_operand" "")
3019 (match_operand:SI 2 "general_operand" "")
3020 (match_operand:SI 3 "" "")]
3024 /* Trap instruction to flush all the registers window. */
3025 emit_insn (gen_flush_register_windows ());
3026 /* Load the fp value for the containing fn into %fp.
3027 This is needed because operands[2] refers to %fp.
3028 Virtual register instantiation fails if the virtual %fp isn't set from a
3029 register. Thus we must copy operands[0] into a register if it isn't
3031 if (GET_CODE (operands[0]) != REG)
3032 operands[0] = force_reg (SImode, operands[0]);
3033 emit_move_insn (virtual_stack_vars_rtx, operands[0]);
3034 /* Find the containing function's current nonlocal goto handler,
3035 which will do any cleanups and then jump to the label. */
3036 emit_move_insn (gen_rtx (REG, SImode, 8), operands[1]);
3037 /* Restore %fp from stack pointer value for containing function.
3038 The restore insn that follows will move this to %sp,
3039 and reload the appropriate value into %fp. */
3040 emit_move_insn (frame_pointer_rtx, operands[2]);
3041 /* Put in the static chain register the nonlocal label address. */
3042 emit_move_insn (static_chain_rtx, operands[3]);
3043 /* USE of frame_pointer_rtx added for consistency; not clear if
3045 emit_insn (gen_rtx (USE, VOIDmode, frame_pointer_rtx));
3046 emit_insn (gen_rtx (USE, VOIDmode, stack_pointer_rtx));
3047 emit_insn (gen_rtx (USE, VOIDmode, static_chain_rtx));
3048 emit_insn (gen_rtx (USE, VOIDmode, gen_rtx (REG, SImode, 8)));
3049 /* Return, restoring reg window and jumping to goto handler. */
3050 emit_insn (gen_goto_handler_and_restore ());
3054 ;; Special trap insn to flush register windows.
3055 (define_insn "flush_register_windows"
3056 [(unspec_volatile [(const_int 0)] 0)]
3059 [(set_attr "type" "misc")])
3061 (define_insn "goto_handler_and_restore"
3062 [(unspec_volatile [(const_int 0)] 1)]
3064 "jmp %%o0+0\;restore"
3065 [(set_attr "type" "misc")
3066 (set_attr "length" "2")])
3068 ;; Special pattern for the FLUSH instruction.
3070 (define_insn "flush"
3071 [(unspec_volatile [(match_operand 0 "" "")] 2)]
3074 [(set_attr "type" "misc")])
3078 ;; The scan instruction searches from the most significant bit while ffs
3079 ;; searches from the least significant bit. The bit index and treatment of
3080 ;; zero also differ. It takes at least 7 instructions to get the proper
3081 ;; result. Here is an obvious 8 instruction seequence.
3083 (define_insn "ffssi2"
3084 [(set (match_operand:SI 0 "register_operand" "=&r")
3085 (ffs:SI (match_operand:SI 1 "register_operand" "r")))
3086 (clobber (match_scratch:SI 2 "=&r"))]
3088 "sub %%g0,%1,%0\;and %0,%1,%0\;scan %0,0,%0\;mov 32,%2\;sub %2,%0,%0\;sra %0,31,%2\;and %2,31,%2\;add %2,%0,%0"
3089 [(set_attr "type" "multi")
3090 (set_attr "length" "8")])
3092 ;; Split up troublesome insns for better scheduling. */
3094 ;; The following patterns are straightforward. They can be applied
3095 ;; either before or after register allocation.
3098 [(set (match_operator 0 "memop" [(match_operand:SI 1 "symbolic_operand" "")])
3099 (match_operand 2 "reg_or_0_operand" ""))
3100 (clobber (match_operand:SI 3 "register_operand" ""))]
3102 [(set (match_dup 3) (high:SI (match_dup 1)))
3103 (set (match_op_dup 0 [(lo_sum:SI (match_dup 3) (match_dup 1))])
3108 [(set (match_operator 0 "memop"
3109 [(match_operand:SI 1 "immediate_operand" "")])
3110 (match_operand 2 "general_operand" ""))
3111 (clobber (match_operand:SI 3 "register_operand" ""))]
3113 [(set (match_op_dup 0 [(match_dup 1)])
3117 operands[1] = legitimize_pic_address (operands[1], GET_MODE (operands[0]),
3122 [(set (match_operand 0 "register_operand" "")
3123 (match_operator 1 "memop"
3124 [(match_operand:SI 2 "immediate_operand" "")]))]
3127 (match_op_dup 1 [(match_dup 2)]))]
3130 operands[2] = legitimize_pic_address (operands[2], GET_MODE (operands[1]),
3134 ;; Sign- and Zero-extend operations can have symbolic memory operands.
3137 [(set (match_operand 0 "register_operand" "")
3138 (match_operator 1 "extend_op"
3139 [(match_operator 2 "memop"
3140 [(match_operand:SI 3 "immediate_operand" "")])]))]
3143 (match_op_dup 1 [(match_op_dup 2 [(match_dup 3)])]))]
3146 operands[3] = legitimize_pic_address (operands[3], GET_MODE (operands[2]),
3151 [(set (match_operand:SI 0 "register_operand" "")
3152 (match_operand:SI 1 "immediate_operand" ""))]
3153 "! flag_pic && (GET_CODE (operands[1]) == SYMBOL_REF
3154 || GET_CODE (operands[1]) == CONST
3155 || GET_CODE (operands[1]) == LABEL_REF)"
3156 [(set (match_dup 0) (high:SI (match_dup 1)))
3158 (lo_sum:SI (match_dup 0) (match_dup 1)))]
3161 ;; LABEL_REFs are not modified by `legitimize_pic_address`
3162 ;; so do not recurse infinitely in the PIC case.
3164 [(set (match_operand:SI 0 "register_operand" "")
3165 (match_operand:SI 1 "immediate_operand" ""))]
3166 "flag_pic && (GET_CODE (operands[1]) == SYMBOL_REF
3167 || GET_CODE (operands[1]) == CONST)"
3168 [(set (match_dup 0) (match_dup 1))]
3171 operands[1] = legitimize_pic_address (operands[1], Pmode, operands[0]);
3174 ;; These split sne/seq insns. The forms of the resulting insns are
3175 ;; somewhat bogus, but they avoid extra patterns and show data dependency.
3176 ;; Nothing will look at these in detail after splitting has occurred.
3179 [(set (match_operand:SI 0 "register_operand" "")
3180 (ne:SI (match_operand:SI 1 "register_operand" "") (const_int 0)))
3181 (clobber (reg:CC 0))]
3183 [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
3185 (set (match_dup 0) (ltu:SI (reg:CC 0) (const_int 0)))]
3189 [(set (match_operand:SI 0 "register_operand" "")
3190 (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "")
3192 (clobber (reg:CC 0))]
3194 [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
3196 (set (match_dup 0) (neg:SI (ltu:SI (reg:CC 0) (const_int 0))))]
3200 [(set (match_operand:SI 0 "register_operand" "")
3201 (eq:SI (match_operand:SI 1 "register_operand" "") (const_int 0)))
3202 (clobber (reg:CC 0))]
3204 [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
3206 (set (match_dup 0) (geu:SI (reg:CC 0) (const_int 0)))]
3210 [(set (match_operand:SI 0 "register_operand" "")
3211 (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "")
3213 (clobber (reg:CC 0))]
3215 [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
3217 (set (match_dup 0) (neg:SI (geu:SI (reg:CC 0) (const_int 0))))]
3221 [(set (match_operand:SI 0 "register_operand" "")
3222 (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "")
3224 (match_operand:SI 2 "register_operand" "")))
3225 (clobber (reg:CC 0))]
3227 [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
3229 (set (match_dup 0) (plus:SI (ltu:SI (reg:CC 0) (const_int 0))
3234 [(set (match_operand:SI 0 "register_operand" "")
3235 (minus:SI (match_operand:SI 2 "register_operand" "")
3236 (ne:SI (match_operand:SI 1 "register_operand" "")
3238 (clobber (reg:CC 0))]
3240 [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
3242 (set (match_dup 0) (minus:SI (match_dup 2)
3243 (ltu:SI (reg:CC 0) (const_int 0))))]
3247 [(set (match_operand:SI 0 "register_operand" "")
3248 (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "")
3250 (match_operand:SI 2 "register_operand" "")))
3251 (clobber (reg:CC 0))]
3253 [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
3255 (set (match_dup 0) (plus:SI (geu:SI (reg:CC 0) (const_int 0))
3260 [(set (match_operand:SI 0 "register_operand" "")
3261 (minus:SI (match_operand:SI 2 "register_operand" "")
3262 (eq:SI (match_operand:SI 1 "register_operand" "")
3264 (clobber (reg:CC 0))]
3266 [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
3268 (set (match_dup 0) (minus:SI (match_dup 2)
3269 (geu:SI (reg:CC 0) (const_int 0))))]
3272 ;; Peepholes go at the end.
3274 ;; Optimize consecutive loads or stores into ldd and std when possible.
3275 ;; The conditions in which we do this are very restricted and are
3276 ;; explained in the code for {registers,memory}_ok_for_ldd functions.
3279 [(set (match_operand:SI 0 "register_operand" "=rf")
3280 (match_operand:SI 1 "memory_operand" ""))
3281 (set (match_operand:SI 2 "register_operand" "=rf")
3282 (match_operand:SI 3 "memory_operand" ""))]
3283 "registers_ok_for_ldd_peep (operands[0], operands[2])
3284 && ! MEM_VOLATILE_P (operands[1]) && ! MEM_VOLATILE_P (operands[3])
3285 && addrs_ok_for_ldd_peep (XEXP (operands[1], 0), XEXP (operands[3], 0))"
3289 [(set (match_operand:SI 0 "memory_operand" "")
3290 (match_operand:SI 1 "register_operand" "rf"))
3291 (set (match_operand:SI 2 "memory_operand" "")
3292 (match_operand:SI 3 "register_operand" "rf"))]
3293 "registers_ok_for_ldd_peep (operands[1], operands[3])
3294 && ! MEM_VOLATILE_P (operands[0]) && ! MEM_VOLATILE_P (operands[2])
3295 && addrs_ok_for_ldd_peep (XEXP (operands[0], 0), XEXP (operands[2], 0))"
3299 [(set (match_operand:SF 0 "register_operand" "=fr")
3300 (match_operand:SF 1 "memory_operand" ""))
3301 (set (match_operand:SF 2 "register_operand" "=fr")
3302 (match_operand:SF 3 "memory_operand" ""))]
3303 "registers_ok_for_ldd_peep (operands[0], operands[2])
3304 && ! MEM_VOLATILE_P (operands[1]) && ! MEM_VOLATILE_P (operands[3])
3305 && addrs_ok_for_ldd_peep (XEXP (operands[1], 0), XEXP (operands[3], 0))"
3309 [(set (match_operand:SF 0 "memory_operand" "")
3310 (match_operand:SF 1 "register_operand" "fr"))
3311 (set (match_operand:SF 2 "memory_operand" "")
3312 (match_operand:SF 3 "register_operand" "fr"))]
3313 "registers_ok_for_ldd_peep (operands[1], operands[3])
3314 && ! MEM_VOLATILE_P (operands[0]) && ! MEM_VOLATILE_P (operands[2])
3315 && addrs_ok_for_ldd_peep (XEXP (operands[0], 0), XEXP (operands[2], 0))"
3319 [(set (match_operand:SI 0 "register_operand" "=rf")
3320 (match_operand:SI 1 "memory_operand" ""))
3321 (set (match_operand:SI 2 "register_operand" "=rf")
3322 (match_operand:SI 3 "memory_operand" ""))]
3323 "registers_ok_for_ldd_peep (operands[2], operands[0])
3324 && ! MEM_VOLATILE_P (operands[3]) && ! MEM_VOLATILE_P (operands[1])
3325 && addrs_ok_for_ldd_peep (XEXP (operands[3], 0), XEXP (operands[1], 0))"
3329 [(set (match_operand:SI 0 "memory_operand" "")
3330 (match_operand:SI 1 "register_operand" "rf"))
3331 (set (match_operand:SI 2 "memory_operand" "")
3332 (match_operand:SI 3 "register_operand" "rf"))]
3333 "registers_ok_for_ldd_peep (operands[3], operands[1])
3334 && ! MEM_VOLATILE_P (operands[2]) && ! MEM_VOLATILE_P (operands[0])
3335 && addrs_ok_for_ldd_peep (XEXP (operands[2], 0), XEXP (operands[0], 0))"
3339 [(set (match_operand:SF 0 "register_operand" "=fr")
3340 (match_operand:SF 1 "memory_operand" ""))
3341 (set (match_operand:SF 2 "register_operand" "=fr")
3342 (match_operand:SF 3 "memory_operand" ""))]
3343 "registers_ok_for_ldd_peep (operands[2], operands[0])
3344 && ! MEM_VOLATILE_P (operands[3]) && ! MEM_VOLATILE_P (operands[1])
3345 && addrs_ok_for_ldd_peep (XEXP (operands[3], 0), XEXP (operands[1], 0))"
3349 [(set (match_operand:SF 0 "memory_operand" "")
3350 (match_operand:SF 1 "register_operand" "fr"))
3351 (set (match_operand:SF 2 "memory_operand" "")
3352 (match_operand:SF 3 "register_operand" "fr"))]
3353 "registers_ok_for_ldd_peep (operands[3], operands[1])
3354 && ! MEM_VOLATILE_P (operands[2]) && ! MEM_VOLATILE_P (operands[0])
3355 && addrs_ok_for_ldd_peep (XEXP (operands[2], 0), XEXP (operands[0], 0))"
3358 ;; Optimize the case of following a reg-reg move with a test
3359 ;; of reg just moved. Don't allow floating point regs for operand 0 or 1.
3360 ;; This can result from a float to fix conversion.
3363 [(set (match_operand:SI 0 "register_operand" "=r")
3364 (match_operand:SI 1 "register_operand" "r"))
3366 (compare:CC (match_operand:SI 2 "register_operand" "r")
3368 "(rtx_equal_p (operands[2], operands[0])
3369 || rtx_equal_p (operands[2], operands[1]))
3370 && ! FP_REG_P (operands[0]) && ! FP_REG_P (operands[1])"
3373 ;; Do {sign,zero}-extended compares somewhat more efficiently.
3374 ;; ??? Is this now the Right Way to do this? Or will SCRATCH
3375 ;; eventually have some impact here?
3378 [(set (match_operand:HI 0 "register_operand" "")
3379 (match_operand:HI 1 "memory_operand" ""))
3380 (set (match_operand:SI 2 "register_operand" "")
3381 (sign_extend:SI (match_dup 0)))
3383 (compare:CC (match_dup 2)
3386 "ldsh %1,%0\;orcc %0,%%g0,%2")
3389 [(set (match_operand:QI 0 "register_operand" "")
3390 (match_operand:QI 1 "memory_operand" ""))
3391 (set (match_operand:SI 2 "register_operand" "")
3392 (sign_extend:SI (match_dup 0)))
3394 (compare:CC (match_dup 2)
3397 "ldsb %1,%0\;orcc %0,%%g0,%2")
3400 [(set (match_operand:HI 0 "register_operand" "")
3401 (match_operand:HI 1 "memory_operand" ""))
3402 (set (match_operand:SI 2 "register_operand" "")
3403 (sign_extend:SI (match_dup 0)))]
3404 "dead_or_set_p (insn, operands[0])"
3407 warning (\"bad peephole\");
3408 if (! MEM_VOLATILE_P (operands[1]))
3410 return \"ldsh %1,%2\";
3414 [(set (match_operand:QI 0 "register_operand" "")
3415 (match_operand:QI 1 "memory_operand" ""))
3416 (set (match_operand:SI 2 "register_operand" "")
3417 (sign_extend:SI (match_dup 0)))]
3418 "dead_or_set_p (insn, operands[0])"
3421 warning (\"bad peephole\");
3422 if (! MEM_VOLATILE_P (operands[1]))
3424 return \"ldsb %1,%2\";
3427 ;; Floating-point move peepholes
3430 [(set (match_operand:SI 0 "register_operand" "=r")
3431 (lo_sum:SI (match_dup 0)
3432 (match_operand:SI 1 "immediate_operand" "i")))
3433 (set (match_operand:DF 2 "register_operand" "=fr")
3434 (mem:DF (match_dup 0)))]
3435 "RTX_UNCHANGING_P (operands[1]) && reg_unused_after (operands[0], insn)"
3438 /* Go by way of output_move_double in case the register in operand 2
3439 is not properly aligned for ldd. */
3440 operands[1] = gen_rtx (MEM, DFmode,
3441 gen_rtx (LO_SUM, SImode, operands[0], operands[1]));
3442 operands[0] = operands[2];
3443 return output_move_double (operands);
3447 [(set (match_operand:SI 0 "register_operand" "=r")
3448 (lo_sum:SI (match_dup 0)
3449 (match_operand:SI 1 "immediate_operand" "i")))
3450 (set (match_operand:SF 2 "register_operand" "=fr")
3451 (mem:SF (match_dup 0)))]
3452 "RTX_UNCHANGING_P (operands[1]) && reg_unused_after (operands[0], insn)"
3453 "ld [%0+%%lo(%a1)],%2")
3455 ;; Return peepholes. First the "normal" ones
3457 ;; ??? There are QImode, HImode, and SImode versions of this pattern.
3458 ;; It might be possible to write one more general pattern instead of three.
3461 [(set (match_operand:QI 0 "restore_operand" "")
3462 (match_operand:QI 1 "arith_operand" "rI"))
3467 if (current_function_returns_struct)
3468 return \"jmp %%i7+12\;restore %%g0,%1,%Y0\";
3470 return \"ret\;restore %%g0,%1,%Y0\";
3472 [(set_attr "type" "multi")])
3475 [(set (match_operand:HI 0 "restore_operand" "")
3476 (match_operand:HI 1 "arith_operand" "rI"))
3481 if (current_function_returns_struct)
3482 return \"jmp %%i7+12\;restore %%g0,%1,%Y0\";
3484 return \"ret\;restore %%g0,%1,%Y0\";
3486 [(set_attr "type" "multi")])
3489 [(set (match_operand:SI 0 "restore_operand" "")
3490 (match_operand:SI 1 "arith_operand" "rI"))
3495 if (current_function_returns_struct)
3496 return \"jmp %%i7+12\;restore %%g0,%1,%Y0\";
3498 return \"ret\;restore %%g0,%1,%Y0\";
3500 [(set_attr "type" "multi")])
3502 ;; The following pattern is only generated by delayed-branch scheduling,
3503 ;; when the insn winds up in the epilogue. This can only happen when
3504 ;; ! TARGET_FPU because otherwise fp return values are in %f0.
3506 [(set (match_operand:SF 0 "restore_operand" "r")
3507 (match_operand:SF 1 "register_operand" "r"))
3509 "! TARGET_FPU && ! TARGET_EPILOGUE"
3512 if (current_function_returns_struct)
3513 return \"jmp %%i7+12\;restore %%g0,%1,%Y0\";
3515 return \"ret\;restore %%g0,%1,%Y0\";
3517 [(set_attr "type" "multi")])
3520 [(set (match_operand:SI 0 "restore_operand" "")
3521 (plus:SI (match_operand:SI 1 "arith_operand" "%r")
3522 (match_operand:SI 2 "arith_operand" "rI")))
3527 if (current_function_returns_struct)
3528 return \"jmp %%i7+12\;restore %r1,%2,%Y0\";
3530 return \"ret\;restore %r1,%2,%Y0\";
3532 [(set_attr "type" "multi")])
3534 ;; Turned off because it should never match (subtracting a constant
3535 ;; is turned into addition) and because it would do the wrong thing
3536 ;; when operand 2 is -4096 (--4096 == 4096 is not a valid immediate).
3538 ;; [(set (match_operand:SI 0 "restore_operand" "")
3539 ;; (minus:SI (match_operand:SI 1 "register_operand" "r")
3540 ;; (match_operand:SI 2 "small_int" "I")))
3542 ;; "! TARGET_EPILOGUE"
3543 ;; "ret\;restore %1,-(%2),%Y0"
3544 ;; [(set_attr "type" "multi")])
3546 ;; The following pattern is only generated by delayed-branch scheduling,
3547 ;; when the insn winds up in the epilogue.
3550 (match_operand:SF 0 "register_operand" "f"))
3553 "ret\;fmovs %0,%%f0"
3554 [(set_attr "type" "multi")])
3556 ;; Now peepholes to go a call followed by a jump.
3559 [(parallel [(set (match_operand 0 "" "")
3560 (call (mem:SI (match_operand:SI 1 "call_operand_address" "pi"))
3561 (match_operand 2 "" "")))
3562 (clobber (reg:SI 15))])
3563 (set (pc) (label_ref (match_operand 3 "" "")))]
3564 "short_branch (INSN_UID (insn), INSN_UID (operands[3]))"
3567 return \"call %a1,%2\;add %%o7,(%l3-.-4),%%o7\";
3571 [(parallel [(call (mem:SI (match_operand:SI 0 "call_operand_address" "pi"))
3572 (match_operand 1 "" ""))
3573 (clobber (reg:SI 15))])
3574 (set (pc) (label_ref (match_operand 2 "" "")))]
3575 "short_branch (INSN_UID (insn), INSN_UID (operands[2]))"
3578 return \"call %a0,%1\;add %%o7,(%l2-.-4),%%o7\";
3582 [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
3583 (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
3585 (clobber (reg:CC 0))])
3586 (set (reg:CC 0) (compare (match_dup 0) (const_int 0)))]