1 ;; Machine description for SPARC chip for GCC
2 ;; Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
3 ;; 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
4 ;; Free Software Foundation, Inc.
5 ;; Contributed by Michael Tiemann (tiemann@cygnus.com)
6 ;; 64-bit SPARC-V9 support by Michael Tiemann, Jim Wilson, and Doug Evans,
9 ;; This file is part of GCC.
11 ;; GCC is free software; you can redistribute it and/or modify
12 ;; it under the terms of the GNU General Public License as published by
13 ;; the Free Software Foundation; either version 3, or (at your option)
16 ;; GCC is distributed in the hope that it will be useful,
17 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
18 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 ;; GNU General Public License for more details.
21 ;; You should have received a copy of the GNU General Public License
22 ;; along with GCC; see the file COPYING3. If not see
23 ;; <http://www.gnu.org/licenses/>.
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)
49 (UNSPEC_TLSLD_BASE 35)
79 ;; The upper 32 fp regs on the v9 can't hold SFmode values. To deal with this
80 ;; a second register class, EXTRA_FP_REGS, exists for the v9 chip. The name
81 ;; is a bit of a misnomer as it covers all 64 fp regs. The corresponding
82 ;; constraint letter is 'e'. To avoid any confusion, 'e' is used instead of
83 ;; 'f' for all DF/TFmode values, including those that are specific to the v8.
86 ;; Attribute for cpu type.
87 ;; These must match the values for enum processor_type in sparc.h.
94 hypersparc,sparclite86x,
101 (const (symbol_ref "sparc_cpu_attr")))
103 ;; Attribute for the instruction set.
104 ;; At present we only need to distinguish v9/!v9, but for clarity we
105 ;; test TARGET_V8 too.
106 (define_attr "isa" "v7,v8,v9,sparclet"
108 (cond [(symbol_ref "TARGET_V9") (const_string "v9")
109 (symbol_ref "TARGET_V8") (const_string "v8")
110 (symbol_ref "TARGET_SPARCLET") (const_string "sparclet")]
111 (const_string "v7"))))
117 uncond_branch,branch,call,sibcall,call_no_delay_slot,return,
125 fga,fgm_pack,fgm_mul,fgm_pdist,fgm_cmp,
128 multi,savew,flushw,iflush,trap"
129 (const_string "ialu"))
131 ;; True if branch/call has empty delay slot and will emit a nop in it
132 (define_attr "empty_delay_slot" "false,true"
133 (symbol_ref "(empty_delay_slot (insn)
134 ? EMPTY_DELAY_SLOT_TRUE : EMPTY_DELAY_SLOT_FALSE)"))
136 (define_attr "branch_type" "none,icc,fcc,reg"
137 (const_string "none"))
139 (define_attr "pic" "false,true"
140 (symbol_ref "(flag_pic != 0 ? PIC_TRUE : PIC_FALSE)"))
142 (define_attr "calls_alloca" "false,true"
143 (symbol_ref "(cfun->calls_alloca != 0
144 ? CALLS_ALLOCA_TRUE : CALLS_ALLOCA_FALSE)"))
146 (define_attr "calls_eh_return" "false,true"
147 (symbol_ref "(crtl->calls_eh_return != 0
148 ? CALLS_EH_RETURN_TRUE : CALLS_EH_RETURN_FALSE)"))
150 (define_attr "leaf_function" "false,true"
151 (symbol_ref "(current_function_uses_only_leaf_regs != 0
152 ? LEAF_FUNCTION_TRUE : LEAF_FUNCTION_FALSE)"))
154 (define_attr "delayed_branch" "false,true"
155 (symbol_ref "(flag_delayed_branch != 0
156 ? DELAYED_BRANCH_TRUE : DELAYED_BRANCH_FALSE)"))
158 ;; Length (in # of insns).
159 ;; Beware that setting a length greater or equal to 3 for conditional branches
160 ;; has a side-effect (see output_cbranch and output_v9branch).
161 (define_attr "length" ""
162 (cond [(eq_attr "type" "uncond_branch,call")
163 (if_then_else (eq_attr "empty_delay_slot" "true")
166 (eq_attr "type" "sibcall")
167 (if_then_else (eq_attr "leaf_function" "true")
168 (if_then_else (eq_attr "empty_delay_slot" "true")
171 (if_then_else (eq_attr "empty_delay_slot" "true")
174 (eq_attr "branch_type" "icc")
175 (if_then_else (match_operand 0 "noov_compare64_operator" "")
176 (if_then_else (lt (pc) (match_dup 1))
177 (if_then_else (lt (minus (match_dup 1) (pc)) (const_int 260000))
178 (if_then_else (eq_attr "empty_delay_slot" "true")
181 (if_then_else (eq_attr "empty_delay_slot" "true")
184 (if_then_else (lt (minus (pc) (match_dup 1)) (const_int 260000))
185 (if_then_else (eq_attr "empty_delay_slot" "true")
188 (if_then_else (eq_attr "empty_delay_slot" "true")
191 (if_then_else (eq_attr "empty_delay_slot" "true")
194 (eq_attr "branch_type" "fcc")
195 (if_then_else (match_operand 0 "fcc0_register_operand" "")
196 (if_then_else (eq_attr "empty_delay_slot" "true")
197 (if_then_else (eq (symbol_ref "TARGET_V9") (const_int 0))
200 (if_then_else (eq (symbol_ref "TARGET_V9") (const_int 0))
203 (if_then_else (lt (pc) (match_dup 2))
204 (if_then_else (lt (minus (match_dup 2) (pc)) (const_int 260000))
205 (if_then_else (eq_attr "empty_delay_slot" "true")
208 (if_then_else (eq_attr "empty_delay_slot" "true")
211 (if_then_else (lt (minus (pc) (match_dup 2)) (const_int 260000))
212 (if_then_else (eq_attr "empty_delay_slot" "true")
215 (if_then_else (eq_attr "empty_delay_slot" "true")
218 (eq_attr "branch_type" "reg")
219 (if_then_else (lt (pc) (match_dup 2))
220 (if_then_else (lt (minus (match_dup 2) (pc)) (const_int 32000))
221 (if_then_else (eq_attr "empty_delay_slot" "true")
224 (if_then_else (eq_attr "empty_delay_slot" "true")
227 (if_then_else (lt (minus (pc) (match_dup 2)) (const_int 32000))
228 (if_then_else (eq_attr "empty_delay_slot" "true")
231 (if_then_else (eq_attr "empty_delay_slot" "true")
237 (define_attr "fptype" "single,double"
238 (const_string "single"))
240 ;; UltraSPARC-III integer load type.
241 (define_attr "us3load_type" "2cycle,3cycle"
242 (const_string "2cycle"))
244 (define_asm_attributes
245 [(set_attr "length" "2")
246 (set_attr "type" "multi")])
248 ;; Attributes for instruction and branch scheduling
249 (define_attr "tls_call_delay" "false,true"
250 (symbol_ref "(tls_call_delay (insn)
251 ? TLS_CALL_DELAY_TRUE : TLS_CALL_DELAY_FALSE)"))
253 (define_attr "in_call_delay" "false,true"
254 (cond [(eq_attr "type" "uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
255 (const_string "false")
256 (eq_attr "type" "load,fpload,store,fpstore")
257 (if_then_else (eq_attr "length" "1")
258 (const_string "true")
259 (const_string "false"))]
260 (if_then_else (and (eq_attr "length" "1")
261 (eq_attr "tls_call_delay" "true"))
262 (const_string "true")
263 (const_string "false"))))
265 (define_attr "eligible_for_sibcall_delay" "false,true"
266 (symbol_ref "(eligible_for_sibcall_delay (insn)
267 ? ELIGIBLE_FOR_SIBCALL_DELAY_TRUE
268 : ELIGIBLE_FOR_SIBCALL_DELAY_FALSE)"))
270 (define_attr "eligible_for_return_delay" "false,true"
271 (symbol_ref "(eligible_for_return_delay (insn)
272 ? ELIGIBLE_FOR_RETURN_DELAY_TRUE
273 : ELIGIBLE_FOR_RETURN_DELAY_FALSE)"))
275 ;; ??? !v9: Should implement the notion of predelay slots for floating-point
276 ;; branches. This would allow us to remove the nop always inserted before
277 ;; a floating point branch.
279 ;; ??? It is OK for fill_simple_delay_slots to put load/store instructions
280 ;; in a delay slot, but it is not OK for fill_eager_delay_slots to do so.
281 ;; This is because doing so will add several pipeline stalls to the path
282 ;; that the load/store did not come from. Unfortunately, there is no way
283 ;; to prevent fill_eager_delay_slots from using load/store without completely
284 ;; disabling them. For the SPEC benchmark set, this is a serious lose,
285 ;; because it prevents us from moving back the final store of inner loops.
287 (define_attr "in_branch_delay" "false,true"
288 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
289 (eq_attr "length" "1"))
290 (const_string "true")
291 (const_string "false")))
293 (define_attr "in_uncond_branch_delay" "false,true"
294 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
295 (eq_attr "length" "1"))
296 (const_string "true")
297 (const_string "false")))
299 (define_attr "in_annul_branch_delay" "false,true"
300 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
301 (eq_attr "length" "1"))
302 (const_string "true")
303 (const_string "false")))
305 (define_delay (eq_attr "type" "call")
306 [(eq_attr "in_call_delay" "true") (nil) (nil)])
308 (define_delay (eq_attr "type" "sibcall")
309 [(eq_attr "eligible_for_sibcall_delay" "true") (nil) (nil)])
311 (define_delay (eq_attr "type" "branch")
312 [(eq_attr "in_branch_delay" "true")
313 (nil) (eq_attr "in_annul_branch_delay" "true")])
315 (define_delay (eq_attr "type" "uncond_branch")
316 [(eq_attr "in_uncond_branch_delay" "true")
319 (define_delay (eq_attr "type" "return")
320 [(eq_attr "eligible_for_return_delay" "true") (nil) (nil)])
323 ;; Include SPARC DFA schedulers
325 (include "cypress.md")
326 (include "supersparc.md")
327 (include "hypersparc.md")
328 (include "sparclet.md")
329 (include "ultra1_2.md")
330 (include "ultra3.md")
331 (include "niagara.md")
332 (include "niagara2.md")
335 ;; Operand and operator predicates and constraints
337 (include "predicates.md")
338 (include "constraints.md")
341 ;; Compare instructions.
343 ;; We generate RTL for comparisons and branches by having the cmpxx
344 ;; patterns store away the operands. Then, the scc and bcc patterns
345 ;; emit RTL for both the compare and the branch.
347 ;; We do this because we want to generate different code for an sne and
348 ;; seq insn. In those cases, if the second operand of the compare is not
349 ;; const0_rtx, we want to compute the xor of the two operands and test
352 ;; We start with the DEFINE_EXPANDs, then the DEFINE_INSNs to match
353 ;; the patterns. Finally, we have the DEFINE_SPLITs for some of the scc
354 ;; insns that actually require more than one machine instruction.
356 (define_expand "cmpsi"
358 (compare:CC (match_operand:SI 0 "compare_operand" "")
359 (match_operand:SI 1 "arith_operand" "")))]
362 if (GET_CODE (operands[0]) == ZERO_EXTRACT && operands[1] != const0_rtx)
363 operands[0] = force_reg (SImode, operands[0]);
365 sparc_compare_op0 = operands[0];
366 sparc_compare_op1 = operands[1];
370 (define_expand "cmpdi"
372 (compare:CCX (match_operand:DI 0 "compare_operand" "")
373 (match_operand:DI 1 "arith_operand" "")))]
376 if (GET_CODE (operands[0]) == ZERO_EXTRACT && operands[1] != const0_rtx)
377 operands[0] = force_reg (DImode, operands[0]);
379 sparc_compare_op0 = operands[0];
380 sparc_compare_op1 = operands[1];
384 (define_expand "cmpsf"
385 ;; The 96 here isn't ever used by anyone.
387 (compare:CCFP (match_operand:SF 0 "register_operand" "")
388 (match_operand:SF 1 "register_operand" "")))]
391 sparc_compare_op0 = operands[0];
392 sparc_compare_op1 = operands[1];
396 (define_expand "cmpdf"
397 ;; The 96 here isn't ever used by anyone.
399 (compare:CCFP (match_operand:DF 0 "register_operand" "")
400 (match_operand:DF 1 "register_operand" "")))]
403 sparc_compare_op0 = operands[0];
404 sparc_compare_op1 = operands[1];
408 (define_expand "cmptf"
409 ;; The 96 here isn't ever used by anyone.
411 (compare:CCFP (match_operand:TF 0 "register_operand" "")
412 (match_operand:TF 1 "register_operand" "")))]
415 sparc_compare_op0 = operands[0];
416 sparc_compare_op1 = operands[1];
420 ;; Now the compare DEFINE_INSNs.
422 (define_insn "*cmpsi_insn"
424 (compare:CC (match_operand:SI 0 "register_operand" "r")
425 (match_operand:SI 1 "arith_operand" "rI")))]
428 [(set_attr "type" "compare")])
430 (define_insn "*cmpdi_sp64"
432 (compare:CCX (match_operand:DI 0 "register_operand" "r")
433 (match_operand:DI 1 "arith_operand" "rI")))]
436 [(set_attr "type" "compare")])
438 (define_insn "*cmpsf_fpe"
439 [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
440 (compare:CCFPE (match_operand:SF 1 "register_operand" "f")
441 (match_operand:SF 2 "register_operand" "f")))]
445 return "fcmpes\t%0, %1, %2";
446 return "fcmpes\t%1, %2";
448 [(set_attr "type" "fpcmp")])
450 (define_insn "*cmpdf_fpe"
451 [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
452 (compare:CCFPE (match_operand:DF 1 "register_operand" "e")
453 (match_operand:DF 2 "register_operand" "e")))]
457 return "fcmped\t%0, %1, %2";
458 return "fcmped\t%1, %2";
460 [(set_attr "type" "fpcmp")
461 (set_attr "fptype" "double")])
463 (define_insn "*cmptf_fpe"
464 [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
465 (compare:CCFPE (match_operand:TF 1 "register_operand" "e")
466 (match_operand:TF 2 "register_operand" "e")))]
467 "TARGET_FPU && TARGET_HARD_QUAD"
470 return "fcmpeq\t%0, %1, %2";
471 return "fcmpeq\t%1, %2";
473 [(set_attr "type" "fpcmp")])
475 (define_insn "*cmpsf_fp"
476 [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
477 (compare:CCFP (match_operand:SF 1 "register_operand" "f")
478 (match_operand:SF 2 "register_operand" "f")))]
482 return "fcmps\t%0, %1, %2";
483 return "fcmps\t%1, %2";
485 [(set_attr "type" "fpcmp")])
487 (define_insn "*cmpdf_fp"
488 [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
489 (compare:CCFP (match_operand:DF 1 "register_operand" "e")
490 (match_operand:DF 2 "register_operand" "e")))]
494 return "fcmpd\t%0, %1, %2";
495 return "fcmpd\t%1, %2";
497 [(set_attr "type" "fpcmp")
498 (set_attr "fptype" "double")])
500 (define_insn "*cmptf_fp"
501 [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
502 (compare:CCFP (match_operand:TF 1 "register_operand" "e")
503 (match_operand:TF 2 "register_operand" "e")))]
504 "TARGET_FPU && TARGET_HARD_QUAD"
507 return "fcmpq\t%0, %1, %2";
508 return "fcmpq\t%1, %2";
510 [(set_attr "type" "fpcmp")])
512 ;; Next come the scc insns. For seq, sne, sgeu, and sltu, we can do this
513 ;; without jumps using the addx/subx instructions. For seq/sne on v9 we use
514 ;; the same code as v8 (the addx/subx method has more applications). The
515 ;; exception to this is "reg != 0" which can be done in one instruction on v9
516 ;; (so we do it). For the rest, on v9 we use conditional moves; on v8, we do
519 ;; Seq_special[_xxx] and sne_special[_xxx] clobber the CC reg, because they
520 ;; generate addcc/subcc instructions.
522 (define_expand "seqsi_special"
524 (xor:SI (match_operand:SI 1 "register_operand" "")
525 (match_operand:SI 2 "register_operand" "")))
526 (parallel [(set (match_operand:SI 0 "register_operand" "")
527 (eq:SI (match_dup 3) (const_int 0)))
528 (clobber (reg:CC 100))])]
530 { operands[3] = gen_reg_rtx (SImode); })
532 (define_expand "seqdi_special"
534 (xor:DI (match_operand:DI 1 "register_operand" "")
535 (match_operand:DI 2 "register_operand" "")))
536 (set (match_operand:DI 0 "register_operand" "")
537 (eq:DI (match_dup 3) (const_int 0)))]
539 { operands[3] = gen_reg_rtx (DImode); })
541 (define_expand "snesi_special"
543 (xor:SI (match_operand:SI 1 "register_operand" "")
544 (match_operand:SI 2 "register_operand" "")))
545 (parallel [(set (match_operand:SI 0 "register_operand" "")
546 (ne:SI (match_dup 3) (const_int 0)))
547 (clobber (reg:CC 100))])]
549 { operands[3] = gen_reg_rtx (SImode); })
551 (define_expand "snedi_special"
553 (xor:DI (match_operand:DI 1 "register_operand" "")
554 (match_operand:DI 2 "register_operand" "")))
555 (set (match_operand:DI 0 "register_operand" "")
556 (ne:DI (match_dup 3) (const_int 0)))]
558 { operands[3] = gen_reg_rtx (DImode); })
560 (define_expand "seqdi_special_trunc"
562 (xor:DI (match_operand:DI 1 "register_operand" "")
563 (match_operand:DI 2 "register_operand" "")))
564 (set (match_operand:SI 0 "register_operand" "")
565 (eq:SI (match_dup 3) (const_int 0)))]
567 { operands[3] = gen_reg_rtx (DImode); })
569 (define_expand "snedi_special_trunc"
571 (xor:DI (match_operand:DI 1 "register_operand" "")
572 (match_operand:DI 2 "register_operand" "")))
573 (set (match_operand:SI 0 "register_operand" "")
574 (ne:SI (match_dup 3) (const_int 0)))]
576 { operands[3] = gen_reg_rtx (DImode); })
578 (define_expand "seqsi_special_extend"
580 (xor:SI (match_operand:SI 1 "register_operand" "")
581 (match_operand:SI 2 "register_operand" "")))
582 (parallel [(set (match_operand:DI 0 "register_operand" "")
583 (eq:DI (match_dup 3) (const_int 0)))
584 (clobber (reg:CC 100))])]
586 { operands[3] = gen_reg_rtx (SImode); })
588 (define_expand "snesi_special_extend"
590 (xor:SI (match_operand:SI 1 "register_operand" "")
591 (match_operand:SI 2 "register_operand" "")))
592 (parallel [(set (match_operand:DI 0 "register_operand" "")
593 (ne:DI (match_dup 3) (const_int 0)))
594 (clobber (reg:CC 100))])]
596 { operands[3] = gen_reg_rtx (SImode); })
598 ;; ??? v9: Operand 0 needs a mode, so SImode was chosen.
599 ;; However, the code handles both SImode and DImode.
601 [(set (match_operand:SI 0 "int_register_operand" "")
602 (eq:SI (match_dup 1) (const_int 0)))]
605 if (GET_MODE (sparc_compare_op0) == SImode)
609 if (GET_MODE (operands[0]) == SImode)
610 pat = gen_seqsi_special (operands[0], sparc_compare_op0,
612 else if (! TARGET_ARCH64)
615 pat = gen_seqsi_special_extend (operands[0], sparc_compare_op0,
620 else if (GET_MODE (sparc_compare_op0) == DImode)
626 else if (GET_MODE (operands[0]) == SImode)
627 pat = gen_seqdi_special_trunc (operands[0], sparc_compare_op0,
630 pat = gen_seqdi_special (operands[0], sparc_compare_op0,
635 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
638 = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, EQ);
639 gcc_assert (code == NE);
640 emit_insn (gen_sne (operands[0]));
645 if (gen_v9_scc (EQ, operands))
652 ;; ??? v9: Operand 0 needs a mode, so SImode was chosen.
653 ;; However, the code handles both SImode and DImode.
655 [(set (match_operand:SI 0 "int_register_operand" "")
656 (ne:SI (match_dup 1) (const_int 0)))]
659 if (GET_MODE (sparc_compare_op0) == SImode)
663 if (GET_MODE (operands[0]) == SImode)
664 pat = gen_snesi_special (operands[0], sparc_compare_op0,
666 else if (! TARGET_ARCH64)
669 pat = gen_snesi_special_extend (operands[0], sparc_compare_op0,
674 else if (GET_MODE (sparc_compare_op0) == DImode)
680 else if (GET_MODE (operands[0]) == SImode)
681 pat = gen_snedi_special_trunc (operands[0], sparc_compare_op0,
684 pat = gen_snedi_special (operands[0], sparc_compare_op0,
689 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
692 = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, NE);
693 gcc_assert (code == NE);
694 emit_insn (gen_sne (operands[0]));
699 if (gen_v9_scc (NE, operands))
707 [(set (match_operand:SI 0 "int_register_operand" "")
708 (gt:SI (match_dup 1) (const_int 0)))]
711 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
714 = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GT);
715 gcc_assert (code == NE);
716 emit_insn (gen_sne (operands[0]));
721 if (gen_v9_scc (GT, operands))
729 [(set (match_operand:SI 0 "int_register_operand" "")
730 (lt:SI (match_dup 1) (const_int 0)))]
733 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
736 = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LT);
737 gcc_assert (code == NE);
738 emit_insn (gen_sne (operands[0]));
743 if (gen_v9_scc (LT, operands))
751 [(set (match_operand:SI 0 "int_register_operand" "")
752 (ge:SI (match_dup 1) (const_int 0)))]
755 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
758 = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GE);
759 gcc_assert (code == NE);
760 emit_insn (gen_sne (operands[0]));
765 if (gen_v9_scc (GE, operands))
773 [(set (match_operand:SI 0 "int_register_operand" "")
774 (le:SI (match_dup 1) (const_int 0)))]
777 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
780 = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LE);
781 gcc_assert (code == NE);
782 emit_insn (gen_sne (operands[0]));
787 if (gen_v9_scc (LE, operands))
794 (define_expand "sgtu"
795 [(set (match_operand:SI 0 "int_register_operand" "")
796 (gtu:SI (match_dup 1) (const_int 0)))]
803 /* We can do ltu easily, so if both operands are registers, swap them and
805 if ((GET_CODE (sparc_compare_op0) == REG
806 || GET_CODE (sparc_compare_op0) == SUBREG)
807 && (GET_CODE (sparc_compare_op1) == REG
808 || GET_CODE (sparc_compare_op1) == SUBREG))
810 tem = sparc_compare_op0;
811 sparc_compare_op0 = sparc_compare_op1;
812 sparc_compare_op1 = tem;
813 pat = gen_sltu (operands[0]);
822 if (gen_v9_scc (GTU, operands))
828 (define_expand "sltu"
829 [(set (match_operand:SI 0 "int_register_operand" "")
830 (ltu:SI (match_dup 1) (const_int 0)))]
835 if (gen_v9_scc (LTU, operands))
838 operands[1] = gen_compare_reg (LTU);
841 (define_expand "sgeu"
842 [(set (match_operand:SI 0 "int_register_operand" "")
843 (geu:SI (match_dup 1) (const_int 0)))]
848 if (gen_v9_scc (GEU, operands))
851 operands[1] = gen_compare_reg (GEU);
854 (define_expand "sleu"
855 [(set (match_operand:SI 0 "int_register_operand" "")
856 (leu:SI (match_dup 1) (const_int 0)))]
863 /* We can do geu easily, so if both operands are registers, swap them and
865 if ((GET_CODE (sparc_compare_op0) == REG
866 || GET_CODE (sparc_compare_op0) == SUBREG)
867 && (GET_CODE (sparc_compare_op1) == REG
868 || GET_CODE (sparc_compare_op1) == SUBREG))
870 tem = sparc_compare_op0;
871 sparc_compare_op0 = sparc_compare_op1;
872 sparc_compare_op1 = tem;
873 pat = gen_sgeu (operands[0]);
882 if (gen_v9_scc (LEU, operands))
888 ;; Now the DEFINE_INSNs for the scc cases.
890 ;; The SEQ and SNE patterns are special because they can be done
891 ;; without any branching and do not involve a COMPARE. We want
892 ;; them to always use the splits below so the results can be
895 (define_insn_and_split "*snesi_zero"
896 [(set (match_operand:SI 0 "register_operand" "=r")
897 (ne:SI (match_operand:SI 1 "register_operand" "r")
899 (clobber (reg:CC 100))]
903 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
905 (set (match_dup 0) (ltu:SI (reg:CC 100) (const_int 0)))]
907 [(set_attr "length" "2")])
909 (define_insn_and_split "*neg_snesi_zero"
910 [(set (match_operand:SI 0 "register_operand" "=r")
911 (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
913 (clobber (reg:CC 100))]
917 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
919 (set (match_dup 0) (neg:SI (ltu:SI (reg:CC 100) (const_int 0))))]
921 [(set_attr "length" "2")])
923 (define_insn_and_split "*snesi_zero_extend"
924 [(set (match_operand:DI 0 "register_operand" "=r")
925 (ne:DI (match_operand:SI 1 "register_operand" "r")
927 (clobber (reg:CC 100))]
931 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (minus:SI (const_int 0)
934 (set (match_dup 0) (zero_extend:DI (plus:SI (plus:SI (const_int 0)
936 (ltu:SI (reg:CC_NOOV 100)
939 [(set_attr "length" "2")])
941 (define_insn_and_split "*snedi_zero"
942 [(set (match_operand:DI 0 "register_operand" "=&r")
943 (ne:DI (match_operand:DI 1 "register_operand" "r")
947 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
948 [(set (match_dup 0) (const_int 0))
949 (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
954 [(set_attr "length" "2")])
956 (define_insn_and_split "*neg_snedi_zero"
957 [(set (match_operand:DI 0 "register_operand" "=&r")
958 (neg:DI (ne:DI (match_operand:DI 1 "register_operand" "r")
962 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
963 [(set (match_dup 0) (const_int 0))
964 (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
969 [(set_attr "length" "2")])
971 (define_insn_and_split "*snedi_zero_trunc"
972 [(set (match_operand:SI 0 "register_operand" "=&r")
973 (ne:SI (match_operand:DI 1 "register_operand" "r")
977 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
978 [(set (match_dup 0) (const_int 0))
979 (set (match_dup 0) (if_then_else:SI (ne:DI (match_dup 1)
984 [(set_attr "length" "2")])
986 (define_insn_and_split "*seqsi_zero"
987 [(set (match_operand:SI 0 "register_operand" "=r")
988 (eq:SI (match_operand:SI 1 "register_operand" "r")
990 (clobber (reg:CC 100))]
994 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
996 (set (match_dup 0) (geu:SI (reg:CC 100) (const_int 0)))]
998 [(set_attr "length" "2")])
1000 (define_insn_and_split "*neg_seqsi_zero"
1001 [(set (match_operand:SI 0 "register_operand" "=r")
1002 (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
1004 (clobber (reg:CC 100))]
1008 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1010 (set (match_dup 0) (neg:SI (geu:SI (reg:CC 100) (const_int 0))))]
1012 [(set_attr "length" "2")])
1014 (define_insn_and_split "*seqsi_zero_extend"
1015 [(set (match_operand:DI 0 "register_operand" "=r")
1016 (eq:DI (match_operand:SI 1 "register_operand" "r")
1018 (clobber (reg:CC 100))]
1022 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (minus:SI (const_int 0)
1025 (set (match_dup 0) (zero_extend:DI (minus:SI (minus:SI (const_int 0)
1027 (ltu:SI (reg:CC_NOOV 100)
1030 [(set_attr "length" "2")])
1032 (define_insn_and_split "*seqdi_zero"
1033 [(set (match_operand:DI 0 "register_operand" "=&r")
1034 (eq:DI (match_operand:DI 1 "register_operand" "r")
1038 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
1039 [(set (match_dup 0) (const_int 0))
1040 (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
1045 [(set_attr "length" "2")])
1047 (define_insn_and_split "*neg_seqdi_zero"
1048 [(set (match_operand:DI 0 "register_operand" "=&r")
1049 (neg:DI (eq:DI (match_operand:DI 1 "register_operand" "r")
1053 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
1054 [(set (match_dup 0) (const_int 0))
1055 (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
1060 [(set_attr "length" "2")])
1062 (define_insn_and_split "*seqdi_zero_trunc"
1063 [(set (match_operand:SI 0 "register_operand" "=&r")
1064 (eq:SI (match_operand:DI 1 "register_operand" "r")
1068 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
1069 [(set (match_dup 0) (const_int 0))
1070 (set (match_dup 0) (if_then_else:SI (eq:DI (match_dup 1)
1075 [(set_attr "length" "2")])
1077 ;; We can also do (x + (i == 0)) and related, so put them in.
1078 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1081 (define_insn_and_split "*x_plus_i_ne_0"
1082 [(set (match_operand:SI 0 "register_operand" "=r")
1083 (plus:SI (ne: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 (ltu:SI (reg:CC 100) (const_int 0))
1095 [(set_attr "length" "2")])
1097 (define_insn_and_split "*x_minus_i_ne_0"
1098 [(set (match_operand:SI 0 "register_operand" "=r")
1099 (minus:SI (match_operand:SI 2 "register_operand" "r")
1100 (ne: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 (ltu:SI (reg:CC 100) (const_int 0))))]
1111 [(set_attr "length" "2")])
1113 (define_insn_and_split "*x_plus_i_eq_0"
1114 [(set (match_operand:SI 0 "register_operand" "=r")
1115 (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
1117 (match_operand:SI 2 "register_operand" "r")))
1118 (clobber (reg:CC 100))]
1122 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1124 (set (match_dup 0) (plus:SI (geu:SI (reg:CC 100) (const_int 0))
1127 [(set_attr "length" "2")])
1129 (define_insn_and_split "*x_minus_i_eq_0"
1130 [(set (match_operand:SI 0 "register_operand" "=r")
1131 (minus:SI (match_operand:SI 2 "register_operand" "r")
1132 (eq:SI (match_operand:SI 1 "register_operand" "r")
1134 (clobber (reg:CC 100))]
1138 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1140 (set (match_dup 0) (minus:SI (match_dup 2)
1141 (geu:SI (reg:CC 100) (const_int 0))))]
1143 [(set_attr "length" "2")])
1145 ;; We can also do GEU and LTU directly, but these operate after a compare.
1146 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1149 (define_insn "*sltu_insn"
1150 [(set (match_operand:SI 0 "register_operand" "=r")
1151 (ltu:SI (reg:CC 100) (const_int 0)))]
1154 [(set_attr "type" "ialuX")])
1156 (define_insn "*neg_sltu_insn"
1157 [(set (match_operand:SI 0 "register_operand" "=r")
1158 (neg:SI (ltu:SI (reg:CC 100) (const_int 0))))]
1161 [(set_attr "type" "ialuX")])
1163 ;; ??? Combine should canonicalize these next two to the same pattern.
1164 (define_insn "*neg_sltu_minus_x"
1165 [(set (match_operand:SI 0 "register_operand" "=r")
1166 (minus:SI (neg:SI (ltu:SI (reg:CC 100) (const_int 0)))
1167 (match_operand:SI 1 "arith_operand" "rI")))]
1169 "subx\t%%g0, %1, %0"
1170 [(set_attr "type" "ialuX")])
1172 (define_insn "*neg_sltu_plus_x"
1173 [(set (match_operand:SI 0 "register_operand" "=r")
1174 (neg:SI (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1175 (match_operand:SI 1 "arith_operand" "rI"))))]
1177 "subx\t%%g0, %1, %0"
1178 [(set_attr "type" "ialuX")])
1180 (define_insn "*sgeu_insn"
1181 [(set (match_operand:SI 0 "register_operand" "=r")
1182 (geu:SI (reg:CC 100) (const_int 0)))]
1184 "subx\t%%g0, -1, %0"
1185 [(set_attr "type" "ialuX")])
1187 (define_insn "*neg_sgeu_insn"
1188 [(set (match_operand:SI 0 "register_operand" "=r")
1189 (neg:SI (geu:SI (reg:CC 100) (const_int 0))))]
1191 "addx\t%%g0, -1, %0"
1192 [(set_attr "type" "ialuX")])
1194 ;; We can also do (x + ((unsigned) i >= 0)) and related, so put them in.
1195 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1198 (define_insn "*sltu_plus_x"
1199 [(set (match_operand:SI 0 "register_operand" "=r")
1200 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1201 (match_operand:SI 1 "arith_operand" "rI")))]
1203 "addx\t%%g0, %1, %0"
1204 [(set_attr "type" "ialuX")])
1206 (define_insn "*sltu_plus_x_plus_y"
1207 [(set (match_operand:SI 0 "register_operand" "=r")
1208 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1209 (plus:SI (match_operand:SI 1 "arith_operand" "%r")
1210 (match_operand:SI 2 "arith_operand" "rI"))))]
1213 [(set_attr "type" "ialuX")])
1215 (define_insn "*x_minus_sltu"
1216 [(set (match_operand:SI 0 "register_operand" "=r")
1217 (minus:SI (match_operand:SI 1 "register_operand" "r")
1218 (ltu:SI (reg:CC 100) (const_int 0))))]
1221 [(set_attr "type" "ialuX")])
1223 ;; ??? Combine should canonicalize these next two to the same pattern.
1224 (define_insn "*x_minus_y_minus_sltu"
1225 [(set (match_operand:SI 0 "register_operand" "=r")
1226 (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
1227 (match_operand:SI 2 "arith_operand" "rI"))
1228 (ltu:SI (reg:CC 100) (const_int 0))))]
1231 [(set_attr "type" "ialuX")])
1233 (define_insn "*x_minus_sltu_plus_y"
1234 [(set (match_operand:SI 0 "register_operand" "=r")
1235 (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
1236 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1237 (match_operand:SI 2 "arith_operand" "rI"))))]
1240 [(set_attr "type" "ialuX")])
1242 (define_insn "*sgeu_plus_x"
1243 [(set (match_operand:SI 0 "register_operand" "=r")
1244 (plus:SI (geu:SI (reg:CC 100) (const_int 0))
1245 (match_operand:SI 1 "register_operand" "r")))]
1248 [(set_attr "type" "ialuX")])
1250 (define_insn "*x_minus_sgeu"
1251 [(set (match_operand:SI 0 "register_operand" "=r")
1252 (minus:SI (match_operand:SI 1 "register_operand" "r")
1253 (geu:SI (reg:CC 100) (const_int 0))))]
1256 [(set_attr "type" "ialuX")])
1259 [(set (match_operand:SI 0 "register_operand" "")
1260 (match_operator:SI 2 "noov_compare_operator"
1261 [(match_operand 1 "icc_or_fcc_register_operand" "")
1264 && REGNO (operands[1]) == SPARC_ICC_REG
1265 && (GET_MODE (operands[1]) == CCXmode
1266 /* 32-bit LTU/GEU are better implemented using addx/subx. */
1267 || (GET_CODE (operands[2]) != LTU && GET_CODE (operands[2]) != GEU))"
1268 [(set (match_dup 0) (const_int 0))
1270 (if_then_else:SI (match_op_dup:SI 2 [(match_dup 1) (const_int 0)])
1276 ;; These control RTL generation for conditional jump insns
1278 ;; The quad-word fp compare library routines all return nonzero to indicate
1279 ;; true, which is different from the equivalent libgcc routines, so we must
1280 ;; handle them specially here.
1282 (define_expand "beq"
1284 (if_then_else (eq (match_dup 1) (const_int 0))
1285 (label_ref (match_operand 0 "" ""))
1289 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1290 && GET_CODE (sparc_compare_op0) == REG
1291 && GET_MODE (sparc_compare_op0) == DImode)
1293 emit_v9_brxx_insn (EQ, sparc_compare_op0, operands[0]);
1296 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1299 = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, EQ);
1300 gcc_assert (code == NE);
1301 emit_jump_insn (gen_bne (operands[0]));
1304 operands[1] = gen_compare_reg (EQ);
1307 (define_expand "bne"
1309 (if_then_else (ne (match_dup 1) (const_int 0))
1310 (label_ref (match_operand 0 "" ""))
1314 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1315 && GET_CODE (sparc_compare_op0) == REG
1316 && GET_MODE (sparc_compare_op0) == DImode)
1318 emit_v9_brxx_insn (NE, sparc_compare_op0, operands[0]);
1321 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1324 = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, NE);
1325 gcc_assert (code == NE);
1326 emit_jump_insn (gen_bne (operands[0]));
1329 operands[1] = gen_compare_reg (NE);
1332 (define_expand "bgt"
1334 (if_then_else (gt (match_dup 1) (const_int 0))
1335 (label_ref (match_operand 0 "" ""))
1339 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1340 && GET_CODE (sparc_compare_op0) == REG
1341 && GET_MODE (sparc_compare_op0) == DImode)
1343 emit_v9_brxx_insn (GT, sparc_compare_op0, operands[0]);
1346 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1349 = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GT);
1350 gcc_assert (code == NE);
1351 emit_jump_insn (gen_bne (operands[0]));
1354 operands[1] = gen_compare_reg (GT);
1357 (define_expand "bgtu"
1359 (if_then_else (gtu (match_dup 1) (const_int 0))
1360 (label_ref (match_operand 0 "" ""))
1364 operands[1] = gen_compare_reg (GTU);
1367 (define_expand "blt"
1369 (if_then_else (lt (match_dup 1) (const_int 0))
1370 (label_ref (match_operand 0 "" ""))
1374 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1375 && GET_CODE (sparc_compare_op0) == REG
1376 && GET_MODE (sparc_compare_op0) == DImode)
1378 emit_v9_brxx_insn (LT, sparc_compare_op0, operands[0]);
1381 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1384 = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LT);
1385 gcc_assert (code == NE);
1386 emit_jump_insn (gen_bne (operands[0]));
1389 operands[1] = gen_compare_reg (LT);
1392 (define_expand "bltu"
1394 (if_then_else (ltu (match_dup 1) (const_int 0))
1395 (label_ref (match_operand 0 "" ""))
1399 operands[1] = gen_compare_reg (LTU);
1402 (define_expand "bge"
1404 (if_then_else (ge (match_dup 1) (const_int 0))
1405 (label_ref (match_operand 0 "" ""))
1409 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1410 && GET_CODE (sparc_compare_op0) == REG
1411 && GET_MODE (sparc_compare_op0) == DImode)
1413 emit_v9_brxx_insn (GE, sparc_compare_op0, operands[0]);
1416 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1419 = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GE);
1420 gcc_assert (code == NE);
1421 emit_jump_insn (gen_bne (operands[0]));
1424 operands[1] = gen_compare_reg (GE);
1427 (define_expand "bgeu"
1429 (if_then_else (geu (match_dup 1) (const_int 0))
1430 (label_ref (match_operand 0 "" ""))
1434 operands[1] = gen_compare_reg (GEU);
1437 (define_expand "ble"
1439 (if_then_else (le (match_dup 1) (const_int 0))
1440 (label_ref (match_operand 0 "" ""))
1444 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1445 && GET_CODE (sparc_compare_op0) == REG
1446 && GET_MODE (sparc_compare_op0) == DImode)
1448 emit_v9_brxx_insn (LE, sparc_compare_op0, operands[0]);
1451 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1454 = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LE);
1455 gcc_assert (code == NE);
1456 emit_jump_insn (gen_bne (operands[0]));
1459 operands[1] = gen_compare_reg (LE);
1462 (define_expand "bleu"
1464 (if_then_else (leu (match_dup 1) (const_int 0))
1465 (label_ref (match_operand 0 "" ""))
1469 operands[1] = gen_compare_reg (LEU);
1472 (define_expand "bunordered"
1474 (if_then_else (unordered (match_dup 1) (const_int 0))
1475 (label_ref (match_operand 0 "" ""))
1479 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1482 = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNORDERED);
1483 gcc_assert (code == EQ);
1484 emit_jump_insn (gen_beq (operands[0]));
1487 operands[1] = gen_compare_reg (UNORDERED);
1490 (define_expand "bordered"
1492 (if_then_else (ordered (match_dup 1) (const_int 0))
1493 (label_ref (match_operand 0 "" ""))
1497 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1500 = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, ORDERED);
1501 gcc_assert (code == NE);
1502 emit_jump_insn (gen_bne (operands[0]));
1505 operands[1] = gen_compare_reg (ORDERED);
1508 (define_expand "bungt"
1510 (if_then_else (ungt (match_dup 1) (const_int 0))
1511 (label_ref (match_operand 0 "" ""))
1515 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1518 = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNGT);
1519 gcc_assert (code == GT);
1520 emit_jump_insn (gen_bgt (operands[0]));
1523 operands[1] = gen_compare_reg (UNGT);
1526 (define_expand "bunlt"
1528 (if_then_else (unlt (match_dup 1) (const_int 0))
1529 (label_ref (match_operand 0 "" ""))
1533 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1536 = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNLT);
1537 gcc_assert (code == NE);
1538 emit_jump_insn (gen_bne (operands[0]));
1541 operands[1] = gen_compare_reg (UNLT);
1544 (define_expand "buneq"
1546 (if_then_else (uneq (match_dup 1) (const_int 0))
1547 (label_ref (match_operand 0 "" ""))
1551 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1554 = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNEQ);
1555 gcc_assert (code == EQ);
1556 emit_jump_insn (gen_beq (operands[0]));
1559 operands[1] = gen_compare_reg (UNEQ);
1562 (define_expand "bunge"
1564 (if_then_else (unge (match_dup 1) (const_int 0))
1565 (label_ref (match_operand 0 "" ""))
1569 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1572 = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNGE);
1573 gcc_assert (code == NE);
1574 emit_jump_insn (gen_bne (operands[0]));
1577 operands[1] = gen_compare_reg (UNGE);
1580 (define_expand "bunle"
1582 (if_then_else (unle (match_dup 1) (const_int 0))
1583 (label_ref (match_operand 0 "" ""))
1587 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1590 = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNLE);
1591 gcc_assert (code == NE);
1592 emit_jump_insn (gen_bne (operands[0]));
1595 operands[1] = gen_compare_reg (UNLE);
1598 (define_expand "bltgt"
1600 (if_then_else (ltgt (match_dup 1) (const_int 0))
1601 (label_ref (match_operand 0 "" ""))
1605 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1608 = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LTGT);
1609 gcc_assert (code == NE);
1610 emit_jump_insn (gen_bne (operands[0]));
1613 operands[1] = gen_compare_reg (LTGT);
1616 ;; Now match both normal and inverted jump.
1618 ;; XXX fpcmp nop braindamage
1619 (define_insn "*normal_branch"
1621 (if_then_else (match_operator 0 "noov_compare_operator"
1622 [(reg 100) (const_int 0)])
1623 (label_ref (match_operand 1 "" ""))
1627 return output_cbranch (operands[0], operands[1], 1, 0,
1628 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1631 [(set_attr "type" "branch")
1632 (set_attr "branch_type" "icc")])
1634 ;; XXX fpcmp nop braindamage
1635 (define_insn "*inverted_branch"
1637 (if_then_else (match_operator 0 "noov_compare_operator"
1638 [(reg 100) (const_int 0)])
1640 (label_ref (match_operand 1 "" ""))))]
1643 return output_cbranch (operands[0], operands[1], 1, 1,
1644 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1647 [(set_attr "type" "branch")
1648 (set_attr "branch_type" "icc")])
1650 ;; XXX fpcmp nop braindamage
1651 (define_insn "*normal_fp_branch"
1653 (if_then_else (match_operator 1 "comparison_operator"
1654 [(match_operand:CCFP 0 "fcc_register_operand" "c")
1656 (label_ref (match_operand 2 "" ""))
1660 return output_cbranch (operands[1], operands[2], 2, 0,
1661 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1664 [(set_attr "type" "branch")
1665 (set_attr "branch_type" "fcc")])
1667 ;; XXX fpcmp nop braindamage
1668 (define_insn "*inverted_fp_branch"
1670 (if_then_else (match_operator 1 "comparison_operator"
1671 [(match_operand:CCFP 0 "fcc_register_operand" "c")
1674 (label_ref (match_operand 2 "" ""))))]
1677 return output_cbranch (operands[1], operands[2], 2, 1,
1678 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1681 [(set_attr "type" "branch")
1682 (set_attr "branch_type" "fcc")])
1684 ;; XXX fpcmp nop braindamage
1685 (define_insn "*normal_fpe_branch"
1687 (if_then_else (match_operator 1 "comparison_operator"
1688 [(match_operand:CCFPE 0 "fcc_register_operand" "c")
1690 (label_ref (match_operand 2 "" ""))
1694 return output_cbranch (operands[1], operands[2], 2, 0,
1695 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1698 [(set_attr "type" "branch")
1699 (set_attr "branch_type" "fcc")])
1701 ;; XXX fpcmp nop braindamage
1702 (define_insn "*inverted_fpe_branch"
1704 (if_then_else (match_operator 1 "comparison_operator"
1705 [(match_operand:CCFPE 0 "fcc_register_operand" "c")
1708 (label_ref (match_operand 2 "" ""))))]
1711 return output_cbranch (operands[1], operands[2], 2, 1,
1712 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1715 [(set_attr "type" "branch")
1716 (set_attr "branch_type" "fcc")])
1718 ;; SPARC V9-specific jump insns. None of these are guaranteed to be
1719 ;; in the architecture.
1721 ;; There are no 32 bit brreg insns.
1724 (define_insn "*normal_int_branch_sp64"
1726 (if_then_else (match_operator 0 "v9_register_compare_operator"
1727 [(match_operand:DI 1 "register_operand" "r")
1729 (label_ref (match_operand 2 "" ""))
1733 return output_v9branch (operands[0], operands[2], 1, 2, 0,
1734 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1737 [(set_attr "type" "branch")
1738 (set_attr "branch_type" "reg")])
1741 (define_insn "*inverted_int_branch_sp64"
1743 (if_then_else (match_operator 0 "v9_register_compare_operator"
1744 [(match_operand:DI 1 "register_operand" "r")
1747 (label_ref (match_operand 2 "" ""))))]
1750 return output_v9branch (operands[0], operands[2], 1, 2, 1,
1751 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1754 [(set_attr "type" "branch")
1755 (set_attr "branch_type" "reg")])
1758 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
1760 ;; Load in operand 0 the (absolute) address of operand 1, which is a symbolic
1761 ;; value subject to a PC-relative relocation. Operand 2 is a helper function
1762 ;; that adds the PC value at the call point to operand 0.
1764 (define_insn "load_pcrel_sym<P:mode>"
1765 [(set (match_operand:P 0 "register_operand" "=r")
1766 (unspec:P [(match_operand:P 1 "symbolic_operand" "")
1767 (match_operand:P 2 "call_address_operand" "")] UNSPEC_LOAD_PCREL_SYM))
1768 (clobber (reg:P 15))]
1771 if (flag_delayed_branch)
1772 return "sethi\t%%hi(%a1-4), %0\n\tcall\t%a2\n\t add\t%0, %%lo(%a1+4), %0";
1774 return "sethi\t%%hi(%a1-8), %0\n\tadd\t%0, %%lo(%a1-4), %0\n\tcall\t%a2\n\t nop";
1776 [(set (attr "type") (const_string "multi"))
1777 (set (attr "length")
1778 (if_then_else (eq_attr "delayed_branch" "true")
1783 ;; Integer move instructions
1785 (define_expand "movqi"
1786 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1787 (match_operand:QI 1 "general_operand" ""))]
1790 if (sparc_expand_move (QImode, operands))
1794 (define_insn "*movqi_insn"
1795 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m")
1796 (match_operand:QI 1 "input_operand" "rI,m,rJ"))]
1797 "(register_operand (operands[0], QImode)
1798 || register_or_zero_operand (operands[1], QImode))"
1803 [(set_attr "type" "*,load,store")
1804 (set_attr "us3load_type" "*,3cycle,*")])
1806 (define_expand "movhi"
1807 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1808 (match_operand:HI 1 "general_operand" ""))]
1811 if (sparc_expand_move (HImode, operands))
1815 (define_insn "*movhi_insn"
1816 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1817 (match_operand:HI 1 "input_operand" "rI,K,m,rJ"))]
1818 "(register_operand (operands[0], HImode)
1819 || register_or_zero_operand (operands[1], HImode))"
1822 sethi\t%%hi(%a1), %0
1825 [(set_attr "type" "*,*,load,store")
1826 (set_attr "us3load_type" "*,*,3cycle,*")])
1828 ;; We always work with constants here.
1829 (define_insn "*movhi_lo_sum"
1830 [(set (match_operand:HI 0 "register_operand" "=r")
1831 (ior:HI (match_operand:HI 1 "register_operand" "%r")
1832 (match_operand:HI 2 "small_int_operand" "I")))]
1836 (define_expand "movsi"
1837 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1838 (match_operand:SI 1 "general_operand" ""))]
1841 if (sparc_expand_move (SImode, operands))
1845 (define_insn "*movsi_insn"
1846 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,m,!f,!f,!m,d")
1847 (match_operand:SI 1 "input_operand" "rI,K,m,rJ,f,m,f,J"))]
1848 "(register_operand (operands[0], SImode)
1849 || register_or_zero_operand (operands[1], SImode))"
1852 sethi\t%%hi(%a1), %0
1859 [(set_attr "type" "*,*,load,store,fpmove,fpload,fpstore,fga")])
1861 (define_insn "*movsi_lo_sum"
1862 [(set (match_operand:SI 0 "register_operand" "=r")
1863 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1864 (match_operand:SI 2 "immediate_operand" "in")))]
1866 "or\t%1, %%lo(%a2), %0")
1868 (define_insn "*movsi_high"
1869 [(set (match_operand:SI 0 "register_operand" "=r")
1870 (high:SI (match_operand:SI 1 "immediate_operand" "in")))]
1872 "sethi\t%%hi(%a1), %0")
1874 ;; The next two patterns must wrap the SYMBOL_REF in an UNSPEC
1875 ;; so that CSE won't optimize the address computation away.
1876 (define_insn "movsi_lo_sum_pic"
1877 [(set (match_operand:SI 0 "register_operand" "=r")
1878 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1879 (unspec:SI [(match_operand:SI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
1881 "or\t%1, %%lo(%a2), %0")
1883 (define_insn "movsi_high_pic"
1884 [(set (match_operand:SI 0 "register_operand" "=r")
1885 (high:SI (unspec:SI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
1886 "flag_pic && check_pic (1)"
1887 "sethi\t%%hi(%a1), %0")
1889 (define_expand "movsi_pic_label_ref"
1890 [(set (match_dup 3) (high:SI
1891 (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
1892 (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1893 (set (match_dup 4) (lo_sum:SI (match_dup 3)
1894 (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1895 (set (match_operand:SI 0 "register_operand" "=r")
1896 (minus:SI (match_dup 5) (match_dup 4)))]
1899 crtl->uses_pic_offset_table = 1;
1900 operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
1901 if (!can_create_pseudo_p ())
1903 operands[3] = operands[0];
1904 operands[4] = operands[0];
1908 operands[3] = gen_reg_rtx (SImode);
1909 operands[4] = gen_reg_rtx (SImode);
1911 operands[5] = pic_offset_table_rtx;
1914 (define_insn "*movsi_high_pic_label_ref"
1915 [(set (match_operand:SI 0 "register_operand" "=r")
1917 (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
1918 (match_operand:SI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1920 "sethi\t%%hi(%a2-(%a1-.)), %0")
1922 (define_insn "*movsi_lo_sum_pic_label_ref"
1923 [(set (match_operand:SI 0 "register_operand" "=r")
1924 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1925 (unspec:SI [(match_operand:SI 2 "label_ref_operand" "")
1926 (match_operand:SI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1928 "or\t%1, %%lo(%a3-(%a2-.)), %0")
1930 ;; Set up the PIC register for VxWorks.
1932 (define_expand "vxworks_load_got"
1934 (high:SI (match_dup 1)))
1936 (mem:SI (lo_sum:SI (match_dup 0) (match_dup 1))))
1938 (mem:SI (lo_sum:SI (match_dup 0) (match_dup 2))))]
1939 "TARGET_VXWORKS_RTP"
1941 operands[0] = pic_offset_table_rtx;
1942 operands[1] = gen_rtx_SYMBOL_REF (SImode, VXWORKS_GOTT_BASE);
1943 operands[2] = gen_rtx_SYMBOL_REF (SImode, VXWORKS_GOTT_INDEX);
1946 (define_expand "movdi"
1947 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1948 (match_operand:DI 1 "general_operand" ""))]
1951 if (sparc_expand_move (DImode, operands))
1955 ;; Be careful, fmovd does not exist when !v9.
1956 ;; We match MEM moves directly when we have correct even
1957 ;; numbered registers, but fall into splits otherwise.
1958 ;; The constraint ordering here is really important to
1959 ;; avoid insane problems in reload, especially for patterns
1962 ;; (set (mem:DI (plus:SI (reg:SI 30 %fp)
1963 ;; (const_int -5016)))
1967 (define_insn "*movdi_insn_sp32"
1968 [(set (match_operand:DI 0 "nonimmediate_operand"
1969 "=o,T,U,o,r,r,r,?T,?f,?f,?o,?f")
1970 (match_operand:DI 1 "input_operand"
1971 " J,U,T,r,o,i,r, f, T, o, f, f"))]
1973 && (register_operand (operands[0], DImode)
1974 || register_or_zero_operand (operands[1], DImode))"
1988 [(set_attr "type" "store,store,load,*,*,*,*,fpstore,fpload,*,*,*")
1989 (set_attr "length" "2,*,*,2,2,2,2,*,*,2,2,2")])
1991 (define_insn "*movdi_insn_sp32_v9"
1992 [(set (match_operand:DI 0 "nonimmediate_operand"
1993 "=T,o,T,U,o,r,r,r,?T,?f,?f,?o,?e,?e,?W")
1994 (match_operand:DI 1 "input_operand"
1995 " J,J,U,T,r,o,i,r, f, T, o, f, e, W, e"))]
1998 && (register_operand (operands[0], DImode)
1999 || register_or_zero_operand (operands[1], DImode))"
2016 [(set_attr "type" "store,store,store,load,*,*,*,*,fpstore,fpload,*,*,fpmove,fpload,fpstore")
2017 (set_attr "length" "*,2,*,*,2,2,2,2,*,*,2,2,*,*,*")
2018 (set_attr "fptype" "*,*,*,*,*,*,*,*,*,*,*,*,double,*,*")])
2020 (define_insn "*movdi_insn_sp64"
2021 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,m,?e,?e,?W,b")
2022 (match_operand:DI 1 "input_operand" "rI,N,m,rJ,e,W,e,J"))]
2024 && (register_operand (operands[0], DImode)
2025 || register_or_zero_operand (operands[1], DImode))"
2028 sethi\t%%hi(%a1), %0
2035 [(set_attr "type" "*,*,load,store,fpmove,fpload,fpstore,fga")
2036 (set_attr "fptype" "*,*,*,*,double,*,*,double")])
2038 (define_expand "movdi_pic_label_ref"
2039 [(set (match_dup 3) (high:DI
2040 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
2041 (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
2042 (set (match_dup 4) (lo_sum:DI (match_dup 3)
2043 (unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
2044 (set (match_operand:DI 0 "register_operand" "=r")
2045 (minus:DI (match_dup 5) (match_dup 4)))]
2046 "TARGET_ARCH64 && flag_pic"
2048 crtl->uses_pic_offset_table = 1;
2049 operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
2050 if (!can_create_pseudo_p ())
2052 operands[3] = operands[0];
2053 operands[4] = operands[0];
2057 operands[3] = gen_reg_rtx (DImode);
2058 operands[4] = gen_reg_rtx (DImode);
2060 operands[5] = pic_offset_table_rtx;
2063 (define_insn "*movdi_high_pic_label_ref"
2064 [(set (match_operand:DI 0 "register_operand" "=r")
2066 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
2067 (match_operand:DI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
2068 "TARGET_ARCH64 && flag_pic"
2069 "sethi\t%%hi(%a2-(%a1-.)), %0")
2071 (define_insn "*movdi_lo_sum_pic_label_ref"
2072 [(set (match_operand:DI 0 "register_operand" "=r")
2073 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2074 (unspec:DI [(match_operand:DI 2 "label_ref_operand" "")
2075 (match_operand:DI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
2076 "TARGET_ARCH64 && flag_pic"
2077 "or\t%1, %%lo(%a3-(%a2-.)), %0")
2079 ;; SPARC-v9 code model support insns. See sparc_emit_set_symbolic_const64
2080 ;; in sparc.c to see what is going on here... PIC stuff comes first.
2082 (define_insn "movdi_lo_sum_pic"
2083 [(set (match_operand:DI 0 "register_operand" "=r")
2084 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2085 (unspec:DI [(match_operand:DI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
2086 "TARGET_ARCH64 && flag_pic"
2087 "or\t%1, %%lo(%a2), %0")
2089 (define_insn "movdi_high_pic"
2090 [(set (match_operand:DI 0 "register_operand" "=r")
2091 (high:DI (unspec:DI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
2092 "TARGET_ARCH64 && flag_pic && check_pic (1)"
2093 "sethi\t%%hi(%a1), %0")
2095 (define_insn "*sethi_di_medlow_embmedany_pic"
2096 [(set (match_operand:DI 0 "register_operand" "=r")
2097 (high:DI (match_operand:DI 1 "medium_pic_operand" "")))]
2098 "(TARGET_CM_MEDLOW || TARGET_CM_EMBMEDANY) && check_pic (1)"
2099 "sethi\t%%hi(%a1), %0")
2101 (define_insn "*sethi_di_medlow"
2102 [(set (match_operand:DI 0 "register_operand" "=r")
2103 (high:DI (match_operand:DI 1 "symbolic_operand" "")))]
2104 "TARGET_CM_MEDLOW && check_pic (1)"
2105 "sethi\t%%hi(%a1), %0")
2107 (define_insn "*losum_di_medlow"
2108 [(set (match_operand:DI 0 "register_operand" "=r")
2109 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2110 (match_operand:DI 2 "symbolic_operand" "")))]
2112 "or\t%1, %%lo(%a2), %0")
2114 (define_insn "seth44"
2115 [(set (match_operand:DI 0 "register_operand" "=r")
2116 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETH44)))]
2118 "sethi\t%%h44(%a1), %0")
2120 (define_insn "setm44"
2121 [(set (match_operand:DI 0 "register_operand" "=r")
2122 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2123 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_SETM44)))]
2125 "or\t%1, %%m44(%a2), %0")
2127 (define_insn "setl44"
2128 [(set (match_operand:DI 0 "register_operand" "=r")
2129 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2130 (match_operand:DI 2 "symbolic_operand" "")))]
2132 "or\t%1, %%l44(%a2), %0")
2134 (define_insn "sethh"
2135 [(set (match_operand:DI 0 "register_operand" "=r")
2136 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETHH)))]
2138 "sethi\t%%hh(%a1), %0")
2140 (define_insn "setlm"
2141 [(set (match_operand:DI 0 "register_operand" "=r")
2142 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETLM)))]
2144 "sethi\t%%lm(%a1), %0")
2146 (define_insn "sethm"
2147 [(set (match_operand:DI 0 "register_operand" "=r")
2148 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2149 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_EMB_SETHM)))]
2151 "or\t%1, %%hm(%a2), %0")
2153 (define_insn "setlo"
2154 [(set (match_operand:DI 0 "register_operand" "=r")
2155 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2156 (match_operand:DI 2 "symbolic_operand" "")))]
2158 "or\t%1, %%lo(%a2), %0")
2160 (define_insn "embmedany_sethi"
2161 [(set (match_operand:DI 0 "register_operand" "=r")
2162 (high:DI (unspec:DI [(match_operand:DI 1 "data_segment_operand" "")] UNSPEC_EMB_HISUM)))]
2163 "TARGET_CM_EMBMEDANY && check_pic (1)"
2164 "sethi\t%%hi(%a1), %0")
2166 (define_insn "embmedany_losum"
2167 [(set (match_operand:DI 0 "register_operand" "=r")
2168 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2169 (match_operand:DI 2 "data_segment_operand" "")))]
2170 "TARGET_CM_EMBMEDANY"
2171 "add\t%1, %%lo(%a2), %0")
2173 (define_insn "embmedany_brsum"
2174 [(set (match_operand:DI 0 "register_operand" "=r")
2175 (unspec:DI [(match_operand:DI 1 "register_operand" "r")] UNSPEC_EMB_HISUM))]
2176 "TARGET_CM_EMBMEDANY"
2179 (define_insn "embmedany_textuhi"
2180 [(set (match_operand:DI 0 "register_operand" "=r")
2181 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTUHI)))]
2182 "TARGET_CM_EMBMEDANY && check_pic (1)"
2183 "sethi\t%%uhi(%a1), %0")
2185 (define_insn "embmedany_texthi"
2186 [(set (match_operand:DI 0 "register_operand" "=r")
2187 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTHI)))]
2188 "TARGET_CM_EMBMEDANY && check_pic (1)"
2189 "sethi\t%%hi(%a1), %0")
2191 (define_insn "embmedany_textulo"
2192 [(set (match_operand:DI 0 "register_operand" "=r")
2193 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2194 (unspec:DI [(match_operand:DI 2 "text_segment_operand" "")] UNSPEC_EMB_TEXTULO)))]
2195 "TARGET_CM_EMBMEDANY"
2196 "or\t%1, %%ulo(%a2), %0")
2198 (define_insn "embmedany_textlo"
2199 [(set (match_operand:DI 0 "register_operand" "=r")
2200 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2201 (match_operand:DI 2 "text_segment_operand" "")))]
2202 "TARGET_CM_EMBMEDANY"
2203 "or\t%1, %%lo(%a2), %0")
2205 ;; Now some patterns to help reload out a bit.
2206 (define_expand "reload_indi"
2207 [(parallel [(match_operand:DI 0 "register_operand" "=r")
2208 (match_operand:DI 1 "immediate_operand" "")
2209 (match_operand:TI 2 "register_operand" "=&r")])]
2211 || TARGET_CM_EMBMEDANY)
2214 sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
2218 (define_expand "reload_outdi"
2219 [(parallel [(match_operand:DI 0 "register_operand" "=r")
2220 (match_operand:DI 1 "immediate_operand" "")
2221 (match_operand:TI 2 "register_operand" "=&r")])]
2223 || TARGET_CM_EMBMEDANY)
2226 sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
2230 ;; Split up putting CONSTs and REGs into DI regs when !arch64
2232 [(set (match_operand:DI 0 "register_operand" "")
2233 (match_operand:DI 1 "const_int_operand" ""))]
2234 "! TARGET_ARCH64 && reload_completed"
2235 [(clobber (const_int 0))]
2237 #if HOST_BITS_PER_WIDE_INT == 32
2238 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
2239 (INTVAL (operands[1]) < 0) ?
2242 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2245 unsigned int low, high;
2247 low = trunc_int_for_mode (INTVAL (operands[1]), SImode);
2248 high = trunc_int_for_mode (INTVAL (operands[1]) >> 32, SImode);
2249 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), GEN_INT (high)));
2251 /* Slick... but this trick loses if this subreg constant part
2252 can be done in one insn. */
2254 && ! SPARC_SETHI32_P (high)
2255 && ! SPARC_SIMM13_P (high))
2256 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2257 gen_highpart (SImode, operands[0])));
2259 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), GEN_INT (low)));
2265 [(set (match_operand:DI 0 "register_operand" "")
2266 (match_operand:DI 1 "const_double_operand" ""))]
2270 && ((GET_CODE (operands[0]) == REG
2271 && REGNO (operands[0]) < 32)
2272 || (GET_CODE (operands[0]) == SUBREG
2273 && GET_CODE (SUBREG_REG (operands[0])) == REG
2274 && REGNO (SUBREG_REG (operands[0])) < 32))))"
2275 [(clobber (const_int 0))]
2277 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
2278 GEN_INT (CONST_DOUBLE_HIGH (operands[1]))));
2280 /* Slick... but this trick loses if this subreg constant part
2281 can be done in one insn. */
2282 if (CONST_DOUBLE_LOW (operands[1]) == CONST_DOUBLE_HIGH (operands[1])
2283 && ! SPARC_SETHI32_P (CONST_DOUBLE_HIGH (operands[1]))
2284 && ! SPARC_SIMM13_P (CONST_DOUBLE_HIGH (operands[1])))
2286 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2287 gen_highpart (SImode, operands[0])));
2291 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2292 GEN_INT (CONST_DOUBLE_LOW (operands[1]))));
2298 [(set (match_operand:DI 0 "register_operand" "")
2299 (match_operand:DI 1 "register_operand" ""))]
2303 && ((GET_CODE (operands[0]) == REG
2304 && REGNO (operands[0]) < 32)
2305 || (GET_CODE (operands[0]) == SUBREG
2306 && GET_CODE (SUBREG_REG (operands[0])) == REG
2307 && REGNO (SUBREG_REG (operands[0])) < 32))))"
2308 [(clobber (const_int 0))]
2310 rtx set_dest = operands[0];
2311 rtx set_src = operands[1];
2315 dest1 = gen_highpart (SImode, set_dest);
2316 dest2 = gen_lowpart (SImode, set_dest);
2317 src1 = gen_highpart (SImode, set_src);
2318 src2 = gen_lowpart (SImode, set_src);
2320 /* Now emit using the real source and destination we found, swapping
2321 the order if we detect overlap. */
2322 if (reg_overlap_mentioned_p (dest1, src2))
2324 emit_insn (gen_movsi (dest2, src2));
2325 emit_insn (gen_movsi (dest1, src1));
2329 emit_insn (gen_movsi (dest1, src1));
2330 emit_insn (gen_movsi (dest2, src2));
2335 ;; Now handle the cases of memory moves from/to non-even
2336 ;; DI mode register pairs.
2338 [(set (match_operand:DI 0 "register_operand" "")
2339 (match_operand:DI 1 "memory_operand" ""))]
2342 && sparc_splitdi_legitimate (operands[0], operands[1]))"
2343 [(clobber (const_int 0))]
2345 rtx word0 = adjust_address (operands[1], SImode, 0);
2346 rtx word1 = adjust_address (operands[1], SImode, 4);
2347 rtx high_part = gen_highpart (SImode, operands[0]);
2348 rtx low_part = gen_lowpart (SImode, operands[0]);
2350 if (reg_overlap_mentioned_p (high_part, word1))
2352 emit_insn (gen_movsi (low_part, word1));
2353 emit_insn (gen_movsi (high_part, word0));
2357 emit_insn (gen_movsi (high_part, word0));
2358 emit_insn (gen_movsi (low_part, word1));
2364 [(set (match_operand:DI 0 "memory_operand" "")
2365 (match_operand:DI 1 "register_operand" ""))]
2368 && sparc_splitdi_legitimate (operands[1], operands[0]))"
2369 [(clobber (const_int 0))]
2371 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0),
2372 gen_highpart (SImode, operands[1])));
2373 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4),
2374 gen_lowpart (SImode, operands[1])));
2379 [(set (match_operand:DI 0 "memory_operand" "")
2380 (match_operand:DI 1 "const_zero_operand" ""))]
2384 && ! mem_min_alignment (operands[0], 8)))
2385 && offsettable_memref_p (operands[0])"
2386 [(clobber (const_int 0))]
2388 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0), const0_rtx));
2389 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4), const0_rtx));
2394 ;; Floating point and vector move instructions
2396 ;; We don't define V1SI because SI should work just fine.
2397 (define_mode_iterator V32 [SF V2HI V4QI])
2399 ;; Yes, you guessed it right, the former movsf expander.
2400 (define_expand "mov<V32:mode>"
2401 [(set (match_operand:V32 0 "nonimmediate_operand" "")
2402 (match_operand:V32 1 "general_operand" ""))]
2403 "<V32:MODE>mode == SFmode || TARGET_VIS"
2405 if (sparc_expand_move (<V32:MODE>mode, operands))
2409 (define_insn "*movsf_insn"
2410 [(set (match_operand:V32 0 "nonimmediate_operand" "=d,f,*r,*r,*r,f,*r,m,m")
2411 (match_operand:V32 1 "input_operand" "GY,f,*rRY,Q,S,m,m,f,*rGY"))]
2413 && (register_operand (operands[0], <V32:MODE>mode)
2414 || register_or_zero_operand (operands[1], <V32:MODE>mode))"
2416 if (GET_CODE (operands[1]) == CONST_DOUBLE
2417 && (which_alternative == 2
2418 || which_alternative == 3
2419 || which_alternative == 4))
2424 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2425 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2426 operands[1] = GEN_INT (i);
2429 switch (which_alternative)
2432 return "fzeros\t%0";
2434 return "fmovs\t%1, %0";
2436 return "mov\t%1, %0";
2438 return "sethi\t%%hi(%a1), %0";
2443 return "ld\t%1, %0";
2446 return "st\t%r1, %0";
2451 [(set_attr "type" "fga,fpmove,*,*,*,fpload,load,fpstore,store")])
2453 ;; Exactly the same as above, except that all `f' cases are deleted.
2454 ;; This is necessary to prevent reload from ever trying to use a `f' reg
2457 (define_insn "*movsf_insn_no_fpu"
2458 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r,r,m")
2459 (match_operand:SF 1 "input_operand" "rR,Q,S,m,rG"))]
2461 && (register_operand (operands[0], SFmode)
2462 || register_or_zero_operand (operands[1], SFmode))"
2464 if (GET_CODE (operands[1]) == CONST_DOUBLE
2465 && (which_alternative == 0
2466 || which_alternative == 1
2467 || which_alternative == 2))
2472 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2473 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2474 operands[1] = GEN_INT (i);
2477 switch (which_alternative)
2480 return "mov\t%1, %0";
2482 return "sethi\t%%hi(%a1), %0";
2486 return "ld\t%1, %0";
2488 return "st\t%r1, %0";
2493 [(set_attr "type" "*,*,*,load,store")])
2495 ;; The following 3 patterns build SFmode constants in integer registers.
2497 (define_insn "*movsf_lo_sum"
2498 [(set (match_operand:SF 0 "register_operand" "=r")
2499 (lo_sum:SF (match_operand:SF 1 "register_operand" "r")
2500 (match_operand:SF 2 "fp_const_high_losum_operand" "S")))]
2506 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[2]);
2507 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2508 operands[2] = GEN_INT (i);
2509 return "or\t%1, %%lo(%a2), %0";
2512 (define_insn "*movsf_high"
2513 [(set (match_operand:SF 0 "register_operand" "=r")
2514 (high:SF (match_operand:SF 1 "fp_const_high_losum_operand" "S")))]
2520 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2521 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2522 operands[1] = GEN_INT (i);
2523 return "sethi\t%%hi(%1), %0";
2527 [(set (match_operand:SF 0 "register_operand" "")
2528 (match_operand:SF 1 "fp_const_high_losum_operand" ""))]
2529 "REG_P (operands[0]) && REGNO (operands[0]) < 32"
2530 [(set (match_dup 0) (high:SF (match_dup 1)))
2531 (set (match_dup 0) (lo_sum:SF (match_dup 0) (match_dup 1)))])
2533 (define_mode_iterator V64 [DF V2SI V4HI V8QI])
2535 ;; Yes, you again guessed it right, the former movdf expander.
2536 (define_expand "mov<V64:mode>"
2537 [(set (match_operand:V64 0 "nonimmediate_operand" "")
2538 (match_operand:V64 1 "general_operand" ""))]
2539 "<V64:MODE>mode == DFmode || TARGET_VIS"
2541 if (sparc_expand_move (<V64:MODE>mode, operands))
2545 ;; Be careful, fmovd does not exist when !v9.
2546 (define_insn "*movdf_insn_sp32"
2547 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,W,U,T,o,e,*r,o,e,o")
2548 (match_operand:DF 1 "input_operand" "W#F,e,T,U,G,e,*rFo,*r,o#F,e"))]
2551 && (register_operand (operands[0], DFmode)
2552 || register_or_zero_operand (operands[1], DFmode))"
2564 [(set_attr "type" "fpload,fpstore,load,store,*,*,*,*,*,*")
2565 (set_attr "length" "*,*,*,*,2,2,2,2,2,2")])
2567 (define_insn "*movdf_insn_sp32_no_fpu"
2568 [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,o,r,o")
2569 (match_operand:DF 1 "input_operand" "T,U,G,ro,r"))]
2572 && (register_operand (operands[0], DFmode)
2573 || register_or_zero_operand (operands[1], DFmode))"
2580 [(set_attr "type" "load,store,*,*,*")
2581 (set_attr "length" "*,*,2,2,2")])
2583 ;; We have available v9 double floats but not 64-bit integer registers.
2584 (define_insn "*movdf_insn_sp32_v9"
2585 [(set (match_operand:V64 0 "nonimmediate_operand" "=b,e,e,T,W,U,T,f,*r,o")
2586 (match_operand:V64 1 "input_operand" "GY,e,W#F,GY,e,T,U,o#F,*roGYDF,*rGYf"))]
2590 && (register_operand (operands[0], <V64:MODE>mode)
2591 || register_or_zero_operand (operands[1], <V64:MODE>mode))"
2603 [(set_attr "type" "fga,fpmove,load,store,store,load,store,*,*,*")
2604 (set_attr "length" "*,*,*,*,*,*,*,2,2,2")
2605 (set_attr "fptype" "double,double,*,*,*,*,*,*,*,*")])
2607 (define_insn "*movdf_insn_sp32_v9_no_fpu"
2608 [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,T,r,o")
2609 (match_operand:DF 1 "input_operand" "T,U,G,ro,rG"))]
2613 && (register_operand (operands[0], DFmode)
2614 || register_or_zero_operand (operands[1], DFmode))"
2621 [(set_attr "type" "load,store,store,*,*")
2622 (set_attr "length" "*,*,*,2,2")])
2624 ;; We have available both v9 double floats and 64-bit integer registers.
2625 (define_insn "*movdf_insn_sp64"
2626 [(set (match_operand:V64 0 "nonimmediate_operand" "=b,e,e,W,*r,*r,m,*r")
2627 (match_operand:V64 1 "input_operand" "GY,e,W#F,e,*rGY,m,*rGY,DF"))]
2630 && (register_operand (operands[0], <V64:MODE>mode)
2631 || register_or_zero_operand (operands[1], <V64:MODE>mode))"
2641 [(set_attr "type" "fga,fpmove,load,store,*,load,store,*")
2642 (set_attr "length" "*,*,*,*,*,*,*,2")
2643 (set_attr "fptype" "double,double,*,*,*,*,*,*")])
2645 (define_insn "*movdf_insn_sp64_no_fpu"
2646 [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m")
2647 (match_operand:DF 1 "input_operand" "r,m,rG"))]
2650 && (register_operand (operands[0], DFmode)
2651 || register_or_zero_operand (operands[1], DFmode))"
2656 [(set_attr "type" "*,load,store")])
2658 ;; This pattern builds V64mode constants in integer registers.
2660 [(set (match_operand:V64 0 "register_operand" "")
2661 (match_operand:V64 1 "const_double_or_vector_operand" ""))]
2663 && (GET_CODE (operands[0]) == REG
2664 && REGNO (operands[0]) < 32)
2665 && ! const_zero_operand (operands[1], GET_MODE (operands[0]))
2666 && reload_completed"
2667 [(clobber (const_int 0))]
2669 operands[0] = gen_rtx_raw_REG (DImode, REGNO (operands[0]));
2673 #if HOST_BITS_PER_WIDE_INT == 32
2676 enum machine_mode mode = GET_MODE (operands[1]);
2677 rtx tem = simplify_subreg (DImode, operands[1], mode, 0);
2678 emit_insn (gen_movdi (operands[0], tem));
2683 enum machine_mode mode = GET_MODE (operands[1]);
2684 rtx hi = simplify_subreg (SImode, operands[1], mode, 0);
2685 rtx lo = simplify_subreg (SImode, operands[1], mode, 4);
2687 gcc_assert (GET_CODE (hi) == CONST_INT);
2688 gcc_assert (GET_CODE (lo) == CONST_INT);
2690 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), hi));
2692 /* Slick... but this trick loses if this subreg constant part
2693 can be done in one insn. */
2695 && ! SPARC_SETHI32_P (INTVAL (hi))
2696 && ! SPARC_SIMM13_P (INTVAL (hi)))
2698 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2699 gen_highpart (SImode, operands[0])));
2703 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), lo));
2709 ;; Ok, now the splits to handle all the multi insn and
2710 ;; mis-aligned memory address cases.
2711 ;; In these splits please take note that we must be
2712 ;; careful when V9 but not ARCH64 because the integer
2713 ;; register DFmode cases must be handled.
2715 [(set (match_operand:V64 0 "register_operand" "")
2716 (match_operand:V64 1 "register_operand" ""))]
2719 && ((GET_CODE (operands[0]) == REG
2720 && REGNO (operands[0]) < 32)
2721 || (GET_CODE (operands[0]) == SUBREG
2722 && GET_CODE (SUBREG_REG (operands[0])) == REG
2723 && REGNO (SUBREG_REG (operands[0])) < 32))))
2724 && reload_completed"
2725 [(clobber (const_int 0))]
2727 rtx set_dest = operands[0];
2728 rtx set_src = operands[1];
2731 enum machine_mode half_mode;
2733 /* We can be expanded for DFmode or integral vector modes. */
2734 if (<V64:MODE>mode == DFmode)
2739 dest1 = gen_highpart (half_mode, set_dest);
2740 dest2 = gen_lowpart (half_mode, set_dest);
2741 src1 = gen_highpart (half_mode, set_src);
2742 src2 = gen_lowpart (half_mode, set_src);
2744 /* Now emit using the real source and destination we found, swapping
2745 the order if we detect overlap. */
2746 if (reg_overlap_mentioned_p (dest1, src2))
2748 emit_move_insn_1 (dest2, src2);
2749 emit_move_insn_1 (dest1, src1);
2753 emit_move_insn_1 (dest1, src1);
2754 emit_move_insn_1 (dest2, src2);
2760 [(set (match_operand:V64 0 "register_operand" "")
2761 (match_operand:V64 1 "memory_operand" ""))]
2764 && (((REGNO (operands[0]) % 2) != 0)
2765 || ! mem_min_alignment (operands[1], 8))
2766 && offsettable_memref_p (operands[1])"
2767 [(clobber (const_int 0))]
2769 enum machine_mode half_mode;
2772 /* We can be expanded for DFmode or integral vector modes. */
2773 if (<V64:MODE>mode == DFmode)
2778 word0 = adjust_address (operands[1], half_mode, 0);
2779 word1 = adjust_address (operands[1], half_mode, 4);
2781 if (reg_overlap_mentioned_p (gen_highpart (half_mode, operands[0]), word1))
2783 emit_move_insn_1 (gen_lowpart (half_mode, operands[0]), word1);
2784 emit_move_insn_1 (gen_highpart (half_mode, operands[0]), word0);
2788 emit_move_insn_1 (gen_highpart (half_mode, operands[0]), word0);
2789 emit_move_insn_1 (gen_lowpart (half_mode, operands[0]), word1);
2795 [(set (match_operand:V64 0 "memory_operand" "")
2796 (match_operand:V64 1 "register_operand" ""))]
2799 && (((REGNO (operands[1]) % 2) != 0)
2800 || ! mem_min_alignment (operands[0], 8))
2801 && offsettable_memref_p (operands[0])"
2802 [(clobber (const_int 0))]
2804 enum machine_mode half_mode;
2807 /* We can be expanded for DFmode or integral vector modes. */
2808 if (<V64:MODE>mode == DFmode)
2813 word0 = adjust_address (operands[0], half_mode, 0);
2814 word1 = adjust_address (operands[0], half_mode, 4);
2816 emit_move_insn_1 (word0, gen_highpart (half_mode, operands[1]));
2817 emit_move_insn_1 (word1, gen_lowpart (half_mode, operands[1]));
2822 [(set (match_operand:V64 0 "memory_operand" "")
2823 (match_operand:V64 1 "const_zero_operand" ""))]
2827 && ! mem_min_alignment (operands[0], 8)))
2828 && offsettable_memref_p (operands[0])"
2829 [(clobber (const_int 0))]
2831 enum machine_mode half_mode;
2834 /* We can be expanded for DFmode or integral vector modes. */
2835 if (<V64:MODE>mode == DFmode)
2840 dest1 = adjust_address (operands[0], half_mode, 0);
2841 dest2 = adjust_address (operands[0], half_mode, 4);
2843 emit_move_insn_1 (dest1, CONST0_RTX (half_mode));
2844 emit_move_insn_1 (dest2, CONST0_RTX (half_mode));
2849 [(set (match_operand:V64 0 "register_operand" "")
2850 (match_operand:V64 1 "const_zero_operand" ""))]
2853 && ((GET_CODE (operands[0]) == REG
2854 && REGNO (operands[0]) < 32)
2855 || (GET_CODE (operands[0]) == SUBREG
2856 && GET_CODE (SUBREG_REG (operands[0])) == REG
2857 && REGNO (SUBREG_REG (operands[0])) < 32))"
2858 [(clobber (const_int 0))]
2860 enum machine_mode half_mode;
2861 rtx set_dest = operands[0];
2864 /* We can be expanded for DFmode or integral vector modes. */
2865 if (<V64:MODE>mode == DFmode)
2870 dest1 = gen_highpart (half_mode, set_dest);
2871 dest2 = gen_lowpart (half_mode, set_dest);
2872 emit_move_insn_1 (dest1, CONST0_RTX (half_mode));
2873 emit_move_insn_1 (dest2, CONST0_RTX (half_mode));
2877 (define_expand "movtf"
2878 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2879 (match_operand:TF 1 "general_operand" ""))]
2882 if (sparc_expand_move (TFmode, operands))
2886 (define_insn "*movtf_insn_sp32"
2887 [(set (match_operand:TF 0 "nonimmediate_operand" "=b,e,o,U,r")
2888 (match_operand:TF 1 "input_operand" "G,oe,GeUr,o,roG"))]
2891 && (register_operand (operands[0], TFmode)
2892 || register_or_zero_operand (operands[1], TFmode))"
2894 [(set_attr "length" "4")])
2896 ;; Exactly the same as above, except that all `e' cases are deleted.
2897 ;; This is necessary to prevent reload from ever trying to use a `e' reg
2900 (define_insn "*movtf_insn_sp32_no_fpu"
2901 [(set (match_operand:TF 0 "nonimmediate_operand" "=o,U,o,r,o")
2902 (match_operand:TF 1 "input_operand" "G,o,U,roG,r"))]
2905 && (register_operand (operands[0], TFmode)
2906 || register_or_zero_operand (operands[1], TFmode))"
2908 [(set_attr "length" "4")])
2910 (define_insn "*movtf_insn_sp64"
2911 [(set (match_operand:TF 0 "nonimmediate_operand" "=b,e,o,r")
2912 (match_operand:TF 1 "input_operand" "G,oe,Ger,roG"))]
2915 && ! TARGET_HARD_QUAD
2916 && (register_operand (operands[0], TFmode)
2917 || register_or_zero_operand (operands[1], TFmode))"
2919 [(set_attr "length" "2")])
2921 (define_insn "*movtf_insn_sp64_hq"
2922 [(set (match_operand:TF 0 "nonimmediate_operand" "=b,e,e,m,o,r")
2923 (match_operand:TF 1 "input_operand" "G,e,m,e,rG,roG"))]
2927 && (register_operand (operands[0], TFmode)
2928 || register_or_zero_operand (operands[1], TFmode))"
2936 [(set_attr "type" "*,fpmove,fpload,fpstore,*,*")
2937 (set_attr "length" "2,*,*,*,2,2")])
2939 (define_insn "*movtf_insn_sp64_no_fpu"
2940 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o")
2941 (match_operand:TF 1 "input_operand" "orG,rG"))]
2944 && (register_operand (operands[0], TFmode)
2945 || register_or_zero_operand (operands[1], TFmode))"
2947 [(set_attr "length" "2")])
2949 ;; Now all the splits to handle multi-insn TF mode moves.
2951 [(set (match_operand:TF 0 "register_operand" "")
2952 (match_operand:TF 1 "register_operand" ""))]
2956 && ! TARGET_HARD_QUAD)
2957 || ! fp_register_operand (operands[0], TFmode))"
2958 [(clobber (const_int 0))]
2960 rtx set_dest = operands[0];
2961 rtx set_src = operands[1];
2965 dest1 = gen_df_reg (set_dest, 0);
2966 dest2 = gen_df_reg (set_dest, 1);
2967 src1 = gen_df_reg (set_src, 0);
2968 src2 = gen_df_reg (set_src, 1);
2970 /* Now emit using the real source and destination we found, swapping
2971 the order if we detect overlap. */
2972 if (reg_overlap_mentioned_p (dest1, src2))
2974 emit_insn (gen_movdf (dest2, src2));
2975 emit_insn (gen_movdf (dest1, src1));
2979 emit_insn (gen_movdf (dest1, src1));
2980 emit_insn (gen_movdf (dest2, src2));
2986 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2987 (match_operand:TF 1 "const_zero_operand" ""))]
2989 [(clobber (const_int 0))]
2991 rtx set_dest = operands[0];
2994 switch (GET_CODE (set_dest))
2997 dest1 = gen_df_reg (set_dest, 0);
2998 dest2 = gen_df_reg (set_dest, 1);
3001 dest1 = adjust_address (set_dest, DFmode, 0);
3002 dest2 = adjust_address (set_dest, DFmode, 8);
3008 emit_insn (gen_movdf (dest1, CONST0_RTX (DFmode)));
3009 emit_insn (gen_movdf (dest2, CONST0_RTX (DFmode)));
3014 [(set (match_operand:TF 0 "register_operand" "")
3015 (match_operand:TF 1 "memory_operand" ""))]
3017 && offsettable_memref_p (operands[1])
3019 || ! TARGET_HARD_QUAD
3020 || ! fp_register_operand (operands[0], TFmode)))"
3021 [(clobber (const_int 0))]
3023 rtx word0 = adjust_address (operands[1], DFmode, 0);
3024 rtx word1 = adjust_address (operands[1], DFmode, 8);
3025 rtx set_dest, dest1, dest2;
3027 set_dest = operands[0];
3029 dest1 = gen_df_reg (set_dest, 0);
3030 dest2 = gen_df_reg (set_dest, 1);
3032 /* Now output, ordering such that we don't clobber any registers
3033 mentioned in the address. */
3034 if (reg_overlap_mentioned_p (dest1, word1))
3037 emit_insn (gen_movdf (dest2, word1));
3038 emit_insn (gen_movdf (dest1, word0));
3042 emit_insn (gen_movdf (dest1, word0));
3043 emit_insn (gen_movdf (dest2, word1));
3049 [(set (match_operand:TF 0 "memory_operand" "")
3050 (match_operand:TF 1 "register_operand" ""))]
3052 && offsettable_memref_p (operands[0])
3054 || ! TARGET_HARD_QUAD
3055 || ! fp_register_operand (operands[1], TFmode)))"
3056 [(clobber (const_int 0))]
3058 rtx set_src = operands[1];
3060 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 0),
3061 gen_df_reg (set_src, 0)));
3062 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 8),
3063 gen_df_reg (set_src, 1)));
3068 ;; SPARC-V9 conditional move instructions
3070 ;; We can handle larger constants here for some flavors, but for now we keep
3071 ;; it simple and only allow those constants supported by all flavors.
3072 ;; Note that emit_conditional_move canonicalizes operands 2,3 so that operand
3073 ;; 3 contains the constant if one is present, but we handle either for
3074 ;; generality (sparc.c puts a constant in operand 2).
3076 (define_mode_iterator I [QI HI SI DI])
3078 (define_expand "mov<I:mode>cc"
3079 [(set (match_operand:I 0 "register_operand" "")
3080 (if_then_else:I (match_operand 1 "comparison_operator" "")
3081 (match_operand:I 2 "arith10_operand" "")
3082 (match_operand:I 3 "arith10_operand" "")))]
3083 "TARGET_V9 && !(<I:MODE>mode == DImode && TARGET_ARCH32)"
3085 enum rtx_code code = GET_CODE (operands[1]);
3087 if (GET_MODE (sparc_compare_op0) == DImode
3091 if (sparc_compare_op1 == const0_rtx
3092 && GET_CODE (sparc_compare_op0) == REG
3093 && GET_MODE (sparc_compare_op0) == DImode
3094 && v9_regcmp_p (code))
3095 operands[1] = gen_rtx_fmt_ee (code, DImode, sparc_compare_op0, const0_rtx);
3097 operands[1] = gen_compare_operator (code);
3100 (define_mode_iterator F [SF DF TF])
3102 (define_expand "mov<F:mode>cc"
3103 [(set (match_operand:F 0 "register_operand" "")
3104 (if_then_else:F (match_operand 1 "comparison_operator" "")
3105 (match_operand:F 2 "register_operand" "")
3106 (match_operand:F 3 "register_operand" "")))]
3107 "TARGET_V9 && TARGET_FPU"
3109 enum rtx_code code = GET_CODE (operands[1]);
3111 if (GET_MODE (sparc_compare_op0) == DImode
3115 if (sparc_compare_op1 == const0_rtx
3116 && GET_CODE (sparc_compare_op0) == REG
3117 && GET_MODE (sparc_compare_op0) == DImode
3118 && v9_regcmp_p (code))
3119 operands[1] = gen_rtx_fmt_ee (code, DImode, sparc_compare_op0, const0_rtx);
3121 operands[1] = gen_compare_operator (code);
3124 ;; Conditional move define_insns
3126 (define_insn "*mov<I:mode>_cc_v9"
3127 [(set (match_operand:I 0 "register_operand" "=r,r")
3128 (if_then_else:I (match_operator 1 "comparison_operator"
3129 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
3131 (match_operand:I 3 "arith11_operand" "rL,0")
3132 (match_operand:I 4 "arith11_operand" "0,rL")))]
3133 "TARGET_V9 && !(<I:MODE>mode == DImode && TARGET_ARCH32)"
3136 mov%c1\t%x2, %4, %0"
3137 [(set_attr "type" "cmove")])
3139 (define_insn "*mov<I:mode>_cc_reg_sp64"
3140 [(set (match_operand:I 0 "register_operand" "=r,r")
3141 (if_then_else:I (match_operator 1 "v9_register_compare_operator"
3142 [(match_operand:DI 2 "register_operand" "r,r")
3144 (match_operand:I 3 "arith10_operand" "rM,0")
3145 (match_operand:I 4 "arith10_operand" "0,rM")))]
3148 movr%D1\t%2, %r3, %0
3149 movr%d1\t%2, %r4, %0"
3150 [(set_attr "type" "cmove")])
3152 (define_insn "*movsf_cc_v9"
3153 [(set (match_operand:SF 0 "register_operand" "=f,f")
3154 (if_then_else:SF (match_operator 1 "comparison_operator"
3155 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
3157 (match_operand:SF 3 "register_operand" "f,0")
3158 (match_operand:SF 4 "register_operand" "0,f")))]
3159 "TARGET_V9 && TARGET_FPU"
3161 fmovs%C1\t%x2, %3, %0
3162 fmovs%c1\t%x2, %4, %0"
3163 [(set_attr "type" "fpcmove")])
3165 (define_insn "*movsf_cc_reg_sp64"
3166 [(set (match_operand:SF 0 "register_operand" "=f,f")
3167 (if_then_else:SF (match_operator 1 "v9_register_compare_operator"
3168 [(match_operand:DI 2 "register_operand" "r,r")
3170 (match_operand:SF 3 "register_operand" "f,0")
3171 (match_operand:SF 4 "register_operand" "0,f")))]
3172 "TARGET_ARCH64 && TARGET_FPU"
3174 fmovrs%D1\t%2, %3, %0
3175 fmovrs%d1\t%2, %4, %0"
3176 [(set_attr "type" "fpcrmove")])
3178 ;; Named because invoked by movtf_cc_v9
3179 (define_insn "movdf_cc_v9"
3180 [(set (match_operand:DF 0 "register_operand" "=e,e")
3181 (if_then_else:DF (match_operator 1 "comparison_operator"
3182 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
3184 (match_operand:DF 3 "register_operand" "e,0")
3185 (match_operand:DF 4 "register_operand" "0,e")))]
3186 "TARGET_V9 && TARGET_FPU"
3188 fmovd%C1\t%x2, %3, %0
3189 fmovd%c1\t%x2, %4, %0"
3190 [(set_attr "type" "fpcmove")
3191 (set_attr "fptype" "double")])
3193 ;; Named because invoked by movtf_cc_reg_sp64
3194 (define_insn "movdf_cc_reg_sp64"
3195 [(set (match_operand:DF 0 "register_operand" "=e,e")
3196 (if_then_else:DF (match_operator 1 "v9_register_compare_operator"
3197 [(match_operand:DI 2 "register_operand" "r,r")
3199 (match_operand:DF 3 "register_operand" "e,0")
3200 (match_operand:DF 4 "register_operand" "0,e")))]
3201 "TARGET_ARCH64 && TARGET_FPU"
3203 fmovrd%D1\t%2, %3, %0
3204 fmovrd%d1\t%2, %4, %0"
3205 [(set_attr "type" "fpcrmove")
3206 (set_attr "fptype" "double")])
3208 (define_insn "*movtf_cc_hq_v9"
3209 [(set (match_operand:TF 0 "register_operand" "=e,e")
3210 (if_then_else:TF (match_operator 1 "comparison_operator"
3211 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
3213 (match_operand:TF 3 "register_operand" "e,0")
3214 (match_operand:TF 4 "register_operand" "0,e")))]
3215 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
3217 fmovq%C1\t%x2, %3, %0
3218 fmovq%c1\t%x2, %4, %0"
3219 [(set_attr "type" "fpcmove")])
3221 (define_insn "*movtf_cc_reg_hq_sp64"
3222 [(set (match_operand:TF 0 "register_operand" "=e,e")
3223 (if_then_else:TF (match_operator 1 "v9_register_compare_operator"
3224 [(match_operand:DI 2 "register_operand" "r,r")
3226 (match_operand:TF 3 "register_operand" "e,0")
3227 (match_operand:TF 4 "register_operand" "0,e")))]
3228 "TARGET_ARCH64 && TARGET_FPU && TARGET_HARD_QUAD"
3230 fmovrq%D1\t%2, %3, %0
3231 fmovrq%d1\t%2, %4, %0"
3232 [(set_attr "type" "fpcrmove")])
3234 (define_insn_and_split "*movtf_cc_v9"
3235 [(set (match_operand:TF 0 "register_operand" "=e,e")
3236 (if_then_else:TF (match_operator 1 "comparison_operator"
3237 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
3239 (match_operand:TF 3 "register_operand" "e,0")
3240 (match_operand:TF 4 "register_operand" "0,e")))]
3241 "TARGET_V9 && TARGET_FPU && !TARGET_HARD_QUAD"
3243 "&& reload_completed"
3244 [(clobber (const_int 0))]
3246 rtx set_dest = operands[0];
3247 rtx set_srca = operands[3];
3248 rtx set_srcb = operands[4];
3249 int third = rtx_equal_p (set_dest, set_srca);
3251 rtx srca1, srca2, srcb1, srcb2;
3253 dest1 = gen_df_reg (set_dest, 0);
3254 dest2 = gen_df_reg (set_dest, 1);
3255 srca1 = gen_df_reg (set_srca, 0);
3256 srca2 = gen_df_reg (set_srca, 1);
3257 srcb1 = gen_df_reg (set_srcb, 0);
3258 srcb2 = gen_df_reg (set_srcb, 1);
3260 /* Now emit using the real source and destination we found, swapping
3261 the order if we detect overlap. */
3262 if ((third && reg_overlap_mentioned_p (dest1, srcb2))
3263 || (!third && reg_overlap_mentioned_p (dest1, srca2)))
3265 emit_insn (gen_movdf_cc_v9 (dest2, operands[1], operands[2], srca2, srcb2));
3266 emit_insn (gen_movdf_cc_v9 (dest1, operands[1], operands[2], srca1, srcb1));
3270 emit_insn (gen_movdf_cc_v9 (dest1, operands[1], operands[2], srca1, srcb1));
3271 emit_insn (gen_movdf_cc_v9 (dest2, operands[1], operands[2], srca2, srcb2));
3275 [(set_attr "length" "2")])
3277 (define_insn_and_split "*movtf_cc_reg_sp64"
3278 [(set (match_operand:TF 0 "register_operand" "=e,e")
3279 (if_then_else:TF (match_operator 1 "v9_register_compare_operator"
3280 [(match_operand:DI 2 "register_operand" "r,r")
3282 (match_operand:TF 3 "register_operand" "e,0")
3283 (match_operand:TF 4 "register_operand" "0,e")))]
3284 "TARGET_ARCH64 && TARGET_FPU && ! TARGET_HARD_QUAD"
3286 "&& reload_completed"
3287 [(clobber (const_int 0))]
3289 rtx set_dest = operands[0];
3290 rtx set_srca = operands[3];
3291 rtx set_srcb = operands[4];
3292 int third = rtx_equal_p (set_dest, set_srca);
3294 rtx srca1, srca2, srcb1, srcb2;
3296 dest1 = gen_df_reg (set_dest, 0);
3297 dest2 = gen_df_reg (set_dest, 1);
3298 srca1 = gen_df_reg (set_srca, 0);
3299 srca2 = gen_df_reg (set_srca, 1);
3300 srcb1 = gen_df_reg (set_srcb, 0);
3301 srcb2 = gen_df_reg (set_srcb, 1);
3303 /* Now emit using the real source and destination we found, swapping
3304 the order if we detect overlap. */
3305 if ((third && reg_overlap_mentioned_p (dest1, srcb2))
3306 || (!third && reg_overlap_mentioned_p (dest1, srca2)))
3308 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
3309 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
3313 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
3314 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
3318 [(set_attr "length" "2")])
3321 ;; Zero-extension instructions
3323 ;; These patterns originally accepted general_operands, however, slightly
3324 ;; better code is generated by only accepting register_operands, and then
3325 ;; letting combine generate the ldu[hb] insns.
3327 (define_expand "zero_extendhisi2"
3328 [(set (match_operand:SI 0 "register_operand" "")
3329 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
3332 rtx temp = gen_reg_rtx (SImode);
3333 rtx shift_16 = GEN_INT (16);
3334 int op1_subbyte = 0;
3336 if (GET_CODE (operand1) == SUBREG)
3338 op1_subbyte = SUBREG_BYTE (operand1);
3339 op1_subbyte /= GET_MODE_SIZE (SImode);
3340 op1_subbyte *= GET_MODE_SIZE (SImode);
3341 operand1 = XEXP (operand1, 0);
3344 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3346 emit_insn (gen_lshrsi3 (operand0, temp, shift_16));
3350 (define_insn "*zero_extendhisi2_insn"
3351 [(set (match_operand:SI 0 "register_operand" "=r")
3352 (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
3355 [(set_attr "type" "load")
3356 (set_attr "us3load_type" "3cycle")])
3358 (define_expand "zero_extendqihi2"
3359 [(set (match_operand:HI 0 "register_operand" "")
3360 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
3364 (define_insn "*zero_extendqihi2_insn"
3365 [(set (match_operand:HI 0 "register_operand" "=r,r")
3366 (zero_extend:HI (match_operand:QI 1 "input_operand" "r,m")))]
3367 "GET_CODE (operands[1]) != CONST_INT"
3371 [(set_attr "type" "*,load")
3372 (set_attr "us3load_type" "*,3cycle")])
3374 (define_expand "zero_extendqisi2"
3375 [(set (match_operand:SI 0 "register_operand" "")
3376 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
3380 (define_insn "*zero_extendqisi2_insn"
3381 [(set (match_operand:SI 0 "register_operand" "=r,r")
3382 (zero_extend:SI (match_operand:QI 1 "input_operand" "r,m")))]
3383 "GET_CODE (operands[1]) != CONST_INT"
3387 [(set_attr "type" "*,load")
3388 (set_attr "us3load_type" "*,3cycle")])
3390 (define_expand "zero_extendqidi2"
3391 [(set (match_operand:DI 0 "register_operand" "")
3392 (zero_extend:DI (match_operand:QI 1 "register_operand" "")))]
3396 (define_insn "*zero_extendqidi2_insn"
3397 [(set (match_operand:DI 0 "register_operand" "=r,r")
3398 (zero_extend:DI (match_operand:QI 1 "input_operand" "r,m")))]
3399 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
3403 [(set_attr "type" "*,load")
3404 (set_attr "us3load_type" "*,3cycle")])
3406 (define_expand "zero_extendhidi2"
3407 [(set (match_operand:DI 0 "register_operand" "")
3408 (zero_extend:DI (match_operand:HI 1 "register_operand" "")))]
3411 rtx temp = gen_reg_rtx (DImode);
3412 rtx shift_48 = GEN_INT (48);
3413 int op1_subbyte = 0;
3415 if (GET_CODE (operand1) == SUBREG)
3417 op1_subbyte = SUBREG_BYTE (operand1);
3418 op1_subbyte /= GET_MODE_SIZE (DImode);
3419 op1_subbyte *= GET_MODE_SIZE (DImode);
3420 operand1 = XEXP (operand1, 0);
3423 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
3425 emit_insn (gen_lshrdi3 (operand0, temp, shift_48));
3429 (define_insn "*zero_extendhidi2_insn"
3430 [(set (match_operand:DI 0 "register_operand" "=r")
3431 (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
3434 [(set_attr "type" "load")
3435 (set_attr "us3load_type" "3cycle")])
3437 ;; ??? Write truncdisi pattern using sra?
3439 (define_expand "zero_extendsidi2"
3440 [(set (match_operand:DI 0 "register_operand" "")
3441 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
3445 (define_insn "*zero_extendsidi2_insn_sp64"
3446 [(set (match_operand:DI 0 "register_operand" "=r,r")
3447 (zero_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
3448 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
3452 [(set_attr "type" "shift,load")])
3454 (define_insn_and_split "*zero_extendsidi2_insn_sp32"
3455 [(set (match_operand:DI 0 "register_operand" "=r")
3456 (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
3459 "&& reload_completed"
3460 [(set (match_dup 2) (match_dup 3))
3461 (set (match_dup 4) (match_dup 5))]
3465 dest1 = gen_highpart (SImode, operands[0]);
3466 dest2 = gen_lowpart (SImode, operands[0]);
3468 /* Swap the order in case of overlap. */
3469 if (REGNO (dest1) == REGNO (operands[1]))
3471 operands[2] = dest2;
3472 operands[3] = operands[1];
3473 operands[4] = dest1;
3474 operands[5] = const0_rtx;
3478 operands[2] = dest1;
3479 operands[3] = const0_rtx;
3480 operands[4] = dest2;
3481 operands[5] = operands[1];
3484 [(set_attr "length" "2")])
3486 ;; Simplify comparisons of extended values.
3488 (define_insn "*cmp_zero_extendqisi2"
3490 (compare:CC (zero_extend:SI (match_operand:QI 0 "register_operand" "r"))
3493 "andcc\t%0, 0xff, %%g0"
3494 [(set_attr "type" "compare")])
3496 (define_insn "*cmp_zero_qi"
3498 (compare:CC (match_operand:QI 0 "register_operand" "r")
3501 "andcc\t%0, 0xff, %%g0"
3502 [(set_attr "type" "compare")])
3504 (define_insn "*cmp_zero_extendqisi2_set"
3506 (compare:CC (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
3508 (set (match_operand:SI 0 "register_operand" "=r")
3509 (zero_extend:SI (match_dup 1)))]
3511 "andcc\t%1, 0xff, %0"
3512 [(set_attr "type" "compare")])
3514 (define_insn "*cmp_zero_extendqisi2_andcc_set"
3516 (compare:CC (and:SI (match_operand:SI 1 "register_operand" "r")
3519 (set (match_operand:SI 0 "register_operand" "=r")
3520 (zero_extend:SI (subreg:QI (match_dup 1) 0)))]
3522 "andcc\t%1, 0xff, %0"
3523 [(set_attr "type" "compare")])
3525 (define_insn "*cmp_zero_extendqidi2"
3527 (compare:CCX (zero_extend:DI (match_operand:QI 0 "register_operand" "r"))
3530 "andcc\t%0, 0xff, %%g0"
3531 [(set_attr "type" "compare")])
3533 (define_insn "*cmp_zero_qi_sp64"
3535 (compare:CCX (match_operand:QI 0 "register_operand" "r")
3538 "andcc\t%0, 0xff, %%g0"
3539 [(set_attr "type" "compare")])
3541 (define_insn "*cmp_zero_extendqidi2_set"
3543 (compare:CCX (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
3545 (set (match_operand:DI 0 "register_operand" "=r")
3546 (zero_extend:DI (match_dup 1)))]
3548 "andcc\t%1, 0xff, %0"
3549 [(set_attr "type" "compare")])
3551 (define_insn "*cmp_zero_extendqidi2_andcc_set"
3553 (compare:CCX (and:DI (match_operand:DI 1 "register_operand" "r")
3556 (set (match_operand:DI 0 "register_operand" "=r")
3557 (zero_extend:DI (subreg:QI (match_dup 1) 0)))]
3559 "andcc\t%1, 0xff, %0"
3560 [(set_attr "type" "compare")])
3562 ;; Similarly, handle {SI,DI}->QI mode truncation followed by a compare.
3564 (define_insn "*cmp_siqi_trunc"
3566 (compare:CC (subreg:QI (match_operand:SI 0 "register_operand" "r") 3)
3569 "andcc\t%0, 0xff, %%g0"
3570 [(set_attr "type" "compare")])
3572 (define_insn "*cmp_siqi_trunc_set"
3574 (compare:CC (subreg:QI (match_operand:SI 1 "register_operand" "r") 3)
3576 (set (match_operand:QI 0 "register_operand" "=r")
3577 (subreg:QI (match_dup 1) 3))]
3579 "andcc\t%1, 0xff, %0"
3580 [(set_attr "type" "compare")])
3582 (define_insn "*cmp_diqi_trunc"
3584 (compare:CC (subreg:QI (match_operand:DI 0 "register_operand" "r") 7)
3587 "andcc\t%0, 0xff, %%g0"
3588 [(set_attr "type" "compare")])
3590 (define_insn "*cmp_diqi_trunc_set"
3592 (compare:CC (subreg:QI (match_operand:DI 1 "register_operand" "r") 7)
3594 (set (match_operand:QI 0 "register_operand" "=r")
3595 (subreg:QI (match_dup 1) 7))]
3597 "andcc\t%1, 0xff, %0"
3598 [(set_attr "type" "compare")])
3601 ;; Sign-extension instructions
3603 ;; These patterns originally accepted general_operands, however, slightly
3604 ;; better code is generated by only accepting register_operands, and then
3605 ;; letting combine generate the lds[hb] insns.
3607 (define_expand "extendhisi2"
3608 [(set (match_operand:SI 0 "register_operand" "")
3609 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
3612 rtx temp = gen_reg_rtx (SImode);
3613 rtx shift_16 = GEN_INT (16);
3614 int op1_subbyte = 0;
3616 if (GET_CODE (operand1) == SUBREG)
3618 op1_subbyte = SUBREG_BYTE (operand1);
3619 op1_subbyte /= GET_MODE_SIZE (SImode);
3620 op1_subbyte *= GET_MODE_SIZE (SImode);
3621 operand1 = XEXP (operand1, 0);
3624 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3626 emit_insn (gen_ashrsi3 (operand0, temp, shift_16));
3630 (define_insn "*sign_extendhisi2_insn"
3631 [(set (match_operand:SI 0 "register_operand" "=r")
3632 (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
3635 [(set_attr "type" "sload")
3636 (set_attr "us3load_type" "3cycle")])
3638 (define_expand "extendqihi2"
3639 [(set (match_operand:HI 0 "register_operand" "")
3640 (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
3643 rtx temp = gen_reg_rtx (SImode);
3644 rtx shift_24 = GEN_INT (24);
3645 int op1_subbyte = 0;
3646 int op0_subbyte = 0;
3648 if (GET_CODE (operand1) == SUBREG)
3650 op1_subbyte = SUBREG_BYTE (operand1);
3651 op1_subbyte /= GET_MODE_SIZE (SImode);
3652 op1_subbyte *= GET_MODE_SIZE (SImode);
3653 operand1 = XEXP (operand1, 0);
3655 if (GET_CODE (operand0) == SUBREG)
3657 op0_subbyte = SUBREG_BYTE (operand0);
3658 op0_subbyte /= GET_MODE_SIZE (SImode);
3659 op0_subbyte *= GET_MODE_SIZE (SImode);
3660 operand0 = XEXP (operand0, 0);
3662 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3664 if (GET_MODE (operand0) != SImode)
3665 operand0 = gen_rtx_SUBREG (SImode, operand0, op0_subbyte);
3666 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
3670 (define_insn "*sign_extendqihi2_insn"
3671 [(set (match_operand:HI 0 "register_operand" "=r")
3672 (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
3675 [(set_attr "type" "sload")
3676 (set_attr "us3load_type" "3cycle")])
3678 (define_expand "extendqisi2"
3679 [(set (match_operand:SI 0 "register_operand" "")
3680 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
3683 rtx temp = gen_reg_rtx (SImode);
3684 rtx shift_24 = GEN_INT (24);
3685 int op1_subbyte = 0;
3687 if (GET_CODE (operand1) == SUBREG)
3689 op1_subbyte = SUBREG_BYTE (operand1);
3690 op1_subbyte /= GET_MODE_SIZE (SImode);
3691 op1_subbyte *= GET_MODE_SIZE (SImode);
3692 operand1 = XEXP (operand1, 0);
3695 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3697 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
3701 (define_insn "*sign_extendqisi2_insn"
3702 [(set (match_operand:SI 0 "register_operand" "=r")
3703 (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
3706 [(set_attr "type" "sload")
3707 (set_attr "us3load_type" "3cycle")])
3709 (define_expand "extendqidi2"
3710 [(set (match_operand:DI 0 "register_operand" "")
3711 (sign_extend:DI (match_operand:QI 1 "register_operand" "")))]
3714 rtx temp = gen_reg_rtx (DImode);
3715 rtx shift_56 = GEN_INT (56);
3716 int op1_subbyte = 0;
3718 if (GET_CODE (operand1) == SUBREG)
3720 op1_subbyte = SUBREG_BYTE (operand1);
3721 op1_subbyte /= GET_MODE_SIZE (DImode);
3722 op1_subbyte *= GET_MODE_SIZE (DImode);
3723 operand1 = XEXP (operand1, 0);
3726 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
3728 emit_insn (gen_ashrdi3 (operand0, temp, shift_56));
3732 (define_insn "*sign_extendqidi2_insn"
3733 [(set (match_operand:DI 0 "register_operand" "=r")
3734 (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
3737 [(set_attr "type" "sload")
3738 (set_attr "us3load_type" "3cycle")])
3740 (define_expand "extendhidi2"
3741 [(set (match_operand:DI 0 "register_operand" "")
3742 (sign_extend:DI (match_operand:HI 1 "register_operand" "")))]
3745 rtx temp = gen_reg_rtx (DImode);
3746 rtx shift_48 = GEN_INT (48);
3747 int op1_subbyte = 0;
3749 if (GET_CODE (operand1) == SUBREG)
3751 op1_subbyte = SUBREG_BYTE (operand1);
3752 op1_subbyte /= GET_MODE_SIZE (DImode);
3753 op1_subbyte *= GET_MODE_SIZE (DImode);
3754 operand1 = XEXP (operand1, 0);
3757 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
3759 emit_insn (gen_ashrdi3 (operand0, temp, shift_48));
3763 (define_insn "*sign_extendhidi2_insn"
3764 [(set (match_operand:DI 0 "register_operand" "=r")
3765 (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
3768 [(set_attr "type" "sload")
3769 (set_attr "us3load_type" "3cycle")])
3771 (define_expand "extendsidi2"
3772 [(set (match_operand:DI 0 "register_operand" "")
3773 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
3777 (define_insn "*sign_extendsidi2_insn"
3778 [(set (match_operand:DI 0 "register_operand" "=r,r")
3779 (sign_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
3784 [(set_attr "type" "shift,sload")
3785 (set_attr "us3load_type" "*,3cycle")])
3788 ;; Special pattern for optimizing bit-field compares. This is needed
3789 ;; because combine uses this as a canonical form.
3791 (define_insn "*cmp_zero_extract"
3794 (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
3795 (match_operand:SI 1 "small_int_operand" "I")
3796 (match_operand:SI 2 "small_int_operand" "I"))
3798 "INTVAL (operands[2]) > 19"
3800 int len = INTVAL (operands[1]);
3801 int pos = 32 - INTVAL (operands[2]) - len;
3802 HOST_WIDE_INT mask = ((1 << len) - 1) << pos;
3803 operands[1] = GEN_INT (mask);
3804 return "andcc\t%0, %1, %%g0";
3806 [(set_attr "type" "compare")])
3808 (define_insn "*cmp_zero_extract_sp64"
3811 (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
3812 (match_operand:SI 1 "small_int_operand" "I")
3813 (match_operand:SI 2 "small_int_operand" "I"))
3815 "TARGET_ARCH64 && INTVAL (operands[2]) > 51"
3817 int len = INTVAL (operands[1]);
3818 int pos = 64 - INTVAL (operands[2]) - len;
3819 HOST_WIDE_INT mask = (((unsigned HOST_WIDE_INT) 1 << len) - 1) << pos;
3820 operands[1] = GEN_INT (mask);
3821 return "andcc\t%0, %1, %%g0";
3823 [(set_attr "type" "compare")])
3826 ;; Conversions between float, double and long double.
3828 (define_insn "extendsfdf2"
3829 [(set (match_operand:DF 0 "register_operand" "=e")
3831 (match_operand:SF 1 "register_operand" "f")))]
3834 [(set_attr "type" "fp")
3835 (set_attr "fptype" "double")])
3837 (define_expand "extendsftf2"
3838 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3840 (match_operand:SF 1 "register_operand" "")))]
3841 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3842 "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
3844 (define_insn "*extendsftf2_hq"
3845 [(set (match_operand:TF 0 "register_operand" "=e")
3847 (match_operand:SF 1 "register_operand" "f")))]
3848 "TARGET_FPU && TARGET_HARD_QUAD"
3850 [(set_attr "type" "fp")])
3852 (define_expand "extenddftf2"
3853 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3855 (match_operand:DF 1 "register_operand" "")))]
3856 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3857 "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
3859 (define_insn "*extenddftf2_hq"
3860 [(set (match_operand:TF 0 "register_operand" "=e")
3862 (match_operand:DF 1 "register_operand" "e")))]
3863 "TARGET_FPU && TARGET_HARD_QUAD"
3865 [(set_attr "type" "fp")])
3867 (define_insn "truncdfsf2"
3868 [(set (match_operand:SF 0 "register_operand" "=f")
3870 (match_operand:DF 1 "register_operand" "e")))]
3873 [(set_attr "type" "fp")
3874 (set_attr "fptype" "double")])
3876 (define_expand "trunctfsf2"
3877 [(set (match_operand:SF 0 "register_operand" "")
3879 (match_operand:TF 1 "general_operand" "")))]
3880 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3881 "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
3883 (define_insn "*trunctfsf2_hq"
3884 [(set (match_operand:SF 0 "register_operand" "=f")
3886 (match_operand:TF 1 "register_operand" "e")))]
3887 "TARGET_FPU && TARGET_HARD_QUAD"
3889 [(set_attr "type" "fp")])
3891 (define_expand "trunctfdf2"
3892 [(set (match_operand:DF 0 "register_operand" "")
3894 (match_operand:TF 1 "general_operand" "")))]
3895 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3896 "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
3898 (define_insn "*trunctfdf2_hq"
3899 [(set (match_operand:DF 0 "register_operand" "=e")
3901 (match_operand:TF 1 "register_operand" "e")))]
3902 "TARGET_FPU && TARGET_HARD_QUAD"
3904 [(set_attr "type" "fp")])
3907 ;; Conversion between fixed point and floating point.
3909 (define_insn "floatsisf2"
3910 [(set (match_operand:SF 0 "register_operand" "=f")
3911 (float:SF (match_operand:SI 1 "register_operand" "f")))]
3914 [(set_attr "type" "fp")
3915 (set_attr "fptype" "double")])
3917 (define_insn "floatsidf2"
3918 [(set (match_operand:DF 0 "register_operand" "=e")
3919 (float:DF (match_operand:SI 1 "register_operand" "f")))]
3922 [(set_attr "type" "fp")
3923 (set_attr "fptype" "double")])
3925 (define_expand "floatsitf2"
3926 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3927 (float:TF (match_operand:SI 1 "register_operand" "")))]
3928 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3929 "emit_tfmode_cvt (FLOAT, operands); DONE;")
3931 (define_insn "*floatsitf2_hq"
3932 [(set (match_operand:TF 0 "register_operand" "=e")
3933 (float:TF (match_operand:SI 1 "register_operand" "f")))]
3934 "TARGET_FPU && TARGET_HARD_QUAD"
3936 [(set_attr "type" "fp")])
3938 (define_expand "floatunssitf2"
3939 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3940 (unsigned_float:TF (match_operand:SI 1 "register_operand" "")))]
3941 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3942 "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
3944 ;; Now the same for 64 bit sources.
3946 (define_insn "floatdisf2"
3947 [(set (match_operand:SF 0 "register_operand" "=f")
3948 (float:SF (match_operand:DI 1 "register_operand" "e")))]
3949 "TARGET_V9 && TARGET_FPU"
3951 [(set_attr "type" "fp")
3952 (set_attr "fptype" "double")])
3954 (define_expand "floatunsdisf2"
3955 [(use (match_operand:SF 0 "register_operand" ""))
3956 (use (match_operand:DI 1 "general_operand" ""))]
3957 "TARGET_ARCH64 && TARGET_FPU"
3958 "sparc_emit_floatunsdi (operands, SFmode); DONE;")
3960 (define_insn "floatdidf2"
3961 [(set (match_operand:DF 0 "register_operand" "=e")
3962 (float:DF (match_operand:DI 1 "register_operand" "e")))]
3963 "TARGET_V9 && TARGET_FPU"
3965 [(set_attr "type" "fp")
3966 (set_attr "fptype" "double")])
3968 (define_expand "floatunsdidf2"
3969 [(use (match_operand:DF 0 "register_operand" ""))
3970 (use (match_operand:DI 1 "general_operand" ""))]
3971 "TARGET_ARCH64 && TARGET_FPU"
3972 "sparc_emit_floatunsdi (operands, DFmode); DONE;")
3974 (define_expand "floatditf2"
3975 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3976 (float:TF (match_operand:DI 1 "register_operand" "")))]
3977 "TARGET_FPU && TARGET_V9 && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3978 "emit_tfmode_cvt (FLOAT, operands); DONE;")
3980 (define_insn "*floatditf2_hq"
3981 [(set (match_operand:TF 0 "register_operand" "=e")
3982 (float:TF (match_operand:DI 1 "register_operand" "e")))]
3983 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
3985 [(set_attr "type" "fp")])
3987 (define_expand "floatunsditf2"
3988 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3989 (unsigned_float:TF (match_operand:DI 1 "register_operand" "")))]
3990 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3991 "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
3993 ;; Convert a float to an actual integer.
3994 ;; Truncation is performed as part of the conversion.
3996 (define_insn "fix_truncsfsi2"
3997 [(set (match_operand:SI 0 "register_operand" "=f")
3998 (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
4001 [(set_attr "type" "fp")
4002 (set_attr "fptype" "double")])
4004 (define_insn "fix_truncdfsi2"
4005 [(set (match_operand:SI 0 "register_operand" "=f")
4006 (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
4009 [(set_attr "type" "fp")
4010 (set_attr "fptype" "double")])
4012 (define_expand "fix_trunctfsi2"
4013 [(set (match_operand:SI 0 "register_operand" "")
4014 (fix:SI (match_operand:TF 1 "general_operand" "")))]
4015 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4016 "emit_tfmode_cvt (FIX, operands); DONE;")
4018 (define_insn "*fix_trunctfsi2_hq"
4019 [(set (match_operand:SI 0 "register_operand" "=f")
4020 (fix:SI (match_operand:TF 1 "register_operand" "e")))]
4021 "TARGET_FPU && TARGET_HARD_QUAD"
4023 [(set_attr "type" "fp")])
4025 (define_expand "fixuns_trunctfsi2"
4026 [(set (match_operand:SI 0 "register_operand" "")
4027 (unsigned_fix:SI (match_operand:TF 1 "general_operand" "")))]
4028 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4029 "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
4031 ;; Now the same, for V9 targets
4033 (define_insn "fix_truncsfdi2"
4034 [(set (match_operand:DI 0 "register_operand" "=e")
4035 (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
4036 "TARGET_V9 && TARGET_FPU"
4038 [(set_attr "type" "fp")
4039 (set_attr "fptype" "double")])
4041 (define_expand "fixuns_truncsfdi2"
4042 [(use (match_operand:DI 0 "register_operand" ""))
4043 (use (match_operand:SF 1 "general_operand" ""))]
4044 "TARGET_ARCH64 && TARGET_FPU"
4045 "sparc_emit_fixunsdi (operands, SFmode); DONE;")
4047 (define_insn "fix_truncdfdi2"
4048 [(set (match_operand:DI 0 "register_operand" "=e")
4049 (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
4050 "TARGET_V9 && TARGET_FPU"
4052 [(set_attr "type" "fp")
4053 (set_attr "fptype" "double")])
4055 (define_expand "fixuns_truncdfdi2"
4056 [(use (match_operand:DI 0 "register_operand" ""))
4057 (use (match_operand:DF 1 "general_operand" ""))]
4058 "TARGET_ARCH64 && TARGET_FPU"
4059 "sparc_emit_fixunsdi (operands, DFmode); DONE;")
4061 (define_expand "fix_trunctfdi2"
4062 [(set (match_operand:DI 0 "register_operand" "")
4063 (fix:DI (match_operand:TF 1 "general_operand" "")))]
4064 "TARGET_V9 && TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4065 "emit_tfmode_cvt (FIX, operands); DONE;")
4067 (define_insn "*fix_trunctfdi2_hq"
4068 [(set (match_operand:DI 0 "register_operand" "=e")
4069 (fix:DI (match_operand:TF 1 "register_operand" "e")))]
4070 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
4072 [(set_attr "type" "fp")])
4074 (define_expand "fixuns_trunctfdi2"
4075 [(set (match_operand:DI 0 "register_operand" "")
4076 (unsigned_fix:DI (match_operand:TF 1 "general_operand" "")))]
4077 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4078 "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
4081 ;; Integer addition/subtraction instructions.
4083 (define_expand "adddi3"
4084 [(set (match_operand:DI 0 "register_operand" "")
4085 (plus:DI (match_operand:DI 1 "register_operand" "")
4086 (match_operand:DI 2 "arith_double_add_operand" "")))]
4089 if (! TARGET_ARCH64)
4091 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
4092 gen_rtx_SET (VOIDmode, operands[0],
4093 gen_rtx_PLUS (DImode, operands[1],
4095 gen_rtx_CLOBBER (VOIDmode,
4096 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
4101 (define_insn_and_split "adddi3_insn_sp32"
4102 [(set (match_operand:DI 0 "register_operand" "=r")
4103 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
4104 (match_operand:DI 2 "arith_double_operand" "rHI")))
4105 (clobber (reg:CC 100))]
4108 "&& reload_completed"
4109 [(parallel [(set (reg:CC_NOOV 100)
4110 (compare:CC_NOOV (plus:SI (match_dup 4)
4114 (plus:SI (match_dup 4) (match_dup 5)))])
4116 (plus:SI (plus:SI (match_dup 7)
4118 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4120 operands[3] = gen_lowpart (SImode, operands[0]);
4121 operands[4] = gen_lowpart (SImode, operands[1]);
4122 operands[5] = gen_lowpart (SImode, operands[2]);
4123 operands[6] = gen_highpart (SImode, operands[0]);
4124 operands[7] = gen_highpart_mode (SImode, DImode, operands[1]);
4125 #if HOST_BITS_PER_WIDE_INT == 32
4126 if (GET_CODE (operands[2]) == CONST_INT)
4128 if (INTVAL (operands[2]) < 0)
4129 operands[8] = constm1_rtx;
4131 operands[8] = const0_rtx;
4135 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
4137 [(set_attr "length" "2")])
4139 ;; LTU here means "carry set"
4141 [(set (match_operand:SI 0 "register_operand" "=r")
4142 (plus:SI (plus:SI (match_operand:SI 1 "arith_operand" "%r")
4143 (match_operand:SI 2 "arith_operand" "rI"))
4144 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4147 [(set_attr "type" "ialuX")])
4149 (define_insn_and_split "*addx_extend_sp32"
4150 [(set (match_operand:DI 0 "register_operand" "=r")
4151 (zero_extend:DI (plus:SI (plus:SI
4152 (match_operand:SI 1 "register_or_zero_operand" "%rJ")
4153 (match_operand:SI 2 "arith_operand" "rI"))
4154 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4157 "&& reload_completed"
4158 [(set (match_dup 3) (plus:SI (plus:SI (match_dup 1) (match_dup 2))
4159 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
4160 (set (match_dup 4) (const_int 0))]
4161 "operands[3] = gen_lowpart (SImode, operands[0]);
4162 operands[4] = gen_highpart_mode (SImode, DImode, operands[1]);"
4163 [(set_attr "length" "2")])
4165 (define_insn "*addx_extend_sp64"
4166 [(set (match_operand:DI 0 "register_operand" "=r")
4167 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ")
4168 (match_operand:SI 2 "arith_operand" "rI"))
4169 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4172 [(set_attr "type" "ialuX")])
4174 (define_insn_and_split ""
4175 [(set (match_operand:DI 0 "register_operand" "=r")
4176 (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4177 (match_operand:DI 2 "register_operand" "r")))
4178 (clobber (reg:CC 100))]
4181 "&& reload_completed"
4182 [(parallel [(set (reg:CC_NOOV 100)
4183 (compare:CC_NOOV (plus:SI (match_dup 3) (match_dup 1))
4185 (set (match_dup 5) (plus:SI (match_dup 3) (match_dup 1)))])
4187 (plus:SI (plus:SI (match_dup 4) (const_int 0))
4188 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4189 "operands[3] = gen_lowpart (SImode, operands[2]);
4190 operands[4] = gen_highpart (SImode, operands[2]);
4191 operands[5] = gen_lowpart (SImode, operands[0]);
4192 operands[6] = gen_highpart (SImode, operands[0]);"
4193 [(set_attr "length" "2")])
4195 (define_insn "*adddi3_sp64"
4196 [(set (match_operand:DI 0 "register_operand" "=r,r")
4197 (plus:DI (match_operand:DI 1 "register_operand" "%r,r")
4198 (match_operand:DI 2 "arith_add_operand" "rI,O")))]
4204 (define_insn "addsi3"
4205 [(set (match_operand:SI 0 "register_operand" "=r,r,d")
4206 (plus:SI (match_operand:SI 1 "register_operand" "%r,r,d")
4207 (match_operand:SI 2 "arith_add_operand" "rI,O,d")))]
4212 fpadd32s\t%1, %2, %0"
4213 [(set_attr "type" "*,*,fga")
4214 (set_attr "fptype" "*,*,single")])
4216 (define_insn "*cmp_cc_plus"
4217 [(set (reg:CC_NOOV 100)
4218 (compare:CC_NOOV (plus:SI (match_operand:SI 0 "arith_operand" "%r")
4219 (match_operand:SI 1 "arith_operand" "rI"))
4222 "addcc\t%0, %1, %%g0"
4223 [(set_attr "type" "compare")])
4225 (define_insn "*cmp_ccx_plus"
4226 [(set (reg:CCX_NOOV 100)
4227 (compare:CCX_NOOV (plus:DI (match_operand:DI 0 "arith_operand" "%r")
4228 (match_operand:DI 1 "arith_operand" "rI"))
4231 "addcc\t%0, %1, %%g0"
4232 [(set_attr "type" "compare")])
4234 (define_insn "*cmp_cc_plus_set"
4235 [(set (reg:CC_NOOV 100)
4236 (compare:CC_NOOV (plus:SI (match_operand:SI 1 "arith_operand" "%r")
4237 (match_operand:SI 2 "arith_operand" "rI"))
4239 (set (match_operand:SI 0 "register_operand" "=r")
4240 (plus:SI (match_dup 1) (match_dup 2)))]
4243 [(set_attr "type" "compare")])
4245 (define_insn "*cmp_ccx_plus_set"
4246 [(set (reg:CCX_NOOV 100)
4247 (compare:CCX_NOOV (plus:DI (match_operand:DI 1 "arith_operand" "%r")
4248 (match_operand:DI 2 "arith_operand" "rI"))
4250 (set (match_operand:DI 0 "register_operand" "=r")
4251 (plus:DI (match_dup 1) (match_dup 2)))]
4254 [(set_attr "type" "compare")])
4256 (define_expand "subdi3"
4257 [(set (match_operand:DI 0 "register_operand" "")
4258 (minus:DI (match_operand:DI 1 "register_operand" "")
4259 (match_operand:DI 2 "arith_double_add_operand" "")))]
4262 if (! TARGET_ARCH64)
4264 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
4265 gen_rtx_SET (VOIDmode, operands[0],
4266 gen_rtx_MINUS (DImode, operands[1],
4268 gen_rtx_CLOBBER (VOIDmode,
4269 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
4274 (define_insn_and_split "subdi3_insn_sp32"
4275 [(set (match_operand:DI 0 "register_operand" "=r")
4276 (minus:DI (match_operand:DI 1 "register_operand" "r")
4277 (match_operand:DI 2 "arith_double_operand" "rHI")))
4278 (clobber (reg:CC 100))]
4281 "&& reload_completed"
4282 [(parallel [(set (reg:CC_NOOV 100)
4283 (compare:CC_NOOV (minus:SI (match_dup 4)
4287 (minus:SI (match_dup 4) (match_dup 5)))])
4289 (minus:SI (minus:SI (match_dup 7)
4291 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4293 operands[3] = gen_lowpart (SImode, operands[0]);
4294 operands[4] = gen_lowpart (SImode, operands[1]);
4295 operands[5] = gen_lowpart (SImode, operands[2]);
4296 operands[6] = gen_highpart (SImode, operands[0]);
4297 operands[7] = gen_highpart (SImode, operands[1]);
4298 #if HOST_BITS_PER_WIDE_INT == 32
4299 if (GET_CODE (operands[2]) == CONST_INT)
4301 if (INTVAL (operands[2]) < 0)
4302 operands[8] = constm1_rtx;
4304 operands[8] = const0_rtx;
4308 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
4310 [(set_attr "length" "2")])
4312 ;; LTU here means "carry set"
4314 [(set (match_operand:SI 0 "register_operand" "=r")
4315 (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
4316 (match_operand:SI 2 "arith_operand" "rI"))
4317 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4320 [(set_attr "type" "ialuX")])
4322 (define_insn "*subx_extend_sp64"
4323 [(set (match_operand:DI 0 "register_operand" "=r")
4324 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
4325 (match_operand:SI 2 "arith_operand" "rI"))
4326 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4329 [(set_attr "type" "ialuX")])
4331 (define_insn_and_split "*subx_extend"
4332 [(set (match_operand:DI 0 "register_operand" "=r")
4333 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
4334 (match_operand:SI 2 "arith_operand" "rI"))
4335 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4338 "&& reload_completed"
4339 [(set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 2))
4340 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
4341 (set (match_dup 4) (const_int 0))]
4342 "operands[3] = gen_lowpart (SImode, operands[0]);
4343 operands[4] = gen_highpart (SImode, operands[0]);"
4344 [(set_attr "length" "2")])
4346 (define_insn_and_split ""
4347 [(set (match_operand:DI 0 "register_operand" "=r")
4348 (minus:DI (match_operand:DI 1 "register_operand" "r")
4349 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))
4350 (clobber (reg:CC 100))]
4353 "&& reload_completed"
4354 [(parallel [(set (reg:CC_NOOV 100)
4355 (compare:CC_NOOV (minus:SI (match_dup 3) (match_dup 2))
4357 (set (match_dup 5) (minus:SI (match_dup 3) (match_dup 2)))])
4359 (minus:SI (minus:SI (match_dup 4) (const_int 0))
4360 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4361 "operands[3] = gen_lowpart (SImode, operands[1]);
4362 operands[4] = gen_highpart (SImode, operands[1]);
4363 operands[5] = gen_lowpart (SImode, operands[0]);
4364 operands[6] = gen_highpart (SImode, operands[0]);"
4365 [(set_attr "length" "2")])
4367 (define_insn "*subdi3_sp64"
4368 [(set (match_operand:DI 0 "register_operand" "=r,r")
4369 (minus:DI (match_operand:DI 1 "register_operand" "r,r")
4370 (match_operand:DI 2 "arith_add_operand" "rI,O")))]
4376 (define_insn "subsi3"
4377 [(set (match_operand:SI 0 "register_operand" "=r,r,d")
4378 (minus:SI (match_operand:SI 1 "register_operand" "r,r,d")
4379 (match_operand:SI 2 "arith_add_operand" "rI,O,d")))]
4384 fpsub32s\t%1, %2, %0"
4385 [(set_attr "type" "*,*,fga")
4386 (set_attr "fptype" "*,*,single")])
4388 (define_insn "*cmp_minus_cc"
4389 [(set (reg:CC_NOOV 100)
4390 (compare:CC_NOOV (minus:SI (match_operand:SI 0 "register_or_zero_operand" "rJ")
4391 (match_operand:SI 1 "arith_operand" "rI"))
4394 "subcc\t%r0, %1, %%g0"
4395 [(set_attr "type" "compare")])
4397 (define_insn "*cmp_minus_ccx"
4398 [(set (reg:CCX_NOOV 100)
4399 (compare:CCX_NOOV (minus:DI (match_operand:DI 0 "register_operand" "r")
4400 (match_operand:DI 1 "arith_operand" "rI"))
4403 "subcc\t%0, %1, %%g0"
4404 [(set_attr "type" "compare")])
4406 (define_insn "cmp_minus_cc_set"
4407 [(set (reg:CC_NOOV 100)
4408 (compare:CC_NOOV (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
4409 (match_operand:SI 2 "arith_operand" "rI"))
4411 (set (match_operand:SI 0 "register_operand" "=r")
4412 (minus:SI (match_dup 1) (match_dup 2)))]
4414 "subcc\t%r1, %2, %0"
4415 [(set_attr "type" "compare")])
4417 (define_insn "*cmp_minus_ccx_set"
4418 [(set (reg:CCX_NOOV 100)
4419 (compare:CCX_NOOV (minus:DI (match_operand:DI 1 "register_operand" "r")
4420 (match_operand:DI 2 "arith_operand" "rI"))
4422 (set (match_operand:DI 0 "register_operand" "=r")
4423 (minus:DI (match_dup 1) (match_dup 2)))]
4426 [(set_attr "type" "compare")])
4429 ;; Integer multiply/divide instructions.
4431 ;; The 32-bit multiply/divide instructions are deprecated on v9, but at
4432 ;; least in UltraSPARC I, II and IIi it is a win tick-wise.
4434 (define_insn "mulsi3"
4435 [(set (match_operand:SI 0 "register_operand" "=r")
4436 (mult:SI (match_operand:SI 1 "arith_operand" "%r")
4437 (match_operand:SI 2 "arith_operand" "rI")))]
4440 [(set_attr "type" "imul")])
4442 (define_expand "muldi3"
4443 [(set (match_operand:DI 0 "register_operand" "")
4444 (mult:DI (match_operand:DI 1 "arith_operand" "")
4445 (match_operand:DI 2 "arith_operand" "")))]
4446 "TARGET_ARCH64 || TARGET_V8PLUS"
4450 emit_insn (gen_muldi3_v8plus (operands[0], operands[1], operands[2]));
4455 (define_insn "*muldi3_sp64"
4456 [(set (match_operand:DI 0 "register_operand" "=r")
4457 (mult:DI (match_operand:DI 1 "arith_operand" "%r")
4458 (match_operand:DI 2 "arith_operand" "rI")))]
4461 [(set_attr "type" "imul")])
4463 ;; V8plus wide multiply.
4465 (define_insn "muldi3_v8plus"
4466 [(set (match_operand:DI 0 "register_operand" "=r,h")
4467 (mult:DI (match_operand:DI 1 "arith_operand" "%r,0")
4468 (match_operand:DI 2 "arith_operand" "rI,rI")))
4469 (clobber (match_scratch:SI 3 "=&h,X"))
4470 (clobber (match_scratch:SI 4 "=&h,X"))]
4473 if (sparc_check_64 (operands[1], insn) <= 0)
4474 output_asm_insn ("srl\t%L1, 0, %L1", operands);
4475 if (which_alternative == 1)
4476 output_asm_insn ("sllx\t%H1, 32, %H1", operands);
4477 if (GET_CODE (operands[2]) == CONST_INT)
4479 if (which_alternative == 1)
4480 return "or\t%L1, %H1, %H1\n\tmulx\t%H1, %2, %L0\;srlx\t%L0, 32, %H0";
4482 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";
4484 else if (rtx_equal_p (operands[1], operands[2]))
4486 if (which_alternative == 1)
4487 return "or\t%L1, %H1, %H1\n\tmulx\t%H1, %H1, %L0\;srlx\t%L0, 32, %H0";
4489 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";
4491 if (sparc_check_64 (operands[2], insn) <= 0)
4492 output_asm_insn ("srl\t%L2, 0, %L2", operands);
4493 if (which_alternative == 1)
4494 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";
4496 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";
4498 [(set_attr "type" "multi")
4499 (set_attr "length" "9,8")])
4501 (define_insn "*cmp_mul_set"
4503 (compare:CC (mult:SI (match_operand:SI 1 "arith_operand" "%r")
4504 (match_operand:SI 2 "arith_operand" "rI"))
4506 (set (match_operand:SI 0 "register_operand" "=r")
4507 (mult:SI (match_dup 1) (match_dup 2)))]
4508 "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS"
4509 "smulcc\t%1, %2, %0"
4510 [(set_attr "type" "imul")])
4512 (define_expand "mulsidi3"
4513 [(set (match_operand:DI 0 "register_operand" "")
4514 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
4515 (sign_extend:DI (match_operand:SI 2 "arith_operand" ""))))]
4518 if (CONSTANT_P (operands[2]))
4521 emit_insn (gen_const_mulsidi3_v8plus (operands[0], operands[1],
4523 else if (TARGET_ARCH32)
4524 emit_insn (gen_const_mulsidi3_sp32 (operands[0], operands[1],
4527 emit_insn (gen_const_mulsidi3_sp64 (operands[0], operands[1],
4533 emit_insn (gen_mulsidi3_v8plus (operands[0], operands[1], operands[2]));
4538 ;; V9 puts the 64-bit product in a 64-bit register. Only out or global
4539 ;; registers can hold 64-bit values in the V8plus environment.
4541 (define_insn "mulsidi3_v8plus"
4542 [(set (match_operand:DI 0 "register_operand" "=h,r")
4543 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4544 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
4545 (clobber (match_scratch:SI 3 "=X,&h"))]
4548 smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
4549 smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4550 [(set_attr "type" "multi")
4551 (set_attr "length" "2,3")])
4554 (define_insn "const_mulsidi3_v8plus"
4555 [(set (match_operand:DI 0 "register_operand" "=h,r")
4556 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4557 (match_operand:DI 2 "small_int_operand" "I,I")))
4558 (clobber (match_scratch:SI 3 "=X,&h"))]
4561 smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
4562 smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4563 [(set_attr "type" "multi")
4564 (set_attr "length" "2,3")])
4567 (define_insn "*mulsidi3_sp32"
4568 [(set (match_operand:DI 0 "register_operand" "=r")
4569 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4570 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4573 return TARGET_SPARCLET
4574 ? "smuld\t%1, %2, %L0"
4575 : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
4578 (if_then_else (eq_attr "isa" "sparclet")
4579 (const_string "imul") (const_string "multi")))
4580 (set (attr "length")
4581 (if_then_else (eq_attr "isa" "sparclet")
4582 (const_int 1) (const_int 2)))])
4584 (define_insn "*mulsidi3_sp64"
4585 [(set (match_operand:DI 0 "register_operand" "=r")
4586 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4587 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4588 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4590 [(set_attr "type" "imul")])
4592 ;; Extra pattern, because sign_extend of a constant isn't valid.
4595 (define_insn "const_mulsidi3_sp32"
4596 [(set (match_operand:DI 0 "register_operand" "=r")
4597 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4598 (match_operand:DI 2 "small_int_operand" "I")))]
4601 return TARGET_SPARCLET
4602 ? "smuld\t%1, %2, %L0"
4603 : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
4606 (if_then_else (eq_attr "isa" "sparclet")
4607 (const_string "imul") (const_string "multi")))
4608 (set (attr "length")
4609 (if_then_else (eq_attr "isa" "sparclet")
4610 (const_int 1) (const_int 2)))])
4612 (define_insn "const_mulsidi3_sp64"
4613 [(set (match_operand:DI 0 "register_operand" "=r")
4614 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4615 (match_operand:DI 2 "small_int_operand" "I")))]
4616 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4618 [(set_attr "type" "imul")])
4620 (define_expand "smulsi3_highpart"
4621 [(set (match_operand:SI 0 "register_operand" "")
4623 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
4624 (sign_extend:DI (match_operand:SI 2 "arith_operand" "")))
4626 "TARGET_HARD_MUL && TARGET_ARCH32"
4628 if (CONSTANT_P (operands[2]))
4632 emit_insn (gen_const_smulsi3_highpart_v8plus (operands[0],
4638 emit_insn (gen_const_smulsi3_highpart (operands[0], operands[1], operands[2]));
4643 emit_insn (gen_smulsi3_highpart_v8plus (operands[0], operands[1],
4644 operands[2], GEN_INT (32)));
4650 (define_insn "smulsi3_highpart_v8plus"
4651 [(set (match_operand:SI 0 "register_operand" "=h,r")
4653 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4654 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
4655 (match_operand:SI 3 "small_int_operand" "I,I"))))
4656 (clobber (match_scratch:SI 4 "=X,&h"))]
4659 smul\t%1, %2, %0\;srlx\t%0, %3, %0
4660 smul\t%1, %2, %4\;srlx\t%4, %3, %0"
4661 [(set_attr "type" "multi")
4662 (set_attr "length" "2")])
4664 ;; The combiner changes TRUNCATE in the previous pattern to SUBREG.
4667 [(set (match_operand:SI 0 "register_operand" "=h,r")
4670 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4671 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
4672 (match_operand:SI 3 "small_int_operand" "I,I"))
4674 (clobber (match_scratch:SI 4 "=X,&h"))]
4677 smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
4678 smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
4679 [(set_attr "type" "multi")
4680 (set_attr "length" "2")])
4683 (define_insn "const_smulsi3_highpart_v8plus"
4684 [(set (match_operand:SI 0 "register_operand" "=h,r")
4686 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4687 (match_operand:DI 2 "small_int_operand" "I,I"))
4688 (match_operand:SI 3 "small_int_operand" "I,I"))))
4689 (clobber (match_scratch:SI 4 "=X,&h"))]
4692 smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
4693 smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
4694 [(set_attr "type" "multi")
4695 (set_attr "length" "2")])
4698 (define_insn "*smulsi3_highpart_sp32"
4699 [(set (match_operand:SI 0 "register_operand" "=r")
4701 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4702 (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
4705 "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
4706 [(set_attr "type" "multi")
4707 (set_attr "length" "2")])
4710 (define_insn "const_smulsi3_highpart"
4711 [(set (match_operand:SI 0 "register_operand" "=r")
4713 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4714 (match_operand:DI 2 "small_int_operand" "i"))
4717 "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
4718 [(set_attr "type" "multi")
4719 (set_attr "length" "2")])
4721 (define_expand "umulsidi3"
4722 [(set (match_operand:DI 0 "register_operand" "")
4723 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
4724 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" ""))))]
4727 if (CONSTANT_P (operands[2]))
4730 emit_insn (gen_const_umulsidi3_v8plus (operands[0], operands[1],
4732 else if (TARGET_ARCH32)
4733 emit_insn (gen_const_umulsidi3_sp32 (operands[0], operands[1],
4736 emit_insn (gen_const_umulsidi3_sp64 (operands[0], operands[1],
4742 emit_insn (gen_umulsidi3_v8plus (operands[0], operands[1], operands[2]));
4748 (define_insn "umulsidi3_v8plus"
4749 [(set (match_operand:DI 0 "register_operand" "=h,r")
4750 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4751 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
4752 (clobber (match_scratch:SI 3 "=X,&h"))]
4755 umul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
4756 umul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4757 [(set_attr "type" "multi")
4758 (set_attr "length" "2,3")])
4761 (define_insn "*umulsidi3_sp32"
4762 [(set (match_operand:DI 0 "register_operand" "=r")
4763 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4764 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4767 return TARGET_SPARCLET
4768 ? "umuld\t%1, %2, %L0"
4769 : "umul\t%1, %2, %L0\n\trd\t%%y, %H0";
4772 (if_then_else (eq_attr "isa" "sparclet")
4773 (const_string "imul") (const_string "multi")))
4774 (set (attr "length")
4775 (if_then_else (eq_attr "isa" "sparclet")
4776 (const_int 1) (const_int 2)))])
4778 (define_insn "*umulsidi3_sp64"
4779 [(set (match_operand:DI 0 "register_operand" "=r")
4780 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4781 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4782 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4784 [(set_attr "type" "imul")])
4786 ;; Extra pattern, because sign_extend of a constant isn't valid.
4789 (define_insn "const_umulsidi3_sp32"
4790 [(set (match_operand:DI 0 "register_operand" "=r")
4791 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4792 (match_operand:DI 2 "uns_small_int_operand" "")))]
4795 return TARGET_SPARCLET
4796 ? "umuld\t%1, %s2, %L0"
4797 : "umul\t%1, %s2, %L0\n\trd\t%%y, %H0";
4800 (if_then_else (eq_attr "isa" "sparclet")
4801 (const_string "imul") (const_string "multi")))
4802 (set (attr "length")
4803 (if_then_else (eq_attr "isa" "sparclet")
4804 (const_int 1) (const_int 2)))])
4806 (define_insn "const_umulsidi3_sp64"
4807 [(set (match_operand:DI 0 "register_operand" "=r")
4808 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4809 (match_operand:DI 2 "uns_small_int_operand" "")))]
4810 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4812 [(set_attr "type" "imul")])
4815 (define_insn "const_umulsidi3_v8plus"
4816 [(set (match_operand:DI 0 "register_operand" "=h,r")
4817 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4818 (match_operand:DI 2 "uns_small_int_operand" "")))
4819 (clobber (match_scratch:SI 3 "=X,h"))]
4822 umul\t%1, %s2, %L0\n\tsrlx\t%L0, 32, %H0
4823 umul\t%1, %s2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4824 [(set_attr "type" "multi")
4825 (set_attr "length" "2,3")])
4827 (define_expand "umulsi3_highpart"
4828 [(set (match_operand:SI 0 "register_operand" "")
4830 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
4831 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" "")))
4833 "TARGET_HARD_MUL && TARGET_ARCH32"
4835 if (CONSTANT_P (operands[2]))
4839 emit_insn (gen_const_umulsi3_highpart_v8plus (operands[0],
4845 emit_insn (gen_const_umulsi3_highpart (operands[0], operands[1], operands[2]));
4850 emit_insn (gen_umulsi3_highpart_v8plus (operands[0], operands[1],
4851 operands[2], GEN_INT (32)));
4857 (define_insn "umulsi3_highpart_v8plus"
4858 [(set (match_operand:SI 0 "register_operand" "=h,r")
4860 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4861 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
4862 (match_operand:SI 3 "small_int_operand" "I,I"))))
4863 (clobber (match_scratch:SI 4 "=X,h"))]
4866 umul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
4867 umul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
4868 [(set_attr "type" "multi")
4869 (set_attr "length" "2")])
4872 (define_insn "const_umulsi3_highpart_v8plus"
4873 [(set (match_operand:SI 0 "register_operand" "=h,r")
4875 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4876 (match_operand:DI 2 "uns_small_int_operand" ""))
4877 (match_operand:SI 3 "small_int_operand" "I,I"))))
4878 (clobber (match_scratch:SI 4 "=X,h"))]
4881 umul\t%1, %s2, %0\n\tsrlx\t%0, %3, %0
4882 umul\t%1, %s2, %4\n\tsrlx\t%4, %3, %0"
4883 [(set_attr "type" "multi")
4884 (set_attr "length" "2")])
4887 (define_insn "*umulsi3_highpart_sp32"
4888 [(set (match_operand:SI 0 "register_operand" "=r")
4890 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4891 (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
4894 "umul\t%1, %2, %%g0\n\trd\t%%y, %0"
4895 [(set_attr "type" "multi")
4896 (set_attr "length" "2")])
4899 (define_insn "const_umulsi3_highpart"
4900 [(set (match_operand:SI 0 "register_operand" "=r")
4902 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4903 (match_operand:DI 2 "uns_small_int_operand" ""))
4906 "umul\t%1, %s2, %%g0\n\trd\t%%y, %0"
4907 [(set_attr "type" "multi")
4908 (set_attr "length" "2")])
4910 (define_expand "divsi3"
4911 [(parallel [(set (match_operand:SI 0 "register_operand" "")
4912 (div:SI (match_operand:SI 1 "register_operand" "")
4913 (match_operand:SI 2 "input_operand" "")))
4914 (clobber (match_scratch:SI 3 ""))])]
4915 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4919 operands[3] = gen_reg_rtx(SImode);
4920 emit_insn (gen_ashrsi3 (operands[3], operands[1], GEN_INT (31)));
4921 emit_insn (gen_divsi3_sp64 (operands[0], operands[1], operands[2],
4927 ;; The V8 architecture specifies that there must be at least 3 instructions
4928 ;; between a write to the Y register and a use of it for correct results.
4929 ;; We try to fill one of them with a simple constant or a memory load.
4931 (define_insn "divsi3_sp32"
4932 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
4933 (div:SI (match_operand:SI 1 "register_operand" "r,r,r")
4934 (match_operand:SI 2 "input_operand" "rI,K,m")))
4935 (clobber (match_scratch:SI 3 "=&r,&r,&r"))]
4936 "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS) && TARGET_ARCH32"
4938 output_asm_insn ("sra\t%1, 31, %3", operands);
4939 output_asm_insn ("wr\t%3, 0, %%y", operands);
4941 switch (which_alternative)
4945 return "sdiv\t%1, %2, %0";
4947 return "nop\n\tnop\n\tnop\n\tsdiv\t%1, %2, %0";
4950 return "sethi\t%%hi(%a2), %3\n\tsdiv\t%1, %3, %0";
4952 return "sethi\t%%hi(%a2), %3\n\tnop\n\tnop\n\tsdiv\t%1, %3, %0";
4955 return "ld\t%2, %3\n\tsdiv\t%1, %3, %0";
4957 return "ld\t%2, %3\n\tnop\n\tnop\n\tsdiv\t%1, %3, %0";
4962 [(set_attr "type" "multi")
4963 (set (attr "length")
4964 (if_then_else (eq_attr "isa" "v9")
4965 (const_int 4) (const_int 6)))])
4967 (define_insn "divsi3_sp64"
4968 [(set (match_operand:SI 0 "register_operand" "=r")
4969 (div:SI (match_operand:SI 1 "register_operand" "r")
4970 (match_operand:SI 2 "input_operand" "rI")))
4971 (use (match_operand:SI 3 "register_operand" "r"))]
4972 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4973 "wr\t%%g0, %3, %%y\n\tsdiv\t%1, %2, %0"
4974 [(set_attr "type" "multi")
4975 (set_attr "length" "2")])
4977 (define_insn "divdi3"
4978 [(set (match_operand:DI 0 "register_operand" "=r")
4979 (div:DI (match_operand:DI 1 "register_operand" "r")
4980 (match_operand:DI 2 "arith_operand" "rI")))]
4983 [(set_attr "type" "idiv")])
4985 (define_insn "*cmp_sdiv_cc_set"
4987 (compare:CC (div:SI (match_operand:SI 1 "register_operand" "r")
4988 (match_operand:SI 2 "arith_operand" "rI"))
4990 (set (match_operand:SI 0 "register_operand" "=r")
4991 (div:SI (match_dup 1) (match_dup 2)))
4992 (clobber (match_scratch:SI 3 "=&r"))]
4993 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4995 output_asm_insn ("sra\t%1, 31, %3", operands);
4996 output_asm_insn ("wr\t%3, 0, %%y", operands);
4999 return "sdivcc\t%1, %2, %0";
5001 return "nop\n\tnop\n\tnop\n\tsdivcc\t%1, %2, %0";
5003 [(set_attr "type" "multi")
5004 (set (attr "length")
5005 (if_then_else (eq_attr "isa" "v9")
5006 (const_int 3) (const_int 6)))])
5009 (define_expand "udivsi3"
5010 [(set (match_operand:SI 0 "register_operand" "")
5011 (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "")
5012 (match_operand:SI 2 "input_operand" "")))]
5013 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
5016 ;; The V8 architecture specifies that there must be at least 3 instructions
5017 ;; between a write to the Y register and a use of it for correct results.
5018 ;; We try to fill one of them with a simple constant or a memory load.
5020 (define_insn "udivsi3_sp32"
5021 [(set (match_operand:SI 0 "register_operand" "=r,&r,&r,&r")
5022 (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "r,r,r,m")
5023 (match_operand:SI 2 "input_operand" "rI,K,m,r")))]
5024 "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS) && TARGET_ARCH32"
5026 output_asm_insn ("wr\t%%g0, 0, %%y", operands);
5028 switch (which_alternative)
5032 return "udiv\t%1, %2, %0";
5034 return "nop\n\tnop\n\tnop\n\tudiv\t%1, %2, %0";
5037 return "sethi\t%%hi(%a2), %0\n\tudiv\t%1, %0, %0";
5039 return "sethi\t%%hi(%a2), %0\n\tnop\n\tnop\n\tudiv\t%1, %0, %0";
5042 return "ld\t%2, %0\n\tudiv\t%1, %0, %0";
5044 return "ld\t%2, %0\n\tnop\n\tnop\n\tudiv\t%1, %0, %0";
5047 return "ld\t%1, %0\n\tudiv\t%0, %2, %0";
5049 return "ld\t%1, %0\n\tnop\n\tnop\n\tudiv\t%0, %2, %0";
5054 [(set_attr "type" "multi")
5055 (set (attr "length")
5056 (if_then_else (eq_attr "isa" "v9")
5057 (const_int 3) (const_int 5)))])
5059 (define_insn "udivsi3_sp64"
5060 [(set (match_operand:SI 0 "register_operand" "=r")
5061 (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "r")
5062 (match_operand:SI 2 "input_operand" "rI")))]
5063 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5064 "wr\t%%g0, 0, %%y\n\tudiv\t%1, %2, %0"
5065 [(set_attr "type" "multi")
5066 (set_attr "length" "2")])
5068 (define_insn "udivdi3"
5069 [(set (match_operand:DI 0 "register_operand" "=r")
5070 (udiv:DI (match_operand:DI 1 "register_operand" "r")
5071 (match_operand:DI 2 "arith_operand" "rI")))]
5074 [(set_attr "type" "idiv")])
5076 (define_insn "*cmp_udiv_cc_set"
5078 (compare:CC (udiv:SI (match_operand:SI 1 "register_operand" "r")
5079 (match_operand:SI 2 "arith_operand" "rI"))
5081 (set (match_operand:SI 0 "register_operand" "=r")
5082 (udiv:SI (match_dup 1) (match_dup 2)))]
5083 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
5085 output_asm_insn ("wr\t%%g0, 0, %%y", operands);
5088 return "udivcc\t%1, %2, %0";
5090 return "nop\n\tnop\n\tnop\n\tudivcc\t%1, %2, %0";
5092 [(set_attr "type" "multi")
5093 (set (attr "length")
5094 (if_then_else (eq_attr "isa" "v9")
5095 (const_int 2) (const_int 5)))])
5097 ; sparclet multiply/accumulate insns
5099 (define_insn "*smacsi"
5100 [(set (match_operand:SI 0 "register_operand" "=r")
5101 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "%r")
5102 (match_operand:SI 2 "arith_operand" "rI"))
5103 (match_operand:SI 3 "register_operand" "0")))]
5106 [(set_attr "type" "imul")])
5108 (define_insn "*smacdi"
5109 [(set (match_operand:DI 0 "register_operand" "=r")
5110 (plus:DI (mult:DI (sign_extend:DI
5111 (match_operand:SI 1 "register_operand" "%r"))
5113 (match_operand:SI 2 "register_operand" "r")))
5114 (match_operand:DI 3 "register_operand" "0")))]
5116 "smacd\t%1, %2, %L0"
5117 [(set_attr "type" "imul")])
5119 (define_insn "*umacdi"
5120 [(set (match_operand:DI 0 "register_operand" "=r")
5121 (plus:DI (mult:DI (zero_extend:DI
5122 (match_operand:SI 1 "register_operand" "%r"))
5124 (match_operand:SI 2 "register_operand" "r")))
5125 (match_operand:DI 3 "register_operand" "0")))]
5127 "umacd\t%1, %2, %L0"
5128 [(set_attr "type" "imul")])
5131 ;; Boolean instructions.
5133 ;; We define DImode `and' so with DImode `not' we can get
5134 ;; DImode `andn'. Other combinations are possible.
5136 (define_mode_iterator V64I [DI V2SI V4HI V8QI])
5137 (define_mode_iterator V32I [SI V2HI V4QI])
5139 (define_expand "and<V64I:mode>3"
5140 [(set (match_operand:V64I 0 "register_operand" "")
5141 (and:V64I (match_operand:V64I 1 "arith_double_operand" "")
5142 (match_operand:V64I 2 "arith_double_operand" "")))]
5146 (define_insn "*and<V64I:mode>3_sp32"
5147 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5148 (and:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
5149 (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
5154 [(set_attr "type" "*,fga")
5155 (set_attr "length" "2,*")
5156 (set_attr "fptype" "*,double")])
5158 (define_insn "*and<V64I:mode>3_sp64"
5159 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5160 (and:V64I (match_operand:V64I 1 "arith_operand" "%r,b")
5161 (match_operand:V64I 2 "arith_operand" "rI,b")))]
5166 [(set_attr "type" "*,fga")
5167 (set_attr "fptype" "*,double")])
5169 (define_insn "and<V32I:mode>3"
5170 [(set (match_operand:V32I 0 "register_operand" "=r,d")
5171 (and:V32I (match_operand:V32I 1 "arith_operand" "%r,d")
5172 (match_operand:V32I 2 "arith_operand" "rI,d")))]
5177 [(set_attr "type" "*,fga")
5178 (set_attr "fptype" "*,single")])
5181 [(set (match_operand:SI 0 "register_operand" "")
5182 (and:SI (match_operand:SI 1 "register_operand" "")
5183 (match_operand:SI 2 "const_compl_high_operand" "")))
5184 (clobber (match_operand:SI 3 "register_operand" ""))]
5186 [(set (match_dup 3) (match_dup 4))
5187 (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 1)))]
5189 operands[4] = GEN_INT (~INTVAL (operands[2]));
5192 (define_insn_and_split "*and_not_<V64I:mode>_sp32"
5193 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5194 (and:V64I (not:V64I (match_operand:V64I 1 "register_operand" "%r,b"))
5195 (match_operand:V64I 2 "register_operand" "r,b")))]
5199 fandnot1\t%1, %2, %0"
5200 "&& reload_completed
5201 && ((GET_CODE (operands[0]) == REG
5202 && REGNO (operands[0]) < 32)
5203 || (GET_CODE (operands[0]) == SUBREG
5204 && GET_CODE (SUBREG_REG (operands[0])) == REG
5205 && REGNO (SUBREG_REG (operands[0])) < 32))"
5206 [(set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))
5207 (set (match_dup 6) (and:SI (not:SI (match_dup 7)) (match_dup 8)))]
5208 "operands[3] = gen_highpart (SImode, operands[0]);
5209 operands[4] = gen_highpart (SImode, operands[1]);
5210 operands[5] = gen_highpart (SImode, operands[2]);
5211 operands[6] = gen_lowpart (SImode, operands[0]);
5212 operands[7] = gen_lowpart (SImode, operands[1]);
5213 operands[8] = gen_lowpart (SImode, operands[2]);"
5214 [(set_attr "type" "*,fga")
5215 (set_attr "length" "2,*")
5216 (set_attr "fptype" "*,double")])
5218 (define_insn "*and_not_<V64I:mode>_sp64"
5219 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5220 (and:V64I (not:V64I (match_operand:V64I 1 "register_operand" "%r,b"))
5221 (match_operand:V64I 2 "register_operand" "r,b")))]
5225 fandnot1\t%1, %2, %0"
5226 [(set_attr "type" "*,fga")
5227 (set_attr "fptype" "*,double")])
5229 (define_insn "*and_not_<V32I:mode>"
5230 [(set (match_operand:V32I 0 "register_operand" "=r,d")
5231 (and:V32I (not:V32I (match_operand:V32I 1 "register_operand" "%r,d"))
5232 (match_operand:V32I 2 "register_operand" "r,d")))]
5236 fandnot1s\t%1, %2, %0"
5237 [(set_attr "type" "*,fga")
5238 (set_attr "fptype" "*,single")])
5240 (define_expand "ior<V64I:mode>3"
5241 [(set (match_operand:V64I 0 "register_operand" "")
5242 (ior:V64I (match_operand:V64I 1 "arith_double_operand" "")
5243 (match_operand:V64I 2 "arith_double_operand" "")))]
5247 (define_insn "*ior<V64I:mode>3_sp32"
5248 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5249 (ior:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
5250 (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
5255 [(set_attr "type" "*,fga")
5256 (set_attr "length" "2,*")
5257 (set_attr "fptype" "*,double")])
5259 (define_insn "*ior<V64I:mode>3_sp64"
5260 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5261 (ior:V64I (match_operand:V64I 1 "arith_operand" "%r,b")
5262 (match_operand:V64I 2 "arith_operand" "rI,b")))]
5267 [(set_attr "type" "*,fga")
5268 (set_attr "fptype" "*,double")])
5270 (define_insn "ior<V32I:mode>3"
5271 [(set (match_operand:V32I 0 "register_operand" "=r,d")
5272 (ior:V32I (match_operand:V32I 1 "arith_operand" "%r,d")
5273 (match_operand:V32I 2 "arith_operand" "rI,d")))]
5278 [(set_attr "type" "*,fga")
5279 (set_attr "fptype" "*,single")])
5282 [(set (match_operand:SI 0 "register_operand" "")
5283 (ior:SI (match_operand:SI 1 "register_operand" "")
5284 (match_operand:SI 2 "const_compl_high_operand" "")))
5285 (clobber (match_operand:SI 3 "register_operand" ""))]
5287 [(set (match_dup 3) (match_dup 4))
5288 (set (match_dup 0) (ior:SI (not:SI (match_dup 3)) (match_dup 1)))]
5290 operands[4] = GEN_INT (~INTVAL (operands[2]));
5293 (define_insn_and_split "*or_not_<V64I:mode>_sp32"
5294 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5295 (ior:V64I (not:V64I (match_operand:V64I 1 "register_operand" "r,b"))
5296 (match_operand:V64I 2 "register_operand" "r,b")))]
5300 fornot1\t%1, %2, %0"
5301 "&& reload_completed
5302 && ((GET_CODE (operands[0]) == REG
5303 && REGNO (operands[0]) < 32)
5304 || (GET_CODE (operands[0]) == SUBREG
5305 && GET_CODE (SUBREG_REG (operands[0])) == REG
5306 && REGNO (SUBREG_REG (operands[0])) < 32))"
5307 [(set (match_dup 3) (ior:SI (not:SI (match_dup 4)) (match_dup 5)))
5308 (set (match_dup 6) (ior:SI (not:SI (match_dup 7)) (match_dup 8)))]
5309 "operands[3] = gen_highpart (SImode, operands[0]);
5310 operands[4] = gen_highpart (SImode, operands[1]);
5311 operands[5] = gen_highpart (SImode, operands[2]);
5312 operands[6] = gen_lowpart (SImode, operands[0]);
5313 operands[7] = gen_lowpart (SImode, operands[1]);
5314 operands[8] = gen_lowpart (SImode, operands[2]);"
5315 [(set_attr "type" "*,fga")
5316 (set_attr "length" "2,*")
5317 (set_attr "fptype" "*,double")])
5319 (define_insn "*or_not_<V64I:mode>_sp64"
5320 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5321 (ior:V64I (not:V64I (match_operand:V64I 1 "register_operand" "r,b"))
5322 (match_operand:V64I 2 "register_operand" "r,b")))]
5326 fornot1\t%1, %2, %0"
5327 [(set_attr "type" "*,fga")
5328 (set_attr "fptype" "*,double")])
5330 (define_insn "*or_not_<V32I:mode>"
5331 [(set (match_operand:V32I 0 "register_operand" "=r,d")
5332 (ior:V32I (not:V32I (match_operand:V32I 1 "register_operand" "r,d"))
5333 (match_operand:V32I 2 "register_operand" "r,d")))]
5337 fornot1s\t%1, %2, %0"
5338 [(set_attr "type" "*,fga")
5339 (set_attr "fptype" "*,single")])
5341 (define_expand "xor<V64I:mode>3"
5342 [(set (match_operand:V64I 0 "register_operand" "")
5343 (xor:V64I (match_operand:V64I 1 "arith_double_operand" "")
5344 (match_operand:V64I 2 "arith_double_operand" "")))]
5348 (define_insn "*xor<V64I:mode>3_sp32"
5349 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5350 (xor:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
5351 (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
5356 [(set_attr "type" "*,fga")
5357 (set_attr "length" "2,*")
5358 (set_attr "fptype" "*,double")])
5360 (define_insn "*xor<V64I:mode>3_sp64"
5361 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5362 (xor:V64I (match_operand:V64I 1 "arith_operand" "%rJ,b")
5363 (match_operand:V64I 2 "arith_operand" "rI,b")))]
5368 [(set_attr "type" "*,fga")
5369 (set_attr "fptype" "*,double")])
5371 (define_insn "xor<V32I:mode>3"
5372 [(set (match_operand:V32I 0 "register_operand" "=r,d")
5373 (xor:V32I (match_operand:V32I 1 "arith_operand" "%rJ,d")
5374 (match_operand:V32I 2 "arith_operand" "rI,d")))]
5379 [(set_attr "type" "*,fga")
5380 (set_attr "fptype" "*,single")])
5383 [(set (match_operand:SI 0 "register_operand" "")
5384 (xor:SI (match_operand:SI 1 "register_operand" "")
5385 (match_operand:SI 2 "const_compl_high_operand" "")))
5386 (clobber (match_operand:SI 3 "register_operand" ""))]
5388 [(set (match_dup 3) (match_dup 4))
5389 (set (match_dup 0) (not:SI (xor:SI (match_dup 3) (match_dup 1))))]
5391 operands[4] = GEN_INT (~INTVAL (operands[2]));
5395 [(set (match_operand:SI 0 "register_operand" "")
5396 (not:SI (xor:SI (match_operand:SI 1 "register_operand" "")
5397 (match_operand:SI 2 "const_compl_high_operand" ""))))
5398 (clobber (match_operand:SI 3 "register_operand" ""))]
5400 [(set (match_dup 3) (match_dup 4))
5401 (set (match_dup 0) (xor:SI (match_dup 3) (match_dup 1)))]
5403 operands[4] = GEN_INT (~INTVAL (operands[2]));
5406 ;; Split DImode logical operations requiring two instructions.
5408 [(set (match_operand:V64I 0 "register_operand" "")
5409 (match_operator:V64I 1 "cc_arith_operator" ; AND, IOR, XOR
5410 [(match_operand:V64I 2 "register_operand" "")
5411 (match_operand:V64I 3 "arith_double_operand" "")]))]
5414 && ((GET_CODE (operands[0]) == REG
5415 && REGNO (operands[0]) < 32)
5416 || (GET_CODE (operands[0]) == SUBREG
5417 && GET_CODE (SUBREG_REG (operands[0])) == REG
5418 && REGNO (SUBREG_REG (operands[0])) < 32))"
5419 [(set (match_dup 4) (match_op_dup:SI 1 [(match_dup 6) (match_dup 8)]))
5420 (set (match_dup 5) (match_op_dup:SI 1 [(match_dup 7) (match_dup 9)]))]
5422 operands[4] = gen_highpart (SImode, operands[0]);
5423 operands[5] = gen_lowpart (SImode, operands[0]);
5424 operands[6] = gen_highpart (SImode, operands[2]);
5425 operands[7] = gen_lowpart (SImode, operands[2]);
5426 #if HOST_BITS_PER_WIDE_INT == 32
5427 if (GET_CODE (operands[3]) == CONST_INT && <V64I:MODE>mode == DImode)
5429 if (INTVAL (operands[3]) < 0)
5430 operands[8] = constm1_rtx;
5432 operands[8] = const0_rtx;
5436 operands[8] = gen_highpart_mode (SImode, <V64I:MODE>mode, operands[3]);
5437 operands[9] = gen_lowpart (SImode, operands[3]);
5440 ;; xnor patterns. Note that (a ^ ~b) == (~a ^ b) == ~(a ^ b).
5441 ;; Combine now canonicalizes to the rightmost expression.
5442 (define_insn_and_split "*xor_not_<V64I:mode>_sp32"
5443 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5444 (not:V64I (xor:V64I (match_operand:V64I 1 "register_operand" "r,b")
5445 (match_operand:V64I 2 "register_operand" "r,b"))))]
5450 "&& reload_completed
5451 && ((GET_CODE (operands[0]) == REG
5452 && REGNO (operands[0]) < 32)
5453 || (GET_CODE (operands[0]) == SUBREG
5454 && GET_CODE (SUBREG_REG (operands[0])) == REG
5455 && REGNO (SUBREG_REG (operands[0])) < 32))"
5456 [(set (match_dup 3) (not:SI (xor:SI (match_dup 4) (match_dup 5))))
5457 (set (match_dup 6) (not:SI (xor:SI (match_dup 7) (match_dup 8))))]
5458 "operands[3] = gen_highpart (SImode, operands[0]);
5459 operands[4] = gen_highpart (SImode, operands[1]);
5460 operands[5] = gen_highpart (SImode, operands[2]);
5461 operands[6] = gen_lowpart (SImode, operands[0]);
5462 operands[7] = gen_lowpart (SImode, operands[1]);
5463 operands[8] = gen_lowpart (SImode, operands[2]);"
5464 [(set_attr "type" "*,fga")
5465 (set_attr "length" "2,*")
5466 (set_attr "fptype" "*,double")])
5468 (define_insn "*xor_not_<V64I:mode>_sp64"
5469 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5470 (not:V64I (xor:V64I (match_operand:V64I 1 "register_or_zero_operand" "rJ,b")
5471 (match_operand:V64I 2 "arith_operand" "rI,b"))))]
5476 [(set_attr "type" "*,fga")
5477 (set_attr "fptype" "*,double")])
5479 (define_insn "*xor_not_<V32I:mode>"
5480 [(set (match_operand:V32I 0 "register_operand" "=r,d")
5481 (not:V32I (xor:V32I (match_operand:V32I 1 "register_or_zero_operand" "rJ,d")
5482 (match_operand:V32I 2 "arith_operand" "rI,d"))))]
5487 [(set_attr "type" "*,fga")
5488 (set_attr "fptype" "*,single")])
5490 ;; These correspond to the above in the case where we also (or only)
5491 ;; want to set the condition code.
5493 (define_insn "*cmp_cc_arith_op"
5496 (match_operator:SI 2 "cc_arith_operator"
5497 [(match_operand:SI 0 "arith_operand" "%r")
5498 (match_operand:SI 1 "arith_operand" "rI")])
5501 "%A2cc\t%0, %1, %%g0"
5502 [(set_attr "type" "compare")])
5504 (define_insn "*cmp_ccx_arith_op"
5507 (match_operator:DI 2 "cc_arith_operator"
5508 [(match_operand:DI 0 "arith_operand" "%r")
5509 (match_operand:DI 1 "arith_operand" "rI")])
5512 "%A2cc\t%0, %1, %%g0"
5513 [(set_attr "type" "compare")])
5515 (define_insn "*cmp_cc_arith_op_set"
5518 (match_operator:SI 3 "cc_arith_operator"
5519 [(match_operand:SI 1 "arith_operand" "%r")
5520 (match_operand:SI 2 "arith_operand" "rI")])
5522 (set (match_operand:SI 0 "register_operand" "=r")
5523 (match_operator:SI 4 "cc_arith_operator" [(match_dup 1) (match_dup 2)]))]
5524 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
5526 [(set_attr "type" "compare")])
5528 (define_insn "*cmp_ccx_arith_op_set"
5531 (match_operator:DI 3 "cc_arith_operator"
5532 [(match_operand:DI 1 "arith_operand" "%r")
5533 (match_operand:DI 2 "arith_operand" "rI")])
5535 (set (match_operand:DI 0 "register_operand" "=r")
5536 (match_operator:DI 4 "cc_arith_operator" [(match_dup 1) (match_dup 2)]))]
5537 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
5539 [(set_attr "type" "compare")])
5541 (define_insn "*cmp_cc_xor_not"
5544 (not:SI (xor:SI (match_operand:SI 0 "register_or_zero_operand" "%rJ")
5545 (match_operand:SI 1 "arith_operand" "rI")))
5548 "xnorcc\t%r0, %1, %%g0"
5549 [(set_attr "type" "compare")])
5551 (define_insn "*cmp_ccx_xor_not"
5554 (not:DI (xor:DI (match_operand:DI 0 "register_or_zero_operand" "%rJ")
5555 (match_operand:DI 1 "arith_operand" "rI")))
5558 "xnorcc\t%r0, %1, %%g0"
5559 [(set_attr "type" "compare")])
5561 (define_insn "*cmp_cc_xor_not_set"
5564 (not:SI (xor:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ")
5565 (match_operand:SI 2 "arith_operand" "rI")))
5567 (set (match_operand:SI 0 "register_operand" "=r")
5568 (not:SI (xor:SI (match_dup 1) (match_dup 2))))]
5570 "xnorcc\t%r1, %2, %0"
5571 [(set_attr "type" "compare")])
5573 (define_insn "*cmp_ccx_xor_not_set"
5576 (not:DI (xor:DI (match_operand:DI 1 "register_or_zero_operand" "%rJ")
5577 (match_operand:DI 2 "arith_operand" "rI")))
5579 (set (match_operand:DI 0 "register_operand" "=r")
5580 (not:DI (xor:DI (match_dup 1) (match_dup 2))))]
5582 "xnorcc\t%r1, %2, %0"
5583 [(set_attr "type" "compare")])
5585 (define_insn "*cmp_cc_arith_op_not"
5588 (match_operator:SI 2 "cc_arith_not_operator"
5589 [(not:SI (match_operand:SI 0 "arith_operand" "rI"))
5590 (match_operand:SI 1 "register_or_zero_operand" "rJ")])
5593 "%B2cc\t%r1, %0, %%g0"
5594 [(set_attr "type" "compare")])
5596 (define_insn "*cmp_ccx_arith_op_not"
5599 (match_operator:DI 2 "cc_arith_not_operator"
5600 [(not:DI (match_operand:DI 0 "arith_operand" "rI"))
5601 (match_operand:DI 1 "register_or_zero_operand" "rJ")])
5604 "%B2cc\t%r1, %0, %%g0"
5605 [(set_attr "type" "compare")])
5607 (define_insn "*cmp_cc_arith_op_not_set"
5610 (match_operator:SI 3 "cc_arith_not_operator"
5611 [(not:SI (match_operand:SI 1 "arith_operand" "rI"))
5612 (match_operand:SI 2 "register_or_zero_operand" "rJ")])
5614 (set (match_operand:SI 0 "register_operand" "=r")
5615 (match_operator:SI 4 "cc_arith_not_operator"
5616 [(not:SI (match_dup 1)) (match_dup 2)]))]
5617 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
5618 "%B3cc\t%r2, %1, %0"
5619 [(set_attr "type" "compare")])
5621 (define_insn "*cmp_ccx_arith_op_not_set"
5624 (match_operator:DI 3 "cc_arith_not_operator"
5625 [(not:DI (match_operand:DI 1 "arith_operand" "rI"))
5626 (match_operand:DI 2 "register_or_zero_operand" "rJ")])
5628 (set (match_operand:DI 0 "register_operand" "=r")
5629 (match_operator:DI 4 "cc_arith_not_operator"
5630 [(not:DI (match_dup 1)) (match_dup 2)]))]
5631 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
5632 "%B3cc\t%r2, %1, %0"
5633 [(set_attr "type" "compare")])
5635 ;; We cannot use the "neg" pseudo insn because the Sun assembler
5636 ;; does not know how to make it work for constants.
5638 (define_expand "negdi2"
5639 [(set (match_operand:DI 0 "register_operand" "=r")
5640 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
5643 if (! TARGET_ARCH64)
5645 emit_insn (gen_rtx_PARALLEL
5648 gen_rtx_SET (VOIDmode, operand0,
5649 gen_rtx_NEG (DImode, operand1)),
5650 gen_rtx_CLOBBER (VOIDmode,
5651 gen_rtx_REG (CCmode,
5657 (define_insn_and_split "*negdi2_sp32"
5658 [(set (match_operand:DI 0 "register_operand" "=r")
5659 (neg:DI (match_operand:DI 1 "register_operand" "r")))
5660 (clobber (reg:CC 100))]
5663 "&& reload_completed"
5664 [(parallel [(set (reg:CC_NOOV 100)
5665 (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 5))
5667 (set (match_dup 4) (minus:SI (const_int 0) (match_dup 5)))])
5668 (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
5669 (ltu:SI (reg:CC 100) (const_int 0))))]
5670 "operands[2] = gen_highpart (SImode, operands[0]);
5671 operands[3] = gen_highpart (SImode, operands[1]);
5672 operands[4] = gen_lowpart (SImode, operands[0]);
5673 operands[5] = gen_lowpart (SImode, operands[1]);"
5674 [(set_attr "length" "2")])
5676 (define_insn "*negdi2_sp64"
5677 [(set (match_operand:DI 0 "register_operand" "=r")
5678 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
5680 "sub\t%%g0, %1, %0")
5682 (define_insn "negsi2"
5683 [(set (match_operand:SI 0 "register_operand" "=r")
5684 (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
5686 "sub\t%%g0, %1, %0")
5688 (define_insn "*cmp_cc_neg"
5689 [(set (reg:CC_NOOV 100)
5690 (compare:CC_NOOV (neg:SI (match_operand:SI 0 "arith_operand" "rI"))
5693 "subcc\t%%g0, %0, %%g0"
5694 [(set_attr "type" "compare")])
5696 (define_insn "*cmp_ccx_neg"
5697 [(set (reg:CCX_NOOV 100)
5698 (compare:CCX_NOOV (neg:DI (match_operand:DI 0 "arith_operand" "rI"))
5701 "subcc\t%%g0, %0, %%g0"
5702 [(set_attr "type" "compare")])
5704 (define_insn "*cmp_cc_set_neg"
5705 [(set (reg:CC_NOOV 100)
5706 (compare:CC_NOOV (neg:SI (match_operand:SI 1 "arith_operand" "rI"))
5708 (set (match_operand:SI 0 "register_operand" "=r")
5709 (neg:SI (match_dup 1)))]
5711 "subcc\t%%g0, %1, %0"
5712 [(set_attr "type" "compare")])
5714 (define_insn "*cmp_ccx_set_neg"
5715 [(set (reg:CCX_NOOV 100)
5716 (compare:CCX_NOOV (neg:DI (match_operand:DI 1 "arith_operand" "rI"))
5718 (set (match_operand:DI 0 "register_operand" "=r")
5719 (neg:DI (match_dup 1)))]
5721 "subcc\t%%g0, %1, %0"
5722 [(set_attr "type" "compare")])
5724 ;; We cannot use the "not" pseudo insn because the Sun assembler
5725 ;; does not know how to make it work for constants.
5726 (define_expand "one_cmpl<V64I:mode>2"
5727 [(set (match_operand:V64I 0 "register_operand" "")
5728 (not:V64I (match_operand:V64I 1 "register_operand" "")))]
5732 (define_insn_and_split "*one_cmpl<V64I:mode>2_sp32"
5733 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5734 (not:V64I (match_operand:V64I 1 "register_operand" "r,b")))]
5739 "&& reload_completed
5740 && ((GET_CODE (operands[0]) == REG
5741 && REGNO (operands[0]) < 32)
5742 || (GET_CODE (operands[0]) == SUBREG
5743 && GET_CODE (SUBREG_REG (operands[0])) == REG
5744 && REGNO (SUBREG_REG (operands[0])) < 32))"
5745 [(set (match_dup 2) (not:SI (xor:SI (match_dup 3) (const_int 0))))
5746 (set (match_dup 4) (not:SI (xor:SI (match_dup 5) (const_int 0))))]
5747 "operands[2] = gen_highpart (SImode, operands[0]);
5748 operands[3] = gen_highpart (SImode, operands[1]);
5749 operands[4] = gen_lowpart (SImode, operands[0]);
5750 operands[5] = gen_lowpart (SImode, operands[1]);"
5751 [(set_attr "type" "*,fga")
5752 (set_attr "length" "2,*")
5753 (set_attr "fptype" "*,double")])
5755 (define_insn "*one_cmpl<V64I:mode>2_sp64"
5756 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5757 (not:V64I (match_operand:V64I 1 "arith_operand" "rI,b")))]
5762 [(set_attr "type" "*,fga")
5763 (set_attr "fptype" "*,double")])
5765 (define_insn "one_cmpl<V32I:mode>2"
5766 [(set (match_operand:V32I 0 "register_operand" "=r,d")
5767 (not:V32I (match_operand:V32I 1 "arith_operand" "rI,d")))]
5772 [(set_attr "type" "*,fga")
5773 (set_attr "fptype" "*,single")])
5775 (define_insn "*cmp_cc_not"
5777 (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI"))
5780 "xnorcc\t%%g0, %0, %%g0"
5781 [(set_attr "type" "compare")])
5783 (define_insn "*cmp_ccx_not"
5785 (compare:CCX (not:DI (match_operand:DI 0 "arith_operand" "rI"))
5788 "xnorcc\t%%g0, %0, %%g0"
5789 [(set_attr "type" "compare")])
5791 (define_insn "*cmp_cc_set_not"
5793 (compare:CC (not:SI (match_operand:SI 1 "arith_operand" "rI"))
5795 (set (match_operand:SI 0 "register_operand" "=r")
5796 (not:SI (match_dup 1)))]
5798 "xnorcc\t%%g0, %1, %0"
5799 [(set_attr "type" "compare")])
5801 (define_insn "*cmp_ccx_set_not"
5803 (compare:CCX (not:DI (match_operand:DI 1 "arith_operand" "rI"))
5805 (set (match_operand:DI 0 "register_operand" "=r")
5806 (not:DI (match_dup 1)))]
5808 "xnorcc\t%%g0, %1, %0"
5809 [(set_attr "type" "compare")])
5811 (define_insn "*cmp_cc_set"
5812 [(set (match_operand:SI 0 "register_operand" "=r")
5813 (match_operand:SI 1 "register_operand" "r"))
5815 (compare:CC (match_dup 1)
5819 [(set_attr "type" "compare")])
5821 (define_insn "*cmp_ccx_set64"
5822 [(set (match_operand:DI 0 "register_operand" "=r")
5823 (match_operand:DI 1 "register_operand" "r"))
5825 (compare:CCX (match_dup 1)
5829 [(set_attr "type" "compare")])
5832 ;; Floating point arithmetic instructions.
5834 (define_expand "addtf3"
5835 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5836 (plus:TF (match_operand:TF 1 "general_operand" "")
5837 (match_operand:TF 2 "general_operand" "")))]
5838 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5839 "emit_tfmode_binop (PLUS, operands); DONE;")
5841 (define_insn "*addtf3_hq"
5842 [(set (match_operand:TF 0 "register_operand" "=e")
5843 (plus:TF (match_operand:TF 1 "register_operand" "e")
5844 (match_operand:TF 2 "register_operand" "e")))]
5845 "TARGET_FPU && TARGET_HARD_QUAD"
5847 [(set_attr "type" "fp")])
5849 (define_insn "adddf3"
5850 [(set (match_operand:DF 0 "register_operand" "=e")
5851 (plus:DF (match_operand:DF 1 "register_operand" "e")
5852 (match_operand:DF 2 "register_operand" "e")))]
5855 [(set_attr "type" "fp")
5856 (set_attr "fptype" "double")])
5858 (define_insn "addsf3"
5859 [(set (match_operand:SF 0 "register_operand" "=f")
5860 (plus:SF (match_operand:SF 1 "register_operand" "f")
5861 (match_operand:SF 2 "register_operand" "f")))]
5864 [(set_attr "type" "fp")])
5866 (define_expand "subtf3"
5867 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5868 (minus:TF (match_operand:TF 1 "general_operand" "")
5869 (match_operand:TF 2 "general_operand" "")))]
5870 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5871 "emit_tfmode_binop (MINUS, operands); DONE;")
5873 (define_insn "*subtf3_hq"
5874 [(set (match_operand:TF 0 "register_operand" "=e")
5875 (minus:TF (match_operand:TF 1 "register_operand" "e")
5876 (match_operand:TF 2 "register_operand" "e")))]
5877 "TARGET_FPU && TARGET_HARD_QUAD"
5879 [(set_attr "type" "fp")])
5881 (define_insn "subdf3"
5882 [(set (match_operand:DF 0 "register_operand" "=e")
5883 (minus:DF (match_operand:DF 1 "register_operand" "e")
5884 (match_operand:DF 2 "register_operand" "e")))]
5887 [(set_attr "type" "fp")
5888 (set_attr "fptype" "double")])
5890 (define_insn "subsf3"
5891 [(set (match_operand:SF 0 "register_operand" "=f")
5892 (minus:SF (match_operand:SF 1 "register_operand" "f")
5893 (match_operand:SF 2 "register_operand" "f")))]
5896 [(set_attr "type" "fp")])
5898 (define_expand "multf3"
5899 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5900 (mult:TF (match_operand:TF 1 "general_operand" "")
5901 (match_operand:TF 2 "general_operand" "")))]
5902 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5903 "emit_tfmode_binop (MULT, operands); DONE;")
5905 (define_insn "*multf3_hq"
5906 [(set (match_operand:TF 0 "register_operand" "=e")
5907 (mult:TF (match_operand:TF 1 "register_operand" "e")
5908 (match_operand:TF 2 "register_operand" "e")))]
5909 "TARGET_FPU && TARGET_HARD_QUAD"
5911 [(set_attr "type" "fpmul")])
5913 (define_insn "muldf3"
5914 [(set (match_operand:DF 0 "register_operand" "=e")
5915 (mult:DF (match_operand:DF 1 "register_operand" "e")
5916 (match_operand:DF 2 "register_operand" "e")))]
5919 [(set_attr "type" "fpmul")
5920 (set_attr "fptype" "double")])
5922 (define_insn "mulsf3"
5923 [(set (match_operand:SF 0 "register_operand" "=f")
5924 (mult:SF (match_operand:SF 1 "register_operand" "f")
5925 (match_operand:SF 2 "register_operand" "f")))]
5928 [(set_attr "type" "fpmul")])
5930 (define_insn "*muldf3_extend"
5931 [(set (match_operand:DF 0 "register_operand" "=e")
5932 (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "f"))
5933 (float_extend:DF (match_operand:SF 2 "register_operand" "f"))))]
5934 "(TARGET_V8 || TARGET_V9) && TARGET_FPU"
5935 "fsmuld\t%1, %2, %0"
5936 [(set_attr "type" "fpmul")
5937 (set_attr "fptype" "double")])
5939 (define_insn "*multf3_extend"
5940 [(set (match_operand:TF 0 "register_operand" "=e")
5941 (mult:TF (float_extend:TF (match_operand:DF 1 "register_operand" "e"))
5942 (float_extend:TF (match_operand:DF 2 "register_operand" "e"))))]
5943 "(TARGET_V8 || TARGET_V9) && TARGET_FPU && TARGET_HARD_QUAD"
5944 "fdmulq\t%1, %2, %0"
5945 [(set_attr "type" "fpmul")])
5947 (define_expand "divtf3"
5948 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5949 (div:TF (match_operand:TF 1 "general_operand" "")
5950 (match_operand:TF 2 "general_operand" "")))]
5951 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5952 "emit_tfmode_binop (DIV, operands); DONE;")
5954 ;; don't have timing for quad-prec. divide.
5955 (define_insn "*divtf3_hq"
5956 [(set (match_operand:TF 0 "register_operand" "=e")
5957 (div:TF (match_operand:TF 1 "register_operand" "e")
5958 (match_operand:TF 2 "register_operand" "e")))]
5959 "TARGET_FPU && TARGET_HARD_QUAD"
5961 [(set_attr "type" "fpdivd")])
5963 (define_insn "divdf3"
5964 [(set (match_operand:DF 0 "register_operand" "=e")
5965 (div:DF (match_operand:DF 1 "register_operand" "e")
5966 (match_operand:DF 2 "register_operand" "e")))]
5969 [(set_attr "type" "fpdivd")
5970 (set_attr "fptype" "double")])
5972 (define_insn "divsf3"
5973 [(set (match_operand:SF 0 "register_operand" "=f")
5974 (div:SF (match_operand:SF 1 "register_operand" "f")
5975 (match_operand:SF 2 "register_operand" "f")))]
5978 [(set_attr "type" "fpdivs")])
5980 (define_expand "negtf2"
5981 [(set (match_operand:TF 0 "register_operand" "=e,e")
5982 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
5986 (define_insn_and_split "*negtf2_notv9"
5987 [(set (match_operand:TF 0 "register_operand" "=e,e")
5988 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
5989 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
5995 "&& reload_completed
5996 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5997 [(set (match_dup 2) (neg:SF (match_dup 3)))
5998 (set (match_dup 4) (match_dup 5))
5999 (set (match_dup 6) (match_dup 7))]
6000 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6001 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6002 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6003 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
6004 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6005 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6006 [(set_attr "type" "fpmove,*")
6007 (set_attr "length" "*,2")])
6009 (define_insn_and_split "*negtf2_v9"
6010 [(set (match_operand:TF 0 "register_operand" "=e,e")
6011 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
6012 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
6013 "TARGET_FPU && TARGET_V9"
6017 "&& reload_completed
6018 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6019 [(set (match_dup 2) (neg:DF (match_dup 3)))
6020 (set (match_dup 4) (match_dup 5))]
6021 "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
6022 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
6023 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6024 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6025 [(set_attr "type" "fpmove,*")
6026 (set_attr "length" "*,2")
6027 (set_attr "fptype" "double")])
6029 (define_expand "negdf2"
6030 [(set (match_operand:DF 0 "register_operand" "")
6031 (neg:DF (match_operand:DF 1 "register_operand" "")))]
6035 (define_insn_and_split "*negdf2_notv9"
6036 [(set (match_operand:DF 0 "register_operand" "=e,e")
6037 (neg:DF (match_operand:DF 1 "register_operand" "0,e")))]
6038 "TARGET_FPU && ! TARGET_V9"
6042 "&& reload_completed
6043 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6044 [(set (match_dup 2) (neg:SF (match_dup 3)))
6045 (set (match_dup 4) (match_dup 5))]
6046 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6047 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6048 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6049 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);"
6050 [(set_attr "type" "fpmove,*")
6051 (set_attr "length" "*,2")])
6053 (define_insn "*negdf2_v9"
6054 [(set (match_operand:DF 0 "register_operand" "=e")
6055 (neg:DF (match_operand:DF 1 "register_operand" "e")))]
6056 "TARGET_FPU && TARGET_V9"
6058 [(set_attr "type" "fpmove")
6059 (set_attr "fptype" "double")])
6061 (define_insn "negsf2"
6062 [(set (match_operand:SF 0 "register_operand" "=f")
6063 (neg:SF (match_operand:SF 1 "register_operand" "f")))]
6066 [(set_attr "type" "fpmove")])
6068 (define_expand "abstf2"
6069 [(set (match_operand:TF 0 "register_operand" "")
6070 (abs:TF (match_operand:TF 1 "register_operand" "")))]
6074 (define_insn_and_split "*abstf2_notv9"
6075 [(set (match_operand:TF 0 "register_operand" "=e,e")
6076 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6077 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
6078 "TARGET_FPU && ! TARGET_V9"
6082 "&& reload_completed
6083 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6084 [(set (match_dup 2) (abs:SF (match_dup 3)))
6085 (set (match_dup 4) (match_dup 5))
6086 (set (match_dup 6) (match_dup 7))]
6087 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6088 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6089 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6090 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
6091 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6092 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6093 [(set_attr "type" "fpmove,*")
6094 (set_attr "length" "*,2")])
6096 (define_insn "*abstf2_hq_v9"
6097 [(set (match_operand:TF 0 "register_operand" "=e,e")
6098 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6099 "TARGET_FPU && TARGET_V9 && TARGET_HARD_QUAD"
6103 [(set_attr "type" "fpmove")
6104 (set_attr "fptype" "double,*")])
6106 (define_insn_and_split "*abstf2_v9"
6107 [(set (match_operand:TF 0 "register_operand" "=e,e")
6108 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6109 "TARGET_FPU && TARGET_V9 && !TARGET_HARD_QUAD"
6113 "&& reload_completed
6114 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6115 [(set (match_dup 2) (abs:DF (match_dup 3)))
6116 (set (match_dup 4) (match_dup 5))]
6117 "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
6118 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
6119 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6120 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6121 [(set_attr "type" "fpmove,*")
6122 (set_attr "length" "*,2")
6123 (set_attr "fptype" "double,*")])
6125 (define_expand "absdf2"
6126 [(set (match_operand:DF 0 "register_operand" "")
6127 (abs:DF (match_operand:DF 1 "register_operand" "")))]
6131 (define_insn_and_split "*absdf2_notv9"
6132 [(set (match_operand:DF 0 "register_operand" "=e,e")
6133 (abs:DF (match_operand:DF 1 "register_operand" "0,e")))]
6134 "TARGET_FPU && ! TARGET_V9"
6138 "&& reload_completed
6139 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6140 [(set (match_dup 2) (abs:SF (match_dup 3)))
6141 (set (match_dup 4) (match_dup 5))]
6142 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6143 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6144 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6145 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);"
6146 [(set_attr "type" "fpmove,*")
6147 (set_attr "length" "*,2")])
6149 (define_insn "*absdf2_v9"
6150 [(set (match_operand:DF 0 "register_operand" "=e")
6151 (abs:DF (match_operand:DF 1 "register_operand" "e")))]
6152 "TARGET_FPU && TARGET_V9"
6154 [(set_attr "type" "fpmove")
6155 (set_attr "fptype" "double")])
6157 (define_insn "abssf2"
6158 [(set (match_operand:SF 0 "register_operand" "=f")
6159 (abs:SF (match_operand:SF 1 "register_operand" "f")))]
6162 [(set_attr "type" "fpmove")])
6164 (define_expand "sqrttf2"
6165 [(set (match_operand:TF 0 "nonimmediate_operand" "")
6166 (sqrt:TF (match_operand:TF 1 "general_operand" "")))]
6167 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6168 "emit_tfmode_unop (SQRT, operands); DONE;")
6170 (define_insn "*sqrttf2_hq"
6171 [(set (match_operand:TF 0 "register_operand" "=e")
6172 (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
6173 "TARGET_FPU && TARGET_HARD_QUAD"
6175 [(set_attr "type" "fpsqrtd")])
6177 (define_insn "sqrtdf2"
6178 [(set (match_operand:DF 0 "register_operand" "=e")
6179 (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
6182 [(set_attr "type" "fpsqrtd")
6183 (set_attr "fptype" "double")])
6185 (define_insn "sqrtsf2"
6186 [(set (match_operand:SF 0 "register_operand" "=f")
6187 (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
6190 [(set_attr "type" "fpsqrts")])
6193 ;; Arithmetic shift instructions.
6195 (define_insn "ashlsi3"
6196 [(set (match_operand:SI 0 "register_operand" "=r")
6197 (ashift:SI (match_operand:SI 1 "register_operand" "r")
6198 (match_operand:SI 2 "arith_operand" "rI")))]
6201 if (GET_CODE (operands[2]) == CONST_INT)
6202 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6203 return "sll\t%1, %2, %0";
6206 (if_then_else (match_operand 2 "const_one_operand" "")
6207 (const_string "ialu") (const_string "shift")))])
6209 (define_expand "ashldi3"
6210 [(set (match_operand:DI 0 "register_operand" "=r")
6211 (ashift:DI (match_operand:DI 1 "register_operand" "r")
6212 (match_operand:SI 2 "arith_operand" "rI")))]
6213 "TARGET_ARCH64 || TARGET_V8PLUS"
6215 if (! TARGET_ARCH64)
6217 if (GET_CODE (operands[2]) == CONST_INT)
6219 emit_insn (gen_ashldi3_v8plus (operands[0], operands[1], operands[2]));
6224 (define_insn "*ashldi3_sp64"
6225 [(set (match_operand:DI 0 "register_operand" "=r")
6226 (ashift:DI (match_operand:DI 1 "register_operand" "r")
6227 (match_operand:SI 2 "arith_operand" "rI")))]
6230 if (GET_CODE (operands[2]) == CONST_INT)
6231 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
6232 return "sllx\t%1, %2, %0";
6235 (if_then_else (match_operand 2 "const_one_operand" "")
6236 (const_string "ialu") (const_string "shift")))])
6239 (define_insn "ashldi3_v8plus"
6240 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
6241 (ashift:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
6242 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
6243 (clobber (match_scratch:SI 3 "=X,X,&h"))]
6245 "* return output_v8plus_shift (operands, insn, \"sllx\");"
6246 [(set_attr "type" "multi")
6247 (set_attr "length" "5,5,6")])
6249 ;; Optimize (1LL<<x)-1
6250 ;; XXX this also needs to be fixed to handle equal subregs
6251 ;; XXX first before we could re-enable it.
6253 ; [(set (match_operand:DI 0 "register_operand" "=h")
6254 ; (plus:DI (ashift:DI (const_int 1)
6255 ; (match_operand:SI 1 "arith_operand" "rI"))
6257 ; "0 && TARGET_V8PLUS"
6259 ; if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == REGNO (operands[0]))
6260 ; return "mov\t1, %L0\;sllx\t%L0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
6261 ; return "mov\t1, %H0\;sllx\t%H0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
6263 ; [(set_attr "type" "multi")
6264 ; (set_attr "length" "4")])
6266 (define_insn "*cmp_cc_ashift_1"
6267 [(set (reg:CC_NOOV 100)
6268 (compare:CC_NOOV (ashift:SI (match_operand:SI 0 "register_operand" "r")
6272 "addcc\t%0, %0, %%g0"
6273 [(set_attr "type" "compare")])
6275 (define_insn "*cmp_cc_set_ashift_1"
6276 [(set (reg:CC_NOOV 100)
6277 (compare:CC_NOOV (ashift:SI (match_operand:SI 1 "register_operand" "r")
6280 (set (match_operand:SI 0 "register_operand" "=r")
6281 (ashift:SI (match_dup 1) (const_int 1)))]
6284 [(set_attr "type" "compare")])
6286 (define_insn "ashrsi3"
6287 [(set (match_operand:SI 0 "register_operand" "=r")
6288 (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
6289 (match_operand:SI 2 "arith_operand" "rI")))]
6292 if (GET_CODE (operands[2]) == CONST_INT)
6293 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6294 return "sra\t%1, %2, %0";
6296 [(set_attr "type" "shift")])
6298 (define_insn "*ashrsi3_extend"
6299 [(set (match_operand:DI 0 "register_operand" "=r")
6300 (sign_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
6301 (match_operand:SI 2 "arith_operand" "r"))))]
6304 [(set_attr "type" "shift")])
6306 ;; This handles the case as above, but with constant shift instead of
6307 ;; register. Combiner "simplifies" it for us a little bit though.
6308 (define_insn "*ashrsi3_extend2"
6309 [(set (match_operand:DI 0 "register_operand" "=r")
6310 (ashiftrt:DI (ashift:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
6312 (match_operand:SI 2 "small_int_operand" "I")))]
6313 "TARGET_ARCH64 && INTVAL (operands[2]) >= 32 && INTVAL (operands[2]) < 64"
6315 operands[2] = GEN_INT (INTVAL (operands[2]) - 32);
6316 return "sra\t%1, %2, %0";
6318 [(set_attr "type" "shift")])
6320 (define_expand "ashrdi3"
6321 [(set (match_operand:DI 0 "register_operand" "=r")
6322 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
6323 (match_operand:SI 2 "arith_operand" "rI")))]
6324 "TARGET_ARCH64 || TARGET_V8PLUS"
6326 if (! TARGET_ARCH64)
6328 if (GET_CODE (operands[2]) == CONST_INT)
6329 FAIL; /* prefer generic code in this case */
6330 emit_insn (gen_ashrdi3_v8plus (operands[0], operands[1], operands[2]));
6335 (define_insn "*ashrdi3_sp64"
6336 [(set (match_operand:DI 0 "register_operand" "=r")
6337 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
6338 (match_operand:SI 2 "arith_operand" "rI")))]
6342 if (GET_CODE (operands[2]) == CONST_INT)
6343 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
6344 return "srax\t%1, %2, %0";
6346 [(set_attr "type" "shift")])
6349 (define_insn "ashrdi3_v8plus"
6350 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
6351 (ashiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
6352 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
6353 (clobber (match_scratch:SI 3 "=X,X,&h"))]
6355 "* return output_v8plus_shift (operands, insn, \"srax\");"
6356 [(set_attr "type" "multi")
6357 (set_attr "length" "5,5,6")])
6359 (define_insn "lshrsi3"
6360 [(set (match_operand:SI 0 "register_operand" "=r")
6361 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
6362 (match_operand:SI 2 "arith_operand" "rI")))]
6365 if (GET_CODE (operands[2]) == CONST_INT)
6366 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6367 return "srl\t%1, %2, %0";
6369 [(set_attr "type" "shift")])
6371 ;; This handles the case where
6372 ;; (zero_extend:DI (lshiftrt:SI (match_operand:SI) (match_operand:SI))),
6373 ;; but combiner "simplifies" it for us.
6374 (define_insn "*lshrsi3_extend"
6375 [(set (match_operand:DI 0 "register_operand" "=r")
6376 (and:DI (subreg:DI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
6377 (match_operand:SI 2 "arith_operand" "r")) 0)
6378 (match_operand 3 "const_int_operand" "")))]
6379 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) == 0xffffffff"
6381 [(set_attr "type" "shift")])
6383 ;; This handles the case where
6384 ;; (lshiftrt:DI (zero_extend:DI (match_operand:SI)) (const_int >=0 < 32))
6385 ;; but combiner "simplifies" it for us.
6386 (define_insn "*lshrsi3_extend2"
6387 [(set (match_operand:DI 0 "register_operand" "=r")
6388 (zero_extract:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
6389 (match_operand 2 "small_int_operand" "I")
6391 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
6393 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
6394 return "srl\t%1, %2, %0";
6396 [(set_attr "type" "shift")])
6398 (define_expand "lshrdi3"
6399 [(set (match_operand:DI 0 "register_operand" "=r")
6400 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6401 (match_operand:SI 2 "arith_operand" "rI")))]
6402 "TARGET_ARCH64 || TARGET_V8PLUS"
6404 if (! TARGET_ARCH64)
6406 if (GET_CODE (operands[2]) == CONST_INT)
6408 emit_insn (gen_lshrdi3_v8plus (operands[0], operands[1], operands[2]));
6413 (define_insn "*lshrdi3_sp64"
6414 [(set (match_operand:DI 0 "register_operand" "=r")
6415 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6416 (match_operand:SI 2 "arith_operand" "rI")))]
6419 if (GET_CODE (operands[2]) == CONST_INT)
6420 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
6421 return "srlx\t%1, %2, %0";
6423 [(set_attr "type" "shift")])
6426 (define_insn "lshrdi3_v8plus"
6427 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
6428 (lshiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
6429 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
6430 (clobber (match_scratch:SI 3 "=X,X,&h"))]
6432 "* return output_v8plus_shift (operands, insn, \"srlx\");"
6433 [(set_attr "type" "multi")
6434 (set_attr "length" "5,5,6")])
6437 [(set (match_operand:SI 0 "register_operand" "=r")
6438 (ashiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6440 (match_operand:SI 2 "small_int_operand" "I")))]
6441 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
6443 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
6444 return "srax\t%1, %2, %0";
6446 [(set_attr "type" "shift")])
6449 [(set (match_operand:SI 0 "register_operand" "=r")
6450 (lshiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
6452 (match_operand:SI 2 "small_int_operand" "I")))]
6453 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
6455 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
6456 return "srlx\t%1, %2, %0";
6458 [(set_attr "type" "shift")])
6461 [(set (match_operand:SI 0 "register_operand" "=r")
6462 (ashiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
6463 (match_operand:SI 2 "small_int_operand" "I")) 4)
6464 (match_operand:SI 3 "small_int_operand" "I")))]
6466 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
6467 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
6468 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
6470 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
6472 return "srax\t%1, %2, %0";
6474 [(set_attr "type" "shift")])
6477 [(set (match_operand:SI 0 "register_operand" "=r")
6478 (lshiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6479 (match_operand:SI 2 "small_int_operand" "I")) 4)
6480 (match_operand:SI 3 "small_int_operand" "I")))]
6482 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
6483 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
6484 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
6486 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
6488 return "srlx\t%1, %2, %0";
6490 [(set_attr "type" "shift")])
6493 ;; Unconditional and other jump instructions.
6496 [(set (pc) (label_ref (match_operand 0 "" "")))]
6498 "* return output_ubranch (operands[0], 0, insn);"
6499 [(set_attr "type" "uncond_branch")])
6501 (define_expand "tablejump"
6502 [(parallel [(set (pc) (match_operand 0 "register_operand" "r"))
6503 (use (label_ref (match_operand 1 "" "")))])]
6506 gcc_assert (GET_MODE (operands[0]) == CASE_VECTOR_MODE);
6508 /* In pic mode, our address differences are against the base of the
6509 table. Add that base value back in; CSE ought to be able to combine
6510 the two address loads. */
6514 tmp = gen_rtx_LABEL_REF (Pmode, operands[1]);
6516 if (CASE_VECTOR_MODE != Pmode)
6517 tmp2 = gen_rtx_SIGN_EXTEND (Pmode, tmp2);
6518 tmp = gen_rtx_PLUS (Pmode, tmp2, tmp);
6519 operands[0] = memory_address (Pmode, tmp);
6523 (define_insn "*tablejump_sp32"
6524 [(set (pc) (match_operand:SI 0 "address_operand" "p"))
6525 (use (label_ref (match_operand 1 "" "")))]
6528 [(set_attr "type" "uncond_branch")])
6530 (define_insn "*tablejump_sp64"
6531 [(set (pc) (match_operand:DI 0 "address_operand" "p"))
6532 (use (label_ref (match_operand 1 "" "")))]
6535 [(set_attr "type" "uncond_branch")])
6538 ;; Jump to subroutine instructions.
6540 (define_expand "call"
6541 ;; Note that this expression is not used for generating RTL.
6542 ;; All the RTL is generated explicitly below.
6543 [(call (match_operand 0 "call_operand" "")
6544 (match_operand 3 "" "i"))]
6545 ;; operands[2] is next_arg_register
6546 ;; operands[3] is struct_value_size_rtx.
6551 gcc_assert (MEM_P (operands[0]) && GET_MODE (operands[0]) == FUNCTION_MODE);
6553 gcc_assert (GET_CODE (operands[3]) == CONST_INT);
6555 if (GET_CODE (XEXP (operands[0], 0)) == LABEL_REF)
6557 /* This is really a PIC sequence. We want to represent
6558 it as a funny jump so its delay slots can be filled.
6560 ??? But if this really *is* a CALL, will not it clobber the
6561 call-clobbered registers? We lose this if it is a JUMP_INSN.
6562 Why cannot we have delay slots filled if it were a CALL? */
6564 /* We accept negative sizes for untyped calls. */
6565 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
6570 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
6572 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
6578 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
6579 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
6583 fn_rtx = operands[0];
6585 /* We accept negative sizes for untyped calls. */
6586 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
6587 sparc_emit_call_insn
6590 gen_rtvec (3, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx),
6592 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))),
6595 sparc_emit_call_insn
6598 gen_rtvec (2, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx),
6599 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))),
6607 ;; We can't use the same pattern for these two insns, because then registers
6608 ;; in the address may not be properly reloaded.
6610 (define_insn "*call_address_sp32"
6611 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6612 (match_operand 1 "" ""))
6613 (clobber (reg:SI 15))]
6614 ;;- Do not use operand 1 for most machines.
6617 [(set_attr "type" "call")])
6619 (define_insn "*call_symbolic_sp32"
6620 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6621 (match_operand 1 "" ""))
6622 (clobber (reg:SI 15))]
6623 ;;- Do not use operand 1 for most machines.
6626 [(set_attr "type" "call")])
6628 (define_insn "*call_address_sp64"
6629 [(call (mem:DI (match_operand:DI 0 "address_operand" "p"))
6630 (match_operand 1 "" ""))
6631 (clobber (reg:DI 15))]
6632 ;;- Do not use operand 1 for most machines.
6635 [(set_attr "type" "call")])
6637 (define_insn "*call_symbolic_sp64"
6638 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
6639 (match_operand 1 "" ""))
6640 (clobber (reg:DI 15))]
6641 ;;- Do not use operand 1 for most machines.
6644 [(set_attr "type" "call")])
6646 ;; This is a call that wants a structure value.
6647 ;; There is no such critter for v9 (??? we may need one anyway).
6648 (define_insn "*call_address_struct_value_sp32"
6649 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6650 (match_operand 1 "" ""))
6651 (match_operand 2 "immediate_operand" "")
6652 (clobber (reg:SI 15))]
6653 ;;- Do not use operand 1 for most machines.
6654 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
6656 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xfff);
6657 return "call\t%a0, %1\n\t nop\n\tunimp\t%2";
6659 [(set_attr "type" "call_no_delay_slot")
6660 (set_attr "length" "3")])
6662 ;; This is a call that wants a structure value.
6663 ;; There is no such critter for v9 (??? we may need one anyway).
6664 (define_insn "*call_symbolic_struct_value_sp32"
6665 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6666 (match_operand 1 "" ""))
6667 (match_operand 2 "immediate_operand" "")
6668 (clobber (reg:SI 15))]
6669 ;;- Do not use operand 1 for most machines.
6670 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
6672 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xfff);
6673 return "call\t%a0, %1\n\t nop\n\tunimp\t%2";
6675 [(set_attr "type" "call_no_delay_slot")
6676 (set_attr "length" "3")])
6678 ;; This is a call that may want a structure value. This is used for
6680 (define_insn "*call_address_untyped_struct_value_sp32"
6681 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6682 (match_operand 1 "" ""))
6683 (match_operand 2 "immediate_operand" "")
6684 (clobber (reg:SI 15))]
6685 ;;- Do not use operand 1 for most machines.
6686 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
6687 "call\t%a0, %1\n\t nop\n\tnop"
6688 [(set_attr "type" "call_no_delay_slot")
6689 (set_attr "length" "3")])
6691 ;; This is a call that may want a structure value. This is used for
6693 (define_insn "*call_symbolic_untyped_struct_value_sp32"
6694 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6695 (match_operand 1 "" ""))
6696 (match_operand 2 "immediate_operand" "")
6697 (clobber (reg:SI 15))]
6698 ;;- Do not use operand 1 for most machines.
6699 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
6700 "call\t%a0, %1\n\t nop\n\tnop"
6701 [(set_attr "type" "call_no_delay_slot")
6702 (set_attr "length" "3")])
6704 (define_expand "call_value"
6705 ;; Note that this expression is not used for generating RTL.
6706 ;; All the RTL is generated explicitly below.
6707 [(set (match_operand 0 "register_operand" "=rf")
6708 (call (match_operand 1 "" "")
6709 (match_operand 4 "" "")))]
6710 ;; operand 2 is stack_size_rtx
6711 ;; operand 3 is next_arg_register
6717 gcc_assert (MEM_P (operands[1]) && GET_MODE (operands[1]) == FUNCTION_MODE);
6719 fn_rtx = operands[1];
6722 gen_rtx_SET (VOIDmode, operands[0],
6723 gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx)),
6724 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)));
6726 sparc_emit_call_insn (gen_rtx_PARALLEL (VOIDmode, vec), XEXP (fn_rtx, 0));
6731 (define_insn "*call_value_address_sp32"
6732 [(set (match_operand 0 "" "=rf")
6733 (call (mem:SI (match_operand:SI 1 "address_operand" "p"))
6734 (match_operand 2 "" "")))
6735 (clobber (reg:SI 15))]
6736 ;;- Do not use operand 2 for most machines.
6739 [(set_attr "type" "call")])
6741 (define_insn "*call_value_symbolic_sp32"
6742 [(set (match_operand 0 "" "=rf")
6743 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
6744 (match_operand 2 "" "")))
6745 (clobber (reg:SI 15))]
6746 ;;- Do not use operand 2 for most machines.
6749 [(set_attr "type" "call")])
6751 (define_insn "*call_value_address_sp64"
6752 [(set (match_operand 0 "" "")
6753 (call (mem:DI (match_operand:DI 1 "address_operand" "p"))
6754 (match_operand 2 "" "")))
6755 (clobber (reg:DI 15))]
6756 ;;- Do not use operand 2 for most machines.
6759 [(set_attr "type" "call")])
6761 (define_insn "*call_value_symbolic_sp64"
6762 [(set (match_operand 0 "" "")
6763 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
6764 (match_operand 2 "" "")))
6765 (clobber (reg:DI 15))]
6766 ;;- Do not use operand 2 for most machines.
6769 [(set_attr "type" "call")])
6771 (define_expand "untyped_call"
6772 [(parallel [(call (match_operand 0 "" "")
6774 (match_operand:BLK 1 "memory_operand" "")
6775 (match_operand 2 "" "")])]
6778 rtx valreg1 = gen_rtx_REG (DImode, 8);
6779 rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
6780 rtx result = operands[1];
6782 /* Pass constm1 to indicate that it may expect a structure value, but
6783 we don't know what size it is. */
6784 emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, constm1_rtx));
6786 /* Save the function value registers. */
6787 emit_move_insn (adjust_address (result, DImode, 0), valreg1);
6788 emit_move_insn (adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8),
6791 /* The optimizer does not know that the call sets the function value
6792 registers we stored in the result block. We avoid problems by
6793 claiming that all hard registers are used and clobbered at this
6795 emit_insn (gen_blockage ());
6800 ;; Tail call instructions.
6802 (define_expand "sibcall"
6803 [(parallel [(call (match_operand 0 "call_operand" "") (const_int 0))
6808 (define_insn "*sibcall_symbolic_sp32"
6809 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6810 (match_operand 1 "" ""))
6813 "* return output_sibcall(insn, operands[0]);"
6814 [(set_attr "type" "sibcall")])
6816 (define_insn "*sibcall_symbolic_sp64"
6817 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
6818 (match_operand 1 "" ""))
6821 "* return output_sibcall(insn, operands[0]);"
6822 [(set_attr "type" "sibcall")])
6824 (define_expand "sibcall_value"
6825 [(parallel [(set (match_operand 0 "register_operand" "=rf")
6826 (call (match_operand 1 "" "") (const_int 0)))
6831 (define_insn "*sibcall_value_symbolic_sp32"
6832 [(set (match_operand 0 "" "=rf")
6833 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
6834 (match_operand 2 "" "")))
6837 "* return output_sibcall(insn, operands[1]);"
6838 [(set_attr "type" "sibcall")])
6840 (define_insn "*sibcall_value_symbolic_sp64"
6841 [(set (match_operand 0 "" "")
6842 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
6843 (match_operand 2 "" "")))
6846 "* return output_sibcall(insn, operands[1]);"
6847 [(set_attr "type" "sibcall")])
6850 ;; Special instructions.
6852 (define_expand "prologue"
6856 sparc_expand_prologue ();
6860 ;; The "save register window" insn is modelled as follows so that the DWARF-2
6861 ;; backend automatically emits the required call frame debugging information
6862 ;; while it is parsing it. Therefore, the pattern should not be modified
6863 ;; without first studying the impact of the changes on the debug info.
6864 ;; [(set (%fp) (%sp))
6865 ;; (set (%sp) (unspec_volatile [(%sp) (-frame_size)] UNSPECV_SAVEW))
6866 ;; (set (%i7) (%o7))]
6868 (define_insn "save_register_window<P:mode>"
6869 [(set (reg:P 30) (reg:P 14))
6870 (set (reg:P 14) (unspec_volatile:P [(reg:P 14)
6871 (match_operand:P 0 "arith_operand" "rI")] UNSPECV_SAVEW))
6872 (set (reg:P 31) (reg:P 15))]
6874 "save\t%%sp, %0, %%sp"
6875 [(set_attr "type" "savew")])
6877 (define_expand "epilogue"
6881 sparc_expand_epilogue ();
6884 (define_expand "sibcall_epilogue"
6888 sparc_expand_epilogue ();
6892 (define_expand "return"
6894 "sparc_can_use_return_insn_p ()"
6897 (define_insn "*return_internal"
6900 "* return output_return (insn);"
6901 [(set_attr "type" "return")
6902 (set (attr "length")
6903 (cond [(eq_attr "leaf_function" "true")
6904 (if_then_else (eq_attr "empty_delay_slot" "true")
6907 (eq_attr "calls_eh_return" "true")
6908 (if_then_else (eq_attr "delayed_branch" "true")
6909 (if_then_else (eq_attr "isa" "v9")
6912 (if_then_else (eq_attr "isa" "v9")
6915 (eq_attr "empty_delay_slot" "true")
6916 (if_then_else (eq_attr "delayed_branch" "true")
6921 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
6922 ;; all of memory. This blocks insns from being moved across this point.
6924 (define_insn "blockage"
6925 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
6928 [(set_attr "length" "0")])
6930 ;; Prepare to return any type including a structure value.
6932 (define_expand "untyped_return"
6933 [(match_operand:BLK 0 "memory_operand" "")
6934 (match_operand 1 "" "")]
6937 rtx valreg1 = gen_rtx_REG (DImode, 24);
6938 rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
6939 rtx result = operands[0];
6941 if (! TARGET_ARCH64)
6943 rtx rtnreg = gen_rtx_REG (SImode, (current_function_uses_only_leaf_regs
6945 rtx value = gen_reg_rtx (SImode);
6947 /* Fetch the instruction where we will return to and see if it's an unimp
6948 instruction (the most significant 10 bits will be zero). If so,
6949 update the return address to skip the unimp instruction. */
6950 emit_move_insn (value,
6951 gen_rtx_MEM (SImode, plus_constant (rtnreg, 8)));
6952 emit_insn (gen_lshrsi3 (value, value, GEN_INT (22)));
6953 emit_insn (gen_update_return (rtnreg, value));
6956 /* Reload the function value registers. */
6957 emit_move_insn (valreg1, adjust_address (result, DImode, 0));
6958 emit_move_insn (valreg2,
6959 adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8));
6961 /* Put USE insns before the return. */
6965 /* Construct the return. */
6966 expand_naked_return ();
6971 ;; Adjust the return address conditionally. If the value of op1 is equal
6972 ;; to all zero then adjust the return address i.e. op0 = op0 + 4.
6973 ;; This is technically *half* the check required by the 32-bit SPARC
6974 ;; psABI. This check only ensures that an "unimp" insn was written by
6975 ;; the caller, but doesn't check to see if the expected size matches
6976 ;; (this is encoded in the 12 lower bits). This check is obsolete and
6977 ;; only used by the above code "untyped_return".
6979 (define_insn "update_return"
6980 [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
6981 (match_operand:SI 1 "register_operand" "r")] UNSPEC_UPDATE_RETURN)]
6984 if (flag_delayed_branch)
6985 return "cmp\t%1, 0\n\tbe,a\t.+8\n\t add\t%0, 4, %0";
6987 return "cmp\t%1, 0\n\tbne\t.+12\n\t nop\n\tadd\t%0, 4, %0";
6989 [(set (attr "type") (const_string "multi"))
6990 (set (attr "length")
6991 (if_then_else (eq_attr "delayed_branch" "true")
7000 (define_expand "indirect_jump"
7001 [(set (pc) (match_operand 0 "address_operand" "p"))]
7005 (define_insn "*branch_sp32"
7006 [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
7009 [(set_attr "type" "uncond_branch")])
7011 (define_insn "*branch_sp64"
7012 [(set (pc) (match_operand:DI 0 "address_operand" "p"))]
7015 [(set_attr "type" "uncond_branch")])
7017 (define_expand "nonlocal_goto"
7018 [(match_operand:SI 0 "general_operand" "")
7019 (match_operand:SI 1 "general_operand" "")
7020 (match_operand:SI 2 "general_operand" "")
7021 (match_operand:SI 3 "" "")]
7024 rtx lab = operands[1];
7025 rtx stack = operands[2];
7026 rtx fp = operands[3];
7029 /* Trap instruction to flush all the register windows. */
7030 emit_insn (gen_flush_register_windows ());
7032 /* Load the fp value for the containing fn into %fp. This is needed
7033 because STACK refers to %fp. Note that virtual register instantiation
7034 fails if the virtual %fp isn't set from a register. */
7035 if (GET_CODE (fp) != REG)
7036 fp = force_reg (Pmode, fp);
7037 emit_move_insn (virtual_stack_vars_rtx, fp);
7039 /* Find the containing function's current nonlocal goto handler,
7040 which will do any cleanups and then jump to the label. */
7041 labreg = gen_rtx_REG (Pmode, 8);
7042 emit_move_insn (labreg, lab);
7044 /* Restore %fp from stack pointer value for containing function.
7045 The restore insn that follows will move this to %sp,
7046 and reload the appropriate value into %fp. */
7047 emit_move_insn (hard_frame_pointer_rtx, stack);
7049 emit_use (stack_pointer_rtx);
7050 emit_use (static_chain_rtx);
7052 /* ??? The V9-specific version was disabled in rev 1.65. */
7053 emit_jump_insn (gen_goto_handler_and_restore (labreg));
7058 ;; Special trap insn to flush register windows.
7059 (define_insn "flush_register_windows"
7060 [(unspec_volatile [(const_int 0)] UNSPECV_FLUSHW)]
7062 { return TARGET_V9 ? "flushw" : "ta\t3"; }
7063 [(set_attr "type" "flushw")])
7065 (define_insn "goto_handler_and_restore"
7066 [(unspec_volatile [(match_operand 0 "register_operand" "=r")] UNSPECV_GOTO)]
7067 "GET_MODE (operands[0]) == Pmode"
7069 if (flag_delayed_branch)
7070 return "jmp\t%0\n\t restore";
7072 return "mov\t%0,%%g1\n\trestore\n\tjmp\t%%g1\n\t nop";
7074 [(set (attr "type") (const_string "multi"))
7075 (set (attr "length")
7076 (if_then_else (eq_attr "delayed_branch" "true")
7080 ;; For __builtin_setjmp we need to flush register windows iff the function
7081 ;; calls alloca as well, because otherwise the register window might be
7082 ;; saved after %sp adjustment and thus setjmp would crash
7083 (define_expand "builtin_setjmp_setup"
7084 [(match_operand 0 "register_operand" "r")]
7087 emit_insn (gen_do_builtin_setjmp_setup ());
7091 (define_insn "do_builtin_setjmp_setup"
7092 [(unspec_volatile [(const_int 0)] UNSPECV_SETJMP)]
7095 if (!cfun->calls_alloca)
7099 fputs ("\tflushw\n", asm_out_file);
7101 fprintf (asm_out_file, "\tst%c\t%%l7, [%%sp+%d]\n",
7102 TARGET_ARCH64 ? 'x' : 'w',
7103 SPARC_STACK_BIAS + 7 * UNITS_PER_WORD);
7104 fprintf (asm_out_file, "\tst%c\t%%fp, [%%sp+%d]\n",
7105 TARGET_ARCH64 ? 'x' : 'w',
7106 SPARC_STACK_BIAS + 14 * UNITS_PER_WORD);
7107 fprintf (asm_out_file, "\tst%c\t%%i7, [%%sp+%d]\n",
7108 TARGET_ARCH64 ? 'x' : 'w',
7109 SPARC_STACK_BIAS + 15 * UNITS_PER_WORD);
7112 [(set_attr "type" "multi")
7113 (set (attr "length")
7114 (cond [(eq_attr "calls_alloca" "false")
7116 (eq_attr "isa" "!v9")
7118 (eq_attr "pic" "true")
7119 (const_int 4)] (const_int 3)))])
7121 ;; Pattern for use after a setjmp to store FP and the return register
7122 ;; into the stack area.
7124 (define_expand "setjmp"
7130 mem = gen_rtx_MEM (Pmode,
7131 plus_constant (stack_pointer_rtx,
7132 SPARC_STACK_BIAS + 14 * UNITS_PER_WORD));
7133 emit_insn (gen_rtx_SET (VOIDmode, mem, frame_pointer_rtx));
7135 mem = gen_rtx_MEM (Pmode,
7136 plus_constant (stack_pointer_rtx,
7137 SPARC_STACK_BIAS + 15 * UNITS_PER_WORD));
7138 emit_insn (gen_rtx_SET (VOIDmode, mem, gen_rtx_REG (Pmode, 31)));
7142 ;; Special pattern for the FLUSH instruction.
7144 ; We do SImode and DImode versions of this to quiet down genrecog's complaints
7145 ; of the define_insn otherwise missing a mode. We make "flush", aka
7146 ; gen_flush, the default one since sparc_initialize_trampoline uses
7147 ; it on SImode mem values.
7149 (define_insn "flush"
7150 [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")] UNSPECV_FLUSH)]
7152 { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; }
7153 [(set_attr "type" "iflush")])
7155 (define_insn "flushdi"
7156 [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")] UNSPECV_FLUSH)]
7158 { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; }
7159 [(set_attr "type" "iflush")])
7162 ;; Find first set instructions.
7164 ;; The scan instruction searches from the most significant bit while ffs
7165 ;; searches from the least significant bit. The bit index and treatment of
7166 ;; zero also differ. It takes at least 7 instructions to get the proper
7167 ;; result. Here is an obvious 8 instruction sequence.
7170 (define_insn "ffssi2"
7171 [(set (match_operand:SI 0 "register_operand" "=&r")
7172 (ffs:SI (match_operand:SI 1 "register_operand" "r")))
7173 (clobber (match_scratch:SI 2 "=&r"))]
7174 "TARGET_SPARCLITE || TARGET_SPARCLET"
7176 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";
7178 [(set_attr "type" "multi")
7179 (set_attr "length" "8")])
7181 ;; ??? This should be a define expand, so that the extra instruction have
7182 ;; a chance of being optimized away.
7184 ;; Disabled because none of the UltraSPARCs implement popc. The HAL R1
7185 ;; does, but no one uses that and we don't have a switch for it.
7187 ;(define_insn "ffsdi2"
7188 ; [(set (match_operand:DI 0 "register_operand" "=&r")
7189 ; (ffs:DI (match_operand:DI 1 "register_operand" "r")))
7190 ; (clobber (match_scratch:DI 2 "=&r"))]
7192 ; "neg\t%1, %2\;xnor\t%1, %2, %2\;popc\t%2, %0\;movzr\t%1, 0, %0"
7193 ; [(set_attr "type" "multi")
7194 ; (set_attr "length" "4")])
7198 ;; Peepholes go at the end.
7200 ;; Optimize consecutive loads or stores into ldd and std when possible.
7201 ;; The conditions in which we do this are very restricted and are
7202 ;; explained in the code for {registers,memory}_ok_for_ldd functions.
7205 [(set (match_operand:SI 0 "memory_operand" "")
7207 (set (match_operand:SI 1 "memory_operand" "")
7210 && mems_ok_for_ldd_peep (operands[0], operands[1], NULL_RTX)"
7213 "operands[0] = widen_memory_access (operands[0], DImode, 0);")
7216 [(set (match_operand:SI 0 "memory_operand" "")
7218 (set (match_operand:SI 1 "memory_operand" "")
7221 && mems_ok_for_ldd_peep (operands[1], operands[0], NULL_RTX)"
7224 "operands[1] = widen_memory_access (operands[1], DImode, 0);")
7227 [(set (match_operand:SI 0 "register_operand" "")
7228 (match_operand:SI 1 "memory_operand" ""))
7229 (set (match_operand:SI 2 "register_operand" "")
7230 (match_operand:SI 3 "memory_operand" ""))]
7231 "registers_ok_for_ldd_peep (operands[0], operands[2])
7232 && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
7235 "operands[1] = widen_memory_access (operands[1], DImode, 0);
7236 operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));")
7239 [(set (match_operand:SI 0 "memory_operand" "")
7240 (match_operand:SI 1 "register_operand" ""))
7241 (set (match_operand:SI 2 "memory_operand" "")
7242 (match_operand:SI 3 "register_operand" ""))]
7243 "registers_ok_for_ldd_peep (operands[1], operands[3])
7244 && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
7247 "operands[0] = widen_memory_access (operands[0], DImode, 0);
7248 operands[1] = gen_rtx_REG (DImode, REGNO (operands[1]));")
7251 [(set (match_operand:SF 0 "register_operand" "")
7252 (match_operand:SF 1 "memory_operand" ""))
7253 (set (match_operand:SF 2 "register_operand" "")
7254 (match_operand:SF 3 "memory_operand" ""))]
7255 "registers_ok_for_ldd_peep (operands[0], operands[2])
7256 && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
7259 "operands[1] = widen_memory_access (operands[1], DFmode, 0);
7260 operands[0] = gen_rtx_REG (DFmode, REGNO (operands[0]));")
7263 [(set (match_operand:SF 0 "memory_operand" "")
7264 (match_operand:SF 1 "register_operand" ""))
7265 (set (match_operand:SF 2 "memory_operand" "")
7266 (match_operand:SF 3 "register_operand" ""))]
7267 "registers_ok_for_ldd_peep (operands[1], operands[3])
7268 && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
7271 "operands[0] = widen_memory_access (operands[0], DFmode, 0);
7272 operands[1] = gen_rtx_REG (DFmode, REGNO (operands[1]));")
7275 [(set (match_operand:SI 0 "register_operand" "")
7276 (match_operand:SI 1 "memory_operand" ""))
7277 (set (match_operand:SI 2 "register_operand" "")
7278 (match_operand:SI 3 "memory_operand" ""))]
7279 "registers_ok_for_ldd_peep (operands[2], operands[0])
7280 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
7283 "operands[3] = widen_memory_access (operands[3], DImode, 0);
7284 operands[2] = gen_rtx_REG (DImode, REGNO (operands[2]));")
7287 [(set (match_operand:SI 0 "memory_operand" "")
7288 (match_operand:SI 1 "register_operand" ""))
7289 (set (match_operand:SI 2 "memory_operand" "")
7290 (match_operand:SI 3 "register_operand" ""))]
7291 "registers_ok_for_ldd_peep (operands[3], operands[1])
7292 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
7295 "operands[2] = widen_memory_access (operands[2], DImode, 0);
7296 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
7300 [(set (match_operand:SF 0 "register_operand" "")
7301 (match_operand:SF 1 "memory_operand" ""))
7302 (set (match_operand:SF 2 "register_operand" "")
7303 (match_operand:SF 3 "memory_operand" ""))]
7304 "registers_ok_for_ldd_peep (operands[2], operands[0])
7305 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
7308 "operands[3] = widen_memory_access (operands[3], DFmode, 0);
7309 operands[2] = gen_rtx_REG (DFmode, REGNO (operands[2]));")
7312 [(set (match_operand:SF 0 "memory_operand" "")
7313 (match_operand:SF 1 "register_operand" ""))
7314 (set (match_operand:SF 2 "memory_operand" "")
7315 (match_operand:SF 3 "register_operand" ""))]
7316 "registers_ok_for_ldd_peep (operands[3], operands[1])
7317 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
7320 "operands[2] = widen_memory_access (operands[2], DFmode, 0);
7321 operands[3] = gen_rtx_REG (DFmode, REGNO (operands[3]));")
7323 ;; Optimize the case of following a reg-reg move with a test
7324 ;; of reg just moved. Don't allow floating point regs for operand 0 or 1.
7325 ;; This can result from a float to fix conversion.
7328 [(set (match_operand:SI 0 "register_operand" "")
7329 (match_operand:SI 1 "register_operand" ""))
7331 (compare:CC (match_operand:SI 2 "register_operand" "")
7333 "(rtx_equal_p (operands[2], operands[0])
7334 || rtx_equal_p (operands[2], operands[1]))
7335 && ! SPARC_FP_REG_P (REGNO (operands[0]))
7336 && ! SPARC_FP_REG_P (REGNO (operands[1]))"
7337 [(parallel [(set (match_dup 0) (match_dup 1))
7339 (compare:CC (match_dup 1) (const_int 0)))])]
7343 [(set (match_operand:DI 0 "register_operand" "")
7344 (match_operand:DI 1 "register_operand" ""))
7346 (compare:CCX (match_operand:DI 2 "register_operand" "")
7349 && (rtx_equal_p (operands[2], operands[0])
7350 || rtx_equal_p (operands[2], operands[1]))
7351 && ! SPARC_FP_REG_P (REGNO (operands[0]))
7352 && ! SPARC_FP_REG_P (REGNO (operands[1]))"
7353 [(parallel [(set (match_dup 0) (match_dup 1))
7355 (compare:CCX (match_dup 1) (const_int 0)))])]
7359 ;; Prefetch instructions.
7361 ;; ??? UltraSPARC-III note: A memory operation loading into the floating point register
7362 ;; ??? file, if it hits the prefetch cache, has a chance to dual-issue with other memory
7363 ;; ??? operations. With DFA we might be able to model this, but it requires a lot of
7365 (define_expand "prefetch"
7366 [(match_operand 0 "address_operand" "")
7367 (match_operand 1 "const_int_operand" "")
7368 (match_operand 2 "const_int_operand" "")]
7372 emit_insn (gen_prefetch_64 (operands[0], operands[1], operands[2]));
7374 emit_insn (gen_prefetch_32 (operands[0], operands[1], operands[2]));
7378 (define_insn "prefetch_64"
7379 [(prefetch (match_operand:DI 0 "address_operand" "p")
7380 (match_operand:DI 1 "const_int_operand" "n")
7381 (match_operand:DI 2 "const_int_operand" "n"))]
7384 static const char * const prefetch_instr[2][2] = {
7386 "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
7387 "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
7390 "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
7391 "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
7394 int read_or_write = INTVAL (operands[1]);
7395 int locality = INTVAL (operands[2]);
7397 gcc_assert (read_or_write == 0 || read_or_write == 1);
7398 gcc_assert (locality >= 0 && locality < 4);
7399 return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
7401 [(set_attr "type" "load")])
7403 (define_insn "prefetch_32"
7404 [(prefetch (match_operand:SI 0 "address_operand" "p")
7405 (match_operand:SI 1 "const_int_operand" "n")
7406 (match_operand:SI 2 "const_int_operand" "n"))]
7409 static const char * const prefetch_instr[2][2] = {
7411 "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
7412 "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
7415 "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
7416 "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
7419 int read_or_write = INTVAL (operands[1]);
7420 int locality = INTVAL (operands[2]);
7422 gcc_assert (read_or_write == 0 || read_or_write == 1);
7423 gcc_assert (locality >= 0 && locality < 4);
7424 return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
7426 [(set_attr "type" "load")])
7429 ;; Trap instructions.
7432 [(trap_if (const_int 1) (const_int 5))]
7435 [(set_attr "type" "trap")])
7437 (define_expand "conditional_trap"
7438 [(trap_if (match_operator 0 "noov_compare_operator" [(match_dup 2) (match_dup 3)])
7439 (match_operand:SI 1 "arith_operand" ""))]
7441 "operands[2] = gen_compare_reg (GET_CODE (operands[0]));
7442 if (GET_MODE (operands[2]) != CCmode && GET_MODE (operands[2]) != CCXmode)
7444 operands[3] = const0_rtx;")
7447 [(trap_if (match_operator 0 "noov_compare_operator" [(reg:CC 100) (const_int 0)])
7448 (match_operand:SI 1 "arith_operand" "rM"))]
7452 return "t%C0\t%%icc, %1";
7456 [(set_attr "type" "trap")])
7459 [(trap_if (match_operator 0 "noov_compare_operator" [(reg:CCX 100) (const_int 0)])
7460 (match_operand:SI 1 "arith_operand" "rM"))]
7463 [(set_attr "type" "trap")])
7466 ;; TLS support instructions.
7468 (define_insn "tgd_hi22"
7469 [(set (match_operand:SI 0 "register_operand" "=r")
7470 (high:SI (unspec:SI [(match_operand 1 "tgd_symbolic_operand" "")]
7473 "sethi\\t%%tgd_hi22(%a1), %0")
7475 (define_insn "tgd_lo10"
7476 [(set (match_operand:SI 0 "register_operand" "=r")
7477 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7478 (unspec:SI [(match_operand 2 "tgd_symbolic_operand" "")]
7481 "add\\t%1, %%tgd_lo10(%a2), %0")
7483 (define_insn "tgd_add32"
7484 [(set (match_operand:SI 0 "register_operand" "=r")
7485 (plus:SI (match_operand:SI 1 "register_operand" "r")
7486 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7487 (match_operand 3 "tgd_symbolic_operand" "")]
7489 "TARGET_TLS && TARGET_ARCH32"
7490 "add\\t%1, %2, %0, %%tgd_add(%a3)")
7492 (define_insn "tgd_add64"
7493 [(set (match_operand:DI 0 "register_operand" "=r")
7494 (plus:DI (match_operand:DI 1 "register_operand" "r")
7495 (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7496 (match_operand 3 "tgd_symbolic_operand" "")]
7498 "TARGET_TLS && TARGET_ARCH64"
7499 "add\\t%1, %2, %0, %%tgd_add(%a3)")
7501 (define_insn "tgd_call32"
7502 [(set (match_operand 0 "register_operand" "=r")
7503 (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")
7504 (match_operand 2 "tgd_symbolic_operand" "")]
7506 (match_operand 3 "" "")))
7507 (clobber (reg:SI 15))]
7508 "TARGET_TLS && TARGET_ARCH32"
7509 "call\t%a1, %%tgd_call(%a2)%#"
7510 [(set_attr "type" "call")])
7512 (define_insn "tgd_call64"
7513 [(set (match_operand 0 "register_operand" "=r")
7514 (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")
7515 (match_operand 2 "tgd_symbolic_operand" "")]
7517 (match_operand 3 "" "")))
7518 (clobber (reg:DI 15))]
7519 "TARGET_TLS && TARGET_ARCH64"
7520 "call\t%a1, %%tgd_call(%a2)%#"
7521 [(set_attr "type" "call")])
7523 (define_insn "tldm_hi22"
7524 [(set (match_operand:SI 0 "register_operand" "=r")
7525 (high:SI (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
7527 "sethi\\t%%tldm_hi22(%&), %0")
7529 (define_insn "tldm_lo10"
7530 [(set (match_operand:SI 0 "register_operand" "=r")
7531 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7532 (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
7534 "add\\t%1, %%tldm_lo10(%&), %0")
7536 (define_insn "tldm_add32"
7537 [(set (match_operand:SI 0 "register_operand" "=r")
7538 (plus:SI (match_operand:SI 1 "register_operand" "r")
7539 (unspec:SI [(match_operand:SI 2 "register_operand" "r")]
7541 "TARGET_TLS && TARGET_ARCH32"
7542 "add\\t%1, %2, %0, %%tldm_add(%&)")
7544 (define_insn "tldm_add64"
7545 [(set (match_operand:DI 0 "register_operand" "=r")
7546 (plus:DI (match_operand:DI 1 "register_operand" "r")
7547 (unspec:DI [(match_operand:SI 2 "register_operand" "r")]
7549 "TARGET_TLS && TARGET_ARCH64"
7550 "add\\t%1, %2, %0, %%tldm_add(%&)")
7552 (define_insn "tldm_call32"
7553 [(set (match_operand 0 "register_operand" "=r")
7554 (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")]
7556 (match_operand 2 "" "")))
7557 (clobber (reg:SI 15))]
7558 "TARGET_TLS && TARGET_ARCH32"
7559 "call\t%a1, %%tldm_call(%&)%#"
7560 [(set_attr "type" "call")])
7562 (define_insn "tldm_call64"
7563 [(set (match_operand 0 "register_operand" "=r")
7564 (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")]
7566 (match_operand 2 "" "")))
7567 (clobber (reg:DI 15))]
7568 "TARGET_TLS && TARGET_ARCH64"
7569 "call\t%a1, %%tldm_call(%&)%#"
7570 [(set_attr "type" "call")])
7572 (define_insn "tldo_hix22"
7573 [(set (match_operand:SI 0 "register_operand" "=r")
7574 (high:SI (unspec:SI [(match_operand 1 "tld_symbolic_operand" "")]
7577 "sethi\\t%%tldo_hix22(%a1), %0")
7579 (define_insn "tldo_lox10"
7580 [(set (match_operand:SI 0 "register_operand" "=r")
7581 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7582 (unspec:SI [(match_operand 2 "tld_symbolic_operand" "")]
7585 "xor\\t%1, %%tldo_lox10(%a2), %0")
7587 (define_insn "tldo_add32"
7588 [(set (match_operand:SI 0 "register_operand" "=r")
7589 (plus:SI (match_operand:SI 1 "register_operand" "r")
7590 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7591 (match_operand 3 "tld_symbolic_operand" "")]
7593 "TARGET_TLS && TARGET_ARCH32"
7594 "add\\t%1, %2, %0, %%tldo_add(%a3)")
7596 (define_insn "tldo_add64"
7597 [(set (match_operand:DI 0 "register_operand" "=r")
7598 (plus:DI (match_operand:DI 1 "register_operand" "r")
7599 (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7600 (match_operand 3 "tld_symbolic_operand" "")]
7602 "TARGET_TLS && TARGET_ARCH64"
7603 "add\\t%1, %2, %0, %%tldo_add(%a3)")
7605 (define_insn "tie_hi22"
7606 [(set (match_operand:SI 0 "register_operand" "=r")
7607 (high:SI (unspec:SI [(match_operand 1 "tie_symbolic_operand" "")]
7610 "sethi\\t%%tie_hi22(%a1), %0")
7612 (define_insn "tie_lo10"
7613 [(set (match_operand:SI 0 "register_operand" "=r")
7614 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7615 (unspec:SI [(match_operand 2 "tie_symbolic_operand" "")]
7618 "add\\t%1, %%tie_lo10(%a2), %0")
7620 (define_insn "tie_ld32"
7621 [(set (match_operand:SI 0 "register_operand" "=r")
7622 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
7623 (match_operand:SI 2 "register_operand" "r")
7624 (match_operand 3 "tie_symbolic_operand" "")]
7626 "TARGET_TLS && TARGET_ARCH32"
7627 "ld\\t[%1 + %2], %0, %%tie_ld(%a3)"
7628 [(set_attr "type" "load")])
7630 (define_insn "tie_ld64"
7631 [(set (match_operand:DI 0 "register_operand" "=r")
7632 (unspec:DI [(match_operand:DI 1 "register_operand" "r")
7633 (match_operand:SI 2 "register_operand" "r")
7634 (match_operand 3 "tie_symbolic_operand" "")]
7636 "TARGET_TLS && TARGET_ARCH64"
7637 "ldx\\t[%1 + %2], %0, %%tie_ldx(%a3)"
7638 [(set_attr "type" "load")])
7640 (define_insn "tie_add32"
7641 [(set (match_operand:SI 0 "register_operand" "=r")
7642 (plus:SI (match_operand:SI 1 "register_operand" "r")
7643 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7644 (match_operand 3 "tie_symbolic_operand" "")]
7646 "TARGET_SUN_TLS && TARGET_ARCH32"
7647 "add\\t%1, %2, %0, %%tie_add(%a3)")
7649 (define_insn "tie_add64"
7650 [(set (match_operand:DI 0 "register_operand" "=r")
7651 (plus:DI (match_operand:DI 1 "register_operand" "r")
7652 (unspec:DI [(match_operand:DI 2 "register_operand" "r")
7653 (match_operand 3 "tie_symbolic_operand" "")]
7655 "TARGET_SUN_TLS && TARGET_ARCH64"
7656 "add\\t%1, %2, %0, %%tie_add(%a3)")
7658 (define_insn "tle_hix22_sp32"
7659 [(set (match_operand:SI 0 "register_operand" "=r")
7660 (high:SI (unspec:SI [(match_operand 1 "tle_symbolic_operand" "")]
7662 "TARGET_TLS && TARGET_ARCH32"
7663 "sethi\\t%%tle_hix22(%a1), %0")
7665 (define_insn "tle_lox10_sp32"
7666 [(set (match_operand:SI 0 "register_operand" "=r")
7667 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7668 (unspec:SI [(match_operand 2 "tle_symbolic_operand" "")]
7670 "TARGET_TLS && TARGET_ARCH32"
7671 "xor\\t%1, %%tle_lox10(%a2), %0")
7673 (define_insn "tle_hix22_sp64"
7674 [(set (match_operand:DI 0 "register_operand" "=r")
7675 (high:DI (unspec:DI [(match_operand 1 "tle_symbolic_operand" "")]
7677 "TARGET_TLS && TARGET_ARCH64"
7678 "sethi\\t%%tle_hix22(%a1), %0")
7680 (define_insn "tle_lox10_sp64"
7681 [(set (match_operand:DI 0 "register_operand" "=r")
7682 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
7683 (unspec:DI [(match_operand 2 "tle_symbolic_operand" "")]
7685 "TARGET_TLS && TARGET_ARCH64"
7686 "xor\\t%1, %%tle_lox10(%a2), %0")
7688 ;; Now patterns combining tldo_add{32,64} with some integer loads or stores
7689 (define_insn "*tldo_ldub_sp32"
7690 [(set (match_operand:QI 0 "register_operand" "=r")
7691 (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7692 (match_operand 3 "tld_symbolic_operand" "")]
7694 (match_operand:SI 1 "register_operand" "r"))))]
7695 "TARGET_TLS && TARGET_ARCH32"
7696 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7697 [(set_attr "type" "load")
7698 (set_attr "us3load_type" "3cycle")])
7700 (define_insn "*tldo_ldub1_sp32"
7701 [(set (match_operand:HI 0 "register_operand" "=r")
7702 (zero_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7703 (match_operand 3 "tld_symbolic_operand" "")]
7705 (match_operand:SI 1 "register_operand" "r")))))]
7706 "TARGET_TLS && TARGET_ARCH32"
7707 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7708 [(set_attr "type" "load")
7709 (set_attr "us3load_type" "3cycle")])
7711 (define_insn "*tldo_ldub2_sp32"
7712 [(set (match_operand:SI 0 "register_operand" "=r")
7713 (zero_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7714 (match_operand 3 "tld_symbolic_operand" "")]
7716 (match_operand:SI 1 "register_operand" "r")))))]
7717 "TARGET_TLS && TARGET_ARCH32"
7718 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7719 [(set_attr "type" "load")
7720 (set_attr "us3load_type" "3cycle")])
7722 (define_insn "*tldo_ldsb1_sp32"
7723 [(set (match_operand:HI 0 "register_operand" "=r")
7724 (sign_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7725 (match_operand 3 "tld_symbolic_operand" "")]
7727 (match_operand:SI 1 "register_operand" "r")))))]
7728 "TARGET_TLS && TARGET_ARCH32"
7729 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7730 [(set_attr "type" "sload")
7731 (set_attr "us3load_type" "3cycle")])
7733 (define_insn "*tldo_ldsb2_sp32"
7734 [(set (match_operand:SI 0 "register_operand" "=r")
7735 (sign_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7736 (match_operand 3 "tld_symbolic_operand" "")]
7738 (match_operand:SI 1 "register_operand" "r")))))]
7739 "TARGET_TLS && TARGET_ARCH32"
7740 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7741 [(set_attr "type" "sload")
7742 (set_attr "us3load_type" "3cycle")])
7744 (define_insn "*tldo_ldub_sp64"
7745 [(set (match_operand:QI 0 "register_operand" "=r")
7746 (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7747 (match_operand 3 "tld_symbolic_operand" "")]
7749 (match_operand:DI 1 "register_operand" "r"))))]
7750 "TARGET_TLS && TARGET_ARCH64"
7751 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7752 [(set_attr "type" "load")
7753 (set_attr "us3load_type" "3cycle")])
7755 (define_insn "*tldo_ldub1_sp64"
7756 [(set (match_operand:HI 0 "register_operand" "=r")
7757 (zero_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7758 (match_operand 3 "tld_symbolic_operand" "")]
7760 (match_operand:DI 1 "register_operand" "r")))))]
7761 "TARGET_TLS && TARGET_ARCH64"
7762 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7763 [(set_attr "type" "load")
7764 (set_attr "us3load_type" "3cycle")])
7766 (define_insn "*tldo_ldub2_sp64"
7767 [(set (match_operand:SI 0 "register_operand" "=r")
7768 (zero_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7769 (match_operand 3 "tld_symbolic_operand" "")]
7771 (match_operand:DI 1 "register_operand" "r")))))]
7772 "TARGET_TLS && TARGET_ARCH64"
7773 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7774 [(set_attr "type" "load")
7775 (set_attr "us3load_type" "3cycle")])
7777 (define_insn "*tldo_ldub3_sp64"
7778 [(set (match_operand:DI 0 "register_operand" "=r")
7779 (zero_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7780 (match_operand 3 "tld_symbolic_operand" "")]
7782 (match_operand:DI 1 "register_operand" "r")))))]
7783 "TARGET_TLS && TARGET_ARCH64"
7784 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7785 [(set_attr "type" "load")
7786 (set_attr "us3load_type" "3cycle")])
7788 (define_insn "*tldo_ldsb1_sp64"
7789 [(set (match_operand:HI 0 "register_operand" "=r")
7790 (sign_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7791 (match_operand 3 "tld_symbolic_operand" "")]
7793 (match_operand:DI 1 "register_operand" "r")))))]
7794 "TARGET_TLS && TARGET_ARCH64"
7795 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7796 [(set_attr "type" "sload")
7797 (set_attr "us3load_type" "3cycle")])
7799 (define_insn "*tldo_ldsb2_sp64"
7800 [(set (match_operand:SI 0 "register_operand" "=r")
7801 (sign_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7802 (match_operand 3 "tld_symbolic_operand" "")]
7804 (match_operand:DI 1 "register_operand" "r")))))]
7805 "TARGET_TLS && TARGET_ARCH64"
7806 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7807 [(set_attr "type" "sload")
7808 (set_attr "us3load_type" "3cycle")])
7810 (define_insn "*tldo_ldsb3_sp64"
7811 [(set (match_operand:DI 0 "register_operand" "=r")
7812 (sign_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7813 (match_operand 3 "tld_symbolic_operand" "")]
7815 (match_operand:DI 1 "register_operand" "r")))))]
7816 "TARGET_TLS && TARGET_ARCH64"
7817 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7818 [(set_attr "type" "sload")
7819 (set_attr "us3load_type" "3cycle")])
7821 (define_insn "*tldo_lduh_sp32"
7822 [(set (match_operand:HI 0 "register_operand" "=r")
7823 (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7824 (match_operand 3 "tld_symbolic_operand" "")]
7826 (match_operand:SI 1 "register_operand" "r"))))]
7827 "TARGET_TLS && TARGET_ARCH32"
7828 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7829 [(set_attr "type" "load")
7830 (set_attr "us3load_type" "3cycle")])
7832 (define_insn "*tldo_lduh1_sp32"
7833 [(set (match_operand:SI 0 "register_operand" "=r")
7834 (zero_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7835 (match_operand 3 "tld_symbolic_operand" "")]
7837 (match_operand:SI 1 "register_operand" "r")))))]
7838 "TARGET_TLS && TARGET_ARCH32"
7839 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7840 [(set_attr "type" "load")
7841 (set_attr "us3load_type" "3cycle")])
7843 (define_insn "*tldo_ldsh1_sp32"
7844 [(set (match_operand:SI 0 "register_operand" "=r")
7845 (sign_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7846 (match_operand 3 "tld_symbolic_operand" "")]
7848 (match_operand:SI 1 "register_operand" "r")))))]
7849 "TARGET_TLS && TARGET_ARCH32"
7850 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
7851 [(set_attr "type" "sload")
7852 (set_attr "us3load_type" "3cycle")])
7854 (define_insn "*tldo_lduh_sp64"
7855 [(set (match_operand:HI 0 "register_operand" "=r")
7856 (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7857 (match_operand 3 "tld_symbolic_operand" "")]
7859 (match_operand:DI 1 "register_operand" "r"))))]
7860 "TARGET_TLS && TARGET_ARCH64"
7861 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7862 [(set_attr "type" "load")
7863 (set_attr "us3load_type" "3cycle")])
7865 (define_insn "*tldo_lduh1_sp64"
7866 [(set (match_operand:SI 0 "register_operand" "=r")
7867 (zero_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7868 (match_operand 3 "tld_symbolic_operand" "")]
7870 (match_operand:DI 1 "register_operand" "r")))))]
7871 "TARGET_TLS && TARGET_ARCH64"
7872 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7873 [(set_attr "type" "load")
7874 (set_attr "us3load_type" "3cycle")])
7876 (define_insn "*tldo_lduh2_sp64"
7877 [(set (match_operand:DI 0 "register_operand" "=r")
7878 (zero_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7879 (match_operand 3 "tld_symbolic_operand" "")]
7881 (match_operand:DI 1 "register_operand" "r")))))]
7882 "TARGET_TLS && TARGET_ARCH64"
7883 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7884 [(set_attr "type" "load")
7885 (set_attr "us3load_type" "3cycle")])
7887 (define_insn "*tldo_ldsh1_sp64"
7888 [(set (match_operand:SI 0 "register_operand" "=r")
7889 (sign_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7890 (match_operand 3 "tld_symbolic_operand" "")]
7892 (match_operand:DI 1 "register_operand" "r")))))]
7893 "TARGET_TLS && TARGET_ARCH64"
7894 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
7895 [(set_attr "type" "sload")
7896 (set_attr "us3load_type" "3cycle")])
7898 (define_insn "*tldo_ldsh2_sp64"
7899 [(set (match_operand:DI 0 "register_operand" "=r")
7900 (sign_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7901 (match_operand 3 "tld_symbolic_operand" "")]
7903 (match_operand:DI 1 "register_operand" "r")))))]
7904 "TARGET_TLS && TARGET_ARCH64"
7905 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
7906 [(set_attr "type" "sload")
7907 (set_attr "us3load_type" "3cycle")])
7909 (define_insn "*tldo_lduw_sp32"
7910 [(set (match_operand:SI 0 "register_operand" "=r")
7911 (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7912 (match_operand 3 "tld_symbolic_operand" "")]
7914 (match_operand:SI 1 "register_operand" "r"))))]
7915 "TARGET_TLS && TARGET_ARCH32"
7916 "ld\t[%1 + %2], %0, %%tldo_add(%3)"
7917 [(set_attr "type" "load")])
7919 (define_insn "*tldo_lduw_sp64"
7920 [(set (match_operand:SI 0 "register_operand" "=r")
7921 (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7922 (match_operand 3 "tld_symbolic_operand" "")]
7924 (match_operand:DI 1 "register_operand" "r"))))]
7925 "TARGET_TLS && TARGET_ARCH64"
7926 "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
7927 [(set_attr "type" "load")])
7929 (define_insn "*tldo_lduw1_sp64"
7930 [(set (match_operand:DI 0 "register_operand" "=r")
7931 (zero_extend:DI (mem:SI (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 "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
7937 [(set_attr "type" "load")])
7939 (define_insn "*tldo_ldsw1_sp64"
7940 [(set (match_operand:DI 0 "register_operand" "=r")
7941 (sign_extend:DI (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7942 (match_operand 3 "tld_symbolic_operand" "")]
7944 (match_operand:DI 1 "register_operand" "r")))))]
7945 "TARGET_TLS && TARGET_ARCH64"
7946 "ldsw\t[%1 + %2], %0, %%tldo_add(%3)"
7947 [(set_attr "type" "sload")
7948 (set_attr "us3load_type" "3cycle")])
7950 (define_insn "*tldo_ldx_sp64"
7951 [(set (match_operand:DI 0 "register_operand" "=r")
7952 (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7953 (match_operand 3 "tld_symbolic_operand" "")]
7955 (match_operand:DI 1 "register_operand" "r"))))]
7956 "TARGET_TLS && TARGET_ARCH64"
7957 "ldx\t[%1 + %2], %0, %%tldo_add(%3)"
7958 [(set_attr "type" "load")])
7960 (define_insn "*tldo_stb_sp32"
7961 [(set (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7962 (match_operand 3 "tld_symbolic_operand" "")]
7964 (match_operand:SI 1 "register_operand" "r")))
7965 (match_operand:QI 0 "register_operand" "=r"))]
7966 "TARGET_TLS && TARGET_ARCH32"
7967 "stb\t%0, [%1 + %2], %%tldo_add(%3)"
7968 [(set_attr "type" "store")])
7970 (define_insn "*tldo_stb_sp64"
7971 [(set (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7972 (match_operand 3 "tld_symbolic_operand" "")]
7974 (match_operand:DI 1 "register_operand" "r")))
7975 (match_operand:QI 0 "register_operand" "=r"))]
7976 "TARGET_TLS && TARGET_ARCH64"
7977 "stb\t%0, [%1 + %2], %%tldo_add(%3)"
7978 [(set_attr "type" "store")])
7980 (define_insn "*tldo_sth_sp32"
7981 [(set (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7982 (match_operand 3 "tld_symbolic_operand" "")]
7984 (match_operand:SI 1 "register_operand" "r")))
7985 (match_operand:HI 0 "register_operand" "=r"))]
7986 "TARGET_TLS && TARGET_ARCH32"
7987 "sth\t%0, [%1 + %2], %%tldo_add(%3)"
7988 [(set_attr "type" "store")])
7990 (define_insn "*tldo_sth_sp64"
7991 [(set (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7992 (match_operand 3 "tld_symbolic_operand" "")]
7994 (match_operand:DI 1 "register_operand" "r")))
7995 (match_operand:HI 0 "register_operand" "=r"))]
7996 "TARGET_TLS && TARGET_ARCH64"
7997 "sth\t%0, [%1 + %2], %%tldo_add(%3)"
7998 [(set_attr "type" "store")])
8000 (define_insn "*tldo_stw_sp32"
8001 [(set (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8002 (match_operand 3 "tld_symbolic_operand" "")]
8004 (match_operand:SI 1 "register_operand" "r")))
8005 (match_operand:SI 0 "register_operand" "=r"))]
8006 "TARGET_TLS && TARGET_ARCH32"
8007 "st\t%0, [%1 + %2], %%tldo_add(%3)"
8008 [(set_attr "type" "store")])
8010 (define_insn "*tldo_stw_sp64"
8011 [(set (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8012 (match_operand 3 "tld_symbolic_operand" "")]
8014 (match_operand:DI 1 "register_operand" "r")))
8015 (match_operand:SI 0 "register_operand" "=r"))]
8016 "TARGET_TLS && TARGET_ARCH64"
8017 "stw\t%0, [%1 + %2], %%tldo_add(%3)"
8018 [(set_attr "type" "store")])
8020 (define_insn "*tldo_stx_sp64"
8021 [(set (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8022 (match_operand 3 "tld_symbolic_operand" "")]
8024 (match_operand:DI 1 "register_operand" "r")))
8025 (match_operand:DI 0 "register_operand" "=r"))]
8026 "TARGET_TLS && TARGET_ARCH64"
8027 "stx\t%0, [%1 + %2], %%tldo_add(%3)"
8028 [(set_attr "type" "store")])
8031 ;; Stack protector instructions.
8033 (define_expand "stack_protect_set"
8034 [(match_operand 0 "memory_operand" "")
8035 (match_operand 1 "memory_operand" "")]
8038 #ifdef TARGET_THREAD_SSP_OFFSET
8039 rtx tlsreg = gen_rtx_REG (Pmode, 7);
8040 rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
8041 operands[1] = gen_rtx_MEM (Pmode, addr);
8044 emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
8046 emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
8050 (define_insn "stack_protect_setsi"
8051 [(set (match_operand:SI 0 "memory_operand" "=m")
8052 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
8053 (set (match_scratch:SI 2 "=&r") (const_int 0))]
8055 "ld\t%1, %2\;st\t%2, %0\;mov\t0, %2"
8056 [(set_attr "type" "multi")
8057 (set_attr "length" "3")])
8059 (define_insn "stack_protect_setdi"
8060 [(set (match_operand:DI 0 "memory_operand" "=m")
8061 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
8062 (set (match_scratch:DI 2 "=&r") (const_int 0))]
8064 "ldx\t%1, %2\;stx\t%2, %0\;mov\t0, %2"
8065 [(set_attr "type" "multi")
8066 (set_attr "length" "3")])
8068 (define_expand "stack_protect_test"
8069 [(match_operand 0 "memory_operand" "")
8070 (match_operand 1 "memory_operand" "")
8071 (match_operand 2 "" "")]
8074 #ifdef TARGET_THREAD_SSP_OFFSET
8075 rtx tlsreg = gen_rtx_REG (Pmode, 7);
8076 rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
8077 operands[1] = gen_rtx_MEM (Pmode, addr);
8081 rtx temp = gen_reg_rtx (Pmode);
8082 emit_insn (gen_stack_protect_testdi (temp, operands[0], operands[1]));
8083 sparc_compare_op0 = temp;
8084 sparc_compare_op1 = const0_rtx;
8088 emit_insn (gen_stack_protect_testsi (operands[0], operands[1]));
8089 sparc_compare_op0 = gen_rtx_REG (CCmode, SPARC_ICC_REG);
8090 sparc_compare_op1 = const0_rtx;
8092 emit_jump_insn (gen_beq (operands[2]));
8096 (define_insn "stack_protect_testsi"
8098 (unspec:CC [(match_operand:SI 0 "memory_operand" "m")
8099 (match_operand:SI 1 "memory_operand" "m")]
8101 (set (match_scratch:SI 3 "=r") (const_int 0))
8102 (clobber (match_scratch:SI 2 "=&r"))]
8104 "ld\t%0, %2\;ld\t%1, %3\;xorcc\t%2, %3, %2\;mov\t0, %3"
8105 [(set_attr "type" "multi")
8106 (set_attr "length" "4")])
8108 (define_insn "stack_protect_testdi"
8109 [(set (match_operand:DI 0 "register_operand" "=&r")
8110 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
8111 (match_operand:DI 2 "memory_operand" "m")]
8113 (set (match_scratch:DI 3 "=r") (const_int 0))]
8115 "ldx\t%1, %0\;ldx\t%2, %3\;xor\t%0, %3, %0\;mov\t0, %3"
8116 [(set_attr "type" "multi")
8117 (set_attr "length" "4")])
8120 ;; Vector instructions.
8122 (define_insn "addv2si3"
8123 [(set (match_operand:V2SI 0 "register_operand" "=e")
8124 (plus:V2SI (match_operand:V2SI 1 "register_operand" "e")
8125 (match_operand:V2SI 2 "register_operand" "e")))]
8127 "fpadd32\t%1, %2, %0"
8128 [(set_attr "type" "fga")
8129 (set_attr "fptype" "double")])
8131 (define_insn "addv4hi3"
8132 [(set (match_operand:V4HI 0 "register_operand" "=e")
8133 (plus:V4HI (match_operand:V4HI 1 "register_operand" "e")
8134 (match_operand:V4HI 2 "register_operand" "e")))]
8136 "fpadd16\t%1, %2, %0"
8137 [(set_attr "type" "fga")
8138 (set_attr "fptype" "double")])
8140 ;; fpadd32s is emitted by the addsi3 pattern.
8142 (define_insn "addv2hi3"
8143 [(set (match_operand:V2HI 0 "register_operand" "=f")
8144 (plus:V2HI (match_operand:V2HI 1 "register_operand" "f")
8145 (match_operand:V2HI 2 "register_operand" "f")))]
8147 "fpadd16s\t%1, %2, %0"
8148 [(set_attr "type" "fga")
8149 (set_attr "fptype" "single")])
8151 (define_insn "subv2si3"
8152 [(set (match_operand:V2SI 0 "register_operand" "=e")
8153 (minus:V2SI (match_operand:V2SI 1 "register_operand" "e")
8154 (match_operand:V2SI 2 "register_operand" "e")))]
8156 "fpsub32\t%1, %2, %0"
8157 [(set_attr "type" "fga")
8158 (set_attr "fptype" "double")])
8160 (define_insn "subv4hi3"
8161 [(set (match_operand:V4HI 0 "register_operand" "=e")
8162 (minus:V4HI (match_operand:V4HI 1 "register_operand" "e")
8163 (match_operand:V4HI 2 "register_operand" "e")))]
8165 "fpsub16\t%1, %2, %0"
8166 [(set_attr "type" "fga")
8167 (set_attr "fptype" "double")])
8169 ;; fpsub32s is emitted by the subsi3 pattern.
8171 (define_insn "subv2hi3"
8172 [(set (match_operand:V2HI 0 "register_operand" "=f")
8173 (minus:V2HI (match_operand:V2HI 1 "register_operand" "f")
8174 (match_operand:V2HI 2 "register_operand" "f")))]
8176 "fpsub16s\t%1, %2, %0"
8177 [(set_attr "type" "fga")
8178 (set_attr "fptype" "single")])
8180 ;; All other logical instructions have integer equivalents so they
8181 ;; are defined together.
8183 ;; (ior (not (op1)) (not (op2))) is the canonical form of NAND.
8185 (define_insn "*nand<V64:mode>_vis"
8186 [(set (match_operand:V64 0 "register_operand" "=e")
8187 (ior:V64 (not:V64 (match_operand:V64 1 "register_operand" "e"))
8188 (not:V64 (match_operand:V64 2 "register_operand" "e"))))]
8191 [(set_attr "type" "fga")
8192 (set_attr "fptype" "double")])
8194 (define_insn "*nand<V32:mode>_vis"
8195 [(set (match_operand:V32 0 "register_operand" "=f")
8196 (ior:V32 (not:V32 (match_operand:V32 1 "register_operand" "f"))
8197 (not:V32 (match_operand:V32 2 "register_operand" "f"))))]
8199 "fnands\t%1, %2, %0"
8200 [(set_attr "type" "fga")
8201 (set_attr "fptype" "single")])
8203 ;; Hard to generate VIS instructions. We have builtins for these.
8205 (define_insn "fpack16_vis"
8206 [(set (match_operand:V4QI 0 "register_operand" "=f")
8207 (unspec:V4QI [(match_operand:V4HI 1 "register_operand" "e")]
8211 [(set_attr "type" "fga")
8212 (set_attr "fptype" "double")])
8214 (define_insn "fpackfix_vis"
8215 [(set (match_operand:V2HI 0 "register_operand" "=f")
8216 (unspec:V2HI [(match_operand:V2SI 1 "register_operand" "e")]
8220 [(set_attr "type" "fga")
8221 (set_attr "fptype" "double")])
8223 (define_insn "fpack32_vis"
8224 [(set (match_operand:V8QI 0 "register_operand" "=e")
8225 (unspec:V8QI [(match_operand:V2SI 1 "register_operand" "e")
8226 (match_operand:V8QI 2 "register_operand" "e")]
8229 "fpack32\t%1, %2, %0"
8230 [(set_attr "type" "fga")
8231 (set_attr "fptype" "double")])
8233 (define_insn "fexpand_vis"
8234 [(set (match_operand:V4HI 0 "register_operand" "=e")
8235 (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")]
8239 [(set_attr "type" "fga")
8240 (set_attr "fptype" "double")])
8242 ;; It may be possible to describe this operation as (1 indexed):
8243 ;; (vec_select (vec_duplicate (vec_duplicate (vec_concat 1 2)))
8244 ;; 1,5,10,14,19,23,28,32)
8245 ;; Note that (vec_merge:V8QI [(V4QI) (V4QI)] (10101010 = 170) doesn't work
8246 ;; because vec_merge expects all the operands to be of the same type.
8247 (define_insn "fpmerge_vis"
8248 [(set (match_operand:V8QI 0 "register_operand" "=e")
8249 (unspec:V8QI [(match_operand:V4QI 1 "register_operand" "f")
8250 (match_operand:V4QI 2 "register_operand" "f")]
8253 "fpmerge\t%1, %2, %0"
8254 [(set_attr "type" "fga")
8255 (set_attr "fptype" "double")])
8257 ;; Partitioned multiply instructions
8258 (define_insn "fmul8x16_vis"
8259 [(set (match_operand:V4HI 0 "register_operand" "=e")
8260 (mult:V4HI (match_operand:V4QI 1 "register_operand" "f")
8261 (match_operand:V4HI 2 "register_operand" "e")))]
8263 "fmul8x16\t%1, %2, %0"
8264 [(set_attr "type" "fpmul")
8265 (set_attr "fptype" "double")])
8267 ;; Only one of the following two insns can be a multiply.
8268 (define_insn "fmul8x16au_vis"
8269 [(set (match_operand:V4HI 0 "register_operand" "=e")
8270 (mult:V4HI (match_operand:V4QI 1 "register_operand" "f")
8271 (match_operand:V2HI 2 "register_operand" "f")))]
8273 "fmul8x16au\t%1, %2, %0"
8274 [(set_attr "type" "fpmul")
8275 (set_attr "fptype" "double")])
8277 (define_insn "fmul8x16al_vis"
8278 [(set (match_operand:V4HI 0 "register_operand" "=e")
8279 (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")
8280 (match_operand:V2HI 2 "register_operand" "f")]
8283 "fmul8x16al\t%1, %2, %0"
8284 [(set_attr "type" "fpmul")
8285 (set_attr "fptype" "double")])
8287 ;; Only one of the following two insns can be a multiply.
8288 (define_insn "fmul8sux16_vis"
8289 [(set (match_operand:V4HI 0 "register_operand" "=e")
8290 (mult:V4HI (match_operand:V8QI 1 "register_operand" "e")
8291 (match_operand:V4HI 2 "register_operand" "e")))]
8293 "fmul8sux16\t%1, %2, %0"
8294 [(set_attr "type" "fpmul")
8295 (set_attr "fptype" "double")])
8297 (define_insn "fmul8ulx16_vis"
8298 [(set (match_operand:V4HI 0 "register_operand" "=e")
8299 (unspec:V4HI [(match_operand:V8QI 1 "register_operand" "e")
8300 (match_operand:V4HI 2 "register_operand" "e")]
8303 "fmul8ulx16\t%1, %2, %0"
8304 [(set_attr "type" "fpmul")
8305 (set_attr "fptype" "double")])
8307 ;; Only one of the following two insns can be a multiply.
8308 (define_insn "fmuld8sux16_vis"
8309 [(set (match_operand:V2SI 0 "register_operand" "=e")
8310 (mult:V2SI (match_operand:V4QI 1 "register_operand" "f")
8311 (match_operand:V2HI 2 "register_operand" "f")))]
8313 "fmuld8sux16\t%1, %2, %0"
8314 [(set_attr "type" "fpmul")
8315 (set_attr "fptype" "double")])
8317 (define_insn "fmuld8ulx16_vis"
8318 [(set (match_operand:V2SI 0 "register_operand" "=e")
8319 (unspec:V2SI [(match_operand:V4QI 1 "register_operand" "f")
8320 (match_operand:V2HI 2 "register_operand" "f")]
8323 "fmuld8ulx16\t%1, %2, %0"
8324 [(set_attr "type" "fpmul")
8325 (set_attr "fptype" "double")])
8327 ;; Using faligndata only makes sense after an alignaddr since the choice of
8328 ;; bytes to take out of each operand is dependent on the results of the last
8330 (define_insn "faligndata<V64I:mode>_vis"
8331 [(set (match_operand:V64I 0 "register_operand" "=e")
8332 (unspec:V64I [(match_operand:V64I 1 "register_operand" "e")
8333 (match_operand:V64I 2 "register_operand" "e")]
8336 "faligndata\t%1, %2, %0"
8337 [(set_attr "type" "fga")
8338 (set_attr "fptype" "double")])
8340 (define_insn "alignaddr<P:mode>_vis"
8341 [(set (match_operand:P 0 "register_operand" "=r")
8342 (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
8343 (match_operand:P 2 "register_or_zero_operand" "rJ")]
8346 "alignaddr\t%r1, %r2, %0")
8348 (define_insn "pdist_vis"
8349 [(set (match_operand:DI 0 "register_operand" "=e")
8350 (unspec:DI [(match_operand:V8QI 1 "register_operand" "e")
8351 (match_operand:V8QI 2 "register_operand" "e")
8352 (match_operand:DI 3 "register_operand" "0")]
8356 [(set_attr "type" "fga")
8357 (set_attr "fptype" "double")])