1 ;; Machine description for SPARC chip for GCC
2 ;; Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
3 ;; 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
4 ;; Contributed by Michael Tiemann (tiemann@cygnus.com)
5 ;; 64-bit SPARC-V9 support by Michael Tiemann, Jim Wilson, and Doug Evans,
8 ;; This file is part of GCC.
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 2, or (at your option)
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 ;; GNU General Public License for more details.
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING. If not, write to
22 ;; the Free Software Foundation, 51 Franklin Street, Fifth Floor,
23 ;; Boston, MA 02110-1301, USA.
25 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
29 (UNSPEC_UPDATE_RETURN 1)
30 (UNSPEC_LOAD_PCREL_SYM 2)
31 (UNSPEC_MOVE_PIC_LABEL 5)
37 (UNSPEC_EMB_TEXTUHI 13)
38 (UNSPEC_EMB_TEXTHI 14)
39 (UNSPEC_EMB_TEXTULO 15)
47 (UNSPEC_TLSLD_BASE 35)
74 ;; The upper 32 fp regs on the v9 can't hold SFmode values. To deal with this
75 ;; a second register class, EXTRA_FP_REGS, exists for the v9 chip. The name
76 ;; is a bit of a misnomer as it covers all 64 fp regs. The corresponding
77 ;; constraint letter is 'e'. To avoid any confusion, 'e' is used instead of
78 ;; 'f' for all DF/TFmode values, including those that are specific to the v8.
81 ;; Attribute for cpu type.
82 ;; These must match the values for enum processor_type in sparc.h.
89 hypersparc,sparclite86x,
94 (const (symbol_ref "sparc_cpu_attr")))
96 ;; Attribute for the instruction set.
97 ;; At present we only need to distinguish v9/!v9, but for clarity we
98 ;; test TARGET_V8 too.
99 (define_attr "isa" "v7,v8,v9,sparclet"
101 (cond [(symbol_ref "TARGET_V9") (const_string "v9")
102 (symbol_ref "TARGET_V8") (const_string "v8")
103 (symbol_ref "TARGET_SPARCLET") (const_string "sparclet")]
104 (const_string "v7"))))
110 uncond_branch,branch,call,sibcall,call_no_delay_slot,return,
118 fga,fgm_pack,fgm_mul,fgm_pdist,fgm_cmp,
121 multi,savew,flushw,iflush,trap"
122 (const_string "ialu"))
124 ;; True if branch/call has empty delay slot and will emit a nop in it
125 (define_attr "empty_delay_slot" "false,true"
126 (symbol_ref "empty_delay_slot (insn)"))
128 (define_attr "branch_type" "none,icc,fcc,reg"
129 (const_string "none"))
131 (define_attr "pic" "false,true"
132 (symbol_ref "flag_pic != 0"))
134 (define_attr "calls_alloca" "false,true"
135 (symbol_ref "current_function_calls_alloca != 0"))
137 (define_attr "calls_eh_return" "false,true"
138 (symbol_ref "current_function_calls_eh_return !=0 "))
140 (define_attr "leaf_function" "false,true"
141 (symbol_ref "current_function_uses_only_leaf_regs != 0"))
143 (define_attr "delayed_branch" "false,true"
144 (symbol_ref "flag_delayed_branch != 0"))
146 ;; Length (in # of insns).
147 ;; Beware that setting a length greater or equal to 3 for conditional branches
148 ;; has a side-effect (see output_cbranch and output_v9branch).
149 (define_attr "length" ""
150 (cond [(eq_attr "type" "uncond_branch,call")
151 (if_then_else (eq_attr "empty_delay_slot" "true")
154 (eq_attr "type" "sibcall")
155 (if_then_else (eq_attr "leaf_function" "true")
156 (if_then_else (eq_attr "empty_delay_slot" "true")
159 (if_then_else (eq_attr "empty_delay_slot" "true")
162 (eq_attr "branch_type" "icc")
163 (if_then_else (match_operand 0 "noov_compare64_operator" "")
164 (if_then_else (lt (pc) (match_dup 1))
165 (if_then_else (lt (minus (match_dup 1) (pc)) (const_int 260000))
166 (if_then_else (eq_attr "empty_delay_slot" "true")
169 (if_then_else (eq_attr "empty_delay_slot" "true")
172 (if_then_else (lt (minus (pc) (match_dup 1)) (const_int 260000))
173 (if_then_else (eq_attr "empty_delay_slot" "true")
176 (if_then_else (eq_attr "empty_delay_slot" "true")
179 (if_then_else (eq_attr "empty_delay_slot" "true")
182 (eq_attr "branch_type" "fcc")
183 (if_then_else (match_operand 0 "fcc0_register_operand" "")
184 (if_then_else (eq_attr "empty_delay_slot" "true")
185 (if_then_else (eq (symbol_ref "TARGET_V9") (const_int 0))
188 (if_then_else (eq (symbol_ref "TARGET_V9") (const_int 0))
191 (if_then_else (lt (pc) (match_dup 2))
192 (if_then_else (lt (minus (match_dup 2) (pc)) (const_int 260000))
193 (if_then_else (eq_attr "empty_delay_slot" "true")
196 (if_then_else (eq_attr "empty_delay_slot" "true")
199 (if_then_else (lt (minus (pc) (match_dup 2)) (const_int 260000))
200 (if_then_else (eq_attr "empty_delay_slot" "true")
203 (if_then_else (eq_attr "empty_delay_slot" "true")
206 (eq_attr "branch_type" "reg")
207 (if_then_else (lt (pc) (match_dup 2))
208 (if_then_else (lt (minus (match_dup 2) (pc)) (const_int 32000))
209 (if_then_else (eq_attr "empty_delay_slot" "true")
212 (if_then_else (eq_attr "empty_delay_slot" "true")
215 (if_then_else (lt (minus (pc) (match_dup 2)) (const_int 32000))
216 (if_then_else (eq_attr "empty_delay_slot" "true")
219 (if_then_else (eq_attr "empty_delay_slot" "true")
225 (define_attr "fptype" "single,double"
226 (const_string "single"))
228 ;; UltraSPARC-III integer load type.
229 (define_attr "us3load_type" "2cycle,3cycle"
230 (const_string "2cycle"))
232 (define_asm_attributes
233 [(set_attr "length" "2")
234 (set_attr "type" "multi")])
236 ;; Attributes for instruction and branch scheduling
237 (define_attr "tls_call_delay" "false,true"
238 (symbol_ref "tls_call_delay (insn)"))
240 (define_attr "in_call_delay" "false,true"
241 (cond [(eq_attr "type" "uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
242 (const_string "false")
243 (eq_attr "type" "load,fpload,store,fpstore")
244 (if_then_else (eq_attr "length" "1")
245 (const_string "true")
246 (const_string "false"))]
247 (if_then_else (and (eq_attr "length" "1")
248 (eq_attr "tls_call_delay" "true"))
249 (const_string "true")
250 (const_string "false"))))
252 (define_attr "eligible_for_sibcall_delay" "false,true"
253 (symbol_ref "eligible_for_sibcall_delay (insn)"))
255 (define_attr "eligible_for_return_delay" "false,true"
256 (symbol_ref "eligible_for_return_delay (insn)"))
258 ;; ??? !v9: Should implement the notion of predelay slots for floating-point
259 ;; branches. This would allow us to remove the nop always inserted before
260 ;; a floating point branch.
262 ;; ??? It is OK for fill_simple_delay_slots to put load/store instructions
263 ;; in a delay slot, but it is not OK for fill_eager_delay_slots to do so.
264 ;; This is because doing so will add several pipeline stalls to the path
265 ;; that the load/store did not come from. Unfortunately, there is no way
266 ;; to prevent fill_eager_delay_slots from using load/store without completely
267 ;; disabling them. For the SPEC benchmark set, this is a serious lose,
268 ;; because it prevents us from moving back the final store of inner loops.
270 (define_attr "in_branch_delay" "false,true"
271 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
272 (eq_attr "length" "1"))
273 (const_string "true")
274 (const_string "false")))
276 (define_attr "in_uncond_branch_delay" "false,true"
277 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
278 (eq_attr "length" "1"))
279 (const_string "true")
280 (const_string "false")))
282 (define_attr "in_annul_branch_delay" "false,true"
283 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
284 (eq_attr "length" "1"))
285 (const_string "true")
286 (const_string "false")))
288 (define_delay (eq_attr "type" "call")
289 [(eq_attr "in_call_delay" "true") (nil) (nil)])
291 (define_delay (eq_attr "type" "sibcall")
292 [(eq_attr "eligible_for_sibcall_delay" "true") (nil) (nil)])
294 (define_delay (eq_attr "type" "branch")
295 [(eq_attr "in_branch_delay" "true")
296 (nil) (eq_attr "in_annul_branch_delay" "true")])
298 (define_delay (eq_attr "type" "uncond_branch")
299 [(eq_attr "in_uncond_branch_delay" "true")
302 (define_delay (eq_attr "type" "return")
303 [(eq_attr "eligible_for_return_delay" "true") (nil) (nil)])
306 ;; Include SPARC DFA schedulers
308 (include "cypress.md")
309 (include "supersparc.md")
310 (include "hypersparc.md")
311 (include "sparclet.md")
312 (include "ultra1_2.md")
313 (include "ultra3.md")
316 ;; Operand and operator predicates.
318 (include "predicates.md")
321 ;; Compare instructions.
323 ;; We generate RTL for comparisons and branches by having the cmpxx
324 ;; patterns store away the operands. Then, the scc and bcc patterns
325 ;; emit RTL for both the compare and the branch.
327 ;; We do this because we want to generate different code for an sne and
328 ;; seq insn. In those cases, if the second operand of the compare is not
329 ;; const0_rtx, we want to compute the xor of the two operands and test
332 ;; We start with the DEFINE_EXPANDs, then the DEFINE_INSNs to match
333 ;; the patterns. Finally, we have the DEFINE_SPLITs for some of the scc
334 ;; insns that actually require more than one machine instruction.
336 (define_expand "cmpsi"
338 (compare:CC (match_operand:SI 0 "compare_operand" "")
339 (match_operand:SI 1 "arith_operand" "")))]
342 if (GET_CODE (operands[0]) == ZERO_EXTRACT && operands[1] != const0_rtx)
343 operands[0] = force_reg (SImode, operands[0]);
345 sparc_compare_op0 = operands[0];
346 sparc_compare_op1 = operands[1];
350 (define_expand "cmpdi"
352 (compare:CCX (match_operand:DI 0 "compare_operand" "")
353 (match_operand:DI 1 "arith_operand" "")))]
356 if (GET_CODE (operands[0]) == ZERO_EXTRACT && operands[1] != const0_rtx)
357 operands[0] = force_reg (DImode, operands[0]);
359 sparc_compare_op0 = operands[0];
360 sparc_compare_op1 = operands[1];
364 (define_expand "cmpsf"
365 ;; The 96 here isn't ever used by anyone.
367 (compare:CCFP (match_operand:SF 0 "register_operand" "")
368 (match_operand:SF 1 "register_operand" "")))]
371 sparc_compare_op0 = operands[0];
372 sparc_compare_op1 = operands[1];
376 (define_expand "cmpdf"
377 ;; The 96 here isn't ever used by anyone.
379 (compare:CCFP (match_operand:DF 0 "register_operand" "")
380 (match_operand:DF 1 "register_operand" "")))]
383 sparc_compare_op0 = operands[0];
384 sparc_compare_op1 = operands[1];
388 (define_expand "cmptf"
389 ;; The 96 here isn't ever used by anyone.
391 (compare:CCFP (match_operand:TF 0 "register_operand" "")
392 (match_operand:TF 1 "register_operand" "")))]
395 sparc_compare_op0 = operands[0];
396 sparc_compare_op1 = operands[1];
400 ;; Now the compare DEFINE_INSNs.
402 (define_insn "*cmpsi_insn"
404 (compare:CC (match_operand:SI 0 "register_operand" "r")
405 (match_operand:SI 1 "arith_operand" "rI")))]
408 [(set_attr "type" "compare")])
410 (define_insn "*cmpdi_sp64"
412 (compare:CCX (match_operand:DI 0 "register_operand" "r")
413 (match_operand:DI 1 "arith_operand" "rI")))]
416 [(set_attr "type" "compare")])
418 (define_insn "*cmpsf_fpe"
419 [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
420 (compare:CCFPE (match_operand:SF 1 "register_operand" "f")
421 (match_operand:SF 2 "register_operand" "f")))]
425 return "fcmpes\t%0, %1, %2";
426 return "fcmpes\t%1, %2";
428 [(set_attr "type" "fpcmp")])
430 (define_insn "*cmpdf_fpe"
431 [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
432 (compare:CCFPE (match_operand:DF 1 "register_operand" "e")
433 (match_operand:DF 2 "register_operand" "e")))]
437 return "fcmped\t%0, %1, %2";
438 return "fcmped\t%1, %2";
440 [(set_attr "type" "fpcmp")
441 (set_attr "fptype" "double")])
443 (define_insn "*cmptf_fpe"
444 [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
445 (compare:CCFPE (match_operand:TF 1 "register_operand" "e")
446 (match_operand:TF 2 "register_operand" "e")))]
447 "TARGET_FPU && TARGET_HARD_QUAD"
450 return "fcmpeq\t%0, %1, %2";
451 return "fcmpeq\t%1, %2";
453 [(set_attr "type" "fpcmp")])
455 (define_insn "*cmpsf_fp"
456 [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
457 (compare:CCFP (match_operand:SF 1 "register_operand" "f")
458 (match_operand:SF 2 "register_operand" "f")))]
462 return "fcmps\t%0, %1, %2";
463 return "fcmps\t%1, %2";
465 [(set_attr "type" "fpcmp")])
467 (define_insn "*cmpdf_fp"
468 [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
469 (compare:CCFP (match_operand:DF 1 "register_operand" "e")
470 (match_operand:DF 2 "register_operand" "e")))]
474 return "fcmpd\t%0, %1, %2";
475 return "fcmpd\t%1, %2";
477 [(set_attr "type" "fpcmp")
478 (set_attr "fptype" "double")])
480 (define_insn "*cmptf_fp"
481 [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
482 (compare:CCFP (match_operand:TF 1 "register_operand" "e")
483 (match_operand:TF 2 "register_operand" "e")))]
484 "TARGET_FPU && TARGET_HARD_QUAD"
487 return "fcmpq\t%0, %1, %2";
488 return "fcmpq\t%1, %2";
490 [(set_attr "type" "fpcmp")])
492 ;; Next come the scc insns. For seq, sne, sgeu, and sltu, we can do this
493 ;; without jumps using the addx/subx instructions. For seq/sne on v9 we use
494 ;; the same code as v8 (the addx/subx method has more applications). The
495 ;; exception to this is "reg != 0" which can be done in one instruction on v9
496 ;; (so we do it). For the rest, on v9 we use conditional moves; on v8, we do
499 ;; Seq_special[_xxx] and sne_special[_xxx] clobber the CC reg, because they
500 ;; generate addcc/subcc instructions.
502 (define_expand "seqsi_special"
504 (xor:SI (match_operand:SI 1 "register_operand" "")
505 (match_operand:SI 2 "register_operand" "")))
506 (parallel [(set (match_operand:SI 0 "register_operand" "")
507 (eq:SI (match_dup 3) (const_int 0)))
508 (clobber (reg:CC 100))])]
510 { operands[3] = gen_reg_rtx (SImode); })
512 (define_expand "seqdi_special"
514 (xor:DI (match_operand:DI 1 "register_operand" "")
515 (match_operand:DI 2 "register_operand" "")))
516 (set (match_operand:DI 0 "register_operand" "")
517 (eq:DI (match_dup 3) (const_int 0)))]
519 { operands[3] = gen_reg_rtx (DImode); })
521 (define_expand "snesi_special"
523 (xor:SI (match_operand:SI 1 "register_operand" "")
524 (match_operand:SI 2 "register_operand" "")))
525 (parallel [(set (match_operand:SI 0 "register_operand" "")
526 (ne:SI (match_dup 3) (const_int 0)))
527 (clobber (reg:CC 100))])]
529 { operands[3] = gen_reg_rtx (SImode); })
531 (define_expand "snedi_special"
533 (xor:DI (match_operand:DI 1 "register_operand" "")
534 (match_operand:DI 2 "register_operand" "")))
535 (set (match_operand:DI 0 "register_operand" "")
536 (ne:DI (match_dup 3) (const_int 0)))]
538 { operands[3] = gen_reg_rtx (DImode); })
540 (define_expand "seqdi_special_trunc"
542 (xor:DI (match_operand:DI 1 "register_operand" "")
543 (match_operand:DI 2 "register_operand" "")))
544 (set (match_operand:SI 0 "register_operand" "")
545 (eq:SI (match_dup 3) (const_int 0)))]
547 { operands[3] = gen_reg_rtx (DImode); })
549 (define_expand "snedi_special_trunc"
551 (xor:DI (match_operand:DI 1 "register_operand" "")
552 (match_operand:DI 2 "register_operand" "")))
553 (set (match_operand:SI 0 "register_operand" "")
554 (ne:SI (match_dup 3) (const_int 0)))]
556 { operands[3] = gen_reg_rtx (DImode); })
558 (define_expand "seqsi_special_extend"
560 (xor:SI (match_operand:SI 1 "register_operand" "")
561 (match_operand:SI 2 "register_operand" "")))
562 (parallel [(set (match_operand:DI 0 "register_operand" "")
563 (eq:DI (match_dup 3) (const_int 0)))
564 (clobber (reg:CC 100))])]
566 { operands[3] = gen_reg_rtx (SImode); })
568 (define_expand "snesi_special_extend"
570 (xor:SI (match_operand:SI 1 "register_operand" "")
571 (match_operand:SI 2 "register_operand" "")))
572 (parallel [(set (match_operand:DI 0 "register_operand" "")
573 (ne:DI (match_dup 3) (const_int 0)))
574 (clobber (reg:CC 100))])]
576 { operands[3] = gen_reg_rtx (SImode); })
578 ;; ??? v9: Operand 0 needs a mode, so SImode was chosen.
579 ;; However, the code handles both SImode and DImode.
581 [(set (match_operand:SI 0 "int_register_operand" "")
582 (eq:SI (match_dup 1) (const_int 0)))]
585 if (GET_MODE (sparc_compare_op0) == SImode)
589 if (GET_MODE (operands[0]) == SImode)
590 pat = gen_seqsi_special (operands[0], sparc_compare_op0,
592 else if (! TARGET_ARCH64)
595 pat = gen_seqsi_special_extend (operands[0], sparc_compare_op0,
600 else if (GET_MODE (sparc_compare_op0) == DImode)
606 else if (GET_MODE (operands[0]) == SImode)
607 pat = gen_seqdi_special_trunc (operands[0], sparc_compare_op0,
610 pat = gen_seqdi_special (operands[0], sparc_compare_op0,
615 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
617 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, EQ);
618 emit_jump_insn (gen_sne (operands[0]));
623 if (gen_v9_scc (EQ, operands))
630 ;; ??? v9: Operand 0 needs a mode, so SImode was chosen.
631 ;; However, the code handles both SImode and DImode.
633 [(set (match_operand:SI 0 "int_register_operand" "")
634 (ne:SI (match_dup 1) (const_int 0)))]
637 if (GET_MODE (sparc_compare_op0) == SImode)
641 if (GET_MODE (operands[0]) == SImode)
642 pat = gen_snesi_special (operands[0], sparc_compare_op0,
644 else if (! TARGET_ARCH64)
647 pat = gen_snesi_special_extend (operands[0], sparc_compare_op0,
652 else if (GET_MODE (sparc_compare_op0) == DImode)
658 else if (GET_MODE (operands[0]) == SImode)
659 pat = gen_snedi_special_trunc (operands[0], sparc_compare_op0,
662 pat = gen_snedi_special (operands[0], sparc_compare_op0,
667 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
669 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, NE);
670 emit_jump_insn (gen_sne (operands[0]));
675 if (gen_v9_scc (NE, operands))
683 [(set (match_operand:SI 0 "int_register_operand" "")
684 (gt:SI (match_dup 1) (const_int 0)))]
687 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
689 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GT);
690 emit_jump_insn (gen_sne (operands[0]));
695 if (gen_v9_scc (GT, operands))
703 [(set (match_operand:SI 0 "int_register_operand" "")
704 (lt:SI (match_dup 1) (const_int 0)))]
707 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
709 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LT);
710 emit_jump_insn (gen_sne (operands[0]));
715 if (gen_v9_scc (LT, operands))
723 [(set (match_operand:SI 0 "int_register_operand" "")
724 (ge:SI (match_dup 1) (const_int 0)))]
727 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
729 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GE);
730 emit_jump_insn (gen_sne (operands[0]));
735 if (gen_v9_scc (GE, operands))
743 [(set (match_operand:SI 0 "int_register_operand" "")
744 (le:SI (match_dup 1) (const_int 0)))]
747 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
749 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LE);
750 emit_jump_insn (gen_sne (operands[0]));
755 if (gen_v9_scc (LE, operands))
762 (define_expand "sgtu"
763 [(set (match_operand:SI 0 "int_register_operand" "")
764 (gtu:SI (match_dup 1) (const_int 0)))]
771 /* We can do ltu easily, so if both operands are registers, swap them and
773 if ((GET_CODE (sparc_compare_op0) == REG
774 || GET_CODE (sparc_compare_op0) == SUBREG)
775 && (GET_CODE (sparc_compare_op1) == REG
776 || GET_CODE (sparc_compare_op1) == SUBREG))
778 tem = sparc_compare_op0;
779 sparc_compare_op0 = sparc_compare_op1;
780 sparc_compare_op1 = tem;
781 pat = gen_sltu (operands[0]);
790 if (gen_v9_scc (GTU, operands))
796 (define_expand "sltu"
797 [(set (match_operand:SI 0 "int_register_operand" "")
798 (ltu:SI (match_dup 1) (const_int 0)))]
803 if (gen_v9_scc (LTU, operands))
806 operands[1] = gen_compare_reg (LTU, sparc_compare_op0, sparc_compare_op1);
809 (define_expand "sgeu"
810 [(set (match_operand:SI 0 "int_register_operand" "")
811 (geu:SI (match_dup 1) (const_int 0)))]
816 if (gen_v9_scc (GEU, operands))
819 operands[1] = gen_compare_reg (GEU, sparc_compare_op0, sparc_compare_op1);
822 (define_expand "sleu"
823 [(set (match_operand:SI 0 "int_register_operand" "")
824 (leu:SI (match_dup 1) (const_int 0)))]
831 /* We can do geu easily, so if both operands are registers, swap them and
833 if ((GET_CODE (sparc_compare_op0) == REG
834 || GET_CODE (sparc_compare_op0) == SUBREG)
835 && (GET_CODE (sparc_compare_op1) == REG
836 || GET_CODE (sparc_compare_op1) == SUBREG))
838 tem = sparc_compare_op0;
839 sparc_compare_op0 = sparc_compare_op1;
840 sparc_compare_op1 = tem;
841 pat = gen_sgeu (operands[0]);
850 if (gen_v9_scc (LEU, operands))
856 ;; Now the DEFINE_INSNs for the scc cases.
858 ;; The SEQ and SNE patterns are special because they can be done
859 ;; without any branching and do not involve a COMPARE. We want
860 ;; them to always use the splits below so the results can be
863 (define_insn_and_split "*snesi_zero"
864 [(set (match_operand:SI 0 "register_operand" "=r")
865 (ne:SI (match_operand:SI 1 "register_operand" "r")
867 (clobber (reg:CC 100))]
871 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
873 (set (match_dup 0) (ltu:SI (reg:CC 100) (const_int 0)))]
875 [(set_attr "length" "2")])
877 (define_insn_and_split "*neg_snesi_zero"
878 [(set (match_operand:SI 0 "register_operand" "=r")
879 (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
881 (clobber (reg:CC 100))]
885 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
887 (set (match_dup 0) (neg:SI (ltu:SI (reg:CC 100) (const_int 0))))]
889 [(set_attr "length" "2")])
891 (define_insn_and_split "*snesi_zero_extend"
892 [(set (match_operand:DI 0 "register_operand" "=r")
893 (ne:DI (match_operand:SI 1 "register_operand" "r")
895 (clobber (reg:CC 100))]
899 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (minus:SI (const_int 0)
902 (set (match_dup 0) (zero_extend:DI (plus:SI (plus:SI (const_int 0)
904 (ltu:SI (reg:CC_NOOV 100)
907 [(set_attr "length" "2")])
909 (define_insn_and_split "*snedi_zero"
910 [(set (match_operand:DI 0 "register_operand" "=&r")
911 (ne:DI (match_operand:DI 1 "register_operand" "r")
915 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
916 [(set (match_dup 0) (const_int 0))
917 (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
922 [(set_attr "length" "2")])
924 (define_insn_and_split "*neg_snedi_zero"
925 [(set (match_operand:DI 0 "register_operand" "=&r")
926 (neg:DI (ne:DI (match_operand:DI 1 "register_operand" "r")
930 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
931 [(set (match_dup 0) (const_int 0))
932 (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
937 [(set_attr "length" "2")])
939 (define_insn_and_split "*snedi_zero_trunc"
940 [(set (match_operand:SI 0 "register_operand" "=&r")
941 (ne:SI (match_operand:DI 1 "register_operand" "r")
945 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
946 [(set (match_dup 0) (const_int 0))
947 (set (match_dup 0) (if_then_else:SI (ne:DI (match_dup 1)
952 [(set_attr "length" "2")])
954 (define_insn_and_split "*seqsi_zero"
955 [(set (match_operand:SI 0 "register_operand" "=r")
956 (eq:SI (match_operand:SI 1 "register_operand" "r")
958 (clobber (reg:CC 100))]
962 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
964 (set (match_dup 0) (geu:SI (reg:CC 100) (const_int 0)))]
966 [(set_attr "length" "2")])
968 (define_insn_and_split "*neg_seqsi_zero"
969 [(set (match_operand:SI 0 "register_operand" "=r")
970 (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
972 (clobber (reg:CC 100))]
976 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
978 (set (match_dup 0) (neg:SI (geu:SI (reg:CC 100) (const_int 0))))]
980 [(set_attr "length" "2")])
982 (define_insn_and_split "*seqsi_zero_extend"
983 [(set (match_operand:DI 0 "register_operand" "=r")
984 (eq:DI (match_operand:SI 1 "register_operand" "r")
986 (clobber (reg:CC 100))]
990 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (minus:SI (const_int 0)
993 (set (match_dup 0) (zero_extend:DI (minus:SI (minus:SI (const_int 0)
995 (ltu:SI (reg:CC_NOOV 100)
998 [(set_attr "length" "2")])
1000 (define_insn_and_split "*seqdi_zero"
1001 [(set (match_operand:DI 0 "register_operand" "=&r")
1002 (eq:DI (match_operand:DI 1 "register_operand" "r")
1006 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
1007 [(set (match_dup 0) (const_int 0))
1008 (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
1013 [(set_attr "length" "2")])
1015 (define_insn_and_split "*neg_seqdi_zero"
1016 [(set (match_operand:DI 0 "register_operand" "=&r")
1017 (neg:DI (eq:DI (match_operand:DI 1 "register_operand" "r")
1021 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
1022 [(set (match_dup 0) (const_int 0))
1023 (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
1028 [(set_attr "length" "2")])
1030 (define_insn_and_split "*seqdi_zero_trunc"
1031 [(set (match_operand:SI 0 "register_operand" "=&r")
1032 (eq:SI (match_operand:DI 1 "register_operand" "r")
1036 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
1037 [(set (match_dup 0) (const_int 0))
1038 (set (match_dup 0) (if_then_else:SI (eq:DI (match_dup 1)
1043 [(set_attr "length" "2")])
1045 ;; We can also do (x + (i == 0)) and related, so put them in.
1046 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1049 (define_insn_and_split "*x_plus_i_ne_0"
1050 [(set (match_operand:SI 0 "register_operand" "=r")
1051 (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
1053 (match_operand:SI 2 "register_operand" "r")))
1054 (clobber (reg:CC 100))]
1058 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1060 (set (match_dup 0) (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1063 [(set_attr "length" "2")])
1065 (define_insn_and_split "*x_minus_i_ne_0"
1066 [(set (match_operand:SI 0 "register_operand" "=r")
1067 (minus:SI (match_operand:SI 2 "register_operand" "r")
1068 (ne:SI (match_operand:SI 1 "register_operand" "r")
1070 (clobber (reg:CC 100))]
1074 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1076 (set (match_dup 0) (minus:SI (match_dup 2)
1077 (ltu:SI (reg:CC 100) (const_int 0))))]
1079 [(set_attr "length" "2")])
1081 (define_insn_and_split "*x_plus_i_eq_0"
1082 [(set (match_operand:SI 0 "register_operand" "=r")
1083 (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
1085 (match_operand:SI 2 "register_operand" "r")))
1086 (clobber (reg:CC 100))]
1090 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1092 (set (match_dup 0) (plus:SI (geu:SI (reg:CC 100) (const_int 0))
1095 [(set_attr "length" "2")])
1097 (define_insn_and_split "*x_minus_i_eq_0"
1098 [(set (match_operand:SI 0 "register_operand" "=r")
1099 (minus:SI (match_operand:SI 2 "register_operand" "r")
1100 (eq:SI (match_operand:SI 1 "register_operand" "r")
1102 (clobber (reg:CC 100))]
1106 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1108 (set (match_dup 0) (minus:SI (match_dup 2)
1109 (geu:SI (reg:CC 100) (const_int 0))))]
1111 [(set_attr "length" "2")])
1113 ;; We can also do GEU and LTU directly, but these operate after a compare.
1114 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1117 (define_insn "*sltu_insn"
1118 [(set (match_operand:SI 0 "register_operand" "=r")
1119 (ltu:SI (reg:CC 100) (const_int 0)))]
1122 [(set_attr "type" "ialuX")])
1124 (define_insn "*neg_sltu_insn"
1125 [(set (match_operand:SI 0 "register_operand" "=r")
1126 (neg:SI (ltu:SI (reg:CC 100) (const_int 0))))]
1129 [(set_attr "type" "ialuX")])
1131 ;; ??? Combine should canonicalize these next two to the same pattern.
1132 (define_insn "*neg_sltu_minus_x"
1133 [(set (match_operand:SI 0 "register_operand" "=r")
1134 (minus:SI (neg:SI (ltu:SI (reg:CC 100) (const_int 0)))
1135 (match_operand:SI 1 "arith_operand" "rI")))]
1137 "subx\t%%g0, %1, %0"
1138 [(set_attr "type" "ialuX")])
1140 (define_insn "*neg_sltu_plus_x"
1141 [(set (match_operand:SI 0 "register_operand" "=r")
1142 (neg:SI (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1143 (match_operand:SI 1 "arith_operand" "rI"))))]
1145 "subx\t%%g0, %1, %0"
1146 [(set_attr "type" "ialuX")])
1148 (define_insn "*sgeu_insn"
1149 [(set (match_operand:SI 0 "register_operand" "=r")
1150 (geu:SI (reg:CC 100) (const_int 0)))]
1152 "subx\t%%g0, -1, %0"
1153 [(set_attr "type" "ialuX")])
1155 (define_insn "*neg_sgeu_insn"
1156 [(set (match_operand:SI 0 "register_operand" "=r")
1157 (neg:SI (geu:SI (reg:CC 100) (const_int 0))))]
1159 "addx\t%%g0, -1, %0"
1160 [(set_attr "type" "ialuX")])
1162 ;; We can also do (x + ((unsigned) i >= 0)) and related, so put them in.
1163 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1166 (define_insn "*sltu_plus_x"
1167 [(set (match_operand:SI 0 "register_operand" "=r")
1168 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1169 (match_operand:SI 1 "arith_operand" "rI")))]
1171 "addx\t%%g0, %1, %0"
1172 [(set_attr "type" "ialuX")])
1174 (define_insn "*sltu_plus_x_plus_y"
1175 [(set (match_operand:SI 0 "register_operand" "=r")
1176 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1177 (plus:SI (match_operand:SI 1 "arith_operand" "%r")
1178 (match_operand:SI 2 "arith_operand" "rI"))))]
1181 [(set_attr "type" "ialuX")])
1183 (define_insn "*x_minus_sltu"
1184 [(set (match_operand:SI 0 "register_operand" "=r")
1185 (minus:SI (match_operand:SI 1 "register_operand" "r")
1186 (ltu:SI (reg:CC 100) (const_int 0))))]
1189 [(set_attr "type" "ialuX")])
1191 ;; ??? Combine should canonicalize these next two to the same pattern.
1192 (define_insn "*x_minus_y_minus_sltu"
1193 [(set (match_operand:SI 0 "register_operand" "=r")
1194 (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
1195 (match_operand:SI 2 "arith_operand" "rI"))
1196 (ltu:SI (reg:CC 100) (const_int 0))))]
1199 [(set_attr "type" "ialuX")])
1201 (define_insn "*x_minus_sltu_plus_y"
1202 [(set (match_operand:SI 0 "register_operand" "=r")
1203 (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
1204 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1205 (match_operand:SI 2 "arith_operand" "rI"))))]
1208 [(set_attr "type" "ialuX")])
1210 (define_insn "*sgeu_plus_x"
1211 [(set (match_operand:SI 0 "register_operand" "=r")
1212 (plus:SI (geu:SI (reg:CC 100) (const_int 0))
1213 (match_operand:SI 1 "register_operand" "r")))]
1216 [(set_attr "type" "ialuX")])
1218 (define_insn "*x_minus_sgeu"
1219 [(set (match_operand:SI 0 "register_operand" "=r")
1220 (minus:SI (match_operand:SI 1 "register_operand" "r")
1221 (geu:SI (reg:CC 100) (const_int 0))))]
1224 [(set_attr "type" "ialuX")])
1227 [(set (match_operand:SI 0 "register_operand" "")
1228 (match_operator:SI 2 "noov_compare_operator"
1229 [(match_operand 1 "icc_or_fcc_register_operand" "")
1232 && REGNO (operands[1]) == SPARC_ICC_REG
1233 && (GET_MODE (operands[1]) == CCXmode
1234 /* 32 bit LTU/GEU are better implemented using addx/subx. */
1235 || (GET_CODE (operands[2]) != LTU && GET_CODE (operands[2]) != GEU))"
1236 [(set (match_dup 0) (const_int 0))
1238 (if_then_else:SI (match_op_dup:SI 2 [(match_dup 1) (const_int 0)])
1244 ;; These control RTL generation for conditional jump insns
1246 ;; The quad-word fp compare library routines all return nonzero to indicate
1247 ;; true, which is different from the equivalent libgcc routines, so we must
1248 ;; handle them specially here.
1250 (define_expand "beq"
1252 (if_then_else (eq (match_dup 1) (const_int 0))
1253 (label_ref (match_operand 0 "" ""))
1257 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1258 && GET_CODE (sparc_compare_op0) == REG
1259 && GET_MODE (sparc_compare_op0) == DImode)
1261 emit_v9_brxx_insn (EQ, sparc_compare_op0, operands[0]);
1264 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1266 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, EQ);
1267 emit_jump_insn (gen_bne (operands[0]));
1270 operands[1] = gen_compare_reg (EQ, sparc_compare_op0, sparc_compare_op1);
1273 (define_expand "bne"
1275 (if_then_else (ne (match_dup 1) (const_int 0))
1276 (label_ref (match_operand 0 "" ""))
1280 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1281 && GET_CODE (sparc_compare_op0) == REG
1282 && GET_MODE (sparc_compare_op0) == DImode)
1284 emit_v9_brxx_insn (NE, sparc_compare_op0, operands[0]);
1287 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1289 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, NE);
1290 emit_jump_insn (gen_bne (operands[0]));
1293 operands[1] = gen_compare_reg (NE, sparc_compare_op0, sparc_compare_op1);
1296 (define_expand "bgt"
1298 (if_then_else (gt (match_dup 1) (const_int 0))
1299 (label_ref (match_operand 0 "" ""))
1303 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1304 && GET_CODE (sparc_compare_op0) == REG
1305 && GET_MODE (sparc_compare_op0) == DImode)
1307 emit_v9_brxx_insn (GT, sparc_compare_op0, operands[0]);
1310 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1312 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GT);
1313 emit_jump_insn (gen_bne (operands[0]));
1316 operands[1] = gen_compare_reg (GT, sparc_compare_op0, sparc_compare_op1);
1319 (define_expand "bgtu"
1321 (if_then_else (gtu (match_dup 1) (const_int 0))
1322 (label_ref (match_operand 0 "" ""))
1326 operands[1] = gen_compare_reg (GTU, sparc_compare_op0, sparc_compare_op1);
1329 (define_expand "blt"
1331 (if_then_else (lt (match_dup 1) (const_int 0))
1332 (label_ref (match_operand 0 "" ""))
1336 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1337 && GET_CODE (sparc_compare_op0) == REG
1338 && GET_MODE (sparc_compare_op0) == DImode)
1340 emit_v9_brxx_insn (LT, sparc_compare_op0, operands[0]);
1343 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1345 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LT);
1346 emit_jump_insn (gen_bne (operands[0]));
1349 operands[1] = gen_compare_reg (LT, sparc_compare_op0, sparc_compare_op1);
1352 (define_expand "bltu"
1354 (if_then_else (ltu (match_dup 1) (const_int 0))
1355 (label_ref (match_operand 0 "" ""))
1359 operands[1] = gen_compare_reg (LTU, sparc_compare_op0, sparc_compare_op1);
1362 (define_expand "bge"
1364 (if_then_else (ge (match_dup 1) (const_int 0))
1365 (label_ref (match_operand 0 "" ""))
1369 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1370 && GET_CODE (sparc_compare_op0) == REG
1371 && GET_MODE (sparc_compare_op0) == DImode)
1373 emit_v9_brxx_insn (GE, sparc_compare_op0, operands[0]);
1376 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1378 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GE);
1379 emit_jump_insn (gen_bne (operands[0]));
1382 operands[1] = gen_compare_reg (GE, sparc_compare_op0, sparc_compare_op1);
1385 (define_expand "bgeu"
1387 (if_then_else (geu (match_dup 1) (const_int 0))
1388 (label_ref (match_operand 0 "" ""))
1392 operands[1] = gen_compare_reg (GEU, sparc_compare_op0, sparc_compare_op1);
1395 (define_expand "ble"
1397 (if_then_else (le (match_dup 1) (const_int 0))
1398 (label_ref (match_operand 0 "" ""))
1402 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1403 && GET_CODE (sparc_compare_op0) == REG
1404 && GET_MODE (sparc_compare_op0) == DImode)
1406 emit_v9_brxx_insn (LE, sparc_compare_op0, operands[0]);
1409 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1411 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LE);
1412 emit_jump_insn (gen_bne (operands[0]));
1415 operands[1] = gen_compare_reg (LE, sparc_compare_op0, sparc_compare_op1);
1418 (define_expand "bleu"
1420 (if_then_else (leu (match_dup 1) (const_int 0))
1421 (label_ref (match_operand 0 "" ""))
1425 operands[1] = gen_compare_reg (LEU, sparc_compare_op0, sparc_compare_op1);
1428 (define_expand "bunordered"
1430 (if_then_else (unordered (match_dup 1) (const_int 0))
1431 (label_ref (match_operand 0 "" ""))
1435 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1437 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1,
1439 emit_jump_insn (gen_beq (operands[0]));
1442 operands[1] = gen_compare_reg (UNORDERED, sparc_compare_op0,
1446 (define_expand "bordered"
1448 (if_then_else (ordered (match_dup 1) (const_int 0))
1449 (label_ref (match_operand 0 "" ""))
1453 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1455 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, ORDERED);
1456 emit_jump_insn (gen_bne (operands[0]));
1459 operands[1] = gen_compare_reg (ORDERED, sparc_compare_op0,
1463 (define_expand "bungt"
1465 (if_then_else (ungt (match_dup 1) (const_int 0))
1466 (label_ref (match_operand 0 "" ""))
1470 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1472 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNGT);
1473 emit_jump_insn (gen_bgt (operands[0]));
1476 operands[1] = gen_compare_reg (UNGT, sparc_compare_op0, sparc_compare_op1);
1479 (define_expand "bunlt"
1481 (if_then_else (unlt (match_dup 1) (const_int 0))
1482 (label_ref (match_operand 0 "" ""))
1486 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1488 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNLT);
1489 emit_jump_insn (gen_bne (operands[0]));
1492 operands[1] = gen_compare_reg (UNLT, sparc_compare_op0, sparc_compare_op1);
1495 (define_expand "buneq"
1497 (if_then_else (uneq (match_dup 1) (const_int 0))
1498 (label_ref (match_operand 0 "" ""))
1502 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1504 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNEQ);
1505 emit_jump_insn (gen_beq (operands[0]));
1508 operands[1] = gen_compare_reg (UNEQ, sparc_compare_op0, sparc_compare_op1);
1511 (define_expand "bunge"
1513 (if_then_else (unge (match_dup 1) (const_int 0))
1514 (label_ref (match_operand 0 "" ""))
1518 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1520 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNGE);
1521 emit_jump_insn (gen_bne (operands[0]));
1524 operands[1] = gen_compare_reg (UNGE, sparc_compare_op0, sparc_compare_op1);
1527 (define_expand "bunle"
1529 (if_then_else (unle (match_dup 1) (const_int 0))
1530 (label_ref (match_operand 0 "" ""))
1534 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1536 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNLE);
1537 emit_jump_insn (gen_bne (operands[0]));
1540 operands[1] = gen_compare_reg (UNLE, sparc_compare_op0, sparc_compare_op1);
1543 (define_expand "bltgt"
1545 (if_then_else (ltgt (match_dup 1) (const_int 0))
1546 (label_ref (match_operand 0 "" ""))
1550 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1552 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LTGT);
1553 emit_jump_insn (gen_bne (operands[0]));
1556 operands[1] = gen_compare_reg (LTGT, sparc_compare_op0, sparc_compare_op1);
1559 ;; Now match both normal and inverted jump.
1561 ;; XXX fpcmp nop braindamage
1562 (define_insn "*normal_branch"
1564 (if_then_else (match_operator 0 "noov_compare_operator"
1565 [(reg 100) (const_int 0)])
1566 (label_ref (match_operand 1 "" ""))
1570 return output_cbranch (operands[0], operands[1], 1, 0,
1571 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1574 [(set_attr "type" "branch")
1575 (set_attr "branch_type" "icc")])
1577 ;; XXX fpcmp nop braindamage
1578 (define_insn "*inverted_branch"
1580 (if_then_else (match_operator 0 "noov_compare_operator"
1581 [(reg 100) (const_int 0)])
1583 (label_ref (match_operand 1 "" ""))))]
1586 return output_cbranch (operands[0], operands[1], 1, 1,
1587 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1590 [(set_attr "type" "branch")
1591 (set_attr "branch_type" "icc")])
1593 ;; XXX fpcmp nop braindamage
1594 (define_insn "*normal_fp_branch"
1596 (if_then_else (match_operator 1 "comparison_operator"
1597 [(match_operand:CCFP 0 "fcc_register_operand" "c")
1599 (label_ref (match_operand 2 "" ""))
1603 return output_cbranch (operands[1], operands[2], 2, 0,
1604 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1607 [(set_attr "type" "branch")
1608 (set_attr "branch_type" "fcc")])
1610 ;; XXX fpcmp nop braindamage
1611 (define_insn "*inverted_fp_branch"
1613 (if_then_else (match_operator 1 "comparison_operator"
1614 [(match_operand:CCFP 0 "fcc_register_operand" "c")
1617 (label_ref (match_operand 2 "" ""))))]
1620 return output_cbranch (operands[1], operands[2], 2, 1,
1621 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1624 [(set_attr "type" "branch")
1625 (set_attr "branch_type" "fcc")])
1627 ;; XXX fpcmp nop braindamage
1628 (define_insn "*normal_fpe_branch"
1630 (if_then_else (match_operator 1 "comparison_operator"
1631 [(match_operand:CCFPE 0 "fcc_register_operand" "c")
1633 (label_ref (match_operand 2 "" ""))
1637 return output_cbranch (operands[1], operands[2], 2, 0,
1638 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1641 [(set_attr "type" "branch")
1642 (set_attr "branch_type" "fcc")])
1644 ;; XXX fpcmp nop braindamage
1645 (define_insn "*inverted_fpe_branch"
1647 (if_then_else (match_operator 1 "comparison_operator"
1648 [(match_operand:CCFPE 0 "fcc_register_operand" "c")
1651 (label_ref (match_operand 2 "" ""))))]
1654 return output_cbranch (operands[1], operands[2], 2, 1,
1655 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1658 [(set_attr "type" "branch")
1659 (set_attr "branch_type" "fcc")])
1661 ;; SPARC V9-specific jump insns. None of these are guaranteed to be
1662 ;; in the architecture.
1664 ;; There are no 32 bit brreg insns.
1667 (define_insn "*normal_int_branch_sp64"
1669 (if_then_else (match_operator 0 "v9_register_compare_operator"
1670 [(match_operand:DI 1 "register_operand" "r")
1672 (label_ref (match_operand 2 "" ""))
1676 return output_v9branch (operands[0], operands[2], 1, 2, 0,
1677 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1680 [(set_attr "type" "branch")
1681 (set_attr "branch_type" "reg")])
1684 (define_insn "*inverted_int_branch_sp64"
1686 (if_then_else (match_operator 0 "v9_register_compare_operator"
1687 [(match_operand:DI 1 "register_operand" "r")
1690 (label_ref (match_operand 2 "" ""))))]
1693 return output_v9branch (operands[0], operands[2], 1, 2, 1,
1694 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1697 [(set_attr "type" "branch")
1698 (set_attr "branch_type" "reg")])
1701 (define_mode_macro P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
1703 ;; Load in operand 0 the (absolute) address of operand 1, which is a symbolic
1704 ;; value subject to a PC-relative relocation. Operand 2 is a helper function
1705 ;; that adds the PC value at the call point to operand 0.
1707 (define_insn "load_pcrel_sym<P:mode>"
1708 [(set (match_operand:P 0 "register_operand" "=r")
1709 (unspec:P [(match_operand:P 1 "symbolic_operand" "")
1710 (match_operand:P 2 "call_address_operand" "")] UNSPEC_LOAD_PCREL_SYM))
1711 (clobber (reg:P 15))]
1714 if (flag_delayed_branch)
1715 return "sethi\t%%hi(%a1-4), %0\n\tcall\t%a2\n\t add\t%0, %%lo(%a1+4), %0";
1717 return "sethi\t%%hi(%a1-8), %0\n\tadd\t%0, %%lo(%a1-4), %0\n\tcall\t%a2\n\t nop";
1719 [(set (attr "type") (const_string "multi"))
1720 (set (attr "length")
1721 (if_then_else (eq_attr "delayed_branch" "true")
1726 ;; Integer move instructions
1728 (define_expand "movqi"
1729 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1730 (match_operand:QI 1 "general_operand" ""))]
1733 if (sparc_expand_move (QImode, operands))
1737 (define_insn "*movqi_insn"
1738 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m")
1739 (match_operand:QI 1 "input_operand" "rI,m,rJ"))]
1740 "(register_operand (operands[0], QImode)
1741 || register_or_zero_operand (operands[1], QImode))"
1746 [(set_attr "type" "*,load,store")
1747 (set_attr "us3load_type" "*,3cycle,*")])
1749 (define_expand "movhi"
1750 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1751 (match_operand:HI 1 "general_operand" ""))]
1754 if (sparc_expand_move (HImode, operands))
1758 (define_insn "*movhi_insn"
1759 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1760 (match_operand:HI 1 "input_operand" "rI,K,m,rJ"))]
1761 "(register_operand (operands[0], HImode)
1762 || register_or_zero_operand (operands[1], HImode))"
1765 sethi\t%%hi(%a1), %0
1768 [(set_attr "type" "*,*,load,store")
1769 (set_attr "us3load_type" "*,*,3cycle,*")])
1771 ;; We always work with constants here.
1772 (define_insn "*movhi_lo_sum"
1773 [(set (match_operand:HI 0 "register_operand" "=r")
1774 (ior:HI (match_operand:HI 1 "register_operand" "%r")
1775 (match_operand:HI 2 "small_int_operand" "I")))]
1779 (define_expand "movsi"
1780 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1781 (match_operand:SI 1 "general_operand" ""))]
1784 if (sparc_expand_move (SImode, operands))
1788 (define_insn "*movsi_insn"
1789 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,m,!f,!f,!m,d")
1790 (match_operand:SI 1 "input_operand" "rI,K,m,rJ,f,m,f,J"))]
1791 "(register_operand (operands[0], SImode)
1792 || register_or_zero_operand (operands[1], SImode))"
1795 sethi\t%%hi(%a1), %0
1802 [(set_attr "type" "*,*,load,store,fpmove,fpload,fpstore,fga")])
1804 (define_insn "*movsi_lo_sum"
1805 [(set (match_operand:SI 0 "register_operand" "=r")
1806 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1807 (match_operand:SI 2 "immediate_operand" "in")))]
1809 "or\t%1, %%lo(%a2), %0")
1811 (define_insn "*movsi_high"
1812 [(set (match_operand:SI 0 "register_operand" "=r")
1813 (high:SI (match_operand:SI 1 "immediate_operand" "in")))]
1815 "sethi\t%%hi(%a1), %0")
1817 ;; The next two patterns must wrap the SYMBOL_REF in an UNSPEC
1818 ;; so that CSE won't optimize the address computation away.
1819 (define_insn "movsi_lo_sum_pic"
1820 [(set (match_operand:SI 0 "register_operand" "=r")
1821 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1822 (unspec:SI [(match_operand:SI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
1824 "or\t%1, %%lo(%a2), %0")
1826 (define_insn "movsi_high_pic"
1827 [(set (match_operand:SI 0 "register_operand" "=r")
1828 (high:SI (unspec:SI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
1829 "flag_pic && check_pic (1)"
1830 "sethi\t%%hi(%a1), %0")
1832 (define_expand "movsi_pic_label_ref"
1833 [(set (match_dup 3) (high:SI
1834 (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
1835 (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1836 (set (match_dup 4) (lo_sum:SI (match_dup 3)
1837 (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1838 (set (match_operand:SI 0 "register_operand" "=r")
1839 (minus:SI (match_dup 5) (match_dup 4)))]
1842 current_function_uses_pic_offset_table = 1;
1843 operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
1846 operands[3] = operands[0];
1847 operands[4] = operands[0];
1851 operands[3] = gen_reg_rtx (SImode);
1852 operands[4] = gen_reg_rtx (SImode);
1854 operands[5] = pic_offset_table_rtx;
1857 (define_insn "*movsi_high_pic_label_ref"
1858 [(set (match_operand:SI 0 "register_operand" "=r")
1860 (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
1861 (match_operand:SI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1863 "sethi\t%%hi(%a2-(%a1-.)), %0")
1865 (define_insn "*movsi_lo_sum_pic_label_ref"
1866 [(set (match_operand:SI 0 "register_operand" "=r")
1867 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1868 (unspec:SI [(match_operand:SI 2 "label_ref_operand" "")
1869 (match_operand:SI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1871 "or\t%1, %%lo(%a3-(%a2-.)), %0")
1873 (define_expand "movdi"
1874 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1875 (match_operand:DI 1 "general_operand" ""))]
1878 if (sparc_expand_move (DImode, operands))
1882 ;; Be careful, fmovd does not exist when !v9.
1883 ;; We match MEM moves directly when we have correct even
1884 ;; numbered registers, but fall into splits otherwise.
1885 ;; The constraint ordering here is really important to
1886 ;; avoid insane problems in reload, especially for patterns
1889 ;; (set (mem:DI (plus:SI (reg:SI 30 %fp)
1890 ;; (const_int -5016)))
1894 (define_insn "*movdi_insn_sp32"
1895 [(set (match_operand:DI 0 "nonimmediate_operand"
1896 "=o,T,U,o,r,r,r,?T,?f,?f,?o,?f")
1897 (match_operand:DI 1 "input_operand"
1898 " J,U,T,r,o,i,r, f, T, o, f, f"))]
1900 && (register_operand (operands[0], DImode)
1901 || register_or_zero_operand (operands[1], DImode))"
1915 [(set_attr "type" "store,store,load,*,*,*,*,fpstore,fpload,*,*,*")
1916 (set_attr "length" "2,*,*,2,2,2,2,*,*,2,2,2")])
1918 (define_insn "*movdi_insn_sp32_v9"
1919 [(set (match_operand:DI 0 "nonimmediate_operand"
1920 "=T,o,T,U,o,r,r,r,?T,?f,?f,?o,?e,?e,?W")
1921 (match_operand:DI 1 "input_operand"
1922 " J,J,U,T,r,o,i,r, f, T, o, f, e, W, e"))]
1925 && (register_operand (operands[0], DImode)
1926 || register_or_zero_operand (operands[1], DImode))"
1943 [(set_attr "type" "store,store,store,load,*,*,*,*,fpstore,fpload,*,*,fpmove,fpload,fpstore")
1944 (set_attr "length" "*,2,*,*,2,2,2,2,*,*,2,2,*,*,*")
1945 (set_attr "fptype" "*,*,*,*,*,*,*,*,*,*,*,*,double,*,*")])
1947 (define_insn "*movdi_insn_sp64"
1948 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,m,?e,?e,?W,b")
1949 (match_operand:DI 1 "input_operand" "rI,N,m,rJ,e,W,e,J"))]
1951 && (register_operand (operands[0], DImode)
1952 || register_or_zero_operand (operands[1], DImode))"
1955 sethi\t%%hi(%a1), %0
1962 [(set_attr "type" "*,*,load,store,fpmove,fpload,fpstore,fga")
1963 (set_attr "fptype" "*,*,*,*,double,*,*,double")])
1965 (define_expand "movdi_pic_label_ref"
1966 [(set (match_dup 3) (high:DI
1967 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
1968 (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1969 (set (match_dup 4) (lo_sum:DI (match_dup 3)
1970 (unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1971 (set (match_operand:DI 0 "register_operand" "=r")
1972 (minus:DI (match_dup 5) (match_dup 4)))]
1973 "TARGET_ARCH64 && flag_pic"
1975 current_function_uses_pic_offset_table = 1;
1976 operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
1979 operands[3] = operands[0];
1980 operands[4] = operands[0];
1984 operands[3] = gen_reg_rtx (DImode);
1985 operands[4] = gen_reg_rtx (DImode);
1987 operands[5] = pic_offset_table_rtx;
1990 (define_insn "*movdi_high_pic_label_ref"
1991 [(set (match_operand:DI 0 "register_operand" "=r")
1993 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
1994 (match_operand:DI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1995 "TARGET_ARCH64 && flag_pic"
1996 "sethi\t%%hi(%a2-(%a1-.)), %0")
1998 (define_insn "*movdi_lo_sum_pic_label_ref"
1999 [(set (match_operand:DI 0 "register_operand" "=r")
2000 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2001 (unspec:DI [(match_operand:DI 2 "label_ref_operand" "")
2002 (match_operand:DI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
2003 "TARGET_ARCH64 && flag_pic"
2004 "or\t%1, %%lo(%a3-(%a2-.)), %0")
2006 ;; SPARC-v9 code model support insns. See sparc_emit_set_symbolic_const64
2007 ;; in sparc.c to see what is going on here... PIC stuff comes first.
2009 (define_insn "movdi_lo_sum_pic"
2010 [(set (match_operand:DI 0 "register_operand" "=r")
2011 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2012 (unspec:DI [(match_operand:DI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
2013 "TARGET_ARCH64 && flag_pic"
2014 "or\t%1, %%lo(%a2), %0")
2016 (define_insn "movdi_high_pic"
2017 [(set (match_operand:DI 0 "register_operand" "=r")
2018 (high:DI (unspec:DI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
2019 "TARGET_ARCH64 && flag_pic && check_pic (1)"
2020 "sethi\t%%hi(%a1), %0")
2022 (define_insn "*sethi_di_medlow_embmedany_pic"
2023 [(set (match_operand:DI 0 "register_operand" "=r")
2024 (high:DI (match_operand:DI 1 "medium_pic_operand" "")))]
2025 "(TARGET_CM_MEDLOW || TARGET_CM_EMBMEDANY) && check_pic (1)"
2026 "sethi\t%%hi(%a1), %0")
2028 (define_insn "*sethi_di_medlow"
2029 [(set (match_operand:DI 0 "register_operand" "=r")
2030 (high:DI (match_operand:DI 1 "symbolic_operand" "")))]
2031 "TARGET_CM_MEDLOW && check_pic (1)"
2032 "sethi\t%%hi(%a1), %0")
2034 (define_insn "*losum_di_medlow"
2035 [(set (match_operand:DI 0 "register_operand" "=r")
2036 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2037 (match_operand:DI 2 "symbolic_operand" "")))]
2039 "or\t%1, %%lo(%a2), %0")
2041 (define_insn "seth44"
2042 [(set (match_operand:DI 0 "register_operand" "=r")
2043 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETH44)))]
2045 "sethi\t%%h44(%a1), %0")
2047 (define_insn "setm44"
2048 [(set (match_operand:DI 0 "register_operand" "=r")
2049 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2050 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_SETM44)))]
2052 "or\t%1, %%m44(%a2), %0")
2054 (define_insn "setl44"
2055 [(set (match_operand:DI 0 "register_operand" "=r")
2056 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2057 (match_operand:DI 2 "symbolic_operand" "")))]
2059 "or\t%1, %%l44(%a2), %0")
2061 (define_insn "sethh"
2062 [(set (match_operand:DI 0 "register_operand" "=r")
2063 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETHH)))]
2065 "sethi\t%%hh(%a1), %0")
2067 (define_insn "setlm"
2068 [(set (match_operand:DI 0 "register_operand" "=r")
2069 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETLM)))]
2071 "sethi\t%%lm(%a1), %0")
2073 (define_insn "sethm"
2074 [(set (match_operand:DI 0 "register_operand" "=r")
2075 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2076 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_EMB_SETHM)))]
2078 "or\t%1, %%hm(%a2), %0")
2080 (define_insn "setlo"
2081 [(set (match_operand:DI 0 "register_operand" "=r")
2082 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2083 (match_operand:DI 2 "symbolic_operand" "")))]
2085 "or\t%1, %%lo(%a2), %0")
2087 (define_insn "embmedany_sethi"
2088 [(set (match_operand:DI 0 "register_operand" "=r")
2089 (high:DI (unspec:DI [(match_operand:DI 1 "data_segment_operand" "")] UNSPEC_EMB_HISUM)))]
2090 "TARGET_CM_EMBMEDANY && check_pic (1)"
2091 "sethi\t%%hi(%a1), %0")
2093 (define_insn "embmedany_losum"
2094 [(set (match_operand:DI 0 "register_operand" "=r")
2095 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2096 (match_operand:DI 2 "data_segment_operand" "")))]
2097 "TARGET_CM_EMBMEDANY"
2098 "add\t%1, %%lo(%a2), %0")
2100 (define_insn "embmedany_brsum"
2101 [(set (match_operand:DI 0 "register_operand" "=r")
2102 (unspec:DI [(match_operand:DI 1 "register_operand" "r")] UNSPEC_EMB_HISUM))]
2103 "TARGET_CM_EMBMEDANY"
2106 (define_insn "embmedany_textuhi"
2107 [(set (match_operand:DI 0 "register_operand" "=r")
2108 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTUHI)))]
2109 "TARGET_CM_EMBMEDANY && check_pic (1)"
2110 "sethi\t%%uhi(%a1), %0")
2112 (define_insn "embmedany_texthi"
2113 [(set (match_operand:DI 0 "register_operand" "=r")
2114 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTHI)))]
2115 "TARGET_CM_EMBMEDANY && check_pic (1)"
2116 "sethi\t%%hi(%a1), %0")
2118 (define_insn "embmedany_textulo"
2119 [(set (match_operand:DI 0 "register_operand" "=r")
2120 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2121 (unspec:DI [(match_operand:DI 2 "text_segment_operand" "")] UNSPEC_EMB_TEXTULO)))]
2122 "TARGET_CM_EMBMEDANY"
2123 "or\t%1, %%ulo(%a2), %0")
2125 (define_insn "embmedany_textlo"
2126 [(set (match_operand:DI 0 "register_operand" "=r")
2127 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2128 (match_operand:DI 2 "text_segment_operand" "")))]
2129 "TARGET_CM_EMBMEDANY"
2130 "or\t%1, %%lo(%a2), %0")
2132 ;; Now some patterns to help reload out a bit.
2133 (define_expand "reload_indi"
2134 [(parallel [(match_operand:DI 0 "register_operand" "=r")
2135 (match_operand:DI 1 "immediate_operand" "")
2136 (match_operand:TI 2 "register_operand" "=&r")])]
2138 || TARGET_CM_EMBMEDANY)
2141 sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
2145 (define_expand "reload_outdi"
2146 [(parallel [(match_operand:DI 0 "register_operand" "=r")
2147 (match_operand:DI 1 "immediate_operand" "")
2148 (match_operand:TI 2 "register_operand" "=&r")])]
2150 || TARGET_CM_EMBMEDANY)
2153 sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
2157 ;; Split up putting CONSTs and REGs into DI regs when !arch64
2159 [(set (match_operand:DI 0 "register_operand" "")
2160 (match_operand:DI 1 "const_int_operand" ""))]
2161 "! TARGET_ARCH64 && reload_completed"
2162 [(clobber (const_int 0))]
2164 #if HOST_BITS_PER_WIDE_INT == 32
2165 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
2166 (INTVAL (operands[1]) < 0) ?
2169 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2172 unsigned int low, high;
2174 low = trunc_int_for_mode (INTVAL (operands[1]), SImode);
2175 high = trunc_int_for_mode (INTVAL (operands[1]) >> 32, SImode);
2176 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), GEN_INT (high)));
2178 /* Slick... but this trick loses if this subreg constant part
2179 can be done in one insn. */
2181 && ! SPARC_SETHI32_P (high)
2182 && ! SPARC_SIMM13_P (high))
2183 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2184 gen_highpart (SImode, operands[0])));
2186 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), GEN_INT (low)));
2192 [(set (match_operand:DI 0 "register_operand" "")
2193 (match_operand:DI 1 "const_double_operand" ""))]
2197 && ((GET_CODE (operands[0]) == REG
2198 && REGNO (operands[0]) < 32)
2199 || (GET_CODE (operands[0]) == SUBREG
2200 && GET_CODE (SUBREG_REG (operands[0])) == REG
2201 && REGNO (SUBREG_REG (operands[0])) < 32))))"
2202 [(clobber (const_int 0))]
2204 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
2205 GEN_INT (CONST_DOUBLE_HIGH (operands[1]))));
2207 /* Slick... but this trick loses if this subreg constant part
2208 can be done in one insn. */
2209 if (CONST_DOUBLE_LOW (operands[1]) == CONST_DOUBLE_HIGH (operands[1])
2210 && ! SPARC_SETHI32_P (CONST_DOUBLE_HIGH (operands[1]))
2211 && ! SPARC_SIMM13_P (CONST_DOUBLE_HIGH (operands[1])))
2213 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2214 gen_highpart (SImode, operands[0])));
2218 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2219 GEN_INT (CONST_DOUBLE_LOW (operands[1]))));
2225 [(set (match_operand:DI 0 "register_operand" "")
2226 (match_operand:DI 1 "register_operand" ""))]
2230 && ((GET_CODE (operands[0]) == REG
2231 && REGNO (operands[0]) < 32)
2232 || (GET_CODE (operands[0]) == SUBREG
2233 && GET_CODE (SUBREG_REG (operands[0])) == REG
2234 && REGNO (SUBREG_REG (operands[0])) < 32))))"
2235 [(clobber (const_int 0))]
2237 rtx set_dest = operands[0];
2238 rtx set_src = operands[1];
2242 dest1 = gen_highpart (SImode, set_dest);
2243 dest2 = gen_lowpart (SImode, set_dest);
2244 src1 = gen_highpart (SImode, set_src);
2245 src2 = gen_lowpart (SImode, set_src);
2247 /* Now emit using the real source and destination we found, swapping
2248 the order if we detect overlap. */
2249 if (reg_overlap_mentioned_p (dest1, src2))
2251 emit_insn (gen_movsi (dest2, src2));
2252 emit_insn (gen_movsi (dest1, src1));
2256 emit_insn (gen_movsi (dest1, src1));
2257 emit_insn (gen_movsi (dest2, src2));
2262 ;; Now handle the cases of memory moves from/to non-even
2263 ;; DI mode register pairs.
2265 [(set (match_operand:DI 0 "register_operand" "")
2266 (match_operand:DI 1 "memory_operand" ""))]
2269 && sparc_splitdi_legitimate (operands[0], operands[1]))"
2270 [(clobber (const_int 0))]
2272 rtx word0 = adjust_address (operands[1], SImode, 0);
2273 rtx word1 = adjust_address (operands[1], SImode, 4);
2274 rtx high_part = gen_highpart (SImode, operands[0]);
2275 rtx low_part = gen_lowpart (SImode, operands[0]);
2277 if (reg_overlap_mentioned_p (high_part, word1))
2279 emit_insn (gen_movsi (low_part, word1));
2280 emit_insn (gen_movsi (high_part, word0));
2284 emit_insn (gen_movsi (high_part, word0));
2285 emit_insn (gen_movsi (low_part, word1));
2291 [(set (match_operand:DI 0 "memory_operand" "")
2292 (match_operand:DI 1 "register_operand" ""))]
2295 && sparc_splitdi_legitimate (operands[1], operands[0]))"
2296 [(clobber (const_int 0))]
2298 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0),
2299 gen_highpart (SImode, operands[1])));
2300 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4),
2301 gen_lowpart (SImode, operands[1])));
2306 [(set (match_operand:DI 0 "memory_operand" "")
2307 (match_operand:DI 1 "const_zero_operand" ""))]
2311 && ! mem_min_alignment (operands[0], 8)))
2312 && offsettable_memref_p (operands[0])"
2313 [(clobber (const_int 0))]
2315 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0), const0_rtx));
2316 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4), const0_rtx));
2321 ;; Floating point and vector move instructions
2323 ;; We don't define V1SI because SI should work just fine.
2324 (define_mode_macro V32 [SF V2HI V4QI])
2326 ;; Yes, you guessed it right, the former movsf expander.
2327 (define_expand "mov<V32:mode>"
2328 [(set (match_operand:V32 0 "nonimmediate_operand" "")
2329 (match_operand:V32 1 "general_operand" ""))]
2330 "<V32:MODE>mode == SFmode || TARGET_VIS"
2332 if (sparc_expand_move (<V32:MODE>mode, operands))
2336 (define_insn "*movsf_insn"
2337 [(set (match_operand:V32 0 "nonimmediate_operand" "=d,f,*r,*r,*r,f,*r,m,m")
2338 (match_operand:V32 1 "input_operand" "GY,f,*rRY,Q,S,m,m,f,*rGY"))]
2340 && (register_operand (operands[0], <V32:MODE>mode)
2341 || register_or_zero_operand (operands[1], <V32:MODE>mode))"
2343 if (GET_CODE (operands[1]) == CONST_DOUBLE
2344 && (which_alternative == 2
2345 || which_alternative == 3
2346 || which_alternative == 4))
2351 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2352 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2353 operands[1] = GEN_INT (i);
2356 switch (which_alternative)
2359 return "fzeros\t%0";
2361 return "fmovs\t%1, %0";
2363 return "mov\t%1, %0";
2365 return "sethi\t%%hi(%a1), %0";
2370 return "ld\t%1, %0";
2373 return "st\t%r1, %0";
2378 [(set_attr "type" "fga,fpmove,*,*,*,fpload,load,fpstore,store")])
2380 ;; Exactly the same as above, except that all `f' cases are deleted.
2381 ;; This is necessary to prevent reload from ever trying to use a `f' reg
2384 (define_insn "*movsf_insn_no_fpu"
2385 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r,r,m")
2386 (match_operand:SF 1 "input_operand" "rR,Q,S,m,rG"))]
2388 && (register_operand (operands[0], SFmode)
2389 || register_or_zero_operand (operands[1], SFmode))"
2391 if (GET_CODE (operands[1]) == CONST_DOUBLE
2392 && (which_alternative == 0
2393 || which_alternative == 1
2394 || which_alternative == 2))
2399 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2400 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2401 operands[1] = GEN_INT (i);
2404 switch (which_alternative)
2407 return "mov\t%1, %0";
2409 return "sethi\t%%hi(%a1), %0";
2413 return "ld\t%1, %0";
2415 return "st\t%r1, %0";
2420 [(set_attr "type" "*,*,*,load,store")])
2422 ;; The following 3 patterns build SFmode constants in integer registers.
2424 (define_insn "*movsf_lo_sum"
2425 [(set (match_operand:SF 0 "register_operand" "=r")
2426 (lo_sum:SF (match_operand:SF 1 "register_operand" "r")
2427 (match_operand:SF 2 "fp_const_high_losum_operand" "S")))]
2433 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[2]);
2434 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2435 operands[2] = GEN_INT (i);
2436 return "or\t%1, %%lo(%a2), %0";
2439 (define_insn "*movsf_high"
2440 [(set (match_operand:SF 0 "register_operand" "=r")
2441 (high:SF (match_operand:SF 1 "fp_const_high_losum_operand" "S")))]
2447 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2448 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2449 operands[1] = GEN_INT (i);
2450 return "sethi\t%%hi(%1), %0";
2454 [(set (match_operand:SF 0 "register_operand" "")
2455 (match_operand:SF 1 "fp_const_high_losum_operand" ""))]
2456 "REG_P (operands[0]) && REGNO (operands[0]) < 32"
2457 [(set (match_dup 0) (high:SF (match_dup 1)))
2458 (set (match_dup 0) (lo_sum:SF (match_dup 0) (match_dup 1)))])
2460 (define_mode_macro V64 [DF V2SI V4HI V8QI])
2462 ;; Yes, you again guessed it right, the former movdf expander.
2463 (define_expand "mov<V64:mode>"
2464 [(set (match_operand:V64 0 "nonimmediate_operand" "")
2465 (match_operand:V64 1 "general_operand" ""))]
2466 "<V64:MODE>mode == DFmode || TARGET_VIS"
2468 if (sparc_expand_move (<V64:MODE>mode, operands))
2472 ;; Be careful, fmovd does not exist when !v9.
2473 (define_insn "*movdf_insn_sp32"
2474 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,W,U,T,o,e,*r,o,e,o")
2475 (match_operand:DF 1 "input_operand" "W#F,e,T,U,G,e,*rFo,*r,o#F,e"))]
2478 && (register_operand (operands[0], DFmode)
2479 || register_or_zero_operand (operands[1], DFmode))"
2491 [(set_attr "type" "fpload,fpstore,load,store,*,*,*,*,*,*")
2492 (set_attr "length" "*,*,*,*,2,2,2,2,2,2")])
2494 (define_insn "*movdf_insn_sp32_no_fpu"
2495 [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,o,r,o")
2496 (match_operand:DF 1 "input_operand" "T,U,G,ro,r"))]
2499 && (register_operand (operands[0], DFmode)
2500 || register_or_zero_operand (operands[1], DFmode))"
2507 [(set_attr "type" "load,store,*,*,*")
2508 (set_attr "length" "*,*,2,2,2")])
2510 ;; We have available v9 double floats but not 64-bit integer registers.
2511 (define_insn "*movdf_insn_sp32_v9"
2512 [(set (match_operand:V64 0 "nonimmediate_operand" "=b,e,e,T,W,U,T,f,*r,o")
2513 (match_operand:V64 1 "input_operand" "GY,e,W#F,GY,e,T,U,o#F,*roGYF,*rGYf"))]
2517 && (register_operand (operands[0], <V64:MODE>mode)
2518 || register_or_zero_operand (operands[1], <V64:MODE>mode))"
2530 [(set_attr "type" "fga,fpmove,load,store,store,load,store,*,*,*")
2531 (set_attr "length" "*,*,*,*,*,*,*,2,2,2")
2532 (set_attr "fptype" "double,double,*,*,*,*,*,*,*,*")])
2534 (define_insn "*movdf_insn_sp32_v9_no_fpu"
2535 [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,T,r,o")
2536 (match_operand:DF 1 "input_operand" "T,U,G,ro,rG"))]
2540 && (register_operand (operands[0], DFmode)
2541 || register_or_zero_operand (operands[1], DFmode))"
2548 [(set_attr "type" "load,store,store,*,*")
2549 (set_attr "length" "*,*,*,2,2")])
2551 ;; We have available both v9 double floats and 64-bit integer registers.
2552 (define_insn "*movdf_insn_sp64"
2553 [(set (match_operand:V64 0 "nonimmediate_operand" "=b,e,e,W,*r,*r,m,*r")
2554 (match_operand:V64 1 "input_operand" "GY,e,W#F,e,*rGY,m,*rGY,F"))]
2557 && (register_operand (operands[0], <V64:MODE>mode)
2558 || register_or_zero_operand (operands[1], <V64:MODE>mode))"
2568 [(set_attr "type" "fga,fpmove,load,store,*,load,store,*")
2569 (set_attr "length" "*,*,*,*,*,*,*,2")
2570 (set_attr "fptype" "double,double,*,*,*,*,*,*")])
2572 (define_insn "*movdf_insn_sp64_no_fpu"
2573 [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m")
2574 (match_operand:DF 1 "input_operand" "r,m,rG"))]
2577 && (register_operand (operands[0], DFmode)
2578 || register_or_zero_operand (operands[1], DFmode))"
2583 [(set_attr "type" "*,load,store")])
2585 ;; This pattern build DFmode constants in integer registers.
2587 [(set (match_operand:DF 0 "register_operand" "")
2588 (match_operand:DF 1 "const_double_operand" ""))]
2590 && (GET_CODE (operands[0]) == REG
2591 && REGNO (operands[0]) < 32)
2592 && ! const_zero_operand(operands[1], DFmode)
2593 && reload_completed"
2594 [(clobber (const_int 0))]
2599 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2600 REAL_VALUE_TO_TARGET_DOUBLE (r, l);
2601 operands[0] = gen_rtx_raw_REG (DImode, REGNO (operands[0]));
2605 #if HOST_BITS_PER_WIDE_INT == 32
2610 val = ((HOST_WIDE_INT)(unsigned long)l[1] |
2611 ((HOST_WIDE_INT)(unsigned long)l[0] << 32));
2612 emit_insn (gen_movdi (operands[0], gen_int_mode (val, DImode)));
2617 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
2618 gen_int_mode (l[0], SImode)));
2620 /* Slick... but this trick loses if this subreg constant part
2621 can be done in one insn. */
2623 && ! SPARC_SETHI32_P (l[0])
2624 && ! SPARC_SIMM13_P (l[0]))
2626 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2627 gen_highpart (SImode, operands[0])));
2631 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2632 gen_int_mode (l[1], SImode)));
2638 ;; Ok, now the splits to handle all the multi insn and
2639 ;; mis-aligned memory address cases.
2640 ;; In these splits please take note that we must be
2641 ;; careful when V9 but not ARCH64 because the integer
2642 ;; register DFmode cases must be handled.
2644 [(set (match_operand:V64 0 "register_operand" "")
2645 (match_operand:V64 1 "register_operand" ""))]
2648 && ((GET_CODE (operands[0]) == REG
2649 && REGNO (operands[0]) < 32)
2650 || (GET_CODE (operands[0]) == SUBREG
2651 && GET_CODE (SUBREG_REG (operands[0])) == REG
2652 && REGNO (SUBREG_REG (operands[0])) < 32))))
2653 && reload_completed"
2654 [(clobber (const_int 0))]
2656 rtx set_dest = operands[0];
2657 rtx set_src = operands[1];
2660 enum machine_mode half_mode;
2662 /* We can be expanded for DFmode or integral vector modes. */
2663 if (<V64:MODE>mode == DFmode)
2668 dest1 = gen_highpart (half_mode, set_dest);
2669 dest2 = gen_lowpart (half_mode, set_dest);
2670 src1 = gen_highpart (half_mode, set_src);
2671 src2 = gen_lowpart (half_mode, set_src);
2673 /* Now emit using the real source and destination we found, swapping
2674 the order if we detect overlap. */
2675 if (reg_overlap_mentioned_p (dest1, src2))
2677 emit_move_insn_1 (dest2, src2);
2678 emit_move_insn_1 (dest1, src1);
2682 emit_move_insn_1 (dest1, src1);
2683 emit_move_insn_1 (dest2, src2);
2689 [(set (match_operand:V64 0 "register_operand" "")
2690 (match_operand:V64 1 "memory_operand" ""))]
2693 && (((REGNO (operands[0]) % 2) != 0)
2694 || ! mem_min_alignment (operands[1], 8))
2695 && offsettable_memref_p (operands[1])"
2696 [(clobber (const_int 0))]
2698 enum machine_mode half_mode;
2701 /* We can be expanded for DFmode or integral vector modes. */
2702 if (<V64:MODE>mode == DFmode)
2707 word0 = adjust_address (operands[1], half_mode, 0);
2708 word1 = adjust_address (operands[1], half_mode, 4);
2710 if (reg_overlap_mentioned_p (gen_highpart (half_mode, operands[0]), word1))
2712 emit_move_insn_1 (gen_lowpart (half_mode, operands[0]), word1);
2713 emit_move_insn_1 (gen_highpart (half_mode, operands[0]), word0);
2717 emit_move_insn_1 (gen_highpart (half_mode, operands[0]), word0);
2718 emit_move_insn_1 (gen_lowpart (half_mode, operands[0]), word1);
2724 [(set (match_operand:V64 0 "memory_operand" "")
2725 (match_operand:V64 1 "register_operand" ""))]
2728 && (((REGNO (operands[1]) % 2) != 0)
2729 || ! mem_min_alignment (operands[0], 8))
2730 && offsettable_memref_p (operands[0])"
2731 [(clobber (const_int 0))]
2733 enum machine_mode half_mode;
2736 /* We can be expanded for DFmode or integral vector modes. */
2737 if (<V64:MODE>mode == DFmode)
2742 word0 = adjust_address (operands[0], half_mode, 0);
2743 word1 = adjust_address (operands[0], half_mode, 4);
2745 emit_move_insn_1 (word0, gen_highpart (half_mode, operands[1]));
2746 emit_move_insn_1 (word1, gen_lowpart (half_mode, operands[1]));
2751 [(set (match_operand:V64 0 "memory_operand" "")
2752 (match_operand:V64 1 "const_zero_operand" ""))]
2756 && ! mem_min_alignment (operands[0], 8)))
2757 && offsettable_memref_p (operands[0])"
2758 [(clobber (const_int 0))]
2760 enum machine_mode half_mode;
2763 /* We can be expanded for DFmode or integral vector modes. */
2764 if (<V64:MODE>mode == DFmode)
2769 dest1 = adjust_address (operands[0], half_mode, 0);
2770 dest2 = adjust_address (operands[0], half_mode, 4);
2772 emit_move_insn_1 (dest1, CONST0_RTX (half_mode));
2773 emit_move_insn_1 (dest2, CONST0_RTX (half_mode));
2778 [(set (match_operand:V64 0 "register_operand" "")
2779 (match_operand:V64 1 "const_zero_operand" ""))]
2782 && ((GET_CODE (operands[0]) == REG
2783 && REGNO (operands[0]) < 32)
2784 || (GET_CODE (operands[0]) == SUBREG
2785 && GET_CODE (SUBREG_REG (operands[0])) == REG
2786 && REGNO (SUBREG_REG (operands[0])) < 32))"
2787 [(clobber (const_int 0))]
2789 enum machine_mode half_mode;
2790 rtx set_dest = operands[0];
2793 /* We can be expanded for DFmode or integral vector modes. */
2794 if (<V64:MODE>mode == DFmode)
2799 dest1 = gen_highpart (half_mode, set_dest);
2800 dest2 = gen_lowpart (half_mode, set_dest);
2801 emit_move_insn_1 (dest1, CONST0_RTX (half_mode));
2802 emit_move_insn_1 (dest2, CONST0_RTX (half_mode));
2806 (define_expand "movtf"
2807 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2808 (match_operand:TF 1 "general_operand" ""))]
2811 if (sparc_expand_move (TFmode, operands))
2815 (define_insn "*movtf_insn_sp32"
2816 [(set (match_operand:TF 0 "nonimmediate_operand" "=b,e,o,U,r")
2817 (match_operand:TF 1 "input_operand" "G,oe,GeUr,o,roG"))]
2820 && (register_operand (operands[0], TFmode)
2821 || register_or_zero_operand (operands[1], TFmode))"
2823 [(set_attr "length" "4")])
2825 ;; Exactly the same as above, except that all `e' cases are deleted.
2826 ;; This is necessary to prevent reload from ever trying to use a `e' reg
2829 (define_insn "*movtf_insn_sp32_no_fpu"
2830 [(set (match_operand:TF 0 "nonimmediate_operand" "=o,U,o,r,o")
2831 (match_operand:TF 1 "input_operand" "G,o,U,roG,r"))]
2834 && (register_operand (operands[0], TFmode)
2835 || register_or_zero_operand (operands[1], TFmode))"
2837 [(set_attr "length" "4")])
2839 (define_insn "*movtf_insn_sp64"
2840 [(set (match_operand:TF 0 "nonimmediate_operand" "=b,e,o,r")
2841 (match_operand:TF 1 "input_operand" "G,oe,Ger,roG"))]
2844 && ! TARGET_HARD_QUAD
2845 && (register_operand (operands[0], TFmode)
2846 || register_or_zero_operand (operands[1], TFmode))"
2848 [(set_attr "length" "2")])
2850 (define_insn "*movtf_insn_sp64_hq"
2851 [(set (match_operand:TF 0 "nonimmediate_operand" "=b,e,e,m,o,r")
2852 (match_operand:TF 1 "input_operand" "G,e,m,e,rG,roG"))]
2856 && (register_operand (operands[0], TFmode)
2857 || register_or_zero_operand (operands[1], TFmode))"
2865 [(set_attr "type" "*,fpmove,fpload,fpstore,*,*")
2866 (set_attr "length" "2,*,*,*,2,2")])
2868 (define_insn "*movtf_insn_sp64_no_fpu"
2869 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o")
2870 (match_operand:TF 1 "input_operand" "orG,rG"))]
2873 && (register_operand (operands[0], TFmode)
2874 || register_or_zero_operand (operands[1], TFmode))"
2876 [(set_attr "length" "2")])
2878 ;; Now all the splits to handle multi-insn TF mode moves.
2880 [(set (match_operand:TF 0 "register_operand" "")
2881 (match_operand:TF 1 "register_operand" ""))]
2885 && ! TARGET_HARD_QUAD)
2886 || ! fp_register_operand (operands[0], TFmode))"
2887 [(clobber (const_int 0))]
2889 rtx set_dest = operands[0];
2890 rtx set_src = operands[1];
2894 dest1 = gen_df_reg (set_dest, 0);
2895 dest2 = gen_df_reg (set_dest, 1);
2896 src1 = gen_df_reg (set_src, 0);
2897 src2 = gen_df_reg (set_src, 1);
2899 /* Now emit using the real source and destination we found, swapping
2900 the order if we detect overlap. */
2901 if (reg_overlap_mentioned_p (dest1, src2))
2903 emit_insn (gen_movdf (dest2, src2));
2904 emit_insn (gen_movdf (dest1, src1));
2908 emit_insn (gen_movdf (dest1, src1));
2909 emit_insn (gen_movdf (dest2, src2));
2915 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2916 (match_operand:TF 1 "const_zero_operand" ""))]
2918 [(clobber (const_int 0))]
2920 rtx set_dest = operands[0];
2923 switch (GET_CODE (set_dest))
2926 dest1 = gen_df_reg (set_dest, 0);
2927 dest2 = gen_df_reg (set_dest, 1);
2930 dest1 = adjust_address (set_dest, DFmode, 0);
2931 dest2 = adjust_address (set_dest, DFmode, 8);
2937 emit_insn (gen_movdf (dest1, CONST0_RTX (DFmode)));
2938 emit_insn (gen_movdf (dest2, CONST0_RTX (DFmode)));
2943 [(set (match_operand:TF 0 "register_operand" "")
2944 (match_operand:TF 1 "memory_operand" ""))]
2946 && offsettable_memref_p (operands[1])
2948 || ! TARGET_HARD_QUAD
2949 || ! fp_register_operand (operands[0], TFmode)))"
2950 [(clobber (const_int 0))]
2952 rtx word0 = adjust_address (operands[1], DFmode, 0);
2953 rtx word1 = adjust_address (operands[1], DFmode, 8);
2954 rtx set_dest, dest1, dest2;
2956 set_dest = operands[0];
2958 dest1 = gen_df_reg (set_dest, 0);
2959 dest2 = gen_df_reg (set_dest, 1);
2961 /* Now output, ordering such that we don't clobber any registers
2962 mentioned in the address. */
2963 if (reg_overlap_mentioned_p (dest1, word1))
2966 emit_insn (gen_movdf (dest2, word1));
2967 emit_insn (gen_movdf (dest1, word0));
2971 emit_insn (gen_movdf (dest1, word0));
2972 emit_insn (gen_movdf (dest2, word1));
2978 [(set (match_operand:TF 0 "memory_operand" "")
2979 (match_operand:TF 1 "register_operand" ""))]
2981 && offsettable_memref_p (operands[0])
2983 || ! TARGET_HARD_QUAD
2984 || ! fp_register_operand (operands[1], TFmode)))"
2985 [(clobber (const_int 0))]
2987 rtx set_src = operands[1];
2989 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 0),
2990 gen_df_reg (set_src, 0)));
2991 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 8),
2992 gen_df_reg (set_src, 1)));
2997 ;; SPARC-V9 conditional move instructions.
2999 ;; We can handle larger constants here for some flavors, but for now we keep
3000 ;; it simple and only allow those constants supported by all flavors.
3001 ;; Note that emit_conditional_move canonicalizes operands 2,3 so that operand
3002 ;; 3 contains the constant if one is present, but we handle either for
3003 ;; generality (sparc.c puts a constant in operand 2).
3005 (define_expand "movqicc"
3006 [(set (match_operand:QI 0 "register_operand" "")
3007 (if_then_else:QI (match_operand 1 "comparison_operator" "")
3008 (match_operand:QI 2 "arith10_operand" "")
3009 (match_operand:QI 3 "arith10_operand" "")))]
3012 enum rtx_code code = GET_CODE (operands[1]);
3014 if (GET_MODE (sparc_compare_op0) == DImode
3018 if (sparc_compare_op1 == const0_rtx
3019 && GET_CODE (sparc_compare_op0) == REG
3020 && GET_MODE (sparc_compare_op0) == DImode
3021 && v9_regcmp_p (code))
3023 operands[1] = gen_rtx_fmt_ee (code, DImode,
3024 sparc_compare_op0, sparc_compare_op1);
3028 rtx cc_reg = gen_compare_reg (code,
3029 sparc_compare_op0, sparc_compare_op1);
3030 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3034 (define_expand "movhicc"
3035 [(set (match_operand:HI 0 "register_operand" "")
3036 (if_then_else:HI (match_operand 1 "comparison_operator" "")
3037 (match_operand:HI 2 "arith10_operand" "")
3038 (match_operand:HI 3 "arith10_operand" "")))]
3041 enum rtx_code code = GET_CODE (operands[1]);
3043 if (GET_MODE (sparc_compare_op0) == DImode
3047 if (sparc_compare_op1 == const0_rtx
3048 && GET_CODE (sparc_compare_op0) == REG
3049 && GET_MODE (sparc_compare_op0) == DImode
3050 && v9_regcmp_p (code))
3052 operands[1] = gen_rtx_fmt_ee (code, DImode,
3053 sparc_compare_op0, sparc_compare_op1);
3057 rtx cc_reg = gen_compare_reg (code,
3058 sparc_compare_op0, sparc_compare_op1);
3059 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3063 (define_expand "movsicc"
3064 [(set (match_operand:SI 0 "register_operand" "")
3065 (if_then_else:SI (match_operand 1 "comparison_operator" "")
3066 (match_operand:SI 2 "arith10_operand" "")
3067 (match_operand:SI 3 "arith10_operand" "")))]
3070 enum rtx_code code = GET_CODE (operands[1]);
3071 enum machine_mode op0_mode = GET_MODE (sparc_compare_op0);
3073 if (sparc_compare_op1 == const0_rtx
3074 && GET_CODE (sparc_compare_op0) == REG
3075 && (TARGET_ARCH64 && op0_mode == DImode && v9_regcmp_p (code)))
3077 operands[1] = gen_rtx_fmt_ee (code, op0_mode,
3078 sparc_compare_op0, sparc_compare_op1);
3082 rtx cc_reg = gen_compare_reg (code,
3083 sparc_compare_op0, sparc_compare_op1);
3084 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg),
3085 cc_reg, const0_rtx);
3089 (define_expand "movdicc"
3090 [(set (match_operand:DI 0 "register_operand" "")
3091 (if_then_else:DI (match_operand 1 "comparison_operator" "")
3092 (match_operand:DI 2 "arith10_operand" "")
3093 (match_operand:DI 3 "arith10_operand" "")))]
3096 enum rtx_code code = GET_CODE (operands[1]);
3098 if (sparc_compare_op1 == const0_rtx
3099 && GET_CODE (sparc_compare_op0) == REG
3100 && GET_MODE (sparc_compare_op0) == DImode
3101 && v9_regcmp_p (code))
3103 operands[1] = gen_rtx_fmt_ee (code, DImode,
3104 sparc_compare_op0, sparc_compare_op1);
3108 rtx cc_reg = gen_compare_reg (code,
3109 sparc_compare_op0, sparc_compare_op1);
3110 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg),
3111 cc_reg, const0_rtx);
3115 (define_expand "movsfcc"
3116 [(set (match_operand:SF 0 "register_operand" "")
3117 (if_then_else:SF (match_operand 1 "comparison_operator" "")
3118 (match_operand:SF 2 "register_operand" "")
3119 (match_operand:SF 3 "register_operand" "")))]
3120 "TARGET_V9 && TARGET_FPU"
3122 enum rtx_code code = GET_CODE (operands[1]);
3124 if (GET_MODE (sparc_compare_op0) == DImode
3128 if (sparc_compare_op1 == const0_rtx
3129 && GET_CODE (sparc_compare_op0) == REG
3130 && GET_MODE (sparc_compare_op0) == DImode
3131 && v9_regcmp_p (code))
3133 operands[1] = gen_rtx_fmt_ee (code, DImode,
3134 sparc_compare_op0, sparc_compare_op1);
3138 rtx cc_reg = gen_compare_reg (code,
3139 sparc_compare_op0, sparc_compare_op1);
3140 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3144 (define_expand "movdfcc"
3145 [(set (match_operand:DF 0 "register_operand" "")
3146 (if_then_else:DF (match_operand 1 "comparison_operator" "")
3147 (match_operand:DF 2 "register_operand" "")
3148 (match_operand:DF 3 "register_operand" "")))]
3149 "TARGET_V9 && TARGET_FPU"
3151 enum rtx_code code = GET_CODE (operands[1]);
3153 if (GET_MODE (sparc_compare_op0) == DImode
3157 if (sparc_compare_op1 == const0_rtx
3158 && GET_CODE (sparc_compare_op0) == REG
3159 && GET_MODE (sparc_compare_op0) == DImode
3160 && v9_regcmp_p (code))
3162 operands[1] = gen_rtx_fmt_ee (code, DImode,
3163 sparc_compare_op0, sparc_compare_op1);
3167 rtx cc_reg = gen_compare_reg (code,
3168 sparc_compare_op0, sparc_compare_op1);
3169 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3173 (define_expand "movtfcc"
3174 [(set (match_operand:TF 0 "register_operand" "")
3175 (if_then_else:TF (match_operand 1 "comparison_operator" "")
3176 (match_operand:TF 2 "register_operand" "")
3177 (match_operand:TF 3 "register_operand" "")))]
3178 "TARGET_V9 && TARGET_FPU"
3180 enum rtx_code code = GET_CODE (operands[1]);
3182 if (GET_MODE (sparc_compare_op0) == DImode
3186 if (sparc_compare_op1 == const0_rtx
3187 && GET_CODE (sparc_compare_op0) == REG
3188 && GET_MODE (sparc_compare_op0) == DImode
3189 && v9_regcmp_p (code))
3191 operands[1] = gen_rtx_fmt_ee (code, DImode,
3192 sparc_compare_op0, sparc_compare_op1);
3196 rtx cc_reg = gen_compare_reg (code,
3197 sparc_compare_op0, sparc_compare_op1);
3198 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3202 ;; Conditional move define_insns.
3204 (define_insn "*movqi_cc_sp64"
3205 [(set (match_operand:QI 0 "register_operand" "=r,r")
3206 (if_then_else:QI (match_operator 1 "comparison_operator"
3207 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
3209 (match_operand:QI 3 "arith11_operand" "rL,0")
3210 (match_operand:QI 4 "arith11_operand" "0,rL")))]
3214 mov%c1\t%x2, %4, %0"
3215 [(set_attr "type" "cmove")])
3217 (define_insn "*movhi_cc_sp64"
3218 [(set (match_operand:HI 0 "register_operand" "=r,r")
3219 (if_then_else:HI (match_operator 1 "comparison_operator"
3220 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
3222 (match_operand:HI 3 "arith11_operand" "rL,0")
3223 (match_operand:HI 4 "arith11_operand" "0,rL")))]
3227 mov%c1\t%x2, %4, %0"
3228 [(set_attr "type" "cmove")])
3230 (define_insn "*movsi_cc_sp64"
3231 [(set (match_operand:SI 0 "register_operand" "=r,r")
3232 (if_then_else:SI (match_operator 1 "comparison_operator"
3233 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
3235 (match_operand:SI 3 "arith11_operand" "rL,0")
3236 (match_operand:SI 4 "arith11_operand" "0,rL")))]
3240 mov%c1\t%x2, %4, %0"
3241 [(set_attr "type" "cmove")])
3243 (define_insn "*movdi_cc_sp64"
3244 [(set (match_operand:DI 0 "register_operand" "=r,r")
3245 (if_then_else:DI (match_operator 1 "comparison_operator"
3246 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
3248 (match_operand:DI 3 "arith11_operand" "rL,0")
3249 (match_operand:DI 4 "arith11_operand" "0,rL")))]
3253 mov%c1\t%x2, %4, %0"
3254 [(set_attr "type" "cmove")])
3256 (define_insn "*movdi_cc_sp64_trunc"
3257 [(set (match_operand:SI 0 "register_operand" "=r,r")
3258 (if_then_else:SI (match_operator 1 "comparison_operator"
3259 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
3261 (match_operand:SI 3 "arith11_operand" "rL,0")
3262 (match_operand:SI 4 "arith11_operand" "0,rL")))]
3266 mov%c1\t%x2, %4, %0"
3267 [(set_attr "type" "cmove")])
3269 (define_insn "*movsf_cc_sp64"
3270 [(set (match_operand:SF 0 "register_operand" "=f,f")
3271 (if_then_else:SF (match_operator 1 "comparison_operator"
3272 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
3274 (match_operand:SF 3 "register_operand" "f,0")
3275 (match_operand:SF 4 "register_operand" "0,f")))]
3276 "TARGET_V9 && TARGET_FPU"
3278 fmovs%C1\t%x2, %3, %0
3279 fmovs%c1\t%x2, %4, %0"
3280 [(set_attr "type" "fpcmove")])
3282 (define_insn "movdf_cc_sp64"
3283 [(set (match_operand:DF 0 "register_operand" "=e,e")
3284 (if_then_else:DF (match_operator 1 "comparison_operator"
3285 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
3287 (match_operand:DF 3 "register_operand" "e,0")
3288 (match_operand:DF 4 "register_operand" "0,e")))]
3289 "TARGET_V9 && TARGET_FPU"
3291 fmovd%C1\t%x2, %3, %0
3292 fmovd%c1\t%x2, %4, %0"
3293 [(set_attr "type" "fpcmove")
3294 (set_attr "fptype" "double")])
3296 (define_insn "*movtf_cc_hq_sp64"
3297 [(set (match_operand:TF 0 "register_operand" "=e,e")
3298 (if_then_else:TF (match_operator 1 "comparison_operator"
3299 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
3301 (match_operand:TF 3 "register_operand" "e,0")
3302 (match_operand:TF 4 "register_operand" "0,e")))]
3303 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
3305 fmovq%C1\t%x2, %3, %0
3306 fmovq%c1\t%x2, %4, %0"
3307 [(set_attr "type" "fpcmove")])
3309 (define_insn_and_split "*movtf_cc_sp64"
3310 [(set (match_operand:TF 0 "register_operand" "=e,e")
3311 (if_then_else:TF (match_operator 1 "comparison_operator"
3312 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
3314 (match_operand:TF 3 "register_operand" "e,0")
3315 (match_operand:TF 4 "register_operand" "0,e")))]
3316 "TARGET_V9 && TARGET_FPU && !TARGET_HARD_QUAD"
3318 "&& reload_completed"
3319 [(clobber (const_int 0))]
3321 rtx set_dest = operands[0];
3322 rtx set_srca = operands[3];
3323 rtx set_srcb = operands[4];
3324 int third = rtx_equal_p (set_dest, set_srca);
3326 rtx srca1, srca2, srcb1, srcb2;
3328 dest1 = gen_df_reg (set_dest, 0);
3329 dest2 = gen_df_reg (set_dest, 1);
3330 srca1 = gen_df_reg (set_srca, 0);
3331 srca2 = gen_df_reg (set_srca, 1);
3332 srcb1 = gen_df_reg (set_srcb, 0);
3333 srcb2 = gen_df_reg (set_srcb, 1);
3335 /* Now emit using the real source and destination we found, swapping
3336 the order if we detect overlap. */
3337 if ((third && reg_overlap_mentioned_p (dest1, srcb2))
3338 || (!third && reg_overlap_mentioned_p (dest1, srca2)))
3340 emit_insn (gen_movdf_cc_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
3341 emit_insn (gen_movdf_cc_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
3345 emit_insn (gen_movdf_cc_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
3346 emit_insn (gen_movdf_cc_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
3350 [(set_attr "length" "2")])
3352 (define_insn "*movqi_cc_reg_sp64"
3353 [(set (match_operand:QI 0 "register_operand" "=r,r")
3354 (if_then_else:QI (match_operator 1 "v9_register_compare_operator"
3355 [(match_operand:DI 2 "register_operand" "r,r")
3357 (match_operand:QI 3 "arith10_operand" "rM,0")
3358 (match_operand:QI 4 "arith10_operand" "0,rM")))]
3361 movr%D1\t%2, %r3, %0
3362 movr%d1\t%2, %r4, %0"
3363 [(set_attr "type" "cmove")])
3365 (define_insn "*movhi_cc_reg_sp64"
3366 [(set (match_operand:HI 0 "register_operand" "=r,r")
3367 (if_then_else:HI (match_operator 1 "v9_register_compare_operator"
3368 [(match_operand:DI 2 "register_operand" "r,r")
3370 (match_operand:HI 3 "arith10_operand" "rM,0")
3371 (match_operand:HI 4 "arith10_operand" "0,rM")))]
3374 movr%D1\t%2, %r3, %0
3375 movr%d1\t%2, %r4, %0"
3376 [(set_attr "type" "cmove")])
3378 (define_insn "*movsi_cc_reg_sp64"
3379 [(set (match_operand:SI 0 "register_operand" "=r,r")
3380 (if_then_else:SI (match_operator 1 "v9_register_compare_operator"
3381 [(match_operand:DI 2 "register_operand" "r,r")
3383 (match_operand:SI 3 "arith10_operand" "rM,0")
3384 (match_operand:SI 4 "arith10_operand" "0,rM")))]
3387 movr%D1\t%2, %r3, %0
3388 movr%d1\t%2, %r4, %0"
3389 [(set_attr "type" "cmove")])
3391 (define_insn "*movdi_cc_reg_sp64"
3392 [(set (match_operand:DI 0 "register_operand" "=r,r")
3393 (if_then_else:DI (match_operator 1 "v9_register_compare_operator"
3394 [(match_operand:DI 2 "register_operand" "r,r")
3396 (match_operand:DI 3 "arith10_operand" "rM,0")
3397 (match_operand:DI 4 "arith10_operand" "0,rM")))]
3400 movr%D1\t%2, %r3, %0
3401 movr%d1\t%2, %r4, %0"
3402 [(set_attr "type" "cmove")])
3404 (define_insn "*movsf_cc_reg_sp64"
3405 [(set (match_operand:SF 0 "register_operand" "=f,f")
3406 (if_then_else:SF (match_operator 1 "v9_register_compare_operator"
3407 [(match_operand:DI 2 "register_operand" "r,r")
3409 (match_operand:SF 3 "register_operand" "f,0")
3410 (match_operand:SF 4 "register_operand" "0,f")))]
3411 "TARGET_ARCH64 && TARGET_FPU"
3413 fmovrs%D1\t%2, %3, %0
3414 fmovrs%d1\t%2, %4, %0"
3415 [(set_attr "type" "fpcrmove")])
3417 (define_insn "movdf_cc_reg_sp64"
3418 [(set (match_operand:DF 0 "register_operand" "=e,e")
3419 (if_then_else:DF (match_operator 1 "v9_register_compare_operator"
3420 [(match_operand:DI 2 "register_operand" "r,r")
3422 (match_operand:DF 3 "register_operand" "e,0")
3423 (match_operand:DF 4 "register_operand" "0,e")))]
3424 "TARGET_ARCH64 && TARGET_FPU"
3426 fmovrd%D1\t%2, %3, %0
3427 fmovrd%d1\t%2, %4, %0"
3428 [(set_attr "type" "fpcrmove")
3429 (set_attr "fptype" "double")])
3431 (define_insn "*movtf_cc_reg_hq_sp64"
3432 [(set (match_operand:TF 0 "register_operand" "=e,e")
3433 (if_then_else:TF (match_operator 1 "v9_register_compare_operator"
3434 [(match_operand:DI 2 "register_operand" "r,r")
3436 (match_operand:TF 3 "register_operand" "e,0")
3437 (match_operand:TF 4 "register_operand" "0,e")))]
3438 "TARGET_ARCH64 && TARGET_FPU && TARGET_HARD_QUAD"
3440 fmovrq%D1\t%2, %3, %0
3441 fmovrq%d1\t%2, %4, %0"
3442 [(set_attr "type" "fpcrmove")])
3444 (define_insn_and_split "*movtf_cc_reg_sp64"
3445 [(set (match_operand:TF 0 "register_operand" "=e,e")
3446 (if_then_else:TF (match_operator 1 "v9_register_compare_operator"
3447 [(match_operand:DI 2 "register_operand" "r,r")
3449 (match_operand:TF 3 "register_operand" "e,0")
3450 (match_operand:TF 4 "register_operand" "0,e")))]
3451 "TARGET_ARCH64 && TARGET_FPU && ! TARGET_HARD_QUAD"
3453 "&& reload_completed"
3454 [(clobber (const_int 0))]
3456 rtx set_dest = operands[0];
3457 rtx set_srca = operands[3];
3458 rtx set_srcb = operands[4];
3459 int third = rtx_equal_p (set_dest, set_srca);
3461 rtx srca1, srca2, srcb1, srcb2;
3463 dest1 = gen_df_reg (set_dest, 0);
3464 dest2 = gen_df_reg (set_dest, 1);
3465 srca1 = gen_df_reg (set_srca, 0);
3466 srca2 = gen_df_reg (set_srca, 1);
3467 srcb1 = gen_df_reg (set_srcb, 0);
3468 srcb2 = gen_df_reg (set_srcb, 1);
3470 /* Now emit using the real source and destination we found, swapping
3471 the order if we detect overlap. */
3472 if ((third && reg_overlap_mentioned_p (dest1, srcb2))
3473 || (!third && reg_overlap_mentioned_p (dest1, srca2)))
3475 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
3476 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
3480 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
3481 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
3485 [(set_attr "length" "2")])
3488 ;; Zero-extension instructions
3490 ;; These patterns originally accepted general_operands, however, slightly
3491 ;; better code is generated by only accepting register_operands, and then
3492 ;; letting combine generate the ldu[hb] insns.
3494 (define_expand "zero_extendhisi2"
3495 [(set (match_operand:SI 0 "register_operand" "")
3496 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
3499 rtx temp = gen_reg_rtx (SImode);
3500 rtx shift_16 = GEN_INT (16);
3501 int op1_subbyte = 0;
3503 if (GET_CODE (operand1) == SUBREG)
3505 op1_subbyte = SUBREG_BYTE (operand1);
3506 op1_subbyte /= GET_MODE_SIZE (SImode);
3507 op1_subbyte *= GET_MODE_SIZE (SImode);
3508 operand1 = XEXP (operand1, 0);
3511 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3513 emit_insn (gen_lshrsi3 (operand0, temp, shift_16));
3517 (define_insn "*zero_extendhisi2_insn"
3518 [(set (match_operand:SI 0 "register_operand" "=r")
3519 (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
3522 [(set_attr "type" "load")
3523 (set_attr "us3load_type" "3cycle")])
3525 (define_expand "zero_extendqihi2"
3526 [(set (match_operand:HI 0 "register_operand" "")
3527 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
3531 (define_insn "*zero_extendqihi2_insn"
3532 [(set (match_operand:HI 0 "register_operand" "=r,r")
3533 (zero_extend:HI (match_operand:QI 1 "input_operand" "r,m")))]
3534 "GET_CODE (operands[1]) != CONST_INT"
3538 [(set_attr "type" "*,load")
3539 (set_attr "us3load_type" "*,3cycle")])
3541 (define_expand "zero_extendqisi2"
3542 [(set (match_operand:SI 0 "register_operand" "")
3543 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
3547 (define_insn "*zero_extendqisi2_insn"
3548 [(set (match_operand:SI 0 "register_operand" "=r,r")
3549 (zero_extend:SI (match_operand:QI 1 "input_operand" "r,m")))]
3550 "GET_CODE (operands[1]) != CONST_INT"
3554 [(set_attr "type" "*,load")
3555 (set_attr "us3load_type" "*,3cycle")])
3557 (define_expand "zero_extendqidi2"
3558 [(set (match_operand:DI 0 "register_operand" "")
3559 (zero_extend:DI (match_operand:QI 1 "register_operand" "")))]
3563 (define_insn "*zero_extendqidi2_insn"
3564 [(set (match_operand:DI 0 "register_operand" "=r,r")
3565 (zero_extend:DI (match_operand:QI 1 "input_operand" "r,m")))]
3566 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
3570 [(set_attr "type" "*,load")
3571 (set_attr "us3load_type" "*,3cycle")])
3573 (define_expand "zero_extendhidi2"
3574 [(set (match_operand:DI 0 "register_operand" "")
3575 (zero_extend:DI (match_operand:HI 1 "register_operand" "")))]
3578 rtx temp = gen_reg_rtx (DImode);
3579 rtx shift_48 = GEN_INT (48);
3580 int op1_subbyte = 0;
3582 if (GET_CODE (operand1) == SUBREG)
3584 op1_subbyte = SUBREG_BYTE (operand1);
3585 op1_subbyte /= GET_MODE_SIZE (DImode);
3586 op1_subbyte *= GET_MODE_SIZE (DImode);
3587 operand1 = XEXP (operand1, 0);
3590 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
3592 emit_insn (gen_lshrdi3 (operand0, temp, shift_48));
3596 (define_insn "*zero_extendhidi2_insn"
3597 [(set (match_operand:DI 0 "register_operand" "=r")
3598 (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
3601 [(set_attr "type" "load")
3602 (set_attr "us3load_type" "3cycle")])
3604 ;; ??? Write truncdisi pattern using sra?
3606 (define_expand "zero_extendsidi2"
3607 [(set (match_operand:DI 0 "register_operand" "")
3608 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
3612 (define_insn "*zero_extendsidi2_insn_sp64"
3613 [(set (match_operand:DI 0 "register_operand" "=r,r")
3614 (zero_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
3615 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
3619 [(set_attr "type" "shift,load")])
3621 (define_insn_and_split "*zero_extendsidi2_insn_sp32"
3622 [(set (match_operand:DI 0 "register_operand" "=r")
3623 (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
3626 "&& reload_completed"
3627 [(set (match_dup 2) (match_dup 3))
3628 (set (match_dup 4) (match_dup 5))]
3632 dest1 = gen_highpart (SImode, operands[0]);
3633 dest2 = gen_lowpart (SImode, operands[0]);
3635 /* Swap the order in case of overlap. */
3636 if (REGNO (dest1) == REGNO (operands[1]))
3638 operands[2] = dest2;
3639 operands[3] = operands[1];
3640 operands[4] = dest1;
3641 operands[5] = const0_rtx;
3645 operands[2] = dest1;
3646 operands[3] = const0_rtx;
3647 operands[4] = dest2;
3648 operands[5] = operands[1];
3651 [(set_attr "length" "2")])
3653 ;; Simplify comparisons of extended values.
3655 (define_insn "*cmp_zero_extendqisi2"
3657 (compare:CC (zero_extend:SI (match_operand:QI 0 "register_operand" "r"))
3660 "andcc\t%0, 0xff, %%g0"
3661 [(set_attr "type" "compare")])
3663 (define_insn "*cmp_zero_qi"
3665 (compare:CC (match_operand:QI 0 "register_operand" "r")
3668 "andcc\t%0, 0xff, %%g0"
3669 [(set_attr "type" "compare")])
3671 (define_insn "*cmp_zero_extendqisi2_set"
3673 (compare:CC (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
3675 (set (match_operand:SI 0 "register_operand" "=r")
3676 (zero_extend:SI (match_dup 1)))]
3678 "andcc\t%1, 0xff, %0"
3679 [(set_attr "type" "compare")])
3681 (define_insn "*cmp_zero_extendqisi2_andcc_set"
3683 (compare:CC (and:SI (match_operand:SI 1 "register_operand" "r")
3686 (set (match_operand:SI 0 "register_operand" "=r")
3687 (zero_extend:SI (subreg:QI (match_dup 1) 0)))]
3689 "andcc\t%1, 0xff, %0"
3690 [(set_attr "type" "compare")])
3692 (define_insn "*cmp_zero_extendqidi2"
3694 (compare:CCX (zero_extend:DI (match_operand:QI 0 "register_operand" "r"))
3697 "andcc\t%0, 0xff, %%g0"
3698 [(set_attr "type" "compare")])
3700 (define_insn "*cmp_zero_qi_sp64"
3702 (compare:CCX (match_operand:QI 0 "register_operand" "r")
3705 "andcc\t%0, 0xff, %%g0"
3706 [(set_attr "type" "compare")])
3708 (define_insn "*cmp_zero_extendqidi2_set"
3710 (compare:CCX (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
3712 (set (match_operand:DI 0 "register_operand" "=r")
3713 (zero_extend:DI (match_dup 1)))]
3715 "andcc\t%1, 0xff, %0"
3716 [(set_attr "type" "compare")])
3718 (define_insn "*cmp_zero_extendqidi2_andcc_set"
3720 (compare:CCX (and:DI (match_operand:DI 1 "register_operand" "r")
3723 (set (match_operand:DI 0 "register_operand" "=r")
3724 (zero_extend:DI (subreg:QI (match_dup 1) 0)))]
3726 "andcc\t%1, 0xff, %0"
3727 [(set_attr "type" "compare")])
3729 ;; Similarly, handle {SI,DI}->QI mode truncation followed by a compare.
3731 (define_insn "*cmp_siqi_trunc"
3733 (compare:CC (subreg:QI (match_operand:SI 0 "register_operand" "r") 3)
3736 "andcc\t%0, 0xff, %%g0"
3737 [(set_attr "type" "compare")])
3739 (define_insn "*cmp_siqi_trunc_set"
3741 (compare:CC (subreg:QI (match_operand:SI 1 "register_operand" "r") 3)
3743 (set (match_operand:QI 0 "register_operand" "=r")
3744 (subreg:QI (match_dup 1) 3))]
3746 "andcc\t%1, 0xff, %0"
3747 [(set_attr "type" "compare")])
3749 (define_insn "*cmp_diqi_trunc"
3751 (compare:CC (subreg:QI (match_operand:DI 0 "register_operand" "r") 7)
3754 "andcc\t%0, 0xff, %%g0"
3755 [(set_attr "type" "compare")])
3757 (define_insn "*cmp_diqi_trunc_set"
3759 (compare:CC (subreg:QI (match_operand:DI 1 "register_operand" "r") 7)
3761 (set (match_operand:QI 0 "register_operand" "=r")
3762 (subreg:QI (match_dup 1) 7))]
3764 "andcc\t%1, 0xff, %0"
3765 [(set_attr "type" "compare")])
3768 ;; Sign-extension instructions
3770 ;; These patterns originally accepted general_operands, however, slightly
3771 ;; better code is generated by only accepting register_operands, and then
3772 ;; letting combine generate the lds[hb] insns.
3774 (define_expand "extendhisi2"
3775 [(set (match_operand:SI 0 "register_operand" "")
3776 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
3779 rtx temp = gen_reg_rtx (SImode);
3780 rtx shift_16 = GEN_INT (16);
3781 int op1_subbyte = 0;
3783 if (GET_CODE (operand1) == SUBREG)
3785 op1_subbyte = SUBREG_BYTE (operand1);
3786 op1_subbyte /= GET_MODE_SIZE (SImode);
3787 op1_subbyte *= GET_MODE_SIZE (SImode);
3788 operand1 = XEXP (operand1, 0);
3791 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3793 emit_insn (gen_ashrsi3 (operand0, temp, shift_16));
3797 (define_insn "*sign_extendhisi2_insn"
3798 [(set (match_operand:SI 0 "register_operand" "=r")
3799 (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
3802 [(set_attr "type" "sload")
3803 (set_attr "us3load_type" "3cycle")])
3805 (define_expand "extendqihi2"
3806 [(set (match_operand:HI 0 "register_operand" "")
3807 (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
3810 rtx temp = gen_reg_rtx (SImode);
3811 rtx shift_24 = GEN_INT (24);
3812 int op1_subbyte = 0;
3813 int op0_subbyte = 0;
3815 if (GET_CODE (operand1) == SUBREG)
3817 op1_subbyte = SUBREG_BYTE (operand1);
3818 op1_subbyte /= GET_MODE_SIZE (SImode);
3819 op1_subbyte *= GET_MODE_SIZE (SImode);
3820 operand1 = XEXP (operand1, 0);
3822 if (GET_CODE (operand0) == SUBREG)
3824 op0_subbyte = SUBREG_BYTE (operand0);
3825 op0_subbyte /= GET_MODE_SIZE (SImode);
3826 op0_subbyte *= GET_MODE_SIZE (SImode);
3827 operand0 = XEXP (operand0, 0);
3829 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3831 if (GET_MODE (operand0) != SImode)
3832 operand0 = gen_rtx_SUBREG (SImode, operand0, op0_subbyte);
3833 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
3837 (define_insn "*sign_extendqihi2_insn"
3838 [(set (match_operand:HI 0 "register_operand" "=r")
3839 (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
3842 [(set_attr "type" "sload")
3843 (set_attr "us3load_type" "3cycle")])
3845 (define_expand "extendqisi2"
3846 [(set (match_operand:SI 0 "register_operand" "")
3847 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
3850 rtx temp = gen_reg_rtx (SImode);
3851 rtx shift_24 = GEN_INT (24);
3852 int op1_subbyte = 0;
3854 if (GET_CODE (operand1) == SUBREG)
3856 op1_subbyte = SUBREG_BYTE (operand1);
3857 op1_subbyte /= GET_MODE_SIZE (SImode);
3858 op1_subbyte *= GET_MODE_SIZE (SImode);
3859 operand1 = XEXP (operand1, 0);
3862 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3864 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
3868 (define_insn "*sign_extendqisi2_insn"
3869 [(set (match_operand:SI 0 "register_operand" "=r")
3870 (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
3873 [(set_attr "type" "sload")
3874 (set_attr "us3load_type" "3cycle")])
3876 (define_expand "extendqidi2"
3877 [(set (match_operand:DI 0 "register_operand" "")
3878 (sign_extend:DI (match_operand:QI 1 "register_operand" "")))]
3881 rtx temp = gen_reg_rtx (DImode);
3882 rtx shift_56 = GEN_INT (56);
3883 int op1_subbyte = 0;
3885 if (GET_CODE (operand1) == SUBREG)
3887 op1_subbyte = SUBREG_BYTE (operand1);
3888 op1_subbyte /= GET_MODE_SIZE (DImode);
3889 op1_subbyte *= GET_MODE_SIZE (DImode);
3890 operand1 = XEXP (operand1, 0);
3893 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
3895 emit_insn (gen_ashrdi3 (operand0, temp, shift_56));
3899 (define_insn "*sign_extendqidi2_insn"
3900 [(set (match_operand:DI 0 "register_operand" "=r")
3901 (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
3904 [(set_attr "type" "sload")
3905 (set_attr "us3load_type" "3cycle")])
3907 (define_expand "extendhidi2"
3908 [(set (match_operand:DI 0 "register_operand" "")
3909 (sign_extend:DI (match_operand:HI 1 "register_operand" "")))]
3912 rtx temp = gen_reg_rtx (DImode);
3913 rtx shift_48 = GEN_INT (48);
3914 int op1_subbyte = 0;
3916 if (GET_CODE (operand1) == SUBREG)
3918 op1_subbyte = SUBREG_BYTE (operand1);
3919 op1_subbyte /= GET_MODE_SIZE (DImode);
3920 op1_subbyte *= GET_MODE_SIZE (DImode);
3921 operand1 = XEXP (operand1, 0);
3924 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
3926 emit_insn (gen_ashrdi3 (operand0, temp, shift_48));
3930 (define_insn "*sign_extendhidi2_insn"
3931 [(set (match_operand:DI 0 "register_operand" "=r")
3932 (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
3935 [(set_attr "type" "sload")
3936 (set_attr "us3load_type" "3cycle")])
3938 (define_expand "extendsidi2"
3939 [(set (match_operand:DI 0 "register_operand" "")
3940 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
3944 (define_insn "*sign_extendsidi2_insn"
3945 [(set (match_operand:DI 0 "register_operand" "=r,r")
3946 (sign_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
3951 [(set_attr "type" "shift,sload")
3952 (set_attr "us3load_type" "*,3cycle")])
3955 ;; Special pattern for optimizing bit-field compares. This is needed
3956 ;; because combine uses this as a canonical form.
3958 (define_insn "*cmp_zero_extract"
3961 (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
3962 (match_operand:SI 1 "small_int_operand" "I")
3963 (match_operand:SI 2 "small_int_operand" "I"))
3965 "INTVAL (operands[2]) > 19"
3967 int len = INTVAL (operands[1]);
3968 int pos = 32 - INTVAL (operands[2]) - len;
3969 HOST_WIDE_INT mask = ((1 << len) - 1) << pos;
3970 operands[1] = GEN_INT (mask);
3971 return "andcc\t%0, %1, %%g0";
3973 [(set_attr "type" "compare")])
3975 (define_insn "*cmp_zero_extract_sp64"
3978 (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
3979 (match_operand:SI 1 "small_int_operand" "I")
3980 (match_operand:SI 2 "small_int_operand" "I"))
3982 "TARGET_ARCH64 && INTVAL (operands[2]) > 51"
3984 int len = INTVAL (operands[1]);
3985 int pos = 64 - INTVAL (operands[2]) - len;
3986 HOST_WIDE_INT mask = (((unsigned HOST_WIDE_INT) 1 << len) - 1) << pos;
3987 operands[1] = GEN_INT (mask);
3988 return "andcc\t%0, %1, %%g0";
3990 [(set_attr "type" "compare")])
3993 ;; Conversions between float, double and long double.
3995 (define_insn "extendsfdf2"
3996 [(set (match_operand:DF 0 "register_operand" "=e")
3998 (match_operand:SF 1 "register_operand" "f")))]
4001 [(set_attr "type" "fp")
4002 (set_attr "fptype" "double")])
4004 (define_expand "extendsftf2"
4005 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4007 (match_operand:SF 1 "register_operand" "")))]
4008 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4009 "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
4011 (define_insn "*extendsftf2_hq"
4012 [(set (match_operand:TF 0 "register_operand" "=e")
4014 (match_operand:SF 1 "register_operand" "f")))]
4015 "TARGET_FPU && TARGET_HARD_QUAD"
4017 [(set_attr "type" "fp")])
4019 (define_expand "extenddftf2"
4020 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4022 (match_operand:DF 1 "register_operand" "")))]
4023 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4024 "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
4026 (define_insn "*extenddftf2_hq"
4027 [(set (match_operand:TF 0 "register_operand" "=e")
4029 (match_operand:DF 1 "register_operand" "e")))]
4030 "TARGET_FPU && TARGET_HARD_QUAD"
4032 [(set_attr "type" "fp")])
4034 (define_insn "truncdfsf2"
4035 [(set (match_operand:SF 0 "register_operand" "=f")
4037 (match_operand:DF 1 "register_operand" "e")))]
4040 [(set_attr "type" "fp")
4041 (set_attr "fptype" "double")])
4043 (define_expand "trunctfsf2"
4044 [(set (match_operand:SF 0 "register_operand" "")
4046 (match_operand:TF 1 "general_operand" "")))]
4047 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4048 "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
4050 (define_insn "*trunctfsf2_hq"
4051 [(set (match_operand:SF 0 "register_operand" "=f")
4053 (match_operand:TF 1 "register_operand" "e")))]
4054 "TARGET_FPU && TARGET_HARD_QUAD"
4056 [(set_attr "type" "fp")])
4058 (define_expand "trunctfdf2"
4059 [(set (match_operand:DF 0 "register_operand" "")
4061 (match_operand:TF 1 "general_operand" "")))]
4062 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4063 "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
4065 (define_insn "*trunctfdf2_hq"
4066 [(set (match_operand:DF 0 "register_operand" "=e")
4068 (match_operand:TF 1 "register_operand" "e")))]
4069 "TARGET_FPU && TARGET_HARD_QUAD"
4071 [(set_attr "type" "fp")])
4074 ;; Conversion between fixed point and floating point.
4076 (define_insn "floatsisf2"
4077 [(set (match_operand:SF 0 "register_operand" "=f")
4078 (float:SF (match_operand:SI 1 "register_operand" "f")))]
4081 [(set_attr "type" "fp")
4082 (set_attr "fptype" "double")])
4084 (define_insn "floatsidf2"
4085 [(set (match_operand:DF 0 "register_operand" "=e")
4086 (float:DF (match_operand:SI 1 "register_operand" "f")))]
4089 [(set_attr "type" "fp")
4090 (set_attr "fptype" "double")])
4092 (define_expand "floatsitf2"
4093 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4094 (float:TF (match_operand:SI 1 "register_operand" "")))]
4095 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4096 "emit_tfmode_cvt (FLOAT, operands); DONE;")
4098 (define_insn "*floatsitf2_hq"
4099 [(set (match_operand:TF 0 "register_operand" "=e")
4100 (float:TF (match_operand:SI 1 "register_operand" "f")))]
4101 "TARGET_FPU && TARGET_HARD_QUAD"
4103 [(set_attr "type" "fp")])
4105 (define_expand "floatunssitf2"
4106 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4107 (unsigned_float:TF (match_operand:SI 1 "register_operand" "")))]
4108 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4109 "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
4111 ;; Now the same for 64 bit sources.
4113 (define_insn "floatdisf2"
4114 [(set (match_operand:SF 0 "register_operand" "=f")
4115 (float:SF (match_operand:DI 1 "register_operand" "e")))]
4116 "TARGET_V9 && TARGET_FPU"
4118 [(set_attr "type" "fp")
4119 (set_attr "fptype" "double")])
4121 (define_expand "floatunsdisf2"
4122 [(use (match_operand:SF 0 "register_operand" ""))
4123 (use (match_operand:DI 1 "general_operand" ""))]
4124 "TARGET_ARCH64 && TARGET_FPU"
4125 "sparc_emit_floatunsdi (operands, SFmode); DONE;")
4127 (define_insn "floatdidf2"
4128 [(set (match_operand:DF 0 "register_operand" "=e")
4129 (float:DF (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 "floatunsdidf2"
4136 [(use (match_operand:DF 0 "register_operand" ""))
4137 (use (match_operand:DI 1 "general_operand" ""))]
4138 "TARGET_ARCH64 && TARGET_FPU"
4139 "sparc_emit_floatunsdi (operands, DFmode); DONE;")
4141 (define_expand "floatditf2"
4142 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4143 (float:TF (match_operand:DI 1 "register_operand" "")))]
4144 "TARGET_FPU && TARGET_V9 && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4145 "emit_tfmode_cvt (FLOAT, operands); DONE;")
4147 (define_insn "*floatditf2_hq"
4148 [(set (match_operand:TF 0 "register_operand" "=e")
4149 (float:TF (match_operand:DI 1 "register_operand" "e")))]
4150 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
4152 [(set_attr "type" "fp")])
4154 (define_expand "floatunsditf2"
4155 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4156 (unsigned_float:TF (match_operand:DI 1 "register_operand" "")))]
4157 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4158 "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
4160 ;; Convert a float to an actual integer.
4161 ;; Truncation is performed as part of the conversion.
4163 (define_insn "fix_truncsfsi2"
4164 [(set (match_operand:SI 0 "register_operand" "=f")
4165 (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
4168 [(set_attr "type" "fp")
4169 (set_attr "fptype" "double")])
4171 (define_insn "fix_truncdfsi2"
4172 [(set (match_operand:SI 0 "register_operand" "=f")
4173 (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
4176 [(set_attr "type" "fp")
4177 (set_attr "fptype" "double")])
4179 (define_expand "fix_trunctfsi2"
4180 [(set (match_operand:SI 0 "register_operand" "")
4181 (fix:SI (match_operand:TF 1 "general_operand" "")))]
4182 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4183 "emit_tfmode_cvt (FIX, operands); DONE;")
4185 (define_insn "*fix_trunctfsi2_hq"
4186 [(set (match_operand:SI 0 "register_operand" "=f")
4187 (fix:SI (match_operand:TF 1 "register_operand" "e")))]
4188 "TARGET_FPU && TARGET_HARD_QUAD"
4190 [(set_attr "type" "fp")])
4192 (define_expand "fixuns_trunctfsi2"
4193 [(set (match_operand:SI 0 "register_operand" "")
4194 (unsigned_fix:SI (match_operand:TF 1 "general_operand" "")))]
4195 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4196 "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
4198 ;; Now the same, for V9 targets
4200 (define_insn "fix_truncsfdi2"
4201 [(set (match_operand:DI 0 "register_operand" "=e")
4202 (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
4203 "TARGET_V9 && TARGET_FPU"
4205 [(set_attr "type" "fp")
4206 (set_attr "fptype" "double")])
4208 (define_expand "fixuns_truncsfdi2"
4209 [(use (match_operand:DI 0 "register_operand" ""))
4210 (use (match_operand:SF 1 "general_operand" ""))]
4211 "TARGET_ARCH64 && TARGET_FPU"
4212 "sparc_emit_fixunsdi (operands, SFmode); DONE;")
4214 (define_insn "fix_truncdfdi2"
4215 [(set (match_operand:DI 0 "register_operand" "=e")
4216 (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
4217 "TARGET_V9 && TARGET_FPU"
4219 [(set_attr "type" "fp")
4220 (set_attr "fptype" "double")])
4222 (define_expand "fixuns_truncdfdi2"
4223 [(use (match_operand:DI 0 "register_operand" ""))
4224 (use (match_operand:DF 1 "general_operand" ""))]
4225 "TARGET_ARCH64 && TARGET_FPU"
4226 "sparc_emit_fixunsdi (operands, DFmode); DONE;")
4228 (define_expand "fix_trunctfdi2"
4229 [(set (match_operand:DI 0 "register_operand" "")
4230 (fix:DI (match_operand:TF 1 "general_operand" "")))]
4231 "TARGET_V9 && TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4232 "emit_tfmode_cvt (FIX, operands); DONE;")
4234 (define_insn "*fix_trunctfdi2_hq"
4235 [(set (match_operand:DI 0 "register_operand" "=e")
4236 (fix:DI (match_operand:TF 1 "register_operand" "e")))]
4237 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
4239 [(set_attr "type" "fp")])
4241 (define_expand "fixuns_trunctfdi2"
4242 [(set (match_operand:DI 0 "register_operand" "")
4243 (unsigned_fix:DI (match_operand:TF 1 "general_operand" "")))]
4244 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4245 "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
4248 ;; Integer addition/subtraction instructions.
4250 (define_expand "adddi3"
4251 [(set (match_operand:DI 0 "register_operand" "")
4252 (plus:DI (match_operand:DI 1 "register_operand" "")
4253 (match_operand:DI 2 "arith_double_add_operand" "")))]
4256 if (! TARGET_ARCH64)
4258 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
4259 gen_rtx_SET (VOIDmode, operands[0],
4260 gen_rtx_PLUS (DImode, operands[1],
4262 gen_rtx_CLOBBER (VOIDmode,
4263 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
4268 (define_insn_and_split "adddi3_insn_sp32"
4269 [(set (match_operand:DI 0 "register_operand" "=r")
4270 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
4271 (match_operand:DI 2 "arith_double_operand" "rHI")))
4272 (clobber (reg:CC 100))]
4275 "&& reload_completed"
4276 [(parallel [(set (reg:CC_NOOV 100)
4277 (compare:CC_NOOV (plus:SI (match_dup 4)
4281 (plus:SI (match_dup 4) (match_dup 5)))])
4283 (plus:SI (plus:SI (match_dup 7)
4285 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4287 operands[3] = gen_lowpart (SImode, operands[0]);
4288 operands[4] = gen_lowpart (SImode, operands[1]);
4289 operands[5] = gen_lowpart (SImode, operands[2]);
4290 operands[6] = gen_highpart (SImode, operands[0]);
4291 operands[7] = gen_highpart_mode (SImode, DImode, operands[1]);
4292 #if HOST_BITS_PER_WIDE_INT == 32
4293 if (GET_CODE (operands[2]) == CONST_INT)
4295 if (INTVAL (operands[2]) < 0)
4296 operands[8] = constm1_rtx;
4298 operands[8] = const0_rtx;
4302 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
4304 [(set_attr "length" "2")])
4306 ;; LTU here means "carry set"
4308 [(set (match_operand:SI 0 "register_operand" "=r")
4309 (plus:SI (plus:SI (match_operand:SI 1 "arith_operand" "%r")
4310 (match_operand:SI 2 "arith_operand" "rI"))
4311 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4314 [(set_attr "type" "ialuX")])
4316 (define_insn_and_split "*addx_extend_sp32"
4317 [(set (match_operand:DI 0 "register_operand" "=r")
4318 (zero_extend:DI (plus:SI (plus:SI
4319 (match_operand:SI 1 "register_or_zero_operand" "%rJ")
4320 (match_operand:SI 2 "arith_operand" "rI"))
4321 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4324 "&& reload_completed"
4325 [(set (match_dup 3) (plus:SI (plus:SI (match_dup 1) (match_dup 2))
4326 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
4327 (set (match_dup 4) (const_int 0))]
4328 "operands[3] = gen_lowpart (SImode, operands[0]);
4329 operands[4] = gen_highpart_mode (SImode, DImode, operands[1]);"
4330 [(set_attr "length" "2")])
4332 (define_insn "*addx_extend_sp64"
4333 [(set (match_operand:DI 0 "register_operand" "=r")
4334 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ")
4335 (match_operand:SI 2 "arith_operand" "rI"))
4336 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4339 [(set_attr "type" "ialuX")])
4341 (define_insn_and_split ""
4342 [(set (match_operand:DI 0 "register_operand" "=r")
4343 (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4344 (match_operand:DI 2 "register_operand" "r")))
4345 (clobber (reg:CC 100))]
4348 "&& reload_completed"
4349 [(parallel [(set (reg:CC_NOOV 100)
4350 (compare:CC_NOOV (plus:SI (match_dup 3) (match_dup 1))
4352 (set (match_dup 5) (plus:SI (match_dup 3) (match_dup 1)))])
4354 (plus:SI (plus:SI (match_dup 4) (const_int 0))
4355 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4356 "operands[3] = gen_lowpart (SImode, operands[2]);
4357 operands[4] = gen_highpart (SImode, operands[2]);
4358 operands[5] = gen_lowpart (SImode, operands[0]);
4359 operands[6] = gen_highpart (SImode, operands[0]);"
4360 [(set_attr "length" "2")])
4362 (define_insn "*adddi3_sp64"
4363 [(set (match_operand:DI 0 "register_operand" "=r,r")
4364 (plus:DI (match_operand:DI 1 "register_operand" "%r,r")
4365 (match_operand:DI 2 "arith_add_operand" "rI,O")))]
4371 (define_insn "addsi3"
4372 [(set (match_operand:SI 0 "register_operand" "=r,r,d")
4373 (plus:SI (match_operand:SI 1 "register_operand" "%r,r,d")
4374 (match_operand:SI 2 "arith_add_operand" "rI,O,d")))]
4379 fpadd32s\t%1, %2, %0"
4380 [(set_attr "type" "*,*,fga")
4381 (set_attr "fptype" "*,*,single")])
4383 (define_insn "*cmp_cc_plus"
4384 [(set (reg:CC_NOOV 100)
4385 (compare:CC_NOOV (plus:SI (match_operand:SI 0 "arith_operand" "%r")
4386 (match_operand:SI 1 "arith_operand" "rI"))
4389 "addcc\t%0, %1, %%g0"
4390 [(set_attr "type" "compare")])
4392 (define_insn "*cmp_ccx_plus"
4393 [(set (reg:CCX_NOOV 100)
4394 (compare:CCX_NOOV (plus:DI (match_operand:DI 0 "arith_operand" "%r")
4395 (match_operand:DI 1 "arith_operand" "rI"))
4398 "addcc\t%0, %1, %%g0"
4399 [(set_attr "type" "compare")])
4401 (define_insn "*cmp_cc_plus_set"
4402 [(set (reg:CC_NOOV 100)
4403 (compare:CC_NOOV (plus:SI (match_operand:SI 1 "arith_operand" "%r")
4404 (match_operand:SI 2 "arith_operand" "rI"))
4406 (set (match_operand:SI 0 "register_operand" "=r")
4407 (plus:SI (match_dup 1) (match_dup 2)))]
4410 [(set_attr "type" "compare")])
4412 (define_insn "*cmp_ccx_plus_set"
4413 [(set (reg:CCX_NOOV 100)
4414 (compare:CCX_NOOV (plus:DI (match_operand:DI 1 "arith_operand" "%r")
4415 (match_operand:DI 2 "arith_operand" "rI"))
4417 (set (match_operand:DI 0 "register_operand" "=r")
4418 (plus:DI (match_dup 1) (match_dup 2)))]
4421 [(set_attr "type" "compare")])
4423 (define_expand "subdi3"
4424 [(set (match_operand:DI 0 "register_operand" "")
4425 (minus:DI (match_operand:DI 1 "register_operand" "")
4426 (match_operand:DI 2 "arith_double_add_operand" "")))]
4429 if (! TARGET_ARCH64)
4431 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
4432 gen_rtx_SET (VOIDmode, operands[0],
4433 gen_rtx_MINUS (DImode, operands[1],
4435 gen_rtx_CLOBBER (VOIDmode,
4436 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
4441 (define_insn_and_split "subdi3_insn_sp32"
4442 [(set (match_operand:DI 0 "register_operand" "=r")
4443 (minus:DI (match_operand:DI 1 "register_operand" "r")
4444 (match_operand:DI 2 "arith_double_operand" "rHI")))
4445 (clobber (reg:CC 100))]
4448 "&& reload_completed"
4449 [(parallel [(set (reg:CC_NOOV 100)
4450 (compare:CC_NOOV (minus:SI (match_dup 4)
4454 (minus:SI (match_dup 4) (match_dup 5)))])
4456 (minus:SI (minus:SI (match_dup 7)
4458 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4460 operands[3] = gen_lowpart (SImode, operands[0]);
4461 operands[4] = gen_lowpart (SImode, operands[1]);
4462 operands[5] = gen_lowpart (SImode, operands[2]);
4463 operands[6] = gen_highpart (SImode, operands[0]);
4464 operands[7] = gen_highpart (SImode, operands[1]);
4465 #if HOST_BITS_PER_WIDE_INT == 32
4466 if (GET_CODE (operands[2]) == CONST_INT)
4468 if (INTVAL (operands[2]) < 0)
4469 operands[8] = constm1_rtx;
4471 operands[8] = const0_rtx;
4475 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
4477 [(set_attr "length" "2")])
4479 ;; LTU here means "carry set"
4481 [(set (match_operand:SI 0 "register_operand" "=r")
4482 (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
4483 (match_operand:SI 2 "arith_operand" "rI"))
4484 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4487 [(set_attr "type" "ialuX")])
4489 (define_insn "*subx_extend_sp64"
4490 [(set (match_operand:DI 0 "register_operand" "=r")
4491 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
4492 (match_operand:SI 2 "arith_operand" "rI"))
4493 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4496 [(set_attr "type" "ialuX")])
4498 (define_insn_and_split "*subx_extend"
4499 [(set (match_operand:DI 0 "register_operand" "=r")
4500 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
4501 (match_operand:SI 2 "arith_operand" "rI"))
4502 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4505 "&& reload_completed"
4506 [(set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 2))
4507 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
4508 (set (match_dup 4) (const_int 0))]
4509 "operands[3] = gen_lowpart (SImode, operands[0]);
4510 operands[4] = gen_highpart (SImode, operands[0]);"
4511 [(set_attr "length" "2")])
4513 (define_insn_and_split ""
4514 [(set (match_operand:DI 0 "register_operand" "=r")
4515 (minus:DI (match_operand:DI 1 "register_operand" "r")
4516 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))
4517 (clobber (reg:CC 100))]
4520 "&& reload_completed"
4521 [(parallel [(set (reg:CC_NOOV 100)
4522 (compare:CC_NOOV (minus:SI (match_dup 3) (match_dup 2))
4524 (set (match_dup 5) (minus:SI (match_dup 3) (match_dup 2)))])
4526 (minus:SI (minus:SI (match_dup 4) (const_int 0))
4527 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4528 "operands[3] = gen_lowpart (SImode, operands[1]);
4529 operands[4] = gen_highpart (SImode, operands[1]);
4530 operands[5] = gen_lowpart (SImode, operands[0]);
4531 operands[6] = gen_highpart (SImode, operands[0]);"
4532 [(set_attr "length" "2")])
4534 (define_insn "*subdi3_sp64"
4535 [(set (match_operand:DI 0 "register_operand" "=r,r")
4536 (minus:DI (match_operand:DI 1 "register_operand" "r,r")
4537 (match_operand:DI 2 "arith_add_operand" "rI,O")))]
4543 (define_insn "subsi3"
4544 [(set (match_operand:SI 0 "register_operand" "=r,r,d")
4545 (minus:SI (match_operand:SI 1 "register_operand" "r,r,d")
4546 (match_operand:SI 2 "arith_add_operand" "rI,O,d")))]
4551 fpsub32s\t%1, %2, %0"
4552 [(set_attr "type" "*,*,fga")
4553 (set_attr "fptype" "*,*,single")])
4555 (define_insn "*cmp_minus_cc"
4556 [(set (reg:CC_NOOV 100)
4557 (compare:CC_NOOV (minus:SI (match_operand:SI 0 "register_or_zero_operand" "rJ")
4558 (match_operand:SI 1 "arith_operand" "rI"))
4561 "subcc\t%r0, %1, %%g0"
4562 [(set_attr "type" "compare")])
4564 (define_insn "*cmp_minus_ccx"
4565 [(set (reg:CCX_NOOV 100)
4566 (compare:CCX_NOOV (minus:DI (match_operand:DI 0 "register_operand" "r")
4567 (match_operand:DI 1 "arith_operand" "rI"))
4570 "subcc\t%0, %1, %%g0"
4571 [(set_attr "type" "compare")])
4573 (define_insn "cmp_minus_cc_set"
4574 [(set (reg:CC_NOOV 100)
4575 (compare:CC_NOOV (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
4576 (match_operand:SI 2 "arith_operand" "rI"))
4578 (set (match_operand:SI 0 "register_operand" "=r")
4579 (minus:SI (match_dup 1) (match_dup 2)))]
4581 "subcc\t%r1, %2, %0"
4582 [(set_attr "type" "compare")])
4584 (define_insn "*cmp_minus_ccx_set"
4585 [(set (reg:CCX_NOOV 100)
4586 (compare:CCX_NOOV (minus:DI (match_operand:DI 1 "register_operand" "r")
4587 (match_operand:DI 2 "arith_operand" "rI"))
4589 (set (match_operand:DI 0 "register_operand" "=r")
4590 (minus:DI (match_dup 1) (match_dup 2)))]
4593 [(set_attr "type" "compare")])
4596 ;; Integer multiply/divide instructions.
4598 ;; The 32 bit multiply/divide instructions are deprecated on v9, but at
4599 ;; least in UltraSPARC I, II and IIi it is a win tick-wise.
4601 (define_insn "mulsi3"
4602 [(set (match_operand:SI 0 "register_operand" "=r")
4603 (mult:SI (match_operand:SI 1 "arith_operand" "%r")
4604 (match_operand:SI 2 "arith_operand" "rI")))]
4607 [(set_attr "type" "imul")])
4609 (define_expand "muldi3"
4610 [(set (match_operand:DI 0 "register_operand" "")
4611 (mult:DI (match_operand:DI 1 "arith_operand" "")
4612 (match_operand:DI 2 "arith_operand" "")))]
4613 "TARGET_ARCH64 || TARGET_V8PLUS"
4617 emit_insn (gen_muldi3_v8plus (operands[0], operands[1], operands[2]));
4622 (define_insn "*muldi3_sp64"
4623 [(set (match_operand:DI 0 "register_operand" "=r")
4624 (mult:DI (match_operand:DI 1 "arith_operand" "%r")
4625 (match_operand:DI 2 "arith_operand" "rI")))]
4628 [(set_attr "type" "imul")])
4630 ;; V8plus wide multiply.
4632 (define_insn "muldi3_v8plus"
4633 [(set (match_operand:DI 0 "register_operand" "=r,h")
4634 (mult:DI (match_operand:DI 1 "arith_operand" "%r,0")
4635 (match_operand:DI 2 "arith_operand" "rI,rI")))
4636 (clobber (match_scratch:SI 3 "=&h,X"))
4637 (clobber (match_scratch:SI 4 "=&h,X"))]
4640 if (sparc_check_64 (operands[1], insn) <= 0)
4641 output_asm_insn ("srl\t%L1, 0, %L1", operands);
4642 if (which_alternative == 1)
4643 output_asm_insn ("sllx\t%H1, 32, %H1", operands);
4644 if (GET_CODE (operands[2]) == CONST_INT)
4646 if (which_alternative == 1)
4647 return "or\t%L1, %H1, %H1\n\tmulx\t%H1, %2, %L0\;srlx\t%L0, 32, %H0";
4649 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";
4651 else if (rtx_equal_p (operands[1], operands[2]))
4653 if (which_alternative == 1)
4654 return "or\t%L1, %H1, %H1\n\tmulx\t%H1, %H1, %L0\;srlx\t%L0, 32, %H0";
4656 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";
4658 if (sparc_check_64 (operands[2], insn) <= 0)
4659 output_asm_insn ("srl\t%L2, 0, %L2", operands);
4660 if (which_alternative == 1)
4661 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";
4663 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";
4665 [(set_attr "type" "multi")
4666 (set_attr "length" "9,8")])
4668 (define_insn "*cmp_mul_set"
4670 (compare:CC (mult:SI (match_operand:SI 1 "arith_operand" "%r")
4671 (match_operand:SI 2 "arith_operand" "rI"))
4673 (set (match_operand:SI 0 "register_operand" "=r")
4674 (mult:SI (match_dup 1) (match_dup 2)))]
4675 "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS"
4676 "smulcc\t%1, %2, %0"
4677 [(set_attr "type" "imul")])
4679 (define_expand "mulsidi3"
4680 [(set (match_operand:DI 0 "register_operand" "")
4681 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
4682 (sign_extend:DI (match_operand:SI 2 "arith_operand" ""))))]
4685 if (CONSTANT_P (operands[2]))
4688 emit_insn (gen_const_mulsidi3_v8plus (operands[0], operands[1],
4690 else if (TARGET_ARCH32)
4691 emit_insn (gen_const_mulsidi3_sp32 (operands[0], operands[1],
4694 emit_insn (gen_const_mulsidi3_sp64 (operands[0], operands[1],
4700 emit_insn (gen_mulsidi3_v8plus (operands[0], operands[1], operands[2]));
4705 ;; V9 puts the 64 bit product in a 64 bit register. Only out or global
4706 ;; registers can hold 64 bit values in the V8plus environment.
4708 (define_insn "mulsidi3_v8plus"
4709 [(set (match_operand:DI 0 "register_operand" "=h,r")
4710 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4711 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
4712 (clobber (match_scratch:SI 3 "=X,&h"))]
4715 smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
4716 smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4717 [(set_attr "type" "multi")
4718 (set_attr "length" "2,3")])
4721 (define_insn "const_mulsidi3_v8plus"
4722 [(set (match_operand:DI 0 "register_operand" "=h,r")
4723 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4724 (match_operand:DI 2 "small_int_operand" "I,I")))
4725 (clobber (match_scratch:SI 3 "=X,&h"))]
4728 smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
4729 smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4730 [(set_attr "type" "multi")
4731 (set_attr "length" "2,3")])
4734 (define_insn "*mulsidi3_sp32"
4735 [(set (match_operand:DI 0 "register_operand" "=r")
4736 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4737 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4740 return TARGET_SPARCLET
4741 ? "smuld\t%1, %2, %L0"
4742 : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
4745 (if_then_else (eq_attr "isa" "sparclet")
4746 (const_string "imul") (const_string "multi")))
4747 (set (attr "length")
4748 (if_then_else (eq_attr "isa" "sparclet")
4749 (const_int 1) (const_int 2)))])
4751 (define_insn "*mulsidi3_sp64"
4752 [(set (match_operand:DI 0 "register_operand" "=r")
4753 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4754 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4755 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4757 [(set_attr "type" "imul")])
4759 ;; Extra pattern, because sign_extend of a constant isn't valid.
4762 (define_insn "const_mulsidi3_sp32"
4763 [(set (match_operand:DI 0 "register_operand" "=r")
4764 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4765 (match_operand:DI 2 "small_int_operand" "I")))]
4768 return TARGET_SPARCLET
4769 ? "smuld\t%1, %2, %L0"
4770 : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
4773 (if_then_else (eq_attr "isa" "sparclet")
4774 (const_string "imul") (const_string "multi")))
4775 (set (attr "length")
4776 (if_then_else (eq_attr "isa" "sparclet")
4777 (const_int 1) (const_int 2)))])
4779 (define_insn "const_mulsidi3_sp64"
4780 [(set (match_operand:DI 0 "register_operand" "=r")
4781 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4782 (match_operand:DI 2 "small_int_operand" "I")))]
4783 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4785 [(set_attr "type" "imul")])
4787 (define_expand "smulsi3_highpart"
4788 [(set (match_operand:SI 0 "register_operand" "")
4790 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
4791 (sign_extend:DI (match_operand:SI 2 "arith_operand" "")))
4793 "TARGET_HARD_MUL && TARGET_ARCH32"
4795 if (CONSTANT_P (operands[2]))
4799 emit_insn (gen_const_smulsi3_highpart_v8plus (operands[0],
4805 emit_insn (gen_const_smulsi3_highpart (operands[0], operands[1], operands[2]));
4810 emit_insn (gen_smulsi3_highpart_v8plus (operands[0], operands[1],
4811 operands[2], GEN_INT (32)));
4817 (define_insn "smulsi3_highpart_v8plus"
4818 [(set (match_operand:SI 0 "register_operand" "=h,r")
4820 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4821 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
4822 (match_operand:SI 3 "small_int_operand" "I,I"))))
4823 (clobber (match_scratch:SI 4 "=X,&h"))]
4826 smul\t%1, %2, %0\;srlx\t%0, %3, %0
4827 smul\t%1, %2, %4\;srlx\t%4, %3, %0"
4828 [(set_attr "type" "multi")
4829 (set_attr "length" "2")])
4831 ;; The combiner changes TRUNCATE in the previous pattern to SUBREG.
4834 [(set (match_operand:SI 0 "register_operand" "=h,r")
4837 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4838 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
4839 (match_operand:SI 3 "small_int_operand" "I,I"))
4841 (clobber (match_scratch:SI 4 "=X,&h"))]
4844 smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
4845 smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
4846 [(set_attr "type" "multi")
4847 (set_attr "length" "2")])
4850 (define_insn "const_smulsi3_highpart_v8plus"
4851 [(set (match_operand:SI 0 "register_operand" "=h,r")
4853 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4854 (match_operand:DI 2 "small_int_operand" "I,I"))
4855 (match_operand:SI 3 "small_int_operand" "I,I"))))
4856 (clobber (match_scratch:SI 4 "=X,&h"))]
4859 smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
4860 smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
4861 [(set_attr "type" "multi")
4862 (set_attr "length" "2")])
4865 (define_insn "*smulsi3_highpart_sp32"
4866 [(set (match_operand:SI 0 "register_operand" "=r")
4868 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4869 (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
4872 "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
4873 [(set_attr "type" "multi")
4874 (set_attr "length" "2")])
4877 (define_insn "const_smulsi3_highpart"
4878 [(set (match_operand:SI 0 "register_operand" "=r")
4880 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4881 (match_operand:DI 2 "small_int_operand" "i"))
4884 "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
4885 [(set_attr "type" "multi")
4886 (set_attr "length" "2")])
4888 (define_expand "umulsidi3"
4889 [(set (match_operand:DI 0 "register_operand" "")
4890 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
4891 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" ""))))]
4894 if (CONSTANT_P (operands[2]))
4897 emit_insn (gen_const_umulsidi3_v8plus (operands[0], operands[1],
4899 else if (TARGET_ARCH32)
4900 emit_insn (gen_const_umulsidi3_sp32 (operands[0], operands[1],
4903 emit_insn (gen_const_umulsidi3_sp64 (operands[0], operands[1],
4909 emit_insn (gen_umulsidi3_v8plus (operands[0], operands[1], operands[2]));
4915 (define_insn "umulsidi3_v8plus"
4916 [(set (match_operand:DI 0 "register_operand" "=h,r")
4917 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4918 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
4919 (clobber (match_scratch:SI 3 "=X,&h"))]
4922 umul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
4923 umul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4924 [(set_attr "type" "multi")
4925 (set_attr "length" "2,3")])
4928 (define_insn "*umulsidi3_sp32"
4929 [(set (match_operand:DI 0 "register_operand" "=r")
4930 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4931 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4934 return TARGET_SPARCLET
4935 ? "umuld\t%1, %2, %L0"
4936 : "umul\t%1, %2, %L0\n\trd\t%%y, %H0";
4939 (if_then_else (eq_attr "isa" "sparclet")
4940 (const_string "imul") (const_string "multi")))
4941 (set (attr "length")
4942 (if_then_else (eq_attr "isa" "sparclet")
4943 (const_int 1) (const_int 2)))])
4945 (define_insn "*umulsidi3_sp64"
4946 [(set (match_operand:DI 0 "register_operand" "=r")
4947 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4948 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4949 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4951 [(set_attr "type" "imul")])
4953 ;; Extra pattern, because sign_extend of a constant isn't valid.
4956 (define_insn "const_umulsidi3_sp32"
4957 [(set (match_operand:DI 0 "register_operand" "=r")
4958 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4959 (match_operand:DI 2 "uns_small_int_operand" "")))]
4962 return TARGET_SPARCLET
4963 ? "umuld\t%1, %s2, %L0"
4964 : "umul\t%1, %s2, %L0\n\trd\t%%y, %H0";
4967 (if_then_else (eq_attr "isa" "sparclet")
4968 (const_string "imul") (const_string "multi")))
4969 (set (attr "length")
4970 (if_then_else (eq_attr "isa" "sparclet")
4971 (const_int 1) (const_int 2)))])
4973 (define_insn "const_umulsidi3_sp64"
4974 [(set (match_operand:DI 0 "register_operand" "=r")
4975 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4976 (match_operand:DI 2 "uns_small_int_operand" "")))]
4977 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4979 [(set_attr "type" "imul")])
4982 (define_insn "const_umulsidi3_v8plus"
4983 [(set (match_operand:DI 0 "register_operand" "=h,r")
4984 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4985 (match_operand:DI 2 "uns_small_int_operand" "")))
4986 (clobber (match_scratch:SI 3 "=X,h"))]
4989 umul\t%1, %s2, %L0\n\tsrlx\t%L0, 32, %H0
4990 umul\t%1, %s2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4991 [(set_attr "type" "multi")
4992 (set_attr "length" "2,3")])
4994 (define_expand "umulsi3_highpart"
4995 [(set (match_operand:SI 0 "register_operand" "")
4997 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
4998 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" "")))
5000 "TARGET_HARD_MUL && TARGET_ARCH32"
5002 if (CONSTANT_P (operands[2]))
5006 emit_insn (gen_const_umulsi3_highpart_v8plus (operands[0],
5012 emit_insn (gen_const_umulsi3_highpart (operands[0], operands[1], operands[2]));
5017 emit_insn (gen_umulsi3_highpart_v8plus (operands[0], operands[1],
5018 operands[2], GEN_INT (32)));
5024 (define_insn "umulsi3_highpart_v8plus"
5025 [(set (match_operand:SI 0 "register_operand" "=h,r")
5027 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5028 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
5029 (match_operand:SI 3 "small_int_operand" "I,I"))))
5030 (clobber (match_scratch:SI 4 "=X,h"))]
5033 umul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
5034 umul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
5035 [(set_attr "type" "multi")
5036 (set_attr "length" "2")])
5039 (define_insn "const_umulsi3_highpart_v8plus"
5040 [(set (match_operand:SI 0 "register_operand" "=h,r")
5042 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5043 (match_operand:DI 2 "uns_small_int_operand" ""))
5044 (match_operand:SI 3 "small_int_operand" "I,I"))))
5045 (clobber (match_scratch:SI 4 "=X,h"))]
5048 umul\t%1, %s2, %0\n\tsrlx\t%0, %3, %0
5049 umul\t%1, %s2, %4\n\tsrlx\t%4, %3, %0"
5050 [(set_attr "type" "multi")
5051 (set_attr "length" "2")])
5054 (define_insn "*umulsi3_highpart_sp32"
5055 [(set (match_operand:SI 0 "register_operand" "=r")
5057 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5058 (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
5061 "umul\t%1, %2, %%g0\n\trd\t%%y, %0"
5062 [(set_attr "type" "multi")
5063 (set_attr "length" "2")])
5066 (define_insn "const_umulsi3_highpart"
5067 [(set (match_operand:SI 0 "register_operand" "=r")
5069 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5070 (match_operand:DI 2 "uns_small_int_operand" ""))
5073 "umul\t%1, %s2, %%g0\n\trd\t%%y, %0"
5074 [(set_attr "type" "multi")
5075 (set_attr "length" "2")])
5077 ;; The V8 architecture specifies that there must be 3 instructions between
5078 ;; a Y register write and a use of it for correct results.
5080 (define_expand "divsi3"
5081 [(parallel [(set (match_operand:SI 0 "register_operand" "=r,r")
5082 (div:SI (match_operand:SI 1 "register_operand" "r,r")
5083 (match_operand:SI 2 "input_operand" "rI,m")))
5084 (clobber (match_scratch:SI 3 "=&r,&r"))])]
5085 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
5089 operands[3] = gen_reg_rtx(SImode);
5090 emit_insn (gen_ashrsi3 (operands[3], operands[1], GEN_INT (31)));
5091 emit_insn (gen_divsi3_sp64 (operands[0], operands[1], operands[2],
5097 (define_insn "divsi3_sp32"
5098 [(set (match_operand:SI 0 "register_operand" "=r,r")
5099 (div:SI (match_operand:SI 1 "register_operand" "r,r")
5100 (match_operand:SI 2 "input_operand" "rI,m")))
5101 (clobber (match_scratch:SI 3 "=&r,&r"))]
5102 "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS)
5105 if (which_alternative == 0)
5107 return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tsdiv\t%1, %2, %0";
5109 return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tnop\n\tnop\n\tnop\n\tsdiv\t%1, %2, %0";
5112 return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tld\t%2, %3\n\tsdiv\t%1, %3, %0";
5114 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";
5116 [(set_attr "type" "multi")
5117 (set (attr "length")
5118 (if_then_else (eq_attr "isa" "v9")
5119 (const_int 4) (const_int 6)))])
5121 (define_insn "divsi3_sp64"
5122 [(set (match_operand:SI 0 "register_operand" "=r")
5123 (div:SI (match_operand:SI 1 "register_operand" "r")
5124 (match_operand:SI 2 "input_operand" "rI")))
5125 (use (match_operand:SI 3 "register_operand" "r"))]
5126 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5127 "wr\t%%g0, %3, %%y\n\tsdiv\t%1, %2, %0"
5128 [(set_attr "type" "multi")
5129 (set_attr "length" "2")])
5131 (define_insn "divdi3"
5132 [(set (match_operand:DI 0 "register_operand" "=r")
5133 (div:DI (match_operand:DI 1 "register_operand" "r")
5134 (match_operand:DI 2 "arith_operand" "rI")))]
5137 [(set_attr "type" "idiv")])
5139 (define_insn "*cmp_sdiv_cc_set"
5141 (compare:CC (div:SI (match_operand:SI 1 "register_operand" "r")
5142 (match_operand:SI 2 "arith_operand" "rI"))
5144 (set (match_operand:SI 0 "register_operand" "=r")
5145 (div:SI (match_dup 1) (match_dup 2)))
5146 (clobber (match_scratch:SI 3 "=&r"))]
5147 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
5150 return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tsdivcc\t%1, %2, %0";
5152 return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tnop\n\tnop\n\tnop\n\tsdivcc\t%1, %2, %0";
5154 [(set_attr "type" "multi")
5155 (set (attr "length")
5156 (if_then_else (eq_attr "isa" "v9")
5157 (const_int 3) (const_int 6)))])
5160 (define_expand "udivsi3"
5161 [(set (match_operand:SI 0 "register_operand" "")
5162 (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "")
5163 (match_operand:SI 2 "input_operand" "")))]
5164 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
5167 ;; The V8 architecture specifies that there must be 3 instructions between
5168 ;; a Y register write and a use of it for correct results.
5170 (define_insn "udivsi3_sp32"
5171 [(set (match_operand:SI 0 "register_operand" "=r,&r,&r")
5172 (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "r,r,m")
5173 (match_operand:SI 2 "input_operand" "rI,m,r")))]
5174 "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS)
5177 output_asm_insn ("wr\t%%g0, %%g0, %%y", operands);
5178 switch (which_alternative)
5181 return "nop\n\tnop\n\tnop\n\tudiv\t%1, %2, %0";
5183 return "ld\t%2, %0\n\tnop\n\tnop\n\tudiv\t%1, %0, %0";
5185 return "ld\t%1, %0\n\tnop\n\tnop\n\tudiv\t%0, %2, %0";
5188 [(set_attr "type" "multi")
5189 (set_attr "length" "5")])
5191 (define_insn "udivsi3_sp64"
5192 [(set (match_operand:SI 0 "register_operand" "=r")
5193 (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "r")
5194 (match_operand:SI 2 "input_operand" "rI")))]
5195 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5196 "wr\t%%g0, 0, %%y\n\tudiv\t%1, %2, %0"
5197 [(set_attr "type" "multi")
5198 (set_attr "length" "2")])
5200 (define_insn "udivdi3"
5201 [(set (match_operand:DI 0 "register_operand" "=r")
5202 (udiv:DI (match_operand:DI 1 "register_operand" "r")
5203 (match_operand:DI 2 "arith_operand" "rI")))]
5206 [(set_attr "type" "idiv")])
5208 (define_insn "*cmp_udiv_cc_set"
5210 (compare:CC (udiv:SI (match_operand:SI 1 "register_operand" "r")
5211 (match_operand:SI 2 "arith_operand" "rI"))
5213 (set (match_operand:SI 0 "register_operand" "=r")
5214 (udiv:SI (match_dup 1) (match_dup 2)))]
5216 || TARGET_DEPRECATED_V8_INSNS"
5219 return "wr\t%%g0, %%g0, %%y\n\tudivcc\t%1, %2, %0";
5221 return "wr\t%%g0, %%g0, %%y\n\tnop\n\tnop\n\tnop\n\tudivcc\t%1, %2, %0";
5223 [(set_attr "type" "multi")
5224 (set (attr "length")
5225 (if_then_else (eq_attr "isa" "v9")
5226 (const_int 2) (const_int 5)))])
5228 ; sparclet multiply/accumulate insns
5230 (define_insn "*smacsi"
5231 [(set (match_operand:SI 0 "register_operand" "=r")
5232 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "%r")
5233 (match_operand:SI 2 "arith_operand" "rI"))
5234 (match_operand:SI 3 "register_operand" "0")))]
5237 [(set_attr "type" "imul")])
5239 (define_insn "*smacdi"
5240 [(set (match_operand:DI 0 "register_operand" "=r")
5241 (plus:DI (mult:DI (sign_extend:DI
5242 (match_operand:SI 1 "register_operand" "%r"))
5244 (match_operand:SI 2 "register_operand" "r")))
5245 (match_operand:DI 3 "register_operand" "0")))]
5247 "smacd\t%1, %2, %L0"
5248 [(set_attr "type" "imul")])
5250 (define_insn "*umacdi"
5251 [(set (match_operand:DI 0 "register_operand" "=r")
5252 (plus:DI (mult:DI (zero_extend:DI
5253 (match_operand:SI 1 "register_operand" "%r"))
5255 (match_operand:SI 2 "register_operand" "r")))
5256 (match_operand:DI 3 "register_operand" "0")))]
5258 "umacd\t%1, %2, %L0"
5259 [(set_attr "type" "imul")])
5262 ;; Boolean instructions.
5264 ;; We define DImode `and' so with DImode `not' we can get
5265 ;; DImode `andn'. Other combinations are possible.
5267 (define_mode_macro V64I [DI V2SI V4HI V8QI])
5268 (define_mode_macro V32I [SI V2HI V4QI])
5270 (define_expand "and<V64I:mode>3"
5271 [(set (match_operand:V64I 0 "register_operand" "")
5272 (and:V64I (match_operand:V64I 1 "arith_double_operand" "")
5273 (match_operand:V64I 2 "arith_double_operand" "")))]
5277 (define_insn "*and<V64I:mode>3_sp32"
5278 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5279 (and:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
5280 (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
5285 [(set_attr "type" "*,fga")
5286 (set_attr "length" "2,*")
5287 (set_attr "fptype" "*,double")])
5289 (define_insn "*and<V64I:mode>3_sp64"
5290 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5291 (and:V64I (match_operand:V64I 1 "arith_operand" "%r,b")
5292 (match_operand:V64I 2 "arith_operand" "rI,b")))]
5297 [(set_attr "type" "*,fga")
5298 (set_attr "fptype" "*,double")])
5300 (define_insn "and<V32I:mode>3"
5301 [(set (match_operand:V32I 0 "register_operand" "=r,d")
5302 (and:V32I (match_operand:V32I 1 "arith_operand" "%r,d")
5303 (match_operand:V32I 2 "arith_operand" "rI,d")))]
5308 [(set_attr "type" "*,fga")
5309 (set_attr "fptype" "*,single")])
5312 [(set (match_operand:SI 0 "register_operand" "")
5313 (and:SI (match_operand:SI 1 "register_operand" "")
5314 (match_operand:SI 2 "const_compl_high_operand" "")))
5315 (clobber (match_operand:SI 3 "register_operand" ""))]
5317 [(set (match_dup 3) (match_dup 4))
5318 (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 1)))]
5320 operands[4] = GEN_INT (~INTVAL (operands[2]));
5323 (define_insn_and_split "*and_not_<V64I:mode>_sp32"
5324 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5325 (and:V64I (not:V64I (match_operand:V64I 1 "register_operand" "%r,b"))
5326 (match_operand:V64I 2 "register_operand" "r,b")))]
5330 fandnot1\t%1, %2, %0"
5331 "&& reload_completed
5332 && ((GET_CODE (operands[0]) == REG
5333 && REGNO (operands[0]) < 32)
5334 || (GET_CODE (operands[0]) == SUBREG
5335 && GET_CODE (SUBREG_REG (operands[0])) == REG
5336 && REGNO (SUBREG_REG (operands[0])) < 32))"
5337 [(set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))
5338 (set (match_dup 6) (and:SI (not:SI (match_dup 7)) (match_dup 8)))]
5339 "operands[3] = gen_highpart (SImode, operands[0]);
5340 operands[4] = gen_highpart (SImode, operands[1]);
5341 operands[5] = gen_highpart (SImode, operands[2]);
5342 operands[6] = gen_lowpart (SImode, operands[0]);
5343 operands[7] = gen_lowpart (SImode, operands[1]);
5344 operands[8] = gen_lowpart (SImode, operands[2]);"
5345 [(set_attr "type" "*,fga")
5346 (set_attr "length" "2,*")
5347 (set_attr "fptype" "*,double")])
5349 (define_insn "*and_not_<V64I:mode>_sp64"
5350 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5351 (and:V64I (not:V64I (match_operand:V64I 1 "register_operand" "%r,b"))
5352 (match_operand:V64I 2 "register_operand" "r,b")))]
5356 fandnot1\t%1, %2, %0"
5357 [(set_attr "type" "*,fga")
5358 (set_attr "fptype" "*,double")])
5360 (define_insn "*and_not_<V32I:mode>"
5361 [(set (match_operand:V32I 0 "register_operand" "=r,d")
5362 (and:V32I (not:V32I (match_operand:V32I 1 "register_operand" "%r,d"))
5363 (match_operand:V32I 2 "register_operand" "r,d")))]
5367 fandnot1s\t%1, %2, %0"
5368 [(set_attr "type" "*,fga")
5369 (set_attr "fptype" "*,single")])
5371 (define_expand "ior<V64I:mode>3"
5372 [(set (match_operand:V64I 0 "register_operand" "")
5373 (ior:V64I (match_operand:V64I 1 "arith_double_operand" "")
5374 (match_operand:V64I 2 "arith_double_operand" "")))]
5378 (define_insn "*ior<V64I:mode>3_sp32"
5379 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5380 (ior:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
5381 (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
5386 [(set_attr "type" "*,fga")
5387 (set_attr "length" "2,*")
5388 (set_attr "fptype" "*,double")])
5390 (define_insn "*ior<V64I:mode>3_sp64"
5391 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5392 (ior:V64I (match_operand:V64I 1 "arith_operand" "%r,b")
5393 (match_operand:V64I 2 "arith_operand" "rI,b")))]
5398 [(set_attr "type" "*,fga")
5399 (set_attr "fptype" "*,double")])
5401 (define_insn "ior<V32I:mode>3"
5402 [(set (match_operand:V32I 0 "register_operand" "=r,d")
5403 (ior:V32I (match_operand:V32I 1 "arith_operand" "%r,d")
5404 (match_operand:V32I 2 "arith_operand" "rI,d")))]
5409 [(set_attr "type" "*,fga")
5410 (set_attr "fptype" "*,single")])
5413 [(set (match_operand:SI 0 "register_operand" "")
5414 (ior:SI (match_operand:SI 1 "register_operand" "")
5415 (match_operand:SI 2 "const_compl_high_operand" "")))
5416 (clobber (match_operand:SI 3 "register_operand" ""))]
5418 [(set (match_dup 3) (match_dup 4))
5419 (set (match_dup 0) (ior:SI (not:SI (match_dup 3)) (match_dup 1)))]
5421 operands[4] = GEN_INT (~INTVAL (operands[2]));
5424 (define_insn_and_split "*or_not_<V64I:mode>_sp32"
5425 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5426 (ior:V64I (not:V64I (match_operand:V64I 1 "register_operand" "r,b"))
5427 (match_operand:V64I 2 "register_operand" "r,b")))]
5431 fornot1\t%1, %2, %0"
5432 "&& reload_completed
5433 && ((GET_CODE (operands[0]) == REG
5434 && REGNO (operands[0]) < 32)
5435 || (GET_CODE (operands[0]) == SUBREG
5436 && GET_CODE (SUBREG_REG (operands[0])) == REG
5437 && REGNO (SUBREG_REG (operands[0])) < 32))"
5438 [(set (match_dup 3) (ior:SI (not:SI (match_dup 4)) (match_dup 5)))
5439 (set (match_dup 6) (ior:SI (not:SI (match_dup 7)) (match_dup 8)))]
5440 "operands[3] = gen_highpart (SImode, operands[0]);
5441 operands[4] = gen_highpart (SImode, operands[1]);
5442 operands[5] = gen_highpart (SImode, operands[2]);
5443 operands[6] = gen_lowpart (SImode, operands[0]);
5444 operands[7] = gen_lowpart (SImode, operands[1]);
5445 operands[8] = gen_lowpart (SImode, operands[2]);"
5446 [(set_attr "type" "*,fga")
5447 (set_attr "length" "2,*")
5448 (set_attr "fptype" "*,double")])
5450 (define_insn "*or_not_<V64I:mode>_sp64"
5451 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5452 (ior:V64I (not:V64I (match_operand:V64I 1 "register_operand" "r,b"))
5453 (match_operand:V64I 2 "register_operand" "r,b")))]
5457 fornot1\t%1, %2, %0"
5458 [(set_attr "type" "*,fga")
5459 (set_attr "fptype" "*,double")])
5461 (define_insn "*or_not_<V32I:mode>"
5462 [(set (match_operand:V32I 0 "register_operand" "=r,d")
5463 (ior:V32I (not:V32I (match_operand:V32I 1 "register_operand" "r,d"))
5464 (match_operand:V32I 2 "register_operand" "r,d")))]
5468 fornot1s\t%1, %2, %0"
5469 [(set_attr "type" "*,fga")
5470 (set_attr "fptype" "*,single")])
5472 (define_expand "xor<V64I:mode>3"
5473 [(set (match_operand:V64I 0 "register_operand" "")
5474 (xor:V64I (match_operand:V64I 1 "arith_double_operand" "")
5475 (match_operand:V64I 2 "arith_double_operand" "")))]
5479 (define_insn "*xor<V64I:mode>3_sp32"
5480 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5481 (xor:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
5482 (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
5487 [(set_attr "type" "*,fga")
5488 (set_attr "length" "2,*")
5489 (set_attr "fptype" "*,double")])
5491 (define_insn "*xor<V64I:mode>3_sp64"
5492 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5493 (xor:V64I (match_operand:V64I 1 "arith_operand" "%rJ,b")
5494 (match_operand:V64I 2 "arith_operand" "rI,b")))]
5499 [(set_attr "type" "*,fga")
5500 (set_attr "fptype" "*,double")])
5502 (define_insn "xor<V32I:mode>3"
5503 [(set (match_operand:V32I 0 "register_operand" "=r,d")
5504 (xor:V32I (match_operand:V32I 1 "arith_operand" "%rJ,d")
5505 (match_operand:V32I 2 "arith_operand" "rI,d")))]
5510 [(set_attr "type" "*,fga")
5511 (set_attr "fptype" "*,single")])
5514 [(set (match_operand:SI 0 "register_operand" "")
5515 (xor:SI (match_operand:SI 1 "register_operand" "")
5516 (match_operand:SI 2 "const_compl_high_operand" "")))
5517 (clobber (match_operand:SI 3 "register_operand" ""))]
5519 [(set (match_dup 3) (match_dup 4))
5520 (set (match_dup 0) (not:SI (xor:SI (match_dup 3) (match_dup 1))))]
5522 operands[4] = GEN_INT (~INTVAL (operands[2]));
5526 [(set (match_operand:SI 0 "register_operand" "")
5527 (not:SI (xor:SI (match_operand:SI 1 "register_operand" "")
5528 (match_operand:SI 2 "const_compl_high_operand" ""))))
5529 (clobber (match_operand:SI 3 "register_operand" ""))]
5531 [(set (match_dup 3) (match_dup 4))
5532 (set (match_dup 0) (xor:SI (match_dup 3) (match_dup 1)))]
5534 operands[4] = GEN_INT (~INTVAL (operands[2]));
5537 ;; Split DImode logical operations requiring two instructions.
5539 [(set (match_operand:V64I 0 "register_operand" "")
5540 (match_operator:V64I 1 "cc_arith_operator" ; AND, IOR, XOR
5541 [(match_operand:V64I 2 "register_operand" "")
5542 (match_operand:V64I 3 "arith_double_operand" "")]))]
5545 && ((GET_CODE (operands[0]) == REG
5546 && REGNO (operands[0]) < 32)
5547 || (GET_CODE (operands[0]) == SUBREG
5548 && GET_CODE (SUBREG_REG (operands[0])) == REG
5549 && REGNO (SUBREG_REG (operands[0])) < 32))"
5550 [(set (match_dup 4) (match_op_dup:SI 1 [(match_dup 6) (match_dup 8)]))
5551 (set (match_dup 5) (match_op_dup:SI 1 [(match_dup 7) (match_dup 9)]))]
5553 operands[4] = gen_highpart (SImode, operands[0]);
5554 operands[5] = gen_lowpart (SImode, operands[0]);
5555 operands[6] = gen_highpart (SImode, operands[2]);
5556 operands[7] = gen_lowpart (SImode, operands[2]);
5557 #if HOST_BITS_PER_WIDE_INT == 32
5558 if (GET_CODE (operands[3]) == CONST_INT && <V64I:MODE>mode == DImode)
5560 if (INTVAL (operands[3]) < 0)
5561 operands[8] = constm1_rtx;
5563 operands[8] = const0_rtx;
5567 operands[8] = gen_highpart_mode (SImode, <V64I:MODE>mode, operands[3]);
5568 operands[9] = gen_lowpart (SImode, operands[3]);
5571 ;; xnor patterns. Note that (a ^ ~b) == (~a ^ b) == ~(a ^ b).
5572 ;; Combine now canonicalizes to the rightmost expression.
5573 (define_insn_and_split "*xor_not_<V64I:mode>_sp32"
5574 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5575 (not:V64I (xor:V64I (match_operand:V64I 1 "register_operand" "r,b")
5576 (match_operand:V64I 2 "register_operand" "r,b"))))]
5581 "&& reload_completed
5582 && ((GET_CODE (operands[0]) == REG
5583 && REGNO (operands[0]) < 32)
5584 || (GET_CODE (operands[0]) == SUBREG
5585 && GET_CODE (SUBREG_REG (operands[0])) == REG
5586 && REGNO (SUBREG_REG (operands[0])) < 32))"
5587 [(set (match_dup 3) (not:SI (xor:SI (match_dup 4) (match_dup 5))))
5588 (set (match_dup 6) (not:SI (xor:SI (match_dup 7) (match_dup 8))))]
5589 "operands[3] = gen_highpart (SImode, operands[0]);
5590 operands[4] = gen_highpart (SImode, operands[1]);
5591 operands[5] = gen_highpart (SImode, operands[2]);
5592 operands[6] = gen_lowpart (SImode, operands[0]);
5593 operands[7] = gen_lowpart (SImode, operands[1]);
5594 operands[8] = gen_lowpart (SImode, operands[2]);"
5595 [(set_attr "type" "*,fga")
5596 (set_attr "length" "2,*")
5597 (set_attr "fptype" "*,double")])
5599 (define_insn "*xor_not_<V64I:mode>_sp64"
5600 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5601 (not:V64I (xor:V64I (match_operand:V64I 1 "register_or_zero_operand" "rJ,b")
5602 (match_operand:V64I 2 "arith_operand" "rI,b"))))]
5607 [(set_attr "type" "*,fga")
5608 (set_attr "fptype" "*,double")])
5610 (define_insn "*xor_not_<V32I:mode>"
5611 [(set (match_operand:V32I 0 "register_operand" "=r,d")
5612 (not:V32I (xor:V32I (match_operand:V32I 1 "register_or_zero_operand" "rJ,d")
5613 (match_operand:V32I 2 "arith_operand" "rI,d"))))]
5618 [(set_attr "type" "*,fga")
5619 (set_attr "fptype" "*,single")])
5621 ;; These correspond to the above in the case where we also (or only)
5622 ;; want to set the condition code.
5624 (define_insn "*cmp_cc_arith_op"
5627 (match_operator:SI 2 "cc_arith_operator"
5628 [(match_operand:SI 0 "arith_operand" "%r")
5629 (match_operand:SI 1 "arith_operand" "rI")])
5632 "%A2cc\t%0, %1, %%g0"
5633 [(set_attr "type" "compare")])
5635 (define_insn "*cmp_ccx_arith_op"
5638 (match_operator:DI 2 "cc_arith_operator"
5639 [(match_operand:DI 0 "arith_operand" "%r")
5640 (match_operand:DI 1 "arith_operand" "rI")])
5643 "%A2cc\t%0, %1, %%g0"
5644 [(set_attr "type" "compare")])
5646 (define_insn "*cmp_cc_arith_op_set"
5649 (match_operator:SI 3 "cc_arith_operator"
5650 [(match_operand:SI 1 "arith_operand" "%r")
5651 (match_operand:SI 2 "arith_operand" "rI")])
5653 (set (match_operand:SI 0 "register_operand" "=r")
5654 (match_operator:SI 4 "cc_arith_operator" [(match_dup 1) (match_dup 2)]))]
5655 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
5657 [(set_attr "type" "compare")])
5659 (define_insn "*cmp_ccx_arith_op_set"
5662 (match_operator:DI 3 "cc_arith_operator"
5663 [(match_operand:DI 1 "arith_operand" "%r")
5664 (match_operand:DI 2 "arith_operand" "rI")])
5666 (set (match_operand:DI 0 "register_operand" "=r")
5667 (match_operator:DI 4 "cc_arith_operator" [(match_dup 1) (match_dup 2)]))]
5668 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
5670 [(set_attr "type" "compare")])
5672 (define_insn "*cmp_cc_xor_not"
5675 (not:SI (xor:SI (match_operand:SI 0 "register_or_zero_operand" "%rJ")
5676 (match_operand:SI 1 "arith_operand" "rI")))
5679 "xnorcc\t%r0, %1, %%g0"
5680 [(set_attr "type" "compare")])
5682 (define_insn "*cmp_ccx_xor_not"
5685 (not:DI (xor:DI (match_operand:DI 0 "register_or_zero_operand" "%rJ")
5686 (match_operand:DI 1 "arith_operand" "rI")))
5689 "xnorcc\t%r0, %1, %%g0"
5690 [(set_attr "type" "compare")])
5692 (define_insn "*cmp_cc_xor_not_set"
5695 (not:SI (xor:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ")
5696 (match_operand:SI 2 "arith_operand" "rI")))
5698 (set (match_operand:SI 0 "register_operand" "=r")
5699 (not:SI (xor:SI (match_dup 1) (match_dup 2))))]
5701 "xnorcc\t%r1, %2, %0"
5702 [(set_attr "type" "compare")])
5704 (define_insn "*cmp_ccx_xor_not_set"
5707 (not:DI (xor:DI (match_operand:DI 1 "register_or_zero_operand" "%rJ")
5708 (match_operand:DI 2 "arith_operand" "rI")))
5710 (set (match_operand:DI 0 "register_operand" "=r")
5711 (not:DI (xor:DI (match_dup 1) (match_dup 2))))]
5713 "xnorcc\t%r1, %2, %0"
5714 [(set_attr "type" "compare")])
5716 (define_insn "*cmp_cc_arith_op_not"
5719 (match_operator:SI 2 "cc_arith_not_operator"
5720 [(not:SI (match_operand:SI 0 "arith_operand" "rI"))
5721 (match_operand:SI 1 "register_or_zero_operand" "rJ")])
5724 "%B2cc\t%r1, %0, %%g0"
5725 [(set_attr "type" "compare")])
5727 (define_insn "*cmp_ccx_arith_op_not"
5730 (match_operator:DI 2 "cc_arith_not_operator"
5731 [(not:DI (match_operand:DI 0 "arith_operand" "rI"))
5732 (match_operand:DI 1 "register_or_zero_operand" "rJ")])
5735 "%B2cc\t%r1, %0, %%g0"
5736 [(set_attr "type" "compare")])
5738 (define_insn "*cmp_cc_arith_op_not_set"
5741 (match_operator:SI 3 "cc_arith_not_operator"
5742 [(not:SI (match_operand:SI 1 "arith_operand" "rI"))
5743 (match_operand:SI 2 "register_or_zero_operand" "rJ")])
5745 (set (match_operand:SI 0 "register_operand" "=r")
5746 (match_operator:SI 4 "cc_arith_not_operator"
5747 [(not:SI (match_dup 1)) (match_dup 2)]))]
5748 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
5749 "%B3cc\t%r2, %1, %0"
5750 [(set_attr "type" "compare")])
5752 (define_insn "*cmp_ccx_arith_op_not_set"
5755 (match_operator:DI 3 "cc_arith_not_operator"
5756 [(not:DI (match_operand:DI 1 "arith_operand" "rI"))
5757 (match_operand:DI 2 "register_or_zero_operand" "rJ")])
5759 (set (match_operand:DI 0 "register_operand" "=r")
5760 (match_operator:DI 4 "cc_arith_not_operator"
5761 [(not:DI (match_dup 1)) (match_dup 2)]))]
5762 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
5763 "%B3cc\t%r2, %1, %0"
5764 [(set_attr "type" "compare")])
5766 ;; We cannot use the "neg" pseudo insn because the Sun assembler
5767 ;; does not know how to make it work for constants.
5769 (define_expand "negdi2"
5770 [(set (match_operand:DI 0 "register_operand" "=r")
5771 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
5774 if (! TARGET_ARCH64)
5776 emit_insn (gen_rtx_PARALLEL
5779 gen_rtx_SET (VOIDmode, operand0,
5780 gen_rtx_NEG (DImode, operand1)),
5781 gen_rtx_CLOBBER (VOIDmode,
5782 gen_rtx_REG (CCmode,
5788 (define_insn_and_split "*negdi2_sp32"
5789 [(set (match_operand:DI 0 "register_operand" "=r")
5790 (neg:DI (match_operand:DI 1 "register_operand" "r")))
5791 (clobber (reg:CC 100))]
5794 "&& reload_completed"
5795 [(parallel [(set (reg:CC_NOOV 100)
5796 (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 5))
5798 (set (match_dup 4) (minus:SI (const_int 0) (match_dup 5)))])
5799 (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
5800 (ltu:SI (reg:CC 100) (const_int 0))))]
5801 "operands[2] = gen_highpart (SImode, operands[0]);
5802 operands[3] = gen_highpart (SImode, operands[1]);
5803 operands[4] = gen_lowpart (SImode, operands[0]);
5804 operands[5] = gen_lowpart (SImode, operands[1]);"
5805 [(set_attr "length" "2")])
5807 (define_insn "*negdi2_sp64"
5808 [(set (match_operand:DI 0 "register_operand" "=r")
5809 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
5811 "sub\t%%g0, %1, %0")
5813 (define_insn "negsi2"
5814 [(set (match_operand:SI 0 "register_operand" "=r")
5815 (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
5817 "sub\t%%g0, %1, %0")
5819 (define_insn "*cmp_cc_neg"
5820 [(set (reg:CC_NOOV 100)
5821 (compare:CC_NOOV (neg:SI (match_operand:SI 0 "arith_operand" "rI"))
5824 "subcc\t%%g0, %0, %%g0"
5825 [(set_attr "type" "compare")])
5827 (define_insn "*cmp_ccx_neg"
5828 [(set (reg:CCX_NOOV 100)
5829 (compare:CCX_NOOV (neg:DI (match_operand:DI 0 "arith_operand" "rI"))
5832 "subcc\t%%g0, %0, %%g0"
5833 [(set_attr "type" "compare")])
5835 (define_insn "*cmp_cc_set_neg"
5836 [(set (reg:CC_NOOV 100)
5837 (compare:CC_NOOV (neg:SI (match_operand:SI 1 "arith_operand" "rI"))
5839 (set (match_operand:SI 0 "register_operand" "=r")
5840 (neg:SI (match_dup 1)))]
5842 "subcc\t%%g0, %1, %0"
5843 [(set_attr "type" "compare")])
5845 (define_insn "*cmp_ccx_set_neg"
5846 [(set (reg:CCX_NOOV 100)
5847 (compare:CCX_NOOV (neg:DI (match_operand:DI 1 "arith_operand" "rI"))
5849 (set (match_operand:DI 0 "register_operand" "=r")
5850 (neg:DI (match_dup 1)))]
5852 "subcc\t%%g0, %1, %0"
5853 [(set_attr "type" "compare")])
5855 ;; We cannot use the "not" pseudo insn because the Sun assembler
5856 ;; does not know how to make it work for constants.
5857 (define_expand "one_cmpl<V64I:mode>2"
5858 [(set (match_operand:V64I 0 "register_operand" "")
5859 (not:V64I (match_operand:V64I 1 "register_operand" "")))]
5863 (define_insn_and_split "*one_cmpl<V64I:mode>2_sp32"
5864 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5865 (not:V64I (match_operand:V64I 1 "register_operand" "r,b")))]
5870 "&& reload_completed
5871 && ((GET_CODE (operands[0]) == REG
5872 && REGNO (operands[0]) < 32)
5873 || (GET_CODE (operands[0]) == SUBREG
5874 && GET_CODE (SUBREG_REG (operands[0])) == REG
5875 && REGNO (SUBREG_REG (operands[0])) < 32))"
5876 [(set (match_dup 2) (not:SI (xor:SI (match_dup 3) (const_int 0))))
5877 (set (match_dup 4) (not:SI (xor:SI (match_dup 5) (const_int 0))))]
5878 "operands[2] = gen_highpart (SImode, operands[0]);
5879 operands[3] = gen_highpart (SImode, operands[1]);
5880 operands[4] = gen_lowpart (SImode, operands[0]);
5881 operands[5] = gen_lowpart (SImode, operands[1]);"
5882 [(set_attr "type" "*,fga")
5883 (set_attr "length" "2,*")
5884 (set_attr "fptype" "*,double")])
5886 (define_insn "*one_cmpl<V64I:mode>2_sp64"
5887 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5888 (not:V64I (match_operand:V64I 1 "arith_operand" "rI,b")))]
5893 [(set_attr "type" "*,fga")
5894 (set_attr "fptype" "*,double")])
5896 (define_insn "one_cmpl<V32I:mode>2"
5897 [(set (match_operand:V32I 0 "register_operand" "=r,d")
5898 (not:V32I (match_operand:V32I 1 "arith_operand" "rI,d")))]
5903 [(set_attr "type" "*,fga")
5904 (set_attr "fptype" "*,single")])
5906 (define_insn "*cmp_cc_not"
5908 (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI"))
5911 "xnorcc\t%%g0, %0, %%g0"
5912 [(set_attr "type" "compare")])
5914 (define_insn "*cmp_ccx_not"
5916 (compare:CCX (not:DI (match_operand:DI 0 "arith_operand" "rI"))
5919 "xnorcc\t%%g0, %0, %%g0"
5920 [(set_attr "type" "compare")])
5922 (define_insn "*cmp_cc_set_not"
5924 (compare:CC (not:SI (match_operand:SI 1 "arith_operand" "rI"))
5926 (set (match_operand:SI 0 "register_operand" "=r")
5927 (not:SI (match_dup 1)))]
5929 "xnorcc\t%%g0, %1, %0"
5930 [(set_attr "type" "compare")])
5932 (define_insn "*cmp_ccx_set_not"
5934 (compare:CCX (not:DI (match_operand:DI 1 "arith_operand" "rI"))
5936 (set (match_operand:DI 0 "register_operand" "=r")
5937 (not:DI (match_dup 1)))]
5939 "xnorcc\t%%g0, %1, %0"
5940 [(set_attr "type" "compare")])
5942 (define_insn "*cmp_cc_set"
5943 [(set (match_operand:SI 0 "register_operand" "=r")
5944 (match_operand:SI 1 "register_operand" "r"))
5946 (compare:CC (match_dup 1)
5950 [(set_attr "type" "compare")])
5952 (define_insn "*cmp_ccx_set64"
5953 [(set (match_operand:DI 0 "register_operand" "=r")
5954 (match_operand:DI 1 "register_operand" "r"))
5956 (compare:CCX (match_dup 1)
5960 [(set_attr "type" "compare")])
5963 ;; Floating point arithmetic instructions.
5965 (define_expand "addtf3"
5966 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5967 (plus:TF (match_operand:TF 1 "general_operand" "")
5968 (match_operand:TF 2 "general_operand" "")))]
5969 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5970 "emit_tfmode_binop (PLUS, operands); DONE;")
5972 (define_insn "*addtf3_hq"
5973 [(set (match_operand:TF 0 "register_operand" "=e")
5974 (plus:TF (match_operand:TF 1 "register_operand" "e")
5975 (match_operand:TF 2 "register_operand" "e")))]
5976 "TARGET_FPU && TARGET_HARD_QUAD"
5978 [(set_attr "type" "fp")])
5980 (define_insn "adddf3"
5981 [(set (match_operand:DF 0 "register_operand" "=e")
5982 (plus:DF (match_operand:DF 1 "register_operand" "e")
5983 (match_operand:DF 2 "register_operand" "e")))]
5986 [(set_attr "type" "fp")
5987 (set_attr "fptype" "double")])
5989 (define_insn "addsf3"
5990 [(set (match_operand:SF 0 "register_operand" "=f")
5991 (plus:SF (match_operand:SF 1 "register_operand" "f")
5992 (match_operand:SF 2 "register_operand" "f")))]
5995 [(set_attr "type" "fp")])
5997 (define_expand "subtf3"
5998 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5999 (minus:TF (match_operand:TF 1 "general_operand" "")
6000 (match_operand:TF 2 "general_operand" "")))]
6001 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6002 "emit_tfmode_binop (MINUS, operands); DONE;")
6004 (define_insn "*subtf3_hq"
6005 [(set (match_operand:TF 0 "register_operand" "=e")
6006 (minus:TF (match_operand:TF 1 "register_operand" "e")
6007 (match_operand:TF 2 "register_operand" "e")))]
6008 "TARGET_FPU && TARGET_HARD_QUAD"
6010 [(set_attr "type" "fp")])
6012 (define_insn "subdf3"
6013 [(set (match_operand:DF 0 "register_operand" "=e")
6014 (minus:DF (match_operand:DF 1 "register_operand" "e")
6015 (match_operand:DF 2 "register_operand" "e")))]
6018 [(set_attr "type" "fp")
6019 (set_attr "fptype" "double")])
6021 (define_insn "subsf3"
6022 [(set (match_operand:SF 0 "register_operand" "=f")
6023 (minus:SF (match_operand:SF 1 "register_operand" "f")
6024 (match_operand:SF 2 "register_operand" "f")))]
6027 [(set_attr "type" "fp")])
6029 (define_expand "multf3"
6030 [(set (match_operand:TF 0 "nonimmediate_operand" "")
6031 (mult:TF (match_operand:TF 1 "general_operand" "")
6032 (match_operand:TF 2 "general_operand" "")))]
6033 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6034 "emit_tfmode_binop (MULT, operands); DONE;")
6036 (define_insn "*multf3_hq"
6037 [(set (match_operand:TF 0 "register_operand" "=e")
6038 (mult:TF (match_operand:TF 1 "register_operand" "e")
6039 (match_operand:TF 2 "register_operand" "e")))]
6040 "TARGET_FPU && TARGET_HARD_QUAD"
6042 [(set_attr "type" "fpmul")])
6044 (define_insn "muldf3"
6045 [(set (match_operand:DF 0 "register_operand" "=e")
6046 (mult:DF (match_operand:DF 1 "register_operand" "e")
6047 (match_operand:DF 2 "register_operand" "e")))]
6050 [(set_attr "type" "fpmul")
6051 (set_attr "fptype" "double")])
6053 (define_insn "mulsf3"
6054 [(set (match_operand:SF 0 "register_operand" "=f")
6055 (mult:SF (match_operand:SF 1 "register_operand" "f")
6056 (match_operand:SF 2 "register_operand" "f")))]
6059 [(set_attr "type" "fpmul")])
6061 (define_insn "*muldf3_extend"
6062 [(set (match_operand:DF 0 "register_operand" "=e")
6063 (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "f"))
6064 (float_extend:DF (match_operand:SF 2 "register_operand" "f"))))]
6065 "(TARGET_V8 || TARGET_V9) && TARGET_FPU"
6066 "fsmuld\t%1, %2, %0"
6067 [(set_attr "type" "fpmul")
6068 (set_attr "fptype" "double")])
6070 (define_insn "*multf3_extend"
6071 [(set (match_operand:TF 0 "register_operand" "=e")
6072 (mult:TF (float_extend:TF (match_operand:DF 1 "register_operand" "e"))
6073 (float_extend:TF (match_operand:DF 2 "register_operand" "e"))))]
6074 "(TARGET_V8 || TARGET_V9) && TARGET_FPU && TARGET_HARD_QUAD"
6075 "fdmulq\t%1, %2, %0"
6076 [(set_attr "type" "fpmul")])
6078 (define_expand "divtf3"
6079 [(set (match_operand:TF 0 "nonimmediate_operand" "")
6080 (div:TF (match_operand:TF 1 "general_operand" "")
6081 (match_operand:TF 2 "general_operand" "")))]
6082 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6083 "emit_tfmode_binop (DIV, operands); DONE;")
6085 ;; don't have timing for quad-prec. divide.
6086 (define_insn "*divtf3_hq"
6087 [(set (match_operand:TF 0 "register_operand" "=e")
6088 (div:TF (match_operand:TF 1 "register_operand" "e")
6089 (match_operand:TF 2 "register_operand" "e")))]
6090 "TARGET_FPU && TARGET_HARD_QUAD"
6092 [(set_attr "type" "fpdivd")])
6094 (define_insn "divdf3"
6095 [(set (match_operand:DF 0 "register_operand" "=e")
6096 (div:DF (match_operand:DF 1 "register_operand" "e")
6097 (match_operand:DF 2 "register_operand" "e")))]
6100 [(set_attr "type" "fpdivd")
6101 (set_attr "fptype" "double")])
6103 (define_insn "divsf3"
6104 [(set (match_operand:SF 0 "register_operand" "=f")
6105 (div:SF (match_operand:SF 1 "register_operand" "f")
6106 (match_operand:SF 2 "register_operand" "f")))]
6109 [(set_attr "type" "fpdivs")])
6111 (define_expand "negtf2"
6112 [(set (match_operand:TF 0 "register_operand" "=e,e")
6113 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
6117 (define_insn_and_split "*negtf2_notv9"
6118 [(set (match_operand:TF 0 "register_operand" "=e,e")
6119 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
6120 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
6126 "&& reload_completed
6127 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6128 [(set (match_dup 2) (neg:SF (match_dup 3)))
6129 (set (match_dup 4) (match_dup 5))
6130 (set (match_dup 6) (match_dup 7))]
6131 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6132 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6133 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6134 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
6135 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6136 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6137 [(set_attr "type" "fpmove,*")
6138 (set_attr "length" "*,2")])
6140 (define_insn_and_split "*negtf2_v9"
6141 [(set (match_operand:TF 0 "register_operand" "=e,e")
6142 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
6143 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
6144 "TARGET_FPU && TARGET_V9"
6148 "&& reload_completed
6149 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6150 [(set (match_dup 2) (neg:DF (match_dup 3)))
6151 (set (match_dup 4) (match_dup 5))]
6152 "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
6153 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
6154 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6155 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6156 [(set_attr "type" "fpmove,*")
6157 (set_attr "length" "*,2")
6158 (set_attr "fptype" "double")])
6160 (define_expand "negdf2"
6161 [(set (match_operand:DF 0 "register_operand" "")
6162 (neg:DF (match_operand:DF 1 "register_operand" "")))]
6166 (define_insn_and_split "*negdf2_notv9"
6167 [(set (match_operand:DF 0 "register_operand" "=e,e")
6168 (neg:DF (match_operand:DF 1 "register_operand" "0,e")))]
6169 "TARGET_FPU && ! TARGET_V9"
6173 "&& reload_completed
6174 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6175 [(set (match_dup 2) (neg:SF (match_dup 3)))
6176 (set (match_dup 4) (match_dup 5))]
6177 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6178 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6179 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6180 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);"
6181 [(set_attr "type" "fpmove,*")
6182 (set_attr "length" "*,2")])
6184 (define_insn "*negdf2_v9"
6185 [(set (match_operand:DF 0 "register_operand" "=e")
6186 (neg:DF (match_operand:DF 1 "register_operand" "e")))]
6187 "TARGET_FPU && TARGET_V9"
6189 [(set_attr "type" "fpmove")
6190 (set_attr "fptype" "double")])
6192 (define_insn "negsf2"
6193 [(set (match_operand:SF 0 "register_operand" "=f")
6194 (neg:SF (match_operand:SF 1 "register_operand" "f")))]
6197 [(set_attr "type" "fpmove")])
6199 (define_expand "abstf2"
6200 [(set (match_operand:TF 0 "register_operand" "")
6201 (abs:TF (match_operand:TF 1 "register_operand" "")))]
6205 (define_insn_and_split "*abstf2_notv9"
6206 [(set (match_operand:TF 0 "register_operand" "=e,e")
6207 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6208 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
6209 "TARGET_FPU && ! TARGET_V9"
6213 "&& reload_completed
6214 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6215 [(set (match_dup 2) (abs:SF (match_dup 3)))
6216 (set (match_dup 4) (match_dup 5))
6217 (set (match_dup 6) (match_dup 7))]
6218 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6219 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6220 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6221 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
6222 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6223 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6224 [(set_attr "type" "fpmove,*")
6225 (set_attr "length" "*,2")])
6227 (define_insn "*abstf2_hq_v9"
6228 [(set (match_operand:TF 0 "register_operand" "=e,e")
6229 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6230 "TARGET_FPU && TARGET_V9 && TARGET_HARD_QUAD"
6234 [(set_attr "type" "fpmove")
6235 (set_attr "fptype" "double,*")])
6237 (define_insn_and_split "*abstf2_v9"
6238 [(set (match_operand:TF 0 "register_operand" "=e,e")
6239 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6240 "TARGET_FPU && TARGET_V9 && !TARGET_HARD_QUAD"
6244 "&& reload_completed
6245 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6246 [(set (match_dup 2) (abs:DF (match_dup 3)))
6247 (set (match_dup 4) (match_dup 5))]
6248 "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
6249 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
6250 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6251 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6252 [(set_attr "type" "fpmove,*")
6253 (set_attr "length" "*,2")
6254 (set_attr "fptype" "double,*")])
6256 (define_expand "absdf2"
6257 [(set (match_operand:DF 0 "register_operand" "")
6258 (abs:DF (match_operand:DF 1 "register_operand" "")))]
6262 (define_insn_and_split "*absdf2_notv9"
6263 [(set (match_operand:DF 0 "register_operand" "=e,e")
6264 (abs:DF (match_operand:DF 1 "register_operand" "0,e")))]
6265 "TARGET_FPU && ! TARGET_V9"
6269 "&& reload_completed
6270 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6271 [(set (match_dup 2) (abs:SF (match_dup 3)))
6272 (set (match_dup 4) (match_dup 5))]
6273 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6274 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6275 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6276 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);"
6277 [(set_attr "type" "fpmove,*")
6278 (set_attr "length" "*,2")])
6280 (define_insn "*absdf2_v9"
6281 [(set (match_operand:DF 0 "register_operand" "=e")
6282 (abs:DF (match_operand:DF 1 "register_operand" "e")))]
6283 "TARGET_FPU && TARGET_V9"
6285 [(set_attr "type" "fpmove")
6286 (set_attr "fptype" "double")])
6288 (define_insn "abssf2"
6289 [(set (match_operand:SF 0 "register_operand" "=f")
6290 (abs:SF (match_operand:SF 1 "register_operand" "f")))]
6293 [(set_attr "type" "fpmove")])
6295 (define_expand "sqrttf2"
6296 [(set (match_operand:TF 0 "nonimmediate_operand" "")
6297 (sqrt:TF (match_operand:TF 1 "general_operand" "")))]
6298 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6299 "emit_tfmode_unop (SQRT, operands); DONE;")
6301 (define_insn "*sqrttf2_hq"
6302 [(set (match_operand:TF 0 "register_operand" "=e")
6303 (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
6304 "TARGET_FPU && TARGET_HARD_QUAD"
6306 [(set_attr "type" "fpsqrtd")])
6308 (define_insn "sqrtdf2"
6309 [(set (match_operand:DF 0 "register_operand" "=e")
6310 (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
6313 [(set_attr "type" "fpsqrtd")
6314 (set_attr "fptype" "double")])
6316 (define_insn "sqrtsf2"
6317 [(set (match_operand:SF 0 "register_operand" "=f")
6318 (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
6321 [(set_attr "type" "fpsqrts")])
6324 ;; Arithmetic shift instructions.
6326 (define_insn "ashlsi3"
6327 [(set (match_operand:SI 0 "register_operand" "=r")
6328 (ashift:SI (match_operand:SI 1 "register_operand" "r")
6329 (match_operand:SI 2 "arith_operand" "rI")))]
6332 if (GET_CODE (operands[2]) == CONST_INT)
6333 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6334 return "sll\t%1, %2, %0";
6337 (if_then_else (match_operand 2 "const_one_operand" "")
6338 (const_string "ialu") (const_string "shift")))])
6340 (define_expand "ashldi3"
6341 [(set (match_operand:DI 0 "register_operand" "=r")
6342 (ashift:DI (match_operand:DI 1 "register_operand" "r")
6343 (match_operand:SI 2 "arith_operand" "rI")))]
6344 "TARGET_ARCH64 || TARGET_V8PLUS"
6346 if (! TARGET_ARCH64)
6348 if (GET_CODE (operands[2]) == CONST_INT)
6350 emit_insn (gen_ashldi3_v8plus (operands[0], operands[1], operands[2]));
6355 (define_insn "*ashldi3_sp64"
6356 [(set (match_operand:DI 0 "register_operand" "=r")
6357 (ashift:DI (match_operand:DI 1 "register_operand" "r")
6358 (match_operand:SI 2 "arith_operand" "rI")))]
6361 if (GET_CODE (operands[2]) == CONST_INT)
6362 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
6363 return "sllx\t%1, %2, %0";
6366 (if_then_else (match_operand 2 "const_one_operand" "")
6367 (const_string "ialu") (const_string "shift")))])
6370 (define_insn "ashldi3_v8plus"
6371 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
6372 (ashift:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
6373 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
6374 (clobber (match_scratch:SI 3 "=X,X,&h"))]
6376 "* return output_v8plus_shift (operands, insn, \"sllx\");"
6377 [(set_attr "type" "multi")
6378 (set_attr "length" "5,5,6")])
6380 ;; Optimize (1LL<<x)-1
6381 ;; XXX this also needs to be fixed to handle equal subregs
6382 ;; XXX first before we could re-enable it.
6384 ; [(set (match_operand:DI 0 "register_operand" "=h")
6385 ; (plus:DI (ashift:DI (const_int 1)
6386 ; (match_operand:SI 1 "arith_operand" "rI"))
6388 ; "0 && TARGET_V8PLUS"
6390 ; if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == REGNO (operands[0]))
6391 ; return "mov\t1, %L0\;sllx\t%L0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
6392 ; return "mov\t1, %H0\;sllx\t%H0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
6394 ; [(set_attr "type" "multi")
6395 ; (set_attr "length" "4")])
6397 (define_insn "*cmp_cc_ashift_1"
6398 [(set (reg:CC_NOOV 100)
6399 (compare:CC_NOOV (ashift:SI (match_operand:SI 0 "register_operand" "r")
6403 "addcc\t%0, %0, %%g0"
6404 [(set_attr "type" "compare")])
6406 (define_insn "*cmp_cc_set_ashift_1"
6407 [(set (reg:CC_NOOV 100)
6408 (compare:CC_NOOV (ashift:SI (match_operand:SI 1 "register_operand" "r")
6411 (set (match_operand:SI 0 "register_operand" "=r")
6412 (ashift:SI (match_dup 1) (const_int 1)))]
6415 [(set_attr "type" "compare")])
6417 (define_insn "ashrsi3"
6418 [(set (match_operand:SI 0 "register_operand" "=r")
6419 (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
6420 (match_operand:SI 2 "arith_operand" "rI")))]
6423 if (GET_CODE (operands[2]) == CONST_INT)
6424 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6425 return "sra\t%1, %2, %0";
6427 [(set_attr "type" "shift")])
6429 (define_insn "*ashrsi3_extend"
6430 [(set (match_operand:DI 0 "register_operand" "=r")
6431 (sign_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
6432 (match_operand:SI 2 "arith_operand" "r"))))]
6435 [(set_attr "type" "shift")])
6437 ;; This handles the case as above, but with constant shift instead of
6438 ;; register. Combiner "simplifies" it for us a little bit though.
6439 (define_insn "*ashrsi3_extend2"
6440 [(set (match_operand:DI 0 "register_operand" "=r")
6441 (ashiftrt:DI (ashift:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
6443 (match_operand:SI 2 "small_int_operand" "I")))]
6444 "TARGET_ARCH64 && INTVAL (operands[2]) >= 32 && INTVAL (operands[2]) < 64"
6446 operands[2] = GEN_INT (INTVAL (operands[2]) - 32);
6447 return "sra\t%1, %2, %0";
6449 [(set_attr "type" "shift")])
6451 (define_expand "ashrdi3"
6452 [(set (match_operand:DI 0 "register_operand" "=r")
6453 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
6454 (match_operand:SI 2 "arith_operand" "rI")))]
6455 "TARGET_ARCH64 || TARGET_V8PLUS"
6457 if (! TARGET_ARCH64)
6459 if (GET_CODE (operands[2]) == CONST_INT)
6460 FAIL; /* prefer generic code in this case */
6461 emit_insn (gen_ashrdi3_v8plus (operands[0], operands[1], operands[2]));
6466 (define_insn "*ashrdi3_sp64"
6467 [(set (match_operand:DI 0 "register_operand" "=r")
6468 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
6469 (match_operand:SI 2 "arith_operand" "rI")))]
6473 if (GET_CODE (operands[2]) == CONST_INT)
6474 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
6475 return "srax\t%1, %2, %0";
6477 [(set_attr "type" "shift")])
6480 (define_insn "ashrdi3_v8plus"
6481 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
6482 (ashiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
6483 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
6484 (clobber (match_scratch:SI 3 "=X,X,&h"))]
6486 "* return output_v8plus_shift (operands, insn, \"srax\");"
6487 [(set_attr "type" "multi")
6488 (set_attr "length" "5,5,6")])
6490 (define_insn "lshrsi3"
6491 [(set (match_operand:SI 0 "register_operand" "=r")
6492 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
6493 (match_operand:SI 2 "arith_operand" "rI")))]
6496 if (GET_CODE (operands[2]) == CONST_INT)
6497 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6498 return "srl\t%1, %2, %0";
6500 [(set_attr "type" "shift")])
6502 ;; This handles the case where
6503 ;; (zero_extend:DI (lshiftrt:SI (match_operand:SI) (match_operand:SI))),
6504 ;; but combiner "simplifies" it for us.
6505 (define_insn "*lshrsi3_extend"
6506 [(set (match_operand:DI 0 "register_operand" "=r")
6507 (and:DI (subreg:DI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
6508 (match_operand:SI 2 "arith_operand" "r")) 0)
6509 (match_operand 3 "const_int_operand" "")))]
6510 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) == 0xffffffff"
6512 [(set_attr "type" "shift")])
6514 ;; This handles the case where
6515 ;; (lshiftrt:DI (zero_extend:DI (match_operand:SI)) (const_int >=0 < 32))
6516 ;; but combiner "simplifies" it for us.
6517 (define_insn "*lshrsi3_extend2"
6518 [(set (match_operand:DI 0 "register_operand" "=r")
6519 (zero_extract:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
6520 (match_operand 2 "small_int_operand" "I")
6522 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
6524 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
6525 return "srl\t%1, %2, %0";
6527 [(set_attr "type" "shift")])
6529 (define_expand "lshrdi3"
6530 [(set (match_operand:DI 0 "register_operand" "=r")
6531 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6532 (match_operand:SI 2 "arith_operand" "rI")))]
6533 "TARGET_ARCH64 || TARGET_V8PLUS"
6535 if (! TARGET_ARCH64)
6537 if (GET_CODE (operands[2]) == CONST_INT)
6539 emit_insn (gen_lshrdi3_v8plus (operands[0], operands[1], operands[2]));
6544 (define_insn "*lshrdi3_sp64"
6545 [(set (match_operand:DI 0 "register_operand" "=r")
6546 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6547 (match_operand:SI 2 "arith_operand" "rI")))]
6550 if (GET_CODE (operands[2]) == CONST_INT)
6551 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
6552 return "srlx\t%1, %2, %0";
6554 [(set_attr "type" "shift")])
6557 (define_insn "lshrdi3_v8plus"
6558 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
6559 (lshiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
6560 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
6561 (clobber (match_scratch:SI 3 "=X,X,&h"))]
6563 "* return output_v8plus_shift (operands, insn, \"srlx\");"
6564 [(set_attr "type" "multi")
6565 (set_attr "length" "5,5,6")])
6568 [(set (match_operand:SI 0 "register_operand" "=r")
6569 (ashiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6571 (match_operand:SI 2 "small_int_operand" "I")))]
6572 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
6574 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
6575 return "srax\t%1, %2, %0";
6577 [(set_attr "type" "shift")])
6580 [(set (match_operand:SI 0 "register_operand" "=r")
6581 (lshiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
6583 (match_operand:SI 2 "small_int_operand" "I")))]
6584 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
6586 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
6587 return "srlx\t%1, %2, %0";
6589 [(set_attr "type" "shift")])
6592 [(set (match_operand:SI 0 "register_operand" "=r")
6593 (ashiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
6594 (match_operand:SI 2 "small_int_operand" "I")) 4)
6595 (match_operand:SI 3 "small_int_operand" "I")))]
6597 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
6598 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
6599 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
6601 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
6603 return "srax\t%1, %2, %0";
6605 [(set_attr "type" "shift")])
6608 [(set (match_operand:SI 0 "register_operand" "=r")
6609 (lshiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6610 (match_operand:SI 2 "small_int_operand" "I")) 4)
6611 (match_operand:SI 3 "small_int_operand" "I")))]
6613 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
6614 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
6615 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
6617 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
6619 return "srlx\t%1, %2, %0";
6621 [(set_attr "type" "shift")])
6624 ;; Unconditional and other jump instructions.
6627 [(set (pc) (label_ref (match_operand 0 "" "")))]
6629 "* return output_ubranch (operands[0], 0, insn);"
6630 [(set_attr "type" "uncond_branch")])
6632 (define_expand "tablejump"
6633 [(parallel [(set (pc) (match_operand 0 "register_operand" "r"))
6634 (use (label_ref (match_operand 1 "" "")))])]
6637 gcc_assert (GET_MODE (operands[0]) == CASE_VECTOR_MODE);
6639 /* In pic mode, our address differences are against the base of the
6640 table. Add that base value back in; CSE ought to be able to combine
6641 the two address loads. */
6645 tmp = gen_rtx_LABEL_REF (Pmode, operands[1]);
6647 if (CASE_VECTOR_MODE != Pmode)
6648 tmp2 = gen_rtx_SIGN_EXTEND (Pmode, tmp2);
6649 tmp = gen_rtx_PLUS (Pmode, tmp2, tmp);
6650 operands[0] = memory_address (Pmode, tmp);
6654 (define_insn "*tablejump_sp32"
6655 [(set (pc) (match_operand:SI 0 "address_operand" "p"))
6656 (use (label_ref (match_operand 1 "" "")))]
6659 [(set_attr "type" "uncond_branch")])
6661 (define_insn "*tablejump_sp64"
6662 [(set (pc) (match_operand:DI 0 "address_operand" "p"))
6663 (use (label_ref (match_operand 1 "" "")))]
6666 [(set_attr "type" "uncond_branch")])
6669 ;; Jump to subroutine instructions.
6671 (define_expand "call"
6672 ;; Note that this expression is not used for generating RTL.
6673 ;; All the RTL is generated explicitly below.
6674 [(call (match_operand 0 "call_operand" "")
6675 (match_operand 3 "" "i"))]
6676 ;; operands[2] is next_arg_register
6677 ;; operands[3] is struct_value_size_rtx.
6682 gcc_assert (GET_MODE (operands[0]) == FUNCTION_MODE);
6684 gcc_assert (GET_CODE (operands[3]) == CONST_INT);
6686 if (GET_CODE (XEXP (operands[0], 0)) == LABEL_REF)
6688 /* This is really a PIC sequence. We want to represent
6689 it as a funny jump so its delay slots can be filled.
6691 ??? But if this really *is* a CALL, will not it clobber the
6692 call-clobbered registers? We lose this if it is a JUMP_INSN.
6693 Why cannot we have delay slots filled if it were a CALL? */
6695 /* We accept negative sizes for untyped calls. */
6696 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
6701 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
6703 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
6709 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
6710 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
6714 fn_rtx = operands[0];
6716 /* We accept negative sizes for untyped calls. */
6717 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
6721 gen_rtvec (3, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx),
6723 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
6728 gen_rtvec (2, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx),
6729 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
6736 ;; We can't use the same pattern for these two insns, because then registers
6737 ;; in the address may not be properly reloaded.
6739 (define_insn "*call_address_sp32"
6740 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6741 (match_operand 1 "" ""))
6742 (clobber (reg:SI 15))]
6743 ;;- Do not use operand 1 for most machines.
6746 [(set_attr "type" "call")])
6748 (define_insn "*call_symbolic_sp32"
6749 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6750 (match_operand 1 "" ""))
6751 (clobber (reg:SI 15))]
6752 ;;- Do not use operand 1 for most machines.
6755 [(set_attr "type" "call")])
6757 (define_insn "*call_address_sp64"
6758 [(call (mem:DI (match_operand:DI 0 "address_operand" "p"))
6759 (match_operand 1 "" ""))
6760 (clobber (reg:DI 15))]
6761 ;;- Do not use operand 1 for most machines.
6764 [(set_attr "type" "call")])
6766 (define_insn "*call_symbolic_sp64"
6767 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
6768 (match_operand 1 "" ""))
6769 (clobber (reg:DI 15))]
6770 ;;- Do not use operand 1 for most machines.
6773 [(set_attr "type" "call")])
6775 ;; This is a call that wants a structure value.
6776 ;; There is no such critter for v9 (??? we may need one anyway).
6777 (define_insn "*call_address_struct_value_sp32"
6778 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6779 (match_operand 1 "" ""))
6780 (match_operand 2 "immediate_operand" "")
6781 (clobber (reg:SI 15))]
6782 ;;- Do not use operand 1 for most machines.
6783 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
6785 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xfff);
6786 return "call\t%a0, %1\n\t nop\n\tunimp\t%2";
6788 [(set_attr "type" "call_no_delay_slot")
6789 (set_attr "length" "3")])
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_symbolic_struct_value_sp32"
6794 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
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 may want a structure value. This is used for
6809 (define_insn "*call_address_untyped_struct_value_sp32"
6810 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
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"
6816 "call\t%a0, %1\n\t nop\n\tnop"
6817 [(set_attr "type" "call_no_delay_slot")
6818 (set_attr "length" "3")])
6820 ;; This is a call that may want a structure value. This is used for
6822 (define_insn "*call_symbolic_untyped_struct_value_sp32"
6823 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6824 (match_operand 1 "" ""))
6825 (match_operand 2 "immediate_operand" "")
6826 (clobber (reg:SI 15))]
6827 ;;- Do not use operand 1 for most machines.
6828 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
6829 "call\t%a0, %1\n\t nop\n\tnop"
6830 [(set_attr "type" "call_no_delay_slot")
6831 (set_attr "length" "3")])
6833 (define_expand "call_value"
6834 ;; Note that this expression is not used for generating RTL.
6835 ;; All the RTL is generated explicitly below.
6836 [(set (match_operand 0 "register_operand" "=rf")
6837 (call (match_operand 1 "" "")
6838 (match_operand 4 "" "")))]
6839 ;; operand 2 is stack_size_rtx
6840 ;; operand 3 is next_arg_register
6846 gcc_assert (GET_MODE (operands[1]) == FUNCTION_MODE);
6848 fn_rtx = operands[1];
6851 gen_rtx_SET (VOIDmode, operands[0],
6852 gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx)),
6853 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)));
6855 emit_call_insn (gen_rtx_PARALLEL (VOIDmode, vec));
6860 (define_insn "*call_value_address_sp32"
6861 [(set (match_operand 0 "" "=rf")
6862 (call (mem:SI (match_operand:SI 1 "address_operand" "p"))
6863 (match_operand 2 "" "")))
6864 (clobber (reg:SI 15))]
6865 ;;- Do not use operand 2 for most machines.
6868 [(set_attr "type" "call")])
6870 (define_insn "*call_value_symbolic_sp32"
6871 [(set (match_operand 0 "" "=rf")
6872 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
6873 (match_operand 2 "" "")))
6874 (clobber (reg:SI 15))]
6875 ;;- Do not use operand 2 for most machines.
6878 [(set_attr "type" "call")])
6880 (define_insn "*call_value_address_sp64"
6881 [(set (match_operand 0 "" "")
6882 (call (mem:DI (match_operand:DI 1 "address_operand" "p"))
6883 (match_operand 2 "" "")))
6884 (clobber (reg:DI 15))]
6885 ;;- Do not use operand 2 for most machines.
6888 [(set_attr "type" "call")])
6890 (define_insn "*call_value_symbolic_sp64"
6891 [(set (match_operand 0 "" "")
6892 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
6893 (match_operand 2 "" "")))
6894 (clobber (reg:DI 15))]
6895 ;;- Do not use operand 2 for most machines.
6898 [(set_attr "type" "call")])
6900 (define_expand "untyped_call"
6901 [(parallel [(call (match_operand 0 "" "")
6903 (match_operand:BLK 1 "memory_operand" "")
6904 (match_operand 2 "" "")])]
6907 rtx valreg1 = gen_rtx_REG (DImode, 8);
6908 rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
6909 rtx result = operands[1];
6911 /* Pass constm1 to indicate that it may expect a structure value, but
6912 we don't know what size it is. */
6913 emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, constm1_rtx));
6915 /* Save the function value registers. */
6916 emit_move_insn (adjust_address (result, DImode, 0), valreg1);
6917 emit_move_insn (adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8),
6920 /* The optimizer does not know that the call sets the function value
6921 registers we stored in the result block. We avoid problems by
6922 claiming that all hard registers are used and clobbered at this
6924 emit_insn (gen_blockage ());
6929 ;; Tail call instructions.
6931 (define_expand "sibcall"
6932 [(parallel [(call (match_operand 0 "call_operand" "") (const_int 0))
6937 (define_insn "*sibcall_symbolic_sp32"
6938 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6939 (match_operand 1 "" ""))
6942 "* return output_sibcall(insn, operands[0]);"
6943 [(set_attr "type" "sibcall")])
6945 (define_insn "*sibcall_symbolic_sp64"
6946 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
6947 (match_operand 1 "" ""))
6950 "* return output_sibcall(insn, operands[0]);"
6951 [(set_attr "type" "sibcall")])
6953 (define_expand "sibcall_value"
6954 [(parallel [(set (match_operand 0 "register_operand" "=rf")
6955 (call (match_operand 1 "" "") (const_int 0)))
6960 (define_insn "*sibcall_value_symbolic_sp32"
6961 [(set (match_operand 0 "" "=rf")
6962 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
6963 (match_operand 2 "" "")))
6966 "* return output_sibcall(insn, operands[1]);"
6967 [(set_attr "type" "sibcall")])
6969 (define_insn "*sibcall_value_symbolic_sp64"
6970 [(set (match_operand 0 "" "")
6971 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
6972 (match_operand 2 "" "")))
6975 "* return output_sibcall(insn, operands[1]);"
6976 [(set_attr "type" "sibcall")])
6979 ;; Special instructions.
6981 (define_expand "prologue"
6985 sparc_expand_prologue ();
6989 ;; The "save register window" insn is modelled as follows so that the DWARF-2
6990 ;; backend automatically emits the required call frame debugging information
6991 ;; while it is parsing it. Therefore, the pattern should not be modified
6992 ;; without first studying the impact of the changes on the debug info.
6993 ;; [(set (%fp) (%sp))
6994 ;; (set (%sp) (unspec_volatile [(%sp) (-frame_size)] UNSPECV_SAVEW))
6995 ;; (set (%i7) (%o7))]
6997 (define_insn "save_register_window<P:mode>"
6998 [(set (reg:P 30) (reg:P 14))
6999 (set (reg:P 14) (unspec_volatile:P [(reg:P 14)
7000 (match_operand:P 0 "arith_operand" "rI")] UNSPECV_SAVEW))
7001 (set (reg:P 31) (reg:P 15))]
7003 "save\t%%sp, %0, %%sp"
7004 [(set_attr "type" "savew")])
7006 (define_expand "epilogue"
7010 sparc_expand_epilogue ();
7013 (define_expand "sibcall_epilogue"
7017 sparc_expand_epilogue ();
7021 (define_expand "return"
7023 "sparc_can_use_return_insn_p ()"
7026 (define_insn "*return_internal"
7029 "* return output_return (insn);"
7030 [(set_attr "type" "return")
7031 (set (attr "length")
7032 (cond [(eq_attr "leaf_function" "true")
7033 (if_then_else (eq_attr "empty_delay_slot" "true")
7036 (eq_attr "calls_eh_return" "true")
7037 (if_then_else (eq_attr "delayed_branch" "true")
7038 (if_then_else (eq_attr "isa" "v9")
7041 (if_then_else (eq_attr "isa" "v9")
7044 (eq_attr "empty_delay_slot" "true")
7045 (if_then_else (eq_attr "delayed_branch" "true")
7050 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
7051 ;; all of memory. This blocks insns from being moved across this point.
7053 (define_insn "blockage"
7054 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
7057 [(set_attr "length" "0")])
7059 ;; Prepare to return any type including a structure value.
7061 (define_expand "untyped_return"
7062 [(match_operand:BLK 0 "memory_operand" "")
7063 (match_operand 1 "" "")]
7066 rtx valreg1 = gen_rtx_REG (DImode, 24);
7067 rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
7068 rtx result = operands[0];
7070 if (! TARGET_ARCH64)
7072 rtx rtnreg = gen_rtx_REG (SImode, (current_function_uses_only_leaf_regs
7074 rtx value = gen_reg_rtx (SImode);
7076 /* Fetch the instruction where we will return to and see if it's an unimp
7077 instruction (the most significant 10 bits will be zero). If so,
7078 update the return address to skip the unimp instruction. */
7079 emit_move_insn (value,
7080 gen_rtx_MEM (SImode, plus_constant (rtnreg, 8)));
7081 emit_insn (gen_lshrsi3 (value, value, GEN_INT (22)));
7082 emit_insn (gen_update_return (rtnreg, value));
7085 /* Reload the function value registers. */
7086 emit_move_insn (valreg1, adjust_address (result, DImode, 0));
7087 emit_move_insn (valreg2,
7088 adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8));
7090 /* Put USE insns before the return. */
7091 emit_insn (gen_rtx_USE (VOIDmode, valreg1));
7092 emit_insn (gen_rtx_USE (VOIDmode, valreg2));
7094 /* Construct the return. */
7095 expand_naked_return ();
7100 ;; This is a bit of a hack. We're incrementing a fixed register (%i7),
7101 ;; and parts of the compiler don't want to believe that the add is needed.
7103 (define_insn "update_return"
7104 [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
7105 (match_operand:SI 1 "register_operand" "r")] UNSPEC_UPDATE_RETURN)]
7108 if (flag_delayed_branch)
7109 return "cmp\t%1, 0\n\tbe,a\t.+8\n\t add\t%0, 4, %0";
7111 return "cmp\t%1, 0\n\tbne\t.+12\n\t nop\n\tadd\t%0, 4, %0";
7113 [(set (attr "type") (const_string "multi"))
7114 (set (attr "length")
7115 (if_then_else (eq_attr "delayed_branch" "true")
7124 (define_expand "indirect_jump"
7125 [(set (pc) (match_operand 0 "address_operand" "p"))]
7129 (define_insn "*branch_sp32"
7130 [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
7133 [(set_attr "type" "uncond_branch")])
7135 (define_insn "*branch_sp64"
7136 [(set (pc) (match_operand:DI 0 "address_operand" "p"))]
7139 [(set_attr "type" "uncond_branch")])
7141 (define_expand "nonlocal_goto"
7142 [(match_operand:SI 0 "general_operand" "")
7143 (match_operand:SI 1 "general_operand" "")
7144 (match_operand:SI 2 "general_operand" "")
7145 (match_operand:SI 3 "" "")]
7148 rtx lab = operands[1];
7149 rtx stack = operands[2];
7150 rtx fp = operands[3];
7153 /* Trap instruction to flush all the register windows. */
7154 emit_insn (gen_flush_register_windows ());
7156 /* Load the fp value for the containing fn into %fp. This is needed
7157 because STACK refers to %fp. Note that virtual register instantiation
7158 fails if the virtual %fp isn't set from a register. */
7159 if (GET_CODE (fp) != REG)
7160 fp = force_reg (Pmode, fp);
7161 emit_move_insn (virtual_stack_vars_rtx, fp);
7163 /* Find the containing function's current nonlocal goto handler,
7164 which will do any cleanups and then jump to the label. */
7165 labreg = gen_rtx_REG (Pmode, 8);
7166 emit_move_insn (labreg, lab);
7168 /* Restore %fp from stack pointer value for containing function.
7169 The restore insn that follows will move this to %sp,
7170 and reload the appropriate value into %fp. */
7171 emit_move_insn (hard_frame_pointer_rtx, stack);
7173 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
7174 emit_insn (gen_rtx_USE (VOIDmode, static_chain_rtx));
7176 /* ??? The V9-specific version was disabled in rev 1.65. */
7177 emit_jump_insn (gen_goto_handler_and_restore (labreg));
7182 ;; Special trap insn to flush register windows.
7183 (define_insn "flush_register_windows"
7184 [(unspec_volatile [(const_int 0)] UNSPECV_FLUSHW)]
7186 { return TARGET_V9 ? "flushw" : "ta\t3"; }
7187 [(set_attr "type" "flushw")])
7189 (define_insn "goto_handler_and_restore"
7190 [(unspec_volatile [(match_operand 0 "register_operand" "=r")] UNSPECV_GOTO)]
7191 "GET_MODE (operands[0]) == Pmode"
7193 if (flag_delayed_branch)
7194 return "jmp\t%0\n\t restore";
7196 return "mov\t%0,%%g1\n\trestore\n\tjmp\t%%g1\n\t nop";
7198 [(set (attr "type") (const_string "multi"))
7199 (set (attr "length")
7200 (if_then_else (eq_attr "delayed_branch" "true")
7204 ;; For __builtin_setjmp we need to flush register windows iff the function
7205 ;; calls alloca as well, because otherwise the register window might be
7206 ;; saved after %sp adjustment and thus setjmp would crash
7207 (define_expand "builtin_setjmp_setup"
7208 [(match_operand 0 "register_operand" "r")]
7211 emit_insn (gen_do_builtin_setjmp_setup ());
7215 (define_insn "do_builtin_setjmp_setup"
7216 [(unspec_volatile [(const_int 0)] UNSPECV_SETJMP)]
7219 if (! current_function_calls_alloca)
7223 fputs ("\tflushw\n", asm_out_file);
7225 fprintf (asm_out_file, "\tst%c\t%%l7, [%%sp+%d]\n",
7226 TARGET_ARCH64 ? 'x' : 'w',
7227 SPARC_STACK_BIAS + 7 * UNITS_PER_WORD);
7228 fprintf (asm_out_file, "\tst%c\t%%fp, [%%sp+%d]\n",
7229 TARGET_ARCH64 ? 'x' : 'w',
7230 SPARC_STACK_BIAS + 14 * UNITS_PER_WORD);
7231 fprintf (asm_out_file, "\tst%c\t%%i7, [%%sp+%d]\n",
7232 TARGET_ARCH64 ? 'x' : 'w',
7233 SPARC_STACK_BIAS + 15 * UNITS_PER_WORD);
7236 [(set_attr "type" "multi")
7237 (set (attr "length")
7238 (cond [(eq_attr "calls_alloca" "false")
7240 (eq_attr "isa" "!v9")
7242 (eq_attr "pic" "true")
7243 (const_int 4)] (const_int 3)))])
7245 ;; Pattern for use after a setjmp to store FP and the return register
7246 ;; into the stack area.
7248 (define_expand "setjmp"
7253 emit_insn (gen_setjmp_64 ());
7255 emit_insn (gen_setjmp_32 ());
7259 (define_expand "setjmp_32"
7260 [(set (mem:SI (plus:SI (reg:SI 14) (const_int 56))) (match_dup 0))
7261 (set (mem:SI (plus:SI (reg:SI 14) (const_int 60))) (reg:SI 31))]
7263 { operands[0] = frame_pointer_rtx; })
7265 (define_expand "setjmp_64"
7266 [(set (mem:DI (plus:DI (reg:DI 14) (const_int 112))) (match_dup 0))
7267 (set (mem:DI (plus:DI (reg:DI 14) (const_int 120))) (reg:DI 31))]
7269 { operands[0] = frame_pointer_rtx; })
7271 ;; Special pattern for the FLUSH instruction.
7273 ; We do SImode and DImode versions of this to quiet down genrecog's complaints
7274 ; of the define_insn otherwise missing a mode. We make "flush", aka
7275 ; gen_flush, the default one since sparc_initialize_trampoline uses
7276 ; it on SImode mem values.
7278 (define_insn "flush"
7279 [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")] UNSPECV_FLUSH)]
7281 { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; }
7282 [(set_attr "type" "iflush")])
7284 (define_insn "flushdi"
7285 [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")] UNSPECV_FLUSH)]
7287 { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; }
7288 [(set_attr "type" "iflush")])
7291 ;; Find first set instructions.
7293 ;; The scan instruction searches from the most significant bit while ffs
7294 ;; searches from the least significant bit. The bit index and treatment of
7295 ;; zero also differ. It takes at least 7 instructions to get the proper
7296 ;; result. Here is an obvious 8 instruction sequence.
7299 (define_insn "ffssi2"
7300 [(set (match_operand:SI 0 "register_operand" "=&r")
7301 (ffs:SI (match_operand:SI 1 "register_operand" "r")))
7302 (clobber (match_scratch:SI 2 "=&r"))]
7303 "TARGET_SPARCLITE || TARGET_SPARCLET"
7305 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";
7307 [(set_attr "type" "multi")
7308 (set_attr "length" "8")])
7310 ;; ??? This should be a define expand, so that the extra instruction have
7311 ;; a chance of being optimized away.
7313 ;; Disabled because none of the UltraSPARCs implement popc. The HAL R1
7314 ;; does, but no one uses that and we don't have a switch for it.
7316 ;(define_insn "ffsdi2"
7317 ; [(set (match_operand:DI 0 "register_operand" "=&r")
7318 ; (ffs:DI (match_operand:DI 1 "register_operand" "r")))
7319 ; (clobber (match_scratch:DI 2 "=&r"))]
7321 ; "neg\t%1, %2\;xnor\t%1, %2, %2\;popc\t%2, %0\;movzr\t%1, 0, %0"
7322 ; [(set_attr "type" "multi")
7323 ; (set_attr "length" "4")])
7327 ;; Peepholes go at the end.
7329 ;; Optimize consecutive loads or stores into ldd and std when possible.
7330 ;; The conditions in which we do this are very restricted and are
7331 ;; explained in the code for {registers,memory}_ok_for_ldd functions.
7334 [(set (match_operand:SI 0 "memory_operand" "")
7336 (set (match_operand:SI 1 "memory_operand" "")
7339 && mems_ok_for_ldd_peep (operands[0], operands[1], NULL_RTX)"
7342 "operands[0] = widen_memory_access (operands[0], DImode, 0);")
7345 [(set (match_operand:SI 0 "memory_operand" "")
7347 (set (match_operand:SI 1 "memory_operand" "")
7350 && mems_ok_for_ldd_peep (operands[1], operands[0], NULL_RTX)"
7353 "operands[1] = widen_memory_access (operands[1], DImode, 0);")
7356 [(set (match_operand:SI 0 "register_operand" "")
7357 (match_operand:SI 1 "memory_operand" ""))
7358 (set (match_operand:SI 2 "register_operand" "")
7359 (match_operand:SI 3 "memory_operand" ""))]
7360 "registers_ok_for_ldd_peep (operands[0], operands[2])
7361 && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
7364 "operands[1] = widen_memory_access (operands[1], DImode, 0);
7365 operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));")
7368 [(set (match_operand:SI 0 "memory_operand" "")
7369 (match_operand:SI 1 "register_operand" ""))
7370 (set (match_operand:SI 2 "memory_operand" "")
7371 (match_operand:SI 3 "register_operand" ""))]
7372 "registers_ok_for_ldd_peep (operands[1], operands[3])
7373 && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
7376 "operands[0] = widen_memory_access (operands[0], DImode, 0);
7377 operands[1] = gen_rtx_REG (DImode, REGNO (operands[1]));")
7380 [(set (match_operand:SF 0 "register_operand" "")
7381 (match_operand:SF 1 "memory_operand" ""))
7382 (set (match_operand:SF 2 "register_operand" "")
7383 (match_operand:SF 3 "memory_operand" ""))]
7384 "registers_ok_for_ldd_peep (operands[0], operands[2])
7385 && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
7388 "operands[1] = widen_memory_access (operands[1], DFmode, 0);
7389 operands[0] = gen_rtx_REG (DFmode, REGNO (operands[0]));")
7392 [(set (match_operand:SF 0 "memory_operand" "")
7393 (match_operand:SF 1 "register_operand" ""))
7394 (set (match_operand:SF 2 "memory_operand" "")
7395 (match_operand:SF 3 "register_operand" ""))]
7396 "registers_ok_for_ldd_peep (operands[1], operands[3])
7397 && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
7400 "operands[0] = widen_memory_access (operands[0], DFmode, 0);
7401 operands[1] = gen_rtx_REG (DFmode, REGNO (operands[1]));")
7404 [(set (match_operand:SI 0 "register_operand" "")
7405 (match_operand:SI 1 "memory_operand" ""))
7406 (set (match_operand:SI 2 "register_operand" "")
7407 (match_operand:SI 3 "memory_operand" ""))]
7408 "registers_ok_for_ldd_peep (operands[2], operands[0])
7409 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
7412 "operands[3] = widen_memory_access (operands[3], DImode, 0);
7413 operands[2] = gen_rtx_REG (DImode, REGNO (operands[2]));")
7416 [(set (match_operand:SI 0 "memory_operand" "")
7417 (match_operand:SI 1 "register_operand" ""))
7418 (set (match_operand:SI 2 "memory_operand" "")
7419 (match_operand:SI 3 "register_operand" ""))]
7420 "registers_ok_for_ldd_peep (operands[3], operands[1])
7421 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
7424 "operands[2] = widen_memory_access (operands[2], DImode, 0);
7425 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
7429 [(set (match_operand:SF 0 "register_operand" "")
7430 (match_operand:SF 1 "memory_operand" ""))
7431 (set (match_operand:SF 2 "register_operand" "")
7432 (match_operand:SF 3 "memory_operand" ""))]
7433 "registers_ok_for_ldd_peep (operands[2], operands[0])
7434 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
7437 "operands[3] = widen_memory_access (operands[3], DFmode, 0);
7438 operands[2] = gen_rtx_REG (DFmode, REGNO (operands[2]));")
7441 [(set (match_operand:SF 0 "memory_operand" "")
7442 (match_operand:SF 1 "register_operand" ""))
7443 (set (match_operand:SF 2 "memory_operand" "")
7444 (match_operand:SF 3 "register_operand" ""))]
7445 "registers_ok_for_ldd_peep (operands[3], operands[1])
7446 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
7449 "operands[2] = widen_memory_access (operands[2], DFmode, 0);
7450 operands[3] = gen_rtx_REG (DFmode, REGNO (operands[3]));")
7452 ;; Optimize the case of following a reg-reg move with a test
7453 ;; of reg just moved. Don't allow floating point regs for operand 0 or 1.
7454 ;; This can result from a float to fix conversion.
7457 [(set (match_operand:SI 0 "register_operand" "")
7458 (match_operand:SI 1 "register_operand" ""))
7460 (compare:CC (match_operand:SI 2 "register_operand" "")
7462 "(rtx_equal_p (operands[2], operands[0])
7463 || rtx_equal_p (operands[2], operands[1]))
7464 && ! SPARC_FP_REG_P (REGNO (operands[0]))
7465 && ! SPARC_FP_REG_P (REGNO (operands[1]))"
7466 [(parallel [(set (match_dup 0) (match_dup 1))
7468 (compare:CC (match_dup 1) (const_int 0)))])]
7472 [(set (match_operand:DI 0 "register_operand" "")
7473 (match_operand:DI 1 "register_operand" ""))
7475 (compare:CCX (match_operand:DI 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:CCX (match_dup 1) (const_int 0)))])]
7488 ;; Prefetch instructions.
7490 ;; ??? UltraSPARC-III note: A memory operation loading into the floating point register
7491 ;; ??? file, if it hits the prefetch cache, has a chance to dual-issue with other memory
7492 ;; ??? operations. With DFA we might be able to model this, but it requires a lot of
7494 (define_expand "prefetch"
7495 [(match_operand 0 "address_operand" "")
7496 (match_operand 1 "const_int_operand" "")
7497 (match_operand 2 "const_int_operand" "")]
7501 emit_insn (gen_prefetch_64 (operands[0], operands[1], operands[2]));
7503 emit_insn (gen_prefetch_32 (operands[0], operands[1], operands[2]));
7507 (define_insn "prefetch_64"
7508 [(prefetch (match_operand:DI 0 "address_operand" "p")
7509 (match_operand:DI 1 "const_int_operand" "n")
7510 (match_operand:DI 2 "const_int_operand" "n"))]
7513 static const char * const prefetch_instr[2][2] = {
7515 "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
7516 "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
7519 "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
7520 "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
7523 int read_or_write = INTVAL (operands[1]);
7524 int locality = INTVAL (operands[2]);
7526 gcc_assert (read_or_write == 0 || read_or_write == 1);
7527 gcc_assert (locality >= 0 && locality < 4);
7528 return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
7530 [(set_attr "type" "load")])
7532 (define_insn "prefetch_32"
7533 [(prefetch (match_operand:SI 0 "address_operand" "p")
7534 (match_operand:SI 1 "const_int_operand" "n")
7535 (match_operand:SI 2 "const_int_operand" "n"))]
7538 static const char * const prefetch_instr[2][2] = {
7540 "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
7541 "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
7544 "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
7545 "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
7548 int read_or_write = INTVAL (operands[1]);
7549 int locality = INTVAL (operands[2]);
7551 gcc_assert (read_or_write == 0 || read_or_write == 1);
7552 gcc_assert (locality >= 0 && locality < 4);
7553 return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
7555 [(set_attr "type" "load")])
7558 ;; Trap instructions.
7561 [(trap_if (const_int 1) (const_int 5))]
7564 [(set_attr "type" "trap")])
7566 (define_expand "conditional_trap"
7567 [(trap_if (match_operator 0 "noov_compare_operator" [(match_dup 2) (match_dup 3)])
7568 (match_operand:SI 1 "arith_operand" ""))]
7570 "operands[2] = gen_compare_reg (GET_CODE (operands[0]),
7571 sparc_compare_op0, sparc_compare_op1);
7572 if (GET_MODE (operands[2]) != CCmode && GET_MODE (operands[2]) != CCXmode)
7574 operands[3] = const0_rtx;")
7577 [(trap_if (match_operator 0 "noov_compare_operator" [(reg:CC 100) (const_int 0)])
7578 (match_operand:SI 1 "arith_operand" "rM"))]
7582 return "t%C0\t%%icc, %1";
7586 [(set_attr "type" "trap")])
7589 [(trap_if (match_operator 0 "noov_compare_operator" [(reg:CCX 100) (const_int 0)])
7590 (match_operand:SI 1 "arith_operand" "rM"))]
7593 [(set_attr "type" "trap")])
7596 ;; TLS support instructions.
7598 (define_insn "tgd_hi22"
7599 [(set (match_operand:SI 0 "register_operand" "=r")
7600 (high:SI (unspec:SI [(match_operand 1 "tgd_symbolic_operand" "")]
7603 "sethi\\t%%tgd_hi22(%a1), %0")
7605 (define_insn "tgd_lo10"
7606 [(set (match_operand:SI 0 "register_operand" "=r")
7607 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7608 (unspec:SI [(match_operand 2 "tgd_symbolic_operand" "")]
7611 "add\\t%1, %%tgd_lo10(%a2), %0")
7613 (define_insn "tgd_add32"
7614 [(set (match_operand:SI 0 "register_operand" "=r")
7615 (plus:SI (match_operand:SI 1 "register_operand" "r")
7616 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7617 (match_operand 3 "tgd_symbolic_operand" "")]
7619 "TARGET_TLS && TARGET_ARCH32"
7620 "add\\t%1, %2, %0, %%tgd_add(%a3)")
7622 (define_insn "tgd_add64"
7623 [(set (match_operand:DI 0 "register_operand" "=r")
7624 (plus:DI (match_operand:DI 1 "register_operand" "r")
7625 (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7626 (match_operand 3 "tgd_symbolic_operand" "")]
7628 "TARGET_TLS && TARGET_ARCH64"
7629 "add\\t%1, %2, %0, %%tgd_add(%a3)")
7631 (define_insn "tgd_call32"
7632 [(set (match_operand 0 "register_operand" "=r")
7633 (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")
7634 (match_operand 2 "tgd_symbolic_operand" "")]
7636 (match_operand 3 "" "")))
7637 (clobber (reg:SI 15))]
7638 "TARGET_TLS && TARGET_ARCH32"
7639 "call\t%a1, %%tgd_call(%a2)%#"
7640 [(set_attr "type" "call")])
7642 (define_insn "tgd_call64"
7643 [(set (match_operand 0 "register_operand" "=r")
7644 (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")
7645 (match_operand 2 "tgd_symbolic_operand" "")]
7647 (match_operand 3 "" "")))
7648 (clobber (reg:DI 15))]
7649 "TARGET_TLS && TARGET_ARCH64"
7650 "call\t%a1, %%tgd_call(%a2)%#"
7651 [(set_attr "type" "call")])
7653 (define_insn "tldm_hi22"
7654 [(set (match_operand:SI 0 "register_operand" "=r")
7655 (high:SI (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
7657 "sethi\\t%%tldm_hi22(%&), %0")
7659 (define_insn "tldm_lo10"
7660 [(set (match_operand:SI 0 "register_operand" "=r")
7661 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7662 (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
7664 "add\\t%1, %%tldm_lo10(%&), %0")
7666 (define_insn "tldm_add32"
7667 [(set (match_operand:SI 0 "register_operand" "=r")
7668 (plus:SI (match_operand:SI 1 "register_operand" "r")
7669 (unspec:SI [(match_operand:SI 2 "register_operand" "r")]
7671 "TARGET_TLS && TARGET_ARCH32"
7672 "add\\t%1, %2, %0, %%tldm_add(%&)")
7674 (define_insn "tldm_add64"
7675 [(set (match_operand:DI 0 "register_operand" "=r")
7676 (plus:DI (match_operand:DI 1 "register_operand" "r")
7677 (unspec:DI [(match_operand:SI 2 "register_operand" "r")]
7679 "TARGET_TLS && TARGET_ARCH64"
7680 "add\\t%1, %2, %0, %%tldm_add(%&)")
7682 (define_insn "tldm_call32"
7683 [(set (match_operand 0 "register_operand" "=r")
7684 (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")]
7686 (match_operand 2 "" "")))
7687 (clobber (reg:SI 15))]
7688 "TARGET_TLS && TARGET_ARCH32"
7689 "call\t%a1, %%tldm_call(%&)%#"
7690 [(set_attr "type" "call")])
7692 (define_insn "tldm_call64"
7693 [(set (match_operand 0 "register_operand" "=r")
7694 (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")]
7696 (match_operand 2 "" "")))
7697 (clobber (reg:DI 15))]
7698 "TARGET_TLS && TARGET_ARCH64"
7699 "call\t%a1, %%tldm_call(%&)%#"
7700 [(set_attr "type" "call")])
7702 (define_insn "tldo_hix22"
7703 [(set (match_operand:SI 0 "register_operand" "=r")
7704 (high:SI (unspec:SI [(match_operand 1 "tld_symbolic_operand" "")]
7707 "sethi\\t%%tldo_hix22(%a1), %0")
7709 (define_insn "tldo_lox10"
7710 [(set (match_operand:SI 0 "register_operand" "=r")
7711 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7712 (unspec:SI [(match_operand 2 "tld_symbolic_operand" "")]
7715 "xor\\t%1, %%tldo_lox10(%a2), %0")
7717 (define_insn "tldo_add32"
7718 [(set (match_operand:SI 0 "register_operand" "=r")
7719 (plus:SI (match_operand:SI 1 "register_operand" "r")
7720 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7721 (match_operand 3 "tld_symbolic_operand" "")]
7723 "TARGET_TLS && TARGET_ARCH32"
7724 "add\\t%1, %2, %0, %%tldo_add(%a3)")
7726 (define_insn "tldo_add64"
7727 [(set (match_operand:DI 0 "register_operand" "=r")
7728 (plus:DI (match_operand:DI 1 "register_operand" "r")
7729 (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7730 (match_operand 3 "tld_symbolic_operand" "")]
7732 "TARGET_TLS && TARGET_ARCH64"
7733 "add\\t%1, %2, %0, %%tldo_add(%a3)")
7735 (define_insn "tie_hi22"
7736 [(set (match_operand:SI 0 "register_operand" "=r")
7737 (high:SI (unspec:SI [(match_operand 1 "tie_symbolic_operand" "")]
7740 "sethi\\t%%tie_hi22(%a1), %0")
7742 (define_insn "tie_lo10"
7743 [(set (match_operand:SI 0 "register_operand" "=r")
7744 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7745 (unspec:SI [(match_operand 2 "tie_symbolic_operand" "")]
7748 "add\\t%1, %%tie_lo10(%a2), %0")
7750 (define_insn "tie_ld32"
7751 [(set (match_operand:SI 0 "register_operand" "=r")
7752 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
7753 (match_operand:SI 2 "register_operand" "r")
7754 (match_operand 3 "tie_symbolic_operand" "")]
7756 "TARGET_TLS && TARGET_ARCH32"
7757 "ld\\t[%1 + %2], %0, %%tie_ld(%a3)"
7758 [(set_attr "type" "load")])
7760 (define_insn "tie_ld64"
7761 [(set (match_operand:DI 0 "register_operand" "=r")
7762 (unspec:DI [(match_operand:DI 1 "register_operand" "r")
7763 (match_operand:SI 2 "register_operand" "r")
7764 (match_operand 3 "tie_symbolic_operand" "")]
7766 "TARGET_TLS && TARGET_ARCH64"
7767 "ldx\\t[%1 + %2], %0, %%tie_ldx(%a3)"
7768 [(set_attr "type" "load")])
7770 (define_insn "tie_add32"
7771 [(set (match_operand:SI 0 "register_operand" "=r")
7772 (plus:SI (match_operand:SI 1 "register_operand" "r")
7773 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7774 (match_operand 3 "tie_symbolic_operand" "")]
7776 "TARGET_SUN_TLS && TARGET_ARCH32"
7777 "add\\t%1, %2, %0, %%tie_add(%a3)")
7779 (define_insn "tie_add64"
7780 [(set (match_operand:DI 0 "register_operand" "=r")
7781 (plus:DI (match_operand:DI 1 "register_operand" "r")
7782 (unspec:DI [(match_operand:DI 2 "register_operand" "r")
7783 (match_operand 3 "tie_symbolic_operand" "")]
7785 "TARGET_SUN_TLS && TARGET_ARCH64"
7786 "add\\t%1, %2, %0, %%tie_add(%a3)")
7788 (define_insn "tle_hix22_sp32"
7789 [(set (match_operand:SI 0 "register_operand" "=r")
7790 (high:SI (unspec:SI [(match_operand 1 "tle_symbolic_operand" "")]
7792 "TARGET_TLS && TARGET_ARCH32"
7793 "sethi\\t%%tle_hix22(%a1), %0")
7795 (define_insn "tle_lox10_sp32"
7796 [(set (match_operand:SI 0 "register_operand" "=r")
7797 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7798 (unspec:SI [(match_operand 2 "tle_symbolic_operand" "")]
7800 "TARGET_TLS && TARGET_ARCH32"
7801 "xor\\t%1, %%tle_lox10(%a2), %0")
7803 (define_insn "tle_hix22_sp64"
7804 [(set (match_operand:DI 0 "register_operand" "=r")
7805 (high:DI (unspec:DI [(match_operand 1 "tle_symbolic_operand" "")]
7807 "TARGET_TLS && TARGET_ARCH64"
7808 "sethi\\t%%tle_hix22(%a1), %0")
7810 (define_insn "tle_lox10_sp64"
7811 [(set (match_operand:DI 0 "register_operand" "=r")
7812 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
7813 (unspec:DI [(match_operand 2 "tle_symbolic_operand" "")]
7815 "TARGET_TLS && TARGET_ARCH64"
7816 "xor\\t%1, %%tle_lox10(%a2), %0")
7818 ;; Now patterns combining tldo_add{32,64} with some integer loads or stores
7819 (define_insn "*tldo_ldub_sp32"
7820 [(set (match_operand:QI 0 "register_operand" "=r")
7821 (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7822 (match_operand 3 "tld_symbolic_operand" "")]
7824 (match_operand:SI 1 "register_operand" "r"))))]
7825 "TARGET_TLS && TARGET_ARCH32"
7826 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7827 [(set_attr "type" "load")
7828 (set_attr "us3load_type" "3cycle")])
7830 (define_insn "*tldo_ldub1_sp32"
7831 [(set (match_operand:HI 0 "register_operand" "=r")
7832 (zero_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7833 (match_operand 3 "tld_symbolic_operand" "")]
7835 (match_operand:SI 1 "register_operand" "r")))))]
7836 "TARGET_TLS && TARGET_ARCH32"
7837 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7838 [(set_attr "type" "load")
7839 (set_attr "us3load_type" "3cycle")])
7841 (define_insn "*tldo_ldub2_sp32"
7842 [(set (match_operand:SI 0 "register_operand" "=r")
7843 (zero_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7844 (match_operand 3 "tld_symbolic_operand" "")]
7846 (match_operand:SI 1 "register_operand" "r")))))]
7847 "TARGET_TLS && TARGET_ARCH32"
7848 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7849 [(set_attr "type" "load")
7850 (set_attr "us3load_type" "3cycle")])
7852 (define_insn "*tldo_ldsb1_sp32"
7853 [(set (match_operand:HI 0 "register_operand" "=r")
7854 (sign_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7855 (match_operand 3 "tld_symbolic_operand" "")]
7857 (match_operand:SI 1 "register_operand" "r")))))]
7858 "TARGET_TLS && TARGET_ARCH32"
7859 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7860 [(set_attr "type" "sload")
7861 (set_attr "us3load_type" "3cycle")])
7863 (define_insn "*tldo_ldsb2_sp32"
7864 [(set (match_operand:SI 0 "register_operand" "=r")
7865 (sign_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7866 (match_operand 3 "tld_symbolic_operand" "")]
7868 (match_operand:SI 1 "register_operand" "r")))))]
7869 "TARGET_TLS && TARGET_ARCH32"
7870 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7871 [(set_attr "type" "sload")
7872 (set_attr "us3load_type" "3cycle")])
7874 (define_insn "*tldo_ldub_sp64"
7875 [(set (match_operand:QI 0 "register_operand" "=r")
7876 (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7877 (match_operand 3 "tld_symbolic_operand" "")]
7879 (match_operand:DI 1 "register_operand" "r"))))]
7880 "TARGET_TLS && TARGET_ARCH64"
7881 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7882 [(set_attr "type" "load")
7883 (set_attr "us3load_type" "3cycle")])
7885 (define_insn "*tldo_ldub1_sp64"
7886 [(set (match_operand:HI 0 "register_operand" "=r")
7887 (zero_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7888 (match_operand 3 "tld_symbolic_operand" "")]
7890 (match_operand:DI 1 "register_operand" "r")))))]
7891 "TARGET_TLS && TARGET_ARCH64"
7892 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7893 [(set_attr "type" "load")
7894 (set_attr "us3load_type" "3cycle")])
7896 (define_insn "*tldo_ldub2_sp64"
7897 [(set (match_operand:SI 0 "register_operand" "=r")
7898 (zero_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7899 (match_operand 3 "tld_symbolic_operand" "")]
7901 (match_operand:DI 1 "register_operand" "r")))))]
7902 "TARGET_TLS && TARGET_ARCH64"
7903 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7904 [(set_attr "type" "load")
7905 (set_attr "us3load_type" "3cycle")])
7907 (define_insn "*tldo_ldub3_sp64"
7908 [(set (match_operand:DI 0 "register_operand" "=r")
7909 (zero_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7910 (match_operand 3 "tld_symbolic_operand" "")]
7912 (match_operand:DI 1 "register_operand" "r")))))]
7913 "TARGET_TLS && TARGET_ARCH64"
7914 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7915 [(set_attr "type" "load")
7916 (set_attr "us3load_type" "3cycle")])
7918 (define_insn "*tldo_ldsb1_sp64"
7919 [(set (match_operand:HI 0 "register_operand" "=r")
7920 (sign_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7921 (match_operand 3 "tld_symbolic_operand" "")]
7923 (match_operand:DI 1 "register_operand" "r")))))]
7924 "TARGET_TLS && TARGET_ARCH64"
7925 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7926 [(set_attr "type" "sload")
7927 (set_attr "us3load_type" "3cycle")])
7929 (define_insn "*tldo_ldsb2_sp64"
7930 [(set (match_operand:SI 0 "register_operand" "=r")
7931 (sign_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7932 (match_operand 3 "tld_symbolic_operand" "")]
7934 (match_operand:DI 1 "register_operand" "r")))))]
7935 "TARGET_TLS && TARGET_ARCH64"
7936 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7937 [(set_attr "type" "sload")
7938 (set_attr "us3load_type" "3cycle")])
7940 (define_insn "*tldo_ldsb3_sp64"
7941 [(set (match_operand:DI 0 "register_operand" "=r")
7942 (sign_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7943 (match_operand 3 "tld_symbolic_operand" "")]
7945 (match_operand:DI 1 "register_operand" "r")))))]
7946 "TARGET_TLS && TARGET_ARCH64"
7947 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7948 [(set_attr "type" "sload")
7949 (set_attr "us3load_type" "3cycle")])
7951 (define_insn "*tldo_lduh_sp32"
7952 [(set (match_operand:HI 0 "register_operand" "=r")
7953 (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7954 (match_operand 3 "tld_symbolic_operand" "")]
7956 (match_operand:SI 1 "register_operand" "r"))))]
7957 "TARGET_TLS && TARGET_ARCH32"
7958 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7959 [(set_attr "type" "load")
7960 (set_attr "us3load_type" "3cycle")])
7962 (define_insn "*tldo_lduh1_sp32"
7963 [(set (match_operand:SI 0 "register_operand" "=r")
7964 (zero_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7965 (match_operand 3 "tld_symbolic_operand" "")]
7967 (match_operand:SI 1 "register_operand" "r")))))]
7968 "TARGET_TLS && TARGET_ARCH32"
7969 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7970 [(set_attr "type" "load")
7971 (set_attr "us3load_type" "3cycle")])
7973 (define_insn "*tldo_ldsh1_sp32"
7974 [(set (match_operand:SI 0 "register_operand" "=r")
7975 (sign_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7976 (match_operand 3 "tld_symbolic_operand" "")]
7978 (match_operand:SI 1 "register_operand" "r")))))]
7979 "TARGET_TLS && TARGET_ARCH32"
7980 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
7981 [(set_attr "type" "sload")
7982 (set_attr "us3load_type" "3cycle")])
7984 (define_insn "*tldo_lduh_sp64"
7985 [(set (match_operand:HI 0 "register_operand" "=r")
7986 (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7987 (match_operand 3 "tld_symbolic_operand" "")]
7989 (match_operand:DI 1 "register_operand" "r"))))]
7990 "TARGET_TLS && TARGET_ARCH64"
7991 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7992 [(set_attr "type" "load")
7993 (set_attr "us3load_type" "3cycle")])
7995 (define_insn "*tldo_lduh1_sp64"
7996 [(set (match_operand:SI 0 "register_operand" "=r")
7997 (zero_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7998 (match_operand 3 "tld_symbolic_operand" "")]
8000 (match_operand:DI 1 "register_operand" "r")))))]
8001 "TARGET_TLS && TARGET_ARCH64"
8002 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
8003 [(set_attr "type" "load")
8004 (set_attr "us3load_type" "3cycle")])
8006 (define_insn "*tldo_lduh2_sp64"
8007 [(set (match_operand:DI 0 "register_operand" "=r")
8008 (zero_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8009 (match_operand 3 "tld_symbolic_operand" "")]
8011 (match_operand:DI 1 "register_operand" "r")))))]
8012 "TARGET_TLS && TARGET_ARCH64"
8013 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
8014 [(set_attr "type" "load")
8015 (set_attr "us3load_type" "3cycle")])
8017 (define_insn "*tldo_ldsh1_sp64"
8018 [(set (match_operand:SI 0 "register_operand" "=r")
8019 (sign_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8020 (match_operand 3 "tld_symbolic_operand" "")]
8022 (match_operand:DI 1 "register_operand" "r")))))]
8023 "TARGET_TLS && TARGET_ARCH64"
8024 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
8025 [(set_attr "type" "sload")
8026 (set_attr "us3load_type" "3cycle")])
8028 (define_insn "*tldo_ldsh2_sp64"
8029 [(set (match_operand:DI 0 "register_operand" "=r")
8030 (sign_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8031 (match_operand 3 "tld_symbolic_operand" "")]
8033 (match_operand:DI 1 "register_operand" "r")))))]
8034 "TARGET_TLS && TARGET_ARCH64"
8035 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
8036 [(set_attr "type" "sload")
8037 (set_attr "us3load_type" "3cycle")])
8039 (define_insn "*tldo_lduw_sp32"
8040 [(set (match_operand:SI 0 "register_operand" "=r")
8041 (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8042 (match_operand 3 "tld_symbolic_operand" "")]
8044 (match_operand:SI 1 "register_operand" "r"))))]
8045 "TARGET_TLS && TARGET_ARCH32"
8046 "ld\t[%1 + %2], %0, %%tldo_add(%3)"
8047 [(set_attr "type" "load")])
8049 (define_insn "*tldo_lduw_sp64"
8050 [(set (match_operand:SI 0 "register_operand" "=r")
8051 (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8052 (match_operand 3 "tld_symbolic_operand" "")]
8054 (match_operand:DI 1 "register_operand" "r"))))]
8055 "TARGET_TLS && TARGET_ARCH64"
8056 "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
8057 [(set_attr "type" "load")])
8059 (define_insn "*tldo_lduw1_sp64"
8060 [(set (match_operand:DI 0 "register_operand" "=r")
8061 (zero_extend:DI (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8062 (match_operand 3 "tld_symbolic_operand" "")]
8064 (match_operand:DI 1 "register_operand" "r")))))]
8065 "TARGET_TLS && TARGET_ARCH64"
8066 "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
8067 [(set_attr "type" "load")])
8069 (define_insn "*tldo_ldsw1_sp64"
8070 [(set (match_operand:DI 0 "register_operand" "=r")
8071 (sign_extend:DI (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8072 (match_operand 3 "tld_symbolic_operand" "")]
8074 (match_operand:DI 1 "register_operand" "r")))))]
8075 "TARGET_TLS && TARGET_ARCH64"
8076 "ldsw\t[%1 + %2], %0, %%tldo_add(%3)"
8077 [(set_attr "type" "sload")
8078 (set_attr "us3load_type" "3cycle")])
8080 (define_insn "*tldo_ldx_sp64"
8081 [(set (match_operand:DI 0 "register_operand" "=r")
8082 (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8083 (match_operand 3 "tld_symbolic_operand" "")]
8085 (match_operand:DI 1 "register_operand" "r"))))]
8086 "TARGET_TLS && TARGET_ARCH64"
8087 "ldx\t[%1 + %2], %0, %%tldo_add(%3)"
8088 [(set_attr "type" "load")])
8090 (define_insn "*tldo_stb_sp32"
8091 [(set (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8092 (match_operand 3 "tld_symbolic_operand" "")]
8094 (match_operand:SI 1 "register_operand" "r")))
8095 (match_operand:QI 0 "register_operand" "=r"))]
8096 "TARGET_TLS && TARGET_ARCH32"
8097 "stb\t%0, [%1 + %2], %%tldo_add(%3)"
8098 [(set_attr "type" "store")])
8100 (define_insn "*tldo_stb_sp64"
8101 [(set (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8102 (match_operand 3 "tld_symbolic_operand" "")]
8104 (match_operand:DI 1 "register_operand" "r")))
8105 (match_operand:QI 0 "register_operand" "=r"))]
8106 "TARGET_TLS && TARGET_ARCH64"
8107 "stb\t%0, [%1 + %2], %%tldo_add(%3)"
8108 [(set_attr "type" "store")])
8110 (define_insn "*tldo_sth_sp32"
8111 [(set (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8112 (match_operand 3 "tld_symbolic_operand" "")]
8114 (match_operand:SI 1 "register_operand" "r")))
8115 (match_operand:HI 0 "register_operand" "=r"))]
8116 "TARGET_TLS && TARGET_ARCH32"
8117 "sth\t%0, [%1 + %2], %%tldo_add(%3)"
8118 [(set_attr "type" "store")])
8120 (define_insn "*tldo_sth_sp64"
8121 [(set (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8122 (match_operand 3 "tld_symbolic_operand" "")]
8124 (match_operand:DI 1 "register_operand" "r")))
8125 (match_operand:HI 0 "register_operand" "=r"))]
8126 "TARGET_TLS && TARGET_ARCH64"
8127 "sth\t%0, [%1 + %2], %%tldo_add(%3)"
8128 [(set_attr "type" "store")])
8130 (define_insn "*tldo_stw_sp32"
8131 [(set (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8132 (match_operand 3 "tld_symbolic_operand" "")]
8134 (match_operand:SI 1 "register_operand" "r")))
8135 (match_operand:SI 0 "register_operand" "=r"))]
8136 "TARGET_TLS && TARGET_ARCH32"
8137 "st\t%0, [%1 + %2], %%tldo_add(%3)"
8138 [(set_attr "type" "store")])
8140 (define_insn "*tldo_stw_sp64"
8141 [(set (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8142 (match_operand 3 "tld_symbolic_operand" "")]
8144 (match_operand:DI 1 "register_operand" "r")))
8145 (match_operand:SI 0 "register_operand" "=r"))]
8146 "TARGET_TLS && TARGET_ARCH64"
8147 "stw\t%0, [%1 + %2], %%tldo_add(%3)"
8148 [(set_attr "type" "store")])
8150 (define_insn "*tldo_stx_sp64"
8151 [(set (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8152 (match_operand 3 "tld_symbolic_operand" "")]
8154 (match_operand:DI 1 "register_operand" "r")))
8155 (match_operand:DI 0 "register_operand" "=r"))]
8156 "TARGET_TLS && TARGET_ARCH64"
8157 "stx\t%0, [%1 + %2], %%tldo_add(%3)"
8158 [(set_attr "type" "store")])
8161 ;; Stack protector instructions.
8163 (define_expand "stack_protect_set"
8164 [(match_operand 0 "memory_operand" "")
8165 (match_operand 1 "memory_operand" "")]
8168 #ifdef TARGET_THREAD_SSP_OFFSET
8169 rtx tlsreg = gen_rtx_REG (Pmode, 7);
8170 rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
8171 operands[1] = gen_rtx_MEM (Pmode, addr);
8174 emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
8176 emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
8180 (define_insn "stack_protect_setsi"
8181 [(set (match_operand:SI 0 "memory_operand" "=m")
8182 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
8183 (set (match_scratch:SI 2 "=&r") (const_int 0))]
8185 "ld\t%1, %2\;st\t%2, %0\;mov\t0, %2"
8186 [(set_attr "type" "multi")
8187 (set_attr "length" "3")])
8189 (define_insn "stack_protect_setdi"
8190 [(set (match_operand:DI 0 "memory_operand" "=m")
8191 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
8192 (set (match_scratch:DI 2 "=&r") (const_int 0))]
8194 "ldx\t%1, %2\;stx\t%2, %0\;mov\t0, %2"
8195 [(set_attr "type" "multi")
8196 (set_attr "length" "3")])
8198 (define_expand "stack_protect_test"
8199 [(match_operand 0 "memory_operand" "")
8200 (match_operand 1 "memory_operand" "")
8201 (match_operand 2 "" "")]
8204 #ifdef TARGET_THREAD_SSP_OFFSET
8205 rtx tlsreg = gen_rtx_REG (Pmode, 7);
8206 rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
8207 operands[1] = gen_rtx_MEM (Pmode, addr);
8211 rtx temp = gen_reg_rtx (Pmode);
8212 emit_insn (gen_stack_protect_testdi (temp, operands[0], operands[1]));
8213 sparc_compare_op0 = temp;
8214 sparc_compare_op1 = const0_rtx;
8218 emit_insn (gen_stack_protect_testsi (operands[0], operands[1]));
8219 sparc_compare_op0 = operands[0];
8220 sparc_compare_op1 = operands[1];
8221 sparc_compare_emitted = gen_rtx_REG (CCmode, SPARC_ICC_REG);
8223 emit_jump_insn (gen_beq (operands[2]));
8227 (define_insn "stack_protect_testsi"
8229 (unspec:CC [(match_operand:SI 0 "memory_operand" "m")
8230 (match_operand:SI 1 "memory_operand" "m")]
8232 (set (match_scratch:SI 3 "=r") (const_int 0))
8233 (clobber (match_scratch:SI 2 "=&r"))]
8235 "ld\t%0, %2\;ld\t%1, %3\;xorcc\t%2, %3, %2\;mov\t0, %3"
8236 [(set_attr "type" "multi")
8237 (set_attr "length" "4")])
8239 (define_insn "stack_protect_testdi"
8240 [(set (match_operand:DI 0 "register_operand" "=&r")
8241 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
8242 (match_operand:DI 2 "memory_operand" "m")]
8244 (set (match_scratch:DI 3 "=r") (const_int 0))]
8246 "ldx\t%1, %0\;ldx\t%2, %3\;xor\t%0, %3, %0\;mov\t0, %3"
8247 [(set_attr "type" "multi")
8248 (set_attr "length" "4")])
8251 ;; Vector instructions.
8253 (define_insn "addv2si3"
8254 [(set (match_operand:V2SI 0 "register_operand" "=e")
8255 (plus:V2SI (match_operand:V2SI 1 "register_operand" "e")
8256 (match_operand:V2SI 2 "register_operand" "e")))]
8258 "fpadd32\t%1, %2, %0"
8259 [(set_attr "type" "fga")
8260 (set_attr "fptype" "double")])
8262 (define_insn "addv4hi3"
8263 [(set (match_operand:V4HI 0 "register_operand" "=e")
8264 (plus:V4HI (match_operand:V4HI 1 "register_operand" "e")
8265 (match_operand:V4HI 2 "register_operand" "e")))]
8267 "fpadd16\t%1, %2, %0"
8268 [(set_attr "type" "fga")
8269 (set_attr "fptype" "double")])
8271 ;; fpadd32s is emitted by the addsi3 pattern.
8273 (define_insn "addv2hi3"
8274 [(set (match_operand:V2HI 0 "register_operand" "=f")
8275 (plus:V2HI (match_operand:V2HI 1 "register_operand" "f")
8276 (match_operand:V2HI 2 "register_operand" "f")))]
8278 "fpadd16s\t%1, %2, %0"
8279 [(set_attr "type" "fga")
8280 (set_attr "fptype" "single")])
8282 (define_insn "subv2si3"
8283 [(set (match_operand:V2SI 0 "register_operand" "=e")
8284 (minus:V2SI (match_operand:V2SI 1 "register_operand" "e")
8285 (match_operand:V2SI 2 "register_operand" "e")))]
8287 "fpsub32\t%1, %2, %0"
8288 [(set_attr "type" "fga")
8289 (set_attr "fptype" "double")])
8291 (define_insn "subv4hi3"
8292 [(set (match_operand:V4HI 0 "register_operand" "=e")
8293 (minus:V4HI (match_operand:V4HI 1 "register_operand" "e")
8294 (match_operand:V4HI 2 "register_operand" "e")))]
8296 "fpsub16\t%1, %2, %0"
8297 [(set_attr "type" "fga")
8298 (set_attr "fptype" "double")])
8300 ;; fpsub32s is emitted by the subsi3 pattern.
8302 (define_insn "subv2hi3"
8303 [(set (match_operand:V2HI 0 "register_operand" "=f")
8304 (minus:V2HI (match_operand:V2HI 1 "register_operand" "f")
8305 (match_operand:V2HI 2 "register_operand" "f")))]
8307 "fpsub16s\t%1, %2, %0"
8308 [(set_attr "type" "fga")
8309 (set_attr "fptype" "single")])
8311 ;; All other logical instructions have integer equivalents so they
8312 ;; are defined together.
8314 ;; (ior (not (op1)) (not (op2))) is the canonical form of NAND.
8316 (define_insn "*nand<V64mode>_vis"
8317 [(set (match_operand:V64 0 "register_operand" "=e")
8318 (ior:V64 (not:V64 (match_operand:V64 1 "register_operand" "e"))
8319 (not:V64 (match_operand:V64 2 "register_operand" "e"))))]
8322 [(set_attr "type" "fga")
8323 (set_attr "fptype" "double")])
8325 (define_insn "*nand<V32mode>_vis"
8326 [(set (match_operand:V32 0 "register_operand" "=f")
8327 (ior:V32 (not:V32 (match_operand:V32 1 "register_operand" "f"))
8328 (not:V32 (match_operand:V32 2 "register_operand" "f"))))]
8330 "fnands\t%1, %2, %0"
8331 [(set_attr "type" "fga")
8332 (set_attr "fptype" "single")])
8334 ;; Hard to generate VIS instructions. We have builtins for these.
8336 (define_insn "fpack16_vis"
8337 [(set (match_operand:V4QI 0 "register_operand" "=f")
8338 (unspec:V4QI [(match_operand:V4HI 1 "register_operand" "e")]
8342 [(set_attr "type" "fga")
8343 (set_attr "fptype" "double")])
8345 (define_insn "fpackfix_vis"
8346 [(set (match_operand:V2HI 0 "register_operand" "=f")
8347 (unspec:V2HI [(match_operand:V2SI 1 "register_operand" "e")]
8351 [(set_attr "type" "fga")
8352 (set_attr "fptype" "double")])
8354 (define_insn "fpack32_vis"
8355 [(set (match_operand:V8QI 0 "register_operand" "=e")
8356 (unspec:V8QI [(match_operand:V2SI 1 "register_operand" "e")
8357 (match_operand:V8QI 2 "register_operand" "e")]
8360 "fpack32\t%1, %2, %0"
8361 [(set_attr "type" "fga")
8362 (set_attr "fptype" "double")])
8364 (define_insn "fexpand_vis"
8365 [(set (match_operand:V4HI 0 "register_operand" "=e")
8366 (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")]
8370 [(set_attr "type" "fga")
8371 (set_attr "fptype" "double")])
8373 ;; It may be possible to describe this operation as (1 indexed):
8374 ;; (vec_select (vec_duplicate (vec_duplicate (vec_concat 1 2)))
8375 ;; 1,5,10,14,19,23,28,32)
8376 ;; Note that (vec_merge:V8QI [(V4QI) (V4QI)] (10101010 = 170) doesn't work
8377 ;; because vec_merge expects all the operands to be of the same type.
8378 (define_insn "fpmerge_vis"
8379 [(set (match_operand:V8QI 0 "register_operand" "=e")
8380 (unspec:V8QI [(match_operand:V4QI 1 "register_operand" "f")
8381 (match_operand:V4QI 2 "register_operand" "f")]
8384 "fpmerge\t%1, %2, %0"
8385 [(set_attr "type" "fga")
8386 (set_attr "fptype" "double")])
8388 ;; Partitioned multiply instructions
8389 (define_insn "fmul8x16_vis"
8390 [(set (match_operand:V4HI 0 "register_operand" "=e")
8391 (mult:V4HI (match_operand:V4QI 1 "register_operand" "f")
8392 (match_operand:V4HI 2 "register_operand" "e")))]
8394 "fmul8x16\t%1, %2, %0"
8395 [(set_attr "type" "fpmul")
8396 (set_attr "fptype" "double")])
8398 ;; Only one of the following two insns can be a multiply.
8399 (define_insn "fmul8x16au_vis"
8400 [(set (match_operand:V4HI 0 "register_operand" "=e")
8401 (mult:V4HI (match_operand:V4QI 1 "register_operand" "f")
8402 (match_operand:V2HI 2 "register_operand" "f")))]
8404 "fmul8x16au\t%1, %2, %0"
8405 [(set_attr "type" "fpmul")
8406 (set_attr "fptype" "double")])
8408 (define_insn "fmul8x16al_vis"
8409 [(set (match_operand:V4HI 0 "register_operand" "=e")
8410 (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")
8411 (match_operand:V2HI 2 "register_operand" "f")]
8414 "fmul8x16al\t%1, %2, %0"
8415 [(set_attr "type" "fpmul")
8416 (set_attr "fptype" "double")])
8418 ;; Only one of the following two insns can be a multiply.
8419 (define_insn "fmul8sux16_vis"
8420 [(set (match_operand:V4HI 0 "register_operand" "=e")
8421 (mult:V4HI (match_operand:V8QI 1 "register_operand" "e")
8422 (match_operand:V4HI 2 "register_operand" "e")))]
8424 "fmul8sux16\t%1, %2, %0"
8425 [(set_attr "type" "fpmul")
8426 (set_attr "fptype" "double")])
8428 (define_insn "fmul8ulx16_vis"
8429 [(set (match_operand:V4HI 0 "register_operand" "=e")
8430 (unspec:V4HI [(match_operand:V8QI 1 "register_operand" "e")
8431 (match_operand:V4HI 2 "register_operand" "e")]
8434 "fmul8ulx16\t%1, %2, %0"
8435 [(set_attr "type" "fpmul")
8436 (set_attr "fptype" "double")])
8438 ;; Only one of the following two insns can be a multiply.
8439 (define_insn "fmuld8sux16_vis"
8440 [(set (match_operand:V2SI 0 "register_operand" "=e")
8441 (mult:V2SI (match_operand:V4QI 1 "register_operand" "f")
8442 (match_operand:V2HI 2 "register_operand" "f")))]
8444 "fmuld8sux16\t%1, %2, %0"
8445 [(set_attr "type" "fpmul")
8446 (set_attr "fptype" "double")])
8448 (define_insn "fmuld8ulx16_vis"
8449 [(set (match_operand:V2SI 0 "register_operand" "=e")
8450 (unspec:V2SI [(match_operand:V4QI 1 "register_operand" "f")
8451 (match_operand:V2HI 2 "register_operand" "f")]
8454 "fmuld8ulx16\t%1, %2, %0"
8455 [(set_attr "type" "fpmul")
8456 (set_attr "fptype" "double")])
8458 ;; Using faligndata only makes sense after an alignaddr since the choice of
8459 ;; bytes to take out of each operand is dependent on the results of the last
8461 (define_insn "faligndata<V64I:mode>_vis"
8462 [(set (match_operand:V64I 0 "register_operand" "=e")
8463 (unspec:V64I [(match_operand:V64I 1 "register_operand" "e")
8464 (match_operand:V64I 2 "register_operand" "e")]
8467 "faligndata\t%1, %2, %0"
8468 [(set_attr "type" "fga")
8469 (set_attr "fptype" "double")])
8471 (define_insn "alignaddr<P:mode>_vis"
8472 [(set (match_operand:P 0 "register_operand" "=r")
8473 (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
8474 (match_operand:P 2 "register_or_zero_operand" "rJ")]
8477 "alignaddr\t%r1, %r2, %0")
8479 (define_insn "pdist_vis"
8480 [(set (match_operand:DI 0 "register_operand" "=e")
8481 (unspec:DI [(match_operand:V8QI 1 "register_operand" "e")
8482 (match_operand:V8QI 2 "register_operand" "e")
8483 (match_operand:DI 3 "register_operand" "0")]
8487 [(set_attr "type" "fga")
8488 (set_attr "fptype" "double")])