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 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)
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)
59 ;; The upper 32 fp regs on the v9 can't hold SFmode values. To deal with this
60 ;; a second register class, EXTRA_FP_REGS, exists for the v9 chip. The name
61 ;; is a bit of a misnomer as it covers all 64 fp regs. The corresponding
62 ;; constraint letter is 'e'. To avoid any confusion, 'e' is used instead of
63 ;; 'f' for all DF/TFmode values, including those that are specific to the v8.
65 ;; Attribute for cpu type.
66 ;; These must match the values for enum processor_type in sparc.h.
73 hypersparc,sparclite86x,
78 (const (symbol_ref "sparc_cpu_attr")))
80 ;; Attribute for the instruction set.
81 ;; At present we only need to distinguish v9/!v9, but for clarity we
82 ;; test TARGET_V8 too.
83 (define_attr "isa" "v7,v8,v9,sparclet"
85 (cond [(symbol_ref "TARGET_V9") (const_string "v9")
86 (symbol_ref "TARGET_V8") (const_string "v8")
87 (symbol_ref "TARGET_SPARCLET") (const_string "sparclet")]
88 (const_string "v7"))))
91 (define_attr "arch" "arch32bit,arch64bit"
93 (cond [(symbol_ref "TARGET_ARCH64") (const_string "arch64bit")]
94 (const_string "arch32bit"))))
101 uncond_branch,branch,call,sibcall,call_no_delay_slot,
109 fga,fgm_pack,fgm_mul,fgm_pdist,fgm_cmp,
112 multi,flushw,iflush,trap"
113 (const_string "ialu"))
115 ;; true if branch/call has empty delay slot and will emit a nop in it
116 (define_attr "empty_delay_slot" "false,true"
117 (symbol_ref "empty_delay_slot (insn)"))
119 (define_attr "branch_type" "none,icc,fcc,reg" (const_string "none"))
121 (define_attr "pic" "false,true"
122 (symbol_ref "flag_pic != 0"))
124 (define_attr "current_function_calls_alloca" "false,true"
125 (symbol_ref "current_function_calls_alloca != 0"))
127 ;; Length (in # of insns).
128 (define_attr "length" ""
129 (cond [(eq_attr "type" "uncond_branch,call,sibcall")
130 (if_then_else (eq_attr "empty_delay_slot" "true")
133 (eq_attr "branch_type" "icc")
134 (if_then_else (match_operand 0 "noov_compare64_op" "")
135 (if_then_else (lt (pc) (match_dup 1))
136 (if_then_else (lt (minus (match_dup 1) (pc)) (const_int 260000))
137 (if_then_else (eq_attr "empty_delay_slot" "true")
140 (if_then_else (eq_attr "empty_delay_slot" "true")
143 (if_then_else (lt (minus (pc) (match_dup 1)) (const_int 260000))
144 (if_then_else (eq_attr "empty_delay_slot" "true")
147 (if_then_else (eq_attr "empty_delay_slot" "true")
150 (if_then_else (eq_attr "empty_delay_slot" "true")
153 (eq_attr "branch_type" "fcc")
154 (if_then_else (match_operand 0 "fcc0_reg_operand" "")
155 (if_then_else (eq_attr "empty_delay_slot" "true")
156 (if_then_else (eq (symbol_ref "TARGET_V9") (const_int 0))
159 (if_then_else (eq (symbol_ref "TARGET_V9") (const_int 0))
162 (if_then_else (lt (pc) (match_dup 2))
163 (if_then_else (lt (minus (match_dup 2) (pc)) (const_int 260000))
164 (if_then_else (eq_attr "empty_delay_slot" "true")
167 (if_then_else (eq_attr "empty_delay_slot" "true")
170 (if_then_else (lt (minus (pc) (match_dup 2)) (const_int 260000))
171 (if_then_else (eq_attr "empty_delay_slot" "true")
174 (if_then_else (eq_attr "empty_delay_slot" "true")
177 (eq_attr "branch_type" "reg")
178 (if_then_else (lt (pc) (match_dup 2))
179 (if_then_else (lt (minus (match_dup 2) (pc)) (const_int 32000))
180 (if_then_else (eq_attr "empty_delay_slot" "true")
183 (if_then_else (eq_attr "empty_delay_slot" "true")
186 (if_then_else (lt (minus (pc) (match_dup 2)) (const_int 32000))
187 (if_then_else (eq_attr "empty_delay_slot" "true")
190 (if_then_else (eq_attr "empty_delay_slot" "true")
196 (define_attr "fptype" "single,double" (const_string "single"))
198 ;; UltraSPARC-III integer load type.
199 (define_attr "us3load_type" "2cycle,3cycle" (const_string "2cycle"))
201 (define_asm_attributes
202 [(set_attr "length" "2")
203 (set_attr "type" "multi")])
205 ;; Attributes for instruction and branch scheduling
207 (define_attr "tls_call_delay" "false,true"
208 (symbol_ref "tls_call_delay (insn)"))
210 (define_attr "in_call_delay" "false,true"
211 (cond [(eq_attr "type" "uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
212 (const_string "false")
213 (eq_attr "type" "load,fpload,store,fpstore")
214 (if_then_else (eq_attr "length" "1")
215 (const_string "true")
216 (const_string "false"))]
217 (if_then_else (and (eq_attr "length" "1")
218 (eq_attr "tls_call_delay" "true"))
219 (const_string "true")
220 (const_string "false"))))
222 (define_delay (eq_attr "type" "call")
223 [(eq_attr "in_call_delay" "true") (nil) (nil)])
225 (define_attr "eligible_for_sibcall_delay" "false,true"
226 (symbol_ref "eligible_for_sibcall_delay (insn)"))
228 (define_delay (eq_attr "type" "sibcall")
229 [(eq_attr "eligible_for_sibcall_delay" "true") (nil) (nil)])
231 (define_attr "leaf_function" "false,true"
232 (const (symbol_ref "current_function_uses_only_leaf_regs")))
234 ;; ??? Should implement the notion of predelay slots for floating point
235 ;; branches. This would allow us to remove the nop always inserted before
236 ;; a floating point branch.
238 ;; ??? It is OK for fill_simple_delay_slots to put load/store instructions
239 ;; in a delay slot, but it is not OK for fill_eager_delay_slots to do so.
240 ;; This is because doing so will add several pipeline stalls to the path
241 ;; that the load/store did not come from. Unfortunately, there is no way
242 ;; to prevent fill_eager_delay_slots from using load/store without completely
243 ;; disabling them. For the SPEC benchmark set, this is a serious lose,
244 ;; because it prevents us from moving back the final store of inner loops.
246 (define_attr "in_branch_delay" "false,true"
247 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
248 (eq_attr "length" "1"))
249 (const_string "true")
250 (const_string "false")))
252 (define_attr "in_uncond_branch_delay" "false,true"
253 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
254 (eq_attr "length" "1"))
255 (const_string "true")
256 (const_string "false")))
258 (define_attr "in_annul_branch_delay" "false,true"
259 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
260 (eq_attr "length" "1"))
261 (const_string "true")
262 (const_string "false")))
264 (define_delay (eq_attr "type" "branch")
265 [(eq_attr "in_branch_delay" "true")
266 (nil) (eq_attr "in_annul_branch_delay" "true")])
268 (define_delay (eq_attr "type" "uncond_branch")
269 [(eq_attr "in_uncond_branch_delay" "true")
272 ;; Include SPARC DFA schedulers
274 (include "cypress.md")
275 (include "supersparc.md")
276 (include "hypersparc.md")
277 (include "sparclet.md")
278 (include "ultra1_2.md")
279 (include "ultra3.md")
282 ;; Compare instructions.
283 ;; This controls RTL generation and register allocation.
285 ;; We generate RTL for comparisons and branches by having the cmpxx
286 ;; patterns store away the operands. Then, the scc and bcc patterns
287 ;; emit RTL for both the compare and the branch.
289 ;; We do this because we want to generate different code for an sne and
290 ;; seq insn. In those cases, if the second operand of the compare is not
291 ;; const0_rtx, we want to compute the xor of the two operands and test
294 ;; We start with the DEFINE_EXPANDs, then the DEFINE_INSNs to match
295 ;; the patterns. Finally, we have the DEFINE_SPLITs for some of the scc
296 ;; insns that actually require more than one machine instruction.
298 ;; Put cmpsi first among compare insns so it matches two CONST_INT operands.
300 (define_expand "cmpsi"
302 (compare:CC (match_operand:SI 0 "register_operand" "")
303 (match_operand:SI 1 "arith_operand" "")))]
306 sparc_compare_op0 = operands[0];
307 sparc_compare_op1 = operands[1];
311 (define_expand "cmpdi"
313 (compare:CCX (match_operand:DI 0 "register_operand" "")
314 (match_operand:DI 1 "arith_double_operand" "")))]
317 sparc_compare_op0 = operands[0];
318 sparc_compare_op1 = operands[1];
322 (define_expand "cmpsf"
323 ;; The 96 here isn't ever used by anyone.
325 (compare:CCFP (match_operand:SF 0 "register_operand" "")
326 (match_operand:SF 1 "register_operand" "")))]
329 sparc_compare_op0 = operands[0];
330 sparc_compare_op1 = operands[1];
334 (define_expand "cmpdf"
335 ;; The 96 here isn't ever used by anyone.
337 (compare:CCFP (match_operand:DF 0 "register_operand" "")
338 (match_operand:DF 1 "register_operand" "")))]
341 sparc_compare_op0 = operands[0];
342 sparc_compare_op1 = operands[1];
346 (define_expand "cmptf"
347 ;; The 96 here isn't ever used by anyone.
349 (compare:CCFP (match_operand:TF 0 "register_operand" "")
350 (match_operand:TF 1 "register_operand" "")))]
353 sparc_compare_op0 = operands[0];
354 sparc_compare_op1 = operands[1];
358 ;; Now the compare DEFINE_INSNs.
360 (define_insn "*cmpsi_insn"
362 (compare:CC (match_operand:SI 0 "register_operand" "r")
363 (match_operand:SI 1 "arith_operand" "rI")))]
366 [(set_attr "type" "compare")])
368 (define_insn "*cmpdi_sp64"
370 (compare:CCX (match_operand:DI 0 "register_operand" "r")
371 (match_operand:DI 1 "arith_double_operand" "rHI")))]
374 [(set_attr "type" "compare")])
376 (define_insn "*cmpsf_fpe"
377 [(set (match_operand:CCFPE 0 "fcc_reg_operand" "=c")
378 (compare:CCFPE (match_operand:SF 1 "register_operand" "f")
379 (match_operand:SF 2 "register_operand" "f")))]
383 return "fcmpes\t%0, %1, %2";
384 return "fcmpes\t%1, %2";
386 [(set_attr "type" "fpcmp")])
388 (define_insn "*cmpdf_fpe"
389 [(set (match_operand:CCFPE 0 "fcc_reg_operand" "=c")
390 (compare:CCFPE (match_operand:DF 1 "register_operand" "e")
391 (match_operand:DF 2 "register_operand" "e")))]
395 return "fcmped\t%0, %1, %2";
396 return "fcmped\t%1, %2";
398 [(set_attr "type" "fpcmp")
399 (set_attr "fptype" "double")])
401 (define_insn "*cmptf_fpe"
402 [(set (match_operand:CCFPE 0 "fcc_reg_operand" "=c")
403 (compare:CCFPE (match_operand:TF 1 "register_operand" "e")
404 (match_operand:TF 2 "register_operand" "e")))]
405 "TARGET_FPU && TARGET_HARD_QUAD"
408 return "fcmpeq\t%0, %1, %2";
409 return "fcmpeq\t%1, %2";
411 [(set_attr "type" "fpcmp")])
413 (define_insn "*cmpsf_fp"
414 [(set (match_operand:CCFP 0 "fcc_reg_operand" "=c")
415 (compare:CCFP (match_operand:SF 1 "register_operand" "f")
416 (match_operand:SF 2 "register_operand" "f")))]
420 return "fcmps\t%0, %1, %2";
421 return "fcmps\t%1, %2";
423 [(set_attr "type" "fpcmp")])
425 (define_insn "*cmpdf_fp"
426 [(set (match_operand:CCFP 0 "fcc_reg_operand" "=c")
427 (compare:CCFP (match_operand:DF 1 "register_operand" "e")
428 (match_operand:DF 2 "register_operand" "e")))]
432 return "fcmpd\t%0, %1, %2";
433 return "fcmpd\t%1, %2";
435 [(set_attr "type" "fpcmp")
436 (set_attr "fptype" "double")])
438 (define_insn "*cmptf_fp"
439 [(set (match_operand:CCFP 0 "fcc_reg_operand" "=c")
440 (compare:CCFP (match_operand:TF 1 "register_operand" "e")
441 (match_operand:TF 2 "register_operand" "e")))]
442 "TARGET_FPU && TARGET_HARD_QUAD"
445 return "fcmpq\t%0, %1, %2";
446 return "fcmpq\t%1, %2";
448 [(set_attr "type" "fpcmp")])
450 ;; Next come the scc insns. For seq, sne, sgeu, and sltu, we can do this
451 ;; without jumps using the addx/subx instructions. For seq/sne on v9 we use
452 ;; the same code as v8 (the addx/subx method has more applications). The
453 ;; exception to this is "reg != 0" which can be done in one instruction on v9
454 ;; (so we do it). For the rest, on v9 we use conditional moves; on v8, we do
457 ;; Seq_special[_xxx] and sne_special[_xxx] clobber the CC reg, because they
458 ;; generate addcc/subcc instructions.
460 (define_expand "seqsi_special"
462 (xor:SI (match_operand:SI 1 "register_operand" "")
463 (match_operand:SI 2 "register_operand" "")))
464 (parallel [(set (match_operand:SI 0 "register_operand" "")
465 (eq:SI (match_dup 3) (const_int 0)))
466 (clobber (reg:CC 100))])]
468 { operands[3] = gen_reg_rtx (SImode); })
470 (define_expand "seqdi_special"
472 (xor:DI (match_operand:DI 1 "register_operand" "")
473 (match_operand:DI 2 "register_operand" "")))
474 (set (match_operand:DI 0 "register_operand" "")
475 (eq:DI (match_dup 3) (const_int 0)))]
477 { operands[3] = gen_reg_rtx (DImode); })
479 (define_expand "snesi_special"
481 (xor:SI (match_operand:SI 1 "register_operand" "")
482 (match_operand:SI 2 "register_operand" "")))
483 (parallel [(set (match_operand:SI 0 "register_operand" "")
484 (ne:SI (match_dup 3) (const_int 0)))
485 (clobber (reg:CC 100))])]
487 { operands[3] = gen_reg_rtx (SImode); })
489 (define_expand "snedi_special"
491 (xor:DI (match_operand:DI 1 "register_operand" "")
492 (match_operand:DI 2 "register_operand" "")))
493 (set (match_operand:DI 0 "register_operand" "")
494 (ne:DI (match_dup 3) (const_int 0)))]
496 { operands[3] = gen_reg_rtx (DImode); })
498 (define_expand "seqdi_special_trunc"
500 (xor:DI (match_operand:DI 1 "register_operand" "")
501 (match_operand:DI 2 "register_operand" "")))
502 (set (match_operand:SI 0 "register_operand" "")
503 (eq:SI (match_dup 3) (const_int 0)))]
505 { operands[3] = gen_reg_rtx (DImode); })
507 (define_expand "snedi_special_trunc"
509 (xor:DI (match_operand:DI 1 "register_operand" "")
510 (match_operand:DI 2 "register_operand" "")))
511 (set (match_operand:SI 0 "register_operand" "")
512 (ne:SI (match_dup 3) (const_int 0)))]
514 { operands[3] = gen_reg_rtx (DImode); })
516 (define_expand "seqsi_special_extend"
518 (xor:SI (match_operand:SI 1 "register_operand" "")
519 (match_operand:SI 2 "register_operand" "")))
520 (parallel [(set (match_operand:DI 0 "register_operand" "")
521 (eq:DI (match_dup 3) (const_int 0)))
522 (clobber (reg:CC 100))])]
524 { operands[3] = gen_reg_rtx (SImode); })
526 (define_expand "snesi_special_extend"
528 (xor:SI (match_operand:SI 1 "register_operand" "")
529 (match_operand:SI 2 "register_operand" "")))
530 (parallel [(set (match_operand:DI 0 "register_operand" "")
531 (ne:DI (match_dup 3) (const_int 0)))
532 (clobber (reg:CC 100))])]
534 { operands[3] = gen_reg_rtx (SImode); })
536 ;; ??? v9: Operand 0 needs a mode, so SImode was chosen.
537 ;; However, the code handles both SImode and DImode.
539 [(set (match_operand:SI 0 "intreg_operand" "")
540 (eq:SI (match_dup 1) (const_int 0)))]
543 if (GET_MODE (sparc_compare_op0) == SImode)
547 if (GET_MODE (operands[0]) == SImode)
548 pat = gen_seqsi_special (operands[0], sparc_compare_op0,
550 else if (! TARGET_ARCH64)
553 pat = gen_seqsi_special_extend (operands[0], sparc_compare_op0,
558 else if (GET_MODE (sparc_compare_op0) == DImode)
564 else if (GET_MODE (operands[0]) == SImode)
565 pat = gen_seqdi_special_trunc (operands[0], sparc_compare_op0,
568 pat = gen_seqdi_special (operands[0], sparc_compare_op0,
573 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
575 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, EQ);
576 emit_jump_insn (gen_sne (operands[0]));
581 if (gen_v9_scc (EQ, operands))
588 ;; ??? v9: Operand 0 needs a mode, so SImode was chosen.
589 ;; However, the code handles both SImode and DImode.
591 [(set (match_operand:SI 0 "intreg_operand" "")
592 (ne:SI (match_dup 1) (const_int 0)))]
595 if (GET_MODE (sparc_compare_op0) == SImode)
599 if (GET_MODE (operands[0]) == SImode)
600 pat = gen_snesi_special (operands[0], sparc_compare_op0,
602 else if (! TARGET_ARCH64)
605 pat = gen_snesi_special_extend (operands[0], sparc_compare_op0,
610 else if (GET_MODE (sparc_compare_op0) == DImode)
616 else if (GET_MODE (operands[0]) == SImode)
617 pat = gen_snedi_special_trunc (operands[0], sparc_compare_op0,
620 pat = gen_snedi_special (operands[0], sparc_compare_op0,
625 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
627 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, NE);
628 emit_jump_insn (gen_sne (operands[0]));
633 if (gen_v9_scc (NE, operands))
641 [(set (match_operand:SI 0 "intreg_operand" "")
642 (gt:SI (match_dup 1) (const_int 0)))]
645 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
647 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GT);
648 emit_jump_insn (gen_sne (operands[0]));
653 if (gen_v9_scc (GT, operands))
661 [(set (match_operand:SI 0 "intreg_operand" "")
662 (lt:SI (match_dup 1) (const_int 0)))]
665 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
667 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LT);
668 emit_jump_insn (gen_sne (operands[0]));
673 if (gen_v9_scc (LT, operands))
681 [(set (match_operand:SI 0 "intreg_operand" "")
682 (ge:SI (match_dup 1) (const_int 0)))]
685 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
687 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GE);
688 emit_jump_insn (gen_sne (operands[0]));
693 if (gen_v9_scc (GE, operands))
701 [(set (match_operand:SI 0 "intreg_operand" "")
702 (le:SI (match_dup 1) (const_int 0)))]
705 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
707 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LE);
708 emit_jump_insn (gen_sne (operands[0]));
713 if (gen_v9_scc (LE, operands))
720 (define_expand "sgtu"
721 [(set (match_operand:SI 0 "intreg_operand" "")
722 (gtu:SI (match_dup 1) (const_int 0)))]
729 /* We can do ltu easily, so if both operands are registers, swap them and
731 if ((GET_CODE (sparc_compare_op0) == REG
732 || GET_CODE (sparc_compare_op0) == SUBREG)
733 && (GET_CODE (sparc_compare_op1) == REG
734 || GET_CODE (sparc_compare_op1) == SUBREG))
736 tem = sparc_compare_op0;
737 sparc_compare_op0 = sparc_compare_op1;
738 sparc_compare_op1 = tem;
739 pat = gen_sltu (operands[0]);
748 if (gen_v9_scc (GTU, operands))
754 (define_expand "sltu"
755 [(set (match_operand:SI 0 "intreg_operand" "")
756 (ltu:SI (match_dup 1) (const_int 0)))]
761 if (gen_v9_scc (LTU, operands))
764 operands[1] = gen_compare_reg (LTU, sparc_compare_op0, sparc_compare_op1);
767 (define_expand "sgeu"
768 [(set (match_operand:SI 0 "intreg_operand" "")
769 (geu:SI (match_dup 1) (const_int 0)))]
774 if (gen_v9_scc (GEU, operands))
777 operands[1] = gen_compare_reg (GEU, sparc_compare_op0, sparc_compare_op1);
780 (define_expand "sleu"
781 [(set (match_operand:SI 0 "intreg_operand" "")
782 (leu:SI (match_dup 1) (const_int 0)))]
789 /* We can do geu easily, so if both operands are registers, swap them and
791 if ((GET_CODE (sparc_compare_op0) == REG
792 || GET_CODE (sparc_compare_op0) == SUBREG)
793 && (GET_CODE (sparc_compare_op1) == REG
794 || GET_CODE (sparc_compare_op1) == SUBREG))
796 tem = sparc_compare_op0;
797 sparc_compare_op0 = sparc_compare_op1;
798 sparc_compare_op1 = tem;
799 pat = gen_sgeu (operands[0]);
808 if (gen_v9_scc (LEU, operands))
814 ;; Now the DEFINE_INSNs for the scc cases.
816 ;; The SEQ and SNE patterns are special because they can be done
817 ;; without any branching and do not involve a COMPARE. We want
818 ;; them to always use the splitz below so the results can be
821 (define_insn_and_split "*snesi_zero"
822 [(set (match_operand:SI 0 "register_operand" "=r")
823 (ne:SI (match_operand:SI 1 "register_operand" "r")
825 (clobber (reg:CC 100))]
829 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
831 (set (match_dup 0) (ltu:SI (reg:CC 100) (const_int 0)))]
833 [(set_attr "length" "2")])
835 (define_insn_and_split "*neg_snesi_zero"
836 [(set (match_operand:SI 0 "register_operand" "=r")
837 (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
839 (clobber (reg:CC 100))]
843 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
845 (set (match_dup 0) (neg:SI (ltu:SI (reg:CC 100) (const_int 0))))]
847 [(set_attr "length" "2")])
849 (define_insn_and_split "*snesi_zero_extend"
850 [(set (match_operand:DI 0 "register_operand" "=r")
851 (ne:DI (match_operand:SI 1 "register_operand" "r")
853 (clobber (reg:CC 100))]
857 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (minus:SI (const_int 0)
860 (set (match_dup 0) (zero_extend:DI (plus:SI (plus:SI (const_int 0)
862 (ltu:SI (reg:CC_NOOV 100)
865 [(set_attr "length" "2")])
867 (define_insn_and_split "*snedi_zero"
868 [(set (match_operand:DI 0 "register_operand" "=&r")
869 (ne:DI (match_operand:DI 1 "register_operand" "r")
873 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
874 [(set (match_dup 0) (const_int 0))
875 (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
880 [(set_attr "length" "2")])
882 (define_insn_and_split "*neg_snedi_zero"
883 [(set (match_operand:DI 0 "register_operand" "=&r")
884 (neg:DI (ne:DI (match_operand:DI 1 "register_operand" "r")
888 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
889 [(set (match_dup 0) (const_int 0))
890 (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
895 [(set_attr "length" "2")])
897 (define_insn_and_split "*snedi_zero_trunc"
898 [(set (match_operand:SI 0 "register_operand" "=&r")
899 (ne:SI (match_operand:DI 1 "register_operand" "r")
903 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
904 [(set (match_dup 0) (const_int 0))
905 (set (match_dup 0) (if_then_else:SI (ne:DI (match_dup 1)
910 [(set_attr "length" "2")])
912 (define_insn_and_split "*seqsi_zero"
913 [(set (match_operand:SI 0 "register_operand" "=r")
914 (eq:SI (match_operand:SI 1 "register_operand" "r")
916 (clobber (reg:CC 100))]
920 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
922 (set (match_dup 0) (geu:SI (reg:CC 100) (const_int 0)))]
924 [(set_attr "length" "2")])
926 (define_insn_and_split "*neg_seqsi_zero"
927 [(set (match_operand:SI 0 "register_operand" "=r")
928 (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
930 (clobber (reg:CC 100))]
934 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
936 (set (match_dup 0) (neg:SI (geu:SI (reg:CC 100) (const_int 0))))]
938 [(set_attr "length" "2")])
940 (define_insn_and_split "*seqsi_zero_extend"
941 [(set (match_operand:DI 0 "register_operand" "=r")
942 (eq:DI (match_operand:SI 1 "register_operand" "r")
944 (clobber (reg:CC 100))]
948 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (minus:SI (const_int 0)
951 (set (match_dup 0) (zero_extend:DI (minus:SI (minus:SI (const_int 0)
953 (ltu:SI (reg:CC_NOOV 100)
956 [(set_attr "length" "2")])
958 (define_insn_and_split "*seqdi_zero"
959 [(set (match_operand:DI 0 "register_operand" "=&r")
960 (eq:DI (match_operand:DI 1 "register_operand" "r")
964 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
965 [(set (match_dup 0) (const_int 0))
966 (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
971 [(set_attr "length" "2")])
973 (define_insn_and_split "*neg_seqdi_zero"
974 [(set (match_operand:DI 0 "register_operand" "=&r")
975 (neg:DI (eq:DI (match_operand:DI 1 "register_operand" "r")
979 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
980 [(set (match_dup 0) (const_int 0))
981 (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
986 [(set_attr "length" "2")])
988 (define_insn_and_split "*seqdi_zero_trunc"
989 [(set (match_operand:SI 0 "register_operand" "=&r")
990 (eq:SI (match_operand:DI 1 "register_operand" "r")
994 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
995 [(set (match_dup 0) (const_int 0))
996 (set (match_dup 0) (if_then_else:SI (eq:DI (match_dup 1)
1001 [(set_attr "length" "2")])
1003 ;; We can also do (x + (i == 0)) and related, so put them in.
1004 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1007 (define_insn_and_split "*x_plus_i_ne_0"
1008 [(set (match_operand:SI 0 "register_operand" "=r")
1009 (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
1011 (match_operand:SI 2 "register_operand" "r")))
1012 (clobber (reg:CC 100))]
1016 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1018 (set (match_dup 0) (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1021 [(set_attr "length" "2")])
1023 (define_insn_and_split "*x_minus_i_ne_0"
1024 [(set (match_operand:SI 0 "register_operand" "=r")
1025 (minus:SI (match_operand:SI 2 "register_operand" "r")
1026 (ne:SI (match_operand:SI 1 "register_operand" "r")
1028 (clobber (reg:CC 100))]
1032 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1034 (set (match_dup 0) (minus:SI (match_dup 2)
1035 (ltu:SI (reg:CC 100) (const_int 0))))]
1037 [(set_attr "length" "2")])
1039 (define_insn_and_split "*x_plus_i_eq_0"
1040 [(set (match_operand:SI 0 "register_operand" "=r")
1041 (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
1043 (match_operand:SI 2 "register_operand" "r")))
1044 (clobber (reg:CC 100))]
1048 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1050 (set (match_dup 0) (plus:SI (geu:SI (reg:CC 100) (const_int 0))
1053 [(set_attr "length" "2")])
1055 (define_insn_and_split "*x_minus_i_eq_0"
1056 [(set (match_operand:SI 0 "register_operand" "=r")
1057 (minus:SI (match_operand:SI 2 "register_operand" "r")
1058 (eq:SI (match_operand:SI 1 "register_operand" "r")
1060 (clobber (reg:CC 100))]
1064 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1066 (set (match_dup 0) (minus:SI (match_dup 2)
1067 (geu:SI (reg:CC 100) (const_int 0))))]
1069 [(set_attr "length" "2")])
1071 ;; We can also do GEU and LTU directly, but these operate after a compare.
1072 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1075 (define_insn "*sltu_insn"
1076 [(set (match_operand:SI 0 "register_operand" "=r")
1077 (ltu:SI (reg:CC 100) (const_int 0)))]
1080 [(set_attr "type" "ialuX")])
1082 (define_insn "*neg_sltu_insn"
1083 [(set (match_operand:SI 0 "register_operand" "=r")
1084 (neg:SI (ltu:SI (reg:CC 100) (const_int 0))))]
1087 [(set_attr "type" "ialuX")])
1089 ;; ??? Combine should canonicalize these next two to the same pattern.
1090 (define_insn "*neg_sltu_minus_x"
1091 [(set (match_operand:SI 0 "register_operand" "=r")
1092 (minus:SI (neg:SI (ltu:SI (reg:CC 100) (const_int 0)))
1093 (match_operand:SI 1 "arith_operand" "rI")))]
1095 "subx\t%%g0, %1, %0"
1096 [(set_attr "type" "ialuX")])
1098 (define_insn "*neg_sltu_plus_x"
1099 [(set (match_operand:SI 0 "register_operand" "=r")
1100 (neg:SI (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1101 (match_operand:SI 1 "arith_operand" "rI"))))]
1103 "subx\t%%g0, %1, %0"
1104 [(set_attr "type" "ialuX")])
1106 (define_insn "*sgeu_insn"
1107 [(set (match_operand:SI 0 "register_operand" "=r")
1108 (geu:SI (reg:CC 100) (const_int 0)))]
1110 "subx\t%%g0, -1, %0"
1111 [(set_attr "type" "ialuX")])
1113 (define_insn "*neg_sgeu_insn"
1114 [(set (match_operand:SI 0 "register_operand" "=r")
1115 (neg:SI (geu:SI (reg:CC 100) (const_int 0))))]
1117 "addx\t%%g0, -1, %0"
1118 [(set_attr "type" "ialuX")])
1120 ;; We can also do (x + ((unsigned) i >= 0)) and related, so put them in.
1121 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1124 (define_insn "*sltu_plus_x"
1125 [(set (match_operand:SI 0 "register_operand" "=r")
1126 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1127 (match_operand:SI 1 "arith_operand" "rI")))]
1129 "addx\t%%g0, %1, %0"
1130 [(set_attr "type" "ialuX")])
1132 (define_insn "*sltu_plus_x_plus_y"
1133 [(set (match_operand:SI 0 "register_operand" "=r")
1134 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1135 (plus:SI (match_operand:SI 1 "arith_operand" "%r")
1136 (match_operand:SI 2 "arith_operand" "rI"))))]
1139 [(set_attr "type" "ialuX")])
1141 (define_insn "*x_minus_sltu"
1142 [(set (match_operand:SI 0 "register_operand" "=r")
1143 (minus:SI (match_operand:SI 1 "register_operand" "r")
1144 (ltu:SI (reg:CC 100) (const_int 0))))]
1147 [(set_attr "type" "ialuX")])
1149 ;; ??? Combine should canonicalize these next two to the same pattern.
1150 (define_insn "*x_minus_y_minus_sltu"
1151 [(set (match_operand:SI 0 "register_operand" "=r")
1152 (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
1153 (match_operand:SI 2 "arith_operand" "rI"))
1154 (ltu:SI (reg:CC 100) (const_int 0))))]
1157 [(set_attr "type" "ialuX")])
1159 (define_insn "*x_minus_sltu_plus_y"
1160 [(set (match_operand:SI 0 "register_operand" "=r")
1161 (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
1162 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1163 (match_operand:SI 2 "arith_operand" "rI"))))]
1166 [(set_attr "type" "ialuX")])
1168 (define_insn "*sgeu_plus_x"
1169 [(set (match_operand:SI 0 "register_operand" "=r")
1170 (plus:SI (geu:SI (reg:CC 100) (const_int 0))
1171 (match_operand:SI 1 "register_operand" "r")))]
1174 [(set_attr "type" "ialuX")])
1176 (define_insn "*x_minus_sgeu"
1177 [(set (match_operand:SI 0 "register_operand" "=r")
1178 (minus:SI (match_operand:SI 1 "register_operand" "r")
1179 (geu:SI (reg:CC 100) (const_int 0))))]
1182 [(set_attr "type" "ialuX")])
1185 [(set (match_operand:SI 0 "register_operand" "")
1186 (match_operator:SI 2 "noov_compare_op"
1187 [(match_operand 1 "icc_or_fcc_reg_operand" "")
1189 ;; 32 bit LTU/GEU are better implemented using addx/subx
1190 "TARGET_V9 && REGNO (operands[1]) == SPARC_ICC_REG
1191 && (GET_MODE (operands[1]) == CCXmode
1192 || (GET_CODE (operands[2]) != LTU && GET_CODE (operands[2]) != GEU))"
1193 [(set (match_dup 0) (const_int 0))
1195 (if_then_else:SI (match_op_dup:SI 2 [(match_dup 1) (const_int 0)])
1201 ;; These control RTL generation for conditional jump insns
1203 ;; The quad-word fp compare library routines all return nonzero to indicate
1204 ;; true, which is different from the equivalent libgcc routines, so we must
1205 ;; handle them specially here.
1207 (define_expand "beq"
1209 (if_then_else (eq (match_dup 1) (const_int 0))
1210 (label_ref (match_operand 0 "" ""))
1214 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1215 && GET_CODE (sparc_compare_op0) == REG
1216 && GET_MODE (sparc_compare_op0) == DImode)
1218 emit_v9_brxx_insn (EQ, sparc_compare_op0, operands[0]);
1221 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1223 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, EQ);
1224 emit_jump_insn (gen_bne (operands[0]));
1227 operands[1] = gen_compare_reg (EQ, sparc_compare_op0, sparc_compare_op1);
1230 (define_expand "bne"
1232 (if_then_else (ne (match_dup 1) (const_int 0))
1233 (label_ref (match_operand 0 "" ""))
1237 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1238 && GET_CODE (sparc_compare_op0) == REG
1239 && GET_MODE (sparc_compare_op0) == DImode)
1241 emit_v9_brxx_insn (NE, sparc_compare_op0, operands[0]);
1244 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1246 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, NE);
1247 emit_jump_insn (gen_bne (operands[0]));
1250 operands[1] = gen_compare_reg (NE, sparc_compare_op0, sparc_compare_op1);
1253 (define_expand "bgt"
1255 (if_then_else (gt (match_dup 1) (const_int 0))
1256 (label_ref (match_operand 0 "" ""))
1260 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1261 && GET_CODE (sparc_compare_op0) == REG
1262 && GET_MODE (sparc_compare_op0) == DImode)
1264 emit_v9_brxx_insn (GT, sparc_compare_op0, operands[0]);
1267 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1269 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GT);
1270 emit_jump_insn (gen_bne (operands[0]));
1273 operands[1] = gen_compare_reg (GT, sparc_compare_op0, sparc_compare_op1);
1276 (define_expand "bgtu"
1278 (if_then_else (gtu (match_dup 1) (const_int 0))
1279 (label_ref (match_operand 0 "" ""))
1283 operands[1] = gen_compare_reg (GTU, sparc_compare_op0, sparc_compare_op1);
1286 (define_expand "blt"
1288 (if_then_else (lt (match_dup 1) (const_int 0))
1289 (label_ref (match_operand 0 "" ""))
1293 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1294 && GET_CODE (sparc_compare_op0) == REG
1295 && GET_MODE (sparc_compare_op0) == DImode)
1297 emit_v9_brxx_insn (LT, sparc_compare_op0, operands[0]);
1300 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1302 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LT);
1303 emit_jump_insn (gen_bne (operands[0]));
1306 operands[1] = gen_compare_reg (LT, sparc_compare_op0, sparc_compare_op1);
1309 (define_expand "bltu"
1311 (if_then_else (ltu (match_dup 1) (const_int 0))
1312 (label_ref (match_operand 0 "" ""))
1316 operands[1] = gen_compare_reg (LTU, sparc_compare_op0, sparc_compare_op1);
1319 (define_expand "bge"
1321 (if_then_else (ge (match_dup 1) (const_int 0))
1322 (label_ref (match_operand 0 "" ""))
1326 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1327 && GET_CODE (sparc_compare_op0) == REG
1328 && GET_MODE (sparc_compare_op0) == DImode)
1330 emit_v9_brxx_insn (GE, sparc_compare_op0, operands[0]);
1333 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1335 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GE);
1336 emit_jump_insn (gen_bne (operands[0]));
1339 operands[1] = gen_compare_reg (GE, sparc_compare_op0, sparc_compare_op1);
1342 (define_expand "bgeu"
1344 (if_then_else (geu (match_dup 1) (const_int 0))
1345 (label_ref (match_operand 0 "" ""))
1349 operands[1] = gen_compare_reg (GEU, sparc_compare_op0, sparc_compare_op1);
1352 (define_expand "ble"
1354 (if_then_else (le (match_dup 1) (const_int 0))
1355 (label_ref (match_operand 0 "" ""))
1359 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1360 && GET_CODE (sparc_compare_op0) == REG
1361 && GET_MODE (sparc_compare_op0) == DImode)
1363 emit_v9_brxx_insn (LE, sparc_compare_op0, operands[0]);
1366 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1368 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LE);
1369 emit_jump_insn (gen_bne (operands[0]));
1372 operands[1] = gen_compare_reg (LE, sparc_compare_op0, sparc_compare_op1);
1375 (define_expand "bleu"
1377 (if_then_else (leu (match_dup 1) (const_int 0))
1378 (label_ref (match_operand 0 "" ""))
1382 operands[1] = gen_compare_reg (LEU, sparc_compare_op0, sparc_compare_op1);
1385 (define_expand "bunordered"
1387 (if_then_else (unordered (match_dup 1) (const_int 0))
1388 (label_ref (match_operand 0 "" ""))
1392 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1394 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1,
1396 emit_jump_insn (gen_beq (operands[0]));
1399 operands[1] = gen_compare_reg (UNORDERED, sparc_compare_op0,
1403 (define_expand "bordered"
1405 (if_then_else (ordered (match_dup 1) (const_int 0))
1406 (label_ref (match_operand 0 "" ""))
1410 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1412 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, ORDERED);
1413 emit_jump_insn (gen_bne (operands[0]));
1416 operands[1] = gen_compare_reg (ORDERED, sparc_compare_op0,
1420 (define_expand "bungt"
1422 (if_then_else (ungt (match_dup 1) (const_int 0))
1423 (label_ref (match_operand 0 "" ""))
1427 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1429 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNGT);
1430 emit_jump_insn (gen_bgt (operands[0]));
1433 operands[1] = gen_compare_reg (UNGT, sparc_compare_op0, sparc_compare_op1);
1436 (define_expand "bunlt"
1438 (if_then_else (unlt (match_dup 1) (const_int 0))
1439 (label_ref (match_operand 0 "" ""))
1443 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1445 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNLT);
1446 emit_jump_insn (gen_bne (operands[0]));
1449 operands[1] = gen_compare_reg (UNLT, sparc_compare_op0, sparc_compare_op1);
1452 (define_expand "buneq"
1454 (if_then_else (uneq (match_dup 1) (const_int 0))
1455 (label_ref (match_operand 0 "" ""))
1459 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1461 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNEQ);
1462 emit_jump_insn (gen_beq (operands[0]));
1465 operands[1] = gen_compare_reg (UNEQ, sparc_compare_op0, sparc_compare_op1);
1468 (define_expand "bunge"
1470 (if_then_else (unge (match_dup 1) (const_int 0))
1471 (label_ref (match_operand 0 "" ""))
1475 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1477 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNGE);
1478 emit_jump_insn (gen_bne (operands[0]));
1481 operands[1] = gen_compare_reg (UNGE, sparc_compare_op0, sparc_compare_op1);
1484 (define_expand "bunle"
1486 (if_then_else (unle (match_dup 1) (const_int 0))
1487 (label_ref (match_operand 0 "" ""))
1491 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1493 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNLE);
1494 emit_jump_insn (gen_bne (operands[0]));
1497 operands[1] = gen_compare_reg (UNLE, sparc_compare_op0, sparc_compare_op1);
1500 (define_expand "bltgt"
1502 (if_then_else (ltgt (match_dup 1) (const_int 0))
1503 (label_ref (match_operand 0 "" ""))
1507 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1509 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LTGT);
1510 emit_jump_insn (gen_bne (operands[0]));
1513 operands[1] = gen_compare_reg (LTGT, sparc_compare_op0, sparc_compare_op1);
1516 ;; Now match both normal and inverted jump.
1518 ;; XXX fpcmp nop braindamage
1519 (define_insn "*normal_branch"
1521 (if_then_else (match_operator 0 "noov_compare_op"
1522 [(reg 100) (const_int 0)])
1523 (label_ref (match_operand 1 "" ""))
1527 return output_cbranch (operands[0], operands[1], 1, 0,
1528 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1529 ! final_sequence, insn);
1531 [(set_attr "type" "branch")
1532 (set_attr "branch_type" "icc")])
1534 ;; XXX fpcmp nop braindamage
1535 (define_insn "*inverted_branch"
1537 (if_then_else (match_operator 0 "noov_compare_op"
1538 [(reg 100) (const_int 0)])
1540 (label_ref (match_operand 1 "" ""))))]
1543 return output_cbranch (operands[0], operands[1], 1, 1,
1544 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1545 ! final_sequence, insn);
1547 [(set_attr "type" "branch")
1548 (set_attr "branch_type" "icc")])
1550 ;; XXX fpcmp nop braindamage
1551 (define_insn "*normal_fp_branch"
1553 (if_then_else (match_operator 1 "comparison_operator"
1554 [(match_operand:CCFP 0 "fcc_reg_operand" "c")
1556 (label_ref (match_operand 2 "" ""))
1560 return output_cbranch (operands[1], operands[2], 2, 0,
1561 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1562 ! final_sequence, insn);
1564 [(set_attr "type" "branch")
1565 (set_attr "branch_type" "fcc")])
1567 ;; XXX fpcmp nop braindamage
1568 (define_insn "*inverted_fp_branch"
1570 (if_then_else (match_operator 1 "comparison_operator"
1571 [(match_operand:CCFP 0 "fcc_reg_operand" "c")
1574 (label_ref (match_operand 2 "" ""))))]
1577 return output_cbranch (operands[1], operands[2], 2, 1,
1578 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1579 ! final_sequence, insn);
1581 [(set_attr "type" "branch")
1582 (set_attr "branch_type" "fcc")])
1584 ;; XXX fpcmp nop braindamage
1585 (define_insn "*normal_fpe_branch"
1587 (if_then_else (match_operator 1 "comparison_operator"
1588 [(match_operand:CCFPE 0 "fcc_reg_operand" "c")
1590 (label_ref (match_operand 2 "" ""))
1594 return output_cbranch (operands[1], operands[2], 2, 0,
1595 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1596 ! final_sequence, insn);
1598 [(set_attr "type" "branch")
1599 (set_attr "branch_type" "fcc")])
1601 ;; XXX fpcmp nop braindamage
1602 (define_insn "*inverted_fpe_branch"
1604 (if_then_else (match_operator 1 "comparison_operator"
1605 [(match_operand:CCFPE 0 "fcc_reg_operand" "c")
1608 (label_ref (match_operand 2 "" ""))))]
1611 return output_cbranch (operands[1], operands[2], 2, 1,
1612 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1613 ! final_sequence, insn);
1615 [(set_attr "type" "branch")
1616 (set_attr "branch_type" "fcc")])
1618 ;; SPARC V9-specific jump insns. None of these are guaranteed to be
1619 ;; in the architecture.
1621 ;; There are no 32 bit brreg insns.
1624 (define_insn "*normal_int_branch_sp64"
1626 (if_then_else (match_operator 0 "v9_regcmp_op"
1627 [(match_operand:DI 1 "register_operand" "r")
1629 (label_ref (match_operand 2 "" ""))
1633 return output_v9branch (operands[0], operands[2], 1, 2, 0,
1634 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1635 ! final_sequence, insn);
1637 [(set_attr "type" "branch")
1638 (set_attr "branch_type" "reg")])
1641 (define_insn "*inverted_int_branch_sp64"
1643 (if_then_else (match_operator 0 "v9_regcmp_op"
1644 [(match_operand:DI 1 "register_operand" "r")
1647 (label_ref (match_operand 2 "" ""))))]
1650 return output_v9branch (operands[0], operands[2], 1, 2, 1,
1651 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1652 ! final_sequence, insn);
1654 [(set_attr "type" "branch")
1655 (set_attr "branch_type" "reg")])
1657 ;; Load program counter insns.
1659 (define_insn "get_pc"
1660 [(clobber (reg:SI 15))
1661 (set (match_operand 0 "register_operand" "=r")
1662 (unspec [(match_operand 1 "" "") (match_operand 2 "" "")] UNSPEC_GET_PC))]
1663 "flag_pic && REGNO (operands[0]) == 23"
1664 "sethi\t%%hi(%a1-4), %0\n\tcall\t%a2\n\tadd\t%0, %%lo(%a1+4), %0"
1665 [(set_attr "type" "multi")
1666 (set_attr "length" "3")])
1669 ;; Move instructions
1671 (define_expand "movqi"
1672 [(set (match_operand:QI 0 "general_operand" "")
1673 (match_operand:QI 1 "general_operand" ""))]
1676 /* Working with CONST_INTs is easier, so convert
1677 a double if needed. */
1678 if (GET_CODE (operands[1]) == CONST_DOUBLE)
1680 operands[1] = GEN_INT (trunc_int_for_mode
1681 (CONST_DOUBLE_LOW (operands[1]), QImode));
1684 /* Handle sets of MEM first. */
1685 if (GET_CODE (operands[0]) == MEM)
1687 if (reg_or_0_operand (operands[1], QImode))
1690 if (! reload_in_progress)
1692 operands[0] = validize_mem (operands[0]);
1693 operands[1] = force_reg (QImode, operands[1]);
1697 /* Fixup TLS cases. */
1698 if (tls_symbolic_operand (operands [1]))
1699 operands[1] = legitimize_tls_address (operands[1]);
1701 /* Fixup PIC cases. */
1704 if (CONSTANT_P (operands[1])
1705 && pic_address_needs_scratch (operands[1]))
1706 operands[1] = legitimize_pic_address (operands[1], QImode, 0);
1708 if (symbolic_operand (operands[1], QImode))
1710 operands[1] = legitimize_pic_address (operands[1],
1712 (reload_in_progress ?
1719 /* All QI constants require only one insn, so proceed. */
1725 (define_insn "*movqi_insn"
1726 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m")
1727 (match_operand:QI 1 "input_operand" "rI,m,rJ"))]
1728 "(register_operand (operands[0], QImode)
1729 || reg_or_0_operand (operands[1], QImode))"
1734 [(set_attr "type" "*,load,store")
1735 (set_attr "us3load_type" "*,3cycle,*")])
1737 (define_expand "movhi"
1738 [(set (match_operand:HI 0 "general_operand" "")
1739 (match_operand:HI 1 "general_operand" ""))]
1742 /* Working with CONST_INTs is easier, so convert
1743 a double if needed. */
1744 if (GET_CODE (operands[1]) == CONST_DOUBLE)
1745 operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
1747 /* Handle sets of MEM first. */
1748 if (GET_CODE (operands[0]) == MEM)
1750 if (reg_or_0_operand (operands[1], HImode))
1753 if (! reload_in_progress)
1755 operands[0] = validize_mem (operands[0]);
1756 operands[1] = force_reg (HImode, operands[1]);
1760 /* Fixup TLS cases. */
1761 if (tls_symbolic_operand (operands [1]))
1762 operands[1] = legitimize_tls_address (operands[1]);
1764 /* Fixup PIC cases. */
1767 if (CONSTANT_P (operands[1])
1768 && pic_address_needs_scratch (operands[1]))
1769 operands[1] = legitimize_pic_address (operands[1], HImode, 0);
1771 if (symbolic_operand (operands[1], HImode))
1773 operands[1] = legitimize_pic_address (operands[1],
1775 (reload_in_progress ?
1782 /* This makes sure we will not get rematched due to splittage. */
1783 if (! CONSTANT_P (operands[1]) || input_operand (operands[1], HImode))
1785 else if (CONSTANT_P (operands[1])
1786 && GET_CODE (operands[1]) != HIGH
1787 && GET_CODE (operands[1]) != LO_SUM)
1789 sparc_emit_set_const32 (operands[0], operands[1]);
1796 (define_insn "*movhi_const64_special"
1797 [(set (match_operand:HI 0 "register_operand" "=r")
1798 (match_operand:HI 1 "const64_high_operand" ""))]
1800 "sethi\t%%hi(%a1), %0")
1802 (define_insn "*movhi_insn"
1803 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1804 (match_operand:HI 1 "input_operand" "rI,K,m,rJ"))]
1805 "(register_operand (operands[0], HImode)
1806 || reg_or_0_operand (operands[1], HImode))"
1809 sethi\t%%hi(%a1), %0
1812 [(set_attr "type" "*,*,load,store")
1813 (set_attr "us3load_type" "*,*,3cycle,*")])
1815 ;; We always work with constants here.
1816 (define_insn "*movhi_lo_sum"
1817 [(set (match_operand:HI 0 "register_operand" "=r")
1818 (ior:HI (match_operand:HI 1 "register_operand" "%r")
1819 (match_operand:HI 2 "small_int" "I")))]
1823 (define_expand "movsi"
1824 [(set (match_operand:SI 0 "general_operand" "")
1825 (match_operand:SI 1 "general_operand" ""))]
1828 /* Working with CONST_INTs is easier, so convert
1829 a double if needed. */
1830 if (GET_CODE (operands[1]) == CONST_DOUBLE)
1831 operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
1833 /* Handle sets of MEM first. */
1834 if (GET_CODE (operands[0]) == MEM)
1836 if (reg_or_0_operand (operands[1], SImode))
1839 if (! reload_in_progress)
1841 operands[0] = validize_mem (operands[0]);
1842 operands[1] = force_reg (SImode, operands[1]);
1846 /* Fixup TLS cases. */
1847 if (tls_symbolic_operand (operands [1]))
1848 operands[1] = legitimize_tls_address (operands[1]);
1850 /* Fixup PIC cases. */
1853 if (CONSTANT_P (operands[1])
1854 && pic_address_needs_scratch (operands[1]))
1855 operands[1] = legitimize_pic_address (operands[1], SImode, 0);
1857 if (GET_CODE (operands[1]) == LABEL_REF)
1860 emit_insn (gen_movsi_pic_label_ref (operands[0], operands[1]));
1864 if (symbolic_operand (operands[1], SImode))
1866 operands[1] = legitimize_pic_address (operands[1],
1868 (reload_in_progress ?
1875 /* If we are trying to toss an integer constant into the
1876 FPU registers, force it into memory. */
1877 if (GET_CODE (operands[0]) == REG
1878 && REGNO (operands[0]) >= SPARC_FIRST_FP_REG
1879 && REGNO (operands[0]) <= SPARC_LAST_V9_FP_REG
1880 && CONSTANT_P (operands[1]))
1881 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
1884 /* This makes sure we will not get rematched due to splittage. */
1885 if (! CONSTANT_P (operands[1]) || input_operand (operands[1], SImode))
1887 else if (CONSTANT_P (operands[1])
1888 && GET_CODE (operands[1]) != HIGH
1889 && GET_CODE (operands[1]) != LO_SUM)
1891 sparc_emit_set_const32 (operands[0], operands[1]);
1898 ;; This is needed to show CSE exactly which bits are set
1899 ;; in a 64-bit register by sethi instructions.
1900 (define_insn "*movsi_const64_special"
1901 [(set (match_operand:SI 0 "register_operand" "=r")
1902 (match_operand:SI 1 "const64_high_operand" ""))]
1904 "sethi\t%%hi(%a1), %0")
1906 (define_insn "*movsi_insn"
1907 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,f,r,r,r,f,m,m,d")
1908 (match_operand:SI 1 "input_operand" "rI,!f,K,J,m,!m,rJ,!f,J"))]
1909 "(register_operand (operands[0], SImode)
1910 || reg_or_0_operand (operands[1], SImode))"
1914 sethi\t%%hi(%a1), %0
1921 [(set_attr "type" "*,fpmove,*,*,load,fpload,store,fpstore,fga")])
1923 (define_insn "*movsi_lo_sum"
1924 [(set (match_operand:SI 0 "register_operand" "=r")
1925 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1926 (match_operand:SI 2 "immediate_operand" "in")))]
1928 "or\t%1, %%lo(%a2), %0")
1930 (define_insn "*movsi_high"
1931 [(set (match_operand:SI 0 "register_operand" "=r")
1932 (high:SI (match_operand:SI 1 "immediate_operand" "in")))]
1934 "sethi\t%%hi(%a1), %0")
1936 ;; The next two patterns must wrap the SYMBOL_REF in an UNSPEC
1937 ;; so that CSE won't optimize the address computation away.
1938 (define_insn "movsi_lo_sum_pic"
1939 [(set (match_operand:SI 0 "register_operand" "=r")
1940 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1941 (unspec:SI [(match_operand:SI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
1943 "or\t%1, %%lo(%a2), %0")
1945 (define_insn "movsi_high_pic"
1946 [(set (match_operand:SI 0 "register_operand" "=r")
1947 (high:SI (unspec:SI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
1948 "flag_pic && check_pic (1)"
1949 "sethi\t%%hi(%a1), %0")
1951 (define_expand "movsi_pic_label_ref"
1952 [(set (match_dup 3) (high:SI
1953 (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
1954 (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1955 (set (match_dup 4) (lo_sum:SI (match_dup 3)
1956 (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1957 (set (match_operand:SI 0 "register_operand" "=r")
1958 (minus:SI (match_dup 5) (match_dup 4)))]
1961 current_function_uses_pic_offset_table = 1;
1962 operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
1965 operands[3] = operands[0];
1966 operands[4] = operands[0];
1970 operands[3] = gen_reg_rtx (SImode);
1971 operands[4] = gen_reg_rtx (SImode);
1973 operands[5] = pic_offset_table_rtx;
1976 (define_insn "*movsi_high_pic_label_ref"
1977 [(set (match_operand:SI 0 "register_operand" "=r")
1979 (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
1980 (match_operand:SI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1982 "sethi\t%%hi(%a2-(%a1-.)), %0")
1984 (define_insn "*movsi_lo_sum_pic_label_ref"
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 "label_ref_operand" "")
1988 (match_operand:SI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1990 "or\t%1, %%lo(%a3-(%a2-.)), %0")
1992 (define_expand "movdi"
1993 [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand" "")
1994 (match_operand:DI 1 "general_operand" ""))]
1997 /* Where possible, convert CONST_DOUBLE into a CONST_INT. */
1998 if (GET_CODE (operands[1]) == CONST_DOUBLE
1999 #if HOST_BITS_PER_WIDE_INT == 32
2000 && ((CONST_DOUBLE_HIGH (operands[1]) == 0
2001 && (CONST_DOUBLE_LOW (operands[1]) & 0x80000000) == 0)
2002 || (CONST_DOUBLE_HIGH (operands[1]) == (HOST_WIDE_INT) 0xffffffff
2003 && (CONST_DOUBLE_LOW (operands[1]) & 0x80000000) != 0))
2006 operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
2008 /* Handle MEM cases first. */
2009 if (GET_CODE (operands[0]) == MEM)
2011 /* If it's a REG, we can always do it.
2012 The const zero case is more complex, on v9
2013 we can always perform it. */
2014 if (register_operand (operands[1], DImode)
2016 && (operands[1] == const0_rtx)))
2019 if (! reload_in_progress)
2021 operands[0] = validize_mem (operands[0]);
2022 operands[1] = force_reg (DImode, operands[1]);
2026 /* Fixup TLS cases. */
2027 if (tls_symbolic_operand (operands [1]))
2028 operands[1] = legitimize_tls_address (operands[1]);
2032 if (CONSTANT_P (operands[1])
2033 && pic_address_needs_scratch (operands[1]))
2034 operands[1] = legitimize_pic_address (operands[1], DImode, 0);
2036 if (GET_CODE (operands[1]) == LABEL_REF)
2038 if (! TARGET_ARCH64)
2040 emit_insn (gen_movdi_pic_label_ref (operands[0], operands[1]));
2044 if (symbolic_operand (operands[1], DImode))
2046 operands[1] = legitimize_pic_address (operands[1],
2048 (reload_in_progress ?
2055 /* If we are trying to toss an integer constant into the
2056 FPU registers, force it into memory. */
2057 if (GET_CODE (operands[0]) == REG
2058 && REGNO (operands[0]) >= SPARC_FIRST_FP_REG
2059 && REGNO (operands[0]) <= SPARC_LAST_V9_FP_REG
2060 && CONSTANT_P (operands[1]))
2061 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
2064 /* This makes sure we will not get rematched due to splittage. */
2065 if (! CONSTANT_P (operands[1]) || input_operand (operands[1], DImode))
2067 else if (TARGET_ARCH64
2068 && CONSTANT_P (operands[1])
2069 && GET_CODE (operands[1]) != HIGH
2070 && GET_CODE (operands[1]) != LO_SUM)
2072 sparc_emit_set_const64 (operands[0], operands[1]);
2080 ;; Be careful, fmovd does not exist when !v9.
2081 ;; We match MEM moves directly when we have correct even
2082 ;; numbered registers, but fall into splits otherwise.
2083 ;; The constraint ordering here is really important to
2084 ;; avoid insane problems in reload, especially for patterns
2087 ;; (set (mem:DI (plus:SI (reg:SI 30 %fp)
2088 ;; (const_int -5016)))
2092 (define_insn "*movdi_insn_sp32_v9"
2093 [(set (match_operand:DI 0 "nonimmediate_operand"
2094 "=T,o,T,U,o,r,r,r,?T,?f,?f,?o,?e,?e,?W")
2095 (match_operand:DI 1 "input_operand"
2096 " J,J,U,T,r,o,i,r, f, T, o, f, e, W, e"))]
2097 "! TARGET_ARCH64 && TARGET_V9
2098 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2115 [(set_attr "type" "store,store,store,load,*,*,*,*,fpstore,fpload,*,*,fpmove,fpload,fpstore")
2116 (set_attr "length" "*,2,*,*,2,2,2,2,*,*,2,2,*,*,*")
2117 (set_attr "fptype" "*,*,*,*,*,*,*,*,*,*,*,*,double,*,*")])
2119 (define_insn "*movdi_insn_sp32"
2120 [(set (match_operand:DI 0 "nonimmediate_operand"
2121 "=o,T,U,o,r,r,r,?T,?f,?f,?o,?f")
2122 (match_operand:DI 1 "input_operand"
2123 " J,U,T,r,o,i,r, f, T, o, f, f"))]
2125 && (register_operand (operands[0], DImode)
2126 || register_operand (operands[1], DImode))"
2140 [(set_attr "type" "store,store,load,*,*,*,*,fpstore,fpload,*,*,*")
2141 (set_attr "length" "2,*,*,2,2,2,2,*,*,2,2,2")])
2143 ;; The following are generated by sparc_emit_set_const64
2144 (define_insn "*movdi_sp64_dbl"
2145 [(set (match_operand:DI 0 "register_operand" "=r")
2146 (match_operand:DI 1 "const64_operand" ""))]
2148 && HOST_BITS_PER_WIDE_INT != 64)"
2151 ;; This is needed to show CSE exactly which bits are set
2152 ;; in a 64-bit register by sethi instructions.
2153 (define_insn "*movdi_const64_special"
2154 [(set (match_operand:DI 0 "register_operand" "=r")
2155 (match_operand:DI 1 "const64_high_operand" ""))]
2157 "sethi\t%%hi(%a1), %0")
2159 (define_insn "*movdi_insn_sp64_novis"
2160 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,m,?e,?e,?W")
2161 (match_operand:DI 1 "input_operand" "rI,N,J,m,rJ,e,W,e"))]
2162 "TARGET_ARCH64 && ! TARGET_VIS
2163 && (register_operand (operands[0], DImode)
2164 || reg_or_0_operand (operands[1], DImode))"
2167 sethi\t%%hi(%a1), %0
2174 [(set_attr "type" "*,*,*,load,store,fpmove,fpload,fpstore")
2175 (set_attr "fptype" "*,*,*,*,*,double,*,*")])
2177 (define_insn "*movdi_insn_sp64_vis"
2178 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,m,?e,?e,?W,b")
2179 (match_operand:DI 1 "input_operand" "rI,N,J,m,rJ,e,W,e,J"))]
2180 "TARGET_ARCH64 && TARGET_VIS &&
2181 (register_operand (operands[0], DImode)
2182 || reg_or_0_operand (operands[1], DImode))"
2185 sethi\t%%hi(%a1), %0
2193 [(set_attr "type" "*,*,*,load,store,fpmove,fpload,fpstore,fga")
2194 (set_attr "fptype" "*,*,*,*,*,double,*,*,double")])
2196 (define_expand "movdi_pic_label_ref"
2197 [(set (match_dup 3) (high:DI
2198 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
2199 (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
2200 (set (match_dup 4) (lo_sum:DI (match_dup 3)
2201 (unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
2202 (set (match_operand:DI 0 "register_operand" "=r")
2203 (minus:DI (match_dup 5) (match_dup 4)))]
2204 "TARGET_ARCH64 && flag_pic"
2206 current_function_uses_pic_offset_table = 1;
2207 operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
2210 operands[3] = operands[0];
2211 operands[4] = operands[0];
2215 operands[3] = gen_reg_rtx (DImode);
2216 operands[4] = gen_reg_rtx (DImode);
2218 operands[5] = pic_offset_table_rtx;
2221 (define_insn "*movdi_high_pic_label_ref"
2222 [(set (match_operand:DI 0 "register_operand" "=r")
2224 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
2225 (match_operand:DI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
2226 "TARGET_ARCH64 && flag_pic"
2227 "sethi\t%%hi(%a2-(%a1-.)), %0")
2229 (define_insn "*movdi_lo_sum_pic_label_ref"
2230 [(set (match_operand:DI 0 "register_operand" "=r")
2231 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2232 (unspec:DI [(match_operand:DI 2 "label_ref_operand" "")
2233 (match_operand:DI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
2234 "TARGET_ARCH64 && flag_pic"
2235 "or\t%1, %%lo(%a3-(%a2-.)), %0")
2237 ;; SPARC-v9 code model support insns. See sparc_emit_set_symbolic_const64
2238 ;; in sparc.c to see what is going on here... PIC stuff comes first.
2240 (define_insn "movdi_lo_sum_pic"
2241 [(set (match_operand:DI 0 "register_operand" "=r")
2242 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2243 (unspec:DI [(match_operand:DI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
2244 "TARGET_ARCH64 && flag_pic"
2245 "or\t%1, %%lo(%a2), %0")
2247 (define_insn "movdi_high_pic"
2248 [(set (match_operand:DI 0 "register_operand" "=r")
2249 (high:DI (unspec:DI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
2250 "TARGET_ARCH64 && flag_pic && check_pic (1)"
2251 "sethi\t%%hi(%a1), %0")
2253 (define_insn "*sethi_di_medlow_embmedany_pic"
2254 [(set (match_operand:DI 0 "register_operand" "=r")
2255 (high:DI (match_operand:DI 1 "sp64_medium_pic_operand" "")))]
2256 "(TARGET_CM_MEDLOW || TARGET_CM_EMBMEDANY) && check_pic (1)"
2257 "sethi\t%%hi(%a1), %0")
2259 (define_insn "*sethi_di_medlow"
2260 [(set (match_operand:DI 0 "register_operand" "=r")
2261 (high:DI (match_operand:DI 1 "symbolic_operand" "")))]
2262 "TARGET_CM_MEDLOW && check_pic (1)"
2263 "sethi\t%%hi(%a1), %0")
2265 (define_insn "*losum_di_medlow"
2266 [(set (match_operand:DI 0 "register_operand" "=r")
2267 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2268 (match_operand:DI 2 "symbolic_operand" "")))]
2270 "or\t%1, %%lo(%a2), %0")
2272 (define_insn "seth44"
2273 [(set (match_operand:DI 0 "register_operand" "=r")
2274 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETH44)))]
2276 "sethi\t%%h44(%a1), %0")
2278 (define_insn "setm44"
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 "symbolic_operand" "")] UNSPEC_SETM44)))]
2283 "or\t%1, %%m44(%a2), %0")
2285 (define_insn "setl44"
2286 [(set (match_operand:DI 0 "register_operand" "=r")
2287 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2288 (match_operand:DI 2 "symbolic_operand" "")))]
2290 "or\t%1, %%l44(%a2), %0")
2292 (define_insn "sethh"
2293 [(set (match_operand:DI 0 "register_operand" "=r")
2294 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETHH)))]
2296 "sethi\t%%hh(%a1), %0")
2298 (define_insn "setlm"
2299 [(set (match_operand:DI 0 "register_operand" "=r")
2300 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETLM)))]
2302 "sethi\t%%lm(%a1), %0")
2304 (define_insn "sethm"
2305 [(set (match_operand:DI 0 "register_operand" "=r")
2306 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2307 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_EMB_SETHM)))]
2309 "or\t%1, %%hm(%a2), %0")
2311 (define_insn "setlo"
2312 [(set (match_operand:DI 0 "register_operand" "=r")
2313 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2314 (match_operand:DI 2 "symbolic_operand" "")))]
2316 "or\t%1, %%lo(%a2), %0")
2318 (define_insn "embmedany_sethi"
2319 [(set (match_operand:DI 0 "register_operand" "=r")
2320 (high:DI (unspec:DI [(match_operand:DI 1 "data_segment_operand" "")] UNSPEC_EMB_HISUM)))]
2321 "TARGET_CM_EMBMEDANY && check_pic (1)"
2322 "sethi\t%%hi(%a1), %0")
2324 (define_insn "embmedany_losum"
2325 [(set (match_operand:DI 0 "register_operand" "=r")
2326 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2327 (match_operand:DI 2 "data_segment_operand" "")))]
2328 "TARGET_CM_EMBMEDANY"
2329 "add\t%1, %%lo(%a2), %0")
2331 (define_insn "embmedany_brsum"
2332 [(set (match_operand:DI 0 "register_operand" "=r")
2333 (unspec:DI [(match_operand:DI 1 "register_operand" "r")] UNSPEC_EMB_HISUM))]
2334 "TARGET_CM_EMBMEDANY"
2337 (define_insn "embmedany_textuhi"
2338 [(set (match_operand:DI 0 "register_operand" "=r")
2339 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTUHI)))]
2340 "TARGET_CM_EMBMEDANY && check_pic (1)"
2341 "sethi\t%%uhi(%a1), %0")
2343 (define_insn "embmedany_texthi"
2344 [(set (match_operand:DI 0 "register_operand" "=r")
2345 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTHI)))]
2346 "TARGET_CM_EMBMEDANY && check_pic (1)"
2347 "sethi\t%%hi(%a1), %0")
2349 (define_insn "embmedany_textulo"
2350 [(set (match_operand:DI 0 "register_operand" "=r")
2351 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2352 (unspec:DI [(match_operand:DI 2 "text_segment_operand" "")] UNSPEC_EMB_TEXTULO)))]
2353 "TARGET_CM_EMBMEDANY"
2354 "or\t%1, %%ulo(%a2), %0")
2356 (define_insn "embmedany_textlo"
2357 [(set (match_operand:DI 0 "register_operand" "=r")
2358 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2359 (match_operand:DI 2 "text_segment_operand" "")))]
2360 "TARGET_CM_EMBMEDANY"
2361 "or\t%1, %%lo(%a2), %0")
2363 ;; Now some patterns to help reload out a bit.
2364 (define_expand "reload_indi"
2365 [(parallel [(match_operand:DI 0 "register_operand" "=r")
2366 (match_operand:DI 1 "immediate_operand" "")
2367 (match_operand:TI 2 "register_operand" "=&r")])]
2369 || TARGET_CM_EMBMEDANY)
2372 sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
2376 (define_expand "reload_outdi"
2377 [(parallel [(match_operand:DI 0 "register_operand" "=r")
2378 (match_operand:DI 1 "immediate_operand" "")
2379 (match_operand:TI 2 "register_operand" "=&r")])]
2381 || TARGET_CM_EMBMEDANY)
2384 sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
2388 ;; Split up putting CONSTs and REGs into DI regs when !arch64
2390 [(set (match_operand:DI 0 "register_operand" "")
2391 (match_operand:DI 1 "const_int_operand" ""))]
2392 "! TARGET_ARCH64 && reload_completed"
2393 [(clobber (const_int 0))]
2395 #if HOST_BITS_PER_WIDE_INT == 32
2396 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
2397 (INTVAL (operands[1]) < 0) ?
2400 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2403 unsigned int low, high;
2405 low = trunc_int_for_mode (INTVAL (operands[1]), SImode);
2406 high = trunc_int_for_mode (INTVAL (operands[1]) >> 32, SImode);
2407 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), GEN_INT (high)));
2409 /* Slick... but this trick loses if this subreg constant part
2410 can be done in one insn. */
2411 if (low == high && (low & 0x3ff) != 0 && low + 0x1000 >= 0x2000)
2412 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2413 gen_highpart (SImode, operands[0])));
2415 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), GEN_INT (low)));
2421 [(set (match_operand:DI 0 "register_operand" "")
2422 (match_operand:DI 1 "const_double_operand" ""))]
2426 && ((GET_CODE (operands[0]) == REG
2427 && REGNO (operands[0]) < 32)
2428 || (GET_CODE (operands[0]) == SUBREG
2429 && GET_CODE (SUBREG_REG (operands[0])) == REG
2430 && REGNO (SUBREG_REG (operands[0])) < 32))))"
2431 [(clobber (const_int 0))]
2433 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
2434 GEN_INT (CONST_DOUBLE_HIGH (operands[1]))));
2436 /* Slick... but this trick loses if this subreg constant part
2437 can be done in one insn. */
2438 if (CONST_DOUBLE_LOW (operands[1]) == CONST_DOUBLE_HIGH (operands[1])
2439 && !(SPARC_SETHI32_P (CONST_DOUBLE_HIGH (operands[1]))
2440 || SPARC_SIMM13_P (CONST_DOUBLE_HIGH (operands[1]))))
2442 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2443 gen_highpart (SImode, operands[0])));
2447 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2448 GEN_INT (CONST_DOUBLE_LOW (operands[1]))));
2454 [(set (match_operand:DI 0 "register_operand" "")
2455 (match_operand:DI 1 "register_operand" ""))]
2459 && ((GET_CODE (operands[0]) == REG
2460 && REGNO (operands[0]) < 32)
2461 || (GET_CODE (operands[0]) == SUBREG
2462 && GET_CODE (SUBREG_REG (operands[0])) == REG
2463 && REGNO (SUBREG_REG (operands[0])) < 32))))"
2464 [(clobber (const_int 0))]
2466 rtx set_dest = operands[0];
2467 rtx set_src = operands[1];
2471 dest1 = gen_highpart (SImode, set_dest);
2472 dest2 = gen_lowpart (SImode, set_dest);
2473 src1 = gen_highpart (SImode, set_src);
2474 src2 = gen_lowpart (SImode, set_src);
2476 /* Now emit using the real source and destination we found, swapping
2477 the order if we detect overlap. */
2478 if (reg_overlap_mentioned_p (dest1, src2))
2480 emit_insn (gen_movsi (dest2, src2));
2481 emit_insn (gen_movsi (dest1, src1));
2485 emit_insn (gen_movsi (dest1, src1));
2486 emit_insn (gen_movsi (dest2, src2));
2491 ;; Now handle the cases of memory moves from/to non-even
2492 ;; DI mode register pairs.
2494 [(set (match_operand:DI 0 "register_operand" "")
2495 (match_operand:DI 1 "memory_operand" ""))]
2498 && sparc_splitdi_legitimate (operands[0], operands[1]))"
2499 [(clobber (const_int 0))]
2501 rtx word0 = adjust_address (operands[1], SImode, 0);
2502 rtx word1 = adjust_address (operands[1], SImode, 4);
2503 rtx high_part = gen_highpart (SImode, operands[0]);
2504 rtx low_part = gen_lowpart (SImode, operands[0]);
2506 if (reg_overlap_mentioned_p (high_part, word1))
2508 emit_insn (gen_movsi (low_part, word1));
2509 emit_insn (gen_movsi (high_part, word0));
2513 emit_insn (gen_movsi (high_part, word0));
2514 emit_insn (gen_movsi (low_part, word1));
2520 [(set (match_operand:DI 0 "memory_operand" "")
2521 (match_operand:DI 1 "register_operand" ""))]
2524 && sparc_splitdi_legitimate (operands[1], operands[0]))"
2525 [(clobber (const_int 0))]
2527 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0),
2528 gen_highpart (SImode, operands[1])));
2529 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4),
2530 gen_lowpart (SImode, operands[1])));
2535 [(set (match_operand:DI 0 "memory_operand" "")
2540 && ! mem_min_alignment (operands[0], 8)))
2541 && offsettable_memref_p (operands[0])"
2542 [(clobber (const_int 0))]
2544 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0), const0_rtx));
2545 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4), const0_rtx));
2549 ;; Floating point move insns
2551 (define_insn "*movsf_insn_novis"
2552 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,*r,*r,*r,*r,*r,f,m,m")
2553 (match_operand:SF 1 "input_operand" "f,G,Q,*rR,S,m,m,f,*rG"))]
2554 "(TARGET_FPU && ! TARGET_VIS)
2555 && (register_operand (operands[0], SFmode)
2556 || register_operand (operands[1], SFmode)
2557 || fp_zero_operand (operands[1], SFmode))"
2559 if (GET_CODE (operands[1]) == CONST_DOUBLE
2560 && (which_alternative == 2
2561 || which_alternative == 3
2562 || which_alternative == 4))
2567 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2568 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2569 operands[1] = GEN_INT (i);
2572 switch (which_alternative)
2575 return "fmovs\t%1, %0";
2579 return "sethi\t%%hi(%a1), %0";
2581 return "mov\t%1, %0";
2586 return "ld\t%1, %0";
2589 return "st\t%r1, %0";
2594 [(set_attr "type" "fpmove,*,*,*,*,load,fpload,fpstore,store")])
2596 (define_insn "*movsf_insn_vis"
2597 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,*r,*r,*r,*r,*r,f,m,m")
2598 (match_operand:SF 1 "input_operand" "f,G,G,Q,*rR,S,m,m,f,*rG"))]
2599 "(TARGET_FPU && TARGET_VIS)
2600 && (register_operand (operands[0], SFmode)
2601 || register_operand (operands[1], SFmode)
2602 || fp_zero_operand (operands[1], SFmode))"
2604 if (GET_CODE (operands[1]) == CONST_DOUBLE
2605 && (which_alternative == 3
2606 || which_alternative == 4
2607 || which_alternative == 5))
2612 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2613 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2614 operands[1] = GEN_INT (i);
2617 switch (which_alternative)
2620 return "fmovs\t%1, %0";
2622 return "fzeros\t%0";
2626 return "sethi\t%%hi(%a1), %0";
2628 return "mov\t%1, %0";
2633 return "ld\t%1, %0";
2636 return "st\t%r1, %0";
2641 [(set_attr "type" "fpmove,fga,*,*,*,*,load,fpload,fpstore,store")])
2643 ;; Exactly the same as above, except that all `f' cases are deleted.
2644 ;; This is necessary to prevent reload from ever trying to use a `f' reg
2647 (define_insn "*movsf_no_f_insn"
2648 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r,r,r,m")
2649 (match_operand:SF 1 "input_operand" "G,Q,rR,S,m,rG"))]
2651 && (register_operand (operands[0], SFmode)
2652 || register_operand (operands[1], SFmode)
2653 || fp_zero_operand (operands[1], SFmode))"
2655 if (GET_CODE (operands[1]) == CONST_DOUBLE
2656 && (which_alternative == 1
2657 || which_alternative == 2
2658 || which_alternative == 3))
2663 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2664 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2665 operands[1] = GEN_INT (i);
2668 switch (which_alternative)
2673 return "sethi\t%%hi(%a1), %0";
2675 return "mov\t%1, %0";
2679 return "ld\t%1, %0";
2681 return "st\t%r1, %0";
2686 [(set_attr "type" "*,*,*,*,load,store")])
2688 (define_insn "*movsf_lo_sum"
2689 [(set (match_operand:SF 0 "register_operand" "=r")
2690 (lo_sum:SF (match_operand:SF 1 "register_operand" "r")
2691 (match_operand:SF 2 "const_double_operand" "S")))]
2692 "fp_high_losum_p (operands[2])"
2697 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[2]);
2698 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2699 operands[2] = GEN_INT (i);
2700 return "or\t%1, %%lo(%a2), %0";
2703 (define_insn "*movsf_high"
2704 [(set (match_operand:SF 0 "register_operand" "=r")
2705 (high:SF (match_operand:SF 1 "const_double_operand" "S")))]
2706 "fp_high_losum_p (operands[1])"
2711 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2712 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2713 operands[1] = GEN_INT (i);
2714 return "sethi\t%%hi(%1), %0";
2718 [(set (match_operand:SF 0 "register_operand" "")
2719 (match_operand:SF 1 "const_double_operand" ""))]
2720 "fp_high_losum_p (operands[1])
2721 && (GET_CODE (operands[0]) == REG
2722 && REGNO (operands[0]) < 32)"
2723 [(set (match_dup 0) (high:SF (match_dup 1)))
2724 (set (match_dup 0) (lo_sum:SF (match_dup 0) (match_dup 1)))])
2726 (define_expand "movsf"
2727 [(set (match_operand:SF 0 "general_operand" "")
2728 (match_operand:SF 1 "general_operand" ""))]
2731 /* Force SFmode constants into memory. */
2732 if (GET_CODE (operands[0]) == REG
2733 && CONSTANT_P (operands[1]))
2735 /* emit_group_store will send such bogosity to us when it is
2736 not storing directly into memory. So fix this up to avoid
2737 crashes in output_constant_pool. */
2738 if (operands [1] == const0_rtx)
2739 operands[1] = CONST0_RTX (SFmode);
2741 if (TARGET_VIS && fp_zero_operand (operands[1], SFmode))
2744 /* We are able to build any SF constant in integer registers
2745 with at most 2 instructions. */
2746 if (REGNO (operands[0]) < 32)
2749 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
2753 /* Handle sets of MEM first. */
2754 if (GET_CODE (operands[0]) == MEM)
2756 if (register_operand (operands[1], SFmode)
2757 || fp_zero_operand (operands[1], SFmode))
2760 if (! reload_in_progress)
2762 operands[0] = validize_mem (operands[0]);
2763 operands[1] = force_reg (SFmode, operands[1]);
2767 /* Fixup PIC cases. */
2770 if (CONSTANT_P (operands[1])
2771 && pic_address_needs_scratch (operands[1]))
2772 operands[1] = legitimize_pic_address (operands[1], SFmode, 0);
2774 if (symbolic_operand (operands[1], SFmode))
2776 operands[1] = legitimize_pic_address (operands[1],
2778 (reload_in_progress ?
2788 (define_expand "movdf"
2789 [(set (match_operand:DF 0 "general_operand" "")
2790 (match_operand:DF 1 "general_operand" ""))]
2793 /* Force DFmode constants into memory. */
2794 if (GET_CODE (operands[0]) == REG
2795 && CONSTANT_P (operands[1]))
2797 /* emit_group_store will send such bogosity to us when it is
2798 not storing directly into memory. So fix this up to avoid
2799 crashes in output_constant_pool. */
2800 if (operands [1] == const0_rtx)
2801 operands[1] = CONST0_RTX (DFmode);
2803 if ((TARGET_VIS || REGNO (operands[0]) < 32)
2804 && fp_zero_operand (operands[1], DFmode))
2807 /* We are able to build any DF constant in integer registers. */
2808 if (REGNO (operands[0]) < 32
2809 && (reload_completed || reload_in_progress))
2812 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
2816 /* Handle MEM cases first. */
2817 if (GET_CODE (operands[0]) == MEM)
2819 if (register_operand (operands[1], DFmode)
2820 || fp_zero_operand (operands[1], DFmode))
2823 if (! reload_in_progress)
2825 operands[0] = validize_mem (operands[0]);
2826 operands[1] = force_reg (DFmode, operands[1]);
2830 /* Fixup PIC cases. */
2833 if (CONSTANT_P (operands[1])
2834 && pic_address_needs_scratch (operands[1]))
2835 operands[1] = legitimize_pic_address (operands[1], DFmode, 0);
2837 if (symbolic_operand (operands[1], DFmode))
2839 operands[1] = legitimize_pic_address (operands[1],
2841 (reload_in_progress ?
2851 ;; Be careful, fmovd does not exist when !v9.
2852 (define_insn "*movdf_insn_sp32"
2853 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,W,U,T,o,e,*r,o,e,o")
2854 (match_operand:DF 1 "input_operand" "W#F,e,T,U,G,e,*rFo,*r,o#F,e"))]
2857 && (register_operand (operands[0], DFmode)
2858 || register_operand (operands[1], DFmode)
2859 || fp_zero_operand (operands[1], DFmode))"
2871 [(set_attr "type" "fpload,fpstore,load,store,*,*,*,*,*,*")
2872 (set_attr "length" "*,*,*,*,2,2,2,2,2,2")])
2874 (define_insn "*movdf_no_e_insn_sp32"
2875 [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,o,r,o")
2876 (match_operand:DF 1 "input_operand" "T,U,G,ro,r"))]
2880 && (register_operand (operands[0], DFmode)
2881 || register_operand (operands[1], DFmode)
2882 || fp_zero_operand (operands[1], DFmode))"
2889 [(set_attr "type" "load,store,*,*,*")
2890 (set_attr "length" "*,*,2,2,2")])
2892 (define_insn "*movdf_no_e_insn_v9_sp32"
2893 [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,T,r,o")
2894 (match_operand:DF 1 "input_operand" "T,U,G,ro,rG"))]
2898 && (register_operand (operands[0], DFmode)
2899 || register_operand (operands[1], DFmode)
2900 || fp_zero_operand (operands[1], DFmode))"
2907 [(set_attr "type" "load,store,store,*,*")
2908 (set_attr "length" "*,*,*,2,2")])
2910 ;; We have available v9 double floats but not 64-bit
2911 ;; integer registers and no VIS.
2912 (define_insn "*movdf_insn_v9only_novis"
2913 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,T,W,U,T,f,*r,o")
2914 (match_operand:DF 1 "input_operand" "e,W#F,G,e,T,U,o#F,*roF,*rGf"))]
2919 && (register_operand (operands[0], DFmode)
2920 || register_operand (operands[1], DFmode)
2921 || fp_zero_operand (operands[1], DFmode))"
2932 [(set_attr "type" "fpmove,load,store,store,load,store,*,*,*")
2933 (set_attr "length" "*,*,*,*,*,*,2,2,2")
2934 (set_attr "fptype" "double,*,*,*,*,*,*,*,*")])
2936 ;; We have available v9 double floats but not 64-bit
2937 ;; integer registers but we have VIS.
2938 (define_insn "*movdf_insn_v9only_vis"
2939 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,e,T,W,U,T,f,*r,o")
2940 (match_operand:DF 1 "input_operand" "G,e,W#F,G,e,T,U,o#F,*roGF,*rGf"))]
2944 && (register_operand (operands[0], DFmode)
2945 || register_operand (operands[1], DFmode)
2946 || fp_zero_operand (operands[1], DFmode))"
2958 [(set_attr "type" "fga,fpmove,load,store,store,load,store,*,*,*")
2959 (set_attr "length" "*,*,*,*,*,*,*,2,2,2")
2960 (set_attr "fptype" "double,double,*,*,*,*,*,*,*,*")])
2962 ;; We have available both v9 double floats and 64-bit
2963 ;; integer registers. No VIS though.
2964 (define_insn "*movdf_insn_sp64_novis"
2965 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,W,*r,*r,m,*r")
2966 (match_operand:DF 1 "input_operand" "e,W#F,e,*rG,m,*rG,F"))]
2970 && (register_operand (operands[0], DFmode)
2971 || register_operand (operands[1], DFmode)
2972 || fp_zero_operand (operands[1], DFmode))"
2981 [(set_attr "type" "fpmove,load,store,*,load,store,*")
2982 (set_attr "length" "*,*,*,*,*,*,2")
2983 (set_attr "fptype" "double,*,*,*,*,*,*")])
2985 ;; We have available both v9 double floats and 64-bit
2986 ;; integer registers. And we have VIS.
2987 (define_insn "*movdf_insn_sp64_vis"
2988 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,e,W,*r,*r,m,*r")
2989 (match_operand:DF 1 "input_operand" "G,e,W#F,e,*rG,m,*rG,F"))]
2993 && (register_operand (operands[0], DFmode)
2994 || register_operand (operands[1], DFmode)
2995 || fp_zero_operand (operands[1], DFmode))"
3005 [(set_attr "type" "fga,fpmove,load,store,*,load,store,*")
3006 (set_attr "length" "*,*,*,*,*,*,*,2")
3007 (set_attr "fptype" "double,double,*,*,*,*,*,*")])
3009 (define_insn "*movdf_no_e_insn_sp64"
3010 [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m")
3011 (match_operand:DF 1 "input_operand" "r,m,rG"))]
3014 && (register_operand (operands[0], DFmode)
3015 || register_operand (operands[1], DFmode)
3016 || fp_zero_operand (operands[1], DFmode))"
3021 [(set_attr "type" "*,load,store")])
3024 [(set (match_operand:DF 0 "register_operand" "")
3025 (match_operand:DF 1 "const_double_operand" ""))]
3027 && (GET_CODE (operands[0]) == REG
3028 && REGNO (operands[0]) < 32)
3029 && ! fp_zero_operand(operands[1], DFmode)
3030 && reload_completed"
3031 [(clobber (const_int 0))]
3036 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3037 REAL_VALUE_TO_TARGET_DOUBLE (r, l);
3038 operands[0] = gen_rtx_raw_REG (DImode, REGNO (operands[0]));
3042 #if HOST_BITS_PER_WIDE_INT == 64
3045 val = ((HOST_WIDE_INT)(unsigned long)l[1] |
3046 ((HOST_WIDE_INT)(unsigned long)l[0] << 32));
3047 emit_insn (gen_movdi (operands[0], GEN_INT (val)));
3049 emit_insn (gen_movdi (operands[0],
3050 immed_double_const (l[1], l[0], DImode)));
3055 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
3058 /* Slick... but this trick loses if this subreg constant part
3059 can be done in one insn. */
3061 && !(SPARC_SETHI32_P (l[0])
3062 || SPARC_SIMM13_P (l[0])))
3064 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
3065 gen_highpart (SImode, operands[0])));
3069 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
3076 ;; Ok, now the splits to handle all the multi insn and
3077 ;; mis-aligned memory address cases.
3078 ;; In these splits please take note that we must be
3079 ;; careful when V9 but not ARCH64 because the integer
3080 ;; register DFmode cases must be handled.
3082 [(set (match_operand:DF 0 "register_operand" "")
3083 (match_operand:DF 1 "register_operand" ""))]
3086 && ((GET_CODE (operands[0]) == REG
3087 && REGNO (operands[0]) < 32)
3088 || (GET_CODE (operands[0]) == SUBREG
3089 && GET_CODE (SUBREG_REG (operands[0])) == REG
3090 && REGNO (SUBREG_REG (operands[0])) < 32))))
3091 && reload_completed"
3092 [(clobber (const_int 0))]
3094 rtx set_dest = operands[0];
3095 rtx set_src = operands[1];
3099 dest1 = gen_highpart (SFmode, set_dest);
3100 dest2 = gen_lowpart (SFmode, set_dest);
3101 src1 = gen_highpart (SFmode, set_src);
3102 src2 = gen_lowpart (SFmode, set_src);
3104 /* Now emit using the real source and destination we found, swapping
3105 the order if we detect overlap. */
3106 if (reg_overlap_mentioned_p (dest1, src2))
3108 emit_insn (gen_movsf (dest2, src2));
3109 emit_insn (gen_movsf (dest1, src1));
3113 emit_insn (gen_movsf (dest1, src1));
3114 emit_insn (gen_movsf (dest2, src2));
3120 [(set (match_operand:DF 0 "register_operand" "")
3121 (match_operand:DF 1 "memory_operand" ""))]
3124 && (((REGNO (operands[0]) % 2) != 0)
3125 || ! mem_min_alignment (operands[1], 8))
3126 && offsettable_memref_p (operands[1])"
3127 [(clobber (const_int 0))]
3129 rtx word0 = adjust_address (operands[1], SFmode, 0);
3130 rtx word1 = adjust_address (operands[1], SFmode, 4);
3132 if (reg_overlap_mentioned_p (gen_highpart (SFmode, operands[0]), word1))
3134 emit_insn (gen_movsf (gen_lowpart (SFmode, operands[0]),
3136 emit_insn (gen_movsf (gen_highpart (SFmode, operands[0]),
3141 emit_insn (gen_movsf (gen_highpart (SFmode, operands[0]),
3143 emit_insn (gen_movsf (gen_lowpart (SFmode, operands[0]),
3150 [(set (match_operand:DF 0 "memory_operand" "")
3151 (match_operand:DF 1 "register_operand" ""))]
3154 && (((REGNO (operands[1]) % 2) != 0)
3155 || ! mem_min_alignment (operands[0], 8))
3156 && offsettable_memref_p (operands[0])"
3157 [(clobber (const_int 0))]
3159 rtx word0 = adjust_address (operands[0], SFmode, 0);
3160 rtx word1 = adjust_address (operands[0], SFmode, 4);
3162 emit_insn (gen_movsf (word0,
3163 gen_highpart (SFmode, operands[1])));
3164 emit_insn (gen_movsf (word1,
3165 gen_lowpart (SFmode, operands[1])));
3170 [(set (match_operand:DF 0 "memory_operand" "")
3171 (match_operand:DF 1 "fp_zero_operand" ""))]
3175 && ! mem_min_alignment (operands[0], 8)))
3176 && offsettable_memref_p (operands[0])"
3177 [(clobber (const_int 0))]
3181 dest1 = adjust_address (operands[0], SFmode, 0);
3182 dest2 = adjust_address (operands[0], SFmode, 4);
3184 emit_insn (gen_movsf (dest1, CONST0_RTX (SFmode)));
3185 emit_insn (gen_movsf (dest2, CONST0_RTX (SFmode)));
3190 [(set (match_operand:DF 0 "register_operand" "")
3191 (match_operand:DF 1 "fp_zero_operand" ""))]
3194 && ((GET_CODE (operands[0]) == REG
3195 && REGNO (operands[0]) < 32)
3196 || (GET_CODE (operands[0]) == SUBREG
3197 && GET_CODE (SUBREG_REG (operands[0])) == REG
3198 && REGNO (SUBREG_REG (operands[0])) < 32))"
3199 [(clobber (const_int 0))]
3201 rtx set_dest = operands[0];
3204 dest1 = gen_highpart (SFmode, set_dest);
3205 dest2 = gen_lowpart (SFmode, set_dest);
3206 emit_insn (gen_movsf (dest1, CONST0_RTX (SFmode)));
3207 emit_insn (gen_movsf (dest2, CONST0_RTX (SFmode)));
3211 (define_expand "movtf"
3212 [(set (match_operand:TF 0 "general_operand" "")
3213 (match_operand:TF 1 "general_operand" ""))]
3216 /* Force TFmode constants into memory. */
3217 if (GET_CODE (operands[0]) == REG
3218 && CONSTANT_P (operands[1]))
3220 /* emit_group_store will send such bogosity to us when it is
3221 not storing directly into memory. So fix this up to avoid
3222 crashes in output_constant_pool. */
3223 if (operands [1] == const0_rtx)
3224 operands[1] = CONST0_RTX (TFmode);
3226 if (TARGET_VIS && fp_zero_operand (operands[1], TFmode))
3229 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
3233 /* Handle MEM cases first, note that only v9 guarantees
3234 full 16-byte alignment for quads. */
3235 if (GET_CODE (operands[0]) == MEM)
3237 if (register_operand (operands[1], TFmode)
3238 || fp_zero_operand (operands[1], TFmode))
3241 if (! reload_in_progress)
3243 operands[0] = validize_mem (operands[0]);
3244 operands[1] = force_reg (TFmode, operands[1]);
3248 /* Fixup PIC cases. */
3251 if (CONSTANT_P (operands[1])
3252 && pic_address_needs_scratch (operands[1]))
3253 operands[1] = legitimize_pic_address (operands[1], TFmode, 0);
3255 if (symbolic_operand (operands[1], TFmode))
3257 operands[1] = legitimize_pic_address (operands[1],
3259 (reload_in_progress ?
3269 ;; Be careful, fmovq and {st,ld}{x,q} do not exist when !arch64 so
3270 ;; we must split them all. :-(
3271 (define_insn "*movtf_insn_sp32"
3272 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,U,r")
3273 (match_operand:TF 1 "input_operand" "oe,GeUr,o,roG"))]
3277 && (register_operand (operands[0], TFmode)
3278 || register_operand (operands[1], TFmode)
3279 || fp_zero_operand (operands[1], TFmode))"
3281 [(set_attr "length" "4")])
3283 (define_insn "*movtf_insn_vis_sp32"
3284 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,U,r")
3285 (match_operand:TF 1 "input_operand" "Goe,GeUr,o,roG"))]
3289 && (register_operand (operands[0], TFmode)
3290 || register_operand (operands[1], TFmode)
3291 || fp_zero_operand (operands[1], TFmode))"
3293 [(set_attr "length" "4")])
3295 ;; Exactly the same as above, except that all `e' cases are deleted.
3296 ;; This is necessary to prevent reload from ever trying to use a `e' reg
3299 (define_insn "*movtf_no_e_insn_sp32"
3300 [(set (match_operand:TF 0 "nonimmediate_operand" "=o,U,o,r,o")
3301 (match_operand:TF 1 "input_operand" "G,o,U,roG,r"))]
3304 && (register_operand (operands[0], TFmode)
3305 || register_operand (operands[1], TFmode)
3306 || fp_zero_operand (operands[1], TFmode))"
3308 [(set_attr "length" "4")])
3310 ;; Now handle the float reg cases directly when arch64,
3311 ;; hard_quad, and proper reg number alignment are all true.
3312 (define_insn "*movtf_insn_hq_sp64"
3313 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,e,m,o,r")
3314 (match_operand:TF 1 "input_operand" "e,m,e,Gr,roG"))]
3319 && (register_operand (operands[0], TFmode)
3320 || register_operand (operands[1], TFmode)
3321 || fp_zero_operand (operands[1], TFmode))"
3328 [(set_attr "type" "fpmove,fpload,fpstore,*,*")
3329 (set_attr "length" "*,*,*,2,2")])
3331 (define_insn "*movtf_insn_hq_vis_sp64"
3332 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,e,m,eo,r,o")
3333 (match_operand:TF 1 "input_operand" "e,m,e,G,roG,r"))]
3338 && (register_operand (operands[0], TFmode)
3339 || register_operand (operands[1], TFmode)
3340 || fp_zero_operand (operands[1], TFmode))"
3348 [(set_attr "type" "fpmove,fpload,fpstore,*,*,*")
3349 (set_attr "length" "*,*,*,2,2,2")])
3351 ;; Now we allow the integer register cases even when
3352 ;; only arch64 is true.
3353 (define_insn "*movtf_insn_sp64"
3354 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,r")
3355 (match_operand:TF 1 "input_operand" "oe,Ger,orG"))]
3359 && ! TARGET_HARD_QUAD
3360 && (register_operand (operands[0], TFmode)
3361 || register_operand (operands[1], TFmode)
3362 || fp_zero_operand (operands[1], TFmode))"
3364 [(set_attr "length" "2")])
3366 (define_insn "*movtf_insn_vis_sp64"
3367 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,r")
3368 (match_operand:TF 1 "input_operand" "Goe,Ger,orG"))]
3372 && ! TARGET_HARD_QUAD
3373 && (register_operand (operands[0], TFmode)
3374 || register_operand (operands[1], TFmode)
3375 || fp_zero_operand (operands[1], TFmode))"
3377 [(set_attr "length" "2")])
3379 (define_insn "*movtf_no_e_insn_sp64"
3380 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o")
3381 (match_operand:TF 1 "input_operand" "orG,rG"))]
3384 && (register_operand (operands[0], TFmode)
3385 || register_operand (operands[1], TFmode)
3386 || fp_zero_operand (operands[1], TFmode))"
3388 [(set_attr "length" "2")])
3390 ;; Now all the splits to handle multi-insn TF mode moves.
3392 [(set (match_operand:TF 0 "register_operand" "")
3393 (match_operand:TF 1 "register_operand" ""))]
3397 && ! TARGET_HARD_QUAD)
3398 || ! fp_register_operand (operands[0], TFmode))"
3399 [(clobber (const_int 0))]
3401 rtx set_dest = operands[0];
3402 rtx set_src = operands[1];
3406 dest1 = gen_df_reg (set_dest, 0);
3407 dest2 = gen_df_reg (set_dest, 1);
3408 src1 = gen_df_reg (set_src, 0);
3409 src2 = gen_df_reg (set_src, 1);
3411 /* Now emit using the real source and destination we found, swapping
3412 the order if we detect overlap. */
3413 if (reg_overlap_mentioned_p (dest1, src2))
3415 emit_insn (gen_movdf (dest2, src2));
3416 emit_insn (gen_movdf (dest1, src1));
3420 emit_insn (gen_movdf (dest1, src1));
3421 emit_insn (gen_movdf (dest2, src2));
3427 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3428 (match_operand:TF 1 "fp_zero_operand" ""))]
3430 [(clobber (const_int 0))]
3432 rtx set_dest = operands[0];
3435 switch (GET_CODE (set_dest))
3438 dest1 = gen_df_reg (set_dest, 0);
3439 dest2 = gen_df_reg (set_dest, 1);
3442 dest1 = adjust_address (set_dest, DFmode, 0);
3443 dest2 = adjust_address (set_dest, DFmode, 8);
3449 emit_insn (gen_movdf (dest1, CONST0_RTX (DFmode)));
3450 emit_insn (gen_movdf (dest2, CONST0_RTX (DFmode)));
3455 [(set (match_operand:TF 0 "register_operand" "")
3456 (match_operand:TF 1 "memory_operand" ""))]
3458 && offsettable_memref_p (operands[1])
3460 || ! TARGET_HARD_QUAD
3461 || ! fp_register_operand (operands[0], TFmode)))"
3462 [(clobber (const_int 0))]
3464 rtx word0 = adjust_address (operands[1], DFmode, 0);
3465 rtx word1 = adjust_address (operands[1], DFmode, 8);
3466 rtx set_dest, dest1, dest2;
3468 set_dest = operands[0];
3470 dest1 = gen_df_reg (set_dest, 0);
3471 dest2 = gen_df_reg (set_dest, 1);
3473 /* Now output, ordering such that we don't clobber any registers
3474 mentioned in the address. */
3475 if (reg_overlap_mentioned_p (dest1, word1))
3478 emit_insn (gen_movdf (dest2, word1));
3479 emit_insn (gen_movdf (dest1, word0));
3483 emit_insn (gen_movdf (dest1, word0));
3484 emit_insn (gen_movdf (dest2, word1));
3490 [(set (match_operand:TF 0 "memory_operand" "")
3491 (match_operand:TF 1 "register_operand" ""))]
3493 && offsettable_memref_p (operands[0])
3495 || ! TARGET_HARD_QUAD
3496 || ! fp_register_operand (operands[1], TFmode)))"
3497 [(clobber (const_int 0))]
3499 rtx set_src = operands[1];
3501 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 0),
3502 gen_df_reg (set_src, 0)));
3503 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 8),
3504 gen_df_reg (set_src, 1)));
3508 ;; SPARC V9 conditional move instructions.
3510 ;; We can handle larger constants here for some flavors, but for now we keep
3511 ;; it simple and only allow those constants supported by all flavors.
3512 ;; Note that emit_conditional_move canonicalizes operands 2,3 so that operand
3513 ;; 3 contains the constant if one is present, but we handle either for
3514 ;; generality (sparc.c puts a constant in operand 2).
3516 (define_expand "movqicc"
3517 [(set (match_operand:QI 0 "register_operand" "")
3518 (if_then_else:QI (match_operand 1 "comparison_operator" "")
3519 (match_operand:QI 2 "arith10_operand" "")
3520 (match_operand:QI 3 "arith10_operand" "")))]
3523 enum rtx_code code = GET_CODE (operands[1]);
3525 if (GET_MODE (sparc_compare_op0) == DImode
3529 if (sparc_compare_op1 == const0_rtx
3530 && GET_CODE (sparc_compare_op0) == REG
3531 && GET_MODE (sparc_compare_op0) == DImode
3532 && v9_regcmp_p (code))
3534 operands[1] = gen_rtx_fmt_ee (code, DImode,
3535 sparc_compare_op0, sparc_compare_op1);
3539 rtx cc_reg = gen_compare_reg (code,
3540 sparc_compare_op0, sparc_compare_op1);
3541 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3545 (define_expand "movhicc"
3546 [(set (match_operand:HI 0 "register_operand" "")
3547 (if_then_else:HI (match_operand 1 "comparison_operator" "")
3548 (match_operand:HI 2 "arith10_operand" "")
3549 (match_operand:HI 3 "arith10_operand" "")))]
3552 enum rtx_code code = GET_CODE (operands[1]);
3554 if (GET_MODE (sparc_compare_op0) == DImode
3558 if (sparc_compare_op1 == const0_rtx
3559 && GET_CODE (sparc_compare_op0) == REG
3560 && GET_MODE (sparc_compare_op0) == DImode
3561 && v9_regcmp_p (code))
3563 operands[1] = gen_rtx_fmt_ee (code, DImode,
3564 sparc_compare_op0, sparc_compare_op1);
3568 rtx cc_reg = gen_compare_reg (code,
3569 sparc_compare_op0, sparc_compare_op1);
3570 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3574 (define_expand "movsicc"
3575 [(set (match_operand:SI 0 "register_operand" "")
3576 (if_then_else:SI (match_operand 1 "comparison_operator" "")
3577 (match_operand:SI 2 "arith10_operand" "")
3578 (match_operand:SI 3 "arith10_operand" "")))]
3581 enum rtx_code code = GET_CODE (operands[1]);
3582 enum machine_mode op0_mode = GET_MODE (sparc_compare_op0);
3584 if (sparc_compare_op1 == const0_rtx
3585 && GET_CODE (sparc_compare_op0) == REG
3586 && (TARGET_ARCH64 && op0_mode == DImode && v9_regcmp_p (code)))
3588 operands[1] = gen_rtx_fmt_ee (code, op0_mode,
3589 sparc_compare_op0, sparc_compare_op1);
3593 rtx cc_reg = gen_compare_reg (code,
3594 sparc_compare_op0, sparc_compare_op1);
3595 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg),
3596 cc_reg, const0_rtx);
3600 (define_expand "movdicc"
3601 [(set (match_operand:DI 0 "register_operand" "")
3602 (if_then_else:DI (match_operand 1 "comparison_operator" "")
3603 (match_operand:DI 2 "arith10_double_operand" "")
3604 (match_operand:DI 3 "arith10_double_operand" "")))]
3607 enum rtx_code code = GET_CODE (operands[1]);
3609 if (sparc_compare_op1 == const0_rtx
3610 && GET_CODE (sparc_compare_op0) == REG
3611 && GET_MODE (sparc_compare_op0) == DImode
3612 && v9_regcmp_p (code))
3614 operands[1] = gen_rtx_fmt_ee (code, DImode,
3615 sparc_compare_op0, sparc_compare_op1);
3619 rtx cc_reg = gen_compare_reg (code,
3620 sparc_compare_op0, sparc_compare_op1);
3621 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg),
3622 cc_reg, const0_rtx);
3626 (define_expand "movsfcc"
3627 [(set (match_operand:SF 0 "register_operand" "")
3628 (if_then_else:SF (match_operand 1 "comparison_operator" "")
3629 (match_operand:SF 2 "register_operand" "")
3630 (match_operand:SF 3 "register_operand" "")))]
3631 "TARGET_V9 && TARGET_FPU"
3633 enum rtx_code code = GET_CODE (operands[1]);
3635 if (GET_MODE (sparc_compare_op0) == DImode
3639 if (sparc_compare_op1 == const0_rtx
3640 && GET_CODE (sparc_compare_op0) == REG
3641 && GET_MODE (sparc_compare_op0) == DImode
3642 && v9_regcmp_p (code))
3644 operands[1] = gen_rtx_fmt_ee (code, DImode,
3645 sparc_compare_op0, sparc_compare_op1);
3649 rtx cc_reg = gen_compare_reg (code,
3650 sparc_compare_op0, sparc_compare_op1);
3651 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3655 (define_expand "movdfcc"
3656 [(set (match_operand:DF 0 "register_operand" "")
3657 (if_then_else:DF (match_operand 1 "comparison_operator" "")
3658 (match_operand:DF 2 "register_operand" "")
3659 (match_operand:DF 3 "register_operand" "")))]
3660 "TARGET_V9 && TARGET_FPU"
3662 enum rtx_code code = GET_CODE (operands[1]);
3664 if (GET_MODE (sparc_compare_op0) == DImode
3668 if (sparc_compare_op1 == const0_rtx
3669 && GET_CODE (sparc_compare_op0) == REG
3670 && GET_MODE (sparc_compare_op0) == DImode
3671 && v9_regcmp_p (code))
3673 operands[1] = gen_rtx_fmt_ee (code, DImode,
3674 sparc_compare_op0, sparc_compare_op1);
3678 rtx cc_reg = gen_compare_reg (code,
3679 sparc_compare_op0, sparc_compare_op1);
3680 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3684 (define_expand "movtfcc"
3685 [(set (match_operand:TF 0 "register_operand" "")
3686 (if_then_else:TF (match_operand 1 "comparison_operator" "")
3687 (match_operand:TF 2 "register_operand" "")
3688 (match_operand:TF 3 "register_operand" "")))]
3689 "TARGET_V9 && TARGET_FPU"
3691 enum rtx_code code = GET_CODE (operands[1]);
3693 if (GET_MODE (sparc_compare_op0) == DImode
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), cc_reg, const0_rtx);
3713 ;; Conditional move define_insns.
3715 (define_insn "*movqi_cc_sp64"
3716 [(set (match_operand:QI 0 "register_operand" "=r,r")
3717 (if_then_else:QI (match_operator 1 "comparison_operator"
3718 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3720 (match_operand:QI 3 "arith11_operand" "rL,0")
3721 (match_operand:QI 4 "arith11_operand" "0,rL")))]
3725 mov%c1\t%x2, %4, %0"
3726 [(set_attr "type" "cmove")])
3728 (define_insn "*movhi_cc_sp64"
3729 [(set (match_operand:HI 0 "register_operand" "=r,r")
3730 (if_then_else:HI (match_operator 1 "comparison_operator"
3731 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3733 (match_operand:HI 3 "arith11_operand" "rL,0")
3734 (match_operand:HI 4 "arith11_operand" "0,rL")))]
3738 mov%c1\t%x2, %4, %0"
3739 [(set_attr "type" "cmove")])
3741 (define_insn "*movsi_cc_sp64"
3742 [(set (match_operand:SI 0 "register_operand" "=r,r")
3743 (if_then_else:SI (match_operator 1 "comparison_operator"
3744 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3746 (match_operand:SI 3 "arith11_operand" "rL,0")
3747 (match_operand:SI 4 "arith11_operand" "0,rL")))]
3751 mov%c1\t%x2, %4, %0"
3752 [(set_attr "type" "cmove")])
3754 ;; ??? The constraints of operands 3,4 need work.
3755 (define_insn "*movdi_cc_sp64"
3756 [(set (match_operand:DI 0 "register_operand" "=r,r")
3757 (if_then_else:DI (match_operator 1 "comparison_operator"
3758 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3760 (match_operand:DI 3 "arith11_double_operand" "rLH,0")
3761 (match_operand:DI 4 "arith11_double_operand" "0,rLH")))]
3765 mov%c1\t%x2, %4, %0"
3766 [(set_attr "type" "cmove")])
3768 (define_insn "*movdi_cc_sp64_trunc"
3769 [(set (match_operand:SI 0 "register_operand" "=r,r")
3770 (if_then_else:SI (match_operator 1 "comparison_operator"
3771 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3773 (match_operand:SI 3 "arith11_double_operand" "rLH,0")
3774 (match_operand:SI 4 "arith11_double_operand" "0,rLH")))]
3778 mov%c1\t%x2, %4, %0"
3779 [(set_attr "type" "cmove")])
3781 (define_insn "*movsf_cc_sp64"
3782 [(set (match_operand:SF 0 "register_operand" "=f,f")
3783 (if_then_else:SF (match_operator 1 "comparison_operator"
3784 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3786 (match_operand:SF 3 "register_operand" "f,0")
3787 (match_operand:SF 4 "register_operand" "0,f")))]
3788 "TARGET_V9 && TARGET_FPU"
3790 fmovs%C1\t%x2, %3, %0
3791 fmovs%c1\t%x2, %4, %0"
3792 [(set_attr "type" "fpcmove")])
3794 (define_insn "movdf_cc_sp64"
3795 [(set (match_operand:DF 0 "register_operand" "=e,e")
3796 (if_then_else:DF (match_operator 1 "comparison_operator"
3797 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3799 (match_operand:DF 3 "register_operand" "e,0")
3800 (match_operand:DF 4 "register_operand" "0,e")))]
3801 "TARGET_V9 && TARGET_FPU"
3803 fmovd%C1\t%x2, %3, %0
3804 fmovd%c1\t%x2, %4, %0"
3805 [(set_attr "type" "fpcmove")
3806 (set_attr "fptype" "double")])
3808 (define_insn "*movtf_cc_hq_sp64"
3809 [(set (match_operand:TF 0 "register_operand" "=e,e")
3810 (if_then_else:TF (match_operator 1 "comparison_operator"
3811 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3813 (match_operand:TF 3 "register_operand" "e,0")
3814 (match_operand:TF 4 "register_operand" "0,e")))]
3815 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
3817 fmovq%C1\t%x2, %3, %0
3818 fmovq%c1\t%x2, %4, %0"
3819 [(set_attr "type" "fpcmove")])
3821 (define_insn_and_split "*movtf_cc_sp64"
3822 [(set (match_operand:TF 0 "register_operand" "=e,e")
3823 (if_then_else:TF (match_operator 1 "comparison_operator"
3824 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3826 (match_operand:TF 3 "register_operand" "e,0")
3827 (match_operand:TF 4 "register_operand" "0,e")))]
3828 "TARGET_V9 && TARGET_FPU && !TARGET_HARD_QUAD"
3830 "&& reload_completed"
3831 [(clobber (const_int 0))]
3833 rtx set_dest = operands[0];
3834 rtx set_srca = operands[3];
3835 rtx set_srcb = operands[4];
3836 int third = rtx_equal_p (set_dest, set_srca);
3838 rtx srca1, srca2, srcb1, srcb2;
3840 dest1 = gen_df_reg (set_dest, 0);
3841 dest2 = gen_df_reg (set_dest, 1);
3842 srca1 = gen_df_reg (set_srca, 0);
3843 srca2 = gen_df_reg (set_srca, 1);
3844 srcb1 = gen_df_reg (set_srcb, 0);
3845 srcb2 = gen_df_reg (set_srcb, 1);
3847 /* Now emit using the real source and destination we found, swapping
3848 the order if we detect overlap. */
3849 if ((third && reg_overlap_mentioned_p (dest1, srcb2))
3850 || (!third && reg_overlap_mentioned_p (dest1, srca2)))
3852 emit_insn (gen_movdf_cc_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
3853 emit_insn (gen_movdf_cc_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
3857 emit_insn (gen_movdf_cc_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
3858 emit_insn (gen_movdf_cc_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
3862 [(set_attr "length" "2")])
3864 (define_insn "*movqi_cc_reg_sp64"
3865 [(set (match_operand:QI 0 "register_operand" "=r,r")
3866 (if_then_else:QI (match_operator 1 "v9_regcmp_op"
3867 [(match_operand:DI 2 "register_operand" "r,r")
3869 (match_operand:QI 3 "arith10_operand" "rM,0")
3870 (match_operand:QI 4 "arith10_operand" "0,rM")))]
3873 movr%D1\t%2, %r3, %0
3874 movr%d1\t%2, %r4, %0"
3875 [(set_attr "type" "cmove")])
3877 (define_insn "*movhi_cc_reg_sp64"
3878 [(set (match_operand:HI 0 "register_operand" "=r,r")
3879 (if_then_else:HI (match_operator 1 "v9_regcmp_op"
3880 [(match_operand:DI 2 "register_operand" "r,r")
3882 (match_operand:HI 3 "arith10_operand" "rM,0")
3883 (match_operand:HI 4 "arith10_operand" "0,rM")))]
3886 movr%D1\t%2, %r3, %0
3887 movr%d1\t%2, %r4, %0"
3888 [(set_attr "type" "cmove")])
3890 (define_insn "*movsi_cc_reg_sp64"
3891 [(set (match_operand:SI 0 "register_operand" "=r,r")
3892 (if_then_else:SI (match_operator 1 "v9_regcmp_op"
3893 [(match_operand:DI 2 "register_operand" "r,r")
3895 (match_operand:SI 3 "arith10_operand" "rM,0")
3896 (match_operand:SI 4 "arith10_operand" "0,rM")))]
3899 movr%D1\t%2, %r3, %0
3900 movr%d1\t%2, %r4, %0"
3901 [(set_attr "type" "cmove")])
3903 ;; ??? The constraints of operands 3,4 need work.
3904 (define_insn "*movdi_cc_reg_sp64"
3905 [(set (match_operand:DI 0 "register_operand" "=r,r")
3906 (if_then_else:DI (match_operator 1 "v9_regcmp_op"
3907 [(match_operand:DI 2 "register_operand" "r,r")
3909 (match_operand:DI 3 "arith10_double_operand" "rMH,0")
3910 (match_operand:DI 4 "arith10_double_operand" "0,rMH")))]
3913 movr%D1\t%2, %r3, %0
3914 movr%d1\t%2, %r4, %0"
3915 [(set_attr "type" "cmove")])
3917 (define_insn "*movdi_cc_reg_sp64_trunc"
3918 [(set (match_operand:SI 0 "register_operand" "=r,r")
3919 (if_then_else:SI (match_operator 1 "v9_regcmp_op"
3920 [(match_operand:DI 2 "register_operand" "r,r")
3922 (match_operand:SI 3 "arith10_double_operand" "rMH,0")
3923 (match_operand:SI 4 "arith10_double_operand" "0,rMH")))]
3926 movr%D1\t%2, %r3, %0
3927 movr%d1\t%2, %r4, %0"
3928 [(set_attr "type" "cmove")])
3930 (define_insn "*movsf_cc_reg_sp64"
3931 [(set (match_operand:SF 0 "register_operand" "=f,f")
3932 (if_then_else:SF (match_operator 1 "v9_regcmp_op"
3933 [(match_operand:DI 2 "register_operand" "r,r")
3935 (match_operand:SF 3 "register_operand" "f,0")
3936 (match_operand:SF 4 "register_operand" "0,f")))]
3937 "TARGET_ARCH64 && TARGET_FPU"
3939 fmovrs%D1\t%2, %3, %0
3940 fmovrs%d1\t%2, %4, %0"
3941 [(set_attr "type" "fpcrmove")])
3943 (define_insn "movdf_cc_reg_sp64"
3944 [(set (match_operand:DF 0 "register_operand" "=e,e")
3945 (if_then_else:DF (match_operator 1 "v9_regcmp_op"
3946 [(match_operand:DI 2 "register_operand" "r,r")
3948 (match_operand:DF 3 "register_operand" "e,0")
3949 (match_operand:DF 4 "register_operand" "0,e")))]
3950 "TARGET_ARCH64 && TARGET_FPU"
3952 fmovrd%D1\t%2, %3, %0
3953 fmovrd%d1\t%2, %4, %0"
3954 [(set_attr "type" "fpcrmove")
3955 (set_attr "fptype" "double")])
3957 (define_insn "*movtf_cc_reg_hq_sp64"
3958 [(set (match_operand:TF 0 "register_operand" "=e,e")
3959 (if_then_else:TF (match_operator 1 "v9_regcmp_op"
3960 [(match_operand:DI 2 "register_operand" "r,r")
3962 (match_operand:TF 3 "register_operand" "e,0")
3963 (match_operand:TF 4 "register_operand" "0,e")))]
3964 "TARGET_ARCH64 && TARGET_FPU && TARGET_HARD_QUAD"
3966 fmovrq%D1\t%2, %3, %0
3967 fmovrq%d1\t%2, %4, %0"
3968 [(set_attr "type" "fpcrmove")])
3970 (define_insn_and_split "*movtf_cc_reg_sp64"
3971 [(set (match_operand:TF 0 "register_operand" "=e,e")
3972 (if_then_else:TF (match_operator 1 "v9_regcmp_op"
3973 [(match_operand:DI 2 "register_operand" "r,r")
3975 (match_operand:TF 3 "register_operand" "e,0")
3976 (match_operand:TF 4 "register_operand" "0,e")))]
3977 "TARGET_ARCH64 && TARGET_FPU && ! TARGET_HARD_QUAD"
3979 "&& reload_completed"
3980 [(clobber (const_int 0))]
3982 rtx set_dest = operands[0];
3983 rtx set_srca = operands[3];
3984 rtx set_srcb = operands[4];
3985 int third = rtx_equal_p (set_dest, set_srca);
3987 rtx srca1, srca2, srcb1, srcb2;
3989 dest1 = gen_df_reg (set_dest, 0);
3990 dest2 = gen_df_reg (set_dest, 1);
3991 srca1 = gen_df_reg (set_srca, 0);
3992 srca2 = gen_df_reg (set_srca, 1);
3993 srcb1 = gen_df_reg (set_srcb, 0);
3994 srcb2 = gen_df_reg (set_srcb, 1);
3996 /* Now emit using the real source and destination we found, swapping
3997 the order if we detect overlap. */
3998 if ((third && reg_overlap_mentioned_p (dest1, srcb2))
3999 || (!third && reg_overlap_mentioned_p (dest1, srca2)))
4001 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
4002 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
4006 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
4007 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
4011 [(set_attr "length" "2")])
4014 ;;- zero extension instructions
4016 ;; These patterns originally accepted general_operands, however, slightly
4017 ;; better code is generated by only accepting register_operands, and then
4018 ;; letting combine generate the ldu[hb] insns.
4020 (define_expand "zero_extendhisi2"
4021 [(set (match_operand:SI 0 "register_operand" "")
4022 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
4025 rtx temp = gen_reg_rtx (SImode);
4026 rtx shift_16 = GEN_INT (16);
4027 int op1_subbyte = 0;
4029 if (GET_CODE (operand1) == SUBREG)
4031 op1_subbyte = SUBREG_BYTE (operand1);
4032 op1_subbyte /= GET_MODE_SIZE (SImode);
4033 op1_subbyte *= GET_MODE_SIZE (SImode);
4034 operand1 = XEXP (operand1, 0);
4037 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4039 emit_insn (gen_lshrsi3 (operand0, temp, shift_16));
4043 (define_insn "*zero_extendhisi2_insn"
4044 [(set (match_operand:SI 0 "register_operand" "=r")
4045 (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
4048 [(set_attr "type" "load")
4049 (set_attr "us3load_type" "3cycle")])
4051 (define_expand "zero_extendqihi2"
4052 [(set (match_operand:HI 0 "register_operand" "")
4053 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
4057 (define_insn "*zero_extendqihi2_insn"
4058 [(set (match_operand:HI 0 "register_operand" "=r,r")
4059 (zero_extend:HI (match_operand:QI 1 "input_operand" "r,m")))]
4060 "GET_CODE (operands[1]) != CONST_INT"
4064 [(set_attr "type" "*,load")
4065 (set_attr "us3load_type" "*,3cycle")])
4067 (define_expand "zero_extendqisi2"
4068 [(set (match_operand:SI 0 "register_operand" "")
4069 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
4073 (define_insn "*zero_extendqisi2_insn"
4074 [(set (match_operand:SI 0 "register_operand" "=r,r")
4075 (zero_extend:SI (match_operand:QI 1 "input_operand" "r,m")))]
4076 "GET_CODE (operands[1]) != CONST_INT"
4080 [(set_attr "type" "*,load")
4081 (set_attr "us3load_type" "*,3cycle")])
4083 (define_expand "zero_extendqidi2"
4084 [(set (match_operand:DI 0 "register_operand" "")
4085 (zero_extend:DI (match_operand:QI 1 "register_operand" "")))]
4089 (define_insn "*zero_extendqidi2_insn"
4090 [(set (match_operand:DI 0 "register_operand" "=r,r")
4091 (zero_extend:DI (match_operand:QI 1 "input_operand" "r,m")))]
4092 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
4096 [(set_attr "type" "*,load")
4097 (set_attr "us3load_type" "*,3cycle")])
4099 (define_expand "zero_extendhidi2"
4100 [(set (match_operand:DI 0 "register_operand" "")
4101 (zero_extend:DI (match_operand:HI 1 "register_operand" "")))]
4104 rtx temp = gen_reg_rtx (DImode);
4105 rtx shift_48 = GEN_INT (48);
4106 int op1_subbyte = 0;
4108 if (GET_CODE (operand1) == SUBREG)
4110 op1_subbyte = SUBREG_BYTE (operand1);
4111 op1_subbyte /= GET_MODE_SIZE (DImode);
4112 op1_subbyte *= GET_MODE_SIZE (DImode);
4113 operand1 = XEXP (operand1, 0);
4116 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
4118 emit_insn (gen_lshrdi3 (operand0, temp, shift_48));
4122 (define_insn "*zero_extendhidi2_insn"
4123 [(set (match_operand:DI 0 "register_operand" "=r")
4124 (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
4127 [(set_attr "type" "load")
4128 (set_attr "us3load_type" "3cycle")])
4131 ;; ??? Write truncdisi pattern using sra?
4133 (define_expand "zero_extendsidi2"
4134 [(set (match_operand:DI 0 "register_operand" "")
4135 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
4139 (define_insn "*zero_extendsidi2_insn_sp64"
4140 [(set (match_operand:DI 0 "register_operand" "=r,r")
4141 (zero_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
4142 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
4146 [(set_attr "type" "shift,load")])
4148 (define_insn_and_split "*zero_extendsidi2_insn_sp32"
4149 [(set (match_operand:DI 0 "register_operand" "=r")
4150 (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
4153 "&& reload_completed"
4154 [(set (match_dup 2) (match_dup 3))
4155 (set (match_dup 4) (match_dup 5))]
4159 dest1 = gen_highpart (SImode, operands[0]);
4160 dest2 = gen_lowpart (SImode, operands[0]);
4162 /* Swap the order in case of overlap. */
4163 if (REGNO (dest1) == REGNO (operands[1]))
4165 operands[2] = dest2;
4166 operands[3] = operands[1];
4167 operands[4] = dest1;
4168 operands[5] = const0_rtx;
4172 operands[2] = dest1;
4173 operands[3] = const0_rtx;
4174 operands[4] = dest2;
4175 operands[5] = operands[1];
4178 [(set_attr "length" "2")])
4180 ;; Simplify comparisons of extended values.
4182 (define_insn "*cmp_zero_extendqisi2"
4184 (compare:CC (zero_extend:SI (match_operand:QI 0 "register_operand" "r"))
4187 "andcc\t%0, 0xff, %%g0"
4188 [(set_attr "type" "compare")])
4190 (define_insn "*cmp_zero_qi"
4192 (compare:CC (match_operand:QI 0 "register_operand" "r")
4195 "andcc\t%0, 0xff, %%g0"
4196 [(set_attr "type" "compare")])
4198 (define_insn "*cmp_zero_extendqisi2_set"
4200 (compare:CC (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
4202 (set (match_operand:SI 0 "register_operand" "=r")
4203 (zero_extend:SI (match_dup 1)))]
4205 "andcc\t%1, 0xff, %0"
4206 [(set_attr "type" "compare")])
4208 (define_insn "*cmp_zero_extendqisi2_andcc_set"
4210 (compare:CC (and:SI (match_operand:SI 1 "register_operand" "r")
4213 (set (match_operand:SI 0 "register_operand" "=r")
4214 (zero_extend:SI (subreg:QI (match_dup 1) 0)))]
4216 "andcc\t%1, 0xff, %0"
4217 [(set_attr "type" "compare")])
4219 (define_insn "*cmp_zero_extendqidi2"
4221 (compare:CCX (zero_extend:DI (match_operand:QI 0 "register_operand" "r"))
4224 "andcc\t%0, 0xff, %%g0"
4225 [(set_attr "type" "compare")])
4227 (define_insn "*cmp_zero_qi_sp64"
4229 (compare:CCX (match_operand:QI 0 "register_operand" "r")
4232 "andcc\t%0, 0xff, %%g0"
4233 [(set_attr "type" "compare")])
4235 (define_insn "*cmp_zero_extendqidi2_set"
4237 (compare:CCX (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
4239 (set (match_operand:DI 0 "register_operand" "=r")
4240 (zero_extend:DI (match_dup 1)))]
4242 "andcc\t%1, 0xff, %0"
4243 [(set_attr "type" "compare")])
4245 (define_insn "*cmp_zero_extendqidi2_andcc_set"
4247 (compare:CCX (and:DI (match_operand:DI 1 "register_operand" "r")
4250 (set (match_operand:DI 0 "register_operand" "=r")
4251 (zero_extend:DI (subreg:QI (match_dup 1) 0)))]
4253 "andcc\t%1, 0xff, %0"
4254 [(set_attr "type" "compare")])
4256 ;; Similarly, handle {SI,DI}->QI mode truncation followed by a compare.
4258 (define_insn "*cmp_siqi_trunc"
4260 (compare:CC (subreg:QI (match_operand:SI 0 "register_operand" "r") 3)
4263 "andcc\t%0, 0xff, %%g0"
4264 [(set_attr "type" "compare")])
4266 (define_insn "*cmp_siqi_trunc_set"
4268 (compare:CC (subreg:QI (match_operand:SI 1 "register_operand" "r") 3)
4270 (set (match_operand:QI 0 "register_operand" "=r")
4271 (subreg:QI (match_dup 1) 3))]
4273 "andcc\t%1, 0xff, %0"
4274 [(set_attr "type" "compare")])
4276 (define_insn "*cmp_diqi_trunc"
4278 (compare:CC (subreg:QI (match_operand:DI 0 "register_operand" "r") 7)
4281 "andcc\t%0, 0xff, %%g0"
4282 [(set_attr "type" "compare")])
4284 (define_insn "*cmp_diqi_trunc_set"
4286 (compare:CC (subreg:QI (match_operand:DI 1 "register_operand" "r") 7)
4288 (set (match_operand:QI 0 "register_operand" "=r")
4289 (subreg:QI (match_dup 1) 7))]
4291 "andcc\t%1, 0xff, %0"
4292 [(set_attr "type" "compare")])
4294 ;;- sign extension instructions
4296 ;; These patterns originally accepted general_operands, however, slightly
4297 ;; better code is generated by only accepting register_operands, and then
4298 ;; letting combine generate the lds[hb] insns.
4300 (define_expand "extendhisi2"
4301 [(set (match_operand:SI 0 "register_operand" "")
4302 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
4305 rtx temp = gen_reg_rtx (SImode);
4306 rtx shift_16 = GEN_INT (16);
4307 int op1_subbyte = 0;
4309 if (GET_CODE (operand1) == SUBREG)
4311 op1_subbyte = SUBREG_BYTE (operand1);
4312 op1_subbyte /= GET_MODE_SIZE (SImode);
4313 op1_subbyte *= GET_MODE_SIZE (SImode);
4314 operand1 = XEXP (operand1, 0);
4317 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4319 emit_insn (gen_ashrsi3 (operand0, temp, shift_16));
4323 (define_insn "*sign_extendhisi2_insn"
4324 [(set (match_operand:SI 0 "register_operand" "=r")
4325 (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
4328 [(set_attr "type" "sload")
4329 (set_attr "us3load_type" "3cycle")])
4331 (define_expand "extendqihi2"
4332 [(set (match_operand:HI 0 "register_operand" "")
4333 (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
4336 rtx temp = gen_reg_rtx (SImode);
4337 rtx shift_24 = GEN_INT (24);
4338 int op1_subbyte = 0;
4339 int op0_subbyte = 0;
4341 if (GET_CODE (operand1) == SUBREG)
4343 op1_subbyte = SUBREG_BYTE (operand1);
4344 op1_subbyte /= GET_MODE_SIZE (SImode);
4345 op1_subbyte *= GET_MODE_SIZE (SImode);
4346 operand1 = XEXP (operand1, 0);
4348 if (GET_CODE (operand0) == SUBREG)
4350 op0_subbyte = SUBREG_BYTE (operand0);
4351 op0_subbyte /= GET_MODE_SIZE (SImode);
4352 op0_subbyte *= GET_MODE_SIZE (SImode);
4353 operand0 = XEXP (operand0, 0);
4355 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4357 if (GET_MODE (operand0) != SImode)
4358 operand0 = gen_rtx_SUBREG (SImode, operand0, op0_subbyte);
4359 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
4363 (define_insn "*sign_extendqihi2_insn"
4364 [(set (match_operand:HI 0 "register_operand" "=r")
4365 (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
4368 [(set_attr "type" "sload")
4369 (set_attr "us3load_type" "3cycle")])
4371 (define_expand "extendqisi2"
4372 [(set (match_operand:SI 0 "register_operand" "")
4373 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
4376 rtx temp = gen_reg_rtx (SImode);
4377 rtx shift_24 = GEN_INT (24);
4378 int op1_subbyte = 0;
4380 if (GET_CODE (operand1) == SUBREG)
4382 op1_subbyte = SUBREG_BYTE (operand1);
4383 op1_subbyte /= GET_MODE_SIZE (SImode);
4384 op1_subbyte *= GET_MODE_SIZE (SImode);
4385 operand1 = XEXP (operand1, 0);
4388 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4390 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
4394 (define_insn "*sign_extendqisi2_insn"
4395 [(set (match_operand:SI 0 "register_operand" "=r")
4396 (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
4399 [(set_attr "type" "sload")
4400 (set_attr "us3load_type" "3cycle")])
4402 (define_expand "extendqidi2"
4403 [(set (match_operand:DI 0 "register_operand" "")
4404 (sign_extend:DI (match_operand:QI 1 "register_operand" "")))]
4407 rtx temp = gen_reg_rtx (DImode);
4408 rtx shift_56 = GEN_INT (56);
4409 int op1_subbyte = 0;
4411 if (GET_CODE (operand1) == SUBREG)
4413 op1_subbyte = SUBREG_BYTE (operand1);
4414 op1_subbyte /= GET_MODE_SIZE (DImode);
4415 op1_subbyte *= GET_MODE_SIZE (DImode);
4416 operand1 = XEXP (operand1, 0);
4419 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
4421 emit_insn (gen_ashrdi3 (operand0, temp, shift_56));
4425 (define_insn "*sign_extendqidi2_insn"
4426 [(set (match_operand:DI 0 "register_operand" "=r")
4427 (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
4430 [(set_attr "type" "sload")
4431 (set_attr "us3load_type" "3cycle")])
4433 (define_expand "extendhidi2"
4434 [(set (match_operand:DI 0 "register_operand" "")
4435 (sign_extend:DI (match_operand:HI 1 "register_operand" "")))]
4438 rtx temp = gen_reg_rtx (DImode);
4439 rtx shift_48 = GEN_INT (48);
4440 int op1_subbyte = 0;
4442 if (GET_CODE (operand1) == SUBREG)
4444 op1_subbyte = SUBREG_BYTE (operand1);
4445 op1_subbyte /= GET_MODE_SIZE (DImode);
4446 op1_subbyte *= GET_MODE_SIZE (DImode);
4447 operand1 = XEXP (operand1, 0);
4450 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
4452 emit_insn (gen_ashrdi3 (operand0, temp, shift_48));
4456 (define_insn "*sign_extendhidi2_insn"
4457 [(set (match_operand:DI 0 "register_operand" "=r")
4458 (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
4461 [(set_attr "type" "sload")
4462 (set_attr "us3load_type" "3cycle")])
4464 (define_expand "extendsidi2"
4465 [(set (match_operand:DI 0 "register_operand" "")
4466 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
4470 (define_insn "*sign_extendsidi2_insn"
4471 [(set (match_operand:DI 0 "register_operand" "=r,r")
4472 (sign_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
4477 [(set_attr "type" "shift,sload")
4478 (set_attr "us3load_type" "*,3cycle")])
4480 ;; Special pattern for optimizing bit-field compares. This is needed
4481 ;; because combine uses this as a canonical form.
4483 (define_insn "*cmp_zero_extract"
4486 (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
4487 (match_operand:SI 1 "small_int_or_double" "n")
4488 (match_operand:SI 2 "small_int_or_double" "n"))
4490 "(GET_CODE (operands[2]) == CONST_INT
4491 && INTVAL (operands[2]) > 19)
4492 || (GET_CODE (operands[2]) == CONST_DOUBLE
4493 && CONST_DOUBLE_LOW (operands[2]) > 19)"
4495 int len = (GET_CODE (operands[1]) == CONST_INT
4496 ? INTVAL (operands[1])
4497 : CONST_DOUBLE_LOW (operands[1]));
4499 (GET_CODE (operands[2]) == CONST_INT
4500 ? INTVAL (operands[2])
4501 : CONST_DOUBLE_LOW (operands[2])) - len;
4502 HOST_WIDE_INT mask = ((1 << len) - 1) << pos;
4504 operands[1] = GEN_INT (mask);
4505 return "andcc\t%0, %1, %%g0";
4507 [(set_attr "type" "compare")])
4509 (define_insn "*cmp_zero_extract_sp64"
4512 (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
4513 (match_operand:SI 1 "small_int_or_double" "n")
4514 (match_operand:SI 2 "small_int_or_double" "n"))
4517 && ((GET_CODE (operands[2]) == CONST_INT
4518 && INTVAL (operands[2]) > 51)
4519 || (GET_CODE (operands[2]) == CONST_DOUBLE
4520 && CONST_DOUBLE_LOW (operands[2]) > 51))"
4522 int len = (GET_CODE (operands[1]) == CONST_INT
4523 ? INTVAL (operands[1])
4524 : CONST_DOUBLE_LOW (operands[1]));
4526 (GET_CODE (operands[2]) == CONST_INT
4527 ? INTVAL (operands[2])
4528 : CONST_DOUBLE_LOW (operands[2])) - len;
4529 HOST_WIDE_INT mask = (((unsigned HOST_WIDE_INT) 1 << len) - 1) << pos;
4531 operands[1] = GEN_INT (mask);
4532 return "andcc\t%0, %1, %%g0";
4534 [(set_attr "type" "compare")])
4536 ;; Conversions between float, double and long double.
4538 (define_insn "extendsfdf2"
4539 [(set (match_operand:DF 0 "register_operand" "=e")
4541 (match_operand:SF 1 "register_operand" "f")))]
4544 [(set_attr "type" "fp")
4545 (set_attr "fptype" "double")])
4547 (define_expand "extendsftf2"
4548 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4550 (match_operand:SF 1 "register_operand" "")))]
4551 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4552 "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
4554 (define_insn "*extendsftf2_hq"
4555 [(set (match_operand:TF 0 "register_operand" "=e")
4557 (match_operand:SF 1 "register_operand" "f")))]
4558 "TARGET_FPU && TARGET_HARD_QUAD"
4560 [(set_attr "type" "fp")])
4562 (define_expand "extenddftf2"
4563 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4565 (match_operand:DF 1 "register_operand" "")))]
4566 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4567 "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
4569 (define_insn "*extenddftf2_hq"
4570 [(set (match_operand:TF 0 "register_operand" "=e")
4572 (match_operand:DF 1 "register_operand" "e")))]
4573 "TARGET_FPU && TARGET_HARD_QUAD"
4575 [(set_attr "type" "fp")])
4577 (define_insn "truncdfsf2"
4578 [(set (match_operand:SF 0 "register_operand" "=f")
4580 (match_operand:DF 1 "register_operand" "e")))]
4583 [(set_attr "type" "fp")
4584 (set_attr "fptype" "double")])
4586 (define_expand "trunctfsf2"
4587 [(set (match_operand:SF 0 "register_operand" "")
4589 (match_operand:TF 1 "general_operand" "")))]
4590 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4591 "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
4593 (define_insn "*trunctfsf2_hq"
4594 [(set (match_operand:SF 0 "register_operand" "=f")
4596 (match_operand:TF 1 "register_operand" "e")))]
4597 "TARGET_FPU && TARGET_HARD_QUAD"
4599 [(set_attr "type" "fp")])
4601 (define_expand "trunctfdf2"
4602 [(set (match_operand:DF 0 "register_operand" "")
4604 (match_operand:TF 1 "general_operand" "")))]
4605 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4606 "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
4608 (define_insn "*trunctfdf2_hq"
4609 [(set (match_operand:DF 0 "register_operand" "=e")
4611 (match_operand:TF 1 "register_operand" "e")))]
4612 "TARGET_FPU && TARGET_HARD_QUAD"
4614 [(set_attr "type" "fp")])
4616 ;; Conversion between fixed point and floating point.
4618 (define_insn "floatsisf2"
4619 [(set (match_operand:SF 0 "register_operand" "=f")
4620 (float:SF (match_operand:SI 1 "register_operand" "f")))]
4623 [(set_attr "type" "fp")
4624 (set_attr "fptype" "double")])
4626 (define_insn "floatsidf2"
4627 [(set (match_operand:DF 0 "register_operand" "=e")
4628 (float:DF (match_operand:SI 1 "register_operand" "f")))]
4631 [(set_attr "type" "fp")
4632 (set_attr "fptype" "double")])
4634 (define_expand "floatsitf2"
4635 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4636 (float:TF (match_operand:SI 1 "register_operand" "")))]
4637 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4638 "emit_tfmode_cvt (FLOAT, operands); DONE;")
4640 (define_insn "*floatsitf2_hq"
4641 [(set (match_operand:TF 0 "register_operand" "=e")
4642 (float:TF (match_operand:SI 1 "register_operand" "f")))]
4643 "TARGET_FPU && TARGET_HARD_QUAD"
4645 [(set_attr "type" "fp")])
4647 (define_expand "floatunssitf2"
4648 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4649 (unsigned_float:TF (match_operand:SI 1 "register_operand" "")))]
4650 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4651 "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
4653 ;; Now the same for 64 bit sources.
4655 (define_insn "floatdisf2"
4656 [(set (match_operand:SF 0 "register_operand" "=f")
4657 (float:SF (match_operand:DI 1 "register_operand" "e")))]
4658 "TARGET_V9 && TARGET_FPU"
4660 [(set_attr "type" "fp")
4661 (set_attr "fptype" "double")])
4663 (define_expand "floatunsdisf2"
4664 [(use (match_operand:SF 0 "register_operand" ""))
4665 (use (match_operand:DI 1 "general_operand" ""))]
4666 "TARGET_ARCH64 && TARGET_FPU"
4667 "sparc_emit_floatunsdi (operands, SFmode); DONE;")
4669 (define_insn "floatdidf2"
4670 [(set (match_operand:DF 0 "register_operand" "=e")
4671 (float:DF (match_operand:DI 1 "register_operand" "e")))]
4672 "TARGET_V9 && TARGET_FPU"
4674 [(set_attr "type" "fp")
4675 (set_attr "fptype" "double")])
4677 (define_expand "floatunsdidf2"
4678 [(use (match_operand:DF 0 "register_operand" ""))
4679 (use (match_operand:DI 1 "general_operand" ""))]
4680 "TARGET_ARCH64 && TARGET_FPU"
4681 "sparc_emit_floatunsdi (operands, DFmode); DONE;")
4683 (define_expand "floatditf2"
4684 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4685 (float:TF (match_operand:DI 1 "register_operand" "")))]
4686 "TARGET_FPU && TARGET_V9 && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4687 "emit_tfmode_cvt (FLOAT, operands); DONE;")
4689 (define_insn "*floatditf2_hq"
4690 [(set (match_operand:TF 0 "register_operand" "=e")
4691 (float:TF (match_operand:DI 1 "register_operand" "e")))]
4692 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
4694 [(set_attr "type" "fp")])
4696 (define_expand "floatunsditf2"
4697 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4698 (unsigned_float:TF (match_operand:DI 1 "register_operand" "")))]
4699 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4700 "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
4702 ;; Convert a float to an actual integer.
4703 ;; Truncation is performed as part of the conversion.
4705 (define_insn "fix_truncsfsi2"
4706 [(set (match_operand:SI 0 "register_operand" "=f")
4707 (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
4710 [(set_attr "type" "fp")
4711 (set_attr "fptype" "double")])
4713 (define_insn "fix_truncdfsi2"
4714 [(set (match_operand:SI 0 "register_operand" "=f")
4715 (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
4718 [(set_attr "type" "fp")
4719 (set_attr "fptype" "double")])
4721 (define_expand "fix_trunctfsi2"
4722 [(set (match_operand:SI 0 "register_operand" "")
4723 (fix:SI (match_operand:TF 1 "general_operand" "")))]
4724 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4725 "emit_tfmode_cvt (FIX, operands); DONE;")
4727 (define_insn "*fix_trunctfsi2_hq"
4728 [(set (match_operand:SI 0 "register_operand" "=f")
4729 (fix:SI (match_operand:TF 1 "register_operand" "e")))]
4730 "TARGET_FPU && TARGET_HARD_QUAD"
4732 [(set_attr "type" "fp")])
4734 (define_expand "fixuns_trunctfsi2"
4735 [(set (match_operand:SI 0 "register_operand" "")
4736 (unsigned_fix:SI (match_operand:TF 1 "general_operand" "")))]
4737 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4738 "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
4740 ;; Now the same, for V9 targets
4742 (define_insn "fix_truncsfdi2"
4743 [(set (match_operand:DI 0 "register_operand" "=e")
4744 (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
4745 "TARGET_V9 && TARGET_FPU"
4747 [(set_attr "type" "fp")
4748 (set_attr "fptype" "double")])
4750 (define_expand "fixuns_truncsfdi2"
4751 [(use (match_operand:DI 0 "register_operand" ""))
4752 (use (match_operand:SF 1 "general_operand" ""))]
4753 "TARGET_ARCH64 && TARGET_FPU"
4754 "sparc_emit_fixunsdi (operands, SFmode); DONE;")
4756 (define_insn "fix_truncdfdi2"
4757 [(set (match_operand:DI 0 "register_operand" "=e")
4758 (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
4759 "TARGET_V9 && TARGET_FPU"
4761 [(set_attr "type" "fp")
4762 (set_attr "fptype" "double")])
4764 (define_expand "fixuns_truncdfdi2"
4765 [(use (match_operand:DI 0 "register_operand" ""))
4766 (use (match_operand:DF 1 "general_operand" ""))]
4767 "TARGET_ARCH64 && TARGET_FPU"
4768 "sparc_emit_fixunsdi (operands, DFmode); DONE;")
4770 (define_expand "fix_trunctfdi2"
4771 [(set (match_operand:DI 0 "register_operand" "")
4772 (fix:DI (match_operand:TF 1 "general_operand" "")))]
4773 "TARGET_V9 && TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4774 "emit_tfmode_cvt (FIX, operands); DONE;")
4776 (define_insn "*fix_trunctfdi2_hq"
4777 [(set (match_operand:DI 0 "register_operand" "=e")
4778 (fix:DI (match_operand:TF 1 "register_operand" "e")))]
4779 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
4781 [(set_attr "type" "fp")])
4783 (define_expand "fixuns_trunctfdi2"
4784 [(set (match_operand:DI 0 "register_operand" "")
4785 (unsigned_fix:DI (match_operand:TF 1 "general_operand" "")))]
4786 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4787 "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
4789 ;;- arithmetic instructions
4791 (define_expand "adddi3"
4792 [(set (match_operand:DI 0 "register_operand" "")
4793 (plus:DI (match_operand:DI 1 "register_operand" "")
4794 (match_operand:DI 2 "arith_double_add_operand" "")))]
4797 if (! TARGET_ARCH64)
4799 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
4800 gen_rtx_SET (VOIDmode, operands[0],
4801 gen_rtx_PLUS (DImode, operands[1],
4803 gen_rtx_CLOBBER (VOIDmode,
4804 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
4809 (define_insn_and_split "adddi3_insn_sp32"
4810 [(set (match_operand:DI 0 "register_operand" "=r")
4811 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
4812 (match_operand:DI 2 "arith_double_operand" "rHI")))
4813 (clobber (reg:CC 100))]
4816 "&& reload_completed"
4817 [(parallel [(set (reg:CC_NOOV 100)
4818 (compare:CC_NOOV (plus:SI (match_dup 4)
4822 (plus:SI (match_dup 4) (match_dup 5)))])
4824 (plus:SI (plus:SI (match_dup 7)
4826 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4828 operands[3] = gen_lowpart (SImode, operands[0]);
4829 operands[4] = gen_lowpart (SImode, operands[1]);
4830 operands[5] = gen_lowpart (SImode, operands[2]);
4831 operands[6] = gen_highpart (SImode, operands[0]);
4832 operands[7] = gen_highpart_mode (SImode, DImode, operands[1]);
4833 #if HOST_BITS_PER_WIDE_INT == 32
4834 if (GET_CODE (operands[2]) == CONST_INT)
4836 if (INTVAL (operands[2]) < 0)
4837 operands[8] = constm1_rtx;
4839 operands[8] = const0_rtx;
4843 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
4845 [(set_attr "length" "2")])
4848 [(set (match_operand:DI 0 "register_operand" "")
4849 (minus:DI (match_operand:DI 1 "arith_double_operand" "")
4850 (match_operand:DI 2 "arith_double_operand" "")))
4851 (clobber (reg:CC 100))]
4852 "! TARGET_ARCH64 && reload_completed"
4853 [(parallel [(set (reg:CC_NOOV 100)
4854 (compare:CC_NOOV (minus:SI (match_dup 4)
4858 (minus:SI (match_dup 4) (match_dup 5)))])
4860 (minus:SI (minus:SI (match_dup 7)
4862 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4864 operands[3] = gen_lowpart (SImode, operands[0]);
4865 operands[4] = gen_lowpart (SImode, operands[1]);
4866 operands[5] = gen_lowpart (SImode, operands[2]);
4867 operands[6] = gen_highpart (SImode, operands[0]);
4868 operands[7] = gen_highpart (SImode, operands[1]);
4869 #if HOST_BITS_PER_WIDE_INT == 32
4870 if (GET_CODE (operands[2]) == CONST_INT)
4872 if (INTVAL (operands[2]) < 0)
4873 operands[8] = constm1_rtx;
4875 operands[8] = const0_rtx;
4879 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
4882 ;; LTU here means "carry set"
4884 [(set (match_operand:SI 0 "register_operand" "=r")
4885 (plus:SI (plus:SI (match_operand:SI 1 "arith_operand" "%r")
4886 (match_operand:SI 2 "arith_operand" "rI"))
4887 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4890 [(set_attr "type" "ialuX")])
4892 (define_insn_and_split "*addx_extend_sp32"
4893 [(set (match_operand:DI 0 "register_operand" "=r")
4894 (zero_extend:DI (plus:SI (plus:SI
4895 (match_operand:SI 1 "reg_or_0_operand" "%rJ")
4896 (match_operand:SI 2 "arith_operand" "rI"))
4897 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4900 "&& reload_completed"
4901 [(set (match_dup 3) (plus:SI (plus:SI (match_dup 1) (match_dup 2))
4902 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
4903 (set (match_dup 4) (const_int 0))]
4904 "operands[3] = gen_lowpart (SImode, operands[0]);
4905 operands[4] = gen_highpart_mode (SImode, DImode, operands[1]);"
4906 [(set_attr "length" "2")])
4908 (define_insn "*addx_extend_sp64"
4909 [(set (match_operand:DI 0 "register_operand" "=r")
4910 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
4911 (match_operand:SI 2 "arith_operand" "rI"))
4912 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4915 [(set_attr "type" "ialuX")])
4918 [(set (match_operand:SI 0 "register_operand" "=r")
4919 (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
4920 (match_operand:SI 2 "arith_operand" "rI"))
4921 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4924 [(set_attr "type" "ialuX")])
4926 (define_insn "*subx_extend_sp64"
4927 [(set (match_operand:DI 0 "register_operand" "=r")
4928 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
4929 (match_operand:SI 2 "arith_operand" "rI"))
4930 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4933 [(set_attr "type" "ialuX")])
4935 (define_insn_and_split "*subx_extend"
4936 [(set (match_operand:DI 0 "register_operand" "=r")
4937 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
4938 (match_operand:SI 2 "arith_operand" "rI"))
4939 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4942 "&& reload_completed"
4943 [(set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 2))
4944 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
4945 (set (match_dup 4) (const_int 0))]
4946 "operands[3] = gen_lowpart (SImode, operands[0]);
4947 operands[4] = gen_highpart (SImode, operands[0]);"
4948 [(set_attr "length" "2")])
4950 (define_insn_and_split ""
4951 [(set (match_operand:DI 0 "register_operand" "=r")
4952 (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4953 (match_operand:DI 2 "register_operand" "r")))
4954 (clobber (reg:CC 100))]
4957 "&& reload_completed"
4958 [(parallel [(set (reg:CC_NOOV 100)
4959 (compare:CC_NOOV (plus:SI (match_dup 3) (match_dup 1))
4961 (set (match_dup 5) (plus:SI (match_dup 3) (match_dup 1)))])
4963 (plus:SI (plus:SI (match_dup 4) (const_int 0))
4964 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4965 "operands[3] = gen_lowpart (SImode, operands[2]);
4966 operands[4] = gen_highpart (SImode, operands[2]);
4967 operands[5] = gen_lowpart (SImode, operands[0]);
4968 operands[6] = gen_highpart (SImode, operands[0]);"
4969 [(set_attr "length" "2")])
4971 (define_insn "*adddi3_sp64"
4972 [(set (match_operand:DI 0 "register_operand" "=r,r")
4973 (plus:DI (match_operand:DI 1 "register_operand" "%r,r")
4974 (match_operand:DI 2 "arith_double_add_operand" "rHI,O")))]
4980 (define_insn "addsi3"
4981 [(set (match_operand:SI 0 "register_operand" "=r,r,d")
4982 (plus:SI (match_operand:SI 1 "register_operand" "%r,r,d")
4983 (match_operand:SI 2 "arith_add_operand" "rI,O,d")))]
4988 fpadd32s\t%1, %2, %0"
4989 [(set_attr "type" "*,*,fga")])
4991 (define_insn "*cmp_cc_plus"
4992 [(set (reg:CC_NOOV 100)
4993 (compare:CC_NOOV (plus:SI (match_operand:SI 0 "arith_operand" "%r")
4994 (match_operand:SI 1 "arith_operand" "rI"))
4997 "addcc\t%0, %1, %%g0"
4998 [(set_attr "type" "compare")])
5000 (define_insn "*cmp_ccx_plus"
5001 [(set (reg:CCX_NOOV 100)
5002 (compare:CCX_NOOV (plus:DI (match_operand:DI 0 "arith_double_operand" "%r")
5003 (match_operand:DI 1 "arith_double_operand" "rHI"))
5006 "addcc\t%0, %1, %%g0"
5007 [(set_attr "type" "compare")])
5009 (define_insn "*cmp_cc_plus_set"
5010 [(set (reg:CC_NOOV 100)
5011 (compare:CC_NOOV (plus:SI (match_operand:SI 1 "arith_operand" "%r")
5012 (match_operand:SI 2 "arith_operand" "rI"))
5014 (set (match_operand:SI 0 "register_operand" "=r")
5015 (plus:SI (match_dup 1) (match_dup 2)))]
5018 [(set_attr "type" "compare")])
5020 (define_insn "*cmp_ccx_plus_set"
5021 [(set (reg:CCX_NOOV 100)
5022 (compare:CCX_NOOV (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
5023 (match_operand:DI 2 "arith_double_operand" "rHI"))
5025 (set (match_operand:DI 0 "register_operand" "=r")
5026 (plus:DI (match_dup 1) (match_dup 2)))]
5029 [(set_attr "type" "compare")])
5031 (define_expand "subdi3"
5032 [(set (match_operand:DI 0 "register_operand" "")
5033 (minus:DI (match_operand:DI 1 "register_operand" "")
5034 (match_operand:DI 2 "arith_double_add_operand" "")))]
5037 if (! TARGET_ARCH64)
5039 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
5040 gen_rtx_SET (VOIDmode, operands[0],
5041 gen_rtx_MINUS (DImode, operands[1],
5043 gen_rtx_CLOBBER (VOIDmode,
5044 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
5049 (define_insn_and_split "*subdi3_sp32"
5050 [(set (match_operand:DI 0 "register_operand" "=r")
5051 (minus:DI (match_operand:DI 1 "register_operand" "r")
5052 (match_operand:DI 2 "arith_double_operand" "rHI")))
5053 (clobber (reg:CC 100))]
5056 "&& reload_completed
5057 && (GET_CODE (operands[2]) == CONST_INT
5058 || GET_CODE (operands[2]) == CONST_DOUBLE)"
5059 [(clobber (const_int 0))]
5063 highp = gen_highpart_mode (SImode, DImode, operands[2]);
5064 lowp = gen_lowpart (SImode, operands[2]);
5065 if ((lowp == const0_rtx)
5066 && (operands[0] == operands[1]))
5068 emit_insn (gen_rtx_SET (VOIDmode,
5069 gen_highpart (SImode, operands[0]),
5070 gen_rtx_MINUS (SImode,
5071 gen_highpart_mode (SImode, DImode,
5077 emit_insn (gen_cmp_minus_cc_set (gen_lowpart (SImode, operands[0]),
5078 gen_lowpart (SImode, operands[1]),
5080 emit_insn (gen_subx (gen_highpart (SImode, operands[0]),
5081 gen_highpart_mode (SImode, DImode, operands[1]),
5086 [(set_attr "length" "2")])
5089 [(set (match_operand:DI 0 "register_operand" "")
5090 (minus:DI (match_operand:DI 1 "register_operand" "")
5091 (match_operand:DI 2 "register_operand" "")))
5092 (clobber (reg:CC 100))]
5094 && reload_completed"
5095 [(clobber (const_int 0))]
5097 emit_insn (gen_cmp_minus_cc_set (gen_lowpart (SImode, operands[0]),
5098 gen_lowpart (SImode, operands[1]),
5099 gen_lowpart (SImode, operands[2])));
5100 emit_insn (gen_subx (gen_highpart (SImode, operands[0]),
5101 gen_highpart (SImode, operands[1]),
5102 gen_highpart (SImode, operands[2])));
5106 (define_insn_and_split ""
5107 [(set (match_operand:DI 0 "register_operand" "=r")
5108 (minus:DI (match_operand:DI 1 "register_operand" "r")
5109 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))
5110 (clobber (reg:CC 100))]
5113 "&& reload_completed"
5114 [(parallel [(set (reg:CC_NOOV 100)
5115 (compare:CC_NOOV (minus:SI (match_dup 3) (match_dup 2))
5117 (set (match_dup 5) (minus:SI (match_dup 3) (match_dup 2)))])
5119 (minus:SI (minus:SI (match_dup 4) (const_int 0))
5120 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5121 "operands[3] = gen_lowpart (SImode, operands[1]);
5122 operands[4] = gen_highpart (SImode, operands[1]);
5123 operands[5] = gen_lowpart (SImode, operands[0]);
5124 operands[6] = gen_highpart (SImode, operands[0]);"
5125 [(set_attr "length" "2")])
5127 (define_insn "*subdi3_sp64"
5128 [(set (match_operand:DI 0 "register_operand" "=r,r")
5129 (minus:DI (match_operand:DI 1 "register_operand" "r,r")
5130 (match_operand:DI 2 "arith_double_add_operand" "rHI,O")))]
5136 (define_insn "subsi3"
5137 [(set (match_operand:SI 0 "register_operand" "=r,r,d")
5138 (minus:SI (match_operand:SI 1 "register_operand" "r,r,d")
5139 (match_operand:SI 2 "arith_add_operand" "rI,O,d")))]
5144 fpsub32s\t%1, %2, %0"
5145 [(set_attr "type" "*,*,fga")])
5147 (define_insn "*cmp_minus_cc"
5148 [(set (reg:CC_NOOV 100)
5149 (compare:CC_NOOV (minus:SI (match_operand:SI 0 "reg_or_0_operand" "rJ")
5150 (match_operand:SI 1 "arith_operand" "rI"))
5153 "subcc\t%r0, %1, %%g0"
5154 [(set_attr "type" "compare")])
5156 (define_insn "*cmp_minus_ccx"
5157 [(set (reg:CCX_NOOV 100)
5158 (compare:CCX_NOOV (minus:DI (match_operand:DI 0 "register_operand" "r")
5159 (match_operand:DI 1 "arith_double_operand" "rHI"))
5162 "subcc\t%0, %1, %%g0"
5163 [(set_attr "type" "compare")])
5165 (define_insn "cmp_minus_cc_set"
5166 [(set (reg:CC_NOOV 100)
5167 (compare:CC_NOOV (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5168 (match_operand:SI 2 "arith_operand" "rI"))
5170 (set (match_operand:SI 0 "register_operand" "=r")
5171 (minus:SI (match_dup 1) (match_dup 2)))]
5173 "subcc\t%r1, %2, %0"
5174 [(set_attr "type" "compare")])
5176 (define_insn "*cmp_minus_ccx_set"
5177 [(set (reg:CCX_NOOV 100)
5178 (compare:CCX_NOOV (minus:DI (match_operand:DI 1 "register_operand" "r")
5179 (match_operand:DI 2 "arith_double_operand" "rHI"))
5181 (set (match_operand:DI 0 "register_operand" "=r")
5182 (minus:DI (match_dup 1) (match_dup 2)))]
5185 [(set_attr "type" "compare")])
5187 ;; Integer Multiply/Divide.
5189 ;; The 32 bit multiply/divide instructions are deprecated on v9, but at
5190 ;; least in UltraSPARC I, II and IIi it is a win tick-wise.
5192 (define_insn "mulsi3"
5193 [(set (match_operand:SI 0 "register_operand" "=r")
5194 (mult:SI (match_operand:SI 1 "arith_operand" "%r")
5195 (match_operand:SI 2 "arith_operand" "rI")))]
5198 [(set_attr "type" "imul")])
5200 (define_expand "muldi3"
5201 [(set (match_operand:DI 0 "register_operand" "=r")
5202 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r")
5203 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5204 "TARGET_ARCH64 || TARGET_V8PLUS"
5208 emit_insn (gen_muldi3_v8plus (operands[0], operands[1], operands[2]));
5213 (define_insn "*muldi3_sp64"
5214 [(set (match_operand:DI 0 "register_operand" "=r")
5215 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r")
5216 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5219 [(set_attr "type" "imul")])
5221 ;; V8plus wide multiply.
5223 (define_insn "muldi3_v8plus"
5224 [(set (match_operand:DI 0 "register_operand" "=r,h")
5225 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r,0")
5226 (match_operand:DI 2 "arith_double_operand" "rI,rI")))
5227 (clobber (match_scratch:SI 3 "=&h,X"))
5228 (clobber (match_scratch:SI 4 "=&h,X"))]
5231 if (sparc_check_64 (operands[1], insn) <= 0)
5232 output_asm_insn ("srl\t%L1, 0, %L1", operands);
5233 if (which_alternative == 1)
5234 output_asm_insn ("sllx\t%H1, 32, %H1", operands);
5235 if (GET_CODE (operands[2]) == CONST_INT)
5237 if (which_alternative == 1)
5238 return "or\t%L1, %H1, %H1\n\tmulx\t%H1, %2, %L0\;srlx\t%L0, 32, %H0";
5240 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";
5242 else if (rtx_equal_p (operands[1], operands[2]))
5244 if (which_alternative == 1)
5245 return "or\t%L1, %H1, %H1\n\tmulx\t%H1, %H1, %L0\;srlx\t%L0, 32, %H0";
5247 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";
5249 if (sparc_check_64 (operands[2], insn) <= 0)
5250 output_asm_insn ("srl\t%L2, 0, %L2", operands);
5251 if (which_alternative == 1)
5252 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";
5254 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";
5256 [(set_attr "type" "multi")
5257 (set_attr "length" "9,8")])
5259 (define_insn "*cmp_mul_set"
5261 (compare:CC (mult:SI (match_operand:SI 1 "arith_operand" "%r")
5262 (match_operand:SI 2 "arith_operand" "rI"))
5264 (set (match_operand:SI 0 "register_operand" "=r")
5265 (mult:SI (match_dup 1) (match_dup 2)))]
5266 "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS"
5267 "smulcc\t%1, %2, %0"
5268 [(set_attr "type" "imul")])
5270 (define_expand "mulsidi3"
5271 [(set (match_operand:DI 0 "register_operand" "")
5272 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
5273 (sign_extend:DI (match_operand:SI 2 "arith_operand" ""))))]
5276 if (CONSTANT_P (operands[2]))
5279 emit_insn (gen_const_mulsidi3_v8plus (operands[0], operands[1],
5281 else if (TARGET_ARCH32)
5282 emit_insn (gen_const_mulsidi3_sp32 (operands[0], operands[1],
5285 emit_insn (gen_const_mulsidi3_sp64 (operands[0], operands[1],
5291 emit_insn (gen_mulsidi3_v8plus (operands[0], operands[1], operands[2]));
5296 ;; V9 puts the 64 bit product in a 64 bit register. Only out or global
5297 ;; registers can hold 64 bit values in the V8plus environment.
5299 (define_insn "mulsidi3_v8plus"
5300 [(set (match_operand:DI 0 "register_operand" "=h,r")
5301 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5302 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
5303 (clobber (match_scratch:SI 3 "=X,&h"))]
5306 smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
5307 smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
5308 [(set_attr "type" "multi")
5309 (set_attr "length" "2,3")])
5312 (define_insn "const_mulsidi3_v8plus"
5313 [(set (match_operand:DI 0 "register_operand" "=h,r")
5314 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5315 (match_operand:DI 2 "small_int" "I,I")))
5316 (clobber (match_scratch:SI 3 "=X,&h"))]
5319 smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
5320 smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
5321 [(set_attr "type" "multi")
5322 (set_attr "length" "2,3")])
5325 (define_insn "*mulsidi3_sp32"
5326 [(set (match_operand:DI 0 "register_operand" "=r")
5327 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5328 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
5331 return TARGET_SPARCLET
5332 ? "smuld\t%1, %2, %L0"
5333 : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
5336 (if_then_else (eq_attr "isa" "sparclet")
5337 (const_string "imul") (const_string "multi")))
5338 (set (attr "length")
5339 (if_then_else (eq_attr "isa" "sparclet")
5340 (const_int 1) (const_int 2)))])
5342 (define_insn "*mulsidi3_sp64"
5343 [(set (match_operand:DI 0 "register_operand" "=r")
5344 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5345 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
5346 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5348 [(set_attr "type" "imul")])
5350 ;; Extra pattern, because sign_extend of a constant isn't valid.
5353 (define_insn "const_mulsidi3_sp32"
5354 [(set (match_operand:DI 0 "register_operand" "=r")
5355 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5356 (match_operand:DI 2 "small_int" "I")))]
5359 return TARGET_SPARCLET
5360 ? "smuld\t%1, %2, %L0"
5361 : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
5364 (if_then_else (eq_attr "isa" "sparclet")
5365 (const_string "imul") (const_string "multi")))
5366 (set (attr "length")
5367 (if_then_else (eq_attr "isa" "sparclet")
5368 (const_int 1) (const_int 2)))])
5370 (define_insn "const_mulsidi3_sp64"
5371 [(set (match_operand:DI 0 "register_operand" "=r")
5372 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5373 (match_operand:DI 2 "small_int" "I")))]
5374 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5376 [(set_attr "type" "imul")])
5378 (define_expand "smulsi3_highpart"
5379 [(set (match_operand:SI 0 "register_operand" "")
5381 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
5382 (sign_extend:DI (match_operand:SI 2 "arith_operand" "")))
5384 "TARGET_HARD_MUL && TARGET_ARCH32"
5386 if (CONSTANT_P (operands[2]))
5390 emit_insn (gen_const_smulsi3_highpart_v8plus (operands[0],
5396 emit_insn (gen_const_smulsi3_highpart (operands[0], operands[1], operands[2]));
5401 emit_insn (gen_smulsi3_highpart_v8plus (operands[0], operands[1],
5402 operands[2], GEN_INT (32)));
5408 (define_insn "smulsi3_highpart_v8plus"
5409 [(set (match_operand:SI 0 "register_operand" "=h,r")
5411 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5412 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
5413 (match_operand:SI 3 "const_int_operand" "i,i"))))
5414 (clobber (match_scratch:SI 4 "=X,&h"))]
5417 smul\t%1, %2, %0\;srlx\t%0, %3, %0
5418 smul\t%1, %2, %4\;srlx\t%4, %3, %0"
5419 [(set_attr "type" "multi")
5420 (set_attr "length" "2")])
5422 ;; The combiner changes TRUNCATE in the previous pattern to SUBREG.
5425 [(set (match_operand:SI 0 "register_operand" "=h,r")
5428 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5429 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
5430 (match_operand:SI 3 "const_int_operand" "i,i"))
5432 (clobber (match_scratch:SI 4 "=X,&h"))]
5435 smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
5436 smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
5437 [(set_attr "type" "multi")
5438 (set_attr "length" "2")])
5441 (define_insn "const_smulsi3_highpart_v8plus"
5442 [(set (match_operand:SI 0 "register_operand" "=h,r")
5444 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5445 (match_operand:DI 2 "small_int" "i,i"))
5446 (match_operand:SI 3 "const_int_operand" "i,i"))))
5447 (clobber (match_scratch:SI 4 "=X,&h"))]
5450 smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
5451 smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
5452 [(set_attr "type" "multi")
5453 (set_attr "length" "2")])
5456 (define_insn "*smulsi3_highpart_sp32"
5457 [(set (match_operand:SI 0 "register_operand" "=r")
5459 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5460 (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
5463 "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
5464 [(set_attr "type" "multi")
5465 (set_attr "length" "2")])
5468 (define_insn "const_smulsi3_highpart"
5469 [(set (match_operand:SI 0 "register_operand" "=r")
5471 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5472 (match_operand:DI 2 "small_int" "i"))
5475 "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
5476 [(set_attr "type" "multi")
5477 (set_attr "length" "2")])
5479 (define_expand "umulsidi3"
5480 [(set (match_operand:DI 0 "register_operand" "")
5481 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
5482 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" ""))))]
5485 if (CONSTANT_P (operands[2]))
5488 emit_insn (gen_const_umulsidi3_v8plus (operands[0], operands[1],
5490 else if (TARGET_ARCH32)
5491 emit_insn (gen_const_umulsidi3_sp32 (operands[0], operands[1],
5494 emit_insn (gen_const_umulsidi3_sp64 (operands[0], operands[1],
5500 emit_insn (gen_umulsidi3_v8plus (operands[0], operands[1], operands[2]));
5506 (define_insn "umulsidi3_v8plus"
5507 [(set (match_operand:DI 0 "register_operand" "=h,r")
5508 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5509 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
5510 (clobber (match_scratch:SI 3 "=X,&h"))]
5513 umul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
5514 umul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
5515 [(set_attr "type" "multi")
5516 (set_attr "length" "2,3")])
5519 (define_insn "*umulsidi3_sp32"
5520 [(set (match_operand:DI 0 "register_operand" "=r")
5521 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5522 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
5525 return TARGET_SPARCLET
5526 ? "umuld\t%1, %2, %L0"
5527 : "umul\t%1, %2, %L0\n\trd\t%%y, %H0";
5530 (if_then_else (eq_attr "isa" "sparclet")
5531 (const_string "imul") (const_string "multi")))
5532 (set (attr "length")
5533 (if_then_else (eq_attr "isa" "sparclet")
5534 (const_int 1) (const_int 2)))])
5536 (define_insn "*umulsidi3_sp64"
5537 [(set (match_operand:DI 0 "register_operand" "=r")
5538 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5539 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
5540 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5542 [(set_attr "type" "imul")])
5544 ;; Extra pattern, because sign_extend of a constant isn't valid.
5547 (define_insn "const_umulsidi3_sp32"
5548 [(set (match_operand:DI 0 "register_operand" "=r")
5549 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5550 (match_operand:DI 2 "uns_small_int" "")))]
5553 return TARGET_SPARCLET
5554 ? "umuld\t%1, %s2, %L0"
5555 : "umul\t%1, %s2, %L0\n\trd\t%%y, %H0";
5558 (if_then_else (eq_attr "isa" "sparclet")
5559 (const_string "imul") (const_string "multi")))
5560 (set (attr "length")
5561 (if_then_else (eq_attr "isa" "sparclet")
5562 (const_int 1) (const_int 2)))])
5564 (define_insn "const_umulsidi3_sp64"
5565 [(set (match_operand:DI 0 "register_operand" "=r")
5566 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5567 (match_operand:DI 2 "uns_small_int" "")))]
5568 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5570 [(set_attr "type" "imul")])
5573 (define_insn "const_umulsidi3_v8plus"
5574 [(set (match_operand:DI 0 "register_operand" "=h,r")
5575 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5576 (match_operand:DI 2 "uns_small_int" "")))
5577 (clobber (match_scratch:SI 3 "=X,h"))]
5580 umul\t%1, %s2, %L0\n\tsrlx\t%L0, 32, %H0
5581 umul\t%1, %s2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
5582 [(set_attr "type" "multi")
5583 (set_attr "length" "2,3")])
5585 (define_expand "umulsi3_highpart"
5586 [(set (match_operand:SI 0 "register_operand" "")
5588 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
5589 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" "")))
5591 "TARGET_HARD_MUL && TARGET_ARCH32"
5593 if (CONSTANT_P (operands[2]))
5597 emit_insn (gen_const_umulsi3_highpart_v8plus (operands[0],
5603 emit_insn (gen_const_umulsi3_highpart (operands[0], operands[1], operands[2]));
5608 emit_insn (gen_umulsi3_highpart_v8plus (operands[0], operands[1],
5609 operands[2], GEN_INT (32)));
5615 (define_insn "umulsi3_highpart_v8plus"
5616 [(set (match_operand:SI 0 "register_operand" "=h,r")
5618 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5619 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
5620 (match_operand:SI 3 "const_int_operand" "i,i"))))
5621 (clobber (match_scratch:SI 4 "=X,h"))]
5624 umul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
5625 umul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
5626 [(set_attr "type" "multi")
5627 (set_attr "length" "2")])
5630 (define_insn "const_umulsi3_highpart_v8plus"
5631 [(set (match_operand:SI 0 "register_operand" "=h,r")
5633 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5634 (match_operand:DI 2 "uns_small_int" ""))
5635 (match_operand:SI 3 "const_int_operand" "i,i"))))
5636 (clobber (match_scratch:SI 4 "=X,h"))]
5639 umul\t%1, %s2, %0\n\tsrlx\t%0, %3, %0
5640 umul\t%1, %s2, %4\n\tsrlx\t%4, %3, %0"
5641 [(set_attr "type" "multi")
5642 (set_attr "length" "2")])
5645 (define_insn "*umulsi3_highpart_sp32"
5646 [(set (match_operand:SI 0 "register_operand" "=r")
5648 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5649 (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
5652 "umul\t%1, %2, %%g0\n\trd\t%%y, %0"
5653 [(set_attr "type" "multi")
5654 (set_attr "length" "2")])
5657 (define_insn "const_umulsi3_highpart"
5658 [(set (match_operand:SI 0 "register_operand" "=r")
5660 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5661 (match_operand:DI 2 "uns_small_int" ""))
5664 "umul\t%1, %s2, %%g0\n\trd\t%%y, %0"
5665 [(set_attr "type" "multi")
5666 (set_attr "length" "2")])
5668 ;; The v8 architecture specifies that there must be 3 instructions between
5669 ;; a y register write and a use of it for correct results.
5671 (define_expand "divsi3"
5672 [(parallel [(set (match_operand:SI 0 "register_operand" "=r,r")
5673 (div:SI (match_operand:SI 1 "register_operand" "r,r")
5674 (match_operand:SI 2 "input_operand" "rI,m")))
5675 (clobber (match_scratch:SI 3 "=&r,&r"))])]
5676 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
5680 operands[3] = gen_reg_rtx(SImode);
5681 emit_insn (gen_ashrsi3 (operands[3], operands[1], GEN_INT (31)));
5682 emit_insn (gen_divsi3_sp64 (operands[0], operands[1], operands[2],
5688 (define_insn "divsi3_sp32"
5689 [(set (match_operand:SI 0 "register_operand" "=r,r")
5690 (div:SI (match_operand:SI 1 "register_operand" "r,r")
5691 (match_operand:SI 2 "input_operand" "rI,m")))
5692 (clobber (match_scratch:SI 3 "=&r,&r"))]
5693 "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS)
5696 if (which_alternative == 0)
5698 return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tsdiv\t%1, %2, %0";
5700 return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tnop\n\tnop\n\tnop\n\tsdiv\t%1, %2, %0";
5703 return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tld\t%2, %3\n\tsdiv\t%1, %3, %0";
5705 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";
5707 [(set_attr "type" "multi")
5708 (set (attr "length")
5709 (if_then_else (eq_attr "isa" "v9")
5710 (const_int 4) (const_int 6)))])
5712 (define_insn "divsi3_sp64"
5713 [(set (match_operand:SI 0 "register_operand" "=r")
5714 (div:SI (match_operand:SI 1 "register_operand" "r")
5715 (match_operand:SI 2 "input_operand" "rI")))
5716 (use (match_operand:SI 3 "register_operand" "r"))]
5717 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5718 "wr\t%%g0, %3, %%y\n\tsdiv\t%1, %2, %0"
5719 [(set_attr "type" "multi")
5720 (set_attr "length" "2")])
5722 (define_insn "divdi3"
5723 [(set (match_operand:DI 0 "register_operand" "=r")
5724 (div:DI (match_operand:DI 1 "register_operand" "r")
5725 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5728 [(set_attr "type" "idiv")])
5730 (define_insn "*cmp_sdiv_cc_set"
5732 (compare:CC (div:SI (match_operand:SI 1 "register_operand" "r")
5733 (match_operand:SI 2 "arith_operand" "rI"))
5735 (set (match_operand:SI 0 "register_operand" "=r")
5736 (div:SI (match_dup 1) (match_dup 2)))
5737 (clobber (match_scratch:SI 3 "=&r"))]
5738 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
5741 return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tsdivcc\t%1, %2, %0";
5743 return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tnop\n\tnop\n\tnop\n\tsdivcc\t%1, %2, %0";
5745 [(set_attr "type" "multi")
5746 (set (attr "length")
5747 (if_then_else (eq_attr "isa" "v9")
5748 (const_int 3) (const_int 6)))])
5751 (define_expand "udivsi3"
5752 [(set (match_operand:SI 0 "register_operand" "")
5753 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "")
5754 (match_operand:SI 2 "input_operand" "")))]
5755 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
5758 (define_insn "udivsi3_sp32"
5759 [(set (match_operand:SI 0 "register_operand" "=r,&r,&r")
5760 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "r,r,m")
5761 (match_operand:SI 2 "input_operand" "rI,m,r")))]
5763 || TARGET_DEPRECATED_V8_INSNS)
5766 output_asm_insn ("wr\t%%g0, %%g0, %%y", operands);
5767 switch (which_alternative)
5770 return "nop\n\tnop\n\tnop\n\tudiv\t%1, %2, %0";
5772 return "ld\t%2, %0\n\tnop\n\tnop\n\tudiv\t%1, %0, %0";
5774 return "ld\t%1, %0\n\tnop\n\tnop\n\tudiv\t%0, %2, %0";
5777 [(set_attr "type" "multi")
5778 (set_attr "length" "5")])
5780 (define_insn "udivsi3_sp64"
5781 [(set (match_operand:SI 0 "register_operand" "=r")
5782 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "r")
5783 (match_operand:SI 2 "input_operand" "rI")))]
5784 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5785 "wr\t%%g0, 0, %%y\n\tudiv\t%1, %2, %0"
5786 [(set_attr "type" "multi")
5787 (set_attr "length" "2")])
5789 (define_insn "udivdi3"
5790 [(set (match_operand:DI 0 "register_operand" "=r")
5791 (udiv:DI (match_operand:DI 1 "register_operand" "r")
5792 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5795 [(set_attr "type" "idiv")])
5797 (define_insn "*cmp_udiv_cc_set"
5799 (compare:CC (udiv:SI (match_operand:SI 1 "register_operand" "r")
5800 (match_operand:SI 2 "arith_operand" "rI"))
5802 (set (match_operand:SI 0 "register_operand" "=r")
5803 (udiv:SI (match_dup 1) (match_dup 2)))]
5805 || TARGET_DEPRECATED_V8_INSNS"
5808 return "wr\t%%g0, %%g0, %%y\n\tudivcc\t%1, %2, %0";
5810 return "wr\t%%g0, %%g0, %%y\n\tnop\n\tnop\n\tnop\n\tudivcc\t%1, %2, %0";
5812 [(set_attr "type" "multi")
5813 (set (attr "length")
5814 (if_then_else (eq_attr "isa" "v9")
5815 (const_int 2) (const_int 5)))])
5817 ; sparclet multiply/accumulate insns
5819 (define_insn "*smacsi"
5820 [(set (match_operand:SI 0 "register_operand" "=r")
5821 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "%r")
5822 (match_operand:SI 2 "arith_operand" "rI"))
5823 (match_operand:SI 3 "register_operand" "0")))]
5826 [(set_attr "type" "imul")])
5828 (define_insn "*smacdi"
5829 [(set (match_operand:DI 0 "register_operand" "=r")
5830 (plus:DI (mult:DI (sign_extend:DI
5831 (match_operand:SI 1 "register_operand" "%r"))
5833 (match_operand:SI 2 "register_operand" "r")))
5834 (match_operand:DI 3 "register_operand" "0")))]
5836 "smacd\t%1, %2, %L0"
5837 [(set_attr "type" "imul")])
5839 (define_insn "*umacdi"
5840 [(set (match_operand:DI 0 "register_operand" "=r")
5841 (plus:DI (mult:DI (zero_extend:DI
5842 (match_operand:SI 1 "register_operand" "%r"))
5844 (match_operand:SI 2 "register_operand" "r")))
5845 (match_operand:DI 3 "register_operand" "0")))]
5847 "umacd\t%1, %2, %L0"
5848 [(set_attr "type" "imul")])
5850 ;;- Boolean instructions
5851 ;; We define DImode `and' so with DImode `not' we can get
5852 ;; DImode `andn'. Other combinations are possible.
5854 (define_expand "anddi3"
5855 [(set (match_operand:DI 0 "register_operand" "")
5856 (and:DI (match_operand:DI 1 "arith_double_operand" "")
5857 (match_operand:DI 2 "arith_double_operand" "")))]
5861 (define_insn "*anddi3_sp32"
5862 [(set (match_operand:DI 0 "register_operand" "=r,b")
5863 (and:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
5864 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
5869 [(set_attr "type" "*,fga")
5870 (set_attr "length" "2,*")
5871 (set_attr "fptype" "double")])
5873 (define_insn "*anddi3_sp64"
5874 [(set (match_operand:DI 0 "register_operand" "=r,b")
5875 (and:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
5876 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
5881 [(set_attr "type" "*,fga")
5882 (set_attr "fptype" "double")])
5884 (define_insn "andsi3"
5885 [(set (match_operand:SI 0 "register_operand" "=r,d")
5886 (and:SI (match_operand:SI 1 "arith_operand" "%r,d")
5887 (match_operand:SI 2 "arith_operand" "rI,d")))]
5892 [(set_attr "type" "*,fga")])
5895 [(set (match_operand:SI 0 "register_operand" "")
5896 (and:SI (match_operand:SI 1 "register_operand" "")
5897 (match_operand:SI 2 "" "")))
5898 (clobber (match_operand:SI 3 "register_operand" ""))]
5899 "GET_CODE (operands[2]) == CONST_INT
5900 && !SMALL_INT32 (operands[2])
5901 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
5902 [(set (match_dup 3) (match_dup 4))
5903 (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 1)))]
5905 operands[4] = GEN_INT (~INTVAL (operands[2]));
5908 ;; Split DImode logical operations requiring two instructions.
5910 [(set (match_operand:DI 0 "register_operand" "")
5911 (match_operator:DI 1 "cc_arithop" ; AND, IOR, XOR
5912 [(match_operand:DI 2 "register_operand" "")
5913 (match_operand:DI 3 "arith_double_operand" "")]))]
5916 && ((GET_CODE (operands[0]) == REG
5917 && REGNO (operands[0]) < 32)
5918 || (GET_CODE (operands[0]) == SUBREG
5919 && GET_CODE (SUBREG_REG (operands[0])) == REG
5920 && REGNO (SUBREG_REG (operands[0])) < 32))"
5921 [(set (match_dup 4) (match_op_dup:SI 1 [(match_dup 6) (match_dup 8)]))
5922 (set (match_dup 5) (match_op_dup:SI 1 [(match_dup 7) (match_dup 9)]))]
5924 operands[4] = gen_highpart (SImode, operands[0]);
5925 operands[5] = gen_lowpart (SImode, operands[0]);
5926 operands[6] = gen_highpart (SImode, operands[2]);
5927 operands[7] = gen_lowpart (SImode, operands[2]);
5928 #if HOST_BITS_PER_WIDE_INT == 32
5929 if (GET_CODE (operands[3]) == CONST_INT)
5931 if (INTVAL (operands[3]) < 0)
5932 operands[8] = constm1_rtx;
5934 operands[8] = const0_rtx;
5938 operands[8] = gen_highpart_mode (SImode, DImode, operands[3]);
5939 operands[9] = gen_lowpart (SImode, operands[3]);
5942 (define_insn_and_split "*and_not_di_sp32"
5943 [(set (match_operand:DI 0 "register_operand" "=r,b")
5944 (and:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
5945 (match_operand:DI 2 "register_operand" "r,b")))]
5949 fandnot1\t%1, %2, %0"
5950 "&& reload_completed
5951 && ((GET_CODE (operands[0]) == REG
5952 && REGNO (operands[0]) < 32)
5953 || (GET_CODE (operands[0]) == SUBREG
5954 && GET_CODE (SUBREG_REG (operands[0])) == REG
5955 && REGNO (SUBREG_REG (operands[0])) < 32))"
5956 [(set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))
5957 (set (match_dup 6) (and:SI (not:SI (match_dup 7)) (match_dup 8)))]
5958 "operands[3] = gen_highpart (SImode, operands[0]);
5959 operands[4] = gen_highpart (SImode, operands[1]);
5960 operands[5] = gen_highpart (SImode, operands[2]);
5961 operands[6] = gen_lowpart (SImode, operands[0]);
5962 operands[7] = gen_lowpart (SImode, operands[1]);
5963 operands[8] = gen_lowpart (SImode, operands[2]);"
5964 [(set_attr "type" "*,fga")
5965 (set_attr "length" "2,*")
5966 (set_attr "fptype" "double")])
5968 (define_insn "*and_not_di_sp64"
5969 [(set (match_operand:DI 0 "register_operand" "=r,b")
5970 (and:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
5971 (match_operand:DI 2 "register_operand" "r,b")))]
5975 fandnot1\t%1, %2, %0"
5976 [(set_attr "type" "*,fga")
5977 (set_attr "fptype" "double")])
5979 (define_insn "*and_not_si"
5980 [(set (match_operand:SI 0 "register_operand" "=r,d")
5981 (and:SI (not:SI (match_operand:SI 1 "register_operand" "r,d"))
5982 (match_operand:SI 2 "register_operand" "r,d")))]
5986 fandnot1s\t%1, %2, %0"
5987 [(set_attr "type" "*,fga")])
5989 (define_expand "iordi3"
5990 [(set (match_operand:DI 0 "register_operand" "")
5991 (ior:DI (match_operand:DI 1 "arith_double_operand" "")
5992 (match_operand:DI 2 "arith_double_operand" "")))]
5996 (define_insn "*iordi3_sp32"
5997 [(set (match_operand:DI 0 "register_operand" "=r,b")
5998 (ior:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
5999 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6004 [(set_attr "type" "*,fga")
6005 (set_attr "length" "2,*")
6006 (set_attr "fptype" "double")])
6008 (define_insn "*iordi3_sp64"
6009 [(set (match_operand:DI 0 "register_operand" "=r,b")
6010 (ior:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6011 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6016 [(set_attr "type" "*,fga")
6017 (set_attr "fptype" "double")])
6019 (define_insn "iorsi3"
6020 [(set (match_operand:SI 0 "register_operand" "=r,d")
6021 (ior:SI (match_operand:SI 1 "arith_operand" "%r,d")
6022 (match_operand:SI 2 "arith_operand" "rI,d")))]
6027 [(set_attr "type" "*,fga")])
6030 [(set (match_operand:SI 0 "register_operand" "")
6031 (ior:SI (match_operand:SI 1 "register_operand" "")
6032 (match_operand:SI 2 "" "")))
6033 (clobber (match_operand:SI 3 "register_operand" ""))]
6034 "GET_CODE (operands[2]) == CONST_INT
6035 && !SMALL_INT32 (operands[2])
6036 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6037 [(set (match_dup 3) (match_dup 4))
6038 (set (match_dup 0) (ior:SI (not:SI (match_dup 3)) (match_dup 1)))]
6040 operands[4] = GEN_INT (~INTVAL (operands[2]));
6043 (define_insn_and_split "*or_not_di_sp32"
6044 [(set (match_operand:DI 0 "register_operand" "=r,b")
6045 (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6046 (match_operand:DI 2 "register_operand" "r,b")))]
6050 fornot1\t%1, %2, %0"
6051 "&& reload_completed
6052 && ((GET_CODE (operands[0]) == REG
6053 && REGNO (operands[0]) < 32)
6054 || (GET_CODE (operands[0]) == SUBREG
6055 && GET_CODE (SUBREG_REG (operands[0])) == REG
6056 && REGNO (SUBREG_REG (operands[0])) < 32))"
6057 [(set (match_dup 3) (ior:SI (not:SI (match_dup 4)) (match_dup 5)))
6058 (set (match_dup 6) (ior:SI (not:SI (match_dup 7)) (match_dup 8)))]
6059 "operands[3] = gen_highpart (SImode, operands[0]);
6060 operands[4] = gen_highpart (SImode, operands[1]);
6061 operands[5] = gen_highpart (SImode, operands[2]);
6062 operands[6] = gen_lowpart (SImode, operands[0]);
6063 operands[7] = gen_lowpart (SImode, operands[1]);
6064 operands[8] = gen_lowpart (SImode, operands[2]);"
6065 [(set_attr "type" "*,fga")
6066 (set_attr "length" "2,*")
6067 (set_attr "fptype" "double")])
6069 (define_insn "*or_not_di_sp64"
6070 [(set (match_operand:DI 0 "register_operand" "=r,b")
6071 (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6072 (match_operand:DI 2 "register_operand" "r,b")))]
6076 fornot1\t%1, %2, %0"
6077 [(set_attr "type" "*,fga")
6078 (set_attr "fptype" "double")])
6080 (define_insn "*or_not_si"
6081 [(set (match_operand:SI 0 "register_operand" "=r,d")
6082 (ior:SI (not:SI (match_operand:SI 1 "register_operand" "r,d"))
6083 (match_operand:SI 2 "register_operand" "r,d")))]
6087 fornot1s\t%1, %2, %0"
6088 [(set_attr "type" "*,fga")])
6090 (define_expand "xordi3"
6091 [(set (match_operand:DI 0 "register_operand" "")
6092 (xor:DI (match_operand:DI 1 "arith_double_operand" "")
6093 (match_operand:DI 2 "arith_double_operand" "")))]
6097 (define_insn "*xordi3_sp32"
6098 [(set (match_operand:DI 0 "register_operand" "=r,b")
6099 (xor:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6100 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6105 [(set_attr "type" "*,fga")
6106 (set_attr "length" "2,*")
6107 (set_attr "fptype" "double")])
6109 (define_insn "*xordi3_sp64"
6110 [(set (match_operand:DI 0 "register_operand" "=r,b")
6111 (xor:DI (match_operand:DI 1 "arith_double_operand" "%rJ,b")
6112 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6117 [(set_attr "type" "*,fga")
6118 (set_attr "fptype" "double")])
6120 (define_insn "*xordi3_sp64_dbl"
6121 [(set (match_operand:DI 0 "register_operand" "=r")
6122 (xor:DI (match_operand:DI 1 "register_operand" "r")
6123 (match_operand:DI 2 "const64_operand" "")))]
6125 && HOST_BITS_PER_WIDE_INT != 64)"
6128 (define_insn "xorsi3"
6129 [(set (match_operand:SI 0 "register_operand" "=r,d")
6130 (xor:SI (match_operand:SI 1 "arith_operand" "%rJ,d")
6131 (match_operand:SI 2 "arith_operand" "rI,d")))]
6136 [(set_attr "type" "*,fga")])
6139 [(set (match_operand:SI 0 "register_operand" "")
6140 (xor:SI (match_operand:SI 1 "register_operand" "")
6141 (match_operand:SI 2 "" "")))
6142 (clobber (match_operand:SI 3 "register_operand" ""))]
6143 "GET_CODE (operands[2]) == CONST_INT
6144 && !SMALL_INT32 (operands[2])
6145 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6146 [(set (match_dup 3) (match_dup 4))
6147 (set (match_dup 0) (not:SI (xor:SI (match_dup 3) (match_dup 1))))]
6149 operands[4] = GEN_INT (~INTVAL (operands[2]));
6153 [(set (match_operand:SI 0 "register_operand" "")
6154 (not:SI (xor:SI (match_operand:SI 1 "register_operand" "")
6155 (match_operand:SI 2 "" ""))))
6156 (clobber (match_operand:SI 3 "register_operand" ""))]
6157 "GET_CODE (operands[2]) == CONST_INT
6158 && !SMALL_INT32 (operands[2])
6159 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6160 [(set (match_dup 3) (match_dup 4))
6161 (set (match_dup 0) (xor:SI (match_dup 3) (match_dup 1)))]
6163 operands[4] = GEN_INT (~INTVAL (operands[2]));
6166 ;; xnor patterns. Note that (a ^ ~b) == (~a ^ b) == ~(a ^ b).
6167 ;; Combine now canonicalizes to the rightmost expression.
6168 (define_insn_and_split "*xor_not_di_sp32"
6169 [(set (match_operand:DI 0 "register_operand" "=r,b")
6170 (not:DI (xor:DI (match_operand:DI 1 "register_operand" "r,b")
6171 (match_operand:DI 2 "register_operand" "r,b"))))]
6176 "&& reload_completed
6177 && ((GET_CODE (operands[0]) == REG
6178 && REGNO (operands[0]) < 32)
6179 || (GET_CODE (operands[0]) == SUBREG
6180 && GET_CODE (SUBREG_REG (operands[0])) == REG
6181 && REGNO (SUBREG_REG (operands[0])) < 32))"
6182 [(set (match_dup 3) (not:SI (xor:SI (match_dup 4) (match_dup 5))))
6183 (set (match_dup 6) (not:SI (xor:SI (match_dup 7) (match_dup 8))))]
6184 "operands[3] = gen_highpart (SImode, operands[0]);
6185 operands[4] = gen_highpart (SImode, operands[1]);
6186 operands[5] = gen_highpart (SImode, operands[2]);
6187 operands[6] = gen_lowpart (SImode, operands[0]);
6188 operands[7] = gen_lowpart (SImode, operands[1]);
6189 operands[8] = gen_lowpart (SImode, operands[2]);"
6190 [(set_attr "type" "*,fga")
6191 (set_attr "length" "2,*")
6192 (set_attr "fptype" "double")])
6194 (define_insn "*xor_not_di_sp64"
6195 [(set (match_operand:DI 0 "register_operand" "=r,b")
6196 (not:DI (xor:DI (match_operand:DI 1 "reg_or_0_operand" "rJ,b")
6197 (match_operand:DI 2 "arith_double_operand" "rHI,b"))))]
6202 [(set_attr "type" "*,fga")
6203 (set_attr "fptype" "double")])
6205 (define_insn "*xor_not_si"
6206 [(set (match_operand:SI 0 "register_operand" "=r,d")
6207 (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "rJ,d")
6208 (match_operand:SI 2 "arith_operand" "rI,d"))))]
6213 [(set_attr "type" "*,fga")])
6215 ;; These correspond to the above in the case where we also (or only)
6216 ;; want to set the condition code.
6218 (define_insn "*cmp_cc_arith_op"
6221 (match_operator:SI 2 "cc_arithop"
6222 [(match_operand:SI 0 "arith_operand" "%r")
6223 (match_operand:SI 1 "arith_operand" "rI")])
6226 "%A2cc\t%0, %1, %%g0"
6227 [(set_attr "type" "compare")])
6229 (define_insn "*cmp_ccx_arith_op"
6232 (match_operator:DI 2 "cc_arithop"
6233 [(match_operand:DI 0 "arith_double_operand" "%r")
6234 (match_operand:DI 1 "arith_double_operand" "rHI")])
6237 "%A2cc\t%0, %1, %%g0"
6238 [(set_attr "type" "compare")])
6240 (define_insn "*cmp_cc_arith_op_set"
6243 (match_operator:SI 3 "cc_arithop"
6244 [(match_operand:SI 1 "arith_operand" "%r")
6245 (match_operand:SI 2 "arith_operand" "rI")])
6247 (set (match_operand:SI 0 "register_operand" "=r")
6248 (match_operator:SI 4 "cc_arithop" [(match_dup 1) (match_dup 2)]))]
6249 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
6251 [(set_attr "type" "compare")])
6253 (define_insn "*cmp_ccx_arith_op_set"
6256 (match_operator:DI 3 "cc_arithop"
6257 [(match_operand:DI 1 "arith_double_operand" "%r")
6258 (match_operand:DI 2 "arith_double_operand" "rHI")])
6260 (set (match_operand:DI 0 "register_operand" "=r")
6261 (match_operator:DI 4 "cc_arithop" [(match_dup 1) (match_dup 2)]))]
6262 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
6264 [(set_attr "type" "compare")])
6266 (define_insn "*cmp_cc_xor_not"
6269 (not:SI (xor:SI (match_operand:SI 0 "reg_or_0_operand" "%rJ")
6270 (match_operand:SI 1 "arith_operand" "rI")))
6273 "xnorcc\t%r0, %1, %%g0"
6274 [(set_attr "type" "compare")])
6276 (define_insn "*cmp_ccx_xor_not"
6279 (not:DI (xor:DI (match_operand:DI 0 "reg_or_0_operand" "%rJ")
6280 (match_operand:DI 1 "arith_double_operand" "rHI")))
6283 "xnorcc\t%r0, %1, %%g0"
6284 [(set_attr "type" "compare")])
6286 (define_insn "*cmp_cc_xor_not_set"
6289 (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
6290 (match_operand:SI 2 "arith_operand" "rI")))
6292 (set (match_operand:SI 0 "register_operand" "=r")
6293 (not:SI (xor:SI (match_dup 1) (match_dup 2))))]
6295 "xnorcc\t%r1, %2, %0"
6296 [(set_attr "type" "compare")])
6298 (define_insn "*cmp_ccx_xor_not_set"
6301 (not:DI (xor:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ")
6302 (match_operand:DI 2 "arith_double_operand" "rHI")))
6304 (set (match_operand:DI 0 "register_operand" "=r")
6305 (not:DI (xor:DI (match_dup 1) (match_dup 2))))]
6307 "xnorcc\t%r1, %2, %0"
6308 [(set_attr "type" "compare")])
6310 (define_insn "*cmp_cc_arith_op_not"
6313 (match_operator:SI 2 "cc_arithopn"
6314 [(not:SI (match_operand:SI 0 "arith_operand" "rI"))
6315 (match_operand:SI 1 "reg_or_0_operand" "rJ")])
6318 "%B2cc\t%r1, %0, %%g0"
6319 [(set_attr "type" "compare")])
6321 (define_insn "*cmp_ccx_arith_op_not"
6324 (match_operator:DI 2 "cc_arithopn"
6325 [(not:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
6326 (match_operand:DI 1 "reg_or_0_operand" "rJ")])
6329 "%B2cc\t%r1, %0, %%g0"
6330 [(set_attr "type" "compare")])
6332 (define_insn "*cmp_cc_arith_op_not_set"
6335 (match_operator:SI 3 "cc_arithopn"
6336 [(not:SI (match_operand:SI 1 "arith_operand" "rI"))
6337 (match_operand:SI 2 "reg_or_0_operand" "rJ")])
6339 (set (match_operand:SI 0 "register_operand" "=r")
6340 (match_operator:SI 4 "cc_arithopn"
6341 [(not:SI (match_dup 1)) (match_dup 2)]))]
6342 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
6343 "%B3cc\t%r2, %1, %0"
6344 [(set_attr "type" "compare")])
6346 (define_insn "*cmp_ccx_arith_op_not_set"
6349 (match_operator:DI 3 "cc_arithopn"
6350 [(not:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
6351 (match_operand:DI 2 "reg_or_0_operand" "rJ")])
6353 (set (match_operand:DI 0 "register_operand" "=r")
6354 (match_operator:DI 4 "cc_arithopn"
6355 [(not:DI (match_dup 1)) (match_dup 2)]))]
6356 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
6357 "%B3cc\t%r2, %1, %0"
6358 [(set_attr "type" "compare")])
6360 ;; We cannot use the "neg" pseudo insn because the Sun assembler
6361 ;; does not know how to make it work for constants.
6363 (define_expand "negdi2"
6364 [(set (match_operand:DI 0 "register_operand" "=r")
6365 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
6368 if (! TARGET_ARCH64)
6370 emit_insn (gen_rtx_PARALLEL
6373 gen_rtx_SET (VOIDmode, operand0,
6374 gen_rtx_NEG (DImode, operand1)),
6375 gen_rtx_CLOBBER (VOIDmode,
6376 gen_rtx_REG (CCmode,
6382 (define_insn_and_split "*negdi2_sp32"
6383 [(set (match_operand:DI 0 "register_operand" "=r")
6384 (neg:DI (match_operand:DI 1 "register_operand" "r")))
6385 (clobber (reg:CC 100))]
6388 "&& reload_completed"
6389 [(parallel [(set (reg:CC_NOOV 100)
6390 (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 5))
6392 (set (match_dup 4) (minus:SI (const_int 0) (match_dup 5)))])
6393 (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
6394 (ltu:SI (reg:CC 100) (const_int 0))))]
6395 "operands[2] = gen_highpart (SImode, operands[0]);
6396 operands[3] = gen_highpart (SImode, operands[1]);
6397 operands[4] = gen_lowpart (SImode, operands[0]);
6398 operands[5] = gen_lowpart (SImode, operands[1]);"
6399 [(set_attr "length" "2")])
6401 (define_insn "*negdi2_sp64"
6402 [(set (match_operand:DI 0 "register_operand" "=r")
6403 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
6405 "sub\t%%g0, %1, %0")
6407 (define_insn "negsi2"
6408 [(set (match_operand:SI 0 "register_operand" "=r")
6409 (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
6411 "sub\t%%g0, %1, %0")
6413 (define_insn "*cmp_cc_neg"
6414 [(set (reg:CC_NOOV 100)
6415 (compare:CC_NOOV (neg:SI (match_operand:SI 0 "arith_operand" "rI"))
6418 "subcc\t%%g0, %0, %%g0"
6419 [(set_attr "type" "compare")])
6421 (define_insn "*cmp_ccx_neg"
6422 [(set (reg:CCX_NOOV 100)
6423 (compare:CCX_NOOV (neg:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
6426 "subcc\t%%g0, %0, %%g0"
6427 [(set_attr "type" "compare")])
6429 (define_insn "*cmp_cc_set_neg"
6430 [(set (reg:CC_NOOV 100)
6431 (compare:CC_NOOV (neg:SI (match_operand:SI 1 "arith_operand" "rI"))
6433 (set (match_operand:SI 0 "register_operand" "=r")
6434 (neg:SI (match_dup 1)))]
6436 "subcc\t%%g0, %1, %0"
6437 [(set_attr "type" "compare")])
6439 (define_insn "*cmp_ccx_set_neg"
6440 [(set (reg:CCX_NOOV 100)
6441 (compare:CCX_NOOV (neg:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
6443 (set (match_operand:DI 0 "register_operand" "=r")
6444 (neg:DI (match_dup 1)))]
6446 "subcc\t%%g0, %1, %0"
6447 [(set_attr "type" "compare")])
6449 ;; We cannot use the "not" pseudo insn because the Sun assembler
6450 ;; does not know how to make it work for constants.
6451 (define_expand "one_cmpldi2"
6452 [(set (match_operand:DI 0 "register_operand" "")
6453 (not:DI (match_operand:DI 1 "register_operand" "")))]
6457 (define_insn_and_split "*one_cmpldi2_sp32"
6458 [(set (match_operand:DI 0 "register_operand" "=r,b")
6459 (not:DI (match_operand:DI 1 "register_operand" "r,b")))]
6464 "&& reload_completed
6465 && ((GET_CODE (operands[0]) == REG
6466 && REGNO (operands[0]) < 32)
6467 || (GET_CODE (operands[0]) == SUBREG
6468 && GET_CODE (SUBREG_REG (operands[0])) == REG
6469 && REGNO (SUBREG_REG (operands[0])) < 32))"
6470 [(set (match_dup 2) (not:SI (xor:SI (match_dup 3) (const_int 0))))
6471 (set (match_dup 4) (not:SI (xor:SI (match_dup 5) (const_int 0))))]
6472 "operands[2] = gen_highpart (SImode, operands[0]);
6473 operands[3] = gen_highpart (SImode, operands[1]);
6474 operands[4] = gen_lowpart (SImode, operands[0]);
6475 operands[5] = gen_lowpart (SImode, operands[1]);"
6476 [(set_attr "type" "*,fga")
6477 (set_attr "length" "2,*")
6478 (set_attr "fptype" "double")])
6480 (define_insn "*one_cmpldi2_sp64"
6481 [(set (match_operand:DI 0 "register_operand" "=r,b")
6482 (not:DI (match_operand:DI 1 "arith_double_operand" "rHI,b")))]
6487 [(set_attr "type" "*,fga")
6488 (set_attr "fptype" "double")])
6490 (define_insn "one_cmplsi2"
6491 [(set (match_operand:SI 0 "register_operand" "=r,d")
6492 (not:SI (match_operand:SI 1 "arith_operand" "rI,d")))]
6497 [(set_attr "type" "*,fga")])
6499 (define_insn "*cmp_cc_not"
6501 (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI"))
6504 "xnorcc\t%%g0, %0, %%g0"
6505 [(set_attr "type" "compare")])
6507 (define_insn "*cmp_ccx_not"
6509 (compare:CCX (not:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
6512 "xnorcc\t%%g0, %0, %%g0"
6513 [(set_attr "type" "compare")])
6515 (define_insn "*cmp_cc_set_not"
6517 (compare:CC (not:SI (match_operand:SI 1 "arith_operand" "rI"))
6519 (set (match_operand:SI 0 "register_operand" "=r")
6520 (not:SI (match_dup 1)))]
6522 "xnorcc\t%%g0, %1, %0"
6523 [(set_attr "type" "compare")])
6525 (define_insn "*cmp_ccx_set_not"
6527 (compare:CCX (not:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
6529 (set (match_operand:DI 0 "register_operand" "=r")
6530 (not:DI (match_dup 1)))]
6532 "xnorcc\t%%g0, %1, %0"
6533 [(set_attr "type" "compare")])
6535 (define_insn "*cmp_cc_set"
6536 [(set (match_operand:SI 0 "register_operand" "=r")
6537 (match_operand:SI 1 "register_operand" "r"))
6539 (compare:CC (match_dup 1)
6543 [(set_attr "type" "compare")])
6545 (define_insn "*cmp_ccx_set64"
6546 [(set (match_operand:DI 0 "register_operand" "=r")
6547 (match_operand:DI 1 "register_operand" "r"))
6549 (compare:CCX (match_dup 1)
6553 [(set_attr "type" "compare")])
6555 ;; Floating point arithmetic instructions.
6557 (define_expand "addtf3"
6558 [(set (match_operand:TF 0 "nonimmediate_operand" "")
6559 (plus:TF (match_operand:TF 1 "general_operand" "")
6560 (match_operand:TF 2 "general_operand" "")))]
6561 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6562 "emit_tfmode_binop (PLUS, operands); DONE;")
6564 (define_insn "*addtf3_hq"
6565 [(set (match_operand:TF 0 "register_operand" "=e")
6566 (plus:TF (match_operand:TF 1 "register_operand" "e")
6567 (match_operand:TF 2 "register_operand" "e")))]
6568 "TARGET_FPU && TARGET_HARD_QUAD"
6570 [(set_attr "type" "fp")])
6572 (define_insn "adddf3"
6573 [(set (match_operand:DF 0 "register_operand" "=e")
6574 (plus:DF (match_operand:DF 1 "register_operand" "e")
6575 (match_operand:DF 2 "register_operand" "e")))]
6578 [(set_attr "type" "fp")
6579 (set_attr "fptype" "double")])
6581 (define_insn "addsf3"
6582 [(set (match_operand:SF 0 "register_operand" "=f")
6583 (plus:SF (match_operand:SF 1 "register_operand" "f")
6584 (match_operand:SF 2 "register_operand" "f")))]
6587 [(set_attr "type" "fp")])
6589 (define_expand "subtf3"
6590 [(set (match_operand:TF 0 "nonimmediate_operand" "")
6591 (minus:TF (match_operand:TF 1 "general_operand" "")
6592 (match_operand:TF 2 "general_operand" "")))]
6593 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6594 "emit_tfmode_binop (MINUS, operands); DONE;")
6596 (define_insn "*subtf3_hq"
6597 [(set (match_operand:TF 0 "register_operand" "=e")
6598 (minus:TF (match_operand:TF 1 "register_operand" "e")
6599 (match_operand:TF 2 "register_operand" "e")))]
6600 "TARGET_FPU && TARGET_HARD_QUAD"
6602 [(set_attr "type" "fp")])
6604 (define_insn "subdf3"
6605 [(set (match_operand:DF 0 "register_operand" "=e")
6606 (minus:DF (match_operand:DF 1 "register_operand" "e")
6607 (match_operand:DF 2 "register_operand" "e")))]
6610 [(set_attr "type" "fp")
6611 (set_attr "fptype" "double")])
6613 (define_insn "subsf3"
6614 [(set (match_operand:SF 0 "register_operand" "=f")
6615 (minus:SF (match_operand:SF 1 "register_operand" "f")
6616 (match_operand:SF 2 "register_operand" "f")))]
6619 [(set_attr "type" "fp")])
6621 (define_expand "multf3"
6622 [(set (match_operand:TF 0 "nonimmediate_operand" "")
6623 (mult:TF (match_operand:TF 1 "general_operand" "")
6624 (match_operand:TF 2 "general_operand" "")))]
6625 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6626 "emit_tfmode_binop (MULT, operands); DONE;")
6628 (define_insn "*multf3_hq"
6629 [(set (match_operand:TF 0 "register_operand" "=e")
6630 (mult:TF (match_operand:TF 1 "register_operand" "e")
6631 (match_operand:TF 2 "register_operand" "e")))]
6632 "TARGET_FPU && TARGET_HARD_QUAD"
6634 [(set_attr "type" "fpmul")])
6636 (define_insn "muldf3"
6637 [(set (match_operand:DF 0 "register_operand" "=e")
6638 (mult:DF (match_operand:DF 1 "register_operand" "e")
6639 (match_operand:DF 2 "register_operand" "e")))]
6642 [(set_attr "type" "fpmul")
6643 (set_attr "fptype" "double")])
6645 (define_insn "mulsf3"
6646 [(set (match_operand:SF 0 "register_operand" "=f")
6647 (mult:SF (match_operand:SF 1 "register_operand" "f")
6648 (match_operand:SF 2 "register_operand" "f")))]
6651 [(set_attr "type" "fpmul")])
6653 (define_insn "*muldf3_extend"
6654 [(set (match_operand:DF 0 "register_operand" "=e")
6655 (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "f"))
6656 (float_extend:DF (match_operand:SF 2 "register_operand" "f"))))]
6657 "(TARGET_V8 || TARGET_V9) && TARGET_FPU"
6658 "fsmuld\t%1, %2, %0"
6659 [(set_attr "type" "fpmul")
6660 (set_attr "fptype" "double")])
6662 (define_insn "*multf3_extend"
6663 [(set (match_operand:TF 0 "register_operand" "=e")
6664 (mult:TF (float_extend:TF (match_operand:DF 1 "register_operand" "e"))
6665 (float_extend:TF (match_operand:DF 2 "register_operand" "e"))))]
6666 "(TARGET_V8 || TARGET_V9) && TARGET_FPU && TARGET_HARD_QUAD"
6667 "fdmulq\t%1, %2, %0"
6668 [(set_attr "type" "fpmul")])
6670 (define_expand "divtf3"
6671 [(set (match_operand:TF 0 "nonimmediate_operand" "")
6672 (div:TF (match_operand:TF 1 "general_operand" "")
6673 (match_operand:TF 2 "general_operand" "")))]
6674 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6675 "emit_tfmode_binop (DIV, operands); DONE;")
6677 ;; don't have timing for quad-prec. divide.
6678 (define_insn "*divtf3_hq"
6679 [(set (match_operand:TF 0 "register_operand" "=e")
6680 (div:TF (match_operand:TF 1 "register_operand" "e")
6681 (match_operand:TF 2 "register_operand" "e")))]
6682 "TARGET_FPU && TARGET_HARD_QUAD"
6684 [(set_attr "type" "fpdivd")])
6686 (define_insn "divdf3"
6687 [(set (match_operand:DF 0 "register_operand" "=e")
6688 (div:DF (match_operand:DF 1 "register_operand" "e")
6689 (match_operand:DF 2 "register_operand" "e")))]
6692 [(set_attr "type" "fpdivd")
6693 (set_attr "fptype" "double")])
6695 (define_insn "divsf3"
6696 [(set (match_operand:SF 0 "register_operand" "=f")
6697 (div:SF (match_operand:SF 1 "register_operand" "f")
6698 (match_operand:SF 2 "register_operand" "f")))]
6701 [(set_attr "type" "fpdivs")])
6703 (define_expand "negtf2"
6704 [(set (match_operand:TF 0 "register_operand" "=e,e")
6705 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
6709 (define_insn_and_split "*negtf2_notv9"
6710 [(set (match_operand:TF 0 "register_operand" "=e,e")
6711 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
6712 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
6718 "&& reload_completed
6719 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6720 [(set (match_dup 2) (neg:SF (match_dup 3)))
6721 (set (match_dup 4) (match_dup 5))
6722 (set (match_dup 6) (match_dup 7))]
6723 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6724 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6725 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6726 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
6727 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6728 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6729 [(set_attr "type" "fpmove,*")
6730 (set_attr "length" "*,2")])
6732 (define_insn_and_split "*negtf2_v9"
6733 [(set (match_operand:TF 0 "register_operand" "=e,e")
6734 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
6735 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
6736 "TARGET_FPU && TARGET_V9"
6740 "&& reload_completed
6741 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6742 [(set (match_dup 2) (neg:DF (match_dup 3)))
6743 (set (match_dup 4) (match_dup 5))]
6744 "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
6745 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
6746 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6747 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6748 [(set_attr "type" "fpmove,*")
6749 (set_attr "length" "*,2")
6750 (set_attr "fptype" "double")])
6752 (define_expand "negdf2"
6753 [(set (match_operand:DF 0 "register_operand" "")
6754 (neg:DF (match_operand:DF 1 "register_operand" "")))]
6758 (define_insn_and_split "*negdf2_notv9"
6759 [(set (match_operand:DF 0 "register_operand" "=e,e")
6760 (neg:DF (match_operand:DF 1 "register_operand" "0,e")))]
6761 "TARGET_FPU && ! TARGET_V9"
6765 "&& reload_completed
6766 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6767 [(set (match_dup 2) (neg:SF (match_dup 3)))
6768 (set (match_dup 4) (match_dup 5))]
6769 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6770 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6771 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6772 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);"
6773 [(set_attr "type" "fpmove,*")
6774 (set_attr "length" "*,2")])
6776 (define_insn "*negdf2_v9"
6777 [(set (match_operand:DF 0 "register_operand" "=e")
6778 (neg:DF (match_operand:DF 1 "register_operand" "e")))]
6779 "TARGET_FPU && TARGET_V9"
6781 [(set_attr "type" "fpmove")
6782 (set_attr "fptype" "double")])
6784 (define_insn "negsf2"
6785 [(set (match_operand:SF 0 "register_operand" "=f")
6786 (neg:SF (match_operand:SF 1 "register_operand" "f")))]
6789 [(set_attr "type" "fpmove")])
6791 (define_expand "abstf2"
6792 [(set (match_operand:TF 0 "register_operand" "")
6793 (abs:TF (match_operand:TF 1 "register_operand" "")))]
6797 (define_insn_and_split "*abstf2_notv9"
6798 [(set (match_operand:TF 0 "register_operand" "=e,e")
6799 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6800 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
6801 "TARGET_FPU && ! TARGET_V9"
6805 "&& reload_completed
6806 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6807 [(set (match_dup 2) (abs:SF (match_dup 3)))
6808 (set (match_dup 4) (match_dup 5))
6809 (set (match_dup 6) (match_dup 7))]
6810 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6811 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6812 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6813 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
6814 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6815 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6816 [(set_attr "type" "fpmove,*")
6817 (set_attr "length" "*,2")])
6819 (define_insn "*abstf2_hq_v9"
6820 [(set (match_operand:TF 0 "register_operand" "=e,e")
6821 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6822 "TARGET_FPU && TARGET_V9 && TARGET_HARD_QUAD"
6826 [(set_attr "type" "fpmove")
6827 (set_attr "fptype" "double,*")])
6829 (define_insn_and_split "*abstf2_v9"
6830 [(set (match_operand:TF 0 "register_operand" "=e,e")
6831 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6832 "TARGET_FPU && TARGET_V9 && !TARGET_HARD_QUAD"
6836 "&& reload_completed
6837 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6838 [(set (match_dup 2) (abs:DF (match_dup 3)))
6839 (set (match_dup 4) (match_dup 5))]
6840 "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
6841 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
6842 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6843 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6844 [(set_attr "type" "fpmove,*")
6845 (set_attr "length" "*,2")
6846 (set_attr "fptype" "double,*")])
6848 (define_expand "absdf2"
6849 [(set (match_operand:DF 0 "register_operand" "")
6850 (abs:DF (match_operand:DF 1 "register_operand" "")))]
6854 (define_insn_and_split "*absdf2_notv9"
6855 [(set (match_operand:DF 0 "register_operand" "=e,e")
6856 (abs:DF (match_operand:DF 1 "register_operand" "0,e")))]
6857 "TARGET_FPU && ! TARGET_V9"
6861 "&& reload_completed
6862 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6863 [(set (match_dup 2) (abs:SF (match_dup 3)))
6864 (set (match_dup 4) (match_dup 5))]
6865 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6866 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6867 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6868 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);"
6869 [(set_attr "type" "fpmove,*")
6870 (set_attr "length" "*,2")])
6872 (define_insn "*absdf2_v9"
6873 [(set (match_operand:DF 0 "register_operand" "=e")
6874 (abs:DF (match_operand:DF 1 "register_operand" "e")))]
6875 "TARGET_FPU && TARGET_V9"
6877 [(set_attr "type" "fpmove")
6878 (set_attr "fptype" "double")])
6880 (define_insn "abssf2"
6881 [(set (match_operand:SF 0 "register_operand" "=f")
6882 (abs:SF (match_operand:SF 1 "register_operand" "f")))]
6885 [(set_attr "type" "fpmove")])
6887 (define_expand "sqrttf2"
6888 [(set (match_operand:TF 0 "nonimmediate_operand" "")
6889 (sqrt:TF (match_operand:TF 1 "general_operand" "")))]
6890 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6891 "emit_tfmode_unop (SQRT, operands); DONE;")
6893 (define_insn "*sqrttf2_hq"
6894 [(set (match_operand:TF 0 "register_operand" "=e")
6895 (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
6896 "TARGET_FPU && TARGET_HARD_QUAD"
6898 [(set_attr "type" "fpsqrtd")])
6900 (define_insn "sqrtdf2"
6901 [(set (match_operand:DF 0 "register_operand" "=e")
6902 (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
6905 [(set_attr "type" "fpsqrtd")
6906 (set_attr "fptype" "double")])
6908 (define_insn "sqrtsf2"
6909 [(set (match_operand:SF 0 "register_operand" "=f")
6910 (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
6913 [(set_attr "type" "fpsqrts")])
6915 ;;- arithmetic shift instructions
6917 (define_insn "ashlsi3"
6918 [(set (match_operand:SI 0 "register_operand" "=r")
6919 (ashift:SI (match_operand:SI 1 "register_operand" "r")
6920 (match_operand:SI 2 "arith_operand" "rI")))]
6923 if (operands[2] == const1_rtx)
6924 return "add\t%1, %1, %0";
6925 if (GET_CODE (operands[2]) == CONST_INT)
6926 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6927 return "sll\t%1, %2, %0";
6930 (if_then_else (match_operand 2 "const1_operand" "")
6931 (const_string "ialu") (const_string "shift")))])
6933 (define_expand "ashldi3"
6934 [(set (match_operand:DI 0 "register_operand" "=r")
6935 (ashift:DI (match_operand:DI 1 "register_operand" "r")
6936 (match_operand:SI 2 "arith_operand" "rI")))]
6937 "TARGET_ARCH64 || TARGET_V8PLUS"
6939 if (! TARGET_ARCH64)
6941 if (GET_CODE (operands[2]) == CONST_INT)
6943 emit_insn (gen_ashldi3_v8plus (operands[0], operands[1], operands[2]));
6948 (define_insn "*ashldi3_sp64"
6949 [(set (match_operand:DI 0 "register_operand" "=r")
6950 (ashift:DI (match_operand:DI 1 "register_operand" "r")
6951 (match_operand:SI 2 "arith_operand" "rI")))]
6954 if (operands[2] == const1_rtx)
6955 return "add\t%1, %1, %0";
6956 if (GET_CODE (operands[2]) == CONST_INT)
6957 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
6958 return "sllx\t%1, %2, %0";
6961 (if_then_else (match_operand 2 "const1_operand" "")
6962 (const_string "ialu") (const_string "shift")))])
6965 (define_insn "ashldi3_v8plus"
6966 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
6967 (ashift:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
6968 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
6969 (clobber (match_scratch:SI 3 "=X,X,&h"))]
6971 { return sparc_v8plus_shift (operands, insn, "sllx"); }
6972 [(set_attr "type" "multi")
6973 (set_attr "length" "5,5,6")])
6975 ;; Optimize (1LL<<x)-1
6976 ;; XXX this also needs to be fixed to handle equal subregs
6977 ;; XXX first before we could re-enable it.
6979 ; [(set (match_operand:DI 0 "register_operand" "=h")
6980 ; (plus:DI (ashift:DI (const_int 1)
6981 ; (match_operand:SI 1 "arith_operand" "rI"))
6983 ; "0 && TARGET_V8PLUS"
6985 ; if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == REGNO (operands[0]))
6986 ; return "mov\t1, %L0\;sllx\t%L0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
6987 ; return "mov\t1, %H0\;sllx\t%H0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
6989 ; [(set_attr "type" "multi")
6990 ; (set_attr "length" "4")])
6992 (define_insn "*cmp_cc_ashift_1"
6993 [(set (reg:CC_NOOV 100)
6994 (compare:CC_NOOV (ashift:SI (match_operand:SI 0 "register_operand" "r")
6998 "addcc\t%0, %0, %%g0"
6999 [(set_attr "type" "compare")])
7001 (define_insn "*cmp_cc_set_ashift_1"
7002 [(set (reg:CC_NOOV 100)
7003 (compare:CC_NOOV (ashift:SI (match_operand:SI 1 "register_operand" "r")
7006 (set (match_operand:SI 0 "register_operand" "=r")
7007 (ashift:SI (match_dup 1) (const_int 1)))]
7010 [(set_attr "type" "compare")])
7012 (define_insn "ashrsi3"
7013 [(set (match_operand:SI 0 "register_operand" "=r")
7014 (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
7015 (match_operand:SI 2 "arith_operand" "rI")))]
7018 if (GET_CODE (operands[2]) == CONST_INT)
7019 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
7020 return "sra\t%1, %2, %0";
7022 [(set_attr "type" "shift")])
7024 (define_insn "*ashrsi3_extend"
7025 [(set (match_operand:DI 0 "register_operand" "=r")
7026 (sign_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
7027 (match_operand:SI 2 "arith_operand" "r"))))]
7030 [(set_attr "type" "shift")])
7032 ;; This handles the case as above, but with constant shift instead of
7033 ;; register. Combiner "simplifies" it for us a little bit though.
7034 (define_insn "*ashrsi3_extend2"
7035 [(set (match_operand:DI 0 "register_operand" "=r")
7036 (ashiftrt:DI (ashift:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
7038 (match_operand:SI 2 "small_int_or_double" "n")))]
7040 && ((GET_CODE (operands[2]) == CONST_INT
7041 && INTVAL (operands[2]) >= 32 && INTVAL (operands[2]) < 64)
7042 || (GET_CODE (operands[2]) == CONST_DOUBLE
7043 && !CONST_DOUBLE_HIGH (operands[2])
7044 && CONST_DOUBLE_LOW (operands[2]) >= 32
7045 && CONST_DOUBLE_LOW (operands[2]) < 64))"
7047 operands[2] = GEN_INT (INTVAL (operands[2]) - 32);
7049 return "sra\t%1, %2, %0";
7051 [(set_attr "type" "shift")])
7053 (define_expand "ashrdi3"
7054 [(set (match_operand:DI 0 "register_operand" "=r")
7055 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
7056 (match_operand:SI 2 "arith_operand" "rI")))]
7057 "TARGET_ARCH64 || TARGET_V8PLUS"
7059 if (! TARGET_ARCH64)
7061 if (GET_CODE (operands[2]) == CONST_INT)
7062 FAIL; /* prefer generic code in this case */
7063 emit_insn (gen_ashrdi3_v8plus (operands[0], operands[1], operands[2]));
7068 (define_insn "*ashrdi3_sp64"
7069 [(set (match_operand:DI 0 "register_operand" "=r")
7070 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
7071 (match_operand:SI 2 "arith_operand" "rI")))]
7075 if (GET_CODE (operands[2]) == CONST_INT)
7076 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
7077 return "srax\t%1, %2, %0";
7079 [(set_attr "type" "shift")])
7082 (define_insn "ashrdi3_v8plus"
7083 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
7084 (ashiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
7085 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
7086 (clobber (match_scratch:SI 3 "=X,X,&h"))]
7088 { return sparc_v8plus_shift (operands, insn, "srax"); }
7089 [(set_attr "type" "multi")
7090 (set_attr "length" "5,5,6")])
7092 (define_insn "lshrsi3"
7093 [(set (match_operand:SI 0 "register_operand" "=r")
7094 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
7095 (match_operand:SI 2 "arith_operand" "rI")))]
7098 if (GET_CODE (operands[2]) == CONST_INT)
7099 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
7100 return "srl\t%1, %2, %0";
7102 [(set_attr "type" "shift")])
7104 ;; This handles the case where
7105 ;; (zero_extend:DI (lshiftrt:SI (match_operand:SI) (match_operand:SI))),
7106 ;; but combiner "simplifies" it for us.
7107 (define_insn "*lshrsi3_extend"
7108 [(set (match_operand:DI 0 "register_operand" "=r")
7109 (and:DI (subreg:DI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
7110 (match_operand:SI 2 "arith_operand" "r")) 0)
7111 (match_operand 3 "" "")))]
7113 && ((GET_CODE (operands[3]) == CONST_DOUBLE
7114 && CONST_DOUBLE_HIGH (operands[3]) == 0
7115 && CONST_DOUBLE_LOW (operands[3]) == 0xffffffff)
7116 || (HOST_BITS_PER_WIDE_INT >= 64
7117 && GET_CODE (operands[3]) == CONST_INT
7118 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) == 0xffffffff))"
7120 [(set_attr "type" "shift")])
7122 ;; This handles the case where
7123 ;; (lshiftrt:DI (zero_extend:DI (match_operand:SI)) (const_int >=0 < 32))
7124 ;; but combiner "simplifies" it for us.
7125 (define_insn "*lshrsi3_extend2"
7126 [(set (match_operand:DI 0 "register_operand" "=r")
7127 (zero_extract:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
7128 (match_operand 2 "small_int_or_double" "n")
7131 && ((GET_CODE (operands[2]) == CONST_INT
7132 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
7133 || (GET_CODE (operands[2]) == CONST_DOUBLE
7134 && CONST_DOUBLE_HIGH (operands[2]) == 0
7135 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
7137 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
7139 return "srl\t%1, %2, %0";
7141 [(set_attr "type" "shift")])
7143 (define_expand "lshrdi3"
7144 [(set (match_operand:DI 0 "register_operand" "=r")
7145 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
7146 (match_operand:SI 2 "arith_operand" "rI")))]
7147 "TARGET_ARCH64 || TARGET_V8PLUS"
7149 if (! TARGET_ARCH64)
7151 if (GET_CODE (operands[2]) == CONST_INT)
7153 emit_insn (gen_lshrdi3_v8plus (operands[0], operands[1], operands[2]));
7158 (define_insn "*lshrdi3_sp64"
7159 [(set (match_operand:DI 0 "register_operand" "=r")
7160 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
7161 (match_operand:SI 2 "arith_operand" "rI")))]
7164 if (GET_CODE (operands[2]) == CONST_INT)
7165 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
7166 return "srlx\t%1, %2, %0";
7168 [(set_attr "type" "shift")])
7171 (define_insn "lshrdi3_v8plus"
7172 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
7173 (lshiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
7174 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
7175 (clobber (match_scratch:SI 3 "=X,X,&h"))]
7177 { return sparc_v8plus_shift (operands, insn, "srlx"); }
7178 [(set_attr "type" "multi")
7179 (set_attr "length" "5,5,6")])
7182 [(set (match_operand:SI 0 "register_operand" "=r")
7183 (ashiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
7185 (match_operand:SI 2 "small_int_or_double" "n")))]
7187 && ((GET_CODE (operands[2]) == CONST_INT
7188 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
7189 || (GET_CODE (operands[2]) == CONST_DOUBLE
7190 && !CONST_DOUBLE_HIGH (operands[2])
7191 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
7193 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
7195 return "srax\t%1, %2, %0";
7197 [(set_attr "type" "shift")])
7200 [(set (match_operand:SI 0 "register_operand" "=r")
7201 (lshiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
7203 (match_operand:SI 2 "small_int_or_double" "n")))]
7205 && ((GET_CODE (operands[2]) == CONST_INT
7206 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
7207 || (GET_CODE (operands[2]) == CONST_DOUBLE
7208 && !CONST_DOUBLE_HIGH (operands[2])
7209 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
7211 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
7213 return "srlx\t%1, %2, %0";
7215 [(set_attr "type" "shift")])
7218 [(set (match_operand:SI 0 "register_operand" "=r")
7219 (ashiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
7220 (match_operand:SI 2 "small_int_or_double" "n")) 4)
7221 (match_operand:SI 3 "small_int_or_double" "n")))]
7223 && GET_CODE (operands[2]) == CONST_INT && GET_CODE (operands[3]) == CONST_INT
7224 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
7225 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
7226 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
7228 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
7230 return "srax\t%1, %2, %0";
7232 [(set_attr "type" "shift")])
7235 [(set (match_operand:SI 0 "register_operand" "=r")
7236 (lshiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
7237 (match_operand:SI 2 "small_int_or_double" "n")) 4)
7238 (match_operand:SI 3 "small_int_or_double" "n")))]
7240 && GET_CODE (operands[2]) == CONST_INT && GET_CODE (operands[3]) == CONST_INT
7241 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
7242 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
7243 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
7245 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
7247 return "srlx\t%1, %2, %0";
7249 [(set_attr "type" "shift")])
7251 ;; Unconditional and other jump instructions
7252 ;; On the SPARC, by setting the annul bit on an unconditional branch, the
7253 ;; following insn is never executed. This saves us a nop. Dbx does not
7254 ;; handle such branches though, so we only use them when optimizing.
7256 [(set (pc) (label_ref (match_operand 0 "" "")))]
7259 /* TurboSPARC is reported to have problems with
7262 i.e. an empty loop with the annul bit set. The workaround is to use
7266 if (! TARGET_V9 && flag_delayed_branch
7267 && (INSN_ADDRESSES (INSN_UID (operands[0]))
7268 == INSN_ADDRESSES (INSN_UID (insn))))
7271 return TARGET_V9 ? "ba%*,pt\t%%xcc, %l0%(" : "b%*\t%l0%(";
7273 [(set_attr "type" "uncond_branch")])
7275 (define_expand "tablejump"
7276 [(parallel [(set (pc) (match_operand 0 "register_operand" "r"))
7277 (use (label_ref (match_operand 1 "" "")))])]
7280 if (GET_MODE (operands[0]) != CASE_VECTOR_MODE)
7283 /* In pic mode, our address differences are against the base of the
7284 table. Add that base value back in; CSE ought to be able to combine
7285 the two address loads. */
7289 tmp = gen_rtx_LABEL_REF (Pmode, operands[1]);
7291 if (CASE_VECTOR_MODE != Pmode)
7292 tmp2 = gen_rtx_SIGN_EXTEND (Pmode, tmp2);
7293 tmp = gen_rtx_PLUS (Pmode, tmp2, tmp);
7294 operands[0] = memory_address (Pmode, tmp);
7298 (define_insn "*tablejump_sp32"
7299 [(set (pc) (match_operand:SI 0 "address_operand" "p"))
7300 (use (label_ref (match_operand 1 "" "")))]
7303 [(set_attr "type" "uncond_branch")])
7305 (define_insn "*tablejump_sp64"
7306 [(set (pc) (match_operand:DI 0 "address_operand" "p"))
7307 (use (label_ref (match_operand 1 "" "")))]
7310 [(set_attr "type" "uncond_branch")])
7312 ;; This pattern recognizes the "instruction" that appears in
7313 ;; a function call that wants a structure value,
7314 ;; to inform the called function if compiled with Sun CC.
7315 ;(define_insn "*unimp_insn"
7316 ; [(match_operand:SI 0 "immediate_operand" "")]
7317 ; "GET_CODE (operands[0]) == CONST_INT && INTVAL (operands[0]) > 0"
7319 ; [(set_attr "type" "marker")])
7321 ;;- jump to subroutine
7322 (define_expand "call"
7323 ;; Note that this expression is not used for generating RTL.
7324 ;; All the RTL is generated explicitly below.
7325 [(call (match_operand 0 "call_operand" "")
7326 (match_operand 3 "" "i"))]
7327 ;; operands[2] is next_arg_register
7328 ;; operands[3] is struct_value_size_rtx.
7331 rtx fn_rtx, nregs_rtx;
7333 if (GET_MODE (operands[0]) != FUNCTION_MODE)
7336 if (GET_CODE (XEXP (operands[0], 0)) == LABEL_REF)
7338 /* This is really a PIC sequence. We want to represent
7339 it as a funny jump so its delay slots can be filled.
7341 ??? But if this really *is* a CALL, will not it clobber the
7342 call-clobbered registers? We lose this if it is a JUMP_INSN.
7343 Why cannot we have delay slots filled if it were a CALL? */
7345 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
7350 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
7352 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
7358 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
7359 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
7363 fn_rtx = operands[0];
7365 /* Count the number of parameter registers being used by this call.
7366 if that argument is NULL, it means we are using them all, which
7367 means 6 on the sparc. */
7370 nregs_rtx = GEN_INT (REGNO (operands[2]) - 8);
7372 nregs_rtx = GEN_INT (6);
7374 nregs_rtx = const0_rtx;
7377 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
7381 gen_rtvec (3, gen_rtx_CALL (VOIDmode, fn_rtx, nregs_rtx),
7383 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
7388 gen_rtvec (2, gen_rtx_CALL (VOIDmode, fn_rtx, nregs_rtx),
7389 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
7393 /* If this call wants a structure value,
7394 emit an unimp insn to let the called function know about this. */
7395 if (! TARGET_ARCH64 && INTVAL (operands[3]) > 0)
7397 rtx insn = emit_insn (operands[3]);
7398 SCHED_GROUP_P (insn) = 1;
7405 ;; We can't use the same pattern for these two insns, because then registers
7406 ;; in the address may not be properly reloaded.
7408 (define_insn "*call_address_sp32"
7409 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
7410 (match_operand 1 "" ""))
7411 (clobber (reg:SI 15))]
7412 ;;- Do not use operand 1 for most machines.
7415 [(set_attr "type" "call")])
7417 (define_insn "*call_symbolic_sp32"
7418 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
7419 (match_operand 1 "" ""))
7420 (clobber (reg:SI 15))]
7421 ;;- Do not use operand 1 for most machines.
7424 [(set_attr "type" "call")])
7426 (define_insn "*call_address_sp64"
7427 [(call (mem:DI (match_operand:DI 0 "address_operand" "p"))
7428 (match_operand 1 "" ""))
7429 (clobber (reg:DI 15))]
7430 ;;- Do not use operand 1 for most machines.
7433 [(set_attr "type" "call")])
7435 (define_insn "*call_symbolic_sp64"
7436 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
7437 (match_operand 1 "" ""))
7438 (clobber (reg:DI 15))]
7439 ;;- Do not use operand 1 for most machines.
7442 [(set_attr "type" "call")])
7444 ;; This is a call that wants a structure value.
7445 ;; There is no such critter for v9 (??? we may need one anyway).
7446 (define_insn "*call_address_struct_value_sp32"
7447 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
7448 (match_operand 1 "" ""))
7449 (match_operand 2 "immediate_operand" "")
7450 (clobber (reg:SI 15))]
7451 ;;- Do not use operand 1 for most machines.
7452 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 0"
7453 "call\t%a0, %1\n\tnop\n\tunimp\t%2"
7454 [(set_attr "type" "call_no_delay_slot")
7455 (set_attr "length" "3")])
7457 ;; This is a call that wants a structure value.
7458 ;; There is no such critter for v9 (??? we may need one anyway).
7459 (define_insn "*call_symbolic_struct_value_sp32"
7460 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
7461 (match_operand 1 "" ""))
7462 (match_operand 2 "immediate_operand" "")
7463 (clobber (reg:SI 15))]
7464 ;;- Do not use operand 1 for most machines.
7465 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 0"
7466 "call\t%a0, %1\n\tnop\n\tunimp\t%2"
7467 [(set_attr "type" "call_no_delay_slot")
7468 (set_attr "length" "3")])
7470 ;; This is a call that may want a structure value. This is used for
7472 (define_insn "*call_address_untyped_struct_value_sp32"
7473 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
7474 (match_operand 1 "" ""))
7475 (match_operand 2 "immediate_operand" "")
7476 (clobber (reg:SI 15))]
7477 ;;- Do not use operand 1 for most machines.
7478 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
7479 "call\t%a0, %1\n\tnop\n\tnop"
7480 [(set_attr "type" "call_no_delay_slot")
7481 (set_attr "length" "3")])
7483 ;; This is a call that wants a structure value.
7484 (define_insn "*call_symbolic_untyped_struct_value_sp32"
7485 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
7486 (match_operand 1 "" ""))
7487 (match_operand 2 "immediate_operand" "")
7488 (clobber (reg:SI 15))]
7489 ;;- Do not use operand 1 for most machines.
7490 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
7491 "call\t%a0, %1\n\tnop\n\tnop"
7492 [(set_attr "type" "call_no_delay_slot")
7493 (set_attr "length" "3")])
7495 (define_expand "call_value"
7496 ;; Note that this expression is not used for generating RTL.
7497 ;; All the RTL is generated explicitly below.
7498 [(set (match_operand 0 "register_operand" "=rf")
7499 (call (match_operand 1 "" "")
7500 (match_operand 4 "" "")))]
7501 ;; operand 2 is stack_size_rtx
7502 ;; operand 3 is next_arg_register
7505 rtx fn_rtx, nregs_rtx;
7508 if (GET_MODE (operands[1]) != FUNCTION_MODE)
7511 fn_rtx = operands[1];
7515 nregs_rtx = GEN_INT (REGNO (operands[3]) - 8);
7517 nregs_rtx = GEN_INT (6);
7519 nregs_rtx = const0_rtx;
7523 gen_rtx_SET (VOIDmode, operands[0],
7524 gen_rtx_CALL (VOIDmode, fn_rtx, nregs_rtx)),
7525 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)));
7527 emit_call_insn (gen_rtx_PARALLEL (VOIDmode, vec));
7532 (define_insn "*call_value_address_sp32"
7533 [(set (match_operand 0 "" "=rf")
7534 (call (mem:SI (match_operand:SI 1 "address_operand" "p"))
7535 (match_operand 2 "" "")))
7536 (clobber (reg:SI 15))]
7537 ;;- Do not use operand 2 for most machines.
7540 [(set_attr "type" "call")])
7542 (define_insn "*call_value_symbolic_sp32"
7543 [(set (match_operand 0 "" "=rf")
7544 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
7545 (match_operand 2 "" "")))
7546 (clobber (reg:SI 15))]
7547 ;;- Do not use operand 2 for most machines.
7550 [(set_attr "type" "call")])
7552 (define_insn "*call_value_address_sp64"
7553 [(set (match_operand 0 "" "")
7554 (call (mem:DI (match_operand:DI 1 "address_operand" "p"))
7555 (match_operand 2 "" "")))
7556 (clobber (reg:DI 15))]
7557 ;;- Do not use operand 2 for most machines.
7560 [(set_attr "type" "call")])
7562 (define_insn "*call_value_symbolic_sp64"
7563 [(set (match_operand 0 "" "")
7564 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
7565 (match_operand 2 "" "")))
7566 (clobber (reg:DI 15))]
7567 ;;- Do not use operand 2 for most machines.
7570 [(set_attr "type" "call")])
7572 (define_expand "untyped_call"
7573 [(parallel [(call (match_operand 0 "" "")
7575 (match_operand 1 "" "")
7576 (match_operand 2 "" "")])]
7581 /* Pass constm1 to indicate that it may expect a structure value, but
7582 we don't know what size it is. */
7583 emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, constm1_rtx));
7585 for (i = 0; i < XVECLEN (operands[2], 0); i++)
7587 rtx set = XVECEXP (operands[2], 0, i);
7588 emit_move_insn (SET_DEST (set), SET_SRC (set));
7591 /* The optimizer does not know that the call sets the function value
7592 registers we stored in the result block. We avoid problems by
7593 claiming that all hard registers are used and clobbered at this
7595 emit_insn (gen_blockage ());
7601 (define_expand "sibcall"
7602 [(parallel [(call (match_operand 0 "call_operand" "") (const_int 0))
7607 (define_insn "*sibcall_symbolic_sp32"
7608 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
7609 (match_operand 1 "" ""))
7612 "* return output_sibcall(insn, operands[0]);"
7613 [(set_attr "type" "sibcall")])
7615 (define_insn "*sibcall_symbolic_sp64"
7616 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
7617 (match_operand 1 "" ""))
7620 "* return output_sibcall(insn, operands[0]);"
7621 [(set_attr "type" "sibcall")])
7623 (define_expand "sibcall_value"
7624 [(parallel [(set (match_operand 0 "register_operand" "=rf")
7625 (call (match_operand 1 "" "") (const_int 0)))
7630 (define_insn "*sibcall_value_symbolic_sp32"
7631 [(set (match_operand 0 "" "=rf")
7632 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
7633 (match_operand 2 "" "")))
7636 "* return output_sibcall(insn, operands[1]);"
7637 [(set_attr "type" "sibcall")])
7639 (define_insn "*sibcall_value_symbolic_sp64"
7640 [(set (match_operand 0 "" "")
7641 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
7642 (match_operand 2 "" "")))
7645 "* return output_sibcall(insn, operands[1]);"
7646 [(set_attr "type" "sibcall")])
7648 (define_expand "sibcall_epilogue"
7653 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
7654 ;; all of memory. This blocks insns from being moved across this point.
7656 (define_insn "blockage"
7657 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
7660 [(set_attr "length" "0")])
7662 ;; Prepare to return any type including a structure value.
7664 (define_expand "untyped_return"
7665 [(match_operand:BLK 0 "memory_operand" "")
7666 (match_operand 1 "" "")]
7669 rtx valreg1 = gen_rtx_REG (DImode, 24);
7670 rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
7671 rtx result = operands[0];
7673 if (! TARGET_ARCH64)
7675 rtx rtnreg = gen_rtx_REG (SImode, (current_function_uses_only_leaf_regs
7677 rtx value = gen_reg_rtx (SImode);
7679 /* Fetch the instruction where we will return to and see if it's an unimp
7680 instruction (the most significant 10 bits will be zero). If so,
7681 update the return address to skip the unimp instruction. */
7682 emit_move_insn (value,
7683 gen_rtx_MEM (SImode, plus_constant (rtnreg, 8)));
7684 emit_insn (gen_lshrsi3 (value, value, GEN_INT (22)));
7685 emit_insn (gen_update_return (rtnreg, value));
7688 /* Reload the function value registers. */
7689 emit_move_insn (valreg1, adjust_address (result, DImode, 0));
7690 emit_move_insn (valreg2,
7691 adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8));
7693 /* Put USE insns before the return. */
7694 emit_insn (gen_rtx_USE (VOIDmode, valreg1));
7695 emit_insn (gen_rtx_USE (VOIDmode, valreg2));
7697 /* Construct the return. */
7698 expand_naked_return ();
7703 ;; This is a bit of a hack. We're incrementing a fixed register (%i7),
7704 ;; and parts of the compiler don't want to believe that the add is needed.
7706 (define_insn "update_return"
7707 [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
7708 (match_operand:SI 1 "register_operand" "r")] UNSPEC_UPDATE_RETURN)]
7710 "cmp\t%1, 0\;be,a\t.+8\;add\t%0, 4, %0"
7711 [(set_attr "type" "multi")
7712 (set_attr "length" "3")])
7719 (define_expand "indirect_jump"
7720 [(set (pc) (match_operand 0 "address_operand" "p"))]
7724 (define_insn "*branch_sp32"
7725 [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
7728 [(set_attr "type" "uncond_branch")])
7730 (define_insn "*branch_sp64"
7731 [(set (pc) (match_operand:DI 0 "address_operand" "p"))]
7734 [(set_attr "type" "uncond_branch")])
7736 (define_expand "nonlocal_goto"
7737 [(match_operand:SI 0 "general_operand" "")
7738 (match_operand:SI 1 "general_operand" "")
7739 (match_operand:SI 2 "general_operand" "")
7740 (match_operand:SI 3 "" "")]
7744 rtx chain = operands[0];
7746 rtx lab = operands[1];
7747 rtx stack = operands[2];
7748 rtx fp = operands[3];
7751 /* Trap instruction to flush all the register windows. */
7752 emit_insn (gen_flush_register_windows ());
7754 /* Load the fp value for the containing fn into %fp. This is needed
7755 because STACK refers to %fp. Note that virtual register instantiation
7756 fails if the virtual %fp isn't set from a register. */
7757 if (GET_CODE (fp) != REG)
7758 fp = force_reg (Pmode, fp);
7759 emit_move_insn (virtual_stack_vars_rtx, fp);
7761 /* Find the containing function's current nonlocal goto handler,
7762 which will do any cleanups and then jump to the label. */
7763 labreg = gen_rtx_REG (Pmode, 8);
7764 emit_move_insn (labreg, lab);
7766 /* Restore %fp from stack pointer value for containing function.
7767 The restore insn that follows will move this to %sp,
7768 and reload the appropriate value into %fp. */
7769 emit_move_insn (hard_frame_pointer_rtx, stack);
7771 /* USE of frame_pointer_rtx added for consistency; not clear if
7773 /*emit_insn (gen_rtx_USE (VOIDmode, frame_pointer_rtx));*/
7774 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
7777 /* Return, restoring reg window and jumping to goto handler. */
7778 if (TARGET_V9 && GET_CODE (chain) == CONST_INT
7779 && ! (INTVAL (chain) & ~(HOST_WIDE_INT)0xffffffff))
7781 emit_jump_insn (gen_goto_handler_and_restore_v9 (labreg,
7787 /* Put in the static chain register the nonlocal label address. */
7788 emit_move_insn (static_chain_rtx, chain);
7791 emit_insn (gen_rtx_USE (VOIDmode, static_chain_rtx));
7792 emit_jump_insn (gen_goto_handler_and_restore (labreg));
7797 ;; Special trap insn to flush register windows.
7798 (define_insn "flush_register_windows"
7799 [(unspec_volatile [(const_int 0)] UNSPECV_FLUSHW)]
7801 { return TARGET_V9 ? "flushw" : "ta\t3"; }
7802 [(set_attr "type" "flushw")])
7804 (define_insn "goto_handler_and_restore"
7805 [(unspec_volatile [(match_operand 0 "register_operand" "=r")] UNSPECV_GOTO)]
7806 "GET_MODE (operands[0]) == Pmode"
7807 "jmp\t%0+0\n\trestore"
7808 [(set_attr "type" "multi")
7809 (set_attr "length" "2")])
7811 ;;(define_insn "goto_handler_and_restore_v9"
7812 ;; [(unspec_volatile [(match_operand:SI 0 "register_operand" "=r,r")
7813 ;; (match_operand:SI 1 "register_operand" "=r,r")
7814 ;; (match_operand:SI 2 "const_int_operand" "I,n")] UNSPECV_GOTO_V9)]
7815 ;; "TARGET_V9 && ! TARGET_ARCH64"
7817 ;; return\t%0+0\n\tmov\t%2, %Y1
7818 ;; sethi\t%%hi(%2), %1\n\treturn\t%0+0\n\tor\t%Y1, %%lo(%2), %Y1"
7819 ;; [(set_attr "type" "multi")
7820 ;; (set_attr "length" "2,3")])
7822 ;;(define_insn "*goto_handler_and_restore_v9_sp64"
7823 ;; [(unspec_volatile [(match_operand:DI 0 "register_operand" "=r,r")
7824 ;; (match_operand:DI 1 "register_operand" "=r,r")
7825 ;; (match_operand:SI 2 "const_int_operand" "I,n")] UNSPECV_GOTO_V9)]
7826 ;; "TARGET_V9 && TARGET_ARCH64"
7828 ;; return\t%0+0\n\tmov\t%2, %Y1
7829 ;; sethi\t%%hi(%2), %1\n\treturn\t%0+0\n\tor\t%Y1, %%lo(%2), %Y1"
7830 ;; [(set_attr "type" "multi")
7831 ;; (set_attr "length" "2,3")])
7833 ;; For __builtin_setjmp we need to flush register windows iff the function
7834 ;; calls alloca as well, because otherwise the register window might be
7835 ;; saved after %sp adjustment and thus setjmp would crash
7836 (define_expand "builtin_setjmp_setup"
7837 [(match_operand 0 "register_operand" "r")]
7840 emit_insn (gen_do_builtin_setjmp_setup ());
7844 (define_insn "do_builtin_setjmp_setup"
7845 [(unspec_volatile [(const_int 0)] UNSPECV_SETJMP)]
7848 if (! current_function_calls_alloca)
7852 fputs ("\tflushw\n", asm_out_file);
7854 fprintf (asm_out_file, "\tst%c\t%%l7, [%%sp+%d]\n",
7855 TARGET_ARCH64 ? 'x' : 'w',
7856 SPARC_STACK_BIAS + 7 * UNITS_PER_WORD);
7857 fprintf (asm_out_file, "\tst%c\t%%fp, [%%sp+%d]\n",
7858 TARGET_ARCH64 ? 'x' : 'w',
7859 SPARC_STACK_BIAS + 14 * UNITS_PER_WORD);
7860 fprintf (asm_out_file, "\tst%c\t%%i7, [%%sp+%d]\n",
7861 TARGET_ARCH64 ? 'x' : 'w',
7862 SPARC_STACK_BIAS + 15 * UNITS_PER_WORD);
7865 [(set_attr "type" "multi")
7866 (set (attr "length")
7867 (cond [(eq_attr "current_function_calls_alloca" "false")
7869 (eq_attr "isa" "!v9")
7871 (eq_attr "pic" "true")
7872 (const_int 4)] (const_int 3)))])
7874 ;; Pattern for use after a setjmp to store FP and the return register
7875 ;; into the stack area.
7877 (define_expand "setjmp"
7882 emit_insn (gen_setjmp_64 ());
7884 emit_insn (gen_setjmp_32 ());
7888 (define_expand "setjmp_32"
7889 [(set (mem:SI (plus:SI (reg:SI 14) (const_int 56))) (match_dup 0))
7890 (set (mem:SI (plus:SI (reg:SI 14) (const_int 60))) (reg:SI 31))]
7892 { operands[0] = frame_pointer_rtx; })
7894 (define_expand "setjmp_64"
7895 [(set (mem:DI (plus:DI (reg:DI 14) (const_int 112))) (match_dup 0))
7896 (set (mem:DI (plus:DI (reg:DI 14) (const_int 120))) (reg:DI 31))]
7898 { operands[0] = frame_pointer_rtx; })
7900 ;; Special pattern for the FLUSH instruction.
7902 ; We do SImode and DImode versions of this to quiet down genrecog's complaints
7903 ; of the define_insn otherwise missing a mode. We make "flush", aka
7904 ; gen_flush, the default one since sparc_initialize_trampoline uses
7905 ; it on SImode mem values.
7907 (define_insn "flush"
7908 [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")] UNSPECV_FLUSH)]
7910 { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; }
7911 [(set_attr "type" "iflush")])
7913 (define_insn "flushdi"
7914 [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")] UNSPECV_FLUSH)]
7916 { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; }
7917 [(set_attr "type" "iflush")])
7922 ;; The scan instruction searches from the most significant bit while ffs
7923 ;; searches from the least significant bit. The bit index and treatment of
7924 ;; zero also differ. It takes at least 7 instructions to get the proper
7925 ;; result. Here is an obvious 8 instruction sequence.
7928 (define_insn "ffssi2"
7929 [(set (match_operand:SI 0 "register_operand" "=&r")
7930 (ffs:SI (match_operand:SI 1 "register_operand" "r")))
7931 (clobber (match_scratch:SI 2 "=&r"))]
7932 "TARGET_SPARCLITE || TARGET_SPARCLET"
7934 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";
7936 [(set_attr "type" "multi")
7937 (set_attr "length" "8")])
7939 ;; ??? This should be a define expand, so that the extra instruction have
7940 ;; a chance of being optimized away.
7942 ;; Disabled because none of the UltraSPARCs implement popc. The HAL R1
7943 ;; does, but no one uses that and we don't have a switch for it.
7945 ;(define_insn "ffsdi2"
7946 ; [(set (match_operand:DI 0 "register_operand" "=&r")
7947 ; (ffs:DI (match_operand:DI 1 "register_operand" "r")))
7948 ; (clobber (match_scratch:DI 2 "=&r"))]
7950 ; "neg\t%1, %2\;xnor\t%1, %2, %2\;popc\t%2, %0\;movzr\t%1, 0, %0"
7951 ; [(set_attr "type" "multi")
7952 ; (set_attr "length" "4")])
7956 ;; Peepholes go at the end.
7958 ;; Optimize consecutive loads or stores into ldd and std when possible.
7959 ;; The conditions in which we do this are very restricted and are
7960 ;; explained in the code for {registers,memory}_ok_for_ldd functions.
7963 [(set (match_operand:SI 0 "memory_operand" "")
7965 (set (match_operand:SI 1 "memory_operand" "")
7968 && mems_ok_for_ldd_peep (operands[0], operands[1], NULL_RTX)"
7971 "operands[0] = widen_memory_access (operands[0], DImode, 0);")
7974 [(set (match_operand:SI 0 "memory_operand" "")
7976 (set (match_operand:SI 1 "memory_operand" "")
7979 && mems_ok_for_ldd_peep (operands[1], operands[0], NULL_RTX)"
7982 "operands[1] = widen_memory_access (operands[1], DImode, 0);")
7985 [(set (match_operand:SI 0 "register_operand" "")
7986 (match_operand:SI 1 "memory_operand" ""))
7987 (set (match_operand:SI 2 "register_operand" "")
7988 (match_operand:SI 3 "memory_operand" ""))]
7989 "registers_ok_for_ldd_peep (operands[0], operands[2])
7990 && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
7993 "operands[1] = widen_memory_access (operands[1], DImode, 0);
7994 operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));")
7997 [(set (match_operand:SI 0 "memory_operand" "")
7998 (match_operand:SI 1 "register_operand" ""))
7999 (set (match_operand:SI 2 "memory_operand" "")
8000 (match_operand:SI 3 "register_operand" ""))]
8001 "registers_ok_for_ldd_peep (operands[1], operands[3])
8002 && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
8005 "operands[0] = widen_memory_access (operands[0], DImode, 0);
8006 operands[1] = gen_rtx_REG (DImode, REGNO (operands[1]));")
8009 [(set (match_operand:SF 0 "register_operand" "")
8010 (match_operand:SF 1 "memory_operand" ""))
8011 (set (match_operand:SF 2 "register_operand" "")
8012 (match_operand:SF 3 "memory_operand" ""))]
8013 "registers_ok_for_ldd_peep (operands[0], operands[2])
8014 && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
8017 "operands[1] = widen_memory_access (operands[1], DFmode, 0);
8018 operands[0] = gen_rtx_REG (DFmode, REGNO (operands[0]));")
8021 [(set (match_operand:SF 0 "memory_operand" "")
8022 (match_operand:SF 1 "register_operand" ""))
8023 (set (match_operand:SF 2 "memory_operand" "")
8024 (match_operand:SF 3 "register_operand" ""))]
8025 "registers_ok_for_ldd_peep (operands[1], operands[3])
8026 && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
8029 "operands[0] = widen_memory_access (operands[0], DFmode, 0);
8030 operands[1] = gen_rtx_REG (DFmode, REGNO (operands[1]));")
8033 [(set (match_operand:SI 0 "register_operand" "")
8034 (match_operand:SI 1 "memory_operand" ""))
8035 (set (match_operand:SI 2 "register_operand" "")
8036 (match_operand:SI 3 "memory_operand" ""))]
8037 "registers_ok_for_ldd_peep (operands[2], operands[0])
8038 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
8041 "operands[3] = widen_memory_access (operands[3], DImode, 0);
8042 operands[2] = gen_rtx_REG (DImode, REGNO (operands[2]));")
8045 [(set (match_operand:SI 0 "memory_operand" "")
8046 (match_operand:SI 1 "register_operand" ""))
8047 (set (match_operand:SI 2 "memory_operand" "")
8048 (match_operand:SI 3 "register_operand" ""))]
8049 "registers_ok_for_ldd_peep (operands[3], operands[1])
8050 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
8053 "operands[2] = widen_memory_access (operands[2], DImode, 0);
8054 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
8058 [(set (match_operand:SF 0 "register_operand" "")
8059 (match_operand:SF 1 "memory_operand" ""))
8060 (set (match_operand:SF 2 "register_operand" "")
8061 (match_operand:SF 3 "memory_operand" ""))]
8062 "registers_ok_for_ldd_peep (operands[2], operands[0])
8063 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
8066 "operands[3] = widen_memory_access (operands[3], DFmode, 0);
8067 operands[2] = gen_rtx_REG (DFmode, REGNO (operands[2]));")
8070 [(set (match_operand:SF 0 "memory_operand" "")
8071 (match_operand:SF 1 "register_operand" ""))
8072 (set (match_operand:SF 2 "memory_operand" "")
8073 (match_operand:SF 3 "register_operand" ""))]
8074 "registers_ok_for_ldd_peep (operands[3], operands[1])
8075 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
8078 "operands[2] = widen_memory_access (operands[2], DFmode, 0);
8079 operands[3] = gen_rtx_REG (DFmode, REGNO (operands[3]));")
8081 ;; Optimize the case of following a reg-reg move with a test
8082 ;; of reg just moved. Don't allow floating point regs for operand 0 or 1.
8083 ;; This can result from a float to fix conversion.
8086 [(set (match_operand:SI 0 "register_operand" "")
8087 (match_operand:SI 1 "register_operand" ""))
8089 (compare:CC (match_operand:SI 2 "register_operand" "")
8091 "(rtx_equal_p (operands[2], operands[0])
8092 || rtx_equal_p (operands[2], operands[1]))
8093 && ! SPARC_FP_REG_P (REGNO (operands[0]))
8094 && ! SPARC_FP_REG_P (REGNO (operands[1]))"
8095 [(parallel [(set (match_dup 0) (match_dup 1))
8097 (compare:CC (match_dup 1) (const_int 0)))])]
8101 [(set (match_operand:DI 0 "register_operand" "")
8102 (match_operand:DI 1 "register_operand" ""))
8104 (compare:CCX (match_operand:DI 2 "register_operand" "")
8107 && (rtx_equal_p (operands[2], operands[0])
8108 || rtx_equal_p (operands[2], operands[1]))
8109 && ! SPARC_FP_REG_P (REGNO (operands[0]))
8110 && ! SPARC_FP_REG_P (REGNO (operands[1]))"
8111 [(parallel [(set (match_dup 0) (match_dup 1))
8113 (compare:CCX (match_dup 1) (const_int 0)))])]
8116 ;; Return peepholes. These are generated by sparc_function_epilogue
8117 ;; who then immediately calls final_scan_insn.
8119 (define_insn "*return_qi"
8120 [(set (match_operand:QI 0 "restore_operand" "")
8121 (match_operand:QI 1 "arith_operand" "rI"))
8123 "sparc_emitting_epilogue"
8125 if (! TARGET_ARCH64 && current_function_returns_struct)
8126 return "jmp\t%%i7+12\n\trestore %%g0, %1, %Y0";
8127 else if (TARGET_V9 && (GET_CODE (operands[1]) == CONST_INT
8128 || IN_OR_GLOBAL_P (operands[1])))
8129 return "return\t%%i7+8\n\tmov\t%Y1, %Y0";
8131 return "ret\n\trestore %%g0, %1, %Y0";
8133 [(set_attr "type" "multi")
8134 (set_attr "length" "2")])
8136 (define_insn "*return_hi"
8137 [(set (match_operand:HI 0 "restore_operand" "")
8138 (match_operand:HI 1 "arith_operand" "rI"))
8140 "sparc_emitting_epilogue"
8142 if (! TARGET_ARCH64 && current_function_returns_struct)
8143 return "jmp\t%%i7+12\n\trestore %%g0, %1, %Y0";
8144 else if (TARGET_V9 && (GET_CODE (operands[1]) == CONST_INT
8145 || IN_OR_GLOBAL_P (operands[1])))
8146 return "return\t%%i7+8\n\tmov\t%Y1, %Y0";
8148 return "ret\;restore %%g0, %1, %Y0";
8150 [(set_attr "type" "multi")
8151 (set_attr "length" "2")])
8153 (define_insn "*return_si"
8154 [(set (match_operand:SI 0 "restore_operand" "")
8155 (match_operand:SI 1 "arith_operand" "rI"))
8157 "sparc_emitting_epilogue"
8159 if (! TARGET_ARCH64 && current_function_returns_struct)
8160 return "jmp\t%%i7+12\n\trestore %%g0, %1, %Y0";
8161 else if (TARGET_V9 && (GET_CODE (operands[1]) == CONST_INT
8162 || IN_OR_GLOBAL_P (operands[1])))
8163 return "return\t%%i7+8\n\tmov\t%Y1, %Y0";
8165 return "ret\;restore %%g0, %1, %Y0";
8167 [(set_attr "type" "multi")
8168 (set_attr "length" "2")])
8170 (define_insn "*return_sf_no_fpu"
8171 [(set (match_operand:SF 0 "restore_operand" "=r")
8172 (match_operand:SF 1 "register_operand" "r"))
8174 "sparc_emitting_epilogue"
8176 if (! TARGET_ARCH64 && current_function_returns_struct)
8177 return "jmp\t%%i7+12\n\trestore %%g0, %1, %Y0";
8178 else if (TARGET_V9 && IN_OR_GLOBAL_P (operands[1]))
8179 return "return\t%%i7+8\n\tmov\t%Y1, %Y0";
8181 return "ret\;restore %%g0, %1, %Y0";
8183 [(set_attr "type" "multi")
8184 (set_attr "length" "2")])
8186 (define_insn "*return_df_no_fpu"
8187 [(set (match_operand:DF 0 "restore_operand" "=r")
8188 (match_operand:DF 1 "register_operand" "r"))
8190 "sparc_emitting_epilogue && TARGET_ARCH64"
8192 if (IN_OR_GLOBAL_P (operands[1]))
8193 return "return\t%%i7+8\n\tmov\t%Y1, %Y0";
8195 return "ret\;restore %%g0, %1, %Y0";
8197 [(set_attr "type" "multi")
8198 (set_attr "length" "2")])
8200 (define_insn "*return_addsi"
8201 [(set (match_operand:SI 0 "restore_operand" "")
8202 (plus:SI (match_operand:SI 1 "register_operand" "r")
8203 (match_operand:SI 2 "arith_operand" "rI")))
8205 "sparc_emitting_epilogue"
8207 if (! TARGET_ARCH64 && current_function_returns_struct)
8208 return "jmp\t%%i7+12\n\trestore %r1, %2, %Y0";
8209 /* If operands are global or in registers, can use return */
8210 else if (TARGET_V9 && IN_OR_GLOBAL_P (operands[1])
8211 && (GET_CODE (operands[2]) == CONST_INT
8212 || IN_OR_GLOBAL_P (operands[2])))
8213 return "return\t%%i7+8\n\tadd\t%Y1, %Y2, %Y0";
8215 return "ret\;restore %r1, %2, %Y0";
8217 [(set_attr "type" "multi")
8218 (set_attr "length" "2")])
8220 (define_insn "*return_losum_si"
8221 [(set (match_operand:SI 0 "restore_operand" "")
8222 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
8223 (match_operand:SI 2 "immediate_operand" "in")))
8225 "sparc_emitting_epilogue && ! TARGET_CM_MEDMID"
8227 if (! TARGET_ARCH64 && current_function_returns_struct)
8228 return "jmp\t%%i7+12\n\trestore %r1, %%lo(%a2), %Y0";
8229 /* If operands are global or in registers, can use return */
8230 else if (TARGET_V9 && IN_OR_GLOBAL_P (operands[1]))
8231 return "return\t%%i7+8\n\tor\t%Y1, %%lo(%a2), %Y0";
8233 return "ret\;restore %r1, %%lo(%a2), %Y0";
8235 [(set_attr "type" "multi")
8236 (set_attr "length" "2")])
8238 (define_insn "*return_di"
8239 [(set (match_operand:DI 0 "restore_operand" "")
8240 (match_operand:DI 1 "arith_double_operand" "rHI"))
8242 "sparc_emitting_epilogue && TARGET_ARCH64"
8243 "ret\;restore %%g0, %1, %Y0"
8244 [(set_attr "type" "multi")
8245 (set_attr "length" "2")])
8247 (define_insn "*return_adddi"
8248 [(set (match_operand:DI 0 "restore_operand" "")
8249 (plus:DI (match_operand:DI 1 "arith_operand" "%r")
8250 (match_operand:DI 2 "arith_double_operand" "rHI")))
8252 "sparc_emitting_epilogue && TARGET_ARCH64"
8253 "ret\;restore %r1, %2, %Y0"
8254 [(set_attr "type" "multi")
8255 (set_attr "length" "2")])
8257 (define_insn "*return_losum_di"
8258 [(set (match_operand:DI 0 "restore_operand" "")
8259 (lo_sum:DI (match_operand:DI 1 "arith_operand" "%r")
8260 (match_operand:DI 2 "immediate_operand" "in")))
8262 "sparc_emitting_epilogue && TARGET_ARCH64 && ! TARGET_CM_MEDMID"
8263 "ret\;restore %r1, %%lo(%a2), %Y0"
8264 [(set_attr "type" "multi")
8265 (set_attr "length" "2")])
8267 (define_insn "*return_sf"
8269 (match_operand:SF 0 "register_operand" "f"))
8271 "sparc_emitting_epilogue"
8272 "ret\;fmovs\t%0, %%f0"
8273 [(set_attr "type" "multi")
8274 (set_attr "length" "2")])
8276 ;; ??? UltraSPARC-III note: A memory operation loading into the floating point register
8277 ;; ??? file, if it hits the prefetch cache, has a chance to dual-issue with other memory
8278 ;; ??? operations. With DFA we might be able to model this, but it requires a lot of
8280 (define_expand "prefetch"
8281 [(match_operand 0 "address_operand" "")
8282 (match_operand 1 "const_int_operand" "")
8283 (match_operand 2 "const_int_operand" "")]
8287 emit_insn (gen_prefetch_64 (operands[0], operands[1], operands[2]));
8289 emit_insn (gen_prefetch_32 (operands[0], operands[1], operands[2]));
8293 (define_insn "prefetch_64"
8294 [(prefetch (match_operand:DI 0 "address_operand" "p")
8295 (match_operand:DI 1 "const_int_operand" "n")
8296 (match_operand:DI 2 "const_int_operand" "n"))]
8299 static const char * const prefetch_instr[2][2] = {
8301 "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
8302 "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
8305 "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
8306 "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
8309 int read_or_write = INTVAL (operands[1]);
8310 int locality = INTVAL (operands[2]);
8312 if (read_or_write != 0 && read_or_write != 1)
8314 if (locality < 0 || locality > 3)
8316 return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
8318 [(set_attr "type" "load")])
8320 (define_insn "prefetch_32"
8321 [(prefetch (match_operand:SI 0 "address_operand" "p")
8322 (match_operand:SI 1 "const_int_operand" "n")
8323 (match_operand:SI 2 "const_int_operand" "n"))]
8326 static const char * const prefetch_instr[2][2] = {
8328 "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
8329 "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
8332 "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
8333 "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
8336 int read_or_write = INTVAL (operands[1]);
8337 int locality = INTVAL (operands[2]);
8339 if (read_or_write != 0 && read_or_write != 1)
8341 if (locality < 0 || locality > 3)
8343 return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
8345 [(set_attr "type" "load")])
8347 (define_expand "prologue"
8349 "flag_pic && current_function_uses_pic_offset_table"
8351 load_pic_register ();
8356 [(trap_if (const_int 1) (const_int 5))]
8359 [(set_attr "type" "trap")])
8361 (define_expand "conditional_trap"
8362 [(trap_if (match_operator 0 "noov_compare_op"
8363 [(match_dup 2) (match_dup 3)])
8364 (match_operand:SI 1 "arith_operand" ""))]
8366 "operands[2] = gen_compare_reg (GET_CODE (operands[0]),
8367 sparc_compare_op0, sparc_compare_op1);
8368 operands[3] = const0_rtx;")
8371 [(trap_if (match_operator 0 "noov_compare_op" [(reg:CC 100) (const_int 0)])
8372 (match_operand:SI 1 "arith_operand" "rM"))]
8375 [(set_attr "type" "trap")])
8378 [(trap_if (match_operator 0 "noov_compare_op" [(reg:CCX 100) (const_int 0)])
8379 (match_operand:SI 1 "arith_operand" "rM"))]
8382 [(set_attr "type" "trap")])
8385 (define_insn "tgd_hi22"
8386 [(set (match_operand:SI 0 "register_operand" "=r")
8387 (high:SI (unspec:SI [(match_operand 1 "tgd_symbolic_operand" "")]
8390 "sethi\\t%%tgd_hi22(%a1), %0")
8392 (define_insn "tgd_lo10"
8393 [(set (match_operand:SI 0 "register_operand" "=r")
8394 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
8395 (unspec:SI [(match_operand 2 "tgd_symbolic_operand" "")]
8398 "add\\t%1, %%tgd_lo10(%a2), %0")
8400 (define_insn "tgd_add32"
8401 [(set (match_operand:SI 0 "register_operand" "=r")
8402 (plus:SI (match_operand:SI 1 "register_operand" "r")
8403 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8404 (match_operand 3 "tgd_symbolic_operand" "")]
8406 "TARGET_TLS && TARGET_ARCH32"
8407 "add\\t%1, %2, %0, %%tgd_add(%a3)")
8409 (define_insn "tgd_add64"
8410 [(set (match_operand:DI 0 "register_operand" "=r")
8411 (plus:DI (match_operand:DI 1 "register_operand" "r")
8412 (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8413 (match_operand 3 "tgd_symbolic_operand" "")]
8415 "TARGET_TLS && TARGET_ARCH64"
8416 "add\\t%1, %2, %0, %%tgd_add(%a3)")
8418 (define_insn "tgd_call32"
8419 [(set (match_operand 0 "register_operand" "=r")
8420 (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")
8421 (match_operand 2 "tgd_symbolic_operand" "")]
8423 (match_operand 3 "" "")))
8424 (clobber (reg:SI 15))]
8425 "TARGET_TLS && TARGET_ARCH32"
8426 "call\t%a1, %%tgd_call(%a2)%#"
8427 [(set_attr "type" "call")])
8429 (define_insn "tgd_call64"
8430 [(set (match_operand 0 "register_operand" "=r")
8431 (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")
8432 (match_operand 2 "tgd_symbolic_operand" "")]
8434 (match_operand 3 "" "")))
8435 (clobber (reg:DI 15))]
8436 "TARGET_TLS && TARGET_ARCH64"
8437 "call\t%a1, %%tgd_call(%a2)%#"
8438 [(set_attr "type" "call")])
8440 (define_insn "tldm_hi22"
8441 [(set (match_operand:SI 0 "register_operand" "=r")
8442 (high:SI (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
8444 "sethi\\t%%tldm_hi22(%&), %0")
8446 (define_insn "tldm_lo10"
8447 [(set (match_operand:SI 0 "register_operand" "=r")
8448 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
8449 (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
8451 "add\\t%1, %%tldm_lo10(%&), %0")
8453 (define_insn "tldm_add32"
8454 [(set (match_operand:SI 0 "register_operand" "=r")
8455 (plus:SI (match_operand:SI 1 "register_operand" "r")
8456 (unspec:SI [(match_operand:SI 2 "register_operand" "r")]
8458 "TARGET_TLS && TARGET_ARCH32"
8459 "add\\t%1, %2, %0, %%tldm_add(%&)")
8461 (define_insn "tldm_add64"
8462 [(set (match_operand:DI 0 "register_operand" "=r")
8463 (plus:DI (match_operand:DI 1 "register_operand" "r")
8464 (unspec:DI [(match_operand:SI 2 "register_operand" "r")]
8466 "TARGET_TLS && TARGET_ARCH64"
8467 "add\\t%1, %2, %0, %%tldm_add(%&)")
8469 (define_insn "tldm_call32"
8470 [(set (match_operand 0 "register_operand" "=r")
8471 (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")]
8473 (match_operand 2 "" "")))
8474 (clobber (reg:SI 15))]
8475 "TARGET_TLS && TARGET_ARCH32"
8476 "call\t%a1, %%tldm_call(%&)%#"
8477 [(set_attr "type" "call")])
8479 (define_insn "tldm_call64"
8480 [(set (match_operand 0 "register_operand" "=r")
8481 (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")]
8483 (match_operand 2 "" "")))
8484 (clobber (reg:DI 15))]
8485 "TARGET_TLS && TARGET_ARCH64"
8486 "call\t%a1, %%tldm_call(%&)%#"
8487 [(set_attr "type" "call")])
8489 (define_insn "tldo_hix22"
8490 [(set (match_operand:SI 0 "register_operand" "=r")
8491 (high:SI (unspec:SI [(match_operand 1 "tld_symbolic_operand" "")]
8494 "sethi\\t%%tldo_hix22(%a1), %0")
8496 (define_insn "tldo_lox10"
8497 [(set (match_operand:SI 0 "register_operand" "=r")
8498 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
8499 (unspec:SI [(match_operand 2 "tld_symbolic_operand" "")]
8502 "xor\\t%1, %%tldo_lox10(%a2), %0")
8504 (define_insn "tldo_add32"
8505 [(set (match_operand:SI 0 "register_operand" "=r")
8506 (plus:SI (match_operand:SI 1 "register_operand" "r")
8507 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8508 (match_operand 3 "tld_symbolic_operand" "")]
8510 "TARGET_TLS && TARGET_ARCH32"
8511 "add\\t%1, %2, %0, %%tldo_add(%a3)")
8513 (define_insn "tldo_add64"
8514 [(set (match_operand:DI 0 "register_operand" "=r")
8515 (plus:DI (match_operand:DI 1 "register_operand" "r")
8516 (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8517 (match_operand 3 "tld_symbolic_operand" "")]
8519 "TARGET_TLS && TARGET_ARCH64"
8520 "add\\t%1, %2, %0, %%tldo_add(%a3)")
8522 (define_insn "tie_hi22"
8523 [(set (match_operand:SI 0 "register_operand" "=r")
8524 (high:SI (unspec:SI [(match_operand 1 "tie_symbolic_operand" "")]
8527 "sethi\\t%%tie_hi22(%a1), %0")
8529 (define_insn "tie_lo10"
8530 [(set (match_operand:SI 0 "register_operand" "=r")
8531 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
8532 (unspec:SI [(match_operand 2 "tie_symbolic_operand" "")]
8535 "add\\t%1, %%tie_lo10(%a2), %0")
8537 (define_insn "tie_ld32"
8538 [(set (match_operand:SI 0 "register_operand" "=r")
8539 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
8540 (match_operand:SI 2 "register_operand" "r")
8541 (match_operand 3 "tie_symbolic_operand" "")]
8543 "TARGET_TLS && TARGET_ARCH32"
8544 "ld\\t[%1 + %2], %0, %%tie_ld(%a3)"
8545 [(set_attr "type" "load")])
8547 (define_insn "tie_ld64"
8548 [(set (match_operand:DI 0 "register_operand" "=r")
8549 (unspec:DI [(match_operand:DI 1 "register_operand" "r")
8550 (match_operand:SI 2 "register_operand" "r")
8551 (match_operand 3 "tie_symbolic_operand" "")]
8553 "TARGET_TLS && TARGET_ARCH64"
8554 "ldx\\t[%1 + %2], %0, %%tie_ldx(%a3)"
8555 [(set_attr "type" "load")])
8557 (define_insn "tie_add32"
8558 [(set (match_operand:SI 0 "register_operand" "=r")
8559 (plus:SI (match_operand:SI 1 "register_operand" "r")
8560 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8561 (match_operand 3 "tie_symbolic_operand" "")]
8563 "TARGET_SUN_TLS && TARGET_ARCH32"
8564 "add\\t%1, %2, %0, %%tie_add(%a3)")
8566 (define_insn "tie_add64"
8567 [(set (match_operand:DI 0 "register_operand" "=r")
8568 (plus:DI (match_operand:DI 1 "register_operand" "r")
8569 (unspec:DI [(match_operand:DI 2 "register_operand" "r")
8570 (match_operand 3 "tie_symbolic_operand" "")]
8572 "TARGET_SUN_TLS && TARGET_ARCH64"
8573 "add\\t%1, %2, %0, %%tie_add(%a3)")
8575 (define_insn "tle_hix22_sp32"
8576 [(set (match_operand:SI 0 "register_operand" "=r")
8577 (high:SI (unspec:SI [(match_operand 1 "tle_symbolic_operand" "")]
8579 "TARGET_TLS && TARGET_ARCH32"
8580 "sethi\\t%%tle_hix22(%a1), %0")
8582 (define_insn "tle_lox10_sp32"
8583 [(set (match_operand:SI 0 "register_operand" "=r")
8584 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
8585 (unspec:SI [(match_operand 2 "tle_symbolic_operand" "")]
8587 "TARGET_TLS && TARGET_ARCH32"
8588 "xor\\t%1, %%tle_lox10(%a2), %0")
8590 (define_insn "tle_hix22_sp64"
8591 [(set (match_operand:DI 0 "register_operand" "=r")
8592 (high:DI (unspec:DI [(match_operand 1 "tle_symbolic_operand" "")]
8594 "TARGET_TLS && TARGET_ARCH64"
8595 "sethi\\t%%tle_hix22(%a1), %0")
8597 (define_insn "tle_lox10_sp64"
8598 [(set (match_operand:DI 0 "register_operand" "=r")
8599 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
8600 (unspec:DI [(match_operand 2 "tle_symbolic_operand" "")]
8602 "TARGET_TLS && TARGET_ARCH64"
8603 "xor\\t%1, %%tle_lox10(%a2), %0")
8605 ;; Now patterns combining tldo_add{32,64} with some integer loads or stores
8606 (define_insn "*tldo_ldub_sp32"
8607 [(set (match_operand:QI 0 "register_operand" "=r")
8608 (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8609 (match_operand 3 "tld_symbolic_operand" "")]
8611 (match_operand:SI 1 "register_operand" "r"))))]
8612 "TARGET_TLS && TARGET_ARCH32"
8613 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8614 [(set_attr "type" "load")
8615 (set_attr "us3load_type" "3cycle")])
8617 (define_insn "*tldo_ldub1_sp32"
8618 [(set (match_operand:HI 0 "register_operand" "=r")
8619 (zero_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8620 (match_operand 3 "tld_symbolic_operand" "")]
8622 (match_operand:SI 1 "register_operand" "r")))))]
8623 "TARGET_TLS && TARGET_ARCH32"
8624 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8625 [(set_attr "type" "load")
8626 (set_attr "us3load_type" "3cycle")])
8628 (define_insn "*tldo_ldub2_sp32"
8629 [(set (match_operand:SI 0 "register_operand" "=r")
8630 (zero_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8631 (match_operand 3 "tld_symbolic_operand" "")]
8633 (match_operand:SI 1 "register_operand" "r")))))]
8634 "TARGET_TLS && TARGET_ARCH32"
8635 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8636 [(set_attr "type" "load")
8637 (set_attr "us3load_type" "3cycle")])
8639 (define_insn "*tldo_ldsb1_sp32"
8640 [(set (match_operand:HI 0 "register_operand" "=r")
8641 (sign_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8642 (match_operand 3 "tld_symbolic_operand" "")]
8644 (match_operand:SI 1 "register_operand" "r")))))]
8645 "TARGET_TLS && TARGET_ARCH32"
8646 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
8647 [(set_attr "type" "sload")
8648 (set_attr "us3load_type" "3cycle")])
8650 (define_insn "*tldo_ldsb2_sp32"
8651 [(set (match_operand:SI 0 "register_operand" "=r")
8652 (sign_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8653 (match_operand 3 "tld_symbolic_operand" "")]
8655 (match_operand:SI 1 "register_operand" "r")))))]
8656 "TARGET_TLS && TARGET_ARCH32"
8657 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
8658 [(set_attr "type" "sload")
8659 (set_attr "us3load_type" "3cycle")])
8661 (define_insn "*tldo_ldub_sp64"
8662 [(set (match_operand:QI 0 "register_operand" "=r")
8663 (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8664 (match_operand 3 "tld_symbolic_operand" "")]
8666 (match_operand:DI 1 "register_operand" "r"))))]
8667 "TARGET_TLS && TARGET_ARCH64"
8668 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8669 [(set_attr "type" "load")
8670 (set_attr "us3load_type" "3cycle")])
8672 (define_insn "*tldo_ldub1_sp64"
8673 [(set (match_operand:HI 0 "register_operand" "=r")
8674 (zero_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8675 (match_operand 3 "tld_symbolic_operand" "")]
8677 (match_operand:DI 1 "register_operand" "r")))))]
8678 "TARGET_TLS && TARGET_ARCH64"
8679 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8680 [(set_attr "type" "load")
8681 (set_attr "us3load_type" "3cycle")])
8683 (define_insn "*tldo_ldub2_sp64"
8684 [(set (match_operand:SI 0 "register_operand" "=r")
8685 (zero_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8686 (match_operand 3 "tld_symbolic_operand" "")]
8688 (match_operand:DI 1 "register_operand" "r")))))]
8689 "TARGET_TLS && TARGET_ARCH64"
8690 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8691 [(set_attr "type" "load")
8692 (set_attr "us3load_type" "3cycle")])
8694 (define_insn "*tldo_ldub3_sp64"
8695 [(set (match_operand:DI 0 "register_operand" "=r")
8696 (zero_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8697 (match_operand 3 "tld_symbolic_operand" "")]
8699 (match_operand:DI 1 "register_operand" "r")))))]
8700 "TARGET_TLS && TARGET_ARCH64"
8701 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8702 [(set_attr "type" "load")
8703 (set_attr "us3load_type" "3cycle")])
8705 (define_insn "*tldo_ldsb1_sp64"
8706 [(set (match_operand:HI 0 "register_operand" "=r")
8707 (sign_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8708 (match_operand 3 "tld_symbolic_operand" "")]
8710 (match_operand:DI 1 "register_operand" "r")))))]
8711 "TARGET_TLS && TARGET_ARCH64"
8712 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
8713 [(set_attr "type" "sload")
8714 (set_attr "us3load_type" "3cycle")])
8716 (define_insn "*tldo_ldsb2_sp64"
8717 [(set (match_operand:SI 0 "register_operand" "=r")
8718 (sign_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8719 (match_operand 3 "tld_symbolic_operand" "")]
8721 (match_operand:DI 1 "register_operand" "r")))))]
8722 "TARGET_TLS && TARGET_ARCH64"
8723 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
8724 [(set_attr "type" "sload")
8725 (set_attr "us3load_type" "3cycle")])
8727 (define_insn "*tldo_ldsb3_sp64"
8728 [(set (match_operand:DI 0 "register_operand" "=r")
8729 (sign_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8730 (match_operand 3 "tld_symbolic_operand" "")]
8732 (match_operand:DI 1 "register_operand" "r")))))]
8733 "TARGET_TLS && TARGET_ARCH64"
8734 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
8735 [(set_attr "type" "sload")
8736 (set_attr "us3load_type" "3cycle")])
8738 (define_insn "*tldo_lduh_sp32"
8739 [(set (match_operand:HI 0 "register_operand" "=r")
8740 (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8741 (match_operand 3 "tld_symbolic_operand" "")]
8743 (match_operand:SI 1 "register_operand" "r"))))]
8744 "TARGET_TLS && TARGET_ARCH32"
8745 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
8746 [(set_attr "type" "load")
8747 (set_attr "us3load_type" "3cycle")])
8749 (define_insn "*tldo_lduh1_sp32"
8750 [(set (match_operand:SI 0 "register_operand" "=r")
8751 (zero_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8752 (match_operand 3 "tld_symbolic_operand" "")]
8754 (match_operand:SI 1 "register_operand" "r")))))]
8755 "TARGET_TLS && TARGET_ARCH32"
8756 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
8757 [(set_attr "type" "load")
8758 (set_attr "us3load_type" "3cycle")])
8760 (define_insn "*tldo_ldsh1_sp32"
8761 [(set (match_operand:SI 0 "register_operand" "=r")
8762 (sign_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8763 (match_operand 3 "tld_symbolic_operand" "")]
8765 (match_operand:SI 1 "register_operand" "r")))))]
8766 "TARGET_TLS && TARGET_ARCH32"
8767 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
8768 [(set_attr "type" "sload")
8769 (set_attr "us3load_type" "3cycle")])
8771 (define_insn "*tldo_lduh_sp64"
8772 [(set (match_operand:HI 0 "register_operand" "=r")
8773 (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8774 (match_operand 3 "tld_symbolic_operand" "")]
8776 (match_operand:DI 1 "register_operand" "r"))))]
8777 "TARGET_TLS && TARGET_ARCH64"
8778 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
8779 [(set_attr "type" "load")
8780 (set_attr "us3load_type" "3cycle")])
8782 (define_insn "*tldo_lduh1_sp64"
8783 [(set (match_operand:SI 0 "register_operand" "=r")
8784 (zero_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8785 (match_operand 3 "tld_symbolic_operand" "")]
8787 (match_operand:DI 1 "register_operand" "r")))))]
8788 "TARGET_TLS && TARGET_ARCH64"
8789 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
8790 [(set_attr "type" "load")
8791 (set_attr "us3load_type" "3cycle")])
8793 (define_insn "*tldo_lduh2_sp64"
8794 [(set (match_operand:DI 0 "register_operand" "=r")
8795 (zero_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8796 (match_operand 3 "tld_symbolic_operand" "")]
8798 (match_operand:DI 1 "register_operand" "r")))))]
8799 "TARGET_TLS && TARGET_ARCH64"
8800 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
8801 [(set_attr "type" "load")
8802 (set_attr "us3load_type" "3cycle")])
8804 (define_insn "*tldo_ldsh1_sp64"
8805 [(set (match_operand:SI 0 "register_operand" "=r")
8806 (sign_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8807 (match_operand 3 "tld_symbolic_operand" "")]
8809 (match_operand:DI 1 "register_operand" "r")))))]
8810 "TARGET_TLS && TARGET_ARCH64"
8811 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
8812 [(set_attr "type" "sload")
8813 (set_attr "us3load_type" "3cycle")])
8815 (define_insn "*tldo_ldsh2_sp64"
8816 [(set (match_operand:DI 0 "register_operand" "=r")
8817 (sign_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8818 (match_operand 3 "tld_symbolic_operand" "")]
8820 (match_operand:DI 1 "register_operand" "r")))))]
8821 "TARGET_TLS && TARGET_ARCH64"
8822 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
8823 [(set_attr "type" "sload")
8824 (set_attr "us3load_type" "3cycle")])
8826 (define_insn "*tldo_lduw_sp32"
8827 [(set (match_operand:SI 0 "register_operand" "=r")
8828 (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8829 (match_operand 3 "tld_symbolic_operand" "")]
8831 (match_operand:SI 1 "register_operand" "r"))))]
8832 "TARGET_TLS && TARGET_ARCH32"
8833 "ld\t[%1 + %2], %0, %%tldo_add(%3)"
8834 [(set_attr "type" "load")])
8836 (define_insn "*tldo_lduw_sp64"
8837 [(set (match_operand:SI 0 "register_operand" "=r")
8838 (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8839 (match_operand 3 "tld_symbolic_operand" "")]
8841 (match_operand:DI 1 "register_operand" "r"))))]
8842 "TARGET_TLS && TARGET_ARCH64"
8843 "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
8844 [(set_attr "type" "load")])
8846 (define_insn "*tldo_lduw1_sp64"
8847 [(set (match_operand:DI 0 "register_operand" "=r")
8848 (zero_extend:DI (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8849 (match_operand 3 "tld_symbolic_operand" "")]
8851 (match_operand:DI 1 "register_operand" "r")))))]
8852 "TARGET_TLS && TARGET_ARCH64"
8853 "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
8854 [(set_attr "type" "load")])
8856 (define_insn "*tldo_ldsw1_sp64"
8857 [(set (match_operand:DI 0 "register_operand" "=r")
8858 (sign_extend:DI (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8859 (match_operand 3 "tld_symbolic_operand" "")]
8861 (match_operand:DI 1 "register_operand" "r")))))]
8862 "TARGET_TLS && TARGET_ARCH64"
8863 "ldsw\t[%1 + %2], %0, %%tldo_add(%3)"
8864 [(set_attr "type" "sload")
8865 (set_attr "us3load_type" "3cycle")])
8867 (define_insn "*tldo_ldx_sp64"
8868 [(set (match_operand:DI 0 "register_operand" "=r")
8869 (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8870 (match_operand 3 "tld_symbolic_operand" "")]
8872 (match_operand:DI 1 "register_operand" "r"))))]
8873 "TARGET_TLS && TARGET_ARCH64"
8874 "ldx\t[%1 + %2], %0, %%tldo_add(%3)"
8875 [(set_attr "type" "load")])
8877 (define_insn "*tldo_stb_sp32"
8878 [(set (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8879 (match_operand 3 "tld_symbolic_operand" "")]
8881 (match_operand:SI 1 "register_operand" "r")))
8882 (match_operand:QI 0 "register_operand" "=r"))]
8883 "TARGET_TLS && TARGET_ARCH32"
8884 "stb\t%0, [%1 + %2], %%tldo_add(%3)"
8885 [(set_attr "type" "store")])
8887 (define_insn "*tldo_stb_sp64"
8888 [(set (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8889 (match_operand 3 "tld_symbolic_operand" "")]
8891 (match_operand:DI 1 "register_operand" "r")))
8892 (match_operand:QI 0 "register_operand" "=r"))]
8893 "TARGET_TLS && TARGET_ARCH64"
8894 "stb\t%0, [%1 + %2], %%tldo_add(%3)"
8895 [(set_attr "type" "store")])
8897 (define_insn "*tldo_sth_sp32"
8898 [(set (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8899 (match_operand 3 "tld_symbolic_operand" "")]
8901 (match_operand:SI 1 "register_operand" "r")))
8902 (match_operand:HI 0 "register_operand" "=r"))]
8903 "TARGET_TLS && TARGET_ARCH32"
8904 "sth\t%0, [%1 + %2], %%tldo_add(%3)"
8905 [(set_attr "type" "store")])
8907 (define_insn "*tldo_sth_sp64"
8908 [(set (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8909 (match_operand 3 "tld_symbolic_operand" "")]
8911 (match_operand:DI 1 "register_operand" "r")))
8912 (match_operand:HI 0 "register_operand" "=r"))]
8913 "TARGET_TLS && TARGET_ARCH64"
8914 "sth\t%0, [%1 + %2], %%tldo_add(%3)"
8915 [(set_attr "type" "store")])
8917 (define_insn "*tldo_stw_sp32"
8918 [(set (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8919 (match_operand 3 "tld_symbolic_operand" "")]
8921 (match_operand:SI 1 "register_operand" "r")))
8922 (match_operand:SI 0 "register_operand" "=r"))]
8923 "TARGET_TLS && TARGET_ARCH32"
8924 "st\t%0, [%1 + %2], %%tldo_add(%3)"
8925 [(set_attr "type" "store")])
8927 (define_insn "*tldo_stw_sp64"
8928 [(set (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8929 (match_operand 3 "tld_symbolic_operand" "")]
8931 (match_operand:DI 1 "register_operand" "r")))
8932 (match_operand:SI 0 "register_operand" "=r"))]
8933 "TARGET_TLS && TARGET_ARCH64"
8934 "stw\t%0, [%1 + %2], %%tldo_add(%3)"
8935 [(set_attr "type" "store")])
8937 (define_insn "*tldo_stx_sp64"
8938 [(set (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8939 (match_operand 3 "tld_symbolic_operand" "")]
8941 (match_operand:DI 1 "register_operand" "r")))
8942 (match_operand:DI 0 "register_operand" "=r"))]
8943 "TARGET_TLS && TARGET_ARCH64"
8944 "stx\t%0, [%1 + %2], %%tldo_add(%3)"
8945 [(set_attr "type" "store")])