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 "movqi"
776 [(set (match_operand:QI 0 "general_operand" "")
777 (match_operand:QI 1 "general_operand" ""))]
781 if (emit_move_sequence (operands, QImode))
786 [(set (match_operand:QI 0 "reg_or_nonsymb_mem_operand" "=r,r,r,Q")
787 (match_operand:QI 1 "move_operand" "rI,K,Q,rJ"))]
788 "register_operand (operands[0], QImode)
789 || register_operand (operands[1], QImode)
790 || operands[1] == const0_rtx"
796 [(set_attr "type" "move,move,load,store")
797 (set_attr "length" "*,1,*,1")])
800 [(set (match_operand:QI 0 "register_operand" "=r")
801 (subreg:QI (lo_sum:SI (match_operand:QI 1 "register_operand" "r")
802 (match_operand 2 "immediate_operand" "in")) 0))]
805 [(set_attr "length" "1")])
808 [(set (mem:QI (match_operand:SI 0 "symbolic_operand" ""))
809 (match_operand:QI 1 "reg_or_0_operand" "rJ"))
810 (clobber (match_scratch:SI 2 "=&r"))]
812 "sethi %%hi(%a0),%2\;stb %r1,[%2+%%lo(%a0)]"
813 [(set_attr "type" "store")
814 (set_attr "length" "2")])
816 (define_expand "movhi"
817 [(set (match_operand:HI 0 "general_operand" "")
818 (match_operand:HI 1 "general_operand" ""))]
822 if (emit_move_sequence (operands, HImode))
827 [(set (match_operand:HI 0 "reg_or_nonsymb_mem_operand" "=r,r,r,Q")
828 (match_operand:HI 1 "move_operand" "rI,K,Q,rJ"))]
829 "register_operand (operands[0], HImode)
830 || register_operand (operands[1], HImode)
831 || operands[1] == const0_rtx"
837 [(set_attr "type" "move,move,load,store")
838 (set_attr "length" "*,1,*,1")])
841 [(set (match_operand:HI 0 "register_operand" "=r")
842 (lo_sum:HI (match_operand:HI 1 "register_operand" "r")
843 (match_operand 2 "immediate_operand" "in")))]
846 [(set_attr "length" "1")])
849 [(set (mem:HI (match_operand:SI 0 "symbolic_operand" ""))
850 (match_operand:HI 1 "reg_or_0_operand" "rJ"))
851 (clobber (match_scratch:SI 2 "=&r"))]
853 "sethi %%hi(%a0),%2\;sth %r1,[%2+%%lo(%a0)]"
854 [(set_attr "type" "store")
855 (set_attr "length" "2")])
857 (define_expand "movsi"
858 [(set (match_operand:SI 0 "general_operand" "")
859 (match_operand:SI 1 "general_operand" ""))]
863 if (emit_move_sequence (operands, SImode))
867 ;; We must support both 'r' and 'f' registers here, because combine may
868 ;; convert SFmode hard registers to SImode hard registers when simplifying
871 ;; We cannot combine the similar 'r' and 'f' constraints, because it causes
872 ;; problems with register allocation. Reload might try to put an integer
873 ;; in an fp register, or an fp number is an integer register.
876 [(set (match_operand:SI 0 "reg_or_nonsymb_mem_operand" "=r,f,r,r,f,Q,Q")
877 (match_operand:SI 1 "move_operand" "rI,!f,K,Q,!Q,rJ,!f"))]
878 "register_operand (operands[0], SImode)
879 || register_operand (operands[1], SImode)
880 || operands[1] == const0_rtx"
889 [(set_attr "type" "move,fp,move,load,load,store,store")
890 (set_attr "length" "*,*,1,*,*,*,*")])
892 ;; Special pic pattern, for loading the address of a label into a register.
893 ;; It clobbers o7 because the call puts the return address (i.e. pc value)
897 [(set (match_operand:SI 0 "register_operand" "=r")
898 (match_operand:SI 1 "move_pic_label" "i"))
899 (set (reg:SI 15) (pc))]
901 "\\n1:\;call 2f\;sethi %%hi(%l1-1b),%0\\n2:\\tor %0,%%lo(%l1-1b),%0\;add %0,%%o7,%0"
902 [(set_attr "type" "multi")
903 (set_attr "length" "4")])
906 [(set (match_operand:DI 0 "register_operand" "=r")
907 (high:DI (match_operand 1 "" "")))]
911 rtx op0 = operands[0];
912 rtx op1 = operands[1];
914 if (GET_CODE (op1) == CONST_INT)
916 operands[0] = operand_subword (op0, 1, 0, DImode);
917 output_asm_insn (\"sethi %%hi(%a1),%0\", operands);
919 operands[0] = operand_subword (op0, 0, 0, DImode);
920 if (INTVAL (op1) < 0)
921 return \"mov -1,%0\";
925 else if (GET_CODE (op1) == CONST_DOUBLE)
927 operands[0] = operand_subword (op0, 1, 0, DImode);
928 operands[1] = gen_rtx (CONST_INT, VOIDmode, CONST_DOUBLE_LOW (op1));
929 output_asm_insn (\"sethi %%hi(%a1),%0\", operands);
931 operands[0] = operand_subword (op0, 0, 0, DImode);
932 operands[1] = gen_rtx (CONST_INT, VOIDmode, CONST_DOUBLE_HIGH (op1));
933 return singlemove_string (operands);
939 [(set_attr "type" "move")
940 (set_attr "length" "2")])
942 ;; For PIC, symbol_refs are put inside unspec so that the optimizer won't
943 ;; confuse them with real addresses.
945 [(set (match_operand:SI 0 "register_operand" "=r")
946 (high:SI (unspec:SI [(match_operand 1 "" "")] 0)))]
949 [(set_attr "type" "move")
950 (set_attr "length" "1")])
953 [(set (match_operand:SI 0 "register_operand" "=r")
954 (high:SI (match_operand 1 "" "")))]
957 [(set_attr "type" "move")
958 (set_attr "length" "1")])
961 [(set (match_operand:HI 0 "register_operand" "=r")
962 (high:HI (match_operand 1 "" "")))]
965 [(set_attr "type" "move")
966 (set_attr "length" "1")])
968 ;; For PIC, symbol_refs are put inside unspec so that the optimizer won't
969 ;; confuse them with real addresses.
971 [(set (match_operand:SI 0 "register_operand" "=r")
972 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
973 (unspec:SI [(match_operand:SI 2 "immediate_operand" "in")] 0)))]
976 ;; Need to set length for this arith insn because operand2
977 ;; is not an "arith_operand".
978 [(set_attr "length" "1")])
980 ;; ??? Can the next two be moved above the PIC stuff?
983 [(set (match_operand:SI 0 "register_operand" "=r")
984 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
985 (match_operand:SI 2 "immediate_operand" "in")))]
988 ;; Need to set length for this arith insn because operand2
989 ;; is not an "arith_operand".
990 [(set_attr "length" "1")])
993 [(set (mem:SI (match_operand:SI 0 "symbolic_operand" ""))
994 (match_operand:SI 1 "reg_or_0_operand" "rJ"))
995 (clobber (match_scratch:SI 2 "=&r"))]
997 "sethi %%hi(%a0),%2\;st %r1,[%2+%%lo(%a0)]"
998 [(set_attr "type" "store")
999 (set_attr "length" "2")])
1001 (define_expand "movdi"
1002 [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand" "")
1003 (match_operand:DI 1 "general_operand" ""))]
1007 if (emit_move_sequence (operands, DImode))
1012 [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand" "=r,Q,r,r,?f,?f,?Q")
1013 (match_operand:DI 1 "general_operand" "r,r,Q,i,f,Q,f"))]
1014 "register_operand (operands[0], DImode)
1015 || register_operand (operands[1], DImode)
1016 || operands[1] == const0_rtx"
1019 if (FP_REG_P (operands[0]) || FP_REG_P (operands[1]))
1020 return output_fp_move_double (operands);
1021 return output_move_double (operands);
1023 [(set_attr "type" "move,store,load,multi,fp,fpload,fpstore")
1024 (set_attr "length" "2,3,3,3,2,3,3")])
1027 [(set (match_operand:DI 0 "register_operand" "=r")
1028 (lo_sum:DI (match_operand:DI 1 "register_operand" "0")
1029 (match_operand:DI 2 "immediate_operand" "in")))]
1033 /* Don't output a 64 bit constant, since we can't trust the assembler to
1034 handle it correctly. */
1035 if (GET_CODE (operands[2]) == CONST_DOUBLE)
1036 operands[2] = gen_rtx (CONST_INT, VOIDmode, CONST_DOUBLE_LOW (operands[2]));
1037 return \"or %R1,%%lo(%a2),%R0\";
1039 ;; Need to set length for this arith insn because operand2
1040 ;; is not an "arith_operand".
1041 [(set_attr "length" "1")])
1043 ;; ??? There's no symbolic (set (mem:DI ...) ...).
1045 ;; Block move insns.
1047 ;; ??? We get better code without it. See output_block_move in sparc.c.
1049 ;; The definition of this insn does not really explain what it does,
1050 ;; but it should suffice
1051 ;; that anything generated as this insn will be recognized as one
1052 ;; and that it will not successfully combine with anything.
1053 ;(define_expand "movstrsi"
1054 ; [(parallel [(set (mem:BLK (match_operand:BLK 0 "general_operand" ""))
1055 ; (mem:BLK (match_operand:BLK 1 "general_operand" "")))
1056 ; (use (match_operand:SI 2 "nonmemory_operand" ""))
1057 ; (use (match_operand:SI 3 "immediate_operand" ""))
1058 ; (clobber (match_dup 0))
1059 ; (clobber (match_dup 1))
1060 ; (clobber (match_scratch:SI 4 ""))
1061 ; (clobber (reg:SI 0))
1062 ; (clobber (reg:SI 1))])]
1066 ; /* If the size isn't known, don't emit inline code. output_block_move
1067 ; would output code that's much slower than the library function.
1068 ; Also don't output code for large blocks. */
1069 ; if (GET_CODE (operands[2]) != CONST_INT
1070 ; || GET_CODE (operands[3]) != CONST_INT
1071 ; || INTVAL (operands[2]) / INTVAL (operands[3]) > 16)
1074 ; operands[0] = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
1075 ; operands[1] = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
1076 ; operands[2] = force_not_mem (operands[2]);
1080 ; [(set (mem:BLK (match_operand:SI 0 "register_operand" "+r"))
1081 ; (mem:BLK (match_operand:SI 1 "register_operand" "+r")))
1082 ; (use (match_operand:SI 2 "nonmemory_operand" "rn"))
1083 ; (use (match_operand:SI 3 "immediate_operand" "i"))
1084 ; (clobber (match_dup 0))
1085 ; (clobber (match_dup 1))
1086 ; (clobber (match_scratch:SI 4 "=&r"))
1087 ; (clobber (reg:SI 0))
1088 ; (clobber (reg:SI 1))]
1090 ; "* return output_block_move (operands);"
1091 ; [(set_attr "type" "multi")
1092 ; (set_attr "length" "6")])
1094 ;; Floating point move insns
1096 ;; This pattern forces (set (reg:SF ...) (const_double ...))
1097 ;; to be reloaded by putting the constant into memory.
1098 ;; It must come before the more general movsf pattern.
1100 [(set (match_operand:SF 0 "general_operand" "=?r,f,m")
1101 (match_operand:SF 1 "" "?E,m,G"))]
1102 "TARGET_FPU && GET_CODE (operands[1]) == CONST_DOUBLE"
1105 switch (which_alternative)
1108 return singlemove_string (operands);
1110 return \"ld %1,%0\";
1112 return \"st %%g0,%0\";
1115 [(set_attr "type" "load,fpload,store")
1116 (set_attr "length" "2,1,1")])
1118 (define_expand "movsf"
1119 [(set (match_operand:SF 0 "general_operand" "")
1120 (match_operand:SF 1 "general_operand" ""))]
1124 if (emit_move_sequence (operands, SFmode))
1129 [(set (match_operand:SF 0 "reg_or_nonsymb_mem_operand" "=f,r,f,r,Q,Q")
1130 (match_operand:SF 1 "reg_or_nonsymb_mem_operand" "f,r,Q,Q,f,r"))]
1132 && (register_operand (operands[0], SFmode)
1133 || register_operand (operands[1], SFmode))"
1141 [(set_attr "type" "fp,move,fpload,load,fpstore,store")])
1143 ;; Exactly the same as above, except that all `f' cases are deleted.
1144 ;; This is necessary to prevent reload from ever trying to use a `f' reg
1148 [(set (match_operand:SF 0 "reg_or_nonsymb_mem_operand" "=r,r,Q")
1149 (match_operand:SF 1 "reg_or_nonsymb_mem_operand" "r,Q,r"))]
1151 && (register_operand (operands[0], SFmode)
1152 || register_operand (operands[1], SFmode))"
1157 [(set_attr "type" "move,load,store")])
1160 [(set (mem:SF (match_operand:SI 0 "symbolic_operand" "i"))
1161 (match_operand:SF 1 "reg_or_0_operand" "rfG"))
1162 (clobber (match_scratch:SI 2 "=&r"))]
1164 "sethi %%hi(%a0),%2\;st %r1,[%2+%%lo(%a0)]"
1165 [(set_attr "type" "store")
1166 (set_attr "length" "2")])
1168 ;; This pattern forces (set (reg:DF ...) (const_double ...))
1169 ;; to be reloaded by putting the constant into memory.
1170 ;; It must come before the more general movdf pattern.
1173 [(set (match_operand:DF 0 "general_operand" "=?r,f,o")
1174 (match_operand:DF 1 "" "?E,m,G"))]
1175 "TARGET_FPU && GET_CODE (operands[1]) == CONST_DOUBLE"
1178 switch (which_alternative)
1181 return output_move_double (operands);
1183 return output_fp_move_double (operands);
1185 operands[1] = adj_offsettable_operand (operands[0], 4);
1186 return \"st %%g0,%0\;st %%g0,%1\";
1189 [(set_attr "type" "load,fpload,store")
1190 (set_attr "length" "3,3,3")])
1192 (define_expand "movdf"
1193 [(set (match_operand:DF 0 "general_operand" "")
1194 (match_operand:DF 1 "general_operand" ""))]
1198 if (emit_move_sequence (operands, DFmode))
1203 [(set (match_operand:DF 0 "reg_or_nonsymb_mem_operand" "=T,U,f,r,Q,Q,f,r")
1204 (match_operand:DF 1 "reg_or_nonsymb_mem_operand" "U,T,f,r,f,r,Q,Q"))]
1206 && (register_operand (operands[0], DFmode)
1207 || register_operand (operands[1], DFmode))"
1210 if (FP_REG_P (operands[0]) || FP_REG_P (operands[1]))
1211 return output_fp_move_double (operands);
1212 return output_move_double (operands);
1214 [(set_attr "type" "fpstore,fpload,fp,move,fpstore,store,fpload,load")
1215 (set_attr "length" "1,1,2,2,3,3,3,3")])
1217 ;; Exactly the same as above, except that all `f' cases are deleted.
1218 ;; This is necessary to prevent reload from ever trying to use a `f' reg
1222 [(set (match_operand:DF 0 "reg_or_nonsymb_mem_operand" "=T,U,r,Q,&r")
1223 (match_operand:DF 1 "reg_or_nonsymb_mem_operand" "U,T,r,r,Q"))]
1225 && (register_operand (operands[0], DFmode)
1226 || register_operand (operands[1], DFmode))"
1227 "* return output_move_double (operands);"
1228 [(set_attr "type" "store,load,move,store,load")
1229 (set_attr "length" "1,1,2,3,3")])
1232 [(set (match_operand:DF 0 "register_operand" "")
1233 (match_operand:DF 1 "register_operand" ""))]
1235 [(set (match_dup 2) (match_dup 3))
1236 (set (match_dup 4) (match_dup 5))]
1238 { operands[2] = operand_subword (operands[0], 0, 0, DFmode);
1239 operands[3] = operand_subword (operands[1], 0, 0, DFmode);
1240 operands[4] = operand_subword (operands[0], 1, 0, DFmode);
1241 operands[5] = operand_subword (operands[1], 1, 0, DFmode); }")
1244 [(set (mem:DF (match_operand:SI 0 "symbolic_operand" "i,i"))
1245 (match_operand:DF 1 "reg_or_0_operand" "rf,G"))
1246 (clobber (match_scratch:SI 2 "=&r,&r"))]
1250 output_asm_insn (\"sethi %%hi(%a0),%2\", operands);
1251 if (which_alternative == 0)
1252 return \"std %1,[%2+%%lo(%a0)]\";
1254 return \"st %%g0,[%2+%%lo(%a0)]\;st %%g0,[%2+%%lo(%a0+4)]\";
1256 [(set_attr "type" "store")
1257 (set_attr "length" "3")])
1259 ;; This pattern forces (set (reg:TF ...) (const_double ...))
1260 ;; to be reloaded by putting the constant into memory.
1261 ;; It must come before the more general movtf pattern.
1263 [(set (match_operand:TF 0 "general_operand" "=?r,f,o")
1264 (match_operand:TF 1 "" "?E,m,G"))]
1265 "TARGET_FPU && GET_CODE (operands[1]) == CONST_DOUBLE"
1268 switch (which_alternative)
1271 return output_move_quad (operands);
1273 return output_fp_move_quad (operands);
1275 operands[1] = adj_offsettable_operand (operands[0], 4);
1276 operands[2] = adj_offsettable_operand (operands[0], 8);
1277 operands[3] = adj_offsettable_operand (operands[0], 12);
1278 return \"st %%g0,%0\;st %%g0,%1\;st %%g0,%2\;st %%g0,%3\";
1281 [(set_attr "type" "load,fpload,store")
1282 (set_attr "length" "5,5,5")])
1284 (define_expand "movtf"
1285 [(set (match_operand:TF 0 "general_operand" "")
1286 (match_operand:TF 1 "general_operand" ""))]
1290 if (emit_move_sequence (operands, TFmode))
1295 [(set (match_operand:TF 0 "reg_or_nonsymb_mem_operand" "=f,r,Q,Q,f,&r")
1296 (match_operand:TF 1 "reg_or_nonsymb_mem_operand" "f,r,f,r,Q,Q"))]
1298 && (register_operand (operands[0], TFmode)
1299 || register_operand (operands[1], TFmode))"
1302 if (FP_REG_P (operands[0]) || FP_REG_P (operands[1]))
1303 return output_fp_move_quad (operands);
1304 return output_move_quad (operands);
1306 [(set_attr "type" "fp,move,fpstore,store,fpload,load")
1307 (set_attr "length" "4,4,5,5,5,5")])
1309 ;; Exactly the same as above, except that all `f' cases are deleted.
1310 ;; This is necessary to prevent reload from ever trying to use a `f' reg
1314 [(set (match_operand:TF 0 "reg_or_nonsymb_mem_operand" "=r,Q,&r")
1315 (match_operand:TF 1 "reg_or_nonsymb_mem_operand" "r,r,Q"))]
1317 && (register_operand (operands[0], TFmode)
1318 || register_operand (operands[1], TFmode))"
1321 if (FP_REG_P (operands[0]) || FP_REG_P (operands[1]))
1322 return output_fp_move_quad (operands);
1323 return output_move_quad (operands);
1325 [(set_attr "type" "move,store,load")
1326 (set_attr "length" "4,5,5")])
1329 [(set (mem:TF (match_operand:SI 0 "symbolic_operand" "i,i"))
1330 (match_operand:TF 1 "reg_or_0_operand" "rf,G"))
1331 (clobber (match_scratch:SI 2 "=&r,&r"))]
1335 output_asm_insn (\"sethi %%hi(%a0),%2\", operands);
1336 if (which_alternative == 0)
1337 return \"std %1,[%2+%%lo(%a0)]\;std %S1,[%2+%%lo(%a0+8)]\";
1339 return \"st %%g0,[%2+%%lo(%a0)]\;st %%g0,[%2+%%lo(%a0+4)]\; st %%g0,[%2+%%lo(%a0+8)]\;st %%g0,[%2+%%lo(%a0+12)]\";
1341 [(set_attr "type" "store")
1342 (set_attr "length" "5")])
1344 ;;- zero extension instructions
1346 ;; These patterns originally accepted general_operands, however, slightly
1347 ;; better code is generated by only accepting register_operands, and then
1348 ;; letting combine generate the ldu[hb] insns.
1350 (define_expand "zero_extendhisi2"
1351 [(set (match_operand:SI 0 "register_operand" "")
1352 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
1356 rtx temp = gen_reg_rtx (SImode);
1357 rtx shift_16 = gen_rtx (CONST_INT, VOIDmode, 16);
1358 int op1_subword = 0;
1360 if (GET_CODE (operand1) == SUBREG)
1362 op1_subword = SUBREG_WORD (operand1);
1363 operand1 = XEXP (operand1, 0);
1366 emit_insn (gen_ashlsi3 (temp, gen_rtx (SUBREG, SImode, operand1,
1369 emit_insn (gen_lshrsi3 (operand0, temp, shift_16));
1374 [(set (match_operand:SI 0 "register_operand" "=r")
1375 (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
1378 [(set_attr "type" "load")])
1380 (define_expand "zero_extendqihi2"
1381 [(set (match_operand:HI 0 "register_operand" "")
1382 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
1387 [(set (match_operand:HI 0 "register_operand" "=r,r")
1388 (zero_extend:HI (match_operand:QI 1 "sparc_operand" "r,Q")))]
1389 "GET_CODE (operands[1]) != CONST_INT"
1393 [(set_attr "type" "unary,load")
1394 (set_attr "length" "1")])
1396 (define_expand "zero_extendqisi2"
1397 [(set (match_operand:SI 0 "register_operand" "")
1398 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
1403 [(set (match_operand:SI 0 "register_operand" "=r,r")
1404 (zero_extend:SI (match_operand:QI 1 "sparc_operand" "r,Q")))]
1405 "GET_CODE (operands[1]) != CONST_INT"
1409 [(set_attr "type" "unary,load")
1410 (set_attr "length" "1")])
1414 (compare:CC (zero_extend:SI (match_operand:QI 0 "register_operand" "r"))
1417 "andcc %0,0xff,%%g0"
1418 [(set_attr "type" "compare")])
1422 (compare:CC (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
1424 (set (match_operand:SI 0 "register_operand" "=r")
1425 (zero_extend:SI (match_dup 1)))]
1428 [(set_attr "type" "unary")])
1430 ;; Similarly, handle SI->QI mode truncation followed by a compare.
1434 (compare:CC (subreg:QI (match_operand:SI 0 "register_operand" "r") 0)
1437 "andcc %0,0xff,%%g0"
1438 [(set_attr "type" "compare")])
1442 (compare:CC (subreg:QI (match_operand:SI 1 "register_operand" "r") 0)
1444 (set (match_operand:QI 0 "register_operand" "=r")
1448 [(set_attr "type" "unary")])
1450 ;;- sign extension instructions
1452 ;; These patterns originally accepted general_operands, however, slightly
1453 ;; better code is generated by only accepting register_operands, and then
1454 ;; letting combine generate the lds[hb] insns.
1456 (define_expand "extendhisi2"
1457 [(set (match_operand:SI 0 "register_operand" "")
1458 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
1462 rtx temp = gen_reg_rtx (SImode);
1463 rtx shift_16 = gen_rtx (CONST_INT, VOIDmode, 16);
1464 int op1_subword = 0;
1466 if (GET_CODE (operand1) == SUBREG)
1468 op1_subword = SUBREG_WORD (operand1);
1469 operand1 = XEXP (operand1, 0);
1472 emit_insn (gen_ashlsi3 (temp, gen_rtx (SUBREG, SImode, operand1,
1475 emit_insn (gen_ashrsi3 (operand0, temp, shift_16));
1480 [(set (match_operand:SI 0 "register_operand" "=r")
1481 (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
1484 [(set_attr "type" "load")])
1486 (define_expand "extendqihi2"
1487 [(set (match_operand:HI 0 "register_operand" "")
1488 (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
1492 rtx temp = gen_reg_rtx (SImode);
1493 rtx shift_24 = gen_rtx (CONST_INT, VOIDmode, 24);
1494 int op1_subword = 0;
1495 int op0_subword = 0;
1497 if (GET_CODE (operand1) == SUBREG)
1499 op1_subword = SUBREG_WORD (operand1);
1500 operand1 = XEXP (operand1, 0);
1502 if (GET_CODE (operand0) == SUBREG)
1504 op0_subword = SUBREG_WORD (operand0);
1505 operand0 = XEXP (operand0, 0);
1507 emit_insn (gen_ashlsi3 (temp, gen_rtx (SUBREG, SImode, operand1,
1510 if (GET_MODE (operand0) != SImode)
1511 operand0 = gen_rtx (SUBREG, SImode, operand0, op0_subword);
1512 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
1517 [(set (match_operand:HI 0 "register_operand" "=r")
1518 (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
1521 [(set_attr "type" "load")])
1523 (define_expand "extendqisi2"
1524 [(set (match_operand:SI 0 "register_operand" "")
1525 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
1529 rtx temp = gen_reg_rtx (SImode);
1530 rtx shift_24 = gen_rtx (CONST_INT, VOIDmode, 24);
1531 int op1_subword = 0;
1533 if (GET_CODE (operand1) == SUBREG)
1535 op1_subword = SUBREG_WORD (operand1);
1536 operand1 = XEXP (operand1, 0);
1539 emit_insn (gen_ashlsi3 (temp, gen_rtx (SUBREG, SImode, operand1,
1542 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
1547 [(set (match_operand:SI 0 "register_operand" "=r")
1548 (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
1551 [(set_attr "type" "load")])
1553 ;; Special pattern for optimizing bit-field compares. This is needed
1554 ;; because combine uses this as a canonical form.
1559 (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
1560 (match_operand:SI 1 "small_int" "n")
1561 (match_operand:SI 2 "small_int" "n"))
1563 "INTVAL (operands[2]) > 19"
1566 int len = INTVAL (operands[1]);
1567 int pos = 32 - INTVAL (operands[2]) - len;
1568 unsigned mask = ((1 << len) - 1) << pos;
1570 operands[1] = gen_rtx (CONST_INT, VOIDmode, mask);
1571 return \"andcc %0,%1,%%g0\";
1574 ;; Conversions between float, double and long double.
1576 (define_insn "extendsfdf2"
1577 [(set (match_operand:DF 0 "register_operand" "=f")
1579 (match_operand:SF 1 "register_operand" "f")))]
1582 [(set_attr "type" "fp")])
1584 (define_insn "extendsftf2"
1585 [(set (match_operand:TF 0 "register_operand" "=f")
1587 (match_operand:SF 1 "register_operand" "f")))]
1590 [(set_attr "type" "fp")])
1592 (define_insn "extenddftf2"
1593 [(set (match_operand:TF 0 "register_operand" "=f")
1595 (match_operand:DF 1 "register_operand" "f")))]
1598 [(set_attr "type" "fp")])
1600 (define_insn "truncdfsf2"
1601 [(set (match_operand:SF 0 "register_operand" "=f")
1603 (match_operand:DF 1 "register_operand" "f")))]
1606 [(set_attr "type" "fp")])
1608 (define_insn "trunctfsf2"
1609 [(set (match_operand:SF 0 "register_operand" "=f")
1611 (match_operand:TF 1 "register_operand" "f")))]
1614 [(set_attr "type" "fp")])
1616 (define_insn "trunctfdf2"
1617 [(set (match_operand:DF 0 "register_operand" "=f")
1619 (match_operand:TF 1 "register_operand" "f")))]
1622 [(set_attr "type" "fp")])
1624 ;; Conversion between fixed point and floating point.
1626 (define_insn "floatsisf2"
1627 [(set (match_operand:SF 0 "register_operand" "=f")
1628 (float:SF (match_operand:SI 1 "register_operand" "f")))]
1631 [(set_attr "type" "fp")])
1633 (define_insn "floatsidf2"
1634 [(set (match_operand:DF 0 "register_operand" "=f")
1635 (float:DF (match_operand:SI 1 "register_operand" "f")))]
1638 [(set_attr "type" "fp")])
1640 (define_insn "floatsitf2"
1641 [(set (match_operand:TF 0 "register_operand" "=f")
1642 (float:TF (match_operand:SI 1 "register_operand" "f")))]
1645 [(set_attr "type" "fp")])
1647 ;; Convert a float to an actual integer.
1648 ;; Truncation is performed as part of the conversion.
1650 (define_insn "fix_truncsfsi2"
1651 [(set (match_operand:SI 0 "register_operand" "=f")
1652 (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
1655 [(set_attr "type" "fp")])
1657 (define_insn "fix_truncdfsi2"
1658 [(set (match_operand:SI 0 "register_operand" "=f")
1659 (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "f"))))]
1662 [(set_attr "type" "fp")])
1664 (define_insn "fix_trunctfsi2"
1665 [(set (match_operand:SI 0 "register_operand" "=f")
1666 (fix:SI (fix:TF (match_operand:TF 1 "register_operand" "f"))))]
1669 [(set_attr "type" "fp")])
1671 ;;- arithmetic instructions
1673 (define_insn "adddi3"
1674 [(set (match_operand:DI 0 "register_operand" "=r")
1675 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
1676 (match_operand:DI 2 "arith_double_operand" "rHI")))
1677 (clobber (reg:SI 0))]
1681 rtx op2 = operands[2];
1683 /* If constant is positive, upper bits zeroed, otherwise unchanged.
1684 Give the assembler a chance to pick the move instruction. */
1685 if (GET_CODE (op2) == CONST_INT)
1687 int sign = INTVAL (op2);
1689 return \"addcc %R1,%2,%R0\;addx %1,-1,%0\";
1690 return \"addcc %R1,%2,%R0\;addx %1,0,%0\";
1692 else if (GET_CODE (op2) == CONST_DOUBLE)
1694 int sign = CONST_DOUBLE_HIGH (op2);
1695 operands[2] = gen_rtx (CONST_INT, VOIDmode,
1696 CONST_DOUBLE_LOW (operands[1]));
1698 return \"addcc %R1,%2,%R0\;addx %1,-1,%0\";
1699 return \"addcc %R1,%2,%R0\;addx %1,0,%0\";
1701 return \"addcc %R1,%R2,%R0\;addx %1,%2,%0\";
1703 [(set_attr "length" "2")])
1705 (define_insn "addsi3"
1706 [(set (match_operand:SI 0 "register_operand" "=r")
1707 (plus:SI (match_operand:SI 1 "arith_operand" "%r")
1708 (match_operand:SI 2 "arith_operand" "rI")))]
1713 [(set (reg:CC_NOOV 0)
1714 (compare:CC_NOOV (plus:SI (match_operand:SI 0 "arith_operand" "%r")
1715 (match_operand:SI 1 "arith_operand" "rI"))
1719 [(set_attr "type" "compare")])
1722 [(set (reg:CC_NOOV 0)
1723 (compare:CC_NOOV (plus:SI (match_operand:SI 1 "arith_operand" "%r")
1724 (match_operand:SI 2 "arith_operand" "rI"))
1726 (set (match_operand:SI 0 "register_operand" "=r")
1727 (plus:SI (match_dup 1) (match_dup 2)))]
1731 (define_insn "subdi3"
1732 [(set (match_operand:DI 0 "register_operand" "=r")
1733 (minus:DI (match_operand:DI 1 "register_operand" "r")
1734 (match_operand:DI 2 "arith_double_operand" "rHI")))
1735 (clobber (reg:SI 0))]
1739 rtx op2 = operands[2];
1741 /* If constant is positive, upper bits zeroed, otherwise unchanged.
1742 Give the assembler a chance to pick the move instruction. */
1743 if (GET_CODE (op2) == CONST_INT)
1745 int sign = INTVAL (op2);
1747 return \"subcc %R1,%2,%R0\;subx %1,-1,%0\";
1748 return \"subcc %R1,%2,%R0\;subx %1,0,%0\";
1750 else if (GET_CODE (op2) == CONST_DOUBLE)
1752 int sign = CONST_DOUBLE_HIGH (op2);
1753 operands[2] = gen_rtx (CONST_INT, VOIDmode,
1754 CONST_DOUBLE_LOW (operands[1]));
1756 return \"subcc %R1,%2,%R0\;subx %1,-1,%0\";
1757 return \"subcc %R1,%2,%R0\;subx %1,0,%0\";
1759 return \"subcc %R1,%R2,%R0\;subx %1,%2,%0\";
1761 [(set_attr "length" "2")])
1763 (define_insn "subsi3"
1764 [(set (match_operand:SI 0 "register_operand" "=r")
1765 (minus:SI (match_operand:SI 1 "register_operand" "r")
1766 (match_operand:SI 2 "arith_operand" "rI")))]
1771 [(set (reg:CC_NOOV 0)
1772 (compare:CC_NOOV (minus:SI (match_operand:SI 0 "register_operand" "r")
1773 (match_operand:SI 1 "arith_operand" "rI"))
1777 [(set_attr "type" "compare")])
1780 [(set (reg:CC_NOOV 0)
1781 (compare:CC_NOOV (minus:SI (match_operand:SI 1 "register_operand" "r")
1782 (match_operand:SI 2 "arith_operand" "rI"))
1784 (set (match_operand:SI 0 "register_operand" "=r")
1785 (minus:SI (match_dup 1) (match_dup 2)))]
1789 (define_insn "mulsi3"
1790 [(set (match_operand:SI 0 "register_operand" "=r")
1791 (mult:SI (match_operand:SI 1 "arith_operand" "%r")
1792 (match_operand:SI 2 "arith_operand" "rI")))]
1793 "TARGET_V8 || TARGET_SPARCLITE"
1796 ;; It is not known whether this will match.
1799 [(set (match_operand:SI 0 "register_operand" "=r")
1800 (mult:SI (match_operand:SI 1 "arith_operand" "%r")
1801 (match_operand:SI 2 "arith_operand" "rI")))
1802 (set (reg:CC_NOOV 0)
1803 (compare:CC_NOOV (mult:SI (match_dup 1) (match_dup 2))
1805 "TARGET_V8 || TARGET_SPARCLITE"
1808 (define_expand "mulsidi3"
1809 [(set (match_operand:DI 0 "register_operand" "")
1810 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
1811 (sign_extend:DI (match_operand:SI 2 "arith_operand" ""))))]
1812 "TARGET_V8 || TARGET_SPARCLITE"
1815 if (CONSTANT_P (operands[2]))
1817 emit_insn (gen_const_mulsidi3 (operands[0], operands[1], operands[2]));
1823 [(set (match_operand:DI 0 "register_operand" "=r")
1824 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
1825 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
1826 "TARGET_V8 || TARGET_SPARCLITE"
1827 "smul %1,%2,%R0\;rd %%y,%0"
1828 [(set_attr "length" "2")])
1830 ;; Extra pattern, because sign_extend of a constant isn't legal.
1832 (define_insn "const_mulsidi3"
1833 [(set (match_operand:DI 0 "register_operand" "=r")
1834 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
1835 (match_operand:SI 2 "small_int" "I")))]
1836 "TARGET_V8 || TARGET_SPARCLITE"
1837 "smul %1,%2,%R0\;rd %%y,%0"
1838 [(set_attr "length" "2")])
1840 (define_expand "umulsidi3"
1841 [(set (match_operand:DI 0 "register_operand" "")
1842 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
1843 (zero_extend:DI (match_operand:SI 2 "arith_operand" ""))))]
1844 "TARGET_V8 || TARGET_SPARCLITE"
1847 if (CONSTANT_P (operands[2]))
1849 emit_insn (gen_const_umulsidi3 (operands[0], operands[1], operands[2]));
1855 [(set (match_operand:DI 0 "register_operand" "=r")
1856 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
1857 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
1858 "TARGET_V8 || TARGET_SPARCLITE"
1859 "umul %1,%2,%R0\;rd %%y,%0"
1860 [(set_attr "length" "2")])
1862 ;; Extra pattern, because sign_extend of a constant isn't legal.
1864 (define_insn "const_umulsidi3"
1865 [(set (match_operand:DI 0 "register_operand" "=r")
1866 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
1867 (match_operand:SI 2 "small_int" "I")))]
1868 "TARGET_V8 || TARGET_SPARCLITE"
1869 "umul %1,%2,%R0\;rd %%y,%0"
1870 [(set_attr "length" "2")])
1872 ;; The architecture specifies that there must be 3 instructions between
1873 ;; a y register write and a use of it for correct results.
1875 (define_insn "divsi3"
1876 [(set (match_operand:SI 0 "register_operand" "=r")
1877 (div:SI (match_operand:SI 1 "register_operand" "r")
1878 (match_operand:SI 2 "arith_operand" "rI")))
1879 (clobber (match_scratch:SI 3 "=&r"))]
1881 "sra %1,31,%3\;wr %%g0,%3,%%y\;nop\;nop\;nop\;sdiv %1,%2,%0"
1882 [(set_attr "length" "6")])
1884 ;; It is not known whether this will match.
1887 [(set (match_operand:SI 0 "register_operand" "=r")
1888 (div:SI (match_operand:SI 1 "register_operand" "r")
1889 (match_operand:SI 2 "arith_operand" "rI")))
1891 (compare:CC (div:SI (match_dup 1) (match_dup 2))
1893 (clobber (match_scratch:SI 3 "=&r"))]
1895 "sra %1,31,%3\;wr %%g0,%3,%%y\;nop\;nop\;nop\;sdivcc %1,%2,%0"
1896 [(set_attr "length" "6")])
1898 (define_insn "udivsi3"
1899 [(set (match_operand:SI 0 "register_operand" "=r")
1900 (udiv:SI (match_operand:SI 1 "register_operand" "r")
1901 (match_operand:SI 2 "arith_operand" "rI")))]
1903 "wr %%g0,%%g0,%%y\;nop\;nop\;nop\;udiv %1,%2,%0"
1904 [(set_attr "length" "5")])
1906 ;; It is not known whether this will match.
1909 [(set (match_operand:SI 0 "register_operand" "=r")
1910 (udiv:SI (match_operand:SI 1 "register_operand" "r")
1911 (match_operand:SI 2 "arith_operand" "rI")))
1913 (compare:CC (udiv:SI (match_dup 1) (match_dup 2))
1916 "wr %%g0,%%g0,%%y\;nop\;nop\;nop\;udivcc %1,%2,%0"
1917 [(set_attr "length" "5")])
1919 ;;- Boolean instructions
1920 ;; We define DImode `and` so with DImode `not` we can get
1921 ;; DImode `andn`. Other combinations are possible.
1923 (define_expand "anddi3"
1924 [(set (match_operand:DI 0 "register_operand" "")
1925 (and:DI (match_operand:DI 1 "arith_double_operand" "")
1926 (match_operand:DI 2 "arith_double_operand" "")))]
1931 [(set (match_operand:DI 0 "register_operand" "=r")
1932 (and:DI (match_operand:DI 1 "arith_double_operand" "%r")
1933 (match_operand:DI 2 "arith_double_operand" "rHI")))]
1937 rtx op2 = operands[2];
1939 /* If constant is positive, upper bits zeroed, otherwise unchanged.
1940 Give the assembler a chance to pick the move instruction. */
1941 if (GET_CODE (op2) == CONST_INT)
1943 int sign = INTVAL (op2);
1945 return \"mov %1,%0\;and %R1,%2,%R0\";
1946 return \"mov 0,%0\;and %R1,%2,%R0\";
1948 else if (GET_CODE (op2) == CONST_DOUBLE)
1950 int sign = CONST_DOUBLE_HIGH (op2);
1951 operands[2] = gen_rtx (CONST_INT, VOIDmode,
1952 CONST_DOUBLE_LOW (operands[1]));
1954 return \"mov %1,%0\;and %R1,%2,%R0\";
1955 return \"mov 0,%0\;and %R1,%2,%R0\";
1957 return \"and %1,%2,%0\;and %R1,%R2,%R0\";
1959 [(set_attr "length" "2")])
1961 (define_insn "andsi3"
1962 [(set (match_operand:SI 0 "register_operand" "=r")
1963 (and:SI (match_operand:SI 1 "arith_operand" "%r")
1964 (match_operand:SI 2 "arith_operand" "rI")))]
1969 [(set (match_operand:SI 0 "register_operand" "")
1970 (and:SI (match_operand:SI 1 "register_operand" "")
1971 (match_operand:SI 2 "" "")))
1972 (clobber (match_operand:SI 3 "register_operand" ""))]
1973 "GET_CODE (operands[2]) == CONST_INT
1974 && !SMALL_INT (operands[2])
1975 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
1976 [(set (match_dup 3) (match_dup 4))
1977 (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 1)))]
1980 operands[4] = gen_rtx (CONST_INT, VOIDmode, ~INTVAL (operands[2]));
1984 [(set (match_operand:DI 0 "register_operand" "=r")
1985 (and:DI (not:DI (match_operand:DI 1 "register_operand" "r"))
1986 (match_operand:DI 2 "register_operand" "r")))]
1988 "andn %2,%1,%0\;andn %R2,%R1,%R0"
1989 [(set_attr "length" "2")])
1992 [(set (match_operand:SI 0 "register_operand" "=r")
1993 (and:SI (not:SI (match_operand:SI 1 "register_operand" "r"))
1994 (match_operand:SI 2 "register_operand" "r")))]
1998 (define_expand "iordi3"
1999 [(set (match_operand:DI 0 "register_operand" "")
2000 (ior:DI (match_operand:DI 1 "arith_double_operand" "")
2001 (match_operand:DI 2 "arith_double_operand" "")))]
2006 [(set (match_operand:DI 0 "register_operand" "=r")
2007 (ior:DI (match_operand:DI 1 "arith_double_operand" "%r")
2008 (match_operand:DI 2 "arith_double_operand" "rHI")))]
2012 rtx op2 = operands[2];
2014 /* If constant is positive, upper bits zeroed, otherwise unchanged.
2015 Give the assembler a chance to pick the move instruction. */
2016 if (GET_CODE (op2) == CONST_INT)
2018 int sign = INTVAL (op2);
2020 return \"mov -1,%0\;or %R1,%2,%R0\";
2021 return \"mov %1,%0\;or %R1,%2,%R0\";
2023 else if (GET_CODE (op2) == CONST_DOUBLE)
2025 int sign = CONST_DOUBLE_HIGH (op2);
2026 operands[2] = gen_rtx (CONST_INT, VOIDmode,
2027 CONST_DOUBLE_LOW (operands[1]));
2029 return \"mov -1,%0\;or %R1,%2,%R0\";
2030 return \"mov %1,%0\;or %R1,%2,%R0\";
2032 return \"or %1,%2,%0\;or %R1,%R2,%R0\";
2034 [(set_attr "length" "2")])
2036 (define_insn "iorsi3"
2037 [(set (match_operand:SI 0 "register_operand" "=r")
2038 (ior:SI (match_operand:SI 1 "arith_operand" "%r")
2039 (match_operand:SI 2 "arith_operand" "rI")))]
2044 [(set (match_operand:SI 0 "register_operand" "")
2045 (ior:SI (match_operand:SI 1 "register_operand" "")
2046 (match_operand:SI 2 "" "")))
2047 (clobber (match_operand:SI 3 "register_operand" ""))]
2048 "GET_CODE (operands[2]) == CONST_INT
2049 && !SMALL_INT (operands[2])
2050 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
2051 [(set (match_dup 3) (match_dup 4))
2052 (set (match_dup 0) (ior:SI (not:SI (match_dup 3)) (match_dup 1)))]
2055 operands[4] = gen_rtx (CONST_INT, VOIDmode, ~INTVAL (operands[2]));
2059 [(set (match_operand:DI 0 "register_operand" "=r")
2060 (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r"))
2061 (match_operand:DI 2 "register_operand" "r")))]
2063 "orn %2,%1,%0\;orn %R2,%R1,%R0"
2064 [(set_attr "length" "2")])
2067 [(set (match_operand:SI 0 "register_operand" "=r")
2068 (ior:SI (not:SI (match_operand:SI 1 "register_operand" "r"))
2069 (match_operand:SI 2 "register_operand" "r")))]
2073 (define_expand "xordi3"
2074 [(set (match_operand:DI 0 "register_operand" "")
2075 (xor:DI (match_operand:DI 1 "arith_double_operand" "")
2076 (match_operand:DI 2 "arith_double_operand" "")))]
2081 [(set (match_operand:DI 0 "register_operand" "=r")
2082 (xor:DI (match_operand:DI 1 "arith_double_operand" "%r")
2083 (match_operand:DI 2 "arith_double_operand" "rHI")))]
2087 rtx op2 = operands[2];
2089 /* If constant is positive, upper bits zeroed, otherwise unchanged.
2090 Give the assembler a chance to pick the move instruction. */
2091 if (GET_CODE (op2) == CONST_INT)
2093 int sign = INTVAL (op2);
2095 return \"xor %1,-1,%0\;xor %R1,%2,%R0\";
2096 return \"mov %1,%0\;xor %R1,%2,%R0\";
2098 else if (GET_CODE (op2) == CONST_DOUBLE)
2100 int sign = CONST_DOUBLE_HIGH (op2);
2101 operands[2] = gen_rtx (CONST_INT, VOIDmode,
2102 CONST_DOUBLE_LOW (operands[1]));
2104 return \"xor %1,-1,%0\;xor %R1,%2,%R0\";
2105 return \"mov %1,%0\;xor %R1,%2,%R0\";
2107 return \"xor %1,%2,%0\;xor %R1,%R2,%R0\";
2109 [(set_attr "length" "2")])
2111 (define_insn "xorsi3"
2112 [(set (match_operand:SI 0 "register_operand" "=r")
2113 (xor:SI (match_operand:SI 1 "arith_operand" "%rJ")
2114 (match_operand:SI 2 "arith_operand" "rI")))]
2119 [(set (match_operand:SI 0 "register_operand" "")
2120 (xor:SI (match_operand:SI 1 "register_operand" "")
2121 (match_operand:SI 2 "" "")))
2122 (clobber (match_operand:SI 3 "register_operand" ""))]
2123 "GET_CODE (operands[2]) == CONST_INT
2124 && !SMALL_INT (operands[2])
2125 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
2126 [(set (match_dup 3) (match_dup 4))
2127 (set (match_dup 0) (not:SI (xor:SI (match_dup 3) (match_dup 1))))]
2130 operands[4] = gen_rtx (CONST_INT, VOIDmode, ~INTVAL (operands[2]));
2134 [(set (match_operand:SI 0 "register_operand" "")
2135 (not:SI (xor:SI (match_operand:SI 1 "register_operand" "")
2136 (match_operand:SI 2 "" ""))))
2137 (clobber (match_operand:SI 3 "register_operand" ""))]
2138 "GET_CODE (operands[2]) == CONST_INT
2139 && !SMALL_INT (operands[2])
2140 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
2141 [(set (match_dup 3) (match_dup 4))
2142 (set (match_dup 0) (xor:SI (match_dup 3) (match_dup 1)))]
2145 operands[4] = gen_rtx (CONST_INT, VOIDmode, ~INTVAL (operands[2]));
2148 ;; xnor patterns. Note that (a ^ ~b) == (~a ^ b) == ~(a ^ b).
2149 ;; Combine now canonicalizes to the rightmost expression.
2151 [(set (match_operand:DI 0 "register_operand" "=r")
2152 (not:DI (xor:DI (match_operand:DI 1 "register_operand" "r")
2153 (match_operand:DI 2 "register_operand" "r"))))]
2155 "xnor %1,%2,%0\;xnor %R1,%R2,%R0"
2156 [(set_attr "length" "2")])
2159 [(set (match_operand:SI 0 "register_operand" "=r")
2160 (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
2161 (match_operand:SI 2 "arith_operand" "rI"))))]
2165 ;; These correspond to the above in the case where we also (or only)
2166 ;; want to set the condition code.
2171 (match_operator:SI 2 "cc_arithop"
2172 [(match_operand:SI 0 "arith_operand" "%r")
2173 (match_operand:SI 1 "arith_operand" "rI")])
2177 [(set_attr "type" "compare")])
2182 (match_operator:SI 3 "cc_arithop"
2183 [(match_operand:SI 1 "arith_operand" "%r")
2184 (match_operand:SI 2 "arith_operand" "rI")])
2186 (set (match_operand:SI 0 "register_operand" "=r")
2194 (not:SI (xor:SI (match_operand:SI 0 "reg_or_0_operand" "%rJ")
2195 (match_operand:SI 1 "arith_operand" "rI")))
2198 "xnorcc %r0,%1,%%g0"
2199 [(set_attr "type" "compare")])
2204 (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
2205 (match_operand:SI 2 "arith_operand" "rI")))
2207 (set (match_operand:SI 0 "register_operand" "=r")
2208 (not:SI (xor:SI (match_dup 1) (match_dup 2))))]
2215 (match_operator:SI 2 "cc_arithopn"
2216 [(not:SI (match_operand:SI 0 "arith_operand" "rI"))
2217 (match_operand:SI 1 "reg_or_0_operand" "rJ")])
2221 [(set_attr "type" "compare")])
2226 (match_operator:SI 3 "cc_arithopn"
2227 [(not:SI (match_operand:SI 1 "arith_operand" "rI"))
2228 (match_operand:SI 2 "reg_or_0_operand" "rJ")])
2230 (set (match_operand:SI 0 "register_operand" "=r")
2235 ;; We cannot use the "neg" pseudo insn because the Sun assembler
2236 ;; does not know how to make it work for constants.
2238 (define_insn "negdi2"
2239 [(set (match_operand:DI 0 "register_operand" "=r")
2240 (neg:DI (match_operand:DI 1 "register_operand" "r")))
2241 (clobber (reg:SI 0))]
2243 "subcc %%g0,%R1,%R0\;subx %%g0,%1,%0"
2244 [(set_attr "type" "unary")
2245 (set_attr "length" "2")])
2247 (define_insn "negsi2"
2248 [(set (match_operand:SI 0 "general_operand" "=r")
2249 (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
2252 [(set_attr "type" "unary")])
2255 [(set (reg:CC_NOOV 0)
2256 (compare:CC_NOOV (neg:SI (match_operand:SI 0 "arith_operand" "rI"))
2259 "subcc %%g0,%0,%%g0"
2260 [(set_attr "type" "compare")])
2263 [(set (reg:CC_NOOV 0)
2264 (compare:CC_NOOV (neg:SI (match_operand:SI 1 "arith_operand" "rI"))
2266 (set (match_operand:SI 0 "register_operand" "=r")
2267 (neg:SI (match_dup 1)))]
2270 [(set_attr "type" "unary")])
2272 ;; We cannot use the "not" pseudo insn because the Sun assembler
2273 ;; does not know how to make it work for constants.
2274 (define_expand "one_cmpldi2"
2275 [(set (match_operand:DI 0 "register_operand" "=r")
2276 (not:DI (match_operand:DI 1 "arith_double_operand" "rHI")))]
2281 [(set (match_operand:DI 0 "register_operand" "=r")
2282 (not:DI (match_operand:DI 1 "arith_double_operand" "rHI")))]
2286 rtx op1 = operands[1];
2288 if (GET_CODE (op1) == CONST_INT)
2290 int sign = INTVAL (op1);
2292 return \"xnor %%g0,%1,%R0\;xnor %%g0,-1,%0\";
2293 return \"xnor %%g0,%1,%R0\;xnor %%g0,0,%0\";
2295 else if (GET_CODE (op1) == CONST_DOUBLE)
2297 int sign = CONST_DOUBLE_HIGH (op1);
2298 operands[1] = gen_rtx (CONST_INT, VOIDmode,
2299 CONST_DOUBLE_LOW (operands[1]));
2301 return \"xnor %%g0,%1,%R0\;xnor %%g0,-1,%0\";
2302 return \"xnor %%g0,%1,%R0\;xnor %%g0,0,%0\";
2304 return \"xnor %%g0,%1,%0\;xnor %%g0,%R1,%R0\";
2306 [(set_attr "type" "unary")
2307 (set_attr "length" "2")])
2309 (define_insn "one_cmplsi2"
2310 [(set (match_operand:SI 0 "register_operand" "=r")
2311 (not:SI (match_operand:SI 1 "arith_operand" "rI")))]
2314 [(set_attr "type" "unary")])
2318 (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI"))
2321 "xnorcc %%g0,%0,%%g0"
2322 [(set_attr "type" "compare")])
2326 (compare:CC (not:SI (match_operand:SI 1 "arith_operand" "rI"))
2328 (set (match_operand:SI 0 "register_operand" "=r")
2329 (not:SI (match_dup 1)))]
2332 [(set_attr "type" "unary")])
2334 ;; Floating point arithmetic instructions.
2336 (define_insn "addtf3"
2337 [(set (match_operand:TF 0 "register_operand" "=f")
2338 (plus:TF (match_operand:TF 1 "register_operand" "f")
2339 (match_operand:TF 2 "register_operand" "f")))]
2342 [(set_attr "type" "fp")])
2344 (define_insn "adddf3"
2345 [(set (match_operand:DF 0 "register_operand" "=f")
2346 (plus:DF (match_operand:DF 1 "register_operand" "f")
2347 (match_operand:DF 2 "register_operand" "f")))]
2350 [(set_attr "type" "fp")])
2352 (define_insn "addsf3"
2353 [(set (match_operand:SF 0 "register_operand" "=f")
2354 (plus:SF (match_operand:SF 1 "register_operand" "f")
2355 (match_operand:SF 2 "register_operand" "f")))]
2358 [(set_attr "type" "fp")])
2360 (define_insn "subtf3"
2361 [(set (match_operand:TF 0 "register_operand" "=f")
2362 (minus:TF (match_operand:TF 1 "register_operand" "f")
2363 (match_operand:TF 2 "register_operand" "f")))]
2366 [(set_attr "type" "fp")])
2368 (define_insn "subdf3"
2369 [(set (match_operand:DF 0 "register_operand" "=f")
2370 (minus:DF (match_operand:DF 1 "register_operand" "f")
2371 (match_operand:DF 2 "register_operand" "f")))]
2374 [(set_attr "type" "fp")])
2376 (define_insn "subsf3"
2377 [(set (match_operand:SF 0 "register_operand" "=f")
2378 (minus:SF (match_operand:SF 1 "register_operand" "f")
2379 (match_operand:SF 2 "register_operand" "f")))]
2382 [(set_attr "type" "fp")])
2384 (define_insn "multf3"
2385 [(set (match_operand:TF 0 "register_operand" "=f")
2386 (mult:TF (match_operand:TF 1 "register_operand" "f")
2387 (match_operand:TF 2 "register_operand" "f")))]
2390 [(set_attr "type" "fpmul")])
2392 (define_insn "muldf3"
2393 [(set (match_operand:DF 0 "register_operand" "=f")
2394 (mult:DF (match_operand:DF 1 "register_operand" "f")
2395 (match_operand:DF 2 "register_operand" "f")))]
2398 [(set_attr "type" "fpmul")])
2400 (define_insn "mulsf3"
2401 [(set (match_operand:SF 0 "register_operand" "=f")
2402 (mult:SF (match_operand:SF 1 "register_operand" "f")
2403 (match_operand:SF 2 "register_operand" "f")))]
2406 [(set_attr "type" "fpmul")])
2409 [(set (match_operand:DF 0 "register_operand" "=f")
2410 (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "f"))
2411 (float_extend:DF (match_operand:SF 2 "register_operand" "f"))))]
2412 "TARGET_V8 && TARGET_FPU"
2414 [(set_attr "type" "fpmul")])
2417 [(set (match_operand:TF 0 "register_operand" "=f")
2418 (mult:TF (float_extend:TF (match_operand:DF 1 "register_operand" "f"))
2419 (float_extend:TF (match_operand:DF 2 "register_operand" "f"))))]
2420 "TARGET_V8 && TARGET_FPU"
2422 [(set_attr "type" "fpmul")])
2424 (define_insn "divtf3"
2425 [(set (match_operand:TF 0 "register_operand" "=f")
2426 (div:TF (match_operand:TF 1 "register_operand" "f")
2427 (match_operand:TF 2 "register_operand" "f")))]
2430 [(set_attr "type" "fpdiv")])
2432 (define_insn "divdf3"
2433 [(set (match_operand:DF 0 "register_operand" "=f")
2434 (div:DF (match_operand:DF 1 "register_operand" "f")
2435 (match_operand:DF 2 "register_operand" "f")))]
2438 [(set_attr "type" "fpdiv")])
2440 (define_insn "divsf3"
2441 [(set (match_operand:SF 0 "register_operand" "=f")
2442 (div:SF (match_operand:SF 1 "register_operand" "f")
2443 (match_operand:SF 2 "register_operand" "f")))]
2446 [(set_attr "type" "fpdiv")])
2448 (define_insn "negtf2"
2449 [(set (match_operand:TF 0 "register_operand" "=f,f")
2450 (neg:TF (match_operand:TF 1 "register_operand" "0,f")))]
2454 fnegs %1,%0\;fmovs %R1,%R0\;fmovs %S1,%S0\;fmovs %T1,%T0"
2455 [(set_attr "type" "fp")
2456 (set_attr "length" "1,4")])
2458 (define_insn "negdf2"
2459 [(set (match_operand:DF 0 "register_operand" "=f,f")
2460 (neg:DF (match_operand:DF 1 "register_operand" "0,f")))]
2464 fnegs %1,%0\;fmovs %R1,%R0"
2465 [(set_attr "type" "fp")
2466 (set_attr "length" "1,2")])
2468 (define_insn "negsf2"
2469 [(set (match_operand:SF 0 "register_operand" "=f")
2470 (neg:SF (match_operand:SF 1 "register_operand" "f")))]
2473 [(set_attr "type" "fp")])
2475 (define_insn "abstf2"
2476 [(set (match_operand:TF 0 "register_operand" "=f,f")
2477 (abs:TF (match_operand:TF 1 "register_operand" "0,f")))]
2481 fabss %1,%0\;fmovs %R1,%R0\;fmovs %S1,%S0\;fmovs %T1,%T0"
2482 [(set_attr "type" "fp")
2483 (set_attr "length" "1,4")])
2485 (define_insn "absdf2"
2486 [(set (match_operand:DF 0 "register_operand" "=f,f")
2487 (abs:DF (match_operand:DF 1 "register_operand" "0,f")))]
2491 fabss %1,%0\;fmovs %R1,%R0"
2492 [(set_attr "type" "fp")
2493 (set_attr "length" "1,2")])
2495 (define_insn "abssf2"
2496 [(set (match_operand:SF 0 "register_operand" "=f")
2497 (abs:SF (match_operand:SF 1 "register_operand" "f")))]
2500 [(set_attr "type" "fp")])
2502 (define_insn "sqrttf2"
2503 [(set (match_operand:TF 0 "register_operand" "=f")
2504 (sqrt:TF (match_operand:TF 1 "register_operand" "f")))]
2507 [(set_attr "type" "fpsqrt")])
2509 (define_insn "sqrtdf2"
2510 [(set (match_operand:DF 0 "register_operand" "=f")
2511 (sqrt:DF (match_operand:DF 1 "register_operand" "f")))]
2514 [(set_attr "type" "fpsqrt")])
2516 (define_insn "sqrtsf2"
2517 [(set (match_operand:SF 0 "register_operand" "=f")
2518 (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
2521 [(set_attr "type" "fpsqrt")])
2523 ;;- arithmetic shift instructions
2525 (define_insn "ashlsi3"
2526 [(set (match_operand:SI 0 "register_operand" "=r")
2527 (ashift:SI (match_operand:SI 1 "register_operand" "r")
2528 (match_operand:SI 2 "shift_operand" "rI")))]
2532 (define_insn "ashrsi3"
2533 [(set (match_operand:SI 0 "register_operand" "=r")
2534 (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
2535 (match_operand:SI 2 "shift_operand" "rI")))]
2539 (define_insn "lshrsi3"
2540 [(set (match_operand:SI 0 "register_operand" "=r")
2541 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
2542 (match_operand:SI 2 "shift_operand" "rI")))]
2546 ;; Unconditional and other jump instructions
2547 ;; On the Sparc, by setting the annul bit on an unconditional branch, the
2548 ;; following insn is never executed. This saves us a nop. Dbx does not
2549 ;; handle such branches though, so we only use them when optimizing.
2551 [(set (pc) (label_ref (match_operand 0 "" "")))]
2554 [(set_attr "type" "uncond_branch")])
2556 (define_expand "tablejump"
2557 [(parallel [(set (pc) (match_operand:SI 0 "register_operand" "r"))
2558 (use (label_ref (match_operand 1 "" "")))])]
2562 /* We need to use the PC value in %o7 that was set up when the address
2563 of the label was loaded into a register, so we need different RTL. */
2566 emit_insn (gen_pic_tablejump (operands[0], operands[1]));
2571 (define_insn "pic_tablejump"
2572 [(set (pc) (match_operand:SI 0 "register_operand" "r"))
2573 (use (label_ref (match_operand 1 "" "")))
2577 [(set_attr "type" "uncond_branch")])
2580 [(set (pc) (match_operand:SI 0 "address_operand" "p"))
2581 (use (label_ref (match_operand 1 "" "")))]
2584 [(set_attr "type" "uncond_branch")])
2587 [(set (pc) (label_ref (match_operand 0 "" "")))
2588 (set (reg:SI 15) (label_ref (match_dup 0)))]
2591 [(set_attr "type" "uncond_branch")])
2593 ;; This pattern recognizes the "instruction" that appears in
2594 ;; a function call that wants a structure value,
2595 ;; to inform the called function if compiled with Sun CC.
2597 ; [(match_operand:SI 0 "immediate_operand" "")]
2598 ; "GET_CODE (operands[0]) == CONST_INT && INTVAL (operands[0]) > 0"
2600 ; [(set_attr "type" "marker")])
2602 ;;- jump to subroutine
2603 (define_expand "call"
2604 ;; Note that this expression is not used for generating RTL.
2605 ;; All the RTL is generated explicitly below.
2606 [(call (match_operand:SI 0 "call_operand" "")
2607 (match_operand 3 "" "i"))]
2608 ;; operands[2] is next_arg_register
2609 ;; operands[3] is struct_value_size_rtx.
2613 rtx fn_rtx, nregs_rtx;
2615 if (GET_CODE (XEXP (operands[0], 0)) == LABEL_REF)
2617 /* This is really a PIC sequence. We want to represent
2618 it as a funny jump so it's delay slots can be filled.
2620 ??? But if this really *is* a CALL, will not it clobber the
2621 call-clobbered registers? We lose this if it is a JUMP_INSN.
2622 Why cannot we have delay slots filled if it were a CALL? */
2624 if (INTVAL (operands[3]) > 0)
2625 emit_jump_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (3,
2626 gen_rtx (SET, VOIDmode, pc_rtx,
2627 XEXP (operands[0], 0)),
2629 gen_rtx (CLOBBER, VOIDmode,
2630 gen_rtx (REG, SImode, 15)))));
2632 emit_jump_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (2,
2633 gen_rtx (SET, VOIDmode, pc_rtx,
2634 XEXP (operands[0], 0)),
2635 gen_rtx (CLOBBER, VOIDmode,
2636 gen_rtx (REG, SImode, 15)))));
2640 fn_rtx = operands[0];
2642 /* Count the number of parameter registers being used by this call.
2643 if that argument is NULL, it means we are using them all, which
2644 means 6 on the sparc. */
2647 nregs_rtx = gen_rtx (CONST_INT, VOIDmode, REGNO (operands[2]) - 8);
2649 nregs_rtx = gen_rtx (CONST_INT, VOIDmode, 6);
2651 nregs_rtx = const0_rtx;
2654 if (INTVAL (operands[3]) > 0)
2655 emit_call_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (3,
2656 gen_rtx (CALL, VOIDmode, fn_rtx, nregs_rtx),
2658 gen_rtx (CLOBBER, VOIDmode,
2659 gen_rtx (REG, SImode, 15)))));
2661 emit_call_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (2,
2662 gen_rtx (CALL, VOIDmode, fn_rtx, nregs_rtx),
2663 gen_rtx (CLOBBER, VOIDmode,
2664 gen_rtx (REG, SImode, 15)))));
2668 /* If this call wants a structure value,
2669 emit an unimp insn to let the called function know about this. */
2670 if (INTVAL (operands[3]) > 0)
2672 rtx insn = emit_insn (operands[3]);
2673 SCHED_GROUP_P (insn) = 1;
2680 ;; We can't use the same pattern for these two insns, because then registers
2681 ;; in the address may not be properly reloaded.
2684 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
2685 (match_operand 1 "" ""))
2686 (clobber (reg:SI 15))]
2687 ;;- Do not use operand 1 for most machines.
2691 return \"call %a0,%1%#\";
2693 [(set_attr "type" "call")])
2696 [(call (mem:SI (match_operand:SI 0 "immediate_operand" "i"))
2697 (match_operand 1 "" ""))
2698 (clobber (reg:SI 15))]
2699 ;;- Do not use operand 1 for most machines.
2703 return \"call %a0,%1%#\";
2705 [(set_attr "type" "call")])
2707 ;; This is a call that wants a structure value.
2709 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
2710 (match_operand 1 "" ""))
2711 (match_operand 2 "immediate_operand" "")
2712 (clobber (reg:SI 15))]
2713 ;;- Do not use operand 1 for most machines.
2714 "GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
2717 return \"call %a0,%1\;nop\;unimp %2\";
2719 [(set_attr "type" "call_no_delay_slot")])
2721 ;; This is a call that wants a structure value.
2723 [(call (mem:SI (match_operand:SI 0 "immediate_operand" "i"))
2724 (match_operand 1 "" ""))
2725 (match_operand 2 "immediate_operand" "")
2726 (clobber (reg:SI 15))]
2727 ;;- Do not use operand 1 for most machines.
2728 "GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
2731 return \"call %a0,%1\;nop\;unimp %2\";
2733 [(set_attr "type" "call_no_delay_slot")])
2735 (define_expand "call_value"
2736 [(set (match_operand 0 "register_operand" "=rf")
2737 (call (match_operand:SI 1 "" "")
2738 (match_operand 4 "" "")))]
2739 ;; operand 3 is next_arg_register
2743 rtx fn_rtx, nregs_rtx;
2746 fn_rtx = operands[1];
2750 nregs_rtx = gen_rtx (CONST_INT, VOIDmode, REGNO (operands[3]) - 8);
2752 nregs_rtx = gen_rtx (CONST_INT, VOIDmode, 6);
2754 nregs_rtx = const0_rtx;
2758 gen_rtx (SET, VOIDmode, operands[0],
2759 gen_rtx (CALL, VOIDmode, fn_rtx, nregs_rtx)),
2760 gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, 15)));
2762 emit_call_insn (gen_rtx (PARALLEL, VOIDmode, vec));
2768 [(set (match_operand 0 "" "=rf")
2769 (call (mem:SI (match_operand:SI 1 "address_operand" "p"))
2770 (match_operand 2 "" "")))
2771 (clobber (reg:SI 15))]
2772 ;;- Do not use operand 2 for most machines.
2776 return \"call %a1,%2%#\";
2778 [(set_attr "type" "call")])
2781 [(set (match_operand 0 "" "=rf")
2782 (call (mem:SI (match_operand:SI 1 "immediate_operand" "i"))
2783 (match_operand 2 "" "")))
2784 (clobber (reg:SI 15))]
2785 ;;- Do not use operand 2 for most machines.
2789 return \"call %a1,%2%#\";
2791 [(set_attr "type" "call")])
2793 (define_expand "untyped_call"
2794 [(parallel [(call (match_operand:SI 0 "call_operand" "")
2796 (match_operand:BLK 1 "memory_operand" "")
2797 (match_operand 2 "" "")
2798 (clobber (reg:SI 15))])]
2802 operands[1] = change_address (operands[1], DImode, XEXP (operands[1], 0));
2805 ;; Make a call followed by two nops in case the function being called
2806 ;; returns a structure value and expects to skip an unimp instruction.
2809 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
2811 (match_operand:DI 1 "memory_operand" "o")
2812 (match_operand 2 "" "")
2813 (clobber (reg:SI 15))]
2817 operands[2] = adj_offsettable_operand (operands[1], 8);
2818 return \"call %a0,0\;nop\;nop\;std %%o0,%1\;st %%f0,%2\";
2820 [(set_attr "type" "multi")])
2822 ;; Make a call followed by two nops in case the function being called
2823 ;; returns a structure value and expects to skip an unimp instruction.
2826 [(call (mem:SI (match_operand:SI 0 "immediate_operand" "i"))
2828 (match_operand:DI 1 "memory_operand" "o")
2829 (match_operand 2 "" "")
2830 (clobber (reg:SI 15))]
2834 operands[2] = adj_offsettable_operand (operands[1], 8);
2835 return \"call %a0,0\;nop\;nop\;std %%o0,%1\;st %%f0,%2\";
2837 [(set_attr "type" "multi")])
2839 ;; Prepare to return any type including a structure value.
2841 (define_expand "untyped_return"
2842 [(match_operand:BLK 0 "memory_operand" "")
2843 (match_operand 1 "" "")]
2847 rtx valreg1 = gen_rtx (REG, DImode, 24);
2848 rtx valreg2 = gen_rtx (REG, DFmode, 32);
2849 rtx result = operands[0];
2850 rtx rtnreg = gen_rtx (REG, SImode, (leaf_function ? 15 : 31));
2851 rtx value = gen_reg_rtx (SImode);
2853 /* Fetch the instruction where we will return to and see if it's an unimp
2854 instruction (the most significant 10 bits will be zero). If so,
2855 update the return address to skip the unimp instruction. */
2856 emit_move_insn (value,
2857 gen_rtx (MEM, SImode, plus_constant (rtnreg, 8)));
2858 emit_insn (gen_lshrsi3 (value, value, GEN_INT (22)));
2859 emit_insn (gen_update_return (rtnreg, value));
2861 /* Reload the function value registers. */
2862 emit_move_insn (valreg1, change_address (result, DImode, XEXP (result, 0)));
2863 emit_move_insn (valreg2,
2864 change_address (result, DFmode,
2865 plus_constant (XEXP (result, 0), 8)));
2867 /* Put USE insns before the return. */
2868 emit_insn (gen_rtx (USE, VOIDmode, valreg1));
2869 emit_insn (gen_rtx (USE, VOIDmode, valreg2));
2871 /* Construct the return. */
2872 expand_null_return ();
2877 ;; This is a bit of a hack. We're incrementing a fixed register (%i7),
2878 ;; and parts of the compiler don't want to believe that the add is needed.
2880 (define_insn "update_return"
2881 [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
2882 (match_operand:SI 1 "register_operand" "r")] 0)]
2884 "cmp %1,0\;be,a .+8\;add %0,4,%0"
2885 [(set_attr "type" "multi")])
2887 (define_insn "return"
2890 "* return output_return (operands);"
2891 [(set_attr "type" "multi")])
2898 (define_insn "indirect_jump"
2899 [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
2902 [(set_attr "type" "uncond_branch")])
2904 (define_expand "nonlocal_goto"
2905 [(match_operand:SI 0 "general_operand" "")
2906 (match_operand:SI 1 "general_operand" "")
2907 (match_operand:SI 2 "general_operand" "")
2908 (match_operand:SI 3 "" "")]
2912 /* Trap instruction to flush all the registers window. */
2913 emit_insn (gen_flush_register_windows ());
2914 /* Load the fp value for the containing fn into %fp.
2915 This is needed because operands[2] refers to %fp.
2916 Virtual register instantiation fails if the virtual %fp isn't set from a
2917 register. Thus we must copy operands[0] into a register if it isn't
2919 if (GET_CODE (operands[0]) != REG)
2920 operands[0] = force_reg (SImode, operands[0]);
2921 emit_move_insn (virtual_stack_vars_rtx, operands[0]);
2922 /* Find the containing function's current nonlocal goto handler,
2923 which will do any cleanups and then jump to the label. */
2924 emit_move_insn (gen_rtx (REG, SImode, 8), operands[1]);
2925 /* Restore %fp from stack pointer value for containing function.
2926 The restore insn that follows will move this to %sp,
2927 and reload the appropriate value into %fp. */
2928 emit_move_insn (frame_pointer_rtx, operands[2]);
2929 /* Put in the static chain register the nonlocal label address. */
2930 emit_move_insn (static_chain_rtx, operands[3]);
2931 /* USE of frame_pointer_rtx added for consistency; not clear if
2933 emit_insn (gen_rtx (USE, VOIDmode, frame_pointer_rtx));
2934 emit_insn (gen_rtx (USE, VOIDmode, stack_pointer_rtx));
2935 emit_insn (gen_rtx (USE, VOIDmode, static_chain_rtx));
2936 emit_insn (gen_rtx (USE, VOIDmode, gen_rtx (REG, SImode, 8)));
2937 /* Return, restoring reg window and jumping to goto handler. */
2938 emit_insn (gen_goto_handler_and_restore ());
2942 ;; Special trap insn to flush register windows.
2943 (define_insn "flush_register_windows"
2944 [(unspec_volatile [(const_int 0)] 0)]
2947 [(set_attr "type" "misc")])
2949 (define_insn "goto_handler_and_restore"
2950 [(unspec_volatile [(const_int 0)] 1)]
2952 "jmp %%o0+0\;restore"
2953 [(set_attr "type" "misc")
2954 (set_attr "length" "2")])
2958 ;; The scan instruction searches from the most significant bit while ffs
2959 ;; searches from the least significant bit. The bit index and treatment of
2960 ;; zero also differ. It takes at least 7 instructions to get the proper
2961 ;; result. Here is an obvious 8 instruction seequence.
2963 (define_insn "ffssi2"
2964 [(set (match_operand:SI 0 "register_operand" "=&r")
2965 (ffs:SI (match_operand:SI 1 "register_operand" "r")))
2966 (clobber (match_scratch:SI 2 "=&r"))]
2968 "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"
2969 [(set_attr "type" "multi")
2970 (set_attr "length" "8")])
2972 ;; Split up troublesome insns for better scheduling. */
2974 ;; The following patterns are straightforward. They can be applied
2975 ;; either before or after register allocation.
2978 [(set (match_operator 0 "memop" [(match_operand:SI 1 "symbolic_operand" "")])
2979 (match_operand 2 "reg_or_0_operand" ""))
2980 (clobber (match_operand:SI 3 "register_operand" ""))]
2982 [(set (match_dup 3) (high:SI (match_dup 1)))
2983 (set (match_op_dup 0 [(lo_sum:SI (match_dup 3) (match_dup 1))])
2988 [(set (match_operator 0 "memop"
2989 [(match_operand:SI 1 "immediate_operand" "")])
2990 (match_operand 2 "general_operand" ""))
2991 (clobber (match_operand:SI 3 "register_operand" ""))]
2993 [(set (match_op_dup 0 [(match_dup 1)])
2997 operands[1] = legitimize_pic_address (operands[1], GET_MODE (operands[0]),
3002 [(set (match_operand 0 "register_operand" "")
3003 (match_operator 1 "memop"
3004 [(match_operand:SI 2 "immediate_operand" "")]))]
3007 (match_op_dup 1 [(match_dup 2)]))]
3010 operands[2] = legitimize_pic_address (operands[2], GET_MODE (operands[1]),
3014 ;; Sign- and Zero-extend operations can have symbolic memory operands.
3017 [(set (match_operand 0 "register_operand" "")
3018 (match_operator 1 "extend_op"
3019 [(match_operator 2 "memop"
3020 [(match_operand:SI 3 "immediate_operand" "")])]))]
3023 (match_op_dup 1 [(match_op_dup 2 [(match_dup 3)])]))]
3026 operands[3] = legitimize_pic_address (operands[3], GET_MODE (operands[2]),
3031 [(set (match_operand:SI 0 "register_operand" "")
3032 (match_operand:SI 1 "immediate_operand" ""))]
3033 "! flag_pic && (GET_CODE (operands[1]) == SYMBOL_REF
3034 || GET_CODE (operands[1]) == CONST
3035 || GET_CODE (operands[1]) == LABEL_REF)"
3036 [(set (match_dup 0) (high:SI (match_dup 1)))
3038 (lo_sum:SI (match_dup 0) (match_dup 1)))]
3041 ;; LABEL_REFs are not modified by `legitimize_pic_address`
3042 ;; so do not recurse infinitely in the PIC case.
3044 [(set (match_operand:SI 0 "register_operand" "")
3045 (match_operand:SI 1 "immediate_operand" ""))]
3046 "flag_pic && (GET_CODE (operands[1]) == SYMBOL_REF
3047 || GET_CODE (operands[1]) == CONST)"
3048 [(set (match_dup 0) (match_dup 1))]
3051 operands[1] = legitimize_pic_address (operands[1], Pmode, operands[0]);
3054 ;; These split sne/seq insns. The forms of the resulting insns are
3055 ;; somewhat bogus, but they avoid extra patterns and show data dependency.
3056 ;; Nothing will look at these in detail after splitting has occurred.
3059 [(set (match_operand:SI 0 "register_operand" "")
3060 (ne:SI (match_operand:SI 1 "register_operand" "") (const_int 0)))
3061 (clobber (reg:CC 0))]
3063 [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
3065 (set (match_dup 0) (ltu:SI (reg:CC 0) (const_int 0)))]
3069 [(set (match_operand:SI 0 "register_operand" "")
3070 (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "")
3072 (clobber (reg:CC 0))]
3074 [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
3076 (set (match_dup 0) (neg:SI (ltu:SI (reg:CC 0) (const_int 0))))]
3080 [(set (match_operand:SI 0 "register_operand" "")
3081 (eq:SI (match_operand:SI 1 "register_operand" "") (const_int 0)))
3082 (clobber (reg:CC 0))]
3084 [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
3086 (set (match_dup 0) (geu:SI (reg:CC 0) (const_int 0)))]
3090 [(set (match_operand:SI 0 "register_operand" "")
3091 (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "")
3093 (clobber (reg:CC 0))]
3095 [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
3097 (set (match_dup 0) (neg:SI (geu:SI (reg:CC 0) (const_int 0))))]
3101 [(set (match_operand:SI 0 "register_operand" "")
3102 (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "")
3104 (match_operand:SI 2 "register_operand" "")))
3105 (clobber (reg:CC 0))]
3107 [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
3109 (set (match_dup 0) (plus:SI (ltu:SI (reg:CC 0) (const_int 0))
3114 [(set (match_operand:SI 0 "register_operand" "")
3115 (minus:SI (match_operand:SI 2 "register_operand" "")
3116 (ne:SI (match_operand:SI 1 "register_operand" "")
3118 (clobber (reg:CC 0))]
3120 [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
3122 (set (match_dup 0) (minus:SI (match_dup 2)
3123 (ltu:SI (reg:CC 0) (const_int 0))))]
3127 [(set (match_operand:SI 0 "register_operand" "")
3128 (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "")
3130 (match_operand:SI 2 "register_operand" "")))
3131 (clobber (reg:CC 0))]
3133 [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
3135 (set (match_dup 0) (plus:SI (geu:SI (reg:CC 0) (const_int 0))
3140 [(set (match_operand:SI 0 "register_operand" "")
3141 (minus:SI (match_operand:SI 2 "register_operand" "")
3142 (eq:SI (match_operand:SI 1 "register_operand" "")
3144 (clobber (reg:CC 0))]
3146 [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
3148 (set (match_dup 0) (minus:SI (match_dup 2)
3149 (geu:SI (reg:CC 0) (const_int 0))))]
3152 ;; Peepholes go at the end.
3154 ;; Optimize consecutive loads or stores into ldd and std when possible.
3155 ;; The conditions in which we do this are very restricted and are
3156 ;; explained in the code for {registers,memory}_ok_for_ldd functions.
3159 [(set (match_operand:SI 0 "register_operand" "=rf")
3160 (match_operand:SI 1 "memory_operand" ""))
3161 (set (match_operand:SI 2 "register_operand" "=rf")
3162 (match_operand:SI 3 "memory_operand" ""))]
3163 "registers_ok_for_ldd_peep (operands[0], operands[2])
3164 && ! MEM_VOLATILE_P (operands[1]) && ! MEM_VOLATILE_P (operands[3])
3165 && addrs_ok_for_ldd_peep (XEXP (operands[1], 0), XEXP (operands[3], 0))"
3169 [(set (match_operand:SI 0 "memory_operand" "")
3170 (match_operand:SI 1 "register_operand" "rf"))
3171 (set (match_operand:SI 2 "memory_operand" "")
3172 (match_operand:SI 3 "register_operand" "rf"))]
3173 "registers_ok_for_ldd_peep (operands[1], operands[3])
3174 && ! MEM_VOLATILE_P (operands[0]) && ! MEM_VOLATILE_P (operands[2])
3175 && addrs_ok_for_ldd_peep (XEXP (operands[0], 0), XEXP (operands[2], 0))"
3179 [(set (match_operand:SF 0 "register_operand" "=fr")
3180 (match_operand:SF 1 "memory_operand" ""))
3181 (set (match_operand:SF 2 "register_operand" "=fr")
3182 (match_operand:SF 3 "memory_operand" ""))]
3183 "registers_ok_for_ldd_peep (operands[0], operands[2])
3184 && ! MEM_VOLATILE_P (operands[1]) && ! MEM_VOLATILE_P (operands[3])
3185 && addrs_ok_for_ldd_peep (XEXP (operands[1], 0), XEXP (operands[3], 0))"
3189 [(set (match_operand:SF 0 "memory_operand" "")
3190 (match_operand:SF 1 "register_operand" "fr"))
3191 (set (match_operand:SF 2 "memory_operand" "")
3192 (match_operand:SF 3 "register_operand" "fr"))]
3193 "registers_ok_for_ldd_peep (operands[1], operands[3])
3194 && ! MEM_VOLATILE_P (operands[0]) && ! MEM_VOLATILE_P (operands[2])
3195 && addrs_ok_for_ldd_peep (XEXP (operands[0], 0), XEXP (operands[2], 0))"
3199 [(set (match_operand:SI 0 "register_operand" "=rf")
3200 (match_operand:SI 1 "memory_operand" ""))
3201 (set (match_operand:SI 2 "register_operand" "=rf")
3202 (match_operand:SI 3 "memory_operand" ""))]
3203 "registers_ok_for_ldd_peep (operands[2], operands[0])
3204 && ! MEM_VOLATILE_P (operands[3]) && ! MEM_VOLATILE_P (operands[1])
3205 && addrs_ok_for_ldd_peep (XEXP (operands[3], 0), XEXP (operands[1], 0))"
3209 [(set (match_operand:SI 0 "memory_operand" "")
3210 (match_operand:SI 1 "register_operand" "rf"))
3211 (set (match_operand:SI 2 "memory_operand" "")
3212 (match_operand:SI 3 "register_operand" "rf"))]
3213 "registers_ok_for_ldd_peep (operands[3], operands[1])
3214 && ! MEM_VOLATILE_P (operands[2]) && ! MEM_VOLATILE_P (operands[0])
3215 && addrs_ok_for_ldd_peep (XEXP (operands[2], 0), XEXP (operands[0], 0))"
3219 [(set (match_operand:SF 0 "register_operand" "=fr")
3220 (match_operand:SF 1 "memory_operand" ""))
3221 (set (match_operand:SF 2 "register_operand" "=fr")
3222 (match_operand:SF 3 "memory_operand" ""))]
3223 "registers_ok_for_ldd_peep (operands[2], operands[0])
3224 && ! MEM_VOLATILE_P (operands[3]) && ! MEM_VOLATILE_P (operands[1])
3225 && addrs_ok_for_ldd_peep (XEXP (operands[3], 0), XEXP (operands[1], 0))"
3229 [(set (match_operand:SF 0 "memory_operand" "")
3230 (match_operand:SF 1 "register_operand" "fr"))
3231 (set (match_operand:SF 2 "memory_operand" "")
3232 (match_operand:SF 3 "register_operand" "fr"))]
3233 "registers_ok_for_ldd_peep (operands[3], operands[1])
3234 && ! MEM_VOLATILE_P (operands[2]) && ! MEM_VOLATILE_P (operands[0])
3235 && addrs_ok_for_ldd_peep (XEXP (operands[2], 0), XEXP (operands[0], 0))"
3238 ;; Optimize the case of following a reg-reg move with a test
3239 ;; of reg just moved. Don't allow floating point regs for operand 0 or 1.
3240 ;; This can result from a float to fix conversion.
3243 [(set (match_operand:SI 0 "register_operand" "=r")
3244 (match_operand:SI 1 "register_operand" "r"))
3246 (compare:CC (match_operand:SI 2 "register_operand" "r")
3248 "(rtx_equal_p (operands[2], operands[0])
3249 || rtx_equal_p (operands[2], operands[1]))
3250 && ! FP_REG_P (operands[0]) && ! FP_REG_P (operands[1])"
3253 ;; Do {sign,zero}-extended compares somewhat more efficiently.
3254 ;; ??? Is this now the Right Way to do this? Or will SCRATCH
3255 ;; eventually have some impact here?
3258 [(set (match_operand:HI 0 "register_operand" "")
3259 (match_operand:HI 1 "memory_operand" ""))
3260 (set (match_operand:SI 2 "register_operand" "")
3261 (sign_extend:SI (match_dup 0)))
3263 (compare:CC (match_dup 2)
3266 "ldsh %1,%0\;orcc %0,%%g0,%2")
3269 [(set (match_operand:QI 0 "register_operand" "")
3270 (match_operand:QI 1 "memory_operand" ""))
3271 (set (match_operand:SI 2 "register_operand" "")
3272 (sign_extend:SI (match_dup 0)))
3274 (compare:CC (match_dup 2)
3277 "ldsb %1,%0\;orcc %0,%%g0,%2")
3280 [(set (match_operand:HI 0 "register_operand" "")
3281 (match_operand:HI 1 "memory_operand" ""))
3282 (set (match_operand:SI 2 "register_operand" "")
3283 (sign_extend:SI (match_dup 0)))]
3284 "dead_or_set_p (insn, operands[0])"
3287 warning (\"bad peephole\");
3288 if (! MEM_VOLATILE_P (operands[1]))
3290 return \"ldsh %1,%2\";
3294 [(set (match_operand:QI 0 "register_operand" "")
3295 (match_operand:QI 1 "memory_operand" ""))
3296 (set (match_operand:SI 2 "register_operand" "")
3297 (sign_extend:SI (match_dup 0)))]
3298 "dead_or_set_p (insn, operands[0])"
3301 warning (\"bad peephole\");
3302 if (! MEM_VOLATILE_P (operands[1]))
3304 return \"ldsb %1,%2\";
3307 ;; Floating-point move peepholes
3310 [(set (match_operand:SI 0 "register_operand" "=r")
3311 (lo_sum:SI (match_dup 0)
3312 (match_operand:SI 1 "immediate_operand" "i")))
3313 (set (match_operand:DF 2 "register_operand" "=fr")
3314 (mem:DF (match_dup 0)))]
3315 "RTX_UNCHANGING_P (operands[1]) && reg_unused_after (operands[0], insn)"
3318 /* Go by way of output_move_double in case the register in operand 2
3319 is not properly aligned for ldd. */
3320 operands[1] = gen_rtx (MEM, DFmode,
3321 gen_rtx (LO_SUM, SImode, operands[0], operands[1]));
3322 operands[0] = operands[2];
3323 return output_move_double (operands);
3327 [(set (match_operand:SI 0 "register_operand" "=r")
3328 (lo_sum:SI (match_dup 0)
3329 (match_operand:SI 1 "immediate_operand" "i")))
3330 (set (match_operand:SF 2 "register_operand" "=fr")
3331 (mem:SF (match_dup 0)))]
3332 "RTX_UNCHANGING_P (operands[1]) && reg_unused_after (operands[0], insn)"
3333 "ld [%0+%%lo(%a1)],%2")
3335 ;; Return peepholes. First the "normal" ones
3337 ;; ??? There are QImode, HImode, and SImode versions of this pattern.
3338 ;; It might be possible to write one more general pattern instead of three.
3341 [(set (match_operand:QI 0 "restore_operand" "")
3342 (match_operand:QI 1 "arith_operand" "rI"))
3347 if (current_function_returns_struct)
3348 return \"jmp %%i7+12\;restore %%g0,%1,%Y0\";
3350 return \"ret\;restore %%g0,%1,%Y0\";
3352 [(set_attr "type" "multi")])
3355 [(set (match_operand:HI 0 "restore_operand" "")
3356 (match_operand:HI 1 "arith_operand" "rI"))
3361 if (current_function_returns_struct)
3362 return \"jmp %%i7+12\;restore %%g0,%1,%Y0\";
3364 return \"ret\;restore %%g0,%1,%Y0\";
3366 [(set_attr "type" "multi")])
3369 [(set (match_operand:SI 0 "restore_operand" "")
3370 (match_operand:SI 1 "arith_operand" "rI"))
3375 if (current_function_returns_struct)
3376 return \"jmp %%i7+12\;restore %%g0,%1,%Y0\";
3378 return \"ret\;restore %%g0,%1,%Y0\";
3380 [(set_attr "type" "multi")])
3382 ;; The following pattern is only generated by delayed-branch scheduling,
3383 ;; when the insn winds up in the epilogue. This can only happen when
3384 ;; ! TARGET_FPU because otherwise fp return values are in %f0.
3386 [(set (match_operand:SF 0 "restore_operand" "r")
3387 (match_operand:SF 1 "register_operand" "r"))
3389 "! TARGET_FPU && ! TARGET_EPILOGUE"
3392 if (current_function_returns_struct)
3393 return \"jmp %%i7+12\;restore %%g0,%1,%Y0\";
3395 return \"ret\;restore %%g0,%1,%Y0\";
3397 [(set_attr "type" "multi")])
3400 [(set (match_operand:SI 0 "restore_operand" "")
3401 (plus:SI (match_operand:SI 1 "arith_operand" "%r")
3402 (match_operand:SI 2 "arith_operand" "rI")))
3407 if (current_function_returns_struct)
3408 return \"jmp %%i7+12\;restore %r1,%2,%Y0\";
3410 return \"ret\;restore %r1,%2,%Y0\";
3412 [(set_attr "type" "multi")])
3414 ;; Turned off because it should never match (subtracting a constant
3415 ;; is turned into addition) and because it would do the wrong thing
3416 ;; when operand 2 is -4096 (--4096 == 4096 is not a valid immediate).
3418 ;; [(set (match_operand:SI 0 "restore_operand" "")
3419 ;; (minus:SI (match_operand:SI 1 "register_operand" "r")
3420 ;; (match_operand:SI 2 "small_int" "I")))
3422 ;; "! TARGET_EPILOGUE"
3423 ;; "ret\;restore %1,-(%2),%Y0"
3424 ;; [(set_attr "type" "multi")])
3426 ;; The following pattern is only generated by delayed-branch scheduling,
3427 ;; when the insn winds up in the epilogue.
3430 (match_operand:SF 0 "register_operand" "f"))
3433 "ret\;fmovs %0,%%f0"
3434 [(set_attr "type" "multi")])
3436 ;; Now peepholes to go a call followed by a jump.
3439 [(parallel [(set (match_operand 0 "" "")
3440 (call (mem:SI (match_operand:SI 1 "call_operand_address" "pi"))
3441 (match_operand 2 "" "")))
3442 (clobber (reg:SI 15))])
3443 (set (pc) (label_ref (match_operand 3 "" "")))]
3444 "short_branch (INSN_UID (insn), INSN_UID (operands[3]))"
3447 return \"call %a1,%2\;add %%o7,(%l3-.-4),%%o7\";
3451 [(parallel [(call (mem:SI (match_operand:SI 0 "call_operand_address" "pi"))
3452 (match_operand 1 "" ""))
3453 (clobber (reg:SI 15))])
3454 (set (pc) (label_ref (match_operand 2 "" "")))]
3455 "short_branch (INSN_UID (insn), INSN_UID (operands[2]))"
3458 return \"call %a0,%1\;add %%o7,(%l2-.-4),%%o7\";
3462 [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
3463 (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
3465 (clobber (reg:CC 0))])
3466 (set (reg:CC 0) (compare (match_dup 0) (const_int 0)))]