1 ;; Machine description for SPARC chip for GCC
2 ;; Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
3 ;; 1999, 2000, 2001, 2002, 2003, 2004, 2005,2006, 2007 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 GCC.
10 ;; GCC 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 3, or (at your option)
15 ;; GCC 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 GCC; see the file COPYING3. If not see
22 ;; <http://www.gnu.org/licenses/>.
24 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
28 (UNSPEC_UPDATE_RETURN 1)
29 (UNSPEC_LOAD_PCREL_SYM 2)
30 (UNSPEC_MOVE_PIC_LABEL 5)
36 (UNSPEC_EMB_TEXTUHI 13)
37 (UNSPEC_EMB_TEXTHI 14)
38 (UNSPEC_EMB_TEXTULO 15)
46 (UNSPEC_TLSLD_BASE 35)
77 ;; The upper 32 fp regs on the v9 can't hold SFmode values. To deal with this
78 ;; a second register class, EXTRA_FP_REGS, exists for the v9 chip. The name
79 ;; is a bit of a misnomer as it covers all 64 fp regs. The corresponding
80 ;; constraint letter is 'e'. To avoid any confusion, 'e' is used instead of
81 ;; 'f' for all DF/TFmode values, including those that are specific to the v8.
84 ;; Attribute for cpu type.
85 ;; These must match the values for enum processor_type in sparc.h.
92 hypersparc,sparclite86x,
98 (const (symbol_ref "sparc_cpu_attr")))
100 ;; Attribute for the instruction set.
101 ;; At present we only need to distinguish v9/!v9, but for clarity we
102 ;; test TARGET_V8 too.
103 (define_attr "isa" "v7,v8,v9,sparclet"
105 (cond [(symbol_ref "TARGET_V9") (const_string "v9")
106 (symbol_ref "TARGET_V8") (const_string "v8")
107 (symbol_ref "TARGET_SPARCLET") (const_string "sparclet")]
108 (const_string "v7"))))
114 uncond_branch,branch,call,sibcall,call_no_delay_slot,return,
122 fga,fgm_pack,fgm_mul,fgm_pdist,fgm_cmp,
125 multi,savew,flushw,iflush,trap"
126 (const_string "ialu"))
128 ;; True if branch/call has empty delay slot and will emit a nop in it
129 (define_attr "empty_delay_slot" "false,true"
130 (symbol_ref "empty_delay_slot (insn)"))
132 (define_attr "branch_type" "none,icc,fcc,reg"
133 (const_string "none"))
135 (define_attr "pic" "false,true"
136 (symbol_ref "flag_pic != 0"))
138 (define_attr "calls_alloca" "false,true"
139 (symbol_ref "current_function_calls_alloca != 0"))
141 (define_attr "calls_eh_return" "false,true"
142 (symbol_ref "current_function_calls_eh_return !=0 "))
144 (define_attr "leaf_function" "false,true"
145 (symbol_ref "current_function_uses_only_leaf_regs != 0"))
147 (define_attr "delayed_branch" "false,true"
148 (symbol_ref "flag_delayed_branch != 0"))
150 ;; Length (in # of insns).
151 ;; Beware that setting a length greater or equal to 3 for conditional branches
152 ;; has a side-effect (see output_cbranch and output_v9branch).
153 (define_attr "length" ""
154 (cond [(eq_attr "type" "uncond_branch,call")
155 (if_then_else (eq_attr "empty_delay_slot" "true")
158 (eq_attr "type" "sibcall")
159 (if_then_else (eq_attr "leaf_function" "true")
160 (if_then_else (eq_attr "empty_delay_slot" "true")
163 (if_then_else (eq_attr "empty_delay_slot" "true")
166 (eq_attr "branch_type" "icc")
167 (if_then_else (match_operand 0 "noov_compare64_operator" "")
168 (if_then_else (lt (pc) (match_dup 1))
169 (if_then_else (lt (minus (match_dup 1) (pc)) (const_int 260000))
170 (if_then_else (eq_attr "empty_delay_slot" "true")
173 (if_then_else (eq_attr "empty_delay_slot" "true")
176 (if_then_else (lt (minus (pc) (match_dup 1)) (const_int 260000))
177 (if_then_else (eq_attr "empty_delay_slot" "true")
180 (if_then_else (eq_attr "empty_delay_slot" "true")
183 (if_then_else (eq_attr "empty_delay_slot" "true")
186 (eq_attr "branch_type" "fcc")
187 (if_then_else (match_operand 0 "fcc0_register_operand" "")
188 (if_then_else (eq_attr "empty_delay_slot" "true")
189 (if_then_else (eq (symbol_ref "TARGET_V9") (const_int 0))
192 (if_then_else (eq (symbol_ref "TARGET_V9") (const_int 0))
195 (if_then_else (lt (pc) (match_dup 2))
196 (if_then_else (lt (minus (match_dup 2) (pc)) (const_int 260000))
197 (if_then_else (eq_attr "empty_delay_slot" "true")
200 (if_then_else (eq_attr "empty_delay_slot" "true")
203 (if_then_else (lt (minus (pc) (match_dup 2)) (const_int 260000))
204 (if_then_else (eq_attr "empty_delay_slot" "true")
207 (if_then_else (eq_attr "empty_delay_slot" "true")
210 (eq_attr "branch_type" "reg")
211 (if_then_else (lt (pc) (match_dup 2))
212 (if_then_else (lt (minus (match_dup 2) (pc)) (const_int 32000))
213 (if_then_else (eq_attr "empty_delay_slot" "true")
216 (if_then_else (eq_attr "empty_delay_slot" "true")
219 (if_then_else (lt (minus (pc) (match_dup 2)) (const_int 32000))
220 (if_then_else (eq_attr "empty_delay_slot" "true")
223 (if_then_else (eq_attr "empty_delay_slot" "true")
229 (define_attr "fptype" "single,double"
230 (const_string "single"))
232 ;; UltraSPARC-III integer load type.
233 (define_attr "us3load_type" "2cycle,3cycle"
234 (const_string "2cycle"))
236 (define_asm_attributes
237 [(set_attr "length" "2")
238 (set_attr "type" "multi")])
240 ;; Attributes for instruction and branch scheduling
241 (define_attr "tls_call_delay" "false,true"
242 (symbol_ref "tls_call_delay (insn)"))
244 (define_attr "in_call_delay" "false,true"
245 (cond [(eq_attr "type" "uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
246 (const_string "false")
247 (eq_attr "type" "load,fpload,store,fpstore")
248 (if_then_else (eq_attr "length" "1")
249 (const_string "true")
250 (const_string "false"))]
251 (if_then_else (and (eq_attr "length" "1")
252 (eq_attr "tls_call_delay" "true"))
253 (const_string "true")
254 (const_string "false"))))
256 (define_attr "eligible_for_sibcall_delay" "false,true"
257 (symbol_ref "eligible_for_sibcall_delay (insn)"))
259 (define_attr "eligible_for_return_delay" "false,true"
260 (symbol_ref "eligible_for_return_delay (insn)"))
262 ;; ??? !v9: Should implement the notion of predelay slots for floating-point
263 ;; branches. This would allow us to remove the nop always inserted before
264 ;; a floating point branch.
266 ;; ??? It is OK for fill_simple_delay_slots to put load/store instructions
267 ;; in a delay slot, but it is not OK for fill_eager_delay_slots to do so.
268 ;; This is because doing so will add several pipeline stalls to the path
269 ;; that the load/store did not come from. Unfortunately, there is no way
270 ;; to prevent fill_eager_delay_slots from using load/store without completely
271 ;; disabling them. For the SPEC benchmark set, this is a serious lose,
272 ;; because it prevents us from moving back the final store of inner loops.
274 (define_attr "in_branch_delay" "false,true"
275 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
276 (eq_attr "length" "1"))
277 (const_string "true")
278 (const_string "false")))
280 (define_attr "in_uncond_branch_delay" "false,true"
281 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
282 (eq_attr "length" "1"))
283 (const_string "true")
284 (const_string "false")))
286 (define_attr "in_annul_branch_delay" "false,true"
287 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
288 (eq_attr "length" "1"))
289 (const_string "true")
290 (const_string "false")))
292 (define_delay (eq_attr "type" "call")
293 [(eq_attr "in_call_delay" "true") (nil) (nil)])
295 (define_delay (eq_attr "type" "sibcall")
296 [(eq_attr "eligible_for_sibcall_delay" "true") (nil) (nil)])
298 (define_delay (eq_attr "type" "branch")
299 [(eq_attr "in_branch_delay" "true")
300 (nil) (eq_attr "in_annul_branch_delay" "true")])
302 (define_delay (eq_attr "type" "uncond_branch")
303 [(eq_attr "in_uncond_branch_delay" "true")
306 (define_delay (eq_attr "type" "return")
307 [(eq_attr "eligible_for_return_delay" "true") (nil) (nil)])
310 ;; Include SPARC DFA schedulers
312 (include "cypress.md")
313 (include "supersparc.md")
314 (include "hypersparc.md")
315 (include "sparclet.md")
316 (include "ultra1_2.md")
317 (include "ultra3.md")
318 (include "niagara.md")
321 ;; Operand and operator predicates.
323 (include "predicates.md")
326 ;; Compare instructions.
328 ;; We generate RTL for comparisons and branches by having the cmpxx
329 ;; patterns store away the operands. Then, the scc and bcc patterns
330 ;; emit RTL for both the compare and the branch.
332 ;; We do this because we want to generate different code for an sne and
333 ;; seq insn. In those cases, if the second operand of the compare is not
334 ;; const0_rtx, we want to compute the xor of the two operands and test
337 ;; We start with the DEFINE_EXPANDs, then the DEFINE_INSNs to match
338 ;; the patterns. Finally, we have the DEFINE_SPLITs for some of the scc
339 ;; insns that actually require more than one machine instruction.
341 (define_expand "cmpsi"
343 (compare:CC (match_operand:SI 0 "compare_operand" "")
344 (match_operand:SI 1 "arith_operand" "")))]
347 if (GET_CODE (operands[0]) == ZERO_EXTRACT && operands[1] != const0_rtx)
348 operands[0] = force_reg (SImode, operands[0]);
350 sparc_compare_op0 = operands[0];
351 sparc_compare_op1 = operands[1];
355 (define_expand "cmpdi"
357 (compare:CCX (match_operand:DI 0 "compare_operand" "")
358 (match_operand:DI 1 "arith_operand" "")))]
361 if (GET_CODE (operands[0]) == ZERO_EXTRACT && operands[1] != const0_rtx)
362 operands[0] = force_reg (DImode, operands[0]);
364 sparc_compare_op0 = operands[0];
365 sparc_compare_op1 = operands[1];
369 (define_expand "cmpsf"
370 ;; The 96 here isn't ever used by anyone.
372 (compare:CCFP (match_operand:SF 0 "register_operand" "")
373 (match_operand:SF 1 "register_operand" "")))]
376 sparc_compare_op0 = operands[0];
377 sparc_compare_op1 = operands[1];
381 (define_expand "cmpdf"
382 ;; The 96 here isn't ever used by anyone.
384 (compare:CCFP (match_operand:DF 0 "register_operand" "")
385 (match_operand:DF 1 "register_operand" "")))]
388 sparc_compare_op0 = operands[0];
389 sparc_compare_op1 = operands[1];
393 (define_expand "cmptf"
394 ;; The 96 here isn't ever used by anyone.
396 (compare:CCFP (match_operand:TF 0 "register_operand" "")
397 (match_operand:TF 1 "register_operand" "")))]
400 sparc_compare_op0 = operands[0];
401 sparc_compare_op1 = operands[1];
405 ;; Now the compare DEFINE_INSNs.
407 (define_insn "*cmpsi_insn"
409 (compare:CC (match_operand:SI 0 "register_operand" "r")
410 (match_operand:SI 1 "arith_operand" "rI")))]
413 [(set_attr "type" "compare")])
415 (define_insn "*cmpdi_sp64"
417 (compare:CCX (match_operand:DI 0 "register_operand" "r")
418 (match_operand:DI 1 "arith_operand" "rI")))]
421 [(set_attr "type" "compare")])
423 (define_insn "*cmpsf_fpe"
424 [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
425 (compare:CCFPE (match_operand:SF 1 "register_operand" "f")
426 (match_operand:SF 2 "register_operand" "f")))]
430 return "fcmpes\t%0, %1, %2";
431 return "fcmpes\t%1, %2";
433 [(set_attr "type" "fpcmp")])
435 (define_insn "*cmpdf_fpe"
436 [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
437 (compare:CCFPE (match_operand:DF 1 "register_operand" "e")
438 (match_operand:DF 2 "register_operand" "e")))]
442 return "fcmped\t%0, %1, %2";
443 return "fcmped\t%1, %2";
445 [(set_attr "type" "fpcmp")
446 (set_attr "fptype" "double")])
448 (define_insn "*cmptf_fpe"
449 [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
450 (compare:CCFPE (match_operand:TF 1 "register_operand" "e")
451 (match_operand:TF 2 "register_operand" "e")))]
452 "TARGET_FPU && TARGET_HARD_QUAD"
455 return "fcmpeq\t%0, %1, %2";
456 return "fcmpeq\t%1, %2";
458 [(set_attr "type" "fpcmp")])
460 (define_insn "*cmpsf_fp"
461 [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
462 (compare:CCFP (match_operand:SF 1 "register_operand" "f")
463 (match_operand:SF 2 "register_operand" "f")))]
467 return "fcmps\t%0, %1, %2";
468 return "fcmps\t%1, %2";
470 [(set_attr "type" "fpcmp")])
472 (define_insn "*cmpdf_fp"
473 [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
474 (compare:CCFP (match_operand:DF 1 "register_operand" "e")
475 (match_operand:DF 2 "register_operand" "e")))]
479 return "fcmpd\t%0, %1, %2";
480 return "fcmpd\t%1, %2";
482 [(set_attr "type" "fpcmp")
483 (set_attr "fptype" "double")])
485 (define_insn "*cmptf_fp"
486 [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
487 (compare:CCFP (match_operand:TF 1 "register_operand" "e")
488 (match_operand:TF 2 "register_operand" "e")))]
489 "TARGET_FPU && TARGET_HARD_QUAD"
492 return "fcmpq\t%0, %1, %2";
493 return "fcmpq\t%1, %2";
495 [(set_attr "type" "fpcmp")])
497 ;; Next come the scc insns. For seq, sne, sgeu, and sltu, we can do this
498 ;; without jumps using the addx/subx instructions. For seq/sne on v9 we use
499 ;; the same code as v8 (the addx/subx method has more applications). The
500 ;; exception to this is "reg != 0" which can be done in one instruction on v9
501 ;; (so we do it). For the rest, on v9 we use conditional moves; on v8, we do
504 ;; Seq_special[_xxx] and sne_special[_xxx] clobber the CC reg, because they
505 ;; generate addcc/subcc instructions.
507 (define_expand "seqsi_special"
509 (xor:SI (match_operand:SI 1 "register_operand" "")
510 (match_operand:SI 2 "register_operand" "")))
511 (parallel [(set (match_operand:SI 0 "register_operand" "")
512 (eq:SI (match_dup 3) (const_int 0)))
513 (clobber (reg:CC 100))])]
515 { operands[3] = gen_reg_rtx (SImode); })
517 (define_expand "seqdi_special"
519 (xor:DI (match_operand:DI 1 "register_operand" "")
520 (match_operand:DI 2 "register_operand" "")))
521 (set (match_operand:DI 0 "register_operand" "")
522 (eq:DI (match_dup 3) (const_int 0)))]
524 { operands[3] = gen_reg_rtx (DImode); })
526 (define_expand "snesi_special"
528 (xor:SI (match_operand:SI 1 "register_operand" "")
529 (match_operand:SI 2 "register_operand" "")))
530 (parallel [(set (match_operand:SI 0 "register_operand" "")
531 (ne:SI (match_dup 3) (const_int 0)))
532 (clobber (reg:CC 100))])]
534 { operands[3] = gen_reg_rtx (SImode); })
536 (define_expand "snedi_special"
538 (xor:DI (match_operand:DI 1 "register_operand" "")
539 (match_operand:DI 2 "register_operand" "")))
540 (set (match_operand:DI 0 "register_operand" "")
541 (ne:DI (match_dup 3) (const_int 0)))]
543 { operands[3] = gen_reg_rtx (DImode); })
545 (define_expand "seqdi_special_trunc"
547 (xor:DI (match_operand:DI 1 "register_operand" "")
548 (match_operand:DI 2 "register_operand" "")))
549 (set (match_operand:SI 0 "register_operand" "")
550 (eq:SI (match_dup 3) (const_int 0)))]
552 { operands[3] = gen_reg_rtx (DImode); })
554 (define_expand "snedi_special_trunc"
556 (xor:DI (match_operand:DI 1 "register_operand" "")
557 (match_operand:DI 2 "register_operand" "")))
558 (set (match_operand:SI 0 "register_operand" "")
559 (ne:SI (match_dup 3) (const_int 0)))]
561 { operands[3] = gen_reg_rtx (DImode); })
563 (define_expand "seqsi_special_extend"
565 (xor:SI (match_operand:SI 1 "register_operand" "")
566 (match_operand:SI 2 "register_operand" "")))
567 (parallel [(set (match_operand:DI 0 "register_operand" "")
568 (eq:DI (match_dup 3) (const_int 0)))
569 (clobber (reg:CC 100))])]
571 { operands[3] = gen_reg_rtx (SImode); })
573 (define_expand "snesi_special_extend"
575 (xor:SI (match_operand:SI 1 "register_operand" "")
576 (match_operand:SI 2 "register_operand" "")))
577 (parallel [(set (match_operand:DI 0 "register_operand" "")
578 (ne:DI (match_dup 3) (const_int 0)))
579 (clobber (reg:CC 100))])]
581 { operands[3] = gen_reg_rtx (SImode); })
583 ;; ??? v9: Operand 0 needs a mode, so SImode was chosen.
584 ;; However, the code handles both SImode and DImode.
586 [(set (match_operand:SI 0 "int_register_operand" "")
587 (eq:SI (match_dup 1) (const_int 0)))]
590 if (GET_MODE (sparc_compare_op0) == SImode)
594 if (GET_MODE (operands[0]) == SImode)
595 pat = gen_seqsi_special (operands[0], sparc_compare_op0,
597 else if (! TARGET_ARCH64)
600 pat = gen_seqsi_special_extend (operands[0], sparc_compare_op0,
605 else if (GET_MODE (sparc_compare_op0) == DImode)
611 else if (GET_MODE (operands[0]) == SImode)
612 pat = gen_seqdi_special_trunc (operands[0], sparc_compare_op0,
615 pat = gen_seqdi_special (operands[0], sparc_compare_op0,
620 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
622 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, EQ);
623 emit_jump_insn (gen_sne (operands[0]));
628 if (gen_v9_scc (EQ, operands))
635 ;; ??? v9: Operand 0 needs a mode, so SImode was chosen.
636 ;; However, the code handles both SImode and DImode.
638 [(set (match_operand:SI 0 "int_register_operand" "")
639 (ne:SI (match_dup 1) (const_int 0)))]
642 if (GET_MODE (sparc_compare_op0) == SImode)
646 if (GET_MODE (operands[0]) == SImode)
647 pat = gen_snesi_special (operands[0], sparc_compare_op0,
649 else if (! TARGET_ARCH64)
652 pat = gen_snesi_special_extend (operands[0], sparc_compare_op0,
657 else if (GET_MODE (sparc_compare_op0) == DImode)
663 else if (GET_MODE (operands[0]) == SImode)
664 pat = gen_snedi_special_trunc (operands[0], sparc_compare_op0,
667 pat = gen_snedi_special (operands[0], sparc_compare_op0,
672 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
674 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, NE);
675 emit_jump_insn (gen_sne (operands[0]));
680 if (gen_v9_scc (NE, operands))
688 [(set (match_operand:SI 0 "int_register_operand" "")
689 (gt:SI (match_dup 1) (const_int 0)))]
692 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
694 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GT);
695 emit_jump_insn (gen_sne (operands[0]));
700 if (gen_v9_scc (GT, operands))
708 [(set (match_operand:SI 0 "int_register_operand" "")
709 (lt:SI (match_dup 1) (const_int 0)))]
712 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
714 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LT);
715 emit_jump_insn (gen_sne (operands[0]));
720 if (gen_v9_scc (LT, operands))
728 [(set (match_operand:SI 0 "int_register_operand" "")
729 (ge:SI (match_dup 1) (const_int 0)))]
732 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
734 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GE);
735 emit_jump_insn (gen_sne (operands[0]));
740 if (gen_v9_scc (GE, operands))
748 [(set (match_operand:SI 0 "int_register_operand" "")
749 (le:SI (match_dup 1) (const_int 0)))]
752 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
754 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LE);
755 emit_jump_insn (gen_sne (operands[0]));
760 if (gen_v9_scc (LE, operands))
767 (define_expand "sgtu"
768 [(set (match_operand:SI 0 "int_register_operand" "")
769 (gtu:SI (match_dup 1) (const_int 0)))]
776 /* We can do ltu easily, so if both operands are registers, swap them and
778 if ((GET_CODE (sparc_compare_op0) == REG
779 || GET_CODE (sparc_compare_op0) == SUBREG)
780 && (GET_CODE (sparc_compare_op1) == REG
781 || GET_CODE (sparc_compare_op1) == SUBREG))
783 tem = sparc_compare_op0;
784 sparc_compare_op0 = sparc_compare_op1;
785 sparc_compare_op1 = tem;
786 pat = gen_sltu (operands[0]);
795 if (gen_v9_scc (GTU, operands))
801 (define_expand "sltu"
802 [(set (match_operand:SI 0 "int_register_operand" "")
803 (ltu:SI (match_dup 1) (const_int 0)))]
808 if (gen_v9_scc (LTU, operands))
811 operands[1] = gen_compare_reg (LTU);
814 (define_expand "sgeu"
815 [(set (match_operand:SI 0 "int_register_operand" "")
816 (geu:SI (match_dup 1) (const_int 0)))]
821 if (gen_v9_scc (GEU, operands))
824 operands[1] = gen_compare_reg (GEU);
827 (define_expand "sleu"
828 [(set (match_operand:SI 0 "int_register_operand" "")
829 (leu:SI (match_dup 1) (const_int 0)))]
836 /* We can do geu easily, so if both operands are registers, swap them and
838 if ((GET_CODE (sparc_compare_op0) == REG
839 || GET_CODE (sparc_compare_op0) == SUBREG)
840 && (GET_CODE (sparc_compare_op1) == REG
841 || GET_CODE (sparc_compare_op1) == SUBREG))
843 tem = sparc_compare_op0;
844 sparc_compare_op0 = sparc_compare_op1;
845 sparc_compare_op1 = tem;
846 pat = gen_sgeu (operands[0]);
855 if (gen_v9_scc (LEU, operands))
861 ;; Now the DEFINE_INSNs for the scc cases.
863 ;; The SEQ and SNE patterns are special because they can be done
864 ;; without any branching and do not involve a COMPARE. We want
865 ;; them to always use the splits below so the results can be
868 (define_insn_and_split "*snesi_zero"
869 [(set (match_operand:SI 0 "register_operand" "=r")
870 (ne:SI (match_operand:SI 1 "register_operand" "r")
872 (clobber (reg:CC 100))]
876 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
878 (set (match_dup 0) (ltu:SI (reg:CC 100) (const_int 0)))]
880 [(set_attr "length" "2")])
882 (define_insn_and_split "*neg_snesi_zero"
883 [(set (match_operand:SI 0 "register_operand" "=r")
884 (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
886 (clobber (reg:CC 100))]
890 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
892 (set (match_dup 0) (neg:SI (ltu:SI (reg:CC 100) (const_int 0))))]
894 [(set_attr "length" "2")])
896 (define_insn_and_split "*snesi_zero_extend"
897 [(set (match_operand:DI 0 "register_operand" "=r")
898 (ne:DI (match_operand:SI 1 "register_operand" "r")
900 (clobber (reg:CC 100))]
904 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (minus:SI (const_int 0)
907 (set (match_dup 0) (zero_extend:DI (plus:SI (plus:SI (const_int 0)
909 (ltu:SI (reg:CC_NOOV 100)
912 [(set_attr "length" "2")])
914 (define_insn_and_split "*snedi_zero"
915 [(set (match_operand:DI 0 "register_operand" "=&r")
916 (ne:DI (match_operand:DI 1 "register_operand" "r")
920 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
921 [(set (match_dup 0) (const_int 0))
922 (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
927 [(set_attr "length" "2")])
929 (define_insn_and_split "*neg_snedi_zero"
930 [(set (match_operand:DI 0 "register_operand" "=&r")
931 (neg:DI (ne:DI (match_operand:DI 1 "register_operand" "r")
935 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
936 [(set (match_dup 0) (const_int 0))
937 (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
942 [(set_attr "length" "2")])
944 (define_insn_and_split "*snedi_zero_trunc"
945 [(set (match_operand:SI 0 "register_operand" "=&r")
946 (ne:SI (match_operand:DI 1 "register_operand" "r")
950 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
951 [(set (match_dup 0) (const_int 0))
952 (set (match_dup 0) (if_then_else:SI (ne:DI (match_dup 1)
957 [(set_attr "length" "2")])
959 (define_insn_and_split "*seqsi_zero"
960 [(set (match_operand:SI 0 "register_operand" "=r")
961 (eq:SI (match_operand:SI 1 "register_operand" "r")
963 (clobber (reg:CC 100))]
967 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
969 (set (match_dup 0) (geu:SI (reg:CC 100) (const_int 0)))]
971 [(set_attr "length" "2")])
973 (define_insn_and_split "*neg_seqsi_zero"
974 [(set (match_operand:SI 0 "register_operand" "=r")
975 (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
977 (clobber (reg:CC 100))]
981 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
983 (set (match_dup 0) (neg:SI (geu:SI (reg:CC 100) (const_int 0))))]
985 [(set_attr "length" "2")])
987 (define_insn_and_split "*seqsi_zero_extend"
988 [(set (match_operand:DI 0 "register_operand" "=r")
989 (eq:DI (match_operand:SI 1 "register_operand" "r")
991 (clobber (reg:CC 100))]
995 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (minus:SI (const_int 0)
998 (set (match_dup 0) (zero_extend:DI (minus:SI (minus:SI (const_int 0)
1000 (ltu:SI (reg:CC_NOOV 100)
1003 [(set_attr "length" "2")])
1005 (define_insn_and_split "*seqdi_zero"
1006 [(set (match_operand:DI 0 "register_operand" "=&r")
1007 (eq:DI (match_operand:DI 1 "register_operand" "r")
1011 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
1012 [(set (match_dup 0) (const_int 0))
1013 (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
1018 [(set_attr "length" "2")])
1020 (define_insn_and_split "*neg_seqdi_zero"
1021 [(set (match_operand:DI 0 "register_operand" "=&r")
1022 (neg:DI (eq:DI (match_operand:DI 1 "register_operand" "r")
1026 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
1027 [(set (match_dup 0) (const_int 0))
1028 (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
1033 [(set_attr "length" "2")])
1035 (define_insn_and_split "*seqdi_zero_trunc"
1036 [(set (match_operand:SI 0 "register_operand" "=&r")
1037 (eq:SI (match_operand:DI 1 "register_operand" "r")
1041 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
1042 [(set (match_dup 0) (const_int 0))
1043 (set (match_dup 0) (if_then_else:SI (eq:DI (match_dup 1)
1048 [(set_attr "length" "2")])
1050 ;; We can also do (x + (i == 0)) and related, so put them in.
1051 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1054 (define_insn_and_split "*x_plus_i_ne_0"
1055 [(set (match_operand:SI 0 "register_operand" "=r")
1056 (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
1058 (match_operand:SI 2 "register_operand" "r")))
1059 (clobber (reg:CC 100))]
1063 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1065 (set (match_dup 0) (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1068 [(set_attr "length" "2")])
1070 (define_insn_and_split "*x_minus_i_ne_0"
1071 [(set (match_operand:SI 0 "register_operand" "=r")
1072 (minus:SI (match_operand:SI 2 "register_operand" "r")
1073 (ne:SI (match_operand:SI 1 "register_operand" "r")
1075 (clobber (reg:CC 100))]
1079 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1081 (set (match_dup 0) (minus:SI (match_dup 2)
1082 (ltu:SI (reg:CC 100) (const_int 0))))]
1084 [(set_attr "length" "2")])
1086 (define_insn_and_split "*x_plus_i_eq_0"
1087 [(set (match_operand:SI 0 "register_operand" "=r")
1088 (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
1090 (match_operand:SI 2 "register_operand" "r")))
1091 (clobber (reg:CC 100))]
1095 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1097 (set (match_dup 0) (plus:SI (geu:SI (reg:CC 100) (const_int 0))
1100 [(set_attr "length" "2")])
1102 (define_insn_and_split "*x_minus_i_eq_0"
1103 [(set (match_operand:SI 0 "register_operand" "=r")
1104 (minus:SI (match_operand:SI 2 "register_operand" "r")
1105 (eq:SI (match_operand:SI 1 "register_operand" "r")
1107 (clobber (reg:CC 100))]
1111 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1113 (set (match_dup 0) (minus:SI (match_dup 2)
1114 (geu:SI (reg:CC 100) (const_int 0))))]
1116 [(set_attr "length" "2")])
1118 ;; We can also do GEU and LTU directly, but these operate after a compare.
1119 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1122 (define_insn "*sltu_insn"
1123 [(set (match_operand:SI 0 "register_operand" "=r")
1124 (ltu:SI (reg:CC 100) (const_int 0)))]
1127 [(set_attr "type" "ialuX")])
1129 (define_insn "*neg_sltu_insn"
1130 [(set (match_operand:SI 0 "register_operand" "=r")
1131 (neg:SI (ltu:SI (reg:CC 100) (const_int 0))))]
1134 [(set_attr "type" "ialuX")])
1136 ;; ??? Combine should canonicalize these next two to the same pattern.
1137 (define_insn "*neg_sltu_minus_x"
1138 [(set (match_operand:SI 0 "register_operand" "=r")
1139 (minus:SI (neg:SI (ltu:SI (reg:CC 100) (const_int 0)))
1140 (match_operand:SI 1 "arith_operand" "rI")))]
1142 "subx\t%%g0, %1, %0"
1143 [(set_attr "type" "ialuX")])
1145 (define_insn "*neg_sltu_plus_x"
1146 [(set (match_operand:SI 0 "register_operand" "=r")
1147 (neg:SI (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1148 (match_operand:SI 1 "arith_operand" "rI"))))]
1150 "subx\t%%g0, %1, %0"
1151 [(set_attr "type" "ialuX")])
1153 (define_insn "*sgeu_insn"
1154 [(set (match_operand:SI 0 "register_operand" "=r")
1155 (geu:SI (reg:CC 100) (const_int 0)))]
1157 "subx\t%%g0, -1, %0"
1158 [(set_attr "type" "ialuX")])
1160 (define_insn "*neg_sgeu_insn"
1161 [(set (match_operand:SI 0 "register_operand" "=r")
1162 (neg:SI (geu:SI (reg:CC 100) (const_int 0))))]
1164 "addx\t%%g0, -1, %0"
1165 [(set_attr "type" "ialuX")])
1167 ;; We can also do (x + ((unsigned) i >= 0)) and related, so put them in.
1168 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1171 (define_insn "*sltu_plus_x"
1172 [(set (match_operand:SI 0 "register_operand" "=r")
1173 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1174 (match_operand:SI 1 "arith_operand" "rI")))]
1176 "addx\t%%g0, %1, %0"
1177 [(set_attr "type" "ialuX")])
1179 (define_insn "*sltu_plus_x_plus_y"
1180 [(set (match_operand:SI 0 "register_operand" "=r")
1181 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1182 (plus:SI (match_operand:SI 1 "arith_operand" "%r")
1183 (match_operand:SI 2 "arith_operand" "rI"))))]
1186 [(set_attr "type" "ialuX")])
1188 (define_insn "*x_minus_sltu"
1189 [(set (match_operand:SI 0 "register_operand" "=r")
1190 (minus:SI (match_operand:SI 1 "register_operand" "r")
1191 (ltu:SI (reg:CC 100) (const_int 0))))]
1194 [(set_attr "type" "ialuX")])
1196 ;; ??? Combine should canonicalize these next two to the same pattern.
1197 (define_insn "*x_minus_y_minus_sltu"
1198 [(set (match_operand:SI 0 "register_operand" "=r")
1199 (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
1200 (match_operand:SI 2 "arith_operand" "rI"))
1201 (ltu:SI (reg:CC 100) (const_int 0))))]
1204 [(set_attr "type" "ialuX")])
1206 (define_insn "*x_minus_sltu_plus_y"
1207 [(set (match_operand:SI 0 "register_operand" "=r")
1208 (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
1209 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1210 (match_operand:SI 2 "arith_operand" "rI"))))]
1213 [(set_attr "type" "ialuX")])
1215 (define_insn "*sgeu_plus_x"
1216 [(set (match_operand:SI 0 "register_operand" "=r")
1217 (plus:SI (geu:SI (reg:CC 100) (const_int 0))
1218 (match_operand:SI 1 "register_operand" "r")))]
1221 [(set_attr "type" "ialuX")])
1223 (define_insn "*x_minus_sgeu"
1224 [(set (match_operand:SI 0 "register_operand" "=r")
1225 (minus:SI (match_operand:SI 1 "register_operand" "r")
1226 (geu:SI (reg:CC 100) (const_int 0))))]
1229 [(set_attr "type" "ialuX")])
1232 [(set (match_operand:SI 0 "register_operand" "")
1233 (match_operator:SI 2 "noov_compare_operator"
1234 [(match_operand 1 "icc_or_fcc_register_operand" "")
1237 && REGNO (operands[1]) == SPARC_ICC_REG
1238 && (GET_MODE (operands[1]) == CCXmode
1239 /* 32-bit LTU/GEU are better implemented using addx/subx. */
1240 || (GET_CODE (operands[2]) != LTU && GET_CODE (operands[2]) != GEU))"
1241 [(set (match_dup 0) (const_int 0))
1243 (if_then_else:SI (match_op_dup:SI 2 [(match_dup 1) (const_int 0)])
1249 ;; These control RTL generation for conditional jump insns
1251 ;; The quad-word fp compare library routines all return nonzero to indicate
1252 ;; true, which is different from the equivalent libgcc routines, so we must
1253 ;; handle them specially here.
1255 (define_expand "beq"
1257 (if_then_else (eq (match_dup 1) (const_int 0))
1258 (label_ref (match_operand 0 "" ""))
1262 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1263 && GET_CODE (sparc_compare_op0) == REG
1264 && GET_MODE (sparc_compare_op0) == DImode)
1266 emit_v9_brxx_insn (EQ, sparc_compare_op0, operands[0]);
1269 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1271 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, EQ);
1272 emit_jump_insn (gen_bne (operands[0]));
1275 operands[1] = gen_compare_reg (EQ);
1278 (define_expand "bne"
1280 (if_then_else (ne (match_dup 1) (const_int 0))
1281 (label_ref (match_operand 0 "" ""))
1285 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1286 && GET_CODE (sparc_compare_op0) == REG
1287 && GET_MODE (sparc_compare_op0) == DImode)
1289 emit_v9_brxx_insn (NE, sparc_compare_op0, operands[0]);
1292 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1294 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, NE);
1295 emit_jump_insn (gen_bne (operands[0]));
1298 operands[1] = gen_compare_reg (NE);
1301 (define_expand "bgt"
1303 (if_then_else (gt (match_dup 1) (const_int 0))
1304 (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 (GT, 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, GT);
1318 emit_jump_insn (gen_bne (operands[0]));
1321 operands[1] = gen_compare_reg (GT);
1324 (define_expand "bgtu"
1326 (if_then_else (gtu (match_dup 1) (const_int 0))
1327 (label_ref (match_operand 0 "" ""))
1331 operands[1] = gen_compare_reg (GTU);
1334 (define_expand "blt"
1336 (if_then_else (lt (match_dup 1) (const_int 0))
1337 (label_ref (match_operand 0 "" ""))
1341 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1342 && GET_CODE (sparc_compare_op0) == REG
1343 && GET_MODE (sparc_compare_op0) == DImode)
1345 emit_v9_brxx_insn (LT, sparc_compare_op0, operands[0]);
1348 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1350 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LT);
1351 emit_jump_insn (gen_bne (operands[0]));
1354 operands[1] = gen_compare_reg (LT);
1357 (define_expand "bltu"
1359 (if_then_else (ltu (match_dup 1) (const_int 0))
1360 (label_ref (match_operand 0 "" ""))
1364 operands[1] = gen_compare_reg (LTU);
1367 (define_expand "bge"
1369 (if_then_else (ge (match_dup 1) (const_int 0))
1370 (label_ref (match_operand 0 "" ""))
1374 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1375 && GET_CODE (sparc_compare_op0) == REG
1376 && GET_MODE (sparc_compare_op0) == DImode)
1378 emit_v9_brxx_insn (GE, sparc_compare_op0, operands[0]);
1381 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1383 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GE);
1384 emit_jump_insn (gen_bne (operands[0]));
1387 operands[1] = gen_compare_reg (GE);
1390 (define_expand "bgeu"
1392 (if_then_else (geu (match_dup 1) (const_int 0))
1393 (label_ref (match_operand 0 "" ""))
1397 operands[1] = gen_compare_reg (GEU);
1400 (define_expand "ble"
1402 (if_then_else (le (match_dup 1) (const_int 0))
1403 (label_ref (match_operand 0 "" ""))
1407 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1408 && GET_CODE (sparc_compare_op0) == REG
1409 && GET_MODE (sparc_compare_op0) == DImode)
1411 emit_v9_brxx_insn (LE, sparc_compare_op0, operands[0]);
1414 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1416 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LE);
1417 emit_jump_insn (gen_bne (operands[0]));
1420 operands[1] = gen_compare_reg (LE);
1423 (define_expand "bleu"
1425 (if_then_else (leu (match_dup 1) (const_int 0))
1426 (label_ref (match_operand 0 "" ""))
1430 operands[1] = gen_compare_reg (LEU);
1433 (define_expand "bunordered"
1435 (if_then_else (unordered (match_dup 1) (const_int 0))
1436 (label_ref (match_operand 0 "" ""))
1440 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1442 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1,
1444 emit_jump_insn (gen_beq (operands[0]));
1447 operands[1] = gen_compare_reg (UNORDERED);
1450 (define_expand "bordered"
1452 (if_then_else (ordered (match_dup 1) (const_int 0))
1453 (label_ref (match_operand 0 "" ""))
1457 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1459 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, ORDERED);
1460 emit_jump_insn (gen_bne (operands[0]));
1463 operands[1] = gen_compare_reg (ORDERED);
1466 (define_expand "bungt"
1468 (if_then_else (ungt (match_dup 1) (const_int 0))
1469 (label_ref (match_operand 0 "" ""))
1473 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1475 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNGT);
1476 emit_jump_insn (gen_bgt (operands[0]));
1479 operands[1] = gen_compare_reg (UNGT);
1482 (define_expand "bunlt"
1484 (if_then_else (unlt (match_dup 1) (const_int 0))
1485 (label_ref (match_operand 0 "" ""))
1489 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1491 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNLT);
1492 emit_jump_insn (gen_bne (operands[0]));
1495 operands[1] = gen_compare_reg (UNLT);
1498 (define_expand "buneq"
1500 (if_then_else (uneq (match_dup 1) (const_int 0))
1501 (label_ref (match_operand 0 "" ""))
1505 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1507 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNEQ);
1508 emit_jump_insn (gen_beq (operands[0]));
1511 operands[1] = gen_compare_reg (UNEQ);
1514 (define_expand "bunge"
1516 (if_then_else (unge (match_dup 1) (const_int 0))
1517 (label_ref (match_operand 0 "" ""))
1521 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1523 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNGE);
1524 emit_jump_insn (gen_bne (operands[0]));
1527 operands[1] = gen_compare_reg (UNGE);
1530 (define_expand "bunle"
1532 (if_then_else (unle (match_dup 1) (const_int 0))
1533 (label_ref (match_operand 0 "" ""))
1537 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1539 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNLE);
1540 emit_jump_insn (gen_bne (operands[0]));
1543 operands[1] = gen_compare_reg (UNLE);
1546 (define_expand "bltgt"
1548 (if_then_else (ltgt (match_dup 1) (const_int 0))
1549 (label_ref (match_operand 0 "" ""))
1553 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1555 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LTGT);
1556 emit_jump_insn (gen_bne (operands[0]));
1559 operands[1] = gen_compare_reg (LTGT);
1562 ;; Now match both normal and inverted jump.
1564 ;; XXX fpcmp nop braindamage
1565 (define_insn "*normal_branch"
1567 (if_then_else (match_operator 0 "noov_compare_operator"
1568 [(reg 100) (const_int 0)])
1569 (label_ref (match_operand 1 "" ""))
1573 return output_cbranch (operands[0], operands[1], 1, 0,
1574 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1577 [(set_attr "type" "branch")
1578 (set_attr "branch_type" "icc")])
1580 ;; XXX fpcmp nop braindamage
1581 (define_insn "*inverted_branch"
1583 (if_then_else (match_operator 0 "noov_compare_operator"
1584 [(reg 100) (const_int 0)])
1586 (label_ref (match_operand 1 "" ""))))]
1589 return output_cbranch (operands[0], operands[1], 1, 1,
1590 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1593 [(set_attr "type" "branch")
1594 (set_attr "branch_type" "icc")])
1596 ;; XXX fpcmp nop braindamage
1597 (define_insn "*normal_fp_branch"
1599 (if_then_else (match_operator 1 "comparison_operator"
1600 [(match_operand:CCFP 0 "fcc_register_operand" "c")
1602 (label_ref (match_operand 2 "" ""))
1606 return output_cbranch (operands[1], operands[2], 2, 0,
1607 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1610 [(set_attr "type" "branch")
1611 (set_attr "branch_type" "fcc")])
1613 ;; XXX fpcmp nop braindamage
1614 (define_insn "*inverted_fp_branch"
1616 (if_then_else (match_operator 1 "comparison_operator"
1617 [(match_operand:CCFP 0 "fcc_register_operand" "c")
1620 (label_ref (match_operand 2 "" ""))))]
1623 return output_cbranch (operands[1], operands[2], 2, 1,
1624 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1627 [(set_attr "type" "branch")
1628 (set_attr "branch_type" "fcc")])
1630 ;; XXX fpcmp nop braindamage
1631 (define_insn "*normal_fpe_branch"
1633 (if_then_else (match_operator 1 "comparison_operator"
1634 [(match_operand:CCFPE 0 "fcc_register_operand" "c")
1636 (label_ref (match_operand 2 "" ""))
1640 return output_cbranch (operands[1], operands[2], 2, 0,
1641 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1644 [(set_attr "type" "branch")
1645 (set_attr "branch_type" "fcc")])
1647 ;; XXX fpcmp nop braindamage
1648 (define_insn "*inverted_fpe_branch"
1650 (if_then_else (match_operator 1 "comparison_operator"
1651 [(match_operand:CCFPE 0 "fcc_register_operand" "c")
1654 (label_ref (match_operand 2 "" ""))))]
1657 return output_cbranch (operands[1], operands[2], 2, 1,
1658 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1661 [(set_attr "type" "branch")
1662 (set_attr "branch_type" "fcc")])
1664 ;; SPARC V9-specific jump insns. None of these are guaranteed to be
1665 ;; in the architecture.
1667 ;; There are no 32 bit brreg insns.
1670 (define_insn "*normal_int_branch_sp64"
1672 (if_then_else (match_operator 0 "v9_register_compare_operator"
1673 [(match_operand:DI 1 "register_operand" "r")
1675 (label_ref (match_operand 2 "" ""))
1679 return output_v9branch (operands[0], operands[2], 1, 2, 0,
1680 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1683 [(set_attr "type" "branch")
1684 (set_attr "branch_type" "reg")])
1687 (define_insn "*inverted_int_branch_sp64"
1689 (if_then_else (match_operator 0 "v9_register_compare_operator"
1690 [(match_operand:DI 1 "register_operand" "r")
1693 (label_ref (match_operand 2 "" ""))))]
1696 return output_v9branch (operands[0], operands[2], 1, 2, 1,
1697 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1700 [(set_attr "type" "branch")
1701 (set_attr "branch_type" "reg")])
1704 (define_mode_macro P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
1706 ;; Load in operand 0 the (absolute) address of operand 1, which is a symbolic
1707 ;; value subject to a PC-relative relocation. Operand 2 is a helper function
1708 ;; that adds the PC value at the call point to operand 0.
1710 (define_insn "load_pcrel_sym<P:mode>"
1711 [(set (match_operand:P 0 "register_operand" "=r")
1712 (unspec:P [(match_operand:P 1 "symbolic_operand" "")
1713 (match_operand:P 2 "call_address_operand" "")] UNSPEC_LOAD_PCREL_SYM))
1714 (clobber (reg:P 15))]
1717 if (flag_delayed_branch)
1718 return "sethi\t%%hi(%a1-4), %0\n\tcall\t%a2\n\t add\t%0, %%lo(%a1+4), %0";
1720 return "sethi\t%%hi(%a1-8), %0\n\tadd\t%0, %%lo(%a1-4), %0\n\tcall\t%a2\n\t nop";
1722 [(set (attr "type") (const_string "multi"))
1723 (set (attr "length")
1724 (if_then_else (eq_attr "delayed_branch" "true")
1729 ;; Integer move instructions
1731 (define_expand "movqi"
1732 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1733 (match_operand:QI 1 "general_operand" ""))]
1736 if (sparc_expand_move (QImode, operands))
1740 (define_insn "*movqi_insn"
1741 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m")
1742 (match_operand:QI 1 "input_operand" "rI,m,rJ"))]
1743 "(register_operand (operands[0], QImode)
1744 || register_or_zero_operand (operands[1], QImode))"
1749 [(set_attr "type" "*,load,store")
1750 (set_attr "us3load_type" "*,3cycle,*")])
1752 (define_expand "movhi"
1753 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1754 (match_operand:HI 1 "general_operand" ""))]
1757 if (sparc_expand_move (HImode, operands))
1761 (define_insn "*movhi_insn"
1762 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1763 (match_operand:HI 1 "input_operand" "rI,K,m,rJ"))]
1764 "(register_operand (operands[0], HImode)
1765 || register_or_zero_operand (operands[1], HImode))"
1768 sethi\t%%hi(%a1), %0
1771 [(set_attr "type" "*,*,load,store")
1772 (set_attr "us3load_type" "*,*,3cycle,*")])
1774 ;; We always work with constants here.
1775 (define_insn "*movhi_lo_sum"
1776 [(set (match_operand:HI 0 "register_operand" "=r")
1777 (ior:HI (match_operand:HI 1 "register_operand" "%r")
1778 (match_operand:HI 2 "small_int_operand" "I")))]
1782 (define_expand "movsi"
1783 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1784 (match_operand:SI 1 "general_operand" ""))]
1787 if (sparc_expand_move (SImode, operands))
1791 (define_insn "*movsi_insn"
1792 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,m,!f,!f,!m,d")
1793 (match_operand:SI 1 "input_operand" "rI,K,m,rJ,f,m,f,J"))]
1794 "(register_operand (operands[0], SImode)
1795 || register_or_zero_operand (operands[1], SImode))"
1798 sethi\t%%hi(%a1), %0
1805 [(set_attr "type" "*,*,load,store,fpmove,fpload,fpstore,fga")])
1807 (define_insn "*movsi_lo_sum"
1808 [(set (match_operand:SI 0 "register_operand" "=r")
1809 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1810 (match_operand:SI 2 "immediate_operand" "in")))]
1812 "or\t%1, %%lo(%a2), %0")
1814 (define_insn "*movsi_high"
1815 [(set (match_operand:SI 0 "register_operand" "=r")
1816 (high:SI (match_operand:SI 1 "immediate_operand" "in")))]
1818 "sethi\t%%hi(%a1), %0")
1820 ;; The next two patterns must wrap the SYMBOL_REF in an UNSPEC
1821 ;; so that CSE won't optimize the address computation away.
1822 (define_insn "movsi_lo_sum_pic"
1823 [(set (match_operand:SI 0 "register_operand" "=r")
1824 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1825 (unspec:SI [(match_operand:SI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
1827 "or\t%1, %%lo(%a2), %0")
1829 (define_insn "movsi_high_pic"
1830 [(set (match_operand:SI 0 "register_operand" "=r")
1831 (high:SI (unspec:SI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
1832 "flag_pic && check_pic (1)"
1833 "sethi\t%%hi(%a1), %0")
1835 (define_expand "movsi_pic_label_ref"
1836 [(set (match_dup 3) (high:SI
1837 (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
1838 (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1839 (set (match_dup 4) (lo_sum:SI (match_dup 3)
1840 (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1841 (set (match_operand:SI 0 "register_operand" "=r")
1842 (minus:SI (match_dup 5) (match_dup 4)))]
1845 current_function_uses_pic_offset_table = 1;
1846 operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
1847 if (!can_create_pseudo_p ())
1849 operands[3] = operands[0];
1850 operands[4] = operands[0];
1854 operands[3] = gen_reg_rtx (SImode);
1855 operands[4] = gen_reg_rtx (SImode);
1857 operands[5] = pic_offset_table_rtx;
1860 (define_insn "*movsi_high_pic_label_ref"
1861 [(set (match_operand:SI 0 "register_operand" "=r")
1863 (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
1864 (match_operand:SI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1866 "sethi\t%%hi(%a2-(%a1-.)), %0")
1868 (define_insn "*movsi_lo_sum_pic_label_ref"
1869 [(set (match_operand:SI 0 "register_operand" "=r")
1870 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1871 (unspec:SI [(match_operand:SI 2 "label_ref_operand" "")
1872 (match_operand:SI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1874 "or\t%1, %%lo(%a3-(%a2-.)), %0")
1876 ;; Set up the PIC register for VxWorks.
1878 (define_expand "vxworks_load_got"
1880 (high:SI (match_dup 1)))
1882 (mem:SI (lo_sum:SI (match_dup 0) (match_dup 1))))
1884 (mem:SI (lo_sum:SI (match_dup 0) (match_dup 2))))]
1885 "TARGET_VXWORKS_RTP"
1887 operands[0] = pic_offset_table_rtx;
1888 operands[1] = gen_rtx_SYMBOL_REF (SImode, VXWORKS_GOTT_BASE);
1889 operands[2] = gen_rtx_SYMBOL_REF (SImode, VXWORKS_GOTT_INDEX);
1892 (define_expand "movdi"
1893 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1894 (match_operand:DI 1 "general_operand" ""))]
1897 if (sparc_expand_move (DImode, operands))
1901 ;; Be careful, fmovd does not exist when !v9.
1902 ;; We match MEM moves directly when we have correct even
1903 ;; numbered registers, but fall into splits otherwise.
1904 ;; The constraint ordering here is really important to
1905 ;; avoid insane problems in reload, especially for patterns
1908 ;; (set (mem:DI (plus:SI (reg:SI 30 %fp)
1909 ;; (const_int -5016)))
1913 (define_insn "*movdi_insn_sp32"
1914 [(set (match_operand:DI 0 "nonimmediate_operand"
1915 "=o,T,U,o,r,r,r,?T,?f,?f,?o,?f")
1916 (match_operand:DI 1 "input_operand"
1917 " J,U,T,r,o,i,r, f, T, o, f, f"))]
1919 && (register_operand (operands[0], DImode)
1920 || register_or_zero_operand (operands[1], DImode))"
1934 [(set_attr "type" "store,store,load,*,*,*,*,fpstore,fpload,*,*,*")
1935 (set_attr "length" "2,*,*,2,2,2,2,*,*,2,2,2")])
1937 (define_insn "*movdi_insn_sp32_v9"
1938 [(set (match_operand:DI 0 "nonimmediate_operand"
1939 "=T,o,T,U,o,r,r,r,?T,?f,?f,?o,?e,?e,?W")
1940 (match_operand:DI 1 "input_operand"
1941 " J,J,U,T,r,o,i,r, f, T, o, f, e, W, e"))]
1944 && (register_operand (operands[0], DImode)
1945 || register_or_zero_operand (operands[1], DImode))"
1962 [(set_attr "type" "store,store,store,load,*,*,*,*,fpstore,fpload,*,*,fpmove,fpload,fpstore")
1963 (set_attr "length" "*,2,*,*,2,2,2,2,*,*,2,2,*,*,*")
1964 (set_attr "fptype" "*,*,*,*,*,*,*,*,*,*,*,*,double,*,*")])
1966 (define_insn "*movdi_insn_sp64"
1967 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,m,?e,?e,?W,b")
1968 (match_operand:DI 1 "input_operand" "rI,N,m,rJ,e,W,e,J"))]
1970 && (register_operand (operands[0], DImode)
1971 || register_or_zero_operand (operands[1], DImode))"
1974 sethi\t%%hi(%a1), %0
1981 [(set_attr "type" "*,*,load,store,fpmove,fpload,fpstore,fga")
1982 (set_attr "fptype" "*,*,*,*,double,*,*,double")])
1984 (define_expand "movdi_pic_label_ref"
1985 [(set (match_dup 3) (high:DI
1986 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
1987 (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1988 (set (match_dup 4) (lo_sum:DI (match_dup 3)
1989 (unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1990 (set (match_operand:DI 0 "register_operand" "=r")
1991 (minus:DI (match_dup 5) (match_dup 4)))]
1992 "TARGET_ARCH64 && flag_pic"
1994 current_function_uses_pic_offset_table = 1;
1995 operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
1996 if (!can_create_pseudo_p ())
1998 operands[3] = operands[0];
1999 operands[4] = operands[0];
2003 operands[3] = gen_reg_rtx (DImode);
2004 operands[4] = gen_reg_rtx (DImode);
2006 operands[5] = pic_offset_table_rtx;
2009 (define_insn "*movdi_high_pic_label_ref"
2010 [(set (match_operand:DI 0 "register_operand" "=r")
2012 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
2013 (match_operand:DI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
2014 "TARGET_ARCH64 && flag_pic"
2015 "sethi\t%%hi(%a2-(%a1-.)), %0")
2017 (define_insn "*movdi_lo_sum_pic_label_ref"
2018 [(set (match_operand:DI 0 "register_operand" "=r")
2019 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2020 (unspec:DI [(match_operand:DI 2 "label_ref_operand" "")
2021 (match_operand:DI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
2022 "TARGET_ARCH64 && flag_pic"
2023 "or\t%1, %%lo(%a3-(%a2-.)), %0")
2025 ;; SPARC-v9 code model support insns. See sparc_emit_set_symbolic_const64
2026 ;; in sparc.c to see what is going on here... PIC stuff comes first.
2028 (define_insn "movdi_lo_sum_pic"
2029 [(set (match_operand:DI 0 "register_operand" "=r")
2030 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2031 (unspec:DI [(match_operand:DI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
2032 "TARGET_ARCH64 && flag_pic"
2033 "or\t%1, %%lo(%a2), %0")
2035 (define_insn "movdi_high_pic"
2036 [(set (match_operand:DI 0 "register_operand" "=r")
2037 (high:DI (unspec:DI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
2038 "TARGET_ARCH64 && flag_pic && check_pic (1)"
2039 "sethi\t%%hi(%a1), %0")
2041 (define_insn "*sethi_di_medlow_embmedany_pic"
2042 [(set (match_operand:DI 0 "register_operand" "=r")
2043 (high:DI (match_operand:DI 1 "medium_pic_operand" "")))]
2044 "(TARGET_CM_MEDLOW || TARGET_CM_EMBMEDANY) && check_pic (1)"
2045 "sethi\t%%hi(%a1), %0")
2047 (define_insn "*sethi_di_medlow"
2048 [(set (match_operand:DI 0 "register_operand" "=r")
2049 (high:DI (match_operand:DI 1 "symbolic_operand" "")))]
2050 "TARGET_CM_MEDLOW && check_pic (1)"
2051 "sethi\t%%hi(%a1), %0")
2053 (define_insn "*losum_di_medlow"
2054 [(set (match_operand:DI 0 "register_operand" "=r")
2055 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2056 (match_operand:DI 2 "symbolic_operand" "")))]
2058 "or\t%1, %%lo(%a2), %0")
2060 (define_insn "seth44"
2061 [(set (match_operand:DI 0 "register_operand" "=r")
2062 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETH44)))]
2064 "sethi\t%%h44(%a1), %0")
2066 (define_insn "setm44"
2067 [(set (match_operand:DI 0 "register_operand" "=r")
2068 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2069 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_SETM44)))]
2071 "or\t%1, %%m44(%a2), %0")
2073 (define_insn "setl44"
2074 [(set (match_operand:DI 0 "register_operand" "=r")
2075 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2076 (match_operand:DI 2 "symbolic_operand" "")))]
2078 "or\t%1, %%l44(%a2), %0")
2080 (define_insn "sethh"
2081 [(set (match_operand:DI 0 "register_operand" "=r")
2082 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETHH)))]
2084 "sethi\t%%hh(%a1), %0")
2086 (define_insn "setlm"
2087 [(set (match_operand:DI 0 "register_operand" "=r")
2088 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETLM)))]
2090 "sethi\t%%lm(%a1), %0")
2092 (define_insn "sethm"
2093 [(set (match_operand:DI 0 "register_operand" "=r")
2094 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2095 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_EMB_SETHM)))]
2097 "or\t%1, %%hm(%a2), %0")
2099 (define_insn "setlo"
2100 [(set (match_operand:DI 0 "register_operand" "=r")
2101 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2102 (match_operand:DI 2 "symbolic_operand" "")))]
2104 "or\t%1, %%lo(%a2), %0")
2106 (define_insn "embmedany_sethi"
2107 [(set (match_operand:DI 0 "register_operand" "=r")
2108 (high:DI (unspec:DI [(match_operand:DI 1 "data_segment_operand" "")] UNSPEC_EMB_HISUM)))]
2109 "TARGET_CM_EMBMEDANY && check_pic (1)"
2110 "sethi\t%%hi(%a1), %0")
2112 (define_insn "embmedany_losum"
2113 [(set (match_operand:DI 0 "register_operand" "=r")
2114 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2115 (match_operand:DI 2 "data_segment_operand" "")))]
2116 "TARGET_CM_EMBMEDANY"
2117 "add\t%1, %%lo(%a2), %0")
2119 (define_insn "embmedany_brsum"
2120 [(set (match_operand:DI 0 "register_operand" "=r")
2121 (unspec:DI [(match_operand:DI 1 "register_operand" "r")] UNSPEC_EMB_HISUM))]
2122 "TARGET_CM_EMBMEDANY"
2125 (define_insn "embmedany_textuhi"
2126 [(set (match_operand:DI 0 "register_operand" "=r")
2127 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTUHI)))]
2128 "TARGET_CM_EMBMEDANY && check_pic (1)"
2129 "sethi\t%%uhi(%a1), %0")
2131 (define_insn "embmedany_texthi"
2132 [(set (match_operand:DI 0 "register_operand" "=r")
2133 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTHI)))]
2134 "TARGET_CM_EMBMEDANY && check_pic (1)"
2135 "sethi\t%%hi(%a1), %0")
2137 (define_insn "embmedany_textulo"
2138 [(set (match_operand:DI 0 "register_operand" "=r")
2139 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2140 (unspec:DI [(match_operand:DI 2 "text_segment_operand" "")] UNSPEC_EMB_TEXTULO)))]
2141 "TARGET_CM_EMBMEDANY"
2142 "or\t%1, %%ulo(%a2), %0")
2144 (define_insn "embmedany_textlo"
2145 [(set (match_operand:DI 0 "register_operand" "=r")
2146 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2147 (match_operand:DI 2 "text_segment_operand" "")))]
2148 "TARGET_CM_EMBMEDANY"
2149 "or\t%1, %%lo(%a2), %0")
2151 ;; Now some patterns to help reload out a bit.
2152 (define_expand "reload_indi"
2153 [(parallel [(match_operand:DI 0 "register_operand" "=r")
2154 (match_operand:DI 1 "immediate_operand" "")
2155 (match_operand:TI 2 "register_operand" "=&r")])]
2157 || TARGET_CM_EMBMEDANY)
2160 sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
2164 (define_expand "reload_outdi"
2165 [(parallel [(match_operand:DI 0 "register_operand" "=r")
2166 (match_operand:DI 1 "immediate_operand" "")
2167 (match_operand:TI 2 "register_operand" "=&r")])]
2169 || TARGET_CM_EMBMEDANY)
2172 sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
2176 ;; Split up putting CONSTs and REGs into DI regs when !arch64
2178 [(set (match_operand:DI 0 "register_operand" "")
2179 (match_operand:DI 1 "const_int_operand" ""))]
2180 "! TARGET_ARCH64 && reload_completed"
2181 [(clobber (const_int 0))]
2183 #if HOST_BITS_PER_WIDE_INT == 32
2184 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
2185 (INTVAL (operands[1]) < 0) ?
2188 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2191 unsigned int low, high;
2193 low = trunc_int_for_mode (INTVAL (operands[1]), SImode);
2194 high = trunc_int_for_mode (INTVAL (operands[1]) >> 32, SImode);
2195 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), GEN_INT (high)));
2197 /* Slick... but this trick loses if this subreg constant part
2198 can be done in one insn. */
2200 && ! SPARC_SETHI32_P (high)
2201 && ! SPARC_SIMM13_P (high))
2202 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2203 gen_highpart (SImode, operands[0])));
2205 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), GEN_INT (low)));
2211 [(set (match_operand:DI 0 "register_operand" "")
2212 (match_operand:DI 1 "const_double_operand" ""))]
2216 && ((GET_CODE (operands[0]) == REG
2217 && REGNO (operands[0]) < 32)
2218 || (GET_CODE (operands[0]) == SUBREG
2219 && GET_CODE (SUBREG_REG (operands[0])) == REG
2220 && REGNO (SUBREG_REG (operands[0])) < 32))))"
2221 [(clobber (const_int 0))]
2223 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
2224 GEN_INT (CONST_DOUBLE_HIGH (operands[1]))));
2226 /* Slick... but this trick loses if this subreg constant part
2227 can be done in one insn. */
2228 if (CONST_DOUBLE_LOW (operands[1]) == CONST_DOUBLE_HIGH (operands[1])
2229 && ! SPARC_SETHI32_P (CONST_DOUBLE_HIGH (operands[1]))
2230 && ! SPARC_SIMM13_P (CONST_DOUBLE_HIGH (operands[1])))
2232 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2233 gen_highpart (SImode, operands[0])));
2237 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2238 GEN_INT (CONST_DOUBLE_LOW (operands[1]))));
2244 [(set (match_operand:DI 0 "register_operand" "")
2245 (match_operand:DI 1 "register_operand" ""))]
2249 && ((GET_CODE (operands[0]) == REG
2250 && REGNO (operands[0]) < 32)
2251 || (GET_CODE (operands[0]) == SUBREG
2252 && GET_CODE (SUBREG_REG (operands[0])) == REG
2253 && REGNO (SUBREG_REG (operands[0])) < 32))))"
2254 [(clobber (const_int 0))]
2256 rtx set_dest = operands[0];
2257 rtx set_src = operands[1];
2261 dest1 = gen_highpart (SImode, set_dest);
2262 dest2 = gen_lowpart (SImode, set_dest);
2263 src1 = gen_highpart (SImode, set_src);
2264 src2 = gen_lowpart (SImode, set_src);
2266 /* Now emit using the real source and destination we found, swapping
2267 the order if we detect overlap. */
2268 if (reg_overlap_mentioned_p (dest1, src2))
2270 emit_insn (gen_movsi (dest2, src2));
2271 emit_insn (gen_movsi (dest1, src1));
2275 emit_insn (gen_movsi (dest1, src1));
2276 emit_insn (gen_movsi (dest2, src2));
2281 ;; Now handle the cases of memory moves from/to non-even
2282 ;; DI mode register pairs.
2284 [(set (match_operand:DI 0 "register_operand" "")
2285 (match_operand:DI 1 "memory_operand" ""))]
2288 && sparc_splitdi_legitimate (operands[0], operands[1]))"
2289 [(clobber (const_int 0))]
2291 rtx word0 = adjust_address (operands[1], SImode, 0);
2292 rtx word1 = adjust_address (operands[1], SImode, 4);
2293 rtx high_part = gen_highpart (SImode, operands[0]);
2294 rtx low_part = gen_lowpart (SImode, operands[0]);
2296 if (reg_overlap_mentioned_p (high_part, word1))
2298 emit_insn (gen_movsi (low_part, word1));
2299 emit_insn (gen_movsi (high_part, word0));
2303 emit_insn (gen_movsi (high_part, word0));
2304 emit_insn (gen_movsi (low_part, word1));
2310 [(set (match_operand:DI 0 "memory_operand" "")
2311 (match_operand:DI 1 "register_operand" ""))]
2314 && sparc_splitdi_legitimate (operands[1], operands[0]))"
2315 [(clobber (const_int 0))]
2317 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0),
2318 gen_highpart (SImode, operands[1])));
2319 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4),
2320 gen_lowpart (SImode, operands[1])));
2325 [(set (match_operand:DI 0 "memory_operand" "")
2326 (match_operand:DI 1 "const_zero_operand" ""))]
2330 && ! mem_min_alignment (operands[0], 8)))
2331 && offsettable_memref_p (operands[0])"
2332 [(clobber (const_int 0))]
2334 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0), const0_rtx));
2335 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4), const0_rtx));
2340 ;; Floating point and vector move instructions
2342 ;; We don't define V1SI because SI should work just fine.
2343 (define_mode_macro V32 [SF V2HI V4QI])
2345 ;; Yes, you guessed it right, the former movsf expander.
2346 (define_expand "mov<V32:mode>"
2347 [(set (match_operand:V32 0 "nonimmediate_operand" "")
2348 (match_operand:V32 1 "general_operand" ""))]
2349 "<V32:MODE>mode == SFmode || TARGET_VIS"
2351 if (sparc_expand_move (<V32:MODE>mode, operands))
2355 (define_insn "*movsf_insn"
2356 [(set (match_operand:V32 0 "nonimmediate_operand" "=d,f,*r,*r,*r,f,*r,m,m")
2357 (match_operand:V32 1 "input_operand" "GY,f,*rRY,Q,S,m,m,f,*rGY"))]
2359 && (register_operand (operands[0], <V32:MODE>mode)
2360 || register_or_zero_operand (operands[1], <V32:MODE>mode))"
2362 if (GET_CODE (operands[1]) == CONST_DOUBLE
2363 && (which_alternative == 2
2364 || which_alternative == 3
2365 || which_alternative == 4))
2370 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2371 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2372 operands[1] = GEN_INT (i);
2375 switch (which_alternative)
2378 return "fzeros\t%0";
2380 return "fmovs\t%1, %0";
2382 return "mov\t%1, %0";
2384 return "sethi\t%%hi(%a1), %0";
2389 return "ld\t%1, %0";
2392 return "st\t%r1, %0";
2397 [(set_attr "type" "fga,fpmove,*,*,*,fpload,load,fpstore,store")])
2399 ;; Exactly the same as above, except that all `f' cases are deleted.
2400 ;; This is necessary to prevent reload from ever trying to use a `f' reg
2403 (define_insn "*movsf_insn_no_fpu"
2404 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r,r,m")
2405 (match_operand:SF 1 "input_operand" "rR,Q,S,m,rG"))]
2407 && (register_operand (operands[0], SFmode)
2408 || register_or_zero_operand (operands[1], SFmode))"
2410 if (GET_CODE (operands[1]) == CONST_DOUBLE
2411 && (which_alternative == 0
2412 || which_alternative == 1
2413 || which_alternative == 2))
2418 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2419 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2420 operands[1] = GEN_INT (i);
2423 switch (which_alternative)
2426 return "mov\t%1, %0";
2428 return "sethi\t%%hi(%a1), %0";
2432 return "ld\t%1, %0";
2434 return "st\t%r1, %0";
2439 [(set_attr "type" "*,*,*,load,store")])
2441 ;; The following 3 patterns build SFmode constants in integer registers.
2443 (define_insn "*movsf_lo_sum"
2444 [(set (match_operand:SF 0 "register_operand" "=r")
2445 (lo_sum:SF (match_operand:SF 1 "register_operand" "r")
2446 (match_operand:SF 2 "fp_const_high_losum_operand" "S")))]
2452 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[2]);
2453 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2454 operands[2] = GEN_INT (i);
2455 return "or\t%1, %%lo(%a2), %0";
2458 (define_insn "*movsf_high"
2459 [(set (match_operand:SF 0 "register_operand" "=r")
2460 (high:SF (match_operand:SF 1 "fp_const_high_losum_operand" "S")))]
2466 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2467 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2468 operands[1] = GEN_INT (i);
2469 return "sethi\t%%hi(%1), %0";
2473 [(set (match_operand:SF 0 "register_operand" "")
2474 (match_operand:SF 1 "fp_const_high_losum_operand" ""))]
2475 "REG_P (operands[0]) && REGNO (operands[0]) < 32"
2476 [(set (match_dup 0) (high:SF (match_dup 1)))
2477 (set (match_dup 0) (lo_sum:SF (match_dup 0) (match_dup 1)))])
2479 (define_mode_macro V64 [DF V2SI V4HI V8QI])
2481 ;; Yes, you again guessed it right, the former movdf expander.
2482 (define_expand "mov<V64:mode>"
2483 [(set (match_operand:V64 0 "nonimmediate_operand" "")
2484 (match_operand:V64 1 "general_operand" ""))]
2485 "<V64:MODE>mode == DFmode || TARGET_VIS"
2487 if (sparc_expand_move (<V64:MODE>mode, operands))
2491 ;; Be careful, fmovd does not exist when !v9.
2492 (define_insn "*movdf_insn_sp32"
2493 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,W,U,T,o,e,*r,o,e,o")
2494 (match_operand:DF 1 "input_operand" "W#F,e,T,U,G,e,*rFo,*r,o#F,e"))]
2497 && (register_operand (operands[0], DFmode)
2498 || register_or_zero_operand (operands[1], DFmode))"
2510 [(set_attr "type" "fpload,fpstore,load,store,*,*,*,*,*,*")
2511 (set_attr "length" "*,*,*,*,2,2,2,2,2,2")])
2513 (define_insn "*movdf_insn_sp32_no_fpu"
2514 [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,o,r,o")
2515 (match_operand:DF 1 "input_operand" "T,U,G,ro,r"))]
2518 && (register_operand (operands[0], DFmode)
2519 || register_or_zero_operand (operands[1], DFmode))"
2526 [(set_attr "type" "load,store,*,*,*")
2527 (set_attr "length" "*,*,2,2,2")])
2529 ;; We have available v9 double floats but not 64-bit integer registers.
2530 (define_insn "*movdf_insn_sp32_v9"
2531 [(set (match_operand:V64 0 "nonimmediate_operand" "=b,e,e,T,W,U,T,f,*r,o")
2532 (match_operand:V64 1 "input_operand" "GY,e,W#F,GY,e,T,U,o#F,*roGYF,*rGYf"))]
2536 && (register_operand (operands[0], <V64:MODE>mode)
2537 || register_or_zero_operand (operands[1], <V64:MODE>mode))"
2549 [(set_attr "type" "fga,fpmove,load,store,store,load,store,*,*,*")
2550 (set_attr "length" "*,*,*,*,*,*,*,2,2,2")
2551 (set_attr "fptype" "double,double,*,*,*,*,*,*,*,*")])
2553 (define_insn "*movdf_insn_sp32_v9_no_fpu"
2554 [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,T,r,o")
2555 (match_operand:DF 1 "input_operand" "T,U,G,ro,rG"))]
2559 && (register_operand (operands[0], DFmode)
2560 || register_or_zero_operand (operands[1], DFmode))"
2567 [(set_attr "type" "load,store,store,*,*")
2568 (set_attr "length" "*,*,*,2,2")])
2570 ;; We have available both v9 double floats and 64-bit integer registers.
2571 (define_insn "*movdf_insn_sp64"
2572 [(set (match_operand:V64 0 "nonimmediate_operand" "=b,e,e,W,*r,*r,m,*r")
2573 (match_operand:V64 1 "input_operand" "GY,e,W#F,e,*rGY,m,*rGY,F"))]
2576 && (register_operand (operands[0], <V64:MODE>mode)
2577 || register_or_zero_operand (operands[1], <V64:MODE>mode))"
2587 [(set_attr "type" "fga,fpmove,load,store,*,load,store,*")
2588 (set_attr "length" "*,*,*,*,*,*,*,2")
2589 (set_attr "fptype" "double,double,*,*,*,*,*,*")])
2591 (define_insn "*movdf_insn_sp64_no_fpu"
2592 [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m")
2593 (match_operand:DF 1 "input_operand" "r,m,rG"))]
2596 && (register_operand (operands[0], DFmode)
2597 || register_or_zero_operand (operands[1], DFmode))"
2602 [(set_attr "type" "*,load,store")])
2604 ;; This pattern build DFmode constants in integer registers.
2606 [(set (match_operand:DF 0 "register_operand" "")
2607 (match_operand:DF 1 "const_double_operand" ""))]
2609 && (GET_CODE (operands[0]) == REG
2610 && REGNO (operands[0]) < 32)
2611 && ! const_zero_operand(operands[1], DFmode)
2612 && reload_completed"
2613 [(clobber (const_int 0))]
2618 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2619 REAL_VALUE_TO_TARGET_DOUBLE (r, l);
2620 operands[0] = gen_rtx_raw_REG (DImode, REGNO (operands[0]));
2624 #if HOST_BITS_PER_WIDE_INT == 32
2629 val = ((HOST_WIDE_INT)(unsigned long)l[1] |
2630 ((HOST_WIDE_INT)(unsigned long)l[0] << 32));
2631 emit_insn (gen_movdi (operands[0], gen_int_mode (val, DImode)));
2636 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
2637 gen_int_mode (l[0], SImode)));
2639 /* Slick... but this trick loses if this subreg constant part
2640 can be done in one insn. */
2642 && ! SPARC_SETHI32_P (l[0])
2643 && ! SPARC_SIMM13_P (l[0]))
2645 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2646 gen_highpart (SImode, operands[0])));
2650 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2651 gen_int_mode (l[1], SImode)));
2657 ;; Ok, now the splits to handle all the multi insn and
2658 ;; mis-aligned memory address cases.
2659 ;; In these splits please take note that we must be
2660 ;; careful when V9 but not ARCH64 because the integer
2661 ;; register DFmode cases must be handled.
2663 [(set (match_operand:V64 0 "register_operand" "")
2664 (match_operand:V64 1 "register_operand" ""))]
2667 && ((GET_CODE (operands[0]) == REG
2668 && REGNO (operands[0]) < 32)
2669 || (GET_CODE (operands[0]) == SUBREG
2670 && GET_CODE (SUBREG_REG (operands[0])) == REG
2671 && REGNO (SUBREG_REG (operands[0])) < 32))))
2672 && reload_completed"
2673 [(clobber (const_int 0))]
2675 rtx set_dest = operands[0];
2676 rtx set_src = operands[1];
2679 enum machine_mode half_mode;
2681 /* We can be expanded for DFmode or integral vector modes. */
2682 if (<V64:MODE>mode == DFmode)
2687 dest1 = gen_highpart (half_mode, set_dest);
2688 dest2 = gen_lowpart (half_mode, set_dest);
2689 src1 = gen_highpart (half_mode, set_src);
2690 src2 = gen_lowpart (half_mode, set_src);
2692 /* Now emit using the real source and destination we found, swapping
2693 the order if we detect overlap. */
2694 if (reg_overlap_mentioned_p (dest1, src2))
2696 emit_move_insn_1 (dest2, src2);
2697 emit_move_insn_1 (dest1, src1);
2701 emit_move_insn_1 (dest1, src1);
2702 emit_move_insn_1 (dest2, src2);
2708 [(set (match_operand:V64 0 "register_operand" "")
2709 (match_operand:V64 1 "memory_operand" ""))]
2712 && (((REGNO (operands[0]) % 2) != 0)
2713 || ! mem_min_alignment (operands[1], 8))
2714 && offsettable_memref_p (operands[1])"
2715 [(clobber (const_int 0))]
2717 enum machine_mode half_mode;
2720 /* We can be expanded for DFmode or integral vector modes. */
2721 if (<V64:MODE>mode == DFmode)
2726 word0 = adjust_address (operands[1], half_mode, 0);
2727 word1 = adjust_address (operands[1], half_mode, 4);
2729 if (reg_overlap_mentioned_p (gen_highpart (half_mode, operands[0]), word1))
2731 emit_move_insn_1 (gen_lowpart (half_mode, operands[0]), word1);
2732 emit_move_insn_1 (gen_highpart (half_mode, operands[0]), word0);
2736 emit_move_insn_1 (gen_highpart (half_mode, operands[0]), word0);
2737 emit_move_insn_1 (gen_lowpart (half_mode, operands[0]), word1);
2743 [(set (match_operand:V64 0 "memory_operand" "")
2744 (match_operand:V64 1 "register_operand" ""))]
2747 && (((REGNO (operands[1]) % 2) != 0)
2748 || ! mem_min_alignment (operands[0], 8))
2749 && offsettable_memref_p (operands[0])"
2750 [(clobber (const_int 0))]
2752 enum machine_mode half_mode;
2755 /* We can be expanded for DFmode or integral vector modes. */
2756 if (<V64:MODE>mode == DFmode)
2761 word0 = adjust_address (operands[0], half_mode, 0);
2762 word1 = adjust_address (operands[0], half_mode, 4);
2764 emit_move_insn_1 (word0, gen_highpart (half_mode, operands[1]));
2765 emit_move_insn_1 (word1, gen_lowpart (half_mode, operands[1]));
2770 [(set (match_operand:V64 0 "memory_operand" "")
2771 (match_operand:V64 1 "const_zero_operand" ""))]
2775 && ! mem_min_alignment (operands[0], 8)))
2776 && offsettable_memref_p (operands[0])"
2777 [(clobber (const_int 0))]
2779 enum machine_mode half_mode;
2782 /* We can be expanded for DFmode or integral vector modes. */
2783 if (<V64:MODE>mode == DFmode)
2788 dest1 = adjust_address (operands[0], half_mode, 0);
2789 dest2 = adjust_address (operands[0], half_mode, 4);
2791 emit_move_insn_1 (dest1, CONST0_RTX (half_mode));
2792 emit_move_insn_1 (dest2, CONST0_RTX (half_mode));
2797 [(set (match_operand:V64 0 "register_operand" "")
2798 (match_operand:V64 1 "const_zero_operand" ""))]
2801 && ((GET_CODE (operands[0]) == REG
2802 && REGNO (operands[0]) < 32)
2803 || (GET_CODE (operands[0]) == SUBREG
2804 && GET_CODE (SUBREG_REG (operands[0])) == REG
2805 && REGNO (SUBREG_REG (operands[0])) < 32))"
2806 [(clobber (const_int 0))]
2808 enum machine_mode half_mode;
2809 rtx set_dest = operands[0];
2812 /* We can be expanded for DFmode or integral vector modes. */
2813 if (<V64:MODE>mode == DFmode)
2818 dest1 = gen_highpart (half_mode, set_dest);
2819 dest2 = gen_lowpart (half_mode, set_dest);
2820 emit_move_insn_1 (dest1, CONST0_RTX (half_mode));
2821 emit_move_insn_1 (dest2, CONST0_RTX (half_mode));
2825 (define_expand "movtf"
2826 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2827 (match_operand:TF 1 "general_operand" ""))]
2830 if (sparc_expand_move (TFmode, operands))
2834 (define_insn "*movtf_insn_sp32"
2835 [(set (match_operand:TF 0 "nonimmediate_operand" "=b,e,o,U,r")
2836 (match_operand:TF 1 "input_operand" "G,oe,GeUr,o,roG"))]
2839 && (register_operand (operands[0], TFmode)
2840 || register_or_zero_operand (operands[1], TFmode))"
2842 [(set_attr "length" "4")])
2844 ;; Exactly the same as above, except that all `e' cases are deleted.
2845 ;; This is necessary to prevent reload from ever trying to use a `e' reg
2848 (define_insn "*movtf_insn_sp32_no_fpu"
2849 [(set (match_operand:TF 0 "nonimmediate_operand" "=o,U,o,r,o")
2850 (match_operand:TF 1 "input_operand" "G,o,U,roG,r"))]
2853 && (register_operand (operands[0], TFmode)
2854 || register_or_zero_operand (operands[1], TFmode))"
2856 [(set_attr "length" "4")])
2858 (define_insn "*movtf_insn_sp64"
2859 [(set (match_operand:TF 0 "nonimmediate_operand" "=b,e,o,r")
2860 (match_operand:TF 1 "input_operand" "G,oe,Ger,roG"))]
2863 && ! TARGET_HARD_QUAD
2864 && (register_operand (operands[0], TFmode)
2865 || register_or_zero_operand (operands[1], TFmode))"
2867 [(set_attr "length" "2")])
2869 (define_insn "*movtf_insn_sp64_hq"
2870 [(set (match_operand:TF 0 "nonimmediate_operand" "=b,e,e,m,o,r")
2871 (match_operand:TF 1 "input_operand" "G,e,m,e,rG,roG"))]
2875 && (register_operand (operands[0], TFmode)
2876 || register_or_zero_operand (operands[1], TFmode))"
2884 [(set_attr "type" "*,fpmove,fpload,fpstore,*,*")
2885 (set_attr "length" "2,*,*,*,2,2")])
2887 (define_insn "*movtf_insn_sp64_no_fpu"
2888 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o")
2889 (match_operand:TF 1 "input_operand" "orG,rG"))]
2892 && (register_operand (operands[0], TFmode)
2893 || register_or_zero_operand (operands[1], TFmode))"
2895 [(set_attr "length" "2")])
2897 ;; Now all the splits to handle multi-insn TF mode moves.
2899 [(set (match_operand:TF 0 "register_operand" "")
2900 (match_operand:TF 1 "register_operand" ""))]
2904 && ! TARGET_HARD_QUAD)
2905 || ! fp_register_operand (operands[0], TFmode))"
2906 [(clobber (const_int 0))]
2908 rtx set_dest = operands[0];
2909 rtx set_src = operands[1];
2913 dest1 = gen_df_reg (set_dest, 0);
2914 dest2 = gen_df_reg (set_dest, 1);
2915 src1 = gen_df_reg (set_src, 0);
2916 src2 = gen_df_reg (set_src, 1);
2918 /* Now emit using the real source and destination we found, swapping
2919 the order if we detect overlap. */
2920 if (reg_overlap_mentioned_p (dest1, src2))
2922 emit_insn (gen_movdf (dest2, src2));
2923 emit_insn (gen_movdf (dest1, src1));
2927 emit_insn (gen_movdf (dest1, src1));
2928 emit_insn (gen_movdf (dest2, src2));
2934 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2935 (match_operand:TF 1 "const_zero_operand" ""))]
2937 [(clobber (const_int 0))]
2939 rtx set_dest = operands[0];
2942 switch (GET_CODE (set_dest))
2945 dest1 = gen_df_reg (set_dest, 0);
2946 dest2 = gen_df_reg (set_dest, 1);
2949 dest1 = adjust_address (set_dest, DFmode, 0);
2950 dest2 = adjust_address (set_dest, DFmode, 8);
2956 emit_insn (gen_movdf (dest1, CONST0_RTX (DFmode)));
2957 emit_insn (gen_movdf (dest2, CONST0_RTX (DFmode)));
2962 [(set (match_operand:TF 0 "register_operand" "")
2963 (match_operand:TF 1 "memory_operand" ""))]
2965 && offsettable_memref_p (operands[1])
2967 || ! TARGET_HARD_QUAD
2968 || ! fp_register_operand (operands[0], TFmode)))"
2969 [(clobber (const_int 0))]
2971 rtx word0 = adjust_address (operands[1], DFmode, 0);
2972 rtx word1 = adjust_address (operands[1], DFmode, 8);
2973 rtx set_dest, dest1, dest2;
2975 set_dest = operands[0];
2977 dest1 = gen_df_reg (set_dest, 0);
2978 dest2 = gen_df_reg (set_dest, 1);
2980 /* Now output, ordering such that we don't clobber any registers
2981 mentioned in the address. */
2982 if (reg_overlap_mentioned_p (dest1, word1))
2985 emit_insn (gen_movdf (dest2, word1));
2986 emit_insn (gen_movdf (dest1, word0));
2990 emit_insn (gen_movdf (dest1, word0));
2991 emit_insn (gen_movdf (dest2, word1));
2997 [(set (match_operand:TF 0 "memory_operand" "")
2998 (match_operand:TF 1 "register_operand" ""))]
3000 && offsettable_memref_p (operands[0])
3002 || ! TARGET_HARD_QUAD
3003 || ! fp_register_operand (operands[1], TFmode)))"
3004 [(clobber (const_int 0))]
3006 rtx set_src = operands[1];
3008 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 0),
3009 gen_df_reg (set_src, 0)));
3010 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 8),
3011 gen_df_reg (set_src, 1)));
3016 ;; SPARC-V9 conditional move instructions.
3018 ;; We can handle larger constants here for some flavors, but for now we keep
3019 ;; it simple and only allow those constants supported by all flavors.
3020 ;; Note that emit_conditional_move canonicalizes operands 2,3 so that operand
3021 ;; 3 contains the constant if one is present, but we handle either for
3022 ;; generality (sparc.c puts a constant in operand 2).
3024 (define_expand "movqicc"
3025 [(set (match_operand:QI 0 "register_operand" "")
3026 (if_then_else:QI (match_operand 1 "comparison_operator" "")
3027 (match_operand:QI 2 "arith10_operand" "")
3028 (match_operand:QI 3 "arith10_operand" "")))]
3031 enum rtx_code code = GET_CODE (operands[1]);
3033 if (GET_MODE (sparc_compare_op0) == DImode
3037 if (sparc_compare_op1 == const0_rtx
3038 && GET_CODE (sparc_compare_op0) == REG
3039 && GET_MODE (sparc_compare_op0) == DImode
3040 && v9_regcmp_p (code))
3042 operands[1] = gen_rtx_fmt_ee (code, DImode,
3043 sparc_compare_op0, sparc_compare_op1);
3047 rtx cc_reg = gen_compare_reg (code);
3048 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3052 (define_expand "movhicc"
3053 [(set (match_operand:HI 0 "register_operand" "")
3054 (if_then_else:HI (match_operand 1 "comparison_operator" "")
3055 (match_operand:HI 2 "arith10_operand" "")
3056 (match_operand:HI 3 "arith10_operand" "")))]
3059 enum rtx_code code = GET_CODE (operands[1]);
3061 if (GET_MODE (sparc_compare_op0) == DImode
3065 if (sparc_compare_op1 == const0_rtx
3066 && GET_CODE (sparc_compare_op0) == REG
3067 && GET_MODE (sparc_compare_op0) == DImode
3068 && v9_regcmp_p (code))
3070 operands[1] = gen_rtx_fmt_ee (code, DImode,
3071 sparc_compare_op0, sparc_compare_op1);
3075 rtx cc_reg = gen_compare_reg (code);
3076 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3080 (define_expand "movsicc"
3081 [(set (match_operand:SI 0 "register_operand" "")
3082 (if_then_else:SI (match_operand 1 "comparison_operator" "")
3083 (match_operand:SI 2 "arith10_operand" "")
3084 (match_operand:SI 3 "arith10_operand" "")))]
3087 enum rtx_code code = GET_CODE (operands[1]);
3088 enum machine_mode op0_mode = GET_MODE (sparc_compare_op0);
3090 if (sparc_compare_op1 == const0_rtx
3091 && GET_CODE (sparc_compare_op0) == REG
3092 && (TARGET_ARCH64 && op0_mode == DImode && v9_regcmp_p (code)))
3094 operands[1] = gen_rtx_fmt_ee (code, op0_mode,
3095 sparc_compare_op0, sparc_compare_op1);
3099 rtx cc_reg = gen_compare_reg (code);
3100 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg),
3101 cc_reg, const0_rtx);
3105 (define_expand "movdicc"
3106 [(set (match_operand:DI 0 "register_operand" "")
3107 (if_then_else:DI (match_operand 1 "comparison_operator" "")
3108 (match_operand:DI 2 "arith10_operand" "")
3109 (match_operand:DI 3 "arith10_operand" "")))]
3112 enum rtx_code code = GET_CODE (operands[1]);
3114 if (sparc_compare_op1 == const0_rtx
3115 && GET_CODE (sparc_compare_op0) == REG
3116 && GET_MODE (sparc_compare_op0) == DImode
3117 && v9_regcmp_p (code))
3119 operands[1] = gen_rtx_fmt_ee (code, DImode,
3120 sparc_compare_op0, sparc_compare_op1);
3124 rtx cc_reg = gen_compare_reg (code);
3125 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg),
3126 cc_reg, const0_rtx);
3130 (define_expand "movsfcc"
3131 [(set (match_operand:SF 0 "register_operand" "")
3132 (if_then_else:SF (match_operand 1 "comparison_operator" "")
3133 (match_operand:SF 2 "register_operand" "")
3134 (match_operand:SF 3 "register_operand" "")))]
3135 "TARGET_V9 && TARGET_FPU"
3137 enum rtx_code code = GET_CODE (operands[1]);
3139 if (GET_MODE (sparc_compare_op0) == DImode
3143 if (sparc_compare_op1 == const0_rtx
3144 && GET_CODE (sparc_compare_op0) == REG
3145 && GET_MODE (sparc_compare_op0) == DImode
3146 && v9_regcmp_p (code))
3148 operands[1] = gen_rtx_fmt_ee (code, DImode,
3149 sparc_compare_op0, sparc_compare_op1);
3153 rtx cc_reg = gen_compare_reg (code);
3154 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3158 (define_expand "movdfcc"
3159 [(set (match_operand:DF 0 "register_operand" "")
3160 (if_then_else:DF (match_operand 1 "comparison_operator" "")
3161 (match_operand:DF 2 "register_operand" "")
3162 (match_operand:DF 3 "register_operand" "")))]
3163 "TARGET_V9 && TARGET_FPU"
3165 enum rtx_code code = GET_CODE (operands[1]);
3167 if (GET_MODE (sparc_compare_op0) == DImode
3171 if (sparc_compare_op1 == const0_rtx
3172 && GET_CODE (sparc_compare_op0) == REG
3173 && GET_MODE (sparc_compare_op0) == DImode
3174 && v9_regcmp_p (code))
3176 operands[1] = gen_rtx_fmt_ee (code, DImode,
3177 sparc_compare_op0, sparc_compare_op1);
3181 rtx cc_reg = gen_compare_reg (code);
3182 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3186 (define_expand "movtfcc"
3187 [(set (match_operand:TF 0 "register_operand" "")
3188 (if_then_else:TF (match_operand 1 "comparison_operator" "")
3189 (match_operand:TF 2 "register_operand" "")
3190 (match_operand:TF 3 "register_operand" "")))]
3191 "TARGET_V9 && TARGET_FPU"
3193 enum rtx_code code = GET_CODE (operands[1]);
3195 if (GET_MODE (sparc_compare_op0) == DImode
3199 if (sparc_compare_op1 == const0_rtx
3200 && GET_CODE (sparc_compare_op0) == REG
3201 && GET_MODE (sparc_compare_op0) == DImode
3202 && v9_regcmp_p (code))
3204 operands[1] = gen_rtx_fmt_ee (code, DImode,
3205 sparc_compare_op0, sparc_compare_op1);
3209 rtx cc_reg = gen_compare_reg (code);
3210 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3214 ;; Conditional move define_insns.
3216 (define_insn "*movqi_cc_sp64"
3217 [(set (match_operand:QI 0 "register_operand" "=r,r")
3218 (if_then_else:QI (match_operator 1 "comparison_operator"
3219 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
3221 (match_operand:QI 3 "arith11_operand" "rL,0")
3222 (match_operand:QI 4 "arith11_operand" "0,rL")))]
3226 mov%c1\t%x2, %4, %0"
3227 [(set_attr "type" "cmove")])
3229 (define_insn "*movhi_cc_sp64"
3230 [(set (match_operand:HI 0 "register_operand" "=r,r")
3231 (if_then_else:HI (match_operator 1 "comparison_operator"
3232 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
3234 (match_operand:HI 3 "arith11_operand" "rL,0")
3235 (match_operand:HI 4 "arith11_operand" "0,rL")))]
3239 mov%c1\t%x2, %4, %0"
3240 [(set_attr "type" "cmove")])
3242 (define_insn "*movsi_cc_sp64"
3243 [(set (match_operand:SI 0 "register_operand" "=r,r")
3244 (if_then_else:SI (match_operator 1 "comparison_operator"
3245 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
3247 (match_operand:SI 3 "arith11_operand" "rL,0")
3248 (match_operand:SI 4 "arith11_operand" "0,rL")))]
3252 mov%c1\t%x2, %4, %0"
3253 [(set_attr "type" "cmove")])
3255 (define_insn "*movdi_cc_sp64"
3256 [(set (match_operand:DI 0 "register_operand" "=r,r")
3257 (if_then_else:DI (match_operator 1 "comparison_operator"
3258 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
3260 (match_operand:DI 3 "arith11_operand" "rL,0")
3261 (match_operand:DI 4 "arith11_operand" "0,rL")))]
3265 mov%c1\t%x2, %4, %0"
3266 [(set_attr "type" "cmove")])
3268 (define_insn "*movdi_cc_sp64_trunc"
3269 [(set (match_operand:SI 0 "register_operand" "=r,r")
3270 (if_then_else:SI (match_operator 1 "comparison_operator"
3271 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
3273 (match_operand:SI 3 "arith11_operand" "rL,0")
3274 (match_operand:SI 4 "arith11_operand" "0,rL")))]
3278 mov%c1\t%x2, %4, %0"
3279 [(set_attr "type" "cmove")])
3281 (define_insn "*movsf_cc_sp64"
3282 [(set (match_operand:SF 0 "register_operand" "=f,f")
3283 (if_then_else:SF (match_operator 1 "comparison_operator"
3284 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
3286 (match_operand:SF 3 "register_operand" "f,0")
3287 (match_operand:SF 4 "register_operand" "0,f")))]
3288 "TARGET_V9 && TARGET_FPU"
3290 fmovs%C1\t%x2, %3, %0
3291 fmovs%c1\t%x2, %4, %0"
3292 [(set_attr "type" "fpcmove")])
3294 (define_insn "movdf_cc_sp64"
3295 [(set (match_operand:DF 0 "register_operand" "=e,e")
3296 (if_then_else:DF (match_operator 1 "comparison_operator"
3297 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
3299 (match_operand:DF 3 "register_operand" "e,0")
3300 (match_operand:DF 4 "register_operand" "0,e")))]
3301 "TARGET_V9 && TARGET_FPU"
3303 fmovd%C1\t%x2, %3, %0
3304 fmovd%c1\t%x2, %4, %0"
3305 [(set_attr "type" "fpcmove")
3306 (set_attr "fptype" "double")])
3308 (define_insn "*movtf_cc_hq_sp64"
3309 [(set (match_operand:TF 0 "register_operand" "=e,e")
3310 (if_then_else:TF (match_operator 1 "comparison_operator"
3311 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
3313 (match_operand:TF 3 "register_operand" "e,0")
3314 (match_operand:TF 4 "register_operand" "0,e")))]
3315 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
3317 fmovq%C1\t%x2, %3, %0
3318 fmovq%c1\t%x2, %4, %0"
3319 [(set_attr "type" "fpcmove")])
3321 (define_insn_and_split "*movtf_cc_sp64"
3322 [(set (match_operand:TF 0 "register_operand" "=e,e")
3323 (if_then_else:TF (match_operator 1 "comparison_operator"
3324 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
3326 (match_operand:TF 3 "register_operand" "e,0")
3327 (match_operand:TF 4 "register_operand" "0,e")))]
3328 "TARGET_V9 && TARGET_FPU && !TARGET_HARD_QUAD"
3330 "&& reload_completed"
3331 [(clobber (const_int 0))]
3333 rtx set_dest = operands[0];
3334 rtx set_srca = operands[3];
3335 rtx set_srcb = operands[4];
3336 int third = rtx_equal_p (set_dest, set_srca);
3338 rtx srca1, srca2, srcb1, srcb2;
3340 dest1 = gen_df_reg (set_dest, 0);
3341 dest2 = gen_df_reg (set_dest, 1);
3342 srca1 = gen_df_reg (set_srca, 0);
3343 srca2 = gen_df_reg (set_srca, 1);
3344 srcb1 = gen_df_reg (set_srcb, 0);
3345 srcb2 = gen_df_reg (set_srcb, 1);
3347 /* Now emit using the real source and destination we found, swapping
3348 the order if we detect overlap. */
3349 if ((third && reg_overlap_mentioned_p (dest1, srcb2))
3350 || (!third && reg_overlap_mentioned_p (dest1, srca2)))
3352 emit_insn (gen_movdf_cc_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
3353 emit_insn (gen_movdf_cc_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
3357 emit_insn (gen_movdf_cc_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
3358 emit_insn (gen_movdf_cc_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
3362 [(set_attr "length" "2")])
3364 (define_insn "*movqi_cc_reg_sp64"
3365 [(set (match_operand:QI 0 "register_operand" "=r,r")
3366 (if_then_else:QI (match_operator 1 "v9_register_compare_operator"
3367 [(match_operand:DI 2 "register_operand" "r,r")
3369 (match_operand:QI 3 "arith10_operand" "rM,0")
3370 (match_operand:QI 4 "arith10_operand" "0,rM")))]
3373 movr%D1\t%2, %r3, %0
3374 movr%d1\t%2, %r4, %0"
3375 [(set_attr "type" "cmove")])
3377 (define_insn "*movhi_cc_reg_sp64"
3378 [(set (match_operand:HI 0 "register_operand" "=r,r")
3379 (if_then_else:HI (match_operator 1 "v9_register_compare_operator"
3380 [(match_operand:DI 2 "register_operand" "r,r")
3382 (match_operand:HI 3 "arith10_operand" "rM,0")
3383 (match_operand:HI 4 "arith10_operand" "0,rM")))]
3386 movr%D1\t%2, %r3, %0
3387 movr%d1\t%2, %r4, %0"
3388 [(set_attr "type" "cmove")])
3390 (define_insn "*movsi_cc_reg_sp64"
3391 [(set (match_operand:SI 0 "register_operand" "=r,r")
3392 (if_then_else:SI (match_operator 1 "v9_register_compare_operator"
3393 [(match_operand:DI 2 "register_operand" "r,r")
3395 (match_operand:SI 3 "arith10_operand" "rM,0")
3396 (match_operand:SI 4 "arith10_operand" "0,rM")))]
3399 movr%D1\t%2, %r3, %0
3400 movr%d1\t%2, %r4, %0"
3401 [(set_attr "type" "cmove")])
3403 (define_insn "*movdi_cc_reg_sp64"
3404 [(set (match_operand:DI 0 "register_operand" "=r,r")
3405 (if_then_else:DI (match_operator 1 "v9_register_compare_operator"
3406 [(match_operand:DI 2 "register_operand" "r,r")
3408 (match_operand:DI 3 "arith10_operand" "rM,0")
3409 (match_operand:DI 4 "arith10_operand" "0,rM")))]
3412 movr%D1\t%2, %r3, %0
3413 movr%d1\t%2, %r4, %0"
3414 [(set_attr "type" "cmove")])
3416 (define_insn "*movsf_cc_reg_sp64"
3417 [(set (match_operand:SF 0 "register_operand" "=f,f")
3418 (if_then_else:SF (match_operator 1 "v9_register_compare_operator"
3419 [(match_operand:DI 2 "register_operand" "r,r")
3421 (match_operand:SF 3 "register_operand" "f,0")
3422 (match_operand:SF 4 "register_operand" "0,f")))]
3423 "TARGET_ARCH64 && TARGET_FPU"
3425 fmovrs%D1\t%2, %3, %0
3426 fmovrs%d1\t%2, %4, %0"
3427 [(set_attr "type" "fpcrmove")])
3429 (define_insn "movdf_cc_reg_sp64"
3430 [(set (match_operand:DF 0 "register_operand" "=e,e")
3431 (if_then_else:DF (match_operator 1 "v9_register_compare_operator"
3432 [(match_operand:DI 2 "register_operand" "r,r")
3434 (match_operand:DF 3 "register_operand" "e,0")
3435 (match_operand:DF 4 "register_operand" "0,e")))]
3436 "TARGET_ARCH64 && TARGET_FPU"
3438 fmovrd%D1\t%2, %3, %0
3439 fmovrd%d1\t%2, %4, %0"
3440 [(set_attr "type" "fpcrmove")
3441 (set_attr "fptype" "double")])
3443 (define_insn "*movtf_cc_reg_hq_sp64"
3444 [(set (match_operand:TF 0 "register_operand" "=e,e")
3445 (if_then_else:TF (match_operator 1 "v9_register_compare_operator"
3446 [(match_operand:DI 2 "register_operand" "r,r")
3448 (match_operand:TF 3 "register_operand" "e,0")
3449 (match_operand:TF 4 "register_operand" "0,e")))]
3450 "TARGET_ARCH64 && TARGET_FPU && TARGET_HARD_QUAD"
3452 fmovrq%D1\t%2, %3, %0
3453 fmovrq%d1\t%2, %4, %0"
3454 [(set_attr "type" "fpcrmove")])
3456 (define_insn_and_split "*movtf_cc_reg_sp64"
3457 [(set (match_operand:TF 0 "register_operand" "=e,e")
3458 (if_then_else:TF (match_operator 1 "v9_register_compare_operator"
3459 [(match_operand:DI 2 "register_operand" "r,r")
3461 (match_operand:TF 3 "register_operand" "e,0")
3462 (match_operand:TF 4 "register_operand" "0,e")))]
3463 "TARGET_ARCH64 && TARGET_FPU && ! TARGET_HARD_QUAD"
3465 "&& reload_completed"
3466 [(clobber (const_int 0))]
3468 rtx set_dest = operands[0];
3469 rtx set_srca = operands[3];
3470 rtx set_srcb = operands[4];
3471 int third = rtx_equal_p (set_dest, set_srca);
3473 rtx srca1, srca2, srcb1, srcb2;
3475 dest1 = gen_df_reg (set_dest, 0);
3476 dest2 = gen_df_reg (set_dest, 1);
3477 srca1 = gen_df_reg (set_srca, 0);
3478 srca2 = gen_df_reg (set_srca, 1);
3479 srcb1 = gen_df_reg (set_srcb, 0);
3480 srcb2 = gen_df_reg (set_srcb, 1);
3482 /* Now emit using the real source and destination we found, swapping
3483 the order if we detect overlap. */
3484 if ((third && reg_overlap_mentioned_p (dest1, srcb2))
3485 || (!third && reg_overlap_mentioned_p (dest1, srca2)))
3487 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
3488 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
3492 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
3493 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
3497 [(set_attr "length" "2")])
3500 ;; Zero-extension instructions
3502 ;; These patterns originally accepted general_operands, however, slightly
3503 ;; better code is generated by only accepting register_operands, and then
3504 ;; letting combine generate the ldu[hb] insns.
3506 (define_expand "zero_extendhisi2"
3507 [(set (match_operand:SI 0 "register_operand" "")
3508 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
3511 rtx temp = gen_reg_rtx (SImode);
3512 rtx shift_16 = GEN_INT (16);
3513 int op1_subbyte = 0;
3515 if (GET_CODE (operand1) == SUBREG)
3517 op1_subbyte = SUBREG_BYTE (operand1);
3518 op1_subbyte /= GET_MODE_SIZE (SImode);
3519 op1_subbyte *= GET_MODE_SIZE (SImode);
3520 operand1 = XEXP (operand1, 0);
3523 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3525 emit_insn (gen_lshrsi3 (operand0, temp, shift_16));
3529 (define_insn "*zero_extendhisi2_insn"
3530 [(set (match_operand:SI 0 "register_operand" "=r")
3531 (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
3534 [(set_attr "type" "load")
3535 (set_attr "us3load_type" "3cycle")])
3537 (define_expand "zero_extendqihi2"
3538 [(set (match_operand:HI 0 "register_operand" "")
3539 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
3543 (define_insn "*zero_extendqihi2_insn"
3544 [(set (match_operand:HI 0 "register_operand" "=r,r")
3545 (zero_extend:HI (match_operand:QI 1 "input_operand" "r,m")))]
3546 "GET_CODE (operands[1]) != CONST_INT"
3550 [(set_attr "type" "*,load")
3551 (set_attr "us3load_type" "*,3cycle")])
3553 (define_expand "zero_extendqisi2"
3554 [(set (match_operand:SI 0 "register_operand" "")
3555 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
3559 (define_insn "*zero_extendqisi2_insn"
3560 [(set (match_operand:SI 0 "register_operand" "=r,r")
3561 (zero_extend:SI (match_operand:QI 1 "input_operand" "r,m")))]
3562 "GET_CODE (operands[1]) != CONST_INT"
3566 [(set_attr "type" "*,load")
3567 (set_attr "us3load_type" "*,3cycle")])
3569 (define_expand "zero_extendqidi2"
3570 [(set (match_operand:DI 0 "register_operand" "")
3571 (zero_extend:DI (match_operand:QI 1 "register_operand" "")))]
3575 (define_insn "*zero_extendqidi2_insn"
3576 [(set (match_operand:DI 0 "register_operand" "=r,r")
3577 (zero_extend:DI (match_operand:QI 1 "input_operand" "r,m")))]
3578 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
3582 [(set_attr "type" "*,load")
3583 (set_attr "us3load_type" "*,3cycle")])
3585 (define_expand "zero_extendhidi2"
3586 [(set (match_operand:DI 0 "register_operand" "")
3587 (zero_extend:DI (match_operand:HI 1 "register_operand" "")))]
3590 rtx temp = gen_reg_rtx (DImode);
3591 rtx shift_48 = GEN_INT (48);
3592 int op1_subbyte = 0;
3594 if (GET_CODE (operand1) == SUBREG)
3596 op1_subbyte = SUBREG_BYTE (operand1);
3597 op1_subbyte /= GET_MODE_SIZE (DImode);
3598 op1_subbyte *= GET_MODE_SIZE (DImode);
3599 operand1 = XEXP (operand1, 0);
3602 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
3604 emit_insn (gen_lshrdi3 (operand0, temp, shift_48));
3608 (define_insn "*zero_extendhidi2_insn"
3609 [(set (match_operand:DI 0 "register_operand" "=r")
3610 (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
3613 [(set_attr "type" "load")
3614 (set_attr "us3load_type" "3cycle")])
3616 ;; ??? Write truncdisi pattern using sra?
3618 (define_expand "zero_extendsidi2"
3619 [(set (match_operand:DI 0 "register_operand" "")
3620 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
3624 (define_insn "*zero_extendsidi2_insn_sp64"
3625 [(set (match_operand:DI 0 "register_operand" "=r,r")
3626 (zero_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
3627 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
3631 [(set_attr "type" "shift,load")])
3633 (define_insn_and_split "*zero_extendsidi2_insn_sp32"
3634 [(set (match_operand:DI 0 "register_operand" "=r")
3635 (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
3638 "&& reload_completed"
3639 [(set (match_dup 2) (match_dup 3))
3640 (set (match_dup 4) (match_dup 5))]
3644 dest1 = gen_highpart (SImode, operands[0]);
3645 dest2 = gen_lowpart (SImode, operands[0]);
3647 /* Swap the order in case of overlap. */
3648 if (REGNO (dest1) == REGNO (operands[1]))
3650 operands[2] = dest2;
3651 operands[3] = operands[1];
3652 operands[4] = dest1;
3653 operands[5] = const0_rtx;
3657 operands[2] = dest1;
3658 operands[3] = const0_rtx;
3659 operands[4] = dest2;
3660 operands[5] = operands[1];
3663 [(set_attr "length" "2")])
3665 ;; Simplify comparisons of extended values.
3667 (define_insn "*cmp_zero_extendqisi2"
3669 (compare:CC (zero_extend:SI (match_operand:QI 0 "register_operand" "r"))
3672 "andcc\t%0, 0xff, %%g0"
3673 [(set_attr "type" "compare")])
3675 (define_insn "*cmp_zero_qi"
3677 (compare:CC (match_operand:QI 0 "register_operand" "r")
3680 "andcc\t%0, 0xff, %%g0"
3681 [(set_attr "type" "compare")])
3683 (define_insn "*cmp_zero_extendqisi2_set"
3685 (compare:CC (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
3687 (set (match_operand:SI 0 "register_operand" "=r")
3688 (zero_extend:SI (match_dup 1)))]
3690 "andcc\t%1, 0xff, %0"
3691 [(set_attr "type" "compare")])
3693 (define_insn "*cmp_zero_extendqisi2_andcc_set"
3695 (compare:CC (and:SI (match_operand:SI 1 "register_operand" "r")
3698 (set (match_operand:SI 0 "register_operand" "=r")
3699 (zero_extend:SI (subreg:QI (match_dup 1) 0)))]
3701 "andcc\t%1, 0xff, %0"
3702 [(set_attr "type" "compare")])
3704 (define_insn "*cmp_zero_extendqidi2"
3706 (compare:CCX (zero_extend:DI (match_operand:QI 0 "register_operand" "r"))
3709 "andcc\t%0, 0xff, %%g0"
3710 [(set_attr "type" "compare")])
3712 (define_insn "*cmp_zero_qi_sp64"
3714 (compare:CCX (match_operand:QI 0 "register_operand" "r")
3717 "andcc\t%0, 0xff, %%g0"
3718 [(set_attr "type" "compare")])
3720 (define_insn "*cmp_zero_extendqidi2_set"
3722 (compare:CCX (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
3724 (set (match_operand:DI 0 "register_operand" "=r")
3725 (zero_extend:DI (match_dup 1)))]
3727 "andcc\t%1, 0xff, %0"
3728 [(set_attr "type" "compare")])
3730 (define_insn "*cmp_zero_extendqidi2_andcc_set"
3732 (compare:CCX (and:DI (match_operand:DI 1 "register_operand" "r")
3735 (set (match_operand:DI 0 "register_operand" "=r")
3736 (zero_extend:DI (subreg:QI (match_dup 1) 0)))]
3738 "andcc\t%1, 0xff, %0"
3739 [(set_attr "type" "compare")])
3741 ;; Similarly, handle {SI,DI}->QI mode truncation followed by a compare.
3743 (define_insn "*cmp_siqi_trunc"
3745 (compare:CC (subreg:QI (match_operand:SI 0 "register_operand" "r") 3)
3748 "andcc\t%0, 0xff, %%g0"
3749 [(set_attr "type" "compare")])
3751 (define_insn "*cmp_siqi_trunc_set"
3753 (compare:CC (subreg:QI (match_operand:SI 1 "register_operand" "r") 3)
3755 (set (match_operand:QI 0 "register_operand" "=r")
3756 (subreg:QI (match_dup 1) 3))]
3758 "andcc\t%1, 0xff, %0"
3759 [(set_attr "type" "compare")])
3761 (define_insn "*cmp_diqi_trunc"
3763 (compare:CC (subreg:QI (match_operand:DI 0 "register_operand" "r") 7)
3766 "andcc\t%0, 0xff, %%g0"
3767 [(set_attr "type" "compare")])
3769 (define_insn "*cmp_diqi_trunc_set"
3771 (compare:CC (subreg:QI (match_operand:DI 1 "register_operand" "r") 7)
3773 (set (match_operand:QI 0 "register_operand" "=r")
3774 (subreg:QI (match_dup 1) 7))]
3776 "andcc\t%1, 0xff, %0"
3777 [(set_attr "type" "compare")])
3780 ;; Sign-extension instructions
3782 ;; These patterns originally accepted general_operands, however, slightly
3783 ;; better code is generated by only accepting register_operands, and then
3784 ;; letting combine generate the lds[hb] insns.
3786 (define_expand "extendhisi2"
3787 [(set (match_operand:SI 0 "register_operand" "")
3788 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
3791 rtx temp = gen_reg_rtx (SImode);
3792 rtx shift_16 = GEN_INT (16);
3793 int op1_subbyte = 0;
3795 if (GET_CODE (operand1) == SUBREG)
3797 op1_subbyte = SUBREG_BYTE (operand1);
3798 op1_subbyte /= GET_MODE_SIZE (SImode);
3799 op1_subbyte *= GET_MODE_SIZE (SImode);
3800 operand1 = XEXP (operand1, 0);
3803 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3805 emit_insn (gen_ashrsi3 (operand0, temp, shift_16));
3809 (define_insn "*sign_extendhisi2_insn"
3810 [(set (match_operand:SI 0 "register_operand" "=r")
3811 (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
3814 [(set_attr "type" "sload")
3815 (set_attr "us3load_type" "3cycle")])
3817 (define_expand "extendqihi2"
3818 [(set (match_operand:HI 0 "register_operand" "")
3819 (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
3822 rtx temp = gen_reg_rtx (SImode);
3823 rtx shift_24 = GEN_INT (24);
3824 int op1_subbyte = 0;
3825 int op0_subbyte = 0;
3827 if (GET_CODE (operand1) == SUBREG)
3829 op1_subbyte = SUBREG_BYTE (operand1);
3830 op1_subbyte /= GET_MODE_SIZE (SImode);
3831 op1_subbyte *= GET_MODE_SIZE (SImode);
3832 operand1 = XEXP (operand1, 0);
3834 if (GET_CODE (operand0) == SUBREG)
3836 op0_subbyte = SUBREG_BYTE (operand0);
3837 op0_subbyte /= GET_MODE_SIZE (SImode);
3838 op0_subbyte *= GET_MODE_SIZE (SImode);
3839 operand0 = XEXP (operand0, 0);
3841 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3843 if (GET_MODE (operand0) != SImode)
3844 operand0 = gen_rtx_SUBREG (SImode, operand0, op0_subbyte);
3845 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
3849 (define_insn "*sign_extendqihi2_insn"
3850 [(set (match_operand:HI 0 "register_operand" "=r")
3851 (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
3854 [(set_attr "type" "sload")
3855 (set_attr "us3load_type" "3cycle")])
3857 (define_expand "extendqisi2"
3858 [(set (match_operand:SI 0 "register_operand" "")
3859 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
3862 rtx temp = gen_reg_rtx (SImode);
3863 rtx shift_24 = GEN_INT (24);
3864 int op1_subbyte = 0;
3866 if (GET_CODE (operand1) == SUBREG)
3868 op1_subbyte = SUBREG_BYTE (operand1);
3869 op1_subbyte /= GET_MODE_SIZE (SImode);
3870 op1_subbyte *= GET_MODE_SIZE (SImode);
3871 operand1 = XEXP (operand1, 0);
3874 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3876 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
3880 (define_insn "*sign_extendqisi2_insn"
3881 [(set (match_operand:SI 0 "register_operand" "=r")
3882 (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
3885 [(set_attr "type" "sload")
3886 (set_attr "us3load_type" "3cycle")])
3888 (define_expand "extendqidi2"
3889 [(set (match_operand:DI 0 "register_operand" "")
3890 (sign_extend:DI (match_operand:QI 1 "register_operand" "")))]
3893 rtx temp = gen_reg_rtx (DImode);
3894 rtx shift_56 = GEN_INT (56);
3895 int op1_subbyte = 0;
3897 if (GET_CODE (operand1) == SUBREG)
3899 op1_subbyte = SUBREG_BYTE (operand1);
3900 op1_subbyte /= GET_MODE_SIZE (DImode);
3901 op1_subbyte *= GET_MODE_SIZE (DImode);
3902 operand1 = XEXP (operand1, 0);
3905 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
3907 emit_insn (gen_ashrdi3 (operand0, temp, shift_56));
3911 (define_insn "*sign_extendqidi2_insn"
3912 [(set (match_operand:DI 0 "register_operand" "=r")
3913 (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
3916 [(set_attr "type" "sload")
3917 (set_attr "us3load_type" "3cycle")])
3919 (define_expand "extendhidi2"
3920 [(set (match_operand:DI 0 "register_operand" "")
3921 (sign_extend:DI (match_operand:HI 1 "register_operand" "")))]
3924 rtx temp = gen_reg_rtx (DImode);
3925 rtx shift_48 = GEN_INT (48);
3926 int op1_subbyte = 0;
3928 if (GET_CODE (operand1) == SUBREG)
3930 op1_subbyte = SUBREG_BYTE (operand1);
3931 op1_subbyte /= GET_MODE_SIZE (DImode);
3932 op1_subbyte *= GET_MODE_SIZE (DImode);
3933 operand1 = XEXP (operand1, 0);
3936 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
3938 emit_insn (gen_ashrdi3 (operand0, temp, shift_48));
3942 (define_insn "*sign_extendhidi2_insn"
3943 [(set (match_operand:DI 0 "register_operand" "=r")
3944 (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
3947 [(set_attr "type" "sload")
3948 (set_attr "us3load_type" "3cycle")])
3950 (define_expand "extendsidi2"
3951 [(set (match_operand:DI 0 "register_operand" "")
3952 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
3956 (define_insn "*sign_extendsidi2_insn"
3957 [(set (match_operand:DI 0 "register_operand" "=r,r")
3958 (sign_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
3963 [(set_attr "type" "shift,sload")
3964 (set_attr "us3load_type" "*,3cycle")])
3967 ;; Special pattern for optimizing bit-field compares. This is needed
3968 ;; because combine uses this as a canonical form.
3970 (define_insn "*cmp_zero_extract"
3973 (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
3974 (match_operand:SI 1 "small_int_operand" "I")
3975 (match_operand:SI 2 "small_int_operand" "I"))
3977 "INTVAL (operands[2]) > 19"
3979 int len = INTVAL (operands[1]);
3980 int pos = 32 - INTVAL (operands[2]) - len;
3981 HOST_WIDE_INT mask = ((1 << len) - 1) << pos;
3982 operands[1] = GEN_INT (mask);
3983 return "andcc\t%0, %1, %%g0";
3985 [(set_attr "type" "compare")])
3987 (define_insn "*cmp_zero_extract_sp64"
3990 (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
3991 (match_operand:SI 1 "small_int_operand" "I")
3992 (match_operand:SI 2 "small_int_operand" "I"))
3994 "TARGET_ARCH64 && INTVAL (operands[2]) > 51"
3996 int len = INTVAL (operands[1]);
3997 int pos = 64 - INTVAL (operands[2]) - len;
3998 HOST_WIDE_INT mask = (((unsigned HOST_WIDE_INT) 1 << len) - 1) << pos;
3999 operands[1] = GEN_INT (mask);
4000 return "andcc\t%0, %1, %%g0";
4002 [(set_attr "type" "compare")])
4005 ;; Conversions between float, double and long double.
4007 (define_insn "extendsfdf2"
4008 [(set (match_operand:DF 0 "register_operand" "=e")
4010 (match_operand:SF 1 "register_operand" "f")))]
4013 [(set_attr "type" "fp")
4014 (set_attr "fptype" "double")])
4016 (define_expand "extendsftf2"
4017 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4019 (match_operand:SF 1 "register_operand" "")))]
4020 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4021 "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
4023 (define_insn "*extendsftf2_hq"
4024 [(set (match_operand:TF 0 "register_operand" "=e")
4026 (match_operand:SF 1 "register_operand" "f")))]
4027 "TARGET_FPU && TARGET_HARD_QUAD"
4029 [(set_attr "type" "fp")])
4031 (define_expand "extenddftf2"
4032 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4034 (match_operand:DF 1 "register_operand" "")))]
4035 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4036 "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
4038 (define_insn "*extenddftf2_hq"
4039 [(set (match_operand:TF 0 "register_operand" "=e")
4041 (match_operand:DF 1 "register_operand" "e")))]
4042 "TARGET_FPU && TARGET_HARD_QUAD"
4044 [(set_attr "type" "fp")])
4046 (define_insn "truncdfsf2"
4047 [(set (match_operand:SF 0 "register_operand" "=f")
4049 (match_operand:DF 1 "register_operand" "e")))]
4052 [(set_attr "type" "fp")
4053 (set_attr "fptype" "double")])
4055 (define_expand "trunctfsf2"
4056 [(set (match_operand:SF 0 "register_operand" "")
4058 (match_operand:TF 1 "general_operand" "")))]
4059 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4060 "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
4062 (define_insn "*trunctfsf2_hq"
4063 [(set (match_operand:SF 0 "register_operand" "=f")
4065 (match_operand:TF 1 "register_operand" "e")))]
4066 "TARGET_FPU && TARGET_HARD_QUAD"
4068 [(set_attr "type" "fp")])
4070 (define_expand "trunctfdf2"
4071 [(set (match_operand:DF 0 "register_operand" "")
4073 (match_operand:TF 1 "general_operand" "")))]
4074 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4075 "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
4077 (define_insn "*trunctfdf2_hq"
4078 [(set (match_operand:DF 0 "register_operand" "=e")
4080 (match_operand:TF 1 "register_operand" "e")))]
4081 "TARGET_FPU && TARGET_HARD_QUAD"
4083 [(set_attr "type" "fp")])
4086 ;; Conversion between fixed point and floating point.
4088 (define_insn "floatsisf2"
4089 [(set (match_operand:SF 0 "register_operand" "=f")
4090 (float:SF (match_operand:SI 1 "register_operand" "f")))]
4093 [(set_attr "type" "fp")
4094 (set_attr "fptype" "double")])
4096 (define_insn "floatsidf2"
4097 [(set (match_operand:DF 0 "register_operand" "=e")
4098 (float:DF (match_operand:SI 1 "register_operand" "f")))]
4101 [(set_attr "type" "fp")
4102 (set_attr "fptype" "double")])
4104 (define_expand "floatsitf2"
4105 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4106 (float:TF (match_operand:SI 1 "register_operand" "")))]
4107 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4108 "emit_tfmode_cvt (FLOAT, operands); DONE;")
4110 (define_insn "*floatsitf2_hq"
4111 [(set (match_operand:TF 0 "register_operand" "=e")
4112 (float:TF (match_operand:SI 1 "register_operand" "f")))]
4113 "TARGET_FPU && TARGET_HARD_QUAD"
4115 [(set_attr "type" "fp")])
4117 (define_expand "floatunssitf2"
4118 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4119 (unsigned_float:TF (match_operand:SI 1 "register_operand" "")))]
4120 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4121 "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
4123 ;; Now the same for 64 bit sources.
4125 (define_insn "floatdisf2"
4126 [(set (match_operand:SF 0 "register_operand" "=f")
4127 (float:SF (match_operand:DI 1 "register_operand" "e")))]
4128 "TARGET_V9 && TARGET_FPU"
4130 [(set_attr "type" "fp")
4131 (set_attr "fptype" "double")])
4133 (define_expand "floatunsdisf2"
4134 [(use (match_operand:SF 0 "register_operand" ""))
4135 (use (match_operand:DI 1 "general_operand" ""))]
4136 "TARGET_ARCH64 && TARGET_FPU"
4137 "sparc_emit_floatunsdi (operands, SFmode); DONE;")
4139 (define_insn "floatdidf2"
4140 [(set (match_operand:DF 0 "register_operand" "=e")
4141 (float:DF (match_operand:DI 1 "register_operand" "e")))]
4142 "TARGET_V9 && TARGET_FPU"
4144 [(set_attr "type" "fp")
4145 (set_attr "fptype" "double")])
4147 (define_expand "floatunsdidf2"
4148 [(use (match_operand:DF 0 "register_operand" ""))
4149 (use (match_operand:DI 1 "general_operand" ""))]
4150 "TARGET_ARCH64 && TARGET_FPU"
4151 "sparc_emit_floatunsdi (operands, DFmode); DONE;")
4153 (define_expand "floatditf2"
4154 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4155 (float:TF (match_operand:DI 1 "register_operand" "")))]
4156 "TARGET_FPU && TARGET_V9 && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4157 "emit_tfmode_cvt (FLOAT, operands); DONE;")
4159 (define_insn "*floatditf2_hq"
4160 [(set (match_operand:TF 0 "register_operand" "=e")
4161 (float:TF (match_operand:DI 1 "register_operand" "e")))]
4162 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
4164 [(set_attr "type" "fp")])
4166 (define_expand "floatunsditf2"
4167 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4168 (unsigned_float:TF (match_operand:DI 1 "register_operand" "")))]
4169 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4170 "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
4172 ;; Convert a float to an actual integer.
4173 ;; Truncation is performed as part of the conversion.
4175 (define_insn "fix_truncsfsi2"
4176 [(set (match_operand:SI 0 "register_operand" "=f")
4177 (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
4180 [(set_attr "type" "fp")
4181 (set_attr "fptype" "double")])
4183 (define_insn "fix_truncdfsi2"
4184 [(set (match_operand:SI 0 "register_operand" "=f")
4185 (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
4188 [(set_attr "type" "fp")
4189 (set_attr "fptype" "double")])
4191 (define_expand "fix_trunctfsi2"
4192 [(set (match_operand:SI 0 "register_operand" "")
4193 (fix:SI (match_operand:TF 1 "general_operand" "")))]
4194 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4195 "emit_tfmode_cvt (FIX, operands); DONE;")
4197 (define_insn "*fix_trunctfsi2_hq"
4198 [(set (match_operand:SI 0 "register_operand" "=f")
4199 (fix:SI (match_operand:TF 1 "register_operand" "e")))]
4200 "TARGET_FPU && TARGET_HARD_QUAD"
4202 [(set_attr "type" "fp")])
4204 (define_expand "fixuns_trunctfsi2"
4205 [(set (match_operand:SI 0 "register_operand" "")
4206 (unsigned_fix:SI (match_operand:TF 1 "general_operand" "")))]
4207 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4208 "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
4210 ;; Now the same, for V9 targets
4212 (define_insn "fix_truncsfdi2"
4213 [(set (match_operand:DI 0 "register_operand" "=e")
4214 (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
4215 "TARGET_V9 && TARGET_FPU"
4217 [(set_attr "type" "fp")
4218 (set_attr "fptype" "double")])
4220 (define_expand "fixuns_truncsfdi2"
4221 [(use (match_operand:DI 0 "register_operand" ""))
4222 (use (match_operand:SF 1 "general_operand" ""))]
4223 "TARGET_ARCH64 && TARGET_FPU"
4224 "sparc_emit_fixunsdi (operands, SFmode); DONE;")
4226 (define_insn "fix_truncdfdi2"
4227 [(set (match_operand:DI 0 "register_operand" "=e")
4228 (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
4229 "TARGET_V9 && TARGET_FPU"
4231 [(set_attr "type" "fp")
4232 (set_attr "fptype" "double")])
4234 (define_expand "fixuns_truncdfdi2"
4235 [(use (match_operand:DI 0 "register_operand" ""))
4236 (use (match_operand:DF 1 "general_operand" ""))]
4237 "TARGET_ARCH64 && TARGET_FPU"
4238 "sparc_emit_fixunsdi (operands, DFmode); DONE;")
4240 (define_expand "fix_trunctfdi2"
4241 [(set (match_operand:DI 0 "register_operand" "")
4242 (fix:DI (match_operand:TF 1 "general_operand" "")))]
4243 "TARGET_V9 && TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4244 "emit_tfmode_cvt (FIX, operands); DONE;")
4246 (define_insn "*fix_trunctfdi2_hq"
4247 [(set (match_operand:DI 0 "register_operand" "=e")
4248 (fix:DI (match_operand:TF 1 "register_operand" "e")))]
4249 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
4251 [(set_attr "type" "fp")])
4253 (define_expand "fixuns_trunctfdi2"
4254 [(set (match_operand:DI 0 "register_operand" "")
4255 (unsigned_fix:DI (match_operand:TF 1 "general_operand" "")))]
4256 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4257 "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
4260 ;; Integer addition/subtraction instructions.
4262 (define_expand "adddi3"
4263 [(set (match_operand:DI 0 "register_operand" "")
4264 (plus:DI (match_operand:DI 1 "register_operand" "")
4265 (match_operand:DI 2 "arith_double_add_operand" "")))]
4268 if (! TARGET_ARCH64)
4270 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
4271 gen_rtx_SET (VOIDmode, operands[0],
4272 gen_rtx_PLUS (DImode, operands[1],
4274 gen_rtx_CLOBBER (VOIDmode,
4275 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
4280 (define_insn_and_split "adddi3_insn_sp32"
4281 [(set (match_operand:DI 0 "register_operand" "=r")
4282 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
4283 (match_operand:DI 2 "arith_double_operand" "rHI")))
4284 (clobber (reg:CC 100))]
4287 "&& reload_completed"
4288 [(parallel [(set (reg:CC_NOOV 100)
4289 (compare:CC_NOOV (plus:SI (match_dup 4)
4293 (plus:SI (match_dup 4) (match_dup 5)))])
4295 (plus:SI (plus:SI (match_dup 7)
4297 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4299 operands[3] = gen_lowpart (SImode, operands[0]);
4300 operands[4] = gen_lowpart (SImode, operands[1]);
4301 operands[5] = gen_lowpart (SImode, operands[2]);
4302 operands[6] = gen_highpart (SImode, operands[0]);
4303 operands[7] = gen_highpart_mode (SImode, DImode, operands[1]);
4304 #if HOST_BITS_PER_WIDE_INT == 32
4305 if (GET_CODE (operands[2]) == CONST_INT)
4307 if (INTVAL (operands[2]) < 0)
4308 operands[8] = constm1_rtx;
4310 operands[8] = const0_rtx;
4314 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
4316 [(set_attr "length" "2")])
4318 ;; LTU here means "carry set"
4320 [(set (match_operand:SI 0 "register_operand" "=r")
4321 (plus:SI (plus:SI (match_operand:SI 1 "arith_operand" "%r")
4322 (match_operand:SI 2 "arith_operand" "rI"))
4323 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4326 [(set_attr "type" "ialuX")])
4328 (define_insn_and_split "*addx_extend_sp32"
4329 [(set (match_operand:DI 0 "register_operand" "=r")
4330 (zero_extend:DI (plus:SI (plus:SI
4331 (match_operand:SI 1 "register_or_zero_operand" "%rJ")
4332 (match_operand:SI 2 "arith_operand" "rI"))
4333 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4336 "&& reload_completed"
4337 [(set (match_dup 3) (plus:SI (plus:SI (match_dup 1) (match_dup 2))
4338 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
4339 (set (match_dup 4) (const_int 0))]
4340 "operands[3] = gen_lowpart (SImode, operands[0]);
4341 operands[4] = gen_highpart_mode (SImode, DImode, operands[1]);"
4342 [(set_attr "length" "2")])
4344 (define_insn "*addx_extend_sp64"
4345 [(set (match_operand:DI 0 "register_operand" "=r")
4346 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ")
4347 (match_operand:SI 2 "arith_operand" "rI"))
4348 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4351 [(set_attr "type" "ialuX")])
4353 (define_insn_and_split ""
4354 [(set (match_operand:DI 0 "register_operand" "=r")
4355 (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4356 (match_operand:DI 2 "register_operand" "r")))
4357 (clobber (reg:CC 100))]
4360 "&& reload_completed"
4361 [(parallel [(set (reg:CC_NOOV 100)
4362 (compare:CC_NOOV (plus:SI (match_dup 3) (match_dup 1))
4364 (set (match_dup 5) (plus:SI (match_dup 3) (match_dup 1)))])
4366 (plus:SI (plus:SI (match_dup 4) (const_int 0))
4367 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4368 "operands[3] = gen_lowpart (SImode, operands[2]);
4369 operands[4] = gen_highpart (SImode, operands[2]);
4370 operands[5] = gen_lowpart (SImode, operands[0]);
4371 operands[6] = gen_highpart (SImode, operands[0]);"
4372 [(set_attr "length" "2")])
4374 (define_insn "*adddi3_sp64"
4375 [(set (match_operand:DI 0 "register_operand" "=r,r")
4376 (plus:DI (match_operand:DI 1 "register_operand" "%r,r")
4377 (match_operand:DI 2 "arith_add_operand" "rI,O")))]
4383 (define_insn "addsi3"
4384 [(set (match_operand:SI 0 "register_operand" "=r,r,d")
4385 (plus:SI (match_operand:SI 1 "register_operand" "%r,r,d")
4386 (match_operand:SI 2 "arith_add_operand" "rI,O,d")))]
4391 fpadd32s\t%1, %2, %0"
4392 [(set_attr "type" "*,*,fga")
4393 (set_attr "fptype" "*,*,single")])
4395 (define_insn "*cmp_cc_plus"
4396 [(set (reg:CC_NOOV 100)
4397 (compare:CC_NOOV (plus:SI (match_operand:SI 0 "arith_operand" "%r")
4398 (match_operand:SI 1 "arith_operand" "rI"))
4401 "addcc\t%0, %1, %%g0"
4402 [(set_attr "type" "compare")])
4404 (define_insn "*cmp_ccx_plus"
4405 [(set (reg:CCX_NOOV 100)
4406 (compare:CCX_NOOV (plus:DI (match_operand:DI 0 "arith_operand" "%r")
4407 (match_operand:DI 1 "arith_operand" "rI"))
4410 "addcc\t%0, %1, %%g0"
4411 [(set_attr "type" "compare")])
4413 (define_insn "*cmp_cc_plus_set"
4414 [(set (reg:CC_NOOV 100)
4415 (compare:CC_NOOV (plus:SI (match_operand:SI 1 "arith_operand" "%r")
4416 (match_operand:SI 2 "arith_operand" "rI"))
4418 (set (match_operand:SI 0 "register_operand" "=r")
4419 (plus:SI (match_dup 1) (match_dup 2)))]
4422 [(set_attr "type" "compare")])
4424 (define_insn "*cmp_ccx_plus_set"
4425 [(set (reg:CCX_NOOV 100)
4426 (compare:CCX_NOOV (plus:DI (match_operand:DI 1 "arith_operand" "%r")
4427 (match_operand:DI 2 "arith_operand" "rI"))
4429 (set (match_operand:DI 0 "register_operand" "=r")
4430 (plus:DI (match_dup 1) (match_dup 2)))]
4433 [(set_attr "type" "compare")])
4435 (define_expand "subdi3"
4436 [(set (match_operand:DI 0 "register_operand" "")
4437 (minus:DI (match_operand:DI 1 "register_operand" "")
4438 (match_operand:DI 2 "arith_double_add_operand" "")))]
4441 if (! TARGET_ARCH64)
4443 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
4444 gen_rtx_SET (VOIDmode, operands[0],
4445 gen_rtx_MINUS (DImode, operands[1],
4447 gen_rtx_CLOBBER (VOIDmode,
4448 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
4453 (define_insn_and_split "subdi3_insn_sp32"
4454 [(set (match_operand:DI 0 "register_operand" "=r")
4455 (minus:DI (match_operand:DI 1 "register_operand" "r")
4456 (match_operand:DI 2 "arith_double_operand" "rHI")))
4457 (clobber (reg:CC 100))]
4460 "&& reload_completed"
4461 [(parallel [(set (reg:CC_NOOV 100)
4462 (compare:CC_NOOV (minus:SI (match_dup 4)
4466 (minus:SI (match_dup 4) (match_dup 5)))])
4468 (minus:SI (minus:SI (match_dup 7)
4470 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4472 operands[3] = gen_lowpart (SImode, operands[0]);
4473 operands[4] = gen_lowpart (SImode, operands[1]);
4474 operands[5] = gen_lowpart (SImode, operands[2]);
4475 operands[6] = gen_highpart (SImode, operands[0]);
4476 operands[7] = gen_highpart (SImode, operands[1]);
4477 #if HOST_BITS_PER_WIDE_INT == 32
4478 if (GET_CODE (operands[2]) == CONST_INT)
4480 if (INTVAL (operands[2]) < 0)
4481 operands[8] = constm1_rtx;
4483 operands[8] = const0_rtx;
4487 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
4489 [(set_attr "length" "2")])
4491 ;; LTU here means "carry set"
4493 [(set (match_operand:SI 0 "register_operand" "=r")
4494 (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
4495 (match_operand:SI 2 "arith_operand" "rI"))
4496 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4499 [(set_attr "type" "ialuX")])
4501 (define_insn "*subx_extend_sp64"
4502 [(set (match_operand:DI 0 "register_operand" "=r")
4503 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
4504 (match_operand:SI 2 "arith_operand" "rI"))
4505 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4508 [(set_attr "type" "ialuX")])
4510 (define_insn_and_split "*subx_extend"
4511 [(set (match_operand:DI 0 "register_operand" "=r")
4512 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
4513 (match_operand:SI 2 "arith_operand" "rI"))
4514 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4517 "&& reload_completed"
4518 [(set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 2))
4519 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
4520 (set (match_dup 4) (const_int 0))]
4521 "operands[3] = gen_lowpart (SImode, operands[0]);
4522 operands[4] = gen_highpart (SImode, operands[0]);"
4523 [(set_attr "length" "2")])
4525 (define_insn_and_split ""
4526 [(set (match_operand:DI 0 "register_operand" "=r")
4527 (minus:DI (match_operand:DI 1 "register_operand" "r")
4528 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))
4529 (clobber (reg:CC 100))]
4532 "&& reload_completed"
4533 [(parallel [(set (reg:CC_NOOV 100)
4534 (compare:CC_NOOV (minus:SI (match_dup 3) (match_dup 2))
4536 (set (match_dup 5) (minus:SI (match_dup 3) (match_dup 2)))])
4538 (minus:SI (minus:SI (match_dup 4) (const_int 0))
4539 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4540 "operands[3] = gen_lowpart (SImode, operands[1]);
4541 operands[4] = gen_highpart (SImode, operands[1]);
4542 operands[5] = gen_lowpart (SImode, operands[0]);
4543 operands[6] = gen_highpart (SImode, operands[0]);"
4544 [(set_attr "length" "2")])
4546 (define_insn "*subdi3_sp64"
4547 [(set (match_operand:DI 0 "register_operand" "=r,r")
4548 (minus:DI (match_operand:DI 1 "register_operand" "r,r")
4549 (match_operand:DI 2 "arith_add_operand" "rI,O")))]
4555 (define_insn "subsi3"
4556 [(set (match_operand:SI 0 "register_operand" "=r,r,d")
4557 (minus:SI (match_operand:SI 1 "register_operand" "r,r,d")
4558 (match_operand:SI 2 "arith_add_operand" "rI,O,d")))]
4563 fpsub32s\t%1, %2, %0"
4564 [(set_attr "type" "*,*,fga")
4565 (set_attr "fptype" "*,*,single")])
4567 (define_insn "*cmp_minus_cc"
4568 [(set (reg:CC_NOOV 100)
4569 (compare:CC_NOOV (minus:SI (match_operand:SI 0 "register_or_zero_operand" "rJ")
4570 (match_operand:SI 1 "arith_operand" "rI"))
4573 "subcc\t%r0, %1, %%g0"
4574 [(set_attr "type" "compare")])
4576 (define_insn "*cmp_minus_ccx"
4577 [(set (reg:CCX_NOOV 100)
4578 (compare:CCX_NOOV (minus:DI (match_operand:DI 0 "register_operand" "r")
4579 (match_operand:DI 1 "arith_operand" "rI"))
4582 "subcc\t%0, %1, %%g0"
4583 [(set_attr "type" "compare")])
4585 (define_insn "cmp_minus_cc_set"
4586 [(set (reg:CC_NOOV 100)
4587 (compare:CC_NOOV (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
4588 (match_operand:SI 2 "arith_operand" "rI"))
4590 (set (match_operand:SI 0 "register_operand" "=r")
4591 (minus:SI (match_dup 1) (match_dup 2)))]
4593 "subcc\t%r1, %2, %0"
4594 [(set_attr "type" "compare")])
4596 (define_insn "*cmp_minus_ccx_set"
4597 [(set (reg:CCX_NOOV 100)
4598 (compare:CCX_NOOV (minus:DI (match_operand:DI 1 "register_operand" "r")
4599 (match_operand:DI 2 "arith_operand" "rI"))
4601 (set (match_operand:DI 0 "register_operand" "=r")
4602 (minus:DI (match_dup 1) (match_dup 2)))]
4605 [(set_attr "type" "compare")])
4608 ;; Integer multiply/divide instructions.
4610 ;; The 32-bit multiply/divide instructions are deprecated on v9, but at
4611 ;; least in UltraSPARC I, II and IIi it is a win tick-wise.
4613 (define_insn "mulsi3"
4614 [(set (match_operand:SI 0 "register_operand" "=r")
4615 (mult:SI (match_operand:SI 1 "arith_operand" "%r")
4616 (match_operand:SI 2 "arith_operand" "rI")))]
4619 [(set_attr "type" "imul")])
4621 (define_expand "muldi3"
4622 [(set (match_operand:DI 0 "register_operand" "")
4623 (mult:DI (match_operand:DI 1 "arith_operand" "")
4624 (match_operand:DI 2 "arith_operand" "")))]
4625 "TARGET_ARCH64 || TARGET_V8PLUS"
4629 emit_insn (gen_muldi3_v8plus (operands[0], operands[1], operands[2]));
4634 (define_insn "*muldi3_sp64"
4635 [(set (match_operand:DI 0 "register_operand" "=r")
4636 (mult:DI (match_operand:DI 1 "arith_operand" "%r")
4637 (match_operand:DI 2 "arith_operand" "rI")))]
4640 [(set_attr "type" "imul")])
4642 ;; V8plus wide multiply.
4644 (define_insn "muldi3_v8plus"
4645 [(set (match_operand:DI 0 "register_operand" "=r,h")
4646 (mult:DI (match_operand:DI 1 "arith_operand" "%r,0")
4647 (match_operand:DI 2 "arith_operand" "rI,rI")))
4648 (clobber (match_scratch:SI 3 "=&h,X"))
4649 (clobber (match_scratch:SI 4 "=&h,X"))]
4652 if (sparc_check_64 (operands[1], insn) <= 0)
4653 output_asm_insn ("srl\t%L1, 0, %L1", operands);
4654 if (which_alternative == 1)
4655 output_asm_insn ("sllx\t%H1, 32, %H1", operands);
4656 if (GET_CODE (operands[2]) == CONST_INT)
4658 if (which_alternative == 1)
4659 return "or\t%L1, %H1, %H1\n\tmulx\t%H1, %2, %L0\;srlx\t%L0, 32, %H0";
4661 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";
4663 else if (rtx_equal_p (operands[1], operands[2]))
4665 if (which_alternative == 1)
4666 return "or\t%L1, %H1, %H1\n\tmulx\t%H1, %H1, %L0\;srlx\t%L0, 32, %H0";
4668 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";
4670 if (sparc_check_64 (operands[2], insn) <= 0)
4671 output_asm_insn ("srl\t%L2, 0, %L2", operands);
4672 if (which_alternative == 1)
4673 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";
4675 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";
4677 [(set_attr "type" "multi")
4678 (set_attr "length" "9,8")])
4680 (define_insn "*cmp_mul_set"
4682 (compare:CC (mult:SI (match_operand:SI 1 "arith_operand" "%r")
4683 (match_operand:SI 2 "arith_operand" "rI"))
4685 (set (match_operand:SI 0 "register_operand" "=r")
4686 (mult:SI (match_dup 1) (match_dup 2)))]
4687 "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS"
4688 "smulcc\t%1, %2, %0"
4689 [(set_attr "type" "imul")])
4691 (define_expand "mulsidi3"
4692 [(set (match_operand:DI 0 "register_operand" "")
4693 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
4694 (sign_extend:DI (match_operand:SI 2 "arith_operand" ""))))]
4697 if (CONSTANT_P (operands[2]))
4700 emit_insn (gen_const_mulsidi3_v8plus (operands[0], operands[1],
4702 else if (TARGET_ARCH32)
4703 emit_insn (gen_const_mulsidi3_sp32 (operands[0], operands[1],
4706 emit_insn (gen_const_mulsidi3_sp64 (operands[0], operands[1],
4712 emit_insn (gen_mulsidi3_v8plus (operands[0], operands[1], operands[2]));
4717 ;; V9 puts the 64-bit product in a 64-bit register. Only out or global
4718 ;; registers can hold 64-bit values in the V8plus environment.
4720 (define_insn "mulsidi3_v8plus"
4721 [(set (match_operand:DI 0 "register_operand" "=h,r")
4722 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4723 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
4724 (clobber (match_scratch:SI 3 "=X,&h"))]
4727 smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
4728 smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4729 [(set_attr "type" "multi")
4730 (set_attr "length" "2,3")])
4733 (define_insn "const_mulsidi3_v8plus"
4734 [(set (match_operand:DI 0 "register_operand" "=h,r")
4735 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4736 (match_operand:DI 2 "small_int_operand" "I,I")))
4737 (clobber (match_scratch:SI 3 "=X,&h"))]
4740 smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
4741 smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4742 [(set_attr "type" "multi")
4743 (set_attr "length" "2,3")])
4746 (define_insn "*mulsidi3_sp32"
4747 [(set (match_operand:DI 0 "register_operand" "=r")
4748 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4749 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4752 return TARGET_SPARCLET
4753 ? "smuld\t%1, %2, %L0"
4754 : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
4757 (if_then_else (eq_attr "isa" "sparclet")
4758 (const_string "imul") (const_string "multi")))
4759 (set (attr "length")
4760 (if_then_else (eq_attr "isa" "sparclet")
4761 (const_int 1) (const_int 2)))])
4763 (define_insn "*mulsidi3_sp64"
4764 [(set (match_operand:DI 0 "register_operand" "=r")
4765 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4766 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4767 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4769 [(set_attr "type" "imul")])
4771 ;; Extra pattern, because sign_extend of a constant isn't valid.
4774 (define_insn "const_mulsidi3_sp32"
4775 [(set (match_operand:DI 0 "register_operand" "=r")
4776 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4777 (match_operand:DI 2 "small_int_operand" "I")))]
4780 return TARGET_SPARCLET
4781 ? "smuld\t%1, %2, %L0"
4782 : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
4785 (if_then_else (eq_attr "isa" "sparclet")
4786 (const_string "imul") (const_string "multi")))
4787 (set (attr "length")
4788 (if_then_else (eq_attr "isa" "sparclet")
4789 (const_int 1) (const_int 2)))])
4791 (define_insn "const_mulsidi3_sp64"
4792 [(set (match_operand:DI 0 "register_operand" "=r")
4793 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4794 (match_operand:DI 2 "small_int_operand" "I")))]
4795 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4797 [(set_attr "type" "imul")])
4799 (define_expand "smulsi3_highpart"
4800 [(set (match_operand:SI 0 "register_operand" "")
4802 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
4803 (sign_extend:DI (match_operand:SI 2 "arith_operand" "")))
4805 "TARGET_HARD_MUL && TARGET_ARCH32"
4807 if (CONSTANT_P (operands[2]))
4811 emit_insn (gen_const_smulsi3_highpart_v8plus (operands[0],
4817 emit_insn (gen_const_smulsi3_highpart (operands[0], operands[1], operands[2]));
4822 emit_insn (gen_smulsi3_highpart_v8plus (operands[0], operands[1],
4823 operands[2], GEN_INT (32)));
4829 (define_insn "smulsi3_highpart_v8plus"
4830 [(set (match_operand:SI 0 "register_operand" "=h,r")
4832 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4833 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
4834 (match_operand:SI 3 "small_int_operand" "I,I"))))
4835 (clobber (match_scratch:SI 4 "=X,&h"))]
4838 smul\t%1, %2, %0\;srlx\t%0, %3, %0
4839 smul\t%1, %2, %4\;srlx\t%4, %3, %0"
4840 [(set_attr "type" "multi")
4841 (set_attr "length" "2")])
4843 ;; The combiner changes TRUNCATE in the previous pattern to SUBREG.
4846 [(set (match_operand:SI 0 "register_operand" "=h,r")
4849 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4850 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
4851 (match_operand:SI 3 "small_int_operand" "I,I"))
4853 (clobber (match_scratch:SI 4 "=X,&h"))]
4856 smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
4857 smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
4858 [(set_attr "type" "multi")
4859 (set_attr "length" "2")])
4862 (define_insn "const_smulsi3_highpart_v8plus"
4863 [(set (match_operand:SI 0 "register_operand" "=h,r")
4865 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4866 (match_operand:DI 2 "small_int_operand" "I,I"))
4867 (match_operand:SI 3 "small_int_operand" "I,I"))))
4868 (clobber (match_scratch:SI 4 "=X,&h"))]
4871 smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
4872 smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
4873 [(set_attr "type" "multi")
4874 (set_attr "length" "2")])
4877 (define_insn "*smulsi3_highpart_sp32"
4878 [(set (match_operand:SI 0 "register_operand" "=r")
4880 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4881 (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
4884 "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
4885 [(set_attr "type" "multi")
4886 (set_attr "length" "2")])
4889 (define_insn "const_smulsi3_highpart"
4890 [(set (match_operand:SI 0 "register_operand" "=r")
4892 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4893 (match_operand:DI 2 "small_int_operand" "i"))
4896 "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
4897 [(set_attr "type" "multi")
4898 (set_attr "length" "2")])
4900 (define_expand "umulsidi3"
4901 [(set (match_operand:DI 0 "register_operand" "")
4902 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
4903 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" ""))))]
4906 if (CONSTANT_P (operands[2]))
4909 emit_insn (gen_const_umulsidi3_v8plus (operands[0], operands[1],
4911 else if (TARGET_ARCH32)
4912 emit_insn (gen_const_umulsidi3_sp32 (operands[0], operands[1],
4915 emit_insn (gen_const_umulsidi3_sp64 (operands[0], operands[1],
4921 emit_insn (gen_umulsidi3_v8plus (operands[0], operands[1], operands[2]));
4927 (define_insn "umulsidi3_v8plus"
4928 [(set (match_operand:DI 0 "register_operand" "=h,r")
4929 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4930 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
4931 (clobber (match_scratch:SI 3 "=X,&h"))]
4934 umul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
4935 umul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4936 [(set_attr "type" "multi")
4937 (set_attr "length" "2,3")])
4940 (define_insn "*umulsidi3_sp32"
4941 [(set (match_operand:DI 0 "register_operand" "=r")
4942 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4943 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4946 return TARGET_SPARCLET
4947 ? "umuld\t%1, %2, %L0"
4948 : "umul\t%1, %2, %L0\n\trd\t%%y, %H0";
4951 (if_then_else (eq_attr "isa" "sparclet")
4952 (const_string "imul") (const_string "multi")))
4953 (set (attr "length")
4954 (if_then_else (eq_attr "isa" "sparclet")
4955 (const_int 1) (const_int 2)))])
4957 (define_insn "*umulsidi3_sp64"
4958 [(set (match_operand:DI 0 "register_operand" "=r")
4959 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4960 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4961 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4963 [(set_attr "type" "imul")])
4965 ;; Extra pattern, because sign_extend of a constant isn't valid.
4968 (define_insn "const_umulsidi3_sp32"
4969 [(set (match_operand:DI 0 "register_operand" "=r")
4970 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4971 (match_operand:DI 2 "uns_small_int_operand" "")))]
4974 return TARGET_SPARCLET
4975 ? "umuld\t%1, %s2, %L0"
4976 : "umul\t%1, %s2, %L0\n\trd\t%%y, %H0";
4979 (if_then_else (eq_attr "isa" "sparclet")
4980 (const_string "imul") (const_string "multi")))
4981 (set (attr "length")
4982 (if_then_else (eq_attr "isa" "sparclet")
4983 (const_int 1) (const_int 2)))])
4985 (define_insn "const_umulsidi3_sp64"
4986 [(set (match_operand:DI 0 "register_operand" "=r")
4987 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4988 (match_operand:DI 2 "uns_small_int_operand" "")))]
4989 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4991 [(set_attr "type" "imul")])
4994 (define_insn "const_umulsidi3_v8plus"
4995 [(set (match_operand:DI 0 "register_operand" "=h,r")
4996 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4997 (match_operand:DI 2 "uns_small_int_operand" "")))
4998 (clobber (match_scratch:SI 3 "=X,h"))]
5001 umul\t%1, %s2, %L0\n\tsrlx\t%L0, 32, %H0
5002 umul\t%1, %s2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
5003 [(set_attr "type" "multi")
5004 (set_attr "length" "2,3")])
5006 (define_expand "umulsi3_highpart"
5007 [(set (match_operand:SI 0 "register_operand" "")
5009 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
5010 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" "")))
5012 "TARGET_HARD_MUL && TARGET_ARCH32"
5014 if (CONSTANT_P (operands[2]))
5018 emit_insn (gen_const_umulsi3_highpart_v8plus (operands[0],
5024 emit_insn (gen_const_umulsi3_highpart (operands[0], operands[1], operands[2]));
5029 emit_insn (gen_umulsi3_highpart_v8plus (operands[0], operands[1],
5030 operands[2], GEN_INT (32)));
5036 (define_insn "umulsi3_highpart_v8plus"
5037 [(set (match_operand:SI 0 "register_operand" "=h,r")
5039 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5040 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
5041 (match_operand:SI 3 "small_int_operand" "I,I"))))
5042 (clobber (match_scratch:SI 4 "=X,h"))]
5045 umul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
5046 umul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
5047 [(set_attr "type" "multi")
5048 (set_attr "length" "2")])
5051 (define_insn "const_umulsi3_highpart_v8plus"
5052 [(set (match_operand:SI 0 "register_operand" "=h,r")
5054 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5055 (match_operand:DI 2 "uns_small_int_operand" ""))
5056 (match_operand:SI 3 "small_int_operand" "I,I"))))
5057 (clobber (match_scratch:SI 4 "=X,h"))]
5060 umul\t%1, %s2, %0\n\tsrlx\t%0, %3, %0
5061 umul\t%1, %s2, %4\n\tsrlx\t%4, %3, %0"
5062 [(set_attr "type" "multi")
5063 (set_attr "length" "2")])
5066 (define_insn "*umulsi3_highpart_sp32"
5067 [(set (match_operand:SI 0 "register_operand" "=r")
5069 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5070 (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
5073 "umul\t%1, %2, %%g0\n\trd\t%%y, %0"
5074 [(set_attr "type" "multi")
5075 (set_attr "length" "2")])
5078 (define_insn "const_umulsi3_highpart"
5079 [(set (match_operand:SI 0 "register_operand" "=r")
5081 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5082 (match_operand:DI 2 "uns_small_int_operand" ""))
5085 "umul\t%1, %s2, %%g0\n\trd\t%%y, %0"
5086 [(set_attr "type" "multi")
5087 (set_attr "length" "2")])
5089 ;; The V8 architecture specifies that there must be 3 instructions between
5090 ;; a Y register write and a use of it for correct results.
5092 (define_expand "divsi3"
5093 [(parallel [(set (match_operand:SI 0 "register_operand" "=r,r")
5094 (div:SI (match_operand:SI 1 "register_operand" "r,r")
5095 (match_operand:SI 2 "input_operand" "rI,m")))
5096 (clobber (match_scratch:SI 3 "=&r,&r"))])]
5097 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
5101 operands[3] = gen_reg_rtx(SImode);
5102 emit_insn (gen_ashrsi3 (operands[3], operands[1], GEN_INT (31)));
5103 emit_insn (gen_divsi3_sp64 (operands[0], operands[1], operands[2],
5109 (define_insn "divsi3_sp32"
5110 [(set (match_operand:SI 0 "register_operand" "=r,r")
5111 (div:SI (match_operand:SI 1 "register_operand" "r,r")
5112 (match_operand:SI 2 "input_operand" "rI,m")))
5113 (clobber (match_scratch:SI 3 "=&r,&r"))]
5114 "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS)
5117 if (which_alternative == 0)
5119 return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tsdiv\t%1, %2, %0";
5121 return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tnop\n\tnop\n\tnop\n\tsdiv\t%1, %2, %0";
5124 return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tld\t%2, %3\n\tsdiv\t%1, %3, %0";
5126 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";
5128 [(set_attr "type" "multi")
5129 (set (attr "length")
5130 (if_then_else (eq_attr "isa" "v9")
5131 (const_int 4) (const_int 6)))])
5133 (define_insn "divsi3_sp64"
5134 [(set (match_operand:SI 0 "register_operand" "=r")
5135 (div:SI (match_operand:SI 1 "register_operand" "r")
5136 (match_operand:SI 2 "input_operand" "rI")))
5137 (use (match_operand:SI 3 "register_operand" "r"))]
5138 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5139 "wr\t%%g0, %3, %%y\n\tsdiv\t%1, %2, %0"
5140 [(set_attr "type" "multi")
5141 (set_attr "length" "2")])
5143 (define_insn "divdi3"
5144 [(set (match_operand:DI 0 "register_operand" "=r")
5145 (div:DI (match_operand:DI 1 "register_operand" "r")
5146 (match_operand:DI 2 "arith_operand" "rI")))]
5149 [(set_attr "type" "idiv")])
5151 (define_insn "*cmp_sdiv_cc_set"
5153 (compare:CC (div:SI (match_operand:SI 1 "register_operand" "r")
5154 (match_operand:SI 2 "arith_operand" "rI"))
5156 (set (match_operand:SI 0 "register_operand" "=r")
5157 (div:SI (match_dup 1) (match_dup 2)))
5158 (clobber (match_scratch:SI 3 "=&r"))]
5159 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
5162 return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tsdivcc\t%1, %2, %0";
5164 return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tnop\n\tnop\n\tnop\n\tsdivcc\t%1, %2, %0";
5166 [(set_attr "type" "multi")
5167 (set (attr "length")
5168 (if_then_else (eq_attr "isa" "v9")
5169 (const_int 3) (const_int 6)))])
5172 (define_expand "udivsi3"
5173 [(set (match_operand:SI 0 "register_operand" "")
5174 (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "")
5175 (match_operand:SI 2 "input_operand" "")))]
5176 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
5179 ;; The V8 architecture specifies that there must be 3 instructions between
5180 ;; a Y register write and a use of it for correct results.
5182 (define_insn "udivsi3_sp32"
5183 [(set (match_operand:SI 0 "register_operand" "=r,&r,&r")
5184 (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "r,r,m")
5185 (match_operand:SI 2 "input_operand" "rI,m,r")))]
5186 "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS)
5189 output_asm_insn ("wr\t%%g0, %%g0, %%y", operands);
5190 switch (which_alternative)
5193 return "nop\n\tnop\n\tnop\n\tudiv\t%1, %2, %0";
5195 return "ld\t%2, %0\n\tnop\n\tnop\n\tudiv\t%1, %0, %0";
5197 return "ld\t%1, %0\n\tnop\n\tnop\n\tudiv\t%0, %2, %0";
5200 [(set_attr "type" "multi")
5201 (set_attr "length" "5")])
5203 (define_insn "udivsi3_sp64"
5204 [(set (match_operand:SI 0 "register_operand" "=r")
5205 (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "r")
5206 (match_operand:SI 2 "input_operand" "rI")))]
5207 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5208 "wr\t%%g0, 0, %%y\n\tudiv\t%1, %2, %0"
5209 [(set_attr "type" "multi")
5210 (set_attr "length" "2")])
5212 (define_insn "udivdi3"
5213 [(set (match_operand:DI 0 "register_operand" "=r")
5214 (udiv:DI (match_operand:DI 1 "register_operand" "r")
5215 (match_operand:DI 2 "arith_operand" "rI")))]
5218 [(set_attr "type" "idiv")])
5220 (define_insn "*cmp_udiv_cc_set"
5222 (compare:CC (udiv:SI (match_operand:SI 1 "register_operand" "r")
5223 (match_operand:SI 2 "arith_operand" "rI"))
5225 (set (match_operand:SI 0 "register_operand" "=r")
5226 (udiv:SI (match_dup 1) (match_dup 2)))]
5228 || TARGET_DEPRECATED_V8_INSNS"
5231 return "wr\t%%g0, %%g0, %%y\n\tudivcc\t%1, %2, %0";
5233 return "wr\t%%g0, %%g0, %%y\n\tnop\n\tnop\n\tnop\n\tudivcc\t%1, %2, %0";
5235 [(set_attr "type" "multi")
5236 (set (attr "length")
5237 (if_then_else (eq_attr "isa" "v9")
5238 (const_int 2) (const_int 5)))])
5240 ; sparclet multiply/accumulate insns
5242 (define_insn "*smacsi"
5243 [(set (match_operand:SI 0 "register_operand" "=r")
5244 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "%r")
5245 (match_operand:SI 2 "arith_operand" "rI"))
5246 (match_operand:SI 3 "register_operand" "0")))]
5249 [(set_attr "type" "imul")])
5251 (define_insn "*smacdi"
5252 [(set (match_operand:DI 0 "register_operand" "=r")
5253 (plus:DI (mult:DI (sign_extend:DI
5254 (match_operand:SI 1 "register_operand" "%r"))
5256 (match_operand:SI 2 "register_operand" "r")))
5257 (match_operand:DI 3 "register_operand" "0")))]
5259 "smacd\t%1, %2, %L0"
5260 [(set_attr "type" "imul")])
5262 (define_insn "*umacdi"
5263 [(set (match_operand:DI 0 "register_operand" "=r")
5264 (plus:DI (mult:DI (zero_extend:DI
5265 (match_operand:SI 1 "register_operand" "%r"))
5267 (match_operand:SI 2 "register_operand" "r")))
5268 (match_operand:DI 3 "register_operand" "0")))]
5270 "umacd\t%1, %2, %L0"
5271 [(set_attr "type" "imul")])
5274 ;; Boolean instructions.
5276 ;; We define DImode `and' so with DImode `not' we can get
5277 ;; DImode `andn'. Other combinations are possible.
5279 (define_mode_macro V64I [DI V2SI V4HI V8QI])
5280 (define_mode_macro V32I [SI V2HI V4QI])
5282 (define_expand "and<V64I:mode>3"
5283 [(set (match_operand:V64I 0 "register_operand" "")
5284 (and:V64I (match_operand:V64I 1 "arith_double_operand" "")
5285 (match_operand:V64I 2 "arith_double_operand" "")))]
5289 (define_insn "*and<V64I:mode>3_sp32"
5290 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5291 (and:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
5292 (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
5297 [(set_attr "type" "*,fga")
5298 (set_attr "length" "2,*")
5299 (set_attr "fptype" "*,double")])
5301 (define_insn "*and<V64I:mode>3_sp64"
5302 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5303 (and:V64I (match_operand:V64I 1 "arith_operand" "%r,b")
5304 (match_operand:V64I 2 "arith_operand" "rI,b")))]
5309 [(set_attr "type" "*,fga")
5310 (set_attr "fptype" "*,double")])
5312 (define_insn "and<V32I:mode>3"
5313 [(set (match_operand:V32I 0 "register_operand" "=r,d")
5314 (and:V32I (match_operand:V32I 1 "arith_operand" "%r,d")
5315 (match_operand:V32I 2 "arith_operand" "rI,d")))]
5320 [(set_attr "type" "*,fga")
5321 (set_attr "fptype" "*,single")])
5324 [(set (match_operand:SI 0 "register_operand" "")
5325 (and:SI (match_operand:SI 1 "register_operand" "")
5326 (match_operand:SI 2 "const_compl_high_operand" "")))
5327 (clobber (match_operand:SI 3 "register_operand" ""))]
5329 [(set (match_dup 3) (match_dup 4))
5330 (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 1)))]
5332 operands[4] = GEN_INT (~INTVAL (operands[2]));
5335 (define_insn_and_split "*and_not_<V64I:mode>_sp32"
5336 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5337 (and:V64I (not:V64I (match_operand:V64I 1 "register_operand" "%r,b"))
5338 (match_operand:V64I 2 "register_operand" "r,b")))]
5342 fandnot1\t%1, %2, %0"
5343 "&& reload_completed
5344 && ((GET_CODE (operands[0]) == REG
5345 && REGNO (operands[0]) < 32)
5346 || (GET_CODE (operands[0]) == SUBREG
5347 && GET_CODE (SUBREG_REG (operands[0])) == REG
5348 && REGNO (SUBREG_REG (operands[0])) < 32))"
5349 [(set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))
5350 (set (match_dup 6) (and:SI (not:SI (match_dup 7)) (match_dup 8)))]
5351 "operands[3] = gen_highpart (SImode, operands[0]);
5352 operands[4] = gen_highpart (SImode, operands[1]);
5353 operands[5] = gen_highpart (SImode, operands[2]);
5354 operands[6] = gen_lowpart (SImode, operands[0]);
5355 operands[7] = gen_lowpart (SImode, operands[1]);
5356 operands[8] = gen_lowpart (SImode, operands[2]);"
5357 [(set_attr "type" "*,fga")
5358 (set_attr "length" "2,*")
5359 (set_attr "fptype" "*,double")])
5361 (define_insn "*and_not_<V64I:mode>_sp64"
5362 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5363 (and:V64I (not:V64I (match_operand:V64I 1 "register_operand" "%r,b"))
5364 (match_operand:V64I 2 "register_operand" "r,b")))]
5368 fandnot1\t%1, %2, %0"
5369 [(set_attr "type" "*,fga")
5370 (set_attr "fptype" "*,double")])
5372 (define_insn "*and_not_<V32I:mode>"
5373 [(set (match_operand:V32I 0 "register_operand" "=r,d")
5374 (and:V32I (not:V32I (match_operand:V32I 1 "register_operand" "%r,d"))
5375 (match_operand:V32I 2 "register_operand" "r,d")))]
5379 fandnot1s\t%1, %2, %0"
5380 [(set_attr "type" "*,fga")
5381 (set_attr "fptype" "*,single")])
5383 (define_expand "ior<V64I:mode>3"
5384 [(set (match_operand:V64I 0 "register_operand" "")
5385 (ior:V64I (match_operand:V64I 1 "arith_double_operand" "")
5386 (match_operand:V64I 2 "arith_double_operand" "")))]
5390 (define_insn "*ior<V64I:mode>3_sp32"
5391 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5392 (ior:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
5393 (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
5398 [(set_attr "type" "*,fga")
5399 (set_attr "length" "2,*")
5400 (set_attr "fptype" "*,double")])
5402 (define_insn "*ior<V64I:mode>3_sp64"
5403 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5404 (ior:V64I (match_operand:V64I 1 "arith_operand" "%r,b")
5405 (match_operand:V64I 2 "arith_operand" "rI,b")))]
5410 [(set_attr "type" "*,fga")
5411 (set_attr "fptype" "*,double")])
5413 (define_insn "ior<V32I:mode>3"
5414 [(set (match_operand:V32I 0 "register_operand" "=r,d")
5415 (ior:V32I (match_operand:V32I 1 "arith_operand" "%r,d")
5416 (match_operand:V32I 2 "arith_operand" "rI,d")))]
5421 [(set_attr "type" "*,fga")
5422 (set_attr "fptype" "*,single")])
5425 [(set (match_operand:SI 0 "register_operand" "")
5426 (ior:SI (match_operand:SI 1 "register_operand" "")
5427 (match_operand:SI 2 "const_compl_high_operand" "")))
5428 (clobber (match_operand:SI 3 "register_operand" ""))]
5430 [(set (match_dup 3) (match_dup 4))
5431 (set (match_dup 0) (ior:SI (not:SI (match_dup 3)) (match_dup 1)))]
5433 operands[4] = GEN_INT (~INTVAL (operands[2]));
5436 (define_insn_and_split "*or_not_<V64I:mode>_sp32"
5437 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5438 (ior:V64I (not:V64I (match_operand:V64I 1 "register_operand" "r,b"))
5439 (match_operand:V64I 2 "register_operand" "r,b")))]
5443 fornot1\t%1, %2, %0"
5444 "&& reload_completed
5445 && ((GET_CODE (operands[0]) == REG
5446 && REGNO (operands[0]) < 32)
5447 || (GET_CODE (operands[0]) == SUBREG
5448 && GET_CODE (SUBREG_REG (operands[0])) == REG
5449 && REGNO (SUBREG_REG (operands[0])) < 32))"
5450 [(set (match_dup 3) (ior:SI (not:SI (match_dup 4)) (match_dup 5)))
5451 (set (match_dup 6) (ior:SI (not:SI (match_dup 7)) (match_dup 8)))]
5452 "operands[3] = gen_highpart (SImode, operands[0]);
5453 operands[4] = gen_highpart (SImode, operands[1]);
5454 operands[5] = gen_highpart (SImode, operands[2]);
5455 operands[6] = gen_lowpart (SImode, operands[0]);
5456 operands[7] = gen_lowpart (SImode, operands[1]);
5457 operands[8] = gen_lowpart (SImode, operands[2]);"
5458 [(set_attr "type" "*,fga")
5459 (set_attr "length" "2,*")
5460 (set_attr "fptype" "*,double")])
5462 (define_insn "*or_not_<V64I:mode>_sp64"
5463 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5464 (ior:V64I (not:V64I (match_operand:V64I 1 "register_operand" "r,b"))
5465 (match_operand:V64I 2 "register_operand" "r,b")))]
5469 fornot1\t%1, %2, %0"
5470 [(set_attr "type" "*,fga")
5471 (set_attr "fptype" "*,double")])
5473 (define_insn "*or_not_<V32I:mode>"
5474 [(set (match_operand:V32I 0 "register_operand" "=r,d")
5475 (ior:V32I (not:V32I (match_operand:V32I 1 "register_operand" "r,d"))
5476 (match_operand:V32I 2 "register_operand" "r,d")))]
5480 fornot1s\t%1, %2, %0"
5481 [(set_attr "type" "*,fga")
5482 (set_attr "fptype" "*,single")])
5484 (define_expand "xor<V64I:mode>3"
5485 [(set (match_operand:V64I 0 "register_operand" "")
5486 (xor:V64I (match_operand:V64I 1 "arith_double_operand" "")
5487 (match_operand:V64I 2 "arith_double_operand" "")))]
5491 (define_insn "*xor<V64I:mode>3_sp32"
5492 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5493 (xor:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
5494 (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
5499 [(set_attr "type" "*,fga")
5500 (set_attr "length" "2,*")
5501 (set_attr "fptype" "*,double")])
5503 (define_insn "*xor<V64I:mode>3_sp64"
5504 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5505 (xor:V64I (match_operand:V64I 1 "arith_operand" "%rJ,b")
5506 (match_operand:V64I 2 "arith_operand" "rI,b")))]
5511 [(set_attr "type" "*,fga")
5512 (set_attr "fptype" "*,double")])
5514 (define_insn "xor<V32I:mode>3"
5515 [(set (match_operand:V32I 0 "register_operand" "=r,d")
5516 (xor:V32I (match_operand:V32I 1 "arith_operand" "%rJ,d")
5517 (match_operand:V32I 2 "arith_operand" "rI,d")))]
5522 [(set_attr "type" "*,fga")
5523 (set_attr "fptype" "*,single")])
5526 [(set (match_operand:SI 0 "register_operand" "")
5527 (xor:SI (match_operand:SI 1 "register_operand" "")
5528 (match_operand:SI 2 "const_compl_high_operand" "")))
5529 (clobber (match_operand:SI 3 "register_operand" ""))]
5531 [(set (match_dup 3) (match_dup 4))
5532 (set (match_dup 0) (not:SI (xor:SI (match_dup 3) (match_dup 1))))]
5534 operands[4] = GEN_INT (~INTVAL (operands[2]));
5538 [(set (match_operand:SI 0 "register_operand" "")
5539 (not:SI (xor:SI (match_operand:SI 1 "register_operand" "")
5540 (match_operand:SI 2 "const_compl_high_operand" ""))))
5541 (clobber (match_operand:SI 3 "register_operand" ""))]
5543 [(set (match_dup 3) (match_dup 4))
5544 (set (match_dup 0) (xor:SI (match_dup 3) (match_dup 1)))]
5546 operands[4] = GEN_INT (~INTVAL (operands[2]));
5549 ;; Split DImode logical operations requiring two instructions.
5551 [(set (match_operand:V64I 0 "register_operand" "")
5552 (match_operator:V64I 1 "cc_arith_operator" ; AND, IOR, XOR
5553 [(match_operand:V64I 2 "register_operand" "")
5554 (match_operand:V64I 3 "arith_double_operand" "")]))]
5557 && ((GET_CODE (operands[0]) == REG
5558 && REGNO (operands[0]) < 32)
5559 || (GET_CODE (operands[0]) == SUBREG
5560 && GET_CODE (SUBREG_REG (operands[0])) == REG
5561 && REGNO (SUBREG_REG (operands[0])) < 32))"
5562 [(set (match_dup 4) (match_op_dup:SI 1 [(match_dup 6) (match_dup 8)]))
5563 (set (match_dup 5) (match_op_dup:SI 1 [(match_dup 7) (match_dup 9)]))]
5565 operands[4] = gen_highpart (SImode, operands[0]);
5566 operands[5] = gen_lowpart (SImode, operands[0]);
5567 operands[6] = gen_highpart (SImode, operands[2]);
5568 operands[7] = gen_lowpart (SImode, operands[2]);
5569 #if HOST_BITS_PER_WIDE_INT == 32
5570 if (GET_CODE (operands[3]) == CONST_INT && <V64I:MODE>mode == DImode)
5572 if (INTVAL (operands[3]) < 0)
5573 operands[8] = constm1_rtx;
5575 operands[8] = const0_rtx;
5579 operands[8] = gen_highpart_mode (SImode, <V64I:MODE>mode, operands[3]);
5580 operands[9] = gen_lowpart (SImode, operands[3]);
5583 ;; xnor patterns. Note that (a ^ ~b) == (~a ^ b) == ~(a ^ b).
5584 ;; Combine now canonicalizes to the rightmost expression.
5585 (define_insn_and_split "*xor_not_<V64I:mode>_sp32"
5586 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5587 (not:V64I (xor:V64I (match_operand:V64I 1 "register_operand" "r,b")
5588 (match_operand:V64I 2 "register_operand" "r,b"))))]
5593 "&& reload_completed
5594 && ((GET_CODE (operands[0]) == REG
5595 && REGNO (operands[0]) < 32)
5596 || (GET_CODE (operands[0]) == SUBREG
5597 && GET_CODE (SUBREG_REG (operands[0])) == REG
5598 && REGNO (SUBREG_REG (operands[0])) < 32))"
5599 [(set (match_dup 3) (not:SI (xor:SI (match_dup 4) (match_dup 5))))
5600 (set (match_dup 6) (not:SI (xor:SI (match_dup 7) (match_dup 8))))]
5601 "operands[3] = gen_highpart (SImode, operands[0]);
5602 operands[4] = gen_highpart (SImode, operands[1]);
5603 operands[5] = gen_highpart (SImode, operands[2]);
5604 operands[6] = gen_lowpart (SImode, operands[0]);
5605 operands[7] = gen_lowpart (SImode, operands[1]);
5606 operands[8] = gen_lowpart (SImode, operands[2]);"
5607 [(set_attr "type" "*,fga")
5608 (set_attr "length" "2,*")
5609 (set_attr "fptype" "*,double")])
5611 (define_insn "*xor_not_<V64I:mode>_sp64"
5612 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5613 (not:V64I (xor:V64I (match_operand:V64I 1 "register_or_zero_operand" "rJ,b")
5614 (match_operand:V64I 2 "arith_operand" "rI,b"))))]
5619 [(set_attr "type" "*,fga")
5620 (set_attr "fptype" "*,double")])
5622 (define_insn "*xor_not_<V32I:mode>"
5623 [(set (match_operand:V32I 0 "register_operand" "=r,d")
5624 (not:V32I (xor:V32I (match_operand:V32I 1 "register_or_zero_operand" "rJ,d")
5625 (match_operand:V32I 2 "arith_operand" "rI,d"))))]
5630 [(set_attr "type" "*,fga")
5631 (set_attr "fptype" "*,single")])
5633 ;; These correspond to the above in the case where we also (or only)
5634 ;; want to set the condition code.
5636 (define_insn "*cmp_cc_arith_op"
5639 (match_operator:SI 2 "cc_arith_operator"
5640 [(match_operand:SI 0 "arith_operand" "%r")
5641 (match_operand:SI 1 "arith_operand" "rI")])
5644 "%A2cc\t%0, %1, %%g0"
5645 [(set_attr "type" "compare")])
5647 (define_insn "*cmp_ccx_arith_op"
5650 (match_operator:DI 2 "cc_arith_operator"
5651 [(match_operand:DI 0 "arith_operand" "%r")
5652 (match_operand:DI 1 "arith_operand" "rI")])
5655 "%A2cc\t%0, %1, %%g0"
5656 [(set_attr "type" "compare")])
5658 (define_insn "*cmp_cc_arith_op_set"
5661 (match_operator:SI 3 "cc_arith_operator"
5662 [(match_operand:SI 1 "arith_operand" "%r")
5663 (match_operand:SI 2 "arith_operand" "rI")])
5665 (set (match_operand:SI 0 "register_operand" "=r")
5666 (match_operator:SI 4 "cc_arith_operator" [(match_dup 1) (match_dup 2)]))]
5667 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
5669 [(set_attr "type" "compare")])
5671 (define_insn "*cmp_ccx_arith_op_set"
5674 (match_operator:DI 3 "cc_arith_operator"
5675 [(match_operand:DI 1 "arith_operand" "%r")
5676 (match_operand:DI 2 "arith_operand" "rI")])
5678 (set (match_operand:DI 0 "register_operand" "=r")
5679 (match_operator:DI 4 "cc_arith_operator" [(match_dup 1) (match_dup 2)]))]
5680 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
5682 [(set_attr "type" "compare")])
5684 (define_insn "*cmp_cc_xor_not"
5687 (not:SI (xor:SI (match_operand:SI 0 "register_or_zero_operand" "%rJ")
5688 (match_operand:SI 1 "arith_operand" "rI")))
5691 "xnorcc\t%r0, %1, %%g0"
5692 [(set_attr "type" "compare")])
5694 (define_insn "*cmp_ccx_xor_not"
5697 (not:DI (xor:DI (match_operand:DI 0 "register_or_zero_operand" "%rJ")
5698 (match_operand:DI 1 "arith_operand" "rI")))
5701 "xnorcc\t%r0, %1, %%g0"
5702 [(set_attr "type" "compare")])
5704 (define_insn "*cmp_cc_xor_not_set"
5707 (not:SI (xor:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ")
5708 (match_operand:SI 2 "arith_operand" "rI")))
5710 (set (match_operand:SI 0 "register_operand" "=r")
5711 (not:SI (xor:SI (match_dup 1) (match_dup 2))))]
5713 "xnorcc\t%r1, %2, %0"
5714 [(set_attr "type" "compare")])
5716 (define_insn "*cmp_ccx_xor_not_set"
5719 (not:DI (xor:DI (match_operand:DI 1 "register_or_zero_operand" "%rJ")
5720 (match_operand:DI 2 "arith_operand" "rI")))
5722 (set (match_operand:DI 0 "register_operand" "=r")
5723 (not:DI (xor:DI (match_dup 1) (match_dup 2))))]
5725 "xnorcc\t%r1, %2, %0"
5726 [(set_attr "type" "compare")])
5728 (define_insn "*cmp_cc_arith_op_not"
5731 (match_operator:SI 2 "cc_arith_not_operator"
5732 [(not:SI (match_operand:SI 0 "arith_operand" "rI"))
5733 (match_operand:SI 1 "register_or_zero_operand" "rJ")])
5736 "%B2cc\t%r1, %0, %%g0"
5737 [(set_attr "type" "compare")])
5739 (define_insn "*cmp_ccx_arith_op_not"
5742 (match_operator:DI 2 "cc_arith_not_operator"
5743 [(not:DI (match_operand:DI 0 "arith_operand" "rI"))
5744 (match_operand:DI 1 "register_or_zero_operand" "rJ")])
5747 "%B2cc\t%r1, %0, %%g0"
5748 [(set_attr "type" "compare")])
5750 (define_insn "*cmp_cc_arith_op_not_set"
5753 (match_operator:SI 3 "cc_arith_not_operator"
5754 [(not:SI (match_operand:SI 1 "arith_operand" "rI"))
5755 (match_operand:SI 2 "register_or_zero_operand" "rJ")])
5757 (set (match_operand:SI 0 "register_operand" "=r")
5758 (match_operator:SI 4 "cc_arith_not_operator"
5759 [(not:SI (match_dup 1)) (match_dup 2)]))]
5760 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
5761 "%B3cc\t%r2, %1, %0"
5762 [(set_attr "type" "compare")])
5764 (define_insn "*cmp_ccx_arith_op_not_set"
5767 (match_operator:DI 3 "cc_arith_not_operator"
5768 [(not:DI (match_operand:DI 1 "arith_operand" "rI"))
5769 (match_operand:DI 2 "register_or_zero_operand" "rJ")])
5771 (set (match_operand:DI 0 "register_operand" "=r")
5772 (match_operator:DI 4 "cc_arith_not_operator"
5773 [(not:DI (match_dup 1)) (match_dup 2)]))]
5774 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
5775 "%B3cc\t%r2, %1, %0"
5776 [(set_attr "type" "compare")])
5778 ;; We cannot use the "neg" pseudo insn because the Sun assembler
5779 ;; does not know how to make it work for constants.
5781 (define_expand "negdi2"
5782 [(set (match_operand:DI 0 "register_operand" "=r")
5783 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
5786 if (! TARGET_ARCH64)
5788 emit_insn (gen_rtx_PARALLEL
5791 gen_rtx_SET (VOIDmode, operand0,
5792 gen_rtx_NEG (DImode, operand1)),
5793 gen_rtx_CLOBBER (VOIDmode,
5794 gen_rtx_REG (CCmode,
5800 (define_insn_and_split "*negdi2_sp32"
5801 [(set (match_operand:DI 0 "register_operand" "=r")
5802 (neg:DI (match_operand:DI 1 "register_operand" "r")))
5803 (clobber (reg:CC 100))]
5806 "&& reload_completed"
5807 [(parallel [(set (reg:CC_NOOV 100)
5808 (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 5))
5810 (set (match_dup 4) (minus:SI (const_int 0) (match_dup 5)))])
5811 (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
5812 (ltu:SI (reg:CC 100) (const_int 0))))]
5813 "operands[2] = gen_highpart (SImode, operands[0]);
5814 operands[3] = gen_highpart (SImode, operands[1]);
5815 operands[4] = gen_lowpart (SImode, operands[0]);
5816 operands[5] = gen_lowpart (SImode, operands[1]);"
5817 [(set_attr "length" "2")])
5819 (define_insn "*negdi2_sp64"
5820 [(set (match_operand:DI 0 "register_operand" "=r")
5821 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
5823 "sub\t%%g0, %1, %0")
5825 (define_insn "negsi2"
5826 [(set (match_operand:SI 0 "register_operand" "=r")
5827 (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
5829 "sub\t%%g0, %1, %0")
5831 (define_insn "*cmp_cc_neg"
5832 [(set (reg:CC_NOOV 100)
5833 (compare:CC_NOOV (neg:SI (match_operand:SI 0 "arith_operand" "rI"))
5836 "subcc\t%%g0, %0, %%g0"
5837 [(set_attr "type" "compare")])
5839 (define_insn "*cmp_ccx_neg"
5840 [(set (reg:CCX_NOOV 100)
5841 (compare:CCX_NOOV (neg:DI (match_operand:DI 0 "arith_operand" "rI"))
5844 "subcc\t%%g0, %0, %%g0"
5845 [(set_attr "type" "compare")])
5847 (define_insn "*cmp_cc_set_neg"
5848 [(set (reg:CC_NOOV 100)
5849 (compare:CC_NOOV (neg:SI (match_operand:SI 1 "arith_operand" "rI"))
5851 (set (match_operand:SI 0 "register_operand" "=r")
5852 (neg:SI (match_dup 1)))]
5854 "subcc\t%%g0, %1, %0"
5855 [(set_attr "type" "compare")])
5857 (define_insn "*cmp_ccx_set_neg"
5858 [(set (reg:CCX_NOOV 100)
5859 (compare:CCX_NOOV (neg:DI (match_operand:DI 1 "arith_operand" "rI"))
5861 (set (match_operand:DI 0 "register_operand" "=r")
5862 (neg:DI (match_dup 1)))]
5864 "subcc\t%%g0, %1, %0"
5865 [(set_attr "type" "compare")])
5867 ;; We cannot use the "not" pseudo insn because the Sun assembler
5868 ;; does not know how to make it work for constants.
5869 (define_expand "one_cmpl<V64I:mode>2"
5870 [(set (match_operand:V64I 0 "register_operand" "")
5871 (not:V64I (match_operand:V64I 1 "register_operand" "")))]
5875 (define_insn_and_split "*one_cmpl<V64I:mode>2_sp32"
5876 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5877 (not:V64I (match_operand:V64I 1 "register_operand" "r,b")))]
5882 "&& reload_completed
5883 && ((GET_CODE (operands[0]) == REG
5884 && REGNO (operands[0]) < 32)
5885 || (GET_CODE (operands[0]) == SUBREG
5886 && GET_CODE (SUBREG_REG (operands[0])) == REG
5887 && REGNO (SUBREG_REG (operands[0])) < 32))"
5888 [(set (match_dup 2) (not:SI (xor:SI (match_dup 3) (const_int 0))))
5889 (set (match_dup 4) (not:SI (xor:SI (match_dup 5) (const_int 0))))]
5890 "operands[2] = gen_highpart (SImode, operands[0]);
5891 operands[3] = gen_highpart (SImode, operands[1]);
5892 operands[4] = gen_lowpart (SImode, operands[0]);
5893 operands[5] = gen_lowpart (SImode, operands[1]);"
5894 [(set_attr "type" "*,fga")
5895 (set_attr "length" "2,*")
5896 (set_attr "fptype" "*,double")])
5898 (define_insn "*one_cmpl<V64I:mode>2_sp64"
5899 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5900 (not:V64I (match_operand:V64I 1 "arith_operand" "rI,b")))]
5905 [(set_attr "type" "*,fga")
5906 (set_attr "fptype" "*,double")])
5908 (define_insn "one_cmpl<V32I:mode>2"
5909 [(set (match_operand:V32I 0 "register_operand" "=r,d")
5910 (not:V32I (match_operand:V32I 1 "arith_operand" "rI,d")))]
5915 [(set_attr "type" "*,fga")
5916 (set_attr "fptype" "*,single")])
5918 (define_insn "*cmp_cc_not"
5920 (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI"))
5923 "xnorcc\t%%g0, %0, %%g0"
5924 [(set_attr "type" "compare")])
5926 (define_insn "*cmp_ccx_not"
5928 (compare:CCX (not:DI (match_operand:DI 0 "arith_operand" "rI"))
5931 "xnorcc\t%%g0, %0, %%g0"
5932 [(set_attr "type" "compare")])
5934 (define_insn "*cmp_cc_set_not"
5936 (compare:CC (not:SI (match_operand:SI 1 "arith_operand" "rI"))
5938 (set (match_operand:SI 0 "register_operand" "=r")
5939 (not:SI (match_dup 1)))]
5941 "xnorcc\t%%g0, %1, %0"
5942 [(set_attr "type" "compare")])
5944 (define_insn "*cmp_ccx_set_not"
5946 (compare:CCX (not:DI (match_operand:DI 1 "arith_operand" "rI"))
5948 (set (match_operand:DI 0 "register_operand" "=r")
5949 (not:DI (match_dup 1)))]
5951 "xnorcc\t%%g0, %1, %0"
5952 [(set_attr "type" "compare")])
5954 (define_insn "*cmp_cc_set"
5955 [(set (match_operand:SI 0 "register_operand" "=r")
5956 (match_operand:SI 1 "register_operand" "r"))
5958 (compare:CC (match_dup 1)
5962 [(set_attr "type" "compare")])
5964 (define_insn "*cmp_ccx_set64"
5965 [(set (match_operand:DI 0 "register_operand" "=r")
5966 (match_operand:DI 1 "register_operand" "r"))
5968 (compare:CCX (match_dup 1)
5972 [(set_attr "type" "compare")])
5975 ;; Floating point arithmetic instructions.
5977 (define_expand "addtf3"
5978 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5979 (plus:TF (match_operand:TF 1 "general_operand" "")
5980 (match_operand:TF 2 "general_operand" "")))]
5981 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5982 "emit_tfmode_binop (PLUS, operands); DONE;")
5984 (define_insn "*addtf3_hq"
5985 [(set (match_operand:TF 0 "register_operand" "=e")
5986 (plus:TF (match_operand:TF 1 "register_operand" "e")
5987 (match_operand:TF 2 "register_operand" "e")))]
5988 "TARGET_FPU && TARGET_HARD_QUAD"
5990 [(set_attr "type" "fp")])
5992 (define_insn "adddf3"
5993 [(set (match_operand:DF 0 "register_operand" "=e")
5994 (plus:DF (match_operand:DF 1 "register_operand" "e")
5995 (match_operand:DF 2 "register_operand" "e")))]
5998 [(set_attr "type" "fp")
5999 (set_attr "fptype" "double")])
6001 (define_insn "addsf3"
6002 [(set (match_operand:SF 0 "register_operand" "=f")
6003 (plus:SF (match_operand:SF 1 "register_operand" "f")
6004 (match_operand:SF 2 "register_operand" "f")))]
6007 [(set_attr "type" "fp")])
6009 (define_expand "subtf3"
6010 [(set (match_operand:TF 0 "nonimmediate_operand" "")
6011 (minus:TF (match_operand:TF 1 "general_operand" "")
6012 (match_operand:TF 2 "general_operand" "")))]
6013 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6014 "emit_tfmode_binop (MINUS, operands); DONE;")
6016 (define_insn "*subtf3_hq"
6017 [(set (match_operand:TF 0 "register_operand" "=e")
6018 (minus:TF (match_operand:TF 1 "register_operand" "e")
6019 (match_operand:TF 2 "register_operand" "e")))]
6020 "TARGET_FPU && TARGET_HARD_QUAD"
6022 [(set_attr "type" "fp")])
6024 (define_insn "subdf3"
6025 [(set (match_operand:DF 0 "register_operand" "=e")
6026 (minus:DF (match_operand:DF 1 "register_operand" "e")
6027 (match_operand:DF 2 "register_operand" "e")))]
6030 [(set_attr "type" "fp")
6031 (set_attr "fptype" "double")])
6033 (define_insn "subsf3"
6034 [(set (match_operand:SF 0 "register_operand" "=f")
6035 (minus:SF (match_operand:SF 1 "register_operand" "f")
6036 (match_operand:SF 2 "register_operand" "f")))]
6039 [(set_attr "type" "fp")])
6041 (define_expand "multf3"
6042 [(set (match_operand:TF 0 "nonimmediate_operand" "")
6043 (mult:TF (match_operand:TF 1 "general_operand" "")
6044 (match_operand:TF 2 "general_operand" "")))]
6045 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6046 "emit_tfmode_binop (MULT, operands); DONE;")
6048 (define_insn "*multf3_hq"
6049 [(set (match_operand:TF 0 "register_operand" "=e")
6050 (mult:TF (match_operand:TF 1 "register_operand" "e")
6051 (match_operand:TF 2 "register_operand" "e")))]
6052 "TARGET_FPU && TARGET_HARD_QUAD"
6054 [(set_attr "type" "fpmul")])
6056 (define_insn "muldf3"
6057 [(set (match_operand:DF 0 "register_operand" "=e")
6058 (mult:DF (match_operand:DF 1 "register_operand" "e")
6059 (match_operand:DF 2 "register_operand" "e")))]
6062 [(set_attr "type" "fpmul")
6063 (set_attr "fptype" "double")])
6065 (define_insn "mulsf3"
6066 [(set (match_operand:SF 0 "register_operand" "=f")
6067 (mult:SF (match_operand:SF 1 "register_operand" "f")
6068 (match_operand:SF 2 "register_operand" "f")))]
6071 [(set_attr "type" "fpmul")])
6073 (define_insn "*muldf3_extend"
6074 [(set (match_operand:DF 0 "register_operand" "=e")
6075 (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "f"))
6076 (float_extend:DF (match_operand:SF 2 "register_operand" "f"))))]
6077 "(TARGET_V8 || TARGET_V9) && TARGET_FPU"
6078 "fsmuld\t%1, %2, %0"
6079 [(set_attr "type" "fpmul")
6080 (set_attr "fptype" "double")])
6082 (define_insn "*multf3_extend"
6083 [(set (match_operand:TF 0 "register_operand" "=e")
6084 (mult:TF (float_extend:TF (match_operand:DF 1 "register_operand" "e"))
6085 (float_extend:TF (match_operand:DF 2 "register_operand" "e"))))]
6086 "(TARGET_V8 || TARGET_V9) && TARGET_FPU && TARGET_HARD_QUAD"
6087 "fdmulq\t%1, %2, %0"
6088 [(set_attr "type" "fpmul")])
6090 (define_expand "divtf3"
6091 [(set (match_operand:TF 0 "nonimmediate_operand" "")
6092 (div:TF (match_operand:TF 1 "general_operand" "")
6093 (match_operand:TF 2 "general_operand" "")))]
6094 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6095 "emit_tfmode_binop (DIV, operands); DONE;")
6097 ;; don't have timing for quad-prec. divide.
6098 (define_insn "*divtf3_hq"
6099 [(set (match_operand:TF 0 "register_operand" "=e")
6100 (div:TF (match_operand:TF 1 "register_operand" "e")
6101 (match_operand:TF 2 "register_operand" "e")))]
6102 "TARGET_FPU && TARGET_HARD_QUAD"
6104 [(set_attr "type" "fpdivd")])
6106 (define_insn "divdf3"
6107 [(set (match_operand:DF 0 "register_operand" "=e")
6108 (div:DF (match_operand:DF 1 "register_operand" "e")
6109 (match_operand:DF 2 "register_operand" "e")))]
6112 [(set_attr "type" "fpdivd")
6113 (set_attr "fptype" "double")])
6115 (define_insn "divsf3"
6116 [(set (match_operand:SF 0 "register_operand" "=f")
6117 (div:SF (match_operand:SF 1 "register_operand" "f")
6118 (match_operand:SF 2 "register_operand" "f")))]
6121 [(set_attr "type" "fpdivs")])
6123 (define_expand "negtf2"
6124 [(set (match_operand:TF 0 "register_operand" "=e,e")
6125 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
6129 (define_insn_and_split "*negtf2_notv9"
6130 [(set (match_operand:TF 0 "register_operand" "=e,e")
6131 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
6132 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
6138 "&& reload_completed
6139 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6140 [(set (match_dup 2) (neg:SF (match_dup 3)))
6141 (set (match_dup 4) (match_dup 5))
6142 (set (match_dup 6) (match_dup 7))]
6143 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6144 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6145 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6146 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
6147 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6148 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6149 [(set_attr "type" "fpmove,*")
6150 (set_attr "length" "*,2")])
6152 (define_insn_and_split "*negtf2_v9"
6153 [(set (match_operand:TF 0 "register_operand" "=e,e")
6154 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
6155 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
6156 "TARGET_FPU && TARGET_V9"
6160 "&& reload_completed
6161 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6162 [(set (match_dup 2) (neg:DF (match_dup 3)))
6163 (set (match_dup 4) (match_dup 5))]
6164 "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
6165 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
6166 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6167 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6168 [(set_attr "type" "fpmove,*")
6169 (set_attr "length" "*,2")
6170 (set_attr "fptype" "double")])
6172 (define_expand "negdf2"
6173 [(set (match_operand:DF 0 "register_operand" "")
6174 (neg:DF (match_operand:DF 1 "register_operand" "")))]
6178 (define_insn_and_split "*negdf2_notv9"
6179 [(set (match_operand:DF 0 "register_operand" "=e,e")
6180 (neg:DF (match_operand:DF 1 "register_operand" "0,e")))]
6181 "TARGET_FPU && ! TARGET_V9"
6185 "&& reload_completed
6186 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6187 [(set (match_dup 2) (neg:SF (match_dup 3)))
6188 (set (match_dup 4) (match_dup 5))]
6189 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6190 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6191 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6192 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);"
6193 [(set_attr "type" "fpmove,*")
6194 (set_attr "length" "*,2")])
6196 (define_insn "*negdf2_v9"
6197 [(set (match_operand:DF 0 "register_operand" "=e")
6198 (neg:DF (match_operand:DF 1 "register_operand" "e")))]
6199 "TARGET_FPU && TARGET_V9"
6201 [(set_attr "type" "fpmove")
6202 (set_attr "fptype" "double")])
6204 (define_insn "negsf2"
6205 [(set (match_operand:SF 0 "register_operand" "=f")
6206 (neg:SF (match_operand:SF 1 "register_operand" "f")))]
6209 [(set_attr "type" "fpmove")])
6211 (define_expand "abstf2"
6212 [(set (match_operand:TF 0 "register_operand" "")
6213 (abs:TF (match_operand:TF 1 "register_operand" "")))]
6217 (define_insn_and_split "*abstf2_notv9"
6218 [(set (match_operand:TF 0 "register_operand" "=e,e")
6219 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6220 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
6221 "TARGET_FPU && ! TARGET_V9"
6225 "&& reload_completed
6226 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6227 [(set (match_dup 2) (abs:SF (match_dup 3)))
6228 (set (match_dup 4) (match_dup 5))
6229 (set (match_dup 6) (match_dup 7))]
6230 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6231 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6232 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6233 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
6234 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6235 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6236 [(set_attr "type" "fpmove,*")
6237 (set_attr "length" "*,2")])
6239 (define_insn "*abstf2_hq_v9"
6240 [(set (match_operand:TF 0 "register_operand" "=e,e")
6241 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6242 "TARGET_FPU && TARGET_V9 && TARGET_HARD_QUAD"
6246 [(set_attr "type" "fpmove")
6247 (set_attr "fptype" "double,*")])
6249 (define_insn_and_split "*abstf2_v9"
6250 [(set (match_operand:TF 0 "register_operand" "=e,e")
6251 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6252 "TARGET_FPU && TARGET_V9 && !TARGET_HARD_QUAD"
6256 "&& reload_completed
6257 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6258 [(set (match_dup 2) (abs:DF (match_dup 3)))
6259 (set (match_dup 4) (match_dup 5))]
6260 "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
6261 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
6262 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6263 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6264 [(set_attr "type" "fpmove,*")
6265 (set_attr "length" "*,2")
6266 (set_attr "fptype" "double,*")])
6268 (define_expand "absdf2"
6269 [(set (match_operand:DF 0 "register_operand" "")
6270 (abs:DF (match_operand:DF 1 "register_operand" "")))]
6274 (define_insn_and_split "*absdf2_notv9"
6275 [(set (match_operand:DF 0 "register_operand" "=e,e")
6276 (abs:DF (match_operand:DF 1 "register_operand" "0,e")))]
6277 "TARGET_FPU && ! TARGET_V9"
6281 "&& reload_completed
6282 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6283 [(set (match_dup 2) (abs:SF (match_dup 3)))
6284 (set (match_dup 4) (match_dup 5))]
6285 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6286 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6287 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6288 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);"
6289 [(set_attr "type" "fpmove,*")
6290 (set_attr "length" "*,2")])
6292 (define_insn "*absdf2_v9"
6293 [(set (match_operand:DF 0 "register_operand" "=e")
6294 (abs:DF (match_operand:DF 1 "register_operand" "e")))]
6295 "TARGET_FPU && TARGET_V9"
6297 [(set_attr "type" "fpmove")
6298 (set_attr "fptype" "double")])
6300 (define_insn "abssf2"
6301 [(set (match_operand:SF 0 "register_operand" "=f")
6302 (abs:SF (match_operand:SF 1 "register_operand" "f")))]
6305 [(set_attr "type" "fpmove")])
6307 (define_expand "sqrttf2"
6308 [(set (match_operand:TF 0 "nonimmediate_operand" "")
6309 (sqrt:TF (match_operand:TF 1 "general_operand" "")))]
6310 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6311 "emit_tfmode_unop (SQRT, operands); DONE;")
6313 (define_insn "*sqrttf2_hq"
6314 [(set (match_operand:TF 0 "register_operand" "=e")
6315 (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
6316 "TARGET_FPU && TARGET_HARD_QUAD"
6318 [(set_attr "type" "fpsqrtd")])
6320 (define_insn "sqrtdf2"
6321 [(set (match_operand:DF 0 "register_operand" "=e")
6322 (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
6325 [(set_attr "type" "fpsqrtd")
6326 (set_attr "fptype" "double")])
6328 (define_insn "sqrtsf2"
6329 [(set (match_operand:SF 0 "register_operand" "=f")
6330 (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
6333 [(set_attr "type" "fpsqrts")])
6336 ;; Arithmetic shift instructions.
6338 (define_insn "ashlsi3"
6339 [(set (match_operand:SI 0 "register_operand" "=r")
6340 (ashift:SI (match_operand:SI 1 "register_operand" "r")
6341 (match_operand:SI 2 "arith_operand" "rI")))]
6344 if (GET_CODE (operands[2]) == CONST_INT)
6345 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6346 return "sll\t%1, %2, %0";
6349 (if_then_else (match_operand 2 "const_one_operand" "")
6350 (const_string "ialu") (const_string "shift")))])
6352 (define_expand "ashldi3"
6353 [(set (match_operand:DI 0 "register_operand" "=r")
6354 (ashift:DI (match_operand:DI 1 "register_operand" "r")
6355 (match_operand:SI 2 "arith_operand" "rI")))]
6356 "TARGET_ARCH64 || TARGET_V8PLUS"
6358 if (! TARGET_ARCH64)
6360 if (GET_CODE (operands[2]) == CONST_INT)
6362 emit_insn (gen_ashldi3_v8plus (operands[0], operands[1], operands[2]));
6367 (define_insn "*ashldi3_sp64"
6368 [(set (match_operand:DI 0 "register_operand" "=r")
6369 (ashift:DI (match_operand:DI 1 "register_operand" "r")
6370 (match_operand:SI 2 "arith_operand" "rI")))]
6373 if (GET_CODE (operands[2]) == CONST_INT)
6374 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
6375 return "sllx\t%1, %2, %0";
6378 (if_then_else (match_operand 2 "const_one_operand" "")
6379 (const_string "ialu") (const_string "shift")))])
6382 (define_insn "ashldi3_v8plus"
6383 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
6384 (ashift:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
6385 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
6386 (clobber (match_scratch:SI 3 "=X,X,&h"))]
6388 "* return output_v8plus_shift (operands, insn, \"sllx\");"
6389 [(set_attr "type" "multi")
6390 (set_attr "length" "5,5,6")])
6392 ;; Optimize (1LL<<x)-1
6393 ;; XXX this also needs to be fixed to handle equal subregs
6394 ;; XXX first before we could re-enable it.
6396 ; [(set (match_operand:DI 0 "register_operand" "=h")
6397 ; (plus:DI (ashift:DI (const_int 1)
6398 ; (match_operand:SI 1 "arith_operand" "rI"))
6400 ; "0 && TARGET_V8PLUS"
6402 ; if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == REGNO (operands[0]))
6403 ; return "mov\t1, %L0\;sllx\t%L0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
6404 ; return "mov\t1, %H0\;sllx\t%H0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
6406 ; [(set_attr "type" "multi")
6407 ; (set_attr "length" "4")])
6409 (define_insn "*cmp_cc_ashift_1"
6410 [(set (reg:CC_NOOV 100)
6411 (compare:CC_NOOV (ashift:SI (match_operand:SI 0 "register_operand" "r")
6415 "addcc\t%0, %0, %%g0"
6416 [(set_attr "type" "compare")])
6418 (define_insn "*cmp_cc_set_ashift_1"
6419 [(set (reg:CC_NOOV 100)
6420 (compare:CC_NOOV (ashift:SI (match_operand:SI 1 "register_operand" "r")
6423 (set (match_operand:SI 0 "register_operand" "=r")
6424 (ashift:SI (match_dup 1) (const_int 1)))]
6427 [(set_attr "type" "compare")])
6429 (define_insn "ashrsi3"
6430 [(set (match_operand:SI 0 "register_operand" "=r")
6431 (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
6432 (match_operand:SI 2 "arith_operand" "rI")))]
6435 if (GET_CODE (operands[2]) == CONST_INT)
6436 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6437 return "sra\t%1, %2, %0";
6439 [(set_attr "type" "shift")])
6441 (define_insn "*ashrsi3_extend"
6442 [(set (match_operand:DI 0 "register_operand" "=r")
6443 (sign_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
6444 (match_operand:SI 2 "arith_operand" "r"))))]
6447 [(set_attr "type" "shift")])
6449 ;; This handles the case as above, but with constant shift instead of
6450 ;; register. Combiner "simplifies" it for us a little bit though.
6451 (define_insn "*ashrsi3_extend2"
6452 [(set (match_operand:DI 0 "register_operand" "=r")
6453 (ashiftrt:DI (ashift:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
6455 (match_operand:SI 2 "small_int_operand" "I")))]
6456 "TARGET_ARCH64 && INTVAL (operands[2]) >= 32 && INTVAL (operands[2]) < 64"
6458 operands[2] = GEN_INT (INTVAL (operands[2]) - 32);
6459 return "sra\t%1, %2, %0";
6461 [(set_attr "type" "shift")])
6463 (define_expand "ashrdi3"
6464 [(set (match_operand:DI 0 "register_operand" "=r")
6465 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
6466 (match_operand:SI 2 "arith_operand" "rI")))]
6467 "TARGET_ARCH64 || TARGET_V8PLUS"
6469 if (! TARGET_ARCH64)
6471 if (GET_CODE (operands[2]) == CONST_INT)
6472 FAIL; /* prefer generic code in this case */
6473 emit_insn (gen_ashrdi3_v8plus (operands[0], operands[1], operands[2]));
6478 (define_insn "*ashrdi3_sp64"
6479 [(set (match_operand:DI 0 "register_operand" "=r")
6480 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
6481 (match_operand:SI 2 "arith_operand" "rI")))]
6485 if (GET_CODE (operands[2]) == CONST_INT)
6486 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
6487 return "srax\t%1, %2, %0";
6489 [(set_attr "type" "shift")])
6492 (define_insn "ashrdi3_v8plus"
6493 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
6494 (ashiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
6495 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
6496 (clobber (match_scratch:SI 3 "=X,X,&h"))]
6498 "* return output_v8plus_shift (operands, insn, \"srax\");"
6499 [(set_attr "type" "multi")
6500 (set_attr "length" "5,5,6")])
6502 (define_insn "lshrsi3"
6503 [(set (match_operand:SI 0 "register_operand" "=r")
6504 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
6505 (match_operand:SI 2 "arith_operand" "rI")))]
6508 if (GET_CODE (operands[2]) == CONST_INT)
6509 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6510 return "srl\t%1, %2, %0";
6512 [(set_attr "type" "shift")])
6514 ;; This handles the case where
6515 ;; (zero_extend:DI (lshiftrt:SI (match_operand:SI) (match_operand:SI))),
6516 ;; but combiner "simplifies" it for us.
6517 (define_insn "*lshrsi3_extend"
6518 [(set (match_operand:DI 0 "register_operand" "=r")
6519 (and:DI (subreg:DI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
6520 (match_operand:SI 2 "arith_operand" "r")) 0)
6521 (match_operand 3 "const_int_operand" "")))]
6522 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) == 0xffffffff"
6524 [(set_attr "type" "shift")])
6526 ;; This handles the case where
6527 ;; (lshiftrt:DI (zero_extend:DI (match_operand:SI)) (const_int >=0 < 32))
6528 ;; but combiner "simplifies" it for us.
6529 (define_insn "*lshrsi3_extend2"
6530 [(set (match_operand:DI 0 "register_operand" "=r")
6531 (zero_extract:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
6532 (match_operand 2 "small_int_operand" "I")
6534 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
6536 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
6537 return "srl\t%1, %2, %0";
6539 [(set_attr "type" "shift")])
6541 (define_expand "lshrdi3"
6542 [(set (match_operand:DI 0 "register_operand" "=r")
6543 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6544 (match_operand:SI 2 "arith_operand" "rI")))]
6545 "TARGET_ARCH64 || TARGET_V8PLUS"
6547 if (! TARGET_ARCH64)
6549 if (GET_CODE (operands[2]) == CONST_INT)
6551 emit_insn (gen_lshrdi3_v8plus (operands[0], operands[1], operands[2]));
6556 (define_insn "*lshrdi3_sp64"
6557 [(set (match_operand:DI 0 "register_operand" "=r")
6558 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6559 (match_operand:SI 2 "arith_operand" "rI")))]
6562 if (GET_CODE (operands[2]) == CONST_INT)
6563 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
6564 return "srlx\t%1, %2, %0";
6566 [(set_attr "type" "shift")])
6569 (define_insn "lshrdi3_v8plus"
6570 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
6571 (lshiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
6572 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
6573 (clobber (match_scratch:SI 3 "=X,X,&h"))]
6575 "* return output_v8plus_shift (operands, insn, \"srlx\");"
6576 [(set_attr "type" "multi")
6577 (set_attr "length" "5,5,6")])
6580 [(set (match_operand:SI 0 "register_operand" "=r")
6581 (ashiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6583 (match_operand:SI 2 "small_int_operand" "I")))]
6584 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
6586 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
6587 return "srax\t%1, %2, %0";
6589 [(set_attr "type" "shift")])
6592 [(set (match_operand:SI 0 "register_operand" "=r")
6593 (lshiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
6595 (match_operand:SI 2 "small_int_operand" "I")))]
6596 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
6598 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
6599 return "srlx\t%1, %2, %0";
6601 [(set_attr "type" "shift")])
6604 [(set (match_operand:SI 0 "register_operand" "=r")
6605 (ashiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
6606 (match_operand:SI 2 "small_int_operand" "I")) 4)
6607 (match_operand:SI 3 "small_int_operand" "I")))]
6609 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
6610 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
6611 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
6613 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
6615 return "srax\t%1, %2, %0";
6617 [(set_attr "type" "shift")])
6620 [(set (match_operand:SI 0 "register_operand" "=r")
6621 (lshiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6622 (match_operand:SI 2 "small_int_operand" "I")) 4)
6623 (match_operand:SI 3 "small_int_operand" "I")))]
6625 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
6626 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
6627 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
6629 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
6631 return "srlx\t%1, %2, %0";
6633 [(set_attr "type" "shift")])
6636 ;; Unconditional and other jump instructions.
6639 [(set (pc) (label_ref (match_operand 0 "" "")))]
6641 "* return output_ubranch (operands[0], 0, insn);"
6642 [(set_attr "type" "uncond_branch")])
6644 (define_expand "tablejump"
6645 [(parallel [(set (pc) (match_operand 0 "register_operand" "r"))
6646 (use (label_ref (match_operand 1 "" "")))])]
6649 gcc_assert (GET_MODE (operands[0]) == CASE_VECTOR_MODE);
6651 /* In pic mode, our address differences are against the base of the
6652 table. Add that base value back in; CSE ought to be able to combine
6653 the two address loads. */
6657 tmp = gen_rtx_LABEL_REF (Pmode, operands[1]);
6659 if (CASE_VECTOR_MODE != Pmode)
6660 tmp2 = gen_rtx_SIGN_EXTEND (Pmode, tmp2);
6661 tmp = gen_rtx_PLUS (Pmode, tmp2, tmp);
6662 operands[0] = memory_address (Pmode, tmp);
6666 (define_insn "*tablejump_sp32"
6667 [(set (pc) (match_operand:SI 0 "address_operand" "p"))
6668 (use (label_ref (match_operand 1 "" "")))]
6671 [(set_attr "type" "uncond_branch")])
6673 (define_insn "*tablejump_sp64"
6674 [(set (pc) (match_operand:DI 0 "address_operand" "p"))
6675 (use (label_ref (match_operand 1 "" "")))]
6678 [(set_attr "type" "uncond_branch")])
6681 ;; Jump to subroutine instructions.
6683 (define_expand "call"
6684 ;; Note that this expression is not used for generating RTL.
6685 ;; All the RTL is generated explicitly below.
6686 [(call (match_operand 0 "call_operand" "")
6687 (match_operand 3 "" "i"))]
6688 ;; operands[2] is next_arg_register
6689 ;; operands[3] is struct_value_size_rtx.
6694 gcc_assert (MEM_P (operands[0]) && GET_MODE (operands[0]) == FUNCTION_MODE);
6696 gcc_assert (GET_CODE (operands[3]) == CONST_INT);
6698 if (GET_CODE (XEXP (operands[0], 0)) == LABEL_REF)
6700 /* This is really a PIC sequence. We want to represent
6701 it as a funny jump so its delay slots can be filled.
6703 ??? But if this really *is* a CALL, will not it clobber the
6704 call-clobbered registers? We lose this if it is a JUMP_INSN.
6705 Why cannot we have delay slots filled if it were a CALL? */
6707 /* We accept negative sizes for untyped calls. */
6708 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
6713 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
6715 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
6721 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
6722 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
6726 fn_rtx = operands[0];
6728 /* We accept negative sizes for untyped calls. */
6729 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
6730 sparc_emit_call_insn
6733 gen_rtvec (3, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx),
6735 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))),
6738 sparc_emit_call_insn
6741 gen_rtvec (2, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx),
6742 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))),
6750 ;; We can't use the same pattern for these two insns, because then registers
6751 ;; in the address may not be properly reloaded.
6753 (define_insn "*call_address_sp32"
6754 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6755 (match_operand 1 "" ""))
6756 (clobber (reg:SI 15))]
6757 ;;- Do not use operand 1 for most machines.
6760 [(set_attr "type" "call")])
6762 (define_insn "*call_symbolic_sp32"
6763 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6764 (match_operand 1 "" ""))
6765 (clobber (reg:SI 15))]
6766 ;;- Do not use operand 1 for most machines.
6769 [(set_attr "type" "call")])
6771 (define_insn "*call_address_sp64"
6772 [(call (mem:DI (match_operand:DI 0 "address_operand" "p"))
6773 (match_operand 1 "" ""))
6774 (clobber (reg:DI 15))]
6775 ;;- Do not use operand 1 for most machines.
6778 [(set_attr "type" "call")])
6780 (define_insn "*call_symbolic_sp64"
6781 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
6782 (match_operand 1 "" ""))
6783 (clobber (reg:DI 15))]
6784 ;;- Do not use operand 1 for most machines.
6787 [(set_attr "type" "call")])
6789 ;; This is a call that wants a structure value.
6790 ;; There is no such critter for v9 (??? we may need one anyway).
6791 (define_insn "*call_address_struct_value_sp32"
6792 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6793 (match_operand 1 "" ""))
6794 (match_operand 2 "immediate_operand" "")
6795 (clobber (reg:SI 15))]
6796 ;;- Do not use operand 1 for most machines.
6797 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
6799 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xfff);
6800 return "call\t%a0, %1\n\t nop\n\tunimp\t%2";
6802 [(set_attr "type" "call_no_delay_slot")
6803 (set_attr "length" "3")])
6805 ;; This is a call that wants a structure value.
6806 ;; There is no such critter for v9 (??? we may need one anyway).
6807 (define_insn "*call_symbolic_struct_value_sp32"
6808 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6809 (match_operand 1 "" ""))
6810 (match_operand 2 "immediate_operand" "")
6811 (clobber (reg:SI 15))]
6812 ;;- Do not use operand 1 for most machines.
6813 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
6815 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xfff);
6816 return "call\t%a0, %1\n\t nop\n\tunimp\t%2";
6818 [(set_attr "type" "call_no_delay_slot")
6819 (set_attr "length" "3")])
6821 ;; This is a call that may want a structure value. This is used for
6823 (define_insn "*call_address_untyped_struct_value_sp32"
6824 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6825 (match_operand 1 "" ""))
6826 (match_operand 2 "immediate_operand" "")
6827 (clobber (reg:SI 15))]
6828 ;;- Do not use operand 1 for most machines.
6829 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
6830 "call\t%a0, %1\n\t nop\n\tnop"
6831 [(set_attr "type" "call_no_delay_slot")
6832 (set_attr "length" "3")])
6834 ;; This is a call that may want a structure value. This is used for
6836 (define_insn "*call_symbolic_untyped_struct_value_sp32"
6837 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6838 (match_operand 1 "" ""))
6839 (match_operand 2 "immediate_operand" "")
6840 (clobber (reg:SI 15))]
6841 ;;- Do not use operand 1 for most machines.
6842 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
6843 "call\t%a0, %1\n\t nop\n\tnop"
6844 [(set_attr "type" "call_no_delay_slot")
6845 (set_attr "length" "3")])
6847 (define_expand "call_value"
6848 ;; Note that this expression is not used for generating RTL.
6849 ;; All the RTL is generated explicitly below.
6850 [(set (match_operand 0 "register_operand" "=rf")
6851 (call (match_operand 1 "" "")
6852 (match_operand 4 "" "")))]
6853 ;; operand 2 is stack_size_rtx
6854 ;; operand 3 is next_arg_register
6860 gcc_assert (MEM_P (operands[1]) && GET_MODE (operands[1]) == FUNCTION_MODE);
6862 fn_rtx = operands[1];
6865 gen_rtx_SET (VOIDmode, operands[0],
6866 gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx)),
6867 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)));
6869 sparc_emit_call_insn (gen_rtx_PARALLEL (VOIDmode, vec), XEXP (fn_rtx, 0));
6874 (define_insn "*call_value_address_sp32"
6875 [(set (match_operand 0 "" "=rf")
6876 (call (mem:SI (match_operand:SI 1 "address_operand" "p"))
6877 (match_operand 2 "" "")))
6878 (clobber (reg:SI 15))]
6879 ;;- Do not use operand 2 for most machines.
6882 [(set_attr "type" "call")])
6884 (define_insn "*call_value_symbolic_sp32"
6885 [(set (match_operand 0 "" "=rf")
6886 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
6887 (match_operand 2 "" "")))
6888 (clobber (reg:SI 15))]
6889 ;;- Do not use operand 2 for most machines.
6892 [(set_attr "type" "call")])
6894 (define_insn "*call_value_address_sp64"
6895 [(set (match_operand 0 "" "")
6896 (call (mem:DI (match_operand:DI 1 "address_operand" "p"))
6897 (match_operand 2 "" "")))
6898 (clobber (reg:DI 15))]
6899 ;;- Do not use operand 2 for most machines.
6902 [(set_attr "type" "call")])
6904 (define_insn "*call_value_symbolic_sp64"
6905 [(set (match_operand 0 "" "")
6906 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
6907 (match_operand 2 "" "")))
6908 (clobber (reg:DI 15))]
6909 ;;- Do not use operand 2 for most machines.
6912 [(set_attr "type" "call")])
6914 (define_expand "untyped_call"
6915 [(parallel [(call (match_operand 0 "" "")
6917 (match_operand:BLK 1 "memory_operand" "")
6918 (match_operand 2 "" "")])]
6921 rtx valreg1 = gen_rtx_REG (DImode, 8);
6922 rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
6923 rtx result = operands[1];
6925 /* Pass constm1 to indicate that it may expect a structure value, but
6926 we don't know what size it is. */
6927 emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, constm1_rtx));
6929 /* Save the function value registers. */
6930 emit_move_insn (adjust_address (result, DImode, 0), valreg1);
6931 emit_move_insn (adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8),
6934 /* The optimizer does not know that the call sets the function value
6935 registers we stored in the result block. We avoid problems by
6936 claiming that all hard registers are used and clobbered at this
6938 emit_insn (gen_blockage ());
6943 ;; Tail call instructions.
6945 (define_expand "sibcall"
6946 [(parallel [(call (match_operand 0 "call_operand" "") (const_int 0))
6951 (define_insn "*sibcall_symbolic_sp32"
6952 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6953 (match_operand 1 "" ""))
6956 "* return output_sibcall(insn, operands[0]);"
6957 [(set_attr "type" "sibcall")])
6959 (define_insn "*sibcall_symbolic_sp64"
6960 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
6961 (match_operand 1 "" ""))
6964 "* return output_sibcall(insn, operands[0]);"
6965 [(set_attr "type" "sibcall")])
6967 (define_expand "sibcall_value"
6968 [(parallel [(set (match_operand 0 "register_operand" "=rf")
6969 (call (match_operand 1 "" "") (const_int 0)))
6974 (define_insn "*sibcall_value_symbolic_sp32"
6975 [(set (match_operand 0 "" "=rf")
6976 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
6977 (match_operand 2 "" "")))
6980 "* return output_sibcall(insn, operands[1]);"
6981 [(set_attr "type" "sibcall")])
6983 (define_insn "*sibcall_value_symbolic_sp64"
6984 [(set (match_operand 0 "" "")
6985 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
6986 (match_operand 2 "" "")))
6989 "* return output_sibcall(insn, operands[1]);"
6990 [(set_attr "type" "sibcall")])
6993 ;; Special instructions.
6995 (define_expand "prologue"
6999 sparc_expand_prologue ();
7003 ;; The "save register window" insn is modelled as follows so that the DWARF-2
7004 ;; backend automatically emits the required call frame debugging information
7005 ;; while it is parsing it. Therefore, the pattern should not be modified
7006 ;; without first studying the impact of the changes on the debug info.
7007 ;; [(set (%fp) (%sp))
7008 ;; (set (%sp) (unspec_volatile [(%sp) (-frame_size)] UNSPECV_SAVEW))
7009 ;; (set (%i7) (%o7))]
7011 (define_insn "save_register_window<P:mode>"
7012 [(set (reg:P 30) (reg:P 14))
7013 (set (reg:P 14) (unspec_volatile:P [(reg:P 14)
7014 (match_operand:P 0 "arith_operand" "rI")] UNSPECV_SAVEW))
7015 (set (reg:P 31) (reg:P 15))]
7017 "save\t%%sp, %0, %%sp"
7018 [(set_attr "type" "savew")])
7020 (define_expand "epilogue"
7024 sparc_expand_epilogue ();
7027 (define_expand "sibcall_epilogue"
7031 sparc_expand_epilogue ();
7035 (define_expand "return"
7037 "sparc_can_use_return_insn_p ()"
7040 (define_insn "*return_internal"
7043 "* return output_return (insn);"
7044 [(set_attr "type" "return")
7045 (set (attr "length")
7046 (cond [(eq_attr "leaf_function" "true")
7047 (if_then_else (eq_attr "empty_delay_slot" "true")
7050 (eq_attr "calls_eh_return" "true")
7051 (if_then_else (eq_attr "delayed_branch" "true")
7052 (if_then_else (eq_attr "isa" "v9")
7055 (if_then_else (eq_attr "isa" "v9")
7058 (eq_attr "empty_delay_slot" "true")
7059 (if_then_else (eq_attr "delayed_branch" "true")
7064 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
7065 ;; all of memory. This blocks insns from being moved across this point.
7067 (define_insn "blockage"
7068 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
7071 [(set_attr "length" "0")])
7073 ;; Prepare to return any type including a structure value.
7075 (define_expand "untyped_return"
7076 [(match_operand:BLK 0 "memory_operand" "")
7077 (match_operand 1 "" "")]
7080 rtx valreg1 = gen_rtx_REG (DImode, 24);
7081 rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
7082 rtx result = operands[0];
7084 if (! TARGET_ARCH64)
7086 rtx rtnreg = gen_rtx_REG (SImode, (current_function_uses_only_leaf_regs
7088 rtx value = gen_reg_rtx (SImode);
7090 /* Fetch the instruction where we will return to and see if it's an unimp
7091 instruction (the most significant 10 bits will be zero). If so,
7092 update the return address to skip the unimp instruction. */
7093 emit_move_insn (value,
7094 gen_rtx_MEM (SImode, plus_constant (rtnreg, 8)));
7095 emit_insn (gen_lshrsi3 (value, value, GEN_INT (22)));
7096 emit_insn (gen_update_return (rtnreg, value));
7099 /* Reload the function value registers. */
7100 emit_move_insn (valreg1, adjust_address (result, DImode, 0));
7101 emit_move_insn (valreg2,
7102 adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8));
7104 /* Put USE insns before the return. */
7105 emit_insn (gen_rtx_USE (VOIDmode, valreg1));
7106 emit_insn (gen_rtx_USE (VOIDmode, valreg2));
7108 /* Construct the return. */
7109 expand_naked_return ();
7114 ;; Adjust the return address conditionally. If the value of op1 is equal
7115 ;; to all zero then adjust the return address i.e. op0 = op0 + 4.
7116 ;; This is technically *half* the check required by the 32-bit SPARC
7117 ;; psABI. This check only ensures that an "unimp" insn was written by
7118 ;; the caller, but doesn't check to see if the expected size matches
7119 ;; (this is encoded in the 12 lower bits). This check is obsolete and
7120 ;; only used by the above code "untyped_return".
7122 (define_insn "update_return"
7123 [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
7124 (match_operand:SI 1 "register_operand" "r")] UNSPEC_UPDATE_RETURN)]
7127 if (flag_delayed_branch)
7128 return "cmp\t%1, 0\n\tbe,a\t.+8\n\t add\t%0, 4, %0";
7130 return "cmp\t%1, 0\n\tbne\t.+12\n\t nop\n\tadd\t%0, 4, %0";
7132 [(set (attr "type") (const_string "multi"))
7133 (set (attr "length")
7134 (if_then_else (eq_attr "delayed_branch" "true")
7143 (define_expand "indirect_jump"
7144 [(set (pc) (match_operand 0 "address_operand" "p"))]
7148 (define_insn "*branch_sp32"
7149 [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
7152 [(set_attr "type" "uncond_branch")])
7154 (define_insn "*branch_sp64"
7155 [(set (pc) (match_operand:DI 0 "address_operand" "p"))]
7158 [(set_attr "type" "uncond_branch")])
7160 (define_expand "nonlocal_goto"
7161 [(match_operand:SI 0 "general_operand" "")
7162 (match_operand:SI 1 "general_operand" "")
7163 (match_operand:SI 2 "general_operand" "")
7164 (match_operand:SI 3 "" "")]
7167 rtx lab = operands[1];
7168 rtx stack = operands[2];
7169 rtx fp = operands[3];
7172 /* Trap instruction to flush all the register windows. */
7173 emit_insn (gen_flush_register_windows ());
7175 /* Load the fp value for the containing fn into %fp. This is needed
7176 because STACK refers to %fp. Note that virtual register instantiation
7177 fails if the virtual %fp isn't set from a register. */
7178 if (GET_CODE (fp) != REG)
7179 fp = force_reg (Pmode, fp);
7180 emit_move_insn (virtual_stack_vars_rtx, fp);
7182 /* Find the containing function's current nonlocal goto handler,
7183 which will do any cleanups and then jump to the label. */
7184 labreg = gen_rtx_REG (Pmode, 8);
7185 emit_move_insn (labreg, lab);
7187 /* Restore %fp from stack pointer value for containing function.
7188 The restore insn that follows will move this to %sp,
7189 and reload the appropriate value into %fp. */
7190 emit_move_insn (hard_frame_pointer_rtx, stack);
7192 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
7193 emit_insn (gen_rtx_USE (VOIDmode, static_chain_rtx));
7195 /* ??? The V9-specific version was disabled in rev 1.65. */
7196 emit_jump_insn (gen_goto_handler_and_restore (labreg));
7201 ;; Special trap insn to flush register windows.
7202 (define_insn "flush_register_windows"
7203 [(unspec_volatile [(const_int 0)] UNSPECV_FLUSHW)]
7205 { return TARGET_V9 ? "flushw" : "ta\t3"; }
7206 [(set_attr "type" "flushw")])
7208 (define_insn "goto_handler_and_restore"
7209 [(unspec_volatile [(match_operand 0 "register_operand" "=r")] UNSPECV_GOTO)]
7210 "GET_MODE (operands[0]) == Pmode"
7212 if (flag_delayed_branch)
7213 return "jmp\t%0\n\t restore";
7215 return "mov\t%0,%%g1\n\trestore\n\tjmp\t%%g1\n\t nop";
7217 [(set (attr "type") (const_string "multi"))
7218 (set (attr "length")
7219 (if_then_else (eq_attr "delayed_branch" "true")
7223 ;; For __builtin_setjmp we need to flush register windows iff the function
7224 ;; calls alloca as well, because otherwise the register window might be
7225 ;; saved after %sp adjustment and thus setjmp would crash
7226 (define_expand "builtin_setjmp_setup"
7227 [(match_operand 0 "register_operand" "r")]
7230 emit_insn (gen_do_builtin_setjmp_setup ());
7234 (define_insn "do_builtin_setjmp_setup"
7235 [(unspec_volatile [(const_int 0)] UNSPECV_SETJMP)]
7238 if (! current_function_calls_alloca)
7242 fputs ("\tflushw\n", asm_out_file);
7244 fprintf (asm_out_file, "\tst%c\t%%l7, [%%sp+%d]\n",
7245 TARGET_ARCH64 ? 'x' : 'w',
7246 SPARC_STACK_BIAS + 7 * UNITS_PER_WORD);
7247 fprintf (asm_out_file, "\tst%c\t%%fp, [%%sp+%d]\n",
7248 TARGET_ARCH64 ? 'x' : 'w',
7249 SPARC_STACK_BIAS + 14 * UNITS_PER_WORD);
7250 fprintf (asm_out_file, "\tst%c\t%%i7, [%%sp+%d]\n",
7251 TARGET_ARCH64 ? 'x' : 'w',
7252 SPARC_STACK_BIAS + 15 * UNITS_PER_WORD);
7255 [(set_attr "type" "multi")
7256 (set (attr "length")
7257 (cond [(eq_attr "calls_alloca" "false")
7259 (eq_attr "isa" "!v9")
7261 (eq_attr "pic" "true")
7262 (const_int 4)] (const_int 3)))])
7264 ;; Pattern for use after a setjmp to store FP and the return register
7265 ;; into the stack area.
7267 (define_expand "setjmp"
7273 mem = gen_rtx_MEM (Pmode,
7274 plus_constant (stack_pointer_rtx,
7275 SPARC_STACK_BIAS + 14 * UNITS_PER_WORD));
7276 emit_insn (gen_rtx_SET (VOIDmode, mem, frame_pointer_rtx));
7278 mem = gen_rtx_MEM (Pmode,
7279 plus_constant (stack_pointer_rtx,
7280 SPARC_STACK_BIAS + 15 * UNITS_PER_WORD));
7281 emit_insn (gen_rtx_SET (VOIDmode, mem, gen_rtx_REG (Pmode, 31)));
7285 ;; Special pattern for the FLUSH instruction.
7287 ; We do SImode and DImode versions of this to quiet down genrecog's complaints
7288 ; of the define_insn otherwise missing a mode. We make "flush", aka
7289 ; gen_flush, the default one since sparc_initialize_trampoline uses
7290 ; it on SImode mem values.
7292 (define_insn "flush"
7293 [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")] UNSPECV_FLUSH)]
7295 { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; }
7296 [(set_attr "type" "iflush")])
7298 (define_insn "flushdi"
7299 [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")] UNSPECV_FLUSH)]
7301 { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; }
7302 [(set_attr "type" "iflush")])
7305 ;; Find first set instructions.
7307 ;; The scan instruction searches from the most significant bit while ffs
7308 ;; searches from the least significant bit. The bit index and treatment of
7309 ;; zero also differ. It takes at least 7 instructions to get the proper
7310 ;; result. Here is an obvious 8 instruction sequence.
7313 (define_insn "ffssi2"
7314 [(set (match_operand:SI 0 "register_operand" "=&r")
7315 (ffs:SI (match_operand:SI 1 "register_operand" "r")))
7316 (clobber (match_scratch:SI 2 "=&r"))]
7317 "TARGET_SPARCLITE || TARGET_SPARCLET"
7319 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";
7321 [(set_attr "type" "multi")
7322 (set_attr "length" "8")])
7324 ;; ??? This should be a define expand, so that the extra instruction have
7325 ;; a chance of being optimized away.
7327 ;; Disabled because none of the UltraSPARCs implement popc. The HAL R1
7328 ;; does, but no one uses that and we don't have a switch for it.
7330 ;(define_insn "ffsdi2"
7331 ; [(set (match_operand:DI 0 "register_operand" "=&r")
7332 ; (ffs:DI (match_operand:DI 1 "register_operand" "r")))
7333 ; (clobber (match_scratch:DI 2 "=&r"))]
7335 ; "neg\t%1, %2\;xnor\t%1, %2, %2\;popc\t%2, %0\;movzr\t%1, 0, %0"
7336 ; [(set_attr "type" "multi")
7337 ; (set_attr "length" "4")])
7341 ;; Peepholes go at the end.
7343 ;; Optimize consecutive loads or stores into ldd and std when possible.
7344 ;; The conditions in which we do this are very restricted and are
7345 ;; explained in the code for {registers,memory}_ok_for_ldd functions.
7348 [(set (match_operand:SI 0 "memory_operand" "")
7350 (set (match_operand:SI 1 "memory_operand" "")
7353 && mems_ok_for_ldd_peep (operands[0], operands[1], NULL_RTX)"
7356 "operands[0] = widen_memory_access (operands[0], DImode, 0);")
7359 [(set (match_operand:SI 0 "memory_operand" "")
7361 (set (match_operand:SI 1 "memory_operand" "")
7364 && mems_ok_for_ldd_peep (operands[1], operands[0], NULL_RTX)"
7367 "operands[1] = widen_memory_access (operands[1], DImode, 0);")
7370 [(set (match_operand:SI 0 "register_operand" "")
7371 (match_operand:SI 1 "memory_operand" ""))
7372 (set (match_operand:SI 2 "register_operand" "")
7373 (match_operand:SI 3 "memory_operand" ""))]
7374 "registers_ok_for_ldd_peep (operands[0], operands[2])
7375 && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
7378 "operands[1] = widen_memory_access (operands[1], DImode, 0);
7379 operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));")
7382 [(set (match_operand:SI 0 "memory_operand" "")
7383 (match_operand:SI 1 "register_operand" ""))
7384 (set (match_operand:SI 2 "memory_operand" "")
7385 (match_operand:SI 3 "register_operand" ""))]
7386 "registers_ok_for_ldd_peep (operands[1], operands[3])
7387 && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
7390 "operands[0] = widen_memory_access (operands[0], DImode, 0);
7391 operands[1] = gen_rtx_REG (DImode, REGNO (operands[1]));")
7394 [(set (match_operand:SF 0 "register_operand" "")
7395 (match_operand:SF 1 "memory_operand" ""))
7396 (set (match_operand:SF 2 "register_operand" "")
7397 (match_operand:SF 3 "memory_operand" ""))]
7398 "registers_ok_for_ldd_peep (operands[0], operands[2])
7399 && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
7402 "operands[1] = widen_memory_access (operands[1], DFmode, 0);
7403 operands[0] = gen_rtx_REG (DFmode, REGNO (operands[0]));")
7406 [(set (match_operand:SF 0 "memory_operand" "")
7407 (match_operand:SF 1 "register_operand" ""))
7408 (set (match_operand:SF 2 "memory_operand" "")
7409 (match_operand:SF 3 "register_operand" ""))]
7410 "registers_ok_for_ldd_peep (operands[1], operands[3])
7411 && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
7414 "operands[0] = widen_memory_access (operands[0], DFmode, 0);
7415 operands[1] = gen_rtx_REG (DFmode, REGNO (operands[1]));")
7418 [(set (match_operand:SI 0 "register_operand" "")
7419 (match_operand:SI 1 "memory_operand" ""))
7420 (set (match_operand:SI 2 "register_operand" "")
7421 (match_operand:SI 3 "memory_operand" ""))]
7422 "registers_ok_for_ldd_peep (operands[2], operands[0])
7423 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
7426 "operands[3] = widen_memory_access (operands[3], DImode, 0);
7427 operands[2] = gen_rtx_REG (DImode, REGNO (operands[2]));")
7430 [(set (match_operand:SI 0 "memory_operand" "")
7431 (match_operand:SI 1 "register_operand" ""))
7432 (set (match_operand:SI 2 "memory_operand" "")
7433 (match_operand:SI 3 "register_operand" ""))]
7434 "registers_ok_for_ldd_peep (operands[3], operands[1])
7435 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
7438 "operands[2] = widen_memory_access (operands[2], DImode, 0);
7439 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
7443 [(set (match_operand:SF 0 "register_operand" "")
7444 (match_operand:SF 1 "memory_operand" ""))
7445 (set (match_operand:SF 2 "register_operand" "")
7446 (match_operand:SF 3 "memory_operand" ""))]
7447 "registers_ok_for_ldd_peep (operands[2], operands[0])
7448 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
7451 "operands[3] = widen_memory_access (operands[3], DFmode, 0);
7452 operands[2] = gen_rtx_REG (DFmode, REGNO (operands[2]));")
7455 [(set (match_operand:SF 0 "memory_operand" "")
7456 (match_operand:SF 1 "register_operand" ""))
7457 (set (match_operand:SF 2 "memory_operand" "")
7458 (match_operand:SF 3 "register_operand" ""))]
7459 "registers_ok_for_ldd_peep (operands[3], operands[1])
7460 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
7463 "operands[2] = widen_memory_access (operands[2], DFmode, 0);
7464 operands[3] = gen_rtx_REG (DFmode, REGNO (operands[3]));")
7466 ;; Optimize the case of following a reg-reg move with a test
7467 ;; of reg just moved. Don't allow floating point regs for operand 0 or 1.
7468 ;; This can result from a float to fix conversion.
7471 [(set (match_operand:SI 0 "register_operand" "")
7472 (match_operand:SI 1 "register_operand" ""))
7474 (compare:CC (match_operand:SI 2 "register_operand" "")
7476 "(rtx_equal_p (operands[2], operands[0])
7477 || rtx_equal_p (operands[2], operands[1]))
7478 && ! SPARC_FP_REG_P (REGNO (operands[0]))
7479 && ! SPARC_FP_REG_P (REGNO (operands[1]))"
7480 [(parallel [(set (match_dup 0) (match_dup 1))
7482 (compare:CC (match_dup 1) (const_int 0)))])]
7486 [(set (match_operand:DI 0 "register_operand" "")
7487 (match_operand:DI 1 "register_operand" ""))
7489 (compare:CCX (match_operand:DI 2 "register_operand" "")
7492 && (rtx_equal_p (operands[2], operands[0])
7493 || rtx_equal_p (operands[2], operands[1]))
7494 && ! SPARC_FP_REG_P (REGNO (operands[0]))
7495 && ! SPARC_FP_REG_P (REGNO (operands[1]))"
7496 [(parallel [(set (match_dup 0) (match_dup 1))
7498 (compare:CCX (match_dup 1) (const_int 0)))])]
7502 ;; Prefetch instructions.
7504 ;; ??? UltraSPARC-III note: A memory operation loading into the floating point register
7505 ;; ??? file, if it hits the prefetch cache, has a chance to dual-issue with other memory
7506 ;; ??? operations. With DFA we might be able to model this, but it requires a lot of
7508 (define_expand "prefetch"
7509 [(match_operand 0 "address_operand" "")
7510 (match_operand 1 "const_int_operand" "")
7511 (match_operand 2 "const_int_operand" "")]
7515 emit_insn (gen_prefetch_64 (operands[0], operands[1], operands[2]));
7517 emit_insn (gen_prefetch_32 (operands[0], operands[1], operands[2]));
7521 (define_insn "prefetch_64"
7522 [(prefetch (match_operand:DI 0 "address_operand" "p")
7523 (match_operand:DI 1 "const_int_operand" "n")
7524 (match_operand:DI 2 "const_int_operand" "n"))]
7527 static const char * const prefetch_instr[2][2] = {
7529 "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
7530 "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
7533 "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
7534 "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
7537 int read_or_write = INTVAL (operands[1]);
7538 int locality = INTVAL (operands[2]);
7540 gcc_assert (read_or_write == 0 || read_or_write == 1);
7541 gcc_assert (locality >= 0 && locality < 4);
7542 return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
7544 [(set_attr "type" "load")])
7546 (define_insn "prefetch_32"
7547 [(prefetch (match_operand:SI 0 "address_operand" "p")
7548 (match_operand:SI 1 "const_int_operand" "n")
7549 (match_operand:SI 2 "const_int_operand" "n"))]
7552 static const char * const prefetch_instr[2][2] = {
7554 "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
7555 "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
7558 "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
7559 "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
7562 int read_or_write = INTVAL (operands[1]);
7563 int locality = INTVAL (operands[2]);
7565 gcc_assert (read_or_write == 0 || read_or_write == 1);
7566 gcc_assert (locality >= 0 && locality < 4);
7567 return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
7569 [(set_attr "type" "load")])
7572 ;; Trap instructions.
7575 [(trap_if (const_int 1) (const_int 5))]
7578 [(set_attr "type" "trap")])
7580 (define_expand "conditional_trap"
7581 [(trap_if (match_operator 0 "noov_compare_operator" [(match_dup 2) (match_dup 3)])
7582 (match_operand:SI 1 "arith_operand" ""))]
7584 "operands[2] = gen_compare_reg (GET_CODE (operands[0]));
7585 if (GET_MODE (operands[2]) != CCmode && GET_MODE (operands[2]) != CCXmode)
7587 operands[3] = const0_rtx;")
7590 [(trap_if (match_operator 0 "noov_compare_operator" [(reg:CC 100) (const_int 0)])
7591 (match_operand:SI 1 "arith_operand" "rM"))]
7595 return "t%C0\t%%icc, %1";
7599 [(set_attr "type" "trap")])
7602 [(trap_if (match_operator 0 "noov_compare_operator" [(reg:CCX 100) (const_int 0)])
7603 (match_operand:SI 1 "arith_operand" "rM"))]
7606 [(set_attr "type" "trap")])
7609 ;; TLS support instructions.
7611 (define_insn "tgd_hi22"
7612 [(set (match_operand:SI 0 "register_operand" "=r")
7613 (high:SI (unspec:SI [(match_operand 1 "tgd_symbolic_operand" "")]
7616 "sethi\\t%%tgd_hi22(%a1), %0")
7618 (define_insn "tgd_lo10"
7619 [(set (match_operand:SI 0 "register_operand" "=r")
7620 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7621 (unspec:SI [(match_operand 2 "tgd_symbolic_operand" "")]
7624 "add\\t%1, %%tgd_lo10(%a2), %0")
7626 (define_insn "tgd_add32"
7627 [(set (match_operand:SI 0 "register_operand" "=r")
7628 (plus:SI (match_operand:SI 1 "register_operand" "r")
7629 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7630 (match_operand 3 "tgd_symbolic_operand" "")]
7632 "TARGET_TLS && TARGET_ARCH32"
7633 "add\\t%1, %2, %0, %%tgd_add(%a3)")
7635 (define_insn "tgd_add64"
7636 [(set (match_operand:DI 0 "register_operand" "=r")
7637 (plus:DI (match_operand:DI 1 "register_operand" "r")
7638 (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7639 (match_operand 3 "tgd_symbolic_operand" "")]
7641 "TARGET_TLS && TARGET_ARCH64"
7642 "add\\t%1, %2, %0, %%tgd_add(%a3)")
7644 (define_insn "tgd_call32"
7645 [(set (match_operand 0 "register_operand" "=r")
7646 (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")
7647 (match_operand 2 "tgd_symbolic_operand" "")]
7649 (match_operand 3 "" "")))
7650 (clobber (reg:SI 15))]
7651 "TARGET_TLS && TARGET_ARCH32"
7652 "call\t%a1, %%tgd_call(%a2)%#"
7653 [(set_attr "type" "call")])
7655 (define_insn "tgd_call64"
7656 [(set (match_operand 0 "register_operand" "=r")
7657 (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")
7658 (match_operand 2 "tgd_symbolic_operand" "")]
7660 (match_operand 3 "" "")))
7661 (clobber (reg:DI 15))]
7662 "TARGET_TLS && TARGET_ARCH64"
7663 "call\t%a1, %%tgd_call(%a2)%#"
7664 [(set_attr "type" "call")])
7666 (define_insn "tldm_hi22"
7667 [(set (match_operand:SI 0 "register_operand" "=r")
7668 (high:SI (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
7670 "sethi\\t%%tldm_hi22(%&), %0")
7672 (define_insn "tldm_lo10"
7673 [(set (match_operand:SI 0 "register_operand" "=r")
7674 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7675 (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
7677 "add\\t%1, %%tldm_lo10(%&), %0")
7679 (define_insn "tldm_add32"
7680 [(set (match_operand:SI 0 "register_operand" "=r")
7681 (plus:SI (match_operand:SI 1 "register_operand" "r")
7682 (unspec:SI [(match_operand:SI 2 "register_operand" "r")]
7684 "TARGET_TLS && TARGET_ARCH32"
7685 "add\\t%1, %2, %0, %%tldm_add(%&)")
7687 (define_insn "tldm_add64"
7688 [(set (match_operand:DI 0 "register_operand" "=r")
7689 (plus:DI (match_operand:DI 1 "register_operand" "r")
7690 (unspec:DI [(match_operand:SI 2 "register_operand" "r")]
7692 "TARGET_TLS && TARGET_ARCH64"
7693 "add\\t%1, %2, %0, %%tldm_add(%&)")
7695 (define_insn "tldm_call32"
7696 [(set (match_operand 0 "register_operand" "=r")
7697 (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")]
7699 (match_operand 2 "" "")))
7700 (clobber (reg:SI 15))]
7701 "TARGET_TLS && TARGET_ARCH32"
7702 "call\t%a1, %%tldm_call(%&)%#"
7703 [(set_attr "type" "call")])
7705 (define_insn "tldm_call64"
7706 [(set (match_operand 0 "register_operand" "=r")
7707 (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")]
7709 (match_operand 2 "" "")))
7710 (clobber (reg:DI 15))]
7711 "TARGET_TLS && TARGET_ARCH64"
7712 "call\t%a1, %%tldm_call(%&)%#"
7713 [(set_attr "type" "call")])
7715 (define_insn "tldo_hix22"
7716 [(set (match_operand:SI 0 "register_operand" "=r")
7717 (high:SI (unspec:SI [(match_operand 1 "tld_symbolic_operand" "")]
7720 "sethi\\t%%tldo_hix22(%a1), %0")
7722 (define_insn "tldo_lox10"
7723 [(set (match_operand:SI 0 "register_operand" "=r")
7724 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7725 (unspec:SI [(match_operand 2 "tld_symbolic_operand" "")]
7728 "xor\\t%1, %%tldo_lox10(%a2), %0")
7730 (define_insn "tldo_add32"
7731 [(set (match_operand:SI 0 "register_operand" "=r")
7732 (plus:SI (match_operand:SI 1 "register_operand" "r")
7733 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7734 (match_operand 3 "tld_symbolic_operand" "")]
7736 "TARGET_TLS && TARGET_ARCH32"
7737 "add\\t%1, %2, %0, %%tldo_add(%a3)")
7739 (define_insn "tldo_add64"
7740 [(set (match_operand:DI 0 "register_operand" "=r")
7741 (plus:DI (match_operand:DI 1 "register_operand" "r")
7742 (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7743 (match_operand 3 "tld_symbolic_operand" "")]
7745 "TARGET_TLS && TARGET_ARCH64"
7746 "add\\t%1, %2, %0, %%tldo_add(%a3)")
7748 (define_insn "tie_hi22"
7749 [(set (match_operand:SI 0 "register_operand" "=r")
7750 (high:SI (unspec:SI [(match_operand 1 "tie_symbolic_operand" "")]
7753 "sethi\\t%%tie_hi22(%a1), %0")
7755 (define_insn "tie_lo10"
7756 [(set (match_operand:SI 0 "register_operand" "=r")
7757 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7758 (unspec:SI [(match_operand 2 "tie_symbolic_operand" "")]
7761 "add\\t%1, %%tie_lo10(%a2), %0")
7763 (define_insn "tie_ld32"
7764 [(set (match_operand:SI 0 "register_operand" "=r")
7765 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
7766 (match_operand:SI 2 "register_operand" "r")
7767 (match_operand 3 "tie_symbolic_operand" "")]
7769 "TARGET_TLS && TARGET_ARCH32"
7770 "ld\\t[%1 + %2], %0, %%tie_ld(%a3)"
7771 [(set_attr "type" "load")])
7773 (define_insn "tie_ld64"
7774 [(set (match_operand:DI 0 "register_operand" "=r")
7775 (unspec:DI [(match_operand:DI 1 "register_operand" "r")
7776 (match_operand:SI 2 "register_operand" "r")
7777 (match_operand 3 "tie_symbolic_operand" "")]
7779 "TARGET_TLS && TARGET_ARCH64"
7780 "ldx\\t[%1 + %2], %0, %%tie_ldx(%a3)"
7781 [(set_attr "type" "load")])
7783 (define_insn "tie_add32"
7784 [(set (match_operand:SI 0 "register_operand" "=r")
7785 (plus:SI (match_operand:SI 1 "register_operand" "r")
7786 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7787 (match_operand 3 "tie_symbolic_operand" "")]
7789 "TARGET_SUN_TLS && TARGET_ARCH32"
7790 "add\\t%1, %2, %0, %%tie_add(%a3)")
7792 (define_insn "tie_add64"
7793 [(set (match_operand:DI 0 "register_operand" "=r")
7794 (plus:DI (match_operand:DI 1 "register_operand" "r")
7795 (unspec:DI [(match_operand:DI 2 "register_operand" "r")
7796 (match_operand 3 "tie_symbolic_operand" "")]
7798 "TARGET_SUN_TLS && TARGET_ARCH64"
7799 "add\\t%1, %2, %0, %%tie_add(%a3)")
7801 (define_insn "tle_hix22_sp32"
7802 [(set (match_operand:SI 0 "register_operand" "=r")
7803 (high:SI (unspec:SI [(match_operand 1 "tle_symbolic_operand" "")]
7805 "TARGET_TLS && TARGET_ARCH32"
7806 "sethi\\t%%tle_hix22(%a1), %0")
7808 (define_insn "tle_lox10_sp32"
7809 [(set (match_operand:SI 0 "register_operand" "=r")
7810 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7811 (unspec:SI [(match_operand 2 "tle_symbolic_operand" "")]
7813 "TARGET_TLS && TARGET_ARCH32"
7814 "xor\\t%1, %%tle_lox10(%a2), %0")
7816 (define_insn "tle_hix22_sp64"
7817 [(set (match_operand:DI 0 "register_operand" "=r")
7818 (high:DI (unspec:DI [(match_operand 1 "tle_symbolic_operand" "")]
7820 "TARGET_TLS && TARGET_ARCH64"
7821 "sethi\\t%%tle_hix22(%a1), %0")
7823 (define_insn "tle_lox10_sp64"
7824 [(set (match_operand:DI 0 "register_operand" "=r")
7825 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
7826 (unspec:DI [(match_operand 2 "tle_symbolic_operand" "")]
7828 "TARGET_TLS && TARGET_ARCH64"
7829 "xor\\t%1, %%tle_lox10(%a2), %0")
7831 ;; Now patterns combining tldo_add{32,64} with some integer loads or stores
7832 (define_insn "*tldo_ldub_sp32"
7833 [(set (match_operand:QI 0 "register_operand" "=r")
7834 (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7835 (match_operand 3 "tld_symbolic_operand" "")]
7837 (match_operand:SI 1 "register_operand" "r"))))]
7838 "TARGET_TLS && TARGET_ARCH32"
7839 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7840 [(set_attr "type" "load")
7841 (set_attr "us3load_type" "3cycle")])
7843 (define_insn "*tldo_ldub1_sp32"
7844 [(set (match_operand:HI 0 "register_operand" "=r")
7845 (zero_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7846 (match_operand 3 "tld_symbolic_operand" "")]
7848 (match_operand:SI 1 "register_operand" "r")))))]
7849 "TARGET_TLS && TARGET_ARCH32"
7850 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7851 [(set_attr "type" "load")
7852 (set_attr "us3load_type" "3cycle")])
7854 (define_insn "*tldo_ldub2_sp32"
7855 [(set (match_operand:SI 0 "register_operand" "=r")
7856 (zero_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7857 (match_operand 3 "tld_symbolic_operand" "")]
7859 (match_operand:SI 1 "register_operand" "r")))))]
7860 "TARGET_TLS && TARGET_ARCH32"
7861 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7862 [(set_attr "type" "load")
7863 (set_attr "us3load_type" "3cycle")])
7865 (define_insn "*tldo_ldsb1_sp32"
7866 [(set (match_operand:HI 0 "register_operand" "=r")
7867 (sign_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7868 (match_operand 3 "tld_symbolic_operand" "")]
7870 (match_operand:SI 1 "register_operand" "r")))))]
7871 "TARGET_TLS && TARGET_ARCH32"
7872 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7873 [(set_attr "type" "sload")
7874 (set_attr "us3load_type" "3cycle")])
7876 (define_insn "*tldo_ldsb2_sp32"
7877 [(set (match_operand:SI 0 "register_operand" "=r")
7878 (sign_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7879 (match_operand 3 "tld_symbolic_operand" "")]
7881 (match_operand:SI 1 "register_operand" "r")))))]
7882 "TARGET_TLS && TARGET_ARCH32"
7883 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7884 [(set_attr "type" "sload")
7885 (set_attr "us3load_type" "3cycle")])
7887 (define_insn "*tldo_ldub_sp64"
7888 [(set (match_operand:QI 0 "register_operand" "=r")
7889 (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7890 (match_operand 3 "tld_symbolic_operand" "")]
7892 (match_operand:DI 1 "register_operand" "r"))))]
7893 "TARGET_TLS && TARGET_ARCH64"
7894 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7895 [(set_attr "type" "load")
7896 (set_attr "us3load_type" "3cycle")])
7898 (define_insn "*tldo_ldub1_sp64"
7899 [(set (match_operand:HI 0 "register_operand" "=r")
7900 (zero_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7901 (match_operand 3 "tld_symbolic_operand" "")]
7903 (match_operand:DI 1 "register_operand" "r")))))]
7904 "TARGET_TLS && TARGET_ARCH64"
7905 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7906 [(set_attr "type" "load")
7907 (set_attr "us3load_type" "3cycle")])
7909 (define_insn "*tldo_ldub2_sp64"
7910 [(set (match_operand:SI 0 "register_operand" "=r")
7911 (zero_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7912 (match_operand 3 "tld_symbolic_operand" "")]
7914 (match_operand:DI 1 "register_operand" "r")))))]
7915 "TARGET_TLS && TARGET_ARCH64"
7916 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7917 [(set_attr "type" "load")
7918 (set_attr "us3load_type" "3cycle")])
7920 (define_insn "*tldo_ldub3_sp64"
7921 [(set (match_operand:DI 0 "register_operand" "=r")
7922 (zero_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7923 (match_operand 3 "tld_symbolic_operand" "")]
7925 (match_operand:DI 1 "register_operand" "r")))))]
7926 "TARGET_TLS && TARGET_ARCH64"
7927 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7928 [(set_attr "type" "load")
7929 (set_attr "us3load_type" "3cycle")])
7931 (define_insn "*tldo_ldsb1_sp64"
7932 [(set (match_operand:HI 0 "register_operand" "=r")
7933 (sign_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7934 (match_operand 3 "tld_symbolic_operand" "")]
7936 (match_operand:DI 1 "register_operand" "r")))))]
7937 "TARGET_TLS && TARGET_ARCH64"
7938 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7939 [(set_attr "type" "sload")
7940 (set_attr "us3load_type" "3cycle")])
7942 (define_insn "*tldo_ldsb2_sp64"
7943 [(set (match_operand:SI 0 "register_operand" "=r")
7944 (sign_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7945 (match_operand 3 "tld_symbolic_operand" "")]
7947 (match_operand:DI 1 "register_operand" "r")))))]
7948 "TARGET_TLS && TARGET_ARCH64"
7949 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7950 [(set_attr "type" "sload")
7951 (set_attr "us3load_type" "3cycle")])
7953 (define_insn "*tldo_ldsb3_sp64"
7954 [(set (match_operand:DI 0 "register_operand" "=r")
7955 (sign_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7956 (match_operand 3 "tld_symbolic_operand" "")]
7958 (match_operand:DI 1 "register_operand" "r")))))]
7959 "TARGET_TLS && TARGET_ARCH64"
7960 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7961 [(set_attr "type" "sload")
7962 (set_attr "us3load_type" "3cycle")])
7964 (define_insn "*tldo_lduh_sp32"
7965 [(set (match_operand:HI 0 "register_operand" "=r")
7966 (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7967 (match_operand 3 "tld_symbolic_operand" "")]
7969 (match_operand:SI 1 "register_operand" "r"))))]
7970 "TARGET_TLS && TARGET_ARCH32"
7971 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7972 [(set_attr "type" "load")
7973 (set_attr "us3load_type" "3cycle")])
7975 (define_insn "*tldo_lduh1_sp32"
7976 [(set (match_operand:SI 0 "register_operand" "=r")
7977 (zero_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7978 (match_operand 3 "tld_symbolic_operand" "")]
7980 (match_operand:SI 1 "register_operand" "r")))))]
7981 "TARGET_TLS && TARGET_ARCH32"
7982 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7983 [(set_attr "type" "load")
7984 (set_attr "us3load_type" "3cycle")])
7986 (define_insn "*tldo_ldsh1_sp32"
7987 [(set (match_operand:SI 0 "register_operand" "=r")
7988 (sign_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7989 (match_operand 3 "tld_symbolic_operand" "")]
7991 (match_operand:SI 1 "register_operand" "r")))))]
7992 "TARGET_TLS && TARGET_ARCH32"
7993 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
7994 [(set_attr "type" "sload")
7995 (set_attr "us3load_type" "3cycle")])
7997 (define_insn "*tldo_lduh_sp64"
7998 [(set (match_operand:HI 0 "register_operand" "=r")
7999 (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8000 (match_operand 3 "tld_symbolic_operand" "")]
8002 (match_operand:DI 1 "register_operand" "r"))))]
8003 "TARGET_TLS && TARGET_ARCH64"
8004 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
8005 [(set_attr "type" "load")
8006 (set_attr "us3load_type" "3cycle")])
8008 (define_insn "*tldo_lduh1_sp64"
8009 [(set (match_operand:SI 0 "register_operand" "=r")
8010 (zero_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8011 (match_operand 3 "tld_symbolic_operand" "")]
8013 (match_operand:DI 1 "register_operand" "r")))))]
8014 "TARGET_TLS && TARGET_ARCH64"
8015 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
8016 [(set_attr "type" "load")
8017 (set_attr "us3load_type" "3cycle")])
8019 (define_insn "*tldo_lduh2_sp64"
8020 [(set (match_operand:DI 0 "register_operand" "=r")
8021 (zero_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8022 (match_operand 3 "tld_symbolic_operand" "")]
8024 (match_operand:DI 1 "register_operand" "r")))))]
8025 "TARGET_TLS && TARGET_ARCH64"
8026 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
8027 [(set_attr "type" "load")
8028 (set_attr "us3load_type" "3cycle")])
8030 (define_insn "*tldo_ldsh1_sp64"
8031 [(set (match_operand:SI 0 "register_operand" "=r")
8032 (sign_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8033 (match_operand 3 "tld_symbolic_operand" "")]
8035 (match_operand:DI 1 "register_operand" "r")))))]
8036 "TARGET_TLS && TARGET_ARCH64"
8037 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
8038 [(set_attr "type" "sload")
8039 (set_attr "us3load_type" "3cycle")])
8041 (define_insn "*tldo_ldsh2_sp64"
8042 [(set (match_operand:DI 0 "register_operand" "=r")
8043 (sign_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8044 (match_operand 3 "tld_symbolic_operand" "")]
8046 (match_operand:DI 1 "register_operand" "r")))))]
8047 "TARGET_TLS && TARGET_ARCH64"
8048 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
8049 [(set_attr "type" "sload")
8050 (set_attr "us3load_type" "3cycle")])
8052 (define_insn "*tldo_lduw_sp32"
8053 [(set (match_operand:SI 0 "register_operand" "=r")
8054 (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8055 (match_operand 3 "tld_symbolic_operand" "")]
8057 (match_operand:SI 1 "register_operand" "r"))))]
8058 "TARGET_TLS && TARGET_ARCH32"
8059 "ld\t[%1 + %2], %0, %%tldo_add(%3)"
8060 [(set_attr "type" "load")])
8062 (define_insn "*tldo_lduw_sp64"
8063 [(set (match_operand:SI 0 "register_operand" "=r")
8064 (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8065 (match_operand 3 "tld_symbolic_operand" "")]
8067 (match_operand:DI 1 "register_operand" "r"))))]
8068 "TARGET_TLS && TARGET_ARCH64"
8069 "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
8070 [(set_attr "type" "load")])
8072 (define_insn "*tldo_lduw1_sp64"
8073 [(set (match_operand:DI 0 "register_operand" "=r")
8074 (zero_extend:DI (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8075 (match_operand 3 "tld_symbolic_operand" "")]
8077 (match_operand:DI 1 "register_operand" "r")))))]
8078 "TARGET_TLS && TARGET_ARCH64"
8079 "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
8080 [(set_attr "type" "load")])
8082 (define_insn "*tldo_ldsw1_sp64"
8083 [(set (match_operand:DI 0 "register_operand" "=r")
8084 (sign_extend:DI (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8085 (match_operand 3 "tld_symbolic_operand" "")]
8087 (match_operand:DI 1 "register_operand" "r")))))]
8088 "TARGET_TLS && TARGET_ARCH64"
8089 "ldsw\t[%1 + %2], %0, %%tldo_add(%3)"
8090 [(set_attr "type" "sload")
8091 (set_attr "us3load_type" "3cycle")])
8093 (define_insn "*tldo_ldx_sp64"
8094 [(set (match_operand:DI 0 "register_operand" "=r")
8095 (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8096 (match_operand 3 "tld_symbolic_operand" "")]
8098 (match_operand:DI 1 "register_operand" "r"))))]
8099 "TARGET_TLS && TARGET_ARCH64"
8100 "ldx\t[%1 + %2], %0, %%tldo_add(%3)"
8101 [(set_attr "type" "load")])
8103 (define_insn "*tldo_stb_sp32"
8104 [(set (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8105 (match_operand 3 "tld_symbolic_operand" "")]
8107 (match_operand:SI 1 "register_operand" "r")))
8108 (match_operand:QI 0 "register_operand" "=r"))]
8109 "TARGET_TLS && TARGET_ARCH32"
8110 "stb\t%0, [%1 + %2], %%tldo_add(%3)"
8111 [(set_attr "type" "store")])
8113 (define_insn "*tldo_stb_sp64"
8114 [(set (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8115 (match_operand 3 "tld_symbolic_operand" "")]
8117 (match_operand:DI 1 "register_operand" "r")))
8118 (match_operand:QI 0 "register_operand" "=r"))]
8119 "TARGET_TLS && TARGET_ARCH64"
8120 "stb\t%0, [%1 + %2], %%tldo_add(%3)"
8121 [(set_attr "type" "store")])
8123 (define_insn "*tldo_sth_sp32"
8124 [(set (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8125 (match_operand 3 "tld_symbolic_operand" "")]
8127 (match_operand:SI 1 "register_operand" "r")))
8128 (match_operand:HI 0 "register_operand" "=r"))]
8129 "TARGET_TLS && TARGET_ARCH32"
8130 "sth\t%0, [%1 + %2], %%tldo_add(%3)"
8131 [(set_attr "type" "store")])
8133 (define_insn "*tldo_sth_sp64"
8134 [(set (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8135 (match_operand 3 "tld_symbolic_operand" "")]
8137 (match_operand:DI 1 "register_operand" "r")))
8138 (match_operand:HI 0 "register_operand" "=r"))]
8139 "TARGET_TLS && TARGET_ARCH64"
8140 "sth\t%0, [%1 + %2], %%tldo_add(%3)"
8141 [(set_attr "type" "store")])
8143 (define_insn "*tldo_stw_sp32"
8144 [(set (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8145 (match_operand 3 "tld_symbolic_operand" "")]
8147 (match_operand:SI 1 "register_operand" "r")))
8148 (match_operand:SI 0 "register_operand" "=r"))]
8149 "TARGET_TLS && TARGET_ARCH32"
8150 "st\t%0, [%1 + %2], %%tldo_add(%3)"
8151 [(set_attr "type" "store")])
8153 (define_insn "*tldo_stw_sp64"
8154 [(set (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8155 (match_operand 3 "tld_symbolic_operand" "")]
8157 (match_operand:DI 1 "register_operand" "r")))
8158 (match_operand:SI 0 "register_operand" "=r"))]
8159 "TARGET_TLS && TARGET_ARCH64"
8160 "stw\t%0, [%1 + %2], %%tldo_add(%3)"
8161 [(set_attr "type" "store")])
8163 (define_insn "*tldo_stx_sp64"
8164 [(set (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8165 (match_operand 3 "tld_symbolic_operand" "")]
8167 (match_operand:DI 1 "register_operand" "r")))
8168 (match_operand:DI 0 "register_operand" "=r"))]
8169 "TARGET_TLS && TARGET_ARCH64"
8170 "stx\t%0, [%1 + %2], %%tldo_add(%3)"
8171 [(set_attr "type" "store")])
8174 ;; Stack protector instructions.
8176 (define_expand "stack_protect_set"
8177 [(match_operand 0 "memory_operand" "")
8178 (match_operand 1 "memory_operand" "")]
8181 #ifdef TARGET_THREAD_SSP_OFFSET
8182 rtx tlsreg = gen_rtx_REG (Pmode, 7);
8183 rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
8184 operands[1] = gen_rtx_MEM (Pmode, addr);
8187 emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
8189 emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
8193 (define_insn "stack_protect_setsi"
8194 [(set (match_operand:SI 0 "memory_operand" "=m")
8195 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
8196 (set (match_scratch:SI 2 "=&r") (const_int 0))]
8198 "ld\t%1, %2\;st\t%2, %0\;mov\t0, %2"
8199 [(set_attr "type" "multi")
8200 (set_attr "length" "3")])
8202 (define_insn "stack_protect_setdi"
8203 [(set (match_operand:DI 0 "memory_operand" "=m")
8204 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
8205 (set (match_scratch:DI 2 "=&r") (const_int 0))]
8207 "ldx\t%1, %2\;stx\t%2, %0\;mov\t0, %2"
8208 [(set_attr "type" "multi")
8209 (set_attr "length" "3")])
8211 (define_expand "stack_protect_test"
8212 [(match_operand 0 "memory_operand" "")
8213 (match_operand 1 "memory_operand" "")
8214 (match_operand 2 "" "")]
8217 #ifdef TARGET_THREAD_SSP_OFFSET
8218 rtx tlsreg = gen_rtx_REG (Pmode, 7);
8219 rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
8220 operands[1] = gen_rtx_MEM (Pmode, addr);
8224 rtx temp = gen_reg_rtx (Pmode);
8225 emit_insn (gen_stack_protect_testdi (temp, operands[0], operands[1]));
8226 sparc_compare_op0 = temp;
8227 sparc_compare_op1 = const0_rtx;
8231 emit_insn (gen_stack_protect_testsi (operands[0], operands[1]));
8232 sparc_compare_op0 = operands[0];
8233 sparc_compare_op1 = operands[1];
8234 sparc_compare_emitted = gen_rtx_REG (CCmode, SPARC_ICC_REG);
8236 emit_jump_insn (gen_beq (operands[2]));
8240 (define_insn "stack_protect_testsi"
8242 (unspec:CC [(match_operand:SI 0 "memory_operand" "m")
8243 (match_operand:SI 1 "memory_operand" "m")]
8245 (set (match_scratch:SI 3 "=r") (const_int 0))
8246 (clobber (match_scratch:SI 2 "=&r"))]
8248 "ld\t%0, %2\;ld\t%1, %3\;xorcc\t%2, %3, %2\;mov\t0, %3"
8249 [(set_attr "type" "multi")
8250 (set_attr "length" "4")])
8252 (define_insn "stack_protect_testdi"
8253 [(set (match_operand:DI 0 "register_operand" "=&r")
8254 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
8255 (match_operand:DI 2 "memory_operand" "m")]
8257 (set (match_scratch:DI 3 "=r") (const_int 0))]
8259 "ldx\t%1, %0\;ldx\t%2, %3\;xor\t%0, %3, %0\;mov\t0, %3"
8260 [(set_attr "type" "multi")
8261 (set_attr "length" "4")])
8264 ;; Vector instructions.
8266 (define_insn "addv2si3"
8267 [(set (match_operand:V2SI 0 "register_operand" "=e")
8268 (plus:V2SI (match_operand:V2SI 1 "register_operand" "e")
8269 (match_operand:V2SI 2 "register_operand" "e")))]
8271 "fpadd32\t%1, %2, %0"
8272 [(set_attr "type" "fga")
8273 (set_attr "fptype" "double")])
8275 (define_insn "addv4hi3"
8276 [(set (match_operand:V4HI 0 "register_operand" "=e")
8277 (plus:V4HI (match_operand:V4HI 1 "register_operand" "e")
8278 (match_operand:V4HI 2 "register_operand" "e")))]
8280 "fpadd16\t%1, %2, %0"
8281 [(set_attr "type" "fga")
8282 (set_attr "fptype" "double")])
8284 ;; fpadd32s is emitted by the addsi3 pattern.
8286 (define_insn "addv2hi3"
8287 [(set (match_operand:V2HI 0 "register_operand" "=f")
8288 (plus:V2HI (match_operand:V2HI 1 "register_operand" "f")
8289 (match_operand:V2HI 2 "register_operand" "f")))]
8291 "fpadd16s\t%1, %2, %0"
8292 [(set_attr "type" "fga")
8293 (set_attr "fptype" "single")])
8295 (define_insn "subv2si3"
8296 [(set (match_operand:V2SI 0 "register_operand" "=e")
8297 (minus:V2SI (match_operand:V2SI 1 "register_operand" "e")
8298 (match_operand:V2SI 2 "register_operand" "e")))]
8300 "fpsub32\t%1, %2, %0"
8301 [(set_attr "type" "fga")
8302 (set_attr "fptype" "double")])
8304 (define_insn "subv4hi3"
8305 [(set (match_operand:V4HI 0 "register_operand" "=e")
8306 (minus:V4HI (match_operand:V4HI 1 "register_operand" "e")
8307 (match_operand:V4HI 2 "register_operand" "e")))]
8309 "fpsub16\t%1, %2, %0"
8310 [(set_attr "type" "fga")
8311 (set_attr "fptype" "double")])
8313 ;; fpsub32s is emitted by the subsi3 pattern.
8315 (define_insn "subv2hi3"
8316 [(set (match_operand:V2HI 0 "register_operand" "=f")
8317 (minus:V2HI (match_operand:V2HI 1 "register_operand" "f")
8318 (match_operand:V2HI 2 "register_operand" "f")))]
8320 "fpsub16s\t%1, %2, %0"
8321 [(set_attr "type" "fga")
8322 (set_attr "fptype" "single")])
8324 ;; All other logical instructions have integer equivalents so they
8325 ;; are defined together.
8327 ;; (ior (not (op1)) (not (op2))) is the canonical form of NAND.
8329 (define_insn "*nand<V64mode>_vis"
8330 [(set (match_operand:V64 0 "register_operand" "=e")
8331 (ior:V64 (not:V64 (match_operand:V64 1 "register_operand" "e"))
8332 (not:V64 (match_operand:V64 2 "register_operand" "e"))))]
8335 [(set_attr "type" "fga")
8336 (set_attr "fptype" "double")])
8338 (define_insn "*nand<V32mode>_vis"
8339 [(set (match_operand:V32 0 "register_operand" "=f")
8340 (ior:V32 (not:V32 (match_operand:V32 1 "register_operand" "f"))
8341 (not:V32 (match_operand:V32 2 "register_operand" "f"))))]
8343 "fnands\t%1, %2, %0"
8344 [(set_attr "type" "fga")
8345 (set_attr "fptype" "single")])
8347 ;; Hard to generate VIS instructions. We have builtins for these.
8349 (define_insn "fpack16_vis"
8350 [(set (match_operand:V4QI 0 "register_operand" "=f")
8351 (unspec:V4QI [(match_operand:V4HI 1 "register_operand" "e")]
8355 [(set_attr "type" "fga")
8356 (set_attr "fptype" "double")])
8358 (define_insn "fpackfix_vis"
8359 [(set (match_operand:V2HI 0 "register_operand" "=f")
8360 (unspec:V2HI [(match_operand:V2SI 1 "register_operand" "e")]
8364 [(set_attr "type" "fga")
8365 (set_attr "fptype" "double")])
8367 (define_insn "fpack32_vis"
8368 [(set (match_operand:V8QI 0 "register_operand" "=e")
8369 (unspec:V8QI [(match_operand:V2SI 1 "register_operand" "e")
8370 (match_operand:V8QI 2 "register_operand" "e")]
8373 "fpack32\t%1, %2, %0"
8374 [(set_attr "type" "fga")
8375 (set_attr "fptype" "double")])
8377 (define_insn "fexpand_vis"
8378 [(set (match_operand:V4HI 0 "register_operand" "=e")
8379 (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")]
8383 [(set_attr "type" "fga")
8384 (set_attr "fptype" "double")])
8386 ;; It may be possible to describe this operation as (1 indexed):
8387 ;; (vec_select (vec_duplicate (vec_duplicate (vec_concat 1 2)))
8388 ;; 1,5,10,14,19,23,28,32)
8389 ;; Note that (vec_merge:V8QI [(V4QI) (V4QI)] (10101010 = 170) doesn't work
8390 ;; because vec_merge expects all the operands to be of the same type.
8391 (define_insn "fpmerge_vis"
8392 [(set (match_operand:V8QI 0 "register_operand" "=e")
8393 (unspec:V8QI [(match_operand:V4QI 1 "register_operand" "f")
8394 (match_operand:V4QI 2 "register_operand" "f")]
8397 "fpmerge\t%1, %2, %0"
8398 [(set_attr "type" "fga")
8399 (set_attr "fptype" "double")])
8401 ;; Partitioned multiply instructions
8402 (define_insn "fmul8x16_vis"
8403 [(set (match_operand:V4HI 0 "register_operand" "=e")
8404 (mult:V4HI (match_operand:V4QI 1 "register_operand" "f")
8405 (match_operand:V4HI 2 "register_operand" "e")))]
8407 "fmul8x16\t%1, %2, %0"
8408 [(set_attr "type" "fpmul")
8409 (set_attr "fptype" "double")])
8411 ;; Only one of the following two insns can be a multiply.
8412 (define_insn "fmul8x16au_vis"
8413 [(set (match_operand:V4HI 0 "register_operand" "=e")
8414 (mult:V4HI (match_operand:V4QI 1 "register_operand" "f")
8415 (match_operand:V2HI 2 "register_operand" "f")))]
8417 "fmul8x16au\t%1, %2, %0"
8418 [(set_attr "type" "fpmul")
8419 (set_attr "fptype" "double")])
8421 (define_insn "fmul8x16al_vis"
8422 [(set (match_operand:V4HI 0 "register_operand" "=e")
8423 (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")
8424 (match_operand:V2HI 2 "register_operand" "f")]
8427 "fmul8x16al\t%1, %2, %0"
8428 [(set_attr "type" "fpmul")
8429 (set_attr "fptype" "double")])
8431 ;; Only one of the following two insns can be a multiply.
8432 (define_insn "fmul8sux16_vis"
8433 [(set (match_operand:V4HI 0 "register_operand" "=e")
8434 (mult:V4HI (match_operand:V8QI 1 "register_operand" "e")
8435 (match_operand:V4HI 2 "register_operand" "e")))]
8437 "fmul8sux16\t%1, %2, %0"
8438 [(set_attr "type" "fpmul")
8439 (set_attr "fptype" "double")])
8441 (define_insn "fmul8ulx16_vis"
8442 [(set (match_operand:V4HI 0 "register_operand" "=e")
8443 (unspec:V4HI [(match_operand:V8QI 1 "register_operand" "e")
8444 (match_operand:V4HI 2 "register_operand" "e")]
8447 "fmul8ulx16\t%1, %2, %0"
8448 [(set_attr "type" "fpmul")
8449 (set_attr "fptype" "double")])
8451 ;; Only one of the following two insns can be a multiply.
8452 (define_insn "fmuld8sux16_vis"
8453 [(set (match_operand:V2SI 0 "register_operand" "=e")
8454 (mult:V2SI (match_operand:V4QI 1 "register_operand" "f")
8455 (match_operand:V2HI 2 "register_operand" "f")))]
8457 "fmuld8sux16\t%1, %2, %0"
8458 [(set_attr "type" "fpmul")
8459 (set_attr "fptype" "double")])
8461 (define_insn "fmuld8ulx16_vis"
8462 [(set (match_operand:V2SI 0 "register_operand" "=e")
8463 (unspec:V2SI [(match_operand:V4QI 1 "register_operand" "f")
8464 (match_operand:V2HI 2 "register_operand" "f")]
8467 "fmuld8ulx16\t%1, %2, %0"
8468 [(set_attr "type" "fpmul")
8469 (set_attr "fptype" "double")])
8471 ;; Using faligndata only makes sense after an alignaddr since the choice of
8472 ;; bytes to take out of each operand is dependent on the results of the last
8474 (define_insn "faligndata<V64I:mode>_vis"
8475 [(set (match_operand:V64I 0 "register_operand" "=e")
8476 (unspec:V64I [(match_operand:V64I 1 "register_operand" "e")
8477 (match_operand:V64I 2 "register_operand" "e")]
8480 "faligndata\t%1, %2, %0"
8481 [(set_attr "type" "fga")
8482 (set_attr "fptype" "double")])
8484 (define_insn "alignaddr<P:mode>_vis"
8485 [(set (match_operand:P 0 "register_operand" "=r")
8486 (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
8487 (match_operand:P 2 "register_or_zero_operand" "rJ")]
8490 "alignaddr\t%r1, %r2, %0")
8492 (define_insn "pdist_vis"
8493 [(set (match_operand:DI 0 "register_operand" "=e")
8494 (unspec:DI [(match_operand:V8QI 1 "register_operand" "e")
8495 (match_operand:V8QI 2 "register_operand" "e")
8496 (match_operand:DI 3 "register_operand" "0")]
8500 [(set_attr "type" "fga")
8501 (set_attr "fptype" "double")])