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 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 2, 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 COPYING. If not, write to
22 ;; the Free Software Foundation, 51 Franklin Street, Fifth Floor,
23 ;; Boston, MA 02110-1301, USA.
25 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
29 (UNSPEC_UPDATE_RETURN 1)
30 (UNSPEC_LOAD_PCREL_SYM 2)
31 (UNSPEC_MOVE_PIC_LABEL 5)
37 (UNSPEC_EMB_TEXTUHI 13)
38 (UNSPEC_EMB_TEXTHI 14)
39 (UNSPEC_EMB_TEXTULO 15)
47 (UNSPEC_TLSLD_BASE 35)
78 ;; The upper 32 fp regs on the v9 can't hold SFmode values. To deal with this
79 ;; a second register class, EXTRA_FP_REGS, exists for the v9 chip. The name
80 ;; is a bit of a misnomer as it covers all 64 fp regs. The corresponding
81 ;; constraint letter is 'e'. To avoid any confusion, 'e' is used instead of
82 ;; 'f' for all DF/TFmode values, including those that are specific to the v8.
85 ;; Attribute for cpu type.
86 ;; These must match the values for enum processor_type in sparc.h.
93 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")
320 ;; Operand and operator predicates.
322 (include "predicates.md")
325 ;; Compare instructions.
327 ;; We generate RTL for comparisons and branches by having the cmpxx
328 ;; patterns store away the operands. Then, the scc and bcc patterns
329 ;; emit RTL for both the compare and the branch.
331 ;; We do this because we want to generate different code for an sne and
332 ;; seq insn. In those cases, if the second operand of the compare is not
333 ;; const0_rtx, we want to compute the xor of the two operands and test
336 ;; We start with the DEFINE_EXPANDs, then the DEFINE_INSNs to match
337 ;; the patterns. Finally, we have the DEFINE_SPLITs for some of the scc
338 ;; insns that actually require more than one machine instruction.
340 (define_expand "cmpsi"
342 (compare:CC (match_operand:SI 0 "compare_operand" "")
343 (match_operand:SI 1 "arith_operand" "")))]
346 if (GET_CODE (operands[0]) == ZERO_EXTRACT && operands[1] != const0_rtx)
347 operands[0] = force_reg (SImode, operands[0]);
349 sparc_compare_op0 = operands[0];
350 sparc_compare_op1 = operands[1];
354 (define_expand "cmpdi"
356 (compare:CCX (match_operand:DI 0 "compare_operand" "")
357 (match_operand:DI 1 "arith_operand" "")))]
360 if (GET_CODE (operands[0]) == ZERO_EXTRACT && operands[1] != const0_rtx)
361 operands[0] = force_reg (DImode, operands[0]);
363 sparc_compare_op0 = operands[0];
364 sparc_compare_op1 = operands[1];
368 (define_expand "cmpsf"
369 ;; The 96 here isn't ever used by anyone.
371 (compare:CCFP (match_operand:SF 0 "register_operand" "")
372 (match_operand:SF 1 "register_operand" "")))]
375 sparc_compare_op0 = operands[0];
376 sparc_compare_op1 = operands[1];
380 (define_expand "cmpdf"
381 ;; The 96 here isn't ever used by anyone.
383 (compare:CCFP (match_operand:DF 0 "register_operand" "")
384 (match_operand:DF 1 "register_operand" "")))]
387 sparc_compare_op0 = operands[0];
388 sparc_compare_op1 = operands[1];
392 (define_expand "cmptf"
393 ;; The 96 here isn't ever used by anyone.
395 (compare:CCFP (match_operand:TF 0 "register_operand" "")
396 (match_operand:TF 1 "register_operand" "")))]
399 sparc_compare_op0 = operands[0];
400 sparc_compare_op1 = operands[1];
404 ;; Now the compare DEFINE_INSNs.
406 (define_insn "*cmpsi_insn"
408 (compare:CC (match_operand:SI 0 "register_operand" "r")
409 (match_operand:SI 1 "arith_operand" "rI")))]
412 [(set_attr "type" "compare")])
414 (define_insn "*cmpdi_sp64"
416 (compare:CCX (match_operand:DI 0 "register_operand" "r")
417 (match_operand:DI 1 "arith_operand" "rI")))]
420 [(set_attr "type" "compare")])
422 (define_insn "*cmpsf_fpe"
423 [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
424 (compare:CCFPE (match_operand:SF 1 "register_operand" "f")
425 (match_operand:SF 2 "register_operand" "f")))]
429 return "fcmpes\t%0, %1, %2";
430 return "fcmpes\t%1, %2";
432 [(set_attr "type" "fpcmp")])
434 (define_insn "*cmpdf_fpe"
435 [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
436 (compare:CCFPE (match_operand:DF 1 "register_operand" "e")
437 (match_operand:DF 2 "register_operand" "e")))]
441 return "fcmped\t%0, %1, %2";
442 return "fcmped\t%1, %2";
444 [(set_attr "type" "fpcmp")
445 (set_attr "fptype" "double")])
447 (define_insn "*cmptf_fpe"
448 [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
449 (compare:CCFPE (match_operand:TF 1 "register_operand" "e")
450 (match_operand:TF 2 "register_operand" "e")))]
451 "TARGET_FPU && TARGET_HARD_QUAD"
454 return "fcmpeq\t%0, %1, %2";
455 return "fcmpeq\t%1, %2";
457 [(set_attr "type" "fpcmp")])
459 (define_insn "*cmpsf_fp"
460 [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
461 (compare:CCFP (match_operand:SF 1 "register_operand" "f")
462 (match_operand:SF 2 "register_operand" "f")))]
466 return "fcmps\t%0, %1, %2";
467 return "fcmps\t%1, %2";
469 [(set_attr "type" "fpcmp")])
471 (define_insn "*cmpdf_fp"
472 [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
473 (compare:CCFP (match_operand:DF 1 "register_operand" "e")
474 (match_operand:DF 2 "register_operand" "e")))]
478 return "fcmpd\t%0, %1, %2";
479 return "fcmpd\t%1, %2";
481 [(set_attr "type" "fpcmp")
482 (set_attr "fptype" "double")])
484 (define_insn "*cmptf_fp"
485 [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
486 (compare:CCFP (match_operand:TF 1 "register_operand" "e")
487 (match_operand:TF 2 "register_operand" "e")))]
488 "TARGET_FPU && TARGET_HARD_QUAD"
491 return "fcmpq\t%0, %1, %2";
492 return "fcmpq\t%1, %2";
494 [(set_attr "type" "fpcmp")])
496 ;; Next come the scc insns. For seq, sne, sgeu, and sltu, we can do this
497 ;; without jumps using the addx/subx instructions. For seq/sne on v9 we use
498 ;; the same code as v8 (the addx/subx method has more applications). The
499 ;; exception to this is "reg != 0" which can be done in one instruction on v9
500 ;; (so we do it). For the rest, on v9 we use conditional moves; on v8, we do
503 ;; Seq_special[_xxx] and sne_special[_xxx] clobber the CC reg, because they
504 ;; generate addcc/subcc instructions.
506 (define_expand "seqsi_special"
508 (xor:SI (match_operand:SI 1 "register_operand" "")
509 (match_operand:SI 2 "register_operand" "")))
510 (parallel [(set (match_operand:SI 0 "register_operand" "")
511 (eq:SI (match_dup 3) (const_int 0)))
512 (clobber (reg:CC 100))])]
514 { operands[3] = gen_reg_rtx (SImode); })
516 (define_expand "seqdi_special"
518 (xor:DI (match_operand:DI 1 "register_operand" "")
519 (match_operand:DI 2 "register_operand" "")))
520 (set (match_operand:DI 0 "register_operand" "")
521 (eq:DI (match_dup 3) (const_int 0)))]
523 { operands[3] = gen_reg_rtx (DImode); })
525 (define_expand "snesi_special"
527 (xor:SI (match_operand:SI 1 "register_operand" "")
528 (match_operand:SI 2 "register_operand" "")))
529 (parallel [(set (match_operand:SI 0 "register_operand" "")
530 (ne:SI (match_dup 3) (const_int 0)))
531 (clobber (reg:CC 100))])]
533 { operands[3] = gen_reg_rtx (SImode); })
535 (define_expand "snedi_special"
537 (xor:DI (match_operand:DI 1 "register_operand" "")
538 (match_operand:DI 2 "register_operand" "")))
539 (set (match_operand:DI 0 "register_operand" "")
540 (ne:DI (match_dup 3) (const_int 0)))]
542 { operands[3] = gen_reg_rtx (DImode); })
544 (define_expand "seqdi_special_trunc"
546 (xor:DI (match_operand:DI 1 "register_operand" "")
547 (match_operand:DI 2 "register_operand" "")))
548 (set (match_operand:SI 0 "register_operand" "")
549 (eq:SI (match_dup 3) (const_int 0)))]
551 { operands[3] = gen_reg_rtx (DImode); })
553 (define_expand "snedi_special_trunc"
555 (xor:DI (match_operand:DI 1 "register_operand" "")
556 (match_operand:DI 2 "register_operand" "")))
557 (set (match_operand:SI 0 "register_operand" "")
558 (ne:SI (match_dup 3) (const_int 0)))]
560 { operands[3] = gen_reg_rtx (DImode); })
562 (define_expand "seqsi_special_extend"
564 (xor:SI (match_operand:SI 1 "register_operand" "")
565 (match_operand:SI 2 "register_operand" "")))
566 (parallel [(set (match_operand:DI 0 "register_operand" "")
567 (eq:DI (match_dup 3) (const_int 0)))
568 (clobber (reg:CC 100))])]
570 { operands[3] = gen_reg_rtx (SImode); })
572 (define_expand "snesi_special_extend"
574 (xor:SI (match_operand:SI 1 "register_operand" "")
575 (match_operand:SI 2 "register_operand" "")))
576 (parallel [(set (match_operand:DI 0 "register_operand" "")
577 (ne:DI (match_dup 3) (const_int 0)))
578 (clobber (reg:CC 100))])]
580 { operands[3] = gen_reg_rtx (SImode); })
582 ;; ??? v9: Operand 0 needs a mode, so SImode was chosen.
583 ;; However, the code handles both SImode and DImode.
585 [(set (match_operand:SI 0 "int_register_operand" "")
586 (eq:SI (match_dup 1) (const_int 0)))]
589 if (GET_MODE (sparc_compare_op0) == SImode)
593 if (GET_MODE (operands[0]) == SImode)
594 pat = gen_seqsi_special (operands[0], sparc_compare_op0,
596 else if (! TARGET_ARCH64)
599 pat = gen_seqsi_special_extend (operands[0], sparc_compare_op0,
604 else if (GET_MODE (sparc_compare_op0) == DImode)
610 else if (GET_MODE (operands[0]) == SImode)
611 pat = gen_seqdi_special_trunc (operands[0], sparc_compare_op0,
614 pat = gen_seqdi_special (operands[0], sparc_compare_op0,
619 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
621 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, EQ);
622 emit_jump_insn (gen_sne (operands[0]));
627 if (gen_v9_scc (EQ, operands))
634 ;; ??? v9: Operand 0 needs a mode, so SImode was chosen.
635 ;; However, the code handles both SImode and DImode.
637 [(set (match_operand:SI 0 "int_register_operand" "")
638 (ne:SI (match_dup 1) (const_int 0)))]
641 if (GET_MODE (sparc_compare_op0) == SImode)
645 if (GET_MODE (operands[0]) == SImode)
646 pat = gen_snesi_special (operands[0], sparc_compare_op0,
648 else if (! TARGET_ARCH64)
651 pat = gen_snesi_special_extend (operands[0], sparc_compare_op0,
656 else if (GET_MODE (sparc_compare_op0) == DImode)
662 else if (GET_MODE (operands[0]) == SImode)
663 pat = gen_snedi_special_trunc (operands[0], sparc_compare_op0,
666 pat = gen_snedi_special (operands[0], sparc_compare_op0,
671 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
673 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, NE);
674 emit_jump_insn (gen_sne (operands[0]));
679 if (gen_v9_scc (NE, operands))
687 [(set (match_operand:SI 0 "int_register_operand" "")
688 (gt:SI (match_dup 1) (const_int 0)))]
691 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
693 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GT);
694 emit_jump_insn (gen_sne (operands[0]));
699 if (gen_v9_scc (GT, operands))
707 [(set (match_operand:SI 0 "int_register_operand" "")
708 (lt:SI (match_dup 1) (const_int 0)))]
711 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
713 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LT);
714 emit_jump_insn (gen_sne (operands[0]));
719 if (gen_v9_scc (LT, operands))
727 [(set (match_operand:SI 0 "int_register_operand" "")
728 (ge:SI (match_dup 1) (const_int 0)))]
731 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
733 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GE);
734 emit_jump_insn (gen_sne (operands[0]));
739 if (gen_v9_scc (GE, operands))
747 [(set (match_operand:SI 0 "int_register_operand" "")
748 (le:SI (match_dup 1) (const_int 0)))]
751 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
753 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LE);
754 emit_jump_insn (gen_sne (operands[0]));
759 if (gen_v9_scc (LE, operands))
766 (define_expand "sgtu"
767 [(set (match_operand:SI 0 "int_register_operand" "")
768 (gtu:SI (match_dup 1) (const_int 0)))]
775 /* We can do ltu easily, so if both operands are registers, swap them and
777 if ((GET_CODE (sparc_compare_op0) == REG
778 || GET_CODE (sparc_compare_op0) == SUBREG)
779 && (GET_CODE (sparc_compare_op1) == REG
780 || GET_CODE (sparc_compare_op1) == SUBREG))
782 tem = sparc_compare_op0;
783 sparc_compare_op0 = sparc_compare_op1;
784 sparc_compare_op1 = tem;
785 pat = gen_sltu (operands[0]);
794 if (gen_v9_scc (GTU, operands))
800 (define_expand "sltu"
801 [(set (match_operand:SI 0 "int_register_operand" "")
802 (ltu:SI (match_dup 1) (const_int 0)))]
807 if (gen_v9_scc (LTU, operands))
810 operands[1] = gen_compare_reg (LTU);
813 (define_expand "sgeu"
814 [(set (match_operand:SI 0 "int_register_operand" "")
815 (geu:SI (match_dup 1) (const_int 0)))]
820 if (gen_v9_scc (GEU, operands))
823 operands[1] = gen_compare_reg (GEU);
826 (define_expand "sleu"
827 [(set (match_operand:SI 0 "int_register_operand" "")
828 (leu:SI (match_dup 1) (const_int 0)))]
835 /* We can do geu easily, so if both operands are registers, swap them and
837 if ((GET_CODE (sparc_compare_op0) == REG
838 || GET_CODE (sparc_compare_op0) == SUBREG)
839 && (GET_CODE (sparc_compare_op1) == REG
840 || GET_CODE (sparc_compare_op1) == SUBREG))
842 tem = sparc_compare_op0;
843 sparc_compare_op0 = sparc_compare_op1;
844 sparc_compare_op1 = tem;
845 pat = gen_sgeu (operands[0]);
854 if (gen_v9_scc (LEU, operands))
860 ;; Now the DEFINE_INSNs for the scc cases.
862 ;; The SEQ and SNE patterns are special because they can be done
863 ;; without any branching and do not involve a COMPARE. We want
864 ;; them to always use the splits below so the results can be
867 (define_insn_and_split "*snesi_zero"
868 [(set (match_operand:SI 0 "register_operand" "=r")
869 (ne:SI (match_operand:SI 1 "register_operand" "r")
871 (clobber (reg:CC 100))]
875 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
877 (set (match_dup 0) (ltu:SI (reg:CC 100) (const_int 0)))]
879 [(set_attr "length" "2")])
881 (define_insn_and_split "*neg_snesi_zero"
882 [(set (match_operand:SI 0 "register_operand" "=r")
883 (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
885 (clobber (reg:CC 100))]
889 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
891 (set (match_dup 0) (neg:SI (ltu:SI (reg:CC 100) (const_int 0))))]
893 [(set_attr "length" "2")])
895 (define_insn_and_split "*snesi_zero_extend"
896 [(set (match_operand:DI 0 "register_operand" "=r")
897 (ne:DI (match_operand:SI 1 "register_operand" "r")
899 (clobber (reg:CC 100))]
903 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (minus:SI (const_int 0)
906 (set (match_dup 0) (zero_extend:DI (plus:SI (plus:SI (const_int 0)
908 (ltu:SI (reg:CC_NOOV 100)
911 [(set_attr "length" "2")])
913 (define_insn_and_split "*snedi_zero"
914 [(set (match_operand:DI 0 "register_operand" "=&r")
915 (ne:DI (match_operand:DI 1 "register_operand" "r")
919 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
920 [(set (match_dup 0) (const_int 0))
921 (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
926 [(set_attr "length" "2")])
928 (define_insn_and_split "*neg_snedi_zero"
929 [(set (match_operand:DI 0 "register_operand" "=&r")
930 (neg:DI (ne:DI (match_operand:DI 1 "register_operand" "r")
934 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
935 [(set (match_dup 0) (const_int 0))
936 (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
941 [(set_attr "length" "2")])
943 (define_insn_and_split "*snedi_zero_trunc"
944 [(set (match_operand:SI 0 "register_operand" "=&r")
945 (ne:SI (match_operand:DI 1 "register_operand" "r")
949 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
950 [(set (match_dup 0) (const_int 0))
951 (set (match_dup 0) (if_then_else:SI (ne:DI (match_dup 1)
956 [(set_attr "length" "2")])
958 (define_insn_and_split "*seqsi_zero"
959 [(set (match_operand:SI 0 "register_operand" "=r")
960 (eq:SI (match_operand:SI 1 "register_operand" "r")
962 (clobber (reg:CC 100))]
966 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
968 (set (match_dup 0) (geu:SI (reg:CC 100) (const_int 0)))]
970 [(set_attr "length" "2")])
972 (define_insn_and_split "*neg_seqsi_zero"
973 [(set (match_operand:SI 0 "register_operand" "=r")
974 (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
976 (clobber (reg:CC 100))]
980 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
982 (set (match_dup 0) (neg:SI (geu:SI (reg:CC 100) (const_int 0))))]
984 [(set_attr "length" "2")])
986 (define_insn_and_split "*seqsi_zero_extend"
987 [(set (match_operand:DI 0 "register_operand" "=r")
988 (eq:DI (match_operand:SI 1 "register_operand" "r")
990 (clobber (reg:CC 100))]
994 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (minus:SI (const_int 0)
997 (set (match_dup 0) (zero_extend:DI (minus:SI (minus:SI (const_int 0)
999 (ltu:SI (reg:CC_NOOV 100)
1002 [(set_attr "length" "2")])
1004 (define_insn_and_split "*seqdi_zero"
1005 [(set (match_operand:DI 0 "register_operand" "=&r")
1006 (eq:DI (match_operand:DI 1 "register_operand" "r")
1010 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
1011 [(set (match_dup 0) (const_int 0))
1012 (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
1017 [(set_attr "length" "2")])
1019 (define_insn_and_split "*neg_seqdi_zero"
1020 [(set (match_operand:DI 0 "register_operand" "=&r")
1021 (neg:DI (eq:DI (match_operand:DI 1 "register_operand" "r")
1025 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
1026 [(set (match_dup 0) (const_int 0))
1027 (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
1032 [(set_attr "length" "2")])
1034 (define_insn_and_split "*seqdi_zero_trunc"
1035 [(set (match_operand:SI 0 "register_operand" "=&r")
1036 (eq:SI (match_operand:DI 1 "register_operand" "r")
1040 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
1041 [(set (match_dup 0) (const_int 0))
1042 (set (match_dup 0) (if_then_else:SI (eq:DI (match_dup 1)
1047 [(set_attr "length" "2")])
1049 ;; We can also do (x + (i == 0)) and related, so put them in.
1050 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1053 (define_insn_and_split "*x_plus_i_ne_0"
1054 [(set (match_operand:SI 0 "register_operand" "=r")
1055 (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
1057 (match_operand:SI 2 "register_operand" "r")))
1058 (clobber (reg:CC 100))]
1062 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1064 (set (match_dup 0) (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1067 [(set_attr "length" "2")])
1069 (define_insn_and_split "*x_minus_i_ne_0"
1070 [(set (match_operand:SI 0 "register_operand" "=r")
1071 (minus:SI (match_operand:SI 2 "register_operand" "r")
1072 (ne:SI (match_operand:SI 1 "register_operand" "r")
1074 (clobber (reg:CC 100))]
1078 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1080 (set (match_dup 0) (minus:SI (match_dup 2)
1081 (ltu:SI (reg:CC 100) (const_int 0))))]
1083 [(set_attr "length" "2")])
1085 (define_insn_and_split "*x_plus_i_eq_0"
1086 [(set (match_operand:SI 0 "register_operand" "=r")
1087 (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
1089 (match_operand:SI 2 "register_operand" "r")))
1090 (clobber (reg:CC 100))]
1094 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1096 (set (match_dup 0) (plus:SI (geu:SI (reg:CC 100) (const_int 0))
1099 [(set_attr "length" "2")])
1101 (define_insn_and_split "*x_minus_i_eq_0"
1102 [(set (match_operand:SI 0 "register_operand" "=r")
1103 (minus:SI (match_operand:SI 2 "register_operand" "r")
1104 (eq:SI (match_operand:SI 1 "register_operand" "r")
1106 (clobber (reg:CC 100))]
1110 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1112 (set (match_dup 0) (minus:SI (match_dup 2)
1113 (geu:SI (reg:CC 100) (const_int 0))))]
1115 [(set_attr "length" "2")])
1117 ;; We can also do GEU and LTU directly, but these operate after a compare.
1118 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1121 (define_insn "*sltu_insn"
1122 [(set (match_operand:SI 0 "register_operand" "=r")
1123 (ltu:SI (reg:CC 100) (const_int 0)))]
1126 [(set_attr "type" "ialuX")])
1128 (define_insn "*neg_sltu_insn"
1129 [(set (match_operand:SI 0 "register_operand" "=r")
1130 (neg:SI (ltu:SI (reg:CC 100) (const_int 0))))]
1133 [(set_attr "type" "ialuX")])
1135 ;; ??? Combine should canonicalize these next two to the same pattern.
1136 (define_insn "*neg_sltu_minus_x"
1137 [(set (match_operand:SI 0 "register_operand" "=r")
1138 (minus:SI (neg:SI (ltu:SI (reg:CC 100) (const_int 0)))
1139 (match_operand:SI 1 "arith_operand" "rI")))]
1141 "subx\t%%g0, %1, %0"
1142 [(set_attr "type" "ialuX")])
1144 (define_insn "*neg_sltu_plus_x"
1145 [(set (match_operand:SI 0 "register_operand" "=r")
1146 (neg:SI (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1147 (match_operand:SI 1 "arith_operand" "rI"))))]
1149 "subx\t%%g0, %1, %0"
1150 [(set_attr "type" "ialuX")])
1152 (define_insn "*sgeu_insn"
1153 [(set (match_operand:SI 0 "register_operand" "=r")
1154 (geu:SI (reg:CC 100) (const_int 0)))]
1156 "subx\t%%g0, -1, %0"
1157 [(set_attr "type" "ialuX")])
1159 (define_insn "*neg_sgeu_insn"
1160 [(set (match_operand:SI 0 "register_operand" "=r")
1161 (neg:SI (geu:SI (reg:CC 100) (const_int 0))))]
1163 "addx\t%%g0, -1, %0"
1164 [(set_attr "type" "ialuX")])
1166 ;; We can also do (x + ((unsigned) i >= 0)) and related, so put them in.
1167 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1170 (define_insn "*sltu_plus_x"
1171 [(set (match_operand:SI 0 "register_operand" "=r")
1172 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1173 (match_operand:SI 1 "arith_operand" "rI")))]
1175 "addx\t%%g0, %1, %0"
1176 [(set_attr "type" "ialuX")])
1178 (define_insn "*sltu_plus_x_plus_y"
1179 [(set (match_operand:SI 0 "register_operand" "=r")
1180 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1181 (plus:SI (match_operand:SI 1 "arith_operand" "%r")
1182 (match_operand:SI 2 "arith_operand" "rI"))))]
1185 [(set_attr "type" "ialuX")])
1187 (define_insn "*x_minus_sltu"
1188 [(set (match_operand:SI 0 "register_operand" "=r")
1189 (minus:SI (match_operand:SI 1 "register_operand" "r")
1190 (ltu:SI (reg:CC 100) (const_int 0))))]
1193 [(set_attr "type" "ialuX")])
1195 ;; ??? Combine should canonicalize these next two to the same pattern.
1196 (define_insn "*x_minus_y_minus_sltu"
1197 [(set (match_operand:SI 0 "register_operand" "=r")
1198 (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
1199 (match_operand:SI 2 "arith_operand" "rI"))
1200 (ltu:SI (reg:CC 100) (const_int 0))))]
1203 [(set_attr "type" "ialuX")])
1205 (define_insn "*x_minus_sltu_plus_y"
1206 [(set (match_operand:SI 0 "register_operand" "=r")
1207 (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
1208 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1209 (match_operand:SI 2 "arith_operand" "rI"))))]
1212 [(set_attr "type" "ialuX")])
1214 (define_insn "*sgeu_plus_x"
1215 [(set (match_operand:SI 0 "register_operand" "=r")
1216 (plus:SI (geu:SI (reg:CC 100) (const_int 0))
1217 (match_operand:SI 1 "register_operand" "r")))]
1220 [(set_attr "type" "ialuX")])
1222 (define_insn "*x_minus_sgeu"
1223 [(set (match_operand:SI 0 "register_operand" "=r")
1224 (minus:SI (match_operand:SI 1 "register_operand" "r")
1225 (geu:SI (reg:CC 100) (const_int 0))))]
1228 [(set_attr "type" "ialuX")])
1231 [(set (match_operand:SI 0 "register_operand" "")
1232 (match_operator:SI 2 "noov_compare_operator"
1233 [(match_operand 1 "icc_or_fcc_register_operand" "")
1236 && REGNO (operands[1]) == SPARC_ICC_REG
1237 && (GET_MODE (operands[1]) == CCXmode
1238 /* 32 bit LTU/GEU are better implemented using addx/subx. */
1239 || (GET_CODE (operands[2]) != LTU && GET_CODE (operands[2]) != GEU))"
1240 [(set (match_dup 0) (const_int 0))
1242 (if_then_else:SI (match_op_dup:SI 2 [(match_dup 1) (const_int 0)])
1248 ;; These control RTL generation for conditional jump insns
1250 ;; The quad-word fp compare library routines all return nonzero to indicate
1251 ;; true, which is different from the equivalent libgcc routines, so we must
1252 ;; handle them specially here.
1254 (define_expand "beq"
1256 (if_then_else (eq (match_dup 1) (const_int 0))
1257 (label_ref (match_operand 0 "" ""))
1261 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1262 && GET_CODE (sparc_compare_op0) == REG
1263 && GET_MODE (sparc_compare_op0) == DImode)
1265 emit_v9_brxx_insn (EQ, sparc_compare_op0, operands[0]);
1268 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1270 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, EQ);
1271 emit_jump_insn (gen_bne (operands[0]));
1274 operands[1] = gen_compare_reg (EQ);
1277 (define_expand "bne"
1279 (if_then_else (ne (match_dup 1) (const_int 0))
1280 (label_ref (match_operand 0 "" ""))
1284 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1285 && GET_CODE (sparc_compare_op0) == REG
1286 && GET_MODE (sparc_compare_op0) == DImode)
1288 emit_v9_brxx_insn (NE, sparc_compare_op0, operands[0]);
1291 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1293 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, NE);
1294 emit_jump_insn (gen_bne (operands[0]));
1297 operands[1] = gen_compare_reg (NE);
1300 (define_expand "bgt"
1302 (if_then_else (gt (match_dup 1) (const_int 0))
1303 (label_ref (match_operand 0 "" ""))
1307 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1308 && GET_CODE (sparc_compare_op0) == REG
1309 && GET_MODE (sparc_compare_op0) == DImode)
1311 emit_v9_brxx_insn (GT, sparc_compare_op0, operands[0]);
1314 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1316 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GT);
1317 emit_jump_insn (gen_bne (operands[0]));
1320 operands[1] = gen_compare_reg (GT);
1323 (define_expand "bgtu"
1325 (if_then_else (gtu (match_dup 1) (const_int 0))
1326 (label_ref (match_operand 0 "" ""))
1330 operands[1] = gen_compare_reg (GTU);
1333 (define_expand "blt"
1335 (if_then_else (lt (match_dup 1) (const_int 0))
1336 (label_ref (match_operand 0 "" ""))
1340 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1341 && GET_CODE (sparc_compare_op0) == REG
1342 && GET_MODE (sparc_compare_op0) == DImode)
1344 emit_v9_brxx_insn (LT, sparc_compare_op0, operands[0]);
1347 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1349 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LT);
1350 emit_jump_insn (gen_bne (operands[0]));
1353 operands[1] = gen_compare_reg (LT);
1356 (define_expand "bltu"
1358 (if_then_else (ltu (match_dup 1) (const_int 0))
1359 (label_ref (match_operand 0 "" ""))
1363 operands[1] = gen_compare_reg (LTU);
1366 (define_expand "bge"
1368 (if_then_else (ge (match_dup 1) (const_int 0))
1369 (label_ref (match_operand 0 "" ""))
1373 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1374 && GET_CODE (sparc_compare_op0) == REG
1375 && GET_MODE (sparc_compare_op0) == DImode)
1377 emit_v9_brxx_insn (GE, sparc_compare_op0, operands[0]);
1380 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1382 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GE);
1383 emit_jump_insn (gen_bne (operands[0]));
1386 operands[1] = gen_compare_reg (GE);
1389 (define_expand "bgeu"
1391 (if_then_else (geu (match_dup 1) (const_int 0))
1392 (label_ref (match_operand 0 "" ""))
1396 operands[1] = gen_compare_reg (GEU);
1399 (define_expand "ble"
1401 (if_then_else (le (match_dup 1) (const_int 0))
1402 (label_ref (match_operand 0 "" ""))
1406 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1407 && GET_CODE (sparc_compare_op0) == REG
1408 && GET_MODE (sparc_compare_op0) == DImode)
1410 emit_v9_brxx_insn (LE, sparc_compare_op0, operands[0]);
1413 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1415 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LE);
1416 emit_jump_insn (gen_bne (operands[0]));
1419 operands[1] = gen_compare_reg (LE);
1422 (define_expand "bleu"
1424 (if_then_else (leu (match_dup 1) (const_int 0))
1425 (label_ref (match_operand 0 "" ""))
1429 operands[1] = gen_compare_reg (LEU);
1432 (define_expand "bunordered"
1434 (if_then_else (unordered (match_dup 1) (const_int 0))
1435 (label_ref (match_operand 0 "" ""))
1439 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1441 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1,
1443 emit_jump_insn (gen_beq (operands[0]));
1446 operands[1] = gen_compare_reg (UNORDERED);
1449 (define_expand "bordered"
1451 (if_then_else (ordered (match_dup 1) (const_int 0))
1452 (label_ref (match_operand 0 "" ""))
1456 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1458 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, ORDERED);
1459 emit_jump_insn (gen_bne (operands[0]));
1462 operands[1] = gen_compare_reg (ORDERED);
1465 (define_expand "bungt"
1467 (if_then_else (ungt (match_dup 1) (const_int 0))
1468 (label_ref (match_operand 0 "" ""))
1472 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1474 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNGT);
1475 emit_jump_insn (gen_bgt (operands[0]));
1478 operands[1] = gen_compare_reg (UNGT);
1481 (define_expand "bunlt"
1483 (if_then_else (unlt (match_dup 1) (const_int 0))
1484 (label_ref (match_operand 0 "" ""))
1488 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1490 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNLT);
1491 emit_jump_insn (gen_bne (operands[0]));
1494 operands[1] = gen_compare_reg (UNLT);
1497 (define_expand "buneq"
1499 (if_then_else (uneq (match_dup 1) (const_int 0))
1500 (label_ref (match_operand 0 "" ""))
1504 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1506 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNEQ);
1507 emit_jump_insn (gen_beq (operands[0]));
1510 operands[1] = gen_compare_reg (UNEQ);
1513 (define_expand "bunge"
1515 (if_then_else (unge (match_dup 1) (const_int 0))
1516 (label_ref (match_operand 0 "" ""))
1520 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1522 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNGE);
1523 emit_jump_insn (gen_bne (operands[0]));
1526 operands[1] = gen_compare_reg (UNGE);
1529 (define_expand "bunle"
1531 (if_then_else (unle (match_dup 1) (const_int 0))
1532 (label_ref (match_operand 0 "" ""))
1536 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1538 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNLE);
1539 emit_jump_insn (gen_bne (operands[0]));
1542 operands[1] = gen_compare_reg (UNLE);
1545 (define_expand "bltgt"
1547 (if_then_else (ltgt (match_dup 1) (const_int 0))
1548 (label_ref (match_operand 0 "" ""))
1552 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1554 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LTGT);
1555 emit_jump_insn (gen_bne (operands[0]));
1558 operands[1] = gen_compare_reg (LTGT);
1561 ;; Now match both normal and inverted jump.
1563 ;; XXX fpcmp nop braindamage
1564 (define_insn "*normal_branch"
1566 (if_then_else (match_operator 0 "noov_compare_operator"
1567 [(reg 100) (const_int 0)])
1568 (label_ref (match_operand 1 "" ""))
1572 return output_cbranch (operands[0], operands[1], 1, 0,
1573 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1576 [(set_attr "type" "branch")
1577 (set_attr "branch_type" "icc")])
1579 ;; XXX fpcmp nop braindamage
1580 (define_insn "*inverted_branch"
1582 (if_then_else (match_operator 0 "noov_compare_operator"
1583 [(reg 100) (const_int 0)])
1585 (label_ref (match_operand 1 "" ""))))]
1588 return output_cbranch (operands[0], operands[1], 1, 1,
1589 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1592 [(set_attr "type" "branch")
1593 (set_attr "branch_type" "icc")])
1595 ;; XXX fpcmp nop braindamage
1596 (define_insn "*normal_fp_branch"
1598 (if_then_else (match_operator 1 "comparison_operator"
1599 [(match_operand:CCFP 0 "fcc_register_operand" "c")
1601 (label_ref (match_operand 2 "" ""))
1605 return output_cbranch (operands[1], operands[2], 2, 0,
1606 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1609 [(set_attr "type" "branch")
1610 (set_attr "branch_type" "fcc")])
1612 ;; XXX fpcmp nop braindamage
1613 (define_insn "*inverted_fp_branch"
1615 (if_then_else (match_operator 1 "comparison_operator"
1616 [(match_operand:CCFP 0 "fcc_register_operand" "c")
1619 (label_ref (match_operand 2 "" ""))))]
1622 return output_cbranch (operands[1], operands[2], 2, 1,
1623 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1626 [(set_attr "type" "branch")
1627 (set_attr "branch_type" "fcc")])
1629 ;; XXX fpcmp nop braindamage
1630 (define_insn "*normal_fpe_branch"
1632 (if_then_else (match_operator 1 "comparison_operator"
1633 [(match_operand:CCFPE 0 "fcc_register_operand" "c")
1635 (label_ref (match_operand 2 "" ""))
1639 return output_cbranch (operands[1], operands[2], 2, 0,
1640 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1643 [(set_attr "type" "branch")
1644 (set_attr "branch_type" "fcc")])
1646 ;; XXX fpcmp nop braindamage
1647 (define_insn "*inverted_fpe_branch"
1649 (if_then_else (match_operator 1 "comparison_operator"
1650 [(match_operand:CCFPE 0 "fcc_register_operand" "c")
1653 (label_ref (match_operand 2 "" ""))))]
1656 return output_cbranch (operands[1], operands[2], 2, 1,
1657 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1660 [(set_attr "type" "branch")
1661 (set_attr "branch_type" "fcc")])
1663 ;; SPARC V9-specific jump insns. None of these are guaranteed to be
1664 ;; in the architecture.
1666 ;; There are no 32 bit brreg insns.
1669 (define_insn "*normal_int_branch_sp64"
1671 (if_then_else (match_operator 0 "v9_register_compare_operator"
1672 [(match_operand:DI 1 "register_operand" "r")
1674 (label_ref (match_operand 2 "" ""))
1678 return output_v9branch (operands[0], operands[2], 1, 2, 0,
1679 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1682 [(set_attr "type" "branch")
1683 (set_attr "branch_type" "reg")])
1686 (define_insn "*inverted_int_branch_sp64"
1688 (if_then_else (match_operator 0 "v9_register_compare_operator"
1689 [(match_operand:DI 1 "register_operand" "r")
1692 (label_ref (match_operand 2 "" ""))))]
1695 return output_v9branch (operands[0], operands[2], 1, 2, 1,
1696 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1699 [(set_attr "type" "branch")
1700 (set_attr "branch_type" "reg")])
1703 (define_mode_macro P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
1705 ;; Load in operand 0 the (absolute) address of operand 1, which is a symbolic
1706 ;; value subject to a PC-relative relocation. Operand 2 is a helper function
1707 ;; that adds the PC value at the call point to operand 0.
1709 (define_insn "load_pcrel_sym<P:mode>"
1710 [(set (match_operand:P 0 "register_operand" "=r")
1711 (unspec:P [(match_operand:P 1 "symbolic_operand" "")
1712 (match_operand:P 2 "call_address_operand" "")] UNSPEC_LOAD_PCREL_SYM))
1713 (clobber (reg:P 15))]
1716 if (flag_delayed_branch)
1717 return "sethi\t%%hi(%a1-4), %0\n\tcall\t%a2\n\t add\t%0, %%lo(%a1+4), %0";
1719 return "sethi\t%%hi(%a1-8), %0\n\tadd\t%0, %%lo(%a1-4), %0\n\tcall\t%a2\n\t nop";
1721 [(set (attr "type") (const_string "multi"))
1722 (set (attr "length")
1723 (if_then_else (eq_attr "delayed_branch" "true")
1728 ;; Integer move instructions
1730 (define_expand "movqi"
1731 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1732 (match_operand:QI 1 "general_operand" ""))]
1735 if (sparc_expand_move (QImode, operands))
1739 (define_insn "*movqi_insn"
1740 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m")
1741 (match_operand:QI 1 "input_operand" "rI,m,rJ"))]
1742 "(register_operand (operands[0], QImode)
1743 || register_or_zero_operand (operands[1], QImode))"
1748 [(set_attr "type" "*,load,store")
1749 (set_attr "us3load_type" "*,3cycle,*")])
1751 (define_expand "movhi"
1752 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1753 (match_operand:HI 1 "general_operand" ""))]
1756 if (sparc_expand_move (HImode, operands))
1760 (define_insn "*movhi_insn"
1761 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1762 (match_operand:HI 1 "input_operand" "rI,K,m,rJ"))]
1763 "(register_operand (operands[0], HImode)
1764 || register_or_zero_operand (operands[1], HImode))"
1767 sethi\t%%hi(%a1), %0
1770 [(set_attr "type" "*,*,load,store")
1771 (set_attr "us3load_type" "*,*,3cycle,*")])
1773 ;; We always work with constants here.
1774 (define_insn "*movhi_lo_sum"
1775 [(set (match_operand:HI 0 "register_operand" "=r")
1776 (ior:HI (match_operand:HI 1 "register_operand" "%r")
1777 (match_operand:HI 2 "small_int_operand" "I")))]
1781 (define_expand "movsi"
1782 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1783 (match_operand:SI 1 "general_operand" ""))]
1786 if (sparc_expand_move (SImode, operands))
1790 (define_insn "*movsi_insn"
1791 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,m,!f,!f,!m,d")
1792 (match_operand:SI 1 "input_operand" "rI,K,m,rJ,f,m,f,J"))]
1793 "(register_operand (operands[0], SImode)
1794 || register_or_zero_operand (operands[1], SImode))"
1797 sethi\t%%hi(%a1), %0
1804 [(set_attr "type" "*,*,load,store,fpmove,fpload,fpstore,fga")])
1806 (define_insn "*movsi_lo_sum"
1807 [(set (match_operand:SI 0 "register_operand" "=r")
1808 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1809 (match_operand:SI 2 "immediate_operand" "in")))]
1811 "or\t%1, %%lo(%a2), %0")
1813 (define_insn "*movsi_high"
1814 [(set (match_operand:SI 0 "register_operand" "=r")
1815 (high:SI (match_operand:SI 1 "immediate_operand" "in")))]
1817 "sethi\t%%hi(%a1), %0")
1819 ;; The next two patterns must wrap the SYMBOL_REF in an UNSPEC
1820 ;; so that CSE won't optimize the address computation away.
1821 (define_insn "movsi_lo_sum_pic"
1822 [(set (match_operand:SI 0 "register_operand" "=r")
1823 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1824 (unspec:SI [(match_operand:SI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
1826 "or\t%1, %%lo(%a2), %0")
1828 (define_insn "movsi_high_pic"
1829 [(set (match_operand:SI 0 "register_operand" "=r")
1830 (high:SI (unspec:SI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
1831 "flag_pic && check_pic (1)"
1832 "sethi\t%%hi(%a1), %0")
1834 (define_expand "movsi_pic_label_ref"
1835 [(set (match_dup 3) (high:SI
1836 (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
1837 (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1838 (set (match_dup 4) (lo_sum:SI (match_dup 3)
1839 (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1840 (set (match_operand:SI 0 "register_operand" "=r")
1841 (minus:SI (match_dup 5) (match_dup 4)))]
1844 current_function_uses_pic_offset_table = 1;
1845 operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
1848 operands[3] = operands[0];
1849 operands[4] = operands[0];
1853 operands[3] = gen_reg_rtx (SImode);
1854 operands[4] = gen_reg_rtx (SImode);
1856 operands[5] = pic_offset_table_rtx;
1859 (define_insn "*movsi_high_pic_label_ref"
1860 [(set (match_operand:SI 0 "register_operand" "=r")
1862 (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
1863 (match_operand:SI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1865 "sethi\t%%hi(%a2-(%a1-.)), %0")
1867 (define_insn "*movsi_lo_sum_pic_label_ref"
1868 [(set (match_operand:SI 0 "register_operand" "=r")
1869 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1870 (unspec:SI [(match_operand:SI 2 "label_ref_operand" "")
1871 (match_operand:SI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1873 "or\t%1, %%lo(%a3-(%a2-.)), %0")
1875 (define_expand "movdi"
1876 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1877 (match_operand:DI 1 "general_operand" ""))]
1880 if (sparc_expand_move (DImode, operands))
1884 ;; Be careful, fmovd does not exist when !v9.
1885 ;; We match MEM moves directly when we have correct even
1886 ;; numbered registers, but fall into splits otherwise.
1887 ;; The constraint ordering here is really important to
1888 ;; avoid insane problems in reload, especially for patterns
1891 ;; (set (mem:DI (plus:SI (reg:SI 30 %fp)
1892 ;; (const_int -5016)))
1896 (define_insn "*movdi_insn_sp32"
1897 [(set (match_operand:DI 0 "nonimmediate_operand"
1898 "=o,T,U,o,r,r,r,?T,?f,?f,?o,?f")
1899 (match_operand:DI 1 "input_operand"
1900 " J,U,T,r,o,i,r, f, T, o, f, f"))]
1902 && (register_operand (operands[0], DImode)
1903 || register_or_zero_operand (operands[1], DImode))"
1917 [(set_attr "type" "store,store,load,*,*,*,*,fpstore,fpload,*,*,*")
1918 (set_attr "length" "2,*,*,2,2,2,2,*,*,2,2,2")])
1920 (define_insn "*movdi_insn_sp32_v9"
1921 [(set (match_operand:DI 0 "nonimmediate_operand"
1922 "=T,o,T,U,o,r,r,r,?T,?f,?f,?o,?e,?e,?W")
1923 (match_operand:DI 1 "input_operand"
1924 " J,J,U,T,r,o,i,r, f, T, o, f, e, W, e"))]
1927 && (register_operand (operands[0], DImode)
1928 || register_or_zero_operand (operands[1], DImode))"
1945 [(set_attr "type" "store,store,store,load,*,*,*,*,fpstore,fpload,*,*,fpmove,fpload,fpstore")
1946 (set_attr "length" "*,2,*,*,2,2,2,2,*,*,2,2,*,*,*")
1947 (set_attr "fptype" "*,*,*,*,*,*,*,*,*,*,*,*,double,*,*")])
1949 (define_insn "*movdi_insn_sp64"
1950 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,m,?e,?e,?W,b")
1951 (match_operand:DI 1 "input_operand" "rI,N,m,rJ,e,W,e,J"))]
1953 && (register_operand (operands[0], DImode)
1954 || register_or_zero_operand (operands[1], DImode))"
1957 sethi\t%%hi(%a1), %0
1964 [(set_attr "type" "*,*,load,store,fpmove,fpload,fpstore,fga")
1965 (set_attr "fptype" "*,*,*,*,double,*,*,double")])
1967 (define_expand "movdi_pic_label_ref"
1968 [(set (match_dup 3) (high:DI
1969 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
1970 (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1971 (set (match_dup 4) (lo_sum:DI (match_dup 3)
1972 (unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1973 (set (match_operand:DI 0 "register_operand" "=r")
1974 (minus:DI (match_dup 5) (match_dup 4)))]
1975 "TARGET_ARCH64 && flag_pic"
1977 current_function_uses_pic_offset_table = 1;
1978 operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
1981 operands[3] = operands[0];
1982 operands[4] = operands[0];
1986 operands[3] = gen_reg_rtx (DImode);
1987 operands[4] = gen_reg_rtx (DImode);
1989 operands[5] = pic_offset_table_rtx;
1992 (define_insn "*movdi_high_pic_label_ref"
1993 [(set (match_operand:DI 0 "register_operand" "=r")
1995 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
1996 (match_operand:DI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1997 "TARGET_ARCH64 && flag_pic"
1998 "sethi\t%%hi(%a2-(%a1-.)), %0")
2000 (define_insn "*movdi_lo_sum_pic_label_ref"
2001 [(set (match_operand:DI 0 "register_operand" "=r")
2002 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2003 (unspec:DI [(match_operand:DI 2 "label_ref_operand" "")
2004 (match_operand:DI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
2005 "TARGET_ARCH64 && flag_pic"
2006 "or\t%1, %%lo(%a3-(%a2-.)), %0")
2008 ;; SPARC-v9 code model support insns. See sparc_emit_set_symbolic_const64
2009 ;; in sparc.c to see what is going on here... PIC stuff comes first.
2011 (define_insn "movdi_lo_sum_pic"
2012 [(set (match_operand:DI 0 "register_operand" "=r")
2013 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2014 (unspec:DI [(match_operand:DI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
2015 "TARGET_ARCH64 && flag_pic"
2016 "or\t%1, %%lo(%a2), %0")
2018 (define_insn "movdi_high_pic"
2019 [(set (match_operand:DI 0 "register_operand" "=r")
2020 (high:DI (unspec:DI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
2021 "TARGET_ARCH64 && flag_pic && check_pic (1)"
2022 "sethi\t%%hi(%a1), %0")
2024 (define_insn "*sethi_di_medlow_embmedany_pic"
2025 [(set (match_operand:DI 0 "register_operand" "=r")
2026 (high:DI (match_operand:DI 1 "medium_pic_operand" "")))]
2027 "(TARGET_CM_MEDLOW || TARGET_CM_EMBMEDANY) && check_pic (1)"
2028 "sethi\t%%hi(%a1), %0")
2030 (define_insn "*sethi_di_medlow"
2031 [(set (match_operand:DI 0 "register_operand" "=r")
2032 (high:DI (match_operand:DI 1 "symbolic_operand" "")))]
2033 "TARGET_CM_MEDLOW && check_pic (1)"
2034 "sethi\t%%hi(%a1), %0")
2036 (define_insn "*losum_di_medlow"
2037 [(set (match_operand:DI 0 "register_operand" "=r")
2038 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2039 (match_operand:DI 2 "symbolic_operand" "")))]
2041 "or\t%1, %%lo(%a2), %0")
2043 (define_insn "seth44"
2044 [(set (match_operand:DI 0 "register_operand" "=r")
2045 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETH44)))]
2047 "sethi\t%%h44(%a1), %0")
2049 (define_insn "setm44"
2050 [(set (match_operand:DI 0 "register_operand" "=r")
2051 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2052 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_SETM44)))]
2054 "or\t%1, %%m44(%a2), %0")
2056 (define_insn "setl44"
2057 [(set (match_operand:DI 0 "register_operand" "=r")
2058 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2059 (match_operand:DI 2 "symbolic_operand" "")))]
2061 "or\t%1, %%l44(%a2), %0")
2063 (define_insn "sethh"
2064 [(set (match_operand:DI 0 "register_operand" "=r")
2065 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETHH)))]
2067 "sethi\t%%hh(%a1), %0")
2069 (define_insn "setlm"
2070 [(set (match_operand:DI 0 "register_operand" "=r")
2071 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETLM)))]
2073 "sethi\t%%lm(%a1), %0")
2075 (define_insn "sethm"
2076 [(set (match_operand:DI 0 "register_operand" "=r")
2077 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2078 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_EMB_SETHM)))]
2080 "or\t%1, %%hm(%a2), %0")
2082 (define_insn "setlo"
2083 [(set (match_operand:DI 0 "register_operand" "=r")
2084 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2085 (match_operand:DI 2 "symbolic_operand" "")))]
2087 "or\t%1, %%lo(%a2), %0")
2089 (define_insn "embmedany_sethi"
2090 [(set (match_operand:DI 0 "register_operand" "=r")
2091 (high:DI (unspec:DI [(match_operand:DI 1 "data_segment_operand" "")] UNSPEC_EMB_HISUM)))]
2092 "TARGET_CM_EMBMEDANY && check_pic (1)"
2093 "sethi\t%%hi(%a1), %0")
2095 (define_insn "embmedany_losum"
2096 [(set (match_operand:DI 0 "register_operand" "=r")
2097 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2098 (match_operand:DI 2 "data_segment_operand" "")))]
2099 "TARGET_CM_EMBMEDANY"
2100 "add\t%1, %%lo(%a2), %0")
2102 (define_insn "embmedany_brsum"
2103 [(set (match_operand:DI 0 "register_operand" "=r")
2104 (unspec:DI [(match_operand:DI 1 "register_operand" "r")] UNSPEC_EMB_HISUM))]
2105 "TARGET_CM_EMBMEDANY"
2108 (define_insn "embmedany_textuhi"
2109 [(set (match_operand:DI 0 "register_operand" "=r")
2110 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTUHI)))]
2111 "TARGET_CM_EMBMEDANY && check_pic (1)"
2112 "sethi\t%%uhi(%a1), %0")
2114 (define_insn "embmedany_texthi"
2115 [(set (match_operand:DI 0 "register_operand" "=r")
2116 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTHI)))]
2117 "TARGET_CM_EMBMEDANY && check_pic (1)"
2118 "sethi\t%%hi(%a1), %0")
2120 (define_insn "embmedany_textulo"
2121 [(set (match_operand:DI 0 "register_operand" "=r")
2122 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2123 (unspec:DI [(match_operand:DI 2 "text_segment_operand" "")] UNSPEC_EMB_TEXTULO)))]
2124 "TARGET_CM_EMBMEDANY"
2125 "or\t%1, %%ulo(%a2), %0")
2127 (define_insn "embmedany_textlo"
2128 [(set (match_operand:DI 0 "register_operand" "=r")
2129 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2130 (match_operand:DI 2 "text_segment_operand" "")))]
2131 "TARGET_CM_EMBMEDANY"
2132 "or\t%1, %%lo(%a2), %0")
2134 ;; Now some patterns to help reload out a bit.
2135 (define_expand "reload_indi"
2136 [(parallel [(match_operand:DI 0 "register_operand" "=r")
2137 (match_operand:DI 1 "immediate_operand" "")
2138 (match_operand:TI 2 "register_operand" "=&r")])]
2140 || TARGET_CM_EMBMEDANY)
2143 sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
2147 (define_expand "reload_outdi"
2148 [(parallel [(match_operand:DI 0 "register_operand" "=r")
2149 (match_operand:DI 1 "immediate_operand" "")
2150 (match_operand:TI 2 "register_operand" "=&r")])]
2152 || TARGET_CM_EMBMEDANY)
2155 sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
2159 ;; Split up putting CONSTs and REGs into DI regs when !arch64
2161 [(set (match_operand:DI 0 "register_operand" "")
2162 (match_operand:DI 1 "const_int_operand" ""))]
2163 "! TARGET_ARCH64 && reload_completed"
2164 [(clobber (const_int 0))]
2166 #if HOST_BITS_PER_WIDE_INT == 32
2167 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
2168 (INTVAL (operands[1]) < 0) ?
2171 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2174 unsigned int low, high;
2176 low = trunc_int_for_mode (INTVAL (operands[1]), SImode);
2177 high = trunc_int_for_mode (INTVAL (operands[1]) >> 32, SImode);
2178 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), GEN_INT (high)));
2180 /* Slick... but this trick loses if this subreg constant part
2181 can be done in one insn. */
2183 && ! SPARC_SETHI32_P (high)
2184 && ! SPARC_SIMM13_P (high))
2185 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2186 gen_highpart (SImode, operands[0])));
2188 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), GEN_INT (low)));
2194 [(set (match_operand:DI 0 "register_operand" "")
2195 (match_operand:DI 1 "const_double_operand" ""))]
2199 && ((GET_CODE (operands[0]) == REG
2200 && REGNO (operands[0]) < 32)
2201 || (GET_CODE (operands[0]) == SUBREG
2202 && GET_CODE (SUBREG_REG (operands[0])) == REG
2203 && REGNO (SUBREG_REG (operands[0])) < 32))))"
2204 [(clobber (const_int 0))]
2206 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
2207 GEN_INT (CONST_DOUBLE_HIGH (operands[1]))));
2209 /* Slick... but this trick loses if this subreg constant part
2210 can be done in one insn. */
2211 if (CONST_DOUBLE_LOW (operands[1]) == CONST_DOUBLE_HIGH (operands[1])
2212 && ! SPARC_SETHI32_P (CONST_DOUBLE_HIGH (operands[1]))
2213 && ! SPARC_SIMM13_P (CONST_DOUBLE_HIGH (operands[1])))
2215 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2216 gen_highpart (SImode, operands[0])));
2220 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2221 GEN_INT (CONST_DOUBLE_LOW (operands[1]))));
2227 [(set (match_operand:DI 0 "register_operand" "")
2228 (match_operand:DI 1 "register_operand" ""))]
2232 && ((GET_CODE (operands[0]) == REG
2233 && REGNO (operands[0]) < 32)
2234 || (GET_CODE (operands[0]) == SUBREG
2235 && GET_CODE (SUBREG_REG (operands[0])) == REG
2236 && REGNO (SUBREG_REG (operands[0])) < 32))))"
2237 [(clobber (const_int 0))]
2239 rtx set_dest = operands[0];
2240 rtx set_src = operands[1];
2244 dest1 = gen_highpart (SImode, set_dest);
2245 dest2 = gen_lowpart (SImode, set_dest);
2246 src1 = gen_highpart (SImode, set_src);
2247 src2 = gen_lowpart (SImode, set_src);
2249 /* Now emit using the real source and destination we found, swapping
2250 the order if we detect overlap. */
2251 if (reg_overlap_mentioned_p (dest1, src2))
2253 emit_insn (gen_movsi (dest2, src2));
2254 emit_insn (gen_movsi (dest1, src1));
2258 emit_insn (gen_movsi (dest1, src1));
2259 emit_insn (gen_movsi (dest2, src2));
2264 ;; Now handle the cases of memory moves from/to non-even
2265 ;; DI mode register pairs.
2267 [(set (match_operand:DI 0 "register_operand" "")
2268 (match_operand:DI 1 "memory_operand" ""))]
2271 && sparc_splitdi_legitimate (operands[0], operands[1]))"
2272 [(clobber (const_int 0))]
2274 rtx word0 = adjust_address (operands[1], SImode, 0);
2275 rtx word1 = adjust_address (operands[1], SImode, 4);
2276 rtx high_part = gen_highpart (SImode, operands[0]);
2277 rtx low_part = gen_lowpart (SImode, operands[0]);
2279 if (reg_overlap_mentioned_p (high_part, word1))
2281 emit_insn (gen_movsi (low_part, word1));
2282 emit_insn (gen_movsi (high_part, word0));
2286 emit_insn (gen_movsi (high_part, word0));
2287 emit_insn (gen_movsi (low_part, word1));
2293 [(set (match_operand:DI 0 "memory_operand" "")
2294 (match_operand:DI 1 "register_operand" ""))]
2297 && sparc_splitdi_legitimate (operands[1], operands[0]))"
2298 [(clobber (const_int 0))]
2300 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0),
2301 gen_highpart (SImode, operands[1])));
2302 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4),
2303 gen_lowpart (SImode, operands[1])));
2308 [(set (match_operand:DI 0 "memory_operand" "")
2309 (match_operand:DI 1 "const_zero_operand" ""))]
2313 && ! mem_min_alignment (operands[0], 8)))
2314 && offsettable_memref_p (operands[0])"
2315 [(clobber (const_int 0))]
2317 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0), const0_rtx));
2318 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4), const0_rtx));
2323 ;; Floating point and vector move instructions
2325 ;; We don't define V1SI because SI should work just fine.
2326 (define_mode_macro V32 [SF V2HI V4QI])
2328 ;; Yes, you guessed it right, the former movsf expander.
2329 (define_expand "mov<V32:mode>"
2330 [(set (match_operand:V32 0 "nonimmediate_operand" "")
2331 (match_operand:V32 1 "general_operand" ""))]
2332 "<V32:MODE>mode == SFmode || TARGET_VIS"
2334 if (sparc_expand_move (<V32:MODE>mode, operands))
2338 (define_insn "*movsf_insn"
2339 [(set (match_operand:V32 0 "nonimmediate_operand" "=d,f,*r,*r,*r,f,*r,m,m")
2340 (match_operand:V32 1 "input_operand" "GY,f,*rRY,Q,S,m,m,f,*rGY"))]
2342 && (register_operand (operands[0], <V32:MODE>mode)
2343 || register_or_zero_operand (operands[1], <V32:MODE>mode))"
2345 if (GET_CODE (operands[1]) == CONST_DOUBLE
2346 && (which_alternative == 2
2347 || which_alternative == 3
2348 || which_alternative == 4))
2353 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2354 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2355 operands[1] = GEN_INT (i);
2358 switch (which_alternative)
2361 return "fzeros\t%0";
2363 return "fmovs\t%1, %0";
2365 return "mov\t%1, %0";
2367 return "sethi\t%%hi(%a1), %0";
2372 return "ld\t%1, %0";
2375 return "st\t%r1, %0";
2380 [(set_attr "type" "fga,fpmove,*,*,*,fpload,load,fpstore,store")])
2382 ;; Exactly the same as above, except that all `f' cases are deleted.
2383 ;; This is necessary to prevent reload from ever trying to use a `f' reg
2386 (define_insn "*movsf_insn_no_fpu"
2387 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r,r,m")
2388 (match_operand:SF 1 "input_operand" "rR,Q,S,m,rG"))]
2390 && (register_operand (operands[0], SFmode)
2391 || register_or_zero_operand (operands[1], SFmode))"
2393 if (GET_CODE (operands[1]) == CONST_DOUBLE
2394 && (which_alternative == 0
2395 || which_alternative == 1
2396 || which_alternative == 2))
2401 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2402 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2403 operands[1] = GEN_INT (i);
2406 switch (which_alternative)
2409 return "mov\t%1, %0";
2411 return "sethi\t%%hi(%a1), %0";
2415 return "ld\t%1, %0";
2417 return "st\t%r1, %0";
2422 [(set_attr "type" "*,*,*,load,store")])
2424 ;; The following 3 patterns build SFmode constants in integer registers.
2426 (define_insn "*movsf_lo_sum"
2427 [(set (match_operand:SF 0 "register_operand" "=r")
2428 (lo_sum:SF (match_operand:SF 1 "register_operand" "r")
2429 (match_operand:SF 2 "fp_const_high_losum_operand" "S")))]
2435 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[2]);
2436 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2437 operands[2] = GEN_INT (i);
2438 return "or\t%1, %%lo(%a2), %0";
2441 (define_insn "*movsf_high"
2442 [(set (match_operand:SF 0 "register_operand" "=r")
2443 (high:SF (match_operand:SF 1 "fp_const_high_losum_operand" "S")))]
2449 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2450 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2451 operands[1] = GEN_INT (i);
2452 return "sethi\t%%hi(%1), %0";
2456 [(set (match_operand:SF 0 "register_operand" "")
2457 (match_operand:SF 1 "fp_const_high_losum_operand" ""))]
2458 "REG_P (operands[0]) && REGNO (operands[0]) < 32"
2459 [(set (match_dup 0) (high:SF (match_dup 1)))
2460 (set (match_dup 0) (lo_sum:SF (match_dup 0) (match_dup 1)))])
2462 (define_mode_macro V64 [DF V2SI V4HI V8QI])
2464 ;; Yes, you again guessed it right, the former movdf expander.
2465 (define_expand "mov<V64:mode>"
2466 [(set (match_operand:V64 0 "nonimmediate_operand" "")
2467 (match_operand:V64 1 "general_operand" ""))]
2468 "<V64:MODE>mode == DFmode || TARGET_VIS"
2470 if (sparc_expand_move (<V64:MODE>mode, operands))
2474 ;; Be careful, fmovd does not exist when !v9.
2475 (define_insn "*movdf_insn_sp32"
2476 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,W,U,T,o,e,*r,o,e,o")
2477 (match_operand:DF 1 "input_operand" "W#F,e,T,U,G,e,*rFo,*r,o#F,e"))]
2480 && (register_operand (operands[0], DFmode)
2481 || register_or_zero_operand (operands[1], DFmode))"
2493 [(set_attr "type" "fpload,fpstore,load,store,*,*,*,*,*,*")
2494 (set_attr "length" "*,*,*,*,2,2,2,2,2,2")])
2496 (define_insn "*movdf_insn_sp32_no_fpu"
2497 [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,o,r,o")
2498 (match_operand:DF 1 "input_operand" "T,U,G,ro,r"))]
2501 && (register_operand (operands[0], DFmode)
2502 || register_or_zero_operand (operands[1], DFmode))"
2509 [(set_attr "type" "load,store,*,*,*")
2510 (set_attr "length" "*,*,2,2,2")])
2512 ;; We have available v9 double floats but not 64-bit integer registers.
2513 (define_insn "*movdf_insn_sp32_v9"
2514 [(set (match_operand:V64 0 "nonimmediate_operand" "=b,e,e,T,W,U,T,f,*r,o")
2515 (match_operand:V64 1 "input_operand" "GY,e,W#F,GY,e,T,U,o#F,*roGYF,*rGYf"))]
2519 && (register_operand (operands[0], <V64:MODE>mode)
2520 || register_or_zero_operand (operands[1], <V64:MODE>mode))"
2532 [(set_attr "type" "fga,fpmove,load,store,store,load,store,*,*,*")
2533 (set_attr "length" "*,*,*,*,*,*,*,2,2,2")
2534 (set_attr "fptype" "double,double,*,*,*,*,*,*,*,*")])
2536 (define_insn "*movdf_insn_sp32_v9_no_fpu"
2537 [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,T,r,o")
2538 (match_operand:DF 1 "input_operand" "T,U,G,ro,rG"))]
2542 && (register_operand (operands[0], DFmode)
2543 || register_or_zero_operand (operands[1], DFmode))"
2550 [(set_attr "type" "load,store,store,*,*")
2551 (set_attr "length" "*,*,*,2,2")])
2553 ;; We have available both v9 double floats and 64-bit integer registers.
2554 (define_insn "*movdf_insn_sp64"
2555 [(set (match_operand:V64 0 "nonimmediate_operand" "=b,e,e,W,*r,*r,m,*r")
2556 (match_operand:V64 1 "input_operand" "GY,e,W#F,e,*rGY,m,*rGY,F"))]
2559 && (register_operand (operands[0], <V64:MODE>mode)
2560 || register_or_zero_operand (operands[1], <V64:MODE>mode))"
2570 [(set_attr "type" "fga,fpmove,load,store,*,load,store,*")
2571 (set_attr "length" "*,*,*,*,*,*,*,2")
2572 (set_attr "fptype" "double,double,*,*,*,*,*,*")])
2574 (define_insn "*movdf_insn_sp64_no_fpu"
2575 [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m")
2576 (match_operand:DF 1 "input_operand" "r,m,rG"))]
2579 && (register_operand (operands[0], DFmode)
2580 || register_or_zero_operand (operands[1], DFmode))"
2585 [(set_attr "type" "*,load,store")])
2587 ;; This pattern build DFmode constants in integer registers.
2589 [(set (match_operand:DF 0 "register_operand" "")
2590 (match_operand:DF 1 "const_double_operand" ""))]
2592 && (GET_CODE (operands[0]) == REG
2593 && REGNO (operands[0]) < 32)
2594 && ! const_zero_operand(operands[1], DFmode)
2595 && reload_completed"
2596 [(clobber (const_int 0))]
2601 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2602 REAL_VALUE_TO_TARGET_DOUBLE (r, l);
2603 operands[0] = gen_rtx_raw_REG (DImode, REGNO (operands[0]));
2607 #if HOST_BITS_PER_WIDE_INT == 32
2612 val = ((HOST_WIDE_INT)(unsigned long)l[1] |
2613 ((HOST_WIDE_INT)(unsigned long)l[0] << 32));
2614 emit_insn (gen_movdi (operands[0], gen_int_mode (val, DImode)));
2619 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
2620 gen_int_mode (l[0], SImode)));
2622 /* Slick... but this trick loses if this subreg constant part
2623 can be done in one insn. */
2625 && ! SPARC_SETHI32_P (l[0])
2626 && ! SPARC_SIMM13_P (l[0]))
2628 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2629 gen_highpart (SImode, operands[0])));
2633 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2634 gen_int_mode (l[1], SImode)));
2640 ;; Ok, now the splits to handle all the multi insn and
2641 ;; mis-aligned memory address cases.
2642 ;; In these splits please take note that we must be
2643 ;; careful when V9 but not ARCH64 because the integer
2644 ;; register DFmode cases must be handled.
2646 [(set (match_operand:V64 0 "register_operand" "")
2647 (match_operand:V64 1 "register_operand" ""))]
2650 && ((GET_CODE (operands[0]) == REG
2651 && REGNO (operands[0]) < 32)
2652 || (GET_CODE (operands[0]) == SUBREG
2653 && GET_CODE (SUBREG_REG (operands[0])) == REG
2654 && REGNO (SUBREG_REG (operands[0])) < 32))))
2655 && reload_completed"
2656 [(clobber (const_int 0))]
2658 rtx set_dest = operands[0];
2659 rtx set_src = operands[1];
2662 enum machine_mode half_mode;
2664 /* We can be expanded for DFmode or integral vector modes. */
2665 if (<V64:MODE>mode == DFmode)
2670 dest1 = gen_highpart (half_mode, set_dest);
2671 dest2 = gen_lowpart (half_mode, set_dest);
2672 src1 = gen_highpart (half_mode, set_src);
2673 src2 = gen_lowpart (half_mode, set_src);
2675 /* Now emit using the real source and destination we found, swapping
2676 the order if we detect overlap. */
2677 if (reg_overlap_mentioned_p (dest1, src2))
2679 emit_move_insn_1 (dest2, src2);
2680 emit_move_insn_1 (dest1, src1);
2684 emit_move_insn_1 (dest1, src1);
2685 emit_move_insn_1 (dest2, src2);
2691 [(set (match_operand:V64 0 "register_operand" "")
2692 (match_operand:V64 1 "memory_operand" ""))]
2695 && (((REGNO (operands[0]) % 2) != 0)
2696 || ! mem_min_alignment (operands[1], 8))
2697 && offsettable_memref_p (operands[1])"
2698 [(clobber (const_int 0))]
2700 enum machine_mode half_mode;
2703 /* We can be expanded for DFmode or integral vector modes. */
2704 if (<V64:MODE>mode == DFmode)
2709 word0 = adjust_address (operands[1], half_mode, 0);
2710 word1 = adjust_address (operands[1], half_mode, 4);
2712 if (reg_overlap_mentioned_p (gen_highpart (half_mode, operands[0]), word1))
2714 emit_move_insn_1 (gen_lowpart (half_mode, operands[0]), word1);
2715 emit_move_insn_1 (gen_highpart (half_mode, operands[0]), word0);
2719 emit_move_insn_1 (gen_highpart (half_mode, operands[0]), word0);
2720 emit_move_insn_1 (gen_lowpart (half_mode, operands[0]), word1);
2726 [(set (match_operand:V64 0 "memory_operand" "")
2727 (match_operand:V64 1 "register_operand" ""))]
2730 && (((REGNO (operands[1]) % 2) != 0)
2731 || ! mem_min_alignment (operands[0], 8))
2732 && offsettable_memref_p (operands[0])"
2733 [(clobber (const_int 0))]
2735 enum machine_mode half_mode;
2738 /* We can be expanded for DFmode or integral vector modes. */
2739 if (<V64:MODE>mode == DFmode)
2744 word0 = adjust_address (operands[0], half_mode, 0);
2745 word1 = adjust_address (operands[0], half_mode, 4);
2747 emit_move_insn_1 (word0, gen_highpart (half_mode, operands[1]));
2748 emit_move_insn_1 (word1, gen_lowpart (half_mode, operands[1]));
2753 [(set (match_operand:V64 0 "memory_operand" "")
2754 (match_operand:V64 1 "const_zero_operand" ""))]
2758 && ! mem_min_alignment (operands[0], 8)))
2759 && offsettable_memref_p (operands[0])"
2760 [(clobber (const_int 0))]
2762 enum machine_mode half_mode;
2765 /* We can be expanded for DFmode or integral vector modes. */
2766 if (<V64:MODE>mode == DFmode)
2771 dest1 = adjust_address (operands[0], half_mode, 0);
2772 dest2 = adjust_address (operands[0], half_mode, 4);
2774 emit_move_insn_1 (dest1, CONST0_RTX (half_mode));
2775 emit_move_insn_1 (dest2, CONST0_RTX (half_mode));
2780 [(set (match_operand:V64 0 "register_operand" "")
2781 (match_operand:V64 1 "const_zero_operand" ""))]
2784 && ((GET_CODE (operands[0]) == REG
2785 && REGNO (operands[0]) < 32)
2786 || (GET_CODE (operands[0]) == SUBREG
2787 && GET_CODE (SUBREG_REG (operands[0])) == REG
2788 && REGNO (SUBREG_REG (operands[0])) < 32))"
2789 [(clobber (const_int 0))]
2791 enum machine_mode half_mode;
2792 rtx set_dest = operands[0];
2795 /* We can be expanded for DFmode or integral vector modes. */
2796 if (<V64:MODE>mode == DFmode)
2801 dest1 = gen_highpart (half_mode, set_dest);
2802 dest2 = gen_lowpart (half_mode, set_dest);
2803 emit_move_insn_1 (dest1, CONST0_RTX (half_mode));
2804 emit_move_insn_1 (dest2, CONST0_RTX (half_mode));
2808 (define_expand "movtf"
2809 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2810 (match_operand:TF 1 "general_operand" ""))]
2813 if (sparc_expand_move (TFmode, operands))
2817 (define_insn "*movtf_insn_sp32"
2818 [(set (match_operand:TF 0 "nonimmediate_operand" "=b,e,o,U,r")
2819 (match_operand:TF 1 "input_operand" "G,oe,GeUr,o,roG"))]
2822 && (register_operand (operands[0], TFmode)
2823 || register_or_zero_operand (operands[1], TFmode))"
2825 [(set_attr "length" "4")])
2827 ;; Exactly the same as above, except that all `e' cases are deleted.
2828 ;; This is necessary to prevent reload from ever trying to use a `e' reg
2831 (define_insn "*movtf_insn_sp32_no_fpu"
2832 [(set (match_operand:TF 0 "nonimmediate_operand" "=o,U,o,r,o")
2833 (match_operand:TF 1 "input_operand" "G,o,U,roG,r"))]
2836 && (register_operand (operands[0], TFmode)
2837 || register_or_zero_operand (operands[1], TFmode))"
2839 [(set_attr "length" "4")])
2841 (define_insn "*movtf_insn_sp64"
2842 [(set (match_operand:TF 0 "nonimmediate_operand" "=b,e,o,r")
2843 (match_operand:TF 1 "input_operand" "G,oe,Ger,roG"))]
2846 && ! TARGET_HARD_QUAD
2847 && (register_operand (operands[0], TFmode)
2848 || register_or_zero_operand (operands[1], TFmode))"
2850 [(set_attr "length" "2")])
2852 (define_insn "*movtf_insn_sp64_hq"
2853 [(set (match_operand:TF 0 "nonimmediate_operand" "=b,e,e,m,o,r")
2854 (match_operand:TF 1 "input_operand" "G,e,m,e,rG,roG"))]
2858 && (register_operand (operands[0], TFmode)
2859 || register_or_zero_operand (operands[1], TFmode))"
2867 [(set_attr "type" "*,fpmove,fpload,fpstore,*,*")
2868 (set_attr "length" "2,*,*,*,2,2")])
2870 (define_insn "*movtf_insn_sp64_no_fpu"
2871 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o")
2872 (match_operand:TF 1 "input_operand" "orG,rG"))]
2875 && (register_operand (operands[0], TFmode)
2876 || register_or_zero_operand (operands[1], TFmode))"
2878 [(set_attr "length" "2")])
2880 ;; Now all the splits to handle multi-insn TF mode moves.
2882 [(set (match_operand:TF 0 "register_operand" "")
2883 (match_operand:TF 1 "register_operand" ""))]
2887 && ! TARGET_HARD_QUAD)
2888 || ! fp_register_operand (operands[0], TFmode))"
2889 [(clobber (const_int 0))]
2891 rtx set_dest = operands[0];
2892 rtx set_src = operands[1];
2896 dest1 = gen_df_reg (set_dest, 0);
2897 dest2 = gen_df_reg (set_dest, 1);
2898 src1 = gen_df_reg (set_src, 0);
2899 src2 = gen_df_reg (set_src, 1);
2901 /* Now emit using the real source and destination we found, swapping
2902 the order if we detect overlap. */
2903 if (reg_overlap_mentioned_p (dest1, src2))
2905 emit_insn (gen_movdf (dest2, src2));
2906 emit_insn (gen_movdf (dest1, src1));
2910 emit_insn (gen_movdf (dest1, src1));
2911 emit_insn (gen_movdf (dest2, src2));
2917 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2918 (match_operand:TF 1 "const_zero_operand" ""))]
2920 [(clobber (const_int 0))]
2922 rtx set_dest = operands[0];
2925 switch (GET_CODE (set_dest))
2928 dest1 = gen_df_reg (set_dest, 0);
2929 dest2 = gen_df_reg (set_dest, 1);
2932 dest1 = adjust_address (set_dest, DFmode, 0);
2933 dest2 = adjust_address (set_dest, DFmode, 8);
2939 emit_insn (gen_movdf (dest1, CONST0_RTX (DFmode)));
2940 emit_insn (gen_movdf (dest2, CONST0_RTX (DFmode)));
2945 [(set (match_operand:TF 0 "register_operand" "")
2946 (match_operand:TF 1 "memory_operand" ""))]
2948 && offsettable_memref_p (operands[1])
2950 || ! TARGET_HARD_QUAD
2951 || ! fp_register_operand (operands[0], TFmode)))"
2952 [(clobber (const_int 0))]
2954 rtx word0 = adjust_address (operands[1], DFmode, 0);
2955 rtx word1 = adjust_address (operands[1], DFmode, 8);
2956 rtx set_dest, dest1, dest2;
2958 set_dest = operands[0];
2960 dest1 = gen_df_reg (set_dest, 0);
2961 dest2 = gen_df_reg (set_dest, 1);
2963 /* Now output, ordering such that we don't clobber any registers
2964 mentioned in the address. */
2965 if (reg_overlap_mentioned_p (dest1, word1))
2968 emit_insn (gen_movdf (dest2, word1));
2969 emit_insn (gen_movdf (dest1, word0));
2973 emit_insn (gen_movdf (dest1, word0));
2974 emit_insn (gen_movdf (dest2, word1));
2980 [(set (match_operand:TF 0 "memory_operand" "")
2981 (match_operand:TF 1 "register_operand" ""))]
2983 && offsettable_memref_p (operands[0])
2985 || ! TARGET_HARD_QUAD
2986 || ! fp_register_operand (operands[1], TFmode)))"
2987 [(clobber (const_int 0))]
2989 rtx set_src = operands[1];
2991 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 0),
2992 gen_df_reg (set_src, 0)));
2993 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 8),
2994 gen_df_reg (set_src, 1)));
2999 ;; SPARC-V9 conditional move instructions.
3001 ;; We can handle larger constants here for some flavors, but for now we keep
3002 ;; it simple and only allow those constants supported by all flavors.
3003 ;; Note that emit_conditional_move canonicalizes operands 2,3 so that operand
3004 ;; 3 contains the constant if one is present, but we handle either for
3005 ;; generality (sparc.c puts a constant in operand 2).
3007 (define_expand "movqicc"
3008 [(set (match_operand:QI 0 "register_operand" "")
3009 (if_then_else:QI (match_operand 1 "comparison_operator" "")
3010 (match_operand:QI 2 "arith10_operand" "")
3011 (match_operand:QI 3 "arith10_operand" "")))]
3014 enum rtx_code code = GET_CODE (operands[1]);
3016 if (GET_MODE (sparc_compare_op0) == DImode
3020 if (sparc_compare_op1 == const0_rtx
3021 && GET_CODE (sparc_compare_op0) == REG
3022 && GET_MODE (sparc_compare_op0) == DImode
3023 && v9_regcmp_p (code))
3025 operands[1] = gen_rtx_fmt_ee (code, DImode,
3026 sparc_compare_op0, sparc_compare_op1);
3030 rtx cc_reg = gen_compare_reg (code);
3031 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3035 (define_expand "movhicc"
3036 [(set (match_operand:HI 0 "register_operand" "")
3037 (if_then_else:HI (match_operand 1 "comparison_operator" "")
3038 (match_operand:HI 2 "arith10_operand" "")
3039 (match_operand:HI 3 "arith10_operand" "")))]
3042 enum rtx_code code = GET_CODE (operands[1]);
3044 if (GET_MODE (sparc_compare_op0) == DImode
3048 if (sparc_compare_op1 == const0_rtx
3049 && GET_CODE (sparc_compare_op0) == REG
3050 && GET_MODE (sparc_compare_op0) == DImode
3051 && v9_regcmp_p (code))
3053 operands[1] = gen_rtx_fmt_ee (code, DImode,
3054 sparc_compare_op0, sparc_compare_op1);
3058 rtx cc_reg = gen_compare_reg (code);
3059 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3063 (define_expand "movsicc"
3064 [(set (match_operand:SI 0 "register_operand" "")
3065 (if_then_else:SI (match_operand 1 "comparison_operator" "")
3066 (match_operand:SI 2 "arith10_operand" "")
3067 (match_operand:SI 3 "arith10_operand" "")))]
3070 enum rtx_code code = GET_CODE (operands[1]);
3071 enum machine_mode op0_mode = GET_MODE (sparc_compare_op0);
3073 if (sparc_compare_op1 == const0_rtx
3074 && GET_CODE (sparc_compare_op0) == REG
3075 && (TARGET_ARCH64 && op0_mode == DImode && v9_regcmp_p (code)))
3077 operands[1] = gen_rtx_fmt_ee (code, op0_mode,
3078 sparc_compare_op0, sparc_compare_op1);
3082 rtx cc_reg = gen_compare_reg (code);
3083 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg),
3084 cc_reg, const0_rtx);
3088 (define_expand "movdicc"
3089 [(set (match_operand:DI 0 "register_operand" "")
3090 (if_then_else:DI (match_operand 1 "comparison_operator" "")
3091 (match_operand:DI 2 "arith10_operand" "")
3092 (match_operand:DI 3 "arith10_operand" "")))]
3095 enum rtx_code code = GET_CODE (operands[1]);
3097 if (sparc_compare_op1 == const0_rtx
3098 && GET_CODE (sparc_compare_op0) == REG
3099 && GET_MODE (sparc_compare_op0) == DImode
3100 && v9_regcmp_p (code))
3102 operands[1] = gen_rtx_fmt_ee (code, DImode,
3103 sparc_compare_op0, sparc_compare_op1);
3107 rtx cc_reg = gen_compare_reg (code);
3108 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg),
3109 cc_reg, const0_rtx);
3113 (define_expand "movsfcc"
3114 [(set (match_operand:SF 0 "register_operand" "")
3115 (if_then_else:SF (match_operand 1 "comparison_operator" "")
3116 (match_operand:SF 2 "register_operand" "")
3117 (match_operand:SF 3 "register_operand" "")))]
3118 "TARGET_V9 && TARGET_FPU"
3120 enum rtx_code code = GET_CODE (operands[1]);
3122 if (GET_MODE (sparc_compare_op0) == DImode
3126 if (sparc_compare_op1 == const0_rtx
3127 && GET_CODE (sparc_compare_op0) == REG
3128 && GET_MODE (sparc_compare_op0) == DImode
3129 && v9_regcmp_p (code))
3131 operands[1] = gen_rtx_fmt_ee (code, DImode,
3132 sparc_compare_op0, sparc_compare_op1);
3136 rtx cc_reg = gen_compare_reg (code);
3137 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3141 (define_expand "movdfcc"
3142 [(set (match_operand:DF 0 "register_operand" "")
3143 (if_then_else:DF (match_operand 1 "comparison_operator" "")
3144 (match_operand:DF 2 "register_operand" "")
3145 (match_operand:DF 3 "register_operand" "")))]
3146 "TARGET_V9 && TARGET_FPU"
3148 enum rtx_code code = GET_CODE (operands[1]);
3150 if (GET_MODE (sparc_compare_op0) == DImode
3154 if (sparc_compare_op1 == const0_rtx
3155 && GET_CODE (sparc_compare_op0) == REG
3156 && GET_MODE (sparc_compare_op0) == DImode
3157 && v9_regcmp_p (code))
3159 operands[1] = gen_rtx_fmt_ee (code, DImode,
3160 sparc_compare_op0, sparc_compare_op1);
3164 rtx cc_reg = gen_compare_reg (code);
3165 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3169 (define_expand "movtfcc"
3170 [(set (match_operand:TF 0 "register_operand" "")
3171 (if_then_else:TF (match_operand 1 "comparison_operator" "")
3172 (match_operand:TF 2 "register_operand" "")
3173 (match_operand:TF 3 "register_operand" "")))]
3174 "TARGET_V9 && TARGET_FPU"
3176 enum rtx_code code = GET_CODE (operands[1]);
3178 if (GET_MODE (sparc_compare_op0) == DImode
3182 if (sparc_compare_op1 == const0_rtx
3183 && GET_CODE (sparc_compare_op0) == REG
3184 && GET_MODE (sparc_compare_op0) == DImode
3185 && v9_regcmp_p (code))
3187 operands[1] = gen_rtx_fmt_ee (code, DImode,
3188 sparc_compare_op0, sparc_compare_op1);
3192 rtx cc_reg = gen_compare_reg (code);
3193 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3197 ;; Conditional move define_insns.
3199 (define_insn "*movqi_cc_sp64"
3200 [(set (match_operand:QI 0 "register_operand" "=r,r")
3201 (if_then_else:QI (match_operator 1 "comparison_operator"
3202 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
3204 (match_operand:QI 3 "arith11_operand" "rL,0")
3205 (match_operand:QI 4 "arith11_operand" "0,rL")))]
3209 mov%c1\t%x2, %4, %0"
3210 [(set_attr "type" "cmove")])
3212 (define_insn "*movhi_cc_sp64"
3213 [(set (match_operand:HI 0 "register_operand" "=r,r")
3214 (if_then_else:HI (match_operator 1 "comparison_operator"
3215 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
3217 (match_operand:HI 3 "arith11_operand" "rL,0")
3218 (match_operand:HI 4 "arith11_operand" "0,rL")))]
3222 mov%c1\t%x2, %4, %0"
3223 [(set_attr "type" "cmove")])
3225 (define_insn "*movsi_cc_sp64"
3226 [(set (match_operand:SI 0 "register_operand" "=r,r")
3227 (if_then_else:SI (match_operator 1 "comparison_operator"
3228 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
3230 (match_operand:SI 3 "arith11_operand" "rL,0")
3231 (match_operand:SI 4 "arith11_operand" "0,rL")))]
3235 mov%c1\t%x2, %4, %0"
3236 [(set_attr "type" "cmove")])
3238 (define_insn "*movdi_cc_sp64"
3239 [(set (match_operand:DI 0 "register_operand" "=r,r")
3240 (if_then_else:DI (match_operator 1 "comparison_operator"
3241 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
3243 (match_operand:DI 3 "arith11_operand" "rL,0")
3244 (match_operand:DI 4 "arith11_operand" "0,rL")))]
3248 mov%c1\t%x2, %4, %0"
3249 [(set_attr "type" "cmove")])
3251 (define_insn "*movdi_cc_sp64_trunc"
3252 [(set (match_operand:SI 0 "register_operand" "=r,r")
3253 (if_then_else:SI (match_operator 1 "comparison_operator"
3254 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
3256 (match_operand:SI 3 "arith11_operand" "rL,0")
3257 (match_operand:SI 4 "arith11_operand" "0,rL")))]
3261 mov%c1\t%x2, %4, %0"
3262 [(set_attr "type" "cmove")])
3264 (define_insn "*movsf_cc_sp64"
3265 [(set (match_operand:SF 0 "register_operand" "=f,f")
3266 (if_then_else:SF (match_operator 1 "comparison_operator"
3267 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
3269 (match_operand:SF 3 "register_operand" "f,0")
3270 (match_operand:SF 4 "register_operand" "0,f")))]
3271 "TARGET_V9 && TARGET_FPU"
3273 fmovs%C1\t%x2, %3, %0
3274 fmovs%c1\t%x2, %4, %0"
3275 [(set_attr "type" "fpcmove")])
3277 (define_insn "movdf_cc_sp64"
3278 [(set (match_operand:DF 0 "register_operand" "=e,e")
3279 (if_then_else:DF (match_operator 1 "comparison_operator"
3280 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
3282 (match_operand:DF 3 "register_operand" "e,0")
3283 (match_operand:DF 4 "register_operand" "0,e")))]
3284 "TARGET_V9 && TARGET_FPU"
3286 fmovd%C1\t%x2, %3, %0
3287 fmovd%c1\t%x2, %4, %0"
3288 [(set_attr "type" "fpcmove")
3289 (set_attr "fptype" "double")])
3291 (define_insn "*movtf_cc_hq_sp64"
3292 [(set (match_operand:TF 0 "register_operand" "=e,e")
3293 (if_then_else:TF (match_operator 1 "comparison_operator"
3294 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
3296 (match_operand:TF 3 "register_operand" "e,0")
3297 (match_operand:TF 4 "register_operand" "0,e")))]
3298 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
3300 fmovq%C1\t%x2, %3, %0
3301 fmovq%c1\t%x2, %4, %0"
3302 [(set_attr "type" "fpcmove")])
3304 (define_insn_and_split "*movtf_cc_sp64"
3305 [(set (match_operand:TF 0 "register_operand" "=e,e")
3306 (if_then_else:TF (match_operator 1 "comparison_operator"
3307 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
3309 (match_operand:TF 3 "register_operand" "e,0")
3310 (match_operand:TF 4 "register_operand" "0,e")))]
3311 "TARGET_V9 && TARGET_FPU && !TARGET_HARD_QUAD"
3313 "&& reload_completed"
3314 [(clobber (const_int 0))]
3316 rtx set_dest = operands[0];
3317 rtx set_srca = operands[3];
3318 rtx set_srcb = operands[4];
3319 int third = rtx_equal_p (set_dest, set_srca);
3321 rtx srca1, srca2, srcb1, srcb2;
3323 dest1 = gen_df_reg (set_dest, 0);
3324 dest2 = gen_df_reg (set_dest, 1);
3325 srca1 = gen_df_reg (set_srca, 0);
3326 srca2 = gen_df_reg (set_srca, 1);
3327 srcb1 = gen_df_reg (set_srcb, 0);
3328 srcb2 = gen_df_reg (set_srcb, 1);
3330 /* Now emit using the real source and destination we found, swapping
3331 the order if we detect overlap. */
3332 if ((third && reg_overlap_mentioned_p (dest1, srcb2))
3333 || (!third && reg_overlap_mentioned_p (dest1, srca2)))
3335 emit_insn (gen_movdf_cc_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
3336 emit_insn (gen_movdf_cc_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
3340 emit_insn (gen_movdf_cc_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
3341 emit_insn (gen_movdf_cc_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
3345 [(set_attr "length" "2")])
3347 (define_insn "*movqi_cc_reg_sp64"
3348 [(set (match_operand:QI 0 "register_operand" "=r,r")
3349 (if_then_else:QI (match_operator 1 "v9_register_compare_operator"
3350 [(match_operand:DI 2 "register_operand" "r,r")
3352 (match_operand:QI 3 "arith10_operand" "rM,0")
3353 (match_operand:QI 4 "arith10_operand" "0,rM")))]
3356 movr%D1\t%2, %r3, %0
3357 movr%d1\t%2, %r4, %0"
3358 [(set_attr "type" "cmove")])
3360 (define_insn "*movhi_cc_reg_sp64"
3361 [(set (match_operand:HI 0 "register_operand" "=r,r")
3362 (if_then_else:HI (match_operator 1 "v9_register_compare_operator"
3363 [(match_operand:DI 2 "register_operand" "r,r")
3365 (match_operand:HI 3 "arith10_operand" "rM,0")
3366 (match_operand:HI 4 "arith10_operand" "0,rM")))]
3369 movr%D1\t%2, %r3, %0
3370 movr%d1\t%2, %r4, %0"
3371 [(set_attr "type" "cmove")])
3373 (define_insn "*movsi_cc_reg_sp64"
3374 [(set (match_operand:SI 0 "register_operand" "=r,r")
3375 (if_then_else:SI (match_operator 1 "v9_register_compare_operator"
3376 [(match_operand:DI 2 "register_operand" "r,r")
3378 (match_operand:SI 3 "arith10_operand" "rM,0")
3379 (match_operand:SI 4 "arith10_operand" "0,rM")))]
3382 movr%D1\t%2, %r3, %0
3383 movr%d1\t%2, %r4, %0"
3384 [(set_attr "type" "cmove")])
3386 (define_insn "*movdi_cc_reg_sp64"
3387 [(set (match_operand:DI 0 "register_operand" "=r,r")
3388 (if_then_else:DI (match_operator 1 "v9_register_compare_operator"
3389 [(match_operand:DI 2 "register_operand" "r,r")
3391 (match_operand:DI 3 "arith10_operand" "rM,0")
3392 (match_operand:DI 4 "arith10_operand" "0,rM")))]
3395 movr%D1\t%2, %r3, %0
3396 movr%d1\t%2, %r4, %0"
3397 [(set_attr "type" "cmove")])
3399 (define_insn "*movsf_cc_reg_sp64"
3400 [(set (match_operand:SF 0 "register_operand" "=f,f")
3401 (if_then_else:SF (match_operator 1 "v9_register_compare_operator"
3402 [(match_operand:DI 2 "register_operand" "r,r")
3404 (match_operand:SF 3 "register_operand" "f,0")
3405 (match_operand:SF 4 "register_operand" "0,f")))]
3406 "TARGET_ARCH64 && TARGET_FPU"
3408 fmovrs%D1\t%2, %3, %0
3409 fmovrs%d1\t%2, %4, %0"
3410 [(set_attr "type" "fpcrmove")])
3412 (define_insn "movdf_cc_reg_sp64"
3413 [(set (match_operand:DF 0 "register_operand" "=e,e")
3414 (if_then_else:DF (match_operator 1 "v9_register_compare_operator"
3415 [(match_operand:DI 2 "register_operand" "r,r")
3417 (match_operand:DF 3 "register_operand" "e,0")
3418 (match_operand:DF 4 "register_operand" "0,e")))]
3419 "TARGET_ARCH64 && TARGET_FPU"
3421 fmovrd%D1\t%2, %3, %0
3422 fmovrd%d1\t%2, %4, %0"
3423 [(set_attr "type" "fpcrmove")
3424 (set_attr "fptype" "double")])
3426 (define_insn "*movtf_cc_reg_hq_sp64"
3427 [(set (match_operand:TF 0 "register_operand" "=e,e")
3428 (if_then_else:TF (match_operator 1 "v9_register_compare_operator"
3429 [(match_operand:DI 2 "register_operand" "r,r")
3431 (match_operand:TF 3 "register_operand" "e,0")
3432 (match_operand:TF 4 "register_operand" "0,e")))]
3433 "TARGET_ARCH64 && TARGET_FPU && TARGET_HARD_QUAD"
3435 fmovrq%D1\t%2, %3, %0
3436 fmovrq%d1\t%2, %4, %0"
3437 [(set_attr "type" "fpcrmove")])
3439 (define_insn_and_split "*movtf_cc_reg_sp64"
3440 [(set (match_operand:TF 0 "register_operand" "=e,e")
3441 (if_then_else:TF (match_operator 1 "v9_register_compare_operator"
3442 [(match_operand:DI 2 "register_operand" "r,r")
3444 (match_operand:TF 3 "register_operand" "e,0")
3445 (match_operand:TF 4 "register_operand" "0,e")))]
3446 "TARGET_ARCH64 && TARGET_FPU && ! TARGET_HARD_QUAD"
3448 "&& reload_completed"
3449 [(clobber (const_int 0))]
3451 rtx set_dest = operands[0];
3452 rtx set_srca = operands[3];
3453 rtx set_srcb = operands[4];
3454 int third = rtx_equal_p (set_dest, set_srca);
3456 rtx srca1, srca2, srcb1, srcb2;
3458 dest1 = gen_df_reg (set_dest, 0);
3459 dest2 = gen_df_reg (set_dest, 1);
3460 srca1 = gen_df_reg (set_srca, 0);
3461 srca2 = gen_df_reg (set_srca, 1);
3462 srcb1 = gen_df_reg (set_srcb, 0);
3463 srcb2 = gen_df_reg (set_srcb, 1);
3465 /* Now emit using the real source and destination we found, swapping
3466 the order if we detect overlap. */
3467 if ((third && reg_overlap_mentioned_p (dest1, srcb2))
3468 || (!third && reg_overlap_mentioned_p (dest1, srca2)))
3470 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
3471 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
3475 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
3476 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
3480 [(set_attr "length" "2")])
3483 ;; Zero-extension instructions
3485 ;; These patterns originally accepted general_operands, however, slightly
3486 ;; better code is generated by only accepting register_operands, and then
3487 ;; letting combine generate the ldu[hb] insns.
3489 (define_expand "zero_extendhisi2"
3490 [(set (match_operand:SI 0 "register_operand" "")
3491 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
3494 rtx temp = gen_reg_rtx (SImode);
3495 rtx shift_16 = GEN_INT (16);
3496 int op1_subbyte = 0;
3498 if (GET_CODE (operand1) == SUBREG)
3500 op1_subbyte = SUBREG_BYTE (operand1);
3501 op1_subbyte /= GET_MODE_SIZE (SImode);
3502 op1_subbyte *= GET_MODE_SIZE (SImode);
3503 operand1 = XEXP (operand1, 0);
3506 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3508 emit_insn (gen_lshrsi3 (operand0, temp, shift_16));
3512 (define_insn "*zero_extendhisi2_insn"
3513 [(set (match_operand:SI 0 "register_operand" "=r")
3514 (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
3517 [(set_attr "type" "load")
3518 (set_attr "us3load_type" "3cycle")])
3520 (define_expand "zero_extendqihi2"
3521 [(set (match_operand:HI 0 "register_operand" "")
3522 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
3526 (define_insn "*zero_extendqihi2_insn"
3527 [(set (match_operand:HI 0 "register_operand" "=r,r")
3528 (zero_extend:HI (match_operand:QI 1 "input_operand" "r,m")))]
3529 "GET_CODE (operands[1]) != CONST_INT"
3533 [(set_attr "type" "*,load")
3534 (set_attr "us3load_type" "*,3cycle")])
3536 (define_expand "zero_extendqisi2"
3537 [(set (match_operand:SI 0 "register_operand" "")
3538 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
3542 (define_insn "*zero_extendqisi2_insn"
3543 [(set (match_operand:SI 0 "register_operand" "=r,r")
3544 (zero_extend:SI (match_operand:QI 1 "input_operand" "r,m")))]
3545 "GET_CODE (operands[1]) != CONST_INT"
3549 [(set_attr "type" "*,load")
3550 (set_attr "us3load_type" "*,3cycle")])
3552 (define_expand "zero_extendqidi2"
3553 [(set (match_operand:DI 0 "register_operand" "")
3554 (zero_extend:DI (match_operand:QI 1 "register_operand" "")))]
3558 (define_insn "*zero_extendqidi2_insn"
3559 [(set (match_operand:DI 0 "register_operand" "=r,r")
3560 (zero_extend:DI (match_operand:QI 1 "input_operand" "r,m")))]
3561 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
3565 [(set_attr "type" "*,load")
3566 (set_attr "us3load_type" "*,3cycle")])
3568 (define_expand "zero_extendhidi2"
3569 [(set (match_operand:DI 0 "register_operand" "")
3570 (zero_extend:DI (match_operand:HI 1 "register_operand" "")))]
3573 rtx temp = gen_reg_rtx (DImode);
3574 rtx shift_48 = GEN_INT (48);
3575 int op1_subbyte = 0;
3577 if (GET_CODE (operand1) == SUBREG)
3579 op1_subbyte = SUBREG_BYTE (operand1);
3580 op1_subbyte /= GET_MODE_SIZE (DImode);
3581 op1_subbyte *= GET_MODE_SIZE (DImode);
3582 operand1 = XEXP (operand1, 0);
3585 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
3587 emit_insn (gen_lshrdi3 (operand0, temp, shift_48));
3591 (define_insn "*zero_extendhidi2_insn"
3592 [(set (match_operand:DI 0 "register_operand" "=r")
3593 (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
3596 [(set_attr "type" "load")
3597 (set_attr "us3load_type" "3cycle")])
3599 ;; ??? Write truncdisi pattern using sra?
3601 (define_expand "zero_extendsidi2"
3602 [(set (match_operand:DI 0 "register_operand" "")
3603 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
3607 (define_insn "*zero_extendsidi2_insn_sp64"
3608 [(set (match_operand:DI 0 "register_operand" "=r,r")
3609 (zero_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
3610 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
3614 [(set_attr "type" "shift,load")])
3616 (define_insn_and_split "*zero_extendsidi2_insn_sp32"
3617 [(set (match_operand:DI 0 "register_operand" "=r")
3618 (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
3621 "&& reload_completed"
3622 [(set (match_dup 2) (match_dup 3))
3623 (set (match_dup 4) (match_dup 5))]
3627 dest1 = gen_highpart (SImode, operands[0]);
3628 dest2 = gen_lowpart (SImode, operands[0]);
3630 /* Swap the order in case of overlap. */
3631 if (REGNO (dest1) == REGNO (operands[1]))
3633 operands[2] = dest2;
3634 operands[3] = operands[1];
3635 operands[4] = dest1;
3636 operands[5] = const0_rtx;
3640 operands[2] = dest1;
3641 operands[3] = const0_rtx;
3642 operands[4] = dest2;
3643 operands[5] = operands[1];
3646 [(set_attr "length" "2")])
3648 ;; Simplify comparisons of extended values.
3650 (define_insn "*cmp_zero_extendqisi2"
3652 (compare:CC (zero_extend:SI (match_operand:QI 0 "register_operand" "r"))
3655 "andcc\t%0, 0xff, %%g0"
3656 [(set_attr "type" "compare")])
3658 (define_insn "*cmp_zero_qi"
3660 (compare:CC (match_operand:QI 0 "register_operand" "r")
3663 "andcc\t%0, 0xff, %%g0"
3664 [(set_attr "type" "compare")])
3666 (define_insn "*cmp_zero_extendqisi2_set"
3668 (compare:CC (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
3670 (set (match_operand:SI 0 "register_operand" "=r")
3671 (zero_extend:SI (match_dup 1)))]
3673 "andcc\t%1, 0xff, %0"
3674 [(set_attr "type" "compare")])
3676 (define_insn "*cmp_zero_extendqisi2_andcc_set"
3678 (compare:CC (and:SI (match_operand:SI 1 "register_operand" "r")
3681 (set (match_operand:SI 0 "register_operand" "=r")
3682 (zero_extend:SI (subreg:QI (match_dup 1) 0)))]
3684 "andcc\t%1, 0xff, %0"
3685 [(set_attr "type" "compare")])
3687 (define_insn "*cmp_zero_extendqidi2"
3689 (compare:CCX (zero_extend:DI (match_operand:QI 0 "register_operand" "r"))
3692 "andcc\t%0, 0xff, %%g0"
3693 [(set_attr "type" "compare")])
3695 (define_insn "*cmp_zero_qi_sp64"
3697 (compare:CCX (match_operand:QI 0 "register_operand" "r")
3700 "andcc\t%0, 0xff, %%g0"
3701 [(set_attr "type" "compare")])
3703 (define_insn "*cmp_zero_extendqidi2_set"
3705 (compare:CCX (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
3707 (set (match_operand:DI 0 "register_operand" "=r")
3708 (zero_extend:DI (match_dup 1)))]
3710 "andcc\t%1, 0xff, %0"
3711 [(set_attr "type" "compare")])
3713 (define_insn "*cmp_zero_extendqidi2_andcc_set"
3715 (compare:CCX (and:DI (match_operand:DI 1 "register_operand" "r")
3718 (set (match_operand:DI 0 "register_operand" "=r")
3719 (zero_extend:DI (subreg:QI (match_dup 1) 0)))]
3721 "andcc\t%1, 0xff, %0"
3722 [(set_attr "type" "compare")])
3724 ;; Similarly, handle {SI,DI}->QI mode truncation followed by a compare.
3726 (define_insn "*cmp_siqi_trunc"
3728 (compare:CC (subreg:QI (match_operand:SI 0 "register_operand" "r") 3)
3731 "andcc\t%0, 0xff, %%g0"
3732 [(set_attr "type" "compare")])
3734 (define_insn "*cmp_siqi_trunc_set"
3736 (compare:CC (subreg:QI (match_operand:SI 1 "register_operand" "r") 3)
3738 (set (match_operand:QI 0 "register_operand" "=r")
3739 (subreg:QI (match_dup 1) 3))]
3741 "andcc\t%1, 0xff, %0"
3742 [(set_attr "type" "compare")])
3744 (define_insn "*cmp_diqi_trunc"
3746 (compare:CC (subreg:QI (match_operand:DI 0 "register_operand" "r") 7)
3749 "andcc\t%0, 0xff, %%g0"
3750 [(set_attr "type" "compare")])
3752 (define_insn "*cmp_diqi_trunc_set"
3754 (compare:CC (subreg:QI (match_operand:DI 1 "register_operand" "r") 7)
3756 (set (match_operand:QI 0 "register_operand" "=r")
3757 (subreg:QI (match_dup 1) 7))]
3759 "andcc\t%1, 0xff, %0"
3760 [(set_attr "type" "compare")])
3763 ;; Sign-extension instructions
3765 ;; These patterns originally accepted general_operands, however, slightly
3766 ;; better code is generated by only accepting register_operands, and then
3767 ;; letting combine generate the lds[hb] insns.
3769 (define_expand "extendhisi2"
3770 [(set (match_operand:SI 0 "register_operand" "")
3771 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
3774 rtx temp = gen_reg_rtx (SImode);
3775 rtx shift_16 = GEN_INT (16);
3776 int op1_subbyte = 0;
3778 if (GET_CODE (operand1) == SUBREG)
3780 op1_subbyte = SUBREG_BYTE (operand1);
3781 op1_subbyte /= GET_MODE_SIZE (SImode);
3782 op1_subbyte *= GET_MODE_SIZE (SImode);
3783 operand1 = XEXP (operand1, 0);
3786 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3788 emit_insn (gen_ashrsi3 (operand0, temp, shift_16));
3792 (define_insn "*sign_extendhisi2_insn"
3793 [(set (match_operand:SI 0 "register_operand" "=r")
3794 (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
3797 [(set_attr "type" "sload")
3798 (set_attr "us3load_type" "3cycle")])
3800 (define_expand "extendqihi2"
3801 [(set (match_operand:HI 0 "register_operand" "")
3802 (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
3805 rtx temp = gen_reg_rtx (SImode);
3806 rtx shift_24 = GEN_INT (24);
3807 int op1_subbyte = 0;
3808 int op0_subbyte = 0;
3810 if (GET_CODE (operand1) == SUBREG)
3812 op1_subbyte = SUBREG_BYTE (operand1);
3813 op1_subbyte /= GET_MODE_SIZE (SImode);
3814 op1_subbyte *= GET_MODE_SIZE (SImode);
3815 operand1 = XEXP (operand1, 0);
3817 if (GET_CODE (operand0) == SUBREG)
3819 op0_subbyte = SUBREG_BYTE (operand0);
3820 op0_subbyte /= GET_MODE_SIZE (SImode);
3821 op0_subbyte *= GET_MODE_SIZE (SImode);
3822 operand0 = XEXP (operand0, 0);
3824 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3826 if (GET_MODE (operand0) != SImode)
3827 operand0 = gen_rtx_SUBREG (SImode, operand0, op0_subbyte);
3828 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
3832 (define_insn "*sign_extendqihi2_insn"
3833 [(set (match_operand:HI 0 "register_operand" "=r")
3834 (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
3837 [(set_attr "type" "sload")
3838 (set_attr "us3load_type" "3cycle")])
3840 (define_expand "extendqisi2"
3841 [(set (match_operand:SI 0 "register_operand" "")
3842 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
3845 rtx temp = gen_reg_rtx (SImode);
3846 rtx shift_24 = GEN_INT (24);
3847 int op1_subbyte = 0;
3849 if (GET_CODE (operand1) == SUBREG)
3851 op1_subbyte = SUBREG_BYTE (operand1);
3852 op1_subbyte /= GET_MODE_SIZE (SImode);
3853 op1_subbyte *= GET_MODE_SIZE (SImode);
3854 operand1 = XEXP (operand1, 0);
3857 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3859 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
3863 (define_insn "*sign_extendqisi2_insn"
3864 [(set (match_operand:SI 0 "register_operand" "=r")
3865 (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
3868 [(set_attr "type" "sload")
3869 (set_attr "us3load_type" "3cycle")])
3871 (define_expand "extendqidi2"
3872 [(set (match_operand:DI 0 "register_operand" "")
3873 (sign_extend:DI (match_operand:QI 1 "register_operand" "")))]
3876 rtx temp = gen_reg_rtx (DImode);
3877 rtx shift_56 = GEN_INT (56);
3878 int op1_subbyte = 0;
3880 if (GET_CODE (operand1) == SUBREG)
3882 op1_subbyte = SUBREG_BYTE (operand1);
3883 op1_subbyte /= GET_MODE_SIZE (DImode);
3884 op1_subbyte *= GET_MODE_SIZE (DImode);
3885 operand1 = XEXP (operand1, 0);
3888 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
3890 emit_insn (gen_ashrdi3 (operand0, temp, shift_56));
3894 (define_insn "*sign_extendqidi2_insn"
3895 [(set (match_operand:DI 0 "register_operand" "=r")
3896 (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
3899 [(set_attr "type" "sload")
3900 (set_attr "us3load_type" "3cycle")])
3902 (define_expand "extendhidi2"
3903 [(set (match_operand:DI 0 "register_operand" "")
3904 (sign_extend:DI (match_operand:HI 1 "register_operand" "")))]
3907 rtx temp = gen_reg_rtx (DImode);
3908 rtx shift_48 = GEN_INT (48);
3909 int op1_subbyte = 0;
3911 if (GET_CODE (operand1) == SUBREG)
3913 op1_subbyte = SUBREG_BYTE (operand1);
3914 op1_subbyte /= GET_MODE_SIZE (DImode);
3915 op1_subbyte *= GET_MODE_SIZE (DImode);
3916 operand1 = XEXP (operand1, 0);
3919 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
3921 emit_insn (gen_ashrdi3 (operand0, temp, shift_48));
3925 (define_insn "*sign_extendhidi2_insn"
3926 [(set (match_operand:DI 0 "register_operand" "=r")
3927 (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
3930 [(set_attr "type" "sload")
3931 (set_attr "us3load_type" "3cycle")])
3933 (define_expand "extendsidi2"
3934 [(set (match_operand:DI 0 "register_operand" "")
3935 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
3939 (define_insn "*sign_extendsidi2_insn"
3940 [(set (match_operand:DI 0 "register_operand" "=r,r")
3941 (sign_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
3946 [(set_attr "type" "shift,sload")
3947 (set_attr "us3load_type" "*,3cycle")])
3950 ;; Special pattern for optimizing bit-field compares. This is needed
3951 ;; because combine uses this as a canonical form.
3953 (define_insn "*cmp_zero_extract"
3956 (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
3957 (match_operand:SI 1 "small_int_operand" "I")
3958 (match_operand:SI 2 "small_int_operand" "I"))
3960 "INTVAL (operands[2]) > 19"
3962 int len = INTVAL (operands[1]);
3963 int pos = 32 - INTVAL (operands[2]) - len;
3964 HOST_WIDE_INT mask = ((1 << len) - 1) << pos;
3965 operands[1] = GEN_INT (mask);
3966 return "andcc\t%0, %1, %%g0";
3968 [(set_attr "type" "compare")])
3970 (define_insn "*cmp_zero_extract_sp64"
3973 (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
3974 (match_operand:SI 1 "small_int_operand" "I")
3975 (match_operand:SI 2 "small_int_operand" "I"))
3977 "TARGET_ARCH64 && INTVAL (operands[2]) > 51"
3979 int len = INTVAL (operands[1]);
3980 int pos = 64 - INTVAL (operands[2]) - len;
3981 HOST_WIDE_INT mask = (((unsigned HOST_WIDE_INT) 1 << len) - 1) << pos;
3982 operands[1] = GEN_INT (mask);
3983 return "andcc\t%0, %1, %%g0";
3985 [(set_attr "type" "compare")])
3988 ;; Conversions between float, double and long double.
3990 (define_insn "extendsfdf2"
3991 [(set (match_operand:DF 0 "register_operand" "=e")
3993 (match_operand:SF 1 "register_operand" "f")))]
3996 [(set_attr "type" "fp")
3997 (set_attr "fptype" "double")])
3999 (define_expand "extendsftf2"
4000 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4002 (match_operand:SF 1 "register_operand" "")))]
4003 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4004 "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
4006 (define_insn "*extendsftf2_hq"
4007 [(set (match_operand:TF 0 "register_operand" "=e")
4009 (match_operand:SF 1 "register_operand" "f")))]
4010 "TARGET_FPU && TARGET_HARD_QUAD"
4012 [(set_attr "type" "fp")])
4014 (define_expand "extenddftf2"
4015 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4017 (match_operand:DF 1 "register_operand" "")))]
4018 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4019 "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
4021 (define_insn "*extenddftf2_hq"
4022 [(set (match_operand:TF 0 "register_operand" "=e")
4024 (match_operand:DF 1 "register_operand" "e")))]
4025 "TARGET_FPU && TARGET_HARD_QUAD"
4027 [(set_attr "type" "fp")])
4029 (define_insn "truncdfsf2"
4030 [(set (match_operand:SF 0 "register_operand" "=f")
4032 (match_operand:DF 1 "register_operand" "e")))]
4035 [(set_attr "type" "fp")
4036 (set_attr "fptype" "double")])
4038 (define_expand "trunctfsf2"
4039 [(set (match_operand:SF 0 "register_operand" "")
4041 (match_operand:TF 1 "general_operand" "")))]
4042 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4043 "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
4045 (define_insn "*trunctfsf2_hq"
4046 [(set (match_operand:SF 0 "register_operand" "=f")
4048 (match_operand:TF 1 "register_operand" "e")))]
4049 "TARGET_FPU && TARGET_HARD_QUAD"
4051 [(set_attr "type" "fp")])
4053 (define_expand "trunctfdf2"
4054 [(set (match_operand:DF 0 "register_operand" "")
4056 (match_operand:TF 1 "general_operand" "")))]
4057 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4058 "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
4060 (define_insn "*trunctfdf2_hq"
4061 [(set (match_operand:DF 0 "register_operand" "=e")
4063 (match_operand:TF 1 "register_operand" "e")))]
4064 "TARGET_FPU && TARGET_HARD_QUAD"
4066 [(set_attr "type" "fp")])
4069 ;; Conversion between fixed point and floating point.
4071 (define_insn "floatsisf2"
4072 [(set (match_operand:SF 0 "register_operand" "=f")
4073 (float:SF (match_operand:SI 1 "register_operand" "f")))]
4076 [(set_attr "type" "fp")
4077 (set_attr "fptype" "double")])
4079 (define_insn "floatsidf2"
4080 [(set (match_operand:DF 0 "register_operand" "=e")
4081 (float:DF (match_operand:SI 1 "register_operand" "f")))]
4084 [(set_attr "type" "fp")
4085 (set_attr "fptype" "double")])
4087 (define_expand "floatsitf2"
4088 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4089 (float:TF (match_operand:SI 1 "register_operand" "")))]
4090 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4091 "emit_tfmode_cvt (FLOAT, operands); DONE;")
4093 (define_insn "*floatsitf2_hq"
4094 [(set (match_operand:TF 0 "register_operand" "=e")
4095 (float:TF (match_operand:SI 1 "register_operand" "f")))]
4096 "TARGET_FPU && TARGET_HARD_QUAD"
4098 [(set_attr "type" "fp")])
4100 (define_expand "floatunssitf2"
4101 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4102 (unsigned_float:TF (match_operand:SI 1 "register_operand" "")))]
4103 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4104 "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
4106 ;; Now the same for 64 bit sources.
4108 (define_insn "floatdisf2"
4109 [(set (match_operand:SF 0 "register_operand" "=f")
4110 (float:SF (match_operand:DI 1 "register_operand" "e")))]
4111 "TARGET_V9 && TARGET_FPU"
4113 [(set_attr "type" "fp")
4114 (set_attr "fptype" "double")])
4116 (define_expand "floatunsdisf2"
4117 [(use (match_operand:SF 0 "register_operand" ""))
4118 (use (match_operand:DI 1 "general_operand" ""))]
4119 "TARGET_ARCH64 && TARGET_FPU"
4120 "sparc_emit_floatunsdi (operands, SFmode); DONE;")
4122 (define_insn "floatdidf2"
4123 [(set (match_operand:DF 0 "register_operand" "=e")
4124 (float:DF (match_operand:DI 1 "register_operand" "e")))]
4125 "TARGET_V9 && TARGET_FPU"
4127 [(set_attr "type" "fp")
4128 (set_attr "fptype" "double")])
4130 (define_expand "floatunsdidf2"
4131 [(use (match_operand:DF 0 "register_operand" ""))
4132 (use (match_operand:DI 1 "general_operand" ""))]
4133 "TARGET_ARCH64 && TARGET_FPU"
4134 "sparc_emit_floatunsdi (operands, DFmode); DONE;")
4136 (define_expand "floatditf2"
4137 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4138 (float:TF (match_operand:DI 1 "register_operand" "")))]
4139 "TARGET_FPU && TARGET_V9 && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4140 "emit_tfmode_cvt (FLOAT, operands); DONE;")
4142 (define_insn "*floatditf2_hq"
4143 [(set (match_operand:TF 0 "register_operand" "=e")
4144 (float:TF (match_operand:DI 1 "register_operand" "e")))]
4145 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
4147 [(set_attr "type" "fp")])
4149 (define_expand "floatunsditf2"
4150 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4151 (unsigned_float:TF (match_operand:DI 1 "register_operand" "")))]
4152 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4153 "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
4155 ;; Convert a float to an actual integer.
4156 ;; Truncation is performed as part of the conversion.
4158 (define_insn "fix_truncsfsi2"
4159 [(set (match_operand:SI 0 "register_operand" "=f")
4160 (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
4163 [(set_attr "type" "fp")
4164 (set_attr "fptype" "double")])
4166 (define_insn "fix_truncdfsi2"
4167 [(set (match_operand:SI 0 "register_operand" "=f")
4168 (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
4171 [(set_attr "type" "fp")
4172 (set_attr "fptype" "double")])
4174 (define_expand "fix_trunctfsi2"
4175 [(set (match_operand:SI 0 "register_operand" "")
4176 (fix:SI (match_operand:TF 1 "general_operand" "")))]
4177 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4178 "emit_tfmode_cvt (FIX, operands); DONE;")
4180 (define_insn "*fix_trunctfsi2_hq"
4181 [(set (match_operand:SI 0 "register_operand" "=f")
4182 (fix:SI (match_operand:TF 1 "register_operand" "e")))]
4183 "TARGET_FPU && TARGET_HARD_QUAD"
4185 [(set_attr "type" "fp")])
4187 (define_expand "fixuns_trunctfsi2"
4188 [(set (match_operand:SI 0 "register_operand" "")
4189 (unsigned_fix:SI (match_operand:TF 1 "general_operand" "")))]
4190 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4191 "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
4193 ;; Now the same, for V9 targets
4195 (define_insn "fix_truncsfdi2"
4196 [(set (match_operand:DI 0 "register_operand" "=e")
4197 (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
4198 "TARGET_V9 && TARGET_FPU"
4200 [(set_attr "type" "fp")
4201 (set_attr "fptype" "double")])
4203 (define_expand "fixuns_truncsfdi2"
4204 [(use (match_operand:DI 0 "register_operand" ""))
4205 (use (match_operand:SF 1 "general_operand" ""))]
4206 "TARGET_ARCH64 && TARGET_FPU"
4207 "sparc_emit_fixunsdi (operands, SFmode); DONE;")
4209 (define_insn "fix_truncdfdi2"
4210 [(set (match_operand:DI 0 "register_operand" "=e")
4211 (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
4212 "TARGET_V9 && TARGET_FPU"
4214 [(set_attr "type" "fp")
4215 (set_attr "fptype" "double")])
4217 (define_expand "fixuns_truncdfdi2"
4218 [(use (match_operand:DI 0 "register_operand" ""))
4219 (use (match_operand:DF 1 "general_operand" ""))]
4220 "TARGET_ARCH64 && TARGET_FPU"
4221 "sparc_emit_fixunsdi (operands, DFmode); DONE;")
4223 (define_expand "fix_trunctfdi2"
4224 [(set (match_operand:DI 0 "register_operand" "")
4225 (fix:DI (match_operand:TF 1 "general_operand" "")))]
4226 "TARGET_V9 && TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4227 "emit_tfmode_cvt (FIX, operands); DONE;")
4229 (define_insn "*fix_trunctfdi2_hq"
4230 [(set (match_operand:DI 0 "register_operand" "=e")
4231 (fix:DI (match_operand:TF 1 "register_operand" "e")))]
4232 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
4234 [(set_attr "type" "fp")])
4236 (define_expand "fixuns_trunctfdi2"
4237 [(set (match_operand:DI 0 "register_operand" "")
4238 (unsigned_fix:DI (match_operand:TF 1 "general_operand" "")))]
4239 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4240 "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
4243 ;; Integer addition/subtraction instructions.
4245 (define_expand "adddi3"
4246 [(set (match_operand:DI 0 "register_operand" "")
4247 (plus:DI (match_operand:DI 1 "register_operand" "")
4248 (match_operand:DI 2 "arith_double_add_operand" "")))]
4251 if (! TARGET_ARCH64)
4253 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
4254 gen_rtx_SET (VOIDmode, operands[0],
4255 gen_rtx_PLUS (DImode, operands[1],
4257 gen_rtx_CLOBBER (VOIDmode,
4258 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
4263 (define_insn_and_split "adddi3_insn_sp32"
4264 [(set (match_operand:DI 0 "register_operand" "=r")
4265 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
4266 (match_operand:DI 2 "arith_double_operand" "rHI")))
4267 (clobber (reg:CC 100))]
4270 "&& reload_completed"
4271 [(parallel [(set (reg:CC_NOOV 100)
4272 (compare:CC_NOOV (plus:SI (match_dup 4)
4276 (plus:SI (match_dup 4) (match_dup 5)))])
4278 (plus:SI (plus:SI (match_dup 7)
4280 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4282 operands[3] = gen_lowpart (SImode, operands[0]);
4283 operands[4] = gen_lowpart (SImode, operands[1]);
4284 operands[5] = gen_lowpart (SImode, operands[2]);
4285 operands[6] = gen_highpart (SImode, operands[0]);
4286 operands[7] = gen_highpart_mode (SImode, DImode, operands[1]);
4287 #if HOST_BITS_PER_WIDE_INT == 32
4288 if (GET_CODE (operands[2]) == CONST_INT)
4290 if (INTVAL (operands[2]) < 0)
4291 operands[8] = constm1_rtx;
4293 operands[8] = const0_rtx;
4297 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
4299 [(set_attr "length" "2")])
4301 ;; LTU here means "carry set"
4303 [(set (match_operand:SI 0 "register_operand" "=r")
4304 (plus:SI (plus:SI (match_operand:SI 1 "arith_operand" "%r")
4305 (match_operand:SI 2 "arith_operand" "rI"))
4306 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4309 [(set_attr "type" "ialuX")])
4311 (define_insn_and_split "*addx_extend_sp32"
4312 [(set (match_operand:DI 0 "register_operand" "=r")
4313 (zero_extend:DI (plus:SI (plus:SI
4314 (match_operand:SI 1 "register_or_zero_operand" "%rJ")
4315 (match_operand:SI 2 "arith_operand" "rI"))
4316 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4319 "&& reload_completed"
4320 [(set (match_dup 3) (plus:SI (plus:SI (match_dup 1) (match_dup 2))
4321 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
4322 (set (match_dup 4) (const_int 0))]
4323 "operands[3] = gen_lowpart (SImode, operands[0]);
4324 operands[4] = gen_highpart_mode (SImode, DImode, operands[1]);"
4325 [(set_attr "length" "2")])
4327 (define_insn "*addx_extend_sp64"
4328 [(set (match_operand:DI 0 "register_operand" "=r")
4329 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ")
4330 (match_operand:SI 2 "arith_operand" "rI"))
4331 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4334 [(set_attr "type" "ialuX")])
4336 (define_insn_and_split ""
4337 [(set (match_operand:DI 0 "register_operand" "=r")
4338 (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4339 (match_operand:DI 2 "register_operand" "r")))
4340 (clobber (reg:CC 100))]
4343 "&& reload_completed"
4344 [(parallel [(set (reg:CC_NOOV 100)
4345 (compare:CC_NOOV (plus:SI (match_dup 3) (match_dup 1))
4347 (set (match_dup 5) (plus:SI (match_dup 3) (match_dup 1)))])
4349 (plus:SI (plus:SI (match_dup 4) (const_int 0))
4350 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4351 "operands[3] = gen_lowpart (SImode, operands[2]);
4352 operands[4] = gen_highpart (SImode, operands[2]);
4353 operands[5] = gen_lowpart (SImode, operands[0]);
4354 operands[6] = gen_highpart (SImode, operands[0]);"
4355 [(set_attr "length" "2")])
4357 (define_insn "*adddi3_sp64"
4358 [(set (match_operand:DI 0 "register_operand" "=r,r")
4359 (plus:DI (match_operand:DI 1 "register_operand" "%r,r")
4360 (match_operand:DI 2 "arith_add_operand" "rI,O")))]
4366 (define_insn "addsi3"
4367 [(set (match_operand:SI 0 "register_operand" "=r,r,d")
4368 (plus:SI (match_operand:SI 1 "register_operand" "%r,r,d")
4369 (match_operand:SI 2 "arith_add_operand" "rI,O,d")))]
4374 fpadd32s\t%1, %2, %0"
4375 [(set_attr "type" "*,*,fga")
4376 (set_attr "fptype" "*,*,single")])
4378 (define_insn "*cmp_cc_plus"
4379 [(set (reg:CC_NOOV 100)
4380 (compare:CC_NOOV (plus:SI (match_operand:SI 0 "arith_operand" "%r")
4381 (match_operand:SI 1 "arith_operand" "rI"))
4384 "addcc\t%0, %1, %%g0"
4385 [(set_attr "type" "compare")])
4387 (define_insn "*cmp_ccx_plus"
4388 [(set (reg:CCX_NOOV 100)
4389 (compare:CCX_NOOV (plus:DI (match_operand:DI 0 "arith_operand" "%r")
4390 (match_operand:DI 1 "arith_operand" "rI"))
4393 "addcc\t%0, %1, %%g0"
4394 [(set_attr "type" "compare")])
4396 (define_insn "*cmp_cc_plus_set"
4397 [(set (reg:CC_NOOV 100)
4398 (compare:CC_NOOV (plus:SI (match_operand:SI 1 "arith_operand" "%r")
4399 (match_operand:SI 2 "arith_operand" "rI"))
4401 (set (match_operand:SI 0 "register_operand" "=r")
4402 (plus:SI (match_dup 1) (match_dup 2)))]
4405 [(set_attr "type" "compare")])
4407 (define_insn "*cmp_ccx_plus_set"
4408 [(set (reg:CCX_NOOV 100)
4409 (compare:CCX_NOOV (plus:DI (match_operand:DI 1 "arith_operand" "%r")
4410 (match_operand:DI 2 "arith_operand" "rI"))
4412 (set (match_operand:DI 0 "register_operand" "=r")
4413 (plus:DI (match_dup 1) (match_dup 2)))]
4416 [(set_attr "type" "compare")])
4418 (define_expand "subdi3"
4419 [(set (match_operand:DI 0 "register_operand" "")
4420 (minus:DI (match_operand:DI 1 "register_operand" "")
4421 (match_operand:DI 2 "arith_double_add_operand" "")))]
4424 if (! TARGET_ARCH64)
4426 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
4427 gen_rtx_SET (VOIDmode, operands[0],
4428 gen_rtx_MINUS (DImode, operands[1],
4430 gen_rtx_CLOBBER (VOIDmode,
4431 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
4436 (define_insn_and_split "subdi3_insn_sp32"
4437 [(set (match_operand:DI 0 "register_operand" "=r")
4438 (minus:DI (match_operand:DI 1 "register_operand" "r")
4439 (match_operand:DI 2 "arith_double_operand" "rHI")))
4440 (clobber (reg:CC 100))]
4443 "&& reload_completed"
4444 [(parallel [(set (reg:CC_NOOV 100)
4445 (compare:CC_NOOV (minus:SI (match_dup 4)
4449 (minus:SI (match_dup 4) (match_dup 5)))])
4451 (minus:SI (minus:SI (match_dup 7)
4453 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4455 operands[3] = gen_lowpart (SImode, operands[0]);
4456 operands[4] = gen_lowpart (SImode, operands[1]);
4457 operands[5] = gen_lowpart (SImode, operands[2]);
4458 operands[6] = gen_highpart (SImode, operands[0]);
4459 operands[7] = gen_highpart (SImode, operands[1]);
4460 #if HOST_BITS_PER_WIDE_INT == 32
4461 if (GET_CODE (operands[2]) == CONST_INT)
4463 if (INTVAL (operands[2]) < 0)
4464 operands[8] = constm1_rtx;
4466 operands[8] = const0_rtx;
4470 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
4472 [(set_attr "length" "2")])
4474 ;; LTU here means "carry set"
4476 [(set (match_operand:SI 0 "register_operand" "=r")
4477 (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
4478 (match_operand:SI 2 "arith_operand" "rI"))
4479 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4482 [(set_attr "type" "ialuX")])
4484 (define_insn "*subx_extend_sp64"
4485 [(set (match_operand:DI 0 "register_operand" "=r")
4486 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
4487 (match_operand:SI 2 "arith_operand" "rI"))
4488 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4491 [(set_attr "type" "ialuX")])
4493 (define_insn_and_split "*subx_extend"
4494 [(set (match_operand:DI 0 "register_operand" "=r")
4495 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
4496 (match_operand:SI 2 "arith_operand" "rI"))
4497 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4500 "&& reload_completed"
4501 [(set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 2))
4502 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
4503 (set (match_dup 4) (const_int 0))]
4504 "operands[3] = gen_lowpart (SImode, operands[0]);
4505 operands[4] = gen_highpart (SImode, operands[0]);"
4506 [(set_attr "length" "2")])
4508 (define_insn_and_split ""
4509 [(set (match_operand:DI 0 "register_operand" "=r")
4510 (minus:DI (match_operand:DI 1 "register_operand" "r")
4511 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))
4512 (clobber (reg:CC 100))]
4515 "&& reload_completed"
4516 [(parallel [(set (reg:CC_NOOV 100)
4517 (compare:CC_NOOV (minus:SI (match_dup 3) (match_dup 2))
4519 (set (match_dup 5) (minus:SI (match_dup 3) (match_dup 2)))])
4521 (minus:SI (minus:SI (match_dup 4) (const_int 0))
4522 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4523 "operands[3] = gen_lowpart (SImode, operands[1]);
4524 operands[4] = gen_highpart (SImode, operands[1]);
4525 operands[5] = gen_lowpart (SImode, operands[0]);
4526 operands[6] = gen_highpart (SImode, operands[0]);"
4527 [(set_attr "length" "2")])
4529 (define_insn "*subdi3_sp64"
4530 [(set (match_operand:DI 0 "register_operand" "=r,r")
4531 (minus:DI (match_operand:DI 1 "register_operand" "r,r")
4532 (match_operand:DI 2 "arith_add_operand" "rI,O")))]
4538 (define_insn "subsi3"
4539 [(set (match_operand:SI 0 "register_operand" "=r,r,d")
4540 (minus:SI (match_operand:SI 1 "register_operand" "r,r,d")
4541 (match_operand:SI 2 "arith_add_operand" "rI,O,d")))]
4546 fpsub32s\t%1, %2, %0"
4547 [(set_attr "type" "*,*,fga")
4548 (set_attr "fptype" "*,*,single")])
4550 (define_insn "*cmp_minus_cc"
4551 [(set (reg:CC_NOOV 100)
4552 (compare:CC_NOOV (minus:SI (match_operand:SI 0 "register_or_zero_operand" "rJ")
4553 (match_operand:SI 1 "arith_operand" "rI"))
4556 "subcc\t%r0, %1, %%g0"
4557 [(set_attr "type" "compare")])
4559 (define_insn "*cmp_minus_ccx"
4560 [(set (reg:CCX_NOOV 100)
4561 (compare:CCX_NOOV (minus:DI (match_operand:DI 0 "register_operand" "r")
4562 (match_operand:DI 1 "arith_operand" "rI"))
4565 "subcc\t%0, %1, %%g0"
4566 [(set_attr "type" "compare")])
4568 (define_insn "cmp_minus_cc_set"
4569 [(set (reg:CC_NOOV 100)
4570 (compare:CC_NOOV (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
4571 (match_operand:SI 2 "arith_operand" "rI"))
4573 (set (match_operand:SI 0 "register_operand" "=r")
4574 (minus:SI (match_dup 1) (match_dup 2)))]
4576 "subcc\t%r1, %2, %0"
4577 [(set_attr "type" "compare")])
4579 (define_insn "*cmp_minus_ccx_set"
4580 [(set (reg:CCX_NOOV 100)
4581 (compare:CCX_NOOV (minus:DI (match_operand:DI 1 "register_operand" "r")
4582 (match_operand:DI 2 "arith_operand" "rI"))
4584 (set (match_operand:DI 0 "register_operand" "=r")
4585 (minus:DI (match_dup 1) (match_dup 2)))]
4588 [(set_attr "type" "compare")])
4591 ;; Integer multiply/divide instructions.
4593 ;; The 32 bit multiply/divide instructions are deprecated on v9, but at
4594 ;; least in UltraSPARC I, II and IIi it is a win tick-wise.
4596 (define_insn "mulsi3"
4597 [(set (match_operand:SI 0 "register_operand" "=r")
4598 (mult:SI (match_operand:SI 1 "arith_operand" "%r")
4599 (match_operand:SI 2 "arith_operand" "rI")))]
4602 [(set_attr "type" "imul")])
4604 (define_expand "muldi3"
4605 [(set (match_operand:DI 0 "register_operand" "")
4606 (mult:DI (match_operand:DI 1 "arith_operand" "")
4607 (match_operand:DI 2 "arith_operand" "")))]
4608 "TARGET_ARCH64 || TARGET_V8PLUS"
4612 emit_insn (gen_muldi3_v8plus (operands[0], operands[1], operands[2]));
4617 (define_insn "*muldi3_sp64"
4618 [(set (match_operand:DI 0 "register_operand" "=r")
4619 (mult:DI (match_operand:DI 1 "arith_operand" "%r")
4620 (match_operand:DI 2 "arith_operand" "rI")))]
4623 [(set_attr "type" "imul")])
4625 ;; V8plus wide multiply.
4627 (define_insn "muldi3_v8plus"
4628 [(set (match_operand:DI 0 "register_operand" "=r,h")
4629 (mult:DI (match_operand:DI 1 "arith_operand" "%r,0")
4630 (match_operand:DI 2 "arith_operand" "rI,rI")))
4631 (clobber (match_scratch:SI 3 "=&h,X"))
4632 (clobber (match_scratch:SI 4 "=&h,X"))]
4635 if (sparc_check_64 (operands[1], insn) <= 0)
4636 output_asm_insn ("srl\t%L1, 0, %L1", operands);
4637 if (which_alternative == 1)
4638 output_asm_insn ("sllx\t%H1, 32, %H1", operands);
4639 if (GET_CODE (operands[2]) == CONST_INT)
4641 if (which_alternative == 1)
4642 return "or\t%L1, %H1, %H1\n\tmulx\t%H1, %2, %L0\;srlx\t%L0, 32, %H0";
4644 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";
4646 else if (rtx_equal_p (operands[1], operands[2]))
4648 if (which_alternative == 1)
4649 return "or\t%L1, %H1, %H1\n\tmulx\t%H1, %H1, %L0\;srlx\t%L0, 32, %H0";
4651 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";
4653 if (sparc_check_64 (operands[2], insn) <= 0)
4654 output_asm_insn ("srl\t%L2, 0, %L2", operands);
4655 if (which_alternative == 1)
4656 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";
4658 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";
4660 [(set_attr "type" "multi")
4661 (set_attr "length" "9,8")])
4663 (define_insn "*cmp_mul_set"
4665 (compare:CC (mult:SI (match_operand:SI 1 "arith_operand" "%r")
4666 (match_operand:SI 2 "arith_operand" "rI"))
4668 (set (match_operand:SI 0 "register_operand" "=r")
4669 (mult:SI (match_dup 1) (match_dup 2)))]
4670 "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS"
4671 "smulcc\t%1, %2, %0"
4672 [(set_attr "type" "imul")])
4674 (define_expand "mulsidi3"
4675 [(set (match_operand:DI 0 "register_operand" "")
4676 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
4677 (sign_extend:DI (match_operand:SI 2 "arith_operand" ""))))]
4680 if (CONSTANT_P (operands[2]))
4683 emit_insn (gen_const_mulsidi3_v8plus (operands[0], operands[1],
4685 else if (TARGET_ARCH32)
4686 emit_insn (gen_const_mulsidi3_sp32 (operands[0], operands[1],
4689 emit_insn (gen_const_mulsidi3_sp64 (operands[0], operands[1],
4695 emit_insn (gen_mulsidi3_v8plus (operands[0], operands[1], operands[2]));
4700 ;; V9 puts the 64 bit product in a 64 bit register. Only out or global
4701 ;; registers can hold 64 bit values in the V8plus environment.
4703 (define_insn "mulsidi3_v8plus"
4704 [(set (match_operand:DI 0 "register_operand" "=h,r")
4705 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4706 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
4707 (clobber (match_scratch:SI 3 "=X,&h"))]
4710 smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
4711 smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4712 [(set_attr "type" "multi")
4713 (set_attr "length" "2,3")])
4716 (define_insn "const_mulsidi3_v8plus"
4717 [(set (match_operand:DI 0 "register_operand" "=h,r")
4718 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4719 (match_operand:DI 2 "small_int_operand" "I,I")))
4720 (clobber (match_scratch:SI 3 "=X,&h"))]
4723 smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
4724 smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4725 [(set_attr "type" "multi")
4726 (set_attr "length" "2,3")])
4729 (define_insn "*mulsidi3_sp32"
4730 [(set (match_operand:DI 0 "register_operand" "=r")
4731 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4732 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4735 return TARGET_SPARCLET
4736 ? "smuld\t%1, %2, %L0"
4737 : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
4740 (if_then_else (eq_attr "isa" "sparclet")
4741 (const_string "imul") (const_string "multi")))
4742 (set (attr "length")
4743 (if_then_else (eq_attr "isa" "sparclet")
4744 (const_int 1) (const_int 2)))])
4746 (define_insn "*mulsidi3_sp64"
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"))))]
4750 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4752 [(set_attr "type" "imul")])
4754 ;; Extra pattern, because sign_extend of a constant isn't valid.
4757 (define_insn "const_mulsidi3_sp32"
4758 [(set (match_operand:DI 0 "register_operand" "=r")
4759 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4760 (match_operand:DI 2 "small_int_operand" "I")))]
4763 return TARGET_SPARCLET
4764 ? "smuld\t%1, %2, %L0"
4765 : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
4768 (if_then_else (eq_attr "isa" "sparclet")
4769 (const_string "imul") (const_string "multi")))
4770 (set (attr "length")
4771 (if_then_else (eq_attr "isa" "sparclet")
4772 (const_int 1) (const_int 2)))])
4774 (define_insn "const_mulsidi3_sp64"
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")))]
4778 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4780 [(set_attr "type" "imul")])
4782 (define_expand "smulsi3_highpart"
4783 [(set (match_operand:SI 0 "register_operand" "")
4785 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
4786 (sign_extend:DI (match_operand:SI 2 "arith_operand" "")))
4788 "TARGET_HARD_MUL && TARGET_ARCH32"
4790 if (CONSTANT_P (operands[2]))
4794 emit_insn (gen_const_smulsi3_highpart_v8plus (operands[0],
4800 emit_insn (gen_const_smulsi3_highpart (operands[0], operands[1], operands[2]));
4805 emit_insn (gen_smulsi3_highpart_v8plus (operands[0], operands[1],
4806 operands[2], GEN_INT (32)));
4812 (define_insn "smulsi3_highpart_v8plus"
4813 [(set (match_operand:SI 0 "register_operand" "=h,r")
4815 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4816 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
4817 (match_operand:SI 3 "small_int_operand" "I,I"))))
4818 (clobber (match_scratch:SI 4 "=X,&h"))]
4821 smul\t%1, %2, %0\;srlx\t%0, %3, %0
4822 smul\t%1, %2, %4\;srlx\t%4, %3, %0"
4823 [(set_attr "type" "multi")
4824 (set_attr "length" "2")])
4826 ;; The combiner changes TRUNCATE in the previous pattern to SUBREG.
4829 [(set (match_operand:SI 0 "register_operand" "=h,r")
4832 (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"))
4836 (clobber (match_scratch:SI 4 "=X,&h"))]
4839 smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
4840 smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
4841 [(set_attr "type" "multi")
4842 (set_attr "length" "2")])
4845 (define_insn "const_smulsi3_highpart_v8plus"
4846 [(set (match_operand:SI 0 "register_operand" "=h,r")
4848 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4849 (match_operand:DI 2 "small_int_operand" "I,I"))
4850 (match_operand:SI 3 "small_int_operand" "I,I"))))
4851 (clobber (match_scratch:SI 4 "=X,&h"))]
4854 smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
4855 smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
4856 [(set_attr "type" "multi")
4857 (set_attr "length" "2")])
4860 (define_insn "*smulsi3_highpart_sp32"
4861 [(set (match_operand:SI 0 "register_operand" "=r")
4863 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4864 (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
4867 "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
4868 [(set_attr "type" "multi")
4869 (set_attr "length" "2")])
4872 (define_insn "const_smulsi3_highpart"
4873 [(set (match_operand:SI 0 "register_operand" "=r")
4875 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4876 (match_operand:DI 2 "small_int_operand" "i"))
4879 "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
4880 [(set_attr "type" "multi")
4881 (set_attr "length" "2")])
4883 (define_expand "umulsidi3"
4884 [(set (match_operand:DI 0 "register_operand" "")
4885 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
4886 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" ""))))]
4889 if (CONSTANT_P (operands[2]))
4892 emit_insn (gen_const_umulsidi3_v8plus (operands[0], operands[1],
4894 else if (TARGET_ARCH32)
4895 emit_insn (gen_const_umulsidi3_sp32 (operands[0], operands[1],
4898 emit_insn (gen_const_umulsidi3_sp64 (operands[0], operands[1],
4904 emit_insn (gen_umulsidi3_v8plus (operands[0], operands[1], operands[2]));
4910 (define_insn "umulsidi3_v8plus"
4911 [(set (match_operand:DI 0 "register_operand" "=h,r")
4912 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4913 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
4914 (clobber (match_scratch:SI 3 "=X,&h"))]
4917 umul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
4918 umul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4919 [(set_attr "type" "multi")
4920 (set_attr "length" "2,3")])
4923 (define_insn "*umulsidi3_sp32"
4924 [(set (match_operand:DI 0 "register_operand" "=r")
4925 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4926 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4929 return TARGET_SPARCLET
4930 ? "umuld\t%1, %2, %L0"
4931 : "umul\t%1, %2, %L0\n\trd\t%%y, %H0";
4934 (if_then_else (eq_attr "isa" "sparclet")
4935 (const_string "imul") (const_string "multi")))
4936 (set (attr "length")
4937 (if_then_else (eq_attr "isa" "sparclet")
4938 (const_int 1) (const_int 2)))])
4940 (define_insn "*umulsidi3_sp64"
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"))))]
4944 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4946 [(set_attr "type" "imul")])
4948 ;; Extra pattern, because sign_extend of a constant isn't valid.
4951 (define_insn "const_umulsidi3_sp32"
4952 [(set (match_operand:DI 0 "register_operand" "=r")
4953 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4954 (match_operand:DI 2 "uns_small_int_operand" "")))]
4957 return TARGET_SPARCLET
4958 ? "umuld\t%1, %s2, %L0"
4959 : "umul\t%1, %s2, %L0\n\trd\t%%y, %H0";
4962 (if_then_else (eq_attr "isa" "sparclet")
4963 (const_string "imul") (const_string "multi")))
4964 (set (attr "length")
4965 (if_then_else (eq_attr "isa" "sparclet")
4966 (const_int 1) (const_int 2)))])
4968 (define_insn "const_umulsidi3_sp64"
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" "")))]
4972 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4974 [(set_attr "type" "imul")])
4977 (define_insn "const_umulsidi3_v8plus"
4978 [(set (match_operand:DI 0 "register_operand" "=h,r")
4979 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4980 (match_operand:DI 2 "uns_small_int_operand" "")))
4981 (clobber (match_scratch:SI 3 "=X,h"))]
4984 umul\t%1, %s2, %L0\n\tsrlx\t%L0, 32, %H0
4985 umul\t%1, %s2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4986 [(set_attr "type" "multi")
4987 (set_attr "length" "2,3")])
4989 (define_expand "umulsi3_highpart"
4990 [(set (match_operand:SI 0 "register_operand" "")
4992 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
4993 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" "")))
4995 "TARGET_HARD_MUL && TARGET_ARCH32"
4997 if (CONSTANT_P (operands[2]))
5001 emit_insn (gen_const_umulsi3_highpart_v8plus (operands[0],
5007 emit_insn (gen_const_umulsi3_highpart (operands[0], operands[1], operands[2]));
5012 emit_insn (gen_umulsi3_highpart_v8plus (operands[0], operands[1],
5013 operands[2], GEN_INT (32)));
5019 (define_insn "umulsi3_highpart_v8plus"
5020 [(set (match_operand:SI 0 "register_operand" "=h,r")
5022 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5023 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
5024 (match_operand:SI 3 "small_int_operand" "I,I"))))
5025 (clobber (match_scratch:SI 4 "=X,h"))]
5028 umul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
5029 umul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
5030 [(set_attr "type" "multi")
5031 (set_attr "length" "2")])
5034 (define_insn "const_umulsi3_highpart_v8plus"
5035 [(set (match_operand:SI 0 "register_operand" "=h,r")
5037 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5038 (match_operand:DI 2 "uns_small_int_operand" ""))
5039 (match_operand:SI 3 "small_int_operand" "I,I"))))
5040 (clobber (match_scratch:SI 4 "=X,h"))]
5043 umul\t%1, %s2, %0\n\tsrlx\t%0, %3, %0
5044 umul\t%1, %s2, %4\n\tsrlx\t%4, %3, %0"
5045 [(set_attr "type" "multi")
5046 (set_attr "length" "2")])
5049 (define_insn "*umulsi3_highpart_sp32"
5050 [(set (match_operand:SI 0 "register_operand" "=r")
5052 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5053 (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
5056 "umul\t%1, %2, %%g0\n\trd\t%%y, %0"
5057 [(set_attr "type" "multi")
5058 (set_attr "length" "2")])
5061 (define_insn "const_umulsi3_highpart"
5062 [(set (match_operand:SI 0 "register_operand" "=r")
5064 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5065 (match_operand:DI 2 "uns_small_int_operand" ""))
5068 "umul\t%1, %s2, %%g0\n\trd\t%%y, %0"
5069 [(set_attr "type" "multi")
5070 (set_attr "length" "2")])
5072 ;; The V8 architecture specifies that there must be 3 instructions between
5073 ;; a Y register write and a use of it for correct results.
5075 (define_expand "divsi3"
5076 [(parallel [(set (match_operand:SI 0 "register_operand" "=r,r")
5077 (div:SI (match_operand:SI 1 "register_operand" "r,r")
5078 (match_operand:SI 2 "input_operand" "rI,m")))
5079 (clobber (match_scratch:SI 3 "=&r,&r"))])]
5080 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
5084 operands[3] = gen_reg_rtx(SImode);
5085 emit_insn (gen_ashrsi3 (operands[3], operands[1], GEN_INT (31)));
5086 emit_insn (gen_divsi3_sp64 (operands[0], operands[1], operands[2],
5092 (define_insn "divsi3_sp32"
5093 [(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)
5100 if (which_alternative == 0)
5102 return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tsdiv\t%1, %2, %0";
5104 return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tnop\n\tnop\n\tnop\n\tsdiv\t%1, %2, %0";
5107 return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tld\t%2, %3\n\tsdiv\t%1, %3, %0";
5109 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";
5111 [(set_attr "type" "multi")
5112 (set (attr "length")
5113 (if_then_else (eq_attr "isa" "v9")
5114 (const_int 4) (const_int 6)))])
5116 (define_insn "divsi3_sp64"
5117 [(set (match_operand:SI 0 "register_operand" "=r")
5118 (div:SI (match_operand:SI 1 "register_operand" "r")
5119 (match_operand:SI 2 "input_operand" "rI")))
5120 (use (match_operand:SI 3 "register_operand" "r"))]
5121 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5122 "wr\t%%g0, %3, %%y\n\tsdiv\t%1, %2, %0"
5123 [(set_attr "type" "multi")
5124 (set_attr "length" "2")])
5126 (define_insn "divdi3"
5127 [(set (match_operand:DI 0 "register_operand" "=r")
5128 (div:DI (match_operand:DI 1 "register_operand" "r")
5129 (match_operand:DI 2 "arith_operand" "rI")))]
5132 [(set_attr "type" "idiv")])
5134 (define_insn "*cmp_sdiv_cc_set"
5136 (compare:CC (div:SI (match_operand:SI 1 "register_operand" "r")
5137 (match_operand:SI 2 "arith_operand" "rI"))
5139 (set (match_operand:SI 0 "register_operand" "=r")
5140 (div:SI (match_dup 1) (match_dup 2)))
5141 (clobber (match_scratch:SI 3 "=&r"))]
5142 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
5145 return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tsdivcc\t%1, %2, %0";
5147 return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tnop\n\tnop\n\tnop\n\tsdivcc\t%1, %2, %0";
5149 [(set_attr "type" "multi")
5150 (set (attr "length")
5151 (if_then_else (eq_attr "isa" "v9")
5152 (const_int 3) (const_int 6)))])
5155 (define_expand "udivsi3"
5156 [(set (match_operand:SI 0 "register_operand" "")
5157 (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "")
5158 (match_operand:SI 2 "input_operand" "")))]
5159 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
5162 ;; The V8 architecture specifies that there must be 3 instructions between
5163 ;; a Y register write and a use of it for correct results.
5165 (define_insn "udivsi3_sp32"
5166 [(set (match_operand:SI 0 "register_operand" "=r,&r,&r")
5167 (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "r,r,m")
5168 (match_operand:SI 2 "input_operand" "rI,m,r")))]
5169 "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS)
5172 output_asm_insn ("wr\t%%g0, %%g0, %%y", operands);
5173 switch (which_alternative)
5176 return "nop\n\tnop\n\tnop\n\tudiv\t%1, %2, %0";
5178 return "ld\t%2, %0\n\tnop\n\tnop\n\tudiv\t%1, %0, %0";
5180 return "ld\t%1, %0\n\tnop\n\tnop\n\tudiv\t%0, %2, %0";
5183 [(set_attr "type" "multi")
5184 (set_attr "length" "5")])
5186 (define_insn "udivsi3_sp64"
5187 [(set (match_operand:SI 0 "register_operand" "=r")
5188 (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "r")
5189 (match_operand:SI 2 "input_operand" "rI")))]
5190 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5191 "wr\t%%g0, 0, %%y\n\tudiv\t%1, %2, %0"
5192 [(set_attr "type" "multi")
5193 (set_attr "length" "2")])
5195 (define_insn "udivdi3"
5196 [(set (match_operand:DI 0 "register_operand" "=r")
5197 (udiv:DI (match_operand:DI 1 "register_operand" "r")
5198 (match_operand:DI 2 "arith_operand" "rI")))]
5201 [(set_attr "type" "idiv")])
5203 (define_insn "*cmp_udiv_cc_set"
5205 (compare:CC (udiv:SI (match_operand:SI 1 "register_operand" "r")
5206 (match_operand:SI 2 "arith_operand" "rI"))
5208 (set (match_operand:SI 0 "register_operand" "=r")
5209 (udiv:SI (match_dup 1) (match_dup 2)))]
5211 || TARGET_DEPRECATED_V8_INSNS"
5214 return "wr\t%%g0, %%g0, %%y\n\tudivcc\t%1, %2, %0";
5216 return "wr\t%%g0, %%g0, %%y\n\tnop\n\tnop\n\tnop\n\tudivcc\t%1, %2, %0";
5218 [(set_attr "type" "multi")
5219 (set (attr "length")
5220 (if_then_else (eq_attr "isa" "v9")
5221 (const_int 2) (const_int 5)))])
5223 ; sparclet multiply/accumulate insns
5225 (define_insn "*smacsi"
5226 [(set (match_operand:SI 0 "register_operand" "=r")
5227 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "%r")
5228 (match_operand:SI 2 "arith_operand" "rI"))
5229 (match_operand:SI 3 "register_operand" "0")))]
5232 [(set_attr "type" "imul")])
5234 (define_insn "*smacdi"
5235 [(set (match_operand:DI 0 "register_operand" "=r")
5236 (plus:DI (mult:DI (sign_extend:DI
5237 (match_operand:SI 1 "register_operand" "%r"))
5239 (match_operand:SI 2 "register_operand" "r")))
5240 (match_operand:DI 3 "register_operand" "0")))]
5242 "smacd\t%1, %2, %L0"
5243 [(set_attr "type" "imul")])
5245 (define_insn "*umacdi"
5246 [(set (match_operand:DI 0 "register_operand" "=r")
5247 (plus:DI (mult:DI (zero_extend:DI
5248 (match_operand:SI 1 "register_operand" "%r"))
5250 (match_operand:SI 2 "register_operand" "r")))
5251 (match_operand:DI 3 "register_operand" "0")))]
5253 "umacd\t%1, %2, %L0"
5254 [(set_attr "type" "imul")])
5257 ;; Boolean instructions.
5259 ;; We define DImode `and' so with DImode `not' we can get
5260 ;; DImode `andn'. Other combinations are possible.
5262 (define_mode_macro V64I [DI V2SI V4HI V8QI])
5263 (define_mode_macro V32I [SI V2HI V4QI])
5265 (define_expand "and<V64I:mode>3"
5266 [(set (match_operand:V64I 0 "register_operand" "")
5267 (and:V64I (match_operand:V64I 1 "arith_double_operand" "")
5268 (match_operand:V64I 2 "arith_double_operand" "")))]
5272 (define_insn "*and<V64I:mode>3_sp32"
5273 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5274 (and:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
5275 (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
5280 [(set_attr "type" "*,fga")
5281 (set_attr "length" "2,*")
5282 (set_attr "fptype" "*,double")])
5284 (define_insn "*and<V64I:mode>3_sp64"
5285 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5286 (and:V64I (match_operand:V64I 1 "arith_operand" "%r,b")
5287 (match_operand:V64I 2 "arith_operand" "rI,b")))]
5292 [(set_attr "type" "*,fga")
5293 (set_attr "fptype" "*,double")])
5295 (define_insn "and<V32I:mode>3"
5296 [(set (match_operand:V32I 0 "register_operand" "=r,d")
5297 (and:V32I (match_operand:V32I 1 "arith_operand" "%r,d")
5298 (match_operand:V32I 2 "arith_operand" "rI,d")))]
5303 [(set_attr "type" "*,fga")
5304 (set_attr "fptype" "*,single")])
5307 [(set (match_operand:SI 0 "register_operand" "")
5308 (and:SI (match_operand:SI 1 "register_operand" "")
5309 (match_operand:SI 2 "const_compl_high_operand" "")))
5310 (clobber (match_operand:SI 3 "register_operand" ""))]
5312 [(set (match_dup 3) (match_dup 4))
5313 (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 1)))]
5315 operands[4] = GEN_INT (~INTVAL (operands[2]));
5318 (define_insn_and_split "*and_not_<V64I:mode>_sp32"
5319 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5320 (and:V64I (not:V64I (match_operand:V64I 1 "register_operand" "%r,b"))
5321 (match_operand:V64I 2 "register_operand" "r,b")))]
5325 fandnot1\t%1, %2, %0"
5326 "&& reload_completed
5327 && ((GET_CODE (operands[0]) == REG
5328 && REGNO (operands[0]) < 32)
5329 || (GET_CODE (operands[0]) == SUBREG
5330 && GET_CODE (SUBREG_REG (operands[0])) == REG
5331 && REGNO (SUBREG_REG (operands[0])) < 32))"
5332 [(set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))
5333 (set (match_dup 6) (and:SI (not:SI (match_dup 7)) (match_dup 8)))]
5334 "operands[3] = gen_highpart (SImode, operands[0]);
5335 operands[4] = gen_highpart (SImode, operands[1]);
5336 operands[5] = gen_highpart (SImode, operands[2]);
5337 operands[6] = gen_lowpart (SImode, operands[0]);
5338 operands[7] = gen_lowpart (SImode, operands[1]);
5339 operands[8] = gen_lowpart (SImode, operands[2]);"
5340 [(set_attr "type" "*,fga")
5341 (set_attr "length" "2,*")
5342 (set_attr "fptype" "*,double")])
5344 (define_insn "*and_not_<V64I:mode>_sp64"
5345 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5346 (and:V64I (not:V64I (match_operand:V64I 1 "register_operand" "%r,b"))
5347 (match_operand:V64I 2 "register_operand" "r,b")))]
5351 fandnot1\t%1, %2, %0"
5352 [(set_attr "type" "*,fga")
5353 (set_attr "fptype" "*,double")])
5355 (define_insn "*and_not_<V32I:mode>"
5356 [(set (match_operand:V32I 0 "register_operand" "=r,d")
5357 (and:V32I (not:V32I (match_operand:V32I 1 "register_operand" "%r,d"))
5358 (match_operand:V32I 2 "register_operand" "r,d")))]
5362 fandnot1s\t%1, %2, %0"
5363 [(set_attr "type" "*,fga")
5364 (set_attr "fptype" "*,single")])
5366 (define_expand "ior<V64I:mode>3"
5367 [(set (match_operand:V64I 0 "register_operand" "")
5368 (ior:V64I (match_operand:V64I 1 "arith_double_operand" "")
5369 (match_operand:V64I 2 "arith_double_operand" "")))]
5373 (define_insn "*ior<V64I:mode>3_sp32"
5374 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5375 (ior:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
5376 (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
5381 [(set_attr "type" "*,fga")
5382 (set_attr "length" "2,*")
5383 (set_attr "fptype" "*,double")])
5385 (define_insn "*ior<V64I:mode>3_sp64"
5386 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5387 (ior:V64I (match_operand:V64I 1 "arith_operand" "%r,b")
5388 (match_operand:V64I 2 "arith_operand" "rI,b")))]
5393 [(set_attr "type" "*,fga")
5394 (set_attr "fptype" "*,double")])
5396 (define_insn "ior<V32I:mode>3"
5397 [(set (match_operand:V32I 0 "register_operand" "=r,d")
5398 (ior:V32I (match_operand:V32I 1 "arith_operand" "%r,d")
5399 (match_operand:V32I 2 "arith_operand" "rI,d")))]
5404 [(set_attr "type" "*,fga")
5405 (set_attr "fptype" "*,single")])
5408 [(set (match_operand:SI 0 "register_operand" "")
5409 (ior:SI (match_operand:SI 1 "register_operand" "")
5410 (match_operand:SI 2 "const_compl_high_operand" "")))
5411 (clobber (match_operand:SI 3 "register_operand" ""))]
5413 [(set (match_dup 3) (match_dup 4))
5414 (set (match_dup 0) (ior:SI (not:SI (match_dup 3)) (match_dup 1)))]
5416 operands[4] = GEN_INT (~INTVAL (operands[2]));
5419 (define_insn_and_split "*or_not_<V64I:mode>_sp32"
5420 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5421 (ior:V64I (not:V64I (match_operand:V64I 1 "register_operand" "r,b"))
5422 (match_operand:V64I 2 "register_operand" "r,b")))]
5426 fornot1\t%1, %2, %0"
5427 "&& reload_completed
5428 && ((GET_CODE (operands[0]) == REG
5429 && REGNO (operands[0]) < 32)
5430 || (GET_CODE (operands[0]) == SUBREG
5431 && GET_CODE (SUBREG_REG (operands[0])) == REG
5432 && REGNO (SUBREG_REG (operands[0])) < 32))"
5433 [(set (match_dup 3) (ior:SI (not:SI (match_dup 4)) (match_dup 5)))
5434 (set (match_dup 6) (ior:SI (not:SI (match_dup 7)) (match_dup 8)))]
5435 "operands[3] = gen_highpart (SImode, operands[0]);
5436 operands[4] = gen_highpart (SImode, operands[1]);
5437 operands[5] = gen_highpart (SImode, operands[2]);
5438 operands[6] = gen_lowpart (SImode, operands[0]);
5439 operands[7] = gen_lowpart (SImode, operands[1]);
5440 operands[8] = gen_lowpart (SImode, operands[2]);"
5441 [(set_attr "type" "*,fga")
5442 (set_attr "length" "2,*")
5443 (set_attr "fptype" "*,double")])
5445 (define_insn "*or_not_<V64I:mode>_sp64"
5446 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5447 (ior:V64I (not:V64I (match_operand:V64I 1 "register_operand" "r,b"))
5448 (match_operand:V64I 2 "register_operand" "r,b")))]
5452 fornot1\t%1, %2, %0"
5453 [(set_attr "type" "*,fga")
5454 (set_attr "fptype" "*,double")])
5456 (define_insn "*or_not_<V32I:mode>"
5457 [(set (match_operand:V32I 0 "register_operand" "=r,d")
5458 (ior:V32I (not:V32I (match_operand:V32I 1 "register_operand" "r,d"))
5459 (match_operand:V32I 2 "register_operand" "r,d")))]
5463 fornot1s\t%1, %2, %0"
5464 [(set_attr "type" "*,fga")
5465 (set_attr "fptype" "*,single")])
5467 (define_expand "xor<V64I:mode>3"
5468 [(set (match_operand:V64I 0 "register_operand" "")
5469 (xor:V64I (match_operand:V64I 1 "arith_double_operand" "")
5470 (match_operand:V64I 2 "arith_double_operand" "")))]
5474 (define_insn "*xor<V64I:mode>3_sp32"
5475 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5476 (xor:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
5477 (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
5482 [(set_attr "type" "*,fga")
5483 (set_attr "length" "2,*")
5484 (set_attr "fptype" "*,double")])
5486 (define_insn "*xor<V64I:mode>3_sp64"
5487 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5488 (xor:V64I (match_operand:V64I 1 "arith_operand" "%rJ,b")
5489 (match_operand:V64I 2 "arith_operand" "rI,b")))]
5494 [(set_attr "type" "*,fga")
5495 (set_attr "fptype" "*,double")])
5497 (define_insn "xor<V32I:mode>3"
5498 [(set (match_operand:V32I 0 "register_operand" "=r,d")
5499 (xor:V32I (match_operand:V32I 1 "arith_operand" "%rJ,d")
5500 (match_operand:V32I 2 "arith_operand" "rI,d")))]
5505 [(set_attr "type" "*,fga")
5506 (set_attr "fptype" "*,single")])
5509 [(set (match_operand:SI 0 "register_operand" "")
5510 (xor:SI (match_operand:SI 1 "register_operand" "")
5511 (match_operand:SI 2 "const_compl_high_operand" "")))
5512 (clobber (match_operand:SI 3 "register_operand" ""))]
5514 [(set (match_dup 3) (match_dup 4))
5515 (set (match_dup 0) (not:SI (xor:SI (match_dup 3) (match_dup 1))))]
5517 operands[4] = GEN_INT (~INTVAL (operands[2]));
5521 [(set (match_operand:SI 0 "register_operand" "")
5522 (not:SI (xor:SI (match_operand:SI 1 "register_operand" "")
5523 (match_operand:SI 2 "const_compl_high_operand" ""))))
5524 (clobber (match_operand:SI 3 "register_operand" ""))]
5526 [(set (match_dup 3) (match_dup 4))
5527 (set (match_dup 0) (xor:SI (match_dup 3) (match_dup 1)))]
5529 operands[4] = GEN_INT (~INTVAL (operands[2]));
5532 ;; Split DImode logical operations requiring two instructions.
5534 [(set (match_operand:V64I 0 "register_operand" "")
5535 (match_operator:V64I 1 "cc_arith_operator" ; AND, IOR, XOR
5536 [(match_operand:V64I 2 "register_operand" "")
5537 (match_operand:V64I 3 "arith_double_operand" "")]))]
5540 && ((GET_CODE (operands[0]) == REG
5541 && REGNO (operands[0]) < 32)
5542 || (GET_CODE (operands[0]) == SUBREG
5543 && GET_CODE (SUBREG_REG (operands[0])) == REG
5544 && REGNO (SUBREG_REG (operands[0])) < 32))"
5545 [(set (match_dup 4) (match_op_dup:SI 1 [(match_dup 6) (match_dup 8)]))
5546 (set (match_dup 5) (match_op_dup:SI 1 [(match_dup 7) (match_dup 9)]))]
5548 operands[4] = gen_highpart (SImode, operands[0]);
5549 operands[5] = gen_lowpart (SImode, operands[0]);
5550 operands[6] = gen_highpart (SImode, operands[2]);
5551 operands[7] = gen_lowpart (SImode, operands[2]);
5552 #if HOST_BITS_PER_WIDE_INT == 32
5553 if (GET_CODE (operands[3]) == CONST_INT && <V64I:MODE>mode == DImode)
5555 if (INTVAL (operands[3]) < 0)
5556 operands[8] = constm1_rtx;
5558 operands[8] = const0_rtx;
5562 operands[8] = gen_highpart_mode (SImode, <V64I:MODE>mode, operands[3]);
5563 operands[9] = gen_lowpart (SImode, operands[3]);
5566 ;; xnor patterns. Note that (a ^ ~b) == (~a ^ b) == ~(a ^ b).
5567 ;; Combine now canonicalizes to the rightmost expression.
5568 (define_insn_and_split "*xor_not_<V64I:mode>_sp32"
5569 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5570 (not:V64I (xor:V64I (match_operand:V64I 1 "register_operand" "r,b")
5571 (match_operand:V64I 2 "register_operand" "r,b"))))]
5576 "&& reload_completed
5577 && ((GET_CODE (operands[0]) == REG
5578 && REGNO (operands[0]) < 32)
5579 || (GET_CODE (operands[0]) == SUBREG
5580 && GET_CODE (SUBREG_REG (operands[0])) == REG
5581 && REGNO (SUBREG_REG (operands[0])) < 32))"
5582 [(set (match_dup 3) (not:SI (xor:SI (match_dup 4) (match_dup 5))))
5583 (set (match_dup 6) (not:SI (xor:SI (match_dup 7) (match_dup 8))))]
5584 "operands[3] = gen_highpart (SImode, operands[0]);
5585 operands[4] = gen_highpart (SImode, operands[1]);
5586 operands[5] = gen_highpart (SImode, operands[2]);
5587 operands[6] = gen_lowpart (SImode, operands[0]);
5588 operands[7] = gen_lowpart (SImode, operands[1]);
5589 operands[8] = gen_lowpart (SImode, operands[2]);"
5590 [(set_attr "type" "*,fga")
5591 (set_attr "length" "2,*")
5592 (set_attr "fptype" "*,double")])
5594 (define_insn "*xor_not_<V64I:mode>_sp64"
5595 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5596 (not:V64I (xor:V64I (match_operand:V64I 1 "register_or_zero_operand" "rJ,b")
5597 (match_operand:V64I 2 "arith_operand" "rI,b"))))]
5602 [(set_attr "type" "*,fga")
5603 (set_attr "fptype" "*,double")])
5605 (define_insn "*xor_not_<V32I:mode>"
5606 [(set (match_operand:V32I 0 "register_operand" "=r,d")
5607 (not:V32I (xor:V32I (match_operand:V32I 1 "register_or_zero_operand" "rJ,d")
5608 (match_operand:V32I 2 "arith_operand" "rI,d"))))]
5613 [(set_attr "type" "*,fga")
5614 (set_attr "fptype" "*,single")])
5616 ;; These correspond to the above in the case where we also (or only)
5617 ;; want to set the condition code.
5619 (define_insn "*cmp_cc_arith_op"
5622 (match_operator:SI 2 "cc_arith_operator"
5623 [(match_operand:SI 0 "arith_operand" "%r")
5624 (match_operand:SI 1 "arith_operand" "rI")])
5627 "%A2cc\t%0, %1, %%g0"
5628 [(set_attr "type" "compare")])
5630 (define_insn "*cmp_ccx_arith_op"
5633 (match_operator:DI 2 "cc_arith_operator"
5634 [(match_operand:DI 0 "arith_operand" "%r")
5635 (match_operand:DI 1 "arith_operand" "rI")])
5638 "%A2cc\t%0, %1, %%g0"
5639 [(set_attr "type" "compare")])
5641 (define_insn "*cmp_cc_arith_op_set"
5644 (match_operator:SI 3 "cc_arith_operator"
5645 [(match_operand:SI 1 "arith_operand" "%r")
5646 (match_operand:SI 2 "arith_operand" "rI")])
5648 (set (match_operand:SI 0 "register_operand" "=r")
5649 (match_operator:SI 4 "cc_arith_operator" [(match_dup 1) (match_dup 2)]))]
5650 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
5652 [(set_attr "type" "compare")])
5654 (define_insn "*cmp_ccx_arith_op_set"
5657 (match_operator:DI 3 "cc_arith_operator"
5658 [(match_operand:DI 1 "arith_operand" "%r")
5659 (match_operand:DI 2 "arith_operand" "rI")])
5661 (set (match_operand:DI 0 "register_operand" "=r")
5662 (match_operator:DI 4 "cc_arith_operator" [(match_dup 1) (match_dup 2)]))]
5663 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
5665 [(set_attr "type" "compare")])
5667 (define_insn "*cmp_cc_xor_not"
5670 (not:SI (xor:SI (match_operand:SI 0 "register_or_zero_operand" "%rJ")
5671 (match_operand:SI 1 "arith_operand" "rI")))
5674 "xnorcc\t%r0, %1, %%g0"
5675 [(set_attr "type" "compare")])
5677 (define_insn "*cmp_ccx_xor_not"
5680 (not:DI (xor:DI (match_operand:DI 0 "register_or_zero_operand" "%rJ")
5681 (match_operand:DI 1 "arith_operand" "rI")))
5684 "xnorcc\t%r0, %1, %%g0"
5685 [(set_attr "type" "compare")])
5687 (define_insn "*cmp_cc_xor_not_set"
5690 (not:SI (xor:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ")
5691 (match_operand:SI 2 "arith_operand" "rI")))
5693 (set (match_operand:SI 0 "register_operand" "=r")
5694 (not:SI (xor:SI (match_dup 1) (match_dup 2))))]
5696 "xnorcc\t%r1, %2, %0"
5697 [(set_attr "type" "compare")])
5699 (define_insn "*cmp_ccx_xor_not_set"
5702 (not:DI (xor:DI (match_operand:DI 1 "register_or_zero_operand" "%rJ")
5703 (match_operand:DI 2 "arith_operand" "rI")))
5705 (set (match_operand:DI 0 "register_operand" "=r")
5706 (not:DI (xor:DI (match_dup 1) (match_dup 2))))]
5708 "xnorcc\t%r1, %2, %0"
5709 [(set_attr "type" "compare")])
5711 (define_insn "*cmp_cc_arith_op_not"
5714 (match_operator:SI 2 "cc_arith_not_operator"
5715 [(not:SI (match_operand:SI 0 "arith_operand" "rI"))
5716 (match_operand:SI 1 "register_or_zero_operand" "rJ")])
5719 "%B2cc\t%r1, %0, %%g0"
5720 [(set_attr "type" "compare")])
5722 (define_insn "*cmp_ccx_arith_op_not"
5725 (match_operator:DI 2 "cc_arith_not_operator"
5726 [(not:DI (match_operand:DI 0 "arith_operand" "rI"))
5727 (match_operand:DI 1 "register_or_zero_operand" "rJ")])
5730 "%B2cc\t%r1, %0, %%g0"
5731 [(set_attr "type" "compare")])
5733 (define_insn "*cmp_cc_arith_op_not_set"
5736 (match_operator:SI 3 "cc_arith_not_operator"
5737 [(not:SI (match_operand:SI 1 "arith_operand" "rI"))
5738 (match_operand:SI 2 "register_or_zero_operand" "rJ")])
5740 (set (match_operand:SI 0 "register_operand" "=r")
5741 (match_operator:SI 4 "cc_arith_not_operator"
5742 [(not:SI (match_dup 1)) (match_dup 2)]))]
5743 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
5744 "%B3cc\t%r2, %1, %0"
5745 [(set_attr "type" "compare")])
5747 (define_insn "*cmp_ccx_arith_op_not_set"
5750 (match_operator:DI 3 "cc_arith_not_operator"
5751 [(not:DI (match_operand:DI 1 "arith_operand" "rI"))
5752 (match_operand:DI 2 "register_or_zero_operand" "rJ")])
5754 (set (match_operand:DI 0 "register_operand" "=r")
5755 (match_operator:DI 4 "cc_arith_not_operator"
5756 [(not:DI (match_dup 1)) (match_dup 2)]))]
5757 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
5758 "%B3cc\t%r2, %1, %0"
5759 [(set_attr "type" "compare")])
5761 ;; We cannot use the "neg" pseudo insn because the Sun assembler
5762 ;; does not know how to make it work for constants.
5764 (define_expand "negdi2"
5765 [(set (match_operand:DI 0 "register_operand" "=r")
5766 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
5769 if (! TARGET_ARCH64)
5771 emit_insn (gen_rtx_PARALLEL
5774 gen_rtx_SET (VOIDmode, operand0,
5775 gen_rtx_NEG (DImode, operand1)),
5776 gen_rtx_CLOBBER (VOIDmode,
5777 gen_rtx_REG (CCmode,
5783 (define_insn_and_split "*negdi2_sp32"
5784 [(set (match_operand:DI 0 "register_operand" "=r")
5785 (neg:DI (match_operand:DI 1 "register_operand" "r")))
5786 (clobber (reg:CC 100))]
5789 "&& reload_completed"
5790 [(parallel [(set (reg:CC_NOOV 100)
5791 (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 5))
5793 (set (match_dup 4) (minus:SI (const_int 0) (match_dup 5)))])
5794 (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
5795 (ltu:SI (reg:CC 100) (const_int 0))))]
5796 "operands[2] = gen_highpart (SImode, operands[0]);
5797 operands[3] = gen_highpart (SImode, operands[1]);
5798 operands[4] = gen_lowpart (SImode, operands[0]);
5799 operands[5] = gen_lowpart (SImode, operands[1]);"
5800 [(set_attr "length" "2")])
5802 (define_insn "*negdi2_sp64"
5803 [(set (match_operand:DI 0 "register_operand" "=r")
5804 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
5806 "sub\t%%g0, %1, %0")
5808 (define_insn "negsi2"
5809 [(set (match_operand:SI 0 "register_operand" "=r")
5810 (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
5812 "sub\t%%g0, %1, %0")
5814 (define_insn "*cmp_cc_neg"
5815 [(set (reg:CC_NOOV 100)
5816 (compare:CC_NOOV (neg:SI (match_operand:SI 0 "arith_operand" "rI"))
5819 "subcc\t%%g0, %0, %%g0"
5820 [(set_attr "type" "compare")])
5822 (define_insn "*cmp_ccx_neg"
5823 [(set (reg:CCX_NOOV 100)
5824 (compare:CCX_NOOV (neg:DI (match_operand:DI 0 "arith_operand" "rI"))
5827 "subcc\t%%g0, %0, %%g0"
5828 [(set_attr "type" "compare")])
5830 (define_insn "*cmp_cc_set_neg"
5831 [(set (reg:CC_NOOV 100)
5832 (compare:CC_NOOV (neg:SI (match_operand:SI 1 "arith_operand" "rI"))
5834 (set (match_operand:SI 0 "register_operand" "=r")
5835 (neg:SI (match_dup 1)))]
5837 "subcc\t%%g0, %1, %0"
5838 [(set_attr "type" "compare")])
5840 (define_insn "*cmp_ccx_set_neg"
5841 [(set (reg:CCX_NOOV 100)
5842 (compare:CCX_NOOV (neg:DI (match_operand:DI 1 "arith_operand" "rI"))
5844 (set (match_operand:DI 0 "register_operand" "=r")
5845 (neg:DI (match_dup 1)))]
5847 "subcc\t%%g0, %1, %0"
5848 [(set_attr "type" "compare")])
5850 ;; We cannot use the "not" pseudo insn because the Sun assembler
5851 ;; does not know how to make it work for constants.
5852 (define_expand "one_cmpl<V64I:mode>2"
5853 [(set (match_operand:V64I 0 "register_operand" "")
5854 (not:V64I (match_operand:V64I 1 "register_operand" "")))]
5858 (define_insn_and_split "*one_cmpl<V64I:mode>2_sp32"
5859 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5860 (not:V64I (match_operand:V64I 1 "register_operand" "r,b")))]
5865 "&& reload_completed
5866 && ((GET_CODE (operands[0]) == REG
5867 && REGNO (operands[0]) < 32)
5868 || (GET_CODE (operands[0]) == SUBREG
5869 && GET_CODE (SUBREG_REG (operands[0])) == REG
5870 && REGNO (SUBREG_REG (operands[0])) < 32))"
5871 [(set (match_dup 2) (not:SI (xor:SI (match_dup 3) (const_int 0))))
5872 (set (match_dup 4) (not:SI (xor:SI (match_dup 5) (const_int 0))))]
5873 "operands[2] = gen_highpart (SImode, operands[0]);
5874 operands[3] = gen_highpart (SImode, operands[1]);
5875 operands[4] = gen_lowpart (SImode, operands[0]);
5876 operands[5] = gen_lowpart (SImode, operands[1]);"
5877 [(set_attr "type" "*,fga")
5878 (set_attr "length" "2,*")
5879 (set_attr "fptype" "*,double")])
5881 (define_insn "*one_cmpl<V64I:mode>2_sp64"
5882 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5883 (not:V64I (match_operand:V64I 1 "arith_operand" "rI,b")))]
5888 [(set_attr "type" "*,fga")
5889 (set_attr "fptype" "*,double")])
5891 (define_insn "one_cmpl<V32I:mode>2"
5892 [(set (match_operand:V32I 0 "register_operand" "=r,d")
5893 (not:V32I (match_operand:V32I 1 "arith_operand" "rI,d")))]
5898 [(set_attr "type" "*,fga")
5899 (set_attr "fptype" "*,single")])
5901 (define_insn "*cmp_cc_not"
5903 (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI"))
5906 "xnorcc\t%%g0, %0, %%g0"
5907 [(set_attr "type" "compare")])
5909 (define_insn "*cmp_ccx_not"
5911 (compare:CCX (not:DI (match_operand:DI 0 "arith_operand" "rI"))
5914 "xnorcc\t%%g0, %0, %%g0"
5915 [(set_attr "type" "compare")])
5917 (define_insn "*cmp_cc_set_not"
5919 (compare:CC (not:SI (match_operand:SI 1 "arith_operand" "rI"))
5921 (set (match_operand:SI 0 "register_operand" "=r")
5922 (not:SI (match_dup 1)))]
5924 "xnorcc\t%%g0, %1, %0"
5925 [(set_attr "type" "compare")])
5927 (define_insn "*cmp_ccx_set_not"
5929 (compare:CCX (not:DI (match_operand:DI 1 "arith_operand" "rI"))
5931 (set (match_operand:DI 0 "register_operand" "=r")
5932 (not:DI (match_dup 1)))]
5934 "xnorcc\t%%g0, %1, %0"
5935 [(set_attr "type" "compare")])
5937 (define_insn "*cmp_cc_set"
5938 [(set (match_operand:SI 0 "register_operand" "=r")
5939 (match_operand:SI 1 "register_operand" "r"))
5941 (compare:CC (match_dup 1)
5945 [(set_attr "type" "compare")])
5947 (define_insn "*cmp_ccx_set64"
5948 [(set (match_operand:DI 0 "register_operand" "=r")
5949 (match_operand:DI 1 "register_operand" "r"))
5951 (compare:CCX (match_dup 1)
5955 [(set_attr "type" "compare")])
5958 ;; Floating point arithmetic instructions.
5960 (define_expand "addtf3"
5961 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5962 (plus:TF (match_operand:TF 1 "general_operand" "")
5963 (match_operand:TF 2 "general_operand" "")))]
5964 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5965 "emit_tfmode_binop (PLUS, operands); DONE;")
5967 (define_insn "*addtf3_hq"
5968 [(set (match_operand:TF 0 "register_operand" "=e")
5969 (plus:TF (match_operand:TF 1 "register_operand" "e")
5970 (match_operand:TF 2 "register_operand" "e")))]
5971 "TARGET_FPU && TARGET_HARD_QUAD"
5973 [(set_attr "type" "fp")])
5975 (define_insn "adddf3"
5976 [(set (match_operand:DF 0 "register_operand" "=e")
5977 (plus:DF (match_operand:DF 1 "register_operand" "e")
5978 (match_operand:DF 2 "register_operand" "e")))]
5981 [(set_attr "type" "fp")
5982 (set_attr "fptype" "double")])
5984 (define_insn "addsf3"
5985 [(set (match_operand:SF 0 "register_operand" "=f")
5986 (plus:SF (match_operand:SF 1 "register_operand" "f")
5987 (match_operand:SF 2 "register_operand" "f")))]
5990 [(set_attr "type" "fp")])
5992 (define_expand "subtf3"
5993 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5994 (minus:TF (match_operand:TF 1 "general_operand" "")
5995 (match_operand:TF 2 "general_operand" "")))]
5996 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5997 "emit_tfmode_binop (MINUS, operands); DONE;")
5999 (define_insn "*subtf3_hq"
6000 [(set (match_operand:TF 0 "register_operand" "=e")
6001 (minus:TF (match_operand:TF 1 "register_operand" "e")
6002 (match_operand:TF 2 "register_operand" "e")))]
6003 "TARGET_FPU && TARGET_HARD_QUAD"
6005 [(set_attr "type" "fp")])
6007 (define_insn "subdf3"
6008 [(set (match_operand:DF 0 "register_operand" "=e")
6009 (minus:DF (match_operand:DF 1 "register_operand" "e")
6010 (match_operand:DF 2 "register_operand" "e")))]
6013 [(set_attr "type" "fp")
6014 (set_attr "fptype" "double")])
6016 (define_insn "subsf3"
6017 [(set (match_operand:SF 0 "register_operand" "=f")
6018 (minus:SF (match_operand:SF 1 "register_operand" "f")
6019 (match_operand:SF 2 "register_operand" "f")))]
6022 [(set_attr "type" "fp")])
6024 (define_expand "multf3"
6025 [(set (match_operand:TF 0 "nonimmediate_operand" "")
6026 (mult:TF (match_operand:TF 1 "general_operand" "")
6027 (match_operand:TF 2 "general_operand" "")))]
6028 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6029 "emit_tfmode_binop (MULT, operands); DONE;")
6031 (define_insn "*multf3_hq"
6032 [(set (match_operand:TF 0 "register_operand" "=e")
6033 (mult:TF (match_operand:TF 1 "register_operand" "e")
6034 (match_operand:TF 2 "register_operand" "e")))]
6035 "TARGET_FPU && TARGET_HARD_QUAD"
6037 [(set_attr "type" "fpmul")])
6039 (define_insn "muldf3"
6040 [(set (match_operand:DF 0 "register_operand" "=e")
6041 (mult:DF (match_operand:DF 1 "register_operand" "e")
6042 (match_operand:DF 2 "register_operand" "e")))]
6045 [(set_attr "type" "fpmul")
6046 (set_attr "fptype" "double")])
6048 (define_insn "mulsf3"
6049 [(set (match_operand:SF 0 "register_operand" "=f")
6050 (mult:SF (match_operand:SF 1 "register_operand" "f")
6051 (match_operand:SF 2 "register_operand" "f")))]
6054 [(set_attr "type" "fpmul")])
6056 (define_insn "*muldf3_extend"
6057 [(set (match_operand:DF 0 "register_operand" "=e")
6058 (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "f"))
6059 (float_extend:DF (match_operand:SF 2 "register_operand" "f"))))]
6060 "(TARGET_V8 || TARGET_V9) && TARGET_FPU"
6061 "fsmuld\t%1, %2, %0"
6062 [(set_attr "type" "fpmul")
6063 (set_attr "fptype" "double")])
6065 (define_insn "*multf3_extend"
6066 [(set (match_operand:TF 0 "register_operand" "=e")
6067 (mult:TF (float_extend:TF (match_operand:DF 1 "register_operand" "e"))
6068 (float_extend:TF (match_operand:DF 2 "register_operand" "e"))))]
6069 "(TARGET_V8 || TARGET_V9) && TARGET_FPU && TARGET_HARD_QUAD"
6070 "fdmulq\t%1, %2, %0"
6071 [(set_attr "type" "fpmul")])
6073 (define_expand "divtf3"
6074 [(set (match_operand:TF 0 "nonimmediate_operand" "")
6075 (div:TF (match_operand:TF 1 "general_operand" "")
6076 (match_operand:TF 2 "general_operand" "")))]
6077 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6078 "emit_tfmode_binop (DIV, operands); DONE;")
6080 ;; don't have timing for quad-prec. divide.
6081 (define_insn "*divtf3_hq"
6082 [(set (match_operand:TF 0 "register_operand" "=e")
6083 (div:TF (match_operand:TF 1 "register_operand" "e")
6084 (match_operand:TF 2 "register_operand" "e")))]
6085 "TARGET_FPU && TARGET_HARD_QUAD"
6087 [(set_attr "type" "fpdivd")])
6089 (define_insn "divdf3"
6090 [(set (match_operand:DF 0 "register_operand" "=e")
6091 (div:DF (match_operand:DF 1 "register_operand" "e")
6092 (match_operand:DF 2 "register_operand" "e")))]
6095 [(set_attr "type" "fpdivd")
6096 (set_attr "fptype" "double")])
6098 (define_insn "divsf3"
6099 [(set (match_operand:SF 0 "register_operand" "=f")
6100 (div:SF (match_operand:SF 1 "register_operand" "f")
6101 (match_operand:SF 2 "register_operand" "f")))]
6104 [(set_attr "type" "fpdivs")])
6106 (define_expand "negtf2"
6107 [(set (match_operand:TF 0 "register_operand" "=e,e")
6108 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
6112 (define_insn_and_split "*negtf2_notv9"
6113 [(set (match_operand:TF 0 "register_operand" "=e,e")
6114 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
6115 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
6121 "&& reload_completed
6122 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6123 [(set (match_dup 2) (neg:SF (match_dup 3)))
6124 (set (match_dup 4) (match_dup 5))
6125 (set (match_dup 6) (match_dup 7))]
6126 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6127 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6128 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6129 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
6130 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6131 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6132 [(set_attr "type" "fpmove,*")
6133 (set_attr "length" "*,2")])
6135 (define_insn_and_split "*negtf2_v9"
6136 [(set (match_operand:TF 0 "register_operand" "=e,e")
6137 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
6138 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
6139 "TARGET_FPU && TARGET_V9"
6143 "&& reload_completed
6144 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6145 [(set (match_dup 2) (neg:DF (match_dup 3)))
6146 (set (match_dup 4) (match_dup 5))]
6147 "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
6148 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
6149 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6150 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6151 [(set_attr "type" "fpmove,*")
6152 (set_attr "length" "*,2")
6153 (set_attr "fptype" "double")])
6155 (define_expand "negdf2"
6156 [(set (match_operand:DF 0 "register_operand" "")
6157 (neg:DF (match_operand:DF 1 "register_operand" "")))]
6161 (define_insn_and_split "*negdf2_notv9"
6162 [(set (match_operand:DF 0 "register_operand" "=e,e")
6163 (neg:DF (match_operand:DF 1 "register_operand" "0,e")))]
6164 "TARGET_FPU && ! TARGET_V9"
6168 "&& reload_completed
6169 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6170 [(set (match_dup 2) (neg:SF (match_dup 3)))
6171 (set (match_dup 4) (match_dup 5))]
6172 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6173 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6174 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6175 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);"
6176 [(set_attr "type" "fpmove,*")
6177 (set_attr "length" "*,2")])
6179 (define_insn "*negdf2_v9"
6180 [(set (match_operand:DF 0 "register_operand" "=e")
6181 (neg:DF (match_operand:DF 1 "register_operand" "e")))]
6182 "TARGET_FPU && TARGET_V9"
6184 [(set_attr "type" "fpmove")
6185 (set_attr "fptype" "double")])
6187 (define_insn "negsf2"
6188 [(set (match_operand:SF 0 "register_operand" "=f")
6189 (neg:SF (match_operand:SF 1 "register_operand" "f")))]
6192 [(set_attr "type" "fpmove")])
6194 (define_expand "abstf2"
6195 [(set (match_operand:TF 0 "register_operand" "")
6196 (abs:TF (match_operand:TF 1 "register_operand" "")))]
6200 (define_insn_and_split "*abstf2_notv9"
6201 [(set (match_operand:TF 0 "register_operand" "=e,e")
6202 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6203 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
6204 "TARGET_FPU && ! TARGET_V9"
6208 "&& reload_completed
6209 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6210 [(set (match_dup 2) (abs:SF (match_dup 3)))
6211 (set (match_dup 4) (match_dup 5))
6212 (set (match_dup 6) (match_dup 7))]
6213 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6214 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6215 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6216 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
6217 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6218 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6219 [(set_attr "type" "fpmove,*")
6220 (set_attr "length" "*,2")])
6222 (define_insn "*abstf2_hq_v9"
6223 [(set (match_operand:TF 0 "register_operand" "=e,e")
6224 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6225 "TARGET_FPU && TARGET_V9 && TARGET_HARD_QUAD"
6229 [(set_attr "type" "fpmove")
6230 (set_attr "fptype" "double,*")])
6232 (define_insn_and_split "*abstf2_v9"
6233 [(set (match_operand:TF 0 "register_operand" "=e,e")
6234 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6235 "TARGET_FPU && TARGET_V9 && !TARGET_HARD_QUAD"
6239 "&& reload_completed
6240 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6241 [(set (match_dup 2) (abs:DF (match_dup 3)))
6242 (set (match_dup 4) (match_dup 5))]
6243 "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
6244 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
6245 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6246 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6247 [(set_attr "type" "fpmove,*")
6248 (set_attr "length" "*,2")
6249 (set_attr "fptype" "double,*")])
6251 (define_expand "absdf2"
6252 [(set (match_operand:DF 0 "register_operand" "")
6253 (abs:DF (match_operand:DF 1 "register_operand" "")))]
6257 (define_insn_and_split "*absdf2_notv9"
6258 [(set (match_operand:DF 0 "register_operand" "=e,e")
6259 (abs:DF (match_operand:DF 1 "register_operand" "0,e")))]
6260 "TARGET_FPU && ! TARGET_V9"
6264 "&& reload_completed
6265 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6266 [(set (match_dup 2) (abs:SF (match_dup 3)))
6267 (set (match_dup 4) (match_dup 5))]
6268 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6269 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6270 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6271 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);"
6272 [(set_attr "type" "fpmove,*")
6273 (set_attr "length" "*,2")])
6275 (define_insn "*absdf2_v9"
6276 [(set (match_operand:DF 0 "register_operand" "=e")
6277 (abs:DF (match_operand:DF 1 "register_operand" "e")))]
6278 "TARGET_FPU && TARGET_V9"
6280 [(set_attr "type" "fpmove")
6281 (set_attr "fptype" "double")])
6283 (define_insn "abssf2"
6284 [(set (match_operand:SF 0 "register_operand" "=f")
6285 (abs:SF (match_operand:SF 1 "register_operand" "f")))]
6288 [(set_attr "type" "fpmove")])
6290 (define_expand "sqrttf2"
6291 [(set (match_operand:TF 0 "nonimmediate_operand" "")
6292 (sqrt:TF (match_operand:TF 1 "general_operand" "")))]
6293 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6294 "emit_tfmode_unop (SQRT, operands); DONE;")
6296 (define_insn "*sqrttf2_hq"
6297 [(set (match_operand:TF 0 "register_operand" "=e")
6298 (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
6299 "TARGET_FPU && TARGET_HARD_QUAD"
6301 [(set_attr "type" "fpsqrtd")])
6303 (define_insn "sqrtdf2"
6304 [(set (match_operand:DF 0 "register_operand" "=e")
6305 (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
6308 [(set_attr "type" "fpsqrtd")
6309 (set_attr "fptype" "double")])
6311 (define_insn "sqrtsf2"
6312 [(set (match_operand:SF 0 "register_operand" "=f")
6313 (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
6316 [(set_attr "type" "fpsqrts")])
6319 ;; Arithmetic shift instructions.
6321 (define_insn "ashlsi3"
6322 [(set (match_operand:SI 0 "register_operand" "=r")
6323 (ashift:SI (match_operand:SI 1 "register_operand" "r")
6324 (match_operand:SI 2 "arith_operand" "rI")))]
6327 if (GET_CODE (operands[2]) == CONST_INT)
6328 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6329 return "sll\t%1, %2, %0";
6332 (if_then_else (match_operand 2 "const_one_operand" "")
6333 (const_string "ialu") (const_string "shift")))])
6335 (define_expand "ashldi3"
6336 [(set (match_operand:DI 0 "register_operand" "=r")
6337 (ashift:DI (match_operand:DI 1 "register_operand" "r")
6338 (match_operand:SI 2 "arith_operand" "rI")))]
6339 "TARGET_ARCH64 || TARGET_V8PLUS"
6341 if (! TARGET_ARCH64)
6343 if (GET_CODE (operands[2]) == CONST_INT)
6345 emit_insn (gen_ashldi3_v8plus (operands[0], operands[1], operands[2]));
6350 (define_insn "*ashldi3_sp64"
6351 [(set (match_operand:DI 0 "register_operand" "=r")
6352 (ashift:DI (match_operand:DI 1 "register_operand" "r")
6353 (match_operand:SI 2 "arith_operand" "rI")))]
6356 if (GET_CODE (operands[2]) == CONST_INT)
6357 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
6358 return "sllx\t%1, %2, %0";
6361 (if_then_else (match_operand 2 "const_one_operand" "")
6362 (const_string "ialu") (const_string "shift")))])
6365 (define_insn "ashldi3_v8plus"
6366 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
6367 (ashift:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
6368 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
6369 (clobber (match_scratch:SI 3 "=X,X,&h"))]
6371 "* return output_v8plus_shift (operands, insn, \"sllx\");"
6372 [(set_attr "type" "multi")
6373 (set_attr "length" "5,5,6")])
6375 ;; Optimize (1LL<<x)-1
6376 ;; XXX this also needs to be fixed to handle equal subregs
6377 ;; XXX first before we could re-enable it.
6379 ; [(set (match_operand:DI 0 "register_operand" "=h")
6380 ; (plus:DI (ashift:DI (const_int 1)
6381 ; (match_operand:SI 1 "arith_operand" "rI"))
6383 ; "0 && TARGET_V8PLUS"
6385 ; if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == REGNO (operands[0]))
6386 ; return "mov\t1, %L0\;sllx\t%L0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
6387 ; return "mov\t1, %H0\;sllx\t%H0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
6389 ; [(set_attr "type" "multi")
6390 ; (set_attr "length" "4")])
6392 (define_insn "*cmp_cc_ashift_1"
6393 [(set (reg:CC_NOOV 100)
6394 (compare:CC_NOOV (ashift:SI (match_operand:SI 0 "register_operand" "r")
6398 "addcc\t%0, %0, %%g0"
6399 [(set_attr "type" "compare")])
6401 (define_insn "*cmp_cc_set_ashift_1"
6402 [(set (reg:CC_NOOV 100)
6403 (compare:CC_NOOV (ashift:SI (match_operand:SI 1 "register_operand" "r")
6406 (set (match_operand:SI 0 "register_operand" "=r")
6407 (ashift:SI (match_dup 1) (const_int 1)))]
6410 [(set_attr "type" "compare")])
6412 (define_insn "ashrsi3"
6413 [(set (match_operand:SI 0 "register_operand" "=r")
6414 (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
6415 (match_operand:SI 2 "arith_operand" "rI")))]
6418 if (GET_CODE (operands[2]) == CONST_INT)
6419 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6420 return "sra\t%1, %2, %0";
6422 [(set_attr "type" "shift")])
6424 (define_insn "*ashrsi3_extend"
6425 [(set (match_operand:DI 0 "register_operand" "=r")
6426 (sign_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
6427 (match_operand:SI 2 "arith_operand" "r"))))]
6430 [(set_attr "type" "shift")])
6432 ;; This handles the case as above, but with constant shift instead of
6433 ;; register. Combiner "simplifies" it for us a little bit though.
6434 (define_insn "*ashrsi3_extend2"
6435 [(set (match_operand:DI 0 "register_operand" "=r")
6436 (ashiftrt:DI (ashift:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
6438 (match_operand:SI 2 "small_int_operand" "I")))]
6439 "TARGET_ARCH64 && INTVAL (operands[2]) >= 32 && INTVAL (operands[2]) < 64"
6441 operands[2] = GEN_INT (INTVAL (operands[2]) - 32);
6442 return "sra\t%1, %2, %0";
6444 [(set_attr "type" "shift")])
6446 (define_expand "ashrdi3"
6447 [(set (match_operand:DI 0 "register_operand" "=r")
6448 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
6449 (match_operand:SI 2 "arith_operand" "rI")))]
6450 "TARGET_ARCH64 || TARGET_V8PLUS"
6452 if (! TARGET_ARCH64)
6454 if (GET_CODE (operands[2]) == CONST_INT)
6455 FAIL; /* prefer generic code in this case */
6456 emit_insn (gen_ashrdi3_v8plus (operands[0], operands[1], operands[2]));
6461 (define_insn "*ashrdi3_sp64"
6462 [(set (match_operand:DI 0 "register_operand" "=r")
6463 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
6464 (match_operand:SI 2 "arith_operand" "rI")))]
6468 if (GET_CODE (operands[2]) == CONST_INT)
6469 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
6470 return "srax\t%1, %2, %0";
6472 [(set_attr "type" "shift")])
6475 (define_insn "ashrdi3_v8plus"
6476 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
6477 (ashiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
6478 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
6479 (clobber (match_scratch:SI 3 "=X,X,&h"))]
6481 "* return output_v8plus_shift (operands, insn, \"srax\");"
6482 [(set_attr "type" "multi")
6483 (set_attr "length" "5,5,6")])
6485 (define_insn "lshrsi3"
6486 [(set (match_operand:SI 0 "register_operand" "=r")
6487 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
6488 (match_operand:SI 2 "arith_operand" "rI")))]
6491 if (GET_CODE (operands[2]) == CONST_INT)
6492 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6493 return "srl\t%1, %2, %0";
6495 [(set_attr "type" "shift")])
6497 ;; This handles the case where
6498 ;; (zero_extend:DI (lshiftrt:SI (match_operand:SI) (match_operand:SI))),
6499 ;; but combiner "simplifies" it for us.
6500 (define_insn "*lshrsi3_extend"
6501 [(set (match_operand:DI 0 "register_operand" "=r")
6502 (and:DI (subreg:DI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
6503 (match_operand:SI 2 "arith_operand" "r")) 0)
6504 (match_operand 3 "const_int_operand" "")))]
6505 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) == 0xffffffff"
6507 [(set_attr "type" "shift")])
6509 ;; This handles the case where
6510 ;; (lshiftrt:DI (zero_extend:DI (match_operand:SI)) (const_int >=0 < 32))
6511 ;; but combiner "simplifies" it for us.
6512 (define_insn "*lshrsi3_extend2"
6513 [(set (match_operand:DI 0 "register_operand" "=r")
6514 (zero_extract:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
6515 (match_operand 2 "small_int_operand" "I")
6517 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
6519 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
6520 return "srl\t%1, %2, %0";
6522 [(set_attr "type" "shift")])
6524 (define_expand "lshrdi3"
6525 [(set (match_operand:DI 0 "register_operand" "=r")
6526 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6527 (match_operand:SI 2 "arith_operand" "rI")))]
6528 "TARGET_ARCH64 || TARGET_V8PLUS"
6530 if (! TARGET_ARCH64)
6532 if (GET_CODE (operands[2]) == CONST_INT)
6534 emit_insn (gen_lshrdi3_v8plus (operands[0], operands[1], operands[2]));
6539 (define_insn "*lshrdi3_sp64"
6540 [(set (match_operand:DI 0 "register_operand" "=r")
6541 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6542 (match_operand:SI 2 "arith_operand" "rI")))]
6545 if (GET_CODE (operands[2]) == CONST_INT)
6546 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
6547 return "srlx\t%1, %2, %0";
6549 [(set_attr "type" "shift")])
6552 (define_insn "lshrdi3_v8plus"
6553 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
6554 (lshiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
6555 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
6556 (clobber (match_scratch:SI 3 "=X,X,&h"))]
6558 "* return output_v8plus_shift (operands, insn, \"srlx\");"
6559 [(set_attr "type" "multi")
6560 (set_attr "length" "5,5,6")])
6563 [(set (match_operand:SI 0 "register_operand" "=r")
6564 (ashiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6566 (match_operand:SI 2 "small_int_operand" "I")))]
6567 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
6569 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
6570 return "srax\t%1, %2, %0";
6572 [(set_attr "type" "shift")])
6575 [(set (match_operand:SI 0 "register_operand" "=r")
6576 (lshiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
6578 (match_operand:SI 2 "small_int_operand" "I")))]
6579 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
6581 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
6582 return "srlx\t%1, %2, %0";
6584 [(set_attr "type" "shift")])
6587 [(set (match_operand:SI 0 "register_operand" "=r")
6588 (ashiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
6589 (match_operand:SI 2 "small_int_operand" "I")) 4)
6590 (match_operand:SI 3 "small_int_operand" "I")))]
6592 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
6593 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
6594 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
6596 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
6598 return "srax\t%1, %2, %0";
6600 [(set_attr "type" "shift")])
6603 [(set (match_operand:SI 0 "register_operand" "=r")
6604 (lshiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6605 (match_operand:SI 2 "small_int_operand" "I")) 4)
6606 (match_operand:SI 3 "small_int_operand" "I")))]
6608 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
6609 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
6610 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
6612 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
6614 return "srlx\t%1, %2, %0";
6616 [(set_attr "type" "shift")])
6619 ;; Unconditional and other jump instructions.
6622 [(set (pc) (label_ref (match_operand 0 "" "")))]
6624 "* return output_ubranch (operands[0], 0, insn);"
6625 [(set_attr "type" "uncond_branch")])
6627 (define_expand "tablejump"
6628 [(parallel [(set (pc) (match_operand 0 "register_operand" "r"))
6629 (use (label_ref (match_operand 1 "" "")))])]
6632 gcc_assert (GET_MODE (operands[0]) == CASE_VECTOR_MODE);
6634 /* In pic mode, our address differences are against the base of the
6635 table. Add that base value back in; CSE ought to be able to combine
6636 the two address loads. */
6640 tmp = gen_rtx_LABEL_REF (Pmode, operands[1]);
6642 if (CASE_VECTOR_MODE != Pmode)
6643 tmp2 = gen_rtx_SIGN_EXTEND (Pmode, tmp2);
6644 tmp = gen_rtx_PLUS (Pmode, tmp2, tmp);
6645 operands[0] = memory_address (Pmode, tmp);
6649 (define_insn "*tablejump_sp32"
6650 [(set (pc) (match_operand:SI 0 "address_operand" "p"))
6651 (use (label_ref (match_operand 1 "" "")))]
6654 [(set_attr "type" "uncond_branch")])
6656 (define_insn "*tablejump_sp64"
6657 [(set (pc) (match_operand:DI 0 "address_operand" "p"))
6658 (use (label_ref (match_operand 1 "" "")))]
6661 [(set_attr "type" "uncond_branch")])
6664 ;; Jump to subroutine instructions.
6666 (define_expand "call"
6667 ;; Note that this expression is not used for generating RTL.
6668 ;; All the RTL is generated explicitly below.
6669 [(call (match_operand 0 "call_operand" "")
6670 (match_operand 3 "" "i"))]
6671 ;; operands[2] is next_arg_register
6672 ;; operands[3] is struct_value_size_rtx.
6677 gcc_assert (GET_MODE (operands[0]) == FUNCTION_MODE);
6679 gcc_assert (GET_CODE (operands[3]) == CONST_INT);
6681 if (GET_CODE (XEXP (operands[0], 0)) == LABEL_REF)
6683 /* This is really a PIC sequence. We want to represent
6684 it as a funny jump so its delay slots can be filled.
6686 ??? But if this really *is* a CALL, will not it clobber the
6687 call-clobbered registers? We lose this if it is a JUMP_INSN.
6688 Why cannot we have delay slots filled if it were a CALL? */
6690 /* We accept negative sizes for untyped calls. */
6691 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
6696 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
6698 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
6704 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
6705 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
6709 fn_rtx = operands[0];
6711 /* We accept negative sizes for untyped calls. */
6712 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
6716 gen_rtvec (3, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx),
6718 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
6723 gen_rtvec (2, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx),
6724 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
6731 ;; We can't use the same pattern for these two insns, because then registers
6732 ;; in the address may not be properly reloaded.
6734 (define_insn "*call_address_sp32"
6735 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6736 (match_operand 1 "" ""))
6737 (clobber (reg:SI 15))]
6738 ;;- Do not use operand 1 for most machines.
6741 [(set_attr "type" "call")])
6743 (define_insn "*call_symbolic_sp32"
6744 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6745 (match_operand 1 "" ""))
6746 (clobber (reg:SI 15))]
6747 ;;- Do not use operand 1 for most machines.
6750 [(set_attr "type" "call")])
6752 (define_insn "*call_address_sp64"
6753 [(call (mem:DI (match_operand:DI 0 "address_operand" "p"))
6754 (match_operand 1 "" ""))
6755 (clobber (reg:DI 15))]
6756 ;;- Do not use operand 1 for most machines.
6759 [(set_attr "type" "call")])
6761 (define_insn "*call_symbolic_sp64"
6762 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
6763 (match_operand 1 "" ""))
6764 (clobber (reg:DI 15))]
6765 ;;- Do not use operand 1 for most machines.
6768 [(set_attr "type" "call")])
6770 ;; This is a call that wants a structure value.
6771 ;; There is no such critter for v9 (??? we may need one anyway).
6772 (define_insn "*call_address_struct_value_sp32"
6773 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6774 (match_operand 1 "" ""))
6775 (match_operand 2 "immediate_operand" "")
6776 (clobber (reg:SI 15))]
6777 ;;- Do not use operand 1 for most machines.
6778 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
6780 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xfff);
6781 return "call\t%a0, %1\n\t nop\n\tunimp\t%2";
6783 [(set_attr "type" "call_no_delay_slot")
6784 (set_attr "length" "3")])
6786 ;; This is a call that wants a structure value.
6787 ;; There is no such critter for v9 (??? we may need one anyway).
6788 (define_insn "*call_symbolic_struct_value_sp32"
6789 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6790 (match_operand 1 "" ""))
6791 (match_operand 2 "immediate_operand" "")
6792 (clobber (reg:SI 15))]
6793 ;;- Do not use operand 1 for most machines.
6794 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
6796 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xfff);
6797 return "call\t%a0, %1\n\t nop\n\tunimp\t%2";
6799 [(set_attr "type" "call_no_delay_slot")
6800 (set_attr "length" "3")])
6802 ;; This is a call that may want a structure value. This is used for
6804 (define_insn "*call_address_untyped_struct_value_sp32"
6805 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6806 (match_operand 1 "" ""))
6807 (match_operand 2 "immediate_operand" "")
6808 (clobber (reg:SI 15))]
6809 ;;- Do not use operand 1 for most machines.
6810 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
6811 "call\t%a0, %1\n\t nop\n\tnop"
6812 [(set_attr "type" "call_no_delay_slot")
6813 (set_attr "length" "3")])
6815 ;; This is a call that may want a structure value. This is used for
6817 (define_insn "*call_symbolic_untyped_struct_value_sp32"
6818 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6819 (match_operand 1 "" ""))
6820 (match_operand 2 "immediate_operand" "")
6821 (clobber (reg:SI 15))]
6822 ;;- Do not use operand 1 for most machines.
6823 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
6824 "call\t%a0, %1\n\t nop\n\tnop"
6825 [(set_attr "type" "call_no_delay_slot")
6826 (set_attr "length" "3")])
6828 (define_expand "call_value"
6829 ;; Note that this expression is not used for generating RTL.
6830 ;; All the RTL is generated explicitly below.
6831 [(set (match_operand 0 "register_operand" "=rf")
6832 (call (match_operand 1 "" "")
6833 (match_operand 4 "" "")))]
6834 ;; operand 2 is stack_size_rtx
6835 ;; operand 3 is next_arg_register
6841 gcc_assert (GET_MODE (operands[1]) == FUNCTION_MODE);
6843 fn_rtx = operands[1];
6846 gen_rtx_SET (VOIDmode, operands[0],
6847 gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx)),
6848 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)));
6850 emit_call_insn (gen_rtx_PARALLEL (VOIDmode, vec));
6855 (define_insn "*call_value_address_sp32"
6856 [(set (match_operand 0 "" "=rf")
6857 (call (mem:SI (match_operand:SI 1 "address_operand" "p"))
6858 (match_operand 2 "" "")))
6859 (clobber (reg:SI 15))]
6860 ;;- Do not use operand 2 for most machines.
6863 [(set_attr "type" "call")])
6865 (define_insn "*call_value_symbolic_sp32"
6866 [(set (match_operand 0 "" "=rf")
6867 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
6868 (match_operand 2 "" "")))
6869 (clobber (reg:SI 15))]
6870 ;;- Do not use operand 2 for most machines.
6873 [(set_attr "type" "call")])
6875 (define_insn "*call_value_address_sp64"
6876 [(set (match_operand 0 "" "")
6877 (call (mem:DI (match_operand:DI 1 "address_operand" "p"))
6878 (match_operand 2 "" "")))
6879 (clobber (reg:DI 15))]
6880 ;;- Do not use operand 2 for most machines.
6883 [(set_attr "type" "call")])
6885 (define_insn "*call_value_symbolic_sp64"
6886 [(set (match_operand 0 "" "")
6887 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
6888 (match_operand 2 "" "")))
6889 (clobber (reg:DI 15))]
6890 ;;- Do not use operand 2 for most machines.
6893 [(set_attr "type" "call")])
6895 (define_expand "untyped_call"
6896 [(parallel [(call (match_operand 0 "" "")
6898 (match_operand:BLK 1 "memory_operand" "")
6899 (match_operand 2 "" "")])]
6902 rtx valreg1 = gen_rtx_REG (DImode, 8);
6903 rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
6904 rtx result = operands[1];
6906 /* Pass constm1 to indicate that it may expect a structure value, but
6907 we don't know what size it is. */
6908 emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, constm1_rtx));
6910 /* Save the function value registers. */
6911 emit_move_insn (adjust_address (result, DImode, 0), valreg1);
6912 emit_move_insn (adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8),
6915 /* The optimizer does not know that the call sets the function value
6916 registers we stored in the result block. We avoid problems by
6917 claiming that all hard registers are used and clobbered at this
6919 emit_insn (gen_blockage ());
6924 ;; Tail call instructions.
6926 (define_expand "sibcall"
6927 [(parallel [(call (match_operand 0 "call_operand" "") (const_int 0))
6932 (define_insn "*sibcall_symbolic_sp32"
6933 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6934 (match_operand 1 "" ""))
6937 "* return output_sibcall(insn, operands[0]);"
6938 [(set_attr "type" "sibcall")])
6940 (define_insn "*sibcall_symbolic_sp64"
6941 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
6942 (match_operand 1 "" ""))
6945 "* return output_sibcall(insn, operands[0]);"
6946 [(set_attr "type" "sibcall")])
6948 (define_expand "sibcall_value"
6949 [(parallel [(set (match_operand 0 "register_operand" "=rf")
6950 (call (match_operand 1 "" "") (const_int 0)))
6955 (define_insn "*sibcall_value_symbolic_sp32"
6956 [(set (match_operand 0 "" "=rf")
6957 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
6958 (match_operand 2 "" "")))
6961 "* return output_sibcall(insn, operands[1]);"
6962 [(set_attr "type" "sibcall")])
6964 (define_insn "*sibcall_value_symbolic_sp64"
6965 [(set (match_operand 0 "" "")
6966 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
6967 (match_operand 2 "" "")))
6970 "* return output_sibcall(insn, operands[1]);"
6971 [(set_attr "type" "sibcall")])
6974 ;; Special instructions.
6976 (define_expand "prologue"
6980 sparc_expand_prologue ();
6984 ;; The "save register window" insn is modelled as follows so that the DWARF-2
6985 ;; backend automatically emits the required call frame debugging information
6986 ;; while it is parsing it. Therefore, the pattern should not be modified
6987 ;; without first studying the impact of the changes on the debug info.
6988 ;; [(set (%fp) (%sp))
6989 ;; (set (%sp) (unspec_volatile [(%sp) (-frame_size)] UNSPECV_SAVEW))
6990 ;; (set (%i7) (%o7))]
6992 (define_insn "save_register_window<P:mode>"
6993 [(set (reg:P 30) (reg:P 14))
6994 (set (reg:P 14) (unspec_volatile:P [(reg:P 14)
6995 (match_operand:P 0 "arith_operand" "rI")] UNSPECV_SAVEW))
6996 (set (reg:P 31) (reg:P 15))]
6998 "save\t%%sp, %0, %%sp"
6999 [(set_attr "type" "savew")])
7001 (define_expand "epilogue"
7005 sparc_expand_epilogue ();
7008 (define_expand "sibcall_epilogue"
7012 sparc_expand_epilogue ();
7016 (define_expand "return"
7018 "sparc_can_use_return_insn_p ()"
7021 (define_insn "*return_internal"
7024 "* return output_return (insn);"
7025 [(set_attr "type" "return")
7026 (set (attr "length")
7027 (cond [(eq_attr "leaf_function" "true")
7028 (if_then_else (eq_attr "empty_delay_slot" "true")
7031 (eq_attr "calls_eh_return" "true")
7032 (if_then_else (eq_attr "delayed_branch" "true")
7033 (if_then_else (eq_attr "isa" "v9")
7036 (if_then_else (eq_attr "isa" "v9")
7039 (eq_attr "empty_delay_slot" "true")
7040 (if_then_else (eq_attr "delayed_branch" "true")
7045 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
7046 ;; all of memory. This blocks insns from being moved across this point.
7048 (define_insn "blockage"
7049 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
7052 [(set_attr "length" "0")])
7054 ;; Prepare to return any type including a structure value.
7056 (define_expand "untyped_return"
7057 [(match_operand:BLK 0 "memory_operand" "")
7058 (match_operand 1 "" "")]
7061 rtx valreg1 = gen_rtx_REG (DImode, 24);
7062 rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
7063 rtx result = operands[0];
7065 if (! TARGET_ARCH64)
7067 rtx rtnreg = gen_rtx_REG (SImode, (current_function_uses_only_leaf_regs
7069 rtx value = gen_reg_rtx (SImode);
7071 /* Fetch the instruction where we will return to and see if it's an unimp
7072 instruction (the most significant 10 bits will be zero). If so,
7073 update the return address to skip the unimp instruction. */
7074 emit_move_insn (value,
7075 gen_rtx_MEM (SImode, plus_constant (rtnreg, 8)));
7076 emit_insn (gen_lshrsi3 (value, value, GEN_INT (22)));
7077 emit_insn (gen_update_return (rtnreg, value));
7080 /* Reload the function value registers. */
7081 emit_move_insn (valreg1, adjust_address (result, DImode, 0));
7082 emit_move_insn (valreg2,
7083 adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8));
7085 /* Put USE insns before the return. */
7086 emit_insn (gen_rtx_USE (VOIDmode, valreg1));
7087 emit_insn (gen_rtx_USE (VOIDmode, valreg2));
7089 /* Construct the return. */
7090 expand_naked_return ();
7095 ;; This is a bit of a hack. We're incrementing a fixed register (%i7),
7096 ;; and parts of the compiler don't want to believe that the add is needed.
7098 (define_insn "update_return"
7099 [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
7100 (match_operand:SI 1 "register_operand" "r")] UNSPEC_UPDATE_RETURN)]
7103 if (flag_delayed_branch)
7104 return "cmp\t%1, 0\n\tbe,a\t.+8\n\t add\t%0, 4, %0";
7106 return "cmp\t%1, 0\n\tbne\t.+12\n\t nop\n\tadd\t%0, 4, %0";
7108 [(set (attr "type") (const_string "multi"))
7109 (set (attr "length")
7110 (if_then_else (eq_attr "delayed_branch" "true")
7119 (define_expand "indirect_jump"
7120 [(set (pc) (match_operand 0 "address_operand" "p"))]
7124 (define_insn "*branch_sp32"
7125 [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
7128 [(set_attr "type" "uncond_branch")])
7130 (define_insn "*branch_sp64"
7131 [(set (pc) (match_operand:DI 0 "address_operand" "p"))]
7134 [(set_attr "type" "uncond_branch")])
7136 (define_expand "nonlocal_goto"
7137 [(match_operand:SI 0 "general_operand" "")
7138 (match_operand:SI 1 "general_operand" "")
7139 (match_operand:SI 2 "general_operand" "")
7140 (match_operand:SI 3 "" "")]
7143 rtx lab = operands[1];
7144 rtx stack = operands[2];
7145 rtx fp = operands[3];
7148 /* Trap instruction to flush all the register windows. */
7149 emit_insn (gen_flush_register_windows ());
7151 /* Load the fp value for the containing fn into %fp. This is needed
7152 because STACK refers to %fp. Note that virtual register instantiation
7153 fails if the virtual %fp isn't set from a register. */
7154 if (GET_CODE (fp) != REG)
7155 fp = force_reg (Pmode, fp);
7156 emit_move_insn (virtual_stack_vars_rtx, fp);
7158 /* Find the containing function's current nonlocal goto handler,
7159 which will do any cleanups and then jump to the label. */
7160 labreg = gen_rtx_REG (Pmode, 8);
7161 emit_move_insn (labreg, lab);
7163 /* Restore %fp from stack pointer value for containing function.
7164 The restore insn that follows will move this to %sp,
7165 and reload the appropriate value into %fp. */
7166 emit_move_insn (hard_frame_pointer_rtx, stack);
7168 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
7169 emit_insn (gen_rtx_USE (VOIDmode, static_chain_rtx));
7171 /* ??? The V9-specific version was disabled in rev 1.65. */
7172 emit_jump_insn (gen_goto_handler_and_restore (labreg));
7177 ;; Special trap insn to flush register windows.
7178 (define_insn "flush_register_windows"
7179 [(unspec_volatile [(const_int 0)] UNSPECV_FLUSHW)]
7181 { return TARGET_V9 ? "flushw" : "ta\t3"; }
7182 [(set_attr "type" "flushw")])
7184 (define_insn "goto_handler_and_restore"
7185 [(unspec_volatile [(match_operand 0 "register_operand" "=r")] UNSPECV_GOTO)]
7186 "GET_MODE (operands[0]) == Pmode"
7188 if (flag_delayed_branch)
7189 return "jmp\t%0\n\t restore";
7191 return "mov\t%0,%%g1\n\trestore\n\tjmp\t%%g1\n\t nop";
7193 [(set (attr "type") (const_string "multi"))
7194 (set (attr "length")
7195 (if_then_else (eq_attr "delayed_branch" "true")
7199 ;; For __builtin_setjmp we need to flush register windows iff the function
7200 ;; calls alloca as well, because otherwise the register window might be
7201 ;; saved after %sp adjustment and thus setjmp would crash
7202 (define_expand "builtin_setjmp_setup"
7203 [(match_operand 0 "register_operand" "r")]
7206 emit_insn (gen_do_builtin_setjmp_setup ());
7210 (define_insn "do_builtin_setjmp_setup"
7211 [(unspec_volatile [(const_int 0)] UNSPECV_SETJMP)]
7214 if (! current_function_calls_alloca)
7218 fputs ("\tflushw\n", asm_out_file);
7220 fprintf (asm_out_file, "\tst%c\t%%l7, [%%sp+%d]\n",
7221 TARGET_ARCH64 ? 'x' : 'w',
7222 SPARC_STACK_BIAS + 7 * UNITS_PER_WORD);
7223 fprintf (asm_out_file, "\tst%c\t%%fp, [%%sp+%d]\n",
7224 TARGET_ARCH64 ? 'x' : 'w',
7225 SPARC_STACK_BIAS + 14 * UNITS_PER_WORD);
7226 fprintf (asm_out_file, "\tst%c\t%%i7, [%%sp+%d]\n",
7227 TARGET_ARCH64 ? 'x' : 'w',
7228 SPARC_STACK_BIAS + 15 * UNITS_PER_WORD);
7231 [(set_attr "type" "multi")
7232 (set (attr "length")
7233 (cond [(eq_attr "calls_alloca" "false")
7235 (eq_attr "isa" "!v9")
7237 (eq_attr "pic" "true")
7238 (const_int 4)] (const_int 3)))])
7240 ;; Pattern for use after a setjmp to store FP and the return register
7241 ;; into the stack area.
7243 (define_expand "setjmp"
7249 mem = gen_rtx_MEM (Pmode,
7250 plus_constant (stack_pointer_rtx,
7251 SPARC_STACK_BIAS + 14 * UNITS_PER_WORD));
7252 emit_insn (gen_rtx_SET (VOIDmode, mem, frame_pointer_rtx));
7254 mem = gen_rtx_MEM (Pmode,
7255 plus_constant (stack_pointer_rtx,
7256 SPARC_STACK_BIAS + 15 * UNITS_PER_WORD));
7257 emit_insn (gen_rtx_SET (VOIDmode, mem, gen_rtx_REG (Pmode, 31)));
7261 ;; Special pattern for the FLUSH instruction.
7263 ; We do SImode and DImode versions of this to quiet down genrecog's complaints
7264 ; of the define_insn otherwise missing a mode. We make "flush", aka
7265 ; gen_flush, the default one since sparc_initialize_trampoline uses
7266 ; it on SImode mem values.
7268 (define_insn "flush"
7269 [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")] UNSPECV_FLUSH)]
7271 { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; }
7272 [(set_attr "type" "iflush")])
7274 (define_insn "flushdi"
7275 [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")] UNSPECV_FLUSH)]
7277 { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; }
7278 [(set_attr "type" "iflush")])
7281 ;; Find first set instructions.
7283 ;; The scan instruction searches from the most significant bit while ffs
7284 ;; searches from the least significant bit. The bit index and treatment of
7285 ;; zero also differ. It takes at least 7 instructions to get the proper
7286 ;; result. Here is an obvious 8 instruction sequence.
7289 (define_insn "ffssi2"
7290 [(set (match_operand:SI 0 "register_operand" "=&r")
7291 (ffs:SI (match_operand:SI 1 "register_operand" "r")))
7292 (clobber (match_scratch:SI 2 "=&r"))]
7293 "TARGET_SPARCLITE || TARGET_SPARCLET"
7295 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";
7297 [(set_attr "type" "multi")
7298 (set_attr "length" "8")])
7300 ;; ??? This should be a define expand, so that the extra instruction have
7301 ;; a chance of being optimized away.
7303 ;; Disabled because none of the UltraSPARCs implement popc. The HAL R1
7304 ;; does, but no one uses that and we don't have a switch for it.
7306 ;(define_insn "ffsdi2"
7307 ; [(set (match_operand:DI 0 "register_operand" "=&r")
7308 ; (ffs:DI (match_operand:DI 1 "register_operand" "r")))
7309 ; (clobber (match_scratch:DI 2 "=&r"))]
7311 ; "neg\t%1, %2\;xnor\t%1, %2, %2\;popc\t%2, %0\;movzr\t%1, 0, %0"
7312 ; [(set_attr "type" "multi")
7313 ; (set_attr "length" "4")])
7317 ;; Peepholes go at the end.
7319 ;; Optimize consecutive loads or stores into ldd and std when possible.
7320 ;; The conditions in which we do this are very restricted and are
7321 ;; explained in the code for {registers,memory}_ok_for_ldd functions.
7324 [(set (match_operand:SI 0 "memory_operand" "")
7326 (set (match_operand:SI 1 "memory_operand" "")
7329 && mems_ok_for_ldd_peep (operands[0], operands[1], NULL_RTX)"
7332 "operands[0] = widen_memory_access (operands[0], DImode, 0);")
7335 [(set (match_operand:SI 0 "memory_operand" "")
7337 (set (match_operand:SI 1 "memory_operand" "")
7340 && mems_ok_for_ldd_peep (operands[1], operands[0], NULL_RTX)"
7343 "operands[1] = widen_memory_access (operands[1], DImode, 0);")
7346 [(set (match_operand:SI 0 "register_operand" "")
7347 (match_operand:SI 1 "memory_operand" ""))
7348 (set (match_operand:SI 2 "register_operand" "")
7349 (match_operand:SI 3 "memory_operand" ""))]
7350 "registers_ok_for_ldd_peep (operands[0], operands[2])
7351 && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
7354 "operands[1] = widen_memory_access (operands[1], DImode, 0);
7355 operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));")
7358 [(set (match_operand:SI 0 "memory_operand" "")
7359 (match_operand:SI 1 "register_operand" ""))
7360 (set (match_operand:SI 2 "memory_operand" "")
7361 (match_operand:SI 3 "register_operand" ""))]
7362 "registers_ok_for_ldd_peep (operands[1], operands[3])
7363 && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
7366 "operands[0] = widen_memory_access (operands[0], DImode, 0);
7367 operands[1] = gen_rtx_REG (DImode, REGNO (operands[1]));")
7370 [(set (match_operand:SF 0 "register_operand" "")
7371 (match_operand:SF 1 "memory_operand" ""))
7372 (set (match_operand:SF 2 "register_operand" "")
7373 (match_operand:SF 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], DFmode, 0);
7379 operands[0] = gen_rtx_REG (DFmode, REGNO (operands[0]));")
7382 [(set (match_operand:SF 0 "memory_operand" "")
7383 (match_operand:SF 1 "register_operand" ""))
7384 (set (match_operand:SF 2 "memory_operand" "")
7385 (match_operand:SF 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], DFmode, 0);
7391 operands[1] = gen_rtx_REG (DFmode, REGNO (operands[1]));")
7394 [(set (match_operand:SI 0 "register_operand" "")
7395 (match_operand:SI 1 "memory_operand" ""))
7396 (set (match_operand:SI 2 "register_operand" "")
7397 (match_operand:SI 3 "memory_operand" ""))]
7398 "registers_ok_for_ldd_peep (operands[2], operands[0])
7399 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
7402 "operands[3] = widen_memory_access (operands[3], DImode, 0);
7403 operands[2] = gen_rtx_REG (DImode, REGNO (operands[2]));")
7406 [(set (match_operand:SI 0 "memory_operand" "")
7407 (match_operand:SI 1 "register_operand" ""))
7408 (set (match_operand:SI 2 "memory_operand" "")
7409 (match_operand:SI 3 "register_operand" ""))]
7410 "registers_ok_for_ldd_peep (operands[3], operands[1])
7411 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
7414 "operands[2] = widen_memory_access (operands[2], DImode, 0);
7415 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
7419 [(set (match_operand:SF 0 "register_operand" "")
7420 (match_operand:SF 1 "memory_operand" ""))
7421 (set (match_operand:SF 2 "register_operand" "")
7422 (match_operand:SF 3 "memory_operand" ""))]
7423 "registers_ok_for_ldd_peep (operands[2], operands[0])
7424 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
7427 "operands[3] = widen_memory_access (operands[3], DFmode, 0);
7428 operands[2] = gen_rtx_REG (DFmode, REGNO (operands[2]));")
7431 [(set (match_operand:SF 0 "memory_operand" "")
7432 (match_operand:SF 1 "register_operand" ""))
7433 (set (match_operand:SF 2 "memory_operand" "")
7434 (match_operand:SF 3 "register_operand" ""))]
7435 "registers_ok_for_ldd_peep (operands[3], operands[1])
7436 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
7439 "operands[2] = widen_memory_access (operands[2], DFmode, 0);
7440 operands[3] = gen_rtx_REG (DFmode, REGNO (operands[3]));")
7442 ;; Optimize the case of following a reg-reg move with a test
7443 ;; of reg just moved. Don't allow floating point regs for operand 0 or 1.
7444 ;; This can result from a float to fix conversion.
7447 [(set (match_operand:SI 0 "register_operand" "")
7448 (match_operand:SI 1 "register_operand" ""))
7450 (compare:CC (match_operand:SI 2 "register_operand" "")
7452 "(rtx_equal_p (operands[2], operands[0])
7453 || rtx_equal_p (operands[2], operands[1]))
7454 && ! SPARC_FP_REG_P (REGNO (operands[0]))
7455 && ! SPARC_FP_REG_P (REGNO (operands[1]))"
7456 [(parallel [(set (match_dup 0) (match_dup 1))
7458 (compare:CC (match_dup 1) (const_int 0)))])]
7462 [(set (match_operand:DI 0 "register_operand" "")
7463 (match_operand:DI 1 "register_operand" ""))
7465 (compare:CCX (match_operand:DI 2 "register_operand" "")
7468 && (rtx_equal_p (operands[2], operands[0])
7469 || rtx_equal_p (operands[2], operands[1]))
7470 && ! SPARC_FP_REG_P (REGNO (operands[0]))
7471 && ! SPARC_FP_REG_P (REGNO (operands[1]))"
7472 [(parallel [(set (match_dup 0) (match_dup 1))
7474 (compare:CCX (match_dup 1) (const_int 0)))])]
7478 ;; Prefetch instructions.
7480 ;; ??? UltraSPARC-III note: A memory operation loading into the floating point register
7481 ;; ??? file, if it hits the prefetch cache, has a chance to dual-issue with other memory
7482 ;; ??? operations. With DFA we might be able to model this, but it requires a lot of
7484 (define_expand "prefetch"
7485 [(match_operand 0 "address_operand" "")
7486 (match_operand 1 "const_int_operand" "")
7487 (match_operand 2 "const_int_operand" "")]
7491 emit_insn (gen_prefetch_64 (operands[0], operands[1], operands[2]));
7493 emit_insn (gen_prefetch_32 (operands[0], operands[1], operands[2]));
7497 (define_insn "prefetch_64"
7498 [(prefetch (match_operand:DI 0 "address_operand" "p")
7499 (match_operand:DI 1 "const_int_operand" "n")
7500 (match_operand:DI 2 "const_int_operand" "n"))]
7503 static const char * const prefetch_instr[2][2] = {
7505 "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
7506 "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
7509 "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
7510 "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
7513 int read_or_write = INTVAL (operands[1]);
7514 int locality = INTVAL (operands[2]);
7516 gcc_assert (read_or_write == 0 || read_or_write == 1);
7517 gcc_assert (locality >= 0 && locality < 4);
7518 return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
7520 [(set_attr "type" "load")])
7522 (define_insn "prefetch_32"
7523 [(prefetch (match_operand:SI 0 "address_operand" "p")
7524 (match_operand:SI 1 "const_int_operand" "n")
7525 (match_operand:SI 2 "const_int_operand" "n"))]
7528 static const char * const prefetch_instr[2][2] = {
7530 "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
7531 "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
7534 "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
7535 "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
7538 int read_or_write = INTVAL (operands[1]);
7539 int locality = INTVAL (operands[2]);
7541 gcc_assert (read_or_write == 0 || read_or_write == 1);
7542 gcc_assert (locality >= 0 && locality < 4);
7543 return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
7545 [(set_attr "type" "load")])
7548 ;; Trap instructions.
7551 [(trap_if (const_int 1) (const_int 5))]
7554 [(set_attr "type" "trap")])
7556 (define_expand "conditional_trap"
7557 [(trap_if (match_operator 0 "noov_compare_operator" [(match_dup 2) (match_dup 3)])
7558 (match_operand:SI 1 "arith_operand" ""))]
7560 "operands[2] = gen_compare_reg (GET_CODE (operands[0]));
7561 if (GET_MODE (operands[2]) != CCmode && GET_MODE (operands[2]) != CCXmode)
7563 operands[3] = const0_rtx;")
7566 [(trap_if (match_operator 0 "noov_compare_operator" [(reg:CC 100) (const_int 0)])
7567 (match_operand:SI 1 "arith_operand" "rM"))]
7571 return "t%C0\t%%icc, %1";
7575 [(set_attr "type" "trap")])
7578 [(trap_if (match_operator 0 "noov_compare_operator" [(reg:CCX 100) (const_int 0)])
7579 (match_operand:SI 1 "arith_operand" "rM"))]
7582 [(set_attr "type" "trap")])
7585 ;; TLS support instructions.
7587 (define_insn "tgd_hi22"
7588 [(set (match_operand:SI 0 "register_operand" "=r")
7589 (high:SI (unspec:SI [(match_operand 1 "tgd_symbolic_operand" "")]
7592 "sethi\\t%%tgd_hi22(%a1), %0")
7594 (define_insn "tgd_lo10"
7595 [(set (match_operand:SI 0 "register_operand" "=r")
7596 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7597 (unspec:SI [(match_operand 2 "tgd_symbolic_operand" "")]
7600 "add\\t%1, %%tgd_lo10(%a2), %0")
7602 (define_insn "tgd_add32"
7603 [(set (match_operand:SI 0 "register_operand" "=r")
7604 (plus:SI (match_operand:SI 1 "register_operand" "r")
7605 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7606 (match_operand 3 "tgd_symbolic_operand" "")]
7608 "TARGET_TLS && TARGET_ARCH32"
7609 "add\\t%1, %2, %0, %%tgd_add(%a3)")
7611 (define_insn "tgd_add64"
7612 [(set (match_operand:DI 0 "register_operand" "=r")
7613 (plus:DI (match_operand:DI 1 "register_operand" "r")
7614 (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7615 (match_operand 3 "tgd_symbolic_operand" "")]
7617 "TARGET_TLS && TARGET_ARCH64"
7618 "add\\t%1, %2, %0, %%tgd_add(%a3)")
7620 (define_insn "tgd_call32"
7621 [(set (match_operand 0 "register_operand" "=r")
7622 (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")
7623 (match_operand 2 "tgd_symbolic_operand" "")]
7625 (match_operand 3 "" "")))
7626 (clobber (reg:SI 15))]
7627 "TARGET_TLS && TARGET_ARCH32"
7628 "call\t%a1, %%tgd_call(%a2)%#"
7629 [(set_attr "type" "call")])
7631 (define_insn "tgd_call64"
7632 [(set (match_operand 0 "register_operand" "=r")
7633 (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")
7634 (match_operand 2 "tgd_symbolic_operand" "")]
7636 (match_operand 3 "" "")))
7637 (clobber (reg:DI 15))]
7638 "TARGET_TLS && TARGET_ARCH64"
7639 "call\t%a1, %%tgd_call(%a2)%#"
7640 [(set_attr "type" "call")])
7642 (define_insn "tldm_hi22"
7643 [(set (match_operand:SI 0 "register_operand" "=r")
7644 (high:SI (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
7646 "sethi\\t%%tldm_hi22(%&), %0")
7648 (define_insn "tldm_lo10"
7649 [(set (match_operand:SI 0 "register_operand" "=r")
7650 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7651 (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
7653 "add\\t%1, %%tldm_lo10(%&), %0")
7655 (define_insn "tldm_add32"
7656 [(set (match_operand:SI 0 "register_operand" "=r")
7657 (plus:SI (match_operand:SI 1 "register_operand" "r")
7658 (unspec:SI [(match_operand:SI 2 "register_operand" "r")]
7660 "TARGET_TLS && TARGET_ARCH32"
7661 "add\\t%1, %2, %0, %%tldm_add(%&)")
7663 (define_insn "tldm_add64"
7664 [(set (match_operand:DI 0 "register_operand" "=r")
7665 (plus:DI (match_operand:DI 1 "register_operand" "r")
7666 (unspec:DI [(match_operand:SI 2 "register_operand" "r")]
7668 "TARGET_TLS && TARGET_ARCH64"
7669 "add\\t%1, %2, %0, %%tldm_add(%&)")
7671 (define_insn "tldm_call32"
7672 [(set (match_operand 0 "register_operand" "=r")
7673 (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")]
7675 (match_operand 2 "" "")))
7676 (clobber (reg:SI 15))]
7677 "TARGET_TLS && TARGET_ARCH32"
7678 "call\t%a1, %%tldm_call(%&)%#"
7679 [(set_attr "type" "call")])
7681 (define_insn "tldm_call64"
7682 [(set (match_operand 0 "register_operand" "=r")
7683 (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")]
7685 (match_operand 2 "" "")))
7686 (clobber (reg:DI 15))]
7687 "TARGET_TLS && TARGET_ARCH64"
7688 "call\t%a1, %%tldm_call(%&)%#"
7689 [(set_attr "type" "call")])
7691 (define_insn "tldo_hix22"
7692 [(set (match_operand:SI 0 "register_operand" "=r")
7693 (high:SI (unspec:SI [(match_operand 1 "tld_symbolic_operand" "")]
7696 "sethi\\t%%tldo_hix22(%a1), %0")
7698 (define_insn "tldo_lox10"
7699 [(set (match_operand:SI 0 "register_operand" "=r")
7700 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7701 (unspec:SI [(match_operand 2 "tld_symbolic_operand" "")]
7704 "xor\\t%1, %%tldo_lox10(%a2), %0")
7706 (define_insn "tldo_add32"
7707 [(set (match_operand:SI 0 "register_operand" "=r")
7708 (plus:SI (match_operand:SI 1 "register_operand" "r")
7709 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7710 (match_operand 3 "tld_symbolic_operand" "")]
7712 "TARGET_TLS && TARGET_ARCH32"
7713 "add\\t%1, %2, %0, %%tldo_add(%a3)")
7715 (define_insn "tldo_add64"
7716 [(set (match_operand:DI 0 "register_operand" "=r")
7717 (plus:DI (match_operand:DI 1 "register_operand" "r")
7718 (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7719 (match_operand 3 "tld_symbolic_operand" "")]
7721 "TARGET_TLS && TARGET_ARCH64"
7722 "add\\t%1, %2, %0, %%tldo_add(%a3)")
7724 (define_insn "tie_hi22"
7725 [(set (match_operand:SI 0 "register_operand" "=r")
7726 (high:SI (unspec:SI [(match_operand 1 "tie_symbolic_operand" "")]
7729 "sethi\\t%%tie_hi22(%a1), %0")
7731 (define_insn "tie_lo10"
7732 [(set (match_operand:SI 0 "register_operand" "=r")
7733 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7734 (unspec:SI [(match_operand 2 "tie_symbolic_operand" "")]
7737 "add\\t%1, %%tie_lo10(%a2), %0")
7739 (define_insn "tie_ld32"
7740 [(set (match_operand:SI 0 "register_operand" "=r")
7741 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
7742 (match_operand:SI 2 "register_operand" "r")
7743 (match_operand 3 "tie_symbolic_operand" "")]
7745 "TARGET_TLS && TARGET_ARCH32"
7746 "ld\\t[%1 + %2], %0, %%tie_ld(%a3)"
7747 [(set_attr "type" "load")])
7749 (define_insn "tie_ld64"
7750 [(set (match_operand:DI 0 "register_operand" "=r")
7751 (unspec:DI [(match_operand:DI 1 "register_operand" "r")
7752 (match_operand:SI 2 "register_operand" "r")
7753 (match_operand 3 "tie_symbolic_operand" "")]
7755 "TARGET_TLS && TARGET_ARCH64"
7756 "ldx\\t[%1 + %2], %0, %%tie_ldx(%a3)"
7757 [(set_attr "type" "load")])
7759 (define_insn "tie_add32"
7760 [(set (match_operand:SI 0 "register_operand" "=r")
7761 (plus:SI (match_operand:SI 1 "register_operand" "r")
7762 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7763 (match_operand 3 "tie_symbolic_operand" "")]
7765 "TARGET_SUN_TLS && TARGET_ARCH32"
7766 "add\\t%1, %2, %0, %%tie_add(%a3)")
7768 (define_insn "tie_add64"
7769 [(set (match_operand:DI 0 "register_operand" "=r")
7770 (plus:DI (match_operand:DI 1 "register_operand" "r")
7771 (unspec:DI [(match_operand:DI 2 "register_operand" "r")
7772 (match_operand 3 "tie_symbolic_operand" "")]
7774 "TARGET_SUN_TLS && TARGET_ARCH64"
7775 "add\\t%1, %2, %0, %%tie_add(%a3)")
7777 (define_insn "tle_hix22_sp32"
7778 [(set (match_operand:SI 0 "register_operand" "=r")
7779 (high:SI (unspec:SI [(match_operand 1 "tle_symbolic_operand" "")]
7781 "TARGET_TLS && TARGET_ARCH32"
7782 "sethi\\t%%tle_hix22(%a1), %0")
7784 (define_insn "tle_lox10_sp32"
7785 [(set (match_operand:SI 0 "register_operand" "=r")
7786 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7787 (unspec:SI [(match_operand 2 "tle_symbolic_operand" "")]
7789 "TARGET_TLS && TARGET_ARCH32"
7790 "xor\\t%1, %%tle_lox10(%a2), %0")
7792 (define_insn "tle_hix22_sp64"
7793 [(set (match_operand:DI 0 "register_operand" "=r")
7794 (high:DI (unspec:DI [(match_operand 1 "tle_symbolic_operand" "")]
7796 "TARGET_TLS && TARGET_ARCH64"
7797 "sethi\\t%%tle_hix22(%a1), %0")
7799 (define_insn "tle_lox10_sp64"
7800 [(set (match_operand:DI 0 "register_operand" "=r")
7801 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
7802 (unspec:DI [(match_operand 2 "tle_symbolic_operand" "")]
7804 "TARGET_TLS && TARGET_ARCH64"
7805 "xor\\t%1, %%tle_lox10(%a2), %0")
7807 ;; Now patterns combining tldo_add{32,64} with some integer loads or stores
7808 (define_insn "*tldo_ldub_sp32"
7809 [(set (match_operand:QI 0 "register_operand" "=r")
7810 (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7811 (match_operand 3 "tld_symbolic_operand" "")]
7813 (match_operand:SI 1 "register_operand" "r"))))]
7814 "TARGET_TLS && TARGET_ARCH32"
7815 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7816 [(set_attr "type" "load")
7817 (set_attr "us3load_type" "3cycle")])
7819 (define_insn "*tldo_ldub1_sp32"
7820 [(set (match_operand:HI 0 "register_operand" "=r")
7821 (zero_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7822 (match_operand 3 "tld_symbolic_operand" "")]
7824 (match_operand:SI 1 "register_operand" "r")))))]
7825 "TARGET_TLS && TARGET_ARCH32"
7826 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7827 [(set_attr "type" "load")
7828 (set_attr "us3load_type" "3cycle")])
7830 (define_insn "*tldo_ldub2_sp32"
7831 [(set (match_operand:SI 0 "register_operand" "=r")
7832 (zero_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7833 (match_operand 3 "tld_symbolic_operand" "")]
7835 (match_operand:SI 1 "register_operand" "r")))))]
7836 "TARGET_TLS && TARGET_ARCH32"
7837 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7838 [(set_attr "type" "load")
7839 (set_attr "us3load_type" "3cycle")])
7841 (define_insn "*tldo_ldsb1_sp32"
7842 [(set (match_operand:HI 0 "register_operand" "=r")
7843 (sign_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7844 (match_operand 3 "tld_symbolic_operand" "")]
7846 (match_operand:SI 1 "register_operand" "r")))))]
7847 "TARGET_TLS && TARGET_ARCH32"
7848 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7849 [(set_attr "type" "sload")
7850 (set_attr "us3load_type" "3cycle")])
7852 (define_insn "*tldo_ldsb2_sp32"
7853 [(set (match_operand:SI 0 "register_operand" "=r")
7854 (sign_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7855 (match_operand 3 "tld_symbolic_operand" "")]
7857 (match_operand:SI 1 "register_operand" "r")))))]
7858 "TARGET_TLS && TARGET_ARCH32"
7859 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7860 [(set_attr "type" "sload")
7861 (set_attr "us3load_type" "3cycle")])
7863 (define_insn "*tldo_ldub_sp64"
7864 [(set (match_operand:QI 0 "register_operand" "=r")
7865 (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7866 (match_operand 3 "tld_symbolic_operand" "")]
7868 (match_operand:DI 1 "register_operand" "r"))))]
7869 "TARGET_TLS && TARGET_ARCH64"
7870 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7871 [(set_attr "type" "load")
7872 (set_attr "us3load_type" "3cycle")])
7874 (define_insn "*tldo_ldub1_sp64"
7875 [(set (match_operand:HI 0 "register_operand" "=r")
7876 (zero_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7877 (match_operand 3 "tld_symbolic_operand" "")]
7879 (match_operand:DI 1 "register_operand" "r")))))]
7880 "TARGET_TLS && TARGET_ARCH64"
7881 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7882 [(set_attr "type" "load")
7883 (set_attr "us3load_type" "3cycle")])
7885 (define_insn "*tldo_ldub2_sp64"
7886 [(set (match_operand:SI 0 "register_operand" "=r")
7887 (zero_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7888 (match_operand 3 "tld_symbolic_operand" "")]
7890 (match_operand:DI 1 "register_operand" "r")))))]
7891 "TARGET_TLS && TARGET_ARCH64"
7892 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7893 [(set_attr "type" "load")
7894 (set_attr "us3load_type" "3cycle")])
7896 (define_insn "*tldo_ldub3_sp64"
7897 [(set (match_operand:DI 0 "register_operand" "=r")
7898 (zero_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7899 (match_operand 3 "tld_symbolic_operand" "")]
7901 (match_operand:DI 1 "register_operand" "r")))))]
7902 "TARGET_TLS && TARGET_ARCH64"
7903 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7904 [(set_attr "type" "load")
7905 (set_attr "us3load_type" "3cycle")])
7907 (define_insn "*tldo_ldsb1_sp64"
7908 [(set (match_operand:HI 0 "register_operand" "=r")
7909 (sign_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7910 (match_operand 3 "tld_symbolic_operand" "")]
7912 (match_operand:DI 1 "register_operand" "r")))))]
7913 "TARGET_TLS && TARGET_ARCH64"
7914 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7915 [(set_attr "type" "sload")
7916 (set_attr "us3load_type" "3cycle")])
7918 (define_insn "*tldo_ldsb2_sp64"
7919 [(set (match_operand:SI 0 "register_operand" "=r")
7920 (sign_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7921 (match_operand 3 "tld_symbolic_operand" "")]
7923 (match_operand:DI 1 "register_operand" "r")))))]
7924 "TARGET_TLS && TARGET_ARCH64"
7925 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7926 [(set_attr "type" "sload")
7927 (set_attr "us3load_type" "3cycle")])
7929 (define_insn "*tldo_ldsb3_sp64"
7930 [(set (match_operand:DI 0 "register_operand" "=r")
7931 (sign_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7932 (match_operand 3 "tld_symbolic_operand" "")]
7934 (match_operand:DI 1 "register_operand" "r")))))]
7935 "TARGET_TLS && TARGET_ARCH64"
7936 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7937 [(set_attr "type" "sload")
7938 (set_attr "us3load_type" "3cycle")])
7940 (define_insn "*tldo_lduh_sp32"
7941 [(set (match_operand:HI 0 "register_operand" "=r")
7942 (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7943 (match_operand 3 "tld_symbolic_operand" "")]
7945 (match_operand:SI 1 "register_operand" "r"))))]
7946 "TARGET_TLS && TARGET_ARCH32"
7947 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7948 [(set_attr "type" "load")
7949 (set_attr "us3load_type" "3cycle")])
7951 (define_insn "*tldo_lduh1_sp32"
7952 [(set (match_operand:SI 0 "register_operand" "=r")
7953 (zero_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7954 (match_operand 3 "tld_symbolic_operand" "")]
7956 (match_operand:SI 1 "register_operand" "r")))))]
7957 "TARGET_TLS && TARGET_ARCH32"
7958 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7959 [(set_attr "type" "load")
7960 (set_attr "us3load_type" "3cycle")])
7962 (define_insn "*tldo_ldsh1_sp32"
7963 [(set (match_operand:SI 0 "register_operand" "=r")
7964 (sign_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7965 (match_operand 3 "tld_symbolic_operand" "")]
7967 (match_operand:SI 1 "register_operand" "r")))))]
7968 "TARGET_TLS && TARGET_ARCH32"
7969 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
7970 [(set_attr "type" "sload")
7971 (set_attr "us3load_type" "3cycle")])
7973 (define_insn "*tldo_lduh_sp64"
7974 [(set (match_operand:HI 0 "register_operand" "=r")
7975 (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7976 (match_operand 3 "tld_symbolic_operand" "")]
7978 (match_operand:DI 1 "register_operand" "r"))))]
7979 "TARGET_TLS && TARGET_ARCH64"
7980 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7981 [(set_attr "type" "load")
7982 (set_attr "us3load_type" "3cycle")])
7984 (define_insn "*tldo_lduh1_sp64"
7985 [(set (match_operand:SI 0 "register_operand" "=r")
7986 (zero_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7987 (match_operand 3 "tld_symbolic_operand" "")]
7989 (match_operand:DI 1 "register_operand" "r")))))]
7990 "TARGET_TLS && TARGET_ARCH64"
7991 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7992 [(set_attr "type" "load")
7993 (set_attr "us3load_type" "3cycle")])
7995 (define_insn "*tldo_lduh2_sp64"
7996 [(set (match_operand:DI 0 "register_operand" "=r")
7997 (zero_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7998 (match_operand 3 "tld_symbolic_operand" "")]
8000 (match_operand:DI 1 "register_operand" "r")))))]
8001 "TARGET_TLS && TARGET_ARCH64"
8002 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
8003 [(set_attr "type" "load")
8004 (set_attr "us3load_type" "3cycle")])
8006 (define_insn "*tldo_ldsh1_sp64"
8007 [(set (match_operand:SI 0 "register_operand" "=r")
8008 (sign_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8009 (match_operand 3 "tld_symbolic_operand" "")]
8011 (match_operand:DI 1 "register_operand" "r")))))]
8012 "TARGET_TLS && TARGET_ARCH64"
8013 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
8014 [(set_attr "type" "sload")
8015 (set_attr "us3load_type" "3cycle")])
8017 (define_insn "*tldo_ldsh2_sp64"
8018 [(set (match_operand:DI 0 "register_operand" "=r")
8019 (sign_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8020 (match_operand 3 "tld_symbolic_operand" "")]
8022 (match_operand:DI 1 "register_operand" "r")))))]
8023 "TARGET_TLS && TARGET_ARCH64"
8024 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
8025 [(set_attr "type" "sload")
8026 (set_attr "us3load_type" "3cycle")])
8028 (define_insn "*tldo_lduw_sp32"
8029 [(set (match_operand:SI 0 "register_operand" "=r")
8030 (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8031 (match_operand 3 "tld_symbolic_operand" "")]
8033 (match_operand:SI 1 "register_operand" "r"))))]
8034 "TARGET_TLS && TARGET_ARCH32"
8035 "ld\t[%1 + %2], %0, %%tldo_add(%3)"
8036 [(set_attr "type" "load")])
8038 (define_insn "*tldo_lduw_sp64"
8039 [(set (match_operand:SI 0 "register_operand" "=r")
8040 (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8041 (match_operand 3 "tld_symbolic_operand" "")]
8043 (match_operand:DI 1 "register_operand" "r"))))]
8044 "TARGET_TLS && TARGET_ARCH64"
8045 "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
8046 [(set_attr "type" "load")])
8048 (define_insn "*tldo_lduw1_sp64"
8049 [(set (match_operand:DI 0 "register_operand" "=r")
8050 (zero_extend:DI (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8051 (match_operand 3 "tld_symbolic_operand" "")]
8053 (match_operand:DI 1 "register_operand" "r")))))]
8054 "TARGET_TLS && TARGET_ARCH64"
8055 "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
8056 [(set_attr "type" "load")])
8058 (define_insn "*tldo_ldsw1_sp64"
8059 [(set (match_operand:DI 0 "register_operand" "=r")
8060 (sign_extend:DI (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8061 (match_operand 3 "tld_symbolic_operand" "")]
8063 (match_operand:DI 1 "register_operand" "r")))))]
8064 "TARGET_TLS && TARGET_ARCH64"
8065 "ldsw\t[%1 + %2], %0, %%tldo_add(%3)"
8066 [(set_attr "type" "sload")
8067 (set_attr "us3load_type" "3cycle")])
8069 (define_insn "*tldo_ldx_sp64"
8070 [(set (match_operand:DI 0 "register_operand" "=r")
8071 (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8072 (match_operand 3 "tld_symbolic_operand" "")]
8074 (match_operand:DI 1 "register_operand" "r"))))]
8075 "TARGET_TLS && TARGET_ARCH64"
8076 "ldx\t[%1 + %2], %0, %%tldo_add(%3)"
8077 [(set_attr "type" "load")])
8079 (define_insn "*tldo_stb_sp32"
8080 [(set (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8081 (match_operand 3 "tld_symbolic_operand" "")]
8083 (match_operand:SI 1 "register_operand" "r")))
8084 (match_operand:QI 0 "register_operand" "=r"))]
8085 "TARGET_TLS && TARGET_ARCH32"
8086 "stb\t%0, [%1 + %2], %%tldo_add(%3)"
8087 [(set_attr "type" "store")])
8089 (define_insn "*tldo_stb_sp64"
8090 [(set (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8091 (match_operand 3 "tld_symbolic_operand" "")]
8093 (match_operand:DI 1 "register_operand" "r")))
8094 (match_operand:QI 0 "register_operand" "=r"))]
8095 "TARGET_TLS && TARGET_ARCH64"
8096 "stb\t%0, [%1 + %2], %%tldo_add(%3)"
8097 [(set_attr "type" "store")])
8099 (define_insn "*tldo_sth_sp32"
8100 [(set (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8101 (match_operand 3 "tld_symbolic_operand" "")]
8103 (match_operand:SI 1 "register_operand" "r")))
8104 (match_operand:HI 0 "register_operand" "=r"))]
8105 "TARGET_TLS && TARGET_ARCH32"
8106 "sth\t%0, [%1 + %2], %%tldo_add(%3)"
8107 [(set_attr "type" "store")])
8109 (define_insn "*tldo_sth_sp64"
8110 [(set (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8111 (match_operand 3 "tld_symbolic_operand" "")]
8113 (match_operand:DI 1 "register_operand" "r")))
8114 (match_operand:HI 0 "register_operand" "=r"))]
8115 "TARGET_TLS && TARGET_ARCH64"
8116 "sth\t%0, [%1 + %2], %%tldo_add(%3)"
8117 [(set_attr "type" "store")])
8119 (define_insn "*tldo_stw_sp32"
8120 [(set (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8121 (match_operand 3 "tld_symbolic_operand" "")]
8123 (match_operand:SI 1 "register_operand" "r")))
8124 (match_operand:SI 0 "register_operand" "=r"))]
8125 "TARGET_TLS && TARGET_ARCH32"
8126 "st\t%0, [%1 + %2], %%tldo_add(%3)"
8127 [(set_attr "type" "store")])
8129 (define_insn "*tldo_stw_sp64"
8130 [(set (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8131 (match_operand 3 "tld_symbolic_operand" "")]
8133 (match_operand:DI 1 "register_operand" "r")))
8134 (match_operand:SI 0 "register_operand" "=r"))]
8135 "TARGET_TLS && TARGET_ARCH64"
8136 "stw\t%0, [%1 + %2], %%tldo_add(%3)"
8137 [(set_attr "type" "store")])
8139 (define_insn "*tldo_stx_sp64"
8140 [(set (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8141 (match_operand 3 "tld_symbolic_operand" "")]
8143 (match_operand:DI 1 "register_operand" "r")))
8144 (match_operand:DI 0 "register_operand" "=r"))]
8145 "TARGET_TLS && TARGET_ARCH64"
8146 "stx\t%0, [%1 + %2], %%tldo_add(%3)"
8147 [(set_attr "type" "store")])
8150 ;; Stack protector instructions.
8152 (define_expand "stack_protect_set"
8153 [(match_operand 0 "memory_operand" "")
8154 (match_operand 1 "memory_operand" "")]
8157 #ifdef TARGET_THREAD_SSP_OFFSET
8158 rtx tlsreg = gen_rtx_REG (Pmode, 7);
8159 rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
8160 operands[1] = gen_rtx_MEM (Pmode, addr);
8163 emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
8165 emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
8169 (define_insn "stack_protect_setsi"
8170 [(set (match_operand:SI 0 "memory_operand" "=m")
8171 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
8172 (set (match_scratch:SI 2 "=&r") (const_int 0))]
8174 "ld\t%1, %2\;st\t%2, %0\;mov\t0, %2"
8175 [(set_attr "type" "multi")
8176 (set_attr "length" "3")])
8178 (define_insn "stack_protect_setdi"
8179 [(set (match_operand:DI 0 "memory_operand" "=m")
8180 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
8181 (set (match_scratch:DI 2 "=&r") (const_int 0))]
8183 "ldx\t%1, %2\;stx\t%2, %0\;mov\t0, %2"
8184 [(set_attr "type" "multi")
8185 (set_attr "length" "3")])
8187 (define_expand "stack_protect_test"
8188 [(match_operand 0 "memory_operand" "")
8189 (match_operand 1 "memory_operand" "")
8190 (match_operand 2 "" "")]
8193 #ifdef TARGET_THREAD_SSP_OFFSET
8194 rtx tlsreg = gen_rtx_REG (Pmode, 7);
8195 rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
8196 operands[1] = gen_rtx_MEM (Pmode, addr);
8200 rtx temp = gen_reg_rtx (Pmode);
8201 emit_insn (gen_stack_protect_testdi (temp, operands[0], operands[1]));
8202 sparc_compare_op0 = temp;
8203 sparc_compare_op1 = const0_rtx;
8207 emit_insn (gen_stack_protect_testsi (operands[0], operands[1]));
8208 sparc_compare_op0 = operands[0];
8209 sparc_compare_op1 = operands[1];
8210 sparc_compare_emitted = gen_rtx_REG (CCmode, SPARC_ICC_REG);
8212 emit_jump_insn (gen_beq (operands[2]));
8216 (define_insn "stack_protect_testsi"
8218 (unspec:CC [(match_operand:SI 0 "memory_operand" "m")
8219 (match_operand:SI 1 "memory_operand" "m")]
8221 (set (match_scratch:SI 3 "=r") (const_int 0))
8222 (clobber (match_scratch:SI 2 "=&r"))]
8224 "ld\t%0, %2\;ld\t%1, %3\;xorcc\t%2, %3, %2\;mov\t0, %3"
8225 [(set_attr "type" "multi")
8226 (set_attr "length" "4")])
8228 (define_insn "stack_protect_testdi"
8229 [(set (match_operand:DI 0 "register_operand" "=&r")
8230 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
8231 (match_operand:DI 2 "memory_operand" "m")]
8233 (set (match_scratch:DI 3 "=r") (const_int 0))]
8235 "ldx\t%1, %0\;ldx\t%2, %3\;xor\t%0, %3, %0\;mov\t0, %3"
8236 [(set_attr "type" "multi")
8237 (set_attr "length" "4")])
8240 ;; Vector instructions.
8242 (define_insn "addv2si3"
8243 [(set (match_operand:V2SI 0 "register_operand" "=e")
8244 (plus:V2SI (match_operand:V2SI 1 "register_operand" "e")
8245 (match_operand:V2SI 2 "register_operand" "e")))]
8247 "fpadd32\t%1, %2, %0"
8248 [(set_attr "type" "fga")
8249 (set_attr "fptype" "double")])
8251 (define_insn "addv4hi3"
8252 [(set (match_operand:V4HI 0 "register_operand" "=e")
8253 (plus:V4HI (match_operand:V4HI 1 "register_operand" "e")
8254 (match_operand:V4HI 2 "register_operand" "e")))]
8256 "fpadd16\t%1, %2, %0"
8257 [(set_attr "type" "fga")
8258 (set_attr "fptype" "double")])
8260 ;; fpadd32s is emitted by the addsi3 pattern.
8262 (define_insn "addv2hi3"
8263 [(set (match_operand:V2HI 0 "register_operand" "=f")
8264 (plus:V2HI (match_operand:V2HI 1 "register_operand" "f")
8265 (match_operand:V2HI 2 "register_operand" "f")))]
8267 "fpadd16s\t%1, %2, %0"
8268 [(set_attr "type" "fga")
8269 (set_attr "fptype" "single")])
8271 (define_insn "subv2si3"
8272 [(set (match_operand:V2SI 0 "register_operand" "=e")
8273 (minus:V2SI (match_operand:V2SI 1 "register_operand" "e")
8274 (match_operand:V2SI 2 "register_operand" "e")))]
8276 "fpsub32\t%1, %2, %0"
8277 [(set_attr "type" "fga")
8278 (set_attr "fptype" "double")])
8280 (define_insn "subv4hi3"
8281 [(set (match_operand:V4HI 0 "register_operand" "=e")
8282 (minus:V4HI (match_operand:V4HI 1 "register_operand" "e")
8283 (match_operand:V4HI 2 "register_operand" "e")))]
8285 "fpsub16\t%1, %2, %0"
8286 [(set_attr "type" "fga")
8287 (set_attr "fptype" "double")])
8289 ;; fpsub32s is emitted by the subsi3 pattern.
8291 (define_insn "subv2hi3"
8292 [(set (match_operand:V2HI 0 "register_operand" "=f")
8293 (minus:V2HI (match_operand:V2HI 1 "register_operand" "f")
8294 (match_operand:V2HI 2 "register_operand" "f")))]
8296 "fpsub16s\t%1, %2, %0"
8297 [(set_attr "type" "fga")
8298 (set_attr "fptype" "single")])
8300 ;; All other logical instructions have integer equivalents so they
8301 ;; are defined together.
8303 ;; (ior (not (op1)) (not (op2))) is the canonical form of NAND.
8305 (define_insn "*nand<V64mode>_vis"
8306 [(set (match_operand:V64 0 "register_operand" "=e")
8307 (ior:V64 (not:V64 (match_operand:V64 1 "register_operand" "e"))
8308 (not:V64 (match_operand:V64 2 "register_operand" "e"))))]
8311 [(set_attr "type" "fga")
8312 (set_attr "fptype" "double")])
8314 (define_insn "*nand<V32mode>_vis"
8315 [(set (match_operand:V32 0 "register_operand" "=f")
8316 (ior:V32 (not:V32 (match_operand:V32 1 "register_operand" "f"))
8317 (not:V32 (match_operand:V32 2 "register_operand" "f"))))]
8319 "fnands\t%1, %2, %0"
8320 [(set_attr "type" "fga")
8321 (set_attr "fptype" "single")])
8323 ;; Hard to generate VIS instructions. We have builtins for these.
8325 (define_insn "fpack16_vis"
8326 [(set (match_operand:V4QI 0 "register_operand" "=f")
8327 (unspec:V4QI [(match_operand:V4HI 1 "register_operand" "e")]
8331 [(set_attr "type" "fga")
8332 (set_attr "fptype" "double")])
8334 (define_insn "fpackfix_vis"
8335 [(set (match_operand:V2HI 0 "register_operand" "=f")
8336 (unspec:V2HI [(match_operand:V2SI 1 "register_operand" "e")]
8340 [(set_attr "type" "fga")
8341 (set_attr "fptype" "double")])
8343 (define_insn "fpack32_vis"
8344 [(set (match_operand:V8QI 0 "register_operand" "=e")
8345 (unspec:V8QI [(match_operand:V2SI 1 "register_operand" "e")
8346 (match_operand:V8QI 2 "register_operand" "e")]
8349 "fpack32\t%1, %2, %0"
8350 [(set_attr "type" "fga")
8351 (set_attr "fptype" "double")])
8353 (define_insn "fexpand_vis"
8354 [(set (match_operand:V4HI 0 "register_operand" "=e")
8355 (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")]
8359 [(set_attr "type" "fga")
8360 (set_attr "fptype" "double")])
8362 ;; It may be possible to describe this operation as (1 indexed):
8363 ;; (vec_select (vec_duplicate (vec_duplicate (vec_concat 1 2)))
8364 ;; 1,5,10,14,19,23,28,32)
8365 ;; Note that (vec_merge:V8QI [(V4QI) (V4QI)] (10101010 = 170) doesn't work
8366 ;; because vec_merge expects all the operands to be of the same type.
8367 (define_insn "fpmerge_vis"
8368 [(set (match_operand:V8QI 0 "register_operand" "=e")
8369 (unspec:V8QI [(match_operand:V4QI 1 "register_operand" "f")
8370 (match_operand:V4QI 2 "register_operand" "f")]
8373 "fpmerge\t%1, %2, %0"
8374 [(set_attr "type" "fga")
8375 (set_attr "fptype" "double")])
8377 ;; Partitioned multiply instructions
8378 (define_insn "fmul8x16_vis"
8379 [(set (match_operand:V4HI 0 "register_operand" "=e")
8380 (mult:V4HI (match_operand:V4QI 1 "register_operand" "f")
8381 (match_operand:V4HI 2 "register_operand" "e")))]
8383 "fmul8x16\t%1, %2, %0"
8384 [(set_attr "type" "fpmul")
8385 (set_attr "fptype" "double")])
8387 ;; Only one of the following two insns can be a multiply.
8388 (define_insn "fmul8x16au_vis"
8389 [(set (match_operand:V4HI 0 "register_operand" "=e")
8390 (mult:V4HI (match_operand:V4QI 1 "register_operand" "f")
8391 (match_operand:V2HI 2 "register_operand" "f")))]
8393 "fmul8x16au\t%1, %2, %0"
8394 [(set_attr "type" "fpmul")
8395 (set_attr "fptype" "double")])
8397 (define_insn "fmul8x16al_vis"
8398 [(set (match_operand:V4HI 0 "register_operand" "=e")
8399 (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")
8400 (match_operand:V2HI 2 "register_operand" "f")]
8403 "fmul8x16al\t%1, %2, %0"
8404 [(set_attr "type" "fpmul")
8405 (set_attr "fptype" "double")])
8407 ;; Only one of the following two insns can be a multiply.
8408 (define_insn "fmul8sux16_vis"
8409 [(set (match_operand:V4HI 0 "register_operand" "=e")
8410 (mult:V4HI (match_operand:V8QI 1 "register_operand" "e")
8411 (match_operand:V4HI 2 "register_operand" "e")))]
8413 "fmul8sux16\t%1, %2, %0"
8414 [(set_attr "type" "fpmul")
8415 (set_attr "fptype" "double")])
8417 (define_insn "fmul8ulx16_vis"
8418 [(set (match_operand:V4HI 0 "register_operand" "=e")
8419 (unspec:V4HI [(match_operand:V8QI 1 "register_operand" "e")
8420 (match_operand:V4HI 2 "register_operand" "e")]
8423 "fmul8ulx16\t%1, %2, %0"
8424 [(set_attr "type" "fpmul")
8425 (set_attr "fptype" "double")])
8427 ;; Only one of the following two insns can be a multiply.
8428 (define_insn "fmuld8sux16_vis"
8429 [(set (match_operand:V2SI 0 "register_operand" "=e")
8430 (mult:V2SI (match_operand:V4QI 1 "register_operand" "f")
8431 (match_operand:V2HI 2 "register_operand" "f")))]
8433 "fmuld8sux16\t%1, %2, %0"
8434 [(set_attr "type" "fpmul")
8435 (set_attr "fptype" "double")])
8437 (define_insn "fmuld8ulx16_vis"
8438 [(set (match_operand:V2SI 0 "register_operand" "=e")
8439 (unspec:V2SI [(match_operand:V4QI 1 "register_operand" "f")
8440 (match_operand:V2HI 2 "register_operand" "f")]
8443 "fmuld8ulx16\t%1, %2, %0"
8444 [(set_attr "type" "fpmul")
8445 (set_attr "fptype" "double")])
8447 ;; Using faligndata only makes sense after an alignaddr since the choice of
8448 ;; bytes to take out of each operand is dependent on the results of the last
8450 (define_insn "faligndata<V64I:mode>_vis"
8451 [(set (match_operand:V64I 0 "register_operand" "=e")
8452 (unspec:V64I [(match_operand:V64I 1 "register_operand" "e")
8453 (match_operand:V64I 2 "register_operand" "e")]
8456 "faligndata\t%1, %2, %0"
8457 [(set_attr "type" "fga")
8458 (set_attr "fptype" "double")])
8460 (define_insn "alignaddr<P:mode>_vis"
8461 [(set (match_operand:P 0 "register_operand" "=r")
8462 (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
8463 (match_operand:P 2 "register_or_zero_operand" "rJ")]
8466 "alignaddr\t%r1, %r2, %0")
8468 (define_insn "pdist_vis"
8469 [(set (match_operand:DI 0 "register_operand" "=e")
8470 (unspec:DI [(match_operand:V8QI 1 "register_operand" "e")
8471 (match_operand:V8QI 2 "register_operand" "e")
8472 (match_operand:DI 3 "register_operand" "0")]
8476 [(set_attr "type" "fga")
8477 (set_attr "fptype" "double")])