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)
74 ;; The upper 32 fp regs on the v9 can't hold SFmode values. To deal with this
75 ;; a second register class, EXTRA_FP_REGS, exists for the v9 chip. The name
76 ;; is a bit of a misnomer as it covers all 64 fp regs. The corresponding
77 ;; constraint letter is 'e'. To avoid any confusion, 'e' is used instead of
78 ;; 'f' for all DF/TFmode values, including those that are specific to the v8.
81 ;; Attribute for cpu type.
82 ;; These must match the values for enum processor_type in sparc.h.
89 hypersparc,sparclite86x,
94 (const (symbol_ref "sparc_cpu_attr")))
96 ;; Attribute for the instruction set.
97 ;; At present we only need to distinguish v9/!v9, but for clarity we
98 ;; test TARGET_V8 too.
99 (define_attr "isa" "v7,v8,v9,sparclet"
101 (cond [(symbol_ref "TARGET_V9") (const_string "v9")
102 (symbol_ref "TARGET_V8") (const_string "v8")
103 (symbol_ref "TARGET_SPARCLET") (const_string "sparclet")]
104 (const_string "v7"))))
110 uncond_branch,branch,call,sibcall,call_no_delay_slot,return,
118 fga,fgm_pack,fgm_mul,fgm_pdist,fgm_cmp,
121 multi,savew,flushw,iflush,trap"
122 (const_string "ialu"))
124 ;; True if branch/call has empty delay slot and will emit a nop in it
125 (define_attr "empty_delay_slot" "false,true"
126 (symbol_ref "empty_delay_slot (insn)"))
128 (define_attr "branch_type" "none,icc,fcc,reg"
129 (const_string "none"))
131 (define_attr "pic" "false,true"
132 (symbol_ref "flag_pic != 0"))
134 (define_attr "calls_alloca" "false,true"
135 (symbol_ref "current_function_calls_alloca != 0"))
137 (define_attr "calls_eh_return" "false,true"
138 (symbol_ref "current_function_calls_eh_return !=0 "))
140 (define_attr "leaf_function" "false,true"
141 (symbol_ref "current_function_uses_only_leaf_regs != 0"))
143 (define_attr "delayed_branch" "false,true"
144 (symbol_ref "flag_delayed_branch != 0"))
146 ;; Length (in # of insns).
147 ;; Beware that setting a length greater or equal to 3 for conditional branches
148 ;; has a side-effect (see output_cbranch and output_v9branch).
149 (define_attr "length" ""
150 (cond [(eq_attr "type" "uncond_branch,call")
151 (if_then_else (eq_attr "empty_delay_slot" "true")
154 (eq_attr "type" "sibcall")
155 (if_then_else (eq_attr "leaf_function" "true")
156 (if_then_else (eq_attr "empty_delay_slot" "true")
159 (if_then_else (eq_attr "empty_delay_slot" "true")
162 (eq_attr "branch_type" "icc")
163 (if_then_else (match_operand 0 "noov_compare64_operator" "")
164 (if_then_else (lt (pc) (match_dup 1))
165 (if_then_else (lt (minus (match_dup 1) (pc)) (const_int 260000))
166 (if_then_else (eq_attr "empty_delay_slot" "true")
169 (if_then_else (eq_attr "empty_delay_slot" "true")
172 (if_then_else (lt (minus (pc) (match_dup 1)) (const_int 260000))
173 (if_then_else (eq_attr "empty_delay_slot" "true")
176 (if_then_else (eq_attr "empty_delay_slot" "true")
179 (if_then_else (eq_attr "empty_delay_slot" "true")
182 (eq_attr "branch_type" "fcc")
183 (if_then_else (match_operand 0 "fcc0_register_operand" "")
184 (if_then_else (eq_attr "empty_delay_slot" "true")
185 (if_then_else (eq (symbol_ref "TARGET_V9") (const_int 0))
188 (if_then_else (eq (symbol_ref "TARGET_V9") (const_int 0))
191 (if_then_else (lt (pc) (match_dup 2))
192 (if_then_else (lt (minus (match_dup 2) (pc)) (const_int 260000))
193 (if_then_else (eq_attr "empty_delay_slot" "true")
196 (if_then_else (eq_attr "empty_delay_slot" "true")
199 (if_then_else (lt (minus (pc) (match_dup 2)) (const_int 260000))
200 (if_then_else (eq_attr "empty_delay_slot" "true")
203 (if_then_else (eq_attr "empty_delay_slot" "true")
206 (eq_attr "branch_type" "reg")
207 (if_then_else (lt (pc) (match_dup 2))
208 (if_then_else (lt (minus (match_dup 2) (pc)) (const_int 32000))
209 (if_then_else (eq_attr "empty_delay_slot" "true")
212 (if_then_else (eq_attr "empty_delay_slot" "true")
215 (if_then_else (lt (minus (pc) (match_dup 2)) (const_int 32000))
216 (if_then_else (eq_attr "empty_delay_slot" "true")
219 (if_then_else (eq_attr "empty_delay_slot" "true")
225 (define_attr "fptype" "single,double"
226 (const_string "single"))
228 ;; UltraSPARC-III integer load type.
229 (define_attr "us3load_type" "2cycle,3cycle"
230 (const_string "2cycle"))
232 (define_asm_attributes
233 [(set_attr "length" "2")
234 (set_attr "type" "multi")])
236 ;; Attributes for instruction and branch scheduling
237 (define_attr "tls_call_delay" "false,true"
238 (symbol_ref "tls_call_delay (insn)"))
240 (define_attr "in_call_delay" "false,true"
241 (cond [(eq_attr "type" "uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
242 (const_string "false")
243 (eq_attr "type" "load,fpload,store,fpstore")
244 (if_then_else (eq_attr "length" "1")
245 (const_string "true")
246 (const_string "false"))]
247 (if_then_else (and (eq_attr "length" "1")
248 (eq_attr "tls_call_delay" "true"))
249 (const_string "true")
250 (const_string "false"))))
252 (define_attr "eligible_for_sibcall_delay" "false,true"
253 (symbol_ref "eligible_for_sibcall_delay (insn)"))
255 (define_attr "eligible_for_return_delay" "false,true"
256 (symbol_ref "eligible_for_return_delay (insn)"))
258 ;; ??? !v9: Should implement the notion of predelay slots for floating-point
259 ;; branches. This would allow us to remove the nop always inserted before
260 ;; a floating point branch.
262 ;; ??? It is OK for fill_simple_delay_slots to put load/store instructions
263 ;; in a delay slot, but it is not OK for fill_eager_delay_slots to do so.
264 ;; This is because doing so will add several pipeline stalls to the path
265 ;; that the load/store did not come from. Unfortunately, there is no way
266 ;; to prevent fill_eager_delay_slots from using load/store without completely
267 ;; disabling them. For the SPEC benchmark set, this is a serious lose,
268 ;; because it prevents us from moving back the final store of inner loops.
270 (define_attr "in_branch_delay" "false,true"
271 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
272 (eq_attr "length" "1"))
273 (const_string "true")
274 (const_string "false")))
276 (define_attr "in_uncond_branch_delay" "false,true"
277 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
278 (eq_attr "length" "1"))
279 (const_string "true")
280 (const_string "false")))
282 (define_attr "in_annul_branch_delay" "false,true"
283 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
284 (eq_attr "length" "1"))
285 (const_string "true")
286 (const_string "false")))
288 (define_delay (eq_attr "type" "call")
289 [(eq_attr "in_call_delay" "true") (nil) (nil)])
291 (define_delay (eq_attr "type" "sibcall")
292 [(eq_attr "eligible_for_sibcall_delay" "true") (nil) (nil)])
294 (define_delay (eq_attr "type" "branch")
295 [(eq_attr "in_branch_delay" "true")
296 (nil) (eq_attr "in_annul_branch_delay" "true")])
298 (define_delay (eq_attr "type" "uncond_branch")
299 [(eq_attr "in_uncond_branch_delay" "true")
302 (define_delay (eq_attr "type" "return")
303 [(eq_attr "eligible_for_return_delay" "true") (nil) (nil)])
306 ;; Include SPARC DFA schedulers
308 (include "cypress.md")
309 (include "supersparc.md")
310 (include "hypersparc.md")
311 (include "sparclet.md")
312 (include "ultra1_2.md")
313 (include "ultra3.md")
316 ;; Operand and operator predicates.
318 (include "predicates.md")
321 ;; Compare instructions.
323 ;; We generate RTL for comparisons and branches by having the cmpxx
324 ;; patterns store away the operands. Then, the scc and bcc patterns
325 ;; emit RTL for both the compare and the branch.
327 ;; We do this because we want to generate different code for an sne and
328 ;; seq insn. In those cases, if the second operand of the compare is not
329 ;; const0_rtx, we want to compute the xor of the two operands and test
332 ;; We start with the DEFINE_EXPANDs, then the DEFINE_INSNs to match
333 ;; the patterns. Finally, we have the DEFINE_SPLITs for some of the scc
334 ;; insns that actually require more than one machine instruction.
336 (define_expand "cmpsi"
338 (compare:CC (match_operand:SI 0 "compare_operand" "")
339 (match_operand:SI 1 "arith_operand" "")))]
342 if (GET_CODE (operands[0]) == ZERO_EXTRACT && operands[1] != const0_rtx)
343 operands[0] = force_reg (SImode, operands[0]);
345 sparc_compare_op0 = operands[0];
346 sparc_compare_op1 = operands[1];
350 (define_expand "cmpdi"
352 (compare:CCX (match_operand:DI 0 "compare_operand" "")
353 (match_operand:DI 1 "arith_operand" "")))]
356 if (GET_CODE (operands[0]) == ZERO_EXTRACT && operands[1] != const0_rtx)
357 operands[0] = force_reg (DImode, operands[0]);
359 sparc_compare_op0 = operands[0];
360 sparc_compare_op1 = operands[1];
364 (define_expand "cmpsf"
365 ;; The 96 here isn't ever used by anyone.
367 (compare:CCFP (match_operand:SF 0 "register_operand" "")
368 (match_operand:SF 1 "register_operand" "")))]
371 sparc_compare_op0 = operands[0];
372 sparc_compare_op1 = operands[1];
376 (define_expand "cmpdf"
377 ;; The 96 here isn't ever used by anyone.
379 (compare:CCFP (match_operand:DF 0 "register_operand" "")
380 (match_operand:DF 1 "register_operand" "")))]
383 sparc_compare_op0 = operands[0];
384 sparc_compare_op1 = operands[1];
388 (define_expand "cmptf"
389 ;; The 96 here isn't ever used by anyone.
391 (compare:CCFP (match_operand:TF 0 "register_operand" "")
392 (match_operand:TF 1 "register_operand" "")))]
395 sparc_compare_op0 = operands[0];
396 sparc_compare_op1 = operands[1];
400 ;; Now the compare DEFINE_INSNs.
402 (define_insn "*cmpsi_insn"
404 (compare:CC (match_operand:SI 0 "register_operand" "r")
405 (match_operand:SI 1 "arith_operand" "rI")))]
408 [(set_attr "type" "compare")])
410 (define_insn "*cmpdi_sp64"
412 (compare:CCX (match_operand:DI 0 "register_operand" "r")
413 (match_operand:DI 1 "arith_operand" "rI")))]
416 [(set_attr "type" "compare")])
418 (define_insn "*cmpsf_fpe"
419 [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
420 (compare:CCFPE (match_operand:SF 1 "register_operand" "f")
421 (match_operand:SF 2 "register_operand" "f")))]
425 return "fcmpes\t%0, %1, %2";
426 return "fcmpes\t%1, %2";
428 [(set_attr "type" "fpcmp")])
430 (define_insn "*cmpdf_fpe"
431 [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
432 (compare:CCFPE (match_operand:DF 1 "register_operand" "e")
433 (match_operand:DF 2 "register_operand" "e")))]
437 return "fcmped\t%0, %1, %2";
438 return "fcmped\t%1, %2";
440 [(set_attr "type" "fpcmp")
441 (set_attr "fptype" "double")])
443 (define_insn "*cmptf_fpe"
444 [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
445 (compare:CCFPE (match_operand:TF 1 "register_operand" "e")
446 (match_operand:TF 2 "register_operand" "e")))]
447 "TARGET_FPU && TARGET_HARD_QUAD"
450 return "fcmpeq\t%0, %1, %2";
451 return "fcmpeq\t%1, %2";
453 [(set_attr "type" "fpcmp")])
455 (define_insn "*cmpsf_fp"
456 [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
457 (compare:CCFP (match_operand:SF 1 "register_operand" "f")
458 (match_operand:SF 2 "register_operand" "f")))]
462 return "fcmps\t%0, %1, %2";
463 return "fcmps\t%1, %2";
465 [(set_attr "type" "fpcmp")])
467 (define_insn "*cmpdf_fp"
468 [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
469 (compare:CCFP (match_operand:DF 1 "register_operand" "e")
470 (match_operand:DF 2 "register_operand" "e")))]
474 return "fcmpd\t%0, %1, %2";
475 return "fcmpd\t%1, %2";
477 [(set_attr "type" "fpcmp")
478 (set_attr "fptype" "double")])
480 (define_insn "*cmptf_fp"
481 [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
482 (compare:CCFP (match_operand:TF 1 "register_operand" "e")
483 (match_operand:TF 2 "register_operand" "e")))]
484 "TARGET_FPU && TARGET_HARD_QUAD"
487 return "fcmpq\t%0, %1, %2";
488 return "fcmpq\t%1, %2";
490 [(set_attr "type" "fpcmp")])
492 ;; Next come the scc insns. For seq, sne, sgeu, and sltu, we can do this
493 ;; without jumps using the addx/subx instructions. For seq/sne on v9 we use
494 ;; the same code as v8 (the addx/subx method has more applications). The
495 ;; exception to this is "reg != 0" which can be done in one instruction on v9
496 ;; (so we do it). For the rest, on v9 we use conditional moves; on v8, we do
499 ;; Seq_special[_xxx] and sne_special[_xxx] clobber the CC reg, because they
500 ;; generate addcc/subcc instructions.
502 (define_expand "seqsi_special"
504 (xor:SI (match_operand:SI 1 "register_operand" "")
505 (match_operand:SI 2 "register_operand" "")))
506 (parallel [(set (match_operand:SI 0 "register_operand" "")
507 (eq:SI (match_dup 3) (const_int 0)))
508 (clobber (reg:CC 100))])]
510 { operands[3] = gen_reg_rtx (SImode); })
512 (define_expand "seqdi_special"
514 (xor:DI (match_operand:DI 1 "register_operand" "")
515 (match_operand:DI 2 "register_operand" "")))
516 (set (match_operand:DI 0 "register_operand" "")
517 (eq:DI (match_dup 3) (const_int 0)))]
519 { operands[3] = gen_reg_rtx (DImode); })
521 (define_expand "snesi_special"
523 (xor:SI (match_operand:SI 1 "register_operand" "")
524 (match_operand:SI 2 "register_operand" "")))
525 (parallel [(set (match_operand:SI 0 "register_operand" "")
526 (ne:SI (match_dup 3) (const_int 0)))
527 (clobber (reg:CC 100))])]
529 { operands[3] = gen_reg_rtx (SImode); })
531 (define_expand "snedi_special"
533 (xor:DI (match_operand:DI 1 "register_operand" "")
534 (match_operand:DI 2 "register_operand" "")))
535 (set (match_operand:DI 0 "register_operand" "")
536 (ne:DI (match_dup 3) (const_int 0)))]
538 { operands[3] = gen_reg_rtx (DImode); })
540 (define_expand "seqdi_special_trunc"
542 (xor:DI (match_operand:DI 1 "register_operand" "")
543 (match_operand:DI 2 "register_operand" "")))
544 (set (match_operand:SI 0 "register_operand" "")
545 (eq:SI (match_dup 3) (const_int 0)))]
547 { operands[3] = gen_reg_rtx (DImode); })
549 (define_expand "snedi_special_trunc"
551 (xor:DI (match_operand:DI 1 "register_operand" "")
552 (match_operand:DI 2 "register_operand" "")))
553 (set (match_operand:SI 0 "register_operand" "")
554 (ne:SI (match_dup 3) (const_int 0)))]
556 { operands[3] = gen_reg_rtx (DImode); })
558 (define_expand "seqsi_special_extend"
560 (xor:SI (match_operand:SI 1 "register_operand" "")
561 (match_operand:SI 2 "register_operand" "")))
562 (parallel [(set (match_operand:DI 0 "register_operand" "")
563 (eq:DI (match_dup 3) (const_int 0)))
564 (clobber (reg:CC 100))])]
566 { operands[3] = gen_reg_rtx (SImode); })
568 (define_expand "snesi_special_extend"
570 (xor:SI (match_operand:SI 1 "register_operand" "")
571 (match_operand:SI 2 "register_operand" "")))
572 (parallel [(set (match_operand:DI 0 "register_operand" "")
573 (ne:DI (match_dup 3) (const_int 0)))
574 (clobber (reg:CC 100))])]
576 { operands[3] = gen_reg_rtx (SImode); })
578 ;; ??? v9: Operand 0 needs a mode, so SImode was chosen.
579 ;; However, the code handles both SImode and DImode.
581 [(set (match_operand:SI 0 "int_register_operand" "")
582 (eq:SI (match_dup 1) (const_int 0)))]
585 if (GET_MODE (sparc_compare_op0) == SImode)
589 if (GET_MODE (operands[0]) == SImode)
590 pat = gen_seqsi_special (operands[0], sparc_compare_op0,
592 else if (! TARGET_ARCH64)
595 pat = gen_seqsi_special_extend (operands[0], sparc_compare_op0,
600 else if (GET_MODE (sparc_compare_op0) == DImode)
606 else if (GET_MODE (operands[0]) == SImode)
607 pat = gen_seqdi_special_trunc (operands[0], sparc_compare_op0,
610 pat = gen_seqdi_special (operands[0], sparc_compare_op0,
615 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
617 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, EQ);
618 emit_jump_insn (gen_sne (operands[0]));
623 if (gen_v9_scc (EQ, operands))
630 ;; ??? v9: Operand 0 needs a mode, so SImode was chosen.
631 ;; However, the code handles both SImode and DImode.
633 [(set (match_operand:SI 0 "int_register_operand" "")
634 (ne:SI (match_dup 1) (const_int 0)))]
637 if (GET_MODE (sparc_compare_op0) == SImode)
641 if (GET_MODE (operands[0]) == SImode)
642 pat = gen_snesi_special (operands[0], sparc_compare_op0,
644 else if (! TARGET_ARCH64)
647 pat = gen_snesi_special_extend (operands[0], sparc_compare_op0,
652 else if (GET_MODE (sparc_compare_op0) == DImode)
658 else if (GET_MODE (operands[0]) == SImode)
659 pat = gen_snedi_special_trunc (operands[0], sparc_compare_op0,
662 pat = gen_snedi_special (operands[0], sparc_compare_op0,
667 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
669 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, NE);
670 emit_jump_insn (gen_sne (operands[0]));
675 if (gen_v9_scc (NE, operands))
683 [(set (match_operand:SI 0 "int_register_operand" "")
684 (gt:SI (match_dup 1) (const_int 0)))]
687 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
689 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GT);
690 emit_jump_insn (gen_sne (operands[0]));
695 if (gen_v9_scc (GT, operands))
703 [(set (match_operand:SI 0 "int_register_operand" "")
704 (lt:SI (match_dup 1) (const_int 0)))]
707 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
709 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LT);
710 emit_jump_insn (gen_sne (operands[0]));
715 if (gen_v9_scc (LT, operands))
723 [(set (match_operand:SI 0 "int_register_operand" "")
724 (ge:SI (match_dup 1) (const_int 0)))]
727 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
729 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GE);
730 emit_jump_insn (gen_sne (operands[0]));
735 if (gen_v9_scc (GE, operands))
743 [(set (match_operand:SI 0 "int_register_operand" "")
744 (le:SI (match_dup 1) (const_int 0)))]
747 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
749 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LE);
750 emit_jump_insn (gen_sne (operands[0]));
755 if (gen_v9_scc (LE, operands))
762 (define_expand "sgtu"
763 [(set (match_operand:SI 0 "int_register_operand" "")
764 (gtu:SI (match_dup 1) (const_int 0)))]
771 /* We can do ltu easily, so if both operands are registers, swap them and
773 if ((GET_CODE (sparc_compare_op0) == REG
774 || GET_CODE (sparc_compare_op0) == SUBREG)
775 && (GET_CODE (sparc_compare_op1) == REG
776 || GET_CODE (sparc_compare_op1) == SUBREG))
778 tem = sparc_compare_op0;
779 sparc_compare_op0 = sparc_compare_op1;
780 sparc_compare_op1 = tem;
781 pat = gen_sltu (operands[0]);
790 if (gen_v9_scc (GTU, operands))
796 (define_expand "sltu"
797 [(set (match_operand:SI 0 "int_register_operand" "")
798 (ltu:SI (match_dup 1) (const_int 0)))]
803 if (gen_v9_scc (LTU, operands))
806 operands[1] = gen_compare_reg (LTU);
809 (define_expand "sgeu"
810 [(set (match_operand:SI 0 "int_register_operand" "")
811 (geu:SI (match_dup 1) (const_int 0)))]
816 if (gen_v9_scc (GEU, operands))
819 operands[1] = gen_compare_reg (GEU);
822 (define_expand "sleu"
823 [(set (match_operand:SI 0 "int_register_operand" "")
824 (leu:SI (match_dup 1) (const_int 0)))]
831 /* We can do geu easily, so if both operands are registers, swap them and
833 if ((GET_CODE (sparc_compare_op0) == REG
834 || GET_CODE (sparc_compare_op0) == SUBREG)
835 && (GET_CODE (sparc_compare_op1) == REG
836 || GET_CODE (sparc_compare_op1) == SUBREG))
838 tem = sparc_compare_op0;
839 sparc_compare_op0 = sparc_compare_op1;
840 sparc_compare_op1 = tem;
841 pat = gen_sgeu (operands[0]);
850 if (gen_v9_scc (LEU, operands))
856 ;; Now the DEFINE_INSNs for the scc cases.
858 ;; The SEQ and SNE patterns are special because they can be done
859 ;; without any branching and do not involve a COMPARE. We want
860 ;; them to always use the splits below so the results can be
863 (define_insn_and_split "*snesi_zero"
864 [(set (match_operand:SI 0 "register_operand" "=r")
865 (ne:SI (match_operand:SI 1 "register_operand" "r")
867 (clobber (reg:CC 100))]
871 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
873 (set (match_dup 0) (ltu:SI (reg:CC 100) (const_int 0)))]
875 [(set_attr "length" "2")])
877 (define_insn_and_split "*neg_snesi_zero"
878 [(set (match_operand:SI 0 "register_operand" "=r")
879 (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
881 (clobber (reg:CC 100))]
885 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
887 (set (match_dup 0) (neg:SI (ltu:SI (reg:CC 100) (const_int 0))))]
889 [(set_attr "length" "2")])
891 (define_insn_and_split "*snesi_zero_extend"
892 [(set (match_operand:DI 0 "register_operand" "=r")
893 (ne:DI (match_operand:SI 1 "register_operand" "r")
895 (clobber (reg:CC 100))]
899 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (minus:SI (const_int 0)
902 (set (match_dup 0) (zero_extend:DI (plus:SI (plus:SI (const_int 0)
904 (ltu:SI (reg:CC_NOOV 100)
907 [(set_attr "length" "2")])
909 (define_insn_and_split "*snedi_zero"
910 [(set (match_operand:DI 0 "register_operand" "=&r")
911 (ne:DI (match_operand:DI 1 "register_operand" "r")
915 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
916 [(set (match_dup 0) (const_int 0))
917 (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
922 [(set_attr "length" "2")])
924 (define_insn_and_split "*neg_snedi_zero"
925 [(set (match_operand:DI 0 "register_operand" "=&r")
926 (neg:DI (ne:DI (match_operand:DI 1 "register_operand" "r")
930 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
931 [(set (match_dup 0) (const_int 0))
932 (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
937 [(set_attr "length" "2")])
939 (define_insn_and_split "*snedi_zero_trunc"
940 [(set (match_operand:SI 0 "register_operand" "=&r")
941 (ne:SI (match_operand:DI 1 "register_operand" "r")
945 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
946 [(set (match_dup 0) (const_int 0))
947 (set (match_dup 0) (if_then_else:SI (ne:DI (match_dup 1)
952 [(set_attr "length" "2")])
954 (define_insn_and_split "*seqsi_zero"
955 [(set (match_operand:SI 0 "register_operand" "=r")
956 (eq:SI (match_operand:SI 1 "register_operand" "r")
958 (clobber (reg:CC 100))]
962 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
964 (set (match_dup 0) (geu:SI (reg:CC 100) (const_int 0)))]
966 [(set_attr "length" "2")])
968 (define_insn_and_split "*neg_seqsi_zero"
969 [(set (match_operand:SI 0 "register_operand" "=r")
970 (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
972 (clobber (reg:CC 100))]
976 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
978 (set (match_dup 0) (neg:SI (geu:SI (reg:CC 100) (const_int 0))))]
980 [(set_attr "length" "2")])
982 (define_insn_and_split "*seqsi_zero_extend"
983 [(set (match_operand:DI 0 "register_operand" "=r")
984 (eq:DI (match_operand:SI 1 "register_operand" "r")
986 (clobber (reg:CC 100))]
990 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (minus:SI (const_int 0)
993 (set (match_dup 0) (zero_extend:DI (minus:SI (minus:SI (const_int 0)
995 (ltu:SI (reg:CC_NOOV 100)
998 [(set_attr "length" "2")])
1000 (define_insn_and_split "*seqdi_zero"
1001 [(set (match_operand:DI 0 "register_operand" "=&r")
1002 (eq:DI (match_operand:DI 1 "register_operand" "r")
1006 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
1007 [(set (match_dup 0) (const_int 0))
1008 (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
1013 [(set_attr "length" "2")])
1015 (define_insn_and_split "*neg_seqdi_zero"
1016 [(set (match_operand:DI 0 "register_operand" "=&r")
1017 (neg:DI (eq:DI (match_operand:DI 1 "register_operand" "r")
1021 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
1022 [(set (match_dup 0) (const_int 0))
1023 (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
1028 [(set_attr "length" "2")])
1030 (define_insn_and_split "*seqdi_zero_trunc"
1031 [(set (match_operand:SI 0 "register_operand" "=&r")
1032 (eq:SI (match_operand:DI 1 "register_operand" "r")
1036 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
1037 [(set (match_dup 0) (const_int 0))
1038 (set (match_dup 0) (if_then_else:SI (eq:DI (match_dup 1)
1043 [(set_attr "length" "2")])
1045 ;; We can also do (x + (i == 0)) and related, so put them in.
1046 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1049 (define_insn_and_split "*x_plus_i_ne_0"
1050 [(set (match_operand:SI 0 "register_operand" "=r")
1051 (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
1053 (match_operand:SI 2 "register_operand" "r")))
1054 (clobber (reg:CC 100))]
1058 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1060 (set (match_dup 0) (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1063 [(set_attr "length" "2")])
1065 (define_insn_and_split "*x_minus_i_ne_0"
1066 [(set (match_operand:SI 0 "register_operand" "=r")
1067 (minus:SI (match_operand:SI 2 "register_operand" "r")
1068 (ne:SI (match_operand:SI 1 "register_operand" "r")
1070 (clobber (reg:CC 100))]
1074 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1076 (set (match_dup 0) (minus:SI (match_dup 2)
1077 (ltu:SI (reg:CC 100) (const_int 0))))]
1079 [(set_attr "length" "2")])
1081 (define_insn_and_split "*x_plus_i_eq_0"
1082 [(set (match_operand:SI 0 "register_operand" "=r")
1083 (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
1085 (match_operand:SI 2 "register_operand" "r")))
1086 (clobber (reg:CC 100))]
1090 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1092 (set (match_dup 0) (plus:SI (geu:SI (reg:CC 100) (const_int 0))
1095 [(set_attr "length" "2")])
1097 (define_insn_and_split "*x_minus_i_eq_0"
1098 [(set (match_operand:SI 0 "register_operand" "=r")
1099 (minus:SI (match_operand:SI 2 "register_operand" "r")
1100 (eq:SI (match_operand:SI 1 "register_operand" "r")
1102 (clobber (reg:CC 100))]
1106 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1108 (set (match_dup 0) (minus:SI (match_dup 2)
1109 (geu:SI (reg:CC 100) (const_int 0))))]
1111 [(set_attr "length" "2")])
1113 ;; We can also do GEU and LTU directly, but these operate after a compare.
1114 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1117 (define_insn "*sltu_insn"
1118 [(set (match_operand:SI 0 "register_operand" "=r")
1119 (ltu:SI (reg:CC 100) (const_int 0)))]
1122 [(set_attr "type" "ialuX")])
1124 (define_insn "*neg_sltu_insn"
1125 [(set (match_operand:SI 0 "register_operand" "=r")
1126 (neg:SI (ltu:SI (reg:CC 100) (const_int 0))))]
1129 [(set_attr "type" "ialuX")])
1131 ;; ??? Combine should canonicalize these next two to the same pattern.
1132 (define_insn "*neg_sltu_minus_x"
1133 [(set (match_operand:SI 0 "register_operand" "=r")
1134 (minus:SI (neg:SI (ltu:SI (reg:CC 100) (const_int 0)))
1135 (match_operand:SI 1 "arith_operand" "rI")))]
1137 "subx\t%%g0, %1, %0"
1138 [(set_attr "type" "ialuX")])
1140 (define_insn "*neg_sltu_plus_x"
1141 [(set (match_operand:SI 0 "register_operand" "=r")
1142 (neg:SI (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1143 (match_operand:SI 1 "arith_operand" "rI"))))]
1145 "subx\t%%g0, %1, %0"
1146 [(set_attr "type" "ialuX")])
1148 (define_insn "*sgeu_insn"
1149 [(set (match_operand:SI 0 "register_operand" "=r")
1150 (geu:SI (reg:CC 100) (const_int 0)))]
1152 "subx\t%%g0, -1, %0"
1153 [(set_attr "type" "ialuX")])
1155 (define_insn "*neg_sgeu_insn"
1156 [(set (match_operand:SI 0 "register_operand" "=r")
1157 (neg:SI (geu:SI (reg:CC 100) (const_int 0))))]
1159 "addx\t%%g0, -1, %0"
1160 [(set_attr "type" "ialuX")])
1162 ;; We can also do (x + ((unsigned) i >= 0)) and related, so put them in.
1163 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1166 (define_insn "*sltu_plus_x"
1167 [(set (match_operand:SI 0 "register_operand" "=r")
1168 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1169 (match_operand:SI 1 "arith_operand" "rI")))]
1171 "addx\t%%g0, %1, %0"
1172 [(set_attr "type" "ialuX")])
1174 (define_insn "*sltu_plus_x_plus_y"
1175 [(set (match_operand:SI 0 "register_operand" "=r")
1176 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1177 (plus:SI (match_operand:SI 1 "arith_operand" "%r")
1178 (match_operand:SI 2 "arith_operand" "rI"))))]
1181 [(set_attr "type" "ialuX")])
1183 (define_insn "*x_minus_sltu"
1184 [(set (match_operand:SI 0 "register_operand" "=r")
1185 (minus:SI (match_operand:SI 1 "register_operand" "r")
1186 (ltu:SI (reg:CC 100) (const_int 0))))]
1189 [(set_attr "type" "ialuX")])
1191 ;; ??? Combine should canonicalize these next two to the same pattern.
1192 (define_insn "*x_minus_y_minus_sltu"
1193 [(set (match_operand:SI 0 "register_operand" "=r")
1194 (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
1195 (match_operand:SI 2 "arith_operand" "rI"))
1196 (ltu:SI (reg:CC 100) (const_int 0))))]
1199 [(set_attr "type" "ialuX")])
1201 (define_insn "*x_minus_sltu_plus_y"
1202 [(set (match_operand:SI 0 "register_operand" "=r")
1203 (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
1204 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1205 (match_operand:SI 2 "arith_operand" "rI"))))]
1208 [(set_attr "type" "ialuX")])
1210 (define_insn "*sgeu_plus_x"
1211 [(set (match_operand:SI 0 "register_operand" "=r")
1212 (plus:SI (geu:SI (reg:CC 100) (const_int 0))
1213 (match_operand:SI 1 "register_operand" "r")))]
1216 [(set_attr "type" "ialuX")])
1218 (define_insn "*x_minus_sgeu"
1219 [(set (match_operand:SI 0 "register_operand" "=r")
1220 (minus:SI (match_operand:SI 1 "register_operand" "r")
1221 (geu:SI (reg:CC 100) (const_int 0))))]
1224 [(set_attr "type" "ialuX")])
1227 [(set (match_operand:SI 0 "register_operand" "")
1228 (match_operator:SI 2 "noov_compare_operator"
1229 [(match_operand 1 "icc_or_fcc_register_operand" "")
1232 && REGNO (operands[1]) == SPARC_ICC_REG
1233 && (GET_MODE (operands[1]) == CCXmode
1234 /* 32 bit LTU/GEU are better implemented using addx/subx. */
1235 || (GET_CODE (operands[2]) != LTU && GET_CODE (operands[2]) != GEU))"
1236 [(set (match_dup 0) (const_int 0))
1238 (if_then_else:SI (match_op_dup:SI 2 [(match_dup 1) (const_int 0)])
1244 ;; These control RTL generation for conditional jump insns
1246 ;; The quad-word fp compare library routines all return nonzero to indicate
1247 ;; true, which is different from the equivalent libgcc routines, so we must
1248 ;; handle them specially here.
1250 (define_expand "beq"
1252 (if_then_else (eq (match_dup 1) (const_int 0))
1253 (label_ref (match_operand 0 "" ""))
1257 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1258 && GET_CODE (sparc_compare_op0) == REG
1259 && GET_MODE (sparc_compare_op0) == DImode)
1261 emit_v9_brxx_insn (EQ, sparc_compare_op0, operands[0]);
1264 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1266 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, EQ);
1267 emit_jump_insn (gen_bne (operands[0]));
1270 operands[1] = gen_compare_reg (EQ);
1273 (define_expand "bne"
1275 (if_then_else (ne (match_dup 1) (const_int 0))
1276 (label_ref (match_operand 0 "" ""))
1280 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1281 && GET_CODE (sparc_compare_op0) == REG
1282 && GET_MODE (sparc_compare_op0) == DImode)
1284 emit_v9_brxx_insn (NE, sparc_compare_op0, operands[0]);
1287 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1289 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, NE);
1290 emit_jump_insn (gen_bne (operands[0]));
1293 operands[1] = gen_compare_reg (NE);
1296 (define_expand "bgt"
1298 (if_then_else (gt (match_dup 1) (const_int 0))
1299 (label_ref (match_operand 0 "" ""))
1303 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1304 && GET_CODE (sparc_compare_op0) == REG
1305 && GET_MODE (sparc_compare_op0) == DImode)
1307 emit_v9_brxx_insn (GT, sparc_compare_op0, operands[0]);
1310 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1312 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GT);
1313 emit_jump_insn (gen_bne (operands[0]));
1316 operands[1] = gen_compare_reg (GT);
1319 (define_expand "bgtu"
1321 (if_then_else (gtu (match_dup 1) (const_int 0))
1322 (label_ref (match_operand 0 "" ""))
1326 operands[1] = gen_compare_reg (GTU);
1329 (define_expand "blt"
1331 (if_then_else (lt (match_dup 1) (const_int 0))
1332 (label_ref (match_operand 0 "" ""))
1336 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1337 && GET_CODE (sparc_compare_op0) == REG
1338 && GET_MODE (sparc_compare_op0) == DImode)
1340 emit_v9_brxx_insn (LT, sparc_compare_op0, operands[0]);
1343 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1345 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LT);
1346 emit_jump_insn (gen_bne (operands[0]));
1349 operands[1] = gen_compare_reg (LT);
1352 (define_expand "bltu"
1354 (if_then_else (ltu (match_dup 1) (const_int 0))
1355 (label_ref (match_operand 0 "" ""))
1359 operands[1] = gen_compare_reg (LTU);
1362 (define_expand "bge"
1364 (if_then_else (ge (match_dup 1) (const_int 0))
1365 (label_ref (match_operand 0 "" ""))
1369 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1370 && GET_CODE (sparc_compare_op0) == REG
1371 && GET_MODE (sparc_compare_op0) == DImode)
1373 emit_v9_brxx_insn (GE, sparc_compare_op0, operands[0]);
1376 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1378 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GE);
1379 emit_jump_insn (gen_bne (operands[0]));
1382 operands[1] = gen_compare_reg (GE);
1385 (define_expand "bgeu"
1387 (if_then_else (geu (match_dup 1) (const_int 0))
1388 (label_ref (match_operand 0 "" ""))
1392 operands[1] = gen_compare_reg (GEU);
1395 (define_expand "ble"
1397 (if_then_else (le (match_dup 1) (const_int 0))
1398 (label_ref (match_operand 0 "" ""))
1402 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1403 && GET_CODE (sparc_compare_op0) == REG
1404 && GET_MODE (sparc_compare_op0) == DImode)
1406 emit_v9_brxx_insn (LE, sparc_compare_op0, operands[0]);
1409 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1411 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LE);
1412 emit_jump_insn (gen_bne (operands[0]));
1415 operands[1] = gen_compare_reg (LE);
1418 (define_expand "bleu"
1420 (if_then_else (leu (match_dup 1) (const_int 0))
1421 (label_ref (match_operand 0 "" ""))
1425 operands[1] = gen_compare_reg (LEU);
1428 (define_expand "bunordered"
1430 (if_then_else (unordered (match_dup 1) (const_int 0))
1431 (label_ref (match_operand 0 "" ""))
1435 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1437 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1,
1439 emit_jump_insn (gen_beq (operands[0]));
1442 operands[1] = gen_compare_reg (UNORDERED);
1445 (define_expand "bordered"
1447 (if_then_else (ordered (match_dup 1) (const_int 0))
1448 (label_ref (match_operand 0 "" ""))
1452 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1454 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, ORDERED);
1455 emit_jump_insn (gen_bne (operands[0]));
1458 operands[1] = gen_compare_reg (ORDERED);
1461 (define_expand "bungt"
1463 (if_then_else (ungt (match_dup 1) (const_int 0))
1464 (label_ref (match_operand 0 "" ""))
1468 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1470 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNGT);
1471 emit_jump_insn (gen_bgt (operands[0]));
1474 operands[1] = gen_compare_reg (UNGT);
1477 (define_expand "bunlt"
1479 (if_then_else (unlt (match_dup 1) (const_int 0))
1480 (label_ref (match_operand 0 "" ""))
1484 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1486 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNLT);
1487 emit_jump_insn (gen_bne (operands[0]));
1490 operands[1] = gen_compare_reg (UNLT);
1493 (define_expand "buneq"
1495 (if_then_else (uneq (match_dup 1) (const_int 0))
1496 (label_ref (match_operand 0 "" ""))
1500 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1502 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNEQ);
1503 emit_jump_insn (gen_beq (operands[0]));
1506 operands[1] = gen_compare_reg (UNEQ);
1509 (define_expand "bunge"
1511 (if_then_else (unge (match_dup 1) (const_int 0))
1512 (label_ref (match_operand 0 "" ""))
1516 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1518 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNGE);
1519 emit_jump_insn (gen_bne (operands[0]));
1522 operands[1] = gen_compare_reg (UNGE);
1525 (define_expand "bunle"
1527 (if_then_else (unle (match_dup 1) (const_int 0))
1528 (label_ref (match_operand 0 "" ""))
1532 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1534 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNLE);
1535 emit_jump_insn (gen_bne (operands[0]));
1538 operands[1] = gen_compare_reg (UNLE);
1541 (define_expand "bltgt"
1543 (if_then_else (ltgt (match_dup 1) (const_int 0))
1544 (label_ref (match_operand 0 "" ""))
1548 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1550 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LTGT);
1551 emit_jump_insn (gen_bne (operands[0]));
1554 operands[1] = gen_compare_reg (LTGT);
1557 ;; Now match both normal and inverted jump.
1559 ;; XXX fpcmp nop braindamage
1560 (define_insn "*normal_branch"
1562 (if_then_else (match_operator 0 "noov_compare_operator"
1563 [(reg 100) (const_int 0)])
1564 (label_ref (match_operand 1 "" ""))
1568 return output_cbranch (operands[0], operands[1], 1, 0,
1569 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1572 [(set_attr "type" "branch")
1573 (set_attr "branch_type" "icc")])
1575 ;; XXX fpcmp nop braindamage
1576 (define_insn "*inverted_branch"
1578 (if_then_else (match_operator 0 "noov_compare_operator"
1579 [(reg 100) (const_int 0)])
1581 (label_ref (match_operand 1 "" ""))))]
1584 return output_cbranch (operands[0], operands[1], 1, 1,
1585 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1588 [(set_attr "type" "branch")
1589 (set_attr "branch_type" "icc")])
1591 ;; XXX fpcmp nop braindamage
1592 (define_insn "*normal_fp_branch"
1594 (if_then_else (match_operator 1 "comparison_operator"
1595 [(match_operand:CCFP 0 "fcc_register_operand" "c")
1597 (label_ref (match_operand 2 "" ""))
1601 return output_cbranch (operands[1], operands[2], 2, 0,
1602 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1605 [(set_attr "type" "branch")
1606 (set_attr "branch_type" "fcc")])
1608 ;; XXX fpcmp nop braindamage
1609 (define_insn "*inverted_fp_branch"
1611 (if_then_else (match_operator 1 "comparison_operator"
1612 [(match_operand:CCFP 0 "fcc_register_operand" "c")
1615 (label_ref (match_operand 2 "" ""))))]
1618 return output_cbranch (operands[1], operands[2], 2, 1,
1619 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1622 [(set_attr "type" "branch")
1623 (set_attr "branch_type" "fcc")])
1625 ;; XXX fpcmp nop braindamage
1626 (define_insn "*normal_fpe_branch"
1628 (if_then_else (match_operator 1 "comparison_operator"
1629 [(match_operand:CCFPE 0 "fcc_register_operand" "c")
1631 (label_ref (match_operand 2 "" ""))
1635 return output_cbranch (operands[1], operands[2], 2, 0,
1636 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1639 [(set_attr "type" "branch")
1640 (set_attr "branch_type" "fcc")])
1642 ;; XXX fpcmp nop braindamage
1643 (define_insn "*inverted_fpe_branch"
1645 (if_then_else (match_operator 1 "comparison_operator"
1646 [(match_operand:CCFPE 0 "fcc_register_operand" "c")
1649 (label_ref (match_operand 2 "" ""))))]
1652 return output_cbranch (operands[1], operands[2], 2, 1,
1653 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1656 [(set_attr "type" "branch")
1657 (set_attr "branch_type" "fcc")])
1659 ;; SPARC V9-specific jump insns. None of these are guaranteed to be
1660 ;; in the architecture.
1662 ;; There are no 32 bit brreg insns.
1665 (define_insn "*normal_int_branch_sp64"
1667 (if_then_else (match_operator 0 "v9_register_compare_operator"
1668 [(match_operand:DI 1 "register_operand" "r")
1670 (label_ref (match_operand 2 "" ""))
1674 return output_v9branch (operands[0], operands[2], 1, 2, 0,
1675 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1678 [(set_attr "type" "branch")
1679 (set_attr "branch_type" "reg")])
1682 (define_insn "*inverted_int_branch_sp64"
1684 (if_then_else (match_operator 0 "v9_register_compare_operator"
1685 [(match_operand:DI 1 "register_operand" "r")
1688 (label_ref (match_operand 2 "" ""))))]
1691 return output_v9branch (operands[0], operands[2], 1, 2, 1,
1692 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1695 [(set_attr "type" "branch")
1696 (set_attr "branch_type" "reg")])
1699 (define_mode_macro P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
1701 ;; Load in operand 0 the (absolute) address of operand 1, which is a symbolic
1702 ;; value subject to a PC-relative relocation. Operand 2 is a helper function
1703 ;; that adds the PC value at the call point to operand 0.
1705 (define_insn "load_pcrel_sym<P:mode>"
1706 [(set (match_operand:P 0 "register_operand" "=r")
1707 (unspec:P [(match_operand:P 1 "symbolic_operand" "")
1708 (match_operand:P 2 "call_address_operand" "")] UNSPEC_LOAD_PCREL_SYM))
1709 (clobber (reg:P 15))]
1712 if (flag_delayed_branch)
1713 return "sethi\t%%hi(%a1-4), %0\n\tcall\t%a2\n\t add\t%0, %%lo(%a1+4), %0";
1715 return "sethi\t%%hi(%a1-8), %0\n\tadd\t%0, %%lo(%a1-4), %0\n\tcall\t%a2\n\t nop";
1717 [(set (attr "type") (const_string "multi"))
1718 (set (attr "length")
1719 (if_then_else (eq_attr "delayed_branch" "true")
1724 ;; Integer move instructions
1726 (define_expand "movqi"
1727 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1728 (match_operand:QI 1 "general_operand" ""))]
1731 if (sparc_expand_move (QImode, operands))
1735 (define_insn "*movqi_insn"
1736 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m")
1737 (match_operand:QI 1 "input_operand" "rI,m,rJ"))]
1738 "(register_operand (operands[0], QImode)
1739 || register_or_zero_operand (operands[1], QImode))"
1744 [(set_attr "type" "*,load,store")
1745 (set_attr "us3load_type" "*,3cycle,*")])
1747 (define_expand "movhi"
1748 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1749 (match_operand:HI 1 "general_operand" ""))]
1752 if (sparc_expand_move (HImode, operands))
1756 (define_insn "*movhi_insn"
1757 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1758 (match_operand:HI 1 "input_operand" "rI,K,m,rJ"))]
1759 "(register_operand (operands[0], HImode)
1760 || register_or_zero_operand (operands[1], HImode))"
1763 sethi\t%%hi(%a1), %0
1766 [(set_attr "type" "*,*,load,store")
1767 (set_attr "us3load_type" "*,*,3cycle,*")])
1769 ;; We always work with constants here.
1770 (define_insn "*movhi_lo_sum"
1771 [(set (match_operand:HI 0 "register_operand" "=r")
1772 (ior:HI (match_operand:HI 1 "register_operand" "%r")
1773 (match_operand:HI 2 "small_int_operand" "I")))]
1777 (define_expand "movsi"
1778 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1779 (match_operand:SI 1 "general_operand" ""))]
1782 if (sparc_expand_move (SImode, operands))
1786 (define_insn "*movsi_insn"
1787 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,m,!f,!f,!m,d")
1788 (match_operand:SI 1 "input_operand" "rI,K,m,rJ,f,m,f,J"))]
1789 "(register_operand (operands[0], SImode)
1790 || register_or_zero_operand (operands[1], SImode))"
1793 sethi\t%%hi(%a1), %0
1800 [(set_attr "type" "*,*,load,store,fpmove,fpload,fpstore,fga")])
1802 (define_insn "*movsi_lo_sum"
1803 [(set (match_operand:SI 0 "register_operand" "=r")
1804 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1805 (match_operand:SI 2 "immediate_operand" "in")))]
1807 "or\t%1, %%lo(%a2), %0")
1809 (define_insn "*movsi_high"
1810 [(set (match_operand:SI 0 "register_operand" "=r")
1811 (high:SI (match_operand:SI 1 "immediate_operand" "in")))]
1813 "sethi\t%%hi(%a1), %0")
1815 ;; The next two patterns must wrap the SYMBOL_REF in an UNSPEC
1816 ;; so that CSE won't optimize the address computation away.
1817 (define_insn "movsi_lo_sum_pic"
1818 [(set (match_operand:SI 0 "register_operand" "=r")
1819 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1820 (unspec:SI [(match_operand:SI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
1822 "or\t%1, %%lo(%a2), %0")
1824 (define_insn "movsi_high_pic"
1825 [(set (match_operand:SI 0 "register_operand" "=r")
1826 (high:SI (unspec:SI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
1827 "flag_pic && check_pic (1)"
1828 "sethi\t%%hi(%a1), %0")
1830 (define_expand "movsi_pic_label_ref"
1831 [(set (match_dup 3) (high:SI
1832 (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
1833 (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1834 (set (match_dup 4) (lo_sum:SI (match_dup 3)
1835 (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1836 (set (match_operand:SI 0 "register_operand" "=r")
1837 (minus:SI (match_dup 5) (match_dup 4)))]
1840 current_function_uses_pic_offset_table = 1;
1841 operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
1844 operands[3] = operands[0];
1845 operands[4] = operands[0];
1849 operands[3] = gen_reg_rtx (SImode);
1850 operands[4] = gen_reg_rtx (SImode);
1852 operands[5] = pic_offset_table_rtx;
1855 (define_insn "*movsi_high_pic_label_ref"
1856 [(set (match_operand:SI 0 "register_operand" "=r")
1858 (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
1859 (match_operand:SI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1861 "sethi\t%%hi(%a2-(%a1-.)), %0")
1863 (define_insn "*movsi_lo_sum_pic_label_ref"
1864 [(set (match_operand:SI 0 "register_operand" "=r")
1865 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1866 (unspec:SI [(match_operand:SI 2 "label_ref_operand" "")
1867 (match_operand:SI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1869 "or\t%1, %%lo(%a3-(%a2-.)), %0")
1871 (define_expand "movdi"
1872 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1873 (match_operand:DI 1 "general_operand" ""))]
1876 if (sparc_expand_move (DImode, operands))
1880 ;; Be careful, fmovd does not exist when !v9.
1881 ;; We match MEM moves directly when we have correct even
1882 ;; numbered registers, but fall into splits otherwise.
1883 ;; The constraint ordering here is really important to
1884 ;; avoid insane problems in reload, especially for patterns
1887 ;; (set (mem:DI (plus:SI (reg:SI 30 %fp)
1888 ;; (const_int -5016)))
1892 (define_insn "*movdi_insn_sp32"
1893 [(set (match_operand:DI 0 "nonimmediate_operand"
1894 "=o,T,U,o,r,r,r,?T,?f,?f,?o,?f")
1895 (match_operand:DI 1 "input_operand"
1896 " J,U,T,r,o,i,r, f, T, o, f, f"))]
1898 && (register_operand (operands[0], DImode)
1899 || register_or_zero_operand (operands[1], DImode))"
1913 [(set_attr "type" "store,store,load,*,*,*,*,fpstore,fpload,*,*,*")
1914 (set_attr "length" "2,*,*,2,2,2,2,*,*,2,2,2")])
1916 (define_insn "*movdi_insn_sp32_v9"
1917 [(set (match_operand:DI 0 "nonimmediate_operand"
1918 "=T,o,T,U,o,r,r,r,?T,?f,?f,?o,?e,?e,?W")
1919 (match_operand:DI 1 "input_operand"
1920 " J,J,U,T,r,o,i,r, f, T, o, f, e, W, e"))]
1923 && (register_operand (operands[0], DImode)
1924 || register_or_zero_operand (operands[1], DImode))"
1941 [(set_attr "type" "store,store,store,load,*,*,*,*,fpstore,fpload,*,*,fpmove,fpload,fpstore")
1942 (set_attr "length" "*,2,*,*,2,2,2,2,*,*,2,2,*,*,*")
1943 (set_attr "fptype" "*,*,*,*,*,*,*,*,*,*,*,*,double,*,*")])
1945 (define_insn "*movdi_insn_sp64"
1946 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,m,?e,?e,?W,b")
1947 (match_operand:DI 1 "input_operand" "rI,N,m,rJ,e,W,e,J"))]
1949 && (register_operand (operands[0], DImode)
1950 || register_or_zero_operand (operands[1], DImode))"
1953 sethi\t%%hi(%a1), %0
1960 [(set_attr "type" "*,*,load,store,fpmove,fpload,fpstore,fga")
1961 (set_attr "fptype" "*,*,*,*,double,*,*,double")])
1963 (define_expand "movdi_pic_label_ref"
1964 [(set (match_dup 3) (high:DI
1965 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
1966 (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1967 (set (match_dup 4) (lo_sum:DI (match_dup 3)
1968 (unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1969 (set (match_operand:DI 0 "register_operand" "=r")
1970 (minus:DI (match_dup 5) (match_dup 4)))]
1971 "TARGET_ARCH64 && flag_pic"
1973 current_function_uses_pic_offset_table = 1;
1974 operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
1977 operands[3] = operands[0];
1978 operands[4] = operands[0];
1982 operands[3] = gen_reg_rtx (DImode);
1983 operands[4] = gen_reg_rtx (DImode);
1985 operands[5] = pic_offset_table_rtx;
1988 (define_insn "*movdi_high_pic_label_ref"
1989 [(set (match_operand:DI 0 "register_operand" "=r")
1991 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
1992 (match_operand:DI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1993 "TARGET_ARCH64 && flag_pic"
1994 "sethi\t%%hi(%a2-(%a1-.)), %0")
1996 (define_insn "*movdi_lo_sum_pic_label_ref"
1997 [(set (match_operand:DI 0 "register_operand" "=r")
1998 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1999 (unspec:DI [(match_operand:DI 2 "label_ref_operand" "")
2000 (match_operand:DI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
2001 "TARGET_ARCH64 && flag_pic"
2002 "or\t%1, %%lo(%a3-(%a2-.)), %0")
2004 ;; SPARC-v9 code model support insns. See sparc_emit_set_symbolic_const64
2005 ;; in sparc.c to see what is going on here... PIC stuff comes first.
2007 (define_insn "movdi_lo_sum_pic"
2008 [(set (match_operand:DI 0 "register_operand" "=r")
2009 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2010 (unspec:DI [(match_operand:DI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
2011 "TARGET_ARCH64 && flag_pic"
2012 "or\t%1, %%lo(%a2), %0")
2014 (define_insn "movdi_high_pic"
2015 [(set (match_operand:DI 0 "register_operand" "=r")
2016 (high:DI (unspec:DI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
2017 "TARGET_ARCH64 && flag_pic && check_pic (1)"
2018 "sethi\t%%hi(%a1), %0")
2020 (define_insn "*sethi_di_medlow_embmedany_pic"
2021 [(set (match_operand:DI 0 "register_operand" "=r")
2022 (high:DI (match_operand:DI 1 "medium_pic_operand" "")))]
2023 "(TARGET_CM_MEDLOW || TARGET_CM_EMBMEDANY) && check_pic (1)"
2024 "sethi\t%%hi(%a1), %0")
2026 (define_insn "*sethi_di_medlow"
2027 [(set (match_operand:DI 0 "register_operand" "=r")
2028 (high:DI (match_operand:DI 1 "symbolic_operand" "")))]
2029 "TARGET_CM_MEDLOW && check_pic (1)"
2030 "sethi\t%%hi(%a1), %0")
2032 (define_insn "*losum_di_medlow"
2033 [(set (match_operand:DI 0 "register_operand" "=r")
2034 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2035 (match_operand:DI 2 "symbolic_operand" "")))]
2037 "or\t%1, %%lo(%a2), %0")
2039 (define_insn "seth44"
2040 [(set (match_operand:DI 0 "register_operand" "=r")
2041 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETH44)))]
2043 "sethi\t%%h44(%a1), %0")
2045 (define_insn "setm44"
2046 [(set (match_operand:DI 0 "register_operand" "=r")
2047 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2048 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_SETM44)))]
2050 "or\t%1, %%m44(%a2), %0")
2052 (define_insn "setl44"
2053 [(set (match_operand:DI 0 "register_operand" "=r")
2054 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2055 (match_operand:DI 2 "symbolic_operand" "")))]
2057 "or\t%1, %%l44(%a2), %0")
2059 (define_insn "sethh"
2060 [(set (match_operand:DI 0 "register_operand" "=r")
2061 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETHH)))]
2063 "sethi\t%%hh(%a1), %0")
2065 (define_insn "setlm"
2066 [(set (match_operand:DI 0 "register_operand" "=r")
2067 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETLM)))]
2069 "sethi\t%%lm(%a1), %0")
2071 (define_insn "sethm"
2072 [(set (match_operand:DI 0 "register_operand" "=r")
2073 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2074 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_EMB_SETHM)))]
2076 "or\t%1, %%hm(%a2), %0")
2078 (define_insn "setlo"
2079 [(set (match_operand:DI 0 "register_operand" "=r")
2080 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2081 (match_operand:DI 2 "symbolic_operand" "")))]
2083 "or\t%1, %%lo(%a2), %0")
2085 (define_insn "embmedany_sethi"
2086 [(set (match_operand:DI 0 "register_operand" "=r")
2087 (high:DI (unspec:DI [(match_operand:DI 1 "data_segment_operand" "")] UNSPEC_EMB_HISUM)))]
2088 "TARGET_CM_EMBMEDANY && check_pic (1)"
2089 "sethi\t%%hi(%a1), %0")
2091 (define_insn "embmedany_losum"
2092 [(set (match_operand:DI 0 "register_operand" "=r")
2093 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2094 (match_operand:DI 2 "data_segment_operand" "")))]
2095 "TARGET_CM_EMBMEDANY"
2096 "add\t%1, %%lo(%a2), %0")
2098 (define_insn "embmedany_brsum"
2099 [(set (match_operand:DI 0 "register_operand" "=r")
2100 (unspec:DI [(match_operand:DI 1 "register_operand" "r")] UNSPEC_EMB_HISUM))]
2101 "TARGET_CM_EMBMEDANY"
2104 (define_insn "embmedany_textuhi"
2105 [(set (match_operand:DI 0 "register_operand" "=r")
2106 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTUHI)))]
2107 "TARGET_CM_EMBMEDANY && check_pic (1)"
2108 "sethi\t%%uhi(%a1), %0")
2110 (define_insn "embmedany_texthi"
2111 [(set (match_operand:DI 0 "register_operand" "=r")
2112 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTHI)))]
2113 "TARGET_CM_EMBMEDANY && check_pic (1)"
2114 "sethi\t%%hi(%a1), %0")
2116 (define_insn "embmedany_textulo"
2117 [(set (match_operand:DI 0 "register_operand" "=r")
2118 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2119 (unspec:DI [(match_operand:DI 2 "text_segment_operand" "")] UNSPEC_EMB_TEXTULO)))]
2120 "TARGET_CM_EMBMEDANY"
2121 "or\t%1, %%ulo(%a2), %0")
2123 (define_insn "embmedany_textlo"
2124 [(set (match_operand:DI 0 "register_operand" "=r")
2125 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2126 (match_operand:DI 2 "text_segment_operand" "")))]
2127 "TARGET_CM_EMBMEDANY"
2128 "or\t%1, %%lo(%a2), %0")
2130 ;; Now some patterns to help reload out a bit.
2131 (define_expand "reload_indi"
2132 [(parallel [(match_operand:DI 0 "register_operand" "=r")
2133 (match_operand:DI 1 "immediate_operand" "")
2134 (match_operand:TI 2 "register_operand" "=&r")])]
2136 || TARGET_CM_EMBMEDANY)
2139 sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
2143 (define_expand "reload_outdi"
2144 [(parallel [(match_operand:DI 0 "register_operand" "=r")
2145 (match_operand:DI 1 "immediate_operand" "")
2146 (match_operand:TI 2 "register_operand" "=&r")])]
2148 || TARGET_CM_EMBMEDANY)
2151 sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
2155 ;; Split up putting CONSTs and REGs into DI regs when !arch64
2157 [(set (match_operand:DI 0 "register_operand" "")
2158 (match_operand:DI 1 "const_int_operand" ""))]
2159 "! TARGET_ARCH64 && reload_completed"
2160 [(clobber (const_int 0))]
2162 #if HOST_BITS_PER_WIDE_INT == 32
2163 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
2164 (INTVAL (operands[1]) < 0) ?
2167 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2170 unsigned int low, high;
2172 low = trunc_int_for_mode (INTVAL (operands[1]), SImode);
2173 high = trunc_int_for_mode (INTVAL (operands[1]) >> 32, SImode);
2174 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), GEN_INT (high)));
2176 /* Slick... but this trick loses if this subreg constant part
2177 can be done in one insn. */
2179 && ! SPARC_SETHI32_P (high)
2180 && ! SPARC_SIMM13_P (high))
2181 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2182 gen_highpart (SImode, operands[0])));
2184 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), GEN_INT (low)));
2190 [(set (match_operand:DI 0 "register_operand" "")
2191 (match_operand:DI 1 "const_double_operand" ""))]
2195 && ((GET_CODE (operands[0]) == REG
2196 && REGNO (operands[0]) < 32)
2197 || (GET_CODE (operands[0]) == SUBREG
2198 && GET_CODE (SUBREG_REG (operands[0])) == REG
2199 && REGNO (SUBREG_REG (operands[0])) < 32))))"
2200 [(clobber (const_int 0))]
2202 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
2203 GEN_INT (CONST_DOUBLE_HIGH (operands[1]))));
2205 /* Slick... but this trick loses if this subreg constant part
2206 can be done in one insn. */
2207 if (CONST_DOUBLE_LOW (operands[1]) == CONST_DOUBLE_HIGH (operands[1])
2208 && ! SPARC_SETHI32_P (CONST_DOUBLE_HIGH (operands[1]))
2209 && ! SPARC_SIMM13_P (CONST_DOUBLE_HIGH (operands[1])))
2211 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2212 gen_highpart (SImode, operands[0])));
2216 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2217 GEN_INT (CONST_DOUBLE_LOW (operands[1]))));
2223 [(set (match_operand:DI 0 "register_operand" "")
2224 (match_operand:DI 1 "register_operand" ""))]
2228 && ((GET_CODE (operands[0]) == REG
2229 && REGNO (operands[0]) < 32)
2230 || (GET_CODE (operands[0]) == SUBREG
2231 && GET_CODE (SUBREG_REG (operands[0])) == REG
2232 && REGNO (SUBREG_REG (operands[0])) < 32))))"
2233 [(clobber (const_int 0))]
2235 rtx set_dest = operands[0];
2236 rtx set_src = operands[1];
2240 dest1 = gen_highpart (SImode, set_dest);
2241 dest2 = gen_lowpart (SImode, set_dest);
2242 src1 = gen_highpart (SImode, set_src);
2243 src2 = gen_lowpart (SImode, set_src);
2245 /* Now emit using the real source and destination we found, swapping
2246 the order if we detect overlap. */
2247 if (reg_overlap_mentioned_p (dest1, src2))
2249 emit_insn (gen_movsi (dest2, src2));
2250 emit_insn (gen_movsi (dest1, src1));
2254 emit_insn (gen_movsi (dest1, src1));
2255 emit_insn (gen_movsi (dest2, src2));
2260 ;; Now handle the cases of memory moves from/to non-even
2261 ;; DI mode register pairs.
2263 [(set (match_operand:DI 0 "register_operand" "")
2264 (match_operand:DI 1 "memory_operand" ""))]
2267 && sparc_splitdi_legitimate (operands[0], operands[1]))"
2268 [(clobber (const_int 0))]
2270 rtx word0 = adjust_address (operands[1], SImode, 0);
2271 rtx word1 = adjust_address (operands[1], SImode, 4);
2272 rtx high_part = gen_highpart (SImode, operands[0]);
2273 rtx low_part = gen_lowpart (SImode, operands[0]);
2275 if (reg_overlap_mentioned_p (high_part, word1))
2277 emit_insn (gen_movsi (low_part, word1));
2278 emit_insn (gen_movsi (high_part, word0));
2282 emit_insn (gen_movsi (high_part, word0));
2283 emit_insn (gen_movsi (low_part, word1));
2289 [(set (match_operand:DI 0 "memory_operand" "")
2290 (match_operand:DI 1 "register_operand" ""))]
2293 && sparc_splitdi_legitimate (operands[1], operands[0]))"
2294 [(clobber (const_int 0))]
2296 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0),
2297 gen_highpart (SImode, operands[1])));
2298 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4),
2299 gen_lowpart (SImode, operands[1])));
2304 [(set (match_operand:DI 0 "memory_operand" "")
2305 (match_operand:DI 1 "const_zero_operand" ""))]
2309 && ! mem_min_alignment (operands[0], 8)))
2310 && offsettable_memref_p (operands[0])"
2311 [(clobber (const_int 0))]
2313 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0), const0_rtx));
2314 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4), const0_rtx));
2319 ;; Floating point and vector move instructions
2321 ;; We don't define V1SI because SI should work just fine.
2322 (define_mode_macro V32 [SF V2HI V4QI])
2324 ;; Yes, you guessed it right, the former movsf expander.
2325 (define_expand "mov<V32:mode>"
2326 [(set (match_operand:V32 0 "nonimmediate_operand" "")
2327 (match_operand:V32 1 "general_operand" ""))]
2328 "<V32:MODE>mode == SFmode || TARGET_VIS"
2330 if (sparc_expand_move (<V32:MODE>mode, operands))
2334 (define_insn "*movsf_insn"
2335 [(set (match_operand:V32 0 "nonimmediate_operand" "=d,f,*r,*r,*r,f,*r,m,m")
2336 (match_operand:V32 1 "input_operand" "GY,f,*rRY,Q,S,m,m,f,*rGY"))]
2338 && (register_operand (operands[0], <V32:MODE>mode)
2339 || register_or_zero_operand (operands[1], <V32:MODE>mode))"
2341 if (GET_CODE (operands[1]) == CONST_DOUBLE
2342 && (which_alternative == 2
2343 || which_alternative == 3
2344 || which_alternative == 4))
2349 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2350 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2351 operands[1] = GEN_INT (i);
2354 switch (which_alternative)
2357 return "fzeros\t%0";
2359 return "fmovs\t%1, %0";
2361 return "mov\t%1, %0";
2363 return "sethi\t%%hi(%a1), %0";
2368 return "ld\t%1, %0";
2371 return "st\t%r1, %0";
2376 [(set_attr "type" "fga,fpmove,*,*,*,fpload,load,fpstore,store")])
2378 ;; Exactly the same as above, except that all `f' cases are deleted.
2379 ;; This is necessary to prevent reload from ever trying to use a `f' reg
2382 (define_insn "*movsf_insn_no_fpu"
2383 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r,r,m")
2384 (match_operand:SF 1 "input_operand" "rR,Q,S,m,rG"))]
2386 && (register_operand (operands[0], SFmode)
2387 || register_or_zero_operand (operands[1], SFmode))"
2389 if (GET_CODE (operands[1]) == CONST_DOUBLE
2390 && (which_alternative == 0
2391 || which_alternative == 1
2392 || which_alternative == 2))
2397 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2398 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2399 operands[1] = GEN_INT (i);
2402 switch (which_alternative)
2405 return "mov\t%1, %0";
2407 return "sethi\t%%hi(%a1), %0";
2411 return "ld\t%1, %0";
2413 return "st\t%r1, %0";
2418 [(set_attr "type" "*,*,*,load,store")])
2420 ;; The following 3 patterns build SFmode constants in integer registers.
2422 (define_insn "*movsf_lo_sum"
2423 [(set (match_operand:SF 0 "register_operand" "=r")
2424 (lo_sum:SF (match_operand:SF 1 "register_operand" "r")
2425 (match_operand:SF 2 "fp_const_high_losum_operand" "S")))]
2431 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[2]);
2432 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2433 operands[2] = GEN_INT (i);
2434 return "or\t%1, %%lo(%a2), %0";
2437 (define_insn "*movsf_high"
2438 [(set (match_operand:SF 0 "register_operand" "=r")
2439 (high:SF (match_operand:SF 1 "fp_const_high_losum_operand" "S")))]
2445 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2446 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2447 operands[1] = GEN_INT (i);
2448 return "sethi\t%%hi(%1), %0";
2452 [(set (match_operand:SF 0 "register_operand" "")
2453 (match_operand:SF 1 "fp_const_high_losum_operand" ""))]
2454 "REG_P (operands[0]) && REGNO (operands[0]) < 32"
2455 [(set (match_dup 0) (high:SF (match_dup 1)))
2456 (set (match_dup 0) (lo_sum:SF (match_dup 0) (match_dup 1)))])
2458 (define_mode_macro V64 [DF V2SI V4HI V8QI])
2460 ;; Yes, you again guessed it right, the former movdf expander.
2461 (define_expand "mov<V64:mode>"
2462 [(set (match_operand:V64 0 "nonimmediate_operand" "")
2463 (match_operand:V64 1 "general_operand" ""))]
2464 "<V64:MODE>mode == DFmode || TARGET_VIS"
2466 if (sparc_expand_move (<V64:MODE>mode, operands))
2470 ;; Be careful, fmovd does not exist when !v9.
2471 (define_insn "*movdf_insn_sp32"
2472 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,W,U,T,o,e,*r,o,e,o")
2473 (match_operand:DF 1 "input_operand" "W#F,e,T,U,G,e,*rFo,*r,o#F,e"))]
2476 && (register_operand (operands[0], DFmode)
2477 || register_or_zero_operand (operands[1], DFmode))"
2489 [(set_attr "type" "fpload,fpstore,load,store,*,*,*,*,*,*")
2490 (set_attr "length" "*,*,*,*,2,2,2,2,2,2")])
2492 (define_insn "*movdf_insn_sp32_no_fpu"
2493 [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,o,r,o")
2494 (match_operand:DF 1 "input_operand" "T,U,G,ro,r"))]
2497 && (register_operand (operands[0], DFmode)
2498 || register_or_zero_operand (operands[1], DFmode))"
2505 [(set_attr "type" "load,store,*,*,*")
2506 (set_attr "length" "*,*,2,2,2")])
2508 ;; We have available v9 double floats but not 64-bit integer registers.
2509 (define_insn "*movdf_insn_sp32_v9"
2510 [(set (match_operand:V64 0 "nonimmediate_operand" "=b,e,e,T,W,U,T,f,*r,o")
2511 (match_operand:V64 1 "input_operand" "GY,e,W#F,GY,e,T,U,o#F,*roGYF,*rGYf"))]
2515 && (register_operand (operands[0], <V64:MODE>mode)
2516 || register_or_zero_operand (operands[1], <V64:MODE>mode))"
2528 [(set_attr "type" "fga,fpmove,load,store,store,load,store,*,*,*")
2529 (set_attr "length" "*,*,*,*,*,*,*,2,2,2")
2530 (set_attr "fptype" "double,double,*,*,*,*,*,*,*,*")])
2532 (define_insn "*movdf_insn_sp32_v9_no_fpu"
2533 [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,T,r,o")
2534 (match_operand:DF 1 "input_operand" "T,U,G,ro,rG"))]
2538 && (register_operand (operands[0], DFmode)
2539 || register_or_zero_operand (operands[1], DFmode))"
2546 [(set_attr "type" "load,store,store,*,*")
2547 (set_attr "length" "*,*,*,2,2")])
2549 ;; We have available both v9 double floats and 64-bit integer registers.
2550 (define_insn "*movdf_insn_sp64"
2551 [(set (match_operand:V64 0 "nonimmediate_operand" "=b,e,e,W,*r,*r,m,*r")
2552 (match_operand:V64 1 "input_operand" "GY,e,W#F,e,*rGY,m,*rGY,F"))]
2555 && (register_operand (operands[0], <V64:MODE>mode)
2556 || register_or_zero_operand (operands[1], <V64:MODE>mode))"
2566 [(set_attr "type" "fga,fpmove,load,store,*,load,store,*")
2567 (set_attr "length" "*,*,*,*,*,*,*,2")
2568 (set_attr "fptype" "double,double,*,*,*,*,*,*")])
2570 (define_insn "*movdf_insn_sp64_no_fpu"
2571 [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m")
2572 (match_operand:DF 1 "input_operand" "r,m,rG"))]
2575 && (register_operand (operands[0], DFmode)
2576 || register_or_zero_operand (operands[1], DFmode))"
2581 [(set_attr "type" "*,load,store")])
2583 ;; This pattern build DFmode constants in integer registers.
2585 [(set (match_operand:DF 0 "register_operand" "")
2586 (match_operand:DF 1 "const_double_operand" ""))]
2588 && (GET_CODE (operands[0]) == REG
2589 && REGNO (operands[0]) < 32)
2590 && ! const_zero_operand(operands[1], DFmode)
2591 && reload_completed"
2592 [(clobber (const_int 0))]
2597 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2598 REAL_VALUE_TO_TARGET_DOUBLE (r, l);
2599 operands[0] = gen_rtx_raw_REG (DImode, REGNO (operands[0]));
2603 #if HOST_BITS_PER_WIDE_INT == 32
2608 val = ((HOST_WIDE_INT)(unsigned long)l[1] |
2609 ((HOST_WIDE_INT)(unsigned long)l[0] << 32));
2610 emit_insn (gen_movdi (operands[0], gen_int_mode (val, DImode)));
2615 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
2616 gen_int_mode (l[0], SImode)));
2618 /* Slick... but this trick loses if this subreg constant part
2619 can be done in one insn. */
2621 && ! SPARC_SETHI32_P (l[0])
2622 && ! SPARC_SIMM13_P (l[0]))
2624 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2625 gen_highpart (SImode, operands[0])));
2629 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2630 gen_int_mode (l[1], SImode)));
2636 ;; Ok, now the splits to handle all the multi insn and
2637 ;; mis-aligned memory address cases.
2638 ;; In these splits please take note that we must be
2639 ;; careful when V9 but not ARCH64 because the integer
2640 ;; register DFmode cases must be handled.
2642 [(set (match_operand:V64 0 "register_operand" "")
2643 (match_operand:V64 1 "register_operand" ""))]
2646 && ((GET_CODE (operands[0]) == REG
2647 && REGNO (operands[0]) < 32)
2648 || (GET_CODE (operands[0]) == SUBREG
2649 && GET_CODE (SUBREG_REG (operands[0])) == REG
2650 && REGNO (SUBREG_REG (operands[0])) < 32))))
2651 && reload_completed"
2652 [(clobber (const_int 0))]
2654 rtx set_dest = operands[0];
2655 rtx set_src = operands[1];
2658 enum machine_mode half_mode;
2660 /* We can be expanded for DFmode or integral vector modes. */
2661 if (<V64:MODE>mode == DFmode)
2666 dest1 = gen_highpart (half_mode, set_dest);
2667 dest2 = gen_lowpart (half_mode, set_dest);
2668 src1 = gen_highpart (half_mode, set_src);
2669 src2 = gen_lowpart (half_mode, set_src);
2671 /* Now emit using the real source and destination we found, swapping
2672 the order if we detect overlap. */
2673 if (reg_overlap_mentioned_p (dest1, src2))
2675 emit_move_insn_1 (dest2, src2);
2676 emit_move_insn_1 (dest1, src1);
2680 emit_move_insn_1 (dest1, src1);
2681 emit_move_insn_1 (dest2, src2);
2687 [(set (match_operand:V64 0 "register_operand" "")
2688 (match_operand:V64 1 "memory_operand" ""))]
2691 && (((REGNO (operands[0]) % 2) != 0)
2692 || ! mem_min_alignment (operands[1], 8))
2693 && offsettable_memref_p (operands[1])"
2694 [(clobber (const_int 0))]
2696 enum machine_mode half_mode;
2699 /* We can be expanded for DFmode or integral vector modes. */
2700 if (<V64:MODE>mode == DFmode)
2705 word0 = adjust_address (operands[1], half_mode, 0);
2706 word1 = adjust_address (operands[1], half_mode, 4);
2708 if (reg_overlap_mentioned_p (gen_highpart (half_mode, operands[0]), word1))
2710 emit_move_insn_1 (gen_lowpart (half_mode, operands[0]), word1);
2711 emit_move_insn_1 (gen_highpart (half_mode, operands[0]), word0);
2715 emit_move_insn_1 (gen_highpart (half_mode, operands[0]), word0);
2716 emit_move_insn_1 (gen_lowpart (half_mode, operands[0]), word1);
2722 [(set (match_operand:V64 0 "memory_operand" "")
2723 (match_operand:V64 1 "register_operand" ""))]
2726 && (((REGNO (operands[1]) % 2) != 0)
2727 || ! mem_min_alignment (operands[0], 8))
2728 && offsettable_memref_p (operands[0])"
2729 [(clobber (const_int 0))]
2731 enum machine_mode half_mode;
2734 /* We can be expanded for DFmode or integral vector modes. */
2735 if (<V64:MODE>mode == DFmode)
2740 word0 = adjust_address (operands[0], half_mode, 0);
2741 word1 = adjust_address (operands[0], half_mode, 4);
2743 emit_move_insn_1 (word0, gen_highpart (half_mode, operands[1]));
2744 emit_move_insn_1 (word1, gen_lowpart (half_mode, operands[1]));
2749 [(set (match_operand:V64 0 "memory_operand" "")
2750 (match_operand:V64 1 "const_zero_operand" ""))]
2754 && ! mem_min_alignment (operands[0], 8)))
2755 && offsettable_memref_p (operands[0])"
2756 [(clobber (const_int 0))]
2758 enum machine_mode half_mode;
2761 /* We can be expanded for DFmode or integral vector modes. */
2762 if (<V64:MODE>mode == DFmode)
2767 dest1 = adjust_address (operands[0], half_mode, 0);
2768 dest2 = adjust_address (operands[0], half_mode, 4);
2770 emit_move_insn_1 (dest1, CONST0_RTX (half_mode));
2771 emit_move_insn_1 (dest2, CONST0_RTX (half_mode));
2776 [(set (match_operand:V64 0 "register_operand" "")
2777 (match_operand:V64 1 "const_zero_operand" ""))]
2780 && ((GET_CODE (operands[0]) == REG
2781 && REGNO (operands[0]) < 32)
2782 || (GET_CODE (operands[0]) == SUBREG
2783 && GET_CODE (SUBREG_REG (operands[0])) == REG
2784 && REGNO (SUBREG_REG (operands[0])) < 32))"
2785 [(clobber (const_int 0))]
2787 enum machine_mode half_mode;
2788 rtx set_dest = operands[0];
2791 /* We can be expanded for DFmode or integral vector modes. */
2792 if (<V64:MODE>mode == DFmode)
2797 dest1 = gen_highpart (half_mode, set_dest);
2798 dest2 = gen_lowpart (half_mode, set_dest);
2799 emit_move_insn_1 (dest1, CONST0_RTX (half_mode));
2800 emit_move_insn_1 (dest2, CONST0_RTX (half_mode));
2804 (define_expand "movtf"
2805 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2806 (match_operand:TF 1 "general_operand" ""))]
2809 if (sparc_expand_move (TFmode, operands))
2813 (define_insn "*movtf_insn_sp32"
2814 [(set (match_operand:TF 0 "nonimmediate_operand" "=b,e,o,U,r")
2815 (match_operand:TF 1 "input_operand" "G,oe,GeUr,o,roG"))]
2818 && (register_operand (operands[0], TFmode)
2819 || register_or_zero_operand (operands[1], TFmode))"
2821 [(set_attr "length" "4")])
2823 ;; Exactly the same as above, except that all `e' cases are deleted.
2824 ;; This is necessary to prevent reload from ever trying to use a `e' reg
2827 (define_insn "*movtf_insn_sp32_no_fpu"
2828 [(set (match_operand:TF 0 "nonimmediate_operand" "=o,U,o,r,o")
2829 (match_operand:TF 1 "input_operand" "G,o,U,roG,r"))]
2832 && (register_operand (operands[0], TFmode)
2833 || register_or_zero_operand (operands[1], TFmode))"
2835 [(set_attr "length" "4")])
2837 (define_insn "*movtf_insn_sp64"
2838 [(set (match_operand:TF 0 "nonimmediate_operand" "=b,e,o,r")
2839 (match_operand:TF 1 "input_operand" "G,oe,Ger,roG"))]
2842 && ! TARGET_HARD_QUAD
2843 && (register_operand (operands[0], TFmode)
2844 || register_or_zero_operand (operands[1], TFmode))"
2846 [(set_attr "length" "2")])
2848 (define_insn "*movtf_insn_sp64_hq"
2849 [(set (match_operand:TF 0 "nonimmediate_operand" "=b,e,e,m,o,r")
2850 (match_operand:TF 1 "input_operand" "G,e,m,e,rG,roG"))]
2854 && (register_operand (operands[0], TFmode)
2855 || register_or_zero_operand (operands[1], TFmode))"
2863 [(set_attr "type" "*,fpmove,fpload,fpstore,*,*")
2864 (set_attr "length" "2,*,*,*,2,2")])
2866 (define_insn "*movtf_insn_sp64_no_fpu"
2867 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o")
2868 (match_operand:TF 1 "input_operand" "orG,rG"))]
2871 && (register_operand (operands[0], TFmode)
2872 || register_or_zero_operand (operands[1], TFmode))"
2874 [(set_attr "length" "2")])
2876 ;; Now all the splits to handle multi-insn TF mode moves.
2878 [(set (match_operand:TF 0 "register_operand" "")
2879 (match_operand:TF 1 "register_operand" ""))]
2883 && ! TARGET_HARD_QUAD)
2884 || ! fp_register_operand (operands[0], TFmode))"
2885 [(clobber (const_int 0))]
2887 rtx set_dest = operands[0];
2888 rtx set_src = operands[1];
2892 dest1 = gen_df_reg (set_dest, 0);
2893 dest2 = gen_df_reg (set_dest, 1);
2894 src1 = gen_df_reg (set_src, 0);
2895 src2 = gen_df_reg (set_src, 1);
2897 /* Now emit using the real source and destination we found, swapping
2898 the order if we detect overlap. */
2899 if (reg_overlap_mentioned_p (dest1, src2))
2901 emit_insn (gen_movdf (dest2, src2));
2902 emit_insn (gen_movdf (dest1, src1));
2906 emit_insn (gen_movdf (dest1, src1));
2907 emit_insn (gen_movdf (dest2, src2));
2913 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2914 (match_operand:TF 1 "const_zero_operand" ""))]
2916 [(clobber (const_int 0))]
2918 rtx set_dest = operands[0];
2921 switch (GET_CODE (set_dest))
2924 dest1 = gen_df_reg (set_dest, 0);
2925 dest2 = gen_df_reg (set_dest, 1);
2928 dest1 = adjust_address (set_dest, DFmode, 0);
2929 dest2 = adjust_address (set_dest, DFmode, 8);
2935 emit_insn (gen_movdf (dest1, CONST0_RTX (DFmode)));
2936 emit_insn (gen_movdf (dest2, CONST0_RTX (DFmode)));
2941 [(set (match_operand:TF 0 "register_operand" "")
2942 (match_operand:TF 1 "memory_operand" ""))]
2944 && offsettable_memref_p (operands[1])
2946 || ! TARGET_HARD_QUAD
2947 || ! fp_register_operand (operands[0], TFmode)))"
2948 [(clobber (const_int 0))]
2950 rtx word0 = adjust_address (operands[1], DFmode, 0);
2951 rtx word1 = adjust_address (operands[1], DFmode, 8);
2952 rtx set_dest, dest1, dest2;
2954 set_dest = operands[0];
2956 dest1 = gen_df_reg (set_dest, 0);
2957 dest2 = gen_df_reg (set_dest, 1);
2959 /* Now output, ordering such that we don't clobber any registers
2960 mentioned in the address. */
2961 if (reg_overlap_mentioned_p (dest1, word1))
2964 emit_insn (gen_movdf (dest2, word1));
2965 emit_insn (gen_movdf (dest1, word0));
2969 emit_insn (gen_movdf (dest1, word0));
2970 emit_insn (gen_movdf (dest2, word1));
2976 [(set (match_operand:TF 0 "memory_operand" "")
2977 (match_operand:TF 1 "register_operand" ""))]
2979 && offsettable_memref_p (operands[0])
2981 || ! TARGET_HARD_QUAD
2982 || ! fp_register_operand (operands[1], TFmode)))"
2983 [(clobber (const_int 0))]
2985 rtx set_src = operands[1];
2987 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 0),
2988 gen_df_reg (set_src, 0)));
2989 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 8),
2990 gen_df_reg (set_src, 1)));
2995 ;; SPARC-V9 conditional move instructions.
2997 ;; We can handle larger constants here for some flavors, but for now we keep
2998 ;; it simple and only allow those constants supported by all flavors.
2999 ;; Note that emit_conditional_move canonicalizes operands 2,3 so that operand
3000 ;; 3 contains the constant if one is present, but we handle either for
3001 ;; generality (sparc.c puts a constant in operand 2).
3003 (define_expand "movqicc"
3004 [(set (match_operand:QI 0 "register_operand" "")
3005 (if_then_else:QI (match_operand 1 "comparison_operator" "")
3006 (match_operand:QI 2 "arith10_operand" "")
3007 (match_operand:QI 3 "arith10_operand" "")))]
3010 enum rtx_code code = GET_CODE (operands[1]);
3012 if (GET_MODE (sparc_compare_op0) == DImode
3016 if (sparc_compare_op1 == const0_rtx
3017 && GET_CODE (sparc_compare_op0) == REG
3018 && GET_MODE (sparc_compare_op0) == DImode
3019 && v9_regcmp_p (code))
3021 operands[1] = gen_rtx_fmt_ee (code, DImode,
3022 sparc_compare_op0, sparc_compare_op1);
3026 rtx cc_reg = gen_compare_reg (code);
3027 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3031 (define_expand "movhicc"
3032 [(set (match_operand:HI 0 "register_operand" "")
3033 (if_then_else:HI (match_operand 1 "comparison_operator" "")
3034 (match_operand:HI 2 "arith10_operand" "")
3035 (match_operand:HI 3 "arith10_operand" "")))]
3038 enum rtx_code code = GET_CODE (operands[1]);
3040 if (GET_MODE (sparc_compare_op0) == DImode
3044 if (sparc_compare_op1 == const0_rtx
3045 && GET_CODE (sparc_compare_op0) == REG
3046 && GET_MODE (sparc_compare_op0) == DImode
3047 && v9_regcmp_p (code))
3049 operands[1] = gen_rtx_fmt_ee (code, DImode,
3050 sparc_compare_op0, sparc_compare_op1);
3054 rtx cc_reg = gen_compare_reg (code);
3055 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3059 (define_expand "movsicc"
3060 [(set (match_operand:SI 0 "register_operand" "")
3061 (if_then_else:SI (match_operand 1 "comparison_operator" "")
3062 (match_operand:SI 2 "arith10_operand" "")
3063 (match_operand:SI 3 "arith10_operand" "")))]
3066 enum rtx_code code = GET_CODE (operands[1]);
3067 enum machine_mode op0_mode = GET_MODE (sparc_compare_op0);
3069 if (sparc_compare_op1 == const0_rtx
3070 && GET_CODE (sparc_compare_op0) == REG
3071 && (TARGET_ARCH64 && op0_mode == DImode && v9_regcmp_p (code)))
3073 operands[1] = gen_rtx_fmt_ee (code, op0_mode,
3074 sparc_compare_op0, sparc_compare_op1);
3078 rtx cc_reg = gen_compare_reg (code);
3079 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg),
3080 cc_reg, const0_rtx);
3084 (define_expand "movdicc"
3085 [(set (match_operand:DI 0 "register_operand" "")
3086 (if_then_else:DI (match_operand 1 "comparison_operator" "")
3087 (match_operand:DI 2 "arith10_operand" "")
3088 (match_operand:DI 3 "arith10_operand" "")))]
3091 enum rtx_code code = GET_CODE (operands[1]);
3093 if (sparc_compare_op1 == const0_rtx
3094 && GET_CODE (sparc_compare_op0) == REG
3095 && GET_MODE (sparc_compare_op0) == DImode
3096 && v9_regcmp_p (code))
3098 operands[1] = gen_rtx_fmt_ee (code, DImode,
3099 sparc_compare_op0, sparc_compare_op1);
3103 rtx cc_reg = gen_compare_reg (code);
3104 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg),
3105 cc_reg, const0_rtx);
3109 (define_expand "movsfcc"
3110 [(set (match_operand:SF 0 "register_operand" "")
3111 (if_then_else:SF (match_operand 1 "comparison_operator" "")
3112 (match_operand:SF 2 "register_operand" "")
3113 (match_operand:SF 3 "register_operand" "")))]
3114 "TARGET_V9 && TARGET_FPU"
3116 enum rtx_code code = GET_CODE (operands[1]);
3118 if (GET_MODE (sparc_compare_op0) == DImode
3122 if (sparc_compare_op1 == const0_rtx
3123 && GET_CODE (sparc_compare_op0) == REG
3124 && GET_MODE (sparc_compare_op0) == DImode
3125 && v9_regcmp_p (code))
3127 operands[1] = gen_rtx_fmt_ee (code, DImode,
3128 sparc_compare_op0, sparc_compare_op1);
3132 rtx cc_reg = gen_compare_reg (code);
3133 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3137 (define_expand "movdfcc"
3138 [(set (match_operand:DF 0 "register_operand" "")
3139 (if_then_else:DF (match_operand 1 "comparison_operator" "")
3140 (match_operand:DF 2 "register_operand" "")
3141 (match_operand:DF 3 "register_operand" "")))]
3142 "TARGET_V9 && TARGET_FPU"
3144 enum rtx_code code = GET_CODE (operands[1]);
3146 if (GET_MODE (sparc_compare_op0) == DImode
3150 if (sparc_compare_op1 == const0_rtx
3151 && GET_CODE (sparc_compare_op0) == REG
3152 && GET_MODE (sparc_compare_op0) == DImode
3153 && v9_regcmp_p (code))
3155 operands[1] = gen_rtx_fmt_ee (code, DImode,
3156 sparc_compare_op0, sparc_compare_op1);
3160 rtx cc_reg = gen_compare_reg (code);
3161 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3165 (define_expand "movtfcc"
3166 [(set (match_operand:TF 0 "register_operand" "")
3167 (if_then_else:TF (match_operand 1 "comparison_operator" "")
3168 (match_operand:TF 2 "register_operand" "")
3169 (match_operand:TF 3 "register_operand" "")))]
3170 "TARGET_V9 && TARGET_FPU"
3172 enum rtx_code code = GET_CODE (operands[1]);
3174 if (GET_MODE (sparc_compare_op0) == DImode
3178 if (sparc_compare_op1 == const0_rtx
3179 && GET_CODE (sparc_compare_op0) == REG
3180 && GET_MODE (sparc_compare_op0) == DImode
3181 && v9_regcmp_p (code))
3183 operands[1] = gen_rtx_fmt_ee (code, DImode,
3184 sparc_compare_op0, sparc_compare_op1);
3188 rtx cc_reg = gen_compare_reg (code);
3189 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3193 ;; Conditional move define_insns.
3195 (define_insn "*movqi_cc_sp64"
3196 [(set (match_operand:QI 0 "register_operand" "=r,r")
3197 (if_then_else:QI (match_operator 1 "comparison_operator"
3198 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
3200 (match_operand:QI 3 "arith11_operand" "rL,0")
3201 (match_operand:QI 4 "arith11_operand" "0,rL")))]
3205 mov%c1\t%x2, %4, %0"
3206 [(set_attr "type" "cmove")])
3208 (define_insn "*movhi_cc_sp64"
3209 [(set (match_operand:HI 0 "register_operand" "=r,r")
3210 (if_then_else:HI (match_operator 1 "comparison_operator"
3211 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
3213 (match_operand:HI 3 "arith11_operand" "rL,0")
3214 (match_operand:HI 4 "arith11_operand" "0,rL")))]
3218 mov%c1\t%x2, %4, %0"
3219 [(set_attr "type" "cmove")])
3221 (define_insn "*movsi_cc_sp64"
3222 [(set (match_operand:SI 0 "register_operand" "=r,r")
3223 (if_then_else:SI (match_operator 1 "comparison_operator"
3224 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
3226 (match_operand:SI 3 "arith11_operand" "rL,0")
3227 (match_operand:SI 4 "arith11_operand" "0,rL")))]
3231 mov%c1\t%x2, %4, %0"
3232 [(set_attr "type" "cmove")])
3234 (define_insn "*movdi_cc_sp64"
3235 [(set (match_operand:DI 0 "register_operand" "=r,r")
3236 (if_then_else:DI (match_operator 1 "comparison_operator"
3237 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
3239 (match_operand:DI 3 "arith11_operand" "rL,0")
3240 (match_operand:DI 4 "arith11_operand" "0,rL")))]
3244 mov%c1\t%x2, %4, %0"
3245 [(set_attr "type" "cmove")])
3247 (define_insn "*movdi_cc_sp64_trunc"
3248 [(set (match_operand:SI 0 "register_operand" "=r,r")
3249 (if_then_else:SI (match_operator 1 "comparison_operator"
3250 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
3252 (match_operand:SI 3 "arith11_operand" "rL,0")
3253 (match_operand:SI 4 "arith11_operand" "0,rL")))]
3257 mov%c1\t%x2, %4, %0"
3258 [(set_attr "type" "cmove")])
3260 (define_insn "*movsf_cc_sp64"
3261 [(set (match_operand:SF 0 "register_operand" "=f,f")
3262 (if_then_else:SF (match_operator 1 "comparison_operator"
3263 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
3265 (match_operand:SF 3 "register_operand" "f,0")
3266 (match_operand:SF 4 "register_operand" "0,f")))]
3267 "TARGET_V9 && TARGET_FPU"
3269 fmovs%C1\t%x2, %3, %0
3270 fmovs%c1\t%x2, %4, %0"
3271 [(set_attr "type" "fpcmove")])
3273 (define_insn "movdf_cc_sp64"
3274 [(set (match_operand:DF 0 "register_operand" "=e,e")
3275 (if_then_else:DF (match_operator 1 "comparison_operator"
3276 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
3278 (match_operand:DF 3 "register_operand" "e,0")
3279 (match_operand:DF 4 "register_operand" "0,e")))]
3280 "TARGET_V9 && TARGET_FPU"
3282 fmovd%C1\t%x2, %3, %0
3283 fmovd%c1\t%x2, %4, %0"
3284 [(set_attr "type" "fpcmove")
3285 (set_attr "fptype" "double")])
3287 (define_insn "*movtf_cc_hq_sp64"
3288 [(set (match_operand:TF 0 "register_operand" "=e,e")
3289 (if_then_else:TF (match_operator 1 "comparison_operator"
3290 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
3292 (match_operand:TF 3 "register_operand" "e,0")
3293 (match_operand:TF 4 "register_operand" "0,e")))]
3294 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
3296 fmovq%C1\t%x2, %3, %0
3297 fmovq%c1\t%x2, %4, %0"
3298 [(set_attr "type" "fpcmove")])
3300 (define_insn_and_split "*movtf_cc_sp64"
3301 [(set (match_operand:TF 0 "register_operand" "=e,e")
3302 (if_then_else:TF (match_operator 1 "comparison_operator"
3303 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
3305 (match_operand:TF 3 "register_operand" "e,0")
3306 (match_operand:TF 4 "register_operand" "0,e")))]
3307 "TARGET_V9 && TARGET_FPU && !TARGET_HARD_QUAD"
3309 "&& reload_completed"
3310 [(clobber (const_int 0))]
3312 rtx set_dest = operands[0];
3313 rtx set_srca = operands[3];
3314 rtx set_srcb = operands[4];
3315 int third = rtx_equal_p (set_dest, set_srca);
3317 rtx srca1, srca2, srcb1, srcb2;
3319 dest1 = gen_df_reg (set_dest, 0);
3320 dest2 = gen_df_reg (set_dest, 1);
3321 srca1 = gen_df_reg (set_srca, 0);
3322 srca2 = gen_df_reg (set_srca, 1);
3323 srcb1 = gen_df_reg (set_srcb, 0);
3324 srcb2 = gen_df_reg (set_srcb, 1);
3326 /* Now emit using the real source and destination we found, swapping
3327 the order if we detect overlap. */
3328 if ((third && reg_overlap_mentioned_p (dest1, srcb2))
3329 || (!third && reg_overlap_mentioned_p (dest1, srca2)))
3331 emit_insn (gen_movdf_cc_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
3332 emit_insn (gen_movdf_cc_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
3336 emit_insn (gen_movdf_cc_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
3337 emit_insn (gen_movdf_cc_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
3341 [(set_attr "length" "2")])
3343 (define_insn "*movqi_cc_reg_sp64"
3344 [(set (match_operand:QI 0 "register_operand" "=r,r")
3345 (if_then_else:QI (match_operator 1 "v9_register_compare_operator"
3346 [(match_operand:DI 2 "register_operand" "r,r")
3348 (match_operand:QI 3 "arith10_operand" "rM,0")
3349 (match_operand:QI 4 "arith10_operand" "0,rM")))]
3352 movr%D1\t%2, %r3, %0
3353 movr%d1\t%2, %r4, %0"
3354 [(set_attr "type" "cmove")])
3356 (define_insn "*movhi_cc_reg_sp64"
3357 [(set (match_operand:HI 0 "register_operand" "=r,r")
3358 (if_then_else:HI (match_operator 1 "v9_register_compare_operator"
3359 [(match_operand:DI 2 "register_operand" "r,r")
3361 (match_operand:HI 3 "arith10_operand" "rM,0")
3362 (match_operand:HI 4 "arith10_operand" "0,rM")))]
3365 movr%D1\t%2, %r3, %0
3366 movr%d1\t%2, %r4, %0"
3367 [(set_attr "type" "cmove")])
3369 (define_insn "*movsi_cc_reg_sp64"
3370 [(set (match_operand:SI 0 "register_operand" "=r,r")
3371 (if_then_else:SI (match_operator 1 "v9_register_compare_operator"
3372 [(match_operand:DI 2 "register_operand" "r,r")
3374 (match_operand:SI 3 "arith10_operand" "rM,0")
3375 (match_operand:SI 4 "arith10_operand" "0,rM")))]
3378 movr%D1\t%2, %r3, %0
3379 movr%d1\t%2, %r4, %0"
3380 [(set_attr "type" "cmove")])
3382 (define_insn "*movdi_cc_reg_sp64"
3383 [(set (match_operand:DI 0 "register_operand" "=r,r")
3384 (if_then_else:DI (match_operator 1 "v9_register_compare_operator"
3385 [(match_operand:DI 2 "register_operand" "r,r")
3387 (match_operand:DI 3 "arith10_operand" "rM,0")
3388 (match_operand:DI 4 "arith10_operand" "0,rM")))]
3391 movr%D1\t%2, %r3, %0
3392 movr%d1\t%2, %r4, %0"
3393 [(set_attr "type" "cmove")])
3395 (define_insn "*movsf_cc_reg_sp64"
3396 [(set (match_operand:SF 0 "register_operand" "=f,f")
3397 (if_then_else:SF (match_operator 1 "v9_register_compare_operator"
3398 [(match_operand:DI 2 "register_operand" "r,r")
3400 (match_operand:SF 3 "register_operand" "f,0")
3401 (match_operand:SF 4 "register_operand" "0,f")))]
3402 "TARGET_ARCH64 && TARGET_FPU"
3404 fmovrs%D1\t%2, %3, %0
3405 fmovrs%d1\t%2, %4, %0"
3406 [(set_attr "type" "fpcrmove")])
3408 (define_insn "movdf_cc_reg_sp64"
3409 [(set (match_operand:DF 0 "register_operand" "=e,e")
3410 (if_then_else:DF (match_operator 1 "v9_register_compare_operator"
3411 [(match_operand:DI 2 "register_operand" "r,r")
3413 (match_operand:DF 3 "register_operand" "e,0")
3414 (match_operand:DF 4 "register_operand" "0,e")))]
3415 "TARGET_ARCH64 && TARGET_FPU"
3417 fmovrd%D1\t%2, %3, %0
3418 fmovrd%d1\t%2, %4, %0"
3419 [(set_attr "type" "fpcrmove")
3420 (set_attr "fptype" "double")])
3422 (define_insn "*movtf_cc_reg_hq_sp64"
3423 [(set (match_operand:TF 0 "register_operand" "=e,e")
3424 (if_then_else:TF (match_operator 1 "v9_register_compare_operator"
3425 [(match_operand:DI 2 "register_operand" "r,r")
3427 (match_operand:TF 3 "register_operand" "e,0")
3428 (match_operand:TF 4 "register_operand" "0,e")))]
3429 "TARGET_ARCH64 && TARGET_FPU && TARGET_HARD_QUAD"
3431 fmovrq%D1\t%2, %3, %0
3432 fmovrq%d1\t%2, %4, %0"
3433 [(set_attr "type" "fpcrmove")])
3435 (define_insn_and_split "*movtf_cc_reg_sp64"
3436 [(set (match_operand:TF 0 "register_operand" "=e,e")
3437 (if_then_else:TF (match_operator 1 "v9_register_compare_operator"
3438 [(match_operand:DI 2 "register_operand" "r,r")
3440 (match_operand:TF 3 "register_operand" "e,0")
3441 (match_operand:TF 4 "register_operand" "0,e")))]
3442 "TARGET_ARCH64 && TARGET_FPU && ! TARGET_HARD_QUAD"
3444 "&& reload_completed"
3445 [(clobber (const_int 0))]
3447 rtx set_dest = operands[0];
3448 rtx set_srca = operands[3];
3449 rtx set_srcb = operands[4];
3450 int third = rtx_equal_p (set_dest, set_srca);
3452 rtx srca1, srca2, srcb1, srcb2;
3454 dest1 = gen_df_reg (set_dest, 0);
3455 dest2 = gen_df_reg (set_dest, 1);
3456 srca1 = gen_df_reg (set_srca, 0);
3457 srca2 = gen_df_reg (set_srca, 1);
3458 srcb1 = gen_df_reg (set_srcb, 0);
3459 srcb2 = gen_df_reg (set_srcb, 1);
3461 /* Now emit using the real source and destination we found, swapping
3462 the order if we detect overlap. */
3463 if ((third && reg_overlap_mentioned_p (dest1, srcb2))
3464 || (!third && reg_overlap_mentioned_p (dest1, srca2)))
3466 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
3467 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
3471 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
3472 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
3476 [(set_attr "length" "2")])
3479 ;; Zero-extension instructions
3481 ;; These patterns originally accepted general_operands, however, slightly
3482 ;; better code is generated by only accepting register_operands, and then
3483 ;; letting combine generate the ldu[hb] insns.
3485 (define_expand "zero_extendhisi2"
3486 [(set (match_operand:SI 0 "register_operand" "")
3487 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
3490 rtx temp = gen_reg_rtx (SImode);
3491 rtx shift_16 = GEN_INT (16);
3492 int op1_subbyte = 0;
3494 if (GET_CODE (operand1) == SUBREG)
3496 op1_subbyte = SUBREG_BYTE (operand1);
3497 op1_subbyte /= GET_MODE_SIZE (SImode);
3498 op1_subbyte *= GET_MODE_SIZE (SImode);
3499 operand1 = XEXP (operand1, 0);
3502 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3504 emit_insn (gen_lshrsi3 (operand0, temp, shift_16));
3508 (define_insn "*zero_extendhisi2_insn"
3509 [(set (match_operand:SI 0 "register_operand" "=r")
3510 (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
3513 [(set_attr "type" "load")
3514 (set_attr "us3load_type" "3cycle")])
3516 (define_expand "zero_extendqihi2"
3517 [(set (match_operand:HI 0 "register_operand" "")
3518 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
3522 (define_insn "*zero_extendqihi2_insn"
3523 [(set (match_operand:HI 0 "register_operand" "=r,r")
3524 (zero_extend:HI (match_operand:QI 1 "input_operand" "r,m")))]
3525 "GET_CODE (operands[1]) != CONST_INT"
3529 [(set_attr "type" "*,load")
3530 (set_attr "us3load_type" "*,3cycle")])
3532 (define_expand "zero_extendqisi2"
3533 [(set (match_operand:SI 0 "register_operand" "")
3534 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
3538 (define_insn "*zero_extendqisi2_insn"
3539 [(set (match_operand:SI 0 "register_operand" "=r,r")
3540 (zero_extend:SI (match_operand:QI 1 "input_operand" "r,m")))]
3541 "GET_CODE (operands[1]) != CONST_INT"
3545 [(set_attr "type" "*,load")
3546 (set_attr "us3load_type" "*,3cycle")])
3548 (define_expand "zero_extendqidi2"
3549 [(set (match_operand:DI 0 "register_operand" "")
3550 (zero_extend:DI (match_operand:QI 1 "register_operand" "")))]
3554 (define_insn "*zero_extendqidi2_insn"
3555 [(set (match_operand:DI 0 "register_operand" "=r,r")
3556 (zero_extend:DI (match_operand:QI 1 "input_operand" "r,m")))]
3557 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
3561 [(set_attr "type" "*,load")
3562 (set_attr "us3load_type" "*,3cycle")])
3564 (define_expand "zero_extendhidi2"
3565 [(set (match_operand:DI 0 "register_operand" "")
3566 (zero_extend:DI (match_operand:HI 1 "register_operand" "")))]
3569 rtx temp = gen_reg_rtx (DImode);
3570 rtx shift_48 = GEN_INT (48);
3571 int op1_subbyte = 0;
3573 if (GET_CODE (operand1) == SUBREG)
3575 op1_subbyte = SUBREG_BYTE (operand1);
3576 op1_subbyte /= GET_MODE_SIZE (DImode);
3577 op1_subbyte *= GET_MODE_SIZE (DImode);
3578 operand1 = XEXP (operand1, 0);
3581 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
3583 emit_insn (gen_lshrdi3 (operand0, temp, shift_48));
3587 (define_insn "*zero_extendhidi2_insn"
3588 [(set (match_operand:DI 0 "register_operand" "=r")
3589 (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
3592 [(set_attr "type" "load")
3593 (set_attr "us3load_type" "3cycle")])
3595 ;; ??? Write truncdisi pattern using sra?
3597 (define_expand "zero_extendsidi2"
3598 [(set (match_operand:DI 0 "register_operand" "")
3599 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
3603 (define_insn "*zero_extendsidi2_insn_sp64"
3604 [(set (match_operand:DI 0 "register_operand" "=r,r")
3605 (zero_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
3606 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
3610 [(set_attr "type" "shift,load")])
3612 (define_insn_and_split "*zero_extendsidi2_insn_sp32"
3613 [(set (match_operand:DI 0 "register_operand" "=r")
3614 (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
3617 "&& reload_completed"
3618 [(set (match_dup 2) (match_dup 3))
3619 (set (match_dup 4) (match_dup 5))]
3623 dest1 = gen_highpart (SImode, operands[0]);
3624 dest2 = gen_lowpart (SImode, operands[0]);
3626 /* Swap the order in case of overlap. */
3627 if (REGNO (dest1) == REGNO (operands[1]))
3629 operands[2] = dest2;
3630 operands[3] = operands[1];
3631 operands[4] = dest1;
3632 operands[5] = const0_rtx;
3636 operands[2] = dest1;
3637 operands[3] = const0_rtx;
3638 operands[4] = dest2;
3639 operands[5] = operands[1];
3642 [(set_attr "length" "2")])
3644 ;; Simplify comparisons of extended values.
3646 (define_insn "*cmp_zero_extendqisi2"
3648 (compare:CC (zero_extend:SI (match_operand:QI 0 "register_operand" "r"))
3651 "andcc\t%0, 0xff, %%g0"
3652 [(set_attr "type" "compare")])
3654 (define_insn "*cmp_zero_qi"
3656 (compare:CC (match_operand:QI 0 "register_operand" "r")
3659 "andcc\t%0, 0xff, %%g0"
3660 [(set_attr "type" "compare")])
3662 (define_insn "*cmp_zero_extendqisi2_set"
3664 (compare:CC (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
3666 (set (match_operand:SI 0 "register_operand" "=r")
3667 (zero_extend:SI (match_dup 1)))]
3669 "andcc\t%1, 0xff, %0"
3670 [(set_attr "type" "compare")])
3672 (define_insn "*cmp_zero_extendqisi2_andcc_set"
3674 (compare:CC (and:SI (match_operand:SI 1 "register_operand" "r")
3677 (set (match_operand:SI 0 "register_operand" "=r")
3678 (zero_extend:SI (subreg:QI (match_dup 1) 0)))]
3680 "andcc\t%1, 0xff, %0"
3681 [(set_attr "type" "compare")])
3683 (define_insn "*cmp_zero_extendqidi2"
3685 (compare:CCX (zero_extend:DI (match_operand:QI 0 "register_operand" "r"))
3688 "andcc\t%0, 0xff, %%g0"
3689 [(set_attr "type" "compare")])
3691 (define_insn "*cmp_zero_qi_sp64"
3693 (compare:CCX (match_operand:QI 0 "register_operand" "r")
3696 "andcc\t%0, 0xff, %%g0"
3697 [(set_attr "type" "compare")])
3699 (define_insn "*cmp_zero_extendqidi2_set"
3701 (compare:CCX (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
3703 (set (match_operand:DI 0 "register_operand" "=r")
3704 (zero_extend:DI (match_dup 1)))]
3706 "andcc\t%1, 0xff, %0"
3707 [(set_attr "type" "compare")])
3709 (define_insn "*cmp_zero_extendqidi2_andcc_set"
3711 (compare:CCX (and:DI (match_operand:DI 1 "register_operand" "r")
3714 (set (match_operand:DI 0 "register_operand" "=r")
3715 (zero_extend:DI (subreg:QI (match_dup 1) 0)))]
3717 "andcc\t%1, 0xff, %0"
3718 [(set_attr "type" "compare")])
3720 ;; Similarly, handle {SI,DI}->QI mode truncation followed by a compare.
3722 (define_insn "*cmp_siqi_trunc"
3724 (compare:CC (subreg:QI (match_operand:SI 0 "register_operand" "r") 3)
3727 "andcc\t%0, 0xff, %%g0"
3728 [(set_attr "type" "compare")])
3730 (define_insn "*cmp_siqi_trunc_set"
3732 (compare:CC (subreg:QI (match_operand:SI 1 "register_operand" "r") 3)
3734 (set (match_operand:QI 0 "register_operand" "=r")
3735 (subreg:QI (match_dup 1) 3))]
3737 "andcc\t%1, 0xff, %0"
3738 [(set_attr "type" "compare")])
3740 (define_insn "*cmp_diqi_trunc"
3742 (compare:CC (subreg:QI (match_operand:DI 0 "register_operand" "r") 7)
3745 "andcc\t%0, 0xff, %%g0"
3746 [(set_attr "type" "compare")])
3748 (define_insn "*cmp_diqi_trunc_set"
3750 (compare:CC (subreg:QI (match_operand:DI 1 "register_operand" "r") 7)
3752 (set (match_operand:QI 0 "register_operand" "=r")
3753 (subreg:QI (match_dup 1) 7))]
3755 "andcc\t%1, 0xff, %0"
3756 [(set_attr "type" "compare")])
3759 ;; Sign-extension instructions
3761 ;; These patterns originally accepted general_operands, however, slightly
3762 ;; better code is generated by only accepting register_operands, and then
3763 ;; letting combine generate the lds[hb] insns.
3765 (define_expand "extendhisi2"
3766 [(set (match_operand:SI 0 "register_operand" "")
3767 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
3770 rtx temp = gen_reg_rtx (SImode);
3771 rtx shift_16 = GEN_INT (16);
3772 int op1_subbyte = 0;
3774 if (GET_CODE (operand1) == SUBREG)
3776 op1_subbyte = SUBREG_BYTE (operand1);
3777 op1_subbyte /= GET_MODE_SIZE (SImode);
3778 op1_subbyte *= GET_MODE_SIZE (SImode);
3779 operand1 = XEXP (operand1, 0);
3782 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3784 emit_insn (gen_ashrsi3 (operand0, temp, shift_16));
3788 (define_insn "*sign_extendhisi2_insn"
3789 [(set (match_operand:SI 0 "register_operand" "=r")
3790 (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
3793 [(set_attr "type" "sload")
3794 (set_attr "us3load_type" "3cycle")])
3796 (define_expand "extendqihi2"
3797 [(set (match_operand:HI 0 "register_operand" "")
3798 (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
3801 rtx temp = gen_reg_rtx (SImode);
3802 rtx shift_24 = GEN_INT (24);
3803 int op1_subbyte = 0;
3804 int op0_subbyte = 0;
3806 if (GET_CODE (operand1) == SUBREG)
3808 op1_subbyte = SUBREG_BYTE (operand1);
3809 op1_subbyte /= GET_MODE_SIZE (SImode);
3810 op1_subbyte *= GET_MODE_SIZE (SImode);
3811 operand1 = XEXP (operand1, 0);
3813 if (GET_CODE (operand0) == SUBREG)
3815 op0_subbyte = SUBREG_BYTE (operand0);
3816 op0_subbyte /= GET_MODE_SIZE (SImode);
3817 op0_subbyte *= GET_MODE_SIZE (SImode);
3818 operand0 = XEXP (operand0, 0);
3820 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3822 if (GET_MODE (operand0) != SImode)
3823 operand0 = gen_rtx_SUBREG (SImode, operand0, op0_subbyte);
3824 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
3828 (define_insn "*sign_extendqihi2_insn"
3829 [(set (match_operand:HI 0 "register_operand" "=r")
3830 (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
3833 [(set_attr "type" "sload")
3834 (set_attr "us3load_type" "3cycle")])
3836 (define_expand "extendqisi2"
3837 [(set (match_operand:SI 0 "register_operand" "")
3838 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
3841 rtx temp = gen_reg_rtx (SImode);
3842 rtx shift_24 = GEN_INT (24);
3843 int op1_subbyte = 0;
3845 if (GET_CODE (operand1) == SUBREG)
3847 op1_subbyte = SUBREG_BYTE (operand1);
3848 op1_subbyte /= GET_MODE_SIZE (SImode);
3849 op1_subbyte *= GET_MODE_SIZE (SImode);
3850 operand1 = XEXP (operand1, 0);
3853 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3855 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
3859 (define_insn "*sign_extendqisi2_insn"
3860 [(set (match_operand:SI 0 "register_operand" "=r")
3861 (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
3864 [(set_attr "type" "sload")
3865 (set_attr "us3load_type" "3cycle")])
3867 (define_expand "extendqidi2"
3868 [(set (match_operand:DI 0 "register_operand" "")
3869 (sign_extend:DI (match_operand:QI 1 "register_operand" "")))]
3872 rtx temp = gen_reg_rtx (DImode);
3873 rtx shift_56 = GEN_INT (56);
3874 int op1_subbyte = 0;
3876 if (GET_CODE (operand1) == SUBREG)
3878 op1_subbyte = SUBREG_BYTE (operand1);
3879 op1_subbyte /= GET_MODE_SIZE (DImode);
3880 op1_subbyte *= GET_MODE_SIZE (DImode);
3881 operand1 = XEXP (operand1, 0);
3884 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
3886 emit_insn (gen_ashrdi3 (operand0, temp, shift_56));
3890 (define_insn "*sign_extendqidi2_insn"
3891 [(set (match_operand:DI 0 "register_operand" "=r")
3892 (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
3895 [(set_attr "type" "sload")
3896 (set_attr "us3load_type" "3cycle")])
3898 (define_expand "extendhidi2"
3899 [(set (match_operand:DI 0 "register_operand" "")
3900 (sign_extend:DI (match_operand:HI 1 "register_operand" "")))]
3903 rtx temp = gen_reg_rtx (DImode);
3904 rtx shift_48 = GEN_INT (48);
3905 int op1_subbyte = 0;
3907 if (GET_CODE (operand1) == SUBREG)
3909 op1_subbyte = SUBREG_BYTE (operand1);
3910 op1_subbyte /= GET_MODE_SIZE (DImode);
3911 op1_subbyte *= GET_MODE_SIZE (DImode);
3912 operand1 = XEXP (operand1, 0);
3915 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
3917 emit_insn (gen_ashrdi3 (operand0, temp, shift_48));
3921 (define_insn "*sign_extendhidi2_insn"
3922 [(set (match_operand:DI 0 "register_operand" "=r")
3923 (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
3926 [(set_attr "type" "sload")
3927 (set_attr "us3load_type" "3cycle")])
3929 (define_expand "extendsidi2"
3930 [(set (match_operand:DI 0 "register_operand" "")
3931 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
3935 (define_insn "*sign_extendsidi2_insn"
3936 [(set (match_operand:DI 0 "register_operand" "=r,r")
3937 (sign_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
3942 [(set_attr "type" "shift,sload")
3943 (set_attr "us3load_type" "*,3cycle")])
3946 ;; Special pattern for optimizing bit-field compares. This is needed
3947 ;; because combine uses this as a canonical form.
3949 (define_insn "*cmp_zero_extract"
3952 (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
3953 (match_operand:SI 1 "small_int_operand" "I")
3954 (match_operand:SI 2 "small_int_operand" "I"))
3956 "INTVAL (operands[2]) > 19"
3958 int len = INTVAL (operands[1]);
3959 int pos = 32 - INTVAL (operands[2]) - len;
3960 HOST_WIDE_INT mask = ((1 << len) - 1) << pos;
3961 operands[1] = GEN_INT (mask);
3962 return "andcc\t%0, %1, %%g0";
3964 [(set_attr "type" "compare")])
3966 (define_insn "*cmp_zero_extract_sp64"
3969 (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
3970 (match_operand:SI 1 "small_int_operand" "I")
3971 (match_operand:SI 2 "small_int_operand" "I"))
3973 "TARGET_ARCH64 && INTVAL (operands[2]) > 51"
3975 int len = INTVAL (operands[1]);
3976 int pos = 64 - INTVAL (operands[2]) - len;
3977 HOST_WIDE_INT mask = (((unsigned HOST_WIDE_INT) 1 << len) - 1) << pos;
3978 operands[1] = GEN_INT (mask);
3979 return "andcc\t%0, %1, %%g0";
3981 [(set_attr "type" "compare")])
3984 ;; Conversions between float, double and long double.
3986 (define_insn "extendsfdf2"
3987 [(set (match_operand:DF 0 "register_operand" "=e")
3989 (match_operand:SF 1 "register_operand" "f")))]
3992 [(set_attr "type" "fp")
3993 (set_attr "fptype" "double")])
3995 (define_expand "extendsftf2"
3996 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3998 (match_operand:SF 1 "register_operand" "")))]
3999 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4000 "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
4002 (define_insn "*extendsftf2_hq"
4003 [(set (match_operand:TF 0 "register_operand" "=e")
4005 (match_operand:SF 1 "register_operand" "f")))]
4006 "TARGET_FPU && TARGET_HARD_QUAD"
4008 [(set_attr "type" "fp")])
4010 (define_expand "extenddftf2"
4011 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4013 (match_operand:DF 1 "register_operand" "")))]
4014 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4015 "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
4017 (define_insn "*extenddftf2_hq"
4018 [(set (match_operand:TF 0 "register_operand" "=e")
4020 (match_operand:DF 1 "register_operand" "e")))]
4021 "TARGET_FPU && TARGET_HARD_QUAD"
4023 [(set_attr "type" "fp")])
4025 (define_insn "truncdfsf2"
4026 [(set (match_operand:SF 0 "register_operand" "=f")
4028 (match_operand:DF 1 "register_operand" "e")))]
4031 [(set_attr "type" "fp")
4032 (set_attr "fptype" "double")])
4034 (define_expand "trunctfsf2"
4035 [(set (match_operand:SF 0 "register_operand" "")
4037 (match_operand:TF 1 "general_operand" "")))]
4038 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4039 "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
4041 (define_insn "*trunctfsf2_hq"
4042 [(set (match_operand:SF 0 "register_operand" "=f")
4044 (match_operand:TF 1 "register_operand" "e")))]
4045 "TARGET_FPU && TARGET_HARD_QUAD"
4047 [(set_attr "type" "fp")])
4049 (define_expand "trunctfdf2"
4050 [(set (match_operand:DF 0 "register_operand" "")
4052 (match_operand:TF 1 "general_operand" "")))]
4053 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4054 "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
4056 (define_insn "*trunctfdf2_hq"
4057 [(set (match_operand:DF 0 "register_operand" "=e")
4059 (match_operand:TF 1 "register_operand" "e")))]
4060 "TARGET_FPU && TARGET_HARD_QUAD"
4062 [(set_attr "type" "fp")])
4065 ;; Conversion between fixed point and floating point.
4067 (define_insn "floatsisf2"
4068 [(set (match_operand:SF 0 "register_operand" "=f")
4069 (float:SF (match_operand:SI 1 "register_operand" "f")))]
4072 [(set_attr "type" "fp")
4073 (set_attr "fptype" "double")])
4075 (define_insn "floatsidf2"
4076 [(set (match_operand:DF 0 "register_operand" "=e")
4077 (float:DF (match_operand:SI 1 "register_operand" "f")))]
4080 [(set_attr "type" "fp")
4081 (set_attr "fptype" "double")])
4083 (define_expand "floatsitf2"
4084 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4085 (float:TF (match_operand:SI 1 "register_operand" "")))]
4086 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4087 "emit_tfmode_cvt (FLOAT, operands); DONE;")
4089 (define_insn "*floatsitf2_hq"
4090 [(set (match_operand:TF 0 "register_operand" "=e")
4091 (float:TF (match_operand:SI 1 "register_operand" "f")))]
4092 "TARGET_FPU && TARGET_HARD_QUAD"
4094 [(set_attr "type" "fp")])
4096 (define_expand "floatunssitf2"
4097 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4098 (unsigned_float:TF (match_operand:SI 1 "register_operand" "")))]
4099 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4100 "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
4102 ;; Now the same for 64 bit sources.
4104 (define_insn "floatdisf2"
4105 [(set (match_operand:SF 0 "register_operand" "=f")
4106 (float:SF (match_operand:DI 1 "register_operand" "e")))]
4107 "TARGET_V9 && TARGET_FPU"
4109 [(set_attr "type" "fp")
4110 (set_attr "fptype" "double")])
4112 (define_expand "floatunsdisf2"
4113 [(use (match_operand:SF 0 "register_operand" ""))
4114 (use (match_operand:DI 1 "general_operand" ""))]
4115 "TARGET_ARCH64 && TARGET_FPU"
4116 "sparc_emit_floatunsdi (operands, SFmode); DONE;")
4118 (define_insn "floatdidf2"
4119 [(set (match_operand:DF 0 "register_operand" "=e")
4120 (float:DF (match_operand:DI 1 "register_operand" "e")))]
4121 "TARGET_V9 && TARGET_FPU"
4123 [(set_attr "type" "fp")
4124 (set_attr "fptype" "double")])
4126 (define_expand "floatunsdidf2"
4127 [(use (match_operand:DF 0 "register_operand" ""))
4128 (use (match_operand:DI 1 "general_operand" ""))]
4129 "TARGET_ARCH64 && TARGET_FPU"
4130 "sparc_emit_floatunsdi (operands, DFmode); DONE;")
4132 (define_expand "floatditf2"
4133 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4134 (float:TF (match_operand:DI 1 "register_operand" "")))]
4135 "TARGET_FPU && TARGET_V9 && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4136 "emit_tfmode_cvt (FLOAT, operands); DONE;")
4138 (define_insn "*floatditf2_hq"
4139 [(set (match_operand:TF 0 "register_operand" "=e")
4140 (float:TF (match_operand:DI 1 "register_operand" "e")))]
4141 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
4143 [(set_attr "type" "fp")])
4145 (define_expand "floatunsditf2"
4146 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4147 (unsigned_float:TF (match_operand:DI 1 "register_operand" "")))]
4148 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4149 "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
4151 ;; Convert a float to an actual integer.
4152 ;; Truncation is performed as part of the conversion.
4154 (define_insn "fix_truncsfsi2"
4155 [(set (match_operand:SI 0 "register_operand" "=f")
4156 (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
4159 [(set_attr "type" "fp")
4160 (set_attr "fptype" "double")])
4162 (define_insn "fix_truncdfsi2"
4163 [(set (match_operand:SI 0 "register_operand" "=f")
4164 (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
4167 [(set_attr "type" "fp")
4168 (set_attr "fptype" "double")])
4170 (define_expand "fix_trunctfsi2"
4171 [(set (match_operand:SI 0 "register_operand" "")
4172 (fix:SI (match_operand:TF 1 "general_operand" "")))]
4173 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4174 "emit_tfmode_cvt (FIX, operands); DONE;")
4176 (define_insn "*fix_trunctfsi2_hq"
4177 [(set (match_operand:SI 0 "register_operand" "=f")
4178 (fix:SI (match_operand:TF 1 "register_operand" "e")))]
4179 "TARGET_FPU && TARGET_HARD_QUAD"
4181 [(set_attr "type" "fp")])
4183 (define_expand "fixuns_trunctfsi2"
4184 [(set (match_operand:SI 0 "register_operand" "")
4185 (unsigned_fix:SI (match_operand:TF 1 "general_operand" "")))]
4186 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4187 "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
4189 ;; Now the same, for V9 targets
4191 (define_insn "fix_truncsfdi2"
4192 [(set (match_operand:DI 0 "register_operand" "=e")
4193 (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
4194 "TARGET_V9 && TARGET_FPU"
4196 [(set_attr "type" "fp")
4197 (set_attr "fptype" "double")])
4199 (define_expand "fixuns_truncsfdi2"
4200 [(use (match_operand:DI 0 "register_operand" ""))
4201 (use (match_operand:SF 1 "general_operand" ""))]
4202 "TARGET_ARCH64 && TARGET_FPU"
4203 "sparc_emit_fixunsdi (operands, SFmode); DONE;")
4205 (define_insn "fix_truncdfdi2"
4206 [(set (match_operand:DI 0 "register_operand" "=e")
4207 (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
4208 "TARGET_V9 && TARGET_FPU"
4210 [(set_attr "type" "fp")
4211 (set_attr "fptype" "double")])
4213 (define_expand "fixuns_truncdfdi2"
4214 [(use (match_operand:DI 0 "register_operand" ""))
4215 (use (match_operand:DF 1 "general_operand" ""))]
4216 "TARGET_ARCH64 && TARGET_FPU"
4217 "sparc_emit_fixunsdi (operands, DFmode); DONE;")
4219 (define_expand "fix_trunctfdi2"
4220 [(set (match_operand:DI 0 "register_operand" "")
4221 (fix:DI (match_operand:TF 1 "general_operand" "")))]
4222 "TARGET_V9 && TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4223 "emit_tfmode_cvt (FIX, operands); DONE;")
4225 (define_insn "*fix_trunctfdi2_hq"
4226 [(set (match_operand:DI 0 "register_operand" "=e")
4227 (fix:DI (match_operand:TF 1 "register_operand" "e")))]
4228 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
4230 [(set_attr "type" "fp")])
4232 (define_expand "fixuns_trunctfdi2"
4233 [(set (match_operand:DI 0 "register_operand" "")
4234 (unsigned_fix:DI (match_operand:TF 1 "general_operand" "")))]
4235 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4236 "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
4239 ;; Integer addition/subtraction instructions.
4241 (define_expand "adddi3"
4242 [(set (match_operand:DI 0 "register_operand" "")
4243 (plus:DI (match_operand:DI 1 "register_operand" "")
4244 (match_operand:DI 2 "arith_double_add_operand" "")))]
4247 if (! TARGET_ARCH64)
4249 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
4250 gen_rtx_SET (VOIDmode, operands[0],
4251 gen_rtx_PLUS (DImode, operands[1],
4253 gen_rtx_CLOBBER (VOIDmode,
4254 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
4259 (define_insn_and_split "adddi3_insn_sp32"
4260 [(set (match_operand:DI 0 "register_operand" "=r")
4261 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
4262 (match_operand:DI 2 "arith_double_operand" "rHI")))
4263 (clobber (reg:CC 100))]
4266 "&& reload_completed"
4267 [(parallel [(set (reg:CC_NOOV 100)
4268 (compare:CC_NOOV (plus:SI (match_dup 4)
4272 (plus:SI (match_dup 4) (match_dup 5)))])
4274 (plus:SI (plus:SI (match_dup 7)
4276 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4278 operands[3] = gen_lowpart (SImode, operands[0]);
4279 operands[4] = gen_lowpart (SImode, operands[1]);
4280 operands[5] = gen_lowpart (SImode, operands[2]);
4281 operands[6] = gen_highpart (SImode, operands[0]);
4282 operands[7] = gen_highpart_mode (SImode, DImode, operands[1]);
4283 #if HOST_BITS_PER_WIDE_INT == 32
4284 if (GET_CODE (operands[2]) == CONST_INT)
4286 if (INTVAL (operands[2]) < 0)
4287 operands[8] = constm1_rtx;
4289 operands[8] = const0_rtx;
4293 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
4295 [(set_attr "length" "2")])
4297 ;; LTU here means "carry set"
4299 [(set (match_operand:SI 0 "register_operand" "=r")
4300 (plus:SI (plus:SI (match_operand:SI 1 "arith_operand" "%r")
4301 (match_operand:SI 2 "arith_operand" "rI"))
4302 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4305 [(set_attr "type" "ialuX")])
4307 (define_insn_and_split "*addx_extend_sp32"
4308 [(set (match_operand:DI 0 "register_operand" "=r")
4309 (zero_extend:DI (plus:SI (plus:SI
4310 (match_operand:SI 1 "register_or_zero_operand" "%rJ")
4311 (match_operand:SI 2 "arith_operand" "rI"))
4312 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4315 "&& reload_completed"
4316 [(set (match_dup 3) (plus:SI (plus:SI (match_dup 1) (match_dup 2))
4317 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
4318 (set (match_dup 4) (const_int 0))]
4319 "operands[3] = gen_lowpart (SImode, operands[0]);
4320 operands[4] = gen_highpart_mode (SImode, DImode, operands[1]);"
4321 [(set_attr "length" "2")])
4323 (define_insn "*addx_extend_sp64"
4324 [(set (match_operand:DI 0 "register_operand" "=r")
4325 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ")
4326 (match_operand:SI 2 "arith_operand" "rI"))
4327 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4330 [(set_attr "type" "ialuX")])
4332 (define_insn_and_split ""
4333 [(set (match_operand:DI 0 "register_operand" "=r")
4334 (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4335 (match_operand:DI 2 "register_operand" "r")))
4336 (clobber (reg:CC 100))]
4339 "&& reload_completed"
4340 [(parallel [(set (reg:CC_NOOV 100)
4341 (compare:CC_NOOV (plus:SI (match_dup 3) (match_dup 1))
4343 (set (match_dup 5) (plus:SI (match_dup 3) (match_dup 1)))])
4345 (plus:SI (plus:SI (match_dup 4) (const_int 0))
4346 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4347 "operands[3] = gen_lowpart (SImode, operands[2]);
4348 operands[4] = gen_highpart (SImode, operands[2]);
4349 operands[5] = gen_lowpart (SImode, operands[0]);
4350 operands[6] = gen_highpart (SImode, operands[0]);"
4351 [(set_attr "length" "2")])
4353 (define_insn "*adddi3_sp64"
4354 [(set (match_operand:DI 0 "register_operand" "=r,r")
4355 (plus:DI (match_operand:DI 1 "register_operand" "%r,r")
4356 (match_operand:DI 2 "arith_add_operand" "rI,O")))]
4362 (define_insn "addsi3"
4363 [(set (match_operand:SI 0 "register_operand" "=r,r,d")
4364 (plus:SI (match_operand:SI 1 "register_operand" "%r,r,d")
4365 (match_operand:SI 2 "arith_add_operand" "rI,O,d")))]
4370 fpadd32s\t%1, %2, %0"
4371 [(set_attr "type" "*,*,fga")
4372 (set_attr "fptype" "*,*,single")])
4374 (define_insn "*cmp_cc_plus"
4375 [(set (reg:CC_NOOV 100)
4376 (compare:CC_NOOV (plus:SI (match_operand:SI 0 "arith_operand" "%r")
4377 (match_operand:SI 1 "arith_operand" "rI"))
4380 "addcc\t%0, %1, %%g0"
4381 [(set_attr "type" "compare")])
4383 (define_insn "*cmp_ccx_plus"
4384 [(set (reg:CCX_NOOV 100)
4385 (compare:CCX_NOOV (plus:DI (match_operand:DI 0 "arith_operand" "%r")
4386 (match_operand:DI 1 "arith_operand" "rI"))
4389 "addcc\t%0, %1, %%g0"
4390 [(set_attr "type" "compare")])
4392 (define_insn "*cmp_cc_plus_set"
4393 [(set (reg:CC_NOOV 100)
4394 (compare:CC_NOOV (plus:SI (match_operand:SI 1 "arith_operand" "%r")
4395 (match_operand:SI 2 "arith_operand" "rI"))
4397 (set (match_operand:SI 0 "register_operand" "=r")
4398 (plus:SI (match_dup 1) (match_dup 2)))]
4401 [(set_attr "type" "compare")])
4403 (define_insn "*cmp_ccx_plus_set"
4404 [(set (reg:CCX_NOOV 100)
4405 (compare:CCX_NOOV (plus:DI (match_operand:DI 1 "arith_operand" "%r")
4406 (match_operand:DI 2 "arith_operand" "rI"))
4408 (set (match_operand:DI 0 "register_operand" "=r")
4409 (plus:DI (match_dup 1) (match_dup 2)))]
4412 [(set_attr "type" "compare")])
4414 (define_expand "subdi3"
4415 [(set (match_operand:DI 0 "register_operand" "")
4416 (minus:DI (match_operand:DI 1 "register_operand" "")
4417 (match_operand:DI 2 "arith_double_add_operand" "")))]
4420 if (! TARGET_ARCH64)
4422 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
4423 gen_rtx_SET (VOIDmode, operands[0],
4424 gen_rtx_MINUS (DImode, operands[1],
4426 gen_rtx_CLOBBER (VOIDmode,
4427 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
4432 (define_insn_and_split "subdi3_insn_sp32"
4433 [(set (match_operand:DI 0 "register_operand" "=r")
4434 (minus:DI (match_operand:DI 1 "register_operand" "r")
4435 (match_operand:DI 2 "arith_double_operand" "rHI")))
4436 (clobber (reg:CC 100))]
4439 "&& reload_completed"
4440 [(parallel [(set (reg:CC_NOOV 100)
4441 (compare:CC_NOOV (minus:SI (match_dup 4)
4445 (minus:SI (match_dup 4) (match_dup 5)))])
4447 (minus:SI (minus:SI (match_dup 7)
4449 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4451 operands[3] = gen_lowpart (SImode, operands[0]);
4452 operands[4] = gen_lowpart (SImode, operands[1]);
4453 operands[5] = gen_lowpart (SImode, operands[2]);
4454 operands[6] = gen_highpart (SImode, operands[0]);
4455 operands[7] = gen_highpart (SImode, operands[1]);
4456 #if HOST_BITS_PER_WIDE_INT == 32
4457 if (GET_CODE (operands[2]) == CONST_INT)
4459 if (INTVAL (operands[2]) < 0)
4460 operands[8] = constm1_rtx;
4462 operands[8] = const0_rtx;
4466 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
4468 [(set_attr "length" "2")])
4470 ;; LTU here means "carry set"
4472 [(set (match_operand:SI 0 "register_operand" "=r")
4473 (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
4474 (match_operand:SI 2 "arith_operand" "rI"))
4475 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4478 [(set_attr "type" "ialuX")])
4480 (define_insn "*subx_extend_sp64"
4481 [(set (match_operand:DI 0 "register_operand" "=r")
4482 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
4483 (match_operand:SI 2 "arith_operand" "rI"))
4484 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4487 [(set_attr "type" "ialuX")])
4489 (define_insn_and_split "*subx_extend"
4490 [(set (match_operand:DI 0 "register_operand" "=r")
4491 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
4492 (match_operand:SI 2 "arith_operand" "rI"))
4493 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4496 "&& reload_completed"
4497 [(set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 2))
4498 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
4499 (set (match_dup 4) (const_int 0))]
4500 "operands[3] = gen_lowpart (SImode, operands[0]);
4501 operands[4] = gen_highpart (SImode, operands[0]);"
4502 [(set_attr "length" "2")])
4504 (define_insn_and_split ""
4505 [(set (match_operand:DI 0 "register_operand" "=r")
4506 (minus:DI (match_operand:DI 1 "register_operand" "r")
4507 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))
4508 (clobber (reg:CC 100))]
4511 "&& reload_completed"
4512 [(parallel [(set (reg:CC_NOOV 100)
4513 (compare:CC_NOOV (minus:SI (match_dup 3) (match_dup 2))
4515 (set (match_dup 5) (minus:SI (match_dup 3) (match_dup 2)))])
4517 (minus:SI (minus:SI (match_dup 4) (const_int 0))
4518 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4519 "operands[3] = gen_lowpart (SImode, operands[1]);
4520 operands[4] = gen_highpart (SImode, operands[1]);
4521 operands[5] = gen_lowpart (SImode, operands[0]);
4522 operands[6] = gen_highpart (SImode, operands[0]);"
4523 [(set_attr "length" "2")])
4525 (define_insn "*subdi3_sp64"
4526 [(set (match_operand:DI 0 "register_operand" "=r,r")
4527 (minus:DI (match_operand:DI 1 "register_operand" "r,r")
4528 (match_operand:DI 2 "arith_add_operand" "rI,O")))]
4534 (define_insn "subsi3"
4535 [(set (match_operand:SI 0 "register_operand" "=r,r,d")
4536 (minus:SI (match_operand:SI 1 "register_operand" "r,r,d")
4537 (match_operand:SI 2 "arith_add_operand" "rI,O,d")))]
4542 fpsub32s\t%1, %2, %0"
4543 [(set_attr "type" "*,*,fga")
4544 (set_attr "fptype" "*,*,single")])
4546 (define_insn "*cmp_minus_cc"
4547 [(set (reg:CC_NOOV 100)
4548 (compare:CC_NOOV (minus:SI (match_operand:SI 0 "register_or_zero_operand" "rJ")
4549 (match_operand:SI 1 "arith_operand" "rI"))
4552 "subcc\t%r0, %1, %%g0"
4553 [(set_attr "type" "compare")])
4555 (define_insn "*cmp_minus_ccx"
4556 [(set (reg:CCX_NOOV 100)
4557 (compare:CCX_NOOV (minus:DI (match_operand:DI 0 "register_operand" "r")
4558 (match_operand:DI 1 "arith_operand" "rI"))
4561 "subcc\t%0, %1, %%g0"
4562 [(set_attr "type" "compare")])
4564 (define_insn "cmp_minus_cc_set"
4565 [(set (reg:CC_NOOV 100)
4566 (compare:CC_NOOV (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
4567 (match_operand:SI 2 "arith_operand" "rI"))
4569 (set (match_operand:SI 0 "register_operand" "=r")
4570 (minus:SI (match_dup 1) (match_dup 2)))]
4572 "subcc\t%r1, %2, %0"
4573 [(set_attr "type" "compare")])
4575 (define_insn "*cmp_minus_ccx_set"
4576 [(set (reg:CCX_NOOV 100)
4577 (compare:CCX_NOOV (minus:DI (match_operand:DI 1 "register_operand" "r")
4578 (match_operand:DI 2 "arith_operand" "rI"))
4580 (set (match_operand:DI 0 "register_operand" "=r")
4581 (minus:DI (match_dup 1) (match_dup 2)))]
4584 [(set_attr "type" "compare")])
4587 ;; Integer multiply/divide instructions.
4589 ;; The 32 bit multiply/divide instructions are deprecated on v9, but at
4590 ;; least in UltraSPARC I, II and IIi it is a win tick-wise.
4592 (define_insn "mulsi3"
4593 [(set (match_operand:SI 0 "register_operand" "=r")
4594 (mult:SI (match_operand:SI 1 "arith_operand" "%r")
4595 (match_operand:SI 2 "arith_operand" "rI")))]
4598 [(set_attr "type" "imul")])
4600 (define_expand "muldi3"
4601 [(set (match_operand:DI 0 "register_operand" "")
4602 (mult:DI (match_operand:DI 1 "arith_operand" "")
4603 (match_operand:DI 2 "arith_operand" "")))]
4604 "TARGET_ARCH64 || TARGET_V8PLUS"
4608 emit_insn (gen_muldi3_v8plus (operands[0], operands[1], operands[2]));
4613 (define_insn "*muldi3_sp64"
4614 [(set (match_operand:DI 0 "register_operand" "=r")
4615 (mult:DI (match_operand:DI 1 "arith_operand" "%r")
4616 (match_operand:DI 2 "arith_operand" "rI")))]
4619 [(set_attr "type" "imul")])
4621 ;; V8plus wide multiply.
4623 (define_insn "muldi3_v8plus"
4624 [(set (match_operand:DI 0 "register_operand" "=r,h")
4625 (mult:DI (match_operand:DI 1 "arith_operand" "%r,0")
4626 (match_operand:DI 2 "arith_operand" "rI,rI")))
4627 (clobber (match_scratch:SI 3 "=&h,X"))
4628 (clobber (match_scratch:SI 4 "=&h,X"))]
4631 if (sparc_check_64 (operands[1], insn) <= 0)
4632 output_asm_insn ("srl\t%L1, 0, %L1", operands);
4633 if (which_alternative == 1)
4634 output_asm_insn ("sllx\t%H1, 32, %H1", operands);
4635 if (GET_CODE (operands[2]) == CONST_INT)
4637 if (which_alternative == 1)
4638 return "or\t%L1, %H1, %H1\n\tmulx\t%H1, %2, %L0\;srlx\t%L0, 32, %H0";
4640 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";
4642 else if (rtx_equal_p (operands[1], operands[2]))
4644 if (which_alternative == 1)
4645 return "or\t%L1, %H1, %H1\n\tmulx\t%H1, %H1, %L0\;srlx\t%L0, 32, %H0";
4647 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";
4649 if (sparc_check_64 (operands[2], insn) <= 0)
4650 output_asm_insn ("srl\t%L2, 0, %L2", operands);
4651 if (which_alternative == 1)
4652 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";
4654 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";
4656 [(set_attr "type" "multi")
4657 (set_attr "length" "9,8")])
4659 (define_insn "*cmp_mul_set"
4661 (compare:CC (mult:SI (match_operand:SI 1 "arith_operand" "%r")
4662 (match_operand:SI 2 "arith_operand" "rI"))
4664 (set (match_operand:SI 0 "register_operand" "=r")
4665 (mult:SI (match_dup 1) (match_dup 2)))]
4666 "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS"
4667 "smulcc\t%1, %2, %0"
4668 [(set_attr "type" "imul")])
4670 (define_expand "mulsidi3"
4671 [(set (match_operand:DI 0 "register_operand" "")
4672 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
4673 (sign_extend:DI (match_operand:SI 2 "arith_operand" ""))))]
4676 if (CONSTANT_P (operands[2]))
4679 emit_insn (gen_const_mulsidi3_v8plus (operands[0], operands[1],
4681 else if (TARGET_ARCH32)
4682 emit_insn (gen_const_mulsidi3_sp32 (operands[0], operands[1],
4685 emit_insn (gen_const_mulsidi3_sp64 (operands[0], operands[1],
4691 emit_insn (gen_mulsidi3_v8plus (operands[0], operands[1], operands[2]));
4696 ;; V9 puts the 64 bit product in a 64 bit register. Only out or global
4697 ;; registers can hold 64 bit values in the V8plus environment.
4699 (define_insn "mulsidi3_v8plus"
4700 [(set (match_operand:DI 0 "register_operand" "=h,r")
4701 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4702 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
4703 (clobber (match_scratch:SI 3 "=X,&h"))]
4706 smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
4707 smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4708 [(set_attr "type" "multi")
4709 (set_attr "length" "2,3")])
4712 (define_insn "const_mulsidi3_v8plus"
4713 [(set (match_operand:DI 0 "register_operand" "=h,r")
4714 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4715 (match_operand:DI 2 "small_int_operand" "I,I")))
4716 (clobber (match_scratch:SI 3 "=X,&h"))]
4719 smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
4720 smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4721 [(set_attr "type" "multi")
4722 (set_attr "length" "2,3")])
4725 (define_insn "*mulsidi3_sp32"
4726 [(set (match_operand:DI 0 "register_operand" "=r")
4727 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4728 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4731 return TARGET_SPARCLET
4732 ? "smuld\t%1, %2, %L0"
4733 : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
4736 (if_then_else (eq_attr "isa" "sparclet")
4737 (const_string "imul") (const_string "multi")))
4738 (set (attr "length")
4739 (if_then_else (eq_attr "isa" "sparclet")
4740 (const_int 1) (const_int 2)))])
4742 (define_insn "*mulsidi3_sp64"
4743 [(set (match_operand:DI 0 "register_operand" "=r")
4744 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4745 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4746 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4748 [(set_attr "type" "imul")])
4750 ;; Extra pattern, because sign_extend of a constant isn't valid.
4753 (define_insn "const_mulsidi3_sp32"
4754 [(set (match_operand:DI 0 "register_operand" "=r")
4755 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4756 (match_operand:DI 2 "small_int_operand" "I")))]
4759 return TARGET_SPARCLET
4760 ? "smuld\t%1, %2, %L0"
4761 : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
4764 (if_then_else (eq_attr "isa" "sparclet")
4765 (const_string "imul") (const_string "multi")))
4766 (set (attr "length")
4767 (if_then_else (eq_attr "isa" "sparclet")
4768 (const_int 1) (const_int 2)))])
4770 (define_insn "const_mulsidi3_sp64"
4771 [(set (match_operand:DI 0 "register_operand" "=r")
4772 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4773 (match_operand:DI 2 "small_int_operand" "I")))]
4774 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4776 [(set_attr "type" "imul")])
4778 (define_expand "smulsi3_highpart"
4779 [(set (match_operand:SI 0 "register_operand" "")
4781 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
4782 (sign_extend:DI (match_operand:SI 2 "arith_operand" "")))
4784 "TARGET_HARD_MUL && TARGET_ARCH32"
4786 if (CONSTANT_P (operands[2]))
4790 emit_insn (gen_const_smulsi3_highpart_v8plus (operands[0],
4796 emit_insn (gen_const_smulsi3_highpart (operands[0], operands[1], operands[2]));
4801 emit_insn (gen_smulsi3_highpart_v8plus (operands[0], operands[1],
4802 operands[2], GEN_INT (32)));
4808 (define_insn "smulsi3_highpart_v8plus"
4809 [(set (match_operand:SI 0 "register_operand" "=h,r")
4811 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4812 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
4813 (match_operand:SI 3 "small_int_operand" "I,I"))))
4814 (clobber (match_scratch:SI 4 "=X,&h"))]
4817 smul\t%1, %2, %0\;srlx\t%0, %3, %0
4818 smul\t%1, %2, %4\;srlx\t%4, %3, %0"
4819 [(set_attr "type" "multi")
4820 (set_attr "length" "2")])
4822 ;; The combiner changes TRUNCATE in the previous pattern to SUBREG.
4825 [(set (match_operand:SI 0 "register_operand" "=h,r")
4828 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4829 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
4830 (match_operand:SI 3 "small_int_operand" "I,I"))
4832 (clobber (match_scratch:SI 4 "=X,&h"))]
4835 smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
4836 smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
4837 [(set_attr "type" "multi")
4838 (set_attr "length" "2")])
4841 (define_insn "const_smulsi3_highpart_v8plus"
4842 [(set (match_operand:SI 0 "register_operand" "=h,r")
4844 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4845 (match_operand:DI 2 "small_int_operand" "I,I"))
4846 (match_operand:SI 3 "small_int_operand" "I,I"))))
4847 (clobber (match_scratch:SI 4 "=X,&h"))]
4850 smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
4851 smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
4852 [(set_attr "type" "multi")
4853 (set_attr "length" "2")])
4856 (define_insn "*smulsi3_highpart_sp32"
4857 [(set (match_operand:SI 0 "register_operand" "=r")
4859 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4860 (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
4863 "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
4864 [(set_attr "type" "multi")
4865 (set_attr "length" "2")])
4868 (define_insn "const_smulsi3_highpart"
4869 [(set (match_operand:SI 0 "register_operand" "=r")
4871 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4872 (match_operand:DI 2 "small_int_operand" "i"))
4875 "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
4876 [(set_attr "type" "multi")
4877 (set_attr "length" "2")])
4879 (define_expand "umulsidi3"
4880 [(set (match_operand:DI 0 "register_operand" "")
4881 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
4882 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" ""))))]
4885 if (CONSTANT_P (operands[2]))
4888 emit_insn (gen_const_umulsidi3_v8plus (operands[0], operands[1],
4890 else if (TARGET_ARCH32)
4891 emit_insn (gen_const_umulsidi3_sp32 (operands[0], operands[1],
4894 emit_insn (gen_const_umulsidi3_sp64 (operands[0], operands[1],
4900 emit_insn (gen_umulsidi3_v8plus (operands[0], operands[1], operands[2]));
4906 (define_insn "umulsidi3_v8plus"
4907 [(set (match_operand:DI 0 "register_operand" "=h,r")
4908 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4909 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
4910 (clobber (match_scratch:SI 3 "=X,&h"))]
4913 umul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
4914 umul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4915 [(set_attr "type" "multi")
4916 (set_attr "length" "2,3")])
4919 (define_insn "*umulsidi3_sp32"
4920 [(set (match_operand:DI 0 "register_operand" "=r")
4921 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4922 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4925 return TARGET_SPARCLET
4926 ? "umuld\t%1, %2, %L0"
4927 : "umul\t%1, %2, %L0\n\trd\t%%y, %H0";
4930 (if_then_else (eq_attr "isa" "sparclet")
4931 (const_string "imul") (const_string "multi")))
4932 (set (attr "length")
4933 (if_then_else (eq_attr "isa" "sparclet")
4934 (const_int 1) (const_int 2)))])
4936 (define_insn "*umulsidi3_sp64"
4937 [(set (match_operand:DI 0 "register_operand" "=r")
4938 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4939 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4940 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4942 [(set_attr "type" "imul")])
4944 ;; Extra pattern, because sign_extend of a constant isn't valid.
4947 (define_insn "const_umulsidi3_sp32"
4948 [(set (match_operand:DI 0 "register_operand" "=r")
4949 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4950 (match_operand:DI 2 "uns_small_int_operand" "")))]
4953 return TARGET_SPARCLET
4954 ? "umuld\t%1, %s2, %L0"
4955 : "umul\t%1, %s2, %L0\n\trd\t%%y, %H0";
4958 (if_then_else (eq_attr "isa" "sparclet")
4959 (const_string "imul") (const_string "multi")))
4960 (set (attr "length")
4961 (if_then_else (eq_attr "isa" "sparclet")
4962 (const_int 1) (const_int 2)))])
4964 (define_insn "const_umulsidi3_sp64"
4965 [(set (match_operand:DI 0 "register_operand" "=r")
4966 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4967 (match_operand:DI 2 "uns_small_int_operand" "")))]
4968 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4970 [(set_attr "type" "imul")])
4973 (define_insn "const_umulsidi3_v8plus"
4974 [(set (match_operand:DI 0 "register_operand" "=h,r")
4975 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4976 (match_operand:DI 2 "uns_small_int_operand" "")))
4977 (clobber (match_scratch:SI 3 "=X,h"))]
4980 umul\t%1, %s2, %L0\n\tsrlx\t%L0, 32, %H0
4981 umul\t%1, %s2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4982 [(set_attr "type" "multi")
4983 (set_attr "length" "2,3")])
4985 (define_expand "umulsi3_highpart"
4986 [(set (match_operand:SI 0 "register_operand" "")
4988 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
4989 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" "")))
4991 "TARGET_HARD_MUL && TARGET_ARCH32"
4993 if (CONSTANT_P (operands[2]))
4997 emit_insn (gen_const_umulsi3_highpart_v8plus (operands[0],
5003 emit_insn (gen_const_umulsi3_highpart (operands[0], operands[1], operands[2]));
5008 emit_insn (gen_umulsi3_highpart_v8plus (operands[0], operands[1],
5009 operands[2], GEN_INT (32)));
5015 (define_insn "umulsi3_highpart_v8plus"
5016 [(set (match_operand:SI 0 "register_operand" "=h,r")
5018 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5019 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
5020 (match_operand:SI 3 "small_int_operand" "I,I"))))
5021 (clobber (match_scratch:SI 4 "=X,h"))]
5024 umul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
5025 umul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
5026 [(set_attr "type" "multi")
5027 (set_attr "length" "2")])
5030 (define_insn "const_umulsi3_highpart_v8plus"
5031 [(set (match_operand:SI 0 "register_operand" "=h,r")
5033 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5034 (match_operand:DI 2 "uns_small_int_operand" ""))
5035 (match_operand:SI 3 "small_int_operand" "I,I"))))
5036 (clobber (match_scratch:SI 4 "=X,h"))]
5039 umul\t%1, %s2, %0\n\tsrlx\t%0, %3, %0
5040 umul\t%1, %s2, %4\n\tsrlx\t%4, %3, %0"
5041 [(set_attr "type" "multi")
5042 (set_attr "length" "2")])
5045 (define_insn "*umulsi3_highpart_sp32"
5046 [(set (match_operand:SI 0 "register_operand" "=r")
5048 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5049 (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
5052 "umul\t%1, %2, %%g0\n\trd\t%%y, %0"
5053 [(set_attr "type" "multi")
5054 (set_attr "length" "2")])
5057 (define_insn "const_umulsi3_highpart"
5058 [(set (match_operand:SI 0 "register_operand" "=r")
5060 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5061 (match_operand:DI 2 "uns_small_int_operand" ""))
5064 "umul\t%1, %s2, %%g0\n\trd\t%%y, %0"
5065 [(set_attr "type" "multi")
5066 (set_attr "length" "2")])
5068 ;; The V8 architecture specifies that there must be 3 instructions between
5069 ;; a Y register write and a use of it for correct results.
5071 (define_expand "divsi3"
5072 [(parallel [(set (match_operand:SI 0 "register_operand" "=r,r")
5073 (div:SI (match_operand:SI 1 "register_operand" "r,r")
5074 (match_operand:SI 2 "input_operand" "rI,m")))
5075 (clobber (match_scratch:SI 3 "=&r,&r"))])]
5076 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
5080 operands[3] = gen_reg_rtx(SImode);
5081 emit_insn (gen_ashrsi3 (operands[3], operands[1], GEN_INT (31)));
5082 emit_insn (gen_divsi3_sp64 (operands[0], operands[1], operands[2],
5088 (define_insn "divsi3_sp32"
5089 [(set (match_operand:SI 0 "register_operand" "=r,r")
5090 (div:SI (match_operand:SI 1 "register_operand" "r,r")
5091 (match_operand:SI 2 "input_operand" "rI,m")))
5092 (clobber (match_scratch:SI 3 "=&r,&r"))]
5093 "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS)
5096 if (which_alternative == 0)
5098 return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tsdiv\t%1, %2, %0";
5100 return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tnop\n\tnop\n\tnop\n\tsdiv\t%1, %2, %0";
5103 return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tld\t%2, %3\n\tsdiv\t%1, %3, %0";
5105 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";
5107 [(set_attr "type" "multi")
5108 (set (attr "length")
5109 (if_then_else (eq_attr "isa" "v9")
5110 (const_int 4) (const_int 6)))])
5112 (define_insn "divsi3_sp64"
5113 [(set (match_operand:SI 0 "register_operand" "=r")
5114 (div:SI (match_operand:SI 1 "register_operand" "r")
5115 (match_operand:SI 2 "input_operand" "rI")))
5116 (use (match_operand:SI 3 "register_operand" "r"))]
5117 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5118 "wr\t%%g0, %3, %%y\n\tsdiv\t%1, %2, %0"
5119 [(set_attr "type" "multi")
5120 (set_attr "length" "2")])
5122 (define_insn "divdi3"
5123 [(set (match_operand:DI 0 "register_operand" "=r")
5124 (div:DI (match_operand:DI 1 "register_operand" "r")
5125 (match_operand:DI 2 "arith_operand" "rI")))]
5128 [(set_attr "type" "idiv")])
5130 (define_insn "*cmp_sdiv_cc_set"
5132 (compare:CC (div:SI (match_operand:SI 1 "register_operand" "r")
5133 (match_operand:SI 2 "arith_operand" "rI"))
5135 (set (match_operand:SI 0 "register_operand" "=r")
5136 (div:SI (match_dup 1) (match_dup 2)))
5137 (clobber (match_scratch:SI 3 "=&r"))]
5138 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
5141 return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tsdivcc\t%1, %2, %0";
5143 return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tnop\n\tnop\n\tnop\n\tsdivcc\t%1, %2, %0";
5145 [(set_attr "type" "multi")
5146 (set (attr "length")
5147 (if_then_else (eq_attr "isa" "v9")
5148 (const_int 3) (const_int 6)))])
5151 (define_expand "udivsi3"
5152 [(set (match_operand:SI 0 "register_operand" "")
5153 (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "")
5154 (match_operand:SI 2 "input_operand" "")))]
5155 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
5158 ;; The V8 architecture specifies that there must be 3 instructions between
5159 ;; a Y register write and a use of it for correct results.
5161 (define_insn "udivsi3_sp32"
5162 [(set (match_operand:SI 0 "register_operand" "=r,&r,&r")
5163 (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "r,r,m")
5164 (match_operand:SI 2 "input_operand" "rI,m,r")))]
5165 "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS)
5168 output_asm_insn ("wr\t%%g0, %%g0, %%y", operands);
5169 switch (which_alternative)
5172 return "nop\n\tnop\n\tnop\n\tudiv\t%1, %2, %0";
5174 return "ld\t%2, %0\n\tnop\n\tnop\n\tudiv\t%1, %0, %0";
5176 return "ld\t%1, %0\n\tnop\n\tnop\n\tudiv\t%0, %2, %0";
5179 [(set_attr "type" "multi")
5180 (set_attr "length" "5")])
5182 (define_insn "udivsi3_sp64"
5183 [(set (match_operand:SI 0 "register_operand" "=r")
5184 (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "r")
5185 (match_operand:SI 2 "input_operand" "rI")))]
5186 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5187 "wr\t%%g0, 0, %%y\n\tudiv\t%1, %2, %0"
5188 [(set_attr "type" "multi")
5189 (set_attr "length" "2")])
5191 (define_insn "udivdi3"
5192 [(set (match_operand:DI 0 "register_operand" "=r")
5193 (udiv:DI (match_operand:DI 1 "register_operand" "r")
5194 (match_operand:DI 2 "arith_operand" "rI")))]
5197 [(set_attr "type" "idiv")])
5199 (define_insn "*cmp_udiv_cc_set"
5201 (compare:CC (udiv:SI (match_operand:SI 1 "register_operand" "r")
5202 (match_operand:SI 2 "arith_operand" "rI"))
5204 (set (match_operand:SI 0 "register_operand" "=r")
5205 (udiv:SI (match_dup 1) (match_dup 2)))]
5207 || TARGET_DEPRECATED_V8_INSNS"
5210 return "wr\t%%g0, %%g0, %%y\n\tudivcc\t%1, %2, %0";
5212 return "wr\t%%g0, %%g0, %%y\n\tnop\n\tnop\n\tnop\n\tudivcc\t%1, %2, %0";
5214 [(set_attr "type" "multi")
5215 (set (attr "length")
5216 (if_then_else (eq_attr "isa" "v9")
5217 (const_int 2) (const_int 5)))])
5219 ; sparclet multiply/accumulate insns
5221 (define_insn "*smacsi"
5222 [(set (match_operand:SI 0 "register_operand" "=r")
5223 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "%r")
5224 (match_operand:SI 2 "arith_operand" "rI"))
5225 (match_operand:SI 3 "register_operand" "0")))]
5228 [(set_attr "type" "imul")])
5230 (define_insn "*smacdi"
5231 [(set (match_operand:DI 0 "register_operand" "=r")
5232 (plus:DI (mult:DI (sign_extend:DI
5233 (match_operand:SI 1 "register_operand" "%r"))
5235 (match_operand:SI 2 "register_operand" "r")))
5236 (match_operand:DI 3 "register_operand" "0")))]
5238 "smacd\t%1, %2, %L0"
5239 [(set_attr "type" "imul")])
5241 (define_insn "*umacdi"
5242 [(set (match_operand:DI 0 "register_operand" "=r")
5243 (plus:DI (mult:DI (zero_extend:DI
5244 (match_operand:SI 1 "register_operand" "%r"))
5246 (match_operand:SI 2 "register_operand" "r")))
5247 (match_operand:DI 3 "register_operand" "0")))]
5249 "umacd\t%1, %2, %L0"
5250 [(set_attr "type" "imul")])
5253 ;; Boolean instructions.
5255 ;; We define DImode `and' so with DImode `not' we can get
5256 ;; DImode `andn'. Other combinations are possible.
5258 (define_mode_macro V64I [DI V2SI V4HI V8QI])
5259 (define_mode_macro V32I [SI V2HI V4QI])
5261 (define_expand "and<V64I:mode>3"
5262 [(set (match_operand:V64I 0 "register_operand" "")
5263 (and:V64I (match_operand:V64I 1 "arith_double_operand" "")
5264 (match_operand:V64I 2 "arith_double_operand" "")))]
5268 (define_insn "*and<V64I:mode>3_sp32"
5269 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5270 (and:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
5271 (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
5276 [(set_attr "type" "*,fga")
5277 (set_attr "length" "2,*")
5278 (set_attr "fptype" "*,double")])
5280 (define_insn "*and<V64I:mode>3_sp64"
5281 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5282 (and:V64I (match_operand:V64I 1 "arith_operand" "%r,b")
5283 (match_operand:V64I 2 "arith_operand" "rI,b")))]
5288 [(set_attr "type" "*,fga")
5289 (set_attr "fptype" "*,double")])
5291 (define_insn "and<V32I:mode>3"
5292 [(set (match_operand:V32I 0 "register_operand" "=r,d")
5293 (and:V32I (match_operand:V32I 1 "arith_operand" "%r,d")
5294 (match_operand:V32I 2 "arith_operand" "rI,d")))]
5299 [(set_attr "type" "*,fga")
5300 (set_attr "fptype" "*,single")])
5303 [(set (match_operand:SI 0 "register_operand" "")
5304 (and:SI (match_operand:SI 1 "register_operand" "")
5305 (match_operand:SI 2 "const_compl_high_operand" "")))
5306 (clobber (match_operand:SI 3 "register_operand" ""))]
5308 [(set (match_dup 3) (match_dup 4))
5309 (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 1)))]
5311 operands[4] = GEN_INT (~INTVAL (operands[2]));
5314 (define_insn_and_split "*and_not_<V64I:mode>_sp32"
5315 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5316 (and:V64I (not:V64I (match_operand:V64I 1 "register_operand" "%r,b"))
5317 (match_operand:V64I 2 "register_operand" "r,b")))]
5321 fandnot1\t%1, %2, %0"
5322 "&& reload_completed
5323 && ((GET_CODE (operands[0]) == REG
5324 && REGNO (operands[0]) < 32)
5325 || (GET_CODE (operands[0]) == SUBREG
5326 && GET_CODE (SUBREG_REG (operands[0])) == REG
5327 && REGNO (SUBREG_REG (operands[0])) < 32))"
5328 [(set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))
5329 (set (match_dup 6) (and:SI (not:SI (match_dup 7)) (match_dup 8)))]
5330 "operands[3] = gen_highpart (SImode, operands[0]);
5331 operands[4] = gen_highpart (SImode, operands[1]);
5332 operands[5] = gen_highpart (SImode, operands[2]);
5333 operands[6] = gen_lowpart (SImode, operands[0]);
5334 operands[7] = gen_lowpart (SImode, operands[1]);
5335 operands[8] = gen_lowpart (SImode, operands[2]);"
5336 [(set_attr "type" "*,fga")
5337 (set_attr "length" "2,*")
5338 (set_attr "fptype" "*,double")])
5340 (define_insn "*and_not_<V64I:mode>_sp64"
5341 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5342 (and:V64I (not:V64I (match_operand:V64I 1 "register_operand" "%r,b"))
5343 (match_operand:V64I 2 "register_operand" "r,b")))]
5347 fandnot1\t%1, %2, %0"
5348 [(set_attr "type" "*,fga")
5349 (set_attr "fptype" "*,double")])
5351 (define_insn "*and_not_<V32I:mode>"
5352 [(set (match_operand:V32I 0 "register_operand" "=r,d")
5353 (and:V32I (not:V32I (match_operand:V32I 1 "register_operand" "%r,d"))
5354 (match_operand:V32I 2 "register_operand" "r,d")))]
5358 fandnot1s\t%1, %2, %0"
5359 [(set_attr "type" "*,fga")
5360 (set_attr "fptype" "*,single")])
5362 (define_expand "ior<V64I:mode>3"
5363 [(set (match_operand:V64I 0 "register_operand" "")
5364 (ior:V64I (match_operand:V64I 1 "arith_double_operand" "")
5365 (match_operand:V64I 2 "arith_double_operand" "")))]
5369 (define_insn "*ior<V64I:mode>3_sp32"
5370 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5371 (ior:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
5372 (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
5377 [(set_attr "type" "*,fga")
5378 (set_attr "length" "2,*")
5379 (set_attr "fptype" "*,double")])
5381 (define_insn "*ior<V64I:mode>3_sp64"
5382 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5383 (ior:V64I (match_operand:V64I 1 "arith_operand" "%r,b")
5384 (match_operand:V64I 2 "arith_operand" "rI,b")))]
5389 [(set_attr "type" "*,fga")
5390 (set_attr "fptype" "*,double")])
5392 (define_insn "ior<V32I:mode>3"
5393 [(set (match_operand:V32I 0 "register_operand" "=r,d")
5394 (ior:V32I (match_operand:V32I 1 "arith_operand" "%r,d")
5395 (match_operand:V32I 2 "arith_operand" "rI,d")))]
5400 [(set_attr "type" "*,fga")
5401 (set_attr "fptype" "*,single")])
5404 [(set (match_operand:SI 0 "register_operand" "")
5405 (ior:SI (match_operand:SI 1 "register_operand" "")
5406 (match_operand:SI 2 "const_compl_high_operand" "")))
5407 (clobber (match_operand:SI 3 "register_operand" ""))]
5409 [(set (match_dup 3) (match_dup 4))
5410 (set (match_dup 0) (ior:SI (not:SI (match_dup 3)) (match_dup 1)))]
5412 operands[4] = GEN_INT (~INTVAL (operands[2]));
5415 (define_insn_and_split "*or_not_<V64I:mode>_sp32"
5416 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5417 (ior:V64I (not:V64I (match_operand:V64I 1 "register_operand" "r,b"))
5418 (match_operand:V64I 2 "register_operand" "r,b")))]
5422 fornot1\t%1, %2, %0"
5423 "&& reload_completed
5424 && ((GET_CODE (operands[0]) == REG
5425 && REGNO (operands[0]) < 32)
5426 || (GET_CODE (operands[0]) == SUBREG
5427 && GET_CODE (SUBREG_REG (operands[0])) == REG
5428 && REGNO (SUBREG_REG (operands[0])) < 32))"
5429 [(set (match_dup 3) (ior:SI (not:SI (match_dup 4)) (match_dup 5)))
5430 (set (match_dup 6) (ior:SI (not:SI (match_dup 7)) (match_dup 8)))]
5431 "operands[3] = gen_highpart (SImode, operands[0]);
5432 operands[4] = gen_highpart (SImode, operands[1]);
5433 operands[5] = gen_highpart (SImode, operands[2]);
5434 operands[6] = gen_lowpart (SImode, operands[0]);
5435 operands[7] = gen_lowpart (SImode, operands[1]);
5436 operands[8] = gen_lowpart (SImode, operands[2]);"
5437 [(set_attr "type" "*,fga")
5438 (set_attr "length" "2,*")
5439 (set_attr "fptype" "*,double")])
5441 (define_insn "*or_not_<V64I:mode>_sp64"
5442 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5443 (ior:V64I (not:V64I (match_operand:V64I 1 "register_operand" "r,b"))
5444 (match_operand:V64I 2 "register_operand" "r,b")))]
5448 fornot1\t%1, %2, %0"
5449 [(set_attr "type" "*,fga")
5450 (set_attr "fptype" "*,double")])
5452 (define_insn "*or_not_<V32I:mode>"
5453 [(set (match_operand:V32I 0 "register_operand" "=r,d")
5454 (ior:V32I (not:V32I (match_operand:V32I 1 "register_operand" "r,d"))
5455 (match_operand:V32I 2 "register_operand" "r,d")))]
5459 fornot1s\t%1, %2, %0"
5460 [(set_attr "type" "*,fga")
5461 (set_attr "fptype" "*,single")])
5463 (define_expand "xor<V64I:mode>3"
5464 [(set (match_operand:V64I 0 "register_operand" "")
5465 (xor:V64I (match_operand:V64I 1 "arith_double_operand" "")
5466 (match_operand:V64I 2 "arith_double_operand" "")))]
5470 (define_insn "*xor<V64I:mode>3_sp32"
5471 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5472 (xor:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
5473 (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
5478 [(set_attr "type" "*,fga")
5479 (set_attr "length" "2,*")
5480 (set_attr "fptype" "*,double")])
5482 (define_insn "*xor<V64I:mode>3_sp64"
5483 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5484 (xor:V64I (match_operand:V64I 1 "arith_operand" "%rJ,b")
5485 (match_operand:V64I 2 "arith_operand" "rI,b")))]
5490 [(set_attr "type" "*,fga")
5491 (set_attr "fptype" "*,double")])
5493 (define_insn "xor<V32I:mode>3"
5494 [(set (match_operand:V32I 0 "register_operand" "=r,d")
5495 (xor:V32I (match_operand:V32I 1 "arith_operand" "%rJ,d")
5496 (match_operand:V32I 2 "arith_operand" "rI,d")))]
5501 [(set_attr "type" "*,fga")
5502 (set_attr "fptype" "*,single")])
5505 [(set (match_operand:SI 0 "register_operand" "")
5506 (xor:SI (match_operand:SI 1 "register_operand" "")
5507 (match_operand:SI 2 "const_compl_high_operand" "")))
5508 (clobber (match_operand:SI 3 "register_operand" ""))]
5510 [(set (match_dup 3) (match_dup 4))
5511 (set (match_dup 0) (not:SI (xor:SI (match_dup 3) (match_dup 1))))]
5513 operands[4] = GEN_INT (~INTVAL (operands[2]));
5517 [(set (match_operand:SI 0 "register_operand" "")
5518 (not:SI (xor:SI (match_operand:SI 1 "register_operand" "")
5519 (match_operand:SI 2 "const_compl_high_operand" ""))))
5520 (clobber (match_operand:SI 3 "register_operand" ""))]
5522 [(set (match_dup 3) (match_dup 4))
5523 (set (match_dup 0) (xor:SI (match_dup 3) (match_dup 1)))]
5525 operands[4] = GEN_INT (~INTVAL (operands[2]));
5528 ;; Split DImode logical operations requiring two instructions.
5530 [(set (match_operand:V64I 0 "register_operand" "")
5531 (match_operator:V64I 1 "cc_arith_operator" ; AND, IOR, XOR
5532 [(match_operand:V64I 2 "register_operand" "")
5533 (match_operand:V64I 3 "arith_double_operand" "")]))]
5536 && ((GET_CODE (operands[0]) == REG
5537 && REGNO (operands[0]) < 32)
5538 || (GET_CODE (operands[0]) == SUBREG
5539 && GET_CODE (SUBREG_REG (operands[0])) == REG
5540 && REGNO (SUBREG_REG (operands[0])) < 32))"
5541 [(set (match_dup 4) (match_op_dup:SI 1 [(match_dup 6) (match_dup 8)]))
5542 (set (match_dup 5) (match_op_dup:SI 1 [(match_dup 7) (match_dup 9)]))]
5544 operands[4] = gen_highpart (SImode, operands[0]);
5545 operands[5] = gen_lowpart (SImode, operands[0]);
5546 operands[6] = gen_highpart (SImode, operands[2]);
5547 operands[7] = gen_lowpart (SImode, operands[2]);
5548 #if HOST_BITS_PER_WIDE_INT == 32
5549 if (GET_CODE (operands[3]) == CONST_INT && <V64I:MODE>mode == DImode)
5551 if (INTVAL (operands[3]) < 0)
5552 operands[8] = constm1_rtx;
5554 operands[8] = const0_rtx;
5558 operands[8] = gen_highpart_mode (SImode, <V64I:MODE>mode, operands[3]);
5559 operands[9] = gen_lowpart (SImode, operands[3]);
5562 ;; xnor patterns. Note that (a ^ ~b) == (~a ^ b) == ~(a ^ b).
5563 ;; Combine now canonicalizes to the rightmost expression.
5564 (define_insn_and_split "*xor_not_<V64I:mode>_sp32"
5565 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5566 (not:V64I (xor:V64I (match_operand:V64I 1 "register_operand" "r,b")
5567 (match_operand:V64I 2 "register_operand" "r,b"))))]
5572 "&& reload_completed
5573 && ((GET_CODE (operands[0]) == REG
5574 && REGNO (operands[0]) < 32)
5575 || (GET_CODE (operands[0]) == SUBREG
5576 && GET_CODE (SUBREG_REG (operands[0])) == REG
5577 && REGNO (SUBREG_REG (operands[0])) < 32))"
5578 [(set (match_dup 3) (not:SI (xor:SI (match_dup 4) (match_dup 5))))
5579 (set (match_dup 6) (not:SI (xor:SI (match_dup 7) (match_dup 8))))]
5580 "operands[3] = gen_highpart (SImode, operands[0]);
5581 operands[4] = gen_highpart (SImode, operands[1]);
5582 operands[5] = gen_highpart (SImode, operands[2]);
5583 operands[6] = gen_lowpart (SImode, operands[0]);
5584 operands[7] = gen_lowpart (SImode, operands[1]);
5585 operands[8] = gen_lowpart (SImode, operands[2]);"
5586 [(set_attr "type" "*,fga")
5587 (set_attr "length" "2,*")
5588 (set_attr "fptype" "*,double")])
5590 (define_insn "*xor_not_<V64I:mode>_sp64"
5591 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5592 (not:V64I (xor:V64I (match_operand:V64I 1 "register_or_zero_operand" "rJ,b")
5593 (match_operand:V64I 2 "arith_operand" "rI,b"))))]
5598 [(set_attr "type" "*,fga")
5599 (set_attr "fptype" "*,double")])
5601 (define_insn "*xor_not_<V32I:mode>"
5602 [(set (match_operand:V32I 0 "register_operand" "=r,d")
5603 (not:V32I (xor:V32I (match_operand:V32I 1 "register_or_zero_operand" "rJ,d")
5604 (match_operand:V32I 2 "arith_operand" "rI,d"))))]
5609 [(set_attr "type" "*,fga")
5610 (set_attr "fptype" "*,single")])
5612 ;; These correspond to the above in the case where we also (or only)
5613 ;; want to set the condition code.
5615 (define_insn "*cmp_cc_arith_op"
5618 (match_operator:SI 2 "cc_arith_operator"
5619 [(match_operand:SI 0 "arith_operand" "%r")
5620 (match_operand:SI 1 "arith_operand" "rI")])
5623 "%A2cc\t%0, %1, %%g0"
5624 [(set_attr "type" "compare")])
5626 (define_insn "*cmp_ccx_arith_op"
5629 (match_operator:DI 2 "cc_arith_operator"
5630 [(match_operand:DI 0 "arith_operand" "%r")
5631 (match_operand:DI 1 "arith_operand" "rI")])
5634 "%A2cc\t%0, %1, %%g0"
5635 [(set_attr "type" "compare")])
5637 (define_insn "*cmp_cc_arith_op_set"
5640 (match_operator:SI 3 "cc_arith_operator"
5641 [(match_operand:SI 1 "arith_operand" "%r")
5642 (match_operand:SI 2 "arith_operand" "rI")])
5644 (set (match_operand:SI 0 "register_operand" "=r")
5645 (match_operator:SI 4 "cc_arith_operator" [(match_dup 1) (match_dup 2)]))]
5646 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
5648 [(set_attr "type" "compare")])
5650 (define_insn "*cmp_ccx_arith_op_set"
5653 (match_operator:DI 3 "cc_arith_operator"
5654 [(match_operand:DI 1 "arith_operand" "%r")
5655 (match_operand:DI 2 "arith_operand" "rI")])
5657 (set (match_operand:DI 0 "register_operand" "=r")
5658 (match_operator:DI 4 "cc_arith_operator" [(match_dup 1) (match_dup 2)]))]
5659 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
5661 [(set_attr "type" "compare")])
5663 (define_insn "*cmp_cc_xor_not"
5666 (not:SI (xor:SI (match_operand:SI 0 "register_or_zero_operand" "%rJ")
5667 (match_operand:SI 1 "arith_operand" "rI")))
5670 "xnorcc\t%r0, %1, %%g0"
5671 [(set_attr "type" "compare")])
5673 (define_insn "*cmp_ccx_xor_not"
5676 (not:DI (xor:DI (match_operand:DI 0 "register_or_zero_operand" "%rJ")
5677 (match_operand:DI 1 "arith_operand" "rI")))
5680 "xnorcc\t%r0, %1, %%g0"
5681 [(set_attr "type" "compare")])
5683 (define_insn "*cmp_cc_xor_not_set"
5686 (not:SI (xor:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ")
5687 (match_operand:SI 2 "arith_operand" "rI")))
5689 (set (match_operand:SI 0 "register_operand" "=r")
5690 (not:SI (xor:SI (match_dup 1) (match_dup 2))))]
5692 "xnorcc\t%r1, %2, %0"
5693 [(set_attr "type" "compare")])
5695 (define_insn "*cmp_ccx_xor_not_set"
5698 (not:DI (xor:DI (match_operand:DI 1 "register_or_zero_operand" "%rJ")
5699 (match_operand:DI 2 "arith_operand" "rI")))
5701 (set (match_operand:DI 0 "register_operand" "=r")
5702 (not:DI (xor:DI (match_dup 1) (match_dup 2))))]
5704 "xnorcc\t%r1, %2, %0"
5705 [(set_attr "type" "compare")])
5707 (define_insn "*cmp_cc_arith_op_not"
5710 (match_operator:SI 2 "cc_arith_not_operator"
5711 [(not:SI (match_operand:SI 0 "arith_operand" "rI"))
5712 (match_operand:SI 1 "register_or_zero_operand" "rJ")])
5715 "%B2cc\t%r1, %0, %%g0"
5716 [(set_attr "type" "compare")])
5718 (define_insn "*cmp_ccx_arith_op_not"
5721 (match_operator:DI 2 "cc_arith_not_operator"
5722 [(not:DI (match_operand:DI 0 "arith_operand" "rI"))
5723 (match_operand:DI 1 "register_or_zero_operand" "rJ")])
5726 "%B2cc\t%r1, %0, %%g0"
5727 [(set_attr "type" "compare")])
5729 (define_insn "*cmp_cc_arith_op_not_set"
5732 (match_operator:SI 3 "cc_arith_not_operator"
5733 [(not:SI (match_operand:SI 1 "arith_operand" "rI"))
5734 (match_operand:SI 2 "register_or_zero_operand" "rJ")])
5736 (set (match_operand:SI 0 "register_operand" "=r")
5737 (match_operator:SI 4 "cc_arith_not_operator"
5738 [(not:SI (match_dup 1)) (match_dup 2)]))]
5739 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
5740 "%B3cc\t%r2, %1, %0"
5741 [(set_attr "type" "compare")])
5743 (define_insn "*cmp_ccx_arith_op_not_set"
5746 (match_operator:DI 3 "cc_arith_not_operator"
5747 [(not:DI (match_operand:DI 1 "arith_operand" "rI"))
5748 (match_operand:DI 2 "register_or_zero_operand" "rJ")])
5750 (set (match_operand:DI 0 "register_operand" "=r")
5751 (match_operator:DI 4 "cc_arith_not_operator"
5752 [(not:DI (match_dup 1)) (match_dup 2)]))]
5753 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
5754 "%B3cc\t%r2, %1, %0"
5755 [(set_attr "type" "compare")])
5757 ;; We cannot use the "neg" pseudo insn because the Sun assembler
5758 ;; does not know how to make it work for constants.
5760 (define_expand "negdi2"
5761 [(set (match_operand:DI 0 "register_operand" "=r")
5762 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
5765 if (! TARGET_ARCH64)
5767 emit_insn (gen_rtx_PARALLEL
5770 gen_rtx_SET (VOIDmode, operand0,
5771 gen_rtx_NEG (DImode, operand1)),
5772 gen_rtx_CLOBBER (VOIDmode,
5773 gen_rtx_REG (CCmode,
5779 (define_insn_and_split "*negdi2_sp32"
5780 [(set (match_operand:DI 0 "register_operand" "=r")
5781 (neg:DI (match_operand:DI 1 "register_operand" "r")))
5782 (clobber (reg:CC 100))]
5785 "&& reload_completed"
5786 [(parallel [(set (reg:CC_NOOV 100)
5787 (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 5))
5789 (set (match_dup 4) (minus:SI (const_int 0) (match_dup 5)))])
5790 (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
5791 (ltu:SI (reg:CC 100) (const_int 0))))]
5792 "operands[2] = gen_highpart (SImode, operands[0]);
5793 operands[3] = gen_highpart (SImode, operands[1]);
5794 operands[4] = gen_lowpart (SImode, operands[0]);
5795 operands[5] = gen_lowpart (SImode, operands[1]);"
5796 [(set_attr "length" "2")])
5798 (define_insn "*negdi2_sp64"
5799 [(set (match_operand:DI 0 "register_operand" "=r")
5800 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
5802 "sub\t%%g0, %1, %0")
5804 (define_insn "negsi2"
5805 [(set (match_operand:SI 0 "register_operand" "=r")
5806 (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
5808 "sub\t%%g0, %1, %0")
5810 (define_insn "*cmp_cc_neg"
5811 [(set (reg:CC_NOOV 100)
5812 (compare:CC_NOOV (neg:SI (match_operand:SI 0 "arith_operand" "rI"))
5815 "subcc\t%%g0, %0, %%g0"
5816 [(set_attr "type" "compare")])
5818 (define_insn "*cmp_ccx_neg"
5819 [(set (reg:CCX_NOOV 100)
5820 (compare:CCX_NOOV (neg:DI (match_operand:DI 0 "arith_operand" "rI"))
5823 "subcc\t%%g0, %0, %%g0"
5824 [(set_attr "type" "compare")])
5826 (define_insn "*cmp_cc_set_neg"
5827 [(set (reg:CC_NOOV 100)
5828 (compare:CC_NOOV (neg:SI (match_operand:SI 1 "arith_operand" "rI"))
5830 (set (match_operand:SI 0 "register_operand" "=r")
5831 (neg:SI (match_dup 1)))]
5833 "subcc\t%%g0, %1, %0"
5834 [(set_attr "type" "compare")])
5836 (define_insn "*cmp_ccx_set_neg"
5837 [(set (reg:CCX_NOOV 100)
5838 (compare:CCX_NOOV (neg:DI (match_operand:DI 1 "arith_operand" "rI"))
5840 (set (match_operand:DI 0 "register_operand" "=r")
5841 (neg:DI (match_dup 1)))]
5843 "subcc\t%%g0, %1, %0"
5844 [(set_attr "type" "compare")])
5846 ;; We cannot use the "not" pseudo insn because the Sun assembler
5847 ;; does not know how to make it work for constants.
5848 (define_expand "one_cmpl<V64I:mode>2"
5849 [(set (match_operand:V64I 0 "register_operand" "")
5850 (not:V64I (match_operand:V64I 1 "register_operand" "")))]
5854 (define_insn_and_split "*one_cmpl<V64I:mode>2_sp32"
5855 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5856 (not:V64I (match_operand:V64I 1 "register_operand" "r,b")))]
5861 "&& reload_completed
5862 && ((GET_CODE (operands[0]) == REG
5863 && REGNO (operands[0]) < 32)
5864 || (GET_CODE (operands[0]) == SUBREG
5865 && GET_CODE (SUBREG_REG (operands[0])) == REG
5866 && REGNO (SUBREG_REG (operands[0])) < 32))"
5867 [(set (match_dup 2) (not:SI (xor:SI (match_dup 3) (const_int 0))))
5868 (set (match_dup 4) (not:SI (xor:SI (match_dup 5) (const_int 0))))]
5869 "operands[2] = gen_highpart (SImode, operands[0]);
5870 operands[3] = gen_highpart (SImode, operands[1]);
5871 operands[4] = gen_lowpart (SImode, operands[0]);
5872 operands[5] = gen_lowpart (SImode, operands[1]);"
5873 [(set_attr "type" "*,fga")
5874 (set_attr "length" "2,*")
5875 (set_attr "fptype" "*,double")])
5877 (define_insn "*one_cmpl<V64I:mode>2_sp64"
5878 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5879 (not:V64I (match_operand:V64I 1 "arith_operand" "rI,b")))]
5884 [(set_attr "type" "*,fga")
5885 (set_attr "fptype" "*,double")])
5887 (define_insn "one_cmpl<V32I:mode>2"
5888 [(set (match_operand:V32I 0 "register_operand" "=r,d")
5889 (not:V32I (match_operand:V32I 1 "arith_operand" "rI,d")))]
5894 [(set_attr "type" "*,fga")
5895 (set_attr "fptype" "*,single")])
5897 (define_insn "*cmp_cc_not"
5899 (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI"))
5902 "xnorcc\t%%g0, %0, %%g0"
5903 [(set_attr "type" "compare")])
5905 (define_insn "*cmp_ccx_not"
5907 (compare:CCX (not:DI (match_operand:DI 0 "arith_operand" "rI"))
5910 "xnorcc\t%%g0, %0, %%g0"
5911 [(set_attr "type" "compare")])
5913 (define_insn "*cmp_cc_set_not"
5915 (compare:CC (not:SI (match_operand:SI 1 "arith_operand" "rI"))
5917 (set (match_operand:SI 0 "register_operand" "=r")
5918 (not:SI (match_dup 1)))]
5920 "xnorcc\t%%g0, %1, %0"
5921 [(set_attr "type" "compare")])
5923 (define_insn "*cmp_ccx_set_not"
5925 (compare:CCX (not:DI (match_operand:DI 1 "arith_operand" "rI"))
5927 (set (match_operand:DI 0 "register_operand" "=r")
5928 (not:DI (match_dup 1)))]
5930 "xnorcc\t%%g0, %1, %0"
5931 [(set_attr "type" "compare")])
5933 (define_insn "*cmp_cc_set"
5934 [(set (match_operand:SI 0 "register_operand" "=r")
5935 (match_operand:SI 1 "register_operand" "r"))
5937 (compare:CC (match_dup 1)
5941 [(set_attr "type" "compare")])
5943 (define_insn "*cmp_ccx_set64"
5944 [(set (match_operand:DI 0 "register_operand" "=r")
5945 (match_operand:DI 1 "register_operand" "r"))
5947 (compare:CCX (match_dup 1)
5951 [(set_attr "type" "compare")])
5954 ;; Floating point arithmetic instructions.
5956 (define_expand "addtf3"
5957 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5958 (plus:TF (match_operand:TF 1 "general_operand" "")
5959 (match_operand:TF 2 "general_operand" "")))]
5960 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5961 "emit_tfmode_binop (PLUS, operands); DONE;")
5963 (define_insn "*addtf3_hq"
5964 [(set (match_operand:TF 0 "register_operand" "=e")
5965 (plus:TF (match_operand:TF 1 "register_operand" "e")
5966 (match_operand:TF 2 "register_operand" "e")))]
5967 "TARGET_FPU && TARGET_HARD_QUAD"
5969 [(set_attr "type" "fp")])
5971 (define_insn "adddf3"
5972 [(set (match_operand:DF 0 "register_operand" "=e")
5973 (plus:DF (match_operand:DF 1 "register_operand" "e")
5974 (match_operand:DF 2 "register_operand" "e")))]
5977 [(set_attr "type" "fp")
5978 (set_attr "fptype" "double")])
5980 (define_insn "addsf3"
5981 [(set (match_operand:SF 0 "register_operand" "=f")
5982 (plus:SF (match_operand:SF 1 "register_operand" "f")
5983 (match_operand:SF 2 "register_operand" "f")))]
5986 [(set_attr "type" "fp")])
5988 (define_expand "subtf3"
5989 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5990 (minus:TF (match_operand:TF 1 "general_operand" "")
5991 (match_operand:TF 2 "general_operand" "")))]
5992 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5993 "emit_tfmode_binop (MINUS, operands); DONE;")
5995 (define_insn "*subtf3_hq"
5996 [(set (match_operand:TF 0 "register_operand" "=e")
5997 (minus:TF (match_operand:TF 1 "register_operand" "e")
5998 (match_operand:TF 2 "register_operand" "e")))]
5999 "TARGET_FPU && TARGET_HARD_QUAD"
6001 [(set_attr "type" "fp")])
6003 (define_insn "subdf3"
6004 [(set (match_operand:DF 0 "register_operand" "=e")
6005 (minus:DF (match_operand:DF 1 "register_operand" "e")
6006 (match_operand:DF 2 "register_operand" "e")))]
6009 [(set_attr "type" "fp")
6010 (set_attr "fptype" "double")])
6012 (define_insn "subsf3"
6013 [(set (match_operand:SF 0 "register_operand" "=f")
6014 (minus:SF (match_operand:SF 1 "register_operand" "f")
6015 (match_operand:SF 2 "register_operand" "f")))]
6018 [(set_attr "type" "fp")])
6020 (define_expand "multf3"
6021 [(set (match_operand:TF 0 "nonimmediate_operand" "")
6022 (mult:TF (match_operand:TF 1 "general_operand" "")
6023 (match_operand:TF 2 "general_operand" "")))]
6024 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6025 "emit_tfmode_binop (MULT, operands); DONE;")
6027 (define_insn "*multf3_hq"
6028 [(set (match_operand:TF 0 "register_operand" "=e")
6029 (mult:TF (match_operand:TF 1 "register_operand" "e")
6030 (match_operand:TF 2 "register_operand" "e")))]
6031 "TARGET_FPU && TARGET_HARD_QUAD"
6033 [(set_attr "type" "fpmul")])
6035 (define_insn "muldf3"
6036 [(set (match_operand:DF 0 "register_operand" "=e")
6037 (mult:DF (match_operand:DF 1 "register_operand" "e")
6038 (match_operand:DF 2 "register_operand" "e")))]
6041 [(set_attr "type" "fpmul")
6042 (set_attr "fptype" "double")])
6044 (define_insn "mulsf3"
6045 [(set (match_operand:SF 0 "register_operand" "=f")
6046 (mult:SF (match_operand:SF 1 "register_operand" "f")
6047 (match_operand:SF 2 "register_operand" "f")))]
6050 [(set_attr "type" "fpmul")])
6052 (define_insn "*muldf3_extend"
6053 [(set (match_operand:DF 0 "register_operand" "=e")
6054 (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "f"))
6055 (float_extend:DF (match_operand:SF 2 "register_operand" "f"))))]
6056 "(TARGET_V8 || TARGET_V9) && TARGET_FPU"
6057 "fsmuld\t%1, %2, %0"
6058 [(set_attr "type" "fpmul")
6059 (set_attr "fptype" "double")])
6061 (define_insn "*multf3_extend"
6062 [(set (match_operand:TF 0 "register_operand" "=e")
6063 (mult:TF (float_extend:TF (match_operand:DF 1 "register_operand" "e"))
6064 (float_extend:TF (match_operand:DF 2 "register_operand" "e"))))]
6065 "(TARGET_V8 || TARGET_V9) && TARGET_FPU && TARGET_HARD_QUAD"
6066 "fdmulq\t%1, %2, %0"
6067 [(set_attr "type" "fpmul")])
6069 (define_expand "divtf3"
6070 [(set (match_operand:TF 0 "nonimmediate_operand" "")
6071 (div:TF (match_operand:TF 1 "general_operand" "")
6072 (match_operand:TF 2 "general_operand" "")))]
6073 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6074 "emit_tfmode_binop (DIV, operands); DONE;")
6076 ;; don't have timing for quad-prec. divide.
6077 (define_insn "*divtf3_hq"
6078 [(set (match_operand:TF 0 "register_operand" "=e")
6079 (div:TF (match_operand:TF 1 "register_operand" "e")
6080 (match_operand:TF 2 "register_operand" "e")))]
6081 "TARGET_FPU && TARGET_HARD_QUAD"
6083 [(set_attr "type" "fpdivd")])
6085 (define_insn "divdf3"
6086 [(set (match_operand:DF 0 "register_operand" "=e")
6087 (div:DF (match_operand:DF 1 "register_operand" "e")
6088 (match_operand:DF 2 "register_operand" "e")))]
6091 [(set_attr "type" "fpdivd")
6092 (set_attr "fptype" "double")])
6094 (define_insn "divsf3"
6095 [(set (match_operand:SF 0 "register_operand" "=f")
6096 (div:SF (match_operand:SF 1 "register_operand" "f")
6097 (match_operand:SF 2 "register_operand" "f")))]
6100 [(set_attr "type" "fpdivs")])
6102 (define_expand "negtf2"
6103 [(set (match_operand:TF 0 "register_operand" "=e,e")
6104 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
6108 (define_insn_and_split "*negtf2_notv9"
6109 [(set (match_operand:TF 0 "register_operand" "=e,e")
6110 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
6111 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
6117 "&& reload_completed
6118 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6119 [(set (match_dup 2) (neg:SF (match_dup 3)))
6120 (set (match_dup 4) (match_dup 5))
6121 (set (match_dup 6) (match_dup 7))]
6122 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6123 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6124 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6125 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
6126 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6127 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6128 [(set_attr "type" "fpmove,*")
6129 (set_attr "length" "*,2")])
6131 (define_insn_and_split "*negtf2_v9"
6132 [(set (match_operand:TF 0 "register_operand" "=e,e")
6133 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
6134 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
6135 "TARGET_FPU && TARGET_V9"
6139 "&& reload_completed
6140 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6141 [(set (match_dup 2) (neg:DF (match_dup 3)))
6142 (set (match_dup 4) (match_dup 5))]
6143 "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
6144 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
6145 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6146 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6147 [(set_attr "type" "fpmove,*")
6148 (set_attr "length" "*,2")
6149 (set_attr "fptype" "double")])
6151 (define_expand "negdf2"
6152 [(set (match_operand:DF 0 "register_operand" "")
6153 (neg:DF (match_operand:DF 1 "register_operand" "")))]
6157 (define_insn_and_split "*negdf2_notv9"
6158 [(set (match_operand:DF 0 "register_operand" "=e,e")
6159 (neg:DF (match_operand:DF 1 "register_operand" "0,e")))]
6160 "TARGET_FPU && ! TARGET_V9"
6164 "&& reload_completed
6165 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6166 [(set (match_dup 2) (neg:SF (match_dup 3)))
6167 (set (match_dup 4) (match_dup 5))]
6168 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6169 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6170 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6171 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);"
6172 [(set_attr "type" "fpmove,*")
6173 (set_attr "length" "*,2")])
6175 (define_insn "*negdf2_v9"
6176 [(set (match_operand:DF 0 "register_operand" "=e")
6177 (neg:DF (match_operand:DF 1 "register_operand" "e")))]
6178 "TARGET_FPU && TARGET_V9"
6180 [(set_attr "type" "fpmove")
6181 (set_attr "fptype" "double")])
6183 (define_insn "negsf2"
6184 [(set (match_operand:SF 0 "register_operand" "=f")
6185 (neg:SF (match_operand:SF 1 "register_operand" "f")))]
6188 [(set_attr "type" "fpmove")])
6190 (define_expand "abstf2"
6191 [(set (match_operand:TF 0 "register_operand" "")
6192 (abs:TF (match_operand:TF 1 "register_operand" "")))]
6196 (define_insn_and_split "*abstf2_notv9"
6197 [(set (match_operand:TF 0 "register_operand" "=e,e")
6198 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6199 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
6200 "TARGET_FPU && ! TARGET_V9"
6204 "&& reload_completed
6205 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6206 [(set (match_dup 2) (abs:SF (match_dup 3)))
6207 (set (match_dup 4) (match_dup 5))
6208 (set (match_dup 6) (match_dup 7))]
6209 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6210 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6211 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6212 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
6213 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6214 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6215 [(set_attr "type" "fpmove,*")
6216 (set_attr "length" "*,2")])
6218 (define_insn "*abstf2_hq_v9"
6219 [(set (match_operand:TF 0 "register_operand" "=e,e")
6220 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6221 "TARGET_FPU && TARGET_V9 && TARGET_HARD_QUAD"
6225 [(set_attr "type" "fpmove")
6226 (set_attr "fptype" "double,*")])
6228 (define_insn_and_split "*abstf2_v9"
6229 [(set (match_operand:TF 0 "register_operand" "=e,e")
6230 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6231 "TARGET_FPU && TARGET_V9 && !TARGET_HARD_QUAD"
6235 "&& reload_completed
6236 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6237 [(set (match_dup 2) (abs:DF (match_dup 3)))
6238 (set (match_dup 4) (match_dup 5))]
6239 "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
6240 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
6241 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6242 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6243 [(set_attr "type" "fpmove,*")
6244 (set_attr "length" "*,2")
6245 (set_attr "fptype" "double,*")])
6247 (define_expand "absdf2"
6248 [(set (match_operand:DF 0 "register_operand" "")
6249 (abs:DF (match_operand:DF 1 "register_operand" "")))]
6253 (define_insn_and_split "*absdf2_notv9"
6254 [(set (match_operand:DF 0 "register_operand" "=e,e")
6255 (abs:DF (match_operand:DF 1 "register_operand" "0,e")))]
6256 "TARGET_FPU && ! TARGET_V9"
6260 "&& reload_completed
6261 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6262 [(set (match_dup 2) (abs:SF (match_dup 3)))
6263 (set (match_dup 4) (match_dup 5))]
6264 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6265 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6266 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6267 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);"
6268 [(set_attr "type" "fpmove,*")
6269 (set_attr "length" "*,2")])
6271 (define_insn "*absdf2_v9"
6272 [(set (match_operand:DF 0 "register_operand" "=e")
6273 (abs:DF (match_operand:DF 1 "register_operand" "e")))]
6274 "TARGET_FPU && TARGET_V9"
6276 [(set_attr "type" "fpmove")
6277 (set_attr "fptype" "double")])
6279 (define_insn "abssf2"
6280 [(set (match_operand:SF 0 "register_operand" "=f")
6281 (abs:SF (match_operand:SF 1 "register_operand" "f")))]
6284 [(set_attr "type" "fpmove")])
6286 (define_expand "sqrttf2"
6287 [(set (match_operand:TF 0 "nonimmediate_operand" "")
6288 (sqrt:TF (match_operand:TF 1 "general_operand" "")))]
6289 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6290 "emit_tfmode_unop (SQRT, operands); DONE;")
6292 (define_insn "*sqrttf2_hq"
6293 [(set (match_operand:TF 0 "register_operand" "=e")
6294 (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
6295 "TARGET_FPU && TARGET_HARD_QUAD"
6297 [(set_attr "type" "fpsqrtd")])
6299 (define_insn "sqrtdf2"
6300 [(set (match_operand:DF 0 "register_operand" "=e")
6301 (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
6304 [(set_attr "type" "fpsqrtd")
6305 (set_attr "fptype" "double")])
6307 (define_insn "sqrtsf2"
6308 [(set (match_operand:SF 0 "register_operand" "=f")
6309 (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
6312 [(set_attr "type" "fpsqrts")])
6315 ;; Arithmetic shift instructions.
6317 (define_insn "ashlsi3"
6318 [(set (match_operand:SI 0 "register_operand" "=r")
6319 (ashift:SI (match_operand:SI 1 "register_operand" "r")
6320 (match_operand:SI 2 "arith_operand" "rI")))]
6323 if (GET_CODE (operands[2]) == CONST_INT)
6324 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6325 return "sll\t%1, %2, %0";
6328 (if_then_else (match_operand 2 "const_one_operand" "")
6329 (const_string "ialu") (const_string "shift")))])
6331 (define_expand "ashldi3"
6332 [(set (match_operand:DI 0 "register_operand" "=r")
6333 (ashift:DI (match_operand:DI 1 "register_operand" "r")
6334 (match_operand:SI 2 "arith_operand" "rI")))]
6335 "TARGET_ARCH64 || TARGET_V8PLUS"
6337 if (! TARGET_ARCH64)
6339 if (GET_CODE (operands[2]) == CONST_INT)
6341 emit_insn (gen_ashldi3_v8plus (operands[0], operands[1], operands[2]));
6346 (define_insn "*ashldi3_sp64"
6347 [(set (match_operand:DI 0 "register_operand" "=r")
6348 (ashift:DI (match_operand:DI 1 "register_operand" "r")
6349 (match_operand:SI 2 "arith_operand" "rI")))]
6352 if (GET_CODE (operands[2]) == CONST_INT)
6353 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
6354 return "sllx\t%1, %2, %0";
6357 (if_then_else (match_operand 2 "const_one_operand" "")
6358 (const_string "ialu") (const_string "shift")))])
6361 (define_insn "ashldi3_v8plus"
6362 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
6363 (ashift:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
6364 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
6365 (clobber (match_scratch:SI 3 "=X,X,&h"))]
6367 "* return output_v8plus_shift (operands, insn, \"sllx\");"
6368 [(set_attr "type" "multi")
6369 (set_attr "length" "5,5,6")])
6371 ;; Optimize (1LL<<x)-1
6372 ;; XXX this also needs to be fixed to handle equal subregs
6373 ;; XXX first before we could re-enable it.
6375 ; [(set (match_operand:DI 0 "register_operand" "=h")
6376 ; (plus:DI (ashift:DI (const_int 1)
6377 ; (match_operand:SI 1 "arith_operand" "rI"))
6379 ; "0 && TARGET_V8PLUS"
6381 ; if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == REGNO (operands[0]))
6382 ; return "mov\t1, %L0\;sllx\t%L0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
6383 ; return "mov\t1, %H0\;sllx\t%H0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
6385 ; [(set_attr "type" "multi")
6386 ; (set_attr "length" "4")])
6388 (define_insn "*cmp_cc_ashift_1"
6389 [(set (reg:CC_NOOV 100)
6390 (compare:CC_NOOV (ashift:SI (match_operand:SI 0 "register_operand" "r")
6394 "addcc\t%0, %0, %%g0"
6395 [(set_attr "type" "compare")])
6397 (define_insn "*cmp_cc_set_ashift_1"
6398 [(set (reg:CC_NOOV 100)
6399 (compare:CC_NOOV (ashift:SI (match_operand:SI 1 "register_operand" "r")
6402 (set (match_operand:SI 0 "register_operand" "=r")
6403 (ashift:SI (match_dup 1) (const_int 1)))]
6406 [(set_attr "type" "compare")])
6408 (define_insn "ashrsi3"
6409 [(set (match_operand:SI 0 "register_operand" "=r")
6410 (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
6411 (match_operand:SI 2 "arith_operand" "rI")))]
6414 if (GET_CODE (operands[2]) == CONST_INT)
6415 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6416 return "sra\t%1, %2, %0";
6418 [(set_attr "type" "shift")])
6420 (define_insn "*ashrsi3_extend"
6421 [(set (match_operand:DI 0 "register_operand" "=r")
6422 (sign_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
6423 (match_operand:SI 2 "arith_operand" "r"))))]
6426 [(set_attr "type" "shift")])
6428 ;; This handles the case as above, but with constant shift instead of
6429 ;; register. Combiner "simplifies" it for us a little bit though.
6430 (define_insn "*ashrsi3_extend2"
6431 [(set (match_operand:DI 0 "register_operand" "=r")
6432 (ashiftrt:DI (ashift:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
6434 (match_operand:SI 2 "small_int_operand" "I")))]
6435 "TARGET_ARCH64 && INTVAL (operands[2]) >= 32 && INTVAL (operands[2]) < 64"
6437 operands[2] = GEN_INT (INTVAL (operands[2]) - 32);
6438 return "sra\t%1, %2, %0";
6440 [(set_attr "type" "shift")])
6442 (define_expand "ashrdi3"
6443 [(set (match_operand:DI 0 "register_operand" "=r")
6444 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
6445 (match_operand:SI 2 "arith_operand" "rI")))]
6446 "TARGET_ARCH64 || TARGET_V8PLUS"
6448 if (! TARGET_ARCH64)
6450 if (GET_CODE (operands[2]) == CONST_INT)
6451 FAIL; /* prefer generic code in this case */
6452 emit_insn (gen_ashrdi3_v8plus (operands[0], operands[1], operands[2]));
6457 (define_insn "*ashrdi3_sp64"
6458 [(set (match_operand:DI 0 "register_operand" "=r")
6459 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
6460 (match_operand:SI 2 "arith_operand" "rI")))]
6464 if (GET_CODE (operands[2]) == CONST_INT)
6465 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
6466 return "srax\t%1, %2, %0";
6468 [(set_attr "type" "shift")])
6471 (define_insn "ashrdi3_v8plus"
6472 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
6473 (ashiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
6474 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
6475 (clobber (match_scratch:SI 3 "=X,X,&h"))]
6477 "* return output_v8plus_shift (operands, insn, \"srax\");"
6478 [(set_attr "type" "multi")
6479 (set_attr "length" "5,5,6")])
6481 (define_insn "lshrsi3"
6482 [(set (match_operand:SI 0 "register_operand" "=r")
6483 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
6484 (match_operand:SI 2 "arith_operand" "rI")))]
6487 if (GET_CODE (operands[2]) == CONST_INT)
6488 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6489 return "srl\t%1, %2, %0";
6491 [(set_attr "type" "shift")])
6493 ;; This handles the case where
6494 ;; (zero_extend:DI (lshiftrt:SI (match_operand:SI) (match_operand:SI))),
6495 ;; but combiner "simplifies" it for us.
6496 (define_insn "*lshrsi3_extend"
6497 [(set (match_operand:DI 0 "register_operand" "=r")
6498 (and:DI (subreg:DI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
6499 (match_operand:SI 2 "arith_operand" "r")) 0)
6500 (match_operand 3 "const_int_operand" "")))]
6501 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) == 0xffffffff"
6503 [(set_attr "type" "shift")])
6505 ;; This handles the case where
6506 ;; (lshiftrt:DI (zero_extend:DI (match_operand:SI)) (const_int >=0 < 32))
6507 ;; but combiner "simplifies" it for us.
6508 (define_insn "*lshrsi3_extend2"
6509 [(set (match_operand:DI 0 "register_operand" "=r")
6510 (zero_extract:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
6511 (match_operand 2 "small_int_operand" "I")
6513 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
6515 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
6516 return "srl\t%1, %2, %0";
6518 [(set_attr "type" "shift")])
6520 (define_expand "lshrdi3"
6521 [(set (match_operand:DI 0 "register_operand" "=r")
6522 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6523 (match_operand:SI 2 "arith_operand" "rI")))]
6524 "TARGET_ARCH64 || TARGET_V8PLUS"
6526 if (! TARGET_ARCH64)
6528 if (GET_CODE (operands[2]) == CONST_INT)
6530 emit_insn (gen_lshrdi3_v8plus (operands[0], operands[1], operands[2]));
6535 (define_insn "*lshrdi3_sp64"
6536 [(set (match_operand:DI 0 "register_operand" "=r")
6537 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6538 (match_operand:SI 2 "arith_operand" "rI")))]
6541 if (GET_CODE (operands[2]) == CONST_INT)
6542 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
6543 return "srlx\t%1, %2, %0";
6545 [(set_attr "type" "shift")])
6548 (define_insn "lshrdi3_v8plus"
6549 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
6550 (lshiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
6551 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
6552 (clobber (match_scratch:SI 3 "=X,X,&h"))]
6554 "* return output_v8plus_shift (operands, insn, \"srlx\");"
6555 [(set_attr "type" "multi")
6556 (set_attr "length" "5,5,6")])
6559 [(set (match_operand:SI 0 "register_operand" "=r")
6560 (ashiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6562 (match_operand:SI 2 "small_int_operand" "I")))]
6563 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
6565 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
6566 return "srax\t%1, %2, %0";
6568 [(set_attr "type" "shift")])
6571 [(set (match_operand:SI 0 "register_operand" "=r")
6572 (lshiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
6574 (match_operand:SI 2 "small_int_operand" "I")))]
6575 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
6577 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
6578 return "srlx\t%1, %2, %0";
6580 [(set_attr "type" "shift")])
6583 [(set (match_operand:SI 0 "register_operand" "=r")
6584 (ashiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
6585 (match_operand:SI 2 "small_int_operand" "I")) 4)
6586 (match_operand:SI 3 "small_int_operand" "I")))]
6588 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
6589 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
6590 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
6592 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
6594 return "srax\t%1, %2, %0";
6596 [(set_attr "type" "shift")])
6599 [(set (match_operand:SI 0 "register_operand" "=r")
6600 (lshiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6601 (match_operand:SI 2 "small_int_operand" "I")) 4)
6602 (match_operand:SI 3 "small_int_operand" "I")))]
6604 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
6605 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
6606 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
6608 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
6610 return "srlx\t%1, %2, %0";
6612 [(set_attr "type" "shift")])
6615 ;; Unconditional and other jump instructions.
6618 [(set (pc) (label_ref (match_operand 0 "" "")))]
6620 "* return output_ubranch (operands[0], 0, insn);"
6621 [(set_attr "type" "uncond_branch")])
6623 (define_expand "tablejump"
6624 [(parallel [(set (pc) (match_operand 0 "register_operand" "r"))
6625 (use (label_ref (match_operand 1 "" "")))])]
6628 gcc_assert (GET_MODE (operands[0]) == CASE_VECTOR_MODE);
6630 /* In pic mode, our address differences are against the base of the
6631 table. Add that base value back in; CSE ought to be able to combine
6632 the two address loads. */
6636 tmp = gen_rtx_LABEL_REF (Pmode, operands[1]);
6638 if (CASE_VECTOR_MODE != Pmode)
6639 tmp2 = gen_rtx_SIGN_EXTEND (Pmode, tmp2);
6640 tmp = gen_rtx_PLUS (Pmode, tmp2, tmp);
6641 operands[0] = memory_address (Pmode, tmp);
6645 (define_insn "*tablejump_sp32"
6646 [(set (pc) (match_operand:SI 0 "address_operand" "p"))
6647 (use (label_ref (match_operand 1 "" "")))]
6650 [(set_attr "type" "uncond_branch")])
6652 (define_insn "*tablejump_sp64"
6653 [(set (pc) (match_operand:DI 0 "address_operand" "p"))
6654 (use (label_ref (match_operand 1 "" "")))]
6657 [(set_attr "type" "uncond_branch")])
6660 ;; Jump to subroutine instructions.
6662 (define_expand "call"
6663 ;; Note that this expression is not used for generating RTL.
6664 ;; All the RTL is generated explicitly below.
6665 [(call (match_operand 0 "call_operand" "")
6666 (match_operand 3 "" "i"))]
6667 ;; operands[2] is next_arg_register
6668 ;; operands[3] is struct_value_size_rtx.
6673 gcc_assert (GET_MODE (operands[0]) == FUNCTION_MODE);
6675 gcc_assert (GET_CODE (operands[3]) == CONST_INT);
6677 if (GET_CODE (XEXP (operands[0], 0)) == LABEL_REF)
6679 /* This is really a PIC sequence. We want to represent
6680 it as a funny jump so its delay slots can be filled.
6682 ??? But if this really *is* a CALL, will not it clobber the
6683 call-clobbered registers? We lose this if it is a JUMP_INSN.
6684 Why cannot we have delay slots filled if it were a CALL? */
6686 /* We accept negative sizes for untyped calls. */
6687 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
6692 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
6694 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
6700 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
6701 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
6705 fn_rtx = operands[0];
6707 /* We accept negative sizes for untyped calls. */
6708 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
6712 gen_rtvec (3, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx),
6714 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
6719 gen_rtvec (2, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx),
6720 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
6727 ;; We can't use the same pattern for these two insns, because then registers
6728 ;; in the address may not be properly reloaded.
6730 (define_insn "*call_address_sp32"
6731 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6732 (match_operand 1 "" ""))
6733 (clobber (reg:SI 15))]
6734 ;;- Do not use operand 1 for most machines.
6737 [(set_attr "type" "call")])
6739 (define_insn "*call_symbolic_sp32"
6740 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6741 (match_operand 1 "" ""))
6742 (clobber (reg:SI 15))]
6743 ;;- Do not use operand 1 for most machines.
6746 [(set_attr "type" "call")])
6748 (define_insn "*call_address_sp64"
6749 [(call (mem:DI (match_operand:DI 0 "address_operand" "p"))
6750 (match_operand 1 "" ""))
6751 (clobber (reg:DI 15))]
6752 ;;- Do not use operand 1 for most machines.
6755 [(set_attr "type" "call")])
6757 (define_insn "*call_symbolic_sp64"
6758 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
6759 (match_operand 1 "" ""))
6760 (clobber (reg:DI 15))]
6761 ;;- Do not use operand 1 for most machines.
6764 [(set_attr "type" "call")])
6766 ;; This is a call that wants a structure value.
6767 ;; There is no such critter for v9 (??? we may need one anyway).
6768 (define_insn "*call_address_struct_value_sp32"
6769 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6770 (match_operand 1 "" ""))
6771 (match_operand 2 "immediate_operand" "")
6772 (clobber (reg:SI 15))]
6773 ;;- Do not use operand 1 for most machines.
6774 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
6776 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xfff);
6777 return "call\t%a0, %1\n\t nop\n\tunimp\t%2";
6779 [(set_attr "type" "call_no_delay_slot")
6780 (set_attr "length" "3")])
6782 ;; This is a call that wants a structure value.
6783 ;; There is no such critter for v9 (??? we may need one anyway).
6784 (define_insn "*call_symbolic_struct_value_sp32"
6785 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6786 (match_operand 1 "" ""))
6787 (match_operand 2 "immediate_operand" "")
6788 (clobber (reg:SI 15))]
6789 ;;- Do not use operand 1 for most machines.
6790 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
6792 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xfff);
6793 return "call\t%a0, %1\n\t nop\n\tunimp\t%2";
6795 [(set_attr "type" "call_no_delay_slot")
6796 (set_attr "length" "3")])
6798 ;; This is a call that may want a structure value. This is used for
6800 (define_insn "*call_address_untyped_struct_value_sp32"
6801 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6802 (match_operand 1 "" ""))
6803 (match_operand 2 "immediate_operand" "")
6804 (clobber (reg:SI 15))]
6805 ;;- Do not use operand 1 for most machines.
6806 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
6807 "call\t%a0, %1\n\t nop\n\tnop"
6808 [(set_attr "type" "call_no_delay_slot")
6809 (set_attr "length" "3")])
6811 ;; This is a call that may want a structure value. This is used for
6813 (define_insn "*call_symbolic_untyped_struct_value_sp32"
6814 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6815 (match_operand 1 "" ""))
6816 (match_operand 2 "immediate_operand" "")
6817 (clobber (reg:SI 15))]
6818 ;;- Do not use operand 1 for most machines.
6819 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
6820 "call\t%a0, %1\n\t nop\n\tnop"
6821 [(set_attr "type" "call_no_delay_slot")
6822 (set_attr "length" "3")])
6824 (define_expand "call_value"
6825 ;; Note that this expression is not used for generating RTL.
6826 ;; All the RTL is generated explicitly below.
6827 [(set (match_operand 0 "register_operand" "=rf")
6828 (call (match_operand 1 "" "")
6829 (match_operand 4 "" "")))]
6830 ;; operand 2 is stack_size_rtx
6831 ;; operand 3 is next_arg_register
6837 gcc_assert (GET_MODE (operands[1]) == FUNCTION_MODE);
6839 fn_rtx = operands[1];
6842 gen_rtx_SET (VOIDmode, operands[0],
6843 gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx)),
6844 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)));
6846 emit_call_insn (gen_rtx_PARALLEL (VOIDmode, vec));
6851 (define_insn "*call_value_address_sp32"
6852 [(set (match_operand 0 "" "=rf")
6853 (call (mem:SI (match_operand:SI 1 "address_operand" "p"))
6854 (match_operand 2 "" "")))
6855 (clobber (reg:SI 15))]
6856 ;;- Do not use operand 2 for most machines.
6859 [(set_attr "type" "call")])
6861 (define_insn "*call_value_symbolic_sp32"
6862 [(set (match_operand 0 "" "=rf")
6863 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
6864 (match_operand 2 "" "")))
6865 (clobber (reg:SI 15))]
6866 ;;- Do not use operand 2 for most machines.
6869 [(set_attr "type" "call")])
6871 (define_insn "*call_value_address_sp64"
6872 [(set (match_operand 0 "" "")
6873 (call (mem:DI (match_operand:DI 1 "address_operand" "p"))
6874 (match_operand 2 "" "")))
6875 (clobber (reg:DI 15))]
6876 ;;- Do not use operand 2 for most machines.
6879 [(set_attr "type" "call")])
6881 (define_insn "*call_value_symbolic_sp64"
6882 [(set (match_operand 0 "" "")
6883 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
6884 (match_operand 2 "" "")))
6885 (clobber (reg:DI 15))]
6886 ;;- Do not use operand 2 for most machines.
6889 [(set_attr "type" "call")])
6891 (define_expand "untyped_call"
6892 [(parallel [(call (match_operand 0 "" "")
6894 (match_operand:BLK 1 "memory_operand" "")
6895 (match_operand 2 "" "")])]
6898 rtx valreg1 = gen_rtx_REG (DImode, 8);
6899 rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
6900 rtx result = operands[1];
6902 /* Pass constm1 to indicate that it may expect a structure value, but
6903 we don't know what size it is. */
6904 emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, constm1_rtx));
6906 /* Save the function value registers. */
6907 emit_move_insn (adjust_address (result, DImode, 0), valreg1);
6908 emit_move_insn (adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8),
6911 /* The optimizer does not know that the call sets the function value
6912 registers we stored in the result block. We avoid problems by
6913 claiming that all hard registers are used and clobbered at this
6915 emit_insn (gen_blockage ());
6920 ;; Tail call instructions.
6922 (define_expand "sibcall"
6923 [(parallel [(call (match_operand 0 "call_operand" "") (const_int 0))
6928 (define_insn "*sibcall_symbolic_sp32"
6929 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6930 (match_operand 1 "" ""))
6933 "* return output_sibcall(insn, operands[0]);"
6934 [(set_attr "type" "sibcall")])
6936 (define_insn "*sibcall_symbolic_sp64"
6937 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
6938 (match_operand 1 "" ""))
6941 "* return output_sibcall(insn, operands[0]);"
6942 [(set_attr "type" "sibcall")])
6944 (define_expand "sibcall_value"
6945 [(parallel [(set (match_operand 0 "register_operand" "=rf")
6946 (call (match_operand 1 "" "") (const_int 0)))
6951 (define_insn "*sibcall_value_symbolic_sp32"
6952 [(set (match_operand 0 "" "=rf")
6953 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
6954 (match_operand 2 "" "")))
6957 "* return output_sibcall(insn, operands[1]);"
6958 [(set_attr "type" "sibcall")])
6960 (define_insn "*sibcall_value_symbolic_sp64"
6961 [(set (match_operand 0 "" "")
6962 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
6963 (match_operand 2 "" "")))
6966 "* return output_sibcall(insn, operands[1]);"
6967 [(set_attr "type" "sibcall")])
6970 ;; Special instructions.
6972 (define_expand "prologue"
6976 sparc_expand_prologue ();
6980 ;; The "save register window" insn is modelled as follows so that the DWARF-2
6981 ;; backend automatically emits the required call frame debugging information
6982 ;; while it is parsing it. Therefore, the pattern should not be modified
6983 ;; without first studying the impact of the changes on the debug info.
6984 ;; [(set (%fp) (%sp))
6985 ;; (set (%sp) (unspec_volatile [(%sp) (-frame_size)] UNSPECV_SAVEW))
6986 ;; (set (%i7) (%o7))]
6988 (define_insn "save_register_window<P:mode>"
6989 [(set (reg:P 30) (reg:P 14))
6990 (set (reg:P 14) (unspec_volatile:P [(reg:P 14)
6991 (match_operand:P 0 "arith_operand" "rI")] UNSPECV_SAVEW))
6992 (set (reg:P 31) (reg:P 15))]
6994 "save\t%%sp, %0, %%sp"
6995 [(set_attr "type" "savew")])
6997 (define_expand "epilogue"
7001 sparc_expand_epilogue ();
7004 (define_expand "sibcall_epilogue"
7008 sparc_expand_epilogue ();
7012 (define_expand "return"
7014 "sparc_can_use_return_insn_p ()"
7017 (define_insn "*return_internal"
7020 "* return output_return (insn);"
7021 [(set_attr "type" "return")
7022 (set (attr "length")
7023 (cond [(eq_attr "leaf_function" "true")
7024 (if_then_else (eq_attr "empty_delay_slot" "true")
7027 (eq_attr "calls_eh_return" "true")
7028 (if_then_else (eq_attr "delayed_branch" "true")
7029 (if_then_else (eq_attr "isa" "v9")
7032 (if_then_else (eq_attr "isa" "v9")
7035 (eq_attr "empty_delay_slot" "true")
7036 (if_then_else (eq_attr "delayed_branch" "true")
7041 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
7042 ;; all of memory. This blocks insns from being moved across this point.
7044 (define_insn "blockage"
7045 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
7048 [(set_attr "length" "0")])
7050 ;; Prepare to return any type including a structure value.
7052 (define_expand "untyped_return"
7053 [(match_operand:BLK 0 "memory_operand" "")
7054 (match_operand 1 "" "")]
7057 rtx valreg1 = gen_rtx_REG (DImode, 24);
7058 rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
7059 rtx result = operands[0];
7061 if (! TARGET_ARCH64)
7063 rtx rtnreg = gen_rtx_REG (SImode, (current_function_uses_only_leaf_regs
7065 rtx value = gen_reg_rtx (SImode);
7067 /* Fetch the instruction where we will return to and see if it's an unimp
7068 instruction (the most significant 10 bits will be zero). If so,
7069 update the return address to skip the unimp instruction. */
7070 emit_move_insn (value,
7071 gen_rtx_MEM (SImode, plus_constant (rtnreg, 8)));
7072 emit_insn (gen_lshrsi3 (value, value, GEN_INT (22)));
7073 emit_insn (gen_update_return (rtnreg, value));
7076 /* Reload the function value registers. */
7077 emit_move_insn (valreg1, adjust_address (result, DImode, 0));
7078 emit_move_insn (valreg2,
7079 adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8));
7081 /* Put USE insns before the return. */
7082 emit_insn (gen_rtx_USE (VOIDmode, valreg1));
7083 emit_insn (gen_rtx_USE (VOIDmode, valreg2));
7085 /* Construct the return. */
7086 expand_naked_return ();
7091 ;; This is a bit of a hack. We're incrementing a fixed register (%i7),
7092 ;; and parts of the compiler don't want to believe that the add is needed.
7094 (define_insn "update_return"
7095 [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
7096 (match_operand:SI 1 "register_operand" "r")] UNSPEC_UPDATE_RETURN)]
7099 if (flag_delayed_branch)
7100 return "cmp\t%1, 0\n\tbe,a\t.+8\n\t add\t%0, 4, %0";
7102 return "cmp\t%1, 0\n\tbne\t.+12\n\t nop\n\tadd\t%0, 4, %0";
7104 [(set (attr "type") (const_string "multi"))
7105 (set (attr "length")
7106 (if_then_else (eq_attr "delayed_branch" "true")
7115 (define_expand "indirect_jump"
7116 [(set (pc) (match_operand 0 "address_operand" "p"))]
7120 (define_insn "*branch_sp32"
7121 [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
7124 [(set_attr "type" "uncond_branch")])
7126 (define_insn "*branch_sp64"
7127 [(set (pc) (match_operand:DI 0 "address_operand" "p"))]
7130 [(set_attr "type" "uncond_branch")])
7132 (define_expand "nonlocal_goto"
7133 [(match_operand:SI 0 "general_operand" "")
7134 (match_operand:SI 1 "general_operand" "")
7135 (match_operand:SI 2 "general_operand" "")
7136 (match_operand:SI 3 "" "")]
7139 rtx lab = operands[1];
7140 rtx stack = operands[2];
7141 rtx fp = operands[3];
7144 /* Trap instruction to flush all the register windows. */
7145 emit_insn (gen_flush_register_windows ());
7147 /* Load the fp value for the containing fn into %fp. This is needed
7148 because STACK refers to %fp. Note that virtual register instantiation
7149 fails if the virtual %fp isn't set from a register. */
7150 if (GET_CODE (fp) != REG)
7151 fp = force_reg (Pmode, fp);
7152 emit_move_insn (virtual_stack_vars_rtx, fp);
7154 /* Find the containing function's current nonlocal goto handler,
7155 which will do any cleanups and then jump to the label. */
7156 labreg = gen_rtx_REG (Pmode, 8);
7157 emit_move_insn (labreg, lab);
7159 /* Restore %fp from stack pointer value for containing function.
7160 The restore insn that follows will move this to %sp,
7161 and reload the appropriate value into %fp. */
7162 emit_move_insn (hard_frame_pointer_rtx, stack);
7164 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
7165 emit_insn (gen_rtx_USE (VOIDmode, static_chain_rtx));
7167 /* ??? The V9-specific version was disabled in rev 1.65. */
7168 emit_jump_insn (gen_goto_handler_and_restore (labreg));
7173 ;; Special trap insn to flush register windows.
7174 (define_insn "flush_register_windows"
7175 [(unspec_volatile [(const_int 0)] UNSPECV_FLUSHW)]
7177 { return TARGET_V9 ? "flushw" : "ta\t3"; }
7178 [(set_attr "type" "flushw")])
7180 (define_insn "goto_handler_and_restore"
7181 [(unspec_volatile [(match_operand 0 "register_operand" "=r")] UNSPECV_GOTO)]
7182 "GET_MODE (operands[0]) == Pmode"
7184 if (flag_delayed_branch)
7185 return "jmp\t%0\n\t restore";
7187 return "mov\t%0,%%g1\n\trestore\n\tjmp\t%%g1\n\t nop";
7189 [(set (attr "type") (const_string "multi"))
7190 (set (attr "length")
7191 (if_then_else (eq_attr "delayed_branch" "true")
7195 ;; For __builtin_setjmp we need to flush register windows iff the function
7196 ;; calls alloca as well, because otherwise the register window might be
7197 ;; saved after %sp adjustment and thus setjmp would crash
7198 (define_expand "builtin_setjmp_setup"
7199 [(match_operand 0 "register_operand" "r")]
7202 emit_insn (gen_do_builtin_setjmp_setup ());
7206 (define_insn "do_builtin_setjmp_setup"
7207 [(unspec_volatile [(const_int 0)] UNSPECV_SETJMP)]
7210 if (! current_function_calls_alloca)
7214 fputs ("\tflushw\n", asm_out_file);
7216 fprintf (asm_out_file, "\tst%c\t%%l7, [%%sp+%d]\n",
7217 TARGET_ARCH64 ? 'x' : 'w',
7218 SPARC_STACK_BIAS + 7 * UNITS_PER_WORD);
7219 fprintf (asm_out_file, "\tst%c\t%%fp, [%%sp+%d]\n",
7220 TARGET_ARCH64 ? 'x' : 'w',
7221 SPARC_STACK_BIAS + 14 * UNITS_PER_WORD);
7222 fprintf (asm_out_file, "\tst%c\t%%i7, [%%sp+%d]\n",
7223 TARGET_ARCH64 ? 'x' : 'w',
7224 SPARC_STACK_BIAS + 15 * UNITS_PER_WORD);
7227 [(set_attr "type" "multi")
7228 (set (attr "length")
7229 (cond [(eq_attr "calls_alloca" "false")
7231 (eq_attr "isa" "!v9")
7233 (eq_attr "pic" "true")
7234 (const_int 4)] (const_int 3)))])
7236 ;; Pattern for use after a setjmp to store FP and the return register
7237 ;; into the stack area.
7239 (define_expand "setjmp"
7244 emit_insn (gen_setjmp_64 ());
7246 emit_insn (gen_setjmp_32 ());
7250 (define_expand "setjmp_32"
7251 [(set (mem:SI (plus:SI (reg:SI 14) (const_int 56))) (match_dup 0))
7252 (set (mem:SI (plus:SI (reg:SI 14) (const_int 60))) (reg:SI 31))]
7254 { operands[0] = frame_pointer_rtx; })
7256 (define_expand "setjmp_64"
7257 [(set (mem:DI (plus:DI (reg:DI 14) (const_int 112))) (match_dup 0))
7258 (set (mem:DI (plus:DI (reg:DI 14) (const_int 120))) (reg:DI 31))]
7260 { operands[0] = frame_pointer_rtx; })
7262 ;; Special pattern for the FLUSH instruction.
7264 ; We do SImode and DImode versions of this to quiet down genrecog's complaints
7265 ; of the define_insn otherwise missing a mode. We make "flush", aka
7266 ; gen_flush, the default one since sparc_initialize_trampoline uses
7267 ; it on SImode mem values.
7269 (define_insn "flush"
7270 [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")] UNSPECV_FLUSH)]
7272 { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; }
7273 [(set_attr "type" "iflush")])
7275 (define_insn "flushdi"
7276 [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")] UNSPECV_FLUSH)]
7278 { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; }
7279 [(set_attr "type" "iflush")])
7282 ;; Find first set instructions.
7284 ;; The scan instruction searches from the most significant bit while ffs
7285 ;; searches from the least significant bit. The bit index and treatment of
7286 ;; zero also differ. It takes at least 7 instructions to get the proper
7287 ;; result. Here is an obvious 8 instruction sequence.
7290 (define_insn "ffssi2"
7291 [(set (match_operand:SI 0 "register_operand" "=&r")
7292 (ffs:SI (match_operand:SI 1 "register_operand" "r")))
7293 (clobber (match_scratch:SI 2 "=&r"))]
7294 "TARGET_SPARCLITE || TARGET_SPARCLET"
7296 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";
7298 [(set_attr "type" "multi")
7299 (set_attr "length" "8")])
7301 ;; ??? This should be a define expand, so that the extra instruction have
7302 ;; a chance of being optimized away.
7304 ;; Disabled because none of the UltraSPARCs implement popc. The HAL R1
7305 ;; does, but no one uses that and we don't have a switch for it.
7307 ;(define_insn "ffsdi2"
7308 ; [(set (match_operand:DI 0 "register_operand" "=&r")
7309 ; (ffs:DI (match_operand:DI 1 "register_operand" "r")))
7310 ; (clobber (match_scratch:DI 2 "=&r"))]
7312 ; "neg\t%1, %2\;xnor\t%1, %2, %2\;popc\t%2, %0\;movzr\t%1, 0, %0"
7313 ; [(set_attr "type" "multi")
7314 ; (set_attr "length" "4")])
7318 ;; Peepholes go at the end.
7320 ;; Optimize consecutive loads or stores into ldd and std when possible.
7321 ;; The conditions in which we do this are very restricted and are
7322 ;; explained in the code for {registers,memory}_ok_for_ldd functions.
7325 [(set (match_operand:SI 0 "memory_operand" "")
7327 (set (match_operand:SI 1 "memory_operand" "")
7330 && mems_ok_for_ldd_peep (operands[0], operands[1], NULL_RTX)"
7333 "operands[0] = widen_memory_access (operands[0], DImode, 0);")
7336 [(set (match_operand:SI 0 "memory_operand" "")
7338 (set (match_operand:SI 1 "memory_operand" "")
7341 && mems_ok_for_ldd_peep (operands[1], operands[0], NULL_RTX)"
7344 "operands[1] = widen_memory_access (operands[1], DImode, 0);")
7347 [(set (match_operand:SI 0 "register_operand" "")
7348 (match_operand:SI 1 "memory_operand" ""))
7349 (set (match_operand:SI 2 "register_operand" "")
7350 (match_operand:SI 3 "memory_operand" ""))]
7351 "registers_ok_for_ldd_peep (operands[0], operands[2])
7352 && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
7355 "operands[1] = widen_memory_access (operands[1], DImode, 0);
7356 operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));")
7359 [(set (match_operand:SI 0 "memory_operand" "")
7360 (match_operand:SI 1 "register_operand" ""))
7361 (set (match_operand:SI 2 "memory_operand" "")
7362 (match_operand:SI 3 "register_operand" ""))]
7363 "registers_ok_for_ldd_peep (operands[1], operands[3])
7364 && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
7367 "operands[0] = widen_memory_access (operands[0], DImode, 0);
7368 operands[1] = gen_rtx_REG (DImode, REGNO (operands[1]));")
7371 [(set (match_operand:SF 0 "register_operand" "")
7372 (match_operand:SF 1 "memory_operand" ""))
7373 (set (match_operand:SF 2 "register_operand" "")
7374 (match_operand:SF 3 "memory_operand" ""))]
7375 "registers_ok_for_ldd_peep (operands[0], operands[2])
7376 && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
7379 "operands[1] = widen_memory_access (operands[1], DFmode, 0);
7380 operands[0] = gen_rtx_REG (DFmode, REGNO (operands[0]));")
7383 [(set (match_operand:SF 0 "memory_operand" "")
7384 (match_operand:SF 1 "register_operand" ""))
7385 (set (match_operand:SF 2 "memory_operand" "")
7386 (match_operand:SF 3 "register_operand" ""))]
7387 "registers_ok_for_ldd_peep (operands[1], operands[3])
7388 && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
7391 "operands[0] = widen_memory_access (operands[0], DFmode, 0);
7392 operands[1] = gen_rtx_REG (DFmode, REGNO (operands[1]));")
7395 [(set (match_operand:SI 0 "register_operand" "")
7396 (match_operand:SI 1 "memory_operand" ""))
7397 (set (match_operand:SI 2 "register_operand" "")
7398 (match_operand:SI 3 "memory_operand" ""))]
7399 "registers_ok_for_ldd_peep (operands[2], operands[0])
7400 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
7403 "operands[3] = widen_memory_access (operands[3], DImode, 0);
7404 operands[2] = gen_rtx_REG (DImode, REGNO (operands[2]));")
7407 [(set (match_operand:SI 0 "memory_operand" "")
7408 (match_operand:SI 1 "register_operand" ""))
7409 (set (match_operand:SI 2 "memory_operand" "")
7410 (match_operand:SI 3 "register_operand" ""))]
7411 "registers_ok_for_ldd_peep (operands[3], operands[1])
7412 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
7415 "operands[2] = widen_memory_access (operands[2], DImode, 0);
7416 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
7420 [(set (match_operand:SF 0 "register_operand" "")
7421 (match_operand:SF 1 "memory_operand" ""))
7422 (set (match_operand:SF 2 "register_operand" "")
7423 (match_operand:SF 3 "memory_operand" ""))]
7424 "registers_ok_for_ldd_peep (operands[2], operands[0])
7425 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
7428 "operands[3] = widen_memory_access (operands[3], DFmode, 0);
7429 operands[2] = gen_rtx_REG (DFmode, REGNO (operands[2]));")
7432 [(set (match_operand:SF 0 "memory_operand" "")
7433 (match_operand:SF 1 "register_operand" ""))
7434 (set (match_operand:SF 2 "memory_operand" "")
7435 (match_operand:SF 3 "register_operand" ""))]
7436 "registers_ok_for_ldd_peep (operands[3], operands[1])
7437 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
7440 "operands[2] = widen_memory_access (operands[2], DFmode, 0);
7441 operands[3] = gen_rtx_REG (DFmode, REGNO (operands[3]));")
7443 ;; Optimize the case of following a reg-reg move with a test
7444 ;; of reg just moved. Don't allow floating point regs for operand 0 or 1.
7445 ;; This can result from a float to fix conversion.
7448 [(set (match_operand:SI 0 "register_operand" "")
7449 (match_operand:SI 1 "register_operand" ""))
7451 (compare:CC (match_operand:SI 2 "register_operand" "")
7453 "(rtx_equal_p (operands[2], operands[0])
7454 || rtx_equal_p (operands[2], operands[1]))
7455 && ! SPARC_FP_REG_P (REGNO (operands[0]))
7456 && ! SPARC_FP_REG_P (REGNO (operands[1]))"
7457 [(parallel [(set (match_dup 0) (match_dup 1))
7459 (compare:CC (match_dup 1) (const_int 0)))])]
7463 [(set (match_operand:DI 0 "register_operand" "")
7464 (match_operand:DI 1 "register_operand" ""))
7466 (compare:CCX (match_operand:DI 2 "register_operand" "")
7469 && (rtx_equal_p (operands[2], operands[0])
7470 || rtx_equal_p (operands[2], operands[1]))
7471 && ! SPARC_FP_REG_P (REGNO (operands[0]))
7472 && ! SPARC_FP_REG_P (REGNO (operands[1]))"
7473 [(parallel [(set (match_dup 0) (match_dup 1))
7475 (compare:CCX (match_dup 1) (const_int 0)))])]
7479 ;; Prefetch instructions.
7481 ;; ??? UltraSPARC-III note: A memory operation loading into the floating point register
7482 ;; ??? file, if it hits the prefetch cache, has a chance to dual-issue with other memory
7483 ;; ??? operations. With DFA we might be able to model this, but it requires a lot of
7485 (define_expand "prefetch"
7486 [(match_operand 0 "address_operand" "")
7487 (match_operand 1 "const_int_operand" "")
7488 (match_operand 2 "const_int_operand" "")]
7492 emit_insn (gen_prefetch_64 (operands[0], operands[1], operands[2]));
7494 emit_insn (gen_prefetch_32 (operands[0], operands[1], operands[2]));
7498 (define_insn "prefetch_64"
7499 [(prefetch (match_operand:DI 0 "address_operand" "p")
7500 (match_operand:DI 1 "const_int_operand" "n")
7501 (match_operand:DI 2 "const_int_operand" "n"))]
7504 static const char * const prefetch_instr[2][2] = {
7506 "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
7507 "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
7510 "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
7511 "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
7514 int read_or_write = INTVAL (operands[1]);
7515 int locality = INTVAL (operands[2]);
7517 gcc_assert (read_or_write == 0 || read_or_write == 1);
7518 gcc_assert (locality >= 0 && locality < 4);
7519 return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
7521 [(set_attr "type" "load")])
7523 (define_insn "prefetch_32"
7524 [(prefetch (match_operand:SI 0 "address_operand" "p")
7525 (match_operand:SI 1 "const_int_operand" "n")
7526 (match_operand:SI 2 "const_int_operand" "n"))]
7529 static const char * const prefetch_instr[2][2] = {
7531 "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
7532 "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
7535 "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
7536 "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
7539 int read_or_write = INTVAL (operands[1]);
7540 int locality = INTVAL (operands[2]);
7542 gcc_assert (read_or_write == 0 || read_or_write == 1);
7543 gcc_assert (locality >= 0 && locality < 4);
7544 return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
7546 [(set_attr "type" "load")])
7549 ;; Trap instructions.
7552 [(trap_if (const_int 1) (const_int 5))]
7555 [(set_attr "type" "trap")])
7557 (define_expand "conditional_trap"
7558 [(trap_if (match_operator 0 "noov_compare_operator" [(match_dup 2) (match_dup 3)])
7559 (match_operand:SI 1 "arith_operand" ""))]
7561 "operands[2] = gen_compare_reg (GET_CODE (operands[0]));
7562 if (GET_MODE (operands[2]) != CCmode && GET_MODE (operands[2]) != CCXmode)
7564 operands[3] = const0_rtx;")
7567 [(trap_if (match_operator 0 "noov_compare_operator" [(reg:CC 100) (const_int 0)])
7568 (match_operand:SI 1 "arith_operand" "rM"))]
7572 return "t%C0\t%%icc, %1";
7576 [(set_attr "type" "trap")])
7579 [(trap_if (match_operator 0 "noov_compare_operator" [(reg:CCX 100) (const_int 0)])
7580 (match_operand:SI 1 "arith_operand" "rM"))]
7583 [(set_attr "type" "trap")])
7586 ;; TLS support instructions.
7588 (define_insn "tgd_hi22"
7589 [(set (match_operand:SI 0 "register_operand" "=r")
7590 (high:SI (unspec:SI [(match_operand 1 "tgd_symbolic_operand" "")]
7593 "sethi\\t%%tgd_hi22(%a1), %0")
7595 (define_insn "tgd_lo10"
7596 [(set (match_operand:SI 0 "register_operand" "=r")
7597 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7598 (unspec:SI [(match_operand 2 "tgd_symbolic_operand" "")]
7601 "add\\t%1, %%tgd_lo10(%a2), %0")
7603 (define_insn "tgd_add32"
7604 [(set (match_operand:SI 0 "register_operand" "=r")
7605 (plus:SI (match_operand:SI 1 "register_operand" "r")
7606 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7607 (match_operand 3 "tgd_symbolic_operand" "")]
7609 "TARGET_TLS && TARGET_ARCH32"
7610 "add\\t%1, %2, %0, %%tgd_add(%a3)")
7612 (define_insn "tgd_add64"
7613 [(set (match_operand:DI 0 "register_operand" "=r")
7614 (plus:DI (match_operand:DI 1 "register_operand" "r")
7615 (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7616 (match_operand 3 "tgd_symbolic_operand" "")]
7618 "TARGET_TLS && TARGET_ARCH64"
7619 "add\\t%1, %2, %0, %%tgd_add(%a3)")
7621 (define_insn "tgd_call32"
7622 [(set (match_operand 0 "register_operand" "=r")
7623 (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")
7624 (match_operand 2 "tgd_symbolic_operand" "")]
7626 (match_operand 3 "" "")))
7627 (clobber (reg:SI 15))]
7628 "TARGET_TLS && TARGET_ARCH32"
7629 "call\t%a1, %%tgd_call(%a2)%#"
7630 [(set_attr "type" "call")])
7632 (define_insn "tgd_call64"
7633 [(set (match_operand 0 "register_operand" "=r")
7634 (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")
7635 (match_operand 2 "tgd_symbolic_operand" "")]
7637 (match_operand 3 "" "")))
7638 (clobber (reg:DI 15))]
7639 "TARGET_TLS && TARGET_ARCH64"
7640 "call\t%a1, %%tgd_call(%a2)%#"
7641 [(set_attr "type" "call")])
7643 (define_insn "tldm_hi22"
7644 [(set (match_operand:SI 0 "register_operand" "=r")
7645 (high:SI (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
7647 "sethi\\t%%tldm_hi22(%&), %0")
7649 (define_insn "tldm_lo10"
7650 [(set (match_operand:SI 0 "register_operand" "=r")
7651 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7652 (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
7654 "add\\t%1, %%tldm_lo10(%&), %0")
7656 (define_insn "tldm_add32"
7657 [(set (match_operand:SI 0 "register_operand" "=r")
7658 (plus:SI (match_operand:SI 1 "register_operand" "r")
7659 (unspec:SI [(match_operand:SI 2 "register_operand" "r")]
7661 "TARGET_TLS && TARGET_ARCH32"
7662 "add\\t%1, %2, %0, %%tldm_add(%&)")
7664 (define_insn "tldm_add64"
7665 [(set (match_operand:DI 0 "register_operand" "=r")
7666 (plus:DI (match_operand:DI 1 "register_operand" "r")
7667 (unspec:DI [(match_operand:SI 2 "register_operand" "r")]
7669 "TARGET_TLS && TARGET_ARCH64"
7670 "add\\t%1, %2, %0, %%tldm_add(%&)")
7672 (define_insn "tldm_call32"
7673 [(set (match_operand 0 "register_operand" "=r")
7674 (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")]
7676 (match_operand 2 "" "")))
7677 (clobber (reg:SI 15))]
7678 "TARGET_TLS && TARGET_ARCH32"
7679 "call\t%a1, %%tldm_call(%&)%#"
7680 [(set_attr "type" "call")])
7682 (define_insn "tldm_call64"
7683 [(set (match_operand 0 "register_operand" "=r")
7684 (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")]
7686 (match_operand 2 "" "")))
7687 (clobber (reg:DI 15))]
7688 "TARGET_TLS && TARGET_ARCH64"
7689 "call\t%a1, %%tldm_call(%&)%#"
7690 [(set_attr "type" "call")])
7692 (define_insn "tldo_hix22"
7693 [(set (match_operand:SI 0 "register_operand" "=r")
7694 (high:SI (unspec:SI [(match_operand 1 "tld_symbolic_operand" "")]
7697 "sethi\\t%%tldo_hix22(%a1), %0")
7699 (define_insn "tldo_lox10"
7700 [(set (match_operand:SI 0 "register_operand" "=r")
7701 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7702 (unspec:SI [(match_operand 2 "tld_symbolic_operand" "")]
7705 "xor\\t%1, %%tldo_lox10(%a2), %0")
7707 (define_insn "tldo_add32"
7708 [(set (match_operand:SI 0 "register_operand" "=r")
7709 (plus:SI (match_operand:SI 1 "register_operand" "r")
7710 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7711 (match_operand 3 "tld_symbolic_operand" "")]
7713 "TARGET_TLS && TARGET_ARCH32"
7714 "add\\t%1, %2, %0, %%tldo_add(%a3)")
7716 (define_insn "tldo_add64"
7717 [(set (match_operand:DI 0 "register_operand" "=r")
7718 (plus:DI (match_operand:DI 1 "register_operand" "r")
7719 (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7720 (match_operand 3 "tld_symbolic_operand" "")]
7722 "TARGET_TLS && TARGET_ARCH64"
7723 "add\\t%1, %2, %0, %%tldo_add(%a3)")
7725 (define_insn "tie_hi22"
7726 [(set (match_operand:SI 0 "register_operand" "=r")
7727 (high:SI (unspec:SI [(match_operand 1 "tie_symbolic_operand" "")]
7730 "sethi\\t%%tie_hi22(%a1), %0")
7732 (define_insn "tie_lo10"
7733 [(set (match_operand:SI 0 "register_operand" "=r")
7734 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7735 (unspec:SI [(match_operand 2 "tie_symbolic_operand" "")]
7738 "add\\t%1, %%tie_lo10(%a2), %0")
7740 (define_insn "tie_ld32"
7741 [(set (match_operand:SI 0 "register_operand" "=r")
7742 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
7743 (match_operand:SI 2 "register_operand" "r")
7744 (match_operand 3 "tie_symbolic_operand" "")]
7746 "TARGET_TLS && TARGET_ARCH32"
7747 "ld\\t[%1 + %2], %0, %%tie_ld(%a3)"
7748 [(set_attr "type" "load")])
7750 (define_insn "tie_ld64"
7751 [(set (match_operand:DI 0 "register_operand" "=r")
7752 (unspec:DI [(match_operand:DI 1 "register_operand" "r")
7753 (match_operand:SI 2 "register_operand" "r")
7754 (match_operand 3 "tie_symbolic_operand" "")]
7756 "TARGET_TLS && TARGET_ARCH64"
7757 "ldx\\t[%1 + %2], %0, %%tie_ldx(%a3)"
7758 [(set_attr "type" "load")])
7760 (define_insn "tie_add32"
7761 [(set (match_operand:SI 0 "register_operand" "=r")
7762 (plus:SI (match_operand:SI 1 "register_operand" "r")
7763 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7764 (match_operand 3 "tie_symbolic_operand" "")]
7766 "TARGET_SUN_TLS && TARGET_ARCH32"
7767 "add\\t%1, %2, %0, %%tie_add(%a3)")
7769 (define_insn "tie_add64"
7770 [(set (match_operand:DI 0 "register_operand" "=r")
7771 (plus:DI (match_operand:DI 1 "register_operand" "r")
7772 (unspec:DI [(match_operand:DI 2 "register_operand" "r")
7773 (match_operand 3 "tie_symbolic_operand" "")]
7775 "TARGET_SUN_TLS && TARGET_ARCH64"
7776 "add\\t%1, %2, %0, %%tie_add(%a3)")
7778 (define_insn "tle_hix22_sp32"
7779 [(set (match_operand:SI 0 "register_operand" "=r")
7780 (high:SI (unspec:SI [(match_operand 1 "tle_symbolic_operand" "")]
7782 "TARGET_TLS && TARGET_ARCH32"
7783 "sethi\\t%%tle_hix22(%a1), %0")
7785 (define_insn "tle_lox10_sp32"
7786 [(set (match_operand:SI 0 "register_operand" "=r")
7787 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7788 (unspec:SI [(match_operand 2 "tle_symbolic_operand" "")]
7790 "TARGET_TLS && TARGET_ARCH32"
7791 "xor\\t%1, %%tle_lox10(%a2), %0")
7793 (define_insn "tle_hix22_sp64"
7794 [(set (match_operand:DI 0 "register_operand" "=r")
7795 (high:DI (unspec:DI [(match_operand 1 "tle_symbolic_operand" "")]
7797 "TARGET_TLS && TARGET_ARCH64"
7798 "sethi\\t%%tle_hix22(%a1), %0")
7800 (define_insn "tle_lox10_sp64"
7801 [(set (match_operand:DI 0 "register_operand" "=r")
7802 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
7803 (unspec:DI [(match_operand 2 "tle_symbolic_operand" "")]
7805 "TARGET_TLS && TARGET_ARCH64"
7806 "xor\\t%1, %%tle_lox10(%a2), %0")
7808 ;; Now patterns combining tldo_add{32,64} with some integer loads or stores
7809 (define_insn "*tldo_ldub_sp32"
7810 [(set (match_operand:QI 0 "register_operand" "=r")
7811 (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7812 (match_operand 3 "tld_symbolic_operand" "")]
7814 (match_operand:SI 1 "register_operand" "r"))))]
7815 "TARGET_TLS && TARGET_ARCH32"
7816 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7817 [(set_attr "type" "load")
7818 (set_attr "us3load_type" "3cycle")])
7820 (define_insn "*tldo_ldub1_sp32"
7821 [(set (match_operand:HI 0 "register_operand" "=r")
7822 (zero_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7823 (match_operand 3 "tld_symbolic_operand" "")]
7825 (match_operand:SI 1 "register_operand" "r")))))]
7826 "TARGET_TLS && TARGET_ARCH32"
7827 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7828 [(set_attr "type" "load")
7829 (set_attr "us3load_type" "3cycle")])
7831 (define_insn "*tldo_ldub2_sp32"
7832 [(set (match_operand:SI 0 "register_operand" "=r")
7833 (zero_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7834 (match_operand 3 "tld_symbolic_operand" "")]
7836 (match_operand:SI 1 "register_operand" "r")))))]
7837 "TARGET_TLS && TARGET_ARCH32"
7838 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7839 [(set_attr "type" "load")
7840 (set_attr "us3load_type" "3cycle")])
7842 (define_insn "*tldo_ldsb1_sp32"
7843 [(set (match_operand:HI 0 "register_operand" "=r")
7844 (sign_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7845 (match_operand 3 "tld_symbolic_operand" "")]
7847 (match_operand:SI 1 "register_operand" "r")))))]
7848 "TARGET_TLS && TARGET_ARCH32"
7849 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7850 [(set_attr "type" "sload")
7851 (set_attr "us3load_type" "3cycle")])
7853 (define_insn "*tldo_ldsb2_sp32"
7854 [(set (match_operand:SI 0 "register_operand" "=r")
7855 (sign_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7856 (match_operand 3 "tld_symbolic_operand" "")]
7858 (match_operand:SI 1 "register_operand" "r")))))]
7859 "TARGET_TLS && TARGET_ARCH32"
7860 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7861 [(set_attr "type" "sload")
7862 (set_attr "us3load_type" "3cycle")])
7864 (define_insn "*tldo_ldub_sp64"
7865 [(set (match_operand:QI 0 "register_operand" "=r")
7866 (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7867 (match_operand 3 "tld_symbolic_operand" "")]
7869 (match_operand:DI 1 "register_operand" "r"))))]
7870 "TARGET_TLS && TARGET_ARCH64"
7871 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7872 [(set_attr "type" "load")
7873 (set_attr "us3load_type" "3cycle")])
7875 (define_insn "*tldo_ldub1_sp64"
7876 [(set (match_operand:HI 0 "register_operand" "=r")
7877 (zero_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7878 (match_operand 3 "tld_symbolic_operand" "")]
7880 (match_operand:DI 1 "register_operand" "r")))))]
7881 "TARGET_TLS && TARGET_ARCH64"
7882 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7883 [(set_attr "type" "load")
7884 (set_attr "us3load_type" "3cycle")])
7886 (define_insn "*tldo_ldub2_sp64"
7887 [(set (match_operand:SI 0 "register_operand" "=r")
7888 (zero_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7889 (match_operand 3 "tld_symbolic_operand" "")]
7891 (match_operand:DI 1 "register_operand" "r")))))]
7892 "TARGET_TLS && TARGET_ARCH64"
7893 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7894 [(set_attr "type" "load")
7895 (set_attr "us3load_type" "3cycle")])
7897 (define_insn "*tldo_ldub3_sp64"
7898 [(set (match_operand:DI 0 "register_operand" "=r")
7899 (zero_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7900 (match_operand 3 "tld_symbolic_operand" "")]
7902 (match_operand:DI 1 "register_operand" "r")))))]
7903 "TARGET_TLS && TARGET_ARCH64"
7904 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7905 [(set_attr "type" "load")
7906 (set_attr "us3load_type" "3cycle")])
7908 (define_insn "*tldo_ldsb1_sp64"
7909 [(set (match_operand:HI 0 "register_operand" "=r")
7910 (sign_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7911 (match_operand 3 "tld_symbolic_operand" "")]
7913 (match_operand:DI 1 "register_operand" "r")))))]
7914 "TARGET_TLS && TARGET_ARCH64"
7915 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7916 [(set_attr "type" "sload")
7917 (set_attr "us3load_type" "3cycle")])
7919 (define_insn "*tldo_ldsb2_sp64"
7920 [(set (match_operand:SI 0 "register_operand" "=r")
7921 (sign_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7922 (match_operand 3 "tld_symbolic_operand" "")]
7924 (match_operand:DI 1 "register_operand" "r")))))]
7925 "TARGET_TLS && TARGET_ARCH64"
7926 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7927 [(set_attr "type" "sload")
7928 (set_attr "us3load_type" "3cycle")])
7930 (define_insn "*tldo_ldsb3_sp64"
7931 [(set (match_operand:DI 0 "register_operand" "=r")
7932 (sign_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7933 (match_operand 3 "tld_symbolic_operand" "")]
7935 (match_operand:DI 1 "register_operand" "r")))))]
7936 "TARGET_TLS && TARGET_ARCH64"
7937 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7938 [(set_attr "type" "sload")
7939 (set_attr "us3load_type" "3cycle")])
7941 (define_insn "*tldo_lduh_sp32"
7942 [(set (match_operand:HI 0 "register_operand" "=r")
7943 (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7944 (match_operand 3 "tld_symbolic_operand" "")]
7946 (match_operand:SI 1 "register_operand" "r"))))]
7947 "TARGET_TLS && TARGET_ARCH32"
7948 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7949 [(set_attr "type" "load")
7950 (set_attr "us3load_type" "3cycle")])
7952 (define_insn "*tldo_lduh1_sp32"
7953 [(set (match_operand:SI 0 "register_operand" "=r")
7954 (zero_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7955 (match_operand 3 "tld_symbolic_operand" "")]
7957 (match_operand:SI 1 "register_operand" "r")))))]
7958 "TARGET_TLS && TARGET_ARCH32"
7959 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7960 [(set_attr "type" "load")
7961 (set_attr "us3load_type" "3cycle")])
7963 (define_insn "*tldo_ldsh1_sp32"
7964 [(set (match_operand:SI 0 "register_operand" "=r")
7965 (sign_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7966 (match_operand 3 "tld_symbolic_operand" "")]
7968 (match_operand:SI 1 "register_operand" "r")))))]
7969 "TARGET_TLS && TARGET_ARCH32"
7970 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
7971 [(set_attr "type" "sload")
7972 (set_attr "us3load_type" "3cycle")])
7974 (define_insn "*tldo_lduh_sp64"
7975 [(set (match_operand:HI 0 "register_operand" "=r")
7976 (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7977 (match_operand 3 "tld_symbolic_operand" "")]
7979 (match_operand:DI 1 "register_operand" "r"))))]
7980 "TARGET_TLS && TARGET_ARCH64"
7981 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7982 [(set_attr "type" "load")
7983 (set_attr "us3load_type" "3cycle")])
7985 (define_insn "*tldo_lduh1_sp64"
7986 [(set (match_operand:SI 0 "register_operand" "=r")
7987 (zero_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7988 (match_operand 3 "tld_symbolic_operand" "")]
7990 (match_operand:DI 1 "register_operand" "r")))))]
7991 "TARGET_TLS && TARGET_ARCH64"
7992 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7993 [(set_attr "type" "load")
7994 (set_attr "us3load_type" "3cycle")])
7996 (define_insn "*tldo_lduh2_sp64"
7997 [(set (match_operand:DI 0 "register_operand" "=r")
7998 (zero_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7999 (match_operand 3 "tld_symbolic_operand" "")]
8001 (match_operand:DI 1 "register_operand" "r")))))]
8002 "TARGET_TLS && TARGET_ARCH64"
8003 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
8004 [(set_attr "type" "load")
8005 (set_attr "us3load_type" "3cycle")])
8007 (define_insn "*tldo_ldsh1_sp64"
8008 [(set (match_operand:SI 0 "register_operand" "=r")
8009 (sign_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8010 (match_operand 3 "tld_symbolic_operand" "")]
8012 (match_operand:DI 1 "register_operand" "r")))))]
8013 "TARGET_TLS && TARGET_ARCH64"
8014 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
8015 [(set_attr "type" "sload")
8016 (set_attr "us3load_type" "3cycle")])
8018 (define_insn "*tldo_ldsh2_sp64"
8019 [(set (match_operand:DI 0 "register_operand" "=r")
8020 (sign_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8021 (match_operand 3 "tld_symbolic_operand" "")]
8023 (match_operand:DI 1 "register_operand" "r")))))]
8024 "TARGET_TLS && TARGET_ARCH64"
8025 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
8026 [(set_attr "type" "sload")
8027 (set_attr "us3load_type" "3cycle")])
8029 (define_insn "*tldo_lduw_sp32"
8030 [(set (match_operand:SI 0 "register_operand" "=r")
8031 (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8032 (match_operand 3 "tld_symbolic_operand" "")]
8034 (match_operand:SI 1 "register_operand" "r"))))]
8035 "TARGET_TLS && TARGET_ARCH32"
8036 "ld\t[%1 + %2], %0, %%tldo_add(%3)"
8037 [(set_attr "type" "load")])
8039 (define_insn "*tldo_lduw_sp64"
8040 [(set (match_operand:SI 0 "register_operand" "=r")
8041 (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8042 (match_operand 3 "tld_symbolic_operand" "")]
8044 (match_operand:DI 1 "register_operand" "r"))))]
8045 "TARGET_TLS && TARGET_ARCH64"
8046 "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
8047 [(set_attr "type" "load")])
8049 (define_insn "*tldo_lduw1_sp64"
8050 [(set (match_operand:DI 0 "register_operand" "=r")
8051 (zero_extend:DI (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8052 (match_operand 3 "tld_symbolic_operand" "")]
8054 (match_operand:DI 1 "register_operand" "r")))))]
8055 "TARGET_TLS && TARGET_ARCH64"
8056 "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
8057 [(set_attr "type" "load")])
8059 (define_insn "*tldo_ldsw1_sp64"
8060 [(set (match_operand:DI 0 "register_operand" "=r")
8061 (sign_extend:DI (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8062 (match_operand 3 "tld_symbolic_operand" "")]
8064 (match_operand:DI 1 "register_operand" "r")))))]
8065 "TARGET_TLS && TARGET_ARCH64"
8066 "ldsw\t[%1 + %2], %0, %%tldo_add(%3)"
8067 [(set_attr "type" "sload")
8068 (set_attr "us3load_type" "3cycle")])
8070 (define_insn "*tldo_ldx_sp64"
8071 [(set (match_operand:DI 0 "register_operand" "=r")
8072 (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8073 (match_operand 3 "tld_symbolic_operand" "")]
8075 (match_operand:DI 1 "register_operand" "r"))))]
8076 "TARGET_TLS && TARGET_ARCH64"
8077 "ldx\t[%1 + %2], %0, %%tldo_add(%3)"
8078 [(set_attr "type" "load")])
8080 (define_insn "*tldo_stb_sp32"
8081 [(set (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8082 (match_operand 3 "tld_symbolic_operand" "")]
8084 (match_operand:SI 1 "register_operand" "r")))
8085 (match_operand:QI 0 "register_operand" "=r"))]
8086 "TARGET_TLS && TARGET_ARCH32"
8087 "stb\t%0, [%1 + %2], %%tldo_add(%3)"
8088 [(set_attr "type" "store")])
8090 (define_insn "*tldo_stb_sp64"
8091 [(set (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8092 (match_operand 3 "tld_symbolic_operand" "")]
8094 (match_operand:DI 1 "register_operand" "r")))
8095 (match_operand:QI 0 "register_operand" "=r"))]
8096 "TARGET_TLS && TARGET_ARCH64"
8097 "stb\t%0, [%1 + %2], %%tldo_add(%3)"
8098 [(set_attr "type" "store")])
8100 (define_insn "*tldo_sth_sp32"
8101 [(set (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8102 (match_operand 3 "tld_symbolic_operand" "")]
8104 (match_operand:SI 1 "register_operand" "r")))
8105 (match_operand:HI 0 "register_operand" "=r"))]
8106 "TARGET_TLS && TARGET_ARCH32"
8107 "sth\t%0, [%1 + %2], %%tldo_add(%3)"
8108 [(set_attr "type" "store")])
8110 (define_insn "*tldo_sth_sp64"
8111 [(set (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8112 (match_operand 3 "tld_symbolic_operand" "")]
8114 (match_operand:DI 1 "register_operand" "r")))
8115 (match_operand:HI 0 "register_operand" "=r"))]
8116 "TARGET_TLS && TARGET_ARCH64"
8117 "sth\t%0, [%1 + %2], %%tldo_add(%3)"
8118 [(set_attr "type" "store")])
8120 (define_insn "*tldo_stw_sp32"
8121 [(set (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8122 (match_operand 3 "tld_symbolic_operand" "")]
8124 (match_operand:SI 1 "register_operand" "r")))
8125 (match_operand:SI 0 "register_operand" "=r"))]
8126 "TARGET_TLS && TARGET_ARCH32"
8127 "st\t%0, [%1 + %2], %%tldo_add(%3)"
8128 [(set_attr "type" "store")])
8130 (define_insn "*tldo_stw_sp64"
8131 [(set (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8132 (match_operand 3 "tld_symbolic_operand" "")]
8134 (match_operand:DI 1 "register_operand" "r")))
8135 (match_operand:SI 0 "register_operand" "=r"))]
8136 "TARGET_TLS && TARGET_ARCH64"
8137 "stw\t%0, [%1 + %2], %%tldo_add(%3)"
8138 [(set_attr "type" "store")])
8140 (define_insn "*tldo_stx_sp64"
8141 [(set (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8142 (match_operand 3 "tld_symbolic_operand" "")]
8144 (match_operand:DI 1 "register_operand" "r")))
8145 (match_operand:DI 0 "register_operand" "=r"))]
8146 "TARGET_TLS && TARGET_ARCH64"
8147 "stx\t%0, [%1 + %2], %%tldo_add(%3)"
8148 [(set_attr "type" "store")])
8151 ;; Stack protector instructions.
8153 (define_expand "stack_protect_set"
8154 [(match_operand 0 "memory_operand" "")
8155 (match_operand 1 "memory_operand" "")]
8158 #ifdef TARGET_THREAD_SSP_OFFSET
8159 rtx tlsreg = gen_rtx_REG (Pmode, 7);
8160 rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
8161 operands[1] = gen_rtx_MEM (Pmode, addr);
8164 emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
8166 emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
8170 (define_insn "stack_protect_setsi"
8171 [(set (match_operand:SI 0 "memory_operand" "=m")
8172 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
8173 (set (match_scratch:SI 2 "=&r") (const_int 0))]
8175 "ld\t%1, %2\;st\t%2, %0\;mov\t0, %2"
8176 [(set_attr "type" "multi")
8177 (set_attr "length" "3")])
8179 (define_insn "stack_protect_setdi"
8180 [(set (match_operand:DI 0 "memory_operand" "=m")
8181 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
8182 (set (match_scratch:DI 2 "=&r") (const_int 0))]
8184 "ldx\t%1, %2\;stx\t%2, %0\;mov\t0, %2"
8185 [(set_attr "type" "multi")
8186 (set_attr "length" "3")])
8188 (define_expand "stack_protect_test"
8189 [(match_operand 0 "memory_operand" "")
8190 (match_operand 1 "memory_operand" "")
8191 (match_operand 2 "" "")]
8194 #ifdef TARGET_THREAD_SSP_OFFSET
8195 rtx tlsreg = gen_rtx_REG (Pmode, 7);
8196 rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
8197 operands[1] = gen_rtx_MEM (Pmode, addr);
8201 rtx temp = gen_reg_rtx (Pmode);
8202 emit_insn (gen_stack_protect_testdi (temp, operands[0], operands[1]));
8203 sparc_compare_op0 = temp;
8204 sparc_compare_op1 = const0_rtx;
8208 emit_insn (gen_stack_protect_testsi (operands[0], operands[1]));
8209 sparc_compare_op0 = operands[0];
8210 sparc_compare_op1 = operands[1];
8211 sparc_compare_emitted = gen_rtx_REG (CCmode, SPARC_ICC_REG);
8213 emit_jump_insn (gen_beq (operands[2]));
8217 (define_insn "stack_protect_testsi"
8219 (unspec:CC [(match_operand:SI 0 "memory_operand" "m")
8220 (match_operand:SI 1 "memory_operand" "m")]
8222 (set (match_scratch:SI 3 "=r") (const_int 0))
8223 (clobber (match_scratch:SI 2 "=&r"))]
8225 "ld\t%0, %2\;ld\t%1, %3\;xorcc\t%2, %3, %2\;mov\t0, %3"
8226 [(set_attr "type" "multi")
8227 (set_attr "length" "4")])
8229 (define_insn "stack_protect_testdi"
8230 [(set (match_operand:DI 0 "register_operand" "=&r")
8231 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
8232 (match_operand:DI 2 "memory_operand" "m")]
8234 (set (match_scratch:DI 3 "=r") (const_int 0))]
8236 "ldx\t%1, %0\;ldx\t%2, %3\;xor\t%0, %3, %0\;mov\t0, %3"
8237 [(set_attr "type" "multi")
8238 (set_attr "length" "4")])
8241 ;; Vector instructions.
8243 (define_insn "addv2si3"
8244 [(set (match_operand:V2SI 0 "register_operand" "=e")
8245 (plus:V2SI (match_operand:V2SI 1 "register_operand" "e")
8246 (match_operand:V2SI 2 "register_operand" "e")))]
8248 "fpadd32\t%1, %2, %0"
8249 [(set_attr "type" "fga")
8250 (set_attr "fptype" "double")])
8252 (define_insn "addv4hi3"
8253 [(set (match_operand:V4HI 0 "register_operand" "=e")
8254 (plus:V4HI (match_operand:V4HI 1 "register_operand" "e")
8255 (match_operand:V4HI 2 "register_operand" "e")))]
8257 "fpadd16\t%1, %2, %0"
8258 [(set_attr "type" "fga")
8259 (set_attr "fptype" "double")])
8261 ;; fpadd32s is emitted by the addsi3 pattern.
8263 (define_insn "addv2hi3"
8264 [(set (match_operand:V2HI 0 "register_operand" "=f")
8265 (plus:V2HI (match_operand:V2HI 1 "register_operand" "f")
8266 (match_operand:V2HI 2 "register_operand" "f")))]
8268 "fpadd16s\t%1, %2, %0"
8269 [(set_attr "type" "fga")
8270 (set_attr "fptype" "single")])
8272 (define_insn "subv2si3"
8273 [(set (match_operand:V2SI 0 "register_operand" "=e")
8274 (minus:V2SI (match_operand:V2SI 1 "register_operand" "e")
8275 (match_operand:V2SI 2 "register_operand" "e")))]
8277 "fpsub32\t%1, %2, %0"
8278 [(set_attr "type" "fga")
8279 (set_attr "fptype" "double")])
8281 (define_insn "subv4hi3"
8282 [(set (match_operand:V4HI 0 "register_operand" "=e")
8283 (minus:V4HI (match_operand:V4HI 1 "register_operand" "e")
8284 (match_operand:V4HI 2 "register_operand" "e")))]
8286 "fpsub16\t%1, %2, %0"
8287 [(set_attr "type" "fga")
8288 (set_attr "fptype" "double")])
8290 ;; fpsub32s is emitted by the subsi3 pattern.
8292 (define_insn "subv2hi3"
8293 [(set (match_operand:V2HI 0 "register_operand" "=f")
8294 (minus:V2HI (match_operand:V2HI 1 "register_operand" "f")
8295 (match_operand:V2HI 2 "register_operand" "f")))]
8297 "fpsub16s\t%1, %2, %0"
8298 [(set_attr "type" "fga")
8299 (set_attr "fptype" "single")])
8301 ;; All other logical instructions have integer equivalents so they
8302 ;; are defined together.
8304 ;; (ior (not (op1)) (not (op2))) is the canonical form of NAND.
8306 (define_insn "*nand<V64mode>_vis"
8307 [(set (match_operand:V64 0 "register_operand" "=e")
8308 (ior:V64 (not:V64 (match_operand:V64 1 "register_operand" "e"))
8309 (not:V64 (match_operand:V64 2 "register_operand" "e"))))]
8312 [(set_attr "type" "fga")
8313 (set_attr "fptype" "double")])
8315 (define_insn "*nand<V32mode>_vis"
8316 [(set (match_operand:V32 0 "register_operand" "=f")
8317 (ior:V32 (not:V32 (match_operand:V32 1 "register_operand" "f"))
8318 (not:V32 (match_operand:V32 2 "register_operand" "f"))))]
8320 "fnands\t%1, %2, %0"
8321 [(set_attr "type" "fga")
8322 (set_attr "fptype" "single")])
8324 ;; Hard to generate VIS instructions. We have builtins for these.
8326 (define_insn "fpack16_vis"
8327 [(set (match_operand:V4QI 0 "register_operand" "=f")
8328 (unspec:V4QI [(match_operand:V4HI 1 "register_operand" "e")]
8332 [(set_attr "type" "fga")
8333 (set_attr "fptype" "double")])
8335 (define_insn "fpackfix_vis"
8336 [(set (match_operand:V2HI 0 "register_operand" "=f")
8337 (unspec:V2HI [(match_operand:V2SI 1 "register_operand" "e")]
8341 [(set_attr "type" "fga")
8342 (set_attr "fptype" "double")])
8344 (define_insn "fpack32_vis"
8345 [(set (match_operand:V8QI 0 "register_operand" "=e")
8346 (unspec:V8QI [(match_operand:V2SI 1 "register_operand" "e")
8347 (match_operand:V8QI 2 "register_operand" "e")]
8350 "fpack32\t%1, %2, %0"
8351 [(set_attr "type" "fga")
8352 (set_attr "fptype" "double")])
8354 (define_insn "fexpand_vis"
8355 [(set (match_operand:V4HI 0 "register_operand" "=e")
8356 (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")]
8360 [(set_attr "type" "fga")
8361 (set_attr "fptype" "double")])
8363 ;; It may be possible to describe this operation as (1 indexed):
8364 ;; (vec_select (vec_duplicate (vec_duplicate (vec_concat 1 2)))
8365 ;; 1,5,10,14,19,23,28,32)
8366 ;; Note that (vec_merge:V8QI [(V4QI) (V4QI)] (10101010 = 170) doesn't work
8367 ;; because vec_merge expects all the operands to be of the same type.
8368 (define_insn "fpmerge_vis"
8369 [(set (match_operand:V8QI 0 "register_operand" "=e")
8370 (unspec:V8QI [(match_operand:V4QI 1 "register_operand" "f")
8371 (match_operand:V4QI 2 "register_operand" "f")]
8374 "fpmerge\t%1, %2, %0"
8375 [(set_attr "type" "fga")
8376 (set_attr "fptype" "double")])
8378 ;; Partitioned multiply instructions
8379 (define_insn "fmul8x16_vis"
8380 [(set (match_operand:V4HI 0 "register_operand" "=e")
8381 (mult:V4HI (match_operand:V4QI 1 "register_operand" "f")
8382 (match_operand:V4HI 2 "register_operand" "e")))]
8384 "fmul8x16\t%1, %2, %0"
8385 [(set_attr "type" "fpmul")
8386 (set_attr "fptype" "double")])
8388 ;; Only one of the following two insns can be a multiply.
8389 (define_insn "fmul8x16au_vis"
8390 [(set (match_operand:V4HI 0 "register_operand" "=e")
8391 (mult:V4HI (match_operand:V4QI 1 "register_operand" "f")
8392 (match_operand:V2HI 2 "register_operand" "f")))]
8394 "fmul8x16au\t%1, %2, %0"
8395 [(set_attr "type" "fpmul")
8396 (set_attr "fptype" "double")])
8398 (define_insn "fmul8x16al_vis"
8399 [(set (match_operand:V4HI 0 "register_operand" "=e")
8400 (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")
8401 (match_operand:V2HI 2 "register_operand" "f")]
8404 "fmul8x16al\t%1, %2, %0"
8405 [(set_attr "type" "fpmul")
8406 (set_attr "fptype" "double")])
8408 ;; Only one of the following two insns can be a multiply.
8409 (define_insn "fmul8sux16_vis"
8410 [(set (match_operand:V4HI 0 "register_operand" "=e")
8411 (mult:V4HI (match_operand:V8QI 1 "register_operand" "e")
8412 (match_operand:V4HI 2 "register_operand" "e")))]
8414 "fmul8sux16\t%1, %2, %0"
8415 [(set_attr "type" "fpmul")
8416 (set_attr "fptype" "double")])
8418 (define_insn "fmul8ulx16_vis"
8419 [(set (match_operand:V4HI 0 "register_operand" "=e")
8420 (unspec:V4HI [(match_operand:V8QI 1 "register_operand" "e")
8421 (match_operand:V4HI 2 "register_operand" "e")]
8424 "fmul8ulx16\t%1, %2, %0"
8425 [(set_attr "type" "fpmul")
8426 (set_attr "fptype" "double")])
8428 ;; Only one of the following two insns can be a multiply.
8429 (define_insn "fmuld8sux16_vis"
8430 [(set (match_operand:V2SI 0 "register_operand" "=e")
8431 (mult:V2SI (match_operand:V4QI 1 "register_operand" "f")
8432 (match_operand:V2HI 2 "register_operand" "f")))]
8434 "fmuld8sux16\t%1, %2, %0"
8435 [(set_attr "type" "fpmul")
8436 (set_attr "fptype" "double")])
8438 (define_insn "fmuld8ulx16_vis"
8439 [(set (match_operand:V2SI 0 "register_operand" "=e")
8440 (unspec:V2SI [(match_operand:V4QI 1 "register_operand" "f")
8441 (match_operand:V2HI 2 "register_operand" "f")]
8444 "fmuld8ulx16\t%1, %2, %0"
8445 [(set_attr "type" "fpmul")
8446 (set_attr "fptype" "double")])
8448 ;; Using faligndata only makes sense after an alignaddr since the choice of
8449 ;; bytes to take out of each operand is dependent on the results of the last
8451 (define_insn "faligndata<V64I:mode>_vis"
8452 [(set (match_operand:V64I 0 "register_operand" "=e")
8453 (unspec:V64I [(match_operand:V64I 1 "register_operand" "e")
8454 (match_operand:V64I 2 "register_operand" "e")]
8457 "faligndata\t%1, %2, %0"
8458 [(set_attr "type" "fga")
8459 (set_attr "fptype" "double")])
8461 (define_insn "alignaddr<P:mode>_vis"
8462 [(set (match_operand:P 0 "register_operand" "=r")
8463 (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
8464 (match_operand:P 2 "register_or_zero_operand" "rJ")]
8467 "alignaddr\t%r1, %r2, %0")
8469 (define_insn "pdist_vis"
8470 [(set (match_operand:DI 0 "register_operand" "=e")
8471 (unspec:DI [(match_operand:V8QI 1 "register_operand" "e")
8472 (match_operand:V8QI 2 "register_operand" "e")
8473 (match_operand:DI 3 "register_operand" "0")]
8477 [(set_attr "type" "fga")
8478 (set_attr "fptype" "double")])