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")
810 (match_operand:SI 1 "move_operand" "rI,K,Q,!Q,rJ,!f"))]
811 "register_operand (operands[0], SImode)
812 || register_operand (operands[1], SImode)
813 || operands[1] == const0_rtx"
821 [(set_attr "type" "move,move,load,load,store,store")
822 (set_attr "length" "*,1,*,*,*,*")])
824 ;; Special pic pattern, for loading the address of a label into a register.
825 ;; It clobbers o7 because the call puts the return address (i.e. pc value)
829 [(set (match_operand:SI 0 "register_operand" "=r")
830 (match_operand:SI 1 "move_pic_label" "i"))
831 (set (reg:SI 15) (pc))]
833 "\\n1:\;call 2f\;sethi %%hi(%l1-1b),%0\\n2:\\tor %0,%%lo(%l1-1b),%0\;add %0,%%o7,%0"
834 [(set_attr "type" "multi")
835 (set_attr "length" "4")])
838 [(set (match_operand:DI 0 "register_operand" "=r")
839 (high:DI (match_operand 1 "" "")))]
843 rtx op0 = operands[0];
844 rtx op1 = operands[1];
846 if (GET_CODE (op1) == CONST_INT)
848 operands[0] = operand_subword (op0, 1, 0, DImode);
849 output_asm_insn (\"sethi %%hi(%a1),%0\", operands);
851 operands[0] = operand_subword (op0, 0, 0, DImode);
852 if (INTVAL (op1) < 0)
853 output_asm_insn (\"mov -1,%0\", operands);
855 output_asm_insn (\"mov 0,%0\", operands);
857 else if (GET_CODE (op1) == CONST_DOUBLE)
859 operands[0] = operand_subword (op0, 1, 0, DImode);
860 operands[1] = gen_rtx (CONST_INT, VOIDmode, CONST_DOUBLE_LOW (op1));
861 output_asm_insn (\"sethi %%hi(%a1),%0\", operands);
863 operands[0] = operand_subword (op0, 0, 0, DImode);
864 operands[1] = gen_rtx (CONST_INT, VOIDmode, CONST_DOUBLE_HIGH (op1));
865 output_asm_insn (singlemove_string (operands), operands);
870 [(set_attr "type" "move")
871 (set_attr "length" "2")])
873 ;; For PIC, symbol_refs are put inside unspec so that the optimizer won't
874 ;; confuse them with real addresses.
876 [(set (match_operand:SI 0 "register_operand" "=r")
877 (high:SI (unspec:SI [(match_operand 1 "" "")] 0)))]
880 [(set_attr "type" "move")
881 (set_attr "length" "1")])
884 [(set (match_operand:SI 0 "register_operand" "=r")
885 (high:SI (match_operand 1 "" "")))]
888 [(set_attr "type" "move")
889 (set_attr "length" "1")])
892 [(set (match_operand:HI 0 "register_operand" "=r")
893 (high:HI (match_operand 1 "" "")))]
896 [(set_attr "type" "move")
897 (set_attr "length" "1")])
900 [(set (match_operand:DI 0 "register_operand" "=r")
901 (lo_sum:DI (match_operand:DI 1 "register_operand" "0")
902 (match_operand:DI 2 "immediate_operand" "in")))]
906 /* Don't output a 64 bit constant, since we can't trust the assembler to
907 handle it correctly. */
908 if (GET_CODE (operands[2]) == CONST_DOUBLE)
909 operands[2] = gen_rtx (CONST_INT, VOIDmode, CONST_DOUBLE_LOW (operands[2]));
910 return \"or %R1,%%lo(%a2),%R0\";
912 ;; Need to set length for this arith insn because operand2
913 ;; is not an "arith_operand".
914 [(set_attr "length" "1")])
916 ;; For PIC, symbol_refs are put inside unspec so that the optimizer won't
917 ;; confuse them with real addresses.
919 [(set (match_operand:SI 0 "register_operand" "=r")
920 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
921 (unspec:SI [(match_operand:SI 2 "immediate_operand" "in")] 0)))]
924 ;; Need to set length for this arith insn because operand2
925 ;; is not an "arith_operand".
926 [(set_attr "length" "1")])
929 [(set (match_operand:SI 0 "register_operand" "=r")
930 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
931 (match_operand:SI 2 "immediate_operand" "in")))]
934 ;; Need to set length for this arith insn because operand2
935 ;; is not an "arith_operand".
936 [(set_attr "length" "1")])
939 [(set (mem:SI (match_operand:SI 0 "symbolic_operand" ""))
940 (match_operand:SI 1 "reg_or_0_operand" "rJ"))
941 (clobber (match_scratch:SI 2 "=&r"))]
943 "sethi %%hi(%a0),%2\;st %r1,[%2+%%lo(%a0)]"
944 [(set_attr "type" "store")
945 (set_attr "length" "2")])
947 (define_expand "movhi"
948 [(set (match_operand:HI 0 "general_operand" "")
949 (match_operand:HI 1 "general_operand" ""))]
953 if (emit_move_sequence (operands, HImode, 0))
958 [(set (match_operand:HI 0 "reg_or_nonsymb_mem_operand" "=r,r,r,Q")
959 (match_operand:HI 1 "move_operand" "rI,K,Q,rJ"))]
960 "register_operand (operands[0], HImode)
961 || register_operand (operands[1], HImode)
962 || operands[1] == const0_rtx"
968 [(set_attr "type" "move,move,load,store")
969 (set_attr "length" "*,1,*,1")])
972 [(set (match_operand:HI 0 "register_operand" "=r")
973 (lo_sum:HI (match_operand:HI 1 "register_operand" "r")
974 (match_operand 2 "immediate_operand" "in")))]
977 [(set_attr "length" "1")])
980 [(set (mem:HI (match_operand:SI 0 "symbolic_operand" ""))
981 (match_operand:HI 1 "reg_or_0_operand" "rJ"))
982 (clobber (match_scratch:SI 2 "=&r"))]
984 "sethi %%hi(%a0),%2\;sth %r1,[%2+%%lo(%a0)]"
985 [(set_attr "type" "store")
986 (set_attr "length" "2")])
988 (define_expand "movqi"
989 [(set (match_operand:QI 0 "general_operand" "")
990 (match_operand:QI 1 "general_operand" ""))]
994 if (emit_move_sequence (operands, QImode, 0))
999 [(set (match_operand:QI 0 "reg_or_nonsymb_mem_operand" "=r,r,r,Q")
1000 (match_operand:QI 1 "move_operand" "rI,K,Q,rJ"))]
1001 "register_operand (operands[0], QImode)
1002 || register_operand (operands[1], QImode)
1003 || operands[1] == const0_rtx"
1009 [(set_attr "type" "move,move,load,store")
1010 (set_attr "length" "*,1,*,1")])
1013 [(set (match_operand:QI 0 "register_operand" "=r")
1014 (subreg:QI (lo_sum:SI (match_operand:QI 1 "register_operand" "r")
1015 (match_operand 2 "immediate_operand" "in")) 0))]
1017 "or %1,%%lo(%a2),%0"
1018 [(set_attr "length" "1")])
1021 [(set (mem:QI (match_operand:SI 0 "symbolic_operand" ""))
1022 (match_operand:QI 1 "reg_or_0_operand" "rJ"))
1023 (clobber (match_scratch:SI 2 "=&r"))]
1025 "sethi %%hi(%a0),%2\;stb %r1,[%2+%%lo(%a0)]"
1026 [(set_attr "type" "store")
1027 (set_attr "length" "2")])
1029 ;; The definition of this insn does not really explain what it does,
1030 ;; but it should suffice
1031 ;; that anything generated as this insn will be recognized as one
1032 ;; and that it will not successfully combine with anything.
1033 (define_expand "movstrsi"
1034 [(parallel [(set (mem:BLK (match_operand:BLK 0 "general_operand" ""))
1035 (mem:BLK (match_operand:BLK 1 "general_operand" "")))
1036 (use (match_operand:SI 2 "nonmemory_operand" ""))
1037 (use (match_operand:SI 3 "immediate_operand" ""))
1038 (clobber (match_dup 0))
1039 (clobber (match_dup 1))
1040 (clobber (match_scratch:SI 4 ""))
1041 (clobber (reg:SI 0))
1042 (clobber (reg:SI 1))])]
1046 /* If the size isn't known, don't emit inline code. output_block_move
1047 would output code that's much slower than the library function.
1048 Also don't output code for large blocks. */
1049 if (GET_CODE (operands[2]) != CONST_INT
1050 || GET_CODE (operands[3]) != CONST_INT
1051 || INTVAL (operands[2]) / INTVAL (operands[3]) > 16)
1054 operands[0] = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
1055 operands[1] = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
1056 operands[2] = force_not_mem (operands[2]);
1060 [(set (mem:BLK (match_operand:SI 0 "register_operand" "+r"))
1061 (mem:BLK (match_operand:SI 1 "register_operand" "+r")))
1062 (use (match_operand:SI 2 "nonmemory_operand" "rn"))
1063 (use (match_operand:SI 3 "immediate_operand" "i"))
1064 (clobber (match_dup 0))
1065 (clobber (match_dup 1))
1066 (clobber (match_scratch:SI 4 "=&r"))
1067 (clobber (reg:SI 0))
1068 (clobber (reg:SI 1))]
1070 "* return output_block_move (operands);"
1071 [(set_attr "type" "multi")
1072 (set_attr "length" "6")])
1074 ;; Floating point move insns
1076 ;; This pattern forces (set (reg:TF ...) (const_double ...))
1077 ;; to be reloaded by putting the constant into memory.
1078 ;; It must come before the more general movtf pattern.
1080 [(set (match_operand:TF 0 "general_operand" "=?r,f,o")
1081 (match_operand:TF 1 "" "?E,m,G"))]
1082 "TARGET_FPU && GET_CODE (operands[1]) == CONST_DOUBLE"
1085 switch (which_alternative)
1088 return output_move_quad (operands);
1090 return output_fp_move_quad (operands);
1092 operands[1] = adj_offsettable_operand (operands[0], 4);
1093 operands[2] = adj_offsettable_operand (operands[0], 8);
1094 operands[3] = adj_offsettable_operand (operands[0], 12);
1095 return \"st %%g0,%0\;st %%g0,%1\;st %%g0,%2\;st %%g0,%3\";
1098 [(set_attr "type" "load,fpload,store")
1099 (set_attr "length" "5,5,5")])
1101 (define_expand "movtf"
1102 [(set (match_operand:TF 0 "general_operand" "")
1103 (match_operand:TF 1 "general_operand" ""))]
1107 if (emit_move_sequence (operands, TFmode, 0))
1112 [(set (match_operand:TF 0 "reg_or_nonsymb_mem_operand" "=f,r,Q,Q,f,&r")
1113 (match_operand:TF 1 "reg_or_nonsymb_mem_operand" "f,r,f,r,Q,Q"))]
1115 && (register_operand (operands[0], TFmode)
1116 || register_operand (operands[1], TFmode))"
1119 if (FP_REG_P (operands[0]) || FP_REG_P (operands[1]))
1120 return output_fp_move_quad (operands);
1121 return output_move_quad (operands);
1123 [(set_attr "type" "fp,move,fpstore,store,fpload,load")
1124 (set_attr "length" "4,4,5,5,5,5")])
1126 ;; Exactly the same as above, except that all `f' cases are deleted.
1127 ;; This is necessary to prevent reload from ever trying to use a `f' reg
1131 [(set (match_operand:TF 0 "reg_or_nonsymb_mem_operand" "=r,Q,&r")
1132 (match_operand:TF 1 "reg_or_nonsymb_mem_operand" "r,r,Q"))]
1134 && (register_operand (operands[0], TFmode)
1135 || register_operand (operands[1], TFmode))"
1138 if (FP_REG_P (operands[0]) || FP_REG_P (operands[1]))
1139 return output_fp_move_quad (operands);
1140 return output_move_quad (operands);
1142 [(set_attr "type" "move,store,load")
1143 (set_attr "length" "4,5,5")])
1146 [(set (mem:TF (match_operand:SI 0 "symbolic_operand" "i,i"))
1147 (match_operand:TF 1 "reg_or_0_operand" "rf,G"))
1148 (clobber (match_scratch:SI 2 "=&r,&r"))]
1152 output_asm_insn (\"sethi %%hi(%a0),%2\", operands);
1153 if (which_alternative == 0)
1154 return \"std %1,[%2+%%lo(%a0)]\;std %S1,[%2+%%lo(%a0+8)]\";
1156 return \"st %%g0,[%2+%%lo(%a0)]\;st %%g0,[%2+%%lo(%a0+4)]\; st %%g0,[%2+%%lo(%a0+8)]\;st %%g0,[%2+%%lo(%a0+12)]\";
1158 [(set_attr "type" "store")
1159 (set_attr "length" "5")])
1161 ;; This pattern forces (set (reg:DF ...) (const_double ...))
1162 ;; to be reloaded by putting the constant into memory.
1163 ;; It must come before the more general movdf pattern.
1166 [(set (match_operand:DF 0 "general_operand" "=?r,f,o")
1167 (match_operand:DF 1 "" "?E,m,G"))]
1168 "TARGET_FPU && GET_CODE (operands[1]) == CONST_DOUBLE"
1171 switch (which_alternative)
1174 return output_move_double (operands);
1176 return output_fp_move_double (operands);
1178 operands[1] = adj_offsettable_operand (operands[0], 4);
1179 return \"st %%g0,%0\;st %%g0,%1\";
1182 [(set_attr "type" "load,fpload,store")
1183 (set_attr "length" "3,3,3")])
1185 (define_expand "movdf"
1186 [(set (match_operand:DF 0 "general_operand" "")
1187 (match_operand:DF 1 "general_operand" ""))]
1191 if (emit_move_sequence (operands, DFmode, 0))
1196 [(set (match_operand:DF 0 "reg_or_nonsymb_mem_operand" "=T,U,f,r,Q,Q,f,&r")
1197 (match_operand:DF 1 "reg_or_nonsymb_mem_operand" "U,T,f,r,f,r,Q,Q"))]
1199 && (register_operand (operands[0], DFmode)
1200 || register_operand (operands[1], DFmode))"
1203 if (FP_REG_P (operands[0]) || FP_REG_P (operands[1]))
1204 return output_fp_move_double (operands);
1205 return output_move_double (operands);
1207 [(set_attr "type" "fpstore,fpload,fp,move,fpstore,store,fpload,load")
1208 (set_attr "length" "1,1,2,2,3,3,3,3")])
1210 ;; Exactly the same as above, except that all `f' cases are deleted.
1211 ;; This is necessary to prevent reload from ever trying to use a `f' reg
1215 [(set (match_operand:DF 0 "reg_or_nonsymb_mem_operand" "=T,U,r,Q,&r")
1216 (match_operand:DF 1 "reg_or_nonsymb_mem_operand" "U,T,r,r,Q"))]
1218 && (register_operand (operands[0], DFmode)
1219 || register_operand (operands[1], DFmode))"
1220 "* return output_move_double (operands);"
1221 [(set_attr "type" "store,load,move,store,load")
1222 (set_attr "length" "1,1,2,3,3")])
1225 [(set (mem:DF (match_operand:SI 0 "symbolic_operand" "i,i"))
1226 (match_operand:DF 1 "reg_or_0_operand" "rf,G"))
1227 (clobber (match_scratch:SI 2 "=&r,&r"))]
1231 output_asm_insn (\"sethi %%hi(%a0),%2\", operands);
1232 if (which_alternative == 0)
1233 return \"std %1,[%2+%%lo(%a0)]\";
1235 return \"st %%g0,[%2+%%lo(%a0)]\;st %%g0,[%2+%%lo(%a0+4)]\";
1237 [(set_attr "type" "store")
1238 (set_attr "length" "3")])
1240 ;; Double-word move insns.
1242 (define_expand "movdi"
1243 [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand" "")
1244 (match_operand:DI 1 "general_operand" ""))]
1248 if (emit_move_sequence (operands, DImode, 0))
1253 [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand" "=r,Q,&r,&r,?f,?f,?Q")
1254 (match_operand:DI 1 "general_operand" "r,r,Q,i,f,Q,f"))]
1255 "register_operand (operands[0], DImode)
1256 || register_operand (operands[1], DImode)
1257 || operands[1] == const0_rtx"
1260 if (FP_REG_P (operands[0]) || FP_REG_P (operands[1]))
1261 return output_fp_move_double (operands);
1262 return output_move_double (operands);
1264 [(set_attr "type" "move,store,load,multi,fp,fpload,fpstore")
1265 (set_attr "length" "2,3,3,3,2,3,3")])
1267 ;; Floating-point move insns.
1269 ;; This pattern forces (set (reg:SF ...) (const_double ...))
1270 ;; to be reloaded by putting the constant into memory.
1271 ;; It must come before the more general movsf pattern.
1273 [(set (match_operand:SF 0 "general_operand" "=?r,f,m")
1274 (match_operand:SF 1 "" "?E,m,G"))]
1275 "TARGET_FPU && GET_CODE (operands[1]) == CONST_DOUBLE"
1278 switch (which_alternative)
1281 return singlemove_string (operands);
1283 return \"ld %1,%0\";
1285 return \"st %%g0,%0\";
1288 [(set_attr "type" "load,fpload,store")
1289 (set_attr "length" "2,1,1")])
1291 (define_expand "movsf"
1292 [(set (match_operand:SF 0 "general_operand" "")
1293 (match_operand:SF 1 "general_operand" ""))]
1297 if (emit_move_sequence (operands, SFmode, 0))
1302 [(set (match_operand:SF 0 "reg_or_nonsymb_mem_operand" "=f,r,f,r,Q,Q")
1303 (match_operand:SF 1 "reg_or_nonsymb_mem_operand" "f,r,Q,Q,f,r"))]
1305 && (register_operand (operands[0], SFmode)
1306 || register_operand (operands[1], SFmode))"
1314 [(set_attr "type" "fp,move,fpload,load,fpstore,store")])
1316 ;; Exactly the same as above, except that all `f' cases are deleted.
1317 ;; This is necessary to prevent reload from ever trying to use a `f' reg
1321 [(set (match_operand:SF 0 "reg_or_nonsymb_mem_operand" "=r,r,Q")
1322 (match_operand:SF 1 "reg_or_nonsymb_mem_operand" "r,Q,r"))]
1324 && (register_operand (operands[0], SFmode)
1325 || register_operand (operands[1], SFmode))"
1330 [(set_attr "type" "move,load,store")])
1333 [(set (mem:SF (match_operand:SI 0 "symbolic_operand" "i"))
1334 (match_operand:SF 1 "reg_or_0_operand" "rfG"))
1335 (clobber (match_scratch:SI 2 "=&r"))]
1337 "sethi %%hi(%a0),%2\;st %r1,[%2+%%lo(%a0)]"
1338 [(set_attr "type" "store")
1339 (set_attr "length" "2")])
1341 ;;- zero extension instructions
1343 ;; These patterns originally accepted general_operands, however, slightly
1344 ;; better code is generated by only accepting register_operands, and then
1345 ;; letting combine generate the ldu[hb] insns.
1347 (define_expand "zero_extendhisi2"
1348 [(set (match_operand:SI 0 "register_operand" "")
1349 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
1353 rtx temp = gen_reg_rtx (SImode);
1354 rtx shift_16 = gen_rtx (CONST_INT, VOIDmode, 16);
1356 if (GET_CODE (operand1) == SUBREG)
1357 operand1 = XEXP (operand1, 0);
1359 emit_insn (gen_ashlsi3 (temp, gen_rtx (SUBREG, SImode, operand1, 0),
1361 emit_insn (gen_lshrsi3 (operand0, temp, shift_16));
1366 [(set (match_operand:SI 0 "register_operand" "=r")
1367 (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
1370 [(set_attr "type" "load")])
1372 (define_expand "zero_extendqihi2"
1373 [(set (match_operand:HI 0 "register_operand" "")
1374 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
1379 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
1380 (zero_extend:HI (match_operand:QI 1 "sparc_operand" "r,I,Q")))]
1381 "GET_CODE (operands[1]) != CONST_INT"
1386 [(set_attr "type" "unary,move,load")
1387 (set_attr "length" "1")])
1389 (define_expand "zero_extendqisi2"
1390 [(set (match_operand:SI 0 "register_operand" "")
1391 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
1396 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
1397 (zero_extend:SI (match_operand:QI 1 "sparc_operand" "r,I,Q")))]
1398 "GET_CODE (operands[1]) != CONST_INT"
1403 [(set_attr "type" "unary,move,load")
1404 (set_attr "length" "1")])
1408 (compare:CC (zero_extend:SI (match_operand:QI 0 "register_operand" "r"))
1411 "andcc %0,0xff,%%g0"
1412 [(set_attr "type" "compare")])
1416 (compare:CC (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
1418 (set (match_operand:SI 0 "register_operand" "=r")
1419 (zero_extend:SI (match_dup 1)))]
1422 [(set_attr "type" "unary")])
1424 ;;- sign extension instructions
1426 ;; These patterns originally accepted general_operands, however, slightly
1427 ;; better code is generated by only accepting register_operands, and then
1428 ;; letting combine generate the lds[hb] insns.
1430 (define_expand "extendhisi2"
1431 [(set (match_operand:SI 0 "register_operand" "")
1432 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
1436 rtx temp = gen_reg_rtx (SImode);
1437 rtx shift_16 = gen_rtx (CONST_INT, VOIDmode, 16);
1439 if (GET_CODE (operand1) == SUBREG)
1440 operand1 = XEXP (operand1, 0);
1442 emit_insn (gen_ashlsi3 (temp, gen_rtx (SUBREG, SImode, operand1, 0),
1444 emit_insn (gen_ashrsi3 (operand0, temp, shift_16));
1449 [(set (match_operand:SI 0 "register_operand" "=r")
1450 (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
1453 [(set_attr "type" "load")])
1455 (define_expand "extendqihi2"
1456 [(set (match_operand:HI 0 "register_operand" "")
1457 (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
1461 rtx temp = gen_reg_rtx (SImode);
1462 rtx shift_24 = gen_rtx (CONST_INT, VOIDmode, 24);
1464 if (GET_CODE (operand1) == SUBREG)
1465 operand1 = XEXP (operand1, 0);
1466 if (GET_CODE (operand0) == SUBREG)
1467 operand0 = XEXP (operand0, 0);
1468 emit_insn (gen_ashlsi3 (temp, gen_rtx (SUBREG, SImode, operand1, 0),
1470 if (GET_MODE (operand0) != SImode)
1471 operand0 = gen_rtx (SUBREG, SImode, operand0, 0);
1472 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
1477 [(set (match_operand:HI 0 "register_operand" "=r")
1478 (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
1481 [(set_attr "type" "load")])
1483 (define_expand "extendqisi2"
1484 [(set (match_operand:SI 0 "register_operand" "")
1485 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
1489 rtx temp = gen_reg_rtx (SImode);
1490 rtx shift_24 = gen_rtx (CONST_INT, VOIDmode, 24);
1492 if (GET_CODE (operand1) == SUBREG)
1493 operand1 = XEXP (operand1, 0);
1494 emit_insn (gen_ashlsi3 (temp, gen_rtx (SUBREG, SImode, operand1, 0),
1496 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
1501 [(set (match_operand:SI 0 "register_operand" "=r")
1502 (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
1505 [(set_attr "type" "load")])
1507 ;; Special pattern for optimizing bit-field compares. This is needed
1508 ;; because combine uses this as a canonical form.
1513 (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
1514 (match_operand:SI 1 "small_int" "n")
1515 (match_operand:SI 2 "small_int" "n"))
1517 "INTVAL (operands[2]) > 19"
1520 int len = INTVAL (operands[1]);
1521 int pos = 32 - INTVAL (operands[2]) - len;
1522 unsigned mask = ((1 << len) - 1) << pos;
1524 operands[1] = gen_rtx (CONST_INT, VOIDmode, mask);
1525 return \"andcc %0,%1,%%g0\";
1528 ;; Conversions between float, double and long double.
1530 (define_insn "extendsfdf2"
1531 [(set (match_operand:DF 0 "register_operand" "=f")
1533 (match_operand:SF 1 "register_operand" "f")))]
1536 [(set_attr "type" "fp")])
1538 (define_insn "extendsftf2"
1539 [(set (match_operand:TF 0 "register_operand" "=f")
1541 (match_operand:SF 1 "register_operand" "f")))]
1544 [(set_attr "type" "fp")])
1546 (define_insn "extenddftf2"
1547 [(set (match_operand:TF 0 "register_operand" "=f")
1549 (match_operand:DF 1 "register_operand" "f")))]
1552 [(set_attr "type" "fp")])
1554 (define_insn "truncdfsf2"
1555 [(set (match_operand:SF 0 "register_operand" "=f")
1557 (match_operand:DF 1 "register_operand" "f")))]
1560 [(set_attr "type" "fp")])
1562 (define_insn "trunctfsf2"
1563 [(set (match_operand:SF 0 "register_operand" "=f")
1565 (match_operand:TF 1 "register_operand" "f")))]
1568 [(set_attr "type" "fp")])
1570 (define_insn "trunctfdf2"
1571 [(set (match_operand:DF 0 "register_operand" "=f")
1573 (match_operand:TF 1 "register_operand" "f")))]
1576 [(set_attr "type" "fp")])
1578 ;; Conversion between fixed point and floating point.
1580 (define_insn "floatsisf2"
1581 [(set (match_operand:SF 0 "register_operand" "=f")
1582 (float:SF (match_operand:SI 1 "register_operand" "f")))]
1585 [(set_attr "type" "fp")])
1587 (define_insn "floatsidf2"
1588 [(set (match_operand:DF 0 "register_operand" "=f")
1589 (float:DF (match_operand:SI 1 "register_operand" "f")))]
1592 [(set_attr "type" "fp")])
1594 (define_insn "floatsitf2"
1595 [(set (match_operand:TF 0 "register_operand" "=f")
1596 (float:TF (match_operand:SI 1 "register_operand" "f")))]
1599 [(set_attr "type" "fp")])
1601 ;; Convert a float to an actual integer.
1602 ;; Truncation is performed as part of the conversion.
1604 (define_insn "fix_truncsfsi2"
1605 [(set (match_operand:SI 0 "register_operand" "=f")
1606 (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
1609 [(set_attr "type" "fp")])
1611 (define_insn "fix_truncdfsi2"
1612 [(set (match_operand:SI 0 "register_operand" "=f")
1613 (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "f"))))]
1616 [(set_attr "type" "fp")])
1618 (define_insn "fix_trunctfsi2"
1619 [(set (match_operand:SI 0 "register_operand" "=f")
1620 (fix:SI (fix:TF (match_operand:TF 1 "register_operand" "f"))))]
1623 [(set_attr "type" "fp")])
1625 ;;- arithmetic instructions
1627 (define_insn "adddi3"
1628 [(set (match_operand:DI 0 "register_operand" "=r")
1629 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
1630 (match_operand:DI 2 "arith_double_operand" "rHI")))
1631 (clobber (reg:SI 0))]
1635 rtx op2 = operands[2];
1637 /* If constant is positive, upper bits zeroed, otherwise unchanged.
1638 Give the assembler a chance to pick the move instruction. */
1639 if (GET_CODE (op2) == CONST_INT)
1641 int sign = INTVAL (op2);
1643 return \"addcc %R1,%2,%R0\;addx %1,-1,%0\";
1644 return \"addcc %R1,%2,%R0\;addx %1,0,%0\";
1646 else if (GET_CODE (op2) == CONST_DOUBLE)
1648 int sign = CONST_DOUBLE_HIGH (op2);
1649 operands[2] = gen_rtx (CONST_INT, VOIDmode,
1650 CONST_DOUBLE_LOW (operands[1]));
1652 return \"addcc %R1,%2,%R0\;addx %1,-1,%0\";
1653 return \"addcc %R1,%2,%R0\;addx %1,0,%0\";
1655 return \"addcc %R1,%R2,%R0\;addx %1,%2,%0\";
1657 [(set_attr "length" "2")])
1659 (define_insn "addsi3"
1660 [(set (match_operand:SI 0 "register_operand" "=r")
1661 (plus:SI (match_operand:SI 1 "arith_operand" "%r")
1662 (match_operand:SI 2 "arith_operand" "rI")))]
1667 [(set (reg:CC_NOOV 0)
1668 (compare:CC_NOOV (plus:SI (match_operand:SI 0 "arith_operand" "%r")
1669 (match_operand:SI 1 "arith_operand" "rI"))
1673 [(set_attr "type" "compare")])
1676 [(set (reg:CC_NOOV 0)
1677 (compare:CC_NOOV (plus:SI (match_operand:SI 1 "arith_operand" "%r")
1678 (match_operand:SI 2 "arith_operand" "rI"))
1680 (set (match_operand:SI 0 "register_operand" "=r")
1681 (plus:SI (match_dup 1) (match_dup 2)))]
1685 (define_insn "subdi3"
1686 [(set (match_operand:DI 0 "register_operand" "=r")
1687 (minus:DI (match_operand:DI 1 "register_operand" "r")
1688 (match_operand:DI 2 "arith_double_operand" "rHI")))
1689 (clobber (reg:SI 0))]
1693 rtx op2 = operands[2];
1695 /* If constant is positive, upper bits zeroed, otherwise unchanged.
1696 Give the assembler a chance to pick the move instruction. */
1697 if (GET_CODE (op2) == CONST_INT)
1699 int sign = INTVAL (op2);
1701 return \"subcc %R1,%2,%R0\;subx %1,-1,%0\";
1702 return \"subcc %R1,%2,%R0\;subx %1,0,%0\";
1704 else if (GET_CODE (op2) == CONST_DOUBLE)
1706 int sign = CONST_DOUBLE_HIGH (op2);
1707 operands[2] = gen_rtx (CONST_INT, VOIDmode,
1708 CONST_DOUBLE_LOW (operands[1]));
1710 return \"subcc %R1,%2,%R0\;subx %1,-1,%0\";
1711 return \"subcc %R1,%2,%R0\;subx %1,0,%0\";
1713 return \"subcc %R1,%R2,%R0\;subx %1,%2,%0\";
1715 [(set_attr "length" "2")])
1717 (define_insn "subsi3"
1718 [(set (match_operand:SI 0 "register_operand" "=r")
1719 (minus:SI (match_operand:SI 1 "register_operand" "r")
1720 (match_operand:SI 2 "arith_operand" "rI")))]
1725 [(set (reg:CC_NOOV 0)
1726 (compare:CC_NOOV (minus:SI (match_operand:SI 0 "register_operand" "r")
1727 (match_operand:SI 1 "arith_operand" "rI"))
1731 [(set_attr "type" "compare")])
1734 [(set (reg:CC_NOOV 0)
1735 (compare:CC_NOOV (minus:SI (match_operand:SI 1 "register_operand" "r")
1736 (match_operand:SI 2 "arith_operand" "rI"))
1738 (set (match_operand:SI 0 "register_operand" "=r")
1739 (minus:SI (match_dup 1) (match_dup 2)))]
1743 (define_insn "mulsi3"
1744 [(set (match_operand:SI 0 "register_operand" "=r")
1745 (mult:SI (match_operand:SI 1 "arith_operand" "%r")
1746 (match_operand:SI 2 "arith_operand" "rI")))]
1747 "TARGET_V8 || TARGET_SPARCLITE"
1750 ;; It is not known whether this will match.
1753 [(set (match_operand:SI 0 "register_operand" "=r")
1754 (mult:SI (match_operand:SI 1 "arith_operand" "%r")
1755 (match_operand:SI 2 "arith_operand" "rI")))
1756 (set (reg:CC_NOOV 0)
1757 (compare:CC_NOOV (mult:SI (match_dup 1) (match_dup 2))
1759 "TARGET_V8 || TARGET_SPARCLITE"
1762 (define_expand "mulsidi3"
1763 [(set (match_operand:DI 0 "register_operand" "")
1764 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
1765 (sign_extend:DI (match_operand:SI 2 "arith_operand" ""))))]
1766 "TARGET_V8 || TARGET_SPARCLITE"
1769 if (CONSTANT_P (operands[2]))
1771 emit_insn (gen_const_mulsidi3 (operands[0], operands[1], operands[2]));
1777 [(set (match_operand:DI 0 "register_operand" "=r")
1778 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
1779 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
1780 "TARGET_V8 || TARGET_SPARCLITE"
1781 "smul %1,%2,%R0\;rd %%y,%0"
1782 [(set_attr "length" "2")])
1784 ;; Extra pattern, because sign_extend of a constant isn't legal.
1786 (define_insn "const_mulsidi3"
1787 [(set (match_operand:DI 0 "register_operand" "=r")
1788 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
1789 (match_operand:SI 2 "small_int" "I")))]
1790 "TARGET_V8 || TARGET_SPARCLITE"
1791 "smul %1,%2,%R0\;rd %%y,%0"
1792 [(set_attr "length" "2")])
1794 (define_expand "umulsidi3"
1795 [(set (match_operand:DI 0 "register_operand" "")
1796 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
1797 (zero_extend:DI (match_operand:SI 2 "arith_operand" ""))))]
1798 "TARGET_V8 || TARGET_SPARCLITE"
1801 if (CONSTANT_P (operands[2]))
1803 emit_insn (gen_const_umulsidi3 (operands[0], operands[1], operands[2]));
1809 [(set (match_operand:DI 0 "register_operand" "=r")
1810 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
1811 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
1812 "TARGET_V8 || TARGET_SPARCLITE"
1813 "umul %1,%2,%R0\;rd %%y,%0"
1814 [(set_attr "length" "2")])
1816 ;; Extra pattern, because sign_extend of a constant isn't legal.
1818 (define_insn "const_umulsidi3"
1819 [(set (match_operand:DI 0 "register_operand" "=r")
1820 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
1821 (match_operand:SI 2 "small_int" "I")))]
1822 "TARGET_V8 || TARGET_SPARCLITE"
1823 "umul %1,%2,%R0\;rd %%y,%0"
1824 [(set_attr "length" "2")])
1826 ;; The architecture specifies that there must be 3 instructions between
1827 ;; a y register write and a use of it for correct results.
1829 (define_insn "divsi3"
1830 [(set (match_operand:SI 0 "register_operand" "=r")
1831 (div:SI (match_operand:SI 1 "register_operand" "r")
1832 (match_operand:SI 2 "arith_operand" "rI")))
1833 (clobber (match_scratch:SI 3 "=&r"))]
1835 "sra %1,31,%3\;wr %%g0,%3,%%y\;nop\;nop\;nop\;sdiv %1,%2,%0"
1836 [(set_attr "length" "6")])
1838 ;; It is not known whether this will match.
1841 [(set (match_operand:SI 0 "register_operand" "=r")
1842 (div:SI (match_operand:SI 1 "register_operand" "r")
1843 (match_operand:SI 2 "arith_operand" "rI")))
1845 (compare:CC (div:SI (match_dup 1) (match_dup 2))
1847 (clobber (match_scratch:SI 3 "=&r"))]
1849 "sra %1,31,%3\;wr %%g0,%3,%%y\;nop\;nop\;nop\;sdivcc %1,%2,%0"
1850 [(set_attr "length" "6")])
1852 (define_insn "udivsi3"
1853 [(set (match_operand:SI 0 "register_operand" "=r")
1854 (udiv:SI (match_operand:SI 1 "register_operand" "r")
1855 (match_operand:SI 2 "arith_operand" "rI")))]
1857 "wr %%g0,%%g0,%%y\;nop\;nop\;nop\;udiv %1,%2,%0"
1858 [(set_attr "length" "5")])
1860 ;; It is not known whether this will match.
1863 [(set (match_operand:SI 0 "register_operand" "=r")
1864 (udiv:SI (match_operand:SI 1 "register_operand" "r")
1865 (match_operand:SI 2 "arith_operand" "rI")))
1867 (compare:CC (udiv:SI (match_dup 1) (match_dup 2))
1870 "wr %%g0,%%g0,%%y\;nop\;nop\;nop\;udivcc %1,%2,%0"
1871 [(set_attr "length" "5")])
1873 ;;- and instructions
1874 ;; We define DImode `and` so with DImode `not` we can get
1875 ;; DImode `andn`. Other combinations are possible.
1877 (define_expand "anddi3"
1878 [(set (match_operand:DI 0 "register_operand" "")
1879 (and:DI (match_operand:DI 1 "arith_double_operand" "")
1880 (match_operand:DI 2 "arith_double_operand" "")))]
1885 [(set (match_operand:DI 0 "register_operand" "=r")
1886 (and:DI (match_operand:DI 1 "arith_double_operand" "%r")
1887 (match_operand:DI 2 "arith_double_operand" "rHI")))]
1891 rtx op2 = operands[2];
1893 /* If constant is positive, upper bits zeroed, otherwise unchanged.
1894 Give the assembler a chance to pick the move instruction. */
1895 if (GET_CODE (op2) == CONST_INT)
1897 int sign = INTVAL (op2);
1899 return \"mov %1,%0\;and %R1,%2,%R0\";
1900 return \"mov 0,%0\;and %R1,%2,%R0\";
1902 else if (GET_CODE (op2) == CONST_DOUBLE)
1904 int sign = CONST_DOUBLE_HIGH (op2);
1905 operands[2] = gen_rtx (CONST_INT, VOIDmode,
1906 CONST_DOUBLE_LOW (operands[1]));
1908 return \"mov %1,%0\;and %R1,%2,%R0\";
1909 return \"mov 0,%0\;and %R1,%2,%R0\";
1911 return \"and %1,%2,%0\;and %R1,%R2,%R0\";
1913 [(set_attr "length" "2")])
1915 (define_insn "andsi3"
1916 [(set (match_operand:SI 0 "register_operand" "=r")
1917 (and:SI (match_operand:SI 1 "arith_operand" "%r")
1918 (match_operand:SI 2 "arith_operand" "rI")))]
1923 [(set (match_operand:SI 0 "register_operand" "")
1924 (and:SI (match_operand:SI 1 "register_operand" "")
1925 (match_operand:SI 2 "" "")))
1926 (clobber (match_operand:SI 3 "register_operand" ""))]
1927 "GET_CODE (operands[2]) == CONST_INT
1928 && !SMALL_INT (operands[2])
1929 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
1930 [(set (match_dup 3) (match_dup 4))
1931 (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 1)))]
1934 operands[4] = gen_rtx (CONST_INT, VOIDmode, ~INTVAL (operands[2]));
1938 [(set (match_operand:DI 0 "register_operand" "=r")
1939 (and:DI (not:DI (match_operand:DI 1 "register_operand" "r"))
1940 (match_operand:DI 2 "register_operand" "r")))]
1942 "andn %2,%1,%0\;andn %R2,%R1,%R0"
1943 [(set_attr "length" "2")])
1946 [(set (match_operand:SI 0 "register_operand" "=r")
1947 (and:SI (not:SI (match_operand:SI 1 "register_operand" "r"))
1948 (match_operand:SI 2 "register_operand" "r")))]
1952 (define_expand "iordi3"
1953 [(set (match_operand:DI 0 "register_operand" "")
1954 (ior:DI (match_operand:DI 1 "arith_double_operand" "")
1955 (match_operand:DI 2 "arith_double_operand" "")))]
1960 [(set (match_operand:DI 0 "register_operand" "=r")
1961 (ior:DI (match_operand:DI 1 "arith_double_operand" "%r")
1962 (match_operand:DI 2 "arith_double_operand" "rHI")))]
1966 rtx op2 = operands[2];
1968 /* If constant is positive, upper bits zeroed, otherwise unchanged.
1969 Give the assembler a chance to pick the move instruction. */
1970 if (GET_CODE (op2) == CONST_INT)
1972 int sign = INTVAL (op2);
1974 return \"mov -1,%0\;or %R1,%2,%R0\";
1975 return \"mov %1,%0\;or %R1,%2,%R0\";
1977 else if (GET_CODE (op2) == CONST_DOUBLE)
1979 int sign = CONST_DOUBLE_HIGH (op2);
1980 operands[2] = gen_rtx (CONST_INT, VOIDmode,
1981 CONST_DOUBLE_LOW (operands[1]));
1983 return \"mov -1,%0\;or %R1,%2,%R0\";
1984 return \"mov %1,%0\;or %R1,%2,%R0\";
1986 return \"or %1,%2,%0\;or %R1,%R2,%R0\";
1988 [(set_attr "length" "2")])
1990 (define_insn "iorsi3"
1991 [(set (match_operand:SI 0 "register_operand" "=r")
1992 (ior:SI (match_operand:SI 1 "arith_operand" "%r")
1993 (match_operand:SI 2 "arith_operand" "rI")))]
1998 [(set (match_operand:SI 0 "register_operand" "")
1999 (ior:SI (match_operand:SI 1 "register_operand" "")
2000 (match_operand:SI 2 "" "")))
2001 (clobber (match_operand:SI 3 "register_operand" ""))]
2002 "GET_CODE (operands[2]) == CONST_INT
2003 && !SMALL_INT (operands[2])
2004 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
2005 [(set (match_dup 3) (match_dup 4))
2006 (set (match_dup 0) (ior:SI (not:SI (match_dup 3)) (match_dup 1)))]
2009 operands[4] = gen_rtx (CONST_INT, VOIDmode, ~INTVAL (operands[2]));
2013 [(set (match_operand:DI 0 "register_operand" "=r")
2014 (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r"))
2015 (match_operand:DI 2 "register_operand" "r")))]
2017 "orn %2,%1,%0\;orn %R2,%R1,%R0"
2018 [(set_attr "length" "2")])
2021 [(set (match_operand:SI 0 "register_operand" "=r")
2022 (ior:SI (not:SI (match_operand:SI 1 "register_operand" "r"))
2023 (match_operand:SI 2 "register_operand" "r")))]
2027 (define_expand "xordi3"
2028 [(set (match_operand:DI 0 "register_operand" "")
2029 (xor:DI (match_operand:DI 1 "arith_double_operand" "")
2030 (match_operand:DI 2 "arith_double_operand" "")))]
2035 [(set (match_operand:DI 0 "register_operand" "=r")
2036 (xor:DI (match_operand:DI 1 "arith_double_operand" "%r")
2037 (match_operand:DI 2 "arith_double_operand" "rHI")))]
2041 rtx op2 = operands[2];
2043 /* If constant is positive, upper bits zeroed, otherwise unchanged.
2044 Give the assembler a chance to pick the move instruction. */
2045 if (GET_CODE (op2) == CONST_INT)
2047 int sign = INTVAL (op2);
2049 return \"xor %1,-1,%0\;xor %R1,%2,%R0\";
2050 return \"mov %1,%0\;xor %R1,%2,%R0\";
2052 else if (GET_CODE (op2) == CONST_DOUBLE)
2054 int sign = CONST_DOUBLE_HIGH (op2);
2055 operands[2] = gen_rtx (CONST_INT, VOIDmode,
2056 CONST_DOUBLE_LOW (operands[1]));
2058 return \"xor %1,-1,%0\;xor %R1,%2,%R0\";
2059 return \"mov %1,%0\;xor %R1,%2,%R0\";
2061 return \"xor %1,%2,%0\;xor %R1,%R2,%R0\";
2063 [(set_attr "length" "2")])
2065 (define_insn "xorsi3"
2066 [(set (match_operand:SI 0 "register_operand" "=r")
2067 (xor:SI (match_operand:SI 1 "arith_operand" "%rJ")
2068 (match_operand:SI 2 "arith_operand" "rI")))]
2073 [(set (match_operand:SI 0 "register_operand" "")
2074 (xor:SI (match_operand:SI 1 "register_operand" "")
2075 (match_operand:SI 2 "" "")))
2076 (clobber (match_operand:SI 3 "register_operand" ""))]
2077 "GET_CODE (operands[2]) == CONST_INT
2078 && !SMALL_INT (operands[2])
2079 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
2080 [(set (match_dup 3) (match_dup 4))
2081 (set (match_dup 0) (not:SI (xor:SI (match_dup 3) (match_dup 1))))]
2084 operands[4] = gen_rtx (CONST_INT, VOIDmode, ~INTVAL (operands[2]));
2088 [(set (match_operand:SI 0 "register_operand" "")
2089 (not:SI (xor:SI (match_operand:SI 1 "register_operand" "")
2090 (match_operand:SI 2 "" ""))))
2091 (clobber (match_operand:SI 3 "register_operand" ""))]
2092 "GET_CODE (operands[2]) == CONST_INT
2093 && !SMALL_INT (operands[2])
2094 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
2095 [(set (match_dup 3) (match_dup 4))
2096 (set (match_dup 0) (xor:SI (match_dup 3) (match_dup 1)))]
2099 operands[4] = gen_rtx (CONST_INT, VOIDmode, ~INTVAL (operands[2]));
2102 ;; xnor patterns. Note that (a ^ ~b) == (~a ^ b) == ~(a ^ b).
2103 ;; Combine now canonicalizes to the rightmost expression.
2105 [(set (match_operand:DI 0 "register_operand" "=r")
2106 (not:DI (xor:DI (match_operand:DI 1 "register_operand" "r")
2107 (match_operand:DI 2 "register_operand" "r"))))]
2109 "xnor %1,%2,%0\;xnor %R1,%R2,%R0"
2110 [(set_attr "length" "2")])
2113 [(set (match_operand:SI 0 "register_operand" "=r")
2114 (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
2115 (match_operand:SI 2 "arith_operand" "rI"))))]
2119 ;; These correspond to the above in the case where we also (or only)
2120 ;; want to set the condition code.
2125 (match_operator:SI 2 "cc_arithop"
2126 [(match_operand:SI 0 "arith_operand" "%r")
2127 (match_operand:SI 1 "arith_operand" "rI")])
2131 [(set_attr "type" "compare")])
2136 (match_operator:SI 3 "cc_arithop"
2137 [(match_operand:SI 1 "arith_operand" "%r")
2138 (match_operand:SI 2 "arith_operand" "rI")])
2140 (set (match_operand:SI 0 "register_operand" "=r")
2148 (not:SI (xor:SI (match_operand:SI 0 "reg_or_0_operand" "%rJ")
2149 (match_operand:SI 1 "arith_operand" "rI")))
2152 "xnorcc %r0,%1,%%g0"
2153 [(set_attr "type" "compare")])
2158 (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
2159 (match_operand:SI 2 "arith_operand" "rI")))
2161 (set (match_operand:SI 0 "register_operand" "=r")
2162 (not:SI (xor:SI (match_dup 1) (match_dup 2))))]
2169 (match_operator:SI 2 "cc_arithopn"
2170 [(not:SI (match_operand:SI 0 "arith_operand" "rI"))
2171 (match_operand:SI 1 "reg_or_0_operand" "rJ")])
2175 [(set_attr "type" "compare")])
2180 (match_operator:SI 3 "cc_arithopn"
2181 [(not:SI (match_operand:SI 1 "arith_operand" "rI"))
2182 (match_operand:SI 2 "reg_or_0_operand" "rJ")])
2184 (set (match_operand:SI 0 "register_operand" "=r")
2189 ;; We cannot use the "neg" pseudo insn because the Sun assembler
2190 ;; does not know how to make it work for constants.
2192 (define_insn "negdi2"
2193 [(set (match_operand:DI 0 "register_operand" "=r")
2194 (neg:DI (match_operand:DI 1 "register_operand" "r")))
2195 (clobber (reg:SI 0))]
2197 "subcc %%g0,%R1,%R0\;subx %%g0,%1,%0"
2198 [(set_attr "type" "unary")
2199 (set_attr "length" "2")])
2201 (define_insn "negsi2"
2202 [(set (match_operand:SI 0 "general_operand" "=r")
2203 (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
2206 [(set_attr "type" "unary")])
2209 [(set (reg:CC_NOOV 0)
2210 (compare:CC_NOOV (neg:SI (match_operand:SI 0 "arith_operand" "rI"))
2213 "subcc %%g0,%0,%%g0"
2214 [(set_attr "type" "compare")])
2217 [(set (reg:CC_NOOV 0)
2218 (compare:CC_NOOV (neg:SI (match_operand:SI 1 "arith_operand" "rI"))
2220 (set (match_operand:SI 0 "register_operand" "=r")
2221 (neg:SI (match_dup 1)))]
2224 [(set_attr "type" "unary")])
2226 ;; We cannot use the "not" pseudo insn because the Sun assembler
2227 ;; does not know how to make it work for constants.
2228 (define_expand "one_cmpldi2"
2229 [(set (match_operand:DI 0 "register_operand" "=r")
2230 (not:DI (match_operand:DI 1 "arith_double_operand" "rHI")))]
2235 [(set (match_operand:DI 0 "register_operand" "=r")
2236 (not:DI (match_operand:DI 1 "arith_double_operand" "rHI")))]
2240 rtx op1 = operands[1];
2242 if (GET_CODE (op1) == CONST_INT)
2244 int sign = INTVAL (op1);
2246 return \"xnor %%g0,%1,%R0\;xnor %%g0,-1,%0\";
2247 return \"xnor %%g0,%1,%R0\;xnor %%g0,0,%0\";
2249 else if (GET_CODE (op1) == CONST_DOUBLE)
2251 int sign = CONST_DOUBLE_HIGH (op1);
2252 operands[1] = gen_rtx (CONST_INT, VOIDmode,
2253 CONST_DOUBLE_LOW (operands[1]));
2255 return \"xnor %%g0,%1,%R0\;xnor %%g0,-1,%0\";
2256 return \"xnor %%g0,%1,%R0\;xnor %%g0,0,%0\";
2258 return \"xnor %%g0,%1,%0\;xnor %%g0,%R1,%R0\";
2260 [(set_attr "type" "unary")
2261 (set_attr "length" "2")])
2263 (define_insn "one_cmplsi2"
2264 [(set (match_operand:SI 0 "register_operand" "=r")
2265 (not:SI (match_operand:SI 1 "arith_operand" "rI")))]
2268 [(set_attr "type" "unary")])
2272 (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI"))
2275 "xnorcc %%g0,%0,%%g0"
2276 [(set_attr "type" "compare")])
2280 (compare:CC (not:SI (match_operand:SI 1 "arith_operand" "rI"))
2282 (set (match_operand:SI 0 "register_operand" "=r")
2283 (not:SI (match_dup 1)))]
2286 [(set_attr "type" "unary")])
2288 ;; Floating point arithmetic instructions.
2290 (define_insn "addtf3"
2291 [(set (match_operand:TF 0 "register_operand" "=f")
2292 (plus:TF (match_operand:TF 1 "register_operand" "f")
2293 (match_operand:TF 2 "register_operand" "f")))]
2296 [(set_attr "type" "fp")])
2298 (define_insn "adddf3"
2299 [(set (match_operand:DF 0 "register_operand" "=f")
2300 (plus:DF (match_operand:DF 1 "register_operand" "f")
2301 (match_operand:DF 2 "register_operand" "f")))]
2304 [(set_attr "type" "fp")])
2306 (define_insn "addsf3"
2307 [(set (match_operand:SF 0 "register_operand" "=f")
2308 (plus:SF (match_operand:SF 1 "register_operand" "f")
2309 (match_operand:SF 2 "register_operand" "f")))]
2312 [(set_attr "type" "fp")])
2314 (define_insn "subtf3"
2315 [(set (match_operand:TF 0 "register_operand" "=f")
2316 (minus:TF (match_operand:TF 1 "register_operand" "f")
2317 (match_operand:TF 2 "register_operand" "f")))]
2320 [(set_attr "type" "fp")])
2322 (define_insn "subdf3"
2323 [(set (match_operand:DF 0 "register_operand" "=f")
2324 (minus:DF (match_operand:DF 1 "register_operand" "f")
2325 (match_operand:DF 2 "register_operand" "f")))]
2328 [(set_attr "type" "fp")])
2330 (define_insn "subsf3"
2331 [(set (match_operand:SF 0 "register_operand" "=f")
2332 (minus:SF (match_operand:SF 1 "register_operand" "f")
2333 (match_operand:SF 2 "register_operand" "f")))]
2336 [(set_attr "type" "fp")])
2338 (define_insn "multf3"
2339 [(set (match_operand:TF 0 "register_operand" "=f")
2340 (mult:TF (match_operand:TF 1 "register_operand" "f")
2341 (match_operand:TF 2 "register_operand" "f")))]
2344 [(set_attr "type" "fpmul")])
2346 (define_insn "muldf3"
2347 [(set (match_operand:DF 0 "register_operand" "=f")
2348 (mult:DF (match_operand:DF 1 "register_operand" "f")
2349 (match_operand:DF 2 "register_operand" "f")))]
2352 [(set_attr "type" "fpmul")])
2354 (define_insn "mulsf3"
2355 [(set (match_operand:SF 0 "register_operand" "=f")
2356 (mult:SF (match_operand:SF 1 "register_operand" "f")
2357 (match_operand:SF 2 "register_operand" "f")))]
2360 [(set_attr "type" "fpmul")])
2363 [(set (match_operand:DF 0 "register_operand" "=f")
2364 (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "f"))
2365 (float_extend:DF (match_operand:SF 2 "register_operand" "f"))))]
2366 "TARGET_V8 && TARGET_FPU"
2368 [(set_attr "type" "fpmul")])
2371 [(set (match_operand:TF 0 "register_operand" "=f")
2372 (mult:TF (float_extend:TF (match_operand:DF 1 "register_operand" "f"))
2373 (float_extend:TF (match_operand:DF 2 "register_operand" "f"))))]
2374 "TARGET_V8 && TARGET_FPU"
2376 [(set_attr "type" "fpmul")])
2378 (define_insn "divtf3"
2379 [(set (match_operand:TF 0 "register_operand" "=f")
2380 (div:TF (match_operand:TF 1 "register_operand" "f")
2381 (match_operand:TF 2 "register_operand" "f")))]
2384 [(set_attr "type" "fpdiv")])
2386 (define_insn "divdf3"
2387 [(set (match_operand:DF 0 "register_operand" "=f")
2388 (div:DF (match_operand:DF 1 "register_operand" "f")
2389 (match_operand:DF 2 "register_operand" "f")))]
2392 [(set_attr "type" "fpdiv")])
2394 (define_insn "divsf3"
2395 [(set (match_operand:SF 0 "register_operand" "=f")
2396 (div:SF (match_operand:SF 1 "register_operand" "f")
2397 (match_operand:SF 2 "register_operand" "f")))]
2400 [(set_attr "type" "fpdiv")])
2402 (define_insn "negtf2"
2403 [(set (match_operand:TF 0 "register_operand" "=f,f")
2404 (neg:TF (match_operand:TF 1 "register_operand" "0,f")))]
2408 fnegs %1,%0\;fmovs %R1,%R0\;fmovs %S1,%S0\;fmovs %T1,%T0"
2409 [(set_attr "type" "fp")
2410 (set_attr "length" "1,4")])
2412 (define_insn "negdf2"
2413 [(set (match_operand:DF 0 "register_operand" "=f,f")
2414 (neg:DF (match_operand:DF 1 "register_operand" "0,f")))]
2418 fnegs %1,%0\;fmovs %R1,%R0"
2419 [(set_attr "type" "fp")
2420 (set_attr "length" "1,2")])
2422 (define_insn "negsf2"
2423 [(set (match_operand:SF 0 "register_operand" "=f")
2424 (neg:SF (match_operand:SF 1 "register_operand" "f")))]
2427 [(set_attr "type" "fp")])
2429 (define_insn "abstf2"
2430 [(set (match_operand:TF 0 "register_operand" "=f,f")
2431 (abs:TF (match_operand:TF 1 "register_operand" "0,f")))]
2435 fabss %1,%0\;fmovs %R1,%R0\;fmovs %S1,%S0\;fmovs %T1,%T0"
2436 [(set_attr "type" "fp")
2437 (set_attr "length" "1,4")])
2439 (define_insn "absdf2"
2440 [(set (match_operand:DF 0 "register_operand" "=f,f")
2441 (abs:DF (match_operand:DF 1 "register_operand" "0,f")))]
2445 fabss %1,%0\;fmovs %R1,%R0"
2446 [(set_attr "type" "fp")
2447 (set_attr "length" "1,2")])
2449 (define_insn "abssf2"
2450 [(set (match_operand:SF 0 "register_operand" "=f")
2451 (abs:SF (match_operand:SF 1 "register_operand" "f")))]
2454 [(set_attr "type" "fp")])
2456 (define_insn "sqrttf2"
2457 [(set (match_operand:TF 0 "register_operand" "=f")
2458 (sqrt:TF (match_operand:TF 1 "register_operand" "f")))]
2461 [(set_attr "type" "fpsqrt")])
2463 (define_insn "sqrtdf2"
2464 [(set (match_operand:DF 0 "register_operand" "=f")
2465 (sqrt:DF (match_operand:DF 1 "register_operand" "f")))]
2468 [(set_attr "type" "fpsqrt")])
2470 (define_insn "sqrtsf2"
2471 [(set (match_operand:SF 0 "register_operand" "=f")
2472 (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
2475 [(set_attr "type" "fpsqrt")])
2477 ;;- arithmetic shift instructions
2479 ;; We can trivially handle shifting the constant 1 by 64 bits.
2480 ;; For other shifts we use the library routine.
2481 ;; ??? Questionable, we can do better than this can't we?
2482 (define_expand "ashldi3"
2483 [(parallel [(set (match_operand:DI 0 "register_operand" "")
2484 (ashift:DI (match_operand:DI 1 "const_double_operand" "")
2485 (match_operand:SI 2 "register_operand" "")))
2486 (clobber (reg:SI 0))])]
2490 if (GET_CODE (operands[1]) == CONST_DOUBLE
2491 && CONST_DOUBLE_HIGH (operands[1]) == 0
2492 && CONST_DOUBLE_LOW (operands[1]) == 1)
2493 operands[1] = const1_rtx;
2494 else if (operands[1] != const1_rtx)
2498 ;; ??? Questionable, we can do better than this can't we?
2500 [(set (match_operand:DI 0 "register_operand" "=&r")
2501 (ashift:DI (const_int 1)
2502 (match_operand:SI 1 "register_operand" "r")))
2503 (clobber (reg:SI 0))]
2505 "subcc %1,32,%%g0\;addx %%g0,0,%R0\;xor %R0,1,%0\;sll %R0,%1,%R0\;sll %0,%1,%0"
2506 [(set_attr "type" "multi")
2507 (set_attr "length" "5")])
2509 (define_insn "ashlsi3"
2510 [(set (match_operand:SI 0 "register_operand" "=r")
2511 (ashift:SI (match_operand:SI 1 "register_operand" "r")
2512 (match_operand:SI 2 "arith_operand" "rI")))]
2516 (define_insn "ashrsi3"
2517 [(set (match_operand:SI 0 "register_operand" "=r")
2518 (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
2519 (match_operand:SI 2 "arith_operand" "rI")))]
2523 (define_insn "lshrsi3"
2524 [(set (match_operand:SI 0 "register_operand" "=r")
2525 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
2526 (match_operand:SI 2 "arith_operand" "rI")))]
2530 ;; Unconditional and other jump instructions
2531 ;; On the Sparc, by setting the annul bit on an unconditional branch, the
2532 ;; following insn is never executed. This saves us a nop. Dbx does not
2533 ;; handle such branches though, so we only use them when optimizing.
2535 [(set (pc) (label_ref (match_operand 0 "" "")))]
2538 [(set_attr "type" "uncond_branch")])
2540 (define_expand "tablejump"
2541 [(parallel [(set (pc) (match_operand:SI 0 "register_operand" "r"))
2542 (use (label_ref (match_operand 1 "" "")))])]
2546 /* We need to use the PC value in %o7 that was set up when the address
2547 of the label was loaded into a register, so we need different RTL. */
2550 emit_insn (gen_pic_tablejump (operands[0], operands[1]));
2555 (define_insn "pic_tablejump"
2556 [(set (pc) (match_operand:SI 0 "register_operand" "r"))
2557 (use (label_ref (match_operand 1 "" "")))
2561 [(set_attr "type" "uncond_branch")])
2564 [(set (pc) (match_operand:SI 0 "address_operand" "p"))
2565 (use (label_ref (match_operand 1 "" "")))]
2568 [(set_attr "type" "uncond_branch")])
2571 [(set (pc) (label_ref (match_operand 0 "" "")))
2572 (set (reg:SI 15) (label_ref (match_dup 0)))]
2575 [(set_attr "type" "uncond_branch")])
2577 ;; This pattern recognizes the "instruction" that appears in
2578 ;; a function call that wants a structure value,
2579 ;; to inform the called function if compiled with Sun CC.
2581 ; [(match_operand:SI 0 "immediate_operand" "")]
2582 ; "GET_CODE (operands[0]) == CONST_INT && INTVAL (operands[0]) > 0"
2584 ; [(set_attr "type" "marker")])
2586 ;;- jump to subroutine
2587 (define_expand "call"
2588 ;; Note that this expression is not used for generating RTL.
2589 ;; All the RTL is generated explicitly below.
2590 [(call (match_operand:SI 0 "call_operand" "")
2591 (match_operand 3 "" "i"))]
2592 ;; operands[2] is next_arg_register
2593 ;; operands[3] is struct_value_size_rtx.
2597 rtx fn_rtx, nregs_rtx;
2599 if (GET_CODE (XEXP (operands[0], 0)) == LABEL_REF)
2601 /* This is really a PIC sequence. We want to represent
2602 it as a funny jump so it's delay slots can be filled.
2604 ??? But if this really *is* a CALL, will not it clobber the
2605 call-clobbered registers? We lose this if it is a JUMP_INSN.
2606 Why cannot we have delay slots filled if it were a CALL? */
2608 if (INTVAL (operands[3]) > 0)
2609 emit_jump_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (3,
2610 gen_rtx (SET, VOIDmode, pc_rtx,
2611 XEXP (operands[0], 0)),
2613 gen_rtx (CLOBBER, VOIDmode,
2614 gen_rtx (REG, SImode, 15)))));
2616 emit_jump_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (2,
2617 gen_rtx (SET, VOIDmode, pc_rtx,
2618 XEXP (operands[0], 0)),
2619 gen_rtx (CLOBBER, VOIDmode,
2620 gen_rtx (REG, SImode, 15)))));
2624 fn_rtx = operands[0];
2626 /* Count the number of parameter registers being used by this call.
2627 if that argument is NULL, it means we are using them all, which
2628 means 6 on the sparc. */
2631 nregs_rtx = gen_rtx (CONST_INT, VOIDmode, REGNO (operands[2]) - 8);
2633 nregs_rtx = gen_rtx (CONST_INT, VOIDmode, 6);
2635 nregs_rtx = const0_rtx;
2638 if (INTVAL (operands[3]) > 0)
2639 emit_call_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (3,
2640 gen_rtx (CALL, VOIDmode, fn_rtx, nregs_rtx),
2642 gen_rtx (CLOBBER, VOIDmode,
2643 gen_rtx (REG, SImode, 15)))));
2645 emit_call_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (2,
2646 gen_rtx (CALL, VOIDmode, fn_rtx, nregs_rtx),
2647 gen_rtx (CLOBBER, VOIDmode,
2648 gen_rtx (REG, SImode, 15)))));
2652 /* If this call wants a structure value,
2653 emit an unimp insn to let the called function know about this. */
2654 if (INTVAL (operands[3]) > 0)
2656 rtx insn = emit_insn (operands[3]);
2657 SCHED_GROUP_P (insn) = 1;
2665 [(call (mem:SI (match_operand:SI 0 "call_operand_address" "S,r"))
2666 (match_operand 1 "" ""))
2667 (clobber (reg:SI 15))]
2668 ;;- Do not use operand 1 for most machines.
2672 return \"call %a0,%1%#\";
2674 [(set_attr "type" "call")])
2676 ;; This is a call that wants a structure value.
2678 [(call (mem:SI (match_operand:SI 0 "call_operand_address" "S,r"))
2679 (match_operand 1 "" ""))
2680 (match_operand 2 "immediate_operand" "")
2681 (clobber (reg:SI 15))]
2682 ;;- Do not use operand 1 for most machines.
2683 "GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
2686 return \"call %a0,%1\;nop\;unimp %2\";
2688 [(set_attr "type" "call_no_delay_slot")])
2690 (define_expand "call_value"
2691 [(set (match_operand 0 "register_operand" "=rf")
2692 (call (match_operand:SI 1 "" "")
2693 (match_operand 4 "" "")))]
2694 ;; operand 3 is next_arg_register
2698 rtx fn_rtx, nregs_rtx;
2701 fn_rtx = operands[1];
2705 nregs_rtx = gen_rtx (CONST_INT, VOIDmode, REGNO (operands[3]) - 8);
2707 nregs_rtx = gen_rtx (CONST_INT, VOIDmode, 6);
2709 nregs_rtx = const0_rtx;
2713 gen_rtx (SET, VOIDmode, operands[0],
2714 gen_rtx (CALL, VOIDmode, fn_rtx, nregs_rtx)),
2715 gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, 15)));
2717 emit_call_insn (gen_rtx (PARALLEL, VOIDmode, vec));
2723 [(set (match_operand 0 "" "=rf")
2724 (call (mem:SI (match_operand:SI 1 "call_operand_address" "rS"))
2725 (match_operand 2 "" "")))
2726 (clobber (reg:SI 15))]
2727 ;;- Do not use operand 2 for most machines.
2731 return \"call %a1,%2%#\";
2733 [(set_attr "type" "call")])
2735 (define_insn "return"
2738 "* return output_return (operands);"
2739 [(set_attr "type" "multi")])
2746 (define_insn "indirect_jump"
2747 [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
2750 [(set_attr "type" "uncond_branch")])
2752 (define_expand "nonlocal_goto"
2753 [(match_operand:SI 0 "general_operand" "")
2754 (match_operand:SI 1 "general_operand" "")
2755 (match_operand:SI 2 "general_operand" "")
2756 (match_operand:SI 3 "" "")]
2760 /* Trap instruction to flush all the registers window. */
2761 emit_insn (gen_rtx (UNSPEC_VOLATILE, VOIDmode,
2762 gen_rtvec (1, const0_rtx), 0));
2763 /* Load the fp value for the containing fn into %fp.
2764 This is needed because operands[2] refers to %fp.
2765 Virtual register instantiation fails if the virtual %fp isn't set from a
2766 register. Thus we must copy operands[0] into a register if it isn't
2768 if (GET_CODE (operands[0]) != REG)
2769 operands[0] = force_reg (SImode, operands[0]);
2770 emit_move_insn (virtual_stack_vars_rtx, operands[0]);
2771 /* Find the containing function's current nonlocal goto handler,
2772 which will do any cleanups and then jump to the label. */
2773 emit_move_insn (gen_rtx (REG, SImode, 8), operands[1]);
2774 /* Restore %fp from stack pointer value for containing function.
2775 The restore insn that follows will move this to %sp,
2776 and reload the appropriate value into %fp. */
2777 emit_move_insn (frame_pointer_rtx, operands[2]);
2778 /* Put in the static chain register the nonlocal label address. */
2779 emit_move_insn (static_chain_rtx, operands[3]);
2780 /* USE of frame_pointer_rtx added for consistency; not clear if
2782 emit_insn (gen_rtx (USE, VOIDmode, frame_pointer_rtx));
2783 emit_insn (gen_rtx (USE, VOIDmode, stack_pointer_rtx));
2784 emit_insn (gen_rtx (USE, VOIDmode, static_chain_rtx));
2785 emit_insn (gen_rtx (USE, VOIDmode, gen_rtx (REG, SImode, 8)));
2786 /* Return, restoring reg window and jumping to goto handler. */
2787 emit_insn (gen_rtx (UNSPEC_VOLATILE, VOIDmode,
2788 gen_rtvec (1, const0_rtx), 1));
2792 ;; Special trap insn to flush register windows.
2794 [(unspec_volatile [(const_int 0)] 0)]
2797 [(set_attr "type" "misc")])
2800 [(unspec_volatile [(const_int 0)] 1)]
2802 "jmp %%o0+0\;restore"
2803 [(set_attr "type" "misc")
2804 (set_attr "length" "2")])
2808 ;; The scan instruction searches from the most significant bit while ffs
2809 ;; searches from the least significant bit. The bit index and treatment of
2810 ;; zero also differ. It takes at least 7 instructions to get the proper
2811 ;; result. Here is an obvious 8 instruction seequence.
2813 (define_insn "ffssi2"
2814 [(set (match_operand:SI 0 "register_operand" "=&r")
2815 (ffs:SI (match_operand:SI 1 "register_operand" "r")))
2816 (clobber (match_scratch:SI 2 "=&r"))]
2818 "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"
2819 [(set_attr "type" "multi")
2820 (set_attr "length" "8")])
2822 ;; Split up troublesome insns for better scheduling. */
2824 ;; The following patterns are straightforward. They can be applied
2825 ;; either before or after register allocation.
2828 [(set (match_operator 0 "memop" [(match_operand:SI 1 "symbolic_operand" "")])
2829 (match_operand 2 "reg_or_0_operand" ""))
2830 (clobber (match_operand:SI 3 "register_operand" ""))]
2832 [(set (match_dup 3) (high:SI (match_dup 1)))
2833 (set (match_op_dup 0 [(lo_sum:SI (match_dup 3) (match_dup 1))])
2838 [(set (match_operator 0 "memop"
2839 [(match_operand:SI 1 "immediate_operand" "")])
2840 (match_operand 2 "general_operand" ""))
2841 (clobber (match_operand:SI 3 "register_operand" ""))]
2843 [(set (match_op_dup 0 [(match_dup 1)])
2847 operands[1] = legitimize_pic_address (operands[1], GET_MODE (operands[0]),
2852 [(set (match_operand 0 "register_operand" "")
2853 (match_operator 1 "memop"
2854 [(match_operand:SI 2 "immediate_operand" "")]))]
2857 (match_op_dup 1 [(match_dup 2)]))]
2860 operands[2] = legitimize_pic_address (operands[2], GET_MODE (operands[1]),
2864 ;; Sign- and Zero-extend operations can have symbolic memory operands.
2867 [(set (match_operand 0 "register_operand" "")
2868 (match_operator 1 "extend_op"
2869 [(match_operator 2 "memop"
2870 [(match_operand:SI 3 "immediate_operand" "")])]))]
2873 (match_op_dup 1 [(match_op_dup 2 [(match_dup 3)])]))]
2876 operands[3] = legitimize_pic_address (operands[3], GET_MODE (operands[2]),
2881 [(set (match_operand:SI 0 "register_operand" "")
2882 (match_operand:SI 1 "immediate_operand" ""))]
2883 "! flag_pic && (GET_CODE (operands[1]) == SYMBOL_REF
2884 || GET_CODE (operands[1]) == CONST
2885 || GET_CODE (operands[1]) == LABEL_REF)"
2886 [(set (match_dup 0) (high:SI (match_dup 1)))
2888 (lo_sum:SI (match_dup 0) (match_dup 1)))]
2891 ;; LABEL_REFs are not modified by `legitimize_pic_address`
2892 ;; so do not recurse infinitely in the PIC case.
2894 [(set (match_operand:SI 0 "register_operand" "")
2895 (match_operand:SI 1 "immediate_operand" ""))]
2896 "flag_pic && (GET_CODE (operands[1]) == SYMBOL_REF
2897 || GET_CODE (operands[1]) == CONST)"
2898 [(set (match_dup 0) (match_dup 1))]
2901 operands[1] = legitimize_pic_address (operands[1], Pmode, operands[0], 0);
2904 ;; These split sne/seq insns. The forms of the resulting insns are
2905 ;; somewhat bogus, but they avoid extra patterns and show data dependency.
2906 ;; Nothing will look at these in detail after splitting has occurred.
2909 [(set (match_operand:SI 0 "register_operand" "")
2910 (ne:SI (match_operand:SI 1 "register_operand" "") (const_int 0)))
2911 (clobber (reg:CC 0))]
2913 [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
2915 (set (match_dup 0) (ltu:SI (reg:CC 0) (const_int 0)))]
2919 [(set (match_operand:SI 0 "register_operand" "")
2920 (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "")
2922 (clobber (reg:CC 0))]
2924 [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
2926 (set (match_dup 0) (neg:SI (ltu:SI (reg:CC 0) (const_int 0))))]
2930 [(set (match_operand:SI 0 "register_operand" "")
2931 (eq:SI (match_operand:SI 1 "register_operand" "") (const_int 0)))
2932 (clobber (reg:CC 0))]
2934 [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
2936 (set (match_dup 0) (geu:SI (reg:CC 0) (const_int 0)))]
2940 [(set (match_operand:SI 0 "register_operand" "")
2941 (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "")
2943 (clobber (reg:CC 0))]
2945 [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
2947 (set (match_dup 0) (neg:SI (geu:SI (reg:CC 0) (const_int 0))))]
2951 [(set (match_operand:SI 0 "register_operand" "")
2952 (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "")
2954 (match_operand:SI 2 "register_operand" "")))
2955 (clobber (reg:CC 0))]
2957 [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
2959 (set (match_dup 0) (plus:SI (ltu:SI (reg:CC 0) (const_int 0))
2964 [(set (match_operand:SI 0 "register_operand" "")
2965 (minus:SI (match_operand:SI 2 "register_operand" "")
2966 (ne:SI (match_operand:SI 1 "register_operand" "")
2968 (clobber (reg:CC 0))]
2970 [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
2972 (set (match_dup 0) (minus:SI (match_dup 2)
2973 (ltu:SI (reg:CC 0) (const_int 0))))]
2977 [(set (match_operand:SI 0 "register_operand" "")
2978 (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "")
2980 (match_operand:SI 2 "register_operand" "")))
2981 (clobber (reg:CC 0))]
2983 [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
2985 (set (match_dup 0) (plus:SI (geu:SI (reg:CC 0) (const_int 0))
2990 [(set (match_operand:SI 0 "register_operand" "")
2991 (minus:SI (match_operand:SI 2 "register_operand" "")
2992 (eq:SI (match_operand:SI 1 "register_operand" "")
2994 (clobber (reg:CC 0))]
2996 [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
2998 (set (match_dup 0) (minus:SI (match_dup 2)
2999 (geu:SI (reg:CC 0) (const_int 0))))]
3002 ;; Peepholes go at the end.
3004 ;; Optimize consecutive loads or stores into ldd and std when possible.
3005 ;; The conditions in which we do this are very restricted and are
3006 ;; explained in the code for {registers,memory}_ok_for_ldd functions.
3009 [(set (match_operand:SI 0 "register_operand" "=rf")
3010 (match_operand:SI 1 "memory_operand" ""))
3011 (set (match_operand:SI 2 "register_operand" "=rf")
3012 (match_operand:SI 3 "memory_operand" ""))]
3013 "registers_ok_for_ldd_peep (operands[0], operands[2])
3014 && ! MEM_VOLATILE_P (operands[1]) && ! MEM_VOLATILE_P (operands[3])
3015 && addrs_ok_for_ldd_peep (XEXP (operands[1], 0), XEXP (operands[3], 0))"
3019 [(set (match_operand:SI 0 "memory_operand" "")
3020 (match_operand:SI 1 "register_operand" "rf"))
3021 (set (match_operand:SI 2 "memory_operand" "")
3022 (match_operand:SI 3 "register_operand" "rf"))]
3023 "registers_ok_for_ldd_peep (operands[1], operands[3])
3024 && ! MEM_VOLATILE_P (operands[0]) && ! MEM_VOLATILE_P (operands[2])
3025 && addrs_ok_for_ldd_peep (XEXP (operands[0], 0), XEXP (operands[2], 0))"
3029 [(set (match_operand:SF 0 "register_operand" "=fr")
3030 (match_operand:SF 1 "memory_operand" ""))
3031 (set (match_operand:SF 2 "register_operand" "=fr")
3032 (match_operand:SF 3 "memory_operand" ""))]
3033 "registers_ok_for_ldd_peep (operands[0], operands[2])
3034 && ! MEM_VOLATILE_P (operands[1]) && ! MEM_VOLATILE_P (operands[3])
3035 && addrs_ok_for_ldd_peep (XEXP (operands[1], 0), XEXP (operands[3], 0))"
3039 [(set (match_operand:SF 0 "memory_operand" "")
3040 (match_operand:SF 1 "register_operand" "fr"))
3041 (set (match_operand:SF 2 "memory_operand" "")
3042 (match_operand:SF 3 "register_operand" "fr"))]
3043 "registers_ok_for_ldd_peep (operands[1], operands[3])
3044 && ! MEM_VOLATILE_P (operands[0]) && ! MEM_VOLATILE_P (operands[2])
3045 && addrs_ok_for_ldd_peep (XEXP (operands[0], 0), XEXP (operands[2], 0))"
3049 [(set (match_operand:SI 0 "register_operand" "=rf")
3050 (match_operand:SI 1 "memory_operand" ""))
3051 (set (match_operand:SI 2 "register_operand" "=rf")
3052 (match_operand:SI 3 "memory_operand" ""))]
3053 "registers_ok_for_ldd_peep (operands[2], operands[0])
3054 && ! MEM_VOLATILE_P (operands[3]) && ! MEM_VOLATILE_P (operands[1])
3055 && addrs_ok_for_ldd_peep (XEXP (operands[3], 0), XEXP (operands[1], 0))"
3059 [(set (match_operand:SI 0 "memory_operand" "")
3060 (match_operand:SI 1 "register_operand" "rf"))
3061 (set (match_operand:SI 2 "memory_operand" "")
3062 (match_operand:SI 3 "register_operand" "rf"))]
3063 "registers_ok_for_ldd_peep (operands[3], operands[1])
3064 && ! MEM_VOLATILE_P (operands[2]) && ! MEM_VOLATILE_P (operands[0])
3065 && addrs_ok_for_ldd_peep (XEXP (operands[2], 0), XEXP (operands[0], 0))"
3069 [(set (match_operand:SF 0 "register_operand" "=fr")
3070 (match_operand:SF 1 "memory_operand" ""))
3071 (set (match_operand:SF 2 "register_operand" "=fr")
3072 (match_operand:SF 3 "memory_operand" ""))]
3073 "registers_ok_for_ldd_peep (operands[2], operands[0])
3074 && ! MEM_VOLATILE_P (operands[3]) && ! MEM_VOLATILE_P (operands[1])
3075 && addrs_ok_for_ldd_peep (XEXP (operands[3], 0), XEXP (operands[1], 0))"
3079 [(set (match_operand:SF 0 "memory_operand" "")
3080 (match_operand:SF 1 "register_operand" "fr"))
3081 (set (match_operand:SF 2 "memory_operand" "")
3082 (match_operand:SF 3 "register_operand" "fr"))]
3083 "registers_ok_for_ldd_peep (operands[3], operands[1])
3084 && ! MEM_VOLATILE_P (operands[2]) && ! MEM_VOLATILE_P (operands[0])
3085 && addrs_ok_for_ldd_peep (XEXP (operands[2], 0), XEXP (operands[0], 0))"
3088 ;; Optimize the case of following a reg-reg move with a test
3089 ;; of reg just moved. Don't allow floating point regs for operand 0 or 1.
3090 ;; This can result from a float to fix conversion.
3093 [(set (match_operand:SI 0 "register_operand" "=r")
3094 (match_operand:SI 1 "register_operand" "r"))
3096 (compare:CC (match_operand:SI 2 "register_operand" "r")
3098 "(rtx_equal_p (operands[2], operands[0])
3099 || rtx_equal_p (operands[2], operands[1]))
3100 && ! FP_REG_P (operands[0]) && ! FP_REG_P (operands[1])"
3103 ;; Do {sign,zero}-extended compares somewhat more efficiently.
3104 ;; ??? Is this now the Right Way to do this? Or will SCRATCH
3105 ;; eventually have some impact here?
3108 [(set (match_operand:HI 0 "register_operand" "")
3109 (match_operand:HI 1 "memory_operand" ""))
3110 (set (match_operand:SI 2 "register_operand" "")
3111 (sign_extend:SI (match_dup 0)))
3113 (compare:CC (match_dup 2)
3116 "ldsh %1,%0\;orcc %0,%%g0,%2")
3119 [(set (match_operand:QI 0 "register_operand" "")
3120 (match_operand:QI 1 "memory_operand" ""))
3121 (set (match_operand:SI 2 "register_operand" "")
3122 (sign_extend:SI (match_dup 0)))
3124 (compare:CC (match_dup 2)
3127 "ldsb %1,%0\;orcc %0,%%g0,%2")
3130 [(set (match_operand:HI 0 "register_operand" "")
3131 (match_operand:HI 1 "memory_operand" ""))
3132 (set (match_operand:SI 2 "register_operand" "")
3133 (sign_extend:SI (match_dup 0)))]
3134 "dead_or_set_p (insn, operands[0])"
3137 warning (\"bad peephole\");
3138 if (! MEM_VOLATILE_P (operands[1]))
3140 return \"ldsh %1,%2\";
3144 [(set (match_operand:QI 0 "register_operand" "")
3145 (match_operand:QI 1 "memory_operand" ""))
3146 (set (match_operand:SI 2 "register_operand" "")
3147 (sign_extend:SI (match_dup 0)))]
3148 "dead_or_set_p (insn, operands[0])"
3151 warning (\"bad peephole\");
3152 if (! MEM_VOLATILE_P (operands[1]))
3154 return \"ldsb %1,%2\";
3157 ;; Floating-point move peepholes
3160 [(set (match_operand:SI 0 "register_operand" "=r")
3161 (lo_sum:SI (match_dup 0)
3162 (match_operand:SI 1 "immediate_operand" "i")))
3163 (set (match_operand:DF 2 "register_operand" "=fr")
3164 (mem:DF (match_dup 0)))]
3165 "RTX_UNCHANGING_P (operands[1]) && reg_unused_after (operands[0], insn)"
3168 /* Go by way of output_move_double in case the register in operand 2
3169 is not properly aligned for ldd. */
3170 operands[1] = gen_rtx (MEM, DFmode,
3171 gen_rtx (LO_SUM, SImode, operands[0], operands[1]));
3172 operands[0] = operands[2];
3173 return output_move_double (operands);
3177 [(set (match_operand:SI 0 "register_operand" "=r")
3178 (lo_sum:SI (match_dup 0)
3179 (match_operand:SI 1 "immediate_operand" "i")))
3180 (set (match_operand:SF 2 "register_operand" "=fr")
3181 (mem:SF (match_dup 0)))]
3182 "RTX_UNCHANGING_P (operands[1]) && reg_unused_after (operands[0], insn)"
3183 "ld [%0+%%lo(%a1)],%2")
3185 ;; Return peepholes. First the "normal" ones
3187 ;; ??? There are QImode, HImode, and SImode versions of this pattern.
3188 ;; It might be possible to write one more general pattern instead of three.
3191 [(set (match_operand:QI 0 "restore_operand" "")
3192 (match_operand:QI 1 "arith_operand" "rI"))
3197 if (current_function_returns_struct)
3198 return \"jmp %%i7+12\;restore %%g0,%1,%Y0\";
3200 return \"ret\;restore %%g0,%1,%Y0\";
3202 [(set_attr "type" "multi")])
3205 [(set (match_operand:HI 0 "restore_operand" "")
3206 (match_operand:HI 1 "arith_operand" "rI"))
3211 if (current_function_returns_struct)
3212 return \"jmp %%i7+12\;restore %%g0,%1,%Y0\";
3214 return \"ret\;restore %%g0,%1,%Y0\";
3216 [(set_attr "type" "multi")])
3219 [(set (match_operand:SI 0 "restore_operand" "")
3220 (match_operand:SI 1 "arith_operand" "rI"))
3225 if (current_function_returns_struct)
3226 return \"jmp %%i7+12\;restore %%g0,%1,%Y0\";
3228 return \"ret\;restore %%g0,%1,%Y0\";
3230 [(set_attr "type" "multi")])
3232 ;; The following pattern is only generated by delayed-branch scheduling,
3233 ;; when the insn winds up in the epilogue. This can only happen when
3234 ;; ! TARGET_FPU because otherwise fp return values are in %f0.
3236 [(set (match_operand:SF 0 "restore_operand" "r")
3237 (match_operand:SF 1 "register_operand" "r"))
3239 "! TARGET_FPU && ! TARGET_EPILOGUE"
3242 if (current_function_returns_struct)
3243 return \"jmp %%i7+12\;restore %%g0,%1,%Y0\";
3245 return \"ret\;restore %%g0,%1,%Y0\";
3247 [(set_attr "type" "multi")])
3250 [(set (match_operand:SI 0 "restore_operand" "")
3251 (plus:SI (match_operand:SI 1 "arith_operand" "%r")
3252 (match_operand:SI 2 "arith_operand" "rI")))
3257 if (current_function_returns_struct)
3258 return \"jmp %%i7+12\;restore %r1,%2,%Y0\";
3260 return \"ret\;restore %r1,%2,%Y0\";
3262 [(set_attr "type" "multi")])
3264 ;; Turned off because it should never match (subtracting a constant
3265 ;; is turned into addition) and because it would do the wrong thing
3266 ;; when operand 2 is -4096 (--4096 == 4096 is not a valid immediate).
3268 ;; [(set (match_operand:SI 0 "restore_operand" "")
3269 ;; (minus:SI (match_operand:SI 1 "register_operand" "r")
3270 ;; (match_operand:SI 2 "small_int" "I")))
3272 ;; "! TARGET_EPILOGUE"
3273 ;; "ret\;restore %1,-(%2),%Y0"
3274 ;; [(set_attr "type" "multi")])
3276 ;; The following pattern is only generated by delayed-branch scheduling,
3277 ;; when the insn winds up in the epilogue.
3280 (match_operand:SF 0 "register_operand" "f"))
3283 "ret\;fmovs %0,%%f0"
3284 [(set_attr "type" "multi")])
3286 ;; Now peepholes to go a call followed by a jump.
3289 [(parallel [(set (match_operand 0 "" "")
3290 (call (mem:SI (match_operand:SI 1 "call_operand_address" "S,r"))
3291 (match_operand 2 "" "")))
3292 (clobber (reg:SI 15))])
3293 (set (pc) (label_ref (match_operand 3 "" "")))]
3294 "short_branch (INSN_UID (insn), INSN_UID (operands[3]))"
3297 return \"call %a1,%2\;add %%o7,(%l3-.-4),%%o7\";
3301 [(parallel [(call (mem:SI (match_operand:SI 0 "call_operand_address" "S,r"))
3302 (match_operand 1 "" ""))
3303 (clobber (reg:SI 15))])
3304 (set (pc) (label_ref (match_operand 2 "" "")))]
3305 "short_branch (INSN_UID (insn), INSN_UID (operands[2]))"
3308 return \"call %a0,%1\;add %%o7,(%l2-.-4),%%o7\";
3312 [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
3313 (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
3315 (clobber (reg:CC 0))])
3316 (set (reg:CC 0) (compare (match_dup 0) (const_int 0)))]
3320 ;;- Local variables:
3322 ;;- comment-start: ";;- "
3323 ;;- eval: (set-syntax-table (copy-sequence (syntax-table)))
3324 ;;- eval: (modify-syntax-entry ?[ "(]")
3325 ;;- eval: (modify-syntax-entry ?] ")[")
3326 ;;- eval: (modify-syntax-entry ?{ "(}")
3327 ;;- eval: (modify-syntax-entry ?} "){")