1 ;;- Machine description for SPARC chip for GNU C compiler
2 ;; Copyright (C) 1987, 88, 89, 92, 93, 94, 1995 Free Software Foundation, Inc.
3 ;; Contributed by Michael Tiemann (tiemann@cygnus.com)
4 ;; 64 bit SPARC V9 support by Michael Tiemann, Jim Wilson, and Doug Evans,
7 ;; This file is part of GNU CC.
9 ;; GNU CC is free software; you can redistribute it and/or modify
10 ;; it under the terms of the GNU General Public License as published by
11 ;; the Free Software Foundation; either version 2, or (at your option)
14 ;; GNU CC is distributed in the hope that it will be useful,
15 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
16 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 ;; GNU General Public License for more details.
19 ;; You should have received a copy of the GNU General Public License
20 ;; along with GNU CC; see the file COPYING. If not, write to
21 ;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
23 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
25 ;; The upper 32 fp regs on the v9 can't hold SFmode values. To deal with this
26 ;; a second register class, EXTRA_FP_REGS, exists for the v9 chip. The name
27 ;; is a bit of a misnomer as it covers all 64 fp regs. The corresponding
28 ;; constraint letter is 'e'. To avoid any confusion, 'e' is used instead of
29 ;; 'f' for all DF/TFmode values, including those that are specific to the v8.
31 ;; Architecture type. Arch32bit includes v7, sparclite, v8.
33 (define_attr "arch" "arch32bit,arch64bit"
34 (const (symbol_ref "sparc_arch_type")))
36 ;; CPU type. This is only used for instruction scheduling
37 (define_attr "cpu" "cypress,supersparc"
39 (cond [(symbol_ref "TARGET_SUPERSPARC") (const_string "supersparc")]
40 (const_string "cypress"))))
42 ;; Insn type. Used to default other attribute values.
44 ;; type "unary" insns have one input operand (1) and one output operand (0)
45 ;; type "binary" insns have two input operands (1,2) and one output (0)
46 ;; type "compare" insns have one or two input operands (0,1) and no output
47 ;; type "call_no_delay_slot" is a call followed by an unimp instruction.
50 "move,unary,binary,compare,load,store,ialu,shift,uncond_branch,branch,call,call_no_delay_slot,address,imul,fpload,fpstore,fp,fpcmp,fpmul,fpdivs,fpdivd,fpsqrt,cmove,multi,misc"
51 (const_string "binary"))
53 ;; Set true if insn uses call-clobbered intermediate register.
54 (define_attr "use_clobbered" "false,true"
55 (if_then_else (and (eq_attr "type" "address")
56 (match_operand 0 "clobbered_register" ""))
58 (const_string "false")))
60 ;; Length (in # of insns).
61 (define_attr "length" ""
62 (cond [(eq_attr "type" "load,fpload")
63 (if_then_else (match_operand 1 "symbolic_memory_operand" "")
64 (const_int 2) (const_int 1))
66 (eq_attr "type" "store,fpstore")
67 (if_then_else (match_operand 0 "symbolic_memory_operand" "")
68 (const_int 2) (const_int 1))
70 (eq_attr "type" "address") (const_int 2)
72 (eq_attr "type" "binary")
73 (if_then_else (ior (match_operand 2 "arith_operand" "")
74 (match_operand 2 "arith_double_operand" ""))
75 (const_int 1) (const_int 3))
77 (eq_attr "type" "multi") (const_int 2)
79 (eq_attr "type" "move,unary")
80 (if_then_else (ior (match_operand 1 "arith_operand" "")
81 (match_operand 1 "arith_double_operand" ""))
82 (const_int 1) (const_int 2))]
86 (define_asm_attributes
87 [(set_attr "length" "1")
88 (set_attr "type" "multi")])
90 ;; Attributes for instruction and branch scheduling
92 (define_attr "in_call_delay" "false,true"
93 (cond [(eq_attr "type" "uncond_branch,branch,call,call_no_delay_slot,multi")
94 (const_string "false")
95 (eq_attr "type" "load,fpload,store,fpstore")
96 (if_then_else (eq_attr "length" "1")
98 (const_string "false"))
99 (eq_attr "type" "address")
100 (if_then_else (eq_attr "use_clobbered" "false")
101 (const_string "true")
102 (const_string "false"))]
103 (if_then_else (eq_attr "length" "1")
104 (const_string "true")
105 (const_string "false"))))
107 (define_delay (eq_attr "type" "call")
108 [(eq_attr "in_call_delay" "true") (nil) (nil)])
110 ;; ??? Should implement the notion of predelay slots for floating point
111 ;; branches. This would allow us to remove the nop always inserted before
112 ;; a floating point branch.
114 ;; ??? It is OK for fill_simple_delay_slots to put load/store instructions
115 ;; in a delay slot, but it is not OK for fill_eager_delay_slots to do so.
116 ;; This is because doing so will add several pipeline stalls to the path
117 ;; that the load/store did not come from. Unfortunately, there is no way
118 ;; to prevent fill_eager_delay_slots from using load/store without completely
119 ;; disabling them. For the SPEC benchmark set, this is a serious lose,
120 ;; because it prevents us from moving back the final store of inner loops.
122 (define_attr "in_branch_delay" "false,true"
123 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,call_no_delay_slot,multi")
124 (eq_attr "length" "1"))
125 (const_string "true")
126 (const_string "false")))
128 (define_attr "in_uncond_branch_delay" "false,true"
129 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,call_no_delay_slot,multi")
130 (eq_attr "length" "1"))
131 (const_string "true")
132 (const_string "false")))
134 (define_attr "in_annul_branch_delay" "false,true"
135 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,call_no_delay_slot,multi")
136 (eq_attr "length" "1"))
137 (const_string "true")
138 (const_string "false")))
140 (define_delay (eq_attr "type" "branch")
141 [(eq_attr "in_branch_delay" "true")
142 (nil) (eq_attr "in_annul_branch_delay" "true")])
144 (define_delay (eq_attr "type" "uncond_branch")
145 [(eq_attr "in_uncond_branch_delay" "true")
148 ;; Function units of the SPARC
150 ;; (define_function_unit {name} {num-units} {n-users} {test}
151 ;; {ready-delay} {issue-delay} [{conflict-list}])
154 ;; (Noted only for documentation; units that take one cycle do not need to
157 ;; On the sparclite, integer multiply takes 1, 3, or 5 cycles depending on
160 ;; (define_function_unit "alu" 1 0
161 ;; (eq_attr "type" "unary,binary,move,address") 1 0)
163 ;; ---- cypress CY7C602 scheduling:
164 ;; Memory with load-delay of 1 (i.e., 2 cycle load).
165 (define_function_unit "memory" 1 0
166 (and (eq_attr "type" "load,fpload") (eq_attr "cpu" "cypress")) 2 2)
168 ;; SPARC has two floating-point units: the FP ALU,
169 ;; and the FP MUL/DIV/SQRT unit.
170 ;; Instruction timings on the CY7C602 are as follows
184 ;; The CY7C602 can only support 2 fp isnsn simultaneously.
185 ;; More insns cause the chip to stall.
187 (define_function_unit "fp_alu" 1 0
188 (and (eq_attr "type" "fp") (eq_attr "cpu" "cypress")) 5 5)
189 (define_function_unit "fp_mds" 1 0
190 (and (eq_attr "type" "fpmul") (eq_attr "cpu" "cypress")) 7 7)
191 (define_function_unit "fp_mds" 1 0
192 (and (eq_attr "type" "fpdivs,fpdivd") (eq_attr "cpu" "cypress")) 37 37)
193 (define_function_unit "fp_mds" 1 0
194 (and (eq_attr "type" "fpsqrt") (eq_attr "cpu" "cypress")) 63 63)
196 ;; ----- The TMS390Z55 scheduling
197 ;; The Supersparc can issue 1 - 3 insns per cycle; here we assume
198 ;; three insns/cycle, and hence multiply all costs by three.
199 ;; Combinations up to two integer, one ld/st, one fp.
200 ;; Memory delivers its result in one cycle to IU, zero cycles to FP
201 (define_function_unit "memory" 1 0
202 (and (eq_attr "type" "load") (eq_attr "cpu" "supersparc")) 3 3)
203 (define_function_unit "memory" 1 0
204 (and (eq_attr "type" "fpload") (eq_attr "cpu" "supersparc")) 1 3)
205 ;; at least one in three instructions can be a mem opt.
206 (define_function_unit "memory" 1 0
207 (and (eq_attr "type" "store,fpstore") (eq_attr "cpu" "supersparc")) 1 3)
208 ;; at least one in three instructions can be a shift op.
209 (define_function_unit "shift" 1 0
210 (and (eq_attr "type" "shift") (eq_attr "cpu" "supersparc")) 1 3)
212 ;; There are only two write ports to the integer register file
213 ;; A store also uses a write port
214 (define_function_unit "iwport" 2 0
215 (and (eq_attr "type" "load,store,shift,ialu") (eq_attr "cpu" "supersparc")) 1 3)
217 ;; Timings; throughput/latency
218 ;; FADD 1/3 add/sub, format conv, compar, abs, neg
226 (define_function_unit "fp_alu" 1 0
227 (and (eq_attr "type" "fp,fpcmp") (eq_attr "cpu" "supersparc")) 9 3)
228 (define_function_unit "fp_mds" 1 0
229 (and (eq_attr "type" "fpmul") (eq_attr "cpu" "supersparc")) 9 3)
230 (define_function_unit "fp_mds" 1 0
231 (and (eq_attr "type" "fpdivs") (eq_attr "cpu" "supersparc")) 18 12)
232 (define_function_unit "fp_mds" 1 0
233 (and (eq_attr "type" "fpdivd") (eq_attr "cpu" "supersparc")) 27 21)
234 (define_function_unit "fp_mds" 1 0
235 (and (eq_attr "type" "fpsqrt") (eq_attr "cpu" "supersparc")) 36 30)
236 (define_function_unit "fp_mds" 1 0
237 (and (eq_attr "type" "imul") (eq_attr "cpu" "supersparc")) 12 12)
239 ;; Compare instructions.
240 ;; This controls RTL generation and register allocation.
242 ;; We generate RTL for comparisons and branches by having the cmpxx
243 ;; patterns store away the operands. Then, the scc and bcc patterns
244 ;; emit RTL for both the compare and the branch.
246 ;; We do this because we want to generate different code for an sne and
247 ;; seq insn. In those cases, if the second operand of the compare is not
248 ;; const0_rtx, we want to compute the xor of the two operands and test
251 ;; We start with the DEFINE_EXPANDs, then the DEFINE_INSNs to match
252 ;; the patterns. Finally, we have the DEFINE_SPLITs for some of the scc
253 ;; insns that actually require more than one machine instruction.
255 ;; Put cmpsi first among compare insns so it matches two CONST_INT operands.
257 (define_expand "cmpsi"
259 (compare:CC (match_operand:SI 0 "register_operand" "")
260 (match_operand:SI 1 "arith_operand" "")))]
264 sparc_compare_op0 = operands[0];
265 sparc_compare_op1 = operands[1];
269 (define_expand "cmpdi"
271 (compare:CCX (match_operand:DI 0 "register_operand" "")
272 (match_operand:DI 1 "arith_double_operand" "")))]
276 sparc_compare_op0 = operands[0];
277 sparc_compare_op1 = operands[1];
281 (define_expand "cmpsf"
283 (compare:CCFP (match_operand:SF 0 "register_operand" "")
284 (match_operand:SF 1 "register_operand" "")))]
288 sparc_compare_op0 = operands[0];
289 sparc_compare_op1 = operands[1];
293 (define_expand "cmpdf"
295 (compare:CCFP (match_operand:DF 0 "register_operand" "")
296 (match_operand:DF 1 "register_operand" "")))]
300 sparc_compare_op0 = operands[0];
301 sparc_compare_op1 = operands[1];
305 (define_expand "cmptf"
307 (compare:CCFP (match_operand:TF 0 "register_operand" "")
308 (match_operand:TF 1 "register_operand" "")))]
312 sparc_compare_op0 = operands[0];
313 sparc_compare_op1 = operands[1];
317 ;; Next come the scc insns. For seq, sne, sgeu, and sltu, we can do this
318 ;; without jumps using the addx/subx instructions. For seq/sne on v9 we use
319 ;; the same code as v8 (the addx/subx method has more applications). The
320 ;; exception to this is "reg != 0" which can be done in one instruction on v9
321 ;; (so we do it). For the rest, on v9 we use conditional moves; on v8, we do
324 ;; Seq_special[_xxx] and sne_special[_xxx] clobber the CC reg, because they
325 ;; generate addcc/subcc instructions.
327 (define_expand "seqsi_special"
329 (xor:SI (match_operand:SI 1 "register_operand" "")
330 (match_operand:SI 2 "register_operand" "")))
331 (parallel [(set (match_operand:SI 0 "register_operand" "")
332 (eq:SI (match_dup 3) (const_int 0)))
333 (clobber (reg:CC 0))])]
335 "{ operands[3] = gen_reg_rtx (SImode); }")
337 (define_expand "seqdi_special"
339 (xor:DI (match_operand:DI 1 "register_operand" "")
340 (match_operand:DI 2 "register_operand" "")))
341 (parallel [(set (match_operand:DI 0 "register_operand" "")
342 (eq:DI (match_dup 3) (const_int 0)))
343 (clobber (reg:CCX 0))])]
345 "{ operands[3] = gen_reg_rtx (DImode); }")
347 (define_expand "snesi_special"
349 (xor:SI (match_operand:SI 1 "register_operand" "")
350 (match_operand:SI 2 "register_operand" "")))
351 (parallel [(set (match_operand:SI 0 "register_operand" "")
352 (ne:SI (match_dup 3) (const_int 0)))
353 (clobber (reg:CC 0))])]
355 "{ operands[3] = gen_reg_rtx (SImode); }")
357 (define_expand "snedi_special"
359 (xor:DI (match_operand:DI 1 "register_operand" "")
360 (match_operand:DI 2 "register_operand" "")))
361 (parallel [(set (match_operand:DI 0 "register_operand" "")
362 (ne:DI (match_dup 3) (const_int 0)))
363 (clobber (reg:CCX 0))])]
365 "{ operands[3] = gen_reg_rtx (DImode); }")
367 (define_expand "seqdi_special_trunc"
369 (xor:DI (match_operand:DI 1 "register_operand" "")
370 (match_operand:DI 2 "register_operand" "")))
371 (parallel [(set (match_operand:SI 0 "register_operand" "")
372 (eq:SI (subreg:SI (match_dup 3) 0) (const_int 0)))
373 (clobber (reg:CC 0))])]
375 "{ operands[3] = gen_reg_rtx (DImode); }")
377 (define_expand "snedi_special_trunc"
379 (xor:DI (match_operand:DI 1 "register_operand" "")
380 (match_operand:DI 2 "register_operand" "")))
381 (parallel [(set (match_operand:SI 0 "register_operand" "")
382 (ne:SI (subreg:SI (match_dup 3) 0) (const_int 0)))
383 (clobber (reg:CC 0))])]
385 "{ operands[3] = gen_reg_rtx (DImode); }")
387 (define_expand "seqsi_special_extend"
388 [(set (subreg:SI (match_dup 3) 0)
389 (xor:SI (match_operand:SI 1 "register_operand" "")
390 (match_operand:SI 2 "register_operand" "")))
391 (parallel [(set (match_operand:DI 0 "register_operand" "")
392 (eq:DI (match_dup 3) (const_int 0)))
393 (clobber (reg:CCX 0))])]
395 "{ operands[3] = gen_reg_rtx (DImode); }")
397 (define_expand "snesi_special_extend"
398 [(set (subreg:SI (match_dup 3) 0)
399 (xor:SI (match_operand:SI 1 "register_operand" "")
400 (match_operand:SI 2 "register_operand" "")))
401 (parallel [(set (match_operand:DI 0 "register_operand" "")
402 (ne:DI (match_dup 3) (const_int 0)))
403 (clobber (reg:CCX 0))])]
405 "{ operands[3] = gen_reg_rtx (DImode); }")
407 ;; ??? v9: Operand 0 needs a mode, so SImode was chosen.
408 ;; However, the code handles both SImode and DImode.
410 [(set (match_operand:SI 0 "intreg_operand" "")
411 (eq:SI (match_dup 1) (const_int 0)))]
415 if (GET_MODE (sparc_compare_op0) == SImode)
419 if (GET_MODE (operands[0]) == SImode)
420 pat = gen_seqsi_special (operands[0], sparc_compare_op0,
422 else if (! TARGET_V9)
425 pat = gen_seqsi_special_extend (operands[0], sparc_compare_op0,
430 else if (GET_MODE (sparc_compare_op0) == DImode)
434 if (GET_MODE (operands[0]) == SImode)
435 pat = gen_seqdi_special_trunc (operands[0], sparc_compare_op0,
437 else if (! TARGET_V9)
440 pat = gen_seqdi_special (operands[0], sparc_compare_op0,
445 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
447 emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, EQ);
448 emit_insn (gen_sne (operands[0]));
453 if (gen_v9_scc (EQ, operands))
457 operands[1] = gen_compare_reg (EQ, sparc_compare_op0, sparc_compare_op1);
460 ;; ??? v9: Operand 0 needs a mode, so SImode was chosen.
461 ;; However, the code handles both SImode and DImode.
463 [(set (match_operand:SI 0 "intreg_operand" "")
464 (ne:SI (match_dup 1) (const_int 0)))]
468 if (GET_MODE (sparc_compare_op0) == SImode)
472 if (GET_MODE (operands[0]) == SImode)
473 pat = gen_snesi_special (operands[0], sparc_compare_op0,
475 else if (! TARGET_V9)
478 pat = gen_snesi_special_extend (operands[0], sparc_compare_op0,
483 else if (GET_MODE (sparc_compare_op0) == DImode)
487 if (GET_MODE (operands[0]) == SImode)
488 pat = gen_snedi_special_trunc (operands[0], sparc_compare_op0,
490 else if (! TARGET_V9)
493 pat = gen_snedi_special (operands[0], sparc_compare_op0,
498 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
500 emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, NE);
501 emit_insn (gen_sne (operands[0]));
506 if (gen_v9_scc (NE, operands))
510 operands[1] = gen_compare_reg (NE, sparc_compare_op0, sparc_compare_op1);
514 [(set (match_operand:SI 0 "intreg_operand" "")
515 (gt:SI (match_dup 1) (const_int 0)))]
519 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
521 emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GT);
522 emit_insn (gen_sne (operands[0]));
527 if (gen_v9_scc (GT, operands))
531 operands[1] = gen_compare_reg (GT, sparc_compare_op0, sparc_compare_op1);
535 [(set (match_operand:SI 0 "intreg_operand" "")
536 (lt:SI (match_dup 1) (const_int 0)))]
540 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
542 emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LT);
543 emit_insn (gen_sne (operands[0]));
548 if (gen_v9_scc (LT, operands))
552 operands[1] = gen_compare_reg (LT, sparc_compare_op0, sparc_compare_op1);
556 [(set (match_operand:SI 0 "intreg_operand" "")
557 (ge:SI (match_dup 1) (const_int 0)))]
561 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
563 emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GE);
564 emit_insn (gen_sne (operands[0]));
569 if (gen_v9_scc (GE, operands))
573 operands[1] = gen_compare_reg (GE, sparc_compare_op0, sparc_compare_op1);
577 [(set (match_operand:SI 0 "intreg_operand" "")
578 (le:SI (match_dup 1) (const_int 0)))]
582 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
584 emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LE);
585 emit_insn (gen_sne (operands[0]));
590 if (gen_v9_scc (LE, operands))
594 operands[1] = gen_compare_reg (LE, sparc_compare_op0, sparc_compare_op1);
597 (define_expand "sgtu"
598 [(set (match_operand:SI 0 "intreg_operand" "")
599 (gtu:SI (match_dup 1) (const_int 0)))]
607 /* We can do ltu easily, so if both operands are registers, swap them and
609 if ((GET_CODE (sparc_compare_op0) == REG
610 || GET_CODE (sparc_compare_op0) == SUBREG)
611 && (GET_CODE (sparc_compare_op1) == REG
612 || GET_CODE (sparc_compare_op1) == SUBREG))
614 tem = sparc_compare_op0;
615 sparc_compare_op0 = sparc_compare_op1;
616 sparc_compare_op1 = tem;
617 emit_insn (gen_sltu (operands[0]));
623 if (gen_v9_scc (GTU, operands))
626 operands[1] = gen_compare_reg (GTU, sparc_compare_op0, sparc_compare_op1);
629 (define_expand "sltu"
630 [(set (match_operand:SI 0 "intreg_operand" "")
631 (ltu:SI (match_dup 1) (const_int 0)))]
637 if (gen_v9_scc (LTU, operands))
640 operands[1] = gen_compare_reg (LTU, sparc_compare_op0, sparc_compare_op1);
643 (define_expand "sgeu"
644 [(set (match_operand:SI 0 "intreg_operand" "")
645 (geu:SI (match_dup 1) (const_int 0)))]
651 if (gen_v9_scc (GEU, operands))
654 operands[1] = gen_compare_reg (GEU, sparc_compare_op0, sparc_compare_op1);
657 (define_expand "sleu"
658 [(set (match_operand:SI 0 "intreg_operand" "")
659 (leu:SI (match_dup 1) (const_int 0)))]
667 /* We can do geu easily, so if both operands are registers, swap them and
669 if ((GET_CODE (sparc_compare_op0) == REG
670 || GET_CODE (sparc_compare_op0) == SUBREG)
671 && (GET_CODE (sparc_compare_op1) == REG
672 || GET_CODE (sparc_compare_op1) == SUBREG))
674 tem = sparc_compare_op0;
675 sparc_compare_op0 = sparc_compare_op1;
676 sparc_compare_op1 = tem;
677 emit_insn (gen_sgeu (operands[0]));
683 if (gen_v9_scc (LEU, operands))
686 operands[1] = gen_compare_reg (LEU, sparc_compare_op0, sparc_compare_op1);
689 ;; Now the DEFINE_INSNs for the compare and scc cases. First the compares.
693 (compare:CC (match_operand:SI 0 "register_operand" "r")
694 (match_operand:SI 1 "arith_operand" "rI")))]
697 [(set_attr "type" "compare")])
701 (compare:CCFPE (match_operand:SF 0 "register_operand" "f")
702 (match_operand:SF 1 "register_operand" "f")))]
703 "! TARGET_V9 && TARGET_FPU"
705 [(set_attr "type" "fpcmp")])
709 (compare:CCFPE (match_operand:DF 0 "register_operand" "e")
710 (match_operand:DF 1 "register_operand" "e")))]
711 "! TARGET_V9 && TARGET_FPU"
713 [(set_attr "type" "fpcmp")])
717 (compare:CCFPE (match_operand:TF 0 "register_operand" "e")
718 (match_operand:TF 1 "register_operand" "e")))]
719 "! TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
721 [(set_attr "type" "fpcmp")])
725 (compare:CCFP (match_operand:SF 0 "register_operand" "f")
726 (match_operand:SF 1 "register_operand" "f")))]
727 "! TARGET_V9 && TARGET_FPU"
729 [(set_attr "type" "fpcmp")])
733 (compare:CCFP (match_operand:DF 0 "register_operand" "e")
734 (match_operand:DF 1 "register_operand" "e")))]
735 "! TARGET_V9 && TARGET_FPU"
737 [(set_attr "type" "fpcmp")])
741 (compare:CCFP (match_operand:TF 0 "register_operand" "e")
742 (match_operand:TF 1 "register_operand" "e")))]
743 "! TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
745 [(set_attr "type" "fpcmp")])
749 (compare:CCX (match_operand:DI 0 "register_operand" "r")
750 (match_operand:DI 1 "arith_double_operand" "rHI")))]
753 [(set_attr "type" "compare")])
756 [(set (match_operand:CCFPE 0 "ccfp_reg_operand" "=c")
757 (compare:CCFPE (match_operand:SF 1 "register_operand" "f")
758 (match_operand:SF 2 "register_operand" "f")))]
759 "TARGET_V9 && TARGET_FPU"
761 [(set_attr "type" "fpcmp")])
764 [(set (match_operand:CCFPE 0 "ccfp_reg_operand" "=c")
765 (compare:CCFPE (match_operand:DF 1 "register_operand" "e")
766 (match_operand:DF 2 "register_operand" "e")))]
767 "TARGET_V9 && TARGET_FPU"
769 [(set_attr "type" "fpcmp")])
772 [(set (match_operand:CCFPE 0 "ccfp_reg_operand" "=c")
773 (compare:CCFPE (match_operand:TF 1 "register_operand" "e")
774 (match_operand:TF 2 "register_operand" "e")))]
775 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
777 [(set_attr "type" "fpcmp")])
780 [(set (match_operand:CCFP 0 "ccfp_reg_operand" "=c")
781 (compare:CCFP (match_operand:SF 1 "register_operand" "f")
782 (match_operand:SF 2 "register_operand" "f")))]
783 "TARGET_V9 && TARGET_FPU"
785 [(set_attr "type" "fpcmp")])
788 [(set (match_operand:CCFP 0 "ccfp_reg_operand" "=c")
789 (compare:CCFP (match_operand:DF 1 "register_operand" "e")
790 (match_operand:DF 2 "register_operand" "e")))]
791 "TARGET_V9 && TARGET_FPU"
793 [(set_attr "type" "fpcmp")])
796 [(set (match_operand:CCFP 0 "ccfp_reg_operand" "=c")
797 (compare:CCFP (match_operand:TF 1 "register_operand" "e")
798 (match_operand:TF 2 "register_operand" "e")))]
799 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
801 [(set_attr "type" "fpcmp")])
803 ;; The SEQ and SNE patterns are special because they can be done
804 ;; without any branching and do not involve a COMPARE.
807 [(set (match_operand:SI 0 "register_operand" "=r")
808 (ne:SI (match_operand:SI 1 "register_operand" "r")
810 (clobber (reg:CC 0))]
812 "subcc %%g0,%1,%%g0\;addx %%g0,0,%0"
813 [(set_attr "type" "unary")
814 (set_attr "length" "2")])
817 [(set (match_operand:SI 0 "register_operand" "=r")
818 (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
820 (clobber (reg:CC 0))]
822 "subcc %%g0,%1,%%g0\;subx %%g0,0,%0"
823 [(set_attr "type" "unary")
824 (set_attr "length" "2")])
827 [(set (match_operand:DI 0 "register_operand" "=r")
828 (ne:DI (match_operand:DI 1 "register_operand" "r")
830 (clobber (reg:CCX 0))]
832 "mov 0,%0\;movrnz %1,1,%0"
833 [(set_attr "type" "unary")
834 (set_attr "length" "2")])
837 [(set (match_operand:DI 0 "register_operand" "=r")
838 (neg:DI (ne:DI (match_operand:DI 1 "register_operand" "r")
840 (clobber (reg:CCX 0))]
842 "mov 0,%0\;movrnz %1,-1,%0"
843 [(set_attr "type" "unary")
844 (set_attr "length" "2")])
847 [(set (match_operand:SI 0 "register_operand" "=r")
848 (eq:SI (match_operand:SI 1 "register_operand" "r")
850 (clobber (reg:CC 0))]
852 "subcc %%g0,%1,%%g0\;subx %%g0,-1,%0"
853 [(set_attr "type" "unary")
854 (set_attr "length" "2")])
857 [(set (match_operand:SI 0 "register_operand" "=r")
858 (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
860 (clobber (reg:CC 0))]
862 "subcc %%g0,%1,%%g0\;addx %%g0,-1,%0"
863 [(set_attr "type" "unary")
864 (set_attr "length" "2")])
867 [(set (match_operand:DI 0 "register_operand" "=r")
868 (eq:DI (match_operand:DI 1 "register_operand" "r")
870 (clobber (reg:CCX 0))]
872 "mov 0,%0\;movrz %1,1,%0"
873 [(set_attr "type" "unary")
874 (set_attr "length" "2")])
877 [(set (match_operand:DI 0 "register_operand" "=r")
878 (neg:DI (eq:DI (match_operand:DI 1 "register_operand" "r")
880 (clobber (reg:CCX 0))]
882 "mov 0,%0\;movrz %1,-1,%0"
883 [(set_attr "type" "unary")
884 (set_attr "length" "2")])
886 ;; We can also do (x + (i == 0)) and related, so put them in.
887 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
891 [(set (match_operand:SI 0 "register_operand" "=r")
892 (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
894 (match_operand:SI 2 "register_operand" "r")))
895 (clobber (reg:CC 0))]
897 "subcc %%g0,%1,%%g0\;addx %2,0,%0"
898 [(set_attr "length" "2")])
901 [(set (match_operand:SI 0 "register_operand" "=r")
902 (minus:SI (match_operand:SI 2 "register_operand" "r")
903 (ne:SI (match_operand:SI 1 "register_operand" "r")
905 (clobber (reg:CC 0))]
907 "subcc %%g0,%1,%%g0\;subx %2,0,%0"
908 [(set_attr "length" "2")])
911 [(set (match_operand:SI 0 "register_operand" "=r")
912 (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
914 (match_operand:SI 2 "register_operand" "r")))
915 (clobber (reg:CC 0))]
917 "subcc %%g0,%1,%%g0\;subx %2,-1,%0"
918 [(set_attr "length" "2")])
921 [(set (match_operand:SI 0 "register_operand" "=r")
922 (minus:SI (match_operand:SI 2 "register_operand" "r")
923 (eq:SI (match_operand:SI 1 "register_operand" "r")
925 (clobber (reg:CC 0))]
927 "subcc %%g0,%1,%%g0\;addx %2,-1,%0"
928 [(set_attr "length" "2")])
930 ;; We can also do GEU and LTU directly, but these operate after a compare.
931 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
935 [(set (match_operand:SI 0 "register_operand" "=r")
936 (ltu:SI (reg:CC 0) (const_int 0)))]
939 [(set_attr "type" "misc")])
942 [(set (match_operand:SI 0 "register_operand" "=r")
943 (neg:SI (ltu:SI (reg:CC 0) (const_int 0))))]
946 [(set_attr "type" "misc")])
948 ;; ??? Combine should canonicalize these next two to the same pattern.
950 [(set (match_operand:SI 0 "register_operand" "=r")
951 (minus:SI (neg:SI (ltu:SI (reg:CC 0) (const_int 0)))
952 (match_operand:SI 1 "arith_operand" "rI")))]
955 [(set_attr "type" "unary")])
958 [(set (match_operand:SI 0 "register_operand" "=r")
959 (neg:SI (plus:SI (ltu:SI (reg:CC 0) (const_int 0))
960 (match_operand:SI 1 "arith_operand" "rI"))))]
963 [(set_attr "type" "unary")])
966 [(set (match_operand:SI 0 "register_operand" "=r")
967 (geu:SI (reg:CC 0) (const_int 0)))]
970 [(set_attr "type" "misc")])
973 [(set (match_operand:SI 0 "register_operand" "=r")
974 (neg:SI (geu:SI (reg:CC 0) (const_int 0))))]
977 [(set_attr "type" "misc")])
979 ;; We can also do (x + ((unsigned) i >= 0)) and related, so put them in.
980 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
984 [(set (match_operand:SI 0 "register_operand" "=r")
985 (plus:SI (ltu:SI (reg:CC 0) (const_int 0))
986 (match_operand:SI 1 "arith_operand" "rI")))]
989 [(set_attr "type" "unary")])
992 [(set (match_operand:SI 0 "register_operand" "=r")
993 (plus:SI (ltu:SI (reg:CC 0) (const_int 0))
994 (plus:SI (match_operand:SI 1 "arith_operand" "%r")
995 (match_operand:SI 2 "arith_operand" "rI"))))]
1000 [(set (match_operand:SI 0 "register_operand" "=r")
1001 (minus:SI (match_operand:SI 1 "register_operand" "r")
1002 (ltu:SI (reg:CC 0) (const_int 0))))]
1005 [(set_attr "type" "unary")])
1007 ;; ??? Combine should canonicalize these next two to the same pattern.
1009 [(set (match_operand:SI 0 "register_operand" "=r")
1010 (minus:SI (minus:SI (match_operand:SI 1 "register_operand" "r")
1011 (match_operand:SI 2 "arith_operand" "rI"))
1012 (ltu:SI (reg:CC 0) (const_int 0))))]
1017 [(set (match_operand:SI 0 "register_operand" "=r")
1018 (minus:SI (match_operand:SI 1 "register_operand" "r")
1019 (plus:SI (ltu:SI (reg:CC 0) (const_int 0))
1020 (match_operand:SI 2 "arith_operand" "rI"))))]
1025 [(set (match_operand:SI 0 "register_operand" "=r")
1026 (plus:SI (geu:SI (reg:CC 0) (const_int 0))
1027 (match_operand:SI 1 "register_operand" "r")))]
1030 [(set_attr "type" "unary")])
1033 [(set (match_operand:SI 0 "register_operand" "=r")
1034 (minus:SI (match_operand:SI 1 "register_operand" "r")
1035 (geu:SI (reg:CC 0) (const_int 0))))]
1038 [(set_attr "type" "unary")])
1040 ;; Now we have the generic scc insns.
1041 ;; !v9: These will be done using a jump.
1042 ;; v9: Use conditional moves which are defined elsewhere.
1043 ;; We have to exclude the cases above, since we will not want combine to
1044 ;; turn something that does not require a jump into something that does.
1047 [(set (match_operand:SI 0 "register_operand" "=r")
1048 (match_operator:SI 1 "noov_compare_op" [(reg 0) (const_int 0)]))]
1050 "* return output_scc_insn (operands, insn); "
1051 [(set_attr "type" "multi")
1052 (set_attr "length" "3")])
1055 [(set (match_operand:DI 0 "register_operand" "=r")
1056 (match_operator:DI 1 "noov_compare_op" [(reg 0) (const_int 0)]))]
1058 "* return output_scc_insn (operands, insn); "
1059 [(set_attr "type" "multi")
1060 (set_attr "length" "3")])
1062 ;; These control RTL generation for conditional jump insns
1064 ;; The quad-word fp compare library routines all return nonzero to indicate
1065 ;; true, which is different from the equivalent libgcc routines, so we must
1066 ;; handle them specially here.
1068 (define_expand "beq"
1070 (if_then_else (eq (match_dup 1) (const_int 0))
1071 (label_ref (match_operand 0 "" ""))
1076 if (TARGET_V9 && sparc_compare_op1 == const0_rtx
1077 && GET_CODE (sparc_compare_op0) == REG
1078 && GET_MODE (sparc_compare_op0) == DImode)
1080 emit_v9_brxx_insn (EQ, sparc_compare_op0, operands[0]);
1083 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1085 emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, EQ);
1086 emit_jump_insn (gen_bne (operands[0]));
1089 operands[1] = gen_compare_reg (EQ, sparc_compare_op0, sparc_compare_op1);
1092 (define_expand "bne"
1094 (if_then_else (ne (match_dup 1) (const_int 0))
1095 (label_ref (match_operand 0 "" ""))
1100 if (TARGET_V9 && sparc_compare_op1 == const0_rtx
1101 && GET_CODE (sparc_compare_op0) == REG
1102 && GET_MODE (sparc_compare_op0) == DImode)
1104 emit_v9_brxx_insn (NE, sparc_compare_op0, operands[0]);
1107 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1109 emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, NE);
1110 emit_jump_insn (gen_bne (operands[0]));
1113 operands[1] = gen_compare_reg (NE, sparc_compare_op0, sparc_compare_op1);
1116 (define_expand "bgt"
1118 (if_then_else (gt (match_dup 1) (const_int 0))
1119 (label_ref (match_operand 0 "" ""))
1124 if (TARGET_V9 && sparc_compare_op1 == const0_rtx
1125 && GET_CODE (sparc_compare_op0) == REG
1126 && GET_MODE (sparc_compare_op0) == DImode)
1128 emit_v9_brxx_insn (GT, sparc_compare_op0, operands[0]);
1131 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1133 emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GT);
1134 emit_jump_insn (gen_bne (operands[0]));
1137 operands[1] = gen_compare_reg (GT, sparc_compare_op0, sparc_compare_op1);
1140 (define_expand "bgtu"
1142 (if_then_else (gtu (match_dup 1) (const_int 0))
1143 (label_ref (match_operand 0 "" ""))
1147 { operands[1] = gen_compare_reg (GTU, sparc_compare_op0, sparc_compare_op1);
1150 (define_expand "blt"
1152 (if_then_else (lt (match_dup 1) (const_int 0))
1153 (label_ref (match_operand 0 "" ""))
1158 if (TARGET_V9 && sparc_compare_op1 == const0_rtx
1159 && GET_CODE (sparc_compare_op0) == REG
1160 && GET_MODE (sparc_compare_op0) == DImode)
1162 emit_v9_brxx_insn (LT, sparc_compare_op0, operands[0]);
1165 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1167 emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LT);
1168 emit_jump_insn (gen_bne (operands[0]));
1171 operands[1] = gen_compare_reg (LT, sparc_compare_op0, sparc_compare_op1);
1174 (define_expand "bltu"
1176 (if_then_else (ltu (match_dup 1) (const_int 0))
1177 (label_ref (match_operand 0 "" ""))
1181 { operands[1] = gen_compare_reg (LTU, sparc_compare_op0, sparc_compare_op1);
1184 (define_expand "bge"
1186 (if_then_else (ge (match_dup 1) (const_int 0))
1187 (label_ref (match_operand 0 "" ""))
1192 if (TARGET_V9 && sparc_compare_op1 == const0_rtx
1193 && GET_CODE (sparc_compare_op0) == REG
1194 && GET_MODE (sparc_compare_op0) == DImode)
1196 emit_v9_brxx_insn (GE, sparc_compare_op0, operands[0]);
1199 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1201 emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GE);
1202 emit_jump_insn (gen_bne (operands[0]));
1205 operands[1] = gen_compare_reg (GE, sparc_compare_op0, sparc_compare_op1);
1208 (define_expand "bgeu"
1210 (if_then_else (geu (match_dup 1) (const_int 0))
1211 (label_ref (match_operand 0 "" ""))
1215 { operands[1] = gen_compare_reg (GEU, sparc_compare_op0, sparc_compare_op1);
1218 (define_expand "ble"
1220 (if_then_else (le (match_dup 1) (const_int 0))
1221 (label_ref (match_operand 0 "" ""))
1226 if (TARGET_V9 && sparc_compare_op1 == const0_rtx
1227 && GET_CODE (sparc_compare_op0) == REG
1228 && GET_MODE (sparc_compare_op0) == DImode)
1230 emit_v9_brxx_insn (LE, sparc_compare_op0, operands[0]);
1233 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1235 emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LE);
1236 emit_jump_insn (gen_bne (operands[0]));
1239 operands[1] = gen_compare_reg (LE, sparc_compare_op0, sparc_compare_op1);
1242 (define_expand "bleu"
1244 (if_then_else (leu (match_dup 1) (const_int 0))
1245 (label_ref (match_operand 0 "" ""))
1249 { operands[1] = gen_compare_reg (LEU, sparc_compare_op0, sparc_compare_op1);
1252 ;; Now match both normal and inverted jump.
1256 (if_then_else (match_operator 0 "noov_compare_op"
1257 [(reg 0) (const_int 0)])
1258 (label_ref (match_operand 1 "" ""))
1263 return output_cbranch (operands[0], 0, 1, 0,
1264 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1267 [(set_attr "type" "branch")])
1271 (if_then_else (match_operator 0 "noov_compare_op"
1272 [(reg 0) (const_int 0)])
1274 (label_ref (match_operand 1 "" ""))))]
1278 return output_cbranch (operands[0], 0, 1, 1,
1279 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1282 [(set_attr "type" "branch")])
1286 (if_then_else (match_operator 0 "comparison_operator"
1287 [(match_operand:CCFP 1 "ccfp_reg_operand" "c")
1289 (label_ref (match_operand 2 "" ""))
1294 return output_cbranch (operands[0], operands[1], 2, 0,
1295 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1298 [(set_attr "type" "branch")])
1302 (if_then_else (match_operator 0 "comparison_operator"
1303 [(match_operand:CCFP 1 "ccfp_reg_operand" "c")
1306 (label_ref (match_operand 2 "" ""))))]
1310 return output_cbranch (operands[0], operands[1], 2, 1,
1311 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1314 [(set_attr "type" "branch")])
1318 (if_then_else (match_operator 0 "comparison_operator"
1319 [(match_operand:CCFPE 1 "ccfp_reg_operand" "c")
1321 (label_ref (match_operand 2 "" ""))
1326 return output_cbranch (operands[0], operands[1], 2, 0,
1327 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1330 [(set_attr "type" "branch")])
1334 (if_then_else (match_operator 0 "comparison_operator"
1335 [(match_operand:CCFPE 1 "ccfp_reg_operand" "c")
1338 (label_ref (match_operand 2 "" ""))))]
1342 return output_cbranch (operands[0], operands[1], 2, 1,
1343 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1346 [(set_attr "type" "branch")])
1348 ;; Sparc V9-specific jump insns. None of these are guaranteed to be
1349 ;; in the architecture.
1351 ;; There are no 32 bit brreg insns.
1355 (if_then_else (match_operator 0 "v9_regcmp_op"
1356 [(match_operand:DI 1 "register_operand" "r")
1358 (label_ref (match_operand 2 "" ""))
1363 return output_v9branch (operands[0], 1, 2, 0,
1364 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1367 [(set_attr "type" "branch")])
1371 (if_then_else (match_operator 0 "v9_regcmp_op"
1372 [(match_operand:DI 1 "register_operand" "r")
1375 (label_ref (match_operand 2 "" ""))))]
1379 return output_v9branch (operands[0], 1, 2, 1,
1380 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1383 [(set_attr "type" "branch")])
1385 ;; Esoteric move insns (lo_sum, high, pic).
1388 [(set (match_operand:SI 0 "register_operand" "=r")
1389 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1390 (match_operand:SI 2 "immediate_operand" "in")))]
1392 ;; V9 needs "add" because of the code models. We still use "or" for v8
1393 ;; so we can compare the old compiler with the new.
1394 "* return TARGET_V9 ? \"add %1,%%lo(%a2),%0\" : \"or %1,%%lo(%a2),%0\";"
1395 ;; Need to set length for this arith insn because operand2
1396 ;; is not an "arith_operand".
1397 [(set_attr "length" "1")])
1399 ;; For PIC, symbol_refs are put inside unspec so that the optimizer will not
1400 ;; confuse them with real addresses.
1402 [(set (match_operand:SI 0 "register_operand" "=r")
1403 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1404 (unspec:SI [(match_operand:SI 2 "immediate_operand" "in")] 0)))]
1406 ;; V9 needs "add" because of the code models. We still use "or" for v8
1407 ;; so we can compare the old compiler with the new.
1408 "* return TARGET_V9 ? \"add %1,%%lo(%a2),%0\" : \"or %1,%%lo(%a2),%0\";"
1409 ;; Need to set length for this arith insn because operand2
1410 ;; is not an "arith_operand".
1411 [(set_attr "length" "1")])
1413 ;; For PIC, symbol_refs are put inside unspec so that the optimizer will not
1414 ;; confuse them with real addresses.
1416 [(set (match_operand:SI 0 "register_operand" "=r")
1417 (high:SI (unspec:SI [(match_operand 1 "" "")] 0)))]
1419 "sethi %%hi(%a1),%0"
1420 [(set_attr "type" "move")
1421 (set_attr "length" "1")])
1424 [(set (match_operand:SI 0 "register_operand" "=r")
1425 (high:SI (match_operand 1 "" "")))]
1427 "sethi %%hi(%a1),%0"
1428 [(set_attr "type" "move")
1429 (set_attr "length" "1")])
1432 [(set (match_operand:HI 0 "register_operand" "=r")
1433 (high:HI (match_operand 1 "" "")))]
1435 "sethi %%hi(%a1),%0"
1436 [(set_attr "type" "move")
1437 (set_attr "length" "1")])
1439 ;; Special pic pattern, for loading the address of a label into a register.
1440 ;; It clobbers o7 because the call puts the return address (i.e. pc value)
1444 [(set (match_operand:SI 0 "register_operand" "=r")
1445 (match_operand:SI 1 "move_pic_label" "i"))
1446 (set (reg:SI 15) (pc))]
1448 "\\n1:\;call 2f\;sethi %%hi(%l1-1b),%0\\n2:\\tor %0,%%lo(%l1-1b),%0\;add %0,%%o7,%0"
1449 [(set_attr "type" "multi")
1450 (set_attr "length" "4")])
1452 ;; v9 special pic pattern, for loading the address of a label into a register.
1455 [(set (match_operand:DI 0 "register_operand" "=r")
1456 (match_operand:DI 1 "move_pic_label" "i"))
1457 (set (reg:DI 15) (pc))]
1459 "\\n1:\;call 2f\;sethi %%hi(%l1-1b),%0\\n2:\\tor %0,%%lo(%l1-1b),%0\;add %0,%%o7,%0"
1460 [(set_attr "type" "multi")
1461 (set_attr "length" "4")])
1464 [(set (match_operand:DI 0 "register_operand" "=r")
1465 (lo_sum:DI (match_operand:DI 1 "register_operand" "0")
1466 (match_operand:DI 2 "immediate_operand" "in")))]
1470 /* Don't output a 64 bit constant, since we can't trust the assembler to
1471 handle it correctly. */
1472 if (GET_CODE (operands[2]) == CONST_DOUBLE)
1473 operands[2] = gen_rtx (CONST_INT, VOIDmode, CONST_DOUBLE_LOW (operands[2]));
1474 return \"or %R1,%%lo(%a2),%R0\";
1476 ;; Need to set length for this arith insn because operand2
1477 ;; is not an "arith_operand".
1478 [(set_attr "length" "1")])
1480 ;; ??? Gas does not handle %lo(DI), so we use the same code for ! TARGET_V9.
1481 ;; ??? The previous comment is obsolete.
1482 ;; ??? Optimizer does not handle "or %o1,%lo(0),%o1". How about add?
1485 [(set (match_operand:DI 0 "register_operand" "=r")
1486 (lo_sum:DI (match_operand:DI 1 "register_operand" "0")
1487 (match_operand:DI 2 "immediate_operand" "in")))]
1491 /* Don't output a 64 bit constant, since we can't trust the assembler to
1492 handle it correctly. */
1493 if (GET_CODE (operands[2]) == CONST_DOUBLE)
1494 operands[2] = gen_rtx (CONST_INT, VOIDmode, CONST_DOUBLE_LOW (operands[2]));
1495 /* Note that we use add here. This is important because Medium/Anywhere
1496 code model support depends on it. */
1497 return \"add %1,%%lo(%a2),%0\";
1499 ;; Need to set length for this arith insn because operand2
1500 ;; is not an "arith_operand".
1501 [(set_attr "length" "1")])
1504 [(set (match_operand:DI 0 "register_operand" "=r")
1505 (high:DI (match_operand 1 "" "")))]
1506 "! TARGET_V9 && check_pic (1)"
1509 rtx op0 = operands[0];
1510 rtx op1 = operands[1];
1512 if (GET_CODE (op1) == CONST_INT)
1514 operands[0] = operand_subword (op0, 1, 0, DImode);
1515 output_asm_insn (\"sethi %%hi(%a1),%0\", operands);
1517 operands[0] = operand_subword (op0, 0, 0, DImode);
1518 if (INTVAL (op1) < 0)
1519 return \"mov -1,%0\";
1521 return \"mov 0,%0\";
1523 else if (GET_CODE (op1) == CONST_DOUBLE)
1525 operands[0] = operand_subword (op0, 1, 0, DImode);
1526 operands[1] = gen_rtx (CONST_INT, VOIDmode, CONST_DOUBLE_LOW (op1));
1527 output_asm_insn (\"sethi %%hi(%a1),%0\", operands);
1529 operands[0] = operand_subword (op0, 0, 0, DImode);
1530 operands[1] = gen_rtx (CONST_INT, VOIDmode, CONST_DOUBLE_HIGH (op1));
1531 return singlemove_string (operands);
1537 [(set_attr "type" "move")
1538 (set_attr "length" "2")])
1540 ;;; ??? This pattern originally clobbered a scratch register. However, this
1541 ;;; is invalid, the movdi pattern may not use a temp register because it
1542 ;;; may be called from reload to reload a DImode value. In that case, we
1543 ;;; end up with a scratch register that never gets allocated. To avoid this,
1544 ;;; we use global register 1 which is never otherwise used by gcc as a temp.
1545 ;;; The correct solution here might be to force DImode constants to memory,
1546 ;;; e.g. by using a toc like the romp and rs6000 ports do for addresses, reg
1547 ;;; 1 will then no longer need to be considered a fixed reg.
1549 ;;; Gas doesn't have any 64 bit constant support, so don't use %uhi and %ulo
1550 ;;; on constants. Symbols have to be handled by the linker, so we must use
1551 ;;; %uhi and %ulo for them, but gas will handle these correctly.
1552 ;;; ??? This comment is obsolete, gas handles them now.
1555 [(set (match_operand:DI 0 "register_operand" "=r")
1556 (high:DI (match_operand 1 "const_double_operand" "")))
1557 (clobber (reg:DI 1))]
1558 "TARGET_V9 && check_pic (1)"
1563 split_double (operands[1], &high, &low);
1565 if (high == const0_rtx)
1568 output_asm_insn (\"sethi %%hi(%a1),%0\", operands);
1573 output_asm_insn (singlemove_string (operands), operands);
1576 output_asm_insn (\"sllx %0,32,%0\", operands);
1577 if (low != const0_rtx)
1578 output_asm_insn (\"sethi %%hi(%a1),%%g1; or %0,%%g1,%0\", operands);
1581 [(set_attr "type" "move")
1582 (set_attr "length" "5")])
1584 ;; Most of the required support for the various code models is here.
1585 ;; We can do this because sparcs need the high insn to load the address. We
1586 ;; just need to get high to do the right thing for each code model. Then each
1587 ;; uses the same "%X+%lo(...)" in the load/store insn.
1589 ;; When TARGET_MEDLOW, assume that the upper 32 bits of symbol addresses are
1591 ;; When TARGET_MEDANY, the upper 32 bits of function addresses are 0.
1592 ;; The data segment has a maximum size of 32 bits, but may be located anywhere.
1593 ;; MEDANY_BASE_REG contains the start address, currently %g4.
1594 ;; When TARGET_FULLANY, symbolic addresses are 64 bits.
1597 [(set (match_operand:DI 0 "register_operand" "=r")
1598 (high:DI (match_operand 1 "" "")))
1599 ;; ??? Why the clobber?
1600 (clobber (reg:DI 1))]
1601 "TARGET_MEDLOW && check_pic (1)"
1602 "sethi %%hi(%a1),%0"
1603 [(set_attr "type" "move")
1604 (set_attr "length" "1")])
1606 ;; WARNING: %0 gets %hi(%1)+%g4.
1607 ;; You cannot OR in %lo(%1), it must be added in.
1610 [(set (match_operand:DI 0 "register_operand" "=r")
1611 (high:DI (match_operand 1 "data_segment_operand" "")))
1612 ;; ??? Why the clobber?
1613 (clobber (reg:DI 1))]
1614 "TARGET_MEDANY && check_pic (1)"
1615 "sethi %%hi(%a1),%0; add %0,%%g4,%0"
1616 [(set_attr "type" "move")
1617 (set_attr "length" "2")])
1620 [(set (match_operand:DI 0 "register_operand" "=r")
1621 (high:DI (match_operand 1 "text_segment_operand" "")))
1622 ;; ??? Why the clobber?
1623 (clobber (reg:DI 1))]
1624 "TARGET_MEDANY && check_pic (1)"
1625 "sethi %%hi(%a1),%0"
1626 [(set_attr "type" "move")
1627 (set_attr "length" "1")])
1630 [(set (match_operand:DI 0 "register_operand" "=r")
1631 (high:DI (match_operand 1 "" "")))
1632 (clobber (reg:DI 1))]
1633 "TARGET_FULLANY && check_pic (1)"
1634 "sethi %%uhi(%a1),%%g1; or %%g1,%%ulo(%a1),%%g1; sllx %%g1,32,%%g1; sethi %%hi(%a1),%0; or %0,%%g1,%0"
1635 [(set_attr "type" "move")
1636 (set_attr "length" "5")])
1638 ;; Move instructions
1640 (define_expand "movqi"
1641 [(set (match_operand:QI 0 "general_operand" "")
1642 (match_operand:QI 1 "general_operand" ""))]
1646 if (emit_move_sequence (operands, QImode))
1651 [(set (match_operand:QI 0 "reg_or_nonsymb_mem_operand" "=r,r,r,Q")
1652 (match_operand:QI 1 "move_operand" "rI,K,Q,rJ"))]
1653 "register_operand (operands[0], QImode)
1654 || register_operand (operands[1], QImode)
1655 || operands[1] == const0_rtx"
1661 [(set_attr "type" "move,move,load,store")
1662 (set_attr "length" "*,1,*,1")])
1665 [(set (match_operand:QI 0 "register_operand" "=r")
1666 (subreg:QI (lo_sum:SI (match_operand:QI 1 "register_operand" "r")
1667 (match_operand 2 "immediate_operand" "in")) 0))]
1669 "or %1,%%lo(%a2),%0"
1670 [(set_attr "length" "1")])
1673 [(set (mem:QI (match_operand:SI 0 "symbolic_operand" ""))
1674 (match_operand:QI 1 "reg_or_0_operand" "rJ"))
1675 (clobber (match_scratch:SI 2 "=&r"))]
1676 "(reload_completed || reload_in_progress) && ! TARGET_PTR64"
1677 "sethi %%hi(%a0),%2\;stb %r1,[%2+%%lo(%a0)]"
1678 [(set_attr "type" "store")
1679 (set_attr "length" "2")])
1681 (define_expand "movhi"
1682 [(set (match_operand:HI 0 "general_operand" "")
1683 (match_operand:HI 1 "general_operand" ""))]
1687 if (emit_move_sequence (operands, HImode))
1692 [(set (match_operand:HI 0 "reg_or_nonsymb_mem_operand" "=r,r,r,Q")
1693 (match_operand:HI 1 "move_operand" "rI,K,Q,rJ"))]
1694 "register_operand (operands[0], HImode)
1695 || register_operand (operands[1], HImode)
1696 || operands[1] == const0_rtx"
1702 [(set_attr "type" "move,move,load,store")
1703 (set_attr "length" "*,1,*,1")])
1706 [(set (match_operand:HI 0 "register_operand" "=r")
1707 (lo_sum:HI (match_operand:HI 1 "register_operand" "r")
1708 (match_operand 2 "immediate_operand" "in")))]
1710 "or %1,%%lo(%a2),%0"
1711 [(set_attr "length" "1")])
1714 [(set (mem:HI (match_operand:SI 0 "symbolic_operand" ""))
1715 (match_operand:HI 1 "reg_or_0_operand" "rJ"))
1716 (clobber (match_scratch:SI 2 "=&r"))]
1717 "(reload_completed || reload_in_progress) && ! TARGET_PTR64"
1718 "sethi %%hi(%a0),%2\;sth %r1,[%2+%%lo(%a0)]"
1719 [(set_attr "type" "store")
1720 (set_attr "length" "2")])
1722 (define_expand "movsi"
1723 [(set (match_operand:SI 0 "general_operand" "")
1724 (match_operand:SI 1 "general_operand" ""))]
1728 if (emit_move_sequence (operands, SImode))
1732 ;; We must support both 'r' and 'f' registers here, because combine may
1733 ;; convert SFmode hard registers to SImode hard registers when simplifying
1736 ;; We cannot combine the similar 'r' and 'f' constraints, because it causes
1737 ;; problems with register allocation. Reload might try to put an integer
1738 ;; in an fp register, or an fp number is an integer register.
1741 [(set (match_operand:SI 0 "reg_or_nonsymb_mem_operand" "=r,f,r,r,f,Q,Q")
1742 (match_operand:SI 1 "move_operand" "rI,!f,K,Q,!Q,rJ,!f"))]
1743 "register_operand (operands[0], SImode)
1744 || register_operand (operands[1], SImode)
1745 || operands[1] == const0_rtx"
1754 [(set_attr "type" "move,fp,move,load,load,store,store")
1755 (set_attr "length" "*,*,1,*,*,*,*")])
1758 [(set (mem:SI (match_operand:SI 0 "symbolic_operand" ""))
1759 (match_operand:SI 1 "reg_or_0_operand" "rJ"))
1760 (clobber (match_scratch:SI 2 "=&r"))]
1761 "(reload_completed || reload_in_progress) && ! TARGET_PTR64"
1762 "sethi %%hi(%a0),%2\;st %r1,[%2+%%lo(%a0)]"
1763 [(set_attr "type" "store")
1764 (set_attr "length" "2")])
1766 (define_expand "movdi"
1767 [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand" "")
1768 (match_operand:DI 1 "general_operand" ""))]
1772 if (emit_move_sequence (operands, DImode))
1777 [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand" "=r,T,U,Q,r,r,?f,?f,?Q")
1778 (match_operand:DI 1 "general_operand" "r,U,T,r,Q,i,f,Q,f"))]
1780 && (register_operand (operands[0], DImode)
1781 || register_operand (operands[1], DImode)
1782 || operands[1] == const0_rtx)"
1785 if (FP_REG_P (operands[0]) || FP_REG_P (operands[1]))
1786 return output_fp_move_double (operands);
1787 return output_move_double (operands);
1789 [(set_attr "type" "move,store,load,store,load,multi,fp,fpload,fpstore")
1790 (set_attr "length" "2,1,1,3,3,3,2,3,3")])
1792 ;;; ??? The trick used below can be extended to load any negative 32 bit
1793 ;;; constant in two instructions. Currently the compiler will use HIGH/LO_SUM
1794 ;;; for anything not matching the HIK constraints, which results in 5
1795 ;;; instructions. Positive 32 bit constants can be loaded in the obvious way
1796 ;;; with sethi/ori. To extend the trick, in the xor instruction, use
1797 ;;; xor %o0, ((op1 & 0x3ff) | -0x400), %o0
1798 ;;; This needs the original value of operands[1], not the inverted value.
1801 [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand" "=r,r,r,Q,?f,?f,?Q")
1802 (match_operand:DI 1 "move_operand" "rI,K,Q,rJ,f,Q,f"))]
1804 && (register_operand (operands[0], DImode)
1805 || register_operand (operands[1], DImode)
1806 || operands[1] == const0_rtx)"
1809 switch (which_alternative)
1812 return \"mov %1,%0\";
1814 /* Sethi does not sign extend, so we must use a little trickery
1815 to use it for negative numbers. Invert the constant before
1816 loading it in, then use a xor immediate to invert the loaded bits
1817 (along with the upper 32 bits) to the desired constant. This
1818 works because the sethi and immediate fields overlap. */
1820 if ((INTVAL (operands[1]) & 0x80000000) == 0)
1821 return \"sethi %%hi(%a1),%0\";
1824 operands[1] = gen_rtx (CONST_INT, VOIDmode,
1825 ~ INTVAL (operands[1]));
1826 output_asm_insn (\"sethi %%hi(%a1),%0\", operands);
1827 /* The low 10 bits are already zero, but invert the rest.
1828 Assemblers don't accept 0x1c00, so use -0x400 instead. */
1829 return \"xor %0,-0x400,%0\";
1832 return \"ldx %1,%0\";
1834 return \"stx %r1,%0\";
1836 return \"mov %1,%0\";
1838 return \"ldd %1,%0\";
1840 return \"std %1,%0\";
1843 [(set_attr "type" "move,move,load,store,fp,fpload,fpstore")
1844 (set_attr "length" "1,2,1,1,1,1,1")])
1846 ;; ??? There's no symbolic (set (mem:DI ...) ...).
1847 ;; Experimentation with v9 suggested one isn't needed.
1849 ;; Block move insns.
1851 ;; ??? We get better code without it. See output_block_move in sparc.c.
1853 ;; The definition of this insn does not really explain what it does,
1854 ;; but it should suffice
1855 ;; that anything generated as this insn will be recognized as one
1856 ;; and that it will not successfully combine with anything.
1857 ;(define_expand "movstrsi"
1858 ; [(parallel [(set (mem:BLK (match_operand:BLK 0 "general_operand" ""))
1859 ; (mem:BLK (match_operand:BLK 1 "general_operand" "")))
1860 ; (use (match_operand:SI 2 "nonmemory_operand" ""))
1861 ; (use (match_operand:SI 3 "immediate_operand" ""))
1862 ; (clobber (match_dup 0))
1863 ; (clobber (match_dup 1))
1864 ; (clobber (match_scratch:SI 4 ""))
1865 ; (clobber (reg:SI 0))
1866 ; (clobber (reg:SI 1))])]
1870 ; /* If the size isn't known, don't emit inline code. output_block_move
1871 ; would output code that's much slower than the library function.
1872 ; Also don't output code for large blocks. */
1873 ; if (GET_CODE (operands[2]) != CONST_INT
1874 ; || GET_CODE (operands[3]) != CONST_INT
1875 ; || INTVAL (operands[2]) / INTVAL (operands[3]) > 16)
1878 ; operands[0] = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
1879 ; operands[1] = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
1880 ; operands[2] = force_not_mem (operands[2]);
1884 ; [(set (mem:BLK (match_operand:SI 0 "register_operand" "+r"))
1885 ; (mem:BLK (match_operand:SI 1 "register_operand" "+r")))
1886 ; (use (match_operand:SI 2 "nonmemory_operand" "rn"))
1887 ; (use (match_operand:SI 3 "immediate_operand" "i"))
1888 ; (clobber (match_dup 0))
1889 ; (clobber (match_dup 1))
1890 ; (clobber (match_scratch:SI 4 "=&r"))
1891 ; (clobber (reg:SI 0))
1892 ; (clobber (reg:SI 1))]
1894 ; "* return output_block_move (operands);"
1895 ; [(set_attr "type" "multi")
1896 ; (set_attr "length" "6")])
1898 ;; Floating point move insns
1900 ;; This pattern forces (set (reg:SF ...) (const_double ...))
1901 ;; to be reloaded by putting the constant into memory.
1902 ;; It must come before the more general movsf pattern.
1904 [(set (match_operand:SF 0 "general_operand" "=?r,f,m")
1905 (match_operand:SF 1 "" "?F,m,G"))]
1906 "TARGET_FPU && GET_CODE (operands[1]) == CONST_DOUBLE"
1909 switch (which_alternative)
1912 return singlemove_string (operands);
1914 return \"ld %1,%0\";
1916 return \"st %%g0,%0\";
1919 [(set_attr "type" "load,fpload,store")
1920 (set_attr "length" "2,1,1")])
1922 (define_expand "movsf"
1923 [(set (match_operand:SF 0 "general_operand" "")
1924 (match_operand:SF 1 "general_operand" ""))]
1928 if (emit_move_sequence (operands, SFmode))
1933 [(set (match_operand:SF 0 "reg_or_nonsymb_mem_operand" "=f,r,f,r,Q,Q")
1934 (match_operand:SF 1 "reg_or_nonsymb_mem_operand" "f,r,Q,Q,f,r"))]
1936 && (register_operand (operands[0], SFmode)
1937 || register_operand (operands[1], SFmode))"
1945 [(set_attr "type" "fp,move,fpload,load,fpstore,store")])
1947 ;; Exactly the same as above, except that all `f' cases are deleted.
1948 ;; This is necessary to prevent reload from ever trying to use a `f' reg
1952 [(set (match_operand:SF 0 "reg_or_nonsymb_mem_operand" "=r,r,Q")
1953 (match_operand:SF 1 "reg_or_nonsymb_mem_operand" "r,Q,r"))]
1955 && (register_operand (operands[0], SFmode)
1956 || register_operand (operands[1], SFmode))"
1961 [(set_attr "type" "move,load,store")])
1964 [(set (mem:SF (match_operand:SI 0 "symbolic_operand" "i"))
1965 (match_operand:SF 1 "reg_or_0_operand" "rfG"))
1966 (clobber (match_scratch:SI 2 "=&r"))]
1967 "(reload_completed || reload_in_progress) && ! TARGET_PTR64"
1968 "sethi %%hi(%a0),%2\;st %r1,[%2+%%lo(%a0)]"
1969 [(set_attr "type" "store")
1970 (set_attr "length" "2")])
1972 ;; This pattern forces (set (reg:DF ...) (const_double ...))
1973 ;; to be reloaded by putting the constant into memory.
1974 ;; It must come before the more general movdf pattern.
1977 [(set (match_operand:DF 0 "general_operand" "=?r,e,o")
1978 (match_operand:DF 1 "" "?F,m,G"))]
1979 "TARGET_FPU && GET_CODE (operands[1]) == CONST_DOUBLE"
1982 switch (which_alternative)
1985 return output_move_double (operands);
1987 return output_fp_move_double (operands);
1991 return \"stx %%g0,%0\";
1995 operands[1] = adj_offsettable_operand (operands[0], 4);
1996 return \"st %%g0,%0\;st %%g0,%1\";
2000 [(set_attr "type" "load,fpload,store")
2001 (set_attr "length" "3,3,3")])
2003 (define_expand "movdf"
2004 [(set (match_operand:DF 0 "general_operand" "")
2005 (match_operand:DF 1 "general_operand" ""))]
2009 if (emit_move_sequence (operands, DFmode))
2014 [(set (match_operand:DF 0 "reg_or_nonsymb_mem_operand" "=T,U,e,r,Q,Q,e,r")
2015 (match_operand:DF 1 "reg_or_nonsymb_mem_operand" "U,T,e,r,e,r,Q,Q"))]
2017 && (register_operand (operands[0], DFmode)
2018 || register_operand (operands[1], DFmode))"
2021 if (FP_REG_P (operands[0]) || FP_REG_P (operands[1]))
2022 return output_fp_move_double (operands);
2023 return output_move_double (operands);
2025 [(set_attr "type" "fpstore,fpload,fp,move,fpstore,store,fpload,load")
2026 (set_attr "length" "1,1,2,2,3,3,3,3")])
2028 ;; Exactly the same as above, except that all `e' cases are deleted.
2029 ;; This is necessary to prevent reload from ever trying to use a `e' reg
2033 [(set (match_operand:DF 0 "reg_or_nonsymb_mem_operand" "=T,U,r,Q,&r")
2034 (match_operand:DF 1 "reg_or_nonsymb_mem_operand" "U,T,r,r,Q"))]
2036 && (register_operand (operands[0], DFmode)
2037 || register_operand (operands[1], DFmode))"
2038 "* return output_move_double (operands);"
2039 [(set_attr "type" "store,load,move,store,load")
2040 (set_attr "length" "1,1,2,3,3")])
2042 ;; Must handle overlapping registers here, since parameters can be unaligned
2044 ;; ??? Do we need a v9 version of this?
2046 [(set (match_operand:DF 0 "register_operand" "")
2047 (match_operand:DF 1 "register_operand" ""))]
2048 "! TARGET_V9 && reload_completed"
2049 [(set (match_dup 2) (match_dup 3))
2050 (set (match_dup 4) (match_dup 5))]
2053 rtx first_set = operand_subword (operands[0], 0, 0, DFmode);
2054 rtx second_use = operand_subword (operands[1], 1, 0, DFmode);
2056 if (REGNO (first_set) == REGNO (second_use))
2058 operands[2] = operand_subword (operands[0], 1, 0, DFmode);
2059 operands[3] = second_use;
2060 operands[4] = first_set;
2061 operands[5] = operand_subword (operands[1], 0, 0, DFmode);
2065 operands[2] = first_set;
2066 operands[3] = operand_subword (operands[1], 0, 0, DFmode);
2067 operands[4] = operand_subword (operands[0], 1, 0, DFmode);
2068 operands[5] = second_use;
2073 [(set (mem:DF (match_operand:SI 0 "symbolic_operand" "i,i"))
2074 (match_operand:DF 1 "reg_or_0_operand" "re,G"))
2075 (clobber (match_scratch:SI 2 "=&r,&r"))]
2076 "(reload_completed || reload_in_progress) && ! TARGET_PTR64"
2079 output_asm_insn (\"sethi %%hi(%a0),%2\", operands);
2080 if (which_alternative == 0)
2081 return \"std %1,[%2+%%lo(%a0)]\";
2083 return \"st %%g0,[%2+%%lo(%a0)]\;st %%g0,[%2+%%lo(%a0+4)]\";
2085 [(set_attr "type" "store")
2086 (set_attr "length" "3")])
2088 ;; This pattern forces (set (reg:TF ...) (const_double ...))
2089 ;; to be reloaded by putting the constant into memory.
2090 ;; It must come before the more general movtf pattern.
2092 [(set (match_operand:TF 0 "general_operand" "=?r,e,o")
2093 (match_operand:TF 1 "" "?F,m,G"))]
2094 "TARGET_FPU && GET_CODE (operands[1]) == CONST_DOUBLE"
2097 switch (which_alternative)
2100 return output_move_quad (operands);
2102 return output_fp_move_quad (operands);
2106 operands[1] = adj_offsettable_operand (operands[0], 8);
2107 return \"stx %%g0,%0\;stx %%g0,%1\";
2111 /* ??? Do we run off the end of the array here? */
2112 operands[1] = adj_offsettable_operand (operands[0], 4);
2113 operands[2] = adj_offsettable_operand (operands[0], 8);
2114 operands[3] = adj_offsettable_operand (operands[0], 12);
2115 return \"st %%g0,%0\;st %%g0,%1\;st %%g0,%2\;st %%g0,%3\";
2119 [(set_attr "type" "load,fpload,store")
2120 (set_attr "length" "5,5,5")])
2122 (define_expand "movtf"
2123 [(set (match_operand:TF 0 "general_operand" "")
2124 (match_operand:TF 1 "general_operand" ""))]
2128 if (emit_move_sequence (operands, TFmode))
2133 [(set (match_operand:TF 0 "reg_or_nonsymb_mem_operand" "=e,r,Q,Q,e,&r")
2134 (match_operand:TF 1 "reg_or_nonsymb_mem_operand" "e,r,e,r,Q,Q"))]
2136 && (register_operand (operands[0], TFmode)
2137 || register_operand (operands[1], TFmode))"
2140 if (FP_REG_P (operands[0]) || FP_REG_P (operands[1]))
2141 return output_fp_move_quad (operands);
2142 return output_move_quad (operands);
2144 [(set_attr "type" "fp,move,fpstore,store,fpload,load")
2145 (set_attr "length" "4,4,5,5,5,5")])
2147 ;; Exactly the same as above, except that all `e' cases are deleted.
2148 ;; This is necessary to prevent reload from ever trying to use a `e' reg
2152 [(set (match_operand:TF 0 "reg_or_nonsymb_mem_operand" "=r,Q,&r")
2153 (match_operand:TF 1 "reg_or_nonsymb_mem_operand" "r,r,Q"))]
2155 && (register_operand (operands[0], TFmode)
2156 || register_operand (operands[1], TFmode))"
2159 if (FP_REG_P (operands[0]) || FP_REG_P (operands[1]))
2160 return output_fp_move_quad (operands);
2161 return output_move_quad (operands);
2163 [(set_attr "type" "move,store,load")
2164 (set_attr "length" "4,5,5")])
2166 ;; This is disabled because it does not work. Long doubles have only 8
2167 ;; byte alignment. Adding an offset of 8 or 12 to an 8 byte aligned %lo may
2168 ;; cause it to overflow. See also GO_IF_LEGITIMATE_ADDRESS.
2170 [(set (mem:TF (match_operand:SI 0 "symbolic_operand" "i,i"))
2171 (match_operand:TF 1 "reg_or_0_operand" "re,G"))
2172 (clobber (match_scratch:SI 2 "=&r,&r"))]
2173 "0 && (reload_completed || reload_in_progress) && ! TARGET_PTR64"
2176 output_asm_insn (\"sethi %%hi(%a0),%2\", operands);
2177 if (which_alternative == 0)
2178 return \"std %1,[%2+%%lo(%a0)]\;std %S1,[%2+%%lo(%a0+8)]\";
2180 return \"st %%g0,[%2+%%lo(%a0)]\;st %%g0,[%2+%%lo(%a0+4)]\; st %%g0,[%2+%%lo(%a0+8)]\;st %%g0,[%2+%%lo(%a0+12)]\";
2182 [(set_attr "type" "store")
2183 (set_attr "length" "5")])
2185 ;; Sparc V9 conditional move instructions.
2187 ; ??? There is not actually a 32 bit version of this instruction.
2189 [(set (match_operand:SI 0 "register_operand" "=r")
2190 (if_then_else (match_operator 1 "comparison_operator"
2191 [(reg:CC 0) (const_int 0)])
2192 (match_operand:SI 2 "arith11_operand" "ri")
2193 (match_operand:SI 3 "register_operand" "0")))]
2195 "mov%C1 %%icc,%2,%0"
2196 [(set_attr "type" "cmove")])
2199 [(set (match_operand:DI 0 "register_operand" "=r")
2200 (if_then_else (match_operator 1 "comparison_operator"
2201 [(reg:CC 0) (const_int 0)])
2202 (match_operand:DI 2 "arith11_double_operand" "rHI")
2203 (match_operand:DI 3 "register_operand" "0")))]
2205 "mov%C1 %%icc,%2,%0"
2206 [(set_attr "type" "cmove")])
2208 ;; ??? There is not actually a 32 bit version of this instruction.
2210 [(set (match_operand:SI 0 "register_operand" "=r")
2211 (if_then_else (match_operator 1 "comparison_operator"
2212 [(reg:CCX 0) (const_int 0)])
2213 (match_operand:SI 2 "arith11_operand" "ri")
2214 (match_operand:SI 3 "register_operand" "0")))]
2216 "mov%C1 %%xcc,%2,%0"
2217 [(set_attr "type" "cmove")])
2220 [(set (match_operand:DI 0 "register_operand" "=r")
2221 (if_then_else (match_operator 1 "comparison_operator"
2222 [(reg:CCX 0) (const_int 0)])
2223 (match_operand:DI 2 "arith11_double_operand" "rHI")
2224 (match_operand:DI 3 "register_operand" "0")))]
2226 "mov%C1 %%xcc,%2,%0"
2227 [(set_attr "type" "cmove")])
2229 ;; ??? There is not actually a 32 bit version of this instruction.
2231 [(set (match_operand:SI 0 "register_operand" "=r")
2232 (if_then_else (match_operator 1 "comparison_operator"
2233 [(match_operand:CCFP 2 "ccfp_reg_operand" "c")
2235 (match_operand:SI 3 "arith11_operand" "ri")
2236 (match_operand:SI 4 "register_operand" "0")))]
2239 [(set_attr "type" "cmove")])
2241 ;; ??? There is not actually a 32 bit version of this instruction.
2243 [(set (match_operand:SI 0 "register_operand" "=r")
2244 (if_then_else (match_operator 1 "comparison_operator"
2245 [(match_operand:CCFPE 2 "ccfp_reg_operand" "c")
2247 (match_operand:SI 3 "arith11_operand" "ri")
2248 (match_operand:SI 4 "register_operand" "0")))]
2251 [(set_attr "type" "cmove")])
2254 [(set (match_operand:DI 0 "register_operand" "=r")
2255 (if_then_else (match_operator 1 "comparison_operator"
2256 [(match_operand:CCFP 2 "ccfp_reg_operand" "c")
2258 (match_operand:DI 3 "arith11_double_operand" "rHI")
2259 (match_operand:DI 4 "register_operand" "0")))]
2262 [(set_attr "type" "cmove")])
2265 [(set (match_operand:DI 0 "register_operand" "=r")
2266 (if_then_else (match_operator 1 "comparison_operator"
2267 [(match_operand:CCFPE 2 "ccfp_reg_operand" "c")
2269 (match_operand:DI 3 "arith11_double_operand" "rHI")
2270 (match_operand:DI 4 "register_operand" "0")))]
2273 [(set_attr "type" "cmove")])
2275 ;; ??? There is not actually a 32 bit version of this instruction.
2277 [(set (match_operand:SI 0 "register_operand" "=r")
2278 (if_then_else (match_operator 1 "v9_regcmp_op"
2279 [(match_operand:DI 2 "register_operand" "r")
2281 (match_operand:SI 3 "arith10_operand" "ri")
2282 (match_operand:SI 4 "register_operand" "0")))]
2285 [(set_attr "type" "cmove")])
2288 [(set (match_operand:DI 0 "register_operand" "=r")
2289 (if_then_else (match_operator 1 "v9_regcmp_op"
2290 [(match_operand:DI 2 "register_operand" "r")
2292 (match_operand:DI 3 "arith10_double_operand" "ri")
2293 (match_operand:DI 4 "register_operand" "0")))]
2296 [(set_attr "type" "cmove")])
2299 [(set (match_operand:SF 0 "register_operand" "=f")
2300 (if_then_else (match_operator 1 "v9_regcmp_op"
2301 [(match_operand:DI 2 "register_operand" "r")
2303 (match_operand:SF 3 "register_operand" "f")
2304 (match_operand:SF 4 "register_operand" "0")))]
2305 "TARGET_V9 && TARGET_FPU"
2306 "fmovrs%D1 %2,%r3,%0"
2307 [(set_attr "type" "cmove")])
2310 [(set (match_operand:DF 0 "register_operand" "=e")
2311 (if_then_else (match_operator 1 "v9_regcmp_op"
2312 [(match_operand:DI 2 "register_operand" "r")
2314 (match_operand:DF 3 "register_operand" "e")
2315 (match_operand:DF 4 "register_operand" "0")))]
2316 "TARGET_V9 && TARGET_FPU"
2317 "fmovrd%D1 %2,%r3,%0"
2318 [(set_attr "type" "cmove")])
2321 [(set (match_operand:TF 0 "register_operand" "=e")
2322 (if_then_else (match_operator 1 "v9_regcmp_op"
2323 [(match_operand:DI 2 "register_operand" "r")
2325 (match_operand:TF 3 "register_operand" "e")
2326 (match_operand:TF 4 "register_operand" "0")))]
2327 "TARGET_V9 && TARGET_FPU"
2328 "fmovrq%D1 %2,%r3,%0"
2329 [(set_attr "type" "cmove")])
2332 [(set (match_operand:SF 0 "register_operand" "=f")
2333 (if_then_else (match_operator 1 "comparison_operator"
2334 [(match_operand:CCFP 2 "ccfp_reg_operand" "c")
2336 (match_operand:SF 3 "register_operand" "f")
2337 (match_operand:SF 4 "register_operand" "0")))]
2338 "TARGET_V9 && TARGET_FPU"
2340 [(set_attr "type" "cmove")])
2343 [(set (match_operand:SF 0 "register_operand" "=f")
2344 (if_then_else (match_operator 1 "comparison_operator"
2345 [(match_operand:CCFPE 2 "ccfp_reg_operand" "c")
2347 (match_operand:SF 3 "register_operand" "f")
2348 (match_operand:SF 4 "register_operand" "0")))]
2349 "TARGET_V9 && TARGET_FPU"
2351 [(set_attr "type" "cmove")])
2354 [(set (match_operand:DF 0 "register_operand" "=e")
2355 (if_then_else (match_operator 1 "comparison_operator"
2356 [(match_operand:CCFP 2 "ccfp_reg_operand" "c")
2358 (match_operand:DF 3 "register_operand" "e")
2359 (match_operand:DF 4 "register_operand" "0")))]
2360 "TARGET_V9 && TARGET_FPU"
2362 [(set_attr "type" "cmove")])
2365 [(set (match_operand:DF 0 "register_operand" "=e")
2366 (if_then_else (match_operator 1 "comparison_operator"
2367 [(match_operand:CCFPE 2 "ccfp_reg_operand" "c")
2369 (match_operand:DF 3 "register_operand" "e")
2370 (match_operand:DF 4 "register_operand" "0")))]
2371 "TARGET_V9 && TARGET_FPU"
2373 [(set_attr "type" "cmove")])
2376 [(set (match_operand:TF 0 "register_operand" "=e")
2377 (if_then_else (match_operator 1 "comparison_operator"
2378 [(match_operand:CCFP 2 "ccfp_reg_operand" "c")
2380 (match_operand:TF 3 "register_operand" "e")
2381 (match_operand:TF 4 "register_operand" "0")))]
2382 "TARGET_V9 && TARGET_FPU"
2384 [(set_attr "type" "cmove")])
2387 [(set (match_operand:TF 0 "register_operand" "=e")
2388 (if_then_else (match_operator 1 "comparison_operator"
2389 [(match_operand:CCFPE 2 "ccfp_reg_operand" "c")
2391 (match_operand:TF 3 "register_operand" "e")
2392 (match_operand:TF 4 "register_operand" "0")))]
2393 "TARGET_V9 && TARGET_FPU"
2395 [(set_attr "type" "cmove")])
2398 [(set (match_operand:SF 0 "register_operand" "=f")
2399 (if_then_else (match_operator 1 "comparison_operator"
2400 [(reg:CC 0) (const_int 0)])
2401 (match_operand:SF 2 "register_operand" "f")
2402 (match_operand:SF 3 "register_operand" "0")))]
2403 "TARGET_V9 && TARGET_FPU"
2404 "fmovs%C1 %%icc,%2,%0"
2405 [(set_attr "type" "cmove")])
2408 [(set (match_operand:DF 0 "register_operand" "=e")
2409 (if_then_else (match_operator 1 "comparison_operator"
2410 [(reg:CC 0) (const_int 0)])
2411 (match_operand:DF 2 "register_operand" "e")
2412 (match_operand:DF 3 "register_operand" "0")))]
2413 "TARGET_V9 && TARGET_FPU"
2414 "fmovd%C1 %%icc,%2,%0"
2415 [(set_attr "type" "cmove")])
2418 [(set (match_operand:TF 0 "register_operand" "=e")
2419 (if_then_else (match_operator 1 "comparison_operator"
2420 [(reg:CC 0) (const_int 0)])
2421 (match_operand:TF 2 "register_operand" "e")
2422 (match_operand:TF 3 "register_operand" "0")))]
2423 "TARGET_V9 && TARGET_FPU"
2424 "fmovq%C1 %%icc,%2,%0"
2425 [(set_attr "type" "cmove")])
2428 [(set (match_operand:SF 0 "register_operand" "=f")
2429 (if_then_else (match_operator 1 "comparison_operator"
2430 [(reg:CCX 0) (const_int 0)])
2431 (match_operand:SF 2 "register_operand" "f")
2432 (match_operand:SF 3 "register_operand" "0")))]
2433 "TARGET_V9 && TARGET_FPU"
2434 "fmovs%C1 %%xcc,%2,%0"
2435 [(set_attr "type" "cmove")])
2438 [(set (match_operand:DF 0 "register_operand" "=e")
2439 (if_then_else (match_operator 1 "comparison_operator"
2440 [(reg:CCX 0) (const_int 0)])
2441 (match_operand:DF 2 "register_operand" "e")
2442 (match_operand:DF 3 "register_operand" "0")))]
2443 "TARGET_V9 && TARGET_FPU"
2444 "fmovd%C1 %%xcc,%2,%0"
2445 [(set_attr "type" "cmove")])
2448 [(set (match_operand:TF 0 "register_operand" "=e")
2449 (if_then_else (match_operator 1 "comparison_operator"
2450 [(reg:CCX 0) (const_int 0)])
2451 (match_operand:TF 2 "register_operand" "e")
2452 (match_operand:TF 3 "register_operand" "0")))]
2453 "TARGET_V9 && TARGET_FPU"
2454 "fmovq%C1 %%xcc,%2,%0"
2455 [(set_attr "type" "cmove")])
2457 ;;- zero extension instructions
2459 ;; These patterns originally accepted general_operands, however, slightly
2460 ;; better code is generated by only accepting register_operands, and then
2461 ;; letting combine generate the ldu[hb] insns.
2463 (define_expand "zero_extendhisi2"
2464 [(set (match_operand:SI 0 "register_operand" "")
2465 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
2469 rtx temp = gen_reg_rtx (SImode);
2470 rtx shift_16 = gen_rtx (CONST_INT, VOIDmode, 16);
2471 int op1_subword = 0;
2473 if (GET_CODE (operand1) == SUBREG)
2475 op1_subword = SUBREG_WORD (operand1);
2476 operand1 = XEXP (operand1, 0);
2479 emit_insn (gen_ashlsi3 (temp, gen_rtx (SUBREG, SImode, operand1,
2482 emit_insn (gen_lshrsi3 (operand0, temp, shift_16));
2487 [(set (match_operand:SI 0 "register_operand" "=r")
2488 (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
2491 [(set_attr "type" "load")])
2493 (define_expand "zero_extendqihi2"
2494 [(set (match_operand:HI 0 "register_operand" "")
2495 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
2500 [(set (match_operand:HI 0 "register_operand" "=r,r")
2501 (zero_extend:HI (match_operand:QI 1 "sparc_operand" "r,Q")))]
2502 "GET_CODE (operands[1]) != CONST_INT"
2506 [(set_attr "type" "unary,load")
2507 (set_attr "length" "1")])
2509 (define_expand "zero_extendqisi2"
2510 [(set (match_operand:SI 0 "register_operand" "")
2511 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
2516 [(set (match_operand:SI 0 "register_operand" "=r,r")
2517 (zero_extend:SI (match_operand:QI 1 "sparc_operand" "r,Q")))]
2518 "GET_CODE (operands[1]) != CONST_INT"
2522 [(set_attr "type" "unary,load")
2523 (set_attr "length" "1")])
2525 (define_expand "zero_extendqidi2"
2526 [(set (match_operand:DI 0 "register_operand" "")
2527 (zero_extend:DI (match_operand:QI 1 "register_operand" "")))]
2532 [(set (match_operand:DI 0 "register_operand" "=r,r")
2533 (zero_extend:DI (match_operand:QI 1 "sparc_operand" "r,Q")))]
2534 "TARGET_V9 && GET_CODE (operands[1]) != CONST_INT"
2538 [(set_attr "type" "unary,load")
2539 (set_attr "length" "1")])
2541 (define_expand "zero_extendhidi2"
2542 [(set (match_operand:DI 0 "register_operand" "")
2543 (zero_extend:DI (match_operand:HI 1 "register_operand" "")))]
2547 rtx temp = gen_reg_rtx (DImode);
2548 rtx shift_48 = gen_rtx (CONST_INT, VOIDmode, 48);
2549 int op1_subword = 0;
2551 if (GET_CODE (operand1) == SUBREG)
2553 op1_subword = SUBREG_WORD (operand1);
2554 operand1 = XEXP (operand1, 0);
2557 emit_insn (gen_ashldi3 (temp, gen_rtx (SUBREG, DImode, operand1,
2560 emit_insn (gen_lshrdi3 (operand0, temp, shift_48));
2565 [(set (match_operand:DI 0 "register_operand" "=r")
2566 (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
2569 [(set_attr "type" "load")])
2571 ;; ??? Write truncdisi pattern using sra?
2573 (define_expand "zero_extendsidi2"
2574 [(set (match_operand:DI 0 "register_operand" "")
2575 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
2580 [(set (match_operand:DI 0 "register_operand" "=r,r")
2581 (zero_extend:DI (match_operand:SI 1 "sparc_operand" "r,Q")))]
2582 "TARGET_V9 && GET_CODE (operands[1]) != CONST_INT"
2586 [(set_attr "type" "unary,load")
2587 (set_attr "length" "1")])
2589 ;; Simplify comparisons of extended values.
2593 (compare:CC (zero_extend:SI (match_operand:QI 0 "register_operand" "r"))
2596 "andcc %0,0xff,%%g0"
2597 [(set_attr "type" "compare")])
2601 (compare:CC (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
2603 (set (match_operand:SI 0 "register_operand" "=r")
2604 (zero_extend:SI (match_dup 1)))]
2607 [(set_attr "type" "unary")])
2609 ;; Similarly, handle SI->QI mode truncation followed by a compare.
2613 (compare:CC (subreg:QI (match_operand:SI 0 "register_operand" "r") 0)
2616 "andcc %0,0xff,%%g0"
2617 [(set_attr "type" "compare")])
2621 (compare:CC (subreg:QI (match_operand:SI 1 "register_operand" "r") 0)
2623 (set (match_operand:QI 0 "register_operand" "=r")
2627 [(set_attr "type" "unary")])
2629 ;;- sign extension instructions
2631 ;; These patterns originally accepted general_operands, however, slightly
2632 ;; better code is generated by only accepting register_operands, and then
2633 ;; letting combine generate the lds[hb] insns.
2635 (define_expand "extendhisi2"
2636 [(set (match_operand:SI 0 "register_operand" "")
2637 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
2641 rtx temp = gen_reg_rtx (SImode);
2642 rtx shift_16 = gen_rtx (CONST_INT, VOIDmode, 16);
2643 int op1_subword = 0;
2645 if (GET_CODE (operand1) == SUBREG)
2647 op1_subword = SUBREG_WORD (operand1);
2648 operand1 = XEXP (operand1, 0);
2651 emit_insn (gen_ashlsi3 (temp, gen_rtx (SUBREG, SImode, operand1,
2654 emit_insn (gen_ashrsi3 (operand0, temp, shift_16));
2659 [(set (match_operand:SI 0 "register_operand" "=r")
2660 (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
2663 [(set_attr "type" "load")])
2665 (define_expand "extendqihi2"
2666 [(set (match_operand:HI 0 "register_operand" "")
2667 (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
2671 rtx temp = gen_reg_rtx (SImode);
2672 rtx shift_24 = gen_rtx (CONST_INT, VOIDmode, 24);
2673 int op1_subword = 0;
2674 int op0_subword = 0;
2676 if (GET_CODE (operand1) == SUBREG)
2678 op1_subword = SUBREG_WORD (operand1);
2679 operand1 = XEXP (operand1, 0);
2681 if (GET_CODE (operand0) == SUBREG)
2683 op0_subword = SUBREG_WORD (operand0);
2684 operand0 = XEXP (operand0, 0);
2686 emit_insn (gen_ashlsi3 (temp, gen_rtx (SUBREG, SImode, operand1,
2689 if (GET_MODE (operand0) != SImode)
2690 operand0 = gen_rtx (SUBREG, SImode, operand0, op0_subword);
2691 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
2696 [(set (match_operand:HI 0 "register_operand" "=r")
2697 (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
2700 [(set_attr "type" "load")])
2702 (define_expand "extendqisi2"
2703 [(set (match_operand:SI 0 "register_operand" "")
2704 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
2708 rtx temp = gen_reg_rtx (SImode);
2709 rtx shift_24 = gen_rtx (CONST_INT, VOIDmode, 24);
2710 int op1_subword = 0;
2712 if (GET_CODE (operand1) == SUBREG)
2714 op1_subword = SUBREG_WORD (operand1);
2715 operand1 = XEXP (operand1, 0);
2718 emit_insn (gen_ashlsi3 (temp, gen_rtx (SUBREG, SImode, operand1,
2721 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
2726 [(set (match_operand:SI 0 "register_operand" "=r")
2727 (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
2730 [(set_attr "type" "load")])
2732 (define_expand "extendqidi2"
2733 [(set (match_operand:DI 0 "register_operand" "")
2734 (sign_extend:DI (match_operand:QI 1 "register_operand" "")))]
2738 rtx temp = gen_reg_rtx (DImode);
2739 rtx shift_56 = gen_rtx (CONST_INT, VOIDmode, 56);
2740 int op1_subword = 0;
2742 if (GET_CODE (operand1) == SUBREG)
2744 op1_subword = SUBREG_WORD (operand1);
2745 operand1 = XEXP (operand1, 0);
2748 emit_insn (gen_ashldi3 (temp, gen_rtx (SUBREG, DImode, operand1,
2751 emit_insn (gen_ashrdi3 (operand0, temp, shift_56));
2756 [(set (match_operand:DI 0 "register_operand" "=r")
2757 (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
2760 [(set_attr "type" "load")])
2762 (define_expand "extendhidi2"
2763 [(set (match_operand:DI 0 "register_operand" "")
2764 (sign_extend:DI (match_operand:HI 1 "register_operand" "")))]
2768 rtx temp = gen_reg_rtx (DImode);
2769 rtx shift_48 = gen_rtx (CONST_INT, VOIDmode, 48);
2770 int op1_subword = 0;
2772 if (GET_CODE (operand1) == SUBREG)
2774 op1_subword = SUBREG_WORD (operand1);
2775 operand1 = XEXP (operand1, 0);
2778 emit_insn (gen_ashldi3 (temp, gen_rtx (SUBREG, DImode, operand1,
2781 emit_insn (gen_ashrdi3 (operand0, temp, shift_48));
2786 [(set (match_operand:DI 0 "register_operand" "=r")
2787 (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
2790 [(set_attr "type" "load")])
2792 (define_expand "extendsidi2"
2793 [(set (match_operand:DI 0 "register_operand" "")
2794 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
2799 [(set (match_operand:DI 0 "register_operand" "=r,r")
2800 (sign_extend:DI (match_operand:SI 1 "sparc_operand" "r,Q")))]
2805 [(set_attr "type" "unary,load")
2806 (set_attr "length" "1")])
2808 ;; Special pattern for optimizing bit-field compares. This is needed
2809 ;; because combine uses this as a canonical form.
2814 (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
2815 (match_operand:SI 1 "small_int" "n")
2816 (match_operand:SI 2 "small_int" "n"))
2818 "INTVAL (operands[2]) > 19"
2821 int len = INTVAL (operands[1]);
2822 int pos = 32 - INTVAL (operands[2]) - len;
2823 unsigned mask = ((1 << len) - 1) << pos;
2825 operands[1] = gen_rtx (CONST_INT, VOIDmode, mask);
2826 return \"andcc %0,%1,%%g0\";
2832 (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
2833 (match_operand:SI 1 "small_int" "n")
2834 (match_operand:SI 2 "small_int" "n"))
2836 "TARGET_V9 && INTVAL (operands[2]) > 51"
2839 int len = INTVAL (operands[1]);
2840 int pos = 64 - INTVAL (operands[2]) - len;
2841 unsigned mask = ((1 << len) - 1) << pos;
2843 operands[1] = gen_rtx (CONST_INT, VOIDmode, mask);
2844 return \"andcc %0,%1,%%g0\";
2847 ;; Conversions between float, double and long double.
2849 (define_insn "extendsfdf2"
2850 [(set (match_operand:DF 0 "register_operand" "=e")
2852 (match_operand:SF 1 "register_operand" "f")))]
2855 [(set_attr "type" "fp")])
2857 (define_insn "extendsftf2"
2858 [(set (match_operand:TF 0 "register_operand" "=e")
2860 (match_operand:SF 1 "register_operand" "f")))]
2861 "TARGET_FPU && TARGET_HARD_QUAD"
2863 [(set_attr "type" "fp")])
2865 (define_insn "extenddftf2"
2866 [(set (match_operand:TF 0 "register_operand" "=e")
2868 (match_operand:DF 1 "register_operand" "e")))]
2869 "TARGET_FPU && TARGET_HARD_QUAD"
2871 [(set_attr "type" "fp")])
2873 (define_insn "truncdfsf2"
2874 [(set (match_operand:SF 0 "register_operand" "=f")
2876 (match_operand:DF 1 "register_operand" "e")))]
2879 [(set_attr "type" "fp")])
2881 (define_insn "trunctfsf2"
2882 [(set (match_operand:SF 0 "register_operand" "=f")
2884 (match_operand:TF 1 "register_operand" "e")))]
2885 "TARGET_FPU && TARGET_HARD_QUAD"
2887 [(set_attr "type" "fp")])
2889 (define_insn "trunctfdf2"
2890 [(set (match_operand:DF 0 "register_operand" "=e")
2892 (match_operand:TF 1 "register_operand" "e")))]
2893 "TARGET_FPU && TARGET_HARD_QUAD"
2895 [(set_attr "type" "fp")])
2897 ;; Conversion between fixed point and floating point.
2899 (define_insn "floatsisf2"
2900 [(set (match_operand:SF 0 "register_operand" "=f")
2901 (float:SF (match_operand:SI 1 "register_operand" "f")))]
2904 [(set_attr "type" "fp")])
2906 (define_insn "floatsidf2"
2907 [(set (match_operand:DF 0 "register_operand" "=e")
2908 (float:DF (match_operand:SI 1 "register_operand" "f")))]
2911 [(set_attr "type" "fp")])
2913 (define_insn "floatsitf2"
2914 [(set (match_operand:TF 0 "register_operand" "=e")
2915 (float:TF (match_operand:SI 1 "register_operand" "f")))]
2916 "TARGET_FPU && TARGET_HARD_QUAD"
2918 [(set_attr "type" "fp")])
2920 ;; Now the same for 64 bit sources.
2921 ;; ??? We cannot put DImode values in fp regs (see below near fix_truncdfsi2).
2923 (define_expand "floatdisf2"
2924 [(parallel [(set (match_operand:SF 0 "register_operand" "")
2925 (float:SF (match_operand:DI 1 "general_operand" "")))
2926 (clobber (match_dup 2))
2927 (clobber (match_dup 3))])]
2928 "TARGET_V9 && TARGET_FPU"
2931 operands[2] = gen_reg_rtx (DFmode);
2932 operands[3] = sparc64_fpconv_stack_temp ();
2935 (define_expand "floatdidf2"
2936 [(parallel [(set (match_operand:DF 0 "register_operand" "")
2937 (float:DF (match_operand:DI 1 "general_operand" "")))
2938 (clobber (match_dup 2))
2939 (clobber (match_dup 3))])]
2940 "TARGET_V9 && TARGET_FPU"
2943 operands[2] = gen_reg_rtx (DFmode);
2944 operands[3] = sparc64_fpconv_stack_temp ();
2947 (define_expand "floatditf2"
2948 [(parallel [(set (match_operand:TF 0 "register_operand" "")
2949 (float:TF (match_operand:DI 1 "general_operand" "")))
2950 (clobber (match_dup 2))
2951 (clobber (match_dup 3))])]
2952 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
2955 operands[2] = gen_reg_rtx (DFmode);
2956 operands[3] = sparc64_fpconv_stack_temp ();
2960 [(parallel [(set (match_operand:SF 0 "register_operand" "=f")
2961 (float:SF (match_operand:DI 1 "general_operand" "rm")))
2962 (clobber (match_operand:DF 2 "register_operand" "=&e"))
2963 (clobber (match_operand:DI 3 "memory_operand" "m"))])]
2964 "TARGET_V9 && TARGET_FPU"
2967 if (GET_CODE (operands[1]) == MEM)
2968 output_asm_insn (\"ldd %1,%2\", operands);
2970 output_asm_insn (\"stx %1,%3\;ldd %3,%2\", operands);
2971 return \"fxtos %2,%0\";
2973 [(set_attr "type" "fp")
2974 (set_attr "length" "3")])
2977 [(parallel [(set (match_operand:DF 0 "register_operand" "=e")
2978 (float:DF (match_operand:DI 1 "general_operand" "rm")))
2979 (clobber (match_operand:DF 2 "register_operand" "=&e"))
2980 (clobber (match_operand:DI 3 "memory_operand" "m"))])]
2981 "TARGET_V9 && TARGET_FPU"
2984 if (GET_CODE (operands[1]) == MEM)
2985 output_asm_insn (\"ldd %1,%2\", operands);
2987 output_asm_insn (\"stx %1,%3\;ldd %3,%2\", operands);
2988 return \"fxtod %2,%0\";
2990 [(set_attr "type" "fp")
2991 (set_attr "length" "3")])
2994 [(parallel [(set (match_operand:TF 0 "register_operand" "=e")
2995 (float:TF (match_operand:DI 1 "general_operand" "rm")))
2996 (clobber (match_operand:DF 2 "register_operand" "=&e"))
2997 (clobber (match_operand:DI 3 "memory_operand" "m"))])]
2998 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
3001 if (GET_CODE (operands[1]) == MEM)
3002 output_asm_insn (\"ldd %1,%2\", operands);
3004 output_asm_insn (\"stx %1,%3\;ldd %3,%2\", operands);
3005 return \"fxtoq %2,%0\";
3007 [(set_attr "type" "fp")
3008 (set_attr "length" "3")])
3010 ;; ??? Ideally, these are what we would like to use.
3012 (define_insn "floatdisf2_v9"
3013 [(set (match_operand:SF 0 "register_operand" "=f")
3014 (float:SF (match_operand:DI 1 "register_operand" "e")))]
3015 "0 && TARGET_V9 && TARGET_FPU"
3017 [(set_attr "type" "fp")])
3019 (define_insn "floatdidf2_v9"
3020 [(set (match_operand:DF 0 "register_operand" "=e")
3021 (float:DF (match_operand:DI 1 "register_operand" "e")))]
3022 "0 && TARGET_V9 && TARGET_FPU"
3024 [(set_attr "type" "fp")])
3026 (define_insn "floatditf2_v9"
3027 [(set (match_operand:TF 0 "register_operand" "=e")
3028 (float:TF (match_operand:DI 1 "register_operand" "e")))]
3029 "0 && TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
3031 [(set_attr "type" "fp")])
3033 ;; Convert a float to an actual integer.
3034 ;; Truncation is performed as part of the conversion.
3036 (define_insn "fix_truncsfsi2"
3037 [(set (match_operand:SI 0 "register_operand" "=f")
3038 (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
3041 [(set_attr "type" "fp")])
3043 (define_insn "fix_truncdfsi2"
3044 [(set (match_operand:SI 0 "register_operand" "=f")
3045 (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
3048 [(set_attr "type" "fp")])
3050 (define_insn "fix_trunctfsi2"
3051 [(set (match_operand:SI 0 "register_operand" "=f")
3052 (fix:SI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
3053 "TARGET_FPU && TARGET_HARD_QUAD"
3055 [(set_attr "type" "fp")])
3057 ;; Now the same, for 64-bit targets
3058 ;; ??? We try to work around an interesting problem.
3059 ;; If gcc tries to do a subreg on the result it will get the wrong answer:
3060 ;; "(subreg:SI (reg:DI M int-reg) 0)" is the same as
3061 ;; "(subreg:SI (reg:DI N float-reg) 1)", but gcc does not know how to change
3062 ;; the "0" to a "1". One could enhance alter_subreg but it is not clear how to
3065 (define_expand "fix_truncsfdi2"
3066 [(parallel [(set (match_operand:DI 0 "general_operand" "")
3067 (fix:DI (fix:SF (match_operand:SF 1 "register_operand" ""))))
3068 (clobber (match_dup 2))
3069 (clobber (match_dup 3))])]
3070 "TARGET_V9 && TARGET_FPU"
3073 operands[2] = gen_reg_rtx (DFmode);
3074 operands[3] = sparc64_fpconv_stack_temp ();
3077 (define_expand "fix_truncdfdi2"
3078 [(parallel [(set (match_operand:DI 0 "general_operand" "")
3079 (fix:DI (fix:DF (match_operand:DF 1 "register_operand" ""))))
3080 (clobber (match_dup 2))
3081 (clobber (match_dup 3))])]
3082 "TARGET_V9 && TARGET_FPU"
3085 operands[2] = gen_reg_rtx (DFmode);
3086 operands[3] = sparc64_fpconv_stack_temp ();
3089 (define_expand "fix_trunctfdi2"
3090 [(parallel [(set (match_operand:DI 0 "general_operand" "")
3091 (fix:DI (fix:TF (match_operand:TF 1 "register_operand" ""))))
3092 (clobber (match_dup 2))
3093 (clobber (match_dup 3))])]
3094 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
3097 operands[2] = gen_reg_rtx (DFmode);
3098 operands[3] = sparc64_fpconv_stack_temp ();
3102 [(parallel [(set (match_operand:DI 0 "general_operand" "=rm")
3103 (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))
3104 (clobber (match_operand:DF 2 "register_operand" "=&e"))
3105 (clobber (match_operand:DI 3 "memory_operand" "m"))])]
3106 "TARGET_V9 && TARGET_FPU"
3109 output_asm_insn (\"fstox %1,%2\", operands);
3110 if (GET_CODE (operands[0]) == MEM)
3111 return \"std %2,%0\";
3113 return \"std %2,%3\;ldx %3,%0\";
3115 [(set_attr "type" "fp")
3116 (set_attr "length" "3")])
3119 [(parallel [(set (match_operand:DI 0 "general_operand" "=rm")
3120 (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "e"))))
3121 (clobber (match_operand:DF 2 "register_operand" "=&e"))
3122 (clobber (match_operand:DI 3 "memory_operand" "m"))])]
3123 "TARGET_V9 && TARGET_FPU"
3126 output_asm_insn (\"fdtox %1,%2\", operands);
3127 if (GET_CODE (operands[0]) == MEM)
3128 return \"std %2,%0\";
3130 return \"std %2,%3\;ldx %3,%0\";
3132 [(set_attr "type" "fp")
3133 (set_attr "length" "3")])
3136 [(parallel [(set (match_operand:DI 0 "general_operand" "=rm")
3137 (fix:DI (fix:TF (match_operand:TF 1 "register_operand" "e"))))
3138 (clobber (match_operand:DF 2 "register_operand" "=&e"))
3139 (clobber (match_operand:DI 3 "memory_operand" "m"))])]
3140 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
3143 output_asm_insn (\"fqtox %1,%2\", operands);
3144 if (GET_CODE (operands[0]) == MEM)
3145 return \"std %2,%0\";
3147 return \"std %2,%3\;ldx %3,%0\";
3149 [(set_attr "type" "fp")
3150 (set_attr "length" "3")])
3152 ;; ??? Ideally, these are what we would like to use.
3154 (define_insn "fix_truncsfdi2_v9"
3155 [(set (match_operand:DI 0 "register_operand" "=e")
3156 (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
3157 "0 && TARGET_V9 && TARGET_FPU"
3159 [(set_attr "type" "fp")])
3161 (define_insn "fix_truncdfdi2_v9"
3162 [(set (match_operand:DI 0 "register_operand" "=e")
3163 (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
3164 "0 && TARGET_V9 && TARGET_FPU"
3166 [(set_attr "type" "fp")])
3168 (define_insn "fix_trunctfdi2_v9"
3169 [(set (match_operand:DI 0 "register_operand" "=e")
3170 (fix:DI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
3171 "0 && TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
3173 [(set_attr "type" "fp")])
3175 ;;- arithmetic instructions
3177 (define_expand "adddi3"
3178 [(set (match_operand:DI 0 "register_operand" "=r")
3179 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
3180 (match_operand:DI 2 "arith_double_operand" "rHI")))]
3186 emit_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (2,
3187 gen_rtx (SET, VOIDmode, operands[0],
3188 gen_rtx (PLUS, DImode, operands[1],
3190 gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, 0)))));
3196 [(set (match_operand:DI 0 "register_operand" "=r")
3197 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
3198 (match_operand:DI 2 "arith_double_operand" "rHI")))
3199 (clobber (reg:SI 0))]
3203 rtx op2 = operands[2];
3205 /* If constant is positive, upper bits zeroed, otherwise unchanged.
3206 Give the assembler a chance to pick the move instruction. */
3207 if (GET_CODE (op2) == CONST_INT)
3209 int sign = INTVAL (op2);
3211 return \"addcc %R1,%2,%R0\;addx %1,-1,%0\";
3212 return \"addcc %R1,%2,%R0\;addx %1,0,%0\";
3214 else if (GET_CODE (op2) == CONST_DOUBLE)
3217 xoperands[0] = operands[0];
3218 xoperands[1] = operands[1];
3219 xoperands[2] = GEN_INT (CONST_DOUBLE_LOW (op2));
3220 xoperands[3] = GEN_INT (CONST_DOUBLE_HIGH (op2));
3221 if (xoperands[2] == const0_rtx && xoperands[0] == xoperands[1])
3222 output_asm_insn (\"add %1,%3,%0\", xoperands);
3224 output_asm_insn (\"addcc %R1,%2,%R0\;addx %1,%3,%0\", xoperands);
3227 return \"addcc %R1,%R2,%R0\;addx %1,%2,%0\";
3229 [(set_attr "length" "2")])
3232 [(set (match_operand:DI 0 "register_operand" "=r")
3233 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
3234 (match_operand:DI 2 "arith_double_operand" "rHI")))]
3238 (define_insn "addsi3"
3239 [(set (match_operand:SI 0 "register_operand" "=r")
3240 (plus:SI (match_operand:SI 1 "arith_operand" "%r")
3241 (match_operand:SI 2 "arith_operand" "rI")))]
3244 [(set_attr "type" "ialu")])
3247 [(set (reg:CC_NOOV 0)
3248 (compare:CC_NOOV (plus:SI (match_operand:SI 0 "arith_operand" "%r")
3249 (match_operand:SI 1 "arith_operand" "rI"))
3253 [(set_attr "type" "compare")])
3256 [(set (reg:CCX_NOOV 0)
3257 (compare:CCX_NOOV (plus:DI (match_operand:DI 0 "arith_double_operand" "%r")
3258 (match_operand:DI 1 "arith_double_operand" "rHI"))
3262 [(set_attr "type" "compare")])
3265 [(set (reg:CC_NOOV 0)
3266 (compare:CC_NOOV (plus:SI (match_operand:SI 1 "arith_operand" "%r")
3267 (match_operand:SI 2 "arith_operand" "rI"))
3269 (set (match_operand:SI 0 "register_operand" "=r")
3270 (plus:SI (match_dup 1) (match_dup 2)))]
3275 [(set (reg:CCX_NOOV 0)
3276 (compare:CCX_NOOV (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
3277 (match_operand:DI 2 "arith_double_operand" "rHI"))
3279 (set (match_operand:DI 0 "register_operand" "=r")
3280 (plus:DI (match_dup 1) (match_dup 2)))]
3284 (define_expand "subdi3"
3285 [(set (match_operand:DI 0 "register_operand" "=r")
3286 (minus:DI (match_operand:DI 1 "register_operand" "r")
3287 (match_operand:DI 2 "arith_double_operand" "rHI")))]
3293 emit_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (2,
3294 gen_rtx (SET, VOIDmode, operands[0],
3295 gen_rtx (MINUS, DImode, operands[1],
3297 gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, 0)))));
3303 [(set (match_operand:DI 0 "register_operand" "=r")
3304 (minus:DI (match_operand:DI 1 "register_operand" "r")
3305 (match_operand:DI 2 "arith_double_operand" "rHI")))
3306 (clobber (reg:SI 0))]
3310 rtx op2 = operands[2];
3312 /* If constant is positive, upper bits zeroed, otherwise unchanged.
3313 Give the assembler a chance to pick the move instruction. */
3314 if (GET_CODE (op2) == CONST_INT)
3316 int sign = INTVAL (op2);
3318 return \"subcc %R1,%2,%R0\;subx %1,-1,%0\";
3319 return \"subcc %R1,%2,%R0\;subx %1,0,%0\";
3321 else if (GET_CODE (op2) == CONST_DOUBLE)
3324 xoperands[0] = operands[0];
3325 xoperands[1] = operands[1];
3326 xoperands[2] = GEN_INT (CONST_DOUBLE_LOW (op2));
3327 xoperands[3] = GEN_INT (CONST_DOUBLE_HIGH (op2));
3328 if (xoperands[2] == const0_rtx && xoperands[0] == xoperands[1])
3329 output_asm_insn (\"sub %1,%3,%0\", xoperands);
3331 output_asm_insn (\"subcc %R1,%2,%R0\;subx %1,%3,%0\", xoperands);
3334 return \"subcc %R1,%R2,%R0\;subx %1,%2,%0\";
3336 [(set_attr "length" "2")])
3339 [(set (match_operand:DI 0 "register_operand" "=r")
3340 (minus:DI (match_operand:DI 1 "register_operand" "r")
3341 (match_operand:DI 2 "arith_double_operand" "rHI")))]
3345 (define_insn "subsi3"
3346 [(set (match_operand:SI 0 "register_operand" "=r")
3347 (minus:SI (match_operand:SI 1 "register_operand" "r")
3348 (match_operand:SI 2 "arith_operand" "rI")))]
3351 [(set_attr "type" "ialu")])
3354 [(set (reg:CC_NOOV 0)
3355 (compare:CC_NOOV (minus:SI (match_operand:SI 0 "register_operand" "r")
3356 (match_operand:SI 1 "arith_operand" "rI"))
3360 [(set_attr "type" "compare")])
3363 [(set (reg:CCX_NOOV 0)
3364 (compare:CCX_NOOV (minus:DI (match_operand:DI 0 "register_operand" "r")
3365 (match_operand:DI 1 "arith_double_operand" "rHI"))
3369 [(set_attr "type" "compare")])
3372 [(set (reg:CC_NOOV 0)
3373 (compare:CC_NOOV (minus:SI (match_operand:SI 1 "register_operand" "r")
3374 (match_operand:SI 2 "arith_operand" "rI"))
3376 (set (match_operand:SI 0 "register_operand" "=r")
3377 (minus:SI (match_dup 1) (match_dup 2)))]
3382 [(set (reg:CCX_NOOV 0)
3383 (compare:CCX_NOOV (minus:DI (match_operand:DI 1 "register_operand" "r")
3384 (match_operand:DI 2 "arith_double_operand" "rHI"))
3386 (set (match_operand:DI 0 "register_operand" "=r")
3387 (minus:DI (match_dup 1) (match_dup 2)))]
3391 ;; This is anachronistic, and should not be used in v9 software.
3392 ;; The v9 compiler will widen the args and use muldi3.
3394 (define_insn "mulsi3"
3395 [(set (match_operand:SI 0 "register_operand" "=r")
3396 (mult:SI (match_operand:SI 1 "arith_operand" "%r")
3397 (match_operand:SI 2 "arith_operand" "rI")))]
3398 "TARGET_V8 || TARGET_SPARCLITE"
3400 [(set_attr "type" "imul")])
3402 (define_insn "muldi3"
3403 [(set (match_operand:DI 0 "register_operand" "=r")
3404 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r")
3405 (match_operand:DI 2 "arith_double_operand" "rHI")))]
3409 ;; It is not known whether this will match.
3412 [(set (match_operand:SI 0 "register_operand" "=r")
3413 (mult:SI (match_operand:SI 1 "arith_operand" "%r")
3414 (match_operand:SI 2 "arith_operand" "rI")))
3415 (set (reg:CC_NOOV 0)
3416 (compare:CC_NOOV (mult:SI (match_dup 1) (match_dup 2))
3418 "TARGET_V8 || TARGET_SPARCLITE"
3420 [(set_attr "type" "imul")])
3422 (define_expand "mulsidi3"
3423 [(set (match_operand:DI 0 "register_operand" "")
3424 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
3425 (sign_extend:DI (match_operand:SI 2 "arith_operand" ""))))]
3426 "TARGET_V8 || TARGET_SPARCLITE"
3429 if (CONSTANT_P (operands[2]))
3431 emit_insn (gen_const_mulsidi3 (operands[0], operands[1], operands[2]));
3437 [(set (match_operand:DI 0 "register_operand" "=r")
3438 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
3439 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
3440 "TARGET_V8 || TARGET_SPARCLITE"
3441 "smul %1,%2,%R0\;rd %%y,%0"
3442 [(set_attr "length" "2")])
3444 ;; Extra pattern, because sign_extend of a constant isn't valid.
3446 (define_insn "const_mulsidi3"
3447 [(set (match_operand:DI 0 "register_operand" "=r")
3448 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
3449 (match_operand:SI 2 "small_int" "I")))]
3450 "TARGET_V8 || TARGET_SPARCLITE"
3451 "smul %1,%2,%R0\;rd %%y,%0"
3452 [(set_attr "length" "2")])
3454 (define_expand "smulsi3_highpart"
3455 [(set (match_operand:SI 0 "register_operand" "")
3457 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
3458 (sign_extend:DI (match_operand:SI 2 "arith_operand" "")))
3460 "TARGET_V8 || TARGET_SPARCLITE"
3463 if (CONSTANT_P (operands[2]))
3465 emit_insn (gen_const_smulsi3_highpart (operands[0], operands[1], operands[2]));
3471 [(set (match_operand:SI 0 "register_operand" "=r")
3473 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
3474 (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
3476 "TARGET_V8 || TARGET_SPARCLITE"
3477 "smul %1,%2,%%g0\;rd %%y,%0"
3478 [(set_attr "length" "2")])
3480 (define_insn "const_smulsi3_highpart"
3481 [(set (match_operand:SI 0 "register_operand" "=r")
3483 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
3484 (match_operand:SI 2 "register_operand" "r"))
3486 "TARGET_V8 || TARGET_SPARCLITE"
3487 "smul %1,%2,%%g0\;rd %%y,%0"
3488 [(set_attr "length" "2")])
3490 (define_expand "umulsidi3"
3491 [(set (match_operand:DI 0 "register_operand" "")
3492 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
3493 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" ""))))]
3494 "TARGET_V8 || TARGET_SPARCLITE"
3497 if (CONSTANT_P (operands[2]))
3499 emit_insn (gen_const_umulsidi3 (operands[0], operands[1], operands[2]));
3505 [(set (match_operand:DI 0 "register_operand" "=r")
3506 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
3507 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
3508 "TARGET_V8 || TARGET_SPARCLITE"
3509 "umul %1,%2,%R0\;rd %%y,%0"
3510 [(set_attr "length" "2")])
3512 ;; Extra pattern, because sign_extend of a constant isn't valid.
3514 (define_insn "const_umulsidi3"
3515 [(set (match_operand:DI 0 "register_operand" "=r")
3516 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
3517 (match_operand:SI 2 "uns_small_int" "")))]
3518 "TARGET_V8 || TARGET_SPARCLITE"
3519 "umul %1,%2,%R0\;rd %%y,%0"
3520 [(set_attr "length" "2")])
3522 (define_expand "umulsi3_highpart"
3523 [(set (match_operand:SI 0 "register_operand" "")
3525 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
3526 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" "")))
3528 "TARGET_V8 || TARGET_SPARCLITE"
3531 if (CONSTANT_P (operands[2]))
3533 emit_insn (gen_const_umulsi3_highpart (operands[0], operands[1], operands[2]));
3539 [(set (match_operand:SI 0 "register_operand" "=r")
3541 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
3542 (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
3544 "TARGET_V8 || TARGET_SPARCLITE"
3545 "umul %1,%2,%%g0\;rd %%y,%0"
3546 [(set_attr "length" "2")])
3548 (define_insn "const_umulsi3_highpart"
3549 [(set (match_operand:SI 0 "register_operand" "=r")
3551 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
3552 (match_operand:SI 2 "uns_small_int" ""))
3554 "TARGET_V8 || TARGET_SPARCLITE"
3555 "umul %1,%2,%%g0\;rd %%y,%0"
3556 [(set_attr "length" "2")])
3558 ;; The architecture specifies that there must be 3 instructions between
3559 ;; a y register write and a use of it for correct results.
3561 (define_insn "divsi3"
3562 [(set (match_operand:SI 0 "register_operand" "=r")
3563 (div:SI (match_operand:SI 1 "register_operand" "r")
3564 (match_operand:SI 2 "arith_operand" "rI")))
3565 (clobber (match_scratch:SI 3 "=&r"))]
3567 "sra %1,31,%3\;wr %%g0,%3,%%y\;nop\;nop\;nop\;sdiv %1,%2,%0"
3568 [(set_attr "length" "6")])
3570 (define_insn "divdi3"
3571 [(set (match_operand:DI 0 "register_operand" "=r")
3572 (div:DI (match_operand:DI 1 "register_operand" "r")
3573 (match_operand:DI 2 "arith_double_operand" "rHI")))]
3577 ;; It is not known whether this will match.
3580 [(set (match_operand:SI 0 "register_operand" "=r")
3581 (div:SI (match_operand:SI 1 "register_operand" "r")
3582 (match_operand:SI 2 "arith_operand" "rI")))
3584 (compare:CC (div:SI (match_dup 1) (match_dup 2))
3586 (clobber (match_scratch:SI 3 "=&r"))]
3588 "sra %1,31,%3\;wr %%g0,%3,%%y\;nop\;nop\;nop\;sdivcc %1,%2,%0"
3589 [(set_attr "length" "6")])
3591 (define_insn "udivsi3"
3592 [(set (match_operand:SI 0 "register_operand" "=r")
3593 (udiv:SI (match_operand:SI 1 "register_operand" "r")
3594 (match_operand:SI 2 "arith_operand" "rI")))]
3596 "wr %%g0,%%g0,%%y\;nop\;nop\;nop\;udiv %1,%2,%0"
3597 [(set_attr "length" "5")])
3599 (define_insn "udivdi3"
3600 [(set (match_operand:DI 0 "register_operand" "=r")
3601 (udiv:DI (match_operand:DI 1 "register_operand" "r")
3602 (match_operand:DI 2 "arith_double_operand" "rHI")))]
3606 ;; It is not known whether this will match.
3609 [(set (match_operand:SI 0 "register_operand" "=r")
3610 (udiv:SI (match_operand:SI 1 "register_operand" "r")
3611 (match_operand:SI 2 "arith_operand" "rI")))
3613 (compare:CC (udiv:SI (match_dup 1) (match_dup 2))
3616 "wr %%g0,%%g0,%%y\;nop\;nop\;nop\;udivcc %1,%2,%0"
3617 [(set_attr "length" "5")])
3619 ;;- Boolean instructions
3620 ;; We define DImode `and` so with DImode `not` we can get
3621 ;; DImode `andn`. Other combinations are possible.
3623 (define_expand "anddi3"
3624 [(set (match_operand:DI 0 "register_operand" "")
3625 (and:DI (match_operand:DI 1 "arith_double_operand" "")
3626 (match_operand:DI 2 "arith_double_operand" "")))]
3631 [(set (match_operand:DI 0 "register_operand" "=r")
3632 (and:DI (match_operand:DI 1 "arith_double_operand" "%r")
3633 (match_operand:DI 2 "arith_double_operand" "rHI")))]
3637 rtx op2 = operands[2];
3639 /* If constant is positive, upper bits zeroed, otherwise unchanged.
3640 Give the assembler a chance to pick the move instruction. */
3641 if (GET_CODE (op2) == CONST_INT)
3643 int sign = INTVAL (op2);
3645 return \"mov %1,%0\;and %R1,%2,%R0\";
3646 return \"mov 0,%0\;and %R1,%2,%R0\";
3648 else if (GET_CODE (op2) == CONST_DOUBLE)
3651 xoperands[0] = operands[0];
3652 xoperands[1] = operands[1];
3653 xoperands[2] = GEN_INT (CONST_DOUBLE_LOW (op2));
3654 xoperands[3] = GEN_INT (CONST_DOUBLE_HIGH (op2));
3655 /* We could optimize then operands[1] == operands[0]
3656 and either half of the constant is -1. */
3657 output_asm_insn (\"and %R1,%2,%R0\;and %1,%3,%0\", xoperands);
3660 return \"and %1,%2,%0\;and %R1,%R2,%R0\";
3662 [(set_attr "length" "2")])
3665 [(set (match_operand:DI 0 "register_operand" "=r")
3666 (and:DI (match_operand:DI 1 "arith_double_operand" "%r")
3667 (match_operand:DI 2 "arith_double_operand" "rHI")))]
3671 (define_insn "andsi3"
3672 [(set (match_operand:SI 0 "register_operand" "=r")
3673 (and:SI (match_operand:SI 1 "arith_operand" "%r")
3674 (match_operand:SI 2 "arith_operand" "rI")))]
3677 [(set_attr "type" "ialu")])
3680 [(set (match_operand:SI 0 "register_operand" "")
3681 (and:SI (match_operand:SI 1 "register_operand" "")
3682 (match_operand:SI 2 "" "")))
3683 (clobber (match_operand:SI 3 "register_operand" ""))]
3684 "GET_CODE (operands[2]) == CONST_INT
3685 && !SMALL_INT (operands[2])
3686 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
3687 [(set (match_dup 3) (match_dup 4))
3688 (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 1)))]
3691 operands[4] = gen_rtx (CONST_INT, VOIDmode, ~INTVAL (operands[2]));
3695 [(set (match_operand:DI 0 "register_operand" "=r")
3696 (and:DI (not:DI (match_operand:DI 1 "register_operand" "r"))
3697 (match_operand:DI 2 "register_operand" "r")))]
3699 "andn %2,%1,%0\;andn %R2,%R1,%R0"
3700 [(set_attr "length" "2")])
3703 [(set (match_operand:DI 0 "register_operand" "=r")
3704 (and:DI (not:DI (match_operand:DI 1 "register_operand" "r"))
3705 (match_operand:DI 2 "register_operand" "r")))]
3710 [(set (match_operand:SI 0 "register_operand" "=r")
3711 (and:SI (not:SI (match_operand:SI 1 "register_operand" "r"))
3712 (match_operand:SI 2 "register_operand" "r")))]
3715 [(set_attr "type" "ialu")])
3717 (define_expand "iordi3"
3718 [(set (match_operand:DI 0 "register_operand" "")
3719 (ior:DI (match_operand:DI 1 "arith_double_operand" "")
3720 (match_operand:DI 2 "arith_double_operand" "")))]
3725 [(set (match_operand:DI 0 "register_operand" "=r")
3726 (ior:DI (match_operand:DI 1 "arith_double_operand" "%r")
3727 (match_operand:DI 2 "arith_double_operand" "rHI")))]
3731 rtx op2 = operands[2];
3733 /* If constant is positive, upper bits zeroed, otherwise unchanged.
3734 Give the assembler a chance to pick the move instruction. */
3735 if (GET_CODE (op2) == CONST_INT)
3737 int sign = INTVAL (op2);
3739 return \"mov -1,%0\;or %R1,%2,%R0\";
3740 return \"mov %1,%0\;or %R1,%2,%R0\";
3742 else if (GET_CODE (op2) == CONST_DOUBLE)
3745 xoperands[0] = operands[0];
3746 xoperands[1] = operands[1];
3747 xoperands[2] = GEN_INT (CONST_DOUBLE_LOW (op2));
3748 xoperands[3] = GEN_INT (CONST_DOUBLE_HIGH (op2));
3749 /* We could optimize then operands[1] == operands[0]
3750 and either half of the constant is 0. */
3751 output_asm_insn (\"or %R1,%2,%R0\;or %1,%3,%0\", xoperands);
3754 return \"or %1,%2,%0\;or %R1,%R2,%R0\";
3756 [(set_attr "length" "2")])
3759 [(set (match_operand:DI 0 "register_operand" "=r")
3760 (ior:DI (match_operand:DI 1 "arith_double_operand" "%r")
3761 (match_operand:DI 2 "arith_double_operand" "rHI")))]
3765 (define_insn "iorsi3"
3766 [(set (match_operand:SI 0 "register_operand" "=r")
3767 (ior:SI (match_operand:SI 1 "arith_operand" "%r")
3768 (match_operand:SI 2 "arith_operand" "rI")))]
3771 [(set_attr "type" "ialu")])
3774 [(set (match_operand:SI 0 "register_operand" "")
3775 (ior:SI (match_operand:SI 1 "register_operand" "")
3776 (match_operand:SI 2 "" "")))
3777 (clobber (match_operand:SI 3 "register_operand" ""))]
3778 "GET_CODE (operands[2]) == CONST_INT
3779 && !SMALL_INT (operands[2])
3780 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
3781 [(set (match_dup 3) (match_dup 4))
3782 (set (match_dup 0) (ior:SI (not:SI (match_dup 3)) (match_dup 1)))]
3785 operands[4] = gen_rtx (CONST_INT, VOIDmode, ~INTVAL (operands[2]));
3789 [(set (match_operand:DI 0 "register_operand" "=r")
3790 (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r"))
3791 (match_operand:DI 2 "register_operand" "r")))]
3793 "orn %2,%1,%0\;orn %R2,%R1,%R0"
3794 [(set_attr "length" "2")])
3797 [(set (match_operand:DI 0 "register_operand" "=r")
3798 (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r"))
3799 (match_operand:DI 2 "register_operand" "r")))]
3804 [(set (match_operand:SI 0 "register_operand" "=r")
3805 (ior:SI (not:SI (match_operand:SI 1 "register_operand" "r"))
3806 (match_operand:SI 2 "register_operand" "r")))]
3809 [(set_attr "type" "ialu")])
3811 (define_expand "xordi3"
3812 [(set (match_operand:DI 0 "register_operand" "")
3813 (xor:DI (match_operand:DI 1 "arith_double_operand" "")
3814 (match_operand:DI 2 "arith_double_operand" "")))]
3819 [(set (match_operand:DI 0 "register_operand" "=r")
3820 (xor:DI (match_operand:DI 1 "arith_double_operand" "%r")
3821 (match_operand:DI 2 "arith_double_operand" "rHI")))]
3825 rtx op2 = operands[2];
3827 /* If constant is positive, upper bits zeroed, otherwise unchanged.
3828 Give the assembler a chance to pick the move instruction. */
3829 if (GET_CODE (op2) == CONST_INT)
3831 int sign = INTVAL (op2);
3833 return \"xor %1,-1,%0\;xor %R1,%2,%R0\";
3834 return \"mov %1,%0\;xor %R1,%2,%R0\";
3836 else if (GET_CODE (op2) == CONST_DOUBLE)
3839 xoperands[0] = operands[0];
3840 xoperands[1] = operands[1];
3841 xoperands[2] = GEN_INT (CONST_DOUBLE_LOW (op2));
3842 xoperands[3] = GEN_INT (CONST_DOUBLE_HIGH (op2));
3843 /* We could optimize then operands[1] == operands[0]
3844 and either half of the constant is 0. */
3845 output_asm_insn (\"xor %R1,%2,%R0\;xor %1,%3,%0\", xoperands);
3848 return \"xor %1,%2,%0\;xor %R1,%R2,%R0\";
3850 [(set_attr "length" "2")])
3853 [(set (match_operand:DI 0 "register_operand" "=r")
3854 (xor:DI (match_operand:DI 1 "arith_double_operand" "%rJ")
3855 (match_operand:DI 2 "arith_double_operand" "rHI")))]
3859 (define_insn "xorsi3"
3860 [(set (match_operand:SI 0 "register_operand" "=r")
3861 (xor:SI (match_operand:SI 1 "arith_operand" "%rJ")
3862 (match_operand:SI 2 "arith_operand" "rI")))]
3865 [(set_attr "type" "ialu")])
3868 [(set (match_operand:SI 0 "register_operand" "")
3869 (xor:SI (match_operand:SI 1 "register_operand" "")
3870 (match_operand:SI 2 "" "")))
3871 (clobber (match_operand:SI 3 "register_operand" ""))]
3872 "GET_CODE (operands[2]) == CONST_INT
3873 && !SMALL_INT (operands[2])
3874 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
3875 [(set (match_dup 3) (match_dup 4))
3876 (set (match_dup 0) (not:SI (xor:SI (match_dup 3) (match_dup 1))))]
3879 operands[4] = gen_rtx (CONST_INT, VOIDmode, ~INTVAL (operands[2]));
3883 [(set (match_operand:SI 0 "register_operand" "")
3884 (not:SI (xor:SI (match_operand:SI 1 "register_operand" "")
3885 (match_operand:SI 2 "" ""))))
3886 (clobber (match_operand:SI 3 "register_operand" ""))]
3887 "GET_CODE (operands[2]) == CONST_INT
3888 && !SMALL_INT (operands[2])
3889 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
3890 [(set (match_dup 3) (match_dup 4))
3891 (set (match_dup 0) (xor:SI (match_dup 3) (match_dup 1)))]
3894 operands[4] = gen_rtx (CONST_INT, VOIDmode, ~INTVAL (operands[2]));
3897 ;; xnor patterns. Note that (a ^ ~b) == (~a ^ b) == ~(a ^ b).
3898 ;; Combine now canonicalizes to the rightmost expression.
3900 [(set (match_operand:DI 0 "register_operand" "=r")
3901 (not:DI (xor:DI (match_operand:DI 1 "register_operand" "r")
3902 (match_operand:DI 2 "register_operand" "r"))))]
3904 "xnor %1,%2,%0\;xnor %R1,%R2,%R0"
3905 [(set_attr "length" "2")])
3908 [(set (match_operand:DI 0 "register_operand" "=r")
3909 (not:DI (xor:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
3910 (match_operand:DI 2 "arith_double_operand" "rHI"))))]
3915 [(set (match_operand:SI 0 "register_operand" "=r")
3916 (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
3917 (match_operand:SI 2 "arith_operand" "rI"))))]
3920 [(set_attr "type" "ialu")])
3922 ;; These correspond to the above in the case where we also (or only)
3923 ;; want to set the condition code.
3928 (match_operator:SI 2 "cc_arithop"
3929 [(match_operand:SI 0 "arith_operand" "%r")
3930 (match_operand:SI 1 "arith_operand" "rI")])
3934 [(set_attr "type" "compare")])
3939 (match_operator:DI 2 "cc_arithop"
3940 [(match_operand:DI 0 "arith_double_operand" "%r")
3941 (match_operand:DI 1 "arith_double_operand" "rHI")])
3945 [(set_attr "type" "compare")])
3950 (match_operator:SI 3 "cc_arithop"
3951 [(match_operand:SI 1 "arith_operand" "%r")
3952 (match_operand:SI 2 "arith_operand" "rI")])
3954 (set (match_operand:SI 0 "register_operand" "=r")
3962 (match_operator:DI 3 "cc_arithop"
3963 [(match_operand:DI 1 "arith_double_operand" "%r")
3964 (match_operand:DI 2 "arith_double_operand" "rHI")])
3966 (set (match_operand:DI 0 "register_operand" "=r")
3974 (not:SI (xor:SI (match_operand:SI 0 "reg_or_0_operand" "%rJ")
3975 (match_operand:SI 1 "arith_operand" "rI")))
3978 "xnorcc %r0,%1,%%g0"
3979 [(set_attr "type" "compare")])
3984 (not:DI (xor:DI (match_operand:DI 0 "reg_or_0_operand" "%rJ")
3985 (match_operand:DI 1 "arith_double_operand" "rHI")))
3988 "xnorcc %r0,%1,%%g0"
3989 [(set_attr "type" "compare")])
3994 (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
3995 (match_operand:SI 2 "arith_operand" "rI")))
3997 (set (match_operand:SI 0 "register_operand" "=r")
3998 (not:SI (xor:SI (match_dup 1) (match_dup 2))))]
4005 (not:DI (xor:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ")
4006 (match_operand:DI 2 "arith_double_operand" "rHI")))
4008 (set (match_operand:DI 0 "register_operand" "=r")
4009 (not:DI (xor:DI (match_dup 1) (match_dup 2))))]
4016 (match_operator:SI 2 "cc_arithopn"
4017 [(not:SI (match_operand:SI 0 "arith_operand" "rI"))
4018 (match_operand:SI 1 "reg_or_0_operand" "rJ")])
4022 [(set_attr "type" "compare")])
4027 (match_operator:DI 2 "cc_arithopn"
4028 [(not:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
4029 (match_operand:DI 1 "reg_or_0_operand" "rJ")])
4033 [(set_attr "type" "compare")])
4038 (match_operator:SI 3 "cc_arithopn"
4039 [(not:SI (match_operand:SI 1 "arith_operand" "rI"))
4040 (match_operand:SI 2 "reg_or_0_operand" "rJ")])
4042 (set (match_operand:SI 0 "register_operand" "=r")
4050 (match_operator:DI 3 "cc_arithopn"
4051 [(not:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
4052 (match_operand:DI 2 "reg_or_0_operand" "rJ")])
4054 (set (match_operand:DI 0 "register_operand" "=r")
4059 ;; We cannot use the "neg" pseudo insn because the Sun assembler
4060 ;; does not know how to make it work for constants.
4062 (define_expand "negdi2"
4063 [(set (match_operand:DI 0 "register_operand" "=r")
4064 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
4070 emit_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (2,
4071 gen_rtx (SET, VOIDmode, operand0,
4072 gen_rtx (NEG, DImode, operand1)),
4073 gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, 0)))));
4079 [(set (match_operand:DI 0 "register_operand" "=r")
4080 (neg:DI (match_operand:DI 1 "register_operand" "r")))
4081 (clobber (reg:SI 0))]
4083 "subcc %%g0,%R1,%R0\;subx %%g0,%1,%0"
4084 [(set_attr "type" "unary")
4085 (set_attr "length" "2")])
4088 [(set (match_operand:DI 0 "register_operand" "=r")
4089 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
4092 [(set_attr "type" "unary")
4093 (set_attr "length" "1")])
4095 (define_insn "negsi2"
4096 [(set (match_operand:SI 0 "register_operand" "=r")
4097 (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
4100 [(set_attr "type" "unary")])
4103 [(set (reg:CC_NOOV 0)
4104 (compare:CC_NOOV (neg:SI (match_operand:SI 0 "arith_operand" "rI"))
4107 "subcc %%g0,%0,%%g0"
4108 [(set_attr "type" "compare")])
4111 [(set (reg:CCX_NOOV 0)
4112 (compare:CCX_NOOV (neg:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
4115 "subcc %%g0,%0,%%g0"
4116 [(set_attr "type" "compare")])
4119 [(set (reg:CC_NOOV 0)
4120 (compare:CC_NOOV (neg:SI (match_operand:SI 1 "arith_operand" "rI"))
4122 (set (match_operand:SI 0 "register_operand" "=r")
4123 (neg:SI (match_dup 1)))]
4126 [(set_attr "type" "unary")])
4129 [(set (reg:CCX_NOOV 0)
4130 (compare:CCX_NOOV (neg:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
4132 (set (match_operand:DI 0 "register_operand" "=r")
4133 (neg:DI (match_dup 1)))]
4136 [(set_attr "type" "unary")])
4138 ;; We cannot use the "not" pseudo insn because the Sun assembler
4139 ;; does not know how to make it work for constants.
4140 (define_expand "one_cmpldi2"
4141 [(set (match_operand:DI 0 "register_operand" "")
4142 (not:DI (match_operand:DI 1 "register_operand" "")))]
4147 [(set (match_operand:DI 0 "register_operand" "=r")
4148 (not:DI (match_operand:DI 1 "register_operand" "r")))]
4150 "xnor %%g0,%1,%0\;xnor %%g0,%R1,%R0"
4151 [(set_attr "type" "unary")
4152 (set_attr "length" "2")])
4155 [(set (match_operand:DI 0 "register_operand" "=r")
4156 (not:DI (match_operand:DI 1 "arith_double_operand" "rHI")))]
4159 [(set_attr "type" "unary")])
4161 (define_insn "one_cmplsi2"
4162 [(set (match_operand:SI 0 "register_operand" "=r")
4163 (not:SI (match_operand:SI 1 "arith_operand" "rI")))]
4166 [(set_attr "type" "unary")])
4170 (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI"))
4173 "xnorcc %%g0,%0,%%g0"
4174 [(set_attr "type" "compare")])
4178 (compare:CCX (not:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
4181 "xnorcc %%g0,%0,%%g0"
4182 [(set_attr "type" "compare")])
4186 (compare:CC (not:SI (match_operand:SI 1 "arith_operand" "rI"))
4188 (set (match_operand:SI 0 "register_operand" "=r")
4189 (not:SI (match_dup 1)))]
4192 [(set_attr "type" "unary")])
4196 (compare:CCX (not:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
4198 (set (match_operand:DI 0 "register_operand" "=r")
4199 (not:DI (match_dup 1)))]
4202 [(set_attr "type" "unary")])
4204 ;; Floating point arithmetic instructions.
4206 (define_insn "addtf3"
4207 [(set (match_operand:TF 0 "register_operand" "=e")
4208 (plus:TF (match_operand:TF 1 "register_operand" "e")
4209 (match_operand:TF 2 "register_operand" "e")))]
4210 "TARGET_FPU && TARGET_HARD_QUAD"
4212 [(set_attr "type" "fp")])
4214 (define_insn "adddf3"
4215 [(set (match_operand:DF 0 "register_operand" "=e")
4216 (plus:DF (match_operand:DF 1 "register_operand" "e")
4217 (match_operand:DF 2 "register_operand" "e")))]
4220 [(set_attr "type" "fp")])
4222 (define_insn "addsf3"
4223 [(set (match_operand:SF 0 "register_operand" "=f")
4224 (plus:SF (match_operand:SF 1 "register_operand" "f")
4225 (match_operand:SF 2 "register_operand" "f")))]
4228 [(set_attr "type" "fp")])
4230 (define_insn "subtf3"
4231 [(set (match_operand:TF 0 "register_operand" "=e")
4232 (minus:TF (match_operand:TF 1 "register_operand" "e")
4233 (match_operand:TF 2 "register_operand" "e")))]
4234 "TARGET_FPU && TARGET_HARD_QUAD"
4236 [(set_attr "type" "fp")])
4238 (define_insn "subdf3"
4239 [(set (match_operand:DF 0 "register_operand" "=e")
4240 (minus:DF (match_operand:DF 1 "register_operand" "e")
4241 (match_operand:DF 2 "register_operand" "e")))]
4244 [(set_attr "type" "fp")])
4246 (define_insn "subsf3"
4247 [(set (match_operand:SF 0 "register_operand" "=f")
4248 (minus:SF (match_operand:SF 1 "register_operand" "f")
4249 (match_operand:SF 2 "register_operand" "f")))]
4252 [(set_attr "type" "fp")])
4254 (define_insn "multf3"
4255 [(set (match_operand:TF 0 "register_operand" "=e")
4256 (mult:TF (match_operand:TF 1 "register_operand" "e")
4257 (match_operand:TF 2 "register_operand" "e")))]
4258 "TARGET_FPU && TARGET_HARD_QUAD"
4260 [(set_attr "type" "fpmul")])
4262 (define_insn "muldf3"
4263 [(set (match_operand:DF 0 "register_operand" "=e")
4264 (mult:DF (match_operand:DF 1 "register_operand" "e")
4265 (match_operand:DF 2 "register_operand" "e")))]
4268 [(set_attr "type" "fpmul")])
4270 (define_insn "mulsf3"
4271 [(set (match_operand:SF 0 "register_operand" "=f")
4272 (mult:SF (match_operand:SF 1 "register_operand" "f")
4273 (match_operand:SF 2 "register_operand" "f")))]
4276 [(set_attr "type" "fpmul")])
4279 [(set (match_operand:DF 0 "register_operand" "=e")
4280 (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "f"))
4281 (float_extend:DF (match_operand:SF 2 "register_operand" "f"))))]
4282 "(TARGET_V8 || TARGET_V9) && TARGET_FPU"
4284 [(set_attr "type" "fpmul")])
4287 [(set (match_operand:TF 0 "register_operand" "=e")
4288 (mult:TF (float_extend:TF (match_operand:DF 1 "register_operand" "e"))
4289 (float_extend:TF (match_operand:DF 2 "register_operand" "e"))))]
4290 "(TARGET_V8 || TARGET_V9) && TARGET_FPU"
4292 [(set_attr "type" "fpmul")])
4294 ;; don't have timing for quad-prec. divide.
4295 (define_insn "divtf3"
4296 [(set (match_operand:TF 0 "register_operand" "=e")
4297 (div:TF (match_operand:TF 1 "register_operand" "e")
4298 (match_operand:TF 2 "register_operand" "e")))]
4299 "TARGET_FPU && TARGET_HARD_QUAD"
4301 [(set_attr "type" "fpdivd")])
4303 (define_insn "divdf3"
4304 [(set (match_operand:DF 0 "register_operand" "=e")
4305 (div:DF (match_operand:DF 1 "register_operand" "e")
4306 (match_operand:DF 2 "register_operand" "e")))]
4309 [(set_attr "type" "fpdivd")])
4311 (define_insn "divsf3"
4312 [(set (match_operand:SF 0 "register_operand" "=f")
4313 (div:SF (match_operand:SF 1 "register_operand" "f")
4314 (match_operand:SF 2 "register_operand" "f")))]
4317 [(set_attr "type" "fpdivs")])
4319 (define_insn "negtf2"
4320 [(set (match_operand:TF 0 "register_operand" "=e,e")
4321 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
4326 return \"fnegd %1,%0\"; /* Can't use fnegs, won't work with upper regs. */
4327 else if (which_alternative == 0)
4328 return \"fnegs %0,%0\";
4330 return \"fnegs %1,%0\;fmovs %R1,%R0\;fmovs %S1,%S0\;fmovs %T1,%T0\";
4332 [(set_attr "type" "fp")
4333 (set_attr_alternative "length"
4335 (if_then_else (eq_attr "arch" "arch32bit") (const_int 4) (const_int 1))])])
4337 (define_insn "negdf2"
4338 [(set (match_operand:DF 0 "register_operand" "=e,e")
4339 (neg:DF (match_operand:DF 1 "register_operand" "0,e")))]
4344 return \"fnegd %1,%0\";
4345 else if (which_alternative == 0)
4346 return \"fnegs %0,%0\";
4348 return \"fnegs %1,%0\;fmovs %R1,%R0\";
4350 [(set_attr "type" "fp")
4351 (set_attr_alternative "length"
4353 (if_then_else (eq_attr "arch" "arch32bit") (const_int 2) (const_int 1))])])
4355 (define_insn "negsf2"
4356 [(set (match_operand:SF 0 "register_operand" "=f")
4357 (neg:SF (match_operand:SF 1 "register_operand" "f")))]
4360 [(set_attr "type" "fp")])
4362 (define_insn "abstf2"
4363 [(set (match_operand:TF 0 "register_operand" "=e,e")
4364 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
4369 return \"fabsd %1,%0\"; /* Can't use fabss, won't work with upper regs. */
4370 else if (which_alternative == 0)
4371 return \"fabss %0,%0\";
4373 return \"fabss %1,%0\;fmovs %R1,%R0\;fmovs %S1,%S0\;fmovs %T1,%T0\";
4375 [(set_attr "type" "fp")
4376 (set_attr_alternative "length"
4378 (if_then_else (eq_attr "arch" "arch32bit") (const_int 4) (const_int 1))])])
4380 (define_insn "absdf2"
4381 [(set (match_operand:DF 0 "register_operand" "=e,e")
4382 (abs:DF (match_operand:DF 1 "register_operand" "0,e")))]
4387 return \"fabsd %1,%0\";
4388 else if (which_alternative == 0)
4389 return \"fabss %0,%0\";
4391 return \"fabss %1,%0\;fmovs %R1,%R0\";
4393 [(set_attr "type" "fp")
4394 (set_attr_alternative "length"
4396 (if_then_else (eq_attr "arch" "arch32bit") (const_int 2) (const_int 1))])])
4398 (define_insn "abssf2"
4399 [(set (match_operand:SF 0 "register_operand" "=f")
4400 (abs:SF (match_operand:SF 1 "register_operand" "f")))]
4403 [(set_attr "type" "fp")])
4405 (define_insn "sqrttf2"
4406 [(set (match_operand:TF 0 "register_operand" "=e")
4407 (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
4408 "TARGET_FPU && TARGET_HARD_QUAD"
4410 [(set_attr "type" "fpsqrt")])
4412 (define_insn "sqrtdf2"
4413 [(set (match_operand:DF 0 "register_operand" "=e")
4414 (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
4417 [(set_attr "type" "fpsqrt")])
4419 (define_insn "sqrtsf2"
4420 [(set (match_operand:SF 0 "register_operand" "=f")
4421 (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
4424 [(set_attr "type" "fpsqrt")])
4426 ;;- arithmetic shift instructions
4428 (define_insn "ashlsi3"
4429 [(set (match_operand:SI 0 "register_operand" "=r")
4430 (ashift:SI (match_operand:SI 1 "register_operand" "r")
4431 (match_operand:SI 2 "arith_operand" "rI")))]
4435 if (GET_CODE (operands[2]) == CONST_INT
4436 && (unsigned) INTVAL (operands[2]) > 31)
4437 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
4439 return \"sll %1,%2,%0\";
4441 [(set_attr "type" "shift")])
4443 (define_insn "ashldi3"
4444 [(set (match_operand:DI 0 "register_operand" "=r")
4445 (ashift:DI (match_operand:DI 1 "register_operand" "r")
4446 (match_operand:SI 2 "arith_operand" "rI")))]
4450 if (GET_CODE (operands[2]) == CONST_INT
4451 && (unsigned) INTVAL (operands[2]) > 63)
4452 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
4454 return \"sllx %1,%2,%0\";
4458 [(set (reg:CC_NOOV 0)
4459 (compare:CC_NOOV (ashift:SI (match_operand:SI 0 "register_operand" "r")
4464 [(set_attr "type" "compare")])
4467 [(set (reg:CC_NOOV 0)
4468 (compare:CC_NOOV (ashift:SI (match_operand:SI 1 "register_operand" "r")
4471 (set (match_operand:SI 0 "register_operand" "=r")
4472 (ashift:SI (match_dup 1) (const_int 1)))]
4476 (define_insn "ashrsi3"
4477 [(set (match_operand:SI 0 "register_operand" "=r")
4478 (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
4479 (match_operand:SI 2 "arith_operand" "rI")))]
4483 if (GET_CODE (operands[2]) == CONST_INT
4484 && (unsigned) INTVAL (operands[2]) > 31)
4485 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
4487 return \"sra %1,%2,%0\";
4489 [(set_attr "type" "shift")])
4491 (define_insn "ashrdi3"
4492 [(set (match_operand:DI 0 "register_operand" "=r")
4493 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
4494 (match_operand:SI 2 "arith_operand" "rI")))]
4498 if (GET_CODE (operands[2]) == CONST_INT
4499 && (unsigned) INTVAL (operands[2]) > 63)
4500 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
4502 return \"srax %1,%2,%0\";
4505 (define_insn "lshrsi3"
4506 [(set (match_operand:SI 0 "register_operand" "=r")
4507 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
4508 (match_operand:SI 2 "arith_operand" "rI")))]
4512 if (GET_CODE (operands[2]) == CONST_INT
4513 && (unsigned) INTVAL (operands[2]) > 31)
4514 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
4516 return \"srl %1,%2,%0\";
4518 [(set_attr "type" "shift")])
4520 (define_insn "lshrdi3"
4521 [(set (match_operand:DI 0 "register_operand" "=r")
4522 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
4523 (match_operand:SI 2 "arith_operand" "rI")))]
4527 if (GET_CODE (operands[2]) == CONST_INT
4528 && (unsigned) INTVAL (operands[2]) > 63)
4529 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
4531 return \"srlx %1,%2,%0\";
4534 ;; Unconditional and other jump instructions
4535 ;; On the Sparc, by setting the annul bit on an unconditional branch, the
4536 ;; following insn is never executed. This saves us a nop. Dbx does not
4537 ;; handle such branches though, so we only use them when optimizing.
4539 [(set (pc) (label_ref (match_operand 0 "" "")))]
4542 [(set_attr "type" "uncond_branch")])
4544 (define_expand "tablejump"
4545 [(parallel [(set (pc) (match_operand 0 "register_operand" "r"))
4546 (use (label_ref (match_operand 1 "" "")))])]
4550 if (GET_MODE (operands[0]) != Pmode)
4553 /* We need to use the PC value in %o7 that was set up when the address
4554 of the label was loaded into a register, so we need different RTL. */
4558 emit_jump_insn (gen_pic_tablejump_32 (operands[0], operands[1]));
4560 emit_jump_insn (gen_pic_tablejump_64 (operands[0], operands[1]));
4565 (define_insn "pic_tablejump_32"
4566 [(set (pc) (match_operand:SI 0 "register_operand" "r"))
4567 (use (label_ref (match_operand 1 "" "")))
4571 [(set_attr "type" "uncond_branch")])
4573 (define_insn "pic_tablejump_64"
4574 [(set (pc) (match_operand:DI 0 "register_operand" "r"))
4575 (use (label_ref (match_operand 1 "" "")))
4579 [(set_attr "type" "uncond_branch")])
4582 [(set (pc) (match_operand:SI 0 "address_operand" "p"))
4583 (use (label_ref (match_operand 1 "" "")))]
4586 [(set_attr "type" "uncond_branch")])
4589 [(set (pc) (match_operand:DI 0 "address_operand" "p"))
4590 (use (label_ref (match_operand 1 "" "")))]
4593 [(set_attr "type" "uncond_branch")])
4596 [(set (pc) (label_ref (match_operand 0 "" "")))
4597 (set (reg:SI 15) (label_ref (match_dup 0)))]
4600 [(set_attr "type" "uncond_branch")])
4603 [(set (pc) (label_ref (match_operand 0 "" "")))
4604 (set (reg:DI 15) (label_ref (match_dup 0)))]
4607 [(set_attr "type" "uncond_branch")])
4609 ;; This pattern recognizes the "instruction" that appears in
4610 ;; a function call that wants a structure value,
4611 ;; to inform the called function if compiled with Sun CC.
4613 ; [(match_operand:SI 0 "immediate_operand" "")]
4614 ; "GET_CODE (operands[0]) == CONST_INT && INTVAL (operands[0]) > 0"
4616 ; [(set_attr "type" "marker")])
4618 ;;- jump to subroutine
4619 (define_expand "call"
4620 ;; Note that this expression is not used for generating RTL.
4621 ;; All the RTL is generated explicitly below.
4622 [(call (match_operand 0 "call_operand" "")
4623 (match_operand 3 "" "i"))]
4624 ;; operands[2] is next_arg_register
4625 ;; operands[3] is struct_value_size_rtx.
4629 rtx fn_rtx, nregs_rtx;
4631 if (GET_MODE (operands[0]) != FUNCTION_MODE)
4634 if (GET_CODE (XEXP (operands[0], 0)) == LABEL_REF)
4636 /* This is really a PIC sequence. We want to represent
4637 it as a funny jump so it's delay slots can be filled.
4639 ??? But if this really *is* a CALL, will not it clobber the
4640 call-clobbered registers? We lose this if it is a JUMP_INSN.
4641 Why cannot we have delay slots filled if it were a CALL? */
4643 if (! TARGET_V9 && INTVAL (operands[3]) != 0)
4644 emit_jump_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (3,
4645 gen_rtx (SET, VOIDmode, pc_rtx,
4646 XEXP (operands[0], 0)),
4648 gen_rtx (CLOBBER, VOIDmode,
4649 gen_rtx (REG, Pmode, 15)))));
4651 emit_jump_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (2,
4652 gen_rtx (SET, VOIDmode, pc_rtx,
4653 XEXP (operands[0], 0)),
4654 gen_rtx (CLOBBER, VOIDmode,
4655 gen_rtx (REG, Pmode, 15)))));
4659 fn_rtx = operands[0];
4661 /* Count the number of parameter registers being used by this call.
4662 if that argument is NULL, it means we are using them all, which
4663 means 6 on the sparc. */
4666 nregs_rtx = gen_rtx (CONST_INT, VOIDmode, REGNO (operands[2]) - 8);
4668 nregs_rtx = gen_rtx (CONST_INT, VOIDmode, 6);
4670 nregs_rtx = const0_rtx;
4673 if (! TARGET_V9 && INTVAL (operands[3]) != 0)
4674 emit_call_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (3,
4675 gen_rtx (CALL, VOIDmode, fn_rtx, nregs_rtx),
4677 gen_rtx (CLOBBER, VOIDmode,
4678 gen_rtx (REG, Pmode, 15)))));
4680 emit_call_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (2,
4681 gen_rtx (CALL, VOIDmode, fn_rtx, nregs_rtx),
4682 gen_rtx (CLOBBER, VOIDmode,
4683 gen_rtx (REG, Pmode, 15)))));
4687 /* If this call wants a structure value,
4688 emit an unimp insn to let the called function know about this. */
4689 if (! TARGET_V9 && INTVAL (operands[3]) > 0)
4691 rtx insn = emit_insn (operands[3]);
4692 SCHED_GROUP_P (insn) = 1;
4699 ;; We can't use the same pattern for these two insns, because then registers
4700 ;; in the address may not be properly reloaded.
4703 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
4704 (match_operand 1 "" ""))
4705 (clobber (reg:SI 15))]
4706 ;;- Do not use operand 1 for most machines.
4710 return \"call %a0,%1%#\";
4712 [(set_attr "type" "call")])
4715 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
4716 (match_operand 1 "" ""))
4717 (clobber (reg:SI 15))]
4718 ;;- Do not use operand 1 for most machines.
4722 return \"call %a0,%1%#\";
4724 [(set_attr "type" "call")])
4727 [(call (mem:SI (match_operand:DI 0 "address_operand" "p"))
4728 (match_operand 1 "" ""))
4729 (clobber (reg:DI 15))]
4730 ;;- Do not use operand 1 for most machines.
4734 return \"call %a0,%1%#\";
4736 [(set_attr "type" "call")])
4739 [(call (mem:SI (match_operand:DI 0 "symbolic_operand" "s"))
4740 (match_operand 1 "" ""))
4741 (clobber (reg:DI 15))]
4742 ;;- Do not use operand 1 for most machines.
4746 return \"call %a0,%1%#\";
4748 [(set_attr "type" "call")])
4750 ;; This is a call that wants a structure value.
4751 ;; There is no such critter for v9 (??? we may need one anyway).
4753 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
4754 (match_operand 1 "" ""))
4755 (match_operand 2 "immediate_operand" "")
4756 (clobber (reg:SI 15))]
4757 ;;- Do not use operand 1 for most machines.
4758 "! TARGET_V9 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
4761 return \"call %a0,%1\;nop\;unimp %2\";
4763 [(set_attr "type" "call_no_delay_slot")])
4765 ;; This is a call that wants a structure value.
4766 ;; There is no such critter for v9 (??? we may need one anyway).
4768 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
4769 (match_operand 1 "" ""))
4770 (match_operand 2 "immediate_operand" "")
4771 (clobber (reg:SI 15))]
4772 ;;- Do not use operand 1 for most machines.
4773 "! TARGET_V9 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
4776 return \"call %a0,%1\;nop\;unimp %2\";
4778 [(set_attr "type" "call_no_delay_slot")])
4780 ;; This is a call that may want a structure value. This is used for
4783 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
4784 (match_operand 1 "" ""))
4785 (match_operand 2 "immediate_operand" "")
4786 (clobber (reg:SI 15))]
4787 ;;- Do not use operand 1 for most machines.
4788 "! TARGET_V9 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
4791 return \"call %a0,%1\;nop\;nop\";
4793 [(set_attr "type" "call_no_delay_slot")])
4795 ;; This is a call that wants a structure value.
4797 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
4798 (match_operand 1 "" ""))
4799 (match_operand 2 "immediate_operand" "")
4800 (clobber (reg:SI 15))]
4801 ;;- Do not use operand 1 for most machines.
4802 "! TARGET_V9 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
4805 return \"call %a0,%1\;nop\;nop\";
4807 [(set_attr "type" "call_no_delay_slot")])
4809 (define_expand "call_value"
4810 ;; Note that this expression is not used for generating RTL.
4811 ;; All the RTL is generated explicitly below.
4812 [(set (match_operand 0 "register_operand" "=rf")
4813 (call (match_operand:SI 1 "" "")
4814 (match_operand 4 "" "")))]
4815 ;; operand 2 is stack_size_rtx
4816 ;; operand 3 is next_arg_register
4820 rtx fn_rtx, nregs_rtx;
4823 if (GET_MODE (operands[1]) != FUNCTION_MODE)
4826 fn_rtx = operands[1];
4830 nregs_rtx = gen_rtx (CONST_INT, VOIDmode, REGNO (operands[3]) - 8);
4832 nregs_rtx = gen_rtx (CONST_INT, VOIDmode, 6);
4834 nregs_rtx = const0_rtx;
4838 gen_rtx (SET, VOIDmode, operands[0],
4839 gen_rtx (CALL, VOIDmode, fn_rtx, nregs_rtx)),
4840 gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, Pmode, 15)));
4842 emit_call_insn (gen_rtx (PARALLEL, VOIDmode, vec));
4848 [(set (match_operand 0 "" "=rf")
4849 (call (mem:SI (match_operand:SI 1 "address_operand" "p"))
4850 (match_operand 2 "" "")))
4851 (clobber (reg:SI 15))]
4852 ;;- Do not use operand 2 for most machines.
4856 return \"call %a1,%2%#\";
4858 [(set_attr "type" "call")])
4861 [(set (match_operand 0 "" "=rf")
4862 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
4863 (match_operand 2 "" "")))
4864 (clobber (reg:SI 15))]
4865 ;;- Do not use operand 2 for most machines.
4869 return \"call %a1,%2%#\";
4871 [(set_attr "type" "call")])
4874 [(set (match_operand 0 "" "=rf")
4875 (call (mem:SI (match_operand:DI 1 "address_operand" "p"))
4876 (match_operand 2 "" "")))
4877 (clobber (reg:DI 15))]
4878 ;;- Do not use operand 2 for most machines.
4882 return \"call %a1,%2%#\";
4884 [(set_attr "type" "call")])
4887 [(set (match_operand 0 "" "=rf")
4888 (call (mem:SI (match_operand:DI 1 "symbolic_operand" "s"))
4889 (match_operand 2 "" "")))
4890 (clobber (reg:DI 15))]
4891 ;;- Do not use operand 2 for most machines.
4895 return \"call %a1,%2%#\";
4897 [(set_attr "type" "call")])
4899 (define_expand "untyped_call"
4900 [(parallel [(call (match_operand 0 "" "")
4902 (match_operand 1 "" "")
4903 (match_operand 2 "" "")])]
4909 /* Pass constm1 to indicate that it may expect a structure value, but
4910 we don't know what size it is. */
4911 emit_call_insn (gen_call (operands[0], const0_rtx, NULL, constm1_rtx));
4913 for (i = 0; i < XVECLEN (operands[2], 0); i++)
4915 rtx set = XVECEXP (operands[2], 0, i);
4916 emit_move_insn (SET_DEST (set), SET_SRC (set));
4919 /* The optimizer does not know that the call sets the function value
4920 registers we stored in the result block. We avoid problems by
4921 claiming that all hard registers are used and clobbered at this
4923 emit_insn (gen_blockage ());
4928 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
4929 ;; all of memory. This blocks insns from being moved across this point.
4931 (define_insn "blockage"
4932 [(unspec_volatile [(const_int 0)] 0)]
4936 ;; Prepare to return any type including a structure value.
4938 (define_expand "untyped_return"
4939 [(match_operand:BLK 0 "memory_operand" "")
4940 (match_operand 1 "" "")]
4944 rtx valreg1 = gen_rtx (REG, DImode, 24);
4945 rtx valreg2 = gen_rtx (REG, TARGET_V9 ? TFmode : DFmode, 32);
4946 rtx result = operands[0];
4950 rtx rtnreg = gen_rtx (REG, SImode, (leaf_function ? 15 : 31));
4951 rtx value = gen_reg_rtx (SImode);
4953 /* Fetch the instruction where we will return to and see if it's an unimp
4954 instruction (the most significant 10 bits will be zero). If so,
4955 update the return address to skip the unimp instruction. */
4956 emit_move_insn (value,
4957 gen_rtx (MEM, SImode, plus_constant (rtnreg, 8)));
4958 emit_insn (gen_lshrsi3 (value, value, GEN_INT (22)));
4959 emit_insn (gen_update_return (rtnreg, value));
4962 /* Reload the function value registers. */
4963 emit_move_insn (valreg1, change_address (result, DImode, XEXP (result, 0)));
4964 emit_move_insn (valreg2,
4965 change_address (result, TARGET_V9 ? TFmode : DFmode,
4966 plus_constant (XEXP (result, 0), 8)));
4968 /* Put USE insns before the return. */
4969 emit_insn (gen_rtx (USE, VOIDmode, valreg1));
4970 emit_insn (gen_rtx (USE, VOIDmode, valreg2));
4972 /* Construct the return. */
4973 expand_null_return ();
4978 ;; This is a bit of a hack. We're incrementing a fixed register (%i7),
4979 ;; and parts of the compiler don't want to believe that the add is needed.
4981 (define_insn "update_return"
4982 [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
4983 (match_operand:SI 1 "register_operand" "r")] 0)]
4985 "cmp %1,0\;be,a .+8\;add %0,4,%0"
4986 [(set_attr "type" "multi")])
4988 (define_insn "return"
4991 "* return output_return (operands);"
4992 [(set_attr "type" "multi")])
4999 (define_expand "indirect_jump"
5000 [(set (pc) (match_operand 0 "address_operand" "p"))]
5005 [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
5008 [(set_attr "type" "uncond_branch")])
5011 [(set (pc) (match_operand:DI 0 "address_operand" "p"))]
5014 [(set_attr "type" "uncond_branch")])
5016 ;; ??? This doesn't handle v9 yet. It also doesn't work with -mflat.
5017 (define_expand "nonlocal_goto"
5018 [(match_operand:SI 0 "general_operand" "")
5019 (match_operand:SI 1 "general_operand" "")
5020 (match_operand:SI 2 "general_operand" "")
5021 (match_operand:SI 3 "" "")]
5025 /* Trap instruction to flush all the register windows. */
5026 emit_insn (gen_flush_register_windows ());
5027 /* Load the fp value for the containing fn into %fp.
5028 This is needed because operands[2] refers to %fp.
5029 Virtual register instantiation fails if the virtual %fp isn't set from a
5030 register. Thus we must copy operands[0] into a register if it isn't
5032 if (GET_CODE (operands[0]) != REG)
5033 operands[0] = force_reg (SImode, operands[0]);
5034 emit_move_insn (virtual_stack_vars_rtx, operands[0]);
5035 /* Find the containing function's current nonlocal goto handler,
5036 which will do any cleanups and then jump to the label. */
5037 emit_move_insn (gen_rtx (REG, SImode, 8), operands[1]);
5038 /* Restore %fp from stack pointer value for containing function.
5039 The restore insn that follows will move this to %sp,
5040 and reload the appropriate value into %fp. */
5041 emit_move_insn (frame_pointer_rtx, operands[2]);
5042 /* Put in the static chain register the nonlocal label address. */
5043 emit_move_insn (static_chain_rtx, operands[3]);
5044 /* USE of frame_pointer_rtx added for consistency; not clear if
5046 emit_insn (gen_rtx (USE, VOIDmode, frame_pointer_rtx));
5047 emit_insn (gen_rtx (USE, VOIDmode, stack_pointer_rtx));
5048 emit_insn (gen_rtx (USE, VOIDmode, static_chain_rtx));
5049 emit_insn (gen_rtx (USE, VOIDmode, gen_rtx (REG, SImode, 8)));
5050 /* Return, restoring reg window and jumping to goto handler. */
5051 emit_insn (gen_goto_handler_and_restore ());
5055 ;; Special trap insn to flush register windows.
5056 (define_insn "flush_register_windows"
5057 [(unspec_volatile [(const_int 0)] 1)]
5059 "* return TARGET_V9 ? \"flushw\" : \"ta 3\";"
5060 [(set_attr "type" "misc")])
5062 (define_insn "goto_handler_and_restore"
5063 [(unspec_volatile [(const_int 0)] 2)]
5065 "jmp %%o0+0\;restore"
5066 [(set_attr "type" "misc")
5067 (set_attr "length" "2")])
5069 ;; Special pattern for the FLUSH instruction.
5071 (define_insn "flush"
5072 [(unspec_volatile [(match_operand 0 "memory_operand" "m")] 3)]
5074 "* return TARGET_V9 ? \"flush %f0\" : \"iflush %f0\";"
5075 [(set_attr "type" "misc")])
5079 ;; The scan instruction searches from the most significant bit while ffs
5080 ;; searches from the least significant bit. The bit index and treatment of
5081 ;; zero also differ. It takes at least 7 instructions to get the proper
5082 ;; result. Here is an obvious 8 instruction seequence.
5084 (define_insn "ffssi2"
5085 [(set (match_operand:SI 0 "register_operand" "=&r")
5086 (ffs:SI (match_operand:SI 1 "register_operand" "r")))
5087 (clobber (match_scratch:SI 2 "=&r"))]
5089 "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"
5090 [(set_attr "type" "multi")
5091 (set_attr "length" "8")])
5093 ;; ??? This should be a define expand, so that the extra instruction have
5094 ;; a chance of being optimized away.
5096 (define_insn "ffsdi2"
5097 [(set (match_operand:DI 0 "register_operand" "=&r")
5098 (ffs:DI (match_operand:DI 1 "register_operand" "r")))
5099 (clobber (match_scratch:DI 2 "=&r"))]
5101 "neg %1,%2\;not %2,%2\;xor %1,%2,%2\;popc %2,%0\;movrz %1,%%g0,%0"
5102 [(set_attr "type" "multi")
5103 (set_attr "length" "5")])
5105 ;; Split up troublesome insns for better scheduling. */
5107 ;; The following patterns are straightforward. They can be applied
5108 ;; either before or after register allocation.
5111 [(set (match_operator 0 "memop" [(match_operand:SI 1 "symbolic_operand" "")])
5112 (match_operand 2 "reg_or_0_operand" ""))
5113 (clobber (match_operand:SI 3 "register_operand" ""))]
5115 [(set (match_dup 3) (high:SI (match_dup 1)))
5116 (set (match_op_dup 0 [(lo_sum:SI (match_dup 3) (match_dup 1))])
5121 [(set (match_operator 0 "memop"
5122 [(match_operand:SI 1 "immediate_operand" "")])
5123 (match_operand 2 "general_operand" ""))
5124 (clobber (match_operand:SI 3 "register_operand" ""))]
5126 [(set (match_op_dup 0 [(match_dup 1)])
5130 operands[1] = legitimize_pic_address (operands[1], GET_MODE (operands[0]),
5135 [(set (match_operand 0 "register_operand" "")
5136 (match_operator 1 "memop"
5137 [(match_operand:SI 2 "immediate_operand" "")]))]
5140 (match_op_dup 1 [(match_dup 2)]))]
5143 operands[2] = legitimize_pic_address (operands[2], GET_MODE (operands[1]),
5147 ;; Sign- and Zero-extend operations can have symbolic memory operands.
5150 [(set (match_operand 0 "register_operand" "")
5151 (match_operator 1 "extend_op"
5152 [(match_operator 2 "memop"
5153 [(match_operand:SI 3 "immediate_operand" "")])]))]
5156 (match_op_dup 1 [(match_op_dup 2 [(match_dup 3)])]))]
5159 operands[3] = legitimize_pic_address (operands[3], GET_MODE (operands[2]),
5164 [(set (match_operand:SI 0 "register_operand" "")
5165 (match_operand:SI 1 "immediate_operand" ""))]
5166 "! flag_pic && (GET_CODE (operands[1]) == SYMBOL_REF
5167 || GET_CODE (operands[1]) == CONST
5168 || GET_CODE (operands[1]) == LABEL_REF)"
5169 [(set (match_dup 0) (high:SI (match_dup 1)))
5171 (lo_sum:SI (match_dup 0) (match_dup 1)))]
5174 ;; LABEL_REFs are not modified by `legitimize_pic_address`
5175 ;; so do not recurse infinitely in the PIC case.
5177 [(set (match_operand:SI 0 "register_operand" "")
5178 (match_operand:SI 1 "immediate_operand" ""))]
5179 "flag_pic && (GET_CODE (operands[1]) == SYMBOL_REF
5180 || GET_CODE (operands[1]) == CONST)"
5181 [(set (match_dup 0) (match_dup 1))]
5184 operands[1] = legitimize_pic_address (operands[1], Pmode, operands[0]);
5187 ;; These split sne/seq insns. The forms of the resulting insns are
5188 ;; somewhat bogus, but they avoid extra patterns and show data dependency.
5189 ;; Nothing will look at these in detail after splitting has occurred.
5191 ;; ??? v9 DImode versions are missing because addc and subc use %icc.
5194 [(set (match_operand:SI 0 "register_operand" "")
5195 (ne:SI (match_operand:SI 1 "register_operand" "")
5197 (clobber (reg:CC 0))]
5199 [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
5201 (set (match_dup 0) (ltu:SI (reg:CC 0) (const_int 0)))]
5205 [(set (match_operand:SI 0 "register_operand" "")
5206 (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "")
5208 (clobber (reg:CC 0))]
5210 [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
5212 (set (match_dup 0) (neg:SI (ltu:SI (reg:CC 0) (const_int 0))))]
5216 [(set (match_operand:SI 0 "register_operand" "")
5217 (eq:SI (match_operand:SI 1 "register_operand" "")
5219 (clobber (reg:CC 0))]
5221 [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
5223 (set (match_dup 0) (geu:SI (reg:CC 0) (const_int 0)))]
5227 [(set (match_operand:SI 0 "register_operand" "")
5228 (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "")
5230 (clobber (reg:CC 0))]
5232 [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
5234 (set (match_dup 0) (neg:SI (geu:SI (reg:CC 0) (const_int 0))))]
5238 [(set (match_operand:SI 0 "register_operand" "")
5239 (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "")
5241 (match_operand:SI 2 "register_operand" "")))
5242 (clobber (reg:CC 0))]
5244 [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
5246 (set (match_dup 0) (plus:SI (ltu:SI (reg:CC 0) (const_int 0))
5251 [(set (match_operand:SI 0 "register_operand" "")
5252 (minus:SI (match_operand:SI 2 "register_operand" "")
5253 (ne:SI (match_operand:SI 1 "register_operand" "")
5255 (clobber (reg:CC 0))]
5257 [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
5259 (set (match_dup 0) (minus:SI (match_dup 2)
5260 (ltu:SI (reg:CC 0) (const_int 0))))]
5264 [(set (match_operand:SI 0 "register_operand" "")
5265 (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "")
5267 (match_operand:SI 2 "register_operand" "")))
5268 (clobber (reg:CC 0))]
5270 [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
5272 (set (match_dup 0) (plus:SI (geu:SI (reg:CC 0) (const_int 0))
5277 [(set (match_operand:SI 0 "register_operand" "")
5278 (minus:SI (match_operand:SI 2 "register_operand" "")
5279 (eq:SI (match_operand:SI 1 "register_operand" "")
5281 (clobber (reg:CC 0))]
5283 [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
5285 (set (match_dup 0) (minus:SI (match_dup 2)
5286 (geu:SI (reg:CC 0) (const_int 0))))]
5289 ;; Peepholes go at the end.
5291 ;; Optimize consecutive loads or stores into ldd and std when possible.
5292 ;; The conditions in which we do this are very restricted and are
5293 ;; explained in the code for {registers,memory}_ok_for_ldd functions.
5296 [(set (match_operand:SI 0 "register_operand" "=rf")
5297 (match_operand:SI 1 "memory_operand" ""))
5298 (set (match_operand:SI 2 "register_operand" "=rf")
5299 (match_operand:SI 3 "memory_operand" ""))]
5301 && registers_ok_for_ldd_peep (operands[0], operands[2])
5302 && ! MEM_VOLATILE_P (operands[1]) && ! MEM_VOLATILE_P (operands[3])
5303 && addrs_ok_for_ldd_peep (XEXP (operands[1], 0), XEXP (operands[3], 0))"
5307 [(set (match_operand:SI 0 "memory_operand" "")
5308 (match_operand:SI 1 "register_operand" "rf"))
5309 (set (match_operand:SI 2 "memory_operand" "")
5310 (match_operand:SI 3 "register_operand" "rf"))]
5312 && registers_ok_for_ldd_peep (operands[1], operands[3])
5313 && ! MEM_VOLATILE_P (operands[0]) && ! MEM_VOLATILE_P (operands[2])
5314 && addrs_ok_for_ldd_peep (XEXP (operands[0], 0), XEXP (operands[2], 0))"
5318 [(set (match_operand:SF 0 "register_operand" "=fr")
5319 (match_operand:SF 1 "memory_operand" ""))
5320 (set (match_operand:SF 2 "register_operand" "=fr")
5321 (match_operand:SF 3 "memory_operand" ""))]
5323 && registers_ok_for_ldd_peep (operands[0], operands[2])
5324 && ! MEM_VOLATILE_P (operands[1]) && ! MEM_VOLATILE_P (operands[3])
5325 && addrs_ok_for_ldd_peep (XEXP (operands[1], 0), XEXP (operands[3], 0))"
5329 [(set (match_operand:SF 0 "memory_operand" "")
5330 (match_operand:SF 1 "register_operand" "fr"))
5331 (set (match_operand:SF 2 "memory_operand" "")
5332 (match_operand:SF 3 "register_operand" "fr"))]
5334 && registers_ok_for_ldd_peep (operands[1], operands[3])
5335 && ! MEM_VOLATILE_P (operands[0]) && ! MEM_VOLATILE_P (operands[2])
5336 && addrs_ok_for_ldd_peep (XEXP (operands[0], 0), XEXP (operands[2], 0))"
5340 [(set (match_operand:SI 0 "register_operand" "=rf")
5341 (match_operand:SI 1 "memory_operand" ""))
5342 (set (match_operand:SI 2 "register_operand" "=rf")
5343 (match_operand:SI 3 "memory_operand" ""))]
5345 && registers_ok_for_ldd_peep (operands[2], operands[0])
5346 && ! MEM_VOLATILE_P (operands[3]) && ! MEM_VOLATILE_P (operands[1])
5347 && addrs_ok_for_ldd_peep (XEXP (operands[3], 0), XEXP (operands[1], 0))"
5351 [(set (match_operand:SI 0 "memory_operand" "")
5352 (match_operand:SI 1 "register_operand" "rf"))
5353 (set (match_operand:SI 2 "memory_operand" "")
5354 (match_operand:SI 3 "register_operand" "rf"))]
5356 && registers_ok_for_ldd_peep (operands[3], operands[1])
5357 && ! MEM_VOLATILE_P (operands[2]) && ! MEM_VOLATILE_P (operands[0])
5358 && addrs_ok_for_ldd_peep (XEXP (operands[2], 0), XEXP (operands[0], 0))"
5362 [(set (match_operand:SF 0 "register_operand" "=fr")
5363 (match_operand:SF 1 "memory_operand" ""))
5364 (set (match_operand:SF 2 "register_operand" "=fr")
5365 (match_operand:SF 3 "memory_operand" ""))]
5367 && registers_ok_for_ldd_peep (operands[2], operands[0])
5368 && ! MEM_VOLATILE_P (operands[3]) && ! MEM_VOLATILE_P (operands[1])
5369 && addrs_ok_for_ldd_peep (XEXP (operands[3], 0), XEXP (operands[1], 0))"
5373 [(set (match_operand:SF 0 "memory_operand" "")
5374 (match_operand:SF 1 "register_operand" "fr"))
5375 (set (match_operand:SF 2 "memory_operand" "")
5376 (match_operand:SF 3 "register_operand" "fr"))]
5378 && registers_ok_for_ldd_peep (operands[3], operands[1])
5379 && ! MEM_VOLATILE_P (operands[2]) && ! MEM_VOLATILE_P (operands[0])
5380 && addrs_ok_for_ldd_peep (XEXP (operands[2], 0), XEXP (operands[0], 0))"
5383 ;; Optimize the case of following a reg-reg move with a test
5384 ;; of reg just moved. Don't allow floating point regs for operand 0 or 1.
5385 ;; This can result from a float to fix conversion.
5388 [(set (match_operand:SI 0 "register_operand" "=r")
5389 (match_operand:SI 1 "register_operand" "r"))
5391 (compare:CC (match_operand:SI 2 "register_operand" "r")
5393 "(rtx_equal_p (operands[2], operands[0])
5394 || rtx_equal_p (operands[2], operands[1]))
5395 && ! FP_REG_P (operands[0]) && ! FP_REG_P (operands[1])"
5399 [(set (match_operand:DI 0 "register_operand" "=r")
5400 (match_operand:DI 1 "register_operand" "r"))
5402 (compare:CCX (match_operand:DI 2 "register_operand" "r")
5405 && (rtx_equal_p (operands[2], operands[0])
5406 || rtx_equal_p (operands[2], operands[1]))
5407 && ! FP_REG_P (operands[0]) && ! FP_REG_P (operands[1])"
5410 ;; Do {sign,zero}-extended compares somewhat more efficiently.
5411 ;; ??? Is this now the Right Way to do this? Or will SCRATCH
5412 ;; eventually have some impact here?
5415 [(set (match_operand:HI 0 "register_operand" "")
5416 (match_operand:HI 1 "memory_operand" ""))
5417 (set (match_operand:SI 2 "register_operand" "")
5418 (sign_extend:SI (match_dup 0)))
5420 (compare:CC (match_dup 2)
5423 "ldsh %1,%0\;orcc %0,%%g0,%2")
5426 [(set (match_operand:HI 0 "register_operand" "")
5427 (match_operand:HI 1 "memory_operand" ""))
5428 (set (match_operand:DI 2 "register_operand" "")
5429 (sign_extend:DI (match_dup 0)))
5431 (compare:CCX (match_dup 2)
5434 "ldsh %1,%0\;orcc %0,%%g0,%2")
5437 [(set (match_operand:QI 0 "register_operand" "")
5438 (match_operand:QI 1 "memory_operand" ""))
5439 (set (match_operand:SI 2 "register_operand" "")
5440 (sign_extend:SI (match_dup 0)))
5442 (compare:CC (match_dup 2)
5445 "ldsb %1,%0\;orcc %0,%%g0,%2")
5448 [(set (match_operand:QI 0 "register_operand" "")
5449 (match_operand:QI 1 "memory_operand" ""))
5450 (set (match_operand:DI 2 "register_operand" "")
5451 (sign_extend:DI (match_dup 0)))
5453 (compare:CCX (match_dup 2)
5456 "ldsb %1,%0\;orcc %0,%%g0,%2")
5459 [(set (match_operand:HI 0 "register_operand" "")
5460 (match_operand:HI 1 "memory_operand" ""))
5461 (set (match_operand:SI 2 "register_operand" "")
5462 (sign_extend:SI (match_dup 0)))]
5463 "dead_or_set_p (insn, operands[0])"
5466 warning (\"bad peephole\");
5467 if (! MEM_VOLATILE_P (operands[1]))
5469 return \"ldsh %1,%2\";
5473 [(set (match_operand:QI 0 "register_operand" "")
5474 (match_operand:QI 1 "memory_operand" ""))
5475 (set (match_operand:SI 2 "register_operand" "")
5476 (sign_extend:SI (match_dup 0)))]
5477 "dead_or_set_p (insn, operands[0])"
5480 warning (\"bad peephole\");
5481 if (! MEM_VOLATILE_P (operands[1]))
5483 return \"ldsb %1,%2\";
5486 ;; Floating-point move peepholes
5487 ;; ??? v9: Do we want similar ones?
5490 [(set (match_operand:SI 0 "register_operand" "=r")
5491 (lo_sum:SI (match_dup 0)
5492 (match_operand:SI 1 "immediate_operand" "i")))
5493 (set (match_operand:DF 2 "register_operand" "=er")
5494 (mem:DF (match_dup 0)))]
5495 "RTX_UNCHANGING_P (operands[1]) && reg_unused_after (operands[0], insn)"
5498 /* Go by way of output_move_double in case the register in operand 2
5499 is not properly aligned for ldd. */
5500 operands[1] = gen_rtx (MEM, DFmode,
5501 gen_rtx (LO_SUM, SImode, operands[0], operands[1]));
5502 operands[0] = operands[2];
5503 return output_move_double (operands);
5507 [(set (match_operand:SI 0 "register_operand" "=r")
5508 (lo_sum:SI (match_dup 0)
5509 (match_operand:SI 1 "immediate_operand" "i")))
5510 (set (match_operand:SF 2 "register_operand" "=fr")
5511 (mem:SF (match_dup 0)))]
5512 "RTX_UNCHANGING_P (operands[1]) && reg_unused_after (operands[0], insn)"
5513 "ld [%0+%%lo(%a1)],%2")
5515 ;; Return peepholes. First the "normal" ones
5517 ;; ??? There are QImode, HImode, and SImode versions of this pattern.
5518 ;; It might be possible to write one more general pattern instead of three.
5521 [(set (match_operand:QI 0 "restore_operand" "")
5522 (match_operand:QI 1 "arith_operand" "rI"))
5527 if (! TARGET_V9 && current_function_returns_struct)
5528 return \"jmp %%i7+12\;restore %%g0,%1,%Y0\";
5530 return \"ret\;restore %%g0,%1,%Y0\";
5532 [(set_attr "type" "multi")])
5535 [(set (match_operand:HI 0 "restore_operand" "")
5536 (match_operand:HI 1 "arith_operand" "rI"))
5541 if (! TARGET_V9 && current_function_returns_struct)
5542 return \"jmp %%i7+12\;restore %%g0,%1,%Y0\";
5544 return \"ret\;restore %%g0,%1,%Y0\";
5546 [(set_attr "type" "multi")])
5549 [(set (match_operand:SI 0 "restore_operand" "")
5550 (match_operand:SI 1 "arith_operand" "rI"))
5555 if (! TARGET_V9 && current_function_returns_struct)
5556 return \"jmp %%i7+12\;restore %%g0,%1,%Y0\";
5558 return \"ret\;restore %%g0,%1,%Y0\";
5560 [(set_attr "type" "multi")])
5562 ;; The following pattern is only generated by delayed-branch scheduling,
5563 ;; when the insn winds up in the epilogue. This can only happen when
5564 ;; ! TARGET_FPU because otherwise fp return values are in %f0.
5566 [(set (match_operand:SF 0 "restore_operand" "r")
5567 (match_operand:SF 1 "register_operand" "r"))
5569 "! TARGET_FPU && ! TARGET_EPILOGUE"
5572 if (! TARGET_V9 && current_function_returns_struct)
5573 return \"jmp %%i7+12\;restore %%g0,%1,%Y0\";
5575 return \"ret\;restore %%g0,%1,%Y0\";
5577 [(set_attr "type" "multi")])
5580 [(set (match_operand:SI 0 "restore_operand" "")
5581 (plus:SI (match_operand:SI 1 "arith_operand" "%r")
5582 (match_operand:SI 2 "arith_operand" "rI")))
5587 if (! TARGET_V9 && current_function_returns_struct)
5588 return \"jmp %%i7+12\;restore %r1,%2,%Y0\";
5590 return \"ret\;restore %r1,%2,%Y0\";
5592 [(set_attr "type" "multi")])
5595 [(set (match_operand:DI 0 "restore_operand" "")
5596 (match_operand:DI 1 "arith_double_operand" "rHI"))
5598 "TARGET_V9 && ! TARGET_EPILOGUE"
5599 "ret\;restore %%g0,%1,%Y0"
5600 [(set_attr "type" "multi")])
5603 [(set (match_operand:DI 0 "restore_operand" "")
5604 (plus:DI (match_operand:DI 1 "arith_operand" "%r")
5605 (match_operand:DI 2 "arith_double_operand" "rHI")))
5607 "TARGET_V9 && ! TARGET_EPILOGUE"
5608 "ret\;restore %r1,%2,%Y0"
5609 [(set_attr "type" "multi")])
5611 ;; Turned off because it should never match (subtracting a constant
5612 ;; is turned into addition) and because it would do the wrong thing
5613 ;; when operand 2 is -4096 (--4096 == 4096 is not a valid immediate).
5615 ;; [(set (match_operand:SI 0 "restore_operand" "")
5616 ;; (minus:SI (match_operand:SI 1 "register_operand" "r")
5617 ;; (match_operand:SI 2 "small_int" "I")))
5619 ;; "! TARGET_EPILOGUE"
5620 ;; "ret\;restore %1,-(%2),%Y0"
5621 ;; [(set_attr "type" "multi")])
5623 ;; The following pattern is only generated by delayed-branch scheduling,
5624 ;; when the insn winds up in the epilogue.
5627 (match_operand:SF 0 "register_operand" "f"))
5630 "ret\;fmovs %0,%%f0"
5631 [(set_attr "type" "multi")])
5633 ;; Now peepholes to do a call followed by a jump.
5636 [(parallel [(set (match_operand 0 "" "")
5637 (call (mem:SI (match_operand:SI 1 "call_operand_address" "ps"))
5638 (match_operand 2 "" "")))
5639 (clobber (reg:SI 15))])
5640 (set (pc) (label_ref (match_operand 3 "" "")))]
5641 "short_branch (INSN_UID (insn), INSN_UID (operands[3]))"
5644 return \"call %a1,%2\;add %%o7,(%l3-.-4),%%o7\";
5648 [(parallel [(call (mem:SI (match_operand:SI 0 "call_operand_address" "ps"))
5649 (match_operand 1 "" ""))
5650 (clobber (reg:SI 15))])
5651 (set (pc) (label_ref (match_operand 2 "" "")))]
5652 "short_branch (INSN_UID (insn), INSN_UID (operands[2]))"
5655 return \"call %a0,%1\;add %%o7,(%l2-.-4),%%o7\";
5659 [(parallel [(set (match_operand 0 "" "")
5660 (call (mem:SI (match_operand:DI 1 "call_operand_address" "ps"))
5661 (match_operand 2 "" "")))
5662 (clobber (reg:DI 15))])
5663 (set (pc) (label_ref (match_operand 3 "" "")))]
5664 "TARGET_V9 && short_branch (INSN_UID (insn), INSN_UID (operands[3]))"
5667 return \"call %a1,%2\;add %%o7,(%l3-.-4),%%o7\";
5671 [(parallel [(call (mem:SI (match_operand:DI 0 "call_operand_address" "ps"))
5672 (match_operand 1 "" ""))
5673 (clobber (reg:DI 15))])
5674 (set (pc) (label_ref (match_operand 2 "" "")))]
5675 "TARGET_V9 && short_branch (INSN_UID (insn), INSN_UID (operands[2]))"
5678 return \"call %a0,%1\;add %%o7,(%l2-.-4),%%o7\";
5681 ;; Other miscellaneous peepholes.
5684 [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
5685 (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5687 (clobber (reg:CC 0))])
5688 (set (reg:CC 0) (compare (match_dup 0) (const_int 0)))]