1 ;;- Machine description for SPARC chip for GNU C compiler
2 ;; Copyright (C) 1987, 1988, 1989, 1992 Free Software Foundation, Inc.
3 ;; Contributed by Michael Tiemann (tiemann@cygnus.com)
5 ;; This file is part of GNU CC.
7 ;; GNU CC is free software; you can redistribute it and/or modify
8 ;; it under the terms of the GNU General Public License as published by
9 ;; the Free Software Foundation; either version 2, or (at your option)
12 ;; GNU CC is distributed in the hope that it will be useful,
13 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
14 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 ;; GNU General Public License for more details.
17 ;; You should have received a copy of the GNU General Public License
18 ;; along with GNU CC; see the file COPYING. If not, write to
19 ;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
22 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
24 ;; Insn type. Used to default other attribute values.
26 ;; type "unary" insns have one input operand (1) and one output operand (0)
27 ;; type "binary" insns have two input operands (1,2) and one output (0)
28 ;; type "compare" insns have one or two input operands (0,1) and no output
29 ;; type "call_no_delay_slot" is a call followed by an unimp instruction.
32 "move,unary,binary,compare,load,store,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 "movsi"
776 [(set (match_operand:SI 0 "general_operand" "")
777 (match_operand:SI 1 "general_operand" ""))]
781 if (emit_move_sequence (operands, SImode, NULL_RTX))
785 (define_expand "reload_insi"
786 [(set (match_operand:SI 0 "register_operand" "=r")
787 (match_operand:SI 1 "general_operand" ""))
788 (clobber (match_operand:SI 2 "register_operand" "=&r"))]
792 if (emit_move_sequence (operands, SImode, operands[2]))
795 /* We don't want the clobber emitted, so handle this ourselves. */
796 emit_insn (gen_rtx (SET, VOIDmode, operands[0], operands[1]));
800 ;; We must support both 'r' and 'f' registers here, because combine may
801 ;; convert SFmode hard registers to SImode hard registers when simplifying
804 ;; We cannot combine the similar 'r' and 'f' constraints, because it causes
805 ;; problems with register allocation. Reload might try to put an integer
806 ;; in an fp register, or an fp number is an integer register.
809 [(set (match_operand:SI 0 "reg_or_nonsymb_mem_operand" "=r,f,r,r,f,Q,Q")
810 (match_operand:SI 1 "move_operand" "rI,!f,K,Q,!Q,rJ,!f"))]
811 "register_operand (operands[0], SImode)
812 || register_operand (operands[1], SImode)
813 || operands[1] == const0_rtx"
822 [(set_attr "type" "move,fp,move,load,load,store,store")
823 (set_attr "length" "*,*,1,*,*,*,*")])
825 ;; Special pic pattern, for loading the address of a label into a register.
826 ;; It clobbers o7 because the call puts the return address (i.e. pc value)
830 [(set (match_operand:SI 0 "register_operand" "=r")
831 (match_operand:SI 1 "move_pic_label" "i"))
832 (set (reg:SI 15) (pc))]
834 "\\n1:\;call 2f\;sethi %%hi(%l1-1b),%0\\n2:\\tor %0,%%lo(%l1-1b),%0\;add %0,%%o7,%0"
835 [(set_attr "type" "multi")
836 (set_attr "length" "4")])
839 [(set (match_operand:DI 0 "register_operand" "=r")
840 (high:DI (match_operand 1 "" "")))]
844 rtx op0 = operands[0];
845 rtx op1 = operands[1];
847 if (GET_CODE (op1) == CONST_INT)
849 operands[0] = operand_subword (op0, 1, 0, DImode);
850 output_asm_insn (\"sethi %%hi(%a1),%0\", operands);
852 operands[0] = operand_subword (op0, 0, 0, DImode);
853 if (INTVAL (op1) < 0)
854 return \"mov -1,%0\";
858 else if (GET_CODE (op1) == CONST_DOUBLE)
860 operands[0] = operand_subword (op0, 1, 0, DImode);
861 operands[1] = gen_rtx (CONST_INT, VOIDmode, CONST_DOUBLE_LOW (op1));
862 output_asm_insn (\"sethi %%hi(%a1),%0\", operands);
864 operands[0] = operand_subword (op0, 0, 0, DImode);
865 operands[1] = gen_rtx (CONST_INT, VOIDmode, CONST_DOUBLE_HIGH (op1));
866 return singlemove_string (operands);
872 [(set_attr "type" "move")
873 (set_attr "length" "2")])
875 ;; For PIC, symbol_refs are put inside unspec so that the optimizer won't
876 ;; confuse them with real addresses.
878 [(set (match_operand:SI 0 "register_operand" "=r")
879 (high:SI (unspec:SI [(match_operand 1 "" "")] 0)))]
882 [(set_attr "type" "move")
883 (set_attr "length" "1")])
886 [(set (match_operand:SI 0 "register_operand" "=r")
887 (high:SI (match_operand 1 "" "")))]
890 [(set_attr "type" "move")
891 (set_attr "length" "1")])
894 [(set (match_operand:HI 0 "register_operand" "=r")
895 (high:HI (match_operand 1 "" "")))]
898 [(set_attr "type" "move")
899 (set_attr "length" "1")])
902 [(set (match_operand:DI 0 "register_operand" "=r")
903 (lo_sum:DI (match_operand:DI 1 "register_operand" "0")
904 (match_operand:DI 2 "immediate_operand" "in")))]
908 /* Don't output a 64 bit constant, since we can't trust the assembler to
909 handle it correctly. */
910 if (GET_CODE (operands[2]) == CONST_DOUBLE)
911 operands[2] = gen_rtx (CONST_INT, VOIDmode, CONST_DOUBLE_LOW (operands[2]));
912 return \"or %R1,%%lo(%a2),%R0\";
914 ;; Need to set length for this arith insn because operand2
915 ;; is not an "arith_operand".
916 [(set_attr "length" "1")])
918 ;; For PIC, symbol_refs are put inside unspec so that the optimizer won't
919 ;; confuse them with real addresses.
921 [(set (match_operand:SI 0 "register_operand" "=r")
922 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
923 (unspec:SI [(match_operand:SI 2 "immediate_operand" "in")] 0)))]
926 ;; Need to set length for this arith insn because operand2
927 ;; is not an "arith_operand".
928 [(set_attr "length" "1")])
931 [(set (match_operand:SI 0 "register_operand" "=r")
932 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
933 (match_operand:SI 2 "immediate_operand" "in")))]
936 ;; Need to set length for this arith insn because operand2
937 ;; is not an "arith_operand".
938 [(set_attr "length" "1")])
941 [(set (mem:SI (match_operand:SI 0 "symbolic_operand" ""))
942 (match_operand:SI 1 "reg_or_0_operand" "rJ"))
943 (clobber (match_scratch:SI 2 "=&r"))]
945 "sethi %%hi(%a0),%2\;st %r1,[%2+%%lo(%a0)]"
946 [(set_attr "type" "store")
947 (set_attr "length" "2")])
949 (define_expand "movhi"
950 [(set (match_operand:HI 0 "general_operand" "")
951 (match_operand:HI 1 "general_operand" ""))]
955 if (emit_move_sequence (operands, HImode, NULL_RTX))
960 [(set (match_operand:HI 0 "reg_or_nonsymb_mem_operand" "=r,r,r,Q")
961 (match_operand:HI 1 "move_operand" "rI,K,Q,rJ"))]
962 "register_operand (operands[0], HImode)
963 || register_operand (operands[1], HImode)
964 || operands[1] == const0_rtx"
970 [(set_attr "type" "move,move,load,store")
971 (set_attr "length" "*,1,*,1")])
974 [(set (match_operand:HI 0 "register_operand" "=r")
975 (lo_sum:HI (match_operand:HI 1 "register_operand" "r")
976 (match_operand 2 "immediate_operand" "in")))]
979 [(set_attr "length" "1")])
982 [(set (mem:HI (match_operand:SI 0 "symbolic_operand" ""))
983 (match_operand:HI 1 "reg_or_0_operand" "rJ"))
984 (clobber (match_scratch:SI 2 "=&r"))]
986 "sethi %%hi(%a0),%2\;sth %r1,[%2+%%lo(%a0)]"
987 [(set_attr "type" "store")
988 (set_attr "length" "2")])
990 (define_expand "movqi"
991 [(set (match_operand:QI 0 "general_operand" "")
992 (match_operand:QI 1 "general_operand" ""))]
996 if (emit_move_sequence (operands, QImode, NULL_RTX))
1001 [(set (match_operand:QI 0 "reg_or_nonsymb_mem_operand" "=r,r,r,Q")
1002 (match_operand:QI 1 "move_operand" "rI,K,Q,rJ"))]
1003 "register_operand (operands[0], QImode)
1004 || register_operand (operands[1], QImode)
1005 || operands[1] == const0_rtx"
1011 [(set_attr "type" "move,move,load,store")
1012 (set_attr "length" "*,1,*,1")])
1015 [(set (match_operand:QI 0 "register_operand" "=r")
1016 (subreg:QI (lo_sum:SI (match_operand:QI 1 "register_operand" "r")
1017 (match_operand 2 "immediate_operand" "in")) 0))]
1019 "or %1,%%lo(%a2),%0"
1020 [(set_attr "length" "1")])
1023 [(set (mem:QI (match_operand:SI 0 "symbolic_operand" ""))
1024 (match_operand:QI 1 "reg_or_0_operand" "rJ"))
1025 (clobber (match_scratch:SI 2 "=&r"))]
1027 "sethi %%hi(%a0),%2\;stb %r1,[%2+%%lo(%a0)]"
1028 [(set_attr "type" "store")
1029 (set_attr "length" "2")])
1031 ;; ??? We get better code without it. See output_block_move in sparc.c.
1033 ;; The definition of this insn does not really explain what it does,
1034 ;; but it should suffice
1035 ;; that anything generated as this insn will be recognized as one
1036 ;; and that it will not successfully combine with anything.
1037 ;(define_expand "movstrsi"
1038 ; [(parallel [(set (mem:BLK (match_operand:BLK 0 "general_operand" ""))
1039 ; (mem:BLK (match_operand:BLK 1 "general_operand" "")))
1040 ; (use (match_operand:SI 2 "nonmemory_operand" ""))
1041 ; (use (match_operand:SI 3 "immediate_operand" ""))
1042 ; (clobber (match_dup 0))
1043 ; (clobber (match_dup 1))
1044 ; (clobber (match_scratch:SI 4 ""))
1045 ; (clobber (reg:SI 0))
1046 ; (clobber (reg:SI 1))])]
1050 ; /* If the size isn't known, don't emit inline code. output_block_move
1051 ; would output code that's much slower than the library function.
1052 ; Also don't output code for large blocks. */
1053 ; if (GET_CODE (operands[2]) != CONST_INT
1054 ; || GET_CODE (operands[3]) != CONST_INT
1055 ; || INTVAL (operands[2]) / INTVAL (operands[3]) > 16)
1058 ; operands[0] = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
1059 ; operands[1] = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
1060 ; operands[2] = force_not_mem (operands[2]);
1064 ; [(set (mem:BLK (match_operand:SI 0 "register_operand" "+r"))
1065 ; (mem:BLK (match_operand:SI 1 "register_operand" "+r")))
1066 ; (use (match_operand:SI 2 "nonmemory_operand" "rn"))
1067 ; (use (match_operand:SI 3 "immediate_operand" "i"))
1068 ; (clobber (match_dup 0))
1069 ; (clobber (match_dup 1))
1070 ; (clobber (match_scratch:SI 4 "=&r"))
1071 ; (clobber (reg:SI 0))
1072 ; (clobber (reg:SI 1))]
1074 ; "* return output_block_move (operands);"
1075 ; [(set_attr "type" "multi")
1076 ; (set_attr "length" "6")])
1078 ;; Floating point move insns
1080 ;; This pattern forces (set (reg:TF ...) (const_double ...))
1081 ;; to be reloaded by putting the constant into memory.
1082 ;; It must come before the more general movtf pattern.
1084 [(set (match_operand:TF 0 "general_operand" "=?r,f,o")
1085 (match_operand:TF 1 "" "?E,m,G"))]
1086 "TARGET_FPU && GET_CODE (operands[1]) == CONST_DOUBLE"
1089 switch (which_alternative)
1092 return output_move_quad (operands);
1094 return output_fp_move_quad (operands);
1096 operands[1] = adj_offsettable_operand (operands[0], 4);
1097 operands[2] = adj_offsettable_operand (operands[0], 8);
1098 operands[3] = adj_offsettable_operand (operands[0], 12);
1099 return \"st %%g0,%0\;st %%g0,%1\;st %%g0,%2\;st %%g0,%3\";
1102 [(set_attr "type" "load,fpload,store")
1103 (set_attr "length" "5,5,5")])
1105 (define_expand "movtf"
1106 [(set (match_operand:TF 0 "general_operand" "")
1107 (match_operand:TF 1 "general_operand" ""))]
1111 if (emit_move_sequence (operands, TFmode, NULL_RTX))
1116 [(set (match_operand:TF 0 "reg_or_nonsymb_mem_operand" "=f,r,Q,Q,f,&r")
1117 (match_operand:TF 1 "reg_or_nonsymb_mem_operand" "f,r,f,r,Q,Q"))]
1119 && (register_operand (operands[0], TFmode)
1120 || register_operand (operands[1], TFmode))"
1123 if (FP_REG_P (operands[0]) || FP_REG_P (operands[1]))
1124 return output_fp_move_quad (operands);
1125 return output_move_quad (operands);
1127 [(set_attr "type" "fp,move,fpstore,store,fpload,load")
1128 (set_attr "length" "4,4,5,5,5,5")])
1130 ;; Exactly the same as above, except that all `f' cases are deleted.
1131 ;; This is necessary to prevent reload from ever trying to use a `f' reg
1135 [(set (match_operand:TF 0 "reg_or_nonsymb_mem_operand" "=r,Q,&r")
1136 (match_operand:TF 1 "reg_or_nonsymb_mem_operand" "r,r,Q"))]
1138 && (register_operand (operands[0], TFmode)
1139 || register_operand (operands[1], TFmode))"
1142 if (FP_REG_P (operands[0]) || FP_REG_P (operands[1]))
1143 return output_fp_move_quad (operands);
1144 return output_move_quad (operands);
1146 [(set_attr "type" "move,store,load")
1147 (set_attr "length" "4,5,5")])
1150 [(set (mem:TF (match_operand:SI 0 "symbolic_operand" "i,i"))
1151 (match_operand:TF 1 "reg_or_0_operand" "rf,G"))
1152 (clobber (match_scratch:SI 2 "=&r,&r"))]
1156 output_asm_insn (\"sethi %%hi(%a0),%2\", operands);
1157 if (which_alternative == 0)
1158 return \"std %1,[%2+%%lo(%a0)]\;std %S1,[%2+%%lo(%a0+8)]\";
1160 return \"st %%g0,[%2+%%lo(%a0)]\;st %%g0,[%2+%%lo(%a0+4)]\; st %%g0,[%2+%%lo(%a0+8)]\;st %%g0,[%2+%%lo(%a0+12)]\";
1162 [(set_attr "type" "store")
1163 (set_attr "length" "5")])
1165 ;; This pattern forces (set (reg:DF ...) (const_double ...))
1166 ;; to be reloaded by putting the constant into memory.
1167 ;; It must come before the more general movdf pattern.
1170 [(set (match_operand:DF 0 "general_operand" "=?r,f,o")
1171 (match_operand:DF 1 "" "?E,m,G"))]
1172 "TARGET_FPU && GET_CODE (operands[1]) == CONST_DOUBLE"
1175 switch (which_alternative)
1178 return output_move_double (operands);
1180 return output_fp_move_double (operands);
1182 operands[1] = adj_offsettable_operand (operands[0], 4);
1183 return \"st %%g0,%0\;st %%g0,%1\";
1186 [(set_attr "type" "load,fpload,store")
1187 (set_attr "length" "3,3,3")])
1189 (define_expand "movdf"
1190 [(set (match_operand:DF 0 "general_operand" "")
1191 (match_operand:DF 1 "general_operand" ""))]
1195 if (emit_move_sequence (operands, DFmode, NULL_RTX))
1200 [(set (match_operand:DF 0 "reg_or_nonsymb_mem_operand" "=T,U,f,r,Q,Q,f,r")
1201 (match_operand:DF 1 "reg_or_nonsymb_mem_operand" "U,T,f,r,f,r,Q,Q"))]
1203 && (register_operand (operands[0], DFmode)
1204 || register_operand (operands[1], DFmode))"
1207 if (FP_REG_P (operands[0]) || FP_REG_P (operands[1]))
1208 return output_fp_move_double (operands);
1209 return output_move_double (operands);
1211 [(set_attr "type" "fpstore,fpload,fp,move,fpstore,store,fpload,load")
1212 (set_attr "length" "1,1,2,2,3,3,3,3")])
1214 ;; Exactly the same as above, except that all `f' cases are deleted.
1215 ;; This is necessary to prevent reload from ever trying to use a `f' reg
1219 [(set (match_operand:DF 0 "reg_or_nonsymb_mem_operand" "=T,U,r,Q,&r")
1220 (match_operand:DF 1 "reg_or_nonsymb_mem_operand" "U,T,r,r,Q"))]
1222 && (register_operand (operands[0], DFmode)
1223 || register_operand (operands[1], DFmode))"
1224 "* return output_move_double (operands);"
1225 [(set_attr "type" "store,load,move,store,load")
1226 (set_attr "length" "1,1,2,3,3")])
1229 [(set (match_operand:DF 0 "register_operand" "")
1230 (match_operand:DF 1 "register_operand" ""))]
1232 [(set (match_dup 2) (match_dup 3))
1233 (set (match_dup 4) (match_dup 5))]
1235 { operands[2] = operand_subword (operands[0], 0, 0, DFmode);
1236 operands[3] = operand_subword (operands[1], 0, 0, DFmode);
1237 operands[4] = operand_subword (operands[0], 1, 0, DFmode);
1238 operands[5] = operand_subword (operands[1], 1, 0, DFmode); }")
1241 [(set (mem:DF (match_operand:SI 0 "symbolic_operand" "i,i"))
1242 (match_operand:DF 1 "reg_or_0_operand" "rf,G"))
1243 (clobber (match_scratch:SI 2 "=&r,&r"))]
1247 output_asm_insn (\"sethi %%hi(%a0),%2\", operands);
1248 if (which_alternative == 0)
1249 return \"std %1,[%2+%%lo(%a0)]\";
1251 return \"st %%g0,[%2+%%lo(%a0)]\;st %%g0,[%2+%%lo(%a0+4)]\";
1253 [(set_attr "type" "store")
1254 (set_attr "length" "3")])
1256 ;; Double-word move insns.
1258 (define_expand "movdi"
1259 [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand" "")
1260 (match_operand:DI 1 "general_operand" ""))]
1264 if (emit_move_sequence (operands, DImode, NULL_RTX))
1269 [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand" "=r,Q,r,&r,?f,?f,?Q")
1270 (match_operand:DI 1 "general_operand" "r,r,Q,i,f,Q,f"))]
1271 "register_operand (operands[0], DImode)
1272 || register_operand (operands[1], DImode)
1273 || operands[1] == const0_rtx"
1276 if (FP_REG_P (operands[0]) || FP_REG_P (operands[1]))
1277 return output_fp_move_double (operands);
1278 return output_move_double (operands);
1280 [(set_attr "type" "move,store,load,multi,fp,fpload,fpstore")
1281 (set_attr "length" "2,3,3,3,2,3,3")])
1283 ;; Floating-point move insns.
1285 ;; This pattern forces (set (reg:SF ...) (const_double ...))
1286 ;; to be reloaded by putting the constant into memory.
1287 ;; It must come before the more general movsf pattern.
1289 [(set (match_operand:SF 0 "general_operand" "=?r,f,m")
1290 (match_operand:SF 1 "" "?E,m,G"))]
1291 "TARGET_FPU && GET_CODE (operands[1]) == CONST_DOUBLE"
1294 switch (which_alternative)
1297 return singlemove_string (operands);
1299 return \"ld %1,%0\";
1301 return \"st %%g0,%0\";
1304 [(set_attr "type" "load,fpload,store")
1305 (set_attr "length" "2,1,1")])
1307 (define_expand "movsf"
1308 [(set (match_operand:SF 0 "general_operand" "")
1309 (match_operand:SF 1 "general_operand" ""))]
1313 if (emit_move_sequence (operands, SFmode, NULL_RTX))
1318 [(set (match_operand:SF 0 "reg_or_nonsymb_mem_operand" "=f,r,f,r,Q,Q")
1319 (match_operand:SF 1 "reg_or_nonsymb_mem_operand" "f,r,Q,Q,f,r"))]
1321 && (register_operand (operands[0], SFmode)
1322 || register_operand (operands[1], SFmode))"
1330 [(set_attr "type" "fp,move,fpload,load,fpstore,store")])
1332 ;; Exactly the same as above, except that all `f' cases are deleted.
1333 ;; This is necessary to prevent reload from ever trying to use a `f' reg
1337 [(set (match_operand:SF 0 "reg_or_nonsymb_mem_operand" "=r,r,Q")
1338 (match_operand:SF 1 "reg_or_nonsymb_mem_operand" "r,Q,r"))]
1340 && (register_operand (operands[0], SFmode)
1341 || register_operand (operands[1], SFmode))"
1346 [(set_attr "type" "move,load,store")])
1349 [(set (mem:SF (match_operand:SI 0 "symbolic_operand" "i"))
1350 (match_operand:SF 1 "reg_or_0_operand" "rfG"))
1351 (clobber (match_scratch:SI 2 "=&r"))]
1353 "sethi %%hi(%a0),%2\;st %r1,[%2+%%lo(%a0)]"
1354 [(set_attr "type" "store")
1355 (set_attr "length" "2")])
1357 ;;- zero extension instructions
1359 ;; These patterns originally accepted general_operands, however, slightly
1360 ;; better code is generated by only accepting register_operands, and then
1361 ;; letting combine generate the ldu[hb] insns.
1363 (define_expand "zero_extendhisi2"
1364 [(set (match_operand:SI 0 "register_operand" "")
1365 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
1369 rtx temp = gen_reg_rtx (SImode);
1370 rtx shift_16 = gen_rtx (CONST_INT, VOIDmode, 16);
1371 int op1_subword = 0;
1373 if (GET_CODE (operand1) == SUBREG)
1375 op1_subword = SUBREG_WORD (operand1);
1376 operand1 = XEXP (operand1, 0);
1379 emit_insn (gen_ashlsi3 (temp, gen_rtx (SUBREG, SImode, operand1,
1382 emit_insn (gen_lshrsi3 (operand0, temp, shift_16));
1387 [(set (match_operand:SI 0 "register_operand" "=r")
1388 (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
1391 [(set_attr "type" "load")])
1393 (define_expand "zero_extendqihi2"
1394 [(set (match_operand:HI 0 "register_operand" "")
1395 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
1400 [(set (match_operand:HI 0 "register_operand" "=r,r")
1401 (zero_extend:HI (match_operand:QI 1 "sparc_operand" "r,Q")))]
1402 "GET_CODE (operands[1]) != CONST_INT"
1406 [(set_attr "type" "unary,load")
1407 (set_attr "length" "1")])
1409 (define_expand "zero_extendqisi2"
1410 [(set (match_operand:SI 0 "register_operand" "")
1411 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
1416 [(set (match_operand:SI 0 "register_operand" "=r,r")
1417 (zero_extend:SI (match_operand:QI 1 "sparc_operand" "r,Q")))]
1418 "GET_CODE (operands[1]) != CONST_INT"
1422 [(set_attr "type" "unary,load")
1423 (set_attr "length" "1")])
1427 (compare:CC (zero_extend:SI (match_operand:QI 0 "register_operand" "r"))
1430 "andcc %0,0xff,%%g0"
1431 [(set_attr "type" "compare")])
1435 (compare:CC (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
1437 (set (match_operand:SI 0 "register_operand" "=r")
1438 (zero_extend:SI (match_dup 1)))]
1441 [(set_attr "type" "unary")])
1443 ;; Similarly, handle SI->QI mode truncation followed by a compare.
1447 (compare:CC (subreg:QI (match_operand:SI 0 "register_operand" "r") 0)
1450 "andcc %0,0xff,%%g0"
1451 [(set_attr "type" "compare")])
1455 (compare:CC (subreg:QI (match_operand:SI 1 "register_operand" "r") 0)
1457 (set (match_operand:QI 0 "register_operand" "=r")
1461 [(set_attr "type" "unary")])
1463 ;;- sign extension instructions
1465 ;; These patterns originally accepted general_operands, however, slightly
1466 ;; better code is generated by only accepting register_operands, and then
1467 ;; letting combine generate the lds[hb] insns.
1469 (define_expand "extendhisi2"
1470 [(set (match_operand:SI 0 "register_operand" "")
1471 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
1475 rtx temp = gen_reg_rtx (SImode);
1476 rtx shift_16 = gen_rtx (CONST_INT, VOIDmode, 16);
1477 int op1_subword = 0;
1479 if (GET_CODE (operand1) == SUBREG)
1481 op1_subword = SUBREG_WORD (operand1);
1482 operand1 = XEXP (operand1, 0);
1485 emit_insn (gen_ashlsi3 (temp, gen_rtx (SUBREG, SImode, operand1,
1488 emit_insn (gen_ashrsi3 (operand0, temp, shift_16));
1493 [(set (match_operand:SI 0 "register_operand" "=r")
1494 (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
1497 [(set_attr "type" "load")])
1499 (define_expand "extendqihi2"
1500 [(set (match_operand:HI 0 "register_operand" "")
1501 (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
1505 rtx temp = gen_reg_rtx (SImode);
1506 rtx shift_24 = gen_rtx (CONST_INT, VOIDmode, 24);
1507 int op1_subword = 0;
1508 int op0_subword = 0;
1510 if (GET_CODE (operand1) == SUBREG)
1512 op1_subword = SUBREG_WORD (operand1);
1513 operand1 = XEXP (operand1, 0);
1515 if (GET_CODE (operand0) == SUBREG)
1517 op0_subword = SUBREG_WORD (operand0);
1518 operand0 = XEXP (operand0, 0);
1520 emit_insn (gen_ashlsi3 (temp, gen_rtx (SUBREG, SImode, operand1,
1523 if (GET_MODE (operand0) != SImode)
1524 operand0 = gen_rtx (SUBREG, SImode, operand0, op0_subword);
1525 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
1530 [(set (match_operand:HI 0 "register_operand" "=r")
1531 (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
1534 [(set_attr "type" "load")])
1536 (define_expand "extendqisi2"
1537 [(set (match_operand:SI 0 "register_operand" "")
1538 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
1542 rtx temp = gen_reg_rtx (SImode);
1543 rtx shift_24 = gen_rtx (CONST_INT, VOIDmode, 24);
1544 int op1_subword = 0;
1546 if (GET_CODE (operand1) == SUBREG)
1548 op1_subword = SUBREG_WORD (operand1);
1549 operand1 = XEXP (operand1, 0);
1552 emit_insn (gen_ashlsi3 (temp, gen_rtx (SUBREG, SImode, operand1,
1555 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
1560 [(set (match_operand:SI 0 "register_operand" "=r")
1561 (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
1564 [(set_attr "type" "load")])
1566 ;; Special pattern for optimizing bit-field compares. This is needed
1567 ;; because combine uses this as a canonical form.
1572 (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
1573 (match_operand:SI 1 "small_int" "n")
1574 (match_operand:SI 2 "small_int" "n"))
1576 "INTVAL (operands[2]) > 19"
1579 int len = INTVAL (operands[1]);
1580 int pos = 32 - INTVAL (operands[2]) - len;
1581 unsigned mask = ((1 << len) - 1) << pos;
1583 operands[1] = gen_rtx (CONST_INT, VOIDmode, mask);
1584 return \"andcc %0,%1,%%g0\";
1587 ;; Conversions between float, double and long double.
1589 (define_insn "extendsfdf2"
1590 [(set (match_operand:DF 0 "register_operand" "=f")
1592 (match_operand:SF 1 "register_operand" "f")))]
1595 [(set_attr "type" "fp")])
1597 (define_insn "extendsftf2"
1598 [(set (match_operand:TF 0 "register_operand" "=f")
1600 (match_operand:SF 1 "register_operand" "f")))]
1603 [(set_attr "type" "fp")])
1605 (define_insn "extenddftf2"
1606 [(set (match_operand:TF 0 "register_operand" "=f")
1608 (match_operand:DF 1 "register_operand" "f")))]
1611 [(set_attr "type" "fp")])
1613 (define_insn "truncdfsf2"
1614 [(set (match_operand:SF 0 "register_operand" "=f")
1616 (match_operand:DF 1 "register_operand" "f")))]
1619 [(set_attr "type" "fp")])
1621 (define_insn "trunctfsf2"
1622 [(set (match_operand:SF 0 "register_operand" "=f")
1624 (match_operand:TF 1 "register_operand" "f")))]
1627 [(set_attr "type" "fp")])
1629 (define_insn "trunctfdf2"
1630 [(set (match_operand:DF 0 "register_operand" "=f")
1632 (match_operand:TF 1 "register_operand" "f")))]
1635 [(set_attr "type" "fp")])
1637 ;; Conversion between fixed point and floating point.
1639 (define_insn "floatsisf2"
1640 [(set (match_operand:SF 0 "register_operand" "=f")
1641 (float:SF (match_operand:SI 1 "register_operand" "f")))]
1644 [(set_attr "type" "fp")])
1646 (define_insn "floatsidf2"
1647 [(set (match_operand:DF 0 "register_operand" "=f")
1648 (float:DF (match_operand:SI 1 "register_operand" "f")))]
1651 [(set_attr "type" "fp")])
1653 (define_insn "floatsitf2"
1654 [(set (match_operand:TF 0 "register_operand" "=f")
1655 (float:TF (match_operand:SI 1 "register_operand" "f")))]
1658 [(set_attr "type" "fp")])
1660 ;; Convert a float to an actual integer.
1661 ;; Truncation is performed as part of the conversion.
1663 (define_insn "fix_truncsfsi2"
1664 [(set (match_operand:SI 0 "register_operand" "=f")
1665 (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
1668 [(set_attr "type" "fp")])
1670 (define_insn "fix_truncdfsi2"
1671 [(set (match_operand:SI 0 "register_operand" "=f")
1672 (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "f"))))]
1675 [(set_attr "type" "fp")])
1677 (define_insn "fix_trunctfsi2"
1678 [(set (match_operand:SI 0 "register_operand" "=f")
1679 (fix:SI (fix:TF (match_operand:TF 1 "register_operand" "f"))))]
1682 [(set_attr "type" "fp")])
1684 ;;- arithmetic instructions
1686 (define_insn "adddi3"
1687 [(set (match_operand:DI 0 "register_operand" "=r")
1688 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
1689 (match_operand:DI 2 "arith_double_operand" "rHI")))
1690 (clobber (reg:SI 0))]
1694 rtx op2 = operands[2];
1696 /* If constant is positive, upper bits zeroed, otherwise unchanged.
1697 Give the assembler a chance to pick the move instruction. */
1698 if (GET_CODE (op2) == CONST_INT)
1700 int sign = INTVAL (op2);
1702 return \"addcc %R1,%2,%R0\;addx %1,-1,%0\";
1703 return \"addcc %R1,%2,%R0\;addx %1,0,%0\";
1705 else if (GET_CODE (op2) == CONST_DOUBLE)
1707 int sign = CONST_DOUBLE_HIGH (op2);
1708 operands[2] = gen_rtx (CONST_INT, VOIDmode,
1709 CONST_DOUBLE_LOW (operands[1]));
1711 return \"addcc %R1,%2,%R0\;addx %1,-1,%0\";
1712 return \"addcc %R1,%2,%R0\;addx %1,0,%0\";
1714 return \"addcc %R1,%R2,%R0\;addx %1,%2,%0\";
1716 [(set_attr "length" "2")])
1718 (define_insn "addsi3"
1719 [(set (match_operand:SI 0 "register_operand" "=r")
1720 (plus:SI (match_operand:SI 1 "arith_operand" "%r")
1721 (match_operand:SI 2 "arith_operand" "rI")))]
1726 [(set (reg:CC_NOOV 0)
1727 (compare:CC_NOOV (plus:SI (match_operand:SI 0 "arith_operand" "%r")
1728 (match_operand:SI 1 "arith_operand" "rI"))
1732 [(set_attr "type" "compare")])
1735 [(set (reg:CC_NOOV 0)
1736 (compare:CC_NOOV (plus:SI (match_operand:SI 1 "arith_operand" "%r")
1737 (match_operand:SI 2 "arith_operand" "rI"))
1739 (set (match_operand:SI 0 "register_operand" "=r")
1740 (plus:SI (match_dup 1) (match_dup 2)))]
1744 (define_insn "subdi3"
1745 [(set (match_operand:DI 0 "register_operand" "=r")
1746 (minus:DI (match_operand:DI 1 "register_operand" "r")
1747 (match_operand:DI 2 "arith_double_operand" "rHI")))
1748 (clobber (reg:SI 0))]
1752 rtx op2 = operands[2];
1754 /* If constant is positive, upper bits zeroed, otherwise unchanged.
1755 Give the assembler a chance to pick the move instruction. */
1756 if (GET_CODE (op2) == CONST_INT)
1758 int sign = INTVAL (op2);
1760 return \"subcc %R1,%2,%R0\;subx %1,-1,%0\";
1761 return \"subcc %R1,%2,%R0\;subx %1,0,%0\";
1763 else if (GET_CODE (op2) == CONST_DOUBLE)
1765 int sign = CONST_DOUBLE_HIGH (op2);
1766 operands[2] = gen_rtx (CONST_INT, VOIDmode,
1767 CONST_DOUBLE_LOW (operands[1]));
1769 return \"subcc %R1,%2,%R0\;subx %1,-1,%0\";
1770 return \"subcc %R1,%2,%R0\;subx %1,0,%0\";
1772 return \"subcc %R1,%R2,%R0\;subx %1,%2,%0\";
1774 [(set_attr "length" "2")])
1776 (define_insn "subsi3"
1777 [(set (match_operand:SI 0 "register_operand" "=r")
1778 (minus:SI (match_operand:SI 1 "register_operand" "r")
1779 (match_operand:SI 2 "arith_operand" "rI")))]
1784 [(set (reg:CC_NOOV 0)
1785 (compare:CC_NOOV (minus:SI (match_operand:SI 0 "register_operand" "r")
1786 (match_operand:SI 1 "arith_operand" "rI"))
1790 [(set_attr "type" "compare")])
1793 [(set (reg:CC_NOOV 0)
1794 (compare:CC_NOOV (minus:SI (match_operand:SI 1 "register_operand" "r")
1795 (match_operand:SI 2 "arith_operand" "rI"))
1797 (set (match_operand:SI 0 "register_operand" "=r")
1798 (minus:SI (match_dup 1) (match_dup 2)))]
1802 (define_insn "mulsi3"
1803 [(set (match_operand:SI 0 "register_operand" "=r")
1804 (mult:SI (match_operand:SI 1 "arith_operand" "%r")
1805 (match_operand:SI 2 "arith_operand" "rI")))]
1806 "TARGET_V8 || TARGET_SPARCLITE"
1809 ;; It is not known whether this will match.
1812 [(set (match_operand:SI 0 "register_operand" "=r")
1813 (mult:SI (match_operand:SI 1 "arith_operand" "%r")
1814 (match_operand:SI 2 "arith_operand" "rI")))
1815 (set (reg:CC_NOOV 0)
1816 (compare:CC_NOOV (mult:SI (match_dup 1) (match_dup 2))
1818 "TARGET_V8 || TARGET_SPARCLITE"
1821 (define_expand "mulsidi3"
1822 [(set (match_operand:DI 0 "register_operand" "")
1823 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
1824 (sign_extend:DI (match_operand:SI 2 "arith_operand" ""))))]
1825 "TARGET_V8 || TARGET_SPARCLITE"
1828 if (CONSTANT_P (operands[2]))
1830 emit_insn (gen_const_mulsidi3 (operands[0], operands[1], operands[2]));
1836 [(set (match_operand:DI 0 "register_operand" "=r")
1837 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
1838 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
1839 "TARGET_V8 || TARGET_SPARCLITE"
1840 "smul %1,%2,%R0\;rd %%y,%0"
1841 [(set_attr "length" "2")])
1843 ;; Extra pattern, because sign_extend of a constant isn't legal.
1845 (define_insn "const_mulsidi3"
1846 [(set (match_operand:DI 0 "register_operand" "=r")
1847 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
1848 (match_operand:SI 2 "small_int" "I")))]
1849 "TARGET_V8 || TARGET_SPARCLITE"
1850 "smul %1,%2,%R0\;rd %%y,%0"
1851 [(set_attr "length" "2")])
1853 (define_expand "umulsidi3"
1854 [(set (match_operand:DI 0 "register_operand" "")
1855 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
1856 (zero_extend:DI (match_operand:SI 2 "arith_operand" ""))))]
1857 "TARGET_V8 || TARGET_SPARCLITE"
1860 if (CONSTANT_P (operands[2]))
1862 emit_insn (gen_const_umulsidi3 (operands[0], operands[1], operands[2]));
1868 [(set (match_operand:DI 0 "register_operand" "=r")
1869 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
1870 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
1871 "TARGET_V8 || TARGET_SPARCLITE"
1872 "umul %1,%2,%R0\;rd %%y,%0"
1873 [(set_attr "length" "2")])
1875 ;; Extra pattern, because sign_extend of a constant isn't legal.
1877 (define_insn "const_umulsidi3"
1878 [(set (match_operand:DI 0 "register_operand" "=r")
1879 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
1880 (match_operand:SI 2 "small_int" "I")))]
1881 "TARGET_V8 || TARGET_SPARCLITE"
1882 "umul %1,%2,%R0\;rd %%y,%0"
1883 [(set_attr "length" "2")])
1885 ;; The architecture specifies that there must be 3 instructions between
1886 ;; a y register write and a use of it for correct results.
1888 (define_insn "divsi3"
1889 [(set (match_operand:SI 0 "register_operand" "=r")
1890 (div:SI (match_operand:SI 1 "register_operand" "r")
1891 (match_operand:SI 2 "arith_operand" "rI")))
1892 (clobber (match_scratch:SI 3 "=&r"))]
1894 "sra %1,31,%3\;wr %%g0,%3,%%y\;nop\;nop\;nop\;sdiv %1,%2,%0"
1895 [(set_attr "length" "6")])
1897 ;; It is not known whether this will match.
1900 [(set (match_operand:SI 0 "register_operand" "=r")
1901 (div:SI (match_operand:SI 1 "register_operand" "r")
1902 (match_operand:SI 2 "arith_operand" "rI")))
1904 (compare:CC (div:SI (match_dup 1) (match_dup 2))
1906 (clobber (match_scratch:SI 3 "=&r"))]
1908 "sra %1,31,%3\;wr %%g0,%3,%%y\;nop\;nop\;nop\;sdivcc %1,%2,%0"
1909 [(set_attr "length" "6")])
1911 (define_insn "udivsi3"
1912 [(set (match_operand:SI 0 "register_operand" "=r")
1913 (udiv:SI (match_operand:SI 1 "register_operand" "r")
1914 (match_operand:SI 2 "arith_operand" "rI")))]
1916 "wr %%g0,%%g0,%%y\;nop\;nop\;nop\;udiv %1,%2,%0"
1917 [(set_attr "length" "5")])
1919 ;; It is not known whether this will match.
1922 [(set (match_operand:SI 0 "register_operand" "=r")
1923 (udiv:SI (match_operand:SI 1 "register_operand" "r")
1924 (match_operand:SI 2 "arith_operand" "rI")))
1926 (compare:CC (udiv:SI (match_dup 1) (match_dup 2))
1929 "wr %%g0,%%g0,%%y\;nop\;nop\;nop\;udivcc %1,%2,%0"
1930 [(set_attr "length" "5")])
1932 ;;- and instructions
1933 ;; We define DImode `and` so with DImode `not` we can get
1934 ;; DImode `andn`. Other combinations are possible.
1936 (define_expand "anddi3"
1937 [(set (match_operand:DI 0 "register_operand" "")
1938 (and:DI (match_operand:DI 1 "arith_double_operand" "")
1939 (match_operand:DI 2 "arith_double_operand" "")))]
1944 [(set (match_operand:DI 0 "register_operand" "=r")
1945 (and:DI (match_operand:DI 1 "arith_double_operand" "%r")
1946 (match_operand:DI 2 "arith_double_operand" "rHI")))]
1950 rtx op2 = operands[2];
1952 /* If constant is positive, upper bits zeroed, otherwise unchanged.
1953 Give the assembler a chance to pick the move instruction. */
1954 if (GET_CODE (op2) == CONST_INT)
1956 int sign = INTVAL (op2);
1958 return \"mov %1,%0\;and %R1,%2,%R0\";
1959 return \"mov 0,%0\;and %R1,%2,%R0\";
1961 else if (GET_CODE (op2) == CONST_DOUBLE)
1963 int sign = CONST_DOUBLE_HIGH (op2);
1964 operands[2] = gen_rtx (CONST_INT, VOIDmode,
1965 CONST_DOUBLE_LOW (operands[1]));
1967 return \"mov %1,%0\;and %R1,%2,%R0\";
1968 return \"mov 0,%0\;and %R1,%2,%R0\";
1970 return \"and %1,%2,%0\;and %R1,%R2,%R0\";
1972 [(set_attr "length" "2")])
1974 (define_insn "andsi3"
1975 [(set (match_operand:SI 0 "register_operand" "=r")
1976 (and:SI (match_operand:SI 1 "arith_operand" "%r")
1977 (match_operand:SI 2 "arith_operand" "rI")))]
1982 [(set (match_operand:SI 0 "register_operand" "")
1983 (and:SI (match_operand:SI 1 "register_operand" "")
1984 (match_operand:SI 2 "" "")))
1985 (clobber (match_operand:SI 3 "register_operand" ""))]
1986 "GET_CODE (operands[2]) == CONST_INT
1987 && !SMALL_INT (operands[2])
1988 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
1989 [(set (match_dup 3) (match_dup 4))
1990 (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 1)))]
1993 operands[4] = gen_rtx (CONST_INT, VOIDmode, ~INTVAL (operands[2]));
1997 [(set (match_operand:DI 0 "register_operand" "=r")
1998 (and:DI (not:DI (match_operand:DI 1 "register_operand" "r"))
1999 (match_operand:DI 2 "register_operand" "r")))]
2001 "andn %2,%1,%0\;andn %R2,%R1,%R0"
2002 [(set_attr "length" "2")])
2005 [(set (match_operand:SI 0 "register_operand" "=r")
2006 (and:SI (not:SI (match_operand:SI 1 "register_operand" "r"))
2007 (match_operand:SI 2 "register_operand" "r")))]
2011 (define_expand "iordi3"
2012 [(set (match_operand:DI 0 "register_operand" "")
2013 (ior:DI (match_operand:DI 1 "arith_double_operand" "")
2014 (match_operand:DI 2 "arith_double_operand" "")))]
2019 [(set (match_operand:DI 0 "register_operand" "=r")
2020 (ior:DI (match_operand:DI 1 "arith_double_operand" "%r")
2021 (match_operand:DI 2 "arith_double_operand" "rHI")))]
2025 rtx op2 = operands[2];
2027 /* If constant is positive, upper bits zeroed, otherwise unchanged.
2028 Give the assembler a chance to pick the move instruction. */
2029 if (GET_CODE (op2) == CONST_INT)
2031 int sign = INTVAL (op2);
2033 return \"mov -1,%0\;or %R1,%2,%R0\";
2034 return \"mov %1,%0\;or %R1,%2,%R0\";
2036 else if (GET_CODE (op2) == CONST_DOUBLE)
2038 int sign = CONST_DOUBLE_HIGH (op2);
2039 operands[2] = gen_rtx (CONST_INT, VOIDmode,
2040 CONST_DOUBLE_LOW (operands[1]));
2042 return \"mov -1,%0\;or %R1,%2,%R0\";
2043 return \"mov %1,%0\;or %R1,%2,%R0\";
2045 return \"or %1,%2,%0\;or %R1,%R2,%R0\";
2047 [(set_attr "length" "2")])
2049 (define_insn "iorsi3"
2050 [(set (match_operand:SI 0 "register_operand" "=r")
2051 (ior:SI (match_operand:SI 1 "arith_operand" "%r")
2052 (match_operand:SI 2 "arith_operand" "rI")))]
2057 [(set (match_operand:SI 0 "register_operand" "")
2058 (ior:SI (match_operand:SI 1 "register_operand" "")
2059 (match_operand:SI 2 "" "")))
2060 (clobber (match_operand:SI 3 "register_operand" ""))]
2061 "GET_CODE (operands[2]) == CONST_INT
2062 && !SMALL_INT (operands[2])
2063 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
2064 [(set (match_dup 3) (match_dup 4))
2065 (set (match_dup 0) (ior:SI (not:SI (match_dup 3)) (match_dup 1)))]
2068 operands[4] = gen_rtx (CONST_INT, VOIDmode, ~INTVAL (operands[2]));
2072 [(set (match_operand:DI 0 "register_operand" "=r")
2073 (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r"))
2074 (match_operand:DI 2 "register_operand" "r")))]
2076 "orn %2,%1,%0\;orn %R2,%R1,%R0"
2077 [(set_attr "length" "2")])
2080 [(set (match_operand:SI 0 "register_operand" "=r")
2081 (ior:SI (not:SI (match_operand:SI 1 "register_operand" "r"))
2082 (match_operand:SI 2 "register_operand" "r")))]
2086 (define_expand "xordi3"
2087 [(set (match_operand:DI 0 "register_operand" "")
2088 (xor:DI (match_operand:DI 1 "arith_double_operand" "")
2089 (match_operand:DI 2 "arith_double_operand" "")))]
2094 [(set (match_operand:DI 0 "register_operand" "=r")
2095 (xor:DI (match_operand:DI 1 "arith_double_operand" "%r")
2096 (match_operand:DI 2 "arith_double_operand" "rHI")))]
2100 rtx op2 = operands[2];
2102 /* If constant is positive, upper bits zeroed, otherwise unchanged.
2103 Give the assembler a chance to pick the move instruction. */
2104 if (GET_CODE (op2) == CONST_INT)
2106 int sign = INTVAL (op2);
2108 return \"xor %1,-1,%0\;xor %R1,%2,%R0\";
2109 return \"mov %1,%0\;xor %R1,%2,%R0\";
2111 else if (GET_CODE (op2) == CONST_DOUBLE)
2113 int sign = CONST_DOUBLE_HIGH (op2);
2114 operands[2] = gen_rtx (CONST_INT, VOIDmode,
2115 CONST_DOUBLE_LOW (operands[1]));
2117 return \"xor %1,-1,%0\;xor %R1,%2,%R0\";
2118 return \"mov %1,%0\;xor %R1,%2,%R0\";
2120 return \"xor %1,%2,%0\;xor %R1,%R2,%R0\";
2122 [(set_attr "length" "2")])
2124 (define_insn "xorsi3"
2125 [(set (match_operand:SI 0 "register_operand" "=r")
2126 (xor:SI (match_operand:SI 1 "arith_operand" "%rJ")
2127 (match_operand:SI 2 "arith_operand" "rI")))]
2132 [(set (match_operand:SI 0 "register_operand" "")
2133 (xor:SI (match_operand:SI 1 "register_operand" "")
2134 (match_operand:SI 2 "" "")))
2135 (clobber (match_operand:SI 3 "register_operand" ""))]
2136 "GET_CODE (operands[2]) == CONST_INT
2137 && !SMALL_INT (operands[2])
2138 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
2139 [(set (match_dup 3) (match_dup 4))
2140 (set (match_dup 0) (not:SI (xor:SI (match_dup 3) (match_dup 1))))]
2143 operands[4] = gen_rtx (CONST_INT, VOIDmode, ~INTVAL (operands[2]));
2147 [(set (match_operand:SI 0 "register_operand" "")
2148 (not:SI (xor:SI (match_operand:SI 1 "register_operand" "")
2149 (match_operand:SI 2 "" ""))))
2150 (clobber (match_operand:SI 3 "register_operand" ""))]
2151 "GET_CODE (operands[2]) == CONST_INT
2152 && !SMALL_INT (operands[2])
2153 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
2154 [(set (match_dup 3) (match_dup 4))
2155 (set (match_dup 0) (xor:SI (match_dup 3) (match_dup 1)))]
2158 operands[4] = gen_rtx (CONST_INT, VOIDmode, ~INTVAL (operands[2]));
2161 ;; xnor patterns. Note that (a ^ ~b) == (~a ^ b) == ~(a ^ b).
2162 ;; Combine now canonicalizes to the rightmost expression.
2164 [(set (match_operand:DI 0 "register_operand" "=r")
2165 (not:DI (xor:DI (match_operand:DI 1 "register_operand" "r")
2166 (match_operand:DI 2 "register_operand" "r"))))]
2168 "xnor %1,%2,%0\;xnor %R1,%R2,%R0"
2169 [(set_attr "length" "2")])
2172 [(set (match_operand:SI 0 "register_operand" "=r")
2173 (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
2174 (match_operand:SI 2 "arith_operand" "rI"))))]
2178 ;; These correspond to the above in the case where we also (or only)
2179 ;; want to set the condition code.
2184 (match_operator:SI 2 "cc_arithop"
2185 [(match_operand:SI 0 "arith_operand" "%r")
2186 (match_operand:SI 1 "arith_operand" "rI")])
2190 [(set_attr "type" "compare")])
2195 (match_operator:SI 3 "cc_arithop"
2196 [(match_operand:SI 1 "arith_operand" "%r")
2197 (match_operand:SI 2 "arith_operand" "rI")])
2199 (set (match_operand:SI 0 "register_operand" "=r")
2207 (not:SI (xor:SI (match_operand:SI 0 "reg_or_0_operand" "%rJ")
2208 (match_operand:SI 1 "arith_operand" "rI")))
2211 "xnorcc %r0,%1,%%g0"
2212 [(set_attr "type" "compare")])
2217 (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
2218 (match_operand:SI 2 "arith_operand" "rI")))
2220 (set (match_operand:SI 0 "register_operand" "=r")
2221 (not:SI (xor:SI (match_dup 1) (match_dup 2))))]
2228 (match_operator:SI 2 "cc_arithopn"
2229 [(not:SI (match_operand:SI 0 "arith_operand" "rI"))
2230 (match_operand:SI 1 "reg_or_0_operand" "rJ")])
2234 [(set_attr "type" "compare")])
2239 (match_operator:SI 3 "cc_arithopn"
2240 [(not:SI (match_operand:SI 1 "arith_operand" "rI"))
2241 (match_operand:SI 2 "reg_or_0_operand" "rJ")])
2243 (set (match_operand:SI 0 "register_operand" "=r")
2248 ;; We cannot use the "neg" pseudo insn because the Sun assembler
2249 ;; does not know how to make it work for constants.
2251 (define_insn "negdi2"
2252 [(set (match_operand:DI 0 "register_operand" "=r")
2253 (neg:DI (match_operand:DI 1 "register_operand" "r")))
2254 (clobber (reg:SI 0))]
2256 "subcc %%g0,%R1,%R0\;subx %%g0,%1,%0"
2257 [(set_attr "type" "unary")
2258 (set_attr "length" "2")])
2260 (define_insn "negsi2"
2261 [(set (match_operand:SI 0 "general_operand" "=r")
2262 (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
2265 [(set_attr "type" "unary")])
2268 [(set (reg:CC_NOOV 0)
2269 (compare:CC_NOOV (neg:SI (match_operand:SI 0 "arith_operand" "rI"))
2272 "subcc %%g0,%0,%%g0"
2273 [(set_attr "type" "compare")])
2276 [(set (reg:CC_NOOV 0)
2277 (compare:CC_NOOV (neg:SI (match_operand:SI 1 "arith_operand" "rI"))
2279 (set (match_operand:SI 0 "register_operand" "=r")
2280 (neg:SI (match_dup 1)))]
2283 [(set_attr "type" "unary")])
2285 ;; We cannot use the "not" pseudo insn because the Sun assembler
2286 ;; does not know how to make it work for constants.
2287 (define_expand "one_cmpldi2"
2288 [(set (match_operand:DI 0 "register_operand" "=r")
2289 (not:DI (match_operand:DI 1 "arith_double_operand" "rHI")))]
2294 [(set (match_operand:DI 0 "register_operand" "=r")
2295 (not:DI (match_operand:DI 1 "arith_double_operand" "rHI")))]
2299 rtx op1 = operands[1];
2301 if (GET_CODE (op1) == CONST_INT)
2303 int sign = INTVAL (op1);
2305 return \"xnor %%g0,%1,%R0\;xnor %%g0,-1,%0\";
2306 return \"xnor %%g0,%1,%R0\;xnor %%g0,0,%0\";
2308 else if (GET_CODE (op1) == CONST_DOUBLE)
2310 int sign = CONST_DOUBLE_HIGH (op1);
2311 operands[1] = gen_rtx (CONST_INT, VOIDmode,
2312 CONST_DOUBLE_LOW (operands[1]));
2314 return \"xnor %%g0,%1,%R0\;xnor %%g0,-1,%0\";
2315 return \"xnor %%g0,%1,%R0\;xnor %%g0,0,%0\";
2317 return \"xnor %%g0,%1,%0\;xnor %%g0,%R1,%R0\";
2319 [(set_attr "type" "unary")
2320 (set_attr "length" "2")])
2322 (define_insn "one_cmplsi2"
2323 [(set (match_operand:SI 0 "register_operand" "=r")
2324 (not:SI (match_operand:SI 1 "arith_operand" "rI")))]
2327 [(set_attr "type" "unary")])
2331 (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI"))
2334 "xnorcc %%g0,%0,%%g0"
2335 [(set_attr "type" "compare")])
2339 (compare:CC (not:SI (match_operand:SI 1 "arith_operand" "rI"))
2341 (set (match_operand:SI 0 "register_operand" "=r")
2342 (not:SI (match_dup 1)))]
2345 [(set_attr "type" "unary")])
2347 ;; Floating point arithmetic instructions.
2349 (define_insn "addtf3"
2350 [(set (match_operand:TF 0 "register_operand" "=f")
2351 (plus:TF (match_operand:TF 1 "register_operand" "f")
2352 (match_operand:TF 2 "register_operand" "f")))]
2355 [(set_attr "type" "fp")])
2357 (define_insn "adddf3"
2358 [(set (match_operand:DF 0 "register_operand" "=f")
2359 (plus:DF (match_operand:DF 1 "register_operand" "f")
2360 (match_operand:DF 2 "register_operand" "f")))]
2363 [(set_attr "type" "fp")])
2365 (define_insn "addsf3"
2366 [(set (match_operand:SF 0 "register_operand" "=f")
2367 (plus:SF (match_operand:SF 1 "register_operand" "f")
2368 (match_operand:SF 2 "register_operand" "f")))]
2371 [(set_attr "type" "fp")])
2373 (define_insn "subtf3"
2374 [(set (match_operand:TF 0 "register_operand" "=f")
2375 (minus:TF (match_operand:TF 1 "register_operand" "f")
2376 (match_operand:TF 2 "register_operand" "f")))]
2379 [(set_attr "type" "fp")])
2381 (define_insn "subdf3"
2382 [(set (match_operand:DF 0 "register_operand" "=f")
2383 (minus:DF (match_operand:DF 1 "register_operand" "f")
2384 (match_operand:DF 2 "register_operand" "f")))]
2387 [(set_attr "type" "fp")])
2389 (define_insn "subsf3"
2390 [(set (match_operand:SF 0 "register_operand" "=f")
2391 (minus:SF (match_operand:SF 1 "register_operand" "f")
2392 (match_operand:SF 2 "register_operand" "f")))]
2395 [(set_attr "type" "fp")])
2397 (define_insn "multf3"
2398 [(set (match_operand:TF 0 "register_operand" "=f")
2399 (mult:TF (match_operand:TF 1 "register_operand" "f")
2400 (match_operand:TF 2 "register_operand" "f")))]
2403 [(set_attr "type" "fpmul")])
2405 (define_insn "muldf3"
2406 [(set (match_operand:DF 0 "register_operand" "=f")
2407 (mult:DF (match_operand:DF 1 "register_operand" "f")
2408 (match_operand:DF 2 "register_operand" "f")))]
2411 [(set_attr "type" "fpmul")])
2413 (define_insn "mulsf3"
2414 [(set (match_operand:SF 0 "register_operand" "=f")
2415 (mult:SF (match_operand:SF 1 "register_operand" "f")
2416 (match_operand:SF 2 "register_operand" "f")))]
2419 [(set_attr "type" "fpmul")])
2422 [(set (match_operand:DF 0 "register_operand" "=f")
2423 (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "f"))
2424 (float_extend:DF (match_operand:SF 2 "register_operand" "f"))))]
2425 "TARGET_V8 && TARGET_FPU"
2427 [(set_attr "type" "fpmul")])
2430 [(set (match_operand:TF 0 "register_operand" "=f")
2431 (mult:TF (float_extend:TF (match_operand:DF 1 "register_operand" "f"))
2432 (float_extend:TF (match_operand:DF 2 "register_operand" "f"))))]
2433 "TARGET_V8 && TARGET_FPU"
2435 [(set_attr "type" "fpmul")])
2437 (define_insn "divtf3"
2438 [(set (match_operand:TF 0 "register_operand" "=f")
2439 (div:TF (match_operand:TF 1 "register_operand" "f")
2440 (match_operand:TF 2 "register_operand" "f")))]
2443 [(set_attr "type" "fpdiv")])
2445 (define_insn "divdf3"
2446 [(set (match_operand:DF 0 "register_operand" "=f")
2447 (div:DF (match_operand:DF 1 "register_operand" "f")
2448 (match_operand:DF 2 "register_operand" "f")))]
2451 [(set_attr "type" "fpdiv")])
2453 (define_insn "divsf3"
2454 [(set (match_operand:SF 0 "register_operand" "=f")
2455 (div:SF (match_operand:SF 1 "register_operand" "f")
2456 (match_operand:SF 2 "register_operand" "f")))]
2459 [(set_attr "type" "fpdiv")])
2461 (define_insn "negtf2"
2462 [(set (match_operand:TF 0 "register_operand" "=f,f")
2463 (neg:TF (match_operand:TF 1 "register_operand" "0,f")))]
2467 fnegs %1,%0\;fmovs %R1,%R0\;fmovs %S1,%S0\;fmovs %T1,%T0"
2468 [(set_attr "type" "fp")
2469 (set_attr "length" "1,4")])
2471 (define_insn "negdf2"
2472 [(set (match_operand:DF 0 "register_operand" "=f,f")
2473 (neg:DF (match_operand:DF 1 "register_operand" "0,f")))]
2477 fnegs %1,%0\;fmovs %R1,%R0"
2478 [(set_attr "type" "fp")
2479 (set_attr "length" "1,2")])
2481 (define_insn "negsf2"
2482 [(set (match_operand:SF 0 "register_operand" "=f")
2483 (neg:SF (match_operand:SF 1 "register_operand" "f")))]
2486 [(set_attr "type" "fp")])
2488 (define_insn "abstf2"
2489 [(set (match_operand:TF 0 "register_operand" "=f,f")
2490 (abs:TF (match_operand:TF 1 "register_operand" "0,f")))]
2494 fabss %1,%0\;fmovs %R1,%R0\;fmovs %S1,%S0\;fmovs %T1,%T0"
2495 [(set_attr "type" "fp")
2496 (set_attr "length" "1,4")])
2498 (define_insn "absdf2"
2499 [(set (match_operand:DF 0 "register_operand" "=f,f")
2500 (abs:DF (match_operand:DF 1 "register_operand" "0,f")))]
2504 fabss %1,%0\;fmovs %R1,%R0"
2505 [(set_attr "type" "fp")
2506 (set_attr "length" "1,2")])
2508 (define_insn "abssf2"
2509 [(set (match_operand:SF 0 "register_operand" "=f")
2510 (abs:SF (match_operand:SF 1 "register_operand" "f")))]
2513 [(set_attr "type" "fp")])
2515 (define_insn "sqrttf2"
2516 [(set (match_operand:TF 0 "register_operand" "=f")
2517 (sqrt:TF (match_operand:TF 1 "register_operand" "f")))]
2520 [(set_attr "type" "fpsqrt")])
2522 (define_insn "sqrtdf2"
2523 [(set (match_operand:DF 0 "register_operand" "=f")
2524 (sqrt:DF (match_operand:DF 1 "register_operand" "f")))]
2527 [(set_attr "type" "fpsqrt")])
2529 (define_insn "sqrtsf2"
2530 [(set (match_operand:SF 0 "register_operand" "=f")
2531 (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
2534 [(set_attr "type" "fpsqrt")])
2536 ;;- arithmetic shift instructions
2538 (define_insn "ashlsi3"
2539 [(set (match_operand:SI 0 "register_operand" "=r")
2540 (ashift:SI (match_operand:SI 1 "register_operand" "r")
2541 (match_operand:SI 2 "arith_operand" "rI")))]
2545 (define_expand "ashldi3"
2546 [(parallel [(set (match_operand:DI 0 "register_operand" "")
2547 (ashift:DI (match_operand:DI 1 "register_operand" "")
2548 (match_operand:DI 2 "const_int_operand" "")))
2549 (clobber (match_scratch:SI 3 ""))])]
2553 if (GET_CODE (operands[2]) != CONST_INT)
2558 [(set (match_operand:DI 0 "register_operand" "=r")
2559 (ashift:DI (match_operand:DI 1 "register_operand" "r")
2560 (match_operand:DI 2 "const_int_operand" "I")))
2561 (clobber (match_scratch:SI 3 "=r"))]
2562 "INTVAL (operands[2]) < 32"
2565 operands[4] = GEN_INT (32 - INTVAL (operands[2]));
2566 return \"srl %R1,%4,%3\;sll %R1,%2,%R0\;sll %1,%2,%0\;or %3,%0,%0\";
2568 [(set_attr "type" "multi")
2569 (set_attr "length" "4")])
2572 [(set (match_operand:DI 0 "register_operand" "=r")
2573 (lshift:DI (match_operand:DI 1 "register_operand" "r")
2574 (match_operand:DI 2 "const_int_operand" "I")))
2575 (clobber (match_scratch:SI 3 "=X"))]
2576 "INTVAL (operands[2]) >= 32"
2579 operands[4] = GEN_INT (INTVAL (operands[2]) - 32);
2580 return \"sll %R1,%4,%0\;mov %%g0,%R0\";
2582 [(set_attr "type" "multi")
2583 (set_attr "length" "2")])
2585 (define_insn "ashrsi3"
2586 [(set (match_operand:SI 0 "register_operand" "=r")
2587 (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
2588 (match_operand:SI 2 "arith_operand" "rI")))]
2592 (define_insn "lshrsi3"
2593 [(set (match_operand:SI 0 "register_operand" "=r")
2594 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
2595 (match_operand:SI 2 "arith_operand" "rI")))]
2599 (define_expand "lshrdi3"
2600 [(parallel [(set (match_operand:DI 0 "register_operand" "")
2601 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
2602 (match_operand:DI 2 "const_int_operand" "")))
2603 (clobber (match_scratch:SI 3 ""))])]
2607 if (GET_CODE (operands[2]) != CONST_INT)
2612 [(set (match_operand:DI 0 "register_operand" "=r")
2613 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
2614 (match_operand:DI 2 "const_int_operand" "I")))
2615 (clobber (match_scratch:SI 3 "=r"))]
2616 "INTVAL (operands[2]) < 32"
2619 operands[4] = GEN_INT (32 - INTVAL (operands[2]));
2620 return \"sll %1,%4,%3\;srl %1,%2,%0\;srl %R1,%2,%R0\;or %3,%R0,%R0\";
2622 [(set_attr "type" "multi")
2623 (set_attr "length" "4")])
2626 [(set (match_operand:DI 0 "register_operand" "=r")
2627 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
2628 (match_operand:DI 2 "const_int_operand" "I")))
2629 (clobber (match_scratch:SI 3 "=X"))]
2630 "INTVAL (operands[2]) >= 32"
2633 operands[4] = GEN_INT (INTVAL (operands[2]) - 32);
2634 return \"srl %1,%4,%R0\;mov %%g0,%0\";
2636 [(set_attr "type" "multi")
2637 (set_attr "length" "2")])
2639 ;; Unconditional and other jump instructions
2640 ;; On the Sparc, by setting the annul bit on an unconditional branch, the
2641 ;; following insn is never executed. This saves us a nop. Dbx does not
2642 ;; handle such branches though, so we only use them when optimizing.
2644 [(set (pc) (label_ref (match_operand 0 "" "")))]
2647 [(set_attr "type" "uncond_branch")])
2649 (define_expand "tablejump"
2650 [(parallel [(set (pc) (match_operand:SI 0 "register_operand" "r"))
2651 (use (label_ref (match_operand 1 "" "")))])]
2655 /* We need to use the PC value in %o7 that was set up when the address
2656 of the label was loaded into a register, so we need different RTL. */
2659 emit_insn (gen_pic_tablejump (operands[0], operands[1]));
2664 (define_insn "pic_tablejump"
2665 [(set (pc) (match_operand:SI 0 "register_operand" "r"))
2666 (use (label_ref (match_operand 1 "" "")))
2670 [(set_attr "type" "uncond_branch")])
2673 [(set (pc) (match_operand:SI 0 "address_operand" "p"))
2674 (use (label_ref (match_operand 1 "" "")))]
2677 [(set_attr "type" "uncond_branch")])
2680 [(set (pc) (label_ref (match_operand 0 "" "")))
2681 (set (reg:SI 15) (label_ref (match_dup 0)))]
2684 [(set_attr "type" "uncond_branch")])
2686 ;; This pattern recognizes the "instruction" that appears in
2687 ;; a function call that wants a structure value,
2688 ;; to inform the called function if compiled with Sun CC.
2690 ; [(match_operand:SI 0 "immediate_operand" "")]
2691 ; "GET_CODE (operands[0]) == CONST_INT && INTVAL (operands[0]) > 0"
2693 ; [(set_attr "type" "marker")])
2695 ;;- jump to subroutine
2696 (define_expand "call"
2697 ;; Note that this expression is not used for generating RTL.
2698 ;; All the RTL is generated explicitly below.
2699 [(call (match_operand:SI 0 "call_operand" "")
2700 (match_operand 3 "" "i"))]
2701 ;; operands[2] is next_arg_register
2702 ;; operands[3] is struct_value_size_rtx.
2706 rtx fn_rtx, nregs_rtx;
2708 if (GET_CODE (XEXP (operands[0], 0)) == LABEL_REF)
2710 /* This is really a PIC sequence. We want to represent
2711 it as a funny jump so it's delay slots can be filled.
2713 ??? But if this really *is* a CALL, will not it clobber the
2714 call-clobbered registers? We lose this if it is a JUMP_INSN.
2715 Why cannot we have delay slots filled if it were a CALL? */
2717 if (INTVAL (operands[3]) > 0)
2718 emit_jump_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (3,
2719 gen_rtx (SET, VOIDmode, pc_rtx,
2720 XEXP (operands[0], 0)),
2722 gen_rtx (CLOBBER, VOIDmode,
2723 gen_rtx (REG, SImode, 15)))));
2725 emit_jump_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (2,
2726 gen_rtx (SET, VOIDmode, pc_rtx,
2727 XEXP (operands[0], 0)),
2728 gen_rtx (CLOBBER, VOIDmode,
2729 gen_rtx (REG, SImode, 15)))));
2733 fn_rtx = operands[0];
2735 /* Count the number of parameter registers being used by this call.
2736 if that argument is NULL, it means we are using them all, which
2737 means 6 on the sparc. */
2740 nregs_rtx = gen_rtx (CONST_INT, VOIDmode, REGNO (operands[2]) - 8);
2742 nregs_rtx = gen_rtx (CONST_INT, VOIDmode, 6);
2744 nregs_rtx = const0_rtx;
2747 if (INTVAL (operands[3]) > 0)
2748 emit_call_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (3,
2749 gen_rtx (CALL, VOIDmode, fn_rtx, nregs_rtx),
2751 gen_rtx (CLOBBER, VOIDmode,
2752 gen_rtx (REG, SImode, 15)))));
2754 emit_call_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (2,
2755 gen_rtx (CALL, VOIDmode, fn_rtx, nregs_rtx),
2756 gen_rtx (CLOBBER, VOIDmode,
2757 gen_rtx (REG, SImode, 15)))));
2761 /* If this call wants a structure value,
2762 emit an unimp insn to let the called function know about this. */
2763 if (INTVAL (operands[3]) > 0)
2765 rtx insn = emit_insn (operands[3]);
2766 SCHED_GROUP_P (insn) = 1;
2774 [(call (mem:SI (match_operand:SI 0 "call_operand_address" "S,r"))
2775 (match_operand 1 "" ""))
2776 (clobber (reg:SI 15))]
2777 ;;- Do not use operand 1 for most machines.
2781 return \"call %a0,%1%#\";
2783 [(set_attr "type" "call")])
2785 ;; This is a call that wants a structure value.
2787 [(call (mem:SI (match_operand:SI 0 "call_operand_address" "S,r"))
2788 (match_operand 1 "" ""))
2789 (match_operand 2 "immediate_operand" "")
2790 (clobber (reg:SI 15))]
2791 ;;- Do not use operand 1 for most machines.
2792 "GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
2795 return \"call %a0,%1\;nop\;unimp %2\";
2797 [(set_attr "type" "call_no_delay_slot")])
2799 (define_expand "call_value"
2800 [(set (match_operand 0 "register_operand" "=rf")
2801 (call (match_operand:SI 1 "" "")
2802 (match_operand 4 "" "")))]
2803 ;; operand 3 is next_arg_register
2807 rtx fn_rtx, nregs_rtx;
2810 fn_rtx = operands[1];
2814 nregs_rtx = gen_rtx (CONST_INT, VOIDmode, REGNO (operands[3]) - 8);
2816 nregs_rtx = gen_rtx (CONST_INT, VOIDmode, 6);
2818 nregs_rtx = const0_rtx;
2822 gen_rtx (SET, VOIDmode, operands[0],
2823 gen_rtx (CALL, VOIDmode, fn_rtx, nregs_rtx)),
2824 gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, 15)));
2826 emit_call_insn (gen_rtx (PARALLEL, VOIDmode, vec));
2832 [(set (match_operand 0 "" "=rf")
2833 (call (mem:SI (match_operand:SI 1 "call_operand_address" "rS"))
2834 (match_operand 2 "" "")))
2835 (clobber (reg:SI 15))]
2836 ;;- Do not use operand 2 for most machines.
2840 return \"call %a1,%2%#\";
2842 [(set_attr "type" "call")])
2844 (define_expand "untyped_call"
2845 [(parallel [(call (match_operand:SI 0 "call_operand" "")
2847 (match_operand:BLK 1 "memory_operand" "")
2848 (match_operand 2 "" "")
2849 (clobber (reg:SI 15))])]
2853 operands[1] = change_address (operands[1], DImode, XEXP (operands[1], 0));
2856 ;; Make a call followed by two nops in case the function being called
2857 ;; returns a structure value and expects to skip an unimp instruction.
2860 [(call (mem:SI (match_operand:SI 0 "call_operand_address" "rS"))
2862 (match_operand:DI 1 "memory_operand" "o")
2863 (match_operand 2 "" "")
2864 (clobber (reg:SI 15))]
2868 operands[2] = adj_offsettable_operand (operands[1], 8);
2869 return \"call %a0,0\;nop\;nop\;std %%o0,%1\;st %%f0,%2\";
2871 [(set_attr "type" "multi")])
2873 ;; Prepare to return any type including a structure value.
2875 (define_expand "untyped_return"
2876 [(match_operand:BLK 0 "memory_operand" "")
2877 (match_operand 1 "" "")]
2881 rtx valreg1 = gen_rtx (REG, DImode, 24);
2882 rtx valreg2 = gen_rtx (REG, DFmode, 32);
2883 rtx result = operands[0];
2884 rtx rtnreg = gen_rtx (REG, SImode, (leaf_function ? 15 : 31));
2885 rtx value = gen_reg_rtx (SImode);
2887 /* Fetch the instruction where we will return to and see if it's an unimp
2888 instruction (the most significant 10 bits will be zero). If so,
2889 update the return address to skip the unimp instruction. */
2890 emit_move_insn (value,
2891 gen_rtx (MEM, SImode, plus_constant (rtnreg, 8)));
2892 emit_insn (gen_lshrsi3 (value, value, GEN_INT (22)));
2893 emit_insn (gen_update_return (rtnreg, value));
2895 /* Reload the function value registers. */
2896 emit_move_insn (valreg1, change_address (result, DImode, XEXP (result, 0)));
2897 emit_move_insn (valreg2,
2898 change_address (result, DFmode,
2899 plus_constant (XEXP (result, 0), 8)));
2901 /* Put USE insns before the return. */
2902 emit_insn (gen_rtx (USE, VOIDmode, valreg1));
2903 emit_insn (gen_rtx (USE, VOIDmode, valreg2));
2905 /* Construct the return. */
2906 expand_null_return ();
2911 ;; This is a bit of a hack. We're incrementing a fixed register (%i7),
2912 ;; and parts of the compiler don't want to believe that the add is needed.
2914 (define_insn "update_return"
2915 [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
2916 (match_operand:SI 1 "register_operand" "r")] 0)]
2918 "cmp %1,0\;be,a .+8\;add %0,4,%0"
2919 [(set_attr "type" "multi")])
2921 (define_insn "return"
2924 "* return output_return (operands);"
2925 [(set_attr "type" "multi")])
2932 (define_insn "indirect_jump"
2933 [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
2936 [(set_attr "type" "uncond_branch")])
2938 (define_expand "nonlocal_goto"
2939 [(match_operand:SI 0 "general_operand" "")
2940 (match_operand:SI 1 "general_operand" "")
2941 (match_operand:SI 2 "general_operand" "")
2942 (match_operand:SI 3 "" "")]
2946 /* Trap instruction to flush all the registers window. */
2947 emit_insn (gen_flush_register_windows ());
2948 /* Load the fp value for the containing fn into %fp.
2949 This is needed because operands[2] refers to %fp.
2950 Virtual register instantiation fails if the virtual %fp isn't set from a
2951 register. Thus we must copy operands[0] into a register if it isn't
2953 if (GET_CODE (operands[0]) != REG)
2954 operands[0] = force_reg (SImode, operands[0]);
2955 emit_move_insn (virtual_stack_vars_rtx, operands[0]);
2956 /* Find the containing function's current nonlocal goto handler,
2957 which will do any cleanups and then jump to the label. */
2958 emit_move_insn (gen_rtx (REG, SImode, 8), operands[1]);
2959 /* Restore %fp from stack pointer value for containing function.
2960 The restore insn that follows will move this to %sp,
2961 and reload the appropriate value into %fp. */
2962 emit_move_insn (frame_pointer_rtx, operands[2]);
2963 /* Put in the static chain register the nonlocal label address. */
2964 emit_move_insn (static_chain_rtx, operands[3]);
2965 /* USE of frame_pointer_rtx added for consistency; not clear if
2967 emit_insn (gen_rtx (USE, VOIDmode, frame_pointer_rtx));
2968 emit_insn (gen_rtx (USE, VOIDmode, stack_pointer_rtx));
2969 emit_insn (gen_rtx (USE, VOIDmode, static_chain_rtx));
2970 emit_insn (gen_rtx (USE, VOIDmode, gen_rtx (REG, SImode, 8)));
2971 /* Return, restoring reg window and jumping to goto handler. */
2972 emit_insn (gen_goto_handler_and_restore ());
2976 ;; Special trap insn to flush register windows.
2977 (define_insn "flush_register_windows"
2978 [(unspec_volatile [(const_int 0)] 0)]
2981 [(set_attr "type" "misc")])
2983 (define_insn "goto_handler_and_restore"
2984 [(unspec_volatile [(const_int 0)] 1)]
2986 "jmp %%o0+0\;restore"
2987 [(set_attr "type" "misc")
2988 (set_attr "length" "2")])
2992 ;; The scan instruction searches from the most significant bit while ffs
2993 ;; searches from the least significant bit. The bit index and treatment of
2994 ;; zero also differ. It takes at least 7 instructions to get the proper
2995 ;; result. Here is an obvious 8 instruction seequence.
2997 (define_insn "ffssi2"
2998 [(set (match_operand:SI 0 "register_operand" "=&r")
2999 (ffs:SI (match_operand:SI 1 "register_operand" "r")))
3000 (clobber (match_scratch:SI 2 "=&r"))]
3002 "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"
3003 [(set_attr "type" "multi")
3004 (set_attr "length" "8")])
3006 ;; Split up troublesome insns for better scheduling. */
3008 ;; The following patterns are straightforward. They can be applied
3009 ;; either before or after register allocation.
3012 [(set (match_operator 0 "memop" [(match_operand:SI 1 "symbolic_operand" "")])
3013 (match_operand 2 "reg_or_0_operand" ""))
3014 (clobber (match_operand:SI 3 "register_operand" ""))]
3016 [(set (match_dup 3) (high:SI (match_dup 1)))
3017 (set (match_op_dup 0 [(lo_sum:SI (match_dup 3) (match_dup 1))])
3022 [(set (match_operator 0 "memop"
3023 [(match_operand:SI 1 "immediate_operand" "")])
3024 (match_operand 2 "general_operand" ""))
3025 (clobber (match_operand:SI 3 "register_operand" ""))]
3027 [(set (match_op_dup 0 [(match_dup 1)])
3031 operands[1] = legitimize_pic_address (operands[1], GET_MODE (operands[0]),
3036 [(set (match_operand 0 "register_operand" "")
3037 (match_operator 1 "memop"
3038 [(match_operand:SI 2 "immediate_operand" "")]))]
3041 (match_op_dup 1 [(match_dup 2)]))]
3044 operands[2] = legitimize_pic_address (operands[2], GET_MODE (operands[1]),
3048 ;; Sign- and Zero-extend operations can have symbolic memory operands.
3051 [(set (match_operand 0 "register_operand" "")
3052 (match_operator 1 "extend_op"
3053 [(match_operator 2 "memop"
3054 [(match_operand:SI 3 "immediate_operand" "")])]))]
3057 (match_op_dup 1 [(match_op_dup 2 [(match_dup 3)])]))]
3060 operands[3] = legitimize_pic_address (operands[3], GET_MODE (operands[2]),
3065 [(set (match_operand:SI 0 "register_operand" "")
3066 (match_operand:SI 1 "immediate_operand" ""))]
3067 "! flag_pic && (GET_CODE (operands[1]) == SYMBOL_REF
3068 || GET_CODE (operands[1]) == CONST
3069 || GET_CODE (operands[1]) == LABEL_REF)"
3070 [(set (match_dup 0) (high:SI (match_dup 1)))
3072 (lo_sum:SI (match_dup 0) (match_dup 1)))]
3075 ;; LABEL_REFs are not modified by `legitimize_pic_address`
3076 ;; so do not recurse infinitely in the PIC case.
3078 [(set (match_operand:SI 0 "register_operand" "")
3079 (match_operand:SI 1 "immediate_operand" ""))]
3080 "flag_pic && (GET_CODE (operands[1]) == SYMBOL_REF
3081 || GET_CODE (operands[1]) == CONST)"
3082 [(set (match_dup 0) (match_dup 1))]
3085 operands[1] = legitimize_pic_address (operands[1], Pmode, operands[0], 0);
3088 ;; These split sne/seq insns. The forms of the resulting insns are
3089 ;; somewhat bogus, but they avoid extra patterns and show data dependency.
3090 ;; Nothing will look at these in detail after splitting has occurred.
3093 [(set (match_operand:SI 0 "register_operand" "")
3094 (ne:SI (match_operand:SI 1 "register_operand" "") (const_int 0)))
3095 (clobber (reg:CC 0))]
3097 [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
3099 (set (match_dup 0) (ltu:SI (reg:CC 0) (const_int 0)))]
3103 [(set (match_operand:SI 0 "register_operand" "")
3104 (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "")
3106 (clobber (reg:CC 0))]
3108 [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
3110 (set (match_dup 0) (neg:SI (ltu:SI (reg:CC 0) (const_int 0))))]
3114 [(set (match_operand:SI 0 "register_operand" "")
3115 (eq:SI (match_operand:SI 1 "register_operand" "") (const_int 0)))
3116 (clobber (reg:CC 0))]
3118 [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
3120 (set (match_dup 0) (geu:SI (reg:CC 0) (const_int 0)))]
3124 [(set (match_operand:SI 0 "register_operand" "")
3125 (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "")
3127 (clobber (reg:CC 0))]
3129 [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
3131 (set (match_dup 0) (neg:SI (geu:SI (reg:CC 0) (const_int 0))))]
3135 [(set (match_operand:SI 0 "register_operand" "")
3136 (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "")
3138 (match_operand:SI 2 "register_operand" "")))
3139 (clobber (reg:CC 0))]
3141 [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
3143 (set (match_dup 0) (plus:SI (ltu:SI (reg:CC 0) (const_int 0))
3148 [(set (match_operand:SI 0 "register_operand" "")
3149 (minus:SI (match_operand:SI 2 "register_operand" "")
3150 (ne:SI (match_operand:SI 1 "register_operand" "")
3152 (clobber (reg:CC 0))]
3154 [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
3156 (set (match_dup 0) (minus:SI (match_dup 2)
3157 (ltu:SI (reg:CC 0) (const_int 0))))]
3161 [(set (match_operand:SI 0 "register_operand" "")
3162 (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "")
3164 (match_operand:SI 2 "register_operand" "")))
3165 (clobber (reg:CC 0))]
3167 [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
3169 (set (match_dup 0) (plus:SI (geu:SI (reg:CC 0) (const_int 0))
3174 [(set (match_operand:SI 0 "register_operand" "")
3175 (minus:SI (match_operand:SI 2 "register_operand" "")
3176 (eq:SI (match_operand:SI 1 "register_operand" "")
3178 (clobber (reg:CC 0))]
3180 [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
3182 (set (match_dup 0) (minus:SI (match_dup 2)
3183 (geu:SI (reg:CC 0) (const_int 0))))]
3186 ;; Peepholes go at the end.
3188 ;; Optimize consecutive loads or stores into ldd and std when possible.
3189 ;; The conditions in which we do this are very restricted and are
3190 ;; explained in the code for {registers,memory}_ok_for_ldd functions.
3193 [(set (match_operand:SI 0 "register_operand" "=rf")
3194 (match_operand:SI 1 "memory_operand" ""))
3195 (set (match_operand:SI 2 "register_operand" "=rf")
3196 (match_operand:SI 3 "memory_operand" ""))]
3197 "registers_ok_for_ldd_peep (operands[0], operands[2])
3198 && ! MEM_VOLATILE_P (operands[1]) && ! MEM_VOLATILE_P (operands[3])
3199 && addrs_ok_for_ldd_peep (XEXP (operands[1], 0), XEXP (operands[3], 0))"
3203 [(set (match_operand:SI 0 "memory_operand" "")
3204 (match_operand:SI 1 "register_operand" "rf"))
3205 (set (match_operand:SI 2 "memory_operand" "")
3206 (match_operand:SI 3 "register_operand" "rf"))]
3207 "registers_ok_for_ldd_peep (operands[1], operands[3])
3208 && ! MEM_VOLATILE_P (operands[0]) && ! MEM_VOLATILE_P (operands[2])
3209 && addrs_ok_for_ldd_peep (XEXP (operands[0], 0), XEXP (operands[2], 0))"
3213 [(set (match_operand:SF 0 "register_operand" "=fr")
3214 (match_operand:SF 1 "memory_operand" ""))
3215 (set (match_operand:SF 2 "register_operand" "=fr")
3216 (match_operand:SF 3 "memory_operand" ""))]
3217 "registers_ok_for_ldd_peep (operands[0], operands[2])
3218 && ! MEM_VOLATILE_P (operands[1]) && ! MEM_VOLATILE_P (operands[3])
3219 && addrs_ok_for_ldd_peep (XEXP (operands[1], 0), XEXP (operands[3], 0))"
3223 [(set (match_operand:SF 0 "memory_operand" "")
3224 (match_operand:SF 1 "register_operand" "fr"))
3225 (set (match_operand:SF 2 "memory_operand" "")
3226 (match_operand:SF 3 "register_operand" "fr"))]
3227 "registers_ok_for_ldd_peep (operands[1], operands[3])
3228 && ! MEM_VOLATILE_P (operands[0]) && ! MEM_VOLATILE_P (operands[2])
3229 && addrs_ok_for_ldd_peep (XEXP (operands[0], 0), XEXP (operands[2], 0))"
3233 [(set (match_operand:SI 0 "register_operand" "=rf")
3234 (match_operand:SI 1 "memory_operand" ""))
3235 (set (match_operand:SI 2 "register_operand" "=rf")
3236 (match_operand:SI 3 "memory_operand" ""))]
3237 "registers_ok_for_ldd_peep (operands[2], operands[0])
3238 && ! MEM_VOLATILE_P (operands[3]) && ! MEM_VOLATILE_P (operands[1])
3239 && addrs_ok_for_ldd_peep (XEXP (operands[3], 0), XEXP (operands[1], 0))"
3243 [(set (match_operand:SI 0 "memory_operand" "")
3244 (match_operand:SI 1 "register_operand" "rf"))
3245 (set (match_operand:SI 2 "memory_operand" "")
3246 (match_operand:SI 3 "register_operand" "rf"))]
3247 "registers_ok_for_ldd_peep (operands[3], operands[1])
3248 && ! MEM_VOLATILE_P (operands[2]) && ! MEM_VOLATILE_P (operands[0])
3249 && addrs_ok_for_ldd_peep (XEXP (operands[2], 0), XEXP (operands[0], 0))"
3253 [(set (match_operand:SF 0 "register_operand" "=fr")
3254 (match_operand:SF 1 "memory_operand" ""))
3255 (set (match_operand:SF 2 "register_operand" "=fr")
3256 (match_operand:SF 3 "memory_operand" ""))]
3257 "registers_ok_for_ldd_peep (operands[2], operands[0])
3258 && ! MEM_VOLATILE_P (operands[3]) && ! MEM_VOLATILE_P (operands[1])
3259 && addrs_ok_for_ldd_peep (XEXP (operands[3], 0), XEXP (operands[1], 0))"
3263 [(set (match_operand:SF 0 "memory_operand" "")
3264 (match_operand:SF 1 "register_operand" "fr"))
3265 (set (match_operand:SF 2 "memory_operand" "")
3266 (match_operand:SF 3 "register_operand" "fr"))]
3267 "registers_ok_for_ldd_peep (operands[3], operands[1])
3268 && ! MEM_VOLATILE_P (operands[2]) && ! MEM_VOLATILE_P (operands[0])
3269 && addrs_ok_for_ldd_peep (XEXP (operands[2], 0), XEXP (operands[0], 0))"
3272 ;; Optimize the case of following a reg-reg move with a test
3273 ;; of reg just moved. Don't allow floating point regs for operand 0 or 1.
3274 ;; This can result from a float to fix conversion.
3277 [(set (match_operand:SI 0 "register_operand" "=r")
3278 (match_operand:SI 1 "register_operand" "r"))
3280 (compare:CC (match_operand:SI 2 "register_operand" "r")
3282 "(rtx_equal_p (operands[2], operands[0])
3283 || rtx_equal_p (operands[2], operands[1]))
3284 && ! FP_REG_P (operands[0]) && ! FP_REG_P (operands[1])"
3287 ;; Do {sign,zero}-extended compares somewhat more efficiently.
3288 ;; ??? Is this now the Right Way to do this? Or will SCRATCH
3289 ;; eventually have some impact here?
3292 [(set (match_operand:HI 0 "register_operand" "")
3293 (match_operand:HI 1 "memory_operand" ""))
3294 (set (match_operand:SI 2 "register_operand" "")
3295 (sign_extend:SI (match_dup 0)))
3297 (compare:CC (match_dup 2)
3300 "ldsh %1,%0\;orcc %0,%%g0,%2")
3303 [(set (match_operand:QI 0 "register_operand" "")
3304 (match_operand:QI 1 "memory_operand" ""))
3305 (set (match_operand:SI 2 "register_operand" "")
3306 (sign_extend:SI (match_dup 0)))
3308 (compare:CC (match_dup 2)
3311 "ldsb %1,%0\;orcc %0,%%g0,%2")
3314 [(set (match_operand:HI 0 "register_operand" "")
3315 (match_operand:HI 1 "memory_operand" ""))
3316 (set (match_operand:SI 2 "register_operand" "")
3317 (sign_extend:SI (match_dup 0)))]
3318 "dead_or_set_p (insn, operands[0])"
3321 warning (\"bad peephole\");
3322 if (! MEM_VOLATILE_P (operands[1]))
3324 return \"ldsh %1,%2\";
3328 [(set (match_operand:QI 0 "register_operand" "")
3329 (match_operand:QI 1 "memory_operand" ""))
3330 (set (match_operand:SI 2 "register_operand" "")
3331 (sign_extend:SI (match_dup 0)))]
3332 "dead_or_set_p (insn, operands[0])"
3335 warning (\"bad peephole\");
3336 if (! MEM_VOLATILE_P (operands[1]))
3338 return \"ldsb %1,%2\";
3341 ;; Floating-point move peepholes
3344 [(set (match_operand:SI 0 "register_operand" "=r")
3345 (lo_sum:SI (match_dup 0)
3346 (match_operand:SI 1 "immediate_operand" "i")))
3347 (set (match_operand:DF 2 "register_operand" "=fr")
3348 (mem:DF (match_dup 0)))]
3349 "RTX_UNCHANGING_P (operands[1]) && reg_unused_after (operands[0], insn)"
3352 /* Go by way of output_move_double in case the register in operand 2
3353 is not properly aligned for ldd. */
3354 operands[1] = gen_rtx (MEM, DFmode,
3355 gen_rtx (LO_SUM, SImode, operands[0], operands[1]));
3356 operands[0] = operands[2];
3357 return output_move_double (operands);
3361 [(set (match_operand:SI 0 "register_operand" "=r")
3362 (lo_sum:SI (match_dup 0)
3363 (match_operand:SI 1 "immediate_operand" "i")))
3364 (set (match_operand:SF 2 "register_operand" "=fr")
3365 (mem:SF (match_dup 0)))]
3366 "RTX_UNCHANGING_P (operands[1]) && reg_unused_after (operands[0], insn)"
3367 "ld [%0+%%lo(%a1)],%2")
3369 ;; Return peepholes. First the "normal" ones
3371 ;; ??? There are QImode, HImode, and SImode versions of this pattern.
3372 ;; It might be possible to write one more general pattern instead of three.
3375 [(set (match_operand:QI 0 "restore_operand" "")
3376 (match_operand:QI 1 "arith_operand" "rI"))
3381 if (current_function_returns_struct)
3382 return \"jmp %%i7+12\;restore %%g0,%1,%Y0\";
3384 return \"ret\;restore %%g0,%1,%Y0\";
3386 [(set_attr "type" "multi")])
3389 [(set (match_operand:HI 0 "restore_operand" "")
3390 (match_operand:HI 1 "arith_operand" "rI"))
3395 if (current_function_returns_struct)
3396 return \"jmp %%i7+12\;restore %%g0,%1,%Y0\";
3398 return \"ret\;restore %%g0,%1,%Y0\";
3400 [(set_attr "type" "multi")])
3403 [(set (match_operand:SI 0 "restore_operand" "")
3404 (match_operand:SI 1 "arith_operand" "rI"))
3409 if (current_function_returns_struct)
3410 return \"jmp %%i7+12\;restore %%g0,%1,%Y0\";
3412 return \"ret\;restore %%g0,%1,%Y0\";
3414 [(set_attr "type" "multi")])
3416 ;; The following pattern is only generated by delayed-branch scheduling,
3417 ;; when the insn winds up in the epilogue. This can only happen when
3418 ;; ! TARGET_FPU because otherwise fp return values are in %f0.
3420 [(set (match_operand:SF 0 "restore_operand" "r")
3421 (match_operand:SF 1 "register_operand" "r"))
3423 "! TARGET_FPU && ! TARGET_EPILOGUE"
3426 if (current_function_returns_struct)
3427 return \"jmp %%i7+12\;restore %%g0,%1,%Y0\";
3429 return \"ret\;restore %%g0,%1,%Y0\";
3431 [(set_attr "type" "multi")])
3434 [(set (match_operand:SI 0 "restore_operand" "")
3435 (plus:SI (match_operand:SI 1 "arith_operand" "%r")
3436 (match_operand:SI 2 "arith_operand" "rI")))
3441 if (current_function_returns_struct)
3442 return \"jmp %%i7+12\;restore %r1,%2,%Y0\";
3444 return \"ret\;restore %r1,%2,%Y0\";
3446 [(set_attr "type" "multi")])
3448 ;; Turned off because it should never match (subtracting a constant
3449 ;; is turned into addition) and because it would do the wrong thing
3450 ;; when operand 2 is -4096 (--4096 == 4096 is not a valid immediate).
3452 ;; [(set (match_operand:SI 0 "restore_operand" "")
3453 ;; (minus:SI (match_operand:SI 1 "register_operand" "r")
3454 ;; (match_operand:SI 2 "small_int" "I")))
3456 ;; "! TARGET_EPILOGUE"
3457 ;; "ret\;restore %1,-(%2),%Y0"
3458 ;; [(set_attr "type" "multi")])
3460 ;; The following pattern is only generated by delayed-branch scheduling,
3461 ;; when the insn winds up in the epilogue.
3464 (match_operand:SF 0 "register_operand" "f"))
3467 "ret\;fmovs %0,%%f0"
3468 [(set_attr "type" "multi")])
3470 ;; Now peepholes to go a call followed by a jump.
3473 [(parallel [(set (match_operand 0 "" "")
3474 (call (mem:SI (match_operand:SI 1 "call_operand_address" "S,r"))
3475 (match_operand 2 "" "")))
3476 (clobber (reg:SI 15))])
3477 (set (pc) (label_ref (match_operand 3 "" "")))]
3478 "short_branch (INSN_UID (insn), INSN_UID (operands[3]))"
3481 return \"call %a1,%2\;add %%o7,(%l3-.-4),%%o7\";
3485 [(parallel [(call (mem:SI (match_operand:SI 0 "call_operand_address" "S,r"))
3486 (match_operand 1 "" ""))
3487 (clobber (reg:SI 15))])
3488 (set (pc) (label_ref (match_operand 2 "" "")))]
3489 "short_branch (INSN_UID (insn), INSN_UID (operands[2]))"
3492 return \"call %a0,%1\;add %%o7,(%l2-.-4),%%o7\";
3496 [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
3497 (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
3499 (clobber (reg:CC 0))])
3500 (set (reg:CC 0) (compare (match_dup 0) (const_int 0)))]