1 ;;- Machine description for SPARC chip for GNU C compiler
2 ;; Copyright (C) 1987, 88, 89, 92-95, 1996 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, 59 Temple Place - Suite 330,
22 ;; Boston, MA 02111-1307, USA.
24 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
26 ;; The upper 32 fp regs on the v9 can't hold SFmode values. To deal with this
27 ;; a second register class, EXTRA_FP_REGS, exists for the v9 chip. The name
28 ;; is a bit of a misnomer as it covers all 64 fp regs. The corresponding
29 ;; constraint letter is 'e'. To avoid any confusion, 'e' is used instead of
30 ;; 'f' for all DF/TFmode values, including those that are specific to the v8.
32 ;; Attribute for cpu type.
33 ;; These must match the values for enum processor_type in sparc.h.
34 (define_attr "cpu" "v7,cypress,v8,supersparc,sparclite,f930,f934,sparclet,90c701,v8plus,v9,ultrasparc"
35 (const (symbol_ref "sparc_cpu_attr")))
37 ;; Attribute for the instruction set.
38 ;; At present we only need to distinguish v9/!v9, but for clarity we
39 ;; test TARGET_V8 too.
40 (define_attr "isa" "v6,v8,v9"
42 (cond [(symbol_ref "TARGET_V9") (const_string "v9")
43 (symbol_ref "TARGET_V8") (const_string "v8")]
44 (const_string "v6"))))
47 (define_attr "arch" "arch32bit,arch64bit"
49 (cond [(symbol_ref "TARGET_ARCH64") (const_string "arch64bit")]
50 (const_string "arch32bit"))))
52 ;; Insn type. Used to default other attribute values.
54 ;; type "unary" insns have one input operand (1) and one output operand (0)
55 ;; type "binary" insns have two input operands (1,2) and one output (0)
56 ;; type "compare" insns have one or two input operands (0,1) and no output
57 ;; type "call_no_delay_slot" is a call followed by an unimp instruction.
60 "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"
61 (const_string "binary"))
63 ;; Set true if insn uses call-clobbered intermediate register.
64 (define_attr "use_clobbered" "false,true"
65 (if_then_else (and (eq_attr "type" "address")
66 (match_operand 0 "clobbered_register" ""))
68 (const_string "false")))
70 ;; Length (in # of insns).
71 (define_attr "length" ""
72 (cond [(eq_attr "type" "load,fpload")
73 (if_then_else (match_operand 1 "symbolic_memory_operand" "")
74 (const_int 2) (const_int 1))
76 (eq_attr "type" "store,fpstore")
77 (if_then_else (match_operand 0 "symbolic_memory_operand" "")
78 (const_int 2) (const_int 1))
80 (eq_attr "type" "address") (const_int 2)
82 (eq_attr "type" "binary")
83 (if_then_else (ior (match_operand 2 "arith_operand" "")
84 (match_operand 2 "arith_double_operand" ""))
85 (const_int 1) (const_int 3))
87 (eq_attr "type" "multi") (const_int 2)
89 (eq_attr "type" "move,unary")
90 (if_then_else (ior (match_operand 1 "arith_operand" "")
91 (match_operand 1 "arith_double_operand" ""))
92 (const_int 1) (const_int 2))]
96 (define_asm_attributes
97 [(set_attr "length" "1")
98 (set_attr "type" "multi")])
100 ;; Attributes for instruction and branch scheduling
102 (define_attr "in_call_delay" "false,true"
103 (cond [(eq_attr "type" "uncond_branch,branch,call,call_no_delay_slot,multi")
104 (const_string "false")
105 (eq_attr "type" "load,fpload,store,fpstore")
106 (if_then_else (eq_attr "length" "1")
107 (const_string "true")
108 (const_string "false"))
109 (eq_attr "type" "address")
110 (if_then_else (eq_attr "use_clobbered" "false")
111 (const_string "true")
112 (const_string "false"))]
113 (if_then_else (eq_attr "length" "1")
114 (const_string "true")
115 (const_string "false"))))
117 (define_delay (eq_attr "type" "call")
118 [(eq_attr "in_call_delay" "true") (nil) (nil)])
120 ;; ??? Should implement the notion of predelay slots for floating point
121 ;; branches. This would allow us to remove the nop always inserted before
122 ;; a floating point branch.
124 ;; ??? It is OK for fill_simple_delay_slots to put load/store instructions
125 ;; in a delay slot, but it is not OK for fill_eager_delay_slots to do so.
126 ;; This is because doing so will add several pipeline stalls to the path
127 ;; that the load/store did not come from. Unfortunately, there is no way
128 ;; to prevent fill_eager_delay_slots from using load/store without completely
129 ;; disabling them. For the SPEC benchmark set, this is a serious lose,
130 ;; because it prevents us from moving back the final store of inner loops.
132 (define_attr "in_branch_delay" "false,true"
133 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,call_no_delay_slot,multi")
134 (eq_attr "length" "1"))
135 (const_string "true")
136 (const_string "false")))
138 (define_attr "in_uncond_branch_delay" "false,true"
139 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,call_no_delay_slot,multi")
140 (eq_attr "length" "1"))
141 (const_string "true")
142 (const_string "false")))
144 (define_attr "in_annul_branch_delay" "false,true"
145 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,call_no_delay_slot,multi")
146 (eq_attr "length" "1"))
147 (const_string "true")
148 (const_string "false")))
150 (define_delay (eq_attr "type" "branch")
151 [(eq_attr "in_branch_delay" "true")
152 (nil) (eq_attr "in_annul_branch_delay" "true")])
154 (define_delay (eq_attr "type" "uncond_branch")
155 [(eq_attr "in_uncond_branch_delay" "true")
158 ;; Function units of the SPARC
160 ;; (define_function_unit {name} {num-units} {n-users} {test}
161 ;; {ready-delay} {issue-delay} [{conflict-list}])
164 ;; (Noted only for documentation; units that take one cycle do not need to
167 ;; On the sparclite, integer multiply takes 1, 3, or 5 cycles depending on
170 ;; (define_function_unit "alu" 1 0
171 ;; (eq_attr "type" "unary,binary,move,address") 1 0)
173 ;; ---- cypress CY7C602 scheduling:
174 ;; Memory with load-delay of 1 (i.e., 2 cycle load).
175 (define_function_unit "memory" 1 0
176 (and (eq_attr "type" "load,fpload") (eq_attr "cpu" "cypress")) 2 2)
178 ;; SPARC has two floating-point units: the FP ALU,
179 ;; and the FP MUL/DIV/SQRT unit.
180 ;; Instruction timings on the CY7C602 are as follows
194 ;; The CY7C602 can only support 2 fp isnsn simultaneously.
195 ;; More insns cause the chip to stall.
197 (define_function_unit "fp_alu" 1 0
198 (and (eq_attr "type" "fp") (eq_attr "cpu" "cypress")) 5 5)
199 (define_function_unit "fp_mds" 1 0
200 (and (eq_attr "type" "fpmul") (eq_attr "cpu" "cypress")) 7 7)
201 (define_function_unit "fp_mds" 1 0
202 (and (eq_attr "type" "fpdivs,fpdivd") (eq_attr "cpu" "cypress")) 37 37)
203 (define_function_unit "fp_mds" 1 0
204 (and (eq_attr "type" "fpsqrt") (eq_attr "cpu" "cypress")) 63 63)
206 ;; ----- The TMS390Z55 scheduling
207 ;; The Supersparc can issue 1 - 3 insns per cycle; here we assume
208 ;; three insns/cycle, and hence multiply all costs by three.
209 ;; Combinations up to two integer, one ld/st, one fp.
210 ;; Memory delivers its result in one cycle to IU, zero cycles to FP
211 (define_function_unit "memory" 1 0
212 (and (eq_attr "type" "load") (eq_attr "cpu" "supersparc")) 3 3)
213 (define_function_unit "memory" 1 0
214 (and (eq_attr "type" "fpload") (eq_attr "cpu" "supersparc")) 1 3)
215 ;; at least one in three instructions can be a mem opt.
216 (define_function_unit "memory" 1 0
217 (and (eq_attr "type" "store,fpstore") (eq_attr "cpu" "supersparc")) 1 3)
218 ;; at least one in three instructions can be a shift op.
219 (define_function_unit "shift" 1 0
220 (and (eq_attr "type" "shift") (eq_attr "cpu" "supersparc")) 1 3)
222 ;; There are only two write ports to the integer register file
223 ;; A store also uses a write port
224 (define_function_unit "iwport" 2 0
225 (and (eq_attr "type" "load,store,shift,ialu") (eq_attr "cpu" "supersparc")) 1 3)
227 ;; Timings; throughput/latency
228 ;; FADD 1/3 add/sub, format conv, compar, abs, neg
236 (define_function_unit "fp_alu" 1 0
237 (and (eq_attr "type" "fp,fpcmp") (eq_attr "cpu" "supersparc")) 9 3)
238 (define_function_unit "fp_mds" 1 0
239 (and (eq_attr "type" "fpmul") (eq_attr "cpu" "supersparc")) 9 3)
240 (define_function_unit "fp_mds" 1 0
241 (and (eq_attr "type" "fpdivs") (eq_attr "cpu" "supersparc")) 18 12)
242 (define_function_unit "fp_mds" 1 0
243 (and (eq_attr "type" "fpdivd") (eq_attr "cpu" "supersparc")) 27 21)
244 (define_function_unit "fp_mds" 1 0
245 (and (eq_attr "type" "fpsqrt") (eq_attr "cpu" "supersparc")) 36 30)
246 (define_function_unit "fp_mds" 1 0
247 (and (eq_attr "type" "imul") (eq_attr "cpu" "supersparc")) 12 12)
249 ;; Compare instructions.
250 ;; This controls RTL generation and register allocation.
252 ;; We generate RTL for comparisons and branches by having the cmpxx
253 ;; patterns store away the operands. Then, the scc and bcc patterns
254 ;; emit RTL for both the compare and the branch.
256 ;; We do this because we want to generate different code for an sne and
257 ;; seq insn. In those cases, if the second operand of the compare is not
258 ;; const0_rtx, we want to compute the xor of the two operands and test
261 ;; We start with the DEFINE_EXPANDs, then the DEFINE_INSNs to match
262 ;; the patterns. Finally, we have the DEFINE_SPLITs for some of the scc
263 ;; insns that actually require more than one machine instruction.
265 ;; Put cmpsi first among compare insns so it matches two CONST_INT operands.
267 (define_expand "cmpsi"
269 (compare:CC (match_operand:SI 0 "register_operand" "")
270 (match_operand:SI 1 "arith_operand" "")))]
274 sparc_compare_op0 = operands[0];
275 sparc_compare_op1 = operands[1];
279 (define_expand "cmpdi"
281 (compare:CCX (match_operand:DI 0 "register_operand" "")
282 (match_operand:DI 1 "arith_double_operand" "")))]
286 sparc_compare_op0 = operands[0];
287 sparc_compare_op1 = operands[1];
291 (define_expand "cmpsf"
293 (compare:CCFP (match_operand:SF 0 "register_operand" "")
294 (match_operand:SF 1 "register_operand" "")))]
298 sparc_compare_op0 = operands[0];
299 sparc_compare_op1 = operands[1];
303 (define_expand "cmpdf"
305 (compare:CCFP (match_operand:DF 0 "register_operand" "")
306 (match_operand:DF 1 "register_operand" "")))]
310 sparc_compare_op0 = operands[0];
311 sparc_compare_op1 = operands[1];
315 (define_expand "cmptf"
317 (compare:CCFP (match_operand:TF 0 "register_operand" "")
318 (match_operand:TF 1 "register_operand" "")))]
322 sparc_compare_op0 = operands[0];
323 sparc_compare_op1 = operands[1];
327 ;; Next come the scc insns. For seq, sne, sgeu, and sltu, we can do this
328 ;; without jumps using the addx/subx instructions. For seq/sne on v9 we use
329 ;; the same code as v8 (the addx/subx method has more applications). The
330 ;; exception to this is "reg != 0" which can be done in one instruction on v9
331 ;; (so we do it). For the rest, on v9 we use conditional moves; on v8, we do
334 ;; Seq_special[_xxx] and sne_special[_xxx] clobber the CC reg, because they
335 ;; generate addcc/subcc instructions.
337 (define_expand "seqsi_special"
339 (xor:SI (match_operand:SI 1 "register_operand" "")
340 (match_operand:SI 2 "register_operand" "")))
341 (parallel [(set (match_operand:SI 0 "register_operand" "")
342 (eq:SI (match_dup 3) (const_int 0)))
343 (clobber (reg:CC 0))])]
345 "{ operands[3] = gen_reg_rtx (SImode); }")
347 (define_expand "seqdi_special"
349 (xor:DI (match_operand:DI 1 "register_operand" "")
350 (match_operand:DI 2 "register_operand" "")))
351 (parallel [(set (match_operand:DI 0 "register_operand" "")
352 (eq:DI (match_dup 3) (const_int 0)))
353 (clobber (reg:CCX 0))])]
355 "{ operands[3] = gen_reg_rtx (DImode); }")
357 (define_expand "snesi_special"
359 (xor:SI (match_operand:SI 1 "register_operand" "")
360 (match_operand:SI 2 "register_operand" "")))
361 (parallel [(set (match_operand:SI 0 "register_operand" "")
362 (ne:SI (match_dup 3) (const_int 0)))
363 (clobber (reg:CC 0))])]
365 "{ operands[3] = gen_reg_rtx (SImode); }")
367 (define_expand "snedi_special"
369 (xor:DI (match_operand:DI 1 "register_operand" "")
370 (match_operand:DI 2 "register_operand" "")))
371 (parallel [(set (match_operand:DI 0 "register_operand" "")
372 (ne:DI (match_dup 3) (const_int 0)))
373 (clobber (reg:CCX 0))])]
375 "{ operands[3] = gen_reg_rtx (DImode); }")
377 (define_expand "seqdi_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 (eq:DI (match_dup 3) (const_int 0)))
383 (clobber (reg:CCX 0))])]
385 "{ operands[3] = gen_reg_rtx (DImode); }")
387 (define_expand "snedi_special_trunc"
389 (xor:DI (match_operand:DI 1 "register_operand" "")
390 (match_operand:DI 2 "register_operand" "")))
391 (parallel [(set (match_operand:SI 0 "register_operand" "")
392 (ne:DI (match_dup 3) (const_int 0)))
393 (clobber (reg:CCX 0))])]
395 "{ operands[3] = gen_reg_rtx (DImode); }")
397 (define_expand "seqsi_special_extend"
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 (eq:SI (match_dup 3) (const_int 0)))
403 (clobber (reg:CC 0))])]
405 "{ operands[3] = gen_reg_rtx (SImode); }")
407 (define_expand "snesi_special_extend"
409 (xor:SI (match_operand:SI 1 "register_operand" "")
410 (match_operand:SI 2 "register_operand" "")))
411 (parallel [(set (match_operand:DI 0 "register_operand" "")
412 (ne:SI (match_dup 3) (const_int 0)))
413 (clobber (reg:CC 0))])]
415 "{ operands[3] = gen_reg_rtx (SImode); }")
417 ;; ??? v9: Operand 0 needs a mode, so SImode was chosen.
418 ;; However, the code handles both SImode and DImode.
420 [(set (match_operand:SI 0 "intreg_operand" "")
421 (eq:SI (match_dup 1) (const_int 0)))]
425 if (GET_MODE (sparc_compare_op0) == SImode)
429 if (GET_MODE (operands[0]) == SImode)
430 pat = gen_seqsi_special (operands[0], sparc_compare_op0,
432 else if (! TARGET_ARCH64)
435 pat = gen_seqsi_special_extend (operands[0], sparc_compare_op0,
440 else if (GET_MODE (sparc_compare_op0) == DImode)
446 else if (GET_MODE (operands[0]) == SImode)
447 pat = gen_seqdi_special_trunc (operands[0], sparc_compare_op0,
450 pat = gen_seqdi_special (operands[0], sparc_compare_op0,
455 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
457 emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, EQ);
458 emit_insn (gen_sne (operands[0]));
463 if (gen_v9_scc (EQ, operands))
467 operands[1] = gen_compare_reg (EQ, sparc_compare_op0, sparc_compare_op1);
470 ;; ??? v9: Operand 0 needs a mode, so SImode was chosen.
471 ;; However, the code handles both SImode and DImode.
473 [(set (match_operand:SI 0 "intreg_operand" "")
474 (ne:SI (match_dup 1) (const_int 0)))]
478 if (GET_MODE (sparc_compare_op0) == SImode)
482 if (GET_MODE (operands[0]) == SImode)
483 pat = gen_snesi_special (operands[0], sparc_compare_op0,
485 else if (! TARGET_ARCH64)
488 pat = gen_snesi_special_extend (operands[0], sparc_compare_op0,
493 else if (GET_MODE (sparc_compare_op0) == DImode)
499 else if (GET_MODE (operands[0]) == SImode)
500 pat = gen_snedi_special_trunc (operands[0], sparc_compare_op0,
503 pat = gen_snedi_special (operands[0], sparc_compare_op0,
508 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
510 emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, NE);
511 emit_insn (gen_sne (operands[0]));
516 if (gen_v9_scc (NE, operands))
520 operands[1] = gen_compare_reg (NE, sparc_compare_op0, sparc_compare_op1);
524 [(set (match_operand:SI 0 "intreg_operand" "")
525 (gt:SI (match_dup 1) (const_int 0)))]
529 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
531 emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GT);
532 emit_insn (gen_sne (operands[0]));
537 if (gen_v9_scc (GT, operands))
541 operands[1] = gen_compare_reg (GT, sparc_compare_op0, sparc_compare_op1);
545 [(set (match_operand:SI 0 "intreg_operand" "")
546 (lt:SI (match_dup 1) (const_int 0)))]
550 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
552 emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LT);
553 emit_insn (gen_sne (operands[0]));
558 if (gen_v9_scc (LT, operands))
562 operands[1] = gen_compare_reg (LT, sparc_compare_op0, sparc_compare_op1);
566 [(set (match_operand:SI 0 "intreg_operand" "")
567 (ge:SI (match_dup 1) (const_int 0)))]
571 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
573 emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GE);
574 emit_insn (gen_sne (operands[0]));
579 if (gen_v9_scc (GE, operands))
583 operands[1] = gen_compare_reg (GE, sparc_compare_op0, sparc_compare_op1);
587 [(set (match_operand:SI 0 "intreg_operand" "")
588 (le:SI (match_dup 1) (const_int 0)))]
592 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
594 emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LE);
595 emit_insn (gen_sne (operands[0]));
600 if (gen_v9_scc (LE, operands))
604 operands[1] = gen_compare_reg (LE, sparc_compare_op0, sparc_compare_op1);
607 (define_expand "sgtu"
608 [(set (match_operand:SI 0 "intreg_operand" "")
609 (gtu:SI (match_dup 1) (const_int 0)))]
617 /* We can do ltu easily, so if both operands are registers, swap them and
619 if ((GET_CODE (sparc_compare_op0) == REG
620 || GET_CODE (sparc_compare_op0) == SUBREG)
621 && (GET_CODE (sparc_compare_op1) == REG
622 || GET_CODE (sparc_compare_op1) == SUBREG))
624 tem = sparc_compare_op0;
625 sparc_compare_op0 = sparc_compare_op1;
626 sparc_compare_op1 = tem;
627 emit_insn (gen_sltu (operands[0]));
633 if (gen_v9_scc (GTU, operands))
636 operands[1] = gen_compare_reg (GTU, sparc_compare_op0, sparc_compare_op1);
639 (define_expand "sltu"
640 [(set (match_operand:SI 0 "intreg_operand" "")
641 (ltu:SI (match_dup 1) (const_int 0)))]
647 if (gen_v9_scc (LTU, operands))
650 operands[1] = gen_compare_reg (LTU, sparc_compare_op0, sparc_compare_op1);
653 (define_expand "sgeu"
654 [(set (match_operand:SI 0 "intreg_operand" "")
655 (geu:SI (match_dup 1) (const_int 0)))]
661 if (gen_v9_scc (GEU, operands))
664 operands[1] = gen_compare_reg (GEU, sparc_compare_op0, sparc_compare_op1);
667 (define_expand "sleu"
668 [(set (match_operand:SI 0 "intreg_operand" "")
669 (leu:SI (match_dup 1) (const_int 0)))]
677 /* We can do geu easily, so if both operands are registers, swap them and
679 if ((GET_CODE (sparc_compare_op0) == REG
680 || GET_CODE (sparc_compare_op0) == SUBREG)
681 && (GET_CODE (sparc_compare_op1) == REG
682 || GET_CODE (sparc_compare_op1) == SUBREG))
684 tem = sparc_compare_op0;
685 sparc_compare_op0 = sparc_compare_op1;
686 sparc_compare_op1 = tem;
687 emit_insn (gen_sgeu (operands[0]));
693 if (gen_v9_scc (LEU, operands))
696 operands[1] = gen_compare_reg (LEU, sparc_compare_op0, sparc_compare_op1);
699 ;; Now the DEFINE_INSNs for the compare and scc cases. First the compares.
701 (define_insn "*cmpsi_insn"
703 (compare:CC (match_operand:SI 0 "register_operand" "r")
704 (match_operand:SI 1 "arith_operand" "rI")))]
707 [(set_attr "type" "compare")])
709 (define_insn "*cmpsf_fpe_sp32"
711 (compare:CCFPE (match_operand:SF 0 "register_operand" "f")
712 (match_operand:SF 1 "register_operand" "f")))]
713 "! TARGET_V9 && TARGET_FPU"
715 [(set_attr "type" "fpcmp")])
717 (define_insn "*cmpdf_fpe_sp32"
719 (compare:CCFPE (match_operand:DF 0 "register_operand" "e")
720 (match_operand:DF 1 "register_operand" "e")))]
721 "! TARGET_V9 && TARGET_FPU"
723 [(set_attr "type" "fpcmp")])
725 (define_insn "*cmptf_fpe_sp32"
727 (compare:CCFPE (match_operand:TF 0 "register_operand" "e")
728 (match_operand:TF 1 "register_operand" "e")))]
729 "! TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
731 [(set_attr "type" "fpcmp")])
733 (define_insn "*cmpsf_fp_sp32"
735 (compare:CCFP (match_operand:SF 0 "register_operand" "f")
736 (match_operand:SF 1 "register_operand" "f")))]
737 "! TARGET_V9 && TARGET_FPU"
739 [(set_attr "type" "fpcmp")])
741 (define_insn "*cmpdf_fp_sp32"
743 (compare:CCFP (match_operand:DF 0 "register_operand" "e")
744 (match_operand:DF 1 "register_operand" "e")))]
745 "! TARGET_V9 && TARGET_FPU"
747 [(set_attr "type" "fpcmp")])
749 (define_insn "*cmptf_fp_sp32"
751 (compare:CCFP (match_operand:TF 0 "register_operand" "e")
752 (match_operand:TF 1 "register_operand" "e")))]
753 "! TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
755 [(set_attr "type" "fpcmp")])
757 (define_insn "*cmpdi_sp64"
759 (compare:CCX (match_operand:DI 0 "register_operand" "r")
760 (match_operand:DI 1 "arith_double_operand" "rHI")))]
763 [(set_attr "type" "compare")])
765 (define_insn "*cmpsf_fpe_sp64"
766 [(set (match_operand:CCFPE 0 "ccfp_reg_operand" "=c")
767 (compare:CCFPE (match_operand:SF 1 "register_operand" "f")
768 (match_operand:SF 2 "register_operand" "f")))]
769 "TARGET_V9 && TARGET_FPU"
771 [(set_attr "type" "fpcmp")])
773 (define_insn "*cmpdf_fpe_sp64"
774 [(set (match_operand:CCFPE 0 "ccfp_reg_operand" "=c")
775 (compare:CCFPE (match_operand:DF 1 "register_operand" "e")
776 (match_operand:DF 2 "register_operand" "e")))]
777 "TARGET_V9 && TARGET_FPU"
779 [(set_attr "type" "fpcmp")])
781 (define_insn "*cmptf_fpe_sp64"
782 [(set (match_operand:CCFPE 0 "ccfp_reg_operand" "=c")
783 (compare:CCFPE (match_operand:TF 1 "register_operand" "e")
784 (match_operand:TF 2 "register_operand" "e")))]
785 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
787 [(set_attr "type" "fpcmp")])
789 (define_insn "*cmpsf_fp_sp64"
790 [(set (match_operand:CCFP 0 "ccfp_reg_operand" "=c")
791 (compare:CCFP (match_operand:SF 1 "register_operand" "f")
792 (match_operand:SF 2 "register_operand" "f")))]
793 "TARGET_V9 && TARGET_FPU"
795 [(set_attr "type" "fpcmp")])
797 (define_insn "*cmpdf_fp_sp64"
798 [(set (match_operand:CCFP 0 "ccfp_reg_operand" "=c")
799 (compare:CCFP (match_operand:DF 1 "register_operand" "e")
800 (match_operand:DF 2 "register_operand" "e")))]
801 "TARGET_V9 && TARGET_FPU"
803 [(set_attr "type" "fpcmp")])
805 (define_insn "*cmptf_fp_sp64"
806 [(set (match_operand:CCFP 0 "ccfp_reg_operand" "=c")
807 (compare:CCFP (match_operand:TF 1 "register_operand" "e")
808 (match_operand:TF 2 "register_operand" "e")))]
809 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
811 [(set_attr "type" "fpcmp")])
813 ;; The SEQ and SNE patterns are special because they can be done
814 ;; without any branching and do not involve a COMPARE.
816 (define_insn "*snesi_zero"
817 [(set (match_operand:SI 0 "register_operand" "=r")
818 (ne:SI (match_operand:SI 1 "register_operand" "r")
820 (clobber (reg:CC 0))]
822 "subcc %%g0,%1,%%g0\;addx %%g0,0,%0"
823 [(set_attr "type" "unary")
824 (set_attr "length" "2")])
826 (define_insn "*neg_snesi_zero"
827 [(set (match_operand:SI 0 "register_operand" "=r")
828 (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
830 (clobber (reg:CC 0))]
832 "subcc %%g0,%1,%%g0\;subx %%g0,0,%0"
833 [(set_attr "type" "unary")
834 (set_attr "length" "2")])
836 (define_insn "*snesi_zero_extend"
837 [(set (match_operand:DI 0 "register_operand" "=r")
838 (ne:SI (match_operand:SI 1 "register_operand" "r")
840 (clobber (reg:CC 0))]
842 "subcc %%g0,%1,%%g0\;addx %%g0,0,%0"
843 [(set_attr "type" "unary")
844 (set_attr "length" "2")])
846 (define_insn "*snedi_zero"
847 [(set (match_operand:DI 0 "register_operand" "=r")
848 (ne:DI (match_operand:DI 1 "register_operand" "r")
850 (clobber (reg:CCX 0))]
852 "mov 0,%0\;movrnz %1,1,%0"
853 [(set_attr "type" "unary")
854 (set_attr "length" "2")])
856 (define_insn "*neg_snedi_zero"
857 [(set (match_operand:DI 0 "register_operand" "=r")
858 (neg:DI (ne:DI (match_operand:DI 1 "register_operand" "r")
860 (clobber (reg:CCX 0))]
862 "mov 0,%0\;movrnz %1,-1,%0"
863 [(set_attr "type" "unary")
864 (set_attr "length" "2")])
866 (define_insn "*snedi_zero_trunc_sp32"
867 [(set (match_operand:SI 0 "register_operand" "=r")
868 (ne:DI (match_operand:DI 1 "register_operand" "r")
870 (clobber (reg:CCX 0))]
872 "xor %1,%R1,%0\;subcc %%g0,%0,%%g0\;addx %%g0,0,%0"
873 [(set_attr "type" "unary")
874 (set_attr "length" "3")])
876 (define_insn "*snedi_zero_trunc_sp64"
877 [(set (match_operand:SI 0 "register_operand" "=r")
878 (ne:DI (match_operand:DI 1 "register_operand" "r")
880 (clobber (reg:CCX 0))]
882 "mov 0,%0\;movrnz %1,1,%0"
883 [(set_attr "type" "unary")
884 (set_attr "length" "2")])
886 (define_insn "*seqsi_zero"
887 [(set (match_operand:SI 0 "register_operand" "=r")
888 (eq:SI (match_operand:SI 1 "register_operand" "r")
890 (clobber (reg:CC 0))]
892 "subcc %%g0,%1,%%g0\;subx %%g0,-1,%0"
893 [(set_attr "type" "unary")
894 (set_attr "length" "2")])
896 (define_insn "*neg_seqsi_zero"
897 [(set (match_operand:SI 0 "register_operand" "=r")
898 (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
900 (clobber (reg:CC 0))]
902 "subcc %%g0,%1,%%g0\;addx %%g0,-1,%0"
903 [(set_attr "type" "unary")
904 (set_attr "length" "2")])
906 (define_insn "*seqsi_zero_extend"
907 [(set (match_operand:DI 0 "register_operand" "=r")
908 (eq:SI (match_operand:SI 1 "register_operand" "r")
910 (clobber (reg:CC 0))]
912 "subcc %%g0,%1,%%g0\;subx %%g0,-1,%0"
913 [(set_attr "type" "unary")
914 (set_attr "length" "2")])
916 (define_insn "*seqdi_zero"
917 [(set (match_operand:DI 0 "register_operand" "=r")
918 (eq:DI (match_operand:DI 1 "register_operand" "r")
920 (clobber (reg:CCX 0))]
922 "mov 0,%0\;movrz %1,1,%0"
923 [(set_attr "type" "unary")
924 (set_attr "length" "2")])
926 (define_insn "*neg_seqdi_zero"
927 [(set (match_operand:DI 0 "register_operand" "=r")
928 (neg:DI (eq:DI (match_operand:DI 1 "register_operand" "r")
930 (clobber (reg:CCX 0))]
932 "mov 0,%0\;movrz %1,-1,%0"
933 [(set_attr "type" "unary")
934 (set_attr "length" "2")])
936 (define_insn "*seqdi_zero_trunc_sp32"
937 [(set (match_operand:SI 0 "register_operand" "=r")
938 (eq:DI (match_operand:DI 1 "register_operand" "r")
940 (clobber (reg:CCX 0))]
942 "xor %1,%R1,%0\;subcc %%g0,%0,%%g0\;subx %%g0,-1,%0"
943 [(set_attr "type" "unary")
944 (set_attr "length" "3")])
946 (define_insn "*seqdi_zero_trunc_sp64"
947 [(set (match_operand:SI 0 "register_operand" "=r")
948 (eq:DI (match_operand:DI 1 "register_operand" "r")
950 (clobber (reg:CCX 0))]
952 "mov 0,%0\;movrz %1,1,%0"
953 [(set_attr "type" "unary")
954 (set_attr "length" "2")])
956 ;; We can also do (x + (i == 0)) and related, so put them in.
957 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
960 (define_insn "*x_plus_i_ne_0"
961 [(set (match_operand:SI 0 "register_operand" "=r")
962 (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
964 (match_operand:SI 2 "register_operand" "r")))
965 (clobber (reg:CC 0))]
967 "subcc %%g0,%1,%%g0\;addx %2,0,%0"
968 [(set_attr "length" "2")])
970 (define_insn "*x_minus_i_ne_0"
971 [(set (match_operand:SI 0 "register_operand" "=r")
972 (minus:SI (match_operand:SI 2 "register_operand" "r")
973 (ne:SI (match_operand:SI 1 "register_operand" "r")
975 (clobber (reg:CC 0))]
977 "subcc %%g0,%1,%%g0\;subx %2,0,%0"
978 [(set_attr "length" "2")])
980 (define_insn "*x_plus_i_eq_0"
981 [(set (match_operand:SI 0 "register_operand" "=r")
982 (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
984 (match_operand:SI 2 "register_operand" "r")))
985 (clobber (reg:CC 0))]
987 "subcc %%g0,%1,%%g0\;subx %2,-1,%0"
988 [(set_attr "length" "2")])
990 (define_insn "*x_minus_i_eq_0"
991 [(set (match_operand:SI 0 "register_operand" "=r")
992 (minus:SI (match_operand:SI 2 "register_operand" "r")
993 (eq:SI (match_operand:SI 1 "register_operand" "r")
995 (clobber (reg:CC 0))]
997 "subcc %%g0,%1,%%g0\;addx %2,-1,%0"
998 [(set_attr "length" "2")])
1000 ;; We can also do GEU and LTU directly, but these operate after a compare.
1001 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1004 (define_insn "*sltu_insn"
1005 [(set (match_operand:SI 0 "register_operand" "=r")
1006 (ltu:SI (reg:CC 0) (const_int 0)))]
1009 [(set_attr "type" "misc")])
1011 (define_insn "*neg_sltu_insn"
1012 [(set (match_operand:SI 0 "register_operand" "=r")
1013 (neg:SI (ltu:SI (reg:CC 0) (const_int 0))))]
1016 [(set_attr "type" "misc")])
1018 ;; ??? Combine should canonicalize these next two to the same pattern.
1019 (define_insn "*neg_sltu_minus_x"
1020 [(set (match_operand:SI 0 "register_operand" "=r")
1021 (minus:SI (neg:SI (ltu:SI (reg:CC 0) (const_int 0)))
1022 (match_operand:SI 1 "arith_operand" "rI")))]
1025 [(set_attr "type" "unary")])
1027 (define_insn "*neg_sltu_plus_x"
1028 [(set (match_operand:SI 0 "register_operand" "=r")
1029 (neg:SI (plus:SI (ltu:SI (reg:CC 0) (const_int 0))
1030 (match_operand:SI 1 "arith_operand" "rI"))))]
1033 [(set_attr "type" "unary")])
1035 (define_insn "*sgeu_insn"
1036 [(set (match_operand:SI 0 "register_operand" "=r")
1037 (geu:SI (reg:CC 0) (const_int 0)))]
1040 [(set_attr "type" "misc")])
1042 (define_insn "*neg_sgeu_insn"
1043 [(set (match_operand:SI 0 "register_operand" "=r")
1044 (neg:SI (geu:SI (reg:CC 0) (const_int 0))))]
1047 [(set_attr "type" "misc")])
1049 ;; We can also do (x + ((unsigned) i >= 0)) and related, so put them in.
1050 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1053 (define_insn "*sltu_plus_x"
1054 [(set (match_operand:SI 0 "register_operand" "=r")
1055 (plus:SI (ltu:SI (reg:CC 0) (const_int 0))
1056 (match_operand:SI 1 "arith_operand" "rI")))]
1059 [(set_attr "type" "unary")])
1061 (define_insn "*sltu_plus_x_plus_y"
1062 [(set (match_operand:SI 0 "register_operand" "=r")
1063 (plus:SI (ltu:SI (reg:CC 0) (const_int 0))
1064 (plus:SI (match_operand:SI 1 "arith_operand" "%r")
1065 (match_operand:SI 2 "arith_operand" "rI"))))]
1069 (define_insn "*x_minus_sltu"
1070 [(set (match_operand:SI 0 "register_operand" "=r")
1071 (minus:SI (match_operand:SI 1 "register_operand" "r")
1072 (ltu:SI (reg:CC 0) (const_int 0))))]
1075 [(set_attr "type" "unary")])
1077 ;; ??? Combine should canonicalize these next two to the same pattern.
1078 (define_insn "*x_minus_y_minus_sltu"
1079 [(set (match_operand:SI 0 "register_operand" "=r")
1080 (minus:SI (minus:SI (match_operand:SI 1 "register_operand" "r")
1081 (match_operand:SI 2 "arith_operand" "rI"))
1082 (ltu:SI (reg:CC 0) (const_int 0))))]
1086 (define_insn "*x_minus_sltu_plus_y"
1087 [(set (match_operand:SI 0 "register_operand" "=r")
1088 (minus:SI (match_operand:SI 1 "register_operand" "r")
1089 (plus:SI (ltu:SI (reg:CC 0) (const_int 0))
1090 (match_operand:SI 2 "arith_operand" "rI"))))]
1094 (define_insn "*sgeu_plus_x"
1095 [(set (match_operand:SI 0 "register_operand" "=r")
1096 (plus:SI (geu:SI (reg:CC 0) (const_int 0))
1097 (match_operand:SI 1 "register_operand" "r")))]
1100 [(set_attr "type" "unary")])
1102 (define_insn "*x_minus_sgeu"
1103 [(set (match_operand:SI 0 "register_operand" "=r")
1104 (minus:SI (match_operand:SI 1 "register_operand" "r")
1105 (geu:SI (reg:CC 0) (const_int 0))))]
1108 [(set_attr "type" "unary")])
1110 ;; Now we have the generic scc insns.
1111 ;; !v9: These will be done using a jump.
1112 ;; v9: Use conditional moves which are defined elsewhere.
1113 ;; We have to exclude the cases above, since we will not want combine to
1114 ;; turn something that does not require a jump into something that does.
1116 (define_insn "*scc_si"
1117 [(set (match_operand:SI 0 "register_operand" "=r")
1118 (match_operator:SI 1 "noov_compare_op" [(reg 0) (const_int 0)]))]
1120 "* return output_scc_insn (operands, insn); "
1121 [(set_attr "type" "multi")
1122 (set_attr "length" "3")])
1124 (define_insn "*scc_di"
1125 [(set (match_operand:DI 0 "register_operand" "=r")
1126 (match_operator:DI 1 "noov_compare_op" [(reg 0) (const_int 0)]))]
1128 "* return output_scc_insn (operands, insn); "
1129 [(set_attr "type" "multi")
1130 (set_attr "length" "3")])
1132 ;; These control RTL generation for conditional jump insns
1134 ;; The quad-word fp compare library routines all return nonzero to indicate
1135 ;; true, which is different from the equivalent libgcc routines, so we must
1136 ;; handle them specially here.
1138 (define_expand "beq"
1140 (if_then_else (eq (match_dup 1) (const_int 0))
1141 (label_ref (match_operand 0 "" ""))
1146 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1147 && GET_CODE (sparc_compare_op0) == REG
1148 && GET_MODE (sparc_compare_op0) == DImode)
1150 emit_v9_brxx_insn (EQ, sparc_compare_op0, operands[0]);
1153 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1155 emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, EQ);
1156 emit_jump_insn (gen_bne (operands[0]));
1159 operands[1] = gen_compare_reg (EQ, sparc_compare_op0, sparc_compare_op1);
1162 (define_expand "bne"
1164 (if_then_else (ne (match_dup 1) (const_int 0))
1165 (label_ref (match_operand 0 "" ""))
1170 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1171 && GET_CODE (sparc_compare_op0) == REG
1172 && GET_MODE (sparc_compare_op0) == DImode)
1174 emit_v9_brxx_insn (NE, sparc_compare_op0, operands[0]);
1177 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1179 emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, NE);
1180 emit_jump_insn (gen_bne (operands[0]));
1183 operands[1] = gen_compare_reg (NE, sparc_compare_op0, sparc_compare_op1);
1186 (define_expand "bgt"
1188 (if_then_else (gt (match_dup 1) (const_int 0))
1189 (label_ref (match_operand 0 "" ""))
1194 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1195 && GET_CODE (sparc_compare_op0) == REG
1196 && GET_MODE (sparc_compare_op0) == DImode)
1198 emit_v9_brxx_insn (GT, sparc_compare_op0, operands[0]);
1201 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1203 emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GT);
1204 emit_jump_insn (gen_bne (operands[0]));
1207 operands[1] = gen_compare_reg (GT, sparc_compare_op0, sparc_compare_op1);
1210 (define_expand "bgtu"
1212 (if_then_else (gtu (match_dup 1) (const_int 0))
1213 (label_ref (match_operand 0 "" ""))
1217 { operands[1] = gen_compare_reg (GTU, sparc_compare_op0, sparc_compare_op1);
1220 (define_expand "blt"
1222 (if_then_else (lt (match_dup 1) (const_int 0))
1223 (label_ref (match_operand 0 "" ""))
1228 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1229 && GET_CODE (sparc_compare_op0) == REG
1230 && GET_MODE (sparc_compare_op0) == DImode)
1232 emit_v9_brxx_insn (LT, sparc_compare_op0, operands[0]);
1235 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1237 emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LT);
1238 emit_jump_insn (gen_bne (operands[0]));
1241 operands[1] = gen_compare_reg (LT, sparc_compare_op0, sparc_compare_op1);
1244 (define_expand "bltu"
1246 (if_then_else (ltu (match_dup 1) (const_int 0))
1247 (label_ref (match_operand 0 "" ""))
1251 { operands[1] = gen_compare_reg (LTU, sparc_compare_op0, sparc_compare_op1);
1254 (define_expand "bge"
1256 (if_then_else (ge (match_dup 1) (const_int 0))
1257 (label_ref (match_operand 0 "" ""))
1262 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1263 && GET_CODE (sparc_compare_op0) == REG
1264 && GET_MODE (sparc_compare_op0) == DImode)
1266 emit_v9_brxx_insn (GE, sparc_compare_op0, operands[0]);
1269 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1271 emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GE);
1272 emit_jump_insn (gen_bne (operands[0]));
1275 operands[1] = gen_compare_reg (GE, sparc_compare_op0, sparc_compare_op1);
1278 (define_expand "bgeu"
1280 (if_then_else (geu (match_dup 1) (const_int 0))
1281 (label_ref (match_operand 0 "" ""))
1285 { operands[1] = gen_compare_reg (GEU, sparc_compare_op0, sparc_compare_op1);
1288 (define_expand "ble"
1290 (if_then_else (le (match_dup 1) (const_int 0))
1291 (label_ref (match_operand 0 "" ""))
1296 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1297 && GET_CODE (sparc_compare_op0) == REG
1298 && GET_MODE (sparc_compare_op0) == DImode)
1300 emit_v9_brxx_insn (LE, sparc_compare_op0, operands[0]);
1303 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1305 emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LE);
1306 emit_jump_insn (gen_bne (operands[0]));
1309 operands[1] = gen_compare_reg (LE, sparc_compare_op0, sparc_compare_op1);
1312 (define_expand "bleu"
1314 (if_then_else (leu (match_dup 1) (const_int 0))
1315 (label_ref (match_operand 0 "" ""))
1319 { operands[1] = gen_compare_reg (LEU, sparc_compare_op0, sparc_compare_op1);
1322 ;; Now match both normal and inverted jump.
1324 (define_insn "*normal_branch"
1326 (if_then_else (match_operator 0 "noov_compare_op"
1327 [(reg 0) (const_int 0)])
1328 (label_ref (match_operand 1 "" ""))
1333 return output_cbranch (operands[0], 0, 1, 0,
1334 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1337 [(set_attr "type" "branch")])
1339 (define_insn "*inverted_branch"
1341 (if_then_else (match_operator 0 "noov_compare_op"
1342 [(reg 0) (const_int 0)])
1344 (label_ref (match_operand 1 "" ""))))]
1348 return output_cbranch (operands[0], 0, 1, 1,
1349 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1352 [(set_attr "type" "branch")])
1354 (define_insn "*normal_fp_branch_sp64"
1356 (if_then_else (match_operator 0 "comparison_operator"
1357 [(match_operand:CCFP 1 "ccfp_reg_operand" "c")
1359 (label_ref (match_operand 2 "" ""))
1364 return output_cbranch (operands[0], operands[1], 2, 0,
1365 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1368 [(set_attr "type" "branch")])
1370 (define_insn "*inverted_fp_branch_sp64"
1372 (if_then_else (match_operator 0 "comparison_operator"
1373 [(match_operand:CCFP 1 "ccfp_reg_operand" "c")
1376 (label_ref (match_operand 2 "" ""))))]
1380 return output_cbranch (operands[0], operands[1], 2, 1,
1381 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1384 [(set_attr "type" "branch")])
1386 (define_insn "*normal_fpe_branch_sp64"
1388 (if_then_else (match_operator 0 "comparison_operator"
1389 [(match_operand:CCFPE 1 "ccfp_reg_operand" "c")
1391 (label_ref (match_operand 2 "" ""))
1396 return output_cbranch (operands[0], operands[1], 2, 0,
1397 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1400 [(set_attr "type" "branch")])
1402 (define_insn "*inverted_fpe_branch_sp64"
1404 (if_then_else (match_operator 0 "comparison_operator"
1405 [(match_operand:CCFPE 1 "ccfp_reg_operand" "c")
1408 (label_ref (match_operand 2 "" ""))))]
1412 return output_cbranch (operands[0], operands[1], 2, 1,
1413 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1416 [(set_attr "type" "branch")])
1418 ;; Sparc V9-specific jump insns. None of these are guaranteed to be
1419 ;; in the architecture.
1421 ;; There are no 32 bit brreg insns.
1423 (define_insn "*normal_int_branch_sp64"
1425 (if_then_else (match_operator 0 "v9_regcmp_op"
1426 [(match_operand:DI 1 "register_operand" "r")
1428 (label_ref (match_operand 2 "" ""))
1433 return output_v9branch (operands[0], 1, 2, 0,
1434 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1437 [(set_attr "type" "branch")])
1439 (define_insn "*inverted_int_branch_sp64"
1441 (if_then_else (match_operator 0 "v9_regcmp_op"
1442 [(match_operand:DI 1 "register_operand" "r")
1445 (label_ref (match_operand 2 "" ""))))]
1449 return output_v9branch (operands[0], 1, 2, 1,
1450 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1453 [(set_attr "type" "branch")])
1455 ;; Esoteric move insns (lo_sum, high, pic).
1457 (define_insn "*lo_sum_si"
1458 [(set (match_operand:SI 0 "register_operand" "=r")
1459 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1460 (match_operand:SI 2 "immediate_operand" "in")))]
1462 ;; V9 needs "add" because of the code models. We still use "or" for v8
1463 ;; so we can compare the old compiler with the new.
1464 "* return TARGET_ARCH64 ? \"add %1,%%lo(%a2),%0\" : \"or %1,%%lo(%a2),%0\";"
1465 ;; Need to set length for this arith insn because operand2
1466 ;; is not an "arith_operand".
1467 [(set_attr "length" "1")])
1469 ;; For PIC, symbol_refs are put inside unspec so that the optimizer will not
1470 ;; confuse them with real addresses.
1471 (define_insn "pic_lo_sum_si"
1472 [(set (match_operand:SI 0 "register_operand" "=r")
1473 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1474 (unspec:SI [(match_operand:SI 2 "immediate_operand" "in")] 0)))]
1476 ;; V9 needs "add" because of the code models. We still use "or" for v8
1477 ;; so we can compare the old compiler with the new.
1478 "* return TARGET_ARCH64 ? \"add %1,%%lo(%a2),%0\" : \"or %1,%%lo(%a2),%0\";"
1479 ;; Need to set length for this arith insn because operand2
1480 ;; is not an "arith_operand".
1481 [(set_attr "length" "1")])
1483 ;; The PIC version of sethi must appear before the non-pic case so that
1484 ;; the unspec will not be matched as part of the operand.
1485 ;; For PIC, symbol_refs are put inside unspec so that the optimizer will not
1486 ;; confuse them with real addresses.
1487 (define_insn "pic_sethi_si"
1488 [(set (match_operand:SI 0 "register_operand" "=r")
1489 (high:SI (unspec:SI [(match_operand 1 "" "")] 0)))]
1490 "flag_pic && check_pic (1)"
1491 "sethi %%hi(%a1),%0"
1492 [(set_attr "type" "move")
1493 (set_attr "length" "1")])
1495 (define_insn "*sethi_si"
1496 [(set (match_operand:SI 0 "register_operand" "=r")
1497 (high:SI (match_operand 1 "" "")))]
1499 "sethi %%hi(%a1),%0"
1500 [(set_attr "type" "move")
1501 (set_attr "length" "1")])
1503 (define_insn "*sethi_hi"
1504 [(set (match_operand:HI 0 "register_operand" "=r")
1505 (high:HI (match_operand 1 "" "")))]
1507 "sethi %%hi(%a1),%0"
1508 [(set_attr "type" "move")
1509 (set_attr "length" "1")])
1511 (define_insn "get_pc_sp32"
1512 [(set (pc) (label_ref (match_operand 0 "" "")))
1513 (set (reg:SI 15) (label_ref (match_dup 0)))]
1516 [(set_attr "type" "uncond_branch")])
1518 (define_insn "get_pc_sp64"
1519 [(set (match_operand:DI 0 "register_operand" "=r") (pc))]
1522 [(set_attr "type" "move")])
1524 ;; Special pic pattern, for loading the address of a label into a register.
1525 ;; It clobbers o7 because the call puts the return address (i.e. pc value)
1526 ;; there. The pic tablejump pattern also uses this.
1528 (define_insn "move_pic_label_si"
1529 [(set (match_operand:SI 0 "register_operand" "=r")
1530 (label_ref:SI (match_operand 1 "" "")))
1531 (set (reg:SI 15) (pc))]
1535 if (get_attr_length (insn) == 2)
1536 return \"\\n1:\;call 2f\;add %%o7,%%lo(%l1-1b),%0\\n2:\";
1538 return \"\\n1:\;call 2f\;sethi %%hi(%l1-1b),%0\\n2:\\tor %0,%%lo(%l1-1b),%0\;add %0,%%o7,%0\";
1540 [(set_attr "type" "multi")
1541 ; 1024 = 4096 bytes / 4 bytes/insn
1542 (set (attr "length") (if_then_else (ltu (minus (match_dup 1) (pc))
1547 ;; Special sparc64 pattern for loading the address of a label into a register.
1548 ;; The pic and non-pic cases are the same since it's the most efficient way.
1550 ;; ??? The non-pic case doesn't need to use %o7, we could use a scratch
1551 ;; instead. But the pic case doesn't need to use %o7 either. We handle them
1552 ;; both here so that when this is fixed, they can both be fixed together.
1553 ;; Don't forget that the pic jump table stuff uses %o7 (that will need to be
1556 (define_insn "move_label_di"
1557 [(set (match_operand:DI 0 "register_operand" "=r")
1558 (label_ref:DI (match_operand 1 "" "")))
1559 (set (reg:DI 15) (pc))]
1563 if (get_attr_length (insn) == 2)
1564 return \"\\n1:\;rd %%pc,%%o7\;add %%o7,%l1-1b,%0\";
1566 return \"\\n1:\;rd %%pc,%%o7\;sethi %%hi(%l1-1b),%0\;add %0,%%lo(%l1-1b),%0\;sra %0,0,%0\;add %0,%%o7,%0\";
1568 [(set_attr "type" "multi")
1569 ; 1024 = 4096 bytes / 4 bytes/insn
1570 (set (attr "length") (if_then_else (ltu (minus (match_dup 1) (pc))
1575 (define_insn "*lo_sum_di_sp32"
1576 [(set (match_operand:DI 0 "register_operand" "=r")
1577 (lo_sum:DI (match_operand:DI 1 "register_operand" "0")
1578 (match_operand:DI 2 "immediate_operand" "in")))]
1582 /* Don't output a 64 bit constant, since we can't trust the assembler to
1583 handle it correctly. */
1584 if (GET_CODE (operands[2]) == CONST_DOUBLE)
1585 operands[2] = gen_rtx (CONST_INT, VOIDmode, CONST_DOUBLE_LOW (operands[2]));
1586 return \"or %R1,%%lo(%a2),%R0\";
1588 ;; Need to set length for this arith insn because operand2
1589 ;; is not an "arith_operand".
1590 [(set_attr "length" "1")])
1592 ;; ??? Optimizer does not handle "or %o1,%lo(0),%o1". How about add?
1594 (define_insn "*lo_sum_di_sp64"
1595 [(set (match_operand:DI 0 "register_operand" "=r")
1596 (lo_sum:DI (match_operand:DI 1 "register_operand" "0")
1597 (match_operand:DI 2 "immediate_operand" "in")))]
1601 /* Don't output a 64 bit constant, since we can't trust the assembler to
1602 handle it correctly. */
1603 if (GET_CODE (operands[2]) == CONST_DOUBLE)
1604 operands[2] = gen_rtx (CONST_INT, VOIDmode, CONST_DOUBLE_LOW (operands[2]));
1605 /* Note that we use add here. This is important because Medium/Anywhere
1606 code model support depends on it. */
1607 return \"add %1,%%lo(%a2),%0\";
1609 ;; Need to set length for this arith insn because operand2
1610 ;; is not an "arith_operand".
1611 [(set_attr "length" "1")])
1613 (define_insn "*sethi_di_sp32"
1614 [(set (match_operand:DI 0 "register_operand" "=r")
1615 (high:DI (match_operand 1 "" "")))]
1616 "! TARGET_ARCH64 && check_pic (1)"
1619 rtx op0 = operands[0];
1620 rtx op1 = operands[1];
1622 if (GET_CODE (op1) == CONST_INT)
1624 operands[0] = operand_subword (op0, 1, 0, DImode);
1625 output_asm_insn (\"sethi %%hi(%a1),%0\", operands);
1627 operands[0] = operand_subword (op0, 0, 0, DImode);
1628 if (INTVAL (op1) < 0)
1629 return \"mov -1,%0\";
1631 return \"mov 0,%0\";
1633 else if (GET_CODE (op1) == CONST_DOUBLE)
1635 operands[0] = operand_subword (op0, 1, 0, DImode);
1636 operands[1] = gen_rtx (CONST_INT, VOIDmode, CONST_DOUBLE_LOW (op1));
1637 output_asm_insn (\"sethi %%hi(%a1),%0\", operands);
1639 operands[0] = operand_subword (op0, 0, 0, DImode);
1640 operands[1] = gen_rtx (CONST_INT, VOIDmode, CONST_DOUBLE_HIGH (op1));
1641 return singlemove_string (operands);
1647 [(set_attr "type" "move")
1648 (set_attr "length" "2")])
1650 ;;; ??? This pattern originally clobbered a scratch register. However, this
1651 ;;; is invalid, the movdi pattern may not use a temp register because it
1652 ;;; may be called from reload to reload a DImode value. In that case, we
1653 ;;; end up with a scratch register that never gets allocated. To avoid this,
1654 ;;; we use global register 1 which is never otherwise used by gcc as a temp.
1655 ;;; The correct solution here might be to force DImode constants to memory,
1656 ;;; e.g. by using a toc like the romp and rs6000 ports do for addresses, reg
1657 ;;; 1 will then no longer need to be considered a fixed reg.
1659 (define_expand "sethi_di_sp64"
1661 [(set (match_operand:DI 0 "register_operand" "")
1662 (high:DI (match_operand 1 "general_operand" "")))
1663 (clobber (reg:DI 1))])]
1667 (define_insn "*sethi_di_sp64_const"
1668 [(set (match_operand:DI 0 "register_operand" "=r")
1669 (high:DI (match_operand 1 "const_double_operand" "")))
1670 (clobber (reg:DI 1))]
1671 "TARGET_ARCH64 && check_pic (1)"
1676 split_double (operands[1], &high, &low);
1678 if (high == const0_rtx)
1681 output_asm_insn (\"sethi %%hi(%a1),%0\", operands);
1686 output_asm_insn (singlemove_string (operands), operands);
1689 output_asm_insn (\"sllx %0,32,%0\", operands);
1690 if (low != const0_rtx)
1691 output_asm_insn (\"sethi %%hi(%a1),%%g1; or %0,%%g1,%0\", operands);
1696 [(set_attr "type" "move")
1697 (set_attr "length" "5")])
1699 ;; Most of the required support for the various code models is here.
1700 ;; We can do this because sparcs need the high insn to load the address. We
1701 ;; just need to get high to do the right thing for each code model. Then each
1702 ;; uses the same "%X+%lo(...)" in the load/store insn.
1704 ;; When TARGET_MEDLOW, assume that the upper 32 bits of symbol addresses are
1706 ;; When TARGET_MEDANY, the text and data segments have a maximum size of 32
1707 ;; bits and may be located anywhere. MEDANY_BASE_REG contains the start
1708 ;; address of the data segment, currently %g4.
1709 ;; When TARGET_FULLANY, symbolic addresses are 64 bits.
1711 (define_insn "*sethi_di_medlow"
1712 [(set (match_operand:DI 0 "register_operand" "=r")
1713 (high:DI (match_operand 1 "" "")))
1714 ;; The clobber is here because emit_move_sequence assumes the worst case.
1715 (clobber (reg:DI 1))]
1716 "TARGET_MEDLOW && check_pic (1)"
1717 "sethi %%hi(%a1),%0"
1718 [(set_attr "type" "move")
1719 (set_attr "length" "1")])
1721 (define_insn "*sethi_di_medium_pic"
1722 [(set (match_operand:DI 0 "register_operand" "=r")
1723 (high:DI (match_operand 1 "sp64_medium_pic_operand" "")))]
1724 "(TARGET_MEDLOW || TARGET_MEDANY) && check_pic (1)"
1725 "sethi %%hi(%a1),%0"
1726 [(set_attr "type" "move")
1727 (set_attr "length" "1")])
1729 ;; WARNING: %0 gets %hi(%1)+%g4.
1730 ;; You cannot OR in %lo(%1), it must be added in.
1732 (define_insn "*sethi_di_medany_data"
1733 [(set (match_operand:DI 0 "register_operand" "=r")
1734 (high:DI (match_operand 1 "data_segment_operand" "")))
1735 ;; The clobber is here because emit_move_sequence assumes the worst case.
1736 (clobber (reg:DI 1))]
1737 "TARGET_MEDANY && check_pic (1)"
1738 "sethi %%hi(%a1),%0; add %0,%%g4,%0"
1739 [(set_attr "type" "move")
1740 (set_attr "length" "2")])
1742 (define_insn "*sethi_di_medany_text"
1743 [(set (match_operand:DI 0 "register_operand" "=r")
1744 (high:DI (match_operand 1 "text_segment_operand" "")))
1745 ;; The clobber is here because emit_move_sequence assumes the worst case.
1746 (clobber (reg:DI 1))]
1747 "TARGET_MEDANY && check_pic (1)"
1748 "sethi %%uhi(%a1),%%g1; or %%g1,%%ulo(%a1),%%g1; sllx %%g1,32,%%g1; sethi %%hi(%a1),%0; or %0,%%g1,%0"
1749 [(set_attr "type" "move")
1750 (set_attr "length" "5")])
1752 (define_insn "*sethi_di_fullany"
1753 [(set (match_operand:DI 0 "register_operand" "=r")
1754 (high:DI (match_operand 1 "" "")))
1755 (clobber (reg:DI 1))]
1756 "TARGET_FULLANY && check_pic (1)"
1757 "sethi %%uhi(%a1),%%g1; or %%g1,%%ulo(%a1),%%g1; sllx %%g1,32,%%g1; sethi %%hi(%a1),%0; or %0,%%g1,%0"
1758 [(set_attr "type" "move")
1759 (set_attr "length" "5")])
1761 ;; Move instructions
1763 (define_expand "movqi"
1764 [(set (match_operand:QI 0 "general_operand" "")
1765 (match_operand:QI 1 "general_operand" ""))]
1769 if (emit_move_sequence (operands, QImode))
1773 (define_insn "*movqi_insn"
1774 [(set (match_operand:QI 0 "reg_or_nonsymb_mem_operand" "=r,r,r,Q")
1775 (match_operand:QI 1 "move_operand" "rI,K,Q,rJ"))]
1776 "register_operand (operands[0], QImode)
1777 || register_operand (operands[1], QImode)
1778 || operands[1] == const0_rtx"
1784 [(set_attr "type" "move,move,load,store")
1785 (set_attr "length" "*,1,*,1")])
1787 (define_insn "*lo_sum_qi"
1788 [(set (match_operand:QI 0 "register_operand" "=r")
1789 (subreg:QI (lo_sum:SI (match_operand:QI 1 "register_operand" "r")
1790 (match_operand 2 "immediate_operand" "in")) 0))]
1792 "or %1,%%lo(%a2),%0"
1793 [(set_attr "length" "1")])
1795 (define_insn "*store_qi"
1796 [(set (mem:QI (match_operand:SI 0 "symbolic_operand" ""))
1797 (match_operand:QI 1 "reg_or_0_operand" "rJ"))
1798 (clobber (match_scratch:SI 2 "=&r"))]
1799 "(reload_completed || reload_in_progress) && ! TARGET_PTR64"
1800 "sethi %%hi(%a0),%2\;stb %r1,[%2+%%lo(%a0)]"
1801 [(set_attr "type" "store")
1802 (set_attr "length" "2")])
1804 (define_expand "movhi"
1805 [(set (match_operand:HI 0 "general_operand" "")
1806 (match_operand:HI 1 "general_operand" ""))]
1810 if (emit_move_sequence (operands, HImode))
1814 (define_insn "*movhi_insn"
1815 [(set (match_operand:HI 0 "reg_or_nonsymb_mem_operand" "=r,r,r,Q")
1816 (match_operand:HI 1 "move_operand" "rI,K,Q,rJ"))]
1817 "register_operand (operands[0], HImode)
1818 || register_operand (operands[1], HImode)
1819 || operands[1] == const0_rtx"
1825 [(set_attr "type" "move,move,load,store")
1826 (set_attr "length" "*,1,*,1")])
1828 (define_insn "*lo_sum_hi"
1829 [(set (match_operand:HI 0 "register_operand" "=r")
1830 (lo_sum:HI (match_operand:HI 1 "register_operand" "r")
1831 (match_operand 2 "immediate_operand" "in")))]
1833 "or %1,%%lo(%a2),%0"
1834 [(set_attr "length" "1")])
1836 (define_insn "*store_hi"
1837 [(set (mem:HI (match_operand:SI 0 "symbolic_operand" ""))
1838 (match_operand:HI 1 "reg_or_0_operand" "rJ"))
1839 (clobber (match_scratch:SI 2 "=&r"))]
1840 "(reload_completed || reload_in_progress) && ! TARGET_PTR64"
1841 "sethi %%hi(%a0),%2\;sth %r1,[%2+%%lo(%a0)]"
1842 [(set_attr "type" "store")
1843 (set_attr "length" "2")])
1845 (define_expand "movsi"
1846 [(set (match_operand:SI 0 "general_operand" "")
1847 (match_operand:SI 1 "general_operand" ""))]
1851 if (emit_move_sequence (operands, SImode))
1855 ;; We must support both 'r' and 'f' registers here, because combine may
1856 ;; convert SFmode hard registers to SImode hard registers when simplifying
1859 ;; We cannot combine the similar 'r' and 'f' constraints, because it causes
1860 ;; problems with register allocation. Reload might try to put an integer
1861 ;; in an fp register, or an fp number is an integer register.
1863 (define_insn "*movsi_insn"
1864 [(set (match_operand:SI 0 "reg_or_nonsymb_mem_operand" "=r,f,r,r,f,Q,Q")
1865 (match_operand:SI 1 "move_operand" "rI,!f,K,Q,!Q,rJ,!f"))]
1866 "register_operand (operands[0], SImode)
1867 || register_operand (operands[1], SImode)
1868 || operands[1] == const0_rtx"
1877 [(set_attr "type" "move,fp,move,load,load,store,store")
1878 (set_attr "length" "*,*,1,*,*,*,*")])
1880 (define_insn "*store_si"
1881 [(set (mem:SI (match_operand:SI 0 "symbolic_operand" ""))
1882 (match_operand:SI 1 "reg_or_0_operand" "rJ"))
1883 (clobber (match_scratch:SI 2 "=&r"))]
1884 "(reload_completed || reload_in_progress) && ! TARGET_PTR64"
1885 "sethi %%hi(%a0),%2\;st %r1,[%2+%%lo(%a0)]"
1886 [(set_attr "type" "store")
1887 (set_attr "length" "2")])
1889 (define_expand "movdi"
1890 [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand" "")
1891 (match_operand:DI 1 "general_operand" ""))]
1895 if (emit_move_sequence (operands, DImode))
1899 (define_insn "*movdi_sp32_insn"
1900 [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand" "=r,T,U,Q,r,r,?f,?f,?Q")
1901 (match_operand:DI 1 "general_operand" "r,U,T,r,Q,i,f,Q,f"))]
1903 && (register_operand (operands[0], DImode)
1904 || register_operand (operands[1], DImode)
1905 || operands[1] == const0_rtx)"
1908 if (FP_REG_P (operands[0]) || FP_REG_P (operands[1]))
1909 return output_fp_move_double (operands);
1910 return output_move_double (operands);
1912 [(set_attr "type" "move,store,load,store,load,multi,fp,fpload,fpstore")
1913 (set_attr "length" "2,1,1,3,3,3,2,3,3")])
1915 ;;; ??? The trick used below can be extended to load any negative 32 bit
1916 ;;; constant in two instructions. Currently the compiler will use HIGH/LO_SUM
1917 ;;; for anything not matching the HIK constraints, which results in 5
1918 ;;; instructions. Positive 32 bit constants can be loaded in the obvious way
1919 ;;; with sethi/ori. To extend the trick, in the xor instruction, use
1920 ;;; xor %o0, ((op1 & 0x3ff) | -0x400), %o0
1921 ;;; This needs the original value of operands[1], not the inverted value.
1923 (define_insn "*movdi_sp64_insn"
1924 [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand" "=r,r,r,Q,?f,?f,?Q")
1925 (match_operand:DI 1 "move_operand" "rI,K,Q,rJ,f,Q,f"))]
1927 && (register_operand (operands[0], DImode)
1928 || register_operand (operands[1], DImode)
1929 || operands[1] == const0_rtx)"
1932 switch (which_alternative)
1935 return \"mov %1,%0\";
1937 /* Sethi does not sign extend, so we must use a little trickery
1938 to use it for negative numbers. Invert the constant before
1939 loading it in, then use a xor immediate to invert the loaded bits
1940 (along with the upper 32 bits) to the desired constant. This
1941 works because the sethi and immediate fields overlap. */
1943 if ((INTVAL (operands[1]) & 0x80000000) == 0)
1944 return \"sethi %%hi(%a1),%0\";
1947 operands[1] = gen_rtx (CONST_INT, VOIDmode,
1948 ~ INTVAL (operands[1]));
1949 output_asm_insn (\"sethi %%hi(%a1),%0\", operands);
1950 /* The low 10 bits are already zero, but invert the rest.
1951 Assemblers don't accept 0x1c00, so use -0x400 instead. */
1952 return \"xor %0,-0x400,%0\";
1955 return \"ldx %1,%0\";
1957 return \"stx %r1,%0\";
1959 return \"mov %1,%0\";
1961 return \"ldd %1,%0\";
1963 return \"std %1,%0\";
1966 [(set_attr "type" "move,move,load,store,fp,fpload,fpstore")
1967 (set_attr "length" "1,2,1,1,1,1,1")])
1969 ;; ??? There's no symbolic (set (mem:DI ...) ...).
1970 ;; Experimentation with v9 suggested one isn't needed.
1972 ;; Block move insns.
1974 ;; ??? We get better code without it. See output_block_move in sparc.c.
1976 ;; The definition of this insn does not really explain what it does,
1977 ;; but it should suffice
1978 ;; that anything generated as this insn will be recognized as one
1979 ;; and that it will not successfully combine with anything.
1980 ;(define_expand "movstrsi"
1981 ; [(parallel [(set (mem:BLK (match_operand:BLK 0 "general_operand" ""))
1982 ; (mem:BLK (match_operand:BLK 1 "general_operand" "")))
1983 ; (use (match_operand:SI 2 "nonmemory_operand" ""))
1984 ; (use (match_operand:SI 3 "immediate_operand" ""))
1985 ; (clobber (match_dup 0))
1986 ; (clobber (match_dup 1))
1987 ; (clobber (match_scratch:SI 4 ""))
1988 ; (clobber (reg:SI 0))
1989 ; (clobber (reg:SI 1))])]
1993 ; /* If the size isn't known, don't emit inline code. output_block_move
1994 ; would output code that's much slower than the library function.
1995 ; Also don't output code for large blocks. */
1996 ; if (GET_CODE (operands[2]) != CONST_INT
1997 ; || GET_CODE (operands[3]) != CONST_INT
1998 ; || INTVAL (operands[2]) / INTVAL (operands[3]) > 16)
2001 ; operands[0] = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
2002 ; operands[1] = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
2003 ; operands[2] = force_not_mem (operands[2]);
2006 ;(define_insn "*block_move_insn"
2007 ; [(set (mem:BLK (match_operand:SI 0 "register_operand" "+r"))
2008 ; (mem:BLK (match_operand:SI 1 "register_operand" "+r")))
2009 ; (use (match_operand:SI 2 "nonmemory_operand" "rn"))
2010 ; (use (match_operand:SI 3 "immediate_operand" "i"))
2011 ; (clobber (match_dup 0))
2012 ; (clobber (match_dup 1))
2013 ; (clobber (match_scratch:SI 4 "=&r"))
2014 ; (clobber (reg:SI 0))
2015 ; (clobber (reg:SI 1))]
2017 ; "* return output_block_move (operands);"
2018 ; [(set_attr "type" "multi")
2019 ; (set_attr "length" "6")])
2021 ;; Floating point move insns
2023 ;; This pattern forces (set (reg:SF ...) (const_double ...))
2024 ;; to be reloaded by putting the constant into memory.
2025 ;; It must come before the more general movsf pattern.
2026 (define_insn "*movsf_const_insn"
2027 [(set (match_operand:SF 0 "general_operand" "=?r,f,m")
2028 (match_operand:SF 1 "" "?F,m,G"))]
2029 "TARGET_FPU && GET_CODE (operands[1]) == CONST_DOUBLE"
2032 switch (which_alternative)
2035 return singlemove_string (operands);
2037 return \"ld %1,%0\";
2039 return \"st %%g0,%0\";
2042 [(set_attr "type" "load,fpload,store")
2043 (set_attr "length" "2,1,1")])
2045 (define_expand "movsf"
2046 [(set (match_operand:SF 0 "general_operand" "")
2047 (match_operand:SF 1 "general_operand" ""))]
2051 if (emit_move_sequence (operands, SFmode))
2055 (define_insn "*movsf_insn"
2056 [(set (match_operand:SF 0 "reg_or_nonsymb_mem_operand" "=f,r,f,r,Q,Q")
2057 (match_operand:SF 1 "reg_or_nonsymb_mem_operand" "f,r,Q,Q,f,r"))]
2059 && (register_operand (operands[0], SFmode)
2060 || register_operand (operands[1], SFmode))"
2068 [(set_attr "type" "fp,move,fpload,load,fpstore,store")])
2070 ;; Exactly the same as above, except that all `f' cases are deleted.
2071 ;; This is necessary to prevent reload from ever trying to use a `f' reg
2074 (define_insn "*movsf_no_f_insn"
2075 [(set (match_operand:SF 0 "reg_or_nonsymb_mem_operand" "=r,r,Q")
2076 (match_operand:SF 1 "reg_or_nonsymb_mem_operand" "r,Q,r"))]
2078 && (register_operand (operands[0], SFmode)
2079 || register_operand (operands[1], SFmode))"
2084 [(set_attr "type" "move,load,store")])
2086 (define_insn "*store_sf"
2087 [(set (mem:SF (match_operand:SI 0 "symbolic_operand" "i"))
2088 (match_operand:SF 1 "reg_or_0_operand" "rfG"))
2089 (clobber (match_scratch:SI 2 "=&r"))]
2090 "(reload_completed || reload_in_progress) && ! TARGET_PTR64"
2091 "sethi %%hi(%a0),%2\;st %r1,[%2+%%lo(%a0)]"
2092 [(set_attr "type" "store")
2093 (set_attr "length" "2")])
2095 ;; This pattern forces (set (reg:DF ...) (const_double ...))
2096 ;; to be reloaded by putting the constant into memory.
2097 ;; It must come before the more general movdf pattern.
2099 (define_insn "*movdf_const_insn"
2100 [(set (match_operand:DF 0 "general_operand" "=?r,e,o")
2101 (match_operand:DF 1 "" "?F,m,G"))]
2102 "TARGET_FPU && GET_CODE (operands[1]) == CONST_DOUBLE"
2105 switch (which_alternative)
2108 return output_move_double (operands);
2110 return output_fp_move_double (operands);
2114 return \"stx %%g0,%0\";
2118 operands[1] = adj_offsettable_operand (operands[0], 4);
2119 return \"st %%g0,%0\;st %%g0,%1\";
2123 [(set_attr "type" "load,fpload,store")
2124 (set_attr "length" "3,3,3")])
2126 (define_expand "movdf"
2127 [(set (match_operand:DF 0 "general_operand" "")
2128 (match_operand:DF 1 "general_operand" ""))]
2132 if (emit_move_sequence (operands, DFmode))
2136 (define_insn "*movdf_insn"
2137 [(set (match_operand:DF 0 "reg_or_nonsymb_mem_operand" "=T,U,e,r,Q,Q,e,r")
2138 (match_operand:DF 1 "reg_or_nonsymb_mem_operand" "U,T,e,r,e,r,Q,Q"))]
2140 && (register_operand (operands[0], DFmode)
2141 || register_operand (operands[1], DFmode))"
2144 if (FP_REG_P (operands[0]) || FP_REG_P (operands[1]))
2145 return output_fp_move_double (operands);
2146 return output_move_double (operands);
2148 [(set_attr "type" "fpstore,fpload,fp,move,fpstore,store,fpload,load")
2149 (set_attr "length" "1,1,2,2,3,3,3,3")])
2151 ;; Exactly the same as above, except that all `e' cases are deleted.
2152 ;; This is necessary to prevent reload from ever trying to use a `e' reg
2155 (define_insn "*movdf_no_e_insn"
2156 [(set (match_operand:DF 0 "reg_or_nonsymb_mem_operand" "=T,U,r,Q,&r")
2157 (match_operand:DF 1 "reg_or_nonsymb_mem_operand" "U,T,r,r,Q"))]
2159 && (register_operand (operands[0], DFmode)
2160 || register_operand (operands[1], DFmode))"
2161 "* return output_move_double (operands);"
2162 [(set_attr "type" "store,load,move,store,load")
2163 (set_attr "length" "1,1,2,3,3")])
2165 ;; Must handle overlapping registers here, since parameters can be unaligned
2167 ;; ??? Do we need a v9 version of this?
2169 [(set (match_operand:DF 0 "register_operand" "")
2170 (match_operand:DF 1 "register_operand" ""))]
2171 "! TARGET_ARCH64 && reload_completed"
2172 [(set (match_dup 2) (match_dup 3))
2173 (set (match_dup 4) (match_dup 5))]
2176 rtx first_set = operand_subword (operands[0], 0, 0, DFmode);
2177 rtx second_use = operand_subword (operands[1], 1, 0, DFmode);
2179 if (REGNO (first_set) == REGNO (second_use))
2181 operands[2] = operand_subword (operands[0], 1, 0, DFmode);
2182 operands[3] = second_use;
2183 operands[4] = first_set;
2184 operands[5] = operand_subword (operands[1], 0, 0, DFmode);
2188 operands[2] = first_set;
2189 operands[3] = operand_subword (operands[1], 0, 0, DFmode);
2190 operands[4] = operand_subword (operands[0], 1, 0, DFmode);
2191 operands[5] = second_use;
2195 (define_insn "*store_df"
2196 [(set (mem:DF (match_operand:SI 0 "symbolic_operand" "i,i"))
2197 (match_operand:DF 1 "reg_or_0_operand" "re,G"))
2198 (clobber (match_scratch:SI 2 "=&r,&r"))]
2199 "(reload_completed || reload_in_progress) && ! TARGET_PTR64"
2202 output_asm_insn (\"sethi %%hi(%a0),%2\", operands);
2203 if (which_alternative == 0)
2204 return \"std %1,[%2+%%lo(%a0)]\";
2206 return \"st %%g0,[%2+%%lo(%a0)]\;st %%g0,[%2+%%lo(%a0+4)]\";
2208 [(set_attr "type" "store")
2209 (set_attr "length" "3")])
2211 ;; This pattern forces (set (reg:TF ...) (const_double ...))
2212 ;; to be reloaded by putting the constant into memory.
2213 ;; It must come before the more general movtf pattern.
2214 (define_insn "*movtf_const_insn"
2215 [(set (match_operand:TF 0 "general_operand" "=?r,e,o")
2216 (match_operand:TF 1 "" "?F,m,G"))]
2217 "TARGET_FPU && GET_CODE (operands[1]) == CONST_DOUBLE"
2220 switch (which_alternative)
2223 return output_move_quad (operands);
2225 return output_fp_move_quad (operands);
2229 operands[1] = adj_offsettable_operand (operands[0], 8);
2230 return \"stx %%g0,%0\;stx %%g0,%1\";
2234 /* ??? Do we run off the end of the array here? */
2235 operands[1] = adj_offsettable_operand (operands[0], 4);
2236 operands[2] = adj_offsettable_operand (operands[0], 8);
2237 operands[3] = adj_offsettable_operand (operands[0], 12);
2238 return \"st %%g0,%0\;st %%g0,%1\;st %%g0,%2\;st %%g0,%3\";
2242 [(set_attr "type" "load,fpload,store")
2243 (set_attr "length" "5,5,5")])
2245 (define_expand "movtf"
2246 [(set (match_operand:TF 0 "general_operand" "")
2247 (match_operand:TF 1 "general_operand" ""))]
2251 if (emit_move_sequence (operands, TFmode))
2255 (define_insn "*movtf_insn"
2256 [(set (match_operand:TF 0 "reg_or_nonsymb_mem_operand" "=e,r,Q,Q,e,&r")
2257 (match_operand:TF 1 "reg_or_nonsymb_mem_operand" "e,r,e,r,Q,Q"))]
2259 && (register_operand (operands[0], TFmode)
2260 || register_operand (operands[1], TFmode))"
2263 if (FP_REG_P (operands[0]) || FP_REG_P (operands[1]))
2264 return output_fp_move_quad (operands);
2265 return output_move_quad (operands);
2267 [(set_attr "type" "fp,move,fpstore,store,fpload,load")
2268 (set_attr "length" "4,4,5,5,5,5")])
2270 ;; Exactly the same as above, except that all `e' cases are deleted.
2271 ;; This is necessary to prevent reload from ever trying to use a `e' reg
2274 (define_insn "*movtf_no_e_insn"
2275 [(set (match_operand:TF 0 "reg_or_nonsymb_mem_operand" "=r,Q,&r")
2276 (match_operand:TF 1 "reg_or_nonsymb_mem_operand" "r,r,Q"))]
2278 && (register_operand (operands[0], TFmode)
2279 || register_operand (operands[1], TFmode))"
2282 if (FP_REG_P (operands[0]) || FP_REG_P (operands[1]))
2283 return output_fp_move_quad (operands);
2284 return output_move_quad (operands);
2286 [(set_attr "type" "move,store,load")
2287 (set_attr "length" "4,5,5")])
2289 ;; This is disabled because it does not work. Long doubles have only 8
2290 ;; byte alignment. Adding an offset of 8 or 12 to an 8 byte aligned %lo may
2291 ;; cause it to overflow. See also GO_IF_LEGITIMATE_ADDRESS.
2292 (define_insn "*store_tf"
2293 [(set (mem:TF (match_operand:SI 0 "symbolic_operand" "i,i"))
2294 (match_operand:TF 1 "reg_or_0_operand" "re,G"))
2295 (clobber (match_scratch:SI 2 "=&r,&r"))]
2296 "0 && (reload_completed || reload_in_progress) && ! TARGET_PTR64"
2299 output_asm_insn (\"sethi %%hi(%a0),%2\", operands);
2300 if (which_alternative == 0)
2301 return \"std %1,[%2+%%lo(%a0)]\;std %S1,[%2+%%lo(%a0+8)]\";
2303 return \"st %%g0,[%2+%%lo(%a0)]\;st %%g0,[%2+%%lo(%a0+4)]\; st %%g0,[%2+%%lo(%a0+8)]\;st %%g0,[%2+%%lo(%a0+12)]\";
2305 [(set_attr "type" "store")
2306 (set_attr "length" "5")])
2308 ;; Sparc V9 conditional move instructions.
2310 ;; We can handle larger constants here for some flavors, but for now we play
2311 ;; it safe and only allow those constants supported by all flavours.
2313 (define_expand "movsicc"
2314 [(set (match_operand:SI 0 "register_operand" "")
2315 (if_then_else (match_operand 1 "comparison_operator" "")
2316 (match_operand:SI 2 "arith10_operand" "")
2317 (match_operand:SI 3 "register_operand" "")))]
2321 enum rtx_code code = GET_CODE (operands[1]);
2323 if (sparc_compare_op1 == const0_rtx
2324 && GET_CODE (sparc_compare_op0) == REG
2325 && GET_MODE (sparc_compare_op0) == DImode
2326 && v9_regcmp_p (code))
2328 operands[1] = gen_rtx (code, DImode,
2329 sparc_compare_op0, sparc_compare_op1);
2333 rtx cc_reg = gen_compare_reg (code,
2334 sparc_compare_op0, sparc_compare_op1);
2335 operands[1] = gen_rtx (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
2339 (define_expand "movdicc"
2340 [(set (match_operand:DI 0 "register_operand" "")
2341 (if_then_else (match_operand 1 "comparison_operator" "")
2342 (match_operand:DI 2 "arith10_operand" "")
2343 (match_operand:DI 3 "register_operand" "")))]
2347 enum rtx_code code = GET_CODE (operands[1]);
2349 if (sparc_compare_op1 == const0_rtx
2350 && GET_CODE (sparc_compare_op0) == REG
2351 && GET_MODE (sparc_compare_op0) == DImode
2352 && v9_regcmp_p (code))
2354 operands[1] = gen_rtx (code, DImode,
2355 sparc_compare_op0, sparc_compare_op1);
2359 rtx cc_reg = gen_compare_reg (code,
2360 sparc_compare_op0, sparc_compare_op1);
2361 operands[1] = gen_rtx (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
2365 (define_expand "movsfcc"
2366 [(set (match_operand:SF 0 "register_operand" "")
2367 (if_then_else (match_operand 1 "comparison_operator" "")
2368 (match_operand:SF 2 "register_operand" "")
2369 (match_operand:SF 3 "register_operand" "")))]
2373 enum rtx_code code = GET_CODE (operands[1]);
2375 if (sparc_compare_op1 == const0_rtx
2376 && GET_CODE (sparc_compare_op0) == REG
2377 && GET_MODE (sparc_compare_op0) == DImode
2378 && v9_regcmp_p (code))
2380 operands[1] = gen_rtx (code, DImode,
2381 sparc_compare_op0, sparc_compare_op1);
2385 rtx cc_reg = gen_compare_reg (code,
2386 sparc_compare_op0, sparc_compare_op1);
2387 operands[1] = gen_rtx (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
2391 (define_expand "movdfcc"
2392 [(set (match_operand:DF 0 "register_operand" "")
2393 (if_then_else (match_operand 1 "comparison_operator" "")
2394 (match_operand:DF 2 "register_operand" "")
2395 (match_operand:DF 3 "register_operand" "")))]
2399 enum rtx_code code = GET_CODE (operands[1]);
2401 if (sparc_compare_op1 == const0_rtx
2402 && GET_CODE (sparc_compare_op0) == REG
2403 && GET_MODE (sparc_compare_op0) == DImode
2404 && v9_regcmp_p (code))
2406 operands[1] = gen_rtx (code, DImode,
2407 sparc_compare_op0, sparc_compare_op1);
2411 rtx cc_reg = gen_compare_reg (code,
2412 sparc_compare_op0, sparc_compare_op1);
2413 operands[1] = gen_rtx (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
2417 (define_expand "movtfcc"
2418 [(set (match_operand:TF 0 "register_operand" "")
2419 (if_then_else (match_operand 1 "comparison_operator" "")
2420 (match_operand:TF 2 "register_operand" "")
2421 (match_operand:TF 3 "register_operand" "")))]
2425 enum rtx_code code = GET_CODE (operands[1]);
2427 if (sparc_compare_op1 == const0_rtx
2428 && GET_CODE (sparc_compare_op0) == REG
2429 && GET_MODE (sparc_compare_op0) == DImode
2430 && v9_regcmp_p (code))
2432 operands[1] = gen_rtx (code, DImode,
2433 sparc_compare_op0, sparc_compare_op1);
2437 rtx cc_reg = gen_compare_reg (code,
2438 sparc_compare_op0, sparc_compare_op1);
2439 operands[1] = gen_rtx (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
2443 /* Conditional move define_insns. */
2445 (define_insn "*movsi_cc_sp64"
2446 [(set (match_operand:SI 0 "register_operand" "=r")
2447 (if_then_else (match_operator 1 "comparison_operator"
2448 [(reg:CC 0) (const_int 0)])
2449 (match_operand:SI 2 "arith11_operand" "ri")
2450 (match_operand:SI 3 "register_operand" "0")))]
2452 "mov%C1 %%icc,%2,%0"
2453 [(set_attr "type" "cmove")])
2455 (define_insn "*movdi_cc_sp64"
2456 [(set (match_operand:DI 0 "register_operand" "=r")
2457 (if_then_else (match_operator 1 "comparison_operator"
2458 [(reg:CC 0) (const_int 0)])
2459 (match_operand:DI 2 "arith11_double_operand" "rHI")
2460 (match_operand:DI 3 "register_operand" "0")))]
2462 "mov%C1 %%icc,%2,%0"
2463 [(set_attr "type" "cmove")])
2465 (define_insn "*movsi_ccx_sp64"
2466 [(set (match_operand:SI 0 "register_operand" "=r")
2467 (if_then_else (match_operator 1 "comparison_operator"
2468 [(reg:CCX 0) (const_int 0)])
2469 (match_operand:SI 2 "arith11_operand" "ri")
2470 (match_operand:SI 3 "register_operand" "0")))]
2472 "mov%C1 %%xcc,%2,%0"
2473 [(set_attr "type" "cmove")])
2475 (define_insn "*movdi_ccx_sp64"
2476 [(set (match_operand:DI 0 "register_operand" "=r")
2477 (if_then_else (match_operator 1 "comparison_operator"
2478 [(reg:CCX 0) (const_int 0)])
2479 (match_operand:DI 2 "arith11_double_operand" "rHI")
2480 (match_operand:DI 3 "register_operand" "0")))]
2482 "mov%C1 %%xcc,%2,%0"
2483 [(set_attr "type" "cmove")])
2485 (define_insn "*movsi_ccfp_sp64"
2486 [(set (match_operand:SI 0 "register_operand" "=r")
2487 (if_then_else (match_operator 1 "comparison_operator"
2488 [(match_operand:CCFP 2 "ccfp_reg_operand" "c")
2490 (match_operand:SI 3 "arith11_operand" "ri")
2491 (match_operand:SI 4 "register_operand" "0")))]
2494 [(set_attr "type" "cmove")])
2496 (define_insn "*movsi_ccfpe_sp64"
2497 [(set (match_operand:SI 0 "register_operand" "=r")
2498 (if_then_else (match_operator 1 "comparison_operator"
2499 [(match_operand:CCFPE 2 "ccfp_reg_operand" "c")
2501 (match_operand:SI 3 "arith11_operand" "ri")
2502 (match_operand:SI 4 "register_operand" "0")))]
2505 [(set_attr "type" "cmove")])
2507 (define_insn "*movdi_ccfp_sp64"
2508 [(set (match_operand:DI 0 "register_operand" "=r")
2509 (if_then_else (match_operator 1 "comparison_operator"
2510 [(match_operand:CCFP 2 "ccfp_reg_operand" "c")
2512 (match_operand:DI 3 "arith11_double_operand" "rHI")
2513 (match_operand:DI 4 "register_operand" "0")))]
2516 [(set_attr "type" "cmove")])
2518 (define_insn "*movdi_ccfpe_sp64"
2519 [(set (match_operand:DI 0 "register_operand" "=r")
2520 (if_then_else (match_operator 1 "comparison_operator"
2521 [(match_operand:CCFPE 2 "ccfp_reg_operand" "c")
2523 (match_operand:DI 3 "arith11_double_operand" "rHI")
2524 (match_operand:DI 4 "register_operand" "0")))]
2527 [(set_attr "type" "cmove")])
2529 (define_insn "*movsi_cc_reg_sp64"
2530 [(set (match_operand:SI 0 "register_operand" "=r")
2531 (if_then_else (match_operator 1 "v9_regcmp_op"
2532 [(match_operand:DI 2 "register_operand" "r")
2534 (match_operand:SI 3 "arith10_operand" "ri")
2535 (match_operand:SI 4 "register_operand" "0")))]
2538 [(set_attr "type" "cmove")])
2540 (define_insn "*movdi_cc_reg_sp64"
2541 [(set (match_operand:DI 0 "register_operand" "=r")
2542 (if_then_else (match_operator 1 "v9_regcmp_op"
2543 [(match_operand:DI 2 "register_operand" "r")
2545 (match_operand:DI 3 "arith10_double_operand" "ri")
2546 (match_operand:DI 4 "register_operand" "0")))]
2549 [(set_attr "type" "cmove")])
2551 (define_insn "*movsf_cc_reg_sp64"
2552 [(set (match_operand:SF 0 "register_operand" "=f")
2553 (if_then_else (match_operator 1 "v9_regcmp_op"
2554 [(match_operand:DI 2 "register_operand" "r")
2556 (match_operand:SF 3 "register_operand" "f")
2557 (match_operand:SF 4 "register_operand" "0")))]
2558 "TARGET_ARCH64 && TARGET_FPU"
2559 "fmovrs%D1 %2,%r3,%0"
2560 [(set_attr "type" "cmove")])
2562 (define_insn "*movdf_cc_reg_sp64"
2563 [(set (match_operand:DF 0 "register_operand" "=e")
2564 (if_then_else (match_operator 1 "v9_regcmp_op"
2565 [(match_operand:DI 2 "register_operand" "r")
2567 (match_operand:DF 3 "register_operand" "e")
2568 (match_operand:DF 4 "register_operand" "0")))]
2569 "TARGET_ARCH64 && TARGET_FPU"
2570 "fmovrd%D1 %2,%r3,%0"
2571 [(set_attr "type" "cmove")])
2573 (define_insn "*movtf_cc_reg_sp64"
2574 [(set (match_operand:TF 0 "register_operand" "=e")
2575 (if_then_else (match_operator 1 "v9_regcmp_op"
2576 [(match_operand:DI 2 "register_operand" "r")
2578 (match_operand:TF 3 "register_operand" "e")
2579 (match_operand:TF 4 "register_operand" "0")))]
2580 "TARGET_ARCH64 && TARGET_FPU"
2581 "fmovrq%D1 %2,%r3,%0"
2582 [(set_attr "type" "cmove")])
2584 (define_insn "*movsf_ccfp_sp64"
2585 [(set (match_operand:SF 0 "register_operand" "=f")
2586 (if_then_else (match_operator 1 "comparison_operator"
2587 [(match_operand:CCFP 2 "ccfp_reg_operand" "c")
2589 (match_operand:SF 3 "register_operand" "f")
2590 (match_operand:SF 4 "register_operand" "0")))]
2591 "TARGET_V9 && TARGET_FPU"
2593 [(set_attr "type" "cmove")])
2595 (define_insn "*movsf_ccfpe_sp64"
2596 [(set (match_operand:SF 0 "register_operand" "=f")
2597 (if_then_else (match_operator 1 "comparison_operator"
2598 [(match_operand:CCFPE 2 "ccfp_reg_operand" "c")
2600 (match_operand:SF 3 "register_operand" "f")
2601 (match_operand:SF 4 "register_operand" "0")))]
2602 "TARGET_V9 && TARGET_FPU"
2604 [(set_attr "type" "cmove")])
2606 (define_insn "*movdf_ccfp_sp64"
2607 [(set (match_operand:DF 0 "register_operand" "=e")
2608 (if_then_else (match_operator 1 "comparison_operator"
2609 [(match_operand:CCFP 2 "ccfp_reg_operand" "c")
2611 (match_operand:DF 3 "register_operand" "e")
2612 (match_operand:DF 4 "register_operand" "0")))]
2613 "TARGET_V9 && TARGET_FPU"
2615 [(set_attr "type" "cmove")])
2617 (define_insn "*movdf_ccfpe_sp64"
2618 [(set (match_operand:DF 0 "register_operand" "=e")
2619 (if_then_else (match_operator 1 "comparison_operator"
2620 [(match_operand:CCFPE 2 "ccfp_reg_operand" "c")
2622 (match_operand:DF 3 "register_operand" "e")
2623 (match_operand:DF 4 "register_operand" "0")))]
2624 "TARGET_V9 && TARGET_FPU"
2626 [(set_attr "type" "cmove")])
2628 (define_insn "*movtf_ccfp_sp64"
2629 [(set (match_operand:TF 0 "register_operand" "=e")
2630 (if_then_else (match_operator 1 "comparison_operator"
2631 [(match_operand:CCFP 2 "ccfp_reg_operand" "c")
2633 (match_operand:TF 3 "register_operand" "e")
2634 (match_operand:TF 4 "register_operand" "0")))]
2635 "TARGET_V9 && TARGET_FPU"
2637 [(set_attr "type" "cmove")])
2639 (define_insn "*movtf_ccfpe_sp64"
2640 [(set (match_operand:TF 0 "register_operand" "=e")
2641 (if_then_else (match_operator 1 "comparison_operator"
2642 [(match_operand:CCFPE 2 "ccfp_reg_operand" "c")
2644 (match_operand:TF 3 "register_operand" "e")
2645 (match_operand:TF 4 "register_operand" "0")))]
2646 "TARGET_V9 && TARGET_FPU"
2648 [(set_attr "type" "cmove")])
2650 (define_insn "*movsf_cc_sp64"
2651 [(set (match_operand:SF 0 "register_operand" "=f")
2652 (if_then_else (match_operator 1 "comparison_operator"
2653 [(reg:CC 0) (const_int 0)])
2654 (match_operand:SF 2 "register_operand" "f")
2655 (match_operand:SF 3 "register_operand" "0")))]
2656 "TARGET_V9 && TARGET_FPU"
2657 "fmovs%C1 %%icc,%2,%0"
2658 [(set_attr "type" "cmove")])
2660 (define_insn "*movdf_cc_sp64"
2661 [(set (match_operand:DF 0 "register_operand" "=e")
2662 (if_then_else (match_operator 1 "comparison_operator"
2663 [(reg:CC 0) (const_int 0)])
2664 (match_operand:DF 2 "register_operand" "e")
2665 (match_operand:DF 3 "register_operand" "0")))]
2666 "TARGET_V9 && TARGET_FPU"
2667 "fmovd%C1 %%icc,%2,%0"
2668 [(set_attr "type" "cmove")])
2670 (define_insn "*movtf_cc_sp64"
2671 [(set (match_operand:TF 0 "register_operand" "=e")
2672 (if_then_else (match_operator 1 "comparison_operator"
2673 [(reg:CC 0) (const_int 0)])
2674 (match_operand:TF 2 "register_operand" "e")
2675 (match_operand:TF 3 "register_operand" "0")))]
2676 "TARGET_V9 && TARGET_FPU"
2677 "fmovq%C1 %%icc,%2,%0"
2678 [(set_attr "type" "cmove")])
2680 (define_insn "*movsf_ccx_sp64"
2681 [(set (match_operand:SF 0 "register_operand" "=f")
2682 (if_then_else (match_operator 1 "comparison_operator"
2683 [(reg:CCX 0) (const_int 0)])
2684 (match_operand:SF 2 "register_operand" "f")
2685 (match_operand:SF 3 "register_operand" "0")))]
2686 "TARGET_ARCH64 && TARGET_FPU"
2687 "fmovs%C1 %%xcc,%2,%0"
2688 [(set_attr "type" "cmove")])
2690 (define_insn "*movdf_ccx_sp64"
2691 [(set (match_operand:DF 0 "register_operand" "=e")
2692 (if_then_else (match_operator 1 "comparison_operator"
2693 [(reg:CCX 0) (const_int 0)])
2694 (match_operand:DF 2 "register_operand" "e")
2695 (match_operand:DF 3 "register_operand" "0")))]
2696 "TARGET_ARCH64 && TARGET_FPU"
2697 "fmovd%C1 %%xcc,%2,%0"
2698 [(set_attr "type" "cmove")])
2700 (define_insn "*movtf_ccx_sp64"
2701 [(set (match_operand:TF 0 "register_operand" "=e")
2702 (if_then_else (match_operator 1 "comparison_operator"
2703 [(reg:CCX 0) (const_int 0)])
2704 (match_operand:TF 2 "register_operand" "e")
2705 (match_operand:TF 3 "register_operand" "0")))]
2706 "TARGET_ARCH64 && TARGET_FPU"
2707 "fmovq%C1 %%xcc,%2,%0"
2708 [(set_attr "type" "cmove")])
2710 ;;- zero extension instructions
2712 ;; These patterns originally accepted general_operands, however, slightly
2713 ;; better code is generated by only accepting register_operands, and then
2714 ;; letting combine generate the ldu[hb] insns.
2716 (define_expand "zero_extendhisi2"
2717 [(set (match_operand:SI 0 "register_operand" "")
2718 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
2722 rtx temp = gen_reg_rtx (SImode);
2723 rtx shift_16 = gen_rtx (CONST_INT, VOIDmode, 16);
2724 int op1_subword = 0;
2726 if (GET_CODE (operand1) == SUBREG)
2728 op1_subword = SUBREG_WORD (operand1);
2729 operand1 = XEXP (operand1, 0);
2732 emit_insn (gen_ashlsi3 (temp, gen_rtx (SUBREG, SImode, operand1,
2735 emit_insn (gen_lshrsi3 (operand0, temp, shift_16));
2739 (define_insn "*zero_extendhisi2_insn"
2740 [(set (match_operand:SI 0 "register_operand" "=r")
2741 (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
2744 [(set_attr "type" "load")])
2746 (define_expand "zero_extendqihi2"
2747 [(set (match_operand:HI 0 "register_operand" "")
2748 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
2752 (define_insn "*zero_extendqihi2_insn"
2753 [(set (match_operand:HI 0 "register_operand" "=r,r")
2754 (zero_extend:HI (match_operand:QI 1 "sparc_operand" "r,Q")))]
2755 "GET_CODE (operands[1]) != CONST_INT"
2759 [(set_attr "type" "unary,load")
2760 (set_attr "length" "1")])
2762 (define_expand "zero_extendqisi2"
2763 [(set (match_operand:SI 0 "register_operand" "")
2764 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
2768 (define_insn "*zero_extendqisi2_insn"
2769 [(set (match_operand:SI 0 "register_operand" "=r,r")
2770 (zero_extend:SI (match_operand:QI 1 "sparc_operand" "r,Q")))]
2771 "GET_CODE (operands[1]) != CONST_INT"
2775 [(set_attr "type" "unary,load")
2776 (set_attr "length" "1")])
2778 (define_expand "zero_extendqidi2"
2779 [(set (match_operand:DI 0 "register_operand" "")
2780 (zero_extend:DI (match_operand:QI 1 "register_operand" "")))]
2784 (define_insn "*zero_extendqidi2_insn"
2785 [(set (match_operand:DI 0 "register_operand" "=r,r")
2786 (zero_extend:DI (match_operand:QI 1 "sparc_operand" "r,Q")))]
2787 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
2791 [(set_attr "type" "unary,load")
2792 (set_attr "length" "1")])
2794 (define_expand "zero_extendhidi2"
2795 [(set (match_operand:DI 0 "register_operand" "")
2796 (zero_extend:DI (match_operand:HI 1 "register_operand" "")))]
2800 rtx temp = gen_reg_rtx (DImode);
2801 rtx shift_48 = gen_rtx (CONST_INT, VOIDmode, 48);
2802 int op1_subword = 0;
2804 if (GET_CODE (operand1) == SUBREG)
2806 op1_subword = SUBREG_WORD (operand1);
2807 operand1 = XEXP (operand1, 0);
2810 emit_insn (gen_ashldi3 (temp, gen_rtx (SUBREG, DImode, operand1,
2813 emit_insn (gen_lshrdi3 (operand0, temp, shift_48));
2817 (define_insn "*zero_extendhidi2_insn"
2818 [(set (match_operand:DI 0 "register_operand" "=r")
2819 (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
2822 [(set_attr "type" "load")])
2824 ;; ??? Write truncdisi pattern using sra?
2826 (define_expand "zero_extendsidi2"
2827 [(set (match_operand:DI 0 "register_operand" "")
2828 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
2832 (define_insn "*zero_extendsidi2_insn"
2833 [(set (match_operand:DI 0 "register_operand" "=r,r")
2834 (zero_extend:DI (match_operand:SI 1 "sparc_operand" "r,Q")))]
2835 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
2839 [(set_attr "type" "unary,load")
2840 (set_attr "length" "1")])
2842 ;; Simplify comparisons of extended values.
2844 (define_insn "*cmp_zero_extendqisi2"
2846 (compare:CC (zero_extend:SI (match_operand:QI 0 "register_operand" "r"))
2849 "andcc %0,0xff,%%g0"
2850 [(set_attr "type" "compare")])
2852 (define_insn "*cmp_zero_extendqisi2_set"
2854 (compare:CC (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
2856 (set (match_operand:SI 0 "register_operand" "=r")
2857 (zero_extend:SI (match_dup 1)))]
2860 [(set_attr "type" "unary")])
2862 ;; Similarly, handle SI->QI mode truncation followed by a compare.
2864 (define_insn "*cmp_siqi_trunc"
2866 (compare:CC (subreg:QI (match_operand:SI 0 "register_operand" "r") 0)
2869 "andcc %0,0xff,%%g0"
2870 [(set_attr "type" "compare")])
2872 (define_insn "*cmp_siqi_trunc_set"
2874 (compare:CC (subreg:QI (match_operand:SI 1 "register_operand" "r") 0)
2876 (set (match_operand:QI 0 "register_operand" "=r")
2880 [(set_attr "type" "unary")])
2882 ;;- sign extension instructions
2884 ;; These patterns originally accepted general_operands, however, slightly
2885 ;; better code is generated by only accepting register_operands, and then
2886 ;; letting combine generate the lds[hb] insns.
2888 (define_expand "extendhisi2"
2889 [(set (match_operand:SI 0 "register_operand" "")
2890 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
2894 rtx temp = gen_reg_rtx (SImode);
2895 rtx shift_16 = gen_rtx (CONST_INT, VOIDmode, 16);
2896 int op1_subword = 0;
2898 if (GET_CODE (operand1) == SUBREG)
2900 op1_subword = SUBREG_WORD (operand1);
2901 operand1 = XEXP (operand1, 0);
2904 emit_insn (gen_ashlsi3 (temp, gen_rtx (SUBREG, SImode, operand1,
2907 emit_insn (gen_ashrsi3 (operand0, temp, shift_16));
2911 (define_insn "*sign_extendhisi2_insn"
2912 [(set (match_operand:SI 0 "register_operand" "=r")
2913 (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
2916 [(set_attr "type" "load")])
2918 (define_expand "extendqihi2"
2919 [(set (match_operand:HI 0 "register_operand" "")
2920 (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
2924 rtx temp = gen_reg_rtx (SImode);
2925 rtx shift_24 = gen_rtx (CONST_INT, VOIDmode, 24);
2926 int op1_subword = 0;
2927 int op0_subword = 0;
2929 if (GET_CODE (operand1) == SUBREG)
2931 op1_subword = SUBREG_WORD (operand1);
2932 operand1 = XEXP (operand1, 0);
2934 if (GET_CODE (operand0) == SUBREG)
2936 op0_subword = SUBREG_WORD (operand0);
2937 operand0 = XEXP (operand0, 0);
2939 emit_insn (gen_ashlsi3 (temp, gen_rtx (SUBREG, SImode, operand1,
2942 if (GET_MODE (operand0) != SImode)
2943 operand0 = gen_rtx (SUBREG, SImode, operand0, op0_subword);
2944 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
2948 (define_insn "*sign_extendqihi2_insn"
2949 [(set (match_operand:HI 0 "register_operand" "=r")
2950 (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
2953 [(set_attr "type" "load")])
2955 (define_expand "extendqisi2"
2956 [(set (match_operand:SI 0 "register_operand" "")
2957 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
2961 rtx temp = gen_reg_rtx (SImode);
2962 rtx shift_24 = gen_rtx (CONST_INT, VOIDmode, 24);
2963 int op1_subword = 0;
2965 if (GET_CODE (operand1) == SUBREG)
2967 op1_subword = SUBREG_WORD (operand1);
2968 operand1 = XEXP (operand1, 0);
2971 emit_insn (gen_ashlsi3 (temp, gen_rtx (SUBREG, SImode, operand1,
2974 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
2978 (define_insn "*sign_extendqisi2_insn"
2979 [(set (match_operand:SI 0 "register_operand" "=r")
2980 (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
2983 [(set_attr "type" "load")])
2985 (define_expand "extendqidi2"
2986 [(set (match_operand:DI 0 "register_operand" "")
2987 (sign_extend:DI (match_operand:QI 1 "register_operand" "")))]
2991 rtx temp = gen_reg_rtx (DImode);
2992 rtx shift_56 = gen_rtx (CONST_INT, VOIDmode, 56);
2993 int op1_subword = 0;
2995 if (GET_CODE (operand1) == SUBREG)
2997 op1_subword = SUBREG_WORD (operand1);
2998 operand1 = XEXP (operand1, 0);
3001 emit_insn (gen_ashldi3 (temp, gen_rtx (SUBREG, DImode, operand1,
3004 emit_insn (gen_ashrdi3 (operand0, temp, shift_56));
3008 (define_insn "*sign_extendqidi2_insn"
3009 [(set (match_operand:DI 0 "register_operand" "=r")
3010 (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
3013 [(set_attr "type" "load")])
3015 (define_expand "extendhidi2"
3016 [(set (match_operand:DI 0 "register_operand" "")
3017 (sign_extend:DI (match_operand:HI 1 "register_operand" "")))]
3021 rtx temp = gen_reg_rtx (DImode);
3022 rtx shift_48 = gen_rtx (CONST_INT, VOIDmode, 48);
3023 int op1_subword = 0;
3025 if (GET_CODE (operand1) == SUBREG)
3027 op1_subword = SUBREG_WORD (operand1);
3028 operand1 = XEXP (operand1, 0);
3031 emit_insn (gen_ashldi3 (temp, gen_rtx (SUBREG, DImode, operand1,
3034 emit_insn (gen_ashrdi3 (operand0, temp, shift_48));
3038 (define_insn "*sign_extendhidi2_insn"
3039 [(set (match_operand:DI 0 "register_operand" "=r")
3040 (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
3043 [(set_attr "type" "load")])
3045 (define_expand "extendsidi2"
3046 [(set (match_operand:DI 0 "register_operand" "")
3047 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
3051 (define_insn "*sign_extendsidi2_insn"
3052 [(set (match_operand:DI 0 "register_operand" "=r,r")
3053 (sign_extend:DI (match_operand:SI 1 "sparc_operand" "r,Q")))]
3058 [(set_attr "type" "unary,load")
3059 (set_attr "length" "1")])
3061 ;; Special pattern for optimizing bit-field compares. This is needed
3062 ;; because combine uses this as a canonical form.
3064 (define_insn "*cmp_zero_extract"
3067 (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
3068 (match_operand:SI 1 "small_int" "n")
3069 (match_operand:SI 2 "small_int" "n"))
3071 "INTVAL (operands[2]) > 19"
3074 int len = INTVAL (operands[1]);
3075 int pos = 32 - INTVAL (operands[2]) - len;
3076 unsigned mask = ((1 << len) - 1) << pos;
3078 operands[1] = gen_rtx (CONST_INT, VOIDmode, mask);
3079 return \"andcc %0,%1,%%g0\";
3082 (define_insn "*cmp_zero_extract_sp64"
3085 (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
3086 (match_operand:SI 1 "small_int" "n")
3087 (match_operand:SI 2 "small_int" "n"))
3089 "TARGET_ARCH64 && INTVAL (operands[2]) > 51"
3092 int len = INTVAL (operands[1]);
3093 int pos = 64 - INTVAL (operands[2]) - len;
3094 unsigned mask = ((1 << len) - 1) << pos;
3096 operands[1] = gen_rtx (CONST_INT, VOIDmode, mask);
3097 return \"andcc %0,%1,%%g0\";
3100 ;; Conversions between float, double and long double.
3102 (define_insn "extendsfdf2"
3103 [(set (match_operand:DF 0 "register_operand" "=e")
3105 (match_operand:SF 1 "register_operand" "f")))]
3108 [(set_attr "type" "fp")])
3110 (define_insn "extendsftf2"
3111 [(set (match_operand:TF 0 "register_operand" "=e")
3113 (match_operand:SF 1 "register_operand" "f")))]
3114 "TARGET_FPU && TARGET_HARD_QUAD"
3116 [(set_attr "type" "fp")])
3118 (define_insn "extenddftf2"
3119 [(set (match_operand:TF 0 "register_operand" "=e")
3121 (match_operand:DF 1 "register_operand" "e")))]
3122 "TARGET_FPU && TARGET_HARD_QUAD"
3124 [(set_attr "type" "fp")])
3126 (define_insn "truncdfsf2"
3127 [(set (match_operand:SF 0 "register_operand" "=f")
3129 (match_operand:DF 1 "register_operand" "e")))]
3132 [(set_attr "type" "fp")])
3134 (define_insn "trunctfsf2"
3135 [(set (match_operand:SF 0 "register_operand" "=f")
3137 (match_operand:TF 1 "register_operand" "e")))]
3138 "TARGET_FPU && TARGET_HARD_QUAD"
3140 [(set_attr "type" "fp")])
3142 (define_insn "trunctfdf2"
3143 [(set (match_operand:DF 0 "register_operand" "=e")
3145 (match_operand:TF 1 "register_operand" "e")))]
3146 "TARGET_FPU && TARGET_HARD_QUAD"
3148 [(set_attr "type" "fp")])
3150 ;; Conversion between fixed point and floating point.
3152 (define_insn "floatsisf2"
3153 [(set (match_operand:SF 0 "register_operand" "=f")
3154 (float:SF (match_operand:SI 1 "register_operand" "f")))]
3157 [(set_attr "type" "fp")])
3159 (define_insn "floatsidf2"
3160 [(set (match_operand:DF 0 "register_operand" "=e")
3161 (float:DF (match_operand:SI 1 "register_operand" "f")))]
3164 [(set_attr "type" "fp")])
3166 (define_insn "floatsitf2"
3167 [(set (match_operand:TF 0 "register_operand" "=e")
3168 (float:TF (match_operand:SI 1 "register_operand" "f")))]
3169 "TARGET_FPU && TARGET_HARD_QUAD"
3171 [(set_attr "type" "fp")])
3173 ;; Now the same for 64 bit sources.
3174 ;; ??? We cannot put DImode values in fp regs (see below near fix_truncdfsi2).
3176 (define_expand "floatdisf2"
3177 [(parallel [(set (match_operand:SF 0 "register_operand" "")
3178 (float:SF (match_operand:DI 1 "general_operand" "")))
3179 (clobber (match_dup 2))
3180 (clobber (match_dup 3))])]
3181 "TARGET_ARCH64 && TARGET_FPU"
3184 operands[2] = gen_reg_rtx (DFmode);
3185 operands[3] = sparc64_fpconv_stack_temp ();
3188 (define_expand "floatdidf2"
3189 [(parallel [(set (match_operand:DF 0 "register_operand" "")
3190 (float:DF (match_operand:DI 1 "general_operand" "")))
3191 (clobber (match_dup 2))
3192 (clobber (match_dup 3))])]
3193 "TARGET_ARCH64 && TARGET_FPU"
3196 operands[2] = gen_reg_rtx (DFmode);
3197 operands[3] = sparc64_fpconv_stack_temp ();
3200 (define_expand "floatditf2"
3201 [(parallel [(set (match_operand:TF 0 "register_operand" "")
3202 (float:TF (match_operand:DI 1 "general_operand" "")))
3203 (clobber (match_dup 2))
3204 (clobber (match_dup 3))])]
3205 "TARGET_ARCH64 && TARGET_FPU && TARGET_HARD_QUAD"
3208 operands[2] = gen_reg_rtx (DFmode);
3209 operands[3] = sparc64_fpconv_stack_temp ();
3212 (define_insn "*floatdisf2_insn"
3213 [(parallel [(set (match_operand:SF 0 "register_operand" "=f")
3214 (float:SF (match_operand:DI 1 "general_operand" "rm")))
3215 (clobber (match_operand:DF 2 "register_operand" "=&e"))
3216 (clobber (match_operand:DI 3 "memory_operand" "m"))])]
3217 "TARGET_ARCH64 && TARGET_FPU"
3220 if (GET_CODE (operands[1]) == MEM)
3221 output_asm_insn (\"ldd %1,%2\", operands);
3223 output_asm_insn (\"stx %1,%3\;ldd %3,%2\", operands);
3224 return \"fxtos %2,%0\";
3226 [(set_attr "type" "fp")
3227 (set_attr "length" "3")])
3229 (define_insn "*floatdidf2_insn"
3230 [(parallel [(set (match_operand:DF 0 "register_operand" "=e")
3231 (float:DF (match_operand:DI 1 "general_operand" "rm")))
3232 (clobber (match_operand:DF 2 "register_operand" "=&e"))
3233 (clobber (match_operand:DI 3 "memory_operand" "m"))])]
3234 "TARGET_ARCH64 && TARGET_FPU"
3237 if (GET_CODE (operands[1]) == MEM)
3238 output_asm_insn (\"ldd %1,%2\", operands);
3240 output_asm_insn (\"stx %1,%3\;ldd %3,%2\", operands);
3241 return \"fxtod %2,%0\";
3243 [(set_attr "type" "fp")
3244 (set_attr "length" "3")])
3246 (define_insn "*floatditf2_insn"
3247 [(parallel [(set (match_operand:TF 0 "register_operand" "=e")
3248 (float:TF (match_operand:DI 1 "general_operand" "rm")))
3249 (clobber (match_operand:DF 2 "register_operand" "=&e"))
3250 (clobber (match_operand:DI 3 "memory_operand" "m"))])]
3251 "TARGET_ARCH64 && TARGET_FPU && TARGET_HARD_QUAD"
3254 if (GET_CODE (operands[1]) == MEM)
3255 output_asm_insn (\"ldd %1,%2\", operands);
3257 output_asm_insn (\"stx %1,%3\;ldd %3,%2\", operands);
3258 return \"fxtoq %2,%0\";
3260 [(set_attr "type" "fp")
3261 (set_attr "length" "3")])
3263 ;; ??? Ideally, these are what we would like to use.
3265 (define_insn "floatdisf2_sp64"
3266 [(set (match_operand:SF 0 "register_operand" "=f")
3267 (float:SF (match_operand:DI 1 "register_operand" "e")))]
3268 "0 && TARGET_ARCH64 && TARGET_FPU"
3270 [(set_attr "type" "fp")])
3272 (define_insn "floatdidf2_sp64"
3273 [(set (match_operand:DF 0 "register_operand" "=e")
3274 (float:DF (match_operand:DI 1 "register_operand" "e")))]
3275 "0 && TARGET_ARCH64 && TARGET_FPU"
3277 [(set_attr "type" "fp")])
3279 (define_insn "floatditf2_sp64"
3280 [(set (match_operand:TF 0 "register_operand" "=e")
3281 (float:TF (match_operand:DI 1 "register_operand" "e")))]
3282 "0 && TARGET_ARCH64 && TARGET_FPU && TARGET_HARD_QUAD"
3284 [(set_attr "type" "fp")])
3286 ;; Convert a float to an actual integer.
3287 ;; Truncation is performed as part of the conversion.
3289 (define_insn "fix_truncsfsi2"
3290 [(set (match_operand:SI 0 "register_operand" "=f")
3291 (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
3294 [(set_attr "type" "fp")])
3296 (define_insn "fix_truncdfsi2"
3297 [(set (match_operand:SI 0 "register_operand" "=f")
3298 (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
3301 [(set_attr "type" "fp")])
3303 (define_insn "fix_trunctfsi2"
3304 [(set (match_operand:SI 0 "register_operand" "=f")
3305 (fix:SI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
3306 "TARGET_FPU && TARGET_HARD_QUAD"
3308 [(set_attr "type" "fp")])
3310 ;; Now the same, for 64-bit targets
3311 ;; ??? We try to work around an interesting problem.
3312 ;; If gcc tries to do a subreg on the result it will get the wrong answer:
3313 ;; "(subreg:SI (reg:DI M int-reg) 0)" is the same as
3314 ;; "(subreg:SI (reg:DI N float-reg) 1)", but gcc does not know how to change
3315 ;; the "0" to a "1". One could enhance alter_subreg but it is not clear how to
3318 (define_expand "fix_truncsfdi2"
3319 [(parallel [(set (match_operand:DI 0 "general_operand" "")
3320 (fix:DI (fix:SF (match_operand:SF 1 "register_operand" ""))))
3321 (clobber (match_dup 2))
3322 (clobber (match_dup 3))])]
3323 "TARGET_ARCH64 && TARGET_FPU"
3326 operands[2] = gen_reg_rtx (DFmode);
3327 operands[3] = sparc64_fpconv_stack_temp ();
3330 (define_expand "fix_truncdfdi2"
3331 [(parallel [(set (match_operand:DI 0 "general_operand" "")
3332 (fix:DI (fix:DF (match_operand:DF 1 "register_operand" ""))))
3333 (clobber (match_dup 2))
3334 (clobber (match_dup 3))])]
3335 "TARGET_ARCH64 && TARGET_FPU"
3338 operands[2] = gen_reg_rtx (DFmode);
3339 operands[3] = sparc64_fpconv_stack_temp ();
3342 (define_expand "fix_trunctfdi2"
3343 [(parallel [(set (match_operand:DI 0 "general_operand" "")
3344 (fix:DI (fix:TF (match_operand:TF 1 "register_operand" ""))))
3345 (clobber (match_dup 2))
3346 (clobber (match_dup 3))])]
3347 "TARGET_ARCH64 && TARGET_FPU && TARGET_HARD_QUAD"
3350 operands[2] = gen_reg_rtx (DFmode);
3351 operands[3] = sparc64_fpconv_stack_temp ();
3354 (define_insn "*fix_truncsfdi2_insn"
3355 [(parallel [(set (match_operand:DI 0 "general_operand" "=rm")
3356 (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))
3357 (clobber (match_operand:DF 2 "register_operand" "=&e"))
3358 (clobber (match_operand:DI 3 "memory_operand" "m"))])]
3359 "TARGET_ARCH64 && TARGET_FPU"
3362 output_asm_insn (\"fstox %1,%2\", operands);
3363 if (GET_CODE (operands[0]) == MEM)
3364 return \"std %2,%0\";
3366 return \"std %2,%3\;ldx %3,%0\";
3368 [(set_attr "type" "fp")
3369 (set_attr "length" "3")])
3371 (define_insn "*fix_truncdfdi2_insn"
3372 [(parallel [(set (match_operand:DI 0 "general_operand" "=rm")
3373 (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "e"))))
3374 (clobber (match_operand:DF 2 "register_operand" "=&e"))
3375 (clobber (match_operand:DI 3 "memory_operand" "m"))])]
3376 "TARGET_ARCH64 && TARGET_FPU"
3379 output_asm_insn (\"fdtox %1,%2\", operands);
3380 if (GET_CODE (operands[0]) == MEM)
3381 return \"std %2,%0\";
3383 return \"std %2,%3\;ldx %3,%0\";
3385 [(set_attr "type" "fp")
3386 (set_attr "length" "3")])
3388 (define_insn "*fix_trunctfdi2_insn"
3389 [(parallel [(set (match_operand:DI 0 "general_operand" "=rm")
3390 (fix:DI (fix:TF (match_operand:TF 1 "register_operand" "e"))))
3391 (clobber (match_operand:DF 2 "register_operand" "=&e"))
3392 (clobber (match_operand:DI 3 "memory_operand" "m"))])]
3393 "TARGET_ARCH64 && TARGET_FPU && TARGET_HARD_QUAD"
3396 output_asm_insn (\"fqtox %1,%2\", operands);
3397 if (GET_CODE (operands[0]) == MEM)
3398 return \"std %2,%0\";
3400 return \"std %2,%3\;ldx %3,%0\";
3402 [(set_attr "type" "fp")
3403 (set_attr "length" "3")])
3405 ;; ??? Ideally, these are what we would like to use.
3407 (define_insn "fix_truncsfdi2_sp64"
3408 [(set (match_operand:DI 0 "register_operand" "=e")
3409 (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
3410 "0 && TARGET_ARCH64 && TARGET_FPU"
3412 [(set_attr "type" "fp")])
3414 (define_insn "fix_truncdfdi2_sp64"
3415 [(set (match_operand:DI 0 "register_operand" "=e")
3416 (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
3417 "0 && TARGET_ARCH64 && TARGET_FPU"
3419 [(set_attr "type" "fp")])
3421 (define_insn "fix_trunctfdi2_sp64"
3422 [(set (match_operand:DI 0 "register_operand" "=e")
3423 (fix:DI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
3424 "0 && TARGET_ARCH64 && TARGET_FPU && TARGET_HARD_QUAD"
3426 [(set_attr "type" "fp")])
3428 ;;- arithmetic instructions
3430 (define_expand "adddi3"
3431 [(set (match_operand:DI 0 "register_operand" "=r")
3432 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
3433 (match_operand:DI 2 "arith_double_operand" "rHI")))]
3437 if (! TARGET_ARCH64)
3439 emit_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (2,
3440 gen_rtx (SET, VOIDmode, operands[0],
3441 gen_rtx (PLUS, DImode, operands[1],
3443 gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, 0)))));
3448 (define_insn "*adddi3_sp32"
3449 [(set (match_operand:DI 0 "register_operand" "=r")
3450 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
3451 (match_operand:DI 2 "arith_double_operand" "rHI")))
3452 (clobber (reg:SI 0))]
3456 rtx op2 = operands[2];
3458 /* If constant is positive, upper bits zeroed, otherwise unchanged.
3459 Give the assembler a chance to pick the move instruction. */
3460 if (GET_CODE (op2) == CONST_INT)
3462 int sign = INTVAL (op2);
3464 return \"addcc %R1,%2,%R0\;addx %1,-1,%0\";
3465 return \"addcc %R1,%2,%R0\;addx %1,0,%0\";
3467 else if (GET_CODE (op2) == CONST_DOUBLE)
3470 xoperands[0] = operands[0];
3471 xoperands[1] = operands[1];
3472 xoperands[2] = GEN_INT (CONST_DOUBLE_LOW (op2));
3473 xoperands[3] = GEN_INT (CONST_DOUBLE_HIGH (op2));
3474 if (xoperands[2] == const0_rtx && xoperands[0] == xoperands[1])
3475 output_asm_insn (\"add %1,%3,%0\", xoperands);
3477 output_asm_insn (\"addcc %R1,%2,%R0\;addx %1,%3,%0\", xoperands);
3480 return \"addcc %R1,%R2,%R0\;addx %1,%2,%0\";
3482 [(set_attr "length" "2")])
3484 (define_insn "*adddi3_sp64"
3485 [(set (match_operand:DI 0 "register_operand" "=r")
3486 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
3487 (match_operand:DI 2 "arith_double_operand" "rHI")))]
3491 (define_insn "addsi3"
3492 [(set (match_operand:SI 0 "register_operand" "=r")
3493 (plus:SI (match_operand:SI 1 "arith_operand" "%r")
3494 (match_operand:SI 2 "arith_operand" "rI")))]
3497 [(set_attr "type" "ialu")])
3499 (define_insn "*cmp_cc_plus"
3500 [(set (reg:CC_NOOV 0)
3501 (compare:CC_NOOV (plus:SI (match_operand:SI 0 "arith_operand" "%r")
3502 (match_operand:SI 1 "arith_operand" "rI"))
3506 [(set_attr "type" "compare")])
3508 (define_insn "*cmp_ccx_plus"
3509 [(set (reg:CCX_NOOV 0)
3510 (compare:CCX_NOOV (plus:DI (match_operand:DI 0 "arith_double_operand" "%r")
3511 (match_operand:DI 1 "arith_double_operand" "rHI"))
3515 [(set_attr "type" "compare")])
3517 (define_insn "*cmp_cc_plus_set"
3518 [(set (reg:CC_NOOV 0)
3519 (compare:CC_NOOV (plus:SI (match_operand:SI 1 "arith_operand" "%r")
3520 (match_operand:SI 2 "arith_operand" "rI"))
3522 (set (match_operand:SI 0 "register_operand" "=r")
3523 (plus:SI (match_dup 1) (match_dup 2)))]
3527 (define_insn "*cmp_ccx_plus_set"
3528 [(set (reg:CCX_NOOV 0)
3529 (compare:CCX_NOOV (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
3530 (match_operand:DI 2 "arith_double_operand" "rHI"))
3532 (set (match_operand:DI 0 "register_operand" "=r")
3533 (plus:DI (match_dup 1) (match_dup 2)))]
3537 (define_expand "subdi3"
3538 [(set (match_operand:DI 0 "register_operand" "=r")
3539 (minus:DI (match_operand:DI 1 "register_operand" "r")
3540 (match_operand:DI 2 "arith_double_operand" "rHI")))]
3544 if (! TARGET_ARCH64)
3546 emit_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (2,
3547 gen_rtx (SET, VOIDmode, operands[0],
3548 gen_rtx (MINUS, DImode, operands[1],
3550 gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, 0)))));
3555 (define_insn "*subdi3_sp32"
3556 [(set (match_operand:DI 0 "register_operand" "=r")
3557 (minus:DI (match_operand:DI 1 "register_operand" "r")
3558 (match_operand:DI 2 "arith_double_operand" "rHI")))
3559 (clobber (reg:SI 0))]
3563 rtx op2 = operands[2];
3565 /* If constant is positive, upper bits zeroed, otherwise unchanged.
3566 Give the assembler a chance to pick the move instruction. */
3567 if (GET_CODE (op2) == CONST_INT)
3569 int sign = INTVAL (op2);
3571 return \"subcc %R1,%2,%R0\;subx %1,-1,%0\";
3572 return \"subcc %R1,%2,%R0\;subx %1,0,%0\";
3574 else if (GET_CODE (op2) == CONST_DOUBLE)
3577 xoperands[0] = operands[0];
3578 xoperands[1] = operands[1];
3579 xoperands[2] = GEN_INT (CONST_DOUBLE_LOW (op2));
3580 xoperands[3] = GEN_INT (CONST_DOUBLE_HIGH (op2));
3581 if (xoperands[2] == const0_rtx && xoperands[0] == xoperands[1])
3582 output_asm_insn (\"sub %1,%3,%0\", xoperands);
3584 output_asm_insn (\"subcc %R1,%2,%R0\;subx %1,%3,%0\", xoperands);
3587 return \"subcc %R1,%R2,%R0\;subx %1,%2,%0\";
3589 [(set_attr "length" "2")])
3591 (define_insn "*subdi3_sp64"
3592 [(set (match_operand:DI 0 "register_operand" "=r")
3593 (minus:DI (match_operand:DI 1 "register_operand" "r")
3594 (match_operand:DI 2 "arith_double_operand" "rHI")))]
3598 (define_insn "subsi3"
3599 [(set (match_operand:SI 0 "register_operand" "=r")
3600 (minus:SI (match_operand:SI 1 "register_operand" "r")
3601 (match_operand:SI 2 "arith_operand" "rI")))]
3604 [(set_attr "type" "ialu")])
3606 (define_insn "*cmp_minus_cc"
3607 [(set (reg:CC_NOOV 0)
3608 (compare:CC_NOOV (minus:SI (match_operand:SI 0 "register_operand" "r")
3609 (match_operand:SI 1 "arith_operand" "rI"))
3613 [(set_attr "type" "compare")])
3615 (define_insn "*cmp_minus_ccx"
3616 [(set (reg:CCX_NOOV 0)
3617 (compare:CCX_NOOV (minus:DI (match_operand:DI 0 "register_operand" "r")
3618 (match_operand:DI 1 "arith_double_operand" "rHI"))
3622 [(set_attr "type" "compare")])
3624 (define_insn "*cmp_minus_cc_set"
3625 [(set (reg:CC_NOOV 0)
3626 (compare:CC_NOOV (minus:SI (match_operand:SI 1 "register_operand" "r")
3627 (match_operand:SI 2 "arith_operand" "rI"))
3629 (set (match_operand:SI 0 "register_operand" "=r")
3630 (minus:SI (match_dup 1) (match_dup 2)))]
3634 (define_insn "*cmp_minus_ccx_set"
3635 [(set (reg:CCX_NOOV 0)
3636 (compare:CCX_NOOV (minus:DI (match_operand:DI 1 "register_operand" "r")
3637 (match_operand:DI 2 "arith_double_operand" "rHI"))
3639 (set (match_operand:DI 0 "register_operand" "=r")
3640 (minus:DI (match_dup 1) (match_dup 2)))]
3644 ;; Integer Multiply/Divide.
3646 ;; The 32 bit multiply/divide instructions are deprecated on v9 and shouldn't
3647 ;; we used. We still use them in 32 bit v9 compilers.
3648 ;; The 64 bit v9 compiler will (/should) widen the args and use muldi3.
3650 (define_insn "mulsi3"
3651 [(set (match_operand:SI 0 "register_operand" "=r")
3652 (mult:SI (match_operand:SI 1 "arith_operand" "%r")
3653 (match_operand:SI 2 "arith_operand" "rI")))]
3654 "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS"
3656 [(set_attr "type" "imul")])
3658 (define_insn "muldi3"
3659 [(set (match_operand:DI 0 "register_operand" "=r")
3660 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r")
3661 (match_operand:DI 2 "arith_double_operand" "rHI")))]
3665 ;; It is not known whether this will match.
3667 (define_insn "*cmp_mul_set"
3668 [(set (match_operand:SI 0 "register_operand" "=r")
3669 (mult:SI (match_operand:SI 1 "arith_operand" "%r")
3670 (match_operand:SI 2 "arith_operand" "rI")))
3671 (set (reg:CC_NOOV 0)
3672 (compare:CC_NOOV (mult:SI (match_dup 1) (match_dup 2))
3674 "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS"
3676 [(set_attr "type" "imul")])
3678 (define_expand "mulsidi3"
3679 [(set (match_operand:DI 0 "register_operand" "")
3680 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
3681 (sign_extend:DI (match_operand:SI 2 "arith_operand" ""))))]
3682 "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS"
3685 if (CONSTANT_P (operands[2]))
3687 emit_insn (gen_const_mulsidi3 (operands[0], operands[1], operands[2]));
3692 (define_insn "*mulsidi3_sp32"
3693 [(set (match_operand:DI 0 "register_operand" "=r")
3694 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
3695 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
3696 "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS"
3697 "smul %1,%2,%R0\;rd %%y,%0"
3698 [(set_attr "length" "2")])
3700 ;; Extra pattern, because sign_extend of a constant isn't valid.
3702 (define_insn "const_mulsidi3"
3703 [(set (match_operand:DI 0 "register_operand" "=r")
3704 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
3705 (match_operand:SI 2 "small_int" "I")))]
3706 "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS"
3707 "smul %1,%2,%R0\;rd %%y,%0"
3708 [(set_attr "length" "2")])
3710 (define_expand "smulsi3_highpart"
3711 [(set (match_operand:SI 0 "register_operand" "")
3713 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
3714 (sign_extend:DI (match_operand:SI 2 "arith_operand" "")))
3716 "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS"
3719 if (CONSTANT_P (operands[2]))
3721 emit_insn (gen_const_smulsi3_highpart (operands[0], operands[1], operands[2]));
3726 (define_insn "*smulsidi3_highpart_sp32"
3727 [(set (match_operand:SI 0 "register_operand" "=r")
3729 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
3730 (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
3732 "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS"
3733 "smul %1,%2,%%g0\;rd %%y,%0"
3734 [(set_attr "length" "2")])
3736 (define_insn "const_smulsi3_highpart"
3737 [(set (match_operand:SI 0 "register_operand" "=r")
3739 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
3740 (match_operand:SI 2 "register_operand" "r"))
3742 "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS"
3743 "smul %1,%2,%%g0\;rd %%y,%0"
3744 [(set_attr "length" "2")])
3746 (define_expand "umulsidi3"
3747 [(set (match_operand:DI 0 "register_operand" "")
3748 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
3749 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" ""))))]
3750 "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS"
3753 if (CONSTANT_P (operands[2]))
3755 emit_insn (gen_const_umulsidi3 (operands[0], operands[1], operands[2]));
3760 (define_insn "*umulsidi3_sp32"
3761 [(set (match_operand:DI 0 "register_operand" "=r")
3762 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
3763 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
3764 "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS"
3765 "umul %1,%2,%R0\;rd %%y,%0"
3766 [(set_attr "length" "2")])
3768 ;; Extra pattern, because sign_extend of a constant isn't valid.
3770 (define_insn "const_umulsidi3"
3771 [(set (match_operand:DI 0 "register_operand" "=r")
3772 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
3773 (match_operand:SI 2 "uns_small_int" "")))]
3774 "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS"
3775 "umul %1,%2,%R0\;rd %%y,%0"
3776 [(set_attr "length" "2")])
3778 (define_expand "umulsi3_highpart"
3779 [(set (match_operand:SI 0 "register_operand" "")
3781 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
3782 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" "")))
3784 "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS"
3787 if (CONSTANT_P (operands[2]))
3789 emit_insn (gen_const_umulsi3_highpart (operands[0], operands[1], operands[2]));
3794 (define_insn "*umulsidi3_highpart_sp32"
3795 [(set (match_operand:SI 0 "register_operand" "=r")
3797 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
3798 (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
3800 "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS"
3801 "umul %1,%2,%%g0\;rd %%y,%0"
3802 [(set_attr "length" "2")])
3804 (define_insn "const_umulsi3_highpart"
3805 [(set (match_operand:SI 0 "register_operand" "=r")
3807 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
3808 (match_operand:SI 2 "uns_small_int" ""))
3810 "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS"
3811 "umul %1,%2,%%g0\;rd %%y,%0"
3812 [(set_attr "length" "2")])
3814 ;; The v8 architecture specifies that there must be 3 instructions between
3815 ;; a y register write and a use of it for correct results.
3817 (define_insn "divsi3"
3818 [(set (match_operand:SI 0 "register_operand" "=r")
3819 (div:SI (match_operand:SI 1 "register_operand" "r")
3820 (match_operand:SI 2 "arith_operand" "rI")))
3821 (clobber (match_scratch:SI 3 "=&r"))]
3822 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
3826 return \"sra %1,31,%3\;wr %%g0,%3,%%y\;sdiv %1,%2,%0\";
3828 return \"sra %1,31,%3\;wr %%g0,%3,%%y\;nop\;nop\;nop\;sdiv %1,%2,%0\";
3830 [(set (attr "length")
3831 (if_then_else (eq_attr "isa" "v9")
3832 (const_int 3) (const_int 6)))])
3834 (define_insn "divdi3"
3835 [(set (match_operand:DI 0 "register_operand" "=r")
3836 (div:DI (match_operand:DI 1 "register_operand" "r")
3837 (match_operand:DI 2 "arith_double_operand" "rHI")))]
3841 ;; It is not known whether this will match.
3843 (define_insn "*cmp_sdiv_cc_set"
3844 [(set (match_operand:SI 0 "register_operand" "=r")
3845 (div:SI (match_operand:SI 1 "register_operand" "r")
3846 (match_operand:SI 2 "arith_operand" "rI")))
3848 (compare:CC (div:SI (match_dup 1) (match_dup 2))
3850 (clobber (match_scratch:SI 3 "=&r"))]
3851 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
3855 return \"sra %1,31,%3\;wr %%g0,%3,%%y\;sdivcc %1,%2,%0\";
3857 return \"sra %1,31,%3\;wr %%g0,%3,%%y\;nop\;nop\;nop\;sdivcc %1,%2,%0\";
3859 [(set (attr "length")
3860 (if_then_else (eq_attr "isa" "v9")
3861 (const_int 3) (const_int 6)))])
3863 (define_insn "udivsi3"
3864 [(set (match_operand:SI 0 "register_operand" "=r")
3865 (udiv:SI (match_operand:SI 1 "register_operand" "r")
3866 (match_operand:SI 2 "arith_operand" "rI")))]
3867 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
3871 return \"wr %%g0,%%g0,%%y\;udiv %1,%2,%0\";
3873 return \"wr %%g0,%%g0,%%y\;nop\;nop\;nop\;udiv %1,%2,%0\";
3875 [(set (attr "length")
3876 (if_then_else (eq_attr "isa" "v9")
3877 (const_int 2) (const_int 5)))])
3879 (define_insn "udivdi3"
3880 [(set (match_operand:DI 0 "register_operand" "=r")
3881 (udiv:DI (match_operand:DI 1 "register_operand" "r")
3882 (match_operand:DI 2 "arith_double_operand" "rHI")))]
3886 ;; It is not known whether this will match.
3888 (define_insn "*cmp_udiv_cc_set"
3889 [(set (match_operand:SI 0 "register_operand" "=r")
3890 (udiv:SI (match_operand:SI 1 "register_operand" "r")
3891 (match_operand:SI 2 "arith_operand" "rI")))
3893 (compare:CC (udiv:SI (match_dup 1) (match_dup 2))
3895 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
3899 return \"wr %%g0,%%g0,%%y\;udivcc %1,%2,%0\";
3901 return \"wr %%g0,%%g0,%%y\;nop\;nop\;nop\;udivcc %1,%2,%0\";
3903 [(set (attr "length")
3904 (if_then_else (eq_attr "isa" "v9")
3905 (const_int 2) (const_int 5)))])
3907 ;;- Boolean instructions
3908 ;; We define DImode `and` so with DImode `not` we can get
3909 ;; DImode `andn`. Other combinations are possible.
3911 (define_expand "anddi3"
3912 [(set (match_operand:DI 0 "register_operand" "")
3913 (and:DI (match_operand:DI 1 "arith_double_operand" "")
3914 (match_operand:DI 2 "arith_double_operand" "")))]
3918 (define_insn "*anddi3_sp32"
3919 [(set (match_operand:DI 0 "register_operand" "=r")
3920 (and:DI (match_operand:DI 1 "arith_double_operand" "%r")
3921 (match_operand:DI 2 "arith_double_operand" "rHI")))]
3925 rtx op2 = operands[2];
3927 /* If constant is positive, upper bits zeroed, otherwise unchanged.
3928 Give the assembler a chance to pick the move instruction. */
3929 if (GET_CODE (op2) == CONST_INT)
3931 int sign = INTVAL (op2);
3933 return \"mov %1,%0\;and %R1,%2,%R0\";
3934 return \"mov 0,%0\;and %R1,%2,%R0\";
3936 else if (GET_CODE (op2) == CONST_DOUBLE)
3939 xoperands[0] = operands[0];
3940 xoperands[1] = operands[1];
3941 xoperands[2] = GEN_INT (CONST_DOUBLE_LOW (op2));
3942 xoperands[3] = GEN_INT (CONST_DOUBLE_HIGH (op2));
3943 /* We could optimize then operands[1] == operands[0]
3944 and either half of the constant is -1. */
3945 output_asm_insn (\"and %R1,%2,%R0\;and %1,%3,%0\", xoperands);
3948 return \"and %1,%2,%0\;and %R1,%R2,%R0\";
3950 [(set_attr "length" "2")])
3952 (define_insn "*anddi3_sp64"
3953 [(set (match_operand:DI 0 "register_operand" "=r")
3954 (and:DI (match_operand:DI 1 "arith_double_operand" "%r")
3955 (match_operand:DI 2 "arith_double_operand" "rHI")))]
3959 (define_insn "andsi3"
3960 [(set (match_operand:SI 0 "register_operand" "=r")
3961 (and:SI (match_operand:SI 1 "arith_operand" "%r")
3962 (match_operand:SI 2 "arith_operand" "rI")))]
3965 [(set_attr "type" "ialu")])
3968 [(set (match_operand:SI 0 "register_operand" "")
3969 (and:SI (match_operand:SI 1 "register_operand" "")
3970 (match_operand:SI 2 "" "")))
3971 (clobber (match_operand:SI 3 "register_operand" ""))]
3972 "GET_CODE (operands[2]) == CONST_INT
3973 && !SMALL_INT (operands[2])
3974 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
3975 [(set (match_dup 3) (match_dup 4))
3976 (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 1)))]
3979 operands[4] = gen_rtx (CONST_INT, VOIDmode, ~INTVAL (operands[2]));
3982 (define_insn "*and_not_di_sp32"
3983 [(set (match_operand:DI 0 "register_operand" "=r")
3984 (and:DI (not:DI (match_operand:DI 1 "register_operand" "r"))
3985 (match_operand:DI 2 "register_operand" "r")))]
3987 "andn %2,%1,%0\;andn %R2,%R1,%R0"
3988 [(set_attr "length" "2")])
3990 (define_insn "*and_not_di_sp64"
3991 [(set (match_operand:DI 0 "register_operand" "=r")
3992 (and:DI (not:DI (match_operand:DI 1 "register_operand" "r"))
3993 (match_operand:DI 2 "register_operand" "r")))]
3997 (define_insn "*and_not_si"
3998 [(set (match_operand:SI 0 "register_operand" "=r")
3999 (and:SI (not:SI (match_operand:SI 1 "register_operand" "r"))
4000 (match_operand:SI 2 "register_operand" "r")))]
4003 [(set_attr "type" "ialu")])
4005 (define_expand "iordi3"
4006 [(set (match_operand:DI 0 "register_operand" "")
4007 (ior:DI (match_operand:DI 1 "arith_double_operand" "")
4008 (match_operand:DI 2 "arith_double_operand" "")))]
4012 (define_insn "*iordi3_sp32"
4013 [(set (match_operand:DI 0 "register_operand" "=r")
4014 (ior:DI (match_operand:DI 1 "arith_double_operand" "%r")
4015 (match_operand:DI 2 "arith_double_operand" "rHI")))]
4019 rtx op2 = operands[2];
4021 /* If constant is positive, upper bits zeroed, otherwise unchanged.
4022 Give the assembler a chance to pick the move instruction. */
4023 if (GET_CODE (op2) == CONST_INT)
4025 int sign = INTVAL (op2);
4027 return \"mov -1,%0\;or %R1,%2,%R0\";
4028 return \"mov %1,%0\;or %R1,%2,%R0\";
4030 else if (GET_CODE (op2) == CONST_DOUBLE)
4033 xoperands[0] = operands[0];
4034 xoperands[1] = operands[1];
4035 xoperands[2] = GEN_INT (CONST_DOUBLE_LOW (op2));
4036 xoperands[3] = GEN_INT (CONST_DOUBLE_HIGH (op2));
4037 /* We could optimize then operands[1] == operands[0]
4038 and either half of the constant is 0. */
4039 output_asm_insn (\"or %R1,%2,%R0\;or %1,%3,%0\", xoperands);
4042 return \"or %1,%2,%0\;or %R1,%R2,%R0\";
4044 [(set_attr "length" "2")])
4046 (define_insn "*iordi3_sp64"
4047 [(set (match_operand:DI 0 "register_operand" "=r")
4048 (ior:DI (match_operand:DI 1 "arith_double_operand" "%r")
4049 (match_operand:DI 2 "arith_double_operand" "rHI")))]
4053 (define_insn "iorsi3"
4054 [(set (match_operand:SI 0 "register_operand" "=r")
4055 (ior:SI (match_operand:SI 1 "arith_operand" "%r")
4056 (match_operand:SI 2 "arith_operand" "rI")))]
4059 [(set_attr "type" "ialu")])
4062 [(set (match_operand:SI 0 "register_operand" "")
4063 (ior:SI (match_operand:SI 1 "register_operand" "")
4064 (match_operand:SI 2 "" "")))
4065 (clobber (match_operand:SI 3 "register_operand" ""))]
4066 "GET_CODE (operands[2]) == CONST_INT
4067 && !SMALL_INT (operands[2])
4068 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
4069 [(set (match_dup 3) (match_dup 4))
4070 (set (match_dup 0) (ior:SI (not:SI (match_dup 3)) (match_dup 1)))]
4073 operands[4] = gen_rtx (CONST_INT, VOIDmode, ~INTVAL (operands[2]));
4076 (define_insn "*or_not_di_sp32"
4077 [(set (match_operand:DI 0 "register_operand" "=r")
4078 (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r"))
4079 (match_operand:DI 2 "register_operand" "r")))]
4081 "orn %2,%1,%0\;orn %R2,%R1,%R0"
4082 [(set_attr "length" "2")])
4084 (define_insn "*or_not_di_sp64"
4085 [(set (match_operand:DI 0 "register_operand" "=r")
4086 (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r"))
4087 (match_operand:DI 2 "register_operand" "r")))]
4091 (define_insn "*or_not_si"
4092 [(set (match_operand:SI 0 "register_operand" "=r")
4093 (ior:SI (not:SI (match_operand:SI 1 "register_operand" "r"))
4094 (match_operand:SI 2 "register_operand" "r")))]
4097 [(set_attr "type" "ialu")])
4099 (define_expand "xordi3"
4100 [(set (match_operand:DI 0 "register_operand" "")
4101 (xor:DI (match_operand:DI 1 "arith_double_operand" "")
4102 (match_operand:DI 2 "arith_double_operand" "")))]
4106 (define_insn "*xorsi3_sp32"
4107 [(set (match_operand:DI 0 "register_operand" "=r")
4108 (xor:DI (match_operand:DI 1 "arith_double_operand" "%r")
4109 (match_operand:DI 2 "arith_double_operand" "rHI")))]
4113 rtx op2 = operands[2];
4115 /* If constant is positive, upper bits zeroed, otherwise unchanged.
4116 Give the assembler a chance to pick the move instruction. */
4117 if (GET_CODE (op2) == CONST_INT)
4119 int sign = INTVAL (op2);
4121 return \"xor %1,-1,%0\;xor %R1,%2,%R0\";
4122 return \"mov %1,%0\;xor %R1,%2,%R0\";
4124 else if (GET_CODE (op2) == CONST_DOUBLE)
4127 xoperands[0] = operands[0];
4128 xoperands[1] = operands[1];
4129 xoperands[2] = GEN_INT (CONST_DOUBLE_LOW (op2));
4130 xoperands[3] = GEN_INT (CONST_DOUBLE_HIGH (op2));
4131 /* We could optimize then operands[1] == operands[0]
4132 and either half of the constant is 0. */
4133 output_asm_insn (\"xor %R1,%2,%R0\;xor %1,%3,%0\", xoperands);
4136 return \"xor %1,%2,%0\;xor %R1,%R2,%R0\";
4138 [(set_attr "length" "2")])
4140 (define_insn "*xordi3_sp64"
4141 [(set (match_operand:DI 0 "register_operand" "=r")
4142 (xor:DI (match_operand:DI 1 "arith_double_operand" "%rJ")
4143 (match_operand:DI 2 "arith_double_operand" "rHI")))]
4147 (define_insn "xorsi3"
4148 [(set (match_operand:SI 0 "register_operand" "=r")
4149 (xor:SI (match_operand:SI 1 "arith_operand" "%rJ")
4150 (match_operand:SI 2 "arith_operand" "rI")))]
4153 [(set_attr "type" "ialu")])
4156 [(set (match_operand:SI 0 "register_operand" "")
4157 (xor:SI (match_operand:SI 1 "register_operand" "")
4158 (match_operand:SI 2 "" "")))
4159 (clobber (match_operand:SI 3 "register_operand" ""))]
4160 "GET_CODE (operands[2]) == CONST_INT
4161 && !SMALL_INT (operands[2])
4162 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
4163 [(set (match_dup 3) (match_dup 4))
4164 (set (match_dup 0) (not:SI (xor:SI (match_dup 3) (match_dup 1))))]
4167 operands[4] = gen_rtx (CONST_INT, VOIDmode, ~INTVAL (operands[2]));
4171 [(set (match_operand:SI 0 "register_operand" "")
4172 (not:SI (xor:SI (match_operand:SI 1 "register_operand" "")
4173 (match_operand:SI 2 "" ""))))
4174 (clobber (match_operand:SI 3 "register_operand" ""))]
4175 "GET_CODE (operands[2]) == CONST_INT
4176 && !SMALL_INT (operands[2])
4177 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
4178 [(set (match_dup 3) (match_dup 4))
4179 (set (match_dup 0) (xor:SI (match_dup 3) (match_dup 1)))]
4182 operands[4] = gen_rtx (CONST_INT, VOIDmode, ~INTVAL (operands[2]));
4185 ;; xnor patterns. Note that (a ^ ~b) == (~a ^ b) == ~(a ^ b).
4186 ;; Combine now canonicalizes to the rightmost expression.
4187 (define_insn "*xor_not_di_sp32"
4188 [(set (match_operand:DI 0 "register_operand" "=r")
4189 (not:DI (xor:DI (match_operand:DI 1 "register_operand" "r")
4190 (match_operand:DI 2 "register_operand" "r"))))]
4192 "xnor %1,%2,%0\;xnor %R1,%R2,%R0"
4193 [(set_attr "length" "2")])
4195 (define_insn "*xor_not_di_sp64"
4196 [(set (match_operand:DI 0 "register_operand" "=r")
4197 (not:DI (xor:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
4198 (match_operand:DI 2 "arith_double_operand" "rHI"))))]
4202 (define_insn "*xor_not_si"
4203 [(set (match_operand:SI 0 "register_operand" "=r")
4204 (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
4205 (match_operand:SI 2 "arith_operand" "rI"))))]
4208 [(set_attr "type" "ialu")])
4210 ;; These correspond to the above in the case where we also (or only)
4211 ;; want to set the condition code.
4213 (define_insn "*cmp_cc_arith_op"
4216 (match_operator:SI 2 "cc_arithop"
4217 [(match_operand:SI 0 "arith_operand" "%r")
4218 (match_operand:SI 1 "arith_operand" "rI")])
4222 [(set_attr "type" "compare")])
4224 (define_insn "*cmp_ccx_arith_op"
4227 (match_operator:DI 2 "cc_arithop"
4228 [(match_operand:DI 0 "arith_double_operand" "%r")
4229 (match_operand:DI 1 "arith_double_operand" "rHI")])
4233 [(set_attr "type" "compare")])
4235 (define_insn "*cmp_cc_arith_op_set"
4238 (match_operator:SI 3 "cc_arithop"
4239 [(match_operand:SI 1 "arith_operand" "%r")
4240 (match_operand:SI 2 "arith_operand" "rI")])
4242 (set (match_operand:SI 0 "register_operand" "=r")
4247 (define_insn "*cmp_ccx_arith_op_set"
4250 (match_operator:DI 3 "cc_arithop"
4251 [(match_operand:DI 1 "arith_double_operand" "%r")
4252 (match_operand:DI 2 "arith_double_operand" "rHI")])
4254 (set (match_operand:DI 0 "register_operand" "=r")
4259 (define_insn "*cmp_cc_xor_not"
4262 (not:SI (xor:SI (match_operand:SI 0 "reg_or_0_operand" "%rJ")
4263 (match_operand:SI 1 "arith_operand" "rI")))
4266 "xnorcc %r0,%1,%%g0"
4267 [(set_attr "type" "compare")])
4269 (define_insn "*cmp_ccx_xor_not"
4272 (not:DI (xor:DI (match_operand:DI 0 "reg_or_0_operand" "%rJ")
4273 (match_operand:DI 1 "arith_double_operand" "rHI")))
4276 "xnorcc %r0,%1,%%g0"
4277 [(set_attr "type" "compare")])
4279 (define_insn "*cmp_cc_xor_not_set"
4282 (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
4283 (match_operand:SI 2 "arith_operand" "rI")))
4285 (set (match_operand:SI 0 "register_operand" "=r")
4286 (not:SI (xor:SI (match_dup 1) (match_dup 2))))]
4290 (define_insn "*cmp_ccx_xor_not_set"
4293 (not:DI (xor:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ")
4294 (match_operand:DI 2 "arith_double_operand" "rHI")))
4296 (set (match_operand:DI 0 "register_operand" "=r")
4297 (not:DI (xor:DI (match_dup 1) (match_dup 2))))]
4301 (define_insn "*cmp_cc_arith_op_not"
4304 (match_operator:SI 2 "cc_arithopn"
4305 [(not:SI (match_operand:SI 0 "arith_operand" "rI"))
4306 (match_operand:SI 1 "reg_or_0_operand" "rJ")])
4310 [(set_attr "type" "compare")])
4312 (define_insn "*cmp_ccx_arith_op_not"
4315 (match_operator:DI 2 "cc_arithopn"
4316 [(not:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
4317 (match_operand:DI 1 "reg_or_0_operand" "rJ")])
4321 [(set_attr "type" "compare")])
4323 (define_insn "*cmp_cc_arith_op_not_set"
4326 (match_operator:SI 3 "cc_arithopn"
4327 [(not:SI (match_operand:SI 1 "arith_operand" "rI"))
4328 (match_operand:SI 2 "reg_or_0_operand" "rJ")])
4330 (set (match_operand:SI 0 "register_operand" "=r")
4335 (define_insn "*cmp_ccx_arith_op_not_set"
4338 (match_operator:DI 3 "cc_arithopn"
4339 [(not:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
4340 (match_operand:DI 2 "reg_or_0_operand" "rJ")])
4342 (set (match_operand:DI 0 "register_operand" "=r")
4347 ;; We cannot use the "neg" pseudo insn because the Sun assembler
4348 ;; does not know how to make it work for constants.
4350 (define_expand "negdi2"
4351 [(set (match_operand:DI 0 "register_operand" "=r")
4352 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
4356 if (! TARGET_ARCH64)
4358 emit_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (2,
4359 gen_rtx (SET, VOIDmode, operand0,
4360 gen_rtx (NEG, DImode, operand1)),
4361 gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, 0)))));
4366 (define_insn "*negdi2_sp32"
4367 [(set (match_operand:DI 0 "register_operand" "=r")
4368 (neg:DI (match_operand:DI 1 "register_operand" "r")))
4369 (clobber (reg:SI 0))]
4371 "subcc %%g0,%R1,%R0\;subx %%g0,%1,%0"
4372 [(set_attr "type" "unary")
4373 (set_attr "length" "2")])
4375 (define_insn "*negdi2_sp64"
4376 [(set (match_operand:DI 0 "register_operand" "=r")
4377 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
4380 [(set_attr "type" "unary")
4381 (set_attr "length" "1")])
4383 (define_insn "negsi2"
4384 [(set (match_operand:SI 0 "register_operand" "=r")
4385 (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
4388 [(set_attr "type" "unary")])
4390 (define_insn "*cmp_cc_neg"
4391 [(set (reg:CC_NOOV 0)
4392 (compare:CC_NOOV (neg:SI (match_operand:SI 0 "arith_operand" "rI"))
4395 "subcc %%g0,%0,%%g0"
4396 [(set_attr "type" "compare")])
4398 (define_insn "*cmp_ccx_neg"
4399 [(set (reg:CCX_NOOV 0)
4400 (compare:CCX_NOOV (neg:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
4403 "subcc %%g0,%0,%%g0"
4404 [(set_attr "type" "compare")])
4406 (define_insn "*cmp_cc_set_neg"
4407 [(set (reg:CC_NOOV 0)
4408 (compare:CC_NOOV (neg:SI (match_operand:SI 1 "arith_operand" "rI"))
4410 (set (match_operand:SI 0 "register_operand" "=r")
4411 (neg:SI (match_dup 1)))]
4414 [(set_attr "type" "unary")])
4416 (define_insn "*cmp_ccx_set_neg"
4417 [(set (reg:CCX_NOOV 0)
4418 (compare:CCX_NOOV (neg:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
4420 (set (match_operand:DI 0 "register_operand" "=r")
4421 (neg:DI (match_dup 1)))]
4424 [(set_attr "type" "unary")])
4426 ;; We cannot use the "not" pseudo insn because the Sun assembler
4427 ;; does not know how to make it work for constants.
4428 (define_expand "one_cmpldi2"
4429 [(set (match_operand:DI 0 "register_operand" "")
4430 (not:DI (match_operand:DI 1 "register_operand" "")))]
4434 (define_insn "*one_cmpldi2_sp32"
4435 [(set (match_operand:DI 0 "register_operand" "=r")
4436 (not:DI (match_operand:DI 1 "register_operand" "r")))]
4438 "xnor %%g0,%1,%0\;xnor %%g0,%R1,%R0"
4439 [(set_attr "type" "unary")
4440 (set_attr "length" "2")])
4442 (define_insn "*one_cmpldi2_sp64"
4443 [(set (match_operand:DI 0 "register_operand" "=r")
4444 (not:DI (match_operand:DI 1 "arith_double_operand" "rHI")))]
4447 [(set_attr "type" "unary")])
4449 (define_insn "one_cmplsi2"
4450 [(set (match_operand:SI 0 "register_operand" "=r")
4451 (not:SI (match_operand:SI 1 "arith_operand" "rI")))]
4454 [(set_attr "type" "unary")])
4456 (define_insn "*cmp_cc_not"
4458 (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI"))
4461 "xnorcc %%g0,%0,%%g0"
4462 [(set_attr "type" "compare")])
4464 (define_insn "*cmp_ccx_not"
4466 (compare:CCX (not:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
4469 "xnorcc %%g0,%0,%%g0"
4470 [(set_attr "type" "compare")])
4472 (define_insn "*cmp_cc_set_not"
4474 (compare:CC (not:SI (match_operand:SI 1 "arith_operand" "rI"))
4476 (set (match_operand:SI 0 "register_operand" "=r")
4477 (not:SI (match_dup 1)))]
4480 [(set_attr "type" "unary")])
4482 (define_insn "*cmp_ccx_set_not"
4484 (compare:CCX (not:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
4486 (set (match_operand:DI 0 "register_operand" "=r")
4487 (not:DI (match_dup 1)))]
4490 [(set_attr "type" "unary")])
4492 ;; Floating point arithmetic instructions.
4494 (define_insn "addtf3"
4495 [(set (match_operand:TF 0 "register_operand" "=e")
4496 (plus:TF (match_operand:TF 1 "register_operand" "e")
4497 (match_operand:TF 2 "register_operand" "e")))]
4498 "TARGET_FPU && TARGET_HARD_QUAD"
4500 [(set_attr "type" "fp")])
4502 (define_insn "adddf3"
4503 [(set (match_operand:DF 0 "register_operand" "=e")
4504 (plus:DF (match_operand:DF 1 "register_operand" "e")
4505 (match_operand:DF 2 "register_operand" "e")))]
4508 [(set_attr "type" "fp")])
4510 (define_insn "addsf3"
4511 [(set (match_operand:SF 0 "register_operand" "=f")
4512 (plus:SF (match_operand:SF 1 "register_operand" "f")
4513 (match_operand:SF 2 "register_operand" "f")))]
4516 [(set_attr "type" "fp")])
4518 (define_insn "subtf3"
4519 [(set (match_operand:TF 0 "register_operand" "=e")
4520 (minus:TF (match_operand:TF 1 "register_operand" "e")
4521 (match_operand:TF 2 "register_operand" "e")))]
4522 "TARGET_FPU && TARGET_HARD_QUAD"
4524 [(set_attr "type" "fp")])
4526 (define_insn "subdf3"
4527 [(set (match_operand:DF 0 "register_operand" "=e")
4528 (minus:DF (match_operand:DF 1 "register_operand" "e")
4529 (match_operand:DF 2 "register_operand" "e")))]
4532 [(set_attr "type" "fp")])
4534 (define_insn "subsf3"
4535 [(set (match_operand:SF 0 "register_operand" "=f")
4536 (minus:SF (match_operand:SF 1 "register_operand" "f")
4537 (match_operand:SF 2 "register_operand" "f")))]
4540 [(set_attr "type" "fp")])
4542 (define_insn "multf3"
4543 [(set (match_operand:TF 0 "register_operand" "=e")
4544 (mult:TF (match_operand:TF 1 "register_operand" "e")
4545 (match_operand:TF 2 "register_operand" "e")))]
4546 "TARGET_FPU && TARGET_HARD_QUAD"
4548 [(set_attr "type" "fpmul")])
4550 (define_insn "muldf3"
4551 [(set (match_operand:DF 0 "register_operand" "=e")
4552 (mult:DF (match_operand:DF 1 "register_operand" "e")
4553 (match_operand:DF 2 "register_operand" "e")))]
4556 [(set_attr "type" "fpmul")])
4558 (define_insn "mulsf3"
4559 [(set (match_operand:SF 0 "register_operand" "=f")
4560 (mult:SF (match_operand:SF 1 "register_operand" "f")
4561 (match_operand:SF 2 "register_operand" "f")))]
4564 [(set_attr "type" "fpmul")])
4566 (define_insn "*muldf3_extend"
4567 [(set (match_operand:DF 0 "register_operand" "=e")
4568 (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "f"))
4569 (float_extend:DF (match_operand:SF 2 "register_operand" "f"))))]
4570 "(TARGET_V8 || TARGET_V9) && TARGET_FPU"
4572 [(set_attr "type" "fpmul")])
4574 (define_insn "*multf3_extend"
4575 [(set (match_operand:TF 0 "register_operand" "=e")
4576 (mult:TF (float_extend:TF (match_operand:DF 1 "register_operand" "e"))
4577 (float_extend:TF (match_operand:DF 2 "register_operand" "e"))))]
4578 "(TARGET_V8 || TARGET_V9) && TARGET_FPU && TARGET_HARD_QUAD"
4580 [(set_attr "type" "fpmul")])
4582 ;; don't have timing for quad-prec. divide.
4583 (define_insn "divtf3"
4584 [(set (match_operand:TF 0 "register_operand" "=e")
4585 (div:TF (match_operand:TF 1 "register_operand" "e")
4586 (match_operand:TF 2 "register_operand" "e")))]
4587 "TARGET_FPU && TARGET_HARD_QUAD"
4589 [(set_attr "type" "fpdivd")])
4591 (define_insn "divdf3"
4592 [(set (match_operand:DF 0 "register_operand" "=e")
4593 (div:DF (match_operand:DF 1 "register_operand" "e")
4594 (match_operand:DF 2 "register_operand" "e")))]
4597 [(set_attr "type" "fpdivd")])
4599 (define_insn "divsf3"
4600 [(set (match_operand:SF 0 "register_operand" "=f")
4601 (div:SF (match_operand:SF 1 "register_operand" "f")
4602 (match_operand:SF 2 "register_operand" "f")))]
4605 [(set_attr "type" "fpdivs")])
4607 (define_insn "negtf2"
4608 [(set (match_operand:TF 0 "register_operand" "=e,e")
4609 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
4614 return \"fnegd %1,%0\"; /* Can't use fnegs, won't work with upper regs. */
4615 else if (which_alternative == 0)
4616 return \"fnegs %0,%0\";
4618 return \"fnegs %1,%0\;fmovs %R1,%R0\;fmovs %S1,%S0\;fmovs %T1,%T0\";
4620 [(set_attr "type" "fp")
4621 (set_attr_alternative "length"
4623 (if_then_else (eq_attr "isa" "v9") (const_int 1) (const_int 4))])])
4625 (define_insn "negdf2"
4626 [(set (match_operand:DF 0 "register_operand" "=e,e")
4627 (neg:DF (match_operand:DF 1 "register_operand" "0,e")))]
4632 return \"fnegd %1,%0\";
4633 else if (which_alternative == 0)
4634 return \"fnegs %0,%0\";
4636 return \"fnegs %1,%0\;fmovs %R1,%R0\";
4638 [(set_attr "type" "fp")
4639 (set_attr_alternative "length"
4641 (if_then_else (eq_attr "isa" "v9") (const_int 1) (const_int 2))])])
4643 (define_insn "negsf2"
4644 [(set (match_operand:SF 0 "register_operand" "=f")
4645 (neg:SF (match_operand:SF 1 "register_operand" "f")))]
4648 [(set_attr "type" "fp")])
4650 (define_insn "abstf2"
4651 [(set (match_operand:TF 0 "register_operand" "=e,e")
4652 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
4657 return \"fabsd %1,%0\"; /* Can't use fabss, won't work with upper regs. */
4658 else if (which_alternative == 0)
4659 return \"fabss %0,%0\";
4661 return \"fabss %1,%0\;fmovs %R1,%R0\;fmovs %S1,%S0\;fmovs %T1,%T0\";
4663 [(set_attr "type" "fp")
4664 (set_attr_alternative "length"
4666 (if_then_else (eq_attr "isa" "v9") (const_int 1) (const_int 4))])])
4668 (define_insn "absdf2"
4669 [(set (match_operand:DF 0 "register_operand" "=e,e")
4670 (abs:DF (match_operand:DF 1 "register_operand" "0,e")))]
4675 return \"fabsd %1,%0\";
4676 else if (which_alternative == 0)
4677 return \"fabss %0,%0\";
4679 return \"fabss %1,%0\;fmovs %R1,%R0\";
4681 [(set_attr "type" "fp")
4682 (set_attr_alternative "length"
4684 (if_then_else (eq_attr "isa" "v9") (const_int 1) (const_int 2))])])
4686 (define_insn "abssf2"
4687 [(set (match_operand:SF 0 "register_operand" "=f")
4688 (abs:SF (match_operand:SF 1 "register_operand" "f")))]
4691 [(set_attr "type" "fp")])
4693 (define_insn "sqrttf2"
4694 [(set (match_operand:TF 0 "register_operand" "=e")
4695 (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
4696 "TARGET_FPU && TARGET_HARD_QUAD"
4698 [(set_attr "type" "fpsqrt")])
4700 (define_insn "sqrtdf2"
4701 [(set (match_operand:DF 0 "register_operand" "=e")
4702 (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
4705 [(set_attr "type" "fpsqrt")])
4707 (define_insn "sqrtsf2"
4708 [(set (match_operand:SF 0 "register_operand" "=f")
4709 (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
4712 [(set_attr "type" "fpsqrt")])
4714 ;;- arithmetic shift instructions
4716 (define_insn "ashlsi3"
4717 [(set (match_operand:SI 0 "register_operand" "=r")
4718 (ashift:SI (match_operand:SI 1 "register_operand" "r")
4719 (match_operand:SI 2 "arith_operand" "rI")))]
4723 if (GET_CODE (operands[2]) == CONST_INT
4724 && (unsigned) INTVAL (operands[2]) > 31)
4725 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
4727 return \"sll %1,%2,%0\";
4729 [(set_attr "type" "shift")])
4731 (define_insn "ashldi3"
4732 [(set (match_operand:DI 0 "register_operand" "=r")
4733 (ashift:DI (match_operand:DI 1 "register_operand" "r")
4734 (match_operand:SI 2 "arith_operand" "rI")))]
4738 if (GET_CODE (operands[2]) == CONST_INT
4739 && (unsigned) INTVAL (operands[2]) > 63)
4740 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
4742 return \"sllx %1,%2,%0\";
4745 (define_insn "*cmp_cc_ashift_1"
4746 [(set (reg:CC_NOOV 0)
4747 (compare:CC_NOOV (ashift:SI (match_operand:SI 0 "register_operand" "r")
4752 [(set_attr "type" "compare")])
4754 (define_insn "*cmp_cc_set_ashift_1"
4755 [(set (reg:CC_NOOV 0)
4756 (compare:CC_NOOV (ashift:SI (match_operand:SI 1 "register_operand" "r")
4759 (set (match_operand:SI 0 "register_operand" "=r")
4760 (ashift:SI (match_dup 1) (const_int 1)))]
4764 (define_insn "ashrsi3"
4765 [(set (match_operand:SI 0 "register_operand" "=r")
4766 (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
4767 (match_operand:SI 2 "arith_operand" "rI")))]
4771 if (GET_CODE (operands[2]) == CONST_INT
4772 && (unsigned) INTVAL (operands[2]) > 31)
4773 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
4775 return \"sra %1,%2,%0\";
4777 [(set_attr "type" "shift")])
4779 (define_insn "ashrdi3"
4780 [(set (match_operand:DI 0 "register_operand" "=r")
4781 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
4782 (match_operand:SI 2 "arith_operand" "rI")))]
4786 if (GET_CODE (operands[2]) == CONST_INT
4787 && (unsigned) INTVAL (operands[2]) > 63)
4788 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
4790 return \"srax %1,%2,%0\";
4793 (define_insn "lshrsi3"
4794 [(set (match_operand:SI 0 "register_operand" "=r")
4795 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
4796 (match_operand:SI 2 "arith_operand" "rI")))]
4800 if (GET_CODE (operands[2]) == CONST_INT
4801 && (unsigned) INTVAL (operands[2]) > 31)
4802 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
4804 return \"srl %1,%2,%0\";
4806 [(set_attr "type" "shift")])
4808 (define_insn "lshrdi3"
4809 [(set (match_operand:DI 0 "register_operand" "=r")
4810 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
4811 (match_operand:SI 2 "arith_operand" "rI")))]
4815 if (GET_CODE (operands[2]) == CONST_INT
4816 && (unsigned) INTVAL (operands[2]) > 63)
4817 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
4819 return \"srlx %1,%2,%0\";
4822 ;; Unconditional and other jump instructions
4823 ;; On the Sparc, by setting the annul bit on an unconditional branch, the
4824 ;; following insn is never executed. This saves us a nop. Dbx does not
4825 ;; handle such branches though, so we only use them when optimizing.
4827 [(set (pc) (label_ref (match_operand 0 "" "")))]
4830 [(set_attr "type" "uncond_branch")])
4832 (define_expand "tablejump"
4833 [(parallel [(set (pc) (match_operand 0 "register_operand" "r"))
4834 (use (label_ref (match_operand 1 "" "")))])]
4838 if (GET_MODE (operands[0]) != Pmode)
4841 /* We need to use the PC value in %o7 that was set up when the address
4842 of the label was loaded into a register, so we need different RTL. */
4846 emit_jump_insn (gen_pic_tablejump_32 (operands[0], operands[1]));
4848 emit_jump_insn (gen_pic_tablejump_64 (operands[0], operands[1]));
4853 (define_insn "pic_tablejump_32"
4854 [(set (pc) (match_operand:SI 0 "register_operand" "r"))
4855 (use (label_ref (match_operand 1 "" "")))
4859 [(set_attr "type" "uncond_branch")])
4861 (define_insn "pic_tablejump_64"
4862 [(set (pc) (match_operand:DI 0 "register_operand" "r"))
4863 (use (label_ref (match_operand 1 "" "")))
4867 [(set_attr "type" "uncond_branch")])
4869 (define_insn "*tablejump_sp32"
4870 [(set (pc) (match_operand:SI 0 "address_operand" "p"))
4871 (use (label_ref (match_operand 1 "" "")))]
4874 [(set_attr "type" "uncond_branch")])
4876 (define_insn "*tablejump_sp64"
4877 [(set (pc) (match_operand:DI 0 "address_operand" "p"))
4878 (use (label_ref (match_operand 1 "" "")))]
4881 [(set_attr "type" "uncond_branch")])
4883 ;; This pattern recognizes the "instruction" that appears in
4884 ;; a function call that wants a structure value,
4885 ;; to inform the called function if compiled with Sun CC.
4886 ;(define_insn "*unimp_insn"
4887 ; [(match_operand:SI 0 "immediate_operand" "")]
4888 ; "GET_CODE (operands[0]) == CONST_INT && INTVAL (operands[0]) > 0"
4890 ; [(set_attr "type" "marker")])
4892 ;;- jump to subroutine
4893 (define_expand "call"
4894 ;; Note that this expression is not used for generating RTL.
4895 ;; All the RTL is generated explicitly below.
4896 [(call (match_operand 0 "call_operand" "")
4897 (match_operand 3 "" "i"))]
4898 ;; operands[2] is next_arg_register
4899 ;; operands[3] is struct_value_size_rtx.
4903 rtx fn_rtx, nregs_rtx;
4905 if (GET_MODE (operands[0]) != FUNCTION_MODE)
4908 if (GET_CODE (XEXP (operands[0], 0)) == LABEL_REF)
4910 /* This is really a PIC sequence. We want to represent
4911 it as a funny jump so it's delay slots can be filled.
4913 ??? But if this really *is* a CALL, will not it clobber the
4914 call-clobbered registers? We lose this if it is a JUMP_INSN.
4915 Why cannot we have delay slots filled if it were a CALL? */
4917 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
4918 emit_jump_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (3,
4919 gen_rtx (SET, VOIDmode, pc_rtx,
4920 XEXP (operands[0], 0)),
4922 gen_rtx (CLOBBER, VOIDmode,
4923 gen_rtx (REG, Pmode, 15)))));
4925 emit_jump_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (2,
4926 gen_rtx (SET, VOIDmode, pc_rtx,
4927 XEXP (operands[0], 0)),
4928 gen_rtx (CLOBBER, VOIDmode,
4929 gen_rtx (REG, Pmode, 15)))));
4933 fn_rtx = operands[0];
4935 /* Count the number of parameter registers being used by this call.
4936 if that argument is NULL, it means we are using them all, which
4937 means 6 on the sparc. */
4940 nregs_rtx = gen_rtx (CONST_INT, VOIDmode, REGNO (operands[2]) - 8);
4942 nregs_rtx = gen_rtx (CONST_INT, VOIDmode, 6);
4944 nregs_rtx = const0_rtx;
4947 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
4948 emit_call_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (3,
4949 gen_rtx (CALL, VOIDmode, fn_rtx, nregs_rtx),
4951 gen_rtx (CLOBBER, VOIDmode,
4952 gen_rtx (REG, Pmode, 15)))));
4954 emit_call_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (2,
4955 gen_rtx (CALL, VOIDmode, fn_rtx, nregs_rtx),
4956 gen_rtx (CLOBBER, VOIDmode,
4957 gen_rtx (REG, Pmode, 15)))));
4961 /* If this call wants a structure value,
4962 emit an unimp insn to let the called function know about this. */
4963 if (! TARGET_ARCH64 && INTVAL (operands[3]) > 0)
4965 rtx insn = emit_insn (operands[3]);
4966 SCHED_GROUP_P (insn) = 1;
4973 ;; We can't use the same pattern for these two insns, because then registers
4974 ;; in the address may not be properly reloaded.
4976 (define_insn "*call_address_sp32"
4977 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
4978 (match_operand 1 "" ""))
4979 (clobber (reg:SI 15))]
4980 ;;- Do not use operand 1 for most machines.
4983 [(set_attr "type" "call")])
4985 (define_insn "*call_symbolic_sp32"
4986 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
4987 (match_operand 1 "" ""))
4988 (clobber (reg:SI 15))]
4989 ;;- Do not use operand 1 for most machines.
4992 [(set_attr "type" "call")])
4994 (define_insn "*call_address_sp64"
4995 [(call (mem:SI (match_operand:DI 0 "address_operand" "p"))
4996 (match_operand 1 "" ""))
4997 (clobber (reg:DI 15))]
4998 ;;- Do not use operand 1 for most machines.
5001 [(set_attr "type" "call")])
5003 (define_insn "*call_symbolic_sp64"
5004 [(call (mem:SI (match_operand:DI 0 "symbolic_operand" "s"))
5005 (match_operand 1 "" ""))
5006 (clobber (reg:DI 15))]
5007 ;;- Do not use operand 1 for most machines.
5010 [(set_attr "type" "call")])
5012 ;; This is a call that wants a structure value.
5013 ;; There is no such critter for v9 (??? we may need one anyway).
5014 (define_insn "*call_address_struct_value_sp32"
5015 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
5016 (match_operand 1 "" ""))
5017 (match_operand 2 "immediate_operand" "")
5018 (clobber (reg:SI 15))]
5019 ;;- Do not use operand 1 for most machines.
5020 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
5021 "call %a0,%1\;nop\;unimp %2"
5022 [(set_attr "type" "call_no_delay_slot")])
5024 ;; This is a call that wants a structure value.
5025 ;; There is no such critter for v9 (??? we may need one anyway).
5026 (define_insn "*call_symbolic_struct_value_sp32"
5027 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
5028 (match_operand 1 "" ""))
5029 (match_operand 2 "immediate_operand" "")
5030 (clobber (reg:SI 15))]
5031 ;;- Do not use operand 1 for most machines.
5032 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
5033 "call %a0,%1\;nop\;unimp %2"
5034 [(set_attr "type" "call_no_delay_slot")])
5036 ;; This is a call that may want a structure value. This is used for
5038 (define_insn "*call_address_untyped_struct_value_sp32"
5039 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
5040 (match_operand 1 "" ""))
5041 (match_operand 2 "immediate_operand" "")
5042 (clobber (reg:SI 15))]
5043 ;;- Do not use operand 1 for most machines.
5044 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
5045 "call %a0,%1\;nop\;nop"
5046 [(set_attr "type" "call_no_delay_slot")])
5048 ;; This is a call that wants a structure value.
5049 (define_insn "*call_symbolic_untyped_struct_value_sp32"
5050 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
5051 (match_operand 1 "" ""))
5052 (match_operand 2 "immediate_operand" "")
5053 (clobber (reg:SI 15))]
5054 ;;- Do not use operand 1 for most machines.
5055 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
5056 "call %a0,%1\;nop\;nop"
5057 [(set_attr "type" "call_no_delay_slot")])
5059 (define_expand "call_value"
5060 ;; Note that this expression is not used for generating RTL.
5061 ;; All the RTL is generated explicitly below.
5062 [(set (match_operand 0 "register_operand" "=rf")
5063 (call (match_operand:SI 1 "" "")
5064 (match_operand 4 "" "")))]
5065 ;; operand 2 is stack_size_rtx
5066 ;; operand 3 is next_arg_register
5070 rtx fn_rtx, nregs_rtx;
5073 if (GET_MODE (operands[1]) != FUNCTION_MODE)
5076 fn_rtx = operands[1];
5080 nregs_rtx = gen_rtx (CONST_INT, VOIDmode, REGNO (operands[3]) - 8);
5082 nregs_rtx = gen_rtx (CONST_INT, VOIDmode, 6);
5084 nregs_rtx = const0_rtx;
5088 gen_rtx (SET, VOIDmode, operands[0],
5089 gen_rtx (CALL, VOIDmode, fn_rtx, nregs_rtx)),
5090 gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, Pmode, 15)));
5092 emit_call_insn (gen_rtx (PARALLEL, VOIDmode, vec));
5097 (define_insn "*call_value_address_sp32"
5098 [(set (match_operand 0 "" "=rf")
5099 (call (mem:SI (match_operand:SI 1 "address_operand" "p"))
5100 (match_operand 2 "" "")))
5101 (clobber (reg:SI 15))]
5102 ;;- Do not use operand 2 for most machines.
5105 [(set_attr "type" "call")])
5107 (define_insn "*call_value_symbolic_sp32"
5108 [(set (match_operand 0 "" "=rf")
5109 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
5110 (match_operand 2 "" "")))
5111 (clobber (reg:SI 15))]
5112 ;;- Do not use operand 2 for most machines.
5115 [(set_attr "type" "call")])
5117 (define_insn "*call_value_address_sp64"
5118 [(set (match_operand 0 "" "=rf")
5119 (call (mem:SI (match_operand:DI 1 "address_operand" "p"))
5120 (match_operand 2 "" "")))
5121 (clobber (reg:DI 15))]
5122 ;;- Do not use operand 2 for most machines.
5125 [(set_attr "type" "call")])
5127 (define_insn "*call_value_symbolic_sp64"
5128 [(set (match_operand 0 "" "=rf")
5129 (call (mem:SI (match_operand:DI 1 "symbolic_operand" "s"))
5130 (match_operand 2 "" "")))
5131 (clobber (reg:DI 15))]
5132 ;;- Do not use operand 2 for most machines.
5135 [(set_attr "type" "call")])
5137 (define_expand "untyped_call"
5138 [(parallel [(call (match_operand 0 "" "")
5140 (match_operand 1 "" "")
5141 (match_operand 2 "" "")])]
5147 /* Pass constm1 to indicate that it may expect a structure value, but
5148 we don't know what size it is. */
5149 emit_call_insn (gen_call (operands[0], const0_rtx, NULL, constm1_rtx));
5151 for (i = 0; i < XVECLEN (operands[2], 0); i++)
5153 rtx set = XVECEXP (operands[2], 0, i);
5154 emit_move_insn (SET_DEST (set), SET_SRC (set));
5157 /* The optimizer does not know that the call sets the function value
5158 registers we stored in the result block. We avoid problems by
5159 claiming that all hard registers are used and clobbered at this
5161 emit_insn (gen_blockage ());
5166 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
5167 ;; all of memory. This blocks insns from being moved across this point.
5169 (define_insn "blockage"
5170 [(unspec_volatile [(const_int 0)] 0)]
5174 ;; Prepare to return any type including a structure value.
5176 (define_expand "untyped_return"
5177 [(match_operand:BLK 0 "memory_operand" "")
5178 (match_operand 1 "" "")]
5182 rtx valreg1 = gen_rtx (REG, DImode, 24);
5183 rtx valreg2 = gen_rtx (REG, TARGET_ARCH64 ? TFmode : DFmode, 32);
5184 rtx result = operands[0];
5186 if (! TARGET_ARCH64)
5188 rtx rtnreg = gen_rtx (REG, SImode, (leaf_function ? 15 : 31));
5189 rtx value = gen_reg_rtx (SImode);
5191 /* Fetch the instruction where we will return to and see if it's an unimp
5192 instruction (the most significant 10 bits will be zero). If so,
5193 update the return address to skip the unimp instruction. */
5194 emit_move_insn (value,
5195 gen_rtx (MEM, SImode, plus_constant (rtnreg, 8)));
5196 emit_insn (gen_lshrsi3 (value, value, GEN_INT (22)));
5197 emit_insn (gen_update_return (rtnreg, value));
5200 /* Reload the function value registers. */
5201 emit_move_insn (valreg1, change_address (result, DImode, XEXP (result, 0)));
5202 emit_move_insn (valreg2,
5203 change_address (result, TARGET_ARCH64 ? TFmode : DFmode,
5204 plus_constant (XEXP (result, 0), 8)));
5206 /* Put USE insns before the return. */
5207 emit_insn (gen_rtx (USE, VOIDmode, valreg1));
5208 emit_insn (gen_rtx (USE, VOIDmode, valreg2));
5210 /* Construct the return. */
5211 expand_null_return ();
5216 ;; This is a bit of a hack. We're incrementing a fixed register (%i7),
5217 ;; and parts of the compiler don't want to believe that the add is needed.
5219 (define_insn "update_return"
5220 [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
5221 (match_operand:SI 1 "register_operand" "r")] 0)]
5223 "cmp %1,0\;be,a .+8\;add %0,4,%0"
5224 [(set_attr "type" "multi")])
5226 (define_insn "return"
5229 "* return output_return (operands);"
5230 [(set_attr "type" "multi")])
5237 (define_expand "indirect_jump"
5238 [(set (pc) (match_operand 0 "address_operand" "p"))]
5242 (define_insn "*branch_sp32"
5243 [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
5246 [(set_attr "type" "uncond_branch")])
5248 (define_insn "*branch_sp64"
5249 [(set (pc) (match_operand:DI 0 "address_operand" "p"))]
5252 [(set_attr "type" "uncond_branch")])
5254 ;; ??? Doesn't work with -mflat.
5255 (define_expand "nonlocal_goto"
5256 [(match_operand:SI 0 "general_operand" "")
5257 (match_operand:SI 1 "general_operand" "")
5258 (match_operand:SI 2 "general_operand" "")
5259 (match_operand:SI 3 "" "")]
5263 /* Trap instruction to flush all the register windows. */
5264 emit_insn (gen_flush_register_windows ());
5265 /* Load the fp value for the containing fn into %fp.
5266 This is needed because operands[2] refers to %fp.
5267 Virtual register instantiation fails if the virtual %fp isn't set from a
5268 register. Thus we must copy operands[0] into a register if it isn't
5270 if (GET_CODE (operands[0]) != REG)
5271 operands[0] = force_reg (Pmode, operands[0]);
5272 emit_move_insn (virtual_stack_vars_rtx, operands[0]);
5273 /* Find the containing function's current nonlocal goto handler,
5274 which will do any cleanups and then jump to the label. */
5275 emit_move_insn (gen_rtx (REG, Pmode, 8), operands[1]);
5276 /* Restore %fp from stack pointer value for containing function.
5277 The restore insn that follows will move this to %sp,
5278 and reload the appropriate value into %fp. */
5279 emit_move_insn (frame_pointer_rtx, operands[2]);
5280 /* Put in the static chain register the nonlocal label address. */
5281 emit_move_insn (static_chain_rtx, operands[3]);
5282 /* USE of frame_pointer_rtx added for consistency; not clear if
5284 emit_insn (gen_rtx (USE, VOIDmode, frame_pointer_rtx));
5285 emit_insn (gen_rtx (USE, VOIDmode, stack_pointer_rtx));
5286 emit_insn (gen_rtx (USE, VOIDmode, static_chain_rtx));
5287 /* Return, restoring reg window and jumping to goto handler. */
5288 emit_insn (gen_goto_handler_and_restore ());
5292 ;; Special trap insn to flush register windows.
5293 (define_insn "flush_register_windows"
5294 [(unspec_volatile [(const_int 0)] 1)]
5296 ;; ??? Use TARGET_V9 instead?
5297 "* return TARGET_ARCH64 ? \"flushw\" : \"ta 3\";"
5298 [(set_attr "type" "misc")])
5300 (define_insn "goto_handler_and_restore"
5301 [(unspec_volatile [(const_int 0)] 2)
5304 "jmp %%o0+0\;restore"
5305 [(set_attr "type" "misc")
5306 (set_attr "length" "2")])
5308 ;; Special pattern for the FLUSH instruction.
5310 (define_insn "flush"
5311 [(unspec_volatile [(match_operand 0 "memory_operand" "m")] 3)]
5313 "* return TARGET_V9 ? \"flush %f0\" : \"iflush %f0\";"
5314 [(set_attr "type" "misc")])
5318 ;; The scan instruction searches from the most significant bit while ffs
5319 ;; searches from the least significant bit. The bit index and treatment of
5320 ;; zero also differ. It takes at least 7 instructions to get the proper
5321 ;; result. Here is an obvious 8 instruction sequence.
5323 (define_insn "ffssi2"
5324 [(set (match_operand:SI 0 "register_operand" "=&r")
5325 (ffs:SI (match_operand:SI 1 "register_operand" "r")))
5326 (clobber (match_scratch:SI 2 "=&r"))]
5328 "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"
5329 [(set_attr "type" "multi")
5330 (set_attr "length" "8")])
5332 ;; ??? This should be a define expand, so that the extra instruction have
5333 ;; a chance of being optimized away.
5335 (define_insn "ffsdi2"
5336 [(set (match_operand:DI 0 "register_operand" "=&r")
5337 (ffs:DI (match_operand:DI 1 "register_operand" "r")))
5338 (clobber (match_scratch:DI 2 "=&r"))]
5340 "neg %1,%2\;not %2,%2\;xor %1,%2,%2\;popc %2,%0\;movrz %1,%%g0,%0"
5341 [(set_attr "type" "multi")
5342 (set_attr "length" "5")])
5344 ;; Split up troublesome insns for better scheduling. */
5346 ;; The following patterns are straightforward. They can be applied
5347 ;; either before or after register allocation.
5350 [(set (match_operand 0 "splittable_symbolic_memory_operand" "")
5351 (match_operand 1 "reg_or_0_operand" ""))
5352 (clobber (match_operand:SI 2 "register_operand" ""))]
5354 [(set (match_dup 2) (high:SI (match_dup 3)))
5355 (set (match_dup 4) (match_dup 1))]
5358 operands[3] = XEXP (operands[0], 0);
5359 operands[4] = gen_rtx (MEM, GET_MODE (operands[0]),
5360 gen_rtx (LO_SUM, SImode, operands[2], operands[3]));
5361 MEM_IN_STRUCT_P (operands[4]) = MEM_IN_STRUCT_P (operands[0]);
5362 MEM_VOLATILE_P (operands[4]) = MEM_VOLATILE_P (operands[0]);
5363 RTX_UNCHANGING_P (operands[4]) = RTX_UNCHANGING_P (operands[0]);
5367 [(set (match_operand 0 "splittable_immediate_memory_operand" "")
5368 (match_operand 1 "general_operand" ""))
5369 (clobber (match_operand:SI 2 "register_operand" ""))]
5371 [(set (match_dup 3) (match_dup 1))]
5374 rtx addr = legitimize_pic_address (XEXP (operands[0], 0),
5375 GET_MODE (operands[0]),
5377 operands[3] = gen_rtx (MEM, GET_MODE (operands[0]), addr);
5378 MEM_IN_STRUCT_P (operands[3]) = MEM_IN_STRUCT_P (operands[0]);
5379 MEM_VOLATILE_P (operands[3]) = MEM_VOLATILE_P (operands[0]);
5380 RTX_UNCHANGING_P (operands[3]) = RTX_UNCHANGING_P (operands[0]);
5384 [(set (match_operand 0 "register_operand" "")
5385 (match_operand 1 "splittable_immediate_memory_operand" ""))]
5387 [(set (match_dup 0) (match_dup 2))]
5390 rtx addr = legitimize_pic_address (XEXP (operands[1], 0),
5391 GET_MODE (operands[1]),
5393 operands[2] = gen_rtx (MEM, GET_MODE (operands[1]), addr);
5394 MEM_IN_STRUCT_P (operands[2]) = MEM_IN_STRUCT_P (operands[1]);
5395 MEM_VOLATILE_P (operands[2]) = MEM_VOLATILE_P (operands[1]);
5396 RTX_UNCHANGING_P (operands[2]) = RTX_UNCHANGING_P (operands[1]);
5399 ;; Sign- and Zero-extend operations can have symbolic memory operands.
5402 [(set (match_operand 0 "register_operand" "")
5403 (match_operator 1 "extend_op" [(match_operand 2 "splittable_immediate_memory_operand" "")]))]
5405 [(set (match_dup 0) (match_op_dup 1 [(match_dup 3)]))]
5408 rtx addr = legitimize_pic_address (XEXP (operands[2], 0),
5409 GET_MODE (operands[2]),
5411 operands[3] = gen_rtx (MEM, GET_MODE (operands[2]), addr);
5412 MEM_IN_STRUCT_P (operands[3]) = MEM_IN_STRUCT_P (operands[2]);
5413 MEM_VOLATILE_P (operands[3]) = MEM_VOLATILE_P (operands[2]);
5414 RTX_UNCHANGING_P (operands[3]) = RTX_UNCHANGING_P (operands[2]);
5418 [(set (match_operand:SI 0 "register_operand" "")
5419 (match_operand:SI 1 "immediate_operand" ""))]
5420 "! flag_pic && (GET_CODE (operands[1]) == SYMBOL_REF
5421 || GET_CODE (operands[1]) == CONST
5422 || GET_CODE (operands[1]) == LABEL_REF)"
5423 [(set (match_dup 0) (high:SI (match_dup 1)))
5425 (lo_sum:SI (match_dup 0) (match_dup 1)))]
5428 ;; LABEL_REFs are not modified by `legitimize_pic_address`
5429 ;; so do not recurse infinitely in the PIC case.
5431 [(set (match_operand:SI 0 "register_operand" "")
5432 (match_operand:SI 1 "immediate_operand" ""))]
5433 "flag_pic && (GET_CODE (operands[1]) == SYMBOL_REF
5434 || GET_CODE (operands[1]) == CONST)"
5435 [(set (match_dup 0) (match_dup 1))]
5438 operands[1] = legitimize_pic_address (operands[1], Pmode, operands[0]);
5441 ;; These split sne/seq insns. The forms of the resulting insns are
5442 ;; somewhat bogus, but they avoid extra patterns and show data dependency.
5443 ;; Nothing will look at these in detail after splitting has occurred.
5445 ;; ??? v9 DImode versions are missing because addc and subc use %icc.
5448 [(set (match_operand:SI 0 "register_operand" "")
5449 (ne:SI (match_operand:SI 1 "register_operand" "")
5451 (clobber (reg:CC 0))]
5453 [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
5455 (set (match_dup 0) (ltu:SI (reg:CC 0) (const_int 0)))]
5459 [(set (match_operand:SI 0 "register_operand" "")
5460 (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "")
5462 (clobber (reg:CC 0))]
5464 [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
5466 (set (match_dup 0) (neg:SI (ltu:SI (reg:CC 0) (const_int 0))))]
5470 [(set (match_operand:SI 0 "register_operand" "")
5471 (eq:SI (match_operand:SI 1 "register_operand" "")
5473 (clobber (reg:CC 0))]
5475 [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
5477 (set (match_dup 0) (geu:SI (reg:CC 0) (const_int 0)))]
5481 [(set (match_operand:SI 0 "register_operand" "")
5482 (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "")
5484 (clobber (reg:CC 0))]
5486 [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
5488 (set (match_dup 0) (neg:SI (geu:SI (reg:CC 0) (const_int 0))))]
5492 [(set (match_operand:SI 0 "register_operand" "")
5493 (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "")
5495 (match_operand:SI 2 "register_operand" "")))
5496 (clobber (reg:CC 0))]
5498 [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
5500 (set (match_dup 0) (plus:SI (ltu:SI (reg:CC 0) (const_int 0))
5505 [(set (match_operand:SI 0 "register_operand" "")
5506 (minus:SI (match_operand:SI 2 "register_operand" "")
5507 (ne:SI (match_operand:SI 1 "register_operand" "")
5509 (clobber (reg:CC 0))]
5511 [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
5513 (set (match_dup 0) (minus:SI (match_dup 2)
5514 (ltu:SI (reg:CC 0) (const_int 0))))]
5518 [(set (match_operand:SI 0 "register_operand" "")
5519 (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "")
5521 (match_operand:SI 2 "register_operand" "")))
5522 (clobber (reg:CC 0))]
5524 [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
5526 (set (match_dup 0) (plus:SI (geu:SI (reg:CC 0) (const_int 0))
5531 [(set (match_operand:SI 0 "register_operand" "")
5532 (minus:SI (match_operand:SI 2 "register_operand" "")
5533 (eq:SI (match_operand:SI 1 "register_operand" "")
5535 (clobber (reg:CC 0))]
5537 [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
5539 (set (match_dup 0) (minus:SI (match_dup 2)
5540 (geu:SI (reg:CC 0) (const_int 0))))]
5543 ;; Peepholes go at the end.
5545 ;; Optimize consecutive loads or stores into ldd and std when possible.
5546 ;; The conditions in which we do this are very restricted and are
5547 ;; explained in the code for {registers,memory}_ok_for_ldd functions.
5550 [(set (match_operand:SI 0 "register_operand" "=rf")
5551 (match_operand:SI 1 "memory_operand" ""))
5552 (set (match_operand:SI 2 "register_operand" "=rf")
5553 (match_operand:SI 3 "memory_operand" ""))]
5555 && registers_ok_for_ldd_peep (operands[0], operands[2])
5556 && ! MEM_VOLATILE_P (operands[1]) && ! MEM_VOLATILE_P (operands[3])
5557 && addrs_ok_for_ldd_peep (XEXP (operands[1], 0), XEXP (operands[3], 0))"
5561 [(set (match_operand:SI 0 "memory_operand" "")
5562 (match_operand:SI 1 "register_operand" "rf"))
5563 (set (match_operand:SI 2 "memory_operand" "")
5564 (match_operand:SI 3 "register_operand" "rf"))]
5566 && registers_ok_for_ldd_peep (operands[1], operands[3])
5567 && ! MEM_VOLATILE_P (operands[0]) && ! MEM_VOLATILE_P (operands[2])
5568 && addrs_ok_for_ldd_peep (XEXP (operands[0], 0), XEXP (operands[2], 0))"
5572 [(set (match_operand:SF 0 "register_operand" "=fr")
5573 (match_operand:SF 1 "memory_operand" ""))
5574 (set (match_operand:SF 2 "register_operand" "=fr")
5575 (match_operand:SF 3 "memory_operand" ""))]
5577 && registers_ok_for_ldd_peep (operands[0], operands[2])
5578 && ! MEM_VOLATILE_P (operands[1]) && ! MEM_VOLATILE_P (operands[3])
5579 && addrs_ok_for_ldd_peep (XEXP (operands[1], 0), XEXP (operands[3], 0))"
5583 [(set (match_operand:SF 0 "memory_operand" "")
5584 (match_operand:SF 1 "register_operand" "fr"))
5585 (set (match_operand:SF 2 "memory_operand" "")
5586 (match_operand:SF 3 "register_operand" "fr"))]
5588 && registers_ok_for_ldd_peep (operands[1], operands[3])
5589 && ! MEM_VOLATILE_P (operands[0]) && ! MEM_VOLATILE_P (operands[2])
5590 && addrs_ok_for_ldd_peep (XEXP (operands[0], 0), XEXP (operands[2], 0))"
5594 [(set (match_operand:SI 0 "register_operand" "=rf")
5595 (match_operand:SI 1 "memory_operand" ""))
5596 (set (match_operand:SI 2 "register_operand" "=rf")
5597 (match_operand:SI 3 "memory_operand" ""))]
5599 && registers_ok_for_ldd_peep (operands[2], operands[0])
5600 && ! MEM_VOLATILE_P (operands[3]) && ! MEM_VOLATILE_P (operands[1])
5601 && addrs_ok_for_ldd_peep (XEXP (operands[3], 0), XEXP (operands[1], 0))"
5605 [(set (match_operand:SI 0 "memory_operand" "")
5606 (match_operand:SI 1 "register_operand" "rf"))
5607 (set (match_operand:SI 2 "memory_operand" "")
5608 (match_operand:SI 3 "register_operand" "rf"))]
5610 && registers_ok_for_ldd_peep (operands[3], operands[1])
5611 && ! MEM_VOLATILE_P (operands[2]) && ! MEM_VOLATILE_P (operands[0])
5612 && addrs_ok_for_ldd_peep (XEXP (operands[2], 0), XEXP (operands[0], 0))"
5616 [(set (match_operand:SF 0 "register_operand" "=fr")
5617 (match_operand:SF 1 "memory_operand" ""))
5618 (set (match_operand:SF 2 "register_operand" "=fr")
5619 (match_operand:SF 3 "memory_operand" ""))]
5621 && registers_ok_for_ldd_peep (operands[2], operands[0])
5622 && ! MEM_VOLATILE_P (operands[3]) && ! MEM_VOLATILE_P (operands[1])
5623 && addrs_ok_for_ldd_peep (XEXP (operands[3], 0), XEXP (operands[1], 0))"
5627 [(set (match_operand:SF 0 "memory_operand" "")
5628 (match_operand:SF 1 "register_operand" "fr"))
5629 (set (match_operand:SF 2 "memory_operand" "")
5630 (match_operand:SF 3 "register_operand" "fr"))]
5632 && registers_ok_for_ldd_peep (operands[3], operands[1])
5633 && ! MEM_VOLATILE_P (operands[2]) && ! MEM_VOLATILE_P (operands[0])
5634 && addrs_ok_for_ldd_peep (XEXP (operands[2], 0), XEXP (operands[0], 0))"
5637 ;; Optimize the case of following a reg-reg move with a test
5638 ;; of reg just moved. Don't allow floating point regs for operand 0 or 1.
5639 ;; This can result from a float to fix conversion.
5642 [(set (match_operand:SI 0 "register_operand" "=r")
5643 (match_operand:SI 1 "register_operand" "r"))
5645 (compare:CC (match_operand:SI 2 "register_operand" "r")
5647 "(rtx_equal_p (operands[2], operands[0])
5648 || rtx_equal_p (operands[2], operands[1]))
5649 && ! FP_REG_P (operands[0]) && ! FP_REG_P (operands[1])"
5653 [(set (match_operand:DI 0 "register_operand" "=r")
5654 (match_operand:DI 1 "register_operand" "r"))
5656 (compare:CCX (match_operand:DI 2 "register_operand" "r")
5659 && (rtx_equal_p (operands[2], operands[0])
5660 || rtx_equal_p (operands[2], operands[1]))
5661 && ! FP_REG_P (operands[0]) && ! FP_REG_P (operands[1])"
5664 ;; Do {sign,zero}-extended compares somewhat more efficiently.
5665 ;; ??? Is this now the Right Way to do this? Or will SCRATCH
5666 ;; eventually have some impact here?
5669 [(set (match_operand:HI 0 "register_operand" "")
5670 (match_operand:HI 1 "memory_operand" ""))
5671 (set (match_operand:SI 2 "register_operand" "")
5672 (sign_extend:SI (match_dup 0)))
5674 (compare:CC (match_dup 2)
5677 "ldsh %1,%0\;orcc %0,%%g0,%2")
5680 [(set (match_operand:HI 0 "register_operand" "")
5681 (match_operand:HI 1 "memory_operand" ""))
5682 (set (match_operand:DI 2 "register_operand" "")
5683 (sign_extend:DI (match_dup 0)))
5685 (compare:CCX (match_dup 2)
5688 "ldsh %1,%0\;orcc %0,%%g0,%2")
5691 [(set (match_operand:QI 0 "register_operand" "")
5692 (match_operand:QI 1 "memory_operand" ""))
5693 (set (match_operand:SI 2 "register_operand" "")
5694 (sign_extend:SI (match_dup 0)))
5696 (compare:CC (match_dup 2)
5699 "ldsb %1,%0\;orcc %0,%%g0,%2")
5702 [(set (match_operand:QI 0 "register_operand" "")
5703 (match_operand:QI 1 "memory_operand" ""))
5704 (set (match_operand:DI 2 "register_operand" "")
5705 (sign_extend:DI (match_dup 0)))
5707 (compare:CCX (match_dup 2)
5710 "ldsb %1,%0\;orcc %0,%%g0,%2")
5712 ;; Floating-point move peepholes
5713 ;; ??? v9: Do we want similar ones?
5716 [(set (match_operand:SI 0 "register_operand" "=r")
5717 (lo_sum:SI (match_dup 0)
5718 (match_operand:SI 1 "immediate_operand" "i")))
5719 (set (match_operand:DF 2 "register_operand" "=er")
5720 (mem:DF (match_dup 0)))]
5721 "RTX_UNCHANGING_P (operands[1]) && reg_unused_after (operands[0], insn)"
5724 /* Go by way of output_move_double in case the register in operand 2
5725 is not properly aligned for ldd. */
5726 operands[1] = gen_rtx (MEM, DFmode,
5727 gen_rtx (LO_SUM, SImode, operands[0], operands[1]));
5728 operands[0] = operands[2];
5729 return output_move_double (operands);
5733 [(set (match_operand:SI 0 "register_operand" "=r")
5734 (lo_sum:SI (match_dup 0)
5735 (match_operand:SI 1 "immediate_operand" "i")))
5736 (set (match_operand:SF 2 "register_operand" "=fr")
5737 (mem:SF (match_dup 0)))]
5738 "RTX_UNCHANGING_P (operands[1]) && reg_unused_after (operands[0], insn)"
5739 "ld [%0+%%lo(%a1)],%2")
5741 ;; Return peepholes. First the "normal" ones
5743 ;; ??? There are QImode, HImode, and SImode versions of this pattern.
5744 ;; It might be possible to write one more general pattern instead of three.
5746 (define_insn "*return_qi"
5747 [(set (match_operand:QI 0 "restore_operand" "")
5748 (match_operand:QI 1 "arith_operand" "rI"))
5753 if (! TARGET_ARCH64 && current_function_returns_struct)
5754 return \"jmp %%i7+12\;restore %%g0,%1,%Y0\";
5756 return \"ret\;restore %%g0,%1,%Y0\";
5758 [(set_attr "type" "multi")])
5760 (define_insn "*return_hi"
5761 [(set (match_operand:HI 0 "restore_operand" "")
5762 (match_operand:HI 1 "arith_operand" "rI"))
5767 if (! TARGET_ARCH64 && current_function_returns_struct)
5768 return \"jmp %%i7+12\;restore %%g0,%1,%Y0\";
5770 return \"ret\;restore %%g0,%1,%Y0\";
5772 [(set_attr "type" "multi")])
5774 (define_insn "*return_si"
5775 [(set (match_operand:SI 0 "restore_operand" "")
5776 (match_operand:SI 1 "arith_operand" "rI"))
5781 if (! TARGET_ARCH64 && current_function_returns_struct)
5782 return \"jmp %%i7+12\;restore %%g0,%1,%Y0\";
5784 return \"ret\;restore %%g0,%1,%Y0\";
5786 [(set_attr "type" "multi")])
5788 ;; The following pattern is only generated by delayed-branch scheduling,
5789 ;; when the insn winds up in the epilogue. This can only happen when
5790 ;; ! TARGET_FPU because otherwise fp return values are in %f0.
5791 (define_insn "*return_sf_no_fpu"
5792 [(set (match_operand:SF 0 "restore_operand" "r")
5793 (match_operand:SF 1 "register_operand" "r"))
5795 "! TARGET_FPU && ! TARGET_EPILOGUE"
5798 if (! TARGET_ARCH64 && current_function_returns_struct)
5799 return \"jmp %%i7+12\;restore %%g0,%1,%Y0\";
5801 return \"ret\;restore %%g0,%1,%Y0\";
5803 [(set_attr "type" "multi")])
5805 (define_insn "*return_addsi"
5806 [(set (match_operand:SI 0 "restore_operand" "")
5807 (plus:SI (match_operand:SI 1 "arith_operand" "%r")
5808 (match_operand:SI 2 "arith_operand" "rI")))
5813 if (! TARGET_ARCH64 && current_function_returns_struct)
5814 return \"jmp %%i7+12\;restore %r1,%2,%Y0\";
5816 return \"ret\;restore %r1,%2,%Y0\";
5818 [(set_attr "type" "multi")])
5820 (define_insn "*return_di"
5821 [(set (match_operand:DI 0 "restore_operand" "")
5822 (match_operand:DI 1 "arith_double_operand" "rHI"))
5824 "TARGET_ARCH64 && ! TARGET_EPILOGUE"
5825 "ret\;restore %%g0,%1,%Y0"
5826 [(set_attr "type" "multi")])
5828 (define_insn "*return_adddi"
5829 [(set (match_operand:DI 0 "restore_operand" "")
5830 (plus:DI (match_operand:DI 1 "arith_operand" "%r")
5831 (match_operand:DI 2 "arith_double_operand" "rHI")))
5833 "TARGET_ARCH64 && ! TARGET_EPILOGUE"
5834 "ret\;restore %r1,%2,%Y0"
5835 [(set_attr "type" "multi")])
5837 ;; Turned off because it should never match (subtracting a constant
5838 ;; is turned into addition) and because it would do the wrong thing
5839 ;; when operand 2 is -4096 (--4096 == 4096 is not a valid immediate).
5840 ;;(define_insn "*minus_const"
5841 ;; [(set (match_operand:SI 0 "restore_operand" "")
5842 ;; (minus:SI (match_operand:SI 1 "register_operand" "r")
5843 ;; (match_operand:SI 2 "small_int" "I")))
5845 ;; "! TARGET_EPILOGUE"
5846 ;; "ret\;restore %1,-(%2),%Y0"
5847 ;; [(set_attr "type" "multi")])
5849 ;; The following pattern is only generated by delayed-branch scheduling,
5850 ;; when the insn winds up in the epilogue.
5851 (define_insn "*return_sf"
5853 (match_operand:SF 0 "register_operand" "f"))
5856 "ret\;fmovs %0,%%f0"
5857 [(set_attr "type" "multi")])
5859 ;; Now peepholes to do a call followed by a jump.
5862 [(parallel [(set (match_operand 0 "" "")
5863 (call (mem:SI (match_operand:SI 1 "call_operand_address" "ps"))
5864 (match_operand 2 "" "")))
5865 (clobber (reg:SI 15))])
5866 (set (pc) (label_ref (match_operand 3 "" "")))]
5867 "short_branch (INSN_UID (insn), INSN_UID (operands[3]))"
5868 "call %a1,%2\;add %%o7,(%l3-.-4),%%o7")
5871 [(parallel [(call (mem:SI (match_operand:SI 0 "call_operand_address" "ps"))
5872 (match_operand 1 "" ""))
5873 (clobber (reg:SI 15))])
5874 (set (pc) (label_ref (match_operand 2 "" "")))]
5875 "short_branch (INSN_UID (insn), INSN_UID (operands[2]))"
5878 return \"call %a0,%1\;add %%o7,(%l2-.-4),%%o7\";
5882 [(parallel [(set (match_operand 0 "" "")
5883 (call (mem:SI (match_operand:DI 1 "call_operand_address" "ps"))
5884 (match_operand 2 "" "")))
5885 (clobber (reg:DI 15))])
5886 (set (pc) (label_ref (match_operand 3 "" "")))]
5887 "TARGET_ARCH64 && short_branch (INSN_UID (insn), INSN_UID (operands[3]))"
5888 "call %a1,%2\;add %%o7,(%l3-.-4),%%o7")
5891 [(parallel [(call (mem:SI (match_operand:DI 0 "call_operand_address" "ps"))
5892 (match_operand 1 "" ""))
5893 (clobber (reg:DI 15))])
5894 (set (pc) (label_ref (match_operand 2 "" "")))]
5895 "TARGET_ARCH64 && short_branch (INSN_UID (insn), INSN_UID (operands[2]))"
5896 "call %a0,%1\;add %%o7,(%l2-.-4),%%o7")
5898 ;; Other miscellaneous peepholes.
5901 [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
5902 (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5904 (clobber (reg:CC 0))])
5905 (set (reg:CC 0) (compare (match_dup 0) (const_int 0)))]