1 ;; Machine description for SPARC chip for GCC
2 ;; Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
3 ;; 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
4 ;; Contributed by Michael Tiemann (tiemann@cygnus.com)
5 ;; 64-bit SPARC-V9 support by Michael Tiemann, Jim Wilson, and Doug Evans,
8 ;; This file is part of GCC.
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 2, or (at your option)
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 ;; GNU General Public License for more details.
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING. If not, write to
22 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
23 ;; Boston, MA 02111-1307, USA.
25 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
29 (UNSPEC_UPDATE_RETURN 1)
30 (UNSPEC_LOAD_PCREL_SYM 2)
31 (UNSPEC_MOVE_PIC_LABEL 5)
37 (UNSPEC_EMB_TEXTUHI 13)
38 (UNSPEC_EMB_TEXTHI 14)
39 (UNSPEC_EMB_TEXTULO 15)
47 (UNSPEC_TLSLD_BASE 35)
71 ;; The upper 32 fp regs on the v9 can't hold SFmode values. To deal with this
72 ;; a second register class, EXTRA_FP_REGS, exists for the v9 chip. The name
73 ;; is a bit of a misnomer as it covers all 64 fp regs. The corresponding
74 ;; constraint letter is 'e'. To avoid any confusion, 'e' is used instead of
75 ;; 'f' for all DF/TFmode values, including those that are specific to the v8.
77 ;; Attribute for cpu type.
78 ;; These must match the values for enum processor_type in sparc.h.
85 hypersparc,sparclite86x,
90 (const (symbol_ref "sparc_cpu_attr")))
92 ;; Attribute for the instruction set.
93 ;; At present we only need to distinguish v9/!v9, but for clarity we
94 ;; test TARGET_V8 too.
95 (define_attr "isa" "v7,v8,v9,sparclet"
97 (cond [(symbol_ref "TARGET_V9") (const_string "v9")
98 (symbol_ref "TARGET_V8") (const_string "v8")
99 (symbol_ref "TARGET_SPARCLET") (const_string "sparclet")]
100 (const_string "v7"))))
106 uncond_branch,branch,call,sibcall,call_no_delay_slot,return,
114 fga,fgm_pack,fgm_mul,fgm_pdist,fgm_cmp,
117 multi,savew,flushw,iflush,trap"
118 (const_string "ialu"))
120 ;; True if branch/call has empty delay slot and will emit a nop in it
121 (define_attr "empty_delay_slot" "false,true"
122 (symbol_ref "empty_delay_slot (insn)"))
124 (define_attr "branch_type" "none,icc,fcc,reg"
125 (const_string "none"))
127 (define_attr "pic" "false,true"
128 (symbol_ref "flag_pic != 0"))
130 (define_attr "calls_alloca" "false,true"
131 (symbol_ref "current_function_calls_alloca != 0"))
133 (define_attr "calls_eh_return" "false,true"
134 (symbol_ref "current_function_calls_eh_return !=0 "))
136 (define_attr "leaf_function" "false,true"
137 (symbol_ref "current_function_uses_only_leaf_regs != 0"))
139 (define_attr "delayed_branch" "false,true"
140 (symbol_ref "flag_delayed_branch != 0"))
142 ;; Length (in # of insns).
143 ;; Beware that setting a length greater or equal to 3 for conditional branches
144 ;; has a side-effect (see output_cbranch and output_v9branch).
145 (define_attr "length" ""
146 (cond [(eq_attr "type" "uncond_branch,call")
147 (if_then_else (eq_attr "empty_delay_slot" "true")
150 (eq_attr "type" "sibcall")
151 (if_then_else (eq_attr "leaf_function" "true")
152 (if_then_else (eq_attr "empty_delay_slot" "true")
155 (if_then_else (eq_attr "empty_delay_slot" "true")
158 (eq_attr "branch_type" "icc")
159 (if_then_else (match_operand 0 "noov_compare64_op" "")
160 (if_then_else (lt (pc) (match_dup 1))
161 (if_then_else (lt (minus (match_dup 1) (pc)) (const_int 260000))
162 (if_then_else (eq_attr "empty_delay_slot" "true")
165 (if_then_else (eq_attr "empty_delay_slot" "true")
168 (if_then_else (lt (minus (pc) (match_dup 1)) (const_int 260000))
169 (if_then_else (eq_attr "empty_delay_slot" "true")
172 (if_then_else (eq_attr "empty_delay_slot" "true")
175 (if_then_else (eq_attr "empty_delay_slot" "true")
178 (eq_attr "branch_type" "fcc")
179 (if_then_else (match_operand 0 "fcc0_reg_operand" "")
180 (if_then_else (eq_attr "empty_delay_slot" "true")
181 (if_then_else (eq (symbol_ref "TARGET_V9") (const_int 0))
184 (if_then_else (eq (symbol_ref "TARGET_V9") (const_int 0))
187 (if_then_else (lt (pc) (match_dup 2))
188 (if_then_else (lt (minus (match_dup 2) (pc)) (const_int 260000))
189 (if_then_else (eq_attr "empty_delay_slot" "true")
192 (if_then_else (eq_attr "empty_delay_slot" "true")
195 (if_then_else (lt (minus (pc) (match_dup 2)) (const_int 260000))
196 (if_then_else (eq_attr "empty_delay_slot" "true")
199 (if_then_else (eq_attr "empty_delay_slot" "true")
202 (eq_attr "branch_type" "reg")
203 (if_then_else (lt (pc) (match_dup 2))
204 (if_then_else (lt (minus (match_dup 2) (pc)) (const_int 32000))
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 32000))
212 (if_then_else (eq_attr "empty_delay_slot" "true")
215 (if_then_else (eq_attr "empty_delay_slot" "true")
221 (define_attr "fptype" "single,double"
222 (const_string "single"))
224 ;; UltraSPARC-III integer load type.
225 (define_attr "us3load_type" "2cycle,3cycle"
226 (const_string "2cycle"))
228 (define_asm_attributes
229 [(set_attr "length" "2")
230 (set_attr "type" "multi")])
232 ;; Attributes for instruction and branch scheduling
233 (define_attr "tls_call_delay" "false,true"
234 (symbol_ref "tls_call_delay (insn)"))
236 (define_attr "in_call_delay" "false,true"
237 (cond [(eq_attr "type" "uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
238 (const_string "false")
239 (eq_attr "type" "load,fpload,store,fpstore")
240 (if_then_else (eq_attr "length" "1")
241 (const_string "true")
242 (const_string "false"))]
243 (if_then_else (and (eq_attr "length" "1")
244 (eq_attr "tls_call_delay" "true"))
245 (const_string "true")
246 (const_string "false"))))
248 (define_attr "eligible_for_sibcall_delay" "false,true"
249 (symbol_ref "eligible_for_sibcall_delay (insn)"))
251 (define_attr "eligible_for_return_delay" "false,true"
252 (symbol_ref "eligible_for_return_delay (insn)"))
254 ;; ??? !v9: Should implement the notion of predelay slots for floating-point
255 ;; branches. This would allow us to remove the nop always inserted before
256 ;; a floating point branch.
258 ;; ??? It is OK for fill_simple_delay_slots to put load/store instructions
259 ;; in a delay slot, but it is not OK for fill_eager_delay_slots to do so.
260 ;; This is because doing so will add several pipeline stalls to the path
261 ;; that the load/store did not come from. Unfortunately, there is no way
262 ;; to prevent fill_eager_delay_slots from using load/store without completely
263 ;; disabling them. For the SPEC benchmark set, this is a serious lose,
264 ;; because it prevents us from moving back the final store of inner loops.
266 (define_attr "in_branch_delay" "false,true"
267 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
268 (eq_attr "length" "1"))
269 (const_string "true")
270 (const_string "false")))
272 (define_attr "in_uncond_branch_delay" "false,true"
273 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
274 (eq_attr "length" "1"))
275 (const_string "true")
276 (const_string "false")))
278 (define_attr "in_annul_branch_delay" "false,true"
279 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
280 (eq_attr "length" "1"))
281 (const_string "true")
282 (const_string "false")))
284 (define_delay (eq_attr "type" "call")
285 [(eq_attr "in_call_delay" "true") (nil) (nil)])
287 (define_delay (eq_attr "type" "sibcall")
288 [(eq_attr "eligible_for_sibcall_delay" "true") (nil) (nil)])
290 (define_delay (eq_attr "type" "branch")
291 [(eq_attr "in_branch_delay" "true")
292 (nil) (eq_attr "in_annul_branch_delay" "true")])
294 (define_delay (eq_attr "type" "uncond_branch")
295 [(eq_attr "in_uncond_branch_delay" "true")
298 (define_delay (eq_attr "type" "return")
299 [(eq_attr "eligible_for_return_delay" "true") (nil) (nil)])
301 ;; Include SPARC DFA schedulers
303 (include "cypress.md")
304 (include "supersparc.md")
305 (include "hypersparc.md")
306 (include "sparclet.md")
307 (include "ultra1_2.md")
308 (include "ultra3.md")
311 ;; Compare instructions.
312 ;; This controls RTL generation and register allocation.
314 ;; We generate RTL for comparisons and branches by having the cmpxx
315 ;; patterns store away the operands. Then, the scc and bcc patterns
316 ;; emit RTL for both the compare and the branch.
318 ;; We do this because we want to generate different code for an sne and
319 ;; seq insn. In those cases, if the second operand of the compare is not
320 ;; const0_rtx, we want to compute the xor of the two operands and test
323 ;; We start with the DEFINE_EXPANDs, then the DEFINE_INSNs to match
324 ;; the patterns. Finally, we have the DEFINE_SPLITs for some of the scc
325 ;; insns that actually require more than one machine instruction.
327 ;; Put cmpsi first among compare insns so it matches two CONST_INT operands.
329 (define_expand "cmpsi"
331 (compare:CC (match_operand:SI 0 "compare_operand" "")
332 (match_operand:SI 1 "arith_operand" "")))]
335 if (GET_CODE (operands[0]) == ZERO_EXTRACT && operands[1] != const0_rtx)
336 operands[0] = force_reg (SImode, operands[0]);
338 sparc_compare_op0 = operands[0];
339 sparc_compare_op1 = operands[1];
343 (define_expand "cmpdi"
345 (compare:CCX (match_operand:DI 0 "compare_operand" "")
346 (match_operand:DI 1 "arith_double_operand" "")))]
349 if (GET_CODE (operands[0]) == ZERO_EXTRACT && operands[1] != const0_rtx)
350 operands[0] = force_reg (DImode, operands[0]);
352 sparc_compare_op0 = operands[0];
353 sparc_compare_op1 = operands[1];
357 (define_expand "cmpsf"
358 ;; The 96 here isn't ever used by anyone.
360 (compare:CCFP (match_operand:SF 0 "register_operand" "")
361 (match_operand:SF 1 "register_operand" "")))]
364 sparc_compare_op0 = operands[0];
365 sparc_compare_op1 = operands[1];
369 (define_expand "cmpdf"
370 ;; The 96 here isn't ever used by anyone.
372 (compare:CCFP (match_operand:DF 0 "register_operand" "")
373 (match_operand:DF 1 "register_operand" "")))]
376 sparc_compare_op0 = operands[0];
377 sparc_compare_op1 = operands[1];
381 (define_expand "cmptf"
382 ;; The 96 here isn't ever used by anyone.
384 (compare:CCFP (match_operand:TF 0 "register_operand" "")
385 (match_operand:TF 1 "register_operand" "")))]
388 sparc_compare_op0 = operands[0];
389 sparc_compare_op1 = operands[1];
393 ;; Now the compare DEFINE_INSNs.
395 (define_insn "*cmpsi_insn"
397 (compare:CC (match_operand:SI 0 "register_operand" "r")
398 (match_operand:SI 1 "arith_operand" "rI")))]
401 [(set_attr "type" "compare")])
403 (define_insn "*cmpdi_sp64"
405 (compare:CCX (match_operand:DI 0 "register_operand" "r")
406 (match_operand:DI 1 "arith_double_operand" "rHI")))]
409 [(set_attr "type" "compare")])
411 (define_insn "*cmpsf_fpe"
412 [(set (match_operand:CCFPE 0 "fcc_reg_operand" "=c")
413 (compare:CCFPE (match_operand:SF 1 "register_operand" "f")
414 (match_operand:SF 2 "register_operand" "f")))]
418 return "fcmpes\t%0, %1, %2";
419 return "fcmpes\t%1, %2";
421 [(set_attr "type" "fpcmp")])
423 (define_insn "*cmpdf_fpe"
424 [(set (match_operand:CCFPE 0 "fcc_reg_operand" "=c")
425 (compare:CCFPE (match_operand:DF 1 "register_operand" "e")
426 (match_operand:DF 2 "register_operand" "e")))]
430 return "fcmped\t%0, %1, %2";
431 return "fcmped\t%1, %2";
433 [(set_attr "type" "fpcmp")
434 (set_attr "fptype" "double")])
436 (define_insn "*cmptf_fpe"
437 [(set (match_operand:CCFPE 0 "fcc_reg_operand" "=c")
438 (compare:CCFPE (match_operand:TF 1 "register_operand" "e")
439 (match_operand:TF 2 "register_operand" "e")))]
440 "TARGET_FPU && TARGET_HARD_QUAD"
443 return "fcmpeq\t%0, %1, %2";
444 return "fcmpeq\t%1, %2";
446 [(set_attr "type" "fpcmp")])
448 (define_insn "*cmpsf_fp"
449 [(set (match_operand:CCFP 0 "fcc_reg_operand" "=c")
450 (compare:CCFP (match_operand:SF 1 "register_operand" "f")
451 (match_operand:SF 2 "register_operand" "f")))]
455 return "fcmps\t%0, %1, %2";
456 return "fcmps\t%1, %2";
458 [(set_attr "type" "fpcmp")])
460 (define_insn "*cmpdf_fp"
461 [(set (match_operand:CCFP 0 "fcc_reg_operand" "=c")
462 (compare:CCFP (match_operand:DF 1 "register_operand" "e")
463 (match_operand:DF 2 "register_operand" "e")))]
467 return "fcmpd\t%0, %1, %2";
468 return "fcmpd\t%1, %2";
470 [(set_attr "type" "fpcmp")
471 (set_attr "fptype" "double")])
473 (define_insn "*cmptf_fp"
474 [(set (match_operand:CCFP 0 "fcc_reg_operand" "=c")
475 (compare:CCFP (match_operand:TF 1 "register_operand" "e")
476 (match_operand:TF 2 "register_operand" "e")))]
477 "TARGET_FPU && TARGET_HARD_QUAD"
480 return "fcmpq\t%0, %1, %2";
481 return "fcmpq\t%1, %2";
483 [(set_attr "type" "fpcmp")])
485 ;; Next come the scc insns. For seq, sne, sgeu, and sltu, we can do this
486 ;; without jumps using the addx/subx instructions. For seq/sne on v9 we use
487 ;; the same code as v8 (the addx/subx method has more applications). The
488 ;; exception to this is "reg != 0" which can be done in one instruction on v9
489 ;; (so we do it). For the rest, on v9 we use conditional moves; on v8, we do
492 ;; Seq_special[_xxx] and sne_special[_xxx] clobber the CC reg, because they
493 ;; generate addcc/subcc instructions.
495 (define_expand "seqsi_special"
497 (xor:SI (match_operand:SI 1 "register_operand" "")
498 (match_operand:SI 2 "register_operand" "")))
499 (parallel [(set (match_operand:SI 0 "register_operand" "")
500 (eq:SI (match_dup 3) (const_int 0)))
501 (clobber (reg:CC 100))])]
503 { operands[3] = gen_reg_rtx (SImode); })
505 (define_expand "seqdi_special"
507 (xor:DI (match_operand:DI 1 "register_operand" "")
508 (match_operand:DI 2 "register_operand" "")))
509 (set (match_operand:DI 0 "register_operand" "")
510 (eq:DI (match_dup 3) (const_int 0)))]
512 { operands[3] = gen_reg_rtx (DImode); })
514 (define_expand "snesi_special"
516 (xor:SI (match_operand:SI 1 "register_operand" "")
517 (match_operand:SI 2 "register_operand" "")))
518 (parallel [(set (match_operand:SI 0 "register_operand" "")
519 (ne:SI (match_dup 3) (const_int 0)))
520 (clobber (reg:CC 100))])]
522 { operands[3] = gen_reg_rtx (SImode); })
524 (define_expand "snedi_special"
526 (xor:DI (match_operand:DI 1 "register_operand" "")
527 (match_operand:DI 2 "register_operand" "")))
528 (set (match_operand:DI 0 "register_operand" "")
529 (ne:DI (match_dup 3) (const_int 0)))]
531 { operands[3] = gen_reg_rtx (DImode); })
533 (define_expand "seqdi_special_trunc"
535 (xor:DI (match_operand:DI 1 "register_operand" "")
536 (match_operand:DI 2 "register_operand" "")))
537 (set (match_operand:SI 0 "register_operand" "")
538 (eq:SI (match_dup 3) (const_int 0)))]
540 { operands[3] = gen_reg_rtx (DImode); })
542 (define_expand "snedi_special_trunc"
544 (xor:DI (match_operand:DI 1 "register_operand" "")
545 (match_operand:DI 2 "register_operand" "")))
546 (set (match_operand:SI 0 "register_operand" "")
547 (ne:SI (match_dup 3) (const_int 0)))]
549 { operands[3] = gen_reg_rtx (DImode); })
551 (define_expand "seqsi_special_extend"
553 (xor:SI (match_operand:SI 1 "register_operand" "")
554 (match_operand:SI 2 "register_operand" "")))
555 (parallel [(set (match_operand:DI 0 "register_operand" "")
556 (eq:DI (match_dup 3) (const_int 0)))
557 (clobber (reg:CC 100))])]
559 { operands[3] = gen_reg_rtx (SImode); })
561 (define_expand "snesi_special_extend"
563 (xor:SI (match_operand:SI 1 "register_operand" "")
564 (match_operand:SI 2 "register_operand" "")))
565 (parallel [(set (match_operand:DI 0 "register_operand" "")
566 (ne:DI (match_dup 3) (const_int 0)))
567 (clobber (reg:CC 100))])]
569 { operands[3] = gen_reg_rtx (SImode); })
571 ;; ??? v9: Operand 0 needs a mode, so SImode was chosen.
572 ;; However, the code handles both SImode and DImode.
574 [(set (match_operand:SI 0 "intreg_operand" "")
575 (eq:SI (match_dup 1) (const_int 0)))]
578 if (GET_MODE (sparc_compare_op0) == SImode)
582 if (GET_MODE (operands[0]) == SImode)
583 pat = gen_seqsi_special (operands[0], sparc_compare_op0,
585 else if (! TARGET_ARCH64)
588 pat = gen_seqsi_special_extend (operands[0], sparc_compare_op0,
593 else if (GET_MODE (sparc_compare_op0) == DImode)
599 else if (GET_MODE (operands[0]) == SImode)
600 pat = gen_seqdi_special_trunc (operands[0], sparc_compare_op0,
603 pat = gen_seqdi_special (operands[0], sparc_compare_op0,
608 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
610 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, EQ);
611 emit_jump_insn (gen_sne (operands[0]));
616 if (gen_v9_scc (EQ, operands))
623 ;; ??? v9: Operand 0 needs a mode, so SImode was chosen.
624 ;; However, the code handles both SImode and DImode.
626 [(set (match_operand:SI 0 "intreg_operand" "")
627 (ne:SI (match_dup 1) (const_int 0)))]
630 if (GET_MODE (sparc_compare_op0) == SImode)
634 if (GET_MODE (operands[0]) == SImode)
635 pat = gen_snesi_special (operands[0], sparc_compare_op0,
637 else if (! TARGET_ARCH64)
640 pat = gen_snesi_special_extend (operands[0], sparc_compare_op0,
645 else if (GET_MODE (sparc_compare_op0) == DImode)
651 else if (GET_MODE (operands[0]) == SImode)
652 pat = gen_snedi_special_trunc (operands[0], sparc_compare_op0,
655 pat = gen_snedi_special (operands[0], sparc_compare_op0,
660 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
662 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, NE);
663 emit_jump_insn (gen_sne (operands[0]));
668 if (gen_v9_scc (NE, operands))
676 [(set (match_operand:SI 0 "intreg_operand" "")
677 (gt:SI (match_dup 1) (const_int 0)))]
680 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
682 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GT);
683 emit_jump_insn (gen_sne (operands[0]));
688 if (gen_v9_scc (GT, operands))
696 [(set (match_operand:SI 0 "intreg_operand" "")
697 (lt:SI (match_dup 1) (const_int 0)))]
700 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
702 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LT);
703 emit_jump_insn (gen_sne (operands[0]));
708 if (gen_v9_scc (LT, operands))
716 [(set (match_operand:SI 0 "intreg_operand" "")
717 (ge:SI (match_dup 1) (const_int 0)))]
720 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
722 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GE);
723 emit_jump_insn (gen_sne (operands[0]));
728 if (gen_v9_scc (GE, operands))
736 [(set (match_operand:SI 0 "intreg_operand" "")
737 (le:SI (match_dup 1) (const_int 0)))]
740 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
742 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LE);
743 emit_jump_insn (gen_sne (operands[0]));
748 if (gen_v9_scc (LE, operands))
755 (define_expand "sgtu"
756 [(set (match_operand:SI 0 "intreg_operand" "")
757 (gtu:SI (match_dup 1) (const_int 0)))]
764 /* We can do ltu easily, so if both operands are registers, swap them and
766 if ((GET_CODE (sparc_compare_op0) == REG
767 || GET_CODE (sparc_compare_op0) == SUBREG)
768 && (GET_CODE (sparc_compare_op1) == REG
769 || GET_CODE (sparc_compare_op1) == SUBREG))
771 tem = sparc_compare_op0;
772 sparc_compare_op0 = sparc_compare_op1;
773 sparc_compare_op1 = tem;
774 pat = gen_sltu (operands[0]);
783 if (gen_v9_scc (GTU, operands))
789 (define_expand "sltu"
790 [(set (match_operand:SI 0 "intreg_operand" "")
791 (ltu:SI (match_dup 1) (const_int 0)))]
796 if (gen_v9_scc (LTU, operands))
799 operands[1] = gen_compare_reg (LTU, sparc_compare_op0, sparc_compare_op1);
802 (define_expand "sgeu"
803 [(set (match_operand:SI 0 "intreg_operand" "")
804 (geu:SI (match_dup 1) (const_int 0)))]
809 if (gen_v9_scc (GEU, operands))
812 operands[1] = gen_compare_reg (GEU, sparc_compare_op0, sparc_compare_op1);
815 (define_expand "sleu"
816 [(set (match_operand:SI 0 "intreg_operand" "")
817 (leu:SI (match_dup 1) (const_int 0)))]
824 /* We can do geu easily, so if both operands are registers, swap them and
826 if ((GET_CODE (sparc_compare_op0) == REG
827 || GET_CODE (sparc_compare_op0) == SUBREG)
828 && (GET_CODE (sparc_compare_op1) == REG
829 || GET_CODE (sparc_compare_op1) == SUBREG))
831 tem = sparc_compare_op0;
832 sparc_compare_op0 = sparc_compare_op1;
833 sparc_compare_op1 = tem;
834 pat = gen_sgeu (operands[0]);
843 if (gen_v9_scc (LEU, operands))
849 ;; Now the DEFINE_INSNs for the scc cases.
851 ;; The SEQ and SNE patterns are special because they can be done
852 ;; without any branching and do not involve a COMPARE. We want
853 ;; them to always use the splitz below so the results can be
856 (define_insn_and_split "*snesi_zero"
857 [(set (match_operand:SI 0 "register_operand" "=r")
858 (ne:SI (match_operand:SI 1 "register_operand" "r")
860 (clobber (reg:CC 100))]
864 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
866 (set (match_dup 0) (ltu:SI (reg:CC 100) (const_int 0)))]
868 [(set_attr "length" "2")])
870 (define_insn_and_split "*neg_snesi_zero"
871 [(set (match_operand:SI 0 "register_operand" "=r")
872 (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
874 (clobber (reg:CC 100))]
878 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
880 (set (match_dup 0) (neg:SI (ltu:SI (reg:CC 100) (const_int 0))))]
882 [(set_attr "length" "2")])
884 (define_insn_and_split "*snesi_zero_extend"
885 [(set (match_operand:DI 0 "register_operand" "=r")
886 (ne:DI (match_operand:SI 1 "register_operand" "r")
888 (clobber (reg:CC 100))]
892 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (minus:SI (const_int 0)
895 (set (match_dup 0) (zero_extend:DI (plus:SI (plus:SI (const_int 0)
897 (ltu:SI (reg:CC_NOOV 100)
900 [(set_attr "length" "2")])
902 (define_insn_and_split "*snedi_zero"
903 [(set (match_operand:DI 0 "register_operand" "=&r")
904 (ne:DI (match_operand:DI 1 "register_operand" "r")
908 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
909 [(set (match_dup 0) (const_int 0))
910 (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
915 [(set_attr "length" "2")])
917 (define_insn_and_split "*neg_snedi_zero"
918 [(set (match_operand:DI 0 "register_operand" "=&r")
919 (neg:DI (ne:DI (match_operand:DI 1 "register_operand" "r")
923 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
924 [(set (match_dup 0) (const_int 0))
925 (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
930 [(set_attr "length" "2")])
932 (define_insn_and_split "*snedi_zero_trunc"
933 [(set (match_operand:SI 0 "register_operand" "=&r")
934 (ne:SI (match_operand:DI 1 "register_operand" "r")
938 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
939 [(set (match_dup 0) (const_int 0))
940 (set (match_dup 0) (if_then_else:SI (ne:DI (match_dup 1)
945 [(set_attr "length" "2")])
947 (define_insn_and_split "*seqsi_zero"
948 [(set (match_operand:SI 0 "register_operand" "=r")
949 (eq:SI (match_operand:SI 1 "register_operand" "r")
951 (clobber (reg:CC 100))]
955 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
957 (set (match_dup 0) (geu:SI (reg:CC 100) (const_int 0)))]
959 [(set_attr "length" "2")])
961 (define_insn_and_split "*neg_seqsi_zero"
962 [(set (match_operand:SI 0 "register_operand" "=r")
963 (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
965 (clobber (reg:CC 100))]
969 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
971 (set (match_dup 0) (neg:SI (geu:SI (reg:CC 100) (const_int 0))))]
973 [(set_attr "length" "2")])
975 (define_insn_and_split "*seqsi_zero_extend"
976 [(set (match_operand:DI 0 "register_operand" "=r")
977 (eq:DI (match_operand:SI 1 "register_operand" "r")
979 (clobber (reg:CC 100))]
983 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (minus:SI (const_int 0)
986 (set (match_dup 0) (zero_extend:DI (minus:SI (minus:SI (const_int 0)
988 (ltu:SI (reg:CC_NOOV 100)
991 [(set_attr "length" "2")])
993 (define_insn_and_split "*seqdi_zero"
994 [(set (match_operand:DI 0 "register_operand" "=&r")
995 (eq:DI (match_operand:DI 1 "register_operand" "r")
999 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
1000 [(set (match_dup 0) (const_int 0))
1001 (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
1006 [(set_attr "length" "2")])
1008 (define_insn_and_split "*neg_seqdi_zero"
1009 [(set (match_operand:DI 0 "register_operand" "=&r")
1010 (neg:DI (eq:DI (match_operand:DI 1 "register_operand" "r")
1014 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
1015 [(set (match_dup 0) (const_int 0))
1016 (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
1021 [(set_attr "length" "2")])
1023 (define_insn_and_split "*seqdi_zero_trunc"
1024 [(set (match_operand:SI 0 "register_operand" "=&r")
1025 (eq:SI (match_operand:DI 1 "register_operand" "r")
1029 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
1030 [(set (match_dup 0) (const_int 0))
1031 (set (match_dup 0) (if_then_else:SI (eq:DI (match_dup 1)
1036 [(set_attr "length" "2")])
1038 ;; We can also do (x + (i == 0)) and related, so put them in.
1039 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1042 (define_insn_and_split "*x_plus_i_ne_0"
1043 [(set (match_operand:SI 0 "register_operand" "=r")
1044 (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
1046 (match_operand:SI 2 "register_operand" "r")))
1047 (clobber (reg:CC 100))]
1051 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1053 (set (match_dup 0) (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1056 [(set_attr "length" "2")])
1058 (define_insn_and_split "*x_minus_i_ne_0"
1059 [(set (match_operand:SI 0 "register_operand" "=r")
1060 (minus:SI (match_operand:SI 2 "register_operand" "r")
1061 (ne:SI (match_operand:SI 1 "register_operand" "r")
1063 (clobber (reg:CC 100))]
1067 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1069 (set (match_dup 0) (minus:SI (match_dup 2)
1070 (ltu:SI (reg:CC 100) (const_int 0))))]
1072 [(set_attr "length" "2")])
1074 (define_insn_and_split "*x_plus_i_eq_0"
1075 [(set (match_operand:SI 0 "register_operand" "=r")
1076 (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
1078 (match_operand:SI 2 "register_operand" "r")))
1079 (clobber (reg:CC 100))]
1083 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1085 (set (match_dup 0) (plus:SI (geu:SI (reg:CC 100) (const_int 0))
1088 [(set_attr "length" "2")])
1090 (define_insn_and_split "*x_minus_i_eq_0"
1091 [(set (match_operand:SI 0 "register_operand" "=r")
1092 (minus:SI (match_operand:SI 2 "register_operand" "r")
1093 (eq:SI (match_operand:SI 1 "register_operand" "r")
1095 (clobber (reg:CC 100))]
1099 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1101 (set (match_dup 0) (minus:SI (match_dup 2)
1102 (geu:SI (reg:CC 100) (const_int 0))))]
1104 [(set_attr "length" "2")])
1106 ;; We can also do GEU and LTU directly, but these operate after a compare.
1107 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1110 (define_insn "*sltu_insn"
1111 [(set (match_operand:SI 0 "register_operand" "=r")
1112 (ltu:SI (reg:CC 100) (const_int 0)))]
1115 [(set_attr "type" "ialuX")])
1117 (define_insn "*neg_sltu_insn"
1118 [(set (match_operand:SI 0 "register_operand" "=r")
1119 (neg:SI (ltu:SI (reg:CC 100) (const_int 0))))]
1122 [(set_attr "type" "ialuX")])
1124 ;; ??? Combine should canonicalize these next two to the same pattern.
1125 (define_insn "*neg_sltu_minus_x"
1126 [(set (match_operand:SI 0 "register_operand" "=r")
1127 (minus:SI (neg:SI (ltu:SI (reg:CC 100) (const_int 0)))
1128 (match_operand:SI 1 "arith_operand" "rI")))]
1130 "subx\t%%g0, %1, %0"
1131 [(set_attr "type" "ialuX")])
1133 (define_insn "*neg_sltu_plus_x"
1134 [(set (match_operand:SI 0 "register_operand" "=r")
1135 (neg:SI (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1136 (match_operand:SI 1 "arith_operand" "rI"))))]
1138 "subx\t%%g0, %1, %0"
1139 [(set_attr "type" "ialuX")])
1141 (define_insn "*sgeu_insn"
1142 [(set (match_operand:SI 0 "register_operand" "=r")
1143 (geu:SI (reg:CC 100) (const_int 0)))]
1145 "subx\t%%g0, -1, %0"
1146 [(set_attr "type" "ialuX")])
1148 (define_insn "*neg_sgeu_insn"
1149 [(set (match_operand:SI 0 "register_operand" "=r")
1150 (neg:SI (geu:SI (reg:CC 100) (const_int 0))))]
1152 "addx\t%%g0, -1, %0"
1153 [(set_attr "type" "ialuX")])
1155 ;; We can also do (x + ((unsigned) i >= 0)) and related, so put them in.
1156 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1159 (define_insn "*sltu_plus_x"
1160 [(set (match_operand:SI 0 "register_operand" "=r")
1161 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1162 (match_operand:SI 1 "arith_operand" "rI")))]
1164 "addx\t%%g0, %1, %0"
1165 [(set_attr "type" "ialuX")])
1167 (define_insn "*sltu_plus_x_plus_y"
1168 [(set (match_operand:SI 0 "register_operand" "=r")
1169 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1170 (plus:SI (match_operand:SI 1 "arith_operand" "%r")
1171 (match_operand:SI 2 "arith_operand" "rI"))))]
1174 [(set_attr "type" "ialuX")])
1176 (define_insn "*x_minus_sltu"
1177 [(set (match_operand:SI 0 "register_operand" "=r")
1178 (minus:SI (match_operand:SI 1 "register_operand" "r")
1179 (ltu:SI (reg:CC 100) (const_int 0))))]
1182 [(set_attr "type" "ialuX")])
1184 ;; ??? Combine should canonicalize these next two to the same pattern.
1185 (define_insn "*x_minus_y_minus_sltu"
1186 [(set (match_operand:SI 0 "register_operand" "=r")
1187 (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
1188 (match_operand:SI 2 "arith_operand" "rI"))
1189 (ltu:SI (reg:CC 100) (const_int 0))))]
1192 [(set_attr "type" "ialuX")])
1194 (define_insn "*x_minus_sltu_plus_y"
1195 [(set (match_operand:SI 0 "register_operand" "=r")
1196 (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
1197 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1198 (match_operand:SI 2 "arith_operand" "rI"))))]
1201 [(set_attr "type" "ialuX")])
1203 (define_insn "*sgeu_plus_x"
1204 [(set (match_operand:SI 0 "register_operand" "=r")
1205 (plus:SI (geu:SI (reg:CC 100) (const_int 0))
1206 (match_operand:SI 1 "register_operand" "r")))]
1209 [(set_attr "type" "ialuX")])
1211 (define_insn "*x_minus_sgeu"
1212 [(set (match_operand:SI 0 "register_operand" "=r")
1213 (minus:SI (match_operand:SI 1 "register_operand" "r")
1214 (geu:SI (reg:CC 100) (const_int 0))))]
1217 [(set_attr "type" "ialuX")])
1220 [(set (match_operand:SI 0 "register_operand" "")
1221 (match_operator:SI 2 "noov_compare_op"
1222 [(match_operand 1 "icc_or_fcc_reg_operand" "")
1225 && REGNO (operands[1]) == SPARC_ICC_REG
1226 && (GET_MODE (operands[1]) == CCXmode
1227 /* 32 bit LTU/GEU are better implemented using addx/subx. */
1228 || (GET_CODE (operands[2]) != LTU && GET_CODE (operands[2]) != GEU))"
1229 [(set (match_dup 0) (const_int 0))
1231 (if_then_else:SI (match_op_dup:SI 2 [(match_dup 1) (const_int 0)])
1237 ;; These control RTL generation for conditional jump insns
1239 ;; The quad-word fp compare library routines all return nonzero to indicate
1240 ;; true, which is different from the equivalent libgcc routines, so we must
1241 ;; handle them specially here.
1243 (define_expand "beq"
1245 (if_then_else (eq (match_dup 1) (const_int 0))
1246 (label_ref (match_operand 0 "" ""))
1250 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1251 && GET_CODE (sparc_compare_op0) == REG
1252 && GET_MODE (sparc_compare_op0) == DImode)
1254 emit_v9_brxx_insn (EQ, sparc_compare_op0, operands[0]);
1257 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1259 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, EQ);
1260 emit_jump_insn (gen_bne (operands[0]));
1263 operands[1] = gen_compare_reg (EQ, sparc_compare_op0, sparc_compare_op1);
1266 (define_expand "bne"
1268 (if_then_else (ne (match_dup 1) (const_int 0))
1269 (label_ref (match_operand 0 "" ""))
1273 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1274 && GET_CODE (sparc_compare_op0) == REG
1275 && GET_MODE (sparc_compare_op0) == DImode)
1277 emit_v9_brxx_insn (NE, sparc_compare_op0, operands[0]);
1280 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1282 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, NE);
1283 emit_jump_insn (gen_bne (operands[0]));
1286 operands[1] = gen_compare_reg (NE, sparc_compare_op0, sparc_compare_op1);
1289 (define_expand "bgt"
1291 (if_then_else (gt (match_dup 1) (const_int 0))
1292 (label_ref (match_operand 0 "" ""))
1296 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1297 && GET_CODE (sparc_compare_op0) == REG
1298 && GET_MODE (sparc_compare_op0) == DImode)
1300 emit_v9_brxx_insn (GT, sparc_compare_op0, operands[0]);
1303 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1305 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GT);
1306 emit_jump_insn (gen_bne (operands[0]));
1309 operands[1] = gen_compare_reg (GT, sparc_compare_op0, sparc_compare_op1);
1312 (define_expand "bgtu"
1314 (if_then_else (gtu (match_dup 1) (const_int 0))
1315 (label_ref (match_operand 0 "" ""))
1319 operands[1] = gen_compare_reg (GTU, sparc_compare_op0, sparc_compare_op1);
1322 (define_expand "blt"
1324 (if_then_else (lt (match_dup 1) (const_int 0))
1325 (label_ref (match_operand 0 "" ""))
1329 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1330 && GET_CODE (sparc_compare_op0) == REG
1331 && GET_MODE (sparc_compare_op0) == DImode)
1333 emit_v9_brxx_insn (LT, sparc_compare_op0, operands[0]);
1336 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1338 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LT);
1339 emit_jump_insn (gen_bne (operands[0]));
1342 operands[1] = gen_compare_reg (LT, sparc_compare_op0, sparc_compare_op1);
1345 (define_expand "bltu"
1347 (if_then_else (ltu (match_dup 1) (const_int 0))
1348 (label_ref (match_operand 0 "" ""))
1352 operands[1] = gen_compare_reg (LTU, sparc_compare_op0, sparc_compare_op1);
1355 (define_expand "bge"
1357 (if_then_else (ge (match_dup 1) (const_int 0))
1358 (label_ref (match_operand 0 "" ""))
1362 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1363 && GET_CODE (sparc_compare_op0) == REG
1364 && GET_MODE (sparc_compare_op0) == DImode)
1366 emit_v9_brxx_insn (GE, sparc_compare_op0, operands[0]);
1369 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1371 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GE);
1372 emit_jump_insn (gen_bne (operands[0]));
1375 operands[1] = gen_compare_reg (GE, sparc_compare_op0, sparc_compare_op1);
1378 (define_expand "bgeu"
1380 (if_then_else (geu (match_dup 1) (const_int 0))
1381 (label_ref (match_operand 0 "" ""))
1385 operands[1] = gen_compare_reg (GEU, sparc_compare_op0, sparc_compare_op1);
1388 (define_expand "ble"
1390 (if_then_else (le (match_dup 1) (const_int 0))
1391 (label_ref (match_operand 0 "" ""))
1395 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1396 && GET_CODE (sparc_compare_op0) == REG
1397 && GET_MODE (sparc_compare_op0) == DImode)
1399 emit_v9_brxx_insn (LE, sparc_compare_op0, operands[0]);
1402 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1404 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LE);
1405 emit_jump_insn (gen_bne (operands[0]));
1408 operands[1] = gen_compare_reg (LE, sparc_compare_op0, sparc_compare_op1);
1411 (define_expand "bleu"
1413 (if_then_else (leu (match_dup 1) (const_int 0))
1414 (label_ref (match_operand 0 "" ""))
1418 operands[1] = gen_compare_reg (LEU, sparc_compare_op0, sparc_compare_op1);
1421 (define_expand "bunordered"
1423 (if_then_else (unordered (match_dup 1) (const_int 0))
1424 (label_ref (match_operand 0 "" ""))
1428 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1430 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1,
1432 emit_jump_insn (gen_beq (operands[0]));
1435 operands[1] = gen_compare_reg (UNORDERED, sparc_compare_op0,
1439 (define_expand "bordered"
1441 (if_then_else (ordered (match_dup 1) (const_int 0))
1442 (label_ref (match_operand 0 "" ""))
1446 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1448 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, ORDERED);
1449 emit_jump_insn (gen_bne (operands[0]));
1452 operands[1] = gen_compare_reg (ORDERED, sparc_compare_op0,
1456 (define_expand "bungt"
1458 (if_then_else (ungt (match_dup 1) (const_int 0))
1459 (label_ref (match_operand 0 "" ""))
1463 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1465 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNGT);
1466 emit_jump_insn (gen_bgt (operands[0]));
1469 operands[1] = gen_compare_reg (UNGT, sparc_compare_op0, sparc_compare_op1);
1472 (define_expand "bunlt"
1474 (if_then_else (unlt (match_dup 1) (const_int 0))
1475 (label_ref (match_operand 0 "" ""))
1479 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1481 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNLT);
1482 emit_jump_insn (gen_bne (operands[0]));
1485 operands[1] = gen_compare_reg (UNLT, sparc_compare_op0, sparc_compare_op1);
1488 (define_expand "buneq"
1490 (if_then_else (uneq (match_dup 1) (const_int 0))
1491 (label_ref (match_operand 0 "" ""))
1495 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1497 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNEQ);
1498 emit_jump_insn (gen_beq (operands[0]));
1501 operands[1] = gen_compare_reg (UNEQ, sparc_compare_op0, sparc_compare_op1);
1504 (define_expand "bunge"
1506 (if_then_else (unge (match_dup 1) (const_int 0))
1507 (label_ref (match_operand 0 "" ""))
1511 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1513 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNGE);
1514 emit_jump_insn (gen_bne (operands[0]));
1517 operands[1] = gen_compare_reg (UNGE, sparc_compare_op0, sparc_compare_op1);
1520 (define_expand "bunle"
1522 (if_then_else (unle (match_dup 1) (const_int 0))
1523 (label_ref (match_operand 0 "" ""))
1527 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1529 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNLE);
1530 emit_jump_insn (gen_bne (operands[0]));
1533 operands[1] = gen_compare_reg (UNLE, sparc_compare_op0, sparc_compare_op1);
1536 (define_expand "bltgt"
1538 (if_then_else (ltgt (match_dup 1) (const_int 0))
1539 (label_ref (match_operand 0 "" ""))
1543 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1545 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LTGT);
1546 emit_jump_insn (gen_bne (operands[0]));
1549 operands[1] = gen_compare_reg (LTGT, sparc_compare_op0, sparc_compare_op1);
1552 ;; Now match both normal and inverted jump.
1554 ;; XXX fpcmp nop braindamage
1555 (define_insn "*normal_branch"
1557 (if_then_else (match_operator 0 "noov_compare_op"
1558 [(reg 100) (const_int 0)])
1559 (label_ref (match_operand 1 "" ""))
1563 return output_cbranch (operands[0], operands[1], 1, 0,
1564 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1567 [(set_attr "type" "branch")
1568 (set_attr "branch_type" "icc")])
1570 ;; XXX fpcmp nop braindamage
1571 (define_insn "*inverted_branch"
1573 (if_then_else (match_operator 0 "noov_compare_op"
1574 [(reg 100) (const_int 0)])
1576 (label_ref (match_operand 1 "" ""))))]
1579 return output_cbranch (operands[0], operands[1], 1, 1,
1580 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1583 [(set_attr "type" "branch")
1584 (set_attr "branch_type" "icc")])
1586 ;; XXX fpcmp nop braindamage
1587 (define_insn "*normal_fp_branch"
1589 (if_then_else (match_operator 1 "comparison_operator"
1590 [(match_operand:CCFP 0 "fcc_reg_operand" "c")
1592 (label_ref (match_operand 2 "" ""))
1596 return output_cbranch (operands[1], operands[2], 2, 0,
1597 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1600 [(set_attr "type" "branch")
1601 (set_attr "branch_type" "fcc")])
1603 ;; XXX fpcmp nop braindamage
1604 (define_insn "*inverted_fp_branch"
1606 (if_then_else (match_operator 1 "comparison_operator"
1607 [(match_operand:CCFP 0 "fcc_reg_operand" "c")
1610 (label_ref (match_operand 2 "" ""))))]
1613 return output_cbranch (operands[1], operands[2], 2, 1,
1614 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1617 [(set_attr "type" "branch")
1618 (set_attr "branch_type" "fcc")])
1620 ;; XXX fpcmp nop braindamage
1621 (define_insn "*normal_fpe_branch"
1623 (if_then_else (match_operator 1 "comparison_operator"
1624 [(match_operand:CCFPE 0 "fcc_reg_operand" "c")
1626 (label_ref (match_operand 2 "" ""))
1630 return output_cbranch (operands[1], operands[2], 2, 0,
1631 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1634 [(set_attr "type" "branch")
1635 (set_attr "branch_type" "fcc")])
1637 ;; XXX fpcmp nop braindamage
1638 (define_insn "*inverted_fpe_branch"
1640 (if_then_else (match_operator 1 "comparison_operator"
1641 [(match_operand:CCFPE 0 "fcc_reg_operand" "c")
1644 (label_ref (match_operand 2 "" ""))))]
1647 return output_cbranch (operands[1], operands[2], 2, 1,
1648 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1651 [(set_attr "type" "branch")
1652 (set_attr "branch_type" "fcc")])
1654 ;; SPARC V9-specific jump insns. None of these are guaranteed to be
1655 ;; in the architecture.
1657 ;; There are no 32 bit brreg insns.
1660 (define_insn "*normal_int_branch_sp64"
1662 (if_then_else (match_operator 0 "v9_regcmp_op"
1663 [(match_operand:DI 1 "register_operand" "r")
1665 (label_ref (match_operand 2 "" ""))
1669 return output_v9branch (operands[0], operands[2], 1, 2, 0,
1670 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1673 [(set_attr "type" "branch")
1674 (set_attr "branch_type" "reg")])
1677 (define_insn "*inverted_int_branch_sp64"
1679 (if_then_else (match_operator 0 "v9_regcmp_op"
1680 [(match_operand:DI 1 "register_operand" "r")
1683 (label_ref (match_operand 2 "" ""))))]
1686 return output_v9branch (operands[0], operands[2], 1, 2, 1,
1687 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1690 [(set_attr "type" "branch")
1691 (set_attr "branch_type" "reg")])
1693 ;; Load in operand 0 the (absolute) address of operand 1, which is a symbolic
1694 ;; value subject to a PC-relative relocation. Operand 2 is a helper function
1695 ;; that adds the PC value at the call point to operand 0.
1697 (define_insn "load_pcrel_sym"
1698 [(set (match_operand 0 "register_operand" "=r")
1699 (unspec [(match_operand 1 "symbolic_operand" "")
1700 (match_operand 2 "call_operand_address" "")] UNSPEC_LOAD_PCREL_SYM))
1701 (clobber (reg:SI 15))]
1704 if (flag_delayed_branch)
1705 return "sethi\t%%hi(%a1-4), %0\n\tcall\t%a2\n\t add\t%0, %%lo(%a1+4), %0";
1707 return "sethi\t%%hi(%a1-8), %0\n\tadd\t%0, %%lo(%a1-4), %0\n\tcall\t%a2\n\t nop";
1709 [(set (attr "type") (const_string "multi"))
1710 (set (attr "length")
1711 (if_then_else (eq_attr "delayed_branch" "true")
1715 ;; Move instructions
1717 (define_expand "movqi"
1718 [(set (match_operand:QI 0 "general_operand" "")
1719 (match_operand:QI 1 "general_operand" ""))]
1722 /* Working with CONST_INTs is easier, so convert
1723 a double if needed. */
1724 if (GET_CODE (operands[1]) == CONST_DOUBLE)
1726 operands[1] = GEN_INT (trunc_int_for_mode
1727 (CONST_DOUBLE_LOW (operands[1]), QImode));
1730 /* Handle sets of MEM first. */
1731 if (GET_CODE (operands[0]) == MEM)
1733 if (reg_or_0_operand (operands[1], QImode))
1736 if (! reload_in_progress)
1738 operands[0] = validize_mem (operands[0]);
1739 operands[1] = force_reg (QImode, operands[1]);
1743 /* Fixup TLS cases. */
1744 if (tls_symbolic_operand (operands [1]))
1745 operands[1] = legitimize_tls_address (operands[1]);
1747 /* Fixup PIC cases. */
1750 if (CONSTANT_P (operands[1])
1751 && pic_address_needs_scratch (operands[1]))
1752 operands[1] = legitimize_pic_address (operands[1], QImode, 0);
1754 if (symbolic_operand (operands[1], QImode))
1756 operands[1] = legitimize_pic_address (operands[1],
1758 (reload_in_progress ?
1765 /* All QI constants require only one insn, so proceed. */
1771 (define_insn "*movqi_insn"
1772 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m")
1773 (match_operand:QI 1 "input_operand" "rI,m,rJ"))]
1774 "(register_operand (operands[0], QImode)
1775 || reg_or_0_operand (operands[1], QImode))"
1780 [(set_attr "type" "*,load,store")
1781 (set_attr "us3load_type" "*,3cycle,*")])
1783 (define_expand "movhi"
1784 [(set (match_operand:HI 0 "general_operand" "")
1785 (match_operand:HI 1 "general_operand" ""))]
1788 /* Working with CONST_INTs is easier, so convert
1789 a double if needed. */
1790 if (GET_CODE (operands[1]) == CONST_DOUBLE)
1791 operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
1793 /* Handle sets of MEM first. */
1794 if (GET_CODE (operands[0]) == MEM)
1796 if (reg_or_0_operand (operands[1], HImode))
1799 if (! reload_in_progress)
1801 operands[0] = validize_mem (operands[0]);
1802 operands[1] = force_reg (HImode, operands[1]);
1806 /* Fixup TLS cases. */
1807 if (tls_symbolic_operand (operands [1]))
1808 operands[1] = legitimize_tls_address (operands[1]);
1810 /* Fixup PIC cases. */
1813 if (CONSTANT_P (operands[1])
1814 && pic_address_needs_scratch (operands[1]))
1815 operands[1] = legitimize_pic_address (operands[1], HImode, 0);
1817 if (symbolic_operand (operands[1], HImode))
1819 operands[1] = legitimize_pic_address (operands[1],
1821 (reload_in_progress ?
1828 /* This makes sure we will not get rematched due to splittage. */
1829 if (! CONSTANT_P (operands[1]) || input_operand (operands[1], HImode))
1831 else if (CONSTANT_P (operands[1])
1832 && GET_CODE (operands[1]) != HIGH
1833 && GET_CODE (operands[1]) != LO_SUM)
1835 sparc_emit_set_const32 (operands[0], operands[1]);
1842 (define_insn "*movhi_const64_special"
1843 [(set (match_operand:HI 0 "register_operand" "=r")
1844 (match_operand:HI 1 "const64_high_operand" ""))]
1846 "sethi\t%%hi(%a1), %0")
1848 (define_insn "*movhi_insn"
1849 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1850 (match_operand:HI 1 "input_operand" "rI,K,m,rJ"))]
1851 "(register_operand (operands[0], HImode)
1852 || reg_or_0_operand (operands[1], HImode))"
1855 sethi\t%%hi(%a1), %0
1858 [(set_attr "type" "*,*,load,store")
1859 (set_attr "us3load_type" "*,*,3cycle,*")])
1861 ;; We always work with constants here.
1862 (define_insn "*movhi_lo_sum"
1863 [(set (match_operand:HI 0 "register_operand" "=r")
1864 (ior:HI (match_operand:HI 1 "register_operand" "%r")
1865 (match_operand:HI 2 "small_int" "I")))]
1869 (define_expand "movsi"
1870 [(set (match_operand:SI 0 "general_operand" "")
1871 (match_operand:SI 1 "general_operand" ""))]
1874 /* Working with CONST_INTs is easier, so convert
1875 a double if needed. */
1876 if (GET_CODE (operands[1]) == CONST_DOUBLE)
1877 operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
1879 /* Handle sets of MEM first. */
1880 if (GET_CODE (operands[0]) == MEM)
1882 if (reg_or_0_operand (operands[1], SImode))
1885 if (! reload_in_progress)
1887 operands[0] = validize_mem (operands[0]);
1888 operands[1] = force_reg (SImode, operands[1]);
1892 /* Fixup TLS cases. */
1893 if (tls_symbolic_operand (operands [1]))
1894 operands[1] = legitimize_tls_address (operands[1]);
1896 /* Fixup PIC cases. */
1899 if (CONSTANT_P (operands[1])
1900 && pic_address_needs_scratch (operands[1]))
1901 operands[1] = legitimize_pic_address (operands[1], SImode, 0);
1903 if (GET_CODE (operands[1]) == LABEL_REF)
1906 emit_insn (gen_movsi_pic_label_ref (operands[0], operands[1]));
1910 if (symbolic_operand (operands[1], SImode))
1912 operands[1] = legitimize_pic_address (operands[1],
1914 (reload_in_progress ?
1921 /* If we are trying to toss an integer constant into the
1922 FPU registers, force it into memory. */
1923 if (GET_CODE (operands[0]) == REG
1924 && REGNO (operands[0]) >= SPARC_FIRST_FP_REG
1925 && REGNO (operands[0]) <= SPARC_LAST_V9_FP_REG
1926 && CONSTANT_P (operands[1]))
1927 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
1930 /* This makes sure we will not get rematched due to splittage. */
1931 if (! CONSTANT_P (operands[1]) || input_operand (operands[1], SImode))
1933 else if (CONSTANT_P (operands[1])
1934 && GET_CODE (operands[1]) != HIGH
1935 && GET_CODE (operands[1]) != LO_SUM)
1937 sparc_emit_set_const32 (operands[0], operands[1]);
1944 ;; This is needed to show CSE exactly which bits are set
1945 ;; in a 64-bit register by sethi instructions.
1946 (define_insn "*movsi_const64_special"
1947 [(set (match_operand:SI 0 "register_operand" "=r")
1948 (match_operand:SI 1 "const64_high_operand" ""))]
1950 "sethi\t%%hi(%a1), %0")
1952 (define_insn "*movsi_insn"
1953 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,f,r,r,r,f,m,m,d")
1954 (match_operand:SI 1 "input_operand" "rI,!f,K,J,m,!m,rJ,!f,J"))]
1955 "(register_operand (operands[0], SImode)
1956 || reg_or_0_operand (operands[1], SImode))"
1960 sethi\t%%hi(%a1), %0
1967 [(set_attr "type" "*,fpmove,*,*,load,fpload,store,fpstore,fga")])
1969 (define_insn "*movsi_lo_sum"
1970 [(set (match_operand:SI 0 "register_operand" "=r")
1971 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1972 (match_operand:SI 2 "immediate_operand" "in")))]
1974 "or\t%1, %%lo(%a2), %0")
1976 (define_insn "*movsi_high"
1977 [(set (match_operand:SI 0 "register_operand" "=r")
1978 (high:SI (match_operand:SI 1 "immediate_operand" "in")))]
1980 "sethi\t%%hi(%a1), %0")
1982 ;; The next two patterns must wrap the SYMBOL_REF in an UNSPEC
1983 ;; so that CSE won't optimize the address computation away.
1984 (define_insn "movsi_lo_sum_pic"
1985 [(set (match_operand:SI 0 "register_operand" "=r")
1986 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1987 (unspec:SI [(match_operand:SI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
1989 "or\t%1, %%lo(%a2), %0")
1991 (define_insn "movsi_high_pic"
1992 [(set (match_operand:SI 0 "register_operand" "=r")
1993 (high:SI (unspec:SI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
1994 "flag_pic && check_pic (1)"
1995 "sethi\t%%hi(%a1), %0")
1997 (define_expand "movsi_pic_label_ref"
1998 [(set (match_dup 3) (high:SI
1999 (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
2000 (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
2001 (set (match_dup 4) (lo_sum:SI (match_dup 3)
2002 (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
2003 (set (match_operand:SI 0 "register_operand" "=r")
2004 (minus:SI (match_dup 5) (match_dup 4)))]
2007 current_function_uses_pic_offset_table = 1;
2008 operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
2011 operands[3] = operands[0];
2012 operands[4] = operands[0];
2016 operands[3] = gen_reg_rtx (SImode);
2017 operands[4] = gen_reg_rtx (SImode);
2019 operands[5] = pic_offset_table_rtx;
2022 (define_insn "*movsi_high_pic_label_ref"
2023 [(set (match_operand:SI 0 "register_operand" "=r")
2025 (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
2026 (match_operand:SI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
2028 "sethi\t%%hi(%a2-(%a1-.)), %0")
2030 (define_insn "*movsi_lo_sum_pic_label_ref"
2031 [(set (match_operand:SI 0 "register_operand" "=r")
2032 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
2033 (unspec:SI [(match_operand:SI 2 "label_ref_operand" "")
2034 (match_operand:SI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
2036 "or\t%1, %%lo(%a3-(%a2-.)), %0")
2038 (define_expand "movdi"
2039 [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand" "")
2040 (match_operand:DI 1 "general_operand" ""))]
2043 /* Where possible, convert CONST_DOUBLE into a CONST_INT. */
2044 if (GET_CODE (operands[1]) == CONST_DOUBLE
2045 #if HOST_BITS_PER_WIDE_INT == 32
2046 && ((CONST_DOUBLE_HIGH (operands[1]) == 0
2047 && (CONST_DOUBLE_LOW (operands[1]) & 0x80000000) == 0)
2048 || (CONST_DOUBLE_HIGH (operands[1]) == (HOST_WIDE_INT) 0xffffffff
2049 && (CONST_DOUBLE_LOW (operands[1]) & 0x80000000) != 0))
2052 operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
2054 /* Handle MEM cases first. */
2055 if (GET_CODE (operands[0]) == MEM)
2057 /* If it's a REG, we can always do it.
2058 The const zero case is more complex, on v9
2059 we can always perform it. */
2060 if (register_operand (operands[1], DImode)
2062 && (operands[1] == const0_rtx)))
2065 if (! reload_in_progress)
2067 operands[0] = validize_mem (operands[0]);
2068 operands[1] = force_reg (DImode, operands[1]);
2072 /* Fixup TLS cases. */
2073 if (tls_symbolic_operand (operands [1]))
2074 operands[1] = legitimize_tls_address (operands[1]);
2078 if (CONSTANT_P (operands[1])
2079 && pic_address_needs_scratch (operands[1]))
2080 operands[1] = legitimize_pic_address (operands[1], DImode, 0);
2082 if (GET_CODE (operands[1]) == LABEL_REF)
2084 if (! TARGET_ARCH64)
2086 emit_insn (gen_movdi_pic_label_ref (operands[0], operands[1]));
2090 if (symbolic_operand (operands[1], DImode))
2092 operands[1] = legitimize_pic_address (operands[1],
2094 (reload_in_progress ?
2101 /* If we are trying to toss an integer constant into the
2102 FPU registers, force it into memory. */
2103 if (GET_CODE (operands[0]) == REG
2104 && REGNO (operands[0]) >= SPARC_FIRST_FP_REG
2105 && REGNO (operands[0]) <= SPARC_LAST_V9_FP_REG
2106 && CONSTANT_P (operands[1]))
2107 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
2110 /* This makes sure we will not get rematched due to splittage. */
2111 if (! CONSTANT_P (operands[1]) || input_operand (operands[1], DImode))
2113 else if (TARGET_ARCH64
2114 && GET_CODE (operands[1]) != HIGH
2115 && GET_CODE (operands[1]) != LO_SUM)
2117 sparc_emit_set_const64 (operands[0], operands[1]);
2125 ;; Be careful, fmovd does not exist when !v9.
2126 ;; We match MEM moves directly when we have correct even
2127 ;; numbered registers, but fall into splits otherwise.
2128 ;; The constraint ordering here is really important to
2129 ;; avoid insane problems in reload, especially for patterns
2132 ;; (set (mem:DI (plus:SI (reg:SI 30 %fp)
2133 ;; (const_int -5016)))
2137 (define_insn "*movdi_insn_sp32_v9"
2138 [(set (match_operand:DI 0 "nonimmediate_operand"
2139 "=T,o,T,U,o,r,r,r,?T,?f,?f,?o,?e,?e,?W")
2140 (match_operand:DI 1 "input_operand"
2141 " J,J,U,T,r,o,i,r, f, T, o, f, e, W, e"))]
2142 "! TARGET_ARCH64 && TARGET_V9
2143 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2160 [(set_attr "type" "store,store,store,load,*,*,*,*,fpstore,fpload,*,*,fpmove,fpload,fpstore")
2161 (set_attr "length" "*,2,*,*,2,2,2,2,*,*,2,2,*,*,*")
2162 (set_attr "fptype" "*,*,*,*,*,*,*,*,*,*,*,*,double,*,*")])
2164 (define_insn "*movdi_insn_sp32"
2165 [(set (match_operand:DI 0 "nonimmediate_operand"
2166 "=o,T,U,o,r,r,r,?T,?f,?f,?o,?f")
2167 (match_operand:DI 1 "input_operand"
2168 " J,U,T,r,o,i,r, f, T, o, f, f"))]
2170 && (register_operand (operands[0], DImode)
2171 || register_operand (operands[1], DImode))"
2185 [(set_attr "type" "store,store,load,*,*,*,*,fpstore,fpload,*,*,*")
2186 (set_attr "length" "2,*,*,2,2,2,2,*,*,2,2,2")])
2188 ;; The following are generated by sparc_emit_set_const64
2189 (define_insn "*movdi_sp64_dbl"
2190 [(set (match_operand:DI 0 "register_operand" "=r")
2191 (match_operand:DI 1 "const64_operand" ""))]
2193 && HOST_BITS_PER_WIDE_INT != 64)"
2196 ;; This is needed to show CSE exactly which bits are set
2197 ;; in a 64-bit register by sethi instructions.
2198 (define_insn "*movdi_const64_special"
2199 [(set (match_operand:DI 0 "register_operand" "=r")
2200 (match_operand:DI 1 "const64_high_operand" ""))]
2202 "sethi\t%%hi(%a1), %0")
2204 (define_insn "*movdi_insn_sp64_novis"
2205 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,m,?e,?e,?W")
2206 (match_operand:DI 1 "input_operand" "rI,N,J,m,rJ,e,W,e"))]
2207 "TARGET_ARCH64 && ! TARGET_VIS
2208 && (register_operand (operands[0], DImode)
2209 || reg_or_0_operand (operands[1], DImode))"
2212 sethi\t%%hi(%a1), %0
2219 [(set_attr "type" "*,*,*,load,store,fpmove,fpload,fpstore")
2220 (set_attr "fptype" "*,*,*,*,*,double,*,*")])
2222 ;; We don't define V1SI because SI should work just fine.
2223 (define_mode_macro V64 [DF V2SI V4HI V8QI])
2224 (define_mode_macro V32 [SF V2HI V4QI])
2226 (define_insn "*movdi_insn_sp64_vis"
2227 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,m,?e,?e,?W,b")
2228 (match_operand:DI 1 "input_operand" "rI,N,J,m,rJ,e,W,e,J"))]
2229 "TARGET_ARCH64 && TARGET_VIS &&
2230 (register_operand (operands[0], DImode)
2231 || reg_or_0_operand (operands[1], DImode))"
2234 sethi\t%%hi(%a1), %0
2242 [(set_attr "type" "*,*,*,load,store,fpmove,fpload,fpstore,fga")
2243 (set_attr "fptype" "*,*,*,*,*,double,*,*,double")])
2245 (define_expand "movdi_pic_label_ref"
2246 [(set (match_dup 3) (high:DI
2247 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
2248 (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
2249 (set (match_dup 4) (lo_sum:DI (match_dup 3)
2250 (unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
2251 (set (match_operand:DI 0 "register_operand" "=r")
2252 (minus:DI (match_dup 5) (match_dup 4)))]
2253 "TARGET_ARCH64 && flag_pic"
2255 current_function_uses_pic_offset_table = 1;
2256 operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
2259 operands[3] = operands[0];
2260 operands[4] = operands[0];
2264 operands[3] = gen_reg_rtx (DImode);
2265 operands[4] = gen_reg_rtx (DImode);
2267 operands[5] = pic_offset_table_rtx;
2270 (define_insn "*movdi_high_pic_label_ref"
2271 [(set (match_operand:DI 0 "register_operand" "=r")
2273 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
2274 (match_operand:DI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
2275 "TARGET_ARCH64 && flag_pic"
2276 "sethi\t%%hi(%a2-(%a1-.)), %0")
2278 (define_insn "*movdi_lo_sum_pic_label_ref"
2279 [(set (match_operand:DI 0 "register_operand" "=r")
2280 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2281 (unspec:DI [(match_operand:DI 2 "label_ref_operand" "")
2282 (match_operand:DI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
2283 "TARGET_ARCH64 && flag_pic"
2284 "or\t%1, %%lo(%a3-(%a2-.)), %0")
2286 ;; SPARC-v9 code model support insns. See sparc_emit_set_symbolic_const64
2287 ;; in sparc.c to see what is going on here... PIC stuff comes first.
2289 (define_insn "movdi_lo_sum_pic"
2290 [(set (match_operand:DI 0 "register_operand" "=r")
2291 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2292 (unspec:DI [(match_operand:DI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
2293 "TARGET_ARCH64 && flag_pic"
2294 "or\t%1, %%lo(%a2), %0")
2296 (define_insn "movdi_high_pic"
2297 [(set (match_operand:DI 0 "register_operand" "=r")
2298 (high:DI (unspec:DI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
2299 "TARGET_ARCH64 && flag_pic && check_pic (1)"
2300 "sethi\t%%hi(%a1), %0")
2302 (define_insn "*sethi_di_medlow_embmedany_pic"
2303 [(set (match_operand:DI 0 "register_operand" "=r")
2304 (high:DI (match_operand:DI 1 "sp64_medium_pic_operand" "")))]
2305 "(TARGET_CM_MEDLOW || TARGET_CM_EMBMEDANY) && check_pic (1)"
2306 "sethi\t%%hi(%a1), %0")
2308 (define_insn "*sethi_di_medlow"
2309 [(set (match_operand:DI 0 "register_operand" "=r")
2310 (high:DI (match_operand:DI 1 "symbolic_operand" "")))]
2311 "TARGET_CM_MEDLOW && check_pic (1)"
2312 "sethi\t%%hi(%a1), %0")
2314 (define_insn "*losum_di_medlow"
2315 [(set (match_operand:DI 0 "register_operand" "=r")
2316 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2317 (match_operand:DI 2 "symbolic_operand" "")))]
2319 "or\t%1, %%lo(%a2), %0")
2321 (define_insn "seth44"
2322 [(set (match_operand:DI 0 "register_operand" "=r")
2323 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETH44)))]
2325 "sethi\t%%h44(%a1), %0")
2327 (define_insn "setm44"
2328 [(set (match_operand:DI 0 "register_operand" "=r")
2329 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2330 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_SETM44)))]
2332 "or\t%1, %%m44(%a2), %0")
2334 (define_insn "setl44"
2335 [(set (match_operand:DI 0 "register_operand" "=r")
2336 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2337 (match_operand:DI 2 "symbolic_operand" "")))]
2339 "or\t%1, %%l44(%a2), %0")
2341 (define_insn "sethh"
2342 [(set (match_operand:DI 0 "register_operand" "=r")
2343 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETHH)))]
2345 "sethi\t%%hh(%a1), %0")
2347 (define_insn "setlm"
2348 [(set (match_operand:DI 0 "register_operand" "=r")
2349 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETLM)))]
2351 "sethi\t%%lm(%a1), %0")
2353 (define_insn "sethm"
2354 [(set (match_operand:DI 0 "register_operand" "=r")
2355 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2356 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_EMB_SETHM)))]
2358 "or\t%1, %%hm(%a2), %0")
2360 (define_insn "setlo"
2361 [(set (match_operand:DI 0 "register_operand" "=r")
2362 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2363 (match_operand:DI 2 "symbolic_operand" "")))]
2365 "or\t%1, %%lo(%a2), %0")
2367 (define_insn "embmedany_sethi"
2368 [(set (match_operand:DI 0 "register_operand" "=r")
2369 (high:DI (unspec:DI [(match_operand:DI 1 "data_segment_operand" "")] UNSPEC_EMB_HISUM)))]
2370 "TARGET_CM_EMBMEDANY && check_pic (1)"
2371 "sethi\t%%hi(%a1), %0")
2373 (define_insn "embmedany_losum"
2374 [(set (match_operand:DI 0 "register_operand" "=r")
2375 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2376 (match_operand:DI 2 "data_segment_operand" "")))]
2377 "TARGET_CM_EMBMEDANY"
2378 "add\t%1, %%lo(%a2), %0")
2380 (define_insn "embmedany_brsum"
2381 [(set (match_operand:DI 0 "register_operand" "=r")
2382 (unspec:DI [(match_operand:DI 1 "register_operand" "r")] UNSPEC_EMB_HISUM))]
2383 "TARGET_CM_EMBMEDANY"
2386 (define_insn "embmedany_textuhi"
2387 [(set (match_operand:DI 0 "register_operand" "=r")
2388 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTUHI)))]
2389 "TARGET_CM_EMBMEDANY && check_pic (1)"
2390 "sethi\t%%uhi(%a1), %0")
2392 (define_insn "embmedany_texthi"
2393 [(set (match_operand:DI 0 "register_operand" "=r")
2394 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTHI)))]
2395 "TARGET_CM_EMBMEDANY && check_pic (1)"
2396 "sethi\t%%hi(%a1), %0")
2398 (define_insn "embmedany_textulo"
2399 [(set (match_operand:DI 0 "register_operand" "=r")
2400 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2401 (unspec:DI [(match_operand:DI 2 "text_segment_operand" "")] UNSPEC_EMB_TEXTULO)))]
2402 "TARGET_CM_EMBMEDANY"
2403 "or\t%1, %%ulo(%a2), %0")
2405 (define_insn "embmedany_textlo"
2406 [(set (match_operand:DI 0 "register_operand" "=r")
2407 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2408 (match_operand:DI 2 "text_segment_operand" "")))]
2409 "TARGET_CM_EMBMEDANY"
2410 "or\t%1, %%lo(%a2), %0")
2412 ;; Now some patterns to help reload out a bit.
2413 (define_expand "reload_indi"
2414 [(parallel [(match_operand:DI 0 "register_operand" "=r")
2415 (match_operand:DI 1 "immediate_operand" "")
2416 (match_operand:TI 2 "register_operand" "=&r")])]
2418 || TARGET_CM_EMBMEDANY)
2421 sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
2425 (define_expand "reload_outdi"
2426 [(parallel [(match_operand:DI 0 "register_operand" "=r")
2427 (match_operand:DI 1 "immediate_operand" "")
2428 (match_operand:TI 2 "register_operand" "=&r")])]
2430 || TARGET_CM_EMBMEDANY)
2433 sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
2437 ;; Split up putting CONSTs and REGs into DI regs when !arch64
2439 [(set (match_operand:DI 0 "register_operand" "")
2440 (match_operand:DI 1 "const_int_operand" ""))]
2441 "! TARGET_ARCH64 && reload_completed"
2442 [(clobber (const_int 0))]
2444 #if HOST_BITS_PER_WIDE_INT == 32
2445 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
2446 (INTVAL (operands[1]) < 0) ?
2449 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2452 unsigned int low, high;
2454 low = trunc_int_for_mode (INTVAL (operands[1]), SImode);
2455 high = trunc_int_for_mode (INTVAL (operands[1]) >> 32, SImode);
2456 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), GEN_INT (high)));
2458 /* Slick... but this trick loses if this subreg constant part
2459 can be done in one insn. */
2460 if (low == high && (low & 0x3ff) != 0 && low + 0x1000 >= 0x2000)
2461 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2462 gen_highpart (SImode, operands[0])));
2464 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), GEN_INT (low)));
2470 [(set (match_operand:DI 0 "register_operand" "")
2471 (match_operand:DI 1 "const_double_operand" ""))]
2475 && ((GET_CODE (operands[0]) == REG
2476 && REGNO (operands[0]) < 32)
2477 || (GET_CODE (operands[0]) == SUBREG
2478 && GET_CODE (SUBREG_REG (operands[0])) == REG
2479 && REGNO (SUBREG_REG (operands[0])) < 32))))"
2480 [(clobber (const_int 0))]
2482 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
2483 GEN_INT (CONST_DOUBLE_HIGH (operands[1]))));
2485 /* Slick... but this trick loses if this subreg constant part
2486 can be done in one insn. */
2487 if (CONST_DOUBLE_LOW (operands[1]) == CONST_DOUBLE_HIGH (operands[1])
2488 && !(SPARC_SETHI32_P (CONST_DOUBLE_HIGH (operands[1]))
2489 || SPARC_SIMM13_P (CONST_DOUBLE_HIGH (operands[1]))))
2491 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2492 gen_highpart (SImode, operands[0])));
2496 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2497 GEN_INT (CONST_DOUBLE_LOW (operands[1]))));
2503 [(set (match_operand:DI 0 "register_operand" "")
2504 (match_operand:DI 1 "register_operand" ""))]
2508 && ((GET_CODE (operands[0]) == REG
2509 && REGNO (operands[0]) < 32)
2510 || (GET_CODE (operands[0]) == SUBREG
2511 && GET_CODE (SUBREG_REG (operands[0])) == REG
2512 && REGNO (SUBREG_REG (operands[0])) < 32))))"
2513 [(clobber (const_int 0))]
2515 rtx set_dest = operands[0];
2516 rtx set_src = operands[1];
2520 dest1 = gen_highpart (SImode, set_dest);
2521 dest2 = gen_lowpart (SImode, set_dest);
2522 src1 = gen_highpart (SImode, set_src);
2523 src2 = gen_lowpart (SImode, set_src);
2525 /* Now emit using the real source and destination we found, swapping
2526 the order if we detect overlap. */
2527 if (reg_overlap_mentioned_p (dest1, src2))
2529 emit_insn (gen_movsi (dest2, src2));
2530 emit_insn (gen_movsi (dest1, src1));
2534 emit_insn (gen_movsi (dest1, src1));
2535 emit_insn (gen_movsi (dest2, src2));
2540 ;; Now handle the cases of memory moves from/to non-even
2541 ;; DI mode register pairs.
2543 [(set (match_operand:DI 0 "register_operand" "")
2544 (match_operand:DI 1 "memory_operand" ""))]
2547 && sparc_splitdi_legitimate (operands[0], operands[1]))"
2548 [(clobber (const_int 0))]
2550 rtx word0 = adjust_address (operands[1], SImode, 0);
2551 rtx word1 = adjust_address (operands[1], SImode, 4);
2552 rtx high_part = gen_highpart (SImode, operands[0]);
2553 rtx low_part = gen_lowpart (SImode, operands[0]);
2555 if (reg_overlap_mentioned_p (high_part, word1))
2557 emit_insn (gen_movsi (low_part, word1));
2558 emit_insn (gen_movsi (high_part, word0));
2562 emit_insn (gen_movsi (high_part, word0));
2563 emit_insn (gen_movsi (low_part, word1));
2569 [(set (match_operand:DI 0 "memory_operand" "")
2570 (match_operand:DI 1 "register_operand" ""))]
2573 && sparc_splitdi_legitimate (operands[1], operands[0]))"
2574 [(clobber (const_int 0))]
2576 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0),
2577 gen_highpart (SImode, operands[1])));
2578 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4),
2579 gen_lowpart (SImode, operands[1])));
2584 [(set (match_operand:DI 0 "memory_operand" "")
2589 && ! mem_min_alignment (operands[0], 8)))
2590 && offsettable_memref_p (operands[0])"
2591 [(clobber (const_int 0))]
2593 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0), const0_rtx));
2594 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4), const0_rtx));
2598 ;; Floating point move insns
2600 (define_insn "*movsf_insn_novis"
2601 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,*r,*r,*r,*r,*r,f,m,m")
2602 (match_operand:SF 1 "input_operand" "f,G,Q,*rR,S,m,m,f,*rG"))]
2603 "(TARGET_FPU && ! TARGET_VIS)
2604 && (register_operand (operands[0], SFmode)
2605 || register_operand (operands[1], SFmode)
2606 || fp_zero_operand (operands[1], SFmode))"
2608 if (GET_CODE (operands[1]) == CONST_DOUBLE
2609 && (which_alternative == 2
2610 || which_alternative == 3
2611 || which_alternative == 4))
2616 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2617 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2618 operands[1] = GEN_INT (i);
2621 switch (which_alternative)
2624 return "fmovs\t%1, %0";
2628 return "sethi\t%%hi(%a1), %0";
2630 return "mov\t%1, %0";
2635 return "ld\t%1, %0";
2638 return "st\t%r1, %0";
2643 [(set_attr "type" "fpmove,*,*,*,*,load,fpload,fpstore,store")])
2645 (define_insn "*movsf_insn_vis"
2646 [(set (match_operand:V32 0 "nonimmediate_operand" "=f,f,*r,*r,*r,*r,*r,f,m,m")
2647 (match_operand:V32 1 "input_operand" "f,GY,GY,Q,*rR,S,m,m,f,*rGY"))]
2648 "(TARGET_FPU && TARGET_VIS)
2649 && (register_operand (operands[0], <V32:MODE>mode)
2650 || register_operand (operands[1], <V32:MODE>mode)
2651 || fp_zero_operand (operands[1], <V32:MODE>mode))"
2653 if (GET_CODE (operands[1]) == CONST_DOUBLE
2654 && (which_alternative == 3
2655 || which_alternative == 4
2656 || which_alternative == 5))
2661 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2662 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2663 operands[1] = GEN_INT (i);
2666 switch (which_alternative)
2669 return "fmovs\t%1, %0";
2671 return "fzeros\t%0";
2675 return "sethi\t%%hi(%a1), %0";
2677 return "mov\t%1, %0";
2682 return "ld\t%1, %0";
2685 return "st\t%r1, %0";
2690 [(set_attr "type" "fpmove,fga,*,*,*,*,load,fpload,fpstore,store")])
2692 ;; Exactly the same as above, except that all `f' cases are deleted.
2693 ;; This is necessary to prevent reload from ever trying to use a `f' reg
2696 (define_insn "*movsf_no_f_insn"
2697 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r,r,r,m")
2698 (match_operand:SF 1 "input_operand" "G,Q,rR,S,m,rG"))]
2700 && (register_operand (operands[0], SFmode)
2701 || register_operand (operands[1], SFmode)
2702 || fp_zero_operand (operands[1], SFmode))"
2704 if (GET_CODE (operands[1]) == CONST_DOUBLE
2705 && (which_alternative == 1
2706 || which_alternative == 2
2707 || which_alternative == 3))
2712 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2713 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2714 operands[1] = GEN_INT (i);
2717 switch (which_alternative)
2722 return "sethi\t%%hi(%a1), %0";
2724 return "mov\t%1, %0";
2728 return "ld\t%1, %0";
2730 return "st\t%r1, %0";
2735 [(set_attr "type" "*,*,*,*,load,store")])
2737 ;; The following 3 patterns build SFmode constants in integer registers.
2739 (define_insn "*movsf_lo_sum"
2740 [(set (match_operand:SF 0 "register_operand" "=r")
2741 (lo_sum:SF (match_operand:SF 1 "register_operand" "r")
2742 (match_operand:SF 2 "const_double_operand" "S")))]
2743 "fp_high_losum_p (operands[2])"
2748 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[2]);
2749 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2750 operands[2] = GEN_INT (i);
2751 return "or\t%1, %%lo(%a2), %0";
2754 (define_insn "*movsf_high"
2755 [(set (match_operand:SF 0 "register_operand" "=r")
2756 (high:SF (match_operand:SF 1 "const_double_operand" "S")))]
2757 "fp_high_losum_p (operands[1])"
2762 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2763 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2764 operands[1] = GEN_INT (i);
2765 return "sethi\t%%hi(%1), %0";
2769 [(set (match_operand:SF 0 "register_operand" "")
2770 (match_operand:SF 1 "const_double_operand" ""))]
2771 "fp_high_losum_p (operands[1])
2772 && (GET_CODE (operands[0]) == REG
2773 && REGNO (operands[0]) < 32)"
2774 [(set (match_dup 0) (high:SF (match_dup 1)))
2775 (set (match_dup 0) (lo_sum:SF (match_dup 0) (match_dup 1)))])
2777 ;; Yes, you guessed it right, the former movsf expander.
2778 (define_expand "mov<V32:mode>"
2779 [(set (match_operand:V32 0 "general_operand" "")
2780 (match_operand:V32 1 "general_operand" ""))]
2781 "<V32:MODE>mode == SFmode || TARGET_VIS"
2783 /* Force constants into memory. */
2784 if (GET_CODE (operands[0]) == REG && CONSTANT_P (operands[1]))
2786 /* emit_group_store will send such bogosity to us when it is
2787 not storing directly into memory. So fix this up to avoid
2788 crashes in output_constant_pool. */
2789 if (operands [1] == const0_rtx)
2790 operands[1] = CONST0_RTX (<V32:MODE>mode);
2792 if ((TARGET_VIS || REGNO (operands[0]) < 32)
2793 && fp_zero_operand (operands[1], <V32:MODE>mode))
2796 /* We are able to build any SF constant in integer registers
2797 with at most 2 instructions. */
2798 if (REGNO (operands[0]) < 32
2799 && <V32:MODE>mode == SFmode)
2802 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
2806 /* Handle sets of MEM first. */
2807 if (GET_CODE (operands[0]) == MEM)
2809 if (register_operand (operands[1], <V32:MODE>mode)
2810 || fp_zero_operand (operands[1], <V32:MODE>mode))
2813 if (! reload_in_progress)
2815 operands[0] = validize_mem (operands[0]);
2816 operands[1] = force_reg (<V32:MODE>mode, operands[1]);
2820 /* Fixup PIC cases. */
2823 if (CONSTANT_P (operands[1])
2824 && pic_address_needs_scratch (operands[1]))
2825 operands[1] = legitimize_pic_address (operands[1], <V32:MODE>mode, 0);
2827 if (symbolic_operand (operands[1], <V32:MODE>mode))
2829 operands[1] = legitimize_pic_address (operands[1],
2831 (reload_in_progress ?
2841 ;; Yes, you again guessed it right, the former movdf expander.
2842 (define_expand "mov<V64:mode>"
2843 [(set (match_operand:V64 0 "general_operand" "")
2844 (match_operand:V64 1 "general_operand" ""))]
2845 "<V64:MODE>mode == DFmode || TARGET_VIS"
2847 /* Force constants into memory. */
2848 if (GET_CODE (operands[0]) == REG && CONSTANT_P (operands[1]))
2850 /* emit_group_store will send such bogosity to us when it is
2851 not storing directly into memory. So fix this up to avoid
2852 crashes in output_constant_pool. */
2853 if (operands [1] == const0_rtx)
2854 operands[1] = CONST0_RTX (<V64:MODE>mode);
2856 if ((TARGET_VIS || REGNO (operands[0]) < 32)
2857 && fp_zero_operand (operands[1], <V64:MODE>mode))
2860 /* We are able to build any DF constant in integer registers. */
2861 if (REGNO (operands[0]) < 32
2862 && <V64:MODE>mode == DFmode
2863 && (reload_completed || reload_in_progress))
2866 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
2870 /* Handle MEM cases first. */
2871 if (GET_CODE (operands[0]) == MEM)
2873 if (register_operand (operands[1], <V64:MODE>mode)
2874 || fp_zero_operand (operands[1], <V64:MODE>mode))
2877 if (! reload_in_progress)
2879 operands[0] = validize_mem (operands[0]);
2880 operands[1] = force_reg (<V64:MODE>mode, operands[1]);
2884 /* Fixup PIC cases. */
2887 if (CONSTANT_P (operands[1])
2888 && pic_address_needs_scratch (operands[1]))
2889 operands[1] = legitimize_pic_address (operands[1], <V64:MODE>mode, 0);
2891 if (symbolic_operand (operands[1], <V64:MODE>mode))
2893 operands[1] = legitimize_pic_address (operands[1],
2895 (reload_in_progress ?
2905 ;; Be careful, fmovd does not exist when !v9.
2906 (define_insn "*movdf_insn_sp32"
2907 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,W,U,T,o,e,*r,o,e,o")
2908 (match_operand:DF 1 "input_operand" "W#F,e,T,U,G,e,*rFo,*r,o#F,e"))]
2911 && (register_operand (operands[0], DFmode)
2912 || register_operand (operands[1], DFmode)
2913 || fp_zero_operand (operands[1], DFmode))"
2925 [(set_attr "type" "fpload,fpstore,load,store,*,*,*,*,*,*")
2926 (set_attr "length" "*,*,*,*,2,2,2,2,2,2")])
2928 (define_insn "*movdf_no_e_insn_sp32"
2929 [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,o,r,o")
2930 (match_operand:DF 1 "input_operand" "T,U,G,ro,r"))]
2934 && (register_operand (operands[0], DFmode)
2935 || register_operand (operands[1], DFmode)
2936 || fp_zero_operand (operands[1], DFmode))"
2943 [(set_attr "type" "load,store,*,*,*")
2944 (set_attr "length" "*,*,2,2,2")])
2946 (define_insn "*movdf_no_e_insn_v9_sp32"
2947 [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,T,r,o")
2948 (match_operand:DF 1 "input_operand" "T,U,G,ro,rG"))]
2952 && (register_operand (operands[0], DFmode)
2953 || register_operand (operands[1], DFmode)
2954 || fp_zero_operand (operands[1], DFmode))"
2961 [(set_attr "type" "load,store,store,*,*")
2962 (set_attr "length" "*,*,*,2,2")])
2964 ;; We have available v9 double floats but not 64-bit
2965 ;; integer registers and no VIS.
2966 (define_insn "*movdf_insn_v9only_novis"
2967 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,T,W,U,T,f,*r,o")
2968 (match_operand:DF 1 "input_operand" "e,W#F,G,e,T,U,o#F,*roF,*rGf"))]
2973 && (register_operand (operands[0], DFmode)
2974 || register_operand (operands[1], DFmode)
2975 || fp_zero_operand (operands[1], DFmode))"
2986 [(set_attr "type" "fpmove,load,store,store,load,store,*,*,*")
2987 (set_attr "length" "*,*,*,*,*,*,2,2,2")
2988 (set_attr "fptype" "double,*,*,*,*,*,*,*,*")])
2990 ;; We have available v9 double floats but not 64-bit
2991 ;; integer registers but we have VIS.
2992 (define_insn "*movdf_insn_v9only_vis"
2993 [(set (match_operand:V64 0 "nonimmediate_operand" "=e,e,e,T,W,U,T,f,*r,o")
2994 (match_operand:V64 1 "input_operand" "GY,e,W#F,GY,e,T,U,o#F,*roGYF,*rGYf"))]
2998 && (register_operand (operands[0], <V64:MODE>mode)
2999 || register_operand (operands[1], <V64:MODE>mode)
3000 || fp_zero_operand (operands[1], <V64:MODE>mode))"
3012 [(set_attr "type" "fga,fpmove,load,store,store,load,store,*,*,*")
3013 (set_attr "length" "*,*,*,*,*,*,*,2,2,2")
3014 (set_attr "fptype" "double,double,*,*,*,*,*,*,*,*")])
3016 ;; We have available both v9 double floats and 64-bit
3017 ;; integer registers. No VIS though.
3018 (define_insn "*movdf_insn_sp64_novis"
3019 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,W,*r,*r,m,*r")
3020 (match_operand:DF 1 "input_operand" "e,W#F,e,*rG,m,*rG,F"))]
3024 && (register_operand (operands[0], DFmode)
3025 || register_operand (operands[1], DFmode)
3026 || fp_zero_operand (operands[1], DFmode))"
3035 [(set_attr "type" "fpmove,load,store,*,load,store,*")
3036 (set_attr "length" "*,*,*,*,*,*,2")
3037 (set_attr "fptype" "double,*,*,*,*,*,*")])
3039 ;; We have available both v9 double floats and 64-bit
3040 ;; integer registers. And we have VIS.
3041 (define_insn "*movdf_insn_sp64_vis"
3042 [(set (match_operand:V64 0 "nonimmediate_operand" "=e,e,e,W,*r,*r,m,*r")
3043 (match_operand:V64 1 "input_operand" "GY,e,W#F,e,*rGY,m,*rGY,F"))]
3047 && (register_operand (operands[0], <V64:MODE>mode)
3048 || register_operand (operands[1], <V64:MODE>mode)
3049 || fp_zero_operand (operands[1], <V64:MODE>mode))"
3059 [(set_attr "type" "fga,fpmove,load,store,*,load,store,*")
3060 (set_attr "length" "*,*,*,*,*,*,*,2")
3061 (set_attr "fptype" "double,double,*,*,*,*,*,*")])
3063 (define_insn "*movdf_no_e_insn_sp64"
3064 [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m")
3065 (match_operand:DF 1 "input_operand" "r,m,rG"))]
3068 && (register_operand (operands[0], DFmode)
3069 || register_operand (operands[1], DFmode)
3070 || fp_zero_operand (operands[1], DFmode))"
3075 [(set_attr "type" "*,load,store")])
3077 ;; This pattern build DFmode constants in integer registers.
3079 [(set (match_operand:DF 0 "register_operand" "")
3080 (match_operand:DF 1 "const_double_operand" ""))]
3082 && (GET_CODE (operands[0]) == REG
3083 && REGNO (operands[0]) < 32)
3084 && ! fp_zero_operand(operands[1], DFmode)
3085 && reload_completed"
3086 [(clobber (const_int 0))]
3091 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3092 REAL_VALUE_TO_TARGET_DOUBLE (r, l);
3093 operands[0] = gen_rtx_raw_REG (DImode, REGNO (operands[0]));
3097 #if HOST_BITS_PER_WIDE_INT == 64
3100 val = ((HOST_WIDE_INT)(unsigned long)l[1] |
3101 ((HOST_WIDE_INT)(unsigned long)l[0] << 32));
3102 emit_insn (gen_movdi (operands[0], GEN_INT (val)));
3104 emit_insn (gen_movdi (operands[0],
3105 immed_double_const (l[1], l[0], DImode)));
3110 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
3113 /* Slick... but this trick loses if this subreg constant part
3114 can be done in one insn. */
3116 && !(SPARC_SETHI32_P (l[0])
3117 || SPARC_SIMM13_P (l[0])))
3119 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
3120 gen_highpart (SImode, operands[0])));
3124 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
3131 ;; Ok, now the splits to handle all the multi insn and
3132 ;; mis-aligned memory address cases.
3133 ;; In these splits please take note that we must be
3134 ;; careful when V9 but not ARCH64 because the integer
3135 ;; register DFmode cases must be handled.
3137 [(set (match_operand:V64 0 "register_operand" "")
3138 (match_operand:V64 1 "register_operand" ""))]
3141 && ((GET_CODE (operands[0]) == REG
3142 && REGNO (operands[0]) < 32)
3143 || (GET_CODE (operands[0]) == SUBREG
3144 && GET_CODE (SUBREG_REG (operands[0])) == REG
3145 && REGNO (SUBREG_REG (operands[0])) < 32))))
3146 && reload_completed"
3147 [(clobber (const_int 0))]
3149 rtx set_dest = operands[0];
3150 rtx set_src = operands[1];
3153 enum machine_mode half_mode;
3155 /* We can be expanded for DFmode or integral vector modes. */
3156 if (<V64:MODE>mode == DFmode)
3161 dest1 = gen_highpart (half_mode, set_dest);
3162 dest2 = gen_lowpart (half_mode, set_dest);
3163 src1 = gen_highpart (half_mode, set_src);
3164 src2 = gen_lowpart (half_mode, set_src);
3166 /* Now emit using the real source and destination we found, swapping
3167 the order if we detect overlap. */
3168 if (reg_overlap_mentioned_p (dest1, src2))
3170 emit_move_insn_1 (dest2, src2);
3171 emit_move_insn_1 (dest1, src1);
3175 emit_move_insn_1 (dest1, src1);
3176 emit_move_insn_1 (dest2, src2);
3182 [(set (match_operand:V64 0 "register_operand" "")
3183 (match_operand:V64 1 "memory_operand" ""))]
3186 && (((REGNO (operands[0]) % 2) != 0)
3187 || ! mem_min_alignment (operands[1], 8))
3188 && offsettable_memref_p (operands[1])"
3189 [(clobber (const_int 0))]
3191 enum machine_mode half_mode;
3194 /* We can be expanded for DFmode or integral vector modes. */
3195 if (<V64:MODE>mode == DFmode)
3200 word0 = adjust_address (operands[1], half_mode, 0);
3201 word1 = adjust_address (operands[1], half_mode, 4);
3203 if (reg_overlap_mentioned_p (gen_highpart (half_mode, operands[0]), word1))
3205 emit_move_insn_1 (gen_lowpart (half_mode, operands[0]), word1);
3206 emit_move_insn_1 (gen_highpart (half_mode, operands[0]), word0);
3210 emit_move_insn_1 (gen_highpart (half_mode, operands[0]), word0);
3211 emit_move_insn_1 (gen_lowpart (half_mode, operands[0]), word1);
3217 [(set (match_operand:V64 0 "memory_operand" "")
3218 (match_operand:V64 1 "register_operand" ""))]
3221 && (((REGNO (operands[1]) % 2) != 0)
3222 || ! mem_min_alignment (operands[0], 8))
3223 && offsettable_memref_p (operands[0])"
3224 [(clobber (const_int 0))]
3226 enum machine_mode half_mode;
3229 /* We can be expanded for DFmode or integral vector modes. */
3230 if (<V64:MODE>mode == DFmode)
3235 word0 = adjust_address (operands[0], half_mode, 0);
3236 word1 = adjust_address (operands[0], half_mode, 4);
3238 emit_move_insn_1 (word0, gen_highpart (half_mode, operands[1]));
3239 emit_move_insn_1 (word1, gen_lowpart (half_mode, operands[1]));
3244 [(set (match_operand:V64 0 "memory_operand" "")
3245 (match_operand:V64 1 "fp_zero_operand" ""))]
3249 && ! mem_min_alignment (operands[0], 8)))
3250 && offsettable_memref_p (operands[0])"
3251 [(clobber (const_int 0))]
3253 enum machine_mode half_mode;
3256 /* We can be expanded for DFmode or integral vector modes. */
3257 if (<V64:MODE>mode == DFmode)
3262 dest1 = adjust_address (operands[0], half_mode, 0);
3263 dest2 = adjust_address (operands[0], half_mode, 4);
3265 emit_move_insn_1 (dest1, CONST0_RTX (half_mode));
3266 emit_move_insn_1 (dest2, CONST0_RTX (half_mode));
3271 [(set (match_operand:V64 0 "register_operand" "")
3272 (match_operand:V64 1 "fp_zero_operand" ""))]
3275 && ((GET_CODE (operands[0]) == REG
3276 && REGNO (operands[0]) < 32)
3277 || (GET_CODE (operands[0]) == SUBREG
3278 && GET_CODE (SUBREG_REG (operands[0])) == REG
3279 && REGNO (SUBREG_REG (operands[0])) < 32))"
3280 [(clobber (const_int 0))]
3282 enum machine_mode half_mode;
3283 rtx set_dest = operands[0];
3286 /* We can be expanded for DFmode or integral vector modes. */
3287 if (<V64:MODE>mode == DFmode)
3292 dest1 = gen_highpart (half_mode, set_dest);
3293 dest2 = gen_lowpart (half_mode, set_dest);
3294 emit_move_insn_1 (dest1, CONST0_RTX (half_mode));
3295 emit_move_insn_1 (dest2, CONST0_RTX (half_mode));
3299 (define_expand "movtf"
3300 [(set (match_operand:TF 0 "general_operand" "")
3301 (match_operand:TF 1 "general_operand" ""))]
3304 /* Force TFmode constants into memory. */
3305 if (GET_CODE (operands[0]) == REG
3306 && CONSTANT_P (operands[1]))
3308 /* emit_group_store will send such bogosity to us when it is
3309 not storing directly into memory. So fix this up to avoid
3310 crashes in output_constant_pool. */
3311 if (operands [1] == const0_rtx)
3312 operands[1] = CONST0_RTX (TFmode);
3314 if (TARGET_VIS && fp_zero_operand (operands[1], TFmode))
3317 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
3321 /* Handle MEM cases first, note that only v9 guarantees
3322 full 16-byte alignment for quads. */
3323 if (GET_CODE (operands[0]) == MEM)
3325 if (register_operand (operands[1], TFmode)
3326 || fp_zero_operand (operands[1], TFmode))
3329 if (! reload_in_progress)
3331 operands[0] = validize_mem (operands[0]);
3332 operands[1] = force_reg (TFmode, operands[1]);
3336 /* Fixup PIC cases. */
3339 if (CONSTANT_P (operands[1])
3340 && pic_address_needs_scratch (operands[1]))
3341 operands[1] = legitimize_pic_address (operands[1], TFmode, 0);
3343 if (symbolic_operand (operands[1], TFmode))
3345 operands[1] = legitimize_pic_address (operands[1],
3347 (reload_in_progress ?
3357 ;; Be careful, fmovq and {st,ld}{x,q} do not exist when !arch64 so
3358 ;; we must split them all. :-(
3359 (define_insn "*movtf_insn_sp32"
3360 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,U,r")
3361 (match_operand:TF 1 "input_operand" "oe,GeUr,o,roG"))]
3365 && (register_operand (operands[0], TFmode)
3366 || register_operand (operands[1], TFmode)
3367 || fp_zero_operand (operands[1], TFmode))"
3369 [(set_attr "length" "4")])
3371 (define_insn "*movtf_insn_vis_sp32"
3372 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,U,r")
3373 (match_operand:TF 1 "input_operand" "Goe,GeUr,o,roG"))]
3377 && (register_operand (operands[0], TFmode)
3378 || register_operand (operands[1], TFmode)
3379 || fp_zero_operand (operands[1], TFmode))"
3381 [(set_attr "length" "4")])
3383 ;; Exactly the same as above, except that all `e' cases are deleted.
3384 ;; This is necessary to prevent reload from ever trying to use a `e' reg
3387 (define_insn "*movtf_no_e_insn_sp32"
3388 [(set (match_operand:TF 0 "nonimmediate_operand" "=o,U,o,r,o")
3389 (match_operand:TF 1 "input_operand" "G,o,U,roG,r"))]
3392 && (register_operand (operands[0], TFmode)
3393 || register_operand (operands[1], TFmode)
3394 || fp_zero_operand (operands[1], TFmode))"
3396 [(set_attr "length" "4")])
3398 ;; Now handle the float reg cases directly when arch64,
3399 ;; hard_quad, and proper reg number alignment are all true.
3400 (define_insn "*movtf_insn_hq_sp64"
3401 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,e,m,o,r")
3402 (match_operand:TF 1 "input_operand" "e,m,e,Gr,roG"))]
3407 && (register_operand (operands[0], TFmode)
3408 || register_operand (operands[1], TFmode)
3409 || fp_zero_operand (operands[1], TFmode))"
3416 [(set_attr "type" "fpmove,fpload,fpstore,*,*")
3417 (set_attr "length" "*,*,*,2,2")])
3419 (define_insn "*movtf_insn_hq_vis_sp64"
3420 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,e,m,eo,r,o")
3421 (match_operand:TF 1 "input_operand" "e,m,e,G,roG,r"))]
3426 && (register_operand (operands[0], TFmode)
3427 || register_operand (operands[1], TFmode)
3428 || fp_zero_operand (operands[1], TFmode))"
3436 [(set_attr "type" "fpmove,fpload,fpstore,*,*,*")
3437 (set_attr "length" "*,*,*,2,2,2")])
3439 ;; Now we allow the integer register cases even when
3440 ;; only arch64 is true.
3441 (define_insn "*movtf_insn_sp64"
3442 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,r")
3443 (match_operand:TF 1 "input_operand" "oe,Ger,orG"))]
3447 && ! TARGET_HARD_QUAD
3448 && (register_operand (operands[0], TFmode)
3449 || register_operand (operands[1], TFmode)
3450 || fp_zero_operand (operands[1], TFmode))"
3452 [(set_attr "length" "2")])
3454 (define_insn "*movtf_insn_vis_sp64"
3455 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,r")
3456 (match_operand:TF 1 "input_operand" "Goe,Ger,orG"))]
3460 && ! TARGET_HARD_QUAD
3461 && (register_operand (operands[0], TFmode)
3462 || register_operand (operands[1], TFmode)
3463 || fp_zero_operand (operands[1], TFmode))"
3465 [(set_attr "length" "2")])
3467 (define_insn "*movtf_no_e_insn_sp64"
3468 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o")
3469 (match_operand:TF 1 "input_operand" "orG,rG"))]
3472 && (register_operand (operands[0], TFmode)
3473 || register_operand (operands[1], TFmode)
3474 || fp_zero_operand (operands[1], TFmode))"
3476 [(set_attr "length" "2")])
3478 ;; Now all the splits to handle multi-insn TF mode moves.
3480 [(set (match_operand:TF 0 "register_operand" "")
3481 (match_operand:TF 1 "register_operand" ""))]
3485 && ! TARGET_HARD_QUAD)
3486 || ! fp_register_operand (operands[0], TFmode))"
3487 [(clobber (const_int 0))]
3489 rtx set_dest = operands[0];
3490 rtx set_src = operands[1];
3494 dest1 = gen_df_reg (set_dest, 0);
3495 dest2 = gen_df_reg (set_dest, 1);
3496 src1 = gen_df_reg (set_src, 0);
3497 src2 = gen_df_reg (set_src, 1);
3499 /* Now emit using the real source and destination we found, swapping
3500 the order if we detect overlap. */
3501 if (reg_overlap_mentioned_p (dest1, src2))
3503 emit_insn (gen_movdf (dest2, src2));
3504 emit_insn (gen_movdf (dest1, src1));
3508 emit_insn (gen_movdf (dest1, src1));
3509 emit_insn (gen_movdf (dest2, src2));
3515 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3516 (match_operand:TF 1 "fp_zero_operand" ""))]
3518 [(clobber (const_int 0))]
3520 rtx set_dest = operands[0];
3523 switch (GET_CODE (set_dest))
3526 dest1 = gen_df_reg (set_dest, 0);
3527 dest2 = gen_df_reg (set_dest, 1);
3530 dest1 = adjust_address (set_dest, DFmode, 0);
3531 dest2 = adjust_address (set_dest, DFmode, 8);
3537 emit_insn (gen_movdf (dest1, CONST0_RTX (DFmode)));
3538 emit_insn (gen_movdf (dest2, CONST0_RTX (DFmode)));
3543 [(set (match_operand:TF 0 "register_operand" "")
3544 (match_operand:TF 1 "memory_operand" ""))]
3546 && offsettable_memref_p (operands[1])
3548 || ! TARGET_HARD_QUAD
3549 || ! fp_register_operand (operands[0], TFmode)))"
3550 [(clobber (const_int 0))]
3552 rtx word0 = adjust_address (operands[1], DFmode, 0);
3553 rtx word1 = adjust_address (operands[1], DFmode, 8);
3554 rtx set_dest, dest1, dest2;
3556 set_dest = operands[0];
3558 dest1 = gen_df_reg (set_dest, 0);
3559 dest2 = gen_df_reg (set_dest, 1);
3561 /* Now output, ordering such that we don't clobber any registers
3562 mentioned in the address. */
3563 if (reg_overlap_mentioned_p (dest1, word1))
3566 emit_insn (gen_movdf (dest2, word1));
3567 emit_insn (gen_movdf (dest1, word0));
3571 emit_insn (gen_movdf (dest1, word0));
3572 emit_insn (gen_movdf (dest2, word1));
3578 [(set (match_operand:TF 0 "memory_operand" "")
3579 (match_operand:TF 1 "register_operand" ""))]
3581 && offsettable_memref_p (operands[0])
3583 || ! TARGET_HARD_QUAD
3584 || ! fp_register_operand (operands[1], TFmode)))"
3585 [(clobber (const_int 0))]
3587 rtx set_src = operands[1];
3589 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 0),
3590 gen_df_reg (set_src, 0)));
3591 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 8),
3592 gen_df_reg (set_src, 1)));
3596 ;; SPARC V9 conditional move instructions.
3598 ;; We can handle larger constants here for some flavors, but for now we keep
3599 ;; it simple and only allow those constants supported by all flavors.
3600 ;; Note that emit_conditional_move canonicalizes operands 2,3 so that operand
3601 ;; 3 contains the constant if one is present, but we handle either for
3602 ;; generality (sparc.c puts a constant in operand 2).
3604 (define_expand "movqicc"
3605 [(set (match_operand:QI 0 "register_operand" "")
3606 (if_then_else:QI (match_operand 1 "comparison_operator" "")
3607 (match_operand:QI 2 "arith10_operand" "")
3608 (match_operand:QI 3 "arith10_operand" "")))]
3611 enum rtx_code code = GET_CODE (operands[1]);
3613 if (GET_MODE (sparc_compare_op0) == DImode
3617 if (sparc_compare_op1 == const0_rtx
3618 && GET_CODE (sparc_compare_op0) == REG
3619 && GET_MODE (sparc_compare_op0) == DImode
3620 && v9_regcmp_p (code))
3622 operands[1] = gen_rtx_fmt_ee (code, DImode,
3623 sparc_compare_op0, sparc_compare_op1);
3627 rtx cc_reg = gen_compare_reg (code,
3628 sparc_compare_op0, sparc_compare_op1);
3629 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3633 (define_expand "movhicc"
3634 [(set (match_operand:HI 0 "register_operand" "")
3635 (if_then_else:HI (match_operand 1 "comparison_operator" "")
3636 (match_operand:HI 2 "arith10_operand" "")
3637 (match_operand:HI 3 "arith10_operand" "")))]
3640 enum rtx_code code = GET_CODE (operands[1]);
3642 if (GET_MODE (sparc_compare_op0) == DImode
3646 if (sparc_compare_op1 == const0_rtx
3647 && GET_CODE (sparc_compare_op0) == REG
3648 && GET_MODE (sparc_compare_op0) == DImode
3649 && v9_regcmp_p (code))
3651 operands[1] = gen_rtx_fmt_ee (code, DImode,
3652 sparc_compare_op0, sparc_compare_op1);
3656 rtx cc_reg = gen_compare_reg (code,
3657 sparc_compare_op0, sparc_compare_op1);
3658 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3662 (define_expand "movsicc"
3663 [(set (match_operand:SI 0 "register_operand" "")
3664 (if_then_else:SI (match_operand 1 "comparison_operator" "")
3665 (match_operand:SI 2 "arith10_operand" "")
3666 (match_operand:SI 3 "arith10_operand" "")))]
3669 enum rtx_code code = GET_CODE (operands[1]);
3670 enum machine_mode op0_mode = GET_MODE (sparc_compare_op0);
3672 if (sparc_compare_op1 == const0_rtx
3673 && GET_CODE (sparc_compare_op0) == REG
3674 && (TARGET_ARCH64 && op0_mode == DImode && v9_regcmp_p (code)))
3676 operands[1] = gen_rtx_fmt_ee (code, op0_mode,
3677 sparc_compare_op0, sparc_compare_op1);
3681 rtx cc_reg = gen_compare_reg (code,
3682 sparc_compare_op0, sparc_compare_op1);
3683 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg),
3684 cc_reg, const0_rtx);
3688 (define_expand "movdicc"
3689 [(set (match_operand:DI 0 "register_operand" "")
3690 (if_then_else:DI (match_operand 1 "comparison_operator" "")
3691 (match_operand:DI 2 "arith10_double_operand" "")
3692 (match_operand:DI 3 "arith10_double_operand" "")))]
3695 enum rtx_code code = GET_CODE (operands[1]);
3697 if (sparc_compare_op1 == const0_rtx
3698 && GET_CODE (sparc_compare_op0) == REG
3699 && GET_MODE (sparc_compare_op0) == DImode
3700 && v9_regcmp_p (code))
3702 operands[1] = gen_rtx_fmt_ee (code, DImode,
3703 sparc_compare_op0, sparc_compare_op1);
3707 rtx cc_reg = gen_compare_reg (code,
3708 sparc_compare_op0, sparc_compare_op1);
3709 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg),
3710 cc_reg, const0_rtx);
3714 (define_expand "movsfcc"
3715 [(set (match_operand:SF 0 "register_operand" "")
3716 (if_then_else:SF (match_operand 1 "comparison_operator" "")
3717 (match_operand:SF 2 "register_operand" "")
3718 (match_operand:SF 3 "register_operand" "")))]
3719 "TARGET_V9 && TARGET_FPU"
3721 enum rtx_code code = GET_CODE (operands[1]);
3723 if (GET_MODE (sparc_compare_op0) == DImode
3727 if (sparc_compare_op1 == const0_rtx
3728 && GET_CODE (sparc_compare_op0) == REG
3729 && GET_MODE (sparc_compare_op0) == DImode
3730 && v9_regcmp_p (code))
3732 operands[1] = gen_rtx_fmt_ee (code, DImode,
3733 sparc_compare_op0, sparc_compare_op1);
3737 rtx cc_reg = gen_compare_reg (code,
3738 sparc_compare_op0, sparc_compare_op1);
3739 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3743 (define_expand "movdfcc"
3744 [(set (match_operand:DF 0 "register_operand" "")
3745 (if_then_else:DF (match_operand 1 "comparison_operator" "")
3746 (match_operand:DF 2 "register_operand" "")
3747 (match_operand:DF 3 "register_operand" "")))]
3748 "TARGET_V9 && TARGET_FPU"
3750 enum rtx_code code = GET_CODE (operands[1]);
3752 if (GET_MODE (sparc_compare_op0) == DImode
3756 if (sparc_compare_op1 == const0_rtx
3757 && GET_CODE (sparc_compare_op0) == REG
3758 && GET_MODE (sparc_compare_op0) == DImode
3759 && v9_regcmp_p (code))
3761 operands[1] = gen_rtx_fmt_ee (code, DImode,
3762 sparc_compare_op0, sparc_compare_op1);
3766 rtx cc_reg = gen_compare_reg (code,
3767 sparc_compare_op0, sparc_compare_op1);
3768 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3772 (define_expand "movtfcc"
3773 [(set (match_operand:TF 0 "register_operand" "")
3774 (if_then_else:TF (match_operand 1 "comparison_operator" "")
3775 (match_operand:TF 2 "register_operand" "")
3776 (match_operand:TF 3 "register_operand" "")))]
3777 "TARGET_V9 && TARGET_FPU"
3779 enum rtx_code code = GET_CODE (operands[1]);
3781 if (GET_MODE (sparc_compare_op0) == DImode
3785 if (sparc_compare_op1 == const0_rtx
3786 && GET_CODE (sparc_compare_op0) == REG
3787 && GET_MODE (sparc_compare_op0) == DImode
3788 && v9_regcmp_p (code))
3790 operands[1] = gen_rtx_fmt_ee (code, DImode,
3791 sparc_compare_op0, sparc_compare_op1);
3795 rtx cc_reg = gen_compare_reg (code,
3796 sparc_compare_op0, sparc_compare_op1);
3797 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3801 ;; Conditional move define_insns.
3803 (define_insn "*movqi_cc_sp64"
3804 [(set (match_operand:QI 0 "register_operand" "=r,r")
3805 (if_then_else:QI (match_operator 1 "comparison_operator"
3806 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3808 (match_operand:QI 3 "arith11_operand" "rL,0")
3809 (match_operand:QI 4 "arith11_operand" "0,rL")))]
3813 mov%c1\t%x2, %4, %0"
3814 [(set_attr "type" "cmove")])
3816 (define_insn "*movhi_cc_sp64"
3817 [(set (match_operand:HI 0 "register_operand" "=r,r")
3818 (if_then_else:HI (match_operator 1 "comparison_operator"
3819 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3821 (match_operand:HI 3 "arith11_operand" "rL,0")
3822 (match_operand:HI 4 "arith11_operand" "0,rL")))]
3826 mov%c1\t%x2, %4, %0"
3827 [(set_attr "type" "cmove")])
3829 (define_insn "*movsi_cc_sp64"
3830 [(set (match_operand:SI 0 "register_operand" "=r,r")
3831 (if_then_else:SI (match_operator 1 "comparison_operator"
3832 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3834 (match_operand:SI 3 "arith11_operand" "rL,0")
3835 (match_operand:SI 4 "arith11_operand" "0,rL")))]
3839 mov%c1\t%x2, %4, %0"
3840 [(set_attr "type" "cmove")])
3842 ;; ??? The constraints of operands 3,4 need work.
3843 (define_insn "*movdi_cc_sp64"
3844 [(set (match_operand:DI 0 "register_operand" "=r,r")
3845 (if_then_else:DI (match_operator 1 "comparison_operator"
3846 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3848 (match_operand:DI 3 "arith11_double_operand" "rLH,0")
3849 (match_operand:DI 4 "arith11_double_operand" "0,rLH")))]
3853 mov%c1\t%x2, %4, %0"
3854 [(set_attr "type" "cmove")])
3856 (define_insn "*movdi_cc_sp64_trunc"
3857 [(set (match_operand:SI 0 "register_operand" "=r,r")
3858 (if_then_else:SI (match_operator 1 "comparison_operator"
3859 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3861 (match_operand:SI 3 "arith11_double_operand" "rLH,0")
3862 (match_operand:SI 4 "arith11_double_operand" "0,rLH")))]
3866 mov%c1\t%x2, %4, %0"
3867 [(set_attr "type" "cmove")])
3869 (define_insn "*movsf_cc_sp64"
3870 [(set (match_operand:SF 0 "register_operand" "=f,f")
3871 (if_then_else:SF (match_operator 1 "comparison_operator"
3872 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3874 (match_operand:SF 3 "register_operand" "f,0")
3875 (match_operand:SF 4 "register_operand" "0,f")))]
3876 "TARGET_V9 && TARGET_FPU"
3878 fmovs%C1\t%x2, %3, %0
3879 fmovs%c1\t%x2, %4, %0"
3880 [(set_attr "type" "fpcmove")])
3882 (define_insn "movdf_cc_sp64"
3883 [(set (match_operand:DF 0 "register_operand" "=e,e")
3884 (if_then_else:DF (match_operator 1 "comparison_operator"
3885 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3887 (match_operand:DF 3 "register_operand" "e,0")
3888 (match_operand:DF 4 "register_operand" "0,e")))]
3889 "TARGET_V9 && TARGET_FPU"
3891 fmovd%C1\t%x2, %3, %0
3892 fmovd%c1\t%x2, %4, %0"
3893 [(set_attr "type" "fpcmove")
3894 (set_attr "fptype" "double")])
3896 (define_insn "*movtf_cc_hq_sp64"
3897 [(set (match_operand:TF 0 "register_operand" "=e,e")
3898 (if_then_else:TF (match_operator 1 "comparison_operator"
3899 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3901 (match_operand:TF 3 "register_operand" "e,0")
3902 (match_operand:TF 4 "register_operand" "0,e")))]
3903 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
3905 fmovq%C1\t%x2, %3, %0
3906 fmovq%c1\t%x2, %4, %0"
3907 [(set_attr "type" "fpcmove")])
3909 (define_insn_and_split "*movtf_cc_sp64"
3910 [(set (match_operand:TF 0 "register_operand" "=e,e")
3911 (if_then_else:TF (match_operator 1 "comparison_operator"
3912 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3914 (match_operand:TF 3 "register_operand" "e,0")
3915 (match_operand:TF 4 "register_operand" "0,e")))]
3916 "TARGET_V9 && TARGET_FPU && !TARGET_HARD_QUAD"
3918 "&& reload_completed"
3919 [(clobber (const_int 0))]
3921 rtx set_dest = operands[0];
3922 rtx set_srca = operands[3];
3923 rtx set_srcb = operands[4];
3924 int third = rtx_equal_p (set_dest, set_srca);
3926 rtx srca1, srca2, srcb1, srcb2;
3928 dest1 = gen_df_reg (set_dest, 0);
3929 dest2 = gen_df_reg (set_dest, 1);
3930 srca1 = gen_df_reg (set_srca, 0);
3931 srca2 = gen_df_reg (set_srca, 1);
3932 srcb1 = gen_df_reg (set_srcb, 0);
3933 srcb2 = gen_df_reg (set_srcb, 1);
3935 /* Now emit using the real source and destination we found, swapping
3936 the order if we detect overlap. */
3937 if ((third && reg_overlap_mentioned_p (dest1, srcb2))
3938 || (!third && reg_overlap_mentioned_p (dest1, srca2)))
3940 emit_insn (gen_movdf_cc_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
3941 emit_insn (gen_movdf_cc_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
3945 emit_insn (gen_movdf_cc_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
3946 emit_insn (gen_movdf_cc_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
3950 [(set_attr "length" "2")])
3952 (define_insn "*movqi_cc_reg_sp64"
3953 [(set (match_operand:QI 0 "register_operand" "=r,r")
3954 (if_then_else:QI (match_operator 1 "v9_regcmp_op"
3955 [(match_operand:DI 2 "register_operand" "r,r")
3957 (match_operand:QI 3 "arith10_operand" "rM,0")
3958 (match_operand:QI 4 "arith10_operand" "0,rM")))]
3961 movr%D1\t%2, %r3, %0
3962 movr%d1\t%2, %r4, %0"
3963 [(set_attr "type" "cmove")])
3965 (define_insn "*movhi_cc_reg_sp64"
3966 [(set (match_operand:HI 0 "register_operand" "=r,r")
3967 (if_then_else:HI (match_operator 1 "v9_regcmp_op"
3968 [(match_operand:DI 2 "register_operand" "r,r")
3970 (match_operand:HI 3 "arith10_operand" "rM,0")
3971 (match_operand:HI 4 "arith10_operand" "0,rM")))]
3974 movr%D1\t%2, %r3, %0
3975 movr%d1\t%2, %r4, %0"
3976 [(set_attr "type" "cmove")])
3978 (define_insn "*movsi_cc_reg_sp64"
3979 [(set (match_operand:SI 0 "register_operand" "=r,r")
3980 (if_then_else:SI (match_operator 1 "v9_regcmp_op"
3981 [(match_operand:DI 2 "register_operand" "r,r")
3983 (match_operand:SI 3 "arith10_operand" "rM,0")
3984 (match_operand:SI 4 "arith10_operand" "0,rM")))]
3987 movr%D1\t%2, %r3, %0
3988 movr%d1\t%2, %r4, %0"
3989 [(set_attr "type" "cmove")])
3991 ;; ??? The constraints of operands 3,4 need work.
3992 (define_insn "*movdi_cc_reg_sp64"
3993 [(set (match_operand:DI 0 "register_operand" "=r,r")
3994 (if_then_else:DI (match_operator 1 "v9_regcmp_op"
3995 [(match_operand:DI 2 "register_operand" "r,r")
3997 (match_operand:DI 3 "arith10_double_operand" "rMH,0")
3998 (match_operand:DI 4 "arith10_double_operand" "0,rMH")))]
4001 movr%D1\t%2, %r3, %0
4002 movr%d1\t%2, %r4, %0"
4003 [(set_attr "type" "cmove")])
4005 (define_insn "*movdi_cc_reg_sp64_trunc"
4006 [(set (match_operand:SI 0 "register_operand" "=r,r")
4007 (if_then_else:SI (match_operator 1 "v9_regcmp_op"
4008 [(match_operand:DI 2 "register_operand" "r,r")
4010 (match_operand:SI 3 "arith10_double_operand" "rMH,0")
4011 (match_operand:SI 4 "arith10_double_operand" "0,rMH")))]
4014 movr%D1\t%2, %r3, %0
4015 movr%d1\t%2, %r4, %0"
4016 [(set_attr "type" "cmove")])
4018 (define_insn "*movsf_cc_reg_sp64"
4019 [(set (match_operand:SF 0 "register_operand" "=f,f")
4020 (if_then_else:SF (match_operator 1 "v9_regcmp_op"
4021 [(match_operand:DI 2 "register_operand" "r,r")
4023 (match_operand:SF 3 "register_operand" "f,0")
4024 (match_operand:SF 4 "register_operand" "0,f")))]
4025 "TARGET_ARCH64 && TARGET_FPU"
4027 fmovrs%D1\t%2, %3, %0
4028 fmovrs%d1\t%2, %4, %0"
4029 [(set_attr "type" "fpcrmove")])
4031 (define_insn "movdf_cc_reg_sp64"
4032 [(set (match_operand:DF 0 "register_operand" "=e,e")
4033 (if_then_else:DF (match_operator 1 "v9_regcmp_op"
4034 [(match_operand:DI 2 "register_operand" "r,r")
4036 (match_operand:DF 3 "register_operand" "e,0")
4037 (match_operand:DF 4 "register_operand" "0,e")))]
4038 "TARGET_ARCH64 && TARGET_FPU"
4040 fmovrd%D1\t%2, %3, %0
4041 fmovrd%d1\t%2, %4, %0"
4042 [(set_attr "type" "fpcrmove")
4043 (set_attr "fptype" "double")])
4045 (define_insn "*movtf_cc_reg_hq_sp64"
4046 [(set (match_operand:TF 0 "register_operand" "=e,e")
4047 (if_then_else:TF (match_operator 1 "v9_regcmp_op"
4048 [(match_operand:DI 2 "register_operand" "r,r")
4050 (match_operand:TF 3 "register_operand" "e,0")
4051 (match_operand:TF 4 "register_operand" "0,e")))]
4052 "TARGET_ARCH64 && TARGET_FPU && TARGET_HARD_QUAD"
4054 fmovrq%D1\t%2, %3, %0
4055 fmovrq%d1\t%2, %4, %0"
4056 [(set_attr "type" "fpcrmove")])
4058 (define_insn_and_split "*movtf_cc_reg_sp64"
4059 [(set (match_operand:TF 0 "register_operand" "=e,e")
4060 (if_then_else:TF (match_operator 1 "v9_regcmp_op"
4061 [(match_operand:DI 2 "register_operand" "r,r")
4063 (match_operand:TF 3 "register_operand" "e,0")
4064 (match_operand:TF 4 "register_operand" "0,e")))]
4065 "TARGET_ARCH64 && TARGET_FPU && ! TARGET_HARD_QUAD"
4067 "&& reload_completed"
4068 [(clobber (const_int 0))]
4070 rtx set_dest = operands[0];
4071 rtx set_srca = operands[3];
4072 rtx set_srcb = operands[4];
4073 int third = rtx_equal_p (set_dest, set_srca);
4075 rtx srca1, srca2, srcb1, srcb2;
4077 dest1 = gen_df_reg (set_dest, 0);
4078 dest2 = gen_df_reg (set_dest, 1);
4079 srca1 = gen_df_reg (set_srca, 0);
4080 srca2 = gen_df_reg (set_srca, 1);
4081 srcb1 = gen_df_reg (set_srcb, 0);
4082 srcb2 = gen_df_reg (set_srcb, 1);
4084 /* Now emit using the real source and destination we found, swapping
4085 the order if we detect overlap. */
4086 if ((third && reg_overlap_mentioned_p (dest1, srcb2))
4087 || (!third && reg_overlap_mentioned_p (dest1, srca2)))
4089 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
4090 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
4094 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
4095 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
4099 [(set_attr "length" "2")])
4102 ;;- zero extension instructions
4104 ;; These patterns originally accepted general_operands, however, slightly
4105 ;; better code is generated by only accepting register_operands, and then
4106 ;; letting combine generate the ldu[hb] insns.
4108 (define_expand "zero_extendhisi2"
4109 [(set (match_operand:SI 0 "register_operand" "")
4110 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
4113 rtx temp = gen_reg_rtx (SImode);
4114 rtx shift_16 = GEN_INT (16);
4115 int op1_subbyte = 0;
4117 if (GET_CODE (operand1) == SUBREG)
4119 op1_subbyte = SUBREG_BYTE (operand1);
4120 op1_subbyte /= GET_MODE_SIZE (SImode);
4121 op1_subbyte *= GET_MODE_SIZE (SImode);
4122 operand1 = XEXP (operand1, 0);
4125 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4127 emit_insn (gen_lshrsi3 (operand0, temp, shift_16));
4131 (define_insn "*zero_extendhisi2_insn"
4132 [(set (match_operand:SI 0 "register_operand" "=r")
4133 (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
4136 [(set_attr "type" "load")
4137 (set_attr "us3load_type" "3cycle")])
4139 (define_expand "zero_extendqihi2"
4140 [(set (match_operand:HI 0 "register_operand" "")
4141 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
4145 (define_insn "*zero_extendqihi2_insn"
4146 [(set (match_operand:HI 0 "register_operand" "=r,r")
4147 (zero_extend:HI (match_operand:QI 1 "input_operand" "r,m")))]
4148 "GET_CODE (operands[1]) != CONST_INT"
4152 [(set_attr "type" "*,load")
4153 (set_attr "us3load_type" "*,3cycle")])
4155 (define_expand "zero_extendqisi2"
4156 [(set (match_operand:SI 0 "register_operand" "")
4157 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
4161 (define_insn "*zero_extendqisi2_insn"
4162 [(set (match_operand:SI 0 "register_operand" "=r,r")
4163 (zero_extend:SI (match_operand:QI 1 "input_operand" "r,m")))]
4164 "GET_CODE (operands[1]) != CONST_INT"
4168 [(set_attr "type" "*,load")
4169 (set_attr "us3load_type" "*,3cycle")])
4171 (define_expand "zero_extendqidi2"
4172 [(set (match_operand:DI 0 "register_operand" "")
4173 (zero_extend:DI (match_operand:QI 1 "register_operand" "")))]
4177 (define_insn "*zero_extendqidi2_insn"
4178 [(set (match_operand:DI 0 "register_operand" "=r,r")
4179 (zero_extend:DI (match_operand:QI 1 "input_operand" "r,m")))]
4180 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
4184 [(set_attr "type" "*,load")
4185 (set_attr "us3load_type" "*,3cycle")])
4187 (define_expand "zero_extendhidi2"
4188 [(set (match_operand:DI 0 "register_operand" "")
4189 (zero_extend:DI (match_operand:HI 1 "register_operand" "")))]
4192 rtx temp = gen_reg_rtx (DImode);
4193 rtx shift_48 = GEN_INT (48);
4194 int op1_subbyte = 0;
4196 if (GET_CODE (operand1) == SUBREG)
4198 op1_subbyte = SUBREG_BYTE (operand1);
4199 op1_subbyte /= GET_MODE_SIZE (DImode);
4200 op1_subbyte *= GET_MODE_SIZE (DImode);
4201 operand1 = XEXP (operand1, 0);
4204 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
4206 emit_insn (gen_lshrdi3 (operand0, temp, shift_48));
4210 (define_insn "*zero_extendhidi2_insn"
4211 [(set (match_operand:DI 0 "register_operand" "=r")
4212 (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
4215 [(set_attr "type" "load")
4216 (set_attr "us3load_type" "3cycle")])
4219 ;; ??? Write truncdisi pattern using sra?
4221 (define_expand "zero_extendsidi2"
4222 [(set (match_operand:DI 0 "register_operand" "")
4223 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
4227 (define_insn "*zero_extendsidi2_insn_sp64"
4228 [(set (match_operand:DI 0 "register_operand" "=r,r")
4229 (zero_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
4230 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
4234 [(set_attr "type" "shift,load")])
4236 (define_insn_and_split "*zero_extendsidi2_insn_sp32"
4237 [(set (match_operand:DI 0 "register_operand" "=r")
4238 (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
4241 "&& reload_completed"
4242 [(set (match_dup 2) (match_dup 3))
4243 (set (match_dup 4) (match_dup 5))]
4247 dest1 = gen_highpart (SImode, operands[0]);
4248 dest2 = gen_lowpart (SImode, operands[0]);
4250 /* Swap the order in case of overlap. */
4251 if (REGNO (dest1) == REGNO (operands[1]))
4253 operands[2] = dest2;
4254 operands[3] = operands[1];
4255 operands[4] = dest1;
4256 operands[5] = const0_rtx;
4260 operands[2] = dest1;
4261 operands[3] = const0_rtx;
4262 operands[4] = dest2;
4263 operands[5] = operands[1];
4266 [(set_attr "length" "2")])
4268 ;; Simplify comparisons of extended values.
4270 (define_insn "*cmp_zero_extendqisi2"
4272 (compare:CC (zero_extend:SI (match_operand:QI 0 "register_operand" "r"))
4275 "andcc\t%0, 0xff, %%g0"
4276 [(set_attr "type" "compare")])
4278 (define_insn "*cmp_zero_qi"
4280 (compare:CC (match_operand:QI 0 "register_operand" "r")
4283 "andcc\t%0, 0xff, %%g0"
4284 [(set_attr "type" "compare")])
4286 (define_insn "*cmp_zero_extendqisi2_set"
4288 (compare:CC (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
4290 (set (match_operand:SI 0 "register_operand" "=r")
4291 (zero_extend:SI (match_dup 1)))]
4293 "andcc\t%1, 0xff, %0"
4294 [(set_attr "type" "compare")])
4296 (define_insn "*cmp_zero_extendqisi2_andcc_set"
4298 (compare:CC (and:SI (match_operand:SI 1 "register_operand" "r")
4301 (set (match_operand:SI 0 "register_operand" "=r")
4302 (zero_extend:SI (subreg:QI (match_dup 1) 0)))]
4304 "andcc\t%1, 0xff, %0"
4305 [(set_attr "type" "compare")])
4307 (define_insn "*cmp_zero_extendqidi2"
4309 (compare:CCX (zero_extend:DI (match_operand:QI 0 "register_operand" "r"))
4312 "andcc\t%0, 0xff, %%g0"
4313 [(set_attr "type" "compare")])
4315 (define_insn "*cmp_zero_qi_sp64"
4317 (compare:CCX (match_operand:QI 0 "register_operand" "r")
4320 "andcc\t%0, 0xff, %%g0"
4321 [(set_attr "type" "compare")])
4323 (define_insn "*cmp_zero_extendqidi2_set"
4325 (compare:CCX (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
4327 (set (match_operand:DI 0 "register_operand" "=r")
4328 (zero_extend:DI (match_dup 1)))]
4330 "andcc\t%1, 0xff, %0"
4331 [(set_attr "type" "compare")])
4333 (define_insn "*cmp_zero_extendqidi2_andcc_set"
4335 (compare:CCX (and:DI (match_operand:DI 1 "register_operand" "r")
4338 (set (match_operand:DI 0 "register_operand" "=r")
4339 (zero_extend:DI (subreg:QI (match_dup 1) 0)))]
4341 "andcc\t%1, 0xff, %0"
4342 [(set_attr "type" "compare")])
4344 ;; Similarly, handle {SI,DI}->QI mode truncation followed by a compare.
4346 (define_insn "*cmp_siqi_trunc"
4348 (compare:CC (subreg:QI (match_operand:SI 0 "register_operand" "r") 3)
4351 "andcc\t%0, 0xff, %%g0"
4352 [(set_attr "type" "compare")])
4354 (define_insn "*cmp_siqi_trunc_set"
4356 (compare:CC (subreg:QI (match_operand:SI 1 "register_operand" "r") 3)
4358 (set (match_operand:QI 0 "register_operand" "=r")
4359 (subreg:QI (match_dup 1) 3))]
4361 "andcc\t%1, 0xff, %0"
4362 [(set_attr "type" "compare")])
4364 (define_insn "*cmp_diqi_trunc"
4366 (compare:CC (subreg:QI (match_operand:DI 0 "register_operand" "r") 7)
4369 "andcc\t%0, 0xff, %%g0"
4370 [(set_attr "type" "compare")])
4372 (define_insn "*cmp_diqi_trunc_set"
4374 (compare:CC (subreg:QI (match_operand:DI 1 "register_operand" "r") 7)
4376 (set (match_operand:QI 0 "register_operand" "=r")
4377 (subreg:QI (match_dup 1) 7))]
4379 "andcc\t%1, 0xff, %0"
4380 [(set_attr "type" "compare")])
4382 ;;- sign extension instructions
4384 ;; These patterns originally accepted general_operands, however, slightly
4385 ;; better code is generated by only accepting register_operands, and then
4386 ;; letting combine generate the lds[hb] insns.
4388 (define_expand "extendhisi2"
4389 [(set (match_operand:SI 0 "register_operand" "")
4390 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
4393 rtx temp = gen_reg_rtx (SImode);
4394 rtx shift_16 = GEN_INT (16);
4395 int op1_subbyte = 0;
4397 if (GET_CODE (operand1) == SUBREG)
4399 op1_subbyte = SUBREG_BYTE (operand1);
4400 op1_subbyte /= GET_MODE_SIZE (SImode);
4401 op1_subbyte *= GET_MODE_SIZE (SImode);
4402 operand1 = XEXP (operand1, 0);
4405 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4407 emit_insn (gen_ashrsi3 (operand0, temp, shift_16));
4411 (define_insn "*sign_extendhisi2_insn"
4412 [(set (match_operand:SI 0 "register_operand" "=r")
4413 (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
4416 [(set_attr "type" "sload")
4417 (set_attr "us3load_type" "3cycle")])
4419 (define_expand "extendqihi2"
4420 [(set (match_operand:HI 0 "register_operand" "")
4421 (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
4424 rtx temp = gen_reg_rtx (SImode);
4425 rtx shift_24 = GEN_INT (24);
4426 int op1_subbyte = 0;
4427 int op0_subbyte = 0;
4429 if (GET_CODE (operand1) == SUBREG)
4431 op1_subbyte = SUBREG_BYTE (operand1);
4432 op1_subbyte /= GET_MODE_SIZE (SImode);
4433 op1_subbyte *= GET_MODE_SIZE (SImode);
4434 operand1 = XEXP (operand1, 0);
4436 if (GET_CODE (operand0) == SUBREG)
4438 op0_subbyte = SUBREG_BYTE (operand0);
4439 op0_subbyte /= GET_MODE_SIZE (SImode);
4440 op0_subbyte *= GET_MODE_SIZE (SImode);
4441 operand0 = XEXP (operand0, 0);
4443 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4445 if (GET_MODE (operand0) != SImode)
4446 operand0 = gen_rtx_SUBREG (SImode, operand0, op0_subbyte);
4447 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
4451 (define_insn "*sign_extendqihi2_insn"
4452 [(set (match_operand:HI 0 "register_operand" "=r")
4453 (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
4456 [(set_attr "type" "sload")
4457 (set_attr "us3load_type" "3cycle")])
4459 (define_expand "extendqisi2"
4460 [(set (match_operand:SI 0 "register_operand" "")
4461 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
4464 rtx temp = gen_reg_rtx (SImode);
4465 rtx shift_24 = GEN_INT (24);
4466 int op1_subbyte = 0;
4468 if (GET_CODE (operand1) == SUBREG)
4470 op1_subbyte = SUBREG_BYTE (operand1);
4471 op1_subbyte /= GET_MODE_SIZE (SImode);
4472 op1_subbyte *= GET_MODE_SIZE (SImode);
4473 operand1 = XEXP (operand1, 0);
4476 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4478 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
4482 (define_insn "*sign_extendqisi2_insn"
4483 [(set (match_operand:SI 0 "register_operand" "=r")
4484 (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
4487 [(set_attr "type" "sload")
4488 (set_attr "us3load_type" "3cycle")])
4490 (define_expand "extendqidi2"
4491 [(set (match_operand:DI 0 "register_operand" "")
4492 (sign_extend:DI (match_operand:QI 1 "register_operand" "")))]
4495 rtx temp = gen_reg_rtx (DImode);
4496 rtx shift_56 = GEN_INT (56);
4497 int op1_subbyte = 0;
4499 if (GET_CODE (operand1) == SUBREG)
4501 op1_subbyte = SUBREG_BYTE (operand1);
4502 op1_subbyte /= GET_MODE_SIZE (DImode);
4503 op1_subbyte *= GET_MODE_SIZE (DImode);
4504 operand1 = XEXP (operand1, 0);
4507 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
4509 emit_insn (gen_ashrdi3 (operand0, temp, shift_56));
4513 (define_insn "*sign_extendqidi2_insn"
4514 [(set (match_operand:DI 0 "register_operand" "=r")
4515 (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
4518 [(set_attr "type" "sload")
4519 (set_attr "us3load_type" "3cycle")])
4521 (define_expand "extendhidi2"
4522 [(set (match_operand:DI 0 "register_operand" "")
4523 (sign_extend:DI (match_operand:HI 1 "register_operand" "")))]
4526 rtx temp = gen_reg_rtx (DImode);
4527 rtx shift_48 = GEN_INT (48);
4528 int op1_subbyte = 0;
4530 if (GET_CODE (operand1) == SUBREG)
4532 op1_subbyte = SUBREG_BYTE (operand1);
4533 op1_subbyte /= GET_MODE_SIZE (DImode);
4534 op1_subbyte *= GET_MODE_SIZE (DImode);
4535 operand1 = XEXP (operand1, 0);
4538 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
4540 emit_insn (gen_ashrdi3 (operand0, temp, shift_48));
4544 (define_insn "*sign_extendhidi2_insn"
4545 [(set (match_operand:DI 0 "register_operand" "=r")
4546 (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
4549 [(set_attr "type" "sload")
4550 (set_attr "us3load_type" "3cycle")])
4552 (define_expand "extendsidi2"
4553 [(set (match_operand:DI 0 "register_operand" "")
4554 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
4558 (define_insn "*sign_extendsidi2_insn"
4559 [(set (match_operand:DI 0 "register_operand" "=r,r")
4560 (sign_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
4565 [(set_attr "type" "shift,sload")
4566 (set_attr "us3load_type" "*,3cycle")])
4568 ;; Special pattern for optimizing bit-field compares. This is needed
4569 ;; because combine uses this as a canonical form.
4571 (define_insn "*cmp_zero_extract"
4574 (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
4575 (match_operand:SI 1 "small_int_or_double" "n")
4576 (match_operand:SI 2 "small_int_or_double" "n"))
4578 "(GET_CODE (operands[2]) == CONST_INT
4579 && INTVAL (operands[2]) > 19)
4580 || (GET_CODE (operands[2]) == CONST_DOUBLE
4581 && CONST_DOUBLE_LOW (operands[2]) > 19)"
4583 int len = (GET_CODE (operands[1]) == CONST_INT
4584 ? INTVAL (operands[1])
4585 : CONST_DOUBLE_LOW (operands[1]));
4587 (GET_CODE (operands[2]) == CONST_INT
4588 ? INTVAL (operands[2])
4589 : CONST_DOUBLE_LOW (operands[2])) - len;
4590 HOST_WIDE_INT mask = ((1 << len) - 1) << pos;
4592 operands[1] = GEN_INT (mask);
4593 return "andcc\t%0, %1, %%g0";
4595 [(set_attr "type" "compare")])
4597 (define_insn "*cmp_zero_extract_sp64"
4600 (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
4601 (match_operand:SI 1 "small_int_or_double" "n")
4602 (match_operand:SI 2 "small_int_or_double" "n"))
4605 && ((GET_CODE (operands[2]) == CONST_INT
4606 && INTVAL (operands[2]) > 51)
4607 || (GET_CODE (operands[2]) == CONST_DOUBLE
4608 && CONST_DOUBLE_LOW (operands[2]) > 51))"
4610 int len = (GET_CODE (operands[1]) == CONST_INT
4611 ? INTVAL (operands[1])
4612 : CONST_DOUBLE_LOW (operands[1]));
4614 (GET_CODE (operands[2]) == CONST_INT
4615 ? INTVAL (operands[2])
4616 : CONST_DOUBLE_LOW (operands[2])) - len;
4617 HOST_WIDE_INT mask = (((unsigned HOST_WIDE_INT) 1 << len) - 1) << pos;
4619 operands[1] = GEN_INT (mask);
4620 return "andcc\t%0, %1, %%g0";
4622 [(set_attr "type" "compare")])
4624 ;; Conversions between float, double and long double.
4626 (define_insn "extendsfdf2"
4627 [(set (match_operand:DF 0 "register_operand" "=e")
4629 (match_operand:SF 1 "register_operand" "f")))]
4632 [(set_attr "type" "fp")
4633 (set_attr "fptype" "double")])
4635 (define_expand "extendsftf2"
4636 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4638 (match_operand:SF 1 "register_operand" "")))]
4639 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4640 "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
4642 (define_insn "*extendsftf2_hq"
4643 [(set (match_operand:TF 0 "register_operand" "=e")
4645 (match_operand:SF 1 "register_operand" "f")))]
4646 "TARGET_FPU && TARGET_HARD_QUAD"
4648 [(set_attr "type" "fp")])
4650 (define_expand "extenddftf2"
4651 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4653 (match_operand:DF 1 "register_operand" "")))]
4654 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4655 "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
4657 (define_insn "*extenddftf2_hq"
4658 [(set (match_operand:TF 0 "register_operand" "=e")
4660 (match_operand:DF 1 "register_operand" "e")))]
4661 "TARGET_FPU && TARGET_HARD_QUAD"
4663 [(set_attr "type" "fp")])
4665 (define_insn "truncdfsf2"
4666 [(set (match_operand:SF 0 "register_operand" "=f")
4668 (match_operand:DF 1 "register_operand" "e")))]
4671 [(set_attr "type" "fp")
4672 (set_attr "fptype" "double")])
4674 (define_expand "trunctfsf2"
4675 [(set (match_operand:SF 0 "register_operand" "")
4677 (match_operand:TF 1 "general_operand" "")))]
4678 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4679 "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
4681 (define_insn "*trunctfsf2_hq"
4682 [(set (match_operand:SF 0 "register_operand" "=f")
4684 (match_operand:TF 1 "register_operand" "e")))]
4685 "TARGET_FPU && TARGET_HARD_QUAD"
4687 [(set_attr "type" "fp")])
4689 (define_expand "trunctfdf2"
4690 [(set (match_operand:DF 0 "register_operand" "")
4692 (match_operand:TF 1 "general_operand" "")))]
4693 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4694 "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
4696 (define_insn "*trunctfdf2_hq"
4697 [(set (match_operand:DF 0 "register_operand" "=e")
4699 (match_operand:TF 1 "register_operand" "e")))]
4700 "TARGET_FPU && TARGET_HARD_QUAD"
4702 [(set_attr "type" "fp")])
4704 ;; Conversion between fixed point and floating point.
4706 (define_insn "floatsisf2"
4707 [(set (match_operand:SF 0 "register_operand" "=f")
4708 (float:SF (match_operand:SI 1 "register_operand" "f")))]
4711 [(set_attr "type" "fp")
4712 (set_attr "fptype" "double")])
4714 (define_insn "floatsidf2"
4715 [(set (match_operand:DF 0 "register_operand" "=e")
4716 (float:DF (match_operand:SI 1 "register_operand" "f")))]
4719 [(set_attr "type" "fp")
4720 (set_attr "fptype" "double")])
4722 (define_expand "floatsitf2"
4723 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4724 (float:TF (match_operand:SI 1 "register_operand" "")))]
4725 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4726 "emit_tfmode_cvt (FLOAT, operands); DONE;")
4728 (define_insn "*floatsitf2_hq"
4729 [(set (match_operand:TF 0 "register_operand" "=e")
4730 (float:TF (match_operand:SI 1 "register_operand" "f")))]
4731 "TARGET_FPU && TARGET_HARD_QUAD"
4733 [(set_attr "type" "fp")])
4735 (define_expand "floatunssitf2"
4736 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4737 (unsigned_float:TF (match_operand:SI 1 "register_operand" "")))]
4738 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4739 "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
4741 ;; Now the same for 64 bit sources.
4743 (define_insn "floatdisf2"
4744 [(set (match_operand:SF 0 "register_operand" "=f")
4745 (float:SF (match_operand:DI 1 "register_operand" "e")))]
4746 "TARGET_V9 && TARGET_FPU"
4748 [(set_attr "type" "fp")
4749 (set_attr "fptype" "double")])
4751 (define_expand "floatunsdisf2"
4752 [(use (match_operand:SF 0 "register_operand" ""))
4753 (use (match_operand:DI 1 "general_operand" ""))]
4754 "TARGET_ARCH64 && TARGET_FPU"
4755 "sparc_emit_floatunsdi (operands, SFmode); DONE;")
4757 (define_insn "floatdidf2"
4758 [(set (match_operand:DF 0 "register_operand" "=e")
4759 (float:DF (match_operand:DI 1 "register_operand" "e")))]
4760 "TARGET_V9 && TARGET_FPU"
4762 [(set_attr "type" "fp")
4763 (set_attr "fptype" "double")])
4765 (define_expand "floatunsdidf2"
4766 [(use (match_operand:DF 0 "register_operand" ""))
4767 (use (match_operand:DI 1 "general_operand" ""))]
4768 "TARGET_ARCH64 && TARGET_FPU"
4769 "sparc_emit_floatunsdi (operands, DFmode); DONE;")
4771 (define_expand "floatditf2"
4772 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4773 (float:TF (match_operand:DI 1 "register_operand" "")))]
4774 "TARGET_FPU && TARGET_V9 && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4775 "emit_tfmode_cvt (FLOAT, operands); DONE;")
4777 (define_insn "*floatditf2_hq"
4778 [(set (match_operand:TF 0 "register_operand" "=e")
4779 (float:TF (match_operand:DI 1 "register_operand" "e")))]
4780 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
4782 [(set_attr "type" "fp")])
4784 (define_expand "floatunsditf2"
4785 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4786 (unsigned_float:TF (match_operand:DI 1 "register_operand" "")))]
4787 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4788 "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
4790 ;; Convert a float to an actual integer.
4791 ;; Truncation is performed as part of the conversion.
4793 (define_insn "fix_truncsfsi2"
4794 [(set (match_operand:SI 0 "register_operand" "=f")
4795 (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
4798 [(set_attr "type" "fp")
4799 (set_attr "fptype" "double")])
4801 (define_insn "fix_truncdfsi2"
4802 [(set (match_operand:SI 0 "register_operand" "=f")
4803 (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
4806 [(set_attr "type" "fp")
4807 (set_attr "fptype" "double")])
4809 (define_expand "fix_trunctfsi2"
4810 [(set (match_operand:SI 0 "register_operand" "")
4811 (fix:SI (match_operand:TF 1 "general_operand" "")))]
4812 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4813 "emit_tfmode_cvt (FIX, operands); DONE;")
4815 (define_insn "*fix_trunctfsi2_hq"
4816 [(set (match_operand:SI 0 "register_operand" "=f")
4817 (fix:SI (match_operand:TF 1 "register_operand" "e")))]
4818 "TARGET_FPU && TARGET_HARD_QUAD"
4820 [(set_attr "type" "fp")])
4822 (define_expand "fixuns_trunctfsi2"
4823 [(set (match_operand:SI 0 "register_operand" "")
4824 (unsigned_fix:SI (match_operand:TF 1 "general_operand" "")))]
4825 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4826 "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
4828 ;; Now the same, for V9 targets
4830 (define_insn "fix_truncsfdi2"
4831 [(set (match_operand:DI 0 "register_operand" "=e")
4832 (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
4833 "TARGET_V9 && TARGET_FPU"
4835 [(set_attr "type" "fp")
4836 (set_attr "fptype" "double")])
4838 (define_expand "fixuns_truncsfdi2"
4839 [(use (match_operand:DI 0 "register_operand" ""))
4840 (use (match_operand:SF 1 "general_operand" ""))]
4841 "TARGET_ARCH64 && TARGET_FPU"
4842 "sparc_emit_fixunsdi (operands, SFmode); DONE;")
4844 (define_insn "fix_truncdfdi2"
4845 [(set (match_operand:DI 0 "register_operand" "=e")
4846 (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
4847 "TARGET_V9 && TARGET_FPU"
4849 [(set_attr "type" "fp")
4850 (set_attr "fptype" "double")])
4852 (define_expand "fixuns_truncdfdi2"
4853 [(use (match_operand:DI 0 "register_operand" ""))
4854 (use (match_operand:DF 1 "general_operand" ""))]
4855 "TARGET_ARCH64 && TARGET_FPU"
4856 "sparc_emit_fixunsdi (operands, DFmode); DONE;")
4858 (define_expand "fix_trunctfdi2"
4859 [(set (match_operand:DI 0 "register_operand" "")
4860 (fix:DI (match_operand:TF 1 "general_operand" "")))]
4861 "TARGET_V9 && TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4862 "emit_tfmode_cvt (FIX, operands); DONE;")
4864 (define_insn "*fix_trunctfdi2_hq"
4865 [(set (match_operand:DI 0 "register_operand" "=e")
4866 (fix:DI (match_operand:TF 1 "register_operand" "e")))]
4867 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
4869 [(set_attr "type" "fp")])
4871 (define_expand "fixuns_trunctfdi2"
4872 [(set (match_operand:DI 0 "register_operand" "")
4873 (unsigned_fix:DI (match_operand:TF 1 "general_operand" "")))]
4874 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4875 "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
4877 ;;- arithmetic instructions
4879 (define_expand "adddi3"
4880 [(set (match_operand:DI 0 "register_operand" "")
4881 (plus:DI (match_operand:DI 1 "register_operand" "")
4882 (match_operand:DI 2 "arith_double_add_operand" "")))]
4885 if (! TARGET_ARCH64)
4887 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
4888 gen_rtx_SET (VOIDmode, operands[0],
4889 gen_rtx_PLUS (DImode, operands[1],
4891 gen_rtx_CLOBBER (VOIDmode,
4892 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
4897 (define_insn_and_split "adddi3_insn_sp32"
4898 [(set (match_operand:DI 0 "register_operand" "=r")
4899 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
4900 (match_operand:DI 2 "arith_double_operand" "rHI")))
4901 (clobber (reg:CC 100))]
4904 "&& reload_completed"
4905 [(parallel [(set (reg:CC_NOOV 100)
4906 (compare:CC_NOOV (plus:SI (match_dup 4)
4910 (plus:SI (match_dup 4) (match_dup 5)))])
4912 (plus:SI (plus:SI (match_dup 7)
4914 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4916 operands[3] = gen_lowpart (SImode, operands[0]);
4917 operands[4] = gen_lowpart (SImode, operands[1]);
4918 operands[5] = gen_lowpart (SImode, operands[2]);
4919 operands[6] = gen_highpart (SImode, operands[0]);
4920 operands[7] = gen_highpart_mode (SImode, DImode, operands[1]);
4921 #if HOST_BITS_PER_WIDE_INT == 32
4922 if (GET_CODE (operands[2]) == CONST_INT)
4924 if (INTVAL (operands[2]) < 0)
4925 operands[8] = constm1_rtx;
4927 operands[8] = const0_rtx;
4931 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
4933 [(set_attr "length" "2")])
4936 [(set (match_operand:DI 0 "register_operand" "")
4937 (minus:DI (match_operand:DI 1 "arith_double_operand" "")
4938 (match_operand:DI 2 "arith_double_operand" "")))
4939 (clobber (reg:CC 100))]
4940 "! TARGET_ARCH64 && reload_completed"
4941 [(parallel [(set (reg:CC_NOOV 100)
4942 (compare:CC_NOOV (minus:SI (match_dup 4)
4946 (minus:SI (match_dup 4) (match_dup 5)))])
4948 (minus:SI (minus:SI (match_dup 7)
4950 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4952 operands[3] = gen_lowpart (SImode, operands[0]);
4953 operands[4] = gen_lowpart (SImode, operands[1]);
4954 operands[5] = gen_lowpart (SImode, operands[2]);
4955 operands[6] = gen_highpart (SImode, operands[0]);
4956 operands[7] = gen_highpart (SImode, operands[1]);
4957 #if HOST_BITS_PER_WIDE_INT == 32
4958 if (GET_CODE (operands[2]) == CONST_INT)
4960 if (INTVAL (operands[2]) < 0)
4961 operands[8] = constm1_rtx;
4963 operands[8] = const0_rtx;
4967 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
4970 ;; LTU here means "carry set"
4972 [(set (match_operand:SI 0 "register_operand" "=r")
4973 (plus:SI (plus:SI (match_operand:SI 1 "arith_operand" "%r")
4974 (match_operand:SI 2 "arith_operand" "rI"))
4975 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4978 [(set_attr "type" "ialuX")])
4980 (define_insn_and_split "*addx_extend_sp32"
4981 [(set (match_operand:DI 0 "register_operand" "=r")
4982 (zero_extend:DI (plus:SI (plus:SI
4983 (match_operand:SI 1 "reg_or_0_operand" "%rJ")
4984 (match_operand:SI 2 "arith_operand" "rI"))
4985 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4988 "&& reload_completed"
4989 [(set (match_dup 3) (plus:SI (plus:SI (match_dup 1) (match_dup 2))
4990 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
4991 (set (match_dup 4) (const_int 0))]
4992 "operands[3] = gen_lowpart (SImode, operands[0]);
4993 operands[4] = gen_highpart_mode (SImode, DImode, operands[1]);"
4994 [(set_attr "length" "2")])
4996 (define_insn "*addx_extend_sp64"
4997 [(set (match_operand:DI 0 "register_operand" "=r")
4998 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
4999 (match_operand:SI 2 "arith_operand" "rI"))
5000 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5003 [(set_attr "type" "ialuX")])
5006 [(set (match_operand:SI 0 "register_operand" "=r")
5007 (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5008 (match_operand:SI 2 "arith_operand" "rI"))
5009 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5012 [(set_attr "type" "ialuX")])
5014 (define_insn "*subx_extend_sp64"
5015 [(set (match_operand:DI 0 "register_operand" "=r")
5016 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5017 (match_operand:SI 2 "arith_operand" "rI"))
5018 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5021 [(set_attr "type" "ialuX")])
5023 (define_insn_and_split "*subx_extend"
5024 [(set (match_operand:DI 0 "register_operand" "=r")
5025 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5026 (match_operand:SI 2 "arith_operand" "rI"))
5027 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5030 "&& reload_completed"
5031 [(set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 2))
5032 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
5033 (set (match_dup 4) (const_int 0))]
5034 "operands[3] = gen_lowpart (SImode, operands[0]);
5035 operands[4] = gen_highpart (SImode, operands[0]);"
5036 [(set_attr "length" "2")])
5038 (define_insn_and_split ""
5039 [(set (match_operand:DI 0 "register_operand" "=r")
5040 (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5041 (match_operand:DI 2 "register_operand" "r")))
5042 (clobber (reg:CC 100))]
5045 "&& reload_completed"
5046 [(parallel [(set (reg:CC_NOOV 100)
5047 (compare:CC_NOOV (plus:SI (match_dup 3) (match_dup 1))
5049 (set (match_dup 5) (plus:SI (match_dup 3) (match_dup 1)))])
5051 (plus:SI (plus:SI (match_dup 4) (const_int 0))
5052 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5053 "operands[3] = gen_lowpart (SImode, operands[2]);
5054 operands[4] = gen_highpart (SImode, operands[2]);
5055 operands[5] = gen_lowpart (SImode, operands[0]);
5056 operands[6] = gen_highpart (SImode, operands[0]);"
5057 [(set_attr "length" "2")])
5059 (define_insn "*adddi3_sp64"
5060 [(set (match_operand:DI 0 "register_operand" "=r,r")
5061 (plus:DI (match_operand:DI 1 "register_operand" "%r,r")
5062 (match_operand:DI 2 "arith_double_add_operand" "rHI,O")))]
5068 (define_insn "addsi3"
5069 [(set (match_operand:SI 0 "register_operand" "=r,r,d")
5070 (plus:SI (match_operand:SI 1 "register_operand" "%r,r,d")
5071 (match_operand:SI 2 "arith_add_operand" "rI,O,d")))]
5076 fpadd32s\t%1, %2, %0"
5077 [(set_attr "type" "*,*,fga")
5078 (set_attr "fptype" "*,*,single")])
5080 (define_insn "*cmp_cc_plus"
5081 [(set (reg:CC_NOOV 100)
5082 (compare:CC_NOOV (plus:SI (match_operand:SI 0 "arith_operand" "%r")
5083 (match_operand:SI 1 "arith_operand" "rI"))
5086 "addcc\t%0, %1, %%g0"
5087 [(set_attr "type" "compare")])
5089 (define_insn "*cmp_ccx_plus"
5090 [(set (reg:CCX_NOOV 100)
5091 (compare:CCX_NOOV (plus:DI (match_operand:DI 0 "arith_double_operand" "%r")
5092 (match_operand:DI 1 "arith_double_operand" "rHI"))
5095 "addcc\t%0, %1, %%g0"
5096 [(set_attr "type" "compare")])
5098 (define_insn "*cmp_cc_plus_set"
5099 [(set (reg:CC_NOOV 100)
5100 (compare:CC_NOOV (plus:SI (match_operand:SI 1 "arith_operand" "%r")
5101 (match_operand:SI 2 "arith_operand" "rI"))
5103 (set (match_operand:SI 0 "register_operand" "=r")
5104 (plus:SI (match_dup 1) (match_dup 2)))]
5107 [(set_attr "type" "compare")])
5109 (define_insn "*cmp_ccx_plus_set"
5110 [(set (reg:CCX_NOOV 100)
5111 (compare:CCX_NOOV (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
5112 (match_operand:DI 2 "arith_double_operand" "rHI"))
5114 (set (match_operand:DI 0 "register_operand" "=r")
5115 (plus:DI (match_dup 1) (match_dup 2)))]
5118 [(set_attr "type" "compare")])
5120 (define_expand "subdi3"
5121 [(set (match_operand:DI 0 "register_operand" "")
5122 (minus:DI (match_operand:DI 1 "register_operand" "")
5123 (match_operand:DI 2 "arith_double_add_operand" "")))]
5126 if (! TARGET_ARCH64)
5128 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
5129 gen_rtx_SET (VOIDmode, operands[0],
5130 gen_rtx_MINUS (DImode, operands[1],
5132 gen_rtx_CLOBBER (VOIDmode,
5133 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
5138 (define_insn_and_split "*subdi3_sp32"
5139 [(set (match_operand:DI 0 "register_operand" "=r")
5140 (minus:DI (match_operand:DI 1 "register_operand" "r")
5141 (match_operand:DI 2 "arith_double_operand" "rHI")))
5142 (clobber (reg:CC 100))]
5145 "&& reload_completed
5146 && (GET_CODE (operands[2]) == CONST_INT
5147 || GET_CODE (operands[2]) == CONST_DOUBLE)"
5148 [(clobber (const_int 0))]
5152 highp = gen_highpart_mode (SImode, DImode, operands[2]);
5153 lowp = gen_lowpart (SImode, operands[2]);
5154 if ((lowp == const0_rtx)
5155 && (operands[0] == operands[1]))
5157 emit_insn (gen_rtx_SET (VOIDmode,
5158 gen_highpart (SImode, operands[0]),
5159 gen_rtx_MINUS (SImode,
5160 gen_highpart_mode (SImode, DImode,
5166 emit_insn (gen_cmp_minus_cc_set (gen_lowpart (SImode, operands[0]),
5167 gen_lowpart (SImode, operands[1]),
5169 emit_insn (gen_subx (gen_highpart (SImode, operands[0]),
5170 gen_highpart_mode (SImode, DImode, operands[1]),
5175 [(set_attr "length" "2")])
5178 [(set (match_operand:DI 0 "register_operand" "")
5179 (minus:DI (match_operand:DI 1 "register_operand" "")
5180 (match_operand:DI 2 "register_operand" "")))
5181 (clobber (reg:CC 100))]
5183 && reload_completed"
5184 [(clobber (const_int 0))]
5186 emit_insn (gen_cmp_minus_cc_set (gen_lowpart (SImode, operands[0]),
5187 gen_lowpart (SImode, operands[1]),
5188 gen_lowpart (SImode, operands[2])));
5189 emit_insn (gen_subx (gen_highpart (SImode, operands[0]),
5190 gen_highpart (SImode, operands[1]),
5191 gen_highpart (SImode, operands[2])));
5195 (define_insn_and_split ""
5196 [(set (match_operand:DI 0 "register_operand" "=r")
5197 (minus:DI (match_operand:DI 1 "register_operand" "r")
5198 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))
5199 (clobber (reg:CC 100))]
5202 "&& reload_completed"
5203 [(parallel [(set (reg:CC_NOOV 100)
5204 (compare:CC_NOOV (minus:SI (match_dup 3) (match_dup 2))
5206 (set (match_dup 5) (minus:SI (match_dup 3) (match_dup 2)))])
5208 (minus:SI (minus:SI (match_dup 4) (const_int 0))
5209 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5210 "operands[3] = gen_lowpart (SImode, operands[1]);
5211 operands[4] = gen_highpart (SImode, operands[1]);
5212 operands[5] = gen_lowpart (SImode, operands[0]);
5213 operands[6] = gen_highpart (SImode, operands[0]);"
5214 [(set_attr "length" "2")])
5216 (define_insn "*subdi3_sp64"
5217 [(set (match_operand:DI 0 "register_operand" "=r,r")
5218 (minus:DI (match_operand:DI 1 "register_operand" "r,r")
5219 (match_operand:DI 2 "arith_double_add_operand" "rHI,O")))]
5225 (define_insn "subsi3"
5226 [(set (match_operand:SI 0 "register_operand" "=r,r,d")
5227 (minus:SI (match_operand:SI 1 "register_operand" "r,r,d")
5228 (match_operand:SI 2 "arith_add_operand" "rI,O,d")))]
5233 fpsub32s\t%1, %2, %0"
5234 [(set_attr "type" "*,*,fga")
5235 (set_attr "fptype" "*,*,single")])
5237 (define_insn "*cmp_minus_cc"
5238 [(set (reg:CC_NOOV 100)
5239 (compare:CC_NOOV (minus:SI (match_operand:SI 0 "reg_or_0_operand" "rJ")
5240 (match_operand:SI 1 "arith_operand" "rI"))
5243 "subcc\t%r0, %1, %%g0"
5244 [(set_attr "type" "compare")])
5246 (define_insn "*cmp_minus_ccx"
5247 [(set (reg:CCX_NOOV 100)
5248 (compare:CCX_NOOV (minus:DI (match_operand:DI 0 "register_operand" "r")
5249 (match_operand:DI 1 "arith_double_operand" "rHI"))
5252 "subcc\t%0, %1, %%g0"
5253 [(set_attr "type" "compare")])
5255 (define_insn "cmp_minus_cc_set"
5256 [(set (reg:CC_NOOV 100)
5257 (compare:CC_NOOV (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5258 (match_operand:SI 2 "arith_operand" "rI"))
5260 (set (match_operand:SI 0 "register_operand" "=r")
5261 (minus:SI (match_dup 1) (match_dup 2)))]
5263 "subcc\t%r1, %2, %0"
5264 [(set_attr "type" "compare")])
5266 (define_insn "*cmp_minus_ccx_set"
5267 [(set (reg:CCX_NOOV 100)
5268 (compare:CCX_NOOV (minus:DI (match_operand:DI 1 "register_operand" "r")
5269 (match_operand:DI 2 "arith_double_operand" "rHI"))
5271 (set (match_operand:DI 0 "register_operand" "=r")
5272 (minus:DI (match_dup 1) (match_dup 2)))]
5275 [(set_attr "type" "compare")])
5277 ;; Integer Multiply/Divide.
5279 ;; The 32 bit multiply/divide instructions are deprecated on v9, but at
5280 ;; least in UltraSPARC I, II and IIi it is a win tick-wise.
5282 (define_insn "mulsi3"
5283 [(set (match_operand:SI 0 "register_operand" "=r")
5284 (mult:SI (match_operand:SI 1 "arith_operand" "%r")
5285 (match_operand:SI 2 "arith_operand" "rI")))]
5288 [(set_attr "type" "imul")])
5290 (define_expand "muldi3"
5291 [(set (match_operand:DI 0 "register_operand" "=r")
5292 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r")
5293 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5294 "TARGET_ARCH64 || TARGET_V8PLUS"
5298 emit_insn (gen_muldi3_v8plus (operands[0], operands[1], operands[2]));
5303 (define_insn "*muldi3_sp64"
5304 [(set (match_operand:DI 0 "register_operand" "=r")
5305 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r")
5306 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5309 [(set_attr "type" "imul")])
5311 ;; V8plus wide multiply.
5313 (define_insn "muldi3_v8plus"
5314 [(set (match_operand:DI 0 "register_operand" "=r,h")
5315 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r,0")
5316 (match_operand:DI 2 "arith_double_operand" "rI,rI")))
5317 (clobber (match_scratch:SI 3 "=&h,X"))
5318 (clobber (match_scratch:SI 4 "=&h,X"))]
5321 if (sparc_check_64 (operands[1], insn) <= 0)
5322 output_asm_insn ("srl\t%L1, 0, %L1", operands);
5323 if (which_alternative == 1)
5324 output_asm_insn ("sllx\t%H1, 32, %H1", operands);
5325 if (GET_CODE (operands[2]) == CONST_INT)
5327 if (which_alternative == 1)
5328 return "or\t%L1, %H1, %H1\n\tmulx\t%H1, %2, %L0\;srlx\t%L0, 32, %H0";
5330 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";
5332 else if (rtx_equal_p (operands[1], operands[2]))
5334 if (which_alternative == 1)
5335 return "or\t%L1, %H1, %H1\n\tmulx\t%H1, %H1, %L0\;srlx\t%L0, 32, %H0";
5337 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";
5339 if (sparc_check_64 (operands[2], insn) <= 0)
5340 output_asm_insn ("srl\t%L2, 0, %L2", operands);
5341 if (which_alternative == 1)
5342 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";
5344 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";
5346 [(set_attr "type" "multi")
5347 (set_attr "length" "9,8")])
5349 (define_insn "*cmp_mul_set"
5351 (compare:CC (mult:SI (match_operand:SI 1 "arith_operand" "%r")
5352 (match_operand:SI 2 "arith_operand" "rI"))
5354 (set (match_operand:SI 0 "register_operand" "=r")
5355 (mult:SI (match_dup 1) (match_dup 2)))]
5356 "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS"
5357 "smulcc\t%1, %2, %0"
5358 [(set_attr "type" "imul")])
5360 (define_expand "mulsidi3"
5361 [(set (match_operand:DI 0 "register_operand" "")
5362 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
5363 (sign_extend:DI (match_operand:SI 2 "arith_operand" ""))))]
5366 if (CONSTANT_P (operands[2]))
5369 emit_insn (gen_const_mulsidi3_v8plus (operands[0], operands[1],
5371 else if (TARGET_ARCH32)
5372 emit_insn (gen_const_mulsidi3_sp32 (operands[0], operands[1],
5375 emit_insn (gen_const_mulsidi3_sp64 (operands[0], operands[1],
5381 emit_insn (gen_mulsidi3_v8plus (operands[0], operands[1], operands[2]));
5386 ;; V9 puts the 64 bit product in a 64 bit register. Only out or global
5387 ;; registers can hold 64 bit values in the V8plus environment.
5389 (define_insn "mulsidi3_v8plus"
5390 [(set (match_operand:DI 0 "register_operand" "=h,r")
5391 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5392 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
5393 (clobber (match_scratch:SI 3 "=X,&h"))]
5396 smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
5397 smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
5398 [(set_attr "type" "multi")
5399 (set_attr "length" "2,3")])
5402 (define_insn "const_mulsidi3_v8plus"
5403 [(set (match_operand:DI 0 "register_operand" "=h,r")
5404 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5405 (match_operand:DI 2 "small_int" "I,I")))
5406 (clobber (match_scratch:SI 3 "=X,&h"))]
5409 smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
5410 smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
5411 [(set_attr "type" "multi")
5412 (set_attr "length" "2,3")])
5415 (define_insn "*mulsidi3_sp32"
5416 [(set (match_operand:DI 0 "register_operand" "=r")
5417 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5418 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
5421 return TARGET_SPARCLET
5422 ? "smuld\t%1, %2, %L0"
5423 : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
5426 (if_then_else (eq_attr "isa" "sparclet")
5427 (const_string "imul") (const_string "multi")))
5428 (set (attr "length")
5429 (if_then_else (eq_attr "isa" "sparclet")
5430 (const_int 1) (const_int 2)))])
5432 (define_insn "*mulsidi3_sp64"
5433 [(set (match_operand:DI 0 "register_operand" "=r")
5434 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5435 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
5436 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5438 [(set_attr "type" "imul")])
5440 ;; Extra pattern, because sign_extend of a constant isn't valid.
5443 (define_insn "const_mulsidi3_sp32"
5444 [(set (match_operand:DI 0 "register_operand" "=r")
5445 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5446 (match_operand:DI 2 "small_int" "I")))]
5449 return TARGET_SPARCLET
5450 ? "smuld\t%1, %2, %L0"
5451 : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
5454 (if_then_else (eq_attr "isa" "sparclet")
5455 (const_string "imul") (const_string "multi")))
5456 (set (attr "length")
5457 (if_then_else (eq_attr "isa" "sparclet")
5458 (const_int 1) (const_int 2)))])
5460 (define_insn "const_mulsidi3_sp64"
5461 [(set (match_operand:DI 0 "register_operand" "=r")
5462 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5463 (match_operand:DI 2 "small_int" "I")))]
5464 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5466 [(set_attr "type" "imul")])
5468 (define_expand "smulsi3_highpart"
5469 [(set (match_operand:SI 0 "register_operand" "")
5471 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
5472 (sign_extend:DI (match_operand:SI 2 "arith_operand" "")))
5474 "TARGET_HARD_MUL && TARGET_ARCH32"
5476 if (CONSTANT_P (operands[2]))
5480 emit_insn (gen_const_smulsi3_highpart_v8plus (operands[0],
5486 emit_insn (gen_const_smulsi3_highpart (operands[0], operands[1], operands[2]));
5491 emit_insn (gen_smulsi3_highpart_v8plus (operands[0], operands[1],
5492 operands[2], GEN_INT (32)));
5498 (define_insn "smulsi3_highpart_v8plus"
5499 [(set (match_operand:SI 0 "register_operand" "=h,r")
5501 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5502 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
5503 (match_operand:SI 3 "const_int_operand" "i,i"))))
5504 (clobber (match_scratch:SI 4 "=X,&h"))]
5507 smul\t%1, %2, %0\;srlx\t%0, %3, %0
5508 smul\t%1, %2, %4\;srlx\t%4, %3, %0"
5509 [(set_attr "type" "multi")
5510 (set_attr "length" "2")])
5512 ;; The combiner changes TRUNCATE in the previous pattern to SUBREG.
5515 [(set (match_operand:SI 0 "register_operand" "=h,r")
5518 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5519 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
5520 (match_operand:SI 3 "const_int_operand" "i,i"))
5522 (clobber (match_scratch:SI 4 "=X,&h"))]
5525 smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
5526 smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
5527 [(set_attr "type" "multi")
5528 (set_attr "length" "2")])
5531 (define_insn "const_smulsi3_highpart_v8plus"
5532 [(set (match_operand:SI 0 "register_operand" "=h,r")
5534 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5535 (match_operand:DI 2 "small_int" "i,i"))
5536 (match_operand:SI 3 "const_int_operand" "i,i"))))
5537 (clobber (match_scratch:SI 4 "=X,&h"))]
5540 smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
5541 smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
5542 [(set_attr "type" "multi")
5543 (set_attr "length" "2")])
5546 (define_insn "*smulsi3_highpart_sp32"
5547 [(set (match_operand:SI 0 "register_operand" "=r")
5549 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5550 (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
5553 "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
5554 [(set_attr "type" "multi")
5555 (set_attr "length" "2")])
5558 (define_insn "const_smulsi3_highpart"
5559 [(set (match_operand:SI 0 "register_operand" "=r")
5561 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5562 (match_operand:DI 2 "small_int" "i"))
5565 "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
5566 [(set_attr "type" "multi")
5567 (set_attr "length" "2")])
5569 (define_expand "umulsidi3"
5570 [(set (match_operand:DI 0 "register_operand" "")
5571 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
5572 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" ""))))]
5575 if (CONSTANT_P (operands[2]))
5578 emit_insn (gen_const_umulsidi3_v8plus (operands[0], operands[1],
5580 else if (TARGET_ARCH32)
5581 emit_insn (gen_const_umulsidi3_sp32 (operands[0], operands[1],
5584 emit_insn (gen_const_umulsidi3_sp64 (operands[0], operands[1],
5590 emit_insn (gen_umulsidi3_v8plus (operands[0], operands[1], operands[2]));
5596 (define_insn "umulsidi3_v8plus"
5597 [(set (match_operand:DI 0 "register_operand" "=h,r")
5598 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5599 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
5600 (clobber (match_scratch:SI 3 "=X,&h"))]
5603 umul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
5604 umul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
5605 [(set_attr "type" "multi")
5606 (set_attr "length" "2,3")])
5609 (define_insn "*umulsidi3_sp32"
5610 [(set (match_operand:DI 0 "register_operand" "=r")
5611 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5612 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
5615 return TARGET_SPARCLET
5616 ? "umuld\t%1, %2, %L0"
5617 : "umul\t%1, %2, %L0\n\trd\t%%y, %H0";
5620 (if_then_else (eq_attr "isa" "sparclet")
5621 (const_string "imul") (const_string "multi")))
5622 (set (attr "length")
5623 (if_then_else (eq_attr "isa" "sparclet")
5624 (const_int 1) (const_int 2)))])
5626 (define_insn "*umulsidi3_sp64"
5627 [(set (match_operand:DI 0 "register_operand" "=r")
5628 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5629 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
5630 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5632 [(set_attr "type" "imul")])
5634 ;; Extra pattern, because sign_extend of a constant isn't valid.
5637 (define_insn "const_umulsidi3_sp32"
5638 [(set (match_operand:DI 0 "register_operand" "=r")
5639 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5640 (match_operand:DI 2 "uns_small_int" "")))]
5643 return TARGET_SPARCLET
5644 ? "umuld\t%1, %s2, %L0"
5645 : "umul\t%1, %s2, %L0\n\trd\t%%y, %H0";
5648 (if_then_else (eq_attr "isa" "sparclet")
5649 (const_string "imul") (const_string "multi")))
5650 (set (attr "length")
5651 (if_then_else (eq_attr "isa" "sparclet")
5652 (const_int 1) (const_int 2)))])
5654 (define_insn "const_umulsidi3_sp64"
5655 [(set (match_operand:DI 0 "register_operand" "=r")
5656 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5657 (match_operand:DI 2 "uns_small_int" "")))]
5658 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5660 [(set_attr "type" "imul")])
5663 (define_insn "const_umulsidi3_v8plus"
5664 [(set (match_operand:DI 0 "register_operand" "=h,r")
5665 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5666 (match_operand:DI 2 "uns_small_int" "")))
5667 (clobber (match_scratch:SI 3 "=X,h"))]
5670 umul\t%1, %s2, %L0\n\tsrlx\t%L0, 32, %H0
5671 umul\t%1, %s2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
5672 [(set_attr "type" "multi")
5673 (set_attr "length" "2,3")])
5675 (define_expand "umulsi3_highpart"
5676 [(set (match_operand:SI 0 "register_operand" "")
5678 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
5679 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" "")))
5681 "TARGET_HARD_MUL && TARGET_ARCH32"
5683 if (CONSTANT_P (operands[2]))
5687 emit_insn (gen_const_umulsi3_highpart_v8plus (operands[0],
5693 emit_insn (gen_const_umulsi3_highpart (operands[0], operands[1], operands[2]));
5698 emit_insn (gen_umulsi3_highpart_v8plus (operands[0], operands[1],
5699 operands[2], GEN_INT (32)));
5705 (define_insn "umulsi3_highpart_v8plus"
5706 [(set (match_operand:SI 0 "register_operand" "=h,r")
5708 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5709 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
5710 (match_operand:SI 3 "const_int_operand" "i,i"))))
5711 (clobber (match_scratch:SI 4 "=X,h"))]
5714 umul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
5715 umul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
5716 [(set_attr "type" "multi")
5717 (set_attr "length" "2")])
5720 (define_insn "const_umulsi3_highpart_v8plus"
5721 [(set (match_operand:SI 0 "register_operand" "=h,r")
5723 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5724 (match_operand:DI 2 "uns_small_int" ""))
5725 (match_operand:SI 3 "const_int_operand" "i,i"))))
5726 (clobber (match_scratch:SI 4 "=X,h"))]
5729 umul\t%1, %s2, %0\n\tsrlx\t%0, %3, %0
5730 umul\t%1, %s2, %4\n\tsrlx\t%4, %3, %0"
5731 [(set_attr "type" "multi")
5732 (set_attr "length" "2")])
5735 (define_insn "*umulsi3_highpart_sp32"
5736 [(set (match_operand:SI 0 "register_operand" "=r")
5738 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5739 (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
5742 "umul\t%1, %2, %%g0\n\trd\t%%y, %0"
5743 [(set_attr "type" "multi")
5744 (set_attr "length" "2")])
5747 (define_insn "const_umulsi3_highpart"
5748 [(set (match_operand:SI 0 "register_operand" "=r")
5750 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5751 (match_operand:DI 2 "uns_small_int" ""))
5754 "umul\t%1, %s2, %%g0\n\trd\t%%y, %0"
5755 [(set_attr "type" "multi")
5756 (set_attr "length" "2")])
5758 ;; The v8 architecture specifies that there must be 3 instructions between
5759 ;; a y register write and a use of it for correct results.
5761 (define_expand "divsi3"
5762 [(parallel [(set (match_operand:SI 0 "register_operand" "=r,r")
5763 (div:SI (match_operand:SI 1 "register_operand" "r,r")
5764 (match_operand:SI 2 "input_operand" "rI,m")))
5765 (clobber (match_scratch:SI 3 "=&r,&r"))])]
5766 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
5770 operands[3] = gen_reg_rtx(SImode);
5771 emit_insn (gen_ashrsi3 (operands[3], operands[1], GEN_INT (31)));
5772 emit_insn (gen_divsi3_sp64 (operands[0], operands[1], operands[2],
5778 (define_insn "divsi3_sp32"
5779 [(set (match_operand:SI 0 "register_operand" "=r,r")
5780 (div:SI (match_operand:SI 1 "register_operand" "r,r")
5781 (match_operand:SI 2 "input_operand" "rI,m")))
5782 (clobber (match_scratch:SI 3 "=&r,&r"))]
5783 "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS)
5786 if (which_alternative == 0)
5788 return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tsdiv\t%1, %2, %0";
5790 return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tnop\n\tnop\n\tnop\n\tsdiv\t%1, %2, %0";
5793 return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tld\t%2, %3\n\tsdiv\t%1, %3, %0";
5795 return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tld\t%2, %3\n\tnop\n\tnop\n\tsdiv\t%1, %3, %0";
5797 [(set_attr "type" "multi")
5798 (set (attr "length")
5799 (if_then_else (eq_attr "isa" "v9")
5800 (const_int 4) (const_int 6)))])
5802 (define_insn "divsi3_sp64"
5803 [(set (match_operand:SI 0 "register_operand" "=r")
5804 (div:SI (match_operand:SI 1 "register_operand" "r")
5805 (match_operand:SI 2 "input_operand" "rI")))
5806 (use (match_operand:SI 3 "register_operand" "r"))]
5807 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5808 "wr\t%%g0, %3, %%y\n\tsdiv\t%1, %2, %0"
5809 [(set_attr "type" "multi")
5810 (set_attr "length" "2")])
5812 (define_insn "divdi3"
5813 [(set (match_operand:DI 0 "register_operand" "=r")
5814 (div:DI (match_operand:DI 1 "register_operand" "r")
5815 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5818 [(set_attr "type" "idiv")])
5820 (define_insn "*cmp_sdiv_cc_set"
5822 (compare:CC (div:SI (match_operand:SI 1 "register_operand" "r")
5823 (match_operand:SI 2 "arith_operand" "rI"))
5825 (set (match_operand:SI 0 "register_operand" "=r")
5826 (div:SI (match_dup 1) (match_dup 2)))
5827 (clobber (match_scratch:SI 3 "=&r"))]
5828 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
5831 return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tsdivcc\t%1, %2, %0";
5833 return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tnop\n\tnop\n\tnop\n\tsdivcc\t%1, %2, %0";
5835 [(set_attr "type" "multi")
5836 (set (attr "length")
5837 (if_then_else (eq_attr "isa" "v9")
5838 (const_int 3) (const_int 6)))])
5841 (define_expand "udivsi3"
5842 [(set (match_operand:SI 0 "register_operand" "")
5843 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "")
5844 (match_operand:SI 2 "input_operand" "")))]
5845 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
5848 (define_insn "udivsi3_sp32"
5849 [(set (match_operand:SI 0 "register_operand" "=r,&r,&r")
5850 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "r,r,m")
5851 (match_operand:SI 2 "input_operand" "rI,m,r")))]
5853 || TARGET_DEPRECATED_V8_INSNS)
5856 output_asm_insn ("wr\t%%g0, %%g0, %%y", operands);
5857 switch (which_alternative)
5860 return "nop\n\tnop\n\tnop\n\tudiv\t%1, %2, %0";
5862 return "ld\t%2, %0\n\tnop\n\tnop\n\tudiv\t%1, %0, %0";
5864 return "ld\t%1, %0\n\tnop\n\tnop\n\tudiv\t%0, %2, %0";
5867 [(set_attr "type" "multi")
5868 (set_attr "length" "5")])
5870 (define_insn "udivsi3_sp64"
5871 [(set (match_operand:SI 0 "register_operand" "=r")
5872 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "r")
5873 (match_operand:SI 2 "input_operand" "rI")))]
5874 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5875 "wr\t%%g0, 0, %%y\n\tudiv\t%1, %2, %0"
5876 [(set_attr "type" "multi")
5877 (set_attr "length" "2")])
5879 (define_insn "udivdi3"
5880 [(set (match_operand:DI 0 "register_operand" "=r")
5881 (udiv:DI (match_operand:DI 1 "register_operand" "r")
5882 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5885 [(set_attr "type" "idiv")])
5887 (define_insn "*cmp_udiv_cc_set"
5889 (compare:CC (udiv:SI (match_operand:SI 1 "register_operand" "r")
5890 (match_operand:SI 2 "arith_operand" "rI"))
5892 (set (match_operand:SI 0 "register_operand" "=r")
5893 (udiv:SI (match_dup 1) (match_dup 2)))]
5895 || TARGET_DEPRECATED_V8_INSNS"
5898 return "wr\t%%g0, %%g0, %%y\n\tudivcc\t%1, %2, %0";
5900 return "wr\t%%g0, %%g0, %%y\n\tnop\n\tnop\n\tnop\n\tudivcc\t%1, %2, %0";
5902 [(set_attr "type" "multi")
5903 (set (attr "length")
5904 (if_then_else (eq_attr "isa" "v9")
5905 (const_int 2) (const_int 5)))])
5907 ; sparclet multiply/accumulate insns
5909 (define_insn "*smacsi"
5910 [(set (match_operand:SI 0 "register_operand" "=r")
5911 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "%r")
5912 (match_operand:SI 2 "arith_operand" "rI"))
5913 (match_operand:SI 3 "register_operand" "0")))]
5916 [(set_attr "type" "imul")])
5918 (define_insn "*smacdi"
5919 [(set (match_operand:DI 0 "register_operand" "=r")
5920 (plus:DI (mult:DI (sign_extend:DI
5921 (match_operand:SI 1 "register_operand" "%r"))
5923 (match_operand:SI 2 "register_operand" "r")))
5924 (match_operand:DI 3 "register_operand" "0")))]
5926 "smacd\t%1, %2, %L0"
5927 [(set_attr "type" "imul")])
5929 (define_insn "*umacdi"
5930 [(set (match_operand:DI 0 "register_operand" "=r")
5931 (plus:DI (mult:DI (zero_extend:DI
5932 (match_operand:SI 1 "register_operand" "%r"))
5934 (match_operand:SI 2 "register_operand" "r")))
5935 (match_operand:DI 3 "register_operand" "0")))]
5937 "umacd\t%1, %2, %L0"
5938 [(set_attr "type" "imul")])
5940 ;;- Boolean instructions
5941 ;; We define DImode `and' so with DImode `not' we can get
5942 ;; DImode `andn'. Other combinations are possible.
5944 (define_mode_macro V64I [DI V2SI V4HI V8QI])
5945 (define_mode_macro V32I [SI V2HI V4QI])
5947 (define_expand "and<V64I:mode>3"
5948 [(set (match_operand:V64I 0 "register_operand" "")
5949 (and:V64I (match_operand:V64I 1 "arith_double_operand" "")
5950 (match_operand:V64I 2 "arith_double_operand" "")))]
5954 (define_insn "*and<V64I:mode>3_sp32"
5955 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5956 (and:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
5957 (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
5962 [(set_attr "type" "*,fga")
5963 (set_attr "length" "2,*")
5964 (set_attr "fptype" "*,double")])
5966 (define_insn "*and<V64I:mode>3_sp64"
5967 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5968 (and:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
5969 (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
5974 [(set_attr "type" "*,fga")
5975 (set_attr "fptype" "*,double")])
5977 (define_insn "and<V32I:mode>3"
5978 [(set (match_operand:V32I 0 "register_operand" "=r,d")
5979 (and:V32I (match_operand:V32I 1 "arith_operand" "%r,d")
5980 (match_operand:V32I 2 "arith_operand" "rI,d")))]
5985 [(set_attr "type" "*,fga")
5986 (set_attr "fptype" "*,single")])
5989 [(set (match_operand:SI 0 "register_operand" "")
5990 (and:SI (match_operand:SI 1 "register_operand" "")
5991 (match_operand:SI 2 "" "")))
5992 (clobber (match_operand:SI 3 "register_operand" ""))]
5993 "GET_CODE (operands[2]) == CONST_INT
5994 && !SMALL_INT32 (operands[2])
5995 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
5996 [(set (match_dup 3) (match_dup 4))
5997 (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 1)))]
5999 operands[4] = GEN_INT (~INTVAL (operands[2]));
6002 (define_insn_and_split "*and_not_<V64I:mode>_sp32"
6003 [(set (match_operand:V64I 0 "register_operand" "=r,b")
6004 (and:V64I (not:V64I (match_operand:V64I 1 "register_operand" "%r,b"))
6005 (match_operand:V64I 2 "register_operand" "r,b")))]
6009 fandnot1\t%1, %2, %0"
6010 "&& reload_completed
6011 && ((GET_CODE (operands[0]) == REG
6012 && REGNO (operands[0]) < 32)
6013 || (GET_CODE (operands[0]) == SUBREG
6014 && GET_CODE (SUBREG_REG (operands[0])) == REG
6015 && REGNO (SUBREG_REG (operands[0])) < 32))"
6016 [(set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))
6017 (set (match_dup 6) (and:SI (not:SI (match_dup 7)) (match_dup 8)))]
6018 "operands[3] = gen_highpart (SImode, operands[0]);
6019 operands[4] = gen_highpart (SImode, operands[1]);
6020 operands[5] = gen_highpart (SImode, operands[2]);
6021 operands[6] = gen_lowpart (SImode, operands[0]);
6022 operands[7] = gen_lowpart (SImode, operands[1]);
6023 operands[8] = gen_lowpart (SImode, operands[2]);"
6024 [(set_attr "type" "*,fga")
6025 (set_attr "length" "2,*")
6026 (set_attr "fptype" "*,double")])
6028 (define_insn "*and_not_<V64I:mode>_sp64"
6029 [(set (match_operand:V64I 0 "register_operand" "=r,b")
6030 (and:V64I (not:V64I (match_operand:V64I 1 "register_operand" "%r,b"))
6031 (match_operand:V64I 2 "register_operand" "r,b")))]
6035 fandnot1\t%1, %2, %0"
6036 [(set_attr "type" "*,fga")
6037 (set_attr "fptype" "*,double")])
6039 (define_insn "*and_not_<V32I:mode>"
6040 [(set (match_operand:V32I 0 "register_operand" "=r,d")
6041 (and:V32I (not:V32I (match_operand:V32I 1 "register_operand" "%r,d"))
6042 (match_operand:V32I 2 "register_operand" "r,d")))]
6046 fandnot1s\t%1, %2, %0"
6047 [(set_attr "type" "*,fga")
6048 (set_attr "fptype" "*,single")])
6050 (define_expand "ior<V64I:mode>3"
6051 [(set (match_operand:V64I 0 "register_operand" "")
6052 (ior:V64I (match_operand:V64I 1 "arith_double_operand" "")
6053 (match_operand:V64I 2 "arith_double_operand" "")))]
6057 (define_insn "*ior<V64I:mode>3_sp32"
6058 [(set (match_operand:V64I 0 "register_operand" "=r,b")
6059 (ior:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
6060 (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
6065 [(set_attr "type" "*,fga")
6066 (set_attr "length" "2,*")
6067 (set_attr "fptype" "*,double")])
6069 (define_insn "*ior<V64I:mode>3_sp64"
6070 [(set (match_operand:V64I 0 "register_operand" "=r,b")
6071 (ior:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
6072 (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
6077 [(set_attr "type" "*,fga")
6078 (set_attr "fptype" "*,double")])
6080 (define_insn "ior<V32I:mode>3"
6081 [(set (match_operand:V32I 0 "register_operand" "=r,d")
6082 (ior:V32I (match_operand:V32I 1 "arith_operand" "%r,d")
6083 (match_operand:V32I 2 "arith_operand" "rI,d")))]
6088 [(set_attr "type" "*,fga")
6089 (set_attr "fptype" "*,single")])
6092 [(set (match_operand:SI 0 "register_operand" "")
6093 (ior:SI (match_operand:SI 1 "register_operand" "")
6094 (match_operand:SI 2 "" "")))
6095 (clobber (match_operand:SI 3 "register_operand" ""))]
6096 "GET_CODE (operands[2]) == CONST_INT
6097 && !SMALL_INT32 (operands[2])
6098 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6099 [(set (match_dup 3) (match_dup 4))
6100 (set (match_dup 0) (ior:SI (not:SI (match_dup 3)) (match_dup 1)))]
6102 operands[4] = GEN_INT (~INTVAL (operands[2]));
6105 (define_insn_and_split "*or_not_<V64I:mode>_sp32"
6106 [(set (match_operand:V64I 0 "register_operand" "=r,b")
6107 (ior:V64I (not:V64I (match_operand:V64I 1 "register_operand" "r,b"))
6108 (match_operand:V64I 2 "register_operand" "r,b")))]
6112 fornot1\t%1, %2, %0"
6113 "&& reload_completed
6114 && ((GET_CODE (operands[0]) == REG
6115 && REGNO (operands[0]) < 32)
6116 || (GET_CODE (operands[0]) == SUBREG
6117 && GET_CODE (SUBREG_REG (operands[0])) == REG
6118 && REGNO (SUBREG_REG (operands[0])) < 32))"
6119 [(set (match_dup 3) (ior:SI (not:SI (match_dup 4)) (match_dup 5)))
6120 (set (match_dup 6) (ior:SI (not:SI (match_dup 7)) (match_dup 8)))]
6121 "operands[3] = gen_highpart (SImode, operands[0]);
6122 operands[4] = gen_highpart (SImode, operands[1]);
6123 operands[5] = gen_highpart (SImode, operands[2]);
6124 operands[6] = gen_lowpart (SImode, operands[0]);
6125 operands[7] = gen_lowpart (SImode, operands[1]);
6126 operands[8] = gen_lowpart (SImode, operands[2]);"
6127 [(set_attr "type" "*,fga")
6128 (set_attr "length" "2,*")
6129 (set_attr "fptype" "*,double")])
6131 (define_insn "*or_not_<V64I:mode>_sp64"
6132 [(set (match_operand:V64I 0 "register_operand" "=r,b")
6133 (ior:V64I (not:V64I (match_operand:V64I 1 "register_operand" "r,b"))
6134 (match_operand:V64I 2 "register_operand" "r,b")))]
6138 fornot1\t%1, %2, %0"
6139 [(set_attr "type" "*,fga")
6140 (set_attr "fptype" "*,double")])
6142 (define_insn "*or_not_<V32I:mode>"
6143 [(set (match_operand:V32I 0 "register_operand" "=r,d")
6144 (ior:V32I (not:V32I (match_operand:V32I 1 "register_operand" "r,d"))
6145 (match_operand:V32I 2 "register_operand" "r,d")))]
6149 fornot1s\t%1, %2, %0"
6150 [(set_attr "type" "*,fga")
6151 (set_attr "fptype" "*,single")])
6153 (define_expand "xor<V64I:mode>3"
6154 [(set (match_operand:V64I 0 "register_operand" "")
6155 (xor:V64I (match_operand:V64I 1 "arith_double_operand" "")
6156 (match_operand:V64I 2 "arith_double_operand" "")))]
6160 (define_insn "*xor<V64I:mode>3_sp32"
6161 [(set (match_operand:V64I 0 "register_operand" "=r,b")
6162 (xor:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
6163 (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
6168 [(set_attr "type" "*,fga")
6169 (set_attr "length" "2,*")
6170 (set_attr "fptype" "*,double")])
6172 (define_insn "*xor<V64I:mode>3_sp64"
6173 [(set (match_operand:V64I 0 "register_operand" "=r,b")
6174 (xor:V64I (match_operand:V64I 1 "arith_double_operand" "%rJ,b")
6175 (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
6180 [(set_attr "type" "*,fga")
6181 (set_attr "fptype" "*,double")])
6183 (define_insn "*xordi3_sp64_dbl"
6184 [(set (match_operand:DI 0 "register_operand" "=r")
6185 (xor:DI (match_operand:DI 1 "register_operand" "r")
6186 (match_operand:DI 2 "const64_operand" "")))]
6188 && HOST_BITS_PER_WIDE_INT != 64)"
6191 (define_insn "xor<V32I:mode>3"
6192 [(set (match_operand:V32I 0 "register_operand" "=r,d")
6193 (xor:V32I (match_operand:V32I 1 "arith_operand" "%rJ,d")
6194 (match_operand:V32I 2 "arith_operand" "rI,d")))]
6199 [(set_attr "type" "*,fga")
6200 (set_attr "fptype" "*,single")])
6203 [(set (match_operand:SI 0 "register_operand" "")
6204 (xor:SI (match_operand:SI 1 "register_operand" "")
6205 (match_operand:SI 2 "" "")))
6206 (clobber (match_operand:SI 3 "register_operand" ""))]
6207 "GET_CODE (operands[2]) == CONST_INT
6208 && !SMALL_INT32 (operands[2])
6209 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6210 [(set (match_dup 3) (match_dup 4))
6211 (set (match_dup 0) (not:SI (xor:SI (match_dup 3) (match_dup 1))))]
6213 operands[4] = GEN_INT (~INTVAL (operands[2]));
6217 [(set (match_operand:SI 0 "register_operand" "")
6218 (not:SI (xor:SI (match_operand:SI 1 "register_operand" "")
6219 (match_operand:SI 2 "" ""))))
6220 (clobber (match_operand:SI 3 "register_operand" ""))]
6221 "GET_CODE (operands[2]) == CONST_INT
6222 && !SMALL_INT32 (operands[2])
6223 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6224 [(set (match_dup 3) (match_dup 4))
6225 (set (match_dup 0) (xor:SI (match_dup 3) (match_dup 1)))]
6227 operands[4] = GEN_INT (~INTVAL (operands[2]));
6230 ;; Split DImode logical operations requiring two instructions.
6232 [(set (match_operand:V64I 0 "register_operand" "")
6233 (match_operator:V64I 1 "cc_arithop" ; AND, IOR, XOR
6234 [(match_operand:V64I 2 "register_operand" "")
6235 (match_operand:V64I 3 "arith_double_operand" "")]))]
6238 && ((GET_CODE (operands[0]) == REG
6239 && REGNO (operands[0]) < 32)
6240 || (GET_CODE (operands[0]) == SUBREG
6241 && GET_CODE (SUBREG_REG (operands[0])) == REG
6242 && REGNO (SUBREG_REG (operands[0])) < 32))"
6243 [(set (match_dup 4) (match_op_dup:SI 1 [(match_dup 6) (match_dup 8)]))
6244 (set (match_dup 5) (match_op_dup:SI 1 [(match_dup 7) (match_dup 9)]))]
6246 operands[4] = gen_highpart (SImode, operands[0]);
6247 operands[5] = gen_lowpart (SImode, operands[0]);
6248 operands[6] = gen_highpart (SImode, operands[2]);
6249 operands[7] = gen_lowpart (SImode, operands[2]);
6250 #if HOST_BITS_PER_WIDE_INT == 32
6251 if (GET_CODE (operands[3]) == CONST_INT && <V64I:MODE>mode == DImode)
6253 if (INTVAL (operands[3]) < 0)
6254 operands[8] = constm1_rtx;
6256 operands[8] = const0_rtx;
6260 operands[8] = gen_highpart_mode (SImode, <V64I:MODE>mode, operands[3]);
6261 operands[9] = gen_lowpart (SImode, operands[3]);
6264 ;; xnor patterns. Note that (a ^ ~b) == (~a ^ b) == ~(a ^ b).
6265 ;; Combine now canonicalizes to the rightmost expression.
6266 (define_insn_and_split "*xor_not_<V64I:mode>_sp32"
6267 [(set (match_operand:V64I 0 "register_operand" "=r,b")
6268 (not:V64I (xor:V64I (match_operand:V64I 1 "register_operand" "r,b")
6269 (match_operand:V64I 2 "register_operand" "r,b"))))]
6274 "&& reload_completed
6275 && ((GET_CODE (operands[0]) == REG
6276 && REGNO (operands[0]) < 32)
6277 || (GET_CODE (operands[0]) == SUBREG
6278 && GET_CODE (SUBREG_REG (operands[0])) == REG
6279 && REGNO (SUBREG_REG (operands[0])) < 32))"
6280 [(set (match_dup 3) (not:SI (xor:SI (match_dup 4) (match_dup 5))))
6281 (set (match_dup 6) (not:SI (xor:SI (match_dup 7) (match_dup 8))))]
6282 "operands[3] = gen_highpart (SImode, operands[0]);
6283 operands[4] = gen_highpart (SImode, operands[1]);
6284 operands[5] = gen_highpart (SImode, operands[2]);
6285 operands[6] = gen_lowpart (SImode, operands[0]);
6286 operands[7] = gen_lowpart (SImode, operands[1]);
6287 operands[8] = gen_lowpart (SImode, operands[2]);"
6288 [(set_attr "type" "*,fga")
6289 (set_attr "length" "2,*")
6290 (set_attr "fptype" "*,double")])
6292 (define_insn "*xor_not_<V64I:mode>_sp64"
6293 [(set (match_operand:V64I 0 "register_operand" "=r,b")
6294 (not:V64I (xor:V64I (match_operand:V64I 1 "reg_or_0_operand" "rJ,b")
6295 (match_operand:V64I 2 "arith_double_operand" "rHI,b"))))]
6300 [(set_attr "type" "*,fga")
6301 (set_attr "fptype" "*,double")])
6303 (define_insn "*xor_not_<V32I:mode>"
6304 [(set (match_operand:V32I 0 "register_operand" "=r,d")
6305 (not:V32I (xor:V32I (match_operand:V32I 1 "reg_or_0_operand" "rJ,d")
6306 (match_operand:V32I 2 "arith_operand" "rI,d"))))]
6311 [(set_attr "type" "*,fga")
6312 (set_attr "fptype" "*,single")])
6314 ;; These correspond to the above in the case where we also (or only)
6315 ;; want to set the condition code.
6317 (define_insn "*cmp_cc_arith_op"
6320 (match_operator:SI 2 "cc_arithop"
6321 [(match_operand:SI 0 "arith_operand" "%r")
6322 (match_operand:SI 1 "arith_operand" "rI")])
6325 "%A2cc\t%0, %1, %%g0"
6326 [(set_attr "type" "compare")])
6328 (define_insn "*cmp_ccx_arith_op"
6331 (match_operator:DI 2 "cc_arithop"
6332 [(match_operand:DI 0 "arith_double_operand" "%r")
6333 (match_operand:DI 1 "arith_double_operand" "rHI")])
6336 "%A2cc\t%0, %1, %%g0"
6337 [(set_attr "type" "compare")])
6339 (define_insn "*cmp_cc_arith_op_set"
6342 (match_operator:SI 3 "cc_arithop"
6343 [(match_operand:SI 1 "arith_operand" "%r")
6344 (match_operand:SI 2 "arith_operand" "rI")])
6346 (set (match_operand:SI 0 "register_operand" "=r")
6347 (match_operator:SI 4 "cc_arithop" [(match_dup 1) (match_dup 2)]))]
6348 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
6350 [(set_attr "type" "compare")])
6352 (define_insn "*cmp_ccx_arith_op_set"
6355 (match_operator:DI 3 "cc_arithop"
6356 [(match_operand:DI 1 "arith_double_operand" "%r")
6357 (match_operand:DI 2 "arith_double_operand" "rHI")])
6359 (set (match_operand:DI 0 "register_operand" "=r")
6360 (match_operator:DI 4 "cc_arithop" [(match_dup 1) (match_dup 2)]))]
6361 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
6363 [(set_attr "type" "compare")])
6365 (define_insn "*cmp_cc_xor_not"
6368 (not:SI (xor:SI (match_operand:SI 0 "reg_or_0_operand" "%rJ")
6369 (match_operand:SI 1 "arith_operand" "rI")))
6372 "xnorcc\t%r0, %1, %%g0"
6373 [(set_attr "type" "compare")])
6375 (define_insn "*cmp_ccx_xor_not"
6378 (not:DI (xor:DI (match_operand:DI 0 "reg_or_0_operand" "%rJ")
6379 (match_operand:DI 1 "arith_double_operand" "rHI")))
6382 "xnorcc\t%r0, %1, %%g0"
6383 [(set_attr "type" "compare")])
6385 (define_insn "*cmp_cc_xor_not_set"
6388 (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
6389 (match_operand:SI 2 "arith_operand" "rI")))
6391 (set (match_operand:SI 0 "register_operand" "=r")
6392 (not:SI (xor:SI (match_dup 1) (match_dup 2))))]
6394 "xnorcc\t%r1, %2, %0"
6395 [(set_attr "type" "compare")])
6397 (define_insn "*cmp_ccx_xor_not_set"
6400 (not:DI (xor:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ")
6401 (match_operand:DI 2 "arith_double_operand" "rHI")))
6403 (set (match_operand:DI 0 "register_operand" "=r")
6404 (not:DI (xor:DI (match_dup 1) (match_dup 2))))]
6406 "xnorcc\t%r1, %2, %0"
6407 [(set_attr "type" "compare")])
6409 (define_insn "*cmp_cc_arith_op_not"
6412 (match_operator:SI 2 "cc_arithopn"
6413 [(not:SI (match_operand:SI 0 "arith_operand" "rI"))
6414 (match_operand:SI 1 "reg_or_0_operand" "rJ")])
6417 "%B2cc\t%r1, %0, %%g0"
6418 [(set_attr "type" "compare")])
6420 (define_insn "*cmp_ccx_arith_op_not"
6423 (match_operator:DI 2 "cc_arithopn"
6424 [(not:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
6425 (match_operand:DI 1 "reg_or_0_operand" "rJ")])
6428 "%B2cc\t%r1, %0, %%g0"
6429 [(set_attr "type" "compare")])
6431 (define_insn "*cmp_cc_arith_op_not_set"
6434 (match_operator:SI 3 "cc_arithopn"
6435 [(not:SI (match_operand:SI 1 "arith_operand" "rI"))
6436 (match_operand:SI 2 "reg_or_0_operand" "rJ")])
6438 (set (match_operand:SI 0 "register_operand" "=r")
6439 (match_operator:SI 4 "cc_arithopn"
6440 [(not:SI (match_dup 1)) (match_dup 2)]))]
6441 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
6442 "%B3cc\t%r2, %1, %0"
6443 [(set_attr "type" "compare")])
6445 (define_insn "*cmp_ccx_arith_op_not_set"
6448 (match_operator:DI 3 "cc_arithopn"
6449 [(not:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
6450 (match_operand:DI 2 "reg_or_0_operand" "rJ")])
6452 (set (match_operand:DI 0 "register_operand" "=r")
6453 (match_operator:DI 4 "cc_arithopn"
6454 [(not:DI (match_dup 1)) (match_dup 2)]))]
6455 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
6456 "%B3cc\t%r2, %1, %0"
6457 [(set_attr "type" "compare")])
6459 ;; We cannot use the "neg" pseudo insn because the Sun assembler
6460 ;; does not know how to make it work for constants.
6462 (define_expand "negdi2"
6463 [(set (match_operand:DI 0 "register_operand" "=r")
6464 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
6467 if (! TARGET_ARCH64)
6469 emit_insn (gen_rtx_PARALLEL
6472 gen_rtx_SET (VOIDmode, operand0,
6473 gen_rtx_NEG (DImode, operand1)),
6474 gen_rtx_CLOBBER (VOIDmode,
6475 gen_rtx_REG (CCmode,
6481 (define_insn_and_split "*negdi2_sp32"
6482 [(set (match_operand:DI 0 "register_operand" "=r")
6483 (neg:DI (match_operand:DI 1 "register_operand" "r")))
6484 (clobber (reg:CC 100))]
6487 "&& reload_completed"
6488 [(parallel [(set (reg:CC_NOOV 100)
6489 (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 5))
6491 (set (match_dup 4) (minus:SI (const_int 0) (match_dup 5)))])
6492 (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
6493 (ltu:SI (reg:CC 100) (const_int 0))))]
6494 "operands[2] = gen_highpart (SImode, operands[0]);
6495 operands[3] = gen_highpart (SImode, operands[1]);
6496 operands[4] = gen_lowpart (SImode, operands[0]);
6497 operands[5] = gen_lowpart (SImode, operands[1]);"
6498 [(set_attr "length" "2")])
6500 (define_insn "*negdi2_sp64"
6501 [(set (match_operand:DI 0 "register_operand" "=r")
6502 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
6504 "sub\t%%g0, %1, %0")
6506 (define_insn "negsi2"
6507 [(set (match_operand:SI 0 "register_operand" "=r")
6508 (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
6510 "sub\t%%g0, %1, %0")
6512 (define_insn "*cmp_cc_neg"
6513 [(set (reg:CC_NOOV 100)
6514 (compare:CC_NOOV (neg:SI (match_operand:SI 0 "arith_operand" "rI"))
6517 "subcc\t%%g0, %0, %%g0"
6518 [(set_attr "type" "compare")])
6520 (define_insn "*cmp_ccx_neg"
6521 [(set (reg:CCX_NOOV 100)
6522 (compare:CCX_NOOV (neg:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
6525 "subcc\t%%g0, %0, %%g0"
6526 [(set_attr "type" "compare")])
6528 (define_insn "*cmp_cc_set_neg"
6529 [(set (reg:CC_NOOV 100)
6530 (compare:CC_NOOV (neg:SI (match_operand:SI 1 "arith_operand" "rI"))
6532 (set (match_operand:SI 0 "register_operand" "=r")
6533 (neg:SI (match_dup 1)))]
6535 "subcc\t%%g0, %1, %0"
6536 [(set_attr "type" "compare")])
6538 (define_insn "*cmp_ccx_set_neg"
6539 [(set (reg:CCX_NOOV 100)
6540 (compare:CCX_NOOV (neg:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
6542 (set (match_operand:DI 0 "register_operand" "=r")
6543 (neg:DI (match_dup 1)))]
6545 "subcc\t%%g0, %1, %0"
6546 [(set_attr "type" "compare")])
6548 ;; We cannot use the "not" pseudo insn because the Sun assembler
6549 ;; does not know how to make it work for constants.
6550 (define_expand "one_cmpl<V64I:mode>2"
6551 [(set (match_operand:V64I 0 "register_operand" "")
6552 (not:V64I (match_operand:V64I 1 "register_operand" "")))]
6556 (define_insn_and_split "*one_cmpl<V64I:mode>2_sp32"
6557 [(set (match_operand:V64I 0 "register_operand" "=r,b")
6558 (not:V64I (match_operand:V64I 1 "register_operand" "r,b")))]
6563 "&& reload_completed
6564 && ((GET_CODE (operands[0]) == REG
6565 && REGNO (operands[0]) < 32)
6566 || (GET_CODE (operands[0]) == SUBREG
6567 && GET_CODE (SUBREG_REG (operands[0])) == REG
6568 && REGNO (SUBREG_REG (operands[0])) < 32))"
6569 [(set (match_dup 2) (not:SI (xor:SI (match_dup 3) (const_int 0))))
6570 (set (match_dup 4) (not:SI (xor:SI (match_dup 5) (const_int 0))))]
6571 "operands[2] = gen_highpart (SImode, operands[0]);
6572 operands[3] = gen_highpart (SImode, operands[1]);
6573 operands[4] = gen_lowpart (SImode, operands[0]);
6574 operands[5] = gen_lowpart (SImode, operands[1]);"
6575 [(set_attr "type" "*,fga")
6576 (set_attr "length" "2,*")
6577 (set_attr "fptype" "*,double")])
6579 (define_insn "*one_cmpl<V64I:mode>2_sp64"
6580 [(set (match_operand:V64I 0 "register_operand" "=r,b")
6581 (not:V64I (match_operand:V64I 1 "arith_double_operand" "rHI,b")))]
6586 [(set_attr "type" "*,fga")
6587 (set_attr "fptype" "*,double")])
6589 (define_insn "one_cmpl<V32I:mode>2"
6590 [(set (match_operand:V32I 0 "register_operand" "=r,d")
6591 (not:V32I (match_operand:V32I 1 "arith_operand" "rI,d")))]
6596 [(set_attr "type" "*,fga")
6597 (set_attr "fptype" "*,single")])
6599 (define_insn "*cmp_cc_not"
6601 (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI"))
6604 "xnorcc\t%%g0, %0, %%g0"
6605 [(set_attr "type" "compare")])
6607 (define_insn "*cmp_ccx_not"
6609 (compare:CCX (not:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
6612 "xnorcc\t%%g0, %0, %%g0"
6613 [(set_attr "type" "compare")])
6615 (define_insn "*cmp_cc_set_not"
6617 (compare:CC (not:SI (match_operand:SI 1 "arith_operand" "rI"))
6619 (set (match_operand:SI 0 "register_operand" "=r")
6620 (not:SI (match_dup 1)))]
6622 "xnorcc\t%%g0, %1, %0"
6623 [(set_attr "type" "compare")])
6625 (define_insn "*cmp_ccx_set_not"
6627 (compare:CCX (not:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
6629 (set (match_operand:DI 0 "register_operand" "=r")
6630 (not:DI (match_dup 1)))]
6632 "xnorcc\t%%g0, %1, %0"
6633 [(set_attr "type" "compare")])
6635 (define_insn "*cmp_cc_set"
6636 [(set (match_operand:SI 0 "register_operand" "=r")
6637 (match_operand:SI 1 "register_operand" "r"))
6639 (compare:CC (match_dup 1)
6643 [(set_attr "type" "compare")])
6645 (define_insn "*cmp_ccx_set64"
6646 [(set (match_operand:DI 0 "register_operand" "=r")
6647 (match_operand:DI 1 "register_operand" "r"))
6649 (compare:CCX (match_dup 1)
6653 [(set_attr "type" "compare")])
6655 ;; Floating point arithmetic instructions.
6657 (define_expand "addtf3"
6658 [(set (match_operand:TF 0 "nonimmediate_operand" "")
6659 (plus:TF (match_operand:TF 1 "general_operand" "")
6660 (match_operand:TF 2 "general_operand" "")))]
6661 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6662 "emit_tfmode_binop (PLUS, operands); DONE;")
6664 (define_insn "*addtf3_hq"
6665 [(set (match_operand:TF 0 "register_operand" "=e")
6666 (plus:TF (match_operand:TF 1 "register_operand" "e")
6667 (match_operand:TF 2 "register_operand" "e")))]
6668 "TARGET_FPU && TARGET_HARD_QUAD"
6670 [(set_attr "type" "fp")])
6672 (define_insn "adddf3"
6673 [(set (match_operand:DF 0 "register_operand" "=e")
6674 (plus:DF (match_operand:DF 1 "register_operand" "e")
6675 (match_operand:DF 2 "register_operand" "e")))]
6678 [(set_attr "type" "fp")
6679 (set_attr "fptype" "double")])
6681 (define_insn "addsf3"
6682 [(set (match_operand:SF 0 "register_operand" "=f")
6683 (plus:SF (match_operand:SF 1 "register_operand" "f")
6684 (match_operand:SF 2 "register_operand" "f")))]
6687 [(set_attr "type" "fp")])
6689 (define_expand "subtf3"
6690 [(set (match_operand:TF 0 "nonimmediate_operand" "")
6691 (minus:TF (match_operand:TF 1 "general_operand" "")
6692 (match_operand:TF 2 "general_operand" "")))]
6693 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6694 "emit_tfmode_binop (MINUS, operands); DONE;")
6696 (define_insn "*subtf3_hq"
6697 [(set (match_operand:TF 0 "register_operand" "=e")
6698 (minus:TF (match_operand:TF 1 "register_operand" "e")
6699 (match_operand:TF 2 "register_operand" "e")))]
6700 "TARGET_FPU && TARGET_HARD_QUAD"
6702 [(set_attr "type" "fp")])
6704 (define_insn "subdf3"
6705 [(set (match_operand:DF 0 "register_operand" "=e")
6706 (minus:DF (match_operand:DF 1 "register_operand" "e")
6707 (match_operand:DF 2 "register_operand" "e")))]
6710 [(set_attr "type" "fp")
6711 (set_attr "fptype" "double")])
6713 (define_insn "subsf3"
6714 [(set (match_operand:SF 0 "register_operand" "=f")
6715 (minus:SF (match_operand:SF 1 "register_operand" "f")
6716 (match_operand:SF 2 "register_operand" "f")))]
6719 [(set_attr "type" "fp")])
6721 (define_expand "multf3"
6722 [(set (match_operand:TF 0 "nonimmediate_operand" "")
6723 (mult:TF (match_operand:TF 1 "general_operand" "")
6724 (match_operand:TF 2 "general_operand" "")))]
6725 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6726 "emit_tfmode_binop (MULT, operands); DONE;")
6728 (define_insn "*multf3_hq"
6729 [(set (match_operand:TF 0 "register_operand" "=e")
6730 (mult:TF (match_operand:TF 1 "register_operand" "e")
6731 (match_operand:TF 2 "register_operand" "e")))]
6732 "TARGET_FPU && TARGET_HARD_QUAD"
6734 [(set_attr "type" "fpmul")])
6736 (define_insn "muldf3"
6737 [(set (match_operand:DF 0 "register_operand" "=e")
6738 (mult:DF (match_operand:DF 1 "register_operand" "e")
6739 (match_operand:DF 2 "register_operand" "e")))]
6742 [(set_attr "type" "fpmul")
6743 (set_attr "fptype" "double")])
6745 (define_insn "mulsf3"
6746 [(set (match_operand:SF 0 "register_operand" "=f")
6747 (mult:SF (match_operand:SF 1 "register_operand" "f")
6748 (match_operand:SF 2 "register_operand" "f")))]
6751 [(set_attr "type" "fpmul")])
6753 (define_insn "*muldf3_extend"
6754 [(set (match_operand:DF 0 "register_operand" "=e")
6755 (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "f"))
6756 (float_extend:DF (match_operand:SF 2 "register_operand" "f"))))]
6757 "(TARGET_V8 || TARGET_V9) && TARGET_FPU"
6758 "fsmuld\t%1, %2, %0"
6759 [(set_attr "type" "fpmul")
6760 (set_attr "fptype" "double")])
6762 (define_insn "*multf3_extend"
6763 [(set (match_operand:TF 0 "register_operand" "=e")
6764 (mult:TF (float_extend:TF (match_operand:DF 1 "register_operand" "e"))
6765 (float_extend:TF (match_operand:DF 2 "register_operand" "e"))))]
6766 "(TARGET_V8 || TARGET_V9) && TARGET_FPU && TARGET_HARD_QUAD"
6767 "fdmulq\t%1, %2, %0"
6768 [(set_attr "type" "fpmul")])
6770 (define_expand "divtf3"
6771 [(set (match_operand:TF 0 "nonimmediate_operand" "")
6772 (div:TF (match_operand:TF 1 "general_operand" "")
6773 (match_operand:TF 2 "general_operand" "")))]
6774 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6775 "emit_tfmode_binop (DIV, operands); DONE;")
6777 ;; don't have timing for quad-prec. divide.
6778 (define_insn "*divtf3_hq"
6779 [(set (match_operand:TF 0 "register_operand" "=e")
6780 (div:TF (match_operand:TF 1 "register_operand" "e")
6781 (match_operand:TF 2 "register_operand" "e")))]
6782 "TARGET_FPU && TARGET_HARD_QUAD"
6784 [(set_attr "type" "fpdivd")])
6786 (define_insn "divdf3"
6787 [(set (match_operand:DF 0 "register_operand" "=e")
6788 (div:DF (match_operand:DF 1 "register_operand" "e")
6789 (match_operand:DF 2 "register_operand" "e")))]
6792 [(set_attr "type" "fpdivd")
6793 (set_attr "fptype" "double")])
6795 (define_insn "divsf3"
6796 [(set (match_operand:SF 0 "register_operand" "=f")
6797 (div:SF (match_operand:SF 1 "register_operand" "f")
6798 (match_operand:SF 2 "register_operand" "f")))]
6801 [(set_attr "type" "fpdivs")])
6803 (define_expand "negtf2"
6804 [(set (match_operand:TF 0 "register_operand" "=e,e")
6805 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
6809 (define_insn_and_split "*negtf2_notv9"
6810 [(set (match_operand:TF 0 "register_operand" "=e,e")
6811 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
6812 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
6818 "&& reload_completed
6819 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6820 [(set (match_dup 2) (neg:SF (match_dup 3)))
6821 (set (match_dup 4) (match_dup 5))
6822 (set (match_dup 6) (match_dup 7))]
6823 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6824 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6825 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6826 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
6827 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6828 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6829 [(set_attr "type" "fpmove,*")
6830 (set_attr "length" "*,2")])
6832 (define_insn_and_split "*negtf2_v9"
6833 [(set (match_operand:TF 0 "register_operand" "=e,e")
6834 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
6835 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
6836 "TARGET_FPU && TARGET_V9"
6840 "&& reload_completed
6841 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6842 [(set (match_dup 2) (neg:DF (match_dup 3)))
6843 (set (match_dup 4) (match_dup 5))]
6844 "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
6845 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
6846 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6847 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6848 [(set_attr "type" "fpmove,*")
6849 (set_attr "length" "*,2")
6850 (set_attr "fptype" "double")])
6852 (define_expand "negdf2"
6853 [(set (match_operand:DF 0 "register_operand" "")
6854 (neg:DF (match_operand:DF 1 "register_operand" "")))]
6858 (define_insn_and_split "*negdf2_notv9"
6859 [(set (match_operand:DF 0 "register_operand" "=e,e")
6860 (neg:DF (match_operand:DF 1 "register_operand" "0,e")))]
6861 "TARGET_FPU && ! TARGET_V9"
6865 "&& reload_completed
6866 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6867 [(set (match_dup 2) (neg:SF (match_dup 3)))
6868 (set (match_dup 4) (match_dup 5))]
6869 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6870 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6871 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6872 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);"
6873 [(set_attr "type" "fpmove,*")
6874 (set_attr "length" "*,2")])
6876 (define_insn "*negdf2_v9"
6877 [(set (match_operand:DF 0 "register_operand" "=e")
6878 (neg:DF (match_operand:DF 1 "register_operand" "e")))]
6879 "TARGET_FPU && TARGET_V9"
6881 [(set_attr "type" "fpmove")
6882 (set_attr "fptype" "double")])
6884 (define_insn "negsf2"
6885 [(set (match_operand:SF 0 "register_operand" "=f")
6886 (neg:SF (match_operand:SF 1 "register_operand" "f")))]
6889 [(set_attr "type" "fpmove")])
6891 (define_expand "abstf2"
6892 [(set (match_operand:TF 0 "register_operand" "")
6893 (abs:TF (match_operand:TF 1 "register_operand" "")))]
6897 (define_insn_and_split "*abstf2_notv9"
6898 [(set (match_operand:TF 0 "register_operand" "=e,e")
6899 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6900 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
6901 "TARGET_FPU && ! TARGET_V9"
6905 "&& reload_completed
6906 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6907 [(set (match_dup 2) (abs:SF (match_dup 3)))
6908 (set (match_dup 4) (match_dup 5))
6909 (set (match_dup 6) (match_dup 7))]
6910 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6911 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6912 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6913 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
6914 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6915 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6916 [(set_attr "type" "fpmove,*")
6917 (set_attr "length" "*,2")])
6919 (define_insn "*abstf2_hq_v9"
6920 [(set (match_operand:TF 0 "register_operand" "=e,e")
6921 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6922 "TARGET_FPU && TARGET_V9 && TARGET_HARD_QUAD"
6926 [(set_attr "type" "fpmove")
6927 (set_attr "fptype" "double,*")])
6929 (define_insn_and_split "*abstf2_v9"
6930 [(set (match_operand:TF 0 "register_operand" "=e,e")
6931 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6932 "TARGET_FPU && TARGET_V9 && !TARGET_HARD_QUAD"
6936 "&& reload_completed
6937 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6938 [(set (match_dup 2) (abs:DF (match_dup 3)))
6939 (set (match_dup 4) (match_dup 5))]
6940 "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
6941 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
6942 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6943 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6944 [(set_attr "type" "fpmove,*")
6945 (set_attr "length" "*,2")
6946 (set_attr "fptype" "double,*")])
6948 (define_expand "absdf2"
6949 [(set (match_operand:DF 0 "register_operand" "")
6950 (abs:DF (match_operand:DF 1 "register_operand" "")))]
6954 (define_insn_and_split "*absdf2_notv9"
6955 [(set (match_operand:DF 0 "register_operand" "=e,e")
6956 (abs:DF (match_operand:DF 1 "register_operand" "0,e")))]
6957 "TARGET_FPU && ! TARGET_V9"
6961 "&& reload_completed
6962 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6963 [(set (match_dup 2) (abs:SF (match_dup 3)))
6964 (set (match_dup 4) (match_dup 5))]
6965 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6966 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6967 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6968 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);"
6969 [(set_attr "type" "fpmove,*")
6970 (set_attr "length" "*,2")])
6972 (define_insn "*absdf2_v9"
6973 [(set (match_operand:DF 0 "register_operand" "=e")
6974 (abs:DF (match_operand:DF 1 "register_operand" "e")))]
6975 "TARGET_FPU && TARGET_V9"
6977 [(set_attr "type" "fpmove")
6978 (set_attr "fptype" "double")])
6980 (define_insn "abssf2"
6981 [(set (match_operand:SF 0 "register_operand" "=f")
6982 (abs:SF (match_operand:SF 1 "register_operand" "f")))]
6985 [(set_attr "type" "fpmove")])
6987 (define_expand "sqrttf2"
6988 [(set (match_operand:TF 0 "nonimmediate_operand" "")
6989 (sqrt:TF (match_operand:TF 1 "general_operand" "")))]
6990 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6991 "emit_tfmode_unop (SQRT, operands); DONE;")
6993 (define_insn "*sqrttf2_hq"
6994 [(set (match_operand:TF 0 "register_operand" "=e")
6995 (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
6996 "TARGET_FPU && TARGET_HARD_QUAD"
6998 [(set_attr "type" "fpsqrtd")])
7000 (define_insn "sqrtdf2"
7001 [(set (match_operand:DF 0 "register_operand" "=e")
7002 (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
7005 [(set_attr "type" "fpsqrtd")
7006 (set_attr "fptype" "double")])
7008 (define_insn "sqrtsf2"
7009 [(set (match_operand:SF 0 "register_operand" "=f")
7010 (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
7013 [(set_attr "type" "fpsqrts")])
7015 ;;- arithmetic shift instructions
7017 (define_insn "ashlsi3"
7018 [(set (match_operand:SI 0 "register_operand" "=r")
7019 (ashift:SI (match_operand:SI 1 "register_operand" "r")
7020 (match_operand:SI 2 "arith_operand" "rI")))]
7023 if (GET_CODE (operands[2]) == CONST_INT)
7024 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
7025 return "sll\t%1, %2, %0";
7028 (if_then_else (match_operand 2 "const1_operand" "")
7029 (const_string "ialu") (const_string "shift")))])
7031 (define_expand "ashldi3"
7032 [(set (match_operand:DI 0 "register_operand" "=r")
7033 (ashift:DI (match_operand:DI 1 "register_operand" "r")
7034 (match_operand:SI 2 "arith_operand" "rI")))]
7035 "TARGET_ARCH64 || TARGET_V8PLUS"
7037 if (! TARGET_ARCH64)
7039 if (GET_CODE (operands[2]) == CONST_INT)
7041 emit_insn (gen_ashldi3_v8plus (operands[0], operands[1], operands[2]));
7046 (define_insn "*ashldi3_sp64"
7047 [(set (match_operand:DI 0 "register_operand" "=r")
7048 (ashift:DI (match_operand:DI 1 "register_operand" "r")
7049 (match_operand:SI 2 "arith_operand" "rI")))]
7052 if (GET_CODE (operands[2]) == CONST_INT)
7053 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
7054 return "sllx\t%1, %2, %0";
7057 (if_then_else (match_operand 2 "const1_operand" "")
7058 (const_string "ialu") (const_string "shift")))])
7061 (define_insn "ashldi3_v8plus"
7062 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
7063 (ashift:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
7064 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
7065 (clobber (match_scratch:SI 3 "=X,X,&h"))]
7067 "* return output_v8plus_shift (operands, insn, \"sllx\");"
7068 [(set_attr "type" "multi")
7069 (set_attr "length" "5,5,6")])
7071 ;; Optimize (1LL<<x)-1
7072 ;; XXX this also needs to be fixed to handle equal subregs
7073 ;; XXX first before we could re-enable it.
7075 ; [(set (match_operand:DI 0 "register_operand" "=h")
7076 ; (plus:DI (ashift:DI (const_int 1)
7077 ; (match_operand:SI 1 "arith_operand" "rI"))
7079 ; "0 && TARGET_V8PLUS"
7081 ; if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == REGNO (operands[0]))
7082 ; return "mov\t1, %L0\;sllx\t%L0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
7083 ; return "mov\t1, %H0\;sllx\t%H0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
7085 ; [(set_attr "type" "multi")
7086 ; (set_attr "length" "4")])
7088 (define_insn "*cmp_cc_ashift_1"
7089 [(set (reg:CC_NOOV 100)
7090 (compare:CC_NOOV (ashift:SI (match_operand:SI 0 "register_operand" "r")
7094 "addcc\t%0, %0, %%g0"
7095 [(set_attr "type" "compare")])
7097 (define_insn "*cmp_cc_set_ashift_1"
7098 [(set (reg:CC_NOOV 100)
7099 (compare:CC_NOOV (ashift:SI (match_operand:SI 1 "register_operand" "r")
7102 (set (match_operand:SI 0 "register_operand" "=r")
7103 (ashift:SI (match_dup 1) (const_int 1)))]
7106 [(set_attr "type" "compare")])
7108 (define_insn "ashrsi3"
7109 [(set (match_operand:SI 0 "register_operand" "=r")
7110 (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
7111 (match_operand:SI 2 "arith_operand" "rI")))]
7114 if (GET_CODE (operands[2]) == CONST_INT)
7115 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
7116 return "sra\t%1, %2, %0";
7118 [(set_attr "type" "shift")])
7120 (define_insn "*ashrsi3_extend"
7121 [(set (match_operand:DI 0 "register_operand" "=r")
7122 (sign_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
7123 (match_operand:SI 2 "arith_operand" "r"))))]
7126 [(set_attr "type" "shift")])
7128 ;; This handles the case as above, but with constant shift instead of
7129 ;; register. Combiner "simplifies" it for us a little bit though.
7130 (define_insn "*ashrsi3_extend2"
7131 [(set (match_operand:DI 0 "register_operand" "=r")
7132 (ashiftrt:DI (ashift:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
7134 (match_operand:SI 2 "small_int_or_double" "n")))]
7136 && ((GET_CODE (operands[2]) == CONST_INT
7137 && INTVAL (operands[2]) >= 32 && INTVAL (operands[2]) < 64)
7138 || (GET_CODE (operands[2]) == CONST_DOUBLE
7139 && !CONST_DOUBLE_HIGH (operands[2])
7140 && CONST_DOUBLE_LOW (operands[2]) >= 32
7141 && CONST_DOUBLE_LOW (operands[2]) < 64))"
7143 operands[2] = GEN_INT (INTVAL (operands[2]) - 32);
7145 return "sra\t%1, %2, %0";
7147 [(set_attr "type" "shift")])
7149 (define_expand "ashrdi3"
7150 [(set (match_operand:DI 0 "register_operand" "=r")
7151 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
7152 (match_operand:SI 2 "arith_operand" "rI")))]
7153 "TARGET_ARCH64 || TARGET_V8PLUS"
7155 if (! TARGET_ARCH64)
7157 if (GET_CODE (operands[2]) == CONST_INT)
7158 FAIL; /* prefer generic code in this case */
7159 emit_insn (gen_ashrdi3_v8plus (operands[0], operands[1], operands[2]));
7164 (define_insn "*ashrdi3_sp64"
7165 [(set (match_operand:DI 0 "register_operand" "=r")
7166 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
7167 (match_operand:SI 2 "arith_operand" "rI")))]
7171 if (GET_CODE (operands[2]) == CONST_INT)
7172 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
7173 return "srax\t%1, %2, %0";
7175 [(set_attr "type" "shift")])
7178 (define_insn "ashrdi3_v8plus"
7179 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
7180 (ashiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
7181 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
7182 (clobber (match_scratch:SI 3 "=X,X,&h"))]
7184 "* return output_v8plus_shift (operands, insn, \"srax\");"
7185 [(set_attr "type" "multi")
7186 (set_attr "length" "5,5,6")])
7188 (define_insn "lshrsi3"
7189 [(set (match_operand:SI 0 "register_operand" "=r")
7190 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
7191 (match_operand:SI 2 "arith_operand" "rI")))]
7194 if (GET_CODE (operands[2]) == CONST_INT)
7195 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
7196 return "srl\t%1, %2, %0";
7198 [(set_attr "type" "shift")])
7200 ;; This handles the case where
7201 ;; (zero_extend:DI (lshiftrt:SI (match_operand:SI) (match_operand:SI))),
7202 ;; but combiner "simplifies" it for us.
7203 (define_insn "*lshrsi3_extend"
7204 [(set (match_operand:DI 0 "register_operand" "=r")
7205 (and:DI (subreg:DI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
7206 (match_operand:SI 2 "arith_operand" "r")) 0)
7207 (match_operand 3 "" "")))]
7209 && ((GET_CODE (operands[3]) == CONST_DOUBLE
7210 && CONST_DOUBLE_HIGH (operands[3]) == 0
7211 && CONST_DOUBLE_LOW (operands[3]) == 0xffffffff)
7212 || (HOST_BITS_PER_WIDE_INT >= 64
7213 && GET_CODE (operands[3]) == CONST_INT
7214 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) == 0xffffffff))"
7216 [(set_attr "type" "shift")])
7218 ;; This handles the case where
7219 ;; (lshiftrt:DI (zero_extend:DI (match_operand:SI)) (const_int >=0 < 32))
7220 ;; but combiner "simplifies" it for us.
7221 (define_insn "*lshrsi3_extend2"
7222 [(set (match_operand:DI 0 "register_operand" "=r")
7223 (zero_extract:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
7224 (match_operand 2 "small_int_or_double" "n")
7227 && ((GET_CODE (operands[2]) == CONST_INT
7228 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
7229 || (GET_CODE (operands[2]) == CONST_DOUBLE
7230 && CONST_DOUBLE_HIGH (operands[2]) == 0
7231 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
7233 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
7235 return "srl\t%1, %2, %0";
7237 [(set_attr "type" "shift")])
7239 (define_expand "lshrdi3"
7240 [(set (match_operand:DI 0 "register_operand" "=r")
7241 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
7242 (match_operand:SI 2 "arith_operand" "rI")))]
7243 "TARGET_ARCH64 || TARGET_V8PLUS"
7245 if (! TARGET_ARCH64)
7247 if (GET_CODE (operands[2]) == CONST_INT)
7249 emit_insn (gen_lshrdi3_v8plus (operands[0], operands[1], operands[2]));
7254 (define_insn "*lshrdi3_sp64"
7255 [(set (match_operand:DI 0 "register_operand" "=r")
7256 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
7257 (match_operand:SI 2 "arith_operand" "rI")))]
7260 if (GET_CODE (operands[2]) == CONST_INT)
7261 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
7262 return "srlx\t%1, %2, %0";
7264 [(set_attr "type" "shift")])
7267 (define_insn "lshrdi3_v8plus"
7268 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
7269 (lshiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
7270 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
7271 (clobber (match_scratch:SI 3 "=X,X,&h"))]
7273 "* return output_v8plus_shift (operands, insn, \"srlx\");"
7274 [(set_attr "type" "multi")
7275 (set_attr "length" "5,5,6")])
7278 [(set (match_operand:SI 0 "register_operand" "=r")
7279 (ashiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
7281 (match_operand:SI 2 "small_int_or_double" "n")))]
7283 && ((GET_CODE (operands[2]) == CONST_INT
7284 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
7285 || (GET_CODE (operands[2]) == CONST_DOUBLE
7286 && !CONST_DOUBLE_HIGH (operands[2])
7287 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
7289 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
7291 return "srax\t%1, %2, %0";
7293 [(set_attr "type" "shift")])
7296 [(set (match_operand:SI 0 "register_operand" "=r")
7297 (lshiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
7299 (match_operand:SI 2 "small_int_or_double" "n")))]
7301 && ((GET_CODE (operands[2]) == CONST_INT
7302 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
7303 || (GET_CODE (operands[2]) == CONST_DOUBLE
7304 && !CONST_DOUBLE_HIGH (operands[2])
7305 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
7307 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
7309 return "srlx\t%1, %2, %0";
7311 [(set_attr "type" "shift")])
7314 [(set (match_operand:SI 0 "register_operand" "=r")
7315 (ashiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
7316 (match_operand:SI 2 "small_int_or_double" "n")) 4)
7317 (match_operand:SI 3 "small_int_or_double" "n")))]
7319 && GET_CODE (operands[2]) == CONST_INT && GET_CODE (operands[3]) == CONST_INT
7320 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
7321 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
7322 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
7324 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
7326 return "srax\t%1, %2, %0";
7328 [(set_attr "type" "shift")])
7331 [(set (match_operand:SI 0 "register_operand" "=r")
7332 (lshiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
7333 (match_operand:SI 2 "small_int_or_double" "n")) 4)
7334 (match_operand:SI 3 "small_int_or_double" "n")))]
7336 && GET_CODE (operands[2]) == CONST_INT && GET_CODE (operands[3]) == CONST_INT
7337 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
7338 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
7339 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
7341 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
7343 return "srlx\t%1, %2, %0";
7345 [(set_attr "type" "shift")])
7347 ;; Unconditional and other jump instructions
7349 [(set (pc) (label_ref (match_operand 0 "" "")))]
7351 "* return output_ubranch (operands[0], 0, insn);"
7352 [(set_attr "type" "uncond_branch")])
7354 (define_expand "tablejump"
7355 [(parallel [(set (pc) (match_operand 0 "register_operand" "r"))
7356 (use (label_ref (match_operand 1 "" "")))])]
7359 if (GET_MODE (operands[0]) != CASE_VECTOR_MODE)
7362 /* In pic mode, our address differences are against the base of the
7363 table. Add that base value back in; CSE ought to be able to combine
7364 the two address loads. */
7368 tmp = gen_rtx_LABEL_REF (Pmode, operands[1]);
7370 if (CASE_VECTOR_MODE != Pmode)
7371 tmp2 = gen_rtx_SIGN_EXTEND (Pmode, tmp2);
7372 tmp = gen_rtx_PLUS (Pmode, tmp2, tmp);
7373 operands[0] = memory_address (Pmode, tmp);
7377 (define_insn "*tablejump_sp32"
7378 [(set (pc) (match_operand:SI 0 "address_operand" "p"))
7379 (use (label_ref (match_operand 1 "" "")))]
7382 [(set_attr "type" "uncond_branch")])
7384 (define_insn "*tablejump_sp64"
7385 [(set (pc) (match_operand:DI 0 "address_operand" "p"))
7386 (use (label_ref (match_operand 1 "" "")))]
7389 [(set_attr "type" "uncond_branch")])
7391 ;;- jump to subroutine
7392 (define_expand "call"
7393 ;; Note that this expression is not used for generating RTL.
7394 ;; All the RTL is generated explicitly below.
7395 [(call (match_operand 0 "call_operand" "")
7396 (match_operand 3 "" "i"))]
7397 ;; operands[2] is next_arg_register
7398 ;; operands[3] is struct_value_size_rtx.
7403 if (GET_MODE (operands[0]) != FUNCTION_MODE)
7406 if (GET_CODE (operands[3]) != CONST_INT)
7409 if (GET_CODE (XEXP (operands[0], 0)) == LABEL_REF)
7411 /* This is really a PIC sequence. We want to represent
7412 it as a funny jump so its delay slots can be filled.
7414 ??? But if this really *is* a CALL, will not it clobber the
7415 call-clobbered registers? We lose this if it is a JUMP_INSN.
7416 Why cannot we have delay slots filled if it were a CALL? */
7418 /* We accept negative sizes for untyped calls. */
7419 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
7424 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
7426 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
7432 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
7433 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
7437 fn_rtx = operands[0];
7439 /* We accept negative sizes for untyped calls. */
7440 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
7444 gen_rtvec (3, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx),
7446 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
7451 gen_rtvec (2, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx),
7452 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
7459 ;; We can't use the same pattern for these two insns, because then registers
7460 ;; in the address may not be properly reloaded.
7462 (define_insn "*call_address_sp32"
7463 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
7464 (match_operand 1 "" ""))
7465 (clobber (reg:SI 15))]
7466 ;;- Do not use operand 1 for most machines.
7469 [(set_attr "type" "call")])
7471 (define_insn "*call_symbolic_sp32"
7472 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
7473 (match_operand 1 "" ""))
7474 (clobber (reg:SI 15))]
7475 ;;- Do not use operand 1 for most machines.
7478 [(set_attr "type" "call")])
7480 (define_insn "*call_address_sp64"
7481 [(call (mem:DI (match_operand:DI 0 "address_operand" "p"))
7482 (match_operand 1 "" ""))
7483 (clobber (reg:DI 15))]
7484 ;;- Do not use operand 1 for most machines.
7487 [(set_attr "type" "call")])
7489 (define_insn "*call_symbolic_sp64"
7490 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
7491 (match_operand 1 "" ""))
7492 (clobber (reg:DI 15))]
7493 ;;- Do not use operand 1 for most machines.
7496 [(set_attr "type" "call")])
7498 ;; This is a call that wants a structure value.
7499 ;; There is no such critter for v9 (??? we may need one anyway).
7500 (define_insn "*call_address_struct_value_sp32"
7501 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
7502 (match_operand 1 "" ""))
7503 (match_operand 2 "immediate_operand" "")
7504 (clobber (reg:SI 15))]
7505 ;;- Do not use operand 1 for most machines.
7506 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
7508 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xfff);
7509 return "call\t%a0, %1\n\t nop\n\tunimp\t%2";
7511 [(set_attr "type" "call_no_delay_slot")
7512 (set_attr "length" "3")])
7514 ;; This is a call that wants a structure value.
7515 ;; There is no such critter for v9 (??? we may need one anyway).
7516 (define_insn "*call_symbolic_struct_value_sp32"
7517 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
7518 (match_operand 1 "" ""))
7519 (match_operand 2 "immediate_operand" "")
7520 (clobber (reg:SI 15))]
7521 ;;- Do not use operand 1 for most machines.
7522 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
7524 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xfff);
7525 return "call\t%a0, %1\n\t nop\n\tunimp\t%2";
7527 [(set_attr "type" "call_no_delay_slot")
7528 (set_attr "length" "3")])
7530 ;; This is a call that may want a structure value. This is used for
7532 (define_insn "*call_address_untyped_struct_value_sp32"
7533 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
7534 (match_operand 1 "" ""))
7535 (match_operand 2 "immediate_operand" "")
7536 (clobber (reg:SI 15))]
7537 ;;- Do not use operand 1 for most machines.
7538 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
7539 "call\t%a0, %1\n\t nop\n\tnop"
7540 [(set_attr "type" "call_no_delay_slot")
7541 (set_attr "length" "3")])
7543 ;; This is a call that may want a structure value. This is used for
7545 (define_insn "*call_symbolic_untyped_struct_value_sp32"
7546 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
7547 (match_operand 1 "" ""))
7548 (match_operand 2 "immediate_operand" "")
7549 (clobber (reg:SI 15))]
7550 ;;- Do not use operand 1 for most machines.
7551 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
7552 "call\t%a0, %1\n\t nop\n\tnop"
7553 [(set_attr "type" "call_no_delay_slot")
7554 (set_attr "length" "3")])
7556 (define_expand "call_value"
7557 ;; Note that this expression is not used for generating RTL.
7558 ;; All the RTL is generated explicitly below.
7559 [(set (match_operand 0 "register_operand" "=rf")
7560 (call (match_operand 1 "" "")
7561 (match_operand 4 "" "")))]
7562 ;; operand 2 is stack_size_rtx
7563 ;; operand 3 is next_arg_register
7569 if (GET_MODE (operands[1]) != FUNCTION_MODE)
7572 fn_rtx = operands[1];
7575 gen_rtx_SET (VOIDmode, operands[0],
7576 gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx)),
7577 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)));
7579 emit_call_insn (gen_rtx_PARALLEL (VOIDmode, vec));
7584 (define_insn "*call_value_address_sp32"
7585 [(set (match_operand 0 "" "=rf")
7586 (call (mem:SI (match_operand:SI 1 "address_operand" "p"))
7587 (match_operand 2 "" "")))
7588 (clobber (reg:SI 15))]
7589 ;;- Do not use operand 2 for most machines.
7592 [(set_attr "type" "call")])
7594 (define_insn "*call_value_symbolic_sp32"
7595 [(set (match_operand 0 "" "=rf")
7596 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
7597 (match_operand 2 "" "")))
7598 (clobber (reg:SI 15))]
7599 ;;- Do not use operand 2 for most machines.
7602 [(set_attr "type" "call")])
7604 (define_insn "*call_value_address_sp64"
7605 [(set (match_operand 0 "" "")
7606 (call (mem:DI (match_operand:DI 1 "address_operand" "p"))
7607 (match_operand 2 "" "")))
7608 (clobber (reg:DI 15))]
7609 ;;- Do not use operand 2 for most machines.
7612 [(set_attr "type" "call")])
7614 (define_insn "*call_value_symbolic_sp64"
7615 [(set (match_operand 0 "" "")
7616 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
7617 (match_operand 2 "" "")))
7618 (clobber (reg:DI 15))]
7619 ;;- Do not use operand 2 for most machines.
7622 [(set_attr "type" "call")])
7624 (define_expand "untyped_call"
7625 [(parallel [(call (match_operand 0 "" "")
7627 (match_operand 1 "" "")
7628 (match_operand 2 "" "")])]
7633 /* Pass constm1 to indicate that it may expect a structure value, but
7634 we don't know what size it is. */
7635 emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, constm1_rtx));
7637 for (i = 0; i < XVECLEN (operands[2], 0); i++)
7639 rtx set = XVECEXP (operands[2], 0, i);
7640 emit_move_insn (SET_DEST (set), SET_SRC (set));
7643 /* The optimizer does not know that the call sets the function value
7644 registers we stored in the result block. We avoid problems by
7645 claiming that all hard registers are used and clobbered at this
7647 emit_insn (gen_blockage ());
7653 (define_expand "sibcall"
7654 [(parallel [(call (match_operand 0 "call_operand" "") (const_int 0))
7659 (define_insn "*sibcall_symbolic_sp32"
7660 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
7661 (match_operand 1 "" ""))
7664 "* return output_sibcall(insn, operands[0]);"
7665 [(set_attr "type" "sibcall")])
7667 (define_insn "*sibcall_symbolic_sp64"
7668 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
7669 (match_operand 1 "" ""))
7672 "* return output_sibcall(insn, operands[0]);"
7673 [(set_attr "type" "sibcall")])
7675 (define_expand "sibcall_value"
7676 [(parallel [(set (match_operand 0 "register_operand" "=rf")
7677 (call (match_operand 1 "" "") (const_int 0)))
7682 (define_insn "*sibcall_value_symbolic_sp32"
7683 [(set (match_operand 0 "" "=rf")
7684 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
7685 (match_operand 2 "" "")))
7688 "* return output_sibcall(insn, operands[1]);"
7689 [(set_attr "type" "sibcall")])
7691 (define_insn "*sibcall_value_symbolic_sp64"
7692 [(set (match_operand 0 "" "")
7693 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
7694 (match_operand 2 "" "")))
7697 "* return output_sibcall(insn, operands[1]);"
7698 [(set_attr "type" "sibcall")])
7700 (define_expand "sibcall_epilogue"
7704 sparc_expand_epilogue ();
7708 (define_expand "prologue"
7712 sparc_expand_prologue ();
7716 ;; The "save register window" insn is modelled as follows so that the DWARF-2
7717 ;; backend automatically emits the required call frame debugging information
7718 ;; while it is parsing it. Therefore, the pattern should not be modified
7719 ;; without first studying the impact of the changes on the debug info.
7720 ;; [(set (%fp) (%sp))
7721 ;; (set (%sp) (unspec_volatile [(%sp) (-frame_size)] UNSPECV_SAVEW))
7722 ;; (set (%i7) (%o7))]
7724 (define_insn "save_register_windowdi"
7725 [(set (reg:DI 30) (reg:DI 14))
7726 (set (reg:DI 14) (unspec_volatile:DI [(reg:DI 14)
7727 (match_operand:DI 0 "arith_operand" "rI")]
7729 (set (reg:DI 31) (reg:DI 15))]
7731 "save\t%%sp, %0, %%sp"
7732 [(set_attr "type" "savew")])
7734 (define_insn "save_register_windowsi"
7735 [(set (reg:SI 30) (reg:SI 14))
7736 (set (reg:SI 14) (unspec_volatile:SI [(reg:SI 14)
7737 (match_operand:SI 0 "arith_operand" "rI")]
7739 (set (reg:SI 31) (reg:SI 15))]
7741 "save\t%%sp, %0, %%sp"
7742 [(set_attr "type" "savew")])
7744 (define_expand "epilogue"
7748 sparc_expand_epilogue ();
7751 (define_expand "return"
7753 "sparc_can_use_return_insn_p ()"
7756 (define_insn "*return_internal"
7759 "* return output_return (insn);"
7760 [(set_attr "type" "return")
7761 (set (attr "length")
7762 (cond [(eq_attr "leaf_function" "true")
7763 (if_then_else (eq_attr "empty_delay_slot" "true")
7766 (eq_attr "calls_eh_return" "true")
7767 (if_then_else (eq_attr "delayed_branch" "true")
7768 (if_then_else (eq_attr "isa" "v9")
7771 (if_then_else (eq_attr "isa" "v9")
7774 (eq_attr "empty_delay_slot" "true")
7775 (if_then_else (eq_attr "delayed_branch" "true")
7780 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
7781 ;; all of memory. This blocks insns from being moved across this point.
7783 (define_insn "blockage"
7784 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
7787 [(set_attr "length" "0")])
7789 ;; Prepare to return any type including a structure value.
7791 (define_expand "untyped_return"
7792 [(match_operand:BLK 0 "memory_operand" "")
7793 (match_operand 1 "" "")]
7796 rtx valreg1 = gen_rtx_REG (DImode, 24);
7797 rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
7798 rtx result = operands[0];
7800 if (! TARGET_ARCH64)
7802 rtx rtnreg = gen_rtx_REG (SImode, (current_function_uses_only_leaf_regs
7804 rtx value = gen_reg_rtx (SImode);
7806 /* Fetch the instruction where we will return to and see if it's an unimp
7807 instruction (the most significant 10 bits will be zero). If so,
7808 update the return address to skip the unimp instruction. */
7809 emit_move_insn (value,
7810 gen_rtx_MEM (SImode, plus_constant (rtnreg, 8)));
7811 emit_insn (gen_lshrsi3 (value, value, GEN_INT (22)));
7812 emit_insn (gen_update_return (rtnreg, value));
7815 /* Reload the function value registers. */
7816 emit_move_insn (valreg1, adjust_address (result, DImode, 0));
7817 emit_move_insn (valreg2,
7818 adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8));
7820 /* Put USE insns before the return. */
7821 emit_insn (gen_rtx_USE (VOIDmode, valreg1));
7822 emit_insn (gen_rtx_USE (VOIDmode, valreg2));
7824 /* Construct the return. */
7825 expand_naked_return ();
7830 ;; This is a bit of a hack. We're incrementing a fixed register (%i7),
7831 ;; and parts of the compiler don't want to believe that the add is needed.
7833 (define_insn "update_return"
7834 [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
7835 (match_operand:SI 1 "register_operand" "r")] UNSPEC_UPDATE_RETURN)]
7838 if (flag_delayed_branch)
7839 return "cmp\t%1, 0\n\tbe,a\t.+8\n\t add\t%0, 4, %0";
7841 return "cmp\t%1, 0\n\tbne\t.+12\n\t nop\n\tadd\t%0, 4, %0";
7843 [(set (attr "type") (const_string "multi"))
7844 (set (attr "length")
7845 (if_then_else (eq_attr "delayed_branch" "true")
7854 (define_expand "indirect_jump"
7855 [(set (pc) (match_operand 0 "address_operand" "p"))]
7859 (define_insn "*branch_sp32"
7860 [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
7863 [(set_attr "type" "uncond_branch")])
7865 (define_insn "*branch_sp64"
7866 [(set (pc) (match_operand:DI 0 "address_operand" "p"))]
7869 [(set_attr "type" "uncond_branch")])
7871 (define_expand "nonlocal_goto"
7872 [(match_operand:SI 0 "general_operand" "")
7873 (match_operand:SI 1 "general_operand" "")
7874 (match_operand:SI 2 "general_operand" "")
7875 (match_operand:SI 3 "" "")]
7878 rtx lab = operands[1];
7879 rtx stack = operands[2];
7880 rtx fp = operands[3];
7883 /* Trap instruction to flush all the register windows. */
7884 emit_insn (gen_flush_register_windows ());
7886 /* Load the fp value for the containing fn into %fp. This is needed
7887 because STACK refers to %fp. Note that virtual register instantiation
7888 fails if the virtual %fp isn't set from a register. */
7889 if (GET_CODE (fp) != REG)
7890 fp = force_reg (Pmode, fp);
7891 emit_move_insn (virtual_stack_vars_rtx, fp);
7893 /* Find the containing function's current nonlocal goto handler,
7894 which will do any cleanups and then jump to the label. */
7895 labreg = gen_rtx_REG (Pmode, 8);
7896 emit_move_insn (labreg, lab);
7898 /* Restore %fp from stack pointer value for containing function.
7899 The restore insn that follows will move this to %sp,
7900 and reload the appropriate value into %fp. */
7901 emit_move_insn (hard_frame_pointer_rtx, stack);
7903 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
7904 emit_insn (gen_rtx_USE (VOIDmode, static_chain_rtx));
7906 /* ??? The V9-specific version was disabled in rev 1.65. */
7907 emit_jump_insn (gen_goto_handler_and_restore (labreg));
7912 ;; Special trap insn to flush register windows.
7913 (define_insn "flush_register_windows"
7914 [(unspec_volatile [(const_int 0)] UNSPECV_FLUSHW)]
7916 { return TARGET_V9 ? "flushw" : "ta\t3"; }
7917 [(set_attr "type" "flushw")])
7919 (define_insn "goto_handler_and_restore"
7920 [(unspec_volatile [(match_operand 0 "register_operand" "=r")] UNSPECV_GOTO)]
7921 "GET_MODE (operands[0]) == Pmode"
7923 if (flag_delayed_branch)
7924 return "jmp\t%0\n\t restore";
7926 return "mov\t%0,%%g1\n\trestore\n\tjmp\t%%g1\n\t nop";
7928 [(set (attr "type") (const_string "multi"))
7929 (set (attr "length")
7930 (if_then_else (eq_attr "delayed_branch" "true")
7934 ;; For __builtin_setjmp we need to flush register windows iff the function
7935 ;; calls alloca as well, because otherwise the register window might be
7936 ;; saved after %sp adjustment and thus setjmp would crash
7937 (define_expand "builtin_setjmp_setup"
7938 [(match_operand 0 "register_operand" "r")]
7941 emit_insn (gen_do_builtin_setjmp_setup ());
7945 (define_insn "do_builtin_setjmp_setup"
7946 [(unspec_volatile [(const_int 0)] UNSPECV_SETJMP)]
7949 if (! current_function_calls_alloca)
7953 fputs ("\tflushw\n", asm_out_file);
7955 fprintf (asm_out_file, "\tst%c\t%%l7, [%%sp+%d]\n",
7956 TARGET_ARCH64 ? 'x' : 'w',
7957 SPARC_STACK_BIAS + 7 * UNITS_PER_WORD);
7958 fprintf (asm_out_file, "\tst%c\t%%fp, [%%sp+%d]\n",
7959 TARGET_ARCH64 ? 'x' : 'w',
7960 SPARC_STACK_BIAS + 14 * UNITS_PER_WORD);
7961 fprintf (asm_out_file, "\tst%c\t%%i7, [%%sp+%d]\n",
7962 TARGET_ARCH64 ? 'x' : 'w',
7963 SPARC_STACK_BIAS + 15 * UNITS_PER_WORD);
7966 [(set_attr "type" "multi")
7967 (set (attr "length")
7968 (cond [(eq_attr "calls_alloca" "false")
7970 (eq_attr "isa" "!v9")
7972 (eq_attr "pic" "true")
7973 (const_int 4)] (const_int 3)))])
7975 ;; Pattern for use after a setjmp to store FP and the return register
7976 ;; into the stack area.
7978 (define_expand "setjmp"
7983 emit_insn (gen_setjmp_64 ());
7985 emit_insn (gen_setjmp_32 ());
7989 (define_expand "setjmp_32"
7990 [(set (mem:SI (plus:SI (reg:SI 14) (const_int 56))) (match_dup 0))
7991 (set (mem:SI (plus:SI (reg:SI 14) (const_int 60))) (reg:SI 31))]
7993 { operands[0] = frame_pointer_rtx; })
7995 (define_expand "setjmp_64"
7996 [(set (mem:DI (plus:DI (reg:DI 14) (const_int 112))) (match_dup 0))
7997 (set (mem:DI (plus:DI (reg:DI 14) (const_int 120))) (reg:DI 31))]
7999 { operands[0] = frame_pointer_rtx; })
8001 ;; Special pattern for the FLUSH instruction.
8003 ; We do SImode and DImode versions of this to quiet down genrecog's complaints
8004 ; of the define_insn otherwise missing a mode. We make "flush", aka
8005 ; gen_flush, the default one since sparc_initialize_trampoline uses
8006 ; it on SImode mem values.
8008 (define_insn "flush"
8009 [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")] UNSPECV_FLUSH)]
8011 { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; }
8012 [(set_attr "type" "iflush")])
8014 (define_insn "flushdi"
8015 [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")] UNSPECV_FLUSH)]
8017 { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; }
8018 [(set_attr "type" "iflush")])
8023 ;; The scan instruction searches from the most significant bit while ffs
8024 ;; searches from the least significant bit. The bit index and treatment of
8025 ;; zero also differ. It takes at least 7 instructions to get the proper
8026 ;; result. Here is an obvious 8 instruction sequence.
8029 (define_insn "ffssi2"
8030 [(set (match_operand:SI 0 "register_operand" "=&r")
8031 (ffs:SI (match_operand:SI 1 "register_operand" "r")))
8032 (clobber (match_scratch:SI 2 "=&r"))]
8033 "TARGET_SPARCLITE || TARGET_SPARCLET"
8035 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";
8037 [(set_attr "type" "multi")
8038 (set_attr "length" "8")])
8040 ;; ??? This should be a define expand, so that the extra instruction have
8041 ;; a chance of being optimized away.
8043 ;; Disabled because none of the UltraSPARCs implement popc. The HAL R1
8044 ;; does, but no one uses that and we don't have a switch for it.
8046 ;(define_insn "ffsdi2"
8047 ; [(set (match_operand:DI 0 "register_operand" "=&r")
8048 ; (ffs:DI (match_operand:DI 1 "register_operand" "r")))
8049 ; (clobber (match_scratch:DI 2 "=&r"))]
8051 ; "neg\t%1, %2\;xnor\t%1, %2, %2\;popc\t%2, %0\;movzr\t%1, 0, %0"
8052 ; [(set_attr "type" "multi")
8053 ; (set_attr "length" "4")])
8057 ;; Peepholes go at the end.
8059 ;; Optimize consecutive loads or stores into ldd and std when possible.
8060 ;; The conditions in which we do this are very restricted and are
8061 ;; explained in the code for {registers,memory}_ok_for_ldd functions.
8064 [(set (match_operand:SI 0 "memory_operand" "")
8066 (set (match_operand:SI 1 "memory_operand" "")
8069 && mems_ok_for_ldd_peep (operands[0], operands[1], NULL_RTX)"
8072 "operands[0] = widen_memory_access (operands[0], DImode, 0);")
8075 [(set (match_operand:SI 0 "memory_operand" "")
8077 (set (match_operand:SI 1 "memory_operand" "")
8080 && mems_ok_for_ldd_peep (operands[1], operands[0], NULL_RTX)"
8083 "operands[1] = widen_memory_access (operands[1], DImode, 0);")
8086 [(set (match_operand:SI 0 "register_operand" "")
8087 (match_operand:SI 1 "memory_operand" ""))
8088 (set (match_operand:SI 2 "register_operand" "")
8089 (match_operand:SI 3 "memory_operand" ""))]
8090 "registers_ok_for_ldd_peep (operands[0], operands[2])
8091 && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
8094 "operands[1] = widen_memory_access (operands[1], DImode, 0);
8095 operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));")
8098 [(set (match_operand:SI 0 "memory_operand" "")
8099 (match_operand:SI 1 "register_operand" ""))
8100 (set (match_operand:SI 2 "memory_operand" "")
8101 (match_operand:SI 3 "register_operand" ""))]
8102 "registers_ok_for_ldd_peep (operands[1], operands[3])
8103 && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
8106 "operands[0] = widen_memory_access (operands[0], DImode, 0);
8107 operands[1] = gen_rtx_REG (DImode, REGNO (operands[1]));")
8110 [(set (match_operand:SF 0 "register_operand" "")
8111 (match_operand:SF 1 "memory_operand" ""))
8112 (set (match_operand:SF 2 "register_operand" "")
8113 (match_operand:SF 3 "memory_operand" ""))]
8114 "registers_ok_for_ldd_peep (operands[0], operands[2])
8115 && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
8118 "operands[1] = widen_memory_access (operands[1], DFmode, 0);
8119 operands[0] = gen_rtx_REG (DFmode, REGNO (operands[0]));")
8122 [(set (match_operand:SF 0 "memory_operand" "")
8123 (match_operand:SF 1 "register_operand" ""))
8124 (set (match_operand:SF 2 "memory_operand" "")
8125 (match_operand:SF 3 "register_operand" ""))]
8126 "registers_ok_for_ldd_peep (operands[1], operands[3])
8127 && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
8130 "operands[0] = widen_memory_access (operands[0], DFmode, 0);
8131 operands[1] = gen_rtx_REG (DFmode, REGNO (operands[1]));")
8134 [(set (match_operand:SI 0 "register_operand" "")
8135 (match_operand:SI 1 "memory_operand" ""))
8136 (set (match_operand:SI 2 "register_operand" "")
8137 (match_operand:SI 3 "memory_operand" ""))]
8138 "registers_ok_for_ldd_peep (operands[2], operands[0])
8139 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
8142 "operands[3] = widen_memory_access (operands[3], DImode, 0);
8143 operands[2] = gen_rtx_REG (DImode, REGNO (operands[2]));")
8146 [(set (match_operand:SI 0 "memory_operand" "")
8147 (match_operand:SI 1 "register_operand" ""))
8148 (set (match_operand:SI 2 "memory_operand" "")
8149 (match_operand:SI 3 "register_operand" ""))]
8150 "registers_ok_for_ldd_peep (operands[3], operands[1])
8151 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
8154 "operands[2] = widen_memory_access (operands[2], DImode, 0);
8155 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
8159 [(set (match_operand:SF 0 "register_operand" "")
8160 (match_operand:SF 1 "memory_operand" ""))
8161 (set (match_operand:SF 2 "register_operand" "")
8162 (match_operand:SF 3 "memory_operand" ""))]
8163 "registers_ok_for_ldd_peep (operands[2], operands[0])
8164 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
8167 "operands[3] = widen_memory_access (operands[3], DFmode, 0);
8168 operands[2] = gen_rtx_REG (DFmode, REGNO (operands[2]));")
8171 [(set (match_operand:SF 0 "memory_operand" "")
8172 (match_operand:SF 1 "register_operand" ""))
8173 (set (match_operand:SF 2 "memory_operand" "")
8174 (match_operand:SF 3 "register_operand" ""))]
8175 "registers_ok_for_ldd_peep (operands[3], operands[1])
8176 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
8179 "operands[2] = widen_memory_access (operands[2], DFmode, 0);
8180 operands[3] = gen_rtx_REG (DFmode, REGNO (operands[3]));")
8182 ;; Optimize the case of following a reg-reg move with a test
8183 ;; of reg just moved. Don't allow floating point regs for operand 0 or 1.
8184 ;; This can result from a float to fix conversion.
8187 [(set (match_operand:SI 0 "register_operand" "")
8188 (match_operand:SI 1 "register_operand" ""))
8190 (compare:CC (match_operand:SI 2 "register_operand" "")
8192 "(rtx_equal_p (operands[2], operands[0])
8193 || rtx_equal_p (operands[2], operands[1]))
8194 && ! SPARC_FP_REG_P (REGNO (operands[0]))
8195 && ! SPARC_FP_REG_P (REGNO (operands[1]))"
8196 [(parallel [(set (match_dup 0) (match_dup 1))
8198 (compare:CC (match_dup 1) (const_int 0)))])]
8202 [(set (match_operand:DI 0 "register_operand" "")
8203 (match_operand:DI 1 "register_operand" ""))
8205 (compare:CCX (match_operand:DI 2 "register_operand" "")
8208 && (rtx_equal_p (operands[2], operands[0])
8209 || rtx_equal_p (operands[2], operands[1]))
8210 && ! SPARC_FP_REG_P (REGNO (operands[0]))
8211 && ! SPARC_FP_REG_P (REGNO (operands[1]))"
8212 [(parallel [(set (match_dup 0) (match_dup 1))
8214 (compare:CCX (match_dup 1) (const_int 0)))])]
8217 ;; ??? UltraSPARC-III note: A memory operation loading into the floating point register
8218 ;; ??? file, if it hits the prefetch cache, has a chance to dual-issue with other memory
8219 ;; ??? operations. With DFA we might be able to model this, but it requires a lot of
8221 (define_expand "prefetch"
8222 [(match_operand 0 "address_operand" "")
8223 (match_operand 1 "const_int_operand" "")
8224 (match_operand 2 "const_int_operand" "")]
8228 emit_insn (gen_prefetch_64 (operands[0], operands[1], operands[2]));
8230 emit_insn (gen_prefetch_32 (operands[0], operands[1], operands[2]));
8234 (define_insn "prefetch_64"
8235 [(prefetch (match_operand:DI 0 "address_operand" "p")
8236 (match_operand:DI 1 "const_int_operand" "n")
8237 (match_operand:DI 2 "const_int_operand" "n"))]
8240 static const char * const prefetch_instr[2][2] = {
8242 "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
8243 "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
8246 "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
8247 "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
8250 int read_or_write = INTVAL (operands[1]);
8251 int locality = INTVAL (operands[2]);
8253 if (read_or_write != 0 && read_or_write != 1)
8255 if (locality < 0 || locality > 3)
8257 return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
8259 [(set_attr "type" "load")])
8261 (define_insn "prefetch_32"
8262 [(prefetch (match_operand:SI 0 "address_operand" "p")
8263 (match_operand:SI 1 "const_int_operand" "n")
8264 (match_operand:SI 2 "const_int_operand" "n"))]
8267 static const char * const prefetch_instr[2][2] = {
8269 "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
8270 "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
8273 "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
8274 "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
8277 int read_or_write = INTVAL (operands[1]);
8278 int locality = INTVAL (operands[2]);
8280 if (read_or_write != 0 && read_or_write != 1)
8282 if (locality < 0 || locality > 3)
8284 return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
8286 [(set_attr "type" "load")])
8289 [(trap_if (const_int 1) (const_int 5))]
8292 [(set_attr "type" "trap")])
8294 (define_expand "conditional_trap"
8295 [(trap_if (match_operator 0 "noov_compare_op" [(match_dup 2) (match_dup 3)])
8296 (match_operand:SI 1 "arith_operand" ""))]
8298 "operands[2] = gen_compare_reg (GET_CODE (operands[0]),
8299 sparc_compare_op0, sparc_compare_op1);
8300 if (GET_MODE (operands[2]) != CCmode && GET_MODE (operands[2]) != CCXmode)
8302 operands[3] = const0_rtx;")
8305 [(trap_if (match_operator 0 "noov_compare_op" [(reg:CC 100) (const_int 0)])
8306 (match_operand:SI 1 "arith_operand" "rM"))]
8310 return "t%C0\t%%icc, %1";
8314 [(set_attr "type" "trap")])
8317 [(trap_if (match_operator 0 "noov_compare_op" [(reg:CCX 100) (const_int 0)])
8318 (match_operand:SI 1 "arith_operand" "rM"))]
8321 [(set_attr "type" "trap")])
8324 (define_insn "tgd_hi22"
8325 [(set (match_operand:SI 0 "register_operand" "=r")
8326 (high:SI (unspec:SI [(match_operand 1 "tgd_symbolic_operand" "")]
8329 "sethi\\t%%tgd_hi22(%a1), %0")
8331 (define_insn "tgd_lo10"
8332 [(set (match_operand:SI 0 "register_operand" "=r")
8333 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
8334 (unspec:SI [(match_operand 2 "tgd_symbolic_operand" "")]
8337 "add\\t%1, %%tgd_lo10(%a2), %0")
8339 (define_insn "tgd_add32"
8340 [(set (match_operand:SI 0 "register_operand" "=r")
8341 (plus:SI (match_operand:SI 1 "register_operand" "r")
8342 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8343 (match_operand 3 "tgd_symbolic_operand" "")]
8345 "TARGET_TLS && TARGET_ARCH32"
8346 "add\\t%1, %2, %0, %%tgd_add(%a3)")
8348 (define_insn "tgd_add64"
8349 [(set (match_operand:DI 0 "register_operand" "=r")
8350 (plus:DI (match_operand:DI 1 "register_operand" "r")
8351 (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8352 (match_operand 3 "tgd_symbolic_operand" "")]
8354 "TARGET_TLS && TARGET_ARCH64"
8355 "add\\t%1, %2, %0, %%tgd_add(%a3)")
8357 (define_insn "tgd_call32"
8358 [(set (match_operand 0 "register_operand" "=r")
8359 (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")
8360 (match_operand 2 "tgd_symbolic_operand" "")]
8362 (match_operand 3 "" "")))
8363 (clobber (reg:SI 15))]
8364 "TARGET_TLS && TARGET_ARCH32"
8365 "call\t%a1, %%tgd_call(%a2)%#"
8366 [(set_attr "type" "call")])
8368 (define_insn "tgd_call64"
8369 [(set (match_operand 0 "register_operand" "=r")
8370 (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")
8371 (match_operand 2 "tgd_symbolic_operand" "")]
8373 (match_operand 3 "" "")))
8374 (clobber (reg:DI 15))]
8375 "TARGET_TLS && TARGET_ARCH64"
8376 "call\t%a1, %%tgd_call(%a2)%#"
8377 [(set_attr "type" "call")])
8379 (define_insn "tldm_hi22"
8380 [(set (match_operand:SI 0 "register_operand" "=r")
8381 (high:SI (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
8383 "sethi\\t%%tldm_hi22(%&), %0")
8385 (define_insn "tldm_lo10"
8386 [(set (match_operand:SI 0 "register_operand" "=r")
8387 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
8388 (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
8390 "add\\t%1, %%tldm_lo10(%&), %0")
8392 (define_insn "tldm_add32"
8393 [(set (match_operand:SI 0 "register_operand" "=r")
8394 (plus:SI (match_operand:SI 1 "register_operand" "r")
8395 (unspec:SI [(match_operand:SI 2 "register_operand" "r")]
8397 "TARGET_TLS && TARGET_ARCH32"
8398 "add\\t%1, %2, %0, %%tldm_add(%&)")
8400 (define_insn "tldm_add64"
8401 [(set (match_operand:DI 0 "register_operand" "=r")
8402 (plus:DI (match_operand:DI 1 "register_operand" "r")
8403 (unspec:DI [(match_operand:SI 2 "register_operand" "r")]
8405 "TARGET_TLS && TARGET_ARCH64"
8406 "add\\t%1, %2, %0, %%tldm_add(%&)")
8408 (define_insn "tldm_call32"
8409 [(set (match_operand 0 "register_operand" "=r")
8410 (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")]
8412 (match_operand 2 "" "")))
8413 (clobber (reg:SI 15))]
8414 "TARGET_TLS && TARGET_ARCH32"
8415 "call\t%a1, %%tldm_call(%&)%#"
8416 [(set_attr "type" "call")])
8418 (define_insn "tldm_call64"
8419 [(set (match_operand 0 "register_operand" "=r")
8420 (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")]
8422 (match_operand 2 "" "")))
8423 (clobber (reg:DI 15))]
8424 "TARGET_TLS && TARGET_ARCH64"
8425 "call\t%a1, %%tldm_call(%&)%#"
8426 [(set_attr "type" "call")])
8428 (define_insn "tldo_hix22"
8429 [(set (match_operand:SI 0 "register_operand" "=r")
8430 (high:SI (unspec:SI [(match_operand 1 "tld_symbolic_operand" "")]
8433 "sethi\\t%%tldo_hix22(%a1), %0")
8435 (define_insn "tldo_lox10"
8436 [(set (match_operand:SI 0 "register_operand" "=r")
8437 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
8438 (unspec:SI [(match_operand 2 "tld_symbolic_operand" "")]
8441 "xor\\t%1, %%tldo_lox10(%a2), %0")
8443 (define_insn "tldo_add32"
8444 [(set (match_operand:SI 0 "register_operand" "=r")
8445 (plus:SI (match_operand:SI 1 "register_operand" "r")
8446 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8447 (match_operand 3 "tld_symbolic_operand" "")]
8449 "TARGET_TLS && TARGET_ARCH32"
8450 "add\\t%1, %2, %0, %%tldo_add(%a3)")
8452 (define_insn "tldo_add64"
8453 [(set (match_operand:DI 0 "register_operand" "=r")
8454 (plus:DI (match_operand:DI 1 "register_operand" "r")
8455 (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8456 (match_operand 3 "tld_symbolic_operand" "")]
8458 "TARGET_TLS && TARGET_ARCH64"
8459 "add\\t%1, %2, %0, %%tldo_add(%a3)")
8461 (define_insn "tie_hi22"
8462 [(set (match_operand:SI 0 "register_operand" "=r")
8463 (high:SI (unspec:SI [(match_operand 1 "tie_symbolic_operand" "")]
8466 "sethi\\t%%tie_hi22(%a1), %0")
8468 (define_insn "tie_lo10"
8469 [(set (match_operand:SI 0 "register_operand" "=r")
8470 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
8471 (unspec:SI [(match_operand 2 "tie_symbolic_operand" "")]
8474 "add\\t%1, %%tie_lo10(%a2), %0")
8476 (define_insn "tie_ld32"
8477 [(set (match_operand:SI 0 "register_operand" "=r")
8478 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
8479 (match_operand:SI 2 "register_operand" "r")
8480 (match_operand 3 "tie_symbolic_operand" "")]
8482 "TARGET_TLS && TARGET_ARCH32"
8483 "ld\\t[%1 + %2], %0, %%tie_ld(%a3)"
8484 [(set_attr "type" "load")])
8486 (define_insn "tie_ld64"
8487 [(set (match_operand:DI 0 "register_operand" "=r")
8488 (unspec:DI [(match_operand:DI 1 "register_operand" "r")
8489 (match_operand:SI 2 "register_operand" "r")
8490 (match_operand 3 "tie_symbolic_operand" "")]
8492 "TARGET_TLS && TARGET_ARCH64"
8493 "ldx\\t[%1 + %2], %0, %%tie_ldx(%a3)"
8494 [(set_attr "type" "load")])
8496 (define_insn "tie_add32"
8497 [(set (match_operand:SI 0 "register_operand" "=r")
8498 (plus:SI (match_operand:SI 1 "register_operand" "r")
8499 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8500 (match_operand 3 "tie_symbolic_operand" "")]
8502 "TARGET_SUN_TLS && TARGET_ARCH32"
8503 "add\\t%1, %2, %0, %%tie_add(%a3)")
8505 (define_insn "tie_add64"
8506 [(set (match_operand:DI 0 "register_operand" "=r")
8507 (plus:DI (match_operand:DI 1 "register_operand" "r")
8508 (unspec:DI [(match_operand:DI 2 "register_operand" "r")
8509 (match_operand 3 "tie_symbolic_operand" "")]
8511 "TARGET_SUN_TLS && TARGET_ARCH64"
8512 "add\\t%1, %2, %0, %%tie_add(%a3)")
8514 (define_insn "tle_hix22_sp32"
8515 [(set (match_operand:SI 0 "register_operand" "=r")
8516 (high:SI (unspec:SI [(match_operand 1 "tle_symbolic_operand" "")]
8518 "TARGET_TLS && TARGET_ARCH32"
8519 "sethi\\t%%tle_hix22(%a1), %0")
8521 (define_insn "tle_lox10_sp32"
8522 [(set (match_operand:SI 0 "register_operand" "=r")
8523 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
8524 (unspec:SI [(match_operand 2 "tle_symbolic_operand" "")]
8526 "TARGET_TLS && TARGET_ARCH32"
8527 "xor\\t%1, %%tle_lox10(%a2), %0")
8529 (define_insn "tle_hix22_sp64"
8530 [(set (match_operand:DI 0 "register_operand" "=r")
8531 (high:DI (unspec:DI [(match_operand 1 "tle_symbolic_operand" "")]
8533 "TARGET_TLS && TARGET_ARCH64"
8534 "sethi\\t%%tle_hix22(%a1), %0")
8536 (define_insn "tle_lox10_sp64"
8537 [(set (match_operand:DI 0 "register_operand" "=r")
8538 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
8539 (unspec:DI [(match_operand 2 "tle_symbolic_operand" "")]
8541 "TARGET_TLS && TARGET_ARCH64"
8542 "xor\\t%1, %%tle_lox10(%a2), %0")
8544 ;; Now patterns combining tldo_add{32,64} with some integer loads or stores
8545 (define_insn "*tldo_ldub_sp32"
8546 [(set (match_operand:QI 0 "register_operand" "=r")
8547 (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8548 (match_operand 3 "tld_symbolic_operand" "")]
8550 (match_operand:SI 1 "register_operand" "r"))))]
8551 "TARGET_TLS && TARGET_ARCH32"
8552 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8553 [(set_attr "type" "load")
8554 (set_attr "us3load_type" "3cycle")])
8556 (define_insn "*tldo_ldub1_sp32"
8557 [(set (match_operand:HI 0 "register_operand" "=r")
8558 (zero_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8559 (match_operand 3 "tld_symbolic_operand" "")]
8561 (match_operand:SI 1 "register_operand" "r")))))]
8562 "TARGET_TLS && TARGET_ARCH32"
8563 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8564 [(set_attr "type" "load")
8565 (set_attr "us3load_type" "3cycle")])
8567 (define_insn "*tldo_ldub2_sp32"
8568 [(set (match_operand:SI 0 "register_operand" "=r")
8569 (zero_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8570 (match_operand 3 "tld_symbolic_operand" "")]
8572 (match_operand:SI 1 "register_operand" "r")))))]
8573 "TARGET_TLS && TARGET_ARCH32"
8574 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8575 [(set_attr "type" "load")
8576 (set_attr "us3load_type" "3cycle")])
8578 (define_insn "*tldo_ldsb1_sp32"
8579 [(set (match_operand:HI 0 "register_operand" "=r")
8580 (sign_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8581 (match_operand 3 "tld_symbolic_operand" "")]
8583 (match_operand:SI 1 "register_operand" "r")))))]
8584 "TARGET_TLS && TARGET_ARCH32"
8585 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
8586 [(set_attr "type" "sload")
8587 (set_attr "us3load_type" "3cycle")])
8589 (define_insn "*tldo_ldsb2_sp32"
8590 [(set (match_operand:SI 0 "register_operand" "=r")
8591 (sign_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8592 (match_operand 3 "tld_symbolic_operand" "")]
8594 (match_operand:SI 1 "register_operand" "r")))))]
8595 "TARGET_TLS && TARGET_ARCH32"
8596 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
8597 [(set_attr "type" "sload")
8598 (set_attr "us3load_type" "3cycle")])
8600 (define_insn "*tldo_ldub_sp64"
8601 [(set (match_operand:QI 0 "register_operand" "=r")
8602 (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8603 (match_operand 3 "tld_symbolic_operand" "")]
8605 (match_operand:DI 1 "register_operand" "r"))))]
8606 "TARGET_TLS && TARGET_ARCH64"
8607 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8608 [(set_attr "type" "load")
8609 (set_attr "us3load_type" "3cycle")])
8611 (define_insn "*tldo_ldub1_sp64"
8612 [(set (match_operand:HI 0 "register_operand" "=r")
8613 (zero_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8614 (match_operand 3 "tld_symbolic_operand" "")]
8616 (match_operand:DI 1 "register_operand" "r")))))]
8617 "TARGET_TLS && TARGET_ARCH64"
8618 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8619 [(set_attr "type" "load")
8620 (set_attr "us3load_type" "3cycle")])
8622 (define_insn "*tldo_ldub2_sp64"
8623 [(set (match_operand:SI 0 "register_operand" "=r")
8624 (zero_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8625 (match_operand 3 "tld_symbolic_operand" "")]
8627 (match_operand:DI 1 "register_operand" "r")))))]
8628 "TARGET_TLS && TARGET_ARCH64"
8629 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8630 [(set_attr "type" "load")
8631 (set_attr "us3load_type" "3cycle")])
8633 (define_insn "*tldo_ldub3_sp64"
8634 [(set (match_operand:DI 0 "register_operand" "=r")
8635 (zero_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8636 (match_operand 3 "tld_symbolic_operand" "")]
8638 (match_operand:DI 1 "register_operand" "r")))))]
8639 "TARGET_TLS && TARGET_ARCH64"
8640 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8641 [(set_attr "type" "load")
8642 (set_attr "us3load_type" "3cycle")])
8644 (define_insn "*tldo_ldsb1_sp64"
8645 [(set (match_operand:HI 0 "register_operand" "=r")
8646 (sign_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8647 (match_operand 3 "tld_symbolic_operand" "")]
8649 (match_operand:DI 1 "register_operand" "r")))))]
8650 "TARGET_TLS && TARGET_ARCH64"
8651 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
8652 [(set_attr "type" "sload")
8653 (set_attr "us3load_type" "3cycle")])
8655 (define_insn "*tldo_ldsb2_sp64"
8656 [(set (match_operand:SI 0 "register_operand" "=r")
8657 (sign_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8658 (match_operand 3 "tld_symbolic_operand" "")]
8660 (match_operand:DI 1 "register_operand" "r")))))]
8661 "TARGET_TLS && TARGET_ARCH64"
8662 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
8663 [(set_attr "type" "sload")
8664 (set_attr "us3load_type" "3cycle")])
8666 (define_insn "*tldo_ldsb3_sp64"
8667 [(set (match_operand:DI 0 "register_operand" "=r")
8668 (sign_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8669 (match_operand 3 "tld_symbolic_operand" "")]
8671 (match_operand:DI 1 "register_operand" "r")))))]
8672 "TARGET_TLS && TARGET_ARCH64"
8673 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
8674 [(set_attr "type" "sload")
8675 (set_attr "us3load_type" "3cycle")])
8677 (define_insn "*tldo_lduh_sp32"
8678 [(set (match_operand:HI 0 "register_operand" "=r")
8679 (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8680 (match_operand 3 "tld_symbolic_operand" "")]
8682 (match_operand:SI 1 "register_operand" "r"))))]
8683 "TARGET_TLS && TARGET_ARCH32"
8684 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
8685 [(set_attr "type" "load")
8686 (set_attr "us3load_type" "3cycle")])
8688 (define_insn "*tldo_lduh1_sp32"
8689 [(set (match_operand:SI 0 "register_operand" "=r")
8690 (zero_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8691 (match_operand 3 "tld_symbolic_operand" "")]
8693 (match_operand:SI 1 "register_operand" "r")))))]
8694 "TARGET_TLS && TARGET_ARCH32"
8695 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
8696 [(set_attr "type" "load")
8697 (set_attr "us3load_type" "3cycle")])
8699 (define_insn "*tldo_ldsh1_sp32"
8700 [(set (match_operand:SI 0 "register_operand" "=r")
8701 (sign_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8702 (match_operand 3 "tld_symbolic_operand" "")]
8704 (match_operand:SI 1 "register_operand" "r")))))]
8705 "TARGET_TLS && TARGET_ARCH32"
8706 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
8707 [(set_attr "type" "sload")
8708 (set_attr "us3load_type" "3cycle")])
8710 (define_insn "*tldo_lduh_sp64"
8711 [(set (match_operand:HI 0 "register_operand" "=r")
8712 (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8713 (match_operand 3 "tld_symbolic_operand" "")]
8715 (match_operand:DI 1 "register_operand" "r"))))]
8716 "TARGET_TLS && TARGET_ARCH64"
8717 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
8718 [(set_attr "type" "load")
8719 (set_attr "us3load_type" "3cycle")])
8721 (define_insn "*tldo_lduh1_sp64"
8722 [(set (match_operand:SI 0 "register_operand" "=r")
8723 (zero_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8724 (match_operand 3 "tld_symbolic_operand" "")]
8726 (match_operand:DI 1 "register_operand" "r")))))]
8727 "TARGET_TLS && TARGET_ARCH64"
8728 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
8729 [(set_attr "type" "load")
8730 (set_attr "us3load_type" "3cycle")])
8732 (define_insn "*tldo_lduh2_sp64"
8733 [(set (match_operand:DI 0 "register_operand" "=r")
8734 (zero_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8735 (match_operand 3 "tld_symbolic_operand" "")]
8737 (match_operand:DI 1 "register_operand" "r")))))]
8738 "TARGET_TLS && TARGET_ARCH64"
8739 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
8740 [(set_attr "type" "load")
8741 (set_attr "us3load_type" "3cycle")])
8743 (define_insn "*tldo_ldsh1_sp64"
8744 [(set (match_operand:SI 0 "register_operand" "=r")
8745 (sign_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8746 (match_operand 3 "tld_symbolic_operand" "")]
8748 (match_operand:DI 1 "register_operand" "r")))))]
8749 "TARGET_TLS && TARGET_ARCH64"
8750 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
8751 [(set_attr "type" "sload")
8752 (set_attr "us3load_type" "3cycle")])
8754 (define_insn "*tldo_ldsh2_sp64"
8755 [(set (match_operand:DI 0 "register_operand" "=r")
8756 (sign_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8757 (match_operand 3 "tld_symbolic_operand" "")]
8759 (match_operand:DI 1 "register_operand" "r")))))]
8760 "TARGET_TLS && TARGET_ARCH64"
8761 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
8762 [(set_attr "type" "sload")
8763 (set_attr "us3load_type" "3cycle")])
8765 (define_insn "*tldo_lduw_sp32"
8766 [(set (match_operand:SI 0 "register_operand" "=r")
8767 (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8768 (match_operand 3 "tld_symbolic_operand" "")]
8770 (match_operand:SI 1 "register_operand" "r"))))]
8771 "TARGET_TLS && TARGET_ARCH32"
8772 "ld\t[%1 + %2], %0, %%tldo_add(%3)"
8773 [(set_attr "type" "load")])
8775 (define_insn "*tldo_lduw_sp64"
8776 [(set (match_operand:SI 0 "register_operand" "=r")
8777 (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8778 (match_operand 3 "tld_symbolic_operand" "")]
8780 (match_operand:DI 1 "register_operand" "r"))))]
8781 "TARGET_TLS && TARGET_ARCH64"
8782 "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
8783 [(set_attr "type" "load")])
8785 (define_insn "*tldo_lduw1_sp64"
8786 [(set (match_operand:DI 0 "register_operand" "=r")
8787 (zero_extend:DI (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8788 (match_operand 3 "tld_symbolic_operand" "")]
8790 (match_operand:DI 1 "register_operand" "r")))))]
8791 "TARGET_TLS && TARGET_ARCH64"
8792 "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
8793 [(set_attr "type" "load")])
8795 (define_insn "*tldo_ldsw1_sp64"
8796 [(set (match_operand:DI 0 "register_operand" "=r")
8797 (sign_extend:DI (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8798 (match_operand 3 "tld_symbolic_operand" "")]
8800 (match_operand:DI 1 "register_operand" "r")))))]
8801 "TARGET_TLS && TARGET_ARCH64"
8802 "ldsw\t[%1 + %2], %0, %%tldo_add(%3)"
8803 [(set_attr "type" "sload")
8804 (set_attr "us3load_type" "3cycle")])
8806 (define_insn "*tldo_ldx_sp64"
8807 [(set (match_operand:DI 0 "register_operand" "=r")
8808 (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8809 (match_operand 3 "tld_symbolic_operand" "")]
8811 (match_operand:DI 1 "register_operand" "r"))))]
8812 "TARGET_TLS && TARGET_ARCH64"
8813 "ldx\t[%1 + %2], %0, %%tldo_add(%3)"
8814 [(set_attr "type" "load")])
8816 (define_insn "*tldo_stb_sp32"
8817 [(set (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8818 (match_operand 3 "tld_symbolic_operand" "")]
8820 (match_operand:SI 1 "register_operand" "r")))
8821 (match_operand:QI 0 "register_operand" "=r"))]
8822 "TARGET_TLS && TARGET_ARCH32"
8823 "stb\t%0, [%1 + %2], %%tldo_add(%3)"
8824 [(set_attr "type" "store")])
8826 (define_insn "*tldo_stb_sp64"
8827 [(set (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8828 (match_operand 3 "tld_symbolic_operand" "")]
8830 (match_operand:DI 1 "register_operand" "r")))
8831 (match_operand:QI 0 "register_operand" "=r"))]
8832 "TARGET_TLS && TARGET_ARCH64"
8833 "stb\t%0, [%1 + %2], %%tldo_add(%3)"
8834 [(set_attr "type" "store")])
8836 (define_insn "*tldo_sth_sp32"
8837 [(set (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8838 (match_operand 3 "tld_symbolic_operand" "")]
8840 (match_operand:SI 1 "register_operand" "r")))
8841 (match_operand:HI 0 "register_operand" "=r"))]
8842 "TARGET_TLS && TARGET_ARCH32"
8843 "sth\t%0, [%1 + %2], %%tldo_add(%3)"
8844 [(set_attr "type" "store")])
8846 (define_insn "*tldo_sth_sp64"
8847 [(set (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8848 (match_operand 3 "tld_symbolic_operand" "")]
8850 (match_operand:DI 1 "register_operand" "r")))
8851 (match_operand:HI 0 "register_operand" "=r"))]
8852 "TARGET_TLS && TARGET_ARCH64"
8853 "sth\t%0, [%1 + %2], %%tldo_add(%3)"
8854 [(set_attr "type" "store")])
8856 (define_insn "*tldo_stw_sp32"
8857 [(set (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8858 (match_operand 3 "tld_symbolic_operand" "")]
8860 (match_operand:SI 1 "register_operand" "r")))
8861 (match_operand:SI 0 "register_operand" "=r"))]
8862 "TARGET_TLS && TARGET_ARCH32"
8863 "st\t%0, [%1 + %2], %%tldo_add(%3)"
8864 [(set_attr "type" "store")])
8866 (define_insn "*tldo_stw_sp64"
8867 [(set (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8868 (match_operand 3 "tld_symbolic_operand" "")]
8870 (match_operand:DI 1 "register_operand" "r")))
8871 (match_operand:SI 0 "register_operand" "=r"))]
8872 "TARGET_TLS && TARGET_ARCH64"
8873 "stw\t%0, [%1 + %2], %%tldo_add(%3)"
8874 [(set_attr "type" "store")])
8876 (define_insn "*tldo_stx_sp64"
8877 [(set (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8878 (match_operand 3 "tld_symbolic_operand" "")]
8880 (match_operand:DI 1 "register_operand" "r")))
8881 (match_operand:DI 0 "register_operand" "=r"))]
8882 "TARGET_TLS && TARGET_ARCH64"
8883 "stx\t%0, [%1 + %2], %%tldo_add(%3)"
8884 [(set_attr "type" "store")])
8886 ;; Vector instructions.
8888 (define_insn "addv2si3"
8889 [(set (match_operand:V2SI 0 "register_operand" "=e")
8890 (plus:V2SI (match_operand:V2SI 1 "register_operand" "e")
8891 (match_operand:V2SI 2 "register_operand" "e")))]
8893 "fpadd32\t%1, %2, %0"
8894 [(set_attr "type" "fga")
8895 (set_attr "fptype" "double")])
8897 (define_insn "addv4hi3"
8898 [(set (match_operand:V4HI 0 "register_operand" "=e")
8899 (plus:V4HI (match_operand:V4HI 1 "register_operand" "e")
8900 (match_operand:V4HI 2 "register_operand" "e")))]
8902 "fpadd16\t%1, %2, %0"
8903 [(set_attr "type" "fga")
8904 (set_attr "fptype" "double")])
8906 ;; fpadd32s is emitted by the addsi3 pattern.
8908 (define_insn "addv2hi3"
8909 [(set (match_operand:V2HI 0 "register_operand" "=f")
8910 (plus:V2HI (match_operand:V2HI 1 "register_operand" "f")
8911 (match_operand:V2HI 2 "register_operand" "f")))]
8913 "fpadd16s\t%1, %2, %0"
8914 [(set_attr "type" "fga")
8915 (set_attr "fptype" "single")])
8917 (define_insn "subv2si3"
8918 [(set (match_operand:V2SI 0 "register_operand" "=e")
8919 (minus:V2SI (match_operand:V2SI 1 "register_operand" "e")
8920 (match_operand:V2SI 2 "register_operand" "e")))]
8922 "fpsub32\t%1, %2, %0"
8923 [(set_attr "type" "fga")
8924 (set_attr "fptype" "double")])
8926 (define_insn "subv4hi3"
8927 [(set (match_operand:V4HI 0 "register_operand" "=e")
8928 (minus:V4HI (match_operand:V4HI 1 "register_operand" "e")
8929 (match_operand:V4HI 2 "register_operand" "e")))]
8931 "fpsub16\t%1, %2, %0"
8932 [(set_attr "type" "fga")
8933 (set_attr "fptype" "double")])
8935 ;; fpsub32s is emitted by the subsi3 pattern.
8937 (define_insn "subv2hi3"
8938 [(set (match_operand:V2HI 0 "register_operand" "=f")
8939 (minus:V2HI (match_operand:V2HI 1 "register_operand" "f")
8940 (match_operand:V2HI 2 "register_operand" "f")))]
8942 "fpsub16s\t%1, %2, %0"
8943 [(set_attr "type" "fga")
8944 (set_attr "fptype" "single")])
8946 ;; All other logical instructions have integer equivalents so they
8947 ;; are defined together.
8949 ;; (ior (not (op1)) (not (op2))) is the canonical form of NAND.
8951 (define_insn "*nand<V64mode>_vis"
8952 [(set (match_operand:V64 0 "register_operand" "=e")
8953 (ior:V64 (not:V64 (match_operand:V64 1 "register_operand" "e"))
8954 (not:V64 (match_operand:V64 2 "register_operand" "e"))))]
8957 [(set_attr "type" "fga")
8958 (set_attr "fptype" "double")])
8960 (define_insn "*nand<V32mode>_vis"
8961 [(set (match_operand:V32 0 "register_operand" "=f")
8962 (ior:V32 (not:V32 (match_operand:V32 1 "register_operand" "f"))
8963 (not:V32 (match_operand:V32 2 "register_operand" "f"))))]
8965 "fnands\t%1, %2, %0"
8966 [(set_attr "type" "fga")
8967 (set_attr "fptype" "single")])
8969 ;; Hard to generate VIS instructions. We have builtins for these.
8971 (define_insn "fpack16_vis"
8972 [(set (match_operand:V4QI 0 "register_operand" "=f")
8973 (unspec:V4QI [(match_operand:V4HI 1 "register_operand" "e")]
8977 [(set_attr "type" "fga")
8978 (set_attr "fptype" "double")])
8980 (define_insn "fpackfix_vis"
8981 [(set (match_operand:V2HI 0 "register_operand" "=f")
8982 (unspec:V2HI [(match_operand:V2SI 1 "register_operand" "e")]
8986 [(set_attr "type" "fga")
8987 (set_attr "fptype" "double")])
8989 (define_insn "fpack32_vis"
8990 [(set (match_operand:V8QI 0 "register_operand" "=e")
8991 (unspec:V8QI [(match_operand:V2SI 1 "register_operand" "e")
8992 (match_operand:V8QI 2 "register_operand" "e")]
8995 "fpack32\t%1, %2, %0"
8996 [(set_attr "type" "fga")
8997 (set_attr "fptype" "double")])
8999 (define_insn "fexpand_vis"
9000 [(set (match_operand:V4HI 0 "register_operand" "=e")
9001 (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")]
9005 [(set_attr "type" "fga")
9006 (set_attr "fptype" "double")])
9008 ;; It may be possible to describe this operation as (1 indexed):
9009 ;; (vec_select (vec_duplicate (vec_duplicate (vec_concat 1 2)))
9010 ;; 1,5,10,14,19,23,28,32)
9011 ;; Note that (vec_merge:V8QI [(V4QI) (V4QI)] (10101010 = 170) doesn't work
9012 ;; because vec_merge expects all the operands to be of the same type.
9013 (define_insn "fpmerge_vis"
9014 [(set (match_operand:V8QI 0 "register_operand" "=e")
9015 (unspec:V8QI [(match_operand:V4QI 1 "register_operand" "f")
9016 (match_operand:V4QI 2 "register_operand" "f")]
9019 "fpmerge\t%1, %2, %0"
9020 [(set_attr "type" "fga")
9021 (set_attr "fptype" "double")])
9023 ;; Partitioned multiply instructions
9024 (define_insn "fmul8x16_vis"
9025 [(set (match_operand:V4HI 0 "register_operand" "=e")
9026 (mult:V4HI (match_operand:V4QI 1 "register_operand" "f")
9027 (match_operand:V4HI 2 "register_operand" "e")))]
9029 "fmul8x16\t%1, %2, %0"
9030 [(set_attr "type" "fpmul")
9031 (set_attr "fptype" "double")])
9033 ;; Only one of the following two insns can be a multiply.
9034 (define_insn "fmul8x16au_vis"
9035 [(set (match_operand:V4HI 0 "register_operand" "=e")
9036 (mult:V4HI (match_operand:V4QI 1 "register_operand" "f")
9037 (match_operand:V2HI 2 "register_operand" "f")))]
9039 "fmul8x16au\t%1, %2, %0"
9040 [(set_attr "type" "fpmul")
9041 (set_attr "fptype" "double")])
9043 (define_insn "fmul8x16al_vis"
9044 [(set (match_operand:V4HI 0 "register_operand" "=e")
9045 (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")
9046 (match_operand:V2HI 2 "register_operand" "f")]
9049 "fmul8x16al\t%1, %2, %0"
9050 [(set_attr "type" "fpmul")
9051 (set_attr "fptype" "double")])
9053 ;; Only one of the following two insns can be a multiply.
9054 (define_insn "fmul8sux16_vis"
9055 [(set (match_operand:V4HI 0 "register_operand" "=e")
9056 (mult:V4HI (match_operand:V8QI 1 "register_operand" "e")
9057 (match_operand:V4HI 2 "register_operand" "e")))]
9059 "fmul8sux16\t%1, %2, %0"
9060 [(set_attr "type" "fpmul")
9061 (set_attr "fptype" "double")])
9063 (define_insn "fmul8ulx16_vis"
9064 [(set (match_operand:V4HI 0 "register_operand" "=e")
9065 (unspec:V4HI [(match_operand:V8QI 1 "register_operand" "e")
9066 (match_operand:V4HI 2 "register_operand" "e")]
9069 "fmul8ulx16\t%1, %2, %0"
9070 [(set_attr "type" "fpmul")
9071 (set_attr "fptype" "double")])
9073 ;; Only one of the following two insns can be a multiply.
9074 (define_insn "fmuld8sux16_vis"
9075 [(set (match_operand:V2SI 0 "register_operand" "=e")
9076 (mult:V2SI (match_operand:V4QI 1 "register_operand" "f")
9077 (match_operand:V2HI 2 "register_operand" "f")))]
9079 "fmuld8sux16\t%1, %2, %0"
9080 [(set_attr "type" "fpmul")
9081 (set_attr "fptype" "double")])
9083 (define_insn "fmuld8ulx16_vis"
9084 [(set (match_operand:V2SI 0 "register_operand" "=e")
9085 (unspec:V2SI [(match_operand:V4QI 1 "register_operand" "f")
9086 (match_operand:V2HI 2 "register_operand" "f")]
9089 "fmuld8ulx16\t%1, %2, %0"
9090 [(set_attr "type" "fpmul")
9091 (set_attr "fptype" "double")])
9093 ;; Using faligndata only makes sense after an alignaddr since the choice of
9094 ;; bytes to take out of each operand is dependant on the results of the last
9096 (define_insn "faligndata<V64I:mode>_vis"
9097 [(set (match_operand:V64I 0 "register_operand" "=e")
9098 (unspec:V64I [(match_operand:V64I 1 "register_operand" "e")
9099 (match_operand:V64I 2 "register_operand" "e")]
9102 "faligndata\t%1, %2, %0"
9103 [(set_attr "type" "fga")
9104 (set_attr "fptype" "double")])
9106 (define_mode_macro P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
9108 (define_insn "alignaddr<P:mode>_vis"
9109 [(set (match_operand:P 0 "register_operand" "=r")
9110 (unspec:P [(match_operand:P 1 "reg_or_0_operand" "rJ")
9111 (match_operand:P 2 "reg_or_0_operand" "rJ")]
9114 "alignaddr\t%r1, %r2, %0")
9116 (define_insn "pdist_vis"
9117 [(set (match_operand:DI 0 "register_operand" "=e")
9118 (unspec:DI [(match_operand:V8QI 1 "register_operand" "e")
9119 (match_operand:V8QI 2 "register_operand" "e")
9120 (match_operand:DI 3 "register_operand" "0")]
9124 [(set_attr "type" "fga")
9125 (set_attr "fptype" "double")])