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")
1380 (zero_extend:HI (match_operand:QI 1 "sparc_operand" "r,Q")))]
1381 "GET_CODE (operands[1]) != CONST_INT"
1385 [(set_attr "type" "unary,load")
1386 (set_attr "length" "1")])
1388 (define_expand "zero_extendqisi2"
1389 [(set (match_operand:SI 0 "register_operand" "")
1390 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
1395 [(set (match_operand:SI 0 "register_operand" "=r,r")
1396 (zero_extend:SI (match_operand:QI 1 "sparc_operand" "r,Q")))]
1397 "GET_CODE (operands[1]) != CONST_INT"
1401 [(set_attr "type" "unary,load")
1402 (set_attr "length" "1")])
1406 (compare:CC (zero_extend:SI (match_operand:QI 0 "register_operand" "r"))
1409 "andcc %0,0xff,%%g0"
1410 [(set_attr "type" "compare")])
1414 (compare:CC (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
1416 (set (match_operand:SI 0 "register_operand" "=r")
1417 (zero_extend:SI (match_dup 1)))]
1420 [(set_attr "type" "unary")])
1422 ;;- sign extension instructions
1424 ;; These patterns originally accepted general_operands, however, slightly
1425 ;; better code is generated by only accepting register_operands, and then
1426 ;; letting combine generate the lds[hb] insns.
1428 (define_expand "extendhisi2"
1429 [(set (match_operand:SI 0 "register_operand" "")
1430 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
1434 rtx temp = gen_reg_rtx (SImode);
1435 rtx shift_16 = gen_rtx (CONST_INT, VOIDmode, 16);
1437 if (GET_CODE (operand1) == SUBREG)
1438 operand1 = XEXP (operand1, 0);
1440 emit_insn (gen_ashlsi3 (temp, gen_rtx (SUBREG, SImode, operand1, 0),
1442 emit_insn (gen_ashrsi3 (operand0, temp, shift_16));
1447 [(set (match_operand:SI 0 "register_operand" "=r")
1448 (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
1451 [(set_attr "type" "load")])
1453 (define_expand "extendqihi2"
1454 [(set (match_operand:HI 0 "register_operand" "")
1455 (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
1459 rtx temp = gen_reg_rtx (SImode);
1460 rtx shift_24 = gen_rtx (CONST_INT, VOIDmode, 24);
1462 if (GET_CODE (operand1) == SUBREG)
1463 operand1 = XEXP (operand1, 0);
1464 if (GET_CODE (operand0) == SUBREG)
1465 operand0 = XEXP (operand0, 0);
1466 emit_insn (gen_ashlsi3 (temp, gen_rtx (SUBREG, SImode, operand1, 0),
1468 if (GET_MODE (operand0) != SImode)
1469 operand0 = gen_rtx (SUBREG, SImode, operand0, 0);
1470 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
1475 [(set (match_operand:HI 0 "register_operand" "=r")
1476 (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
1479 [(set_attr "type" "load")])
1481 (define_expand "extendqisi2"
1482 [(set (match_operand:SI 0 "register_operand" "")
1483 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
1487 rtx temp = gen_reg_rtx (SImode);
1488 rtx shift_24 = gen_rtx (CONST_INT, VOIDmode, 24);
1490 if (GET_CODE (operand1) == SUBREG)
1491 operand1 = XEXP (operand1, 0);
1492 emit_insn (gen_ashlsi3 (temp, gen_rtx (SUBREG, SImode, operand1, 0),
1494 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
1499 [(set (match_operand:SI 0 "register_operand" "=r")
1500 (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
1503 [(set_attr "type" "load")])
1505 ;; Special pattern for optimizing bit-field compares. This is needed
1506 ;; because combine uses this as a canonical form.
1511 (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
1512 (match_operand:SI 1 "small_int" "n")
1513 (match_operand:SI 2 "small_int" "n"))
1515 "INTVAL (operands[2]) > 19"
1518 int len = INTVAL (operands[1]);
1519 int pos = 32 - INTVAL (operands[2]) - len;
1520 unsigned mask = ((1 << len) - 1) << pos;
1522 operands[1] = gen_rtx (CONST_INT, VOIDmode, mask);
1523 return \"andcc %0,%1,%%g0\";
1526 ;; Conversions between float, double and long double.
1528 (define_insn "extendsfdf2"
1529 [(set (match_operand:DF 0 "register_operand" "=f")
1531 (match_operand:SF 1 "register_operand" "f")))]
1534 [(set_attr "type" "fp")])
1536 (define_insn "extendsftf2"
1537 [(set (match_operand:TF 0 "register_operand" "=f")
1539 (match_operand:SF 1 "register_operand" "f")))]
1542 [(set_attr "type" "fp")])
1544 (define_insn "extenddftf2"
1545 [(set (match_operand:TF 0 "register_operand" "=f")
1547 (match_operand:DF 1 "register_operand" "f")))]
1550 [(set_attr "type" "fp")])
1552 (define_insn "truncdfsf2"
1553 [(set (match_operand:SF 0 "register_operand" "=f")
1555 (match_operand:DF 1 "register_operand" "f")))]
1558 [(set_attr "type" "fp")])
1560 (define_insn "trunctfsf2"
1561 [(set (match_operand:SF 0 "register_operand" "=f")
1563 (match_operand:TF 1 "register_operand" "f")))]
1566 [(set_attr "type" "fp")])
1568 (define_insn "trunctfdf2"
1569 [(set (match_operand:DF 0 "register_operand" "=f")
1571 (match_operand:TF 1 "register_operand" "f")))]
1574 [(set_attr "type" "fp")])
1576 ;; Conversion between fixed point and floating point.
1578 (define_insn "floatsisf2"
1579 [(set (match_operand:SF 0 "register_operand" "=f")
1580 (float:SF (match_operand:SI 1 "register_operand" "f")))]
1583 [(set_attr "type" "fp")])
1585 (define_insn "floatsidf2"
1586 [(set (match_operand:DF 0 "register_operand" "=f")
1587 (float:DF (match_operand:SI 1 "register_operand" "f")))]
1590 [(set_attr "type" "fp")])
1592 (define_insn "floatsitf2"
1593 [(set (match_operand:TF 0 "register_operand" "=f")
1594 (float:TF (match_operand:SI 1 "register_operand" "f")))]
1597 [(set_attr "type" "fp")])
1599 ;; Convert a float to an actual integer.
1600 ;; Truncation is performed as part of the conversion.
1602 (define_insn "fix_truncsfsi2"
1603 [(set (match_operand:SI 0 "register_operand" "=f")
1604 (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
1607 [(set_attr "type" "fp")])
1609 (define_insn "fix_truncdfsi2"
1610 [(set (match_operand:SI 0 "register_operand" "=f")
1611 (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "f"))))]
1614 [(set_attr "type" "fp")])
1616 (define_insn "fix_trunctfsi2"
1617 [(set (match_operand:SI 0 "register_operand" "=f")
1618 (fix:SI (fix:TF (match_operand:TF 1 "register_operand" "f"))))]
1621 [(set_attr "type" "fp")])
1623 ;;- arithmetic instructions
1625 (define_insn "adddi3"
1626 [(set (match_operand:DI 0 "register_operand" "=r")
1627 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
1628 (match_operand:DI 2 "arith_double_operand" "rHI")))
1629 (clobber (reg:SI 0))]
1633 rtx op2 = operands[2];
1635 /* If constant is positive, upper bits zeroed, otherwise unchanged.
1636 Give the assembler a chance to pick the move instruction. */
1637 if (GET_CODE (op2) == CONST_INT)
1639 int sign = INTVAL (op2);
1641 return \"addcc %R1,%2,%R0\;addx %1,-1,%0\";
1642 return \"addcc %R1,%2,%R0\;addx %1,0,%0\";
1644 else if (GET_CODE (op2) == CONST_DOUBLE)
1646 int sign = CONST_DOUBLE_HIGH (op2);
1647 operands[2] = gen_rtx (CONST_INT, VOIDmode,
1648 CONST_DOUBLE_LOW (operands[1]));
1650 return \"addcc %R1,%2,%R0\;addx %1,-1,%0\";
1651 return \"addcc %R1,%2,%R0\;addx %1,0,%0\";
1653 return \"addcc %R1,%R2,%R0\;addx %1,%2,%0\";
1655 [(set_attr "length" "2")])
1657 (define_insn "addsi3"
1658 [(set (match_operand:SI 0 "register_operand" "=r")
1659 (plus:SI (match_operand:SI 1 "arith_operand" "%r")
1660 (match_operand:SI 2 "arith_operand" "rI")))]
1665 [(set (reg:CC_NOOV 0)
1666 (compare:CC_NOOV (plus:SI (match_operand:SI 0 "arith_operand" "%r")
1667 (match_operand:SI 1 "arith_operand" "rI"))
1671 [(set_attr "type" "compare")])
1674 [(set (reg:CC_NOOV 0)
1675 (compare:CC_NOOV (plus:SI (match_operand:SI 1 "arith_operand" "%r")
1676 (match_operand:SI 2 "arith_operand" "rI"))
1678 (set (match_operand:SI 0 "register_operand" "=r")
1679 (plus:SI (match_dup 1) (match_dup 2)))]
1683 (define_insn "subdi3"
1684 [(set (match_operand:DI 0 "register_operand" "=r")
1685 (minus:DI (match_operand:DI 1 "register_operand" "r")
1686 (match_operand:DI 2 "arith_double_operand" "rHI")))
1687 (clobber (reg:SI 0))]
1691 rtx op2 = operands[2];
1693 /* If constant is positive, upper bits zeroed, otherwise unchanged.
1694 Give the assembler a chance to pick the move instruction. */
1695 if (GET_CODE (op2) == CONST_INT)
1697 int sign = INTVAL (op2);
1699 return \"subcc %R1,%2,%R0\;subx %1,-1,%0\";
1700 return \"subcc %R1,%2,%R0\;subx %1,0,%0\";
1702 else if (GET_CODE (op2) == CONST_DOUBLE)
1704 int sign = CONST_DOUBLE_HIGH (op2);
1705 operands[2] = gen_rtx (CONST_INT, VOIDmode,
1706 CONST_DOUBLE_LOW (operands[1]));
1708 return \"subcc %R1,%2,%R0\;subx %1,-1,%0\";
1709 return \"subcc %R1,%2,%R0\;subx %1,0,%0\";
1711 return \"subcc %R1,%R2,%R0\;subx %1,%2,%0\";
1713 [(set_attr "length" "2")])
1715 (define_insn "subsi3"
1716 [(set (match_operand:SI 0 "register_operand" "=r")
1717 (minus:SI (match_operand:SI 1 "register_operand" "r")
1718 (match_operand:SI 2 "arith_operand" "rI")))]
1723 [(set (reg:CC_NOOV 0)
1724 (compare:CC_NOOV (minus:SI (match_operand:SI 0 "register_operand" "r")
1725 (match_operand:SI 1 "arith_operand" "rI"))
1729 [(set_attr "type" "compare")])
1732 [(set (reg:CC_NOOV 0)
1733 (compare:CC_NOOV (minus:SI (match_operand:SI 1 "register_operand" "r")
1734 (match_operand:SI 2 "arith_operand" "rI"))
1736 (set (match_operand:SI 0 "register_operand" "=r")
1737 (minus:SI (match_dup 1) (match_dup 2)))]
1741 (define_insn "mulsi3"
1742 [(set (match_operand:SI 0 "register_operand" "=r")
1743 (mult:SI (match_operand:SI 1 "arith_operand" "%r")
1744 (match_operand:SI 2 "arith_operand" "rI")))]
1745 "TARGET_V8 || TARGET_SPARCLITE"
1748 ;; It is not known whether this will match.
1751 [(set (match_operand:SI 0 "register_operand" "=r")
1752 (mult:SI (match_operand:SI 1 "arith_operand" "%r")
1753 (match_operand:SI 2 "arith_operand" "rI")))
1754 (set (reg:CC_NOOV 0)
1755 (compare:CC_NOOV (mult:SI (match_dup 1) (match_dup 2))
1757 "TARGET_V8 || TARGET_SPARCLITE"
1760 (define_expand "mulsidi3"
1761 [(set (match_operand:DI 0 "register_operand" "")
1762 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
1763 (sign_extend:DI (match_operand:SI 2 "arith_operand" ""))))]
1764 "TARGET_V8 || TARGET_SPARCLITE"
1767 if (CONSTANT_P (operands[2]))
1769 emit_insn (gen_const_mulsidi3 (operands[0], operands[1], operands[2]));
1775 [(set (match_operand:DI 0 "register_operand" "=r")
1776 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
1777 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
1778 "TARGET_V8 || TARGET_SPARCLITE"
1779 "smul %1,%2,%R0\;rd %%y,%0"
1780 [(set_attr "length" "2")])
1782 ;; Extra pattern, because sign_extend of a constant isn't legal.
1784 (define_insn "const_mulsidi3"
1785 [(set (match_operand:DI 0 "register_operand" "=r")
1786 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
1787 (match_operand:SI 2 "small_int" "I")))]
1788 "TARGET_V8 || TARGET_SPARCLITE"
1789 "smul %1,%2,%R0\;rd %%y,%0"
1790 [(set_attr "length" "2")])
1792 (define_expand "umulsidi3"
1793 [(set (match_operand:DI 0 "register_operand" "")
1794 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
1795 (zero_extend:DI (match_operand:SI 2 "arith_operand" ""))))]
1796 "TARGET_V8 || TARGET_SPARCLITE"
1799 if (CONSTANT_P (operands[2]))
1801 emit_insn (gen_const_umulsidi3 (operands[0], operands[1], operands[2]));
1807 [(set (match_operand:DI 0 "register_operand" "=r")
1808 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
1809 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
1810 "TARGET_V8 || TARGET_SPARCLITE"
1811 "umul %1,%2,%R0\;rd %%y,%0"
1812 [(set_attr "length" "2")])
1814 ;; Extra pattern, because sign_extend of a constant isn't legal.
1816 (define_insn "const_umulsidi3"
1817 [(set (match_operand:DI 0 "register_operand" "=r")
1818 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
1819 (match_operand:SI 2 "small_int" "I")))]
1820 "TARGET_V8 || TARGET_SPARCLITE"
1821 "umul %1,%2,%R0\;rd %%y,%0"
1822 [(set_attr "length" "2")])
1824 ;; The architecture specifies that there must be 3 instructions between
1825 ;; a y register write and a use of it for correct results.
1827 (define_insn "divsi3"
1828 [(set (match_operand:SI 0 "register_operand" "=r")
1829 (div:SI (match_operand:SI 1 "register_operand" "r")
1830 (match_operand:SI 2 "arith_operand" "rI")))
1831 (clobber (match_scratch:SI 3 "=&r"))]
1833 "sra %1,31,%3\;wr %%g0,%3,%%y\;nop\;nop\;nop\;sdiv %1,%2,%0"
1834 [(set_attr "length" "6")])
1836 ;; It is not known whether this will match.
1839 [(set (match_operand:SI 0 "register_operand" "=r")
1840 (div:SI (match_operand:SI 1 "register_operand" "r")
1841 (match_operand:SI 2 "arith_operand" "rI")))
1843 (compare:CC (div:SI (match_dup 1) (match_dup 2))
1845 (clobber (match_scratch:SI 3 "=&r"))]
1847 "sra %1,31,%3\;wr %%g0,%3,%%y\;nop\;nop\;nop\;sdivcc %1,%2,%0"
1848 [(set_attr "length" "6")])
1850 (define_insn "udivsi3"
1851 [(set (match_operand:SI 0 "register_operand" "=r")
1852 (udiv:SI (match_operand:SI 1 "register_operand" "r")
1853 (match_operand:SI 2 "arith_operand" "rI")))]
1855 "wr %%g0,%%g0,%%y\;nop\;nop\;nop\;udiv %1,%2,%0"
1856 [(set_attr "length" "5")])
1858 ;; It is not known whether this will match.
1861 [(set (match_operand:SI 0 "register_operand" "=r")
1862 (udiv:SI (match_operand:SI 1 "register_operand" "r")
1863 (match_operand:SI 2 "arith_operand" "rI")))
1865 (compare:CC (udiv:SI (match_dup 1) (match_dup 2))
1868 "wr %%g0,%%g0,%%y\;nop\;nop\;nop\;udivcc %1,%2,%0"
1869 [(set_attr "length" "5")])
1871 ;;- and instructions
1872 ;; We define DImode `and` so with DImode `not` we can get
1873 ;; DImode `andn`. Other combinations are possible.
1875 (define_expand "anddi3"
1876 [(set (match_operand:DI 0 "register_operand" "")
1877 (and:DI (match_operand:DI 1 "arith_double_operand" "")
1878 (match_operand:DI 2 "arith_double_operand" "")))]
1883 [(set (match_operand:DI 0 "register_operand" "=r")
1884 (and:DI (match_operand:DI 1 "arith_double_operand" "%r")
1885 (match_operand:DI 2 "arith_double_operand" "rHI")))]
1889 rtx op2 = operands[2];
1891 /* If constant is positive, upper bits zeroed, otherwise unchanged.
1892 Give the assembler a chance to pick the move instruction. */
1893 if (GET_CODE (op2) == CONST_INT)
1895 int sign = INTVAL (op2);
1897 return \"mov %1,%0\;and %R1,%2,%R0\";
1898 return \"mov 0,%0\;and %R1,%2,%R0\";
1900 else if (GET_CODE (op2) == CONST_DOUBLE)
1902 int sign = CONST_DOUBLE_HIGH (op2);
1903 operands[2] = gen_rtx (CONST_INT, VOIDmode,
1904 CONST_DOUBLE_LOW (operands[1]));
1906 return \"mov %1,%0\;and %R1,%2,%R0\";
1907 return \"mov 0,%0\;and %R1,%2,%R0\";
1909 return \"and %1,%2,%0\;and %R1,%R2,%R0\";
1911 [(set_attr "length" "2")])
1913 (define_insn "andsi3"
1914 [(set (match_operand:SI 0 "register_operand" "=r")
1915 (and:SI (match_operand:SI 1 "arith_operand" "%r")
1916 (match_operand:SI 2 "arith_operand" "rI")))]
1921 [(set (match_operand:SI 0 "register_operand" "")
1922 (and:SI (match_operand:SI 1 "register_operand" "")
1923 (match_operand:SI 2 "" "")))
1924 (clobber (match_operand:SI 3 "register_operand" ""))]
1925 "GET_CODE (operands[2]) == CONST_INT
1926 && !SMALL_INT (operands[2])
1927 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
1928 [(set (match_dup 3) (match_dup 4))
1929 (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 1)))]
1932 operands[4] = gen_rtx (CONST_INT, VOIDmode, ~INTVAL (operands[2]));
1936 [(set (match_operand:DI 0 "register_operand" "=r")
1937 (and:DI (not:DI (match_operand:DI 1 "register_operand" "r"))
1938 (match_operand:DI 2 "register_operand" "r")))]
1940 "andn %2,%1,%0\;andn %R2,%R1,%R0"
1941 [(set_attr "length" "2")])
1944 [(set (match_operand:SI 0 "register_operand" "=r")
1945 (and:SI (not:SI (match_operand:SI 1 "register_operand" "r"))
1946 (match_operand:SI 2 "register_operand" "r")))]
1950 (define_expand "iordi3"
1951 [(set (match_operand:DI 0 "register_operand" "")
1952 (ior:DI (match_operand:DI 1 "arith_double_operand" "")
1953 (match_operand:DI 2 "arith_double_operand" "")))]
1958 [(set (match_operand:DI 0 "register_operand" "=r")
1959 (ior:DI (match_operand:DI 1 "arith_double_operand" "%r")
1960 (match_operand:DI 2 "arith_double_operand" "rHI")))]
1964 rtx op2 = operands[2];
1966 /* If constant is positive, upper bits zeroed, otherwise unchanged.
1967 Give the assembler a chance to pick the move instruction. */
1968 if (GET_CODE (op2) == CONST_INT)
1970 int sign = INTVAL (op2);
1972 return \"mov -1,%0\;or %R1,%2,%R0\";
1973 return \"mov %1,%0\;or %R1,%2,%R0\";
1975 else if (GET_CODE (op2) == CONST_DOUBLE)
1977 int sign = CONST_DOUBLE_HIGH (op2);
1978 operands[2] = gen_rtx (CONST_INT, VOIDmode,
1979 CONST_DOUBLE_LOW (operands[1]));
1981 return \"mov -1,%0\;or %R1,%2,%R0\";
1982 return \"mov %1,%0\;or %R1,%2,%R0\";
1984 return \"or %1,%2,%0\;or %R1,%R2,%R0\";
1986 [(set_attr "length" "2")])
1988 (define_insn "iorsi3"
1989 [(set (match_operand:SI 0 "register_operand" "=r")
1990 (ior:SI (match_operand:SI 1 "arith_operand" "%r")
1991 (match_operand:SI 2 "arith_operand" "rI")))]
1996 [(set (match_operand:SI 0 "register_operand" "")
1997 (ior:SI (match_operand:SI 1 "register_operand" "")
1998 (match_operand:SI 2 "" "")))
1999 (clobber (match_operand:SI 3 "register_operand" ""))]
2000 "GET_CODE (operands[2]) == CONST_INT
2001 && !SMALL_INT (operands[2])
2002 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
2003 [(set (match_dup 3) (match_dup 4))
2004 (set (match_dup 0) (ior:SI (not:SI (match_dup 3)) (match_dup 1)))]
2007 operands[4] = gen_rtx (CONST_INT, VOIDmode, ~INTVAL (operands[2]));
2011 [(set (match_operand:DI 0 "register_operand" "=r")
2012 (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r"))
2013 (match_operand:DI 2 "register_operand" "r")))]
2015 "orn %2,%1,%0\;orn %R2,%R1,%R0"
2016 [(set_attr "length" "2")])
2019 [(set (match_operand:SI 0 "register_operand" "=r")
2020 (ior:SI (not:SI (match_operand:SI 1 "register_operand" "r"))
2021 (match_operand:SI 2 "register_operand" "r")))]
2025 (define_expand "xordi3"
2026 [(set (match_operand:DI 0 "register_operand" "")
2027 (xor:DI (match_operand:DI 1 "arith_double_operand" "")
2028 (match_operand:DI 2 "arith_double_operand" "")))]
2033 [(set (match_operand:DI 0 "register_operand" "=r")
2034 (xor:DI (match_operand:DI 1 "arith_double_operand" "%r")
2035 (match_operand:DI 2 "arith_double_operand" "rHI")))]
2039 rtx op2 = operands[2];
2041 /* If constant is positive, upper bits zeroed, otherwise unchanged.
2042 Give the assembler a chance to pick the move instruction. */
2043 if (GET_CODE (op2) == CONST_INT)
2045 int sign = INTVAL (op2);
2047 return \"xor %1,-1,%0\;xor %R1,%2,%R0\";
2048 return \"mov %1,%0\;xor %R1,%2,%R0\";
2050 else if (GET_CODE (op2) == CONST_DOUBLE)
2052 int sign = CONST_DOUBLE_HIGH (op2);
2053 operands[2] = gen_rtx (CONST_INT, VOIDmode,
2054 CONST_DOUBLE_LOW (operands[1]));
2056 return \"xor %1,-1,%0\;xor %R1,%2,%R0\";
2057 return \"mov %1,%0\;xor %R1,%2,%R0\";
2059 return \"xor %1,%2,%0\;xor %R1,%R2,%R0\";
2061 [(set_attr "length" "2")])
2063 (define_insn "xorsi3"
2064 [(set (match_operand:SI 0 "register_operand" "=r")
2065 (xor:SI (match_operand:SI 1 "arith_operand" "%rJ")
2066 (match_operand:SI 2 "arith_operand" "rI")))]
2071 [(set (match_operand:SI 0 "register_operand" "")
2072 (xor:SI (match_operand:SI 1 "register_operand" "")
2073 (match_operand:SI 2 "" "")))
2074 (clobber (match_operand:SI 3 "register_operand" ""))]
2075 "GET_CODE (operands[2]) == CONST_INT
2076 && !SMALL_INT (operands[2])
2077 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
2078 [(set (match_dup 3) (match_dup 4))
2079 (set (match_dup 0) (not:SI (xor:SI (match_dup 3) (match_dup 1))))]
2082 operands[4] = gen_rtx (CONST_INT, VOIDmode, ~INTVAL (operands[2]));
2086 [(set (match_operand:SI 0 "register_operand" "")
2087 (not:SI (xor:SI (match_operand:SI 1 "register_operand" "")
2088 (match_operand:SI 2 "" ""))))
2089 (clobber (match_operand:SI 3 "register_operand" ""))]
2090 "GET_CODE (operands[2]) == CONST_INT
2091 && !SMALL_INT (operands[2])
2092 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
2093 [(set (match_dup 3) (match_dup 4))
2094 (set (match_dup 0) (xor:SI (match_dup 3) (match_dup 1)))]
2097 operands[4] = gen_rtx (CONST_INT, VOIDmode, ~INTVAL (operands[2]));
2100 ;; xnor patterns. Note that (a ^ ~b) == (~a ^ b) == ~(a ^ b).
2101 ;; Combine now canonicalizes to the rightmost expression.
2103 [(set (match_operand:DI 0 "register_operand" "=r")
2104 (not:DI (xor:DI (match_operand:DI 1 "register_operand" "r")
2105 (match_operand:DI 2 "register_operand" "r"))))]
2107 "xnor %1,%2,%0\;xnor %R1,%R2,%R0"
2108 [(set_attr "length" "2")])
2111 [(set (match_operand:SI 0 "register_operand" "=r")
2112 (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
2113 (match_operand:SI 2 "arith_operand" "rI"))))]
2117 ;; These correspond to the above in the case where we also (or only)
2118 ;; want to set the condition code.
2123 (match_operator:SI 2 "cc_arithop"
2124 [(match_operand:SI 0 "arith_operand" "%r")
2125 (match_operand:SI 1 "arith_operand" "rI")])
2129 [(set_attr "type" "compare")])
2134 (match_operator:SI 3 "cc_arithop"
2135 [(match_operand:SI 1 "arith_operand" "%r")
2136 (match_operand:SI 2 "arith_operand" "rI")])
2138 (set (match_operand:SI 0 "register_operand" "=r")
2146 (not:SI (xor:SI (match_operand:SI 0 "reg_or_0_operand" "%rJ")
2147 (match_operand:SI 1 "arith_operand" "rI")))
2150 "xnorcc %r0,%1,%%g0"
2151 [(set_attr "type" "compare")])
2156 (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
2157 (match_operand:SI 2 "arith_operand" "rI")))
2159 (set (match_operand:SI 0 "register_operand" "=r")
2160 (not:SI (xor:SI (match_dup 1) (match_dup 2))))]
2167 (match_operator:SI 2 "cc_arithopn"
2168 [(not:SI (match_operand:SI 0 "arith_operand" "rI"))
2169 (match_operand:SI 1 "reg_or_0_operand" "rJ")])
2173 [(set_attr "type" "compare")])
2178 (match_operator:SI 3 "cc_arithopn"
2179 [(not:SI (match_operand:SI 1 "arith_operand" "rI"))
2180 (match_operand:SI 2 "reg_or_0_operand" "rJ")])
2182 (set (match_operand:SI 0 "register_operand" "=r")
2187 ;; We cannot use the "neg" pseudo insn because the Sun assembler
2188 ;; does not know how to make it work for constants.
2190 (define_insn "negdi2"
2191 [(set (match_operand:DI 0 "register_operand" "=r")
2192 (neg:DI (match_operand:DI 1 "register_operand" "r")))
2193 (clobber (reg:SI 0))]
2195 "subcc %%g0,%R1,%R0\;subx %%g0,%1,%0"
2196 [(set_attr "type" "unary")
2197 (set_attr "length" "2")])
2199 (define_insn "negsi2"
2200 [(set (match_operand:SI 0 "general_operand" "=r")
2201 (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
2204 [(set_attr "type" "unary")])
2207 [(set (reg:CC_NOOV 0)
2208 (compare:CC_NOOV (neg:SI (match_operand:SI 0 "arith_operand" "rI"))
2211 "subcc %%g0,%0,%%g0"
2212 [(set_attr "type" "compare")])
2215 [(set (reg:CC_NOOV 0)
2216 (compare:CC_NOOV (neg:SI (match_operand:SI 1 "arith_operand" "rI"))
2218 (set (match_operand:SI 0 "register_operand" "=r")
2219 (neg:SI (match_dup 1)))]
2222 [(set_attr "type" "unary")])
2224 ;; We cannot use the "not" pseudo insn because the Sun assembler
2225 ;; does not know how to make it work for constants.
2226 (define_expand "one_cmpldi2"
2227 [(set (match_operand:DI 0 "register_operand" "=r")
2228 (not:DI (match_operand:DI 1 "arith_double_operand" "rHI")))]
2233 [(set (match_operand:DI 0 "register_operand" "=r")
2234 (not:DI (match_operand:DI 1 "arith_double_operand" "rHI")))]
2238 rtx op1 = operands[1];
2240 if (GET_CODE (op1) == CONST_INT)
2242 int sign = INTVAL (op1);
2244 return \"xnor %%g0,%1,%R0\;xnor %%g0,-1,%0\";
2245 return \"xnor %%g0,%1,%R0\;xnor %%g0,0,%0\";
2247 else if (GET_CODE (op1) == CONST_DOUBLE)
2249 int sign = CONST_DOUBLE_HIGH (op1);
2250 operands[1] = gen_rtx (CONST_INT, VOIDmode,
2251 CONST_DOUBLE_LOW (operands[1]));
2253 return \"xnor %%g0,%1,%R0\;xnor %%g0,-1,%0\";
2254 return \"xnor %%g0,%1,%R0\;xnor %%g0,0,%0\";
2256 return \"xnor %%g0,%1,%0\;xnor %%g0,%R1,%R0\";
2258 [(set_attr "type" "unary")
2259 (set_attr "length" "2")])
2261 (define_insn "one_cmplsi2"
2262 [(set (match_operand:SI 0 "register_operand" "=r")
2263 (not:SI (match_operand:SI 1 "arith_operand" "rI")))]
2266 [(set_attr "type" "unary")])
2270 (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI"))
2273 "xnorcc %%g0,%0,%%g0"
2274 [(set_attr "type" "compare")])
2278 (compare:CC (not:SI (match_operand:SI 1 "arith_operand" "rI"))
2280 (set (match_operand:SI 0 "register_operand" "=r")
2281 (not:SI (match_dup 1)))]
2284 [(set_attr "type" "unary")])
2286 ;; Floating point arithmetic instructions.
2288 (define_insn "addtf3"
2289 [(set (match_operand:TF 0 "register_operand" "=f")
2290 (plus:TF (match_operand:TF 1 "register_operand" "f")
2291 (match_operand:TF 2 "register_operand" "f")))]
2294 [(set_attr "type" "fp")])
2296 (define_insn "adddf3"
2297 [(set (match_operand:DF 0 "register_operand" "=f")
2298 (plus:DF (match_operand:DF 1 "register_operand" "f")
2299 (match_operand:DF 2 "register_operand" "f")))]
2302 [(set_attr "type" "fp")])
2304 (define_insn "addsf3"
2305 [(set (match_operand:SF 0 "register_operand" "=f")
2306 (plus:SF (match_operand:SF 1 "register_operand" "f")
2307 (match_operand:SF 2 "register_operand" "f")))]
2310 [(set_attr "type" "fp")])
2312 (define_insn "subtf3"
2313 [(set (match_operand:TF 0 "register_operand" "=f")
2314 (minus:TF (match_operand:TF 1 "register_operand" "f")
2315 (match_operand:TF 2 "register_operand" "f")))]
2318 [(set_attr "type" "fp")])
2320 (define_insn "subdf3"
2321 [(set (match_operand:DF 0 "register_operand" "=f")
2322 (minus:DF (match_operand:DF 1 "register_operand" "f")
2323 (match_operand:DF 2 "register_operand" "f")))]
2326 [(set_attr "type" "fp")])
2328 (define_insn "subsf3"
2329 [(set (match_operand:SF 0 "register_operand" "=f")
2330 (minus:SF (match_operand:SF 1 "register_operand" "f")
2331 (match_operand:SF 2 "register_operand" "f")))]
2334 [(set_attr "type" "fp")])
2336 (define_insn "multf3"
2337 [(set (match_operand:TF 0 "register_operand" "=f")
2338 (mult:TF (match_operand:TF 1 "register_operand" "f")
2339 (match_operand:TF 2 "register_operand" "f")))]
2342 [(set_attr "type" "fpmul")])
2344 (define_insn "muldf3"
2345 [(set (match_operand:DF 0 "register_operand" "=f")
2346 (mult:DF (match_operand:DF 1 "register_operand" "f")
2347 (match_operand:DF 2 "register_operand" "f")))]
2350 [(set_attr "type" "fpmul")])
2352 (define_insn "mulsf3"
2353 [(set (match_operand:SF 0 "register_operand" "=f")
2354 (mult:SF (match_operand:SF 1 "register_operand" "f")
2355 (match_operand:SF 2 "register_operand" "f")))]
2358 [(set_attr "type" "fpmul")])
2361 [(set (match_operand:DF 0 "register_operand" "=f")
2362 (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "f"))
2363 (float_extend:DF (match_operand:SF 2 "register_operand" "f"))))]
2364 "TARGET_V8 && TARGET_FPU"
2366 [(set_attr "type" "fpmul")])
2369 [(set (match_operand:TF 0 "register_operand" "=f")
2370 (mult:TF (float_extend:TF (match_operand:DF 1 "register_operand" "f"))
2371 (float_extend:TF (match_operand:DF 2 "register_operand" "f"))))]
2372 "TARGET_V8 && TARGET_FPU"
2374 [(set_attr "type" "fpmul")])
2376 (define_insn "divtf3"
2377 [(set (match_operand:TF 0 "register_operand" "=f")
2378 (div:TF (match_operand:TF 1 "register_operand" "f")
2379 (match_operand:TF 2 "register_operand" "f")))]
2382 [(set_attr "type" "fpdiv")])
2384 (define_insn "divdf3"
2385 [(set (match_operand:DF 0 "register_operand" "=f")
2386 (div:DF (match_operand:DF 1 "register_operand" "f")
2387 (match_operand:DF 2 "register_operand" "f")))]
2390 [(set_attr "type" "fpdiv")])
2392 (define_insn "divsf3"
2393 [(set (match_operand:SF 0 "register_operand" "=f")
2394 (div:SF (match_operand:SF 1 "register_operand" "f")
2395 (match_operand:SF 2 "register_operand" "f")))]
2398 [(set_attr "type" "fpdiv")])
2400 (define_insn "negtf2"
2401 [(set (match_operand:TF 0 "register_operand" "=f,f")
2402 (neg:TF (match_operand:TF 1 "register_operand" "0,f")))]
2406 fnegs %1,%0\;fmovs %R1,%R0\;fmovs %S1,%S0\;fmovs %T1,%T0"
2407 [(set_attr "type" "fp")
2408 (set_attr "length" "1,4")])
2410 (define_insn "negdf2"
2411 [(set (match_operand:DF 0 "register_operand" "=f,f")
2412 (neg:DF (match_operand:DF 1 "register_operand" "0,f")))]
2416 fnegs %1,%0\;fmovs %R1,%R0"
2417 [(set_attr "type" "fp")
2418 (set_attr "length" "1,2")])
2420 (define_insn "negsf2"
2421 [(set (match_operand:SF 0 "register_operand" "=f")
2422 (neg:SF (match_operand:SF 1 "register_operand" "f")))]
2425 [(set_attr "type" "fp")])
2427 (define_insn "abstf2"
2428 [(set (match_operand:TF 0 "register_operand" "=f,f")
2429 (abs:TF (match_operand:TF 1 "register_operand" "0,f")))]
2433 fabss %1,%0\;fmovs %R1,%R0\;fmovs %S1,%S0\;fmovs %T1,%T0"
2434 [(set_attr "type" "fp")
2435 (set_attr "length" "1,4")])
2437 (define_insn "absdf2"
2438 [(set (match_operand:DF 0 "register_operand" "=f,f")
2439 (abs:DF (match_operand:DF 1 "register_operand" "0,f")))]
2443 fabss %1,%0\;fmovs %R1,%R0"
2444 [(set_attr "type" "fp")
2445 (set_attr "length" "1,2")])
2447 (define_insn "abssf2"
2448 [(set (match_operand:SF 0 "register_operand" "=f")
2449 (abs:SF (match_operand:SF 1 "register_operand" "f")))]
2452 [(set_attr "type" "fp")])
2454 (define_insn "sqrttf2"
2455 [(set (match_operand:TF 0 "register_operand" "=f")
2456 (sqrt:TF (match_operand:TF 1 "register_operand" "f")))]
2459 [(set_attr "type" "fpsqrt")])
2461 (define_insn "sqrtdf2"
2462 [(set (match_operand:DF 0 "register_operand" "=f")
2463 (sqrt:DF (match_operand:DF 1 "register_operand" "f")))]
2466 [(set_attr "type" "fpsqrt")])
2468 (define_insn "sqrtsf2"
2469 [(set (match_operand:SF 0 "register_operand" "=f")
2470 (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
2473 [(set_attr "type" "fpsqrt")])
2475 ;;- arithmetic shift instructions
2477 ;; We can trivially handle shifting the constant 1 by 64 bits.
2478 ;; For other shifts we use the library routine.
2479 ;; ??? Questionable, we can do better than this can't we?
2480 (define_expand "ashldi3"
2481 [(parallel [(set (match_operand:DI 0 "register_operand" "")
2482 (ashift:DI (match_operand:DI 1 "const_double_operand" "")
2483 (match_operand:SI 2 "register_operand" "")))
2484 (clobber (reg:SI 0))])]
2488 if (GET_CODE (operands[1]) == CONST_DOUBLE
2489 && CONST_DOUBLE_HIGH (operands[1]) == 0
2490 && CONST_DOUBLE_LOW (operands[1]) == 1)
2491 operands[1] = const1_rtx;
2492 else if (operands[1] != const1_rtx)
2496 ;; ??? Questionable, we can do better than this can't we?
2498 [(set (match_operand:DI 0 "register_operand" "=&r")
2499 (ashift:DI (const_int 1)
2500 (match_operand:SI 1 "register_operand" "r")))
2501 (clobber (reg:SI 0))]
2503 "subcc %1,32,%%g0\;addx %%g0,0,%R0\;xor %R0,1,%0\;sll %R0,%1,%R0\;sll %0,%1,%0"
2504 [(set_attr "type" "multi")
2505 (set_attr "length" "5")])
2507 (define_insn "ashlsi3"
2508 [(set (match_operand:SI 0 "register_operand" "=r")
2509 (ashift:SI (match_operand:SI 1 "register_operand" "r")
2510 (match_operand:SI 2 "arith_operand" "rI")))]
2514 (define_insn "ashrsi3"
2515 [(set (match_operand:SI 0 "register_operand" "=r")
2516 (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
2517 (match_operand:SI 2 "arith_operand" "rI")))]
2521 (define_insn "lshrsi3"
2522 [(set (match_operand:SI 0 "register_operand" "=r")
2523 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
2524 (match_operand:SI 2 "arith_operand" "rI")))]
2528 ;; Unconditional and other jump instructions
2529 ;; On the Sparc, by setting the annul bit on an unconditional branch, the
2530 ;; following insn is never executed. This saves us a nop. Dbx does not
2531 ;; handle such branches though, so we only use them when optimizing.
2533 [(set (pc) (label_ref (match_operand 0 "" "")))]
2536 [(set_attr "type" "uncond_branch")])
2538 (define_expand "tablejump"
2539 [(parallel [(set (pc) (match_operand:SI 0 "register_operand" "r"))
2540 (use (label_ref (match_operand 1 "" "")))])]
2544 /* We need to use the PC value in %o7 that was set up when the address
2545 of the label was loaded into a register, so we need different RTL. */
2548 emit_insn (gen_pic_tablejump (operands[0], operands[1]));
2553 (define_insn "pic_tablejump"
2554 [(set (pc) (match_operand:SI 0 "register_operand" "r"))
2555 (use (label_ref (match_operand 1 "" "")))
2559 [(set_attr "type" "uncond_branch")])
2562 [(set (pc) (match_operand:SI 0 "address_operand" "p"))
2563 (use (label_ref (match_operand 1 "" "")))]
2566 [(set_attr "type" "uncond_branch")])
2569 [(set (pc) (label_ref (match_operand 0 "" "")))
2570 (set (reg:SI 15) (label_ref (match_dup 0)))]
2573 [(set_attr "type" "uncond_branch")])
2575 ;; This pattern recognizes the "instruction" that appears in
2576 ;; a function call that wants a structure value,
2577 ;; to inform the called function if compiled with Sun CC.
2579 ; [(match_operand:SI 0 "immediate_operand" "")]
2580 ; "GET_CODE (operands[0]) == CONST_INT && INTVAL (operands[0]) > 0"
2582 ; [(set_attr "type" "marker")])
2584 ;;- jump to subroutine
2585 (define_expand "call"
2586 ;; Note that this expression is not used for generating RTL.
2587 ;; All the RTL is generated explicitly below.
2588 [(call (match_operand:SI 0 "call_operand" "")
2589 (match_operand 3 "" "i"))]
2590 ;; operands[2] is next_arg_register
2591 ;; operands[3] is struct_value_size_rtx.
2595 rtx fn_rtx, nregs_rtx;
2597 if (GET_CODE (XEXP (operands[0], 0)) == LABEL_REF)
2599 /* This is really a PIC sequence. We want to represent
2600 it as a funny jump so it's delay slots can be filled.
2602 ??? But if this really *is* a CALL, will not it clobber the
2603 call-clobbered registers? We lose this if it is a JUMP_INSN.
2604 Why cannot we have delay slots filled if it were a CALL? */
2606 if (INTVAL (operands[3]) > 0)
2607 emit_jump_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (3,
2608 gen_rtx (SET, VOIDmode, pc_rtx,
2609 XEXP (operands[0], 0)),
2611 gen_rtx (CLOBBER, VOIDmode,
2612 gen_rtx (REG, SImode, 15)))));
2614 emit_jump_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (2,
2615 gen_rtx (SET, VOIDmode, pc_rtx,
2616 XEXP (operands[0], 0)),
2617 gen_rtx (CLOBBER, VOIDmode,
2618 gen_rtx (REG, SImode, 15)))));
2622 fn_rtx = operands[0];
2624 /* Count the number of parameter registers being used by this call.
2625 if that argument is NULL, it means we are using them all, which
2626 means 6 on the sparc. */
2629 nregs_rtx = gen_rtx (CONST_INT, VOIDmode, REGNO (operands[2]) - 8);
2631 nregs_rtx = gen_rtx (CONST_INT, VOIDmode, 6);
2633 nregs_rtx = const0_rtx;
2636 if (INTVAL (operands[3]) > 0)
2637 emit_call_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (3,
2638 gen_rtx (CALL, VOIDmode, fn_rtx, nregs_rtx),
2640 gen_rtx (CLOBBER, VOIDmode,
2641 gen_rtx (REG, SImode, 15)))));
2643 emit_call_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (2,
2644 gen_rtx (CALL, VOIDmode, fn_rtx, nregs_rtx),
2645 gen_rtx (CLOBBER, VOIDmode,
2646 gen_rtx (REG, SImode, 15)))));
2650 /* If this call wants a structure value,
2651 emit an unimp insn to let the called function know about this. */
2652 if (INTVAL (operands[3]) > 0)
2654 rtx insn = emit_insn (operands[3]);
2655 SCHED_GROUP_P (insn) = 1;
2663 [(call (mem:SI (match_operand:SI 0 "call_operand_address" "S,r"))
2664 (match_operand 1 "" ""))
2665 (clobber (reg:SI 15))]
2666 ;;- Do not use operand 1 for most machines.
2670 return \"call %a0,%1%#\";
2672 [(set_attr "type" "call")])
2674 ;; This is a call that wants a structure value.
2676 [(call (mem:SI (match_operand:SI 0 "call_operand_address" "S,r"))
2677 (match_operand 1 "" ""))
2678 (match_operand 2 "immediate_operand" "")
2679 (clobber (reg:SI 15))]
2680 ;;- Do not use operand 1 for most machines.
2681 "GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
2684 return \"call %a0,%1\;nop\;unimp %2\";
2686 [(set_attr "type" "call_no_delay_slot")])
2688 (define_expand "call_value"
2689 [(set (match_operand 0 "register_operand" "=rf")
2690 (call (match_operand:SI 1 "" "")
2691 (match_operand 4 "" "")))]
2692 ;; operand 3 is next_arg_register
2696 rtx fn_rtx, nregs_rtx;
2699 fn_rtx = operands[1];
2703 nregs_rtx = gen_rtx (CONST_INT, VOIDmode, REGNO (operands[3]) - 8);
2705 nregs_rtx = gen_rtx (CONST_INT, VOIDmode, 6);
2707 nregs_rtx = const0_rtx;
2711 gen_rtx (SET, VOIDmode, operands[0],
2712 gen_rtx (CALL, VOIDmode, fn_rtx, nregs_rtx)),
2713 gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, 15)));
2715 emit_call_insn (gen_rtx (PARALLEL, VOIDmode, vec));
2721 [(set (match_operand 0 "" "=rf")
2722 (call (mem:SI (match_operand:SI 1 "call_operand_address" "rS"))
2723 (match_operand 2 "" "")))
2724 (clobber (reg:SI 15))]
2725 ;;- Do not use operand 2 for most machines.
2729 return \"call %a1,%2%#\";
2731 [(set_attr "type" "call")])
2733 (define_insn "return"
2736 "* return output_return (operands);"
2737 [(set_attr "type" "multi")])
2744 (define_insn "indirect_jump"
2745 [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
2748 [(set_attr "type" "uncond_branch")])
2750 (define_expand "nonlocal_goto"
2751 [(match_operand:SI 0 "general_operand" "")
2752 (match_operand:SI 1 "general_operand" "")
2753 (match_operand:SI 2 "general_operand" "")
2754 (match_operand:SI 3 "" "")]
2758 /* Trap instruction to flush all the registers window. */
2759 emit_insn (gen_flush_register_windows ());
2760 /* Load the fp value for the containing fn into %fp.
2761 This is needed because operands[2] refers to %fp.
2762 Virtual register instantiation fails if the virtual %fp isn't set from a
2763 register. Thus we must copy operands[0] into a register if it isn't
2765 if (GET_CODE (operands[0]) != REG)
2766 operands[0] = force_reg (SImode, operands[0]);
2767 emit_move_insn (virtual_stack_vars_rtx, operands[0]);
2768 /* Find the containing function's current nonlocal goto handler,
2769 which will do any cleanups and then jump to the label. */
2770 emit_move_insn (gen_rtx (REG, SImode, 8), operands[1]);
2771 /* Restore %fp from stack pointer value for containing function.
2772 The restore insn that follows will move this to %sp,
2773 and reload the appropriate value into %fp. */
2774 emit_move_insn (frame_pointer_rtx, operands[2]);
2775 /* Put in the static chain register the nonlocal label address. */
2776 emit_move_insn (static_chain_rtx, operands[3]);
2777 /* USE of frame_pointer_rtx added for consistency; not clear if
2779 emit_insn (gen_rtx (USE, VOIDmode, frame_pointer_rtx));
2780 emit_insn (gen_rtx (USE, VOIDmode, stack_pointer_rtx));
2781 emit_insn (gen_rtx (USE, VOIDmode, static_chain_rtx));
2782 emit_insn (gen_rtx (USE, VOIDmode, gen_rtx (REG, SImode, 8)));
2783 /* Return, restoring reg window and jumping to goto handler. */
2784 emit_insn (gen_goto_handler_and_restore ());
2788 ;; Special trap insn to flush register windows.
2789 (define_insn "flush_register_windows"
2790 [(unspec_volatile [(const_int 0)] 0)]
2793 [(set_attr "type" "misc")])
2795 (define_insn "goto_handler_and_restore"
2796 [(unspec_volatile [(const_int 0)] 1)]
2798 "jmp %%o0+0\;restore"
2799 [(set_attr "type" "misc")
2800 (set_attr "length" "2")])
2804 ;; The scan instruction searches from the most significant bit while ffs
2805 ;; searches from the least significant bit. The bit index and treatment of
2806 ;; zero also differ. It takes at least 7 instructions to get the proper
2807 ;; result. Here is an obvious 8 instruction seequence.
2809 (define_insn "ffssi2"
2810 [(set (match_operand:SI 0 "register_operand" "=&r")
2811 (ffs:SI (match_operand:SI 1 "register_operand" "r")))
2812 (clobber (match_scratch:SI 2 "=&r"))]
2814 "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"
2815 [(set_attr "type" "multi")
2816 (set_attr "length" "8")])
2818 ;; Split up troublesome insns for better scheduling. */
2820 ;; The following patterns are straightforward. They can be applied
2821 ;; either before or after register allocation.
2824 [(set (match_operator 0 "memop" [(match_operand:SI 1 "symbolic_operand" "")])
2825 (match_operand 2 "reg_or_0_operand" ""))
2826 (clobber (match_operand:SI 3 "register_operand" ""))]
2828 [(set (match_dup 3) (high:SI (match_dup 1)))
2829 (set (match_op_dup 0 [(lo_sum:SI (match_dup 3) (match_dup 1))])
2834 [(set (match_operator 0 "memop"
2835 [(match_operand:SI 1 "immediate_operand" "")])
2836 (match_operand 2 "general_operand" ""))
2837 (clobber (match_operand:SI 3 "register_operand" ""))]
2839 [(set (match_op_dup 0 [(match_dup 1)])
2843 operands[1] = legitimize_pic_address (operands[1], GET_MODE (operands[0]),
2848 [(set (match_operand 0 "register_operand" "")
2849 (match_operator 1 "memop"
2850 [(match_operand:SI 2 "immediate_operand" "")]))]
2853 (match_op_dup 1 [(match_dup 2)]))]
2856 operands[2] = legitimize_pic_address (operands[2], GET_MODE (operands[1]),
2860 ;; Sign- and Zero-extend operations can have symbolic memory operands.
2863 [(set (match_operand 0 "register_operand" "")
2864 (match_operator 1 "extend_op"
2865 [(match_operator 2 "memop"
2866 [(match_operand:SI 3 "immediate_operand" "")])]))]
2869 (match_op_dup 1 [(match_op_dup 2 [(match_dup 3)])]))]
2872 operands[3] = legitimize_pic_address (operands[3], GET_MODE (operands[2]),
2877 [(set (match_operand:SI 0 "register_operand" "")
2878 (match_operand:SI 1 "immediate_operand" ""))]
2879 "! flag_pic && (GET_CODE (operands[1]) == SYMBOL_REF
2880 || GET_CODE (operands[1]) == CONST
2881 || GET_CODE (operands[1]) == LABEL_REF)"
2882 [(set (match_dup 0) (high:SI (match_dup 1)))
2884 (lo_sum:SI (match_dup 0) (match_dup 1)))]
2887 ;; LABEL_REFs are not modified by `legitimize_pic_address`
2888 ;; so do not recurse infinitely in the PIC case.
2890 [(set (match_operand:SI 0 "register_operand" "")
2891 (match_operand:SI 1 "immediate_operand" ""))]
2892 "flag_pic && (GET_CODE (operands[1]) == SYMBOL_REF
2893 || GET_CODE (operands[1]) == CONST)"
2894 [(set (match_dup 0) (match_dup 1))]
2897 operands[1] = legitimize_pic_address (operands[1], Pmode, operands[0], 0);
2900 ;; These split sne/seq insns. The forms of the resulting insns are
2901 ;; somewhat bogus, but they avoid extra patterns and show data dependency.
2902 ;; Nothing will look at these in detail after splitting has occurred.
2905 [(set (match_operand:SI 0 "register_operand" "")
2906 (ne:SI (match_operand:SI 1 "register_operand" "") (const_int 0)))
2907 (clobber (reg:CC 0))]
2909 [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
2911 (set (match_dup 0) (ltu:SI (reg:CC 0) (const_int 0)))]
2915 [(set (match_operand:SI 0 "register_operand" "")
2916 (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "")
2918 (clobber (reg:CC 0))]
2920 [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
2922 (set (match_dup 0) (neg:SI (ltu:SI (reg:CC 0) (const_int 0))))]
2926 [(set (match_operand:SI 0 "register_operand" "")
2927 (eq:SI (match_operand:SI 1 "register_operand" "") (const_int 0)))
2928 (clobber (reg:CC 0))]
2930 [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
2932 (set (match_dup 0) (geu:SI (reg:CC 0) (const_int 0)))]
2936 [(set (match_operand:SI 0 "register_operand" "")
2937 (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "")
2939 (clobber (reg:CC 0))]
2941 [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
2943 (set (match_dup 0) (neg:SI (geu:SI (reg:CC 0) (const_int 0))))]
2947 [(set (match_operand:SI 0 "register_operand" "")
2948 (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "")
2950 (match_operand:SI 2 "register_operand" "")))
2951 (clobber (reg:CC 0))]
2953 [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
2955 (set (match_dup 0) (plus:SI (ltu:SI (reg:CC 0) (const_int 0))
2960 [(set (match_operand:SI 0 "register_operand" "")
2961 (minus:SI (match_operand:SI 2 "register_operand" "")
2962 (ne:SI (match_operand:SI 1 "register_operand" "")
2964 (clobber (reg:CC 0))]
2966 [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
2968 (set (match_dup 0) (minus:SI (match_dup 2)
2969 (ltu:SI (reg:CC 0) (const_int 0))))]
2973 [(set (match_operand:SI 0 "register_operand" "")
2974 (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "")
2976 (match_operand:SI 2 "register_operand" "")))
2977 (clobber (reg:CC 0))]
2979 [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
2981 (set (match_dup 0) (plus:SI (geu:SI (reg:CC 0) (const_int 0))
2986 [(set (match_operand:SI 0 "register_operand" "")
2987 (minus:SI (match_operand:SI 2 "register_operand" "")
2988 (eq:SI (match_operand:SI 1 "register_operand" "")
2990 (clobber (reg:CC 0))]
2992 [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
2994 (set (match_dup 0) (minus:SI (match_dup 2)
2995 (geu:SI (reg:CC 0) (const_int 0))))]
2998 ;; Peepholes go at the end.
3000 ;; Optimize consecutive loads or stores into ldd and std when possible.
3001 ;; The conditions in which we do this are very restricted and are
3002 ;; explained in the code for {registers,memory}_ok_for_ldd functions.
3005 [(set (match_operand:SI 0 "register_operand" "=rf")
3006 (match_operand:SI 1 "memory_operand" ""))
3007 (set (match_operand:SI 2 "register_operand" "=rf")
3008 (match_operand:SI 3 "memory_operand" ""))]
3009 "registers_ok_for_ldd_peep (operands[0], operands[2])
3010 && ! MEM_VOLATILE_P (operands[1]) && ! MEM_VOLATILE_P (operands[3])
3011 && addrs_ok_for_ldd_peep (XEXP (operands[1], 0), XEXP (operands[3], 0))"
3015 [(set (match_operand:SI 0 "memory_operand" "")
3016 (match_operand:SI 1 "register_operand" "rf"))
3017 (set (match_operand:SI 2 "memory_operand" "")
3018 (match_operand:SI 3 "register_operand" "rf"))]
3019 "registers_ok_for_ldd_peep (operands[1], operands[3])
3020 && ! MEM_VOLATILE_P (operands[0]) && ! MEM_VOLATILE_P (operands[2])
3021 && addrs_ok_for_ldd_peep (XEXP (operands[0], 0), XEXP (operands[2], 0))"
3025 [(set (match_operand:SF 0 "register_operand" "=fr")
3026 (match_operand:SF 1 "memory_operand" ""))
3027 (set (match_operand:SF 2 "register_operand" "=fr")
3028 (match_operand:SF 3 "memory_operand" ""))]
3029 "registers_ok_for_ldd_peep (operands[0], operands[2])
3030 && ! MEM_VOLATILE_P (operands[1]) && ! MEM_VOLATILE_P (operands[3])
3031 && addrs_ok_for_ldd_peep (XEXP (operands[1], 0), XEXP (operands[3], 0))"
3035 [(set (match_operand:SF 0 "memory_operand" "")
3036 (match_operand:SF 1 "register_operand" "fr"))
3037 (set (match_operand:SF 2 "memory_operand" "")
3038 (match_operand:SF 3 "register_operand" "fr"))]
3039 "registers_ok_for_ldd_peep (operands[1], operands[3])
3040 && ! MEM_VOLATILE_P (operands[0]) && ! MEM_VOLATILE_P (operands[2])
3041 && addrs_ok_for_ldd_peep (XEXP (operands[0], 0), XEXP (operands[2], 0))"
3045 [(set (match_operand:SI 0 "register_operand" "=rf")
3046 (match_operand:SI 1 "memory_operand" ""))
3047 (set (match_operand:SI 2 "register_operand" "=rf")
3048 (match_operand:SI 3 "memory_operand" ""))]
3049 "registers_ok_for_ldd_peep (operands[2], operands[0])
3050 && ! MEM_VOLATILE_P (operands[3]) && ! MEM_VOLATILE_P (operands[1])
3051 && addrs_ok_for_ldd_peep (XEXP (operands[3], 0), XEXP (operands[1], 0))"
3055 [(set (match_operand:SI 0 "memory_operand" "")
3056 (match_operand:SI 1 "register_operand" "rf"))
3057 (set (match_operand:SI 2 "memory_operand" "")
3058 (match_operand:SI 3 "register_operand" "rf"))]
3059 "registers_ok_for_ldd_peep (operands[3], operands[1])
3060 && ! MEM_VOLATILE_P (operands[2]) && ! MEM_VOLATILE_P (operands[0])
3061 && addrs_ok_for_ldd_peep (XEXP (operands[2], 0), XEXP (operands[0], 0))"
3065 [(set (match_operand:SF 0 "register_operand" "=fr")
3066 (match_operand:SF 1 "memory_operand" ""))
3067 (set (match_operand:SF 2 "register_operand" "=fr")
3068 (match_operand:SF 3 "memory_operand" ""))]
3069 "registers_ok_for_ldd_peep (operands[2], operands[0])
3070 && ! MEM_VOLATILE_P (operands[3]) && ! MEM_VOLATILE_P (operands[1])
3071 && addrs_ok_for_ldd_peep (XEXP (operands[3], 0), XEXP (operands[1], 0))"
3075 [(set (match_operand:SF 0 "memory_operand" "")
3076 (match_operand:SF 1 "register_operand" "fr"))
3077 (set (match_operand:SF 2 "memory_operand" "")
3078 (match_operand:SF 3 "register_operand" "fr"))]
3079 "registers_ok_for_ldd_peep (operands[3], operands[1])
3080 && ! MEM_VOLATILE_P (operands[2]) && ! MEM_VOLATILE_P (operands[0])
3081 && addrs_ok_for_ldd_peep (XEXP (operands[2], 0), XEXP (operands[0], 0))"
3084 ;; Optimize the case of following a reg-reg move with a test
3085 ;; of reg just moved. Don't allow floating point regs for operand 0 or 1.
3086 ;; This can result from a float to fix conversion.
3089 [(set (match_operand:SI 0 "register_operand" "=r")
3090 (match_operand:SI 1 "register_operand" "r"))
3092 (compare:CC (match_operand:SI 2 "register_operand" "r")
3094 "(rtx_equal_p (operands[2], operands[0])
3095 || rtx_equal_p (operands[2], operands[1]))
3096 && ! FP_REG_P (operands[0]) && ! FP_REG_P (operands[1])"
3099 ;; Do {sign,zero}-extended compares somewhat more efficiently.
3100 ;; ??? Is this now the Right Way to do this? Or will SCRATCH
3101 ;; eventually have some impact here?
3104 [(set (match_operand:HI 0 "register_operand" "")
3105 (match_operand:HI 1 "memory_operand" ""))
3106 (set (match_operand:SI 2 "register_operand" "")
3107 (sign_extend:SI (match_dup 0)))
3109 (compare:CC (match_dup 2)
3112 "ldsh %1,%0\;orcc %0,%%g0,%2")
3115 [(set (match_operand:QI 0 "register_operand" "")
3116 (match_operand:QI 1 "memory_operand" ""))
3117 (set (match_operand:SI 2 "register_operand" "")
3118 (sign_extend:SI (match_dup 0)))
3120 (compare:CC (match_dup 2)
3123 "ldsb %1,%0\;orcc %0,%%g0,%2")
3126 [(set (match_operand:HI 0 "register_operand" "")
3127 (match_operand:HI 1 "memory_operand" ""))
3128 (set (match_operand:SI 2 "register_operand" "")
3129 (sign_extend:SI (match_dup 0)))]
3130 "dead_or_set_p (insn, operands[0])"
3133 warning (\"bad peephole\");
3134 if (! MEM_VOLATILE_P (operands[1]))
3136 return \"ldsh %1,%2\";
3140 [(set (match_operand:QI 0 "register_operand" "")
3141 (match_operand:QI 1 "memory_operand" ""))
3142 (set (match_operand:SI 2 "register_operand" "")
3143 (sign_extend:SI (match_dup 0)))]
3144 "dead_or_set_p (insn, operands[0])"
3147 warning (\"bad peephole\");
3148 if (! MEM_VOLATILE_P (operands[1]))
3150 return \"ldsb %1,%2\";
3153 ;; Floating-point move peepholes
3156 [(set (match_operand:SI 0 "register_operand" "=r")
3157 (lo_sum:SI (match_dup 0)
3158 (match_operand:SI 1 "immediate_operand" "i")))
3159 (set (match_operand:DF 2 "register_operand" "=fr")
3160 (mem:DF (match_dup 0)))]
3161 "RTX_UNCHANGING_P (operands[1]) && reg_unused_after (operands[0], insn)"
3164 /* Go by way of output_move_double in case the register in operand 2
3165 is not properly aligned for ldd. */
3166 operands[1] = gen_rtx (MEM, DFmode,
3167 gen_rtx (LO_SUM, SImode, operands[0], operands[1]));
3168 operands[0] = operands[2];
3169 return output_move_double (operands);
3173 [(set (match_operand:SI 0 "register_operand" "=r")
3174 (lo_sum:SI (match_dup 0)
3175 (match_operand:SI 1 "immediate_operand" "i")))
3176 (set (match_operand:SF 2 "register_operand" "=fr")
3177 (mem:SF (match_dup 0)))]
3178 "RTX_UNCHANGING_P (operands[1]) && reg_unused_after (operands[0], insn)"
3179 "ld [%0+%%lo(%a1)],%2")
3181 ;; Return peepholes. First the "normal" ones
3183 ;; ??? There are QImode, HImode, and SImode versions of this pattern.
3184 ;; It might be possible to write one more general pattern instead of three.
3187 [(set (match_operand:QI 0 "restore_operand" "")
3188 (match_operand:QI 1 "arith_operand" "rI"))
3193 if (current_function_returns_struct)
3194 return \"jmp %%i7+12\;restore %%g0,%1,%Y0\";
3196 return \"ret\;restore %%g0,%1,%Y0\";
3198 [(set_attr "type" "multi")])
3201 [(set (match_operand:HI 0 "restore_operand" "")
3202 (match_operand:HI 1 "arith_operand" "rI"))
3207 if (current_function_returns_struct)
3208 return \"jmp %%i7+12\;restore %%g0,%1,%Y0\";
3210 return \"ret\;restore %%g0,%1,%Y0\";
3212 [(set_attr "type" "multi")])
3215 [(set (match_operand:SI 0 "restore_operand" "")
3216 (match_operand:SI 1 "arith_operand" "rI"))
3221 if (current_function_returns_struct)
3222 return \"jmp %%i7+12\;restore %%g0,%1,%Y0\";
3224 return \"ret\;restore %%g0,%1,%Y0\";
3226 [(set_attr "type" "multi")])
3228 ;; The following pattern is only generated by delayed-branch scheduling,
3229 ;; when the insn winds up in the epilogue. This can only happen when
3230 ;; ! TARGET_FPU because otherwise fp return values are in %f0.
3232 [(set (match_operand:SF 0 "restore_operand" "r")
3233 (match_operand:SF 1 "register_operand" "r"))
3235 "! TARGET_FPU && ! TARGET_EPILOGUE"
3238 if (current_function_returns_struct)
3239 return \"jmp %%i7+12\;restore %%g0,%1,%Y0\";
3241 return \"ret\;restore %%g0,%1,%Y0\";
3243 [(set_attr "type" "multi")])
3246 [(set (match_operand:SI 0 "restore_operand" "")
3247 (plus:SI (match_operand:SI 1 "arith_operand" "%r")
3248 (match_operand:SI 2 "arith_operand" "rI")))
3253 if (current_function_returns_struct)
3254 return \"jmp %%i7+12\;restore %r1,%2,%Y0\";
3256 return \"ret\;restore %r1,%2,%Y0\";
3258 [(set_attr "type" "multi")])
3260 ;; Turned off because it should never match (subtracting a constant
3261 ;; is turned into addition) and because it would do the wrong thing
3262 ;; when operand 2 is -4096 (--4096 == 4096 is not a valid immediate).
3264 ;; [(set (match_operand:SI 0 "restore_operand" "")
3265 ;; (minus:SI (match_operand:SI 1 "register_operand" "r")
3266 ;; (match_operand:SI 2 "small_int" "I")))
3268 ;; "! TARGET_EPILOGUE"
3269 ;; "ret\;restore %1,-(%2),%Y0"
3270 ;; [(set_attr "type" "multi")])
3272 ;; The following pattern is only generated by delayed-branch scheduling,
3273 ;; when the insn winds up in the epilogue.
3276 (match_operand:SF 0 "register_operand" "f"))
3279 "ret\;fmovs %0,%%f0"
3280 [(set_attr "type" "multi")])
3282 ;; Now peepholes to go a call followed by a jump.
3285 [(parallel [(set (match_operand 0 "" "")
3286 (call (mem:SI (match_operand:SI 1 "call_operand_address" "S,r"))
3287 (match_operand 2 "" "")))
3288 (clobber (reg:SI 15))])
3289 (set (pc) (label_ref (match_operand 3 "" "")))]
3290 "short_branch (INSN_UID (insn), INSN_UID (operands[3]))"
3293 return \"call %a1,%2\;add %%o7,(%l3-.-4),%%o7\";
3297 [(parallel [(call (mem:SI (match_operand:SI 0 "call_operand_address" "S,r"))
3298 (match_operand 1 "" ""))
3299 (clobber (reg:SI 15))])
3300 (set (pc) (label_ref (match_operand 2 "" "")))]
3301 "short_branch (INSN_UID (insn), INSN_UID (operands[2]))"
3304 return \"call %a0,%1\;add %%o7,(%l2-.-4),%%o7\";
3308 [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
3309 (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
3311 (clobber (reg:CC 0))])
3312 (set (reg:CC 0) (compare (match_dup 0) (const_int 0)))]