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.
325 (include "predicates.md")
328 ;; Compare instructions.
330 ;; We generate RTL for comparisons and branches by having the cmpxx
331 ;; patterns store away the operands. Then, the scc and bcc patterns
332 ;; emit RTL for both the compare and the branch.
334 ;; We do this because we want to generate different code for an sne and
335 ;; seq insn. In those cases, if the second operand of the compare is not
336 ;; const0_rtx, we want to compute the xor of the two operands and test
339 ;; We start with the DEFINE_EXPANDs, then the DEFINE_INSNs to match
340 ;; the patterns. Finally, we have the DEFINE_SPLITs for some of the scc
341 ;; insns that actually require more than one machine instruction.
343 (define_expand "cmpsi"
345 (compare:CC (match_operand:SI 0 "compare_operand" "")
346 (match_operand:SI 1 "arith_operand" "")))]
349 if (GET_CODE (operands[0]) == ZERO_EXTRACT && operands[1] != const0_rtx)
350 operands[0] = force_reg (SImode, operands[0]);
352 sparc_compare_op0 = operands[0];
353 sparc_compare_op1 = operands[1];
357 (define_expand "cmpdi"
359 (compare:CCX (match_operand:DI 0 "compare_operand" "")
360 (match_operand:DI 1 "arith_operand" "")))]
363 if (GET_CODE (operands[0]) == ZERO_EXTRACT && operands[1] != const0_rtx)
364 operands[0] = force_reg (DImode, operands[0]);
366 sparc_compare_op0 = operands[0];
367 sparc_compare_op1 = operands[1];
371 (define_expand "cmpsf"
372 ;; The 96 here isn't ever used by anyone.
374 (compare:CCFP (match_operand:SF 0 "register_operand" "")
375 (match_operand:SF 1 "register_operand" "")))]
378 sparc_compare_op0 = operands[0];
379 sparc_compare_op1 = operands[1];
383 (define_expand "cmpdf"
384 ;; The 96 here isn't ever used by anyone.
386 (compare:CCFP (match_operand:DF 0 "register_operand" "")
387 (match_operand:DF 1 "register_operand" "")))]
390 sparc_compare_op0 = operands[0];
391 sparc_compare_op1 = operands[1];
395 (define_expand "cmptf"
396 ;; The 96 here isn't ever used by anyone.
398 (compare:CCFP (match_operand:TF 0 "register_operand" "")
399 (match_operand:TF 1 "register_operand" "")))]
402 sparc_compare_op0 = operands[0];
403 sparc_compare_op1 = operands[1];
407 ;; Now the compare DEFINE_INSNs.
409 (define_insn "*cmpsi_insn"
411 (compare:CC (match_operand:SI 0 "register_operand" "r")
412 (match_operand:SI 1 "arith_operand" "rI")))]
415 [(set_attr "type" "compare")])
417 (define_insn "*cmpdi_sp64"
419 (compare:CCX (match_operand:DI 0 "register_operand" "r")
420 (match_operand:DI 1 "arith_operand" "rI")))]
423 [(set_attr "type" "compare")])
425 (define_insn "*cmpsf_fpe"
426 [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
427 (compare:CCFPE (match_operand:SF 1 "register_operand" "f")
428 (match_operand:SF 2 "register_operand" "f")))]
432 return "fcmpes\t%0, %1, %2";
433 return "fcmpes\t%1, %2";
435 [(set_attr "type" "fpcmp")])
437 (define_insn "*cmpdf_fpe"
438 [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
439 (compare:CCFPE (match_operand:DF 1 "register_operand" "e")
440 (match_operand:DF 2 "register_operand" "e")))]
444 return "fcmped\t%0, %1, %2";
445 return "fcmped\t%1, %2";
447 [(set_attr "type" "fpcmp")
448 (set_attr "fptype" "double")])
450 (define_insn "*cmptf_fpe"
451 [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
452 (compare:CCFPE (match_operand:TF 1 "register_operand" "e")
453 (match_operand:TF 2 "register_operand" "e")))]
454 "TARGET_FPU && TARGET_HARD_QUAD"
457 return "fcmpeq\t%0, %1, %2";
458 return "fcmpeq\t%1, %2";
460 [(set_attr "type" "fpcmp")])
462 (define_insn "*cmpsf_fp"
463 [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
464 (compare:CCFP (match_operand:SF 1 "register_operand" "f")
465 (match_operand:SF 2 "register_operand" "f")))]
469 return "fcmps\t%0, %1, %2";
470 return "fcmps\t%1, %2";
472 [(set_attr "type" "fpcmp")])
474 (define_insn "*cmpdf_fp"
475 [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
476 (compare:CCFP (match_operand:DF 1 "register_operand" "e")
477 (match_operand:DF 2 "register_operand" "e")))]
481 return "fcmpd\t%0, %1, %2";
482 return "fcmpd\t%1, %2";
484 [(set_attr "type" "fpcmp")
485 (set_attr "fptype" "double")])
487 (define_insn "*cmptf_fp"
488 [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
489 (compare:CCFP (match_operand:TF 1 "register_operand" "e")
490 (match_operand:TF 2 "register_operand" "e")))]
491 "TARGET_FPU && TARGET_HARD_QUAD"
494 return "fcmpq\t%0, %1, %2";
495 return "fcmpq\t%1, %2";
497 [(set_attr "type" "fpcmp")])
499 ;; Next come the scc insns. For seq, sne, sgeu, and sltu, we can do this
500 ;; without jumps using the addx/subx instructions. For seq/sne on v9 we use
501 ;; the same code as v8 (the addx/subx method has more applications). The
502 ;; exception to this is "reg != 0" which can be done in one instruction on v9
503 ;; (so we do it). For the rest, on v9 we use conditional moves; on v8, we do
506 ;; Seq_special[_xxx] and sne_special[_xxx] clobber the CC reg, because they
507 ;; generate addcc/subcc instructions.
509 (define_expand "seqsi_special"
511 (xor:SI (match_operand:SI 1 "register_operand" "")
512 (match_operand:SI 2 "register_operand" "")))
513 (parallel [(set (match_operand:SI 0 "register_operand" "")
514 (eq:SI (match_dup 3) (const_int 0)))
515 (clobber (reg:CC 100))])]
517 { operands[3] = gen_reg_rtx (SImode); })
519 (define_expand "seqdi_special"
521 (xor:DI (match_operand:DI 1 "register_operand" "")
522 (match_operand:DI 2 "register_operand" "")))
523 (set (match_operand:DI 0 "register_operand" "")
524 (eq:DI (match_dup 3) (const_int 0)))]
526 { operands[3] = gen_reg_rtx (DImode); })
528 (define_expand "snesi_special"
530 (xor:SI (match_operand:SI 1 "register_operand" "")
531 (match_operand:SI 2 "register_operand" "")))
532 (parallel [(set (match_operand:SI 0 "register_operand" "")
533 (ne:SI (match_dup 3) (const_int 0)))
534 (clobber (reg:CC 100))])]
536 { operands[3] = gen_reg_rtx (SImode); })
538 (define_expand "snedi_special"
540 (xor:DI (match_operand:DI 1 "register_operand" "")
541 (match_operand:DI 2 "register_operand" "")))
542 (set (match_operand:DI 0 "register_operand" "")
543 (ne:DI (match_dup 3) (const_int 0)))]
545 { operands[3] = gen_reg_rtx (DImode); })
547 (define_expand "seqdi_special_trunc"
549 (xor:DI (match_operand:DI 1 "register_operand" "")
550 (match_operand:DI 2 "register_operand" "")))
551 (set (match_operand:SI 0 "register_operand" "")
552 (eq:SI (match_dup 3) (const_int 0)))]
554 { operands[3] = gen_reg_rtx (DImode); })
556 (define_expand "snedi_special_trunc"
558 (xor:DI (match_operand:DI 1 "register_operand" "")
559 (match_operand:DI 2 "register_operand" "")))
560 (set (match_operand:SI 0 "register_operand" "")
561 (ne:SI (match_dup 3) (const_int 0)))]
563 { operands[3] = gen_reg_rtx (DImode); })
565 (define_expand "seqsi_special_extend"
567 (xor:SI (match_operand:SI 1 "register_operand" "")
568 (match_operand:SI 2 "register_operand" "")))
569 (parallel [(set (match_operand:DI 0 "register_operand" "")
570 (eq:DI (match_dup 3) (const_int 0)))
571 (clobber (reg:CC 100))])]
573 { operands[3] = gen_reg_rtx (SImode); })
575 (define_expand "snesi_special_extend"
577 (xor:SI (match_operand:SI 1 "register_operand" "")
578 (match_operand:SI 2 "register_operand" "")))
579 (parallel [(set (match_operand:DI 0 "register_operand" "")
580 (ne:DI (match_dup 3) (const_int 0)))
581 (clobber (reg:CC 100))])]
583 { operands[3] = gen_reg_rtx (SImode); })
585 ;; ??? v9: Operand 0 needs a mode, so SImode was chosen.
586 ;; However, the code handles both SImode and DImode.
588 [(set (match_operand:SI 0 "int_register_operand" "")
589 (eq:SI (match_dup 1) (const_int 0)))]
592 if (GET_MODE (sparc_compare_op0) == SImode)
596 if (GET_MODE (operands[0]) == SImode)
597 pat = gen_seqsi_special (operands[0], sparc_compare_op0,
599 else if (! TARGET_ARCH64)
602 pat = gen_seqsi_special_extend (operands[0], sparc_compare_op0,
607 else if (GET_MODE (sparc_compare_op0) == DImode)
613 else if (GET_MODE (operands[0]) == SImode)
614 pat = gen_seqdi_special_trunc (operands[0], sparc_compare_op0,
617 pat = gen_seqdi_special (operands[0], sparc_compare_op0,
622 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
624 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, EQ);
625 emit_jump_insn (gen_sne (operands[0]));
630 if (gen_v9_scc (EQ, operands))
637 ;; ??? v9: Operand 0 needs a mode, so SImode was chosen.
638 ;; However, the code handles both SImode and DImode.
640 [(set (match_operand:SI 0 "int_register_operand" "")
641 (ne:SI (match_dup 1) (const_int 0)))]
644 if (GET_MODE (sparc_compare_op0) == SImode)
648 if (GET_MODE (operands[0]) == SImode)
649 pat = gen_snesi_special (operands[0], sparc_compare_op0,
651 else if (! TARGET_ARCH64)
654 pat = gen_snesi_special_extend (operands[0], sparc_compare_op0,
659 else if (GET_MODE (sparc_compare_op0) == DImode)
665 else if (GET_MODE (operands[0]) == SImode)
666 pat = gen_snedi_special_trunc (operands[0], sparc_compare_op0,
669 pat = gen_snedi_special (operands[0], sparc_compare_op0,
674 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
676 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, NE);
677 emit_jump_insn (gen_sne (operands[0]));
682 if (gen_v9_scc (NE, operands))
690 [(set (match_operand:SI 0 "int_register_operand" "")
691 (gt:SI (match_dup 1) (const_int 0)))]
694 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
696 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GT);
697 emit_jump_insn (gen_sne (operands[0]));
702 if (gen_v9_scc (GT, operands))
710 [(set (match_operand:SI 0 "int_register_operand" "")
711 (lt:SI (match_dup 1) (const_int 0)))]
714 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
716 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LT);
717 emit_jump_insn (gen_sne (operands[0]));
722 if (gen_v9_scc (LT, operands))
730 [(set (match_operand:SI 0 "int_register_operand" "")
731 (ge:SI (match_dup 1) (const_int 0)))]
734 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
736 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GE);
737 emit_jump_insn (gen_sne (operands[0]));
742 if (gen_v9_scc (GE, operands))
750 [(set (match_operand:SI 0 "int_register_operand" "")
751 (le:SI (match_dup 1) (const_int 0)))]
754 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
756 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LE);
757 emit_jump_insn (gen_sne (operands[0]));
762 if (gen_v9_scc (LE, operands))
769 (define_expand "sgtu"
770 [(set (match_operand:SI 0 "int_register_operand" "")
771 (gtu:SI (match_dup 1) (const_int 0)))]
778 /* We can do ltu easily, so if both operands are registers, swap them and
780 if ((GET_CODE (sparc_compare_op0) == REG
781 || GET_CODE (sparc_compare_op0) == SUBREG)
782 && (GET_CODE (sparc_compare_op1) == REG
783 || GET_CODE (sparc_compare_op1) == SUBREG))
785 tem = sparc_compare_op0;
786 sparc_compare_op0 = sparc_compare_op1;
787 sparc_compare_op1 = tem;
788 pat = gen_sltu (operands[0]);
797 if (gen_v9_scc (GTU, operands))
803 (define_expand "sltu"
804 [(set (match_operand:SI 0 "int_register_operand" "")
805 (ltu:SI (match_dup 1) (const_int 0)))]
810 if (gen_v9_scc (LTU, operands))
813 operands[1] = gen_compare_reg (LTU);
816 (define_expand "sgeu"
817 [(set (match_operand:SI 0 "int_register_operand" "")
818 (geu:SI (match_dup 1) (const_int 0)))]
823 if (gen_v9_scc (GEU, operands))
826 operands[1] = gen_compare_reg (GEU);
829 (define_expand "sleu"
830 [(set (match_operand:SI 0 "int_register_operand" "")
831 (leu:SI (match_dup 1) (const_int 0)))]
838 /* We can do geu easily, so if both operands are registers, swap them and
840 if ((GET_CODE (sparc_compare_op0) == REG
841 || GET_CODE (sparc_compare_op0) == SUBREG)
842 && (GET_CODE (sparc_compare_op1) == REG
843 || GET_CODE (sparc_compare_op1) == SUBREG))
845 tem = sparc_compare_op0;
846 sparc_compare_op0 = sparc_compare_op1;
847 sparc_compare_op1 = tem;
848 pat = gen_sgeu (operands[0]);
857 if (gen_v9_scc (LEU, operands))
863 ;; Now the DEFINE_INSNs for the scc cases.
865 ;; The SEQ and SNE patterns are special because they can be done
866 ;; without any branching and do not involve a COMPARE. We want
867 ;; them to always use the splits below so the results can be
870 (define_insn_and_split "*snesi_zero"
871 [(set (match_operand:SI 0 "register_operand" "=r")
872 (ne:SI (match_operand:SI 1 "register_operand" "r")
874 (clobber (reg:CC 100))]
878 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
880 (set (match_dup 0) (ltu:SI (reg:CC 100) (const_int 0)))]
882 [(set_attr "length" "2")])
884 (define_insn_and_split "*neg_snesi_zero"
885 [(set (match_operand:SI 0 "register_operand" "=r")
886 (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
888 (clobber (reg:CC 100))]
892 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
894 (set (match_dup 0) (neg:SI (ltu:SI (reg:CC 100) (const_int 0))))]
896 [(set_attr "length" "2")])
898 (define_insn_and_split "*snesi_zero_extend"
899 [(set (match_operand:DI 0 "register_operand" "=r")
900 (ne:DI (match_operand:SI 1 "register_operand" "r")
902 (clobber (reg:CC 100))]
906 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (minus:SI (const_int 0)
909 (set (match_dup 0) (zero_extend:DI (plus:SI (plus:SI (const_int 0)
911 (ltu:SI (reg:CC_NOOV 100)
914 [(set_attr "length" "2")])
916 (define_insn_and_split "*snedi_zero"
917 [(set (match_operand:DI 0 "register_operand" "=&r")
918 (ne:DI (match_operand:DI 1 "register_operand" "r")
922 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
923 [(set (match_dup 0) (const_int 0))
924 (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
929 [(set_attr "length" "2")])
931 (define_insn_and_split "*neg_snedi_zero"
932 [(set (match_operand:DI 0 "register_operand" "=&r")
933 (neg:DI (ne:DI (match_operand:DI 1 "register_operand" "r")
937 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
938 [(set (match_dup 0) (const_int 0))
939 (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
944 [(set_attr "length" "2")])
946 (define_insn_and_split "*snedi_zero_trunc"
947 [(set (match_operand:SI 0 "register_operand" "=&r")
948 (ne:SI (match_operand:DI 1 "register_operand" "r")
952 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
953 [(set (match_dup 0) (const_int 0))
954 (set (match_dup 0) (if_then_else:SI (ne:DI (match_dup 1)
959 [(set_attr "length" "2")])
961 (define_insn_and_split "*seqsi_zero"
962 [(set (match_operand:SI 0 "register_operand" "=r")
963 (eq:SI (match_operand:SI 1 "register_operand" "r")
965 (clobber (reg:CC 100))]
969 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
971 (set (match_dup 0) (geu:SI (reg:CC 100) (const_int 0)))]
973 [(set_attr "length" "2")])
975 (define_insn_and_split "*neg_seqsi_zero"
976 [(set (match_operand:SI 0 "register_operand" "=r")
977 (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
979 (clobber (reg:CC 100))]
983 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
985 (set (match_dup 0) (neg:SI (geu:SI (reg:CC 100) (const_int 0))))]
987 [(set_attr "length" "2")])
989 (define_insn_and_split "*seqsi_zero_extend"
990 [(set (match_operand:DI 0 "register_operand" "=r")
991 (eq:DI (match_operand:SI 1 "register_operand" "r")
993 (clobber (reg:CC 100))]
997 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (minus:SI (const_int 0)
1000 (set (match_dup 0) (zero_extend:DI (minus:SI (minus:SI (const_int 0)
1002 (ltu:SI (reg:CC_NOOV 100)
1005 [(set_attr "length" "2")])
1007 (define_insn_and_split "*seqdi_zero"
1008 [(set (match_operand:DI 0 "register_operand" "=&r")
1009 (eq:DI (match_operand:DI 1 "register_operand" "r")
1013 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
1014 [(set (match_dup 0) (const_int 0))
1015 (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
1020 [(set_attr "length" "2")])
1022 (define_insn_and_split "*neg_seqdi_zero"
1023 [(set (match_operand:DI 0 "register_operand" "=&r")
1024 (neg:DI (eq:DI (match_operand:DI 1 "register_operand" "r")
1028 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
1029 [(set (match_dup 0) (const_int 0))
1030 (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
1035 [(set_attr "length" "2")])
1037 (define_insn_and_split "*seqdi_zero_trunc"
1038 [(set (match_operand:SI 0 "register_operand" "=&r")
1039 (eq:SI (match_operand:DI 1 "register_operand" "r")
1043 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
1044 [(set (match_dup 0) (const_int 0))
1045 (set (match_dup 0) (if_then_else:SI (eq:DI (match_dup 1)
1050 [(set_attr "length" "2")])
1052 ;; We can also do (x + (i == 0)) and related, so put them in.
1053 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1056 (define_insn_and_split "*x_plus_i_ne_0"
1057 [(set (match_operand:SI 0 "register_operand" "=r")
1058 (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
1060 (match_operand:SI 2 "register_operand" "r")))
1061 (clobber (reg:CC 100))]
1065 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1067 (set (match_dup 0) (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1070 [(set_attr "length" "2")])
1072 (define_insn_and_split "*x_minus_i_ne_0"
1073 [(set (match_operand:SI 0 "register_operand" "=r")
1074 (minus:SI (match_operand:SI 2 "register_operand" "r")
1075 (ne:SI (match_operand:SI 1 "register_operand" "r")
1077 (clobber (reg:CC 100))]
1081 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1083 (set (match_dup 0) (minus:SI (match_dup 2)
1084 (ltu:SI (reg:CC 100) (const_int 0))))]
1086 [(set_attr "length" "2")])
1088 (define_insn_and_split "*x_plus_i_eq_0"
1089 [(set (match_operand:SI 0 "register_operand" "=r")
1090 (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
1092 (match_operand:SI 2 "register_operand" "r")))
1093 (clobber (reg:CC 100))]
1097 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1099 (set (match_dup 0) (plus:SI (geu:SI (reg:CC 100) (const_int 0))
1102 [(set_attr "length" "2")])
1104 (define_insn_and_split "*x_minus_i_eq_0"
1105 [(set (match_operand:SI 0 "register_operand" "=r")
1106 (minus:SI (match_operand:SI 2 "register_operand" "r")
1107 (eq:SI (match_operand:SI 1 "register_operand" "r")
1109 (clobber (reg:CC 100))]
1113 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1115 (set (match_dup 0) (minus:SI (match_dup 2)
1116 (geu:SI (reg:CC 100) (const_int 0))))]
1118 [(set_attr "length" "2")])
1120 ;; We can also do GEU and LTU directly, but these operate after a compare.
1121 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1124 (define_insn "*sltu_insn"
1125 [(set (match_operand:SI 0 "register_operand" "=r")
1126 (ltu:SI (reg:CC 100) (const_int 0)))]
1129 [(set_attr "type" "ialuX")])
1131 (define_insn "*neg_sltu_insn"
1132 [(set (match_operand:SI 0 "register_operand" "=r")
1133 (neg:SI (ltu:SI (reg:CC 100) (const_int 0))))]
1136 [(set_attr "type" "ialuX")])
1138 ;; ??? Combine should canonicalize these next two to the same pattern.
1139 (define_insn "*neg_sltu_minus_x"
1140 [(set (match_operand:SI 0 "register_operand" "=r")
1141 (minus:SI (neg:SI (ltu:SI (reg:CC 100) (const_int 0)))
1142 (match_operand:SI 1 "arith_operand" "rI")))]
1144 "subx\t%%g0, %1, %0"
1145 [(set_attr "type" "ialuX")])
1147 (define_insn "*neg_sltu_plus_x"
1148 [(set (match_operand:SI 0 "register_operand" "=r")
1149 (neg:SI (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1150 (match_operand:SI 1 "arith_operand" "rI"))))]
1152 "subx\t%%g0, %1, %0"
1153 [(set_attr "type" "ialuX")])
1155 (define_insn "*sgeu_insn"
1156 [(set (match_operand:SI 0 "register_operand" "=r")
1157 (geu:SI (reg:CC 100) (const_int 0)))]
1159 "subx\t%%g0, -1, %0"
1160 [(set_attr "type" "ialuX")])
1162 (define_insn "*neg_sgeu_insn"
1163 [(set (match_operand:SI 0 "register_operand" "=r")
1164 (neg:SI (geu:SI (reg:CC 100) (const_int 0))))]
1166 "addx\t%%g0, -1, %0"
1167 [(set_attr "type" "ialuX")])
1169 ;; We can also do (x + ((unsigned) i >= 0)) and related, so put them in.
1170 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1173 (define_insn "*sltu_plus_x"
1174 [(set (match_operand:SI 0 "register_operand" "=r")
1175 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1176 (match_operand:SI 1 "arith_operand" "rI")))]
1178 "addx\t%%g0, %1, %0"
1179 [(set_attr "type" "ialuX")])
1181 (define_insn "*sltu_plus_x_plus_y"
1182 [(set (match_operand:SI 0 "register_operand" "=r")
1183 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1184 (plus:SI (match_operand:SI 1 "arith_operand" "%r")
1185 (match_operand:SI 2 "arith_operand" "rI"))))]
1188 [(set_attr "type" "ialuX")])
1190 (define_insn "*x_minus_sltu"
1191 [(set (match_operand:SI 0 "register_operand" "=r")
1192 (minus:SI (match_operand:SI 1 "register_operand" "r")
1193 (ltu:SI (reg:CC 100) (const_int 0))))]
1196 [(set_attr "type" "ialuX")])
1198 ;; ??? Combine should canonicalize these next two to the same pattern.
1199 (define_insn "*x_minus_y_minus_sltu"
1200 [(set (match_operand:SI 0 "register_operand" "=r")
1201 (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
1202 (match_operand:SI 2 "arith_operand" "rI"))
1203 (ltu:SI (reg:CC 100) (const_int 0))))]
1206 [(set_attr "type" "ialuX")])
1208 (define_insn "*x_minus_sltu_plus_y"
1209 [(set (match_operand:SI 0 "register_operand" "=r")
1210 (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
1211 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1212 (match_operand:SI 2 "arith_operand" "rI"))))]
1215 [(set_attr "type" "ialuX")])
1217 (define_insn "*sgeu_plus_x"
1218 [(set (match_operand:SI 0 "register_operand" "=r")
1219 (plus:SI (geu:SI (reg:CC 100) (const_int 0))
1220 (match_operand:SI 1 "register_operand" "r")))]
1223 [(set_attr "type" "ialuX")])
1225 (define_insn "*x_minus_sgeu"
1226 [(set (match_operand:SI 0 "register_operand" "=r")
1227 (minus:SI (match_operand:SI 1 "register_operand" "r")
1228 (geu:SI (reg:CC 100) (const_int 0))))]
1231 [(set_attr "type" "ialuX")])
1234 [(set (match_operand:SI 0 "register_operand" "")
1235 (match_operator:SI 2 "noov_compare_operator"
1236 [(match_operand 1 "icc_or_fcc_register_operand" "")
1239 && REGNO (operands[1]) == SPARC_ICC_REG
1240 && (GET_MODE (operands[1]) == CCXmode
1241 /* 32-bit LTU/GEU are better implemented using addx/subx. */
1242 || (GET_CODE (operands[2]) != LTU && GET_CODE (operands[2]) != GEU))"
1243 [(set (match_dup 0) (const_int 0))
1245 (if_then_else:SI (match_op_dup:SI 2 [(match_dup 1) (const_int 0)])
1251 ;; These control RTL generation for conditional jump insns
1253 ;; The quad-word fp compare library routines all return nonzero to indicate
1254 ;; true, which is different from the equivalent libgcc routines, so we must
1255 ;; handle them specially here.
1257 (define_expand "beq"
1259 (if_then_else (eq (match_dup 1) (const_int 0))
1260 (label_ref (match_operand 0 "" ""))
1264 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1265 && GET_CODE (sparc_compare_op0) == REG
1266 && GET_MODE (sparc_compare_op0) == DImode)
1268 emit_v9_brxx_insn (EQ, sparc_compare_op0, operands[0]);
1271 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1273 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, EQ);
1274 emit_jump_insn (gen_bne (operands[0]));
1277 operands[1] = gen_compare_reg (EQ);
1280 (define_expand "bne"
1282 (if_then_else (ne (match_dup 1) (const_int 0))
1283 (label_ref (match_operand 0 "" ""))
1287 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1288 && GET_CODE (sparc_compare_op0) == REG
1289 && GET_MODE (sparc_compare_op0) == DImode)
1291 emit_v9_brxx_insn (NE, sparc_compare_op0, operands[0]);
1294 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1296 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, NE);
1297 emit_jump_insn (gen_bne (operands[0]));
1300 operands[1] = gen_compare_reg (NE);
1303 (define_expand "bgt"
1305 (if_then_else (gt (match_dup 1) (const_int 0))
1306 (label_ref (match_operand 0 "" ""))
1310 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1311 && GET_CODE (sparc_compare_op0) == REG
1312 && GET_MODE (sparc_compare_op0) == DImode)
1314 emit_v9_brxx_insn (GT, sparc_compare_op0, operands[0]);
1317 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1319 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GT);
1320 emit_jump_insn (gen_bne (operands[0]));
1323 operands[1] = gen_compare_reg (GT);
1326 (define_expand "bgtu"
1328 (if_then_else (gtu (match_dup 1) (const_int 0))
1329 (label_ref (match_operand 0 "" ""))
1333 operands[1] = gen_compare_reg (GTU);
1336 (define_expand "blt"
1338 (if_then_else (lt (match_dup 1) (const_int 0))
1339 (label_ref (match_operand 0 "" ""))
1343 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1344 && GET_CODE (sparc_compare_op0) == REG
1345 && GET_MODE (sparc_compare_op0) == DImode)
1347 emit_v9_brxx_insn (LT, sparc_compare_op0, operands[0]);
1350 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1352 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LT);
1353 emit_jump_insn (gen_bne (operands[0]));
1356 operands[1] = gen_compare_reg (LT);
1359 (define_expand "bltu"
1361 (if_then_else (ltu (match_dup 1) (const_int 0))
1362 (label_ref (match_operand 0 "" ""))
1366 operands[1] = gen_compare_reg (LTU);
1369 (define_expand "bge"
1371 (if_then_else (ge (match_dup 1) (const_int 0))
1372 (label_ref (match_operand 0 "" ""))
1376 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1377 && GET_CODE (sparc_compare_op0) == REG
1378 && GET_MODE (sparc_compare_op0) == DImode)
1380 emit_v9_brxx_insn (GE, sparc_compare_op0, operands[0]);
1383 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1385 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GE);
1386 emit_jump_insn (gen_bne (operands[0]));
1389 operands[1] = gen_compare_reg (GE);
1392 (define_expand "bgeu"
1394 (if_then_else (geu (match_dup 1) (const_int 0))
1395 (label_ref (match_operand 0 "" ""))
1399 operands[1] = gen_compare_reg (GEU);
1402 (define_expand "ble"
1404 (if_then_else (le (match_dup 1) (const_int 0))
1405 (label_ref (match_operand 0 "" ""))
1409 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1410 && GET_CODE (sparc_compare_op0) == REG
1411 && GET_MODE (sparc_compare_op0) == DImode)
1413 emit_v9_brxx_insn (LE, sparc_compare_op0, operands[0]);
1416 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1418 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LE);
1419 emit_jump_insn (gen_bne (operands[0]));
1422 operands[1] = gen_compare_reg (LE);
1425 (define_expand "bleu"
1427 (if_then_else (leu (match_dup 1) (const_int 0))
1428 (label_ref (match_operand 0 "" ""))
1432 operands[1] = gen_compare_reg (LEU);
1435 (define_expand "bunordered"
1437 (if_then_else (unordered (match_dup 1) (const_int 0))
1438 (label_ref (match_operand 0 "" ""))
1442 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1444 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1,
1446 emit_jump_insn (gen_beq (operands[0]));
1449 operands[1] = gen_compare_reg (UNORDERED);
1452 (define_expand "bordered"
1454 (if_then_else (ordered (match_dup 1) (const_int 0))
1455 (label_ref (match_operand 0 "" ""))
1459 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1461 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, ORDERED);
1462 emit_jump_insn (gen_bne (operands[0]));
1465 operands[1] = gen_compare_reg (ORDERED);
1468 (define_expand "bungt"
1470 (if_then_else (ungt (match_dup 1) (const_int 0))
1471 (label_ref (match_operand 0 "" ""))
1475 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1477 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNGT);
1478 emit_jump_insn (gen_bgt (operands[0]));
1481 operands[1] = gen_compare_reg (UNGT);
1484 (define_expand "bunlt"
1486 (if_then_else (unlt (match_dup 1) (const_int 0))
1487 (label_ref (match_operand 0 "" ""))
1491 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1493 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNLT);
1494 emit_jump_insn (gen_bne (operands[0]));
1497 operands[1] = gen_compare_reg (UNLT);
1500 (define_expand "buneq"
1502 (if_then_else (uneq (match_dup 1) (const_int 0))
1503 (label_ref (match_operand 0 "" ""))
1507 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1509 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNEQ);
1510 emit_jump_insn (gen_beq (operands[0]));
1513 operands[1] = gen_compare_reg (UNEQ);
1516 (define_expand "bunge"
1518 (if_then_else (unge (match_dup 1) (const_int 0))
1519 (label_ref (match_operand 0 "" ""))
1523 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1525 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNGE);
1526 emit_jump_insn (gen_bne (operands[0]));
1529 operands[1] = gen_compare_reg (UNGE);
1532 (define_expand "bunle"
1534 (if_then_else (unle (match_dup 1) (const_int 0))
1535 (label_ref (match_operand 0 "" ""))
1539 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1541 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNLE);
1542 emit_jump_insn (gen_bne (operands[0]));
1545 operands[1] = gen_compare_reg (UNLE);
1548 (define_expand "bltgt"
1550 (if_then_else (ltgt (match_dup 1) (const_int 0))
1551 (label_ref (match_operand 0 "" ""))
1555 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1557 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LTGT);
1558 emit_jump_insn (gen_bne (operands[0]));
1561 operands[1] = gen_compare_reg (LTGT);
1564 ;; Now match both normal and inverted jump.
1566 ;; XXX fpcmp nop braindamage
1567 (define_insn "*normal_branch"
1569 (if_then_else (match_operator 0 "noov_compare_operator"
1570 [(reg 100) (const_int 0)])
1571 (label_ref (match_operand 1 "" ""))
1575 return output_cbranch (operands[0], operands[1], 1, 0,
1576 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1579 [(set_attr "type" "branch")
1580 (set_attr "branch_type" "icc")])
1582 ;; XXX fpcmp nop braindamage
1583 (define_insn "*inverted_branch"
1585 (if_then_else (match_operator 0 "noov_compare_operator"
1586 [(reg 100) (const_int 0)])
1588 (label_ref (match_operand 1 "" ""))))]
1591 return output_cbranch (operands[0], operands[1], 1, 1,
1592 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1595 [(set_attr "type" "branch")
1596 (set_attr "branch_type" "icc")])
1598 ;; XXX fpcmp nop braindamage
1599 (define_insn "*normal_fp_branch"
1601 (if_then_else (match_operator 1 "comparison_operator"
1602 [(match_operand:CCFP 0 "fcc_register_operand" "c")
1604 (label_ref (match_operand 2 "" ""))
1608 return output_cbranch (operands[1], operands[2], 2, 0,
1609 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1612 [(set_attr "type" "branch")
1613 (set_attr "branch_type" "fcc")])
1615 ;; XXX fpcmp nop braindamage
1616 (define_insn "*inverted_fp_branch"
1618 (if_then_else (match_operator 1 "comparison_operator"
1619 [(match_operand:CCFP 0 "fcc_register_operand" "c")
1622 (label_ref (match_operand 2 "" ""))))]
1625 return output_cbranch (operands[1], operands[2], 2, 1,
1626 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1629 [(set_attr "type" "branch")
1630 (set_attr "branch_type" "fcc")])
1632 ;; XXX fpcmp nop braindamage
1633 (define_insn "*normal_fpe_branch"
1635 (if_then_else (match_operator 1 "comparison_operator"
1636 [(match_operand:CCFPE 0 "fcc_register_operand" "c")
1638 (label_ref (match_operand 2 "" ""))
1642 return output_cbranch (operands[1], operands[2], 2, 0,
1643 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1646 [(set_attr "type" "branch")
1647 (set_attr "branch_type" "fcc")])
1649 ;; XXX fpcmp nop braindamage
1650 (define_insn "*inverted_fpe_branch"
1652 (if_then_else (match_operator 1 "comparison_operator"
1653 [(match_operand:CCFPE 0 "fcc_register_operand" "c")
1656 (label_ref (match_operand 2 "" ""))))]
1659 return output_cbranch (operands[1], operands[2], 2, 1,
1660 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1663 [(set_attr "type" "branch")
1664 (set_attr "branch_type" "fcc")])
1666 ;; SPARC V9-specific jump insns. None of these are guaranteed to be
1667 ;; in the architecture.
1669 ;; There are no 32 bit brreg insns.
1672 (define_insn "*normal_int_branch_sp64"
1674 (if_then_else (match_operator 0 "v9_register_compare_operator"
1675 [(match_operand:DI 1 "register_operand" "r")
1677 (label_ref (match_operand 2 "" ""))
1681 return output_v9branch (operands[0], operands[2], 1, 2, 0,
1682 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1685 [(set_attr "type" "branch")
1686 (set_attr "branch_type" "reg")])
1689 (define_insn "*inverted_int_branch_sp64"
1691 (if_then_else (match_operator 0 "v9_register_compare_operator"
1692 [(match_operand:DI 1 "register_operand" "r")
1695 (label_ref (match_operand 2 "" ""))))]
1698 return output_v9branch (operands[0], operands[2], 1, 2, 1,
1699 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1702 [(set_attr "type" "branch")
1703 (set_attr "branch_type" "reg")])
1706 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
1708 ;; Load in operand 0 the (absolute) address of operand 1, which is a symbolic
1709 ;; value subject to a PC-relative relocation. Operand 2 is a helper function
1710 ;; that adds the PC value at the call point to operand 0.
1712 (define_insn "load_pcrel_sym<P:mode>"
1713 [(set (match_operand:P 0 "register_operand" "=r")
1714 (unspec:P [(match_operand:P 1 "symbolic_operand" "")
1715 (match_operand:P 2 "call_address_operand" "")] UNSPEC_LOAD_PCREL_SYM))
1716 (clobber (reg:P 15))]
1719 if (flag_delayed_branch)
1720 return "sethi\t%%hi(%a1-4), %0\n\tcall\t%a2\n\t add\t%0, %%lo(%a1+4), %0";
1722 return "sethi\t%%hi(%a1-8), %0\n\tadd\t%0, %%lo(%a1-4), %0\n\tcall\t%a2\n\t nop";
1724 [(set (attr "type") (const_string "multi"))
1725 (set (attr "length")
1726 (if_then_else (eq_attr "delayed_branch" "true")
1731 ;; Integer move instructions
1733 (define_expand "movqi"
1734 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1735 (match_operand:QI 1 "general_operand" ""))]
1738 if (sparc_expand_move (QImode, operands))
1742 (define_insn "*movqi_insn"
1743 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m")
1744 (match_operand:QI 1 "input_operand" "rI,m,rJ"))]
1745 "(register_operand (operands[0], QImode)
1746 || register_or_zero_operand (operands[1], QImode))"
1751 [(set_attr "type" "*,load,store")
1752 (set_attr "us3load_type" "*,3cycle,*")])
1754 (define_expand "movhi"
1755 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1756 (match_operand:HI 1 "general_operand" ""))]
1759 if (sparc_expand_move (HImode, operands))
1763 (define_insn "*movhi_insn"
1764 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1765 (match_operand:HI 1 "input_operand" "rI,K,m,rJ"))]
1766 "(register_operand (operands[0], HImode)
1767 || register_or_zero_operand (operands[1], HImode))"
1770 sethi\t%%hi(%a1), %0
1773 [(set_attr "type" "*,*,load,store")
1774 (set_attr "us3load_type" "*,*,3cycle,*")])
1776 ;; We always work with constants here.
1777 (define_insn "*movhi_lo_sum"
1778 [(set (match_operand:HI 0 "register_operand" "=r")
1779 (ior:HI (match_operand:HI 1 "register_operand" "%r")
1780 (match_operand:HI 2 "small_int_operand" "I")))]
1784 (define_expand "movsi"
1785 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1786 (match_operand:SI 1 "general_operand" ""))]
1789 if (sparc_expand_move (SImode, operands))
1793 (define_insn "*movsi_insn"
1794 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,m,!f,!f,!m,d")
1795 (match_operand:SI 1 "input_operand" "rI,K,m,rJ,f,m,f,J"))]
1796 "(register_operand (operands[0], SImode)
1797 || register_or_zero_operand (operands[1], SImode))"
1800 sethi\t%%hi(%a1), %0
1807 [(set_attr "type" "*,*,load,store,fpmove,fpload,fpstore,fga")])
1809 (define_insn "*movsi_lo_sum"
1810 [(set (match_operand:SI 0 "register_operand" "=r")
1811 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1812 (match_operand:SI 2 "immediate_operand" "in")))]
1814 "or\t%1, %%lo(%a2), %0")
1816 (define_insn "*movsi_high"
1817 [(set (match_operand:SI 0 "register_operand" "=r")
1818 (high:SI (match_operand:SI 1 "immediate_operand" "in")))]
1820 "sethi\t%%hi(%a1), %0")
1822 ;; The next two patterns must wrap the SYMBOL_REF in an UNSPEC
1823 ;; so that CSE won't optimize the address computation away.
1824 (define_insn "movsi_lo_sum_pic"
1825 [(set (match_operand:SI 0 "register_operand" "=r")
1826 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1827 (unspec:SI [(match_operand:SI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
1829 "or\t%1, %%lo(%a2), %0")
1831 (define_insn "movsi_high_pic"
1832 [(set (match_operand:SI 0 "register_operand" "=r")
1833 (high:SI (unspec:SI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
1834 "flag_pic && check_pic (1)"
1835 "sethi\t%%hi(%a1), %0")
1837 (define_expand "movsi_pic_label_ref"
1838 [(set (match_dup 3) (high:SI
1839 (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
1840 (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1841 (set (match_dup 4) (lo_sum:SI (match_dup 3)
1842 (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1843 (set (match_operand:SI 0 "register_operand" "=r")
1844 (minus:SI (match_dup 5) (match_dup 4)))]
1847 crtl->uses_pic_offset_table = 1;
1848 operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
1849 if (!can_create_pseudo_p ())
1851 operands[3] = operands[0];
1852 operands[4] = operands[0];
1856 operands[3] = gen_reg_rtx (SImode);
1857 operands[4] = gen_reg_rtx (SImode);
1859 operands[5] = pic_offset_table_rtx;
1862 (define_insn "*movsi_high_pic_label_ref"
1863 [(set (match_operand:SI 0 "register_operand" "=r")
1865 (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
1866 (match_operand:SI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1868 "sethi\t%%hi(%a2-(%a1-.)), %0")
1870 (define_insn "*movsi_lo_sum_pic_label_ref"
1871 [(set (match_operand:SI 0 "register_operand" "=r")
1872 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1873 (unspec:SI [(match_operand:SI 2 "label_ref_operand" "")
1874 (match_operand:SI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1876 "or\t%1, %%lo(%a3-(%a2-.)), %0")
1878 ;; Set up the PIC register for VxWorks.
1880 (define_expand "vxworks_load_got"
1882 (high:SI (match_dup 1)))
1884 (mem:SI (lo_sum:SI (match_dup 0) (match_dup 1))))
1886 (mem:SI (lo_sum:SI (match_dup 0) (match_dup 2))))]
1887 "TARGET_VXWORKS_RTP"
1889 operands[0] = pic_offset_table_rtx;
1890 operands[1] = gen_rtx_SYMBOL_REF (SImode, VXWORKS_GOTT_BASE);
1891 operands[2] = gen_rtx_SYMBOL_REF (SImode, VXWORKS_GOTT_INDEX);
1894 (define_expand "movdi"
1895 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1896 (match_operand:DI 1 "general_operand" ""))]
1899 if (sparc_expand_move (DImode, operands))
1903 ;; Be careful, fmovd does not exist when !v9.
1904 ;; We match MEM moves directly when we have correct even
1905 ;; numbered registers, but fall into splits otherwise.
1906 ;; The constraint ordering here is really important to
1907 ;; avoid insane problems in reload, especially for patterns
1910 ;; (set (mem:DI (plus:SI (reg:SI 30 %fp)
1911 ;; (const_int -5016)))
1915 (define_insn "*movdi_insn_sp32"
1916 [(set (match_operand:DI 0 "nonimmediate_operand"
1917 "=o,T,U,o,r,r,r,?T,?f,?f,?o,?f")
1918 (match_operand:DI 1 "input_operand"
1919 " J,U,T,r,o,i,r, f, T, o, f, f"))]
1921 && (register_operand (operands[0], DImode)
1922 || register_or_zero_operand (operands[1], DImode))"
1936 [(set_attr "type" "store,store,load,*,*,*,*,fpstore,fpload,*,*,*")
1937 (set_attr "length" "2,*,*,2,2,2,2,*,*,2,2,2")])
1939 (define_insn "*movdi_insn_sp32_v9"
1940 [(set (match_operand:DI 0 "nonimmediate_operand"
1941 "=T,o,T,U,o,r,r,r,?T,?f,?f,?o,?e,?e,?W")
1942 (match_operand:DI 1 "input_operand"
1943 " J,J,U,T,r,o,i,r, f, T, o, f, e, W, e"))]
1946 && (register_operand (operands[0], DImode)
1947 || register_or_zero_operand (operands[1], DImode))"
1964 [(set_attr "type" "store,store,store,load,*,*,*,*,fpstore,fpload,*,*,fpmove,fpload,fpstore")
1965 (set_attr "length" "*,2,*,*,2,2,2,2,*,*,2,2,*,*,*")
1966 (set_attr "fptype" "*,*,*,*,*,*,*,*,*,*,*,*,double,*,*")])
1968 (define_insn "*movdi_insn_sp64"
1969 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,m,?e,?e,?W,b")
1970 (match_operand:DI 1 "input_operand" "rI,N,m,rJ,e,W,e,J"))]
1972 && (register_operand (operands[0], DImode)
1973 || register_or_zero_operand (operands[1], DImode))"
1976 sethi\t%%hi(%a1), %0
1983 [(set_attr "type" "*,*,load,store,fpmove,fpload,fpstore,fga")
1984 (set_attr "fptype" "*,*,*,*,double,*,*,double")])
1986 (define_expand "movdi_pic_label_ref"
1987 [(set (match_dup 3) (high:DI
1988 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
1989 (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1990 (set (match_dup 4) (lo_sum:DI (match_dup 3)
1991 (unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1992 (set (match_operand:DI 0 "register_operand" "=r")
1993 (minus:DI (match_dup 5) (match_dup 4)))]
1994 "TARGET_ARCH64 && flag_pic"
1996 crtl->uses_pic_offset_table = 1;
1997 operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
1998 if (!can_create_pseudo_p ())
2000 operands[3] = operands[0];
2001 operands[4] = operands[0];
2005 operands[3] = gen_reg_rtx (DImode);
2006 operands[4] = gen_reg_rtx (DImode);
2008 operands[5] = pic_offset_table_rtx;
2011 (define_insn "*movdi_high_pic_label_ref"
2012 [(set (match_operand:DI 0 "register_operand" "=r")
2014 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
2015 (match_operand:DI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
2016 "TARGET_ARCH64 && flag_pic"
2017 "sethi\t%%hi(%a2-(%a1-.)), %0")
2019 (define_insn "*movdi_lo_sum_pic_label_ref"
2020 [(set (match_operand:DI 0 "register_operand" "=r")
2021 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2022 (unspec:DI [(match_operand:DI 2 "label_ref_operand" "")
2023 (match_operand:DI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
2024 "TARGET_ARCH64 && flag_pic"
2025 "or\t%1, %%lo(%a3-(%a2-.)), %0")
2027 ;; SPARC-v9 code model support insns. See sparc_emit_set_symbolic_const64
2028 ;; in sparc.c to see what is going on here... PIC stuff comes first.
2030 (define_insn "movdi_lo_sum_pic"
2031 [(set (match_operand:DI 0 "register_operand" "=r")
2032 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2033 (unspec:DI [(match_operand:DI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
2034 "TARGET_ARCH64 && flag_pic"
2035 "or\t%1, %%lo(%a2), %0")
2037 (define_insn "movdi_high_pic"
2038 [(set (match_operand:DI 0 "register_operand" "=r")
2039 (high:DI (unspec:DI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
2040 "TARGET_ARCH64 && flag_pic && check_pic (1)"
2041 "sethi\t%%hi(%a1), %0")
2043 (define_insn "*sethi_di_medlow_embmedany_pic"
2044 [(set (match_operand:DI 0 "register_operand" "=r")
2045 (high:DI (match_operand:DI 1 "medium_pic_operand" "")))]
2046 "(TARGET_CM_MEDLOW || TARGET_CM_EMBMEDANY) && check_pic (1)"
2047 "sethi\t%%hi(%a1), %0")
2049 (define_insn "*sethi_di_medlow"
2050 [(set (match_operand:DI 0 "register_operand" "=r")
2051 (high:DI (match_operand:DI 1 "symbolic_operand" "")))]
2052 "TARGET_CM_MEDLOW && check_pic (1)"
2053 "sethi\t%%hi(%a1), %0")
2055 (define_insn "*losum_di_medlow"
2056 [(set (match_operand:DI 0 "register_operand" "=r")
2057 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2058 (match_operand:DI 2 "symbolic_operand" "")))]
2060 "or\t%1, %%lo(%a2), %0")
2062 (define_insn "seth44"
2063 [(set (match_operand:DI 0 "register_operand" "=r")
2064 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETH44)))]
2066 "sethi\t%%h44(%a1), %0")
2068 (define_insn "setm44"
2069 [(set (match_operand:DI 0 "register_operand" "=r")
2070 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2071 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_SETM44)))]
2073 "or\t%1, %%m44(%a2), %0")
2075 (define_insn "setl44"
2076 [(set (match_operand:DI 0 "register_operand" "=r")
2077 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2078 (match_operand:DI 2 "symbolic_operand" "")))]
2080 "or\t%1, %%l44(%a2), %0")
2082 (define_insn "sethh"
2083 [(set (match_operand:DI 0 "register_operand" "=r")
2084 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETHH)))]
2086 "sethi\t%%hh(%a1), %0")
2088 (define_insn "setlm"
2089 [(set (match_operand:DI 0 "register_operand" "=r")
2090 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETLM)))]
2092 "sethi\t%%lm(%a1), %0")
2094 (define_insn "sethm"
2095 [(set (match_operand:DI 0 "register_operand" "=r")
2096 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2097 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_EMB_SETHM)))]
2099 "or\t%1, %%hm(%a2), %0")
2101 (define_insn "setlo"
2102 [(set (match_operand:DI 0 "register_operand" "=r")
2103 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2104 (match_operand:DI 2 "symbolic_operand" "")))]
2106 "or\t%1, %%lo(%a2), %0")
2108 (define_insn "embmedany_sethi"
2109 [(set (match_operand:DI 0 "register_operand" "=r")
2110 (high:DI (unspec:DI [(match_operand:DI 1 "data_segment_operand" "")] UNSPEC_EMB_HISUM)))]
2111 "TARGET_CM_EMBMEDANY && check_pic (1)"
2112 "sethi\t%%hi(%a1), %0")
2114 (define_insn "embmedany_losum"
2115 [(set (match_operand:DI 0 "register_operand" "=r")
2116 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2117 (match_operand:DI 2 "data_segment_operand" "")))]
2118 "TARGET_CM_EMBMEDANY"
2119 "add\t%1, %%lo(%a2), %0")
2121 (define_insn "embmedany_brsum"
2122 [(set (match_operand:DI 0 "register_operand" "=r")
2123 (unspec:DI [(match_operand:DI 1 "register_operand" "r")] UNSPEC_EMB_HISUM))]
2124 "TARGET_CM_EMBMEDANY"
2127 (define_insn "embmedany_textuhi"
2128 [(set (match_operand:DI 0 "register_operand" "=r")
2129 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTUHI)))]
2130 "TARGET_CM_EMBMEDANY && check_pic (1)"
2131 "sethi\t%%uhi(%a1), %0")
2133 (define_insn "embmedany_texthi"
2134 [(set (match_operand:DI 0 "register_operand" "=r")
2135 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTHI)))]
2136 "TARGET_CM_EMBMEDANY && check_pic (1)"
2137 "sethi\t%%hi(%a1), %0")
2139 (define_insn "embmedany_textulo"
2140 [(set (match_operand:DI 0 "register_operand" "=r")
2141 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2142 (unspec:DI [(match_operand:DI 2 "text_segment_operand" "")] UNSPEC_EMB_TEXTULO)))]
2143 "TARGET_CM_EMBMEDANY"
2144 "or\t%1, %%ulo(%a2), %0")
2146 (define_insn "embmedany_textlo"
2147 [(set (match_operand:DI 0 "register_operand" "=r")
2148 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2149 (match_operand:DI 2 "text_segment_operand" "")))]
2150 "TARGET_CM_EMBMEDANY"
2151 "or\t%1, %%lo(%a2), %0")
2153 ;; Now some patterns to help reload out a bit.
2154 (define_expand "reload_indi"
2155 [(parallel [(match_operand:DI 0 "register_operand" "=r")
2156 (match_operand:DI 1 "immediate_operand" "")
2157 (match_operand:TI 2 "register_operand" "=&r")])]
2159 || TARGET_CM_EMBMEDANY)
2162 sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
2166 (define_expand "reload_outdi"
2167 [(parallel [(match_operand:DI 0 "register_operand" "=r")
2168 (match_operand:DI 1 "immediate_operand" "")
2169 (match_operand:TI 2 "register_operand" "=&r")])]
2171 || TARGET_CM_EMBMEDANY)
2174 sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
2178 ;; Split up putting CONSTs and REGs into DI regs when !arch64
2180 [(set (match_operand:DI 0 "register_operand" "")
2181 (match_operand:DI 1 "const_int_operand" ""))]
2182 "! TARGET_ARCH64 && reload_completed"
2183 [(clobber (const_int 0))]
2185 #if HOST_BITS_PER_WIDE_INT == 32
2186 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
2187 (INTVAL (operands[1]) < 0) ?
2190 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2193 unsigned int low, high;
2195 low = trunc_int_for_mode (INTVAL (operands[1]), SImode);
2196 high = trunc_int_for_mode (INTVAL (operands[1]) >> 32, SImode);
2197 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), GEN_INT (high)));
2199 /* Slick... but this trick loses if this subreg constant part
2200 can be done in one insn. */
2202 && ! SPARC_SETHI32_P (high)
2203 && ! SPARC_SIMM13_P (high))
2204 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2205 gen_highpart (SImode, operands[0])));
2207 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), GEN_INT (low)));
2213 [(set (match_operand:DI 0 "register_operand" "")
2214 (match_operand:DI 1 "const_double_operand" ""))]
2218 && ((GET_CODE (operands[0]) == REG
2219 && REGNO (operands[0]) < 32)
2220 || (GET_CODE (operands[0]) == SUBREG
2221 && GET_CODE (SUBREG_REG (operands[0])) == REG
2222 && REGNO (SUBREG_REG (operands[0])) < 32))))"
2223 [(clobber (const_int 0))]
2225 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
2226 GEN_INT (CONST_DOUBLE_HIGH (operands[1]))));
2228 /* Slick... but this trick loses if this subreg constant part
2229 can be done in one insn. */
2230 if (CONST_DOUBLE_LOW (operands[1]) == CONST_DOUBLE_HIGH (operands[1])
2231 && ! SPARC_SETHI32_P (CONST_DOUBLE_HIGH (operands[1]))
2232 && ! SPARC_SIMM13_P (CONST_DOUBLE_HIGH (operands[1])))
2234 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2235 gen_highpart (SImode, operands[0])));
2239 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2240 GEN_INT (CONST_DOUBLE_LOW (operands[1]))));
2246 [(set (match_operand:DI 0 "register_operand" "")
2247 (match_operand:DI 1 "register_operand" ""))]
2251 && ((GET_CODE (operands[0]) == REG
2252 && REGNO (operands[0]) < 32)
2253 || (GET_CODE (operands[0]) == SUBREG
2254 && GET_CODE (SUBREG_REG (operands[0])) == REG
2255 && REGNO (SUBREG_REG (operands[0])) < 32))))"
2256 [(clobber (const_int 0))]
2258 rtx set_dest = operands[0];
2259 rtx set_src = operands[1];
2263 dest1 = gen_highpart (SImode, set_dest);
2264 dest2 = gen_lowpart (SImode, set_dest);
2265 src1 = gen_highpart (SImode, set_src);
2266 src2 = gen_lowpart (SImode, set_src);
2268 /* Now emit using the real source and destination we found, swapping
2269 the order if we detect overlap. */
2270 if (reg_overlap_mentioned_p (dest1, src2))
2272 emit_insn (gen_movsi (dest2, src2));
2273 emit_insn (gen_movsi (dest1, src1));
2277 emit_insn (gen_movsi (dest1, src1));
2278 emit_insn (gen_movsi (dest2, src2));
2283 ;; Now handle the cases of memory moves from/to non-even
2284 ;; DI mode register pairs.
2286 [(set (match_operand:DI 0 "register_operand" "")
2287 (match_operand:DI 1 "memory_operand" ""))]
2290 && sparc_splitdi_legitimate (operands[0], operands[1]))"
2291 [(clobber (const_int 0))]
2293 rtx word0 = adjust_address (operands[1], SImode, 0);
2294 rtx word1 = adjust_address (operands[1], SImode, 4);
2295 rtx high_part = gen_highpart (SImode, operands[0]);
2296 rtx low_part = gen_lowpart (SImode, operands[0]);
2298 if (reg_overlap_mentioned_p (high_part, word1))
2300 emit_insn (gen_movsi (low_part, word1));
2301 emit_insn (gen_movsi (high_part, word0));
2305 emit_insn (gen_movsi (high_part, word0));
2306 emit_insn (gen_movsi (low_part, word1));
2312 [(set (match_operand:DI 0 "memory_operand" "")
2313 (match_operand:DI 1 "register_operand" ""))]
2316 && sparc_splitdi_legitimate (operands[1], operands[0]))"
2317 [(clobber (const_int 0))]
2319 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0),
2320 gen_highpart (SImode, operands[1])));
2321 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4),
2322 gen_lowpart (SImode, operands[1])));
2327 [(set (match_operand:DI 0 "memory_operand" "")
2328 (match_operand:DI 1 "const_zero_operand" ""))]
2332 && ! mem_min_alignment (operands[0], 8)))
2333 && offsettable_memref_p (operands[0])"
2334 [(clobber (const_int 0))]
2336 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0), const0_rtx));
2337 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4), const0_rtx));
2342 ;; Floating point and vector move instructions
2344 ;; We don't define V1SI because SI should work just fine.
2345 (define_mode_iterator V32 [SF V2HI V4QI])
2347 ;; Yes, you guessed it right, the former movsf expander.
2348 (define_expand "mov<V32:mode>"
2349 [(set (match_operand:V32 0 "nonimmediate_operand" "")
2350 (match_operand:V32 1 "general_operand" ""))]
2351 "<V32:MODE>mode == SFmode || TARGET_VIS"
2353 if (sparc_expand_move (<V32:MODE>mode, operands))
2357 (define_insn "*movsf_insn"
2358 [(set (match_operand:V32 0 "nonimmediate_operand" "=d,f,*r,*r,*r,f,*r,m,m")
2359 (match_operand:V32 1 "input_operand" "GY,f,*rRY,Q,S,m,m,f,*rGY"))]
2361 && (register_operand (operands[0], <V32:MODE>mode)
2362 || register_or_zero_operand (operands[1], <V32:MODE>mode))"
2364 if (GET_CODE (operands[1]) == CONST_DOUBLE
2365 && (which_alternative == 2
2366 || which_alternative == 3
2367 || which_alternative == 4))
2372 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2373 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2374 operands[1] = GEN_INT (i);
2377 switch (which_alternative)
2380 return "fzeros\t%0";
2382 return "fmovs\t%1, %0";
2384 return "mov\t%1, %0";
2386 return "sethi\t%%hi(%a1), %0";
2391 return "ld\t%1, %0";
2394 return "st\t%r1, %0";
2399 [(set_attr "type" "fga,fpmove,*,*,*,fpload,load,fpstore,store")])
2401 ;; Exactly the same as above, except that all `f' cases are deleted.
2402 ;; This is necessary to prevent reload from ever trying to use a `f' reg
2405 (define_insn "*movsf_insn_no_fpu"
2406 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r,r,m")
2407 (match_operand:SF 1 "input_operand" "rR,Q,S,m,rG"))]
2409 && (register_operand (operands[0], SFmode)
2410 || register_or_zero_operand (operands[1], SFmode))"
2412 if (GET_CODE (operands[1]) == CONST_DOUBLE
2413 && (which_alternative == 0
2414 || which_alternative == 1
2415 || which_alternative == 2))
2420 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2421 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2422 operands[1] = GEN_INT (i);
2425 switch (which_alternative)
2428 return "mov\t%1, %0";
2430 return "sethi\t%%hi(%a1), %0";
2434 return "ld\t%1, %0";
2436 return "st\t%r1, %0";
2441 [(set_attr "type" "*,*,*,load,store")])
2443 ;; The following 3 patterns build SFmode constants in integer registers.
2445 (define_insn "*movsf_lo_sum"
2446 [(set (match_operand:SF 0 "register_operand" "=r")
2447 (lo_sum:SF (match_operand:SF 1 "register_operand" "r")
2448 (match_operand:SF 2 "fp_const_high_losum_operand" "S")))]
2454 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[2]);
2455 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2456 operands[2] = GEN_INT (i);
2457 return "or\t%1, %%lo(%a2), %0";
2460 (define_insn "*movsf_high"
2461 [(set (match_operand:SF 0 "register_operand" "=r")
2462 (high:SF (match_operand:SF 1 "fp_const_high_losum_operand" "S")))]
2468 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2469 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2470 operands[1] = GEN_INT (i);
2471 return "sethi\t%%hi(%1), %0";
2475 [(set (match_operand:SF 0 "register_operand" "")
2476 (match_operand:SF 1 "fp_const_high_losum_operand" ""))]
2477 "REG_P (operands[0]) && REGNO (operands[0]) < 32"
2478 [(set (match_dup 0) (high:SF (match_dup 1)))
2479 (set (match_dup 0) (lo_sum:SF (match_dup 0) (match_dup 1)))])
2481 (define_mode_iterator V64 [DF V2SI V4HI V8QI])
2483 ;; Yes, you again guessed it right, the former movdf expander.
2484 (define_expand "mov<V64:mode>"
2485 [(set (match_operand:V64 0 "nonimmediate_operand" "")
2486 (match_operand:V64 1 "general_operand" ""))]
2487 "<V64:MODE>mode == DFmode || TARGET_VIS"
2489 if (sparc_expand_move (<V64:MODE>mode, operands))
2493 ;; Be careful, fmovd does not exist when !v9.
2494 (define_insn "*movdf_insn_sp32"
2495 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,W,U,T,o,e,*r,o,e,o")
2496 (match_operand:DF 1 "input_operand" "W#F,e,T,U,G,e,*rFo,*r,o#F,e"))]
2499 && (register_operand (operands[0], DFmode)
2500 || register_or_zero_operand (operands[1], DFmode))"
2512 [(set_attr "type" "fpload,fpstore,load,store,*,*,*,*,*,*")
2513 (set_attr "length" "*,*,*,*,2,2,2,2,2,2")])
2515 (define_insn "*movdf_insn_sp32_no_fpu"
2516 [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,o,r,o")
2517 (match_operand:DF 1 "input_operand" "T,U,G,ro,r"))]
2520 && (register_operand (operands[0], DFmode)
2521 || register_or_zero_operand (operands[1], DFmode))"
2528 [(set_attr "type" "load,store,*,*,*")
2529 (set_attr "length" "*,*,2,2,2")])
2531 ;; We have available v9 double floats but not 64-bit integer registers.
2532 (define_insn "*movdf_insn_sp32_v9"
2533 [(set (match_operand:V64 0 "nonimmediate_operand" "=b,e,e,T,W,U,T,f,*r,o")
2534 (match_operand:V64 1 "input_operand" "GY,e,W#F,GY,e,T,U,o#F,*roGYF,*rGYf"))]
2538 && (register_operand (operands[0], <V64:MODE>mode)
2539 || register_or_zero_operand (operands[1], <V64:MODE>mode))"
2551 [(set_attr "type" "fga,fpmove,load,store,store,load,store,*,*,*")
2552 (set_attr "length" "*,*,*,*,*,*,*,2,2,2")
2553 (set_attr "fptype" "double,double,*,*,*,*,*,*,*,*")])
2555 (define_insn "*movdf_insn_sp32_v9_no_fpu"
2556 [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,T,r,o")
2557 (match_operand:DF 1 "input_operand" "T,U,G,ro,rG"))]
2561 && (register_operand (operands[0], DFmode)
2562 || register_or_zero_operand (operands[1], DFmode))"
2569 [(set_attr "type" "load,store,store,*,*")
2570 (set_attr "length" "*,*,*,2,2")])
2572 ;; We have available both v9 double floats and 64-bit integer registers.
2573 (define_insn "*movdf_insn_sp64"
2574 [(set (match_operand:V64 0 "nonimmediate_operand" "=b,e,e,W,*r,*r,m,*r")
2575 (match_operand:V64 1 "input_operand" "GY,e,W#F,e,*rGY,m,*rGY,F"))]
2578 && (register_operand (operands[0], <V64:MODE>mode)
2579 || register_or_zero_operand (operands[1], <V64:MODE>mode))"
2589 [(set_attr "type" "fga,fpmove,load,store,*,load,store,*")
2590 (set_attr "length" "*,*,*,*,*,*,*,2")
2591 (set_attr "fptype" "double,double,*,*,*,*,*,*")])
2593 (define_insn "*movdf_insn_sp64_no_fpu"
2594 [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m")
2595 (match_operand:DF 1 "input_operand" "r,m,rG"))]
2598 && (register_operand (operands[0], DFmode)
2599 || register_or_zero_operand (operands[1], DFmode))"
2604 [(set_attr "type" "*,load,store")])
2606 ;; This pattern build DFmode constants in integer registers.
2608 [(set (match_operand:DF 0 "register_operand" "")
2609 (match_operand:DF 1 "const_double_operand" ""))]
2611 && (GET_CODE (operands[0]) == REG
2612 && REGNO (operands[0]) < 32)
2613 && ! const_zero_operand(operands[1], DFmode)
2614 && reload_completed"
2615 [(clobber (const_int 0))]
2620 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2621 REAL_VALUE_TO_TARGET_DOUBLE (r, l);
2622 operands[0] = gen_rtx_raw_REG (DImode, REGNO (operands[0]));
2626 #if HOST_BITS_PER_WIDE_INT == 32
2631 val = ((HOST_WIDE_INT)(unsigned long)l[1] |
2632 ((HOST_WIDE_INT)(unsigned long)l[0] << 32));
2633 emit_insn (gen_movdi (operands[0], gen_int_mode (val, DImode)));
2638 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
2639 gen_int_mode (l[0], SImode)));
2641 /* Slick... but this trick loses if this subreg constant part
2642 can be done in one insn. */
2644 && ! SPARC_SETHI32_P (l[0])
2645 && ! SPARC_SIMM13_P (l[0]))
2647 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2648 gen_highpart (SImode, operands[0])));
2652 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2653 gen_int_mode (l[1], SImode)));
2659 ;; Ok, now the splits to handle all the multi insn and
2660 ;; mis-aligned memory address cases.
2661 ;; In these splits please take note that we must be
2662 ;; careful when V9 but not ARCH64 because the integer
2663 ;; register DFmode cases must be handled.
2665 [(set (match_operand:V64 0 "register_operand" "")
2666 (match_operand:V64 1 "register_operand" ""))]
2669 && ((GET_CODE (operands[0]) == REG
2670 && REGNO (operands[0]) < 32)
2671 || (GET_CODE (operands[0]) == SUBREG
2672 && GET_CODE (SUBREG_REG (operands[0])) == REG
2673 && REGNO (SUBREG_REG (operands[0])) < 32))))
2674 && reload_completed"
2675 [(clobber (const_int 0))]
2677 rtx set_dest = operands[0];
2678 rtx set_src = operands[1];
2681 enum machine_mode half_mode;
2683 /* We can be expanded for DFmode or integral vector modes. */
2684 if (<V64:MODE>mode == DFmode)
2689 dest1 = gen_highpart (half_mode, set_dest);
2690 dest2 = gen_lowpart (half_mode, set_dest);
2691 src1 = gen_highpart (half_mode, set_src);
2692 src2 = gen_lowpart (half_mode, set_src);
2694 /* Now emit using the real source and destination we found, swapping
2695 the order if we detect overlap. */
2696 if (reg_overlap_mentioned_p (dest1, src2))
2698 emit_move_insn_1 (dest2, src2);
2699 emit_move_insn_1 (dest1, src1);
2703 emit_move_insn_1 (dest1, src1);
2704 emit_move_insn_1 (dest2, src2);
2710 [(set (match_operand:V64 0 "register_operand" "")
2711 (match_operand:V64 1 "memory_operand" ""))]
2714 && (((REGNO (operands[0]) % 2) != 0)
2715 || ! mem_min_alignment (operands[1], 8))
2716 && offsettable_memref_p (operands[1])"
2717 [(clobber (const_int 0))]
2719 enum machine_mode half_mode;
2722 /* We can be expanded for DFmode or integral vector modes. */
2723 if (<V64:MODE>mode == DFmode)
2728 word0 = adjust_address (operands[1], half_mode, 0);
2729 word1 = adjust_address (operands[1], half_mode, 4);
2731 if (reg_overlap_mentioned_p (gen_highpart (half_mode, operands[0]), word1))
2733 emit_move_insn_1 (gen_lowpart (half_mode, operands[0]), word1);
2734 emit_move_insn_1 (gen_highpart (half_mode, operands[0]), word0);
2738 emit_move_insn_1 (gen_highpart (half_mode, operands[0]), word0);
2739 emit_move_insn_1 (gen_lowpart (half_mode, operands[0]), word1);
2745 [(set (match_operand:V64 0 "memory_operand" "")
2746 (match_operand:V64 1 "register_operand" ""))]
2749 && (((REGNO (operands[1]) % 2) != 0)
2750 || ! mem_min_alignment (operands[0], 8))
2751 && offsettable_memref_p (operands[0])"
2752 [(clobber (const_int 0))]
2754 enum machine_mode half_mode;
2757 /* We can be expanded for DFmode or integral vector modes. */
2758 if (<V64:MODE>mode == DFmode)
2763 word0 = adjust_address (operands[0], half_mode, 0);
2764 word1 = adjust_address (operands[0], half_mode, 4);
2766 emit_move_insn_1 (word0, gen_highpart (half_mode, operands[1]));
2767 emit_move_insn_1 (word1, gen_lowpart (half_mode, operands[1]));
2772 [(set (match_operand:V64 0 "memory_operand" "")
2773 (match_operand:V64 1 "const_zero_operand" ""))]
2777 && ! mem_min_alignment (operands[0], 8)))
2778 && offsettable_memref_p (operands[0])"
2779 [(clobber (const_int 0))]
2781 enum machine_mode half_mode;
2784 /* We can be expanded for DFmode or integral vector modes. */
2785 if (<V64:MODE>mode == DFmode)
2790 dest1 = adjust_address (operands[0], half_mode, 0);
2791 dest2 = adjust_address (operands[0], half_mode, 4);
2793 emit_move_insn_1 (dest1, CONST0_RTX (half_mode));
2794 emit_move_insn_1 (dest2, CONST0_RTX (half_mode));
2799 [(set (match_operand:V64 0 "register_operand" "")
2800 (match_operand:V64 1 "const_zero_operand" ""))]
2803 && ((GET_CODE (operands[0]) == REG
2804 && REGNO (operands[0]) < 32)
2805 || (GET_CODE (operands[0]) == SUBREG
2806 && GET_CODE (SUBREG_REG (operands[0])) == REG
2807 && REGNO (SUBREG_REG (operands[0])) < 32))"
2808 [(clobber (const_int 0))]
2810 enum machine_mode half_mode;
2811 rtx set_dest = operands[0];
2814 /* We can be expanded for DFmode or integral vector modes. */
2815 if (<V64:MODE>mode == DFmode)
2820 dest1 = gen_highpart (half_mode, set_dest);
2821 dest2 = gen_lowpart (half_mode, set_dest);
2822 emit_move_insn_1 (dest1, CONST0_RTX (half_mode));
2823 emit_move_insn_1 (dest2, CONST0_RTX (half_mode));
2827 (define_expand "movtf"
2828 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2829 (match_operand:TF 1 "general_operand" ""))]
2832 if (sparc_expand_move (TFmode, operands))
2836 (define_insn "*movtf_insn_sp32"
2837 [(set (match_operand:TF 0 "nonimmediate_operand" "=b,e,o,U,r")
2838 (match_operand:TF 1 "input_operand" "G,oe,GeUr,o,roG"))]
2841 && (register_operand (operands[0], TFmode)
2842 || register_or_zero_operand (operands[1], TFmode))"
2844 [(set_attr "length" "4")])
2846 ;; Exactly the same as above, except that all `e' cases are deleted.
2847 ;; This is necessary to prevent reload from ever trying to use a `e' reg
2850 (define_insn "*movtf_insn_sp32_no_fpu"
2851 [(set (match_operand:TF 0 "nonimmediate_operand" "=o,U,o,r,o")
2852 (match_operand:TF 1 "input_operand" "G,o,U,roG,r"))]
2855 && (register_operand (operands[0], TFmode)
2856 || register_or_zero_operand (operands[1], TFmode))"
2858 [(set_attr "length" "4")])
2860 (define_insn "*movtf_insn_sp64"
2861 [(set (match_operand:TF 0 "nonimmediate_operand" "=b,e,o,r")
2862 (match_operand:TF 1 "input_operand" "G,oe,Ger,roG"))]
2865 && ! TARGET_HARD_QUAD
2866 && (register_operand (operands[0], TFmode)
2867 || register_or_zero_operand (operands[1], TFmode))"
2869 [(set_attr "length" "2")])
2871 (define_insn "*movtf_insn_sp64_hq"
2872 [(set (match_operand:TF 0 "nonimmediate_operand" "=b,e,e,m,o,r")
2873 (match_operand:TF 1 "input_operand" "G,e,m,e,rG,roG"))]
2877 && (register_operand (operands[0], TFmode)
2878 || register_or_zero_operand (operands[1], TFmode))"
2886 [(set_attr "type" "*,fpmove,fpload,fpstore,*,*")
2887 (set_attr "length" "2,*,*,*,2,2")])
2889 (define_insn "*movtf_insn_sp64_no_fpu"
2890 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o")
2891 (match_operand:TF 1 "input_operand" "orG,rG"))]
2894 && (register_operand (operands[0], TFmode)
2895 || register_or_zero_operand (operands[1], TFmode))"
2897 [(set_attr "length" "2")])
2899 ;; Now all the splits to handle multi-insn TF mode moves.
2901 [(set (match_operand:TF 0 "register_operand" "")
2902 (match_operand:TF 1 "register_operand" ""))]
2906 && ! TARGET_HARD_QUAD)
2907 || ! fp_register_operand (operands[0], TFmode))"
2908 [(clobber (const_int 0))]
2910 rtx set_dest = operands[0];
2911 rtx set_src = operands[1];
2915 dest1 = gen_df_reg (set_dest, 0);
2916 dest2 = gen_df_reg (set_dest, 1);
2917 src1 = gen_df_reg (set_src, 0);
2918 src2 = gen_df_reg (set_src, 1);
2920 /* Now emit using the real source and destination we found, swapping
2921 the order if we detect overlap. */
2922 if (reg_overlap_mentioned_p (dest1, src2))
2924 emit_insn (gen_movdf (dest2, src2));
2925 emit_insn (gen_movdf (dest1, src1));
2929 emit_insn (gen_movdf (dest1, src1));
2930 emit_insn (gen_movdf (dest2, src2));
2936 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2937 (match_operand:TF 1 "const_zero_operand" ""))]
2939 [(clobber (const_int 0))]
2941 rtx set_dest = operands[0];
2944 switch (GET_CODE (set_dest))
2947 dest1 = gen_df_reg (set_dest, 0);
2948 dest2 = gen_df_reg (set_dest, 1);
2951 dest1 = adjust_address (set_dest, DFmode, 0);
2952 dest2 = adjust_address (set_dest, DFmode, 8);
2958 emit_insn (gen_movdf (dest1, CONST0_RTX (DFmode)));
2959 emit_insn (gen_movdf (dest2, CONST0_RTX (DFmode)));
2964 [(set (match_operand:TF 0 "register_operand" "")
2965 (match_operand:TF 1 "memory_operand" ""))]
2967 && offsettable_memref_p (operands[1])
2969 || ! TARGET_HARD_QUAD
2970 || ! fp_register_operand (operands[0], TFmode)))"
2971 [(clobber (const_int 0))]
2973 rtx word0 = adjust_address (operands[1], DFmode, 0);
2974 rtx word1 = adjust_address (operands[1], DFmode, 8);
2975 rtx set_dest, dest1, dest2;
2977 set_dest = operands[0];
2979 dest1 = gen_df_reg (set_dest, 0);
2980 dest2 = gen_df_reg (set_dest, 1);
2982 /* Now output, ordering such that we don't clobber any registers
2983 mentioned in the address. */
2984 if (reg_overlap_mentioned_p (dest1, word1))
2987 emit_insn (gen_movdf (dest2, word1));
2988 emit_insn (gen_movdf (dest1, word0));
2992 emit_insn (gen_movdf (dest1, word0));
2993 emit_insn (gen_movdf (dest2, word1));
2999 [(set (match_operand:TF 0 "memory_operand" "")
3000 (match_operand:TF 1 "register_operand" ""))]
3002 && offsettable_memref_p (operands[0])
3004 || ! TARGET_HARD_QUAD
3005 || ! fp_register_operand (operands[1], TFmode)))"
3006 [(clobber (const_int 0))]
3008 rtx set_src = operands[1];
3010 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 0),
3011 gen_df_reg (set_src, 0)));
3012 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 8),
3013 gen_df_reg (set_src, 1)));
3018 ;; SPARC-V9 conditional move instructions.
3020 ;; We can handle larger constants here for some flavors, but for now we keep
3021 ;; it simple and only allow those constants supported by all flavors.
3022 ;; Note that emit_conditional_move canonicalizes operands 2,3 so that operand
3023 ;; 3 contains the constant if one is present, but we handle either for
3024 ;; generality (sparc.c puts a constant in operand 2).
3026 (define_expand "movqicc"
3027 [(set (match_operand:QI 0 "register_operand" "")
3028 (if_then_else:QI (match_operand 1 "comparison_operator" "")
3029 (match_operand:QI 2 "arith10_operand" "")
3030 (match_operand:QI 3 "arith10_operand" "")))]
3033 enum rtx_code code = GET_CODE (operands[1]);
3035 if (GET_MODE (sparc_compare_op0) == DImode
3039 if (sparc_compare_op1 == const0_rtx
3040 && GET_CODE (sparc_compare_op0) == REG
3041 && GET_MODE (sparc_compare_op0) == DImode
3042 && v9_regcmp_p (code))
3044 operands[1] = gen_rtx_fmt_ee (code, DImode,
3045 sparc_compare_op0, sparc_compare_op1);
3049 rtx cc_reg = gen_compare_reg (code);
3050 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3054 (define_expand "movhicc"
3055 [(set (match_operand:HI 0 "register_operand" "")
3056 (if_then_else:HI (match_operand 1 "comparison_operator" "")
3057 (match_operand:HI 2 "arith10_operand" "")
3058 (match_operand:HI 3 "arith10_operand" "")))]
3061 enum rtx_code code = GET_CODE (operands[1]);
3063 if (GET_MODE (sparc_compare_op0) == DImode
3067 if (sparc_compare_op1 == const0_rtx
3068 && GET_CODE (sparc_compare_op0) == REG
3069 && GET_MODE (sparc_compare_op0) == DImode
3070 && v9_regcmp_p (code))
3072 operands[1] = gen_rtx_fmt_ee (code, DImode,
3073 sparc_compare_op0, sparc_compare_op1);
3077 rtx cc_reg = gen_compare_reg (code);
3078 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3082 (define_expand "movsicc"
3083 [(set (match_operand:SI 0 "register_operand" "")
3084 (if_then_else:SI (match_operand 1 "comparison_operator" "")
3085 (match_operand:SI 2 "arith10_operand" "")
3086 (match_operand:SI 3 "arith10_operand" "")))]
3089 enum rtx_code code = GET_CODE (operands[1]);
3090 enum machine_mode op0_mode = GET_MODE (sparc_compare_op0);
3092 if (sparc_compare_op1 == const0_rtx
3093 && GET_CODE (sparc_compare_op0) == REG
3094 && (TARGET_ARCH64 && op0_mode == DImode && v9_regcmp_p (code)))
3096 operands[1] = gen_rtx_fmt_ee (code, op0_mode,
3097 sparc_compare_op0, sparc_compare_op1);
3101 rtx cc_reg = gen_compare_reg (code);
3102 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg),
3103 cc_reg, const0_rtx);
3107 (define_expand "movdicc"
3108 [(set (match_operand:DI 0 "register_operand" "")
3109 (if_then_else:DI (match_operand 1 "comparison_operator" "")
3110 (match_operand:DI 2 "arith10_operand" "")
3111 (match_operand:DI 3 "arith10_operand" "")))]
3114 enum rtx_code code = GET_CODE (operands[1]);
3116 if (sparc_compare_op1 == const0_rtx
3117 && GET_CODE (sparc_compare_op0) == REG
3118 && GET_MODE (sparc_compare_op0) == DImode
3119 && v9_regcmp_p (code))
3121 operands[1] = gen_rtx_fmt_ee (code, DImode,
3122 sparc_compare_op0, sparc_compare_op1);
3126 rtx cc_reg = gen_compare_reg (code);
3127 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg),
3128 cc_reg, const0_rtx);
3132 (define_expand "movsfcc"
3133 [(set (match_operand:SF 0 "register_operand" "")
3134 (if_then_else:SF (match_operand 1 "comparison_operator" "")
3135 (match_operand:SF 2 "register_operand" "")
3136 (match_operand:SF 3 "register_operand" "")))]
3137 "TARGET_V9 && TARGET_FPU"
3139 enum rtx_code code = GET_CODE (operands[1]);
3141 if (GET_MODE (sparc_compare_op0) == DImode
3145 if (sparc_compare_op1 == const0_rtx
3146 && GET_CODE (sparc_compare_op0) == REG
3147 && GET_MODE (sparc_compare_op0) == DImode
3148 && v9_regcmp_p (code))
3150 operands[1] = gen_rtx_fmt_ee (code, DImode,
3151 sparc_compare_op0, sparc_compare_op1);
3155 rtx cc_reg = gen_compare_reg (code);
3156 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3160 (define_expand "movdfcc"
3161 [(set (match_operand:DF 0 "register_operand" "")
3162 (if_then_else:DF (match_operand 1 "comparison_operator" "")
3163 (match_operand:DF 2 "register_operand" "")
3164 (match_operand:DF 3 "register_operand" "")))]
3165 "TARGET_V9 && TARGET_FPU"
3167 enum rtx_code code = GET_CODE (operands[1]);
3169 if (GET_MODE (sparc_compare_op0) == DImode
3173 if (sparc_compare_op1 == const0_rtx
3174 && GET_CODE (sparc_compare_op0) == REG
3175 && GET_MODE (sparc_compare_op0) == DImode
3176 && v9_regcmp_p (code))
3178 operands[1] = gen_rtx_fmt_ee (code, DImode,
3179 sparc_compare_op0, sparc_compare_op1);
3183 rtx cc_reg = gen_compare_reg (code);
3184 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3188 (define_expand "movtfcc"
3189 [(set (match_operand:TF 0 "register_operand" "")
3190 (if_then_else:TF (match_operand 1 "comparison_operator" "")
3191 (match_operand:TF 2 "register_operand" "")
3192 (match_operand:TF 3 "register_operand" "")))]
3193 "TARGET_V9 && TARGET_FPU"
3195 enum rtx_code code = GET_CODE (operands[1]);
3197 if (GET_MODE (sparc_compare_op0) == DImode
3201 if (sparc_compare_op1 == const0_rtx
3202 && GET_CODE (sparc_compare_op0) == REG
3203 && GET_MODE (sparc_compare_op0) == DImode
3204 && v9_regcmp_p (code))
3206 operands[1] = gen_rtx_fmt_ee (code, DImode,
3207 sparc_compare_op0, sparc_compare_op1);
3211 rtx cc_reg = gen_compare_reg (code);
3212 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3216 ;; Conditional move define_insns.
3218 (define_insn "*movqi_cc_sp64"
3219 [(set (match_operand:QI 0 "register_operand" "=r,r")
3220 (if_then_else:QI (match_operator 1 "comparison_operator"
3221 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
3223 (match_operand:QI 3 "arith11_operand" "rL,0")
3224 (match_operand:QI 4 "arith11_operand" "0,rL")))]
3228 mov%c1\t%x2, %4, %0"
3229 [(set_attr "type" "cmove")])
3231 (define_insn "*movhi_cc_sp64"
3232 [(set (match_operand:HI 0 "register_operand" "=r,r")
3233 (if_then_else:HI (match_operator 1 "comparison_operator"
3234 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
3236 (match_operand:HI 3 "arith11_operand" "rL,0")
3237 (match_operand:HI 4 "arith11_operand" "0,rL")))]
3241 mov%c1\t%x2, %4, %0"
3242 [(set_attr "type" "cmove")])
3244 (define_insn "*movsi_cc_sp64"
3245 [(set (match_operand:SI 0 "register_operand" "=r,r")
3246 (if_then_else:SI (match_operator 1 "comparison_operator"
3247 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
3249 (match_operand:SI 3 "arith11_operand" "rL,0")
3250 (match_operand:SI 4 "arith11_operand" "0,rL")))]
3254 mov%c1\t%x2, %4, %0"
3255 [(set_attr "type" "cmove")])
3257 (define_insn "*movdi_cc_sp64"
3258 [(set (match_operand:DI 0 "register_operand" "=r,r")
3259 (if_then_else:DI (match_operator 1 "comparison_operator"
3260 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
3262 (match_operand:DI 3 "arith11_operand" "rL,0")
3263 (match_operand:DI 4 "arith11_operand" "0,rL")))]
3267 mov%c1\t%x2, %4, %0"
3268 [(set_attr "type" "cmove")])
3270 (define_insn "*movdi_cc_sp64_trunc"
3271 [(set (match_operand:SI 0 "register_operand" "=r,r")
3272 (if_then_else:SI (match_operator 1 "comparison_operator"
3273 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
3275 (match_operand:SI 3 "arith11_operand" "rL,0")
3276 (match_operand:SI 4 "arith11_operand" "0,rL")))]
3280 mov%c1\t%x2, %4, %0"
3281 [(set_attr "type" "cmove")])
3283 (define_insn "*movsf_cc_sp64"
3284 [(set (match_operand:SF 0 "register_operand" "=f,f")
3285 (if_then_else:SF (match_operator 1 "comparison_operator"
3286 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
3288 (match_operand:SF 3 "register_operand" "f,0")
3289 (match_operand:SF 4 "register_operand" "0,f")))]
3290 "TARGET_V9 && TARGET_FPU"
3292 fmovs%C1\t%x2, %3, %0
3293 fmovs%c1\t%x2, %4, %0"
3294 [(set_attr "type" "fpcmove")])
3296 (define_insn "movdf_cc_sp64"
3297 [(set (match_operand:DF 0 "register_operand" "=e,e")
3298 (if_then_else:DF (match_operator 1 "comparison_operator"
3299 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
3301 (match_operand:DF 3 "register_operand" "e,0")
3302 (match_operand:DF 4 "register_operand" "0,e")))]
3303 "TARGET_V9 && TARGET_FPU"
3305 fmovd%C1\t%x2, %3, %0
3306 fmovd%c1\t%x2, %4, %0"
3307 [(set_attr "type" "fpcmove")
3308 (set_attr "fptype" "double")])
3310 (define_insn "*movtf_cc_hq_sp64"
3311 [(set (match_operand:TF 0 "register_operand" "=e,e")
3312 (if_then_else:TF (match_operator 1 "comparison_operator"
3313 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
3315 (match_operand:TF 3 "register_operand" "e,0")
3316 (match_operand:TF 4 "register_operand" "0,e")))]
3317 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
3319 fmovq%C1\t%x2, %3, %0
3320 fmovq%c1\t%x2, %4, %0"
3321 [(set_attr "type" "fpcmove")])
3323 (define_insn_and_split "*movtf_cc_sp64"
3324 [(set (match_operand:TF 0 "register_operand" "=e,e")
3325 (if_then_else:TF (match_operator 1 "comparison_operator"
3326 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
3328 (match_operand:TF 3 "register_operand" "e,0")
3329 (match_operand:TF 4 "register_operand" "0,e")))]
3330 "TARGET_V9 && TARGET_FPU && !TARGET_HARD_QUAD"
3332 "&& reload_completed"
3333 [(clobber (const_int 0))]
3335 rtx set_dest = operands[0];
3336 rtx set_srca = operands[3];
3337 rtx set_srcb = operands[4];
3338 int third = rtx_equal_p (set_dest, set_srca);
3340 rtx srca1, srca2, srcb1, srcb2;
3342 dest1 = gen_df_reg (set_dest, 0);
3343 dest2 = gen_df_reg (set_dest, 1);
3344 srca1 = gen_df_reg (set_srca, 0);
3345 srca2 = gen_df_reg (set_srca, 1);
3346 srcb1 = gen_df_reg (set_srcb, 0);
3347 srcb2 = gen_df_reg (set_srcb, 1);
3349 /* Now emit using the real source and destination we found, swapping
3350 the order if we detect overlap. */
3351 if ((third && reg_overlap_mentioned_p (dest1, srcb2))
3352 || (!third && reg_overlap_mentioned_p (dest1, srca2)))
3354 emit_insn (gen_movdf_cc_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
3355 emit_insn (gen_movdf_cc_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
3359 emit_insn (gen_movdf_cc_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
3360 emit_insn (gen_movdf_cc_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
3364 [(set_attr "length" "2")])
3366 (define_insn "*movqi_cc_reg_sp64"
3367 [(set (match_operand:QI 0 "register_operand" "=r,r")
3368 (if_then_else:QI (match_operator 1 "v9_register_compare_operator"
3369 [(match_operand:DI 2 "register_operand" "r,r")
3371 (match_operand:QI 3 "arith10_operand" "rM,0")
3372 (match_operand:QI 4 "arith10_operand" "0,rM")))]
3375 movr%D1\t%2, %r3, %0
3376 movr%d1\t%2, %r4, %0"
3377 [(set_attr "type" "cmove")])
3379 (define_insn "*movhi_cc_reg_sp64"
3380 [(set (match_operand:HI 0 "register_operand" "=r,r")
3381 (if_then_else:HI (match_operator 1 "v9_register_compare_operator"
3382 [(match_operand:DI 2 "register_operand" "r,r")
3384 (match_operand:HI 3 "arith10_operand" "rM,0")
3385 (match_operand:HI 4 "arith10_operand" "0,rM")))]
3388 movr%D1\t%2, %r3, %0
3389 movr%d1\t%2, %r4, %0"
3390 [(set_attr "type" "cmove")])
3392 (define_insn "*movsi_cc_reg_sp64"
3393 [(set (match_operand:SI 0 "register_operand" "=r,r")
3394 (if_then_else:SI (match_operator 1 "v9_register_compare_operator"
3395 [(match_operand:DI 2 "register_operand" "r,r")
3397 (match_operand:SI 3 "arith10_operand" "rM,0")
3398 (match_operand:SI 4 "arith10_operand" "0,rM")))]
3401 movr%D1\t%2, %r3, %0
3402 movr%d1\t%2, %r4, %0"
3403 [(set_attr "type" "cmove")])
3405 (define_insn "*movdi_cc_reg_sp64"
3406 [(set (match_operand:DI 0 "register_operand" "=r,r")
3407 (if_then_else:DI (match_operator 1 "v9_register_compare_operator"
3408 [(match_operand:DI 2 "register_operand" "r,r")
3410 (match_operand:DI 3 "arith10_operand" "rM,0")
3411 (match_operand:DI 4 "arith10_operand" "0,rM")))]
3414 movr%D1\t%2, %r3, %0
3415 movr%d1\t%2, %r4, %0"
3416 [(set_attr "type" "cmove")])
3418 (define_insn "*movsf_cc_reg_sp64"
3419 [(set (match_operand:SF 0 "register_operand" "=f,f")
3420 (if_then_else:SF (match_operator 1 "v9_register_compare_operator"
3421 [(match_operand:DI 2 "register_operand" "r,r")
3423 (match_operand:SF 3 "register_operand" "f,0")
3424 (match_operand:SF 4 "register_operand" "0,f")))]
3425 "TARGET_ARCH64 && TARGET_FPU"
3427 fmovrs%D1\t%2, %3, %0
3428 fmovrs%d1\t%2, %4, %0"
3429 [(set_attr "type" "fpcrmove")])
3431 (define_insn "movdf_cc_reg_sp64"
3432 [(set (match_operand:DF 0 "register_operand" "=e,e")
3433 (if_then_else:DF (match_operator 1 "v9_register_compare_operator"
3434 [(match_operand:DI 2 "register_operand" "r,r")
3436 (match_operand:DF 3 "register_operand" "e,0")
3437 (match_operand:DF 4 "register_operand" "0,e")))]
3438 "TARGET_ARCH64 && TARGET_FPU"
3440 fmovrd%D1\t%2, %3, %0
3441 fmovrd%d1\t%2, %4, %0"
3442 [(set_attr "type" "fpcrmove")
3443 (set_attr "fptype" "double")])
3445 (define_insn "*movtf_cc_reg_hq_sp64"
3446 [(set (match_operand:TF 0 "register_operand" "=e,e")
3447 (if_then_else:TF (match_operator 1 "v9_register_compare_operator"
3448 [(match_operand:DI 2 "register_operand" "r,r")
3450 (match_operand:TF 3 "register_operand" "e,0")
3451 (match_operand:TF 4 "register_operand" "0,e")))]
3452 "TARGET_ARCH64 && TARGET_FPU && TARGET_HARD_QUAD"
3454 fmovrq%D1\t%2, %3, %0
3455 fmovrq%d1\t%2, %4, %0"
3456 [(set_attr "type" "fpcrmove")])
3458 (define_insn_and_split "*movtf_cc_reg_sp64"
3459 [(set (match_operand:TF 0 "register_operand" "=e,e")
3460 (if_then_else:TF (match_operator 1 "v9_register_compare_operator"
3461 [(match_operand:DI 2 "register_operand" "r,r")
3463 (match_operand:TF 3 "register_operand" "e,0")
3464 (match_operand:TF 4 "register_operand" "0,e")))]
3465 "TARGET_ARCH64 && TARGET_FPU && ! TARGET_HARD_QUAD"
3467 "&& reload_completed"
3468 [(clobber (const_int 0))]
3470 rtx set_dest = operands[0];
3471 rtx set_srca = operands[3];
3472 rtx set_srcb = operands[4];
3473 int third = rtx_equal_p (set_dest, set_srca);
3475 rtx srca1, srca2, srcb1, srcb2;
3477 dest1 = gen_df_reg (set_dest, 0);
3478 dest2 = gen_df_reg (set_dest, 1);
3479 srca1 = gen_df_reg (set_srca, 0);
3480 srca2 = gen_df_reg (set_srca, 1);
3481 srcb1 = gen_df_reg (set_srcb, 0);
3482 srcb2 = gen_df_reg (set_srcb, 1);
3484 /* Now emit using the real source and destination we found, swapping
3485 the order if we detect overlap. */
3486 if ((third && reg_overlap_mentioned_p (dest1, srcb2))
3487 || (!third && reg_overlap_mentioned_p (dest1, srca2)))
3489 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
3490 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
3494 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
3495 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
3499 [(set_attr "length" "2")])
3502 ;; Zero-extension instructions
3504 ;; These patterns originally accepted general_operands, however, slightly
3505 ;; better code is generated by only accepting register_operands, and then
3506 ;; letting combine generate the ldu[hb] insns.
3508 (define_expand "zero_extendhisi2"
3509 [(set (match_operand:SI 0 "register_operand" "")
3510 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
3513 rtx temp = gen_reg_rtx (SImode);
3514 rtx shift_16 = GEN_INT (16);
3515 int op1_subbyte = 0;
3517 if (GET_CODE (operand1) == SUBREG)
3519 op1_subbyte = SUBREG_BYTE (operand1);
3520 op1_subbyte /= GET_MODE_SIZE (SImode);
3521 op1_subbyte *= GET_MODE_SIZE (SImode);
3522 operand1 = XEXP (operand1, 0);
3525 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3527 emit_insn (gen_lshrsi3 (operand0, temp, shift_16));
3531 (define_insn "*zero_extendhisi2_insn"
3532 [(set (match_operand:SI 0 "register_operand" "=r")
3533 (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
3536 [(set_attr "type" "load")
3537 (set_attr "us3load_type" "3cycle")])
3539 (define_expand "zero_extendqihi2"
3540 [(set (match_operand:HI 0 "register_operand" "")
3541 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
3545 (define_insn "*zero_extendqihi2_insn"
3546 [(set (match_operand:HI 0 "register_operand" "=r,r")
3547 (zero_extend:HI (match_operand:QI 1 "input_operand" "r,m")))]
3548 "GET_CODE (operands[1]) != CONST_INT"
3552 [(set_attr "type" "*,load")
3553 (set_attr "us3load_type" "*,3cycle")])
3555 (define_expand "zero_extendqisi2"
3556 [(set (match_operand:SI 0 "register_operand" "")
3557 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
3561 (define_insn "*zero_extendqisi2_insn"
3562 [(set (match_operand:SI 0 "register_operand" "=r,r")
3563 (zero_extend:SI (match_operand:QI 1 "input_operand" "r,m")))]
3564 "GET_CODE (operands[1]) != CONST_INT"
3568 [(set_attr "type" "*,load")
3569 (set_attr "us3load_type" "*,3cycle")])
3571 (define_expand "zero_extendqidi2"
3572 [(set (match_operand:DI 0 "register_operand" "")
3573 (zero_extend:DI (match_operand:QI 1 "register_operand" "")))]
3577 (define_insn "*zero_extendqidi2_insn"
3578 [(set (match_operand:DI 0 "register_operand" "=r,r")
3579 (zero_extend:DI (match_operand:QI 1 "input_operand" "r,m")))]
3580 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
3584 [(set_attr "type" "*,load")
3585 (set_attr "us3load_type" "*,3cycle")])
3587 (define_expand "zero_extendhidi2"
3588 [(set (match_operand:DI 0 "register_operand" "")
3589 (zero_extend:DI (match_operand:HI 1 "register_operand" "")))]
3592 rtx temp = gen_reg_rtx (DImode);
3593 rtx shift_48 = GEN_INT (48);
3594 int op1_subbyte = 0;
3596 if (GET_CODE (operand1) == SUBREG)
3598 op1_subbyte = SUBREG_BYTE (operand1);
3599 op1_subbyte /= GET_MODE_SIZE (DImode);
3600 op1_subbyte *= GET_MODE_SIZE (DImode);
3601 operand1 = XEXP (operand1, 0);
3604 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
3606 emit_insn (gen_lshrdi3 (operand0, temp, shift_48));
3610 (define_insn "*zero_extendhidi2_insn"
3611 [(set (match_operand:DI 0 "register_operand" "=r")
3612 (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
3615 [(set_attr "type" "load")
3616 (set_attr "us3load_type" "3cycle")])
3618 ;; ??? Write truncdisi pattern using sra?
3620 (define_expand "zero_extendsidi2"
3621 [(set (match_operand:DI 0 "register_operand" "")
3622 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
3626 (define_insn "*zero_extendsidi2_insn_sp64"
3627 [(set (match_operand:DI 0 "register_operand" "=r,r")
3628 (zero_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
3629 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
3633 [(set_attr "type" "shift,load")])
3635 (define_insn_and_split "*zero_extendsidi2_insn_sp32"
3636 [(set (match_operand:DI 0 "register_operand" "=r")
3637 (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
3640 "&& reload_completed"
3641 [(set (match_dup 2) (match_dup 3))
3642 (set (match_dup 4) (match_dup 5))]
3646 dest1 = gen_highpart (SImode, operands[0]);
3647 dest2 = gen_lowpart (SImode, operands[0]);
3649 /* Swap the order in case of overlap. */
3650 if (REGNO (dest1) == REGNO (operands[1]))
3652 operands[2] = dest2;
3653 operands[3] = operands[1];
3654 operands[4] = dest1;
3655 operands[5] = const0_rtx;
3659 operands[2] = dest1;
3660 operands[3] = const0_rtx;
3661 operands[4] = dest2;
3662 operands[5] = operands[1];
3665 [(set_attr "length" "2")])
3667 ;; Simplify comparisons of extended values.
3669 (define_insn "*cmp_zero_extendqisi2"
3671 (compare:CC (zero_extend:SI (match_operand:QI 0 "register_operand" "r"))
3674 "andcc\t%0, 0xff, %%g0"
3675 [(set_attr "type" "compare")])
3677 (define_insn "*cmp_zero_qi"
3679 (compare:CC (match_operand:QI 0 "register_operand" "r")
3682 "andcc\t%0, 0xff, %%g0"
3683 [(set_attr "type" "compare")])
3685 (define_insn "*cmp_zero_extendqisi2_set"
3687 (compare:CC (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
3689 (set (match_operand:SI 0 "register_operand" "=r")
3690 (zero_extend:SI (match_dup 1)))]
3692 "andcc\t%1, 0xff, %0"
3693 [(set_attr "type" "compare")])
3695 (define_insn "*cmp_zero_extendqisi2_andcc_set"
3697 (compare:CC (and:SI (match_operand:SI 1 "register_operand" "r")
3700 (set (match_operand:SI 0 "register_operand" "=r")
3701 (zero_extend:SI (subreg:QI (match_dup 1) 0)))]
3703 "andcc\t%1, 0xff, %0"
3704 [(set_attr "type" "compare")])
3706 (define_insn "*cmp_zero_extendqidi2"
3708 (compare:CCX (zero_extend:DI (match_operand:QI 0 "register_operand" "r"))
3711 "andcc\t%0, 0xff, %%g0"
3712 [(set_attr "type" "compare")])
3714 (define_insn "*cmp_zero_qi_sp64"
3716 (compare:CCX (match_operand:QI 0 "register_operand" "r")
3719 "andcc\t%0, 0xff, %%g0"
3720 [(set_attr "type" "compare")])
3722 (define_insn "*cmp_zero_extendqidi2_set"
3724 (compare:CCX (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
3726 (set (match_operand:DI 0 "register_operand" "=r")
3727 (zero_extend:DI (match_dup 1)))]
3729 "andcc\t%1, 0xff, %0"
3730 [(set_attr "type" "compare")])
3732 (define_insn "*cmp_zero_extendqidi2_andcc_set"
3734 (compare:CCX (and:DI (match_operand:DI 1 "register_operand" "r")
3737 (set (match_operand:DI 0 "register_operand" "=r")
3738 (zero_extend:DI (subreg:QI (match_dup 1) 0)))]
3740 "andcc\t%1, 0xff, %0"
3741 [(set_attr "type" "compare")])
3743 ;; Similarly, handle {SI,DI}->QI mode truncation followed by a compare.
3745 (define_insn "*cmp_siqi_trunc"
3747 (compare:CC (subreg:QI (match_operand:SI 0 "register_operand" "r") 3)
3750 "andcc\t%0, 0xff, %%g0"
3751 [(set_attr "type" "compare")])
3753 (define_insn "*cmp_siqi_trunc_set"
3755 (compare:CC (subreg:QI (match_operand:SI 1 "register_operand" "r") 3)
3757 (set (match_operand:QI 0 "register_operand" "=r")
3758 (subreg:QI (match_dup 1) 3))]
3760 "andcc\t%1, 0xff, %0"
3761 [(set_attr "type" "compare")])
3763 (define_insn "*cmp_diqi_trunc"
3765 (compare:CC (subreg:QI (match_operand:DI 0 "register_operand" "r") 7)
3768 "andcc\t%0, 0xff, %%g0"
3769 [(set_attr "type" "compare")])
3771 (define_insn "*cmp_diqi_trunc_set"
3773 (compare:CC (subreg:QI (match_operand:DI 1 "register_operand" "r") 7)
3775 (set (match_operand:QI 0 "register_operand" "=r")
3776 (subreg:QI (match_dup 1) 7))]
3778 "andcc\t%1, 0xff, %0"
3779 [(set_attr "type" "compare")])
3782 ;; Sign-extension instructions
3784 ;; These patterns originally accepted general_operands, however, slightly
3785 ;; better code is generated by only accepting register_operands, and then
3786 ;; letting combine generate the lds[hb] insns.
3788 (define_expand "extendhisi2"
3789 [(set (match_operand:SI 0 "register_operand" "")
3790 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
3793 rtx temp = gen_reg_rtx (SImode);
3794 rtx shift_16 = GEN_INT (16);
3795 int op1_subbyte = 0;
3797 if (GET_CODE (operand1) == SUBREG)
3799 op1_subbyte = SUBREG_BYTE (operand1);
3800 op1_subbyte /= GET_MODE_SIZE (SImode);
3801 op1_subbyte *= GET_MODE_SIZE (SImode);
3802 operand1 = XEXP (operand1, 0);
3805 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3807 emit_insn (gen_ashrsi3 (operand0, temp, shift_16));
3811 (define_insn "*sign_extendhisi2_insn"
3812 [(set (match_operand:SI 0 "register_operand" "=r")
3813 (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
3816 [(set_attr "type" "sload")
3817 (set_attr "us3load_type" "3cycle")])
3819 (define_expand "extendqihi2"
3820 [(set (match_operand:HI 0 "register_operand" "")
3821 (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
3824 rtx temp = gen_reg_rtx (SImode);
3825 rtx shift_24 = GEN_INT (24);
3826 int op1_subbyte = 0;
3827 int op0_subbyte = 0;
3829 if (GET_CODE (operand1) == SUBREG)
3831 op1_subbyte = SUBREG_BYTE (operand1);
3832 op1_subbyte /= GET_MODE_SIZE (SImode);
3833 op1_subbyte *= GET_MODE_SIZE (SImode);
3834 operand1 = XEXP (operand1, 0);
3836 if (GET_CODE (operand0) == SUBREG)
3838 op0_subbyte = SUBREG_BYTE (operand0);
3839 op0_subbyte /= GET_MODE_SIZE (SImode);
3840 op0_subbyte *= GET_MODE_SIZE (SImode);
3841 operand0 = XEXP (operand0, 0);
3843 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3845 if (GET_MODE (operand0) != SImode)
3846 operand0 = gen_rtx_SUBREG (SImode, operand0, op0_subbyte);
3847 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
3851 (define_insn "*sign_extendqihi2_insn"
3852 [(set (match_operand:HI 0 "register_operand" "=r")
3853 (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
3856 [(set_attr "type" "sload")
3857 (set_attr "us3load_type" "3cycle")])
3859 (define_expand "extendqisi2"
3860 [(set (match_operand:SI 0 "register_operand" "")
3861 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
3864 rtx temp = gen_reg_rtx (SImode);
3865 rtx shift_24 = GEN_INT (24);
3866 int op1_subbyte = 0;
3868 if (GET_CODE (operand1) == SUBREG)
3870 op1_subbyte = SUBREG_BYTE (operand1);
3871 op1_subbyte /= GET_MODE_SIZE (SImode);
3872 op1_subbyte *= GET_MODE_SIZE (SImode);
3873 operand1 = XEXP (operand1, 0);
3876 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3878 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
3882 (define_insn "*sign_extendqisi2_insn"
3883 [(set (match_operand:SI 0 "register_operand" "=r")
3884 (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
3887 [(set_attr "type" "sload")
3888 (set_attr "us3load_type" "3cycle")])
3890 (define_expand "extendqidi2"
3891 [(set (match_operand:DI 0 "register_operand" "")
3892 (sign_extend:DI (match_operand:QI 1 "register_operand" "")))]
3895 rtx temp = gen_reg_rtx (DImode);
3896 rtx shift_56 = GEN_INT (56);
3897 int op1_subbyte = 0;
3899 if (GET_CODE (operand1) == SUBREG)
3901 op1_subbyte = SUBREG_BYTE (operand1);
3902 op1_subbyte /= GET_MODE_SIZE (DImode);
3903 op1_subbyte *= GET_MODE_SIZE (DImode);
3904 operand1 = XEXP (operand1, 0);
3907 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
3909 emit_insn (gen_ashrdi3 (operand0, temp, shift_56));
3913 (define_insn "*sign_extendqidi2_insn"
3914 [(set (match_operand:DI 0 "register_operand" "=r")
3915 (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
3918 [(set_attr "type" "sload")
3919 (set_attr "us3load_type" "3cycle")])
3921 (define_expand "extendhidi2"
3922 [(set (match_operand:DI 0 "register_operand" "")
3923 (sign_extend:DI (match_operand:HI 1 "register_operand" "")))]
3926 rtx temp = gen_reg_rtx (DImode);
3927 rtx shift_48 = GEN_INT (48);
3928 int op1_subbyte = 0;
3930 if (GET_CODE (operand1) == SUBREG)
3932 op1_subbyte = SUBREG_BYTE (operand1);
3933 op1_subbyte /= GET_MODE_SIZE (DImode);
3934 op1_subbyte *= GET_MODE_SIZE (DImode);
3935 operand1 = XEXP (operand1, 0);
3938 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
3940 emit_insn (gen_ashrdi3 (operand0, temp, shift_48));
3944 (define_insn "*sign_extendhidi2_insn"
3945 [(set (match_operand:DI 0 "register_operand" "=r")
3946 (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
3949 [(set_attr "type" "sload")
3950 (set_attr "us3load_type" "3cycle")])
3952 (define_expand "extendsidi2"
3953 [(set (match_operand:DI 0 "register_operand" "")
3954 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
3958 (define_insn "*sign_extendsidi2_insn"
3959 [(set (match_operand:DI 0 "register_operand" "=r,r")
3960 (sign_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
3965 [(set_attr "type" "shift,sload")
3966 (set_attr "us3load_type" "*,3cycle")])
3969 ;; Special pattern for optimizing bit-field compares. This is needed
3970 ;; because combine uses this as a canonical form.
3972 (define_insn "*cmp_zero_extract"
3975 (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
3976 (match_operand:SI 1 "small_int_operand" "I")
3977 (match_operand:SI 2 "small_int_operand" "I"))
3979 "INTVAL (operands[2]) > 19"
3981 int len = INTVAL (operands[1]);
3982 int pos = 32 - INTVAL (operands[2]) - len;
3983 HOST_WIDE_INT mask = ((1 << len) - 1) << pos;
3984 operands[1] = GEN_INT (mask);
3985 return "andcc\t%0, %1, %%g0";
3987 [(set_attr "type" "compare")])
3989 (define_insn "*cmp_zero_extract_sp64"
3992 (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
3993 (match_operand:SI 1 "small_int_operand" "I")
3994 (match_operand:SI 2 "small_int_operand" "I"))
3996 "TARGET_ARCH64 && INTVAL (operands[2]) > 51"
3998 int len = INTVAL (operands[1]);
3999 int pos = 64 - INTVAL (operands[2]) - len;
4000 HOST_WIDE_INT mask = (((unsigned HOST_WIDE_INT) 1 << len) - 1) << pos;
4001 operands[1] = GEN_INT (mask);
4002 return "andcc\t%0, %1, %%g0";
4004 [(set_attr "type" "compare")])
4007 ;; Conversions between float, double and long double.
4009 (define_insn "extendsfdf2"
4010 [(set (match_operand:DF 0 "register_operand" "=e")
4012 (match_operand:SF 1 "register_operand" "f")))]
4015 [(set_attr "type" "fp")
4016 (set_attr "fptype" "double")])
4018 (define_expand "extendsftf2"
4019 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4021 (match_operand:SF 1 "register_operand" "")))]
4022 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4023 "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
4025 (define_insn "*extendsftf2_hq"
4026 [(set (match_operand:TF 0 "register_operand" "=e")
4028 (match_operand:SF 1 "register_operand" "f")))]
4029 "TARGET_FPU && TARGET_HARD_QUAD"
4031 [(set_attr "type" "fp")])
4033 (define_expand "extenddftf2"
4034 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4036 (match_operand:DF 1 "register_operand" "")))]
4037 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4038 "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
4040 (define_insn "*extenddftf2_hq"
4041 [(set (match_operand:TF 0 "register_operand" "=e")
4043 (match_operand:DF 1 "register_operand" "e")))]
4044 "TARGET_FPU && TARGET_HARD_QUAD"
4046 [(set_attr "type" "fp")])
4048 (define_insn "truncdfsf2"
4049 [(set (match_operand:SF 0 "register_operand" "=f")
4051 (match_operand:DF 1 "register_operand" "e")))]
4054 [(set_attr "type" "fp")
4055 (set_attr "fptype" "double")])
4057 (define_expand "trunctfsf2"
4058 [(set (match_operand:SF 0 "register_operand" "")
4060 (match_operand:TF 1 "general_operand" "")))]
4061 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4062 "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
4064 (define_insn "*trunctfsf2_hq"
4065 [(set (match_operand:SF 0 "register_operand" "=f")
4067 (match_operand:TF 1 "register_operand" "e")))]
4068 "TARGET_FPU && TARGET_HARD_QUAD"
4070 [(set_attr "type" "fp")])
4072 (define_expand "trunctfdf2"
4073 [(set (match_operand:DF 0 "register_operand" "")
4075 (match_operand:TF 1 "general_operand" "")))]
4076 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4077 "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
4079 (define_insn "*trunctfdf2_hq"
4080 [(set (match_operand:DF 0 "register_operand" "=e")
4082 (match_operand:TF 1 "register_operand" "e")))]
4083 "TARGET_FPU && TARGET_HARD_QUAD"
4085 [(set_attr "type" "fp")])
4088 ;; Conversion between fixed point and floating point.
4090 (define_insn "floatsisf2"
4091 [(set (match_operand:SF 0 "register_operand" "=f")
4092 (float:SF (match_operand:SI 1 "register_operand" "f")))]
4095 [(set_attr "type" "fp")
4096 (set_attr "fptype" "double")])
4098 (define_insn "floatsidf2"
4099 [(set (match_operand:DF 0 "register_operand" "=e")
4100 (float:DF (match_operand:SI 1 "register_operand" "f")))]
4103 [(set_attr "type" "fp")
4104 (set_attr "fptype" "double")])
4106 (define_expand "floatsitf2"
4107 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4108 (float:TF (match_operand:SI 1 "register_operand" "")))]
4109 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4110 "emit_tfmode_cvt (FLOAT, operands); DONE;")
4112 (define_insn "*floatsitf2_hq"
4113 [(set (match_operand:TF 0 "register_operand" "=e")
4114 (float:TF (match_operand:SI 1 "register_operand" "f")))]
4115 "TARGET_FPU && TARGET_HARD_QUAD"
4117 [(set_attr "type" "fp")])
4119 (define_expand "floatunssitf2"
4120 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4121 (unsigned_float:TF (match_operand:SI 1 "register_operand" "")))]
4122 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4123 "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
4125 ;; Now the same for 64 bit sources.
4127 (define_insn "floatdisf2"
4128 [(set (match_operand:SF 0 "register_operand" "=f")
4129 (float:SF (match_operand:DI 1 "register_operand" "e")))]
4130 "TARGET_V9 && TARGET_FPU"
4132 [(set_attr "type" "fp")
4133 (set_attr "fptype" "double")])
4135 (define_expand "floatunsdisf2"
4136 [(use (match_operand:SF 0 "register_operand" ""))
4137 (use (match_operand:DI 1 "general_operand" ""))]
4138 "TARGET_ARCH64 && TARGET_FPU"
4139 "sparc_emit_floatunsdi (operands, SFmode); DONE;")
4141 (define_insn "floatdidf2"
4142 [(set (match_operand:DF 0 "register_operand" "=e")
4143 (float:DF (match_operand:DI 1 "register_operand" "e")))]
4144 "TARGET_V9 && TARGET_FPU"
4146 [(set_attr "type" "fp")
4147 (set_attr "fptype" "double")])
4149 (define_expand "floatunsdidf2"
4150 [(use (match_operand:DF 0 "register_operand" ""))
4151 (use (match_operand:DI 1 "general_operand" ""))]
4152 "TARGET_ARCH64 && TARGET_FPU"
4153 "sparc_emit_floatunsdi (operands, DFmode); DONE;")
4155 (define_expand "floatditf2"
4156 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4157 (float:TF (match_operand:DI 1 "register_operand" "")))]
4158 "TARGET_FPU && TARGET_V9 && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4159 "emit_tfmode_cvt (FLOAT, operands); DONE;")
4161 (define_insn "*floatditf2_hq"
4162 [(set (match_operand:TF 0 "register_operand" "=e")
4163 (float:TF (match_operand:DI 1 "register_operand" "e")))]
4164 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
4166 [(set_attr "type" "fp")])
4168 (define_expand "floatunsditf2"
4169 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4170 (unsigned_float:TF (match_operand:DI 1 "register_operand" "")))]
4171 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4172 "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
4174 ;; Convert a float to an actual integer.
4175 ;; Truncation is performed as part of the conversion.
4177 (define_insn "fix_truncsfsi2"
4178 [(set (match_operand:SI 0 "register_operand" "=f")
4179 (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
4182 [(set_attr "type" "fp")
4183 (set_attr "fptype" "double")])
4185 (define_insn "fix_truncdfsi2"
4186 [(set (match_operand:SI 0 "register_operand" "=f")
4187 (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
4190 [(set_attr "type" "fp")
4191 (set_attr "fptype" "double")])
4193 (define_expand "fix_trunctfsi2"
4194 [(set (match_operand:SI 0 "register_operand" "")
4195 (fix:SI (match_operand:TF 1 "general_operand" "")))]
4196 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4197 "emit_tfmode_cvt (FIX, operands); DONE;")
4199 (define_insn "*fix_trunctfsi2_hq"
4200 [(set (match_operand:SI 0 "register_operand" "=f")
4201 (fix:SI (match_operand:TF 1 "register_operand" "e")))]
4202 "TARGET_FPU && TARGET_HARD_QUAD"
4204 [(set_attr "type" "fp")])
4206 (define_expand "fixuns_trunctfsi2"
4207 [(set (match_operand:SI 0 "register_operand" "")
4208 (unsigned_fix:SI (match_operand:TF 1 "general_operand" "")))]
4209 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4210 "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
4212 ;; Now the same, for V9 targets
4214 (define_insn "fix_truncsfdi2"
4215 [(set (match_operand:DI 0 "register_operand" "=e")
4216 (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
4217 "TARGET_V9 && TARGET_FPU"
4219 [(set_attr "type" "fp")
4220 (set_attr "fptype" "double")])
4222 (define_expand "fixuns_truncsfdi2"
4223 [(use (match_operand:DI 0 "register_operand" ""))
4224 (use (match_operand:SF 1 "general_operand" ""))]
4225 "TARGET_ARCH64 && TARGET_FPU"
4226 "sparc_emit_fixunsdi (operands, SFmode); DONE;")
4228 (define_insn "fix_truncdfdi2"
4229 [(set (match_operand:DI 0 "register_operand" "=e")
4230 (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
4231 "TARGET_V9 && TARGET_FPU"
4233 [(set_attr "type" "fp")
4234 (set_attr "fptype" "double")])
4236 (define_expand "fixuns_truncdfdi2"
4237 [(use (match_operand:DI 0 "register_operand" ""))
4238 (use (match_operand:DF 1 "general_operand" ""))]
4239 "TARGET_ARCH64 && TARGET_FPU"
4240 "sparc_emit_fixunsdi (operands, DFmode); DONE;")
4242 (define_expand "fix_trunctfdi2"
4243 [(set (match_operand:DI 0 "register_operand" "")
4244 (fix:DI (match_operand:TF 1 "general_operand" "")))]
4245 "TARGET_V9 && TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4246 "emit_tfmode_cvt (FIX, operands); DONE;")
4248 (define_insn "*fix_trunctfdi2_hq"
4249 [(set (match_operand:DI 0 "register_operand" "=e")
4250 (fix:DI (match_operand:TF 1 "register_operand" "e")))]
4251 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
4253 [(set_attr "type" "fp")])
4255 (define_expand "fixuns_trunctfdi2"
4256 [(set (match_operand:DI 0 "register_operand" "")
4257 (unsigned_fix:DI (match_operand:TF 1 "general_operand" "")))]
4258 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4259 "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
4262 ;; Integer addition/subtraction instructions.
4264 (define_expand "adddi3"
4265 [(set (match_operand:DI 0 "register_operand" "")
4266 (plus:DI (match_operand:DI 1 "register_operand" "")
4267 (match_operand:DI 2 "arith_double_add_operand" "")))]
4270 if (! TARGET_ARCH64)
4272 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
4273 gen_rtx_SET (VOIDmode, operands[0],
4274 gen_rtx_PLUS (DImode, operands[1],
4276 gen_rtx_CLOBBER (VOIDmode,
4277 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
4282 (define_insn_and_split "adddi3_insn_sp32"
4283 [(set (match_operand:DI 0 "register_operand" "=r")
4284 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
4285 (match_operand:DI 2 "arith_double_operand" "rHI")))
4286 (clobber (reg:CC 100))]
4289 "&& reload_completed"
4290 [(parallel [(set (reg:CC_NOOV 100)
4291 (compare:CC_NOOV (plus:SI (match_dup 4)
4295 (plus:SI (match_dup 4) (match_dup 5)))])
4297 (plus:SI (plus:SI (match_dup 7)
4299 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4301 operands[3] = gen_lowpart (SImode, operands[0]);
4302 operands[4] = gen_lowpart (SImode, operands[1]);
4303 operands[5] = gen_lowpart (SImode, operands[2]);
4304 operands[6] = gen_highpart (SImode, operands[0]);
4305 operands[7] = gen_highpart_mode (SImode, DImode, operands[1]);
4306 #if HOST_BITS_PER_WIDE_INT == 32
4307 if (GET_CODE (operands[2]) == CONST_INT)
4309 if (INTVAL (operands[2]) < 0)
4310 operands[8] = constm1_rtx;
4312 operands[8] = const0_rtx;
4316 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
4318 [(set_attr "length" "2")])
4320 ;; LTU here means "carry set"
4322 [(set (match_operand:SI 0 "register_operand" "=r")
4323 (plus:SI (plus:SI (match_operand:SI 1 "arith_operand" "%r")
4324 (match_operand:SI 2 "arith_operand" "rI"))
4325 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4328 [(set_attr "type" "ialuX")])
4330 (define_insn_and_split "*addx_extend_sp32"
4331 [(set (match_operand:DI 0 "register_operand" "=r")
4332 (zero_extend:DI (plus:SI (plus:SI
4333 (match_operand:SI 1 "register_or_zero_operand" "%rJ")
4334 (match_operand:SI 2 "arith_operand" "rI"))
4335 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4338 "&& reload_completed"
4339 [(set (match_dup 3) (plus:SI (plus:SI (match_dup 1) (match_dup 2))
4340 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
4341 (set (match_dup 4) (const_int 0))]
4342 "operands[3] = gen_lowpart (SImode, operands[0]);
4343 operands[4] = gen_highpart_mode (SImode, DImode, operands[1]);"
4344 [(set_attr "length" "2")])
4346 (define_insn "*addx_extend_sp64"
4347 [(set (match_operand:DI 0 "register_operand" "=r")
4348 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ")
4349 (match_operand:SI 2 "arith_operand" "rI"))
4350 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4353 [(set_attr "type" "ialuX")])
4355 (define_insn_and_split ""
4356 [(set (match_operand:DI 0 "register_operand" "=r")
4357 (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4358 (match_operand:DI 2 "register_operand" "r")))
4359 (clobber (reg:CC 100))]
4362 "&& reload_completed"
4363 [(parallel [(set (reg:CC_NOOV 100)
4364 (compare:CC_NOOV (plus:SI (match_dup 3) (match_dup 1))
4366 (set (match_dup 5) (plus:SI (match_dup 3) (match_dup 1)))])
4368 (plus:SI (plus:SI (match_dup 4) (const_int 0))
4369 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4370 "operands[3] = gen_lowpart (SImode, operands[2]);
4371 operands[4] = gen_highpart (SImode, operands[2]);
4372 operands[5] = gen_lowpart (SImode, operands[0]);
4373 operands[6] = gen_highpart (SImode, operands[0]);"
4374 [(set_attr "length" "2")])
4376 (define_insn "*adddi3_sp64"
4377 [(set (match_operand:DI 0 "register_operand" "=r,r")
4378 (plus:DI (match_operand:DI 1 "register_operand" "%r,r")
4379 (match_operand:DI 2 "arith_add_operand" "rI,O")))]
4385 (define_insn "addsi3"
4386 [(set (match_operand:SI 0 "register_operand" "=r,r,d")
4387 (plus:SI (match_operand:SI 1 "register_operand" "%r,r,d")
4388 (match_operand:SI 2 "arith_add_operand" "rI,O,d")))]
4393 fpadd32s\t%1, %2, %0"
4394 [(set_attr "type" "*,*,fga")
4395 (set_attr "fptype" "*,*,single")])
4397 (define_insn "*cmp_cc_plus"
4398 [(set (reg:CC_NOOV 100)
4399 (compare:CC_NOOV (plus:SI (match_operand:SI 0 "arith_operand" "%r")
4400 (match_operand:SI 1 "arith_operand" "rI"))
4403 "addcc\t%0, %1, %%g0"
4404 [(set_attr "type" "compare")])
4406 (define_insn "*cmp_ccx_plus"
4407 [(set (reg:CCX_NOOV 100)
4408 (compare:CCX_NOOV (plus:DI (match_operand:DI 0 "arith_operand" "%r")
4409 (match_operand:DI 1 "arith_operand" "rI"))
4412 "addcc\t%0, %1, %%g0"
4413 [(set_attr "type" "compare")])
4415 (define_insn "*cmp_cc_plus_set"
4416 [(set (reg:CC_NOOV 100)
4417 (compare:CC_NOOV (plus:SI (match_operand:SI 1 "arith_operand" "%r")
4418 (match_operand:SI 2 "arith_operand" "rI"))
4420 (set (match_operand:SI 0 "register_operand" "=r")
4421 (plus:SI (match_dup 1) (match_dup 2)))]
4424 [(set_attr "type" "compare")])
4426 (define_insn "*cmp_ccx_plus_set"
4427 [(set (reg:CCX_NOOV 100)
4428 (compare:CCX_NOOV (plus:DI (match_operand:DI 1 "arith_operand" "%r")
4429 (match_operand:DI 2 "arith_operand" "rI"))
4431 (set (match_operand:DI 0 "register_operand" "=r")
4432 (plus:DI (match_dup 1) (match_dup 2)))]
4435 [(set_attr "type" "compare")])
4437 (define_expand "subdi3"
4438 [(set (match_operand:DI 0 "register_operand" "")
4439 (minus:DI (match_operand:DI 1 "register_operand" "")
4440 (match_operand:DI 2 "arith_double_add_operand" "")))]
4443 if (! TARGET_ARCH64)
4445 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
4446 gen_rtx_SET (VOIDmode, operands[0],
4447 gen_rtx_MINUS (DImode, operands[1],
4449 gen_rtx_CLOBBER (VOIDmode,
4450 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
4455 (define_insn_and_split "subdi3_insn_sp32"
4456 [(set (match_operand:DI 0 "register_operand" "=r")
4457 (minus:DI (match_operand:DI 1 "register_operand" "r")
4458 (match_operand:DI 2 "arith_double_operand" "rHI")))
4459 (clobber (reg:CC 100))]
4462 "&& reload_completed"
4463 [(parallel [(set (reg:CC_NOOV 100)
4464 (compare:CC_NOOV (minus:SI (match_dup 4)
4468 (minus:SI (match_dup 4) (match_dup 5)))])
4470 (minus:SI (minus:SI (match_dup 7)
4472 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4474 operands[3] = gen_lowpart (SImode, operands[0]);
4475 operands[4] = gen_lowpart (SImode, operands[1]);
4476 operands[5] = gen_lowpart (SImode, operands[2]);
4477 operands[6] = gen_highpart (SImode, operands[0]);
4478 operands[7] = gen_highpart (SImode, operands[1]);
4479 #if HOST_BITS_PER_WIDE_INT == 32
4480 if (GET_CODE (operands[2]) == CONST_INT)
4482 if (INTVAL (operands[2]) < 0)
4483 operands[8] = constm1_rtx;
4485 operands[8] = const0_rtx;
4489 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
4491 [(set_attr "length" "2")])
4493 ;; LTU here means "carry set"
4495 [(set (match_operand:SI 0 "register_operand" "=r")
4496 (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
4497 (match_operand:SI 2 "arith_operand" "rI"))
4498 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4501 [(set_attr "type" "ialuX")])
4503 (define_insn "*subx_extend_sp64"
4504 [(set (match_operand:DI 0 "register_operand" "=r")
4505 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
4506 (match_operand:SI 2 "arith_operand" "rI"))
4507 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4510 [(set_attr "type" "ialuX")])
4512 (define_insn_and_split "*subx_extend"
4513 [(set (match_operand:DI 0 "register_operand" "=r")
4514 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
4515 (match_operand:SI 2 "arith_operand" "rI"))
4516 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4519 "&& reload_completed"
4520 [(set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 2))
4521 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
4522 (set (match_dup 4) (const_int 0))]
4523 "operands[3] = gen_lowpart (SImode, operands[0]);
4524 operands[4] = gen_highpart (SImode, operands[0]);"
4525 [(set_attr "length" "2")])
4527 (define_insn_and_split ""
4528 [(set (match_operand:DI 0 "register_operand" "=r")
4529 (minus:DI (match_operand:DI 1 "register_operand" "r")
4530 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))
4531 (clobber (reg:CC 100))]
4534 "&& reload_completed"
4535 [(parallel [(set (reg:CC_NOOV 100)
4536 (compare:CC_NOOV (minus:SI (match_dup 3) (match_dup 2))
4538 (set (match_dup 5) (minus:SI (match_dup 3) (match_dup 2)))])
4540 (minus:SI (minus:SI (match_dup 4) (const_int 0))
4541 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4542 "operands[3] = gen_lowpart (SImode, operands[1]);
4543 operands[4] = gen_highpart (SImode, operands[1]);
4544 operands[5] = gen_lowpart (SImode, operands[0]);
4545 operands[6] = gen_highpart (SImode, operands[0]);"
4546 [(set_attr "length" "2")])
4548 (define_insn "*subdi3_sp64"
4549 [(set (match_operand:DI 0 "register_operand" "=r,r")
4550 (minus:DI (match_operand:DI 1 "register_operand" "r,r")
4551 (match_operand:DI 2 "arith_add_operand" "rI,O")))]
4557 (define_insn "subsi3"
4558 [(set (match_operand:SI 0 "register_operand" "=r,r,d")
4559 (minus:SI (match_operand:SI 1 "register_operand" "r,r,d")
4560 (match_operand:SI 2 "arith_add_operand" "rI,O,d")))]
4565 fpsub32s\t%1, %2, %0"
4566 [(set_attr "type" "*,*,fga")
4567 (set_attr "fptype" "*,*,single")])
4569 (define_insn "*cmp_minus_cc"
4570 [(set (reg:CC_NOOV 100)
4571 (compare:CC_NOOV (minus:SI (match_operand:SI 0 "register_or_zero_operand" "rJ")
4572 (match_operand:SI 1 "arith_operand" "rI"))
4575 "subcc\t%r0, %1, %%g0"
4576 [(set_attr "type" "compare")])
4578 (define_insn "*cmp_minus_ccx"
4579 [(set (reg:CCX_NOOV 100)
4580 (compare:CCX_NOOV (minus:DI (match_operand:DI 0 "register_operand" "r")
4581 (match_operand:DI 1 "arith_operand" "rI"))
4584 "subcc\t%0, %1, %%g0"
4585 [(set_attr "type" "compare")])
4587 (define_insn "cmp_minus_cc_set"
4588 [(set (reg:CC_NOOV 100)
4589 (compare:CC_NOOV (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
4590 (match_operand:SI 2 "arith_operand" "rI"))
4592 (set (match_operand:SI 0 "register_operand" "=r")
4593 (minus:SI (match_dup 1) (match_dup 2)))]
4595 "subcc\t%r1, %2, %0"
4596 [(set_attr "type" "compare")])
4598 (define_insn "*cmp_minus_ccx_set"
4599 [(set (reg:CCX_NOOV 100)
4600 (compare:CCX_NOOV (minus:DI (match_operand:DI 1 "register_operand" "r")
4601 (match_operand:DI 2 "arith_operand" "rI"))
4603 (set (match_operand:DI 0 "register_operand" "=r")
4604 (minus:DI (match_dup 1) (match_dup 2)))]
4607 [(set_attr "type" "compare")])
4610 ;; Integer multiply/divide instructions.
4612 ;; The 32-bit multiply/divide instructions are deprecated on v9, but at
4613 ;; least in UltraSPARC I, II and IIi it is a win tick-wise.
4615 (define_insn "mulsi3"
4616 [(set (match_operand:SI 0 "register_operand" "=r")
4617 (mult:SI (match_operand:SI 1 "arith_operand" "%r")
4618 (match_operand:SI 2 "arith_operand" "rI")))]
4621 [(set_attr "type" "imul")])
4623 (define_expand "muldi3"
4624 [(set (match_operand:DI 0 "register_operand" "")
4625 (mult:DI (match_operand:DI 1 "arith_operand" "")
4626 (match_operand:DI 2 "arith_operand" "")))]
4627 "TARGET_ARCH64 || TARGET_V8PLUS"
4631 emit_insn (gen_muldi3_v8plus (operands[0], operands[1], operands[2]));
4636 (define_insn "*muldi3_sp64"
4637 [(set (match_operand:DI 0 "register_operand" "=r")
4638 (mult:DI (match_operand:DI 1 "arith_operand" "%r")
4639 (match_operand:DI 2 "arith_operand" "rI")))]
4642 [(set_attr "type" "imul")])
4644 ;; V8plus wide multiply.
4646 (define_insn "muldi3_v8plus"
4647 [(set (match_operand:DI 0 "register_operand" "=r,h")
4648 (mult:DI (match_operand:DI 1 "arith_operand" "%r,0")
4649 (match_operand:DI 2 "arith_operand" "rI,rI")))
4650 (clobber (match_scratch:SI 3 "=&h,X"))
4651 (clobber (match_scratch:SI 4 "=&h,X"))]
4654 if (sparc_check_64 (operands[1], insn) <= 0)
4655 output_asm_insn ("srl\t%L1, 0, %L1", operands);
4656 if (which_alternative == 1)
4657 output_asm_insn ("sllx\t%H1, 32, %H1", operands);
4658 if (GET_CODE (operands[2]) == CONST_INT)
4660 if (which_alternative == 1)
4661 return "or\t%L1, %H1, %H1\n\tmulx\t%H1, %2, %L0\;srlx\t%L0, 32, %H0";
4663 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";
4665 else if (rtx_equal_p (operands[1], operands[2]))
4667 if (which_alternative == 1)
4668 return "or\t%L1, %H1, %H1\n\tmulx\t%H1, %H1, %L0\;srlx\t%L0, 32, %H0";
4670 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";
4672 if (sparc_check_64 (operands[2], insn) <= 0)
4673 output_asm_insn ("srl\t%L2, 0, %L2", operands);
4674 if (which_alternative == 1)
4675 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";
4677 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";
4679 [(set_attr "type" "multi")
4680 (set_attr "length" "9,8")])
4682 (define_insn "*cmp_mul_set"
4684 (compare:CC (mult:SI (match_operand:SI 1 "arith_operand" "%r")
4685 (match_operand:SI 2 "arith_operand" "rI"))
4687 (set (match_operand:SI 0 "register_operand" "=r")
4688 (mult:SI (match_dup 1) (match_dup 2)))]
4689 "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS"
4690 "smulcc\t%1, %2, %0"
4691 [(set_attr "type" "imul")])
4693 (define_expand "mulsidi3"
4694 [(set (match_operand:DI 0 "register_operand" "")
4695 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
4696 (sign_extend:DI (match_operand:SI 2 "arith_operand" ""))))]
4699 if (CONSTANT_P (operands[2]))
4702 emit_insn (gen_const_mulsidi3_v8plus (operands[0], operands[1],
4704 else if (TARGET_ARCH32)
4705 emit_insn (gen_const_mulsidi3_sp32 (operands[0], operands[1],
4708 emit_insn (gen_const_mulsidi3_sp64 (operands[0], operands[1],
4714 emit_insn (gen_mulsidi3_v8plus (operands[0], operands[1], operands[2]));
4719 ;; V9 puts the 64-bit product in a 64-bit register. Only out or global
4720 ;; registers can hold 64-bit values in the V8plus environment.
4722 (define_insn "mulsidi3_v8plus"
4723 [(set (match_operand:DI 0 "register_operand" "=h,r")
4724 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4725 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
4726 (clobber (match_scratch:SI 3 "=X,&h"))]
4729 smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
4730 smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4731 [(set_attr "type" "multi")
4732 (set_attr "length" "2,3")])
4735 (define_insn "const_mulsidi3_v8plus"
4736 [(set (match_operand:DI 0 "register_operand" "=h,r")
4737 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4738 (match_operand:DI 2 "small_int_operand" "I,I")))
4739 (clobber (match_scratch:SI 3 "=X,&h"))]
4742 smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
4743 smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4744 [(set_attr "type" "multi")
4745 (set_attr "length" "2,3")])
4748 (define_insn "*mulsidi3_sp32"
4749 [(set (match_operand:DI 0 "register_operand" "=r")
4750 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4751 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4754 return TARGET_SPARCLET
4755 ? "smuld\t%1, %2, %L0"
4756 : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
4759 (if_then_else (eq_attr "isa" "sparclet")
4760 (const_string "imul") (const_string "multi")))
4761 (set (attr "length")
4762 (if_then_else (eq_attr "isa" "sparclet")
4763 (const_int 1) (const_int 2)))])
4765 (define_insn "*mulsidi3_sp64"
4766 [(set (match_operand:DI 0 "register_operand" "=r")
4767 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4768 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4769 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4771 [(set_attr "type" "imul")])
4773 ;; Extra pattern, because sign_extend of a constant isn't valid.
4776 (define_insn "const_mulsidi3_sp32"
4777 [(set (match_operand:DI 0 "register_operand" "=r")
4778 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4779 (match_operand:DI 2 "small_int_operand" "I")))]
4782 return TARGET_SPARCLET
4783 ? "smuld\t%1, %2, %L0"
4784 : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
4787 (if_then_else (eq_attr "isa" "sparclet")
4788 (const_string "imul") (const_string "multi")))
4789 (set (attr "length")
4790 (if_then_else (eq_attr "isa" "sparclet")
4791 (const_int 1) (const_int 2)))])
4793 (define_insn "const_mulsidi3_sp64"
4794 [(set (match_operand:DI 0 "register_operand" "=r")
4795 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4796 (match_operand:DI 2 "small_int_operand" "I")))]
4797 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4799 [(set_attr "type" "imul")])
4801 (define_expand "smulsi3_highpart"
4802 [(set (match_operand:SI 0 "register_operand" "")
4804 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
4805 (sign_extend:DI (match_operand:SI 2 "arith_operand" "")))
4807 "TARGET_HARD_MUL && TARGET_ARCH32"
4809 if (CONSTANT_P (operands[2]))
4813 emit_insn (gen_const_smulsi3_highpart_v8plus (operands[0],
4819 emit_insn (gen_const_smulsi3_highpart (operands[0], operands[1], operands[2]));
4824 emit_insn (gen_smulsi3_highpart_v8plus (operands[0], operands[1],
4825 operands[2], GEN_INT (32)));
4831 (define_insn "smulsi3_highpart_v8plus"
4832 [(set (match_operand:SI 0 "register_operand" "=h,r")
4834 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4835 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
4836 (match_operand:SI 3 "small_int_operand" "I,I"))))
4837 (clobber (match_scratch:SI 4 "=X,&h"))]
4840 smul\t%1, %2, %0\;srlx\t%0, %3, %0
4841 smul\t%1, %2, %4\;srlx\t%4, %3, %0"
4842 [(set_attr "type" "multi")
4843 (set_attr "length" "2")])
4845 ;; The combiner changes TRUNCATE in the previous pattern to SUBREG.
4848 [(set (match_operand:SI 0 "register_operand" "=h,r")
4851 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4852 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
4853 (match_operand:SI 3 "small_int_operand" "I,I"))
4855 (clobber (match_scratch:SI 4 "=X,&h"))]
4858 smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
4859 smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
4860 [(set_attr "type" "multi")
4861 (set_attr "length" "2")])
4864 (define_insn "const_smulsi3_highpart_v8plus"
4865 [(set (match_operand:SI 0 "register_operand" "=h,r")
4867 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4868 (match_operand:DI 2 "small_int_operand" "I,I"))
4869 (match_operand:SI 3 "small_int_operand" "I,I"))))
4870 (clobber (match_scratch:SI 4 "=X,&h"))]
4873 smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
4874 smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
4875 [(set_attr "type" "multi")
4876 (set_attr "length" "2")])
4879 (define_insn "*smulsi3_highpart_sp32"
4880 [(set (match_operand:SI 0 "register_operand" "=r")
4882 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4883 (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
4886 "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
4887 [(set_attr "type" "multi")
4888 (set_attr "length" "2")])
4891 (define_insn "const_smulsi3_highpart"
4892 [(set (match_operand:SI 0 "register_operand" "=r")
4894 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4895 (match_operand:DI 2 "small_int_operand" "i"))
4898 "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
4899 [(set_attr "type" "multi")
4900 (set_attr "length" "2")])
4902 (define_expand "umulsidi3"
4903 [(set (match_operand:DI 0 "register_operand" "")
4904 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
4905 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" ""))))]
4908 if (CONSTANT_P (operands[2]))
4911 emit_insn (gen_const_umulsidi3_v8plus (operands[0], operands[1],
4913 else if (TARGET_ARCH32)
4914 emit_insn (gen_const_umulsidi3_sp32 (operands[0], operands[1],
4917 emit_insn (gen_const_umulsidi3_sp64 (operands[0], operands[1],
4923 emit_insn (gen_umulsidi3_v8plus (operands[0], operands[1], operands[2]));
4929 (define_insn "umulsidi3_v8plus"
4930 [(set (match_operand:DI 0 "register_operand" "=h,r")
4931 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4932 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
4933 (clobber (match_scratch:SI 3 "=X,&h"))]
4936 umul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
4937 umul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4938 [(set_attr "type" "multi")
4939 (set_attr "length" "2,3")])
4942 (define_insn "*umulsidi3_sp32"
4943 [(set (match_operand:DI 0 "register_operand" "=r")
4944 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4945 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4948 return TARGET_SPARCLET
4949 ? "umuld\t%1, %2, %L0"
4950 : "umul\t%1, %2, %L0\n\trd\t%%y, %H0";
4953 (if_then_else (eq_attr "isa" "sparclet")
4954 (const_string "imul") (const_string "multi")))
4955 (set (attr "length")
4956 (if_then_else (eq_attr "isa" "sparclet")
4957 (const_int 1) (const_int 2)))])
4959 (define_insn "*umulsidi3_sp64"
4960 [(set (match_operand:DI 0 "register_operand" "=r")
4961 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4962 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4963 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4965 [(set_attr "type" "imul")])
4967 ;; Extra pattern, because sign_extend of a constant isn't valid.
4970 (define_insn "const_umulsidi3_sp32"
4971 [(set (match_operand:DI 0 "register_operand" "=r")
4972 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4973 (match_operand:DI 2 "uns_small_int_operand" "")))]
4976 return TARGET_SPARCLET
4977 ? "umuld\t%1, %s2, %L0"
4978 : "umul\t%1, %s2, %L0\n\trd\t%%y, %H0";
4981 (if_then_else (eq_attr "isa" "sparclet")
4982 (const_string "imul") (const_string "multi")))
4983 (set (attr "length")
4984 (if_then_else (eq_attr "isa" "sparclet")
4985 (const_int 1) (const_int 2)))])
4987 (define_insn "const_umulsidi3_sp64"
4988 [(set (match_operand:DI 0 "register_operand" "=r")
4989 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4990 (match_operand:DI 2 "uns_small_int_operand" "")))]
4991 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4993 [(set_attr "type" "imul")])
4996 (define_insn "const_umulsidi3_v8plus"
4997 [(set (match_operand:DI 0 "register_operand" "=h,r")
4998 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4999 (match_operand:DI 2 "uns_small_int_operand" "")))
5000 (clobber (match_scratch:SI 3 "=X,h"))]
5003 umul\t%1, %s2, %L0\n\tsrlx\t%L0, 32, %H0
5004 umul\t%1, %s2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
5005 [(set_attr "type" "multi")
5006 (set_attr "length" "2,3")])
5008 (define_expand "umulsi3_highpart"
5009 [(set (match_operand:SI 0 "register_operand" "")
5011 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
5012 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" "")))
5014 "TARGET_HARD_MUL && TARGET_ARCH32"
5016 if (CONSTANT_P (operands[2]))
5020 emit_insn (gen_const_umulsi3_highpart_v8plus (operands[0],
5026 emit_insn (gen_const_umulsi3_highpart (operands[0], operands[1], operands[2]));
5031 emit_insn (gen_umulsi3_highpart_v8plus (operands[0], operands[1],
5032 operands[2], GEN_INT (32)));
5038 (define_insn "umulsi3_highpart_v8plus"
5039 [(set (match_operand:SI 0 "register_operand" "=h,r")
5041 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5042 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
5043 (match_operand:SI 3 "small_int_operand" "I,I"))))
5044 (clobber (match_scratch:SI 4 "=X,h"))]
5047 umul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
5048 umul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
5049 [(set_attr "type" "multi")
5050 (set_attr "length" "2")])
5053 (define_insn "const_umulsi3_highpart_v8plus"
5054 [(set (match_operand:SI 0 "register_operand" "=h,r")
5056 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5057 (match_operand:DI 2 "uns_small_int_operand" ""))
5058 (match_operand:SI 3 "small_int_operand" "I,I"))))
5059 (clobber (match_scratch:SI 4 "=X,h"))]
5062 umul\t%1, %s2, %0\n\tsrlx\t%0, %3, %0
5063 umul\t%1, %s2, %4\n\tsrlx\t%4, %3, %0"
5064 [(set_attr "type" "multi")
5065 (set_attr "length" "2")])
5068 (define_insn "*umulsi3_highpart_sp32"
5069 [(set (match_operand:SI 0 "register_operand" "=r")
5071 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5072 (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
5075 "umul\t%1, %2, %%g0\n\trd\t%%y, %0"
5076 [(set_attr "type" "multi")
5077 (set_attr "length" "2")])
5080 (define_insn "const_umulsi3_highpart"
5081 [(set (match_operand:SI 0 "register_operand" "=r")
5083 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5084 (match_operand:DI 2 "uns_small_int_operand" ""))
5087 "umul\t%1, %s2, %%g0\n\trd\t%%y, %0"
5088 [(set_attr "type" "multi")
5089 (set_attr "length" "2")])
5091 ;; The V8 architecture specifies that there must be 3 instructions between
5092 ;; a Y register write and a use of it for correct results.
5094 (define_expand "divsi3"
5095 [(parallel [(set (match_operand:SI 0 "register_operand" "=r,r")
5096 (div:SI (match_operand:SI 1 "register_operand" "r,r")
5097 (match_operand:SI 2 "input_operand" "rI,m")))
5098 (clobber (match_scratch:SI 3 "=&r,&r"))])]
5099 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
5103 operands[3] = gen_reg_rtx(SImode);
5104 emit_insn (gen_ashrsi3 (operands[3], operands[1], GEN_INT (31)));
5105 emit_insn (gen_divsi3_sp64 (operands[0], operands[1], operands[2],
5111 (define_insn "divsi3_sp32"
5112 [(set (match_operand:SI 0 "register_operand" "=r,r")
5113 (div:SI (match_operand:SI 1 "register_operand" "r,r")
5114 (match_operand:SI 2 "input_operand" "rI,m")))
5115 (clobber (match_scratch:SI 3 "=&r,&r"))]
5116 "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS)
5119 if (which_alternative == 0)
5121 return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tsdiv\t%1, %2, %0";
5123 return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tnop\n\tnop\n\tnop\n\tsdiv\t%1, %2, %0";
5126 return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tld\t%2, %3\n\tsdiv\t%1, %3, %0";
5128 return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tld\t%2, %3\n\tnop\n\tnop\n\tsdiv\t%1, %3, %0";
5130 [(set_attr "type" "multi")
5131 (set (attr "length")
5132 (if_then_else (eq_attr "isa" "v9")
5133 (const_int 4) (const_int 6)))])
5135 (define_insn "divsi3_sp64"
5136 [(set (match_operand:SI 0 "register_operand" "=r")
5137 (div:SI (match_operand:SI 1 "register_operand" "r")
5138 (match_operand:SI 2 "input_operand" "rI")))
5139 (use (match_operand:SI 3 "register_operand" "r"))]
5140 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5141 "wr\t%%g0, %3, %%y\n\tsdiv\t%1, %2, %0"
5142 [(set_attr "type" "multi")
5143 (set_attr "length" "2")])
5145 (define_insn "divdi3"
5146 [(set (match_operand:DI 0 "register_operand" "=r")
5147 (div:DI (match_operand:DI 1 "register_operand" "r")
5148 (match_operand:DI 2 "arith_operand" "rI")))]
5151 [(set_attr "type" "idiv")])
5153 (define_insn "*cmp_sdiv_cc_set"
5155 (compare:CC (div:SI (match_operand:SI 1 "register_operand" "r")
5156 (match_operand:SI 2 "arith_operand" "rI"))
5158 (set (match_operand:SI 0 "register_operand" "=r")
5159 (div:SI (match_dup 1) (match_dup 2)))
5160 (clobber (match_scratch:SI 3 "=&r"))]
5161 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
5164 return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tsdivcc\t%1, %2, %0";
5166 return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tnop\n\tnop\n\tnop\n\tsdivcc\t%1, %2, %0";
5168 [(set_attr "type" "multi")
5169 (set (attr "length")
5170 (if_then_else (eq_attr "isa" "v9")
5171 (const_int 3) (const_int 6)))])
5174 (define_expand "udivsi3"
5175 [(set (match_operand:SI 0 "register_operand" "")
5176 (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "")
5177 (match_operand:SI 2 "input_operand" "")))]
5178 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
5181 ;; The V8 architecture specifies that there must be 3 instructions between
5182 ;; a Y register write and a use of it for correct results.
5184 (define_insn "udivsi3_sp32"
5185 [(set (match_operand:SI 0 "register_operand" "=r,&r,&r")
5186 (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "r,r,m")
5187 (match_operand:SI 2 "input_operand" "rI,m,r")))]
5188 "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS)
5191 output_asm_insn ("wr\t%%g0, %%g0, %%y", operands);
5192 switch (which_alternative)
5195 return "nop\n\tnop\n\tnop\n\tudiv\t%1, %2, %0";
5197 return "ld\t%2, %0\n\tnop\n\tnop\n\tudiv\t%1, %0, %0";
5199 return "ld\t%1, %0\n\tnop\n\tnop\n\tudiv\t%0, %2, %0";
5202 [(set_attr "type" "multi")
5203 (set_attr "length" "5")])
5205 (define_insn "udivsi3_sp64"
5206 [(set (match_operand:SI 0 "register_operand" "=r")
5207 (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "r")
5208 (match_operand:SI 2 "input_operand" "rI")))]
5209 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5210 "wr\t%%g0, 0, %%y\n\tudiv\t%1, %2, %0"
5211 [(set_attr "type" "multi")
5212 (set_attr "length" "2")])
5214 (define_insn "udivdi3"
5215 [(set (match_operand:DI 0 "register_operand" "=r")
5216 (udiv:DI (match_operand:DI 1 "register_operand" "r")
5217 (match_operand:DI 2 "arith_operand" "rI")))]
5220 [(set_attr "type" "idiv")])
5222 (define_insn "*cmp_udiv_cc_set"
5224 (compare:CC (udiv:SI (match_operand:SI 1 "register_operand" "r")
5225 (match_operand:SI 2 "arith_operand" "rI"))
5227 (set (match_operand:SI 0 "register_operand" "=r")
5228 (udiv:SI (match_dup 1) (match_dup 2)))]
5230 || TARGET_DEPRECATED_V8_INSNS"
5233 return "wr\t%%g0, %%g0, %%y\n\tudivcc\t%1, %2, %0";
5235 return "wr\t%%g0, %%g0, %%y\n\tnop\n\tnop\n\tnop\n\tudivcc\t%1, %2, %0";
5237 [(set_attr "type" "multi")
5238 (set (attr "length")
5239 (if_then_else (eq_attr "isa" "v9")
5240 (const_int 2) (const_int 5)))])
5242 ; sparclet multiply/accumulate insns
5244 (define_insn "*smacsi"
5245 [(set (match_operand:SI 0 "register_operand" "=r")
5246 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "%r")
5247 (match_operand:SI 2 "arith_operand" "rI"))
5248 (match_operand:SI 3 "register_operand" "0")))]
5251 [(set_attr "type" "imul")])
5253 (define_insn "*smacdi"
5254 [(set (match_operand:DI 0 "register_operand" "=r")
5255 (plus:DI (mult:DI (sign_extend:DI
5256 (match_operand:SI 1 "register_operand" "%r"))
5258 (match_operand:SI 2 "register_operand" "r")))
5259 (match_operand:DI 3 "register_operand" "0")))]
5261 "smacd\t%1, %2, %L0"
5262 [(set_attr "type" "imul")])
5264 (define_insn "*umacdi"
5265 [(set (match_operand:DI 0 "register_operand" "=r")
5266 (plus:DI (mult:DI (zero_extend:DI
5267 (match_operand:SI 1 "register_operand" "%r"))
5269 (match_operand:SI 2 "register_operand" "r")))
5270 (match_operand:DI 3 "register_operand" "0")))]
5272 "umacd\t%1, %2, %L0"
5273 [(set_attr "type" "imul")])
5276 ;; Boolean instructions.
5278 ;; We define DImode `and' so with DImode `not' we can get
5279 ;; DImode `andn'. Other combinations are possible.
5281 (define_mode_iterator V64I [DI V2SI V4HI V8QI])
5282 (define_mode_iterator V32I [SI V2HI V4QI])
5284 (define_expand "and<V64I:mode>3"
5285 [(set (match_operand:V64I 0 "register_operand" "")
5286 (and:V64I (match_operand:V64I 1 "arith_double_operand" "")
5287 (match_operand:V64I 2 "arith_double_operand" "")))]
5291 (define_insn "*and<V64I:mode>3_sp32"
5292 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5293 (and:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
5294 (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
5299 [(set_attr "type" "*,fga")
5300 (set_attr "length" "2,*")
5301 (set_attr "fptype" "*,double")])
5303 (define_insn "*and<V64I:mode>3_sp64"
5304 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5305 (and:V64I (match_operand:V64I 1 "arith_operand" "%r,b")
5306 (match_operand:V64I 2 "arith_operand" "rI,b")))]
5311 [(set_attr "type" "*,fga")
5312 (set_attr "fptype" "*,double")])
5314 (define_insn "and<V32I:mode>3"
5315 [(set (match_operand:V32I 0 "register_operand" "=r,d")
5316 (and:V32I (match_operand:V32I 1 "arith_operand" "%r,d")
5317 (match_operand:V32I 2 "arith_operand" "rI,d")))]
5322 [(set_attr "type" "*,fga")
5323 (set_attr "fptype" "*,single")])
5326 [(set (match_operand:SI 0 "register_operand" "")
5327 (and:SI (match_operand:SI 1 "register_operand" "")
5328 (match_operand:SI 2 "const_compl_high_operand" "")))
5329 (clobber (match_operand:SI 3 "register_operand" ""))]
5331 [(set (match_dup 3) (match_dup 4))
5332 (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 1)))]
5334 operands[4] = GEN_INT (~INTVAL (operands[2]));
5337 (define_insn_and_split "*and_not_<V64I:mode>_sp32"
5338 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5339 (and:V64I (not:V64I (match_operand:V64I 1 "register_operand" "%r,b"))
5340 (match_operand:V64I 2 "register_operand" "r,b")))]
5344 fandnot1\t%1, %2, %0"
5345 "&& reload_completed
5346 && ((GET_CODE (operands[0]) == REG
5347 && REGNO (operands[0]) < 32)
5348 || (GET_CODE (operands[0]) == SUBREG
5349 && GET_CODE (SUBREG_REG (operands[0])) == REG
5350 && REGNO (SUBREG_REG (operands[0])) < 32))"
5351 [(set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))
5352 (set (match_dup 6) (and:SI (not:SI (match_dup 7)) (match_dup 8)))]
5353 "operands[3] = gen_highpart (SImode, operands[0]);
5354 operands[4] = gen_highpart (SImode, operands[1]);
5355 operands[5] = gen_highpart (SImode, operands[2]);
5356 operands[6] = gen_lowpart (SImode, operands[0]);
5357 operands[7] = gen_lowpart (SImode, operands[1]);
5358 operands[8] = gen_lowpart (SImode, operands[2]);"
5359 [(set_attr "type" "*,fga")
5360 (set_attr "length" "2,*")
5361 (set_attr "fptype" "*,double")])
5363 (define_insn "*and_not_<V64I:mode>_sp64"
5364 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5365 (and:V64I (not:V64I (match_operand:V64I 1 "register_operand" "%r,b"))
5366 (match_operand:V64I 2 "register_operand" "r,b")))]
5370 fandnot1\t%1, %2, %0"
5371 [(set_attr "type" "*,fga")
5372 (set_attr "fptype" "*,double")])
5374 (define_insn "*and_not_<V32I:mode>"
5375 [(set (match_operand:V32I 0 "register_operand" "=r,d")
5376 (and:V32I (not:V32I (match_operand:V32I 1 "register_operand" "%r,d"))
5377 (match_operand:V32I 2 "register_operand" "r,d")))]
5381 fandnot1s\t%1, %2, %0"
5382 [(set_attr "type" "*,fga")
5383 (set_attr "fptype" "*,single")])
5385 (define_expand "ior<V64I:mode>3"
5386 [(set (match_operand:V64I 0 "register_operand" "")
5387 (ior:V64I (match_operand:V64I 1 "arith_double_operand" "")
5388 (match_operand:V64I 2 "arith_double_operand" "")))]
5392 (define_insn "*ior<V64I:mode>3_sp32"
5393 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5394 (ior:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
5395 (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
5400 [(set_attr "type" "*,fga")
5401 (set_attr "length" "2,*")
5402 (set_attr "fptype" "*,double")])
5404 (define_insn "*ior<V64I:mode>3_sp64"
5405 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5406 (ior:V64I (match_operand:V64I 1 "arith_operand" "%r,b")
5407 (match_operand:V64I 2 "arith_operand" "rI,b")))]
5412 [(set_attr "type" "*,fga")
5413 (set_attr "fptype" "*,double")])
5415 (define_insn "ior<V32I:mode>3"
5416 [(set (match_operand:V32I 0 "register_operand" "=r,d")
5417 (ior:V32I (match_operand:V32I 1 "arith_operand" "%r,d")
5418 (match_operand:V32I 2 "arith_operand" "rI,d")))]
5423 [(set_attr "type" "*,fga")
5424 (set_attr "fptype" "*,single")])
5427 [(set (match_operand:SI 0 "register_operand" "")
5428 (ior:SI (match_operand:SI 1 "register_operand" "")
5429 (match_operand:SI 2 "const_compl_high_operand" "")))
5430 (clobber (match_operand:SI 3 "register_operand" ""))]
5432 [(set (match_dup 3) (match_dup 4))
5433 (set (match_dup 0) (ior:SI (not:SI (match_dup 3)) (match_dup 1)))]
5435 operands[4] = GEN_INT (~INTVAL (operands[2]));
5438 (define_insn_and_split "*or_not_<V64I:mode>_sp32"
5439 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5440 (ior:V64I (not:V64I (match_operand:V64I 1 "register_operand" "r,b"))
5441 (match_operand:V64I 2 "register_operand" "r,b")))]
5445 fornot1\t%1, %2, %0"
5446 "&& reload_completed
5447 && ((GET_CODE (operands[0]) == REG
5448 && REGNO (operands[0]) < 32)
5449 || (GET_CODE (operands[0]) == SUBREG
5450 && GET_CODE (SUBREG_REG (operands[0])) == REG
5451 && REGNO (SUBREG_REG (operands[0])) < 32))"
5452 [(set (match_dup 3) (ior:SI (not:SI (match_dup 4)) (match_dup 5)))
5453 (set (match_dup 6) (ior:SI (not:SI (match_dup 7)) (match_dup 8)))]
5454 "operands[3] = gen_highpart (SImode, operands[0]);
5455 operands[4] = gen_highpart (SImode, operands[1]);
5456 operands[5] = gen_highpart (SImode, operands[2]);
5457 operands[6] = gen_lowpart (SImode, operands[0]);
5458 operands[7] = gen_lowpart (SImode, operands[1]);
5459 operands[8] = gen_lowpart (SImode, operands[2]);"
5460 [(set_attr "type" "*,fga")
5461 (set_attr "length" "2,*")
5462 (set_attr "fptype" "*,double")])
5464 (define_insn "*or_not_<V64I:mode>_sp64"
5465 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5466 (ior:V64I (not:V64I (match_operand:V64I 1 "register_operand" "r,b"))
5467 (match_operand:V64I 2 "register_operand" "r,b")))]
5471 fornot1\t%1, %2, %0"
5472 [(set_attr "type" "*,fga")
5473 (set_attr "fptype" "*,double")])
5475 (define_insn "*or_not_<V32I:mode>"
5476 [(set (match_operand:V32I 0 "register_operand" "=r,d")
5477 (ior:V32I (not:V32I (match_operand:V32I 1 "register_operand" "r,d"))
5478 (match_operand:V32I 2 "register_operand" "r,d")))]
5482 fornot1s\t%1, %2, %0"
5483 [(set_attr "type" "*,fga")
5484 (set_attr "fptype" "*,single")])
5486 (define_expand "xor<V64I:mode>3"
5487 [(set (match_operand:V64I 0 "register_operand" "")
5488 (xor:V64I (match_operand:V64I 1 "arith_double_operand" "")
5489 (match_operand:V64I 2 "arith_double_operand" "")))]
5493 (define_insn "*xor<V64I:mode>3_sp32"
5494 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5495 (xor:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
5496 (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
5501 [(set_attr "type" "*,fga")
5502 (set_attr "length" "2,*")
5503 (set_attr "fptype" "*,double")])
5505 (define_insn "*xor<V64I:mode>3_sp64"
5506 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5507 (xor:V64I (match_operand:V64I 1 "arith_operand" "%rJ,b")
5508 (match_operand:V64I 2 "arith_operand" "rI,b")))]
5513 [(set_attr "type" "*,fga")
5514 (set_attr "fptype" "*,double")])
5516 (define_insn "xor<V32I:mode>3"
5517 [(set (match_operand:V32I 0 "register_operand" "=r,d")
5518 (xor:V32I (match_operand:V32I 1 "arith_operand" "%rJ,d")
5519 (match_operand:V32I 2 "arith_operand" "rI,d")))]
5524 [(set_attr "type" "*,fga")
5525 (set_attr "fptype" "*,single")])
5528 [(set (match_operand:SI 0 "register_operand" "")
5529 (xor:SI (match_operand:SI 1 "register_operand" "")
5530 (match_operand:SI 2 "const_compl_high_operand" "")))
5531 (clobber (match_operand:SI 3 "register_operand" ""))]
5533 [(set (match_dup 3) (match_dup 4))
5534 (set (match_dup 0) (not:SI (xor:SI (match_dup 3) (match_dup 1))))]
5536 operands[4] = GEN_INT (~INTVAL (operands[2]));
5540 [(set (match_operand:SI 0 "register_operand" "")
5541 (not:SI (xor:SI (match_operand:SI 1 "register_operand" "")
5542 (match_operand:SI 2 "const_compl_high_operand" ""))))
5543 (clobber (match_operand:SI 3 "register_operand" ""))]
5545 [(set (match_dup 3) (match_dup 4))
5546 (set (match_dup 0) (xor:SI (match_dup 3) (match_dup 1)))]
5548 operands[4] = GEN_INT (~INTVAL (operands[2]));
5551 ;; Split DImode logical operations requiring two instructions.
5553 [(set (match_operand:V64I 0 "register_operand" "")
5554 (match_operator:V64I 1 "cc_arith_operator" ; AND, IOR, XOR
5555 [(match_operand:V64I 2 "register_operand" "")
5556 (match_operand:V64I 3 "arith_double_operand" "")]))]
5559 && ((GET_CODE (operands[0]) == REG
5560 && REGNO (operands[0]) < 32)
5561 || (GET_CODE (operands[0]) == SUBREG
5562 && GET_CODE (SUBREG_REG (operands[0])) == REG
5563 && REGNO (SUBREG_REG (operands[0])) < 32))"
5564 [(set (match_dup 4) (match_op_dup:SI 1 [(match_dup 6) (match_dup 8)]))
5565 (set (match_dup 5) (match_op_dup:SI 1 [(match_dup 7) (match_dup 9)]))]
5567 operands[4] = gen_highpart (SImode, operands[0]);
5568 operands[5] = gen_lowpart (SImode, operands[0]);
5569 operands[6] = gen_highpart (SImode, operands[2]);
5570 operands[7] = gen_lowpart (SImode, operands[2]);
5571 #if HOST_BITS_PER_WIDE_INT == 32
5572 if (GET_CODE (operands[3]) == CONST_INT && <V64I:MODE>mode == DImode)
5574 if (INTVAL (operands[3]) < 0)
5575 operands[8] = constm1_rtx;
5577 operands[8] = const0_rtx;
5581 operands[8] = gen_highpart_mode (SImode, <V64I:MODE>mode, operands[3]);
5582 operands[9] = gen_lowpart (SImode, operands[3]);
5585 ;; xnor patterns. Note that (a ^ ~b) == (~a ^ b) == ~(a ^ b).
5586 ;; Combine now canonicalizes to the rightmost expression.
5587 (define_insn_and_split "*xor_not_<V64I:mode>_sp32"
5588 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5589 (not:V64I (xor:V64I (match_operand:V64I 1 "register_operand" "r,b")
5590 (match_operand:V64I 2 "register_operand" "r,b"))))]
5595 "&& reload_completed
5596 && ((GET_CODE (operands[0]) == REG
5597 && REGNO (operands[0]) < 32)
5598 || (GET_CODE (operands[0]) == SUBREG
5599 && GET_CODE (SUBREG_REG (operands[0])) == REG
5600 && REGNO (SUBREG_REG (operands[0])) < 32))"
5601 [(set (match_dup 3) (not:SI (xor:SI (match_dup 4) (match_dup 5))))
5602 (set (match_dup 6) (not:SI (xor:SI (match_dup 7) (match_dup 8))))]
5603 "operands[3] = gen_highpart (SImode, operands[0]);
5604 operands[4] = gen_highpart (SImode, operands[1]);
5605 operands[5] = gen_highpart (SImode, operands[2]);
5606 operands[6] = gen_lowpart (SImode, operands[0]);
5607 operands[7] = gen_lowpart (SImode, operands[1]);
5608 operands[8] = gen_lowpart (SImode, operands[2]);"
5609 [(set_attr "type" "*,fga")
5610 (set_attr "length" "2,*")
5611 (set_attr "fptype" "*,double")])
5613 (define_insn "*xor_not_<V64I:mode>_sp64"
5614 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5615 (not:V64I (xor:V64I (match_operand:V64I 1 "register_or_zero_operand" "rJ,b")
5616 (match_operand:V64I 2 "arith_operand" "rI,b"))))]
5621 [(set_attr "type" "*,fga")
5622 (set_attr "fptype" "*,double")])
5624 (define_insn "*xor_not_<V32I:mode>"
5625 [(set (match_operand:V32I 0 "register_operand" "=r,d")
5626 (not:V32I (xor:V32I (match_operand:V32I 1 "register_or_zero_operand" "rJ,d")
5627 (match_operand:V32I 2 "arith_operand" "rI,d"))))]
5632 [(set_attr "type" "*,fga")
5633 (set_attr "fptype" "*,single")])
5635 ;; These correspond to the above in the case where we also (or only)
5636 ;; want to set the condition code.
5638 (define_insn "*cmp_cc_arith_op"
5641 (match_operator:SI 2 "cc_arith_operator"
5642 [(match_operand:SI 0 "arith_operand" "%r")
5643 (match_operand:SI 1 "arith_operand" "rI")])
5646 "%A2cc\t%0, %1, %%g0"
5647 [(set_attr "type" "compare")])
5649 (define_insn "*cmp_ccx_arith_op"
5652 (match_operator:DI 2 "cc_arith_operator"
5653 [(match_operand:DI 0 "arith_operand" "%r")
5654 (match_operand:DI 1 "arith_operand" "rI")])
5657 "%A2cc\t%0, %1, %%g0"
5658 [(set_attr "type" "compare")])
5660 (define_insn "*cmp_cc_arith_op_set"
5663 (match_operator:SI 3 "cc_arith_operator"
5664 [(match_operand:SI 1 "arith_operand" "%r")
5665 (match_operand:SI 2 "arith_operand" "rI")])
5667 (set (match_operand:SI 0 "register_operand" "=r")
5668 (match_operator:SI 4 "cc_arith_operator" [(match_dup 1) (match_dup 2)]))]
5669 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
5671 [(set_attr "type" "compare")])
5673 (define_insn "*cmp_ccx_arith_op_set"
5676 (match_operator:DI 3 "cc_arith_operator"
5677 [(match_operand:DI 1 "arith_operand" "%r")
5678 (match_operand:DI 2 "arith_operand" "rI")])
5680 (set (match_operand:DI 0 "register_operand" "=r")
5681 (match_operator:DI 4 "cc_arith_operator" [(match_dup 1) (match_dup 2)]))]
5682 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
5684 [(set_attr "type" "compare")])
5686 (define_insn "*cmp_cc_xor_not"
5689 (not:SI (xor:SI (match_operand:SI 0 "register_or_zero_operand" "%rJ")
5690 (match_operand:SI 1 "arith_operand" "rI")))
5693 "xnorcc\t%r0, %1, %%g0"
5694 [(set_attr "type" "compare")])
5696 (define_insn "*cmp_ccx_xor_not"
5699 (not:DI (xor:DI (match_operand:DI 0 "register_or_zero_operand" "%rJ")
5700 (match_operand:DI 1 "arith_operand" "rI")))
5703 "xnorcc\t%r0, %1, %%g0"
5704 [(set_attr "type" "compare")])
5706 (define_insn "*cmp_cc_xor_not_set"
5709 (not:SI (xor:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ")
5710 (match_operand:SI 2 "arith_operand" "rI")))
5712 (set (match_operand:SI 0 "register_operand" "=r")
5713 (not:SI (xor:SI (match_dup 1) (match_dup 2))))]
5715 "xnorcc\t%r1, %2, %0"
5716 [(set_attr "type" "compare")])
5718 (define_insn "*cmp_ccx_xor_not_set"
5721 (not:DI (xor:DI (match_operand:DI 1 "register_or_zero_operand" "%rJ")
5722 (match_operand:DI 2 "arith_operand" "rI")))
5724 (set (match_operand:DI 0 "register_operand" "=r")
5725 (not:DI (xor:DI (match_dup 1) (match_dup 2))))]
5727 "xnorcc\t%r1, %2, %0"
5728 [(set_attr "type" "compare")])
5730 (define_insn "*cmp_cc_arith_op_not"
5733 (match_operator:SI 2 "cc_arith_not_operator"
5734 [(not:SI (match_operand:SI 0 "arith_operand" "rI"))
5735 (match_operand:SI 1 "register_or_zero_operand" "rJ")])
5738 "%B2cc\t%r1, %0, %%g0"
5739 [(set_attr "type" "compare")])
5741 (define_insn "*cmp_ccx_arith_op_not"
5744 (match_operator:DI 2 "cc_arith_not_operator"
5745 [(not:DI (match_operand:DI 0 "arith_operand" "rI"))
5746 (match_operand:DI 1 "register_or_zero_operand" "rJ")])
5749 "%B2cc\t%r1, %0, %%g0"
5750 [(set_attr "type" "compare")])
5752 (define_insn "*cmp_cc_arith_op_not_set"
5755 (match_operator:SI 3 "cc_arith_not_operator"
5756 [(not:SI (match_operand:SI 1 "arith_operand" "rI"))
5757 (match_operand:SI 2 "register_or_zero_operand" "rJ")])
5759 (set (match_operand:SI 0 "register_operand" "=r")
5760 (match_operator:SI 4 "cc_arith_not_operator"
5761 [(not:SI (match_dup 1)) (match_dup 2)]))]
5762 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
5763 "%B3cc\t%r2, %1, %0"
5764 [(set_attr "type" "compare")])
5766 (define_insn "*cmp_ccx_arith_op_not_set"
5769 (match_operator:DI 3 "cc_arith_not_operator"
5770 [(not:DI (match_operand:DI 1 "arith_operand" "rI"))
5771 (match_operand:DI 2 "register_or_zero_operand" "rJ")])
5773 (set (match_operand:DI 0 "register_operand" "=r")
5774 (match_operator:DI 4 "cc_arith_not_operator"
5775 [(not:DI (match_dup 1)) (match_dup 2)]))]
5776 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
5777 "%B3cc\t%r2, %1, %0"
5778 [(set_attr "type" "compare")])
5780 ;; We cannot use the "neg" pseudo insn because the Sun assembler
5781 ;; does not know how to make it work for constants.
5783 (define_expand "negdi2"
5784 [(set (match_operand:DI 0 "register_operand" "=r")
5785 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
5788 if (! TARGET_ARCH64)
5790 emit_insn (gen_rtx_PARALLEL
5793 gen_rtx_SET (VOIDmode, operand0,
5794 gen_rtx_NEG (DImode, operand1)),
5795 gen_rtx_CLOBBER (VOIDmode,
5796 gen_rtx_REG (CCmode,
5802 (define_insn_and_split "*negdi2_sp32"
5803 [(set (match_operand:DI 0 "register_operand" "=r")
5804 (neg:DI (match_operand:DI 1 "register_operand" "r")))
5805 (clobber (reg:CC 100))]
5808 "&& reload_completed"
5809 [(parallel [(set (reg:CC_NOOV 100)
5810 (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 5))
5812 (set (match_dup 4) (minus:SI (const_int 0) (match_dup 5)))])
5813 (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
5814 (ltu:SI (reg:CC 100) (const_int 0))))]
5815 "operands[2] = gen_highpart (SImode, operands[0]);
5816 operands[3] = gen_highpart (SImode, operands[1]);
5817 operands[4] = gen_lowpart (SImode, operands[0]);
5818 operands[5] = gen_lowpart (SImode, operands[1]);"
5819 [(set_attr "length" "2")])
5821 (define_insn "*negdi2_sp64"
5822 [(set (match_operand:DI 0 "register_operand" "=r")
5823 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
5825 "sub\t%%g0, %1, %0")
5827 (define_insn "negsi2"
5828 [(set (match_operand:SI 0 "register_operand" "=r")
5829 (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
5831 "sub\t%%g0, %1, %0")
5833 (define_insn "*cmp_cc_neg"
5834 [(set (reg:CC_NOOV 100)
5835 (compare:CC_NOOV (neg:SI (match_operand:SI 0 "arith_operand" "rI"))
5838 "subcc\t%%g0, %0, %%g0"
5839 [(set_attr "type" "compare")])
5841 (define_insn "*cmp_ccx_neg"
5842 [(set (reg:CCX_NOOV 100)
5843 (compare:CCX_NOOV (neg:DI (match_operand:DI 0 "arith_operand" "rI"))
5846 "subcc\t%%g0, %0, %%g0"
5847 [(set_attr "type" "compare")])
5849 (define_insn "*cmp_cc_set_neg"
5850 [(set (reg:CC_NOOV 100)
5851 (compare:CC_NOOV (neg:SI (match_operand:SI 1 "arith_operand" "rI"))
5853 (set (match_operand:SI 0 "register_operand" "=r")
5854 (neg:SI (match_dup 1)))]
5856 "subcc\t%%g0, %1, %0"
5857 [(set_attr "type" "compare")])
5859 (define_insn "*cmp_ccx_set_neg"
5860 [(set (reg:CCX_NOOV 100)
5861 (compare:CCX_NOOV (neg:DI (match_operand:DI 1 "arith_operand" "rI"))
5863 (set (match_operand:DI 0 "register_operand" "=r")
5864 (neg:DI (match_dup 1)))]
5866 "subcc\t%%g0, %1, %0"
5867 [(set_attr "type" "compare")])
5869 ;; We cannot use the "not" pseudo insn because the Sun assembler
5870 ;; does not know how to make it work for constants.
5871 (define_expand "one_cmpl<V64I:mode>2"
5872 [(set (match_operand:V64I 0 "register_operand" "")
5873 (not:V64I (match_operand:V64I 1 "register_operand" "")))]
5877 (define_insn_and_split "*one_cmpl<V64I:mode>2_sp32"
5878 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5879 (not:V64I (match_operand:V64I 1 "register_operand" "r,b")))]
5884 "&& reload_completed
5885 && ((GET_CODE (operands[0]) == REG
5886 && REGNO (operands[0]) < 32)
5887 || (GET_CODE (operands[0]) == SUBREG
5888 && GET_CODE (SUBREG_REG (operands[0])) == REG
5889 && REGNO (SUBREG_REG (operands[0])) < 32))"
5890 [(set (match_dup 2) (not:SI (xor:SI (match_dup 3) (const_int 0))))
5891 (set (match_dup 4) (not:SI (xor:SI (match_dup 5) (const_int 0))))]
5892 "operands[2] = gen_highpart (SImode, operands[0]);
5893 operands[3] = gen_highpart (SImode, operands[1]);
5894 operands[4] = gen_lowpart (SImode, operands[0]);
5895 operands[5] = gen_lowpart (SImode, operands[1]);"
5896 [(set_attr "type" "*,fga")
5897 (set_attr "length" "2,*")
5898 (set_attr "fptype" "*,double")])
5900 (define_insn "*one_cmpl<V64I:mode>2_sp64"
5901 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5902 (not:V64I (match_operand:V64I 1 "arith_operand" "rI,b")))]
5907 [(set_attr "type" "*,fga")
5908 (set_attr "fptype" "*,double")])
5910 (define_insn "one_cmpl<V32I:mode>2"
5911 [(set (match_operand:V32I 0 "register_operand" "=r,d")
5912 (not:V32I (match_operand:V32I 1 "arith_operand" "rI,d")))]
5917 [(set_attr "type" "*,fga")
5918 (set_attr "fptype" "*,single")])
5920 (define_insn "*cmp_cc_not"
5922 (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI"))
5925 "xnorcc\t%%g0, %0, %%g0"
5926 [(set_attr "type" "compare")])
5928 (define_insn "*cmp_ccx_not"
5930 (compare:CCX (not:DI (match_operand:DI 0 "arith_operand" "rI"))
5933 "xnorcc\t%%g0, %0, %%g0"
5934 [(set_attr "type" "compare")])
5936 (define_insn "*cmp_cc_set_not"
5938 (compare:CC (not:SI (match_operand:SI 1 "arith_operand" "rI"))
5940 (set (match_operand:SI 0 "register_operand" "=r")
5941 (not:SI (match_dup 1)))]
5943 "xnorcc\t%%g0, %1, %0"
5944 [(set_attr "type" "compare")])
5946 (define_insn "*cmp_ccx_set_not"
5948 (compare:CCX (not:DI (match_operand:DI 1 "arith_operand" "rI"))
5950 (set (match_operand:DI 0 "register_operand" "=r")
5951 (not:DI (match_dup 1)))]
5953 "xnorcc\t%%g0, %1, %0"
5954 [(set_attr "type" "compare")])
5956 (define_insn "*cmp_cc_set"
5957 [(set (match_operand:SI 0 "register_operand" "=r")
5958 (match_operand:SI 1 "register_operand" "r"))
5960 (compare:CC (match_dup 1)
5964 [(set_attr "type" "compare")])
5966 (define_insn "*cmp_ccx_set64"
5967 [(set (match_operand:DI 0 "register_operand" "=r")
5968 (match_operand:DI 1 "register_operand" "r"))
5970 (compare:CCX (match_dup 1)
5974 [(set_attr "type" "compare")])
5977 ;; Floating point arithmetic instructions.
5979 (define_expand "addtf3"
5980 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5981 (plus:TF (match_operand:TF 1 "general_operand" "")
5982 (match_operand:TF 2 "general_operand" "")))]
5983 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5984 "emit_tfmode_binop (PLUS, operands); DONE;")
5986 (define_insn "*addtf3_hq"
5987 [(set (match_operand:TF 0 "register_operand" "=e")
5988 (plus:TF (match_operand:TF 1 "register_operand" "e")
5989 (match_operand:TF 2 "register_operand" "e")))]
5990 "TARGET_FPU && TARGET_HARD_QUAD"
5992 [(set_attr "type" "fp")])
5994 (define_insn "adddf3"
5995 [(set (match_operand:DF 0 "register_operand" "=e")
5996 (plus:DF (match_operand:DF 1 "register_operand" "e")
5997 (match_operand:DF 2 "register_operand" "e")))]
6000 [(set_attr "type" "fp")
6001 (set_attr "fptype" "double")])
6003 (define_insn "addsf3"
6004 [(set (match_operand:SF 0 "register_operand" "=f")
6005 (plus:SF (match_operand:SF 1 "register_operand" "f")
6006 (match_operand:SF 2 "register_operand" "f")))]
6009 [(set_attr "type" "fp")])
6011 (define_expand "subtf3"
6012 [(set (match_operand:TF 0 "nonimmediate_operand" "")
6013 (minus:TF (match_operand:TF 1 "general_operand" "")
6014 (match_operand:TF 2 "general_operand" "")))]
6015 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6016 "emit_tfmode_binop (MINUS, operands); DONE;")
6018 (define_insn "*subtf3_hq"
6019 [(set (match_operand:TF 0 "register_operand" "=e")
6020 (minus:TF (match_operand:TF 1 "register_operand" "e")
6021 (match_operand:TF 2 "register_operand" "e")))]
6022 "TARGET_FPU && TARGET_HARD_QUAD"
6024 [(set_attr "type" "fp")])
6026 (define_insn "subdf3"
6027 [(set (match_operand:DF 0 "register_operand" "=e")
6028 (minus:DF (match_operand:DF 1 "register_operand" "e")
6029 (match_operand:DF 2 "register_operand" "e")))]
6032 [(set_attr "type" "fp")
6033 (set_attr "fptype" "double")])
6035 (define_insn "subsf3"
6036 [(set (match_operand:SF 0 "register_operand" "=f")
6037 (minus:SF (match_operand:SF 1 "register_operand" "f")
6038 (match_operand:SF 2 "register_operand" "f")))]
6041 [(set_attr "type" "fp")])
6043 (define_expand "multf3"
6044 [(set (match_operand:TF 0 "nonimmediate_operand" "")
6045 (mult:TF (match_operand:TF 1 "general_operand" "")
6046 (match_operand:TF 2 "general_operand" "")))]
6047 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6048 "emit_tfmode_binop (MULT, operands); DONE;")
6050 (define_insn "*multf3_hq"
6051 [(set (match_operand:TF 0 "register_operand" "=e")
6052 (mult:TF (match_operand:TF 1 "register_operand" "e")
6053 (match_operand:TF 2 "register_operand" "e")))]
6054 "TARGET_FPU && TARGET_HARD_QUAD"
6056 [(set_attr "type" "fpmul")])
6058 (define_insn "muldf3"
6059 [(set (match_operand:DF 0 "register_operand" "=e")
6060 (mult:DF (match_operand:DF 1 "register_operand" "e")
6061 (match_operand:DF 2 "register_operand" "e")))]
6064 [(set_attr "type" "fpmul")
6065 (set_attr "fptype" "double")])
6067 (define_insn "mulsf3"
6068 [(set (match_operand:SF 0 "register_operand" "=f")
6069 (mult:SF (match_operand:SF 1 "register_operand" "f")
6070 (match_operand:SF 2 "register_operand" "f")))]
6073 [(set_attr "type" "fpmul")])
6075 (define_insn "*muldf3_extend"
6076 [(set (match_operand:DF 0 "register_operand" "=e")
6077 (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "f"))
6078 (float_extend:DF (match_operand:SF 2 "register_operand" "f"))))]
6079 "(TARGET_V8 || TARGET_V9) && TARGET_FPU"
6080 "fsmuld\t%1, %2, %0"
6081 [(set_attr "type" "fpmul")
6082 (set_attr "fptype" "double")])
6084 (define_insn "*multf3_extend"
6085 [(set (match_operand:TF 0 "register_operand" "=e")
6086 (mult:TF (float_extend:TF (match_operand:DF 1 "register_operand" "e"))
6087 (float_extend:TF (match_operand:DF 2 "register_operand" "e"))))]
6088 "(TARGET_V8 || TARGET_V9) && TARGET_FPU && TARGET_HARD_QUAD"
6089 "fdmulq\t%1, %2, %0"
6090 [(set_attr "type" "fpmul")])
6092 (define_expand "divtf3"
6093 [(set (match_operand:TF 0 "nonimmediate_operand" "")
6094 (div:TF (match_operand:TF 1 "general_operand" "")
6095 (match_operand:TF 2 "general_operand" "")))]
6096 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6097 "emit_tfmode_binop (DIV, operands); DONE;")
6099 ;; don't have timing for quad-prec. divide.
6100 (define_insn "*divtf3_hq"
6101 [(set (match_operand:TF 0 "register_operand" "=e")
6102 (div:TF (match_operand:TF 1 "register_operand" "e")
6103 (match_operand:TF 2 "register_operand" "e")))]
6104 "TARGET_FPU && TARGET_HARD_QUAD"
6106 [(set_attr "type" "fpdivd")])
6108 (define_insn "divdf3"
6109 [(set (match_operand:DF 0 "register_operand" "=e")
6110 (div:DF (match_operand:DF 1 "register_operand" "e")
6111 (match_operand:DF 2 "register_operand" "e")))]
6114 [(set_attr "type" "fpdivd")
6115 (set_attr "fptype" "double")])
6117 (define_insn "divsf3"
6118 [(set (match_operand:SF 0 "register_operand" "=f")
6119 (div:SF (match_operand:SF 1 "register_operand" "f")
6120 (match_operand:SF 2 "register_operand" "f")))]
6123 [(set_attr "type" "fpdivs")])
6125 (define_expand "negtf2"
6126 [(set (match_operand:TF 0 "register_operand" "=e,e")
6127 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
6131 (define_insn_and_split "*negtf2_notv9"
6132 [(set (match_operand:TF 0 "register_operand" "=e,e")
6133 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
6134 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
6140 "&& reload_completed
6141 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6142 [(set (match_dup 2) (neg:SF (match_dup 3)))
6143 (set (match_dup 4) (match_dup 5))
6144 (set (match_dup 6) (match_dup 7))]
6145 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6146 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6147 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6148 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
6149 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6150 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6151 [(set_attr "type" "fpmove,*")
6152 (set_attr "length" "*,2")])
6154 (define_insn_and_split "*negtf2_v9"
6155 [(set (match_operand:TF 0 "register_operand" "=e,e")
6156 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
6157 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
6158 "TARGET_FPU && TARGET_V9"
6162 "&& reload_completed
6163 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6164 [(set (match_dup 2) (neg:DF (match_dup 3)))
6165 (set (match_dup 4) (match_dup 5))]
6166 "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
6167 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
6168 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6169 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6170 [(set_attr "type" "fpmove,*")
6171 (set_attr "length" "*,2")
6172 (set_attr "fptype" "double")])
6174 (define_expand "negdf2"
6175 [(set (match_operand:DF 0 "register_operand" "")
6176 (neg:DF (match_operand:DF 1 "register_operand" "")))]
6180 (define_insn_and_split "*negdf2_notv9"
6181 [(set (match_operand:DF 0 "register_operand" "=e,e")
6182 (neg:DF (match_operand:DF 1 "register_operand" "0,e")))]
6183 "TARGET_FPU && ! TARGET_V9"
6187 "&& reload_completed
6188 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6189 [(set (match_dup 2) (neg:SF (match_dup 3)))
6190 (set (match_dup 4) (match_dup 5))]
6191 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6192 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6193 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6194 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);"
6195 [(set_attr "type" "fpmove,*")
6196 (set_attr "length" "*,2")])
6198 (define_insn "*negdf2_v9"
6199 [(set (match_operand:DF 0 "register_operand" "=e")
6200 (neg:DF (match_operand:DF 1 "register_operand" "e")))]
6201 "TARGET_FPU && TARGET_V9"
6203 [(set_attr "type" "fpmove")
6204 (set_attr "fptype" "double")])
6206 (define_insn "negsf2"
6207 [(set (match_operand:SF 0 "register_operand" "=f")
6208 (neg:SF (match_operand:SF 1 "register_operand" "f")))]
6211 [(set_attr "type" "fpmove")])
6213 (define_expand "abstf2"
6214 [(set (match_operand:TF 0 "register_operand" "")
6215 (abs:TF (match_operand:TF 1 "register_operand" "")))]
6219 (define_insn_and_split "*abstf2_notv9"
6220 [(set (match_operand:TF 0 "register_operand" "=e,e")
6221 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6222 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
6223 "TARGET_FPU && ! TARGET_V9"
6227 "&& reload_completed
6228 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6229 [(set (match_dup 2) (abs:SF (match_dup 3)))
6230 (set (match_dup 4) (match_dup 5))
6231 (set (match_dup 6) (match_dup 7))]
6232 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6233 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6234 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6235 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
6236 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6237 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6238 [(set_attr "type" "fpmove,*")
6239 (set_attr "length" "*,2")])
6241 (define_insn "*abstf2_hq_v9"
6242 [(set (match_operand:TF 0 "register_operand" "=e,e")
6243 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6244 "TARGET_FPU && TARGET_V9 && TARGET_HARD_QUAD"
6248 [(set_attr "type" "fpmove")
6249 (set_attr "fptype" "double,*")])
6251 (define_insn_and_split "*abstf2_v9"
6252 [(set (match_operand:TF 0 "register_operand" "=e,e")
6253 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6254 "TARGET_FPU && TARGET_V9 && !TARGET_HARD_QUAD"
6258 "&& reload_completed
6259 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6260 [(set (match_dup 2) (abs:DF (match_dup 3)))
6261 (set (match_dup 4) (match_dup 5))]
6262 "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
6263 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
6264 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6265 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6266 [(set_attr "type" "fpmove,*")
6267 (set_attr "length" "*,2")
6268 (set_attr "fptype" "double,*")])
6270 (define_expand "absdf2"
6271 [(set (match_operand:DF 0 "register_operand" "")
6272 (abs:DF (match_operand:DF 1 "register_operand" "")))]
6276 (define_insn_and_split "*absdf2_notv9"
6277 [(set (match_operand:DF 0 "register_operand" "=e,e")
6278 (abs:DF (match_operand:DF 1 "register_operand" "0,e")))]
6279 "TARGET_FPU && ! TARGET_V9"
6283 "&& reload_completed
6284 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6285 [(set (match_dup 2) (abs:SF (match_dup 3)))
6286 (set (match_dup 4) (match_dup 5))]
6287 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6288 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6289 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6290 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);"
6291 [(set_attr "type" "fpmove,*")
6292 (set_attr "length" "*,2")])
6294 (define_insn "*absdf2_v9"
6295 [(set (match_operand:DF 0 "register_operand" "=e")
6296 (abs:DF (match_operand:DF 1 "register_operand" "e")))]
6297 "TARGET_FPU && TARGET_V9"
6299 [(set_attr "type" "fpmove")
6300 (set_attr "fptype" "double")])
6302 (define_insn "abssf2"
6303 [(set (match_operand:SF 0 "register_operand" "=f")
6304 (abs:SF (match_operand:SF 1 "register_operand" "f")))]
6307 [(set_attr "type" "fpmove")])
6309 (define_expand "sqrttf2"
6310 [(set (match_operand:TF 0 "nonimmediate_operand" "")
6311 (sqrt:TF (match_operand:TF 1 "general_operand" "")))]
6312 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6313 "emit_tfmode_unop (SQRT, operands); DONE;")
6315 (define_insn "*sqrttf2_hq"
6316 [(set (match_operand:TF 0 "register_operand" "=e")
6317 (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
6318 "TARGET_FPU && TARGET_HARD_QUAD"
6320 [(set_attr "type" "fpsqrtd")])
6322 (define_insn "sqrtdf2"
6323 [(set (match_operand:DF 0 "register_operand" "=e")
6324 (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
6327 [(set_attr "type" "fpsqrtd")
6328 (set_attr "fptype" "double")])
6330 (define_insn "sqrtsf2"
6331 [(set (match_operand:SF 0 "register_operand" "=f")
6332 (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
6335 [(set_attr "type" "fpsqrts")])
6338 ;; Arithmetic shift instructions.
6340 (define_insn "ashlsi3"
6341 [(set (match_operand:SI 0 "register_operand" "=r")
6342 (ashift:SI (match_operand:SI 1 "register_operand" "r")
6343 (match_operand:SI 2 "arith_operand" "rI")))]
6346 if (GET_CODE (operands[2]) == CONST_INT)
6347 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6348 return "sll\t%1, %2, %0";
6351 (if_then_else (match_operand 2 "const_one_operand" "")
6352 (const_string "ialu") (const_string "shift")))])
6354 (define_expand "ashldi3"
6355 [(set (match_operand:DI 0 "register_operand" "=r")
6356 (ashift:DI (match_operand:DI 1 "register_operand" "r")
6357 (match_operand:SI 2 "arith_operand" "rI")))]
6358 "TARGET_ARCH64 || TARGET_V8PLUS"
6360 if (! TARGET_ARCH64)
6362 if (GET_CODE (operands[2]) == CONST_INT)
6364 emit_insn (gen_ashldi3_v8plus (operands[0], operands[1], operands[2]));
6369 (define_insn "*ashldi3_sp64"
6370 [(set (match_operand:DI 0 "register_operand" "=r")
6371 (ashift:DI (match_operand:DI 1 "register_operand" "r")
6372 (match_operand:SI 2 "arith_operand" "rI")))]
6375 if (GET_CODE (operands[2]) == CONST_INT)
6376 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
6377 return "sllx\t%1, %2, %0";
6380 (if_then_else (match_operand 2 "const_one_operand" "")
6381 (const_string "ialu") (const_string "shift")))])
6384 (define_insn "ashldi3_v8plus"
6385 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
6386 (ashift:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
6387 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
6388 (clobber (match_scratch:SI 3 "=X,X,&h"))]
6390 "* return output_v8plus_shift (operands, insn, \"sllx\");"
6391 [(set_attr "type" "multi")
6392 (set_attr "length" "5,5,6")])
6394 ;; Optimize (1LL<<x)-1
6395 ;; XXX this also needs to be fixed to handle equal subregs
6396 ;; XXX first before we could re-enable it.
6398 ; [(set (match_operand:DI 0 "register_operand" "=h")
6399 ; (plus:DI (ashift:DI (const_int 1)
6400 ; (match_operand:SI 1 "arith_operand" "rI"))
6402 ; "0 && TARGET_V8PLUS"
6404 ; if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == REGNO (operands[0]))
6405 ; return "mov\t1, %L0\;sllx\t%L0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
6406 ; return "mov\t1, %H0\;sllx\t%H0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
6408 ; [(set_attr "type" "multi")
6409 ; (set_attr "length" "4")])
6411 (define_insn "*cmp_cc_ashift_1"
6412 [(set (reg:CC_NOOV 100)
6413 (compare:CC_NOOV (ashift:SI (match_operand:SI 0 "register_operand" "r")
6417 "addcc\t%0, %0, %%g0"
6418 [(set_attr "type" "compare")])
6420 (define_insn "*cmp_cc_set_ashift_1"
6421 [(set (reg:CC_NOOV 100)
6422 (compare:CC_NOOV (ashift:SI (match_operand:SI 1 "register_operand" "r")
6425 (set (match_operand:SI 0 "register_operand" "=r")
6426 (ashift:SI (match_dup 1) (const_int 1)))]
6429 [(set_attr "type" "compare")])
6431 (define_insn "ashrsi3"
6432 [(set (match_operand:SI 0 "register_operand" "=r")
6433 (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
6434 (match_operand:SI 2 "arith_operand" "rI")))]
6437 if (GET_CODE (operands[2]) == CONST_INT)
6438 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6439 return "sra\t%1, %2, %0";
6441 [(set_attr "type" "shift")])
6443 (define_insn "*ashrsi3_extend"
6444 [(set (match_operand:DI 0 "register_operand" "=r")
6445 (sign_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
6446 (match_operand:SI 2 "arith_operand" "r"))))]
6449 [(set_attr "type" "shift")])
6451 ;; This handles the case as above, but with constant shift instead of
6452 ;; register. Combiner "simplifies" it for us a little bit though.
6453 (define_insn "*ashrsi3_extend2"
6454 [(set (match_operand:DI 0 "register_operand" "=r")
6455 (ashiftrt:DI (ashift:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
6457 (match_operand:SI 2 "small_int_operand" "I")))]
6458 "TARGET_ARCH64 && INTVAL (operands[2]) >= 32 && INTVAL (operands[2]) < 64"
6460 operands[2] = GEN_INT (INTVAL (operands[2]) - 32);
6461 return "sra\t%1, %2, %0";
6463 [(set_attr "type" "shift")])
6465 (define_expand "ashrdi3"
6466 [(set (match_operand:DI 0 "register_operand" "=r")
6467 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
6468 (match_operand:SI 2 "arith_operand" "rI")))]
6469 "TARGET_ARCH64 || TARGET_V8PLUS"
6471 if (! TARGET_ARCH64)
6473 if (GET_CODE (operands[2]) == CONST_INT)
6474 FAIL; /* prefer generic code in this case */
6475 emit_insn (gen_ashrdi3_v8plus (operands[0], operands[1], operands[2]));
6480 (define_insn "*ashrdi3_sp64"
6481 [(set (match_operand:DI 0 "register_operand" "=r")
6482 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
6483 (match_operand:SI 2 "arith_operand" "rI")))]
6487 if (GET_CODE (operands[2]) == CONST_INT)
6488 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
6489 return "srax\t%1, %2, %0";
6491 [(set_attr "type" "shift")])
6494 (define_insn "ashrdi3_v8plus"
6495 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
6496 (ashiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
6497 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
6498 (clobber (match_scratch:SI 3 "=X,X,&h"))]
6500 "* return output_v8plus_shift (operands, insn, \"srax\");"
6501 [(set_attr "type" "multi")
6502 (set_attr "length" "5,5,6")])
6504 (define_insn "lshrsi3"
6505 [(set (match_operand:SI 0 "register_operand" "=r")
6506 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
6507 (match_operand:SI 2 "arith_operand" "rI")))]
6510 if (GET_CODE (operands[2]) == CONST_INT)
6511 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6512 return "srl\t%1, %2, %0";
6514 [(set_attr "type" "shift")])
6516 ;; This handles the case where
6517 ;; (zero_extend:DI (lshiftrt:SI (match_operand:SI) (match_operand:SI))),
6518 ;; but combiner "simplifies" it for us.
6519 (define_insn "*lshrsi3_extend"
6520 [(set (match_operand:DI 0 "register_operand" "=r")
6521 (and:DI (subreg:DI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
6522 (match_operand:SI 2 "arith_operand" "r")) 0)
6523 (match_operand 3 "const_int_operand" "")))]
6524 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) == 0xffffffff"
6526 [(set_attr "type" "shift")])
6528 ;; This handles the case where
6529 ;; (lshiftrt:DI (zero_extend:DI (match_operand:SI)) (const_int >=0 < 32))
6530 ;; but combiner "simplifies" it for us.
6531 (define_insn "*lshrsi3_extend2"
6532 [(set (match_operand:DI 0 "register_operand" "=r")
6533 (zero_extract:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
6534 (match_operand 2 "small_int_operand" "I")
6536 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
6538 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
6539 return "srl\t%1, %2, %0";
6541 [(set_attr "type" "shift")])
6543 (define_expand "lshrdi3"
6544 [(set (match_operand:DI 0 "register_operand" "=r")
6545 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6546 (match_operand:SI 2 "arith_operand" "rI")))]
6547 "TARGET_ARCH64 || TARGET_V8PLUS"
6549 if (! TARGET_ARCH64)
6551 if (GET_CODE (operands[2]) == CONST_INT)
6553 emit_insn (gen_lshrdi3_v8plus (operands[0], operands[1], operands[2]));
6558 (define_insn "*lshrdi3_sp64"
6559 [(set (match_operand:DI 0 "register_operand" "=r")
6560 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6561 (match_operand:SI 2 "arith_operand" "rI")))]
6564 if (GET_CODE (operands[2]) == CONST_INT)
6565 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
6566 return "srlx\t%1, %2, %0";
6568 [(set_attr "type" "shift")])
6571 (define_insn "lshrdi3_v8plus"
6572 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
6573 (lshiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
6574 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
6575 (clobber (match_scratch:SI 3 "=X,X,&h"))]
6577 "* return output_v8plus_shift (operands, insn, \"srlx\");"
6578 [(set_attr "type" "multi")
6579 (set_attr "length" "5,5,6")])
6582 [(set (match_operand:SI 0 "register_operand" "=r")
6583 (ashiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6585 (match_operand:SI 2 "small_int_operand" "I")))]
6586 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
6588 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
6589 return "srax\t%1, %2, %0";
6591 [(set_attr "type" "shift")])
6594 [(set (match_operand:SI 0 "register_operand" "=r")
6595 (lshiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
6597 (match_operand:SI 2 "small_int_operand" "I")))]
6598 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
6600 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
6601 return "srlx\t%1, %2, %0";
6603 [(set_attr "type" "shift")])
6606 [(set (match_operand:SI 0 "register_operand" "=r")
6607 (ashiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
6608 (match_operand:SI 2 "small_int_operand" "I")) 4)
6609 (match_operand:SI 3 "small_int_operand" "I")))]
6611 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
6612 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
6613 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
6615 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
6617 return "srax\t%1, %2, %0";
6619 [(set_attr "type" "shift")])
6622 [(set (match_operand:SI 0 "register_operand" "=r")
6623 (lshiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6624 (match_operand:SI 2 "small_int_operand" "I")) 4)
6625 (match_operand:SI 3 "small_int_operand" "I")))]
6627 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
6628 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
6629 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
6631 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
6633 return "srlx\t%1, %2, %0";
6635 [(set_attr "type" "shift")])
6638 ;; Unconditional and other jump instructions.
6641 [(set (pc) (label_ref (match_operand 0 "" "")))]
6643 "* return output_ubranch (operands[0], 0, insn);"
6644 [(set_attr "type" "uncond_branch")])
6646 (define_expand "tablejump"
6647 [(parallel [(set (pc) (match_operand 0 "register_operand" "r"))
6648 (use (label_ref (match_operand 1 "" "")))])]
6651 gcc_assert (GET_MODE (operands[0]) == CASE_VECTOR_MODE);
6653 /* In pic mode, our address differences are against the base of the
6654 table. Add that base value back in; CSE ought to be able to combine
6655 the two address loads. */
6659 tmp = gen_rtx_LABEL_REF (Pmode, operands[1]);
6661 if (CASE_VECTOR_MODE != Pmode)
6662 tmp2 = gen_rtx_SIGN_EXTEND (Pmode, tmp2);
6663 tmp = gen_rtx_PLUS (Pmode, tmp2, tmp);
6664 operands[0] = memory_address (Pmode, tmp);
6668 (define_insn "*tablejump_sp32"
6669 [(set (pc) (match_operand:SI 0 "address_operand" "p"))
6670 (use (label_ref (match_operand 1 "" "")))]
6673 [(set_attr "type" "uncond_branch")])
6675 (define_insn "*tablejump_sp64"
6676 [(set (pc) (match_operand:DI 0 "address_operand" "p"))
6677 (use (label_ref (match_operand 1 "" "")))]
6680 [(set_attr "type" "uncond_branch")])
6683 ;; Jump to subroutine instructions.
6685 (define_expand "call"
6686 ;; Note that this expression is not used for generating RTL.
6687 ;; All the RTL is generated explicitly below.
6688 [(call (match_operand 0 "call_operand" "")
6689 (match_operand 3 "" "i"))]
6690 ;; operands[2] is next_arg_register
6691 ;; operands[3] is struct_value_size_rtx.
6696 gcc_assert (MEM_P (operands[0]) && GET_MODE (operands[0]) == FUNCTION_MODE);
6698 gcc_assert (GET_CODE (operands[3]) == CONST_INT);
6700 if (GET_CODE (XEXP (operands[0], 0)) == LABEL_REF)
6702 /* This is really a PIC sequence. We want to represent
6703 it as a funny jump so its delay slots can be filled.
6705 ??? But if this really *is* a CALL, will not it clobber the
6706 call-clobbered registers? We lose this if it is a JUMP_INSN.
6707 Why cannot we have delay slots filled if it were a CALL? */
6709 /* We accept negative sizes for untyped calls. */
6710 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
6715 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
6717 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
6723 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
6724 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
6728 fn_rtx = operands[0];
6730 /* We accept negative sizes for untyped calls. */
6731 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
6732 sparc_emit_call_insn
6735 gen_rtvec (3, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx),
6737 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))),
6740 sparc_emit_call_insn
6743 gen_rtvec (2, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx),
6744 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))),
6752 ;; We can't use the same pattern for these two insns, because then registers
6753 ;; in the address may not be properly reloaded.
6755 (define_insn "*call_address_sp32"
6756 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6757 (match_operand 1 "" ""))
6758 (clobber (reg:SI 15))]
6759 ;;- Do not use operand 1 for most machines.
6762 [(set_attr "type" "call")])
6764 (define_insn "*call_symbolic_sp32"
6765 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6766 (match_operand 1 "" ""))
6767 (clobber (reg:SI 15))]
6768 ;;- Do not use operand 1 for most machines.
6771 [(set_attr "type" "call")])
6773 (define_insn "*call_address_sp64"
6774 [(call (mem:DI (match_operand:DI 0 "address_operand" "p"))
6775 (match_operand 1 "" ""))
6776 (clobber (reg:DI 15))]
6777 ;;- Do not use operand 1 for most machines.
6780 [(set_attr "type" "call")])
6782 (define_insn "*call_symbolic_sp64"
6783 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
6784 (match_operand 1 "" ""))
6785 (clobber (reg:DI 15))]
6786 ;;- Do not use operand 1 for most machines.
6789 [(set_attr "type" "call")])
6791 ;; This is a call that wants a structure value.
6792 ;; There is no such critter for v9 (??? we may need one anyway).
6793 (define_insn "*call_address_struct_value_sp32"
6794 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6795 (match_operand 1 "" ""))
6796 (match_operand 2 "immediate_operand" "")
6797 (clobber (reg:SI 15))]
6798 ;;- Do not use operand 1 for most machines.
6799 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
6801 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xfff);
6802 return "call\t%a0, %1\n\t nop\n\tunimp\t%2";
6804 [(set_attr "type" "call_no_delay_slot")
6805 (set_attr "length" "3")])
6807 ;; This is a call that wants a structure value.
6808 ;; There is no such critter for v9 (??? we may need one anyway).
6809 (define_insn "*call_symbolic_struct_value_sp32"
6810 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6811 (match_operand 1 "" ""))
6812 (match_operand 2 "immediate_operand" "")
6813 (clobber (reg:SI 15))]
6814 ;;- Do not use operand 1 for most machines.
6815 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
6817 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xfff);
6818 return "call\t%a0, %1\n\t nop\n\tunimp\t%2";
6820 [(set_attr "type" "call_no_delay_slot")
6821 (set_attr "length" "3")])
6823 ;; This is a call that may want a structure value. This is used for
6825 (define_insn "*call_address_untyped_struct_value_sp32"
6826 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6827 (match_operand 1 "" ""))
6828 (match_operand 2 "immediate_operand" "")
6829 (clobber (reg:SI 15))]
6830 ;;- Do not use operand 1 for most machines.
6831 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
6832 "call\t%a0, %1\n\t nop\n\tnop"
6833 [(set_attr "type" "call_no_delay_slot")
6834 (set_attr "length" "3")])
6836 ;; This is a call that may want a structure value. This is used for
6838 (define_insn "*call_symbolic_untyped_struct_value_sp32"
6839 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6840 (match_operand 1 "" ""))
6841 (match_operand 2 "immediate_operand" "")
6842 (clobber (reg:SI 15))]
6843 ;;- Do not use operand 1 for most machines.
6844 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
6845 "call\t%a0, %1\n\t nop\n\tnop"
6846 [(set_attr "type" "call_no_delay_slot")
6847 (set_attr "length" "3")])
6849 (define_expand "call_value"
6850 ;; Note that this expression is not used for generating RTL.
6851 ;; All the RTL is generated explicitly below.
6852 [(set (match_operand 0 "register_operand" "=rf")
6853 (call (match_operand 1 "" "")
6854 (match_operand 4 "" "")))]
6855 ;; operand 2 is stack_size_rtx
6856 ;; operand 3 is next_arg_register
6862 gcc_assert (MEM_P (operands[1]) && GET_MODE (operands[1]) == FUNCTION_MODE);
6864 fn_rtx = operands[1];
6867 gen_rtx_SET (VOIDmode, operands[0],
6868 gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx)),
6869 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)));
6871 sparc_emit_call_insn (gen_rtx_PARALLEL (VOIDmode, vec), XEXP (fn_rtx, 0));
6876 (define_insn "*call_value_address_sp32"
6877 [(set (match_operand 0 "" "=rf")
6878 (call (mem:SI (match_operand:SI 1 "address_operand" "p"))
6879 (match_operand 2 "" "")))
6880 (clobber (reg:SI 15))]
6881 ;;- Do not use operand 2 for most machines.
6884 [(set_attr "type" "call")])
6886 (define_insn "*call_value_symbolic_sp32"
6887 [(set (match_operand 0 "" "=rf")
6888 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
6889 (match_operand 2 "" "")))
6890 (clobber (reg:SI 15))]
6891 ;;- Do not use operand 2 for most machines.
6894 [(set_attr "type" "call")])
6896 (define_insn "*call_value_address_sp64"
6897 [(set (match_operand 0 "" "")
6898 (call (mem:DI (match_operand:DI 1 "address_operand" "p"))
6899 (match_operand 2 "" "")))
6900 (clobber (reg:DI 15))]
6901 ;;- Do not use operand 2 for most machines.
6904 [(set_attr "type" "call")])
6906 (define_insn "*call_value_symbolic_sp64"
6907 [(set (match_operand 0 "" "")
6908 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
6909 (match_operand 2 "" "")))
6910 (clobber (reg:DI 15))]
6911 ;;- Do not use operand 2 for most machines.
6914 [(set_attr "type" "call")])
6916 (define_expand "untyped_call"
6917 [(parallel [(call (match_operand 0 "" "")
6919 (match_operand:BLK 1 "memory_operand" "")
6920 (match_operand 2 "" "")])]
6923 rtx valreg1 = gen_rtx_REG (DImode, 8);
6924 rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
6925 rtx result = operands[1];
6927 /* Pass constm1 to indicate that it may expect a structure value, but
6928 we don't know what size it is. */
6929 emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, constm1_rtx));
6931 /* Save the function value registers. */
6932 emit_move_insn (adjust_address (result, DImode, 0), valreg1);
6933 emit_move_insn (adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8),
6936 /* The optimizer does not know that the call sets the function value
6937 registers we stored in the result block. We avoid problems by
6938 claiming that all hard registers are used and clobbered at this
6940 emit_insn (gen_blockage ());
6945 ;; Tail call instructions.
6947 (define_expand "sibcall"
6948 [(parallel [(call (match_operand 0 "call_operand" "") (const_int 0))
6953 (define_insn "*sibcall_symbolic_sp32"
6954 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6955 (match_operand 1 "" ""))
6958 "* return output_sibcall(insn, operands[0]);"
6959 [(set_attr "type" "sibcall")])
6961 (define_insn "*sibcall_symbolic_sp64"
6962 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
6963 (match_operand 1 "" ""))
6966 "* return output_sibcall(insn, operands[0]);"
6967 [(set_attr "type" "sibcall")])
6969 (define_expand "sibcall_value"
6970 [(parallel [(set (match_operand 0 "register_operand" "=rf")
6971 (call (match_operand 1 "" "") (const_int 0)))
6976 (define_insn "*sibcall_value_symbolic_sp32"
6977 [(set (match_operand 0 "" "=rf")
6978 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
6979 (match_operand 2 "" "")))
6982 "* return output_sibcall(insn, operands[1]);"
6983 [(set_attr "type" "sibcall")])
6985 (define_insn "*sibcall_value_symbolic_sp64"
6986 [(set (match_operand 0 "" "")
6987 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
6988 (match_operand 2 "" "")))
6991 "* return output_sibcall(insn, operands[1]);"
6992 [(set_attr "type" "sibcall")])
6995 ;; Special instructions.
6997 (define_expand "prologue"
7001 sparc_expand_prologue ();
7005 ;; The "save register window" insn is modelled as follows so that the DWARF-2
7006 ;; backend automatically emits the required call frame debugging information
7007 ;; while it is parsing it. Therefore, the pattern should not be modified
7008 ;; without first studying the impact of the changes on the debug info.
7009 ;; [(set (%fp) (%sp))
7010 ;; (set (%sp) (unspec_volatile [(%sp) (-frame_size)] UNSPECV_SAVEW))
7011 ;; (set (%i7) (%o7))]
7013 (define_insn "save_register_window<P:mode>"
7014 [(set (reg:P 30) (reg:P 14))
7015 (set (reg:P 14) (unspec_volatile:P [(reg:P 14)
7016 (match_operand:P 0 "arith_operand" "rI")] UNSPECV_SAVEW))
7017 (set (reg:P 31) (reg:P 15))]
7019 "save\t%%sp, %0, %%sp"
7020 [(set_attr "type" "savew")])
7022 (define_expand "epilogue"
7026 sparc_expand_epilogue ();
7029 (define_expand "sibcall_epilogue"
7033 sparc_expand_epilogue ();
7037 (define_expand "return"
7039 "sparc_can_use_return_insn_p ()"
7042 (define_insn "*return_internal"
7045 "* return output_return (insn);"
7046 [(set_attr "type" "return")
7047 (set (attr "length")
7048 (cond [(eq_attr "leaf_function" "true")
7049 (if_then_else (eq_attr "empty_delay_slot" "true")
7052 (eq_attr "calls_eh_return" "true")
7053 (if_then_else (eq_attr "delayed_branch" "true")
7054 (if_then_else (eq_attr "isa" "v9")
7057 (if_then_else (eq_attr "isa" "v9")
7060 (eq_attr "empty_delay_slot" "true")
7061 (if_then_else (eq_attr "delayed_branch" "true")
7066 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
7067 ;; all of memory. This blocks insns from being moved across this point.
7069 (define_insn "blockage"
7070 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
7073 [(set_attr "length" "0")])
7075 ;; Prepare to return any type including a structure value.
7077 (define_expand "untyped_return"
7078 [(match_operand:BLK 0 "memory_operand" "")
7079 (match_operand 1 "" "")]
7082 rtx valreg1 = gen_rtx_REG (DImode, 24);
7083 rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
7084 rtx result = operands[0];
7086 if (! TARGET_ARCH64)
7088 rtx rtnreg = gen_rtx_REG (SImode, (current_function_uses_only_leaf_regs
7090 rtx value = gen_reg_rtx (SImode);
7092 /* Fetch the instruction where we will return to and see if it's an unimp
7093 instruction (the most significant 10 bits will be zero). If so,
7094 update the return address to skip the unimp instruction. */
7095 emit_move_insn (value,
7096 gen_rtx_MEM (SImode, plus_constant (rtnreg, 8)));
7097 emit_insn (gen_lshrsi3 (value, value, GEN_INT (22)));
7098 emit_insn (gen_update_return (rtnreg, value));
7101 /* Reload the function value registers. */
7102 emit_move_insn (valreg1, adjust_address (result, DImode, 0));
7103 emit_move_insn (valreg2,
7104 adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8));
7106 /* Put USE insns before the return. */
7110 /* Construct the return. */
7111 expand_naked_return ();
7116 ;; Adjust the return address conditionally. If the value of op1 is equal
7117 ;; to all zero then adjust the return address i.e. op0 = op0 + 4.
7118 ;; This is technically *half* the check required by the 32-bit SPARC
7119 ;; psABI. This check only ensures that an "unimp" insn was written by
7120 ;; the caller, but doesn't check to see if the expected size matches
7121 ;; (this is encoded in the 12 lower bits). This check is obsolete and
7122 ;; only used by the above code "untyped_return".
7124 (define_insn "update_return"
7125 [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
7126 (match_operand:SI 1 "register_operand" "r")] UNSPEC_UPDATE_RETURN)]
7129 if (flag_delayed_branch)
7130 return "cmp\t%1, 0\n\tbe,a\t.+8\n\t add\t%0, 4, %0";
7132 return "cmp\t%1, 0\n\tbne\t.+12\n\t nop\n\tadd\t%0, 4, %0";
7134 [(set (attr "type") (const_string "multi"))
7135 (set (attr "length")
7136 (if_then_else (eq_attr "delayed_branch" "true")
7145 (define_expand "indirect_jump"
7146 [(set (pc) (match_operand 0 "address_operand" "p"))]
7150 (define_insn "*branch_sp32"
7151 [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
7154 [(set_attr "type" "uncond_branch")])
7156 (define_insn "*branch_sp64"
7157 [(set (pc) (match_operand:DI 0 "address_operand" "p"))]
7160 [(set_attr "type" "uncond_branch")])
7162 (define_expand "nonlocal_goto"
7163 [(match_operand:SI 0 "general_operand" "")
7164 (match_operand:SI 1 "general_operand" "")
7165 (match_operand:SI 2 "general_operand" "")
7166 (match_operand:SI 3 "" "")]
7169 rtx lab = operands[1];
7170 rtx stack = operands[2];
7171 rtx fp = operands[3];
7174 /* Trap instruction to flush all the register windows. */
7175 emit_insn (gen_flush_register_windows ());
7177 /* Load the fp value for the containing fn into %fp. This is needed
7178 because STACK refers to %fp. Note that virtual register instantiation
7179 fails if the virtual %fp isn't set from a register. */
7180 if (GET_CODE (fp) != REG)
7181 fp = force_reg (Pmode, fp);
7182 emit_move_insn (virtual_stack_vars_rtx, fp);
7184 /* Find the containing function's current nonlocal goto handler,
7185 which will do any cleanups and then jump to the label. */
7186 labreg = gen_rtx_REG (Pmode, 8);
7187 emit_move_insn (labreg, lab);
7189 /* Restore %fp from stack pointer value for containing function.
7190 The restore insn that follows will move this to %sp,
7191 and reload the appropriate value into %fp. */
7192 emit_move_insn (hard_frame_pointer_rtx, stack);
7194 emit_use (stack_pointer_rtx);
7195 emit_use (static_chain_rtx);
7197 /* ??? The V9-specific version was disabled in rev 1.65. */
7198 emit_jump_insn (gen_goto_handler_and_restore (labreg));
7203 ;; Special trap insn to flush register windows.
7204 (define_insn "flush_register_windows"
7205 [(unspec_volatile [(const_int 0)] UNSPECV_FLUSHW)]
7207 { return TARGET_V9 ? "flushw" : "ta\t3"; }
7208 [(set_attr "type" "flushw")])
7210 (define_insn "goto_handler_and_restore"
7211 [(unspec_volatile [(match_operand 0 "register_operand" "=r")] UNSPECV_GOTO)]
7212 "GET_MODE (operands[0]) == Pmode"
7214 if (flag_delayed_branch)
7215 return "jmp\t%0\n\t restore";
7217 return "mov\t%0,%%g1\n\trestore\n\tjmp\t%%g1\n\t nop";
7219 [(set (attr "type") (const_string "multi"))
7220 (set (attr "length")
7221 (if_then_else (eq_attr "delayed_branch" "true")
7225 ;; For __builtin_setjmp we need to flush register windows iff the function
7226 ;; calls alloca as well, because otherwise the register window might be
7227 ;; saved after %sp adjustment and thus setjmp would crash
7228 (define_expand "builtin_setjmp_setup"
7229 [(match_operand 0 "register_operand" "r")]
7232 emit_insn (gen_do_builtin_setjmp_setup ());
7236 (define_insn "do_builtin_setjmp_setup"
7237 [(unspec_volatile [(const_int 0)] UNSPECV_SETJMP)]
7240 if (! cfun->calls_alloca)
7244 fputs ("\tflushw\n", asm_out_file);
7246 fprintf (asm_out_file, "\tst%c\t%%l7, [%%sp+%d]\n",
7247 TARGET_ARCH64 ? 'x' : 'w',
7248 SPARC_STACK_BIAS + 7 * UNITS_PER_WORD);
7249 fprintf (asm_out_file, "\tst%c\t%%fp, [%%sp+%d]\n",
7250 TARGET_ARCH64 ? 'x' : 'w',
7251 SPARC_STACK_BIAS + 14 * UNITS_PER_WORD);
7252 fprintf (asm_out_file, "\tst%c\t%%i7, [%%sp+%d]\n",
7253 TARGET_ARCH64 ? 'x' : 'w',
7254 SPARC_STACK_BIAS + 15 * UNITS_PER_WORD);
7257 [(set_attr "type" "multi")
7258 (set (attr "length")
7259 (cond [(eq_attr "calls_alloca" "false")
7261 (eq_attr "isa" "!v9")
7263 (eq_attr "pic" "true")
7264 (const_int 4)] (const_int 3)))])
7266 ;; Pattern for use after a setjmp to store FP and the return register
7267 ;; into the stack area.
7269 (define_expand "setjmp"
7275 mem = gen_rtx_MEM (Pmode,
7276 plus_constant (stack_pointer_rtx,
7277 SPARC_STACK_BIAS + 14 * UNITS_PER_WORD));
7278 emit_insn (gen_rtx_SET (VOIDmode, mem, frame_pointer_rtx));
7280 mem = gen_rtx_MEM (Pmode,
7281 plus_constant (stack_pointer_rtx,
7282 SPARC_STACK_BIAS + 15 * UNITS_PER_WORD));
7283 emit_insn (gen_rtx_SET (VOIDmode, mem, gen_rtx_REG (Pmode, 31)));
7287 ;; Special pattern for the FLUSH instruction.
7289 ; We do SImode and DImode versions of this to quiet down genrecog's complaints
7290 ; of the define_insn otherwise missing a mode. We make "flush", aka
7291 ; gen_flush, the default one since sparc_initialize_trampoline uses
7292 ; it on SImode mem values.
7294 (define_insn "flush"
7295 [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")] UNSPECV_FLUSH)]
7297 { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; }
7298 [(set_attr "type" "iflush")])
7300 (define_insn "flushdi"
7301 [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")] UNSPECV_FLUSH)]
7303 { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; }
7304 [(set_attr "type" "iflush")])
7307 ;; Find first set instructions.
7309 ;; The scan instruction searches from the most significant bit while ffs
7310 ;; searches from the least significant bit. The bit index and treatment of
7311 ;; zero also differ. It takes at least 7 instructions to get the proper
7312 ;; result. Here is an obvious 8 instruction sequence.
7315 (define_insn "ffssi2"
7316 [(set (match_operand:SI 0 "register_operand" "=&r")
7317 (ffs:SI (match_operand:SI 1 "register_operand" "r")))
7318 (clobber (match_scratch:SI 2 "=&r"))]
7319 "TARGET_SPARCLITE || TARGET_SPARCLET"
7321 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";
7323 [(set_attr "type" "multi")
7324 (set_attr "length" "8")])
7326 ;; ??? This should be a define expand, so that the extra instruction have
7327 ;; a chance of being optimized away.
7329 ;; Disabled because none of the UltraSPARCs implement popc. The HAL R1
7330 ;; does, but no one uses that and we don't have a switch for it.
7332 ;(define_insn "ffsdi2"
7333 ; [(set (match_operand:DI 0 "register_operand" "=&r")
7334 ; (ffs:DI (match_operand:DI 1 "register_operand" "r")))
7335 ; (clobber (match_scratch:DI 2 "=&r"))]
7337 ; "neg\t%1, %2\;xnor\t%1, %2, %2\;popc\t%2, %0\;movzr\t%1, 0, %0"
7338 ; [(set_attr "type" "multi")
7339 ; (set_attr "length" "4")])
7343 ;; Peepholes go at the end.
7345 ;; Optimize consecutive loads or stores into ldd and std when possible.
7346 ;; The conditions in which we do this are very restricted and are
7347 ;; explained in the code for {registers,memory}_ok_for_ldd functions.
7350 [(set (match_operand:SI 0 "memory_operand" "")
7352 (set (match_operand:SI 1 "memory_operand" "")
7355 && mems_ok_for_ldd_peep (operands[0], operands[1], NULL_RTX)"
7358 "operands[0] = widen_memory_access (operands[0], DImode, 0);")
7361 [(set (match_operand:SI 0 "memory_operand" "")
7363 (set (match_operand:SI 1 "memory_operand" "")
7366 && mems_ok_for_ldd_peep (operands[1], operands[0], NULL_RTX)"
7369 "operands[1] = widen_memory_access (operands[1], DImode, 0);")
7372 [(set (match_operand:SI 0 "register_operand" "")
7373 (match_operand:SI 1 "memory_operand" ""))
7374 (set (match_operand:SI 2 "register_operand" "")
7375 (match_operand:SI 3 "memory_operand" ""))]
7376 "registers_ok_for_ldd_peep (operands[0], operands[2])
7377 && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
7380 "operands[1] = widen_memory_access (operands[1], DImode, 0);
7381 operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));")
7384 [(set (match_operand:SI 0 "memory_operand" "")
7385 (match_operand:SI 1 "register_operand" ""))
7386 (set (match_operand:SI 2 "memory_operand" "")
7387 (match_operand:SI 3 "register_operand" ""))]
7388 "registers_ok_for_ldd_peep (operands[1], operands[3])
7389 && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
7392 "operands[0] = widen_memory_access (operands[0], DImode, 0);
7393 operands[1] = gen_rtx_REG (DImode, REGNO (operands[1]));")
7396 [(set (match_operand:SF 0 "register_operand" "")
7397 (match_operand:SF 1 "memory_operand" ""))
7398 (set (match_operand:SF 2 "register_operand" "")
7399 (match_operand:SF 3 "memory_operand" ""))]
7400 "registers_ok_for_ldd_peep (operands[0], operands[2])
7401 && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
7404 "operands[1] = widen_memory_access (operands[1], DFmode, 0);
7405 operands[0] = gen_rtx_REG (DFmode, REGNO (operands[0]));")
7408 [(set (match_operand:SF 0 "memory_operand" "")
7409 (match_operand:SF 1 "register_operand" ""))
7410 (set (match_operand:SF 2 "memory_operand" "")
7411 (match_operand:SF 3 "register_operand" ""))]
7412 "registers_ok_for_ldd_peep (operands[1], operands[3])
7413 && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
7416 "operands[0] = widen_memory_access (operands[0], DFmode, 0);
7417 operands[1] = gen_rtx_REG (DFmode, REGNO (operands[1]));")
7420 [(set (match_operand:SI 0 "register_operand" "")
7421 (match_operand:SI 1 "memory_operand" ""))
7422 (set (match_operand:SI 2 "register_operand" "")
7423 (match_operand:SI 3 "memory_operand" ""))]
7424 "registers_ok_for_ldd_peep (operands[2], operands[0])
7425 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
7428 "operands[3] = widen_memory_access (operands[3], DImode, 0);
7429 operands[2] = gen_rtx_REG (DImode, REGNO (operands[2]));")
7432 [(set (match_operand:SI 0 "memory_operand" "")
7433 (match_operand:SI 1 "register_operand" ""))
7434 (set (match_operand:SI 2 "memory_operand" "")
7435 (match_operand:SI 3 "register_operand" ""))]
7436 "registers_ok_for_ldd_peep (operands[3], operands[1])
7437 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
7440 "operands[2] = widen_memory_access (operands[2], DImode, 0);
7441 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
7445 [(set (match_operand:SF 0 "register_operand" "")
7446 (match_operand:SF 1 "memory_operand" ""))
7447 (set (match_operand:SF 2 "register_operand" "")
7448 (match_operand:SF 3 "memory_operand" ""))]
7449 "registers_ok_for_ldd_peep (operands[2], operands[0])
7450 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
7453 "operands[3] = widen_memory_access (operands[3], DFmode, 0);
7454 operands[2] = gen_rtx_REG (DFmode, REGNO (operands[2]));")
7457 [(set (match_operand:SF 0 "memory_operand" "")
7458 (match_operand:SF 1 "register_operand" ""))
7459 (set (match_operand:SF 2 "memory_operand" "")
7460 (match_operand:SF 3 "register_operand" ""))]
7461 "registers_ok_for_ldd_peep (operands[3], operands[1])
7462 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
7465 "operands[2] = widen_memory_access (operands[2], DFmode, 0);
7466 operands[3] = gen_rtx_REG (DFmode, REGNO (operands[3]));")
7468 ;; Optimize the case of following a reg-reg move with a test
7469 ;; of reg just moved. Don't allow floating point regs for operand 0 or 1.
7470 ;; This can result from a float to fix conversion.
7473 [(set (match_operand:SI 0 "register_operand" "")
7474 (match_operand:SI 1 "register_operand" ""))
7476 (compare:CC (match_operand:SI 2 "register_operand" "")
7478 "(rtx_equal_p (operands[2], operands[0])
7479 || rtx_equal_p (operands[2], operands[1]))
7480 && ! SPARC_FP_REG_P (REGNO (operands[0]))
7481 && ! SPARC_FP_REG_P (REGNO (operands[1]))"
7482 [(parallel [(set (match_dup 0) (match_dup 1))
7484 (compare:CC (match_dup 1) (const_int 0)))])]
7488 [(set (match_operand:DI 0 "register_operand" "")
7489 (match_operand:DI 1 "register_operand" ""))
7491 (compare:CCX (match_operand:DI 2 "register_operand" "")
7494 && (rtx_equal_p (operands[2], operands[0])
7495 || rtx_equal_p (operands[2], operands[1]))
7496 && ! SPARC_FP_REG_P (REGNO (operands[0]))
7497 && ! SPARC_FP_REG_P (REGNO (operands[1]))"
7498 [(parallel [(set (match_dup 0) (match_dup 1))
7500 (compare:CCX (match_dup 1) (const_int 0)))])]
7504 ;; Prefetch instructions.
7506 ;; ??? UltraSPARC-III note: A memory operation loading into the floating point register
7507 ;; ??? file, if it hits the prefetch cache, has a chance to dual-issue with other memory
7508 ;; ??? operations. With DFA we might be able to model this, but it requires a lot of
7510 (define_expand "prefetch"
7511 [(match_operand 0 "address_operand" "")
7512 (match_operand 1 "const_int_operand" "")
7513 (match_operand 2 "const_int_operand" "")]
7517 emit_insn (gen_prefetch_64 (operands[0], operands[1], operands[2]));
7519 emit_insn (gen_prefetch_32 (operands[0], operands[1], operands[2]));
7523 (define_insn "prefetch_64"
7524 [(prefetch (match_operand:DI 0 "address_operand" "p")
7525 (match_operand:DI 1 "const_int_operand" "n")
7526 (match_operand:DI 2 "const_int_operand" "n"))]
7529 static const char * const prefetch_instr[2][2] = {
7531 "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
7532 "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
7535 "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
7536 "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
7539 int read_or_write = INTVAL (operands[1]);
7540 int locality = INTVAL (operands[2]);
7542 gcc_assert (read_or_write == 0 || read_or_write == 1);
7543 gcc_assert (locality >= 0 && locality < 4);
7544 return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
7546 [(set_attr "type" "load")])
7548 (define_insn "prefetch_32"
7549 [(prefetch (match_operand:SI 0 "address_operand" "p")
7550 (match_operand:SI 1 "const_int_operand" "n")
7551 (match_operand:SI 2 "const_int_operand" "n"))]
7554 static const char * const prefetch_instr[2][2] = {
7556 "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
7557 "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
7560 "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
7561 "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
7564 int read_or_write = INTVAL (operands[1]);
7565 int locality = INTVAL (operands[2]);
7567 gcc_assert (read_or_write == 0 || read_or_write == 1);
7568 gcc_assert (locality >= 0 && locality < 4);
7569 return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
7571 [(set_attr "type" "load")])
7574 ;; Trap instructions.
7577 [(trap_if (const_int 1) (const_int 5))]
7580 [(set_attr "type" "trap")])
7582 (define_expand "conditional_trap"
7583 [(trap_if (match_operator 0 "noov_compare_operator" [(match_dup 2) (match_dup 3)])
7584 (match_operand:SI 1 "arith_operand" ""))]
7586 "operands[2] = gen_compare_reg (GET_CODE (operands[0]));
7587 if (GET_MODE (operands[2]) != CCmode && GET_MODE (operands[2]) != CCXmode)
7589 operands[3] = const0_rtx;")
7592 [(trap_if (match_operator 0 "noov_compare_operator" [(reg:CC 100) (const_int 0)])
7593 (match_operand:SI 1 "arith_operand" "rM"))]
7597 return "t%C0\t%%icc, %1";
7601 [(set_attr "type" "trap")])
7604 [(trap_if (match_operator 0 "noov_compare_operator" [(reg:CCX 100) (const_int 0)])
7605 (match_operand:SI 1 "arith_operand" "rM"))]
7608 [(set_attr "type" "trap")])
7611 ;; TLS support instructions.
7613 (define_insn "tgd_hi22"
7614 [(set (match_operand:SI 0 "register_operand" "=r")
7615 (high:SI (unspec:SI [(match_operand 1 "tgd_symbolic_operand" "")]
7618 "sethi\\t%%tgd_hi22(%a1), %0")
7620 (define_insn "tgd_lo10"
7621 [(set (match_operand:SI 0 "register_operand" "=r")
7622 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7623 (unspec:SI [(match_operand 2 "tgd_symbolic_operand" "")]
7626 "add\\t%1, %%tgd_lo10(%a2), %0")
7628 (define_insn "tgd_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 "tgd_symbolic_operand" "")]
7634 "TARGET_TLS && TARGET_ARCH32"
7635 "add\\t%1, %2, %0, %%tgd_add(%a3)")
7637 (define_insn "tgd_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:SI 2 "register_operand" "r")
7641 (match_operand 3 "tgd_symbolic_operand" "")]
7643 "TARGET_TLS && TARGET_ARCH64"
7644 "add\\t%1, %2, %0, %%tgd_add(%a3)")
7646 (define_insn "tgd_call32"
7647 [(set (match_operand 0 "register_operand" "=r")
7648 (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")
7649 (match_operand 2 "tgd_symbolic_operand" "")]
7651 (match_operand 3 "" "")))
7652 (clobber (reg:SI 15))]
7653 "TARGET_TLS && TARGET_ARCH32"
7654 "call\t%a1, %%tgd_call(%a2)%#"
7655 [(set_attr "type" "call")])
7657 (define_insn "tgd_call64"
7658 [(set (match_operand 0 "register_operand" "=r")
7659 (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")
7660 (match_operand 2 "tgd_symbolic_operand" "")]
7662 (match_operand 3 "" "")))
7663 (clobber (reg:DI 15))]
7664 "TARGET_TLS && TARGET_ARCH64"
7665 "call\t%a1, %%tgd_call(%a2)%#"
7666 [(set_attr "type" "call")])
7668 (define_insn "tldm_hi22"
7669 [(set (match_operand:SI 0 "register_operand" "=r")
7670 (high:SI (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
7672 "sethi\\t%%tldm_hi22(%&), %0")
7674 (define_insn "tldm_lo10"
7675 [(set (match_operand:SI 0 "register_operand" "=r")
7676 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7677 (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
7679 "add\\t%1, %%tldm_lo10(%&), %0")
7681 (define_insn "tldm_add32"
7682 [(set (match_operand:SI 0 "register_operand" "=r")
7683 (plus:SI (match_operand:SI 1 "register_operand" "r")
7684 (unspec:SI [(match_operand:SI 2 "register_operand" "r")]
7686 "TARGET_TLS && TARGET_ARCH32"
7687 "add\\t%1, %2, %0, %%tldm_add(%&)")
7689 (define_insn "tldm_add64"
7690 [(set (match_operand:DI 0 "register_operand" "=r")
7691 (plus:DI (match_operand:DI 1 "register_operand" "r")
7692 (unspec:DI [(match_operand:SI 2 "register_operand" "r")]
7694 "TARGET_TLS && TARGET_ARCH64"
7695 "add\\t%1, %2, %0, %%tldm_add(%&)")
7697 (define_insn "tldm_call32"
7698 [(set (match_operand 0 "register_operand" "=r")
7699 (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")]
7701 (match_operand 2 "" "")))
7702 (clobber (reg:SI 15))]
7703 "TARGET_TLS && TARGET_ARCH32"
7704 "call\t%a1, %%tldm_call(%&)%#"
7705 [(set_attr "type" "call")])
7707 (define_insn "tldm_call64"
7708 [(set (match_operand 0 "register_operand" "=r")
7709 (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")]
7711 (match_operand 2 "" "")))
7712 (clobber (reg:DI 15))]
7713 "TARGET_TLS && TARGET_ARCH64"
7714 "call\t%a1, %%tldm_call(%&)%#"
7715 [(set_attr "type" "call")])
7717 (define_insn "tldo_hix22"
7718 [(set (match_operand:SI 0 "register_operand" "=r")
7719 (high:SI (unspec:SI [(match_operand 1 "tld_symbolic_operand" "")]
7722 "sethi\\t%%tldo_hix22(%a1), %0")
7724 (define_insn "tldo_lox10"
7725 [(set (match_operand:SI 0 "register_operand" "=r")
7726 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7727 (unspec:SI [(match_operand 2 "tld_symbolic_operand" "")]
7730 "xor\\t%1, %%tldo_lox10(%a2), %0")
7732 (define_insn "tldo_add32"
7733 [(set (match_operand:SI 0 "register_operand" "=r")
7734 (plus:SI (match_operand:SI 1 "register_operand" "r")
7735 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7736 (match_operand 3 "tld_symbolic_operand" "")]
7738 "TARGET_TLS && TARGET_ARCH32"
7739 "add\\t%1, %2, %0, %%tldo_add(%a3)")
7741 (define_insn "tldo_add64"
7742 [(set (match_operand:DI 0 "register_operand" "=r")
7743 (plus:DI (match_operand:DI 1 "register_operand" "r")
7744 (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7745 (match_operand 3 "tld_symbolic_operand" "")]
7747 "TARGET_TLS && TARGET_ARCH64"
7748 "add\\t%1, %2, %0, %%tldo_add(%a3)")
7750 (define_insn "tie_hi22"
7751 [(set (match_operand:SI 0 "register_operand" "=r")
7752 (high:SI (unspec:SI [(match_operand 1 "tie_symbolic_operand" "")]
7755 "sethi\\t%%tie_hi22(%a1), %0")
7757 (define_insn "tie_lo10"
7758 [(set (match_operand:SI 0 "register_operand" "=r")
7759 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7760 (unspec:SI [(match_operand 2 "tie_symbolic_operand" "")]
7763 "add\\t%1, %%tie_lo10(%a2), %0")
7765 (define_insn "tie_ld32"
7766 [(set (match_operand:SI 0 "register_operand" "=r")
7767 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
7768 (match_operand:SI 2 "register_operand" "r")
7769 (match_operand 3 "tie_symbolic_operand" "")]
7771 "TARGET_TLS && TARGET_ARCH32"
7772 "ld\\t[%1 + %2], %0, %%tie_ld(%a3)"
7773 [(set_attr "type" "load")])
7775 (define_insn "tie_ld64"
7776 [(set (match_operand:DI 0 "register_operand" "=r")
7777 (unspec:DI [(match_operand:DI 1 "register_operand" "r")
7778 (match_operand:SI 2 "register_operand" "r")
7779 (match_operand 3 "tie_symbolic_operand" "")]
7781 "TARGET_TLS && TARGET_ARCH64"
7782 "ldx\\t[%1 + %2], %0, %%tie_ldx(%a3)"
7783 [(set_attr "type" "load")])
7785 (define_insn "tie_add32"
7786 [(set (match_operand:SI 0 "register_operand" "=r")
7787 (plus:SI (match_operand:SI 1 "register_operand" "r")
7788 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7789 (match_operand 3 "tie_symbolic_operand" "")]
7791 "TARGET_SUN_TLS && TARGET_ARCH32"
7792 "add\\t%1, %2, %0, %%tie_add(%a3)")
7794 (define_insn "tie_add64"
7795 [(set (match_operand:DI 0 "register_operand" "=r")
7796 (plus:DI (match_operand:DI 1 "register_operand" "r")
7797 (unspec:DI [(match_operand:DI 2 "register_operand" "r")
7798 (match_operand 3 "tie_symbolic_operand" "")]
7800 "TARGET_SUN_TLS && TARGET_ARCH64"
7801 "add\\t%1, %2, %0, %%tie_add(%a3)")
7803 (define_insn "tle_hix22_sp32"
7804 [(set (match_operand:SI 0 "register_operand" "=r")
7805 (high:SI (unspec:SI [(match_operand 1 "tle_symbolic_operand" "")]
7807 "TARGET_TLS && TARGET_ARCH32"
7808 "sethi\\t%%tle_hix22(%a1), %0")
7810 (define_insn "tle_lox10_sp32"
7811 [(set (match_operand:SI 0 "register_operand" "=r")
7812 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7813 (unspec:SI [(match_operand 2 "tle_symbolic_operand" "")]
7815 "TARGET_TLS && TARGET_ARCH32"
7816 "xor\\t%1, %%tle_lox10(%a2), %0")
7818 (define_insn "tle_hix22_sp64"
7819 [(set (match_operand:DI 0 "register_operand" "=r")
7820 (high:DI (unspec:DI [(match_operand 1 "tle_symbolic_operand" "")]
7822 "TARGET_TLS && TARGET_ARCH64"
7823 "sethi\\t%%tle_hix22(%a1), %0")
7825 (define_insn "tle_lox10_sp64"
7826 [(set (match_operand:DI 0 "register_operand" "=r")
7827 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
7828 (unspec:DI [(match_operand 2 "tle_symbolic_operand" "")]
7830 "TARGET_TLS && TARGET_ARCH64"
7831 "xor\\t%1, %%tle_lox10(%a2), %0")
7833 ;; Now patterns combining tldo_add{32,64} with some integer loads or stores
7834 (define_insn "*tldo_ldub_sp32"
7835 [(set (match_operand:QI 0 "register_operand" "=r")
7836 (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7837 (match_operand 3 "tld_symbolic_operand" "")]
7839 (match_operand:SI 1 "register_operand" "r"))))]
7840 "TARGET_TLS && TARGET_ARCH32"
7841 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7842 [(set_attr "type" "load")
7843 (set_attr "us3load_type" "3cycle")])
7845 (define_insn "*tldo_ldub1_sp32"
7846 [(set (match_operand:HI 0 "register_operand" "=r")
7847 (zero_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7848 (match_operand 3 "tld_symbolic_operand" "")]
7850 (match_operand:SI 1 "register_operand" "r")))))]
7851 "TARGET_TLS && TARGET_ARCH32"
7852 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7853 [(set_attr "type" "load")
7854 (set_attr "us3load_type" "3cycle")])
7856 (define_insn "*tldo_ldub2_sp32"
7857 [(set (match_operand:SI 0 "register_operand" "=r")
7858 (zero_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7859 (match_operand 3 "tld_symbolic_operand" "")]
7861 (match_operand:SI 1 "register_operand" "r")))))]
7862 "TARGET_TLS && TARGET_ARCH32"
7863 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7864 [(set_attr "type" "load")
7865 (set_attr "us3load_type" "3cycle")])
7867 (define_insn "*tldo_ldsb1_sp32"
7868 [(set (match_operand:HI 0 "register_operand" "=r")
7869 (sign_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7870 (match_operand 3 "tld_symbolic_operand" "")]
7872 (match_operand:SI 1 "register_operand" "r")))))]
7873 "TARGET_TLS && TARGET_ARCH32"
7874 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7875 [(set_attr "type" "sload")
7876 (set_attr "us3load_type" "3cycle")])
7878 (define_insn "*tldo_ldsb2_sp32"
7879 [(set (match_operand:SI 0 "register_operand" "=r")
7880 (sign_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7881 (match_operand 3 "tld_symbolic_operand" "")]
7883 (match_operand:SI 1 "register_operand" "r")))))]
7884 "TARGET_TLS && TARGET_ARCH32"
7885 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7886 [(set_attr "type" "sload")
7887 (set_attr "us3load_type" "3cycle")])
7889 (define_insn "*tldo_ldub_sp64"
7890 [(set (match_operand:QI 0 "register_operand" "=r")
7891 (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7892 (match_operand 3 "tld_symbolic_operand" "")]
7894 (match_operand:DI 1 "register_operand" "r"))))]
7895 "TARGET_TLS && TARGET_ARCH64"
7896 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7897 [(set_attr "type" "load")
7898 (set_attr "us3load_type" "3cycle")])
7900 (define_insn "*tldo_ldub1_sp64"
7901 [(set (match_operand:HI 0 "register_operand" "=r")
7902 (zero_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7903 (match_operand 3 "tld_symbolic_operand" "")]
7905 (match_operand:DI 1 "register_operand" "r")))))]
7906 "TARGET_TLS && TARGET_ARCH64"
7907 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7908 [(set_attr "type" "load")
7909 (set_attr "us3load_type" "3cycle")])
7911 (define_insn "*tldo_ldub2_sp64"
7912 [(set (match_operand:SI 0 "register_operand" "=r")
7913 (zero_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7914 (match_operand 3 "tld_symbolic_operand" "")]
7916 (match_operand:DI 1 "register_operand" "r")))))]
7917 "TARGET_TLS && TARGET_ARCH64"
7918 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7919 [(set_attr "type" "load")
7920 (set_attr "us3load_type" "3cycle")])
7922 (define_insn "*tldo_ldub3_sp64"
7923 [(set (match_operand:DI 0 "register_operand" "=r")
7924 (zero_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7925 (match_operand 3 "tld_symbolic_operand" "")]
7927 (match_operand:DI 1 "register_operand" "r")))))]
7928 "TARGET_TLS && TARGET_ARCH64"
7929 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7930 [(set_attr "type" "load")
7931 (set_attr "us3load_type" "3cycle")])
7933 (define_insn "*tldo_ldsb1_sp64"
7934 [(set (match_operand:HI 0 "register_operand" "=r")
7935 (sign_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7936 (match_operand 3 "tld_symbolic_operand" "")]
7938 (match_operand:DI 1 "register_operand" "r")))))]
7939 "TARGET_TLS && TARGET_ARCH64"
7940 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7941 [(set_attr "type" "sload")
7942 (set_attr "us3load_type" "3cycle")])
7944 (define_insn "*tldo_ldsb2_sp64"
7945 [(set (match_operand:SI 0 "register_operand" "=r")
7946 (sign_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7947 (match_operand 3 "tld_symbolic_operand" "")]
7949 (match_operand:DI 1 "register_operand" "r")))))]
7950 "TARGET_TLS && TARGET_ARCH64"
7951 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7952 [(set_attr "type" "sload")
7953 (set_attr "us3load_type" "3cycle")])
7955 (define_insn "*tldo_ldsb3_sp64"
7956 [(set (match_operand:DI 0 "register_operand" "=r")
7957 (sign_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7958 (match_operand 3 "tld_symbolic_operand" "")]
7960 (match_operand:DI 1 "register_operand" "r")))))]
7961 "TARGET_TLS && TARGET_ARCH64"
7962 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7963 [(set_attr "type" "sload")
7964 (set_attr "us3load_type" "3cycle")])
7966 (define_insn "*tldo_lduh_sp32"
7967 [(set (match_operand:HI 0 "register_operand" "=r")
7968 (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7969 (match_operand 3 "tld_symbolic_operand" "")]
7971 (match_operand:SI 1 "register_operand" "r"))))]
7972 "TARGET_TLS && TARGET_ARCH32"
7973 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7974 [(set_attr "type" "load")
7975 (set_attr "us3load_type" "3cycle")])
7977 (define_insn "*tldo_lduh1_sp32"
7978 [(set (match_operand:SI 0 "register_operand" "=r")
7979 (zero_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7980 (match_operand 3 "tld_symbolic_operand" "")]
7982 (match_operand:SI 1 "register_operand" "r")))))]
7983 "TARGET_TLS && TARGET_ARCH32"
7984 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7985 [(set_attr "type" "load")
7986 (set_attr "us3load_type" "3cycle")])
7988 (define_insn "*tldo_ldsh1_sp32"
7989 [(set (match_operand:SI 0 "register_operand" "=r")
7990 (sign_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7991 (match_operand 3 "tld_symbolic_operand" "")]
7993 (match_operand:SI 1 "register_operand" "r")))))]
7994 "TARGET_TLS && TARGET_ARCH32"
7995 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
7996 [(set_attr "type" "sload")
7997 (set_attr "us3load_type" "3cycle")])
7999 (define_insn "*tldo_lduh_sp64"
8000 [(set (match_operand:HI 0 "register_operand" "=r")
8001 (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8002 (match_operand 3 "tld_symbolic_operand" "")]
8004 (match_operand:DI 1 "register_operand" "r"))))]
8005 "TARGET_TLS && TARGET_ARCH64"
8006 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
8007 [(set_attr "type" "load")
8008 (set_attr "us3load_type" "3cycle")])
8010 (define_insn "*tldo_lduh1_sp64"
8011 [(set (match_operand:SI 0 "register_operand" "=r")
8012 (zero_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8013 (match_operand 3 "tld_symbolic_operand" "")]
8015 (match_operand:DI 1 "register_operand" "r")))))]
8016 "TARGET_TLS && TARGET_ARCH64"
8017 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
8018 [(set_attr "type" "load")
8019 (set_attr "us3load_type" "3cycle")])
8021 (define_insn "*tldo_lduh2_sp64"
8022 [(set (match_operand:DI 0 "register_operand" "=r")
8023 (zero_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8024 (match_operand 3 "tld_symbolic_operand" "")]
8026 (match_operand:DI 1 "register_operand" "r")))))]
8027 "TARGET_TLS && TARGET_ARCH64"
8028 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
8029 [(set_attr "type" "load")
8030 (set_attr "us3load_type" "3cycle")])
8032 (define_insn "*tldo_ldsh1_sp64"
8033 [(set (match_operand:SI 0 "register_operand" "=r")
8034 (sign_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8035 (match_operand 3 "tld_symbolic_operand" "")]
8037 (match_operand:DI 1 "register_operand" "r")))))]
8038 "TARGET_TLS && TARGET_ARCH64"
8039 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
8040 [(set_attr "type" "sload")
8041 (set_attr "us3load_type" "3cycle")])
8043 (define_insn "*tldo_ldsh2_sp64"
8044 [(set (match_operand:DI 0 "register_operand" "=r")
8045 (sign_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8046 (match_operand 3 "tld_symbolic_operand" "")]
8048 (match_operand:DI 1 "register_operand" "r")))))]
8049 "TARGET_TLS && TARGET_ARCH64"
8050 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
8051 [(set_attr "type" "sload")
8052 (set_attr "us3load_type" "3cycle")])
8054 (define_insn "*tldo_lduw_sp32"
8055 [(set (match_operand:SI 0 "register_operand" "=r")
8056 (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8057 (match_operand 3 "tld_symbolic_operand" "")]
8059 (match_operand:SI 1 "register_operand" "r"))))]
8060 "TARGET_TLS && TARGET_ARCH32"
8061 "ld\t[%1 + %2], %0, %%tldo_add(%3)"
8062 [(set_attr "type" "load")])
8064 (define_insn "*tldo_lduw_sp64"
8065 [(set (match_operand:SI 0 "register_operand" "=r")
8066 (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8067 (match_operand 3 "tld_symbolic_operand" "")]
8069 (match_operand:DI 1 "register_operand" "r"))))]
8070 "TARGET_TLS && TARGET_ARCH64"
8071 "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
8072 [(set_attr "type" "load")])
8074 (define_insn "*tldo_lduw1_sp64"
8075 [(set (match_operand:DI 0 "register_operand" "=r")
8076 (zero_extend:DI (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8077 (match_operand 3 "tld_symbolic_operand" "")]
8079 (match_operand:DI 1 "register_operand" "r")))))]
8080 "TARGET_TLS && TARGET_ARCH64"
8081 "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
8082 [(set_attr "type" "load")])
8084 (define_insn "*tldo_ldsw1_sp64"
8085 [(set (match_operand:DI 0 "register_operand" "=r")
8086 (sign_extend:DI (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8087 (match_operand 3 "tld_symbolic_operand" "")]
8089 (match_operand:DI 1 "register_operand" "r")))))]
8090 "TARGET_TLS && TARGET_ARCH64"
8091 "ldsw\t[%1 + %2], %0, %%tldo_add(%3)"
8092 [(set_attr "type" "sload")
8093 (set_attr "us3load_type" "3cycle")])
8095 (define_insn "*tldo_ldx_sp64"
8096 [(set (match_operand:DI 0 "register_operand" "=r")
8097 (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8098 (match_operand 3 "tld_symbolic_operand" "")]
8100 (match_operand:DI 1 "register_operand" "r"))))]
8101 "TARGET_TLS && TARGET_ARCH64"
8102 "ldx\t[%1 + %2], %0, %%tldo_add(%3)"
8103 [(set_attr "type" "load")])
8105 (define_insn "*tldo_stb_sp32"
8106 [(set (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8107 (match_operand 3 "tld_symbolic_operand" "")]
8109 (match_operand:SI 1 "register_operand" "r")))
8110 (match_operand:QI 0 "register_operand" "=r"))]
8111 "TARGET_TLS && TARGET_ARCH32"
8112 "stb\t%0, [%1 + %2], %%tldo_add(%3)"
8113 [(set_attr "type" "store")])
8115 (define_insn "*tldo_stb_sp64"
8116 [(set (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8117 (match_operand 3 "tld_symbolic_operand" "")]
8119 (match_operand:DI 1 "register_operand" "r")))
8120 (match_operand:QI 0 "register_operand" "=r"))]
8121 "TARGET_TLS && TARGET_ARCH64"
8122 "stb\t%0, [%1 + %2], %%tldo_add(%3)"
8123 [(set_attr "type" "store")])
8125 (define_insn "*tldo_sth_sp32"
8126 [(set (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8127 (match_operand 3 "tld_symbolic_operand" "")]
8129 (match_operand:SI 1 "register_operand" "r")))
8130 (match_operand:HI 0 "register_operand" "=r"))]
8131 "TARGET_TLS && TARGET_ARCH32"
8132 "sth\t%0, [%1 + %2], %%tldo_add(%3)"
8133 [(set_attr "type" "store")])
8135 (define_insn "*tldo_sth_sp64"
8136 [(set (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8137 (match_operand 3 "tld_symbolic_operand" "")]
8139 (match_operand:DI 1 "register_operand" "r")))
8140 (match_operand:HI 0 "register_operand" "=r"))]
8141 "TARGET_TLS && TARGET_ARCH64"
8142 "sth\t%0, [%1 + %2], %%tldo_add(%3)"
8143 [(set_attr "type" "store")])
8145 (define_insn "*tldo_stw_sp32"
8146 [(set (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8147 (match_operand 3 "tld_symbolic_operand" "")]
8149 (match_operand:SI 1 "register_operand" "r")))
8150 (match_operand:SI 0 "register_operand" "=r"))]
8151 "TARGET_TLS && TARGET_ARCH32"
8152 "st\t%0, [%1 + %2], %%tldo_add(%3)"
8153 [(set_attr "type" "store")])
8155 (define_insn "*tldo_stw_sp64"
8156 [(set (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8157 (match_operand 3 "tld_symbolic_operand" "")]
8159 (match_operand:DI 1 "register_operand" "r")))
8160 (match_operand:SI 0 "register_operand" "=r"))]
8161 "TARGET_TLS && TARGET_ARCH64"
8162 "stw\t%0, [%1 + %2], %%tldo_add(%3)"
8163 [(set_attr "type" "store")])
8165 (define_insn "*tldo_stx_sp64"
8166 [(set (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8167 (match_operand 3 "tld_symbolic_operand" "")]
8169 (match_operand:DI 1 "register_operand" "r")))
8170 (match_operand:DI 0 "register_operand" "=r"))]
8171 "TARGET_TLS && TARGET_ARCH64"
8172 "stx\t%0, [%1 + %2], %%tldo_add(%3)"
8173 [(set_attr "type" "store")])
8176 ;; Stack protector instructions.
8178 (define_expand "stack_protect_set"
8179 [(match_operand 0 "memory_operand" "")
8180 (match_operand 1 "memory_operand" "")]
8183 #ifdef TARGET_THREAD_SSP_OFFSET
8184 rtx tlsreg = gen_rtx_REG (Pmode, 7);
8185 rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
8186 operands[1] = gen_rtx_MEM (Pmode, addr);
8189 emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
8191 emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
8195 (define_insn "stack_protect_setsi"
8196 [(set (match_operand:SI 0 "memory_operand" "=m")
8197 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
8198 (set (match_scratch:SI 2 "=&r") (const_int 0))]
8200 "ld\t%1, %2\;st\t%2, %0\;mov\t0, %2"
8201 [(set_attr "type" "multi")
8202 (set_attr "length" "3")])
8204 (define_insn "stack_protect_setdi"
8205 [(set (match_operand:DI 0 "memory_operand" "=m")
8206 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
8207 (set (match_scratch:DI 2 "=&r") (const_int 0))]
8209 "ldx\t%1, %2\;stx\t%2, %0\;mov\t0, %2"
8210 [(set_attr "type" "multi")
8211 (set_attr "length" "3")])
8213 (define_expand "stack_protect_test"
8214 [(match_operand 0 "memory_operand" "")
8215 (match_operand 1 "memory_operand" "")
8216 (match_operand 2 "" "")]
8219 #ifdef TARGET_THREAD_SSP_OFFSET
8220 rtx tlsreg = gen_rtx_REG (Pmode, 7);
8221 rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
8222 operands[1] = gen_rtx_MEM (Pmode, addr);
8226 rtx temp = gen_reg_rtx (Pmode);
8227 emit_insn (gen_stack_protect_testdi (temp, operands[0], operands[1]));
8228 sparc_compare_op0 = temp;
8229 sparc_compare_op1 = const0_rtx;
8233 emit_insn (gen_stack_protect_testsi (operands[0], operands[1]));
8234 sparc_compare_op0 = operands[0];
8235 sparc_compare_op1 = operands[1];
8236 sparc_compare_emitted = gen_rtx_REG (CCmode, SPARC_ICC_REG);
8238 emit_jump_insn (gen_beq (operands[2]));
8242 (define_insn "stack_protect_testsi"
8244 (unspec:CC [(match_operand:SI 0 "memory_operand" "m")
8245 (match_operand:SI 1 "memory_operand" "m")]
8247 (set (match_scratch:SI 3 "=r") (const_int 0))
8248 (clobber (match_scratch:SI 2 "=&r"))]
8250 "ld\t%0, %2\;ld\t%1, %3\;xorcc\t%2, %3, %2\;mov\t0, %3"
8251 [(set_attr "type" "multi")
8252 (set_attr "length" "4")])
8254 (define_insn "stack_protect_testdi"
8255 [(set (match_operand:DI 0 "register_operand" "=&r")
8256 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
8257 (match_operand:DI 2 "memory_operand" "m")]
8259 (set (match_scratch:DI 3 "=r") (const_int 0))]
8261 "ldx\t%1, %0\;ldx\t%2, %3\;xor\t%0, %3, %0\;mov\t0, %3"
8262 [(set_attr "type" "multi")
8263 (set_attr "length" "4")])
8266 ;; Vector instructions.
8268 (define_insn "addv2si3"
8269 [(set (match_operand:V2SI 0 "register_operand" "=e")
8270 (plus:V2SI (match_operand:V2SI 1 "register_operand" "e")
8271 (match_operand:V2SI 2 "register_operand" "e")))]
8273 "fpadd32\t%1, %2, %0"
8274 [(set_attr "type" "fga")
8275 (set_attr "fptype" "double")])
8277 (define_insn "addv4hi3"
8278 [(set (match_operand:V4HI 0 "register_operand" "=e")
8279 (plus:V4HI (match_operand:V4HI 1 "register_operand" "e")
8280 (match_operand:V4HI 2 "register_operand" "e")))]
8282 "fpadd16\t%1, %2, %0"
8283 [(set_attr "type" "fga")
8284 (set_attr "fptype" "double")])
8286 ;; fpadd32s is emitted by the addsi3 pattern.
8288 (define_insn "addv2hi3"
8289 [(set (match_operand:V2HI 0 "register_operand" "=f")
8290 (plus:V2HI (match_operand:V2HI 1 "register_operand" "f")
8291 (match_operand:V2HI 2 "register_operand" "f")))]
8293 "fpadd16s\t%1, %2, %0"
8294 [(set_attr "type" "fga")
8295 (set_attr "fptype" "single")])
8297 (define_insn "subv2si3"
8298 [(set (match_operand:V2SI 0 "register_operand" "=e")
8299 (minus:V2SI (match_operand:V2SI 1 "register_operand" "e")
8300 (match_operand:V2SI 2 "register_operand" "e")))]
8302 "fpsub32\t%1, %2, %0"
8303 [(set_attr "type" "fga")
8304 (set_attr "fptype" "double")])
8306 (define_insn "subv4hi3"
8307 [(set (match_operand:V4HI 0 "register_operand" "=e")
8308 (minus:V4HI (match_operand:V4HI 1 "register_operand" "e")
8309 (match_operand:V4HI 2 "register_operand" "e")))]
8311 "fpsub16\t%1, %2, %0"
8312 [(set_attr "type" "fga")
8313 (set_attr "fptype" "double")])
8315 ;; fpsub32s is emitted by the subsi3 pattern.
8317 (define_insn "subv2hi3"
8318 [(set (match_operand:V2HI 0 "register_operand" "=f")
8319 (minus:V2HI (match_operand:V2HI 1 "register_operand" "f")
8320 (match_operand:V2HI 2 "register_operand" "f")))]
8322 "fpsub16s\t%1, %2, %0"
8323 [(set_attr "type" "fga")
8324 (set_attr "fptype" "single")])
8326 ;; All other logical instructions have integer equivalents so they
8327 ;; are defined together.
8329 ;; (ior (not (op1)) (not (op2))) is the canonical form of NAND.
8331 (define_insn "*nand<V64mode>_vis"
8332 [(set (match_operand:V64 0 "register_operand" "=e")
8333 (ior:V64 (not:V64 (match_operand:V64 1 "register_operand" "e"))
8334 (not:V64 (match_operand:V64 2 "register_operand" "e"))))]
8337 [(set_attr "type" "fga")
8338 (set_attr "fptype" "double")])
8340 (define_insn "*nand<V32mode>_vis"
8341 [(set (match_operand:V32 0 "register_operand" "=f")
8342 (ior:V32 (not:V32 (match_operand:V32 1 "register_operand" "f"))
8343 (not:V32 (match_operand:V32 2 "register_operand" "f"))))]
8345 "fnands\t%1, %2, %0"
8346 [(set_attr "type" "fga")
8347 (set_attr "fptype" "single")])
8349 ;; Hard to generate VIS instructions. We have builtins for these.
8351 (define_insn "fpack16_vis"
8352 [(set (match_operand:V4QI 0 "register_operand" "=f")
8353 (unspec:V4QI [(match_operand:V4HI 1 "register_operand" "e")]
8357 [(set_attr "type" "fga")
8358 (set_attr "fptype" "double")])
8360 (define_insn "fpackfix_vis"
8361 [(set (match_operand:V2HI 0 "register_operand" "=f")
8362 (unspec:V2HI [(match_operand:V2SI 1 "register_operand" "e")]
8366 [(set_attr "type" "fga")
8367 (set_attr "fptype" "double")])
8369 (define_insn "fpack32_vis"
8370 [(set (match_operand:V8QI 0 "register_operand" "=e")
8371 (unspec:V8QI [(match_operand:V2SI 1 "register_operand" "e")
8372 (match_operand:V8QI 2 "register_operand" "e")]
8375 "fpack32\t%1, %2, %0"
8376 [(set_attr "type" "fga")
8377 (set_attr "fptype" "double")])
8379 (define_insn "fexpand_vis"
8380 [(set (match_operand:V4HI 0 "register_operand" "=e")
8381 (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")]
8385 [(set_attr "type" "fga")
8386 (set_attr "fptype" "double")])
8388 ;; It may be possible to describe this operation as (1 indexed):
8389 ;; (vec_select (vec_duplicate (vec_duplicate (vec_concat 1 2)))
8390 ;; 1,5,10,14,19,23,28,32)
8391 ;; Note that (vec_merge:V8QI [(V4QI) (V4QI)] (10101010 = 170) doesn't work
8392 ;; because vec_merge expects all the operands to be of the same type.
8393 (define_insn "fpmerge_vis"
8394 [(set (match_operand:V8QI 0 "register_operand" "=e")
8395 (unspec:V8QI [(match_operand:V4QI 1 "register_operand" "f")
8396 (match_operand:V4QI 2 "register_operand" "f")]
8399 "fpmerge\t%1, %2, %0"
8400 [(set_attr "type" "fga")
8401 (set_attr "fptype" "double")])
8403 ;; Partitioned multiply instructions
8404 (define_insn "fmul8x16_vis"
8405 [(set (match_operand:V4HI 0 "register_operand" "=e")
8406 (mult:V4HI (match_operand:V4QI 1 "register_operand" "f")
8407 (match_operand:V4HI 2 "register_operand" "e")))]
8409 "fmul8x16\t%1, %2, %0"
8410 [(set_attr "type" "fpmul")
8411 (set_attr "fptype" "double")])
8413 ;; Only one of the following two insns can be a multiply.
8414 (define_insn "fmul8x16au_vis"
8415 [(set (match_operand:V4HI 0 "register_operand" "=e")
8416 (mult:V4HI (match_operand:V4QI 1 "register_operand" "f")
8417 (match_operand:V2HI 2 "register_operand" "f")))]
8419 "fmul8x16au\t%1, %2, %0"
8420 [(set_attr "type" "fpmul")
8421 (set_attr "fptype" "double")])
8423 (define_insn "fmul8x16al_vis"
8424 [(set (match_operand:V4HI 0 "register_operand" "=e")
8425 (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")
8426 (match_operand:V2HI 2 "register_operand" "f")]
8429 "fmul8x16al\t%1, %2, %0"
8430 [(set_attr "type" "fpmul")
8431 (set_attr "fptype" "double")])
8433 ;; Only one of the following two insns can be a multiply.
8434 (define_insn "fmul8sux16_vis"
8435 [(set (match_operand:V4HI 0 "register_operand" "=e")
8436 (mult:V4HI (match_operand:V8QI 1 "register_operand" "e")
8437 (match_operand:V4HI 2 "register_operand" "e")))]
8439 "fmul8sux16\t%1, %2, %0"
8440 [(set_attr "type" "fpmul")
8441 (set_attr "fptype" "double")])
8443 (define_insn "fmul8ulx16_vis"
8444 [(set (match_operand:V4HI 0 "register_operand" "=e")
8445 (unspec:V4HI [(match_operand:V8QI 1 "register_operand" "e")
8446 (match_operand:V4HI 2 "register_operand" "e")]
8449 "fmul8ulx16\t%1, %2, %0"
8450 [(set_attr "type" "fpmul")
8451 (set_attr "fptype" "double")])
8453 ;; Only one of the following two insns can be a multiply.
8454 (define_insn "fmuld8sux16_vis"
8455 [(set (match_operand:V2SI 0 "register_operand" "=e")
8456 (mult:V2SI (match_operand:V4QI 1 "register_operand" "f")
8457 (match_operand:V2HI 2 "register_operand" "f")))]
8459 "fmuld8sux16\t%1, %2, %0"
8460 [(set_attr "type" "fpmul")
8461 (set_attr "fptype" "double")])
8463 (define_insn "fmuld8ulx16_vis"
8464 [(set (match_operand:V2SI 0 "register_operand" "=e")
8465 (unspec:V2SI [(match_operand:V4QI 1 "register_operand" "f")
8466 (match_operand:V2HI 2 "register_operand" "f")]
8469 "fmuld8ulx16\t%1, %2, %0"
8470 [(set_attr "type" "fpmul")
8471 (set_attr "fptype" "double")])
8473 ;; Using faligndata only makes sense after an alignaddr since the choice of
8474 ;; bytes to take out of each operand is dependent on the results of the last
8476 (define_insn "faligndata<V64I:mode>_vis"
8477 [(set (match_operand:V64I 0 "register_operand" "=e")
8478 (unspec:V64I [(match_operand:V64I 1 "register_operand" "e")
8479 (match_operand:V64I 2 "register_operand" "e")]
8482 "faligndata\t%1, %2, %0"
8483 [(set_attr "type" "fga")
8484 (set_attr "fptype" "double")])
8486 (define_insn "alignaddr<P:mode>_vis"
8487 [(set (match_operand:P 0 "register_operand" "=r")
8488 (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
8489 (match_operand:P 2 "register_or_zero_operand" "rJ")]
8492 "alignaddr\t%r1, %r2, %0")
8494 (define_insn "pdist_vis"
8495 [(set (match_operand:DI 0 "register_operand" "=e")
8496 (unspec:DI [(match_operand:V8QI 1 "register_operand" "e")
8497 (match_operand:V8QI 2 "register_operand" "e")
8498 (match_operand:DI 3 "register_operand" "0")]
8502 [(set_attr "type" "fga")
8503 (set_attr "fptype" "double")])