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 (define_expand "divsi3"
4899 [(parallel [(set (match_operand:SI 0 "register_operand" "")
4900 (div:SI (match_operand:SI 1 "register_operand" "")
4901 (match_operand:SI 2 "input_operand" "")))
4902 (clobber (match_scratch:SI 3 ""))])]
4903 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4907 operands[3] = gen_reg_rtx(SImode);
4908 emit_insn (gen_ashrsi3 (operands[3], operands[1], GEN_INT (31)));
4909 emit_insn (gen_divsi3_sp64 (operands[0], operands[1], operands[2],
4915 ;; The V8 architecture specifies that there must be at least 3 instructions
4916 ;; between a write to the Y register and a use of it for correct results.
4917 ;; We try to fill one of them with a simple constant or a memory load.
4919 (define_insn "divsi3_sp32"
4920 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
4921 (div:SI (match_operand:SI 1 "register_operand" "r,r,r")
4922 (match_operand:SI 2 "input_operand" "rI,K,m")))
4923 (clobber (match_scratch:SI 3 "=&r,&r,&r"))]
4924 "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS) && TARGET_ARCH32"
4926 output_asm_insn ("sra\t%1, 31, %3", operands);
4927 output_asm_insn ("wr\t%3, 0, %%y", operands);
4929 switch (which_alternative)
4933 return "sdiv\t%1, %2, %0";
4935 return "nop\n\tnop\n\tnop\n\tsdiv\t%1, %2, %0";
4938 return "sethi\t%%hi(%a2), %3\n\tsdiv\t%1, %3, %0";
4940 return "sethi\t%%hi(%a2), %3\n\tnop\n\tnop\n\tsdiv\t%1, %3, %0";
4943 return "ld\t%2, %3\n\tsdiv\t%1, %3, %0";
4945 return "ld\t%2, %3\n\tnop\n\tnop\n\tsdiv\t%1, %3, %0";
4950 [(set_attr "type" "multi")
4951 (set (attr "length")
4952 (if_then_else (eq_attr "isa" "v9")
4953 (const_int 4) (const_int 6)))])
4955 (define_insn "divsi3_sp64"
4956 [(set (match_operand:SI 0 "register_operand" "=r")
4957 (div:SI (match_operand:SI 1 "register_operand" "r")
4958 (match_operand:SI 2 "input_operand" "rI")))
4959 (use (match_operand:SI 3 "register_operand" "r"))]
4960 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4961 "wr\t%%g0, %3, %%y\n\tsdiv\t%1, %2, %0"
4962 [(set_attr "type" "multi")
4963 (set_attr "length" "2")])
4965 (define_insn "divdi3"
4966 [(set (match_operand:DI 0 "register_operand" "=r")
4967 (div:DI (match_operand:DI 1 "register_operand" "r")
4968 (match_operand:DI 2 "arith_operand" "rI")))]
4971 [(set_attr "type" "idiv")])
4973 (define_insn "*cmp_sdiv_cc_set"
4975 (compare:CC (div:SI (match_operand:SI 1 "register_operand" "r")
4976 (match_operand:SI 2 "arith_operand" "rI"))
4978 (set (match_operand:SI 0 "register_operand" "=r")
4979 (div:SI (match_dup 1) (match_dup 2)))
4980 (clobber (match_scratch:SI 3 "=&r"))]
4981 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4983 output_asm_insn ("sra\t%1, 31, %3", operands);
4984 output_asm_insn ("wr\t%3, 0, %%y", operands);
4987 return "sdivcc\t%1, %2, %0";
4989 return "nop\n\tnop\n\tnop\n\tsdivcc\t%1, %2, %0";
4991 [(set_attr "type" "multi")
4992 (set (attr "length")
4993 (if_then_else (eq_attr "isa" "v9")
4994 (const_int 3) (const_int 6)))])
4997 (define_expand "udivsi3"
4998 [(set (match_operand:SI 0 "register_operand" "")
4999 (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "")
5000 (match_operand:SI 2 "input_operand" "")))]
5001 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
5004 ;; The V8 architecture specifies that there must be at least 3 instructions
5005 ;; between a write to the Y register and a use of it for correct results.
5006 ;; We try to fill one of them with a simple constant or a memory load.
5008 (define_insn "udivsi3_sp32"
5009 [(set (match_operand:SI 0 "register_operand" "=r,&r,&r,&r")
5010 (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "r,r,r,m")
5011 (match_operand:SI 2 "input_operand" "rI,K,m,r")))]
5012 "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS) && TARGET_ARCH32"
5014 output_asm_insn ("wr\t%%g0, 0, %%y", operands);
5016 switch (which_alternative)
5020 return "udiv\t%1, %2, %0";
5022 return "nop\n\tnop\n\tnop\n\tudiv\t%1, %2, %0";
5025 return "sethi\t%%hi(%a2), %0\n\tudiv\t%1, %0, %0";
5027 return "sethi\t%%hi(%a2), %0\n\tnop\n\tnop\n\tudiv\t%1, %0, %0";
5030 return "ld\t%2, %0\n\tudiv\t%1, %0, %0";
5032 return "ld\t%2, %0\n\tnop\n\tnop\n\tudiv\t%1, %0, %0";
5035 return "ld\t%1, %0\n\tudiv\t%0, %2, %0";
5037 return "ld\t%1, %0\n\tnop\n\tnop\n\tudiv\t%0, %2, %0";
5042 [(set_attr "type" "multi")
5043 (set (attr "length")
5044 (if_then_else (eq_attr "isa" "v9")
5045 (const_int 3) (const_int 5)))])
5047 (define_insn "udivsi3_sp64"
5048 [(set (match_operand:SI 0 "register_operand" "=r")
5049 (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "r")
5050 (match_operand:SI 2 "input_operand" "rI")))]
5051 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5052 "wr\t%%g0, 0, %%y\n\tudiv\t%1, %2, %0"
5053 [(set_attr "type" "multi")
5054 (set_attr "length" "2")])
5056 (define_insn "udivdi3"
5057 [(set (match_operand:DI 0 "register_operand" "=r")
5058 (udiv:DI (match_operand:DI 1 "register_operand" "r")
5059 (match_operand:DI 2 "arith_operand" "rI")))]
5062 [(set_attr "type" "idiv")])
5064 (define_insn "*cmp_udiv_cc_set"
5066 (compare:CC (udiv:SI (match_operand:SI 1 "register_operand" "r")
5067 (match_operand:SI 2 "arith_operand" "rI"))
5069 (set (match_operand:SI 0 "register_operand" "=r")
5070 (udiv:SI (match_dup 1) (match_dup 2)))]
5071 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
5073 output_asm_insn ("wr\t%%g0, 0, %%y", operands);
5076 return "udivcc\t%1, %2, %0";
5078 return "nop\n\tnop\n\tnop\n\tudivcc\t%1, %2, %0";
5080 [(set_attr "type" "multi")
5081 (set (attr "length")
5082 (if_then_else (eq_attr "isa" "v9")
5083 (const_int 2) (const_int 5)))])
5085 ; sparclet multiply/accumulate insns
5087 (define_insn "*smacsi"
5088 [(set (match_operand:SI 0 "register_operand" "=r")
5089 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "%r")
5090 (match_operand:SI 2 "arith_operand" "rI"))
5091 (match_operand:SI 3 "register_operand" "0")))]
5094 [(set_attr "type" "imul")])
5096 (define_insn "*smacdi"
5097 [(set (match_operand:DI 0 "register_operand" "=r")
5098 (plus:DI (mult:DI (sign_extend:DI
5099 (match_operand:SI 1 "register_operand" "%r"))
5101 (match_operand:SI 2 "register_operand" "r")))
5102 (match_operand:DI 3 "register_operand" "0")))]
5104 "smacd\t%1, %2, %L0"
5105 [(set_attr "type" "imul")])
5107 (define_insn "*umacdi"
5108 [(set (match_operand:DI 0 "register_operand" "=r")
5109 (plus:DI (mult:DI (zero_extend:DI
5110 (match_operand:SI 1 "register_operand" "%r"))
5112 (match_operand:SI 2 "register_operand" "r")))
5113 (match_operand:DI 3 "register_operand" "0")))]
5115 "umacd\t%1, %2, %L0"
5116 [(set_attr "type" "imul")])
5119 ;; Boolean instructions.
5121 ;; We define DImode `and' so with DImode `not' we can get
5122 ;; DImode `andn'. Other combinations are possible.
5124 (define_mode_iterator V64I [DI V2SI V4HI V8QI])
5125 (define_mode_iterator V32I [SI V2HI V4QI])
5127 (define_expand "and<V64I:mode>3"
5128 [(set (match_operand:V64I 0 "register_operand" "")
5129 (and:V64I (match_operand:V64I 1 "arith_double_operand" "")
5130 (match_operand:V64I 2 "arith_double_operand" "")))]
5134 (define_insn "*and<V64I:mode>3_sp32"
5135 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5136 (and:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
5137 (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
5142 [(set_attr "type" "*,fga")
5143 (set_attr "length" "2,*")
5144 (set_attr "fptype" "*,double")])
5146 (define_insn "*and<V64I:mode>3_sp64"
5147 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5148 (and:V64I (match_operand:V64I 1 "arith_operand" "%r,b")
5149 (match_operand:V64I 2 "arith_operand" "rI,b")))]
5154 [(set_attr "type" "*,fga")
5155 (set_attr "fptype" "*,double")])
5157 (define_insn "and<V32I:mode>3"
5158 [(set (match_operand:V32I 0 "register_operand" "=r,d")
5159 (and:V32I (match_operand:V32I 1 "arith_operand" "%r,d")
5160 (match_operand:V32I 2 "arith_operand" "rI,d")))]
5165 [(set_attr "type" "*,fga")
5166 (set_attr "fptype" "*,single")])
5169 [(set (match_operand:SI 0 "register_operand" "")
5170 (and:SI (match_operand:SI 1 "register_operand" "")
5171 (match_operand:SI 2 "const_compl_high_operand" "")))
5172 (clobber (match_operand:SI 3 "register_operand" ""))]
5174 [(set (match_dup 3) (match_dup 4))
5175 (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 1)))]
5177 operands[4] = GEN_INT (~INTVAL (operands[2]));
5180 (define_insn_and_split "*and_not_<V64I:mode>_sp32"
5181 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5182 (and:V64I (not:V64I (match_operand:V64I 1 "register_operand" "%r,b"))
5183 (match_operand:V64I 2 "register_operand" "r,b")))]
5187 fandnot1\t%1, %2, %0"
5188 "&& reload_completed
5189 && ((GET_CODE (operands[0]) == REG
5190 && REGNO (operands[0]) < 32)
5191 || (GET_CODE (operands[0]) == SUBREG
5192 && GET_CODE (SUBREG_REG (operands[0])) == REG
5193 && REGNO (SUBREG_REG (operands[0])) < 32))"
5194 [(set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))
5195 (set (match_dup 6) (and:SI (not:SI (match_dup 7)) (match_dup 8)))]
5196 "operands[3] = gen_highpart (SImode, operands[0]);
5197 operands[4] = gen_highpart (SImode, operands[1]);
5198 operands[5] = gen_highpart (SImode, operands[2]);
5199 operands[6] = gen_lowpart (SImode, operands[0]);
5200 operands[7] = gen_lowpart (SImode, operands[1]);
5201 operands[8] = gen_lowpart (SImode, operands[2]);"
5202 [(set_attr "type" "*,fga")
5203 (set_attr "length" "2,*")
5204 (set_attr "fptype" "*,double")])
5206 (define_insn "*and_not_<V64I:mode>_sp64"
5207 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5208 (and:V64I (not:V64I (match_operand:V64I 1 "register_operand" "%r,b"))
5209 (match_operand:V64I 2 "register_operand" "r,b")))]
5213 fandnot1\t%1, %2, %0"
5214 [(set_attr "type" "*,fga")
5215 (set_attr "fptype" "*,double")])
5217 (define_insn "*and_not_<V32I:mode>"
5218 [(set (match_operand:V32I 0 "register_operand" "=r,d")
5219 (and:V32I (not:V32I (match_operand:V32I 1 "register_operand" "%r,d"))
5220 (match_operand:V32I 2 "register_operand" "r,d")))]
5224 fandnot1s\t%1, %2, %0"
5225 [(set_attr "type" "*,fga")
5226 (set_attr "fptype" "*,single")])
5228 (define_expand "ior<V64I:mode>3"
5229 [(set (match_operand:V64I 0 "register_operand" "")
5230 (ior:V64I (match_operand:V64I 1 "arith_double_operand" "")
5231 (match_operand:V64I 2 "arith_double_operand" "")))]
5235 (define_insn "*ior<V64I:mode>3_sp32"
5236 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5237 (ior:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
5238 (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
5243 [(set_attr "type" "*,fga")
5244 (set_attr "length" "2,*")
5245 (set_attr "fptype" "*,double")])
5247 (define_insn "*ior<V64I:mode>3_sp64"
5248 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5249 (ior:V64I (match_operand:V64I 1 "arith_operand" "%r,b")
5250 (match_operand:V64I 2 "arith_operand" "rI,b")))]
5255 [(set_attr "type" "*,fga")
5256 (set_attr "fptype" "*,double")])
5258 (define_insn "ior<V32I:mode>3"
5259 [(set (match_operand:V32I 0 "register_operand" "=r,d")
5260 (ior:V32I (match_operand:V32I 1 "arith_operand" "%r,d")
5261 (match_operand:V32I 2 "arith_operand" "rI,d")))]
5266 [(set_attr "type" "*,fga")
5267 (set_attr "fptype" "*,single")])
5270 [(set (match_operand:SI 0 "register_operand" "")
5271 (ior:SI (match_operand:SI 1 "register_operand" "")
5272 (match_operand:SI 2 "const_compl_high_operand" "")))
5273 (clobber (match_operand:SI 3 "register_operand" ""))]
5275 [(set (match_dup 3) (match_dup 4))
5276 (set (match_dup 0) (ior:SI (not:SI (match_dup 3)) (match_dup 1)))]
5278 operands[4] = GEN_INT (~INTVAL (operands[2]));
5281 (define_insn_and_split "*or_not_<V64I:mode>_sp32"
5282 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5283 (ior:V64I (not:V64I (match_operand:V64I 1 "register_operand" "r,b"))
5284 (match_operand:V64I 2 "register_operand" "r,b")))]
5288 fornot1\t%1, %2, %0"
5289 "&& reload_completed
5290 && ((GET_CODE (operands[0]) == REG
5291 && REGNO (operands[0]) < 32)
5292 || (GET_CODE (operands[0]) == SUBREG
5293 && GET_CODE (SUBREG_REG (operands[0])) == REG
5294 && REGNO (SUBREG_REG (operands[0])) < 32))"
5295 [(set (match_dup 3) (ior:SI (not:SI (match_dup 4)) (match_dup 5)))
5296 (set (match_dup 6) (ior:SI (not:SI (match_dup 7)) (match_dup 8)))]
5297 "operands[3] = gen_highpart (SImode, operands[0]);
5298 operands[4] = gen_highpart (SImode, operands[1]);
5299 operands[5] = gen_highpart (SImode, operands[2]);
5300 operands[6] = gen_lowpart (SImode, operands[0]);
5301 operands[7] = gen_lowpart (SImode, operands[1]);
5302 operands[8] = gen_lowpart (SImode, operands[2]);"
5303 [(set_attr "type" "*,fga")
5304 (set_attr "length" "2,*")
5305 (set_attr "fptype" "*,double")])
5307 (define_insn "*or_not_<V64I:mode>_sp64"
5308 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5309 (ior:V64I (not:V64I (match_operand:V64I 1 "register_operand" "r,b"))
5310 (match_operand:V64I 2 "register_operand" "r,b")))]
5314 fornot1\t%1, %2, %0"
5315 [(set_attr "type" "*,fga")
5316 (set_attr "fptype" "*,double")])
5318 (define_insn "*or_not_<V32I:mode>"
5319 [(set (match_operand:V32I 0 "register_operand" "=r,d")
5320 (ior:V32I (not:V32I (match_operand:V32I 1 "register_operand" "r,d"))
5321 (match_operand:V32I 2 "register_operand" "r,d")))]
5325 fornot1s\t%1, %2, %0"
5326 [(set_attr "type" "*,fga")
5327 (set_attr "fptype" "*,single")])
5329 (define_expand "xor<V64I:mode>3"
5330 [(set (match_operand:V64I 0 "register_operand" "")
5331 (xor:V64I (match_operand:V64I 1 "arith_double_operand" "")
5332 (match_operand:V64I 2 "arith_double_operand" "")))]
5336 (define_insn "*xor<V64I:mode>3_sp32"
5337 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5338 (xor:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
5339 (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
5344 [(set_attr "type" "*,fga")
5345 (set_attr "length" "2,*")
5346 (set_attr "fptype" "*,double")])
5348 (define_insn "*xor<V64I:mode>3_sp64"
5349 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5350 (xor:V64I (match_operand:V64I 1 "arith_operand" "%rJ,b")
5351 (match_operand:V64I 2 "arith_operand" "rI,b")))]
5356 [(set_attr "type" "*,fga")
5357 (set_attr "fptype" "*,double")])
5359 (define_insn "xor<V32I:mode>3"
5360 [(set (match_operand:V32I 0 "register_operand" "=r,d")
5361 (xor:V32I (match_operand:V32I 1 "arith_operand" "%rJ,d")
5362 (match_operand:V32I 2 "arith_operand" "rI,d")))]
5367 [(set_attr "type" "*,fga")
5368 (set_attr "fptype" "*,single")])
5371 [(set (match_operand:SI 0 "register_operand" "")
5372 (xor:SI (match_operand:SI 1 "register_operand" "")
5373 (match_operand:SI 2 "const_compl_high_operand" "")))
5374 (clobber (match_operand:SI 3 "register_operand" ""))]
5376 [(set (match_dup 3) (match_dup 4))
5377 (set (match_dup 0) (not:SI (xor:SI (match_dup 3) (match_dup 1))))]
5379 operands[4] = GEN_INT (~INTVAL (operands[2]));
5383 [(set (match_operand:SI 0 "register_operand" "")
5384 (not:SI (xor:SI (match_operand:SI 1 "register_operand" "")
5385 (match_operand:SI 2 "const_compl_high_operand" ""))))
5386 (clobber (match_operand:SI 3 "register_operand" ""))]
5388 [(set (match_dup 3) (match_dup 4))
5389 (set (match_dup 0) (xor:SI (match_dup 3) (match_dup 1)))]
5391 operands[4] = GEN_INT (~INTVAL (operands[2]));
5394 ;; Split DImode logical operations requiring two instructions.
5396 [(set (match_operand:V64I 0 "register_operand" "")
5397 (match_operator:V64I 1 "cc_arith_operator" ; AND, IOR, XOR
5398 [(match_operand:V64I 2 "register_operand" "")
5399 (match_operand:V64I 3 "arith_double_operand" "")]))]
5402 && ((GET_CODE (operands[0]) == REG
5403 && REGNO (operands[0]) < 32)
5404 || (GET_CODE (operands[0]) == SUBREG
5405 && GET_CODE (SUBREG_REG (operands[0])) == REG
5406 && REGNO (SUBREG_REG (operands[0])) < 32))"
5407 [(set (match_dup 4) (match_op_dup:SI 1 [(match_dup 6) (match_dup 8)]))
5408 (set (match_dup 5) (match_op_dup:SI 1 [(match_dup 7) (match_dup 9)]))]
5410 operands[4] = gen_highpart (SImode, operands[0]);
5411 operands[5] = gen_lowpart (SImode, operands[0]);
5412 operands[6] = gen_highpart (SImode, operands[2]);
5413 operands[7] = gen_lowpart (SImode, operands[2]);
5414 #if HOST_BITS_PER_WIDE_INT == 32
5415 if (GET_CODE (operands[3]) == CONST_INT && <V64I:MODE>mode == DImode)
5417 if (INTVAL (operands[3]) < 0)
5418 operands[8] = constm1_rtx;
5420 operands[8] = const0_rtx;
5424 operands[8] = gen_highpart_mode (SImode, <V64I:MODE>mode, operands[3]);
5425 operands[9] = gen_lowpart (SImode, operands[3]);
5428 ;; xnor patterns. Note that (a ^ ~b) == (~a ^ b) == ~(a ^ b).
5429 ;; Combine now canonicalizes to the rightmost expression.
5430 (define_insn_and_split "*xor_not_<V64I:mode>_sp32"
5431 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5432 (not:V64I (xor:V64I (match_operand:V64I 1 "register_operand" "r,b")
5433 (match_operand:V64I 2 "register_operand" "r,b"))))]
5438 "&& reload_completed
5439 && ((GET_CODE (operands[0]) == REG
5440 && REGNO (operands[0]) < 32)
5441 || (GET_CODE (operands[0]) == SUBREG
5442 && GET_CODE (SUBREG_REG (operands[0])) == REG
5443 && REGNO (SUBREG_REG (operands[0])) < 32))"
5444 [(set (match_dup 3) (not:SI (xor:SI (match_dup 4) (match_dup 5))))
5445 (set (match_dup 6) (not:SI (xor:SI (match_dup 7) (match_dup 8))))]
5446 "operands[3] = gen_highpart (SImode, operands[0]);
5447 operands[4] = gen_highpart (SImode, operands[1]);
5448 operands[5] = gen_highpart (SImode, operands[2]);
5449 operands[6] = gen_lowpart (SImode, operands[0]);
5450 operands[7] = gen_lowpart (SImode, operands[1]);
5451 operands[8] = gen_lowpart (SImode, operands[2]);"
5452 [(set_attr "type" "*,fga")
5453 (set_attr "length" "2,*")
5454 (set_attr "fptype" "*,double")])
5456 (define_insn "*xor_not_<V64I:mode>_sp64"
5457 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5458 (not:V64I (xor:V64I (match_operand:V64I 1 "register_or_zero_operand" "rJ,b")
5459 (match_operand:V64I 2 "arith_operand" "rI,b"))))]
5464 [(set_attr "type" "*,fga")
5465 (set_attr "fptype" "*,double")])
5467 (define_insn "*xor_not_<V32I:mode>"
5468 [(set (match_operand:V32I 0 "register_operand" "=r,d")
5469 (not:V32I (xor:V32I (match_operand:V32I 1 "register_or_zero_operand" "rJ,d")
5470 (match_operand:V32I 2 "arith_operand" "rI,d"))))]
5475 [(set_attr "type" "*,fga")
5476 (set_attr "fptype" "*,single")])
5478 ;; These correspond to the above in the case where we also (or only)
5479 ;; want to set the condition code.
5481 (define_insn "*cmp_cc_arith_op"
5484 (match_operator:SI 2 "cc_arith_operator"
5485 [(match_operand:SI 0 "arith_operand" "%r")
5486 (match_operand:SI 1 "arith_operand" "rI")])
5489 "%A2cc\t%0, %1, %%g0"
5490 [(set_attr "type" "compare")])
5492 (define_insn "*cmp_ccx_arith_op"
5495 (match_operator:DI 2 "cc_arith_operator"
5496 [(match_operand:DI 0 "arith_operand" "%r")
5497 (match_operand:DI 1 "arith_operand" "rI")])
5500 "%A2cc\t%0, %1, %%g0"
5501 [(set_attr "type" "compare")])
5503 (define_insn "*cmp_cc_arith_op_set"
5506 (match_operator:SI 3 "cc_arith_operator"
5507 [(match_operand:SI 1 "arith_operand" "%r")
5508 (match_operand:SI 2 "arith_operand" "rI")])
5510 (set (match_operand:SI 0 "register_operand" "=r")
5511 (match_operator:SI 4 "cc_arith_operator" [(match_dup 1) (match_dup 2)]))]
5512 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
5514 [(set_attr "type" "compare")])
5516 (define_insn "*cmp_ccx_arith_op_set"
5519 (match_operator:DI 3 "cc_arith_operator"
5520 [(match_operand:DI 1 "arith_operand" "%r")
5521 (match_operand:DI 2 "arith_operand" "rI")])
5523 (set (match_operand:DI 0 "register_operand" "=r")
5524 (match_operator:DI 4 "cc_arith_operator" [(match_dup 1) (match_dup 2)]))]
5525 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
5527 [(set_attr "type" "compare")])
5529 (define_insn "*cmp_cc_xor_not"
5532 (not:SI (xor:SI (match_operand:SI 0 "register_or_zero_operand" "%rJ")
5533 (match_operand:SI 1 "arith_operand" "rI")))
5536 "xnorcc\t%r0, %1, %%g0"
5537 [(set_attr "type" "compare")])
5539 (define_insn "*cmp_ccx_xor_not"
5542 (not:DI (xor:DI (match_operand:DI 0 "register_or_zero_operand" "%rJ")
5543 (match_operand:DI 1 "arith_operand" "rI")))
5546 "xnorcc\t%r0, %1, %%g0"
5547 [(set_attr "type" "compare")])
5549 (define_insn "*cmp_cc_xor_not_set"
5552 (not:SI (xor:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ")
5553 (match_operand:SI 2 "arith_operand" "rI")))
5555 (set (match_operand:SI 0 "register_operand" "=r")
5556 (not:SI (xor:SI (match_dup 1) (match_dup 2))))]
5558 "xnorcc\t%r1, %2, %0"
5559 [(set_attr "type" "compare")])
5561 (define_insn "*cmp_ccx_xor_not_set"
5564 (not:DI (xor:DI (match_operand:DI 1 "register_or_zero_operand" "%rJ")
5565 (match_operand:DI 2 "arith_operand" "rI")))
5567 (set (match_operand:DI 0 "register_operand" "=r")
5568 (not:DI (xor:DI (match_dup 1) (match_dup 2))))]
5570 "xnorcc\t%r1, %2, %0"
5571 [(set_attr "type" "compare")])
5573 (define_insn "*cmp_cc_arith_op_not"
5576 (match_operator:SI 2 "cc_arith_not_operator"
5577 [(not:SI (match_operand:SI 0 "arith_operand" "rI"))
5578 (match_operand:SI 1 "register_or_zero_operand" "rJ")])
5581 "%B2cc\t%r1, %0, %%g0"
5582 [(set_attr "type" "compare")])
5584 (define_insn "*cmp_ccx_arith_op_not"
5587 (match_operator:DI 2 "cc_arith_not_operator"
5588 [(not:DI (match_operand:DI 0 "arith_operand" "rI"))
5589 (match_operand:DI 1 "register_or_zero_operand" "rJ")])
5592 "%B2cc\t%r1, %0, %%g0"
5593 [(set_attr "type" "compare")])
5595 (define_insn "*cmp_cc_arith_op_not_set"
5598 (match_operator:SI 3 "cc_arith_not_operator"
5599 [(not:SI (match_operand:SI 1 "arith_operand" "rI"))
5600 (match_operand:SI 2 "register_or_zero_operand" "rJ")])
5602 (set (match_operand:SI 0 "register_operand" "=r")
5603 (match_operator:SI 4 "cc_arith_not_operator"
5604 [(not:SI (match_dup 1)) (match_dup 2)]))]
5605 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
5606 "%B3cc\t%r2, %1, %0"
5607 [(set_attr "type" "compare")])
5609 (define_insn "*cmp_ccx_arith_op_not_set"
5612 (match_operator:DI 3 "cc_arith_not_operator"
5613 [(not:DI (match_operand:DI 1 "arith_operand" "rI"))
5614 (match_operand:DI 2 "register_or_zero_operand" "rJ")])
5616 (set (match_operand:DI 0 "register_operand" "=r")
5617 (match_operator:DI 4 "cc_arith_not_operator"
5618 [(not:DI (match_dup 1)) (match_dup 2)]))]
5619 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
5620 "%B3cc\t%r2, %1, %0"
5621 [(set_attr "type" "compare")])
5623 ;; We cannot use the "neg" pseudo insn because the Sun assembler
5624 ;; does not know how to make it work for constants.
5626 (define_expand "negdi2"
5627 [(set (match_operand:DI 0 "register_operand" "=r")
5628 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
5631 if (! TARGET_ARCH64)
5633 emit_insn (gen_rtx_PARALLEL
5636 gen_rtx_SET (VOIDmode, operand0,
5637 gen_rtx_NEG (DImode, operand1)),
5638 gen_rtx_CLOBBER (VOIDmode,
5639 gen_rtx_REG (CCmode,
5645 (define_insn_and_split "*negdi2_sp32"
5646 [(set (match_operand:DI 0 "register_operand" "=r")
5647 (neg:DI (match_operand:DI 1 "register_operand" "r")))
5648 (clobber (reg:CC 100))]
5651 "&& reload_completed"
5652 [(parallel [(set (reg:CC_NOOV 100)
5653 (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 5))
5655 (set (match_dup 4) (minus:SI (const_int 0) (match_dup 5)))])
5656 (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
5657 (ltu:SI (reg:CC 100) (const_int 0))))]
5658 "operands[2] = gen_highpart (SImode, operands[0]);
5659 operands[3] = gen_highpart (SImode, operands[1]);
5660 operands[4] = gen_lowpart (SImode, operands[0]);
5661 operands[5] = gen_lowpart (SImode, operands[1]);"
5662 [(set_attr "length" "2")])
5664 (define_insn "*negdi2_sp64"
5665 [(set (match_operand:DI 0 "register_operand" "=r")
5666 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
5668 "sub\t%%g0, %1, %0")
5670 (define_insn "negsi2"
5671 [(set (match_operand:SI 0 "register_operand" "=r")
5672 (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
5674 "sub\t%%g0, %1, %0")
5676 (define_insn "*cmp_cc_neg"
5677 [(set (reg:CC_NOOV 100)
5678 (compare:CC_NOOV (neg:SI (match_operand:SI 0 "arith_operand" "rI"))
5681 "subcc\t%%g0, %0, %%g0"
5682 [(set_attr "type" "compare")])
5684 (define_insn "*cmp_ccx_neg"
5685 [(set (reg:CCX_NOOV 100)
5686 (compare:CCX_NOOV (neg:DI (match_operand:DI 0 "arith_operand" "rI"))
5689 "subcc\t%%g0, %0, %%g0"
5690 [(set_attr "type" "compare")])
5692 (define_insn "*cmp_cc_set_neg"
5693 [(set (reg:CC_NOOV 100)
5694 (compare:CC_NOOV (neg:SI (match_operand:SI 1 "arith_operand" "rI"))
5696 (set (match_operand:SI 0 "register_operand" "=r")
5697 (neg:SI (match_dup 1)))]
5699 "subcc\t%%g0, %1, %0"
5700 [(set_attr "type" "compare")])
5702 (define_insn "*cmp_ccx_set_neg"
5703 [(set (reg:CCX_NOOV 100)
5704 (compare:CCX_NOOV (neg:DI (match_operand:DI 1 "arith_operand" "rI"))
5706 (set (match_operand:DI 0 "register_operand" "=r")
5707 (neg:DI (match_dup 1)))]
5709 "subcc\t%%g0, %1, %0"
5710 [(set_attr "type" "compare")])
5712 ;; We cannot use the "not" pseudo insn because the Sun assembler
5713 ;; does not know how to make it work for constants.
5714 (define_expand "one_cmpl<V64I:mode>2"
5715 [(set (match_operand:V64I 0 "register_operand" "")
5716 (not:V64I (match_operand:V64I 1 "register_operand" "")))]
5720 (define_insn_and_split "*one_cmpl<V64I:mode>2_sp32"
5721 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5722 (not:V64I (match_operand:V64I 1 "register_operand" "r,b")))]
5727 "&& reload_completed
5728 && ((GET_CODE (operands[0]) == REG
5729 && REGNO (operands[0]) < 32)
5730 || (GET_CODE (operands[0]) == SUBREG
5731 && GET_CODE (SUBREG_REG (operands[0])) == REG
5732 && REGNO (SUBREG_REG (operands[0])) < 32))"
5733 [(set (match_dup 2) (not:SI (xor:SI (match_dup 3) (const_int 0))))
5734 (set (match_dup 4) (not:SI (xor:SI (match_dup 5) (const_int 0))))]
5735 "operands[2] = gen_highpart (SImode, operands[0]);
5736 operands[3] = gen_highpart (SImode, operands[1]);
5737 operands[4] = gen_lowpart (SImode, operands[0]);
5738 operands[5] = gen_lowpart (SImode, operands[1]);"
5739 [(set_attr "type" "*,fga")
5740 (set_attr "length" "2,*")
5741 (set_attr "fptype" "*,double")])
5743 (define_insn "*one_cmpl<V64I:mode>2_sp64"
5744 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5745 (not:V64I (match_operand:V64I 1 "arith_operand" "rI,b")))]
5750 [(set_attr "type" "*,fga")
5751 (set_attr "fptype" "*,double")])
5753 (define_insn "one_cmpl<V32I:mode>2"
5754 [(set (match_operand:V32I 0 "register_operand" "=r,d")
5755 (not:V32I (match_operand:V32I 1 "arith_operand" "rI,d")))]
5760 [(set_attr "type" "*,fga")
5761 (set_attr "fptype" "*,single")])
5763 (define_insn "*cmp_cc_not"
5765 (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI"))
5768 "xnorcc\t%%g0, %0, %%g0"
5769 [(set_attr "type" "compare")])
5771 (define_insn "*cmp_ccx_not"
5773 (compare:CCX (not:DI (match_operand:DI 0 "arith_operand" "rI"))
5776 "xnorcc\t%%g0, %0, %%g0"
5777 [(set_attr "type" "compare")])
5779 (define_insn "*cmp_cc_set_not"
5781 (compare:CC (not:SI (match_operand:SI 1 "arith_operand" "rI"))
5783 (set (match_operand:SI 0 "register_operand" "=r")
5784 (not:SI (match_dup 1)))]
5786 "xnorcc\t%%g0, %1, %0"
5787 [(set_attr "type" "compare")])
5789 (define_insn "*cmp_ccx_set_not"
5791 (compare:CCX (not:DI (match_operand:DI 1 "arith_operand" "rI"))
5793 (set (match_operand:DI 0 "register_operand" "=r")
5794 (not:DI (match_dup 1)))]
5796 "xnorcc\t%%g0, %1, %0"
5797 [(set_attr "type" "compare")])
5799 (define_insn "*cmp_cc_set"
5800 [(set (match_operand:SI 0 "register_operand" "=r")
5801 (match_operand:SI 1 "register_operand" "r"))
5803 (compare:CC (match_dup 1)
5807 [(set_attr "type" "compare")])
5809 (define_insn "*cmp_ccx_set64"
5810 [(set (match_operand:DI 0 "register_operand" "=r")
5811 (match_operand:DI 1 "register_operand" "r"))
5813 (compare:CCX (match_dup 1)
5817 [(set_attr "type" "compare")])
5820 ;; Floating point arithmetic instructions.
5822 (define_expand "addtf3"
5823 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5824 (plus:TF (match_operand:TF 1 "general_operand" "")
5825 (match_operand:TF 2 "general_operand" "")))]
5826 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5827 "emit_tfmode_binop (PLUS, operands); DONE;")
5829 (define_insn "*addtf3_hq"
5830 [(set (match_operand:TF 0 "register_operand" "=e")
5831 (plus:TF (match_operand:TF 1 "register_operand" "e")
5832 (match_operand:TF 2 "register_operand" "e")))]
5833 "TARGET_FPU && TARGET_HARD_QUAD"
5835 [(set_attr "type" "fp")])
5837 (define_insn "adddf3"
5838 [(set (match_operand:DF 0 "register_operand" "=e")
5839 (plus:DF (match_operand:DF 1 "register_operand" "e")
5840 (match_operand:DF 2 "register_operand" "e")))]
5843 [(set_attr "type" "fp")
5844 (set_attr "fptype" "double")])
5846 (define_insn "addsf3"
5847 [(set (match_operand:SF 0 "register_operand" "=f")
5848 (plus:SF (match_operand:SF 1 "register_operand" "f")
5849 (match_operand:SF 2 "register_operand" "f")))]
5852 [(set_attr "type" "fp")])
5854 (define_expand "subtf3"
5855 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5856 (minus:TF (match_operand:TF 1 "general_operand" "")
5857 (match_operand:TF 2 "general_operand" "")))]
5858 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5859 "emit_tfmode_binop (MINUS, operands); DONE;")
5861 (define_insn "*subtf3_hq"
5862 [(set (match_operand:TF 0 "register_operand" "=e")
5863 (minus:TF (match_operand:TF 1 "register_operand" "e")
5864 (match_operand:TF 2 "register_operand" "e")))]
5865 "TARGET_FPU && TARGET_HARD_QUAD"
5867 [(set_attr "type" "fp")])
5869 (define_insn "subdf3"
5870 [(set (match_operand:DF 0 "register_operand" "=e")
5871 (minus:DF (match_operand:DF 1 "register_operand" "e")
5872 (match_operand:DF 2 "register_operand" "e")))]
5875 [(set_attr "type" "fp")
5876 (set_attr "fptype" "double")])
5878 (define_insn "subsf3"
5879 [(set (match_operand:SF 0 "register_operand" "=f")
5880 (minus:SF (match_operand:SF 1 "register_operand" "f")
5881 (match_operand:SF 2 "register_operand" "f")))]
5884 [(set_attr "type" "fp")])
5886 (define_expand "multf3"
5887 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5888 (mult:TF (match_operand:TF 1 "general_operand" "")
5889 (match_operand:TF 2 "general_operand" "")))]
5890 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5891 "emit_tfmode_binop (MULT, operands); DONE;")
5893 (define_insn "*multf3_hq"
5894 [(set (match_operand:TF 0 "register_operand" "=e")
5895 (mult:TF (match_operand:TF 1 "register_operand" "e")
5896 (match_operand:TF 2 "register_operand" "e")))]
5897 "TARGET_FPU && TARGET_HARD_QUAD"
5899 [(set_attr "type" "fpmul")])
5901 (define_insn "muldf3"
5902 [(set (match_operand:DF 0 "register_operand" "=e")
5903 (mult:DF (match_operand:DF 1 "register_operand" "e")
5904 (match_operand:DF 2 "register_operand" "e")))]
5907 [(set_attr "type" "fpmul")
5908 (set_attr "fptype" "double")])
5910 (define_insn "mulsf3"
5911 [(set (match_operand:SF 0 "register_operand" "=f")
5912 (mult:SF (match_operand:SF 1 "register_operand" "f")
5913 (match_operand:SF 2 "register_operand" "f")))]
5916 [(set_attr "type" "fpmul")])
5918 (define_insn "*muldf3_extend"
5919 [(set (match_operand:DF 0 "register_operand" "=e")
5920 (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "f"))
5921 (float_extend:DF (match_operand:SF 2 "register_operand" "f"))))]
5922 "(TARGET_V8 || TARGET_V9) && TARGET_FPU"
5923 "fsmuld\t%1, %2, %0"
5924 [(set_attr "type" "fpmul")
5925 (set_attr "fptype" "double")])
5927 (define_insn "*multf3_extend"
5928 [(set (match_operand:TF 0 "register_operand" "=e")
5929 (mult:TF (float_extend:TF (match_operand:DF 1 "register_operand" "e"))
5930 (float_extend:TF (match_operand:DF 2 "register_operand" "e"))))]
5931 "(TARGET_V8 || TARGET_V9) && TARGET_FPU && TARGET_HARD_QUAD"
5932 "fdmulq\t%1, %2, %0"
5933 [(set_attr "type" "fpmul")])
5935 (define_expand "divtf3"
5936 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5937 (div:TF (match_operand:TF 1 "general_operand" "")
5938 (match_operand:TF 2 "general_operand" "")))]
5939 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5940 "emit_tfmode_binop (DIV, operands); DONE;")
5942 ;; don't have timing for quad-prec. divide.
5943 (define_insn "*divtf3_hq"
5944 [(set (match_operand:TF 0 "register_operand" "=e")
5945 (div:TF (match_operand:TF 1 "register_operand" "e")
5946 (match_operand:TF 2 "register_operand" "e")))]
5947 "TARGET_FPU && TARGET_HARD_QUAD"
5949 [(set_attr "type" "fpdivd")])
5951 (define_insn "divdf3"
5952 [(set (match_operand:DF 0 "register_operand" "=e")
5953 (div:DF (match_operand:DF 1 "register_operand" "e")
5954 (match_operand:DF 2 "register_operand" "e")))]
5957 [(set_attr "type" "fpdivd")
5958 (set_attr "fptype" "double")])
5960 (define_insn "divsf3"
5961 [(set (match_operand:SF 0 "register_operand" "=f")
5962 (div:SF (match_operand:SF 1 "register_operand" "f")
5963 (match_operand:SF 2 "register_operand" "f")))]
5966 [(set_attr "type" "fpdivs")])
5968 (define_expand "negtf2"
5969 [(set (match_operand:TF 0 "register_operand" "=e,e")
5970 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
5974 (define_insn_and_split "*negtf2_notv9"
5975 [(set (match_operand:TF 0 "register_operand" "=e,e")
5976 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
5977 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
5983 "&& reload_completed
5984 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5985 [(set (match_dup 2) (neg:SF (match_dup 3)))
5986 (set (match_dup 4) (match_dup 5))
5987 (set (match_dup 6) (match_dup 7))]
5988 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
5989 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
5990 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
5991 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
5992 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
5993 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
5994 [(set_attr "type" "fpmove,*")
5995 (set_attr "length" "*,2")])
5997 (define_insn_and_split "*negtf2_v9"
5998 [(set (match_operand:TF 0 "register_operand" "=e,e")
5999 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
6000 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
6001 "TARGET_FPU && TARGET_V9"
6005 "&& reload_completed
6006 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6007 [(set (match_dup 2) (neg:DF (match_dup 3)))
6008 (set (match_dup 4) (match_dup 5))]
6009 "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
6010 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
6011 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6012 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6013 [(set_attr "type" "fpmove,*")
6014 (set_attr "length" "*,2")
6015 (set_attr "fptype" "double")])
6017 (define_expand "negdf2"
6018 [(set (match_operand:DF 0 "register_operand" "")
6019 (neg:DF (match_operand:DF 1 "register_operand" "")))]
6023 (define_insn_and_split "*negdf2_notv9"
6024 [(set (match_operand:DF 0 "register_operand" "=e,e")
6025 (neg:DF (match_operand:DF 1 "register_operand" "0,e")))]
6026 "TARGET_FPU && ! TARGET_V9"
6030 "&& reload_completed
6031 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6032 [(set (match_dup 2) (neg:SF (match_dup 3)))
6033 (set (match_dup 4) (match_dup 5))]
6034 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6035 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6036 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6037 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);"
6038 [(set_attr "type" "fpmove,*")
6039 (set_attr "length" "*,2")])
6041 (define_insn "*negdf2_v9"
6042 [(set (match_operand:DF 0 "register_operand" "=e")
6043 (neg:DF (match_operand:DF 1 "register_operand" "e")))]
6044 "TARGET_FPU && TARGET_V9"
6046 [(set_attr "type" "fpmove")
6047 (set_attr "fptype" "double")])
6049 (define_insn "negsf2"
6050 [(set (match_operand:SF 0 "register_operand" "=f")
6051 (neg:SF (match_operand:SF 1 "register_operand" "f")))]
6054 [(set_attr "type" "fpmove")])
6056 (define_expand "abstf2"
6057 [(set (match_operand:TF 0 "register_operand" "")
6058 (abs:TF (match_operand:TF 1 "register_operand" "")))]
6062 (define_insn_and_split "*abstf2_notv9"
6063 [(set (match_operand:TF 0 "register_operand" "=e,e")
6064 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6065 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
6066 "TARGET_FPU && ! TARGET_V9"
6070 "&& reload_completed
6071 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6072 [(set (match_dup 2) (abs:SF (match_dup 3)))
6073 (set (match_dup 4) (match_dup 5))
6074 (set (match_dup 6) (match_dup 7))]
6075 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6076 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6077 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6078 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
6079 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6080 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6081 [(set_attr "type" "fpmove,*")
6082 (set_attr "length" "*,2")])
6084 (define_insn "*abstf2_hq_v9"
6085 [(set (match_operand:TF 0 "register_operand" "=e,e")
6086 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6087 "TARGET_FPU && TARGET_V9 && TARGET_HARD_QUAD"
6091 [(set_attr "type" "fpmove")
6092 (set_attr "fptype" "double,*")])
6094 (define_insn_and_split "*abstf2_v9"
6095 [(set (match_operand:TF 0 "register_operand" "=e,e")
6096 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6097 "TARGET_FPU && TARGET_V9 && !TARGET_HARD_QUAD"
6101 "&& reload_completed
6102 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6103 [(set (match_dup 2) (abs:DF (match_dup 3)))
6104 (set (match_dup 4) (match_dup 5))]
6105 "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
6106 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
6107 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6108 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6109 [(set_attr "type" "fpmove,*")
6110 (set_attr "length" "*,2")
6111 (set_attr "fptype" "double,*")])
6113 (define_expand "absdf2"
6114 [(set (match_operand:DF 0 "register_operand" "")
6115 (abs:DF (match_operand:DF 1 "register_operand" "")))]
6119 (define_insn_and_split "*absdf2_notv9"
6120 [(set (match_operand:DF 0 "register_operand" "=e,e")
6121 (abs:DF (match_operand:DF 1 "register_operand" "0,e")))]
6122 "TARGET_FPU && ! TARGET_V9"
6126 "&& reload_completed
6127 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6128 [(set (match_dup 2) (abs:SF (match_dup 3)))
6129 (set (match_dup 4) (match_dup 5))]
6130 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6131 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6132 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6133 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);"
6134 [(set_attr "type" "fpmove,*")
6135 (set_attr "length" "*,2")])
6137 (define_insn "*absdf2_v9"
6138 [(set (match_operand:DF 0 "register_operand" "=e")
6139 (abs:DF (match_operand:DF 1 "register_operand" "e")))]
6140 "TARGET_FPU && TARGET_V9"
6142 [(set_attr "type" "fpmove")
6143 (set_attr "fptype" "double")])
6145 (define_insn "abssf2"
6146 [(set (match_operand:SF 0 "register_operand" "=f")
6147 (abs:SF (match_operand:SF 1 "register_operand" "f")))]
6150 [(set_attr "type" "fpmove")])
6152 (define_expand "sqrttf2"
6153 [(set (match_operand:TF 0 "nonimmediate_operand" "")
6154 (sqrt:TF (match_operand:TF 1 "general_operand" "")))]
6155 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6156 "emit_tfmode_unop (SQRT, operands); DONE;")
6158 (define_insn "*sqrttf2_hq"
6159 [(set (match_operand:TF 0 "register_operand" "=e")
6160 (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
6161 "TARGET_FPU && TARGET_HARD_QUAD"
6163 [(set_attr "type" "fpsqrtd")])
6165 (define_insn "sqrtdf2"
6166 [(set (match_operand:DF 0 "register_operand" "=e")
6167 (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
6170 [(set_attr "type" "fpsqrtd")
6171 (set_attr "fptype" "double")])
6173 (define_insn "sqrtsf2"
6174 [(set (match_operand:SF 0 "register_operand" "=f")
6175 (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
6178 [(set_attr "type" "fpsqrts")])
6181 ;; Arithmetic shift instructions.
6183 (define_insn "ashlsi3"
6184 [(set (match_operand:SI 0 "register_operand" "=r")
6185 (ashift:SI (match_operand:SI 1 "register_operand" "r")
6186 (match_operand:SI 2 "arith_operand" "rI")))]
6189 if (GET_CODE (operands[2]) == CONST_INT)
6190 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6191 return "sll\t%1, %2, %0";
6194 (if_then_else (match_operand 2 "const_one_operand" "")
6195 (const_string "ialu") (const_string "shift")))])
6197 (define_expand "ashldi3"
6198 [(set (match_operand:DI 0 "register_operand" "=r")
6199 (ashift:DI (match_operand:DI 1 "register_operand" "r")
6200 (match_operand:SI 2 "arith_operand" "rI")))]
6201 "TARGET_ARCH64 || TARGET_V8PLUS"
6203 if (! TARGET_ARCH64)
6205 if (GET_CODE (operands[2]) == CONST_INT)
6207 emit_insn (gen_ashldi3_v8plus (operands[0], operands[1], operands[2]));
6212 (define_insn "*ashldi3_sp64"
6213 [(set (match_operand:DI 0 "register_operand" "=r")
6214 (ashift:DI (match_operand:DI 1 "register_operand" "r")
6215 (match_operand:SI 2 "arith_operand" "rI")))]
6218 if (GET_CODE (operands[2]) == CONST_INT)
6219 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
6220 return "sllx\t%1, %2, %0";
6223 (if_then_else (match_operand 2 "const_one_operand" "")
6224 (const_string "ialu") (const_string "shift")))])
6227 (define_insn "ashldi3_v8plus"
6228 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
6229 (ashift:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
6230 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
6231 (clobber (match_scratch:SI 3 "=X,X,&h"))]
6233 "* return output_v8plus_shift (operands, insn, \"sllx\");"
6234 [(set_attr "type" "multi")
6235 (set_attr "length" "5,5,6")])
6237 ;; Optimize (1LL<<x)-1
6238 ;; XXX this also needs to be fixed to handle equal subregs
6239 ;; XXX first before we could re-enable it.
6241 ; [(set (match_operand:DI 0 "register_operand" "=h")
6242 ; (plus:DI (ashift:DI (const_int 1)
6243 ; (match_operand:SI 1 "arith_operand" "rI"))
6245 ; "0 && TARGET_V8PLUS"
6247 ; if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == REGNO (operands[0]))
6248 ; return "mov\t1, %L0\;sllx\t%L0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
6249 ; return "mov\t1, %H0\;sllx\t%H0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
6251 ; [(set_attr "type" "multi")
6252 ; (set_attr "length" "4")])
6254 (define_insn "*cmp_cc_ashift_1"
6255 [(set (reg:CC_NOOV 100)
6256 (compare:CC_NOOV (ashift:SI (match_operand:SI 0 "register_operand" "r")
6260 "addcc\t%0, %0, %%g0"
6261 [(set_attr "type" "compare")])
6263 (define_insn "*cmp_cc_set_ashift_1"
6264 [(set (reg:CC_NOOV 100)
6265 (compare:CC_NOOV (ashift:SI (match_operand:SI 1 "register_operand" "r")
6268 (set (match_operand:SI 0 "register_operand" "=r")
6269 (ashift:SI (match_dup 1) (const_int 1)))]
6272 [(set_attr "type" "compare")])
6274 (define_insn "ashrsi3"
6275 [(set (match_operand:SI 0 "register_operand" "=r")
6276 (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
6277 (match_operand:SI 2 "arith_operand" "rI")))]
6280 if (GET_CODE (operands[2]) == CONST_INT)
6281 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6282 return "sra\t%1, %2, %0";
6284 [(set_attr "type" "shift")])
6286 (define_insn "*ashrsi3_extend"
6287 [(set (match_operand:DI 0 "register_operand" "=r")
6288 (sign_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
6289 (match_operand:SI 2 "arith_operand" "r"))))]
6292 [(set_attr "type" "shift")])
6294 ;; This handles the case as above, but with constant shift instead of
6295 ;; register. Combiner "simplifies" it for us a little bit though.
6296 (define_insn "*ashrsi3_extend2"
6297 [(set (match_operand:DI 0 "register_operand" "=r")
6298 (ashiftrt:DI (ashift:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
6300 (match_operand:SI 2 "small_int_operand" "I")))]
6301 "TARGET_ARCH64 && INTVAL (operands[2]) >= 32 && INTVAL (operands[2]) < 64"
6303 operands[2] = GEN_INT (INTVAL (operands[2]) - 32);
6304 return "sra\t%1, %2, %0";
6306 [(set_attr "type" "shift")])
6308 (define_expand "ashrdi3"
6309 [(set (match_operand:DI 0 "register_operand" "=r")
6310 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
6311 (match_operand:SI 2 "arith_operand" "rI")))]
6312 "TARGET_ARCH64 || TARGET_V8PLUS"
6314 if (! TARGET_ARCH64)
6316 if (GET_CODE (operands[2]) == CONST_INT)
6317 FAIL; /* prefer generic code in this case */
6318 emit_insn (gen_ashrdi3_v8plus (operands[0], operands[1], operands[2]));
6323 (define_insn "*ashrdi3_sp64"
6324 [(set (match_operand:DI 0 "register_operand" "=r")
6325 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
6326 (match_operand:SI 2 "arith_operand" "rI")))]
6330 if (GET_CODE (operands[2]) == CONST_INT)
6331 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
6332 return "srax\t%1, %2, %0";
6334 [(set_attr "type" "shift")])
6337 (define_insn "ashrdi3_v8plus"
6338 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
6339 (ashiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
6340 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
6341 (clobber (match_scratch:SI 3 "=X,X,&h"))]
6343 "* return output_v8plus_shift (operands, insn, \"srax\");"
6344 [(set_attr "type" "multi")
6345 (set_attr "length" "5,5,6")])
6347 (define_insn "lshrsi3"
6348 [(set (match_operand:SI 0 "register_operand" "=r")
6349 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
6350 (match_operand:SI 2 "arith_operand" "rI")))]
6353 if (GET_CODE (operands[2]) == CONST_INT)
6354 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6355 return "srl\t%1, %2, %0";
6357 [(set_attr "type" "shift")])
6359 ;; This handles the case where
6360 ;; (zero_extend:DI (lshiftrt:SI (match_operand:SI) (match_operand:SI))),
6361 ;; but combiner "simplifies" it for us.
6362 (define_insn "*lshrsi3_extend"
6363 [(set (match_operand:DI 0 "register_operand" "=r")
6364 (and:DI (subreg:DI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
6365 (match_operand:SI 2 "arith_operand" "r")) 0)
6366 (match_operand 3 "const_int_operand" "")))]
6367 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) == 0xffffffff"
6369 [(set_attr "type" "shift")])
6371 ;; This handles the case where
6372 ;; (lshiftrt:DI (zero_extend:DI (match_operand:SI)) (const_int >=0 < 32))
6373 ;; but combiner "simplifies" it for us.
6374 (define_insn "*lshrsi3_extend2"
6375 [(set (match_operand:DI 0 "register_operand" "=r")
6376 (zero_extract:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
6377 (match_operand 2 "small_int_operand" "I")
6379 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
6381 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
6382 return "srl\t%1, %2, %0";
6384 [(set_attr "type" "shift")])
6386 (define_expand "lshrdi3"
6387 [(set (match_operand:DI 0 "register_operand" "=r")
6388 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6389 (match_operand:SI 2 "arith_operand" "rI")))]
6390 "TARGET_ARCH64 || TARGET_V8PLUS"
6392 if (! TARGET_ARCH64)
6394 if (GET_CODE (operands[2]) == CONST_INT)
6396 emit_insn (gen_lshrdi3_v8plus (operands[0], operands[1], operands[2]));
6401 (define_insn "*lshrdi3_sp64"
6402 [(set (match_operand:DI 0 "register_operand" "=r")
6403 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6404 (match_operand:SI 2 "arith_operand" "rI")))]
6407 if (GET_CODE (operands[2]) == CONST_INT)
6408 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
6409 return "srlx\t%1, %2, %0";
6411 [(set_attr "type" "shift")])
6414 (define_insn "lshrdi3_v8plus"
6415 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
6416 (lshiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
6417 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
6418 (clobber (match_scratch:SI 3 "=X,X,&h"))]
6420 "* return output_v8plus_shift (operands, insn, \"srlx\");"
6421 [(set_attr "type" "multi")
6422 (set_attr "length" "5,5,6")])
6425 [(set (match_operand:SI 0 "register_operand" "=r")
6426 (ashiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6428 (match_operand:SI 2 "small_int_operand" "I")))]
6429 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
6431 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
6432 return "srax\t%1, %2, %0";
6434 [(set_attr "type" "shift")])
6437 [(set (match_operand:SI 0 "register_operand" "=r")
6438 (lshiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
6440 (match_operand:SI 2 "small_int_operand" "I")))]
6441 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
6443 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
6444 return "srlx\t%1, %2, %0";
6446 [(set_attr "type" "shift")])
6449 [(set (match_operand:SI 0 "register_operand" "=r")
6450 (ashiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
6451 (match_operand:SI 2 "small_int_operand" "I")) 4)
6452 (match_operand:SI 3 "small_int_operand" "I")))]
6454 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
6455 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
6456 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
6458 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
6460 return "srax\t%1, %2, %0";
6462 [(set_attr "type" "shift")])
6465 [(set (match_operand:SI 0 "register_operand" "=r")
6466 (lshiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6467 (match_operand:SI 2 "small_int_operand" "I")) 4)
6468 (match_operand:SI 3 "small_int_operand" "I")))]
6470 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
6471 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
6472 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
6474 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
6476 return "srlx\t%1, %2, %0";
6478 [(set_attr "type" "shift")])
6481 ;; Unconditional and other jump instructions.
6484 [(set (pc) (label_ref (match_operand 0 "" "")))]
6486 "* return output_ubranch (operands[0], 0, insn);"
6487 [(set_attr "type" "uncond_branch")])
6489 (define_expand "tablejump"
6490 [(parallel [(set (pc) (match_operand 0 "register_operand" "r"))
6491 (use (label_ref (match_operand 1 "" "")))])]
6494 gcc_assert (GET_MODE (operands[0]) == CASE_VECTOR_MODE);
6496 /* In pic mode, our address differences are against the base of the
6497 table. Add that base value back in; CSE ought to be able to combine
6498 the two address loads. */
6502 tmp = gen_rtx_LABEL_REF (Pmode, operands[1]);
6504 if (CASE_VECTOR_MODE != Pmode)
6505 tmp2 = gen_rtx_SIGN_EXTEND (Pmode, tmp2);
6506 tmp = gen_rtx_PLUS (Pmode, tmp2, tmp);
6507 operands[0] = memory_address (Pmode, tmp);
6511 (define_insn "*tablejump_sp32"
6512 [(set (pc) (match_operand:SI 0 "address_operand" "p"))
6513 (use (label_ref (match_operand 1 "" "")))]
6516 [(set_attr "type" "uncond_branch")])
6518 (define_insn "*tablejump_sp64"
6519 [(set (pc) (match_operand:DI 0 "address_operand" "p"))
6520 (use (label_ref (match_operand 1 "" "")))]
6523 [(set_attr "type" "uncond_branch")])
6526 ;; Jump to subroutine instructions.
6528 (define_expand "call"
6529 ;; Note that this expression is not used for generating RTL.
6530 ;; All the RTL is generated explicitly below.
6531 [(call (match_operand 0 "call_operand" "")
6532 (match_operand 3 "" "i"))]
6533 ;; operands[2] is next_arg_register
6534 ;; operands[3] is struct_value_size_rtx.
6539 gcc_assert (MEM_P (operands[0]) && GET_MODE (operands[0]) == FUNCTION_MODE);
6541 gcc_assert (GET_CODE (operands[3]) == CONST_INT);
6543 if (GET_CODE (XEXP (operands[0], 0)) == LABEL_REF)
6545 /* This is really a PIC sequence. We want to represent
6546 it as a funny jump so its delay slots can be filled.
6548 ??? But if this really *is* a CALL, will not it clobber the
6549 call-clobbered registers? We lose this if it is a JUMP_INSN.
6550 Why cannot we have delay slots filled if it were a CALL? */
6552 /* We accept negative sizes for untyped calls. */
6553 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
6558 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
6560 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
6566 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
6567 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
6571 fn_rtx = operands[0];
6573 /* We accept negative sizes for untyped calls. */
6574 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
6575 sparc_emit_call_insn
6578 gen_rtvec (3, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx),
6580 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))),
6583 sparc_emit_call_insn
6586 gen_rtvec (2, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx),
6587 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))),
6595 ;; We can't use the same pattern for these two insns, because then registers
6596 ;; in the address may not be properly reloaded.
6598 (define_insn "*call_address_sp32"
6599 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6600 (match_operand 1 "" ""))
6601 (clobber (reg:SI 15))]
6602 ;;- Do not use operand 1 for most machines.
6605 [(set_attr "type" "call")])
6607 (define_insn "*call_symbolic_sp32"
6608 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6609 (match_operand 1 "" ""))
6610 (clobber (reg:SI 15))]
6611 ;;- Do not use operand 1 for most machines.
6614 [(set_attr "type" "call")])
6616 (define_insn "*call_address_sp64"
6617 [(call (mem:DI (match_operand:DI 0 "address_operand" "p"))
6618 (match_operand 1 "" ""))
6619 (clobber (reg:DI 15))]
6620 ;;- Do not use operand 1 for most machines.
6623 [(set_attr "type" "call")])
6625 (define_insn "*call_symbolic_sp64"
6626 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
6627 (match_operand 1 "" ""))
6628 (clobber (reg:DI 15))]
6629 ;;- Do not use operand 1 for most machines.
6632 [(set_attr "type" "call")])
6634 ;; This is a call that wants a structure value.
6635 ;; There is no such critter for v9 (??? we may need one anyway).
6636 (define_insn "*call_address_struct_value_sp32"
6637 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6638 (match_operand 1 "" ""))
6639 (match_operand 2 "immediate_operand" "")
6640 (clobber (reg:SI 15))]
6641 ;;- Do not use operand 1 for most machines.
6642 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
6644 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xfff);
6645 return "call\t%a0, %1\n\t nop\n\tunimp\t%2";
6647 [(set_attr "type" "call_no_delay_slot")
6648 (set_attr "length" "3")])
6650 ;; This is a call that wants a structure value.
6651 ;; There is no such critter for v9 (??? we may need one anyway).
6652 (define_insn "*call_symbolic_struct_value_sp32"
6653 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6654 (match_operand 1 "" ""))
6655 (match_operand 2 "immediate_operand" "")
6656 (clobber (reg:SI 15))]
6657 ;;- Do not use operand 1 for most machines.
6658 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
6660 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xfff);
6661 return "call\t%a0, %1\n\t nop\n\tunimp\t%2";
6663 [(set_attr "type" "call_no_delay_slot")
6664 (set_attr "length" "3")])
6666 ;; This is a call that may want a structure value. This is used for
6668 (define_insn "*call_address_untyped_struct_value_sp32"
6669 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6670 (match_operand 1 "" ""))
6671 (match_operand 2 "immediate_operand" "")
6672 (clobber (reg:SI 15))]
6673 ;;- Do not use operand 1 for most machines.
6674 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
6675 "call\t%a0, %1\n\t nop\n\tnop"
6676 [(set_attr "type" "call_no_delay_slot")
6677 (set_attr "length" "3")])
6679 ;; This is a call that may want a structure value. This is used for
6681 (define_insn "*call_symbolic_untyped_struct_value_sp32"
6682 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6683 (match_operand 1 "" ""))
6684 (match_operand 2 "immediate_operand" "")
6685 (clobber (reg:SI 15))]
6686 ;;- Do not use operand 1 for most machines.
6687 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
6688 "call\t%a0, %1\n\t nop\n\tnop"
6689 [(set_attr "type" "call_no_delay_slot")
6690 (set_attr "length" "3")])
6692 (define_expand "call_value"
6693 ;; Note that this expression is not used for generating RTL.
6694 ;; All the RTL is generated explicitly below.
6695 [(set (match_operand 0 "register_operand" "=rf")
6696 (call (match_operand 1 "" "")
6697 (match_operand 4 "" "")))]
6698 ;; operand 2 is stack_size_rtx
6699 ;; operand 3 is next_arg_register
6705 gcc_assert (MEM_P (operands[1]) && GET_MODE (operands[1]) == FUNCTION_MODE);
6707 fn_rtx = operands[1];
6710 gen_rtx_SET (VOIDmode, operands[0],
6711 gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx)),
6712 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)));
6714 sparc_emit_call_insn (gen_rtx_PARALLEL (VOIDmode, vec), XEXP (fn_rtx, 0));
6719 (define_insn "*call_value_address_sp32"
6720 [(set (match_operand 0 "" "=rf")
6721 (call (mem:SI (match_operand:SI 1 "address_operand" "p"))
6722 (match_operand 2 "" "")))
6723 (clobber (reg:SI 15))]
6724 ;;- Do not use operand 2 for most machines.
6727 [(set_attr "type" "call")])
6729 (define_insn "*call_value_symbolic_sp32"
6730 [(set (match_operand 0 "" "=rf")
6731 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
6732 (match_operand 2 "" "")))
6733 (clobber (reg:SI 15))]
6734 ;;- Do not use operand 2 for most machines.
6737 [(set_attr "type" "call")])
6739 (define_insn "*call_value_address_sp64"
6740 [(set (match_operand 0 "" "")
6741 (call (mem:DI (match_operand:DI 1 "address_operand" "p"))
6742 (match_operand 2 "" "")))
6743 (clobber (reg:DI 15))]
6744 ;;- Do not use operand 2 for most machines.
6747 [(set_attr "type" "call")])
6749 (define_insn "*call_value_symbolic_sp64"
6750 [(set (match_operand 0 "" "")
6751 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
6752 (match_operand 2 "" "")))
6753 (clobber (reg:DI 15))]
6754 ;;- Do not use operand 2 for most machines.
6757 [(set_attr "type" "call")])
6759 (define_expand "untyped_call"
6760 [(parallel [(call (match_operand 0 "" "")
6762 (match_operand:BLK 1 "memory_operand" "")
6763 (match_operand 2 "" "")])]
6766 rtx valreg1 = gen_rtx_REG (DImode, 8);
6767 rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
6768 rtx result = operands[1];
6770 /* Pass constm1 to indicate that it may expect a structure value, but
6771 we don't know what size it is. */
6772 emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, constm1_rtx));
6774 /* Save the function value registers. */
6775 emit_move_insn (adjust_address (result, DImode, 0), valreg1);
6776 emit_move_insn (adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8),
6779 /* The optimizer does not know that the call sets the function value
6780 registers we stored in the result block. We avoid problems by
6781 claiming that all hard registers are used and clobbered at this
6783 emit_insn (gen_blockage ());
6788 ;; Tail call instructions.
6790 (define_expand "sibcall"
6791 [(parallel [(call (match_operand 0 "call_operand" "") (const_int 0))
6796 (define_insn "*sibcall_symbolic_sp32"
6797 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6798 (match_operand 1 "" ""))
6801 "* return output_sibcall(insn, operands[0]);"
6802 [(set_attr "type" "sibcall")])
6804 (define_insn "*sibcall_symbolic_sp64"
6805 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
6806 (match_operand 1 "" ""))
6809 "* return output_sibcall(insn, operands[0]);"
6810 [(set_attr "type" "sibcall")])
6812 (define_expand "sibcall_value"
6813 [(parallel [(set (match_operand 0 "register_operand" "=rf")
6814 (call (match_operand 1 "" "") (const_int 0)))
6819 (define_insn "*sibcall_value_symbolic_sp32"
6820 [(set (match_operand 0 "" "=rf")
6821 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
6822 (match_operand 2 "" "")))
6825 "* return output_sibcall(insn, operands[1]);"
6826 [(set_attr "type" "sibcall")])
6828 (define_insn "*sibcall_value_symbolic_sp64"
6829 [(set (match_operand 0 "" "")
6830 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
6831 (match_operand 2 "" "")))
6834 "* return output_sibcall(insn, operands[1]);"
6835 [(set_attr "type" "sibcall")])
6838 ;; Special instructions.
6840 (define_expand "prologue"
6844 sparc_expand_prologue ();
6848 ;; The "save register window" insn is modelled as follows so that the DWARF-2
6849 ;; backend automatically emits the required call frame debugging information
6850 ;; while it is parsing it. Therefore, the pattern should not be modified
6851 ;; without first studying the impact of the changes on the debug info.
6852 ;; [(set (%fp) (%sp))
6853 ;; (set (%sp) (unspec_volatile [(%sp) (-frame_size)] UNSPECV_SAVEW))
6854 ;; (set (%i7) (%o7))]
6856 (define_insn "save_register_window<P:mode>"
6857 [(set (reg:P 30) (reg:P 14))
6858 (set (reg:P 14) (unspec_volatile:P [(reg:P 14)
6859 (match_operand:P 0 "arith_operand" "rI")] UNSPECV_SAVEW))
6860 (set (reg:P 31) (reg:P 15))]
6862 "save\t%%sp, %0, %%sp"
6863 [(set_attr "type" "savew")])
6865 (define_expand "epilogue"
6869 sparc_expand_epilogue ();
6872 (define_expand "sibcall_epilogue"
6876 sparc_expand_epilogue ();
6880 (define_expand "return"
6882 "sparc_can_use_return_insn_p ()"
6885 (define_insn "*return_internal"
6888 "* return output_return (insn);"
6889 [(set_attr "type" "return")
6890 (set (attr "length")
6891 (cond [(eq_attr "leaf_function" "true")
6892 (if_then_else (eq_attr "empty_delay_slot" "true")
6895 (eq_attr "calls_eh_return" "true")
6896 (if_then_else (eq_attr "delayed_branch" "true")
6897 (if_then_else (eq_attr "isa" "v9")
6900 (if_then_else (eq_attr "isa" "v9")
6903 (eq_attr "empty_delay_slot" "true")
6904 (if_then_else (eq_attr "delayed_branch" "true")
6909 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
6910 ;; all of memory. This blocks insns from being moved across this point.
6912 (define_insn "blockage"
6913 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
6916 [(set_attr "length" "0")])
6918 ;; Prepare to return any type including a structure value.
6920 (define_expand "untyped_return"
6921 [(match_operand:BLK 0 "memory_operand" "")
6922 (match_operand 1 "" "")]
6925 rtx valreg1 = gen_rtx_REG (DImode, 24);
6926 rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
6927 rtx result = operands[0];
6929 if (! TARGET_ARCH64)
6931 rtx rtnreg = gen_rtx_REG (SImode, (current_function_uses_only_leaf_regs
6933 rtx value = gen_reg_rtx (SImode);
6935 /* Fetch the instruction where we will return to and see if it's an unimp
6936 instruction (the most significant 10 bits will be zero). If so,
6937 update the return address to skip the unimp instruction. */
6938 emit_move_insn (value,
6939 gen_rtx_MEM (SImode, plus_constant (rtnreg, 8)));
6940 emit_insn (gen_lshrsi3 (value, value, GEN_INT (22)));
6941 emit_insn (gen_update_return (rtnreg, value));
6944 /* Reload the function value registers. */
6945 emit_move_insn (valreg1, adjust_address (result, DImode, 0));
6946 emit_move_insn (valreg2,
6947 adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8));
6949 /* Put USE insns before the return. */
6953 /* Construct the return. */
6954 expand_naked_return ();
6959 ;; Adjust the return address conditionally. If the value of op1 is equal
6960 ;; to all zero then adjust the return address i.e. op0 = op0 + 4.
6961 ;; This is technically *half* the check required by the 32-bit SPARC
6962 ;; psABI. This check only ensures that an "unimp" insn was written by
6963 ;; the caller, but doesn't check to see if the expected size matches
6964 ;; (this is encoded in the 12 lower bits). This check is obsolete and
6965 ;; only used by the above code "untyped_return".
6967 (define_insn "update_return"
6968 [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
6969 (match_operand:SI 1 "register_operand" "r")] UNSPEC_UPDATE_RETURN)]
6972 if (flag_delayed_branch)
6973 return "cmp\t%1, 0\n\tbe,a\t.+8\n\t add\t%0, 4, %0";
6975 return "cmp\t%1, 0\n\tbne\t.+12\n\t nop\n\tadd\t%0, 4, %0";
6977 [(set (attr "type") (const_string "multi"))
6978 (set (attr "length")
6979 (if_then_else (eq_attr "delayed_branch" "true")
6988 (define_expand "indirect_jump"
6989 [(set (pc) (match_operand 0 "address_operand" "p"))]
6993 (define_insn "*branch_sp32"
6994 [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
6997 [(set_attr "type" "uncond_branch")])
6999 (define_insn "*branch_sp64"
7000 [(set (pc) (match_operand:DI 0 "address_operand" "p"))]
7003 [(set_attr "type" "uncond_branch")])
7005 (define_expand "nonlocal_goto"
7006 [(match_operand:SI 0 "general_operand" "")
7007 (match_operand:SI 1 "general_operand" "")
7008 (match_operand:SI 2 "general_operand" "")
7009 (match_operand:SI 3 "" "")]
7012 rtx lab = operands[1];
7013 rtx stack = operands[2];
7014 rtx fp = operands[3];
7017 /* Trap instruction to flush all the register windows. */
7018 emit_insn (gen_flush_register_windows ());
7020 /* Load the fp value for the containing fn into %fp. This is needed
7021 because STACK refers to %fp. Note that virtual register instantiation
7022 fails if the virtual %fp isn't set from a register. */
7023 if (GET_CODE (fp) != REG)
7024 fp = force_reg (Pmode, fp);
7025 emit_move_insn (virtual_stack_vars_rtx, fp);
7027 /* Find the containing function's current nonlocal goto handler,
7028 which will do any cleanups and then jump to the label. */
7029 labreg = gen_rtx_REG (Pmode, 8);
7030 emit_move_insn (labreg, lab);
7032 /* Restore %fp from stack pointer value for containing function.
7033 The restore insn that follows will move this to %sp,
7034 and reload the appropriate value into %fp. */
7035 emit_move_insn (hard_frame_pointer_rtx, stack);
7037 emit_use (stack_pointer_rtx);
7038 emit_use (static_chain_rtx);
7040 /* ??? The V9-specific version was disabled in rev 1.65. */
7041 emit_jump_insn (gen_goto_handler_and_restore (labreg));
7046 ;; Special trap insn to flush register windows.
7047 (define_insn "flush_register_windows"
7048 [(unspec_volatile [(const_int 0)] UNSPECV_FLUSHW)]
7050 { return TARGET_V9 ? "flushw" : "ta\t3"; }
7051 [(set_attr "type" "flushw")])
7053 (define_insn "goto_handler_and_restore"
7054 [(unspec_volatile [(match_operand 0 "register_operand" "=r")] UNSPECV_GOTO)]
7055 "GET_MODE (operands[0]) == Pmode"
7057 if (flag_delayed_branch)
7058 return "jmp\t%0\n\t restore";
7060 return "mov\t%0,%%g1\n\trestore\n\tjmp\t%%g1\n\t nop";
7062 [(set (attr "type") (const_string "multi"))
7063 (set (attr "length")
7064 (if_then_else (eq_attr "delayed_branch" "true")
7068 ;; For __builtin_setjmp we need to flush register windows iff the function
7069 ;; calls alloca as well, because otherwise the register window might be
7070 ;; saved after %sp adjustment and thus setjmp would crash
7071 (define_expand "builtin_setjmp_setup"
7072 [(match_operand 0 "register_operand" "r")]
7075 emit_insn (gen_do_builtin_setjmp_setup ());
7079 (define_insn "do_builtin_setjmp_setup"
7080 [(unspec_volatile [(const_int 0)] UNSPECV_SETJMP)]
7083 if (! cfun->calls_alloca)
7087 fputs ("\tflushw\n", asm_out_file);
7089 fprintf (asm_out_file, "\tst%c\t%%l7, [%%sp+%d]\n",
7090 TARGET_ARCH64 ? 'x' : 'w',
7091 SPARC_STACK_BIAS + 7 * UNITS_PER_WORD);
7092 fprintf (asm_out_file, "\tst%c\t%%fp, [%%sp+%d]\n",
7093 TARGET_ARCH64 ? 'x' : 'w',
7094 SPARC_STACK_BIAS + 14 * UNITS_PER_WORD);
7095 fprintf (asm_out_file, "\tst%c\t%%i7, [%%sp+%d]\n",
7096 TARGET_ARCH64 ? 'x' : 'w',
7097 SPARC_STACK_BIAS + 15 * UNITS_PER_WORD);
7100 [(set_attr "type" "multi")
7101 (set (attr "length")
7102 (cond [(eq_attr "calls_alloca" "false")
7104 (eq_attr "isa" "!v9")
7106 (eq_attr "pic" "true")
7107 (const_int 4)] (const_int 3)))])
7109 ;; Pattern for use after a setjmp to store FP and the return register
7110 ;; into the stack area.
7112 (define_expand "setjmp"
7118 mem = gen_rtx_MEM (Pmode,
7119 plus_constant (stack_pointer_rtx,
7120 SPARC_STACK_BIAS + 14 * UNITS_PER_WORD));
7121 emit_insn (gen_rtx_SET (VOIDmode, mem, frame_pointer_rtx));
7123 mem = gen_rtx_MEM (Pmode,
7124 plus_constant (stack_pointer_rtx,
7125 SPARC_STACK_BIAS + 15 * UNITS_PER_WORD));
7126 emit_insn (gen_rtx_SET (VOIDmode, mem, gen_rtx_REG (Pmode, 31)));
7130 ;; Special pattern for the FLUSH instruction.
7132 ; We do SImode and DImode versions of this to quiet down genrecog's complaints
7133 ; of the define_insn otherwise missing a mode. We make "flush", aka
7134 ; gen_flush, the default one since sparc_initialize_trampoline uses
7135 ; it on SImode mem values.
7137 (define_insn "flush"
7138 [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")] UNSPECV_FLUSH)]
7140 { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; }
7141 [(set_attr "type" "iflush")])
7143 (define_insn "flushdi"
7144 [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")] UNSPECV_FLUSH)]
7146 { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; }
7147 [(set_attr "type" "iflush")])
7150 ;; Find first set instructions.
7152 ;; The scan instruction searches from the most significant bit while ffs
7153 ;; searches from the least significant bit. The bit index and treatment of
7154 ;; zero also differ. It takes at least 7 instructions to get the proper
7155 ;; result. Here is an obvious 8 instruction sequence.
7158 (define_insn "ffssi2"
7159 [(set (match_operand:SI 0 "register_operand" "=&r")
7160 (ffs:SI (match_operand:SI 1 "register_operand" "r")))
7161 (clobber (match_scratch:SI 2 "=&r"))]
7162 "TARGET_SPARCLITE || TARGET_SPARCLET"
7164 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";
7166 [(set_attr "type" "multi")
7167 (set_attr "length" "8")])
7169 ;; ??? This should be a define expand, so that the extra instruction have
7170 ;; a chance of being optimized away.
7172 ;; Disabled because none of the UltraSPARCs implement popc. The HAL R1
7173 ;; does, but no one uses that and we don't have a switch for it.
7175 ;(define_insn "ffsdi2"
7176 ; [(set (match_operand:DI 0 "register_operand" "=&r")
7177 ; (ffs:DI (match_operand:DI 1 "register_operand" "r")))
7178 ; (clobber (match_scratch:DI 2 "=&r"))]
7180 ; "neg\t%1, %2\;xnor\t%1, %2, %2\;popc\t%2, %0\;movzr\t%1, 0, %0"
7181 ; [(set_attr "type" "multi")
7182 ; (set_attr "length" "4")])
7186 ;; Peepholes go at the end.
7188 ;; Optimize consecutive loads or stores into ldd and std when possible.
7189 ;; The conditions in which we do this are very restricted and are
7190 ;; explained in the code for {registers,memory}_ok_for_ldd functions.
7193 [(set (match_operand:SI 0 "memory_operand" "")
7195 (set (match_operand:SI 1 "memory_operand" "")
7198 && mems_ok_for_ldd_peep (operands[0], operands[1], NULL_RTX)"
7201 "operands[0] = widen_memory_access (operands[0], DImode, 0);")
7204 [(set (match_operand:SI 0 "memory_operand" "")
7206 (set (match_operand:SI 1 "memory_operand" "")
7209 && mems_ok_for_ldd_peep (operands[1], operands[0], NULL_RTX)"
7212 "operands[1] = widen_memory_access (operands[1], DImode, 0);")
7215 [(set (match_operand:SI 0 "register_operand" "")
7216 (match_operand:SI 1 "memory_operand" ""))
7217 (set (match_operand:SI 2 "register_operand" "")
7218 (match_operand:SI 3 "memory_operand" ""))]
7219 "registers_ok_for_ldd_peep (operands[0], operands[2])
7220 && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
7223 "operands[1] = widen_memory_access (operands[1], DImode, 0);
7224 operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));")
7227 [(set (match_operand:SI 0 "memory_operand" "")
7228 (match_operand:SI 1 "register_operand" ""))
7229 (set (match_operand:SI 2 "memory_operand" "")
7230 (match_operand:SI 3 "register_operand" ""))]
7231 "registers_ok_for_ldd_peep (operands[1], operands[3])
7232 && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
7235 "operands[0] = widen_memory_access (operands[0], DImode, 0);
7236 operands[1] = gen_rtx_REG (DImode, REGNO (operands[1]));")
7239 [(set (match_operand:SF 0 "register_operand" "")
7240 (match_operand:SF 1 "memory_operand" ""))
7241 (set (match_operand:SF 2 "register_operand" "")
7242 (match_operand:SF 3 "memory_operand" ""))]
7243 "registers_ok_for_ldd_peep (operands[0], operands[2])
7244 && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
7247 "operands[1] = widen_memory_access (operands[1], DFmode, 0);
7248 operands[0] = gen_rtx_REG (DFmode, REGNO (operands[0]));")
7251 [(set (match_operand:SF 0 "memory_operand" "")
7252 (match_operand:SF 1 "register_operand" ""))
7253 (set (match_operand:SF 2 "memory_operand" "")
7254 (match_operand:SF 3 "register_operand" ""))]
7255 "registers_ok_for_ldd_peep (operands[1], operands[3])
7256 && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
7259 "operands[0] = widen_memory_access (operands[0], DFmode, 0);
7260 operands[1] = gen_rtx_REG (DFmode, REGNO (operands[1]));")
7263 [(set (match_operand:SI 0 "register_operand" "")
7264 (match_operand:SI 1 "memory_operand" ""))
7265 (set (match_operand:SI 2 "register_operand" "")
7266 (match_operand:SI 3 "memory_operand" ""))]
7267 "registers_ok_for_ldd_peep (operands[2], operands[0])
7268 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
7271 "operands[3] = widen_memory_access (operands[3], DImode, 0);
7272 operands[2] = gen_rtx_REG (DImode, REGNO (operands[2]));")
7275 [(set (match_operand:SI 0 "memory_operand" "")
7276 (match_operand:SI 1 "register_operand" ""))
7277 (set (match_operand:SI 2 "memory_operand" "")
7278 (match_operand:SI 3 "register_operand" ""))]
7279 "registers_ok_for_ldd_peep (operands[3], operands[1])
7280 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
7283 "operands[2] = widen_memory_access (operands[2], DImode, 0);
7284 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
7288 [(set (match_operand:SF 0 "register_operand" "")
7289 (match_operand:SF 1 "memory_operand" ""))
7290 (set (match_operand:SF 2 "register_operand" "")
7291 (match_operand:SF 3 "memory_operand" ""))]
7292 "registers_ok_for_ldd_peep (operands[2], operands[0])
7293 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
7296 "operands[3] = widen_memory_access (operands[3], DFmode, 0);
7297 operands[2] = gen_rtx_REG (DFmode, REGNO (operands[2]));")
7300 [(set (match_operand:SF 0 "memory_operand" "")
7301 (match_operand:SF 1 "register_operand" ""))
7302 (set (match_operand:SF 2 "memory_operand" "")
7303 (match_operand:SF 3 "register_operand" ""))]
7304 "registers_ok_for_ldd_peep (operands[3], operands[1])
7305 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
7308 "operands[2] = widen_memory_access (operands[2], DFmode, 0);
7309 operands[3] = gen_rtx_REG (DFmode, REGNO (operands[3]));")
7311 ;; Optimize the case of following a reg-reg move with a test
7312 ;; of reg just moved. Don't allow floating point regs for operand 0 or 1.
7313 ;; This can result from a float to fix conversion.
7316 [(set (match_operand:SI 0 "register_operand" "")
7317 (match_operand:SI 1 "register_operand" ""))
7319 (compare:CC (match_operand:SI 2 "register_operand" "")
7321 "(rtx_equal_p (operands[2], operands[0])
7322 || rtx_equal_p (operands[2], operands[1]))
7323 && ! SPARC_FP_REG_P (REGNO (operands[0]))
7324 && ! SPARC_FP_REG_P (REGNO (operands[1]))"
7325 [(parallel [(set (match_dup 0) (match_dup 1))
7327 (compare:CC (match_dup 1) (const_int 0)))])]
7331 [(set (match_operand:DI 0 "register_operand" "")
7332 (match_operand:DI 1 "register_operand" ""))
7334 (compare:CCX (match_operand:DI 2 "register_operand" "")
7337 && (rtx_equal_p (operands[2], operands[0])
7338 || rtx_equal_p (operands[2], operands[1]))
7339 && ! SPARC_FP_REG_P (REGNO (operands[0]))
7340 && ! SPARC_FP_REG_P (REGNO (operands[1]))"
7341 [(parallel [(set (match_dup 0) (match_dup 1))
7343 (compare:CCX (match_dup 1) (const_int 0)))])]
7347 ;; Prefetch instructions.
7349 ;; ??? UltraSPARC-III note: A memory operation loading into the floating point register
7350 ;; ??? file, if it hits the prefetch cache, has a chance to dual-issue with other memory
7351 ;; ??? operations. With DFA we might be able to model this, but it requires a lot of
7353 (define_expand "prefetch"
7354 [(match_operand 0 "address_operand" "")
7355 (match_operand 1 "const_int_operand" "")
7356 (match_operand 2 "const_int_operand" "")]
7360 emit_insn (gen_prefetch_64 (operands[0], operands[1], operands[2]));
7362 emit_insn (gen_prefetch_32 (operands[0], operands[1], operands[2]));
7366 (define_insn "prefetch_64"
7367 [(prefetch (match_operand:DI 0 "address_operand" "p")
7368 (match_operand:DI 1 "const_int_operand" "n")
7369 (match_operand:DI 2 "const_int_operand" "n"))]
7372 static const char * const prefetch_instr[2][2] = {
7374 "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
7375 "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
7378 "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
7379 "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
7382 int read_or_write = INTVAL (operands[1]);
7383 int locality = INTVAL (operands[2]);
7385 gcc_assert (read_or_write == 0 || read_or_write == 1);
7386 gcc_assert (locality >= 0 && locality < 4);
7387 return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
7389 [(set_attr "type" "load")])
7391 (define_insn "prefetch_32"
7392 [(prefetch (match_operand:SI 0 "address_operand" "p")
7393 (match_operand:SI 1 "const_int_operand" "n")
7394 (match_operand:SI 2 "const_int_operand" "n"))]
7397 static const char * const prefetch_instr[2][2] = {
7399 "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
7400 "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
7403 "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
7404 "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
7407 int read_or_write = INTVAL (operands[1]);
7408 int locality = INTVAL (operands[2]);
7410 gcc_assert (read_or_write == 0 || read_or_write == 1);
7411 gcc_assert (locality >= 0 && locality < 4);
7412 return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
7414 [(set_attr "type" "load")])
7417 ;; Trap instructions.
7420 [(trap_if (const_int 1) (const_int 5))]
7423 [(set_attr "type" "trap")])
7425 (define_expand "conditional_trap"
7426 [(trap_if (match_operator 0 "noov_compare_operator" [(match_dup 2) (match_dup 3)])
7427 (match_operand:SI 1 "arith_operand" ""))]
7429 "operands[2] = gen_compare_reg (GET_CODE (operands[0]));
7430 if (GET_MODE (operands[2]) != CCmode && GET_MODE (operands[2]) != CCXmode)
7432 operands[3] = const0_rtx;")
7435 [(trap_if (match_operator 0 "noov_compare_operator" [(reg:CC 100) (const_int 0)])
7436 (match_operand:SI 1 "arith_operand" "rM"))]
7440 return "t%C0\t%%icc, %1";
7444 [(set_attr "type" "trap")])
7447 [(trap_if (match_operator 0 "noov_compare_operator" [(reg:CCX 100) (const_int 0)])
7448 (match_operand:SI 1 "arith_operand" "rM"))]
7451 [(set_attr "type" "trap")])
7454 ;; TLS support instructions.
7456 (define_insn "tgd_hi22"
7457 [(set (match_operand:SI 0 "register_operand" "=r")
7458 (high:SI (unspec:SI [(match_operand 1 "tgd_symbolic_operand" "")]
7461 "sethi\\t%%tgd_hi22(%a1), %0")
7463 (define_insn "tgd_lo10"
7464 [(set (match_operand:SI 0 "register_operand" "=r")
7465 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7466 (unspec:SI [(match_operand 2 "tgd_symbolic_operand" "")]
7469 "add\\t%1, %%tgd_lo10(%a2), %0")
7471 (define_insn "tgd_add32"
7472 [(set (match_operand:SI 0 "register_operand" "=r")
7473 (plus:SI (match_operand:SI 1 "register_operand" "r")
7474 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7475 (match_operand 3 "tgd_symbolic_operand" "")]
7477 "TARGET_TLS && TARGET_ARCH32"
7478 "add\\t%1, %2, %0, %%tgd_add(%a3)")
7480 (define_insn "tgd_add64"
7481 [(set (match_operand:DI 0 "register_operand" "=r")
7482 (plus:DI (match_operand:DI 1 "register_operand" "r")
7483 (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7484 (match_operand 3 "tgd_symbolic_operand" "")]
7486 "TARGET_TLS && TARGET_ARCH64"
7487 "add\\t%1, %2, %0, %%tgd_add(%a3)")
7489 (define_insn "tgd_call32"
7490 [(set (match_operand 0 "register_operand" "=r")
7491 (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")
7492 (match_operand 2 "tgd_symbolic_operand" "")]
7494 (match_operand 3 "" "")))
7495 (clobber (reg:SI 15))]
7496 "TARGET_TLS && TARGET_ARCH32"
7497 "call\t%a1, %%tgd_call(%a2)%#"
7498 [(set_attr "type" "call")])
7500 (define_insn "tgd_call64"
7501 [(set (match_operand 0 "register_operand" "=r")
7502 (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")
7503 (match_operand 2 "tgd_symbolic_operand" "")]
7505 (match_operand 3 "" "")))
7506 (clobber (reg:DI 15))]
7507 "TARGET_TLS && TARGET_ARCH64"
7508 "call\t%a1, %%tgd_call(%a2)%#"
7509 [(set_attr "type" "call")])
7511 (define_insn "tldm_hi22"
7512 [(set (match_operand:SI 0 "register_operand" "=r")
7513 (high:SI (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
7515 "sethi\\t%%tldm_hi22(%&), %0")
7517 (define_insn "tldm_lo10"
7518 [(set (match_operand:SI 0 "register_operand" "=r")
7519 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7520 (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
7522 "add\\t%1, %%tldm_lo10(%&), %0")
7524 (define_insn "tldm_add32"
7525 [(set (match_operand:SI 0 "register_operand" "=r")
7526 (plus:SI (match_operand:SI 1 "register_operand" "r")
7527 (unspec:SI [(match_operand:SI 2 "register_operand" "r")]
7529 "TARGET_TLS && TARGET_ARCH32"
7530 "add\\t%1, %2, %0, %%tldm_add(%&)")
7532 (define_insn "tldm_add64"
7533 [(set (match_operand:DI 0 "register_operand" "=r")
7534 (plus:DI (match_operand:DI 1 "register_operand" "r")
7535 (unspec:DI [(match_operand:SI 2 "register_operand" "r")]
7537 "TARGET_TLS && TARGET_ARCH64"
7538 "add\\t%1, %2, %0, %%tldm_add(%&)")
7540 (define_insn "tldm_call32"
7541 [(set (match_operand 0 "register_operand" "=r")
7542 (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")]
7544 (match_operand 2 "" "")))
7545 (clobber (reg:SI 15))]
7546 "TARGET_TLS && TARGET_ARCH32"
7547 "call\t%a1, %%tldm_call(%&)%#"
7548 [(set_attr "type" "call")])
7550 (define_insn "tldm_call64"
7551 [(set (match_operand 0 "register_operand" "=r")
7552 (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")]
7554 (match_operand 2 "" "")))
7555 (clobber (reg:DI 15))]
7556 "TARGET_TLS && TARGET_ARCH64"
7557 "call\t%a1, %%tldm_call(%&)%#"
7558 [(set_attr "type" "call")])
7560 (define_insn "tldo_hix22"
7561 [(set (match_operand:SI 0 "register_operand" "=r")
7562 (high:SI (unspec:SI [(match_operand 1 "tld_symbolic_operand" "")]
7565 "sethi\\t%%tldo_hix22(%a1), %0")
7567 (define_insn "tldo_lox10"
7568 [(set (match_operand:SI 0 "register_operand" "=r")
7569 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7570 (unspec:SI [(match_operand 2 "tld_symbolic_operand" "")]
7573 "xor\\t%1, %%tldo_lox10(%a2), %0")
7575 (define_insn "tldo_add32"
7576 [(set (match_operand:SI 0 "register_operand" "=r")
7577 (plus:SI (match_operand:SI 1 "register_operand" "r")
7578 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7579 (match_operand 3 "tld_symbolic_operand" "")]
7581 "TARGET_TLS && TARGET_ARCH32"
7582 "add\\t%1, %2, %0, %%tldo_add(%a3)")
7584 (define_insn "tldo_add64"
7585 [(set (match_operand:DI 0 "register_operand" "=r")
7586 (plus:DI (match_operand:DI 1 "register_operand" "r")
7587 (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7588 (match_operand 3 "tld_symbolic_operand" "")]
7590 "TARGET_TLS && TARGET_ARCH64"
7591 "add\\t%1, %2, %0, %%tldo_add(%a3)")
7593 (define_insn "tie_hi22"
7594 [(set (match_operand:SI 0 "register_operand" "=r")
7595 (high:SI (unspec:SI [(match_operand 1 "tie_symbolic_operand" "")]
7598 "sethi\\t%%tie_hi22(%a1), %0")
7600 (define_insn "tie_lo10"
7601 [(set (match_operand:SI 0 "register_operand" "=r")
7602 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7603 (unspec:SI [(match_operand 2 "tie_symbolic_operand" "")]
7606 "add\\t%1, %%tie_lo10(%a2), %0")
7608 (define_insn "tie_ld32"
7609 [(set (match_operand:SI 0 "register_operand" "=r")
7610 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
7611 (match_operand:SI 2 "register_operand" "r")
7612 (match_operand 3 "tie_symbolic_operand" "")]
7614 "TARGET_TLS && TARGET_ARCH32"
7615 "ld\\t[%1 + %2], %0, %%tie_ld(%a3)"
7616 [(set_attr "type" "load")])
7618 (define_insn "tie_ld64"
7619 [(set (match_operand:DI 0 "register_operand" "=r")
7620 (unspec:DI [(match_operand:DI 1 "register_operand" "r")
7621 (match_operand:SI 2 "register_operand" "r")
7622 (match_operand 3 "tie_symbolic_operand" "")]
7624 "TARGET_TLS && TARGET_ARCH64"
7625 "ldx\\t[%1 + %2], %0, %%tie_ldx(%a3)"
7626 [(set_attr "type" "load")])
7628 (define_insn "tie_add32"
7629 [(set (match_operand:SI 0 "register_operand" "=r")
7630 (plus:SI (match_operand:SI 1 "register_operand" "r")
7631 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7632 (match_operand 3 "tie_symbolic_operand" "")]
7634 "TARGET_SUN_TLS && TARGET_ARCH32"
7635 "add\\t%1, %2, %0, %%tie_add(%a3)")
7637 (define_insn "tie_add64"
7638 [(set (match_operand:DI 0 "register_operand" "=r")
7639 (plus:DI (match_operand:DI 1 "register_operand" "r")
7640 (unspec:DI [(match_operand:DI 2 "register_operand" "r")
7641 (match_operand 3 "tie_symbolic_operand" "")]
7643 "TARGET_SUN_TLS && TARGET_ARCH64"
7644 "add\\t%1, %2, %0, %%tie_add(%a3)")
7646 (define_insn "tle_hix22_sp32"
7647 [(set (match_operand:SI 0 "register_operand" "=r")
7648 (high:SI (unspec:SI [(match_operand 1 "tle_symbolic_operand" "")]
7650 "TARGET_TLS && TARGET_ARCH32"
7651 "sethi\\t%%tle_hix22(%a1), %0")
7653 (define_insn "tle_lox10_sp32"
7654 [(set (match_operand:SI 0 "register_operand" "=r")
7655 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7656 (unspec:SI [(match_operand 2 "tle_symbolic_operand" "")]
7658 "TARGET_TLS && TARGET_ARCH32"
7659 "xor\\t%1, %%tle_lox10(%a2), %0")
7661 (define_insn "tle_hix22_sp64"
7662 [(set (match_operand:DI 0 "register_operand" "=r")
7663 (high:DI (unspec:DI [(match_operand 1 "tle_symbolic_operand" "")]
7665 "TARGET_TLS && TARGET_ARCH64"
7666 "sethi\\t%%tle_hix22(%a1), %0")
7668 (define_insn "tle_lox10_sp64"
7669 [(set (match_operand:DI 0 "register_operand" "=r")
7670 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
7671 (unspec:DI [(match_operand 2 "tle_symbolic_operand" "")]
7673 "TARGET_TLS && TARGET_ARCH64"
7674 "xor\\t%1, %%tle_lox10(%a2), %0")
7676 ;; Now patterns combining tldo_add{32,64} with some integer loads or stores
7677 (define_insn "*tldo_ldub_sp32"
7678 [(set (match_operand:QI 0 "register_operand" "=r")
7679 (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7680 (match_operand 3 "tld_symbolic_operand" "")]
7682 (match_operand:SI 1 "register_operand" "r"))))]
7683 "TARGET_TLS && TARGET_ARCH32"
7684 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7685 [(set_attr "type" "load")
7686 (set_attr "us3load_type" "3cycle")])
7688 (define_insn "*tldo_ldub1_sp32"
7689 [(set (match_operand:HI 0 "register_operand" "=r")
7690 (zero_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7691 (match_operand 3 "tld_symbolic_operand" "")]
7693 (match_operand:SI 1 "register_operand" "r")))))]
7694 "TARGET_TLS && TARGET_ARCH32"
7695 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7696 [(set_attr "type" "load")
7697 (set_attr "us3load_type" "3cycle")])
7699 (define_insn "*tldo_ldub2_sp32"
7700 [(set (match_operand:SI 0 "register_operand" "=r")
7701 (zero_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7702 (match_operand 3 "tld_symbolic_operand" "")]
7704 (match_operand:SI 1 "register_operand" "r")))))]
7705 "TARGET_TLS && TARGET_ARCH32"
7706 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7707 [(set_attr "type" "load")
7708 (set_attr "us3load_type" "3cycle")])
7710 (define_insn "*tldo_ldsb1_sp32"
7711 [(set (match_operand:HI 0 "register_operand" "=r")
7712 (sign_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7713 (match_operand 3 "tld_symbolic_operand" "")]
7715 (match_operand:SI 1 "register_operand" "r")))))]
7716 "TARGET_TLS && TARGET_ARCH32"
7717 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7718 [(set_attr "type" "sload")
7719 (set_attr "us3load_type" "3cycle")])
7721 (define_insn "*tldo_ldsb2_sp32"
7722 [(set (match_operand:SI 0 "register_operand" "=r")
7723 (sign_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7724 (match_operand 3 "tld_symbolic_operand" "")]
7726 (match_operand:SI 1 "register_operand" "r")))))]
7727 "TARGET_TLS && TARGET_ARCH32"
7728 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7729 [(set_attr "type" "sload")
7730 (set_attr "us3load_type" "3cycle")])
7732 (define_insn "*tldo_ldub_sp64"
7733 [(set (match_operand:QI 0 "register_operand" "=r")
7734 (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7735 (match_operand 3 "tld_symbolic_operand" "")]
7737 (match_operand:DI 1 "register_operand" "r"))))]
7738 "TARGET_TLS && TARGET_ARCH64"
7739 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7740 [(set_attr "type" "load")
7741 (set_attr "us3load_type" "3cycle")])
7743 (define_insn "*tldo_ldub1_sp64"
7744 [(set (match_operand:HI 0 "register_operand" "=r")
7745 (zero_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7746 (match_operand 3 "tld_symbolic_operand" "")]
7748 (match_operand:DI 1 "register_operand" "r")))))]
7749 "TARGET_TLS && TARGET_ARCH64"
7750 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7751 [(set_attr "type" "load")
7752 (set_attr "us3load_type" "3cycle")])
7754 (define_insn "*tldo_ldub2_sp64"
7755 [(set (match_operand:SI 0 "register_operand" "=r")
7756 (zero_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7757 (match_operand 3 "tld_symbolic_operand" "")]
7759 (match_operand:DI 1 "register_operand" "r")))))]
7760 "TARGET_TLS && TARGET_ARCH64"
7761 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7762 [(set_attr "type" "load")
7763 (set_attr "us3load_type" "3cycle")])
7765 (define_insn "*tldo_ldub3_sp64"
7766 [(set (match_operand:DI 0 "register_operand" "=r")
7767 (zero_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7768 (match_operand 3 "tld_symbolic_operand" "")]
7770 (match_operand:DI 1 "register_operand" "r")))))]
7771 "TARGET_TLS && TARGET_ARCH64"
7772 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7773 [(set_attr "type" "load")
7774 (set_attr "us3load_type" "3cycle")])
7776 (define_insn "*tldo_ldsb1_sp64"
7777 [(set (match_operand:HI 0 "register_operand" "=r")
7778 (sign_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7779 (match_operand 3 "tld_symbolic_operand" "")]
7781 (match_operand:DI 1 "register_operand" "r")))))]
7782 "TARGET_TLS && TARGET_ARCH64"
7783 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7784 [(set_attr "type" "sload")
7785 (set_attr "us3load_type" "3cycle")])
7787 (define_insn "*tldo_ldsb2_sp64"
7788 [(set (match_operand:SI 0 "register_operand" "=r")
7789 (sign_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7790 (match_operand 3 "tld_symbolic_operand" "")]
7792 (match_operand:DI 1 "register_operand" "r")))))]
7793 "TARGET_TLS && TARGET_ARCH64"
7794 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7795 [(set_attr "type" "sload")
7796 (set_attr "us3load_type" "3cycle")])
7798 (define_insn "*tldo_ldsb3_sp64"
7799 [(set (match_operand:DI 0 "register_operand" "=r")
7800 (sign_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7801 (match_operand 3 "tld_symbolic_operand" "")]
7803 (match_operand:DI 1 "register_operand" "r")))))]
7804 "TARGET_TLS && TARGET_ARCH64"
7805 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7806 [(set_attr "type" "sload")
7807 (set_attr "us3load_type" "3cycle")])
7809 (define_insn "*tldo_lduh_sp32"
7810 [(set (match_operand:HI 0 "register_operand" "=r")
7811 (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7812 (match_operand 3 "tld_symbolic_operand" "")]
7814 (match_operand:SI 1 "register_operand" "r"))))]
7815 "TARGET_TLS && TARGET_ARCH32"
7816 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7817 [(set_attr "type" "load")
7818 (set_attr "us3load_type" "3cycle")])
7820 (define_insn "*tldo_lduh1_sp32"
7821 [(set (match_operand:SI 0 "register_operand" "=r")
7822 (zero_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7823 (match_operand 3 "tld_symbolic_operand" "")]
7825 (match_operand:SI 1 "register_operand" "r")))))]
7826 "TARGET_TLS && TARGET_ARCH32"
7827 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7828 [(set_attr "type" "load")
7829 (set_attr "us3load_type" "3cycle")])
7831 (define_insn "*tldo_ldsh1_sp32"
7832 [(set (match_operand:SI 0 "register_operand" "=r")
7833 (sign_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7834 (match_operand 3 "tld_symbolic_operand" "")]
7836 (match_operand:SI 1 "register_operand" "r")))))]
7837 "TARGET_TLS && TARGET_ARCH32"
7838 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
7839 [(set_attr "type" "sload")
7840 (set_attr "us3load_type" "3cycle")])
7842 (define_insn "*tldo_lduh_sp64"
7843 [(set (match_operand:HI 0 "register_operand" "=r")
7844 (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7845 (match_operand 3 "tld_symbolic_operand" "")]
7847 (match_operand:DI 1 "register_operand" "r"))))]
7848 "TARGET_TLS && TARGET_ARCH64"
7849 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7850 [(set_attr "type" "load")
7851 (set_attr "us3load_type" "3cycle")])
7853 (define_insn "*tldo_lduh1_sp64"
7854 [(set (match_operand:SI 0 "register_operand" "=r")
7855 (zero_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7856 (match_operand 3 "tld_symbolic_operand" "")]
7858 (match_operand:DI 1 "register_operand" "r")))))]
7859 "TARGET_TLS && TARGET_ARCH64"
7860 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7861 [(set_attr "type" "load")
7862 (set_attr "us3load_type" "3cycle")])
7864 (define_insn "*tldo_lduh2_sp64"
7865 [(set (match_operand:DI 0 "register_operand" "=r")
7866 (zero_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7867 (match_operand 3 "tld_symbolic_operand" "")]
7869 (match_operand:DI 1 "register_operand" "r")))))]
7870 "TARGET_TLS && TARGET_ARCH64"
7871 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7872 [(set_attr "type" "load")
7873 (set_attr "us3load_type" "3cycle")])
7875 (define_insn "*tldo_ldsh1_sp64"
7876 [(set (match_operand:SI 0 "register_operand" "=r")
7877 (sign_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7878 (match_operand 3 "tld_symbolic_operand" "")]
7880 (match_operand:DI 1 "register_operand" "r")))))]
7881 "TARGET_TLS && TARGET_ARCH64"
7882 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
7883 [(set_attr "type" "sload")
7884 (set_attr "us3load_type" "3cycle")])
7886 (define_insn "*tldo_ldsh2_sp64"
7887 [(set (match_operand:DI 0 "register_operand" "=r")
7888 (sign_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7889 (match_operand 3 "tld_symbolic_operand" "")]
7891 (match_operand:DI 1 "register_operand" "r")))))]
7892 "TARGET_TLS && TARGET_ARCH64"
7893 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
7894 [(set_attr "type" "sload")
7895 (set_attr "us3load_type" "3cycle")])
7897 (define_insn "*tldo_lduw_sp32"
7898 [(set (match_operand:SI 0 "register_operand" "=r")
7899 (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7900 (match_operand 3 "tld_symbolic_operand" "")]
7902 (match_operand:SI 1 "register_operand" "r"))))]
7903 "TARGET_TLS && TARGET_ARCH32"
7904 "ld\t[%1 + %2], %0, %%tldo_add(%3)"
7905 [(set_attr "type" "load")])
7907 (define_insn "*tldo_lduw_sp64"
7908 [(set (match_operand:SI 0 "register_operand" "=r")
7909 (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7910 (match_operand 3 "tld_symbolic_operand" "")]
7912 (match_operand:DI 1 "register_operand" "r"))))]
7913 "TARGET_TLS && TARGET_ARCH64"
7914 "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
7915 [(set_attr "type" "load")])
7917 (define_insn "*tldo_lduw1_sp64"
7918 [(set (match_operand:DI 0 "register_operand" "=r")
7919 (zero_extend:DI (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7920 (match_operand 3 "tld_symbolic_operand" "")]
7922 (match_operand:DI 1 "register_operand" "r")))))]
7923 "TARGET_TLS && TARGET_ARCH64"
7924 "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
7925 [(set_attr "type" "load")])
7927 (define_insn "*tldo_ldsw1_sp64"
7928 [(set (match_operand:DI 0 "register_operand" "=r")
7929 (sign_extend:DI (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7930 (match_operand 3 "tld_symbolic_operand" "")]
7932 (match_operand:DI 1 "register_operand" "r")))))]
7933 "TARGET_TLS && TARGET_ARCH64"
7934 "ldsw\t[%1 + %2], %0, %%tldo_add(%3)"
7935 [(set_attr "type" "sload")
7936 (set_attr "us3load_type" "3cycle")])
7938 (define_insn "*tldo_ldx_sp64"
7939 [(set (match_operand:DI 0 "register_operand" "=r")
7940 (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7941 (match_operand 3 "tld_symbolic_operand" "")]
7943 (match_operand:DI 1 "register_operand" "r"))))]
7944 "TARGET_TLS && TARGET_ARCH64"
7945 "ldx\t[%1 + %2], %0, %%tldo_add(%3)"
7946 [(set_attr "type" "load")])
7948 (define_insn "*tldo_stb_sp32"
7949 [(set (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7950 (match_operand 3 "tld_symbolic_operand" "")]
7952 (match_operand:SI 1 "register_operand" "r")))
7953 (match_operand:QI 0 "register_operand" "=r"))]
7954 "TARGET_TLS && TARGET_ARCH32"
7955 "stb\t%0, [%1 + %2], %%tldo_add(%3)"
7956 [(set_attr "type" "store")])
7958 (define_insn "*tldo_stb_sp64"
7959 [(set (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7960 (match_operand 3 "tld_symbolic_operand" "")]
7962 (match_operand:DI 1 "register_operand" "r")))
7963 (match_operand:QI 0 "register_operand" "=r"))]
7964 "TARGET_TLS && TARGET_ARCH64"
7965 "stb\t%0, [%1 + %2], %%tldo_add(%3)"
7966 [(set_attr "type" "store")])
7968 (define_insn "*tldo_sth_sp32"
7969 [(set (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7970 (match_operand 3 "tld_symbolic_operand" "")]
7972 (match_operand:SI 1 "register_operand" "r")))
7973 (match_operand:HI 0 "register_operand" "=r"))]
7974 "TARGET_TLS && TARGET_ARCH32"
7975 "sth\t%0, [%1 + %2], %%tldo_add(%3)"
7976 [(set_attr "type" "store")])
7978 (define_insn "*tldo_sth_sp64"
7979 [(set (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7980 (match_operand 3 "tld_symbolic_operand" "")]
7982 (match_operand:DI 1 "register_operand" "r")))
7983 (match_operand:HI 0 "register_operand" "=r"))]
7984 "TARGET_TLS && TARGET_ARCH64"
7985 "sth\t%0, [%1 + %2], %%tldo_add(%3)"
7986 [(set_attr "type" "store")])
7988 (define_insn "*tldo_stw_sp32"
7989 [(set (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7990 (match_operand 3 "tld_symbolic_operand" "")]
7992 (match_operand:SI 1 "register_operand" "r")))
7993 (match_operand:SI 0 "register_operand" "=r"))]
7994 "TARGET_TLS && TARGET_ARCH32"
7995 "st\t%0, [%1 + %2], %%tldo_add(%3)"
7996 [(set_attr "type" "store")])
7998 (define_insn "*tldo_stw_sp64"
7999 [(set (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8000 (match_operand 3 "tld_symbolic_operand" "")]
8002 (match_operand:DI 1 "register_operand" "r")))
8003 (match_operand:SI 0 "register_operand" "=r"))]
8004 "TARGET_TLS && TARGET_ARCH64"
8005 "stw\t%0, [%1 + %2], %%tldo_add(%3)"
8006 [(set_attr "type" "store")])
8008 (define_insn "*tldo_stx_sp64"
8009 [(set (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8010 (match_operand 3 "tld_symbolic_operand" "")]
8012 (match_operand:DI 1 "register_operand" "r")))
8013 (match_operand:DI 0 "register_operand" "=r"))]
8014 "TARGET_TLS && TARGET_ARCH64"
8015 "stx\t%0, [%1 + %2], %%tldo_add(%3)"
8016 [(set_attr "type" "store")])
8019 ;; Stack protector instructions.
8021 (define_expand "stack_protect_set"
8022 [(match_operand 0 "memory_operand" "")
8023 (match_operand 1 "memory_operand" "")]
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);
8032 emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
8034 emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
8038 (define_insn "stack_protect_setsi"
8039 [(set (match_operand:SI 0 "memory_operand" "=m")
8040 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
8041 (set (match_scratch:SI 2 "=&r") (const_int 0))]
8043 "ld\t%1, %2\;st\t%2, %0\;mov\t0, %2"
8044 [(set_attr "type" "multi")
8045 (set_attr "length" "3")])
8047 (define_insn "stack_protect_setdi"
8048 [(set (match_operand:DI 0 "memory_operand" "=m")
8049 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
8050 (set (match_scratch:DI 2 "=&r") (const_int 0))]
8052 "ldx\t%1, %2\;stx\t%2, %0\;mov\t0, %2"
8053 [(set_attr "type" "multi")
8054 (set_attr "length" "3")])
8056 (define_expand "stack_protect_test"
8057 [(match_operand 0 "memory_operand" "")
8058 (match_operand 1 "memory_operand" "")
8059 (match_operand 2 "" "")]
8062 #ifdef TARGET_THREAD_SSP_OFFSET
8063 rtx tlsreg = gen_rtx_REG (Pmode, 7);
8064 rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
8065 operands[1] = gen_rtx_MEM (Pmode, addr);
8069 rtx temp = gen_reg_rtx (Pmode);
8070 emit_insn (gen_stack_protect_testdi (temp, operands[0], operands[1]));
8071 sparc_compare_op0 = temp;
8072 sparc_compare_op1 = const0_rtx;
8076 emit_insn (gen_stack_protect_testsi (operands[0], operands[1]));
8077 sparc_compare_op0 = operands[0];
8078 sparc_compare_op1 = operands[1];
8079 sparc_compare_emitted = gen_rtx_REG (CCmode, SPARC_ICC_REG);
8081 emit_jump_insn (gen_beq (operands[2]));
8085 (define_insn "stack_protect_testsi"
8087 (unspec:CC [(match_operand:SI 0 "memory_operand" "m")
8088 (match_operand:SI 1 "memory_operand" "m")]
8090 (set (match_scratch:SI 3 "=r") (const_int 0))
8091 (clobber (match_scratch:SI 2 "=&r"))]
8093 "ld\t%0, %2\;ld\t%1, %3\;xorcc\t%2, %3, %2\;mov\t0, %3"
8094 [(set_attr "type" "multi")
8095 (set_attr "length" "4")])
8097 (define_insn "stack_protect_testdi"
8098 [(set (match_operand:DI 0 "register_operand" "=&r")
8099 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
8100 (match_operand:DI 2 "memory_operand" "m")]
8102 (set (match_scratch:DI 3 "=r") (const_int 0))]
8104 "ldx\t%1, %0\;ldx\t%2, %3\;xor\t%0, %3, %0\;mov\t0, %3"
8105 [(set_attr "type" "multi")
8106 (set_attr "length" "4")])
8109 ;; Vector instructions.
8111 (define_insn "addv2si3"
8112 [(set (match_operand:V2SI 0 "register_operand" "=e")
8113 (plus:V2SI (match_operand:V2SI 1 "register_operand" "e")
8114 (match_operand:V2SI 2 "register_operand" "e")))]
8116 "fpadd32\t%1, %2, %0"
8117 [(set_attr "type" "fga")
8118 (set_attr "fptype" "double")])
8120 (define_insn "addv4hi3"
8121 [(set (match_operand:V4HI 0 "register_operand" "=e")
8122 (plus:V4HI (match_operand:V4HI 1 "register_operand" "e")
8123 (match_operand:V4HI 2 "register_operand" "e")))]
8125 "fpadd16\t%1, %2, %0"
8126 [(set_attr "type" "fga")
8127 (set_attr "fptype" "double")])
8129 ;; fpadd32s is emitted by the addsi3 pattern.
8131 (define_insn "addv2hi3"
8132 [(set (match_operand:V2HI 0 "register_operand" "=f")
8133 (plus:V2HI (match_operand:V2HI 1 "register_operand" "f")
8134 (match_operand:V2HI 2 "register_operand" "f")))]
8136 "fpadd16s\t%1, %2, %0"
8137 [(set_attr "type" "fga")
8138 (set_attr "fptype" "single")])
8140 (define_insn "subv2si3"
8141 [(set (match_operand:V2SI 0 "register_operand" "=e")
8142 (minus:V2SI (match_operand:V2SI 1 "register_operand" "e")
8143 (match_operand:V2SI 2 "register_operand" "e")))]
8145 "fpsub32\t%1, %2, %0"
8146 [(set_attr "type" "fga")
8147 (set_attr "fptype" "double")])
8149 (define_insn "subv4hi3"
8150 [(set (match_operand:V4HI 0 "register_operand" "=e")
8151 (minus:V4HI (match_operand:V4HI 1 "register_operand" "e")
8152 (match_operand:V4HI 2 "register_operand" "e")))]
8154 "fpsub16\t%1, %2, %0"
8155 [(set_attr "type" "fga")
8156 (set_attr "fptype" "double")])
8158 ;; fpsub32s is emitted by the subsi3 pattern.
8160 (define_insn "subv2hi3"
8161 [(set (match_operand:V2HI 0 "register_operand" "=f")
8162 (minus:V2HI (match_operand:V2HI 1 "register_operand" "f")
8163 (match_operand:V2HI 2 "register_operand" "f")))]
8165 "fpsub16s\t%1, %2, %0"
8166 [(set_attr "type" "fga")
8167 (set_attr "fptype" "single")])
8169 ;; All other logical instructions have integer equivalents so they
8170 ;; are defined together.
8172 ;; (ior (not (op1)) (not (op2))) is the canonical form of NAND.
8174 (define_insn "*nand<V64mode>_vis"
8175 [(set (match_operand:V64 0 "register_operand" "=e")
8176 (ior:V64 (not:V64 (match_operand:V64 1 "register_operand" "e"))
8177 (not:V64 (match_operand:V64 2 "register_operand" "e"))))]
8180 [(set_attr "type" "fga")
8181 (set_attr "fptype" "double")])
8183 (define_insn "*nand<V32mode>_vis"
8184 [(set (match_operand:V32 0 "register_operand" "=f")
8185 (ior:V32 (not:V32 (match_operand:V32 1 "register_operand" "f"))
8186 (not:V32 (match_operand:V32 2 "register_operand" "f"))))]
8188 "fnands\t%1, %2, %0"
8189 [(set_attr "type" "fga")
8190 (set_attr "fptype" "single")])
8192 ;; Hard to generate VIS instructions. We have builtins for these.
8194 (define_insn "fpack16_vis"
8195 [(set (match_operand:V4QI 0 "register_operand" "=f")
8196 (unspec:V4QI [(match_operand:V4HI 1 "register_operand" "e")]
8200 [(set_attr "type" "fga")
8201 (set_attr "fptype" "double")])
8203 (define_insn "fpackfix_vis"
8204 [(set (match_operand:V2HI 0 "register_operand" "=f")
8205 (unspec:V2HI [(match_operand:V2SI 1 "register_operand" "e")]
8209 [(set_attr "type" "fga")
8210 (set_attr "fptype" "double")])
8212 (define_insn "fpack32_vis"
8213 [(set (match_operand:V8QI 0 "register_operand" "=e")
8214 (unspec:V8QI [(match_operand:V2SI 1 "register_operand" "e")
8215 (match_operand:V8QI 2 "register_operand" "e")]
8218 "fpack32\t%1, %2, %0"
8219 [(set_attr "type" "fga")
8220 (set_attr "fptype" "double")])
8222 (define_insn "fexpand_vis"
8223 [(set (match_operand:V4HI 0 "register_operand" "=e")
8224 (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")]
8228 [(set_attr "type" "fga")
8229 (set_attr "fptype" "double")])
8231 ;; It may be possible to describe this operation as (1 indexed):
8232 ;; (vec_select (vec_duplicate (vec_duplicate (vec_concat 1 2)))
8233 ;; 1,5,10,14,19,23,28,32)
8234 ;; Note that (vec_merge:V8QI [(V4QI) (V4QI)] (10101010 = 170) doesn't work
8235 ;; because vec_merge expects all the operands to be of the same type.
8236 (define_insn "fpmerge_vis"
8237 [(set (match_operand:V8QI 0 "register_operand" "=e")
8238 (unspec:V8QI [(match_operand:V4QI 1 "register_operand" "f")
8239 (match_operand:V4QI 2 "register_operand" "f")]
8242 "fpmerge\t%1, %2, %0"
8243 [(set_attr "type" "fga")
8244 (set_attr "fptype" "double")])
8246 ;; Partitioned multiply instructions
8247 (define_insn "fmul8x16_vis"
8248 [(set (match_operand:V4HI 0 "register_operand" "=e")
8249 (mult:V4HI (match_operand:V4QI 1 "register_operand" "f")
8250 (match_operand:V4HI 2 "register_operand" "e")))]
8252 "fmul8x16\t%1, %2, %0"
8253 [(set_attr "type" "fpmul")
8254 (set_attr "fptype" "double")])
8256 ;; Only one of the following two insns can be a multiply.
8257 (define_insn "fmul8x16au_vis"
8258 [(set (match_operand:V4HI 0 "register_operand" "=e")
8259 (mult:V4HI (match_operand:V4QI 1 "register_operand" "f")
8260 (match_operand:V2HI 2 "register_operand" "f")))]
8262 "fmul8x16au\t%1, %2, %0"
8263 [(set_attr "type" "fpmul")
8264 (set_attr "fptype" "double")])
8266 (define_insn "fmul8x16al_vis"
8267 [(set (match_operand:V4HI 0 "register_operand" "=e")
8268 (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")
8269 (match_operand:V2HI 2 "register_operand" "f")]
8272 "fmul8x16al\t%1, %2, %0"
8273 [(set_attr "type" "fpmul")
8274 (set_attr "fptype" "double")])
8276 ;; Only one of the following two insns can be a multiply.
8277 (define_insn "fmul8sux16_vis"
8278 [(set (match_operand:V4HI 0 "register_operand" "=e")
8279 (mult:V4HI (match_operand:V8QI 1 "register_operand" "e")
8280 (match_operand:V4HI 2 "register_operand" "e")))]
8282 "fmul8sux16\t%1, %2, %0"
8283 [(set_attr "type" "fpmul")
8284 (set_attr "fptype" "double")])
8286 (define_insn "fmul8ulx16_vis"
8287 [(set (match_operand:V4HI 0 "register_operand" "=e")
8288 (unspec:V4HI [(match_operand:V8QI 1 "register_operand" "e")
8289 (match_operand:V4HI 2 "register_operand" "e")]
8292 "fmul8ulx16\t%1, %2, %0"
8293 [(set_attr "type" "fpmul")
8294 (set_attr "fptype" "double")])
8296 ;; Only one of the following two insns can be a multiply.
8297 (define_insn "fmuld8sux16_vis"
8298 [(set (match_operand:V2SI 0 "register_operand" "=e")
8299 (mult:V2SI (match_operand:V4QI 1 "register_operand" "f")
8300 (match_operand:V2HI 2 "register_operand" "f")))]
8302 "fmuld8sux16\t%1, %2, %0"
8303 [(set_attr "type" "fpmul")
8304 (set_attr "fptype" "double")])
8306 (define_insn "fmuld8ulx16_vis"
8307 [(set (match_operand:V2SI 0 "register_operand" "=e")
8308 (unspec:V2SI [(match_operand:V4QI 1 "register_operand" "f")
8309 (match_operand:V2HI 2 "register_operand" "f")]
8312 "fmuld8ulx16\t%1, %2, %0"
8313 [(set_attr "type" "fpmul")
8314 (set_attr "fptype" "double")])
8316 ;; Using faligndata only makes sense after an alignaddr since the choice of
8317 ;; bytes to take out of each operand is dependent on the results of the last
8319 (define_insn "faligndata<V64I:mode>_vis"
8320 [(set (match_operand:V64I 0 "register_operand" "=e")
8321 (unspec:V64I [(match_operand:V64I 1 "register_operand" "e")
8322 (match_operand:V64I 2 "register_operand" "e")]
8325 "faligndata\t%1, %2, %0"
8326 [(set_attr "type" "fga")
8327 (set_attr "fptype" "double")])
8329 (define_insn "alignaddr<P:mode>_vis"
8330 [(set (match_operand:P 0 "register_operand" "=r")
8331 (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
8332 (match_operand:P 2 "register_or_zero_operand" "rJ")]
8335 "alignaddr\t%r1, %r2, %0")
8337 (define_insn "pdist_vis"
8338 [(set (match_operand:DI 0 "register_operand" "=e")
8339 (unspec:DI [(match_operand:V8QI 1 "register_operand" "e")
8340 (match_operand:V8QI 2 "register_operand" "e")
8341 (match_operand:DI 3 "register_operand" "0")]
8345 [(set_attr "type" "fga")
8346 (set_attr "fptype" "double")])