1 ;; Machine description for SPARC chip for GNU C compiler
2 ;; Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
3 ;; 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
4 ;; Contributed by Michael Tiemann (tiemann@cygnus.com)
5 ;; 64 bit SPARC V9 support by Michael Tiemann, Jim Wilson, and Doug Evans,
8 ;; This file is part of GNU CC.
10 ;; GNU CC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 2, or (at your option)
15 ;; GNU CC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 ;; GNU General Public License for more details.
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GNU CC; see the file COPYING. If not, write to
22 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
23 ;; Boston, MA 02111-1307, USA.
25 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
29 (UNSPEC_UPDATE_RETURN 1)
31 (UNSPEC_MOVE_PIC_LABEL 5)
37 (UNSPEC_EMB_TEXTUHI 13)
38 (UNSPEC_EMB_TEXTHI 14)
39 (UNSPEC_EMB_TEXTULO 15)
52 ;; The upper 32 fp regs on the v9 can't hold SFmode values. To deal with this
53 ;; a second register class, EXTRA_FP_REGS, exists for the v9 chip. The name
54 ;; is a bit of a misnomer as it covers all 64 fp regs. The corresponding
55 ;; constraint letter is 'e'. To avoid any confusion, 'e' is used instead of
56 ;; 'f' for all DF/TFmode values, including those that are specific to the v8.
58 ;; Attribute for cpu type.
59 ;; These must match the values for enum processor_type in sparc.h.
60 (define_attr "cpu" "v7,cypress,v8,supersparc,sparclite,f930,f934,hypersparc,sparclite86x,sparclet,tsc701,v9,ultrasparc,ultrasparc3"
61 (const (symbol_ref "sparc_cpu_attr")))
63 ;; Attribute for the instruction set.
64 ;; At present we only need to distinguish v9/!v9, but for clarity we
65 ;; test TARGET_V8 too.
66 (define_attr "isa" "v6,v8,v9,sparclet"
68 (cond [(symbol_ref "TARGET_V9") (const_string "v9")
69 (symbol_ref "TARGET_V8") (const_string "v8")
70 (symbol_ref "TARGET_SPARCLET") (const_string "sparclet")]
71 (const_string "v6"))))
74 (define_attr "arch" "arch32bit,arch64bit"
76 (cond [(symbol_ref "TARGET_ARCH64") (const_string "arch64bit")]
77 (const_string "arch32bit"))))
82 "ialu,compare,shift,load,sload,store,uncond_branch,branch,call,sibcall,call_no_delay_slot,return,imul,idiv,fpload,fpstore,fp,fpmove,fpcmove,fpcrmove,fpcmp,fpmul,fpdivs,fpdivd,fpsqrts,fpsqrtd,cmove,multi,misc"
83 (const_string "ialu"))
85 ;; true if branch/call has empty delay slot and will emit a nop in it
86 (define_attr "empty_delay_slot" "false,true"
87 (symbol_ref "empty_delay_slot (insn)"))
89 (define_attr "branch_type" "none,icc,fcc,reg" (const_string "none"))
91 (define_attr "pic" "false,true"
92 (symbol_ref "flag_pic != 0"))
94 ;; Length (in # of insns).
95 (define_attr "length" ""
96 (cond [(eq_attr "type" "uncond_branch,call,sibcall")
97 (if_then_else (eq_attr "empty_delay_slot" "true")
100 (eq_attr "branch_type" "icc")
101 (if_then_else (match_operand 0 "noov_compare64_op" "")
102 (if_then_else (lt (pc) (match_dup 1))
103 (if_then_else (lt (minus (match_dup 1) (pc)) (const_int 260000))
104 (if_then_else (eq_attr "empty_delay_slot" "true")
107 (if_then_else (eq_attr "empty_delay_slot" "true")
110 (if_then_else (lt (minus (pc) (match_dup 1)) (const_int 260000))
111 (if_then_else (eq_attr "empty_delay_slot" "true")
114 (if_then_else (eq_attr "empty_delay_slot" "true")
117 (if_then_else (eq_attr "empty_delay_slot" "true")
120 (eq_attr "branch_type" "fcc")
121 (if_then_else (match_operand 0 "fcc0_reg_operand" "")
122 (if_then_else (eq_attr "empty_delay_slot" "true")
125 (if_then_else (lt (pc) (match_dup 2))
126 (if_then_else (lt (minus (match_dup 2) (pc)) (const_int 260000))
127 (if_then_else (eq_attr "empty_delay_slot" "true")
130 (if_then_else (eq_attr "empty_delay_slot" "true")
133 (if_then_else (lt (minus (pc) (match_dup 2)) (const_int 260000))
134 (if_then_else (eq_attr "empty_delay_slot" "true")
137 (if_then_else (eq_attr "empty_delay_slot" "true")
140 (eq_attr "branch_type" "reg")
141 (if_then_else (lt (pc) (match_dup 2))
142 (if_then_else (lt (minus (match_dup 2) (pc)) (const_int 32000))
143 (if_then_else (eq_attr "empty_delay_slot" "true")
146 (if_then_else (eq_attr "empty_delay_slot" "true")
149 (if_then_else (lt (minus (pc) (match_dup 2)) (const_int 32000))
150 (if_then_else (eq_attr "empty_delay_slot" "true")
153 (if_then_else (eq_attr "empty_delay_slot" "true")
159 (define_attr "fptype" "single,double" (const_string "single"))
161 ;; UltraSPARC-III integer load type.
162 (define_attr "us3load_type" "2cycle,3cycle" (const_string "2cycle"))
164 (define_asm_attributes
165 [(set_attr "length" "2")
166 (set_attr "type" "multi")])
168 ;; Attributes for instruction and branch scheduling
170 (define_attr "in_call_delay" "false,true"
171 (cond [(eq_attr "type" "uncond_branch,branch,call,sibcall,call_no_delay_slot,return,multi")
172 (const_string "false")
173 (eq_attr "type" "load,fpload,store,fpstore")
174 (if_then_else (eq_attr "length" "1")
175 (const_string "true")
176 (const_string "false"))]
177 (if_then_else (eq_attr "length" "1")
178 (const_string "true")
179 (const_string "false"))))
181 (define_delay (eq_attr "type" "call")
182 [(eq_attr "in_call_delay" "true") (nil) (nil)])
184 (define_attr "eligible_for_sibcall_delay" "false,true"
185 (symbol_ref "eligible_for_sibcall_delay (insn)"))
187 (define_delay (eq_attr "type" "sibcall")
188 [(eq_attr "eligible_for_sibcall_delay" "true") (nil) (nil)])
190 (define_attr "leaf_function" "false,true"
191 (const (symbol_ref "current_function_uses_only_leaf_regs")))
193 (define_attr "eligible_for_return_delay" "false,true"
194 (symbol_ref "eligible_for_return_delay (insn)"))
196 (define_attr "in_return_delay" "false,true"
197 (if_then_else (and (and (and (eq_attr "type" "ialu,load,sload,store")
198 (eq_attr "length" "1"))
199 (eq_attr "leaf_function" "false"))
200 (eq_attr "eligible_for_return_delay" "false"))
201 (const_string "true")
202 (const_string "false")))
204 (define_delay (and (eq_attr "type" "return")
205 (eq_attr "isa" "v9"))
206 [(eq_attr "in_return_delay" "true") (nil) (nil)])
208 ;; ??? Should implement the notion of predelay slots for floating point
209 ;; branches. This would allow us to remove the nop always inserted before
210 ;; a floating point branch.
212 ;; ??? It is OK for fill_simple_delay_slots to put load/store instructions
213 ;; in a delay slot, but it is not OK for fill_eager_delay_slots to do so.
214 ;; This is because doing so will add several pipeline stalls to the path
215 ;; that the load/store did not come from. Unfortunately, there is no way
216 ;; to prevent fill_eager_delay_slots from using load/store without completely
217 ;; disabling them. For the SPEC benchmark set, this is a serious lose,
218 ;; because it prevents us from moving back the final store of inner loops.
220 (define_attr "in_branch_delay" "false,true"
221 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
222 (eq_attr "length" "1"))
223 (const_string "true")
224 (const_string "false")))
226 (define_attr "in_uncond_branch_delay" "false,true"
227 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
228 (eq_attr "length" "1"))
229 (const_string "true")
230 (const_string "false")))
232 (define_attr "in_annul_branch_delay" "false,true"
233 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
234 (eq_attr "length" "1"))
235 (const_string "true")
236 (const_string "false")))
238 (define_delay (eq_attr "type" "branch")
239 [(eq_attr "in_branch_delay" "true")
240 (nil) (eq_attr "in_annul_branch_delay" "true")])
242 (define_delay (eq_attr "type" "uncond_branch")
243 [(eq_attr "in_uncond_branch_delay" "true")
246 ;; Include SPARC DFA schedulers
248 (include "cypress.md")
249 (include "supersparc.md")
250 (include "hypersparc.md")
251 (include "sparclet.md")
252 (include "ultra1_2.md")
253 (include "ultra3.md")
256 ;; Compare instructions.
257 ;; This controls RTL generation and register allocation.
259 ;; We generate RTL for comparisons and branches by having the cmpxx
260 ;; patterns store away the operands. Then, the scc and bcc patterns
261 ;; emit RTL for both the compare and the branch.
263 ;; We do this because we want to generate different code for an sne and
264 ;; seq insn. In those cases, if the second operand of the compare is not
265 ;; const0_rtx, we want to compute the xor of the two operands and test
268 ;; We start with the DEFINE_EXPANDs, then the DEFINE_INSNs to match
269 ;; the patterns. Finally, we have the DEFINE_SPLITs for some of the scc
270 ;; insns that actually require more than one machine instruction.
272 ;; Put cmpsi first among compare insns so it matches two CONST_INT operands.
274 (define_expand "cmpsi"
276 (compare:CC (match_operand:SI 0 "register_operand" "")
277 (match_operand:SI 1 "arith_operand" "")))]
281 sparc_compare_op0 = operands[0];
282 sparc_compare_op1 = operands[1];
286 (define_expand "cmpdi"
288 (compare:CCX (match_operand:DI 0 "register_operand" "")
289 (match_operand:DI 1 "arith_double_operand" "")))]
293 sparc_compare_op0 = operands[0];
294 sparc_compare_op1 = operands[1];
298 (define_expand "cmpsf"
299 ;; The 96 here isn't ever used by anyone.
301 (compare:CCFP (match_operand:SF 0 "register_operand" "")
302 (match_operand:SF 1 "register_operand" "")))]
306 sparc_compare_op0 = operands[0];
307 sparc_compare_op1 = operands[1];
311 (define_expand "cmpdf"
312 ;; The 96 here isn't ever used by anyone.
314 (compare:CCFP (match_operand:DF 0 "register_operand" "")
315 (match_operand:DF 1 "register_operand" "")))]
319 sparc_compare_op0 = operands[0];
320 sparc_compare_op1 = operands[1];
324 (define_expand "cmptf"
325 ;; The 96 here isn't ever used by anyone.
327 (compare:CCFP (match_operand:TF 0 "register_operand" "")
328 (match_operand:TF 1 "register_operand" "")))]
332 sparc_compare_op0 = operands[0];
333 sparc_compare_op1 = operands[1];
337 ;; Now the compare DEFINE_INSNs.
339 (define_insn "*cmpsi_insn"
341 (compare:CC (match_operand:SI 0 "register_operand" "r")
342 (match_operand:SI 1 "arith_operand" "rI")))]
345 [(set_attr "type" "compare")])
347 (define_insn "*cmpdi_sp64"
349 (compare:CCX (match_operand:DI 0 "register_operand" "r")
350 (match_operand:DI 1 "arith_double_operand" "rHI")))]
353 [(set_attr "type" "compare")])
355 (define_insn "*cmpsf_fpe"
356 [(set (match_operand:CCFPE 0 "fcc_reg_operand" "=c")
357 (compare:CCFPE (match_operand:SF 1 "register_operand" "f")
358 (match_operand:SF 2 "register_operand" "f")))]
363 return \"fcmpes\\t%0, %1, %2\";
364 return \"fcmpes\\t%1, %2\";
366 [(set_attr "type" "fpcmp")])
368 (define_insn "*cmpdf_fpe"
369 [(set (match_operand:CCFPE 0 "fcc_reg_operand" "=c")
370 (compare:CCFPE (match_operand:DF 1 "register_operand" "e")
371 (match_operand:DF 2 "register_operand" "e")))]
376 return \"fcmped\\t%0, %1, %2\";
377 return \"fcmped\\t%1, %2\";
379 [(set_attr "type" "fpcmp")
380 (set_attr "fptype" "double")])
382 (define_insn "*cmptf_fpe"
383 [(set (match_operand:CCFPE 0 "fcc_reg_operand" "=c")
384 (compare:CCFPE (match_operand:TF 1 "register_operand" "e")
385 (match_operand:TF 2 "register_operand" "e")))]
386 "TARGET_FPU && TARGET_HARD_QUAD"
390 return \"fcmpeq\\t%0, %1, %2\";
391 return \"fcmpeq\\t%1, %2\";
393 [(set_attr "type" "fpcmp")])
395 (define_insn "*cmpsf_fp"
396 [(set (match_operand:CCFP 0 "fcc_reg_operand" "=c")
397 (compare:CCFP (match_operand:SF 1 "register_operand" "f")
398 (match_operand:SF 2 "register_operand" "f")))]
403 return \"fcmps\\t%0, %1, %2\";
404 return \"fcmps\\t%1, %2\";
406 [(set_attr "type" "fpcmp")])
408 (define_insn "*cmpdf_fp"
409 [(set (match_operand:CCFP 0 "fcc_reg_operand" "=c")
410 (compare:CCFP (match_operand:DF 1 "register_operand" "e")
411 (match_operand:DF 2 "register_operand" "e")))]
416 return \"fcmpd\\t%0, %1, %2\";
417 return \"fcmpd\\t%1, %2\";
419 [(set_attr "type" "fpcmp")
420 (set_attr "fptype" "double")])
422 (define_insn "*cmptf_fp"
423 [(set (match_operand:CCFP 0 "fcc_reg_operand" "=c")
424 (compare:CCFP (match_operand:TF 1 "register_operand" "e")
425 (match_operand:TF 2 "register_operand" "e")))]
426 "TARGET_FPU && TARGET_HARD_QUAD"
430 return \"fcmpq\\t%0, %1, %2\";
431 return \"fcmpq\\t%1, %2\";
433 [(set_attr "type" "fpcmp")])
435 ;; Next come the scc insns. For seq, sne, sgeu, and sltu, we can do this
436 ;; without jumps using the addx/subx instructions. For seq/sne on v9 we use
437 ;; the same code as v8 (the addx/subx method has more applications). The
438 ;; exception to this is "reg != 0" which can be done in one instruction on v9
439 ;; (so we do it). For the rest, on v9 we use conditional moves; on v8, we do
442 ;; Seq_special[_xxx] and sne_special[_xxx] clobber the CC reg, because they
443 ;; generate addcc/subcc instructions.
445 (define_expand "seqsi_special"
447 (xor:SI (match_operand:SI 1 "register_operand" "")
448 (match_operand:SI 2 "register_operand" "")))
449 (parallel [(set (match_operand:SI 0 "register_operand" "")
450 (eq:SI (match_dup 3) (const_int 0)))
451 (clobber (reg:CC 100))])]
453 "{ operands[3] = gen_reg_rtx (SImode); }")
455 (define_expand "seqdi_special"
457 (xor:DI (match_operand:DI 1 "register_operand" "")
458 (match_operand:DI 2 "register_operand" "")))
459 (set (match_operand:DI 0 "register_operand" "")
460 (eq:DI (match_dup 3) (const_int 0)))]
462 "{ operands[3] = gen_reg_rtx (DImode); }")
464 (define_expand "snesi_special"
466 (xor:SI (match_operand:SI 1 "register_operand" "")
467 (match_operand:SI 2 "register_operand" "")))
468 (parallel [(set (match_operand:SI 0 "register_operand" "")
469 (ne:SI (match_dup 3) (const_int 0)))
470 (clobber (reg:CC 100))])]
472 "{ operands[3] = gen_reg_rtx (SImode); }")
474 (define_expand "snedi_special"
476 (xor:DI (match_operand:DI 1 "register_operand" "")
477 (match_operand:DI 2 "register_operand" "")))
478 (set (match_operand:DI 0 "register_operand" "")
479 (ne:DI (match_dup 3) (const_int 0)))]
481 "{ operands[3] = gen_reg_rtx (DImode); }")
483 (define_expand "seqdi_special_trunc"
485 (xor:DI (match_operand:DI 1 "register_operand" "")
486 (match_operand:DI 2 "register_operand" "")))
487 (set (match_operand:SI 0 "register_operand" "")
488 (eq:SI (match_dup 3) (const_int 0)))]
490 "{ operands[3] = gen_reg_rtx (DImode); }")
492 (define_expand "snedi_special_trunc"
494 (xor:DI (match_operand:DI 1 "register_operand" "")
495 (match_operand:DI 2 "register_operand" "")))
496 (set (match_operand:SI 0 "register_operand" "")
497 (ne:SI (match_dup 3) (const_int 0)))]
499 "{ operands[3] = gen_reg_rtx (DImode); }")
501 (define_expand "seqsi_special_extend"
503 (xor:SI (match_operand:SI 1 "register_operand" "")
504 (match_operand:SI 2 "register_operand" "")))
505 (parallel [(set (match_operand:DI 0 "register_operand" "")
506 (eq:DI (match_dup 3) (const_int 0)))
507 (clobber (reg:CC 100))])]
509 "{ operands[3] = gen_reg_rtx (SImode); }")
511 (define_expand "snesi_special_extend"
513 (xor:SI (match_operand:SI 1 "register_operand" "")
514 (match_operand:SI 2 "register_operand" "")))
515 (parallel [(set (match_operand:DI 0 "register_operand" "")
516 (ne:DI (match_dup 3) (const_int 0)))
517 (clobber (reg:CC 100))])]
519 "{ operands[3] = gen_reg_rtx (SImode); }")
521 ;; ??? v9: Operand 0 needs a mode, so SImode was chosen.
522 ;; However, the code handles both SImode and DImode.
524 [(set (match_operand:SI 0 "intreg_operand" "")
525 (eq:SI (match_dup 1) (const_int 0)))]
529 if (GET_MODE (sparc_compare_op0) == SImode)
533 if (GET_MODE (operands[0]) == SImode)
534 pat = gen_seqsi_special (operands[0], sparc_compare_op0,
536 else if (! TARGET_ARCH64)
539 pat = gen_seqsi_special_extend (operands[0], sparc_compare_op0,
544 else if (GET_MODE (sparc_compare_op0) == DImode)
550 else if (GET_MODE (operands[0]) == SImode)
551 pat = gen_seqdi_special_trunc (operands[0], sparc_compare_op0,
554 pat = gen_seqdi_special (operands[0], sparc_compare_op0,
559 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
561 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, EQ);
562 emit_jump_insn (gen_sne (operands[0]));
567 if (gen_v9_scc (EQ, operands))
574 ;; ??? v9: Operand 0 needs a mode, so SImode was chosen.
575 ;; However, the code handles both SImode and DImode.
577 [(set (match_operand:SI 0 "intreg_operand" "")
578 (ne:SI (match_dup 1) (const_int 0)))]
582 if (GET_MODE (sparc_compare_op0) == SImode)
586 if (GET_MODE (operands[0]) == SImode)
587 pat = gen_snesi_special (operands[0], sparc_compare_op0,
589 else if (! TARGET_ARCH64)
592 pat = gen_snesi_special_extend (operands[0], sparc_compare_op0,
597 else if (GET_MODE (sparc_compare_op0) == DImode)
603 else if (GET_MODE (operands[0]) == SImode)
604 pat = gen_snedi_special_trunc (operands[0], sparc_compare_op0,
607 pat = gen_snedi_special (operands[0], sparc_compare_op0,
612 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
614 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, NE);
615 emit_jump_insn (gen_sne (operands[0]));
620 if (gen_v9_scc (NE, operands))
628 [(set (match_operand:SI 0 "intreg_operand" "")
629 (gt:SI (match_dup 1) (const_int 0)))]
633 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
635 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GT);
636 emit_jump_insn (gen_sne (operands[0]));
641 if (gen_v9_scc (GT, operands))
649 [(set (match_operand:SI 0 "intreg_operand" "")
650 (lt:SI (match_dup 1) (const_int 0)))]
654 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
656 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LT);
657 emit_jump_insn (gen_sne (operands[0]));
662 if (gen_v9_scc (LT, operands))
670 [(set (match_operand:SI 0 "intreg_operand" "")
671 (ge:SI (match_dup 1) (const_int 0)))]
675 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
677 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GE);
678 emit_jump_insn (gen_sne (operands[0]));
683 if (gen_v9_scc (GE, operands))
691 [(set (match_operand:SI 0 "intreg_operand" "")
692 (le:SI (match_dup 1) (const_int 0)))]
696 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
698 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LE);
699 emit_jump_insn (gen_sne (operands[0]));
704 if (gen_v9_scc (LE, operands))
711 (define_expand "sgtu"
712 [(set (match_operand:SI 0 "intreg_operand" "")
713 (gtu:SI (match_dup 1) (const_int 0)))]
721 /* We can do ltu easily, so if both operands are registers, swap them and
723 if ((GET_CODE (sparc_compare_op0) == REG
724 || GET_CODE (sparc_compare_op0) == SUBREG)
725 && (GET_CODE (sparc_compare_op1) == REG
726 || GET_CODE (sparc_compare_op1) == SUBREG))
728 tem = sparc_compare_op0;
729 sparc_compare_op0 = sparc_compare_op1;
730 sparc_compare_op1 = tem;
731 pat = gen_sltu (operands[0]);
740 if (gen_v9_scc (GTU, operands))
746 (define_expand "sltu"
747 [(set (match_operand:SI 0 "intreg_operand" "")
748 (ltu:SI (match_dup 1) (const_int 0)))]
754 if (gen_v9_scc (LTU, operands))
757 operands[1] = gen_compare_reg (LTU, sparc_compare_op0, sparc_compare_op1);
760 (define_expand "sgeu"
761 [(set (match_operand:SI 0 "intreg_operand" "")
762 (geu:SI (match_dup 1) (const_int 0)))]
768 if (gen_v9_scc (GEU, operands))
771 operands[1] = gen_compare_reg (GEU, sparc_compare_op0, sparc_compare_op1);
774 (define_expand "sleu"
775 [(set (match_operand:SI 0 "intreg_operand" "")
776 (leu:SI (match_dup 1) (const_int 0)))]
784 /* We can do geu easily, so if both operands are registers, swap them and
786 if ((GET_CODE (sparc_compare_op0) == REG
787 || GET_CODE (sparc_compare_op0) == SUBREG)
788 && (GET_CODE (sparc_compare_op1) == REG
789 || GET_CODE (sparc_compare_op1) == SUBREG))
791 tem = sparc_compare_op0;
792 sparc_compare_op0 = sparc_compare_op1;
793 sparc_compare_op1 = tem;
794 pat = gen_sgeu (operands[0]);
803 if (gen_v9_scc (LEU, operands))
809 ;; Now the DEFINE_INSNs for the scc cases.
811 ;; The SEQ and SNE patterns are special because they can be done
812 ;; without any branching and do not involve a COMPARE. We want
813 ;; them to always use the splitz below so the results can be
816 (define_insn "*snesi_zero"
817 [(set (match_operand:SI 0 "register_operand" "=r")
818 (ne:SI (match_operand:SI 1 "register_operand" "r")
820 (clobber (reg:CC 100))]
823 [(set_attr "length" "2")])
826 [(set (match_operand:SI 0 "register_operand" "")
827 (ne:SI (match_operand:SI 1 "register_operand" "")
829 (clobber (reg:CC 100))]
831 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
833 (set (match_dup 0) (ltu:SI (reg:CC 100) (const_int 0)))]
836 (define_insn "*neg_snesi_zero"
837 [(set (match_operand:SI 0 "register_operand" "=r")
838 (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
840 (clobber (reg:CC 100))]
843 [(set_attr "length" "2")])
846 [(set (match_operand:SI 0 "register_operand" "")
847 (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "")
849 (clobber (reg:CC 100))]
851 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
853 (set (match_dup 0) (neg:SI (ltu:SI (reg:CC 100) (const_int 0))))]
856 (define_insn "*snesi_zero_extend"
857 [(set (match_operand:DI 0 "register_operand" "=r")
858 (ne:DI (match_operand:SI 1 "register_operand" "r")
860 (clobber (reg:CC 100))]
863 [(set_attr "length" "2")])
866 [(set (match_operand:DI 0 "register_operand" "")
867 (ne:DI (match_operand:SI 1 "register_operand" "")
869 (clobber (reg:CC 100))]
871 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 1))
873 (set (match_dup 0) (zero_extend:DI (plus:SI (plus:SI (const_int 0)
875 (ltu:SI (reg:CC_NOOV 100)
879 (define_insn "*snedi_zero"
880 [(set (match_operand:DI 0 "register_operand" "=&r")
881 (ne:DI (match_operand:DI 1 "register_operand" "r")
885 [(set_attr "length" "2")])
888 [(set (match_operand:DI 0 "register_operand" "")
889 (ne:DI (match_operand:DI 1 "register_operand" "")
892 && ! reg_overlap_mentioned_p (operands[1], operands[0])"
893 [(set (match_dup 0) (const_int 0))
894 (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
900 (define_insn "*neg_snedi_zero"
901 [(set (match_operand:DI 0 "register_operand" "=&r")
902 (neg:DI (ne:DI (match_operand:DI 1 "register_operand" "r")
906 [(set_attr "length" "2")])
909 [(set (match_operand:DI 0 "register_operand" "")
910 (neg:DI (ne:DI (match_operand:DI 1 "register_operand" "")
913 && ! reg_overlap_mentioned_p (operands[1], operands[0])"
914 [(set (match_dup 0) (const_int 0))
915 (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
921 (define_insn "*snedi_zero_trunc"
922 [(set (match_operand:SI 0 "register_operand" "=&r")
923 (ne:SI (match_operand:DI 1 "register_operand" "r")
927 [(set_attr "length" "2")])
930 [(set (match_operand:SI 0 "register_operand" "")
931 (ne:SI (match_operand:DI 1 "register_operand" "")
934 && ! reg_overlap_mentioned_p (operands[1], operands[0])"
935 [(set (match_dup 0) (const_int 0))
936 (set (match_dup 0) (if_then_else:SI (ne:DI (match_dup 1)
942 (define_insn "*seqsi_zero"
943 [(set (match_operand:SI 0 "register_operand" "=r")
944 (eq:SI (match_operand:SI 1 "register_operand" "r")
946 (clobber (reg:CC 100))]
949 [(set_attr "length" "2")])
952 [(set (match_operand:SI 0 "register_operand" "")
953 (eq:SI (match_operand:SI 1 "register_operand" "")
955 (clobber (reg:CC 100))]
957 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
959 (set (match_dup 0) (geu:SI (reg:CC 100) (const_int 0)))]
962 (define_insn "*neg_seqsi_zero"
963 [(set (match_operand:SI 0 "register_operand" "=r")
964 (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
966 (clobber (reg:CC 100))]
969 [(set_attr "length" "2")])
972 [(set (match_operand:SI 0 "register_operand" "")
973 (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "")
975 (clobber (reg:CC 100))]
977 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
979 (set (match_dup 0) (neg:SI (geu:SI (reg:CC 100) (const_int 0))))]
982 (define_insn "*seqsi_zero_extend"
983 [(set (match_operand:DI 0 "register_operand" "=r")
984 (eq:DI (match_operand:SI 1 "register_operand" "r")
986 (clobber (reg:CC 100))]
989 [(set_attr "length" "2")])
992 [(set (match_operand:DI 0 "register_operand" "")
993 (eq:DI (match_operand:SI 1 "register_operand" "")
995 (clobber (reg:CC 100))]
997 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 1))
999 (set (match_dup 0) (zero_extend:DI (minus:SI (minus:SI (const_int 0)
1001 (ltu:SI (reg:CC_NOOV 100)
1005 (define_insn "*seqdi_zero"
1006 [(set (match_operand:DI 0 "register_operand" "=&r")
1007 (eq:DI (match_operand:DI 1 "register_operand" "r")
1011 [(set_attr "length" "2")])
1014 [(set (match_operand:DI 0 "register_operand" "")
1015 (eq:DI (match_operand:DI 1 "register_operand" "")
1018 && ! reg_overlap_mentioned_p (operands[1], operands[0])"
1019 [(set (match_dup 0) (const_int 0))
1020 (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
1026 (define_insn "*neg_seqdi_zero"
1027 [(set (match_operand:DI 0 "register_operand" "=&r")
1028 (neg:DI (eq:DI (match_operand:DI 1 "register_operand" "r")
1032 [(set_attr "length" "2")])
1035 [(set (match_operand:DI 0 "register_operand" "")
1036 (neg:DI (eq:DI (match_operand:DI 1 "register_operand" "")
1039 && ! reg_overlap_mentioned_p (operands[1], operands[0])"
1040 [(set (match_dup 0) (const_int 0))
1041 (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
1047 (define_insn "*seqdi_zero_trunc"
1048 [(set (match_operand:SI 0 "register_operand" "=&r")
1049 (eq:SI (match_operand:DI 1 "register_operand" "r")
1053 [(set_attr "length" "2")])
1056 [(set (match_operand:SI 0 "register_operand" "")
1057 (eq:SI (match_operand:DI 1 "register_operand" "")
1060 && ! reg_overlap_mentioned_p (operands[1], operands[0])"
1061 [(set (match_dup 0) (const_int 0))
1062 (set (match_dup 0) (if_then_else:SI (eq:DI (match_dup 1)
1068 ;; We can also do (x + (i == 0)) and related, so put them in.
1069 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1072 (define_insn "*x_plus_i_ne_0"
1073 [(set (match_operand:SI 0 "register_operand" "=r")
1074 (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
1076 (match_operand:SI 2 "register_operand" "r")))
1077 (clobber (reg:CC 100))]
1080 [(set_attr "length" "2")])
1083 [(set (match_operand:SI 0 "register_operand" "")
1084 (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "")
1086 (match_operand:SI 2 "register_operand" "")))
1087 (clobber (reg:CC 100))]
1089 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1091 (set (match_dup 0) (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1095 (define_insn "*x_minus_i_ne_0"
1096 [(set (match_operand:SI 0 "register_operand" "=r")
1097 (minus:SI (match_operand:SI 2 "register_operand" "r")
1098 (ne:SI (match_operand:SI 1 "register_operand" "r")
1100 (clobber (reg:CC 100))]
1103 [(set_attr "length" "2")])
1106 [(set (match_operand:SI 0 "register_operand" "")
1107 (minus:SI (match_operand:SI 2 "register_operand" "")
1108 (ne:SI (match_operand:SI 1 "register_operand" "")
1110 (clobber (reg:CC 100))]
1112 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1114 (set (match_dup 0) (minus:SI (match_dup 2)
1115 (ltu:SI (reg:CC 100) (const_int 0))))]
1118 (define_insn "*x_plus_i_eq_0"
1119 [(set (match_operand:SI 0 "register_operand" "=r")
1120 (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
1122 (match_operand:SI 2 "register_operand" "r")))
1123 (clobber (reg:CC 100))]
1126 [(set_attr "length" "2")])
1129 [(set (match_operand:SI 0 "register_operand" "")
1130 (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "")
1132 (match_operand:SI 2 "register_operand" "")))
1133 (clobber (reg:CC 100))]
1135 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1137 (set (match_dup 0) (plus:SI (geu:SI (reg:CC 100) (const_int 0))
1141 (define_insn "*x_minus_i_eq_0"
1142 [(set (match_operand:SI 0 "register_operand" "=r")
1143 (minus:SI (match_operand:SI 2 "register_operand" "r")
1144 (eq:SI (match_operand:SI 1 "register_operand" "r")
1146 (clobber (reg:CC 100))]
1149 [(set_attr "length" "2")])
1152 [(set (match_operand:SI 0 "register_operand" "")
1153 (minus:SI (match_operand:SI 2 "register_operand" "")
1154 (eq:SI (match_operand:SI 1 "register_operand" "")
1156 (clobber (reg:CC 100))]
1158 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1160 (set (match_dup 0) (minus:SI (match_dup 2)
1161 (geu:SI (reg:CC 100) (const_int 0))))]
1164 ;; We can also do GEU and LTU directly, but these operate after a compare.
1165 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1168 (define_insn "*sltu_insn"
1169 [(set (match_operand:SI 0 "register_operand" "=r")
1170 (ltu:SI (reg:CC 100) (const_int 0)))]
1172 "addx\\t%%g0, 0, %0"
1173 [(set_attr "type" "misc")])
1175 (define_insn "*neg_sltu_insn"
1176 [(set (match_operand:SI 0 "register_operand" "=r")
1177 (neg:SI (ltu:SI (reg:CC 100) (const_int 0))))]
1179 "subx\\t%%g0, 0, %0"
1180 [(set_attr "type" "misc")])
1182 ;; ??? Combine should canonicalize these next two to the same pattern.
1183 (define_insn "*neg_sltu_minus_x"
1184 [(set (match_operand:SI 0 "register_operand" "=r")
1185 (minus:SI (neg:SI (ltu:SI (reg:CC 100) (const_int 0)))
1186 (match_operand:SI 1 "arith_operand" "rI")))]
1188 "subx\\t%%g0, %1, %0"
1189 [(set_attr "type" "misc")])
1191 (define_insn "*neg_sltu_plus_x"
1192 [(set (match_operand:SI 0 "register_operand" "=r")
1193 (neg:SI (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1194 (match_operand:SI 1 "arith_operand" "rI"))))]
1196 "subx\\t%%g0, %1, %0"
1197 [(set_attr "type" "misc")])
1199 (define_insn "*sgeu_insn"
1200 [(set (match_operand:SI 0 "register_operand" "=r")
1201 (geu:SI (reg:CC 100) (const_int 0)))]
1203 "subx\\t%%g0, -1, %0"
1204 [(set_attr "type" "misc")])
1206 (define_insn "*neg_sgeu_insn"
1207 [(set (match_operand:SI 0 "register_operand" "=r")
1208 (neg:SI (geu:SI (reg:CC 100) (const_int 0))))]
1210 "addx\\t%%g0, -1, %0"
1211 [(set_attr "type" "misc")])
1213 ;; We can also do (x + ((unsigned) i >= 0)) and related, so put them in.
1214 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1217 (define_insn "*sltu_plus_x"
1218 [(set (match_operand:SI 0 "register_operand" "=r")
1219 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1220 (match_operand:SI 1 "arith_operand" "rI")))]
1222 "addx\\t%%g0, %1, %0"
1223 [(set_attr "type" "misc")])
1225 (define_insn "*sltu_plus_x_plus_y"
1226 [(set (match_operand:SI 0 "register_operand" "=r")
1227 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1228 (plus:SI (match_operand:SI 1 "arith_operand" "%r")
1229 (match_operand:SI 2 "arith_operand" "rI"))))]
1232 [(set_attr "type" "misc")])
1234 (define_insn "*x_minus_sltu"
1235 [(set (match_operand:SI 0 "register_operand" "=r")
1236 (minus:SI (match_operand:SI 1 "register_operand" "r")
1237 (ltu:SI (reg:CC 100) (const_int 0))))]
1240 [(set_attr "type" "misc")])
1242 ;; ??? Combine should canonicalize these next two to the same pattern.
1243 (define_insn "*x_minus_y_minus_sltu"
1244 [(set (match_operand:SI 0 "register_operand" "=r")
1245 (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
1246 (match_operand:SI 2 "arith_operand" "rI"))
1247 (ltu:SI (reg:CC 100) (const_int 0))))]
1249 "subx\\t%r1, %2, %0"
1250 [(set_attr "type" "misc")])
1252 (define_insn "*x_minus_sltu_plus_y"
1253 [(set (match_operand:SI 0 "register_operand" "=r")
1254 (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
1255 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1256 (match_operand:SI 2 "arith_operand" "rI"))))]
1258 "subx\\t%r1, %2, %0"
1259 [(set_attr "type" "misc")])
1261 (define_insn "*sgeu_plus_x"
1262 [(set (match_operand:SI 0 "register_operand" "=r")
1263 (plus:SI (geu:SI (reg:CC 100) (const_int 0))
1264 (match_operand:SI 1 "register_operand" "r")))]
1267 [(set_attr "type" "misc")])
1269 (define_insn "*x_minus_sgeu"
1270 [(set (match_operand:SI 0 "register_operand" "=r")
1271 (minus:SI (match_operand:SI 1 "register_operand" "r")
1272 (geu:SI (reg:CC 100) (const_int 0))))]
1275 [(set_attr "type" "misc")])
1278 [(set (match_operand:SI 0 "register_operand" "")
1279 (match_operator:SI 2 "noov_compare_op"
1280 [(match_operand 1 "icc_or_fcc_reg_operand" "")
1282 ;; 32 bit LTU/GEU are better implemented using addx/subx
1283 "TARGET_V9 && REGNO (operands[1]) == SPARC_ICC_REG
1284 && (GET_MODE (operands[1]) == CCXmode
1285 || (GET_CODE (operands[2]) != LTU && GET_CODE (operands[2]) != GEU))"
1286 [(set (match_dup 0) (const_int 0))
1288 (if_then_else:SI (match_op_dup:SI 2 [(match_dup 1) (const_int 0)])
1294 ;; These control RTL generation for conditional jump insns
1296 ;; The quad-word fp compare library routines all return nonzero to indicate
1297 ;; true, which is different from the equivalent libgcc routines, so we must
1298 ;; handle them specially here.
1300 (define_expand "beq"
1302 (if_then_else (eq (match_dup 1) (const_int 0))
1303 (label_ref (match_operand 0 "" ""))
1308 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1309 && GET_CODE (sparc_compare_op0) == REG
1310 && GET_MODE (sparc_compare_op0) == DImode)
1312 emit_v9_brxx_insn (EQ, sparc_compare_op0, operands[0]);
1315 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1317 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, EQ);
1318 emit_jump_insn (gen_bne (operands[0]));
1321 operands[1] = gen_compare_reg (EQ, sparc_compare_op0, sparc_compare_op1);
1324 (define_expand "bne"
1326 (if_then_else (ne (match_dup 1) (const_int 0))
1327 (label_ref (match_operand 0 "" ""))
1332 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1333 && GET_CODE (sparc_compare_op0) == REG
1334 && GET_MODE (sparc_compare_op0) == DImode)
1336 emit_v9_brxx_insn (NE, sparc_compare_op0, operands[0]);
1339 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1341 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, NE);
1342 emit_jump_insn (gen_bne (operands[0]));
1345 operands[1] = gen_compare_reg (NE, sparc_compare_op0, sparc_compare_op1);
1348 (define_expand "bgt"
1350 (if_then_else (gt (match_dup 1) (const_int 0))
1351 (label_ref (match_operand 0 "" ""))
1356 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1357 && GET_CODE (sparc_compare_op0) == REG
1358 && GET_MODE (sparc_compare_op0) == DImode)
1360 emit_v9_brxx_insn (GT, sparc_compare_op0, operands[0]);
1363 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1365 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GT);
1366 emit_jump_insn (gen_bne (operands[0]));
1369 operands[1] = gen_compare_reg (GT, sparc_compare_op0, sparc_compare_op1);
1372 (define_expand "bgtu"
1374 (if_then_else (gtu (match_dup 1) (const_int 0))
1375 (label_ref (match_operand 0 "" ""))
1379 { operands[1] = gen_compare_reg (GTU, sparc_compare_op0, sparc_compare_op1);
1382 (define_expand "blt"
1384 (if_then_else (lt (match_dup 1) (const_int 0))
1385 (label_ref (match_operand 0 "" ""))
1390 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1391 && GET_CODE (sparc_compare_op0) == REG
1392 && GET_MODE (sparc_compare_op0) == DImode)
1394 emit_v9_brxx_insn (LT, sparc_compare_op0, operands[0]);
1397 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1399 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LT);
1400 emit_jump_insn (gen_bne (operands[0]));
1403 operands[1] = gen_compare_reg (LT, sparc_compare_op0, sparc_compare_op1);
1406 (define_expand "bltu"
1408 (if_then_else (ltu (match_dup 1) (const_int 0))
1409 (label_ref (match_operand 0 "" ""))
1413 { operands[1] = gen_compare_reg (LTU, sparc_compare_op0, sparc_compare_op1);
1416 (define_expand "bge"
1418 (if_then_else (ge (match_dup 1) (const_int 0))
1419 (label_ref (match_operand 0 "" ""))
1424 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1425 && GET_CODE (sparc_compare_op0) == REG
1426 && GET_MODE (sparc_compare_op0) == DImode)
1428 emit_v9_brxx_insn (GE, sparc_compare_op0, operands[0]);
1431 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1433 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GE);
1434 emit_jump_insn (gen_bne (operands[0]));
1437 operands[1] = gen_compare_reg (GE, sparc_compare_op0, sparc_compare_op1);
1440 (define_expand "bgeu"
1442 (if_then_else (geu (match_dup 1) (const_int 0))
1443 (label_ref (match_operand 0 "" ""))
1447 { operands[1] = gen_compare_reg (GEU, sparc_compare_op0, sparc_compare_op1);
1450 (define_expand "ble"
1452 (if_then_else (le (match_dup 1) (const_int 0))
1453 (label_ref (match_operand 0 "" ""))
1458 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1459 && GET_CODE (sparc_compare_op0) == REG
1460 && GET_MODE (sparc_compare_op0) == DImode)
1462 emit_v9_brxx_insn (LE, sparc_compare_op0, operands[0]);
1465 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1467 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LE);
1468 emit_jump_insn (gen_bne (operands[0]));
1471 operands[1] = gen_compare_reg (LE, sparc_compare_op0, sparc_compare_op1);
1474 (define_expand "bleu"
1476 (if_then_else (leu (match_dup 1) (const_int 0))
1477 (label_ref (match_operand 0 "" ""))
1481 { operands[1] = gen_compare_reg (LEU, sparc_compare_op0, sparc_compare_op1);
1484 (define_expand "bunordered"
1486 (if_then_else (unordered (match_dup 1) (const_int 0))
1487 (label_ref (match_operand 0 "" ""))
1492 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1494 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1,
1496 emit_jump_insn (gen_beq (operands[0]));
1499 operands[1] = gen_compare_reg (UNORDERED, sparc_compare_op0,
1503 (define_expand "bordered"
1505 (if_then_else (ordered (match_dup 1) (const_int 0))
1506 (label_ref (match_operand 0 "" ""))
1511 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1513 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, ORDERED);
1514 emit_jump_insn (gen_bne (operands[0]));
1517 operands[1] = gen_compare_reg (ORDERED, sparc_compare_op0,
1521 (define_expand "bungt"
1523 (if_then_else (ungt (match_dup 1) (const_int 0))
1524 (label_ref (match_operand 0 "" ""))
1529 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1531 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNGT);
1532 emit_jump_insn (gen_bgt (operands[0]));
1535 operands[1] = gen_compare_reg (UNGT, sparc_compare_op0, sparc_compare_op1);
1538 (define_expand "bunlt"
1540 (if_then_else (unlt (match_dup 1) (const_int 0))
1541 (label_ref (match_operand 0 "" ""))
1546 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1548 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNLT);
1549 emit_jump_insn (gen_bne (operands[0]));
1552 operands[1] = gen_compare_reg (UNLT, sparc_compare_op0, sparc_compare_op1);
1555 (define_expand "buneq"
1557 (if_then_else (uneq (match_dup 1) (const_int 0))
1558 (label_ref (match_operand 0 "" ""))
1563 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1565 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNEQ);
1566 emit_jump_insn (gen_beq (operands[0]));
1569 operands[1] = gen_compare_reg (UNEQ, sparc_compare_op0, sparc_compare_op1);
1572 (define_expand "bunge"
1574 (if_then_else (unge (match_dup 1) (const_int 0))
1575 (label_ref (match_operand 0 "" ""))
1580 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1582 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNGE);
1583 emit_jump_insn (gen_bne (operands[0]));
1586 operands[1] = gen_compare_reg (UNGE, sparc_compare_op0, sparc_compare_op1);
1589 (define_expand "bunle"
1591 (if_then_else (unle (match_dup 1) (const_int 0))
1592 (label_ref (match_operand 0 "" ""))
1597 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1599 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNLE);
1600 emit_jump_insn (gen_bne (operands[0]));
1603 operands[1] = gen_compare_reg (UNLE, sparc_compare_op0, sparc_compare_op1);
1606 (define_expand "bltgt"
1608 (if_then_else (ltgt (match_dup 1) (const_int 0))
1609 (label_ref (match_operand 0 "" ""))
1614 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1616 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LTGT);
1617 emit_jump_insn (gen_bne (operands[0]));
1620 operands[1] = gen_compare_reg (LTGT, sparc_compare_op0, sparc_compare_op1);
1623 ;; Now match both normal and inverted jump.
1625 ;; XXX fpcmp nop braindamage
1626 (define_insn "*normal_branch"
1628 (if_then_else (match_operator 0 "noov_compare_op"
1629 [(reg 100) (const_int 0)])
1630 (label_ref (match_operand 1 "" ""))
1635 return output_cbranch (operands[0], operands[1], 1, 0,
1636 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1637 ! final_sequence, insn);
1639 [(set_attr "type" "branch")
1640 (set_attr "branch_type" "icc")])
1642 ;; XXX fpcmp nop braindamage
1643 (define_insn "*inverted_branch"
1645 (if_then_else (match_operator 0 "noov_compare_op"
1646 [(reg 100) (const_int 0)])
1648 (label_ref (match_operand 1 "" ""))))]
1652 return output_cbranch (operands[0], operands[1], 1, 1,
1653 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1654 ! final_sequence, insn);
1656 [(set_attr "type" "branch")
1657 (set_attr "branch_type" "icc")])
1659 ;; XXX fpcmp nop braindamage
1660 (define_insn "*normal_fp_branch"
1662 (if_then_else (match_operator 1 "comparison_operator"
1663 [(match_operand:CCFP 0 "fcc_reg_operand" "c")
1665 (label_ref (match_operand 2 "" ""))
1670 return output_cbranch (operands[1], operands[2], 2, 0,
1671 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1672 ! final_sequence, insn);
1674 [(set_attr "type" "branch")
1675 (set_attr "branch_type" "fcc")])
1677 ;; XXX fpcmp nop braindamage
1678 (define_insn "*inverted_fp_branch"
1680 (if_then_else (match_operator 1 "comparison_operator"
1681 [(match_operand:CCFP 0 "fcc_reg_operand" "c")
1684 (label_ref (match_operand 2 "" ""))))]
1688 return output_cbranch (operands[1], operands[2], 2, 1,
1689 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1690 ! final_sequence, insn);
1692 [(set_attr "type" "branch")
1693 (set_attr "branch_type" "fcc")])
1695 ;; XXX fpcmp nop braindamage
1696 (define_insn "*normal_fpe_branch"
1698 (if_then_else (match_operator 1 "comparison_operator"
1699 [(match_operand:CCFPE 0 "fcc_reg_operand" "c")
1701 (label_ref (match_operand 2 "" ""))
1706 return output_cbranch (operands[1], operands[2], 2, 0,
1707 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1708 ! final_sequence, insn);
1710 [(set_attr "type" "branch")
1711 (set_attr "branch_type" "fcc")])
1713 ;; XXX fpcmp nop braindamage
1714 (define_insn "*inverted_fpe_branch"
1716 (if_then_else (match_operator 1 "comparison_operator"
1717 [(match_operand:CCFPE 0 "fcc_reg_operand" "c")
1720 (label_ref (match_operand 2 "" ""))))]
1724 return output_cbranch (operands[1], operands[2], 2, 1,
1725 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1726 ! final_sequence, insn);
1728 [(set_attr "type" "branch")
1729 (set_attr "branch_type" "fcc")])
1731 ;; Sparc V9-specific jump insns. None of these are guaranteed to be
1732 ;; in the architecture.
1734 ;; There are no 32 bit brreg insns.
1737 (define_insn "*normal_int_branch_sp64"
1739 (if_then_else (match_operator 0 "v9_regcmp_op"
1740 [(match_operand:DI 1 "register_operand" "r")
1742 (label_ref (match_operand 2 "" ""))
1747 return output_v9branch (operands[0], operands[2], 1, 2, 0,
1748 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1749 ! final_sequence, insn);
1751 [(set_attr "type" "branch")
1752 (set_attr "branch_type" "reg")])
1755 (define_insn "*inverted_int_branch_sp64"
1757 (if_then_else (match_operator 0 "v9_regcmp_op"
1758 [(match_operand:DI 1 "register_operand" "r")
1761 (label_ref (match_operand 2 "" ""))))]
1765 return output_v9branch (operands[0], operands[2], 1, 2, 1,
1766 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1767 ! final_sequence, insn);
1769 [(set_attr "type" "branch")
1770 (set_attr "branch_type" "reg")])
1772 ;; Load program counter insns.
1774 (define_insn "get_pc"
1775 [(clobber (reg:SI 15))
1776 (set (match_operand 0 "register_operand" "=r")
1777 (unspec [(match_operand 1 "" "") (match_operand 2 "" "")] UNSPEC_GET_PC))]
1778 "flag_pic && REGNO (operands[0]) == 23"
1779 "sethi\\t%%hi(%a1-4), %0\\n\\tcall\\t%a2\\n\\tadd\\t%0, %%lo(%a1+4), %0"
1780 [(set_attr "type" "multi")
1781 (set_attr "length" "3")])
1783 ;; Currently unused...
1784 ;; (define_insn "get_pc_via_rdpc"
1785 ;; [(set (match_operand 0 "register_operand" "=r") (pc))]
1788 ;; [(set_attr "type" "misc")])
1791 ;; Move instructions
1793 (define_expand "movqi"
1794 [(set (match_operand:QI 0 "general_operand" "")
1795 (match_operand:QI 1 "general_operand" ""))]
1799 /* Working with CONST_INTs is easier, so convert
1800 a double if needed. */
1801 if (GET_CODE (operands[1]) == CONST_DOUBLE)
1803 operands[1] = GEN_INT (trunc_int_for_mode
1804 (CONST_DOUBLE_LOW (operands[1]), QImode));
1807 /* Handle sets of MEM first. */
1808 if (GET_CODE (operands[0]) == MEM)
1810 if (reg_or_0_operand (operands[1], QImode))
1813 if (! reload_in_progress)
1815 operands[0] = validize_mem (operands[0]);
1816 operands[1] = force_reg (QImode, operands[1]);
1820 /* Fixup PIC cases. */
1823 if (CONSTANT_P (operands[1])
1824 && pic_address_needs_scratch (operands[1]))
1825 operands[1] = legitimize_pic_address (operands[1], QImode, 0);
1827 if (symbolic_operand (operands[1], QImode))
1829 operands[1] = legitimize_pic_address (operands[1],
1831 (reload_in_progress ?
1838 /* All QI constants require only one insn, so proceed. */
1844 (define_insn "*movqi_insn"
1845 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m")
1846 (match_operand:QI 1 "input_operand" "rI,m,rJ"))]
1847 "(register_operand (operands[0], QImode)
1848 || reg_or_0_operand (operands[1], QImode))"
1853 [(set_attr "type" "*,load,store")
1854 (set_attr "us3load_type" "*,3cycle,*")])
1856 (define_expand "movhi"
1857 [(set (match_operand:HI 0 "general_operand" "")
1858 (match_operand:HI 1 "general_operand" ""))]
1862 /* Working with CONST_INTs is easier, so convert
1863 a double if needed. */
1864 if (GET_CODE (operands[1]) == CONST_DOUBLE)
1865 operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
1867 /* Handle sets of MEM first. */
1868 if (GET_CODE (operands[0]) == MEM)
1870 if (reg_or_0_operand (operands[1], HImode))
1873 if (! reload_in_progress)
1875 operands[0] = validize_mem (operands[0]);
1876 operands[1] = force_reg (HImode, operands[1]);
1880 /* Fixup PIC cases. */
1883 if (CONSTANT_P (operands[1])
1884 && pic_address_needs_scratch (operands[1]))
1885 operands[1] = legitimize_pic_address (operands[1], HImode, 0);
1887 if (symbolic_operand (operands[1], HImode))
1889 operands[1] = legitimize_pic_address (operands[1],
1891 (reload_in_progress ?
1898 /* This makes sure we will not get rematched due to splittage. */
1899 if (! CONSTANT_P (operands[1]) || input_operand (operands[1], HImode))
1901 else if (CONSTANT_P (operands[1])
1902 && GET_CODE (operands[1]) != HIGH
1903 && GET_CODE (operands[1]) != LO_SUM)
1905 sparc_emit_set_const32 (operands[0], operands[1]);
1912 (define_insn "*movhi_const64_special"
1913 [(set (match_operand:HI 0 "register_operand" "=r")
1914 (match_operand:HI 1 "const64_high_operand" ""))]
1916 "sethi\\t%%hi(%a1), %0")
1918 (define_insn "*movhi_insn"
1919 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1920 (match_operand:HI 1 "input_operand" "rI,K,m,rJ"))]
1921 "(register_operand (operands[0], HImode)
1922 || reg_or_0_operand (operands[1], HImode))"
1925 sethi\\t%%hi(%a1), %0
1928 [(set_attr "type" "*,*,load,store")
1929 (set_attr "us3load_type" "*,*,3cycle,*")])
1931 ;; We always work with constants here.
1932 (define_insn "*movhi_lo_sum"
1933 [(set (match_operand:HI 0 "register_operand" "=r")
1934 (ior:HI (match_operand:HI 1 "arith_operand" "%r")
1935 (match_operand:HI 2 "arith_operand" "I")))]
1939 (define_expand "movsi"
1940 [(set (match_operand:SI 0 "general_operand" "")
1941 (match_operand:SI 1 "general_operand" ""))]
1945 /* Working with CONST_INTs is easier, so convert
1946 a double if needed. */
1947 if (GET_CODE (operands[1]) == CONST_DOUBLE)
1948 operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
1950 /* Handle sets of MEM first. */
1951 if (GET_CODE (operands[0]) == MEM)
1953 if (reg_or_0_operand (operands[1], SImode))
1956 if (! reload_in_progress)
1958 operands[0] = validize_mem (operands[0]);
1959 operands[1] = force_reg (SImode, operands[1]);
1963 /* Fixup PIC cases. */
1966 if (CONSTANT_P (operands[1])
1967 && pic_address_needs_scratch (operands[1]))
1968 operands[1] = legitimize_pic_address (operands[1], SImode, 0);
1970 if (GET_CODE (operands[1]) == LABEL_REF)
1973 emit_insn (gen_movsi_pic_label_ref (operands[0], operands[1]));
1977 if (symbolic_operand (operands[1], SImode))
1979 operands[1] = legitimize_pic_address (operands[1],
1981 (reload_in_progress ?
1988 /* If we are trying to toss an integer constant into the
1989 FPU registers, force it into memory. */
1990 if (GET_CODE (operands[0]) == REG
1991 && REGNO (operands[0]) >= SPARC_FIRST_FP_REG
1992 && REGNO (operands[0]) <= SPARC_LAST_V9_FP_REG
1993 && CONSTANT_P (operands[1]))
1994 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
1997 /* This makes sure we will not get rematched due to splittage. */
1998 if (! CONSTANT_P (operands[1]) || input_operand (operands[1], SImode))
2000 else if (CONSTANT_P (operands[1])
2001 && GET_CODE (operands[1]) != HIGH
2002 && GET_CODE (operands[1]) != LO_SUM)
2004 sparc_emit_set_const32 (operands[0], operands[1]);
2011 ;; This is needed to show CSE exactly which bits are set
2012 ;; in a 64-bit register by sethi instructions.
2013 (define_insn "*movsi_const64_special"
2014 [(set (match_operand:SI 0 "register_operand" "=r")
2015 (match_operand:SI 1 "const64_high_operand" ""))]
2017 "sethi\\t%%hi(%a1), %0")
2019 (define_insn "*movsi_insn"
2020 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,f,r,r,r,f,m,m,d")
2021 (match_operand:SI 1 "input_operand" "rI,!f,K,J,m,!m,rJ,!f,J"))]
2022 "(register_operand (operands[0], SImode)
2023 || reg_or_0_operand (operands[1], SImode))"
2027 sethi\\t%%hi(%a1), %0
2034 [(set_attr "type" "*,fpmove,*,*,load,fpload,store,fpstore,fpmove")])
2036 (define_insn "*movsi_lo_sum"
2037 [(set (match_operand:SI 0 "register_operand" "=r")
2038 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
2039 (match_operand:SI 2 "immediate_operand" "in")))]
2041 "or\\t%1, %%lo(%a2), %0")
2043 (define_insn "*movsi_high"
2044 [(set (match_operand:SI 0 "register_operand" "=r")
2045 (high:SI (match_operand:SI 1 "immediate_operand" "in")))]
2047 "sethi\\t%%hi(%a1), %0")
2049 ;; The next two patterns must wrap the SYMBOL_REF in an UNSPEC
2050 ;; so that CSE won't optimize the address computation away.
2051 (define_insn "movsi_lo_sum_pic"
2052 [(set (match_operand:SI 0 "register_operand" "=r")
2053 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
2054 (unspec:SI [(match_operand:SI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
2056 "or\\t%1, %%lo(%a2), %0")
2058 (define_insn "movsi_high_pic"
2059 [(set (match_operand:SI 0 "register_operand" "=r")
2060 (high:SI (unspec:SI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
2061 "flag_pic && check_pic (1)"
2062 "sethi\\t%%hi(%a1), %0")
2064 (define_expand "movsi_pic_label_ref"
2065 [(set (match_dup 3) (high:SI
2066 (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
2067 (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
2068 (set (match_dup 4) (lo_sum:SI (match_dup 3)
2069 (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
2070 (set (match_operand:SI 0 "register_operand" "=r")
2071 (minus:SI (match_dup 5) (match_dup 4)))]
2075 current_function_uses_pic_offset_table = 1;
2076 operands[2] = gen_rtx_SYMBOL_REF (Pmode, \"_GLOBAL_OFFSET_TABLE_\");
2079 operands[3] = operands[0];
2080 operands[4] = operands[0];
2084 operands[3] = gen_reg_rtx (SImode);
2085 operands[4] = gen_reg_rtx (SImode);
2087 operands[5] = pic_offset_table_rtx;
2090 (define_insn "*movsi_high_pic_label_ref"
2091 [(set (match_operand:SI 0 "register_operand" "=r")
2093 (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
2094 (match_operand:SI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
2096 "sethi\\t%%hi(%a2-(%a1-.)), %0")
2098 (define_insn "*movsi_lo_sum_pic_label_ref"
2099 [(set (match_operand:SI 0 "register_operand" "=r")
2100 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
2101 (unspec:SI [(match_operand:SI 2 "label_ref_operand" "")
2102 (match_operand:SI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
2104 "or\\t%1, %%lo(%a3-(%a2-.)), %0")
2106 (define_expand "movdi"
2107 [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand" "")
2108 (match_operand:DI 1 "general_operand" ""))]
2112 /* Where possible, convert CONST_DOUBLE into a CONST_INT. */
2113 if (GET_CODE (operands[1]) == CONST_DOUBLE
2114 #if HOST_BITS_PER_WIDE_INT == 32
2115 && ((CONST_DOUBLE_HIGH (operands[1]) == 0
2116 && (CONST_DOUBLE_LOW (operands[1]) & 0x80000000) == 0)
2117 || (CONST_DOUBLE_HIGH (operands[1]) == (HOST_WIDE_INT) 0xffffffff
2118 && (CONST_DOUBLE_LOW (operands[1]) & 0x80000000) != 0))
2121 operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
2123 /* Handle MEM cases first. */
2124 if (GET_CODE (operands[0]) == MEM)
2126 /* If it's a REG, we can always do it.
2127 The const zero case is more complex, on v9
2128 we can always perform it. */
2129 if (register_operand (operands[1], DImode)
2131 && (operands[1] == const0_rtx)))
2134 if (! reload_in_progress)
2136 operands[0] = validize_mem (operands[0]);
2137 operands[1] = force_reg (DImode, operands[1]);
2143 if (CONSTANT_P (operands[1])
2144 && pic_address_needs_scratch (operands[1]))
2145 operands[1] = legitimize_pic_address (operands[1], DImode, 0);
2147 if (GET_CODE (operands[1]) == LABEL_REF)
2149 if (! TARGET_ARCH64)
2151 emit_insn (gen_movdi_pic_label_ref (operands[0], operands[1]));
2155 if (symbolic_operand (operands[1], DImode))
2157 operands[1] = legitimize_pic_address (operands[1],
2159 (reload_in_progress ?
2166 /* If we are trying to toss an integer constant into the
2167 FPU registers, force it into memory. */
2168 if (GET_CODE (operands[0]) == REG
2169 && REGNO (operands[0]) >= SPARC_FIRST_FP_REG
2170 && REGNO (operands[0]) <= SPARC_LAST_V9_FP_REG
2171 && CONSTANT_P (operands[1]))
2172 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
2175 /* This makes sure we will not get rematched due to splittage. */
2176 if (! CONSTANT_P (operands[1]) || input_operand (operands[1], DImode))
2178 else if (TARGET_ARCH64
2179 && CONSTANT_P (operands[1])
2180 && GET_CODE (operands[1]) != HIGH
2181 && GET_CODE (operands[1]) != LO_SUM)
2183 sparc_emit_set_const64 (operands[0], operands[1]);
2191 ;; Be careful, fmovd does not exist when !arch64.
2192 ;; We match MEM moves directly when we have correct even
2193 ;; numbered registers, but fall into splits otherwise.
2194 ;; The constraint ordering here is really important to
2195 ;; avoid insane problems in reload, especially for patterns
2198 ;; (set (mem:DI (plus:SI (reg:SI 30 %fp)
2199 ;; (const_int -5016)))
2203 (define_insn "*movdi_insn_sp32_v9"
2204 [(set (match_operand:DI 0 "nonimmediate_operand"
2205 "=T,o,T,U,o,r,r,r,?T,?f,?f,?o,?f")
2206 (match_operand:DI 1 "input_operand"
2207 " J,J,U,T,r,o,i,r, f, T, o, f, f"))]
2208 "! TARGET_ARCH64 && TARGET_V9
2209 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2224 [(set_attr "type" "store,store,store,load,*,*,*,*,fpstore,fpload,*,*,*")
2225 (set_attr "length" "*,2,*,*,2,2,2,2,*,*,2,2,2")])
2227 (define_insn "*movdi_insn_sp32"
2228 [(set (match_operand:DI 0 "nonimmediate_operand"
2229 "=o,T,U,o,r,r,r,?T,?f,?f,?o,?f")
2230 (match_operand:DI 1 "input_operand"
2231 " J,U,T,r,o,i,r, f, T, o, f, f"))]
2233 && (register_operand (operands[0], DImode)
2234 || register_operand (operands[1], DImode))"
2248 [(set_attr "type" "store,store,load,*,*,*,*,fpstore,fpload,*,*,*")
2249 (set_attr "length" "2,*,*,2,2,2,2,*,*,2,2,2")])
2251 ;; The following are generated by sparc_emit_set_const64
2252 (define_insn "*movdi_sp64_dbl"
2253 [(set (match_operand:DI 0 "register_operand" "=r")
2254 (match_operand:DI 1 "const64_operand" ""))]
2256 && HOST_BITS_PER_WIDE_INT != 64)"
2259 ;; This is needed to show CSE exactly which bits are set
2260 ;; in a 64-bit register by sethi instructions.
2261 (define_insn "*movdi_const64_special"
2262 [(set (match_operand:DI 0 "register_operand" "=r")
2263 (match_operand:DI 1 "const64_high_operand" ""))]
2265 "sethi\\t%%hi(%a1), %0")
2267 (define_insn "*movdi_insn_sp64_novis"
2268 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,m,?e,?e,?W")
2269 (match_operand:DI 1 "input_operand" "rI,N,J,m,rJ,e,W,e"))]
2270 "TARGET_ARCH64 && ! TARGET_VIS
2271 && (register_operand (operands[0], DImode)
2272 || reg_or_0_operand (operands[1], DImode))"
2275 sethi\\t%%hi(%a1), %0
2282 [(set_attr "type" "*,*,*,load,store,fpmove,fpload,fpstore")
2283 (set_attr "fptype" "*,*,*,*,*,double,*,*")])
2285 (define_insn "*movdi_insn_sp64_vis"
2286 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,m,?e,?e,?W,b")
2287 (match_operand:DI 1 "input_operand" "rI,N,J,m,rJ,e,W,e,J"))]
2288 "TARGET_ARCH64 && TARGET_VIS &&
2289 (register_operand (operands[0], DImode)
2290 || reg_or_0_operand (operands[1], DImode))"
2293 sethi\\t%%hi(%a1), %0
2301 [(set_attr "type" "*,*,*,load,store,fpmove,fpload,fpstore,fpmove")
2302 (set_attr "fptype" "*,*,*,*,*,double,*,*,double")])
2304 (define_expand "movdi_pic_label_ref"
2305 [(set (match_dup 3) (high:DI
2306 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
2307 (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
2308 (set (match_dup 4) (lo_sum:DI (match_dup 3)
2309 (unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
2310 (set (match_operand:DI 0 "register_operand" "=r")
2311 (minus:DI (match_dup 5) (match_dup 4)))]
2312 "TARGET_ARCH64 && flag_pic"
2315 current_function_uses_pic_offset_table = 1;
2316 operands[2] = gen_rtx_SYMBOL_REF (Pmode, \"_GLOBAL_OFFSET_TABLE_\");
2319 operands[3] = operands[0];
2320 operands[4] = operands[0];
2324 operands[3] = gen_reg_rtx (DImode);
2325 operands[4] = gen_reg_rtx (DImode);
2327 operands[5] = pic_offset_table_rtx;
2330 (define_insn "*movdi_high_pic_label_ref"
2331 [(set (match_operand:DI 0 "register_operand" "=r")
2333 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
2334 (match_operand:DI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
2335 "TARGET_ARCH64 && flag_pic"
2336 "sethi\\t%%hi(%a2-(%a1-.)), %0")
2338 (define_insn "*movdi_lo_sum_pic_label_ref"
2339 [(set (match_operand:DI 0 "register_operand" "=r")
2340 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2341 (unspec:DI [(match_operand:DI 2 "label_ref_operand" "")
2342 (match_operand:DI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
2343 "TARGET_ARCH64 && flag_pic"
2344 "or\\t%1, %%lo(%a3-(%a2-.)), %0")
2346 ;; Sparc-v9 code model support insns. See sparc_emit_set_symbolic_const64
2347 ;; in sparc.c to see what is going on here... PIC stuff comes first.
2349 (define_insn "movdi_lo_sum_pic"
2350 [(set (match_operand:DI 0 "register_operand" "=r")
2351 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2352 (unspec:DI [(match_operand:DI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
2353 "TARGET_ARCH64 && flag_pic"
2354 "or\\t%1, %%lo(%a2), %0")
2356 (define_insn "movdi_high_pic"
2357 [(set (match_operand:DI 0 "register_operand" "=r")
2358 (high:DI (unspec:DI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
2359 "TARGET_ARCH64 && flag_pic && check_pic (1)"
2360 "sethi\\t%%hi(%a1), %0")
2362 (define_insn "*sethi_di_medlow_embmedany_pic"
2363 [(set (match_operand:DI 0 "register_operand" "=r")
2364 (high:DI (match_operand:DI 1 "sp64_medium_pic_operand" "")))]
2365 "(TARGET_CM_MEDLOW || TARGET_CM_EMBMEDANY) && check_pic (1)"
2366 "sethi\\t%%hi(%a1), %0")
2368 (define_insn "*sethi_di_medlow"
2369 [(set (match_operand:DI 0 "register_operand" "=r")
2370 (high:DI (match_operand:DI 1 "symbolic_operand" "")))]
2371 "TARGET_CM_MEDLOW && check_pic (1)"
2372 "sethi\\t%%hi(%a1), %0")
2374 (define_insn "*losum_di_medlow"
2375 [(set (match_operand:DI 0 "register_operand" "=r")
2376 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2377 (match_operand:DI 2 "symbolic_operand" "")))]
2379 "or\\t%1, %%lo(%a2), %0")
2381 (define_insn "seth44"
2382 [(set (match_operand:DI 0 "register_operand" "=r")
2383 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETH44)))]
2385 "sethi\\t%%h44(%a1), %0")
2387 (define_insn "setm44"
2388 [(set (match_operand:DI 0 "register_operand" "=r")
2389 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2390 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_SETM44)))]
2392 "or\\t%1, %%m44(%a2), %0")
2394 (define_insn "setl44"
2395 [(set (match_operand:DI 0 "register_operand" "=r")
2396 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2397 (match_operand:DI 2 "symbolic_operand" "")))]
2399 "or\\t%1, %%l44(%a2), %0")
2401 (define_insn "sethh"
2402 [(set (match_operand:DI 0 "register_operand" "=r")
2403 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETHH)))]
2405 "sethi\\t%%hh(%a1), %0")
2407 (define_insn "setlm"
2408 [(set (match_operand:DI 0 "register_operand" "=r")
2409 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETLM)))]
2411 "sethi\\t%%lm(%a1), %0")
2413 (define_insn "sethm"
2414 [(set (match_operand:DI 0 "register_operand" "=r")
2415 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2416 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_EMB_SETHM)))]
2418 "or\\t%1, %%hm(%a2), %0")
2420 (define_insn "setlo"
2421 [(set (match_operand:DI 0 "register_operand" "=r")
2422 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2423 (match_operand:DI 2 "symbolic_operand" "")))]
2425 "or\\t%1, %%lo(%a2), %0")
2427 (define_insn "embmedany_sethi"
2428 [(set (match_operand:DI 0 "register_operand" "=r")
2429 (high:DI (unspec:DI [(match_operand:DI 1 "data_segment_operand" "")] UNSPEC_EMB_HISUM)))]
2430 "TARGET_CM_EMBMEDANY && check_pic (1)"
2431 "sethi\\t%%hi(%a1), %0")
2433 (define_insn "embmedany_losum"
2434 [(set (match_operand:DI 0 "register_operand" "=r")
2435 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2436 (match_operand:DI 2 "data_segment_operand" "")))]
2437 "TARGET_CM_EMBMEDANY"
2438 "add\\t%1, %%lo(%a2), %0")
2440 (define_insn "embmedany_brsum"
2441 [(set (match_operand:DI 0 "register_operand" "=r")
2442 (unspec:DI [(match_operand:DI 1 "register_operand" "r")] UNSPEC_EMB_HISUM))]
2443 "TARGET_CM_EMBMEDANY"
2446 (define_insn "embmedany_textuhi"
2447 [(set (match_operand:DI 0 "register_operand" "=r")
2448 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTUHI)))]
2449 "TARGET_CM_EMBMEDANY && check_pic (1)"
2450 "sethi\\t%%uhi(%a1), %0")
2452 (define_insn "embmedany_texthi"
2453 [(set (match_operand:DI 0 "register_operand" "=r")
2454 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTHI)))]
2455 "TARGET_CM_EMBMEDANY && check_pic (1)"
2456 "sethi\\t%%hi(%a1), %0")
2458 (define_insn "embmedany_textulo"
2459 [(set (match_operand:DI 0 "register_operand" "=r")
2460 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2461 (unspec:DI [(match_operand:DI 2 "text_segment_operand" "")] UNSPEC_EMB_TEXTULO)))]
2462 "TARGET_CM_EMBMEDANY"
2463 "or\\t%1, %%ulo(%a2), %0")
2465 (define_insn "embmedany_textlo"
2466 [(set (match_operand:DI 0 "register_operand" "=r")
2467 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2468 (match_operand:DI 2 "text_segment_operand" "")))]
2469 "TARGET_CM_EMBMEDANY"
2470 "or\\t%1, %%lo(%a2), %0")
2472 ;; Now some patterns to help reload out a bit.
2473 (define_expand "reload_indi"
2474 [(parallel [(match_operand:DI 0 "register_operand" "=r")
2475 (match_operand:DI 1 "immediate_operand" "")
2476 (match_operand:TI 2 "register_operand" "=&r")])]
2478 || TARGET_CM_EMBMEDANY)
2482 sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
2486 (define_expand "reload_outdi"
2487 [(parallel [(match_operand:DI 0 "register_operand" "=r")
2488 (match_operand:DI 1 "immediate_operand" "")
2489 (match_operand:TI 2 "register_operand" "=&r")])]
2491 || TARGET_CM_EMBMEDANY)
2495 sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
2499 ;; Split up putting CONSTs and REGs into DI regs when !arch64
2501 [(set (match_operand:DI 0 "register_operand" "")
2502 (match_operand:DI 1 "const_int_operand" ""))]
2503 "! TARGET_ARCH64 && reload_completed"
2504 [(clobber (const_int 0))]
2507 #if HOST_BITS_PER_WIDE_INT == 32
2508 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
2509 (INTVAL (operands[1]) < 0) ?
2512 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2515 unsigned int low, high;
2517 low = trunc_int_for_mode (INTVAL (operands[1]), SImode);
2518 high = trunc_int_for_mode (INTVAL (operands[1]) >> 32, SImode);
2519 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), GEN_INT (high)));
2521 /* Slick... but this trick loses if this subreg constant part
2522 can be done in one insn. */
2523 if (low == high && (low & 0x3ff) != 0 && low + 0x1000 >= 0x2000)
2524 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2525 gen_highpart (SImode, operands[0])));
2527 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), GEN_INT (low)));
2533 [(set (match_operand:DI 0 "register_operand" "")
2534 (match_operand:DI 1 "const_double_operand" ""))]
2535 "! TARGET_ARCH64 && reload_completed"
2536 [(clobber (const_int 0))]
2539 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
2540 GEN_INT (CONST_DOUBLE_HIGH (operands[1]))));
2542 /* Slick... but this trick loses if this subreg constant part
2543 can be done in one insn. */
2544 if (CONST_DOUBLE_LOW (operands[1]) == CONST_DOUBLE_HIGH (operands[1])
2545 && !(SPARC_SETHI32_P (CONST_DOUBLE_HIGH (operands[1]))
2546 || SPARC_SIMM13_P (CONST_DOUBLE_HIGH (operands[1]))))
2548 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2549 gen_highpart (SImode, operands[0])));
2553 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2554 GEN_INT (CONST_DOUBLE_LOW (operands[1]))));
2560 [(set (match_operand:DI 0 "register_operand" "")
2561 (match_operand:DI 1 "register_operand" ""))]
2562 "! TARGET_ARCH64 && reload_completed"
2563 [(clobber (const_int 0))]
2566 rtx set_dest = operands[0];
2567 rtx set_src = operands[1];
2571 dest1 = gen_highpart (SImode, set_dest);
2572 dest2 = gen_lowpart (SImode, set_dest);
2573 src1 = gen_highpart (SImode, set_src);
2574 src2 = gen_lowpart (SImode, set_src);
2576 /* Now emit using the real source and destination we found, swapping
2577 the order if we detect overlap. */
2578 if (reg_overlap_mentioned_p (dest1, src2))
2580 emit_insn (gen_movsi (dest2, src2));
2581 emit_insn (gen_movsi (dest1, src1));
2585 emit_insn (gen_movsi (dest1, src1));
2586 emit_insn (gen_movsi (dest2, src2));
2591 ;; Now handle the cases of memory moves from/to non-even
2592 ;; DI mode register pairs.
2594 [(set (match_operand:DI 0 "register_operand" "")
2595 (match_operand:DI 1 "memory_operand" ""))]
2598 && sparc_splitdi_legitimate (operands[0], operands[1]))"
2599 [(clobber (const_int 0))]
2602 rtx word0 = adjust_address (operands[1], SImode, 0);
2603 rtx word1 = adjust_address (operands[1], SImode, 4);
2604 rtx high_part = gen_highpart (SImode, operands[0]);
2605 rtx low_part = gen_lowpart (SImode, operands[0]);
2607 if (reg_overlap_mentioned_p (high_part, word1))
2609 emit_insn (gen_movsi (low_part, word1));
2610 emit_insn (gen_movsi (high_part, word0));
2614 emit_insn (gen_movsi (high_part, word0));
2615 emit_insn (gen_movsi (low_part, word1));
2621 [(set (match_operand:DI 0 "memory_operand" "")
2622 (match_operand:DI 1 "register_operand" ""))]
2625 && sparc_splitdi_legitimate (operands[1], operands[0]))"
2626 [(clobber (const_int 0))]
2629 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0),
2630 gen_highpart (SImode, operands[1])));
2631 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4),
2632 gen_lowpart (SImode, operands[1])));
2637 [(set (match_operand:DI 0 "memory_operand" "")
2642 && ! mem_min_alignment (operands[0], 8)))
2643 && offsettable_memref_p (operands[0])"
2644 [(clobber (const_int 0))]
2647 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0), const0_rtx));
2648 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4), const0_rtx));
2652 ;; Floating point move insns
2654 (define_insn "*movsf_insn_novis"
2655 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,*r,*r,*r,*r,*r,f,m,m")
2656 (match_operand:SF 1 "input_operand" "f,G,Q,*rR,S,m,m,f,*rG"))]
2657 "(TARGET_FPU && ! TARGET_VIS)
2658 && (register_operand (operands[0], SFmode)
2659 || register_operand (operands[1], SFmode)
2660 || fp_zero_operand (operands[1], SFmode))"
2663 if (GET_CODE (operands[1]) == CONST_DOUBLE
2664 && (which_alternative == 2
2665 || which_alternative == 3
2666 || which_alternative == 4))
2671 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2672 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2673 operands[1] = GEN_INT (i);
2676 switch (which_alternative)
2679 return \"fmovs\\t%1, %0\";
2681 return \"clr\\t%0\";
2683 return \"sethi\\t%%hi(%a1), %0\";
2685 return \"mov\\t%1, %0\";
2690 return \"ld\\t%1, %0\";
2693 return \"st\\t%r1, %0\";
2698 [(set_attr "type" "fpmove,*,*,*,*,load,fpload,fpstore,store")])
2700 (define_insn "*movsf_insn_vis"
2701 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,*r,*r,*r,*r,*r,f,m,m")
2702 (match_operand:SF 1 "input_operand" "f,G,G,Q,*rR,S,m,m,f,*rG"))]
2703 "(TARGET_FPU && TARGET_VIS)
2704 && (register_operand (operands[0], SFmode)
2705 || register_operand (operands[1], SFmode)
2706 || fp_zero_operand (operands[1], SFmode))"
2709 if (GET_CODE (operands[1]) == CONST_DOUBLE
2710 && (which_alternative == 3
2711 || which_alternative == 4
2712 || which_alternative == 5))
2717 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2718 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2719 operands[1] = GEN_INT (i);
2722 switch (which_alternative)
2725 return \"fmovs\\t%1, %0\";
2727 return \"fzeros\\t%0\";
2729 return \"clr\\t%0\";
2731 return \"sethi\\t%%hi(%a1), %0\";
2733 return \"mov\\t%1, %0\";
2738 return \"ld\\t%1, %0\";
2741 return \"st\\t%r1, %0\";
2746 [(set_attr "type" "fpmove,fpmove,*,*,*,*,load,fpload,fpstore,store")])
2748 ;; Exactly the same as above, except that all `f' cases are deleted.
2749 ;; This is necessary to prevent reload from ever trying to use a `f' reg
2752 (define_insn "*movsf_no_f_insn"
2753 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r,r,r,m")
2754 (match_operand:SF 1 "input_operand" "G,Q,rR,S,m,rG"))]
2756 && (register_operand (operands[0], SFmode)
2757 || register_operand (operands[1], SFmode)
2758 || fp_zero_operand (operands[1], SFmode))"
2761 if (GET_CODE (operands[1]) == CONST_DOUBLE
2762 && (which_alternative == 1
2763 || which_alternative == 2
2764 || which_alternative == 3))
2769 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2770 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2771 operands[1] = GEN_INT (i);
2774 switch (which_alternative)
2777 return \"clr\\t%0\";
2779 return \"sethi\\t%%hi(%a1), %0\";
2781 return \"mov\\t%1, %0\";
2785 return \"ld\\t%1, %0\";
2787 return \"st\\t%r1, %0\";
2792 [(set_attr "type" "*,*,*,*,load,store")])
2794 (define_insn "*movsf_lo_sum"
2795 [(set (match_operand:SF 0 "register_operand" "=r")
2796 (lo_sum:SF (match_operand:SF 1 "register_operand" "r")
2797 (match_operand:SF 2 "const_double_operand" "S")))]
2798 "fp_high_losum_p (operands[2])"
2804 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[2]);
2805 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2806 operands[2] = GEN_INT (i);
2807 return \"or\\t%1, %%lo(%a2), %0\";
2810 (define_insn "*movsf_high"
2811 [(set (match_operand:SF 0 "register_operand" "=r")
2812 (high:SF (match_operand:SF 1 "const_double_operand" "S")))]
2813 "fp_high_losum_p (operands[1])"
2819 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2820 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2821 operands[1] = GEN_INT (i);
2822 return \"sethi\\t%%hi(%1), %0\";
2826 [(set (match_operand:SF 0 "register_operand" "")
2827 (match_operand:SF 1 "const_double_operand" ""))]
2828 "fp_high_losum_p (operands[1])
2829 && (GET_CODE (operands[0]) == REG
2830 && REGNO (operands[0]) < 32)"
2831 [(set (match_dup 0) (high:SF (match_dup 1)))
2832 (set (match_dup 0) (lo_sum:SF (match_dup 0) (match_dup 1)))])
2834 (define_expand "movsf"
2835 [(set (match_operand:SF 0 "general_operand" "")
2836 (match_operand:SF 1 "general_operand" ""))]
2840 /* Force SFmode constants into memory. */
2841 if (GET_CODE (operands[0]) == REG
2842 && CONSTANT_P (operands[1]))
2844 /* emit_group_store will send such bogosity to us when it is
2845 not storing directly into memory. So fix this up to avoid
2846 crashes in output_constant_pool. */
2847 if (operands [1] == const0_rtx)
2848 operands[1] = CONST0_RTX (SFmode);
2850 if (TARGET_VIS && fp_zero_operand (operands[1], SFmode))
2853 /* We are able to build any SF constant in integer registers
2854 with at most 2 instructions. */
2855 if (REGNO (operands[0]) < 32)
2858 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
2862 /* Handle sets of MEM first. */
2863 if (GET_CODE (operands[0]) == MEM)
2865 if (register_operand (operands[1], SFmode)
2866 || fp_zero_operand (operands[1], SFmode))
2869 if (! reload_in_progress)
2871 operands[0] = validize_mem (operands[0]);
2872 operands[1] = force_reg (SFmode, operands[1]);
2876 /* Fixup PIC cases. */
2879 if (CONSTANT_P (operands[1])
2880 && pic_address_needs_scratch (operands[1]))
2881 operands[1] = legitimize_pic_address (operands[1], SFmode, 0);
2883 if (symbolic_operand (operands[1], SFmode))
2885 operands[1] = legitimize_pic_address (operands[1],
2887 (reload_in_progress ?
2897 (define_expand "movdf"
2898 [(set (match_operand:DF 0 "general_operand" "")
2899 (match_operand:DF 1 "general_operand" ""))]
2903 /* Force DFmode constants into memory. */
2904 if (GET_CODE (operands[0]) == REG
2905 && CONSTANT_P (operands[1]))
2907 /* emit_group_store will send such bogosity to us when it is
2908 not storing directly into memory. So fix this up to avoid
2909 crashes in output_constant_pool. */
2910 if (operands [1] == const0_rtx)
2911 operands[1] = CONST0_RTX (DFmode);
2913 if ((TARGET_VIS || REGNO (operands[0]) < 32)
2914 && fp_zero_operand (operands[1], DFmode))
2917 /* We are able to build any DF constant in integer registers. */
2918 if (REGNO (operands[0]) < 32
2919 && (reload_completed || reload_in_progress))
2922 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
2926 /* Handle MEM cases first. */
2927 if (GET_CODE (operands[0]) == MEM)
2929 if (register_operand (operands[1], DFmode)
2930 || fp_zero_operand (operands[1], DFmode))
2933 if (! reload_in_progress)
2935 operands[0] = validize_mem (operands[0]);
2936 operands[1] = force_reg (DFmode, operands[1]);
2940 /* Fixup PIC cases. */
2943 if (CONSTANT_P (operands[1])
2944 && pic_address_needs_scratch (operands[1]))
2945 operands[1] = legitimize_pic_address (operands[1], DFmode, 0);
2947 if (symbolic_operand (operands[1], DFmode))
2949 operands[1] = legitimize_pic_address (operands[1],
2951 (reload_in_progress ?
2961 ;; Be careful, fmovd does not exist when !v9.
2962 (define_insn "*movdf_insn_sp32"
2963 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,W,U,T,o,e,*r,o,e,o")
2964 (match_operand:DF 1 "input_operand" "W#F,e,T,U,G,e,*rFo,*r,o#F,e"))]
2967 && (register_operand (operands[0], DFmode)
2968 || register_operand (operands[1], DFmode)
2969 || fp_zero_operand (operands[1], DFmode))"
2981 [(set_attr "type" "fpload,fpstore,load,store,*,*,*,*,*,*")
2982 (set_attr "length" "*,*,*,*,2,2,2,2,2,2")])
2984 (define_insn "*movdf_no_e_insn_sp32"
2985 [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,o,r,o")
2986 (match_operand:DF 1 "input_operand" "T,U,G,ro,r"))]
2990 && (register_operand (operands[0], DFmode)
2991 || register_operand (operands[1], DFmode)
2992 || fp_zero_operand (operands[1], DFmode))"
2999 [(set_attr "type" "load,store,*,*,*")
3000 (set_attr "length" "*,*,2,2,2")])
3002 (define_insn "*movdf_no_e_insn_v9_sp32"
3003 [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,T,r,o")
3004 (match_operand:DF 1 "input_operand" "T,U,G,ro,rG"))]
3008 && (register_operand (operands[0], DFmode)
3009 || register_operand (operands[1], DFmode)
3010 || fp_zero_operand (operands[1], DFmode))"
3017 [(set_attr "type" "load,store,store,*,*")
3018 (set_attr "length" "*,*,*,2,2")])
3020 ;; We have available v9 double floats but not 64-bit
3021 ;; integer registers and no VIS.
3022 (define_insn "*movdf_insn_v9only_novis"
3023 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,T,W,U,T,f,*r,o")
3024 (match_operand:DF 1 "input_operand" "e,W#F,G,e,T,U,o#F,*roF,*rGf"))]
3029 && (register_operand (operands[0], DFmode)
3030 || register_operand (operands[1], DFmode)
3031 || fp_zero_operand (operands[1], DFmode))"
3042 [(set_attr "type" "fpmove,load,store,store,load,store,*,*,*")
3043 (set_attr "length" "*,*,*,*,*,*,2,2,2")
3044 (set_attr "fptype" "double,*,*,*,*,*,*,*,*")])
3046 ;; We have available v9 double floats but not 64-bit
3047 ;; integer registers but we have VIS.
3048 (define_insn "*movdf_insn_v9only_vis"
3049 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,e,T,W,U,T,f,*r,o")
3050 (match_operand:DF 1 "input_operand" "G,e,W#F,G,e,T,U,o#F,*roGF,*rGf"))]
3054 && (register_operand (operands[0], DFmode)
3055 || register_operand (operands[1], DFmode)
3056 || fp_zero_operand (operands[1], DFmode))"
3068 [(set_attr "type" "fpmove,fpmove,load,store,store,load,store,*,*,*")
3069 (set_attr "length" "*,*,*,*,*,*,*,2,2,2")
3070 (set_attr "fptype" "double,double,*,*,*,*,*,*,*,*")])
3072 ;; We have available both v9 double floats and 64-bit
3073 ;; integer registers. No VIS though.
3074 (define_insn "*movdf_insn_sp64_novis"
3075 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,W,*r,*r,m,*r")
3076 (match_operand:DF 1 "input_operand" "e,W#F,e,*rG,m,*rG,F"))]
3080 && (register_operand (operands[0], DFmode)
3081 || register_operand (operands[1], DFmode)
3082 || fp_zero_operand (operands[1], DFmode))"
3091 [(set_attr "type" "fpmove,load,store,*,load,store,*")
3092 (set_attr "length" "*,*,*,*,*,*,2")
3093 (set_attr "fptype" "double,*,*,*,*,*,*")])
3095 ;; We have available both v9 double floats and 64-bit
3096 ;; integer registers. And we have VIS.
3097 (define_insn "*movdf_insn_sp64_vis"
3098 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,e,W,*r,*r,m,*r")
3099 (match_operand:DF 1 "input_operand" "G,e,W#F,e,*rG,m,*rG,F"))]
3103 && (register_operand (operands[0], DFmode)
3104 || register_operand (operands[1], DFmode)
3105 || fp_zero_operand (operands[1], DFmode))"
3115 [(set_attr "type" "fpmove,fpmove,load,store,*,load,store,*")
3116 (set_attr "length" "*,*,*,*,*,*,*,2")
3117 (set_attr "fptype" "double,double,*,*,*,*,*,*")])
3119 (define_insn "*movdf_no_e_insn_sp64"
3120 [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m")
3121 (match_operand:DF 1 "input_operand" "r,m,rG"))]
3124 && (register_operand (operands[0], DFmode)
3125 || register_operand (operands[1], DFmode)
3126 || fp_zero_operand (operands[1], DFmode))"
3131 [(set_attr "type" "*,load,store")])
3134 [(set (match_operand:DF 0 "register_operand" "")
3135 (match_operand:DF 1 "const_double_operand" ""))]
3137 && (GET_CODE (operands[0]) == REG
3138 && REGNO (operands[0]) < 32)
3139 && ! fp_zero_operand(operands[1], DFmode)
3140 && reload_completed"
3141 [(clobber (const_int 0))]
3147 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3148 REAL_VALUE_TO_TARGET_DOUBLE (r, l);
3149 operands[0] = gen_rtx_raw_REG (DImode, REGNO (operands[0]));
3153 #if HOST_BITS_PER_WIDE_INT == 64
3156 val = ((HOST_WIDE_INT)(unsigned long)l[1] |
3157 ((HOST_WIDE_INT)(unsigned long)l[0] << 32));
3158 emit_insn (gen_movdi (operands[0], GEN_INT (val)));
3160 emit_insn (gen_movdi (operands[0],
3161 immed_double_const (l[1], l[0], DImode)));
3166 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
3169 /* Slick... but this trick loses if this subreg constant part
3170 can be done in one insn. */
3172 && !(SPARC_SETHI32_P (l[0])
3173 || SPARC_SIMM13_P (l[0])))
3175 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
3176 gen_highpart (SImode, operands[0])));
3180 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
3187 ;; Ok, now the splits to handle all the multi insn and
3188 ;; mis-aligned memory address cases.
3189 ;; In these splits please take note that we must be
3190 ;; careful when V9 but not ARCH64 because the integer
3191 ;; register DFmode cases must be handled.
3193 [(set (match_operand:DF 0 "register_operand" "")
3194 (match_operand:DF 1 "register_operand" ""))]
3197 && ((GET_CODE (operands[0]) == REG
3198 && REGNO (operands[0]) < 32)
3199 || (GET_CODE (operands[0]) == SUBREG
3200 && GET_CODE (SUBREG_REG (operands[0])) == REG
3201 && REGNO (SUBREG_REG (operands[0])) < 32))))
3202 && reload_completed"
3203 [(clobber (const_int 0))]
3206 rtx set_dest = operands[0];
3207 rtx set_src = operands[1];
3211 dest1 = gen_highpart (SFmode, set_dest);
3212 dest2 = gen_lowpart (SFmode, set_dest);
3213 src1 = gen_highpart (SFmode, set_src);
3214 src2 = gen_lowpart (SFmode, set_src);
3216 /* Now emit using the real source and destination we found, swapping
3217 the order if we detect overlap. */
3218 if (reg_overlap_mentioned_p (dest1, src2))
3220 emit_insn (gen_movsf (dest2, src2));
3221 emit_insn (gen_movsf (dest1, src1));
3225 emit_insn (gen_movsf (dest1, src1));
3226 emit_insn (gen_movsf (dest2, src2));
3232 [(set (match_operand:DF 0 "register_operand" "")
3233 (match_operand:DF 1 "memory_operand" ""))]
3236 && (((REGNO (operands[0]) % 2) != 0)
3237 || ! mem_min_alignment (operands[1], 8))
3238 && offsettable_memref_p (operands[1])"
3239 [(clobber (const_int 0))]
3242 rtx word0 = adjust_address (operands[1], SFmode, 0);
3243 rtx word1 = adjust_address (operands[1], SFmode, 4);
3245 if (reg_overlap_mentioned_p (gen_highpart (SFmode, operands[0]), word1))
3247 emit_insn (gen_movsf (gen_lowpart (SFmode, operands[0]),
3249 emit_insn (gen_movsf (gen_highpart (SFmode, operands[0]),
3254 emit_insn (gen_movsf (gen_highpart (SFmode, operands[0]),
3256 emit_insn (gen_movsf (gen_lowpart (SFmode, operands[0]),
3263 [(set (match_operand:DF 0 "memory_operand" "")
3264 (match_operand:DF 1 "register_operand" ""))]
3267 && (((REGNO (operands[1]) % 2) != 0)
3268 || ! mem_min_alignment (operands[0], 8))
3269 && offsettable_memref_p (operands[0])"
3270 [(clobber (const_int 0))]
3273 rtx word0 = adjust_address (operands[0], SFmode, 0);
3274 rtx word1 = adjust_address (operands[0], SFmode, 4);
3276 emit_insn (gen_movsf (word0,
3277 gen_highpart (SFmode, operands[1])));
3278 emit_insn (gen_movsf (word1,
3279 gen_lowpart (SFmode, operands[1])));
3284 [(set (match_operand:DF 0 "memory_operand" "")
3285 (match_operand:DF 1 "fp_zero_operand" ""))]
3289 && ! mem_min_alignment (operands[0], 8)))
3290 && offsettable_memref_p (operands[0])"
3291 [(clobber (const_int 0))]
3296 dest1 = adjust_address (operands[0], SFmode, 0);
3297 dest2 = adjust_address (operands[0], SFmode, 4);
3299 emit_insn (gen_movsf (dest1, CONST0_RTX (SFmode)));
3300 emit_insn (gen_movsf (dest2, CONST0_RTX (SFmode)));
3305 [(set (match_operand:DF 0 "register_operand" "")
3306 (match_operand:DF 1 "fp_zero_operand" ""))]
3309 && ((GET_CODE (operands[0]) == REG
3310 && REGNO (operands[0]) < 32)
3311 || (GET_CODE (operands[0]) == SUBREG
3312 && GET_CODE (SUBREG_REG (operands[0])) == REG
3313 && REGNO (SUBREG_REG (operands[0])) < 32))"
3314 [(clobber (const_int 0))]
3317 rtx set_dest = operands[0];
3320 dest1 = gen_highpart (SFmode, set_dest);
3321 dest2 = gen_lowpart (SFmode, set_dest);
3322 emit_insn (gen_movsf (dest1, CONST0_RTX (SFmode)));
3323 emit_insn (gen_movsf (dest2, CONST0_RTX (SFmode)));
3327 (define_expand "movtf"
3328 [(set (match_operand:TF 0 "general_operand" "")
3329 (match_operand:TF 1 "general_operand" ""))]
3333 /* Force TFmode constants into memory. */
3334 if (GET_CODE (operands[0]) == REG
3335 && CONSTANT_P (operands[1]))
3337 /* emit_group_store will send such bogosity to us when it is
3338 not storing directly into memory. So fix this up to avoid
3339 crashes in output_constant_pool. */
3340 if (operands [1] == const0_rtx)
3341 operands[1] = CONST0_RTX (TFmode);
3343 if (TARGET_VIS && fp_zero_operand (operands[1], TFmode))
3346 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
3350 /* Handle MEM cases first, note that only v9 guarentees
3351 full 16-byte alignment for quads. */
3352 if (GET_CODE (operands[0]) == MEM)
3354 if (register_operand (operands[1], TFmode)
3355 || fp_zero_operand (operands[1], TFmode))
3358 if (! reload_in_progress)
3360 operands[0] = validize_mem (operands[0]);
3361 operands[1] = force_reg (TFmode, operands[1]);
3365 /* Fixup PIC cases. */
3368 if (CONSTANT_P (operands[1])
3369 && pic_address_needs_scratch (operands[1]))
3370 operands[1] = legitimize_pic_address (operands[1], TFmode, 0);
3372 if (symbolic_operand (operands[1], TFmode))
3374 operands[1] = legitimize_pic_address (operands[1],
3376 (reload_in_progress ?
3386 ;; Be careful, fmovq and {st,ld}{x,q} do not exist when !arch64 so
3387 ;; we must split them all. :-(
3388 (define_insn "*movtf_insn_sp32"
3389 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,U,r")
3390 (match_operand:TF 1 "input_operand" "oe,GeUr,o,roG"))]
3394 && (register_operand (operands[0], TFmode)
3395 || register_operand (operands[1], TFmode)
3396 || fp_zero_operand (operands[1], TFmode))"
3398 [(set_attr "length" "4")])
3400 (define_insn "*movtf_insn_vis_sp32"
3401 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,U,r")
3402 (match_operand:TF 1 "input_operand" "Goe,GeUr,o,roG"))]
3406 && (register_operand (operands[0], TFmode)
3407 || register_operand (operands[1], TFmode)
3408 || fp_zero_operand (operands[1], TFmode))"
3410 [(set_attr "length" "4")])
3412 ;; Exactly the same as above, except that all `e' cases are deleted.
3413 ;; This is necessary to prevent reload from ever trying to use a `e' reg
3416 (define_insn "*movtf_no_e_insn_sp32"
3417 [(set (match_operand:TF 0 "nonimmediate_operand" "=o,U,o,r,o")
3418 (match_operand:TF 1 "input_operand" "G,o,U,roG,r"))]
3421 && (register_operand (operands[0], TFmode)
3422 || register_operand (operands[1], TFmode)
3423 || fp_zero_operand (operands[1], TFmode))"
3425 [(set_attr "length" "4")])
3427 ;; Now handle the float reg cases directly when arch64,
3428 ;; hard_quad, and proper reg number alignment are all true.
3429 (define_insn "*movtf_insn_hq_sp64"
3430 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,e,m,o,r")
3431 (match_operand:TF 1 "input_operand" "e,m,e,Gr,roG"))]
3436 && (register_operand (operands[0], TFmode)
3437 || register_operand (operands[1], TFmode)
3438 || fp_zero_operand (operands[1], TFmode))"
3445 [(set_attr "type" "fpmove,fpload,fpstore,*,*")
3446 (set_attr "length" "*,*,*,2,2")])
3448 (define_insn "*movtf_insn_hq_vis_sp64"
3449 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,e,m,eo,r,o")
3450 (match_operand:TF 1 "input_operand" "e,m,e,G,roG,r"))]
3455 && (register_operand (operands[0], TFmode)
3456 || register_operand (operands[1], TFmode)
3457 || fp_zero_operand (operands[1], TFmode))"
3465 [(set_attr "type" "fpmove,fpload,fpstore,*,*,*")
3466 (set_attr "length" "*,*,*,2,2,2")])
3468 ;; Now we allow the integer register cases even when
3469 ;; only arch64 is true.
3470 (define_insn "*movtf_insn_sp64"
3471 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,r")
3472 (match_operand:TF 1 "input_operand" "oe,Ger,orG"))]
3476 && ! TARGET_HARD_QUAD
3477 && (register_operand (operands[0], TFmode)
3478 || register_operand (operands[1], TFmode)
3479 || fp_zero_operand (operands[1], TFmode))"
3481 [(set_attr "length" "2")])
3483 (define_insn "*movtf_insn_vis_sp64"
3484 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,r")
3485 (match_operand:TF 1 "input_operand" "Goe,Ger,orG"))]
3489 && ! TARGET_HARD_QUAD
3490 && (register_operand (operands[0], TFmode)
3491 || register_operand (operands[1], TFmode)
3492 || fp_zero_operand (operands[1], TFmode))"
3494 [(set_attr "length" "2")])
3496 (define_insn "*movtf_no_e_insn_sp64"
3497 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o")
3498 (match_operand:TF 1 "input_operand" "orG,rG"))]
3501 && (register_operand (operands[0], TFmode)
3502 || register_operand (operands[1], TFmode)
3503 || fp_zero_operand (operands[1], TFmode))"
3505 [(set_attr "length" "2")])
3507 ;; Now all the splits to handle multi-insn TF mode moves.
3509 [(set (match_operand:TF 0 "register_operand" "")
3510 (match_operand:TF 1 "register_operand" ""))]
3514 && ! TARGET_HARD_QUAD)
3515 || ! fp_register_operand (operands[0], TFmode))"
3516 [(clobber (const_int 0))]
3519 rtx set_dest = operands[0];
3520 rtx set_src = operands[1];
3524 dest1 = gen_df_reg (set_dest, 0);
3525 dest2 = gen_df_reg (set_dest, 1);
3526 src1 = gen_df_reg (set_src, 0);
3527 src2 = gen_df_reg (set_src, 1);
3529 /* Now emit using the real source and destination we found, swapping
3530 the order if we detect overlap. */
3531 if (reg_overlap_mentioned_p (dest1, src2))
3533 emit_insn (gen_movdf (dest2, src2));
3534 emit_insn (gen_movdf (dest1, src1));
3538 emit_insn (gen_movdf (dest1, src1));
3539 emit_insn (gen_movdf (dest2, src2));
3545 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3546 (match_operand:TF 1 "fp_zero_operand" ""))]
3548 [(clobber (const_int 0))]
3551 rtx set_dest = operands[0];
3554 switch (GET_CODE (set_dest))
3557 dest1 = gen_df_reg (set_dest, 0);
3558 dest2 = gen_df_reg (set_dest, 1);
3561 dest1 = adjust_address (set_dest, DFmode, 0);
3562 dest2 = adjust_address (set_dest, DFmode, 8);
3568 emit_insn (gen_movdf (dest1, CONST0_RTX (DFmode)));
3569 emit_insn (gen_movdf (dest2, CONST0_RTX (DFmode)));
3574 [(set (match_operand:TF 0 "register_operand" "")
3575 (match_operand:TF 1 "memory_operand" ""))]
3577 && offsettable_memref_p (operands[1])
3579 || ! TARGET_HARD_QUAD
3580 || ! fp_register_operand (operands[0], TFmode)))"
3581 [(clobber (const_int 0))]
3584 rtx word0 = adjust_address (operands[1], DFmode, 0);
3585 rtx word1 = adjust_address (operands[1], DFmode, 8);
3586 rtx set_dest, dest1, dest2;
3588 set_dest = operands[0];
3590 dest1 = gen_df_reg (set_dest, 0);
3591 dest2 = gen_df_reg (set_dest, 1);
3593 /* Now output, ordering such that we don't clobber any registers
3594 mentioned in the address. */
3595 if (reg_overlap_mentioned_p (dest1, word1))
3598 emit_insn (gen_movdf (dest2, word1));
3599 emit_insn (gen_movdf (dest1, word0));
3603 emit_insn (gen_movdf (dest1, word0));
3604 emit_insn (gen_movdf (dest2, word1));
3610 [(set (match_operand:TF 0 "memory_operand" "")
3611 (match_operand:TF 1 "register_operand" ""))]
3613 && offsettable_memref_p (operands[0])
3615 || ! TARGET_HARD_QUAD
3616 || ! fp_register_operand (operands[1], TFmode)))"
3617 [(clobber (const_int 0))]
3620 rtx set_src = operands[1];
3622 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 0),
3623 gen_df_reg (set_src, 0)));
3624 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 8),
3625 gen_df_reg (set_src, 1)));
3629 ;; Sparc V9 conditional move instructions.
3631 ;; We can handle larger constants here for some flavors, but for now we keep
3632 ;; it simple and only allow those constants supported by all flavours.
3633 ;; Note that emit_conditional_move canonicalizes operands 2,3 so that operand
3634 ;; 3 contains the constant if one is present, but we handle either for
3635 ;; generality (sparc.c puts a constant in operand 2).
3637 (define_expand "movqicc"
3638 [(set (match_operand:QI 0 "register_operand" "")
3639 (if_then_else:QI (match_operand 1 "comparison_operator" "")
3640 (match_operand:QI 2 "arith10_operand" "")
3641 (match_operand:QI 3 "arith10_operand" "")))]
3645 enum rtx_code code = GET_CODE (operands[1]);
3647 if (GET_MODE (sparc_compare_op0) == DImode
3651 if (sparc_compare_op1 == const0_rtx
3652 && GET_CODE (sparc_compare_op0) == REG
3653 && GET_MODE (sparc_compare_op0) == DImode
3654 && v9_regcmp_p (code))
3656 operands[1] = gen_rtx_fmt_ee (code, DImode,
3657 sparc_compare_op0, sparc_compare_op1);
3661 rtx cc_reg = gen_compare_reg (code,
3662 sparc_compare_op0, sparc_compare_op1);
3663 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3667 (define_expand "movhicc"
3668 [(set (match_operand:HI 0 "register_operand" "")
3669 (if_then_else:HI (match_operand 1 "comparison_operator" "")
3670 (match_operand:HI 2 "arith10_operand" "")
3671 (match_operand:HI 3 "arith10_operand" "")))]
3675 enum rtx_code code = GET_CODE (operands[1]);
3677 if (GET_MODE (sparc_compare_op0) == DImode
3681 if (sparc_compare_op1 == const0_rtx
3682 && GET_CODE (sparc_compare_op0) == REG
3683 && GET_MODE (sparc_compare_op0) == DImode
3684 && v9_regcmp_p (code))
3686 operands[1] = gen_rtx_fmt_ee (code, DImode,
3687 sparc_compare_op0, sparc_compare_op1);
3691 rtx cc_reg = gen_compare_reg (code,
3692 sparc_compare_op0, sparc_compare_op1);
3693 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3697 (define_expand "movsicc"
3698 [(set (match_operand:SI 0 "register_operand" "")
3699 (if_then_else:SI (match_operand 1 "comparison_operator" "")
3700 (match_operand:SI 2 "arith10_operand" "")
3701 (match_operand:SI 3 "arith10_operand" "")))]
3705 enum rtx_code code = GET_CODE (operands[1]);
3706 enum machine_mode op0_mode = GET_MODE (sparc_compare_op0);
3708 if (sparc_compare_op1 == const0_rtx
3709 && GET_CODE (sparc_compare_op0) == REG
3710 && (TARGET_ARCH64 && op0_mode == DImode && v9_regcmp_p (code)))
3712 operands[1] = gen_rtx_fmt_ee (code, op0_mode,
3713 sparc_compare_op0, sparc_compare_op1);
3717 rtx cc_reg = gen_compare_reg (code,
3718 sparc_compare_op0, sparc_compare_op1);
3719 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg),
3720 cc_reg, const0_rtx);
3724 (define_expand "movdicc"
3725 [(set (match_operand:DI 0 "register_operand" "")
3726 (if_then_else:DI (match_operand 1 "comparison_operator" "")
3727 (match_operand:DI 2 "arith10_double_operand" "")
3728 (match_operand:DI 3 "arith10_double_operand" "")))]
3732 enum rtx_code code = GET_CODE (operands[1]);
3734 if (sparc_compare_op1 == const0_rtx
3735 && GET_CODE (sparc_compare_op0) == REG
3736 && GET_MODE (sparc_compare_op0) == DImode
3737 && v9_regcmp_p (code))
3739 operands[1] = gen_rtx_fmt_ee (code, DImode,
3740 sparc_compare_op0, sparc_compare_op1);
3744 rtx cc_reg = gen_compare_reg (code,
3745 sparc_compare_op0, sparc_compare_op1);
3746 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg),
3747 cc_reg, const0_rtx);
3751 (define_expand "movsfcc"
3752 [(set (match_operand:SF 0 "register_operand" "")
3753 (if_then_else:SF (match_operand 1 "comparison_operator" "")
3754 (match_operand:SF 2 "register_operand" "")
3755 (match_operand:SF 3 "register_operand" "")))]
3756 "TARGET_V9 && TARGET_FPU"
3759 enum rtx_code code = GET_CODE (operands[1]);
3761 if (GET_MODE (sparc_compare_op0) == DImode
3765 if (sparc_compare_op1 == const0_rtx
3766 && GET_CODE (sparc_compare_op0) == REG
3767 && GET_MODE (sparc_compare_op0) == DImode
3768 && v9_regcmp_p (code))
3770 operands[1] = gen_rtx_fmt_ee (code, DImode,
3771 sparc_compare_op0, sparc_compare_op1);
3775 rtx cc_reg = gen_compare_reg (code,
3776 sparc_compare_op0, sparc_compare_op1);
3777 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3781 (define_expand "movdfcc"
3782 [(set (match_operand:DF 0 "register_operand" "")
3783 (if_then_else:DF (match_operand 1 "comparison_operator" "")
3784 (match_operand:DF 2 "register_operand" "")
3785 (match_operand:DF 3 "register_operand" "")))]
3786 "TARGET_V9 && TARGET_FPU"
3789 enum rtx_code code = GET_CODE (operands[1]);
3791 if (GET_MODE (sparc_compare_op0) == DImode
3795 if (sparc_compare_op1 == const0_rtx
3796 && GET_CODE (sparc_compare_op0) == REG
3797 && GET_MODE (sparc_compare_op0) == DImode
3798 && v9_regcmp_p (code))
3800 operands[1] = gen_rtx_fmt_ee (code, DImode,
3801 sparc_compare_op0, sparc_compare_op1);
3805 rtx cc_reg = gen_compare_reg (code,
3806 sparc_compare_op0, sparc_compare_op1);
3807 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3811 (define_expand "movtfcc"
3812 [(set (match_operand:TF 0 "register_operand" "")
3813 (if_then_else:TF (match_operand 1 "comparison_operator" "")
3814 (match_operand:TF 2 "register_operand" "")
3815 (match_operand:TF 3 "register_operand" "")))]
3816 "TARGET_V9 && TARGET_FPU"
3819 enum rtx_code code = GET_CODE (operands[1]);
3821 if (GET_MODE (sparc_compare_op0) == DImode
3825 if (sparc_compare_op1 == const0_rtx
3826 && GET_CODE (sparc_compare_op0) == REG
3827 && GET_MODE (sparc_compare_op0) == DImode
3828 && v9_regcmp_p (code))
3830 operands[1] = gen_rtx_fmt_ee (code, DImode,
3831 sparc_compare_op0, sparc_compare_op1);
3835 rtx cc_reg = gen_compare_reg (code,
3836 sparc_compare_op0, sparc_compare_op1);
3837 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3841 ;; Conditional move define_insns.
3843 (define_insn "*movqi_cc_sp64"
3844 [(set (match_operand:QI 0 "register_operand" "=r,r")
3845 (if_then_else:QI (match_operator 1 "comparison_operator"
3846 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3848 (match_operand:QI 3 "arith11_operand" "rL,0")
3849 (match_operand:QI 4 "arith11_operand" "0,rL")))]
3852 mov%C1\\t%x2, %3, %0
3853 mov%c1\\t%x2, %4, %0"
3854 [(set_attr "type" "cmove")])
3856 (define_insn "*movhi_cc_sp64"
3857 [(set (match_operand:HI 0 "register_operand" "=r,r")
3858 (if_then_else:HI (match_operator 1 "comparison_operator"
3859 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3861 (match_operand:HI 3 "arith11_operand" "rL,0")
3862 (match_operand:HI 4 "arith11_operand" "0,rL")))]
3865 mov%C1\\t%x2, %3, %0
3866 mov%c1\\t%x2, %4, %0"
3867 [(set_attr "type" "cmove")])
3869 (define_insn "*movsi_cc_sp64"
3870 [(set (match_operand:SI 0 "register_operand" "=r,r")
3871 (if_then_else:SI (match_operator 1 "comparison_operator"
3872 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3874 (match_operand:SI 3 "arith11_operand" "rL,0")
3875 (match_operand:SI 4 "arith11_operand" "0,rL")))]
3878 mov%C1\\t%x2, %3, %0
3879 mov%c1\\t%x2, %4, %0"
3880 [(set_attr "type" "cmove")])
3882 ;; ??? The constraints of operands 3,4 need work.
3883 (define_insn "*movdi_cc_sp64"
3884 [(set (match_operand:DI 0 "register_operand" "=r,r")
3885 (if_then_else:DI (match_operator 1 "comparison_operator"
3886 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3888 (match_operand:DI 3 "arith11_double_operand" "rLH,0")
3889 (match_operand:DI 4 "arith11_double_operand" "0,rLH")))]
3892 mov%C1\\t%x2, %3, %0
3893 mov%c1\\t%x2, %4, %0"
3894 [(set_attr "type" "cmove")])
3896 (define_insn "*movdi_cc_sp64_trunc"
3897 [(set (match_operand:SI 0 "register_operand" "=r,r")
3898 (if_then_else:SI (match_operator 1 "comparison_operator"
3899 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3901 (match_operand:SI 3 "arith11_double_operand" "rLH,0")
3902 (match_operand:SI 4 "arith11_double_operand" "0,rLH")))]
3905 mov%C1\\t%x2, %3, %0
3906 mov%c1\\t%x2, %4, %0"
3907 [(set_attr "type" "cmove")])
3909 (define_insn "*movsf_cc_sp64"
3910 [(set (match_operand:SF 0 "register_operand" "=f,f")
3911 (if_then_else:SF (match_operator 1 "comparison_operator"
3912 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3914 (match_operand:SF 3 "register_operand" "f,0")
3915 (match_operand:SF 4 "register_operand" "0,f")))]
3916 "TARGET_V9 && TARGET_FPU"
3918 fmovs%C1\\t%x2, %3, %0
3919 fmovs%c1\\t%x2, %4, %0"
3920 [(set_attr "type" "fpcmove")])
3922 (define_insn "movdf_cc_sp64"
3923 [(set (match_operand:DF 0 "register_operand" "=e,e")
3924 (if_then_else:DF (match_operator 1 "comparison_operator"
3925 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3927 (match_operand:DF 3 "register_operand" "e,0")
3928 (match_operand:DF 4 "register_operand" "0,e")))]
3929 "TARGET_V9 && TARGET_FPU"
3931 fmovd%C1\\t%x2, %3, %0
3932 fmovd%c1\\t%x2, %4, %0"
3933 [(set_attr "type" "fpcmove")
3934 (set_attr "fptype" "double")])
3936 (define_insn "*movtf_cc_hq_sp64"
3937 [(set (match_operand:TF 0 "register_operand" "=e,e")
3938 (if_then_else:TF (match_operator 1 "comparison_operator"
3939 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3941 (match_operand:TF 3 "register_operand" "e,0")
3942 (match_operand:TF 4 "register_operand" "0,e")))]
3943 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
3945 fmovq%C1\\t%x2, %3, %0
3946 fmovq%c1\\t%x2, %4, %0"
3947 [(set_attr "type" "fpcmove")])
3949 (define_insn "*movtf_cc_sp64"
3950 [(set (match_operand:TF 0 "register_operand" "=e,e")
3951 (if_then_else:TF (match_operator 1 "comparison_operator"
3952 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3954 (match_operand:TF 3 "register_operand" "e,0")
3955 (match_operand:TF 4 "register_operand" "0,e")))]
3956 "TARGET_V9 && TARGET_FPU && !TARGET_HARD_QUAD"
3958 [(set_attr "length" "2")])
3961 [(set (match_operand:TF 0 "register_operand" "")
3962 (if_then_else:TF (match_operator 1 "comparison_operator"
3963 [(match_operand 2 "icc_or_fcc_reg_operand" "")
3965 (match_operand:TF 3 "register_operand" "")
3966 (match_operand:TF 4 "register_operand" "")))]
3967 "reload_completed && TARGET_V9 && TARGET_FPU && !TARGET_HARD_QUAD"
3968 [(clobber (const_int 0))]
3971 rtx set_dest = operands[0];
3972 rtx set_srca = operands[3];
3973 rtx set_srcb = operands[4];
3974 int third = rtx_equal_p (set_dest, set_srca);
3976 rtx srca1, srca2, srcb1, srcb2;
3978 dest1 = gen_df_reg (set_dest, 0);
3979 dest2 = gen_df_reg (set_dest, 1);
3980 srca1 = gen_df_reg (set_srca, 0);
3981 srca2 = gen_df_reg (set_srca, 1);
3982 srcb1 = gen_df_reg (set_srcb, 0);
3983 srcb2 = gen_df_reg (set_srcb, 1);
3985 /* Now emit using the real source and destination we found, swapping
3986 the order if we detect overlap. */
3987 if ((third && reg_overlap_mentioned_p (dest1, srcb2))
3988 || (!third && reg_overlap_mentioned_p (dest1, srca2)))
3990 emit_insn (gen_movdf_cc_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
3991 emit_insn (gen_movdf_cc_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
3995 emit_insn (gen_movdf_cc_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
3996 emit_insn (gen_movdf_cc_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
4001 (define_insn "*movqi_cc_reg_sp64"
4002 [(set (match_operand:QI 0 "register_operand" "=r,r")
4003 (if_then_else:QI (match_operator 1 "v9_regcmp_op"
4004 [(match_operand:DI 2 "register_operand" "r,r")
4006 (match_operand:QI 3 "arith10_operand" "rM,0")
4007 (match_operand:QI 4 "arith10_operand" "0,rM")))]
4010 movr%D1\\t%2, %r3, %0
4011 movr%d1\\t%2, %r4, %0"
4012 [(set_attr "type" "cmove")])
4014 (define_insn "*movhi_cc_reg_sp64"
4015 [(set (match_operand:HI 0 "register_operand" "=r,r")
4016 (if_then_else:HI (match_operator 1 "v9_regcmp_op"
4017 [(match_operand:DI 2 "register_operand" "r,r")
4019 (match_operand:HI 3 "arith10_operand" "rM,0")
4020 (match_operand:HI 4 "arith10_operand" "0,rM")))]
4023 movr%D1\\t%2, %r3, %0
4024 movr%d1\\t%2, %r4, %0"
4025 [(set_attr "type" "cmove")])
4027 (define_insn "*movsi_cc_reg_sp64"
4028 [(set (match_operand:SI 0 "register_operand" "=r,r")
4029 (if_then_else:SI (match_operator 1 "v9_regcmp_op"
4030 [(match_operand:DI 2 "register_operand" "r,r")
4032 (match_operand:SI 3 "arith10_operand" "rM,0")
4033 (match_operand:SI 4 "arith10_operand" "0,rM")))]
4036 movr%D1\\t%2, %r3, %0
4037 movr%d1\\t%2, %r4, %0"
4038 [(set_attr "type" "cmove")])
4040 ;; ??? The constraints of operands 3,4 need work.
4041 (define_insn "*movdi_cc_reg_sp64"
4042 [(set (match_operand:DI 0 "register_operand" "=r,r")
4043 (if_then_else:DI (match_operator 1 "v9_regcmp_op"
4044 [(match_operand:DI 2 "register_operand" "r,r")
4046 (match_operand:DI 3 "arith10_double_operand" "rMH,0")
4047 (match_operand:DI 4 "arith10_double_operand" "0,rMH")))]
4050 movr%D1\\t%2, %r3, %0
4051 movr%d1\\t%2, %r4, %0"
4052 [(set_attr "type" "cmove")])
4054 (define_insn "*movdi_cc_reg_sp64_trunc"
4055 [(set (match_operand:SI 0 "register_operand" "=r,r")
4056 (if_then_else:SI (match_operator 1 "v9_regcmp_op"
4057 [(match_operand:DI 2 "register_operand" "r,r")
4059 (match_operand:SI 3 "arith10_double_operand" "rMH,0")
4060 (match_operand:SI 4 "arith10_double_operand" "0,rMH")))]
4063 movr%D1\\t%2, %r3, %0
4064 movr%d1\\t%2, %r4, %0"
4065 [(set_attr "type" "cmove")])
4067 (define_insn "*movsf_cc_reg_sp64"
4068 [(set (match_operand:SF 0 "register_operand" "=f,f")
4069 (if_then_else:SF (match_operator 1 "v9_regcmp_op"
4070 [(match_operand:DI 2 "register_operand" "r,r")
4072 (match_operand:SF 3 "register_operand" "f,0")
4073 (match_operand:SF 4 "register_operand" "0,f")))]
4074 "TARGET_ARCH64 && TARGET_FPU"
4076 fmovrs%D1\\t%2, %3, %0
4077 fmovrs%d1\\t%2, %4, %0"
4078 [(set_attr "type" "fpcrmove")])
4080 (define_insn "movdf_cc_reg_sp64"
4081 [(set (match_operand:DF 0 "register_operand" "=e,e")
4082 (if_then_else:DF (match_operator 1 "v9_regcmp_op"
4083 [(match_operand:DI 2 "register_operand" "r,r")
4085 (match_operand:DF 3 "register_operand" "e,0")
4086 (match_operand:DF 4 "register_operand" "0,e")))]
4087 "TARGET_ARCH64 && TARGET_FPU"
4089 fmovrd%D1\\t%2, %3, %0
4090 fmovrd%d1\\t%2, %4, %0"
4091 [(set_attr "type" "fpcrmove")
4092 (set_attr "fptype" "double")])
4094 (define_insn "*movtf_cc_reg_hq_sp64"
4095 [(set (match_operand:TF 0 "register_operand" "=e,e")
4096 (if_then_else:TF (match_operator 1 "v9_regcmp_op"
4097 [(match_operand:DI 2 "register_operand" "r,r")
4099 (match_operand:TF 3 "register_operand" "e,0")
4100 (match_operand:TF 4 "register_operand" "0,e")))]
4101 "TARGET_ARCH64 && TARGET_FPU && TARGET_HARD_QUAD"
4103 fmovrq%D1\\t%2, %3, %0
4104 fmovrq%d1\\t%2, %4, %0"
4105 [(set_attr "type" "fpcrmove")])
4107 (define_insn "*movtf_cc_reg_sp64"
4108 [(set (match_operand:TF 0 "register_operand" "=e,e")
4109 (if_then_else:TF (match_operator 1 "v9_regcmp_op"
4110 [(match_operand:DI 2 "register_operand" "r,r")
4112 (match_operand:TF 3 "register_operand" "e,0")
4113 (match_operand:TF 4 "register_operand" "0,e")))]
4114 "TARGET_ARCH64 && TARGET_FPU && ! TARGET_HARD_QUAD"
4116 [(set_attr "length" "2")])
4119 [(set (match_operand:TF 0 "register_operand" "")
4120 (if_then_else:TF (match_operator 1 "v9_regcmp_op"
4121 [(match_operand:DI 2 "register_operand" "")
4123 (match_operand:TF 3 "register_operand" "")
4124 (match_operand:TF 4 "register_operand" "")))]
4125 "reload_completed && TARGET_ARCH64 && TARGET_FPU && ! TARGET_HARD_QUAD"
4126 [(clobber (const_int 0))]
4129 rtx set_dest = operands[0];
4130 rtx set_srca = operands[3];
4131 rtx set_srcb = operands[4];
4132 int third = rtx_equal_p (set_dest, set_srca);
4134 rtx srca1, srca2, srcb1, srcb2;
4136 dest1 = gen_df_reg (set_dest, 0);
4137 dest2 = gen_df_reg (set_dest, 1);
4138 srca1 = gen_df_reg (set_srca, 0);
4139 srca2 = gen_df_reg (set_srca, 1);
4140 srcb1 = gen_df_reg (set_srcb, 0);
4141 srcb2 = gen_df_reg (set_srcb, 1);
4143 /* Now emit using the real source and destination we found, swapping
4144 the order if we detect overlap. */
4145 if ((third && reg_overlap_mentioned_p (dest1, srcb2))
4146 || (!third && reg_overlap_mentioned_p (dest1, srca2)))
4148 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
4149 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
4153 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
4154 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
4160 ;;- zero extension instructions
4162 ;; These patterns originally accepted general_operands, however, slightly
4163 ;; better code is generated by only accepting register_operands, and then
4164 ;; letting combine generate the ldu[hb] insns.
4166 (define_expand "zero_extendhisi2"
4167 [(set (match_operand:SI 0 "register_operand" "")
4168 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
4172 rtx temp = gen_reg_rtx (SImode);
4173 rtx shift_16 = GEN_INT (16);
4174 int op1_subbyte = 0;
4176 if (GET_CODE (operand1) == SUBREG)
4178 op1_subbyte = SUBREG_BYTE (operand1);
4179 op1_subbyte /= GET_MODE_SIZE (SImode);
4180 op1_subbyte *= GET_MODE_SIZE (SImode);
4181 operand1 = XEXP (operand1, 0);
4184 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4186 emit_insn (gen_lshrsi3 (operand0, temp, shift_16));
4190 (define_insn "*zero_extendhisi2_insn"
4191 [(set (match_operand:SI 0 "register_operand" "=r")
4192 (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
4195 [(set_attr "type" "load")
4196 (set_attr "us3load_type" "3cycle")])
4198 (define_expand "zero_extendqihi2"
4199 [(set (match_operand:HI 0 "register_operand" "")
4200 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
4204 (define_insn "*zero_extendqihi2_insn"
4205 [(set (match_operand:HI 0 "register_operand" "=r,r")
4206 (zero_extend:HI (match_operand:QI 1 "input_operand" "r,m")))]
4207 "GET_CODE (operands[1]) != CONST_INT"
4211 [(set_attr "type" "*,load")
4212 (set_attr "us3load_type" "*,3cycle")])
4214 (define_expand "zero_extendqisi2"
4215 [(set (match_operand:SI 0 "register_operand" "")
4216 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
4220 (define_insn "*zero_extendqisi2_insn"
4221 [(set (match_operand:SI 0 "register_operand" "=r,r")
4222 (zero_extend:SI (match_operand:QI 1 "input_operand" "r,m")))]
4223 "GET_CODE (operands[1]) != CONST_INT"
4227 [(set_attr "type" "*,load")
4228 (set_attr "us3load_type" "*,3cycle")])
4230 (define_expand "zero_extendqidi2"
4231 [(set (match_operand:DI 0 "register_operand" "")
4232 (zero_extend:DI (match_operand:QI 1 "register_operand" "")))]
4236 (define_insn "*zero_extendqidi2_insn"
4237 [(set (match_operand:DI 0 "register_operand" "=r,r")
4238 (zero_extend:DI (match_operand:QI 1 "input_operand" "r,m")))]
4239 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
4243 [(set_attr "type" "*,load")
4244 (set_attr "us3load_type" "*,3cycle")])
4246 (define_expand "zero_extendhidi2"
4247 [(set (match_operand:DI 0 "register_operand" "")
4248 (zero_extend:DI (match_operand:HI 1 "register_operand" "")))]
4252 rtx temp = gen_reg_rtx (DImode);
4253 rtx shift_48 = GEN_INT (48);
4254 int op1_subbyte = 0;
4256 if (GET_CODE (operand1) == SUBREG)
4258 op1_subbyte = SUBREG_BYTE (operand1);
4259 op1_subbyte /= GET_MODE_SIZE (DImode);
4260 op1_subbyte *= GET_MODE_SIZE (DImode);
4261 operand1 = XEXP (operand1, 0);
4264 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
4266 emit_insn (gen_lshrdi3 (operand0, temp, shift_48));
4270 (define_insn "*zero_extendhidi2_insn"
4271 [(set (match_operand:DI 0 "register_operand" "=r")
4272 (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
4275 [(set_attr "type" "load")
4276 (set_attr "us3load_type" "3cycle")])
4279 ;; ??? Write truncdisi pattern using sra?
4281 (define_expand "zero_extendsidi2"
4282 [(set (match_operand:DI 0 "register_operand" "")
4283 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
4287 (define_insn "*zero_extendsidi2_insn_sp64"
4288 [(set (match_operand:DI 0 "register_operand" "=r,r")
4289 (zero_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
4290 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
4294 [(set_attr "type" "shift,load")])
4296 (define_insn "*zero_extendsidi2_insn_sp32"
4297 [(set (match_operand:DI 0 "register_operand" "=r")
4298 (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
4301 [(set_attr "length" "2")])
4304 [(set (match_operand:DI 0 "register_operand" "")
4305 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
4306 "! TARGET_ARCH64 && reload_completed"
4307 [(set (match_dup 2) (match_dup 3))
4308 (set (match_dup 4) (match_dup 5))]
4313 dest1 = gen_highpart (SImode, operands[0]);
4314 dest2 = gen_lowpart (SImode, operands[0]);
4316 /* Swap the order in case of overlap. */
4317 if (REGNO (dest1) == REGNO (operands[1]))
4319 operands[2] = dest2;
4320 operands[3] = operands[1];
4321 operands[4] = dest1;
4322 operands[5] = const0_rtx;
4326 operands[2] = dest1;
4327 operands[3] = const0_rtx;
4328 operands[4] = dest2;
4329 operands[5] = operands[1];
4333 ;; Simplify comparisons of extended values.
4335 (define_insn "*cmp_zero_extendqisi2"
4337 (compare:CC (zero_extend:SI (match_operand:QI 0 "register_operand" "r"))
4340 "andcc\\t%0, 0xff, %%g0"
4341 [(set_attr "type" "compare")])
4343 (define_insn "*cmp_zero_qi"
4345 (compare:CC (match_operand:QI 0 "register_operand" "r")
4348 "andcc\\t%0, 0xff, %%g0"
4349 [(set_attr "type" "compare")])
4351 (define_insn "*cmp_zero_extendqisi2_set"
4353 (compare:CC (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
4355 (set (match_operand:SI 0 "register_operand" "=r")
4356 (zero_extend:SI (match_dup 1)))]
4358 "andcc\\t%1, 0xff, %0"
4359 [(set_attr "type" "compare")])
4361 (define_insn "*cmp_zero_extendqisi2_andcc_set"
4363 (compare:CC (and:SI (match_operand:SI 1 "register_operand" "r")
4366 (set (match_operand:SI 0 "register_operand" "=r")
4367 (zero_extend:SI (subreg:QI (match_dup 1) 0)))]
4369 "andcc\\t%1, 0xff, %0"
4370 [(set_attr "type" "compare")])
4372 (define_insn "*cmp_zero_extendqidi2"
4374 (compare:CCX (zero_extend:DI (match_operand:QI 0 "register_operand" "r"))
4377 "andcc\\t%0, 0xff, %%g0"
4378 [(set_attr "type" "compare")])
4380 (define_insn "*cmp_zero_qi_sp64"
4382 (compare:CCX (match_operand:QI 0 "register_operand" "r")
4385 "andcc\\t%0, 0xff, %%g0"
4386 [(set_attr "type" "compare")])
4388 (define_insn "*cmp_zero_extendqidi2_set"
4390 (compare:CCX (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
4392 (set (match_operand:DI 0 "register_operand" "=r")
4393 (zero_extend:DI (match_dup 1)))]
4395 "andcc\\t%1, 0xff, %0"
4396 [(set_attr "type" "compare")])
4398 (define_insn "*cmp_zero_extendqidi2_andcc_set"
4400 (compare:CCX (and:DI (match_operand:DI 1 "register_operand" "r")
4403 (set (match_operand:DI 0 "register_operand" "=r")
4404 (zero_extend:DI (subreg:QI (match_dup 1) 0)))]
4406 "andcc\\t%1, 0xff, %0"
4407 [(set_attr "type" "compare")])
4409 ;; Similarly, handle {SI,DI}->QI mode truncation followed by a compare.
4411 (define_insn "*cmp_siqi_trunc"
4413 (compare:CC (subreg:QI (match_operand:SI 0 "register_operand" "r") 3)
4416 "andcc\\t%0, 0xff, %%g0"
4417 [(set_attr "type" "compare")])
4419 (define_insn "*cmp_siqi_trunc_set"
4421 (compare:CC (subreg:QI (match_operand:SI 1 "register_operand" "r") 3)
4423 (set (match_operand:QI 0 "register_operand" "=r")
4424 (subreg:QI (match_dup 1) 3))]
4426 "andcc\\t%1, 0xff, %0"
4427 [(set_attr "type" "compare")])
4429 (define_insn "*cmp_diqi_trunc"
4431 (compare:CC (subreg:QI (match_operand:DI 0 "register_operand" "r") 7)
4434 "andcc\\t%0, 0xff, %%g0"
4435 [(set_attr "type" "compare")])
4437 (define_insn "*cmp_diqi_trunc_set"
4439 (compare:CC (subreg:QI (match_operand:DI 1 "register_operand" "r") 7)
4441 (set (match_operand:QI 0 "register_operand" "=r")
4442 (subreg:QI (match_dup 1) 7))]
4444 "andcc\\t%1, 0xff, %0"
4445 [(set_attr "type" "compare")])
4447 ;;- sign extension instructions
4449 ;; These patterns originally accepted general_operands, however, slightly
4450 ;; better code is generated by only accepting register_operands, and then
4451 ;; letting combine generate the lds[hb] insns.
4453 (define_expand "extendhisi2"
4454 [(set (match_operand:SI 0 "register_operand" "")
4455 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
4459 rtx temp = gen_reg_rtx (SImode);
4460 rtx shift_16 = GEN_INT (16);
4461 int op1_subbyte = 0;
4463 if (GET_CODE (operand1) == SUBREG)
4465 op1_subbyte = SUBREG_BYTE (operand1);
4466 op1_subbyte /= GET_MODE_SIZE (SImode);
4467 op1_subbyte *= GET_MODE_SIZE (SImode);
4468 operand1 = XEXP (operand1, 0);
4471 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4473 emit_insn (gen_ashrsi3 (operand0, temp, shift_16));
4477 (define_insn "*sign_extendhisi2_insn"
4478 [(set (match_operand:SI 0 "register_operand" "=r")
4479 (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
4482 [(set_attr "type" "sload")
4483 (set_attr "us3load_type" "3cycle")])
4485 (define_expand "extendqihi2"
4486 [(set (match_operand:HI 0 "register_operand" "")
4487 (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
4491 rtx temp = gen_reg_rtx (SImode);
4492 rtx shift_24 = GEN_INT (24);
4493 int op1_subbyte = 0;
4494 int op0_subbyte = 0;
4496 if (GET_CODE (operand1) == SUBREG)
4498 op1_subbyte = SUBREG_BYTE (operand1);
4499 op1_subbyte /= GET_MODE_SIZE (SImode);
4500 op1_subbyte *= GET_MODE_SIZE (SImode);
4501 operand1 = XEXP (operand1, 0);
4503 if (GET_CODE (operand0) == SUBREG)
4505 op0_subbyte = SUBREG_BYTE (operand0);
4506 op0_subbyte /= GET_MODE_SIZE (SImode);
4507 op0_subbyte *= GET_MODE_SIZE (SImode);
4508 operand0 = XEXP (operand0, 0);
4510 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4512 if (GET_MODE (operand0) != SImode)
4513 operand0 = gen_rtx_SUBREG (SImode, operand0, op0_subbyte);
4514 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
4518 (define_insn "*sign_extendqihi2_insn"
4519 [(set (match_operand:HI 0 "register_operand" "=r")
4520 (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
4523 [(set_attr "type" "sload")
4524 (set_attr "us3load_type" "3cycle")])
4526 (define_expand "extendqisi2"
4527 [(set (match_operand:SI 0 "register_operand" "")
4528 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
4532 rtx temp = gen_reg_rtx (SImode);
4533 rtx shift_24 = GEN_INT (24);
4534 int op1_subbyte = 0;
4536 if (GET_CODE (operand1) == SUBREG)
4538 op1_subbyte = SUBREG_BYTE (operand1);
4539 op1_subbyte /= GET_MODE_SIZE (SImode);
4540 op1_subbyte *= GET_MODE_SIZE (SImode);
4541 operand1 = XEXP (operand1, 0);
4544 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4546 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
4550 (define_insn "*sign_extendqisi2_insn"
4551 [(set (match_operand:SI 0 "register_operand" "=r")
4552 (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
4555 [(set_attr "type" "sload")
4556 (set_attr "us3load_type" "3cycle")])
4558 (define_expand "extendqidi2"
4559 [(set (match_operand:DI 0 "register_operand" "")
4560 (sign_extend:DI (match_operand:QI 1 "register_operand" "")))]
4564 rtx temp = gen_reg_rtx (DImode);
4565 rtx shift_56 = GEN_INT (56);
4566 int op1_subbyte = 0;
4568 if (GET_CODE (operand1) == SUBREG)
4570 op1_subbyte = SUBREG_BYTE (operand1);
4571 op1_subbyte /= GET_MODE_SIZE (DImode);
4572 op1_subbyte *= GET_MODE_SIZE (DImode);
4573 operand1 = XEXP (operand1, 0);
4576 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
4578 emit_insn (gen_ashrdi3 (operand0, temp, shift_56));
4582 (define_insn "*sign_extendqidi2_insn"
4583 [(set (match_operand:DI 0 "register_operand" "=r")
4584 (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
4587 [(set_attr "type" "sload")
4588 (set_attr "us3load_type" "3cycle")])
4590 (define_expand "extendhidi2"
4591 [(set (match_operand:DI 0 "register_operand" "")
4592 (sign_extend:DI (match_operand:HI 1 "register_operand" "")))]
4596 rtx temp = gen_reg_rtx (DImode);
4597 rtx shift_48 = GEN_INT (48);
4598 int op1_subbyte = 0;
4600 if (GET_CODE (operand1) == SUBREG)
4602 op1_subbyte = SUBREG_BYTE (operand1);
4603 op1_subbyte /= GET_MODE_SIZE (DImode);
4604 op1_subbyte *= GET_MODE_SIZE (DImode);
4605 operand1 = XEXP (operand1, 0);
4608 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
4610 emit_insn (gen_ashrdi3 (operand0, temp, shift_48));
4614 (define_insn "*sign_extendhidi2_insn"
4615 [(set (match_operand:DI 0 "register_operand" "=r")
4616 (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
4619 [(set_attr "type" "sload")
4620 (set_attr "us3load_type" "3cycle")])
4622 (define_expand "extendsidi2"
4623 [(set (match_operand:DI 0 "register_operand" "")
4624 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
4628 (define_insn "*sign_extendsidi2_insn"
4629 [(set (match_operand:DI 0 "register_operand" "=r,r")
4630 (sign_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
4635 [(set_attr "type" "shift,sload")
4636 (set_attr "us3load_type" "*,3cycle")])
4638 ;; Special pattern for optimizing bit-field compares. This is needed
4639 ;; because combine uses this as a canonical form.
4641 (define_insn "*cmp_zero_extract"
4644 (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
4645 (match_operand:SI 1 "small_int_or_double" "n")
4646 (match_operand:SI 2 "small_int_or_double" "n"))
4648 "(GET_CODE (operands[2]) == CONST_INT
4649 && INTVAL (operands[2]) > 19)
4650 || (GET_CODE (operands[2]) == CONST_DOUBLE
4651 && CONST_DOUBLE_LOW (operands[2]) > 19)"
4654 int len = (GET_CODE (operands[1]) == CONST_INT
4655 ? INTVAL (operands[1])
4656 : CONST_DOUBLE_LOW (operands[1]));
4658 (GET_CODE (operands[2]) == CONST_INT
4659 ? INTVAL (operands[2])
4660 : CONST_DOUBLE_LOW (operands[2])) - len;
4661 HOST_WIDE_INT mask = ((1 << len) - 1) << pos;
4663 operands[1] = GEN_INT (mask);
4664 return \"andcc\\t%0, %1, %%g0\";
4666 [(set_attr "type" "compare")])
4668 (define_insn "*cmp_zero_extract_sp64"
4671 (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
4672 (match_operand:SI 1 "small_int_or_double" "n")
4673 (match_operand:SI 2 "small_int_or_double" "n"))
4676 && ((GET_CODE (operands[2]) == CONST_INT
4677 && INTVAL (operands[2]) > 51)
4678 || (GET_CODE (operands[2]) == CONST_DOUBLE
4679 && CONST_DOUBLE_LOW (operands[2]) > 51))"
4682 int len = (GET_CODE (operands[1]) == CONST_INT
4683 ? INTVAL (operands[1])
4684 : CONST_DOUBLE_LOW (operands[1]));
4686 (GET_CODE (operands[2]) == CONST_INT
4687 ? INTVAL (operands[2])
4688 : CONST_DOUBLE_LOW (operands[2])) - len;
4689 HOST_WIDE_INT mask = (((unsigned HOST_WIDE_INT) 1 << len) - 1) << pos;
4691 operands[1] = GEN_INT (mask);
4692 return \"andcc\\t%0, %1, %%g0\";
4694 [(set_attr "type" "compare")])
4696 ;; Conversions between float, double and long double.
4698 (define_insn "extendsfdf2"
4699 [(set (match_operand:DF 0 "register_operand" "=e")
4701 (match_operand:SF 1 "register_operand" "f")))]
4704 [(set_attr "type" "fp")
4705 (set_attr "fptype" "double")])
4707 (define_expand "extendsftf2"
4708 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4710 (match_operand:SF 1 "register_operand" "")))]
4711 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4712 "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
4714 (define_insn "*extendsftf2_hq"
4715 [(set (match_operand:TF 0 "register_operand" "=e")
4717 (match_operand:SF 1 "register_operand" "f")))]
4718 "TARGET_FPU && TARGET_HARD_QUAD"
4720 [(set_attr "type" "fp")])
4722 (define_expand "extenddftf2"
4723 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4725 (match_operand:DF 1 "register_operand" "")))]
4726 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4727 "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
4729 (define_insn "*extenddftf2_hq"
4730 [(set (match_operand:TF 0 "register_operand" "=e")
4732 (match_operand:DF 1 "register_operand" "e")))]
4733 "TARGET_FPU && TARGET_HARD_QUAD"
4735 [(set_attr "type" "fp")])
4737 (define_insn "truncdfsf2"
4738 [(set (match_operand:SF 0 "register_operand" "=f")
4740 (match_operand:DF 1 "register_operand" "e")))]
4743 [(set_attr "type" "fp")
4744 (set_attr "fptype" "double")])
4746 (define_expand "trunctfsf2"
4747 [(set (match_operand:SF 0 "register_operand" "")
4749 (match_operand:TF 1 "general_operand" "")))]
4750 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4751 "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
4753 (define_insn "*trunctfsf2_hq"
4754 [(set (match_operand:SF 0 "register_operand" "=f")
4756 (match_operand:TF 1 "register_operand" "e")))]
4757 "TARGET_FPU && TARGET_HARD_QUAD"
4759 [(set_attr "type" "fp")])
4761 (define_expand "trunctfdf2"
4762 [(set (match_operand:DF 0 "register_operand" "")
4764 (match_operand:TF 1 "general_operand" "")))]
4765 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4766 "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
4768 (define_insn "*trunctfdf2_hq"
4769 [(set (match_operand:DF 0 "register_operand" "=e")
4771 (match_operand:TF 1 "register_operand" "e")))]
4772 "TARGET_FPU && TARGET_HARD_QUAD"
4774 [(set_attr "type" "fp")])
4776 ;; Conversion between fixed point and floating point.
4778 (define_insn "floatsisf2"
4779 [(set (match_operand:SF 0 "register_operand" "=f")
4780 (float:SF (match_operand:SI 1 "register_operand" "f")))]
4783 [(set_attr "type" "fp")
4784 (set_attr "fptype" "double")])
4786 (define_insn "floatsidf2"
4787 [(set (match_operand:DF 0 "register_operand" "=e")
4788 (float:DF (match_operand:SI 1 "register_operand" "f")))]
4791 [(set_attr "type" "fp")
4792 (set_attr "fptype" "double")])
4794 (define_expand "floatsitf2"
4795 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4796 (float:TF (match_operand:SI 1 "register_operand" "")))]
4797 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4798 "emit_tfmode_cvt (FLOAT, operands); DONE;")
4800 (define_insn "*floatsitf2_hq"
4801 [(set (match_operand:TF 0 "register_operand" "=e")
4802 (float:TF (match_operand:SI 1 "register_operand" "f")))]
4803 "TARGET_FPU && TARGET_HARD_QUAD"
4805 [(set_attr "type" "fp")])
4807 (define_expand "floatunssitf2"
4808 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4809 (unsigned_float:TF (match_operand:SI 1 "register_operand" "")))]
4810 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4811 "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
4813 ;; Now the same for 64 bit sources.
4815 (define_insn "floatdisf2"
4816 [(set (match_operand:SF 0 "register_operand" "=f")
4817 (float:SF (match_operand:DI 1 "register_operand" "e")))]
4818 "TARGET_V9 && TARGET_FPU"
4820 [(set_attr "type" "fp")
4821 (set_attr "fptype" "double")])
4823 (define_expand "floatunsdisf2"
4824 [(use (match_operand:SF 0 "register_operand" ""))
4825 (use (match_operand:DI 1 "register_operand" ""))]
4826 "TARGET_ARCH64 && TARGET_FPU"
4827 "sparc_emit_floatunsdi (operands); DONE;")
4829 (define_insn "floatdidf2"
4830 [(set (match_operand:DF 0 "register_operand" "=e")
4831 (float:DF (match_operand:DI 1 "register_operand" "e")))]
4832 "TARGET_V9 && TARGET_FPU"
4834 [(set_attr "type" "fp")
4835 (set_attr "fptype" "double")])
4837 (define_expand "floatunsdidf2"
4838 [(use (match_operand:DF 0 "register_operand" ""))
4839 (use (match_operand:DI 1 "register_operand" ""))]
4840 "TARGET_ARCH64 && TARGET_FPU"
4841 "sparc_emit_floatunsdi (operands); DONE;")
4843 (define_expand "floatditf2"
4844 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4845 (float:TF (match_operand:DI 1 "register_operand" "")))]
4846 "TARGET_FPU && TARGET_V9 && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4847 "emit_tfmode_cvt (FLOAT, operands); DONE;")
4849 (define_insn "*floatditf2_hq"
4850 [(set (match_operand:TF 0 "register_operand" "=e")
4851 (float:TF (match_operand:DI 1 "register_operand" "e")))]
4852 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
4854 [(set_attr "type" "fp")])
4856 (define_expand "floatunsditf2"
4857 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4858 (unsigned_float:TF (match_operand:DI 1 "register_operand" "")))]
4859 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4860 "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
4862 ;; Convert a float to an actual integer.
4863 ;; Truncation is performed as part of the conversion.
4865 (define_insn "fix_truncsfsi2"
4866 [(set (match_operand:SI 0 "register_operand" "=f")
4867 (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
4870 [(set_attr "type" "fp")
4871 (set_attr "fptype" "double")])
4873 (define_insn "fix_truncdfsi2"
4874 [(set (match_operand:SI 0 "register_operand" "=f")
4875 (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
4878 [(set_attr "type" "fp")
4879 (set_attr "fptype" "double")])
4881 (define_expand "fix_trunctfsi2"
4882 [(set (match_operand:SI 0 "register_operand" "")
4883 (fix:SI (match_operand:TF 1 "general_operand" "")))]
4884 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4885 "emit_tfmode_cvt (FIX, operands); DONE;")
4887 (define_insn "*fix_trunctfsi2_hq"
4888 [(set (match_operand:SI 0 "register_operand" "=f")
4889 (fix:SI (match_operand:TF 1 "register_operand" "e")))]
4890 "TARGET_FPU && TARGET_HARD_QUAD"
4892 [(set_attr "type" "fp")])
4894 (define_expand "fixuns_trunctfsi2"
4895 [(set (match_operand:SI 0 "register_operand" "")
4896 (unsigned_fix:SI (match_operand:TF 1 "general_operand" "")))]
4897 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4898 "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
4900 ;; Now the same, for V9 targets
4902 (define_insn "fix_truncsfdi2"
4903 [(set (match_operand:DI 0 "register_operand" "=e")
4904 (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
4905 "TARGET_V9 && TARGET_FPU"
4907 [(set_attr "type" "fp")
4908 (set_attr "fptype" "double")])
4910 (define_insn "fix_truncdfdi2"
4911 [(set (match_operand:DI 0 "register_operand" "=e")
4912 (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
4913 "TARGET_V9 && TARGET_FPU"
4915 [(set_attr "type" "fp")
4916 (set_attr "fptype" "double")])
4918 (define_expand "fix_trunctfdi2"
4919 [(set (match_operand:DI 0 "register_operand" "")
4920 (fix:DI (match_operand:TF 1 "general_operand" "")))]
4921 "TARGET_V9 && TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4922 "emit_tfmode_cvt (FIX, operands); DONE;")
4924 (define_insn "*fix_trunctfdi2_hq"
4925 [(set (match_operand:DI 0 "register_operand" "=e")
4926 (fix:DI (match_operand:TF 1 "register_operand" "e")))]
4927 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
4929 [(set_attr "type" "fp")])
4931 (define_expand "fixuns_trunctfdi2"
4932 [(set (match_operand:DI 0 "register_operand" "")
4933 (unsigned_fix:DI (match_operand:TF 1 "general_operand" "")))]
4934 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4935 "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
4937 ;;- arithmetic instructions
4939 (define_expand "adddi3"
4940 [(set (match_operand:DI 0 "register_operand" "=r")
4941 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
4942 (match_operand:DI 2 "arith_double_add_operand" "rHI")))]
4948 if (! TARGET_ARCH64)
4950 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
4951 gen_rtx_SET (VOIDmode, operands[0],
4952 gen_rtx_PLUS (DImode, operands[1],
4954 gen_rtx_CLOBBER (VOIDmode,
4955 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
4958 if (arith_double_4096_operand(operands[2], DImode))
4960 switch (GET_CODE (operands[1]))
4962 case CONST_INT: i = INTVAL (operands[1]); break;
4963 case CONST_DOUBLE: i = CONST_DOUBLE_LOW (operands[1]); break;
4965 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
4966 gen_rtx_MINUS (DImode, operands[1],
4970 emit_insn (gen_movdi (operands[0], GEN_INT (i + 4096)));
4975 (define_insn "adddi3_insn_sp32"
4976 [(set (match_operand:DI 0 "register_operand" "=r")
4977 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
4978 (match_operand:DI 2 "arith_double_operand" "rHI")))
4979 (clobber (reg:CC 100))]
4982 [(set_attr "length" "2")])
4985 [(set (match_operand:DI 0 "register_operand" "")
4986 (plus:DI (match_operand:DI 1 "arith_double_operand" "")
4987 (match_operand:DI 2 "arith_double_operand" "")))
4988 (clobber (reg:CC 100))]
4989 "! TARGET_ARCH64 && reload_completed"
4990 [(parallel [(set (reg:CC_NOOV 100)
4991 (compare:CC_NOOV (plus:SI (match_dup 4)
4995 (plus:SI (match_dup 4) (match_dup 5)))])
4997 (plus:SI (plus:SI (match_dup 7)
4999 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5002 operands[3] = gen_lowpart (SImode, operands[0]);
5003 operands[4] = gen_lowpart (SImode, operands[1]);
5004 operands[5] = gen_lowpart (SImode, operands[2]);
5005 operands[6] = gen_highpart (SImode, operands[0]);
5006 operands[7] = gen_highpart_mode (SImode, DImode, operands[1]);
5007 #if HOST_BITS_PER_WIDE_INT == 32
5008 if (GET_CODE (operands[2]) == CONST_INT)
5010 if (INTVAL (operands[2]) < 0)
5011 operands[8] = constm1_rtx;
5013 operands[8] = const0_rtx;
5017 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
5021 [(set (match_operand:DI 0 "register_operand" "")
5022 (minus:DI (match_operand:DI 1 "arith_double_operand" "")
5023 (match_operand:DI 2 "arith_double_operand" "")))
5024 (clobber (reg:CC 100))]
5025 "! TARGET_ARCH64 && reload_completed"
5026 [(parallel [(set (reg:CC_NOOV 100)
5027 (compare:CC_NOOV (minus:SI (match_dup 4)
5031 (minus:SI (match_dup 4) (match_dup 5)))])
5033 (minus:SI (minus:SI (match_dup 7)
5035 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5038 operands[3] = gen_lowpart (SImode, operands[0]);
5039 operands[4] = gen_lowpart (SImode, operands[1]);
5040 operands[5] = gen_lowpart (SImode, operands[2]);
5041 operands[6] = gen_highpart (SImode, operands[0]);
5042 operands[7] = gen_highpart (SImode, operands[1]);
5043 #if HOST_BITS_PER_WIDE_INT == 32
5044 if (GET_CODE (operands[2]) == CONST_INT)
5046 if (INTVAL (operands[2]) < 0)
5047 operands[8] = constm1_rtx;
5049 operands[8] = const0_rtx;
5053 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
5056 ;; LTU here means "carry set"
5058 [(set (match_operand:SI 0 "register_operand" "=r")
5059 (plus:SI (plus:SI (match_operand:SI 1 "arith_operand" "%r")
5060 (match_operand:SI 2 "arith_operand" "rI"))
5061 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5064 [(set_attr "type" "misc")])
5066 (define_insn "*addx_extend_sp32"
5067 [(set (match_operand:DI 0 "register_operand" "=r")
5068 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
5069 (match_operand:SI 2 "arith_operand" "rI"))
5070 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5073 [(set_attr "length" "2")])
5076 [(set (match_operand:DI 0 "register_operand" "")
5077 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "")
5078 (match_operand:SI 2 "arith_operand" ""))
5079 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5080 "! TARGET_ARCH64 && reload_completed"
5081 [(set (match_dup 3) (plus:SI (plus:SI (match_dup 1) (match_dup 2))
5082 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
5083 (set (match_dup 4) (const_int 0))]
5084 "operands[3] = gen_lowpart (SImode, operands[0]);
5085 operands[4] = gen_highpart_mode (SImode, DImode, operands[1]);")
5087 (define_insn "*addx_extend_sp64"
5088 [(set (match_operand:DI 0 "register_operand" "=r")
5089 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
5090 (match_operand:SI 2 "arith_operand" "rI"))
5091 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5093 "addx\\t%r1, %2, %0"
5094 [(set_attr "type" "misc")])
5097 [(set (match_operand:SI 0 "register_operand" "=r")
5098 (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5099 (match_operand:SI 2 "arith_operand" "rI"))
5100 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5102 "subx\\t%r1, %2, %0"
5103 [(set_attr "type" "misc")])
5105 (define_insn "*subx_extend_sp64"
5106 [(set (match_operand:DI 0 "register_operand" "=r")
5107 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5108 (match_operand:SI 2 "arith_operand" "rI"))
5109 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5111 "subx\\t%r1, %2, %0"
5112 [(set_attr "type" "misc")])
5114 (define_insn "*subx_extend"
5115 [(set (match_operand:DI 0 "register_operand" "=r")
5116 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5117 (match_operand:SI 2 "arith_operand" "rI"))
5118 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5121 [(set_attr "length" "2")])
5124 [(set (match_operand:DI 0 "register_operand" "")
5125 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "")
5126 (match_operand:SI 2 "arith_operand" ""))
5127 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5128 "! TARGET_ARCH64 && reload_completed"
5129 [(set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 2))
5130 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
5131 (set (match_dup 4) (const_int 0))]
5132 "operands[3] = gen_lowpart (SImode, operands[0]);
5133 operands[4] = gen_highpart (SImode, operands[0]);")
5136 [(set (match_operand:DI 0 "register_operand" "=r")
5137 (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5138 (match_operand:DI 2 "register_operand" "r")))
5139 (clobber (reg:CC 100))]
5142 [(set_attr "length" "2")])
5145 [(set (match_operand:DI 0 "register_operand" "")
5146 (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
5147 (match_operand:DI 2 "register_operand" "")))
5148 (clobber (reg:CC 100))]
5149 "! TARGET_ARCH64 && reload_completed"
5150 [(parallel [(set (reg:CC_NOOV 100)
5151 (compare:CC_NOOV (plus:SI (match_dup 3) (match_dup 1))
5153 (set (match_dup 5) (plus:SI (match_dup 3) (match_dup 1)))])
5155 (plus:SI (plus:SI (match_dup 4) (const_int 0))
5156 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5157 "operands[3] = gen_lowpart (SImode, operands[2]);
5158 operands[4] = gen_highpart (SImode, operands[2]);
5159 operands[5] = gen_lowpart (SImode, operands[0]);
5160 operands[6] = gen_highpart (SImode, operands[0]);")
5162 (define_insn "*adddi3_sp64"
5163 [(set (match_operand:DI 0 "register_operand" "=r")
5164 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
5165 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5169 (define_expand "addsi3"
5170 [(set (match_operand:SI 0 "register_operand" "=r,d")
5171 (plus:SI (match_operand:SI 1 "arith_operand" "%r,d")
5172 (match_operand:SI 2 "arith_add_operand" "rI,d")))]
5176 if (arith_4096_operand(operands[2], SImode))
5178 if (GET_CODE (operands[1]) == CONST_INT)
5179 emit_insn (gen_movsi (operands[0],
5180 GEN_INT (INTVAL (operands[1]) + 4096)));
5182 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
5183 gen_rtx_MINUS (SImode, operands[1],
5189 (define_insn "*addsi3"
5190 [(set (match_operand:SI 0 "register_operand" "=r,d")
5191 (plus:SI (match_operand:SI 1 "arith_operand" "%r,d")
5192 (match_operand:SI 2 "arith_operand" "rI,d")))]
5196 fpadd32s\\t%1, %2, %0"
5197 [(set_attr "type" "*,fp")])
5199 (define_insn "*cmp_cc_plus"
5200 [(set (reg:CC_NOOV 100)
5201 (compare:CC_NOOV (plus:SI (match_operand:SI 0 "arith_operand" "%r")
5202 (match_operand:SI 1 "arith_operand" "rI"))
5205 "addcc\\t%0, %1, %%g0"
5206 [(set_attr "type" "compare")])
5208 (define_insn "*cmp_ccx_plus"
5209 [(set (reg:CCX_NOOV 100)
5210 (compare:CCX_NOOV (plus:DI (match_operand:DI 0 "arith_double_operand" "%r")
5211 (match_operand:DI 1 "arith_double_operand" "rHI"))
5214 "addcc\\t%0, %1, %%g0"
5215 [(set_attr "type" "compare")])
5217 (define_insn "*cmp_cc_plus_set"
5218 [(set (reg:CC_NOOV 100)
5219 (compare:CC_NOOV (plus:SI (match_operand:SI 1 "arith_operand" "%r")
5220 (match_operand:SI 2 "arith_operand" "rI"))
5222 (set (match_operand:SI 0 "register_operand" "=r")
5223 (plus:SI (match_dup 1) (match_dup 2)))]
5225 "addcc\\t%1, %2, %0"
5226 [(set_attr "type" "compare")])
5228 (define_insn "*cmp_ccx_plus_set"
5229 [(set (reg:CCX_NOOV 100)
5230 (compare:CCX_NOOV (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
5231 (match_operand:DI 2 "arith_double_operand" "rHI"))
5233 (set (match_operand:DI 0 "register_operand" "=r")
5234 (plus:DI (match_dup 1) (match_dup 2)))]
5236 "addcc\\t%1, %2, %0"
5237 [(set_attr "type" "compare")])
5239 (define_expand "subdi3"
5240 [(set (match_operand:DI 0 "register_operand" "=r")
5241 (minus:DI (match_operand:DI 1 "register_operand" "r")
5242 (match_operand:DI 2 "arith_double_add_operand" "rHI")))]
5246 if (! TARGET_ARCH64)
5248 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
5249 gen_rtx_SET (VOIDmode, operands[0],
5250 gen_rtx_MINUS (DImode, operands[1],
5252 gen_rtx_CLOBBER (VOIDmode,
5253 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
5256 if (arith_double_4096_operand(operands[2], DImode))
5258 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
5259 gen_rtx_PLUS (DImode, operands[1],
5265 (define_insn "*subdi3_sp32"
5266 [(set (match_operand:DI 0 "register_operand" "=r")
5267 (minus:DI (match_operand:DI 1 "register_operand" "r")
5268 (match_operand:DI 2 "arith_double_operand" "rHI")))
5269 (clobber (reg:CC 100))]
5272 [(set_attr "length" "2")])
5275 [(set (match_operand:DI 0 "register_operand" "")
5276 (minus:DI (match_operand:DI 1 "register_operand" "")
5277 (match_operand:DI 2 "arith_double_operand" "")))
5278 (clobber (reg:CC 100))]
5281 && (GET_CODE (operands[2]) == CONST_INT
5282 || GET_CODE (operands[2]) == CONST_DOUBLE)"
5283 [(clobber (const_int 0))]
5288 highp = gen_highpart_mode (SImode, DImode, operands[2]);
5289 lowp = gen_lowpart (SImode, operands[2]);
5290 if ((lowp == const0_rtx)
5291 && (operands[0] == operands[1]))
5293 emit_insn (gen_rtx_SET (VOIDmode,
5294 gen_highpart (SImode, operands[0]),
5295 gen_rtx_MINUS (SImode,
5296 gen_highpart_mode (SImode, DImode,
5302 emit_insn (gen_cmp_minus_cc_set (gen_lowpart (SImode, operands[0]),
5303 gen_lowpart (SImode, operands[1]),
5305 emit_insn (gen_subx (gen_highpart (SImode, operands[0]),
5306 gen_highpart_mode (SImode, DImode, operands[1]),
5313 [(set (match_operand:DI 0 "register_operand" "")
5314 (minus:DI (match_operand:DI 1 "register_operand" "")
5315 (match_operand:DI 2 "register_operand" "")))
5316 (clobber (reg:CC 100))]
5318 && reload_completed"
5319 [(clobber (const_int 0))]
5322 emit_insn (gen_cmp_minus_cc_set (gen_lowpart (SImode, operands[0]),
5323 gen_lowpart (SImode, operands[1]),
5324 gen_lowpart (SImode, operands[2])));
5325 emit_insn (gen_subx (gen_highpart (SImode, operands[0]),
5326 gen_highpart (SImode, operands[1]),
5327 gen_highpart (SImode, operands[2])));
5332 [(set (match_operand:DI 0 "register_operand" "=r")
5333 (minus:DI (match_operand:DI 1 "register_operand" "r")
5334 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))
5335 (clobber (reg:CC 100))]
5338 [(set_attr "length" "2")])
5341 [(set (match_operand:DI 0 "register_operand" "")
5342 (minus:DI (match_operand:DI 1 "register_operand" "")
5343 (zero_extend:DI (match_operand:SI 2 "register_operand" ""))))
5344 (clobber (reg:CC 100))]
5345 "! TARGET_ARCH64 && reload_completed"
5346 [(parallel [(set (reg:CC_NOOV 100)
5347 (compare:CC_NOOV (minus:SI (match_dup 3) (match_dup 2))
5349 (set (match_dup 5) (minus:SI (match_dup 3) (match_dup 2)))])
5351 (minus:SI (minus:SI (match_dup 4) (const_int 0))
5352 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5353 "operands[3] = gen_lowpart (SImode, operands[1]);
5354 operands[4] = gen_highpart (SImode, operands[1]);
5355 operands[5] = gen_lowpart (SImode, operands[0]);
5356 operands[6] = gen_highpart (SImode, operands[0]);")
5358 (define_insn "*subdi3_sp64"
5359 [(set (match_operand:DI 0 "register_operand" "=r")
5360 (minus:DI (match_operand:DI 1 "register_operand" "r")
5361 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5365 (define_expand "subsi3"
5366 [(set (match_operand:SI 0 "register_operand" "=r,d")
5367 (minus:SI (match_operand:SI 1 "register_operand" "r,d")
5368 (match_operand:SI 2 "arith_add_operand" "rI,d")))]
5372 if (arith_4096_operand(operands[2], SImode))
5374 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
5375 gen_rtx_PLUS (SImode, operands[1],
5381 (define_insn "*subsi3"
5382 [(set (match_operand:SI 0 "register_operand" "=r,d")
5383 (minus:SI (match_operand:SI 1 "register_operand" "r,d")
5384 (match_operand:SI 2 "arith_operand" "rI,d")))]
5388 fpsub32s\\t%1, %2, %0"
5389 [(set_attr "type" "*,fp")])
5391 (define_insn "*cmp_minus_cc"
5392 [(set (reg:CC_NOOV 100)
5393 (compare:CC_NOOV (minus:SI (match_operand:SI 0 "reg_or_0_operand" "rJ")
5394 (match_operand:SI 1 "arith_operand" "rI"))
5397 "subcc\\t%r0, %1, %%g0"
5398 [(set_attr "type" "compare")])
5400 (define_insn "*cmp_minus_ccx"
5401 [(set (reg:CCX_NOOV 100)
5402 (compare:CCX_NOOV (minus:DI (match_operand:DI 0 "register_operand" "r")
5403 (match_operand:DI 1 "arith_double_operand" "rHI"))
5406 "subcc\\t%0, %1, %%g0"
5407 [(set_attr "type" "compare")])
5409 (define_insn "cmp_minus_cc_set"
5410 [(set (reg:CC_NOOV 100)
5411 (compare:CC_NOOV (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5412 (match_operand:SI 2 "arith_operand" "rI"))
5414 (set (match_operand:SI 0 "register_operand" "=r")
5415 (minus:SI (match_dup 1) (match_dup 2)))]
5417 "subcc\\t%r1, %2, %0"
5418 [(set_attr "type" "compare")])
5420 (define_insn "*cmp_minus_ccx_set"
5421 [(set (reg:CCX_NOOV 100)
5422 (compare:CCX_NOOV (minus:DI (match_operand:DI 1 "register_operand" "r")
5423 (match_operand:DI 2 "arith_double_operand" "rHI"))
5425 (set (match_operand:DI 0 "register_operand" "=r")
5426 (minus:DI (match_dup 1) (match_dup 2)))]
5428 "subcc\\t%1, %2, %0"
5429 [(set_attr "type" "compare")])
5431 ;; Integer Multiply/Divide.
5433 ;; The 32 bit multiply/divide instructions are deprecated on v9, but at
5434 ;; least in UltraSPARC I, II and IIi it is a win tick-wise.
5436 (define_insn "mulsi3"
5437 [(set (match_operand:SI 0 "register_operand" "=r")
5438 (mult:SI (match_operand:SI 1 "arith_operand" "%r")
5439 (match_operand:SI 2 "arith_operand" "rI")))]
5442 [(set_attr "type" "imul")])
5444 (define_expand "muldi3"
5445 [(set (match_operand:DI 0 "register_operand" "=r")
5446 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r")
5447 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5448 "TARGET_ARCH64 || TARGET_V8PLUS"
5453 emit_insn (gen_muldi3_v8plus (operands[0], operands[1], operands[2]));
5458 (define_insn "*muldi3_sp64"
5459 [(set (match_operand:DI 0 "register_operand" "=r")
5460 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r")
5461 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5464 [(set_attr "type" "imul")])
5466 ;; V8plus wide multiply.
5468 (define_insn "muldi3_v8plus"
5469 [(set (match_operand:DI 0 "register_operand" "=r,h")
5470 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r,0")
5471 (match_operand:DI 2 "arith_double_operand" "rI,rI")))
5472 (clobber (match_scratch:SI 3 "=&h,X"))
5473 (clobber (match_scratch:SI 4 "=&h,X"))]
5477 if (sparc_check_64 (operands[1], insn) <= 0)
5478 output_asm_insn (\"srl\\t%L1, 0, %L1\", operands);
5479 if (which_alternative == 1)
5480 output_asm_insn (\"sllx\\t%H1, 32, %H1\", operands);
5481 if (GET_CODE (operands[2]) == CONST_INT)
5483 if (which_alternative == 1)
5484 return \"or\\t%L1, %H1, %H1\\n\\tmulx\\t%H1, %2, %L0\;srlx\\t%L0, 32, %H0\";
5486 return \"sllx\\t%H1, 32, %3\\n\\tor\\t%L1, %3, %3\\n\\tmulx\\t%3, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0\";
5488 else if (rtx_equal_p (operands[1], operands[2]))
5490 if (which_alternative == 1)
5491 return \"or\\t%L1, %H1, %H1\\n\\tmulx\\t%H1, %H1, %L0\;srlx\\t%L0, 32, %H0\";
5493 return \"sllx\\t%H1, 32, %3\\n\\tor\\t%L1, %3, %3\\n\\tmulx\\t%3, %3, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0\";
5495 if (sparc_check_64 (operands[2], insn) <= 0)
5496 output_asm_insn (\"srl\\t%L2, 0, %L2\", operands);
5497 if (which_alternative == 1)
5498 return \"or\\t%L1, %H1, %H1\\n\\tsllx\\t%H2, 32, %L1\\n\\tor\\t%L2, %L1, %L1\\n\\tmulx\\t%H1, %L1, %L0\;srlx\\t%L0, 32, %H0\";
5500 return \"sllx\\t%H1, 32, %3\\n\\tsllx\\t%H2, 32, %4\\n\\tor\\t%L1, %3, %3\\n\\tor\\t%L2, %4, %4\\n\\tmulx\\t%3, %4, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0\";
5502 [(set_attr "type" "multi")
5503 (set_attr "length" "9,8")])
5505 (define_insn "*cmp_mul_set"
5507 (compare:CC (mult:SI (match_operand:SI 1 "arith_operand" "%r")
5508 (match_operand:SI 2 "arith_operand" "rI"))
5510 (set (match_operand:SI 0 "register_operand" "=r")
5511 (mult:SI (match_dup 1) (match_dup 2)))]
5512 "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS"
5513 "smulcc\\t%1, %2, %0"
5514 [(set_attr "type" "imul")])
5516 (define_expand "mulsidi3"
5517 [(set (match_operand:DI 0 "register_operand" "")
5518 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
5519 (sign_extend:DI (match_operand:SI 2 "arith_operand" ""))))]
5523 if (CONSTANT_P (operands[2]))
5526 emit_insn (gen_const_mulsidi3_v8plus (operands[0], operands[1],
5529 emit_insn (gen_const_mulsidi3_sp32 (operands[0], operands[1],
5535 emit_insn (gen_mulsidi3_v8plus (operands[0], operands[1], operands[2]));
5540 ;; V9 puts the 64 bit product in a 64 bit register. Only out or global
5541 ;; registers can hold 64 bit values in the V8plus environment.
5543 (define_insn "mulsidi3_v8plus"
5544 [(set (match_operand:DI 0 "register_operand" "=h,r")
5545 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5546 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
5547 (clobber (match_scratch:SI 3 "=X,&h"))]
5550 smul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
5551 smul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
5552 [(set_attr "type" "multi")
5553 (set_attr "length" "2,3")])
5556 (define_insn "const_mulsidi3_v8plus"
5557 [(set (match_operand:DI 0 "register_operand" "=h,r")
5558 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5559 (match_operand:SI 2 "small_int" "I,I")))
5560 (clobber (match_scratch:SI 3 "=X,&h"))]
5563 smul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
5564 smul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
5565 [(set_attr "type" "multi")
5566 (set_attr "length" "2,3")])
5569 (define_insn "*mulsidi3_sp32"
5570 [(set (match_operand:DI 0 "register_operand" "=r")
5571 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5572 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
5576 return TARGET_SPARCLET ? \"smuld\\t%1, %2, %L0\" : \"smul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
5579 (if_then_else (eq_attr "isa" "sparclet")
5580 (const_string "imul") (const_string "multi")))
5581 (set (attr "length")
5582 (if_then_else (eq_attr "isa" "sparclet")
5583 (const_int 1) (const_int 2)))])
5585 (define_insn "*mulsidi3_sp64"
5586 [(set (match_operand:DI 0 "register_operand" "=r")
5587 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5588 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
5589 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5591 [(set_attr "type" "imul")])
5593 ;; Extra pattern, because sign_extend of a constant isn't valid.
5596 (define_insn "const_mulsidi3_sp32"
5597 [(set (match_operand:DI 0 "register_operand" "=r")
5598 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5599 (match_operand:SI 2 "small_int" "I")))]
5603 return TARGET_SPARCLET ? \"smuld\\t%1, %2, %L0\" : \"smul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
5606 (if_then_else (eq_attr "isa" "sparclet")
5607 (const_string "imul") (const_string "multi")))
5608 (set (attr "length")
5609 (if_then_else (eq_attr "isa" "sparclet")
5610 (const_int 1) (const_int 2)))])
5612 (define_insn "const_mulsidi3_sp64"
5613 [(set (match_operand:DI 0 "register_operand" "=r")
5614 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5615 (match_operand:SI 2 "small_int" "I")))]
5616 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5618 [(set_attr "type" "imul")])
5620 (define_expand "smulsi3_highpart"
5621 [(set (match_operand:SI 0 "register_operand" "")
5623 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
5624 (sign_extend:DI (match_operand:SI 2 "arith_operand" "")))
5626 "TARGET_HARD_MUL && TARGET_ARCH32"
5629 if (CONSTANT_P (operands[2]))
5633 emit_insn (gen_const_smulsi3_highpart_v8plus (operands[0],
5639 emit_insn (gen_const_smulsi3_highpart (operands[0], operands[1], operands[2]));
5644 emit_insn (gen_smulsi3_highpart_v8plus (operands[0], operands[1],
5645 operands[2], GEN_INT (32)));
5651 (define_insn "smulsi3_highpart_v8plus"
5652 [(set (match_operand:SI 0 "register_operand" "=h,r")
5654 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5655 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
5656 (match_operand:SI 3 "const_int_operand" "i,i"))))
5657 (clobber (match_scratch:SI 4 "=X,&h"))]
5660 smul\\t%1, %2, %0\;srlx\\t%0, %3, %0
5661 smul\\t%1, %2, %4\;srlx\\t%4, %3, %0"
5662 [(set_attr "type" "multi")
5663 (set_attr "length" "2")])
5665 ;; The combiner changes TRUNCATE in the previous pattern to SUBREG.
5668 [(set (match_operand:SI 0 "register_operand" "=h,r")
5671 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5672 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
5673 (match_operand:SI 3 "const_int_operand" "i,i"))
5675 (clobber (match_scratch:SI 4 "=X,&h"))]
5678 smul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
5679 smul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
5680 [(set_attr "type" "multi")
5681 (set_attr "length" "2")])
5684 (define_insn "const_smulsi3_highpart_v8plus"
5685 [(set (match_operand:SI 0 "register_operand" "=h,r")
5687 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5688 (match_operand 2 "small_int" "i,i"))
5689 (match_operand:SI 3 "const_int_operand" "i,i"))))
5690 (clobber (match_scratch:SI 4 "=X,&h"))]
5693 smul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
5694 smul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
5695 [(set_attr "type" "multi")
5696 (set_attr "length" "2")])
5699 (define_insn "*smulsi3_highpart_sp32"
5700 [(set (match_operand:SI 0 "register_operand" "=r")
5702 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5703 (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
5706 "smul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
5707 [(set_attr "type" "multi")
5708 (set_attr "length" "2")])
5711 (define_insn "const_smulsi3_highpart"
5712 [(set (match_operand:SI 0 "register_operand" "=r")
5714 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5715 (match_operand:SI 2 "register_operand" "r"))
5718 "smul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
5719 [(set_attr "type" "multi")
5720 (set_attr "length" "2")])
5722 (define_expand "umulsidi3"
5723 [(set (match_operand:DI 0 "register_operand" "")
5724 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
5725 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" ""))))]
5729 if (CONSTANT_P (operands[2]))
5732 emit_insn (gen_const_umulsidi3_v8plus (operands[0], operands[1],
5735 emit_insn (gen_const_umulsidi3_sp32 (operands[0], operands[1],
5741 emit_insn (gen_umulsidi3_v8plus (operands[0], operands[1], operands[2]));
5747 (define_insn "umulsidi3_v8plus"
5748 [(set (match_operand:DI 0 "register_operand" "=h,r")
5749 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5750 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
5751 (clobber (match_scratch:SI 3 "=X,&h"))]
5754 umul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
5755 umul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
5756 [(set_attr "type" "multi")
5757 (set_attr "length" "2,3")])
5760 (define_insn "*umulsidi3_sp32"
5761 [(set (match_operand:DI 0 "register_operand" "=r")
5762 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5763 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
5767 return TARGET_SPARCLET ? \"umuld\\t%1, %2, %L0\" : \"umul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
5770 (if_then_else (eq_attr "isa" "sparclet")
5771 (const_string "imul") (const_string "multi")))
5772 (set (attr "length")
5773 (if_then_else (eq_attr "isa" "sparclet")
5774 (const_int 1) (const_int 2)))])
5776 (define_insn "*umulsidi3_sp64"
5777 [(set (match_operand:DI 0 "register_operand" "=r")
5778 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5779 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
5780 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5782 [(set_attr "type" "imul")])
5784 ;; Extra pattern, because sign_extend of a constant isn't valid.
5787 (define_insn "const_umulsidi3_sp32"
5788 [(set (match_operand:DI 0 "register_operand" "=r")
5789 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5790 (match_operand:SI 2 "uns_small_int" "")))]
5794 return TARGET_SPARCLET ? \"umuld\\t%1, %2, %L0\" : \"umul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
5797 (if_then_else (eq_attr "isa" "sparclet")
5798 (const_string "imul") (const_string "multi")))
5799 (set (attr "length")
5800 (if_then_else (eq_attr "isa" "sparclet")
5801 (const_int 1) (const_int 2)))])
5803 (define_insn "const_umulsidi3_sp64"
5804 [(set (match_operand:DI 0 "register_operand" "=r")
5805 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5806 (match_operand:SI 2 "uns_small_int" "")))]
5807 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5809 [(set_attr "type" "imul")])
5812 (define_insn "const_umulsidi3_v8plus"
5813 [(set (match_operand:DI 0 "register_operand" "=h,r")
5814 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5815 (match_operand:SI 2 "uns_small_int" "")))
5816 (clobber (match_scratch:SI 3 "=X,h"))]
5819 umul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
5820 umul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
5821 [(set_attr "type" "multi")
5822 (set_attr "length" "2,3")])
5824 (define_expand "umulsi3_highpart"
5825 [(set (match_operand:SI 0 "register_operand" "")
5827 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
5828 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" "")))
5830 "TARGET_HARD_MUL && TARGET_ARCH32"
5833 if (CONSTANT_P (operands[2]))
5837 emit_insn (gen_const_umulsi3_highpart_v8plus (operands[0],
5843 emit_insn (gen_const_umulsi3_highpart (operands[0], operands[1], operands[2]));
5848 emit_insn (gen_umulsi3_highpart_v8plus (operands[0], operands[1],
5849 operands[2], GEN_INT (32)));
5855 (define_insn "umulsi3_highpart_v8plus"
5856 [(set (match_operand:SI 0 "register_operand" "=h,r")
5858 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5859 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
5860 (match_operand:SI 3 "const_int_operand" "i,i"))))
5861 (clobber (match_scratch:SI 4 "=X,h"))]
5864 umul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
5865 umul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
5866 [(set_attr "type" "multi")
5867 (set_attr "length" "2")])
5870 (define_insn "const_umulsi3_highpart_v8plus"
5871 [(set (match_operand:SI 0 "register_operand" "=h,r")
5873 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5874 (match_operand:SI 2 "uns_small_int" ""))
5875 (match_operand:SI 3 "const_int_operand" "i,i"))))
5876 (clobber (match_scratch:SI 4 "=X,h"))]
5879 umul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
5880 umul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
5881 [(set_attr "type" "multi")
5882 (set_attr "length" "2")])
5885 (define_insn "*umulsi3_highpart_sp32"
5886 [(set (match_operand:SI 0 "register_operand" "=r")
5888 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5889 (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
5892 "umul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
5893 [(set_attr "type" "multi")
5894 (set_attr "length" "2")])
5897 (define_insn "const_umulsi3_highpart"
5898 [(set (match_operand:SI 0 "register_operand" "=r")
5900 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5901 (match_operand:SI 2 "uns_small_int" ""))
5904 "umul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
5905 [(set_attr "type" "multi")
5906 (set_attr "length" "2")])
5908 ;; The v8 architecture specifies that there must be 3 instructions between
5909 ;; a y register write and a use of it for correct results.
5911 (define_expand "divsi3"
5912 [(parallel [(set (match_operand:SI 0 "register_operand" "=r,r")
5913 (div:SI (match_operand:SI 1 "register_operand" "r,r")
5914 (match_operand:SI 2 "input_operand" "rI,m")))
5915 (clobber (match_scratch:SI 3 "=&r,&r"))])]
5916 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
5921 operands[3] = gen_reg_rtx(SImode);
5922 emit_insn (gen_ashrsi3 (operands[3], operands[1], GEN_INT (31)));
5923 emit_insn (gen_divsi3_sp64 (operands[0], operands[1], operands[2],
5929 (define_insn "divsi3_sp32"
5930 [(set (match_operand:SI 0 "register_operand" "=r,r")
5931 (div:SI (match_operand:SI 1 "register_operand" "r,r")
5932 (match_operand:SI 2 "input_operand" "rI,m")))
5933 (clobber (match_scratch:SI 3 "=&r,&r"))]
5934 "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS)
5938 if (which_alternative == 0)
5940 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tsdiv\\t%1, %2, %0\";
5942 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tnop\\n\\tnop\\n\\tnop\\n\\tsdiv\\t%1, %2, %0\";
5945 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tld\\t%2, %3\\n\\tsdiv\\t%1, %3, %0\";
5947 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tld\\t%2, %3\\n\\tnop\\n\\tnop\\n\\tsdiv\\t%1, %3, %0\";
5949 [(set_attr "type" "multi")
5950 (set (attr "length")
5951 (if_then_else (eq_attr "isa" "v9")
5952 (const_int 4) (const_int 6)))])
5954 (define_insn "divsi3_sp64"
5955 [(set (match_operand:SI 0 "register_operand" "=r")
5956 (div:SI (match_operand:SI 1 "register_operand" "r")
5957 (match_operand:SI 2 "input_operand" "rI")))
5958 (use (match_operand:SI 3 "register_operand" "r"))]
5959 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5960 "wr\\t%%g0, %3, %%y\\n\\tsdiv\\t%1, %2, %0"
5961 [(set_attr "type" "multi")
5962 (set_attr "length" "2")])
5964 (define_insn "divdi3"
5965 [(set (match_operand:DI 0 "register_operand" "=r")
5966 (div:DI (match_operand:DI 1 "register_operand" "r")
5967 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5969 "sdivx\\t%1, %2, %0"
5970 [(set_attr "type" "idiv")])
5972 (define_insn "*cmp_sdiv_cc_set"
5974 (compare:CC (div:SI (match_operand:SI 1 "register_operand" "r")
5975 (match_operand:SI 2 "arith_operand" "rI"))
5977 (set (match_operand:SI 0 "register_operand" "=r")
5978 (div:SI (match_dup 1) (match_dup 2)))
5979 (clobber (match_scratch:SI 3 "=&r"))]
5980 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
5984 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tsdivcc\\t%1, %2, %0\";
5986 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tnop\\n\\tnop\\n\\tnop\\n\\tsdivcc\\t%1, %2, %0\";
5988 [(set_attr "type" "multi")
5989 (set (attr "length")
5990 (if_then_else (eq_attr "isa" "v9")
5991 (const_int 3) (const_int 6)))])
5994 (define_expand "udivsi3"
5995 [(set (match_operand:SI 0 "register_operand" "")
5996 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "")
5997 (match_operand:SI 2 "input_operand" "")))]
5998 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
6001 (define_insn "udivsi3_sp32"
6002 [(set (match_operand:SI 0 "register_operand" "=r,&r,&r")
6003 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "r,r,m")
6004 (match_operand:SI 2 "input_operand" "rI,m,r")))]
6006 || TARGET_DEPRECATED_V8_INSNS)
6010 output_asm_insn (\"wr\\t%%g0, %%g0, %%y\", operands);
6011 switch (which_alternative)
6014 return \"nop\\n\\tnop\\n\\tnop\\n\\tudiv\\t%1, %2, %0\";
6016 return \"ld\\t%2, %0\\n\\tnop\\n\\tnop\\n\\tudiv\\t%1, %0, %0\";
6018 return \"ld\\t%1, %0\\n\\tnop\\n\\tnop\\n\\tudiv\\t%0, %2, %0\";
6021 [(set_attr "type" "multi")
6022 (set_attr "length" "5")])
6024 (define_insn "udivsi3_sp64"
6025 [(set (match_operand:SI 0 "register_operand" "=r")
6026 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "r")
6027 (match_operand:SI 2 "input_operand" "rI")))]
6028 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6029 "wr\\t%%g0, 0, %%y\\n\\tudiv\\t%1, %2, %0"
6030 [(set_attr "type" "multi")
6031 (set_attr "length" "2")])
6033 (define_insn "udivdi3"
6034 [(set (match_operand:DI 0 "register_operand" "=r")
6035 (udiv:DI (match_operand:DI 1 "register_operand" "r")
6036 (match_operand:DI 2 "arith_double_operand" "rHI")))]
6038 "udivx\\t%1, %2, %0"
6039 [(set_attr "type" "idiv")])
6041 (define_insn "*cmp_udiv_cc_set"
6043 (compare:CC (udiv:SI (match_operand:SI 1 "register_operand" "r")
6044 (match_operand:SI 2 "arith_operand" "rI"))
6046 (set (match_operand:SI 0 "register_operand" "=r")
6047 (udiv:SI (match_dup 1) (match_dup 2)))]
6049 || TARGET_DEPRECATED_V8_INSNS"
6053 return \"wr\\t%%g0, %%g0, %%y\\n\\tudivcc\\t%1, %2, %0\";
6055 return \"wr\\t%%g0, %%g0, %%y\\n\\tnop\\n\\tnop\\n\\tnop\\n\\tudivcc\\t%1, %2, %0\";
6057 [(set_attr "type" "multi")
6058 (set (attr "length")
6059 (if_then_else (eq_attr "isa" "v9")
6060 (const_int 2) (const_int 5)))])
6062 ; sparclet multiply/accumulate insns
6064 (define_insn "*smacsi"
6065 [(set (match_operand:SI 0 "register_operand" "=r")
6066 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "%r")
6067 (match_operand:SI 2 "arith_operand" "rI"))
6068 (match_operand:SI 3 "register_operand" "0")))]
6071 [(set_attr "type" "imul")])
6073 (define_insn "*smacdi"
6074 [(set (match_operand:DI 0 "register_operand" "=r")
6075 (plus:DI (mult:DI (sign_extend:DI
6076 (match_operand:SI 1 "register_operand" "%r"))
6078 (match_operand:SI 2 "register_operand" "r")))
6079 (match_operand:DI 3 "register_operand" "0")))]
6081 "smacd\\t%1, %2, %L0"
6082 [(set_attr "type" "imul")])
6084 (define_insn "*umacdi"
6085 [(set (match_operand:DI 0 "register_operand" "=r")
6086 (plus:DI (mult:DI (zero_extend:DI
6087 (match_operand:SI 1 "register_operand" "%r"))
6089 (match_operand:SI 2 "register_operand" "r")))
6090 (match_operand:DI 3 "register_operand" "0")))]
6092 "umacd\\t%1, %2, %L0"
6093 [(set_attr "type" "imul")])
6095 ;;- Boolean instructions
6096 ;; We define DImode `and' so with DImode `not' we can get
6097 ;; DImode `andn'. Other combinations are possible.
6099 (define_expand "anddi3"
6100 [(set (match_operand:DI 0 "register_operand" "")
6101 (and:DI (match_operand:DI 1 "arith_double_operand" "")
6102 (match_operand:DI 2 "arith_double_operand" "")))]
6106 (define_insn "*anddi3_sp32"
6107 [(set (match_operand:DI 0 "register_operand" "=r,b")
6108 (and:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6109 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6114 [(set_attr "type" "*,fp")
6115 (set_attr "length" "2,*")
6116 (set_attr "fptype" "double")])
6118 (define_insn "*anddi3_sp64"
6119 [(set (match_operand:DI 0 "register_operand" "=r,b")
6120 (and:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6121 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6126 [(set_attr "type" "*,fp")
6127 (set_attr "fptype" "double")])
6129 (define_insn "andsi3"
6130 [(set (match_operand:SI 0 "register_operand" "=r,d")
6131 (and:SI (match_operand:SI 1 "arith_operand" "%r,d")
6132 (match_operand:SI 2 "arith_operand" "rI,d")))]
6137 [(set_attr "type" "*,fp")])
6140 [(set (match_operand:SI 0 "register_operand" "")
6141 (and:SI (match_operand:SI 1 "register_operand" "")
6142 (match_operand:SI 2 "" "")))
6143 (clobber (match_operand:SI 3 "register_operand" ""))]
6144 "GET_CODE (operands[2]) == CONST_INT
6145 && !SMALL_INT32 (operands[2])
6146 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6147 [(set (match_dup 3) (match_dup 4))
6148 (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 1)))]
6151 operands[4] = GEN_INT (~INTVAL (operands[2]));
6154 ;; Split DImode logical operations requiring two instructions.
6156 [(set (match_operand:DI 0 "register_operand" "")
6157 (match_operator:DI 1 "cc_arithop" ; AND, IOR, XOR
6158 [(match_operand:DI 2 "register_operand" "")
6159 (match_operand:DI 3 "arith_double_operand" "")]))]
6162 && ((GET_CODE (operands[0]) == REG
6163 && REGNO (operands[0]) < 32)
6164 || (GET_CODE (operands[0]) == SUBREG
6165 && GET_CODE (SUBREG_REG (operands[0])) == REG
6166 && REGNO (SUBREG_REG (operands[0])) < 32))"
6167 [(set (match_dup 4) (match_op_dup:SI 1 [(match_dup 6) (match_dup 8)]))
6168 (set (match_dup 5) (match_op_dup:SI 1 [(match_dup 7) (match_dup 9)]))]
6171 operands[4] = gen_highpart (SImode, operands[0]);
6172 operands[5] = gen_lowpart (SImode, operands[0]);
6173 operands[6] = gen_highpart (SImode, operands[2]);
6174 operands[7] = gen_lowpart (SImode, operands[2]);
6175 #if HOST_BITS_PER_WIDE_INT == 32
6176 if (GET_CODE (operands[3]) == CONST_INT)
6178 if (INTVAL (operands[3]) < 0)
6179 operands[8] = constm1_rtx;
6181 operands[8] = const0_rtx;
6185 operands[8] = gen_highpart_mode (SImode, DImode, operands[3]);
6186 operands[9] = gen_lowpart (SImode, operands[3]);
6189 (define_insn "*and_not_di_sp32"
6190 [(set (match_operand:DI 0 "register_operand" "=r,b")
6191 (and:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6192 (match_operand:DI 2 "register_operand" "r,b")))]
6196 fandnot1\\t%1, %2, %0"
6197 [(set_attr "type" "*,fp")
6198 (set_attr "length" "2,*")
6199 (set_attr "fptype" "double")])
6202 [(set (match_operand:DI 0 "register_operand" "")
6203 (and:DI (not:DI (match_operand:DI 1 "register_operand" ""))
6204 (match_operand:DI 2 "register_operand" "")))]
6207 && ((GET_CODE (operands[0]) == REG
6208 && REGNO (operands[0]) < 32)
6209 || (GET_CODE (operands[0]) == SUBREG
6210 && GET_CODE (SUBREG_REG (operands[0])) == REG
6211 && REGNO (SUBREG_REG (operands[0])) < 32))"
6212 [(set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))
6213 (set (match_dup 6) (and:SI (not:SI (match_dup 7)) (match_dup 8)))]
6214 "operands[3] = gen_highpart (SImode, operands[0]);
6215 operands[4] = gen_highpart (SImode, operands[1]);
6216 operands[5] = gen_highpart (SImode, operands[2]);
6217 operands[6] = gen_lowpart (SImode, operands[0]);
6218 operands[7] = gen_lowpart (SImode, operands[1]);
6219 operands[8] = gen_lowpart (SImode, operands[2]);")
6221 (define_insn "*and_not_di_sp64"
6222 [(set (match_operand:DI 0 "register_operand" "=r,b")
6223 (and:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6224 (match_operand:DI 2 "register_operand" "r,b")))]
6228 fandnot1\\t%1, %2, %0"
6229 [(set_attr "type" "*,fp")
6230 (set_attr "fptype" "double")])
6232 (define_insn "*and_not_si"
6233 [(set (match_operand:SI 0 "register_operand" "=r,d")
6234 (and:SI (not:SI (match_operand:SI 1 "register_operand" "r,d"))
6235 (match_operand:SI 2 "register_operand" "r,d")))]
6239 fandnot1s\\t%1, %2, %0"
6240 [(set_attr "type" "*,fp")])
6242 (define_expand "iordi3"
6243 [(set (match_operand:DI 0 "register_operand" "")
6244 (ior:DI (match_operand:DI 1 "arith_double_operand" "")
6245 (match_operand:DI 2 "arith_double_operand" "")))]
6249 (define_insn "*iordi3_sp32"
6250 [(set (match_operand:DI 0 "register_operand" "=r,b")
6251 (ior:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6252 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6257 [(set_attr "type" "*,fp")
6258 (set_attr "length" "2,*")
6259 (set_attr "fptype" "double")])
6261 (define_insn "*iordi3_sp64"
6262 [(set (match_operand:DI 0 "register_operand" "=r,b")
6263 (ior:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6264 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6269 [(set_attr "type" "*,fp")
6270 (set_attr "fptype" "double")])
6272 (define_insn "iorsi3"
6273 [(set (match_operand:SI 0 "register_operand" "=r,d")
6274 (ior:SI (match_operand:SI 1 "arith_operand" "%r,d")
6275 (match_operand:SI 2 "arith_operand" "rI,d")))]
6280 [(set_attr "type" "*,fp")])
6283 [(set (match_operand:SI 0 "register_operand" "")
6284 (ior:SI (match_operand:SI 1 "register_operand" "")
6285 (match_operand:SI 2 "" "")))
6286 (clobber (match_operand:SI 3 "register_operand" ""))]
6287 "GET_CODE (operands[2]) == CONST_INT
6288 && !SMALL_INT32 (operands[2])
6289 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6290 [(set (match_dup 3) (match_dup 4))
6291 (set (match_dup 0) (ior:SI (not:SI (match_dup 3)) (match_dup 1)))]
6294 operands[4] = GEN_INT (~INTVAL (operands[2]));
6297 (define_insn "*or_not_di_sp32"
6298 [(set (match_operand:DI 0 "register_operand" "=r,b")
6299 (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6300 (match_operand:DI 2 "register_operand" "r,b")))]
6304 fornot1\\t%1, %2, %0"
6305 [(set_attr "type" "*,fp")
6306 (set_attr "length" "2,*")
6307 (set_attr "fptype" "double")])
6310 [(set (match_operand:DI 0 "register_operand" "")
6311 (ior:DI (not:DI (match_operand:DI 1 "register_operand" ""))
6312 (match_operand:DI 2 "register_operand" "")))]
6315 && ((GET_CODE (operands[0]) == REG
6316 && REGNO (operands[0]) < 32)
6317 || (GET_CODE (operands[0]) == SUBREG
6318 && GET_CODE (SUBREG_REG (operands[0])) == REG
6319 && REGNO (SUBREG_REG (operands[0])) < 32))"
6320 [(set (match_dup 3) (ior:SI (not:SI (match_dup 4)) (match_dup 5)))
6321 (set (match_dup 6) (ior:SI (not:SI (match_dup 7)) (match_dup 8)))]
6322 "operands[3] = gen_highpart (SImode, operands[0]);
6323 operands[4] = gen_highpart (SImode, operands[1]);
6324 operands[5] = gen_highpart (SImode, operands[2]);
6325 operands[6] = gen_lowpart (SImode, operands[0]);
6326 operands[7] = gen_lowpart (SImode, operands[1]);
6327 operands[8] = gen_lowpart (SImode, operands[2]);")
6329 (define_insn "*or_not_di_sp64"
6330 [(set (match_operand:DI 0 "register_operand" "=r,b")
6331 (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6332 (match_operand:DI 2 "register_operand" "r,b")))]
6336 fornot1\\t%1, %2, %0"
6337 [(set_attr "type" "*,fp")
6338 (set_attr "fptype" "double")])
6340 (define_insn "*or_not_si"
6341 [(set (match_operand:SI 0 "register_operand" "=r,d")
6342 (ior:SI (not:SI (match_operand:SI 1 "register_operand" "r,d"))
6343 (match_operand:SI 2 "register_operand" "r,d")))]
6347 fornot1s\\t%1, %2, %0"
6348 [(set_attr "type" "*,fp")])
6350 (define_expand "xordi3"
6351 [(set (match_operand:DI 0 "register_operand" "")
6352 (xor:DI (match_operand:DI 1 "arith_double_operand" "")
6353 (match_operand:DI 2 "arith_double_operand" "")))]
6357 (define_insn "*xordi3_sp32"
6358 [(set (match_operand:DI 0 "register_operand" "=r,b")
6359 (xor:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6360 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6365 [(set_attr "type" "*,fp")
6366 (set_attr "length" "2,*")
6367 (set_attr "fptype" "double")])
6369 (define_insn "*xordi3_sp64"
6370 [(set (match_operand:DI 0 "register_operand" "=r,b")
6371 (xor:DI (match_operand:DI 1 "arith_double_operand" "%rJ,b")
6372 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6377 [(set_attr "type" "*,fp")
6378 (set_attr "fptype" "double")])
6380 (define_insn "*xordi3_sp64_dbl"
6381 [(set (match_operand:DI 0 "register_operand" "=r")
6382 (xor:DI (match_operand:DI 1 "register_operand" "r")
6383 (match_operand:DI 2 "const64_operand" "")))]
6385 && HOST_BITS_PER_WIDE_INT != 64)"
6388 (define_insn "xorsi3"
6389 [(set (match_operand:SI 0 "register_operand" "=r,d")
6390 (xor:SI (match_operand:SI 1 "arith_operand" "%rJ,d")
6391 (match_operand:SI 2 "arith_operand" "rI,d")))]
6396 [(set_attr "type" "*,fp")])
6399 [(set (match_operand:SI 0 "register_operand" "")
6400 (xor:SI (match_operand:SI 1 "register_operand" "")
6401 (match_operand:SI 2 "" "")))
6402 (clobber (match_operand:SI 3 "register_operand" ""))]
6403 "GET_CODE (operands[2]) == CONST_INT
6404 && !SMALL_INT32 (operands[2])
6405 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6406 [(set (match_dup 3) (match_dup 4))
6407 (set (match_dup 0) (not:SI (xor:SI (match_dup 3) (match_dup 1))))]
6410 operands[4] = GEN_INT (~INTVAL (operands[2]));
6414 [(set (match_operand:SI 0 "register_operand" "")
6415 (not:SI (xor:SI (match_operand:SI 1 "register_operand" "")
6416 (match_operand:SI 2 "" ""))))
6417 (clobber (match_operand:SI 3 "register_operand" ""))]
6418 "GET_CODE (operands[2]) == CONST_INT
6419 && !SMALL_INT32 (operands[2])
6420 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6421 [(set (match_dup 3) (match_dup 4))
6422 (set (match_dup 0) (xor:SI (match_dup 3) (match_dup 1)))]
6425 operands[4] = GEN_INT (~INTVAL (operands[2]));
6428 ;; xnor patterns. Note that (a ^ ~b) == (~a ^ b) == ~(a ^ b).
6429 ;; Combine now canonicalizes to the rightmost expression.
6430 (define_insn "*xor_not_di_sp32"
6431 [(set (match_operand:DI 0 "register_operand" "=r,b")
6432 (not:DI (xor:DI (match_operand:DI 1 "register_operand" "r,b")
6433 (match_operand:DI 2 "register_operand" "r,b"))))]
6438 [(set_attr "type" "*,fp")
6439 (set_attr "length" "2,*")
6440 (set_attr "fptype" "double")])
6443 [(set (match_operand:DI 0 "register_operand" "")
6444 (not:DI (xor:DI (match_operand:DI 1 "register_operand" "")
6445 (match_operand:DI 2 "register_operand" ""))))]
6448 && ((GET_CODE (operands[0]) == REG
6449 && REGNO (operands[0]) < 32)
6450 || (GET_CODE (operands[0]) == SUBREG
6451 && GET_CODE (SUBREG_REG (operands[0])) == REG
6452 && REGNO (SUBREG_REG (operands[0])) < 32))"
6453 [(set (match_dup 3) (not:SI (xor:SI (match_dup 4) (match_dup 5))))
6454 (set (match_dup 6) (not:SI (xor:SI (match_dup 7) (match_dup 8))))]
6455 "operands[3] = gen_highpart (SImode, operands[0]);
6456 operands[4] = gen_highpart (SImode, operands[1]);
6457 operands[5] = gen_highpart (SImode, operands[2]);
6458 operands[6] = gen_lowpart (SImode, operands[0]);
6459 operands[7] = gen_lowpart (SImode, operands[1]);
6460 operands[8] = gen_lowpart (SImode, operands[2]);")
6462 (define_insn "*xor_not_di_sp64"
6463 [(set (match_operand:DI 0 "register_operand" "=r,b")
6464 (not:DI (xor:DI (match_operand:DI 1 "reg_or_0_operand" "rJ,b")
6465 (match_operand:DI 2 "arith_double_operand" "rHI,b"))))]
6470 [(set_attr "type" "*,fp")
6471 (set_attr "fptype" "double")])
6473 (define_insn "*xor_not_si"
6474 [(set (match_operand:SI 0 "register_operand" "=r,d")
6475 (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "rJ,d")
6476 (match_operand:SI 2 "arith_operand" "rI,d"))))]
6480 fxnors\\t%1, %2, %0"
6481 [(set_attr "type" "*,fp")])
6483 ;; These correspond to the above in the case where we also (or only)
6484 ;; want to set the condition code.
6486 (define_insn "*cmp_cc_arith_op"
6489 (match_operator:SI 2 "cc_arithop"
6490 [(match_operand:SI 0 "arith_operand" "%r")
6491 (match_operand:SI 1 "arith_operand" "rI")])
6494 "%A2cc\\t%0, %1, %%g0"
6495 [(set_attr "type" "compare")])
6497 (define_insn "*cmp_ccx_arith_op"
6500 (match_operator:DI 2 "cc_arithop"
6501 [(match_operand:DI 0 "arith_double_operand" "%r")
6502 (match_operand:DI 1 "arith_double_operand" "rHI")])
6505 "%A2cc\\t%0, %1, %%g0"
6506 [(set_attr "type" "compare")])
6508 (define_insn "*cmp_cc_arith_op_set"
6511 (match_operator:SI 3 "cc_arithop"
6512 [(match_operand:SI 1 "arith_operand" "%r")
6513 (match_operand:SI 2 "arith_operand" "rI")])
6515 (set (match_operand:SI 0 "register_operand" "=r")
6516 (match_operator:SI 4 "cc_arithop" [(match_dup 1) (match_dup 2)]))]
6517 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
6518 "%A3cc\\t%1, %2, %0"
6519 [(set_attr "type" "compare")])
6521 (define_insn "*cmp_ccx_arith_op_set"
6524 (match_operator:DI 3 "cc_arithop"
6525 [(match_operand:DI 1 "arith_double_operand" "%r")
6526 (match_operand:DI 2 "arith_double_operand" "rHI")])
6528 (set (match_operand:DI 0 "register_operand" "=r")
6529 (match_operator:DI 4 "cc_arithop" [(match_dup 1) (match_dup 2)]))]
6530 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
6531 "%A3cc\\t%1, %2, %0"
6532 [(set_attr "type" "compare")])
6534 (define_insn "*cmp_cc_xor_not"
6537 (not:SI (xor:SI (match_operand:SI 0 "reg_or_0_operand" "%rJ")
6538 (match_operand:SI 1 "arith_operand" "rI")))
6541 "xnorcc\\t%r0, %1, %%g0"
6542 [(set_attr "type" "compare")])
6544 (define_insn "*cmp_ccx_xor_not"
6547 (not:DI (xor:DI (match_operand:DI 0 "reg_or_0_operand" "%rJ")
6548 (match_operand:DI 1 "arith_double_operand" "rHI")))
6551 "xnorcc\\t%r0, %1, %%g0"
6552 [(set_attr "type" "compare")])
6554 (define_insn "*cmp_cc_xor_not_set"
6557 (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
6558 (match_operand:SI 2 "arith_operand" "rI")))
6560 (set (match_operand:SI 0 "register_operand" "=r")
6561 (not:SI (xor:SI (match_dup 1) (match_dup 2))))]
6563 "xnorcc\\t%r1, %2, %0"
6564 [(set_attr "type" "compare")])
6566 (define_insn "*cmp_ccx_xor_not_set"
6569 (not:DI (xor:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ")
6570 (match_operand:DI 2 "arith_double_operand" "rHI")))
6572 (set (match_operand:DI 0 "register_operand" "=r")
6573 (not:DI (xor:DI (match_dup 1) (match_dup 2))))]
6575 "xnorcc\\t%r1, %2, %0"
6576 [(set_attr "type" "compare")])
6578 (define_insn "*cmp_cc_arith_op_not"
6581 (match_operator:SI 2 "cc_arithopn"
6582 [(not:SI (match_operand:SI 0 "arith_operand" "rI"))
6583 (match_operand:SI 1 "reg_or_0_operand" "rJ")])
6586 "%B2cc\\t%r1, %0, %%g0"
6587 [(set_attr "type" "compare")])
6589 (define_insn "*cmp_ccx_arith_op_not"
6592 (match_operator:DI 2 "cc_arithopn"
6593 [(not:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
6594 (match_operand:DI 1 "reg_or_0_operand" "rJ")])
6597 "%B2cc\\t%r1, %0, %%g0"
6598 [(set_attr "type" "compare")])
6600 (define_insn "*cmp_cc_arith_op_not_set"
6603 (match_operator:SI 3 "cc_arithopn"
6604 [(not:SI (match_operand:SI 1 "arith_operand" "rI"))
6605 (match_operand:SI 2 "reg_or_0_operand" "rJ")])
6607 (set (match_operand:SI 0 "register_operand" "=r")
6608 (match_operator:SI 4 "cc_arithopn"
6609 [(not:SI (match_dup 1)) (match_dup 2)]))]
6610 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
6611 "%B3cc\\t%r2, %1, %0"
6612 [(set_attr "type" "compare")])
6614 (define_insn "*cmp_ccx_arith_op_not_set"
6617 (match_operator:DI 3 "cc_arithopn"
6618 [(not:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
6619 (match_operand:DI 2 "reg_or_0_operand" "rJ")])
6621 (set (match_operand:DI 0 "register_operand" "=r")
6622 (match_operator:DI 4 "cc_arithopn"
6623 [(not:DI (match_dup 1)) (match_dup 2)]))]
6624 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
6625 "%B3cc\\t%r2, %1, %0"
6626 [(set_attr "type" "compare")])
6628 ;; We cannot use the "neg" pseudo insn because the Sun assembler
6629 ;; does not know how to make it work for constants.
6631 (define_expand "negdi2"
6632 [(set (match_operand:DI 0 "register_operand" "=r")
6633 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
6637 if (! TARGET_ARCH64)
6639 emit_insn (gen_rtx_PARALLEL
6642 gen_rtx_SET (VOIDmode, operand0,
6643 gen_rtx_NEG (DImode, operand1)),
6644 gen_rtx_CLOBBER (VOIDmode,
6645 gen_rtx_REG (CCmode,
6651 (define_insn "*negdi2_sp32"
6652 [(set (match_operand:DI 0 "register_operand" "=r")
6653 (neg:DI (match_operand:DI 1 "register_operand" "r")))
6654 (clobber (reg:CC 100))]
6657 [(set_attr "length" "2")])
6660 [(set (match_operand:DI 0 "register_operand" "")
6661 (neg:DI (match_operand:DI 1 "register_operand" "")))
6662 (clobber (reg:CC 100))]
6664 && reload_completed"
6665 [(parallel [(set (reg:CC_NOOV 100)
6666 (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 5))
6668 (set (match_dup 4) (minus:SI (const_int 0) (match_dup 5)))])
6669 (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
6670 (ltu:SI (reg:CC 100) (const_int 0))))]
6671 "operands[2] = gen_highpart (SImode, operands[0]);
6672 operands[3] = gen_highpart (SImode, operands[1]);
6673 operands[4] = gen_lowpart (SImode, operands[0]);
6674 operands[5] = gen_lowpart (SImode, operands[1]);")
6676 (define_insn "*negdi2_sp64"
6677 [(set (match_operand:DI 0 "register_operand" "=r")
6678 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
6680 "sub\\t%%g0, %1, %0")
6682 (define_insn "negsi2"
6683 [(set (match_operand:SI 0 "register_operand" "=r")
6684 (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
6686 "sub\\t%%g0, %1, %0")
6688 (define_insn "*cmp_cc_neg"
6689 [(set (reg:CC_NOOV 100)
6690 (compare:CC_NOOV (neg:SI (match_operand:SI 0 "arith_operand" "rI"))
6693 "subcc\\t%%g0, %0, %%g0"
6694 [(set_attr "type" "compare")])
6696 (define_insn "*cmp_ccx_neg"
6697 [(set (reg:CCX_NOOV 100)
6698 (compare:CCX_NOOV (neg:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
6701 "subcc\\t%%g0, %0, %%g0"
6702 [(set_attr "type" "compare")])
6704 (define_insn "*cmp_cc_set_neg"
6705 [(set (reg:CC_NOOV 100)
6706 (compare:CC_NOOV (neg:SI (match_operand:SI 1 "arith_operand" "rI"))
6708 (set (match_operand:SI 0 "register_operand" "=r")
6709 (neg:SI (match_dup 1)))]
6711 "subcc\\t%%g0, %1, %0"
6712 [(set_attr "type" "compare")])
6714 (define_insn "*cmp_ccx_set_neg"
6715 [(set (reg:CCX_NOOV 100)
6716 (compare:CCX_NOOV (neg:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
6718 (set (match_operand:DI 0 "register_operand" "=r")
6719 (neg:DI (match_dup 1)))]
6721 "subcc\\t%%g0, %1, %0"
6722 [(set_attr "type" "compare")])
6724 ;; We cannot use the "not" pseudo insn because the Sun assembler
6725 ;; does not know how to make it work for constants.
6726 (define_expand "one_cmpldi2"
6727 [(set (match_operand:DI 0 "register_operand" "")
6728 (not:DI (match_operand:DI 1 "register_operand" "")))]
6732 (define_insn "*one_cmpldi2_sp32"
6733 [(set (match_operand:DI 0 "register_operand" "=r,b")
6734 (not:DI (match_operand:DI 1 "register_operand" "r,b")))]
6739 [(set_attr "type" "*,fp")
6740 (set_attr "length" "2,*")
6741 (set_attr "fptype" "double")])
6744 [(set (match_operand:DI 0 "register_operand" "")
6745 (not:DI (match_operand:DI 1 "register_operand" "")))]
6748 && ((GET_CODE (operands[0]) == REG
6749 && REGNO (operands[0]) < 32)
6750 || (GET_CODE (operands[0]) == SUBREG
6751 && GET_CODE (SUBREG_REG (operands[0])) == REG
6752 && REGNO (SUBREG_REG (operands[0])) < 32))"
6753 [(set (match_dup 2) (not:SI (xor:SI (match_dup 3) (const_int 0))))
6754 (set (match_dup 4) (not:SI (xor:SI (match_dup 5) (const_int 0))))]
6755 "operands[2] = gen_highpart (SImode, operands[0]);
6756 operands[3] = gen_highpart (SImode, operands[1]);
6757 operands[4] = gen_lowpart (SImode, operands[0]);
6758 operands[5] = gen_lowpart (SImode, operands[1]);")
6760 (define_insn "*one_cmpldi2_sp64"
6761 [(set (match_operand:DI 0 "register_operand" "=r,b")
6762 (not:DI (match_operand:DI 1 "arith_double_operand" "rHI,b")))]
6767 [(set_attr "type" "*,fp")
6768 (set_attr "fptype" "double")])
6770 (define_insn "one_cmplsi2"
6771 [(set (match_operand:SI 0 "register_operand" "=r,d")
6772 (not:SI (match_operand:SI 1 "arith_operand" "rI,d")))]
6777 [(set_attr "type" "*,fp")])
6779 (define_insn "*cmp_cc_not"
6781 (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI"))
6784 "xnorcc\\t%%g0, %0, %%g0"
6785 [(set_attr "type" "compare")])
6787 (define_insn "*cmp_ccx_not"
6789 (compare:CCX (not:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
6792 "xnorcc\\t%%g0, %0, %%g0"
6793 [(set_attr "type" "compare")])
6795 (define_insn "*cmp_cc_set_not"
6797 (compare:CC (not:SI (match_operand:SI 1 "arith_operand" "rI"))
6799 (set (match_operand:SI 0 "register_operand" "=r")
6800 (not:SI (match_dup 1)))]
6802 "xnorcc\\t%%g0, %1, %0"
6803 [(set_attr "type" "compare")])
6805 (define_insn "*cmp_ccx_set_not"
6807 (compare:CCX (not:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
6809 (set (match_operand:DI 0 "register_operand" "=r")
6810 (not:DI (match_dup 1)))]
6812 "xnorcc\\t%%g0, %1, %0"
6813 [(set_attr "type" "compare")])
6815 (define_insn "*cmp_cc_set"
6816 [(set (match_operand:SI 0 "register_operand" "=r")
6817 (match_operand:SI 1 "register_operand" "r"))
6819 (compare:CC (match_dup 1)
6823 [(set_attr "type" "compare")])
6825 (define_insn "*cmp_ccx_set64"
6826 [(set (match_operand:DI 0 "register_operand" "=r")
6827 (match_operand:DI 1 "register_operand" "r"))
6829 (compare:CCX (match_dup 1)
6833 [(set_attr "type" "compare")])
6835 ;; Floating point arithmetic instructions.
6837 (define_expand "addtf3"
6838 [(set (match_operand:TF 0 "nonimmediate_operand" "")
6839 (plus:TF (match_operand:TF 1 "general_operand" "")
6840 (match_operand:TF 2 "general_operand" "")))]
6841 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6842 "emit_tfmode_binop (PLUS, operands); DONE;")
6844 (define_insn "*addtf3_hq"
6845 [(set (match_operand:TF 0 "register_operand" "=e")
6846 (plus:TF (match_operand:TF 1 "register_operand" "e")
6847 (match_operand:TF 2 "register_operand" "e")))]
6848 "TARGET_FPU && TARGET_HARD_QUAD"
6849 "faddq\\t%1, %2, %0"
6850 [(set_attr "type" "fp")])
6852 (define_insn "adddf3"
6853 [(set (match_operand:DF 0 "register_operand" "=e")
6854 (plus:DF (match_operand:DF 1 "register_operand" "e")
6855 (match_operand:DF 2 "register_operand" "e")))]
6857 "faddd\\t%1, %2, %0"
6858 [(set_attr "type" "fp")
6859 (set_attr "fptype" "double")])
6861 (define_insn "addsf3"
6862 [(set (match_operand:SF 0 "register_operand" "=f")
6863 (plus:SF (match_operand:SF 1 "register_operand" "f")
6864 (match_operand:SF 2 "register_operand" "f")))]
6866 "fadds\\t%1, %2, %0"
6867 [(set_attr "type" "fp")])
6869 (define_expand "subtf3"
6870 [(set (match_operand:TF 0 "nonimmediate_operand" "")
6871 (minus:TF (match_operand:TF 1 "general_operand" "")
6872 (match_operand:TF 2 "general_operand" "")))]
6873 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6874 "emit_tfmode_binop (MINUS, operands); DONE;")
6876 (define_insn "*subtf3_hq"
6877 [(set (match_operand:TF 0 "register_operand" "=e")
6878 (minus:TF (match_operand:TF 1 "register_operand" "e")
6879 (match_operand:TF 2 "register_operand" "e")))]
6880 "TARGET_FPU && TARGET_HARD_QUAD"
6881 "fsubq\\t%1, %2, %0"
6882 [(set_attr "type" "fp")])
6884 (define_insn "subdf3"
6885 [(set (match_operand:DF 0 "register_operand" "=e")
6886 (minus:DF (match_operand:DF 1 "register_operand" "e")
6887 (match_operand:DF 2 "register_operand" "e")))]
6889 "fsubd\\t%1, %2, %0"
6890 [(set_attr "type" "fp")
6891 (set_attr "fptype" "double")])
6893 (define_insn "subsf3"
6894 [(set (match_operand:SF 0 "register_operand" "=f")
6895 (minus:SF (match_operand:SF 1 "register_operand" "f")
6896 (match_operand:SF 2 "register_operand" "f")))]
6898 "fsubs\\t%1, %2, %0"
6899 [(set_attr "type" "fp")])
6901 (define_expand "multf3"
6902 [(set (match_operand:TF 0 "nonimmediate_operand" "")
6903 (mult:TF (match_operand:TF 1 "general_operand" "")
6904 (match_operand:TF 2 "general_operand" "")))]
6905 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6906 "emit_tfmode_binop (MULT, operands); DONE;")
6908 (define_insn "*multf3_hq"
6909 [(set (match_operand:TF 0 "register_operand" "=e")
6910 (mult:TF (match_operand:TF 1 "register_operand" "e")
6911 (match_operand:TF 2 "register_operand" "e")))]
6912 "TARGET_FPU && TARGET_HARD_QUAD"
6913 "fmulq\\t%1, %2, %0"
6914 [(set_attr "type" "fpmul")])
6916 (define_insn "muldf3"
6917 [(set (match_operand:DF 0 "register_operand" "=e")
6918 (mult:DF (match_operand:DF 1 "register_operand" "e")
6919 (match_operand:DF 2 "register_operand" "e")))]
6921 "fmuld\\t%1, %2, %0"
6922 [(set_attr "type" "fpmul")
6923 (set_attr "fptype" "double")])
6925 (define_insn "mulsf3"
6926 [(set (match_operand:SF 0 "register_operand" "=f")
6927 (mult:SF (match_operand:SF 1 "register_operand" "f")
6928 (match_operand:SF 2 "register_operand" "f")))]
6930 "fmuls\\t%1, %2, %0"
6931 [(set_attr "type" "fpmul")])
6933 (define_insn "*muldf3_extend"
6934 [(set (match_operand:DF 0 "register_operand" "=e")
6935 (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "f"))
6936 (float_extend:DF (match_operand:SF 2 "register_operand" "f"))))]
6937 "(TARGET_V8 || TARGET_V9) && TARGET_FPU"
6938 "fsmuld\\t%1, %2, %0"
6939 [(set_attr "type" "fpmul")
6940 (set_attr "fptype" "double")])
6942 (define_insn "*multf3_extend"
6943 [(set (match_operand:TF 0 "register_operand" "=e")
6944 (mult:TF (float_extend:TF (match_operand:DF 1 "register_operand" "e"))
6945 (float_extend:TF (match_operand:DF 2 "register_operand" "e"))))]
6946 "(TARGET_V8 || TARGET_V9) && TARGET_FPU && TARGET_HARD_QUAD"
6947 "fdmulq\\t%1, %2, %0"
6948 [(set_attr "type" "fpmul")])
6950 (define_expand "divtf3"
6951 [(set (match_operand:TF 0 "nonimmediate_operand" "")
6952 (div:TF (match_operand:TF 1 "general_operand" "")
6953 (match_operand:TF 2 "general_operand" "")))]
6954 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6955 "emit_tfmode_binop (DIV, operands); DONE;")
6957 ;; don't have timing for quad-prec. divide.
6958 (define_insn "*divtf3_hq"
6959 [(set (match_operand:TF 0 "register_operand" "=e")
6960 (div:TF (match_operand:TF 1 "register_operand" "e")
6961 (match_operand:TF 2 "register_operand" "e")))]
6962 "TARGET_FPU && TARGET_HARD_QUAD"
6963 "fdivq\\t%1, %2, %0"
6964 [(set_attr "type" "fpdivd")])
6966 (define_insn "divdf3"
6967 [(set (match_operand:DF 0 "register_operand" "=e")
6968 (div:DF (match_operand:DF 1 "register_operand" "e")
6969 (match_operand:DF 2 "register_operand" "e")))]
6971 "fdivd\\t%1, %2, %0"
6972 [(set_attr "type" "fpdivd")
6973 (set_attr "fptype" "double")])
6975 (define_insn "divsf3"
6976 [(set (match_operand:SF 0 "register_operand" "=f")
6977 (div:SF (match_operand:SF 1 "register_operand" "f")
6978 (match_operand:SF 2 "register_operand" "f")))]
6980 "fdivs\\t%1, %2, %0"
6981 [(set_attr "type" "fpdivs")])
6983 (define_expand "negtf2"
6984 [(set (match_operand:TF 0 "register_operand" "=e,e")
6985 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
6989 (define_insn "*negtf2_notv9"
6990 [(set (match_operand:TF 0 "register_operand" "=e,e")
6991 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
6992 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
6998 [(set_attr "type" "fpmove,*")
6999 (set_attr "length" "*,2")])
7002 [(set (match_operand:TF 0 "register_operand" "")
7003 (neg:TF (match_operand:TF 1 "register_operand" "")))]
7007 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7008 [(set (match_dup 2) (neg:SF (match_dup 3)))
7009 (set (match_dup 4) (match_dup 5))
7010 (set (match_dup 6) (match_dup 7))]
7011 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
7012 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
7013 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
7014 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
7015 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
7016 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);")
7018 (define_insn "*negtf2_v9"
7019 [(set (match_operand:TF 0 "register_operand" "=e,e")
7020 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
7021 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
7022 "TARGET_FPU && TARGET_V9"
7026 [(set_attr "type" "fpmove,*")
7027 (set_attr "length" "*,2")
7028 (set_attr "fptype" "double")])
7031 [(set (match_operand:TF 0 "register_operand" "")
7032 (neg:TF (match_operand:TF 1 "register_operand" "")))]
7036 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7037 [(set (match_dup 2) (neg:DF (match_dup 3)))
7038 (set (match_dup 4) (match_dup 5))]
7039 "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
7040 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
7041 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
7042 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);")
7044 (define_expand "negdf2"
7045 [(set (match_operand:DF 0 "register_operand" "")
7046 (neg:DF (match_operand:DF 1 "register_operand" "")))]
7050 (define_insn "*negdf2_notv9"
7051 [(set (match_operand:DF 0 "register_operand" "=e,e")
7052 (neg:DF (match_operand:DF 1 "register_operand" "0,e")))]
7053 "TARGET_FPU && ! TARGET_V9"
7057 [(set_attr "type" "fpmove,*")
7058 (set_attr "length" "*,2")])
7061 [(set (match_operand:DF 0 "register_operand" "")
7062 (neg:DF (match_operand:DF 1 "register_operand" "")))]
7066 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7067 [(set (match_dup 2) (neg:SF (match_dup 3)))
7068 (set (match_dup 4) (match_dup 5))]
7069 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
7070 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
7071 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
7072 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);")
7074 (define_insn "*negdf2_v9"
7075 [(set (match_operand:DF 0 "register_operand" "=e")
7076 (neg:DF (match_operand:DF 1 "register_operand" "e")))]
7077 "TARGET_FPU && TARGET_V9"
7079 [(set_attr "type" "fpmove")
7080 (set_attr "fptype" "double")])
7082 (define_insn "negsf2"
7083 [(set (match_operand:SF 0 "register_operand" "=f")
7084 (neg:SF (match_operand:SF 1 "register_operand" "f")))]
7087 [(set_attr "type" "fpmove")])
7089 (define_expand "abstf2"
7090 [(set (match_operand:TF 0 "register_operand" "")
7091 (abs:TF (match_operand:TF 1 "register_operand" "")))]
7095 (define_insn "*abstf2_notv9"
7096 [(set (match_operand:TF 0 "register_operand" "=e,e")
7097 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
7098 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
7099 "TARGET_FPU && ! TARGET_V9"
7103 [(set_attr "type" "fpmove,*")
7104 (set_attr "length" "*,2")])
7107 [(set (match_operand:TF 0 "register_operand" "")
7108 (abs:TF (match_operand:TF 1 "register_operand" "")))]
7112 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7113 [(set (match_dup 2) (abs:SF (match_dup 3)))
7114 (set (match_dup 4) (match_dup 5))
7115 (set (match_dup 6) (match_dup 7))]
7116 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
7117 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
7118 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
7119 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
7120 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
7121 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);")
7123 (define_insn "*abstf2_hq_v9"
7124 [(set (match_operand:TF 0 "register_operand" "=e,e")
7125 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
7126 "TARGET_FPU && TARGET_V9 && TARGET_HARD_QUAD"
7130 [(set_attr "type" "fpmove")
7131 (set_attr "fptype" "double,*")])
7133 (define_insn "*abstf2_v9"
7134 [(set (match_operand:TF 0 "register_operand" "=e,e")
7135 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
7136 "TARGET_FPU && TARGET_V9 && !TARGET_HARD_QUAD"
7140 [(set_attr "type" "fpmove,*")
7141 (set_attr "length" "*,2")
7142 (set_attr "fptype" "double,*")])
7145 [(set (match_operand:TF 0 "register_operand" "")
7146 (abs:TF (match_operand:TF 1 "register_operand" "")))]
7150 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7151 [(set (match_dup 2) (abs:DF (match_dup 3)))
7152 (set (match_dup 4) (match_dup 5))]
7153 "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
7154 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
7155 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
7156 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);")
7158 (define_expand "absdf2"
7159 [(set (match_operand:DF 0 "register_operand" "")
7160 (abs:DF (match_operand:DF 1 "register_operand" "")))]
7164 (define_insn "*absdf2_notv9"
7165 [(set (match_operand:DF 0 "register_operand" "=e,e")
7166 (abs:DF (match_operand:DF 1 "register_operand" "0,e")))]
7167 "TARGET_FPU && ! TARGET_V9"
7171 [(set_attr "type" "fpmove,*")
7172 (set_attr "length" "*,2")])
7175 [(set (match_operand:DF 0 "register_operand" "")
7176 (abs:DF (match_operand:DF 1 "register_operand" "")))]
7180 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7181 [(set (match_dup 2) (abs:SF (match_dup 3)))
7182 (set (match_dup 4) (match_dup 5))]
7183 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
7184 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
7185 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
7186 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);")
7188 (define_insn "*absdf2_v9"
7189 [(set (match_operand:DF 0 "register_operand" "=e")
7190 (abs:DF (match_operand:DF 1 "register_operand" "e")))]
7191 "TARGET_FPU && TARGET_V9"
7193 [(set_attr "type" "fpmove")
7194 (set_attr "fptype" "double")])
7196 (define_insn "abssf2"
7197 [(set (match_operand:SF 0 "register_operand" "=f")
7198 (abs:SF (match_operand:SF 1 "register_operand" "f")))]
7201 [(set_attr "type" "fpmove")])
7203 (define_expand "sqrttf2"
7204 [(set (match_operand:TF 0 "nonimmediate_operand" "")
7205 (sqrt:TF (match_operand:TF 1 "general_operand" "")))]
7206 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
7207 "emit_tfmode_unop (SQRT, operands); DONE;")
7209 (define_insn "*sqrttf2_hq"
7210 [(set (match_operand:TF 0 "register_operand" "=e")
7211 (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
7212 "TARGET_FPU && TARGET_HARD_QUAD"
7214 [(set_attr "type" "fpsqrtd")])
7216 (define_insn "sqrtdf2"
7217 [(set (match_operand:DF 0 "register_operand" "=e")
7218 (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
7221 [(set_attr "type" "fpsqrtd")
7222 (set_attr "fptype" "double")])
7224 (define_insn "sqrtsf2"
7225 [(set (match_operand:SF 0 "register_operand" "=f")
7226 (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
7229 [(set_attr "type" "fpsqrts")])
7231 ;;- arithmetic shift instructions
7233 (define_insn "ashlsi3"
7234 [(set (match_operand:SI 0 "register_operand" "=r")
7235 (ashift:SI (match_operand:SI 1 "register_operand" "r")
7236 (match_operand:SI 2 "arith_operand" "rI")))]
7240 if (operands[2] == const1_rtx)
7241 return \"add\\t%1, %1, %0\";
7242 return \"sll\\t%1, %2, %0\";
7245 (if_then_else (match_operand 2 "const1_operand" "")
7246 (const_string "ialu") (const_string "shift")))])
7248 (define_expand "ashldi3"
7249 [(set (match_operand:DI 0 "register_operand" "=r")
7250 (ashift:DI (match_operand:DI 1 "register_operand" "r")
7251 (match_operand:SI 2 "arith_operand" "rI")))]
7252 "TARGET_ARCH64 || TARGET_V8PLUS"
7255 if (! TARGET_ARCH64)
7257 if (GET_CODE (operands[2]) == CONST_INT)
7259 emit_insn (gen_ashldi3_v8plus (operands[0], operands[1], operands[2]));
7264 (define_insn "*ashldi3_sp64"
7265 [(set (match_operand:DI 0 "register_operand" "=r")
7266 (ashift:DI (match_operand:DI 1 "register_operand" "r")
7267 (match_operand:SI 2 "arith_operand" "rI")))]
7271 if (operands[2] == const1_rtx)
7272 return \"add\\t%1, %1, %0\";
7273 return \"sllx\\t%1, %2, %0\";
7276 (if_then_else (match_operand 2 "const1_operand" "")
7277 (const_string "ialu") (const_string "shift")))])
7280 (define_insn "ashldi3_v8plus"
7281 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
7282 (ashift:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
7283 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
7284 (clobber (match_scratch:SI 3 "=X,X,&h"))]
7286 "*return sparc_v8plus_shift (operands, insn, \"sllx\");"
7287 [(set_attr "type" "multi")
7288 (set_attr "length" "5,5,6")])
7290 ;; Optimize (1LL<<x)-1
7291 ;; XXX this also needs to be fixed to handle equal subregs
7292 ;; XXX first before we could re-enable it.
7294 ; [(set (match_operand:DI 0 "register_operand" "=h")
7295 ; (plus:DI (ashift:DI (const_int 1)
7296 ; (match_operand:SI 1 "arith_operand" "rI"))
7298 ; "0 && TARGET_V8PLUS"
7301 ; if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == REGNO (operands[0]))
7302 ; return \"mov\\t1, %L0\;sllx\\t%L0, %1, %L0\;sub\\t%L0, 1, %L0\;srlx\\t%L0, 32, %H0\";
7303 ; return \"mov\\t1, %H0\;sllx\\t%H0, %1, %L0\;sub\\t%L0, 1, %L0\;srlx\\t%L0, 32, %H0\";
7305 ; [(set_attr "type" "multi")
7306 ; (set_attr "length" "4")])
7308 (define_insn "*cmp_cc_ashift_1"
7309 [(set (reg:CC_NOOV 100)
7310 (compare:CC_NOOV (ashift:SI (match_operand:SI 0 "register_operand" "r")
7314 "addcc\\t%0, %0, %%g0"
7315 [(set_attr "type" "compare")])
7317 (define_insn "*cmp_cc_set_ashift_1"
7318 [(set (reg:CC_NOOV 100)
7319 (compare:CC_NOOV (ashift:SI (match_operand:SI 1 "register_operand" "r")
7322 (set (match_operand:SI 0 "register_operand" "=r")
7323 (ashift:SI (match_dup 1) (const_int 1)))]
7325 "addcc\\t%1, %1, %0"
7326 [(set_attr "type" "compare")])
7328 (define_insn "ashrsi3"
7329 [(set (match_operand:SI 0 "register_operand" "=r")
7330 (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
7331 (match_operand:SI 2 "arith_operand" "rI")))]
7335 return \"sra\\t%1, %2, %0\";
7337 [(set_attr "type" "shift")])
7339 (define_insn "*ashrsi3_extend"
7340 [(set (match_operand:DI 0 "register_operand" "=r")
7341 (sign_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
7342 (match_operand:SI 2 "arith_operand" "r"))))]
7345 [(set_attr "type" "shift")])
7347 ;; This handles the case as above, but with constant shift instead of
7348 ;; register. Combiner "simplifies" it for us a little bit though.
7349 (define_insn "*ashrsi3_extend2"
7350 [(set (match_operand:DI 0 "register_operand" "=r")
7351 (ashiftrt:DI (ashift:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
7353 (match_operand:SI 2 "small_int_or_double" "n")))]
7355 && ((GET_CODE (operands[2]) == CONST_INT
7356 && INTVAL (operands[2]) >= 32 && INTVAL (operands[2]) < 64)
7357 || (GET_CODE (operands[2]) == CONST_DOUBLE
7358 && !CONST_DOUBLE_HIGH (operands[2])
7359 && CONST_DOUBLE_LOW (operands[2]) >= 32
7360 && CONST_DOUBLE_LOW (operands[2]) < 64))"
7363 operands[2] = GEN_INT (INTVAL (operands[2]) - 32);
7365 return \"sra\\t%1, %2, %0\";
7367 [(set_attr "type" "shift")])
7369 (define_expand "ashrdi3"
7370 [(set (match_operand:DI 0 "register_operand" "=r")
7371 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
7372 (match_operand:SI 2 "arith_operand" "rI")))]
7373 "TARGET_ARCH64 || TARGET_V8PLUS"
7376 if (! TARGET_ARCH64)
7378 if (GET_CODE (operands[2]) == CONST_INT)
7379 FAIL; /* prefer generic code in this case */
7380 emit_insn (gen_ashrdi3_v8plus (operands[0], operands[1], operands[2]));
7386 [(set (match_operand:DI 0 "register_operand" "=r")
7387 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
7388 (match_operand:SI 2 "arith_operand" "rI")))]
7392 return \"srax\\t%1, %2, %0\";
7394 [(set_attr "type" "shift")])
7397 (define_insn "ashrdi3_v8plus"
7398 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
7399 (ashiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
7400 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
7401 (clobber (match_scratch:SI 3 "=X,X,&h"))]
7403 "*return sparc_v8plus_shift (operands, insn, \"srax\");"
7404 [(set_attr "type" "multi")
7405 (set_attr "length" "5,5,6")])
7407 (define_insn "lshrsi3"
7408 [(set (match_operand:SI 0 "register_operand" "=r")
7409 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
7410 (match_operand:SI 2 "arith_operand" "rI")))]
7414 return \"srl\\t%1, %2, %0\";
7416 [(set_attr "type" "shift")])
7418 ;; This handles the case where
7419 ;; (zero_extend:DI (lshiftrt:SI (match_operand:SI) (match_operand:SI))),
7420 ;; but combiner "simplifies" it for us.
7421 (define_insn "*lshrsi3_extend"
7422 [(set (match_operand:DI 0 "register_operand" "=r")
7423 (and:DI (subreg:DI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
7424 (match_operand:SI 2 "arith_operand" "r")) 0)
7425 (match_operand 3 "" "")))]
7427 && ((GET_CODE (operands[3]) == CONST_DOUBLE
7428 && CONST_DOUBLE_HIGH (operands[3]) == 0
7429 && CONST_DOUBLE_LOW (operands[3]) == 0xffffffff)
7430 || (HOST_BITS_PER_WIDE_INT >= 64
7431 && GET_CODE (operands[3]) == CONST_INT
7432 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) == 0xffffffff))"
7434 [(set_attr "type" "shift")])
7436 ;; This handles the case where
7437 ;; (lshiftrt:DI (zero_extend:DI (match_operand:SI)) (const_int >=0 < 32))
7438 ;; but combiner "simplifies" it for us.
7439 (define_insn "*lshrsi3_extend2"
7440 [(set (match_operand:DI 0 "register_operand" "=r")
7441 (zero_extract:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
7442 (match_operand 2 "small_int_or_double" "n")
7445 && ((GET_CODE (operands[2]) == CONST_INT
7446 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
7447 || (GET_CODE (operands[2]) == CONST_DOUBLE
7448 && CONST_DOUBLE_HIGH (operands[2]) == 0
7449 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
7452 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
7454 return \"srl\\t%1, %2, %0\";
7456 [(set_attr "type" "shift")])
7458 (define_expand "lshrdi3"
7459 [(set (match_operand:DI 0 "register_operand" "=r")
7460 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
7461 (match_operand:SI 2 "arith_operand" "rI")))]
7462 "TARGET_ARCH64 || TARGET_V8PLUS"
7465 if (! TARGET_ARCH64)
7467 if (GET_CODE (operands[2]) == CONST_INT)
7469 emit_insn (gen_lshrdi3_v8plus (operands[0], operands[1], operands[2]));
7475 [(set (match_operand:DI 0 "register_operand" "=r")
7476 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
7477 (match_operand:SI 2 "arith_operand" "rI")))]
7481 return \"srlx\\t%1, %2, %0\";
7483 [(set_attr "type" "shift")])
7486 (define_insn "lshrdi3_v8plus"
7487 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
7488 (lshiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
7489 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
7490 (clobber (match_scratch:SI 3 "=X,X,&h"))]
7492 "*return sparc_v8plus_shift (operands, insn, \"srlx\");"
7493 [(set_attr "type" "multi")
7494 (set_attr "length" "5,5,6")])
7497 [(set (match_operand:SI 0 "register_operand" "=r")
7498 (ashiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
7500 (match_operand:SI 2 "small_int_or_double" "n")))]
7502 && ((GET_CODE (operands[2]) == CONST_INT
7503 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
7504 || (GET_CODE (operands[2]) == CONST_DOUBLE
7505 && !CONST_DOUBLE_HIGH (operands[2])
7506 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
7509 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
7511 return \"srax\\t%1, %2, %0\";
7513 [(set_attr "type" "shift")])
7516 [(set (match_operand:SI 0 "register_operand" "=r")
7517 (lshiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
7519 (match_operand:SI 2 "small_int_or_double" "n")))]
7521 && ((GET_CODE (operands[2]) == CONST_INT
7522 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
7523 || (GET_CODE (operands[2]) == CONST_DOUBLE
7524 && !CONST_DOUBLE_HIGH (operands[2])
7525 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
7528 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
7530 return \"srlx\\t%1, %2, %0\";
7532 [(set_attr "type" "shift")])
7535 [(set (match_operand:SI 0 "register_operand" "=r")
7536 (ashiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
7537 (match_operand:SI 2 "small_int_or_double" "n")) 4)
7538 (match_operand:SI 3 "small_int_or_double" "n")))]
7540 && GET_CODE (operands[2]) == CONST_INT && GET_CODE (operands[3]) == CONST_INT
7541 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
7542 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
7543 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
7546 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
7548 return \"srax\\t%1, %2, %0\";
7550 [(set_attr "type" "shift")])
7553 [(set (match_operand:SI 0 "register_operand" "=r")
7554 (lshiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
7555 (match_operand:SI 2 "small_int_or_double" "n")) 4)
7556 (match_operand:SI 3 "small_int_or_double" "n")))]
7558 && GET_CODE (operands[2]) == CONST_INT && GET_CODE (operands[3]) == CONST_INT
7559 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
7560 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
7561 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
7564 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
7566 return \"srlx\\t%1, %2, %0\";
7568 [(set_attr "type" "shift")])
7570 ;; Unconditional and other jump instructions
7571 ;; On the Sparc, by setting the annul bit on an unconditional branch, the
7572 ;; following insn is never executed. This saves us a nop. Dbx does not
7573 ;; handle such branches though, so we only use them when optimizing.
7575 [(set (pc) (label_ref (match_operand 0 "" "")))]
7579 /* TurboSparc is reported to have problems with
7582 i.e. an empty loop with the annul bit set. The workaround is to use
7586 if (! TARGET_V9 && flag_delayed_branch
7587 && (INSN_ADDRESSES (INSN_UID (operands[0]))
7588 == INSN_ADDRESSES (INSN_UID (insn))))
7589 return \"b\\t%l0%#\";
7591 return TARGET_V9 ? \"ba,pt%*\\t%%xcc, %l0%(\" : \"b%*\\t%l0%(\";
7593 [(set_attr "type" "uncond_branch")])
7595 (define_expand "tablejump"
7596 [(parallel [(set (pc) (match_operand 0 "register_operand" "r"))
7597 (use (label_ref (match_operand 1 "" "")))])]
7601 if (GET_MODE (operands[0]) != CASE_VECTOR_MODE)
7604 /* In pic mode, our address differences are against the base of the
7605 table. Add that base value back in; CSE ought to be able to combine
7606 the two address loads. */
7610 tmp = gen_rtx_LABEL_REF (Pmode, operands[1]);
7612 if (CASE_VECTOR_MODE != Pmode)
7613 tmp2 = gen_rtx_SIGN_EXTEND (Pmode, tmp2);
7614 tmp = gen_rtx_PLUS (Pmode, tmp2, tmp);
7615 operands[0] = memory_address (Pmode, tmp);
7619 (define_insn "*tablejump_sp32"
7620 [(set (pc) (match_operand:SI 0 "address_operand" "p"))
7621 (use (label_ref (match_operand 1 "" "")))]
7624 [(set_attr "type" "uncond_branch")])
7626 (define_insn "*tablejump_sp64"
7627 [(set (pc) (match_operand:DI 0 "address_operand" "p"))
7628 (use (label_ref (match_operand 1 "" "")))]
7631 [(set_attr "type" "uncond_branch")])
7633 ;; This pattern recognizes the "instruction" that appears in
7634 ;; a function call that wants a structure value,
7635 ;; to inform the called function if compiled with Sun CC.
7636 ;(define_insn "*unimp_insn"
7637 ; [(match_operand:SI 0 "immediate_operand" "")]
7638 ; "GET_CODE (operands[0]) == CONST_INT && INTVAL (operands[0]) > 0"
7640 ; [(set_attr "type" "marker")])
7642 ;;- jump to subroutine
7643 (define_expand "call"
7644 ;; Note that this expression is not used for generating RTL.
7645 ;; All the RTL is generated explicitly below.
7646 [(call (match_operand 0 "call_operand" "")
7647 (match_operand 3 "" "i"))]
7648 ;; operands[2] is next_arg_register
7649 ;; operands[3] is struct_value_size_rtx.
7653 rtx fn_rtx, nregs_rtx;
7655 if (GET_MODE (operands[0]) != FUNCTION_MODE)
7658 if (GET_CODE (XEXP (operands[0], 0)) == LABEL_REF)
7660 /* This is really a PIC sequence. We want to represent
7661 it as a funny jump so its delay slots can be filled.
7663 ??? But if this really *is* a CALL, will not it clobber the
7664 call-clobbered registers? We lose this if it is a JUMP_INSN.
7665 Why cannot we have delay slots filled if it were a CALL? */
7667 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
7672 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
7674 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
7680 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
7681 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
7685 fn_rtx = operands[0];
7687 /* Count the number of parameter registers being used by this call.
7688 if that argument is NULL, it means we are using them all, which
7689 means 6 on the sparc. */
7692 nregs_rtx = GEN_INT (REGNO (operands[2]) - 8);
7694 nregs_rtx = GEN_INT (6);
7696 nregs_rtx = const0_rtx;
7699 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
7703 gen_rtvec (3, gen_rtx_CALL (VOIDmode, fn_rtx, nregs_rtx),
7705 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
7710 gen_rtvec (2, gen_rtx_CALL (VOIDmode, fn_rtx, nregs_rtx),
7711 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
7715 /* If this call wants a structure value,
7716 emit an unimp insn to let the called function know about this. */
7717 if (! TARGET_ARCH64 && INTVAL (operands[3]) > 0)
7719 rtx insn = emit_insn (operands[3]);
7720 SCHED_GROUP_P (insn) = 1;
7727 ;; We can't use the same pattern for these two insns, because then registers
7728 ;; in the address may not be properly reloaded.
7730 (define_insn "*call_address_sp32"
7731 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
7732 (match_operand 1 "" ""))
7733 (clobber (reg:SI 15))]
7734 ;;- Do not use operand 1 for most machines.
7737 [(set_attr "type" "call")])
7739 (define_insn "*call_symbolic_sp32"
7740 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
7741 (match_operand 1 "" ""))
7742 (clobber (reg:SI 15))]
7743 ;;- Do not use operand 1 for most machines.
7746 [(set_attr "type" "call")])
7748 (define_insn "*call_address_sp64"
7749 [(call (mem:DI (match_operand:DI 0 "address_operand" "p"))
7750 (match_operand 1 "" ""))
7751 (clobber (reg:DI 15))]
7752 ;;- Do not use operand 1 for most machines.
7755 [(set_attr "type" "call")])
7757 (define_insn "*call_symbolic_sp64"
7758 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
7759 (match_operand 1 "" ""))
7760 (clobber (reg:DI 15))]
7761 ;;- Do not use operand 1 for most machines.
7764 [(set_attr "type" "call")])
7766 ;; This is a call that wants a structure value.
7767 ;; There is no such critter for v9 (??? we may need one anyway).
7768 (define_insn "*call_address_struct_value_sp32"
7769 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
7770 (match_operand 1 "" ""))
7771 (match_operand 2 "immediate_operand" "")
7772 (clobber (reg:SI 15))]
7773 ;;- Do not use operand 1 for most machines.
7774 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 0"
7775 "call\\t%a0, %1\\n\\tnop\\n\\tunimp\\t%2"
7776 [(set_attr "type" "call_no_delay_slot")
7777 (set_attr "length" "3")])
7779 ;; This is a call that wants a structure value.
7780 ;; There is no such critter for v9 (??? we may need one anyway).
7781 (define_insn "*call_symbolic_struct_value_sp32"
7782 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
7783 (match_operand 1 "" ""))
7784 (match_operand 2 "immediate_operand" "")
7785 (clobber (reg:SI 15))]
7786 ;;- Do not use operand 1 for most machines.
7787 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 0"
7788 "call\\t%a0, %1\\n\\tnop\\n\\tunimp\\t%2"
7789 [(set_attr "type" "call_no_delay_slot")
7790 (set_attr "length" "3")])
7792 ;; This is a call that may want a structure value. This is used for
7794 (define_insn "*call_address_untyped_struct_value_sp32"
7795 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
7796 (match_operand 1 "" ""))
7797 (match_operand 2 "immediate_operand" "")
7798 (clobber (reg:SI 15))]
7799 ;;- Do not use operand 1 for most machines.
7800 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
7801 "call\\t%a0, %1\\n\\tnop\\n\\tnop"
7802 [(set_attr "type" "call_no_delay_slot")
7803 (set_attr "length" "3")])
7805 ;; This is a call that wants a structure value.
7806 (define_insn "*call_symbolic_untyped_struct_value_sp32"
7807 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
7808 (match_operand 1 "" ""))
7809 (match_operand 2 "immediate_operand" "")
7810 (clobber (reg:SI 15))]
7811 ;;- Do not use operand 1 for most machines.
7812 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
7813 "call\\t%a0, %1\\n\\tnop\\n\\tnop"
7814 [(set_attr "type" "call_no_delay_slot")
7815 (set_attr "length" "3")])
7817 (define_expand "call_value"
7818 ;; Note that this expression is not used for generating RTL.
7819 ;; All the RTL is generated explicitly below.
7820 [(set (match_operand 0 "register_operand" "=rf")
7821 (call (match_operand 1 "" "")
7822 (match_operand 4 "" "")))]
7823 ;; operand 2 is stack_size_rtx
7824 ;; operand 3 is next_arg_register
7828 rtx fn_rtx, nregs_rtx;
7831 if (GET_MODE (operands[1]) != FUNCTION_MODE)
7834 fn_rtx = operands[1];
7838 nregs_rtx = GEN_INT (REGNO (operands[3]) - 8);
7840 nregs_rtx = GEN_INT (6);
7842 nregs_rtx = const0_rtx;
7846 gen_rtx_SET (VOIDmode, operands[0],
7847 gen_rtx_CALL (VOIDmode, fn_rtx, nregs_rtx)),
7848 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)));
7850 emit_call_insn (gen_rtx_PARALLEL (VOIDmode, vec));
7855 (define_insn "*call_value_address_sp32"
7856 [(set (match_operand 0 "" "=rf")
7857 (call (mem:SI (match_operand:SI 1 "address_operand" "p"))
7858 (match_operand 2 "" "")))
7859 (clobber (reg:SI 15))]
7860 ;;- Do not use operand 2 for most machines.
7863 [(set_attr "type" "call")])
7865 (define_insn "*call_value_symbolic_sp32"
7866 [(set (match_operand 0 "" "=rf")
7867 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
7868 (match_operand 2 "" "")))
7869 (clobber (reg:SI 15))]
7870 ;;- Do not use operand 2 for most machines.
7873 [(set_attr "type" "call")])
7875 (define_insn "*call_value_address_sp64"
7876 [(set (match_operand 0 "" "")
7877 (call (mem:DI (match_operand:DI 1 "address_operand" "p"))
7878 (match_operand 2 "" "")))
7879 (clobber (reg:DI 15))]
7880 ;;- Do not use operand 2 for most machines.
7883 [(set_attr "type" "call")])
7885 (define_insn "*call_value_symbolic_sp64"
7886 [(set (match_operand 0 "" "")
7887 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
7888 (match_operand 2 "" "")))
7889 (clobber (reg:DI 15))]
7890 ;;- Do not use operand 2 for most machines.
7893 [(set_attr "type" "call")])
7895 (define_expand "untyped_call"
7896 [(parallel [(call (match_operand 0 "" "")
7898 (match_operand 1 "" "")
7899 (match_operand 2 "" "")])]
7905 /* Pass constm1 to indicate that it may expect a structure value, but
7906 we don't know what size it is. */
7907 emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, constm1_rtx));
7909 for (i = 0; i < XVECLEN (operands[2], 0); i++)
7911 rtx set = XVECEXP (operands[2], 0, i);
7912 emit_move_insn (SET_DEST (set), SET_SRC (set));
7915 /* The optimizer does not know that the call sets the function value
7916 registers we stored in the result block. We avoid problems by
7917 claiming that all hard registers are used and clobbered at this
7919 emit_insn (gen_blockage ());
7925 (define_expand "sibcall"
7926 [(parallel [(call (match_operand 0 "call_operand" "") (const_int 0))
7931 (define_insn "*sibcall_symbolic_sp32"
7932 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
7933 (match_operand 1 "" ""))
7936 "* return output_sibcall(insn, operands[0]);"
7937 [(set_attr "type" "sibcall")])
7939 (define_insn "*sibcall_symbolic_sp64"
7940 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
7941 (match_operand 1 "" ""))
7944 "* return output_sibcall(insn, operands[0]);"
7945 [(set_attr "type" "sibcall")])
7947 (define_expand "sibcall_value"
7948 [(parallel [(set (match_operand 0 "register_operand" "=rf")
7949 (call (match_operand 1 "" "") (const_int 0)))
7954 (define_insn "*sibcall_value_symbolic_sp32"
7955 [(set (match_operand 0 "" "=rf")
7956 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
7957 (match_operand 2 "" "")))
7960 "* return output_sibcall(insn, operands[1]);"
7961 [(set_attr "type" "sibcall")])
7963 (define_insn "*sibcall_value_symbolic_sp64"
7964 [(set (match_operand 0 "" "")
7965 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
7966 (match_operand 2 "" "")))
7969 "* return output_sibcall(insn, operands[1]);"
7970 [(set_attr "type" "sibcall")])
7972 (define_expand "sibcall_epilogue"
7977 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
7978 ;; all of memory. This blocks insns from being moved across this point.
7980 (define_insn "blockage"
7981 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
7984 [(set_attr "length" "0")])
7986 ;; Prepare to return any type including a structure value.
7988 (define_expand "untyped_return"
7989 [(match_operand:BLK 0 "memory_operand" "")
7990 (match_operand 1 "" "")]
7994 rtx valreg1 = gen_rtx_REG (DImode, 24);
7995 rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
7996 rtx result = operands[0];
7998 if (! TARGET_ARCH64)
8000 rtx rtnreg = gen_rtx_REG (SImode, (current_function_uses_only_leaf_regs
8002 rtx value = gen_reg_rtx (SImode);
8004 /* Fetch the instruction where we will return to and see if it's an unimp
8005 instruction (the most significant 10 bits will be zero). If so,
8006 update the return address to skip the unimp instruction. */
8007 emit_move_insn (value,
8008 gen_rtx_MEM (SImode, plus_constant (rtnreg, 8)));
8009 emit_insn (gen_lshrsi3 (value, value, GEN_INT (22)));
8010 emit_insn (gen_update_return (rtnreg, value));
8013 /* Reload the function value registers. */
8014 emit_move_insn (valreg1, adjust_address (result, DImode, 0));
8015 emit_move_insn (valreg2,
8016 adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8));
8018 /* Put USE insns before the return. */
8019 emit_insn (gen_rtx_USE (VOIDmode, valreg1));
8020 emit_insn (gen_rtx_USE (VOIDmode, valreg2));
8022 /* Construct the return. */
8023 expand_null_return ();
8028 ;; This is a bit of a hack. We're incrementing a fixed register (%i7),
8029 ;; and parts of the compiler don't want to believe that the add is needed.
8031 (define_insn "update_return"
8032 [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
8033 (match_operand:SI 1 "register_operand" "r")] UNSPEC_UPDATE_RETURN)]
8035 "cmp\\t%1, 0\;be,a\\t.+8\;add\\t%0, 4, %0"
8036 [(set_attr "type" "multi")
8037 (set_attr "length" "3")])
8044 (define_expand "indirect_jump"
8045 [(set (pc) (match_operand 0 "address_operand" "p"))]
8049 (define_insn "*branch_sp32"
8050 [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
8053 [(set_attr "type" "uncond_branch")])
8055 (define_insn "*branch_sp64"
8056 [(set (pc) (match_operand:DI 0 "address_operand" "p"))]
8059 [(set_attr "type" "uncond_branch")])
8061 ;; ??? Doesn't work with -mflat.
8062 (define_expand "nonlocal_goto"
8063 [(match_operand:SI 0 "general_operand" "")
8064 (match_operand:SI 1 "general_operand" "")
8065 (match_operand:SI 2 "general_operand" "")
8066 (match_operand:SI 3 "" "")]
8071 rtx chain = operands[0];
8073 rtx lab = operands[1];
8074 rtx stack = operands[2];
8075 rtx fp = operands[3];
8078 /* Trap instruction to flush all the register windows. */
8079 emit_insn (gen_flush_register_windows ());
8081 /* Load the fp value for the containing fn into %fp. This is needed
8082 because STACK refers to %fp. Note that virtual register instantiation
8083 fails if the virtual %fp isn't set from a register. */
8084 if (GET_CODE (fp) != REG)
8085 fp = force_reg (Pmode, fp);
8086 emit_move_insn (virtual_stack_vars_rtx, fp);
8088 /* Find the containing function's current nonlocal goto handler,
8089 which will do any cleanups and then jump to the label. */
8090 labreg = gen_rtx_REG (Pmode, 8);
8091 emit_move_insn (labreg, lab);
8093 /* Restore %fp from stack pointer value for containing function.
8094 The restore insn that follows will move this to %sp,
8095 and reload the appropriate value into %fp. */
8096 emit_move_insn (hard_frame_pointer_rtx, stack);
8098 /* USE of frame_pointer_rtx added for consistency; not clear if
8100 /*emit_insn (gen_rtx_USE (VOIDmode, frame_pointer_rtx));*/
8101 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
8104 /* Return, restoring reg window and jumping to goto handler. */
8105 if (TARGET_V9 && GET_CODE (chain) == CONST_INT
8106 && ! (INTVAL (chain) & ~(HOST_WIDE_INT)0xffffffff))
8108 emit_jump_insn (gen_goto_handler_and_restore_v9 (labreg,
8114 /* Put in the static chain register the nonlocal label address. */
8115 emit_move_insn (static_chain_rtx, chain);
8118 emit_insn (gen_rtx_USE (VOIDmode, static_chain_rtx));
8119 emit_jump_insn (gen_goto_handler_and_restore (labreg));
8124 ;; Special trap insn to flush register windows.
8125 (define_insn "flush_register_windows"
8126 [(unspec_volatile [(const_int 0)] UNSPECV_FLUSHW)]
8128 "* return TARGET_V9 ? \"flushw\" : \"ta\\t3\";"
8129 [(set_attr "type" "misc")])
8131 (define_insn "goto_handler_and_restore"
8132 [(unspec_volatile [(match_operand 0 "register_operand" "=r")] UNSPECV_GOTO)]
8133 "GET_MODE (operands[0]) == Pmode"
8134 "jmp\\t%0+0\\n\\trestore"
8135 [(set_attr "type" "multi")
8136 (set_attr "length" "2")])
8138 ;;(define_insn "goto_handler_and_restore_v9"
8139 ;; [(unspec_volatile [(match_operand:SI 0 "register_operand" "=r,r")
8140 ;; (match_operand:SI 1 "register_operand" "=r,r")
8141 ;; (match_operand:SI 2 "const_int_operand" "I,n")] UNSPECV_GOTO_V9)]
8142 ;; "TARGET_V9 && ! TARGET_ARCH64"
8144 ;; return\\t%0+0\\n\\tmov\\t%2, %Y1
8145 ;; sethi\\t%%hi(%2), %1\\n\\treturn\\t%0+0\\n\\tor\\t%Y1, %%lo(%2), %Y1"
8146 ;; [(set_attr "type" "multi")
8147 ;; (set_attr "length" "2,3")])
8149 ;;(define_insn "*goto_handler_and_restore_v9_sp64"
8150 ;; [(unspec_volatile [(match_operand:DI 0 "register_operand" "=r,r")
8151 ;; (match_operand:DI 1 "register_operand" "=r,r")
8152 ;; (match_operand:SI 2 "const_int_operand" "I,n")] UNSPECV_GOTO_V9)]
8153 ;; "TARGET_V9 && TARGET_ARCH64"
8155 ;; return\\t%0+0\\n\\tmov\\t%2, %Y1
8156 ;; sethi\\t%%hi(%2), %1\\n\\treturn\\t%0+0\\n\\tor\\t%Y1, %%lo(%2), %Y1"
8157 ;; [(set_attr "type" "multi")
8158 ;; (set_attr "length" "2,3")])
8160 ;; For __builtin_setjmp we need to flush register windows iff the function
8161 ;; calls alloca as well, because otherwise the register window might be
8162 ;; saved after %sp adjustement and thus setjmp would crash
8163 (define_expand "builtin_setjmp_setup"
8164 [(match_operand 0 "register_operand" "r")]
8168 emit_insn (gen_do_builtin_setjmp_setup ());
8172 (define_insn "do_builtin_setjmp_setup"
8173 [(unspec_volatile [(const_int 0)] UNSPECV_SETJMP)]
8177 if (! current_function_calls_alloca || ! TARGET_V9 || TARGET_FLAT)
8179 fputs (\"\tflushw\n\", asm_out_file);
8181 fprintf (asm_out_file, \"\tst%c\t%%l7, [%%sp+%d]\n\",
8182 TARGET_ARCH64 ? 'x' : 'w',
8183 SPARC_STACK_BIAS + 7 * UNITS_PER_WORD);
8184 fprintf (asm_out_file, \"\tst%c\t%%fp, [%%sp+%d]\n\",
8185 TARGET_ARCH64 ? 'x' : 'w',
8186 SPARC_STACK_BIAS + 14 * UNITS_PER_WORD);
8187 fprintf (asm_out_file, \"\tst%c\t%%i7, [%%sp+%d]\n\",
8188 TARGET_ARCH64 ? 'x' : 'w',
8189 SPARC_STACK_BIAS + 15 * UNITS_PER_WORD);
8192 [(set_attr "type" "misc")
8193 (set (attr "length") (if_then_else (eq_attr "pic" "true")
8198 [(unspec_volatile [(const_int 0)] UNSPECV_SETJMP)]
8199 "! current_function_calls_alloca || ! TARGET_V9 || TARGET_FLAT"
8203 if (current_function_calls_alloca)
8204 emit_insn (gen_flush_register_windows ());
8208 ;; Pattern for use after a setjmp to store FP and the return register
8209 ;; into the stack area.
8211 (define_expand "setjmp"
8217 emit_insn (gen_setjmp_64 ());
8219 emit_insn (gen_setjmp_32 ());
8223 (define_expand "setjmp_32"
8224 [(set (mem:SI (plus:SI (reg:SI 14) (const_int 56))) (match_dup 0))
8225 (set (mem:SI (plus:SI (reg:SI 14) (const_int 60))) (reg:SI 31))]
8228 { operands[0] = frame_pointer_rtx; }")
8230 (define_expand "setjmp_64"
8231 [(set (mem:DI (plus:DI (reg:DI 14) (const_int 112))) (match_dup 0))
8232 (set (mem:DI (plus:DI (reg:DI 14) (const_int 120))) (reg:DI 31))]
8235 { operands[0] = frame_pointer_rtx; }")
8237 ;; Special pattern for the FLUSH instruction.
8239 ; We do SImode and DImode versions of this to quiet down genrecog's complaints
8240 ; of the define_insn otherwise missing a mode. We make "flush", aka
8241 ; gen_flush, the default one since sparc_initialize_trampoline uses
8242 ; it on SImode mem values.
8244 (define_insn "flush"
8245 [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")] UNSPECV_FLUSH)]
8247 "* return TARGET_V9 ? \"flush\\t%f0\" : \"iflush\\t%f0\";"
8248 [(set_attr "type" "misc")])
8250 (define_insn "flushdi"
8251 [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")] UNSPECV_FLUSH)]
8253 "* return TARGET_V9 ? \"flush\\t%f0\" : \"iflush\\t%f0\";"
8254 [(set_attr "type" "misc")])
8259 ;; The scan instruction searches from the most significant bit while ffs
8260 ;; searches from the least significant bit. The bit index and treatment of
8261 ;; zero also differ. It takes at least 7 instructions to get the proper
8262 ;; result. Here is an obvious 8 instruction sequence.
8265 (define_insn "ffssi2"
8266 [(set (match_operand:SI 0 "register_operand" "=&r")
8267 (ffs:SI (match_operand:SI 1 "register_operand" "r")))
8268 (clobber (match_scratch:SI 2 "=&r"))]
8269 "TARGET_SPARCLITE || TARGET_SPARCLET"
8272 return \"sub\\t%%g0, %1, %0\;and\\t%0, %1, %0\;scan\\t%0, 0, %0\;mov\\t32, %2\;sub\\t%2, %0, %0\;sra\\t%0, 31, %2\;and\\t%2, 31, %2\;add\\t%2, %0, %0\";
8274 [(set_attr "type" "multi")
8275 (set_attr "length" "8")])
8277 ;; ??? This should be a define expand, so that the extra instruction have
8278 ;; a chance of being optimized away.
8280 ;; Disabled because none of the UltraSparcs implement popc. The HAL R1
8281 ;; does, but no one uses that and we don't have a switch for it.
8283 ;(define_insn "ffsdi2"
8284 ; [(set (match_operand:DI 0 "register_operand" "=&r")
8285 ; (ffs:DI (match_operand:DI 1 "register_operand" "r")))
8286 ; (clobber (match_scratch:DI 2 "=&r"))]
8288 ; "neg\\t%1, %2\;xnor\\t%1, %2, %2\;popc\\t%2, %0\;movzr\\t%1, 0, %0"
8289 ; [(set_attr "type" "multi")
8290 ; (set_attr "length" "4")])
8294 ;; Peepholes go at the end.
8296 ;; Optimize consecutive loads or stores into ldd and std when possible.
8297 ;; The conditions in which we do this are very restricted and are
8298 ;; explained in the code for {registers,memory}_ok_for_ldd functions.
8301 [(set (match_operand:SI 0 "memory_operand" "")
8303 (set (match_operand:SI 1 "memory_operand" "")
8306 && mems_ok_for_ldd_peep (operands[0], operands[1], NULL_RTX)"
8309 "operands[0] = change_address (operands[0], DImode, NULL);")
8312 [(set (match_operand:SI 0 "memory_operand" "")
8314 (set (match_operand:SI 1 "memory_operand" "")
8317 && mems_ok_for_ldd_peep (operands[1], operands[0], NULL_RTX)"
8320 "operands[1] = change_address (operands[1], DImode, NULL);")
8323 [(set (match_operand:SI 0 "register_operand" "")
8324 (match_operand:SI 1 "memory_operand" ""))
8325 (set (match_operand:SI 2 "register_operand" "")
8326 (match_operand:SI 3 "memory_operand" ""))]
8327 "registers_ok_for_ldd_peep (operands[0], operands[2])
8328 && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
8331 "operands[1] = change_address (operands[1], DImode, NULL);
8332 operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));")
8335 [(set (match_operand:SI 0 "memory_operand" "")
8336 (match_operand:SI 1 "register_operand" ""))
8337 (set (match_operand:SI 2 "memory_operand" "")
8338 (match_operand:SI 3 "register_operand" ""))]
8339 "registers_ok_for_ldd_peep (operands[1], operands[3])
8340 && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
8343 "operands[0] = change_address (operands[0], DImode, NULL);
8344 operands[1] = gen_rtx_REG (DImode, REGNO (operands[1]));")
8347 [(set (match_operand:SF 0 "register_operand" "")
8348 (match_operand:SF 1 "memory_operand" ""))
8349 (set (match_operand:SF 2 "register_operand" "")
8350 (match_operand:SF 3 "memory_operand" ""))]
8351 "registers_ok_for_ldd_peep (operands[0], operands[2])
8352 && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
8355 "operands[1] = change_address (operands[1], DFmode, NULL);
8356 operands[0] = gen_rtx_REG (DFmode, REGNO (operands[0]));")
8359 [(set (match_operand:SF 0 "memory_operand" "")
8360 (match_operand:SF 1 "register_operand" ""))
8361 (set (match_operand:SF 2 "memory_operand" "")
8362 (match_operand:SF 3 "register_operand" ""))]
8363 "registers_ok_for_ldd_peep (operands[1], operands[3])
8364 && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
8367 "operands[0] = change_address (operands[0], DFmode, NULL);
8368 operands[1] = gen_rtx_REG (DFmode, REGNO (operands[1]));")
8371 [(set (match_operand:SI 0 "register_operand" "")
8372 (match_operand:SI 1 "memory_operand" ""))
8373 (set (match_operand:SI 2 "register_operand" "")
8374 (match_operand:SI 3 "memory_operand" ""))]
8375 "registers_ok_for_ldd_peep (operands[2], operands[0])
8376 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
8379 "operands[3] = change_address (operands[3], DImode, NULL);
8380 operands[2] = gen_rtx_REG (DImode, REGNO (operands[2]));")
8383 [(set (match_operand:SI 0 "memory_operand" "")
8384 (match_operand:SI 1 "register_operand" ""))
8385 (set (match_operand:SI 2 "memory_operand" "")
8386 (match_operand:SI 3 "register_operand" ""))]
8387 "registers_ok_for_ldd_peep (operands[3], operands[1])
8388 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
8391 "operands[2] = change_address (operands[2], DImode, NULL);
8392 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
8396 [(set (match_operand:SF 0 "register_operand" "")
8397 (match_operand:SF 1 "memory_operand" ""))
8398 (set (match_operand:SF 2 "register_operand" "")
8399 (match_operand:SF 3 "memory_operand" ""))]
8400 "registers_ok_for_ldd_peep (operands[2], operands[0])
8401 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
8404 "operands[3] = change_address (operands[3], DFmode, NULL);
8405 operands[2] = gen_rtx_REG (DFmode, REGNO (operands[2]));")
8408 [(set (match_operand:SF 0 "memory_operand" "")
8409 (match_operand:SF 1 "register_operand" ""))
8410 (set (match_operand:SF 2 "memory_operand" "")
8411 (match_operand:SF 3 "register_operand" ""))]
8412 "registers_ok_for_ldd_peep (operands[3], operands[1])
8413 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
8416 "operands[2] = change_address (operands[2], DFmode, NULL);
8417 operands[3] = gen_rtx_REG (DFmode, REGNO (operands[3]));")
8419 ;; Optimize the case of following a reg-reg move with a test
8420 ;; of reg just moved. Don't allow floating point regs for operand 0 or 1.
8421 ;; This can result from a float to fix conversion.
8424 [(set (match_operand:SI 0 "register_operand" "")
8425 (match_operand:SI 1 "register_operand" ""))
8427 (compare:CC (match_operand:SI 2 "register_operand" "")
8429 "(rtx_equal_p (operands[2], operands[0])
8430 || rtx_equal_p (operands[2], operands[1]))
8431 && ! SPARC_FP_REG_P (REGNO (operands[0]))
8432 && ! SPARC_FP_REG_P (REGNO (operands[1]))"
8433 [(parallel [(set (match_dup 0) (match_dup 1))
8435 (compare:CC (match_dup 1) (const_int 0)))])]
8439 [(set (match_operand:DI 0 "register_operand" "")
8440 (match_operand:DI 1 "register_operand" ""))
8442 (compare:CCX (match_operand:DI 2 "register_operand" "")
8445 && (rtx_equal_p (operands[2], operands[0])
8446 || rtx_equal_p (operands[2], operands[1]))
8447 && ! SPARC_FP_REG_P (REGNO (operands[0]))
8448 && ! SPARC_FP_REG_P (REGNO (operands[1]))"
8449 [(parallel [(set (match_dup 0) (match_dup 1))
8451 (compare:CCX (match_dup 1) (const_int 0)))])]
8454 ;; Return peepholes. These are generated by sparc_nonflat_function_epilogue
8455 ;; who then immediately calls final_scan_insn.
8457 (define_insn "*return_qi"
8458 [(set (match_operand:QI 0 "restore_operand" "")
8459 (match_operand:QI 1 "arith_operand" "rI"))
8461 "sparc_emitting_epilogue"
8464 if (! TARGET_ARCH64 && current_function_returns_struct)
8465 return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\";
8466 else if (TARGET_V9 && (GET_CODE (operands[1]) == CONST_INT
8467 || IN_OR_GLOBAL_P (operands[1])))
8468 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
8470 return \"ret\\n\\trestore %%g0, %1, %Y0\";
8472 [(set_attr "type" "multi")
8473 (set_attr "length" "2")])
8475 (define_insn "*return_hi"
8476 [(set (match_operand:HI 0 "restore_operand" "")
8477 (match_operand:HI 1 "arith_operand" "rI"))
8479 "sparc_emitting_epilogue"
8482 if (! TARGET_ARCH64 && current_function_returns_struct)
8483 return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\";
8484 else if (TARGET_V9 && (GET_CODE (operands[1]) == CONST_INT
8485 || IN_OR_GLOBAL_P (operands[1])))
8486 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
8488 return \"ret\;restore %%g0, %1, %Y0\";
8490 [(set_attr "type" "multi")
8491 (set_attr "length" "2")])
8493 (define_insn "*return_si"
8494 [(set (match_operand:SI 0 "restore_operand" "")
8495 (match_operand:SI 1 "arith_operand" "rI"))
8497 "sparc_emitting_epilogue"
8500 if (! TARGET_ARCH64 && current_function_returns_struct)
8501 return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\";
8502 else if (TARGET_V9 && (GET_CODE (operands[1]) == CONST_INT
8503 || IN_OR_GLOBAL_P (operands[1])))
8504 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
8506 return \"ret\;restore %%g0, %1, %Y0\";
8508 [(set_attr "type" "multi")
8509 (set_attr "length" "2")])
8511 (define_insn "*return_sf_no_fpu"
8512 [(set (match_operand:SF 0 "restore_operand" "=r")
8513 (match_operand:SF 1 "register_operand" "r"))
8515 "sparc_emitting_epilogue"
8518 if (! TARGET_ARCH64 && current_function_returns_struct)
8519 return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\";
8520 else if (TARGET_V9 && IN_OR_GLOBAL_P (operands[1]))
8521 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
8523 return \"ret\;restore %%g0, %1, %Y0\";
8525 [(set_attr "type" "multi")
8526 (set_attr "length" "2")])
8528 (define_insn "*return_df_no_fpu"
8529 [(set (match_operand:DF 0 "restore_operand" "=r")
8530 (match_operand:DF 1 "register_operand" "r"))
8532 "sparc_emitting_epilogue && TARGET_ARCH64"
8535 if (IN_OR_GLOBAL_P (operands[1]))
8536 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
8538 return \"ret\;restore %%g0, %1, %Y0\";
8540 [(set_attr "type" "multi")
8541 (set_attr "length" "2")])
8543 (define_insn "*return_addsi"
8544 [(set (match_operand:SI 0 "restore_operand" "")
8545 (plus:SI (match_operand:SI 1 "register_operand" "r")
8546 (match_operand:SI 2 "arith_operand" "rI")))
8548 "sparc_emitting_epilogue"
8551 if (! TARGET_ARCH64 && current_function_returns_struct)
8552 return \"jmp\\t%%i7+12\\n\\trestore %r1, %2, %Y0\";
8553 /* If operands are global or in registers, can use return */
8554 else if (TARGET_V9 && IN_OR_GLOBAL_P (operands[1])
8555 && (GET_CODE (operands[2]) == CONST_INT
8556 || IN_OR_GLOBAL_P (operands[2])))
8557 return \"return\\t%%i7+8\\n\\tadd\\t%Y1, %Y2, %Y0\";
8559 return \"ret\;restore %r1, %2, %Y0\";
8561 [(set_attr "type" "multi")
8562 (set_attr "length" "2")])
8564 (define_insn "*return_losum_si"
8565 [(set (match_operand:SI 0 "restore_operand" "")
8566 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
8567 (match_operand:SI 2 "immediate_operand" "in")))
8569 "sparc_emitting_epilogue && ! TARGET_CM_MEDMID"
8572 if (! TARGET_ARCH64 && current_function_returns_struct)
8573 return \"jmp\\t%%i7+12\\n\\trestore %r1, %%lo(%a2), %Y0\";
8574 /* If operands are global or in registers, can use return */
8575 else if (TARGET_V9 && IN_OR_GLOBAL_P (operands[1]))
8576 return \"return\\t%%i7+8\\n\\tor\\t%Y1, %%lo(%a2), %Y0\";
8578 return \"ret\;restore %r1, %%lo(%a2), %Y0\";
8580 [(set_attr "type" "multi")
8581 (set_attr "length" "2")])
8583 (define_insn "*return_di"
8584 [(set (match_operand:DI 0 "restore_operand" "")
8585 (match_operand:DI 1 "arith_double_operand" "rHI"))
8587 "sparc_emitting_epilogue && TARGET_ARCH64"
8588 "ret\;restore %%g0, %1, %Y0"
8589 [(set_attr "type" "multi")
8590 (set_attr "length" "2")])
8592 (define_insn "*return_adddi"
8593 [(set (match_operand:DI 0 "restore_operand" "")
8594 (plus:DI (match_operand:DI 1 "arith_operand" "%r")
8595 (match_operand:DI 2 "arith_double_operand" "rHI")))
8597 "sparc_emitting_epilogue && TARGET_ARCH64"
8598 "ret\;restore %r1, %2, %Y0"
8599 [(set_attr "type" "multi")
8600 (set_attr "length" "2")])
8602 (define_insn "*return_losum_di"
8603 [(set (match_operand:DI 0 "restore_operand" "")
8604 (lo_sum:DI (match_operand:DI 1 "arith_operand" "%r")
8605 (match_operand:DI 2 "immediate_operand" "in")))
8607 "sparc_emitting_epilogue && TARGET_ARCH64 && ! TARGET_CM_MEDMID"
8608 "ret\;restore %r1, %%lo(%a2), %Y0"
8609 [(set_attr "type" "multi")
8610 (set_attr "length" "2")])
8612 (define_insn "*return_sf"
8614 (match_operand:SF 0 "register_operand" "f"))
8616 "sparc_emitting_epilogue"
8617 "ret\;fmovs\\t%0, %%f0"
8618 [(set_attr "type" "multi")
8619 (set_attr "length" "2")])
8621 ;; Now peepholes to do a call followed by a jump.
8624 [(parallel [(set (match_operand 0 "" "")
8625 (call (mem:SI (match_operand:SI 1 "call_operand_address" "ps"))
8626 (match_operand 2 "" "")))
8627 (clobber (reg:SI 15))])
8628 (set (pc) (label_ref (match_operand 3 "" "")))]
8629 "short_branch (INSN_UID (insn), INSN_UID (operands[3]))
8630 && (USING_SJLJ_EXCEPTIONS || ! can_throw_internal (ins1))
8631 && sparc_cpu != PROCESSOR_ULTRASPARC
8632 && sparc_cpu != PROCESSOR_ULTRASPARC3"
8633 "call\\t%a1, %2\\n\\tadd\\t%%o7, (%l3-.-4), %%o7")
8636 [(parallel [(call (mem:SI (match_operand:SI 0 "call_operand_address" "ps"))
8637 (match_operand 1 "" ""))
8638 (clobber (reg:SI 15))])
8639 (set (pc) (label_ref (match_operand 2 "" "")))]
8640 "short_branch (INSN_UID (insn), INSN_UID (operands[2]))
8641 && (USING_SJLJ_EXCEPTIONS || ! can_throw_internal (ins1))
8642 && sparc_cpu != PROCESSOR_ULTRASPARC
8643 && sparc_cpu != PROCESSOR_ULTRASPARC3"
8644 "call\\t%a0, %1\\n\\tadd\\t%%o7, (%l2-.-4), %%o7")
8646 ;; ??? UltraSPARC-III note: A memory operation loading into the floating point register
8647 ;; ??? file, if it hits the prefetch cache, has a chance to dual-issue with other memory
8648 ;; ??? operations. With DFA we might be able to model this, but it requires a lot of
8650 (define_expand "prefetch"
8651 [(match_operand 0 "address_operand" "")
8652 (match_operand 1 "const_int_operand" "")
8653 (match_operand 2 "const_int_operand" "")]
8658 emit_insn (gen_prefetch_64 (operands[0], operands[1], operands[2]));
8660 emit_insn (gen_prefetch_32 (operands[0], operands[1], operands[2]));
8664 (define_insn "prefetch_64"
8665 [(prefetch (match_operand:DI 0 "address_operand" "p")
8666 (match_operand:DI 1 "const_int_operand" "n")
8667 (match_operand:DI 2 "const_int_operand" "n"))]
8670 static const char * const prefetch_instr[2][2] = {
8672 "prefetch\\t[%a0], 1", /* no locality: prefetch for one read */
8673 "prefetch\\t[%a0], 0", /* medium to high locality: prefetch for several reads */
8676 "prefetch\\t[%a0], 3", /* no locality: prefetch for one write */
8677 "prefetch\\t[%a0], 2", /* medium to high locality: prefetch for several writes */
8680 int read_or_write = INTVAL (operands[1]);
8681 int locality = INTVAL (operands[2]);
8683 if (read_or_write != 0 && read_or_write != 1)
8685 if (locality < 0 || locality > 3)
8687 return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
8689 [(set_attr "type" "load")])
8691 (define_insn "prefetch_32"
8692 [(prefetch (match_operand:SI 0 "address_operand" "p")
8693 (match_operand:SI 1 "const_int_operand" "n")
8694 (match_operand:SI 2 "const_int_operand" "n"))]
8697 static const char * const prefetch_instr[2][2] = {
8699 "prefetch\\t[%a0], 1", /* no locality: prefetch for one read */
8700 "prefetch\\t[%a0], 0", /* medium to high locality: prefetch for several reads */
8703 "prefetch\\t[%a0], 3", /* no locality: prefetch for one write */
8704 "prefetch\\t[%a0], 2", /* medium to high locality: prefetch for several writes */
8707 int read_or_write = INTVAL (operands[1]);
8708 int locality = INTVAL (operands[2]);
8710 if (read_or_write != 0 && read_or_write != 1)
8712 if (locality < 0 || locality > 3)
8714 return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
8716 [(set_attr "type" "load")])
8718 (define_expand "prologue"
8720 "flag_pic && current_function_uses_pic_offset_table"
8723 load_pic_register ();
8727 ;; We need to reload %l7 for -mflat -fpic,
8728 ;; otherwise %l7 should be preserved simply
8729 ;; by loading the function's register window
8730 (define_expand "exception_receiver"
8732 "TARGET_FLAT && flag_pic"
8735 load_pic_register ();
8740 (define_expand "builtin_setjmp_receiver"
8741 [(label_ref (match_operand 0 "" ""))]
8742 "TARGET_FLAT && flag_pic"
8745 load_pic_register ();
8750 [(trap_if (const_int 1) (const_int 5))]
8753 [(set_attr "type" "misc")])
8755 (define_expand "conditional_trap"
8756 [(trap_if (match_operator 0 "noov_compare_op"
8757 [(match_dup 2) (match_dup 3)])
8758 (match_operand:SI 1 "arith_operand" ""))]
8760 "operands[2] = gen_compare_reg (GET_CODE (operands[0]),
8761 sparc_compare_op0, sparc_compare_op1);
8762 operands[3] = const0_rtx;")
8765 [(trap_if (match_operator 0 "noov_compare_op" [(reg:CC 100) (const_int 0)])
8766 (match_operand:SI 1 "arith_operand" "rM"))]
8769 [(set_attr "type" "misc")])
8772 [(trap_if (match_operator 0 "noov_compare_op" [(reg:CCX 100) (const_int 0)])
8773 (match_operand:SI 1 "arith_operand" "rM"))]
8776 [(set_attr "type" "misc")])