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, 0))
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,r,r,f,Q,Q,rf")
810 (match_operand:SI 1 "move_operand" "rI,K,Q,!Q,rJ,!f,!fr"))]
811 "register_operand (operands[0], SImode)
812 || register_operand (operands[1], SImode)
813 || operands[1] == const0_rtx"
821 st %r1,[%@-4]\;ld [%@-4],%0"
822 [(set_attr "type" "move,move,load,load,store,store,multi")
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 output_asm_insn (\"mov -1,%0\", operands);
856 output_asm_insn (\"mov 0,%0\", operands);
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 output_asm_insn (singlemove_string (operands), operands);
871 [(set_attr "type" "move")
872 (set_attr "length" "2")])
874 ;; For PIC, symbol_refs are put inside unspec so that the optimizer won't
875 ;; confuse them with real addresses.
877 [(set (match_operand:SI 0 "register_operand" "=r")
878 (high:SI (unspec:SI [(match_operand 1 "" "")] 0)))]
881 [(set_attr "type" "move")
882 (set_attr "length" "1")])
885 [(set (match_operand:SI 0 "register_operand" "=r")
886 (high:SI (match_operand 1 "" "")))]
889 [(set_attr "type" "move")
890 (set_attr "length" "1")])
893 [(set (match_operand:HI 0 "register_operand" "=r")
894 (high:HI (match_operand 1 "" "")))]
897 [(set_attr "type" "move")
898 (set_attr "length" "1")])
901 [(set (match_operand:DI 0 "register_operand" "=r")
902 (lo_sum:DI (match_operand:DI 1 "register_operand" "0")
903 (match_operand:DI 2 "immediate_operand" "in")))]
907 /* Don't output a 64 bit constant, since we can't trust the assembler to
908 handle it correctly. */
909 if (GET_CODE (operands[2]) == CONST_DOUBLE)
910 operands[2] = gen_rtx (CONST_INT, VOIDmode, CONST_DOUBLE_LOW (operands[2]));
911 return \"or %R1,%%lo(%a2),%R0\";
913 ;; Need to set length for this arith insn because operand2
914 ;; is not an "arith_operand".
915 [(set_attr "length" "1")])
917 ;; For PIC, symbol_refs are put inside unspec so that the optimizer won't
918 ;; confuse them with real addresses.
920 [(set (match_operand:SI 0 "register_operand" "=r")
921 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
922 (unspec:SI [(match_operand:SI 2 "immediate_operand" "in")] 0)))]
925 ;; Need to set length for this arith insn because operand2
926 ;; is not an "arith_operand".
927 [(set_attr "length" "1")])
930 [(set (match_operand:SI 0 "register_operand" "=r")
931 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
932 (match_operand:SI 2 "immediate_operand" "in")))]
935 ;; Need to set length for this arith insn because operand2
936 ;; is not an "arith_operand".
937 [(set_attr "length" "1")])
940 [(set (mem:SI (match_operand:SI 0 "symbolic_operand" ""))
941 (match_operand:SI 1 "reg_or_0_operand" "rJ"))
942 (clobber (match_scratch:SI 2 "=&r"))]
944 "sethi %%hi(%a0),%2\;st %r1,[%2+%%lo(%a0)]"
945 [(set_attr "type" "store")
946 (set_attr "length" "2")])
948 (define_expand "movhi"
949 [(set (match_operand:HI 0 "general_operand" "")
950 (match_operand:HI 1 "general_operand" ""))]
954 if (emit_move_sequence (operands, HImode, 0))
959 [(set (match_operand:HI 0 "reg_or_nonsymb_mem_operand" "=r,r,r,Q")
960 (match_operand:HI 1 "move_operand" "rI,K,Q,rJ"))]
961 "register_operand (operands[0], HImode)
962 || register_operand (operands[1], HImode)
963 || operands[1] == const0_rtx"
969 [(set_attr "type" "move,move,load,store")
970 (set_attr "length" "*,1,*,1")])
973 [(set (match_operand:HI 0 "register_operand" "=r")
974 (lo_sum:HI (match_operand:HI 1 "register_operand" "r")
975 (match_operand 2 "immediate_operand" "in")))]
978 [(set_attr "length" "1")])
981 [(set (mem:HI (match_operand:SI 0 "symbolic_operand" ""))
982 (match_operand:HI 1 "reg_or_0_operand" "rJ"))
983 (clobber (match_scratch:SI 2 "=&r"))]
985 "sethi %%hi(%a0),%2\;sth %r1,[%2+%%lo(%a0)]"
986 [(set_attr "type" "store")
987 (set_attr "length" "2")])
989 (define_expand "movqi"
990 [(set (match_operand:QI 0 "general_operand" "")
991 (match_operand:QI 1 "general_operand" ""))]
995 if (emit_move_sequence (operands, QImode, 0))
1000 [(set (match_operand:QI 0 "reg_or_nonsymb_mem_operand" "=r,r,r,Q")
1001 (match_operand:QI 1 "move_operand" "rI,K,Q,rJ"))]
1002 "register_operand (operands[0], QImode)
1003 || register_operand (operands[1], QImode)
1004 || operands[1] == const0_rtx"
1010 [(set_attr "type" "move,move,load,store")
1011 (set_attr "length" "*,1,*,1")])
1014 [(set (match_operand:QI 0 "register_operand" "=r")
1015 (subreg:QI (lo_sum:SI (match_operand:QI 1 "register_operand" "r")
1016 (match_operand 2 "immediate_operand" "in")) 0))]
1018 "or %1,%%lo(%a2),%0"
1019 [(set_attr "length" "1")])
1022 [(set (mem:QI (match_operand:SI 0 "symbolic_operand" ""))
1023 (match_operand:QI 1 "reg_or_0_operand" "rJ"))
1024 (clobber (match_scratch:SI 2 "=&r"))]
1026 "sethi %%hi(%a0),%2\;stb %r1,[%2+%%lo(%a0)]"
1027 [(set_attr "type" "store")
1028 (set_attr "length" "2")])
1030 ;; The definition of this insn does not really explain what it does,
1031 ;; but it should suffice
1032 ;; that anything generated as this insn will be recognized as one
1033 ;; and that it will not successfully combine with anything.
1034 (define_expand "movstrsi"
1035 [(parallel [(set (mem:BLK (match_operand:BLK 0 "general_operand" ""))
1036 (mem:BLK (match_operand:BLK 1 "general_operand" "")))
1037 (use (match_operand:SI 2 "nonmemory_operand" ""))
1038 (use (match_operand:SI 3 "immediate_operand" ""))
1039 (clobber (match_dup 0))
1040 (clobber (match_dup 1))
1041 (clobber (match_scratch:SI 4 ""))
1042 (clobber (reg:SI 0))
1043 (clobber (reg:SI 1))])]
1047 /* If the size isn't known, don't emit inline code. output_block_move
1048 would output code that's much slower than the library function.
1049 Also don't output code for large blocks. */
1050 if (GET_CODE (operands[2]) != CONST_INT
1051 || GET_CODE (operands[3]) != CONST_INT
1052 || INTVAL (operands[2]) / INTVAL (operands[3]) > 16)
1055 operands[0] = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
1056 operands[1] = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
1057 operands[2] = force_not_mem (operands[2]);
1061 [(set (mem:BLK (match_operand:SI 0 "register_operand" "+r"))
1062 (mem:BLK (match_operand:SI 1 "register_operand" "+r")))
1063 (use (match_operand:SI 2 "nonmemory_operand" "rn"))
1064 (use (match_operand:SI 3 "immediate_operand" "i"))
1065 (clobber (match_dup 0))
1066 (clobber (match_dup 1))
1067 (clobber (match_scratch:SI 4 "=&r"))
1068 (clobber (reg:SI 0))
1069 (clobber (reg:SI 1))]
1071 "* return output_block_move (operands);"
1072 [(set_attr "type" "multi")
1073 (set_attr "length" "6")])
1075 ;; Floating point move insns
1077 ;; This pattern forces (set (reg:TF ...) (const_double ...))
1078 ;; to be reloaded by putting the constant into memory.
1079 ;; It must come before the more general movtf pattern.
1081 [(set (match_operand:TF 0 "general_operand" "=?r,f,o")
1082 (match_operand:TF 1 "" "?E,m,G"))]
1083 "TARGET_FPU && GET_CODE (operands[1]) == CONST_DOUBLE"
1086 switch (which_alternative)
1089 return output_move_quad (operands);
1091 return output_fp_move_quad (operands);
1093 operands[1] = adj_offsettable_operand (operands[0], 4);
1094 operands[2] = adj_offsettable_operand (operands[0], 8);
1095 operands[3] = adj_offsettable_operand (operands[0], 12);
1096 return \"st %%g0,%0\;st %%g0,%1\;st %%g0,%2\;st %%g0,%3\";
1099 [(set_attr "type" "load,fpload,store")
1100 (set_attr "length" "5,5,5")])
1102 (define_expand "movtf"
1103 [(set (match_operand:TF 0 "general_operand" "")
1104 (match_operand:TF 1 "general_operand" ""))]
1108 if (emit_move_sequence (operands, TFmode, 0))
1113 [(set (match_operand:TF 0 "reg_or_nonsymb_mem_operand" "=f,r,Q,Q,f,&r,?f,?r")
1114 (match_operand:TF 1 "reg_or_nonsymb_mem_operand" "f,r,f,r,Q,Q,r,f"))]
1116 && (register_operand (operands[0], TFmode)
1117 || register_operand (operands[1], TFmode))"
1120 if (FP_REG_P (operands[0]) || FP_REG_P (operands[1]))
1121 return output_fp_move_quad (operands);
1122 return output_move_quad (operands);
1124 [(set_attr "type" "fp,move,fpstore,store,fpload,load,multi,multi")
1125 (set_attr "length" "4,4,5,5,5,5,5,5")])
1127 ;; Exactly the same as above, except that all `f' cases are deleted.
1128 ;; This is necessary to prevent reload from ever trying to use a `f' reg
1132 [(set (match_operand:TF 0 "reg_or_nonsymb_mem_operand" "=r,Q,&r")
1133 (match_operand:TF 1 "reg_or_nonsymb_mem_operand" "r,r,Q"))]
1135 && (register_operand (operands[0], TFmode)
1136 || register_operand (operands[1], TFmode))"
1139 if (FP_REG_P (operands[0]) || FP_REG_P (operands[1]))
1140 return output_fp_move_quad (operands);
1141 return output_move_quad (operands);
1143 [(set_attr "type" "move,store,load")
1144 (set_attr "length" "4,5,5")])
1147 [(set (mem:TF (match_operand:SI 0 "symbolic_operand" "i,i"))
1148 (match_operand:TF 1 "reg_or_0_operand" "rf,G"))
1149 (clobber (match_scratch:SI 2 "=&r,&r"))]
1153 output_asm_insn (\"sethi %%hi(%a0),%2\", operands);
1154 if (which_alternative == 0)
1155 return \"std %1,[%2+%%lo(%a0)]\;std %S1,[%2+%%lo(%a0+8)]\";
1157 return \"st %%g0,[%2+%%lo(%a0)]\;st %%g0,[%2+%%lo(%a0+4)]\; st %%g0,[%2+%%lo(%a0+8)]\;st %%g0,[%2+%%lo(%a0+12)]\";
1159 [(set_attr "type" "store")
1160 (set_attr "length" "5")])
1162 ;; This pattern forces (set (reg:DF ...) (const_double ...))
1163 ;; to be reloaded by putting the constant into memory.
1164 ;; It must come before the more general movdf pattern.
1167 [(set (match_operand:DF 0 "general_operand" "=?r,f,o")
1168 (match_operand:DF 1 "" "?E,m,G"))]
1169 "TARGET_FPU && GET_CODE (operands[1]) == CONST_DOUBLE"
1172 switch (which_alternative)
1175 return output_move_double (operands);
1177 return output_fp_move_double (operands);
1179 operands[1] = adj_offsettable_operand (operands[0], 4);
1180 return \"st %%g0,%0\;st %%g0,%1\";
1183 [(set_attr "type" "load,fpload,store")
1184 (set_attr "length" "3,3,3")])
1186 (define_expand "movdf"
1187 [(set (match_operand:DF 0 "general_operand" "")
1188 (match_operand:DF 1 "general_operand" ""))]
1192 if (emit_move_sequence (operands, DFmode, 0))
1197 [(set (match_operand:DF 0 "reg_or_nonsymb_mem_operand" "=T,U,f,r,Q,Q,f,&r,?f,?r")
1198 (match_operand:DF 1 "reg_or_nonsymb_mem_operand" "U,T,f,r,f,r,Q,Q,r,f"))]
1200 && (register_operand (operands[0], DFmode)
1201 || register_operand (operands[1], DFmode))"
1204 if (FP_REG_P (operands[0]) || FP_REG_P (operands[1]))
1205 return output_fp_move_double (operands);
1206 return output_move_double (operands);
1208 [(set_attr "type" "fpstore,fpload,fp,move,fpstore,store,fpload,load,multi,multi")
1209 (set_attr "length" "1,1,2,2,3,3,3,3,3,3")])
1211 ;; Exactly the same as above, except that all `f' cases are deleted.
1212 ;; This is necessary to prevent reload from ever trying to use a `f' reg
1216 [(set (match_operand:DF 0 "reg_or_nonsymb_mem_operand" "=T,U,r,Q,&r")
1217 (match_operand:DF 1 "reg_or_nonsymb_mem_operand" "U,T,r,r,Q"))]
1219 && (register_operand (operands[0], DFmode)
1220 || register_operand (operands[1], DFmode))"
1221 "* return output_move_double (operands);"
1222 [(set_attr "type" "store,load,move,store,load")
1223 (set_attr "length" "1,1,2,3,3")])
1226 [(set (mem:DF (match_operand:SI 0 "symbolic_operand" "i,i"))
1227 (match_operand:DF 1 "reg_or_0_operand" "rf,G"))
1228 (clobber (match_scratch:SI 2 "=&r,&r"))]
1232 output_asm_insn (\"sethi %%hi(%a0),%2\", operands);
1233 if (which_alternative == 0)
1234 return \"std %1,[%2+%%lo(%a0)]\";
1236 return \"st %%g0,[%2+%%lo(%a0)]\;st %%g0,[%2+%%lo(%a0+4)]\";
1238 [(set_attr "type" "store")
1239 (set_attr "length" "3")])
1241 ;; Double-word move insns.
1243 (define_expand "movdi"
1244 [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand" "")
1245 (match_operand:DI 1 "general_operand" ""))]
1249 if (emit_move_sequence (operands, DImode, 0))
1254 [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand" "=r,Q,&r,&r,?f,?f,?f,?r,?Q")
1255 (match_operand:DI 1 "general_operand" "r,r,Q,i,r,f,Q,f,f"))]
1256 "register_operand (operands[0], DImode)
1257 || register_operand (operands[1], DImode)
1258 || operands[1] == const0_rtx"
1261 if (FP_REG_P (operands[0]) || FP_REG_P (operands[1]))
1262 return output_fp_move_double (operands);
1263 return output_move_double (operands);
1265 [(set_attr "type" "move,store,load,multi,multi,fp,fpload,multi,fpstore")
1266 (set_attr "length" "2,3,3,3,3,2,3,3,3")])
1268 ;; Floating-point move insns.
1270 ;; This pattern forces (set (reg:SF ...) (const_double ...))
1271 ;; to be reloaded by putting the constant into memory.
1272 ;; It must come before the more general movsf pattern.
1274 [(set (match_operand:SF 0 "general_operand" "=?r,f,m")
1275 (match_operand:SF 1 "" "?E,m,G"))]
1276 "TARGET_FPU && GET_CODE (operands[1]) == CONST_DOUBLE"
1279 switch (which_alternative)
1282 return singlemove_string (operands);
1284 return \"ld %1,%0\";
1286 return \"st %%g0,%0\";
1289 [(set_attr "type" "load,fpload,store")
1290 (set_attr "length" "2,1,1")])
1292 (define_expand "movsf"
1293 [(set (match_operand:SF 0 "general_operand" "")
1294 (match_operand:SF 1 "general_operand" ""))]
1298 if (emit_move_sequence (operands, SFmode, 0))
1303 [(set (match_operand:SF 0 "reg_or_nonsymb_mem_operand" "=f,r,rf,f,r,Q,Q")
1304 (match_operand:SF 1 "reg_or_nonsymb_mem_operand" "f,r,!rf,Q,Q,f,r"))]
1306 && (register_operand (operands[0], SFmode)
1307 || register_operand (operands[1], SFmode))"
1311 st %r1,[%@-4]\;ld [%@-4],%0
1316 [(set_attr "type" "fp,move,multi,fpload,load,fpstore,store")])
1318 ;; Exactly the same as above, except that all `f' cases are deleted.
1319 ;; This is necessary to prevent reload from ever trying to use a `f' reg
1323 [(set (match_operand:SF 0 "reg_or_nonsymb_mem_operand" "=r,r,Q")
1324 (match_operand:SF 1 "reg_or_nonsymb_mem_operand" "r,Q,r"))]
1326 && (register_operand (operands[0], SFmode)
1327 || register_operand (operands[1], SFmode))"
1332 [(set_attr "type" "move,load,store")])
1335 [(set (mem:SF (match_operand:SI 0 "symbolic_operand" "i"))
1336 (match_operand:SF 1 "reg_or_0_operand" "rfG"))
1337 (clobber (match_scratch:SI 2 "=&r"))]
1339 "sethi %%hi(%a0),%2\;st %r1,[%2+%%lo(%a0)]"
1340 [(set_attr "type" "store")
1341 (set_attr "length" "2")])
1343 ;;- zero extension instructions
1345 ;; These patterns originally accepted general_operands, however, slightly
1346 ;; better code is generated by only accepting register_operands, and then
1347 ;; letting combine generate the ldu[hb] insns.
1349 (define_expand "zero_extendhisi2"
1350 [(set (match_operand:SI 0 "register_operand" "")
1351 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
1355 rtx temp = gen_reg_rtx (SImode);
1356 rtx shift_16 = gen_rtx (CONST_INT, VOIDmode, 16);
1358 if (GET_CODE (operand1) == SUBREG)
1359 operand1 = XEXP (operand1, 0);
1361 emit_insn (gen_ashlsi3 (temp, gen_rtx (SUBREG, SImode, operand1, 0),
1363 emit_insn (gen_lshrsi3 (operand0, temp, shift_16));
1368 [(set (match_operand:SI 0 "register_operand" "=r")
1369 (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
1372 [(set_attr "type" "load")])
1374 (define_expand "zero_extendqihi2"
1375 [(set (match_operand:HI 0 "register_operand" "")
1376 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
1381 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
1382 (zero_extend:HI (match_operand:QI 1 "sparc_operand" "r,I,Q")))]
1383 "GET_CODE (operands[1]) != CONST_INT"
1388 [(set_attr "type" "unary,move,load")
1389 (set_attr "length" "1")])
1391 (define_expand "zero_extendqisi2"
1392 [(set (match_operand:SI 0 "register_operand" "")
1393 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
1398 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
1399 (zero_extend:SI (match_operand:QI 1 "sparc_operand" "r,I,Q")))]
1400 "GET_CODE (operands[1]) != CONST_INT"
1405 [(set_attr "type" "unary,move,load")
1406 (set_attr "length" "1")])
1410 (compare:CC (zero_extend:SI (match_operand:QI 0 "register_operand" "r"))
1413 "andcc %0,0xff,%%g0"
1414 [(set_attr "type" "compare")])
1418 (compare:CC (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
1420 (set (match_operand:SI 0 "register_operand" "=r")
1421 (zero_extend:SI (match_dup 1)))]
1424 [(set_attr "type" "unary")])
1426 ;;- sign extension instructions
1428 ;; These patterns originally accepted general_operands, however, slightly
1429 ;; better code is generated by only accepting register_operands, and then
1430 ;; letting combine generate the lds[hb] insns.
1432 (define_expand "extendhisi2"
1433 [(set (match_operand:SI 0 "register_operand" "")
1434 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
1438 rtx temp = gen_reg_rtx (SImode);
1439 rtx shift_16 = gen_rtx (CONST_INT, VOIDmode, 16);
1441 if (GET_CODE (operand1) == SUBREG)
1442 operand1 = XEXP (operand1, 0);
1444 emit_insn (gen_ashlsi3 (temp, gen_rtx (SUBREG, SImode, operand1, 0),
1446 emit_insn (gen_ashrsi3 (operand0, temp, shift_16));
1451 [(set (match_operand:SI 0 "register_operand" "=r")
1452 (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
1455 [(set_attr "type" "load")])
1457 (define_expand "extendqihi2"
1458 [(set (match_operand:HI 0 "register_operand" "")
1459 (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
1463 rtx temp = gen_reg_rtx (SImode);
1464 rtx shift_24 = gen_rtx (CONST_INT, VOIDmode, 24);
1466 if (GET_CODE (operand1) == SUBREG)
1467 operand1 = XEXP (operand1, 0);
1468 if (GET_CODE (operand0) == SUBREG)
1469 operand0 = XEXP (operand0, 0);
1470 emit_insn (gen_ashlsi3 (temp, gen_rtx (SUBREG, SImode, operand1, 0),
1472 if (GET_MODE (operand0) != SImode)
1473 operand0 = gen_rtx (SUBREG, SImode, operand0, 0);
1474 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
1479 [(set (match_operand:HI 0 "register_operand" "=r")
1480 (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
1483 [(set_attr "type" "load")])
1485 (define_expand "extendqisi2"
1486 [(set (match_operand:SI 0 "register_operand" "")
1487 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
1491 rtx temp = gen_reg_rtx (SImode);
1492 rtx shift_24 = gen_rtx (CONST_INT, VOIDmode, 24);
1494 if (GET_CODE (operand1) == SUBREG)
1495 operand1 = XEXP (operand1, 0);
1496 emit_insn (gen_ashlsi3 (temp, gen_rtx (SUBREG, SImode, operand1, 0),
1498 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
1503 [(set (match_operand:SI 0 "register_operand" "=r")
1504 (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
1507 [(set_attr "type" "load")])
1509 ;; Special pattern for optimizing bit-field compares. This is needed
1510 ;; because combine uses this as a canonical form.
1515 (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
1516 (match_operand:SI 1 "small_int" "n")
1517 (match_operand:SI 2 "small_int" "n"))
1519 "INTVAL (operands[2]) > 19"
1522 int len = INTVAL (operands[1]);
1523 int pos = 32 - INTVAL (operands[2]) - len;
1524 unsigned mask = ((1 << len) - 1) << pos;
1526 operands[1] = gen_rtx (CONST_INT, VOIDmode, mask);
1527 return \"andcc %0,%1,%%g0\";
1530 ;; Conversions between float, double and long double.
1532 (define_insn "extendsfdf2"
1533 [(set (match_operand:DF 0 "register_operand" "=f")
1535 (match_operand:SF 1 "register_operand" "f")))]
1538 [(set_attr "type" "fp")])
1540 (define_insn "extendsftf2"
1541 [(set (match_operand:TF 0 "register_operand" "=f")
1543 (match_operand:SF 1 "register_operand" "f")))]
1546 [(set_attr "type" "fp")])
1548 (define_insn "extenddftf2"
1549 [(set (match_operand:TF 0 "register_operand" "=f")
1551 (match_operand:DF 1 "register_operand" "f")))]
1554 [(set_attr "type" "fp")])
1556 (define_insn "truncdfsf2"
1557 [(set (match_operand:SF 0 "register_operand" "=f")
1559 (match_operand:DF 1 "register_operand" "f")))]
1562 [(set_attr "type" "fp")])
1564 (define_insn "trunctfsf2"
1565 [(set (match_operand:SF 0 "register_operand" "=f")
1567 (match_operand:TF 1 "register_operand" "f")))]
1570 [(set_attr "type" "fp")])
1572 (define_insn "trunctfdf2"
1573 [(set (match_operand:DF 0 "register_operand" "=f")
1575 (match_operand:TF 1 "register_operand" "f")))]
1578 [(set_attr "type" "fp")])
1580 ;; Conversion between fixed point and floating point.
1582 (define_insn "floatsisf2"
1583 [(set (match_operand:SF 0 "register_operand" "=f")
1584 (float:SF (match_operand:SI 1 "register_operand" "f")))]
1587 [(set_attr "type" "fp")])
1589 (define_insn "floatsidf2"
1590 [(set (match_operand:DF 0 "register_operand" "=f")
1591 (float:DF (match_operand:SI 1 "register_operand" "f")))]
1594 [(set_attr "type" "fp")])
1596 (define_insn "floatsitf2"
1597 [(set (match_operand:TF 0 "register_operand" "=f")
1598 (float:TF (match_operand:SI 1 "register_operand" "f")))]
1601 [(set_attr "type" "fp")])
1603 ;; Convert a float to an actual integer.
1604 ;; Truncation is performed as part of the conversion.
1606 (define_insn "fix_truncsfsi2"
1607 [(set (match_operand:SI 0 "register_operand" "=f")
1608 (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
1611 [(set_attr "type" "fp")])
1613 (define_insn "fix_truncdfsi2"
1614 [(set (match_operand:SI 0 "register_operand" "=f")
1615 (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "f"))))]
1618 [(set_attr "type" "fp")])
1620 (define_insn "fix_trunctfsi2"
1621 [(set (match_operand:SI 0 "register_operand" "=f")
1622 (fix:SI (fix:TF (match_operand:TF 1 "register_operand" "f"))))]
1625 [(set_attr "type" "fp")])
1627 ;;- arithmetic instructions
1629 (define_insn "adddi3"
1630 [(set (match_operand:DI 0 "register_operand" "=r")
1631 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
1632 (match_operand:DI 2 "arith_double_operand" "rHI")))
1633 (clobber (reg:SI 0))]
1637 rtx op2 = operands[2];
1639 /* If constant is positive, upper bits zeroed, otherwise unchanged.
1640 Give the assembler a chance to pick the move instruction. */
1641 if (GET_CODE (op2) == CONST_INT)
1643 int sign = INTVAL (op2);
1645 return \"addcc %R1,%2,%R0\;addx %1,-1,%0\";
1646 return \"addcc %R1,%2,%R0\;addx %1,0,%0\";
1648 else if (GET_CODE (op2) == CONST_DOUBLE)
1650 int sign = CONST_DOUBLE_HIGH (op2);
1651 operands[2] = gen_rtx (CONST_INT, VOIDmode,
1652 CONST_DOUBLE_LOW (operands[1]));
1654 return \"addcc %R1,%2,%R0\;addx %1,-1,%0\";
1655 return \"addcc %R1,%2,%R0\;addx %1,0,%0\";
1657 return \"addcc %R1,%R2,%R0\;addx %1,%2,%0\";
1659 [(set_attr "length" "2")])
1661 (define_insn "addsi3"
1662 [(set (match_operand:SI 0 "register_operand" "=r")
1663 (plus:SI (match_operand:SI 1 "arith_operand" "%r")
1664 (match_operand:SI 2 "arith_operand" "rI")))]
1669 [(set (reg:CC_NOOV 0)
1670 (compare:CC_NOOV (plus:SI (match_operand:SI 0 "arith_operand" "%r")
1671 (match_operand:SI 1 "arith_operand" "rI"))
1675 [(set_attr "type" "compare")])
1678 [(set (reg:CC_NOOV 0)
1679 (compare:CC_NOOV (plus:SI (match_operand:SI 1 "arith_operand" "%r")
1680 (match_operand:SI 2 "arith_operand" "rI"))
1682 (set (match_operand:SI 0 "register_operand" "=r")
1683 (plus:SI (match_dup 1) (match_dup 2)))]
1687 (define_insn "subdi3"
1688 [(set (match_operand:DI 0 "register_operand" "=r")
1689 (minus:DI (match_operand:DI 1 "register_operand" "r")
1690 (match_operand:DI 2 "arith_double_operand" "rHI")))
1691 (clobber (reg:SI 0))]
1695 rtx op2 = operands[2];
1697 /* If constant is positive, upper bits zeroed, otherwise unchanged.
1698 Give the assembler a chance to pick the move instruction. */
1699 if (GET_CODE (op2) == CONST_INT)
1701 int sign = INTVAL (op2);
1703 return \"subcc %R1,%2,%R0\;subx %1,-1,%0\";
1704 return \"subcc %R1,%2,%R0\;subx %1,0,%0\";
1706 else if (GET_CODE (op2) == CONST_DOUBLE)
1708 int sign = CONST_DOUBLE_HIGH (op2);
1709 operands[2] = gen_rtx (CONST_INT, VOIDmode,
1710 CONST_DOUBLE_LOW (operands[1]));
1712 return \"subcc %R1,%2,%R0\;subx %1,-1,%0\";
1713 return \"subcc %R1,%2,%R0\;subx %1,0,%0\";
1715 return \"subcc %R1,%R2,%R0\;subx %1,%2,%0\";
1717 [(set_attr "length" "2")])
1719 (define_insn "subsi3"
1720 [(set (match_operand:SI 0 "register_operand" "=r")
1721 (minus:SI (match_operand:SI 1 "register_operand" "r")
1722 (match_operand:SI 2 "arith_operand" "rI")))]
1727 [(set (reg:CC_NOOV 0)
1728 (compare:CC_NOOV (minus:SI (match_operand:SI 0 "register_operand" "r")
1729 (match_operand:SI 1 "arith_operand" "rI"))
1733 [(set_attr "type" "compare")])
1736 [(set (reg:CC_NOOV 0)
1737 (compare:CC_NOOV (minus:SI (match_operand:SI 1 "register_operand" "r")
1738 (match_operand:SI 2 "arith_operand" "rI"))
1740 (set (match_operand:SI 0 "register_operand" "=r")
1741 (minus:SI (match_dup 1) (match_dup 2)))]
1745 (define_insn "mulsi3"
1746 [(set (match_operand:SI 0 "register_operand" "=r")
1747 (mult:SI (match_operand:SI 1 "arith_operand" "%r")
1748 (match_operand:SI 2 "arith_operand" "rI")))]
1749 "TARGET_V8 || TARGET_SPARCLITE"
1752 ;; It is not known whether this will match.
1755 [(set (match_operand:SI 0 "register_operand" "=r")
1756 (mult:SI (match_operand:SI 1 "arith_operand" "%r")
1757 (match_operand:SI 2 "arith_operand" "rI")))
1758 (set (reg:CC_NOOV 0)
1759 (compare:CC_NOOV (mult:SI (match_dup 1) (match_dup 2))
1761 "TARGET_V8 || TARGET_SPARCLITE"
1764 (define_expand "mulsidi3"
1765 [(set (match_operand:DI 0 "register_operand" "")
1766 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
1767 (sign_extend:DI (match_operand:SI 2 "arith_operand" ""))))]
1768 "TARGET_V8 || TARGET_SPARCLITE"
1771 if (CONSTANT_P (operands[2]))
1773 emit_insn (gen_const_mulsidi3 (operands[0], operands[1], operands[2]));
1779 [(set (match_operand:DI 0 "register_operand" "=r")
1780 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
1781 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
1782 "TARGET_V8 || TARGET_SPARCLITE"
1783 "smul %1,%2,%R0\;rd %%y,%0"
1784 [(set_attr "length" "2")])
1786 ;; Extra pattern, because sign_extend of a constant isn't legal.
1788 (define_insn "const_mulsidi3"
1789 [(set (match_operand:DI 0 "register_operand" "=r")
1790 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
1791 (match_operand:SI 2 "small_int" "I")))]
1792 "TARGET_V8 || TARGET_SPARCLITE"
1793 "smul %1,%2,%R0\;rd %%y,%0"
1794 [(set_attr "length" "2")])
1796 (define_expand "umulsidi3"
1797 [(set (match_operand:DI 0 "register_operand" "")
1798 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
1799 (zero_extend:DI (match_operand:SI 2 "arith_operand" ""))))]
1800 "TARGET_V8 || TARGET_SPARCLITE"
1803 if (CONSTANT_P (operands[2]))
1805 emit_insn (gen_const_umulsidi3 (operands[0], operands[1], operands[2]));
1811 [(set (match_operand:DI 0 "register_operand" "=r")
1812 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
1813 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
1814 "TARGET_V8 || TARGET_SPARCLITE"
1815 "umul %1,%2,%R0\;rd %%y,%0"
1816 [(set_attr "length" "2")])
1818 ;; Extra pattern, because sign_extend of a constant isn't legal.
1820 (define_insn "const_umulsidi3"
1821 [(set (match_operand:DI 0 "register_operand" "=r")
1822 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
1823 (match_operand:SI 2 "small_int" "I")))]
1824 "TARGET_V8 || TARGET_SPARCLITE"
1825 "umul %1,%2,%R0\;rd %%y,%0"
1826 [(set_attr "length" "2")])
1828 ;; The architecture specifies that there must be 3 instructions between
1829 ;; a y register write and a use of it for correct results.
1831 (define_insn "divsi3"
1832 [(set (match_operand:SI 0 "register_operand" "=r")
1833 (div:SI (match_operand:SI 1 "register_operand" "r")
1834 (match_operand:SI 2 "arith_operand" "rI")))
1835 (clobber (match_scratch:SI 3 "=&r"))]
1837 "sra %1,31,%3\;wr %%g0,%3,%%y\;nop\;nop\;nop\;sdiv %1,%2,%0"
1838 [(set_attr "length" "6")])
1840 ;; It is not known whether this will match.
1843 [(set (match_operand:SI 0 "register_operand" "=r")
1844 (div:SI (match_operand:SI 1 "register_operand" "r")
1845 (match_operand:SI 2 "arith_operand" "rI")))
1847 (compare:CC (div:SI (match_dup 1) (match_dup 2))
1849 (clobber (match_scratch:SI 3 "=&r"))]
1851 "sra %1,31,%3\;wr %%g0,%3,%%y\;nop\;nop\;nop\;sdivcc %1,%2,%0"
1852 [(set_attr "length" "6")])
1854 (define_insn "udivsi3"
1855 [(set (match_operand:SI 0 "register_operand" "=r")
1856 (udiv:SI (match_operand:SI 1 "register_operand" "r")
1857 (match_operand:SI 2 "arith_operand" "rI")))]
1859 "wr %%g0,%%g0,%%y\;nop\;nop\;nop\;udiv %1,%2,%0"
1860 [(set_attr "length" "5")])
1862 ;; It is not known whether this will match.
1865 [(set (match_operand:SI 0 "register_operand" "=r")
1866 (udiv:SI (match_operand:SI 1 "register_operand" "r")
1867 (match_operand:SI 2 "arith_operand" "rI")))
1869 (compare:CC (udiv:SI (match_dup 1) (match_dup 2))
1872 "wr %%g0,%%g0,%%y\;nop\;nop\;nop\;udivcc %1,%2,%0"
1873 [(set_attr "length" "5")])
1875 ;;- and instructions
1876 ;; We define DImode `and` so with DImode `not` we can get
1877 ;; DImode `andn`. Other combinations are possible.
1879 (define_expand "anddi3"
1880 [(set (match_operand:DI 0 "register_operand" "")
1881 (and:DI (match_operand:DI 1 "arith_double_operand" "")
1882 (match_operand:DI 2 "arith_double_operand" "")))]
1887 [(set (match_operand:DI 0 "register_operand" "=r")
1888 (and:DI (match_operand:DI 1 "arith_double_operand" "%r")
1889 (match_operand:DI 2 "arith_double_operand" "rHI")))]
1893 rtx op2 = operands[2];
1895 /* If constant is positive, upper bits zeroed, otherwise unchanged.
1896 Give the assembler a chance to pick the move instruction. */
1897 if (GET_CODE (op2) == CONST_INT)
1899 int sign = INTVAL (op2);
1901 return \"mov %1,%0\;and %R1,%2,%R0\";
1902 return \"mov 0,%0\;and %R1,%2,%R0\";
1904 else if (GET_CODE (op2) == CONST_DOUBLE)
1906 int sign = CONST_DOUBLE_HIGH (op2);
1907 operands[2] = gen_rtx (CONST_INT, VOIDmode,
1908 CONST_DOUBLE_LOW (operands[1]));
1910 return \"mov %1,%0\;and %R1,%2,%R0\";
1911 return \"mov 0,%0\;and %R1,%2,%R0\";
1913 return \"and %1,%2,%0\;and %R1,%R2,%R0\";
1915 [(set_attr "length" "2")])
1917 (define_insn "andsi3"
1918 [(set (match_operand:SI 0 "register_operand" "=r")
1919 (and:SI (match_operand:SI 1 "arith_operand" "%r")
1920 (match_operand:SI 2 "arith_operand" "rI")))]
1925 [(set (match_operand:SI 0 "register_operand" "")
1926 (and:SI (match_operand:SI 1 "register_operand" "")
1927 (match_operand:SI 2 "" "")))
1928 (clobber (match_operand:SI 3 "register_operand" ""))]
1929 "GET_CODE (operands[2]) == CONST_INT
1930 && !SMALL_INT (operands[2])
1931 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
1932 [(set (match_dup 3) (match_dup 4))
1933 (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 1)))]
1936 operands[4] = gen_rtx (CONST_INT, VOIDmode, ~INTVAL (operands[2]));
1940 [(set (match_operand:DI 0 "register_operand" "=r")
1941 (and:DI (not:DI (match_operand:DI 1 "register_operand" "r"))
1942 (match_operand:DI 2 "register_operand" "r")))]
1944 "andn %2,%1,%0\;andn %R2,%R1,%R0"
1945 [(set_attr "length" "2")])
1948 [(set (match_operand:SI 0 "register_operand" "=r")
1949 (and:SI (not:SI (match_operand:SI 1 "register_operand" "r"))
1950 (match_operand:SI 2 "register_operand" "r")))]
1954 (define_expand "iordi3"
1955 [(set (match_operand:DI 0 "register_operand" "")
1956 (ior:DI (match_operand:DI 1 "arith_double_operand" "")
1957 (match_operand:DI 2 "arith_double_operand" "")))]
1962 [(set (match_operand:DI 0 "register_operand" "=r")
1963 (ior:DI (match_operand:DI 1 "arith_double_operand" "%r")
1964 (match_operand:DI 2 "arith_double_operand" "rHI")))]
1968 rtx op2 = operands[2];
1970 /* If constant is positive, upper bits zeroed, otherwise unchanged.
1971 Give the assembler a chance to pick the move instruction. */
1972 if (GET_CODE (op2) == CONST_INT)
1974 int sign = INTVAL (op2);
1976 return \"mov -1,%0\;or %R1,%2,%R0\";
1977 return \"mov %1,%0\;or %R1,%2,%R0\";
1979 else if (GET_CODE (op2) == CONST_DOUBLE)
1981 int sign = CONST_DOUBLE_HIGH (op2);
1982 operands[2] = gen_rtx (CONST_INT, VOIDmode,
1983 CONST_DOUBLE_LOW (operands[1]));
1985 return \"mov -1,%0\;or %R1,%2,%R0\";
1986 return \"mov %1,%0\;or %R1,%2,%R0\";
1988 return \"or %1,%2,%0\;or %R1,%R2,%R0\";
1990 [(set_attr "length" "2")])
1992 (define_insn "iorsi3"
1993 [(set (match_operand:SI 0 "register_operand" "=r")
1994 (ior:SI (match_operand:SI 1 "arith_operand" "%r")
1995 (match_operand:SI 2 "arith_operand" "rI")))]
2000 [(set (match_operand:SI 0 "register_operand" "")
2001 (ior:SI (match_operand:SI 1 "register_operand" "")
2002 (match_operand:SI 2 "" "")))
2003 (clobber (match_operand:SI 3 "register_operand" ""))]
2004 "GET_CODE (operands[2]) == CONST_INT
2005 && !SMALL_INT (operands[2])
2006 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
2007 [(set (match_dup 3) (match_dup 4))
2008 (set (match_dup 0) (ior:SI (not:SI (match_dup 3)) (match_dup 1)))]
2011 operands[4] = gen_rtx (CONST_INT, VOIDmode, ~INTVAL (operands[2]));
2015 [(set (match_operand:DI 0 "register_operand" "=r")
2016 (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r"))
2017 (match_operand:DI 2 "register_operand" "r")))]
2019 "orn %2,%1,%0\;orn %R2,%R1,%R0"
2020 [(set_attr "length" "2")])
2023 [(set (match_operand:SI 0 "register_operand" "=r")
2024 (ior:SI (not:SI (match_operand:SI 1 "register_operand" "r"))
2025 (match_operand:SI 2 "register_operand" "r")))]
2029 (define_expand "xordi3"
2030 [(set (match_operand:DI 0 "register_operand" "")
2031 (xor:DI (match_operand:DI 1 "arith_double_operand" "")
2032 (match_operand:DI 2 "arith_double_operand" "")))]
2037 [(set (match_operand:DI 0 "register_operand" "=r")
2038 (xor:DI (match_operand:DI 1 "arith_double_operand" "%r")
2039 (match_operand:DI 2 "arith_double_operand" "rHI")))]
2043 rtx op2 = operands[2];
2045 /* If constant is positive, upper bits zeroed, otherwise unchanged.
2046 Give the assembler a chance to pick the move instruction. */
2047 if (GET_CODE (op2) == CONST_INT)
2049 int sign = INTVAL (op2);
2051 return \"xor %1,-1,%0\;xor %R1,%2,%R0\";
2052 return \"mov %1,%0\;xor %R1,%2,%R0\";
2054 else if (GET_CODE (op2) == CONST_DOUBLE)
2056 int sign = CONST_DOUBLE_HIGH (op2);
2057 operands[2] = gen_rtx (CONST_INT, VOIDmode,
2058 CONST_DOUBLE_LOW (operands[1]));
2060 return \"xor %1,-1,%0\;xor %R1,%2,%R0\";
2061 return \"mov %1,%0\;xor %R1,%2,%R0\";
2063 return \"xor %1,%2,%0\;xor %R1,%R2,%R0\";
2065 [(set_attr "length" "2")])
2067 (define_insn "xorsi3"
2068 [(set (match_operand:SI 0 "register_operand" "=r")
2069 (xor:SI (match_operand:SI 1 "arith_operand" "%rJ")
2070 (match_operand:SI 2 "arith_operand" "rI")))]
2075 [(set (match_operand:SI 0 "register_operand" "")
2076 (xor:SI (match_operand:SI 1 "register_operand" "")
2077 (match_operand:SI 2 "" "")))
2078 (clobber (match_operand:SI 3 "register_operand" ""))]
2079 "GET_CODE (operands[2]) == CONST_INT
2080 && !SMALL_INT (operands[2])
2081 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
2082 [(set (match_dup 3) (match_dup 4))
2083 (set (match_dup 0) (not:SI (xor:SI (match_dup 3) (match_dup 1))))]
2086 operands[4] = gen_rtx (CONST_INT, VOIDmode, ~INTVAL (operands[2]));
2090 [(set (match_operand:SI 0 "register_operand" "")
2091 (not:SI (xor:SI (match_operand:SI 1 "register_operand" "")
2092 (match_operand:SI 2 "" ""))))
2093 (clobber (match_operand:SI 3 "register_operand" ""))]
2094 "GET_CODE (operands[2]) == CONST_INT
2095 && !SMALL_INT (operands[2])
2096 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
2097 [(set (match_dup 3) (match_dup 4))
2098 (set (match_dup 0) (xor:SI (match_dup 3) (match_dup 1)))]
2101 operands[4] = gen_rtx (CONST_INT, VOIDmode, ~INTVAL (operands[2]));
2104 ;; xnor patterns. Note that (a ^ ~b) == (~a ^ b) == ~(a ^ b).
2105 ;; Combine now canonicalizes to the rightmost expression.
2107 [(set (match_operand:DI 0 "register_operand" "=r")
2108 (not:DI (xor:DI (match_operand:DI 1 "register_operand" "r")
2109 (match_operand:DI 2 "register_operand" "r"))))]
2111 "xnor %1,%2,%0\;xnor %R1,%R2,%R0"
2112 [(set_attr "length" "2")])
2115 [(set (match_operand:SI 0 "register_operand" "=r")
2116 (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
2117 (match_operand:SI 2 "arith_operand" "rI"))))]
2121 ;; These correspond to the above in the case where we also (or only)
2122 ;; want to set the condition code.
2127 (match_operator:SI 2 "cc_arithop"
2128 [(match_operand:SI 0 "arith_operand" "%r")
2129 (match_operand:SI 1 "arith_operand" "rI")])
2133 [(set_attr "type" "compare")])
2138 (match_operator:SI 3 "cc_arithop"
2139 [(match_operand:SI 1 "arith_operand" "%r")
2140 (match_operand:SI 2 "arith_operand" "rI")])
2142 (set (match_operand:SI 0 "register_operand" "=r")
2150 (not:SI (xor:SI (match_operand:SI 0 "reg_or_0_operand" "%rJ")
2151 (match_operand:SI 1 "arith_operand" "rI")))
2154 "xnorcc %r0,%1,%%g0"
2155 [(set_attr "type" "compare")])
2160 (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
2161 (match_operand:SI 2 "arith_operand" "rI")))
2163 (set (match_operand:SI 0 "register_operand" "=r")
2164 (not:SI (xor:SI (match_dup 1) (match_dup 2))))]
2171 (match_operator:SI 2 "cc_arithopn"
2172 [(not:SI (match_operand:SI 0 "arith_operand" "rI"))
2173 (match_operand:SI 1 "reg_or_0_operand" "rJ")])
2177 [(set_attr "type" "compare")])
2182 (match_operator:SI 3 "cc_arithopn"
2183 [(not:SI (match_operand:SI 1 "arith_operand" "rI"))
2184 (match_operand:SI 2 "reg_or_0_operand" "rJ")])
2186 (set (match_operand:SI 0 "register_operand" "=r")
2191 ;; We cannot use the "neg" pseudo insn because the Sun assembler
2192 ;; does not know how to make it work for constants.
2194 (define_insn "negdi2"
2195 [(set (match_operand:DI 0 "register_operand" "=r")
2196 (neg:DI (match_operand:DI 1 "register_operand" "r")))
2197 (clobber (reg:SI 0))]
2199 "subcc %%g0,%R1,%R0\;subx %%g0,%1,%0"
2200 [(set_attr "type" "unary")
2201 (set_attr "length" "2")])
2203 (define_insn "negsi2"
2204 [(set (match_operand:SI 0 "general_operand" "=r")
2205 (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
2208 [(set_attr "type" "unary")])
2211 [(set (reg:CC_NOOV 0)
2212 (compare:CC_NOOV (neg:SI (match_operand:SI 0 "arith_operand" "rI"))
2215 "subcc %%g0,%0,%%g0"
2216 [(set_attr "type" "compare")])
2219 [(set (reg:CC_NOOV 0)
2220 (compare:CC_NOOV (neg:SI (match_operand:SI 1 "arith_operand" "rI"))
2222 (set (match_operand:SI 0 "register_operand" "=r")
2223 (neg:SI (match_dup 1)))]
2226 [(set_attr "type" "unary")])
2228 ;; We cannot use the "not" pseudo insn because the Sun assembler
2229 ;; does not know how to make it work for constants.
2230 (define_expand "one_cmpldi2"
2231 [(set (match_operand:DI 0 "register_operand" "=r")
2232 (not:DI (match_operand:DI 1 "arith_double_operand" "rHI")))]
2237 [(set (match_operand:DI 0 "register_operand" "=r")
2238 (not:DI (match_operand:DI 1 "arith_double_operand" "rHI")))]
2242 rtx op1 = operands[1];
2244 if (GET_CODE (op1) == CONST_INT)
2246 int sign = INTVAL (op1);
2248 return \"xnor %%g0,%1,%R0\;xnor %%g0,-1,%0\";
2249 return \"xnor %%g0,%1,%R0\;xnor %%g0,0,%0\";
2251 else if (GET_CODE (op1) == CONST_DOUBLE)
2253 int sign = CONST_DOUBLE_HIGH (op1);
2254 operands[1] = gen_rtx (CONST_INT, VOIDmode,
2255 CONST_DOUBLE_LOW (operands[1]));
2257 return \"xnor %%g0,%1,%R0\;xnor %%g0,-1,%0\";
2258 return \"xnor %%g0,%1,%R0\;xnor %%g0,0,%0\";
2260 return \"xnor %%g0,%1,%0\;xnor %%g0,%R1,%R0\";
2262 [(set_attr "type" "unary")
2263 (set_attr "length" "2")])
2265 (define_insn "one_cmplsi2"
2266 [(set (match_operand:SI 0 "register_operand" "=r")
2267 (not:SI (match_operand:SI 1 "arith_operand" "rI")))]
2270 [(set_attr "type" "unary")])
2274 (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI"))
2277 "xnorcc %%g0,%0,%%g0"
2278 [(set_attr "type" "compare")])
2282 (compare:CC (not:SI (match_operand:SI 1 "arith_operand" "rI"))
2284 (set (match_operand:SI 0 "register_operand" "=r")
2285 (not:SI (match_dup 1)))]
2288 [(set_attr "type" "unary")])
2290 ;; Floating point arithmetic instructions.
2292 (define_insn "addtf3"
2293 [(set (match_operand:TF 0 "register_operand" "=f")
2294 (plus:TF (match_operand:TF 1 "register_operand" "f")
2295 (match_operand:TF 2 "register_operand" "f")))]
2298 [(set_attr "type" "fp")])
2300 (define_insn "adddf3"
2301 [(set (match_operand:DF 0 "register_operand" "=f")
2302 (plus:DF (match_operand:DF 1 "register_operand" "f")
2303 (match_operand:DF 2 "register_operand" "f")))]
2306 [(set_attr "type" "fp")])
2308 (define_insn "addsf3"
2309 [(set (match_operand:SF 0 "register_operand" "=f")
2310 (plus:SF (match_operand:SF 1 "register_operand" "f")
2311 (match_operand:SF 2 "register_operand" "f")))]
2314 [(set_attr "type" "fp")])
2316 (define_insn "subtf3"
2317 [(set (match_operand:TF 0 "register_operand" "=f")
2318 (minus:TF (match_operand:TF 1 "register_operand" "f")
2319 (match_operand:TF 2 "register_operand" "f")))]
2322 [(set_attr "type" "fp")])
2324 (define_insn "subdf3"
2325 [(set (match_operand:DF 0 "register_operand" "=f")
2326 (minus:DF (match_operand:DF 1 "register_operand" "f")
2327 (match_operand:DF 2 "register_operand" "f")))]
2330 [(set_attr "type" "fp")])
2332 (define_insn "subsf3"
2333 [(set (match_operand:SF 0 "register_operand" "=f")
2334 (minus:SF (match_operand:SF 1 "register_operand" "f")
2335 (match_operand:SF 2 "register_operand" "f")))]
2338 [(set_attr "type" "fp")])
2340 (define_insn "multf3"
2341 [(set (match_operand:TF 0 "register_operand" "=f")
2342 (mult:TF (match_operand:TF 1 "register_operand" "f")
2343 (match_operand:TF 2 "register_operand" "f")))]
2346 [(set_attr "type" "fpmul")])
2348 (define_insn "muldf3"
2349 [(set (match_operand:DF 0 "register_operand" "=f")
2350 (mult:DF (match_operand:DF 1 "register_operand" "f")
2351 (match_operand:DF 2 "register_operand" "f")))]
2354 [(set_attr "type" "fpmul")])
2356 (define_insn "mulsf3"
2357 [(set (match_operand:SF 0 "register_operand" "=f")
2358 (mult:SF (match_operand:SF 1 "register_operand" "f")
2359 (match_operand:SF 2 "register_operand" "f")))]
2362 [(set_attr "type" "fpmul")])
2365 [(set (match_operand:DF 0 "register_operand" "=f")
2366 (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "f"))
2367 (float_extend:DF (match_operand:SF 2 "register_operand" "f"))))]
2368 "TARGET_V8 && TARGET_FPU"
2370 [(set_attr "type" "fpmul")])
2373 [(set (match_operand:TF 0 "register_operand" "=f")
2374 (mult:TF (float_extend:TF (match_operand:DF 1 "register_operand" "f"))
2375 (float_extend:TF (match_operand:DF 2 "register_operand" "f"))))]
2376 "TARGET_V8 && TARGET_FPU"
2378 [(set_attr "type" "fpmul")])
2380 (define_insn "divtf3"
2381 [(set (match_operand:TF 0 "register_operand" "=f")
2382 (div:TF (match_operand:TF 1 "register_operand" "f")
2383 (match_operand:TF 2 "register_operand" "f")))]
2386 [(set_attr "type" "fpdiv")])
2388 (define_insn "divdf3"
2389 [(set (match_operand:DF 0 "register_operand" "=f")
2390 (div:DF (match_operand:DF 1 "register_operand" "f")
2391 (match_operand:DF 2 "register_operand" "f")))]
2394 [(set_attr "type" "fpdiv")])
2396 (define_insn "divsf3"
2397 [(set (match_operand:SF 0 "register_operand" "=f")
2398 (div:SF (match_operand:SF 1 "register_operand" "f")
2399 (match_operand:SF 2 "register_operand" "f")))]
2402 [(set_attr "type" "fpdiv")])
2404 (define_insn "negtf2"
2405 [(set (match_operand:TF 0 "register_operand" "=f,f")
2406 (neg:TF (match_operand:TF 1 "register_operand" "0,f")))]
2410 fnegs %1,%0\;fmovs %R1,%R0\;fmovs %S1,%S0\;fmovs %T1,%T0"
2411 [(set_attr "type" "fp")
2412 (set_attr "length" "1,4")])
2414 (define_insn "negdf2"
2415 [(set (match_operand:DF 0 "register_operand" "=f,f")
2416 (neg:DF (match_operand:DF 1 "register_operand" "0,f")))]
2420 fnegs %1,%0\;fmovs %R1,%R0"
2421 [(set_attr "type" "fp")
2422 (set_attr "length" "1,2")])
2424 (define_insn "negsf2"
2425 [(set (match_operand:SF 0 "register_operand" "=f")
2426 (neg:SF (match_operand:SF 1 "register_operand" "f")))]
2429 [(set_attr "type" "fp")])
2431 (define_insn "abstf2"
2432 [(set (match_operand:TF 0 "register_operand" "=f,f")
2433 (abs:TF (match_operand:TF 1 "register_operand" "0,f")))]
2437 fabss %1,%0\;fmovs %R1,%R0\;fmovs %S1,%S0\;fmovs %T1,%T0"
2438 [(set_attr "type" "fp")
2439 (set_attr "length" "1,4")])
2441 (define_insn "absdf2"
2442 [(set (match_operand:DF 0 "register_operand" "=f,f")
2443 (abs:DF (match_operand:DF 1 "register_operand" "0,f")))]
2447 fabss %1,%0\;fmovs %R1,%R0"
2448 [(set_attr "type" "fp")
2449 (set_attr "length" "1,2")])
2451 (define_insn "abssf2"
2452 [(set (match_operand:SF 0 "register_operand" "=f")
2453 (abs:SF (match_operand:SF 1 "register_operand" "f")))]
2456 [(set_attr "type" "fp")])
2458 (define_insn "sqrttf2"
2459 [(set (match_operand:TF 0 "register_operand" "=f")
2460 (sqrt:TF (match_operand:TF 1 "register_operand" "f")))]
2463 [(set_attr "type" "fpsqrt")])
2465 (define_insn "sqrtdf2"
2466 [(set (match_operand:DF 0 "register_operand" "=f")
2467 (sqrt:DF (match_operand:DF 1 "register_operand" "f")))]
2470 [(set_attr "type" "fpsqrt")])
2472 (define_insn "sqrtsf2"
2473 [(set (match_operand:SF 0 "register_operand" "=f")
2474 (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
2477 [(set_attr "type" "fpsqrt")])
2479 ;;- arithmetic shift instructions
2481 ;; We can trivially handle shifting the constant 1 by 64 bits.
2482 ;; For other shifts we use the library routine.
2483 ;; ??? Questionable, we can do better than this can't we?
2484 (define_expand "ashldi3"
2485 [(parallel [(set (match_operand:DI 0 "register_operand" "")
2486 (ashift:DI (match_operand:DI 1 "const_double_operand" "")
2487 (match_operand:SI 2 "register_operand" "")))
2488 (clobber (reg:SI 0))])]
2492 if (GET_CODE (operands[1]) == CONST_DOUBLE
2493 && CONST_DOUBLE_HIGH (operands[1]) == 0
2494 && CONST_DOUBLE_LOW (operands[1]) == 1)
2495 operands[1] = const1_rtx;
2496 else if (operands[1] != const1_rtx)
2500 ;; ??? Questionable, we can do better than this can't we?
2502 [(set (match_operand:DI 0 "register_operand" "=&r")
2503 (ashift:DI (const_int 1)
2504 (match_operand:SI 1 "register_operand" "r")))
2505 (clobber (reg:SI 0))]
2507 "subcc %1,32,%%g0\;addx %%g0,0,%R0\;xor %R0,1,%0\;sll %R0,%1,%R0\;sll %0,%1,%0"
2508 [(set_attr "type" "multi")
2509 (set_attr "length" "5")])
2511 (define_insn "ashlsi3"
2512 [(set (match_operand:SI 0 "register_operand" "=r")
2513 (ashift:SI (match_operand:SI 1 "register_operand" "r")
2514 (match_operand:SI 2 "arith_operand" "rI")))]
2518 (define_insn "ashrsi3"
2519 [(set (match_operand:SI 0 "register_operand" "=r")
2520 (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
2521 (match_operand:SI 2 "arith_operand" "rI")))]
2525 (define_insn "lshrsi3"
2526 [(set (match_operand:SI 0 "register_operand" "=r")
2527 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
2528 (match_operand:SI 2 "arith_operand" "rI")))]
2532 ;; Unconditional and other jump instructions
2533 ;; On the Sparc, by setting the annul bit on an unconditional branch, the
2534 ;; following insn is never executed. This saves us a nop. Dbx does not
2535 ;; handle such branches though, so we only use them when optimizing.
2537 [(set (pc) (label_ref (match_operand 0 "" "")))]
2540 [(set_attr "type" "uncond_branch")])
2542 (define_expand "tablejump"
2543 [(parallel [(set (pc) (match_operand:SI 0 "register_operand" "r"))
2544 (use (label_ref (match_operand 1 "" "")))])]
2548 /* We need to use the PC value in %o7 that was set up when the address
2549 of the label was loaded into a register, so we need different RTL. */
2552 emit_insn (gen_pic_tablejump (operands[0], operands[1]));
2557 (define_insn "pic_tablejump"
2558 [(set (pc) (match_operand:SI 0 "register_operand" "r"))
2559 (use (label_ref (match_operand 1 "" "")))
2563 [(set_attr "type" "uncond_branch")])
2566 [(set (pc) (match_operand:SI 0 "address_operand" "p"))
2567 (use (label_ref (match_operand 1 "" "")))]
2570 [(set_attr "type" "uncond_branch")])
2573 [(set (pc) (label_ref (match_operand 0 "" "")))
2574 (set (reg:SI 15) (label_ref (match_dup 0)))]
2577 [(set_attr "type" "uncond_branch")])
2579 ;; This pattern recognizes the "instruction" that appears in
2580 ;; a function call that wants a structure value,
2581 ;; to inform the called function if compiled with Sun CC.
2583 ; [(match_operand:SI 0 "immediate_operand" "")]
2584 ; "GET_CODE (operands[0]) == CONST_INT && INTVAL (operands[0]) > 0"
2586 ; [(set_attr "type" "marker")])
2588 ;;- jump to subroutine
2589 (define_expand "call"
2590 ;; Note that this expression is not used for generating RTL.
2591 ;; All the RTL is generated explicitly below.
2592 [(call (match_operand:SI 0 "call_operand" "")
2593 (match_operand 3 "" "i"))]
2594 ;; operands[2] is next_arg_register
2595 ;; operands[3] is struct_value_size_rtx.
2599 rtx fn_rtx, nregs_rtx;
2601 if (GET_CODE (XEXP (operands[0], 0)) == LABEL_REF)
2603 /* This is really a PIC sequence. We want to represent
2604 it as a funny jump so it's delay slots can be filled.
2606 ??? But if this really *is* a CALL, will not it clobber the
2607 call-clobbered registers? We lose this if it is a JUMP_INSN.
2608 Why cannot we have delay slots filled if it were a CALL? */
2610 if (INTVAL (operands[3]) > 0)
2611 emit_jump_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (3,
2612 gen_rtx (SET, VOIDmode, pc_rtx,
2613 XEXP (operands[0], 0)),
2615 gen_rtx (CLOBBER, VOIDmode,
2616 gen_rtx (REG, SImode, 15)))));
2618 emit_jump_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (2,
2619 gen_rtx (SET, VOIDmode, pc_rtx,
2620 XEXP (operands[0], 0)),
2621 gen_rtx (CLOBBER, VOIDmode,
2622 gen_rtx (REG, SImode, 15)))));
2626 fn_rtx = operands[0];
2628 /* Count the number of parameter registers being used by this call.
2629 if that argument is NULL, it means we are using them all, which
2630 means 6 on the sparc. */
2633 nregs_rtx = gen_rtx (CONST_INT, VOIDmode, REGNO (operands[2]) - 8);
2635 nregs_rtx = gen_rtx (CONST_INT, VOIDmode, 6);
2637 nregs_rtx = const0_rtx;
2640 if (INTVAL (operands[3]) > 0)
2641 emit_call_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (3,
2642 gen_rtx (CALL, VOIDmode, fn_rtx, nregs_rtx),
2644 gen_rtx (CLOBBER, VOIDmode,
2645 gen_rtx (REG, SImode, 15)))));
2647 emit_call_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (2,
2648 gen_rtx (CALL, VOIDmode, fn_rtx, nregs_rtx),
2649 gen_rtx (CLOBBER, VOIDmode,
2650 gen_rtx (REG, SImode, 15)))));
2654 /* If this call wants a structure value,
2655 emit an unimp insn to let the called function know about this. */
2656 if (INTVAL (operands[3]) > 0)
2658 rtx insn = emit_insn (operands[3]);
2659 SCHED_GROUP_P (insn) = 1;
2667 [(call (mem:SI (match_operand:SI 0 "call_operand_address" "S,r"))
2668 (match_operand 1 "" ""))
2669 (clobber (reg:SI 15))]
2670 ;;- Do not use operand 1 for most machines.
2674 return \"call %a0,%1%#\";
2676 [(set_attr "type" "call")])
2678 ;; This is a call that wants a structure value.
2680 [(call (mem:SI (match_operand:SI 0 "call_operand_address" "S,r"))
2681 (match_operand 1 "" ""))
2682 (match_operand 2 "immediate_operand" "")
2683 (clobber (reg:SI 15))]
2684 ;;- Do not use operand 1 for most machines.
2685 "GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
2688 return \"call %a0,%1\;nop\;unimp %2\";
2690 [(set_attr "type" "call_no_delay_slot")])
2692 (define_expand "call_value"
2693 [(set (match_operand 0 "register_operand" "=rf")
2694 (call (match_operand:SI 1 "" "")
2695 (match_operand 4 "" "")))]
2696 ;; operand 3 is next_arg_register
2700 rtx fn_rtx, nregs_rtx;
2703 fn_rtx = operands[1];
2707 nregs_rtx = gen_rtx (CONST_INT, VOIDmode, REGNO (operands[3]) - 8);
2709 nregs_rtx = gen_rtx (CONST_INT, VOIDmode, 6);
2711 nregs_rtx = const0_rtx;
2715 gen_rtx (SET, VOIDmode, operands[0],
2716 gen_rtx (CALL, VOIDmode, fn_rtx, nregs_rtx)),
2717 gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, 15)));
2719 emit_call_insn (gen_rtx (PARALLEL, VOIDmode, vec));
2725 [(set (match_operand 0 "" "=rf")
2726 (call (mem:SI (match_operand:SI 1 "call_operand_address" "rS"))
2727 (match_operand 2 "" "")))
2728 (clobber (reg:SI 15))]
2729 ;;- Do not use operand 2 for most machines.
2733 return \"call %a1,%2%#\";
2735 [(set_attr "type" "call")])
2737 (define_insn "return"
2740 "* return output_return (operands);"
2741 [(set_attr "type" "multi")])
2748 (define_insn "indirect_jump"
2749 [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
2752 [(set_attr "type" "uncond_branch")])
2754 (define_expand "nonlocal_goto"
2755 [(match_operand:SI 0 "general_operand" "")
2756 (match_operand:SI 1 "general_operand" "")
2757 (match_operand:SI 2 "general_operand" "")
2758 (match_operand:SI 3 "" "")]
2762 /* Trap instruction to flush all the registers window. */
2763 emit_insn (gen_rtx (UNSPEC_VOLATILE, VOIDmode,
2764 gen_rtvec (1, const0_rtx), 0));
2765 /* Load the fp value for the containing fn into %fp.
2766 This is needed because operands[2] refers to %fp.
2767 Virtual register instantiation fails if the virtual %fp isn't set from a
2768 register. Thus we must copy operands[0] into a register if it isn't
2770 if (GET_CODE (operands[0]) != REG)
2771 operands[0] = force_reg (SImode, operands[0]);
2772 emit_move_insn (virtual_stack_vars_rtx, operands[0]);
2773 /* Find the containing function's current nonlocal goto handler,
2774 which will do any cleanups and then jump to the label. */
2775 emit_move_insn (gen_rtx (REG, SImode, 8), operands[1]);
2776 /* Restore %fp from stack pointer value for containing function.
2777 The restore insn that follows will move this to %sp,
2778 and reload the appropriate value into %fp. */
2779 emit_move_insn (frame_pointer_rtx, operands[2]);
2780 /* Put in the static chain register the nonlocal label address. */
2781 emit_move_insn (static_chain_rtx, operands[3]);
2782 /* USE of frame_pointer_rtx added for consistency; not clear if
2784 emit_insn (gen_rtx (USE, VOIDmode, frame_pointer_rtx));
2785 emit_insn (gen_rtx (USE, VOIDmode, stack_pointer_rtx));
2786 emit_insn (gen_rtx (USE, VOIDmode, static_chain_rtx));
2787 emit_insn (gen_rtx (USE, VOIDmode, gen_rtx (REG, SImode, 8)));
2788 /* Return, restoring reg window and jumping to goto handler. */
2789 emit_insn (gen_rtx (UNSPEC_VOLATILE, VOIDmode,
2790 gen_rtvec (1, const0_rtx), 1));
2794 ;; Special trap insn to flush register windows.
2796 [(unspec_volatile [(const_int 0)] 0)]
2799 [(set_attr "type" "misc")])
2802 [(unspec_volatile [(const_int 0)] 1)]
2804 "jmp %%o0+0\;restore"
2805 [(set_attr "type" "misc")
2806 (set_attr "length" "2")])
2810 ;; The scan instruction searches from the most significant bit while ffs
2811 ;; searches from the least significant bit. The bit index and treatment of
2812 ;; zero also differ. It takes at least 7 instructions to get the proper
2813 ;; result. Here is an obvious 8 instruction seequence.
2815 (define_insn "ffssi2"
2816 [(set (match_operand:SI 0 "register_operand" "=&r")
2817 (ffs:SI (match_operand:SI 1 "register_operand" "r")))
2818 (clobber (match_scratch:SI 2 "=&r"))]
2820 "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"
2821 [(set_attr "type" "multi")
2822 (set_attr "length" "8")])
2824 ;; Split up troublesome insns for better scheduling. */
2826 ;; The following patterns are straightforward. They can be applied
2827 ;; either before or after register allocation.
2830 [(set (match_operator 0 "memop" [(match_operand:SI 1 "symbolic_operand" "")])
2831 (match_operand 2 "reg_or_0_operand" ""))
2832 (clobber (match_operand:SI 3 "register_operand" ""))]
2834 [(set (match_dup 3) (high:SI (match_dup 1)))
2835 (set (match_op_dup 0 [(lo_sum:SI (match_dup 3) (match_dup 1))])
2840 [(set (match_operator 0 "memop"
2841 [(match_operand:SI 1 "immediate_operand" "")])
2842 (match_operand 2 "general_operand" ""))
2843 (clobber (match_operand:SI 3 "register_operand" ""))]
2845 [(set (match_op_dup 0 [(match_dup 1)])
2849 operands[1] = legitimize_pic_address (operands[1], GET_MODE (operands[0]),
2854 [(set (match_operand 0 "register_operand" "")
2855 (match_operator 1 "memop"
2856 [(match_operand:SI 2 "immediate_operand" "")]))]
2859 (match_op_dup 1 [(match_dup 2)]))]
2862 operands[2] = legitimize_pic_address (operands[2], GET_MODE (operands[1]),
2866 ;; Sign- and Zero-extend operations can have symbolic memory operands.
2869 [(set (match_operand 0 "register_operand" "")
2870 (match_operator 1 "extend_op"
2871 [(match_operator 2 "memop"
2872 [(match_operand:SI 3 "immediate_operand" "")])]))]
2875 (match_op_dup 1 [(match_op_dup 2 [(match_dup 3)])]))]
2878 operands[3] = legitimize_pic_address (operands[3], GET_MODE (operands[2]),
2883 [(set (match_operand:SI 0 "register_operand" "")
2884 (match_operand:SI 1 "immediate_operand" ""))]
2885 "! flag_pic && (GET_CODE (operands[1]) == SYMBOL_REF
2886 || GET_CODE (operands[1]) == CONST
2887 || GET_CODE (operands[1]) == LABEL_REF)"
2888 [(set (match_dup 0) (high:SI (match_dup 1)))
2890 (lo_sum:SI (match_dup 0) (match_dup 1)))]
2893 ;; LABEL_REFs are not modified by `legitimize_pic_address`
2894 ;; so do not recurse infinitely in the PIC case.
2896 [(set (match_operand:SI 0 "register_operand" "")
2897 (match_operand:SI 1 "immediate_operand" ""))]
2898 "flag_pic && (GET_CODE (operands[1]) == SYMBOL_REF
2899 || GET_CODE (operands[1]) == CONST)"
2900 [(set (match_dup 0) (match_dup 1))]
2903 operands[1] = legitimize_pic_address (operands[1], Pmode, operands[0], 0);
2906 ;; These split sne/seq insns. The forms of the resulting insns are
2907 ;; somewhat bogus, but they avoid extra patterns and show data dependency.
2908 ;; Nothing will look at these in detail after splitting has occurred.
2911 [(set (match_operand:SI 0 "register_operand" "")
2912 (ne:SI (match_operand:SI 1 "register_operand" "") (const_int 0)))
2913 (clobber (reg:CC 0))]
2915 [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
2917 (set (match_dup 0) (ltu:SI (reg:CC 0) (const_int 0)))]
2921 [(set (match_operand:SI 0 "register_operand" "")
2922 (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "")
2924 (clobber (reg:CC 0))]
2926 [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
2928 (set (match_dup 0) (neg:SI (ltu:SI (reg:CC 0) (const_int 0))))]
2932 [(set (match_operand:SI 0 "register_operand" "")
2933 (eq:SI (match_operand:SI 1 "register_operand" "") (const_int 0)))
2934 (clobber (reg:CC 0))]
2936 [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
2938 (set (match_dup 0) (geu:SI (reg:CC 0) (const_int 0)))]
2942 [(set (match_operand:SI 0 "register_operand" "")
2943 (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "")
2945 (clobber (reg:CC 0))]
2947 [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
2949 (set (match_dup 0) (neg:SI (geu:SI (reg:CC 0) (const_int 0))))]
2953 [(set (match_operand:SI 0 "register_operand" "")
2954 (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "")
2956 (match_operand:SI 2 "register_operand" "")))
2957 (clobber (reg:CC 0))]
2959 [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
2961 (set (match_dup 0) (plus:SI (ltu:SI (reg:CC 0) (const_int 0))
2966 [(set (match_operand:SI 0 "register_operand" "")
2967 (minus:SI (match_operand:SI 2 "register_operand" "")
2968 (ne:SI (match_operand:SI 1 "register_operand" "")
2970 (clobber (reg:CC 0))]
2972 [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
2974 (set (match_dup 0) (minus:SI (match_dup 2)
2975 (ltu:SI (reg:CC 0) (const_int 0))))]
2979 [(set (match_operand:SI 0 "register_operand" "")
2980 (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "")
2982 (match_operand:SI 2 "register_operand" "")))
2983 (clobber (reg:CC 0))]
2985 [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
2987 (set (match_dup 0) (plus:SI (geu:SI (reg:CC 0) (const_int 0))
2992 [(set (match_operand:SI 0 "register_operand" "")
2993 (minus:SI (match_operand:SI 2 "register_operand" "")
2994 (eq:SI (match_operand:SI 1 "register_operand" "")
2996 (clobber (reg:CC 0))]
2998 [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
3000 (set (match_dup 0) (minus:SI (match_dup 2)
3001 (geu:SI (reg:CC 0) (const_int 0))))]
3004 ;; Peepholes go at the end.
3006 ;; Optimize consecutive loads or stores into ldd and std when possible.
3007 ;; The conditions in which we do this are very restricted and are
3008 ;; explained in the code for {registers,memory}_ok_for_ldd functions.
3011 [(set (match_operand:SI 0 "register_operand" "=rf")
3012 (match_operand:SI 1 "memory_operand" ""))
3013 (set (match_operand:SI 2 "register_operand" "=rf")
3014 (match_operand:SI 3 "memory_operand" ""))]
3015 "registers_ok_for_ldd_peep (operands[0], operands[2])
3016 && ! MEM_VOLATILE_P (operands[1]) && ! MEM_VOLATILE_P (operands[3])
3017 && addrs_ok_for_ldd_peep (XEXP (operands[1], 0), XEXP (operands[3], 0))"
3021 [(set (match_operand:SI 0 "memory_operand" "")
3022 (match_operand:SI 1 "register_operand" "rf"))
3023 (set (match_operand:SI 2 "memory_operand" "")
3024 (match_operand:SI 3 "register_operand" "rf"))]
3025 "registers_ok_for_ldd_peep (operands[1], operands[3])
3026 && ! MEM_VOLATILE_P (operands[0]) && ! MEM_VOLATILE_P (operands[2])
3027 && addrs_ok_for_ldd_peep (XEXP (operands[0], 0), XEXP (operands[2], 0))"
3031 [(set (match_operand:SF 0 "register_operand" "=fr")
3032 (match_operand:SF 1 "memory_operand" ""))
3033 (set (match_operand:SF 2 "register_operand" "=fr")
3034 (match_operand:SF 3 "memory_operand" ""))]
3035 "registers_ok_for_ldd_peep (operands[0], operands[2])
3036 && ! MEM_VOLATILE_P (operands[1]) && ! MEM_VOLATILE_P (operands[3])
3037 && addrs_ok_for_ldd_peep (XEXP (operands[1], 0), XEXP (operands[3], 0))"
3041 [(set (match_operand:SF 0 "memory_operand" "")
3042 (match_operand:SF 1 "register_operand" "fr"))
3043 (set (match_operand:SF 2 "memory_operand" "")
3044 (match_operand:SF 3 "register_operand" "fr"))]
3045 "registers_ok_for_ldd_peep (operands[1], operands[3])
3046 && ! MEM_VOLATILE_P (operands[0]) && ! MEM_VOLATILE_P (operands[2])
3047 && addrs_ok_for_ldd_peep (XEXP (operands[0], 0), XEXP (operands[2], 0))"
3051 [(set (match_operand:SI 0 "register_operand" "=rf")
3052 (match_operand:SI 1 "memory_operand" ""))
3053 (set (match_operand:SI 2 "register_operand" "=rf")
3054 (match_operand:SI 3 "memory_operand" ""))]
3055 "registers_ok_for_ldd_peep (operands[2], operands[0])
3056 && ! MEM_VOLATILE_P (operands[3]) && ! MEM_VOLATILE_P (operands[1])
3057 && addrs_ok_for_ldd_peep (XEXP (operands[3], 0), XEXP (operands[1], 0))"
3061 [(set (match_operand:SI 0 "memory_operand" "")
3062 (match_operand:SI 1 "register_operand" "rf"))
3063 (set (match_operand:SI 2 "memory_operand" "")
3064 (match_operand:SI 3 "register_operand" "rf"))]
3065 "registers_ok_for_ldd_peep (operands[3], operands[1])
3066 && ! MEM_VOLATILE_P (operands[2]) && ! MEM_VOLATILE_P (operands[0])
3067 && addrs_ok_for_ldd_peep (XEXP (operands[2], 0), XEXP (operands[0], 0))"
3071 [(set (match_operand:SF 0 "register_operand" "=fr")
3072 (match_operand:SF 1 "memory_operand" ""))
3073 (set (match_operand:SF 2 "register_operand" "=fr")
3074 (match_operand:SF 3 "memory_operand" ""))]
3075 "registers_ok_for_ldd_peep (operands[2], operands[0])
3076 && ! MEM_VOLATILE_P (operands[3]) && ! MEM_VOLATILE_P (operands[1])
3077 && addrs_ok_for_ldd_peep (XEXP (operands[3], 0), XEXP (operands[1], 0))"
3081 [(set (match_operand:SF 0 "memory_operand" "")
3082 (match_operand:SF 1 "register_operand" "fr"))
3083 (set (match_operand:SF 2 "memory_operand" "")
3084 (match_operand:SF 3 "register_operand" "fr"))]
3085 "registers_ok_for_ldd_peep (operands[3], operands[1])
3086 && ! MEM_VOLATILE_P (operands[2]) && ! MEM_VOLATILE_P (operands[0])
3087 && addrs_ok_for_ldd_peep (XEXP (operands[2], 0), XEXP (operands[0], 0))"
3090 ;; Optimize the case of following a reg-reg move with a test
3091 ;; of reg just moved. Don't allow floating point regs for operand 0 or 1.
3092 ;; This can result from a float to fix conversion.
3095 [(set (match_operand:SI 0 "register_operand" "=r")
3096 (match_operand:SI 1 "register_operand" "r"))
3098 (compare:CC (match_operand:SI 2 "register_operand" "r")
3100 "(rtx_equal_p (operands[2], operands[0])
3101 || rtx_equal_p (operands[2], operands[1]))
3102 && ! FP_REG_P (operands[0]) && ! FP_REG_P (operands[1])"
3105 ;; Do {sign,zero}-extended compares somewhat more efficiently.
3106 ;; ??? Is this now the Right Way to do this? Or will SCRATCH
3107 ;; eventually have some impact here?
3110 [(set (match_operand:HI 0 "register_operand" "")
3111 (match_operand:HI 1 "memory_operand" ""))
3112 (set (match_operand:SI 2 "register_operand" "")
3113 (sign_extend:SI (match_dup 0)))
3115 (compare:CC (match_dup 2)
3118 "ldsh %1,%0\;orcc %0,%%g0,%2")
3121 [(set (match_operand:QI 0 "register_operand" "")
3122 (match_operand:QI 1 "memory_operand" ""))
3123 (set (match_operand:SI 2 "register_operand" "")
3124 (sign_extend:SI (match_dup 0)))
3126 (compare:CC (match_dup 2)
3129 "ldsb %1,%0\;orcc %0,%%g0,%2")
3132 [(set (match_operand:HI 0 "register_operand" "")
3133 (match_operand:HI 1 "memory_operand" ""))
3134 (set (match_operand:SI 2 "register_operand" "")
3135 (sign_extend:SI (match_dup 0)))]
3136 "dead_or_set_p (insn, operands[0])"
3139 warning (\"bad peephole\");
3140 if (! MEM_VOLATILE_P (operands[1]))
3142 return \"ldsh %1,%2\";
3146 [(set (match_operand:QI 0 "register_operand" "")
3147 (match_operand:QI 1 "memory_operand" ""))
3148 (set (match_operand:SI 2 "register_operand" "")
3149 (sign_extend:SI (match_dup 0)))]
3150 "dead_or_set_p (insn, operands[0])"
3153 warning (\"bad peephole\");
3154 if (! MEM_VOLATILE_P (operands[1]))
3156 return \"ldsb %1,%2\";
3159 ;; Floating-point move peepholes
3162 [(set (match_operand:SI 0 "register_operand" "=r")
3163 (lo_sum:SI (match_dup 0)
3164 (match_operand:SI 1 "immediate_operand" "i")))
3165 (set (match_operand:DF 2 "register_operand" "=fr")
3166 (mem:DF (match_dup 0)))]
3167 "RTX_UNCHANGING_P (operands[1]) && reg_unused_after (operands[0], insn)"
3170 /* Go by way of output_move_double in case the register in operand 2
3171 is not properly aligned for ldd. */
3172 operands[1] = gen_rtx (MEM, DFmode,
3173 gen_rtx (LO_SUM, SImode, operands[0], operands[1]));
3174 operands[0] = operands[2];
3175 return output_move_double (operands);
3179 [(set (match_operand:SI 0 "register_operand" "=r")
3180 (lo_sum:SI (match_dup 0)
3181 (match_operand:SI 1 "immediate_operand" "i")))
3182 (set (match_operand:SF 2 "register_operand" "=fr")
3183 (mem:SF (match_dup 0)))]
3184 "RTX_UNCHANGING_P (operands[1]) && reg_unused_after (operands[0], insn)"
3185 "ld [%0+%%lo(%a1)],%2")
3187 ;; Return peepholes. First the "normal" ones
3189 ;; ??? There are QImode, HImode, and SImode versions of this pattern.
3190 ;; It might be possible to write one more general pattern instead of three.
3193 [(set (match_operand:QI 0 "restore_operand" "")
3194 (match_operand:QI 1 "arith_operand" "rI"))
3199 if (current_function_returns_struct)
3200 return \"jmp %%i7+12\;restore %%g0,%1,%Y0\";
3202 return \"ret\;restore %%g0,%1,%Y0\";
3204 [(set_attr "type" "multi")])
3207 [(set (match_operand:HI 0 "restore_operand" "")
3208 (match_operand:HI 1 "arith_operand" "rI"))
3213 if (current_function_returns_struct)
3214 return \"jmp %%i7+12\;restore %%g0,%1,%Y0\";
3216 return \"ret\;restore %%g0,%1,%Y0\";
3218 [(set_attr "type" "multi")])
3221 [(set (match_operand:SI 0 "restore_operand" "")
3222 (match_operand:SI 1 "arith_operand" "rI"))
3227 if (current_function_returns_struct)
3228 return \"jmp %%i7+12\;restore %%g0,%1,%Y0\";
3230 return \"ret\;restore %%g0,%1,%Y0\";
3232 [(set_attr "type" "multi")])
3234 ;; The following pattern is only generated by delayed-branch scheduling,
3235 ;; when the insn winds up in the epilogue. This can only happen when
3236 ;; ! TARGET_FPU because otherwise fp return values are in %f0.
3238 [(set (match_operand:SF 0 "restore_operand" "r")
3239 (match_operand:SF 1 "register_operand" "r"))
3241 "! TARGET_FPU && ! TARGET_EPILOGUE"
3244 if (current_function_returns_struct)
3245 return \"jmp %%i7+12\;restore %%g0,%1,%Y0\";
3247 return \"ret\;restore %%g0,%1,%Y0\";
3249 [(set_attr "type" "multi")])
3252 [(set (match_operand:SI 0 "restore_operand" "")
3253 (plus:SI (match_operand:SI 1 "arith_operand" "%r")
3254 (match_operand:SI 2 "arith_operand" "rI")))
3259 if (current_function_returns_struct)
3260 return \"jmp %%i7+12\;restore %r1,%2,%Y0\";
3262 return \"ret\;restore %r1,%2,%Y0\";
3264 [(set_attr "type" "multi")])
3266 ;; Turned off because it should never match (subtracting a constant
3267 ;; is turned into addition) and because it would do the wrong thing
3268 ;; when operand 2 is -4096 (--4096 == 4096 is not a valid immediate).
3270 ;; [(set (match_operand:SI 0 "restore_operand" "")
3271 ;; (minus:SI (match_operand:SI 1 "register_operand" "r")
3272 ;; (match_operand:SI 2 "small_int" "I")))
3274 ;; "! TARGET_EPILOGUE"
3275 ;; "ret\;restore %1,-(%2),%Y0"
3276 ;; [(set_attr "type" "multi")])
3278 ;; The following pattern is only generated by delayed-branch scheduling,
3279 ;; when the insn winds up in the epilogue.
3282 (match_operand:SF 0 "register_operand" "f"))
3285 "ret\;fmovs %0,%%f0"
3286 [(set_attr "type" "multi")])
3288 ;; Now peepholes to go a call followed by a jump.
3291 [(parallel [(set (match_operand 0 "" "")
3292 (call (mem:SI (match_operand:SI 1 "call_operand_address" "S,r"))
3293 (match_operand 2 "" "")))
3294 (clobber (reg:SI 15))])
3295 (set (pc) (label_ref (match_operand 3 "" "")))]
3296 "short_branch (INSN_UID (insn), INSN_UID (operands[3]))"
3299 return \"call %a1,%2\;add %%o7,(%l3-.-4),%%o7\";
3303 [(parallel [(call (mem:SI (match_operand:SI 0 "call_operand_address" "S,r"))
3304 (match_operand 1 "" ""))
3305 (clobber (reg:SI 15))])
3306 (set (pc) (label_ref (match_operand 2 "" "")))]
3307 "short_branch (INSN_UID (insn), INSN_UID (operands[2]))"
3310 return \"call %a0,%1\;add %%o7,(%l2-.-4),%%o7\";
3314 [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
3315 (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
3317 (clobber (reg:CC 0))])
3318 (set (reg:CC 0) (compare (match_dup 0) (const_int 0)))]
3322 ;;- Local variables:
3324 ;;- comment-start: ";;- "
3325 ;;- eval: (set-syntax-table (copy-sequence (syntax-table)))
3326 ;;- eval: (modify-syntax-entry ?[ "(]")
3327 ;;- eval: (modify-syntax-entry ?] ")[")
3328 ;;- eval: (modify-syntax-entry ?{ "(}")
3329 ;;- eval: (modify-syntax-entry ?} "){")