1 ;; Machine description for SPARC chip for GCC
2 ;; Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
3 ;; 1999, 2000, 2001, 2002, 2003, 2004, 2005,2006, 2007 Free Software Foundation, Inc.
4 ;; Contributed by Michael Tiemann (tiemann@cygnus.com)
5 ;; 64-bit SPARC-V9 support by Michael Tiemann, Jim Wilson, and Doug Evans,
8 ;; This file is part of GCC.
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 3, or (at your option)
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 ;; GNU General Public License for more details.
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING3. If not see
22 ;; <http://www.gnu.org/licenses/>.
24 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
28 (UNSPEC_UPDATE_RETURN 1)
29 (UNSPEC_LOAD_PCREL_SYM 2)
30 (UNSPEC_MOVE_PIC_LABEL 5)
36 (UNSPEC_EMB_TEXTUHI 13)
37 (UNSPEC_EMB_TEXTHI 14)
38 (UNSPEC_EMB_TEXTULO 15)
46 (UNSPEC_TLSLD_BASE 35)
77 ;; The upper 32 fp regs on the v9 can't hold SFmode values. To deal with this
78 ;; a second register class, EXTRA_FP_REGS, exists for the v9 chip. The name
79 ;; is a bit of a misnomer as it covers all 64 fp regs. The corresponding
80 ;; constraint letter is 'e'. To avoid any confusion, 'e' is used instead of
81 ;; 'f' for all DF/TFmode values, including those that are specific to the v8.
84 ;; Attribute for cpu type.
85 ;; These must match the values for enum processor_type in sparc.h.
92 hypersparc,sparclite86x,
99 (const (symbol_ref "sparc_cpu_attr")))
101 ;; Attribute for the instruction set.
102 ;; At present we only need to distinguish v9/!v9, but for clarity we
103 ;; test TARGET_V8 too.
104 (define_attr "isa" "v7,v8,v9,sparclet"
106 (cond [(symbol_ref "TARGET_V9") (const_string "v9")
107 (symbol_ref "TARGET_V8") (const_string "v8")
108 (symbol_ref "TARGET_SPARCLET") (const_string "sparclet")]
109 (const_string "v7"))))
115 uncond_branch,branch,call,sibcall,call_no_delay_slot,return,
123 fga,fgm_pack,fgm_mul,fgm_pdist,fgm_cmp,
126 multi,savew,flushw,iflush,trap"
127 (const_string "ialu"))
129 ;; True if branch/call has empty delay slot and will emit a nop in it
130 (define_attr "empty_delay_slot" "false,true"
131 (symbol_ref "empty_delay_slot (insn)"))
133 (define_attr "branch_type" "none,icc,fcc,reg"
134 (const_string "none"))
136 (define_attr "pic" "false,true"
137 (symbol_ref "flag_pic != 0"))
139 (define_attr "calls_alloca" "false,true"
140 (symbol_ref "cfun->calls_alloca != 0"))
142 (define_attr "calls_eh_return" "false,true"
143 (symbol_ref "crtl->calls_eh_return !=0 "))
145 (define_attr "leaf_function" "false,true"
146 (symbol_ref "current_function_uses_only_leaf_regs != 0"))
148 (define_attr "delayed_branch" "false,true"
149 (symbol_ref "flag_delayed_branch != 0"))
151 ;; Length (in # of insns).
152 ;; Beware that setting a length greater or equal to 3 for conditional branches
153 ;; has a side-effect (see output_cbranch and output_v9branch).
154 (define_attr "length" ""
155 (cond [(eq_attr "type" "uncond_branch,call")
156 (if_then_else (eq_attr "empty_delay_slot" "true")
159 (eq_attr "type" "sibcall")
160 (if_then_else (eq_attr "leaf_function" "true")
161 (if_then_else (eq_attr "empty_delay_slot" "true")
164 (if_then_else (eq_attr "empty_delay_slot" "true")
167 (eq_attr "branch_type" "icc")
168 (if_then_else (match_operand 0 "noov_compare64_operator" "")
169 (if_then_else (lt (pc) (match_dup 1))
170 (if_then_else (lt (minus (match_dup 1) (pc)) (const_int 260000))
171 (if_then_else (eq_attr "empty_delay_slot" "true")
174 (if_then_else (eq_attr "empty_delay_slot" "true")
177 (if_then_else (lt (minus (pc) (match_dup 1)) (const_int 260000))
178 (if_then_else (eq_attr "empty_delay_slot" "true")
181 (if_then_else (eq_attr "empty_delay_slot" "true")
184 (if_then_else (eq_attr "empty_delay_slot" "true")
187 (eq_attr "branch_type" "fcc")
188 (if_then_else (match_operand 0 "fcc0_register_operand" "")
189 (if_then_else (eq_attr "empty_delay_slot" "true")
190 (if_then_else (eq (symbol_ref "TARGET_V9") (const_int 0))
193 (if_then_else (eq (symbol_ref "TARGET_V9") (const_int 0))
196 (if_then_else (lt (pc) (match_dup 2))
197 (if_then_else (lt (minus (match_dup 2) (pc)) (const_int 260000))
198 (if_then_else (eq_attr "empty_delay_slot" "true")
201 (if_then_else (eq_attr "empty_delay_slot" "true")
204 (if_then_else (lt (minus (pc) (match_dup 2)) (const_int 260000))
205 (if_then_else (eq_attr "empty_delay_slot" "true")
208 (if_then_else (eq_attr "empty_delay_slot" "true")
211 (eq_attr "branch_type" "reg")
212 (if_then_else (lt (pc) (match_dup 2))
213 (if_then_else (lt (minus (match_dup 2) (pc)) (const_int 32000))
214 (if_then_else (eq_attr "empty_delay_slot" "true")
217 (if_then_else (eq_attr "empty_delay_slot" "true")
220 (if_then_else (lt (minus (pc) (match_dup 2)) (const_int 32000))
221 (if_then_else (eq_attr "empty_delay_slot" "true")
224 (if_then_else (eq_attr "empty_delay_slot" "true")
230 (define_attr "fptype" "single,double"
231 (const_string "single"))
233 ;; UltraSPARC-III integer load type.
234 (define_attr "us3load_type" "2cycle,3cycle"
235 (const_string "2cycle"))
237 (define_asm_attributes
238 [(set_attr "length" "2")
239 (set_attr "type" "multi")])
241 ;; Attributes for instruction and branch scheduling
242 (define_attr "tls_call_delay" "false,true"
243 (symbol_ref "tls_call_delay (insn)"))
245 (define_attr "in_call_delay" "false,true"
246 (cond [(eq_attr "type" "uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
247 (const_string "false")
248 (eq_attr "type" "load,fpload,store,fpstore")
249 (if_then_else (eq_attr "length" "1")
250 (const_string "true")
251 (const_string "false"))]
252 (if_then_else (and (eq_attr "length" "1")
253 (eq_attr "tls_call_delay" "true"))
254 (const_string "true")
255 (const_string "false"))))
257 (define_attr "eligible_for_sibcall_delay" "false,true"
258 (symbol_ref "eligible_for_sibcall_delay (insn)"))
260 (define_attr "eligible_for_return_delay" "false,true"
261 (symbol_ref "eligible_for_return_delay (insn)"))
263 ;; ??? !v9: Should implement the notion of predelay slots for floating-point
264 ;; branches. This would allow us to remove the nop always inserted before
265 ;; a floating point branch.
267 ;; ??? It is OK for fill_simple_delay_slots to put load/store instructions
268 ;; in a delay slot, but it is not OK for fill_eager_delay_slots to do so.
269 ;; This is because doing so will add several pipeline stalls to the path
270 ;; that the load/store did not come from. Unfortunately, there is no way
271 ;; to prevent fill_eager_delay_slots from using load/store without completely
272 ;; disabling them. For the SPEC benchmark set, this is a serious lose,
273 ;; because it prevents us from moving back the final store of inner loops.
275 (define_attr "in_branch_delay" "false,true"
276 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
277 (eq_attr "length" "1"))
278 (const_string "true")
279 (const_string "false")))
281 (define_attr "in_uncond_branch_delay" "false,true"
282 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
283 (eq_attr "length" "1"))
284 (const_string "true")
285 (const_string "false")))
287 (define_attr "in_annul_branch_delay" "false,true"
288 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
289 (eq_attr "length" "1"))
290 (const_string "true")
291 (const_string "false")))
293 (define_delay (eq_attr "type" "call")
294 [(eq_attr "in_call_delay" "true") (nil) (nil)])
296 (define_delay (eq_attr "type" "sibcall")
297 [(eq_attr "eligible_for_sibcall_delay" "true") (nil) (nil)])
299 (define_delay (eq_attr "type" "branch")
300 [(eq_attr "in_branch_delay" "true")
301 (nil) (eq_attr "in_annul_branch_delay" "true")])
303 (define_delay (eq_attr "type" "uncond_branch")
304 [(eq_attr "in_uncond_branch_delay" "true")
307 (define_delay (eq_attr "type" "return")
308 [(eq_attr "eligible_for_return_delay" "true") (nil) (nil)])
311 ;; Include SPARC DFA schedulers
313 (include "cypress.md")
314 (include "supersparc.md")
315 (include "hypersparc.md")
316 (include "sparclet.md")
317 (include "ultra1_2.md")
318 (include "ultra3.md")
319 (include "niagara.md")
320 (include "niagara2.md")
323 ;; Operand and operator predicates and constraints
325 (include "predicates.md")
326 (include "constraints.md")
329 ;; Compare instructions.
331 ;; We generate RTL for comparisons and branches by having the cmpxx
332 ;; patterns store away the operands. Then, the scc and bcc patterns
333 ;; emit RTL for both the compare and the branch.
335 ;; We do this because we want to generate different code for an sne and
336 ;; seq insn. In those cases, if the second operand of the compare is not
337 ;; const0_rtx, we want to compute the xor of the two operands and test
340 ;; We start with the DEFINE_EXPANDs, then the DEFINE_INSNs to match
341 ;; the patterns. Finally, we have the DEFINE_SPLITs for some of the scc
342 ;; insns that actually require more than one machine instruction.
344 (define_expand "cmpsi"
346 (compare:CC (match_operand:SI 0 "compare_operand" "")
347 (match_operand:SI 1 "arith_operand" "")))]
350 if (GET_CODE (operands[0]) == ZERO_EXTRACT && operands[1] != const0_rtx)
351 operands[0] = force_reg (SImode, operands[0]);
353 sparc_compare_op0 = operands[0];
354 sparc_compare_op1 = operands[1];
358 (define_expand "cmpdi"
360 (compare:CCX (match_operand:DI 0 "compare_operand" "")
361 (match_operand:DI 1 "arith_operand" "")))]
364 if (GET_CODE (operands[0]) == ZERO_EXTRACT && operands[1] != const0_rtx)
365 operands[0] = force_reg (DImode, operands[0]);
367 sparc_compare_op0 = operands[0];
368 sparc_compare_op1 = operands[1];
372 (define_expand "cmpsf"
373 ;; The 96 here isn't ever used by anyone.
375 (compare:CCFP (match_operand:SF 0 "register_operand" "")
376 (match_operand:SF 1 "register_operand" "")))]
379 sparc_compare_op0 = operands[0];
380 sparc_compare_op1 = operands[1];
384 (define_expand "cmpdf"
385 ;; The 96 here isn't ever used by anyone.
387 (compare:CCFP (match_operand:DF 0 "register_operand" "")
388 (match_operand:DF 1 "register_operand" "")))]
391 sparc_compare_op0 = operands[0];
392 sparc_compare_op1 = operands[1];
396 (define_expand "cmptf"
397 ;; The 96 here isn't ever used by anyone.
399 (compare:CCFP (match_operand:TF 0 "register_operand" "")
400 (match_operand:TF 1 "register_operand" "")))]
403 sparc_compare_op0 = operands[0];
404 sparc_compare_op1 = operands[1];
408 ;; Now the compare DEFINE_INSNs.
410 (define_insn "*cmpsi_insn"
412 (compare:CC (match_operand:SI 0 "register_operand" "r")
413 (match_operand:SI 1 "arith_operand" "rI")))]
416 [(set_attr "type" "compare")])
418 (define_insn "*cmpdi_sp64"
420 (compare:CCX (match_operand:DI 0 "register_operand" "r")
421 (match_operand:DI 1 "arith_operand" "rI")))]
424 [(set_attr "type" "compare")])
426 (define_insn "*cmpsf_fpe"
427 [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
428 (compare:CCFPE (match_operand:SF 1 "register_operand" "f")
429 (match_operand:SF 2 "register_operand" "f")))]
433 return "fcmpes\t%0, %1, %2";
434 return "fcmpes\t%1, %2";
436 [(set_attr "type" "fpcmp")])
438 (define_insn "*cmpdf_fpe"
439 [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
440 (compare:CCFPE (match_operand:DF 1 "register_operand" "e")
441 (match_operand:DF 2 "register_operand" "e")))]
445 return "fcmped\t%0, %1, %2";
446 return "fcmped\t%1, %2";
448 [(set_attr "type" "fpcmp")
449 (set_attr "fptype" "double")])
451 (define_insn "*cmptf_fpe"
452 [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
453 (compare:CCFPE (match_operand:TF 1 "register_operand" "e")
454 (match_operand:TF 2 "register_operand" "e")))]
455 "TARGET_FPU && TARGET_HARD_QUAD"
458 return "fcmpeq\t%0, %1, %2";
459 return "fcmpeq\t%1, %2";
461 [(set_attr "type" "fpcmp")])
463 (define_insn "*cmpsf_fp"
464 [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
465 (compare:CCFP (match_operand:SF 1 "register_operand" "f")
466 (match_operand:SF 2 "register_operand" "f")))]
470 return "fcmps\t%0, %1, %2";
471 return "fcmps\t%1, %2";
473 [(set_attr "type" "fpcmp")])
475 (define_insn "*cmpdf_fp"
476 [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
477 (compare:CCFP (match_operand:DF 1 "register_operand" "e")
478 (match_operand:DF 2 "register_operand" "e")))]
482 return "fcmpd\t%0, %1, %2";
483 return "fcmpd\t%1, %2";
485 [(set_attr "type" "fpcmp")
486 (set_attr "fptype" "double")])
488 (define_insn "*cmptf_fp"
489 [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
490 (compare:CCFP (match_operand:TF 1 "register_operand" "e")
491 (match_operand:TF 2 "register_operand" "e")))]
492 "TARGET_FPU && TARGET_HARD_QUAD"
495 return "fcmpq\t%0, %1, %2";
496 return "fcmpq\t%1, %2";
498 [(set_attr "type" "fpcmp")])
500 ;; Next come the scc insns. For seq, sne, sgeu, and sltu, we can do this
501 ;; without jumps using the addx/subx instructions. For seq/sne on v9 we use
502 ;; the same code as v8 (the addx/subx method has more applications). The
503 ;; exception to this is "reg != 0" which can be done in one instruction on v9
504 ;; (so we do it). For the rest, on v9 we use conditional moves; on v8, we do
507 ;; Seq_special[_xxx] and sne_special[_xxx] clobber the CC reg, because they
508 ;; generate addcc/subcc instructions.
510 (define_expand "seqsi_special"
512 (xor:SI (match_operand:SI 1 "register_operand" "")
513 (match_operand:SI 2 "register_operand" "")))
514 (parallel [(set (match_operand:SI 0 "register_operand" "")
515 (eq:SI (match_dup 3) (const_int 0)))
516 (clobber (reg:CC 100))])]
518 { operands[3] = gen_reg_rtx (SImode); })
520 (define_expand "seqdi_special"
522 (xor:DI (match_operand:DI 1 "register_operand" "")
523 (match_operand:DI 2 "register_operand" "")))
524 (set (match_operand:DI 0 "register_operand" "")
525 (eq:DI (match_dup 3) (const_int 0)))]
527 { operands[3] = gen_reg_rtx (DImode); })
529 (define_expand "snesi_special"
531 (xor:SI (match_operand:SI 1 "register_operand" "")
532 (match_operand:SI 2 "register_operand" "")))
533 (parallel [(set (match_operand:SI 0 "register_operand" "")
534 (ne:SI (match_dup 3) (const_int 0)))
535 (clobber (reg:CC 100))])]
537 { operands[3] = gen_reg_rtx (SImode); })
539 (define_expand "snedi_special"
541 (xor:DI (match_operand:DI 1 "register_operand" "")
542 (match_operand:DI 2 "register_operand" "")))
543 (set (match_operand:DI 0 "register_operand" "")
544 (ne:DI (match_dup 3) (const_int 0)))]
546 { operands[3] = gen_reg_rtx (DImode); })
548 (define_expand "seqdi_special_trunc"
550 (xor:DI (match_operand:DI 1 "register_operand" "")
551 (match_operand:DI 2 "register_operand" "")))
552 (set (match_operand:SI 0 "register_operand" "")
553 (eq:SI (match_dup 3) (const_int 0)))]
555 { operands[3] = gen_reg_rtx (DImode); })
557 (define_expand "snedi_special_trunc"
559 (xor:DI (match_operand:DI 1 "register_operand" "")
560 (match_operand:DI 2 "register_operand" "")))
561 (set (match_operand:SI 0 "register_operand" "")
562 (ne:SI (match_dup 3) (const_int 0)))]
564 { operands[3] = gen_reg_rtx (DImode); })
566 (define_expand "seqsi_special_extend"
568 (xor:SI (match_operand:SI 1 "register_operand" "")
569 (match_operand:SI 2 "register_operand" "")))
570 (parallel [(set (match_operand:DI 0 "register_operand" "")
571 (eq:DI (match_dup 3) (const_int 0)))
572 (clobber (reg:CC 100))])]
574 { operands[3] = gen_reg_rtx (SImode); })
576 (define_expand "snesi_special_extend"
578 (xor:SI (match_operand:SI 1 "register_operand" "")
579 (match_operand:SI 2 "register_operand" "")))
580 (parallel [(set (match_operand:DI 0 "register_operand" "")
581 (ne:DI (match_dup 3) (const_int 0)))
582 (clobber (reg:CC 100))])]
584 { operands[3] = gen_reg_rtx (SImode); })
586 ;; ??? v9: Operand 0 needs a mode, so SImode was chosen.
587 ;; However, the code handles both SImode and DImode.
589 [(set (match_operand:SI 0 "int_register_operand" "")
590 (eq:SI (match_dup 1) (const_int 0)))]
593 if (GET_MODE (sparc_compare_op0) == SImode)
597 if (GET_MODE (operands[0]) == SImode)
598 pat = gen_seqsi_special (operands[0], sparc_compare_op0,
600 else if (! TARGET_ARCH64)
603 pat = gen_seqsi_special_extend (operands[0], sparc_compare_op0,
608 else if (GET_MODE (sparc_compare_op0) == DImode)
614 else if (GET_MODE (operands[0]) == SImode)
615 pat = gen_seqdi_special_trunc (operands[0], sparc_compare_op0,
618 pat = gen_seqdi_special (operands[0], sparc_compare_op0,
623 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
626 = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, EQ);
627 gcc_assert (code == NE);
628 emit_insn (gen_sne (operands[0]));
633 if (gen_v9_scc (EQ, operands))
640 ;; ??? v9: Operand 0 needs a mode, so SImode was chosen.
641 ;; However, the code handles both SImode and DImode.
643 [(set (match_operand:SI 0 "int_register_operand" "")
644 (ne:SI (match_dup 1) (const_int 0)))]
647 if (GET_MODE (sparc_compare_op0) == SImode)
651 if (GET_MODE (operands[0]) == SImode)
652 pat = gen_snesi_special (operands[0], sparc_compare_op0,
654 else if (! TARGET_ARCH64)
657 pat = gen_snesi_special_extend (operands[0], sparc_compare_op0,
662 else if (GET_MODE (sparc_compare_op0) == DImode)
668 else if (GET_MODE (operands[0]) == SImode)
669 pat = gen_snedi_special_trunc (operands[0], sparc_compare_op0,
672 pat = gen_snedi_special (operands[0], sparc_compare_op0,
677 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
680 = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, NE);
681 gcc_assert (code == NE);
682 emit_insn (gen_sne (operands[0]));
687 if (gen_v9_scc (NE, operands))
695 [(set (match_operand:SI 0 "int_register_operand" "")
696 (gt:SI (match_dup 1) (const_int 0)))]
699 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
702 = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GT);
703 gcc_assert (code == NE);
704 emit_insn (gen_sne (operands[0]));
709 if (gen_v9_scc (GT, operands))
717 [(set (match_operand:SI 0 "int_register_operand" "")
718 (lt:SI (match_dup 1) (const_int 0)))]
721 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
724 = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LT);
725 gcc_assert (code == NE);
726 emit_insn (gen_sne (operands[0]));
731 if (gen_v9_scc (LT, operands))
739 [(set (match_operand:SI 0 "int_register_operand" "")
740 (ge:SI (match_dup 1) (const_int 0)))]
743 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
746 = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GE);
747 gcc_assert (code == NE);
748 emit_insn (gen_sne (operands[0]));
753 if (gen_v9_scc (GE, operands))
761 [(set (match_operand:SI 0 "int_register_operand" "")
762 (le:SI (match_dup 1) (const_int 0)))]
765 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
768 = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LE);
769 gcc_assert (code == NE);
770 emit_insn (gen_sne (operands[0]));
775 if (gen_v9_scc (LE, operands))
782 (define_expand "sgtu"
783 [(set (match_operand:SI 0 "int_register_operand" "")
784 (gtu:SI (match_dup 1) (const_int 0)))]
791 /* We can do ltu easily, so if both operands are registers, swap them and
793 if ((GET_CODE (sparc_compare_op0) == REG
794 || GET_CODE (sparc_compare_op0) == SUBREG)
795 && (GET_CODE (sparc_compare_op1) == REG
796 || GET_CODE (sparc_compare_op1) == SUBREG))
798 tem = sparc_compare_op0;
799 sparc_compare_op0 = sparc_compare_op1;
800 sparc_compare_op1 = tem;
801 pat = gen_sltu (operands[0]);
810 if (gen_v9_scc (GTU, operands))
816 (define_expand "sltu"
817 [(set (match_operand:SI 0 "int_register_operand" "")
818 (ltu:SI (match_dup 1) (const_int 0)))]
823 if (gen_v9_scc (LTU, operands))
826 operands[1] = gen_compare_reg (LTU);
829 (define_expand "sgeu"
830 [(set (match_operand:SI 0 "int_register_operand" "")
831 (geu:SI (match_dup 1) (const_int 0)))]
836 if (gen_v9_scc (GEU, operands))
839 operands[1] = gen_compare_reg (GEU);
842 (define_expand "sleu"
843 [(set (match_operand:SI 0 "int_register_operand" "")
844 (leu:SI (match_dup 1) (const_int 0)))]
851 /* We can do geu easily, so if both operands are registers, swap them and
853 if ((GET_CODE (sparc_compare_op0) == REG
854 || GET_CODE (sparc_compare_op0) == SUBREG)
855 && (GET_CODE (sparc_compare_op1) == REG
856 || GET_CODE (sparc_compare_op1) == SUBREG))
858 tem = sparc_compare_op0;
859 sparc_compare_op0 = sparc_compare_op1;
860 sparc_compare_op1 = tem;
861 pat = gen_sgeu (operands[0]);
870 if (gen_v9_scc (LEU, operands))
876 ;; Now the DEFINE_INSNs for the scc cases.
878 ;; The SEQ and SNE patterns are special because they can be done
879 ;; without any branching and do not involve a COMPARE. We want
880 ;; them to always use the splits below so the results can be
883 (define_insn_and_split "*snesi_zero"
884 [(set (match_operand:SI 0 "register_operand" "=r")
885 (ne:SI (match_operand:SI 1 "register_operand" "r")
887 (clobber (reg:CC 100))]
891 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
893 (set (match_dup 0) (ltu:SI (reg:CC 100) (const_int 0)))]
895 [(set_attr "length" "2")])
897 (define_insn_and_split "*neg_snesi_zero"
898 [(set (match_operand:SI 0 "register_operand" "=r")
899 (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
901 (clobber (reg:CC 100))]
905 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
907 (set (match_dup 0) (neg:SI (ltu:SI (reg:CC 100) (const_int 0))))]
909 [(set_attr "length" "2")])
911 (define_insn_and_split "*snesi_zero_extend"
912 [(set (match_operand:DI 0 "register_operand" "=r")
913 (ne:DI (match_operand:SI 1 "register_operand" "r")
915 (clobber (reg:CC 100))]
919 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (minus:SI (const_int 0)
922 (set (match_dup 0) (zero_extend:DI (plus:SI (plus:SI (const_int 0)
924 (ltu:SI (reg:CC_NOOV 100)
927 [(set_attr "length" "2")])
929 (define_insn_and_split "*snedi_zero"
930 [(set (match_operand:DI 0 "register_operand" "=&r")
931 (ne:DI (match_operand:DI 1 "register_operand" "r")
935 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
936 [(set (match_dup 0) (const_int 0))
937 (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
942 [(set_attr "length" "2")])
944 (define_insn_and_split "*neg_snedi_zero"
945 [(set (match_operand:DI 0 "register_operand" "=&r")
946 (neg:DI (ne:DI (match_operand:DI 1 "register_operand" "r")
950 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
951 [(set (match_dup 0) (const_int 0))
952 (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
957 [(set_attr "length" "2")])
959 (define_insn_and_split "*snedi_zero_trunc"
960 [(set (match_operand:SI 0 "register_operand" "=&r")
961 (ne:SI (match_operand:DI 1 "register_operand" "r")
965 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
966 [(set (match_dup 0) (const_int 0))
967 (set (match_dup 0) (if_then_else:SI (ne:DI (match_dup 1)
972 [(set_attr "length" "2")])
974 (define_insn_and_split "*seqsi_zero"
975 [(set (match_operand:SI 0 "register_operand" "=r")
976 (eq:SI (match_operand:SI 1 "register_operand" "r")
978 (clobber (reg:CC 100))]
982 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
984 (set (match_dup 0) (geu:SI (reg:CC 100) (const_int 0)))]
986 [(set_attr "length" "2")])
988 (define_insn_and_split "*neg_seqsi_zero"
989 [(set (match_operand:SI 0 "register_operand" "=r")
990 (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
992 (clobber (reg:CC 100))]
996 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
998 (set (match_dup 0) (neg:SI (geu:SI (reg:CC 100) (const_int 0))))]
1000 [(set_attr "length" "2")])
1002 (define_insn_and_split "*seqsi_zero_extend"
1003 [(set (match_operand:DI 0 "register_operand" "=r")
1004 (eq:DI (match_operand:SI 1 "register_operand" "r")
1006 (clobber (reg:CC 100))]
1010 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (minus:SI (const_int 0)
1013 (set (match_dup 0) (zero_extend:DI (minus:SI (minus:SI (const_int 0)
1015 (ltu:SI (reg:CC_NOOV 100)
1018 [(set_attr "length" "2")])
1020 (define_insn_and_split "*seqdi_zero"
1021 [(set (match_operand:DI 0 "register_operand" "=&r")
1022 (eq:DI (match_operand:DI 1 "register_operand" "r")
1026 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
1027 [(set (match_dup 0) (const_int 0))
1028 (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
1033 [(set_attr "length" "2")])
1035 (define_insn_and_split "*neg_seqdi_zero"
1036 [(set (match_operand:DI 0 "register_operand" "=&r")
1037 (neg:DI (eq:DI (match_operand:DI 1 "register_operand" "r")
1041 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
1042 [(set (match_dup 0) (const_int 0))
1043 (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
1048 [(set_attr "length" "2")])
1050 (define_insn_and_split "*seqdi_zero_trunc"
1051 [(set (match_operand:SI 0 "register_operand" "=&r")
1052 (eq:SI (match_operand:DI 1 "register_operand" "r")
1056 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
1057 [(set (match_dup 0) (const_int 0))
1058 (set (match_dup 0) (if_then_else:SI (eq:DI (match_dup 1)
1063 [(set_attr "length" "2")])
1065 ;; We can also do (x + (i == 0)) and related, so put them in.
1066 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1069 (define_insn_and_split "*x_plus_i_ne_0"
1070 [(set (match_operand:SI 0 "register_operand" "=r")
1071 (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
1073 (match_operand:SI 2 "register_operand" "r")))
1074 (clobber (reg:CC 100))]
1078 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1080 (set (match_dup 0) (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1083 [(set_attr "length" "2")])
1085 (define_insn_and_split "*x_minus_i_ne_0"
1086 [(set (match_operand:SI 0 "register_operand" "=r")
1087 (minus:SI (match_operand:SI 2 "register_operand" "r")
1088 (ne:SI (match_operand:SI 1 "register_operand" "r")
1090 (clobber (reg:CC 100))]
1094 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1096 (set (match_dup 0) (minus:SI (match_dup 2)
1097 (ltu:SI (reg:CC 100) (const_int 0))))]
1099 [(set_attr "length" "2")])
1101 (define_insn_and_split "*x_plus_i_eq_0"
1102 [(set (match_operand:SI 0 "register_operand" "=r")
1103 (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
1105 (match_operand:SI 2 "register_operand" "r")))
1106 (clobber (reg:CC 100))]
1110 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1112 (set (match_dup 0) (plus:SI (geu:SI (reg:CC 100) (const_int 0))
1115 [(set_attr "length" "2")])
1117 (define_insn_and_split "*x_minus_i_eq_0"
1118 [(set (match_operand:SI 0 "register_operand" "=r")
1119 (minus:SI (match_operand:SI 2 "register_operand" "r")
1120 (eq:SI (match_operand:SI 1 "register_operand" "r")
1122 (clobber (reg:CC 100))]
1126 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1128 (set (match_dup 0) (minus:SI (match_dup 2)
1129 (geu:SI (reg:CC 100) (const_int 0))))]
1131 [(set_attr "length" "2")])
1133 ;; We can also do GEU and LTU directly, but these operate after a compare.
1134 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1137 (define_insn "*sltu_insn"
1138 [(set (match_operand:SI 0 "register_operand" "=r")
1139 (ltu:SI (reg:CC 100) (const_int 0)))]
1142 [(set_attr "type" "ialuX")])
1144 (define_insn "*neg_sltu_insn"
1145 [(set (match_operand:SI 0 "register_operand" "=r")
1146 (neg:SI (ltu:SI (reg:CC 100) (const_int 0))))]
1149 [(set_attr "type" "ialuX")])
1151 ;; ??? Combine should canonicalize these next two to the same pattern.
1152 (define_insn "*neg_sltu_minus_x"
1153 [(set (match_operand:SI 0 "register_operand" "=r")
1154 (minus:SI (neg:SI (ltu:SI (reg:CC 100) (const_int 0)))
1155 (match_operand:SI 1 "arith_operand" "rI")))]
1157 "subx\t%%g0, %1, %0"
1158 [(set_attr "type" "ialuX")])
1160 (define_insn "*neg_sltu_plus_x"
1161 [(set (match_operand:SI 0 "register_operand" "=r")
1162 (neg:SI (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1163 (match_operand:SI 1 "arith_operand" "rI"))))]
1165 "subx\t%%g0, %1, %0"
1166 [(set_attr "type" "ialuX")])
1168 (define_insn "*sgeu_insn"
1169 [(set (match_operand:SI 0 "register_operand" "=r")
1170 (geu:SI (reg:CC 100) (const_int 0)))]
1172 "subx\t%%g0, -1, %0"
1173 [(set_attr "type" "ialuX")])
1175 (define_insn "*neg_sgeu_insn"
1176 [(set (match_operand:SI 0 "register_operand" "=r")
1177 (neg:SI (geu:SI (reg:CC 100) (const_int 0))))]
1179 "addx\t%%g0, -1, %0"
1180 [(set_attr "type" "ialuX")])
1182 ;; We can also do (x + ((unsigned) i >= 0)) and related, so put them in.
1183 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1186 (define_insn "*sltu_plus_x"
1187 [(set (match_operand:SI 0 "register_operand" "=r")
1188 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1189 (match_operand:SI 1 "arith_operand" "rI")))]
1191 "addx\t%%g0, %1, %0"
1192 [(set_attr "type" "ialuX")])
1194 (define_insn "*sltu_plus_x_plus_y"
1195 [(set (match_operand:SI 0 "register_operand" "=r")
1196 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1197 (plus:SI (match_operand:SI 1 "arith_operand" "%r")
1198 (match_operand:SI 2 "arith_operand" "rI"))))]
1201 [(set_attr "type" "ialuX")])
1203 (define_insn "*x_minus_sltu"
1204 [(set (match_operand:SI 0 "register_operand" "=r")
1205 (minus:SI (match_operand:SI 1 "register_operand" "r")
1206 (ltu:SI (reg:CC 100) (const_int 0))))]
1209 [(set_attr "type" "ialuX")])
1211 ;; ??? Combine should canonicalize these next two to the same pattern.
1212 (define_insn "*x_minus_y_minus_sltu"
1213 [(set (match_operand:SI 0 "register_operand" "=r")
1214 (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
1215 (match_operand:SI 2 "arith_operand" "rI"))
1216 (ltu:SI (reg:CC 100) (const_int 0))))]
1219 [(set_attr "type" "ialuX")])
1221 (define_insn "*x_minus_sltu_plus_y"
1222 [(set (match_operand:SI 0 "register_operand" "=r")
1223 (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
1224 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1225 (match_operand:SI 2 "arith_operand" "rI"))))]
1228 [(set_attr "type" "ialuX")])
1230 (define_insn "*sgeu_plus_x"
1231 [(set (match_operand:SI 0 "register_operand" "=r")
1232 (plus:SI (geu:SI (reg:CC 100) (const_int 0))
1233 (match_operand:SI 1 "register_operand" "r")))]
1236 [(set_attr "type" "ialuX")])
1238 (define_insn "*x_minus_sgeu"
1239 [(set (match_operand:SI 0 "register_operand" "=r")
1240 (minus:SI (match_operand:SI 1 "register_operand" "r")
1241 (geu:SI (reg:CC 100) (const_int 0))))]
1244 [(set_attr "type" "ialuX")])
1247 [(set (match_operand:SI 0 "register_operand" "")
1248 (match_operator:SI 2 "noov_compare_operator"
1249 [(match_operand 1 "icc_or_fcc_register_operand" "")
1252 && REGNO (operands[1]) == SPARC_ICC_REG
1253 && (GET_MODE (operands[1]) == CCXmode
1254 /* 32-bit LTU/GEU are better implemented using addx/subx. */
1255 || (GET_CODE (operands[2]) != LTU && GET_CODE (operands[2]) != GEU))"
1256 [(set (match_dup 0) (const_int 0))
1258 (if_then_else:SI (match_op_dup:SI 2 [(match_dup 1) (const_int 0)])
1264 ;; These control RTL generation for conditional jump insns
1266 ;; The quad-word fp compare library routines all return nonzero to indicate
1267 ;; true, which is different from the equivalent libgcc routines, so we must
1268 ;; handle them specially here.
1270 (define_expand "beq"
1272 (if_then_else (eq (match_dup 1) (const_int 0))
1273 (label_ref (match_operand 0 "" ""))
1277 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1278 && GET_CODE (sparc_compare_op0) == REG
1279 && GET_MODE (sparc_compare_op0) == DImode)
1281 emit_v9_brxx_insn (EQ, sparc_compare_op0, operands[0]);
1284 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1287 = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, EQ);
1288 gcc_assert (code == NE);
1289 emit_jump_insn (gen_bne (operands[0]));
1292 operands[1] = gen_compare_reg (EQ);
1295 (define_expand "bne"
1297 (if_then_else (ne (match_dup 1) (const_int 0))
1298 (label_ref (match_operand 0 "" ""))
1302 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1303 && GET_CODE (sparc_compare_op0) == REG
1304 && GET_MODE (sparc_compare_op0) == DImode)
1306 emit_v9_brxx_insn (NE, sparc_compare_op0, operands[0]);
1309 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1312 = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, NE);
1313 gcc_assert (code == NE);
1314 emit_jump_insn (gen_bne (operands[0]));
1317 operands[1] = gen_compare_reg (NE);
1320 (define_expand "bgt"
1322 (if_then_else (gt (match_dup 1) (const_int 0))
1323 (label_ref (match_operand 0 "" ""))
1327 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1328 && GET_CODE (sparc_compare_op0) == REG
1329 && GET_MODE (sparc_compare_op0) == DImode)
1331 emit_v9_brxx_insn (GT, sparc_compare_op0, operands[0]);
1334 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1337 = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GT);
1338 gcc_assert (code == NE);
1339 emit_jump_insn (gen_bne (operands[0]));
1342 operands[1] = gen_compare_reg (GT);
1345 (define_expand "bgtu"
1347 (if_then_else (gtu (match_dup 1) (const_int 0))
1348 (label_ref (match_operand 0 "" ""))
1352 operands[1] = gen_compare_reg (GTU);
1355 (define_expand "blt"
1357 (if_then_else (lt (match_dup 1) (const_int 0))
1358 (label_ref (match_operand 0 "" ""))
1362 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1363 && GET_CODE (sparc_compare_op0) == REG
1364 && GET_MODE (sparc_compare_op0) == DImode)
1366 emit_v9_brxx_insn (LT, sparc_compare_op0, operands[0]);
1369 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1372 = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LT);
1373 gcc_assert (code == NE);
1374 emit_jump_insn (gen_bne (operands[0]));
1377 operands[1] = gen_compare_reg (LT);
1380 (define_expand "bltu"
1382 (if_then_else (ltu (match_dup 1) (const_int 0))
1383 (label_ref (match_operand 0 "" ""))
1387 operands[1] = gen_compare_reg (LTU);
1390 (define_expand "bge"
1392 (if_then_else (ge (match_dup 1) (const_int 0))
1393 (label_ref (match_operand 0 "" ""))
1397 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1398 && GET_CODE (sparc_compare_op0) == REG
1399 && GET_MODE (sparc_compare_op0) == DImode)
1401 emit_v9_brxx_insn (GE, sparc_compare_op0, operands[0]);
1404 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1407 = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GE);
1408 gcc_assert (code == NE);
1409 emit_jump_insn (gen_bne (operands[0]));
1412 operands[1] = gen_compare_reg (GE);
1415 (define_expand "bgeu"
1417 (if_then_else (geu (match_dup 1) (const_int 0))
1418 (label_ref (match_operand 0 "" ""))
1422 operands[1] = gen_compare_reg (GEU);
1425 (define_expand "ble"
1427 (if_then_else (le (match_dup 1) (const_int 0))
1428 (label_ref (match_operand 0 "" ""))
1432 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1433 && GET_CODE (sparc_compare_op0) == REG
1434 && GET_MODE (sparc_compare_op0) == DImode)
1436 emit_v9_brxx_insn (LE, sparc_compare_op0, operands[0]);
1439 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1442 = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LE);
1443 gcc_assert (code == NE);
1444 emit_jump_insn (gen_bne (operands[0]));
1447 operands[1] = gen_compare_reg (LE);
1450 (define_expand "bleu"
1452 (if_then_else (leu (match_dup 1) (const_int 0))
1453 (label_ref (match_operand 0 "" ""))
1457 operands[1] = gen_compare_reg (LEU);
1460 (define_expand "bunordered"
1462 (if_then_else (unordered (match_dup 1) (const_int 0))
1463 (label_ref (match_operand 0 "" ""))
1467 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1470 = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNORDERED);
1471 gcc_assert (code == EQ);
1472 emit_jump_insn (gen_beq (operands[0]));
1475 operands[1] = gen_compare_reg (UNORDERED);
1478 (define_expand "bordered"
1480 (if_then_else (ordered (match_dup 1) (const_int 0))
1481 (label_ref (match_operand 0 "" ""))
1485 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1488 = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, ORDERED);
1489 gcc_assert (code == NE);
1490 emit_jump_insn (gen_bne (operands[0]));
1493 operands[1] = gen_compare_reg (ORDERED);
1496 (define_expand "bungt"
1498 (if_then_else (ungt (match_dup 1) (const_int 0))
1499 (label_ref (match_operand 0 "" ""))
1503 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1506 = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNGT);
1507 gcc_assert (code == GT);
1508 emit_jump_insn (gen_bgt (operands[0]));
1511 operands[1] = gen_compare_reg (UNGT);
1514 (define_expand "bunlt"
1516 (if_then_else (unlt (match_dup 1) (const_int 0))
1517 (label_ref (match_operand 0 "" ""))
1521 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1524 = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNLT);
1525 gcc_assert (code == NE);
1526 emit_jump_insn (gen_bne (operands[0]));
1529 operands[1] = gen_compare_reg (UNLT);
1532 (define_expand "buneq"
1534 (if_then_else (uneq (match_dup 1) (const_int 0))
1535 (label_ref (match_operand 0 "" ""))
1539 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1542 = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNEQ);
1543 gcc_assert (code == EQ);
1544 emit_jump_insn (gen_beq (operands[0]));
1547 operands[1] = gen_compare_reg (UNEQ);
1550 (define_expand "bunge"
1552 (if_then_else (unge (match_dup 1) (const_int 0))
1553 (label_ref (match_operand 0 "" ""))
1557 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1560 = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNGE);
1561 gcc_assert (code == NE);
1562 emit_jump_insn (gen_bne (operands[0]));
1565 operands[1] = gen_compare_reg (UNGE);
1568 (define_expand "bunle"
1570 (if_then_else (unle (match_dup 1) (const_int 0))
1571 (label_ref (match_operand 0 "" ""))
1575 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1578 = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNLE);
1579 gcc_assert (code == NE);
1580 emit_jump_insn (gen_bne (operands[0]));
1583 operands[1] = gen_compare_reg (UNLE);
1586 (define_expand "bltgt"
1588 (if_then_else (ltgt (match_dup 1) (const_int 0))
1589 (label_ref (match_operand 0 "" ""))
1593 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1596 = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LTGT);
1597 gcc_assert (code == NE);
1598 emit_jump_insn (gen_bne (operands[0]));
1601 operands[1] = gen_compare_reg (LTGT);
1604 ;; Now match both normal and inverted jump.
1606 ;; XXX fpcmp nop braindamage
1607 (define_insn "*normal_branch"
1609 (if_then_else (match_operator 0 "noov_compare_operator"
1610 [(reg 100) (const_int 0)])
1611 (label_ref (match_operand 1 "" ""))
1615 return output_cbranch (operands[0], operands[1], 1, 0,
1616 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1619 [(set_attr "type" "branch")
1620 (set_attr "branch_type" "icc")])
1622 ;; XXX fpcmp nop braindamage
1623 (define_insn "*inverted_branch"
1625 (if_then_else (match_operator 0 "noov_compare_operator"
1626 [(reg 100) (const_int 0)])
1628 (label_ref (match_operand 1 "" ""))))]
1631 return output_cbranch (operands[0], operands[1], 1, 1,
1632 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1635 [(set_attr "type" "branch")
1636 (set_attr "branch_type" "icc")])
1638 ;; XXX fpcmp nop braindamage
1639 (define_insn "*normal_fp_branch"
1641 (if_then_else (match_operator 1 "comparison_operator"
1642 [(match_operand:CCFP 0 "fcc_register_operand" "c")
1644 (label_ref (match_operand 2 "" ""))
1648 return output_cbranch (operands[1], operands[2], 2, 0,
1649 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1652 [(set_attr "type" "branch")
1653 (set_attr "branch_type" "fcc")])
1655 ;; XXX fpcmp nop braindamage
1656 (define_insn "*inverted_fp_branch"
1658 (if_then_else (match_operator 1 "comparison_operator"
1659 [(match_operand:CCFP 0 "fcc_register_operand" "c")
1662 (label_ref (match_operand 2 "" ""))))]
1665 return output_cbranch (operands[1], operands[2], 2, 1,
1666 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1669 [(set_attr "type" "branch")
1670 (set_attr "branch_type" "fcc")])
1672 ;; XXX fpcmp nop braindamage
1673 (define_insn "*normal_fpe_branch"
1675 (if_then_else (match_operator 1 "comparison_operator"
1676 [(match_operand:CCFPE 0 "fcc_register_operand" "c")
1678 (label_ref (match_operand 2 "" ""))
1682 return output_cbranch (operands[1], operands[2], 2, 0,
1683 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1686 [(set_attr "type" "branch")
1687 (set_attr "branch_type" "fcc")])
1689 ;; XXX fpcmp nop braindamage
1690 (define_insn "*inverted_fpe_branch"
1692 (if_then_else (match_operator 1 "comparison_operator"
1693 [(match_operand:CCFPE 0 "fcc_register_operand" "c")
1696 (label_ref (match_operand 2 "" ""))))]
1699 return output_cbranch (operands[1], operands[2], 2, 1,
1700 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1703 [(set_attr "type" "branch")
1704 (set_attr "branch_type" "fcc")])
1706 ;; SPARC V9-specific jump insns. None of these are guaranteed to be
1707 ;; in the architecture.
1709 ;; There are no 32 bit brreg insns.
1712 (define_insn "*normal_int_branch_sp64"
1714 (if_then_else (match_operator 0 "v9_register_compare_operator"
1715 [(match_operand:DI 1 "register_operand" "r")
1717 (label_ref (match_operand 2 "" ""))
1721 return output_v9branch (operands[0], operands[2], 1, 2, 0,
1722 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1725 [(set_attr "type" "branch")
1726 (set_attr "branch_type" "reg")])
1729 (define_insn "*inverted_int_branch_sp64"
1731 (if_then_else (match_operator 0 "v9_register_compare_operator"
1732 [(match_operand:DI 1 "register_operand" "r")
1735 (label_ref (match_operand 2 "" ""))))]
1738 return output_v9branch (operands[0], operands[2], 1, 2, 1,
1739 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1742 [(set_attr "type" "branch")
1743 (set_attr "branch_type" "reg")])
1746 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
1748 ;; Load in operand 0 the (absolute) address of operand 1, which is a symbolic
1749 ;; value subject to a PC-relative relocation. Operand 2 is a helper function
1750 ;; that adds the PC value at the call point to operand 0.
1752 (define_insn "load_pcrel_sym<P:mode>"
1753 [(set (match_operand:P 0 "register_operand" "=r")
1754 (unspec:P [(match_operand:P 1 "symbolic_operand" "")
1755 (match_operand:P 2 "call_address_operand" "")] UNSPEC_LOAD_PCREL_SYM))
1756 (clobber (reg:P 15))]
1759 if (flag_delayed_branch)
1760 return "sethi\t%%hi(%a1-4), %0\n\tcall\t%a2\n\t add\t%0, %%lo(%a1+4), %0";
1762 return "sethi\t%%hi(%a1-8), %0\n\tadd\t%0, %%lo(%a1-4), %0\n\tcall\t%a2\n\t nop";
1764 [(set (attr "type") (const_string "multi"))
1765 (set (attr "length")
1766 (if_then_else (eq_attr "delayed_branch" "true")
1771 ;; Integer move instructions
1773 (define_expand "movqi"
1774 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1775 (match_operand:QI 1 "general_operand" ""))]
1778 if (sparc_expand_move (QImode, operands))
1782 (define_insn "*movqi_insn"
1783 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m")
1784 (match_operand:QI 1 "input_operand" "rI,m,rJ"))]
1785 "(register_operand (operands[0], QImode)
1786 || register_or_zero_operand (operands[1], QImode))"
1791 [(set_attr "type" "*,load,store")
1792 (set_attr "us3load_type" "*,3cycle,*")])
1794 (define_expand "movhi"
1795 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1796 (match_operand:HI 1 "general_operand" ""))]
1799 if (sparc_expand_move (HImode, operands))
1803 (define_insn "*movhi_insn"
1804 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1805 (match_operand:HI 1 "input_operand" "rI,K,m,rJ"))]
1806 "(register_operand (operands[0], HImode)
1807 || register_or_zero_operand (operands[1], HImode))"
1810 sethi\t%%hi(%a1), %0
1813 [(set_attr "type" "*,*,load,store")
1814 (set_attr "us3load_type" "*,*,3cycle,*")])
1816 ;; We always work with constants here.
1817 (define_insn "*movhi_lo_sum"
1818 [(set (match_operand:HI 0 "register_operand" "=r")
1819 (ior:HI (match_operand:HI 1 "register_operand" "%r")
1820 (match_operand:HI 2 "small_int_operand" "I")))]
1824 (define_expand "movsi"
1825 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1826 (match_operand:SI 1 "general_operand" ""))]
1829 if (sparc_expand_move (SImode, operands))
1833 (define_insn "*movsi_insn"
1834 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,m,!f,!f,!m,d")
1835 (match_operand:SI 1 "input_operand" "rI,K,m,rJ,f,m,f,J"))]
1836 "(register_operand (operands[0], SImode)
1837 || register_or_zero_operand (operands[1], SImode))"
1840 sethi\t%%hi(%a1), %0
1847 [(set_attr "type" "*,*,load,store,fpmove,fpload,fpstore,fga")])
1849 (define_insn "*movsi_lo_sum"
1850 [(set (match_operand:SI 0 "register_operand" "=r")
1851 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1852 (match_operand:SI 2 "immediate_operand" "in")))]
1854 "or\t%1, %%lo(%a2), %0")
1856 (define_insn "*movsi_high"
1857 [(set (match_operand:SI 0 "register_operand" "=r")
1858 (high:SI (match_operand:SI 1 "immediate_operand" "in")))]
1860 "sethi\t%%hi(%a1), %0")
1862 ;; The next two patterns must wrap the SYMBOL_REF in an UNSPEC
1863 ;; so that CSE won't optimize the address computation away.
1864 (define_insn "movsi_lo_sum_pic"
1865 [(set (match_operand:SI 0 "register_operand" "=r")
1866 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1867 (unspec:SI [(match_operand:SI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
1869 "or\t%1, %%lo(%a2), %0")
1871 (define_insn "movsi_high_pic"
1872 [(set (match_operand:SI 0 "register_operand" "=r")
1873 (high:SI (unspec:SI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
1874 "flag_pic && check_pic (1)"
1875 "sethi\t%%hi(%a1), %0")
1877 (define_expand "movsi_pic_label_ref"
1878 [(set (match_dup 3) (high:SI
1879 (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
1880 (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1881 (set (match_dup 4) (lo_sum:SI (match_dup 3)
1882 (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1883 (set (match_operand:SI 0 "register_operand" "=r")
1884 (minus:SI (match_dup 5) (match_dup 4)))]
1887 crtl->uses_pic_offset_table = 1;
1888 operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
1889 if (!can_create_pseudo_p ())
1891 operands[3] = operands[0];
1892 operands[4] = operands[0];
1896 operands[3] = gen_reg_rtx (SImode);
1897 operands[4] = gen_reg_rtx (SImode);
1899 operands[5] = pic_offset_table_rtx;
1902 (define_insn "*movsi_high_pic_label_ref"
1903 [(set (match_operand:SI 0 "register_operand" "=r")
1905 (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
1906 (match_operand:SI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1908 "sethi\t%%hi(%a2-(%a1-.)), %0")
1910 (define_insn "*movsi_lo_sum_pic_label_ref"
1911 [(set (match_operand:SI 0 "register_operand" "=r")
1912 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1913 (unspec:SI [(match_operand:SI 2 "label_ref_operand" "")
1914 (match_operand:SI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1916 "or\t%1, %%lo(%a3-(%a2-.)), %0")
1918 ;; Set up the PIC register for VxWorks.
1920 (define_expand "vxworks_load_got"
1922 (high:SI (match_dup 1)))
1924 (mem:SI (lo_sum:SI (match_dup 0) (match_dup 1))))
1926 (mem:SI (lo_sum:SI (match_dup 0) (match_dup 2))))]
1927 "TARGET_VXWORKS_RTP"
1929 operands[0] = pic_offset_table_rtx;
1930 operands[1] = gen_rtx_SYMBOL_REF (SImode, VXWORKS_GOTT_BASE);
1931 operands[2] = gen_rtx_SYMBOL_REF (SImode, VXWORKS_GOTT_INDEX);
1934 (define_expand "movdi"
1935 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1936 (match_operand:DI 1 "general_operand" ""))]
1939 if (sparc_expand_move (DImode, operands))
1943 ;; Be careful, fmovd does not exist when !v9.
1944 ;; We match MEM moves directly when we have correct even
1945 ;; numbered registers, but fall into splits otherwise.
1946 ;; The constraint ordering here is really important to
1947 ;; avoid insane problems in reload, especially for patterns
1950 ;; (set (mem:DI (plus:SI (reg:SI 30 %fp)
1951 ;; (const_int -5016)))
1955 (define_insn "*movdi_insn_sp32"
1956 [(set (match_operand:DI 0 "nonimmediate_operand"
1957 "=o,T,U,o,r,r,r,?T,?f,?f,?o,?f")
1958 (match_operand:DI 1 "input_operand"
1959 " J,U,T,r,o,i,r, f, T, o, f, f"))]
1961 && (register_operand (operands[0], DImode)
1962 || register_or_zero_operand (operands[1], DImode))"
1976 [(set_attr "type" "store,store,load,*,*,*,*,fpstore,fpload,*,*,*")
1977 (set_attr "length" "2,*,*,2,2,2,2,*,*,2,2,2")])
1979 (define_insn "*movdi_insn_sp32_v9"
1980 [(set (match_operand:DI 0 "nonimmediate_operand"
1981 "=T,o,T,U,o,r,r,r,?T,?f,?f,?o,?e,?e,?W")
1982 (match_operand:DI 1 "input_operand"
1983 " J,J,U,T,r,o,i,r, f, T, o, f, e, W, e"))]
1986 && (register_operand (operands[0], DImode)
1987 || register_or_zero_operand (operands[1], DImode))"
2004 [(set_attr "type" "store,store,store,load,*,*,*,*,fpstore,fpload,*,*,fpmove,fpload,fpstore")
2005 (set_attr "length" "*,2,*,*,2,2,2,2,*,*,2,2,*,*,*")
2006 (set_attr "fptype" "*,*,*,*,*,*,*,*,*,*,*,*,double,*,*")])
2008 (define_insn "*movdi_insn_sp64"
2009 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,m,?e,?e,?W,b")
2010 (match_operand:DI 1 "input_operand" "rI,N,m,rJ,e,W,e,J"))]
2012 && (register_operand (operands[0], DImode)
2013 || register_or_zero_operand (operands[1], DImode))"
2016 sethi\t%%hi(%a1), %0
2023 [(set_attr "type" "*,*,load,store,fpmove,fpload,fpstore,fga")
2024 (set_attr "fptype" "*,*,*,*,double,*,*,double")])
2026 (define_expand "movdi_pic_label_ref"
2027 [(set (match_dup 3) (high:DI
2028 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
2029 (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
2030 (set (match_dup 4) (lo_sum:DI (match_dup 3)
2031 (unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
2032 (set (match_operand:DI 0 "register_operand" "=r")
2033 (minus:DI (match_dup 5) (match_dup 4)))]
2034 "TARGET_ARCH64 && flag_pic"
2036 crtl->uses_pic_offset_table = 1;
2037 operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
2038 if (!can_create_pseudo_p ())
2040 operands[3] = operands[0];
2041 operands[4] = operands[0];
2045 operands[3] = gen_reg_rtx (DImode);
2046 operands[4] = gen_reg_rtx (DImode);
2048 operands[5] = pic_offset_table_rtx;
2051 (define_insn "*movdi_high_pic_label_ref"
2052 [(set (match_operand:DI 0 "register_operand" "=r")
2054 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
2055 (match_operand:DI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
2056 "TARGET_ARCH64 && flag_pic"
2057 "sethi\t%%hi(%a2-(%a1-.)), %0")
2059 (define_insn "*movdi_lo_sum_pic_label_ref"
2060 [(set (match_operand:DI 0 "register_operand" "=r")
2061 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2062 (unspec:DI [(match_operand:DI 2 "label_ref_operand" "")
2063 (match_operand:DI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
2064 "TARGET_ARCH64 && flag_pic"
2065 "or\t%1, %%lo(%a3-(%a2-.)), %0")
2067 ;; SPARC-v9 code model support insns. See sparc_emit_set_symbolic_const64
2068 ;; in sparc.c to see what is going on here... PIC stuff comes first.
2070 (define_insn "movdi_lo_sum_pic"
2071 [(set (match_operand:DI 0 "register_operand" "=r")
2072 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2073 (unspec:DI [(match_operand:DI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
2074 "TARGET_ARCH64 && flag_pic"
2075 "or\t%1, %%lo(%a2), %0")
2077 (define_insn "movdi_high_pic"
2078 [(set (match_operand:DI 0 "register_operand" "=r")
2079 (high:DI (unspec:DI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
2080 "TARGET_ARCH64 && flag_pic && check_pic (1)"
2081 "sethi\t%%hi(%a1), %0")
2083 (define_insn "*sethi_di_medlow_embmedany_pic"
2084 [(set (match_operand:DI 0 "register_operand" "=r")
2085 (high:DI (match_operand:DI 1 "medium_pic_operand" "")))]
2086 "(TARGET_CM_MEDLOW || TARGET_CM_EMBMEDANY) && check_pic (1)"
2087 "sethi\t%%hi(%a1), %0")
2089 (define_insn "*sethi_di_medlow"
2090 [(set (match_operand:DI 0 "register_operand" "=r")
2091 (high:DI (match_operand:DI 1 "symbolic_operand" "")))]
2092 "TARGET_CM_MEDLOW && check_pic (1)"
2093 "sethi\t%%hi(%a1), %0")
2095 (define_insn "*losum_di_medlow"
2096 [(set (match_operand:DI 0 "register_operand" "=r")
2097 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2098 (match_operand:DI 2 "symbolic_operand" "")))]
2100 "or\t%1, %%lo(%a2), %0")
2102 (define_insn "seth44"
2103 [(set (match_operand:DI 0 "register_operand" "=r")
2104 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETH44)))]
2106 "sethi\t%%h44(%a1), %0")
2108 (define_insn "setm44"
2109 [(set (match_operand:DI 0 "register_operand" "=r")
2110 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2111 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_SETM44)))]
2113 "or\t%1, %%m44(%a2), %0")
2115 (define_insn "setl44"
2116 [(set (match_operand:DI 0 "register_operand" "=r")
2117 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2118 (match_operand:DI 2 "symbolic_operand" "")))]
2120 "or\t%1, %%l44(%a2), %0")
2122 (define_insn "sethh"
2123 [(set (match_operand:DI 0 "register_operand" "=r")
2124 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETHH)))]
2126 "sethi\t%%hh(%a1), %0")
2128 (define_insn "setlm"
2129 [(set (match_operand:DI 0 "register_operand" "=r")
2130 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETLM)))]
2132 "sethi\t%%lm(%a1), %0")
2134 (define_insn "sethm"
2135 [(set (match_operand:DI 0 "register_operand" "=r")
2136 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2137 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_EMB_SETHM)))]
2139 "or\t%1, %%hm(%a2), %0")
2141 (define_insn "setlo"
2142 [(set (match_operand:DI 0 "register_operand" "=r")
2143 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2144 (match_operand:DI 2 "symbolic_operand" "")))]
2146 "or\t%1, %%lo(%a2), %0")
2148 (define_insn "embmedany_sethi"
2149 [(set (match_operand:DI 0 "register_operand" "=r")
2150 (high:DI (unspec:DI [(match_operand:DI 1 "data_segment_operand" "")] UNSPEC_EMB_HISUM)))]
2151 "TARGET_CM_EMBMEDANY && check_pic (1)"
2152 "sethi\t%%hi(%a1), %0")
2154 (define_insn "embmedany_losum"
2155 [(set (match_operand:DI 0 "register_operand" "=r")
2156 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2157 (match_operand:DI 2 "data_segment_operand" "")))]
2158 "TARGET_CM_EMBMEDANY"
2159 "add\t%1, %%lo(%a2), %0")
2161 (define_insn "embmedany_brsum"
2162 [(set (match_operand:DI 0 "register_operand" "=r")
2163 (unspec:DI [(match_operand:DI 1 "register_operand" "r")] UNSPEC_EMB_HISUM))]
2164 "TARGET_CM_EMBMEDANY"
2167 (define_insn "embmedany_textuhi"
2168 [(set (match_operand:DI 0 "register_operand" "=r")
2169 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTUHI)))]
2170 "TARGET_CM_EMBMEDANY && check_pic (1)"
2171 "sethi\t%%uhi(%a1), %0")
2173 (define_insn "embmedany_texthi"
2174 [(set (match_operand:DI 0 "register_operand" "=r")
2175 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTHI)))]
2176 "TARGET_CM_EMBMEDANY && check_pic (1)"
2177 "sethi\t%%hi(%a1), %0")
2179 (define_insn "embmedany_textulo"
2180 [(set (match_operand:DI 0 "register_operand" "=r")
2181 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2182 (unspec:DI [(match_operand:DI 2 "text_segment_operand" "")] UNSPEC_EMB_TEXTULO)))]
2183 "TARGET_CM_EMBMEDANY"
2184 "or\t%1, %%ulo(%a2), %0")
2186 (define_insn "embmedany_textlo"
2187 [(set (match_operand:DI 0 "register_operand" "=r")
2188 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2189 (match_operand:DI 2 "text_segment_operand" "")))]
2190 "TARGET_CM_EMBMEDANY"
2191 "or\t%1, %%lo(%a2), %0")
2193 ;; Now some patterns to help reload out a bit.
2194 (define_expand "reload_indi"
2195 [(parallel [(match_operand:DI 0 "register_operand" "=r")
2196 (match_operand:DI 1 "immediate_operand" "")
2197 (match_operand:TI 2 "register_operand" "=&r")])]
2199 || TARGET_CM_EMBMEDANY)
2202 sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
2206 (define_expand "reload_outdi"
2207 [(parallel [(match_operand:DI 0 "register_operand" "=r")
2208 (match_operand:DI 1 "immediate_operand" "")
2209 (match_operand:TI 2 "register_operand" "=&r")])]
2211 || TARGET_CM_EMBMEDANY)
2214 sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
2218 ;; Split up putting CONSTs and REGs into DI regs when !arch64
2220 [(set (match_operand:DI 0 "register_operand" "")
2221 (match_operand:DI 1 "const_int_operand" ""))]
2222 "! TARGET_ARCH64 && reload_completed"
2223 [(clobber (const_int 0))]
2225 #if HOST_BITS_PER_WIDE_INT == 32
2226 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
2227 (INTVAL (operands[1]) < 0) ?
2230 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2233 unsigned int low, high;
2235 low = trunc_int_for_mode (INTVAL (operands[1]), SImode);
2236 high = trunc_int_for_mode (INTVAL (operands[1]) >> 32, SImode);
2237 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), GEN_INT (high)));
2239 /* Slick... but this trick loses if this subreg constant part
2240 can be done in one insn. */
2242 && ! SPARC_SETHI32_P (high)
2243 && ! SPARC_SIMM13_P (high))
2244 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2245 gen_highpart (SImode, operands[0])));
2247 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), GEN_INT (low)));
2253 [(set (match_operand:DI 0 "register_operand" "")
2254 (match_operand:DI 1 "const_double_operand" ""))]
2258 && ((GET_CODE (operands[0]) == REG
2259 && REGNO (operands[0]) < 32)
2260 || (GET_CODE (operands[0]) == SUBREG
2261 && GET_CODE (SUBREG_REG (operands[0])) == REG
2262 && REGNO (SUBREG_REG (operands[0])) < 32))))"
2263 [(clobber (const_int 0))]
2265 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
2266 GEN_INT (CONST_DOUBLE_HIGH (operands[1]))));
2268 /* Slick... but this trick loses if this subreg constant part
2269 can be done in one insn. */
2270 if (CONST_DOUBLE_LOW (operands[1]) == CONST_DOUBLE_HIGH (operands[1])
2271 && ! SPARC_SETHI32_P (CONST_DOUBLE_HIGH (operands[1]))
2272 && ! SPARC_SIMM13_P (CONST_DOUBLE_HIGH (operands[1])))
2274 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2275 gen_highpart (SImode, operands[0])));
2279 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2280 GEN_INT (CONST_DOUBLE_LOW (operands[1]))));
2286 [(set (match_operand:DI 0 "register_operand" "")
2287 (match_operand:DI 1 "register_operand" ""))]
2291 && ((GET_CODE (operands[0]) == REG
2292 && REGNO (operands[0]) < 32)
2293 || (GET_CODE (operands[0]) == SUBREG
2294 && GET_CODE (SUBREG_REG (operands[0])) == REG
2295 && REGNO (SUBREG_REG (operands[0])) < 32))))"
2296 [(clobber (const_int 0))]
2298 rtx set_dest = operands[0];
2299 rtx set_src = operands[1];
2303 dest1 = gen_highpart (SImode, set_dest);
2304 dest2 = gen_lowpart (SImode, set_dest);
2305 src1 = gen_highpart (SImode, set_src);
2306 src2 = gen_lowpart (SImode, set_src);
2308 /* Now emit using the real source and destination we found, swapping
2309 the order if we detect overlap. */
2310 if (reg_overlap_mentioned_p (dest1, src2))
2312 emit_insn (gen_movsi (dest2, src2));
2313 emit_insn (gen_movsi (dest1, src1));
2317 emit_insn (gen_movsi (dest1, src1));
2318 emit_insn (gen_movsi (dest2, src2));
2323 ;; Now handle the cases of memory moves from/to non-even
2324 ;; DI mode register pairs.
2326 [(set (match_operand:DI 0 "register_operand" "")
2327 (match_operand:DI 1 "memory_operand" ""))]
2330 && sparc_splitdi_legitimate (operands[0], operands[1]))"
2331 [(clobber (const_int 0))]
2333 rtx word0 = adjust_address (operands[1], SImode, 0);
2334 rtx word1 = adjust_address (operands[1], SImode, 4);
2335 rtx high_part = gen_highpart (SImode, operands[0]);
2336 rtx low_part = gen_lowpart (SImode, operands[0]);
2338 if (reg_overlap_mentioned_p (high_part, word1))
2340 emit_insn (gen_movsi (low_part, word1));
2341 emit_insn (gen_movsi (high_part, word0));
2345 emit_insn (gen_movsi (high_part, word0));
2346 emit_insn (gen_movsi (low_part, word1));
2352 [(set (match_operand:DI 0 "memory_operand" "")
2353 (match_operand:DI 1 "register_operand" ""))]
2356 && sparc_splitdi_legitimate (operands[1], operands[0]))"
2357 [(clobber (const_int 0))]
2359 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0),
2360 gen_highpart (SImode, operands[1])));
2361 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4),
2362 gen_lowpart (SImode, operands[1])));
2367 [(set (match_operand:DI 0 "memory_operand" "")
2368 (match_operand:DI 1 "const_zero_operand" ""))]
2372 && ! mem_min_alignment (operands[0], 8)))
2373 && offsettable_memref_p (operands[0])"
2374 [(clobber (const_int 0))]
2376 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0), const0_rtx));
2377 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4), const0_rtx));
2382 ;; Floating point and vector move instructions
2384 ;; We don't define V1SI because SI should work just fine.
2385 (define_mode_iterator V32 [SF V2HI V4QI])
2387 ;; Yes, you guessed it right, the former movsf expander.
2388 (define_expand "mov<V32:mode>"
2389 [(set (match_operand:V32 0 "nonimmediate_operand" "")
2390 (match_operand:V32 1 "general_operand" ""))]
2391 "<V32:MODE>mode == SFmode || TARGET_VIS"
2393 if (sparc_expand_move (<V32:MODE>mode, operands))
2397 (define_insn "*movsf_insn"
2398 [(set (match_operand:V32 0 "nonimmediate_operand" "=d,f,*r,*r,*r,f,*r,m,m")
2399 (match_operand:V32 1 "input_operand" "GY,f,*rRY,Q,S,m,m,f,*rGY"))]
2401 && (register_operand (operands[0], <V32:MODE>mode)
2402 || register_or_zero_operand (operands[1], <V32:MODE>mode))"
2404 if (GET_CODE (operands[1]) == CONST_DOUBLE
2405 && (which_alternative == 2
2406 || which_alternative == 3
2407 || which_alternative == 4))
2412 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2413 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2414 operands[1] = GEN_INT (i);
2417 switch (which_alternative)
2420 return "fzeros\t%0";
2422 return "fmovs\t%1, %0";
2424 return "mov\t%1, %0";
2426 return "sethi\t%%hi(%a1), %0";
2431 return "ld\t%1, %0";
2434 return "st\t%r1, %0";
2439 [(set_attr "type" "fga,fpmove,*,*,*,fpload,load,fpstore,store")])
2441 ;; Exactly the same as above, except that all `f' cases are deleted.
2442 ;; This is necessary to prevent reload from ever trying to use a `f' reg
2445 (define_insn "*movsf_insn_no_fpu"
2446 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r,r,m")
2447 (match_operand:SF 1 "input_operand" "rR,Q,S,m,rG"))]
2449 && (register_operand (operands[0], SFmode)
2450 || register_or_zero_operand (operands[1], SFmode))"
2452 if (GET_CODE (operands[1]) == CONST_DOUBLE
2453 && (which_alternative == 0
2454 || which_alternative == 1
2455 || which_alternative == 2))
2460 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2461 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2462 operands[1] = GEN_INT (i);
2465 switch (which_alternative)
2468 return "mov\t%1, %0";
2470 return "sethi\t%%hi(%a1), %0";
2474 return "ld\t%1, %0";
2476 return "st\t%r1, %0";
2481 [(set_attr "type" "*,*,*,load,store")])
2483 ;; The following 3 patterns build SFmode constants in integer registers.
2485 (define_insn "*movsf_lo_sum"
2486 [(set (match_operand:SF 0 "register_operand" "=r")
2487 (lo_sum:SF (match_operand:SF 1 "register_operand" "r")
2488 (match_operand:SF 2 "fp_const_high_losum_operand" "S")))]
2494 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[2]);
2495 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2496 operands[2] = GEN_INT (i);
2497 return "or\t%1, %%lo(%a2), %0";
2500 (define_insn "*movsf_high"
2501 [(set (match_operand:SF 0 "register_operand" "=r")
2502 (high:SF (match_operand:SF 1 "fp_const_high_losum_operand" "S")))]
2508 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2509 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2510 operands[1] = GEN_INT (i);
2511 return "sethi\t%%hi(%1), %0";
2515 [(set (match_operand:SF 0 "register_operand" "")
2516 (match_operand:SF 1 "fp_const_high_losum_operand" ""))]
2517 "REG_P (operands[0]) && REGNO (operands[0]) < 32"
2518 [(set (match_dup 0) (high:SF (match_dup 1)))
2519 (set (match_dup 0) (lo_sum:SF (match_dup 0) (match_dup 1)))])
2521 (define_mode_iterator V64 [DF V2SI V4HI V8QI])
2523 ;; Yes, you again guessed it right, the former movdf expander.
2524 (define_expand "mov<V64:mode>"
2525 [(set (match_operand:V64 0 "nonimmediate_operand" "")
2526 (match_operand:V64 1 "general_operand" ""))]
2527 "<V64:MODE>mode == DFmode || TARGET_VIS"
2529 if (sparc_expand_move (<V64:MODE>mode, operands))
2533 ;; Be careful, fmovd does not exist when !v9.
2534 (define_insn "*movdf_insn_sp32"
2535 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,W,U,T,o,e,*r,o,e,o")
2536 (match_operand:DF 1 "input_operand" "W#F,e,T,U,G,e,*rFo,*r,o#F,e"))]
2539 && (register_operand (operands[0], DFmode)
2540 || register_or_zero_operand (operands[1], DFmode))"
2552 [(set_attr "type" "fpload,fpstore,load,store,*,*,*,*,*,*")
2553 (set_attr "length" "*,*,*,*,2,2,2,2,2,2")])
2555 (define_insn "*movdf_insn_sp32_no_fpu"
2556 [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,o,r,o")
2557 (match_operand:DF 1 "input_operand" "T,U,G,ro,r"))]
2560 && (register_operand (operands[0], DFmode)
2561 || register_or_zero_operand (operands[1], DFmode))"
2568 [(set_attr "type" "load,store,*,*,*")
2569 (set_attr "length" "*,*,2,2,2")])
2571 ;; We have available v9 double floats but not 64-bit integer registers.
2572 (define_insn "*movdf_insn_sp32_v9"
2573 [(set (match_operand:V64 0 "nonimmediate_operand" "=b,e,e,T,W,U,T,f,*r,o")
2574 (match_operand:V64 1 "input_operand" "GY,e,W#F,GY,e,T,U,o#F,*roGYF,*rGYf"))]
2578 && (register_operand (operands[0], <V64:MODE>mode)
2579 || register_or_zero_operand (operands[1], <V64:MODE>mode))"
2591 [(set_attr "type" "fga,fpmove,load,store,store,load,store,*,*,*")
2592 (set_attr "length" "*,*,*,*,*,*,*,2,2,2")
2593 (set_attr "fptype" "double,double,*,*,*,*,*,*,*,*")])
2595 (define_insn "*movdf_insn_sp32_v9_no_fpu"
2596 [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,T,r,o")
2597 (match_operand:DF 1 "input_operand" "T,U,G,ro,rG"))]
2601 && (register_operand (operands[0], DFmode)
2602 || register_or_zero_operand (operands[1], DFmode))"
2609 [(set_attr "type" "load,store,store,*,*")
2610 (set_attr "length" "*,*,*,2,2")])
2612 ;; We have available both v9 double floats and 64-bit integer registers.
2613 (define_insn "*movdf_insn_sp64"
2614 [(set (match_operand:V64 0 "nonimmediate_operand" "=b,e,e,W,*r,*r,m,*r")
2615 (match_operand:V64 1 "input_operand" "GY,e,W#F,e,*rGY,m,*rGY,F"))]
2618 && (register_operand (operands[0], <V64:MODE>mode)
2619 || register_or_zero_operand (operands[1], <V64:MODE>mode))"
2629 [(set_attr "type" "fga,fpmove,load,store,*,load,store,*")
2630 (set_attr "length" "*,*,*,*,*,*,*,2")
2631 (set_attr "fptype" "double,double,*,*,*,*,*,*")])
2633 (define_insn "*movdf_insn_sp64_no_fpu"
2634 [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m")
2635 (match_operand:DF 1 "input_operand" "r,m,rG"))]
2638 && (register_operand (operands[0], DFmode)
2639 || register_or_zero_operand (operands[1], DFmode))"
2644 [(set_attr "type" "*,load,store")])
2646 ;; This pattern build DFmode constants in integer registers.
2648 [(set (match_operand:DF 0 "register_operand" "")
2649 (match_operand:DF 1 "const_double_operand" ""))]
2651 && (GET_CODE (operands[0]) == REG
2652 && REGNO (operands[0]) < 32)
2653 && ! const_zero_operand(operands[1], DFmode)
2654 && reload_completed"
2655 [(clobber (const_int 0))]
2660 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2661 REAL_VALUE_TO_TARGET_DOUBLE (r, l);
2662 operands[0] = gen_rtx_raw_REG (DImode, REGNO (operands[0]));
2666 #if HOST_BITS_PER_WIDE_INT == 32
2671 val = ((HOST_WIDE_INT)(unsigned long)l[1] |
2672 ((HOST_WIDE_INT)(unsigned long)l[0] << 32));
2673 emit_insn (gen_movdi (operands[0], gen_int_mode (val, DImode)));
2678 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
2679 gen_int_mode (l[0], SImode)));
2681 /* Slick... but this trick loses if this subreg constant part
2682 can be done in one insn. */
2684 && ! SPARC_SETHI32_P (l[0])
2685 && ! SPARC_SIMM13_P (l[0]))
2687 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2688 gen_highpart (SImode, operands[0])));
2692 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2693 gen_int_mode (l[1], SImode)));
2699 ;; Ok, now the splits to handle all the multi insn and
2700 ;; mis-aligned memory address cases.
2701 ;; In these splits please take note that we must be
2702 ;; careful when V9 but not ARCH64 because the integer
2703 ;; register DFmode cases must be handled.
2705 [(set (match_operand:V64 0 "register_operand" "")
2706 (match_operand:V64 1 "register_operand" ""))]
2709 && ((GET_CODE (operands[0]) == REG
2710 && REGNO (operands[0]) < 32)
2711 || (GET_CODE (operands[0]) == SUBREG
2712 && GET_CODE (SUBREG_REG (operands[0])) == REG
2713 && REGNO (SUBREG_REG (operands[0])) < 32))))
2714 && reload_completed"
2715 [(clobber (const_int 0))]
2717 rtx set_dest = operands[0];
2718 rtx set_src = operands[1];
2721 enum machine_mode half_mode;
2723 /* We can be expanded for DFmode or integral vector modes. */
2724 if (<V64:MODE>mode == DFmode)
2729 dest1 = gen_highpart (half_mode, set_dest);
2730 dest2 = gen_lowpart (half_mode, set_dest);
2731 src1 = gen_highpart (half_mode, set_src);
2732 src2 = gen_lowpart (half_mode, set_src);
2734 /* Now emit using the real source and destination we found, swapping
2735 the order if we detect overlap. */
2736 if (reg_overlap_mentioned_p (dest1, src2))
2738 emit_move_insn_1 (dest2, src2);
2739 emit_move_insn_1 (dest1, src1);
2743 emit_move_insn_1 (dest1, src1);
2744 emit_move_insn_1 (dest2, src2);
2750 [(set (match_operand:V64 0 "register_operand" "")
2751 (match_operand:V64 1 "memory_operand" ""))]
2754 && (((REGNO (operands[0]) % 2) != 0)
2755 || ! mem_min_alignment (operands[1], 8))
2756 && offsettable_memref_p (operands[1])"
2757 [(clobber (const_int 0))]
2759 enum machine_mode half_mode;
2762 /* We can be expanded for DFmode or integral vector modes. */
2763 if (<V64:MODE>mode == DFmode)
2768 word0 = adjust_address (operands[1], half_mode, 0);
2769 word1 = adjust_address (operands[1], half_mode, 4);
2771 if (reg_overlap_mentioned_p (gen_highpart (half_mode, operands[0]), word1))
2773 emit_move_insn_1 (gen_lowpart (half_mode, operands[0]), word1);
2774 emit_move_insn_1 (gen_highpart (half_mode, operands[0]), word0);
2778 emit_move_insn_1 (gen_highpart (half_mode, operands[0]), word0);
2779 emit_move_insn_1 (gen_lowpart (half_mode, operands[0]), word1);
2785 [(set (match_operand:V64 0 "memory_operand" "")
2786 (match_operand:V64 1 "register_operand" ""))]
2789 && (((REGNO (operands[1]) % 2) != 0)
2790 || ! mem_min_alignment (operands[0], 8))
2791 && offsettable_memref_p (operands[0])"
2792 [(clobber (const_int 0))]
2794 enum machine_mode half_mode;
2797 /* We can be expanded for DFmode or integral vector modes. */
2798 if (<V64:MODE>mode == DFmode)
2803 word0 = adjust_address (operands[0], half_mode, 0);
2804 word1 = adjust_address (operands[0], half_mode, 4);
2806 emit_move_insn_1 (word0, gen_highpart (half_mode, operands[1]));
2807 emit_move_insn_1 (word1, gen_lowpart (half_mode, operands[1]));
2812 [(set (match_operand:V64 0 "memory_operand" "")
2813 (match_operand:V64 1 "const_zero_operand" ""))]
2817 && ! mem_min_alignment (operands[0], 8)))
2818 && offsettable_memref_p (operands[0])"
2819 [(clobber (const_int 0))]
2821 enum machine_mode half_mode;
2824 /* We can be expanded for DFmode or integral vector modes. */
2825 if (<V64:MODE>mode == DFmode)
2830 dest1 = adjust_address (operands[0], half_mode, 0);
2831 dest2 = adjust_address (operands[0], half_mode, 4);
2833 emit_move_insn_1 (dest1, CONST0_RTX (half_mode));
2834 emit_move_insn_1 (dest2, CONST0_RTX (half_mode));
2839 [(set (match_operand:V64 0 "register_operand" "")
2840 (match_operand:V64 1 "const_zero_operand" ""))]
2843 && ((GET_CODE (operands[0]) == REG
2844 && REGNO (operands[0]) < 32)
2845 || (GET_CODE (operands[0]) == SUBREG
2846 && GET_CODE (SUBREG_REG (operands[0])) == REG
2847 && REGNO (SUBREG_REG (operands[0])) < 32))"
2848 [(clobber (const_int 0))]
2850 enum machine_mode half_mode;
2851 rtx set_dest = operands[0];
2854 /* We can be expanded for DFmode or integral vector modes. */
2855 if (<V64:MODE>mode == DFmode)
2860 dest1 = gen_highpart (half_mode, set_dest);
2861 dest2 = gen_lowpart (half_mode, set_dest);
2862 emit_move_insn_1 (dest1, CONST0_RTX (half_mode));
2863 emit_move_insn_1 (dest2, CONST0_RTX (half_mode));
2867 (define_expand "movtf"
2868 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2869 (match_operand:TF 1 "general_operand" ""))]
2872 if (sparc_expand_move (TFmode, operands))
2876 (define_insn "*movtf_insn_sp32"
2877 [(set (match_operand:TF 0 "nonimmediate_operand" "=b,e,o,U,r")
2878 (match_operand:TF 1 "input_operand" "G,oe,GeUr,o,roG"))]
2881 && (register_operand (operands[0], TFmode)
2882 || register_or_zero_operand (operands[1], TFmode))"
2884 [(set_attr "length" "4")])
2886 ;; Exactly the same as above, except that all `e' cases are deleted.
2887 ;; This is necessary to prevent reload from ever trying to use a `e' reg
2890 (define_insn "*movtf_insn_sp32_no_fpu"
2891 [(set (match_operand:TF 0 "nonimmediate_operand" "=o,U,o,r,o")
2892 (match_operand:TF 1 "input_operand" "G,o,U,roG,r"))]
2895 && (register_operand (operands[0], TFmode)
2896 || register_or_zero_operand (operands[1], TFmode))"
2898 [(set_attr "length" "4")])
2900 (define_insn "*movtf_insn_sp64"
2901 [(set (match_operand:TF 0 "nonimmediate_operand" "=b,e,o,r")
2902 (match_operand:TF 1 "input_operand" "G,oe,Ger,roG"))]
2905 && ! TARGET_HARD_QUAD
2906 && (register_operand (operands[0], TFmode)
2907 || register_or_zero_operand (operands[1], TFmode))"
2909 [(set_attr "length" "2")])
2911 (define_insn "*movtf_insn_sp64_hq"
2912 [(set (match_operand:TF 0 "nonimmediate_operand" "=b,e,e,m,o,r")
2913 (match_operand:TF 1 "input_operand" "G,e,m,e,rG,roG"))]
2917 && (register_operand (operands[0], TFmode)
2918 || register_or_zero_operand (operands[1], TFmode))"
2926 [(set_attr "type" "*,fpmove,fpload,fpstore,*,*")
2927 (set_attr "length" "2,*,*,*,2,2")])
2929 (define_insn "*movtf_insn_sp64_no_fpu"
2930 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o")
2931 (match_operand:TF 1 "input_operand" "orG,rG"))]
2934 && (register_operand (operands[0], TFmode)
2935 || register_or_zero_operand (operands[1], TFmode))"
2937 [(set_attr "length" "2")])
2939 ;; Now all the splits to handle multi-insn TF mode moves.
2941 [(set (match_operand:TF 0 "register_operand" "")
2942 (match_operand:TF 1 "register_operand" ""))]
2946 && ! TARGET_HARD_QUAD)
2947 || ! fp_register_operand (operands[0], TFmode))"
2948 [(clobber (const_int 0))]
2950 rtx set_dest = operands[0];
2951 rtx set_src = operands[1];
2955 dest1 = gen_df_reg (set_dest, 0);
2956 dest2 = gen_df_reg (set_dest, 1);
2957 src1 = gen_df_reg (set_src, 0);
2958 src2 = gen_df_reg (set_src, 1);
2960 /* Now emit using the real source and destination we found, swapping
2961 the order if we detect overlap. */
2962 if (reg_overlap_mentioned_p (dest1, src2))
2964 emit_insn (gen_movdf (dest2, src2));
2965 emit_insn (gen_movdf (dest1, src1));
2969 emit_insn (gen_movdf (dest1, src1));
2970 emit_insn (gen_movdf (dest2, src2));
2976 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2977 (match_operand:TF 1 "const_zero_operand" ""))]
2979 [(clobber (const_int 0))]
2981 rtx set_dest = operands[0];
2984 switch (GET_CODE (set_dest))
2987 dest1 = gen_df_reg (set_dest, 0);
2988 dest2 = gen_df_reg (set_dest, 1);
2991 dest1 = adjust_address (set_dest, DFmode, 0);
2992 dest2 = adjust_address (set_dest, DFmode, 8);
2998 emit_insn (gen_movdf (dest1, CONST0_RTX (DFmode)));
2999 emit_insn (gen_movdf (dest2, CONST0_RTX (DFmode)));
3004 [(set (match_operand:TF 0 "register_operand" "")
3005 (match_operand:TF 1 "memory_operand" ""))]
3007 && offsettable_memref_p (operands[1])
3009 || ! TARGET_HARD_QUAD
3010 || ! fp_register_operand (operands[0], TFmode)))"
3011 [(clobber (const_int 0))]
3013 rtx word0 = adjust_address (operands[1], DFmode, 0);
3014 rtx word1 = adjust_address (operands[1], DFmode, 8);
3015 rtx set_dest, dest1, dest2;
3017 set_dest = operands[0];
3019 dest1 = gen_df_reg (set_dest, 0);
3020 dest2 = gen_df_reg (set_dest, 1);
3022 /* Now output, ordering such that we don't clobber any registers
3023 mentioned in the address. */
3024 if (reg_overlap_mentioned_p (dest1, word1))
3027 emit_insn (gen_movdf (dest2, word1));
3028 emit_insn (gen_movdf (dest1, word0));
3032 emit_insn (gen_movdf (dest1, word0));
3033 emit_insn (gen_movdf (dest2, word1));
3039 [(set (match_operand:TF 0 "memory_operand" "")
3040 (match_operand:TF 1 "register_operand" ""))]
3042 && offsettable_memref_p (operands[0])
3044 || ! TARGET_HARD_QUAD
3045 || ! fp_register_operand (operands[1], TFmode)))"
3046 [(clobber (const_int 0))]
3048 rtx set_src = operands[1];
3050 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 0),
3051 gen_df_reg (set_src, 0)));
3052 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 8),
3053 gen_df_reg (set_src, 1)));
3058 ;; SPARC-V9 conditional move instructions
3060 ;; We can handle larger constants here for some flavors, but for now we keep
3061 ;; it simple and only allow those constants supported by all flavors.
3062 ;; Note that emit_conditional_move canonicalizes operands 2,3 so that operand
3063 ;; 3 contains the constant if one is present, but we handle either for
3064 ;; generality (sparc.c puts a constant in operand 2).
3066 (define_mode_iterator I [QI HI SI DI])
3068 (define_expand "mov<I:mode>cc"
3069 [(set (match_operand:I 0 "register_operand" "")
3070 (if_then_else:I (match_operand 1 "comparison_operator" "")
3071 (match_operand:I 2 "arith10_operand" "")
3072 (match_operand:I 3 "arith10_operand" "")))]
3073 "TARGET_V9 && !(<I:MODE>mode == DImode && TARGET_ARCH32)"
3075 enum rtx_code code = GET_CODE (operands[1]);
3077 if (GET_MODE (sparc_compare_op0) == DImode
3081 if (sparc_compare_op1 == const0_rtx
3082 && GET_CODE (sparc_compare_op0) == REG
3083 && GET_MODE (sparc_compare_op0) == DImode
3084 && v9_regcmp_p (code))
3085 operands[1] = gen_rtx_fmt_ee (code, DImode, sparc_compare_op0, const0_rtx);
3087 operands[1] = gen_compare_operator (code);
3090 (define_mode_iterator F [SF DF TF])
3092 (define_expand "mov<F:mode>cc"
3093 [(set (match_operand:F 0 "register_operand" "")
3094 (if_then_else:F (match_operand 1 "comparison_operator" "")
3095 (match_operand:F 2 "register_operand" "")
3096 (match_operand:F 3 "register_operand" "")))]
3097 "TARGET_V9 && TARGET_FPU"
3099 enum rtx_code code = GET_CODE (operands[1]);
3101 if (GET_MODE (sparc_compare_op0) == DImode
3105 if (sparc_compare_op1 == const0_rtx
3106 && GET_CODE (sparc_compare_op0) == REG
3107 && GET_MODE (sparc_compare_op0) == DImode
3108 && v9_regcmp_p (code))
3109 operands[1] = gen_rtx_fmt_ee (code, DImode, sparc_compare_op0, const0_rtx);
3111 operands[1] = gen_compare_operator (code);
3114 ;; Conditional move define_insns
3116 (define_insn "*mov<I:mode>_cc_v9"
3117 [(set (match_operand:I 0 "register_operand" "=r,r")
3118 (if_then_else:I (match_operator 1 "comparison_operator"
3119 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
3121 (match_operand:I 3 "arith11_operand" "rL,0")
3122 (match_operand:I 4 "arith11_operand" "0,rL")))]
3123 "TARGET_V9 && !(<I:MODE>mode == DImode && TARGET_ARCH32)"
3126 mov%c1\t%x2, %4, %0"
3127 [(set_attr "type" "cmove")])
3129 (define_insn "*mov<I:mode>_cc_reg_sp64"
3130 [(set (match_operand:I 0 "register_operand" "=r,r")
3131 (if_then_else:I (match_operator 1 "v9_register_compare_operator"
3132 [(match_operand:DI 2 "register_operand" "r,r")
3134 (match_operand:I 3 "arith10_operand" "rM,0")
3135 (match_operand:I 4 "arith10_operand" "0,rM")))]
3138 movr%D1\t%2, %r3, %0
3139 movr%d1\t%2, %r4, %0"
3140 [(set_attr "type" "cmove")])
3142 (define_insn "*movsf_cc_v9"
3143 [(set (match_operand:SF 0 "register_operand" "=f,f")
3144 (if_then_else:SF (match_operator 1 "comparison_operator"
3145 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
3147 (match_operand:SF 3 "register_operand" "f,0")
3148 (match_operand:SF 4 "register_operand" "0,f")))]
3149 "TARGET_V9 && TARGET_FPU"
3151 fmovs%C1\t%x2, %3, %0
3152 fmovs%c1\t%x2, %4, %0"
3153 [(set_attr "type" "fpcmove")])
3155 (define_insn "*movsf_cc_reg_sp64"
3156 [(set (match_operand:SF 0 "register_operand" "=f,f")
3157 (if_then_else:SF (match_operator 1 "v9_register_compare_operator"
3158 [(match_operand:DI 2 "register_operand" "r,r")
3160 (match_operand:SF 3 "register_operand" "f,0")
3161 (match_operand:SF 4 "register_operand" "0,f")))]
3162 "TARGET_ARCH64 && TARGET_FPU"
3164 fmovrs%D1\t%2, %3, %0
3165 fmovrs%d1\t%2, %4, %0"
3166 [(set_attr "type" "fpcrmove")])
3168 ;; Named because invoked by movtf_cc_v9
3169 (define_insn "movdf_cc_v9"
3170 [(set (match_operand:DF 0 "register_operand" "=e,e")
3171 (if_then_else:DF (match_operator 1 "comparison_operator"
3172 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
3174 (match_operand:DF 3 "register_operand" "e,0")
3175 (match_operand:DF 4 "register_operand" "0,e")))]
3176 "TARGET_V9 && TARGET_FPU"
3178 fmovd%C1\t%x2, %3, %0
3179 fmovd%c1\t%x2, %4, %0"
3180 [(set_attr "type" "fpcmove")
3181 (set_attr "fptype" "double")])
3183 ;; Named because invoked by movtf_cc_reg_sp64
3184 (define_insn "movdf_cc_reg_sp64"
3185 [(set (match_operand:DF 0 "register_operand" "=e,e")
3186 (if_then_else:DF (match_operator 1 "v9_register_compare_operator"
3187 [(match_operand:DI 2 "register_operand" "r,r")
3189 (match_operand:DF 3 "register_operand" "e,0")
3190 (match_operand:DF 4 "register_operand" "0,e")))]
3191 "TARGET_ARCH64 && TARGET_FPU"
3193 fmovrd%D1\t%2, %3, %0
3194 fmovrd%d1\t%2, %4, %0"
3195 [(set_attr "type" "fpcrmove")
3196 (set_attr "fptype" "double")])
3198 (define_insn "*movtf_cc_hq_v9"
3199 [(set (match_operand:TF 0 "register_operand" "=e,e")
3200 (if_then_else:TF (match_operator 1 "comparison_operator"
3201 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
3203 (match_operand:TF 3 "register_operand" "e,0")
3204 (match_operand:TF 4 "register_operand" "0,e")))]
3205 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
3207 fmovq%C1\t%x2, %3, %0
3208 fmovq%c1\t%x2, %4, %0"
3209 [(set_attr "type" "fpcmove")])
3211 (define_insn "*movtf_cc_reg_hq_sp64"
3212 [(set (match_operand:TF 0 "register_operand" "=e,e")
3213 (if_then_else:TF (match_operator 1 "v9_register_compare_operator"
3214 [(match_operand:DI 2 "register_operand" "r,r")
3216 (match_operand:TF 3 "register_operand" "e,0")
3217 (match_operand:TF 4 "register_operand" "0,e")))]
3218 "TARGET_ARCH64 && TARGET_FPU && TARGET_HARD_QUAD"
3220 fmovrq%D1\t%2, %3, %0
3221 fmovrq%d1\t%2, %4, %0"
3222 [(set_attr "type" "fpcrmove")])
3224 (define_insn_and_split "*movtf_cc_v9"
3225 [(set (match_operand:TF 0 "register_operand" "=e,e")
3226 (if_then_else:TF (match_operator 1 "comparison_operator"
3227 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
3229 (match_operand:TF 3 "register_operand" "e,0")
3230 (match_operand:TF 4 "register_operand" "0,e")))]
3231 "TARGET_V9 && TARGET_FPU && !TARGET_HARD_QUAD"
3233 "&& reload_completed"
3234 [(clobber (const_int 0))]
3236 rtx set_dest = operands[0];
3237 rtx set_srca = operands[3];
3238 rtx set_srcb = operands[4];
3239 int third = rtx_equal_p (set_dest, set_srca);
3241 rtx srca1, srca2, srcb1, srcb2;
3243 dest1 = gen_df_reg (set_dest, 0);
3244 dest2 = gen_df_reg (set_dest, 1);
3245 srca1 = gen_df_reg (set_srca, 0);
3246 srca2 = gen_df_reg (set_srca, 1);
3247 srcb1 = gen_df_reg (set_srcb, 0);
3248 srcb2 = gen_df_reg (set_srcb, 1);
3250 /* Now emit using the real source and destination we found, swapping
3251 the order if we detect overlap. */
3252 if ((third && reg_overlap_mentioned_p (dest1, srcb2))
3253 || (!third && reg_overlap_mentioned_p (dest1, srca2)))
3255 emit_insn (gen_movdf_cc_v9 (dest2, operands[1], operands[2], srca2, srcb2));
3256 emit_insn (gen_movdf_cc_v9 (dest1, operands[1], operands[2], srca1, srcb1));
3260 emit_insn (gen_movdf_cc_v9 (dest1, operands[1], operands[2], srca1, srcb1));
3261 emit_insn (gen_movdf_cc_v9 (dest2, operands[1], operands[2], srca2, srcb2));
3265 [(set_attr "length" "2")])
3267 (define_insn_and_split "*movtf_cc_reg_sp64"
3268 [(set (match_operand:TF 0 "register_operand" "=e,e")
3269 (if_then_else:TF (match_operator 1 "v9_register_compare_operator"
3270 [(match_operand:DI 2 "register_operand" "r,r")
3272 (match_operand:TF 3 "register_operand" "e,0")
3273 (match_operand:TF 4 "register_operand" "0,e")))]
3274 "TARGET_ARCH64 && TARGET_FPU && ! TARGET_HARD_QUAD"
3276 "&& reload_completed"
3277 [(clobber (const_int 0))]
3279 rtx set_dest = operands[0];
3280 rtx set_srca = operands[3];
3281 rtx set_srcb = operands[4];
3282 int third = rtx_equal_p (set_dest, set_srca);
3284 rtx srca1, srca2, srcb1, srcb2;
3286 dest1 = gen_df_reg (set_dest, 0);
3287 dest2 = gen_df_reg (set_dest, 1);
3288 srca1 = gen_df_reg (set_srca, 0);
3289 srca2 = gen_df_reg (set_srca, 1);
3290 srcb1 = gen_df_reg (set_srcb, 0);
3291 srcb2 = gen_df_reg (set_srcb, 1);
3293 /* Now emit using the real source and destination we found, swapping
3294 the order if we detect overlap. */
3295 if ((third && reg_overlap_mentioned_p (dest1, srcb2))
3296 || (!third && reg_overlap_mentioned_p (dest1, srca2)))
3298 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
3299 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
3303 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
3304 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
3308 [(set_attr "length" "2")])
3311 ;; Zero-extension instructions
3313 ;; These patterns originally accepted general_operands, however, slightly
3314 ;; better code is generated by only accepting register_operands, and then
3315 ;; letting combine generate the ldu[hb] insns.
3317 (define_expand "zero_extendhisi2"
3318 [(set (match_operand:SI 0 "register_operand" "")
3319 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
3322 rtx temp = gen_reg_rtx (SImode);
3323 rtx shift_16 = GEN_INT (16);
3324 int op1_subbyte = 0;
3326 if (GET_CODE (operand1) == SUBREG)
3328 op1_subbyte = SUBREG_BYTE (operand1);
3329 op1_subbyte /= GET_MODE_SIZE (SImode);
3330 op1_subbyte *= GET_MODE_SIZE (SImode);
3331 operand1 = XEXP (operand1, 0);
3334 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3336 emit_insn (gen_lshrsi3 (operand0, temp, shift_16));
3340 (define_insn "*zero_extendhisi2_insn"
3341 [(set (match_operand:SI 0 "register_operand" "=r")
3342 (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
3345 [(set_attr "type" "load")
3346 (set_attr "us3load_type" "3cycle")])
3348 (define_expand "zero_extendqihi2"
3349 [(set (match_operand:HI 0 "register_operand" "")
3350 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
3354 (define_insn "*zero_extendqihi2_insn"
3355 [(set (match_operand:HI 0 "register_operand" "=r,r")
3356 (zero_extend:HI (match_operand:QI 1 "input_operand" "r,m")))]
3357 "GET_CODE (operands[1]) != CONST_INT"
3361 [(set_attr "type" "*,load")
3362 (set_attr "us3load_type" "*,3cycle")])
3364 (define_expand "zero_extendqisi2"
3365 [(set (match_operand:SI 0 "register_operand" "")
3366 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
3370 (define_insn "*zero_extendqisi2_insn"
3371 [(set (match_operand:SI 0 "register_operand" "=r,r")
3372 (zero_extend:SI (match_operand:QI 1 "input_operand" "r,m")))]
3373 "GET_CODE (operands[1]) != CONST_INT"
3377 [(set_attr "type" "*,load")
3378 (set_attr "us3load_type" "*,3cycle")])
3380 (define_expand "zero_extendqidi2"
3381 [(set (match_operand:DI 0 "register_operand" "")
3382 (zero_extend:DI (match_operand:QI 1 "register_operand" "")))]
3386 (define_insn "*zero_extendqidi2_insn"
3387 [(set (match_operand:DI 0 "register_operand" "=r,r")
3388 (zero_extend:DI (match_operand:QI 1 "input_operand" "r,m")))]
3389 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
3393 [(set_attr "type" "*,load")
3394 (set_attr "us3load_type" "*,3cycle")])
3396 (define_expand "zero_extendhidi2"
3397 [(set (match_operand:DI 0 "register_operand" "")
3398 (zero_extend:DI (match_operand:HI 1 "register_operand" "")))]
3401 rtx temp = gen_reg_rtx (DImode);
3402 rtx shift_48 = GEN_INT (48);
3403 int op1_subbyte = 0;
3405 if (GET_CODE (operand1) == SUBREG)
3407 op1_subbyte = SUBREG_BYTE (operand1);
3408 op1_subbyte /= GET_MODE_SIZE (DImode);
3409 op1_subbyte *= GET_MODE_SIZE (DImode);
3410 operand1 = XEXP (operand1, 0);
3413 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
3415 emit_insn (gen_lshrdi3 (operand0, temp, shift_48));
3419 (define_insn "*zero_extendhidi2_insn"
3420 [(set (match_operand:DI 0 "register_operand" "=r")
3421 (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
3424 [(set_attr "type" "load")
3425 (set_attr "us3load_type" "3cycle")])
3427 ;; ??? Write truncdisi pattern using sra?
3429 (define_expand "zero_extendsidi2"
3430 [(set (match_operand:DI 0 "register_operand" "")
3431 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
3435 (define_insn "*zero_extendsidi2_insn_sp64"
3436 [(set (match_operand:DI 0 "register_operand" "=r,r")
3437 (zero_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
3438 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
3442 [(set_attr "type" "shift,load")])
3444 (define_insn_and_split "*zero_extendsidi2_insn_sp32"
3445 [(set (match_operand:DI 0 "register_operand" "=r")
3446 (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
3449 "&& reload_completed"
3450 [(set (match_dup 2) (match_dup 3))
3451 (set (match_dup 4) (match_dup 5))]
3455 dest1 = gen_highpart (SImode, operands[0]);
3456 dest2 = gen_lowpart (SImode, operands[0]);
3458 /* Swap the order in case of overlap. */
3459 if (REGNO (dest1) == REGNO (operands[1]))
3461 operands[2] = dest2;
3462 operands[3] = operands[1];
3463 operands[4] = dest1;
3464 operands[5] = const0_rtx;
3468 operands[2] = dest1;
3469 operands[3] = const0_rtx;
3470 operands[4] = dest2;
3471 operands[5] = operands[1];
3474 [(set_attr "length" "2")])
3476 ;; Simplify comparisons of extended values.
3478 (define_insn "*cmp_zero_extendqisi2"
3480 (compare:CC (zero_extend:SI (match_operand:QI 0 "register_operand" "r"))
3483 "andcc\t%0, 0xff, %%g0"
3484 [(set_attr "type" "compare")])
3486 (define_insn "*cmp_zero_qi"
3488 (compare:CC (match_operand:QI 0 "register_operand" "r")
3491 "andcc\t%0, 0xff, %%g0"
3492 [(set_attr "type" "compare")])
3494 (define_insn "*cmp_zero_extendqisi2_set"
3496 (compare:CC (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
3498 (set (match_operand:SI 0 "register_operand" "=r")
3499 (zero_extend:SI (match_dup 1)))]
3501 "andcc\t%1, 0xff, %0"
3502 [(set_attr "type" "compare")])
3504 (define_insn "*cmp_zero_extendqisi2_andcc_set"
3506 (compare:CC (and:SI (match_operand:SI 1 "register_operand" "r")
3509 (set (match_operand:SI 0 "register_operand" "=r")
3510 (zero_extend:SI (subreg:QI (match_dup 1) 0)))]
3512 "andcc\t%1, 0xff, %0"
3513 [(set_attr "type" "compare")])
3515 (define_insn "*cmp_zero_extendqidi2"
3517 (compare:CCX (zero_extend:DI (match_operand:QI 0 "register_operand" "r"))
3520 "andcc\t%0, 0xff, %%g0"
3521 [(set_attr "type" "compare")])
3523 (define_insn "*cmp_zero_qi_sp64"
3525 (compare:CCX (match_operand:QI 0 "register_operand" "r")
3528 "andcc\t%0, 0xff, %%g0"
3529 [(set_attr "type" "compare")])
3531 (define_insn "*cmp_zero_extendqidi2_set"
3533 (compare:CCX (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
3535 (set (match_operand:DI 0 "register_operand" "=r")
3536 (zero_extend:DI (match_dup 1)))]
3538 "andcc\t%1, 0xff, %0"
3539 [(set_attr "type" "compare")])
3541 (define_insn "*cmp_zero_extendqidi2_andcc_set"
3543 (compare:CCX (and:DI (match_operand:DI 1 "register_operand" "r")
3546 (set (match_operand:DI 0 "register_operand" "=r")
3547 (zero_extend:DI (subreg:QI (match_dup 1) 0)))]
3549 "andcc\t%1, 0xff, %0"
3550 [(set_attr "type" "compare")])
3552 ;; Similarly, handle {SI,DI}->QI mode truncation followed by a compare.
3554 (define_insn "*cmp_siqi_trunc"
3556 (compare:CC (subreg:QI (match_operand:SI 0 "register_operand" "r") 3)
3559 "andcc\t%0, 0xff, %%g0"
3560 [(set_attr "type" "compare")])
3562 (define_insn "*cmp_siqi_trunc_set"
3564 (compare:CC (subreg:QI (match_operand:SI 1 "register_operand" "r") 3)
3566 (set (match_operand:QI 0 "register_operand" "=r")
3567 (subreg:QI (match_dup 1) 3))]
3569 "andcc\t%1, 0xff, %0"
3570 [(set_attr "type" "compare")])
3572 (define_insn "*cmp_diqi_trunc"
3574 (compare:CC (subreg:QI (match_operand:DI 0 "register_operand" "r") 7)
3577 "andcc\t%0, 0xff, %%g0"
3578 [(set_attr "type" "compare")])
3580 (define_insn "*cmp_diqi_trunc_set"
3582 (compare:CC (subreg:QI (match_operand:DI 1 "register_operand" "r") 7)
3584 (set (match_operand:QI 0 "register_operand" "=r")
3585 (subreg:QI (match_dup 1) 7))]
3587 "andcc\t%1, 0xff, %0"
3588 [(set_attr "type" "compare")])
3591 ;; Sign-extension instructions
3593 ;; These patterns originally accepted general_operands, however, slightly
3594 ;; better code is generated by only accepting register_operands, and then
3595 ;; letting combine generate the lds[hb] insns.
3597 (define_expand "extendhisi2"
3598 [(set (match_operand:SI 0 "register_operand" "")
3599 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
3602 rtx temp = gen_reg_rtx (SImode);
3603 rtx shift_16 = GEN_INT (16);
3604 int op1_subbyte = 0;
3606 if (GET_CODE (operand1) == SUBREG)
3608 op1_subbyte = SUBREG_BYTE (operand1);
3609 op1_subbyte /= GET_MODE_SIZE (SImode);
3610 op1_subbyte *= GET_MODE_SIZE (SImode);
3611 operand1 = XEXP (operand1, 0);
3614 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3616 emit_insn (gen_ashrsi3 (operand0, temp, shift_16));
3620 (define_insn "*sign_extendhisi2_insn"
3621 [(set (match_operand:SI 0 "register_operand" "=r")
3622 (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
3625 [(set_attr "type" "sload")
3626 (set_attr "us3load_type" "3cycle")])
3628 (define_expand "extendqihi2"
3629 [(set (match_operand:HI 0 "register_operand" "")
3630 (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
3633 rtx temp = gen_reg_rtx (SImode);
3634 rtx shift_24 = GEN_INT (24);
3635 int op1_subbyte = 0;
3636 int op0_subbyte = 0;
3638 if (GET_CODE (operand1) == SUBREG)
3640 op1_subbyte = SUBREG_BYTE (operand1);
3641 op1_subbyte /= GET_MODE_SIZE (SImode);
3642 op1_subbyte *= GET_MODE_SIZE (SImode);
3643 operand1 = XEXP (operand1, 0);
3645 if (GET_CODE (operand0) == SUBREG)
3647 op0_subbyte = SUBREG_BYTE (operand0);
3648 op0_subbyte /= GET_MODE_SIZE (SImode);
3649 op0_subbyte *= GET_MODE_SIZE (SImode);
3650 operand0 = XEXP (operand0, 0);
3652 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3654 if (GET_MODE (operand0) != SImode)
3655 operand0 = gen_rtx_SUBREG (SImode, operand0, op0_subbyte);
3656 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
3660 (define_insn "*sign_extendqihi2_insn"
3661 [(set (match_operand:HI 0 "register_operand" "=r")
3662 (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
3665 [(set_attr "type" "sload")
3666 (set_attr "us3load_type" "3cycle")])
3668 (define_expand "extendqisi2"
3669 [(set (match_operand:SI 0 "register_operand" "")
3670 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
3673 rtx temp = gen_reg_rtx (SImode);
3674 rtx shift_24 = GEN_INT (24);
3675 int op1_subbyte = 0;
3677 if (GET_CODE (operand1) == SUBREG)
3679 op1_subbyte = SUBREG_BYTE (operand1);
3680 op1_subbyte /= GET_MODE_SIZE (SImode);
3681 op1_subbyte *= GET_MODE_SIZE (SImode);
3682 operand1 = XEXP (operand1, 0);
3685 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3687 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
3691 (define_insn "*sign_extendqisi2_insn"
3692 [(set (match_operand:SI 0 "register_operand" "=r")
3693 (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
3696 [(set_attr "type" "sload")
3697 (set_attr "us3load_type" "3cycle")])
3699 (define_expand "extendqidi2"
3700 [(set (match_operand:DI 0 "register_operand" "")
3701 (sign_extend:DI (match_operand:QI 1 "register_operand" "")))]
3704 rtx temp = gen_reg_rtx (DImode);
3705 rtx shift_56 = GEN_INT (56);
3706 int op1_subbyte = 0;
3708 if (GET_CODE (operand1) == SUBREG)
3710 op1_subbyte = SUBREG_BYTE (operand1);
3711 op1_subbyte /= GET_MODE_SIZE (DImode);
3712 op1_subbyte *= GET_MODE_SIZE (DImode);
3713 operand1 = XEXP (operand1, 0);
3716 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
3718 emit_insn (gen_ashrdi3 (operand0, temp, shift_56));
3722 (define_insn "*sign_extendqidi2_insn"
3723 [(set (match_operand:DI 0 "register_operand" "=r")
3724 (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
3727 [(set_attr "type" "sload")
3728 (set_attr "us3load_type" "3cycle")])
3730 (define_expand "extendhidi2"
3731 [(set (match_operand:DI 0 "register_operand" "")
3732 (sign_extend:DI (match_operand:HI 1 "register_operand" "")))]
3735 rtx temp = gen_reg_rtx (DImode);
3736 rtx shift_48 = GEN_INT (48);
3737 int op1_subbyte = 0;
3739 if (GET_CODE (operand1) == SUBREG)
3741 op1_subbyte = SUBREG_BYTE (operand1);
3742 op1_subbyte /= GET_MODE_SIZE (DImode);
3743 op1_subbyte *= GET_MODE_SIZE (DImode);
3744 operand1 = XEXP (operand1, 0);
3747 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
3749 emit_insn (gen_ashrdi3 (operand0, temp, shift_48));
3753 (define_insn "*sign_extendhidi2_insn"
3754 [(set (match_operand:DI 0 "register_operand" "=r")
3755 (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
3758 [(set_attr "type" "sload")
3759 (set_attr "us3load_type" "3cycle")])
3761 (define_expand "extendsidi2"
3762 [(set (match_operand:DI 0 "register_operand" "")
3763 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
3767 (define_insn "*sign_extendsidi2_insn"
3768 [(set (match_operand:DI 0 "register_operand" "=r,r")
3769 (sign_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
3774 [(set_attr "type" "shift,sload")
3775 (set_attr "us3load_type" "*,3cycle")])
3778 ;; Special pattern for optimizing bit-field compares. This is needed
3779 ;; because combine uses this as a canonical form.
3781 (define_insn "*cmp_zero_extract"
3784 (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
3785 (match_operand:SI 1 "small_int_operand" "I")
3786 (match_operand:SI 2 "small_int_operand" "I"))
3788 "INTVAL (operands[2]) > 19"
3790 int len = INTVAL (operands[1]);
3791 int pos = 32 - INTVAL (operands[2]) - len;
3792 HOST_WIDE_INT mask = ((1 << len) - 1) << pos;
3793 operands[1] = GEN_INT (mask);
3794 return "andcc\t%0, %1, %%g0";
3796 [(set_attr "type" "compare")])
3798 (define_insn "*cmp_zero_extract_sp64"
3801 (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
3802 (match_operand:SI 1 "small_int_operand" "I")
3803 (match_operand:SI 2 "small_int_operand" "I"))
3805 "TARGET_ARCH64 && INTVAL (operands[2]) > 51"
3807 int len = INTVAL (operands[1]);
3808 int pos = 64 - INTVAL (operands[2]) - len;
3809 HOST_WIDE_INT mask = (((unsigned HOST_WIDE_INT) 1 << len) - 1) << pos;
3810 operands[1] = GEN_INT (mask);
3811 return "andcc\t%0, %1, %%g0";
3813 [(set_attr "type" "compare")])
3816 ;; Conversions between float, double and long double.
3818 (define_insn "extendsfdf2"
3819 [(set (match_operand:DF 0 "register_operand" "=e")
3821 (match_operand:SF 1 "register_operand" "f")))]
3824 [(set_attr "type" "fp")
3825 (set_attr "fptype" "double")])
3827 (define_expand "extendsftf2"
3828 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3830 (match_operand:SF 1 "register_operand" "")))]
3831 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3832 "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
3834 (define_insn "*extendsftf2_hq"
3835 [(set (match_operand:TF 0 "register_operand" "=e")
3837 (match_operand:SF 1 "register_operand" "f")))]
3838 "TARGET_FPU && TARGET_HARD_QUAD"
3840 [(set_attr "type" "fp")])
3842 (define_expand "extenddftf2"
3843 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3845 (match_operand:DF 1 "register_operand" "")))]
3846 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3847 "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
3849 (define_insn "*extenddftf2_hq"
3850 [(set (match_operand:TF 0 "register_operand" "=e")
3852 (match_operand:DF 1 "register_operand" "e")))]
3853 "TARGET_FPU && TARGET_HARD_QUAD"
3855 [(set_attr "type" "fp")])
3857 (define_insn "truncdfsf2"
3858 [(set (match_operand:SF 0 "register_operand" "=f")
3860 (match_operand:DF 1 "register_operand" "e")))]
3863 [(set_attr "type" "fp")
3864 (set_attr "fptype" "double")])
3866 (define_expand "trunctfsf2"
3867 [(set (match_operand:SF 0 "register_operand" "")
3869 (match_operand:TF 1 "general_operand" "")))]
3870 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3871 "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
3873 (define_insn "*trunctfsf2_hq"
3874 [(set (match_operand:SF 0 "register_operand" "=f")
3876 (match_operand:TF 1 "register_operand" "e")))]
3877 "TARGET_FPU && TARGET_HARD_QUAD"
3879 [(set_attr "type" "fp")])
3881 (define_expand "trunctfdf2"
3882 [(set (match_operand:DF 0 "register_operand" "")
3884 (match_operand:TF 1 "general_operand" "")))]
3885 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3886 "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
3888 (define_insn "*trunctfdf2_hq"
3889 [(set (match_operand:DF 0 "register_operand" "=e")
3891 (match_operand:TF 1 "register_operand" "e")))]
3892 "TARGET_FPU && TARGET_HARD_QUAD"
3894 [(set_attr "type" "fp")])
3897 ;; Conversion between fixed point and floating point.
3899 (define_insn "floatsisf2"
3900 [(set (match_operand:SF 0 "register_operand" "=f")
3901 (float:SF (match_operand:SI 1 "register_operand" "f")))]
3904 [(set_attr "type" "fp")
3905 (set_attr "fptype" "double")])
3907 (define_insn "floatsidf2"
3908 [(set (match_operand:DF 0 "register_operand" "=e")
3909 (float:DF (match_operand:SI 1 "register_operand" "f")))]
3912 [(set_attr "type" "fp")
3913 (set_attr "fptype" "double")])
3915 (define_expand "floatsitf2"
3916 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3917 (float:TF (match_operand:SI 1 "register_operand" "")))]
3918 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3919 "emit_tfmode_cvt (FLOAT, operands); DONE;")
3921 (define_insn "*floatsitf2_hq"
3922 [(set (match_operand:TF 0 "register_operand" "=e")
3923 (float:TF (match_operand:SI 1 "register_operand" "f")))]
3924 "TARGET_FPU && TARGET_HARD_QUAD"
3926 [(set_attr "type" "fp")])
3928 (define_expand "floatunssitf2"
3929 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3930 (unsigned_float:TF (match_operand:SI 1 "register_operand" "")))]
3931 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3932 "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
3934 ;; Now the same for 64 bit sources.
3936 (define_insn "floatdisf2"
3937 [(set (match_operand:SF 0 "register_operand" "=f")
3938 (float:SF (match_operand:DI 1 "register_operand" "e")))]
3939 "TARGET_V9 && TARGET_FPU"
3941 [(set_attr "type" "fp")
3942 (set_attr "fptype" "double")])
3944 (define_expand "floatunsdisf2"
3945 [(use (match_operand:SF 0 "register_operand" ""))
3946 (use (match_operand:DI 1 "general_operand" ""))]
3947 "TARGET_ARCH64 && TARGET_FPU"
3948 "sparc_emit_floatunsdi (operands, SFmode); DONE;")
3950 (define_insn "floatdidf2"
3951 [(set (match_operand:DF 0 "register_operand" "=e")
3952 (float:DF (match_operand:DI 1 "register_operand" "e")))]
3953 "TARGET_V9 && TARGET_FPU"
3955 [(set_attr "type" "fp")
3956 (set_attr "fptype" "double")])
3958 (define_expand "floatunsdidf2"
3959 [(use (match_operand:DF 0 "register_operand" ""))
3960 (use (match_operand:DI 1 "general_operand" ""))]
3961 "TARGET_ARCH64 && TARGET_FPU"
3962 "sparc_emit_floatunsdi (operands, DFmode); DONE;")
3964 (define_expand "floatditf2"
3965 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3966 (float:TF (match_operand:DI 1 "register_operand" "")))]
3967 "TARGET_FPU && TARGET_V9 && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3968 "emit_tfmode_cvt (FLOAT, operands); DONE;")
3970 (define_insn "*floatditf2_hq"
3971 [(set (match_operand:TF 0 "register_operand" "=e")
3972 (float:TF (match_operand:DI 1 "register_operand" "e")))]
3973 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
3975 [(set_attr "type" "fp")])
3977 (define_expand "floatunsditf2"
3978 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3979 (unsigned_float:TF (match_operand:DI 1 "register_operand" "")))]
3980 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3981 "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
3983 ;; Convert a float to an actual integer.
3984 ;; Truncation is performed as part of the conversion.
3986 (define_insn "fix_truncsfsi2"
3987 [(set (match_operand:SI 0 "register_operand" "=f")
3988 (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
3991 [(set_attr "type" "fp")
3992 (set_attr "fptype" "double")])
3994 (define_insn "fix_truncdfsi2"
3995 [(set (match_operand:SI 0 "register_operand" "=f")
3996 (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
3999 [(set_attr "type" "fp")
4000 (set_attr "fptype" "double")])
4002 (define_expand "fix_trunctfsi2"
4003 [(set (match_operand:SI 0 "register_operand" "")
4004 (fix:SI (match_operand:TF 1 "general_operand" "")))]
4005 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4006 "emit_tfmode_cvt (FIX, operands); DONE;")
4008 (define_insn "*fix_trunctfsi2_hq"
4009 [(set (match_operand:SI 0 "register_operand" "=f")
4010 (fix:SI (match_operand:TF 1 "register_operand" "e")))]
4011 "TARGET_FPU && TARGET_HARD_QUAD"
4013 [(set_attr "type" "fp")])
4015 (define_expand "fixuns_trunctfsi2"
4016 [(set (match_operand:SI 0 "register_operand" "")
4017 (unsigned_fix:SI (match_operand:TF 1 "general_operand" "")))]
4018 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4019 "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
4021 ;; Now the same, for V9 targets
4023 (define_insn "fix_truncsfdi2"
4024 [(set (match_operand:DI 0 "register_operand" "=e")
4025 (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
4026 "TARGET_V9 && TARGET_FPU"
4028 [(set_attr "type" "fp")
4029 (set_attr "fptype" "double")])
4031 (define_expand "fixuns_truncsfdi2"
4032 [(use (match_operand:DI 0 "register_operand" ""))
4033 (use (match_operand:SF 1 "general_operand" ""))]
4034 "TARGET_ARCH64 && TARGET_FPU"
4035 "sparc_emit_fixunsdi (operands, SFmode); DONE;")
4037 (define_insn "fix_truncdfdi2"
4038 [(set (match_operand:DI 0 "register_operand" "=e")
4039 (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
4040 "TARGET_V9 && TARGET_FPU"
4042 [(set_attr "type" "fp")
4043 (set_attr "fptype" "double")])
4045 (define_expand "fixuns_truncdfdi2"
4046 [(use (match_operand:DI 0 "register_operand" ""))
4047 (use (match_operand:DF 1 "general_operand" ""))]
4048 "TARGET_ARCH64 && TARGET_FPU"
4049 "sparc_emit_fixunsdi (operands, DFmode); DONE;")
4051 (define_expand "fix_trunctfdi2"
4052 [(set (match_operand:DI 0 "register_operand" "")
4053 (fix:DI (match_operand:TF 1 "general_operand" "")))]
4054 "TARGET_V9 && TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4055 "emit_tfmode_cvt (FIX, operands); DONE;")
4057 (define_insn "*fix_trunctfdi2_hq"
4058 [(set (match_operand:DI 0 "register_operand" "=e")
4059 (fix:DI (match_operand:TF 1 "register_operand" "e")))]
4060 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
4062 [(set_attr "type" "fp")])
4064 (define_expand "fixuns_trunctfdi2"
4065 [(set (match_operand:DI 0 "register_operand" "")
4066 (unsigned_fix:DI (match_operand:TF 1 "general_operand" "")))]
4067 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4068 "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
4071 ;; Integer addition/subtraction instructions.
4073 (define_expand "adddi3"
4074 [(set (match_operand:DI 0 "register_operand" "")
4075 (plus:DI (match_operand:DI 1 "register_operand" "")
4076 (match_operand:DI 2 "arith_double_add_operand" "")))]
4079 if (! TARGET_ARCH64)
4081 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
4082 gen_rtx_SET (VOIDmode, operands[0],
4083 gen_rtx_PLUS (DImode, operands[1],
4085 gen_rtx_CLOBBER (VOIDmode,
4086 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
4091 (define_insn_and_split "adddi3_insn_sp32"
4092 [(set (match_operand:DI 0 "register_operand" "=r")
4093 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
4094 (match_operand:DI 2 "arith_double_operand" "rHI")))
4095 (clobber (reg:CC 100))]
4098 "&& reload_completed"
4099 [(parallel [(set (reg:CC_NOOV 100)
4100 (compare:CC_NOOV (plus:SI (match_dup 4)
4104 (plus:SI (match_dup 4) (match_dup 5)))])
4106 (plus:SI (plus:SI (match_dup 7)
4108 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4110 operands[3] = gen_lowpart (SImode, operands[0]);
4111 operands[4] = gen_lowpart (SImode, operands[1]);
4112 operands[5] = gen_lowpart (SImode, operands[2]);
4113 operands[6] = gen_highpart (SImode, operands[0]);
4114 operands[7] = gen_highpart_mode (SImode, DImode, operands[1]);
4115 #if HOST_BITS_PER_WIDE_INT == 32
4116 if (GET_CODE (operands[2]) == CONST_INT)
4118 if (INTVAL (operands[2]) < 0)
4119 operands[8] = constm1_rtx;
4121 operands[8] = const0_rtx;
4125 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
4127 [(set_attr "length" "2")])
4129 ;; LTU here means "carry set"
4131 [(set (match_operand:SI 0 "register_operand" "=r")
4132 (plus:SI (plus:SI (match_operand:SI 1 "arith_operand" "%r")
4133 (match_operand:SI 2 "arith_operand" "rI"))
4134 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4137 [(set_attr "type" "ialuX")])
4139 (define_insn_and_split "*addx_extend_sp32"
4140 [(set (match_operand:DI 0 "register_operand" "=r")
4141 (zero_extend:DI (plus:SI (plus:SI
4142 (match_operand:SI 1 "register_or_zero_operand" "%rJ")
4143 (match_operand:SI 2 "arith_operand" "rI"))
4144 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4147 "&& reload_completed"
4148 [(set (match_dup 3) (plus:SI (plus:SI (match_dup 1) (match_dup 2))
4149 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
4150 (set (match_dup 4) (const_int 0))]
4151 "operands[3] = gen_lowpart (SImode, operands[0]);
4152 operands[4] = gen_highpart_mode (SImode, DImode, operands[1]);"
4153 [(set_attr "length" "2")])
4155 (define_insn "*addx_extend_sp64"
4156 [(set (match_operand:DI 0 "register_operand" "=r")
4157 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ")
4158 (match_operand:SI 2 "arith_operand" "rI"))
4159 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4162 [(set_attr "type" "ialuX")])
4164 (define_insn_and_split ""
4165 [(set (match_operand:DI 0 "register_operand" "=r")
4166 (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4167 (match_operand:DI 2 "register_operand" "r")))
4168 (clobber (reg:CC 100))]
4171 "&& reload_completed"
4172 [(parallel [(set (reg:CC_NOOV 100)
4173 (compare:CC_NOOV (plus:SI (match_dup 3) (match_dup 1))
4175 (set (match_dup 5) (plus:SI (match_dup 3) (match_dup 1)))])
4177 (plus:SI (plus:SI (match_dup 4) (const_int 0))
4178 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4179 "operands[3] = gen_lowpart (SImode, operands[2]);
4180 operands[4] = gen_highpart (SImode, operands[2]);
4181 operands[5] = gen_lowpart (SImode, operands[0]);
4182 operands[6] = gen_highpart (SImode, operands[0]);"
4183 [(set_attr "length" "2")])
4185 (define_insn "*adddi3_sp64"
4186 [(set (match_operand:DI 0 "register_operand" "=r,r")
4187 (plus:DI (match_operand:DI 1 "register_operand" "%r,r")
4188 (match_operand:DI 2 "arith_add_operand" "rI,O")))]
4194 (define_insn "addsi3"
4195 [(set (match_operand:SI 0 "register_operand" "=r,r,d")
4196 (plus:SI (match_operand:SI 1 "register_operand" "%r,r,d")
4197 (match_operand:SI 2 "arith_add_operand" "rI,O,d")))]
4202 fpadd32s\t%1, %2, %0"
4203 [(set_attr "type" "*,*,fga")
4204 (set_attr "fptype" "*,*,single")])
4206 (define_insn "*cmp_cc_plus"
4207 [(set (reg:CC_NOOV 100)
4208 (compare:CC_NOOV (plus:SI (match_operand:SI 0 "arith_operand" "%r")
4209 (match_operand:SI 1 "arith_operand" "rI"))
4212 "addcc\t%0, %1, %%g0"
4213 [(set_attr "type" "compare")])
4215 (define_insn "*cmp_ccx_plus"
4216 [(set (reg:CCX_NOOV 100)
4217 (compare:CCX_NOOV (plus:DI (match_operand:DI 0 "arith_operand" "%r")
4218 (match_operand:DI 1 "arith_operand" "rI"))
4221 "addcc\t%0, %1, %%g0"
4222 [(set_attr "type" "compare")])
4224 (define_insn "*cmp_cc_plus_set"
4225 [(set (reg:CC_NOOV 100)
4226 (compare:CC_NOOV (plus:SI (match_operand:SI 1 "arith_operand" "%r")
4227 (match_operand:SI 2 "arith_operand" "rI"))
4229 (set (match_operand:SI 0 "register_operand" "=r")
4230 (plus:SI (match_dup 1) (match_dup 2)))]
4233 [(set_attr "type" "compare")])
4235 (define_insn "*cmp_ccx_plus_set"
4236 [(set (reg:CCX_NOOV 100)
4237 (compare:CCX_NOOV (plus:DI (match_operand:DI 1 "arith_operand" "%r")
4238 (match_operand:DI 2 "arith_operand" "rI"))
4240 (set (match_operand:DI 0 "register_operand" "=r")
4241 (plus:DI (match_dup 1) (match_dup 2)))]
4244 [(set_attr "type" "compare")])
4246 (define_expand "subdi3"
4247 [(set (match_operand:DI 0 "register_operand" "")
4248 (minus:DI (match_operand:DI 1 "register_operand" "")
4249 (match_operand:DI 2 "arith_double_add_operand" "")))]
4252 if (! TARGET_ARCH64)
4254 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
4255 gen_rtx_SET (VOIDmode, operands[0],
4256 gen_rtx_MINUS (DImode, operands[1],
4258 gen_rtx_CLOBBER (VOIDmode,
4259 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
4264 (define_insn_and_split "subdi3_insn_sp32"
4265 [(set (match_operand:DI 0 "register_operand" "=r")
4266 (minus:DI (match_operand:DI 1 "register_operand" "r")
4267 (match_operand:DI 2 "arith_double_operand" "rHI")))
4268 (clobber (reg:CC 100))]
4271 "&& reload_completed"
4272 [(parallel [(set (reg:CC_NOOV 100)
4273 (compare:CC_NOOV (minus:SI (match_dup 4)
4277 (minus:SI (match_dup 4) (match_dup 5)))])
4279 (minus:SI (minus:SI (match_dup 7)
4281 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4283 operands[3] = gen_lowpart (SImode, operands[0]);
4284 operands[4] = gen_lowpart (SImode, operands[1]);
4285 operands[5] = gen_lowpart (SImode, operands[2]);
4286 operands[6] = gen_highpart (SImode, operands[0]);
4287 operands[7] = gen_highpart (SImode, operands[1]);
4288 #if HOST_BITS_PER_WIDE_INT == 32
4289 if (GET_CODE (operands[2]) == CONST_INT)
4291 if (INTVAL (operands[2]) < 0)
4292 operands[8] = constm1_rtx;
4294 operands[8] = const0_rtx;
4298 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
4300 [(set_attr "length" "2")])
4302 ;; LTU here means "carry set"
4304 [(set (match_operand:SI 0 "register_operand" "=r")
4305 (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
4306 (match_operand:SI 2 "arith_operand" "rI"))
4307 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4310 [(set_attr "type" "ialuX")])
4312 (define_insn "*subx_extend_sp64"
4313 [(set (match_operand:DI 0 "register_operand" "=r")
4314 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
4315 (match_operand:SI 2 "arith_operand" "rI"))
4316 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4319 [(set_attr "type" "ialuX")])
4321 (define_insn_and_split "*subx_extend"
4322 [(set (match_operand:DI 0 "register_operand" "=r")
4323 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
4324 (match_operand:SI 2 "arith_operand" "rI"))
4325 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4328 "&& reload_completed"
4329 [(set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 2))
4330 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
4331 (set (match_dup 4) (const_int 0))]
4332 "operands[3] = gen_lowpart (SImode, operands[0]);
4333 operands[4] = gen_highpart (SImode, operands[0]);"
4334 [(set_attr "length" "2")])
4336 (define_insn_and_split ""
4337 [(set (match_operand:DI 0 "register_operand" "=r")
4338 (minus:DI (match_operand:DI 1 "register_operand" "r")
4339 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))
4340 (clobber (reg:CC 100))]
4343 "&& reload_completed"
4344 [(parallel [(set (reg:CC_NOOV 100)
4345 (compare:CC_NOOV (minus:SI (match_dup 3) (match_dup 2))
4347 (set (match_dup 5) (minus:SI (match_dup 3) (match_dup 2)))])
4349 (minus:SI (minus:SI (match_dup 4) (const_int 0))
4350 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4351 "operands[3] = gen_lowpart (SImode, operands[1]);
4352 operands[4] = gen_highpart (SImode, operands[1]);
4353 operands[5] = gen_lowpart (SImode, operands[0]);
4354 operands[6] = gen_highpart (SImode, operands[0]);"
4355 [(set_attr "length" "2")])
4357 (define_insn "*subdi3_sp64"
4358 [(set (match_operand:DI 0 "register_operand" "=r,r")
4359 (minus:DI (match_operand:DI 1 "register_operand" "r,r")
4360 (match_operand:DI 2 "arith_add_operand" "rI,O")))]
4366 (define_insn "subsi3"
4367 [(set (match_operand:SI 0 "register_operand" "=r,r,d")
4368 (minus:SI (match_operand:SI 1 "register_operand" "r,r,d")
4369 (match_operand:SI 2 "arith_add_operand" "rI,O,d")))]
4374 fpsub32s\t%1, %2, %0"
4375 [(set_attr "type" "*,*,fga")
4376 (set_attr "fptype" "*,*,single")])
4378 (define_insn "*cmp_minus_cc"
4379 [(set (reg:CC_NOOV 100)
4380 (compare:CC_NOOV (minus:SI (match_operand:SI 0 "register_or_zero_operand" "rJ")
4381 (match_operand:SI 1 "arith_operand" "rI"))
4384 "subcc\t%r0, %1, %%g0"
4385 [(set_attr "type" "compare")])
4387 (define_insn "*cmp_minus_ccx"
4388 [(set (reg:CCX_NOOV 100)
4389 (compare:CCX_NOOV (minus:DI (match_operand:DI 0 "register_operand" "r")
4390 (match_operand:DI 1 "arith_operand" "rI"))
4393 "subcc\t%0, %1, %%g0"
4394 [(set_attr "type" "compare")])
4396 (define_insn "cmp_minus_cc_set"
4397 [(set (reg:CC_NOOV 100)
4398 (compare:CC_NOOV (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
4399 (match_operand:SI 2 "arith_operand" "rI"))
4401 (set (match_operand:SI 0 "register_operand" "=r")
4402 (minus:SI (match_dup 1) (match_dup 2)))]
4404 "subcc\t%r1, %2, %0"
4405 [(set_attr "type" "compare")])
4407 (define_insn "*cmp_minus_ccx_set"
4408 [(set (reg:CCX_NOOV 100)
4409 (compare:CCX_NOOV (minus:DI (match_operand:DI 1 "register_operand" "r")
4410 (match_operand:DI 2 "arith_operand" "rI"))
4412 (set (match_operand:DI 0 "register_operand" "=r")
4413 (minus:DI (match_dup 1) (match_dup 2)))]
4416 [(set_attr "type" "compare")])
4419 ;; Integer multiply/divide instructions.
4421 ;; The 32-bit multiply/divide instructions are deprecated on v9, but at
4422 ;; least in UltraSPARC I, II and IIi it is a win tick-wise.
4424 (define_insn "mulsi3"
4425 [(set (match_operand:SI 0 "register_operand" "=r")
4426 (mult:SI (match_operand:SI 1 "arith_operand" "%r")
4427 (match_operand:SI 2 "arith_operand" "rI")))]
4430 [(set_attr "type" "imul")])
4432 (define_expand "muldi3"
4433 [(set (match_operand:DI 0 "register_operand" "")
4434 (mult:DI (match_operand:DI 1 "arith_operand" "")
4435 (match_operand:DI 2 "arith_operand" "")))]
4436 "TARGET_ARCH64 || TARGET_V8PLUS"
4440 emit_insn (gen_muldi3_v8plus (operands[0], operands[1], operands[2]));
4445 (define_insn "*muldi3_sp64"
4446 [(set (match_operand:DI 0 "register_operand" "=r")
4447 (mult:DI (match_operand:DI 1 "arith_operand" "%r")
4448 (match_operand:DI 2 "arith_operand" "rI")))]
4451 [(set_attr "type" "imul")])
4453 ;; V8plus wide multiply.
4455 (define_insn "muldi3_v8plus"
4456 [(set (match_operand:DI 0 "register_operand" "=r,h")
4457 (mult:DI (match_operand:DI 1 "arith_operand" "%r,0")
4458 (match_operand:DI 2 "arith_operand" "rI,rI")))
4459 (clobber (match_scratch:SI 3 "=&h,X"))
4460 (clobber (match_scratch:SI 4 "=&h,X"))]
4463 if (sparc_check_64 (operands[1], insn) <= 0)
4464 output_asm_insn ("srl\t%L1, 0, %L1", operands);
4465 if (which_alternative == 1)
4466 output_asm_insn ("sllx\t%H1, 32, %H1", operands);
4467 if (GET_CODE (operands[2]) == CONST_INT)
4469 if (which_alternative == 1)
4470 return "or\t%L1, %H1, %H1\n\tmulx\t%H1, %2, %L0\;srlx\t%L0, 32, %H0";
4472 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";
4474 else if (rtx_equal_p (operands[1], operands[2]))
4476 if (which_alternative == 1)
4477 return "or\t%L1, %H1, %H1\n\tmulx\t%H1, %H1, %L0\;srlx\t%L0, 32, %H0";
4479 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";
4481 if (sparc_check_64 (operands[2], insn) <= 0)
4482 output_asm_insn ("srl\t%L2, 0, %L2", operands);
4483 if (which_alternative == 1)
4484 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";
4486 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";
4488 [(set_attr "type" "multi")
4489 (set_attr "length" "9,8")])
4491 (define_insn "*cmp_mul_set"
4493 (compare:CC (mult:SI (match_operand:SI 1 "arith_operand" "%r")
4494 (match_operand:SI 2 "arith_operand" "rI"))
4496 (set (match_operand:SI 0 "register_operand" "=r")
4497 (mult:SI (match_dup 1) (match_dup 2)))]
4498 "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS"
4499 "smulcc\t%1, %2, %0"
4500 [(set_attr "type" "imul")])
4502 (define_expand "mulsidi3"
4503 [(set (match_operand:DI 0 "register_operand" "")
4504 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
4505 (sign_extend:DI (match_operand:SI 2 "arith_operand" ""))))]
4508 if (CONSTANT_P (operands[2]))
4511 emit_insn (gen_const_mulsidi3_v8plus (operands[0], operands[1],
4513 else if (TARGET_ARCH32)
4514 emit_insn (gen_const_mulsidi3_sp32 (operands[0], operands[1],
4517 emit_insn (gen_const_mulsidi3_sp64 (operands[0], operands[1],
4523 emit_insn (gen_mulsidi3_v8plus (operands[0], operands[1], operands[2]));
4528 ;; V9 puts the 64-bit product in a 64-bit register. Only out or global
4529 ;; registers can hold 64-bit values in the V8plus environment.
4531 (define_insn "mulsidi3_v8plus"
4532 [(set (match_operand:DI 0 "register_operand" "=h,r")
4533 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4534 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
4535 (clobber (match_scratch:SI 3 "=X,&h"))]
4538 smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
4539 smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4540 [(set_attr "type" "multi")
4541 (set_attr "length" "2,3")])
4544 (define_insn "const_mulsidi3_v8plus"
4545 [(set (match_operand:DI 0 "register_operand" "=h,r")
4546 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4547 (match_operand:DI 2 "small_int_operand" "I,I")))
4548 (clobber (match_scratch:SI 3 "=X,&h"))]
4551 smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
4552 smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4553 [(set_attr "type" "multi")
4554 (set_attr "length" "2,3")])
4557 (define_insn "*mulsidi3_sp32"
4558 [(set (match_operand:DI 0 "register_operand" "=r")
4559 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4560 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4563 return TARGET_SPARCLET
4564 ? "smuld\t%1, %2, %L0"
4565 : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
4568 (if_then_else (eq_attr "isa" "sparclet")
4569 (const_string "imul") (const_string "multi")))
4570 (set (attr "length")
4571 (if_then_else (eq_attr "isa" "sparclet")
4572 (const_int 1) (const_int 2)))])
4574 (define_insn "*mulsidi3_sp64"
4575 [(set (match_operand:DI 0 "register_operand" "=r")
4576 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4577 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4578 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4580 [(set_attr "type" "imul")])
4582 ;; Extra pattern, because sign_extend of a constant isn't valid.
4585 (define_insn "const_mulsidi3_sp32"
4586 [(set (match_operand:DI 0 "register_operand" "=r")
4587 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4588 (match_operand:DI 2 "small_int_operand" "I")))]
4591 return TARGET_SPARCLET
4592 ? "smuld\t%1, %2, %L0"
4593 : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
4596 (if_then_else (eq_attr "isa" "sparclet")
4597 (const_string "imul") (const_string "multi")))
4598 (set (attr "length")
4599 (if_then_else (eq_attr "isa" "sparclet")
4600 (const_int 1) (const_int 2)))])
4602 (define_insn "const_mulsidi3_sp64"
4603 [(set (match_operand:DI 0 "register_operand" "=r")
4604 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4605 (match_operand:DI 2 "small_int_operand" "I")))]
4606 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4608 [(set_attr "type" "imul")])
4610 (define_expand "smulsi3_highpart"
4611 [(set (match_operand:SI 0 "register_operand" "")
4613 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
4614 (sign_extend:DI (match_operand:SI 2 "arith_operand" "")))
4616 "TARGET_HARD_MUL && TARGET_ARCH32"
4618 if (CONSTANT_P (operands[2]))
4622 emit_insn (gen_const_smulsi3_highpart_v8plus (operands[0],
4628 emit_insn (gen_const_smulsi3_highpart (operands[0], operands[1], operands[2]));
4633 emit_insn (gen_smulsi3_highpart_v8plus (operands[0], operands[1],
4634 operands[2], GEN_INT (32)));
4640 (define_insn "smulsi3_highpart_v8plus"
4641 [(set (match_operand:SI 0 "register_operand" "=h,r")
4643 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4644 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
4645 (match_operand:SI 3 "small_int_operand" "I,I"))))
4646 (clobber (match_scratch:SI 4 "=X,&h"))]
4649 smul\t%1, %2, %0\;srlx\t%0, %3, %0
4650 smul\t%1, %2, %4\;srlx\t%4, %3, %0"
4651 [(set_attr "type" "multi")
4652 (set_attr "length" "2")])
4654 ;; The combiner changes TRUNCATE in the previous pattern to SUBREG.
4657 [(set (match_operand:SI 0 "register_operand" "=h,r")
4660 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4661 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
4662 (match_operand:SI 3 "small_int_operand" "I,I"))
4664 (clobber (match_scratch:SI 4 "=X,&h"))]
4667 smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
4668 smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
4669 [(set_attr "type" "multi")
4670 (set_attr "length" "2")])
4673 (define_insn "const_smulsi3_highpart_v8plus"
4674 [(set (match_operand:SI 0 "register_operand" "=h,r")
4676 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4677 (match_operand:DI 2 "small_int_operand" "I,I"))
4678 (match_operand:SI 3 "small_int_operand" "I,I"))))
4679 (clobber (match_scratch:SI 4 "=X,&h"))]
4682 smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
4683 smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
4684 [(set_attr "type" "multi")
4685 (set_attr "length" "2")])
4688 (define_insn "*smulsi3_highpart_sp32"
4689 [(set (match_operand:SI 0 "register_operand" "=r")
4691 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4692 (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
4695 "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
4696 [(set_attr "type" "multi")
4697 (set_attr "length" "2")])
4700 (define_insn "const_smulsi3_highpart"
4701 [(set (match_operand:SI 0 "register_operand" "=r")
4703 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4704 (match_operand:DI 2 "small_int_operand" "i"))
4707 "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
4708 [(set_attr "type" "multi")
4709 (set_attr "length" "2")])
4711 (define_expand "umulsidi3"
4712 [(set (match_operand:DI 0 "register_operand" "")
4713 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
4714 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" ""))))]
4717 if (CONSTANT_P (operands[2]))
4720 emit_insn (gen_const_umulsidi3_v8plus (operands[0], operands[1],
4722 else if (TARGET_ARCH32)
4723 emit_insn (gen_const_umulsidi3_sp32 (operands[0], operands[1],
4726 emit_insn (gen_const_umulsidi3_sp64 (operands[0], operands[1],
4732 emit_insn (gen_umulsidi3_v8plus (operands[0], operands[1], operands[2]));
4738 (define_insn "umulsidi3_v8plus"
4739 [(set (match_operand:DI 0 "register_operand" "=h,r")
4740 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4741 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
4742 (clobber (match_scratch:SI 3 "=X,&h"))]
4745 umul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
4746 umul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4747 [(set_attr "type" "multi")
4748 (set_attr "length" "2,3")])
4751 (define_insn "*umulsidi3_sp32"
4752 [(set (match_operand:DI 0 "register_operand" "=r")
4753 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4754 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4757 return TARGET_SPARCLET
4758 ? "umuld\t%1, %2, %L0"
4759 : "umul\t%1, %2, %L0\n\trd\t%%y, %H0";
4762 (if_then_else (eq_attr "isa" "sparclet")
4763 (const_string "imul") (const_string "multi")))
4764 (set (attr "length")
4765 (if_then_else (eq_attr "isa" "sparclet")
4766 (const_int 1) (const_int 2)))])
4768 (define_insn "*umulsidi3_sp64"
4769 [(set (match_operand:DI 0 "register_operand" "=r")
4770 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4771 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4772 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4774 [(set_attr "type" "imul")])
4776 ;; Extra pattern, because sign_extend of a constant isn't valid.
4779 (define_insn "const_umulsidi3_sp32"
4780 [(set (match_operand:DI 0 "register_operand" "=r")
4781 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4782 (match_operand:DI 2 "uns_small_int_operand" "")))]
4785 return TARGET_SPARCLET
4786 ? "umuld\t%1, %s2, %L0"
4787 : "umul\t%1, %s2, %L0\n\trd\t%%y, %H0";
4790 (if_then_else (eq_attr "isa" "sparclet")
4791 (const_string "imul") (const_string "multi")))
4792 (set (attr "length")
4793 (if_then_else (eq_attr "isa" "sparclet")
4794 (const_int 1) (const_int 2)))])
4796 (define_insn "const_umulsidi3_sp64"
4797 [(set (match_operand:DI 0 "register_operand" "=r")
4798 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4799 (match_operand:DI 2 "uns_small_int_operand" "")))]
4800 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4802 [(set_attr "type" "imul")])
4805 (define_insn "const_umulsidi3_v8plus"
4806 [(set (match_operand:DI 0 "register_operand" "=h,r")
4807 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4808 (match_operand:DI 2 "uns_small_int_operand" "")))
4809 (clobber (match_scratch:SI 3 "=X,h"))]
4812 umul\t%1, %s2, %L0\n\tsrlx\t%L0, 32, %H0
4813 umul\t%1, %s2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4814 [(set_attr "type" "multi")
4815 (set_attr "length" "2,3")])
4817 (define_expand "umulsi3_highpart"
4818 [(set (match_operand:SI 0 "register_operand" "")
4820 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
4821 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" "")))
4823 "TARGET_HARD_MUL && TARGET_ARCH32"
4825 if (CONSTANT_P (operands[2]))
4829 emit_insn (gen_const_umulsi3_highpart_v8plus (operands[0],
4835 emit_insn (gen_const_umulsi3_highpart (operands[0], operands[1], operands[2]));
4840 emit_insn (gen_umulsi3_highpart_v8plus (operands[0], operands[1],
4841 operands[2], GEN_INT (32)));
4847 (define_insn "umulsi3_highpart_v8plus"
4848 [(set (match_operand:SI 0 "register_operand" "=h,r")
4850 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4851 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
4852 (match_operand:SI 3 "small_int_operand" "I,I"))))
4853 (clobber (match_scratch:SI 4 "=X,h"))]
4856 umul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
4857 umul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
4858 [(set_attr "type" "multi")
4859 (set_attr "length" "2")])
4862 (define_insn "const_umulsi3_highpart_v8plus"
4863 [(set (match_operand:SI 0 "register_operand" "=h,r")
4865 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4866 (match_operand:DI 2 "uns_small_int_operand" ""))
4867 (match_operand:SI 3 "small_int_operand" "I,I"))))
4868 (clobber (match_scratch:SI 4 "=X,h"))]
4871 umul\t%1, %s2, %0\n\tsrlx\t%0, %3, %0
4872 umul\t%1, %s2, %4\n\tsrlx\t%4, %3, %0"
4873 [(set_attr "type" "multi")
4874 (set_attr "length" "2")])
4877 (define_insn "*umulsi3_highpart_sp32"
4878 [(set (match_operand:SI 0 "register_operand" "=r")
4880 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4881 (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
4884 "umul\t%1, %2, %%g0\n\trd\t%%y, %0"
4885 [(set_attr "type" "multi")
4886 (set_attr "length" "2")])
4889 (define_insn "const_umulsi3_highpart"
4890 [(set (match_operand:SI 0 "register_operand" "=r")
4892 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4893 (match_operand:DI 2 "uns_small_int_operand" ""))
4896 "umul\t%1, %s2, %%g0\n\trd\t%%y, %0"
4897 [(set_attr "type" "multi")
4898 (set_attr "length" "2")])
4900 ;; The V8 architecture specifies that there must be 3 instructions between
4901 ;; a Y register write and a use of it for correct results.
4903 (define_expand "divsi3"
4904 [(parallel [(set (match_operand:SI 0 "register_operand" "=r,r")
4905 (div:SI (match_operand:SI 1 "register_operand" "r,r")
4906 (match_operand:SI 2 "input_operand" "rI,m")))
4907 (clobber (match_scratch:SI 3 "=&r,&r"))])]
4908 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4912 operands[3] = gen_reg_rtx(SImode);
4913 emit_insn (gen_ashrsi3 (operands[3], operands[1], GEN_INT (31)));
4914 emit_insn (gen_divsi3_sp64 (operands[0], operands[1], operands[2],
4920 (define_insn "divsi3_sp32"
4921 [(set (match_operand:SI 0 "register_operand" "=r,r")
4922 (div:SI (match_operand:SI 1 "register_operand" "r,r")
4923 (match_operand:SI 2 "input_operand" "rI,m")))
4924 (clobber (match_scratch:SI 3 "=&r,&r"))]
4925 "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS)
4928 if (which_alternative == 0)
4930 return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tsdiv\t%1, %2, %0";
4932 return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tnop\n\tnop\n\tnop\n\tsdiv\t%1, %2, %0";
4935 return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tld\t%2, %3\n\tsdiv\t%1, %3, %0";
4937 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";
4939 [(set_attr "type" "multi")
4940 (set (attr "length")
4941 (if_then_else (eq_attr "isa" "v9")
4942 (const_int 4) (const_int 6)))])
4944 (define_insn "divsi3_sp64"
4945 [(set (match_operand:SI 0 "register_operand" "=r")
4946 (div:SI (match_operand:SI 1 "register_operand" "r")
4947 (match_operand:SI 2 "input_operand" "rI")))
4948 (use (match_operand:SI 3 "register_operand" "r"))]
4949 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4950 "wr\t%%g0, %3, %%y\n\tsdiv\t%1, %2, %0"
4951 [(set_attr "type" "multi")
4952 (set_attr "length" "2")])
4954 (define_insn "divdi3"
4955 [(set (match_operand:DI 0 "register_operand" "=r")
4956 (div:DI (match_operand:DI 1 "register_operand" "r")
4957 (match_operand:DI 2 "arith_operand" "rI")))]
4960 [(set_attr "type" "idiv")])
4962 (define_insn "*cmp_sdiv_cc_set"
4964 (compare:CC (div:SI (match_operand:SI 1 "register_operand" "r")
4965 (match_operand:SI 2 "arith_operand" "rI"))
4967 (set (match_operand:SI 0 "register_operand" "=r")
4968 (div:SI (match_dup 1) (match_dup 2)))
4969 (clobber (match_scratch:SI 3 "=&r"))]
4970 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4973 return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tsdivcc\t%1, %2, %0";
4975 return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tnop\n\tnop\n\tnop\n\tsdivcc\t%1, %2, %0";
4977 [(set_attr "type" "multi")
4978 (set (attr "length")
4979 (if_then_else (eq_attr "isa" "v9")
4980 (const_int 3) (const_int 6)))])
4983 (define_expand "udivsi3"
4984 [(set (match_operand:SI 0 "register_operand" "")
4985 (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "")
4986 (match_operand:SI 2 "input_operand" "")))]
4987 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4990 ;; The V8 architecture specifies that there must be 3 instructions between
4991 ;; a Y register write and a use of it for correct results.
4993 (define_insn "udivsi3_sp32"
4994 [(set (match_operand:SI 0 "register_operand" "=r,&r,&r")
4995 (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "r,r,m")
4996 (match_operand:SI 2 "input_operand" "rI,m,r")))]
4997 "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS)
5000 output_asm_insn ("wr\t%%g0, %%g0, %%y", operands);
5001 switch (which_alternative)
5004 return "nop\n\tnop\n\tnop\n\tudiv\t%1, %2, %0";
5006 return "ld\t%2, %0\n\tnop\n\tnop\n\tudiv\t%1, %0, %0";
5008 return "ld\t%1, %0\n\tnop\n\tnop\n\tudiv\t%0, %2, %0";
5011 [(set_attr "type" "multi")
5012 (set_attr "length" "5")])
5014 (define_insn "udivsi3_sp64"
5015 [(set (match_operand:SI 0 "register_operand" "=r")
5016 (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "r")
5017 (match_operand:SI 2 "input_operand" "rI")))]
5018 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5019 "wr\t%%g0, 0, %%y\n\tudiv\t%1, %2, %0"
5020 [(set_attr "type" "multi")
5021 (set_attr "length" "2")])
5023 (define_insn "udivdi3"
5024 [(set (match_operand:DI 0 "register_operand" "=r")
5025 (udiv:DI (match_operand:DI 1 "register_operand" "r")
5026 (match_operand:DI 2 "arith_operand" "rI")))]
5029 [(set_attr "type" "idiv")])
5031 (define_insn "*cmp_udiv_cc_set"
5033 (compare:CC (udiv:SI (match_operand:SI 1 "register_operand" "r")
5034 (match_operand:SI 2 "arith_operand" "rI"))
5036 (set (match_operand:SI 0 "register_operand" "=r")
5037 (udiv:SI (match_dup 1) (match_dup 2)))]
5039 || TARGET_DEPRECATED_V8_INSNS"
5042 return "wr\t%%g0, %%g0, %%y\n\tudivcc\t%1, %2, %0";
5044 return "wr\t%%g0, %%g0, %%y\n\tnop\n\tnop\n\tnop\n\tudivcc\t%1, %2, %0";
5046 [(set_attr "type" "multi")
5047 (set (attr "length")
5048 (if_then_else (eq_attr "isa" "v9")
5049 (const_int 2) (const_int 5)))])
5051 ; sparclet multiply/accumulate insns
5053 (define_insn "*smacsi"
5054 [(set (match_operand:SI 0 "register_operand" "=r")
5055 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "%r")
5056 (match_operand:SI 2 "arith_operand" "rI"))
5057 (match_operand:SI 3 "register_operand" "0")))]
5060 [(set_attr "type" "imul")])
5062 (define_insn "*smacdi"
5063 [(set (match_operand:DI 0 "register_operand" "=r")
5064 (plus:DI (mult:DI (sign_extend:DI
5065 (match_operand:SI 1 "register_operand" "%r"))
5067 (match_operand:SI 2 "register_operand" "r")))
5068 (match_operand:DI 3 "register_operand" "0")))]
5070 "smacd\t%1, %2, %L0"
5071 [(set_attr "type" "imul")])
5073 (define_insn "*umacdi"
5074 [(set (match_operand:DI 0 "register_operand" "=r")
5075 (plus:DI (mult:DI (zero_extend:DI
5076 (match_operand:SI 1 "register_operand" "%r"))
5078 (match_operand:SI 2 "register_operand" "r")))
5079 (match_operand:DI 3 "register_operand" "0")))]
5081 "umacd\t%1, %2, %L0"
5082 [(set_attr "type" "imul")])
5085 ;; Boolean instructions.
5087 ;; We define DImode `and' so with DImode `not' we can get
5088 ;; DImode `andn'. Other combinations are possible.
5090 (define_mode_iterator V64I [DI V2SI V4HI V8QI])
5091 (define_mode_iterator V32I [SI V2HI V4QI])
5093 (define_expand "and<V64I:mode>3"
5094 [(set (match_operand:V64I 0 "register_operand" "")
5095 (and:V64I (match_operand:V64I 1 "arith_double_operand" "")
5096 (match_operand:V64I 2 "arith_double_operand" "")))]
5100 (define_insn "*and<V64I:mode>3_sp32"
5101 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5102 (and:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
5103 (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
5108 [(set_attr "type" "*,fga")
5109 (set_attr "length" "2,*")
5110 (set_attr "fptype" "*,double")])
5112 (define_insn "*and<V64I:mode>3_sp64"
5113 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5114 (and:V64I (match_operand:V64I 1 "arith_operand" "%r,b")
5115 (match_operand:V64I 2 "arith_operand" "rI,b")))]
5120 [(set_attr "type" "*,fga")
5121 (set_attr "fptype" "*,double")])
5123 (define_insn "and<V32I:mode>3"
5124 [(set (match_operand:V32I 0 "register_operand" "=r,d")
5125 (and:V32I (match_operand:V32I 1 "arith_operand" "%r,d")
5126 (match_operand:V32I 2 "arith_operand" "rI,d")))]
5131 [(set_attr "type" "*,fga")
5132 (set_attr "fptype" "*,single")])
5135 [(set (match_operand:SI 0 "register_operand" "")
5136 (and:SI (match_operand:SI 1 "register_operand" "")
5137 (match_operand:SI 2 "const_compl_high_operand" "")))
5138 (clobber (match_operand:SI 3 "register_operand" ""))]
5140 [(set (match_dup 3) (match_dup 4))
5141 (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 1)))]
5143 operands[4] = GEN_INT (~INTVAL (operands[2]));
5146 (define_insn_and_split "*and_not_<V64I:mode>_sp32"
5147 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5148 (and:V64I (not:V64I (match_operand:V64I 1 "register_operand" "%r,b"))
5149 (match_operand:V64I 2 "register_operand" "r,b")))]
5153 fandnot1\t%1, %2, %0"
5154 "&& reload_completed
5155 && ((GET_CODE (operands[0]) == REG
5156 && REGNO (operands[0]) < 32)
5157 || (GET_CODE (operands[0]) == SUBREG
5158 && GET_CODE (SUBREG_REG (operands[0])) == REG
5159 && REGNO (SUBREG_REG (operands[0])) < 32))"
5160 [(set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))
5161 (set (match_dup 6) (and:SI (not:SI (match_dup 7)) (match_dup 8)))]
5162 "operands[3] = gen_highpart (SImode, operands[0]);
5163 operands[4] = gen_highpart (SImode, operands[1]);
5164 operands[5] = gen_highpart (SImode, operands[2]);
5165 operands[6] = gen_lowpart (SImode, operands[0]);
5166 operands[7] = gen_lowpart (SImode, operands[1]);
5167 operands[8] = gen_lowpart (SImode, operands[2]);"
5168 [(set_attr "type" "*,fga")
5169 (set_attr "length" "2,*")
5170 (set_attr "fptype" "*,double")])
5172 (define_insn "*and_not_<V64I:mode>_sp64"
5173 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5174 (and:V64I (not:V64I (match_operand:V64I 1 "register_operand" "%r,b"))
5175 (match_operand:V64I 2 "register_operand" "r,b")))]
5179 fandnot1\t%1, %2, %0"
5180 [(set_attr "type" "*,fga")
5181 (set_attr "fptype" "*,double")])
5183 (define_insn "*and_not_<V32I:mode>"
5184 [(set (match_operand:V32I 0 "register_operand" "=r,d")
5185 (and:V32I (not:V32I (match_operand:V32I 1 "register_operand" "%r,d"))
5186 (match_operand:V32I 2 "register_operand" "r,d")))]
5190 fandnot1s\t%1, %2, %0"
5191 [(set_attr "type" "*,fga")
5192 (set_attr "fptype" "*,single")])
5194 (define_expand "ior<V64I:mode>3"
5195 [(set (match_operand:V64I 0 "register_operand" "")
5196 (ior:V64I (match_operand:V64I 1 "arith_double_operand" "")
5197 (match_operand:V64I 2 "arith_double_operand" "")))]
5201 (define_insn "*ior<V64I:mode>3_sp32"
5202 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5203 (ior:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
5204 (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
5209 [(set_attr "type" "*,fga")
5210 (set_attr "length" "2,*")
5211 (set_attr "fptype" "*,double")])
5213 (define_insn "*ior<V64I:mode>3_sp64"
5214 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5215 (ior:V64I (match_operand:V64I 1 "arith_operand" "%r,b")
5216 (match_operand:V64I 2 "arith_operand" "rI,b")))]
5221 [(set_attr "type" "*,fga")
5222 (set_attr "fptype" "*,double")])
5224 (define_insn "ior<V32I:mode>3"
5225 [(set (match_operand:V32I 0 "register_operand" "=r,d")
5226 (ior:V32I (match_operand:V32I 1 "arith_operand" "%r,d")
5227 (match_operand:V32I 2 "arith_operand" "rI,d")))]
5232 [(set_attr "type" "*,fga")
5233 (set_attr "fptype" "*,single")])
5236 [(set (match_operand:SI 0 "register_operand" "")
5237 (ior:SI (match_operand:SI 1 "register_operand" "")
5238 (match_operand:SI 2 "const_compl_high_operand" "")))
5239 (clobber (match_operand:SI 3 "register_operand" ""))]
5241 [(set (match_dup 3) (match_dup 4))
5242 (set (match_dup 0) (ior:SI (not:SI (match_dup 3)) (match_dup 1)))]
5244 operands[4] = GEN_INT (~INTVAL (operands[2]));
5247 (define_insn_and_split "*or_not_<V64I:mode>_sp32"
5248 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5249 (ior:V64I (not:V64I (match_operand:V64I 1 "register_operand" "r,b"))
5250 (match_operand:V64I 2 "register_operand" "r,b")))]
5254 fornot1\t%1, %2, %0"
5255 "&& reload_completed
5256 && ((GET_CODE (operands[0]) == REG
5257 && REGNO (operands[0]) < 32)
5258 || (GET_CODE (operands[0]) == SUBREG
5259 && GET_CODE (SUBREG_REG (operands[0])) == REG
5260 && REGNO (SUBREG_REG (operands[0])) < 32))"
5261 [(set (match_dup 3) (ior:SI (not:SI (match_dup 4)) (match_dup 5)))
5262 (set (match_dup 6) (ior:SI (not:SI (match_dup 7)) (match_dup 8)))]
5263 "operands[3] = gen_highpart (SImode, operands[0]);
5264 operands[4] = gen_highpart (SImode, operands[1]);
5265 operands[5] = gen_highpart (SImode, operands[2]);
5266 operands[6] = gen_lowpart (SImode, operands[0]);
5267 operands[7] = gen_lowpart (SImode, operands[1]);
5268 operands[8] = gen_lowpart (SImode, operands[2]);"
5269 [(set_attr "type" "*,fga")
5270 (set_attr "length" "2,*")
5271 (set_attr "fptype" "*,double")])
5273 (define_insn "*or_not_<V64I:mode>_sp64"
5274 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5275 (ior:V64I (not:V64I (match_operand:V64I 1 "register_operand" "r,b"))
5276 (match_operand:V64I 2 "register_operand" "r,b")))]
5280 fornot1\t%1, %2, %0"
5281 [(set_attr "type" "*,fga")
5282 (set_attr "fptype" "*,double")])
5284 (define_insn "*or_not_<V32I:mode>"
5285 [(set (match_operand:V32I 0 "register_operand" "=r,d")
5286 (ior:V32I (not:V32I (match_operand:V32I 1 "register_operand" "r,d"))
5287 (match_operand:V32I 2 "register_operand" "r,d")))]
5291 fornot1s\t%1, %2, %0"
5292 [(set_attr "type" "*,fga")
5293 (set_attr "fptype" "*,single")])
5295 (define_expand "xor<V64I:mode>3"
5296 [(set (match_operand:V64I 0 "register_operand" "")
5297 (xor:V64I (match_operand:V64I 1 "arith_double_operand" "")
5298 (match_operand:V64I 2 "arith_double_operand" "")))]
5302 (define_insn "*xor<V64I:mode>3_sp32"
5303 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5304 (xor:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
5305 (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
5310 [(set_attr "type" "*,fga")
5311 (set_attr "length" "2,*")
5312 (set_attr "fptype" "*,double")])
5314 (define_insn "*xor<V64I:mode>3_sp64"
5315 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5316 (xor:V64I (match_operand:V64I 1 "arith_operand" "%rJ,b")
5317 (match_operand:V64I 2 "arith_operand" "rI,b")))]
5322 [(set_attr "type" "*,fga")
5323 (set_attr "fptype" "*,double")])
5325 (define_insn "xor<V32I:mode>3"
5326 [(set (match_operand:V32I 0 "register_operand" "=r,d")
5327 (xor:V32I (match_operand:V32I 1 "arith_operand" "%rJ,d")
5328 (match_operand:V32I 2 "arith_operand" "rI,d")))]
5333 [(set_attr "type" "*,fga")
5334 (set_attr "fptype" "*,single")])
5337 [(set (match_operand:SI 0 "register_operand" "")
5338 (xor:SI (match_operand:SI 1 "register_operand" "")
5339 (match_operand:SI 2 "const_compl_high_operand" "")))
5340 (clobber (match_operand:SI 3 "register_operand" ""))]
5342 [(set (match_dup 3) (match_dup 4))
5343 (set (match_dup 0) (not:SI (xor:SI (match_dup 3) (match_dup 1))))]
5345 operands[4] = GEN_INT (~INTVAL (operands[2]));
5349 [(set (match_operand:SI 0 "register_operand" "")
5350 (not:SI (xor:SI (match_operand:SI 1 "register_operand" "")
5351 (match_operand:SI 2 "const_compl_high_operand" ""))))
5352 (clobber (match_operand:SI 3 "register_operand" ""))]
5354 [(set (match_dup 3) (match_dup 4))
5355 (set (match_dup 0) (xor:SI (match_dup 3) (match_dup 1)))]
5357 operands[4] = GEN_INT (~INTVAL (operands[2]));
5360 ;; Split DImode logical operations requiring two instructions.
5362 [(set (match_operand:V64I 0 "register_operand" "")
5363 (match_operator:V64I 1 "cc_arith_operator" ; AND, IOR, XOR
5364 [(match_operand:V64I 2 "register_operand" "")
5365 (match_operand:V64I 3 "arith_double_operand" "")]))]
5368 && ((GET_CODE (operands[0]) == REG
5369 && REGNO (operands[0]) < 32)
5370 || (GET_CODE (operands[0]) == SUBREG
5371 && GET_CODE (SUBREG_REG (operands[0])) == REG
5372 && REGNO (SUBREG_REG (operands[0])) < 32))"
5373 [(set (match_dup 4) (match_op_dup:SI 1 [(match_dup 6) (match_dup 8)]))
5374 (set (match_dup 5) (match_op_dup:SI 1 [(match_dup 7) (match_dup 9)]))]
5376 operands[4] = gen_highpart (SImode, operands[0]);
5377 operands[5] = gen_lowpart (SImode, operands[0]);
5378 operands[6] = gen_highpart (SImode, operands[2]);
5379 operands[7] = gen_lowpart (SImode, operands[2]);
5380 #if HOST_BITS_PER_WIDE_INT == 32
5381 if (GET_CODE (operands[3]) == CONST_INT && <V64I:MODE>mode == DImode)
5383 if (INTVAL (operands[3]) < 0)
5384 operands[8] = constm1_rtx;
5386 operands[8] = const0_rtx;
5390 operands[8] = gen_highpart_mode (SImode, <V64I:MODE>mode, operands[3]);
5391 operands[9] = gen_lowpart (SImode, operands[3]);
5394 ;; xnor patterns. Note that (a ^ ~b) == (~a ^ b) == ~(a ^ b).
5395 ;; Combine now canonicalizes to the rightmost expression.
5396 (define_insn_and_split "*xor_not_<V64I:mode>_sp32"
5397 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5398 (not:V64I (xor:V64I (match_operand:V64I 1 "register_operand" "r,b")
5399 (match_operand:V64I 2 "register_operand" "r,b"))))]
5404 "&& reload_completed
5405 && ((GET_CODE (operands[0]) == REG
5406 && REGNO (operands[0]) < 32)
5407 || (GET_CODE (operands[0]) == SUBREG
5408 && GET_CODE (SUBREG_REG (operands[0])) == REG
5409 && REGNO (SUBREG_REG (operands[0])) < 32))"
5410 [(set (match_dup 3) (not:SI (xor:SI (match_dup 4) (match_dup 5))))
5411 (set (match_dup 6) (not:SI (xor:SI (match_dup 7) (match_dup 8))))]
5412 "operands[3] = gen_highpart (SImode, operands[0]);
5413 operands[4] = gen_highpart (SImode, operands[1]);
5414 operands[5] = gen_highpart (SImode, operands[2]);
5415 operands[6] = gen_lowpart (SImode, operands[0]);
5416 operands[7] = gen_lowpart (SImode, operands[1]);
5417 operands[8] = gen_lowpart (SImode, operands[2]);"
5418 [(set_attr "type" "*,fga")
5419 (set_attr "length" "2,*")
5420 (set_attr "fptype" "*,double")])
5422 (define_insn "*xor_not_<V64I:mode>_sp64"
5423 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5424 (not:V64I (xor:V64I (match_operand:V64I 1 "register_or_zero_operand" "rJ,b")
5425 (match_operand:V64I 2 "arith_operand" "rI,b"))))]
5430 [(set_attr "type" "*,fga")
5431 (set_attr "fptype" "*,double")])
5433 (define_insn "*xor_not_<V32I:mode>"
5434 [(set (match_operand:V32I 0 "register_operand" "=r,d")
5435 (not:V32I (xor:V32I (match_operand:V32I 1 "register_or_zero_operand" "rJ,d")
5436 (match_operand:V32I 2 "arith_operand" "rI,d"))))]
5441 [(set_attr "type" "*,fga")
5442 (set_attr "fptype" "*,single")])
5444 ;; These correspond to the above in the case where we also (or only)
5445 ;; want to set the condition code.
5447 (define_insn "*cmp_cc_arith_op"
5450 (match_operator:SI 2 "cc_arith_operator"
5451 [(match_operand:SI 0 "arith_operand" "%r")
5452 (match_operand:SI 1 "arith_operand" "rI")])
5455 "%A2cc\t%0, %1, %%g0"
5456 [(set_attr "type" "compare")])
5458 (define_insn "*cmp_ccx_arith_op"
5461 (match_operator:DI 2 "cc_arith_operator"
5462 [(match_operand:DI 0 "arith_operand" "%r")
5463 (match_operand:DI 1 "arith_operand" "rI")])
5466 "%A2cc\t%0, %1, %%g0"
5467 [(set_attr "type" "compare")])
5469 (define_insn "*cmp_cc_arith_op_set"
5472 (match_operator:SI 3 "cc_arith_operator"
5473 [(match_operand:SI 1 "arith_operand" "%r")
5474 (match_operand:SI 2 "arith_operand" "rI")])
5476 (set (match_operand:SI 0 "register_operand" "=r")
5477 (match_operator:SI 4 "cc_arith_operator" [(match_dup 1) (match_dup 2)]))]
5478 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
5480 [(set_attr "type" "compare")])
5482 (define_insn "*cmp_ccx_arith_op_set"
5485 (match_operator:DI 3 "cc_arith_operator"
5486 [(match_operand:DI 1 "arith_operand" "%r")
5487 (match_operand:DI 2 "arith_operand" "rI")])
5489 (set (match_operand:DI 0 "register_operand" "=r")
5490 (match_operator:DI 4 "cc_arith_operator" [(match_dup 1) (match_dup 2)]))]
5491 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
5493 [(set_attr "type" "compare")])
5495 (define_insn "*cmp_cc_xor_not"
5498 (not:SI (xor:SI (match_operand:SI 0 "register_or_zero_operand" "%rJ")
5499 (match_operand:SI 1 "arith_operand" "rI")))
5502 "xnorcc\t%r0, %1, %%g0"
5503 [(set_attr "type" "compare")])
5505 (define_insn "*cmp_ccx_xor_not"
5508 (not:DI (xor:DI (match_operand:DI 0 "register_or_zero_operand" "%rJ")
5509 (match_operand:DI 1 "arith_operand" "rI")))
5512 "xnorcc\t%r0, %1, %%g0"
5513 [(set_attr "type" "compare")])
5515 (define_insn "*cmp_cc_xor_not_set"
5518 (not:SI (xor:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ")
5519 (match_operand:SI 2 "arith_operand" "rI")))
5521 (set (match_operand:SI 0 "register_operand" "=r")
5522 (not:SI (xor:SI (match_dup 1) (match_dup 2))))]
5524 "xnorcc\t%r1, %2, %0"
5525 [(set_attr "type" "compare")])
5527 (define_insn "*cmp_ccx_xor_not_set"
5530 (not:DI (xor:DI (match_operand:DI 1 "register_or_zero_operand" "%rJ")
5531 (match_operand:DI 2 "arith_operand" "rI")))
5533 (set (match_operand:DI 0 "register_operand" "=r")
5534 (not:DI (xor:DI (match_dup 1) (match_dup 2))))]
5536 "xnorcc\t%r1, %2, %0"
5537 [(set_attr "type" "compare")])
5539 (define_insn "*cmp_cc_arith_op_not"
5542 (match_operator:SI 2 "cc_arith_not_operator"
5543 [(not:SI (match_operand:SI 0 "arith_operand" "rI"))
5544 (match_operand:SI 1 "register_or_zero_operand" "rJ")])
5547 "%B2cc\t%r1, %0, %%g0"
5548 [(set_attr "type" "compare")])
5550 (define_insn "*cmp_ccx_arith_op_not"
5553 (match_operator:DI 2 "cc_arith_not_operator"
5554 [(not:DI (match_operand:DI 0 "arith_operand" "rI"))
5555 (match_operand:DI 1 "register_or_zero_operand" "rJ")])
5558 "%B2cc\t%r1, %0, %%g0"
5559 [(set_attr "type" "compare")])
5561 (define_insn "*cmp_cc_arith_op_not_set"
5564 (match_operator:SI 3 "cc_arith_not_operator"
5565 [(not:SI (match_operand:SI 1 "arith_operand" "rI"))
5566 (match_operand:SI 2 "register_or_zero_operand" "rJ")])
5568 (set (match_operand:SI 0 "register_operand" "=r")
5569 (match_operator:SI 4 "cc_arith_not_operator"
5570 [(not:SI (match_dup 1)) (match_dup 2)]))]
5571 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
5572 "%B3cc\t%r2, %1, %0"
5573 [(set_attr "type" "compare")])
5575 (define_insn "*cmp_ccx_arith_op_not_set"
5578 (match_operator:DI 3 "cc_arith_not_operator"
5579 [(not:DI (match_operand:DI 1 "arith_operand" "rI"))
5580 (match_operand:DI 2 "register_or_zero_operand" "rJ")])
5582 (set (match_operand:DI 0 "register_operand" "=r")
5583 (match_operator:DI 4 "cc_arith_not_operator"
5584 [(not:DI (match_dup 1)) (match_dup 2)]))]
5585 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
5586 "%B3cc\t%r2, %1, %0"
5587 [(set_attr "type" "compare")])
5589 ;; We cannot use the "neg" pseudo insn because the Sun assembler
5590 ;; does not know how to make it work for constants.
5592 (define_expand "negdi2"
5593 [(set (match_operand:DI 0 "register_operand" "=r")
5594 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
5597 if (! TARGET_ARCH64)
5599 emit_insn (gen_rtx_PARALLEL
5602 gen_rtx_SET (VOIDmode, operand0,
5603 gen_rtx_NEG (DImode, operand1)),
5604 gen_rtx_CLOBBER (VOIDmode,
5605 gen_rtx_REG (CCmode,
5611 (define_insn_and_split "*negdi2_sp32"
5612 [(set (match_operand:DI 0 "register_operand" "=r")
5613 (neg:DI (match_operand:DI 1 "register_operand" "r")))
5614 (clobber (reg:CC 100))]
5617 "&& reload_completed"
5618 [(parallel [(set (reg:CC_NOOV 100)
5619 (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 5))
5621 (set (match_dup 4) (minus:SI (const_int 0) (match_dup 5)))])
5622 (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
5623 (ltu:SI (reg:CC 100) (const_int 0))))]
5624 "operands[2] = gen_highpart (SImode, operands[0]);
5625 operands[3] = gen_highpart (SImode, operands[1]);
5626 operands[4] = gen_lowpart (SImode, operands[0]);
5627 operands[5] = gen_lowpart (SImode, operands[1]);"
5628 [(set_attr "length" "2")])
5630 (define_insn "*negdi2_sp64"
5631 [(set (match_operand:DI 0 "register_operand" "=r")
5632 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
5634 "sub\t%%g0, %1, %0")
5636 (define_insn "negsi2"
5637 [(set (match_operand:SI 0 "register_operand" "=r")
5638 (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
5640 "sub\t%%g0, %1, %0")
5642 (define_insn "*cmp_cc_neg"
5643 [(set (reg:CC_NOOV 100)
5644 (compare:CC_NOOV (neg:SI (match_operand:SI 0 "arith_operand" "rI"))
5647 "subcc\t%%g0, %0, %%g0"
5648 [(set_attr "type" "compare")])
5650 (define_insn "*cmp_ccx_neg"
5651 [(set (reg:CCX_NOOV 100)
5652 (compare:CCX_NOOV (neg:DI (match_operand:DI 0 "arith_operand" "rI"))
5655 "subcc\t%%g0, %0, %%g0"
5656 [(set_attr "type" "compare")])
5658 (define_insn "*cmp_cc_set_neg"
5659 [(set (reg:CC_NOOV 100)
5660 (compare:CC_NOOV (neg:SI (match_operand:SI 1 "arith_operand" "rI"))
5662 (set (match_operand:SI 0 "register_operand" "=r")
5663 (neg:SI (match_dup 1)))]
5665 "subcc\t%%g0, %1, %0"
5666 [(set_attr "type" "compare")])
5668 (define_insn "*cmp_ccx_set_neg"
5669 [(set (reg:CCX_NOOV 100)
5670 (compare:CCX_NOOV (neg:DI (match_operand:DI 1 "arith_operand" "rI"))
5672 (set (match_operand:DI 0 "register_operand" "=r")
5673 (neg:DI (match_dup 1)))]
5675 "subcc\t%%g0, %1, %0"
5676 [(set_attr "type" "compare")])
5678 ;; We cannot use the "not" pseudo insn because the Sun assembler
5679 ;; does not know how to make it work for constants.
5680 (define_expand "one_cmpl<V64I:mode>2"
5681 [(set (match_operand:V64I 0 "register_operand" "")
5682 (not:V64I (match_operand:V64I 1 "register_operand" "")))]
5686 (define_insn_and_split "*one_cmpl<V64I:mode>2_sp32"
5687 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5688 (not:V64I (match_operand:V64I 1 "register_operand" "r,b")))]
5693 "&& reload_completed
5694 && ((GET_CODE (operands[0]) == REG
5695 && REGNO (operands[0]) < 32)
5696 || (GET_CODE (operands[0]) == SUBREG
5697 && GET_CODE (SUBREG_REG (operands[0])) == REG
5698 && REGNO (SUBREG_REG (operands[0])) < 32))"
5699 [(set (match_dup 2) (not:SI (xor:SI (match_dup 3) (const_int 0))))
5700 (set (match_dup 4) (not:SI (xor:SI (match_dup 5) (const_int 0))))]
5701 "operands[2] = gen_highpart (SImode, operands[0]);
5702 operands[3] = gen_highpart (SImode, operands[1]);
5703 operands[4] = gen_lowpart (SImode, operands[0]);
5704 operands[5] = gen_lowpart (SImode, operands[1]);"
5705 [(set_attr "type" "*,fga")
5706 (set_attr "length" "2,*")
5707 (set_attr "fptype" "*,double")])
5709 (define_insn "*one_cmpl<V64I:mode>2_sp64"
5710 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5711 (not:V64I (match_operand:V64I 1 "arith_operand" "rI,b")))]
5716 [(set_attr "type" "*,fga")
5717 (set_attr "fptype" "*,double")])
5719 (define_insn "one_cmpl<V32I:mode>2"
5720 [(set (match_operand:V32I 0 "register_operand" "=r,d")
5721 (not:V32I (match_operand:V32I 1 "arith_operand" "rI,d")))]
5726 [(set_attr "type" "*,fga")
5727 (set_attr "fptype" "*,single")])
5729 (define_insn "*cmp_cc_not"
5731 (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI"))
5734 "xnorcc\t%%g0, %0, %%g0"
5735 [(set_attr "type" "compare")])
5737 (define_insn "*cmp_ccx_not"
5739 (compare:CCX (not:DI (match_operand:DI 0 "arith_operand" "rI"))
5742 "xnorcc\t%%g0, %0, %%g0"
5743 [(set_attr "type" "compare")])
5745 (define_insn "*cmp_cc_set_not"
5747 (compare:CC (not:SI (match_operand:SI 1 "arith_operand" "rI"))
5749 (set (match_operand:SI 0 "register_operand" "=r")
5750 (not:SI (match_dup 1)))]
5752 "xnorcc\t%%g0, %1, %0"
5753 [(set_attr "type" "compare")])
5755 (define_insn "*cmp_ccx_set_not"
5757 (compare:CCX (not:DI (match_operand:DI 1 "arith_operand" "rI"))
5759 (set (match_operand:DI 0 "register_operand" "=r")
5760 (not:DI (match_dup 1)))]
5762 "xnorcc\t%%g0, %1, %0"
5763 [(set_attr "type" "compare")])
5765 (define_insn "*cmp_cc_set"
5766 [(set (match_operand:SI 0 "register_operand" "=r")
5767 (match_operand:SI 1 "register_operand" "r"))
5769 (compare:CC (match_dup 1)
5773 [(set_attr "type" "compare")])
5775 (define_insn "*cmp_ccx_set64"
5776 [(set (match_operand:DI 0 "register_operand" "=r")
5777 (match_operand:DI 1 "register_operand" "r"))
5779 (compare:CCX (match_dup 1)
5783 [(set_attr "type" "compare")])
5786 ;; Floating point arithmetic instructions.
5788 (define_expand "addtf3"
5789 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5790 (plus:TF (match_operand:TF 1 "general_operand" "")
5791 (match_operand:TF 2 "general_operand" "")))]
5792 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5793 "emit_tfmode_binop (PLUS, operands); DONE;")
5795 (define_insn "*addtf3_hq"
5796 [(set (match_operand:TF 0 "register_operand" "=e")
5797 (plus:TF (match_operand:TF 1 "register_operand" "e")
5798 (match_operand:TF 2 "register_operand" "e")))]
5799 "TARGET_FPU && TARGET_HARD_QUAD"
5801 [(set_attr "type" "fp")])
5803 (define_insn "adddf3"
5804 [(set (match_operand:DF 0 "register_operand" "=e")
5805 (plus:DF (match_operand:DF 1 "register_operand" "e")
5806 (match_operand:DF 2 "register_operand" "e")))]
5809 [(set_attr "type" "fp")
5810 (set_attr "fptype" "double")])
5812 (define_insn "addsf3"
5813 [(set (match_operand:SF 0 "register_operand" "=f")
5814 (plus:SF (match_operand:SF 1 "register_operand" "f")
5815 (match_operand:SF 2 "register_operand" "f")))]
5818 [(set_attr "type" "fp")])
5820 (define_expand "subtf3"
5821 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5822 (minus:TF (match_operand:TF 1 "general_operand" "")
5823 (match_operand:TF 2 "general_operand" "")))]
5824 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5825 "emit_tfmode_binop (MINUS, operands); DONE;")
5827 (define_insn "*subtf3_hq"
5828 [(set (match_operand:TF 0 "register_operand" "=e")
5829 (minus:TF (match_operand:TF 1 "register_operand" "e")
5830 (match_operand:TF 2 "register_operand" "e")))]
5831 "TARGET_FPU && TARGET_HARD_QUAD"
5833 [(set_attr "type" "fp")])
5835 (define_insn "subdf3"
5836 [(set (match_operand:DF 0 "register_operand" "=e")
5837 (minus:DF (match_operand:DF 1 "register_operand" "e")
5838 (match_operand:DF 2 "register_operand" "e")))]
5841 [(set_attr "type" "fp")
5842 (set_attr "fptype" "double")])
5844 (define_insn "subsf3"
5845 [(set (match_operand:SF 0 "register_operand" "=f")
5846 (minus:SF (match_operand:SF 1 "register_operand" "f")
5847 (match_operand:SF 2 "register_operand" "f")))]
5850 [(set_attr "type" "fp")])
5852 (define_expand "multf3"
5853 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5854 (mult:TF (match_operand:TF 1 "general_operand" "")
5855 (match_operand:TF 2 "general_operand" "")))]
5856 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5857 "emit_tfmode_binop (MULT, operands); DONE;")
5859 (define_insn "*multf3_hq"
5860 [(set (match_operand:TF 0 "register_operand" "=e")
5861 (mult:TF (match_operand:TF 1 "register_operand" "e")
5862 (match_operand:TF 2 "register_operand" "e")))]
5863 "TARGET_FPU && TARGET_HARD_QUAD"
5865 [(set_attr "type" "fpmul")])
5867 (define_insn "muldf3"
5868 [(set (match_operand:DF 0 "register_operand" "=e")
5869 (mult:DF (match_operand:DF 1 "register_operand" "e")
5870 (match_operand:DF 2 "register_operand" "e")))]
5873 [(set_attr "type" "fpmul")
5874 (set_attr "fptype" "double")])
5876 (define_insn "mulsf3"
5877 [(set (match_operand:SF 0 "register_operand" "=f")
5878 (mult:SF (match_operand:SF 1 "register_operand" "f")
5879 (match_operand:SF 2 "register_operand" "f")))]
5882 [(set_attr "type" "fpmul")])
5884 (define_insn "*muldf3_extend"
5885 [(set (match_operand:DF 0 "register_operand" "=e")
5886 (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "f"))
5887 (float_extend:DF (match_operand:SF 2 "register_operand" "f"))))]
5888 "(TARGET_V8 || TARGET_V9) && TARGET_FPU"
5889 "fsmuld\t%1, %2, %0"
5890 [(set_attr "type" "fpmul")
5891 (set_attr "fptype" "double")])
5893 (define_insn "*multf3_extend"
5894 [(set (match_operand:TF 0 "register_operand" "=e")
5895 (mult:TF (float_extend:TF (match_operand:DF 1 "register_operand" "e"))
5896 (float_extend:TF (match_operand:DF 2 "register_operand" "e"))))]
5897 "(TARGET_V8 || TARGET_V9) && TARGET_FPU && TARGET_HARD_QUAD"
5898 "fdmulq\t%1, %2, %0"
5899 [(set_attr "type" "fpmul")])
5901 (define_expand "divtf3"
5902 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5903 (div:TF (match_operand:TF 1 "general_operand" "")
5904 (match_operand:TF 2 "general_operand" "")))]
5905 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5906 "emit_tfmode_binop (DIV, operands); DONE;")
5908 ;; don't have timing for quad-prec. divide.
5909 (define_insn "*divtf3_hq"
5910 [(set (match_operand:TF 0 "register_operand" "=e")
5911 (div:TF (match_operand:TF 1 "register_operand" "e")
5912 (match_operand:TF 2 "register_operand" "e")))]
5913 "TARGET_FPU && TARGET_HARD_QUAD"
5915 [(set_attr "type" "fpdivd")])
5917 (define_insn "divdf3"
5918 [(set (match_operand:DF 0 "register_operand" "=e")
5919 (div:DF (match_operand:DF 1 "register_operand" "e")
5920 (match_operand:DF 2 "register_operand" "e")))]
5923 [(set_attr "type" "fpdivd")
5924 (set_attr "fptype" "double")])
5926 (define_insn "divsf3"
5927 [(set (match_operand:SF 0 "register_operand" "=f")
5928 (div:SF (match_operand:SF 1 "register_operand" "f")
5929 (match_operand:SF 2 "register_operand" "f")))]
5932 [(set_attr "type" "fpdivs")])
5934 (define_expand "negtf2"
5935 [(set (match_operand:TF 0 "register_operand" "=e,e")
5936 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
5940 (define_insn_and_split "*negtf2_notv9"
5941 [(set (match_operand:TF 0 "register_operand" "=e,e")
5942 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
5943 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
5949 "&& reload_completed
5950 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5951 [(set (match_dup 2) (neg:SF (match_dup 3)))
5952 (set (match_dup 4) (match_dup 5))
5953 (set (match_dup 6) (match_dup 7))]
5954 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
5955 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
5956 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
5957 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
5958 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
5959 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
5960 [(set_attr "type" "fpmove,*")
5961 (set_attr "length" "*,2")])
5963 (define_insn_and_split "*negtf2_v9"
5964 [(set (match_operand:TF 0 "register_operand" "=e,e")
5965 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
5966 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
5967 "TARGET_FPU && TARGET_V9"
5971 "&& reload_completed
5972 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5973 [(set (match_dup 2) (neg:DF (match_dup 3)))
5974 (set (match_dup 4) (match_dup 5))]
5975 "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
5976 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
5977 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
5978 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
5979 [(set_attr "type" "fpmove,*")
5980 (set_attr "length" "*,2")
5981 (set_attr "fptype" "double")])
5983 (define_expand "negdf2"
5984 [(set (match_operand:DF 0 "register_operand" "")
5985 (neg:DF (match_operand:DF 1 "register_operand" "")))]
5989 (define_insn_and_split "*negdf2_notv9"
5990 [(set (match_operand:DF 0 "register_operand" "=e,e")
5991 (neg:DF (match_operand:DF 1 "register_operand" "0,e")))]
5992 "TARGET_FPU && ! TARGET_V9"
5996 "&& reload_completed
5997 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5998 [(set (match_dup 2) (neg:SF (match_dup 3)))
5999 (set (match_dup 4) (match_dup 5))]
6000 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6001 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6002 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6003 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);"
6004 [(set_attr "type" "fpmove,*")
6005 (set_attr "length" "*,2")])
6007 (define_insn "*negdf2_v9"
6008 [(set (match_operand:DF 0 "register_operand" "=e")
6009 (neg:DF (match_operand:DF 1 "register_operand" "e")))]
6010 "TARGET_FPU && TARGET_V9"
6012 [(set_attr "type" "fpmove")
6013 (set_attr "fptype" "double")])
6015 (define_insn "negsf2"
6016 [(set (match_operand:SF 0 "register_operand" "=f")
6017 (neg:SF (match_operand:SF 1 "register_operand" "f")))]
6020 [(set_attr "type" "fpmove")])
6022 (define_expand "abstf2"
6023 [(set (match_operand:TF 0 "register_operand" "")
6024 (abs:TF (match_operand:TF 1 "register_operand" "")))]
6028 (define_insn_and_split "*abstf2_notv9"
6029 [(set (match_operand:TF 0 "register_operand" "=e,e")
6030 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6031 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
6032 "TARGET_FPU && ! TARGET_V9"
6036 "&& reload_completed
6037 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6038 [(set (match_dup 2) (abs:SF (match_dup 3)))
6039 (set (match_dup 4) (match_dup 5))
6040 (set (match_dup 6) (match_dup 7))]
6041 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6042 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6043 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6044 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
6045 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6046 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6047 [(set_attr "type" "fpmove,*")
6048 (set_attr "length" "*,2")])
6050 (define_insn "*abstf2_hq_v9"
6051 [(set (match_operand:TF 0 "register_operand" "=e,e")
6052 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6053 "TARGET_FPU && TARGET_V9 && TARGET_HARD_QUAD"
6057 [(set_attr "type" "fpmove")
6058 (set_attr "fptype" "double,*")])
6060 (define_insn_and_split "*abstf2_v9"
6061 [(set (match_operand:TF 0 "register_operand" "=e,e")
6062 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6063 "TARGET_FPU && TARGET_V9 && !TARGET_HARD_QUAD"
6067 "&& reload_completed
6068 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6069 [(set (match_dup 2) (abs:DF (match_dup 3)))
6070 (set (match_dup 4) (match_dup 5))]
6071 "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
6072 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
6073 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6074 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6075 [(set_attr "type" "fpmove,*")
6076 (set_attr "length" "*,2")
6077 (set_attr "fptype" "double,*")])
6079 (define_expand "absdf2"
6080 [(set (match_operand:DF 0 "register_operand" "")
6081 (abs:DF (match_operand:DF 1 "register_operand" "")))]
6085 (define_insn_and_split "*absdf2_notv9"
6086 [(set (match_operand:DF 0 "register_operand" "=e,e")
6087 (abs:DF (match_operand:DF 1 "register_operand" "0,e")))]
6088 "TARGET_FPU && ! TARGET_V9"
6092 "&& reload_completed
6093 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6094 [(set (match_dup 2) (abs:SF (match_dup 3)))
6095 (set (match_dup 4) (match_dup 5))]
6096 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6097 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6098 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6099 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);"
6100 [(set_attr "type" "fpmove,*")
6101 (set_attr "length" "*,2")])
6103 (define_insn "*absdf2_v9"
6104 [(set (match_operand:DF 0 "register_operand" "=e")
6105 (abs:DF (match_operand:DF 1 "register_operand" "e")))]
6106 "TARGET_FPU && TARGET_V9"
6108 [(set_attr "type" "fpmove")
6109 (set_attr "fptype" "double")])
6111 (define_insn "abssf2"
6112 [(set (match_operand:SF 0 "register_operand" "=f")
6113 (abs:SF (match_operand:SF 1 "register_operand" "f")))]
6116 [(set_attr "type" "fpmove")])
6118 (define_expand "sqrttf2"
6119 [(set (match_operand:TF 0 "nonimmediate_operand" "")
6120 (sqrt:TF (match_operand:TF 1 "general_operand" "")))]
6121 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6122 "emit_tfmode_unop (SQRT, operands); DONE;")
6124 (define_insn "*sqrttf2_hq"
6125 [(set (match_operand:TF 0 "register_operand" "=e")
6126 (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
6127 "TARGET_FPU && TARGET_HARD_QUAD"
6129 [(set_attr "type" "fpsqrtd")])
6131 (define_insn "sqrtdf2"
6132 [(set (match_operand:DF 0 "register_operand" "=e")
6133 (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
6136 [(set_attr "type" "fpsqrtd")
6137 (set_attr "fptype" "double")])
6139 (define_insn "sqrtsf2"
6140 [(set (match_operand:SF 0 "register_operand" "=f")
6141 (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
6144 [(set_attr "type" "fpsqrts")])
6147 ;; Arithmetic shift instructions.
6149 (define_insn "ashlsi3"
6150 [(set (match_operand:SI 0 "register_operand" "=r")
6151 (ashift:SI (match_operand:SI 1 "register_operand" "r")
6152 (match_operand:SI 2 "arith_operand" "rI")))]
6155 if (GET_CODE (operands[2]) == CONST_INT)
6156 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6157 return "sll\t%1, %2, %0";
6160 (if_then_else (match_operand 2 "const_one_operand" "")
6161 (const_string "ialu") (const_string "shift")))])
6163 (define_expand "ashldi3"
6164 [(set (match_operand:DI 0 "register_operand" "=r")
6165 (ashift:DI (match_operand:DI 1 "register_operand" "r")
6166 (match_operand:SI 2 "arith_operand" "rI")))]
6167 "TARGET_ARCH64 || TARGET_V8PLUS"
6169 if (! TARGET_ARCH64)
6171 if (GET_CODE (operands[2]) == CONST_INT)
6173 emit_insn (gen_ashldi3_v8plus (operands[0], operands[1], operands[2]));
6178 (define_insn "*ashldi3_sp64"
6179 [(set (match_operand:DI 0 "register_operand" "=r")
6180 (ashift:DI (match_operand:DI 1 "register_operand" "r")
6181 (match_operand:SI 2 "arith_operand" "rI")))]
6184 if (GET_CODE (operands[2]) == CONST_INT)
6185 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
6186 return "sllx\t%1, %2, %0";
6189 (if_then_else (match_operand 2 "const_one_operand" "")
6190 (const_string "ialu") (const_string "shift")))])
6193 (define_insn "ashldi3_v8plus"
6194 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
6195 (ashift:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
6196 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
6197 (clobber (match_scratch:SI 3 "=X,X,&h"))]
6199 "* return output_v8plus_shift (operands, insn, \"sllx\");"
6200 [(set_attr "type" "multi")
6201 (set_attr "length" "5,5,6")])
6203 ;; Optimize (1LL<<x)-1
6204 ;; XXX this also needs to be fixed to handle equal subregs
6205 ;; XXX first before we could re-enable it.
6207 ; [(set (match_operand:DI 0 "register_operand" "=h")
6208 ; (plus:DI (ashift:DI (const_int 1)
6209 ; (match_operand:SI 1 "arith_operand" "rI"))
6211 ; "0 && TARGET_V8PLUS"
6213 ; if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == REGNO (operands[0]))
6214 ; return "mov\t1, %L0\;sllx\t%L0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
6215 ; return "mov\t1, %H0\;sllx\t%H0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
6217 ; [(set_attr "type" "multi")
6218 ; (set_attr "length" "4")])
6220 (define_insn "*cmp_cc_ashift_1"
6221 [(set (reg:CC_NOOV 100)
6222 (compare:CC_NOOV (ashift:SI (match_operand:SI 0 "register_operand" "r")
6226 "addcc\t%0, %0, %%g0"
6227 [(set_attr "type" "compare")])
6229 (define_insn "*cmp_cc_set_ashift_1"
6230 [(set (reg:CC_NOOV 100)
6231 (compare:CC_NOOV (ashift:SI (match_operand:SI 1 "register_operand" "r")
6234 (set (match_operand:SI 0 "register_operand" "=r")
6235 (ashift:SI (match_dup 1) (const_int 1)))]
6238 [(set_attr "type" "compare")])
6240 (define_insn "ashrsi3"
6241 [(set (match_operand:SI 0 "register_operand" "=r")
6242 (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
6243 (match_operand:SI 2 "arith_operand" "rI")))]
6246 if (GET_CODE (operands[2]) == CONST_INT)
6247 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6248 return "sra\t%1, %2, %0";
6250 [(set_attr "type" "shift")])
6252 (define_insn "*ashrsi3_extend"
6253 [(set (match_operand:DI 0 "register_operand" "=r")
6254 (sign_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
6255 (match_operand:SI 2 "arith_operand" "r"))))]
6258 [(set_attr "type" "shift")])
6260 ;; This handles the case as above, but with constant shift instead of
6261 ;; register. Combiner "simplifies" it for us a little bit though.
6262 (define_insn "*ashrsi3_extend2"
6263 [(set (match_operand:DI 0 "register_operand" "=r")
6264 (ashiftrt:DI (ashift:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
6266 (match_operand:SI 2 "small_int_operand" "I")))]
6267 "TARGET_ARCH64 && INTVAL (operands[2]) >= 32 && INTVAL (operands[2]) < 64"
6269 operands[2] = GEN_INT (INTVAL (operands[2]) - 32);
6270 return "sra\t%1, %2, %0";
6272 [(set_attr "type" "shift")])
6274 (define_expand "ashrdi3"
6275 [(set (match_operand:DI 0 "register_operand" "=r")
6276 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
6277 (match_operand:SI 2 "arith_operand" "rI")))]
6278 "TARGET_ARCH64 || TARGET_V8PLUS"
6280 if (! TARGET_ARCH64)
6282 if (GET_CODE (operands[2]) == CONST_INT)
6283 FAIL; /* prefer generic code in this case */
6284 emit_insn (gen_ashrdi3_v8plus (operands[0], operands[1], operands[2]));
6289 (define_insn "*ashrdi3_sp64"
6290 [(set (match_operand:DI 0 "register_operand" "=r")
6291 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
6292 (match_operand:SI 2 "arith_operand" "rI")))]
6296 if (GET_CODE (operands[2]) == CONST_INT)
6297 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
6298 return "srax\t%1, %2, %0";
6300 [(set_attr "type" "shift")])
6303 (define_insn "ashrdi3_v8plus"
6304 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
6305 (ashiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
6306 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
6307 (clobber (match_scratch:SI 3 "=X,X,&h"))]
6309 "* return output_v8plus_shift (operands, insn, \"srax\");"
6310 [(set_attr "type" "multi")
6311 (set_attr "length" "5,5,6")])
6313 (define_insn "lshrsi3"
6314 [(set (match_operand:SI 0 "register_operand" "=r")
6315 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
6316 (match_operand:SI 2 "arith_operand" "rI")))]
6319 if (GET_CODE (operands[2]) == CONST_INT)
6320 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6321 return "srl\t%1, %2, %0";
6323 [(set_attr "type" "shift")])
6325 ;; This handles the case where
6326 ;; (zero_extend:DI (lshiftrt:SI (match_operand:SI) (match_operand:SI))),
6327 ;; but combiner "simplifies" it for us.
6328 (define_insn "*lshrsi3_extend"
6329 [(set (match_operand:DI 0 "register_operand" "=r")
6330 (and:DI (subreg:DI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
6331 (match_operand:SI 2 "arith_operand" "r")) 0)
6332 (match_operand 3 "const_int_operand" "")))]
6333 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) == 0xffffffff"
6335 [(set_attr "type" "shift")])
6337 ;; This handles the case where
6338 ;; (lshiftrt:DI (zero_extend:DI (match_operand:SI)) (const_int >=0 < 32))
6339 ;; but combiner "simplifies" it for us.
6340 (define_insn "*lshrsi3_extend2"
6341 [(set (match_operand:DI 0 "register_operand" "=r")
6342 (zero_extract:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
6343 (match_operand 2 "small_int_operand" "I")
6345 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
6347 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
6348 return "srl\t%1, %2, %0";
6350 [(set_attr "type" "shift")])
6352 (define_expand "lshrdi3"
6353 [(set (match_operand:DI 0 "register_operand" "=r")
6354 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6355 (match_operand:SI 2 "arith_operand" "rI")))]
6356 "TARGET_ARCH64 || TARGET_V8PLUS"
6358 if (! TARGET_ARCH64)
6360 if (GET_CODE (operands[2]) == CONST_INT)
6362 emit_insn (gen_lshrdi3_v8plus (operands[0], operands[1], operands[2]));
6367 (define_insn "*lshrdi3_sp64"
6368 [(set (match_operand:DI 0 "register_operand" "=r")
6369 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6370 (match_operand:SI 2 "arith_operand" "rI")))]
6373 if (GET_CODE (operands[2]) == CONST_INT)
6374 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
6375 return "srlx\t%1, %2, %0";
6377 [(set_attr "type" "shift")])
6380 (define_insn "lshrdi3_v8plus"
6381 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
6382 (lshiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
6383 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
6384 (clobber (match_scratch:SI 3 "=X,X,&h"))]
6386 "* return output_v8plus_shift (operands, insn, \"srlx\");"
6387 [(set_attr "type" "multi")
6388 (set_attr "length" "5,5,6")])
6391 [(set (match_operand:SI 0 "register_operand" "=r")
6392 (ashiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6394 (match_operand:SI 2 "small_int_operand" "I")))]
6395 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
6397 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
6398 return "srax\t%1, %2, %0";
6400 [(set_attr "type" "shift")])
6403 [(set (match_operand:SI 0 "register_operand" "=r")
6404 (lshiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
6406 (match_operand:SI 2 "small_int_operand" "I")))]
6407 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
6409 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
6410 return "srlx\t%1, %2, %0";
6412 [(set_attr "type" "shift")])
6415 [(set (match_operand:SI 0 "register_operand" "=r")
6416 (ashiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
6417 (match_operand:SI 2 "small_int_operand" "I")) 4)
6418 (match_operand:SI 3 "small_int_operand" "I")))]
6420 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
6421 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
6422 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
6424 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
6426 return "srax\t%1, %2, %0";
6428 [(set_attr "type" "shift")])
6431 [(set (match_operand:SI 0 "register_operand" "=r")
6432 (lshiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6433 (match_operand:SI 2 "small_int_operand" "I")) 4)
6434 (match_operand:SI 3 "small_int_operand" "I")))]
6436 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
6437 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
6438 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
6440 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
6442 return "srlx\t%1, %2, %0";
6444 [(set_attr "type" "shift")])
6447 ;; Unconditional and other jump instructions.
6450 [(set (pc) (label_ref (match_operand 0 "" "")))]
6452 "* return output_ubranch (operands[0], 0, insn);"
6453 [(set_attr "type" "uncond_branch")])
6455 (define_expand "tablejump"
6456 [(parallel [(set (pc) (match_operand 0 "register_operand" "r"))
6457 (use (label_ref (match_operand 1 "" "")))])]
6460 gcc_assert (GET_MODE (operands[0]) == CASE_VECTOR_MODE);
6462 /* In pic mode, our address differences are against the base of the
6463 table. Add that base value back in; CSE ought to be able to combine
6464 the two address loads. */
6468 tmp = gen_rtx_LABEL_REF (Pmode, operands[1]);
6470 if (CASE_VECTOR_MODE != Pmode)
6471 tmp2 = gen_rtx_SIGN_EXTEND (Pmode, tmp2);
6472 tmp = gen_rtx_PLUS (Pmode, tmp2, tmp);
6473 operands[0] = memory_address (Pmode, tmp);
6477 (define_insn "*tablejump_sp32"
6478 [(set (pc) (match_operand:SI 0 "address_operand" "p"))
6479 (use (label_ref (match_operand 1 "" "")))]
6482 [(set_attr "type" "uncond_branch")])
6484 (define_insn "*tablejump_sp64"
6485 [(set (pc) (match_operand:DI 0 "address_operand" "p"))
6486 (use (label_ref (match_operand 1 "" "")))]
6489 [(set_attr "type" "uncond_branch")])
6492 ;; Jump to subroutine instructions.
6494 (define_expand "call"
6495 ;; Note that this expression is not used for generating RTL.
6496 ;; All the RTL is generated explicitly below.
6497 [(call (match_operand 0 "call_operand" "")
6498 (match_operand 3 "" "i"))]
6499 ;; operands[2] is next_arg_register
6500 ;; operands[3] is struct_value_size_rtx.
6505 gcc_assert (MEM_P (operands[0]) && GET_MODE (operands[0]) == FUNCTION_MODE);
6507 gcc_assert (GET_CODE (operands[3]) == CONST_INT);
6509 if (GET_CODE (XEXP (operands[0], 0)) == LABEL_REF)
6511 /* This is really a PIC sequence. We want to represent
6512 it as a funny jump so its delay slots can be filled.
6514 ??? But if this really *is* a CALL, will not it clobber the
6515 call-clobbered registers? We lose this if it is a JUMP_INSN.
6516 Why cannot we have delay slots filled if it were a CALL? */
6518 /* We accept negative sizes for untyped calls. */
6519 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
6524 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
6526 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
6532 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
6533 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
6537 fn_rtx = operands[0];
6539 /* We accept negative sizes for untyped calls. */
6540 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
6541 sparc_emit_call_insn
6544 gen_rtvec (3, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx),
6546 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))),
6549 sparc_emit_call_insn
6552 gen_rtvec (2, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx),
6553 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))),
6561 ;; We can't use the same pattern for these two insns, because then registers
6562 ;; in the address may not be properly reloaded.
6564 (define_insn "*call_address_sp32"
6565 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6566 (match_operand 1 "" ""))
6567 (clobber (reg:SI 15))]
6568 ;;- Do not use operand 1 for most machines.
6571 [(set_attr "type" "call")])
6573 (define_insn "*call_symbolic_sp32"
6574 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6575 (match_operand 1 "" ""))
6576 (clobber (reg:SI 15))]
6577 ;;- Do not use operand 1 for most machines.
6580 [(set_attr "type" "call")])
6582 (define_insn "*call_address_sp64"
6583 [(call (mem:DI (match_operand:DI 0 "address_operand" "p"))
6584 (match_operand 1 "" ""))
6585 (clobber (reg:DI 15))]
6586 ;;- Do not use operand 1 for most machines.
6589 [(set_attr "type" "call")])
6591 (define_insn "*call_symbolic_sp64"
6592 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
6593 (match_operand 1 "" ""))
6594 (clobber (reg:DI 15))]
6595 ;;- Do not use operand 1 for most machines.
6598 [(set_attr "type" "call")])
6600 ;; This is a call that wants a structure value.
6601 ;; There is no such critter for v9 (??? we may need one anyway).
6602 (define_insn "*call_address_struct_value_sp32"
6603 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6604 (match_operand 1 "" ""))
6605 (match_operand 2 "immediate_operand" "")
6606 (clobber (reg:SI 15))]
6607 ;;- Do not use operand 1 for most machines.
6608 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
6610 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xfff);
6611 return "call\t%a0, %1\n\t nop\n\tunimp\t%2";
6613 [(set_attr "type" "call_no_delay_slot")
6614 (set_attr "length" "3")])
6616 ;; This is a call that wants a structure value.
6617 ;; There is no such critter for v9 (??? we may need one anyway).
6618 (define_insn "*call_symbolic_struct_value_sp32"
6619 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6620 (match_operand 1 "" ""))
6621 (match_operand 2 "immediate_operand" "")
6622 (clobber (reg:SI 15))]
6623 ;;- Do not use operand 1 for most machines.
6624 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
6626 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xfff);
6627 return "call\t%a0, %1\n\t nop\n\tunimp\t%2";
6629 [(set_attr "type" "call_no_delay_slot")
6630 (set_attr "length" "3")])
6632 ;; This is a call that may want a structure value. This is used for
6634 (define_insn "*call_address_untyped_struct_value_sp32"
6635 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6636 (match_operand 1 "" ""))
6637 (match_operand 2 "immediate_operand" "")
6638 (clobber (reg:SI 15))]
6639 ;;- Do not use operand 1 for most machines.
6640 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
6641 "call\t%a0, %1\n\t nop\n\tnop"
6642 [(set_attr "type" "call_no_delay_slot")
6643 (set_attr "length" "3")])
6645 ;; This is a call that may want a structure value. This is used for
6647 (define_insn "*call_symbolic_untyped_struct_value_sp32"
6648 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6649 (match_operand 1 "" ""))
6650 (match_operand 2 "immediate_operand" "")
6651 (clobber (reg:SI 15))]
6652 ;;- Do not use operand 1 for most machines.
6653 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
6654 "call\t%a0, %1\n\t nop\n\tnop"
6655 [(set_attr "type" "call_no_delay_slot")
6656 (set_attr "length" "3")])
6658 (define_expand "call_value"
6659 ;; Note that this expression is not used for generating RTL.
6660 ;; All the RTL is generated explicitly below.
6661 [(set (match_operand 0 "register_operand" "=rf")
6662 (call (match_operand 1 "" "")
6663 (match_operand 4 "" "")))]
6664 ;; operand 2 is stack_size_rtx
6665 ;; operand 3 is next_arg_register
6671 gcc_assert (MEM_P (operands[1]) && GET_MODE (operands[1]) == FUNCTION_MODE);
6673 fn_rtx = operands[1];
6676 gen_rtx_SET (VOIDmode, operands[0],
6677 gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx)),
6678 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)));
6680 sparc_emit_call_insn (gen_rtx_PARALLEL (VOIDmode, vec), XEXP (fn_rtx, 0));
6685 (define_insn "*call_value_address_sp32"
6686 [(set (match_operand 0 "" "=rf")
6687 (call (mem:SI (match_operand:SI 1 "address_operand" "p"))
6688 (match_operand 2 "" "")))
6689 (clobber (reg:SI 15))]
6690 ;;- Do not use operand 2 for most machines.
6693 [(set_attr "type" "call")])
6695 (define_insn "*call_value_symbolic_sp32"
6696 [(set (match_operand 0 "" "=rf")
6697 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
6698 (match_operand 2 "" "")))
6699 (clobber (reg:SI 15))]
6700 ;;- Do not use operand 2 for most machines.
6703 [(set_attr "type" "call")])
6705 (define_insn "*call_value_address_sp64"
6706 [(set (match_operand 0 "" "")
6707 (call (mem:DI (match_operand:DI 1 "address_operand" "p"))
6708 (match_operand 2 "" "")))
6709 (clobber (reg:DI 15))]
6710 ;;- Do not use operand 2 for most machines.
6713 [(set_attr "type" "call")])
6715 (define_insn "*call_value_symbolic_sp64"
6716 [(set (match_operand 0 "" "")
6717 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
6718 (match_operand 2 "" "")))
6719 (clobber (reg:DI 15))]
6720 ;;- Do not use operand 2 for most machines.
6723 [(set_attr "type" "call")])
6725 (define_expand "untyped_call"
6726 [(parallel [(call (match_operand 0 "" "")
6728 (match_operand:BLK 1 "memory_operand" "")
6729 (match_operand 2 "" "")])]
6732 rtx valreg1 = gen_rtx_REG (DImode, 8);
6733 rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
6734 rtx result = operands[1];
6736 /* Pass constm1 to indicate that it may expect a structure value, but
6737 we don't know what size it is. */
6738 emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, constm1_rtx));
6740 /* Save the function value registers. */
6741 emit_move_insn (adjust_address (result, DImode, 0), valreg1);
6742 emit_move_insn (adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8),
6745 /* The optimizer does not know that the call sets the function value
6746 registers we stored in the result block. We avoid problems by
6747 claiming that all hard registers are used and clobbered at this
6749 emit_insn (gen_blockage ());
6754 ;; Tail call instructions.
6756 (define_expand "sibcall"
6757 [(parallel [(call (match_operand 0 "call_operand" "") (const_int 0))
6762 (define_insn "*sibcall_symbolic_sp32"
6763 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6764 (match_operand 1 "" ""))
6767 "* return output_sibcall(insn, operands[0]);"
6768 [(set_attr "type" "sibcall")])
6770 (define_insn "*sibcall_symbolic_sp64"
6771 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
6772 (match_operand 1 "" ""))
6775 "* return output_sibcall(insn, operands[0]);"
6776 [(set_attr "type" "sibcall")])
6778 (define_expand "sibcall_value"
6779 [(parallel [(set (match_operand 0 "register_operand" "=rf")
6780 (call (match_operand 1 "" "") (const_int 0)))
6785 (define_insn "*sibcall_value_symbolic_sp32"
6786 [(set (match_operand 0 "" "=rf")
6787 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
6788 (match_operand 2 "" "")))
6791 "* return output_sibcall(insn, operands[1]);"
6792 [(set_attr "type" "sibcall")])
6794 (define_insn "*sibcall_value_symbolic_sp64"
6795 [(set (match_operand 0 "" "")
6796 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
6797 (match_operand 2 "" "")))
6800 "* return output_sibcall(insn, operands[1]);"
6801 [(set_attr "type" "sibcall")])
6804 ;; Special instructions.
6806 (define_expand "prologue"
6810 sparc_expand_prologue ();
6814 ;; The "save register window" insn is modelled as follows so that the DWARF-2
6815 ;; backend automatically emits the required call frame debugging information
6816 ;; while it is parsing it. Therefore, the pattern should not be modified
6817 ;; without first studying the impact of the changes on the debug info.
6818 ;; [(set (%fp) (%sp))
6819 ;; (set (%sp) (unspec_volatile [(%sp) (-frame_size)] UNSPECV_SAVEW))
6820 ;; (set (%i7) (%o7))]
6822 (define_insn "save_register_window<P:mode>"
6823 [(set (reg:P 30) (reg:P 14))
6824 (set (reg:P 14) (unspec_volatile:P [(reg:P 14)
6825 (match_operand:P 0 "arith_operand" "rI")] UNSPECV_SAVEW))
6826 (set (reg:P 31) (reg:P 15))]
6828 "save\t%%sp, %0, %%sp"
6829 [(set_attr "type" "savew")])
6831 (define_expand "epilogue"
6835 sparc_expand_epilogue ();
6838 (define_expand "sibcall_epilogue"
6842 sparc_expand_epilogue ();
6846 (define_expand "return"
6848 "sparc_can_use_return_insn_p ()"
6851 (define_insn "*return_internal"
6854 "* return output_return (insn);"
6855 [(set_attr "type" "return")
6856 (set (attr "length")
6857 (cond [(eq_attr "leaf_function" "true")
6858 (if_then_else (eq_attr "empty_delay_slot" "true")
6861 (eq_attr "calls_eh_return" "true")
6862 (if_then_else (eq_attr "delayed_branch" "true")
6863 (if_then_else (eq_attr "isa" "v9")
6866 (if_then_else (eq_attr "isa" "v9")
6869 (eq_attr "empty_delay_slot" "true")
6870 (if_then_else (eq_attr "delayed_branch" "true")
6875 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
6876 ;; all of memory. This blocks insns from being moved across this point.
6878 (define_insn "blockage"
6879 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
6882 [(set_attr "length" "0")])
6884 ;; Prepare to return any type including a structure value.
6886 (define_expand "untyped_return"
6887 [(match_operand:BLK 0 "memory_operand" "")
6888 (match_operand 1 "" "")]
6891 rtx valreg1 = gen_rtx_REG (DImode, 24);
6892 rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
6893 rtx result = operands[0];
6895 if (! TARGET_ARCH64)
6897 rtx rtnreg = gen_rtx_REG (SImode, (current_function_uses_only_leaf_regs
6899 rtx value = gen_reg_rtx (SImode);
6901 /* Fetch the instruction where we will return to and see if it's an unimp
6902 instruction (the most significant 10 bits will be zero). If so,
6903 update the return address to skip the unimp instruction. */
6904 emit_move_insn (value,
6905 gen_rtx_MEM (SImode, plus_constant (rtnreg, 8)));
6906 emit_insn (gen_lshrsi3 (value, value, GEN_INT (22)));
6907 emit_insn (gen_update_return (rtnreg, value));
6910 /* Reload the function value registers. */
6911 emit_move_insn (valreg1, adjust_address (result, DImode, 0));
6912 emit_move_insn (valreg2,
6913 adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8));
6915 /* Put USE insns before the return. */
6919 /* Construct the return. */
6920 expand_naked_return ();
6925 ;; Adjust the return address conditionally. If the value of op1 is equal
6926 ;; to all zero then adjust the return address i.e. op0 = op0 + 4.
6927 ;; This is technically *half* the check required by the 32-bit SPARC
6928 ;; psABI. This check only ensures that an "unimp" insn was written by
6929 ;; the caller, but doesn't check to see if the expected size matches
6930 ;; (this is encoded in the 12 lower bits). This check is obsolete and
6931 ;; only used by the above code "untyped_return".
6933 (define_insn "update_return"
6934 [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
6935 (match_operand:SI 1 "register_operand" "r")] UNSPEC_UPDATE_RETURN)]
6938 if (flag_delayed_branch)
6939 return "cmp\t%1, 0\n\tbe,a\t.+8\n\t add\t%0, 4, %0";
6941 return "cmp\t%1, 0\n\tbne\t.+12\n\t nop\n\tadd\t%0, 4, %0";
6943 [(set (attr "type") (const_string "multi"))
6944 (set (attr "length")
6945 (if_then_else (eq_attr "delayed_branch" "true")
6954 (define_expand "indirect_jump"
6955 [(set (pc) (match_operand 0 "address_operand" "p"))]
6959 (define_insn "*branch_sp32"
6960 [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
6963 [(set_attr "type" "uncond_branch")])
6965 (define_insn "*branch_sp64"
6966 [(set (pc) (match_operand:DI 0 "address_operand" "p"))]
6969 [(set_attr "type" "uncond_branch")])
6971 (define_expand "nonlocal_goto"
6972 [(match_operand:SI 0 "general_operand" "")
6973 (match_operand:SI 1 "general_operand" "")
6974 (match_operand:SI 2 "general_operand" "")
6975 (match_operand:SI 3 "" "")]
6978 rtx lab = operands[1];
6979 rtx stack = operands[2];
6980 rtx fp = operands[3];
6983 /* Trap instruction to flush all the register windows. */
6984 emit_insn (gen_flush_register_windows ());
6986 /* Load the fp value for the containing fn into %fp. This is needed
6987 because STACK refers to %fp. Note that virtual register instantiation
6988 fails if the virtual %fp isn't set from a register. */
6989 if (GET_CODE (fp) != REG)
6990 fp = force_reg (Pmode, fp);
6991 emit_move_insn (virtual_stack_vars_rtx, fp);
6993 /* Find the containing function's current nonlocal goto handler,
6994 which will do any cleanups and then jump to the label. */
6995 labreg = gen_rtx_REG (Pmode, 8);
6996 emit_move_insn (labreg, lab);
6998 /* Restore %fp from stack pointer value for containing function.
6999 The restore insn that follows will move this to %sp,
7000 and reload the appropriate value into %fp. */
7001 emit_move_insn (hard_frame_pointer_rtx, stack);
7003 emit_use (stack_pointer_rtx);
7004 emit_use (static_chain_rtx);
7006 /* ??? The V9-specific version was disabled in rev 1.65. */
7007 emit_jump_insn (gen_goto_handler_and_restore (labreg));
7012 ;; Special trap insn to flush register windows.
7013 (define_insn "flush_register_windows"
7014 [(unspec_volatile [(const_int 0)] UNSPECV_FLUSHW)]
7016 { return TARGET_V9 ? "flushw" : "ta\t3"; }
7017 [(set_attr "type" "flushw")])
7019 (define_insn "goto_handler_and_restore"
7020 [(unspec_volatile [(match_operand 0 "register_operand" "=r")] UNSPECV_GOTO)]
7021 "GET_MODE (operands[0]) == Pmode"
7023 if (flag_delayed_branch)
7024 return "jmp\t%0\n\t restore";
7026 return "mov\t%0,%%g1\n\trestore\n\tjmp\t%%g1\n\t nop";
7028 [(set (attr "type") (const_string "multi"))
7029 (set (attr "length")
7030 (if_then_else (eq_attr "delayed_branch" "true")
7034 ;; For __builtin_setjmp we need to flush register windows iff the function
7035 ;; calls alloca as well, because otherwise the register window might be
7036 ;; saved after %sp adjustment and thus setjmp would crash
7037 (define_expand "builtin_setjmp_setup"
7038 [(match_operand 0 "register_operand" "r")]
7041 emit_insn (gen_do_builtin_setjmp_setup ());
7045 (define_insn "do_builtin_setjmp_setup"
7046 [(unspec_volatile [(const_int 0)] UNSPECV_SETJMP)]
7049 if (! cfun->calls_alloca)
7053 fputs ("\tflushw\n", asm_out_file);
7055 fprintf (asm_out_file, "\tst%c\t%%l7, [%%sp+%d]\n",
7056 TARGET_ARCH64 ? 'x' : 'w',
7057 SPARC_STACK_BIAS + 7 * UNITS_PER_WORD);
7058 fprintf (asm_out_file, "\tst%c\t%%fp, [%%sp+%d]\n",
7059 TARGET_ARCH64 ? 'x' : 'w',
7060 SPARC_STACK_BIAS + 14 * UNITS_PER_WORD);
7061 fprintf (asm_out_file, "\tst%c\t%%i7, [%%sp+%d]\n",
7062 TARGET_ARCH64 ? 'x' : 'w',
7063 SPARC_STACK_BIAS + 15 * UNITS_PER_WORD);
7066 [(set_attr "type" "multi")
7067 (set (attr "length")
7068 (cond [(eq_attr "calls_alloca" "false")
7070 (eq_attr "isa" "!v9")
7072 (eq_attr "pic" "true")
7073 (const_int 4)] (const_int 3)))])
7075 ;; Pattern for use after a setjmp to store FP and the return register
7076 ;; into the stack area.
7078 (define_expand "setjmp"
7084 mem = gen_rtx_MEM (Pmode,
7085 plus_constant (stack_pointer_rtx,
7086 SPARC_STACK_BIAS + 14 * UNITS_PER_WORD));
7087 emit_insn (gen_rtx_SET (VOIDmode, mem, frame_pointer_rtx));
7089 mem = gen_rtx_MEM (Pmode,
7090 plus_constant (stack_pointer_rtx,
7091 SPARC_STACK_BIAS + 15 * UNITS_PER_WORD));
7092 emit_insn (gen_rtx_SET (VOIDmode, mem, gen_rtx_REG (Pmode, 31)));
7096 ;; Special pattern for the FLUSH instruction.
7098 ; We do SImode and DImode versions of this to quiet down genrecog's complaints
7099 ; of the define_insn otherwise missing a mode. We make "flush", aka
7100 ; gen_flush, the default one since sparc_initialize_trampoline uses
7101 ; it on SImode mem values.
7103 (define_insn "flush"
7104 [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")] UNSPECV_FLUSH)]
7106 { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; }
7107 [(set_attr "type" "iflush")])
7109 (define_insn "flushdi"
7110 [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")] UNSPECV_FLUSH)]
7112 { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; }
7113 [(set_attr "type" "iflush")])
7116 ;; Find first set instructions.
7118 ;; The scan instruction searches from the most significant bit while ffs
7119 ;; searches from the least significant bit. The bit index and treatment of
7120 ;; zero also differ. It takes at least 7 instructions to get the proper
7121 ;; result. Here is an obvious 8 instruction sequence.
7124 (define_insn "ffssi2"
7125 [(set (match_operand:SI 0 "register_operand" "=&r")
7126 (ffs:SI (match_operand:SI 1 "register_operand" "r")))
7127 (clobber (match_scratch:SI 2 "=&r"))]
7128 "TARGET_SPARCLITE || TARGET_SPARCLET"
7130 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";
7132 [(set_attr "type" "multi")
7133 (set_attr "length" "8")])
7135 ;; ??? This should be a define expand, so that the extra instruction have
7136 ;; a chance of being optimized away.
7138 ;; Disabled because none of the UltraSPARCs implement popc. The HAL R1
7139 ;; does, but no one uses that and we don't have a switch for it.
7141 ;(define_insn "ffsdi2"
7142 ; [(set (match_operand:DI 0 "register_operand" "=&r")
7143 ; (ffs:DI (match_operand:DI 1 "register_operand" "r")))
7144 ; (clobber (match_scratch:DI 2 "=&r"))]
7146 ; "neg\t%1, %2\;xnor\t%1, %2, %2\;popc\t%2, %0\;movzr\t%1, 0, %0"
7147 ; [(set_attr "type" "multi")
7148 ; (set_attr "length" "4")])
7152 ;; Peepholes go at the end.
7154 ;; Optimize consecutive loads or stores into ldd and std when possible.
7155 ;; The conditions in which we do this are very restricted and are
7156 ;; explained in the code for {registers,memory}_ok_for_ldd functions.
7159 [(set (match_operand:SI 0 "memory_operand" "")
7161 (set (match_operand:SI 1 "memory_operand" "")
7164 && mems_ok_for_ldd_peep (operands[0], operands[1], NULL_RTX)"
7167 "operands[0] = widen_memory_access (operands[0], DImode, 0);")
7170 [(set (match_operand:SI 0 "memory_operand" "")
7172 (set (match_operand:SI 1 "memory_operand" "")
7175 && mems_ok_for_ldd_peep (operands[1], operands[0], NULL_RTX)"
7178 "operands[1] = widen_memory_access (operands[1], DImode, 0);")
7181 [(set (match_operand:SI 0 "register_operand" "")
7182 (match_operand:SI 1 "memory_operand" ""))
7183 (set (match_operand:SI 2 "register_operand" "")
7184 (match_operand:SI 3 "memory_operand" ""))]
7185 "registers_ok_for_ldd_peep (operands[0], operands[2])
7186 && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
7189 "operands[1] = widen_memory_access (operands[1], DImode, 0);
7190 operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));")
7193 [(set (match_operand:SI 0 "memory_operand" "")
7194 (match_operand:SI 1 "register_operand" ""))
7195 (set (match_operand:SI 2 "memory_operand" "")
7196 (match_operand:SI 3 "register_operand" ""))]
7197 "registers_ok_for_ldd_peep (operands[1], operands[3])
7198 && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
7201 "operands[0] = widen_memory_access (operands[0], DImode, 0);
7202 operands[1] = gen_rtx_REG (DImode, REGNO (operands[1]));")
7205 [(set (match_operand:SF 0 "register_operand" "")
7206 (match_operand:SF 1 "memory_operand" ""))
7207 (set (match_operand:SF 2 "register_operand" "")
7208 (match_operand:SF 3 "memory_operand" ""))]
7209 "registers_ok_for_ldd_peep (operands[0], operands[2])
7210 && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
7213 "operands[1] = widen_memory_access (operands[1], DFmode, 0);
7214 operands[0] = gen_rtx_REG (DFmode, REGNO (operands[0]));")
7217 [(set (match_operand:SF 0 "memory_operand" "")
7218 (match_operand:SF 1 "register_operand" ""))
7219 (set (match_operand:SF 2 "memory_operand" "")
7220 (match_operand:SF 3 "register_operand" ""))]
7221 "registers_ok_for_ldd_peep (operands[1], operands[3])
7222 && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
7225 "operands[0] = widen_memory_access (operands[0], DFmode, 0);
7226 operands[1] = gen_rtx_REG (DFmode, REGNO (operands[1]));")
7229 [(set (match_operand:SI 0 "register_operand" "")
7230 (match_operand:SI 1 "memory_operand" ""))
7231 (set (match_operand:SI 2 "register_operand" "")
7232 (match_operand:SI 3 "memory_operand" ""))]
7233 "registers_ok_for_ldd_peep (operands[2], operands[0])
7234 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
7237 "operands[3] = widen_memory_access (operands[3], DImode, 0);
7238 operands[2] = gen_rtx_REG (DImode, REGNO (operands[2]));")
7241 [(set (match_operand:SI 0 "memory_operand" "")
7242 (match_operand:SI 1 "register_operand" ""))
7243 (set (match_operand:SI 2 "memory_operand" "")
7244 (match_operand:SI 3 "register_operand" ""))]
7245 "registers_ok_for_ldd_peep (operands[3], operands[1])
7246 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
7249 "operands[2] = widen_memory_access (operands[2], DImode, 0);
7250 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
7254 [(set (match_operand:SF 0 "register_operand" "")
7255 (match_operand:SF 1 "memory_operand" ""))
7256 (set (match_operand:SF 2 "register_operand" "")
7257 (match_operand:SF 3 "memory_operand" ""))]
7258 "registers_ok_for_ldd_peep (operands[2], operands[0])
7259 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
7262 "operands[3] = widen_memory_access (operands[3], DFmode, 0);
7263 operands[2] = gen_rtx_REG (DFmode, REGNO (operands[2]));")
7266 [(set (match_operand:SF 0 "memory_operand" "")
7267 (match_operand:SF 1 "register_operand" ""))
7268 (set (match_operand:SF 2 "memory_operand" "")
7269 (match_operand:SF 3 "register_operand" ""))]
7270 "registers_ok_for_ldd_peep (operands[3], operands[1])
7271 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
7274 "operands[2] = widen_memory_access (operands[2], DFmode, 0);
7275 operands[3] = gen_rtx_REG (DFmode, REGNO (operands[3]));")
7277 ;; Optimize the case of following a reg-reg move with a test
7278 ;; of reg just moved. Don't allow floating point regs for operand 0 or 1.
7279 ;; This can result from a float to fix conversion.
7282 [(set (match_operand:SI 0 "register_operand" "")
7283 (match_operand:SI 1 "register_operand" ""))
7285 (compare:CC (match_operand:SI 2 "register_operand" "")
7287 "(rtx_equal_p (operands[2], operands[0])
7288 || rtx_equal_p (operands[2], operands[1]))
7289 && ! SPARC_FP_REG_P (REGNO (operands[0]))
7290 && ! SPARC_FP_REG_P (REGNO (operands[1]))"
7291 [(parallel [(set (match_dup 0) (match_dup 1))
7293 (compare:CC (match_dup 1) (const_int 0)))])]
7297 [(set (match_operand:DI 0 "register_operand" "")
7298 (match_operand:DI 1 "register_operand" ""))
7300 (compare:CCX (match_operand:DI 2 "register_operand" "")
7303 && (rtx_equal_p (operands[2], operands[0])
7304 || rtx_equal_p (operands[2], operands[1]))
7305 && ! SPARC_FP_REG_P (REGNO (operands[0]))
7306 && ! SPARC_FP_REG_P (REGNO (operands[1]))"
7307 [(parallel [(set (match_dup 0) (match_dup 1))
7309 (compare:CCX (match_dup 1) (const_int 0)))])]
7313 ;; Prefetch instructions.
7315 ;; ??? UltraSPARC-III note: A memory operation loading into the floating point register
7316 ;; ??? file, if it hits the prefetch cache, has a chance to dual-issue with other memory
7317 ;; ??? operations. With DFA we might be able to model this, but it requires a lot of
7319 (define_expand "prefetch"
7320 [(match_operand 0 "address_operand" "")
7321 (match_operand 1 "const_int_operand" "")
7322 (match_operand 2 "const_int_operand" "")]
7326 emit_insn (gen_prefetch_64 (operands[0], operands[1], operands[2]));
7328 emit_insn (gen_prefetch_32 (operands[0], operands[1], operands[2]));
7332 (define_insn "prefetch_64"
7333 [(prefetch (match_operand:DI 0 "address_operand" "p")
7334 (match_operand:DI 1 "const_int_operand" "n")
7335 (match_operand:DI 2 "const_int_operand" "n"))]
7338 static const char * const prefetch_instr[2][2] = {
7340 "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
7341 "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
7344 "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
7345 "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
7348 int read_or_write = INTVAL (operands[1]);
7349 int locality = INTVAL (operands[2]);
7351 gcc_assert (read_or_write == 0 || read_or_write == 1);
7352 gcc_assert (locality >= 0 && locality < 4);
7353 return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
7355 [(set_attr "type" "load")])
7357 (define_insn "prefetch_32"
7358 [(prefetch (match_operand:SI 0 "address_operand" "p")
7359 (match_operand:SI 1 "const_int_operand" "n")
7360 (match_operand:SI 2 "const_int_operand" "n"))]
7363 static const char * const prefetch_instr[2][2] = {
7365 "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
7366 "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
7369 "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
7370 "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
7373 int read_or_write = INTVAL (operands[1]);
7374 int locality = INTVAL (operands[2]);
7376 gcc_assert (read_or_write == 0 || read_or_write == 1);
7377 gcc_assert (locality >= 0 && locality < 4);
7378 return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
7380 [(set_attr "type" "load")])
7383 ;; Trap instructions.
7386 [(trap_if (const_int 1) (const_int 5))]
7389 [(set_attr "type" "trap")])
7391 (define_expand "conditional_trap"
7392 [(trap_if (match_operator 0 "noov_compare_operator" [(match_dup 2) (match_dup 3)])
7393 (match_operand:SI 1 "arith_operand" ""))]
7395 "operands[2] = gen_compare_reg (GET_CODE (operands[0]));
7396 if (GET_MODE (operands[2]) != CCmode && GET_MODE (operands[2]) != CCXmode)
7398 operands[3] = const0_rtx;")
7401 [(trap_if (match_operator 0 "noov_compare_operator" [(reg:CC 100) (const_int 0)])
7402 (match_operand:SI 1 "arith_operand" "rM"))]
7406 return "t%C0\t%%icc, %1";
7410 [(set_attr "type" "trap")])
7413 [(trap_if (match_operator 0 "noov_compare_operator" [(reg:CCX 100) (const_int 0)])
7414 (match_operand:SI 1 "arith_operand" "rM"))]
7417 [(set_attr "type" "trap")])
7420 ;; TLS support instructions.
7422 (define_insn "tgd_hi22"
7423 [(set (match_operand:SI 0 "register_operand" "=r")
7424 (high:SI (unspec:SI [(match_operand 1 "tgd_symbolic_operand" "")]
7427 "sethi\\t%%tgd_hi22(%a1), %0")
7429 (define_insn "tgd_lo10"
7430 [(set (match_operand:SI 0 "register_operand" "=r")
7431 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7432 (unspec:SI [(match_operand 2 "tgd_symbolic_operand" "")]
7435 "add\\t%1, %%tgd_lo10(%a2), %0")
7437 (define_insn "tgd_add32"
7438 [(set (match_operand:SI 0 "register_operand" "=r")
7439 (plus:SI (match_operand:SI 1 "register_operand" "r")
7440 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7441 (match_operand 3 "tgd_symbolic_operand" "")]
7443 "TARGET_TLS && TARGET_ARCH32"
7444 "add\\t%1, %2, %0, %%tgd_add(%a3)")
7446 (define_insn "tgd_add64"
7447 [(set (match_operand:DI 0 "register_operand" "=r")
7448 (plus:DI (match_operand:DI 1 "register_operand" "r")
7449 (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7450 (match_operand 3 "tgd_symbolic_operand" "")]
7452 "TARGET_TLS && TARGET_ARCH64"
7453 "add\\t%1, %2, %0, %%tgd_add(%a3)")
7455 (define_insn "tgd_call32"
7456 [(set (match_operand 0 "register_operand" "=r")
7457 (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")
7458 (match_operand 2 "tgd_symbolic_operand" "")]
7460 (match_operand 3 "" "")))
7461 (clobber (reg:SI 15))]
7462 "TARGET_TLS && TARGET_ARCH32"
7463 "call\t%a1, %%tgd_call(%a2)%#"
7464 [(set_attr "type" "call")])
7466 (define_insn "tgd_call64"
7467 [(set (match_operand 0 "register_operand" "=r")
7468 (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")
7469 (match_operand 2 "tgd_symbolic_operand" "")]
7471 (match_operand 3 "" "")))
7472 (clobber (reg:DI 15))]
7473 "TARGET_TLS && TARGET_ARCH64"
7474 "call\t%a1, %%tgd_call(%a2)%#"
7475 [(set_attr "type" "call")])
7477 (define_insn "tldm_hi22"
7478 [(set (match_operand:SI 0 "register_operand" "=r")
7479 (high:SI (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
7481 "sethi\\t%%tldm_hi22(%&), %0")
7483 (define_insn "tldm_lo10"
7484 [(set (match_operand:SI 0 "register_operand" "=r")
7485 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7486 (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
7488 "add\\t%1, %%tldm_lo10(%&), %0")
7490 (define_insn "tldm_add32"
7491 [(set (match_operand:SI 0 "register_operand" "=r")
7492 (plus:SI (match_operand:SI 1 "register_operand" "r")
7493 (unspec:SI [(match_operand:SI 2 "register_operand" "r")]
7495 "TARGET_TLS && TARGET_ARCH32"
7496 "add\\t%1, %2, %0, %%tldm_add(%&)")
7498 (define_insn "tldm_add64"
7499 [(set (match_operand:DI 0 "register_operand" "=r")
7500 (plus:DI (match_operand:DI 1 "register_operand" "r")
7501 (unspec:DI [(match_operand:SI 2 "register_operand" "r")]
7503 "TARGET_TLS && TARGET_ARCH64"
7504 "add\\t%1, %2, %0, %%tldm_add(%&)")
7506 (define_insn "tldm_call32"
7507 [(set (match_operand 0 "register_operand" "=r")
7508 (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")]
7510 (match_operand 2 "" "")))
7511 (clobber (reg:SI 15))]
7512 "TARGET_TLS && TARGET_ARCH32"
7513 "call\t%a1, %%tldm_call(%&)%#"
7514 [(set_attr "type" "call")])
7516 (define_insn "tldm_call64"
7517 [(set (match_operand 0 "register_operand" "=r")
7518 (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")]
7520 (match_operand 2 "" "")))
7521 (clobber (reg:DI 15))]
7522 "TARGET_TLS && TARGET_ARCH64"
7523 "call\t%a1, %%tldm_call(%&)%#"
7524 [(set_attr "type" "call")])
7526 (define_insn "tldo_hix22"
7527 [(set (match_operand:SI 0 "register_operand" "=r")
7528 (high:SI (unspec:SI [(match_operand 1 "tld_symbolic_operand" "")]
7531 "sethi\\t%%tldo_hix22(%a1), %0")
7533 (define_insn "tldo_lox10"
7534 [(set (match_operand:SI 0 "register_operand" "=r")
7535 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7536 (unspec:SI [(match_operand 2 "tld_symbolic_operand" "")]
7539 "xor\\t%1, %%tldo_lox10(%a2), %0")
7541 (define_insn "tldo_add32"
7542 [(set (match_operand:SI 0 "register_operand" "=r")
7543 (plus:SI (match_operand:SI 1 "register_operand" "r")
7544 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7545 (match_operand 3 "tld_symbolic_operand" "")]
7547 "TARGET_TLS && TARGET_ARCH32"
7548 "add\\t%1, %2, %0, %%tldo_add(%a3)")
7550 (define_insn "tldo_add64"
7551 [(set (match_operand:DI 0 "register_operand" "=r")
7552 (plus:DI (match_operand:DI 1 "register_operand" "r")
7553 (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7554 (match_operand 3 "tld_symbolic_operand" "")]
7556 "TARGET_TLS && TARGET_ARCH64"
7557 "add\\t%1, %2, %0, %%tldo_add(%a3)")
7559 (define_insn "tie_hi22"
7560 [(set (match_operand:SI 0 "register_operand" "=r")
7561 (high:SI (unspec:SI [(match_operand 1 "tie_symbolic_operand" "")]
7564 "sethi\\t%%tie_hi22(%a1), %0")
7566 (define_insn "tie_lo10"
7567 [(set (match_operand:SI 0 "register_operand" "=r")
7568 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7569 (unspec:SI [(match_operand 2 "tie_symbolic_operand" "")]
7572 "add\\t%1, %%tie_lo10(%a2), %0")
7574 (define_insn "tie_ld32"
7575 [(set (match_operand:SI 0 "register_operand" "=r")
7576 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
7577 (match_operand:SI 2 "register_operand" "r")
7578 (match_operand 3 "tie_symbolic_operand" "")]
7580 "TARGET_TLS && TARGET_ARCH32"
7581 "ld\\t[%1 + %2], %0, %%tie_ld(%a3)"
7582 [(set_attr "type" "load")])
7584 (define_insn "tie_ld64"
7585 [(set (match_operand:DI 0 "register_operand" "=r")
7586 (unspec:DI [(match_operand:DI 1 "register_operand" "r")
7587 (match_operand:SI 2 "register_operand" "r")
7588 (match_operand 3 "tie_symbolic_operand" "")]
7590 "TARGET_TLS && TARGET_ARCH64"
7591 "ldx\\t[%1 + %2], %0, %%tie_ldx(%a3)"
7592 [(set_attr "type" "load")])
7594 (define_insn "tie_add32"
7595 [(set (match_operand:SI 0 "register_operand" "=r")
7596 (plus:SI (match_operand:SI 1 "register_operand" "r")
7597 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7598 (match_operand 3 "tie_symbolic_operand" "")]
7600 "TARGET_SUN_TLS && TARGET_ARCH32"
7601 "add\\t%1, %2, %0, %%tie_add(%a3)")
7603 (define_insn "tie_add64"
7604 [(set (match_operand:DI 0 "register_operand" "=r")
7605 (plus:DI (match_operand:DI 1 "register_operand" "r")
7606 (unspec:DI [(match_operand:DI 2 "register_operand" "r")
7607 (match_operand 3 "tie_symbolic_operand" "")]
7609 "TARGET_SUN_TLS && TARGET_ARCH64"
7610 "add\\t%1, %2, %0, %%tie_add(%a3)")
7612 (define_insn "tle_hix22_sp32"
7613 [(set (match_operand:SI 0 "register_operand" "=r")
7614 (high:SI (unspec:SI [(match_operand 1 "tle_symbolic_operand" "")]
7616 "TARGET_TLS && TARGET_ARCH32"
7617 "sethi\\t%%tle_hix22(%a1), %0")
7619 (define_insn "tle_lox10_sp32"
7620 [(set (match_operand:SI 0 "register_operand" "=r")
7621 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7622 (unspec:SI [(match_operand 2 "tle_symbolic_operand" "")]
7624 "TARGET_TLS && TARGET_ARCH32"
7625 "xor\\t%1, %%tle_lox10(%a2), %0")
7627 (define_insn "tle_hix22_sp64"
7628 [(set (match_operand:DI 0 "register_operand" "=r")
7629 (high:DI (unspec:DI [(match_operand 1 "tle_symbolic_operand" "")]
7631 "TARGET_TLS && TARGET_ARCH64"
7632 "sethi\\t%%tle_hix22(%a1), %0")
7634 (define_insn "tle_lox10_sp64"
7635 [(set (match_operand:DI 0 "register_operand" "=r")
7636 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
7637 (unspec:DI [(match_operand 2 "tle_symbolic_operand" "")]
7639 "TARGET_TLS && TARGET_ARCH64"
7640 "xor\\t%1, %%tle_lox10(%a2), %0")
7642 ;; Now patterns combining tldo_add{32,64} with some integer loads or stores
7643 (define_insn "*tldo_ldub_sp32"
7644 [(set (match_operand:QI 0 "register_operand" "=r")
7645 (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7646 (match_operand 3 "tld_symbolic_operand" "")]
7648 (match_operand:SI 1 "register_operand" "r"))))]
7649 "TARGET_TLS && TARGET_ARCH32"
7650 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7651 [(set_attr "type" "load")
7652 (set_attr "us3load_type" "3cycle")])
7654 (define_insn "*tldo_ldub1_sp32"
7655 [(set (match_operand:HI 0 "register_operand" "=r")
7656 (zero_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7657 (match_operand 3 "tld_symbolic_operand" "")]
7659 (match_operand:SI 1 "register_operand" "r")))))]
7660 "TARGET_TLS && TARGET_ARCH32"
7661 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7662 [(set_attr "type" "load")
7663 (set_attr "us3load_type" "3cycle")])
7665 (define_insn "*tldo_ldub2_sp32"
7666 [(set (match_operand:SI 0 "register_operand" "=r")
7667 (zero_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7668 (match_operand 3 "tld_symbolic_operand" "")]
7670 (match_operand:SI 1 "register_operand" "r")))))]
7671 "TARGET_TLS && TARGET_ARCH32"
7672 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7673 [(set_attr "type" "load")
7674 (set_attr "us3load_type" "3cycle")])
7676 (define_insn "*tldo_ldsb1_sp32"
7677 [(set (match_operand:HI 0 "register_operand" "=r")
7678 (sign_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7679 (match_operand 3 "tld_symbolic_operand" "")]
7681 (match_operand:SI 1 "register_operand" "r")))))]
7682 "TARGET_TLS && TARGET_ARCH32"
7683 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7684 [(set_attr "type" "sload")
7685 (set_attr "us3load_type" "3cycle")])
7687 (define_insn "*tldo_ldsb2_sp32"
7688 [(set (match_operand:SI 0 "register_operand" "=r")
7689 (sign_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7690 (match_operand 3 "tld_symbolic_operand" "")]
7692 (match_operand:SI 1 "register_operand" "r")))))]
7693 "TARGET_TLS && TARGET_ARCH32"
7694 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7695 [(set_attr "type" "sload")
7696 (set_attr "us3load_type" "3cycle")])
7698 (define_insn "*tldo_ldub_sp64"
7699 [(set (match_operand:QI 0 "register_operand" "=r")
7700 (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7701 (match_operand 3 "tld_symbolic_operand" "")]
7703 (match_operand:DI 1 "register_operand" "r"))))]
7704 "TARGET_TLS && TARGET_ARCH64"
7705 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7706 [(set_attr "type" "load")
7707 (set_attr "us3load_type" "3cycle")])
7709 (define_insn "*tldo_ldub1_sp64"
7710 [(set (match_operand:HI 0 "register_operand" "=r")
7711 (zero_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7712 (match_operand 3 "tld_symbolic_operand" "")]
7714 (match_operand:DI 1 "register_operand" "r")))))]
7715 "TARGET_TLS && TARGET_ARCH64"
7716 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7717 [(set_attr "type" "load")
7718 (set_attr "us3load_type" "3cycle")])
7720 (define_insn "*tldo_ldub2_sp64"
7721 [(set (match_operand:SI 0 "register_operand" "=r")
7722 (zero_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7723 (match_operand 3 "tld_symbolic_operand" "")]
7725 (match_operand:DI 1 "register_operand" "r")))))]
7726 "TARGET_TLS && TARGET_ARCH64"
7727 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7728 [(set_attr "type" "load")
7729 (set_attr "us3load_type" "3cycle")])
7731 (define_insn "*tldo_ldub3_sp64"
7732 [(set (match_operand:DI 0 "register_operand" "=r")
7733 (zero_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7734 (match_operand 3 "tld_symbolic_operand" "")]
7736 (match_operand:DI 1 "register_operand" "r")))))]
7737 "TARGET_TLS && TARGET_ARCH64"
7738 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7739 [(set_attr "type" "load")
7740 (set_attr "us3load_type" "3cycle")])
7742 (define_insn "*tldo_ldsb1_sp64"
7743 [(set (match_operand:HI 0 "register_operand" "=r")
7744 (sign_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7745 (match_operand 3 "tld_symbolic_operand" "")]
7747 (match_operand:DI 1 "register_operand" "r")))))]
7748 "TARGET_TLS && TARGET_ARCH64"
7749 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7750 [(set_attr "type" "sload")
7751 (set_attr "us3load_type" "3cycle")])
7753 (define_insn "*tldo_ldsb2_sp64"
7754 [(set (match_operand:SI 0 "register_operand" "=r")
7755 (sign_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7756 (match_operand 3 "tld_symbolic_operand" "")]
7758 (match_operand:DI 1 "register_operand" "r")))))]
7759 "TARGET_TLS && TARGET_ARCH64"
7760 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7761 [(set_attr "type" "sload")
7762 (set_attr "us3load_type" "3cycle")])
7764 (define_insn "*tldo_ldsb3_sp64"
7765 [(set (match_operand:DI 0 "register_operand" "=r")
7766 (sign_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7767 (match_operand 3 "tld_symbolic_operand" "")]
7769 (match_operand:DI 1 "register_operand" "r")))))]
7770 "TARGET_TLS && TARGET_ARCH64"
7771 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7772 [(set_attr "type" "sload")
7773 (set_attr "us3load_type" "3cycle")])
7775 (define_insn "*tldo_lduh_sp32"
7776 [(set (match_operand:HI 0 "register_operand" "=r")
7777 (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7778 (match_operand 3 "tld_symbolic_operand" "")]
7780 (match_operand:SI 1 "register_operand" "r"))))]
7781 "TARGET_TLS && TARGET_ARCH32"
7782 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7783 [(set_attr "type" "load")
7784 (set_attr "us3load_type" "3cycle")])
7786 (define_insn "*tldo_lduh1_sp32"
7787 [(set (match_operand:SI 0 "register_operand" "=r")
7788 (zero_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7789 (match_operand 3 "tld_symbolic_operand" "")]
7791 (match_operand:SI 1 "register_operand" "r")))))]
7792 "TARGET_TLS && TARGET_ARCH32"
7793 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7794 [(set_attr "type" "load")
7795 (set_attr "us3load_type" "3cycle")])
7797 (define_insn "*tldo_ldsh1_sp32"
7798 [(set (match_operand:SI 0 "register_operand" "=r")
7799 (sign_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7800 (match_operand 3 "tld_symbolic_operand" "")]
7802 (match_operand:SI 1 "register_operand" "r")))))]
7803 "TARGET_TLS && TARGET_ARCH32"
7804 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
7805 [(set_attr "type" "sload")
7806 (set_attr "us3load_type" "3cycle")])
7808 (define_insn "*tldo_lduh_sp64"
7809 [(set (match_operand:HI 0 "register_operand" "=r")
7810 (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7811 (match_operand 3 "tld_symbolic_operand" "")]
7813 (match_operand:DI 1 "register_operand" "r"))))]
7814 "TARGET_TLS && TARGET_ARCH64"
7815 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7816 [(set_attr "type" "load")
7817 (set_attr "us3load_type" "3cycle")])
7819 (define_insn "*tldo_lduh1_sp64"
7820 [(set (match_operand:SI 0 "register_operand" "=r")
7821 (zero_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7822 (match_operand 3 "tld_symbolic_operand" "")]
7824 (match_operand:DI 1 "register_operand" "r")))))]
7825 "TARGET_TLS && TARGET_ARCH64"
7826 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7827 [(set_attr "type" "load")
7828 (set_attr "us3load_type" "3cycle")])
7830 (define_insn "*tldo_lduh2_sp64"
7831 [(set (match_operand:DI 0 "register_operand" "=r")
7832 (zero_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7833 (match_operand 3 "tld_symbolic_operand" "")]
7835 (match_operand:DI 1 "register_operand" "r")))))]
7836 "TARGET_TLS && TARGET_ARCH64"
7837 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7838 [(set_attr "type" "load")
7839 (set_attr "us3load_type" "3cycle")])
7841 (define_insn "*tldo_ldsh1_sp64"
7842 [(set (match_operand:SI 0 "register_operand" "=r")
7843 (sign_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7844 (match_operand 3 "tld_symbolic_operand" "")]
7846 (match_operand:DI 1 "register_operand" "r")))))]
7847 "TARGET_TLS && TARGET_ARCH64"
7848 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
7849 [(set_attr "type" "sload")
7850 (set_attr "us3load_type" "3cycle")])
7852 (define_insn "*tldo_ldsh2_sp64"
7853 [(set (match_operand:DI 0 "register_operand" "=r")
7854 (sign_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7855 (match_operand 3 "tld_symbolic_operand" "")]
7857 (match_operand:DI 1 "register_operand" "r")))))]
7858 "TARGET_TLS && TARGET_ARCH64"
7859 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
7860 [(set_attr "type" "sload")
7861 (set_attr "us3load_type" "3cycle")])
7863 (define_insn "*tldo_lduw_sp32"
7864 [(set (match_operand:SI 0 "register_operand" "=r")
7865 (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7866 (match_operand 3 "tld_symbolic_operand" "")]
7868 (match_operand:SI 1 "register_operand" "r"))))]
7869 "TARGET_TLS && TARGET_ARCH32"
7870 "ld\t[%1 + %2], %0, %%tldo_add(%3)"
7871 [(set_attr "type" "load")])
7873 (define_insn "*tldo_lduw_sp64"
7874 [(set (match_operand:SI 0 "register_operand" "=r")
7875 (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7876 (match_operand 3 "tld_symbolic_operand" "")]
7878 (match_operand:DI 1 "register_operand" "r"))))]
7879 "TARGET_TLS && TARGET_ARCH64"
7880 "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
7881 [(set_attr "type" "load")])
7883 (define_insn "*tldo_lduw1_sp64"
7884 [(set (match_operand:DI 0 "register_operand" "=r")
7885 (zero_extend:DI (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7886 (match_operand 3 "tld_symbolic_operand" "")]
7888 (match_operand:DI 1 "register_operand" "r")))))]
7889 "TARGET_TLS && TARGET_ARCH64"
7890 "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
7891 [(set_attr "type" "load")])
7893 (define_insn "*tldo_ldsw1_sp64"
7894 [(set (match_operand:DI 0 "register_operand" "=r")
7895 (sign_extend:DI (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7896 (match_operand 3 "tld_symbolic_operand" "")]
7898 (match_operand:DI 1 "register_operand" "r")))))]
7899 "TARGET_TLS && TARGET_ARCH64"
7900 "ldsw\t[%1 + %2], %0, %%tldo_add(%3)"
7901 [(set_attr "type" "sload")
7902 (set_attr "us3load_type" "3cycle")])
7904 (define_insn "*tldo_ldx_sp64"
7905 [(set (match_operand:DI 0 "register_operand" "=r")
7906 (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7907 (match_operand 3 "tld_symbolic_operand" "")]
7909 (match_operand:DI 1 "register_operand" "r"))))]
7910 "TARGET_TLS && TARGET_ARCH64"
7911 "ldx\t[%1 + %2], %0, %%tldo_add(%3)"
7912 [(set_attr "type" "load")])
7914 (define_insn "*tldo_stb_sp32"
7915 [(set (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7916 (match_operand 3 "tld_symbolic_operand" "")]
7918 (match_operand:SI 1 "register_operand" "r")))
7919 (match_operand:QI 0 "register_operand" "=r"))]
7920 "TARGET_TLS && TARGET_ARCH32"
7921 "stb\t%0, [%1 + %2], %%tldo_add(%3)"
7922 [(set_attr "type" "store")])
7924 (define_insn "*tldo_stb_sp64"
7925 [(set (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7926 (match_operand 3 "tld_symbolic_operand" "")]
7928 (match_operand:DI 1 "register_operand" "r")))
7929 (match_operand:QI 0 "register_operand" "=r"))]
7930 "TARGET_TLS && TARGET_ARCH64"
7931 "stb\t%0, [%1 + %2], %%tldo_add(%3)"
7932 [(set_attr "type" "store")])
7934 (define_insn "*tldo_sth_sp32"
7935 [(set (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7936 (match_operand 3 "tld_symbolic_operand" "")]
7938 (match_operand:SI 1 "register_operand" "r")))
7939 (match_operand:HI 0 "register_operand" "=r"))]
7940 "TARGET_TLS && TARGET_ARCH32"
7941 "sth\t%0, [%1 + %2], %%tldo_add(%3)"
7942 [(set_attr "type" "store")])
7944 (define_insn "*tldo_sth_sp64"
7945 [(set (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7946 (match_operand 3 "tld_symbolic_operand" "")]
7948 (match_operand:DI 1 "register_operand" "r")))
7949 (match_operand:HI 0 "register_operand" "=r"))]
7950 "TARGET_TLS && TARGET_ARCH64"
7951 "sth\t%0, [%1 + %2], %%tldo_add(%3)"
7952 [(set_attr "type" "store")])
7954 (define_insn "*tldo_stw_sp32"
7955 [(set (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7956 (match_operand 3 "tld_symbolic_operand" "")]
7958 (match_operand:SI 1 "register_operand" "r")))
7959 (match_operand:SI 0 "register_operand" "=r"))]
7960 "TARGET_TLS && TARGET_ARCH32"
7961 "st\t%0, [%1 + %2], %%tldo_add(%3)"
7962 [(set_attr "type" "store")])
7964 (define_insn "*tldo_stw_sp64"
7965 [(set (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7966 (match_operand 3 "tld_symbolic_operand" "")]
7968 (match_operand:DI 1 "register_operand" "r")))
7969 (match_operand:SI 0 "register_operand" "=r"))]
7970 "TARGET_TLS && TARGET_ARCH64"
7971 "stw\t%0, [%1 + %2], %%tldo_add(%3)"
7972 [(set_attr "type" "store")])
7974 (define_insn "*tldo_stx_sp64"
7975 [(set (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7976 (match_operand 3 "tld_symbolic_operand" "")]
7978 (match_operand:DI 1 "register_operand" "r")))
7979 (match_operand:DI 0 "register_operand" "=r"))]
7980 "TARGET_TLS && TARGET_ARCH64"
7981 "stx\t%0, [%1 + %2], %%tldo_add(%3)"
7982 [(set_attr "type" "store")])
7985 ;; Stack protector instructions.
7987 (define_expand "stack_protect_set"
7988 [(match_operand 0 "memory_operand" "")
7989 (match_operand 1 "memory_operand" "")]
7992 #ifdef TARGET_THREAD_SSP_OFFSET
7993 rtx tlsreg = gen_rtx_REG (Pmode, 7);
7994 rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
7995 operands[1] = gen_rtx_MEM (Pmode, addr);
7998 emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
8000 emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
8004 (define_insn "stack_protect_setsi"
8005 [(set (match_operand:SI 0 "memory_operand" "=m")
8006 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
8007 (set (match_scratch:SI 2 "=&r") (const_int 0))]
8009 "ld\t%1, %2\;st\t%2, %0\;mov\t0, %2"
8010 [(set_attr "type" "multi")
8011 (set_attr "length" "3")])
8013 (define_insn "stack_protect_setdi"
8014 [(set (match_operand:DI 0 "memory_operand" "=m")
8015 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
8016 (set (match_scratch:DI 2 "=&r") (const_int 0))]
8018 "ldx\t%1, %2\;stx\t%2, %0\;mov\t0, %2"
8019 [(set_attr "type" "multi")
8020 (set_attr "length" "3")])
8022 (define_expand "stack_protect_test"
8023 [(match_operand 0 "memory_operand" "")
8024 (match_operand 1 "memory_operand" "")
8025 (match_operand 2 "" "")]
8028 #ifdef TARGET_THREAD_SSP_OFFSET
8029 rtx tlsreg = gen_rtx_REG (Pmode, 7);
8030 rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
8031 operands[1] = gen_rtx_MEM (Pmode, addr);
8035 rtx temp = gen_reg_rtx (Pmode);
8036 emit_insn (gen_stack_protect_testdi (temp, operands[0], operands[1]));
8037 sparc_compare_op0 = temp;
8038 sparc_compare_op1 = const0_rtx;
8042 emit_insn (gen_stack_protect_testsi (operands[0], operands[1]));
8043 sparc_compare_op0 = operands[0];
8044 sparc_compare_op1 = operands[1];
8045 sparc_compare_emitted = gen_rtx_REG (CCmode, SPARC_ICC_REG);
8047 emit_jump_insn (gen_beq (operands[2]));
8051 (define_insn "stack_protect_testsi"
8053 (unspec:CC [(match_operand:SI 0 "memory_operand" "m")
8054 (match_operand:SI 1 "memory_operand" "m")]
8056 (set (match_scratch:SI 3 "=r") (const_int 0))
8057 (clobber (match_scratch:SI 2 "=&r"))]
8059 "ld\t%0, %2\;ld\t%1, %3\;xorcc\t%2, %3, %2\;mov\t0, %3"
8060 [(set_attr "type" "multi")
8061 (set_attr "length" "4")])
8063 (define_insn "stack_protect_testdi"
8064 [(set (match_operand:DI 0 "register_operand" "=&r")
8065 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
8066 (match_operand:DI 2 "memory_operand" "m")]
8068 (set (match_scratch:DI 3 "=r") (const_int 0))]
8070 "ldx\t%1, %0\;ldx\t%2, %3\;xor\t%0, %3, %0\;mov\t0, %3"
8071 [(set_attr "type" "multi")
8072 (set_attr "length" "4")])
8075 ;; Vector instructions.
8077 (define_insn "addv2si3"
8078 [(set (match_operand:V2SI 0 "register_operand" "=e")
8079 (plus:V2SI (match_operand:V2SI 1 "register_operand" "e")
8080 (match_operand:V2SI 2 "register_operand" "e")))]
8082 "fpadd32\t%1, %2, %0"
8083 [(set_attr "type" "fga")
8084 (set_attr "fptype" "double")])
8086 (define_insn "addv4hi3"
8087 [(set (match_operand:V4HI 0 "register_operand" "=e")
8088 (plus:V4HI (match_operand:V4HI 1 "register_operand" "e")
8089 (match_operand:V4HI 2 "register_operand" "e")))]
8091 "fpadd16\t%1, %2, %0"
8092 [(set_attr "type" "fga")
8093 (set_attr "fptype" "double")])
8095 ;; fpadd32s is emitted by the addsi3 pattern.
8097 (define_insn "addv2hi3"
8098 [(set (match_operand:V2HI 0 "register_operand" "=f")
8099 (plus:V2HI (match_operand:V2HI 1 "register_operand" "f")
8100 (match_operand:V2HI 2 "register_operand" "f")))]
8102 "fpadd16s\t%1, %2, %0"
8103 [(set_attr "type" "fga")
8104 (set_attr "fptype" "single")])
8106 (define_insn "subv2si3"
8107 [(set (match_operand:V2SI 0 "register_operand" "=e")
8108 (minus:V2SI (match_operand:V2SI 1 "register_operand" "e")
8109 (match_operand:V2SI 2 "register_operand" "e")))]
8111 "fpsub32\t%1, %2, %0"
8112 [(set_attr "type" "fga")
8113 (set_attr "fptype" "double")])
8115 (define_insn "subv4hi3"
8116 [(set (match_operand:V4HI 0 "register_operand" "=e")
8117 (minus:V4HI (match_operand:V4HI 1 "register_operand" "e")
8118 (match_operand:V4HI 2 "register_operand" "e")))]
8120 "fpsub16\t%1, %2, %0"
8121 [(set_attr "type" "fga")
8122 (set_attr "fptype" "double")])
8124 ;; fpsub32s is emitted by the subsi3 pattern.
8126 (define_insn "subv2hi3"
8127 [(set (match_operand:V2HI 0 "register_operand" "=f")
8128 (minus:V2HI (match_operand:V2HI 1 "register_operand" "f")
8129 (match_operand:V2HI 2 "register_operand" "f")))]
8131 "fpsub16s\t%1, %2, %0"
8132 [(set_attr "type" "fga")
8133 (set_attr "fptype" "single")])
8135 ;; All other logical instructions have integer equivalents so they
8136 ;; are defined together.
8138 ;; (ior (not (op1)) (not (op2))) is the canonical form of NAND.
8140 (define_insn "*nand<V64mode>_vis"
8141 [(set (match_operand:V64 0 "register_operand" "=e")
8142 (ior:V64 (not:V64 (match_operand:V64 1 "register_operand" "e"))
8143 (not:V64 (match_operand:V64 2 "register_operand" "e"))))]
8146 [(set_attr "type" "fga")
8147 (set_attr "fptype" "double")])
8149 (define_insn "*nand<V32mode>_vis"
8150 [(set (match_operand:V32 0 "register_operand" "=f")
8151 (ior:V32 (not:V32 (match_operand:V32 1 "register_operand" "f"))
8152 (not:V32 (match_operand:V32 2 "register_operand" "f"))))]
8154 "fnands\t%1, %2, %0"
8155 [(set_attr "type" "fga")
8156 (set_attr "fptype" "single")])
8158 ;; Hard to generate VIS instructions. We have builtins for these.
8160 (define_insn "fpack16_vis"
8161 [(set (match_operand:V4QI 0 "register_operand" "=f")
8162 (unspec:V4QI [(match_operand:V4HI 1 "register_operand" "e")]
8166 [(set_attr "type" "fga")
8167 (set_attr "fptype" "double")])
8169 (define_insn "fpackfix_vis"
8170 [(set (match_operand:V2HI 0 "register_operand" "=f")
8171 (unspec:V2HI [(match_operand:V2SI 1 "register_operand" "e")]
8175 [(set_attr "type" "fga")
8176 (set_attr "fptype" "double")])
8178 (define_insn "fpack32_vis"
8179 [(set (match_operand:V8QI 0 "register_operand" "=e")
8180 (unspec:V8QI [(match_operand:V2SI 1 "register_operand" "e")
8181 (match_operand:V8QI 2 "register_operand" "e")]
8184 "fpack32\t%1, %2, %0"
8185 [(set_attr "type" "fga")
8186 (set_attr "fptype" "double")])
8188 (define_insn "fexpand_vis"
8189 [(set (match_operand:V4HI 0 "register_operand" "=e")
8190 (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")]
8194 [(set_attr "type" "fga")
8195 (set_attr "fptype" "double")])
8197 ;; It may be possible to describe this operation as (1 indexed):
8198 ;; (vec_select (vec_duplicate (vec_duplicate (vec_concat 1 2)))
8199 ;; 1,5,10,14,19,23,28,32)
8200 ;; Note that (vec_merge:V8QI [(V4QI) (V4QI)] (10101010 = 170) doesn't work
8201 ;; because vec_merge expects all the operands to be of the same type.
8202 (define_insn "fpmerge_vis"
8203 [(set (match_operand:V8QI 0 "register_operand" "=e")
8204 (unspec:V8QI [(match_operand:V4QI 1 "register_operand" "f")
8205 (match_operand:V4QI 2 "register_operand" "f")]
8208 "fpmerge\t%1, %2, %0"
8209 [(set_attr "type" "fga")
8210 (set_attr "fptype" "double")])
8212 ;; Partitioned multiply instructions
8213 (define_insn "fmul8x16_vis"
8214 [(set (match_operand:V4HI 0 "register_operand" "=e")
8215 (mult:V4HI (match_operand:V4QI 1 "register_operand" "f")
8216 (match_operand:V4HI 2 "register_operand" "e")))]
8218 "fmul8x16\t%1, %2, %0"
8219 [(set_attr "type" "fpmul")
8220 (set_attr "fptype" "double")])
8222 ;; Only one of the following two insns can be a multiply.
8223 (define_insn "fmul8x16au_vis"
8224 [(set (match_operand:V4HI 0 "register_operand" "=e")
8225 (mult:V4HI (match_operand:V4QI 1 "register_operand" "f")
8226 (match_operand:V2HI 2 "register_operand" "f")))]
8228 "fmul8x16au\t%1, %2, %0"
8229 [(set_attr "type" "fpmul")
8230 (set_attr "fptype" "double")])
8232 (define_insn "fmul8x16al_vis"
8233 [(set (match_operand:V4HI 0 "register_operand" "=e")
8234 (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")
8235 (match_operand:V2HI 2 "register_operand" "f")]
8238 "fmul8x16al\t%1, %2, %0"
8239 [(set_attr "type" "fpmul")
8240 (set_attr "fptype" "double")])
8242 ;; Only one of the following two insns can be a multiply.
8243 (define_insn "fmul8sux16_vis"
8244 [(set (match_operand:V4HI 0 "register_operand" "=e")
8245 (mult:V4HI (match_operand:V8QI 1 "register_operand" "e")
8246 (match_operand:V4HI 2 "register_operand" "e")))]
8248 "fmul8sux16\t%1, %2, %0"
8249 [(set_attr "type" "fpmul")
8250 (set_attr "fptype" "double")])
8252 (define_insn "fmul8ulx16_vis"
8253 [(set (match_operand:V4HI 0 "register_operand" "=e")
8254 (unspec:V4HI [(match_operand:V8QI 1 "register_operand" "e")
8255 (match_operand:V4HI 2 "register_operand" "e")]
8258 "fmul8ulx16\t%1, %2, %0"
8259 [(set_attr "type" "fpmul")
8260 (set_attr "fptype" "double")])
8262 ;; Only one of the following two insns can be a multiply.
8263 (define_insn "fmuld8sux16_vis"
8264 [(set (match_operand:V2SI 0 "register_operand" "=e")
8265 (mult:V2SI (match_operand:V4QI 1 "register_operand" "f")
8266 (match_operand:V2HI 2 "register_operand" "f")))]
8268 "fmuld8sux16\t%1, %2, %0"
8269 [(set_attr "type" "fpmul")
8270 (set_attr "fptype" "double")])
8272 (define_insn "fmuld8ulx16_vis"
8273 [(set (match_operand:V2SI 0 "register_operand" "=e")
8274 (unspec:V2SI [(match_operand:V4QI 1 "register_operand" "f")
8275 (match_operand:V2HI 2 "register_operand" "f")]
8278 "fmuld8ulx16\t%1, %2, %0"
8279 [(set_attr "type" "fpmul")
8280 (set_attr "fptype" "double")])
8282 ;; Using faligndata only makes sense after an alignaddr since the choice of
8283 ;; bytes to take out of each operand is dependent on the results of the last
8285 (define_insn "faligndata<V64I:mode>_vis"
8286 [(set (match_operand:V64I 0 "register_operand" "=e")
8287 (unspec:V64I [(match_operand:V64I 1 "register_operand" "e")
8288 (match_operand:V64I 2 "register_operand" "e")]
8291 "faligndata\t%1, %2, %0"
8292 [(set_attr "type" "fga")
8293 (set_attr "fptype" "double")])
8295 (define_insn "alignaddr<P:mode>_vis"
8296 [(set (match_operand:P 0 "register_operand" "=r")
8297 (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
8298 (match_operand:P 2 "register_or_zero_operand" "rJ")]
8301 "alignaddr\t%r1, %r2, %0")
8303 (define_insn "pdist_vis"
8304 [(set (match_operand:DI 0 "register_operand" "=e")
8305 (unspec:DI [(match_operand:V8QI 1 "register_operand" "e")
8306 (match_operand:V8QI 2 "register_operand" "e")
8307 (match_operand:DI 3 "register_operand" "0")]
8311 [(set_attr "type" "fga")
8312 (set_attr "fptype" "double")])