1 ;;- Machine description for SPARC chip for GNU C compiler
2 ;; Copyright (C) 1987, 88, 89, 92, 93, 1994 Free Software Foundation, Inc.
3 ;; Contributed by Michael Tiemann (tiemann@cygnus.com)
4 ;; 64 bit SPARC V9 support by Michael Tiemann, Jim Wilson, and Doug Evans,
7 ;; This file is part of GNU CC.
9 ;; GNU CC is free software; you can redistribute it and/or modify
10 ;; it under the terms of the GNU General Public License as published by
11 ;; the Free Software Foundation; either version 2, or (at your option)
14 ;; GNU CC is distributed in the hope that it will be useful,
15 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
16 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 ;; GNU General Public License for more details.
19 ;; You should have received a copy of the GNU General Public License
20 ;; along with GNU CC; see the file COPYING. If not, write to
21 ;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
23 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
25 ;; The upper 32 fp regs on the v9 can't hold SFmode values. To deal with this
26 ;; a second register class, EXTRA_FP_REGS, exists for the v9 chip. The name
27 ;; is a bit of a misnomer as it covers all 64 fp regs. The corresponding
28 ;; constraint letter is 'e'. To avoid any confusion, 'e' is used instead of
29 ;; 'f' for all DF/TFmode values, including those that are specific to the v8.
31 ;; Architecture type. Arch32bit includes v7, sparclite, v8.
33 (define_attr "arch" "arch32bit,arch64bit"
34 (const (symbol_ref "sparc_arch_type")))
36 ;; CPU type. This is only used for instruction scheduling
37 (define_attr "cpu" "cypress,supersparc"
39 (cond [(symbol_ref "TARGET_SUPERSPARC") (const_string "supersparc")]
40 (const_string "cypress"))))
42 ;; Insn type. Used to default other attribute values.
44 ;; type "unary" insns have one input operand (1) and one output operand (0)
45 ;; type "binary" insns have two input operands (1,2) and one output (0)
46 ;; type "compare" insns have one or two input operands (0,1) and no output
47 ;; type "call_no_delay_slot" is a call followed by an unimp instruction.
50 "move,unary,binary,compare,load,store,ialu,shift,uncond_branch,branch,call,call_no_delay_slot,address,imul,fpload,fpstore,fp,fpcmp,fpmul,fpdivs,fpdivd,fpsqrt,cmove,multi,misc"
51 (const_string "binary"))
53 ;; Set true if insn uses call-clobbered intermediate register.
54 (define_attr "use_clobbered" "false,true"
55 (if_then_else (and (eq_attr "type" "address")
56 (match_operand 0 "clobbered_register" ""))
58 (const_string "false")))
60 ;; Length (in # of insns).
61 (define_attr "length" ""
62 (cond [(eq_attr "type" "load,fpload")
63 (if_then_else (match_operand 1 "symbolic_memory_operand" "")
64 (const_int 2) (const_int 1))
66 (eq_attr "type" "store,fpstore")
67 (if_then_else (match_operand 0 "symbolic_memory_operand" "")
68 (const_int 2) (const_int 1))
70 (eq_attr "type" "address") (const_int 2)
72 (eq_attr "type" "binary")
73 (if_then_else (ior (match_operand 2 "arith_operand" "")
74 (match_operand 2 "arith_double_operand" ""))
75 (const_int 1) (const_int 3))
77 (eq_attr "type" "multi") (const_int 2)
79 (eq_attr "type" "move,unary")
80 (if_then_else (ior (match_operand 1 "arith_operand" "")
81 (match_operand 1 "arith_double_operand" ""))
82 (const_int 1) (const_int 2))]
86 (define_asm_attributes
87 [(set_attr "length" "1")
88 (set_attr "type" "multi")])
90 ;; Attributes for instruction and branch scheduling
92 (define_attr "in_call_delay" "false,true"
93 (cond [(eq_attr "type" "uncond_branch,branch,call,call_no_delay_slot,multi")
94 (const_string "false")
95 (eq_attr "type" "load,fpload,store,fpstore")
96 (if_then_else (eq_attr "length" "1")
98 (const_string "false"))
99 (eq_attr "type" "address")
100 (if_then_else (eq_attr "use_clobbered" "false")
101 (const_string "true")
102 (const_string "false"))]
103 (if_then_else (eq_attr "length" "1")
104 (const_string "true")
105 (const_string "false"))))
107 (define_delay (eq_attr "type" "call")
108 [(eq_attr "in_call_delay" "true") (nil) (nil)])
110 ;; ??? Should implement the notion of predelay slots for floating point
111 ;; branches. This would allow us to remove the nop always inserted before
112 ;; a floating point branch.
114 ;; ??? It is OK for fill_simple_delay_slots to put load/store instructions
115 ;; in a delay slot, but it is not OK for fill_eager_delay_slots to do so.
116 ;; This is because doing so will add several pipeline stalls to the path
117 ;; that the load/store did not come from. Unfortunately, there is no way
118 ;; to prevent fill_eager_delay_slots from using load/store without completely
119 ;; disabling them. For the SPEC benchmark set, this is a serious lose,
120 ;; because it prevents us from moving back the final store of inner loops.
122 (define_attr "in_branch_delay" "false,true"
123 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,call_no_delay_slot,multi")
124 (eq_attr "length" "1"))
125 (const_string "true")
126 (const_string "false")))
128 (define_attr "in_uncond_branch_delay" "false,true"
129 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,call_no_delay_slot,multi")
130 (eq_attr "length" "1"))
131 (const_string "true")
132 (const_string "false")))
134 (define_attr "in_annul_branch_delay" "false,true"
135 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,call_no_delay_slot,multi")
136 (eq_attr "length" "1"))
137 (const_string "true")
138 (const_string "false")))
140 (define_delay (eq_attr "type" "branch")
141 [(eq_attr "in_branch_delay" "true")
142 (nil) (eq_attr "in_annul_branch_delay" "true")])
144 (define_delay (eq_attr "type" "uncond_branch")
145 [(eq_attr "in_uncond_branch_delay" "true")
148 ;; Function units of the SPARC
150 ;; (define_function_unit {name} {num-units} {n-users} {test}
151 ;; {ready-delay} {issue-delay} [{conflict-list}])
154 ;; (Noted only for documentation; units that take one cycle do not need to
157 ;; On the sparclite, integer multiply takes 1, 3, or 5 cycles depending on
160 ;; (define_function_unit "alu" 1 0
161 ;; (eq_attr "type" "unary,binary,move,address") 1 0)
163 ;; ---- cypress CY7C602 scheduling:
164 ;; Memory with load-delay of 1 (i.e., 2 cycle load).
165 (define_function_unit "memory" 1 0
166 (and (eq_attr "type" "load,fpload") (eq_attr "cpu" "cypress")) 2 2)
168 ;; SPARC has two floating-point units: the FP ALU,
169 ;; and the FP MUL/DIV/SQRT unit.
170 ;; Instruction timings on the CY7C602 are as follows
184 ;; The CY7C602 can only support 2 fp isnsn simultaneously.
185 ;; More insns cause the chip to stall.
187 (define_function_unit "fp_alu" 1 0
188 (and (eq_attr "type" "fp") (eq_attr "cpu" "cypress")) 5 5)
189 (define_function_unit "fp_mds" 1 0
190 (and (eq_attr "type" "fpmul") (eq_attr "cpu" "cypress")) 7 7)
191 (define_function_unit "fp_mds" 1 0
192 (and (eq_attr "type" "fpdivs,fpdivd") (eq_attr "cpu" "cypress")) 37 37)
193 (define_function_unit "fp_mds" 1 0
194 (and (eq_attr "type" "fpsqrt") (eq_attr "cpu" "cypress")) 63 63)
196 ;; ----- The TMS390Z55 scheduling
197 ;; The Supersparc can issue 1 - 3 insns per cycle; here we assume
198 ;; three insns/cycle, and hence multiply all costs by three.
199 ;; Combinations up to two integer, one ld/st, one fp.
200 ;; Memory delivers its result in one cycle to IU, zero cycles to FP
201 (define_function_unit "memory" 1 0
202 (and (eq_attr "type" "load") (eq_attr "cpu" "supersparc")) 3 3)
203 (define_function_unit "memory" 1 0
204 (and (eq_attr "type" "fpload") (eq_attr "cpu" "supersparc")) 1 3)
205 ;; at least one in three instructions can be a mem opt.
206 (define_function_unit "memory" 1 0
207 (and (eq_attr "type" "store,fpstore") (eq_attr "cpu" "supersparc")) 1 3)
208 ;; at least one in three instructions can be a shift op.
209 (define_function_unit "shift" 1 0
210 (and (eq_attr "type" "shift") (eq_attr "cpu" "supersparc")) 1 3)
212 ;; There are only two write ports to the integer register file
213 ;; A store also uses a write port
214 (define_function_unit "iwport" 2 0
215 (and (eq_attr "type" "load,store,shift,ialu") (eq_attr "cpu" "supersparc")) 1 3)
217 ;; Timings; throughput/latency
218 ;; FADD 1/3 add/sub, format conv, compar, abs, neg
226 (define_function_unit "fp_alu" 1 0
227 (and (eq_attr "type" "fp,fpcmp") (eq_attr "cpu" "supersparc")) 9 3)
228 (define_function_unit "fp_mds" 1 0
229 (and (eq_attr "type" "fpmul") (eq_attr "cpu" "supersparc")) 9 3)
230 (define_function_unit "fp_mds" 1 0
231 (and (eq_attr "type" "fpdivs") (eq_attr "cpu" "supersparc")) 18 12)
232 (define_function_unit "fp_mds" 1 0
233 (and (eq_attr "type" "fpdivd") (eq_attr "cpu" "supersparc")) 27 21)
234 (define_function_unit "fp_mds" 1 0
235 (and (eq_attr "type" "fpsqrt") (eq_attr "cpu" "supersparc")) 36 30)
236 (define_function_unit "fp_mds" 1 0
237 (and (eq_attr "type" "imul") (eq_attr "cpu" "supersparc")) 12 12)
239 ;; Compare instructions.
240 ;; This controls RTL generation and register allocation.
242 ;; We generate RTL for comparisons and branches by having the cmpxx
243 ;; patterns store away the operands. Then, the scc and bcc patterns
244 ;; emit RTL for both the compare and the branch.
246 ;; We do this because we want to generate different code for an sne and
247 ;; seq insn. In those cases, if the second operand of the compare is not
248 ;; const0_rtx, we want to compute the xor of the two operands and test
251 ;; We start with the DEFINE_EXPANDs, then the DEFINE_INSNs to match
252 ;; the patterns. Finally, we have the DEFINE_SPLITs for some of the scc
253 ;; insns that actually require more than one machine instruction.
255 ;; Put cmpsi first among compare insns so it matches two CONST_INT operands.
257 (define_expand "cmpsi"
259 (compare:CC (match_operand:SI 0 "register_operand" "")
260 (match_operand:SI 1 "arith_operand" "")))]
264 sparc_compare_op0 = operands[0];
265 sparc_compare_op1 = operands[1];
269 (define_expand "cmpdi"
271 (compare:CCX (match_operand:DI 0 "register_operand" "")
272 (match_operand:DI 1 "arith_double_operand" "")))]
276 sparc_compare_op0 = operands[0];
277 sparc_compare_op1 = operands[1];
281 (define_expand "cmpsf"
283 (compare:CCFP (match_operand:SF 0 "register_operand" "")
284 (match_operand:SF 1 "register_operand" "")))]
288 sparc_compare_op0 = operands[0];
289 sparc_compare_op1 = operands[1];
293 (define_expand "cmpdf"
295 (compare:CCFP (match_operand:DF 0 "register_operand" "")
296 (match_operand:DF 1 "register_operand" "")))]
300 sparc_compare_op0 = operands[0];
301 sparc_compare_op1 = operands[1];
305 (define_expand "cmptf"
307 (compare:CCFP (match_operand:TF 0 "register_operand" "")
308 (match_operand:TF 1 "register_operand" "")))]
312 sparc_compare_op0 = operands[0];
313 sparc_compare_op1 = operands[1];
317 ;; Next come the scc insns. For seq, sne, sgeu, and sltu, we can do this
318 ;; without jumps using the addx/subx instructions. For seq/sne on v9 we use
319 ;; the same code as v8 (the addx/subx method has more applications). The
320 ;; exception to this is "reg != 0" which can be done in one instruction on v9
321 ;; (so we do it). For the rest, on v9 we use conditional moves; on v8, we do
324 ;; Seq_special[_xxx] and sne_special[_xxx] clobber the CC reg, because they
325 ;; generate addcc/subcc instructions.
327 (define_expand "seqsi_special"
329 (xor:SI (match_operand:SI 1 "register_operand" "")
330 (match_operand:SI 2 "register_operand" "")))
331 (parallel [(set (match_operand:SI 0 "register_operand" "")
332 (eq:SI (match_dup 3) (const_int 0)))
333 (clobber (reg:CC 0))])]
335 "{ operands[3] = gen_reg_rtx (SImode); }")
337 (define_expand "seqdi_special"
339 (xor:DI (match_operand:DI 1 "register_operand" "")
340 (match_operand:DI 2 "register_operand" "")))
341 (parallel [(set (match_operand:DI 0 "register_operand" "")
342 (eq:DI (match_dup 3) (const_int 0)))
343 (clobber (reg:CCX 0))])]
345 "{ operands[3] = gen_reg_rtx (DImode); }")
347 (define_expand "snesi_special"
349 (xor:SI (match_operand:SI 1 "register_operand" "")
350 (match_operand:SI 2 "register_operand" "")))
351 (parallel [(set (match_operand:SI 0 "register_operand" "")
352 (ne:SI (match_dup 3) (const_int 0)))
353 (clobber (reg:CC 0))])]
355 "{ operands[3] = gen_reg_rtx (SImode); }")
357 (define_expand "snedi_special"
359 (xor:DI (match_operand:DI 1 "register_operand" "")
360 (match_operand:DI 2 "register_operand" "")))
361 (parallel [(set (match_operand:DI 0 "register_operand" "")
362 (ne:DI (match_dup 3) (const_int 0)))
363 (clobber (reg:CCX 0))])]
365 "{ operands[3] = gen_reg_rtx (DImode); }")
367 (define_expand "seqdi_special_trunc"
369 (xor:DI (match_operand:DI 1 "register_operand" "")
370 (match_operand:DI 2 "register_operand" "")))
371 (parallel [(set (match_operand:SI 0 "register_operand" "")
372 (eq:SI (subreg:SI (match_dup 3) 0) (const_int 0)))
373 (clobber (reg:CC 0))])]
375 "{ operands[3] = gen_reg_rtx (DImode); }")
377 (define_expand "snedi_special_trunc"
379 (xor:DI (match_operand:DI 1 "register_operand" "")
380 (match_operand:DI 2 "register_operand" "")))
381 (parallel [(set (match_operand:SI 0 "register_operand" "")
382 (ne:SI (subreg:SI (match_dup 3) 0) (const_int 0)))
383 (clobber (reg:CC 0))])]
385 "{ operands[3] = gen_reg_rtx (DImode); }")
387 (define_expand "seqsi_special_extend"
388 [(set (subreg:SI (match_dup 3) 0)
389 (xor:SI (match_operand:SI 1 "register_operand" "")
390 (match_operand:SI 2 "register_operand" "")))
391 (parallel [(set (match_operand:DI 0 "register_operand" "")
392 (eq:DI (match_dup 3) (const_int 0)))
393 (clobber (reg:CCX 0))])]
395 "{ operands[3] = gen_reg_rtx (DImode); }")
397 (define_expand "snesi_special_extend"
398 [(set (subreg:SI (match_dup 3) 0)
399 (xor:SI (match_operand:SI 1 "register_operand" "")
400 (match_operand:SI 2 "register_operand" "")))
401 (parallel [(set (match_operand:DI 0 "register_operand" "")
402 (ne:DI (match_dup 3) (const_int 0)))
403 (clobber (reg:CCX 0))])]
405 "{ operands[3] = gen_reg_rtx (DImode); }")
407 ;; ??? v9: Operand 0 needs a mode, so SImode was chosen.
408 ;; However, the code handles both SImode and DImode.
410 [(set (match_operand:SI 0 "intreg_operand" "")
411 (eq:SI (match_dup 1) (const_int 0)))]
415 if (GET_MODE (sparc_compare_op0) == SImode)
419 if (GET_MODE (operands[0]) == SImode)
420 pat = gen_seqsi_special (operands[0], sparc_compare_op0,
422 else if (! TARGET_V9)
425 pat = gen_seqsi_special_extend (operands[0], sparc_compare_op0,
430 else if (GET_MODE (sparc_compare_op0) == DImode)
434 if (GET_MODE (operands[0]) == SImode)
435 pat = gen_seqdi_special_trunc (operands[0], sparc_compare_op0,
437 else if (! TARGET_V9)
440 pat = gen_seqdi_special (operands[0], sparc_compare_op0,
445 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
447 emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, EQ);
448 emit_insn (gen_sne (operands[0]));
453 if (gen_v9_scc (EQ, operands))
457 operands[1] = gen_compare_reg (EQ, sparc_compare_op0, sparc_compare_op1);
460 ;; ??? v9: Operand 0 needs a mode, so SImode was chosen.
461 ;; However, the code handles both SImode and DImode.
463 [(set (match_operand:SI 0 "intreg_operand" "")
464 (ne:SI (match_dup 1) (const_int 0)))]
468 if (GET_MODE (sparc_compare_op0) == SImode)
472 if (GET_MODE (operands[0]) == SImode)
473 pat = gen_snesi_special (operands[0], sparc_compare_op0,
475 else if (! TARGET_V9)
478 pat = gen_snesi_special_extend (operands[0], sparc_compare_op0,
483 else if (GET_MODE (sparc_compare_op0) == DImode)
487 if (GET_MODE (operands[0]) == SImode)
488 pat = gen_snedi_special_trunc (operands[0], sparc_compare_op0,
490 else if (! TARGET_V9)
493 pat = gen_snedi_special (operands[0], sparc_compare_op0,
498 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
500 emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, NE);
501 emit_insn (gen_sne (operands[0]));
506 if (gen_v9_scc (NE, operands))
510 operands[1] = gen_compare_reg (NE, sparc_compare_op0, sparc_compare_op1);
514 [(set (match_operand:SI 0 "intreg_operand" "")
515 (gt:SI (match_dup 1) (const_int 0)))]
519 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
521 emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GT);
522 emit_insn (gen_sne (operands[0]));
527 if (gen_v9_scc (GT, operands))
531 operands[1] = gen_compare_reg (GT, sparc_compare_op0, sparc_compare_op1);
535 [(set (match_operand:SI 0 "intreg_operand" "")
536 (lt:SI (match_dup 1) (const_int 0)))]
540 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
542 emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LT);
543 emit_insn (gen_sne (operands[0]));
548 if (gen_v9_scc (LT, operands))
552 operands[1] = gen_compare_reg (LT, sparc_compare_op0, sparc_compare_op1);
556 [(set (match_operand:SI 0 "intreg_operand" "")
557 (ge:SI (match_dup 1) (const_int 0)))]
561 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
563 emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GE);
564 emit_insn (gen_sne (operands[0]));
569 if (gen_v9_scc (GE, operands))
573 operands[1] = gen_compare_reg (GE, sparc_compare_op0, sparc_compare_op1);
577 [(set (match_operand:SI 0 "intreg_operand" "")
578 (le:SI (match_dup 1) (const_int 0)))]
582 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
584 emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LE);
585 emit_insn (gen_sne (operands[0]));
590 if (gen_v9_scc (LE, operands))
594 operands[1] = gen_compare_reg (LE, sparc_compare_op0, sparc_compare_op1);
597 (define_expand "sgtu"
598 [(set (match_operand:SI 0 "intreg_operand" "")
599 (gtu:SI (match_dup 1) (const_int 0)))]
607 /* We can do ltu easily, so if both operands are registers, swap them and
609 if ((GET_CODE (sparc_compare_op0) == REG
610 || GET_CODE (sparc_compare_op0) == SUBREG)
611 && (GET_CODE (sparc_compare_op1) == REG
612 || GET_CODE (sparc_compare_op1) == SUBREG))
614 tem = sparc_compare_op0;
615 sparc_compare_op0 = sparc_compare_op1;
616 sparc_compare_op1 = tem;
617 emit_insn (gen_sltu (operands[0]));
623 if (gen_v9_scc (GTU, operands))
626 operands[1] = gen_compare_reg (GTU, sparc_compare_op0, sparc_compare_op1);
629 (define_expand "sltu"
630 [(set (match_operand:SI 0 "intreg_operand" "")
631 (ltu:SI (match_dup 1) (const_int 0)))]
637 if (gen_v9_scc (LTU, operands))
640 operands[1] = gen_compare_reg (LTU, sparc_compare_op0, sparc_compare_op1);
643 (define_expand "sgeu"
644 [(set (match_operand:SI 0 "intreg_operand" "")
645 (geu:SI (match_dup 1) (const_int 0)))]
651 if (gen_v9_scc (GEU, operands))
654 operands[1] = gen_compare_reg (GEU, sparc_compare_op0, sparc_compare_op1);
657 (define_expand "sleu"
658 [(set (match_operand:SI 0 "intreg_operand" "")
659 (leu:SI (match_dup 1) (const_int 0)))]
667 /* We can do geu easily, so if both operands are registers, swap them and
669 if ((GET_CODE (sparc_compare_op0) == REG
670 || GET_CODE (sparc_compare_op0) == SUBREG)
671 && (GET_CODE (sparc_compare_op1) == REG
672 || GET_CODE (sparc_compare_op1) == SUBREG))
674 tem = sparc_compare_op0;
675 sparc_compare_op0 = sparc_compare_op1;
676 sparc_compare_op1 = tem;
677 emit_insn (gen_sgeu (operands[0]));
683 if (gen_v9_scc (LEU, operands))
686 operands[1] = gen_compare_reg (LEU, sparc_compare_op0, sparc_compare_op1);
689 ;; Now the DEFINE_INSNs for the compare and scc cases. First the compares.
693 (compare:CC (match_operand:SI 0 "register_operand" "r")
694 (match_operand:SI 1 "arith_operand" "rI")))]
697 [(set_attr "type" "compare")])
701 (compare:CCFPE (match_operand:SF 0 "register_operand" "f")
702 (match_operand:SF 1 "register_operand" "f")))]
703 "! TARGET_V9 && TARGET_FPU"
705 [(set_attr "type" "fpcmp")])
709 (compare:CCFPE (match_operand:DF 0 "register_operand" "e")
710 (match_operand:DF 1 "register_operand" "e")))]
711 "! TARGET_V9 && TARGET_FPU"
713 [(set_attr "type" "fpcmp")])
717 (compare:CCFPE (match_operand:TF 0 "register_operand" "e")
718 (match_operand:TF 1 "register_operand" "e")))]
719 "! TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
721 [(set_attr "type" "fpcmp")])
725 (compare:CCFP (match_operand:SF 0 "register_operand" "f")
726 (match_operand:SF 1 "register_operand" "f")))]
727 "! TARGET_V9 && TARGET_FPU"
729 [(set_attr "type" "fpcmp")])
733 (compare:CCFP (match_operand:DF 0 "register_operand" "e")
734 (match_operand:DF 1 "register_operand" "e")))]
735 "! TARGET_V9 && TARGET_FPU"
737 [(set_attr "type" "fpcmp")])
741 (compare:CCFP (match_operand:TF 0 "register_operand" "e")
742 (match_operand:TF 1 "register_operand" "e")))]
743 "! TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
745 [(set_attr "type" "fpcmp")])
749 (compare:CCX (match_operand:DI 0 "register_operand" "r")
750 (match_operand:DI 1 "arith_double_operand" "rHI")))]
753 [(set_attr "type" "compare")])
756 [(set (match_operand:CCFPE 0 "ccfp_reg_operand" "=c")
757 (compare:CCFPE (match_operand:SF 1 "register_operand" "f")
758 (match_operand:SF 2 "register_operand" "f")))]
759 "TARGET_V9 && TARGET_FPU"
761 [(set_attr "type" "fpcmp")])
764 [(set (match_operand:CCFPE 0 "ccfp_reg_operand" "=c")
765 (compare:CCFPE (match_operand:DF 1 "register_operand" "e")
766 (match_operand:DF 2 "register_operand" "e")))]
767 "TARGET_V9 && TARGET_FPU"
769 [(set_attr "type" "fpcmp")])
772 [(set (match_operand:CCFPE 0 "ccfp_reg_operand" "=c")
773 (compare:CCFPE (match_operand:TF 1 "register_operand" "e")
774 (match_operand:TF 2 "register_operand" "e")))]
775 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
777 [(set_attr "type" "fpcmp")])
780 [(set (match_operand:CCFP 0 "ccfp_reg_operand" "=c")
781 (compare:CCFP (match_operand:SF 1 "register_operand" "f")
782 (match_operand:SF 2 "register_operand" "f")))]
783 "TARGET_V9 && TARGET_FPU"
785 [(set_attr "type" "fpcmp")])
788 [(set (match_operand:CCFP 0 "ccfp_reg_operand" "=c")
789 (compare:CCFP (match_operand:DF 1 "register_operand" "e")
790 (match_operand:DF 2 "register_operand" "e")))]
791 "TARGET_V9 && TARGET_FPU"
793 [(set_attr "type" "fpcmp")])
796 [(set (match_operand:CCFP 0 "ccfp_reg_operand" "=c")
797 (compare:CCFP (match_operand:TF 1 "register_operand" "e")
798 (match_operand:TF 2 "register_operand" "e")))]
799 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
801 [(set_attr "type" "fpcmp")])
803 ;; The SEQ and SNE patterns are special because they can be done
804 ;; without any branching and do not involve a COMPARE.
807 [(set (match_operand:SI 0 "register_operand" "=r")
808 (ne:SI (match_operand:SI 1 "register_operand" "r")
810 (clobber (reg:CC 0))]
812 "subcc %%g0,%1,%%g0\;addx %%g0,0,%0"
813 [(set_attr "type" "unary")
814 (set_attr "length" "2")])
817 [(set (match_operand:SI 0 "register_operand" "=r")
818 (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
820 (clobber (reg:CC 0))]
822 "subcc %%g0,%1,%%g0\;subx %%g0,0,%0"
823 [(set_attr "type" "unary")
824 (set_attr "length" "2")])
827 [(set (match_operand:DI 0 "register_operand" "=r")
828 (ne:DI (match_operand:DI 1 "register_operand" "r")
830 (clobber (reg:CCX 0))]
832 "mov 0,%0\;movrnz %1,1,%0"
833 [(set_attr "type" "unary")
834 (set_attr "length" "2")])
837 [(set (match_operand:DI 0 "register_operand" "=r")
838 (neg:DI (ne:DI (match_operand:DI 1 "register_operand" "r")
840 (clobber (reg:CCX 0))]
842 "mov 0,%0\;movrnz %1,-1,%0"
843 [(set_attr "type" "unary")
844 (set_attr "length" "2")])
847 [(set (match_operand:SI 0 "register_operand" "=r")
848 (eq:SI (match_operand:SI 1 "register_operand" "r")
850 (clobber (reg:CC 0))]
852 "subcc %%g0,%1,%%g0\;subx %%g0,-1,%0"
853 [(set_attr "type" "unary")
854 (set_attr "length" "2")])
857 [(set (match_operand:SI 0 "register_operand" "=r")
858 (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
860 (clobber (reg:CC 0))]
862 "subcc %%g0,%1,%%g0\;addx %%g0,-1,%0"
863 [(set_attr "type" "unary")
864 (set_attr "length" "2")])
867 [(set (match_operand:DI 0 "register_operand" "=r")
868 (eq:DI (match_operand:DI 1 "register_operand" "r")
870 (clobber (reg:CCX 0))]
872 "mov 0,%0\;movrz %1,1,%0"
873 [(set_attr "type" "unary")
874 (set_attr "length" "2")])
877 [(set (match_operand:DI 0 "register_operand" "=r")
878 (neg:DI (eq:DI (match_operand:DI 1 "register_operand" "r")
880 (clobber (reg:CCX 0))]
882 "mov 0,%0\;movrz %1,-1,%0"
883 [(set_attr "type" "unary")
884 (set_attr "length" "2")])
886 ;; We can also do (x + (i == 0)) and related, so put them in.
887 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
891 [(set (match_operand:SI 0 "register_operand" "=r")
892 (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
894 (match_operand:SI 2 "register_operand" "r")))
895 (clobber (reg:CC 0))]
897 "subcc %%g0,%1,%%g0\;addx %2,0,%0"
898 [(set_attr "length" "2")])
901 [(set (match_operand:SI 0 "register_operand" "=r")
902 (minus:SI (match_operand:SI 2 "register_operand" "r")
903 (ne:SI (match_operand:SI 1 "register_operand" "r")
905 (clobber (reg:CC 0))]
907 "subcc %%g0,%1,%%g0\;subx %2,0,%0"
908 [(set_attr "length" "2")])
911 [(set (match_operand:SI 0 "register_operand" "=r")
912 (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
914 (match_operand:SI 2 "register_operand" "r")))
915 (clobber (reg:CC 0))]
917 "subcc %%g0,%1,%%g0\;subx %2,-1,%0"
918 [(set_attr "length" "2")])
921 [(set (match_operand:SI 0 "register_operand" "=r")
922 (minus:SI (match_operand:SI 2 "register_operand" "r")
923 (eq:SI (match_operand:SI 1 "register_operand" "r")
925 (clobber (reg:CC 0))]
927 "subcc %%g0,%1,%%g0\;addx %2,-1,%0"
928 [(set_attr "length" "2")])
930 ;; We can also do GEU and LTU directly, but these operate after a compare.
931 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
935 [(set (match_operand:SI 0 "register_operand" "=r")
936 (ltu:SI (reg:CC 0) (const_int 0)))]
939 [(set_attr "type" "misc")])
942 [(set (match_operand:SI 0 "register_operand" "=r")
943 (neg:SI (ltu:SI (reg:CC 0) (const_int 0))))]
946 [(set_attr "type" "misc")])
948 ;; ??? Combine should canonicalize these next two to the same pattern.
950 [(set (match_operand:SI 0 "register_operand" "=r")
951 (minus:SI (neg:SI (ltu:SI (reg:CC 0) (const_int 0)))
952 (match_operand:SI 1 "arith_operand" "rI")))]
955 [(set_attr "type" "unary")])
958 [(set (match_operand:SI 0 "register_operand" "=r")
959 (neg:SI (plus:SI (ltu:SI (reg:CC 0) (const_int 0))
960 (match_operand:SI 1 "arith_operand" "rI"))))]
963 [(set_attr "type" "unary")])
966 [(set (match_operand:SI 0 "register_operand" "=r")
967 (geu:SI (reg:CC 0) (const_int 0)))]
970 [(set_attr "type" "misc")])
973 [(set (match_operand:SI 0 "register_operand" "=r")
974 (neg:SI (geu:SI (reg:CC 0) (const_int 0))))]
977 [(set_attr "type" "misc")])
979 ;; We can also do (x + ((unsigned) i >= 0)) and related, so put them in.
980 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
984 [(set (match_operand:SI 0 "register_operand" "=r")
985 (plus:SI (ltu:SI (reg:CC 0) (const_int 0))
986 (match_operand:SI 1 "arith_operand" "rI")))]
989 [(set_attr "type" "unary")])
992 [(set (match_operand:SI 0 "register_operand" "=r")
993 (plus:SI (ltu:SI (reg:CC 0) (const_int 0))
994 (plus:SI (match_operand:SI 1 "arith_operand" "%r")
995 (match_operand:SI 2 "arith_operand" "rI"))))]
1000 [(set (match_operand:SI 0 "register_operand" "=r")
1001 (minus:SI (match_operand:SI 1 "register_operand" "r")
1002 (ltu:SI (reg:CC 0) (const_int 0))))]
1005 [(set_attr "type" "unary")])
1007 ;; ??? Combine should canonicalize these next two to the same pattern.
1009 [(set (match_operand:SI 0 "register_operand" "=r")
1010 (minus:SI (minus:SI (match_operand:SI 1 "register_operand" "r")
1011 (match_operand:SI 2 "arith_operand" "rI"))
1012 (ltu:SI (reg:CC 0) (const_int 0))))]
1017 [(set (match_operand:SI 0 "register_operand" "=r")
1018 (minus:SI (match_operand:SI 1 "register_operand" "r")
1019 (plus:SI (ltu:SI (reg:CC 0) (const_int 0))
1020 (match_operand:SI 2 "arith_operand" "rI"))))]
1025 [(set (match_operand:SI 0 "register_operand" "=r")
1026 (plus:SI (geu:SI (reg:CC 0) (const_int 0))
1027 (match_operand:SI 1 "register_operand" "r")))]
1030 [(set_attr "type" "unary")])
1033 [(set (match_operand:SI 0 "register_operand" "=r")
1034 (minus:SI (match_operand:SI 1 "register_operand" "r")
1035 (geu:SI (reg:CC 0) (const_int 0))))]
1038 [(set_attr "type" "unary")])
1040 ;; Now we have the generic scc insns.
1041 ;; !v9: These will be done using a jump.
1042 ;; v9: Use conditional moves which are defined elsewhere.
1043 ;; We have to exclude the cases above, since we will not want combine to
1044 ;; turn something that does not require a jump into something that does.
1047 [(set (match_operand:SI 0 "register_operand" "=r")
1048 (match_operator:SI 1 "noov_compare_op" [(reg 0) (const_int 0)]))]
1050 "* return output_scc_insn (operands, insn); "
1051 [(set_attr "type" "multi")
1052 (set_attr "length" "3")])
1055 [(set (match_operand:DI 0 "register_operand" "=r")
1056 (match_operator:DI 1 "noov_compare_op" [(reg 0) (const_int 0)]))]
1058 "* return output_scc_insn (operands, insn); "
1059 [(set_attr "type" "multi")
1060 (set_attr "length" "3")])
1062 ;; These control RTL generation for conditional jump insns
1064 ;; The quad-word fp compare library routines all return nonzero to indicate
1065 ;; true, which is different from the equivalent libgcc routines, so we must
1066 ;; handle them specially here.
1068 (define_expand "beq"
1070 (if_then_else (eq (match_dup 1) (const_int 0))
1071 (label_ref (match_operand 0 "" ""))
1076 if (TARGET_V9 && sparc_compare_op1 == const0_rtx
1077 && GET_CODE (sparc_compare_op0) == REG
1078 && GET_MODE (sparc_compare_op0) == DImode)
1080 emit_v9_brxx_insn (EQ, sparc_compare_op0, operands[0]);
1083 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1085 emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, EQ);
1086 emit_jump_insn (gen_bne (operands[0]));
1089 operands[1] = gen_compare_reg (EQ, sparc_compare_op0, sparc_compare_op1);
1092 (define_expand "bne"
1094 (if_then_else (ne (match_dup 1) (const_int 0))
1095 (label_ref (match_operand 0 "" ""))
1100 if (TARGET_V9 && sparc_compare_op1 == const0_rtx
1101 && GET_CODE (sparc_compare_op0) == REG
1102 && GET_MODE (sparc_compare_op0) == DImode)
1104 emit_v9_brxx_insn (NE, sparc_compare_op0, operands[0]);
1107 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1109 emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, NE);
1110 emit_jump_insn (gen_bne (operands[0]));
1113 operands[1] = gen_compare_reg (NE, sparc_compare_op0, sparc_compare_op1);
1116 (define_expand "bgt"
1118 (if_then_else (gt (match_dup 1) (const_int 0))
1119 (label_ref (match_operand 0 "" ""))
1124 if (TARGET_V9 && sparc_compare_op1 == const0_rtx
1125 && GET_CODE (sparc_compare_op0) == REG
1126 && GET_MODE (sparc_compare_op0) == DImode)
1128 emit_v9_brxx_insn (GT, sparc_compare_op0, operands[0]);
1131 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1133 emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GT);
1134 emit_jump_insn (gen_bne (operands[0]));
1137 operands[1] = gen_compare_reg (GT, sparc_compare_op0, sparc_compare_op1);
1140 (define_expand "bgtu"
1142 (if_then_else (gtu (match_dup 1) (const_int 0))
1143 (label_ref (match_operand 0 "" ""))
1147 { operands[1] = gen_compare_reg (GTU, sparc_compare_op0, sparc_compare_op1);
1150 (define_expand "blt"
1152 (if_then_else (lt (match_dup 1) (const_int 0))
1153 (label_ref (match_operand 0 "" ""))
1158 if (TARGET_V9 && sparc_compare_op1 == const0_rtx
1159 && GET_CODE (sparc_compare_op0) == REG
1160 && GET_MODE (sparc_compare_op0) == DImode)
1162 emit_v9_brxx_insn (LT, sparc_compare_op0, operands[0]);
1165 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1167 emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LT);
1168 emit_jump_insn (gen_bne (operands[0]));
1171 operands[1] = gen_compare_reg (LT, sparc_compare_op0, sparc_compare_op1);
1174 (define_expand "bltu"
1176 (if_then_else (ltu (match_dup 1) (const_int 0))
1177 (label_ref (match_operand 0 "" ""))
1181 { operands[1] = gen_compare_reg (LTU, sparc_compare_op0, sparc_compare_op1);
1184 (define_expand "bge"
1186 (if_then_else (ge (match_dup 1) (const_int 0))
1187 (label_ref (match_operand 0 "" ""))
1192 if (TARGET_V9 && sparc_compare_op1 == const0_rtx
1193 && GET_CODE (sparc_compare_op0) == REG
1194 && GET_MODE (sparc_compare_op0) == DImode)
1196 emit_v9_brxx_insn (GE, sparc_compare_op0, operands[0]);
1199 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1201 emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GE);
1202 emit_jump_insn (gen_bne (operands[0]));
1205 operands[1] = gen_compare_reg (GE, sparc_compare_op0, sparc_compare_op1);
1208 (define_expand "bgeu"
1210 (if_then_else (geu (match_dup 1) (const_int 0))
1211 (label_ref (match_operand 0 "" ""))
1215 { operands[1] = gen_compare_reg (GEU, sparc_compare_op0, sparc_compare_op1);
1218 (define_expand "ble"
1220 (if_then_else (le (match_dup 1) (const_int 0))
1221 (label_ref (match_operand 0 "" ""))
1226 if (TARGET_V9 && sparc_compare_op1 == const0_rtx
1227 && GET_CODE (sparc_compare_op0) == REG
1228 && GET_MODE (sparc_compare_op0) == DImode)
1230 emit_v9_brxx_insn (LE, sparc_compare_op0, operands[0]);
1233 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1235 emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LE);
1236 emit_jump_insn (gen_bne (operands[0]));
1239 operands[1] = gen_compare_reg (LE, sparc_compare_op0, sparc_compare_op1);
1242 (define_expand "bleu"
1244 (if_then_else (leu (match_dup 1) (const_int 0))
1245 (label_ref (match_operand 0 "" ""))
1249 { operands[1] = gen_compare_reg (LEU, sparc_compare_op0, sparc_compare_op1);
1252 ;; Now match both normal and inverted jump.
1256 (if_then_else (match_operator 0 "noov_compare_op"
1257 [(reg 0) (const_int 0)])
1258 (label_ref (match_operand 1 "" ""))
1263 return output_cbranch (operands[0], 0, 1, 0,
1264 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1267 [(set_attr "type" "branch")])
1271 (if_then_else (match_operator 0 "noov_compare_op"
1272 [(reg 0) (const_int 0)])
1274 (label_ref (match_operand 1 "" ""))))]
1278 return output_cbranch (operands[0], 0, 1, 1,
1279 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1282 [(set_attr "type" "branch")])
1286 (if_then_else (match_operator 0 "comparison_operator"
1287 [(match_operand:CCFP 1 "ccfp_reg_operand" "c")
1289 (label_ref (match_operand 2 "" ""))
1294 return output_cbranch (operands[0], operands[1], 2, 0,
1295 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1298 [(set_attr "type" "branch")])
1302 (if_then_else (match_operator 0 "comparison_operator"
1303 [(match_operand:CCFP 1 "ccfp_reg_operand" "c")
1306 (label_ref (match_operand 2 "" ""))))]
1310 return output_cbranch (operands[0], operands[1], 2, 1,
1311 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1314 [(set_attr "type" "branch")])
1318 (if_then_else (match_operator 0 "comparison_operator"
1319 [(match_operand:CCFPE 1 "ccfp_reg_operand" "c")
1321 (label_ref (match_operand 2 "" ""))
1326 return output_cbranch (operands[0], operands[1], 2, 0,
1327 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1330 [(set_attr "type" "branch")])
1334 (if_then_else (match_operator 0 "comparison_operator"
1335 [(match_operand:CCFPE 1 "ccfp_reg_operand" "c")
1338 (label_ref (match_operand 2 "" ""))))]
1342 return output_cbranch (operands[0], operands[1], 2, 1,
1343 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1346 [(set_attr "type" "branch")])
1348 ;; Sparc V9-specific jump insns. None of these are guaranteed to be
1349 ;; in the architecture.
1351 ;; There are no 32 bit brreg insns.
1355 (if_then_else (match_operator 0 "v9_regcmp_op"
1356 [(match_operand:DI 1 "register_operand" "r")
1358 (label_ref (match_operand 2 "" ""))
1363 return output_v9branch (operands[0], 1, 2, 0,
1364 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1367 [(set_attr "type" "branch")])
1371 (if_then_else (match_operator 0 "v9_regcmp_op"
1372 [(match_operand:DI 1 "register_operand" "r")
1375 (label_ref (match_operand 2 "" ""))))]
1379 return output_v9branch (operands[0], 1, 2, 1,
1380 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1383 [(set_attr "type" "branch")])
1385 ;; Esoteric move insns (lo_sum, high, pic).
1388 [(set (match_operand:SI 0 "register_operand" "=r")
1389 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1390 (match_operand:SI 2 "immediate_operand" "in")))]
1392 ;; V9 needs "add" because of the code models. We still use "or" for v8
1393 ;; so we can compare the old compiler with the new.
1394 "* return TARGET_V9 ? \"add %1,%%lo(%a2),%0\" : \"or %1,%%lo(%a2),%0\";"
1395 ;; Need to set length for this arith insn because operand2
1396 ;; is not an "arith_operand".
1397 [(set_attr "length" "1")])
1399 ;; For PIC, symbol_refs are put inside unspec so that the optimizer will not
1400 ;; confuse them with real addresses.
1402 [(set (match_operand:SI 0 "register_operand" "=r")
1403 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1404 (unspec:SI [(match_operand:SI 2 "immediate_operand" "in")] 0)))]
1406 ;; V9 needs "add" because of the code models. We still use "or" for v8
1407 ;; so we can compare the old compiler with the new.
1408 "* return TARGET_V9 ? \"add %1,%%lo(%a2),%0\" : \"or %1,%%lo(%a2),%0\";"
1409 ;; Need to set length for this arith insn because operand2
1410 ;; is not an "arith_operand".
1411 [(set_attr "length" "1")])
1413 ;; For PIC, symbol_refs are put inside unspec so that the optimizer will not
1414 ;; confuse them with real addresses.
1416 [(set (match_operand:SI 0 "register_operand" "=r")
1417 (high:SI (unspec:SI [(match_operand 1 "" "")] 0)))]
1419 "sethi %%hi(%a1),%0"
1420 [(set_attr "type" "move")
1421 (set_attr "length" "1")])
1424 [(set (match_operand:SI 0 "register_operand" "=r")
1425 (high:SI (match_operand 1 "" "")))]
1427 "sethi %%hi(%a1),%0"
1428 [(set_attr "type" "move")
1429 (set_attr "length" "1")])
1432 [(set (match_operand:HI 0 "register_operand" "=r")
1433 (high:HI (match_operand 1 "" "")))]
1435 "sethi %%hi(%a1),%0"
1436 [(set_attr "type" "move")
1437 (set_attr "length" "1")])
1439 ;; Special pic pattern, for loading the address of a label into a register.
1440 ;; It clobbers o7 because the call puts the return address (i.e. pc value)
1444 [(set (match_operand:SI 0 "register_operand" "=r")
1445 (match_operand:SI 1 "move_pic_label" "i"))
1446 (set (reg:SI 15) (pc))]
1448 "\\n1:\;call 2f\;sethi %%hi(%l1-1b),%0\\n2:\\tor %0,%%lo(%l1-1b),%0\;add %0,%%o7,%0"
1449 [(set_attr "type" "multi")
1450 (set_attr "length" "4")])
1452 ;; v9 special pic pattern, for loading the address of a label into a register.
1455 [(set (match_operand:DI 0 "register_operand" "=r")
1456 (match_operand:DI 1 "move_pic_label" "i"))
1457 (set (reg:DI 15) (pc))]
1459 "\\n1:\;call 2f\;sethi %%hi(%l1-1b),%0\\n2:\\tor %0,%%lo(%l1-1b),%0\;add %0,%%o7,%0"
1460 [(set_attr "type" "multi")
1461 (set_attr "length" "4")])
1464 [(set (match_operand:DI 0 "register_operand" "=r")
1465 (lo_sum:DI (match_operand:DI 1 "register_operand" "0")
1466 (match_operand:DI 2 "immediate_operand" "in")))]
1470 /* Don't output a 64 bit constant, since we can't trust the assembler to
1471 handle it correctly. */
1472 if (GET_CODE (operands[2]) == CONST_DOUBLE)
1473 operands[2] = gen_rtx (CONST_INT, VOIDmode, CONST_DOUBLE_LOW (operands[2]));
1474 return \"or %R1,%%lo(%a2),%R0\";
1476 ;; Need to set length for this arith insn because operand2
1477 ;; is not an "arith_operand".
1478 [(set_attr "length" "1")])
1480 ;; ??? Gas does not handle %lo(DI), so we use the same code for ! TARGET_V9.
1481 ;; ??? The previous comment is obsolete.
1482 ;; ??? Optimizer does not handle "or %o1,%lo(0),%o1". How about add?
1485 [(set (match_operand:DI 0 "register_operand" "=r")
1486 (lo_sum:DI (match_operand:DI 1 "register_operand" "0")
1487 (match_operand:DI 2 "immediate_operand" "in")))]
1491 /* Don't output a 64 bit constant, since we can't trust the assembler to
1492 handle it correctly. */
1493 if (GET_CODE (operands[2]) == CONST_DOUBLE)
1494 operands[2] = gen_rtx (CONST_INT, VOIDmode, CONST_DOUBLE_LOW (operands[2]));
1495 /* Note that we use add here. This is important because Medium/Anywhere
1496 code model support depends on it. */
1497 return \"add %1,%%lo(%a2),%0\";
1499 ;; Need to set length for this arith insn because operand2
1500 ;; is not an "arith_operand".
1501 [(set_attr "length" "1")])
1504 [(set (match_operand:DI 0 "register_operand" "=r")
1505 (high:DI (match_operand 1 "" "")))]
1506 "! TARGET_V9 && check_pic (1)"
1509 rtx op0 = operands[0];
1510 rtx op1 = operands[1];
1512 if (GET_CODE (op1) == CONST_INT)
1514 operands[0] = operand_subword (op0, 1, 0, DImode);
1515 output_asm_insn (\"sethi %%hi(%a1),%0\", operands);
1517 operands[0] = operand_subword (op0, 0, 0, DImode);
1518 if (INTVAL (op1) < 0)
1519 return \"mov -1,%0\";
1521 return \"mov 0,%0\";
1523 else if (GET_CODE (op1) == CONST_DOUBLE)
1525 operands[0] = operand_subword (op0, 1, 0, DImode);
1526 operands[1] = gen_rtx (CONST_INT, VOIDmode, CONST_DOUBLE_LOW (op1));
1527 output_asm_insn (\"sethi %%hi(%a1),%0\", operands);
1529 operands[0] = operand_subword (op0, 0, 0, DImode);
1530 operands[1] = gen_rtx (CONST_INT, VOIDmode, CONST_DOUBLE_HIGH (op1));
1531 return singlemove_string (operands);
1537 [(set_attr "type" "move")
1538 (set_attr "length" "2")])
1540 ;;; ??? This pattern originally clobbered a scratch register. However, this
1541 ;;; is illegal, the movdi pattern may not use a temp register because it
1542 ;;; may be called from reload to reload a DImode value. In that case, we
1543 ;;; end up with a scratch register that never gets allocated. To avoid this,
1544 ;;; we use global register 1 which is never otherwise used by gcc as a temp.
1545 ;;; The correct solution here might be to force DImode constants to memory,
1546 ;;; e.g. by using a toc like the romp and rs6000 ports do for addresses, reg
1547 ;;; 1 will then no longer need to be considered a fixed reg.
1549 ;;; Gas doesn't have any 64 bit constant support, so don't use %uhi and %ulo
1550 ;;; on constants. Symbols have to be handled by the linker, so we must use
1551 ;;; %uhi and %ulo for them, but gas will handle these correctly.
1552 ;;; ??? This comment is obsolete, gas handles them now.
1555 [(set (match_operand:DI 0 "register_operand" "=r")
1556 (high:DI (match_operand 1 "const_double_operand" "")))
1557 (clobber (reg:DI 1))]
1558 "TARGET_V9 && check_pic (1)"
1563 split_double (operands[1], &high, &low);
1565 if (high == const0_rtx)
1568 output_asm_insn (\"sethi %%hi(%a1),%0\", operands);
1573 output_asm_insn (singlemove_string (operands), operands);
1576 output_asm_insn (\"sllx %0,32,%0\", operands);
1577 if (low != const0_rtx)
1578 output_asm_insn (\"sethi %%hi(%a1),%%g1; or %0,%%g1,%0\", operands);
1581 [(set_attr "type" "move")
1582 (set_attr "length" "5")])
1584 ;; Most of the required support for the various code models is here.
1585 ;; We can do this because sparcs need the high insn to load the address. We
1586 ;; just need to get high to do the right thing for each code model. Then each
1587 ;; uses the same "%X+%lo(...)" in the load/store insn.
1589 ;; When TARGET_MEDLOW, assume that the upper 32 bits of symbol addresses are
1591 ;; When TARGET_MEDANY, the upper 32 bits of function addresses are 0.
1592 ;; The data segment has a maximum size of 32 bits, but may be located anywhere.
1593 ;; MEDANY_BASE_REG contains the start address, currently %g4.
1594 ;; When TARGET_FULLANY, symbolic addresses are 64 bits.
1597 [(set (match_operand:DI 0 "register_operand" "=r")
1598 (high:DI (match_operand 1 "" "")))
1599 ;; ??? Why the clobber?
1600 (clobber (reg:DI 1))]
1601 "TARGET_MEDLOW && check_pic (1)"
1602 "sethi %%hi(%a1),%0"
1603 [(set_attr "type" "move")
1604 (set_attr "length" "1")])
1606 ;; WARNING: %0 gets %hi(%1)+%g4.
1607 ;; You cannot OR in %lo(%1), it must be added in.
1610 [(set (match_operand:DI 0 "register_operand" "=r")
1611 (high:DI (match_operand 1 "data_segment_operand" "")))
1612 ;; ??? Why the clobber?
1613 (clobber (reg:DI 1))]
1614 "TARGET_MEDANY && check_pic (1)"
1615 "sethi %%hi(%a1),%0; add %0,%%g4,%0"
1616 [(set_attr "type" "move")
1617 (set_attr "length" "2")])
1620 [(set (match_operand:DI 0 "register_operand" "=r")
1621 (high:DI (match_operand 1 "text_segment_operand" "")))
1622 ;; ??? Why the clobber?
1623 (clobber (reg:DI 1))]
1624 "TARGET_MEDANY && check_pic (1)"
1625 "sethi %%hi(%a1),%0"
1626 [(set_attr "type" "move")
1627 (set_attr "length" "1")])
1630 [(set (match_operand:DI 0 "register_operand" "=r")
1631 (high:DI (match_operand 1 "" "")))
1632 (clobber (reg:DI 1))]
1633 "TARGET_FULLANY && check_pic (1)"
1634 "sethi %%uhi(%a1),%%g1; or %%g1,%%ulo(%a1),%%g1; sllx %%g1,32,%%g1; sethi %%hi(%a1),%0; or %0,%%g1,%0"
1635 [(set_attr "type" "move")
1636 (set_attr "length" "5")])
1638 ;; Move instructions
1640 (define_expand "movqi"
1641 [(set (match_operand:QI 0 "general_operand" "")
1642 (match_operand:QI 1 "general_operand" ""))]
1646 if (emit_move_sequence (operands, QImode))
1651 [(set (match_operand:QI 0 "reg_or_nonsymb_mem_operand" "=r,r,r,Q")
1652 (match_operand:QI 1 "move_operand" "rI,K,Q,rJ"))]
1653 "register_operand (operands[0], QImode)
1654 || register_operand (operands[1], QImode)
1655 || operands[1] == const0_rtx"
1661 [(set_attr "type" "move,move,load,store")
1662 (set_attr "length" "*,1,*,1")])
1665 [(set (match_operand:QI 0 "register_operand" "=r")
1666 (subreg:QI (lo_sum:SI (match_operand:QI 1 "register_operand" "r")
1667 (match_operand 2 "immediate_operand" "in")) 0))]
1669 "or %1,%%lo(%a2),%0"
1670 [(set_attr "length" "1")])
1673 [(set (mem:QI (match_operand:SI 0 "symbolic_operand" ""))
1674 (match_operand:QI 1 "reg_or_0_operand" "rJ"))
1675 (clobber (match_scratch:SI 2 "=&r"))]
1676 "(reload_completed || reload_in_progress) && ! TARGET_PTR64"
1677 "sethi %%hi(%a0),%2\;stb %r1,[%2+%%lo(%a0)]"
1678 [(set_attr "type" "store")
1679 (set_attr "length" "2")])
1681 (define_expand "movhi"
1682 [(set (match_operand:HI 0 "general_operand" "")
1683 (match_operand:HI 1 "general_operand" ""))]
1687 if (emit_move_sequence (operands, HImode))
1692 [(set (match_operand:HI 0 "reg_or_nonsymb_mem_operand" "=r,r,r,Q")
1693 (match_operand:HI 1 "move_operand" "rI,K,Q,rJ"))]
1694 "register_operand (operands[0], HImode)
1695 || register_operand (operands[1], HImode)
1696 || operands[1] == const0_rtx"
1702 [(set_attr "type" "move,move,load,store")
1703 (set_attr "length" "*,1,*,1")])
1706 [(set (match_operand:HI 0 "register_operand" "=r")
1707 (lo_sum:HI (match_operand:HI 1 "register_operand" "r")
1708 (match_operand 2 "immediate_operand" "in")))]
1710 "or %1,%%lo(%a2),%0"
1711 [(set_attr "length" "1")])
1714 [(set (mem:HI (match_operand:SI 0 "symbolic_operand" ""))
1715 (match_operand:HI 1 "reg_or_0_operand" "rJ"))
1716 (clobber (match_scratch:SI 2 "=&r"))]
1717 "(reload_completed || reload_in_progress) && ! TARGET_PTR64"
1718 "sethi %%hi(%a0),%2\;sth %r1,[%2+%%lo(%a0)]"
1719 [(set_attr "type" "store")
1720 (set_attr "length" "2")])
1722 (define_expand "movsi"
1723 [(set (match_operand:SI 0 "general_operand" "")
1724 (match_operand:SI 1 "general_operand" ""))]
1728 if (emit_move_sequence (operands, SImode))
1732 ;; We must support both 'r' and 'f' registers here, because combine may
1733 ;; convert SFmode hard registers to SImode hard registers when simplifying
1736 ;; We cannot combine the similar 'r' and 'f' constraints, because it causes
1737 ;; problems with register allocation. Reload might try to put an integer
1738 ;; in an fp register, or an fp number is an integer register.
1741 [(set (match_operand:SI 0 "reg_or_nonsymb_mem_operand" "=r,f,r,r,f,Q,Q")
1742 (match_operand:SI 1 "move_operand" "rI,!f,K,Q,!Q,rJ,!f"))]
1743 "register_operand (operands[0], SImode)
1744 || register_operand (operands[1], SImode)
1745 || operands[1] == const0_rtx"
1754 [(set_attr "type" "move,fp,move,load,load,store,store")
1755 (set_attr "length" "*,*,1,*,*,*,*")])
1758 [(set (mem:SI (match_operand:SI 0 "symbolic_operand" ""))
1759 (match_operand:SI 1 "reg_or_0_operand" "rJ"))
1760 (clobber (match_scratch:SI 2 "=&r"))]
1761 "(reload_completed || reload_in_progress) && ! TARGET_PTR64"
1762 "sethi %%hi(%a0),%2\;st %r1,[%2+%%lo(%a0)]"
1763 [(set_attr "type" "store")
1764 (set_attr "length" "2")])
1766 (define_expand "movdi"
1767 [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand" "")
1768 (match_operand:DI 1 "general_operand" ""))]
1772 if (emit_move_sequence (operands, DImode))
1777 [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand" "=r,T,U,Q,r,r,?f,?f,?Q")
1778 (match_operand:DI 1 "general_operand" "r,U,T,r,Q,i,f,Q,f"))]
1780 && (register_operand (operands[0], DImode)
1781 || register_operand (operands[1], DImode)
1782 || operands[1] == const0_rtx)"
1785 if (FP_REG_P (operands[0]) || FP_REG_P (operands[1]))
1786 return output_fp_move_double (operands);
1787 return output_move_double (operands);
1789 [(set_attr "type" "move,store,load,store,load,multi,fp,fpload,fpstore")
1790 (set_attr "length" "2,1,1,3,3,3,2,3,3")])
1792 ;;; ??? The trick used below can be extended to load any negative 32 bit
1793 ;;; constant in two instructions. Currently the compiler will use HIGH/LO_SUM
1794 ;;; for anything not matching the HIK constraints, which results in 5
1795 ;;; instructions. Positive 32 bit constants can be loaded in the obvious way
1796 ;;; with sethi/ori. To extend the trick, in the xor instruction, use
1797 ;;; xor %o0, ((op1 & 0x3ff) | -0x400), %o0
1798 ;;; This needs the original value of operands[1], not the inverted value.
1801 [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand" "=r,r,r,Q,?f,?f,?Q")
1802 (match_operand:DI 1 "move_operand" "rI,K,Q,rJ,f,Q,f"))]
1804 && (register_operand (operands[0], DImode)
1805 || register_operand (operands[1], DImode)
1806 || operands[1] == const0_rtx)"
1809 switch (which_alternative)
1812 return \"mov %1,%0\";
1814 /* Sethi does not sign extend, so we must use a little trickery
1815 to use it for negative numbers. Invert the constant before
1816 loading it in, then use a xor immediate to invert the loaded bits
1817 (along with the upper 32 bits) to the desired constant. This
1818 works because the sethi and immediate fields overlap. */
1820 if ((INTVAL (operands[1]) & 0x80000000) == 0)
1821 return \"sethi %%hi(%a1),%0\";
1824 operands[1] = gen_rtx (CONST_INT, VOIDmode,
1825 ~ INTVAL (operands[1]));
1826 output_asm_insn (\"sethi %%hi(%a1),%0\", operands);
1827 /* The low 10 bits are already zero, but invert the rest.
1828 Assemblers don't accept 0x1c00, so use -0x400 instead. */
1829 return \"xor %0,-0x400,%0\";
1832 return \"ldx %1,%0\";
1834 return \"stx %r1,%0\";
1836 return \"mov %1,%0\";
1838 return \"ldd %1,%0\";
1840 return \"std %1,%0\";
1843 [(set_attr "type" "move,move,load,store,fp,fpload,fpstore")
1844 (set_attr "length" "1,2,1,1,1,1,1")])
1846 ;; ??? There's no symbolic (set (mem:DI ...) ...).
1847 ;; Experimentation with v9 suggested one isn't needed.
1849 ;; Block move insns.
1851 ;; ??? We get better code without it. See output_block_move in sparc.c.
1853 ;; The definition of this insn does not really explain what it does,
1854 ;; but it should suffice
1855 ;; that anything generated as this insn will be recognized as one
1856 ;; and that it will not successfully combine with anything.
1857 ;(define_expand "movstrsi"
1858 ; [(parallel [(set (mem:BLK (match_operand:BLK 0 "general_operand" ""))
1859 ; (mem:BLK (match_operand:BLK 1 "general_operand" "")))
1860 ; (use (match_operand:SI 2 "nonmemory_operand" ""))
1861 ; (use (match_operand:SI 3 "immediate_operand" ""))
1862 ; (clobber (match_dup 0))
1863 ; (clobber (match_dup 1))
1864 ; (clobber (match_scratch:SI 4 ""))
1865 ; (clobber (reg:SI 0))
1866 ; (clobber (reg:SI 1))])]
1870 ; /* If the size isn't known, don't emit inline code. output_block_move
1871 ; would output code that's much slower than the library function.
1872 ; Also don't output code for large blocks. */
1873 ; if (GET_CODE (operands[2]) != CONST_INT
1874 ; || GET_CODE (operands[3]) != CONST_INT
1875 ; || INTVAL (operands[2]) / INTVAL (operands[3]) > 16)
1878 ; operands[0] = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
1879 ; operands[1] = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
1880 ; operands[2] = force_not_mem (operands[2]);
1884 ; [(set (mem:BLK (match_operand:SI 0 "register_operand" "+r"))
1885 ; (mem:BLK (match_operand:SI 1 "register_operand" "+r")))
1886 ; (use (match_operand:SI 2 "nonmemory_operand" "rn"))
1887 ; (use (match_operand:SI 3 "immediate_operand" "i"))
1888 ; (clobber (match_dup 0))
1889 ; (clobber (match_dup 1))
1890 ; (clobber (match_scratch:SI 4 "=&r"))
1891 ; (clobber (reg:SI 0))
1892 ; (clobber (reg:SI 1))]
1894 ; "* return output_block_move (operands);"
1895 ; [(set_attr "type" "multi")
1896 ; (set_attr "length" "6")])
1898 ;; Floating point move insns
1900 ;; This pattern forces (set (reg:SF ...) (const_double ...))
1901 ;; to be reloaded by putting the constant into memory.
1902 ;; It must come before the more general movsf pattern.
1904 [(set (match_operand:SF 0 "general_operand" "=?r,f,m")
1905 (match_operand:SF 1 "" "?E,m,G"))]
1906 "TARGET_FPU && GET_CODE (operands[1]) == CONST_DOUBLE"
1909 switch (which_alternative)
1912 return singlemove_string (operands);
1914 return \"ld %1,%0\";
1916 return \"st %%g0,%0\";
1919 [(set_attr "type" "load,fpload,store")
1920 (set_attr "length" "2,1,1")])
1922 (define_expand "movsf"
1923 [(set (match_operand:SF 0 "general_operand" "")
1924 (match_operand:SF 1 "general_operand" ""))]
1928 if (emit_move_sequence (operands, SFmode))
1933 [(set (match_operand:SF 0 "reg_or_nonsymb_mem_operand" "=f,r,f,r,Q,Q")
1934 (match_operand:SF 1 "reg_or_nonsymb_mem_operand" "f,r,Q,Q,f,r"))]
1936 && (register_operand (operands[0], SFmode)
1937 || register_operand (operands[1], SFmode))"
1945 [(set_attr "type" "fp,move,fpload,load,fpstore,store")])
1947 ;; Exactly the same as above, except that all `f' cases are deleted.
1948 ;; This is necessary to prevent reload from ever trying to use a `f' reg
1952 [(set (match_operand:SF 0 "reg_or_nonsymb_mem_operand" "=r,r,Q")
1953 (match_operand:SF 1 "reg_or_nonsymb_mem_operand" "r,Q,r"))]
1955 && (register_operand (operands[0], SFmode)
1956 || register_operand (operands[1], SFmode))"
1961 [(set_attr "type" "move,load,store")])
1964 [(set (mem:SF (match_operand:SI 0 "symbolic_operand" "i"))
1965 (match_operand:SF 1 "reg_or_0_operand" "rfG"))
1966 (clobber (match_scratch:SI 2 "=&r"))]
1967 "(reload_completed || reload_in_progress) && ! TARGET_PTR64"
1968 "sethi %%hi(%a0),%2\;st %r1,[%2+%%lo(%a0)]"
1969 [(set_attr "type" "store")
1970 (set_attr "length" "2")])
1972 ;; This pattern forces (set (reg:DF ...) (const_double ...))
1973 ;; to be reloaded by putting the constant into memory.
1974 ;; It must come before the more general movdf pattern.
1977 [(set (match_operand:DF 0 "general_operand" "=?r,e,o")
1978 (match_operand:DF 1 "" "?E,m,G"))]
1979 "TARGET_FPU && GET_CODE (operands[1]) == CONST_DOUBLE"
1982 switch (which_alternative)
1985 return output_move_double (operands);
1987 return output_fp_move_double (operands);
1991 return \"stx %%g0,%0\";
1995 operands[1] = adj_offsettable_operand (operands[0], 4);
1996 return \"st %%g0,%0\;st %%g0,%1\";
2000 [(set_attr "type" "load,fpload,store")
2001 (set_attr "length" "3,3,3")])
2003 (define_expand "movdf"
2004 [(set (match_operand:DF 0 "general_operand" "")
2005 (match_operand:DF 1 "general_operand" ""))]
2009 if (emit_move_sequence (operands, DFmode))
2014 [(set (match_operand:DF 0 "reg_or_nonsymb_mem_operand" "=T,U,e,r,Q,Q,e,r")
2015 (match_operand:DF 1 "reg_or_nonsymb_mem_operand" "U,T,e,r,e,r,Q,Q"))]
2017 && (register_operand (operands[0], DFmode)
2018 || register_operand (operands[1], DFmode))"
2021 if (FP_REG_P (operands[0]) || FP_REG_P (operands[1]))
2022 return output_fp_move_double (operands);
2023 return output_move_double (operands);
2025 [(set_attr "type" "fpstore,fpload,fp,move,fpstore,store,fpload,load")
2026 (set_attr "length" "1,1,2,2,3,3,3,3")])
2028 ;; Exactly the same as above, except that all `e' cases are deleted.
2029 ;; This is necessary to prevent reload from ever trying to use a `e' reg
2033 [(set (match_operand:DF 0 "reg_or_nonsymb_mem_operand" "=T,U,r,Q,&r")
2034 (match_operand:DF 1 "reg_or_nonsymb_mem_operand" "U,T,r,r,Q"))]
2036 && (register_operand (operands[0], DFmode)
2037 || register_operand (operands[1], DFmode))"
2038 "* return output_move_double (operands);"
2039 [(set_attr "type" "store,load,move,store,load")
2040 (set_attr "length" "1,1,2,3,3")])
2042 ;; ??? Do we need a v9 version of this?
2044 [(set (match_operand:DF 0 "register_operand" "")
2045 (match_operand:DF 1 "register_operand" ""))]
2046 "! TARGET_V9 && reload_completed"
2047 [(set (match_dup 2) (match_dup 3))
2048 (set (match_dup 4) (match_dup 5))]
2050 { operands[2] = operand_subword (operands[0], 0, 0, DFmode);
2051 operands[3] = operand_subword (operands[1], 0, 0, DFmode);
2052 operands[4] = operand_subword (operands[0], 1, 0, DFmode);
2053 operands[5] = operand_subword (operands[1], 1, 0, DFmode); }")
2056 [(set (mem:DF (match_operand:SI 0 "symbolic_operand" "i,i"))
2057 (match_operand:DF 1 "reg_or_0_operand" "re,G"))
2058 (clobber (match_scratch:SI 2 "=&r,&r"))]
2059 "(reload_completed || reload_in_progress) && ! TARGET_PTR64"
2062 output_asm_insn (\"sethi %%hi(%a0),%2\", operands);
2063 if (which_alternative == 0)
2064 return \"std %1,[%2+%%lo(%a0)]\";
2066 return \"st %%g0,[%2+%%lo(%a0)]\;st %%g0,[%2+%%lo(%a0+4)]\";
2068 [(set_attr "type" "store")
2069 (set_attr "length" "3")])
2071 ;; This pattern forces (set (reg:TF ...) (const_double ...))
2072 ;; to be reloaded by putting the constant into memory.
2073 ;; It must come before the more general movtf pattern.
2075 [(set (match_operand:TF 0 "general_operand" "=?r,e,o")
2076 (match_operand:TF 1 "" "?E,m,G"))]
2077 "TARGET_FPU && GET_CODE (operands[1]) == CONST_DOUBLE"
2080 switch (which_alternative)
2083 return output_move_quad (operands);
2085 return output_fp_move_quad (operands);
2089 operands[1] = adj_offsettable_operand (operands[0], 8);
2090 return \"stx %%g0,%0\;stx %%g0,%1\";
2094 /* ??? Do we run off the end of the array here? */
2095 operands[1] = adj_offsettable_operand (operands[0], 4);
2096 operands[2] = adj_offsettable_operand (operands[0], 8);
2097 operands[3] = adj_offsettable_operand (operands[0], 12);
2098 return \"st %%g0,%0\;st %%g0,%1\;st %%g0,%2\;st %%g0,%3\";
2102 [(set_attr "type" "load,fpload,store")
2103 (set_attr "length" "5,5,5")])
2105 (define_expand "movtf"
2106 [(set (match_operand:TF 0 "general_operand" "")
2107 (match_operand:TF 1 "general_operand" ""))]
2111 if (emit_move_sequence (operands, TFmode))
2116 [(set (match_operand:TF 0 "reg_or_nonsymb_mem_operand" "=e,r,Q,Q,e,&r")
2117 (match_operand:TF 1 "reg_or_nonsymb_mem_operand" "e,r,e,r,Q,Q"))]
2119 && (register_operand (operands[0], TFmode)
2120 || register_operand (operands[1], TFmode))"
2123 if (FP_REG_P (operands[0]) || FP_REG_P (operands[1]))
2124 return output_fp_move_quad (operands);
2125 return output_move_quad (operands);
2127 [(set_attr "type" "fp,move,fpstore,store,fpload,load")
2128 (set_attr "length" "4,4,5,5,5,5")])
2130 ;; Exactly the same as above, except that all `e' cases are deleted.
2131 ;; This is necessary to prevent reload from ever trying to use a `e' reg
2135 [(set (match_operand:TF 0 "reg_or_nonsymb_mem_operand" "=r,Q,&r")
2136 (match_operand:TF 1 "reg_or_nonsymb_mem_operand" "r,r,Q"))]
2138 && (register_operand (operands[0], TFmode)
2139 || register_operand (operands[1], TFmode))"
2142 if (FP_REG_P (operands[0]) || FP_REG_P (operands[1]))
2143 return output_fp_move_quad (operands);
2144 return output_move_quad (operands);
2146 [(set_attr "type" "move,store,load")
2147 (set_attr "length" "4,5,5")])
2150 [(set (mem:TF (match_operand:SI 0 "symbolic_operand" "i,i"))
2151 (match_operand:TF 1 "reg_or_0_operand" "re,G"))
2152 (clobber (match_scratch:SI 2 "=&r,&r"))]
2153 "(reload_completed || reload_in_progress) && ! TARGET_PTR64"
2156 output_asm_insn (\"sethi %%hi(%a0),%2\", operands);
2157 if (which_alternative == 0)
2158 return \"std %1,[%2+%%lo(%a0)]\;std %S1,[%2+%%lo(%a0+8)]\";
2160 return \"st %%g0,[%2+%%lo(%a0)]\;st %%g0,[%2+%%lo(%a0+4)]\; st %%g0,[%2+%%lo(%a0+8)]\;st %%g0,[%2+%%lo(%a0+12)]\";
2162 [(set_attr "type" "store")
2163 (set_attr "length" "5")])
2165 ;; Sparc V9 conditional move instructions.
2167 ; ??? There is not actually a 32 bit version of this instruction.
2169 [(set (match_operand:SI 0 "register_operand" "=r")
2170 (if_then_else (match_operator 1 "comparison_operator"
2171 [(reg:CC 0) (const_int 0)])
2172 (match_operand:SI 2 "arith11_operand" "ri")
2173 (match_operand:SI 3 "register_operand" "0")))]
2175 "mov%C1 %%icc,%2,%0"
2176 [(set_attr "type" "cmove")])
2179 [(set (match_operand:DI 0 "register_operand" "=r")
2180 (if_then_else (match_operator 1 "comparison_operator"
2181 [(reg:CC 0) (const_int 0)])
2182 (match_operand:DI 2 "arith11_double_operand" "rHI")
2183 (match_operand:DI 3 "register_operand" "0")))]
2185 "mov%C1 %%icc,%2,%0"
2186 [(set_attr "type" "cmove")])
2188 ;; ??? There is not actually a 32 bit version of this instruction.
2190 [(set (match_operand:SI 0 "register_operand" "=r")
2191 (if_then_else (match_operator 1 "comparison_operator"
2192 [(reg:CCX 0) (const_int 0)])
2193 (match_operand:SI 2 "arith11_operand" "ri")
2194 (match_operand:SI 3 "register_operand" "0")))]
2196 "mov%C1 %%xcc,%2,%0"
2197 [(set_attr "type" "cmove")])
2200 [(set (match_operand:DI 0 "register_operand" "=r")
2201 (if_then_else (match_operator 1 "comparison_operator"
2202 [(reg:CCX 0) (const_int 0)])
2203 (match_operand:DI 2 "arith11_double_operand" "rHI")
2204 (match_operand:DI 3 "register_operand" "0")))]
2206 "mov%C1 %%xcc,%2,%0"
2207 [(set_attr "type" "cmove")])
2209 ;; ??? There is not actually a 32 bit version of this instruction.
2211 [(set (match_operand:SI 0 "register_operand" "=r")
2212 (if_then_else (match_operator 1 "comparison_operator"
2213 [(match_operand:CCFP 2 "ccfp_reg_operand" "c")
2215 (match_operand:SI 3 "arith11_operand" "ri")
2216 (match_operand:SI 4 "register_operand" "0")))]
2219 [(set_attr "type" "cmove")])
2221 ;; ??? There is not actually a 32 bit version of this instruction.
2223 [(set (match_operand:SI 0 "register_operand" "=r")
2224 (if_then_else (match_operator 1 "comparison_operator"
2225 [(match_operand:CCFPE 2 "ccfp_reg_operand" "c")
2227 (match_operand:SI 3 "arith11_operand" "ri")
2228 (match_operand:SI 4 "register_operand" "0")))]
2231 [(set_attr "type" "cmove")])
2234 [(set (match_operand:DI 0 "register_operand" "=r")
2235 (if_then_else (match_operator 1 "comparison_operator"
2236 [(match_operand:CCFP 2 "ccfp_reg_operand" "c")
2238 (match_operand:DI 3 "arith11_double_operand" "rHI")
2239 (match_operand:DI 4 "register_operand" "0")))]
2242 [(set_attr "type" "cmove")])
2245 [(set (match_operand:DI 0 "register_operand" "=r")
2246 (if_then_else (match_operator 1 "comparison_operator"
2247 [(match_operand:CCFPE 2 "ccfp_reg_operand" "c")
2249 (match_operand:DI 3 "arith11_double_operand" "rHI")
2250 (match_operand:DI 4 "register_operand" "0")))]
2253 [(set_attr "type" "cmove")])
2255 ;; ??? There is not actually a 32 bit version of this instruction.
2257 [(set (match_operand:SI 0 "register_operand" "=r")
2258 (if_then_else (match_operator 1 "v9_regcmp_op"
2259 [(match_operand:DI 2 "register_operand" "r")
2261 (match_operand:SI 3 "arith10_operand" "ri")
2262 (match_operand:SI 4 "register_operand" "0")))]
2265 [(set_attr "type" "cmove")])
2268 [(set (match_operand:DI 0 "register_operand" "=r")
2269 (if_then_else (match_operator 1 "v9_regcmp_op"
2270 [(match_operand:DI 2 "register_operand" "r")
2272 (match_operand:DI 3 "arith10_double_operand" "ri")
2273 (match_operand:DI 4 "register_operand" "0")))]
2276 [(set_attr "type" "cmove")])
2279 [(set (match_operand:SF 0 "register_operand" "=f")
2280 (if_then_else (match_operator 1 "v9_regcmp_op"
2281 [(match_operand:DI 2 "register_operand" "r")
2283 (match_operand:SF 3 "register_operand" "f")
2284 (match_operand:SF 4 "register_operand" "0")))]
2285 "TARGET_V9 && TARGET_FPU"
2286 "fmovrs%D1 %2,%r3,%0"
2287 [(set_attr "type" "cmove")])
2290 [(set (match_operand:DF 0 "register_operand" "=e")
2291 (if_then_else (match_operator 1 "v9_regcmp_op"
2292 [(match_operand:DI 2 "register_operand" "r")
2294 (match_operand:DF 3 "register_operand" "e")
2295 (match_operand:DF 4 "register_operand" "0")))]
2296 "TARGET_V9 && TARGET_FPU"
2297 "fmovrd%D1 %2,%r3,%0"
2298 [(set_attr "type" "cmove")])
2301 [(set (match_operand:TF 0 "register_operand" "=e")
2302 (if_then_else (match_operator 1 "v9_regcmp_op"
2303 [(match_operand:DI 2 "register_operand" "r")
2305 (match_operand:TF 3 "register_operand" "e")
2306 (match_operand:TF 4 "register_operand" "0")))]
2307 "TARGET_V9 && TARGET_FPU"
2308 "fmovrq%D1 %2,%r3,%0"
2309 [(set_attr "type" "cmove")])
2312 [(set (match_operand:SF 0 "register_operand" "=f")
2313 (if_then_else (match_operator 1 "comparison_operator"
2314 [(match_operand:CCFP 2 "ccfp_reg_operand" "c")
2316 (match_operand:SF 3 "register_operand" "f")
2317 (match_operand:SF 4 "register_operand" "0")))]
2318 "TARGET_V9 && TARGET_FPU"
2320 [(set_attr "type" "cmove")])
2323 [(set (match_operand:SF 0 "register_operand" "=f")
2324 (if_then_else (match_operator 1 "comparison_operator"
2325 [(match_operand:CCFPE 2 "ccfp_reg_operand" "c")
2327 (match_operand:SF 3 "register_operand" "f")
2328 (match_operand:SF 4 "register_operand" "0")))]
2329 "TARGET_V9 && TARGET_FPU"
2331 [(set_attr "type" "cmove")])
2334 [(set (match_operand:DF 0 "register_operand" "=e")
2335 (if_then_else (match_operator 1 "comparison_operator"
2336 [(match_operand:CCFP 2 "ccfp_reg_operand" "c")
2338 (match_operand:DF 3 "register_operand" "e")
2339 (match_operand:DF 4 "register_operand" "0")))]
2340 "TARGET_V9 && TARGET_FPU"
2342 [(set_attr "type" "cmove")])
2345 [(set (match_operand:DF 0 "register_operand" "=e")
2346 (if_then_else (match_operator 1 "comparison_operator"
2347 [(match_operand:CCFPE 2 "ccfp_reg_operand" "c")
2349 (match_operand:DF 3 "register_operand" "e")
2350 (match_operand:DF 4 "register_operand" "0")))]
2351 "TARGET_V9 && TARGET_FPU"
2353 [(set_attr "type" "cmove")])
2356 [(set (match_operand:TF 0 "register_operand" "=e")
2357 (if_then_else (match_operator 1 "comparison_operator"
2358 [(match_operand:CCFP 2 "ccfp_reg_operand" "c")
2360 (match_operand:TF 3 "register_operand" "e")
2361 (match_operand:TF 4 "register_operand" "0")))]
2362 "TARGET_V9 && TARGET_FPU"
2364 [(set_attr "type" "cmove")])
2367 [(set (match_operand:TF 0 "register_operand" "=e")
2368 (if_then_else (match_operator 1 "comparison_operator"
2369 [(match_operand:CCFPE 2 "ccfp_reg_operand" "c")
2371 (match_operand:TF 3 "register_operand" "e")
2372 (match_operand:TF 4 "register_operand" "0")))]
2373 "TARGET_V9 && TARGET_FPU"
2375 [(set_attr "type" "cmove")])
2378 [(set (match_operand:SF 0 "register_operand" "=f")
2379 (if_then_else (match_operator 1 "comparison_operator"
2380 [(reg:CC 0) (const_int 0)])
2381 (match_operand:SF 2 "register_operand" "f")
2382 (match_operand:SF 3 "register_operand" "0")))]
2383 "TARGET_V9 && TARGET_FPU"
2384 "fmovs%C1 %%icc,%2,%0"
2385 [(set_attr "type" "cmove")])
2388 [(set (match_operand:DF 0 "register_operand" "=e")
2389 (if_then_else (match_operator 1 "comparison_operator"
2390 [(reg:CC 0) (const_int 0)])
2391 (match_operand:DF 2 "register_operand" "e")
2392 (match_operand:DF 3 "register_operand" "0")))]
2393 "TARGET_V9 && TARGET_FPU"
2394 "fmovd%C1 %%icc,%2,%0"
2395 [(set_attr "type" "cmove")])
2398 [(set (match_operand:TF 0 "register_operand" "=e")
2399 (if_then_else (match_operator 1 "comparison_operator"
2400 [(reg:CC 0) (const_int 0)])
2401 (match_operand:TF 2 "register_operand" "e")
2402 (match_operand:TF 3 "register_operand" "0")))]
2403 "TARGET_V9 && TARGET_FPU"
2404 "fmovq%C1 %%icc,%2,%0"
2405 [(set_attr "type" "cmove")])
2408 [(set (match_operand:SF 0 "register_operand" "=f")
2409 (if_then_else (match_operator 1 "comparison_operator"
2410 [(reg:CCX 0) (const_int 0)])
2411 (match_operand:SF 2 "register_operand" "f")
2412 (match_operand:SF 3 "register_operand" "0")))]
2413 "TARGET_V9 && TARGET_FPU"
2414 "fmovs%C1 %%xcc,%2,%0"
2415 [(set_attr "type" "cmove")])
2418 [(set (match_operand:DF 0 "register_operand" "=e")
2419 (if_then_else (match_operator 1 "comparison_operator"
2420 [(reg:CCX 0) (const_int 0)])
2421 (match_operand:DF 2 "register_operand" "e")
2422 (match_operand:DF 3 "register_operand" "0")))]
2423 "TARGET_V9 && TARGET_FPU"
2424 "fmovd%C1 %%xcc,%2,%0"
2425 [(set_attr "type" "cmove")])
2428 [(set (match_operand:TF 0 "register_operand" "=e")
2429 (if_then_else (match_operator 1 "comparison_operator"
2430 [(reg:CCX 0) (const_int 0)])
2431 (match_operand:TF 2 "register_operand" "e")
2432 (match_operand:TF 3 "register_operand" "0")))]
2433 "TARGET_V9 && TARGET_FPU"
2434 "fmovq%C1 %%xcc,%2,%0"
2435 [(set_attr "type" "cmove")])
2437 ;;- zero extension instructions
2439 ;; These patterns originally accepted general_operands, however, slightly
2440 ;; better code is generated by only accepting register_operands, and then
2441 ;; letting combine generate the ldu[hb] insns.
2443 (define_expand "zero_extendhisi2"
2444 [(set (match_operand:SI 0 "register_operand" "")
2445 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
2449 rtx temp = gen_reg_rtx (SImode);
2450 rtx shift_16 = gen_rtx (CONST_INT, VOIDmode, 16);
2451 int op1_subword = 0;
2453 if (GET_CODE (operand1) == SUBREG)
2455 op1_subword = SUBREG_WORD (operand1);
2456 operand1 = XEXP (operand1, 0);
2459 emit_insn (gen_ashlsi3 (temp, gen_rtx (SUBREG, SImode, operand1,
2462 emit_insn (gen_lshrsi3 (operand0, temp, shift_16));
2467 [(set (match_operand:SI 0 "register_operand" "=r")
2468 (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
2471 [(set_attr "type" "load")])
2473 (define_expand "zero_extendqihi2"
2474 [(set (match_operand:HI 0 "register_operand" "")
2475 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
2480 [(set (match_operand:HI 0 "register_operand" "=r,r")
2481 (zero_extend:HI (match_operand:QI 1 "sparc_operand" "r,Q")))]
2482 "GET_CODE (operands[1]) != CONST_INT"
2486 [(set_attr "type" "unary,load")
2487 (set_attr "length" "1")])
2489 (define_expand "zero_extendqisi2"
2490 [(set (match_operand:SI 0 "register_operand" "")
2491 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
2496 [(set (match_operand:SI 0 "register_operand" "=r,r")
2497 (zero_extend:SI (match_operand:QI 1 "sparc_operand" "r,Q")))]
2498 "GET_CODE (operands[1]) != CONST_INT"
2502 [(set_attr "type" "unary,load")
2503 (set_attr "length" "1")])
2505 (define_expand "zero_extendqidi2"
2506 [(set (match_operand:DI 0 "register_operand" "")
2507 (zero_extend:DI (match_operand:QI 1 "register_operand" "")))]
2512 [(set (match_operand:DI 0 "register_operand" "=r,r")
2513 (zero_extend:DI (match_operand:QI 1 "sparc_operand" "r,Q")))]
2514 "TARGET_V9 && GET_CODE (operands[1]) != CONST_INT"
2518 [(set_attr "type" "unary,load")
2519 (set_attr "length" "1")])
2521 (define_expand "zero_extendhidi2"
2522 [(set (match_operand:DI 0 "register_operand" "")
2523 (zero_extend:DI (match_operand:HI 1 "register_operand" "")))]
2527 rtx temp = gen_reg_rtx (DImode);
2528 rtx shift_48 = gen_rtx (CONST_INT, VOIDmode, 48);
2529 int op1_subword = 0;
2531 if (GET_CODE (operand1) == SUBREG)
2533 op1_subword = SUBREG_WORD (operand1);
2534 operand1 = XEXP (operand1, 0);
2537 emit_insn (gen_ashldi3 (temp, gen_rtx (SUBREG, DImode, operand1,
2540 emit_insn (gen_lshrdi3 (operand0, temp, shift_48));
2545 [(set (match_operand:DI 0 "register_operand" "=r")
2546 (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
2549 [(set_attr "type" "load")])
2551 ;; ??? Write truncdisi pattern using sra?
2553 (define_expand "zero_extendsidi2"
2554 [(set (match_operand:DI 0 "register_operand" "")
2555 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
2560 [(set (match_operand:DI 0 "register_operand" "=r,r")
2561 (zero_extend:DI (match_operand:SI 1 "sparc_operand" "r,Q")))]
2562 "TARGET_V9 && GET_CODE (operands[1]) != CONST_INT"
2566 [(set_attr "type" "unary,load")
2567 (set_attr "length" "1")])
2569 ;; Simplify comparisons of extended values.
2573 (compare:CC (zero_extend:SI (match_operand:QI 0 "register_operand" "r"))
2576 "andcc %0,0xff,%%g0"
2577 [(set_attr "type" "compare")])
2581 (compare:CC (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
2583 (set (match_operand:SI 0 "register_operand" "=r")
2584 (zero_extend:SI (match_dup 1)))]
2587 [(set_attr "type" "unary")])
2589 ;; Similarly, handle SI->QI mode truncation followed by a compare.
2593 (compare:CC (subreg:QI (match_operand:SI 0 "register_operand" "r") 0)
2596 "andcc %0,0xff,%%g0"
2597 [(set_attr "type" "compare")])
2601 (compare:CC (subreg:QI (match_operand:SI 1 "register_operand" "r") 0)
2603 (set (match_operand:QI 0 "register_operand" "=r")
2607 [(set_attr "type" "unary")])
2609 ;;- sign extension instructions
2611 ;; These patterns originally accepted general_operands, however, slightly
2612 ;; better code is generated by only accepting register_operands, and then
2613 ;; letting combine generate the lds[hb] insns.
2615 (define_expand "extendhisi2"
2616 [(set (match_operand:SI 0 "register_operand" "")
2617 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
2621 rtx temp = gen_reg_rtx (SImode);
2622 rtx shift_16 = gen_rtx (CONST_INT, VOIDmode, 16);
2623 int op1_subword = 0;
2625 if (GET_CODE (operand1) == SUBREG)
2627 op1_subword = SUBREG_WORD (operand1);
2628 operand1 = XEXP (operand1, 0);
2631 emit_insn (gen_ashlsi3 (temp, gen_rtx (SUBREG, SImode, operand1,
2634 emit_insn (gen_ashrsi3 (operand0, temp, shift_16));
2639 [(set (match_operand:SI 0 "register_operand" "=r")
2640 (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
2643 [(set_attr "type" "load")])
2645 (define_expand "extendqihi2"
2646 [(set (match_operand:HI 0 "register_operand" "")
2647 (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
2651 rtx temp = gen_reg_rtx (SImode);
2652 rtx shift_24 = gen_rtx (CONST_INT, VOIDmode, 24);
2653 int op1_subword = 0;
2654 int op0_subword = 0;
2656 if (GET_CODE (operand1) == SUBREG)
2658 op1_subword = SUBREG_WORD (operand1);
2659 operand1 = XEXP (operand1, 0);
2661 if (GET_CODE (operand0) == SUBREG)
2663 op0_subword = SUBREG_WORD (operand0);
2664 operand0 = XEXP (operand0, 0);
2666 emit_insn (gen_ashlsi3 (temp, gen_rtx (SUBREG, SImode, operand1,
2669 if (GET_MODE (operand0) != SImode)
2670 operand0 = gen_rtx (SUBREG, SImode, operand0, op0_subword);
2671 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
2676 [(set (match_operand:HI 0 "register_operand" "=r")
2677 (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
2680 [(set_attr "type" "load")])
2682 (define_expand "extendqisi2"
2683 [(set (match_operand:SI 0 "register_operand" "")
2684 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
2688 rtx temp = gen_reg_rtx (SImode);
2689 rtx shift_24 = gen_rtx (CONST_INT, VOIDmode, 24);
2690 int op1_subword = 0;
2692 if (GET_CODE (operand1) == SUBREG)
2694 op1_subword = SUBREG_WORD (operand1);
2695 operand1 = XEXP (operand1, 0);
2698 emit_insn (gen_ashlsi3 (temp, gen_rtx (SUBREG, SImode, operand1,
2701 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
2706 [(set (match_operand:SI 0 "register_operand" "=r")
2707 (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
2710 [(set_attr "type" "load")])
2712 (define_expand "extendqidi2"
2713 [(set (match_operand:DI 0 "register_operand" "")
2714 (sign_extend:DI (match_operand:QI 1 "register_operand" "")))]
2718 rtx temp = gen_reg_rtx (DImode);
2719 rtx shift_56 = gen_rtx (CONST_INT, VOIDmode, 56);
2720 int op1_subword = 0;
2722 if (GET_CODE (operand1) == SUBREG)
2724 op1_subword = SUBREG_WORD (operand1);
2725 operand1 = XEXP (operand1, 0);
2728 emit_insn (gen_ashldi3 (temp, gen_rtx (SUBREG, DImode, operand1,
2731 emit_insn (gen_ashrdi3 (operand0, temp, shift_56));
2736 [(set (match_operand:DI 0 "register_operand" "=r")
2737 (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
2740 [(set_attr "type" "load")])
2742 (define_expand "extendhidi2"
2743 [(set (match_operand:DI 0 "register_operand" "")
2744 (sign_extend:DI (match_operand:HI 1 "register_operand" "")))]
2748 rtx temp = gen_reg_rtx (DImode);
2749 rtx shift_48 = gen_rtx (CONST_INT, VOIDmode, 48);
2750 int op1_subword = 0;
2752 if (GET_CODE (operand1) == SUBREG)
2754 op1_subword = SUBREG_WORD (operand1);
2755 operand1 = XEXP (operand1, 0);
2758 emit_insn (gen_ashldi3 (temp, gen_rtx (SUBREG, DImode, operand1,
2761 emit_insn (gen_ashrdi3 (operand0, temp, shift_48));
2766 [(set (match_operand:DI 0 "register_operand" "=r")
2767 (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
2770 [(set_attr "type" "load")])
2772 (define_expand "extendsidi2"
2773 [(set (match_operand:DI 0 "register_operand" "")
2774 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
2779 [(set (match_operand:DI 0 "register_operand" "=r,r")
2780 (sign_extend:DI (match_operand:SI 1 "sparc_operand" "r,Q")))]
2785 [(set_attr "type" "unary,load")
2786 (set_attr "length" "1")])
2788 ;; Special pattern for optimizing bit-field compares. This is needed
2789 ;; because combine uses this as a canonical form.
2794 (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
2795 (match_operand:SI 1 "small_int" "n")
2796 (match_operand:SI 2 "small_int" "n"))
2798 "INTVAL (operands[2]) > 19"
2801 int len = INTVAL (operands[1]);
2802 int pos = 32 - INTVAL (operands[2]) - len;
2803 unsigned mask = ((1 << len) - 1) << pos;
2805 operands[1] = gen_rtx (CONST_INT, VOIDmode, mask);
2806 return \"andcc %0,%1,%%g0\";
2812 (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
2813 (match_operand:SI 1 "small_int" "n")
2814 (match_operand:SI 2 "small_int" "n"))
2816 "TARGET_V9 && INTVAL (operands[2]) > 51"
2819 int len = INTVAL (operands[1]);
2820 int pos = 64 - INTVAL (operands[2]) - len;
2821 unsigned mask = ((1 << len) - 1) << pos;
2823 operands[1] = gen_rtx (CONST_INT, VOIDmode, mask);
2824 return \"andcc %0,%1,%%g0\";
2827 ;; Conversions between float, double and long double.
2829 (define_insn "extendsfdf2"
2830 [(set (match_operand:DF 0 "register_operand" "=e")
2832 (match_operand:SF 1 "register_operand" "f")))]
2835 [(set_attr "type" "fp")])
2837 (define_insn "extendsftf2"
2838 [(set (match_operand:TF 0 "register_operand" "=e")
2840 (match_operand:SF 1 "register_operand" "f")))]
2841 "TARGET_FPU && TARGET_HARD_QUAD"
2843 [(set_attr "type" "fp")])
2845 (define_insn "extenddftf2"
2846 [(set (match_operand:TF 0 "register_operand" "=e")
2848 (match_operand:DF 1 "register_operand" "e")))]
2849 "TARGET_FPU && TARGET_HARD_QUAD"
2851 [(set_attr "type" "fp")])
2853 (define_insn "truncdfsf2"
2854 [(set (match_operand:SF 0 "register_operand" "=f")
2856 (match_operand:DF 1 "register_operand" "e")))]
2859 [(set_attr "type" "fp")])
2861 (define_insn "trunctfsf2"
2862 [(set (match_operand:SF 0 "register_operand" "=f")
2864 (match_operand:TF 1 "register_operand" "e")))]
2865 "TARGET_FPU && TARGET_HARD_QUAD"
2867 [(set_attr "type" "fp")])
2869 (define_insn "trunctfdf2"
2870 [(set (match_operand:DF 0 "register_operand" "=e")
2872 (match_operand:TF 1 "register_operand" "e")))]
2873 "TARGET_FPU && TARGET_HARD_QUAD"
2875 [(set_attr "type" "fp")])
2877 ;; Conversion between fixed point and floating point.
2879 (define_insn "floatsisf2"
2880 [(set (match_operand:SF 0 "register_operand" "=f")
2881 (float:SF (match_operand:SI 1 "register_operand" "f")))]
2884 [(set_attr "type" "fp")])
2886 (define_insn "floatsidf2"
2887 [(set (match_operand:DF 0 "register_operand" "=e")
2888 (float:DF (match_operand:SI 1 "register_operand" "f")))]
2891 [(set_attr "type" "fp")])
2893 (define_insn "floatsitf2"
2894 [(set (match_operand:TF 0 "register_operand" "=e")
2895 (float:TF (match_operand:SI 1 "register_operand" "f")))]
2896 "TARGET_FPU && TARGET_HARD_QUAD"
2898 [(set_attr "type" "fp")])
2900 ;; Now the same for 64 bit sources.
2901 ;; ??? We cannot put DImode values in fp regs (see below near fix_truncdfsi2).
2903 (define_expand "floatdisf2"
2904 [(parallel [(set (match_operand:SF 0 "register_operand" "")
2905 (float:SF (match_operand:DI 1 "general_operand" "")))
2906 (clobber (match_dup 2))
2907 (clobber (match_dup 3))])]
2908 "TARGET_V9 && TARGET_FPU"
2911 operands[2] = gen_reg_rtx (DFmode);
2912 operands[3] = sparc64_fpconv_stack_temp ();
2915 (define_expand "floatdidf2"
2916 [(parallel [(set (match_operand:DF 0 "register_operand" "")
2917 (float:DF (match_operand:DI 1 "general_operand" "")))
2918 (clobber (match_dup 2))
2919 (clobber (match_dup 3))])]
2920 "TARGET_V9 && TARGET_FPU"
2923 operands[2] = gen_reg_rtx (DFmode);
2924 operands[3] = sparc64_fpconv_stack_temp ();
2927 (define_expand "floatditf2"
2928 [(parallel [(set (match_operand:TF 0 "register_operand" "")
2929 (float:TF (match_operand:DI 1 "general_operand" "")))
2930 (clobber (match_dup 2))
2931 (clobber (match_dup 3))])]
2932 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
2935 operands[2] = gen_reg_rtx (DFmode);
2936 operands[3] = sparc64_fpconv_stack_temp ();
2940 [(parallel [(set (match_operand:SF 0 "register_operand" "=f")
2941 (float:SF (match_operand:DI 1 "general_operand" "rm")))
2942 (clobber (match_operand:DF 2 "register_operand" "=&e"))
2943 (clobber (match_operand:DI 3 "memory_operand" "m"))])]
2944 "TARGET_V9 && TARGET_FPU"
2947 if (GET_CODE (operands[1]) == MEM)
2948 output_asm_insn (\"ldd %1,%2\", operands);
2950 output_asm_insn (\"stx %1,%3\;ldd %3,%2\", operands);
2951 return \"fxtos %2,%0\";
2953 [(set_attr "type" "fp")
2954 (set_attr "length" "3")])
2957 [(parallel [(set (match_operand:DF 0 "register_operand" "=e")
2958 (float:DF (match_operand:DI 1 "general_operand" "rm")))
2959 (clobber (match_operand:DF 2 "register_operand" "=&e"))
2960 (clobber (match_operand:DI 3 "memory_operand" "m"))])]
2961 "TARGET_V9 && TARGET_FPU"
2964 if (GET_CODE (operands[1]) == MEM)
2965 output_asm_insn (\"ldd %1,%2\", operands);
2967 output_asm_insn (\"stx %1,%3\;ldd %3,%2\", operands);
2968 return \"fxtod %2,%0\";
2970 [(set_attr "type" "fp")
2971 (set_attr "length" "3")])
2974 [(parallel [(set (match_operand:TF 0 "register_operand" "=e")
2975 (float:TF (match_operand:DI 1 "general_operand" "rm")))
2976 (clobber (match_operand:DF 2 "register_operand" "=&e"))
2977 (clobber (match_operand:DI 3 "memory_operand" "m"))])]
2978 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
2981 if (GET_CODE (operands[1]) == MEM)
2982 output_asm_insn (\"ldd %1,%2\", operands);
2984 output_asm_insn (\"stx %1,%3\;ldd %3,%2\", operands);
2985 return \"fxtoq %2,%0\";
2987 [(set_attr "type" "fp")
2988 (set_attr "length" "3")])
2990 ;; ??? Ideally, these are what we would like to use.
2992 (define_insn "floatdisf2_v9"
2993 [(set (match_operand:SF 0 "register_operand" "=f")
2994 (float:SF (match_operand:DI 1 "register_operand" "e")))]
2995 "0 && TARGET_V9 && TARGET_FPU"
2997 [(set_attr "type" "fp")])
2999 (define_insn "floatdidf2_v9"
3000 [(set (match_operand:DF 0 "register_operand" "=e")
3001 (float:DF (match_operand:DI 1 "register_operand" "e")))]
3002 "0 && TARGET_V9 && TARGET_FPU"
3004 [(set_attr "type" "fp")])
3006 (define_insn "floatditf2_v9"
3007 [(set (match_operand:TF 0 "register_operand" "=e")
3008 (float:TF (match_operand:DI 1 "register_operand" "e")))]
3009 "0 && TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
3011 [(set_attr "type" "fp")])
3013 ;; Convert a float to an actual integer.
3014 ;; Truncation is performed as part of the conversion.
3016 (define_insn "fix_truncsfsi2"
3017 [(set (match_operand:SI 0 "register_operand" "=f")
3018 (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
3021 [(set_attr "type" "fp")])
3023 (define_insn "fix_truncdfsi2"
3024 [(set (match_operand:SI 0 "register_operand" "=f")
3025 (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
3028 [(set_attr "type" "fp")])
3030 (define_insn "fix_trunctfsi2"
3031 [(set (match_operand:SI 0 "register_operand" "=f")
3032 (fix:SI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
3033 "TARGET_FPU && TARGET_HARD_QUAD"
3035 [(set_attr "type" "fp")])
3037 ;; Now the same, for 64-bit targets
3038 ;; ??? We try to work around an interesting problem.
3039 ;; If gcc tries to do a subreg on the result it will get the wrong answer:
3040 ;; "(subreg:SI (reg:DI M int-reg) 0)" is the same as
3041 ;; "(subreg:SI (reg:DI N float-reg) 1)", but gcc does not know how to change
3042 ;; the "0" to a "1". One could enhance alter_subreg but it is not clear how to
3045 (define_expand "fix_truncsfdi2"
3046 [(parallel [(set (match_operand:DI 0 "general_operand" "")
3047 (fix:DI (fix:SF (match_operand:SF 1 "register_operand" ""))))
3048 (clobber (match_dup 2))
3049 (clobber (match_dup 3))])]
3050 "TARGET_V9 && TARGET_FPU"
3053 operands[2] = gen_reg_rtx (DFmode);
3054 operands[3] = sparc64_fpconv_stack_temp ();
3057 (define_expand "fix_truncdfdi2"
3058 [(parallel [(set (match_operand:DI 0 "general_operand" "")
3059 (fix:DI (fix:DF (match_operand:DF 1 "register_operand" ""))))
3060 (clobber (match_dup 2))
3061 (clobber (match_dup 3))])]
3062 "TARGET_V9 && TARGET_FPU"
3065 operands[2] = gen_reg_rtx (DFmode);
3066 operands[3] = sparc64_fpconv_stack_temp ();
3069 (define_expand "fix_trunctfdi2"
3070 [(parallel [(set (match_operand:DI 0 "general_operand" "")
3071 (fix:DI (fix:TF (match_operand:TF 1 "register_operand" ""))))
3072 (clobber (match_dup 2))
3073 (clobber (match_dup 3))])]
3074 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
3077 operands[2] = gen_reg_rtx (DFmode);
3078 operands[3] = sparc64_fpconv_stack_temp ();
3082 [(parallel [(set (match_operand:DI 0 "general_operand" "=rm")
3083 (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))
3084 (clobber (match_operand:DF 2 "register_operand" "=&e"))
3085 (clobber (match_operand:DI 3 "memory_operand" "m"))])]
3086 "TARGET_V9 && TARGET_FPU"
3089 output_asm_insn (\"fstox %1,%2\", operands);
3090 if (GET_CODE (operands[0]) == MEM)
3091 return \"std %2,%0\";
3093 return \"std %2,%3\;ldx %3,%0\";
3095 [(set_attr "type" "fp")
3096 (set_attr "length" "3")])
3099 [(parallel [(set (match_operand:DI 0 "general_operand" "=rm")
3100 (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "e"))))
3101 (clobber (match_operand:DF 2 "register_operand" "=&e"))
3102 (clobber (match_operand:DI 3 "memory_operand" "m"))])]
3103 "TARGET_V9 && TARGET_FPU"
3106 output_asm_insn (\"fdtox %1,%2\", operands);
3107 if (GET_CODE (operands[0]) == MEM)
3108 return \"std %2,%0\";
3110 return \"std %2,%3\;ldx %3,%0\";
3112 [(set_attr "type" "fp")
3113 (set_attr "length" "3")])
3116 [(parallel [(set (match_operand:DI 0 "general_operand" "=rm")
3117 (fix:DI (fix:TF (match_operand:TF 1 "register_operand" "e"))))
3118 (clobber (match_operand:DF 2 "register_operand" "=&e"))
3119 (clobber (match_operand:DI 3 "memory_operand" "m"))])]
3120 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
3123 output_asm_insn (\"fqtox %1,%2\", operands);
3124 if (GET_CODE (operands[0]) == MEM)
3125 return \"std %2,%0\";
3127 return \"std %2,%3\;ldx %3,%0\";
3129 [(set_attr "type" "fp")
3130 (set_attr "length" "3")])
3132 ;; ??? Ideally, these are what we would like to use.
3134 (define_insn "fix_truncsfdi2_v9"
3135 [(set (match_operand:DI 0 "register_operand" "=e")
3136 (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
3137 "0 && TARGET_V9 && TARGET_FPU"
3139 [(set_attr "type" "fp")])
3141 (define_insn "fix_truncdfdi2_v9"
3142 [(set (match_operand:DI 0 "register_operand" "=e")
3143 (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
3144 "0 && TARGET_V9 && TARGET_FPU"
3146 [(set_attr "type" "fp")])
3148 (define_insn "fix_trunctfdi2_v9"
3149 [(set (match_operand:DI 0 "register_operand" "=e")
3150 (fix:DI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
3151 "0 && TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
3153 [(set_attr "type" "fp")])
3155 ;;- arithmetic instructions
3157 (define_expand "adddi3"
3158 [(set (match_operand:DI 0 "register_operand" "=r")
3159 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
3160 (match_operand:DI 2 "arith_double_operand" "rHI")))]
3166 emit_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (2,
3167 gen_rtx (SET, VOIDmode, operands[0],
3168 gen_rtx (PLUS, DImode, operands[1],
3170 gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, 0)))));
3176 [(set (match_operand:DI 0 "register_operand" "=r")
3177 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
3178 (match_operand:DI 2 "arith_double_operand" "rHI")))
3179 (clobber (reg:SI 0))]
3183 rtx op2 = operands[2];
3185 /* If constant is positive, upper bits zeroed, otherwise unchanged.
3186 Give the assembler a chance to pick the move instruction. */
3187 if (GET_CODE (op2) == CONST_INT)
3189 int sign = INTVAL (op2);
3191 return \"addcc %R1,%2,%R0\;addx %1,-1,%0\";
3192 return \"addcc %R1,%2,%R0\;addx %1,0,%0\";
3194 else if (GET_CODE (op2) == CONST_DOUBLE)
3197 xoperands[0] = operands[0];
3198 xoperands[1] = operands[1];
3199 xoperands[2] = GEN_INT (CONST_DOUBLE_LOW (op2));
3200 xoperands[3] = GEN_INT (CONST_DOUBLE_HIGH (op2));
3201 if (xoperands[2] == const0_rtx && xoperands[0] == xoperands[1])
3202 output_asm_insn (\"add %1,%3,%0\", xoperands);
3204 output_asm_insn (\"addcc %R1,%2,%R0\;addx %1,%3,%0\", xoperands);
3207 return \"addcc %R1,%R2,%R0\;addx %1,%2,%0\";
3209 [(set_attr "length" "2")])
3212 [(set (match_operand:DI 0 "register_operand" "=r")
3213 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
3214 (match_operand:DI 2 "arith_double_operand" "rHI")))]
3218 (define_insn "addsi3"
3219 [(set (match_operand:SI 0 "register_operand" "=r")
3220 (plus:SI (match_operand:SI 1 "arith_operand" "%r")
3221 (match_operand:SI 2 "arith_operand" "rI")))]
3224 [(set_attr "type" "ialu")])
3227 [(set (reg:CC_NOOV 0)
3228 (compare:CC_NOOV (plus:SI (match_operand:SI 0 "arith_operand" "%r")
3229 (match_operand:SI 1 "arith_operand" "rI"))
3233 [(set_attr "type" "compare")])
3236 [(set (reg:CCX_NOOV 0)
3237 (compare:CCX_NOOV (plus:DI (match_operand:DI 0 "arith_double_operand" "%r")
3238 (match_operand:DI 1 "arith_double_operand" "rHI"))
3242 [(set_attr "type" "compare")])
3245 [(set (reg:CC_NOOV 0)
3246 (compare:CC_NOOV (plus:SI (match_operand:SI 1 "arith_operand" "%r")
3247 (match_operand:SI 2 "arith_operand" "rI"))
3249 (set (match_operand:SI 0 "register_operand" "=r")
3250 (plus:SI (match_dup 1) (match_dup 2)))]
3255 [(set (reg:CCX_NOOV 0)
3256 (compare:CCX_NOOV (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
3257 (match_operand:DI 2 "arith_double_operand" "rHI"))
3259 (set (match_operand:DI 0 "register_operand" "=r")
3260 (plus:DI (match_dup 1) (match_dup 2)))]
3264 (define_expand "subdi3"
3265 [(set (match_operand:DI 0 "register_operand" "=r")
3266 (minus:DI (match_operand:DI 1 "register_operand" "r")
3267 (match_operand:DI 2 "arith_double_operand" "rHI")))]
3273 emit_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (2,
3274 gen_rtx (SET, VOIDmode, operands[0],
3275 gen_rtx (MINUS, DImode, operands[1],
3277 gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, 0)))));
3283 [(set (match_operand:DI 0 "register_operand" "=r")
3284 (minus:DI (match_operand:DI 1 "register_operand" "r")
3285 (match_operand:DI 2 "arith_double_operand" "rHI")))
3286 (clobber (reg:SI 0))]
3290 rtx op2 = operands[2];
3292 /* If constant is positive, upper bits zeroed, otherwise unchanged.
3293 Give the assembler a chance to pick the move instruction. */
3294 if (GET_CODE (op2) == CONST_INT)
3296 int sign = INTVAL (op2);
3298 return \"subcc %R1,%2,%R0\;subx %1,-1,%0\";
3299 return \"subcc %R1,%2,%R0\;subx %1,0,%0\";
3301 else if (GET_CODE (op2) == CONST_DOUBLE)
3304 xoperands[0] = operands[0];
3305 xoperands[1] = operands[1];
3306 xoperands[2] = GEN_INT (CONST_DOUBLE_LOW (op2));
3307 xoperands[3] = GEN_INT (CONST_DOUBLE_HIGH (op2));
3308 if (xoperands[2] == const0_rtx && xoperands[0] == xoperands[1])
3309 output_asm_insn (\"sub %1,%3,%0\", xoperands);
3311 output_asm_insn (\"subcc %R1,%2,%R0\;subx %1,%3,%0\", xoperands);
3314 return \"subcc %R1,%R2,%R0\;subx %1,%2,%0\";
3316 [(set_attr "length" "2")])
3319 [(set (match_operand:DI 0 "register_operand" "=r")
3320 (minus:DI (match_operand:DI 1 "register_operand" "r")
3321 (match_operand:DI 2 "arith_double_operand" "rHI")))]
3325 (define_insn "subsi3"
3326 [(set (match_operand:SI 0 "register_operand" "=r")
3327 (minus:SI (match_operand:SI 1 "register_operand" "r")
3328 (match_operand:SI 2 "arith_operand" "rI")))]
3331 [(set_attr "type" "ialu")])
3334 [(set (reg:CC_NOOV 0)
3335 (compare:CC_NOOV (minus:SI (match_operand:SI 0 "register_operand" "r")
3336 (match_operand:SI 1 "arith_operand" "rI"))
3340 [(set_attr "type" "compare")])
3343 [(set (reg:CCX_NOOV 0)
3344 (compare:CCX_NOOV (minus:DI (match_operand:DI 0 "register_operand" "r")
3345 (match_operand:DI 1 "arith_double_operand" "rHI"))
3349 [(set_attr "type" "compare")])
3352 [(set (reg:CC_NOOV 0)
3353 (compare:CC_NOOV (minus:SI (match_operand:SI 1 "register_operand" "r")
3354 (match_operand:SI 2 "arith_operand" "rI"))
3356 (set (match_operand:SI 0 "register_operand" "=r")
3357 (minus:SI (match_dup 1) (match_dup 2)))]
3362 [(set (reg:CCX_NOOV 0)
3363 (compare:CCX_NOOV (minus:DI (match_operand:DI 1 "register_operand" "r")
3364 (match_operand:DI 2 "arith_double_operand" "rHI"))
3366 (set (match_operand:DI 0 "register_operand" "=r")
3367 (minus:DI (match_dup 1) (match_dup 2)))]
3371 ;; This is anachronistic, and should not be used in v9 software.
3372 ;; The v9 compiler will widen the args and use muldi3.
3374 (define_insn "mulsi3"
3375 [(set (match_operand:SI 0 "register_operand" "=r")
3376 (mult:SI (match_operand:SI 1 "arith_operand" "%r")
3377 (match_operand:SI 2 "arith_operand" "rI")))]
3378 "TARGET_V8 || TARGET_SPARCLITE"
3380 [(set_attr "type" "imul")])
3382 (define_insn "muldi3"
3383 [(set (match_operand:DI 0 "register_operand" "=r")
3384 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r")
3385 (match_operand:DI 2 "arith_double_operand" "rHI")))]
3389 ;; It is not known whether this will match.
3392 [(set (match_operand:SI 0 "register_operand" "=r")
3393 (mult:SI (match_operand:SI 1 "arith_operand" "%r")
3394 (match_operand:SI 2 "arith_operand" "rI")))
3395 (set (reg:CC_NOOV 0)
3396 (compare:CC_NOOV (mult:SI (match_dup 1) (match_dup 2))
3398 "TARGET_V8 || TARGET_SPARCLITE"
3400 [(set_attr "type" "imul")])
3402 (define_expand "mulsidi3"
3403 [(set (match_operand:DI 0 "register_operand" "")
3404 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
3405 (sign_extend:DI (match_operand:SI 2 "arith_operand" ""))))]
3406 "TARGET_V8 || TARGET_SPARCLITE"
3409 if (CONSTANT_P (operands[2]))
3411 emit_insn (gen_const_mulsidi3 (operands[0], operands[1], operands[2]));
3417 [(set (match_operand:DI 0 "register_operand" "=r")
3418 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
3419 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
3420 "TARGET_V8 || TARGET_SPARCLITE"
3421 "smul %1,%2,%R0\;rd %%y,%0"
3422 [(set_attr "length" "2")])
3424 ;; Extra pattern, because sign_extend of a constant isn't legal.
3426 (define_insn "const_mulsidi3"
3427 [(set (match_operand:DI 0 "register_operand" "=r")
3428 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
3429 (match_operand:SI 2 "small_int" "I")))]
3430 "TARGET_V8 || TARGET_SPARCLITE"
3431 "smul %1,%2,%R0\;rd %%y,%0"
3432 [(set_attr "length" "2")])
3434 (define_expand "smulsi3_highpart"
3435 [(set (match_operand:SI 0 "register_operand" "")
3437 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
3438 (sign_extend:DI (match_operand:SI 2 "arith_operand" "")))
3440 "TARGET_V8 || TARGET_SPARCLITE"
3443 if (CONSTANT_P (operands[2]))
3445 emit_insn (gen_const_smulsi3_highpart (operands[0], operands[1], operands[2]));
3451 [(set (match_operand:SI 0 "register_operand" "=r")
3453 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
3454 (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
3456 "TARGET_V8 || TARGET_SPARCLITE"
3457 "smul %1,%2,%%g0\;rd %%y,%0"
3458 [(set_attr "length" "2")])
3460 (define_insn "const_smulsi3_highpart"
3461 [(set (match_operand:SI 0 "register_operand" "=r")
3463 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
3464 (match_operand:SI 2 "register_operand" "r"))
3466 "TARGET_V8 || TARGET_SPARCLITE"
3467 "smul %1,%2,%%g0\;rd %%y,%0"
3468 [(set_attr "length" "2")])
3470 (define_expand "umulsidi3"
3471 [(set (match_operand:DI 0 "register_operand" "")
3472 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
3473 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" ""))))]
3474 "TARGET_V8 || TARGET_SPARCLITE"
3477 if (CONSTANT_P (operands[2]))
3479 emit_insn (gen_const_umulsidi3 (operands[0], operands[1], operands[2]));
3485 [(set (match_operand:DI 0 "register_operand" "=r")
3486 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
3487 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
3488 "TARGET_V8 || TARGET_SPARCLITE"
3489 "umul %1,%2,%R0\;rd %%y,%0"
3490 [(set_attr "length" "2")])
3492 ;; Extra pattern, because sign_extend of a constant isn't legal.
3494 (define_insn "const_umulsidi3"
3495 [(set (match_operand:DI 0 "register_operand" "=r")
3496 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
3497 (match_operand:SI 2 "uns_small_int" "")))]
3498 "TARGET_V8 || TARGET_SPARCLITE"
3499 "umul %1,%2,%R0\;rd %%y,%0"
3500 [(set_attr "length" "2")])
3502 (define_expand "umulsi3_highpart"
3503 [(set (match_operand:SI 0 "register_operand" "")
3505 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
3506 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" "")))
3508 "TARGET_V8 || TARGET_SPARCLITE"
3511 if (CONSTANT_P (operands[2]))
3513 emit_insn (gen_const_umulsi3_highpart (operands[0], operands[1], operands[2]));
3519 [(set (match_operand:SI 0 "register_operand" "=r")
3521 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
3522 (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
3524 "TARGET_V8 || TARGET_SPARCLITE"
3525 "umul %1,%2,%%g0\;rd %%y,%0"
3526 [(set_attr "length" "2")])
3528 (define_insn "const_umulsi3_highpart"
3529 [(set (match_operand:SI 0 "register_operand" "=r")
3531 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
3532 (match_operand:SI 2 "uns_small_int" ""))
3534 "TARGET_V8 || TARGET_SPARCLITE"
3535 "umul %1,%2,%%g0\;rd %%y,%0"
3536 [(set_attr "length" "2")])
3538 ;; The architecture specifies that there must be 3 instructions between
3539 ;; a y register write and a use of it for correct results.
3541 (define_insn "divsi3"
3542 [(set (match_operand:SI 0 "register_operand" "=r")
3543 (div:SI (match_operand:SI 1 "register_operand" "r")
3544 (match_operand:SI 2 "arith_operand" "rI")))
3545 (clobber (match_scratch:SI 3 "=&r"))]
3547 "sra %1,31,%3\;wr %%g0,%3,%%y\;nop\;nop\;nop\;sdiv %1,%2,%0"
3548 [(set_attr "length" "6")])
3550 (define_insn "divdi3"
3551 [(set (match_operand:DI 0 "register_operand" "=r")
3552 (div:DI (match_operand:DI 1 "register_operand" "r")
3553 (match_operand:DI 2 "arith_double_operand" "rHI")))]
3557 ;; It is not known whether this will match.
3560 [(set (match_operand:SI 0 "register_operand" "=r")
3561 (div:SI (match_operand:SI 1 "register_operand" "r")
3562 (match_operand:SI 2 "arith_operand" "rI")))
3564 (compare:CC (div:SI (match_dup 1) (match_dup 2))
3566 (clobber (match_scratch:SI 3 "=&r"))]
3568 "sra %1,31,%3\;wr %%g0,%3,%%y\;nop\;nop\;nop\;sdivcc %1,%2,%0"
3569 [(set_attr "length" "6")])
3571 (define_insn "udivsi3"
3572 [(set (match_operand:SI 0 "register_operand" "=r")
3573 (udiv:SI (match_operand:SI 1 "register_operand" "r")
3574 (match_operand:SI 2 "arith_operand" "rI")))]
3576 "wr %%g0,%%g0,%%y\;nop\;nop\;nop\;udiv %1,%2,%0"
3577 [(set_attr "length" "5")])
3579 (define_insn "udivdi3"
3580 [(set (match_operand:DI 0 "register_operand" "=r")
3581 (udiv:DI (match_operand:DI 1 "register_operand" "r")
3582 (match_operand:DI 2 "arith_double_operand" "rHI")))]
3586 ;; It is not known whether this will match.
3589 [(set (match_operand:SI 0 "register_operand" "=r")
3590 (udiv:SI (match_operand:SI 1 "register_operand" "r")
3591 (match_operand:SI 2 "arith_operand" "rI")))
3593 (compare:CC (udiv:SI (match_dup 1) (match_dup 2))
3596 "wr %%g0,%%g0,%%y\;nop\;nop\;nop\;udivcc %1,%2,%0"
3597 [(set_attr "length" "5")])
3599 ;;- Boolean instructions
3600 ;; We define DImode `and` so with DImode `not` we can get
3601 ;; DImode `andn`. Other combinations are possible.
3603 (define_expand "anddi3"
3604 [(set (match_operand:DI 0 "register_operand" "")
3605 (and:DI (match_operand:DI 1 "arith_double_operand" "")
3606 (match_operand:DI 2 "arith_double_operand" "")))]
3611 [(set (match_operand:DI 0 "register_operand" "=r")
3612 (and:DI (match_operand:DI 1 "arith_double_operand" "%r")
3613 (match_operand:DI 2 "arith_double_operand" "rHI")))]
3617 rtx op2 = operands[2];
3619 /* If constant is positive, upper bits zeroed, otherwise unchanged.
3620 Give the assembler a chance to pick the move instruction. */
3621 if (GET_CODE (op2) == CONST_INT)
3623 int sign = INTVAL (op2);
3625 return \"mov %1,%0\;and %R1,%2,%R0\";
3626 return \"mov 0,%0\;and %R1,%2,%R0\";
3628 else if (GET_CODE (op2) == CONST_DOUBLE)
3631 xoperands[0] = operands[0];
3632 xoperands[1] = operands[1];
3633 xoperands[2] = GEN_INT (CONST_DOUBLE_LOW (op2));
3634 xoperands[3] = GEN_INT (CONST_DOUBLE_HIGH (op2));
3635 /* We could optimize then operands[1] == operands[0]
3636 and either half of the constant is -1. */
3637 output_asm_insn (\"and %R1,%2,%R0\;and %1,%3,%0\", xoperands);
3640 return \"and %1,%2,%0\;and %R1,%R2,%R0\";
3642 [(set_attr "length" "2")])
3645 [(set (match_operand:DI 0 "register_operand" "=r")
3646 (and:DI (match_operand:DI 1 "arith_double_operand" "%r")
3647 (match_operand:DI 2 "arith_double_operand" "rHI")))]
3651 (define_insn "andsi3"
3652 [(set (match_operand:SI 0 "register_operand" "=r")
3653 (and:SI (match_operand:SI 1 "arith_operand" "%r")
3654 (match_operand:SI 2 "arith_operand" "rI")))]
3657 [(set_attr "type" "ialu")])
3660 [(set (match_operand:SI 0 "register_operand" "")
3661 (and:SI (match_operand:SI 1 "register_operand" "")
3662 (match_operand:SI 2 "" "")))
3663 (clobber (match_operand:SI 3 "register_operand" ""))]
3664 "GET_CODE (operands[2]) == CONST_INT
3665 && !SMALL_INT (operands[2])
3666 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
3667 [(set (match_dup 3) (match_dup 4))
3668 (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 1)))]
3671 operands[4] = gen_rtx (CONST_INT, VOIDmode, ~INTVAL (operands[2]));
3675 [(set (match_operand:DI 0 "register_operand" "=r")
3676 (and:DI (not:DI (match_operand:DI 1 "register_operand" "r"))
3677 (match_operand:DI 2 "register_operand" "r")))]
3679 "andn %2,%1,%0\;andn %R2,%R1,%R0"
3680 [(set_attr "length" "2")])
3683 [(set (match_operand:DI 0 "register_operand" "=r")
3684 (and:DI (not:DI (match_operand:DI 1 "register_operand" "r"))
3685 (match_operand:DI 2 "register_operand" "r")))]
3690 [(set (match_operand:SI 0 "register_operand" "=r")
3691 (and:SI (not:SI (match_operand:SI 1 "register_operand" "r"))
3692 (match_operand:SI 2 "register_operand" "r")))]
3695 [(set_attr "type" "ialu")])
3697 (define_expand "iordi3"
3698 [(set (match_operand:DI 0 "register_operand" "")
3699 (ior:DI (match_operand:DI 1 "arith_double_operand" "")
3700 (match_operand:DI 2 "arith_double_operand" "")))]
3705 [(set (match_operand:DI 0 "register_operand" "=r")
3706 (ior:DI (match_operand:DI 1 "arith_double_operand" "%r")
3707 (match_operand:DI 2 "arith_double_operand" "rHI")))]
3711 rtx op2 = operands[2];
3713 /* If constant is positive, upper bits zeroed, otherwise unchanged.
3714 Give the assembler a chance to pick the move instruction. */
3715 if (GET_CODE (op2) == CONST_INT)
3717 int sign = INTVAL (op2);
3719 return \"mov -1,%0\;or %R1,%2,%R0\";
3720 return \"mov %1,%0\;or %R1,%2,%R0\";
3722 else if (GET_CODE (op2) == CONST_DOUBLE)
3725 xoperands[0] = operands[0];
3726 xoperands[1] = operands[1];
3727 xoperands[2] = GEN_INT (CONST_DOUBLE_LOW (op2));
3728 xoperands[3] = GEN_INT (CONST_DOUBLE_HIGH (op2));
3729 /* We could optimize then operands[1] == operands[0]
3730 and either half of the constant is 0. */
3731 output_asm_insn (\"or %R1,%2,%R0\;or %1,%3,%0\", xoperands);
3734 return \"or %1,%2,%0\;or %R1,%R2,%R0\";
3736 [(set_attr "length" "2")])
3739 [(set (match_operand:DI 0 "register_operand" "=r")
3740 (ior:DI (match_operand:DI 1 "arith_double_operand" "%r")
3741 (match_operand:DI 2 "arith_double_operand" "rHI")))]
3745 (define_insn "iorsi3"
3746 [(set (match_operand:SI 0 "register_operand" "=r")
3747 (ior:SI (match_operand:SI 1 "arith_operand" "%r")
3748 (match_operand:SI 2 "arith_operand" "rI")))]
3751 [(set_attr "type" "ialu")])
3754 [(set (match_operand:SI 0 "register_operand" "")
3755 (ior:SI (match_operand:SI 1 "register_operand" "")
3756 (match_operand:SI 2 "" "")))
3757 (clobber (match_operand:SI 3 "register_operand" ""))]
3758 "GET_CODE (operands[2]) == CONST_INT
3759 && !SMALL_INT (operands[2])
3760 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
3761 [(set (match_dup 3) (match_dup 4))
3762 (set (match_dup 0) (ior:SI (not:SI (match_dup 3)) (match_dup 1)))]
3765 operands[4] = gen_rtx (CONST_INT, VOIDmode, ~INTVAL (operands[2]));
3769 [(set (match_operand:DI 0 "register_operand" "=r")
3770 (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r"))
3771 (match_operand:DI 2 "register_operand" "r")))]
3773 "orn %2,%1,%0\;orn %R2,%R1,%R0"
3774 [(set_attr "length" "2")])
3777 [(set (match_operand:DI 0 "register_operand" "=r")
3778 (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r"))
3779 (match_operand:DI 2 "register_operand" "r")))]
3784 [(set (match_operand:SI 0 "register_operand" "=r")
3785 (ior:SI (not:SI (match_operand:SI 1 "register_operand" "r"))
3786 (match_operand:SI 2 "register_operand" "r")))]
3789 [(set_attr "type" "ialu")])
3791 (define_expand "xordi3"
3792 [(set (match_operand:DI 0 "register_operand" "")
3793 (xor:DI (match_operand:DI 1 "arith_double_operand" "")
3794 (match_operand:DI 2 "arith_double_operand" "")))]
3799 [(set (match_operand:DI 0 "register_operand" "=r")
3800 (xor:DI (match_operand:DI 1 "arith_double_operand" "%r")
3801 (match_operand:DI 2 "arith_double_operand" "rHI")))]
3805 rtx op2 = operands[2];
3807 /* If constant is positive, upper bits zeroed, otherwise unchanged.
3808 Give the assembler a chance to pick the move instruction. */
3809 if (GET_CODE (op2) == CONST_INT)
3811 int sign = INTVAL (op2);
3813 return \"xor %1,-1,%0\;xor %R1,%2,%R0\";
3814 return \"mov %1,%0\;xor %R1,%2,%R0\";
3816 else if (GET_CODE (op2) == CONST_DOUBLE)
3819 xoperands[0] = operands[0];
3820 xoperands[1] = operands[1];
3821 xoperands[2] = GEN_INT (CONST_DOUBLE_LOW (op2));
3822 xoperands[3] = GEN_INT (CONST_DOUBLE_HIGH (op2));
3823 /* We could optimize then operands[1] == operands[0]
3824 and either half of the constant is 0. */
3825 output_asm_insn (\"xor %R1,%2,%R0\;xor %1,%3,%0\", xoperands);
3828 return \"xor %1,%2,%0\;xor %R1,%R2,%R0\";
3830 [(set_attr "length" "2")])
3833 [(set (match_operand:DI 0 "register_operand" "=r")
3834 (xor:DI (match_operand:DI 1 "arith_double_operand" "%rJ")
3835 (match_operand:DI 2 "arith_double_operand" "rHI")))]
3839 (define_insn "xorsi3"
3840 [(set (match_operand:SI 0 "register_operand" "=r")
3841 (xor:SI (match_operand:SI 1 "arith_operand" "%rJ")
3842 (match_operand:SI 2 "arith_operand" "rI")))]
3845 [(set_attr "type" "ialu")])
3848 [(set (match_operand:SI 0 "register_operand" "")
3849 (xor:SI (match_operand:SI 1 "register_operand" "")
3850 (match_operand:SI 2 "" "")))
3851 (clobber (match_operand:SI 3 "register_operand" ""))]
3852 "GET_CODE (operands[2]) == CONST_INT
3853 && !SMALL_INT (operands[2])
3854 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
3855 [(set (match_dup 3) (match_dup 4))
3856 (set (match_dup 0) (not:SI (xor:SI (match_dup 3) (match_dup 1))))]
3859 operands[4] = gen_rtx (CONST_INT, VOIDmode, ~INTVAL (operands[2]));
3863 [(set (match_operand:SI 0 "register_operand" "")
3864 (not:SI (xor:SI (match_operand:SI 1 "register_operand" "")
3865 (match_operand:SI 2 "" ""))))
3866 (clobber (match_operand:SI 3 "register_operand" ""))]
3867 "GET_CODE (operands[2]) == CONST_INT
3868 && !SMALL_INT (operands[2])
3869 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
3870 [(set (match_dup 3) (match_dup 4))
3871 (set (match_dup 0) (xor:SI (match_dup 3) (match_dup 1)))]
3874 operands[4] = gen_rtx (CONST_INT, VOIDmode, ~INTVAL (operands[2]));
3877 ;; xnor patterns. Note that (a ^ ~b) == (~a ^ b) == ~(a ^ b).
3878 ;; Combine now canonicalizes to the rightmost expression.
3880 [(set (match_operand:DI 0 "register_operand" "=r")
3881 (not:DI (xor:DI (match_operand:DI 1 "register_operand" "r")
3882 (match_operand:DI 2 "register_operand" "r"))))]
3884 "xnor %1,%2,%0\;xnor %R1,%R2,%R0"
3885 [(set_attr "length" "2")])
3888 [(set (match_operand:DI 0 "register_operand" "=r")
3889 (not:DI (xor:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
3890 (match_operand:DI 2 "arith_double_operand" "rHI"))))]
3895 [(set (match_operand:SI 0 "register_operand" "=r")
3896 (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
3897 (match_operand:SI 2 "arith_operand" "rI"))))]
3900 [(set_attr "type" "ialu")])
3902 ;; These correspond to the above in the case where we also (or only)
3903 ;; want to set the condition code.
3908 (match_operator:SI 2 "cc_arithop"
3909 [(match_operand:SI 0 "arith_operand" "%r")
3910 (match_operand:SI 1 "arith_operand" "rI")])
3914 [(set_attr "type" "compare")])
3919 (match_operator:DI 2 "cc_arithop"
3920 [(match_operand:DI 0 "arith_double_operand" "%r")
3921 (match_operand:DI 1 "arith_double_operand" "rHI")])
3925 [(set_attr "type" "compare")])
3930 (match_operator:SI 3 "cc_arithop"
3931 [(match_operand:SI 1 "arith_operand" "%r")
3932 (match_operand:SI 2 "arith_operand" "rI")])
3934 (set (match_operand:SI 0 "register_operand" "=r")
3942 (match_operator:DI 3 "cc_arithop"
3943 [(match_operand:DI 1 "arith_double_operand" "%r")
3944 (match_operand:DI 2 "arith_double_operand" "rHI")])
3946 (set (match_operand:DI 0 "register_operand" "=r")
3954 (not:SI (xor:SI (match_operand:SI 0 "reg_or_0_operand" "%rJ")
3955 (match_operand:SI 1 "arith_operand" "rI")))
3958 "xnorcc %r0,%1,%%g0"
3959 [(set_attr "type" "compare")])
3964 (not:DI (xor:DI (match_operand:DI 0 "reg_or_0_operand" "%rJ")
3965 (match_operand:DI 1 "arith_double_operand" "rHI")))
3968 "xnorcc %r0,%1,%%g0"
3969 [(set_attr "type" "compare")])
3974 (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
3975 (match_operand:SI 2 "arith_operand" "rI")))
3977 (set (match_operand:SI 0 "register_operand" "=r")
3978 (not:SI (xor:SI (match_dup 1) (match_dup 2))))]
3985 (not:DI (xor:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ")
3986 (match_operand:DI 2 "arith_double_operand" "rHI")))
3988 (set (match_operand:DI 0 "register_operand" "=r")
3989 (not:DI (xor:DI (match_dup 1) (match_dup 2))))]
3996 (match_operator:SI 2 "cc_arithopn"
3997 [(not:SI (match_operand:SI 0 "arith_operand" "rI"))
3998 (match_operand:SI 1 "reg_or_0_operand" "rJ")])
4002 [(set_attr "type" "compare")])
4007 (match_operator:DI 2 "cc_arithopn"
4008 [(not:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
4009 (match_operand:DI 1 "reg_or_0_operand" "rJ")])
4013 [(set_attr "type" "compare")])
4018 (match_operator:SI 3 "cc_arithopn"
4019 [(not:SI (match_operand:SI 1 "arith_operand" "rI"))
4020 (match_operand:SI 2 "reg_or_0_operand" "rJ")])
4022 (set (match_operand:SI 0 "register_operand" "=r")
4030 (match_operator:DI 3 "cc_arithopn"
4031 [(not:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
4032 (match_operand:DI 2 "reg_or_0_operand" "rJ")])
4034 (set (match_operand:DI 0 "register_operand" "=r")
4039 ;; We cannot use the "neg" pseudo insn because the Sun assembler
4040 ;; does not know how to make it work for constants.
4042 (define_expand "negdi2"
4043 [(set (match_operand:DI 0 "register_operand" "=r")
4044 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
4050 emit_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (2,
4051 gen_rtx (SET, VOIDmode, operand0,
4052 gen_rtx (NEG, DImode, operand1)),
4053 gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, 0)))));
4059 [(set (match_operand:DI 0 "register_operand" "=r")
4060 (neg:DI (match_operand:DI 1 "register_operand" "r")))
4061 (clobber (reg:SI 0))]
4063 "subcc %%g0,%R1,%R0\;subx %%g0,%1,%0"
4064 [(set_attr "type" "unary")
4065 (set_attr "length" "2")])
4068 [(set (match_operand:DI 0 "register_operand" "=r")
4069 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
4072 [(set_attr "type" "unary")
4073 (set_attr "length" "1")])
4075 (define_insn "negsi2"
4076 [(set (match_operand:SI 0 "register_operand" "=r")
4077 (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
4080 [(set_attr "type" "unary")])
4083 [(set (reg:CC_NOOV 0)
4084 (compare:CC_NOOV (neg:SI (match_operand:SI 0 "arith_operand" "rI"))
4087 "subcc %%g0,%0,%%g0"
4088 [(set_attr "type" "compare")])
4091 [(set (reg:CCX_NOOV 0)
4092 (compare:CCX_NOOV (neg:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
4095 "subcc %%g0,%0,%%g0"
4096 [(set_attr "type" "compare")])
4099 [(set (reg:CC_NOOV 0)
4100 (compare:CC_NOOV (neg:SI (match_operand:SI 1 "arith_operand" "rI"))
4102 (set (match_operand:SI 0 "register_operand" "=r")
4103 (neg:SI (match_dup 1)))]
4106 [(set_attr "type" "unary")])
4109 [(set (reg:CCX_NOOV 0)
4110 (compare:CCX_NOOV (neg:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
4112 (set (match_operand:DI 0 "register_operand" "=r")
4113 (neg:DI (match_dup 1)))]
4116 [(set_attr "type" "unary")])
4118 ;; We cannot use the "not" pseudo insn because the Sun assembler
4119 ;; does not know how to make it work for constants.
4120 (define_expand "one_cmpldi2"
4121 [(set (match_operand:DI 0 "register_operand" "")
4122 (not:DI (match_operand:DI 1 "register_operand" "")))]
4127 [(set (match_operand:DI 0 "register_operand" "=r")
4128 (not:DI (match_operand:DI 1 "register_operand" "r")))]
4130 "xnor %%g0,%1,%0\;xnor %%g0,%R1,%R0"
4131 [(set_attr "type" "unary")
4132 (set_attr "length" "2")])
4135 [(set (match_operand:DI 0 "register_operand" "=r")
4136 (not:DI (match_operand:DI 1 "arith_double_operand" "rHI")))]
4139 [(set_attr "type" "unary")])
4141 (define_insn "one_cmplsi2"
4142 [(set (match_operand:SI 0 "register_operand" "=r")
4143 (not:SI (match_operand:SI 1 "arith_operand" "rI")))]
4146 [(set_attr "type" "unary")])
4150 (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI"))
4153 "xnorcc %%g0,%0,%%g0"
4154 [(set_attr "type" "compare")])
4158 (compare:CCX (not:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
4161 "xnorcc %%g0,%0,%%g0"
4162 [(set_attr "type" "compare")])
4166 (compare:CC (not:SI (match_operand:SI 1 "arith_operand" "rI"))
4168 (set (match_operand:SI 0 "register_operand" "=r")
4169 (not:SI (match_dup 1)))]
4172 [(set_attr "type" "unary")])
4176 (compare:CCX (not:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
4178 (set (match_operand:DI 0 "register_operand" "=r")
4179 (not:DI (match_dup 1)))]
4182 [(set_attr "type" "unary")])
4184 ;; Floating point arithmetic instructions.
4186 (define_insn "addtf3"
4187 [(set (match_operand:TF 0 "register_operand" "=e")
4188 (plus:TF (match_operand:TF 1 "register_operand" "e")
4189 (match_operand:TF 2 "register_operand" "e")))]
4190 "TARGET_FPU && TARGET_HARD_QUAD"
4192 [(set_attr "type" "fp")])
4194 (define_insn "adddf3"
4195 [(set (match_operand:DF 0 "register_operand" "=e")
4196 (plus:DF (match_operand:DF 1 "register_operand" "e")
4197 (match_operand:DF 2 "register_operand" "e")))]
4200 [(set_attr "type" "fp")])
4202 (define_insn "addsf3"
4203 [(set (match_operand:SF 0 "register_operand" "=f")
4204 (plus:SF (match_operand:SF 1 "register_operand" "f")
4205 (match_operand:SF 2 "register_operand" "f")))]
4208 [(set_attr "type" "fp")])
4210 (define_insn "subtf3"
4211 [(set (match_operand:TF 0 "register_operand" "=e")
4212 (minus:TF (match_operand:TF 1 "register_operand" "e")
4213 (match_operand:TF 2 "register_operand" "e")))]
4214 "TARGET_FPU && TARGET_HARD_QUAD"
4216 [(set_attr "type" "fp")])
4218 (define_insn "subdf3"
4219 [(set (match_operand:DF 0 "register_operand" "=e")
4220 (minus:DF (match_operand:DF 1 "register_operand" "e")
4221 (match_operand:DF 2 "register_operand" "e")))]
4224 [(set_attr "type" "fp")])
4226 (define_insn "subsf3"
4227 [(set (match_operand:SF 0 "register_operand" "=f")
4228 (minus:SF (match_operand:SF 1 "register_operand" "f")
4229 (match_operand:SF 2 "register_operand" "f")))]
4232 [(set_attr "type" "fp")])
4234 (define_insn "multf3"
4235 [(set (match_operand:TF 0 "register_operand" "=e")
4236 (mult:TF (match_operand:TF 1 "register_operand" "e")
4237 (match_operand:TF 2 "register_operand" "e")))]
4238 "TARGET_FPU && TARGET_HARD_QUAD"
4240 [(set_attr "type" "fpmul")])
4242 (define_insn "muldf3"
4243 [(set (match_operand:DF 0 "register_operand" "=e")
4244 (mult:DF (match_operand:DF 1 "register_operand" "e")
4245 (match_operand:DF 2 "register_operand" "e")))]
4248 [(set_attr "type" "fpmul")])
4250 (define_insn "mulsf3"
4251 [(set (match_operand:SF 0 "register_operand" "=f")
4252 (mult:SF (match_operand:SF 1 "register_operand" "f")
4253 (match_operand:SF 2 "register_operand" "f")))]
4256 [(set_attr "type" "fpmul")])
4259 [(set (match_operand:DF 0 "register_operand" "=e")
4260 (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "f"))
4261 (float_extend:DF (match_operand:SF 2 "register_operand" "f"))))]
4262 "(TARGET_V8 || TARGET_V9) && TARGET_FPU"
4264 [(set_attr "type" "fpmul")])
4267 [(set (match_operand:TF 0 "register_operand" "=e")
4268 (mult:TF (float_extend:TF (match_operand:DF 1 "register_operand" "e"))
4269 (float_extend:TF (match_operand:DF 2 "register_operand" "e"))))]
4270 "(TARGET_V8 || TARGET_V9) && TARGET_FPU"
4272 [(set_attr "type" "fpmul")])
4274 ;; don't have timing for quad-prec. divide.
4275 (define_insn "divtf3"
4276 [(set (match_operand:TF 0 "register_operand" "=e")
4277 (div:TF (match_operand:TF 1 "register_operand" "e")
4278 (match_operand:TF 2 "register_operand" "e")))]
4279 "TARGET_FPU && TARGET_HARD_QUAD"
4281 [(set_attr "type" "fpdivd")])
4283 (define_insn "divdf3"
4284 [(set (match_operand:DF 0 "register_operand" "=e")
4285 (div:DF (match_operand:DF 1 "register_operand" "e")
4286 (match_operand:DF 2 "register_operand" "e")))]
4289 [(set_attr "type" "fpdivd")])
4291 (define_insn "divsf3"
4292 [(set (match_operand:SF 0 "register_operand" "=f")
4293 (div:SF (match_operand:SF 1 "register_operand" "f")
4294 (match_operand:SF 2 "register_operand" "f")))]
4297 [(set_attr "type" "fpdivs")])
4299 (define_insn "negtf2"
4300 [(set (match_operand:TF 0 "register_operand" "=e,e")
4301 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
4306 return \"fnegd %1,%0\"; /* Can't use fnegs, won't work with upper regs. */
4307 else if (which_alternative == 0)
4308 return \"fnegs %0,%0\";
4310 return \"fnegs %1,%0\;fmovs %R1,%R0\;fmovs %S1,%S0\;fmovs %T1,%T0\";
4312 [(set_attr "type" "fp")
4313 (set_attr_alternative "length"
4315 (if_then_else (eq_attr "arch" "arch32bit") (const_int 4) (const_int 1))])])
4317 (define_insn "negdf2"
4318 [(set (match_operand:DF 0 "register_operand" "=e,e")
4319 (neg:DF (match_operand:DF 1 "register_operand" "0,e")))]
4324 return \"fnegd %1,%0\";
4325 else if (which_alternative == 0)
4326 return \"fnegs %0,%0\";
4328 return \"fnegs %1,%0\;fmovs %R1,%R0\";
4330 [(set_attr "type" "fp")
4331 (set_attr_alternative "length"
4333 (if_then_else (eq_attr "arch" "arch32bit") (const_int 2) (const_int 1))])])
4335 (define_insn "negsf2"
4336 [(set (match_operand:SF 0 "register_operand" "=f")
4337 (neg:SF (match_operand:SF 1 "register_operand" "f")))]
4340 [(set_attr "type" "fp")])
4342 (define_insn "abstf2"
4343 [(set (match_operand:TF 0 "register_operand" "=e,e")
4344 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
4349 return \"fabsd %1,%0\"; /* Can't use fabss, won't work with upper regs. */
4350 else if (which_alternative == 0)
4351 return \"fabss %0,%0\";
4353 return \"fabss %1,%0\;fmovs %R1,%R0\;fmovs %S1,%S0\;fmovs %T1,%T0\";
4355 [(set_attr "type" "fp")
4356 (set_attr_alternative "length"
4358 (if_then_else (eq_attr "arch" "arch32bit") (const_int 4) (const_int 1))])])
4360 (define_insn "absdf2"
4361 [(set (match_operand:DF 0 "register_operand" "=e,e")
4362 (abs:DF (match_operand:DF 1 "register_operand" "0,e")))]
4367 return \"fabsd %1,%0\";
4368 else if (which_alternative == 0)
4369 return \"fabss %0,%0\";
4371 return \"fabss %1,%0\;fmovs %R1,%R0\";
4373 [(set_attr "type" "fp")
4374 (set_attr_alternative "length"
4376 (if_then_else (eq_attr "arch" "arch32bit") (const_int 2) (const_int 1))])])
4378 (define_insn "abssf2"
4379 [(set (match_operand:SF 0 "register_operand" "=f")
4380 (abs:SF (match_operand:SF 1 "register_operand" "f")))]
4383 [(set_attr "type" "fp")])
4385 (define_insn "sqrttf2"
4386 [(set (match_operand:TF 0 "register_operand" "=e")
4387 (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
4388 "TARGET_FPU && TARGET_HARD_QUAD"
4390 [(set_attr "type" "fpsqrt")])
4392 (define_insn "sqrtdf2"
4393 [(set (match_operand:DF 0 "register_operand" "=e")
4394 (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
4397 [(set_attr "type" "fpsqrt")])
4399 (define_insn "sqrtsf2"
4400 [(set (match_operand:SF 0 "register_operand" "=f")
4401 (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
4404 [(set_attr "type" "fpsqrt")])
4406 ;;- arithmetic shift instructions
4408 (define_insn "ashlsi3"
4409 [(set (match_operand:SI 0 "register_operand" "=r")
4410 (ashift:SI (match_operand:SI 1 "register_operand" "r")
4411 (match_operand:SI 2 "arith_operand" "rI")))]
4415 if (GET_CODE (operands[2]) == CONST_INT
4416 && (unsigned) INTVAL (operands[2]) > 31)
4417 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
4419 return \"sll %1,%2,%0\";
4421 [(set_attr "type" "shift")])
4423 (define_insn "ashldi3"
4424 [(set (match_operand:DI 0 "register_operand" "=r")
4425 (ashift:DI (match_operand:DI 1 "register_operand" "r")
4426 (match_operand:SI 2 "arith_operand" "rI")))]
4430 if (GET_CODE (operands[2]) == CONST_INT
4431 && (unsigned) INTVAL (operands[2]) > 63)
4432 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
4434 return \"sllx %1,%2,%0\";
4438 [(set (reg:CC_NOOV 0)
4439 (compare:CC_NOOV (ashift:SI (match_operand:SI 0 "register_operand" "r")
4444 [(set_attr "type" "compare")])
4447 [(set (reg:CC_NOOV 0)
4448 (compare:CC_NOOV (ashift:SI (match_operand:SI 1 "register_operand" "r")
4451 (set (match_operand:SI 0 "register_operand" "=r")
4452 (ashift:SI (match_dup 1) (const_int 1)))]
4456 (define_insn "ashrsi3"
4457 [(set (match_operand:SI 0 "register_operand" "=r")
4458 (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
4459 (match_operand:SI 2 "arith_operand" "rI")))]
4463 if (GET_CODE (operands[2]) == CONST_INT
4464 && (unsigned) INTVAL (operands[2]) > 31)
4465 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
4467 return \"sra %1,%2,%0\";
4469 [(set_attr "type" "shift")])
4471 (define_insn "ashrdi3"
4472 [(set (match_operand:DI 0 "register_operand" "=r")
4473 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
4474 (match_operand:SI 2 "arith_operand" "rI")))]
4478 if (GET_CODE (operands[2]) == CONST_INT
4479 && (unsigned) INTVAL (operands[2]) > 63)
4480 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
4482 return \"srax %1,%2,%0\";
4485 (define_insn "lshrsi3"
4486 [(set (match_operand:SI 0 "register_operand" "=r")
4487 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
4488 (match_operand:SI 2 "arith_operand" "rI")))]
4492 if (GET_CODE (operands[2]) == CONST_INT
4493 && (unsigned) INTVAL (operands[2]) > 31)
4494 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
4496 return \"srl %1,%2,%0\";
4498 [(set_attr "type" "shift")])
4500 (define_insn "lshrdi3"
4501 [(set (match_operand:DI 0 "register_operand" "=r")
4502 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
4503 (match_operand:SI 2 "arith_operand" "rI")))]
4507 if (GET_CODE (operands[2]) == CONST_INT
4508 && (unsigned) INTVAL (operands[2]) > 63)
4509 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
4511 return \"srlx %1,%2,%0\";
4514 ;; Unconditional and other jump instructions
4515 ;; On the Sparc, by setting the annul bit on an unconditional branch, the
4516 ;; following insn is never executed. This saves us a nop. Dbx does not
4517 ;; handle such branches though, so we only use them when optimizing.
4519 [(set (pc) (label_ref (match_operand 0 "" "")))]
4522 [(set_attr "type" "uncond_branch")])
4524 (define_expand "tablejump"
4525 [(parallel [(set (pc) (match_operand 0 "register_operand" "r"))
4526 (use (label_ref (match_operand 1 "" "")))])]
4530 if (GET_MODE (operands[0]) != Pmode)
4533 /* We need to use the PC value in %o7 that was set up when the address
4534 of the label was loaded into a register, so we need different RTL. */
4538 emit_jump_insn (gen_pic_tablejump_32 (operands[0], operands[1]));
4540 emit_jump_insn (gen_pic_tablejump_64 (operands[0], operands[1]));
4545 (define_insn "pic_tablejump_32"
4546 [(set (pc) (match_operand:SI 0 "register_operand" "r"))
4547 (use (label_ref (match_operand 1 "" "")))
4551 [(set_attr "type" "uncond_branch")])
4553 (define_insn "pic_tablejump_64"
4554 [(set (pc) (match_operand:DI 0 "register_operand" "r"))
4555 (use (label_ref (match_operand 1 "" "")))
4559 [(set_attr "type" "uncond_branch")])
4562 [(set (pc) (match_operand:SI 0 "address_operand" "p"))
4563 (use (label_ref (match_operand 1 "" "")))]
4566 [(set_attr "type" "uncond_branch")])
4569 [(set (pc) (match_operand:DI 0 "address_operand" "p"))
4570 (use (label_ref (match_operand 1 "" "")))]
4573 [(set_attr "type" "uncond_branch")])
4576 [(set (pc) (label_ref (match_operand 0 "" "")))
4577 (set (reg:SI 15) (label_ref (match_dup 0)))]
4580 [(set_attr "type" "uncond_branch")])
4583 [(set (pc) (label_ref (match_operand 0 "" "")))
4584 (set (reg:DI 15) (label_ref (match_dup 0)))]
4587 [(set_attr "type" "uncond_branch")])
4589 ;; This pattern recognizes the "instruction" that appears in
4590 ;; a function call that wants a structure value,
4591 ;; to inform the called function if compiled with Sun CC.
4593 ; [(match_operand:SI 0 "immediate_operand" "")]
4594 ; "GET_CODE (operands[0]) == CONST_INT && INTVAL (operands[0]) > 0"
4596 ; [(set_attr "type" "marker")])
4598 ;;- jump to subroutine
4599 (define_expand "call"
4600 ;; Note that this expression is not used for generating RTL.
4601 ;; All the RTL is generated explicitly below.
4602 [(call (match_operand 0 "call_operand" "")
4603 (match_operand 3 "" "i"))]
4604 ;; operands[2] is next_arg_register
4605 ;; operands[3] is struct_value_size_rtx.
4609 rtx fn_rtx, nregs_rtx;
4611 if (GET_MODE (operands[0]) != FUNCTION_MODE)
4614 if (GET_CODE (XEXP (operands[0], 0)) == LABEL_REF)
4616 /* This is really a PIC sequence. We want to represent
4617 it as a funny jump so it's delay slots can be filled.
4619 ??? But if this really *is* a CALL, will not it clobber the
4620 call-clobbered registers? We lose this if it is a JUMP_INSN.
4621 Why cannot we have delay slots filled if it were a CALL? */
4623 if (! TARGET_V9 && INTVAL (operands[3]) != 0)
4624 emit_jump_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (3,
4625 gen_rtx (SET, VOIDmode, pc_rtx,
4626 XEXP (operands[0], 0)),
4628 gen_rtx (CLOBBER, VOIDmode,
4629 gen_rtx (REG, Pmode, 15)))));
4631 emit_jump_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (2,
4632 gen_rtx (SET, VOIDmode, pc_rtx,
4633 XEXP (operands[0], 0)),
4634 gen_rtx (CLOBBER, VOIDmode,
4635 gen_rtx (REG, Pmode, 15)))));
4639 fn_rtx = operands[0];
4641 /* Count the number of parameter registers being used by this call.
4642 if that argument is NULL, it means we are using them all, which
4643 means 6 on the sparc. */
4646 nregs_rtx = gen_rtx (CONST_INT, VOIDmode, REGNO (operands[2]) - 8);
4648 nregs_rtx = gen_rtx (CONST_INT, VOIDmode, 6);
4650 nregs_rtx = const0_rtx;
4653 if (! TARGET_V9 && INTVAL (operands[3]) != 0)
4654 emit_call_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (3,
4655 gen_rtx (CALL, VOIDmode, fn_rtx, nregs_rtx),
4657 gen_rtx (CLOBBER, VOIDmode,
4658 gen_rtx (REG, Pmode, 15)))));
4660 emit_call_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (2,
4661 gen_rtx (CALL, VOIDmode, fn_rtx, nregs_rtx),
4662 gen_rtx (CLOBBER, VOIDmode,
4663 gen_rtx (REG, Pmode, 15)))));
4667 /* If this call wants a structure value,
4668 emit an unimp insn to let the called function know about this. */
4669 if (! TARGET_V9 && INTVAL (operands[3]) > 0)
4671 rtx insn = emit_insn (operands[3]);
4672 SCHED_GROUP_P (insn) = 1;
4679 ;; We can't use the same pattern for these two insns, because then registers
4680 ;; in the address may not be properly reloaded.
4683 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
4684 (match_operand 1 "" ""))
4685 (clobber (reg:SI 15))]
4686 ;;- Do not use operand 1 for most machines.
4690 return \"call %a0,%1%#\";
4692 [(set_attr "type" "call")])
4695 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
4696 (match_operand 1 "" ""))
4697 (clobber (reg:SI 15))]
4698 ;;- Do not use operand 1 for most machines.
4702 return \"call %a0,%1%#\";
4704 [(set_attr "type" "call")])
4707 [(call (mem:SI (match_operand:DI 0 "address_operand" "p"))
4708 (match_operand 1 "" ""))
4709 (clobber (reg:DI 15))]
4710 ;;- Do not use operand 1 for most machines.
4714 return \"call %a0,%1%#\";
4716 [(set_attr "type" "call")])
4719 [(call (mem:SI (match_operand:DI 0 "symbolic_operand" "s"))
4720 (match_operand 1 "" ""))
4721 (clobber (reg:DI 15))]
4722 ;;- Do not use operand 1 for most machines.
4726 return \"call %a0,%1%#\";
4728 [(set_attr "type" "call")])
4730 ;; This is a call that wants a structure value.
4731 ;; There is no such critter for v9 (??? we may need one anyway).
4733 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
4734 (match_operand 1 "" ""))
4735 (match_operand 2 "immediate_operand" "")
4736 (clobber (reg:SI 15))]
4737 ;;- Do not use operand 1 for most machines.
4738 "! TARGET_V9 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
4741 return \"call %a0,%1\;nop\;unimp %2\";
4743 [(set_attr "type" "call_no_delay_slot")])
4745 ;; This is a call that wants a structure value.
4746 ;; There is no such critter for v9 (??? we may need one anyway).
4748 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
4749 (match_operand 1 "" ""))
4750 (match_operand 2 "immediate_operand" "")
4751 (clobber (reg:SI 15))]
4752 ;;- Do not use operand 1 for most machines.
4753 "! TARGET_V9 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
4756 return \"call %a0,%1\;nop\;unimp %2\";
4758 [(set_attr "type" "call_no_delay_slot")])
4760 ;; This is a call that may want a structure value. This is used for
4763 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
4764 (match_operand 1 "" ""))
4765 (match_operand 2 "immediate_operand" "")
4766 (clobber (reg:SI 15))]
4767 ;;- Do not use operand 1 for most machines.
4768 "! TARGET_V9 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
4771 return \"call %a0,%1\;nop\;nop\";
4773 [(set_attr "type" "call_no_delay_slot")])
4775 ;; This is a call that wants a structure value.
4777 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
4778 (match_operand 1 "" ""))
4779 (match_operand 2 "immediate_operand" "")
4780 (clobber (reg:SI 15))]
4781 ;;- Do not use operand 1 for most machines.
4782 "! TARGET_V9 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
4785 return \"call %a0,%1\;nop\;nop\";
4787 [(set_attr "type" "call_no_delay_slot")])
4789 (define_expand "call_value"
4790 ;; Note that this expression is not used for generating RTL.
4791 ;; All the RTL is generated explicitly below.
4792 [(set (match_operand 0 "register_operand" "=rf")
4793 (call (match_operand:SI 1 "" "")
4794 (match_operand 4 "" "")))]
4795 ;; operand 2 is stack_size_rtx
4796 ;; operand 3 is next_arg_register
4800 rtx fn_rtx, nregs_rtx;
4803 if (GET_MODE (operands[1]) != FUNCTION_MODE)
4806 fn_rtx = operands[1];
4810 nregs_rtx = gen_rtx (CONST_INT, VOIDmode, REGNO (operands[3]) - 8);
4812 nregs_rtx = gen_rtx (CONST_INT, VOIDmode, 6);
4814 nregs_rtx = const0_rtx;
4818 gen_rtx (SET, VOIDmode, operands[0],
4819 gen_rtx (CALL, VOIDmode, fn_rtx, nregs_rtx)),
4820 gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, Pmode, 15)));
4822 emit_call_insn (gen_rtx (PARALLEL, VOIDmode, vec));
4828 [(set (match_operand 0 "" "=rf")
4829 (call (mem:SI (match_operand:SI 1 "address_operand" "p"))
4830 (match_operand 2 "" "")))
4831 (clobber (reg:SI 15))]
4832 ;;- Do not use operand 2 for most machines.
4836 return \"call %a1,%2%#\";
4838 [(set_attr "type" "call")])
4841 [(set (match_operand 0 "" "=rf")
4842 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
4843 (match_operand 2 "" "")))
4844 (clobber (reg:SI 15))]
4845 ;;- Do not use operand 2 for most machines.
4849 return \"call %a1,%2%#\";
4851 [(set_attr "type" "call")])
4854 [(set (match_operand 0 "" "=rf")
4855 (call (mem:SI (match_operand:DI 1 "address_operand" "p"))
4856 (match_operand 2 "" "")))
4857 (clobber (reg:DI 15))]
4858 ;;- Do not use operand 2 for most machines.
4862 return \"call %a1,%2%#\";
4864 [(set_attr "type" "call")])
4867 [(set (match_operand 0 "" "=rf")
4868 (call (mem:SI (match_operand:DI 1 "symbolic_operand" "s"))
4869 (match_operand 2 "" "")))
4870 (clobber (reg:DI 15))]
4871 ;;- Do not use operand 2 for most machines.
4875 return \"call %a1,%2%#\";
4877 [(set_attr "type" "call")])
4879 (define_expand "untyped_call"
4880 [(parallel [(call (match_operand 0 "" "")
4882 (match_operand 1 "" "")
4883 (match_operand 2 "" "")])]
4889 /* Pass constm1 to indicate that it may expect a structure value, but
4890 we don't know what size it is. */
4891 emit_call_insn (gen_call (operands[0], const0_rtx, NULL, constm1_rtx));
4893 for (i = 0; i < XVECLEN (operands[2], 0); i++)
4895 rtx set = XVECEXP (operands[2], 0, i);
4896 emit_move_insn (SET_DEST (set), SET_SRC (set));
4899 /* The optimizer does not know that the call sets the function value
4900 registers we stored in the result block. We avoid problems by
4901 claiming that all hard registers are used and clobbered at this
4903 emit_insn (gen_blockage ());
4908 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
4909 ;; all of memory. This blocks insns from being moved across this point.
4911 (define_insn "blockage"
4912 [(unspec_volatile [(const_int 0)] 0)]
4916 ;; Prepare to return any type including a structure value.
4918 (define_expand "untyped_return"
4919 [(match_operand:BLK 0 "memory_operand" "")
4920 (match_operand 1 "" "")]
4924 rtx valreg1 = gen_rtx (REG, DImode, 24);
4925 rtx valreg2 = gen_rtx (REG, TARGET_V9 ? TFmode : DFmode, 32);
4926 rtx result = operands[0];
4930 rtx rtnreg = gen_rtx (REG, SImode, (leaf_function ? 15 : 31));
4931 rtx value = gen_reg_rtx (SImode);
4933 /* Fetch the instruction where we will return to and see if it's an unimp
4934 instruction (the most significant 10 bits will be zero). If so,
4935 update the return address to skip the unimp instruction. */
4936 emit_move_insn (value,
4937 gen_rtx (MEM, SImode, plus_constant (rtnreg, 8)));
4938 emit_insn (gen_lshrsi3 (value, value, GEN_INT (22)));
4939 emit_insn (gen_update_return (rtnreg, value));
4942 /* Reload the function value registers. */
4943 emit_move_insn (valreg1, change_address (result, DImode, XEXP (result, 0)));
4944 emit_move_insn (valreg2,
4945 change_address (result, TARGET_V9 ? TFmode : DFmode,
4946 plus_constant (XEXP (result, 0), 8)));
4948 /* Put USE insns before the return. */
4949 emit_insn (gen_rtx (USE, VOIDmode, valreg1));
4950 emit_insn (gen_rtx (USE, VOIDmode, valreg2));
4952 /* Construct the return. */
4953 expand_null_return ();
4958 ;; This is a bit of a hack. We're incrementing a fixed register (%i7),
4959 ;; and parts of the compiler don't want to believe that the add is needed.
4961 (define_insn "update_return"
4962 [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
4963 (match_operand:SI 1 "register_operand" "r")] 0)]
4965 "cmp %1,0\;be,a .+8\;add %0,4,%0"
4966 [(set_attr "type" "multi")])
4968 (define_insn "return"
4971 "* return output_return (operands);"
4972 [(set_attr "type" "multi")])
4979 (define_expand "indirect_jump"
4980 [(set (pc) (match_operand 0 "address_operand" "p"))]
4985 [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
4988 [(set_attr "type" "uncond_branch")])
4991 [(set (pc) (match_operand:DI 0 "address_operand" "p"))]
4994 [(set_attr "type" "uncond_branch")])
4996 ;; ??? This doesn't handle v9 yet. It also doesn't work with -mflat.
4997 (define_expand "nonlocal_goto"
4998 [(match_operand:SI 0 "general_operand" "")
4999 (match_operand:SI 1 "general_operand" "")
5000 (match_operand:SI 2 "general_operand" "")
5001 (match_operand:SI 3 "" "")]
5005 /* Trap instruction to flush all the register windows. */
5006 emit_insn (gen_flush_register_windows ());
5007 /* Load the fp value for the containing fn into %fp.
5008 This is needed because operands[2] refers to %fp.
5009 Virtual register instantiation fails if the virtual %fp isn't set from a
5010 register. Thus we must copy operands[0] into a register if it isn't
5012 if (GET_CODE (operands[0]) != REG)
5013 operands[0] = force_reg (SImode, operands[0]);
5014 emit_move_insn (virtual_stack_vars_rtx, operands[0]);
5015 /* Find the containing function's current nonlocal goto handler,
5016 which will do any cleanups and then jump to the label. */
5017 emit_move_insn (gen_rtx (REG, SImode, 8), operands[1]);
5018 /* Restore %fp from stack pointer value for containing function.
5019 The restore insn that follows will move this to %sp,
5020 and reload the appropriate value into %fp. */
5021 emit_move_insn (frame_pointer_rtx, operands[2]);
5022 /* Put in the static chain register the nonlocal label address. */
5023 emit_move_insn (static_chain_rtx, operands[3]);
5024 /* USE of frame_pointer_rtx added for consistency; not clear if
5026 emit_insn (gen_rtx (USE, VOIDmode, frame_pointer_rtx));
5027 emit_insn (gen_rtx (USE, VOIDmode, stack_pointer_rtx));
5028 emit_insn (gen_rtx (USE, VOIDmode, static_chain_rtx));
5029 emit_insn (gen_rtx (USE, VOIDmode, gen_rtx (REG, SImode, 8)));
5030 /* Return, restoring reg window and jumping to goto handler. */
5031 emit_insn (gen_goto_handler_and_restore ());
5035 ;; Special trap insn to flush register windows.
5036 (define_insn "flush_register_windows"
5037 [(unspec_volatile [(const_int 0)] 1)]
5039 "* return TARGET_V9 ? \"flushw\" : \"ta 3\";"
5040 [(set_attr "type" "misc")])
5042 (define_insn "goto_handler_and_restore"
5043 [(unspec_volatile [(const_int 0)] 2)]
5045 "jmp %%o0+0\;restore"
5046 [(set_attr "type" "misc")
5047 (set_attr "length" "2")])
5049 ;; Special pattern for the FLUSH instruction.
5051 (define_insn "flush"
5052 [(unspec_volatile [(match_operand 0 "" "")] 3)]
5054 "* return TARGET_V9 ? \"flush %a0\" : \"iflush %a0\";"
5055 [(set_attr "type" "misc")])
5059 ;; The scan instruction searches from the most significant bit while ffs
5060 ;; searches from the least significant bit. The bit index and treatment of
5061 ;; zero also differ. It takes at least 7 instructions to get the proper
5062 ;; result. Here is an obvious 8 instruction seequence.
5064 (define_insn "ffssi2"
5065 [(set (match_operand:SI 0 "register_operand" "=&r")
5066 (ffs:SI (match_operand:SI 1 "register_operand" "r")))
5067 (clobber (match_scratch:SI 2 "=&r"))]
5069 "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"
5070 [(set_attr "type" "multi")
5071 (set_attr "length" "8")])
5073 ;; ??? This should be a define expand, so that the extra instruction have
5074 ;; a chance of being optimized away.
5076 (define_insn "ffsdi2"
5077 [(set (match_operand:DI 0 "register_operand" "=&r")
5078 (ffs:DI (match_operand:DI 1 "register_operand" "r")))
5079 (clobber (match_scratch:DI 2 "=&r"))]
5081 "neg %1,%2\;not %2,%2\;xor %1,%2,%2\;popc %2,%0\;movrz %1,%%g0,%0"
5082 [(set_attr "type" "multi")
5083 (set_attr "length" "5")])
5085 ;; Split up troublesome insns for better scheduling. */
5087 ;; The following patterns are straightforward. They can be applied
5088 ;; either before or after register allocation.
5091 [(set (match_operator 0 "memop" [(match_operand:SI 1 "symbolic_operand" "")])
5092 (match_operand 2 "reg_or_0_operand" ""))
5093 (clobber (match_operand:SI 3 "register_operand" ""))]
5095 [(set (match_dup 3) (high:SI (match_dup 1)))
5096 (set (match_op_dup 0 [(lo_sum:SI (match_dup 3) (match_dup 1))])
5101 [(set (match_operator 0 "memop"
5102 [(match_operand:SI 1 "immediate_operand" "")])
5103 (match_operand 2 "general_operand" ""))
5104 (clobber (match_operand:SI 3 "register_operand" ""))]
5106 [(set (match_op_dup 0 [(match_dup 1)])
5110 operands[1] = legitimize_pic_address (operands[1], GET_MODE (operands[0]),
5115 [(set (match_operand 0 "register_operand" "")
5116 (match_operator 1 "memop"
5117 [(match_operand:SI 2 "immediate_operand" "")]))]
5120 (match_op_dup 1 [(match_dup 2)]))]
5123 operands[2] = legitimize_pic_address (operands[2], GET_MODE (operands[1]),
5127 ;; Sign- and Zero-extend operations can have symbolic memory operands.
5130 [(set (match_operand 0 "register_operand" "")
5131 (match_operator 1 "extend_op"
5132 [(match_operator 2 "memop"
5133 [(match_operand:SI 3 "immediate_operand" "")])]))]
5136 (match_op_dup 1 [(match_op_dup 2 [(match_dup 3)])]))]
5139 operands[3] = legitimize_pic_address (operands[3], GET_MODE (operands[2]),
5144 [(set (match_operand:SI 0 "register_operand" "")
5145 (match_operand:SI 1 "immediate_operand" ""))]
5146 "! flag_pic && (GET_CODE (operands[1]) == SYMBOL_REF
5147 || GET_CODE (operands[1]) == CONST
5148 || GET_CODE (operands[1]) == LABEL_REF)"
5149 [(set (match_dup 0) (high:SI (match_dup 1)))
5151 (lo_sum:SI (match_dup 0) (match_dup 1)))]
5154 ;; LABEL_REFs are not modified by `legitimize_pic_address`
5155 ;; so do not recurse infinitely in the PIC case.
5157 [(set (match_operand:SI 0 "register_operand" "")
5158 (match_operand:SI 1 "immediate_operand" ""))]
5159 "flag_pic && (GET_CODE (operands[1]) == SYMBOL_REF
5160 || GET_CODE (operands[1]) == CONST)"
5161 [(set (match_dup 0) (match_dup 1))]
5164 operands[1] = legitimize_pic_address (operands[1], Pmode, operands[0]);
5167 ;; These split sne/seq insns. The forms of the resulting insns are
5168 ;; somewhat bogus, but they avoid extra patterns and show data dependency.
5169 ;; Nothing will look at these in detail after splitting has occurred.
5171 ;; ??? v9 DImode versions are missing because addc and subc use %icc.
5174 [(set (match_operand:SI 0 "register_operand" "")
5175 (ne:SI (match_operand:SI 1 "register_operand" "")
5177 (clobber (reg:CC 0))]
5179 [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
5181 (set (match_dup 0) (ltu:SI (reg:CC 0) (const_int 0)))]
5185 [(set (match_operand:SI 0 "register_operand" "")
5186 (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "")
5188 (clobber (reg:CC 0))]
5190 [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
5192 (set (match_dup 0) (neg:SI (ltu:SI (reg:CC 0) (const_int 0))))]
5196 [(set (match_operand:SI 0 "register_operand" "")
5197 (eq:SI (match_operand:SI 1 "register_operand" "")
5199 (clobber (reg:CC 0))]
5201 [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
5203 (set (match_dup 0) (geu:SI (reg:CC 0) (const_int 0)))]
5207 [(set (match_operand:SI 0 "register_operand" "")
5208 (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "")
5210 (clobber (reg:CC 0))]
5212 [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
5214 (set (match_dup 0) (neg:SI (geu:SI (reg:CC 0) (const_int 0))))]
5218 [(set (match_operand:SI 0 "register_operand" "")
5219 (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "")
5221 (match_operand:SI 2 "register_operand" "")))
5222 (clobber (reg:CC 0))]
5224 [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
5226 (set (match_dup 0) (plus:SI (ltu:SI (reg:CC 0) (const_int 0))
5231 [(set (match_operand:SI 0 "register_operand" "")
5232 (minus:SI (match_operand:SI 2 "register_operand" "")
5233 (ne:SI (match_operand:SI 1 "register_operand" "")
5235 (clobber (reg:CC 0))]
5237 [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
5239 (set (match_dup 0) (minus:SI (match_dup 2)
5240 (ltu:SI (reg:CC 0) (const_int 0))))]
5244 [(set (match_operand:SI 0 "register_operand" "")
5245 (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "")
5247 (match_operand:SI 2 "register_operand" "")))
5248 (clobber (reg:CC 0))]
5250 [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
5252 (set (match_dup 0) (plus:SI (geu:SI (reg:CC 0) (const_int 0))
5257 [(set (match_operand:SI 0 "register_operand" "")
5258 (minus:SI (match_operand:SI 2 "register_operand" "")
5259 (eq:SI (match_operand:SI 1 "register_operand" "")
5261 (clobber (reg:CC 0))]
5263 [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
5265 (set (match_dup 0) (minus:SI (match_dup 2)
5266 (geu:SI (reg:CC 0) (const_int 0))))]
5269 ;; Peepholes go at the end.
5271 ;; Optimize consecutive loads or stores into ldd and std when possible.
5272 ;; The conditions in which we do this are very restricted and are
5273 ;; explained in the code for {registers,memory}_ok_for_ldd functions.
5276 [(set (match_operand:SI 0 "register_operand" "=rf")
5277 (match_operand:SI 1 "memory_operand" ""))
5278 (set (match_operand:SI 2 "register_operand" "=rf")
5279 (match_operand:SI 3 "memory_operand" ""))]
5281 && registers_ok_for_ldd_peep (operands[0], operands[2])
5282 && ! MEM_VOLATILE_P (operands[1]) && ! MEM_VOLATILE_P (operands[3])
5283 && addrs_ok_for_ldd_peep (XEXP (operands[1], 0), XEXP (operands[3], 0))"
5287 [(set (match_operand:SI 0 "memory_operand" "")
5288 (match_operand:SI 1 "register_operand" "rf"))
5289 (set (match_operand:SI 2 "memory_operand" "")
5290 (match_operand:SI 3 "register_operand" "rf"))]
5292 && registers_ok_for_ldd_peep (operands[1], operands[3])
5293 && ! MEM_VOLATILE_P (operands[0]) && ! MEM_VOLATILE_P (operands[2])
5294 && addrs_ok_for_ldd_peep (XEXP (operands[0], 0), XEXP (operands[2], 0))"
5298 [(set (match_operand:SF 0 "register_operand" "=fr")
5299 (match_operand:SF 1 "memory_operand" ""))
5300 (set (match_operand:SF 2 "register_operand" "=fr")
5301 (match_operand:SF 3 "memory_operand" ""))]
5303 && registers_ok_for_ldd_peep (operands[0], operands[2])
5304 && ! MEM_VOLATILE_P (operands[1]) && ! MEM_VOLATILE_P (operands[3])
5305 && addrs_ok_for_ldd_peep (XEXP (operands[1], 0), XEXP (operands[3], 0))"
5309 [(set (match_operand:SF 0 "memory_operand" "")
5310 (match_operand:SF 1 "register_operand" "fr"))
5311 (set (match_operand:SF 2 "memory_operand" "")
5312 (match_operand:SF 3 "register_operand" "fr"))]
5314 && registers_ok_for_ldd_peep (operands[1], operands[3])
5315 && ! MEM_VOLATILE_P (operands[0]) && ! MEM_VOLATILE_P (operands[2])
5316 && addrs_ok_for_ldd_peep (XEXP (operands[0], 0), XEXP (operands[2], 0))"
5320 [(set (match_operand:SI 0 "register_operand" "=rf")
5321 (match_operand:SI 1 "memory_operand" ""))
5322 (set (match_operand:SI 2 "register_operand" "=rf")
5323 (match_operand:SI 3 "memory_operand" ""))]
5325 && registers_ok_for_ldd_peep (operands[2], operands[0])
5326 && ! MEM_VOLATILE_P (operands[3]) && ! MEM_VOLATILE_P (operands[1])
5327 && addrs_ok_for_ldd_peep (XEXP (operands[3], 0), XEXP (operands[1], 0))"
5331 [(set (match_operand:SI 0 "memory_operand" "")
5332 (match_operand:SI 1 "register_operand" "rf"))
5333 (set (match_operand:SI 2 "memory_operand" "")
5334 (match_operand:SI 3 "register_operand" "rf"))]
5336 && registers_ok_for_ldd_peep (operands[3], operands[1])
5337 && ! MEM_VOLATILE_P (operands[2]) && ! MEM_VOLATILE_P (operands[0])
5338 && addrs_ok_for_ldd_peep (XEXP (operands[2], 0), XEXP (operands[0], 0))"
5342 [(set (match_operand:SF 0 "register_operand" "=fr")
5343 (match_operand:SF 1 "memory_operand" ""))
5344 (set (match_operand:SF 2 "register_operand" "=fr")
5345 (match_operand:SF 3 "memory_operand" ""))]
5347 && registers_ok_for_ldd_peep (operands[2], operands[0])
5348 && ! MEM_VOLATILE_P (operands[3]) && ! MEM_VOLATILE_P (operands[1])
5349 && addrs_ok_for_ldd_peep (XEXP (operands[3], 0), XEXP (operands[1], 0))"
5353 [(set (match_operand:SF 0 "memory_operand" "")
5354 (match_operand:SF 1 "register_operand" "fr"))
5355 (set (match_operand:SF 2 "memory_operand" "")
5356 (match_operand:SF 3 "register_operand" "fr"))]
5358 && registers_ok_for_ldd_peep (operands[3], operands[1])
5359 && ! MEM_VOLATILE_P (operands[2]) && ! MEM_VOLATILE_P (operands[0])
5360 && addrs_ok_for_ldd_peep (XEXP (operands[2], 0), XEXP (operands[0], 0))"
5363 ;; Optimize the case of following a reg-reg move with a test
5364 ;; of reg just moved. Don't allow floating point regs for operand 0 or 1.
5365 ;; This can result from a float to fix conversion.
5368 [(set (match_operand:SI 0 "register_operand" "=r")
5369 (match_operand:SI 1 "register_operand" "r"))
5371 (compare:CC (match_operand:SI 2 "register_operand" "r")
5373 "(rtx_equal_p (operands[2], operands[0])
5374 || rtx_equal_p (operands[2], operands[1]))
5375 && ! FP_REG_P (operands[0]) && ! FP_REG_P (operands[1])"
5379 [(set (match_operand:DI 0 "register_operand" "=r")
5380 (match_operand:DI 1 "register_operand" "r"))
5382 (compare:CCX (match_operand:DI 2 "register_operand" "r")
5385 && (rtx_equal_p (operands[2], operands[0])
5386 || rtx_equal_p (operands[2], operands[1]))
5387 && ! FP_REG_P (operands[0]) && ! FP_REG_P (operands[1])"
5390 ;; Do {sign,zero}-extended compares somewhat more efficiently.
5391 ;; ??? Is this now the Right Way to do this? Or will SCRATCH
5392 ;; eventually have some impact here?
5395 [(set (match_operand:HI 0 "register_operand" "")
5396 (match_operand:HI 1 "memory_operand" ""))
5397 (set (match_operand:SI 2 "register_operand" "")
5398 (sign_extend:SI (match_dup 0)))
5400 (compare:CC (match_dup 2)
5403 "ldsh %1,%0\;orcc %0,%%g0,%2")
5406 [(set (match_operand:HI 0 "register_operand" "")
5407 (match_operand:HI 1 "memory_operand" ""))
5408 (set (match_operand:DI 2 "register_operand" "")
5409 (sign_extend:DI (match_dup 0)))
5411 (compare:CCX (match_dup 2)
5414 "ldsh %1,%0\;orcc %0,%%g0,%2")
5417 [(set (match_operand:QI 0 "register_operand" "")
5418 (match_operand:QI 1 "memory_operand" ""))
5419 (set (match_operand:SI 2 "register_operand" "")
5420 (sign_extend:SI (match_dup 0)))
5422 (compare:CC (match_dup 2)
5425 "ldsb %1,%0\;orcc %0,%%g0,%2")
5428 [(set (match_operand:QI 0 "register_operand" "")
5429 (match_operand:QI 1 "memory_operand" ""))
5430 (set (match_operand:DI 2 "register_operand" "")
5431 (sign_extend:DI (match_dup 0)))
5433 (compare:CCX (match_dup 2)
5436 "ldsb %1,%0\;orcc %0,%%g0,%2")
5439 [(set (match_operand:HI 0 "register_operand" "")
5440 (match_operand:HI 1 "memory_operand" ""))
5441 (set (match_operand:SI 2 "register_operand" "")
5442 (sign_extend:SI (match_dup 0)))]
5443 "dead_or_set_p (insn, operands[0])"
5446 warning (\"bad peephole\");
5447 if (! MEM_VOLATILE_P (operands[1]))
5449 return \"ldsh %1,%2\";
5453 [(set (match_operand:QI 0 "register_operand" "")
5454 (match_operand:QI 1 "memory_operand" ""))
5455 (set (match_operand:SI 2 "register_operand" "")
5456 (sign_extend:SI (match_dup 0)))]
5457 "dead_or_set_p (insn, operands[0])"
5460 warning (\"bad peephole\");
5461 if (! MEM_VOLATILE_P (operands[1]))
5463 return \"ldsb %1,%2\";
5466 ;; Floating-point move peepholes
5467 ;; ??? v9: Do we want similar ones?
5470 [(set (match_operand:SI 0 "register_operand" "=r")
5471 (lo_sum:SI (match_dup 0)
5472 (match_operand:SI 1 "immediate_operand" "i")))
5473 (set (match_operand:DF 2 "register_operand" "=er")
5474 (mem:DF (match_dup 0)))]
5475 "RTX_UNCHANGING_P (operands[1]) && reg_unused_after (operands[0], insn)"
5478 /* Go by way of output_move_double in case the register in operand 2
5479 is not properly aligned for ldd. */
5480 operands[1] = gen_rtx (MEM, DFmode,
5481 gen_rtx (LO_SUM, SImode, operands[0], operands[1]));
5482 operands[0] = operands[2];
5483 return output_move_double (operands);
5487 [(set (match_operand:SI 0 "register_operand" "=r")
5488 (lo_sum:SI (match_dup 0)
5489 (match_operand:SI 1 "immediate_operand" "i")))
5490 (set (match_operand:SF 2 "register_operand" "=fr")
5491 (mem:SF (match_dup 0)))]
5492 "RTX_UNCHANGING_P (operands[1]) && reg_unused_after (operands[0], insn)"
5493 "ld [%0+%%lo(%a1)],%2")
5495 ;; Return peepholes. First the "normal" ones
5497 ;; ??? There are QImode, HImode, and SImode versions of this pattern.
5498 ;; It might be possible to write one more general pattern instead of three.
5501 [(set (match_operand:QI 0 "restore_operand" "")
5502 (match_operand:QI 1 "arith_operand" "rI"))
5507 if (! TARGET_V9 && current_function_returns_struct)
5508 return \"jmp %%i7+12\;restore %%g0,%1,%Y0\";
5510 return \"ret\;restore %%g0,%1,%Y0\";
5512 [(set_attr "type" "multi")])
5515 [(set (match_operand:HI 0 "restore_operand" "")
5516 (match_operand:HI 1 "arith_operand" "rI"))
5521 if (! TARGET_V9 && current_function_returns_struct)
5522 return \"jmp %%i7+12\;restore %%g0,%1,%Y0\";
5524 return \"ret\;restore %%g0,%1,%Y0\";
5526 [(set_attr "type" "multi")])
5529 [(set (match_operand:SI 0 "restore_operand" "")
5530 (match_operand:SI 1 "arith_operand" "rI"))
5535 if (! TARGET_V9 && current_function_returns_struct)
5536 return \"jmp %%i7+12\;restore %%g0,%1,%Y0\";
5538 return \"ret\;restore %%g0,%1,%Y0\";
5540 [(set_attr "type" "multi")])
5542 ;; The following pattern is only generated by delayed-branch scheduling,
5543 ;; when the insn winds up in the epilogue. This can only happen when
5544 ;; ! TARGET_FPU because otherwise fp return values are in %f0.
5546 [(set (match_operand:SF 0 "restore_operand" "r")
5547 (match_operand:SF 1 "register_operand" "r"))
5549 "! TARGET_FPU && ! TARGET_EPILOGUE"
5552 if (! TARGET_V9 && current_function_returns_struct)
5553 return \"jmp %%i7+12\;restore %%g0,%1,%Y0\";
5555 return \"ret\;restore %%g0,%1,%Y0\";
5557 [(set_attr "type" "multi")])
5560 [(set (match_operand:SI 0 "restore_operand" "")
5561 (plus:SI (match_operand:SI 1 "arith_operand" "%r")
5562 (match_operand:SI 2 "arith_operand" "rI")))
5567 if (! TARGET_V9 && current_function_returns_struct)
5568 return \"jmp %%i7+12\;restore %r1,%2,%Y0\";
5570 return \"ret\;restore %r1,%2,%Y0\";
5572 [(set_attr "type" "multi")])
5575 [(set (match_operand:DI 0 "restore_operand" "")
5576 (match_operand:DI 1 "arith_double_operand" "rHI"))
5578 "TARGET_V9 && ! TARGET_EPILOGUE"
5579 "ret\;restore %%g0,%1,%Y0"
5580 [(set_attr "type" "multi")])
5583 [(set (match_operand:DI 0 "restore_operand" "")
5584 (plus:DI (match_operand:DI 1 "arith_operand" "%r")
5585 (match_operand:DI 2 "arith_double_operand" "rHI")))
5587 "TARGET_V9 && ! TARGET_EPILOGUE"
5588 "ret\;restore %r1,%2,%Y0"
5589 [(set_attr "type" "multi")])
5591 ;; Turned off because it should never match (subtracting a constant
5592 ;; is turned into addition) and because it would do the wrong thing
5593 ;; when operand 2 is -4096 (--4096 == 4096 is not a valid immediate).
5595 ;; [(set (match_operand:SI 0 "restore_operand" "")
5596 ;; (minus:SI (match_operand:SI 1 "register_operand" "r")
5597 ;; (match_operand:SI 2 "small_int" "I")))
5599 ;; "! TARGET_EPILOGUE"
5600 ;; "ret\;restore %1,-(%2),%Y0"
5601 ;; [(set_attr "type" "multi")])
5603 ;; The following pattern is only generated by delayed-branch scheduling,
5604 ;; when the insn winds up in the epilogue.
5607 (match_operand:SF 0 "register_operand" "f"))
5610 "ret\;fmovs %0,%%f0"
5611 [(set_attr "type" "multi")])
5613 ;; Now peepholes to do a call followed by a jump.
5616 [(parallel [(set (match_operand 0 "" "")
5617 (call (mem:SI (match_operand:SI 1 "call_operand_address" "ps"))
5618 (match_operand 2 "" "")))
5619 (clobber (reg:SI 15))])
5620 (set (pc) (label_ref (match_operand 3 "" "")))]
5621 "short_branch (INSN_UID (insn), INSN_UID (operands[3]))"
5624 return \"call %a1,%2\;add %%o7,(%l3-.-4),%%o7\";
5628 [(parallel [(call (mem:SI (match_operand:SI 0 "call_operand_address" "ps"))
5629 (match_operand 1 "" ""))
5630 (clobber (reg:SI 15))])
5631 (set (pc) (label_ref (match_operand 2 "" "")))]
5632 "short_branch (INSN_UID (insn), INSN_UID (operands[2]))"
5635 return \"call %a0,%1\;add %%o7,(%l2-.-4),%%o7\";
5639 [(parallel [(set (match_operand 0 "" "")
5640 (call (mem:SI (match_operand:DI 1 "call_operand_address" "ps"))
5641 (match_operand 2 "" "")))
5642 (clobber (reg:DI 15))])
5643 (set (pc) (label_ref (match_operand 3 "" "")))]
5644 "TARGET_V9 && short_branch (INSN_UID (insn), INSN_UID (operands[3]))"
5647 return \"call %a1,%2\;add %%o7,(%l3-.-4),%%o7\";
5651 [(parallel [(call (mem:SI (match_operand:DI 0 "call_operand_address" "ps"))
5652 (match_operand 1 "" ""))
5653 (clobber (reg:DI 15))])
5654 (set (pc) (label_ref (match_operand 2 "" "")))]
5655 "TARGET_V9 && short_branch (INSN_UID (insn), INSN_UID (operands[2]))"
5658 return \"call %a0,%1\;add %%o7,(%l2-.-4),%%o7\";
5661 ;; Other miscellaneous peepholes.
5664 [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
5665 (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5667 (clobber (reg:CC 0))])
5668 (set (reg:CC 0) (compare (match_dup 0) (const_int 0)))]