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,*roGYDF,*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,DF"))]
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 builds V64mode constants in integer registers.
2648 [(set (match_operand:V64 0 "register_operand" "")
2649 (match_operand:V64 1 "const_double_or_vector_operand" ""))]
2651 && (GET_CODE (operands[0]) == REG
2652 && REGNO (operands[0]) < 32)
2653 && ! const_zero_operand (operands[1], GET_MODE (operands[0]))
2654 && reload_completed"
2655 [(clobber (const_int 0))]
2657 operands[0] = gen_rtx_raw_REG (DImode, REGNO (operands[0]));
2661 #if HOST_BITS_PER_WIDE_INT == 32
2664 enum machine_mode mode = GET_MODE (operands[1]);
2665 rtx tem = simplify_subreg (DImode, operands[1], mode, 0);
2666 emit_insn (gen_movdi (operands[0], tem));
2671 enum machine_mode mode = GET_MODE (operands[1]);
2672 rtx hi = simplify_subreg (SImode, operands[1], mode, 0);
2673 rtx lo = simplify_subreg (SImode, operands[1], mode, 4);
2675 gcc_assert (GET_CODE (hi) == CONST_INT);
2676 gcc_assert (GET_CODE (lo) == CONST_INT);
2678 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), hi));
2680 /* Slick... but this trick loses if this subreg constant part
2681 can be done in one insn. */
2683 && ! SPARC_SETHI32_P (INTVAL (hi))
2684 && ! SPARC_SIMM13_P (INTVAL (hi)))
2686 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2687 gen_highpart (SImode, operands[0])));
2691 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), lo));
2697 ;; Ok, now the splits to handle all the multi insn and
2698 ;; mis-aligned memory address cases.
2699 ;; In these splits please take note that we must be
2700 ;; careful when V9 but not ARCH64 because the integer
2701 ;; register DFmode cases must be handled.
2703 [(set (match_operand:V64 0 "register_operand" "")
2704 (match_operand:V64 1 "register_operand" ""))]
2707 && ((GET_CODE (operands[0]) == REG
2708 && REGNO (operands[0]) < 32)
2709 || (GET_CODE (operands[0]) == SUBREG
2710 && GET_CODE (SUBREG_REG (operands[0])) == REG
2711 && REGNO (SUBREG_REG (operands[0])) < 32))))
2712 && reload_completed"
2713 [(clobber (const_int 0))]
2715 rtx set_dest = operands[0];
2716 rtx set_src = operands[1];
2719 enum machine_mode half_mode;
2721 /* We can be expanded for DFmode or integral vector modes. */
2722 if (<V64:MODE>mode == DFmode)
2727 dest1 = gen_highpart (half_mode, set_dest);
2728 dest2 = gen_lowpart (half_mode, set_dest);
2729 src1 = gen_highpart (half_mode, set_src);
2730 src2 = gen_lowpart (half_mode, set_src);
2732 /* Now emit using the real source and destination we found, swapping
2733 the order if we detect overlap. */
2734 if (reg_overlap_mentioned_p (dest1, src2))
2736 emit_move_insn_1 (dest2, src2);
2737 emit_move_insn_1 (dest1, src1);
2741 emit_move_insn_1 (dest1, src1);
2742 emit_move_insn_1 (dest2, src2);
2748 [(set (match_operand:V64 0 "register_operand" "")
2749 (match_operand:V64 1 "memory_operand" ""))]
2752 && (((REGNO (operands[0]) % 2) != 0)
2753 || ! mem_min_alignment (operands[1], 8))
2754 && offsettable_memref_p (operands[1])"
2755 [(clobber (const_int 0))]
2757 enum machine_mode half_mode;
2760 /* We can be expanded for DFmode or integral vector modes. */
2761 if (<V64:MODE>mode == DFmode)
2766 word0 = adjust_address (operands[1], half_mode, 0);
2767 word1 = adjust_address (operands[1], half_mode, 4);
2769 if (reg_overlap_mentioned_p (gen_highpart (half_mode, operands[0]), word1))
2771 emit_move_insn_1 (gen_lowpart (half_mode, operands[0]), word1);
2772 emit_move_insn_1 (gen_highpart (half_mode, operands[0]), word0);
2776 emit_move_insn_1 (gen_highpart (half_mode, operands[0]), word0);
2777 emit_move_insn_1 (gen_lowpart (half_mode, operands[0]), word1);
2783 [(set (match_operand:V64 0 "memory_operand" "")
2784 (match_operand:V64 1 "register_operand" ""))]
2787 && (((REGNO (operands[1]) % 2) != 0)
2788 || ! mem_min_alignment (operands[0], 8))
2789 && offsettable_memref_p (operands[0])"
2790 [(clobber (const_int 0))]
2792 enum machine_mode half_mode;
2795 /* We can be expanded for DFmode or integral vector modes. */
2796 if (<V64:MODE>mode == DFmode)
2801 word0 = adjust_address (operands[0], half_mode, 0);
2802 word1 = adjust_address (operands[0], half_mode, 4);
2804 emit_move_insn_1 (word0, gen_highpart (half_mode, operands[1]));
2805 emit_move_insn_1 (word1, gen_lowpart (half_mode, operands[1]));
2810 [(set (match_operand:V64 0 "memory_operand" "")
2811 (match_operand:V64 1 "const_zero_operand" ""))]
2815 && ! mem_min_alignment (operands[0], 8)))
2816 && offsettable_memref_p (operands[0])"
2817 [(clobber (const_int 0))]
2819 enum machine_mode half_mode;
2822 /* We can be expanded for DFmode or integral vector modes. */
2823 if (<V64:MODE>mode == DFmode)
2828 dest1 = adjust_address (operands[0], half_mode, 0);
2829 dest2 = adjust_address (operands[0], half_mode, 4);
2831 emit_move_insn_1 (dest1, CONST0_RTX (half_mode));
2832 emit_move_insn_1 (dest2, CONST0_RTX (half_mode));
2837 [(set (match_operand:V64 0 "register_operand" "")
2838 (match_operand:V64 1 "const_zero_operand" ""))]
2841 && ((GET_CODE (operands[0]) == REG
2842 && REGNO (operands[0]) < 32)
2843 || (GET_CODE (operands[0]) == SUBREG
2844 && GET_CODE (SUBREG_REG (operands[0])) == REG
2845 && REGNO (SUBREG_REG (operands[0])) < 32))"
2846 [(clobber (const_int 0))]
2848 enum machine_mode half_mode;
2849 rtx set_dest = operands[0];
2852 /* We can be expanded for DFmode or integral vector modes. */
2853 if (<V64:MODE>mode == DFmode)
2858 dest1 = gen_highpart (half_mode, set_dest);
2859 dest2 = gen_lowpart (half_mode, set_dest);
2860 emit_move_insn_1 (dest1, CONST0_RTX (half_mode));
2861 emit_move_insn_1 (dest2, CONST0_RTX (half_mode));
2865 (define_expand "movtf"
2866 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2867 (match_operand:TF 1 "general_operand" ""))]
2870 if (sparc_expand_move (TFmode, operands))
2874 (define_insn "*movtf_insn_sp32"
2875 [(set (match_operand:TF 0 "nonimmediate_operand" "=b,e,o,U,r")
2876 (match_operand:TF 1 "input_operand" "G,oe,GeUr,o,roG"))]
2879 && (register_operand (operands[0], TFmode)
2880 || register_or_zero_operand (operands[1], TFmode))"
2882 [(set_attr "length" "4")])
2884 ;; Exactly the same as above, except that all `e' cases are deleted.
2885 ;; This is necessary to prevent reload from ever trying to use a `e' reg
2888 (define_insn "*movtf_insn_sp32_no_fpu"
2889 [(set (match_operand:TF 0 "nonimmediate_operand" "=o,U,o,r,o")
2890 (match_operand:TF 1 "input_operand" "G,o,U,roG,r"))]
2893 && (register_operand (operands[0], TFmode)
2894 || register_or_zero_operand (operands[1], TFmode))"
2896 [(set_attr "length" "4")])
2898 (define_insn "*movtf_insn_sp64"
2899 [(set (match_operand:TF 0 "nonimmediate_operand" "=b,e,o,r")
2900 (match_operand:TF 1 "input_operand" "G,oe,Ger,roG"))]
2903 && ! TARGET_HARD_QUAD
2904 && (register_operand (operands[0], TFmode)
2905 || register_or_zero_operand (operands[1], TFmode))"
2907 [(set_attr "length" "2")])
2909 (define_insn "*movtf_insn_sp64_hq"
2910 [(set (match_operand:TF 0 "nonimmediate_operand" "=b,e,e,m,o,r")
2911 (match_operand:TF 1 "input_operand" "G,e,m,e,rG,roG"))]
2915 && (register_operand (operands[0], TFmode)
2916 || register_or_zero_operand (operands[1], TFmode))"
2924 [(set_attr "type" "*,fpmove,fpload,fpstore,*,*")
2925 (set_attr "length" "2,*,*,*,2,2")])
2927 (define_insn "*movtf_insn_sp64_no_fpu"
2928 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o")
2929 (match_operand:TF 1 "input_operand" "orG,rG"))]
2932 && (register_operand (operands[0], TFmode)
2933 || register_or_zero_operand (operands[1], TFmode))"
2935 [(set_attr "length" "2")])
2937 ;; Now all the splits to handle multi-insn TF mode moves.
2939 [(set (match_operand:TF 0 "register_operand" "")
2940 (match_operand:TF 1 "register_operand" ""))]
2944 && ! TARGET_HARD_QUAD)
2945 || ! fp_register_operand (operands[0], TFmode))"
2946 [(clobber (const_int 0))]
2948 rtx set_dest = operands[0];
2949 rtx set_src = operands[1];
2953 dest1 = gen_df_reg (set_dest, 0);
2954 dest2 = gen_df_reg (set_dest, 1);
2955 src1 = gen_df_reg (set_src, 0);
2956 src2 = gen_df_reg (set_src, 1);
2958 /* Now emit using the real source and destination we found, swapping
2959 the order if we detect overlap. */
2960 if (reg_overlap_mentioned_p (dest1, src2))
2962 emit_insn (gen_movdf (dest2, src2));
2963 emit_insn (gen_movdf (dest1, src1));
2967 emit_insn (gen_movdf (dest1, src1));
2968 emit_insn (gen_movdf (dest2, src2));
2974 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2975 (match_operand:TF 1 "const_zero_operand" ""))]
2977 [(clobber (const_int 0))]
2979 rtx set_dest = operands[0];
2982 switch (GET_CODE (set_dest))
2985 dest1 = gen_df_reg (set_dest, 0);
2986 dest2 = gen_df_reg (set_dest, 1);
2989 dest1 = adjust_address (set_dest, DFmode, 0);
2990 dest2 = adjust_address (set_dest, DFmode, 8);
2996 emit_insn (gen_movdf (dest1, CONST0_RTX (DFmode)));
2997 emit_insn (gen_movdf (dest2, CONST0_RTX (DFmode)));
3002 [(set (match_operand:TF 0 "register_operand" "")
3003 (match_operand:TF 1 "memory_operand" ""))]
3005 && offsettable_memref_p (operands[1])
3007 || ! TARGET_HARD_QUAD
3008 || ! fp_register_operand (operands[0], TFmode)))"
3009 [(clobber (const_int 0))]
3011 rtx word0 = adjust_address (operands[1], DFmode, 0);
3012 rtx word1 = adjust_address (operands[1], DFmode, 8);
3013 rtx set_dest, dest1, dest2;
3015 set_dest = operands[0];
3017 dest1 = gen_df_reg (set_dest, 0);
3018 dest2 = gen_df_reg (set_dest, 1);
3020 /* Now output, ordering such that we don't clobber any registers
3021 mentioned in the address. */
3022 if (reg_overlap_mentioned_p (dest1, word1))
3025 emit_insn (gen_movdf (dest2, word1));
3026 emit_insn (gen_movdf (dest1, word0));
3030 emit_insn (gen_movdf (dest1, word0));
3031 emit_insn (gen_movdf (dest2, word1));
3037 [(set (match_operand:TF 0 "memory_operand" "")
3038 (match_operand:TF 1 "register_operand" ""))]
3040 && offsettable_memref_p (operands[0])
3042 || ! TARGET_HARD_QUAD
3043 || ! fp_register_operand (operands[1], TFmode)))"
3044 [(clobber (const_int 0))]
3046 rtx set_src = operands[1];
3048 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 0),
3049 gen_df_reg (set_src, 0)));
3050 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 8),
3051 gen_df_reg (set_src, 1)));
3056 ;; SPARC-V9 conditional move instructions
3058 ;; We can handle larger constants here for some flavors, but for now we keep
3059 ;; it simple and only allow those constants supported by all flavors.
3060 ;; Note that emit_conditional_move canonicalizes operands 2,3 so that operand
3061 ;; 3 contains the constant if one is present, but we handle either for
3062 ;; generality (sparc.c puts a constant in operand 2).
3064 (define_mode_iterator I [QI HI SI DI])
3066 (define_expand "mov<I:mode>cc"
3067 [(set (match_operand:I 0 "register_operand" "")
3068 (if_then_else:I (match_operand 1 "comparison_operator" "")
3069 (match_operand:I 2 "arith10_operand" "")
3070 (match_operand:I 3 "arith10_operand" "")))]
3071 "TARGET_V9 && !(<I:MODE>mode == DImode && TARGET_ARCH32)"
3073 enum rtx_code code = GET_CODE (operands[1]);
3075 if (GET_MODE (sparc_compare_op0) == DImode
3079 if (sparc_compare_op1 == const0_rtx
3080 && GET_CODE (sparc_compare_op0) == REG
3081 && GET_MODE (sparc_compare_op0) == DImode
3082 && v9_regcmp_p (code))
3083 operands[1] = gen_rtx_fmt_ee (code, DImode, sparc_compare_op0, const0_rtx);
3085 operands[1] = gen_compare_operator (code);
3088 (define_mode_iterator F [SF DF TF])
3090 (define_expand "mov<F:mode>cc"
3091 [(set (match_operand:F 0 "register_operand" "")
3092 (if_then_else:F (match_operand 1 "comparison_operator" "")
3093 (match_operand:F 2 "register_operand" "")
3094 (match_operand:F 3 "register_operand" "")))]
3095 "TARGET_V9 && TARGET_FPU"
3097 enum rtx_code code = GET_CODE (operands[1]);
3099 if (GET_MODE (sparc_compare_op0) == DImode
3103 if (sparc_compare_op1 == const0_rtx
3104 && GET_CODE (sparc_compare_op0) == REG
3105 && GET_MODE (sparc_compare_op0) == DImode
3106 && v9_regcmp_p (code))
3107 operands[1] = gen_rtx_fmt_ee (code, DImode, sparc_compare_op0, const0_rtx);
3109 operands[1] = gen_compare_operator (code);
3112 ;; Conditional move define_insns
3114 (define_insn "*mov<I:mode>_cc_v9"
3115 [(set (match_operand:I 0 "register_operand" "=r,r")
3116 (if_then_else:I (match_operator 1 "comparison_operator"
3117 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
3119 (match_operand:I 3 "arith11_operand" "rL,0")
3120 (match_operand:I 4 "arith11_operand" "0,rL")))]
3121 "TARGET_V9 && !(<I:MODE>mode == DImode && TARGET_ARCH32)"
3124 mov%c1\t%x2, %4, %0"
3125 [(set_attr "type" "cmove")])
3127 (define_insn "*mov<I:mode>_cc_reg_sp64"
3128 [(set (match_operand:I 0 "register_operand" "=r,r")
3129 (if_then_else:I (match_operator 1 "v9_register_compare_operator"
3130 [(match_operand:DI 2 "register_operand" "r,r")
3132 (match_operand:I 3 "arith10_operand" "rM,0")
3133 (match_operand:I 4 "arith10_operand" "0,rM")))]
3136 movr%D1\t%2, %r3, %0
3137 movr%d1\t%2, %r4, %0"
3138 [(set_attr "type" "cmove")])
3140 (define_insn "*movsf_cc_v9"
3141 [(set (match_operand:SF 0 "register_operand" "=f,f")
3142 (if_then_else:SF (match_operator 1 "comparison_operator"
3143 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
3145 (match_operand:SF 3 "register_operand" "f,0")
3146 (match_operand:SF 4 "register_operand" "0,f")))]
3147 "TARGET_V9 && TARGET_FPU"
3149 fmovs%C1\t%x2, %3, %0
3150 fmovs%c1\t%x2, %4, %0"
3151 [(set_attr "type" "fpcmove")])
3153 (define_insn "*movsf_cc_reg_sp64"
3154 [(set (match_operand:SF 0 "register_operand" "=f,f")
3155 (if_then_else:SF (match_operator 1 "v9_register_compare_operator"
3156 [(match_operand:DI 2 "register_operand" "r,r")
3158 (match_operand:SF 3 "register_operand" "f,0")
3159 (match_operand:SF 4 "register_operand" "0,f")))]
3160 "TARGET_ARCH64 && TARGET_FPU"
3162 fmovrs%D1\t%2, %3, %0
3163 fmovrs%d1\t%2, %4, %0"
3164 [(set_attr "type" "fpcrmove")])
3166 ;; Named because invoked by movtf_cc_v9
3167 (define_insn "movdf_cc_v9"
3168 [(set (match_operand:DF 0 "register_operand" "=e,e")
3169 (if_then_else:DF (match_operator 1 "comparison_operator"
3170 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
3172 (match_operand:DF 3 "register_operand" "e,0")
3173 (match_operand:DF 4 "register_operand" "0,e")))]
3174 "TARGET_V9 && TARGET_FPU"
3176 fmovd%C1\t%x2, %3, %0
3177 fmovd%c1\t%x2, %4, %0"
3178 [(set_attr "type" "fpcmove")
3179 (set_attr "fptype" "double")])
3181 ;; Named because invoked by movtf_cc_reg_sp64
3182 (define_insn "movdf_cc_reg_sp64"
3183 [(set (match_operand:DF 0 "register_operand" "=e,e")
3184 (if_then_else:DF (match_operator 1 "v9_register_compare_operator"
3185 [(match_operand:DI 2 "register_operand" "r,r")
3187 (match_operand:DF 3 "register_operand" "e,0")
3188 (match_operand:DF 4 "register_operand" "0,e")))]
3189 "TARGET_ARCH64 && TARGET_FPU"
3191 fmovrd%D1\t%2, %3, %0
3192 fmovrd%d1\t%2, %4, %0"
3193 [(set_attr "type" "fpcrmove")
3194 (set_attr "fptype" "double")])
3196 (define_insn "*movtf_cc_hq_v9"
3197 [(set (match_operand:TF 0 "register_operand" "=e,e")
3198 (if_then_else:TF (match_operator 1 "comparison_operator"
3199 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
3201 (match_operand:TF 3 "register_operand" "e,0")
3202 (match_operand:TF 4 "register_operand" "0,e")))]
3203 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
3205 fmovq%C1\t%x2, %3, %0
3206 fmovq%c1\t%x2, %4, %0"
3207 [(set_attr "type" "fpcmove")])
3209 (define_insn "*movtf_cc_reg_hq_sp64"
3210 [(set (match_operand:TF 0 "register_operand" "=e,e")
3211 (if_then_else:TF (match_operator 1 "v9_register_compare_operator"
3212 [(match_operand:DI 2 "register_operand" "r,r")
3214 (match_operand:TF 3 "register_operand" "e,0")
3215 (match_operand:TF 4 "register_operand" "0,e")))]
3216 "TARGET_ARCH64 && TARGET_FPU && TARGET_HARD_QUAD"
3218 fmovrq%D1\t%2, %3, %0
3219 fmovrq%d1\t%2, %4, %0"
3220 [(set_attr "type" "fpcrmove")])
3222 (define_insn_and_split "*movtf_cc_v9"
3223 [(set (match_operand:TF 0 "register_operand" "=e,e")
3224 (if_then_else:TF (match_operator 1 "comparison_operator"
3225 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
3227 (match_operand:TF 3 "register_operand" "e,0")
3228 (match_operand:TF 4 "register_operand" "0,e")))]
3229 "TARGET_V9 && TARGET_FPU && !TARGET_HARD_QUAD"
3231 "&& reload_completed"
3232 [(clobber (const_int 0))]
3234 rtx set_dest = operands[0];
3235 rtx set_srca = operands[3];
3236 rtx set_srcb = operands[4];
3237 int third = rtx_equal_p (set_dest, set_srca);
3239 rtx srca1, srca2, srcb1, srcb2;
3241 dest1 = gen_df_reg (set_dest, 0);
3242 dest2 = gen_df_reg (set_dest, 1);
3243 srca1 = gen_df_reg (set_srca, 0);
3244 srca2 = gen_df_reg (set_srca, 1);
3245 srcb1 = gen_df_reg (set_srcb, 0);
3246 srcb2 = gen_df_reg (set_srcb, 1);
3248 /* Now emit using the real source and destination we found, swapping
3249 the order if we detect overlap. */
3250 if ((third && reg_overlap_mentioned_p (dest1, srcb2))
3251 || (!third && reg_overlap_mentioned_p (dest1, srca2)))
3253 emit_insn (gen_movdf_cc_v9 (dest2, operands[1], operands[2], srca2, srcb2));
3254 emit_insn (gen_movdf_cc_v9 (dest1, operands[1], operands[2], srca1, srcb1));
3258 emit_insn (gen_movdf_cc_v9 (dest1, operands[1], operands[2], srca1, srcb1));
3259 emit_insn (gen_movdf_cc_v9 (dest2, operands[1], operands[2], srca2, srcb2));
3263 [(set_attr "length" "2")])
3265 (define_insn_and_split "*movtf_cc_reg_sp64"
3266 [(set (match_operand:TF 0 "register_operand" "=e,e")
3267 (if_then_else:TF (match_operator 1 "v9_register_compare_operator"
3268 [(match_operand:DI 2 "register_operand" "r,r")
3270 (match_operand:TF 3 "register_operand" "e,0")
3271 (match_operand:TF 4 "register_operand" "0,e")))]
3272 "TARGET_ARCH64 && TARGET_FPU && ! TARGET_HARD_QUAD"
3274 "&& reload_completed"
3275 [(clobber (const_int 0))]
3277 rtx set_dest = operands[0];
3278 rtx set_srca = operands[3];
3279 rtx set_srcb = operands[4];
3280 int third = rtx_equal_p (set_dest, set_srca);
3282 rtx srca1, srca2, srcb1, srcb2;
3284 dest1 = gen_df_reg (set_dest, 0);
3285 dest2 = gen_df_reg (set_dest, 1);
3286 srca1 = gen_df_reg (set_srca, 0);
3287 srca2 = gen_df_reg (set_srca, 1);
3288 srcb1 = gen_df_reg (set_srcb, 0);
3289 srcb2 = gen_df_reg (set_srcb, 1);
3291 /* Now emit using the real source and destination we found, swapping
3292 the order if we detect overlap. */
3293 if ((third && reg_overlap_mentioned_p (dest1, srcb2))
3294 || (!third && reg_overlap_mentioned_p (dest1, srca2)))
3296 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
3297 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
3301 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
3302 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
3306 [(set_attr "length" "2")])
3309 ;; Zero-extension instructions
3311 ;; These patterns originally accepted general_operands, however, slightly
3312 ;; better code is generated by only accepting register_operands, and then
3313 ;; letting combine generate the ldu[hb] insns.
3315 (define_expand "zero_extendhisi2"
3316 [(set (match_operand:SI 0 "register_operand" "")
3317 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
3320 rtx temp = gen_reg_rtx (SImode);
3321 rtx shift_16 = GEN_INT (16);
3322 int op1_subbyte = 0;
3324 if (GET_CODE (operand1) == SUBREG)
3326 op1_subbyte = SUBREG_BYTE (operand1);
3327 op1_subbyte /= GET_MODE_SIZE (SImode);
3328 op1_subbyte *= GET_MODE_SIZE (SImode);
3329 operand1 = XEXP (operand1, 0);
3332 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3334 emit_insn (gen_lshrsi3 (operand0, temp, shift_16));
3338 (define_insn "*zero_extendhisi2_insn"
3339 [(set (match_operand:SI 0 "register_operand" "=r")
3340 (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
3343 [(set_attr "type" "load")
3344 (set_attr "us3load_type" "3cycle")])
3346 (define_expand "zero_extendqihi2"
3347 [(set (match_operand:HI 0 "register_operand" "")
3348 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
3352 (define_insn "*zero_extendqihi2_insn"
3353 [(set (match_operand:HI 0 "register_operand" "=r,r")
3354 (zero_extend:HI (match_operand:QI 1 "input_operand" "r,m")))]
3355 "GET_CODE (operands[1]) != CONST_INT"
3359 [(set_attr "type" "*,load")
3360 (set_attr "us3load_type" "*,3cycle")])
3362 (define_expand "zero_extendqisi2"
3363 [(set (match_operand:SI 0 "register_operand" "")
3364 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
3368 (define_insn "*zero_extendqisi2_insn"
3369 [(set (match_operand:SI 0 "register_operand" "=r,r")
3370 (zero_extend:SI (match_operand:QI 1 "input_operand" "r,m")))]
3371 "GET_CODE (operands[1]) != CONST_INT"
3375 [(set_attr "type" "*,load")
3376 (set_attr "us3load_type" "*,3cycle")])
3378 (define_expand "zero_extendqidi2"
3379 [(set (match_operand:DI 0 "register_operand" "")
3380 (zero_extend:DI (match_operand:QI 1 "register_operand" "")))]
3384 (define_insn "*zero_extendqidi2_insn"
3385 [(set (match_operand:DI 0 "register_operand" "=r,r")
3386 (zero_extend:DI (match_operand:QI 1 "input_operand" "r,m")))]
3387 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
3391 [(set_attr "type" "*,load")
3392 (set_attr "us3load_type" "*,3cycle")])
3394 (define_expand "zero_extendhidi2"
3395 [(set (match_operand:DI 0 "register_operand" "")
3396 (zero_extend:DI (match_operand:HI 1 "register_operand" "")))]
3399 rtx temp = gen_reg_rtx (DImode);
3400 rtx shift_48 = GEN_INT (48);
3401 int op1_subbyte = 0;
3403 if (GET_CODE (operand1) == SUBREG)
3405 op1_subbyte = SUBREG_BYTE (operand1);
3406 op1_subbyte /= GET_MODE_SIZE (DImode);
3407 op1_subbyte *= GET_MODE_SIZE (DImode);
3408 operand1 = XEXP (operand1, 0);
3411 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
3413 emit_insn (gen_lshrdi3 (operand0, temp, shift_48));
3417 (define_insn "*zero_extendhidi2_insn"
3418 [(set (match_operand:DI 0 "register_operand" "=r")
3419 (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
3422 [(set_attr "type" "load")
3423 (set_attr "us3load_type" "3cycle")])
3425 ;; ??? Write truncdisi pattern using sra?
3427 (define_expand "zero_extendsidi2"
3428 [(set (match_operand:DI 0 "register_operand" "")
3429 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
3433 (define_insn "*zero_extendsidi2_insn_sp64"
3434 [(set (match_operand:DI 0 "register_operand" "=r,r")
3435 (zero_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
3436 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
3440 [(set_attr "type" "shift,load")])
3442 (define_insn_and_split "*zero_extendsidi2_insn_sp32"
3443 [(set (match_operand:DI 0 "register_operand" "=r")
3444 (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
3447 "&& reload_completed"
3448 [(set (match_dup 2) (match_dup 3))
3449 (set (match_dup 4) (match_dup 5))]
3453 dest1 = gen_highpart (SImode, operands[0]);
3454 dest2 = gen_lowpart (SImode, operands[0]);
3456 /* Swap the order in case of overlap. */
3457 if (REGNO (dest1) == REGNO (operands[1]))
3459 operands[2] = dest2;
3460 operands[3] = operands[1];
3461 operands[4] = dest1;
3462 operands[5] = const0_rtx;
3466 operands[2] = dest1;
3467 operands[3] = const0_rtx;
3468 operands[4] = dest2;
3469 operands[5] = operands[1];
3472 [(set_attr "length" "2")])
3474 ;; Simplify comparisons of extended values.
3476 (define_insn "*cmp_zero_extendqisi2"
3478 (compare:CC (zero_extend:SI (match_operand:QI 0 "register_operand" "r"))
3481 "andcc\t%0, 0xff, %%g0"
3482 [(set_attr "type" "compare")])
3484 (define_insn "*cmp_zero_qi"
3486 (compare:CC (match_operand:QI 0 "register_operand" "r")
3489 "andcc\t%0, 0xff, %%g0"
3490 [(set_attr "type" "compare")])
3492 (define_insn "*cmp_zero_extendqisi2_set"
3494 (compare:CC (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
3496 (set (match_operand:SI 0 "register_operand" "=r")
3497 (zero_extend:SI (match_dup 1)))]
3499 "andcc\t%1, 0xff, %0"
3500 [(set_attr "type" "compare")])
3502 (define_insn "*cmp_zero_extendqisi2_andcc_set"
3504 (compare:CC (and:SI (match_operand:SI 1 "register_operand" "r")
3507 (set (match_operand:SI 0 "register_operand" "=r")
3508 (zero_extend:SI (subreg:QI (match_dup 1) 0)))]
3510 "andcc\t%1, 0xff, %0"
3511 [(set_attr "type" "compare")])
3513 (define_insn "*cmp_zero_extendqidi2"
3515 (compare:CCX (zero_extend:DI (match_operand:QI 0 "register_operand" "r"))
3518 "andcc\t%0, 0xff, %%g0"
3519 [(set_attr "type" "compare")])
3521 (define_insn "*cmp_zero_qi_sp64"
3523 (compare:CCX (match_operand:QI 0 "register_operand" "r")
3526 "andcc\t%0, 0xff, %%g0"
3527 [(set_attr "type" "compare")])
3529 (define_insn "*cmp_zero_extendqidi2_set"
3531 (compare:CCX (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
3533 (set (match_operand:DI 0 "register_operand" "=r")
3534 (zero_extend:DI (match_dup 1)))]
3536 "andcc\t%1, 0xff, %0"
3537 [(set_attr "type" "compare")])
3539 (define_insn "*cmp_zero_extendqidi2_andcc_set"
3541 (compare:CCX (and:DI (match_operand:DI 1 "register_operand" "r")
3544 (set (match_operand:DI 0 "register_operand" "=r")
3545 (zero_extend:DI (subreg:QI (match_dup 1) 0)))]
3547 "andcc\t%1, 0xff, %0"
3548 [(set_attr "type" "compare")])
3550 ;; Similarly, handle {SI,DI}->QI mode truncation followed by a compare.
3552 (define_insn "*cmp_siqi_trunc"
3554 (compare:CC (subreg:QI (match_operand:SI 0 "register_operand" "r") 3)
3557 "andcc\t%0, 0xff, %%g0"
3558 [(set_attr "type" "compare")])
3560 (define_insn "*cmp_siqi_trunc_set"
3562 (compare:CC (subreg:QI (match_operand:SI 1 "register_operand" "r") 3)
3564 (set (match_operand:QI 0 "register_operand" "=r")
3565 (subreg:QI (match_dup 1) 3))]
3567 "andcc\t%1, 0xff, %0"
3568 [(set_attr "type" "compare")])
3570 (define_insn "*cmp_diqi_trunc"
3572 (compare:CC (subreg:QI (match_operand:DI 0 "register_operand" "r") 7)
3575 "andcc\t%0, 0xff, %%g0"
3576 [(set_attr "type" "compare")])
3578 (define_insn "*cmp_diqi_trunc_set"
3580 (compare:CC (subreg:QI (match_operand:DI 1 "register_operand" "r") 7)
3582 (set (match_operand:QI 0 "register_operand" "=r")
3583 (subreg:QI (match_dup 1) 7))]
3585 "andcc\t%1, 0xff, %0"
3586 [(set_attr "type" "compare")])
3589 ;; Sign-extension instructions
3591 ;; These patterns originally accepted general_operands, however, slightly
3592 ;; better code is generated by only accepting register_operands, and then
3593 ;; letting combine generate the lds[hb] insns.
3595 (define_expand "extendhisi2"
3596 [(set (match_operand:SI 0 "register_operand" "")
3597 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
3600 rtx temp = gen_reg_rtx (SImode);
3601 rtx shift_16 = GEN_INT (16);
3602 int op1_subbyte = 0;
3604 if (GET_CODE (operand1) == SUBREG)
3606 op1_subbyte = SUBREG_BYTE (operand1);
3607 op1_subbyte /= GET_MODE_SIZE (SImode);
3608 op1_subbyte *= GET_MODE_SIZE (SImode);
3609 operand1 = XEXP (operand1, 0);
3612 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3614 emit_insn (gen_ashrsi3 (operand0, temp, shift_16));
3618 (define_insn "*sign_extendhisi2_insn"
3619 [(set (match_operand:SI 0 "register_operand" "=r")
3620 (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
3623 [(set_attr "type" "sload")
3624 (set_attr "us3load_type" "3cycle")])
3626 (define_expand "extendqihi2"
3627 [(set (match_operand:HI 0 "register_operand" "")
3628 (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
3631 rtx temp = gen_reg_rtx (SImode);
3632 rtx shift_24 = GEN_INT (24);
3633 int op1_subbyte = 0;
3634 int op0_subbyte = 0;
3636 if (GET_CODE (operand1) == SUBREG)
3638 op1_subbyte = SUBREG_BYTE (operand1);
3639 op1_subbyte /= GET_MODE_SIZE (SImode);
3640 op1_subbyte *= GET_MODE_SIZE (SImode);
3641 operand1 = XEXP (operand1, 0);
3643 if (GET_CODE (operand0) == SUBREG)
3645 op0_subbyte = SUBREG_BYTE (operand0);
3646 op0_subbyte /= GET_MODE_SIZE (SImode);
3647 op0_subbyte *= GET_MODE_SIZE (SImode);
3648 operand0 = XEXP (operand0, 0);
3650 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3652 if (GET_MODE (operand0) != SImode)
3653 operand0 = gen_rtx_SUBREG (SImode, operand0, op0_subbyte);
3654 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
3658 (define_insn "*sign_extendqihi2_insn"
3659 [(set (match_operand:HI 0 "register_operand" "=r")
3660 (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
3663 [(set_attr "type" "sload")
3664 (set_attr "us3load_type" "3cycle")])
3666 (define_expand "extendqisi2"
3667 [(set (match_operand:SI 0 "register_operand" "")
3668 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
3671 rtx temp = gen_reg_rtx (SImode);
3672 rtx shift_24 = GEN_INT (24);
3673 int op1_subbyte = 0;
3675 if (GET_CODE (operand1) == SUBREG)
3677 op1_subbyte = SUBREG_BYTE (operand1);
3678 op1_subbyte /= GET_MODE_SIZE (SImode);
3679 op1_subbyte *= GET_MODE_SIZE (SImode);
3680 operand1 = XEXP (operand1, 0);
3683 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3685 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
3689 (define_insn "*sign_extendqisi2_insn"
3690 [(set (match_operand:SI 0 "register_operand" "=r")
3691 (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
3694 [(set_attr "type" "sload")
3695 (set_attr "us3load_type" "3cycle")])
3697 (define_expand "extendqidi2"
3698 [(set (match_operand:DI 0 "register_operand" "")
3699 (sign_extend:DI (match_operand:QI 1 "register_operand" "")))]
3702 rtx temp = gen_reg_rtx (DImode);
3703 rtx shift_56 = GEN_INT (56);
3704 int op1_subbyte = 0;
3706 if (GET_CODE (operand1) == SUBREG)
3708 op1_subbyte = SUBREG_BYTE (operand1);
3709 op1_subbyte /= GET_MODE_SIZE (DImode);
3710 op1_subbyte *= GET_MODE_SIZE (DImode);
3711 operand1 = XEXP (operand1, 0);
3714 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
3716 emit_insn (gen_ashrdi3 (operand0, temp, shift_56));
3720 (define_insn "*sign_extendqidi2_insn"
3721 [(set (match_operand:DI 0 "register_operand" "=r")
3722 (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
3725 [(set_attr "type" "sload")
3726 (set_attr "us3load_type" "3cycle")])
3728 (define_expand "extendhidi2"
3729 [(set (match_operand:DI 0 "register_operand" "")
3730 (sign_extend:DI (match_operand:HI 1 "register_operand" "")))]
3733 rtx temp = gen_reg_rtx (DImode);
3734 rtx shift_48 = GEN_INT (48);
3735 int op1_subbyte = 0;
3737 if (GET_CODE (operand1) == SUBREG)
3739 op1_subbyte = SUBREG_BYTE (operand1);
3740 op1_subbyte /= GET_MODE_SIZE (DImode);
3741 op1_subbyte *= GET_MODE_SIZE (DImode);
3742 operand1 = XEXP (operand1, 0);
3745 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
3747 emit_insn (gen_ashrdi3 (operand0, temp, shift_48));
3751 (define_insn "*sign_extendhidi2_insn"
3752 [(set (match_operand:DI 0 "register_operand" "=r")
3753 (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
3756 [(set_attr "type" "sload")
3757 (set_attr "us3load_type" "3cycle")])
3759 (define_expand "extendsidi2"
3760 [(set (match_operand:DI 0 "register_operand" "")
3761 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
3765 (define_insn "*sign_extendsidi2_insn"
3766 [(set (match_operand:DI 0 "register_operand" "=r,r")
3767 (sign_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
3772 [(set_attr "type" "shift,sload")
3773 (set_attr "us3load_type" "*,3cycle")])
3776 ;; Special pattern for optimizing bit-field compares. This is needed
3777 ;; because combine uses this as a canonical form.
3779 (define_insn "*cmp_zero_extract"
3782 (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
3783 (match_operand:SI 1 "small_int_operand" "I")
3784 (match_operand:SI 2 "small_int_operand" "I"))
3786 "INTVAL (operands[2]) > 19"
3788 int len = INTVAL (operands[1]);
3789 int pos = 32 - INTVAL (operands[2]) - len;
3790 HOST_WIDE_INT mask = ((1 << len) - 1) << pos;
3791 operands[1] = GEN_INT (mask);
3792 return "andcc\t%0, %1, %%g0";
3794 [(set_attr "type" "compare")])
3796 (define_insn "*cmp_zero_extract_sp64"
3799 (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
3800 (match_operand:SI 1 "small_int_operand" "I")
3801 (match_operand:SI 2 "small_int_operand" "I"))
3803 "TARGET_ARCH64 && INTVAL (operands[2]) > 51"
3805 int len = INTVAL (operands[1]);
3806 int pos = 64 - INTVAL (operands[2]) - len;
3807 HOST_WIDE_INT mask = (((unsigned HOST_WIDE_INT) 1 << len) - 1) << pos;
3808 operands[1] = GEN_INT (mask);
3809 return "andcc\t%0, %1, %%g0";
3811 [(set_attr "type" "compare")])
3814 ;; Conversions between float, double and long double.
3816 (define_insn "extendsfdf2"
3817 [(set (match_operand:DF 0 "register_operand" "=e")
3819 (match_operand:SF 1 "register_operand" "f")))]
3822 [(set_attr "type" "fp")
3823 (set_attr "fptype" "double")])
3825 (define_expand "extendsftf2"
3826 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3828 (match_operand:SF 1 "register_operand" "")))]
3829 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3830 "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
3832 (define_insn "*extendsftf2_hq"
3833 [(set (match_operand:TF 0 "register_operand" "=e")
3835 (match_operand:SF 1 "register_operand" "f")))]
3836 "TARGET_FPU && TARGET_HARD_QUAD"
3838 [(set_attr "type" "fp")])
3840 (define_expand "extenddftf2"
3841 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3843 (match_operand:DF 1 "register_operand" "")))]
3844 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3845 "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
3847 (define_insn "*extenddftf2_hq"
3848 [(set (match_operand:TF 0 "register_operand" "=e")
3850 (match_operand:DF 1 "register_operand" "e")))]
3851 "TARGET_FPU && TARGET_HARD_QUAD"
3853 [(set_attr "type" "fp")])
3855 (define_insn "truncdfsf2"
3856 [(set (match_operand:SF 0 "register_operand" "=f")
3858 (match_operand:DF 1 "register_operand" "e")))]
3861 [(set_attr "type" "fp")
3862 (set_attr "fptype" "double")])
3864 (define_expand "trunctfsf2"
3865 [(set (match_operand:SF 0 "register_operand" "")
3867 (match_operand:TF 1 "general_operand" "")))]
3868 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3869 "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
3871 (define_insn "*trunctfsf2_hq"
3872 [(set (match_operand:SF 0 "register_operand" "=f")
3874 (match_operand:TF 1 "register_operand" "e")))]
3875 "TARGET_FPU && TARGET_HARD_QUAD"
3877 [(set_attr "type" "fp")])
3879 (define_expand "trunctfdf2"
3880 [(set (match_operand:DF 0 "register_operand" "")
3882 (match_operand:TF 1 "general_operand" "")))]
3883 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3884 "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
3886 (define_insn "*trunctfdf2_hq"
3887 [(set (match_operand:DF 0 "register_operand" "=e")
3889 (match_operand:TF 1 "register_operand" "e")))]
3890 "TARGET_FPU && TARGET_HARD_QUAD"
3892 [(set_attr "type" "fp")])
3895 ;; Conversion between fixed point and floating point.
3897 (define_insn "floatsisf2"
3898 [(set (match_operand:SF 0 "register_operand" "=f")
3899 (float:SF (match_operand:SI 1 "register_operand" "f")))]
3902 [(set_attr "type" "fp")
3903 (set_attr "fptype" "double")])
3905 (define_insn "floatsidf2"
3906 [(set (match_operand:DF 0 "register_operand" "=e")
3907 (float:DF (match_operand:SI 1 "register_operand" "f")))]
3910 [(set_attr "type" "fp")
3911 (set_attr "fptype" "double")])
3913 (define_expand "floatsitf2"
3914 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3915 (float:TF (match_operand:SI 1 "register_operand" "")))]
3916 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3917 "emit_tfmode_cvt (FLOAT, operands); DONE;")
3919 (define_insn "*floatsitf2_hq"
3920 [(set (match_operand:TF 0 "register_operand" "=e")
3921 (float:TF (match_operand:SI 1 "register_operand" "f")))]
3922 "TARGET_FPU && TARGET_HARD_QUAD"
3924 [(set_attr "type" "fp")])
3926 (define_expand "floatunssitf2"
3927 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3928 (unsigned_float:TF (match_operand:SI 1 "register_operand" "")))]
3929 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3930 "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
3932 ;; Now the same for 64 bit sources.
3934 (define_insn "floatdisf2"
3935 [(set (match_operand:SF 0 "register_operand" "=f")
3936 (float:SF (match_operand:DI 1 "register_operand" "e")))]
3937 "TARGET_V9 && TARGET_FPU"
3939 [(set_attr "type" "fp")
3940 (set_attr "fptype" "double")])
3942 (define_expand "floatunsdisf2"
3943 [(use (match_operand:SF 0 "register_operand" ""))
3944 (use (match_operand:DI 1 "general_operand" ""))]
3945 "TARGET_ARCH64 && TARGET_FPU"
3946 "sparc_emit_floatunsdi (operands, SFmode); DONE;")
3948 (define_insn "floatdidf2"
3949 [(set (match_operand:DF 0 "register_operand" "=e")
3950 (float:DF (match_operand:DI 1 "register_operand" "e")))]
3951 "TARGET_V9 && TARGET_FPU"
3953 [(set_attr "type" "fp")
3954 (set_attr "fptype" "double")])
3956 (define_expand "floatunsdidf2"
3957 [(use (match_operand:DF 0 "register_operand" ""))
3958 (use (match_operand:DI 1 "general_operand" ""))]
3959 "TARGET_ARCH64 && TARGET_FPU"
3960 "sparc_emit_floatunsdi (operands, DFmode); DONE;")
3962 (define_expand "floatditf2"
3963 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3964 (float:TF (match_operand:DI 1 "register_operand" "")))]
3965 "TARGET_FPU && TARGET_V9 && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3966 "emit_tfmode_cvt (FLOAT, operands); DONE;")
3968 (define_insn "*floatditf2_hq"
3969 [(set (match_operand:TF 0 "register_operand" "=e")
3970 (float:TF (match_operand:DI 1 "register_operand" "e")))]
3971 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
3973 [(set_attr "type" "fp")])
3975 (define_expand "floatunsditf2"
3976 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3977 (unsigned_float:TF (match_operand:DI 1 "register_operand" "")))]
3978 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3979 "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
3981 ;; Convert a float to an actual integer.
3982 ;; Truncation is performed as part of the conversion.
3984 (define_insn "fix_truncsfsi2"
3985 [(set (match_operand:SI 0 "register_operand" "=f")
3986 (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
3989 [(set_attr "type" "fp")
3990 (set_attr "fptype" "double")])
3992 (define_insn "fix_truncdfsi2"
3993 [(set (match_operand:SI 0 "register_operand" "=f")
3994 (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
3997 [(set_attr "type" "fp")
3998 (set_attr "fptype" "double")])
4000 (define_expand "fix_trunctfsi2"
4001 [(set (match_operand:SI 0 "register_operand" "")
4002 (fix:SI (match_operand:TF 1 "general_operand" "")))]
4003 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4004 "emit_tfmode_cvt (FIX, operands); DONE;")
4006 (define_insn "*fix_trunctfsi2_hq"
4007 [(set (match_operand:SI 0 "register_operand" "=f")
4008 (fix:SI (match_operand:TF 1 "register_operand" "e")))]
4009 "TARGET_FPU && TARGET_HARD_QUAD"
4011 [(set_attr "type" "fp")])
4013 (define_expand "fixuns_trunctfsi2"
4014 [(set (match_operand:SI 0 "register_operand" "")
4015 (unsigned_fix:SI (match_operand:TF 1 "general_operand" "")))]
4016 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4017 "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
4019 ;; Now the same, for V9 targets
4021 (define_insn "fix_truncsfdi2"
4022 [(set (match_operand:DI 0 "register_operand" "=e")
4023 (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
4024 "TARGET_V9 && TARGET_FPU"
4026 [(set_attr "type" "fp")
4027 (set_attr "fptype" "double")])
4029 (define_expand "fixuns_truncsfdi2"
4030 [(use (match_operand:DI 0 "register_operand" ""))
4031 (use (match_operand:SF 1 "general_operand" ""))]
4032 "TARGET_ARCH64 && TARGET_FPU"
4033 "sparc_emit_fixunsdi (operands, SFmode); DONE;")
4035 (define_insn "fix_truncdfdi2"
4036 [(set (match_operand:DI 0 "register_operand" "=e")
4037 (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
4038 "TARGET_V9 && TARGET_FPU"
4040 [(set_attr "type" "fp")
4041 (set_attr "fptype" "double")])
4043 (define_expand "fixuns_truncdfdi2"
4044 [(use (match_operand:DI 0 "register_operand" ""))
4045 (use (match_operand:DF 1 "general_operand" ""))]
4046 "TARGET_ARCH64 && TARGET_FPU"
4047 "sparc_emit_fixunsdi (operands, DFmode); DONE;")
4049 (define_expand "fix_trunctfdi2"
4050 [(set (match_operand:DI 0 "register_operand" "")
4051 (fix:DI (match_operand:TF 1 "general_operand" "")))]
4052 "TARGET_V9 && TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4053 "emit_tfmode_cvt (FIX, operands); DONE;")
4055 (define_insn "*fix_trunctfdi2_hq"
4056 [(set (match_operand:DI 0 "register_operand" "=e")
4057 (fix:DI (match_operand:TF 1 "register_operand" "e")))]
4058 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
4060 [(set_attr "type" "fp")])
4062 (define_expand "fixuns_trunctfdi2"
4063 [(set (match_operand:DI 0 "register_operand" "")
4064 (unsigned_fix:DI (match_operand:TF 1 "general_operand" "")))]
4065 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4066 "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
4069 ;; Integer addition/subtraction instructions.
4071 (define_expand "adddi3"
4072 [(set (match_operand:DI 0 "register_operand" "")
4073 (plus:DI (match_operand:DI 1 "register_operand" "")
4074 (match_operand:DI 2 "arith_double_add_operand" "")))]
4077 if (! TARGET_ARCH64)
4079 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
4080 gen_rtx_SET (VOIDmode, operands[0],
4081 gen_rtx_PLUS (DImode, operands[1],
4083 gen_rtx_CLOBBER (VOIDmode,
4084 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
4089 (define_insn_and_split "adddi3_insn_sp32"
4090 [(set (match_operand:DI 0 "register_operand" "=r")
4091 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
4092 (match_operand:DI 2 "arith_double_operand" "rHI")))
4093 (clobber (reg:CC 100))]
4096 "&& reload_completed"
4097 [(parallel [(set (reg:CC_NOOV 100)
4098 (compare:CC_NOOV (plus:SI (match_dup 4)
4102 (plus:SI (match_dup 4) (match_dup 5)))])
4104 (plus:SI (plus:SI (match_dup 7)
4106 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4108 operands[3] = gen_lowpart (SImode, operands[0]);
4109 operands[4] = gen_lowpart (SImode, operands[1]);
4110 operands[5] = gen_lowpart (SImode, operands[2]);
4111 operands[6] = gen_highpart (SImode, operands[0]);
4112 operands[7] = gen_highpart_mode (SImode, DImode, operands[1]);
4113 #if HOST_BITS_PER_WIDE_INT == 32
4114 if (GET_CODE (operands[2]) == CONST_INT)
4116 if (INTVAL (operands[2]) < 0)
4117 operands[8] = constm1_rtx;
4119 operands[8] = const0_rtx;
4123 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
4125 [(set_attr "length" "2")])
4127 ;; LTU here means "carry set"
4129 [(set (match_operand:SI 0 "register_operand" "=r")
4130 (plus:SI (plus:SI (match_operand:SI 1 "arith_operand" "%r")
4131 (match_operand:SI 2 "arith_operand" "rI"))
4132 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4135 [(set_attr "type" "ialuX")])
4137 (define_insn_and_split "*addx_extend_sp32"
4138 [(set (match_operand:DI 0 "register_operand" "=r")
4139 (zero_extend:DI (plus:SI (plus:SI
4140 (match_operand:SI 1 "register_or_zero_operand" "%rJ")
4141 (match_operand:SI 2 "arith_operand" "rI"))
4142 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4145 "&& reload_completed"
4146 [(set (match_dup 3) (plus:SI (plus:SI (match_dup 1) (match_dup 2))
4147 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
4148 (set (match_dup 4) (const_int 0))]
4149 "operands[3] = gen_lowpart (SImode, operands[0]);
4150 operands[4] = gen_highpart_mode (SImode, DImode, operands[1]);"
4151 [(set_attr "length" "2")])
4153 (define_insn "*addx_extend_sp64"
4154 [(set (match_operand:DI 0 "register_operand" "=r")
4155 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ")
4156 (match_operand:SI 2 "arith_operand" "rI"))
4157 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4160 [(set_attr "type" "ialuX")])
4162 (define_insn_and_split ""
4163 [(set (match_operand:DI 0 "register_operand" "=r")
4164 (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4165 (match_operand:DI 2 "register_operand" "r")))
4166 (clobber (reg:CC 100))]
4169 "&& reload_completed"
4170 [(parallel [(set (reg:CC_NOOV 100)
4171 (compare:CC_NOOV (plus:SI (match_dup 3) (match_dup 1))
4173 (set (match_dup 5) (plus:SI (match_dup 3) (match_dup 1)))])
4175 (plus:SI (plus:SI (match_dup 4) (const_int 0))
4176 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4177 "operands[3] = gen_lowpart (SImode, operands[2]);
4178 operands[4] = gen_highpart (SImode, operands[2]);
4179 operands[5] = gen_lowpart (SImode, operands[0]);
4180 operands[6] = gen_highpart (SImode, operands[0]);"
4181 [(set_attr "length" "2")])
4183 (define_insn "*adddi3_sp64"
4184 [(set (match_operand:DI 0 "register_operand" "=r,r")
4185 (plus:DI (match_operand:DI 1 "register_operand" "%r,r")
4186 (match_operand:DI 2 "arith_add_operand" "rI,O")))]
4192 (define_insn "addsi3"
4193 [(set (match_operand:SI 0 "register_operand" "=r,r,d")
4194 (plus:SI (match_operand:SI 1 "register_operand" "%r,r,d")
4195 (match_operand:SI 2 "arith_add_operand" "rI,O,d")))]
4200 fpadd32s\t%1, %2, %0"
4201 [(set_attr "type" "*,*,fga")
4202 (set_attr "fptype" "*,*,single")])
4204 (define_insn "*cmp_cc_plus"
4205 [(set (reg:CC_NOOV 100)
4206 (compare:CC_NOOV (plus:SI (match_operand:SI 0 "arith_operand" "%r")
4207 (match_operand:SI 1 "arith_operand" "rI"))
4210 "addcc\t%0, %1, %%g0"
4211 [(set_attr "type" "compare")])
4213 (define_insn "*cmp_ccx_plus"
4214 [(set (reg:CCX_NOOV 100)
4215 (compare:CCX_NOOV (plus:DI (match_operand:DI 0 "arith_operand" "%r")
4216 (match_operand:DI 1 "arith_operand" "rI"))
4219 "addcc\t%0, %1, %%g0"
4220 [(set_attr "type" "compare")])
4222 (define_insn "*cmp_cc_plus_set"
4223 [(set (reg:CC_NOOV 100)
4224 (compare:CC_NOOV (plus:SI (match_operand:SI 1 "arith_operand" "%r")
4225 (match_operand:SI 2 "arith_operand" "rI"))
4227 (set (match_operand:SI 0 "register_operand" "=r")
4228 (plus:SI (match_dup 1) (match_dup 2)))]
4231 [(set_attr "type" "compare")])
4233 (define_insn "*cmp_ccx_plus_set"
4234 [(set (reg:CCX_NOOV 100)
4235 (compare:CCX_NOOV (plus:DI (match_operand:DI 1 "arith_operand" "%r")
4236 (match_operand:DI 2 "arith_operand" "rI"))
4238 (set (match_operand:DI 0 "register_operand" "=r")
4239 (plus:DI (match_dup 1) (match_dup 2)))]
4242 [(set_attr "type" "compare")])
4244 (define_expand "subdi3"
4245 [(set (match_operand:DI 0 "register_operand" "")
4246 (minus:DI (match_operand:DI 1 "register_operand" "")
4247 (match_operand:DI 2 "arith_double_add_operand" "")))]
4250 if (! TARGET_ARCH64)
4252 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
4253 gen_rtx_SET (VOIDmode, operands[0],
4254 gen_rtx_MINUS (DImode, operands[1],
4256 gen_rtx_CLOBBER (VOIDmode,
4257 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
4262 (define_insn_and_split "subdi3_insn_sp32"
4263 [(set (match_operand:DI 0 "register_operand" "=r")
4264 (minus:DI (match_operand:DI 1 "register_operand" "r")
4265 (match_operand:DI 2 "arith_double_operand" "rHI")))
4266 (clobber (reg:CC 100))]
4269 "&& reload_completed"
4270 [(parallel [(set (reg:CC_NOOV 100)
4271 (compare:CC_NOOV (minus:SI (match_dup 4)
4275 (minus:SI (match_dup 4) (match_dup 5)))])
4277 (minus:SI (minus:SI (match_dup 7)
4279 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4281 operands[3] = gen_lowpart (SImode, operands[0]);
4282 operands[4] = gen_lowpart (SImode, operands[1]);
4283 operands[5] = gen_lowpart (SImode, operands[2]);
4284 operands[6] = gen_highpart (SImode, operands[0]);
4285 operands[7] = gen_highpart (SImode, operands[1]);
4286 #if HOST_BITS_PER_WIDE_INT == 32
4287 if (GET_CODE (operands[2]) == CONST_INT)
4289 if (INTVAL (operands[2]) < 0)
4290 operands[8] = constm1_rtx;
4292 operands[8] = const0_rtx;
4296 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
4298 [(set_attr "length" "2")])
4300 ;; LTU here means "carry set"
4302 [(set (match_operand:SI 0 "register_operand" "=r")
4303 (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
4304 (match_operand:SI 2 "arith_operand" "rI"))
4305 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4308 [(set_attr "type" "ialuX")])
4310 (define_insn "*subx_extend_sp64"
4311 [(set (match_operand:DI 0 "register_operand" "=r")
4312 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
4313 (match_operand:SI 2 "arith_operand" "rI"))
4314 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4317 [(set_attr "type" "ialuX")])
4319 (define_insn_and_split "*subx_extend"
4320 [(set (match_operand:DI 0 "register_operand" "=r")
4321 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
4322 (match_operand:SI 2 "arith_operand" "rI"))
4323 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4326 "&& reload_completed"
4327 [(set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 2))
4328 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
4329 (set (match_dup 4) (const_int 0))]
4330 "operands[3] = gen_lowpart (SImode, operands[0]);
4331 operands[4] = gen_highpart (SImode, operands[0]);"
4332 [(set_attr "length" "2")])
4334 (define_insn_and_split ""
4335 [(set (match_operand:DI 0 "register_operand" "=r")
4336 (minus:DI (match_operand:DI 1 "register_operand" "r")
4337 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))
4338 (clobber (reg:CC 100))]
4341 "&& reload_completed"
4342 [(parallel [(set (reg:CC_NOOV 100)
4343 (compare:CC_NOOV (minus:SI (match_dup 3) (match_dup 2))
4345 (set (match_dup 5) (minus:SI (match_dup 3) (match_dup 2)))])
4347 (minus:SI (minus:SI (match_dup 4) (const_int 0))
4348 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4349 "operands[3] = gen_lowpart (SImode, operands[1]);
4350 operands[4] = gen_highpart (SImode, operands[1]);
4351 operands[5] = gen_lowpart (SImode, operands[0]);
4352 operands[6] = gen_highpart (SImode, operands[0]);"
4353 [(set_attr "length" "2")])
4355 (define_insn "*subdi3_sp64"
4356 [(set (match_operand:DI 0 "register_operand" "=r,r")
4357 (minus:DI (match_operand:DI 1 "register_operand" "r,r")
4358 (match_operand:DI 2 "arith_add_operand" "rI,O")))]
4364 (define_insn "subsi3"
4365 [(set (match_operand:SI 0 "register_operand" "=r,r,d")
4366 (minus:SI (match_operand:SI 1 "register_operand" "r,r,d")
4367 (match_operand:SI 2 "arith_add_operand" "rI,O,d")))]
4372 fpsub32s\t%1, %2, %0"
4373 [(set_attr "type" "*,*,fga")
4374 (set_attr "fptype" "*,*,single")])
4376 (define_insn "*cmp_minus_cc"
4377 [(set (reg:CC_NOOV 100)
4378 (compare:CC_NOOV (minus:SI (match_operand:SI 0 "register_or_zero_operand" "rJ")
4379 (match_operand:SI 1 "arith_operand" "rI"))
4382 "subcc\t%r0, %1, %%g0"
4383 [(set_attr "type" "compare")])
4385 (define_insn "*cmp_minus_ccx"
4386 [(set (reg:CCX_NOOV 100)
4387 (compare:CCX_NOOV (minus:DI (match_operand:DI 0 "register_operand" "r")
4388 (match_operand:DI 1 "arith_operand" "rI"))
4391 "subcc\t%0, %1, %%g0"
4392 [(set_attr "type" "compare")])
4394 (define_insn "cmp_minus_cc_set"
4395 [(set (reg:CC_NOOV 100)
4396 (compare:CC_NOOV (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
4397 (match_operand:SI 2 "arith_operand" "rI"))
4399 (set (match_operand:SI 0 "register_operand" "=r")
4400 (minus:SI (match_dup 1) (match_dup 2)))]
4402 "subcc\t%r1, %2, %0"
4403 [(set_attr "type" "compare")])
4405 (define_insn "*cmp_minus_ccx_set"
4406 [(set (reg:CCX_NOOV 100)
4407 (compare:CCX_NOOV (minus:DI (match_operand:DI 1 "register_operand" "r")
4408 (match_operand:DI 2 "arith_operand" "rI"))
4410 (set (match_operand:DI 0 "register_operand" "=r")
4411 (minus:DI (match_dup 1) (match_dup 2)))]
4414 [(set_attr "type" "compare")])
4417 ;; Integer multiply/divide instructions.
4419 ;; The 32-bit multiply/divide instructions are deprecated on v9, but at
4420 ;; least in UltraSPARC I, II and IIi it is a win tick-wise.
4422 (define_insn "mulsi3"
4423 [(set (match_operand:SI 0 "register_operand" "=r")
4424 (mult:SI (match_operand:SI 1 "arith_operand" "%r")
4425 (match_operand:SI 2 "arith_operand" "rI")))]
4428 [(set_attr "type" "imul")])
4430 (define_expand "muldi3"
4431 [(set (match_operand:DI 0 "register_operand" "")
4432 (mult:DI (match_operand:DI 1 "arith_operand" "")
4433 (match_operand:DI 2 "arith_operand" "")))]
4434 "TARGET_ARCH64 || TARGET_V8PLUS"
4438 emit_insn (gen_muldi3_v8plus (operands[0], operands[1], operands[2]));
4443 (define_insn "*muldi3_sp64"
4444 [(set (match_operand:DI 0 "register_operand" "=r")
4445 (mult:DI (match_operand:DI 1 "arith_operand" "%r")
4446 (match_operand:DI 2 "arith_operand" "rI")))]
4449 [(set_attr "type" "imul")])
4451 ;; V8plus wide multiply.
4453 (define_insn "muldi3_v8plus"
4454 [(set (match_operand:DI 0 "register_operand" "=r,h")
4455 (mult:DI (match_operand:DI 1 "arith_operand" "%r,0")
4456 (match_operand:DI 2 "arith_operand" "rI,rI")))
4457 (clobber (match_scratch:SI 3 "=&h,X"))
4458 (clobber (match_scratch:SI 4 "=&h,X"))]
4461 if (sparc_check_64 (operands[1], insn) <= 0)
4462 output_asm_insn ("srl\t%L1, 0, %L1", operands);
4463 if (which_alternative == 1)
4464 output_asm_insn ("sllx\t%H1, 32, %H1", operands);
4465 if (GET_CODE (operands[2]) == CONST_INT)
4467 if (which_alternative == 1)
4468 return "or\t%L1, %H1, %H1\n\tmulx\t%H1, %2, %L0\;srlx\t%L0, 32, %H0";
4470 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";
4472 else if (rtx_equal_p (operands[1], operands[2]))
4474 if (which_alternative == 1)
4475 return "or\t%L1, %H1, %H1\n\tmulx\t%H1, %H1, %L0\;srlx\t%L0, 32, %H0";
4477 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";
4479 if (sparc_check_64 (operands[2], insn) <= 0)
4480 output_asm_insn ("srl\t%L2, 0, %L2", operands);
4481 if (which_alternative == 1)
4482 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";
4484 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";
4486 [(set_attr "type" "multi")
4487 (set_attr "length" "9,8")])
4489 (define_insn "*cmp_mul_set"
4491 (compare:CC (mult:SI (match_operand:SI 1 "arith_operand" "%r")
4492 (match_operand:SI 2 "arith_operand" "rI"))
4494 (set (match_operand:SI 0 "register_operand" "=r")
4495 (mult:SI (match_dup 1) (match_dup 2)))]
4496 "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS"
4497 "smulcc\t%1, %2, %0"
4498 [(set_attr "type" "imul")])
4500 (define_expand "mulsidi3"
4501 [(set (match_operand:DI 0 "register_operand" "")
4502 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
4503 (sign_extend:DI (match_operand:SI 2 "arith_operand" ""))))]
4506 if (CONSTANT_P (operands[2]))
4509 emit_insn (gen_const_mulsidi3_v8plus (operands[0], operands[1],
4511 else if (TARGET_ARCH32)
4512 emit_insn (gen_const_mulsidi3_sp32 (operands[0], operands[1],
4515 emit_insn (gen_const_mulsidi3_sp64 (operands[0], operands[1],
4521 emit_insn (gen_mulsidi3_v8plus (operands[0], operands[1], operands[2]));
4526 ;; V9 puts the 64-bit product in a 64-bit register. Only out or global
4527 ;; registers can hold 64-bit values in the V8plus environment.
4529 (define_insn "mulsidi3_v8plus"
4530 [(set (match_operand:DI 0 "register_operand" "=h,r")
4531 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4532 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
4533 (clobber (match_scratch:SI 3 "=X,&h"))]
4536 smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
4537 smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4538 [(set_attr "type" "multi")
4539 (set_attr "length" "2,3")])
4542 (define_insn "const_mulsidi3_v8plus"
4543 [(set (match_operand:DI 0 "register_operand" "=h,r")
4544 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4545 (match_operand:DI 2 "small_int_operand" "I,I")))
4546 (clobber (match_scratch:SI 3 "=X,&h"))]
4549 smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
4550 smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4551 [(set_attr "type" "multi")
4552 (set_attr "length" "2,3")])
4555 (define_insn "*mulsidi3_sp32"
4556 [(set (match_operand:DI 0 "register_operand" "=r")
4557 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4558 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4561 return TARGET_SPARCLET
4562 ? "smuld\t%1, %2, %L0"
4563 : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
4566 (if_then_else (eq_attr "isa" "sparclet")
4567 (const_string "imul") (const_string "multi")))
4568 (set (attr "length")
4569 (if_then_else (eq_attr "isa" "sparclet")
4570 (const_int 1) (const_int 2)))])
4572 (define_insn "*mulsidi3_sp64"
4573 [(set (match_operand:DI 0 "register_operand" "=r")
4574 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4575 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4576 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4578 [(set_attr "type" "imul")])
4580 ;; Extra pattern, because sign_extend of a constant isn't valid.
4583 (define_insn "const_mulsidi3_sp32"
4584 [(set (match_operand:DI 0 "register_operand" "=r")
4585 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4586 (match_operand:DI 2 "small_int_operand" "I")))]
4589 return TARGET_SPARCLET
4590 ? "smuld\t%1, %2, %L0"
4591 : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
4594 (if_then_else (eq_attr "isa" "sparclet")
4595 (const_string "imul") (const_string "multi")))
4596 (set (attr "length")
4597 (if_then_else (eq_attr "isa" "sparclet")
4598 (const_int 1) (const_int 2)))])
4600 (define_insn "const_mulsidi3_sp64"
4601 [(set (match_operand:DI 0 "register_operand" "=r")
4602 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4603 (match_operand:DI 2 "small_int_operand" "I")))]
4604 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4606 [(set_attr "type" "imul")])
4608 (define_expand "smulsi3_highpart"
4609 [(set (match_operand:SI 0 "register_operand" "")
4611 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
4612 (sign_extend:DI (match_operand:SI 2 "arith_operand" "")))
4614 "TARGET_HARD_MUL && TARGET_ARCH32"
4616 if (CONSTANT_P (operands[2]))
4620 emit_insn (gen_const_smulsi3_highpart_v8plus (operands[0],
4626 emit_insn (gen_const_smulsi3_highpart (operands[0], operands[1], operands[2]));
4631 emit_insn (gen_smulsi3_highpart_v8plus (operands[0], operands[1],
4632 operands[2], GEN_INT (32)));
4638 (define_insn "smulsi3_highpart_v8plus"
4639 [(set (match_operand:SI 0 "register_operand" "=h,r")
4641 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4642 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
4643 (match_operand:SI 3 "small_int_operand" "I,I"))))
4644 (clobber (match_scratch:SI 4 "=X,&h"))]
4647 smul\t%1, %2, %0\;srlx\t%0, %3, %0
4648 smul\t%1, %2, %4\;srlx\t%4, %3, %0"
4649 [(set_attr "type" "multi")
4650 (set_attr "length" "2")])
4652 ;; The combiner changes TRUNCATE in the previous pattern to SUBREG.
4655 [(set (match_operand:SI 0 "register_operand" "=h,r")
4658 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4659 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
4660 (match_operand:SI 3 "small_int_operand" "I,I"))
4662 (clobber (match_scratch:SI 4 "=X,&h"))]
4665 smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
4666 smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
4667 [(set_attr "type" "multi")
4668 (set_attr "length" "2")])
4671 (define_insn "const_smulsi3_highpart_v8plus"
4672 [(set (match_operand:SI 0 "register_operand" "=h,r")
4674 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4675 (match_operand:DI 2 "small_int_operand" "I,I"))
4676 (match_operand:SI 3 "small_int_operand" "I,I"))))
4677 (clobber (match_scratch:SI 4 "=X,&h"))]
4680 smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
4681 smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
4682 [(set_attr "type" "multi")
4683 (set_attr "length" "2")])
4686 (define_insn "*smulsi3_highpart_sp32"
4687 [(set (match_operand:SI 0 "register_operand" "=r")
4689 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4690 (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
4693 "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
4694 [(set_attr "type" "multi")
4695 (set_attr "length" "2")])
4698 (define_insn "const_smulsi3_highpart"
4699 [(set (match_operand:SI 0 "register_operand" "=r")
4701 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4702 (match_operand:DI 2 "small_int_operand" "i"))
4705 "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
4706 [(set_attr "type" "multi")
4707 (set_attr "length" "2")])
4709 (define_expand "umulsidi3"
4710 [(set (match_operand:DI 0 "register_operand" "")
4711 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
4712 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" ""))))]
4715 if (CONSTANT_P (operands[2]))
4718 emit_insn (gen_const_umulsidi3_v8plus (operands[0], operands[1],
4720 else if (TARGET_ARCH32)
4721 emit_insn (gen_const_umulsidi3_sp32 (operands[0], operands[1],
4724 emit_insn (gen_const_umulsidi3_sp64 (operands[0], operands[1],
4730 emit_insn (gen_umulsidi3_v8plus (operands[0], operands[1], operands[2]));
4736 (define_insn "umulsidi3_v8plus"
4737 [(set (match_operand:DI 0 "register_operand" "=h,r")
4738 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4739 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
4740 (clobber (match_scratch:SI 3 "=X,&h"))]
4743 umul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
4744 umul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4745 [(set_attr "type" "multi")
4746 (set_attr "length" "2,3")])
4749 (define_insn "*umulsidi3_sp32"
4750 [(set (match_operand:DI 0 "register_operand" "=r")
4751 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4752 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4755 return TARGET_SPARCLET
4756 ? "umuld\t%1, %2, %L0"
4757 : "umul\t%1, %2, %L0\n\trd\t%%y, %H0";
4760 (if_then_else (eq_attr "isa" "sparclet")
4761 (const_string "imul") (const_string "multi")))
4762 (set (attr "length")
4763 (if_then_else (eq_attr "isa" "sparclet")
4764 (const_int 1) (const_int 2)))])
4766 (define_insn "*umulsidi3_sp64"
4767 [(set (match_operand:DI 0 "register_operand" "=r")
4768 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4769 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4770 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4772 [(set_attr "type" "imul")])
4774 ;; Extra pattern, because sign_extend of a constant isn't valid.
4777 (define_insn "const_umulsidi3_sp32"
4778 [(set (match_operand:DI 0 "register_operand" "=r")
4779 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4780 (match_operand:DI 2 "uns_small_int_operand" "")))]
4783 return TARGET_SPARCLET
4784 ? "umuld\t%1, %s2, %L0"
4785 : "umul\t%1, %s2, %L0\n\trd\t%%y, %H0";
4788 (if_then_else (eq_attr "isa" "sparclet")
4789 (const_string "imul") (const_string "multi")))
4790 (set (attr "length")
4791 (if_then_else (eq_attr "isa" "sparclet")
4792 (const_int 1) (const_int 2)))])
4794 (define_insn "const_umulsidi3_sp64"
4795 [(set (match_operand:DI 0 "register_operand" "=r")
4796 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4797 (match_operand:DI 2 "uns_small_int_operand" "")))]
4798 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4800 [(set_attr "type" "imul")])
4803 (define_insn "const_umulsidi3_v8plus"
4804 [(set (match_operand:DI 0 "register_operand" "=h,r")
4805 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4806 (match_operand:DI 2 "uns_small_int_operand" "")))
4807 (clobber (match_scratch:SI 3 "=X,h"))]
4810 umul\t%1, %s2, %L0\n\tsrlx\t%L0, 32, %H0
4811 umul\t%1, %s2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4812 [(set_attr "type" "multi")
4813 (set_attr "length" "2,3")])
4815 (define_expand "umulsi3_highpart"
4816 [(set (match_operand:SI 0 "register_operand" "")
4818 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
4819 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" "")))
4821 "TARGET_HARD_MUL && TARGET_ARCH32"
4823 if (CONSTANT_P (operands[2]))
4827 emit_insn (gen_const_umulsi3_highpart_v8plus (operands[0],
4833 emit_insn (gen_const_umulsi3_highpart (operands[0], operands[1], operands[2]));
4838 emit_insn (gen_umulsi3_highpart_v8plus (operands[0], operands[1],
4839 operands[2], GEN_INT (32)));
4845 (define_insn "umulsi3_highpart_v8plus"
4846 [(set (match_operand:SI 0 "register_operand" "=h,r")
4848 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4849 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
4850 (match_operand:SI 3 "small_int_operand" "I,I"))))
4851 (clobber (match_scratch:SI 4 "=X,h"))]
4854 umul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
4855 umul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
4856 [(set_attr "type" "multi")
4857 (set_attr "length" "2")])
4860 (define_insn "const_umulsi3_highpart_v8plus"
4861 [(set (match_operand:SI 0 "register_operand" "=h,r")
4863 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4864 (match_operand:DI 2 "uns_small_int_operand" ""))
4865 (match_operand:SI 3 "small_int_operand" "I,I"))))
4866 (clobber (match_scratch:SI 4 "=X,h"))]
4869 umul\t%1, %s2, %0\n\tsrlx\t%0, %3, %0
4870 umul\t%1, %s2, %4\n\tsrlx\t%4, %3, %0"
4871 [(set_attr "type" "multi")
4872 (set_attr "length" "2")])
4875 (define_insn "*umulsi3_highpart_sp32"
4876 [(set (match_operand:SI 0 "register_operand" "=r")
4878 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4879 (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
4882 "umul\t%1, %2, %%g0\n\trd\t%%y, %0"
4883 [(set_attr "type" "multi")
4884 (set_attr "length" "2")])
4887 (define_insn "const_umulsi3_highpart"
4888 [(set (match_operand:SI 0 "register_operand" "=r")
4890 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4891 (match_operand:DI 2 "uns_small_int_operand" ""))
4894 "umul\t%1, %s2, %%g0\n\trd\t%%y, %0"
4895 [(set_attr "type" "multi")
4896 (set_attr "length" "2")])
4898 ;; The V8 architecture specifies that there must be 3 instructions between
4899 ;; a Y register write and a use of it for correct results.
4901 (define_expand "divsi3"
4902 [(parallel [(set (match_operand:SI 0 "register_operand" "=r,r")
4903 (div:SI (match_operand:SI 1 "register_operand" "r,r")
4904 (match_operand:SI 2 "input_operand" "rI,m")))
4905 (clobber (match_scratch:SI 3 "=&r,&r"))])]
4906 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4910 operands[3] = gen_reg_rtx(SImode);
4911 emit_insn (gen_ashrsi3 (operands[3], operands[1], GEN_INT (31)));
4912 emit_insn (gen_divsi3_sp64 (operands[0], operands[1], operands[2],
4918 (define_insn "divsi3_sp32"
4919 [(set (match_operand:SI 0 "register_operand" "=r,r")
4920 (div:SI (match_operand:SI 1 "register_operand" "r,r")
4921 (match_operand:SI 2 "input_operand" "rI,m")))
4922 (clobber (match_scratch:SI 3 "=&r,&r"))]
4923 "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS)
4926 if (which_alternative == 0)
4928 return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tsdiv\t%1, %2, %0";
4930 return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tnop\n\tnop\n\tnop\n\tsdiv\t%1, %2, %0";
4933 return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tld\t%2, %3\n\tsdiv\t%1, %3, %0";
4935 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";
4937 [(set_attr "type" "multi")
4938 (set (attr "length")
4939 (if_then_else (eq_attr "isa" "v9")
4940 (const_int 4) (const_int 6)))])
4942 (define_insn "divsi3_sp64"
4943 [(set (match_operand:SI 0 "register_operand" "=r")
4944 (div:SI (match_operand:SI 1 "register_operand" "r")
4945 (match_operand:SI 2 "input_operand" "rI")))
4946 (use (match_operand:SI 3 "register_operand" "r"))]
4947 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4948 "wr\t%%g0, %3, %%y\n\tsdiv\t%1, %2, %0"
4949 [(set_attr "type" "multi")
4950 (set_attr "length" "2")])
4952 (define_insn "divdi3"
4953 [(set (match_operand:DI 0 "register_operand" "=r")
4954 (div:DI (match_operand:DI 1 "register_operand" "r")
4955 (match_operand:DI 2 "arith_operand" "rI")))]
4958 [(set_attr "type" "idiv")])
4960 (define_insn "*cmp_sdiv_cc_set"
4962 (compare:CC (div:SI (match_operand:SI 1 "register_operand" "r")
4963 (match_operand:SI 2 "arith_operand" "rI"))
4965 (set (match_operand:SI 0 "register_operand" "=r")
4966 (div:SI (match_dup 1) (match_dup 2)))
4967 (clobber (match_scratch:SI 3 "=&r"))]
4968 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4971 return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tsdivcc\t%1, %2, %0";
4973 return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tnop\n\tnop\n\tnop\n\tsdivcc\t%1, %2, %0";
4975 [(set_attr "type" "multi")
4976 (set (attr "length")
4977 (if_then_else (eq_attr "isa" "v9")
4978 (const_int 3) (const_int 6)))])
4981 (define_expand "udivsi3"
4982 [(set (match_operand:SI 0 "register_operand" "")
4983 (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "")
4984 (match_operand:SI 2 "input_operand" "")))]
4985 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4988 ;; The V8 architecture specifies that there must be 3 instructions between
4989 ;; a Y register write and a use of it for correct results.
4991 (define_insn "udivsi3_sp32"
4992 [(set (match_operand:SI 0 "register_operand" "=r,&r,&r")
4993 (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "r,r,m")
4994 (match_operand:SI 2 "input_operand" "rI,m,r")))]
4995 "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS)
4998 output_asm_insn ("wr\t%%g0, %%g0, %%y", operands);
4999 switch (which_alternative)
5002 return "nop\n\tnop\n\tnop\n\tudiv\t%1, %2, %0";
5004 return "ld\t%2, %0\n\tnop\n\tnop\n\tudiv\t%1, %0, %0";
5006 return "ld\t%1, %0\n\tnop\n\tnop\n\tudiv\t%0, %2, %0";
5009 [(set_attr "type" "multi")
5010 (set_attr "length" "5")])
5012 (define_insn "udivsi3_sp64"
5013 [(set (match_operand:SI 0 "register_operand" "=r")
5014 (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "r")
5015 (match_operand:SI 2 "input_operand" "rI")))]
5016 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5017 "wr\t%%g0, 0, %%y\n\tudiv\t%1, %2, %0"
5018 [(set_attr "type" "multi")
5019 (set_attr "length" "2")])
5021 (define_insn "udivdi3"
5022 [(set (match_operand:DI 0 "register_operand" "=r")
5023 (udiv:DI (match_operand:DI 1 "register_operand" "r")
5024 (match_operand:DI 2 "arith_operand" "rI")))]
5027 [(set_attr "type" "idiv")])
5029 (define_insn "*cmp_udiv_cc_set"
5031 (compare:CC (udiv:SI (match_operand:SI 1 "register_operand" "r")
5032 (match_operand:SI 2 "arith_operand" "rI"))
5034 (set (match_operand:SI 0 "register_operand" "=r")
5035 (udiv:SI (match_dup 1) (match_dup 2)))]
5037 || TARGET_DEPRECATED_V8_INSNS"
5040 return "wr\t%%g0, %%g0, %%y\n\tudivcc\t%1, %2, %0";
5042 return "wr\t%%g0, %%g0, %%y\n\tnop\n\tnop\n\tnop\n\tudivcc\t%1, %2, %0";
5044 [(set_attr "type" "multi")
5045 (set (attr "length")
5046 (if_then_else (eq_attr "isa" "v9")
5047 (const_int 2) (const_int 5)))])
5049 ; sparclet multiply/accumulate insns
5051 (define_insn "*smacsi"
5052 [(set (match_operand:SI 0 "register_operand" "=r")
5053 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "%r")
5054 (match_operand:SI 2 "arith_operand" "rI"))
5055 (match_operand:SI 3 "register_operand" "0")))]
5058 [(set_attr "type" "imul")])
5060 (define_insn "*smacdi"
5061 [(set (match_operand:DI 0 "register_operand" "=r")
5062 (plus:DI (mult:DI (sign_extend:DI
5063 (match_operand:SI 1 "register_operand" "%r"))
5065 (match_operand:SI 2 "register_operand" "r")))
5066 (match_operand:DI 3 "register_operand" "0")))]
5068 "smacd\t%1, %2, %L0"
5069 [(set_attr "type" "imul")])
5071 (define_insn "*umacdi"
5072 [(set (match_operand:DI 0 "register_operand" "=r")
5073 (plus:DI (mult:DI (zero_extend:DI
5074 (match_operand:SI 1 "register_operand" "%r"))
5076 (match_operand:SI 2 "register_operand" "r")))
5077 (match_operand:DI 3 "register_operand" "0")))]
5079 "umacd\t%1, %2, %L0"
5080 [(set_attr "type" "imul")])
5083 ;; Boolean instructions.
5085 ;; We define DImode `and' so with DImode `not' we can get
5086 ;; DImode `andn'. Other combinations are possible.
5088 (define_mode_iterator V64I [DI V2SI V4HI V8QI])
5089 (define_mode_iterator V32I [SI V2HI V4QI])
5091 (define_expand "and<V64I:mode>3"
5092 [(set (match_operand:V64I 0 "register_operand" "")
5093 (and:V64I (match_operand:V64I 1 "arith_double_operand" "")
5094 (match_operand:V64I 2 "arith_double_operand" "")))]
5098 (define_insn "*and<V64I:mode>3_sp32"
5099 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5100 (and:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
5101 (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
5106 [(set_attr "type" "*,fga")
5107 (set_attr "length" "2,*")
5108 (set_attr "fptype" "*,double")])
5110 (define_insn "*and<V64I:mode>3_sp64"
5111 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5112 (and:V64I (match_operand:V64I 1 "arith_operand" "%r,b")
5113 (match_operand:V64I 2 "arith_operand" "rI,b")))]
5118 [(set_attr "type" "*,fga")
5119 (set_attr "fptype" "*,double")])
5121 (define_insn "and<V32I:mode>3"
5122 [(set (match_operand:V32I 0 "register_operand" "=r,d")
5123 (and:V32I (match_operand:V32I 1 "arith_operand" "%r,d")
5124 (match_operand:V32I 2 "arith_operand" "rI,d")))]
5129 [(set_attr "type" "*,fga")
5130 (set_attr "fptype" "*,single")])
5133 [(set (match_operand:SI 0 "register_operand" "")
5134 (and:SI (match_operand:SI 1 "register_operand" "")
5135 (match_operand:SI 2 "const_compl_high_operand" "")))
5136 (clobber (match_operand:SI 3 "register_operand" ""))]
5138 [(set (match_dup 3) (match_dup 4))
5139 (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 1)))]
5141 operands[4] = GEN_INT (~INTVAL (operands[2]));
5144 (define_insn_and_split "*and_not_<V64I:mode>_sp32"
5145 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5146 (and:V64I (not:V64I (match_operand:V64I 1 "register_operand" "%r,b"))
5147 (match_operand:V64I 2 "register_operand" "r,b")))]
5151 fandnot1\t%1, %2, %0"
5152 "&& reload_completed
5153 && ((GET_CODE (operands[0]) == REG
5154 && REGNO (operands[0]) < 32)
5155 || (GET_CODE (operands[0]) == SUBREG
5156 && GET_CODE (SUBREG_REG (operands[0])) == REG
5157 && REGNO (SUBREG_REG (operands[0])) < 32))"
5158 [(set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))
5159 (set (match_dup 6) (and:SI (not:SI (match_dup 7)) (match_dup 8)))]
5160 "operands[3] = gen_highpart (SImode, operands[0]);
5161 operands[4] = gen_highpart (SImode, operands[1]);
5162 operands[5] = gen_highpart (SImode, operands[2]);
5163 operands[6] = gen_lowpart (SImode, operands[0]);
5164 operands[7] = gen_lowpart (SImode, operands[1]);
5165 operands[8] = gen_lowpart (SImode, operands[2]);"
5166 [(set_attr "type" "*,fga")
5167 (set_attr "length" "2,*")
5168 (set_attr "fptype" "*,double")])
5170 (define_insn "*and_not_<V64I:mode>_sp64"
5171 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5172 (and:V64I (not:V64I (match_operand:V64I 1 "register_operand" "%r,b"))
5173 (match_operand:V64I 2 "register_operand" "r,b")))]
5177 fandnot1\t%1, %2, %0"
5178 [(set_attr "type" "*,fga")
5179 (set_attr "fptype" "*,double")])
5181 (define_insn "*and_not_<V32I:mode>"
5182 [(set (match_operand:V32I 0 "register_operand" "=r,d")
5183 (and:V32I (not:V32I (match_operand:V32I 1 "register_operand" "%r,d"))
5184 (match_operand:V32I 2 "register_operand" "r,d")))]
5188 fandnot1s\t%1, %2, %0"
5189 [(set_attr "type" "*,fga")
5190 (set_attr "fptype" "*,single")])
5192 (define_expand "ior<V64I:mode>3"
5193 [(set (match_operand:V64I 0 "register_operand" "")
5194 (ior:V64I (match_operand:V64I 1 "arith_double_operand" "")
5195 (match_operand:V64I 2 "arith_double_operand" "")))]
5199 (define_insn "*ior<V64I:mode>3_sp32"
5200 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5201 (ior:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
5202 (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
5207 [(set_attr "type" "*,fga")
5208 (set_attr "length" "2,*")
5209 (set_attr "fptype" "*,double")])
5211 (define_insn "*ior<V64I:mode>3_sp64"
5212 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5213 (ior:V64I (match_operand:V64I 1 "arith_operand" "%r,b")
5214 (match_operand:V64I 2 "arith_operand" "rI,b")))]
5219 [(set_attr "type" "*,fga")
5220 (set_attr "fptype" "*,double")])
5222 (define_insn "ior<V32I:mode>3"
5223 [(set (match_operand:V32I 0 "register_operand" "=r,d")
5224 (ior:V32I (match_operand:V32I 1 "arith_operand" "%r,d")
5225 (match_operand:V32I 2 "arith_operand" "rI,d")))]
5230 [(set_attr "type" "*,fga")
5231 (set_attr "fptype" "*,single")])
5234 [(set (match_operand:SI 0 "register_operand" "")
5235 (ior:SI (match_operand:SI 1 "register_operand" "")
5236 (match_operand:SI 2 "const_compl_high_operand" "")))
5237 (clobber (match_operand:SI 3 "register_operand" ""))]
5239 [(set (match_dup 3) (match_dup 4))
5240 (set (match_dup 0) (ior:SI (not:SI (match_dup 3)) (match_dup 1)))]
5242 operands[4] = GEN_INT (~INTVAL (operands[2]));
5245 (define_insn_and_split "*or_not_<V64I:mode>_sp32"
5246 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5247 (ior:V64I (not:V64I (match_operand:V64I 1 "register_operand" "r,b"))
5248 (match_operand:V64I 2 "register_operand" "r,b")))]
5252 fornot1\t%1, %2, %0"
5253 "&& reload_completed
5254 && ((GET_CODE (operands[0]) == REG
5255 && REGNO (operands[0]) < 32)
5256 || (GET_CODE (operands[0]) == SUBREG
5257 && GET_CODE (SUBREG_REG (operands[0])) == REG
5258 && REGNO (SUBREG_REG (operands[0])) < 32))"
5259 [(set (match_dup 3) (ior:SI (not:SI (match_dup 4)) (match_dup 5)))
5260 (set (match_dup 6) (ior:SI (not:SI (match_dup 7)) (match_dup 8)))]
5261 "operands[3] = gen_highpart (SImode, operands[0]);
5262 operands[4] = gen_highpart (SImode, operands[1]);
5263 operands[5] = gen_highpart (SImode, operands[2]);
5264 operands[6] = gen_lowpart (SImode, operands[0]);
5265 operands[7] = gen_lowpart (SImode, operands[1]);
5266 operands[8] = gen_lowpart (SImode, operands[2]);"
5267 [(set_attr "type" "*,fga")
5268 (set_attr "length" "2,*")
5269 (set_attr "fptype" "*,double")])
5271 (define_insn "*or_not_<V64I:mode>_sp64"
5272 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5273 (ior:V64I (not:V64I (match_operand:V64I 1 "register_operand" "r,b"))
5274 (match_operand:V64I 2 "register_operand" "r,b")))]
5278 fornot1\t%1, %2, %0"
5279 [(set_attr "type" "*,fga")
5280 (set_attr "fptype" "*,double")])
5282 (define_insn "*or_not_<V32I:mode>"
5283 [(set (match_operand:V32I 0 "register_operand" "=r,d")
5284 (ior:V32I (not:V32I (match_operand:V32I 1 "register_operand" "r,d"))
5285 (match_operand:V32I 2 "register_operand" "r,d")))]
5289 fornot1s\t%1, %2, %0"
5290 [(set_attr "type" "*,fga")
5291 (set_attr "fptype" "*,single")])
5293 (define_expand "xor<V64I:mode>3"
5294 [(set (match_operand:V64I 0 "register_operand" "")
5295 (xor:V64I (match_operand:V64I 1 "arith_double_operand" "")
5296 (match_operand:V64I 2 "arith_double_operand" "")))]
5300 (define_insn "*xor<V64I:mode>3_sp32"
5301 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5302 (xor:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
5303 (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
5308 [(set_attr "type" "*,fga")
5309 (set_attr "length" "2,*")
5310 (set_attr "fptype" "*,double")])
5312 (define_insn "*xor<V64I:mode>3_sp64"
5313 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5314 (xor:V64I (match_operand:V64I 1 "arith_operand" "%rJ,b")
5315 (match_operand:V64I 2 "arith_operand" "rI,b")))]
5320 [(set_attr "type" "*,fga")
5321 (set_attr "fptype" "*,double")])
5323 (define_insn "xor<V32I:mode>3"
5324 [(set (match_operand:V32I 0 "register_operand" "=r,d")
5325 (xor:V32I (match_operand:V32I 1 "arith_operand" "%rJ,d")
5326 (match_operand:V32I 2 "arith_operand" "rI,d")))]
5331 [(set_attr "type" "*,fga")
5332 (set_attr "fptype" "*,single")])
5335 [(set (match_operand:SI 0 "register_operand" "")
5336 (xor:SI (match_operand:SI 1 "register_operand" "")
5337 (match_operand:SI 2 "const_compl_high_operand" "")))
5338 (clobber (match_operand:SI 3 "register_operand" ""))]
5340 [(set (match_dup 3) (match_dup 4))
5341 (set (match_dup 0) (not:SI (xor:SI (match_dup 3) (match_dup 1))))]
5343 operands[4] = GEN_INT (~INTVAL (operands[2]));
5347 [(set (match_operand:SI 0 "register_operand" "")
5348 (not:SI (xor:SI (match_operand:SI 1 "register_operand" "")
5349 (match_operand:SI 2 "const_compl_high_operand" ""))))
5350 (clobber (match_operand:SI 3 "register_operand" ""))]
5352 [(set (match_dup 3) (match_dup 4))
5353 (set (match_dup 0) (xor:SI (match_dup 3) (match_dup 1)))]
5355 operands[4] = GEN_INT (~INTVAL (operands[2]));
5358 ;; Split DImode logical operations requiring two instructions.
5360 [(set (match_operand:V64I 0 "register_operand" "")
5361 (match_operator:V64I 1 "cc_arith_operator" ; AND, IOR, XOR
5362 [(match_operand:V64I 2 "register_operand" "")
5363 (match_operand:V64I 3 "arith_double_operand" "")]))]
5366 && ((GET_CODE (operands[0]) == REG
5367 && REGNO (operands[0]) < 32)
5368 || (GET_CODE (operands[0]) == SUBREG
5369 && GET_CODE (SUBREG_REG (operands[0])) == REG
5370 && REGNO (SUBREG_REG (operands[0])) < 32))"
5371 [(set (match_dup 4) (match_op_dup:SI 1 [(match_dup 6) (match_dup 8)]))
5372 (set (match_dup 5) (match_op_dup:SI 1 [(match_dup 7) (match_dup 9)]))]
5374 operands[4] = gen_highpart (SImode, operands[0]);
5375 operands[5] = gen_lowpart (SImode, operands[0]);
5376 operands[6] = gen_highpart (SImode, operands[2]);
5377 operands[7] = gen_lowpart (SImode, operands[2]);
5378 #if HOST_BITS_PER_WIDE_INT == 32
5379 if (GET_CODE (operands[3]) == CONST_INT && <V64I:MODE>mode == DImode)
5381 if (INTVAL (operands[3]) < 0)
5382 operands[8] = constm1_rtx;
5384 operands[8] = const0_rtx;
5388 operands[8] = gen_highpart_mode (SImode, <V64I:MODE>mode, operands[3]);
5389 operands[9] = gen_lowpart (SImode, operands[3]);
5392 ;; xnor patterns. Note that (a ^ ~b) == (~a ^ b) == ~(a ^ b).
5393 ;; Combine now canonicalizes to the rightmost expression.
5394 (define_insn_and_split "*xor_not_<V64I:mode>_sp32"
5395 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5396 (not:V64I (xor:V64I (match_operand:V64I 1 "register_operand" "r,b")
5397 (match_operand:V64I 2 "register_operand" "r,b"))))]
5402 "&& reload_completed
5403 && ((GET_CODE (operands[0]) == REG
5404 && REGNO (operands[0]) < 32)
5405 || (GET_CODE (operands[0]) == SUBREG
5406 && GET_CODE (SUBREG_REG (operands[0])) == REG
5407 && REGNO (SUBREG_REG (operands[0])) < 32))"
5408 [(set (match_dup 3) (not:SI (xor:SI (match_dup 4) (match_dup 5))))
5409 (set (match_dup 6) (not:SI (xor:SI (match_dup 7) (match_dup 8))))]
5410 "operands[3] = gen_highpart (SImode, operands[0]);
5411 operands[4] = gen_highpart (SImode, operands[1]);
5412 operands[5] = gen_highpart (SImode, operands[2]);
5413 operands[6] = gen_lowpart (SImode, operands[0]);
5414 operands[7] = gen_lowpart (SImode, operands[1]);
5415 operands[8] = gen_lowpart (SImode, operands[2]);"
5416 [(set_attr "type" "*,fga")
5417 (set_attr "length" "2,*")
5418 (set_attr "fptype" "*,double")])
5420 (define_insn "*xor_not_<V64I:mode>_sp64"
5421 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5422 (not:V64I (xor:V64I (match_operand:V64I 1 "register_or_zero_operand" "rJ,b")
5423 (match_operand:V64I 2 "arith_operand" "rI,b"))))]
5428 [(set_attr "type" "*,fga")
5429 (set_attr "fptype" "*,double")])
5431 (define_insn "*xor_not_<V32I:mode>"
5432 [(set (match_operand:V32I 0 "register_operand" "=r,d")
5433 (not:V32I (xor:V32I (match_operand:V32I 1 "register_or_zero_operand" "rJ,d")
5434 (match_operand:V32I 2 "arith_operand" "rI,d"))))]
5439 [(set_attr "type" "*,fga")
5440 (set_attr "fptype" "*,single")])
5442 ;; These correspond to the above in the case where we also (or only)
5443 ;; want to set the condition code.
5445 (define_insn "*cmp_cc_arith_op"
5448 (match_operator:SI 2 "cc_arith_operator"
5449 [(match_operand:SI 0 "arith_operand" "%r")
5450 (match_operand:SI 1 "arith_operand" "rI")])
5453 "%A2cc\t%0, %1, %%g0"
5454 [(set_attr "type" "compare")])
5456 (define_insn "*cmp_ccx_arith_op"
5459 (match_operator:DI 2 "cc_arith_operator"
5460 [(match_operand:DI 0 "arith_operand" "%r")
5461 (match_operand:DI 1 "arith_operand" "rI")])
5464 "%A2cc\t%0, %1, %%g0"
5465 [(set_attr "type" "compare")])
5467 (define_insn "*cmp_cc_arith_op_set"
5470 (match_operator:SI 3 "cc_arith_operator"
5471 [(match_operand:SI 1 "arith_operand" "%r")
5472 (match_operand:SI 2 "arith_operand" "rI")])
5474 (set (match_operand:SI 0 "register_operand" "=r")
5475 (match_operator:SI 4 "cc_arith_operator" [(match_dup 1) (match_dup 2)]))]
5476 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
5478 [(set_attr "type" "compare")])
5480 (define_insn "*cmp_ccx_arith_op_set"
5483 (match_operator:DI 3 "cc_arith_operator"
5484 [(match_operand:DI 1 "arith_operand" "%r")
5485 (match_operand:DI 2 "arith_operand" "rI")])
5487 (set (match_operand:DI 0 "register_operand" "=r")
5488 (match_operator:DI 4 "cc_arith_operator" [(match_dup 1) (match_dup 2)]))]
5489 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
5491 [(set_attr "type" "compare")])
5493 (define_insn "*cmp_cc_xor_not"
5496 (not:SI (xor:SI (match_operand:SI 0 "register_or_zero_operand" "%rJ")
5497 (match_operand:SI 1 "arith_operand" "rI")))
5500 "xnorcc\t%r0, %1, %%g0"
5501 [(set_attr "type" "compare")])
5503 (define_insn "*cmp_ccx_xor_not"
5506 (not:DI (xor:DI (match_operand:DI 0 "register_or_zero_operand" "%rJ")
5507 (match_operand:DI 1 "arith_operand" "rI")))
5510 "xnorcc\t%r0, %1, %%g0"
5511 [(set_attr "type" "compare")])
5513 (define_insn "*cmp_cc_xor_not_set"
5516 (not:SI (xor:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ")
5517 (match_operand:SI 2 "arith_operand" "rI")))
5519 (set (match_operand:SI 0 "register_operand" "=r")
5520 (not:SI (xor:SI (match_dup 1) (match_dup 2))))]
5522 "xnorcc\t%r1, %2, %0"
5523 [(set_attr "type" "compare")])
5525 (define_insn "*cmp_ccx_xor_not_set"
5528 (not:DI (xor:DI (match_operand:DI 1 "register_or_zero_operand" "%rJ")
5529 (match_operand:DI 2 "arith_operand" "rI")))
5531 (set (match_operand:DI 0 "register_operand" "=r")
5532 (not:DI (xor:DI (match_dup 1) (match_dup 2))))]
5534 "xnorcc\t%r1, %2, %0"
5535 [(set_attr "type" "compare")])
5537 (define_insn "*cmp_cc_arith_op_not"
5540 (match_operator:SI 2 "cc_arith_not_operator"
5541 [(not:SI (match_operand:SI 0 "arith_operand" "rI"))
5542 (match_operand:SI 1 "register_or_zero_operand" "rJ")])
5545 "%B2cc\t%r1, %0, %%g0"
5546 [(set_attr "type" "compare")])
5548 (define_insn "*cmp_ccx_arith_op_not"
5551 (match_operator:DI 2 "cc_arith_not_operator"
5552 [(not:DI (match_operand:DI 0 "arith_operand" "rI"))
5553 (match_operand:DI 1 "register_or_zero_operand" "rJ")])
5556 "%B2cc\t%r1, %0, %%g0"
5557 [(set_attr "type" "compare")])
5559 (define_insn "*cmp_cc_arith_op_not_set"
5562 (match_operator:SI 3 "cc_arith_not_operator"
5563 [(not:SI (match_operand:SI 1 "arith_operand" "rI"))
5564 (match_operand:SI 2 "register_or_zero_operand" "rJ")])
5566 (set (match_operand:SI 0 "register_operand" "=r")
5567 (match_operator:SI 4 "cc_arith_not_operator"
5568 [(not:SI (match_dup 1)) (match_dup 2)]))]
5569 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
5570 "%B3cc\t%r2, %1, %0"
5571 [(set_attr "type" "compare")])
5573 (define_insn "*cmp_ccx_arith_op_not_set"
5576 (match_operator:DI 3 "cc_arith_not_operator"
5577 [(not:DI (match_operand:DI 1 "arith_operand" "rI"))
5578 (match_operand:DI 2 "register_or_zero_operand" "rJ")])
5580 (set (match_operand:DI 0 "register_operand" "=r")
5581 (match_operator:DI 4 "cc_arith_not_operator"
5582 [(not:DI (match_dup 1)) (match_dup 2)]))]
5583 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
5584 "%B3cc\t%r2, %1, %0"
5585 [(set_attr "type" "compare")])
5587 ;; We cannot use the "neg" pseudo insn because the Sun assembler
5588 ;; does not know how to make it work for constants.
5590 (define_expand "negdi2"
5591 [(set (match_operand:DI 0 "register_operand" "=r")
5592 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
5595 if (! TARGET_ARCH64)
5597 emit_insn (gen_rtx_PARALLEL
5600 gen_rtx_SET (VOIDmode, operand0,
5601 gen_rtx_NEG (DImode, operand1)),
5602 gen_rtx_CLOBBER (VOIDmode,
5603 gen_rtx_REG (CCmode,
5609 (define_insn_and_split "*negdi2_sp32"
5610 [(set (match_operand:DI 0 "register_operand" "=r")
5611 (neg:DI (match_operand:DI 1 "register_operand" "r")))
5612 (clobber (reg:CC 100))]
5615 "&& reload_completed"
5616 [(parallel [(set (reg:CC_NOOV 100)
5617 (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 5))
5619 (set (match_dup 4) (minus:SI (const_int 0) (match_dup 5)))])
5620 (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
5621 (ltu:SI (reg:CC 100) (const_int 0))))]
5622 "operands[2] = gen_highpart (SImode, operands[0]);
5623 operands[3] = gen_highpart (SImode, operands[1]);
5624 operands[4] = gen_lowpart (SImode, operands[0]);
5625 operands[5] = gen_lowpart (SImode, operands[1]);"
5626 [(set_attr "length" "2")])
5628 (define_insn "*negdi2_sp64"
5629 [(set (match_operand:DI 0 "register_operand" "=r")
5630 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
5632 "sub\t%%g0, %1, %0")
5634 (define_insn "negsi2"
5635 [(set (match_operand:SI 0 "register_operand" "=r")
5636 (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
5638 "sub\t%%g0, %1, %0")
5640 (define_insn "*cmp_cc_neg"
5641 [(set (reg:CC_NOOV 100)
5642 (compare:CC_NOOV (neg:SI (match_operand:SI 0 "arith_operand" "rI"))
5645 "subcc\t%%g0, %0, %%g0"
5646 [(set_attr "type" "compare")])
5648 (define_insn "*cmp_ccx_neg"
5649 [(set (reg:CCX_NOOV 100)
5650 (compare:CCX_NOOV (neg:DI (match_operand:DI 0 "arith_operand" "rI"))
5653 "subcc\t%%g0, %0, %%g0"
5654 [(set_attr "type" "compare")])
5656 (define_insn "*cmp_cc_set_neg"
5657 [(set (reg:CC_NOOV 100)
5658 (compare:CC_NOOV (neg:SI (match_operand:SI 1 "arith_operand" "rI"))
5660 (set (match_operand:SI 0 "register_operand" "=r")
5661 (neg:SI (match_dup 1)))]
5663 "subcc\t%%g0, %1, %0"
5664 [(set_attr "type" "compare")])
5666 (define_insn "*cmp_ccx_set_neg"
5667 [(set (reg:CCX_NOOV 100)
5668 (compare:CCX_NOOV (neg:DI (match_operand:DI 1 "arith_operand" "rI"))
5670 (set (match_operand:DI 0 "register_operand" "=r")
5671 (neg:DI (match_dup 1)))]
5673 "subcc\t%%g0, %1, %0"
5674 [(set_attr "type" "compare")])
5676 ;; We cannot use the "not" pseudo insn because the Sun assembler
5677 ;; does not know how to make it work for constants.
5678 (define_expand "one_cmpl<V64I:mode>2"
5679 [(set (match_operand:V64I 0 "register_operand" "")
5680 (not:V64I (match_operand:V64I 1 "register_operand" "")))]
5684 (define_insn_and_split "*one_cmpl<V64I:mode>2_sp32"
5685 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5686 (not:V64I (match_operand:V64I 1 "register_operand" "r,b")))]
5691 "&& reload_completed
5692 && ((GET_CODE (operands[0]) == REG
5693 && REGNO (operands[0]) < 32)
5694 || (GET_CODE (operands[0]) == SUBREG
5695 && GET_CODE (SUBREG_REG (operands[0])) == REG
5696 && REGNO (SUBREG_REG (operands[0])) < 32))"
5697 [(set (match_dup 2) (not:SI (xor:SI (match_dup 3) (const_int 0))))
5698 (set (match_dup 4) (not:SI (xor:SI (match_dup 5) (const_int 0))))]
5699 "operands[2] = gen_highpart (SImode, operands[0]);
5700 operands[3] = gen_highpart (SImode, operands[1]);
5701 operands[4] = gen_lowpart (SImode, operands[0]);
5702 operands[5] = gen_lowpart (SImode, operands[1]);"
5703 [(set_attr "type" "*,fga")
5704 (set_attr "length" "2,*")
5705 (set_attr "fptype" "*,double")])
5707 (define_insn "*one_cmpl<V64I:mode>2_sp64"
5708 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5709 (not:V64I (match_operand:V64I 1 "arith_operand" "rI,b")))]
5714 [(set_attr "type" "*,fga")
5715 (set_attr "fptype" "*,double")])
5717 (define_insn "one_cmpl<V32I:mode>2"
5718 [(set (match_operand:V32I 0 "register_operand" "=r,d")
5719 (not:V32I (match_operand:V32I 1 "arith_operand" "rI,d")))]
5724 [(set_attr "type" "*,fga")
5725 (set_attr "fptype" "*,single")])
5727 (define_insn "*cmp_cc_not"
5729 (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI"))
5732 "xnorcc\t%%g0, %0, %%g0"
5733 [(set_attr "type" "compare")])
5735 (define_insn "*cmp_ccx_not"
5737 (compare:CCX (not:DI (match_operand:DI 0 "arith_operand" "rI"))
5740 "xnorcc\t%%g0, %0, %%g0"
5741 [(set_attr "type" "compare")])
5743 (define_insn "*cmp_cc_set_not"
5745 (compare:CC (not:SI (match_operand:SI 1 "arith_operand" "rI"))
5747 (set (match_operand:SI 0 "register_operand" "=r")
5748 (not:SI (match_dup 1)))]
5750 "xnorcc\t%%g0, %1, %0"
5751 [(set_attr "type" "compare")])
5753 (define_insn "*cmp_ccx_set_not"
5755 (compare:CCX (not:DI (match_operand:DI 1 "arith_operand" "rI"))
5757 (set (match_operand:DI 0 "register_operand" "=r")
5758 (not:DI (match_dup 1)))]
5760 "xnorcc\t%%g0, %1, %0"
5761 [(set_attr "type" "compare")])
5763 (define_insn "*cmp_cc_set"
5764 [(set (match_operand:SI 0 "register_operand" "=r")
5765 (match_operand:SI 1 "register_operand" "r"))
5767 (compare:CC (match_dup 1)
5771 [(set_attr "type" "compare")])
5773 (define_insn "*cmp_ccx_set64"
5774 [(set (match_operand:DI 0 "register_operand" "=r")
5775 (match_operand:DI 1 "register_operand" "r"))
5777 (compare:CCX (match_dup 1)
5781 [(set_attr "type" "compare")])
5784 ;; Floating point arithmetic instructions.
5786 (define_expand "addtf3"
5787 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5788 (plus:TF (match_operand:TF 1 "general_operand" "")
5789 (match_operand:TF 2 "general_operand" "")))]
5790 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5791 "emit_tfmode_binop (PLUS, operands); DONE;")
5793 (define_insn "*addtf3_hq"
5794 [(set (match_operand:TF 0 "register_operand" "=e")
5795 (plus:TF (match_operand:TF 1 "register_operand" "e")
5796 (match_operand:TF 2 "register_operand" "e")))]
5797 "TARGET_FPU && TARGET_HARD_QUAD"
5799 [(set_attr "type" "fp")])
5801 (define_insn "adddf3"
5802 [(set (match_operand:DF 0 "register_operand" "=e")
5803 (plus:DF (match_operand:DF 1 "register_operand" "e")
5804 (match_operand:DF 2 "register_operand" "e")))]
5807 [(set_attr "type" "fp")
5808 (set_attr "fptype" "double")])
5810 (define_insn "addsf3"
5811 [(set (match_operand:SF 0 "register_operand" "=f")
5812 (plus:SF (match_operand:SF 1 "register_operand" "f")
5813 (match_operand:SF 2 "register_operand" "f")))]
5816 [(set_attr "type" "fp")])
5818 (define_expand "subtf3"
5819 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5820 (minus:TF (match_operand:TF 1 "general_operand" "")
5821 (match_operand:TF 2 "general_operand" "")))]
5822 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5823 "emit_tfmode_binop (MINUS, operands); DONE;")
5825 (define_insn "*subtf3_hq"
5826 [(set (match_operand:TF 0 "register_operand" "=e")
5827 (minus:TF (match_operand:TF 1 "register_operand" "e")
5828 (match_operand:TF 2 "register_operand" "e")))]
5829 "TARGET_FPU && TARGET_HARD_QUAD"
5831 [(set_attr "type" "fp")])
5833 (define_insn "subdf3"
5834 [(set (match_operand:DF 0 "register_operand" "=e")
5835 (minus:DF (match_operand:DF 1 "register_operand" "e")
5836 (match_operand:DF 2 "register_operand" "e")))]
5839 [(set_attr "type" "fp")
5840 (set_attr "fptype" "double")])
5842 (define_insn "subsf3"
5843 [(set (match_operand:SF 0 "register_operand" "=f")
5844 (minus:SF (match_operand:SF 1 "register_operand" "f")
5845 (match_operand:SF 2 "register_operand" "f")))]
5848 [(set_attr "type" "fp")])
5850 (define_expand "multf3"
5851 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5852 (mult:TF (match_operand:TF 1 "general_operand" "")
5853 (match_operand:TF 2 "general_operand" "")))]
5854 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5855 "emit_tfmode_binop (MULT, operands); DONE;")
5857 (define_insn "*multf3_hq"
5858 [(set (match_operand:TF 0 "register_operand" "=e")
5859 (mult:TF (match_operand:TF 1 "register_operand" "e")
5860 (match_operand:TF 2 "register_operand" "e")))]
5861 "TARGET_FPU && TARGET_HARD_QUAD"
5863 [(set_attr "type" "fpmul")])
5865 (define_insn "muldf3"
5866 [(set (match_operand:DF 0 "register_operand" "=e")
5867 (mult:DF (match_operand:DF 1 "register_operand" "e")
5868 (match_operand:DF 2 "register_operand" "e")))]
5871 [(set_attr "type" "fpmul")
5872 (set_attr "fptype" "double")])
5874 (define_insn "mulsf3"
5875 [(set (match_operand:SF 0 "register_operand" "=f")
5876 (mult:SF (match_operand:SF 1 "register_operand" "f")
5877 (match_operand:SF 2 "register_operand" "f")))]
5880 [(set_attr "type" "fpmul")])
5882 (define_insn "*muldf3_extend"
5883 [(set (match_operand:DF 0 "register_operand" "=e")
5884 (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "f"))
5885 (float_extend:DF (match_operand:SF 2 "register_operand" "f"))))]
5886 "(TARGET_V8 || TARGET_V9) && TARGET_FPU"
5887 "fsmuld\t%1, %2, %0"
5888 [(set_attr "type" "fpmul")
5889 (set_attr "fptype" "double")])
5891 (define_insn "*multf3_extend"
5892 [(set (match_operand:TF 0 "register_operand" "=e")
5893 (mult:TF (float_extend:TF (match_operand:DF 1 "register_operand" "e"))
5894 (float_extend:TF (match_operand:DF 2 "register_operand" "e"))))]
5895 "(TARGET_V8 || TARGET_V9) && TARGET_FPU && TARGET_HARD_QUAD"
5896 "fdmulq\t%1, %2, %0"
5897 [(set_attr "type" "fpmul")])
5899 (define_expand "divtf3"
5900 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5901 (div:TF (match_operand:TF 1 "general_operand" "")
5902 (match_operand:TF 2 "general_operand" "")))]
5903 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5904 "emit_tfmode_binop (DIV, operands); DONE;")
5906 ;; don't have timing for quad-prec. divide.
5907 (define_insn "*divtf3_hq"
5908 [(set (match_operand:TF 0 "register_operand" "=e")
5909 (div:TF (match_operand:TF 1 "register_operand" "e")
5910 (match_operand:TF 2 "register_operand" "e")))]
5911 "TARGET_FPU && TARGET_HARD_QUAD"
5913 [(set_attr "type" "fpdivd")])
5915 (define_insn "divdf3"
5916 [(set (match_operand:DF 0 "register_operand" "=e")
5917 (div:DF (match_operand:DF 1 "register_operand" "e")
5918 (match_operand:DF 2 "register_operand" "e")))]
5921 [(set_attr "type" "fpdivd")
5922 (set_attr "fptype" "double")])
5924 (define_insn "divsf3"
5925 [(set (match_operand:SF 0 "register_operand" "=f")
5926 (div:SF (match_operand:SF 1 "register_operand" "f")
5927 (match_operand:SF 2 "register_operand" "f")))]
5930 [(set_attr "type" "fpdivs")])
5932 (define_expand "negtf2"
5933 [(set (match_operand:TF 0 "register_operand" "=e,e")
5934 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
5938 (define_insn_and_split "*negtf2_notv9"
5939 [(set (match_operand:TF 0 "register_operand" "=e,e")
5940 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
5941 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
5947 "&& reload_completed
5948 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5949 [(set (match_dup 2) (neg:SF (match_dup 3)))
5950 (set (match_dup 4) (match_dup 5))
5951 (set (match_dup 6) (match_dup 7))]
5952 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
5953 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
5954 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
5955 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
5956 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
5957 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
5958 [(set_attr "type" "fpmove,*")
5959 (set_attr "length" "*,2")])
5961 (define_insn_and_split "*negtf2_v9"
5962 [(set (match_operand:TF 0 "register_operand" "=e,e")
5963 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
5964 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
5965 "TARGET_FPU && TARGET_V9"
5969 "&& reload_completed
5970 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5971 [(set (match_dup 2) (neg:DF (match_dup 3)))
5972 (set (match_dup 4) (match_dup 5))]
5973 "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
5974 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
5975 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
5976 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
5977 [(set_attr "type" "fpmove,*")
5978 (set_attr "length" "*,2")
5979 (set_attr "fptype" "double")])
5981 (define_expand "negdf2"
5982 [(set (match_operand:DF 0 "register_operand" "")
5983 (neg:DF (match_operand:DF 1 "register_operand" "")))]
5987 (define_insn_and_split "*negdf2_notv9"
5988 [(set (match_operand:DF 0 "register_operand" "=e,e")
5989 (neg:DF (match_operand:DF 1 "register_operand" "0,e")))]
5990 "TARGET_FPU && ! TARGET_V9"
5994 "&& reload_completed
5995 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5996 [(set (match_dup 2) (neg:SF (match_dup 3)))
5997 (set (match_dup 4) (match_dup 5))]
5998 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
5999 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6000 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6001 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);"
6002 [(set_attr "type" "fpmove,*")
6003 (set_attr "length" "*,2")])
6005 (define_insn "*negdf2_v9"
6006 [(set (match_operand:DF 0 "register_operand" "=e")
6007 (neg:DF (match_operand:DF 1 "register_operand" "e")))]
6008 "TARGET_FPU && TARGET_V9"
6010 [(set_attr "type" "fpmove")
6011 (set_attr "fptype" "double")])
6013 (define_insn "negsf2"
6014 [(set (match_operand:SF 0 "register_operand" "=f")
6015 (neg:SF (match_operand:SF 1 "register_operand" "f")))]
6018 [(set_attr "type" "fpmove")])
6020 (define_expand "abstf2"
6021 [(set (match_operand:TF 0 "register_operand" "")
6022 (abs:TF (match_operand:TF 1 "register_operand" "")))]
6026 (define_insn_and_split "*abstf2_notv9"
6027 [(set (match_operand:TF 0 "register_operand" "=e,e")
6028 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6029 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
6030 "TARGET_FPU && ! TARGET_V9"
6034 "&& reload_completed
6035 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6036 [(set (match_dup 2) (abs:SF (match_dup 3)))
6037 (set (match_dup 4) (match_dup 5))
6038 (set (match_dup 6) (match_dup 7))]
6039 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6040 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6041 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6042 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
6043 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6044 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6045 [(set_attr "type" "fpmove,*")
6046 (set_attr "length" "*,2")])
6048 (define_insn "*abstf2_hq_v9"
6049 [(set (match_operand:TF 0 "register_operand" "=e,e")
6050 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6051 "TARGET_FPU && TARGET_V9 && TARGET_HARD_QUAD"
6055 [(set_attr "type" "fpmove")
6056 (set_attr "fptype" "double,*")])
6058 (define_insn_and_split "*abstf2_v9"
6059 [(set (match_operand:TF 0 "register_operand" "=e,e")
6060 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6061 "TARGET_FPU && TARGET_V9 && !TARGET_HARD_QUAD"
6065 "&& reload_completed
6066 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6067 [(set (match_dup 2) (abs:DF (match_dup 3)))
6068 (set (match_dup 4) (match_dup 5))]
6069 "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
6070 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
6071 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6072 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6073 [(set_attr "type" "fpmove,*")
6074 (set_attr "length" "*,2")
6075 (set_attr "fptype" "double,*")])
6077 (define_expand "absdf2"
6078 [(set (match_operand:DF 0 "register_operand" "")
6079 (abs:DF (match_operand:DF 1 "register_operand" "")))]
6083 (define_insn_and_split "*absdf2_notv9"
6084 [(set (match_operand:DF 0 "register_operand" "=e,e")
6085 (abs:DF (match_operand:DF 1 "register_operand" "0,e")))]
6086 "TARGET_FPU && ! TARGET_V9"
6090 "&& reload_completed
6091 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6092 [(set (match_dup 2) (abs:SF (match_dup 3)))
6093 (set (match_dup 4) (match_dup 5))]
6094 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6095 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6096 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6097 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);"
6098 [(set_attr "type" "fpmove,*")
6099 (set_attr "length" "*,2")])
6101 (define_insn "*absdf2_v9"
6102 [(set (match_operand:DF 0 "register_operand" "=e")
6103 (abs:DF (match_operand:DF 1 "register_operand" "e")))]
6104 "TARGET_FPU && TARGET_V9"
6106 [(set_attr "type" "fpmove")
6107 (set_attr "fptype" "double")])
6109 (define_insn "abssf2"
6110 [(set (match_operand:SF 0 "register_operand" "=f")
6111 (abs:SF (match_operand:SF 1 "register_operand" "f")))]
6114 [(set_attr "type" "fpmove")])
6116 (define_expand "sqrttf2"
6117 [(set (match_operand:TF 0 "nonimmediate_operand" "")
6118 (sqrt:TF (match_operand:TF 1 "general_operand" "")))]
6119 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6120 "emit_tfmode_unop (SQRT, operands); DONE;")
6122 (define_insn "*sqrttf2_hq"
6123 [(set (match_operand:TF 0 "register_operand" "=e")
6124 (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
6125 "TARGET_FPU && TARGET_HARD_QUAD"
6127 [(set_attr "type" "fpsqrtd")])
6129 (define_insn "sqrtdf2"
6130 [(set (match_operand:DF 0 "register_operand" "=e")
6131 (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
6134 [(set_attr "type" "fpsqrtd")
6135 (set_attr "fptype" "double")])
6137 (define_insn "sqrtsf2"
6138 [(set (match_operand:SF 0 "register_operand" "=f")
6139 (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
6142 [(set_attr "type" "fpsqrts")])
6145 ;; Arithmetic shift instructions.
6147 (define_insn "ashlsi3"
6148 [(set (match_operand:SI 0 "register_operand" "=r")
6149 (ashift:SI (match_operand:SI 1 "register_operand" "r")
6150 (match_operand:SI 2 "arith_operand" "rI")))]
6153 if (GET_CODE (operands[2]) == CONST_INT)
6154 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6155 return "sll\t%1, %2, %0";
6158 (if_then_else (match_operand 2 "const_one_operand" "")
6159 (const_string "ialu") (const_string "shift")))])
6161 (define_expand "ashldi3"
6162 [(set (match_operand:DI 0 "register_operand" "=r")
6163 (ashift:DI (match_operand:DI 1 "register_operand" "r")
6164 (match_operand:SI 2 "arith_operand" "rI")))]
6165 "TARGET_ARCH64 || TARGET_V8PLUS"
6167 if (! TARGET_ARCH64)
6169 if (GET_CODE (operands[2]) == CONST_INT)
6171 emit_insn (gen_ashldi3_v8plus (operands[0], operands[1], operands[2]));
6176 (define_insn "*ashldi3_sp64"
6177 [(set (match_operand:DI 0 "register_operand" "=r")
6178 (ashift:DI (match_operand:DI 1 "register_operand" "r")
6179 (match_operand:SI 2 "arith_operand" "rI")))]
6182 if (GET_CODE (operands[2]) == CONST_INT)
6183 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
6184 return "sllx\t%1, %2, %0";
6187 (if_then_else (match_operand 2 "const_one_operand" "")
6188 (const_string "ialu") (const_string "shift")))])
6191 (define_insn "ashldi3_v8plus"
6192 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
6193 (ashift:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
6194 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
6195 (clobber (match_scratch:SI 3 "=X,X,&h"))]
6197 "* return output_v8plus_shift (operands, insn, \"sllx\");"
6198 [(set_attr "type" "multi")
6199 (set_attr "length" "5,5,6")])
6201 ;; Optimize (1LL<<x)-1
6202 ;; XXX this also needs to be fixed to handle equal subregs
6203 ;; XXX first before we could re-enable it.
6205 ; [(set (match_operand:DI 0 "register_operand" "=h")
6206 ; (plus:DI (ashift:DI (const_int 1)
6207 ; (match_operand:SI 1 "arith_operand" "rI"))
6209 ; "0 && TARGET_V8PLUS"
6211 ; if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == REGNO (operands[0]))
6212 ; return "mov\t1, %L0\;sllx\t%L0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
6213 ; return "mov\t1, %H0\;sllx\t%H0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
6215 ; [(set_attr "type" "multi")
6216 ; (set_attr "length" "4")])
6218 (define_insn "*cmp_cc_ashift_1"
6219 [(set (reg:CC_NOOV 100)
6220 (compare:CC_NOOV (ashift:SI (match_operand:SI 0 "register_operand" "r")
6224 "addcc\t%0, %0, %%g0"
6225 [(set_attr "type" "compare")])
6227 (define_insn "*cmp_cc_set_ashift_1"
6228 [(set (reg:CC_NOOV 100)
6229 (compare:CC_NOOV (ashift:SI (match_operand:SI 1 "register_operand" "r")
6232 (set (match_operand:SI 0 "register_operand" "=r")
6233 (ashift:SI (match_dup 1) (const_int 1)))]
6236 [(set_attr "type" "compare")])
6238 (define_insn "ashrsi3"
6239 [(set (match_operand:SI 0 "register_operand" "=r")
6240 (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
6241 (match_operand:SI 2 "arith_operand" "rI")))]
6244 if (GET_CODE (operands[2]) == CONST_INT)
6245 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6246 return "sra\t%1, %2, %0";
6248 [(set_attr "type" "shift")])
6250 (define_insn "*ashrsi3_extend"
6251 [(set (match_operand:DI 0 "register_operand" "=r")
6252 (sign_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
6253 (match_operand:SI 2 "arith_operand" "r"))))]
6256 [(set_attr "type" "shift")])
6258 ;; This handles the case as above, but with constant shift instead of
6259 ;; register. Combiner "simplifies" it for us a little bit though.
6260 (define_insn "*ashrsi3_extend2"
6261 [(set (match_operand:DI 0 "register_operand" "=r")
6262 (ashiftrt:DI (ashift:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
6264 (match_operand:SI 2 "small_int_operand" "I")))]
6265 "TARGET_ARCH64 && INTVAL (operands[2]) >= 32 && INTVAL (operands[2]) < 64"
6267 operands[2] = GEN_INT (INTVAL (operands[2]) - 32);
6268 return "sra\t%1, %2, %0";
6270 [(set_attr "type" "shift")])
6272 (define_expand "ashrdi3"
6273 [(set (match_operand:DI 0 "register_operand" "=r")
6274 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
6275 (match_operand:SI 2 "arith_operand" "rI")))]
6276 "TARGET_ARCH64 || TARGET_V8PLUS"
6278 if (! TARGET_ARCH64)
6280 if (GET_CODE (operands[2]) == CONST_INT)
6281 FAIL; /* prefer generic code in this case */
6282 emit_insn (gen_ashrdi3_v8plus (operands[0], operands[1], operands[2]));
6287 (define_insn "*ashrdi3_sp64"
6288 [(set (match_operand:DI 0 "register_operand" "=r")
6289 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
6290 (match_operand:SI 2 "arith_operand" "rI")))]
6294 if (GET_CODE (operands[2]) == CONST_INT)
6295 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
6296 return "srax\t%1, %2, %0";
6298 [(set_attr "type" "shift")])
6301 (define_insn "ashrdi3_v8plus"
6302 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
6303 (ashiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
6304 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
6305 (clobber (match_scratch:SI 3 "=X,X,&h"))]
6307 "* return output_v8plus_shift (operands, insn, \"srax\");"
6308 [(set_attr "type" "multi")
6309 (set_attr "length" "5,5,6")])
6311 (define_insn "lshrsi3"
6312 [(set (match_operand:SI 0 "register_operand" "=r")
6313 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
6314 (match_operand:SI 2 "arith_operand" "rI")))]
6317 if (GET_CODE (operands[2]) == CONST_INT)
6318 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6319 return "srl\t%1, %2, %0";
6321 [(set_attr "type" "shift")])
6323 ;; This handles the case where
6324 ;; (zero_extend:DI (lshiftrt:SI (match_operand:SI) (match_operand:SI))),
6325 ;; but combiner "simplifies" it for us.
6326 (define_insn "*lshrsi3_extend"
6327 [(set (match_operand:DI 0 "register_operand" "=r")
6328 (and:DI (subreg:DI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
6329 (match_operand:SI 2 "arith_operand" "r")) 0)
6330 (match_operand 3 "const_int_operand" "")))]
6331 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) == 0xffffffff"
6333 [(set_attr "type" "shift")])
6335 ;; This handles the case where
6336 ;; (lshiftrt:DI (zero_extend:DI (match_operand:SI)) (const_int >=0 < 32))
6337 ;; but combiner "simplifies" it for us.
6338 (define_insn "*lshrsi3_extend2"
6339 [(set (match_operand:DI 0 "register_operand" "=r")
6340 (zero_extract:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
6341 (match_operand 2 "small_int_operand" "I")
6343 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
6345 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
6346 return "srl\t%1, %2, %0";
6348 [(set_attr "type" "shift")])
6350 (define_expand "lshrdi3"
6351 [(set (match_operand:DI 0 "register_operand" "=r")
6352 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6353 (match_operand:SI 2 "arith_operand" "rI")))]
6354 "TARGET_ARCH64 || TARGET_V8PLUS"
6356 if (! TARGET_ARCH64)
6358 if (GET_CODE (operands[2]) == CONST_INT)
6360 emit_insn (gen_lshrdi3_v8plus (operands[0], operands[1], operands[2]));
6365 (define_insn "*lshrdi3_sp64"
6366 [(set (match_operand:DI 0 "register_operand" "=r")
6367 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6368 (match_operand:SI 2 "arith_operand" "rI")))]
6371 if (GET_CODE (operands[2]) == CONST_INT)
6372 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
6373 return "srlx\t%1, %2, %0";
6375 [(set_attr "type" "shift")])
6378 (define_insn "lshrdi3_v8plus"
6379 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
6380 (lshiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
6381 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
6382 (clobber (match_scratch:SI 3 "=X,X,&h"))]
6384 "* return output_v8plus_shift (operands, insn, \"srlx\");"
6385 [(set_attr "type" "multi")
6386 (set_attr "length" "5,5,6")])
6389 [(set (match_operand:SI 0 "register_operand" "=r")
6390 (ashiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6392 (match_operand:SI 2 "small_int_operand" "I")))]
6393 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
6395 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
6396 return "srax\t%1, %2, %0";
6398 [(set_attr "type" "shift")])
6401 [(set (match_operand:SI 0 "register_operand" "=r")
6402 (lshiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
6404 (match_operand:SI 2 "small_int_operand" "I")))]
6405 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
6407 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
6408 return "srlx\t%1, %2, %0";
6410 [(set_attr "type" "shift")])
6413 [(set (match_operand:SI 0 "register_operand" "=r")
6414 (ashiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
6415 (match_operand:SI 2 "small_int_operand" "I")) 4)
6416 (match_operand:SI 3 "small_int_operand" "I")))]
6418 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
6419 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
6420 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
6422 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
6424 return "srax\t%1, %2, %0";
6426 [(set_attr "type" "shift")])
6429 [(set (match_operand:SI 0 "register_operand" "=r")
6430 (lshiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6431 (match_operand:SI 2 "small_int_operand" "I")) 4)
6432 (match_operand:SI 3 "small_int_operand" "I")))]
6434 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
6435 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
6436 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
6438 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
6440 return "srlx\t%1, %2, %0";
6442 [(set_attr "type" "shift")])
6445 ;; Unconditional and other jump instructions.
6448 [(set (pc) (label_ref (match_operand 0 "" "")))]
6450 "* return output_ubranch (operands[0], 0, insn);"
6451 [(set_attr "type" "uncond_branch")])
6453 (define_expand "tablejump"
6454 [(parallel [(set (pc) (match_operand 0 "register_operand" "r"))
6455 (use (label_ref (match_operand 1 "" "")))])]
6458 gcc_assert (GET_MODE (operands[0]) == CASE_VECTOR_MODE);
6460 /* In pic mode, our address differences are against the base of the
6461 table. Add that base value back in; CSE ought to be able to combine
6462 the two address loads. */
6466 tmp = gen_rtx_LABEL_REF (Pmode, operands[1]);
6468 if (CASE_VECTOR_MODE != Pmode)
6469 tmp2 = gen_rtx_SIGN_EXTEND (Pmode, tmp2);
6470 tmp = gen_rtx_PLUS (Pmode, tmp2, tmp);
6471 operands[0] = memory_address (Pmode, tmp);
6475 (define_insn "*tablejump_sp32"
6476 [(set (pc) (match_operand:SI 0 "address_operand" "p"))
6477 (use (label_ref (match_operand 1 "" "")))]
6480 [(set_attr "type" "uncond_branch")])
6482 (define_insn "*tablejump_sp64"
6483 [(set (pc) (match_operand:DI 0 "address_operand" "p"))
6484 (use (label_ref (match_operand 1 "" "")))]
6487 [(set_attr "type" "uncond_branch")])
6490 ;; Jump to subroutine instructions.
6492 (define_expand "call"
6493 ;; Note that this expression is not used for generating RTL.
6494 ;; All the RTL is generated explicitly below.
6495 [(call (match_operand 0 "call_operand" "")
6496 (match_operand 3 "" "i"))]
6497 ;; operands[2] is next_arg_register
6498 ;; operands[3] is struct_value_size_rtx.
6503 gcc_assert (MEM_P (operands[0]) && GET_MODE (operands[0]) == FUNCTION_MODE);
6505 gcc_assert (GET_CODE (operands[3]) == CONST_INT);
6507 if (GET_CODE (XEXP (operands[0], 0)) == LABEL_REF)
6509 /* This is really a PIC sequence. We want to represent
6510 it as a funny jump so its delay slots can be filled.
6512 ??? But if this really *is* a CALL, will not it clobber the
6513 call-clobbered registers? We lose this if it is a JUMP_INSN.
6514 Why cannot we have delay slots filled if it were a CALL? */
6516 /* We accept negative sizes for untyped calls. */
6517 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
6522 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
6524 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
6530 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
6531 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
6535 fn_rtx = operands[0];
6537 /* We accept negative sizes for untyped calls. */
6538 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
6539 sparc_emit_call_insn
6542 gen_rtvec (3, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx),
6544 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))),
6547 sparc_emit_call_insn
6550 gen_rtvec (2, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx),
6551 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))),
6559 ;; We can't use the same pattern for these two insns, because then registers
6560 ;; in the address may not be properly reloaded.
6562 (define_insn "*call_address_sp32"
6563 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6564 (match_operand 1 "" ""))
6565 (clobber (reg:SI 15))]
6566 ;;- Do not use operand 1 for most machines.
6569 [(set_attr "type" "call")])
6571 (define_insn "*call_symbolic_sp32"
6572 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6573 (match_operand 1 "" ""))
6574 (clobber (reg:SI 15))]
6575 ;;- Do not use operand 1 for most machines.
6578 [(set_attr "type" "call")])
6580 (define_insn "*call_address_sp64"
6581 [(call (mem:DI (match_operand:DI 0 "address_operand" "p"))
6582 (match_operand 1 "" ""))
6583 (clobber (reg:DI 15))]
6584 ;;- Do not use operand 1 for most machines.
6587 [(set_attr "type" "call")])
6589 (define_insn "*call_symbolic_sp64"
6590 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
6591 (match_operand 1 "" ""))
6592 (clobber (reg:DI 15))]
6593 ;;- Do not use operand 1 for most machines.
6596 [(set_attr "type" "call")])
6598 ;; This is a call that wants a structure value.
6599 ;; There is no such critter for v9 (??? we may need one anyway).
6600 (define_insn "*call_address_struct_value_sp32"
6601 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6602 (match_operand 1 "" ""))
6603 (match_operand 2 "immediate_operand" "")
6604 (clobber (reg:SI 15))]
6605 ;;- Do not use operand 1 for most machines.
6606 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
6608 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xfff);
6609 return "call\t%a0, %1\n\t nop\n\tunimp\t%2";
6611 [(set_attr "type" "call_no_delay_slot")
6612 (set_attr "length" "3")])
6614 ;; This is a call that wants a structure value.
6615 ;; There is no such critter for v9 (??? we may need one anyway).
6616 (define_insn "*call_symbolic_struct_value_sp32"
6617 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6618 (match_operand 1 "" ""))
6619 (match_operand 2 "immediate_operand" "")
6620 (clobber (reg:SI 15))]
6621 ;;- Do not use operand 1 for most machines.
6622 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
6624 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xfff);
6625 return "call\t%a0, %1\n\t nop\n\tunimp\t%2";
6627 [(set_attr "type" "call_no_delay_slot")
6628 (set_attr "length" "3")])
6630 ;; This is a call that may want a structure value. This is used for
6632 (define_insn "*call_address_untyped_struct_value_sp32"
6633 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6634 (match_operand 1 "" ""))
6635 (match_operand 2 "immediate_operand" "")
6636 (clobber (reg:SI 15))]
6637 ;;- Do not use operand 1 for most machines.
6638 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
6639 "call\t%a0, %1\n\t nop\n\tnop"
6640 [(set_attr "type" "call_no_delay_slot")
6641 (set_attr "length" "3")])
6643 ;; This is a call that may want a structure value. This is used for
6645 (define_insn "*call_symbolic_untyped_struct_value_sp32"
6646 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6647 (match_operand 1 "" ""))
6648 (match_operand 2 "immediate_operand" "")
6649 (clobber (reg:SI 15))]
6650 ;;- Do not use operand 1 for most machines.
6651 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
6652 "call\t%a0, %1\n\t nop\n\tnop"
6653 [(set_attr "type" "call_no_delay_slot")
6654 (set_attr "length" "3")])
6656 (define_expand "call_value"
6657 ;; Note that this expression is not used for generating RTL.
6658 ;; All the RTL is generated explicitly below.
6659 [(set (match_operand 0 "register_operand" "=rf")
6660 (call (match_operand 1 "" "")
6661 (match_operand 4 "" "")))]
6662 ;; operand 2 is stack_size_rtx
6663 ;; operand 3 is next_arg_register
6669 gcc_assert (MEM_P (operands[1]) && GET_MODE (operands[1]) == FUNCTION_MODE);
6671 fn_rtx = operands[1];
6674 gen_rtx_SET (VOIDmode, operands[0],
6675 gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx)),
6676 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)));
6678 sparc_emit_call_insn (gen_rtx_PARALLEL (VOIDmode, vec), XEXP (fn_rtx, 0));
6683 (define_insn "*call_value_address_sp32"
6684 [(set (match_operand 0 "" "=rf")
6685 (call (mem:SI (match_operand:SI 1 "address_operand" "p"))
6686 (match_operand 2 "" "")))
6687 (clobber (reg:SI 15))]
6688 ;;- Do not use operand 2 for most machines.
6691 [(set_attr "type" "call")])
6693 (define_insn "*call_value_symbolic_sp32"
6694 [(set (match_operand 0 "" "=rf")
6695 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
6696 (match_operand 2 "" "")))
6697 (clobber (reg:SI 15))]
6698 ;;- Do not use operand 2 for most machines.
6701 [(set_attr "type" "call")])
6703 (define_insn "*call_value_address_sp64"
6704 [(set (match_operand 0 "" "")
6705 (call (mem:DI (match_operand:DI 1 "address_operand" "p"))
6706 (match_operand 2 "" "")))
6707 (clobber (reg:DI 15))]
6708 ;;- Do not use operand 2 for most machines.
6711 [(set_attr "type" "call")])
6713 (define_insn "*call_value_symbolic_sp64"
6714 [(set (match_operand 0 "" "")
6715 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
6716 (match_operand 2 "" "")))
6717 (clobber (reg:DI 15))]
6718 ;;- Do not use operand 2 for most machines.
6721 [(set_attr "type" "call")])
6723 (define_expand "untyped_call"
6724 [(parallel [(call (match_operand 0 "" "")
6726 (match_operand:BLK 1 "memory_operand" "")
6727 (match_operand 2 "" "")])]
6730 rtx valreg1 = gen_rtx_REG (DImode, 8);
6731 rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
6732 rtx result = operands[1];
6734 /* Pass constm1 to indicate that it may expect a structure value, but
6735 we don't know what size it is. */
6736 emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, constm1_rtx));
6738 /* Save the function value registers. */
6739 emit_move_insn (adjust_address (result, DImode, 0), valreg1);
6740 emit_move_insn (adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8),
6743 /* The optimizer does not know that the call sets the function value
6744 registers we stored in the result block. We avoid problems by
6745 claiming that all hard registers are used and clobbered at this
6747 emit_insn (gen_blockage ());
6752 ;; Tail call instructions.
6754 (define_expand "sibcall"
6755 [(parallel [(call (match_operand 0 "call_operand" "") (const_int 0))
6760 (define_insn "*sibcall_symbolic_sp32"
6761 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6762 (match_operand 1 "" ""))
6765 "* return output_sibcall(insn, operands[0]);"
6766 [(set_attr "type" "sibcall")])
6768 (define_insn "*sibcall_symbolic_sp64"
6769 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
6770 (match_operand 1 "" ""))
6773 "* return output_sibcall(insn, operands[0]);"
6774 [(set_attr "type" "sibcall")])
6776 (define_expand "sibcall_value"
6777 [(parallel [(set (match_operand 0 "register_operand" "=rf")
6778 (call (match_operand 1 "" "") (const_int 0)))
6783 (define_insn "*sibcall_value_symbolic_sp32"
6784 [(set (match_operand 0 "" "=rf")
6785 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
6786 (match_operand 2 "" "")))
6789 "* return output_sibcall(insn, operands[1]);"
6790 [(set_attr "type" "sibcall")])
6792 (define_insn "*sibcall_value_symbolic_sp64"
6793 [(set (match_operand 0 "" "")
6794 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
6795 (match_operand 2 "" "")))
6798 "* return output_sibcall(insn, operands[1]);"
6799 [(set_attr "type" "sibcall")])
6802 ;; Special instructions.
6804 (define_expand "prologue"
6808 sparc_expand_prologue ();
6812 ;; The "save register window" insn is modelled as follows so that the DWARF-2
6813 ;; backend automatically emits the required call frame debugging information
6814 ;; while it is parsing it. Therefore, the pattern should not be modified
6815 ;; without first studying the impact of the changes on the debug info.
6816 ;; [(set (%fp) (%sp))
6817 ;; (set (%sp) (unspec_volatile [(%sp) (-frame_size)] UNSPECV_SAVEW))
6818 ;; (set (%i7) (%o7))]
6820 (define_insn "save_register_window<P:mode>"
6821 [(set (reg:P 30) (reg:P 14))
6822 (set (reg:P 14) (unspec_volatile:P [(reg:P 14)
6823 (match_operand:P 0 "arith_operand" "rI")] UNSPECV_SAVEW))
6824 (set (reg:P 31) (reg:P 15))]
6826 "save\t%%sp, %0, %%sp"
6827 [(set_attr "type" "savew")])
6829 (define_expand "epilogue"
6833 sparc_expand_epilogue ();
6836 (define_expand "sibcall_epilogue"
6840 sparc_expand_epilogue ();
6844 (define_expand "return"
6846 "sparc_can_use_return_insn_p ()"
6849 (define_insn "*return_internal"
6852 "* return output_return (insn);"
6853 [(set_attr "type" "return")
6854 (set (attr "length")
6855 (cond [(eq_attr "leaf_function" "true")
6856 (if_then_else (eq_attr "empty_delay_slot" "true")
6859 (eq_attr "calls_eh_return" "true")
6860 (if_then_else (eq_attr "delayed_branch" "true")
6861 (if_then_else (eq_attr "isa" "v9")
6864 (if_then_else (eq_attr "isa" "v9")
6867 (eq_attr "empty_delay_slot" "true")
6868 (if_then_else (eq_attr "delayed_branch" "true")
6873 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
6874 ;; all of memory. This blocks insns from being moved across this point.
6876 (define_insn "blockage"
6877 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
6880 [(set_attr "length" "0")])
6882 ;; Prepare to return any type including a structure value.
6884 (define_expand "untyped_return"
6885 [(match_operand:BLK 0 "memory_operand" "")
6886 (match_operand 1 "" "")]
6889 rtx valreg1 = gen_rtx_REG (DImode, 24);
6890 rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
6891 rtx result = operands[0];
6893 if (! TARGET_ARCH64)
6895 rtx rtnreg = gen_rtx_REG (SImode, (current_function_uses_only_leaf_regs
6897 rtx value = gen_reg_rtx (SImode);
6899 /* Fetch the instruction where we will return to and see if it's an unimp
6900 instruction (the most significant 10 bits will be zero). If so,
6901 update the return address to skip the unimp instruction. */
6902 emit_move_insn (value,
6903 gen_rtx_MEM (SImode, plus_constant (rtnreg, 8)));
6904 emit_insn (gen_lshrsi3 (value, value, GEN_INT (22)));
6905 emit_insn (gen_update_return (rtnreg, value));
6908 /* Reload the function value registers. */
6909 emit_move_insn (valreg1, adjust_address (result, DImode, 0));
6910 emit_move_insn (valreg2,
6911 adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8));
6913 /* Put USE insns before the return. */
6917 /* Construct the return. */
6918 expand_naked_return ();
6923 ;; Adjust the return address conditionally. If the value of op1 is equal
6924 ;; to all zero then adjust the return address i.e. op0 = op0 + 4.
6925 ;; This is technically *half* the check required by the 32-bit SPARC
6926 ;; psABI. This check only ensures that an "unimp" insn was written by
6927 ;; the caller, but doesn't check to see if the expected size matches
6928 ;; (this is encoded in the 12 lower bits). This check is obsolete and
6929 ;; only used by the above code "untyped_return".
6931 (define_insn "update_return"
6932 [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
6933 (match_operand:SI 1 "register_operand" "r")] UNSPEC_UPDATE_RETURN)]
6936 if (flag_delayed_branch)
6937 return "cmp\t%1, 0\n\tbe,a\t.+8\n\t add\t%0, 4, %0";
6939 return "cmp\t%1, 0\n\tbne\t.+12\n\t nop\n\tadd\t%0, 4, %0";
6941 [(set (attr "type") (const_string "multi"))
6942 (set (attr "length")
6943 (if_then_else (eq_attr "delayed_branch" "true")
6952 (define_expand "indirect_jump"
6953 [(set (pc) (match_operand 0 "address_operand" "p"))]
6957 (define_insn "*branch_sp32"
6958 [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
6961 [(set_attr "type" "uncond_branch")])
6963 (define_insn "*branch_sp64"
6964 [(set (pc) (match_operand:DI 0 "address_operand" "p"))]
6967 [(set_attr "type" "uncond_branch")])
6969 (define_expand "nonlocal_goto"
6970 [(match_operand:SI 0 "general_operand" "")
6971 (match_operand:SI 1 "general_operand" "")
6972 (match_operand:SI 2 "general_operand" "")
6973 (match_operand:SI 3 "" "")]
6976 rtx lab = operands[1];
6977 rtx stack = operands[2];
6978 rtx fp = operands[3];
6981 /* Trap instruction to flush all the register windows. */
6982 emit_insn (gen_flush_register_windows ());
6984 /* Load the fp value for the containing fn into %fp. This is needed
6985 because STACK refers to %fp. Note that virtual register instantiation
6986 fails if the virtual %fp isn't set from a register. */
6987 if (GET_CODE (fp) != REG)
6988 fp = force_reg (Pmode, fp);
6989 emit_move_insn (virtual_stack_vars_rtx, fp);
6991 /* Find the containing function's current nonlocal goto handler,
6992 which will do any cleanups and then jump to the label. */
6993 labreg = gen_rtx_REG (Pmode, 8);
6994 emit_move_insn (labreg, lab);
6996 /* Restore %fp from stack pointer value for containing function.
6997 The restore insn that follows will move this to %sp,
6998 and reload the appropriate value into %fp. */
6999 emit_move_insn (hard_frame_pointer_rtx, stack);
7001 emit_use (stack_pointer_rtx);
7002 emit_use (static_chain_rtx);
7004 /* ??? The V9-specific version was disabled in rev 1.65. */
7005 emit_jump_insn (gen_goto_handler_and_restore (labreg));
7010 ;; Special trap insn to flush register windows.
7011 (define_insn "flush_register_windows"
7012 [(unspec_volatile [(const_int 0)] UNSPECV_FLUSHW)]
7014 { return TARGET_V9 ? "flushw" : "ta\t3"; }
7015 [(set_attr "type" "flushw")])
7017 (define_insn "goto_handler_and_restore"
7018 [(unspec_volatile [(match_operand 0 "register_operand" "=r")] UNSPECV_GOTO)]
7019 "GET_MODE (operands[0]) == Pmode"
7021 if (flag_delayed_branch)
7022 return "jmp\t%0\n\t restore";
7024 return "mov\t%0,%%g1\n\trestore\n\tjmp\t%%g1\n\t nop";
7026 [(set (attr "type") (const_string "multi"))
7027 (set (attr "length")
7028 (if_then_else (eq_attr "delayed_branch" "true")
7032 ;; For __builtin_setjmp we need to flush register windows iff the function
7033 ;; calls alloca as well, because otherwise the register window might be
7034 ;; saved after %sp adjustment and thus setjmp would crash
7035 (define_expand "builtin_setjmp_setup"
7036 [(match_operand 0 "register_operand" "r")]
7039 emit_insn (gen_do_builtin_setjmp_setup ());
7043 (define_insn "do_builtin_setjmp_setup"
7044 [(unspec_volatile [(const_int 0)] UNSPECV_SETJMP)]
7047 if (! cfun->calls_alloca)
7051 fputs ("\tflushw\n", asm_out_file);
7053 fprintf (asm_out_file, "\tst%c\t%%l7, [%%sp+%d]\n",
7054 TARGET_ARCH64 ? 'x' : 'w',
7055 SPARC_STACK_BIAS + 7 * UNITS_PER_WORD);
7056 fprintf (asm_out_file, "\tst%c\t%%fp, [%%sp+%d]\n",
7057 TARGET_ARCH64 ? 'x' : 'w',
7058 SPARC_STACK_BIAS + 14 * UNITS_PER_WORD);
7059 fprintf (asm_out_file, "\tst%c\t%%i7, [%%sp+%d]\n",
7060 TARGET_ARCH64 ? 'x' : 'w',
7061 SPARC_STACK_BIAS + 15 * UNITS_PER_WORD);
7064 [(set_attr "type" "multi")
7065 (set (attr "length")
7066 (cond [(eq_attr "calls_alloca" "false")
7068 (eq_attr "isa" "!v9")
7070 (eq_attr "pic" "true")
7071 (const_int 4)] (const_int 3)))])
7073 ;; Pattern for use after a setjmp to store FP and the return register
7074 ;; into the stack area.
7076 (define_expand "setjmp"
7082 mem = gen_rtx_MEM (Pmode,
7083 plus_constant (stack_pointer_rtx,
7084 SPARC_STACK_BIAS + 14 * UNITS_PER_WORD));
7085 emit_insn (gen_rtx_SET (VOIDmode, mem, frame_pointer_rtx));
7087 mem = gen_rtx_MEM (Pmode,
7088 plus_constant (stack_pointer_rtx,
7089 SPARC_STACK_BIAS + 15 * UNITS_PER_WORD));
7090 emit_insn (gen_rtx_SET (VOIDmode, mem, gen_rtx_REG (Pmode, 31)));
7094 ;; Special pattern for the FLUSH instruction.
7096 ; We do SImode and DImode versions of this to quiet down genrecog's complaints
7097 ; of the define_insn otherwise missing a mode. We make "flush", aka
7098 ; gen_flush, the default one since sparc_initialize_trampoline uses
7099 ; it on SImode mem values.
7101 (define_insn "flush"
7102 [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")] UNSPECV_FLUSH)]
7104 { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; }
7105 [(set_attr "type" "iflush")])
7107 (define_insn "flushdi"
7108 [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")] UNSPECV_FLUSH)]
7110 { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; }
7111 [(set_attr "type" "iflush")])
7114 ;; Find first set instructions.
7116 ;; The scan instruction searches from the most significant bit while ffs
7117 ;; searches from the least significant bit. The bit index and treatment of
7118 ;; zero also differ. It takes at least 7 instructions to get the proper
7119 ;; result. Here is an obvious 8 instruction sequence.
7122 (define_insn "ffssi2"
7123 [(set (match_operand:SI 0 "register_operand" "=&r")
7124 (ffs:SI (match_operand:SI 1 "register_operand" "r")))
7125 (clobber (match_scratch:SI 2 "=&r"))]
7126 "TARGET_SPARCLITE || TARGET_SPARCLET"
7128 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";
7130 [(set_attr "type" "multi")
7131 (set_attr "length" "8")])
7133 ;; ??? This should be a define expand, so that the extra instruction have
7134 ;; a chance of being optimized away.
7136 ;; Disabled because none of the UltraSPARCs implement popc. The HAL R1
7137 ;; does, but no one uses that and we don't have a switch for it.
7139 ;(define_insn "ffsdi2"
7140 ; [(set (match_operand:DI 0 "register_operand" "=&r")
7141 ; (ffs:DI (match_operand:DI 1 "register_operand" "r")))
7142 ; (clobber (match_scratch:DI 2 "=&r"))]
7144 ; "neg\t%1, %2\;xnor\t%1, %2, %2\;popc\t%2, %0\;movzr\t%1, 0, %0"
7145 ; [(set_attr "type" "multi")
7146 ; (set_attr "length" "4")])
7150 ;; Peepholes go at the end.
7152 ;; Optimize consecutive loads or stores into ldd and std when possible.
7153 ;; The conditions in which we do this are very restricted and are
7154 ;; explained in the code for {registers,memory}_ok_for_ldd functions.
7157 [(set (match_operand:SI 0 "memory_operand" "")
7159 (set (match_operand:SI 1 "memory_operand" "")
7162 && mems_ok_for_ldd_peep (operands[0], operands[1], NULL_RTX)"
7165 "operands[0] = widen_memory_access (operands[0], DImode, 0);")
7168 [(set (match_operand:SI 0 "memory_operand" "")
7170 (set (match_operand:SI 1 "memory_operand" "")
7173 && mems_ok_for_ldd_peep (operands[1], operands[0], NULL_RTX)"
7176 "operands[1] = widen_memory_access (operands[1], DImode, 0);")
7179 [(set (match_operand:SI 0 "register_operand" "")
7180 (match_operand:SI 1 "memory_operand" ""))
7181 (set (match_operand:SI 2 "register_operand" "")
7182 (match_operand:SI 3 "memory_operand" ""))]
7183 "registers_ok_for_ldd_peep (operands[0], operands[2])
7184 && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
7187 "operands[1] = widen_memory_access (operands[1], DImode, 0);
7188 operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));")
7191 [(set (match_operand:SI 0 "memory_operand" "")
7192 (match_operand:SI 1 "register_operand" ""))
7193 (set (match_operand:SI 2 "memory_operand" "")
7194 (match_operand:SI 3 "register_operand" ""))]
7195 "registers_ok_for_ldd_peep (operands[1], operands[3])
7196 && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
7199 "operands[0] = widen_memory_access (operands[0], DImode, 0);
7200 operands[1] = gen_rtx_REG (DImode, REGNO (operands[1]));")
7203 [(set (match_operand:SF 0 "register_operand" "")
7204 (match_operand:SF 1 "memory_operand" ""))
7205 (set (match_operand:SF 2 "register_operand" "")
7206 (match_operand:SF 3 "memory_operand" ""))]
7207 "registers_ok_for_ldd_peep (operands[0], operands[2])
7208 && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
7211 "operands[1] = widen_memory_access (operands[1], DFmode, 0);
7212 operands[0] = gen_rtx_REG (DFmode, REGNO (operands[0]));")
7215 [(set (match_operand:SF 0 "memory_operand" "")
7216 (match_operand:SF 1 "register_operand" ""))
7217 (set (match_operand:SF 2 "memory_operand" "")
7218 (match_operand:SF 3 "register_operand" ""))]
7219 "registers_ok_for_ldd_peep (operands[1], operands[3])
7220 && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
7223 "operands[0] = widen_memory_access (operands[0], DFmode, 0);
7224 operands[1] = gen_rtx_REG (DFmode, REGNO (operands[1]));")
7227 [(set (match_operand:SI 0 "register_operand" "")
7228 (match_operand:SI 1 "memory_operand" ""))
7229 (set (match_operand:SI 2 "register_operand" "")
7230 (match_operand:SI 3 "memory_operand" ""))]
7231 "registers_ok_for_ldd_peep (operands[2], operands[0])
7232 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
7235 "operands[3] = widen_memory_access (operands[3], DImode, 0);
7236 operands[2] = gen_rtx_REG (DImode, REGNO (operands[2]));")
7239 [(set (match_operand:SI 0 "memory_operand" "")
7240 (match_operand:SI 1 "register_operand" ""))
7241 (set (match_operand:SI 2 "memory_operand" "")
7242 (match_operand:SI 3 "register_operand" ""))]
7243 "registers_ok_for_ldd_peep (operands[3], operands[1])
7244 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
7247 "operands[2] = widen_memory_access (operands[2], DImode, 0);
7248 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
7252 [(set (match_operand:SF 0 "register_operand" "")
7253 (match_operand:SF 1 "memory_operand" ""))
7254 (set (match_operand:SF 2 "register_operand" "")
7255 (match_operand:SF 3 "memory_operand" ""))]
7256 "registers_ok_for_ldd_peep (operands[2], operands[0])
7257 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
7260 "operands[3] = widen_memory_access (operands[3], DFmode, 0);
7261 operands[2] = gen_rtx_REG (DFmode, REGNO (operands[2]));")
7264 [(set (match_operand:SF 0 "memory_operand" "")
7265 (match_operand:SF 1 "register_operand" ""))
7266 (set (match_operand:SF 2 "memory_operand" "")
7267 (match_operand:SF 3 "register_operand" ""))]
7268 "registers_ok_for_ldd_peep (operands[3], operands[1])
7269 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
7272 "operands[2] = widen_memory_access (operands[2], DFmode, 0);
7273 operands[3] = gen_rtx_REG (DFmode, REGNO (operands[3]));")
7275 ;; Optimize the case of following a reg-reg move with a test
7276 ;; of reg just moved. Don't allow floating point regs for operand 0 or 1.
7277 ;; This can result from a float to fix conversion.
7280 [(set (match_operand:SI 0 "register_operand" "")
7281 (match_operand:SI 1 "register_operand" ""))
7283 (compare:CC (match_operand:SI 2 "register_operand" "")
7285 "(rtx_equal_p (operands[2], operands[0])
7286 || rtx_equal_p (operands[2], operands[1]))
7287 && ! SPARC_FP_REG_P (REGNO (operands[0]))
7288 && ! SPARC_FP_REG_P (REGNO (operands[1]))"
7289 [(parallel [(set (match_dup 0) (match_dup 1))
7291 (compare:CC (match_dup 1) (const_int 0)))])]
7295 [(set (match_operand:DI 0 "register_operand" "")
7296 (match_operand:DI 1 "register_operand" ""))
7298 (compare:CCX (match_operand:DI 2 "register_operand" "")
7301 && (rtx_equal_p (operands[2], operands[0])
7302 || rtx_equal_p (operands[2], operands[1]))
7303 && ! SPARC_FP_REG_P (REGNO (operands[0]))
7304 && ! SPARC_FP_REG_P (REGNO (operands[1]))"
7305 [(parallel [(set (match_dup 0) (match_dup 1))
7307 (compare:CCX (match_dup 1) (const_int 0)))])]
7311 ;; Prefetch instructions.
7313 ;; ??? UltraSPARC-III note: A memory operation loading into the floating point register
7314 ;; ??? file, if it hits the prefetch cache, has a chance to dual-issue with other memory
7315 ;; ??? operations. With DFA we might be able to model this, but it requires a lot of
7317 (define_expand "prefetch"
7318 [(match_operand 0 "address_operand" "")
7319 (match_operand 1 "const_int_operand" "")
7320 (match_operand 2 "const_int_operand" "")]
7324 emit_insn (gen_prefetch_64 (operands[0], operands[1], operands[2]));
7326 emit_insn (gen_prefetch_32 (operands[0], operands[1], operands[2]));
7330 (define_insn "prefetch_64"
7331 [(prefetch (match_operand:DI 0 "address_operand" "p")
7332 (match_operand:DI 1 "const_int_operand" "n")
7333 (match_operand:DI 2 "const_int_operand" "n"))]
7336 static const char * const prefetch_instr[2][2] = {
7338 "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
7339 "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
7342 "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
7343 "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
7346 int read_or_write = INTVAL (operands[1]);
7347 int locality = INTVAL (operands[2]);
7349 gcc_assert (read_or_write == 0 || read_or_write == 1);
7350 gcc_assert (locality >= 0 && locality < 4);
7351 return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
7353 [(set_attr "type" "load")])
7355 (define_insn "prefetch_32"
7356 [(prefetch (match_operand:SI 0 "address_operand" "p")
7357 (match_operand:SI 1 "const_int_operand" "n")
7358 (match_operand:SI 2 "const_int_operand" "n"))]
7361 static const char * const prefetch_instr[2][2] = {
7363 "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
7364 "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
7367 "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
7368 "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
7371 int read_or_write = INTVAL (operands[1]);
7372 int locality = INTVAL (operands[2]);
7374 gcc_assert (read_or_write == 0 || read_or_write == 1);
7375 gcc_assert (locality >= 0 && locality < 4);
7376 return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
7378 [(set_attr "type" "load")])
7381 ;; Trap instructions.
7384 [(trap_if (const_int 1) (const_int 5))]
7387 [(set_attr "type" "trap")])
7389 (define_expand "conditional_trap"
7390 [(trap_if (match_operator 0 "noov_compare_operator" [(match_dup 2) (match_dup 3)])
7391 (match_operand:SI 1 "arith_operand" ""))]
7393 "operands[2] = gen_compare_reg (GET_CODE (operands[0]));
7394 if (GET_MODE (operands[2]) != CCmode && GET_MODE (operands[2]) != CCXmode)
7396 operands[3] = const0_rtx;")
7399 [(trap_if (match_operator 0 "noov_compare_operator" [(reg:CC 100) (const_int 0)])
7400 (match_operand:SI 1 "arith_operand" "rM"))]
7404 return "t%C0\t%%icc, %1";
7408 [(set_attr "type" "trap")])
7411 [(trap_if (match_operator 0 "noov_compare_operator" [(reg:CCX 100) (const_int 0)])
7412 (match_operand:SI 1 "arith_operand" "rM"))]
7415 [(set_attr "type" "trap")])
7418 ;; TLS support instructions.
7420 (define_insn "tgd_hi22"
7421 [(set (match_operand:SI 0 "register_operand" "=r")
7422 (high:SI (unspec:SI [(match_operand 1 "tgd_symbolic_operand" "")]
7425 "sethi\\t%%tgd_hi22(%a1), %0")
7427 (define_insn "tgd_lo10"
7428 [(set (match_operand:SI 0 "register_operand" "=r")
7429 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7430 (unspec:SI [(match_operand 2 "tgd_symbolic_operand" "")]
7433 "add\\t%1, %%tgd_lo10(%a2), %0")
7435 (define_insn "tgd_add32"
7436 [(set (match_operand:SI 0 "register_operand" "=r")
7437 (plus:SI (match_operand:SI 1 "register_operand" "r")
7438 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7439 (match_operand 3 "tgd_symbolic_operand" "")]
7441 "TARGET_TLS && TARGET_ARCH32"
7442 "add\\t%1, %2, %0, %%tgd_add(%a3)")
7444 (define_insn "tgd_add64"
7445 [(set (match_operand:DI 0 "register_operand" "=r")
7446 (plus:DI (match_operand:DI 1 "register_operand" "r")
7447 (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7448 (match_operand 3 "tgd_symbolic_operand" "")]
7450 "TARGET_TLS && TARGET_ARCH64"
7451 "add\\t%1, %2, %0, %%tgd_add(%a3)")
7453 (define_insn "tgd_call32"
7454 [(set (match_operand 0 "register_operand" "=r")
7455 (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")
7456 (match_operand 2 "tgd_symbolic_operand" "")]
7458 (match_operand 3 "" "")))
7459 (clobber (reg:SI 15))]
7460 "TARGET_TLS && TARGET_ARCH32"
7461 "call\t%a1, %%tgd_call(%a2)%#"
7462 [(set_attr "type" "call")])
7464 (define_insn "tgd_call64"
7465 [(set (match_operand 0 "register_operand" "=r")
7466 (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")
7467 (match_operand 2 "tgd_symbolic_operand" "")]
7469 (match_operand 3 "" "")))
7470 (clobber (reg:DI 15))]
7471 "TARGET_TLS && TARGET_ARCH64"
7472 "call\t%a1, %%tgd_call(%a2)%#"
7473 [(set_attr "type" "call")])
7475 (define_insn "tldm_hi22"
7476 [(set (match_operand:SI 0 "register_operand" "=r")
7477 (high:SI (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
7479 "sethi\\t%%tldm_hi22(%&), %0")
7481 (define_insn "tldm_lo10"
7482 [(set (match_operand:SI 0 "register_operand" "=r")
7483 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7484 (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
7486 "add\\t%1, %%tldm_lo10(%&), %0")
7488 (define_insn "tldm_add32"
7489 [(set (match_operand:SI 0 "register_operand" "=r")
7490 (plus:SI (match_operand:SI 1 "register_operand" "r")
7491 (unspec:SI [(match_operand:SI 2 "register_operand" "r")]
7493 "TARGET_TLS && TARGET_ARCH32"
7494 "add\\t%1, %2, %0, %%tldm_add(%&)")
7496 (define_insn "tldm_add64"
7497 [(set (match_operand:DI 0 "register_operand" "=r")
7498 (plus:DI (match_operand:DI 1 "register_operand" "r")
7499 (unspec:DI [(match_operand:SI 2 "register_operand" "r")]
7501 "TARGET_TLS && TARGET_ARCH64"
7502 "add\\t%1, %2, %0, %%tldm_add(%&)")
7504 (define_insn "tldm_call32"
7505 [(set (match_operand 0 "register_operand" "=r")
7506 (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")]
7508 (match_operand 2 "" "")))
7509 (clobber (reg:SI 15))]
7510 "TARGET_TLS && TARGET_ARCH32"
7511 "call\t%a1, %%tldm_call(%&)%#"
7512 [(set_attr "type" "call")])
7514 (define_insn "tldm_call64"
7515 [(set (match_operand 0 "register_operand" "=r")
7516 (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")]
7518 (match_operand 2 "" "")))
7519 (clobber (reg:DI 15))]
7520 "TARGET_TLS && TARGET_ARCH64"
7521 "call\t%a1, %%tldm_call(%&)%#"
7522 [(set_attr "type" "call")])
7524 (define_insn "tldo_hix22"
7525 [(set (match_operand:SI 0 "register_operand" "=r")
7526 (high:SI (unspec:SI [(match_operand 1 "tld_symbolic_operand" "")]
7529 "sethi\\t%%tldo_hix22(%a1), %0")
7531 (define_insn "tldo_lox10"
7532 [(set (match_operand:SI 0 "register_operand" "=r")
7533 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7534 (unspec:SI [(match_operand 2 "tld_symbolic_operand" "")]
7537 "xor\\t%1, %%tldo_lox10(%a2), %0")
7539 (define_insn "tldo_add32"
7540 [(set (match_operand:SI 0 "register_operand" "=r")
7541 (plus:SI (match_operand:SI 1 "register_operand" "r")
7542 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7543 (match_operand 3 "tld_symbolic_operand" "")]
7545 "TARGET_TLS && TARGET_ARCH32"
7546 "add\\t%1, %2, %0, %%tldo_add(%a3)")
7548 (define_insn "tldo_add64"
7549 [(set (match_operand:DI 0 "register_operand" "=r")
7550 (plus:DI (match_operand:DI 1 "register_operand" "r")
7551 (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7552 (match_operand 3 "tld_symbolic_operand" "")]
7554 "TARGET_TLS && TARGET_ARCH64"
7555 "add\\t%1, %2, %0, %%tldo_add(%a3)")
7557 (define_insn "tie_hi22"
7558 [(set (match_operand:SI 0 "register_operand" "=r")
7559 (high:SI (unspec:SI [(match_operand 1 "tie_symbolic_operand" "")]
7562 "sethi\\t%%tie_hi22(%a1), %0")
7564 (define_insn "tie_lo10"
7565 [(set (match_operand:SI 0 "register_operand" "=r")
7566 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7567 (unspec:SI [(match_operand 2 "tie_symbolic_operand" "")]
7570 "add\\t%1, %%tie_lo10(%a2), %0")
7572 (define_insn "tie_ld32"
7573 [(set (match_operand:SI 0 "register_operand" "=r")
7574 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
7575 (match_operand:SI 2 "register_operand" "r")
7576 (match_operand 3 "tie_symbolic_operand" "")]
7578 "TARGET_TLS && TARGET_ARCH32"
7579 "ld\\t[%1 + %2], %0, %%tie_ld(%a3)"
7580 [(set_attr "type" "load")])
7582 (define_insn "tie_ld64"
7583 [(set (match_operand:DI 0 "register_operand" "=r")
7584 (unspec:DI [(match_operand:DI 1 "register_operand" "r")
7585 (match_operand:SI 2 "register_operand" "r")
7586 (match_operand 3 "tie_symbolic_operand" "")]
7588 "TARGET_TLS && TARGET_ARCH64"
7589 "ldx\\t[%1 + %2], %0, %%tie_ldx(%a3)"
7590 [(set_attr "type" "load")])
7592 (define_insn "tie_add32"
7593 [(set (match_operand:SI 0 "register_operand" "=r")
7594 (plus:SI (match_operand:SI 1 "register_operand" "r")
7595 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7596 (match_operand 3 "tie_symbolic_operand" "")]
7598 "TARGET_SUN_TLS && TARGET_ARCH32"
7599 "add\\t%1, %2, %0, %%tie_add(%a3)")
7601 (define_insn "tie_add64"
7602 [(set (match_operand:DI 0 "register_operand" "=r")
7603 (plus:DI (match_operand:DI 1 "register_operand" "r")
7604 (unspec:DI [(match_operand:DI 2 "register_operand" "r")
7605 (match_operand 3 "tie_symbolic_operand" "")]
7607 "TARGET_SUN_TLS && TARGET_ARCH64"
7608 "add\\t%1, %2, %0, %%tie_add(%a3)")
7610 (define_insn "tle_hix22_sp32"
7611 [(set (match_operand:SI 0 "register_operand" "=r")
7612 (high:SI (unspec:SI [(match_operand 1 "tle_symbolic_operand" "")]
7614 "TARGET_TLS && TARGET_ARCH32"
7615 "sethi\\t%%tle_hix22(%a1), %0")
7617 (define_insn "tle_lox10_sp32"
7618 [(set (match_operand:SI 0 "register_operand" "=r")
7619 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7620 (unspec:SI [(match_operand 2 "tle_symbolic_operand" "")]
7622 "TARGET_TLS && TARGET_ARCH32"
7623 "xor\\t%1, %%tle_lox10(%a2), %0")
7625 (define_insn "tle_hix22_sp64"
7626 [(set (match_operand:DI 0 "register_operand" "=r")
7627 (high:DI (unspec:DI [(match_operand 1 "tle_symbolic_operand" "")]
7629 "TARGET_TLS && TARGET_ARCH64"
7630 "sethi\\t%%tle_hix22(%a1), %0")
7632 (define_insn "tle_lox10_sp64"
7633 [(set (match_operand:DI 0 "register_operand" "=r")
7634 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
7635 (unspec:DI [(match_operand 2 "tle_symbolic_operand" "")]
7637 "TARGET_TLS && TARGET_ARCH64"
7638 "xor\\t%1, %%tle_lox10(%a2), %0")
7640 ;; Now patterns combining tldo_add{32,64} with some integer loads or stores
7641 (define_insn "*tldo_ldub_sp32"
7642 [(set (match_operand:QI 0 "register_operand" "=r")
7643 (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7644 (match_operand 3 "tld_symbolic_operand" "")]
7646 (match_operand:SI 1 "register_operand" "r"))))]
7647 "TARGET_TLS && TARGET_ARCH32"
7648 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7649 [(set_attr "type" "load")
7650 (set_attr "us3load_type" "3cycle")])
7652 (define_insn "*tldo_ldub1_sp32"
7653 [(set (match_operand:HI 0 "register_operand" "=r")
7654 (zero_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7655 (match_operand 3 "tld_symbolic_operand" "")]
7657 (match_operand:SI 1 "register_operand" "r")))))]
7658 "TARGET_TLS && TARGET_ARCH32"
7659 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7660 [(set_attr "type" "load")
7661 (set_attr "us3load_type" "3cycle")])
7663 (define_insn "*tldo_ldub2_sp32"
7664 [(set (match_operand:SI 0 "register_operand" "=r")
7665 (zero_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7666 (match_operand 3 "tld_symbolic_operand" "")]
7668 (match_operand:SI 1 "register_operand" "r")))))]
7669 "TARGET_TLS && TARGET_ARCH32"
7670 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7671 [(set_attr "type" "load")
7672 (set_attr "us3load_type" "3cycle")])
7674 (define_insn "*tldo_ldsb1_sp32"
7675 [(set (match_operand:HI 0 "register_operand" "=r")
7676 (sign_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7677 (match_operand 3 "tld_symbolic_operand" "")]
7679 (match_operand:SI 1 "register_operand" "r")))))]
7680 "TARGET_TLS && TARGET_ARCH32"
7681 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7682 [(set_attr "type" "sload")
7683 (set_attr "us3load_type" "3cycle")])
7685 (define_insn "*tldo_ldsb2_sp32"
7686 [(set (match_operand:SI 0 "register_operand" "=r")
7687 (sign_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7688 (match_operand 3 "tld_symbolic_operand" "")]
7690 (match_operand:SI 1 "register_operand" "r")))))]
7691 "TARGET_TLS && TARGET_ARCH32"
7692 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7693 [(set_attr "type" "sload")
7694 (set_attr "us3load_type" "3cycle")])
7696 (define_insn "*tldo_ldub_sp64"
7697 [(set (match_operand:QI 0 "register_operand" "=r")
7698 (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7699 (match_operand 3 "tld_symbolic_operand" "")]
7701 (match_operand:DI 1 "register_operand" "r"))))]
7702 "TARGET_TLS && TARGET_ARCH64"
7703 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7704 [(set_attr "type" "load")
7705 (set_attr "us3load_type" "3cycle")])
7707 (define_insn "*tldo_ldub1_sp64"
7708 [(set (match_operand:HI 0 "register_operand" "=r")
7709 (zero_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7710 (match_operand 3 "tld_symbolic_operand" "")]
7712 (match_operand:DI 1 "register_operand" "r")))))]
7713 "TARGET_TLS && TARGET_ARCH64"
7714 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7715 [(set_attr "type" "load")
7716 (set_attr "us3load_type" "3cycle")])
7718 (define_insn "*tldo_ldub2_sp64"
7719 [(set (match_operand:SI 0 "register_operand" "=r")
7720 (zero_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7721 (match_operand 3 "tld_symbolic_operand" "")]
7723 (match_operand:DI 1 "register_operand" "r")))))]
7724 "TARGET_TLS && TARGET_ARCH64"
7725 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7726 [(set_attr "type" "load")
7727 (set_attr "us3load_type" "3cycle")])
7729 (define_insn "*tldo_ldub3_sp64"
7730 [(set (match_operand:DI 0 "register_operand" "=r")
7731 (zero_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7732 (match_operand 3 "tld_symbolic_operand" "")]
7734 (match_operand:DI 1 "register_operand" "r")))))]
7735 "TARGET_TLS && TARGET_ARCH64"
7736 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7737 [(set_attr "type" "load")
7738 (set_attr "us3load_type" "3cycle")])
7740 (define_insn "*tldo_ldsb1_sp64"
7741 [(set (match_operand:HI 0 "register_operand" "=r")
7742 (sign_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7743 (match_operand 3 "tld_symbolic_operand" "")]
7745 (match_operand:DI 1 "register_operand" "r")))))]
7746 "TARGET_TLS && TARGET_ARCH64"
7747 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7748 [(set_attr "type" "sload")
7749 (set_attr "us3load_type" "3cycle")])
7751 (define_insn "*tldo_ldsb2_sp64"
7752 [(set (match_operand:SI 0 "register_operand" "=r")
7753 (sign_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7754 (match_operand 3 "tld_symbolic_operand" "")]
7756 (match_operand:DI 1 "register_operand" "r")))))]
7757 "TARGET_TLS && TARGET_ARCH64"
7758 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7759 [(set_attr "type" "sload")
7760 (set_attr "us3load_type" "3cycle")])
7762 (define_insn "*tldo_ldsb3_sp64"
7763 [(set (match_operand:DI 0 "register_operand" "=r")
7764 (sign_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7765 (match_operand 3 "tld_symbolic_operand" "")]
7767 (match_operand:DI 1 "register_operand" "r")))))]
7768 "TARGET_TLS && TARGET_ARCH64"
7769 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7770 [(set_attr "type" "sload")
7771 (set_attr "us3load_type" "3cycle")])
7773 (define_insn "*tldo_lduh_sp32"
7774 [(set (match_operand:HI 0 "register_operand" "=r")
7775 (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7776 (match_operand 3 "tld_symbolic_operand" "")]
7778 (match_operand:SI 1 "register_operand" "r"))))]
7779 "TARGET_TLS && TARGET_ARCH32"
7780 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7781 [(set_attr "type" "load")
7782 (set_attr "us3load_type" "3cycle")])
7784 (define_insn "*tldo_lduh1_sp32"
7785 [(set (match_operand:SI 0 "register_operand" "=r")
7786 (zero_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7787 (match_operand 3 "tld_symbolic_operand" "")]
7789 (match_operand:SI 1 "register_operand" "r")))))]
7790 "TARGET_TLS && TARGET_ARCH32"
7791 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7792 [(set_attr "type" "load")
7793 (set_attr "us3load_type" "3cycle")])
7795 (define_insn "*tldo_ldsh1_sp32"
7796 [(set (match_operand:SI 0 "register_operand" "=r")
7797 (sign_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7798 (match_operand 3 "tld_symbolic_operand" "")]
7800 (match_operand:SI 1 "register_operand" "r")))))]
7801 "TARGET_TLS && TARGET_ARCH32"
7802 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
7803 [(set_attr "type" "sload")
7804 (set_attr "us3load_type" "3cycle")])
7806 (define_insn "*tldo_lduh_sp64"
7807 [(set (match_operand:HI 0 "register_operand" "=r")
7808 (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7809 (match_operand 3 "tld_symbolic_operand" "")]
7811 (match_operand:DI 1 "register_operand" "r"))))]
7812 "TARGET_TLS && TARGET_ARCH64"
7813 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7814 [(set_attr "type" "load")
7815 (set_attr "us3load_type" "3cycle")])
7817 (define_insn "*tldo_lduh1_sp64"
7818 [(set (match_operand:SI 0 "register_operand" "=r")
7819 (zero_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7820 (match_operand 3 "tld_symbolic_operand" "")]
7822 (match_operand:DI 1 "register_operand" "r")))))]
7823 "TARGET_TLS && TARGET_ARCH64"
7824 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7825 [(set_attr "type" "load")
7826 (set_attr "us3load_type" "3cycle")])
7828 (define_insn "*tldo_lduh2_sp64"
7829 [(set (match_operand:DI 0 "register_operand" "=r")
7830 (zero_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7831 (match_operand 3 "tld_symbolic_operand" "")]
7833 (match_operand:DI 1 "register_operand" "r")))))]
7834 "TARGET_TLS && TARGET_ARCH64"
7835 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7836 [(set_attr "type" "load")
7837 (set_attr "us3load_type" "3cycle")])
7839 (define_insn "*tldo_ldsh1_sp64"
7840 [(set (match_operand:SI 0 "register_operand" "=r")
7841 (sign_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7842 (match_operand 3 "tld_symbolic_operand" "")]
7844 (match_operand:DI 1 "register_operand" "r")))))]
7845 "TARGET_TLS && TARGET_ARCH64"
7846 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
7847 [(set_attr "type" "sload")
7848 (set_attr "us3load_type" "3cycle")])
7850 (define_insn "*tldo_ldsh2_sp64"
7851 [(set (match_operand:DI 0 "register_operand" "=r")
7852 (sign_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7853 (match_operand 3 "tld_symbolic_operand" "")]
7855 (match_operand:DI 1 "register_operand" "r")))))]
7856 "TARGET_TLS && TARGET_ARCH64"
7857 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
7858 [(set_attr "type" "sload")
7859 (set_attr "us3load_type" "3cycle")])
7861 (define_insn "*tldo_lduw_sp32"
7862 [(set (match_operand:SI 0 "register_operand" "=r")
7863 (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7864 (match_operand 3 "tld_symbolic_operand" "")]
7866 (match_operand:SI 1 "register_operand" "r"))))]
7867 "TARGET_TLS && TARGET_ARCH32"
7868 "ld\t[%1 + %2], %0, %%tldo_add(%3)"
7869 [(set_attr "type" "load")])
7871 (define_insn "*tldo_lduw_sp64"
7872 [(set (match_operand:SI 0 "register_operand" "=r")
7873 (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7874 (match_operand 3 "tld_symbolic_operand" "")]
7876 (match_operand:DI 1 "register_operand" "r"))))]
7877 "TARGET_TLS && TARGET_ARCH64"
7878 "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
7879 [(set_attr "type" "load")])
7881 (define_insn "*tldo_lduw1_sp64"
7882 [(set (match_operand:DI 0 "register_operand" "=r")
7883 (zero_extend:DI (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7884 (match_operand 3 "tld_symbolic_operand" "")]
7886 (match_operand:DI 1 "register_operand" "r")))))]
7887 "TARGET_TLS && TARGET_ARCH64"
7888 "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
7889 [(set_attr "type" "load")])
7891 (define_insn "*tldo_ldsw1_sp64"
7892 [(set (match_operand:DI 0 "register_operand" "=r")
7893 (sign_extend:DI (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7894 (match_operand 3 "tld_symbolic_operand" "")]
7896 (match_operand:DI 1 "register_operand" "r")))))]
7897 "TARGET_TLS && TARGET_ARCH64"
7898 "ldsw\t[%1 + %2], %0, %%tldo_add(%3)"
7899 [(set_attr "type" "sload")
7900 (set_attr "us3load_type" "3cycle")])
7902 (define_insn "*tldo_ldx_sp64"
7903 [(set (match_operand:DI 0 "register_operand" "=r")
7904 (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7905 (match_operand 3 "tld_symbolic_operand" "")]
7907 (match_operand:DI 1 "register_operand" "r"))))]
7908 "TARGET_TLS && TARGET_ARCH64"
7909 "ldx\t[%1 + %2], %0, %%tldo_add(%3)"
7910 [(set_attr "type" "load")])
7912 (define_insn "*tldo_stb_sp32"
7913 [(set (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7914 (match_operand 3 "tld_symbolic_operand" "")]
7916 (match_operand:SI 1 "register_operand" "r")))
7917 (match_operand:QI 0 "register_operand" "=r"))]
7918 "TARGET_TLS && TARGET_ARCH32"
7919 "stb\t%0, [%1 + %2], %%tldo_add(%3)"
7920 [(set_attr "type" "store")])
7922 (define_insn "*tldo_stb_sp64"
7923 [(set (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7924 (match_operand 3 "tld_symbolic_operand" "")]
7926 (match_operand:DI 1 "register_operand" "r")))
7927 (match_operand:QI 0 "register_operand" "=r"))]
7928 "TARGET_TLS && TARGET_ARCH64"
7929 "stb\t%0, [%1 + %2], %%tldo_add(%3)"
7930 [(set_attr "type" "store")])
7932 (define_insn "*tldo_sth_sp32"
7933 [(set (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7934 (match_operand 3 "tld_symbolic_operand" "")]
7936 (match_operand:SI 1 "register_operand" "r")))
7937 (match_operand:HI 0 "register_operand" "=r"))]
7938 "TARGET_TLS && TARGET_ARCH32"
7939 "sth\t%0, [%1 + %2], %%tldo_add(%3)"
7940 [(set_attr "type" "store")])
7942 (define_insn "*tldo_sth_sp64"
7943 [(set (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7944 (match_operand 3 "tld_symbolic_operand" "")]
7946 (match_operand:DI 1 "register_operand" "r")))
7947 (match_operand:HI 0 "register_operand" "=r"))]
7948 "TARGET_TLS && TARGET_ARCH64"
7949 "sth\t%0, [%1 + %2], %%tldo_add(%3)"
7950 [(set_attr "type" "store")])
7952 (define_insn "*tldo_stw_sp32"
7953 [(set (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7954 (match_operand 3 "tld_symbolic_operand" "")]
7956 (match_operand:SI 1 "register_operand" "r")))
7957 (match_operand:SI 0 "register_operand" "=r"))]
7958 "TARGET_TLS && TARGET_ARCH32"
7959 "st\t%0, [%1 + %2], %%tldo_add(%3)"
7960 [(set_attr "type" "store")])
7962 (define_insn "*tldo_stw_sp64"
7963 [(set (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7964 (match_operand 3 "tld_symbolic_operand" "")]
7966 (match_operand:DI 1 "register_operand" "r")))
7967 (match_operand:SI 0 "register_operand" "=r"))]
7968 "TARGET_TLS && TARGET_ARCH64"
7969 "stw\t%0, [%1 + %2], %%tldo_add(%3)"
7970 [(set_attr "type" "store")])
7972 (define_insn "*tldo_stx_sp64"
7973 [(set (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7974 (match_operand 3 "tld_symbolic_operand" "")]
7976 (match_operand:DI 1 "register_operand" "r")))
7977 (match_operand:DI 0 "register_operand" "=r"))]
7978 "TARGET_TLS && TARGET_ARCH64"
7979 "stx\t%0, [%1 + %2], %%tldo_add(%3)"
7980 [(set_attr "type" "store")])
7983 ;; Stack protector instructions.
7985 (define_expand "stack_protect_set"
7986 [(match_operand 0 "memory_operand" "")
7987 (match_operand 1 "memory_operand" "")]
7990 #ifdef TARGET_THREAD_SSP_OFFSET
7991 rtx tlsreg = gen_rtx_REG (Pmode, 7);
7992 rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
7993 operands[1] = gen_rtx_MEM (Pmode, addr);
7996 emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
7998 emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
8002 (define_insn "stack_protect_setsi"
8003 [(set (match_operand:SI 0 "memory_operand" "=m")
8004 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
8005 (set (match_scratch:SI 2 "=&r") (const_int 0))]
8007 "ld\t%1, %2\;st\t%2, %0\;mov\t0, %2"
8008 [(set_attr "type" "multi")
8009 (set_attr "length" "3")])
8011 (define_insn "stack_protect_setdi"
8012 [(set (match_operand:DI 0 "memory_operand" "=m")
8013 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
8014 (set (match_scratch:DI 2 "=&r") (const_int 0))]
8016 "ldx\t%1, %2\;stx\t%2, %0\;mov\t0, %2"
8017 [(set_attr "type" "multi")
8018 (set_attr "length" "3")])
8020 (define_expand "stack_protect_test"
8021 [(match_operand 0 "memory_operand" "")
8022 (match_operand 1 "memory_operand" "")
8023 (match_operand 2 "" "")]
8026 #ifdef TARGET_THREAD_SSP_OFFSET
8027 rtx tlsreg = gen_rtx_REG (Pmode, 7);
8028 rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
8029 operands[1] = gen_rtx_MEM (Pmode, addr);
8033 rtx temp = gen_reg_rtx (Pmode);
8034 emit_insn (gen_stack_protect_testdi (temp, operands[0], operands[1]));
8035 sparc_compare_op0 = temp;
8036 sparc_compare_op1 = const0_rtx;
8040 emit_insn (gen_stack_protect_testsi (operands[0], operands[1]));
8041 sparc_compare_op0 = operands[0];
8042 sparc_compare_op1 = operands[1];
8043 sparc_compare_emitted = gen_rtx_REG (CCmode, SPARC_ICC_REG);
8045 emit_jump_insn (gen_beq (operands[2]));
8049 (define_insn "stack_protect_testsi"
8051 (unspec:CC [(match_operand:SI 0 "memory_operand" "m")
8052 (match_operand:SI 1 "memory_operand" "m")]
8054 (set (match_scratch:SI 3 "=r") (const_int 0))
8055 (clobber (match_scratch:SI 2 "=&r"))]
8057 "ld\t%0, %2\;ld\t%1, %3\;xorcc\t%2, %3, %2\;mov\t0, %3"
8058 [(set_attr "type" "multi")
8059 (set_attr "length" "4")])
8061 (define_insn "stack_protect_testdi"
8062 [(set (match_operand:DI 0 "register_operand" "=&r")
8063 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
8064 (match_operand:DI 2 "memory_operand" "m")]
8066 (set (match_scratch:DI 3 "=r") (const_int 0))]
8068 "ldx\t%1, %0\;ldx\t%2, %3\;xor\t%0, %3, %0\;mov\t0, %3"
8069 [(set_attr "type" "multi")
8070 (set_attr "length" "4")])
8073 ;; Vector instructions.
8075 (define_insn "addv2si3"
8076 [(set (match_operand:V2SI 0 "register_operand" "=e")
8077 (plus:V2SI (match_operand:V2SI 1 "register_operand" "e")
8078 (match_operand:V2SI 2 "register_operand" "e")))]
8080 "fpadd32\t%1, %2, %0"
8081 [(set_attr "type" "fga")
8082 (set_attr "fptype" "double")])
8084 (define_insn "addv4hi3"
8085 [(set (match_operand:V4HI 0 "register_operand" "=e")
8086 (plus:V4HI (match_operand:V4HI 1 "register_operand" "e")
8087 (match_operand:V4HI 2 "register_operand" "e")))]
8089 "fpadd16\t%1, %2, %0"
8090 [(set_attr "type" "fga")
8091 (set_attr "fptype" "double")])
8093 ;; fpadd32s is emitted by the addsi3 pattern.
8095 (define_insn "addv2hi3"
8096 [(set (match_operand:V2HI 0 "register_operand" "=f")
8097 (plus:V2HI (match_operand:V2HI 1 "register_operand" "f")
8098 (match_operand:V2HI 2 "register_operand" "f")))]
8100 "fpadd16s\t%1, %2, %0"
8101 [(set_attr "type" "fga")
8102 (set_attr "fptype" "single")])
8104 (define_insn "subv2si3"
8105 [(set (match_operand:V2SI 0 "register_operand" "=e")
8106 (minus:V2SI (match_operand:V2SI 1 "register_operand" "e")
8107 (match_operand:V2SI 2 "register_operand" "e")))]
8109 "fpsub32\t%1, %2, %0"
8110 [(set_attr "type" "fga")
8111 (set_attr "fptype" "double")])
8113 (define_insn "subv4hi3"
8114 [(set (match_operand:V4HI 0 "register_operand" "=e")
8115 (minus:V4HI (match_operand:V4HI 1 "register_operand" "e")
8116 (match_operand:V4HI 2 "register_operand" "e")))]
8118 "fpsub16\t%1, %2, %0"
8119 [(set_attr "type" "fga")
8120 (set_attr "fptype" "double")])
8122 ;; fpsub32s is emitted by the subsi3 pattern.
8124 (define_insn "subv2hi3"
8125 [(set (match_operand:V2HI 0 "register_operand" "=f")
8126 (minus:V2HI (match_operand:V2HI 1 "register_operand" "f")
8127 (match_operand:V2HI 2 "register_operand" "f")))]
8129 "fpsub16s\t%1, %2, %0"
8130 [(set_attr "type" "fga")
8131 (set_attr "fptype" "single")])
8133 ;; All other logical instructions have integer equivalents so they
8134 ;; are defined together.
8136 ;; (ior (not (op1)) (not (op2))) is the canonical form of NAND.
8138 (define_insn "*nand<V64mode>_vis"
8139 [(set (match_operand:V64 0 "register_operand" "=e")
8140 (ior:V64 (not:V64 (match_operand:V64 1 "register_operand" "e"))
8141 (not:V64 (match_operand:V64 2 "register_operand" "e"))))]
8144 [(set_attr "type" "fga")
8145 (set_attr "fptype" "double")])
8147 (define_insn "*nand<V32mode>_vis"
8148 [(set (match_operand:V32 0 "register_operand" "=f")
8149 (ior:V32 (not:V32 (match_operand:V32 1 "register_operand" "f"))
8150 (not:V32 (match_operand:V32 2 "register_operand" "f"))))]
8152 "fnands\t%1, %2, %0"
8153 [(set_attr "type" "fga")
8154 (set_attr "fptype" "single")])
8156 ;; Hard to generate VIS instructions. We have builtins for these.
8158 (define_insn "fpack16_vis"
8159 [(set (match_operand:V4QI 0 "register_operand" "=f")
8160 (unspec:V4QI [(match_operand:V4HI 1 "register_operand" "e")]
8164 [(set_attr "type" "fga")
8165 (set_attr "fptype" "double")])
8167 (define_insn "fpackfix_vis"
8168 [(set (match_operand:V2HI 0 "register_operand" "=f")
8169 (unspec:V2HI [(match_operand:V2SI 1 "register_operand" "e")]
8173 [(set_attr "type" "fga")
8174 (set_attr "fptype" "double")])
8176 (define_insn "fpack32_vis"
8177 [(set (match_operand:V8QI 0 "register_operand" "=e")
8178 (unspec:V8QI [(match_operand:V2SI 1 "register_operand" "e")
8179 (match_operand:V8QI 2 "register_operand" "e")]
8182 "fpack32\t%1, %2, %0"
8183 [(set_attr "type" "fga")
8184 (set_attr "fptype" "double")])
8186 (define_insn "fexpand_vis"
8187 [(set (match_operand:V4HI 0 "register_operand" "=e")
8188 (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")]
8192 [(set_attr "type" "fga")
8193 (set_attr "fptype" "double")])
8195 ;; It may be possible to describe this operation as (1 indexed):
8196 ;; (vec_select (vec_duplicate (vec_duplicate (vec_concat 1 2)))
8197 ;; 1,5,10,14,19,23,28,32)
8198 ;; Note that (vec_merge:V8QI [(V4QI) (V4QI)] (10101010 = 170) doesn't work
8199 ;; because vec_merge expects all the operands to be of the same type.
8200 (define_insn "fpmerge_vis"
8201 [(set (match_operand:V8QI 0 "register_operand" "=e")
8202 (unspec:V8QI [(match_operand:V4QI 1 "register_operand" "f")
8203 (match_operand:V4QI 2 "register_operand" "f")]
8206 "fpmerge\t%1, %2, %0"
8207 [(set_attr "type" "fga")
8208 (set_attr "fptype" "double")])
8210 ;; Partitioned multiply instructions
8211 (define_insn "fmul8x16_vis"
8212 [(set (match_operand:V4HI 0 "register_operand" "=e")
8213 (mult:V4HI (match_operand:V4QI 1 "register_operand" "f")
8214 (match_operand:V4HI 2 "register_operand" "e")))]
8216 "fmul8x16\t%1, %2, %0"
8217 [(set_attr "type" "fpmul")
8218 (set_attr "fptype" "double")])
8220 ;; Only one of the following two insns can be a multiply.
8221 (define_insn "fmul8x16au_vis"
8222 [(set (match_operand:V4HI 0 "register_operand" "=e")
8223 (mult:V4HI (match_operand:V4QI 1 "register_operand" "f")
8224 (match_operand:V2HI 2 "register_operand" "f")))]
8226 "fmul8x16au\t%1, %2, %0"
8227 [(set_attr "type" "fpmul")
8228 (set_attr "fptype" "double")])
8230 (define_insn "fmul8x16al_vis"
8231 [(set (match_operand:V4HI 0 "register_operand" "=e")
8232 (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")
8233 (match_operand:V2HI 2 "register_operand" "f")]
8236 "fmul8x16al\t%1, %2, %0"
8237 [(set_attr "type" "fpmul")
8238 (set_attr "fptype" "double")])
8240 ;; Only one of the following two insns can be a multiply.
8241 (define_insn "fmul8sux16_vis"
8242 [(set (match_operand:V4HI 0 "register_operand" "=e")
8243 (mult:V4HI (match_operand:V8QI 1 "register_operand" "e")
8244 (match_operand:V4HI 2 "register_operand" "e")))]
8246 "fmul8sux16\t%1, %2, %0"
8247 [(set_attr "type" "fpmul")
8248 (set_attr "fptype" "double")])
8250 (define_insn "fmul8ulx16_vis"
8251 [(set (match_operand:V4HI 0 "register_operand" "=e")
8252 (unspec:V4HI [(match_operand:V8QI 1 "register_operand" "e")
8253 (match_operand:V4HI 2 "register_operand" "e")]
8256 "fmul8ulx16\t%1, %2, %0"
8257 [(set_attr "type" "fpmul")
8258 (set_attr "fptype" "double")])
8260 ;; Only one of the following two insns can be a multiply.
8261 (define_insn "fmuld8sux16_vis"
8262 [(set (match_operand:V2SI 0 "register_operand" "=e")
8263 (mult:V2SI (match_operand:V4QI 1 "register_operand" "f")
8264 (match_operand:V2HI 2 "register_operand" "f")))]
8266 "fmuld8sux16\t%1, %2, %0"
8267 [(set_attr "type" "fpmul")
8268 (set_attr "fptype" "double")])
8270 (define_insn "fmuld8ulx16_vis"
8271 [(set (match_operand:V2SI 0 "register_operand" "=e")
8272 (unspec:V2SI [(match_operand:V4QI 1 "register_operand" "f")
8273 (match_operand:V2HI 2 "register_operand" "f")]
8276 "fmuld8ulx16\t%1, %2, %0"
8277 [(set_attr "type" "fpmul")
8278 (set_attr "fptype" "double")])
8280 ;; Using faligndata only makes sense after an alignaddr since the choice of
8281 ;; bytes to take out of each operand is dependent on the results of the last
8283 (define_insn "faligndata<V64I:mode>_vis"
8284 [(set (match_operand:V64I 0 "register_operand" "=e")
8285 (unspec:V64I [(match_operand:V64I 1 "register_operand" "e")
8286 (match_operand:V64I 2 "register_operand" "e")]
8289 "faligndata\t%1, %2, %0"
8290 [(set_attr "type" "fga")
8291 (set_attr "fptype" "double")])
8293 (define_insn "alignaddr<P:mode>_vis"
8294 [(set (match_operand:P 0 "register_operand" "=r")
8295 (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
8296 (match_operand:P 2 "register_or_zero_operand" "rJ")]
8299 "alignaddr\t%r1, %r2, %0")
8301 (define_insn "pdist_vis"
8302 [(set (match_operand:DI 0 "register_operand" "=e")
8303 (unspec:DI [(match_operand:V8QI 1 "register_operand" "e")
8304 (match_operand:V8QI 2 "register_operand" "e")
8305 (match_operand:DI 3 "register_operand" "0")]
8309 [(set_attr "type" "fga")
8310 (set_attr "fptype" "double")])