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 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" "v6,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 "v6"))))
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,
111 multi,flushw,iflush,trap"
112 (const_string "ialu"))
114 ;; true if branch/call has empty delay slot and will emit a nop in it
115 (define_attr "empty_delay_slot" "false,true"
116 (symbol_ref "empty_delay_slot (insn)"))
118 (define_attr "branch_type" "none,icc,fcc,reg" (const_string "none"))
120 (define_attr "pic" "false,true"
121 (symbol_ref "flag_pic != 0"))
123 (define_attr "current_function_calls_alloca" "false,true"
124 (symbol_ref "current_function_calls_alloca != 0"))
126 (define_attr "flat" "false,true"
127 (symbol_ref "TARGET_FLAT != 0"))
129 ;; Length (in # of insns).
130 (define_attr "length" ""
131 (cond [(eq_attr "type" "uncond_branch,call,sibcall")
132 (if_then_else (eq_attr "empty_delay_slot" "true")
135 (eq_attr "branch_type" "icc")
136 (if_then_else (match_operand 0 "noov_compare64_op" "")
137 (if_then_else (lt (pc) (match_dup 1))
138 (if_then_else (lt (minus (match_dup 1) (pc)) (const_int 260000))
139 (if_then_else (eq_attr "empty_delay_slot" "true")
142 (if_then_else (eq_attr "empty_delay_slot" "true")
145 (if_then_else (lt (minus (pc) (match_dup 1)) (const_int 260000))
146 (if_then_else (eq_attr "empty_delay_slot" "true")
149 (if_then_else (eq_attr "empty_delay_slot" "true")
152 (if_then_else (eq_attr "empty_delay_slot" "true")
155 (eq_attr "branch_type" "fcc")
156 (if_then_else (match_operand 0 "fcc0_reg_operand" "")
157 (if_then_else (eq_attr "empty_delay_slot" "true")
160 (if_then_else (lt (pc) (match_dup 2))
161 (if_then_else (lt (minus (match_dup 2) (pc)) (const_int 260000))
162 (if_then_else (eq_attr "empty_delay_slot" "true")
165 (if_then_else (eq_attr "empty_delay_slot" "true")
168 (if_then_else (lt (minus (pc) (match_dup 2)) (const_int 260000))
169 (if_then_else (eq_attr "empty_delay_slot" "true")
172 (if_then_else (eq_attr "empty_delay_slot" "true")
175 (eq_attr "branch_type" "reg")
176 (if_then_else (lt (pc) (match_dup 2))
177 (if_then_else (lt (minus (match_dup 2) (pc)) (const_int 32000))
178 (if_then_else (eq_attr "empty_delay_slot" "true")
181 (if_then_else (eq_attr "empty_delay_slot" "true")
184 (if_then_else (lt (minus (pc) (match_dup 2)) (const_int 32000))
185 (if_then_else (eq_attr "empty_delay_slot" "true")
188 (if_then_else (eq_attr "empty_delay_slot" "true")
194 (define_attr "fptype" "single,double" (const_string "single"))
196 ;; UltraSPARC-III integer load type.
197 (define_attr "us3load_type" "2cycle,3cycle" (const_string "2cycle"))
199 (define_asm_attributes
200 [(set_attr "length" "2")
201 (set_attr "type" "multi")])
203 ;; Attributes for instruction and branch scheduling
205 (define_attr "tls_call_delay" "false,true"
206 (symbol_ref "tls_call_delay (insn)"))
208 (define_attr "in_call_delay" "false,true"
209 (cond [(eq_attr "type" "uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
210 (const_string "false")
211 (eq_attr "type" "load,fpload,store,fpstore")
212 (if_then_else (eq_attr "length" "1")
213 (const_string "true")
214 (const_string "false"))]
215 (if_then_else (and (eq_attr "length" "1")
216 (eq_attr "tls_call_delay" "true"))
217 (const_string "true")
218 (const_string "false"))))
220 (define_delay (eq_attr "type" "call")
221 [(eq_attr "in_call_delay" "true") (nil) (nil)])
223 (define_attr "eligible_for_sibcall_delay" "false,true"
224 (symbol_ref "eligible_for_sibcall_delay (insn)"))
226 (define_delay (eq_attr "type" "sibcall")
227 [(eq_attr "eligible_for_sibcall_delay" "true") (nil) (nil)])
229 (define_attr "leaf_function" "false,true"
230 (const (symbol_ref "current_function_uses_only_leaf_regs")))
232 ;; ??? Should implement the notion of predelay slots for floating point
233 ;; branches. This would allow us to remove the nop always inserted before
234 ;; a floating point branch.
236 ;; ??? It is OK for fill_simple_delay_slots to put load/store instructions
237 ;; in a delay slot, but it is not OK for fill_eager_delay_slots to do so.
238 ;; This is because doing so will add several pipeline stalls to the path
239 ;; that the load/store did not come from. Unfortunately, there is no way
240 ;; to prevent fill_eager_delay_slots from using load/store without completely
241 ;; disabling them. For the SPEC benchmark set, this is a serious lose,
242 ;; because it prevents us from moving back the final store of inner loops.
244 (define_attr "in_branch_delay" "false,true"
245 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
246 (eq_attr "length" "1"))
247 (const_string "true")
248 (const_string "false")))
250 (define_attr "in_uncond_branch_delay" "false,true"
251 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
252 (eq_attr "length" "1"))
253 (const_string "true")
254 (const_string "false")))
256 (define_attr "in_annul_branch_delay" "false,true"
257 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
258 (eq_attr "length" "1"))
259 (const_string "true")
260 (const_string "false")))
262 (define_delay (eq_attr "type" "branch")
263 [(eq_attr "in_branch_delay" "true")
264 (nil) (eq_attr "in_annul_branch_delay" "true")])
266 (define_delay (eq_attr "type" "uncond_branch")
267 [(eq_attr "in_uncond_branch_delay" "true")
270 ;; Include SPARC DFA schedulers
272 (include "cypress.md")
273 (include "supersparc.md")
274 (include "hypersparc.md")
275 (include "sparclet.md")
276 (include "ultra1_2.md")
277 (include "ultra3.md")
280 ;; Compare instructions.
281 ;; This controls RTL generation and register allocation.
283 ;; We generate RTL for comparisons and branches by having the cmpxx
284 ;; patterns store away the operands. Then, the scc and bcc patterns
285 ;; emit RTL for both the compare and the branch.
287 ;; We do this because we want to generate different code for an sne and
288 ;; seq insn. In those cases, if the second operand of the compare is not
289 ;; const0_rtx, we want to compute the xor of the two operands and test
292 ;; We start with the DEFINE_EXPANDs, then the DEFINE_INSNs to match
293 ;; the patterns. Finally, we have the DEFINE_SPLITs for some of the scc
294 ;; insns that actually require more than one machine instruction.
296 ;; Put cmpsi first among compare insns so it matches two CONST_INT operands.
298 (define_expand "cmpsi"
300 (compare:CC (match_operand:SI 0 "register_operand" "")
301 (match_operand:SI 1 "arith_operand" "")))]
304 sparc_compare_op0 = operands[0];
305 sparc_compare_op1 = operands[1];
309 (define_expand "cmpdi"
311 (compare:CCX (match_operand:DI 0 "register_operand" "")
312 (match_operand:DI 1 "arith_double_operand" "")))]
315 sparc_compare_op0 = operands[0];
316 sparc_compare_op1 = operands[1];
320 (define_expand "cmpsf"
321 ;; The 96 here isn't ever used by anyone.
323 (compare:CCFP (match_operand:SF 0 "register_operand" "")
324 (match_operand:SF 1 "register_operand" "")))]
327 sparc_compare_op0 = operands[0];
328 sparc_compare_op1 = operands[1];
332 (define_expand "cmpdf"
333 ;; The 96 here isn't ever used by anyone.
335 (compare:CCFP (match_operand:DF 0 "register_operand" "")
336 (match_operand:DF 1 "register_operand" "")))]
339 sparc_compare_op0 = operands[0];
340 sparc_compare_op1 = operands[1];
344 (define_expand "cmptf"
345 ;; The 96 here isn't ever used by anyone.
347 (compare:CCFP (match_operand:TF 0 "register_operand" "")
348 (match_operand:TF 1 "register_operand" "")))]
351 sparc_compare_op0 = operands[0];
352 sparc_compare_op1 = operands[1];
356 ;; Now the compare DEFINE_INSNs.
358 (define_insn "*cmpsi_insn"
360 (compare:CC (match_operand:SI 0 "register_operand" "r")
361 (match_operand:SI 1 "arith_operand" "rI")))]
364 [(set_attr "type" "compare")])
366 (define_insn "*cmpdi_sp64"
368 (compare:CCX (match_operand:DI 0 "register_operand" "r")
369 (match_operand:DI 1 "arith_double_operand" "rHI")))]
372 [(set_attr "type" "compare")])
374 (define_insn "*cmpsf_fpe"
375 [(set (match_operand:CCFPE 0 "fcc_reg_operand" "=c")
376 (compare:CCFPE (match_operand:SF 1 "register_operand" "f")
377 (match_operand:SF 2 "register_operand" "f")))]
381 return "fcmpes\t%0, %1, %2";
382 return "fcmpes\t%1, %2";
384 [(set_attr "type" "fpcmp")])
386 (define_insn "*cmpdf_fpe"
387 [(set (match_operand:CCFPE 0 "fcc_reg_operand" "=c")
388 (compare:CCFPE (match_operand:DF 1 "register_operand" "e")
389 (match_operand:DF 2 "register_operand" "e")))]
393 return "fcmped\t%0, %1, %2";
394 return "fcmped\t%1, %2";
396 [(set_attr "type" "fpcmp")
397 (set_attr "fptype" "double")])
399 (define_insn "*cmptf_fpe"
400 [(set (match_operand:CCFPE 0 "fcc_reg_operand" "=c")
401 (compare:CCFPE (match_operand:TF 1 "register_operand" "e")
402 (match_operand:TF 2 "register_operand" "e")))]
403 "TARGET_FPU && TARGET_HARD_QUAD"
406 return "fcmpeq\t%0, %1, %2";
407 return "fcmpeq\t%1, %2";
409 [(set_attr "type" "fpcmp")])
411 (define_insn "*cmpsf_fp"
412 [(set (match_operand:CCFP 0 "fcc_reg_operand" "=c")
413 (compare:CCFP (match_operand:SF 1 "register_operand" "f")
414 (match_operand:SF 2 "register_operand" "f")))]
418 return "fcmps\t%0, %1, %2";
419 return "fcmps\t%1, %2";
421 [(set_attr "type" "fpcmp")])
423 (define_insn "*cmpdf_fp"
424 [(set (match_operand:CCFP 0 "fcc_reg_operand" "=c")
425 (compare:CCFP (match_operand:DF 1 "register_operand" "e")
426 (match_operand:DF 2 "register_operand" "e")))]
430 return "fcmpd\t%0, %1, %2";
431 return "fcmpd\t%1, %2";
433 [(set_attr "type" "fpcmp")
434 (set_attr "fptype" "double")])
436 (define_insn "*cmptf_fp"
437 [(set (match_operand:CCFP 0 "fcc_reg_operand" "=c")
438 (compare:CCFP (match_operand:TF 1 "register_operand" "e")
439 (match_operand:TF 2 "register_operand" "e")))]
440 "TARGET_FPU && TARGET_HARD_QUAD"
443 return "fcmpq\t%0, %1, %2";
444 return "fcmpq\t%1, %2";
446 [(set_attr "type" "fpcmp")])
448 ;; Next come the scc insns. For seq, sne, sgeu, and sltu, we can do this
449 ;; without jumps using the addx/subx instructions. For seq/sne on v9 we use
450 ;; the same code as v8 (the addx/subx method has more applications). The
451 ;; exception to this is "reg != 0" which can be done in one instruction on v9
452 ;; (so we do it). For the rest, on v9 we use conditional moves; on v8, we do
455 ;; Seq_special[_xxx] and sne_special[_xxx] clobber the CC reg, because they
456 ;; generate addcc/subcc instructions.
458 (define_expand "seqsi_special"
460 (xor:SI (match_operand:SI 1 "register_operand" "")
461 (match_operand:SI 2 "register_operand" "")))
462 (parallel [(set (match_operand:SI 0 "register_operand" "")
463 (eq:SI (match_dup 3) (const_int 0)))
464 (clobber (reg:CC 100))])]
466 { operands[3] = gen_reg_rtx (SImode); })
468 (define_expand "seqdi_special"
470 (xor:DI (match_operand:DI 1 "register_operand" "")
471 (match_operand:DI 2 "register_operand" "")))
472 (set (match_operand:DI 0 "register_operand" "")
473 (eq:DI (match_dup 3) (const_int 0)))]
475 { operands[3] = gen_reg_rtx (DImode); })
477 (define_expand "snesi_special"
479 (xor:SI (match_operand:SI 1 "register_operand" "")
480 (match_operand:SI 2 "register_operand" "")))
481 (parallel [(set (match_operand:SI 0 "register_operand" "")
482 (ne:SI (match_dup 3) (const_int 0)))
483 (clobber (reg:CC 100))])]
485 { operands[3] = gen_reg_rtx (SImode); })
487 (define_expand "snedi_special"
489 (xor:DI (match_operand:DI 1 "register_operand" "")
490 (match_operand:DI 2 "register_operand" "")))
491 (set (match_operand:DI 0 "register_operand" "")
492 (ne:DI (match_dup 3) (const_int 0)))]
494 { operands[3] = gen_reg_rtx (DImode); })
496 (define_expand "seqdi_special_trunc"
498 (xor:DI (match_operand:DI 1 "register_operand" "")
499 (match_operand:DI 2 "register_operand" "")))
500 (set (match_operand:SI 0 "register_operand" "")
501 (eq:SI (match_dup 3) (const_int 0)))]
503 { operands[3] = gen_reg_rtx (DImode); })
505 (define_expand "snedi_special_trunc"
507 (xor:DI (match_operand:DI 1 "register_operand" "")
508 (match_operand:DI 2 "register_operand" "")))
509 (set (match_operand:SI 0 "register_operand" "")
510 (ne:SI (match_dup 3) (const_int 0)))]
512 { operands[3] = gen_reg_rtx (DImode); })
514 (define_expand "seqsi_special_extend"
516 (xor:SI (match_operand:SI 1 "register_operand" "")
517 (match_operand:SI 2 "register_operand" "")))
518 (parallel [(set (match_operand:DI 0 "register_operand" "")
519 (eq:DI (match_dup 3) (const_int 0)))
520 (clobber (reg:CC 100))])]
522 { operands[3] = gen_reg_rtx (SImode); })
524 (define_expand "snesi_special_extend"
526 (xor:SI (match_operand:SI 1 "register_operand" "")
527 (match_operand:SI 2 "register_operand" "")))
528 (parallel [(set (match_operand:DI 0 "register_operand" "")
529 (ne:DI (match_dup 3) (const_int 0)))
530 (clobber (reg:CC 100))])]
532 { operands[3] = gen_reg_rtx (SImode); })
534 ;; ??? v9: Operand 0 needs a mode, so SImode was chosen.
535 ;; However, the code handles both SImode and DImode.
537 [(set (match_operand:SI 0 "intreg_operand" "")
538 (eq:SI (match_dup 1) (const_int 0)))]
541 if (GET_MODE (sparc_compare_op0) == SImode)
545 if (GET_MODE (operands[0]) == SImode)
546 pat = gen_seqsi_special (operands[0], sparc_compare_op0,
548 else if (! TARGET_ARCH64)
551 pat = gen_seqsi_special_extend (operands[0], sparc_compare_op0,
556 else if (GET_MODE (sparc_compare_op0) == DImode)
562 else if (GET_MODE (operands[0]) == SImode)
563 pat = gen_seqdi_special_trunc (operands[0], sparc_compare_op0,
566 pat = gen_seqdi_special (operands[0], sparc_compare_op0,
571 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
573 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, EQ);
574 emit_jump_insn (gen_sne (operands[0]));
579 if (gen_v9_scc (EQ, operands))
586 ;; ??? v9: Operand 0 needs a mode, so SImode was chosen.
587 ;; However, the code handles both SImode and DImode.
589 [(set (match_operand:SI 0 "intreg_operand" "")
590 (ne:SI (match_dup 1) (const_int 0)))]
593 if (GET_MODE (sparc_compare_op0) == SImode)
597 if (GET_MODE (operands[0]) == SImode)
598 pat = gen_snesi_special (operands[0], sparc_compare_op0,
600 else if (! TARGET_ARCH64)
603 pat = gen_snesi_special_extend (operands[0], sparc_compare_op0,
608 else if (GET_MODE (sparc_compare_op0) == DImode)
614 else if (GET_MODE (operands[0]) == SImode)
615 pat = gen_snedi_special_trunc (operands[0], sparc_compare_op0,
618 pat = gen_snedi_special (operands[0], sparc_compare_op0,
623 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
625 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, NE);
626 emit_jump_insn (gen_sne (operands[0]));
631 if (gen_v9_scc (NE, operands))
639 [(set (match_operand:SI 0 "intreg_operand" "")
640 (gt:SI (match_dup 1) (const_int 0)))]
643 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
645 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GT);
646 emit_jump_insn (gen_sne (operands[0]));
651 if (gen_v9_scc (GT, operands))
659 [(set (match_operand:SI 0 "intreg_operand" "")
660 (lt:SI (match_dup 1) (const_int 0)))]
663 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
665 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LT);
666 emit_jump_insn (gen_sne (operands[0]));
671 if (gen_v9_scc (LT, operands))
679 [(set (match_operand:SI 0 "intreg_operand" "")
680 (ge:SI (match_dup 1) (const_int 0)))]
683 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
685 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GE);
686 emit_jump_insn (gen_sne (operands[0]));
691 if (gen_v9_scc (GE, operands))
699 [(set (match_operand:SI 0 "intreg_operand" "")
700 (le:SI (match_dup 1) (const_int 0)))]
703 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
705 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LE);
706 emit_jump_insn (gen_sne (operands[0]));
711 if (gen_v9_scc (LE, operands))
718 (define_expand "sgtu"
719 [(set (match_operand:SI 0 "intreg_operand" "")
720 (gtu:SI (match_dup 1) (const_int 0)))]
727 /* We can do ltu easily, so if both operands are registers, swap them and
729 if ((GET_CODE (sparc_compare_op0) == REG
730 || GET_CODE (sparc_compare_op0) == SUBREG)
731 && (GET_CODE (sparc_compare_op1) == REG
732 || GET_CODE (sparc_compare_op1) == SUBREG))
734 tem = sparc_compare_op0;
735 sparc_compare_op0 = sparc_compare_op1;
736 sparc_compare_op1 = tem;
737 pat = gen_sltu (operands[0]);
746 if (gen_v9_scc (GTU, operands))
752 (define_expand "sltu"
753 [(set (match_operand:SI 0 "intreg_operand" "")
754 (ltu:SI (match_dup 1) (const_int 0)))]
759 if (gen_v9_scc (LTU, operands))
762 operands[1] = gen_compare_reg (LTU, sparc_compare_op0, sparc_compare_op1);
765 (define_expand "sgeu"
766 [(set (match_operand:SI 0 "intreg_operand" "")
767 (geu:SI (match_dup 1) (const_int 0)))]
772 if (gen_v9_scc (GEU, operands))
775 operands[1] = gen_compare_reg (GEU, sparc_compare_op0, sparc_compare_op1);
778 (define_expand "sleu"
779 [(set (match_operand:SI 0 "intreg_operand" "")
780 (leu:SI (match_dup 1) (const_int 0)))]
787 /* We can do geu easily, so if both operands are registers, swap them and
789 if ((GET_CODE (sparc_compare_op0) == REG
790 || GET_CODE (sparc_compare_op0) == SUBREG)
791 && (GET_CODE (sparc_compare_op1) == REG
792 || GET_CODE (sparc_compare_op1) == SUBREG))
794 tem = sparc_compare_op0;
795 sparc_compare_op0 = sparc_compare_op1;
796 sparc_compare_op1 = tem;
797 pat = gen_sgeu (operands[0]);
806 if (gen_v9_scc (LEU, operands))
812 ;; Now the DEFINE_INSNs for the scc cases.
814 ;; The SEQ and SNE patterns are special because they can be done
815 ;; without any branching and do not involve a COMPARE. We want
816 ;; them to always use the splitz below so the results can be
819 (define_insn_and_split "*snesi_zero"
820 [(set (match_operand:SI 0 "register_operand" "=r")
821 (ne:SI (match_operand:SI 1 "register_operand" "r")
823 (clobber (reg:CC 100))]
827 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
829 (set (match_dup 0) (ltu:SI (reg:CC 100) (const_int 0)))]
831 [(set_attr "length" "2")])
833 (define_insn_and_split "*neg_snesi_zero"
834 [(set (match_operand:SI 0 "register_operand" "=r")
835 (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
837 (clobber (reg:CC 100))]
841 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
843 (set (match_dup 0) (neg:SI (ltu:SI (reg:CC 100) (const_int 0))))]
845 [(set_attr "length" "2")])
847 (define_insn_and_split "*snesi_zero_extend"
848 [(set (match_operand:DI 0 "register_operand" "=r")
849 (ne:DI (match_operand:SI 1 "register_operand" "r")
851 (clobber (reg:CC 100))]
855 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (minus:SI (const_int 0)
858 (set (match_dup 0) (zero_extend:DI (plus:SI (plus:SI (const_int 0)
860 (ltu:SI (reg:CC_NOOV 100)
863 [(set_attr "length" "2")])
865 (define_insn_and_split "*snedi_zero"
866 [(set (match_operand:DI 0 "register_operand" "=&r")
867 (ne:DI (match_operand:DI 1 "register_operand" "r")
871 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
872 [(set (match_dup 0) (const_int 0))
873 (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
878 [(set_attr "length" "2")])
880 (define_insn_and_split "*neg_snedi_zero"
881 [(set (match_operand:DI 0 "register_operand" "=&r")
882 (neg:DI (ne:DI (match_operand:DI 1 "register_operand" "r")
886 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
887 [(set (match_dup 0) (const_int 0))
888 (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
893 [(set_attr "length" "2")])
895 (define_insn_and_split "*snedi_zero_trunc"
896 [(set (match_operand:SI 0 "register_operand" "=&r")
897 (ne:SI (match_operand:DI 1 "register_operand" "r")
901 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
902 [(set (match_dup 0) (const_int 0))
903 (set (match_dup 0) (if_then_else:SI (ne:DI (match_dup 1)
908 [(set_attr "length" "2")])
910 (define_insn_and_split "*seqsi_zero"
911 [(set (match_operand:SI 0 "register_operand" "=r")
912 (eq:SI (match_operand:SI 1 "register_operand" "r")
914 (clobber (reg:CC 100))]
918 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
920 (set (match_dup 0) (geu:SI (reg:CC 100) (const_int 0)))]
922 [(set_attr "length" "2")])
924 (define_insn_and_split "*neg_seqsi_zero"
925 [(set (match_operand:SI 0 "register_operand" "=r")
926 (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
928 (clobber (reg:CC 100))]
932 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
934 (set (match_dup 0) (neg:SI (geu:SI (reg:CC 100) (const_int 0))))]
936 [(set_attr "length" "2")])
938 (define_insn_and_split "*seqsi_zero_extend"
939 [(set (match_operand:DI 0 "register_operand" "=r")
940 (eq:DI (match_operand:SI 1 "register_operand" "r")
942 (clobber (reg:CC 100))]
946 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (minus:SI (const_int 0)
949 (set (match_dup 0) (zero_extend:DI (minus:SI (minus:SI (const_int 0)
951 (ltu:SI (reg:CC_NOOV 100)
954 [(set_attr "length" "2")])
956 (define_insn_and_split "*seqdi_zero"
957 [(set (match_operand:DI 0 "register_operand" "=&r")
958 (eq:DI (match_operand:DI 1 "register_operand" "r")
962 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
963 [(set (match_dup 0) (const_int 0))
964 (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
969 [(set_attr "length" "2")])
971 (define_insn_and_split "*neg_seqdi_zero"
972 [(set (match_operand:DI 0 "register_operand" "=&r")
973 (neg:DI (eq:DI (match_operand:DI 1 "register_operand" "r")
977 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
978 [(set (match_dup 0) (const_int 0))
979 (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
984 [(set_attr "length" "2")])
986 (define_insn_and_split "*seqdi_zero_trunc"
987 [(set (match_operand:SI 0 "register_operand" "=&r")
988 (eq:SI (match_operand:DI 1 "register_operand" "r")
992 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
993 [(set (match_dup 0) (const_int 0))
994 (set (match_dup 0) (if_then_else:SI (eq:DI (match_dup 1)
999 [(set_attr "length" "2")])
1001 ;; We can also do (x + (i == 0)) and related, so put them in.
1002 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1005 (define_insn_and_split "*x_plus_i_ne_0"
1006 [(set (match_operand:SI 0 "register_operand" "=r")
1007 (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
1009 (match_operand:SI 2 "register_operand" "r")))
1010 (clobber (reg:CC 100))]
1014 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1016 (set (match_dup 0) (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1019 [(set_attr "length" "2")])
1021 (define_insn_and_split "*x_minus_i_ne_0"
1022 [(set (match_operand:SI 0 "register_operand" "=r")
1023 (minus:SI (match_operand:SI 2 "register_operand" "r")
1024 (ne:SI (match_operand:SI 1 "register_operand" "r")
1026 (clobber (reg:CC 100))]
1030 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1032 (set (match_dup 0) (minus:SI (match_dup 2)
1033 (ltu:SI (reg:CC 100) (const_int 0))))]
1035 [(set_attr "length" "2")])
1037 (define_insn_and_split "*x_plus_i_eq_0"
1038 [(set (match_operand:SI 0 "register_operand" "=r")
1039 (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
1041 (match_operand:SI 2 "register_operand" "r")))
1042 (clobber (reg:CC 100))]
1046 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1048 (set (match_dup 0) (plus:SI (geu:SI (reg:CC 100) (const_int 0))
1051 [(set_attr "length" "2")])
1053 (define_insn_and_split "*x_minus_i_eq_0"
1054 [(set (match_operand:SI 0 "register_operand" "=r")
1055 (minus:SI (match_operand:SI 2 "register_operand" "r")
1056 (eq:SI (match_operand:SI 1 "register_operand" "r")
1058 (clobber (reg:CC 100))]
1062 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1064 (set (match_dup 0) (minus:SI (match_dup 2)
1065 (geu:SI (reg:CC 100) (const_int 0))))]
1067 [(set_attr "length" "2")])
1069 ;; We can also do GEU and LTU directly, but these operate after a compare.
1070 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1073 (define_insn "*sltu_insn"
1074 [(set (match_operand:SI 0 "register_operand" "=r")
1075 (ltu:SI (reg:CC 100) (const_int 0)))]
1078 [(set_attr "type" "ialuX")])
1080 (define_insn "*neg_sltu_insn"
1081 [(set (match_operand:SI 0 "register_operand" "=r")
1082 (neg:SI (ltu:SI (reg:CC 100) (const_int 0))))]
1085 [(set_attr "type" "ialuX")])
1087 ;; ??? Combine should canonicalize these next two to the same pattern.
1088 (define_insn "*neg_sltu_minus_x"
1089 [(set (match_operand:SI 0 "register_operand" "=r")
1090 (minus:SI (neg:SI (ltu:SI (reg:CC 100) (const_int 0)))
1091 (match_operand:SI 1 "arith_operand" "rI")))]
1093 "subx\t%%g0, %1, %0"
1094 [(set_attr "type" "ialuX")])
1096 (define_insn "*neg_sltu_plus_x"
1097 [(set (match_operand:SI 0 "register_operand" "=r")
1098 (neg:SI (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1099 (match_operand:SI 1 "arith_operand" "rI"))))]
1101 "subx\t%%g0, %1, %0"
1102 [(set_attr "type" "ialuX")])
1104 (define_insn "*sgeu_insn"
1105 [(set (match_operand:SI 0 "register_operand" "=r")
1106 (geu:SI (reg:CC 100) (const_int 0)))]
1108 "subx\t%%g0, -1, %0"
1109 [(set_attr "type" "ialuX")])
1111 (define_insn "*neg_sgeu_insn"
1112 [(set (match_operand:SI 0 "register_operand" "=r")
1113 (neg:SI (geu:SI (reg:CC 100) (const_int 0))))]
1115 "addx\t%%g0, -1, %0"
1116 [(set_attr "type" "ialuX")])
1118 ;; We can also do (x + ((unsigned) i >= 0)) and related, so put them in.
1119 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1122 (define_insn "*sltu_plus_x"
1123 [(set (match_operand:SI 0 "register_operand" "=r")
1124 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1125 (match_operand:SI 1 "arith_operand" "rI")))]
1127 "addx\t%%g0, %1, %0"
1128 [(set_attr "type" "ialuX")])
1130 (define_insn "*sltu_plus_x_plus_y"
1131 [(set (match_operand:SI 0 "register_operand" "=r")
1132 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1133 (plus:SI (match_operand:SI 1 "arith_operand" "%r")
1134 (match_operand:SI 2 "arith_operand" "rI"))))]
1137 [(set_attr "type" "ialuX")])
1139 (define_insn "*x_minus_sltu"
1140 [(set (match_operand:SI 0 "register_operand" "=r")
1141 (minus:SI (match_operand:SI 1 "register_operand" "r")
1142 (ltu:SI (reg:CC 100) (const_int 0))))]
1145 [(set_attr "type" "ialuX")])
1147 ;; ??? Combine should canonicalize these next two to the same pattern.
1148 (define_insn "*x_minus_y_minus_sltu"
1149 [(set (match_operand:SI 0 "register_operand" "=r")
1150 (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
1151 (match_operand:SI 2 "arith_operand" "rI"))
1152 (ltu:SI (reg:CC 100) (const_int 0))))]
1155 [(set_attr "type" "ialuX")])
1157 (define_insn "*x_minus_sltu_plus_y"
1158 [(set (match_operand:SI 0 "register_operand" "=r")
1159 (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
1160 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1161 (match_operand:SI 2 "arith_operand" "rI"))))]
1164 [(set_attr "type" "ialuX")])
1166 (define_insn "*sgeu_plus_x"
1167 [(set (match_operand:SI 0 "register_operand" "=r")
1168 (plus:SI (geu:SI (reg:CC 100) (const_int 0))
1169 (match_operand:SI 1 "register_operand" "r")))]
1172 [(set_attr "type" "ialuX")])
1174 (define_insn "*x_minus_sgeu"
1175 [(set (match_operand:SI 0 "register_operand" "=r")
1176 (minus:SI (match_operand:SI 1 "register_operand" "r")
1177 (geu:SI (reg:CC 100) (const_int 0))))]
1180 [(set_attr "type" "ialuX")])
1183 [(set (match_operand:SI 0 "register_operand" "")
1184 (match_operator:SI 2 "noov_compare_op"
1185 [(match_operand 1 "icc_or_fcc_reg_operand" "")
1187 ;; 32 bit LTU/GEU are better implemented using addx/subx
1188 "TARGET_V9 && REGNO (operands[1]) == SPARC_ICC_REG
1189 && (GET_MODE (operands[1]) == CCXmode
1190 || (GET_CODE (operands[2]) != LTU && GET_CODE (operands[2]) != GEU))"
1191 [(set (match_dup 0) (const_int 0))
1193 (if_then_else:SI (match_op_dup:SI 2 [(match_dup 1) (const_int 0)])
1199 ;; These control RTL generation for conditional jump insns
1201 ;; The quad-word fp compare library routines all return nonzero to indicate
1202 ;; true, which is different from the equivalent libgcc routines, so we must
1203 ;; handle them specially here.
1205 (define_expand "beq"
1207 (if_then_else (eq (match_dup 1) (const_int 0))
1208 (label_ref (match_operand 0 "" ""))
1212 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1213 && GET_CODE (sparc_compare_op0) == REG
1214 && GET_MODE (sparc_compare_op0) == DImode)
1216 emit_v9_brxx_insn (EQ, sparc_compare_op0, operands[0]);
1219 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1221 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, EQ);
1222 emit_jump_insn (gen_bne (operands[0]));
1225 operands[1] = gen_compare_reg (EQ, sparc_compare_op0, sparc_compare_op1);
1228 (define_expand "bne"
1230 (if_then_else (ne (match_dup 1) (const_int 0))
1231 (label_ref (match_operand 0 "" ""))
1235 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1236 && GET_CODE (sparc_compare_op0) == REG
1237 && GET_MODE (sparc_compare_op0) == DImode)
1239 emit_v9_brxx_insn (NE, sparc_compare_op0, operands[0]);
1242 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1244 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, NE);
1245 emit_jump_insn (gen_bne (operands[0]));
1248 operands[1] = gen_compare_reg (NE, sparc_compare_op0, sparc_compare_op1);
1251 (define_expand "bgt"
1253 (if_then_else (gt (match_dup 1) (const_int 0))
1254 (label_ref (match_operand 0 "" ""))
1258 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1259 && GET_CODE (sparc_compare_op0) == REG
1260 && GET_MODE (sparc_compare_op0) == DImode)
1262 emit_v9_brxx_insn (GT, sparc_compare_op0, operands[0]);
1265 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1267 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GT);
1268 emit_jump_insn (gen_bne (operands[0]));
1271 operands[1] = gen_compare_reg (GT, sparc_compare_op0, sparc_compare_op1);
1274 (define_expand "bgtu"
1276 (if_then_else (gtu (match_dup 1) (const_int 0))
1277 (label_ref (match_operand 0 "" ""))
1281 operands[1] = gen_compare_reg (GTU, sparc_compare_op0, sparc_compare_op1);
1284 (define_expand "blt"
1286 (if_then_else (lt (match_dup 1) (const_int 0))
1287 (label_ref (match_operand 0 "" ""))
1291 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1292 && GET_CODE (sparc_compare_op0) == REG
1293 && GET_MODE (sparc_compare_op0) == DImode)
1295 emit_v9_brxx_insn (LT, sparc_compare_op0, operands[0]);
1298 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1300 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LT);
1301 emit_jump_insn (gen_bne (operands[0]));
1304 operands[1] = gen_compare_reg (LT, sparc_compare_op0, sparc_compare_op1);
1307 (define_expand "bltu"
1309 (if_then_else (ltu (match_dup 1) (const_int 0))
1310 (label_ref (match_operand 0 "" ""))
1314 operands[1] = gen_compare_reg (LTU, sparc_compare_op0, sparc_compare_op1);
1317 (define_expand "bge"
1319 (if_then_else (ge (match_dup 1) (const_int 0))
1320 (label_ref (match_operand 0 "" ""))
1324 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1325 && GET_CODE (sparc_compare_op0) == REG
1326 && GET_MODE (sparc_compare_op0) == DImode)
1328 emit_v9_brxx_insn (GE, sparc_compare_op0, operands[0]);
1331 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1333 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GE);
1334 emit_jump_insn (gen_bne (operands[0]));
1337 operands[1] = gen_compare_reg (GE, sparc_compare_op0, sparc_compare_op1);
1340 (define_expand "bgeu"
1342 (if_then_else (geu (match_dup 1) (const_int 0))
1343 (label_ref (match_operand 0 "" ""))
1347 operands[1] = gen_compare_reg (GEU, sparc_compare_op0, sparc_compare_op1);
1350 (define_expand "ble"
1352 (if_then_else (le (match_dup 1) (const_int 0))
1353 (label_ref (match_operand 0 "" ""))
1357 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1358 && GET_CODE (sparc_compare_op0) == REG
1359 && GET_MODE (sparc_compare_op0) == DImode)
1361 emit_v9_brxx_insn (LE, sparc_compare_op0, operands[0]);
1364 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1366 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LE);
1367 emit_jump_insn (gen_bne (operands[0]));
1370 operands[1] = gen_compare_reg (LE, sparc_compare_op0, sparc_compare_op1);
1373 (define_expand "bleu"
1375 (if_then_else (leu (match_dup 1) (const_int 0))
1376 (label_ref (match_operand 0 "" ""))
1380 operands[1] = gen_compare_reg (LEU, sparc_compare_op0, sparc_compare_op1);
1383 (define_expand "bunordered"
1385 (if_then_else (unordered (match_dup 1) (const_int 0))
1386 (label_ref (match_operand 0 "" ""))
1390 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1392 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1,
1394 emit_jump_insn (gen_beq (operands[0]));
1397 operands[1] = gen_compare_reg (UNORDERED, sparc_compare_op0,
1401 (define_expand "bordered"
1403 (if_then_else (ordered (match_dup 1) (const_int 0))
1404 (label_ref (match_operand 0 "" ""))
1408 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1410 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, ORDERED);
1411 emit_jump_insn (gen_bne (operands[0]));
1414 operands[1] = gen_compare_reg (ORDERED, sparc_compare_op0,
1418 (define_expand "bungt"
1420 (if_then_else (ungt (match_dup 1) (const_int 0))
1421 (label_ref (match_operand 0 "" ""))
1425 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1427 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNGT);
1428 emit_jump_insn (gen_bgt (operands[0]));
1431 operands[1] = gen_compare_reg (UNGT, sparc_compare_op0, sparc_compare_op1);
1434 (define_expand "bunlt"
1436 (if_then_else (unlt (match_dup 1) (const_int 0))
1437 (label_ref (match_operand 0 "" ""))
1441 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1443 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNLT);
1444 emit_jump_insn (gen_bne (operands[0]));
1447 operands[1] = gen_compare_reg (UNLT, sparc_compare_op0, sparc_compare_op1);
1450 (define_expand "buneq"
1452 (if_then_else (uneq (match_dup 1) (const_int 0))
1453 (label_ref (match_operand 0 "" ""))
1457 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1459 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNEQ);
1460 emit_jump_insn (gen_beq (operands[0]));
1463 operands[1] = gen_compare_reg (UNEQ, sparc_compare_op0, sparc_compare_op1);
1466 (define_expand "bunge"
1468 (if_then_else (unge (match_dup 1) (const_int 0))
1469 (label_ref (match_operand 0 "" ""))
1473 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1475 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNGE);
1476 emit_jump_insn (gen_bne (operands[0]));
1479 operands[1] = gen_compare_reg (UNGE, sparc_compare_op0, sparc_compare_op1);
1482 (define_expand "bunle"
1484 (if_then_else (unle (match_dup 1) (const_int 0))
1485 (label_ref (match_operand 0 "" ""))
1489 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1491 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNLE);
1492 emit_jump_insn (gen_bne (operands[0]));
1495 operands[1] = gen_compare_reg (UNLE, sparc_compare_op0, sparc_compare_op1);
1498 (define_expand "bltgt"
1500 (if_then_else (ltgt (match_dup 1) (const_int 0))
1501 (label_ref (match_operand 0 "" ""))
1505 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1507 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LTGT);
1508 emit_jump_insn (gen_bne (operands[0]));
1511 operands[1] = gen_compare_reg (LTGT, sparc_compare_op0, sparc_compare_op1);
1514 ;; Now match both normal and inverted jump.
1516 ;; XXX fpcmp nop braindamage
1517 (define_insn "*normal_branch"
1519 (if_then_else (match_operator 0 "noov_compare_op"
1520 [(reg 100) (const_int 0)])
1521 (label_ref (match_operand 1 "" ""))
1525 return output_cbranch (operands[0], operands[1], 1, 0,
1526 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1527 ! final_sequence, insn);
1529 [(set_attr "type" "branch")
1530 (set_attr "branch_type" "icc")])
1532 ;; XXX fpcmp nop braindamage
1533 (define_insn "*inverted_branch"
1535 (if_then_else (match_operator 0 "noov_compare_op"
1536 [(reg 100) (const_int 0)])
1538 (label_ref (match_operand 1 "" ""))))]
1541 return output_cbranch (operands[0], operands[1], 1, 1,
1542 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1543 ! final_sequence, insn);
1545 [(set_attr "type" "branch")
1546 (set_attr "branch_type" "icc")])
1548 ;; XXX fpcmp nop braindamage
1549 (define_insn "*normal_fp_branch"
1551 (if_then_else (match_operator 1 "comparison_operator"
1552 [(match_operand:CCFP 0 "fcc_reg_operand" "c")
1554 (label_ref (match_operand 2 "" ""))
1558 return output_cbranch (operands[1], operands[2], 2, 0,
1559 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1560 ! final_sequence, insn);
1562 [(set_attr "type" "branch")
1563 (set_attr "branch_type" "fcc")])
1565 ;; XXX fpcmp nop braindamage
1566 (define_insn "*inverted_fp_branch"
1568 (if_then_else (match_operator 1 "comparison_operator"
1569 [(match_operand:CCFP 0 "fcc_reg_operand" "c")
1572 (label_ref (match_operand 2 "" ""))))]
1575 return output_cbranch (operands[1], operands[2], 2, 1,
1576 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1577 ! final_sequence, insn);
1579 [(set_attr "type" "branch")
1580 (set_attr "branch_type" "fcc")])
1582 ;; XXX fpcmp nop braindamage
1583 (define_insn "*normal_fpe_branch"
1585 (if_then_else (match_operator 1 "comparison_operator"
1586 [(match_operand:CCFPE 0 "fcc_reg_operand" "c")
1588 (label_ref (match_operand 2 "" ""))
1592 return output_cbranch (operands[1], operands[2], 2, 0,
1593 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1594 ! final_sequence, insn);
1596 [(set_attr "type" "branch")
1597 (set_attr "branch_type" "fcc")])
1599 ;; XXX fpcmp nop braindamage
1600 (define_insn "*inverted_fpe_branch"
1602 (if_then_else (match_operator 1 "comparison_operator"
1603 [(match_operand:CCFPE 0 "fcc_reg_operand" "c")
1606 (label_ref (match_operand 2 "" ""))))]
1609 return output_cbranch (operands[1], operands[2], 2, 1,
1610 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1611 ! final_sequence, insn);
1613 [(set_attr "type" "branch")
1614 (set_attr "branch_type" "fcc")])
1616 ;; SPARC V9-specific jump insns. None of these are guaranteed to be
1617 ;; in the architecture.
1619 ;; There are no 32 bit brreg insns.
1622 (define_insn "*normal_int_branch_sp64"
1624 (if_then_else (match_operator 0 "v9_regcmp_op"
1625 [(match_operand:DI 1 "register_operand" "r")
1627 (label_ref (match_operand 2 "" ""))
1631 return output_v9branch (operands[0], operands[2], 1, 2, 0,
1632 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1633 ! final_sequence, insn);
1635 [(set_attr "type" "branch")
1636 (set_attr "branch_type" "reg")])
1639 (define_insn "*inverted_int_branch_sp64"
1641 (if_then_else (match_operator 0 "v9_regcmp_op"
1642 [(match_operand:DI 1 "register_operand" "r")
1645 (label_ref (match_operand 2 "" ""))))]
1648 return output_v9branch (operands[0], operands[2], 1, 2, 1,
1649 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1650 ! final_sequence, insn);
1652 [(set_attr "type" "branch")
1653 (set_attr "branch_type" "reg")])
1655 ;; Load program counter insns.
1657 (define_insn "get_pc"
1658 [(clobber (reg:SI 15))
1659 (set (match_operand 0 "register_operand" "=r")
1660 (unspec [(match_operand 1 "" "") (match_operand 2 "" "")] UNSPEC_GET_PC))]
1661 "flag_pic && REGNO (operands[0]) == 23"
1662 "sethi\t%%hi(%a1-4), %0\n\tcall\t%a2\n\tadd\t%0, %%lo(%a1+4), %0"
1663 [(set_attr "type" "multi")
1664 (set_attr "length" "3")])
1667 ;; Move instructions
1669 (define_expand "movqi"
1670 [(set (match_operand:QI 0 "general_operand" "")
1671 (match_operand:QI 1 "general_operand" ""))]
1674 /* Working with CONST_INTs is easier, so convert
1675 a double if needed. */
1676 if (GET_CODE (operands[1]) == CONST_DOUBLE)
1678 operands[1] = GEN_INT (trunc_int_for_mode
1679 (CONST_DOUBLE_LOW (operands[1]), QImode));
1682 /* Handle sets of MEM first. */
1683 if (GET_CODE (operands[0]) == MEM)
1685 if (reg_or_0_operand (operands[1], QImode))
1688 if (! reload_in_progress)
1690 operands[0] = validize_mem (operands[0]);
1691 operands[1] = force_reg (QImode, operands[1]);
1695 /* Fixup TLS cases. */
1696 if (tls_symbolic_operand (operands [1]))
1697 operands[1] = legitimize_tls_address (operands[1]);
1699 /* Fixup PIC cases. */
1702 if (CONSTANT_P (operands[1])
1703 && pic_address_needs_scratch (operands[1]))
1704 operands[1] = legitimize_pic_address (operands[1], QImode, 0);
1706 if (symbolic_operand (operands[1], QImode))
1708 operands[1] = legitimize_pic_address (operands[1],
1710 (reload_in_progress ?
1717 /* All QI constants require only one insn, so proceed. */
1723 (define_insn "*movqi_insn"
1724 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m")
1725 (match_operand:QI 1 "input_operand" "rI,m,rJ"))]
1726 "(register_operand (operands[0], QImode)
1727 || reg_or_0_operand (operands[1], QImode))"
1732 [(set_attr "type" "*,load,store")
1733 (set_attr "us3load_type" "*,3cycle,*")])
1735 (define_expand "movhi"
1736 [(set (match_operand:HI 0 "general_operand" "")
1737 (match_operand:HI 1 "general_operand" ""))]
1740 /* Working with CONST_INTs is easier, so convert
1741 a double if needed. */
1742 if (GET_CODE (operands[1]) == CONST_DOUBLE)
1743 operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
1745 /* Handle sets of MEM first. */
1746 if (GET_CODE (operands[0]) == MEM)
1748 if (reg_or_0_operand (operands[1], HImode))
1751 if (! reload_in_progress)
1753 operands[0] = validize_mem (operands[0]);
1754 operands[1] = force_reg (HImode, operands[1]);
1758 /* Fixup TLS cases. */
1759 if (tls_symbolic_operand (operands [1]))
1760 operands[1] = legitimize_tls_address (operands[1]);
1762 /* Fixup PIC cases. */
1765 if (CONSTANT_P (operands[1])
1766 && pic_address_needs_scratch (operands[1]))
1767 operands[1] = legitimize_pic_address (operands[1], HImode, 0);
1769 if (symbolic_operand (operands[1], HImode))
1771 operands[1] = legitimize_pic_address (operands[1],
1773 (reload_in_progress ?
1780 /* This makes sure we will not get rematched due to splittage. */
1781 if (! CONSTANT_P (operands[1]) || input_operand (operands[1], HImode))
1783 else if (CONSTANT_P (operands[1])
1784 && GET_CODE (operands[1]) != HIGH
1785 && GET_CODE (operands[1]) != LO_SUM)
1787 sparc_emit_set_const32 (operands[0], operands[1]);
1794 (define_insn "*movhi_const64_special"
1795 [(set (match_operand:HI 0 "register_operand" "=r")
1796 (match_operand:HI 1 "const64_high_operand" ""))]
1798 "sethi\t%%hi(%a1), %0")
1800 (define_insn "*movhi_insn"
1801 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1802 (match_operand:HI 1 "input_operand" "rI,K,m,rJ"))]
1803 "(register_operand (operands[0], HImode)
1804 || reg_or_0_operand (operands[1], HImode))"
1807 sethi\t%%hi(%a1), %0
1810 [(set_attr "type" "*,*,load,store")
1811 (set_attr "us3load_type" "*,*,3cycle,*")])
1813 ;; We always work with constants here.
1814 (define_insn "*movhi_lo_sum"
1815 [(set (match_operand:HI 0 "register_operand" "=r")
1816 (ior:HI (match_operand:HI 1 "arith_operand" "%r")
1817 (match_operand:HI 2 "arith_operand" "I")))]
1821 (define_expand "movsi"
1822 [(set (match_operand:SI 0 "general_operand" "")
1823 (match_operand:SI 1 "general_operand" ""))]
1826 /* Working with CONST_INTs is easier, so convert
1827 a double if needed. */
1828 if (GET_CODE (operands[1]) == CONST_DOUBLE)
1829 operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
1831 /* Handle sets of MEM first. */
1832 if (GET_CODE (operands[0]) == MEM)
1834 if (reg_or_0_operand (operands[1], SImode))
1837 if (! reload_in_progress)
1839 operands[0] = validize_mem (operands[0]);
1840 operands[1] = force_reg (SImode, operands[1]);
1844 /* Fixup TLS cases. */
1845 if (tls_symbolic_operand (operands [1]))
1846 operands[1] = legitimize_tls_address (operands[1]);
1848 /* Fixup PIC cases. */
1851 if (CONSTANT_P (operands[1])
1852 && pic_address_needs_scratch (operands[1]))
1853 operands[1] = legitimize_pic_address (operands[1], SImode, 0);
1855 if (GET_CODE (operands[1]) == LABEL_REF)
1858 emit_insn (gen_movsi_pic_label_ref (operands[0], operands[1]));
1862 if (symbolic_operand (operands[1], SImode))
1864 operands[1] = legitimize_pic_address (operands[1],
1866 (reload_in_progress ?
1873 /* If we are trying to toss an integer constant into the
1874 FPU registers, force it into memory. */
1875 if (GET_CODE (operands[0]) == REG
1876 && REGNO (operands[0]) >= SPARC_FIRST_FP_REG
1877 && REGNO (operands[0]) <= SPARC_LAST_V9_FP_REG
1878 && CONSTANT_P (operands[1]))
1879 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
1882 /* This makes sure we will not get rematched due to splittage. */
1883 if (! CONSTANT_P (operands[1]) || input_operand (operands[1], SImode))
1885 else if (CONSTANT_P (operands[1])
1886 && GET_CODE (operands[1]) != HIGH
1887 && GET_CODE (operands[1]) != LO_SUM)
1889 sparc_emit_set_const32 (operands[0], operands[1]);
1896 ;; This is needed to show CSE exactly which bits are set
1897 ;; in a 64-bit register by sethi instructions.
1898 (define_insn "*movsi_const64_special"
1899 [(set (match_operand:SI 0 "register_operand" "=r")
1900 (match_operand:SI 1 "const64_high_operand" ""))]
1902 "sethi\t%%hi(%a1), %0")
1904 (define_insn "*movsi_insn"
1905 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,f,r,r,r,f,m,m,d")
1906 (match_operand:SI 1 "input_operand" "rI,!f,K,J,m,!m,rJ,!f,J"))]
1907 "(register_operand (operands[0], SImode)
1908 || reg_or_0_operand (operands[1], SImode))"
1912 sethi\t%%hi(%a1), %0
1919 [(set_attr "type" "*,fpmove,*,*,load,fpload,store,fpstore,fpmove")])
1921 (define_insn "*movsi_lo_sum"
1922 [(set (match_operand:SI 0 "register_operand" "=r")
1923 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1924 (match_operand:SI 2 "immediate_operand" "in")))]
1926 "or\t%1, %%lo(%a2), %0")
1928 (define_insn "*movsi_high"
1929 [(set (match_operand:SI 0 "register_operand" "=r")
1930 (high:SI (match_operand:SI 1 "immediate_operand" "in")))]
1932 "sethi\t%%hi(%a1), %0")
1934 ;; The next two patterns must wrap the SYMBOL_REF in an UNSPEC
1935 ;; so that CSE won't optimize the address computation away.
1936 (define_insn "movsi_lo_sum_pic"
1937 [(set (match_operand:SI 0 "register_operand" "=r")
1938 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1939 (unspec:SI [(match_operand:SI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
1941 "or\t%1, %%lo(%a2), %0")
1943 (define_insn "movsi_high_pic"
1944 [(set (match_operand:SI 0 "register_operand" "=r")
1945 (high:SI (unspec:SI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
1946 "flag_pic && check_pic (1)"
1947 "sethi\t%%hi(%a1), %0")
1949 (define_expand "movsi_pic_label_ref"
1950 [(set (match_dup 3) (high:SI
1951 (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
1952 (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1953 (set (match_dup 4) (lo_sum:SI (match_dup 3)
1954 (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1955 (set (match_operand:SI 0 "register_operand" "=r")
1956 (minus:SI (match_dup 5) (match_dup 4)))]
1959 current_function_uses_pic_offset_table = 1;
1960 operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
1963 operands[3] = operands[0];
1964 operands[4] = operands[0];
1968 operands[3] = gen_reg_rtx (SImode);
1969 operands[4] = gen_reg_rtx (SImode);
1971 operands[5] = pic_offset_table_rtx;
1974 (define_insn "*movsi_high_pic_label_ref"
1975 [(set (match_operand:SI 0 "register_operand" "=r")
1977 (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
1978 (match_operand:SI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1980 "sethi\t%%hi(%a2-(%a1-.)), %0")
1982 (define_insn "*movsi_lo_sum_pic_label_ref"
1983 [(set (match_operand:SI 0 "register_operand" "=r")
1984 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1985 (unspec:SI [(match_operand:SI 2 "label_ref_operand" "")
1986 (match_operand:SI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1988 "or\t%1, %%lo(%a3-(%a2-.)), %0")
1990 (define_expand "movdi"
1991 [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand" "")
1992 (match_operand:DI 1 "general_operand" ""))]
1995 /* Where possible, convert CONST_DOUBLE into a CONST_INT. */
1996 if (GET_CODE (operands[1]) == CONST_DOUBLE
1997 #if HOST_BITS_PER_WIDE_INT == 32
1998 && ((CONST_DOUBLE_HIGH (operands[1]) == 0
1999 && (CONST_DOUBLE_LOW (operands[1]) & 0x80000000) == 0)
2000 || (CONST_DOUBLE_HIGH (operands[1]) == (HOST_WIDE_INT) 0xffffffff
2001 && (CONST_DOUBLE_LOW (operands[1]) & 0x80000000) != 0))
2004 operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
2006 /* Handle MEM cases first. */
2007 if (GET_CODE (operands[0]) == MEM)
2009 /* If it's a REG, we can always do it.
2010 The const zero case is more complex, on v9
2011 we can always perform it. */
2012 if (register_operand (operands[1], DImode)
2014 && (operands[1] == const0_rtx)))
2017 if (! reload_in_progress)
2019 operands[0] = validize_mem (operands[0]);
2020 operands[1] = force_reg (DImode, operands[1]);
2024 /* Fixup TLS cases. */
2025 if (tls_symbolic_operand (operands [1]))
2026 operands[1] = legitimize_tls_address (operands[1]);
2030 if (CONSTANT_P (operands[1])
2031 && pic_address_needs_scratch (operands[1]))
2032 operands[1] = legitimize_pic_address (operands[1], DImode, 0);
2034 if (GET_CODE (operands[1]) == LABEL_REF)
2036 if (! TARGET_ARCH64)
2038 emit_insn (gen_movdi_pic_label_ref (operands[0], operands[1]));
2042 if (symbolic_operand (operands[1], DImode))
2044 operands[1] = legitimize_pic_address (operands[1],
2046 (reload_in_progress ?
2053 /* If we are trying to toss an integer constant into the
2054 FPU registers, force it into memory. */
2055 if (GET_CODE (operands[0]) == REG
2056 && REGNO (operands[0]) >= SPARC_FIRST_FP_REG
2057 && REGNO (operands[0]) <= SPARC_LAST_V9_FP_REG
2058 && CONSTANT_P (operands[1]))
2059 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
2062 /* This makes sure we will not get rematched due to splittage. */
2063 if (! CONSTANT_P (operands[1]) || input_operand (operands[1], DImode))
2065 else if (TARGET_ARCH64
2066 && CONSTANT_P (operands[1])
2067 && GET_CODE (operands[1]) != HIGH
2068 && GET_CODE (operands[1]) != LO_SUM)
2070 sparc_emit_set_const64 (operands[0], operands[1]);
2078 ;; Be careful, fmovd does not exist when !v9.
2079 ;; We match MEM moves directly when we have correct even
2080 ;; numbered registers, but fall into splits otherwise.
2081 ;; The constraint ordering here is really important to
2082 ;; avoid insane problems in reload, especially for patterns
2085 ;; (set (mem:DI (plus:SI (reg:SI 30 %fp)
2086 ;; (const_int -5016)))
2090 (define_insn "*movdi_insn_sp32_v9"
2091 [(set (match_operand:DI 0 "nonimmediate_operand"
2092 "=T,o,T,U,o,r,r,r,?T,?f,?f,?o,?e,?e,?W")
2093 (match_operand:DI 1 "input_operand"
2094 " J,J,U,T,r,o,i,r, f, T, o, f, e, W, e"))]
2095 "! TARGET_ARCH64 && TARGET_V9
2096 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2113 [(set_attr "type" "store,store,store,load,*,*,*,*,fpstore,fpload,*,*,fpmove,fpload,fpstore")
2114 (set_attr "length" "*,2,*,*,2,2,2,2,*,*,2,2,*,*,*")
2115 (set_attr "fptype" "*,*,*,*,*,*,*,*,*,*,*,*,double,*,*")])
2117 (define_insn "*movdi_insn_sp32"
2118 [(set (match_operand:DI 0 "nonimmediate_operand"
2119 "=o,T,U,o,r,r,r,?T,?f,?f,?o,?f")
2120 (match_operand:DI 1 "input_operand"
2121 " J,U,T,r,o,i,r, f, T, o, f, f"))]
2123 && (register_operand (operands[0], DImode)
2124 || register_operand (operands[1], DImode))"
2138 [(set_attr "type" "store,store,load,*,*,*,*,fpstore,fpload,*,*,*")
2139 (set_attr "length" "2,*,*,2,2,2,2,*,*,2,2,2")])
2141 ;; The following are generated by sparc_emit_set_const64
2142 (define_insn "*movdi_sp64_dbl"
2143 [(set (match_operand:DI 0 "register_operand" "=r")
2144 (match_operand:DI 1 "const64_operand" ""))]
2146 && HOST_BITS_PER_WIDE_INT != 64)"
2149 ;; This is needed to show CSE exactly which bits are set
2150 ;; in a 64-bit register by sethi instructions.
2151 (define_insn "*movdi_const64_special"
2152 [(set (match_operand:DI 0 "register_operand" "=r")
2153 (match_operand:DI 1 "const64_high_operand" ""))]
2155 "sethi\t%%hi(%a1), %0")
2157 (define_insn "*movdi_insn_sp64_novis"
2158 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,m,?e,?e,?W")
2159 (match_operand:DI 1 "input_operand" "rI,N,J,m,rJ,e,W,e"))]
2160 "TARGET_ARCH64 && ! TARGET_VIS
2161 && (register_operand (operands[0], DImode)
2162 || reg_or_0_operand (operands[1], DImode))"
2165 sethi\t%%hi(%a1), %0
2172 [(set_attr "type" "*,*,*,load,store,fpmove,fpload,fpstore")
2173 (set_attr "fptype" "*,*,*,*,*,double,*,*")])
2175 (define_insn "*movdi_insn_sp64_vis"
2176 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,m,?e,?e,?W,b")
2177 (match_operand:DI 1 "input_operand" "rI,N,J,m,rJ,e,W,e,J"))]
2178 "TARGET_ARCH64 && TARGET_VIS &&
2179 (register_operand (operands[0], DImode)
2180 || reg_or_0_operand (operands[1], DImode))"
2183 sethi\t%%hi(%a1), %0
2191 [(set_attr "type" "*,*,*,load,store,fpmove,fpload,fpstore,fpmove")
2192 (set_attr "fptype" "*,*,*,*,*,double,*,*,double")])
2194 (define_expand "movdi_pic_label_ref"
2195 [(set (match_dup 3) (high:DI
2196 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
2197 (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
2198 (set (match_dup 4) (lo_sum:DI (match_dup 3)
2199 (unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
2200 (set (match_operand:DI 0 "register_operand" "=r")
2201 (minus:DI (match_dup 5) (match_dup 4)))]
2202 "TARGET_ARCH64 && flag_pic"
2204 current_function_uses_pic_offset_table = 1;
2205 operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
2208 operands[3] = operands[0];
2209 operands[4] = operands[0];
2213 operands[3] = gen_reg_rtx (DImode);
2214 operands[4] = gen_reg_rtx (DImode);
2216 operands[5] = pic_offset_table_rtx;
2219 (define_insn "*movdi_high_pic_label_ref"
2220 [(set (match_operand:DI 0 "register_operand" "=r")
2222 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
2223 (match_operand:DI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
2224 "TARGET_ARCH64 && flag_pic"
2225 "sethi\t%%hi(%a2-(%a1-.)), %0")
2227 (define_insn "*movdi_lo_sum_pic_label_ref"
2228 [(set (match_operand:DI 0 "register_operand" "=r")
2229 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2230 (unspec:DI [(match_operand:DI 2 "label_ref_operand" "")
2231 (match_operand:DI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
2232 "TARGET_ARCH64 && flag_pic"
2233 "or\t%1, %%lo(%a3-(%a2-.)), %0")
2235 ;; SPARC-v9 code model support insns. See sparc_emit_set_symbolic_const64
2236 ;; in sparc.c to see what is going on here... PIC stuff comes first.
2238 (define_insn "movdi_lo_sum_pic"
2239 [(set (match_operand:DI 0 "register_operand" "=r")
2240 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2241 (unspec:DI [(match_operand:DI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
2242 "TARGET_ARCH64 && flag_pic"
2243 "or\t%1, %%lo(%a2), %0")
2245 (define_insn "movdi_high_pic"
2246 [(set (match_operand:DI 0 "register_operand" "=r")
2247 (high:DI (unspec:DI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
2248 "TARGET_ARCH64 && flag_pic && check_pic (1)"
2249 "sethi\t%%hi(%a1), %0")
2251 (define_insn "*sethi_di_medlow_embmedany_pic"
2252 [(set (match_operand:DI 0 "register_operand" "=r")
2253 (high:DI (match_operand:DI 1 "sp64_medium_pic_operand" "")))]
2254 "(TARGET_CM_MEDLOW || TARGET_CM_EMBMEDANY) && check_pic (1)"
2255 "sethi\t%%hi(%a1), %0")
2257 (define_insn "*sethi_di_medlow"
2258 [(set (match_operand:DI 0 "register_operand" "=r")
2259 (high:DI (match_operand:DI 1 "symbolic_operand" "")))]
2260 "TARGET_CM_MEDLOW && check_pic (1)"
2261 "sethi\t%%hi(%a1), %0")
2263 (define_insn "*losum_di_medlow"
2264 [(set (match_operand:DI 0 "register_operand" "=r")
2265 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2266 (match_operand:DI 2 "symbolic_operand" "")))]
2268 "or\t%1, %%lo(%a2), %0")
2270 (define_insn "seth44"
2271 [(set (match_operand:DI 0 "register_operand" "=r")
2272 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETH44)))]
2274 "sethi\t%%h44(%a1), %0")
2276 (define_insn "setm44"
2277 [(set (match_operand:DI 0 "register_operand" "=r")
2278 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2279 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_SETM44)))]
2281 "or\t%1, %%m44(%a2), %0")
2283 (define_insn "setl44"
2284 [(set (match_operand:DI 0 "register_operand" "=r")
2285 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2286 (match_operand:DI 2 "symbolic_operand" "")))]
2288 "or\t%1, %%l44(%a2), %0")
2290 (define_insn "sethh"
2291 [(set (match_operand:DI 0 "register_operand" "=r")
2292 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETHH)))]
2294 "sethi\t%%hh(%a1), %0")
2296 (define_insn "setlm"
2297 [(set (match_operand:DI 0 "register_operand" "=r")
2298 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETLM)))]
2300 "sethi\t%%lm(%a1), %0")
2302 (define_insn "sethm"
2303 [(set (match_operand:DI 0 "register_operand" "=r")
2304 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2305 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_EMB_SETHM)))]
2307 "or\t%1, %%hm(%a2), %0")
2309 (define_insn "setlo"
2310 [(set (match_operand:DI 0 "register_operand" "=r")
2311 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2312 (match_operand:DI 2 "symbolic_operand" "")))]
2314 "or\t%1, %%lo(%a2), %0")
2316 (define_insn "embmedany_sethi"
2317 [(set (match_operand:DI 0 "register_operand" "=r")
2318 (high:DI (unspec:DI [(match_operand:DI 1 "data_segment_operand" "")] UNSPEC_EMB_HISUM)))]
2319 "TARGET_CM_EMBMEDANY && check_pic (1)"
2320 "sethi\t%%hi(%a1), %0")
2322 (define_insn "embmedany_losum"
2323 [(set (match_operand:DI 0 "register_operand" "=r")
2324 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2325 (match_operand:DI 2 "data_segment_operand" "")))]
2326 "TARGET_CM_EMBMEDANY"
2327 "add\t%1, %%lo(%a2), %0")
2329 (define_insn "embmedany_brsum"
2330 [(set (match_operand:DI 0 "register_operand" "=r")
2331 (unspec:DI [(match_operand:DI 1 "register_operand" "r")] UNSPEC_EMB_HISUM))]
2332 "TARGET_CM_EMBMEDANY"
2335 (define_insn "embmedany_textuhi"
2336 [(set (match_operand:DI 0 "register_operand" "=r")
2337 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTUHI)))]
2338 "TARGET_CM_EMBMEDANY && check_pic (1)"
2339 "sethi\t%%uhi(%a1), %0")
2341 (define_insn "embmedany_texthi"
2342 [(set (match_operand:DI 0 "register_operand" "=r")
2343 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTHI)))]
2344 "TARGET_CM_EMBMEDANY && check_pic (1)"
2345 "sethi\t%%hi(%a1), %0")
2347 (define_insn "embmedany_textulo"
2348 [(set (match_operand:DI 0 "register_operand" "=r")
2349 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2350 (unspec:DI [(match_operand:DI 2 "text_segment_operand" "")] UNSPEC_EMB_TEXTULO)))]
2351 "TARGET_CM_EMBMEDANY"
2352 "or\t%1, %%ulo(%a2), %0")
2354 (define_insn "embmedany_textlo"
2355 [(set (match_operand:DI 0 "register_operand" "=r")
2356 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2357 (match_operand:DI 2 "text_segment_operand" "")))]
2358 "TARGET_CM_EMBMEDANY"
2359 "or\t%1, %%lo(%a2), %0")
2361 ;; Now some patterns to help reload out a bit.
2362 (define_expand "reload_indi"
2363 [(parallel [(match_operand:DI 0 "register_operand" "=r")
2364 (match_operand:DI 1 "immediate_operand" "")
2365 (match_operand:TI 2 "register_operand" "=&r")])]
2367 || TARGET_CM_EMBMEDANY)
2370 sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
2374 (define_expand "reload_outdi"
2375 [(parallel [(match_operand:DI 0 "register_operand" "=r")
2376 (match_operand:DI 1 "immediate_operand" "")
2377 (match_operand:TI 2 "register_operand" "=&r")])]
2379 || TARGET_CM_EMBMEDANY)
2382 sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
2386 ;; Split up putting CONSTs and REGs into DI regs when !arch64
2388 [(set (match_operand:DI 0 "register_operand" "")
2389 (match_operand:DI 1 "const_int_operand" ""))]
2390 "! TARGET_ARCH64 && reload_completed"
2391 [(clobber (const_int 0))]
2393 #if HOST_BITS_PER_WIDE_INT == 32
2394 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
2395 (INTVAL (operands[1]) < 0) ?
2398 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2401 unsigned int low, high;
2403 low = trunc_int_for_mode (INTVAL (operands[1]), SImode);
2404 high = trunc_int_for_mode (INTVAL (operands[1]) >> 32, SImode);
2405 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), GEN_INT (high)));
2407 /* Slick... but this trick loses if this subreg constant part
2408 can be done in one insn. */
2409 if (low == high && (low & 0x3ff) != 0 && low + 0x1000 >= 0x2000)
2410 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2411 gen_highpart (SImode, operands[0])));
2413 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), GEN_INT (low)));
2419 [(set (match_operand:DI 0 "register_operand" "")
2420 (match_operand:DI 1 "const_double_operand" ""))]
2424 && ((GET_CODE (operands[0]) == REG
2425 && REGNO (operands[0]) < 32)
2426 || (GET_CODE (operands[0]) == SUBREG
2427 && GET_CODE (SUBREG_REG (operands[0])) == REG
2428 && REGNO (SUBREG_REG (operands[0])) < 32))))"
2429 [(clobber (const_int 0))]
2431 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
2432 GEN_INT (CONST_DOUBLE_HIGH (operands[1]))));
2434 /* Slick... but this trick loses if this subreg constant part
2435 can be done in one insn. */
2436 if (CONST_DOUBLE_LOW (operands[1]) == CONST_DOUBLE_HIGH (operands[1])
2437 && !(SPARC_SETHI32_P (CONST_DOUBLE_HIGH (operands[1]))
2438 || SPARC_SIMM13_P (CONST_DOUBLE_HIGH (operands[1]))))
2440 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2441 gen_highpart (SImode, operands[0])));
2445 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2446 GEN_INT (CONST_DOUBLE_LOW (operands[1]))));
2452 [(set (match_operand:DI 0 "register_operand" "")
2453 (match_operand:DI 1 "register_operand" ""))]
2457 && ((GET_CODE (operands[0]) == REG
2458 && REGNO (operands[0]) < 32)
2459 || (GET_CODE (operands[0]) == SUBREG
2460 && GET_CODE (SUBREG_REG (operands[0])) == REG
2461 && REGNO (SUBREG_REG (operands[0])) < 32))))"
2462 [(clobber (const_int 0))]
2464 rtx set_dest = operands[0];
2465 rtx set_src = operands[1];
2469 dest1 = gen_highpart (SImode, set_dest);
2470 dest2 = gen_lowpart (SImode, set_dest);
2471 src1 = gen_highpart (SImode, set_src);
2472 src2 = gen_lowpart (SImode, set_src);
2474 /* Now emit using the real source and destination we found, swapping
2475 the order if we detect overlap. */
2476 if (reg_overlap_mentioned_p (dest1, src2))
2478 emit_insn (gen_movsi (dest2, src2));
2479 emit_insn (gen_movsi (dest1, src1));
2483 emit_insn (gen_movsi (dest1, src1));
2484 emit_insn (gen_movsi (dest2, src2));
2489 ;; Now handle the cases of memory moves from/to non-even
2490 ;; DI mode register pairs.
2492 [(set (match_operand:DI 0 "register_operand" "")
2493 (match_operand:DI 1 "memory_operand" ""))]
2496 && sparc_splitdi_legitimate (operands[0], operands[1]))"
2497 [(clobber (const_int 0))]
2499 rtx word0 = adjust_address (operands[1], SImode, 0);
2500 rtx word1 = adjust_address (operands[1], SImode, 4);
2501 rtx high_part = gen_highpart (SImode, operands[0]);
2502 rtx low_part = gen_lowpart (SImode, operands[0]);
2504 if (reg_overlap_mentioned_p (high_part, word1))
2506 emit_insn (gen_movsi (low_part, word1));
2507 emit_insn (gen_movsi (high_part, word0));
2511 emit_insn (gen_movsi (high_part, word0));
2512 emit_insn (gen_movsi (low_part, word1));
2518 [(set (match_operand:DI 0 "memory_operand" "")
2519 (match_operand:DI 1 "register_operand" ""))]
2522 && sparc_splitdi_legitimate (operands[1], operands[0]))"
2523 [(clobber (const_int 0))]
2525 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0),
2526 gen_highpart (SImode, operands[1])));
2527 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4),
2528 gen_lowpart (SImode, operands[1])));
2533 [(set (match_operand:DI 0 "memory_operand" "")
2538 && ! mem_min_alignment (operands[0], 8)))
2539 && offsettable_memref_p (operands[0])"
2540 [(clobber (const_int 0))]
2542 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0), const0_rtx));
2543 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4), const0_rtx));
2547 ;; Floating point move insns
2549 (define_insn "*movsf_insn_novis"
2550 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,*r,*r,*r,*r,*r,f,m,m")
2551 (match_operand:SF 1 "input_operand" "f,G,Q,*rR,S,m,m,f,*rG"))]
2552 "(TARGET_FPU && ! TARGET_VIS)
2553 && (register_operand (operands[0], SFmode)
2554 || register_operand (operands[1], SFmode)
2555 || fp_zero_operand (operands[1], SFmode))"
2557 if (GET_CODE (operands[1]) == CONST_DOUBLE
2558 && (which_alternative == 2
2559 || which_alternative == 3
2560 || which_alternative == 4))
2565 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2566 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2567 operands[1] = GEN_INT (i);
2570 switch (which_alternative)
2573 return "fmovs\t%1, %0";
2577 return "sethi\t%%hi(%a1), %0";
2579 return "mov\t%1, %0";
2584 return "ld\t%1, %0";
2587 return "st\t%r1, %0";
2592 [(set_attr "type" "fpmove,*,*,*,*,load,fpload,fpstore,store")])
2594 (define_insn "*movsf_insn_vis"
2595 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,*r,*r,*r,*r,*r,f,m,m")
2596 (match_operand:SF 1 "input_operand" "f,G,G,Q,*rR,S,m,m,f,*rG"))]
2597 "(TARGET_FPU && TARGET_VIS)
2598 && (register_operand (operands[0], SFmode)
2599 || register_operand (operands[1], SFmode)
2600 || fp_zero_operand (operands[1], SFmode))"
2602 if (GET_CODE (operands[1]) == CONST_DOUBLE
2603 && (which_alternative == 3
2604 || which_alternative == 4
2605 || which_alternative == 5))
2610 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2611 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2612 operands[1] = GEN_INT (i);
2615 switch (which_alternative)
2618 return "fmovs\t%1, %0";
2620 return "fzeros\t%0";
2624 return "sethi\t%%hi(%a1), %0";
2626 return "mov\t%1, %0";
2631 return "ld\t%1, %0";
2634 return "st\t%r1, %0";
2639 [(set_attr "type" "fpmove,fpmove,*,*,*,*,load,fpload,fpstore,store")])
2641 ;; Exactly the same as above, except that all `f' cases are deleted.
2642 ;; This is necessary to prevent reload from ever trying to use a `f' reg
2645 (define_insn "*movsf_no_f_insn"
2646 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r,r,r,m")
2647 (match_operand:SF 1 "input_operand" "G,Q,rR,S,m,rG"))]
2649 && (register_operand (operands[0], SFmode)
2650 || register_operand (operands[1], SFmode)
2651 || fp_zero_operand (operands[1], SFmode))"
2653 if (GET_CODE (operands[1]) == CONST_DOUBLE
2654 && (which_alternative == 1
2655 || which_alternative == 2
2656 || which_alternative == 3))
2661 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2662 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2663 operands[1] = GEN_INT (i);
2666 switch (which_alternative)
2671 return "sethi\t%%hi(%a1), %0";
2673 return "mov\t%1, %0";
2677 return "ld\t%1, %0";
2679 return "st\t%r1, %0";
2684 [(set_attr "type" "*,*,*,*,load,store")])
2686 (define_insn "*movsf_lo_sum"
2687 [(set (match_operand:SF 0 "register_operand" "=r")
2688 (lo_sum:SF (match_operand:SF 1 "register_operand" "r")
2689 (match_operand:SF 2 "const_double_operand" "S")))]
2690 "fp_high_losum_p (operands[2])"
2695 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[2]);
2696 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2697 operands[2] = GEN_INT (i);
2698 return "or\t%1, %%lo(%a2), %0";
2701 (define_insn "*movsf_high"
2702 [(set (match_operand:SF 0 "register_operand" "=r")
2703 (high:SF (match_operand:SF 1 "const_double_operand" "S")))]
2704 "fp_high_losum_p (operands[1])"
2709 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2710 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2711 operands[1] = GEN_INT (i);
2712 return "sethi\t%%hi(%1), %0";
2716 [(set (match_operand:SF 0 "register_operand" "")
2717 (match_operand:SF 1 "const_double_operand" ""))]
2718 "fp_high_losum_p (operands[1])
2719 && (GET_CODE (operands[0]) == REG
2720 && REGNO (operands[0]) < 32)"
2721 [(set (match_dup 0) (high:SF (match_dup 1)))
2722 (set (match_dup 0) (lo_sum:SF (match_dup 0) (match_dup 1)))])
2724 (define_expand "movsf"
2725 [(set (match_operand:SF 0 "general_operand" "")
2726 (match_operand:SF 1 "general_operand" ""))]
2729 /* Force SFmode constants into memory. */
2730 if (GET_CODE (operands[0]) == REG
2731 && CONSTANT_P (operands[1]))
2733 /* emit_group_store will send such bogosity to us when it is
2734 not storing directly into memory. So fix this up to avoid
2735 crashes in output_constant_pool. */
2736 if (operands [1] == const0_rtx)
2737 operands[1] = CONST0_RTX (SFmode);
2739 if (TARGET_VIS && fp_zero_operand (operands[1], SFmode))
2742 /* We are able to build any SF constant in integer registers
2743 with at most 2 instructions. */
2744 if (REGNO (operands[0]) < 32)
2747 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
2751 /* Handle sets of MEM first. */
2752 if (GET_CODE (operands[0]) == MEM)
2754 if (register_operand (operands[1], SFmode)
2755 || fp_zero_operand (operands[1], SFmode))
2758 if (! reload_in_progress)
2760 operands[0] = validize_mem (operands[0]);
2761 operands[1] = force_reg (SFmode, operands[1]);
2765 /* Fixup PIC cases. */
2768 if (CONSTANT_P (operands[1])
2769 && pic_address_needs_scratch (operands[1]))
2770 operands[1] = legitimize_pic_address (operands[1], SFmode, 0);
2772 if (symbolic_operand (operands[1], SFmode))
2774 operands[1] = legitimize_pic_address (operands[1],
2776 (reload_in_progress ?
2786 (define_expand "movdf"
2787 [(set (match_operand:DF 0 "general_operand" "")
2788 (match_operand:DF 1 "general_operand" ""))]
2791 /* Force DFmode constants into memory. */
2792 if (GET_CODE (operands[0]) == REG
2793 && CONSTANT_P (operands[1]))
2795 /* emit_group_store will send such bogosity to us when it is
2796 not storing directly into memory. So fix this up to avoid
2797 crashes in output_constant_pool. */
2798 if (operands [1] == const0_rtx)
2799 operands[1] = CONST0_RTX (DFmode);
2801 if ((TARGET_VIS || REGNO (operands[0]) < 32)
2802 && fp_zero_operand (operands[1], DFmode))
2805 /* We are able to build any DF constant in integer registers. */
2806 if (REGNO (operands[0]) < 32
2807 && (reload_completed || reload_in_progress))
2810 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
2814 /* Handle MEM cases first. */
2815 if (GET_CODE (operands[0]) == MEM)
2817 if (register_operand (operands[1], DFmode)
2818 || fp_zero_operand (operands[1], DFmode))
2821 if (! reload_in_progress)
2823 operands[0] = validize_mem (operands[0]);
2824 operands[1] = force_reg (DFmode, operands[1]);
2828 /* Fixup PIC cases. */
2831 if (CONSTANT_P (operands[1])
2832 && pic_address_needs_scratch (operands[1]))
2833 operands[1] = legitimize_pic_address (operands[1], DFmode, 0);
2835 if (symbolic_operand (operands[1], DFmode))
2837 operands[1] = legitimize_pic_address (operands[1],
2839 (reload_in_progress ?
2849 ;; Be careful, fmovd does not exist when !v9.
2850 (define_insn "*movdf_insn_sp32"
2851 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,W,U,T,o,e,*r,o,e,o")
2852 (match_operand:DF 1 "input_operand" "W#F,e,T,U,G,e,*rFo,*r,o#F,e"))]
2855 && (register_operand (operands[0], DFmode)
2856 || register_operand (operands[1], DFmode)
2857 || fp_zero_operand (operands[1], DFmode))"
2869 [(set_attr "type" "fpload,fpstore,load,store,*,*,*,*,*,*")
2870 (set_attr "length" "*,*,*,*,2,2,2,2,2,2")])
2872 (define_insn "*movdf_no_e_insn_sp32"
2873 [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,o,r,o")
2874 (match_operand:DF 1 "input_operand" "T,U,G,ro,r"))]
2878 && (register_operand (operands[0], DFmode)
2879 || register_operand (operands[1], DFmode)
2880 || fp_zero_operand (operands[1], DFmode))"
2887 [(set_attr "type" "load,store,*,*,*")
2888 (set_attr "length" "*,*,2,2,2")])
2890 (define_insn "*movdf_no_e_insn_v9_sp32"
2891 [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,T,r,o")
2892 (match_operand:DF 1 "input_operand" "T,U,G,ro,rG"))]
2896 && (register_operand (operands[0], DFmode)
2897 || register_operand (operands[1], DFmode)
2898 || fp_zero_operand (operands[1], DFmode))"
2905 [(set_attr "type" "load,store,store,*,*")
2906 (set_attr "length" "*,*,*,2,2")])
2908 ;; We have available v9 double floats but not 64-bit
2909 ;; integer registers and no VIS.
2910 (define_insn "*movdf_insn_v9only_novis"
2911 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,T,W,U,T,f,*r,o")
2912 (match_operand:DF 1 "input_operand" "e,W#F,G,e,T,U,o#F,*roF,*rGf"))]
2917 && (register_operand (operands[0], DFmode)
2918 || register_operand (operands[1], DFmode)
2919 || fp_zero_operand (operands[1], DFmode))"
2930 [(set_attr "type" "fpmove,load,store,store,load,store,*,*,*")
2931 (set_attr "length" "*,*,*,*,*,*,2,2,2")
2932 (set_attr "fptype" "double,*,*,*,*,*,*,*,*")])
2934 ;; We have available v9 double floats but not 64-bit
2935 ;; integer registers but we have VIS.
2936 (define_insn "*movdf_insn_v9only_vis"
2937 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,e,T,W,U,T,f,*r,o")
2938 (match_operand:DF 1 "input_operand" "G,e,W#F,G,e,T,U,o#F,*roGF,*rGf"))]
2942 && (register_operand (operands[0], DFmode)
2943 || register_operand (operands[1], DFmode)
2944 || fp_zero_operand (operands[1], DFmode))"
2956 [(set_attr "type" "fpmove,fpmove,load,store,store,load,store,*,*,*")
2957 (set_attr "length" "*,*,*,*,*,*,*,2,2,2")
2958 (set_attr "fptype" "double,double,*,*,*,*,*,*,*,*")])
2960 ;; We have available both v9 double floats and 64-bit
2961 ;; integer registers. No VIS though.
2962 (define_insn "*movdf_insn_sp64_novis"
2963 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,W,*r,*r,m,*r")
2964 (match_operand:DF 1 "input_operand" "e,W#F,e,*rG,m,*rG,F"))]
2968 && (register_operand (operands[0], DFmode)
2969 || register_operand (operands[1], DFmode)
2970 || fp_zero_operand (operands[1], DFmode))"
2979 [(set_attr "type" "fpmove,load,store,*,load,store,*")
2980 (set_attr "length" "*,*,*,*,*,*,2")
2981 (set_attr "fptype" "double,*,*,*,*,*,*")])
2983 ;; We have available both v9 double floats and 64-bit
2984 ;; integer registers. And we have VIS.
2985 (define_insn "*movdf_insn_sp64_vis"
2986 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,e,W,*r,*r,m,*r")
2987 (match_operand:DF 1 "input_operand" "G,e,W#F,e,*rG,m,*rG,F"))]
2991 && (register_operand (operands[0], DFmode)
2992 || register_operand (operands[1], DFmode)
2993 || fp_zero_operand (operands[1], DFmode))"
3003 [(set_attr "type" "fpmove,fpmove,load,store,*,load,store,*")
3004 (set_attr "length" "*,*,*,*,*,*,*,2")
3005 (set_attr "fptype" "double,double,*,*,*,*,*,*")])
3007 (define_insn "*movdf_no_e_insn_sp64"
3008 [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m")
3009 (match_operand:DF 1 "input_operand" "r,m,rG"))]
3012 && (register_operand (operands[0], DFmode)
3013 || register_operand (operands[1], DFmode)
3014 || fp_zero_operand (operands[1], DFmode))"
3019 [(set_attr "type" "*,load,store")])
3022 [(set (match_operand:DF 0 "register_operand" "")
3023 (match_operand:DF 1 "const_double_operand" ""))]
3025 && (GET_CODE (operands[0]) == REG
3026 && REGNO (operands[0]) < 32)
3027 && ! fp_zero_operand(operands[1], DFmode)
3028 && reload_completed"
3029 [(clobber (const_int 0))]
3034 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3035 REAL_VALUE_TO_TARGET_DOUBLE (r, l);
3036 operands[0] = gen_rtx_raw_REG (DImode, REGNO (operands[0]));
3040 #if HOST_BITS_PER_WIDE_INT == 64
3043 val = ((HOST_WIDE_INT)(unsigned long)l[1] |
3044 ((HOST_WIDE_INT)(unsigned long)l[0] << 32));
3045 emit_insn (gen_movdi (operands[0], GEN_INT (val)));
3047 emit_insn (gen_movdi (operands[0],
3048 immed_double_const (l[1], l[0], DImode)));
3053 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
3056 /* Slick... but this trick loses if this subreg constant part
3057 can be done in one insn. */
3059 && !(SPARC_SETHI32_P (l[0])
3060 || SPARC_SIMM13_P (l[0])))
3062 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
3063 gen_highpart (SImode, operands[0])));
3067 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
3074 ;; Ok, now the splits to handle all the multi insn and
3075 ;; mis-aligned memory address cases.
3076 ;; In these splits please take note that we must be
3077 ;; careful when V9 but not ARCH64 because the integer
3078 ;; register DFmode cases must be handled.
3080 [(set (match_operand:DF 0 "register_operand" "")
3081 (match_operand:DF 1 "register_operand" ""))]
3084 && ((GET_CODE (operands[0]) == REG
3085 && REGNO (operands[0]) < 32)
3086 || (GET_CODE (operands[0]) == SUBREG
3087 && GET_CODE (SUBREG_REG (operands[0])) == REG
3088 && REGNO (SUBREG_REG (operands[0])) < 32))))
3089 && reload_completed"
3090 [(clobber (const_int 0))]
3092 rtx set_dest = operands[0];
3093 rtx set_src = operands[1];
3097 dest1 = gen_highpart (SFmode, set_dest);
3098 dest2 = gen_lowpart (SFmode, set_dest);
3099 src1 = gen_highpart (SFmode, set_src);
3100 src2 = gen_lowpart (SFmode, set_src);
3102 /* Now emit using the real source and destination we found, swapping
3103 the order if we detect overlap. */
3104 if (reg_overlap_mentioned_p (dest1, src2))
3106 emit_insn (gen_movsf (dest2, src2));
3107 emit_insn (gen_movsf (dest1, src1));
3111 emit_insn (gen_movsf (dest1, src1));
3112 emit_insn (gen_movsf (dest2, src2));
3118 [(set (match_operand:DF 0 "register_operand" "")
3119 (match_operand:DF 1 "memory_operand" ""))]
3122 && (((REGNO (operands[0]) % 2) != 0)
3123 || ! mem_min_alignment (operands[1], 8))
3124 && offsettable_memref_p (operands[1])"
3125 [(clobber (const_int 0))]
3127 rtx word0 = adjust_address (operands[1], SFmode, 0);
3128 rtx word1 = adjust_address (operands[1], SFmode, 4);
3130 if (reg_overlap_mentioned_p (gen_highpart (SFmode, operands[0]), word1))
3132 emit_insn (gen_movsf (gen_lowpart (SFmode, operands[0]),
3134 emit_insn (gen_movsf (gen_highpart (SFmode, operands[0]),
3139 emit_insn (gen_movsf (gen_highpart (SFmode, operands[0]),
3141 emit_insn (gen_movsf (gen_lowpart (SFmode, operands[0]),
3148 [(set (match_operand:DF 0 "memory_operand" "")
3149 (match_operand:DF 1 "register_operand" ""))]
3152 && (((REGNO (operands[1]) % 2) != 0)
3153 || ! mem_min_alignment (operands[0], 8))
3154 && offsettable_memref_p (operands[0])"
3155 [(clobber (const_int 0))]
3157 rtx word0 = adjust_address (operands[0], SFmode, 0);
3158 rtx word1 = adjust_address (operands[0], SFmode, 4);
3160 emit_insn (gen_movsf (word0,
3161 gen_highpart (SFmode, operands[1])));
3162 emit_insn (gen_movsf (word1,
3163 gen_lowpart (SFmode, operands[1])));
3168 [(set (match_operand:DF 0 "memory_operand" "")
3169 (match_operand:DF 1 "fp_zero_operand" ""))]
3173 && ! mem_min_alignment (operands[0], 8)))
3174 && offsettable_memref_p (operands[0])"
3175 [(clobber (const_int 0))]
3179 dest1 = adjust_address (operands[0], SFmode, 0);
3180 dest2 = adjust_address (operands[0], SFmode, 4);
3182 emit_insn (gen_movsf (dest1, CONST0_RTX (SFmode)));
3183 emit_insn (gen_movsf (dest2, CONST0_RTX (SFmode)));
3188 [(set (match_operand:DF 0 "register_operand" "")
3189 (match_operand:DF 1 "fp_zero_operand" ""))]
3192 && ((GET_CODE (operands[0]) == REG
3193 && REGNO (operands[0]) < 32)
3194 || (GET_CODE (operands[0]) == SUBREG
3195 && GET_CODE (SUBREG_REG (operands[0])) == REG
3196 && REGNO (SUBREG_REG (operands[0])) < 32))"
3197 [(clobber (const_int 0))]
3199 rtx set_dest = operands[0];
3202 dest1 = gen_highpart (SFmode, set_dest);
3203 dest2 = gen_lowpart (SFmode, set_dest);
3204 emit_insn (gen_movsf (dest1, CONST0_RTX (SFmode)));
3205 emit_insn (gen_movsf (dest2, CONST0_RTX (SFmode)));
3209 (define_expand "movtf"
3210 [(set (match_operand:TF 0 "general_operand" "")
3211 (match_operand:TF 1 "general_operand" ""))]
3214 /* Force TFmode constants into memory. */
3215 if (GET_CODE (operands[0]) == REG
3216 && CONSTANT_P (operands[1]))
3218 /* emit_group_store will send such bogosity to us when it is
3219 not storing directly into memory. So fix this up to avoid
3220 crashes in output_constant_pool. */
3221 if (operands [1] == const0_rtx)
3222 operands[1] = CONST0_RTX (TFmode);
3224 if (TARGET_VIS && fp_zero_operand (operands[1], TFmode))
3227 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
3231 /* Handle MEM cases first, note that only v9 guarantees
3232 full 16-byte alignment for quads. */
3233 if (GET_CODE (operands[0]) == MEM)
3235 if (register_operand (operands[1], TFmode)
3236 || fp_zero_operand (operands[1], TFmode))
3239 if (! reload_in_progress)
3241 operands[0] = validize_mem (operands[0]);
3242 operands[1] = force_reg (TFmode, operands[1]);
3246 /* Fixup PIC cases. */
3249 if (CONSTANT_P (operands[1])
3250 && pic_address_needs_scratch (operands[1]))
3251 operands[1] = legitimize_pic_address (operands[1], TFmode, 0);
3253 if (symbolic_operand (operands[1], TFmode))
3255 operands[1] = legitimize_pic_address (operands[1],
3257 (reload_in_progress ?
3267 ;; Be careful, fmovq and {st,ld}{x,q} do not exist when !arch64 so
3268 ;; we must split them all. :-(
3269 (define_insn "*movtf_insn_sp32"
3270 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,U,r")
3271 (match_operand:TF 1 "input_operand" "oe,GeUr,o,roG"))]
3275 && (register_operand (operands[0], TFmode)
3276 || register_operand (operands[1], TFmode)
3277 || fp_zero_operand (operands[1], TFmode))"
3279 [(set_attr "length" "4")])
3281 (define_insn "*movtf_insn_vis_sp32"
3282 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,U,r")
3283 (match_operand:TF 1 "input_operand" "Goe,GeUr,o,roG"))]
3287 && (register_operand (operands[0], TFmode)
3288 || register_operand (operands[1], TFmode)
3289 || fp_zero_operand (operands[1], TFmode))"
3291 [(set_attr "length" "4")])
3293 ;; Exactly the same as above, except that all `e' cases are deleted.
3294 ;; This is necessary to prevent reload from ever trying to use a `e' reg
3297 (define_insn "*movtf_no_e_insn_sp32"
3298 [(set (match_operand:TF 0 "nonimmediate_operand" "=o,U,o,r,o")
3299 (match_operand:TF 1 "input_operand" "G,o,U,roG,r"))]
3302 && (register_operand (operands[0], TFmode)
3303 || register_operand (operands[1], TFmode)
3304 || fp_zero_operand (operands[1], TFmode))"
3306 [(set_attr "length" "4")])
3308 ;; Now handle the float reg cases directly when arch64,
3309 ;; hard_quad, and proper reg number alignment are all true.
3310 (define_insn "*movtf_insn_hq_sp64"
3311 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,e,m,o,r")
3312 (match_operand:TF 1 "input_operand" "e,m,e,Gr,roG"))]
3317 && (register_operand (operands[0], TFmode)
3318 || register_operand (operands[1], TFmode)
3319 || fp_zero_operand (operands[1], TFmode))"
3326 [(set_attr "type" "fpmove,fpload,fpstore,*,*")
3327 (set_attr "length" "*,*,*,2,2")])
3329 (define_insn "*movtf_insn_hq_vis_sp64"
3330 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,e,m,eo,r,o")
3331 (match_operand:TF 1 "input_operand" "e,m,e,G,roG,r"))]
3336 && (register_operand (operands[0], TFmode)
3337 || register_operand (operands[1], TFmode)
3338 || fp_zero_operand (operands[1], TFmode))"
3346 [(set_attr "type" "fpmove,fpload,fpstore,*,*,*")
3347 (set_attr "length" "*,*,*,2,2,2")])
3349 ;; Now we allow the integer register cases even when
3350 ;; only arch64 is true.
3351 (define_insn "*movtf_insn_sp64"
3352 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,r")
3353 (match_operand:TF 1 "input_operand" "oe,Ger,orG"))]
3357 && ! TARGET_HARD_QUAD
3358 && (register_operand (operands[0], TFmode)
3359 || register_operand (operands[1], TFmode)
3360 || fp_zero_operand (operands[1], TFmode))"
3362 [(set_attr "length" "2")])
3364 (define_insn "*movtf_insn_vis_sp64"
3365 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,r")
3366 (match_operand:TF 1 "input_operand" "Goe,Ger,orG"))]
3370 && ! TARGET_HARD_QUAD
3371 && (register_operand (operands[0], TFmode)
3372 || register_operand (operands[1], TFmode)
3373 || fp_zero_operand (operands[1], TFmode))"
3375 [(set_attr "length" "2")])
3377 (define_insn "*movtf_no_e_insn_sp64"
3378 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o")
3379 (match_operand:TF 1 "input_operand" "orG,rG"))]
3382 && (register_operand (operands[0], TFmode)
3383 || register_operand (operands[1], TFmode)
3384 || fp_zero_operand (operands[1], TFmode))"
3386 [(set_attr "length" "2")])
3388 ;; Now all the splits to handle multi-insn TF mode moves.
3390 [(set (match_operand:TF 0 "register_operand" "")
3391 (match_operand:TF 1 "register_operand" ""))]
3395 && ! TARGET_HARD_QUAD)
3396 || ! fp_register_operand (operands[0], TFmode))"
3397 [(clobber (const_int 0))]
3399 rtx set_dest = operands[0];
3400 rtx set_src = operands[1];
3404 dest1 = gen_df_reg (set_dest, 0);
3405 dest2 = gen_df_reg (set_dest, 1);
3406 src1 = gen_df_reg (set_src, 0);
3407 src2 = gen_df_reg (set_src, 1);
3409 /* Now emit using the real source and destination we found, swapping
3410 the order if we detect overlap. */
3411 if (reg_overlap_mentioned_p (dest1, src2))
3413 emit_insn (gen_movdf (dest2, src2));
3414 emit_insn (gen_movdf (dest1, src1));
3418 emit_insn (gen_movdf (dest1, src1));
3419 emit_insn (gen_movdf (dest2, src2));
3425 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3426 (match_operand:TF 1 "fp_zero_operand" ""))]
3428 [(clobber (const_int 0))]
3430 rtx set_dest = operands[0];
3433 switch (GET_CODE (set_dest))
3436 dest1 = gen_df_reg (set_dest, 0);
3437 dest2 = gen_df_reg (set_dest, 1);
3440 dest1 = adjust_address (set_dest, DFmode, 0);
3441 dest2 = adjust_address (set_dest, DFmode, 8);
3447 emit_insn (gen_movdf (dest1, CONST0_RTX (DFmode)));
3448 emit_insn (gen_movdf (dest2, CONST0_RTX (DFmode)));
3453 [(set (match_operand:TF 0 "register_operand" "")
3454 (match_operand:TF 1 "memory_operand" ""))]
3456 && offsettable_memref_p (operands[1])
3458 || ! TARGET_HARD_QUAD
3459 || ! fp_register_operand (operands[0], TFmode)))"
3460 [(clobber (const_int 0))]
3462 rtx word0 = adjust_address (operands[1], DFmode, 0);
3463 rtx word1 = adjust_address (operands[1], DFmode, 8);
3464 rtx set_dest, dest1, dest2;
3466 set_dest = operands[0];
3468 dest1 = gen_df_reg (set_dest, 0);
3469 dest2 = gen_df_reg (set_dest, 1);
3471 /* Now output, ordering such that we don't clobber any registers
3472 mentioned in the address. */
3473 if (reg_overlap_mentioned_p (dest1, word1))
3476 emit_insn (gen_movdf (dest2, word1));
3477 emit_insn (gen_movdf (dest1, word0));
3481 emit_insn (gen_movdf (dest1, word0));
3482 emit_insn (gen_movdf (dest2, word1));
3488 [(set (match_operand:TF 0 "memory_operand" "")
3489 (match_operand:TF 1 "register_operand" ""))]
3491 && offsettable_memref_p (operands[0])
3493 || ! TARGET_HARD_QUAD
3494 || ! fp_register_operand (operands[1], TFmode)))"
3495 [(clobber (const_int 0))]
3497 rtx set_src = operands[1];
3499 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 0),
3500 gen_df_reg (set_src, 0)));
3501 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 8),
3502 gen_df_reg (set_src, 1)));
3506 ;; SPARC V9 conditional move instructions.
3508 ;; We can handle larger constants here for some flavors, but for now we keep
3509 ;; it simple and only allow those constants supported by all flavors.
3510 ;; Note that emit_conditional_move canonicalizes operands 2,3 so that operand
3511 ;; 3 contains the constant if one is present, but we handle either for
3512 ;; generality (sparc.c puts a constant in operand 2).
3514 (define_expand "movqicc"
3515 [(set (match_operand:QI 0 "register_operand" "")
3516 (if_then_else:QI (match_operand 1 "comparison_operator" "")
3517 (match_operand:QI 2 "arith10_operand" "")
3518 (match_operand:QI 3 "arith10_operand" "")))]
3521 enum rtx_code code = GET_CODE (operands[1]);
3523 if (GET_MODE (sparc_compare_op0) == DImode
3527 if (sparc_compare_op1 == const0_rtx
3528 && GET_CODE (sparc_compare_op0) == REG
3529 && GET_MODE (sparc_compare_op0) == DImode
3530 && v9_regcmp_p (code))
3532 operands[1] = gen_rtx_fmt_ee (code, DImode,
3533 sparc_compare_op0, sparc_compare_op1);
3537 rtx cc_reg = gen_compare_reg (code,
3538 sparc_compare_op0, sparc_compare_op1);
3539 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3543 (define_expand "movhicc"
3544 [(set (match_operand:HI 0 "register_operand" "")
3545 (if_then_else:HI (match_operand 1 "comparison_operator" "")
3546 (match_operand:HI 2 "arith10_operand" "")
3547 (match_operand:HI 3 "arith10_operand" "")))]
3550 enum rtx_code code = GET_CODE (operands[1]);
3552 if (GET_MODE (sparc_compare_op0) == DImode
3556 if (sparc_compare_op1 == const0_rtx
3557 && GET_CODE (sparc_compare_op0) == REG
3558 && GET_MODE (sparc_compare_op0) == DImode
3559 && v9_regcmp_p (code))
3561 operands[1] = gen_rtx_fmt_ee (code, DImode,
3562 sparc_compare_op0, sparc_compare_op1);
3566 rtx cc_reg = gen_compare_reg (code,
3567 sparc_compare_op0, sparc_compare_op1);
3568 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3572 (define_expand "movsicc"
3573 [(set (match_operand:SI 0 "register_operand" "")
3574 (if_then_else:SI (match_operand 1 "comparison_operator" "")
3575 (match_operand:SI 2 "arith10_operand" "")
3576 (match_operand:SI 3 "arith10_operand" "")))]
3579 enum rtx_code code = GET_CODE (operands[1]);
3580 enum machine_mode op0_mode = GET_MODE (sparc_compare_op0);
3582 if (sparc_compare_op1 == const0_rtx
3583 && GET_CODE (sparc_compare_op0) == REG
3584 && (TARGET_ARCH64 && op0_mode == DImode && v9_regcmp_p (code)))
3586 operands[1] = gen_rtx_fmt_ee (code, op0_mode,
3587 sparc_compare_op0, sparc_compare_op1);
3591 rtx cc_reg = gen_compare_reg (code,
3592 sparc_compare_op0, sparc_compare_op1);
3593 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg),
3594 cc_reg, const0_rtx);
3598 (define_expand "movdicc"
3599 [(set (match_operand:DI 0 "register_operand" "")
3600 (if_then_else:DI (match_operand 1 "comparison_operator" "")
3601 (match_operand:DI 2 "arith10_double_operand" "")
3602 (match_operand:DI 3 "arith10_double_operand" "")))]
3605 enum rtx_code code = GET_CODE (operands[1]);
3607 if (sparc_compare_op1 == const0_rtx
3608 && GET_CODE (sparc_compare_op0) == REG
3609 && GET_MODE (sparc_compare_op0) == DImode
3610 && v9_regcmp_p (code))
3612 operands[1] = gen_rtx_fmt_ee (code, DImode,
3613 sparc_compare_op0, sparc_compare_op1);
3617 rtx cc_reg = gen_compare_reg (code,
3618 sparc_compare_op0, sparc_compare_op1);
3619 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg),
3620 cc_reg, const0_rtx);
3624 (define_expand "movsfcc"
3625 [(set (match_operand:SF 0 "register_operand" "")
3626 (if_then_else:SF (match_operand 1 "comparison_operator" "")
3627 (match_operand:SF 2 "register_operand" "")
3628 (match_operand:SF 3 "register_operand" "")))]
3629 "TARGET_V9 && TARGET_FPU"
3631 enum rtx_code code = GET_CODE (operands[1]);
3633 if (GET_MODE (sparc_compare_op0) == DImode
3637 if (sparc_compare_op1 == const0_rtx
3638 && GET_CODE (sparc_compare_op0) == REG
3639 && GET_MODE (sparc_compare_op0) == DImode
3640 && v9_regcmp_p (code))
3642 operands[1] = gen_rtx_fmt_ee (code, DImode,
3643 sparc_compare_op0, sparc_compare_op1);
3647 rtx cc_reg = gen_compare_reg (code,
3648 sparc_compare_op0, sparc_compare_op1);
3649 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3653 (define_expand "movdfcc"
3654 [(set (match_operand:DF 0 "register_operand" "")
3655 (if_then_else:DF (match_operand 1 "comparison_operator" "")
3656 (match_operand:DF 2 "register_operand" "")
3657 (match_operand:DF 3 "register_operand" "")))]
3658 "TARGET_V9 && TARGET_FPU"
3660 enum rtx_code code = GET_CODE (operands[1]);
3662 if (GET_MODE (sparc_compare_op0) == DImode
3666 if (sparc_compare_op1 == const0_rtx
3667 && GET_CODE (sparc_compare_op0) == REG
3668 && GET_MODE (sparc_compare_op0) == DImode
3669 && v9_regcmp_p (code))
3671 operands[1] = gen_rtx_fmt_ee (code, DImode,
3672 sparc_compare_op0, sparc_compare_op1);
3676 rtx cc_reg = gen_compare_reg (code,
3677 sparc_compare_op0, sparc_compare_op1);
3678 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3682 (define_expand "movtfcc"
3683 [(set (match_operand:TF 0 "register_operand" "")
3684 (if_then_else:TF (match_operand 1 "comparison_operator" "")
3685 (match_operand:TF 2 "register_operand" "")
3686 (match_operand:TF 3 "register_operand" "")))]
3687 "TARGET_V9 && TARGET_FPU"
3689 enum rtx_code code = GET_CODE (operands[1]);
3691 if (GET_MODE (sparc_compare_op0) == DImode
3695 if (sparc_compare_op1 == const0_rtx
3696 && GET_CODE (sparc_compare_op0) == REG
3697 && GET_MODE (sparc_compare_op0) == DImode
3698 && v9_regcmp_p (code))
3700 operands[1] = gen_rtx_fmt_ee (code, DImode,
3701 sparc_compare_op0, sparc_compare_op1);
3705 rtx cc_reg = gen_compare_reg (code,
3706 sparc_compare_op0, sparc_compare_op1);
3707 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3711 ;; Conditional move define_insns.
3713 (define_insn "*movqi_cc_sp64"
3714 [(set (match_operand:QI 0 "register_operand" "=r,r")
3715 (if_then_else:QI (match_operator 1 "comparison_operator"
3716 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3718 (match_operand:QI 3 "arith11_operand" "rL,0")
3719 (match_operand:QI 4 "arith11_operand" "0,rL")))]
3723 mov%c1\t%x2, %4, %0"
3724 [(set_attr "type" "cmove")])
3726 (define_insn "*movhi_cc_sp64"
3727 [(set (match_operand:HI 0 "register_operand" "=r,r")
3728 (if_then_else:HI (match_operator 1 "comparison_operator"
3729 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3731 (match_operand:HI 3 "arith11_operand" "rL,0")
3732 (match_operand:HI 4 "arith11_operand" "0,rL")))]
3736 mov%c1\t%x2, %4, %0"
3737 [(set_attr "type" "cmove")])
3739 (define_insn "*movsi_cc_sp64"
3740 [(set (match_operand:SI 0 "register_operand" "=r,r")
3741 (if_then_else:SI (match_operator 1 "comparison_operator"
3742 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3744 (match_operand:SI 3 "arith11_operand" "rL,0")
3745 (match_operand:SI 4 "arith11_operand" "0,rL")))]
3749 mov%c1\t%x2, %4, %0"
3750 [(set_attr "type" "cmove")])
3752 ;; ??? The constraints of operands 3,4 need work.
3753 (define_insn "*movdi_cc_sp64"
3754 [(set (match_operand:DI 0 "register_operand" "=r,r")
3755 (if_then_else:DI (match_operator 1 "comparison_operator"
3756 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3758 (match_operand:DI 3 "arith11_double_operand" "rLH,0")
3759 (match_operand:DI 4 "arith11_double_operand" "0,rLH")))]
3763 mov%c1\t%x2, %4, %0"
3764 [(set_attr "type" "cmove")])
3766 (define_insn "*movdi_cc_sp64_trunc"
3767 [(set (match_operand:SI 0 "register_operand" "=r,r")
3768 (if_then_else:SI (match_operator 1 "comparison_operator"
3769 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3771 (match_operand:SI 3 "arith11_double_operand" "rLH,0")
3772 (match_operand:SI 4 "arith11_double_operand" "0,rLH")))]
3776 mov%c1\t%x2, %4, %0"
3777 [(set_attr "type" "cmove")])
3779 (define_insn "*movsf_cc_sp64"
3780 [(set (match_operand:SF 0 "register_operand" "=f,f")
3781 (if_then_else:SF (match_operator 1 "comparison_operator"
3782 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3784 (match_operand:SF 3 "register_operand" "f,0")
3785 (match_operand:SF 4 "register_operand" "0,f")))]
3786 "TARGET_V9 && TARGET_FPU"
3788 fmovs%C1\t%x2, %3, %0
3789 fmovs%c1\t%x2, %4, %0"
3790 [(set_attr "type" "fpcmove")])
3792 (define_insn "movdf_cc_sp64"
3793 [(set (match_operand:DF 0 "register_operand" "=e,e")
3794 (if_then_else:DF (match_operator 1 "comparison_operator"
3795 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3797 (match_operand:DF 3 "register_operand" "e,0")
3798 (match_operand:DF 4 "register_operand" "0,e")))]
3799 "TARGET_V9 && TARGET_FPU"
3801 fmovd%C1\t%x2, %3, %0
3802 fmovd%c1\t%x2, %4, %0"
3803 [(set_attr "type" "fpcmove")
3804 (set_attr "fptype" "double")])
3806 (define_insn "*movtf_cc_hq_sp64"
3807 [(set (match_operand:TF 0 "register_operand" "=e,e")
3808 (if_then_else:TF (match_operator 1 "comparison_operator"
3809 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3811 (match_operand:TF 3 "register_operand" "e,0")
3812 (match_operand:TF 4 "register_operand" "0,e")))]
3813 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
3815 fmovq%C1\t%x2, %3, %0
3816 fmovq%c1\t%x2, %4, %0"
3817 [(set_attr "type" "fpcmove")])
3819 (define_insn_and_split "*movtf_cc_sp64"
3820 [(set (match_operand:TF 0 "register_operand" "=e,e")
3821 (if_then_else:TF (match_operator 1 "comparison_operator"
3822 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3824 (match_operand:TF 3 "register_operand" "e,0")
3825 (match_operand:TF 4 "register_operand" "0,e")))]
3826 "TARGET_V9 && TARGET_FPU && !TARGET_HARD_QUAD"
3828 "&& reload_completed"
3829 [(clobber (const_int 0))]
3831 rtx set_dest = operands[0];
3832 rtx set_srca = operands[3];
3833 rtx set_srcb = operands[4];
3834 int third = rtx_equal_p (set_dest, set_srca);
3836 rtx srca1, srca2, srcb1, srcb2;
3838 dest1 = gen_df_reg (set_dest, 0);
3839 dest2 = gen_df_reg (set_dest, 1);
3840 srca1 = gen_df_reg (set_srca, 0);
3841 srca2 = gen_df_reg (set_srca, 1);
3842 srcb1 = gen_df_reg (set_srcb, 0);
3843 srcb2 = gen_df_reg (set_srcb, 1);
3845 /* Now emit using the real source and destination we found, swapping
3846 the order if we detect overlap. */
3847 if ((third && reg_overlap_mentioned_p (dest1, srcb2))
3848 || (!third && reg_overlap_mentioned_p (dest1, srca2)))
3850 emit_insn (gen_movdf_cc_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
3851 emit_insn (gen_movdf_cc_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
3855 emit_insn (gen_movdf_cc_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
3856 emit_insn (gen_movdf_cc_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
3860 [(set_attr "length" "2")])
3862 (define_insn "*movqi_cc_reg_sp64"
3863 [(set (match_operand:QI 0 "register_operand" "=r,r")
3864 (if_then_else:QI (match_operator 1 "v9_regcmp_op"
3865 [(match_operand:DI 2 "register_operand" "r,r")
3867 (match_operand:QI 3 "arith10_operand" "rM,0")
3868 (match_operand:QI 4 "arith10_operand" "0,rM")))]
3871 movr%D1\t%2, %r3, %0
3872 movr%d1\t%2, %r4, %0"
3873 [(set_attr "type" "cmove")])
3875 (define_insn "*movhi_cc_reg_sp64"
3876 [(set (match_operand:HI 0 "register_operand" "=r,r")
3877 (if_then_else:HI (match_operator 1 "v9_regcmp_op"
3878 [(match_operand:DI 2 "register_operand" "r,r")
3880 (match_operand:HI 3 "arith10_operand" "rM,0")
3881 (match_operand:HI 4 "arith10_operand" "0,rM")))]
3884 movr%D1\t%2, %r3, %0
3885 movr%d1\t%2, %r4, %0"
3886 [(set_attr "type" "cmove")])
3888 (define_insn "*movsi_cc_reg_sp64"
3889 [(set (match_operand:SI 0 "register_operand" "=r,r")
3890 (if_then_else:SI (match_operator 1 "v9_regcmp_op"
3891 [(match_operand:DI 2 "register_operand" "r,r")
3893 (match_operand:SI 3 "arith10_operand" "rM,0")
3894 (match_operand:SI 4 "arith10_operand" "0,rM")))]
3897 movr%D1\t%2, %r3, %0
3898 movr%d1\t%2, %r4, %0"
3899 [(set_attr "type" "cmove")])
3901 ;; ??? The constraints of operands 3,4 need work.
3902 (define_insn "*movdi_cc_reg_sp64"
3903 [(set (match_operand:DI 0 "register_operand" "=r,r")
3904 (if_then_else:DI (match_operator 1 "v9_regcmp_op"
3905 [(match_operand:DI 2 "register_operand" "r,r")
3907 (match_operand:DI 3 "arith10_double_operand" "rMH,0")
3908 (match_operand:DI 4 "arith10_double_operand" "0,rMH")))]
3911 movr%D1\t%2, %r3, %0
3912 movr%d1\t%2, %r4, %0"
3913 [(set_attr "type" "cmove")])
3915 (define_insn "*movdi_cc_reg_sp64_trunc"
3916 [(set (match_operand:SI 0 "register_operand" "=r,r")
3917 (if_then_else:SI (match_operator 1 "v9_regcmp_op"
3918 [(match_operand:DI 2 "register_operand" "r,r")
3920 (match_operand:SI 3 "arith10_double_operand" "rMH,0")
3921 (match_operand:SI 4 "arith10_double_operand" "0,rMH")))]
3924 movr%D1\t%2, %r3, %0
3925 movr%d1\t%2, %r4, %0"
3926 [(set_attr "type" "cmove")])
3928 (define_insn "*movsf_cc_reg_sp64"
3929 [(set (match_operand:SF 0 "register_operand" "=f,f")
3930 (if_then_else:SF (match_operator 1 "v9_regcmp_op"
3931 [(match_operand:DI 2 "register_operand" "r,r")
3933 (match_operand:SF 3 "register_operand" "f,0")
3934 (match_operand:SF 4 "register_operand" "0,f")))]
3935 "TARGET_ARCH64 && TARGET_FPU"
3937 fmovrs%D1\t%2, %3, %0
3938 fmovrs%d1\t%2, %4, %0"
3939 [(set_attr "type" "fpcrmove")])
3941 (define_insn "movdf_cc_reg_sp64"
3942 [(set (match_operand:DF 0 "register_operand" "=e,e")
3943 (if_then_else:DF (match_operator 1 "v9_regcmp_op"
3944 [(match_operand:DI 2 "register_operand" "r,r")
3946 (match_operand:DF 3 "register_operand" "e,0")
3947 (match_operand:DF 4 "register_operand" "0,e")))]
3948 "TARGET_ARCH64 && TARGET_FPU"
3950 fmovrd%D1\t%2, %3, %0
3951 fmovrd%d1\t%2, %4, %0"
3952 [(set_attr "type" "fpcrmove")
3953 (set_attr "fptype" "double")])
3955 (define_insn "*movtf_cc_reg_hq_sp64"
3956 [(set (match_operand:TF 0 "register_operand" "=e,e")
3957 (if_then_else:TF (match_operator 1 "v9_regcmp_op"
3958 [(match_operand:DI 2 "register_operand" "r,r")
3960 (match_operand:TF 3 "register_operand" "e,0")
3961 (match_operand:TF 4 "register_operand" "0,e")))]
3962 "TARGET_ARCH64 && TARGET_FPU && TARGET_HARD_QUAD"
3964 fmovrq%D1\t%2, %3, %0
3965 fmovrq%d1\t%2, %4, %0"
3966 [(set_attr "type" "fpcrmove")])
3968 (define_insn_and_split "*movtf_cc_reg_sp64"
3969 [(set (match_operand:TF 0 "register_operand" "=e,e")
3970 (if_then_else:TF (match_operator 1 "v9_regcmp_op"
3971 [(match_operand:DI 2 "register_operand" "r,r")
3973 (match_operand:TF 3 "register_operand" "e,0")
3974 (match_operand:TF 4 "register_operand" "0,e")))]
3975 "TARGET_ARCH64 && TARGET_FPU && ! TARGET_HARD_QUAD"
3977 "&& reload_completed"
3978 [(clobber (const_int 0))]
3980 rtx set_dest = operands[0];
3981 rtx set_srca = operands[3];
3982 rtx set_srcb = operands[4];
3983 int third = rtx_equal_p (set_dest, set_srca);
3985 rtx srca1, srca2, srcb1, srcb2;
3987 dest1 = gen_df_reg (set_dest, 0);
3988 dest2 = gen_df_reg (set_dest, 1);
3989 srca1 = gen_df_reg (set_srca, 0);
3990 srca2 = gen_df_reg (set_srca, 1);
3991 srcb1 = gen_df_reg (set_srcb, 0);
3992 srcb2 = gen_df_reg (set_srcb, 1);
3994 /* Now emit using the real source and destination we found, swapping
3995 the order if we detect overlap. */
3996 if ((third && reg_overlap_mentioned_p (dest1, srcb2))
3997 || (!third && reg_overlap_mentioned_p (dest1, srca2)))
3999 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
4000 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
4004 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
4005 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
4009 [(set_attr "length" "2")])
4012 ;;- zero extension instructions
4014 ;; These patterns originally accepted general_operands, however, slightly
4015 ;; better code is generated by only accepting register_operands, and then
4016 ;; letting combine generate the ldu[hb] insns.
4018 (define_expand "zero_extendhisi2"
4019 [(set (match_operand:SI 0 "register_operand" "")
4020 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
4023 rtx temp = gen_reg_rtx (SImode);
4024 rtx shift_16 = GEN_INT (16);
4025 int op1_subbyte = 0;
4027 if (GET_CODE (operand1) == SUBREG)
4029 op1_subbyte = SUBREG_BYTE (operand1);
4030 op1_subbyte /= GET_MODE_SIZE (SImode);
4031 op1_subbyte *= GET_MODE_SIZE (SImode);
4032 operand1 = XEXP (operand1, 0);
4035 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4037 emit_insn (gen_lshrsi3 (operand0, temp, shift_16));
4041 (define_insn "*zero_extendhisi2_insn"
4042 [(set (match_operand:SI 0 "register_operand" "=r")
4043 (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
4046 [(set_attr "type" "load")
4047 (set_attr "us3load_type" "3cycle")])
4049 (define_expand "zero_extendqihi2"
4050 [(set (match_operand:HI 0 "register_operand" "")
4051 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
4055 (define_insn "*zero_extendqihi2_insn"
4056 [(set (match_operand:HI 0 "register_operand" "=r,r")
4057 (zero_extend:HI (match_operand:QI 1 "input_operand" "r,m")))]
4058 "GET_CODE (operands[1]) != CONST_INT"
4062 [(set_attr "type" "*,load")
4063 (set_attr "us3load_type" "*,3cycle")])
4065 (define_expand "zero_extendqisi2"
4066 [(set (match_operand:SI 0 "register_operand" "")
4067 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
4071 (define_insn "*zero_extendqisi2_insn"
4072 [(set (match_operand:SI 0 "register_operand" "=r,r")
4073 (zero_extend:SI (match_operand:QI 1 "input_operand" "r,m")))]
4074 "GET_CODE (operands[1]) != CONST_INT"
4078 [(set_attr "type" "*,load")
4079 (set_attr "us3load_type" "*,3cycle")])
4081 (define_expand "zero_extendqidi2"
4082 [(set (match_operand:DI 0 "register_operand" "")
4083 (zero_extend:DI (match_operand:QI 1 "register_operand" "")))]
4087 (define_insn "*zero_extendqidi2_insn"
4088 [(set (match_operand:DI 0 "register_operand" "=r,r")
4089 (zero_extend:DI (match_operand:QI 1 "input_operand" "r,m")))]
4090 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
4094 [(set_attr "type" "*,load")
4095 (set_attr "us3load_type" "*,3cycle")])
4097 (define_expand "zero_extendhidi2"
4098 [(set (match_operand:DI 0 "register_operand" "")
4099 (zero_extend:DI (match_operand:HI 1 "register_operand" "")))]
4102 rtx temp = gen_reg_rtx (DImode);
4103 rtx shift_48 = GEN_INT (48);
4104 int op1_subbyte = 0;
4106 if (GET_CODE (operand1) == SUBREG)
4108 op1_subbyte = SUBREG_BYTE (operand1);
4109 op1_subbyte /= GET_MODE_SIZE (DImode);
4110 op1_subbyte *= GET_MODE_SIZE (DImode);
4111 operand1 = XEXP (operand1, 0);
4114 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
4116 emit_insn (gen_lshrdi3 (operand0, temp, shift_48));
4120 (define_insn "*zero_extendhidi2_insn"
4121 [(set (match_operand:DI 0 "register_operand" "=r")
4122 (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
4125 [(set_attr "type" "load")
4126 (set_attr "us3load_type" "3cycle")])
4129 ;; ??? Write truncdisi pattern using sra?
4131 (define_expand "zero_extendsidi2"
4132 [(set (match_operand:DI 0 "register_operand" "")
4133 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
4137 (define_insn "*zero_extendsidi2_insn_sp64"
4138 [(set (match_operand:DI 0 "register_operand" "=r,r")
4139 (zero_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
4140 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
4144 [(set_attr "type" "shift,load")])
4146 (define_insn_and_split "*zero_extendsidi2_insn_sp32"
4147 [(set (match_operand:DI 0 "register_operand" "=r")
4148 (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
4151 "&& reload_completed"
4152 [(set (match_dup 2) (match_dup 3))
4153 (set (match_dup 4) (match_dup 5))]
4157 dest1 = gen_highpart (SImode, operands[0]);
4158 dest2 = gen_lowpart (SImode, operands[0]);
4160 /* Swap the order in case of overlap. */
4161 if (REGNO (dest1) == REGNO (operands[1]))
4163 operands[2] = dest2;
4164 operands[3] = operands[1];
4165 operands[4] = dest1;
4166 operands[5] = const0_rtx;
4170 operands[2] = dest1;
4171 operands[3] = const0_rtx;
4172 operands[4] = dest2;
4173 operands[5] = operands[1];
4176 [(set_attr "length" "2")])
4178 ;; Simplify comparisons of extended values.
4180 (define_insn "*cmp_zero_extendqisi2"
4182 (compare:CC (zero_extend:SI (match_operand:QI 0 "register_operand" "r"))
4185 "andcc\t%0, 0xff, %%g0"
4186 [(set_attr "type" "compare")])
4188 (define_insn "*cmp_zero_qi"
4190 (compare:CC (match_operand:QI 0 "register_operand" "r")
4193 "andcc\t%0, 0xff, %%g0"
4194 [(set_attr "type" "compare")])
4196 (define_insn "*cmp_zero_extendqisi2_set"
4198 (compare:CC (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
4200 (set (match_operand:SI 0 "register_operand" "=r")
4201 (zero_extend:SI (match_dup 1)))]
4203 "andcc\t%1, 0xff, %0"
4204 [(set_attr "type" "compare")])
4206 (define_insn "*cmp_zero_extendqisi2_andcc_set"
4208 (compare:CC (and:SI (match_operand:SI 1 "register_operand" "r")
4211 (set (match_operand:SI 0 "register_operand" "=r")
4212 (zero_extend:SI (subreg:QI (match_dup 1) 0)))]
4214 "andcc\t%1, 0xff, %0"
4215 [(set_attr "type" "compare")])
4217 (define_insn "*cmp_zero_extendqidi2"
4219 (compare:CCX (zero_extend:DI (match_operand:QI 0 "register_operand" "r"))
4222 "andcc\t%0, 0xff, %%g0"
4223 [(set_attr "type" "compare")])
4225 (define_insn "*cmp_zero_qi_sp64"
4227 (compare:CCX (match_operand:QI 0 "register_operand" "r")
4230 "andcc\t%0, 0xff, %%g0"
4231 [(set_attr "type" "compare")])
4233 (define_insn "*cmp_zero_extendqidi2_set"
4235 (compare:CCX (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
4237 (set (match_operand:DI 0 "register_operand" "=r")
4238 (zero_extend:DI (match_dup 1)))]
4240 "andcc\t%1, 0xff, %0"
4241 [(set_attr "type" "compare")])
4243 (define_insn "*cmp_zero_extendqidi2_andcc_set"
4245 (compare:CCX (and:DI (match_operand:DI 1 "register_operand" "r")
4248 (set (match_operand:DI 0 "register_operand" "=r")
4249 (zero_extend:DI (subreg:QI (match_dup 1) 0)))]
4251 "andcc\t%1, 0xff, %0"
4252 [(set_attr "type" "compare")])
4254 ;; Similarly, handle {SI,DI}->QI mode truncation followed by a compare.
4256 (define_insn "*cmp_siqi_trunc"
4258 (compare:CC (subreg:QI (match_operand:SI 0 "register_operand" "r") 3)
4261 "andcc\t%0, 0xff, %%g0"
4262 [(set_attr "type" "compare")])
4264 (define_insn "*cmp_siqi_trunc_set"
4266 (compare:CC (subreg:QI (match_operand:SI 1 "register_operand" "r") 3)
4268 (set (match_operand:QI 0 "register_operand" "=r")
4269 (subreg:QI (match_dup 1) 3))]
4271 "andcc\t%1, 0xff, %0"
4272 [(set_attr "type" "compare")])
4274 (define_insn "*cmp_diqi_trunc"
4276 (compare:CC (subreg:QI (match_operand:DI 0 "register_operand" "r") 7)
4279 "andcc\t%0, 0xff, %%g0"
4280 [(set_attr "type" "compare")])
4282 (define_insn "*cmp_diqi_trunc_set"
4284 (compare:CC (subreg:QI (match_operand:DI 1 "register_operand" "r") 7)
4286 (set (match_operand:QI 0 "register_operand" "=r")
4287 (subreg:QI (match_dup 1) 7))]
4289 "andcc\t%1, 0xff, %0"
4290 [(set_attr "type" "compare")])
4292 ;;- sign extension instructions
4294 ;; These patterns originally accepted general_operands, however, slightly
4295 ;; better code is generated by only accepting register_operands, and then
4296 ;; letting combine generate the lds[hb] insns.
4298 (define_expand "extendhisi2"
4299 [(set (match_operand:SI 0 "register_operand" "")
4300 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
4303 rtx temp = gen_reg_rtx (SImode);
4304 rtx shift_16 = GEN_INT (16);
4305 int op1_subbyte = 0;
4307 if (GET_CODE (operand1) == SUBREG)
4309 op1_subbyte = SUBREG_BYTE (operand1);
4310 op1_subbyte /= GET_MODE_SIZE (SImode);
4311 op1_subbyte *= GET_MODE_SIZE (SImode);
4312 operand1 = XEXP (operand1, 0);
4315 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4317 emit_insn (gen_ashrsi3 (operand0, temp, shift_16));
4321 (define_insn "*sign_extendhisi2_insn"
4322 [(set (match_operand:SI 0 "register_operand" "=r")
4323 (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
4326 [(set_attr "type" "sload")
4327 (set_attr "us3load_type" "3cycle")])
4329 (define_expand "extendqihi2"
4330 [(set (match_operand:HI 0 "register_operand" "")
4331 (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
4334 rtx temp = gen_reg_rtx (SImode);
4335 rtx shift_24 = GEN_INT (24);
4336 int op1_subbyte = 0;
4337 int op0_subbyte = 0;
4339 if (GET_CODE (operand1) == SUBREG)
4341 op1_subbyte = SUBREG_BYTE (operand1);
4342 op1_subbyte /= GET_MODE_SIZE (SImode);
4343 op1_subbyte *= GET_MODE_SIZE (SImode);
4344 operand1 = XEXP (operand1, 0);
4346 if (GET_CODE (operand0) == SUBREG)
4348 op0_subbyte = SUBREG_BYTE (operand0);
4349 op0_subbyte /= GET_MODE_SIZE (SImode);
4350 op0_subbyte *= GET_MODE_SIZE (SImode);
4351 operand0 = XEXP (operand0, 0);
4353 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4355 if (GET_MODE (operand0) != SImode)
4356 operand0 = gen_rtx_SUBREG (SImode, operand0, op0_subbyte);
4357 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
4361 (define_insn "*sign_extendqihi2_insn"
4362 [(set (match_operand:HI 0 "register_operand" "=r")
4363 (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
4366 [(set_attr "type" "sload")
4367 (set_attr "us3load_type" "3cycle")])
4369 (define_expand "extendqisi2"
4370 [(set (match_operand:SI 0 "register_operand" "")
4371 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
4374 rtx temp = gen_reg_rtx (SImode);
4375 rtx shift_24 = GEN_INT (24);
4376 int op1_subbyte = 0;
4378 if (GET_CODE (operand1) == SUBREG)
4380 op1_subbyte = SUBREG_BYTE (operand1);
4381 op1_subbyte /= GET_MODE_SIZE (SImode);
4382 op1_subbyte *= GET_MODE_SIZE (SImode);
4383 operand1 = XEXP (operand1, 0);
4386 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4388 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
4392 (define_insn "*sign_extendqisi2_insn"
4393 [(set (match_operand:SI 0 "register_operand" "=r")
4394 (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
4397 [(set_attr "type" "sload")
4398 (set_attr "us3load_type" "3cycle")])
4400 (define_expand "extendqidi2"
4401 [(set (match_operand:DI 0 "register_operand" "")
4402 (sign_extend:DI (match_operand:QI 1 "register_operand" "")))]
4405 rtx temp = gen_reg_rtx (DImode);
4406 rtx shift_56 = GEN_INT (56);
4407 int op1_subbyte = 0;
4409 if (GET_CODE (operand1) == SUBREG)
4411 op1_subbyte = SUBREG_BYTE (operand1);
4412 op1_subbyte /= GET_MODE_SIZE (DImode);
4413 op1_subbyte *= GET_MODE_SIZE (DImode);
4414 operand1 = XEXP (operand1, 0);
4417 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
4419 emit_insn (gen_ashrdi3 (operand0, temp, shift_56));
4423 (define_insn "*sign_extendqidi2_insn"
4424 [(set (match_operand:DI 0 "register_operand" "=r")
4425 (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
4428 [(set_attr "type" "sload")
4429 (set_attr "us3load_type" "3cycle")])
4431 (define_expand "extendhidi2"
4432 [(set (match_operand:DI 0 "register_operand" "")
4433 (sign_extend:DI (match_operand:HI 1 "register_operand" "")))]
4436 rtx temp = gen_reg_rtx (DImode);
4437 rtx shift_48 = GEN_INT (48);
4438 int op1_subbyte = 0;
4440 if (GET_CODE (operand1) == SUBREG)
4442 op1_subbyte = SUBREG_BYTE (operand1);
4443 op1_subbyte /= GET_MODE_SIZE (DImode);
4444 op1_subbyte *= GET_MODE_SIZE (DImode);
4445 operand1 = XEXP (operand1, 0);
4448 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
4450 emit_insn (gen_ashrdi3 (operand0, temp, shift_48));
4454 (define_insn "*sign_extendhidi2_insn"
4455 [(set (match_operand:DI 0 "register_operand" "=r")
4456 (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
4459 [(set_attr "type" "sload")
4460 (set_attr "us3load_type" "3cycle")])
4462 (define_expand "extendsidi2"
4463 [(set (match_operand:DI 0 "register_operand" "")
4464 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
4468 (define_insn "*sign_extendsidi2_insn"
4469 [(set (match_operand:DI 0 "register_operand" "=r,r")
4470 (sign_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
4475 [(set_attr "type" "shift,sload")
4476 (set_attr "us3load_type" "*,3cycle")])
4478 ;; Special pattern for optimizing bit-field compares. This is needed
4479 ;; because combine uses this as a canonical form.
4481 (define_insn "*cmp_zero_extract"
4484 (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
4485 (match_operand:SI 1 "small_int_or_double" "n")
4486 (match_operand:SI 2 "small_int_or_double" "n"))
4488 "(GET_CODE (operands[2]) == CONST_INT
4489 && INTVAL (operands[2]) > 19)
4490 || (GET_CODE (operands[2]) == CONST_DOUBLE
4491 && CONST_DOUBLE_LOW (operands[2]) > 19)"
4493 int len = (GET_CODE (operands[1]) == CONST_INT
4494 ? INTVAL (operands[1])
4495 : CONST_DOUBLE_LOW (operands[1]));
4497 (GET_CODE (operands[2]) == CONST_INT
4498 ? INTVAL (operands[2])
4499 : CONST_DOUBLE_LOW (operands[2])) - len;
4500 HOST_WIDE_INT mask = ((1 << len) - 1) << pos;
4502 operands[1] = GEN_INT (mask);
4503 return "andcc\t%0, %1, %%g0";
4505 [(set_attr "type" "compare")])
4507 (define_insn "*cmp_zero_extract_sp64"
4510 (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
4511 (match_operand:SI 1 "small_int_or_double" "n")
4512 (match_operand:SI 2 "small_int_or_double" "n"))
4515 && ((GET_CODE (operands[2]) == CONST_INT
4516 && INTVAL (operands[2]) > 51)
4517 || (GET_CODE (operands[2]) == CONST_DOUBLE
4518 && CONST_DOUBLE_LOW (operands[2]) > 51))"
4520 int len = (GET_CODE (operands[1]) == CONST_INT
4521 ? INTVAL (operands[1])
4522 : CONST_DOUBLE_LOW (operands[1]));
4524 (GET_CODE (operands[2]) == CONST_INT
4525 ? INTVAL (operands[2])
4526 : CONST_DOUBLE_LOW (operands[2])) - len;
4527 HOST_WIDE_INT mask = (((unsigned HOST_WIDE_INT) 1 << len) - 1) << pos;
4529 operands[1] = GEN_INT (mask);
4530 return "andcc\t%0, %1, %%g0";
4532 [(set_attr "type" "compare")])
4534 ;; Conversions between float, double and long double.
4536 (define_insn "extendsfdf2"
4537 [(set (match_operand:DF 0 "register_operand" "=e")
4539 (match_operand:SF 1 "register_operand" "f")))]
4542 [(set_attr "type" "fp")
4543 (set_attr "fptype" "double")])
4545 (define_expand "extendsftf2"
4546 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4548 (match_operand:SF 1 "register_operand" "")))]
4549 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4550 "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
4552 (define_insn "*extendsftf2_hq"
4553 [(set (match_operand:TF 0 "register_operand" "=e")
4555 (match_operand:SF 1 "register_operand" "f")))]
4556 "TARGET_FPU && TARGET_HARD_QUAD"
4558 [(set_attr "type" "fp")])
4560 (define_expand "extenddftf2"
4561 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4563 (match_operand:DF 1 "register_operand" "")))]
4564 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4565 "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
4567 (define_insn "*extenddftf2_hq"
4568 [(set (match_operand:TF 0 "register_operand" "=e")
4570 (match_operand:DF 1 "register_operand" "e")))]
4571 "TARGET_FPU && TARGET_HARD_QUAD"
4573 [(set_attr "type" "fp")])
4575 (define_insn "truncdfsf2"
4576 [(set (match_operand:SF 0 "register_operand" "=f")
4578 (match_operand:DF 1 "register_operand" "e")))]
4581 [(set_attr "type" "fp")
4582 (set_attr "fptype" "double")])
4584 (define_expand "trunctfsf2"
4585 [(set (match_operand:SF 0 "register_operand" "")
4587 (match_operand:TF 1 "general_operand" "")))]
4588 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4589 "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
4591 (define_insn "*trunctfsf2_hq"
4592 [(set (match_operand:SF 0 "register_operand" "=f")
4594 (match_operand:TF 1 "register_operand" "e")))]
4595 "TARGET_FPU && TARGET_HARD_QUAD"
4597 [(set_attr "type" "fp")])
4599 (define_expand "trunctfdf2"
4600 [(set (match_operand:DF 0 "register_operand" "")
4602 (match_operand:TF 1 "general_operand" "")))]
4603 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4604 "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
4606 (define_insn "*trunctfdf2_hq"
4607 [(set (match_operand:DF 0 "register_operand" "=e")
4609 (match_operand:TF 1 "register_operand" "e")))]
4610 "TARGET_FPU && TARGET_HARD_QUAD"
4612 [(set_attr "type" "fp")])
4614 ;; Conversion between fixed point and floating point.
4616 (define_insn "floatsisf2"
4617 [(set (match_operand:SF 0 "register_operand" "=f")
4618 (float:SF (match_operand:SI 1 "register_operand" "f")))]
4621 [(set_attr "type" "fp")
4622 (set_attr "fptype" "double")])
4624 (define_insn "floatsidf2"
4625 [(set (match_operand:DF 0 "register_operand" "=e")
4626 (float:DF (match_operand:SI 1 "register_operand" "f")))]
4629 [(set_attr "type" "fp")
4630 (set_attr "fptype" "double")])
4632 (define_expand "floatsitf2"
4633 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4634 (float:TF (match_operand:SI 1 "register_operand" "")))]
4635 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4636 "emit_tfmode_cvt (FLOAT, operands); DONE;")
4638 (define_insn "*floatsitf2_hq"
4639 [(set (match_operand:TF 0 "register_operand" "=e")
4640 (float:TF (match_operand:SI 1 "register_operand" "f")))]
4641 "TARGET_FPU && TARGET_HARD_QUAD"
4643 [(set_attr "type" "fp")])
4645 (define_expand "floatunssitf2"
4646 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4647 (unsigned_float:TF (match_operand:SI 1 "register_operand" "")))]
4648 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4649 "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
4651 ;; Now the same for 64 bit sources.
4653 (define_insn "floatdisf2"
4654 [(set (match_operand:SF 0 "register_operand" "=f")
4655 (float:SF (match_operand:DI 1 "register_operand" "e")))]
4656 "TARGET_V9 && TARGET_FPU"
4658 [(set_attr "type" "fp")
4659 (set_attr "fptype" "double")])
4661 (define_expand "floatunsdisf2"
4662 [(use (match_operand:SF 0 "register_operand" ""))
4663 (use (match_operand:DI 1 "register_operand" ""))]
4664 "TARGET_ARCH64 && TARGET_FPU"
4665 "sparc_emit_floatunsdi (operands); DONE;")
4667 (define_insn "floatdidf2"
4668 [(set (match_operand:DF 0 "register_operand" "=e")
4669 (float:DF (match_operand:DI 1 "register_operand" "e")))]
4670 "TARGET_V9 && TARGET_FPU"
4672 [(set_attr "type" "fp")
4673 (set_attr "fptype" "double")])
4675 (define_expand "floatunsdidf2"
4676 [(use (match_operand:DF 0 "register_operand" ""))
4677 (use (match_operand:DI 1 "register_operand" ""))]
4678 "TARGET_ARCH64 && TARGET_FPU"
4679 "sparc_emit_floatunsdi (operands); DONE;")
4681 (define_expand "floatditf2"
4682 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4683 (float:TF (match_operand:DI 1 "register_operand" "")))]
4684 "TARGET_FPU && TARGET_V9 && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4685 "emit_tfmode_cvt (FLOAT, operands); DONE;")
4687 (define_insn "*floatditf2_hq"
4688 [(set (match_operand:TF 0 "register_operand" "=e")
4689 (float:TF (match_operand:DI 1 "register_operand" "e")))]
4690 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
4692 [(set_attr "type" "fp")])
4694 (define_expand "floatunsditf2"
4695 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4696 (unsigned_float:TF (match_operand:DI 1 "register_operand" "")))]
4697 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4698 "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
4700 ;; Convert a float to an actual integer.
4701 ;; Truncation is performed as part of the conversion.
4703 (define_insn "fix_truncsfsi2"
4704 [(set (match_operand:SI 0 "register_operand" "=f")
4705 (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
4708 [(set_attr "type" "fp")
4709 (set_attr "fptype" "double")])
4711 (define_insn "fix_truncdfsi2"
4712 [(set (match_operand:SI 0 "register_operand" "=f")
4713 (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
4716 [(set_attr "type" "fp")
4717 (set_attr "fptype" "double")])
4719 (define_expand "fix_trunctfsi2"
4720 [(set (match_operand:SI 0 "register_operand" "")
4721 (fix:SI (match_operand:TF 1 "general_operand" "")))]
4722 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4723 "emit_tfmode_cvt (FIX, operands); DONE;")
4725 (define_insn "*fix_trunctfsi2_hq"
4726 [(set (match_operand:SI 0 "register_operand" "=f")
4727 (fix:SI (match_operand:TF 1 "register_operand" "e")))]
4728 "TARGET_FPU && TARGET_HARD_QUAD"
4730 [(set_attr "type" "fp")])
4732 (define_expand "fixuns_trunctfsi2"
4733 [(set (match_operand:SI 0 "register_operand" "")
4734 (unsigned_fix:SI (match_operand:TF 1 "general_operand" "")))]
4735 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4736 "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
4738 ;; Now the same, for V9 targets
4740 (define_insn "fix_truncsfdi2"
4741 [(set (match_operand:DI 0 "register_operand" "=e")
4742 (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
4743 "TARGET_V9 && TARGET_FPU"
4745 [(set_attr "type" "fp")
4746 (set_attr "fptype" "double")])
4748 (define_insn "fix_truncdfdi2"
4749 [(set (match_operand:DI 0 "register_operand" "=e")
4750 (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
4751 "TARGET_V9 && TARGET_FPU"
4753 [(set_attr "type" "fp")
4754 (set_attr "fptype" "double")])
4756 (define_expand "fix_trunctfdi2"
4757 [(set (match_operand:DI 0 "register_operand" "")
4758 (fix:DI (match_operand:TF 1 "general_operand" "")))]
4759 "TARGET_V9 && TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4760 "emit_tfmode_cvt (FIX, operands); DONE;")
4762 (define_insn "*fix_trunctfdi2_hq"
4763 [(set (match_operand:DI 0 "register_operand" "=e")
4764 (fix:DI (match_operand:TF 1 "register_operand" "e")))]
4765 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
4767 [(set_attr "type" "fp")])
4769 (define_expand "fixuns_trunctfdi2"
4770 [(set (match_operand:DI 0 "register_operand" "")
4771 (unsigned_fix:DI (match_operand:TF 1 "general_operand" "")))]
4772 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4773 "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
4775 ;;- arithmetic instructions
4777 (define_expand "adddi3"
4778 [(set (match_operand:DI 0 "register_operand" "")
4779 (plus:DI (match_operand:DI 1 "register_operand" "")
4780 (match_operand:DI 2 "arith_double_add_operand" "")))]
4783 if (! TARGET_ARCH64)
4785 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
4786 gen_rtx_SET (VOIDmode, operands[0],
4787 gen_rtx_PLUS (DImode, operands[1],
4789 gen_rtx_CLOBBER (VOIDmode,
4790 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
4795 (define_insn_and_split "adddi3_insn_sp32"
4796 [(set (match_operand:DI 0 "register_operand" "=r")
4797 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
4798 (match_operand:DI 2 "arith_double_operand" "rHI")))
4799 (clobber (reg:CC 100))]
4802 "&& reload_completed"
4803 [(parallel [(set (reg:CC_NOOV 100)
4804 (compare:CC_NOOV (plus:SI (match_dup 4)
4808 (plus:SI (match_dup 4) (match_dup 5)))])
4810 (plus:SI (plus:SI (match_dup 7)
4812 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4814 operands[3] = gen_lowpart (SImode, operands[0]);
4815 operands[4] = gen_lowpart (SImode, operands[1]);
4816 operands[5] = gen_lowpart (SImode, operands[2]);
4817 operands[6] = gen_highpart (SImode, operands[0]);
4818 operands[7] = gen_highpart_mode (SImode, DImode, operands[1]);
4819 #if HOST_BITS_PER_WIDE_INT == 32
4820 if (GET_CODE (operands[2]) == CONST_INT)
4822 if (INTVAL (operands[2]) < 0)
4823 operands[8] = constm1_rtx;
4825 operands[8] = const0_rtx;
4829 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
4831 [(set_attr "length" "2")])
4834 [(set (match_operand:DI 0 "register_operand" "")
4835 (minus:DI (match_operand:DI 1 "arith_double_operand" "")
4836 (match_operand:DI 2 "arith_double_operand" "")))
4837 (clobber (reg:CC 100))]
4838 "! TARGET_ARCH64 && reload_completed"
4839 [(parallel [(set (reg:CC_NOOV 100)
4840 (compare:CC_NOOV (minus:SI (match_dup 4)
4844 (minus:SI (match_dup 4) (match_dup 5)))])
4846 (minus:SI (minus:SI (match_dup 7)
4848 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4850 operands[3] = gen_lowpart (SImode, operands[0]);
4851 operands[4] = gen_lowpart (SImode, operands[1]);
4852 operands[5] = gen_lowpart (SImode, operands[2]);
4853 operands[6] = gen_highpart (SImode, operands[0]);
4854 operands[7] = gen_highpart (SImode, operands[1]);
4855 #if HOST_BITS_PER_WIDE_INT == 32
4856 if (GET_CODE (operands[2]) == CONST_INT)
4858 if (INTVAL (operands[2]) < 0)
4859 operands[8] = constm1_rtx;
4861 operands[8] = const0_rtx;
4865 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
4868 ;; LTU here means "carry set"
4870 [(set (match_operand:SI 0 "register_operand" "=r")
4871 (plus:SI (plus:SI (match_operand:SI 1 "arith_operand" "%r")
4872 (match_operand:SI 2 "arith_operand" "rI"))
4873 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4876 [(set_attr "type" "ialuX")])
4878 (define_insn_and_split "*addx_extend_sp32"
4879 [(set (match_operand:DI 0 "register_operand" "=r")
4880 (zero_extend:DI (plus:SI (plus:SI
4881 (match_operand:SI 1 "reg_or_0_operand" "%rJ")
4882 (match_operand:SI 2 "arith_operand" "rI"))
4883 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4886 "&& reload_completed"
4887 [(set (match_dup 3) (plus:SI (plus:SI (match_dup 1) (match_dup 2))
4888 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
4889 (set (match_dup 4) (const_int 0))]
4890 "operands[3] = gen_lowpart (SImode, operands[0]);
4891 operands[4] = gen_highpart_mode (SImode, DImode, operands[1]);"
4892 [(set_attr "length" "2")])
4894 (define_insn "*addx_extend_sp64"
4895 [(set (match_operand:DI 0 "register_operand" "=r")
4896 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
4897 (match_operand:SI 2 "arith_operand" "rI"))
4898 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4901 [(set_attr "type" "ialuX")])
4904 [(set (match_operand:SI 0 "register_operand" "=r")
4905 (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
4906 (match_operand:SI 2 "arith_operand" "rI"))
4907 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4910 [(set_attr "type" "ialuX")])
4912 (define_insn "*subx_extend_sp64"
4913 [(set (match_operand:DI 0 "register_operand" "=r")
4914 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
4915 (match_operand:SI 2 "arith_operand" "rI"))
4916 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4919 [(set_attr "type" "ialuX")])
4921 (define_insn_and_split "*subx_extend"
4922 [(set (match_operand:DI 0 "register_operand" "=r")
4923 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
4924 (match_operand:SI 2 "arith_operand" "rI"))
4925 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4928 "&& reload_completed"
4929 [(set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 2))
4930 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
4931 (set (match_dup 4) (const_int 0))]
4932 "operands[3] = gen_lowpart (SImode, operands[0]);
4933 operands[4] = gen_highpart (SImode, operands[0]);"
4934 [(set_attr "length" "2")])
4936 (define_insn_and_split ""
4937 [(set (match_operand:DI 0 "register_operand" "=r")
4938 (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4939 (match_operand:DI 2 "register_operand" "r")))
4940 (clobber (reg:CC 100))]
4943 "&& reload_completed"
4944 [(parallel [(set (reg:CC_NOOV 100)
4945 (compare:CC_NOOV (plus:SI (match_dup 3) (match_dup 1))
4947 (set (match_dup 5) (plus:SI (match_dup 3) (match_dup 1)))])
4949 (plus:SI (plus:SI (match_dup 4) (const_int 0))
4950 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4951 "operands[3] = gen_lowpart (SImode, operands[2]);
4952 operands[4] = gen_highpart (SImode, operands[2]);
4953 operands[5] = gen_lowpart (SImode, operands[0]);
4954 operands[6] = gen_highpart (SImode, operands[0]);"
4955 [(set_attr "length" "2")])
4957 (define_insn "*adddi3_sp64"
4958 [(set (match_operand:DI 0 "register_operand" "=r,r")
4959 (plus:DI (match_operand:DI 1 "register_operand" "%r,r")
4960 (match_operand:DI 2 "arith_double_add_operand" "rHI,O")))]
4966 (define_insn "addsi3"
4967 [(set (match_operand:SI 0 "register_operand" "=r,r,d")
4968 (plus:SI (match_operand:SI 1 "register_operand" "%r,r,d")
4969 (match_operand:SI 2 "arith_add_operand" "rI,O,d")))]
4974 fpadd32s\t%1, %2, %0"
4975 [(set_attr "type" "*,*,fp")])
4977 (define_insn "*cmp_cc_plus"
4978 [(set (reg:CC_NOOV 100)
4979 (compare:CC_NOOV (plus:SI (match_operand:SI 0 "arith_operand" "%r")
4980 (match_operand:SI 1 "arith_operand" "rI"))
4983 "addcc\t%0, %1, %%g0"
4984 [(set_attr "type" "compare")])
4986 (define_insn "*cmp_ccx_plus"
4987 [(set (reg:CCX_NOOV 100)
4988 (compare:CCX_NOOV (plus:DI (match_operand:DI 0 "arith_double_operand" "%r")
4989 (match_operand:DI 1 "arith_double_operand" "rHI"))
4992 "addcc\t%0, %1, %%g0"
4993 [(set_attr "type" "compare")])
4995 (define_insn "*cmp_cc_plus_set"
4996 [(set (reg:CC_NOOV 100)
4997 (compare:CC_NOOV (plus:SI (match_operand:SI 1 "arith_operand" "%r")
4998 (match_operand:SI 2 "arith_operand" "rI"))
5000 (set (match_operand:SI 0 "register_operand" "=r")
5001 (plus:SI (match_dup 1) (match_dup 2)))]
5004 [(set_attr "type" "compare")])
5006 (define_insn "*cmp_ccx_plus_set"
5007 [(set (reg:CCX_NOOV 100)
5008 (compare:CCX_NOOV (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
5009 (match_operand:DI 2 "arith_double_operand" "rHI"))
5011 (set (match_operand:DI 0 "register_operand" "=r")
5012 (plus:DI (match_dup 1) (match_dup 2)))]
5015 [(set_attr "type" "compare")])
5017 (define_expand "subdi3"
5018 [(set (match_operand:DI 0 "register_operand" "")
5019 (minus:DI (match_operand:DI 1 "register_operand" "")
5020 (match_operand:DI 2 "arith_double_add_operand" "")))]
5023 if (! TARGET_ARCH64)
5025 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
5026 gen_rtx_SET (VOIDmode, operands[0],
5027 gen_rtx_MINUS (DImode, operands[1],
5029 gen_rtx_CLOBBER (VOIDmode,
5030 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
5035 (define_insn_and_split "*subdi3_sp32"
5036 [(set (match_operand:DI 0 "register_operand" "=r")
5037 (minus:DI (match_operand:DI 1 "register_operand" "r")
5038 (match_operand:DI 2 "arith_double_operand" "rHI")))
5039 (clobber (reg:CC 100))]
5042 "&& reload_completed
5043 && (GET_CODE (operands[2]) == CONST_INT
5044 || GET_CODE (operands[2]) == CONST_DOUBLE)"
5045 [(clobber (const_int 0))]
5049 highp = gen_highpart_mode (SImode, DImode, operands[2]);
5050 lowp = gen_lowpart (SImode, operands[2]);
5051 if ((lowp == const0_rtx)
5052 && (operands[0] == operands[1]))
5054 emit_insn (gen_rtx_SET (VOIDmode,
5055 gen_highpart (SImode, operands[0]),
5056 gen_rtx_MINUS (SImode,
5057 gen_highpart_mode (SImode, DImode,
5063 emit_insn (gen_cmp_minus_cc_set (gen_lowpart (SImode, operands[0]),
5064 gen_lowpart (SImode, operands[1]),
5066 emit_insn (gen_subx (gen_highpart (SImode, operands[0]),
5067 gen_highpart_mode (SImode, DImode, operands[1]),
5072 [(set_attr "length" "2")])
5075 [(set (match_operand:DI 0 "register_operand" "")
5076 (minus:DI (match_operand:DI 1 "register_operand" "")
5077 (match_operand:DI 2 "register_operand" "")))
5078 (clobber (reg:CC 100))]
5080 && reload_completed"
5081 [(clobber (const_int 0))]
5083 emit_insn (gen_cmp_minus_cc_set (gen_lowpart (SImode, operands[0]),
5084 gen_lowpart (SImode, operands[1]),
5085 gen_lowpart (SImode, operands[2])));
5086 emit_insn (gen_subx (gen_highpart (SImode, operands[0]),
5087 gen_highpart (SImode, operands[1]),
5088 gen_highpart (SImode, operands[2])));
5092 (define_insn_and_split ""
5093 [(set (match_operand:DI 0 "register_operand" "=r")
5094 (minus:DI (match_operand:DI 1 "register_operand" "r")
5095 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))
5096 (clobber (reg:CC 100))]
5099 "&& reload_completed"
5100 [(parallel [(set (reg:CC_NOOV 100)
5101 (compare:CC_NOOV (minus:SI (match_dup 3) (match_dup 2))
5103 (set (match_dup 5) (minus:SI (match_dup 3) (match_dup 2)))])
5105 (minus:SI (minus:SI (match_dup 4) (const_int 0))
5106 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5107 "operands[3] = gen_lowpart (SImode, operands[1]);
5108 operands[4] = gen_highpart (SImode, operands[1]);
5109 operands[5] = gen_lowpart (SImode, operands[0]);
5110 operands[6] = gen_highpart (SImode, operands[0]);"
5111 [(set_attr "length" "2")])
5113 (define_insn "*subdi3_sp64"
5114 [(set (match_operand:DI 0 "register_operand" "=r,r")
5115 (minus:DI (match_operand:DI 1 "register_operand" "r,r")
5116 (match_operand:DI 2 "arith_double_add_operand" "rHI,O")))]
5122 (define_insn "subsi3"
5123 [(set (match_operand:SI 0 "register_operand" "=r,r,d")
5124 (minus:SI (match_operand:SI 1 "register_operand" "r,r,d")
5125 (match_operand:SI 2 "arith_add_operand" "rI,O,d")))]
5130 fpsub32s\t%1, %2, %0"
5131 [(set_attr "type" "*,*,fp")])
5133 (define_insn "*cmp_minus_cc"
5134 [(set (reg:CC_NOOV 100)
5135 (compare:CC_NOOV (minus:SI (match_operand:SI 0 "reg_or_0_operand" "rJ")
5136 (match_operand:SI 1 "arith_operand" "rI"))
5139 "subcc\t%r0, %1, %%g0"
5140 [(set_attr "type" "compare")])
5142 (define_insn "*cmp_minus_ccx"
5143 [(set (reg:CCX_NOOV 100)
5144 (compare:CCX_NOOV (minus:DI (match_operand:DI 0 "register_operand" "r")
5145 (match_operand:DI 1 "arith_double_operand" "rHI"))
5148 "subcc\t%0, %1, %%g0"
5149 [(set_attr "type" "compare")])
5151 (define_insn "cmp_minus_cc_set"
5152 [(set (reg:CC_NOOV 100)
5153 (compare:CC_NOOV (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5154 (match_operand:SI 2 "arith_operand" "rI"))
5156 (set (match_operand:SI 0 "register_operand" "=r")
5157 (minus:SI (match_dup 1) (match_dup 2)))]
5159 "subcc\t%r1, %2, %0"
5160 [(set_attr "type" "compare")])
5162 (define_insn "*cmp_minus_ccx_set"
5163 [(set (reg:CCX_NOOV 100)
5164 (compare:CCX_NOOV (minus:DI (match_operand:DI 1 "register_operand" "r")
5165 (match_operand:DI 2 "arith_double_operand" "rHI"))
5167 (set (match_operand:DI 0 "register_operand" "=r")
5168 (minus:DI (match_dup 1) (match_dup 2)))]
5171 [(set_attr "type" "compare")])
5173 ;; Integer Multiply/Divide.
5175 ;; The 32 bit multiply/divide instructions are deprecated on v9, but at
5176 ;; least in UltraSPARC I, II and IIi it is a win tick-wise.
5178 (define_insn "mulsi3"
5179 [(set (match_operand:SI 0 "register_operand" "=r")
5180 (mult:SI (match_operand:SI 1 "arith_operand" "%r")
5181 (match_operand:SI 2 "arith_operand" "rI")))]
5184 [(set_attr "type" "imul")])
5186 (define_expand "muldi3"
5187 [(set (match_operand:DI 0 "register_operand" "=r")
5188 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r")
5189 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5190 "TARGET_ARCH64 || TARGET_V8PLUS"
5194 emit_insn (gen_muldi3_v8plus (operands[0], operands[1], operands[2]));
5199 (define_insn "*muldi3_sp64"
5200 [(set (match_operand:DI 0 "register_operand" "=r")
5201 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r")
5202 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5205 [(set_attr "type" "imul")])
5207 ;; V8plus wide multiply.
5209 (define_insn "muldi3_v8plus"
5210 [(set (match_operand:DI 0 "register_operand" "=r,h")
5211 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r,0")
5212 (match_operand:DI 2 "arith_double_operand" "rI,rI")))
5213 (clobber (match_scratch:SI 3 "=&h,X"))
5214 (clobber (match_scratch:SI 4 "=&h,X"))]
5217 if (sparc_check_64 (operands[1], insn) <= 0)
5218 output_asm_insn ("srl\t%L1, 0, %L1", operands);
5219 if (which_alternative == 1)
5220 output_asm_insn ("sllx\t%H1, 32, %H1", operands);
5221 if (GET_CODE (operands[2]) == CONST_INT)
5223 if (which_alternative == 1)
5224 return "or\t%L1, %H1, %H1\n\tmulx\t%H1, %2, %L0\;srlx\t%L0, 32, %H0";
5226 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";
5228 else if (rtx_equal_p (operands[1], operands[2]))
5230 if (which_alternative == 1)
5231 return "or\t%L1, %H1, %H1\n\tmulx\t%H1, %H1, %L0\;srlx\t%L0, 32, %H0";
5233 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";
5235 if (sparc_check_64 (operands[2], insn) <= 0)
5236 output_asm_insn ("srl\t%L2, 0, %L2", operands);
5237 if (which_alternative == 1)
5238 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";
5240 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";
5242 [(set_attr "type" "multi")
5243 (set_attr "length" "9,8")])
5245 (define_insn "*cmp_mul_set"
5247 (compare:CC (mult:SI (match_operand:SI 1 "arith_operand" "%r")
5248 (match_operand:SI 2 "arith_operand" "rI"))
5250 (set (match_operand:SI 0 "register_operand" "=r")
5251 (mult:SI (match_dup 1) (match_dup 2)))]
5252 "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS"
5253 "smulcc\t%1, %2, %0"
5254 [(set_attr "type" "imul")])
5256 (define_expand "mulsidi3"
5257 [(set (match_operand:DI 0 "register_operand" "")
5258 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
5259 (sign_extend:DI (match_operand:SI 2 "arith_operand" ""))))]
5262 if (CONSTANT_P (operands[2]))
5265 emit_insn (gen_const_mulsidi3_v8plus (operands[0], operands[1],
5267 else if (TARGET_ARCH32)
5268 emit_insn (gen_const_mulsidi3_sp32 (operands[0], operands[1],
5271 emit_insn (gen_const_mulsidi3_sp64 (operands[0], operands[1],
5277 emit_insn (gen_mulsidi3_v8plus (operands[0], operands[1], operands[2]));
5282 ;; V9 puts the 64 bit product in a 64 bit register. Only out or global
5283 ;; registers can hold 64 bit values in the V8plus environment.
5285 (define_insn "mulsidi3_v8plus"
5286 [(set (match_operand:DI 0 "register_operand" "=h,r")
5287 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5288 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
5289 (clobber (match_scratch:SI 3 "=X,&h"))]
5292 smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
5293 smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
5294 [(set_attr "type" "multi")
5295 (set_attr "length" "2,3")])
5298 (define_insn "const_mulsidi3_v8plus"
5299 [(set (match_operand:DI 0 "register_operand" "=h,r")
5300 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5301 (match_operand:DI 2 "small_int" "I,I")))
5302 (clobber (match_scratch:SI 3 "=X,&h"))]
5305 smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
5306 smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
5307 [(set_attr "type" "multi")
5308 (set_attr "length" "2,3")])
5311 (define_insn "*mulsidi3_sp32"
5312 [(set (match_operand:DI 0 "register_operand" "=r")
5313 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5314 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
5317 return TARGET_SPARCLET
5318 ? "smuld\t%1, %2, %L0"
5319 : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
5322 (if_then_else (eq_attr "isa" "sparclet")
5323 (const_string "imul") (const_string "multi")))
5324 (set (attr "length")
5325 (if_then_else (eq_attr "isa" "sparclet")
5326 (const_int 1) (const_int 2)))])
5328 (define_insn "*mulsidi3_sp64"
5329 [(set (match_operand:DI 0 "register_operand" "=r")
5330 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5331 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
5332 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5334 [(set_attr "type" "imul")])
5336 ;; Extra pattern, because sign_extend of a constant isn't valid.
5339 (define_insn "const_mulsidi3_sp32"
5340 [(set (match_operand:DI 0 "register_operand" "=r")
5341 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5342 (match_operand:DI 2 "small_int" "I")))]
5345 return TARGET_SPARCLET
5346 ? "smuld\t%1, %2, %L0"
5347 : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
5350 (if_then_else (eq_attr "isa" "sparclet")
5351 (const_string "imul") (const_string "multi")))
5352 (set (attr "length")
5353 (if_then_else (eq_attr "isa" "sparclet")
5354 (const_int 1) (const_int 2)))])
5356 (define_insn "const_mulsidi3_sp64"
5357 [(set (match_operand:DI 0 "register_operand" "=r")
5358 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5359 (match_operand:DI 2 "small_int" "I")))]
5360 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5362 [(set_attr "type" "imul")])
5364 (define_expand "smulsi3_highpart"
5365 [(set (match_operand:SI 0 "register_operand" "")
5367 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
5368 (sign_extend:DI (match_operand:SI 2 "arith_operand" "")))
5370 "TARGET_HARD_MUL && TARGET_ARCH32"
5372 if (CONSTANT_P (operands[2]))
5376 emit_insn (gen_const_smulsi3_highpart_v8plus (operands[0],
5382 emit_insn (gen_const_smulsi3_highpart (operands[0], operands[1], operands[2]));
5387 emit_insn (gen_smulsi3_highpart_v8plus (operands[0], operands[1],
5388 operands[2], GEN_INT (32)));
5394 (define_insn "smulsi3_highpart_v8plus"
5395 [(set (match_operand:SI 0 "register_operand" "=h,r")
5397 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5398 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
5399 (match_operand:SI 3 "const_int_operand" "i,i"))))
5400 (clobber (match_scratch:SI 4 "=X,&h"))]
5403 smul\t%1, %2, %0\;srlx\t%0, %3, %0
5404 smul\t%1, %2, %4\;srlx\t%4, %3, %0"
5405 [(set_attr "type" "multi")
5406 (set_attr "length" "2")])
5408 ;; The combiner changes TRUNCATE in the previous pattern to SUBREG.
5411 [(set (match_operand:SI 0 "register_operand" "=h,r")
5414 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5415 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
5416 (match_operand:SI 3 "const_int_operand" "i,i"))
5418 (clobber (match_scratch:SI 4 "=X,&h"))]
5421 smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
5422 smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
5423 [(set_attr "type" "multi")
5424 (set_attr "length" "2")])
5427 (define_insn "const_smulsi3_highpart_v8plus"
5428 [(set (match_operand:SI 0 "register_operand" "=h,r")
5430 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5431 (match_operand:DI 2 "small_int" "i,i"))
5432 (match_operand:SI 3 "const_int_operand" "i,i"))))
5433 (clobber (match_scratch:SI 4 "=X,&h"))]
5436 smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
5437 smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
5438 [(set_attr "type" "multi")
5439 (set_attr "length" "2")])
5442 (define_insn "*smulsi3_highpart_sp32"
5443 [(set (match_operand:SI 0 "register_operand" "=r")
5445 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5446 (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
5449 "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
5450 [(set_attr "type" "multi")
5451 (set_attr "length" "2")])
5454 (define_insn "const_smulsi3_highpart"
5455 [(set (match_operand:SI 0 "register_operand" "=r")
5457 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5458 (match_operand:DI 2 "small_int" "i"))
5461 "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
5462 [(set_attr "type" "multi")
5463 (set_attr "length" "2")])
5465 (define_expand "umulsidi3"
5466 [(set (match_operand:DI 0 "register_operand" "")
5467 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
5468 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" ""))))]
5471 if (CONSTANT_P (operands[2]))
5474 emit_insn (gen_const_umulsidi3_v8plus (operands[0], operands[1],
5476 else if (TARGET_ARCH32)
5477 emit_insn (gen_const_umulsidi3_sp32 (operands[0], operands[1],
5480 emit_insn (gen_const_umulsidi3_sp64 (operands[0], operands[1],
5486 emit_insn (gen_umulsidi3_v8plus (operands[0], operands[1], operands[2]));
5492 (define_insn "umulsidi3_v8plus"
5493 [(set (match_operand:DI 0 "register_operand" "=h,r")
5494 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5495 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
5496 (clobber (match_scratch:SI 3 "=X,&h"))]
5499 umul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
5500 umul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
5501 [(set_attr "type" "multi")
5502 (set_attr "length" "2,3")])
5505 (define_insn "*umulsidi3_sp32"
5506 [(set (match_operand:DI 0 "register_operand" "=r")
5507 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5508 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
5511 return TARGET_SPARCLET
5512 ? "umuld\t%1, %2, %L0"
5513 : "umul\t%1, %2, %L0\n\trd\t%%y, %H0";
5516 (if_then_else (eq_attr "isa" "sparclet")
5517 (const_string "imul") (const_string "multi")))
5518 (set (attr "length")
5519 (if_then_else (eq_attr "isa" "sparclet")
5520 (const_int 1) (const_int 2)))])
5522 (define_insn "*umulsidi3_sp64"
5523 [(set (match_operand:DI 0 "register_operand" "=r")
5524 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5525 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
5526 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5528 [(set_attr "type" "imul")])
5530 ;; Extra pattern, because sign_extend of a constant isn't valid.
5533 (define_insn "const_umulsidi3_sp32"
5534 [(set (match_operand:DI 0 "register_operand" "=r")
5535 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5536 (match_operand:DI 2 "uns_small_int" "")))]
5539 return TARGET_SPARCLET
5540 ? "umuld\t%1, %s2, %L0"
5541 : "umul\t%1, %s2, %L0\n\trd\t%%y, %H0";
5544 (if_then_else (eq_attr "isa" "sparclet")
5545 (const_string "imul") (const_string "multi")))
5546 (set (attr "length")
5547 (if_then_else (eq_attr "isa" "sparclet")
5548 (const_int 1) (const_int 2)))])
5550 (define_insn "const_umulsidi3_sp64"
5551 [(set (match_operand:DI 0 "register_operand" "=r")
5552 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5553 (match_operand:DI 2 "uns_small_int" "")))]
5554 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5556 [(set_attr "type" "imul")])
5559 (define_insn "const_umulsidi3_v8plus"
5560 [(set (match_operand:DI 0 "register_operand" "=h,r")
5561 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5562 (match_operand:DI 2 "uns_small_int" "")))
5563 (clobber (match_scratch:SI 3 "=X,h"))]
5566 umul\t%1, %s2, %L0\n\tsrlx\t%L0, 32, %H0
5567 umul\t%1, %s2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
5568 [(set_attr "type" "multi")
5569 (set_attr "length" "2,3")])
5571 (define_expand "umulsi3_highpart"
5572 [(set (match_operand:SI 0 "register_operand" "")
5574 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
5575 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" "")))
5577 "TARGET_HARD_MUL && TARGET_ARCH32"
5579 if (CONSTANT_P (operands[2]))
5583 emit_insn (gen_const_umulsi3_highpart_v8plus (operands[0],
5589 emit_insn (gen_const_umulsi3_highpart (operands[0], operands[1], operands[2]));
5594 emit_insn (gen_umulsi3_highpart_v8plus (operands[0], operands[1],
5595 operands[2], GEN_INT (32)));
5601 (define_insn "umulsi3_highpart_v8plus"
5602 [(set (match_operand:SI 0 "register_operand" "=h,r")
5604 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5605 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
5606 (match_operand:SI 3 "const_int_operand" "i,i"))))
5607 (clobber (match_scratch:SI 4 "=X,h"))]
5610 umul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
5611 umul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
5612 [(set_attr "type" "multi")
5613 (set_attr "length" "2")])
5616 (define_insn "const_umulsi3_highpart_v8plus"
5617 [(set (match_operand:SI 0 "register_operand" "=h,r")
5619 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5620 (match_operand:DI 2 "uns_small_int" ""))
5621 (match_operand:SI 3 "const_int_operand" "i,i"))))
5622 (clobber (match_scratch:SI 4 "=X,h"))]
5625 umul\t%1, %s2, %0\n\tsrlx\t%0, %3, %0
5626 umul\t%1, %s2, %4\n\tsrlx\t%4, %3, %0"
5627 [(set_attr "type" "multi")
5628 (set_attr "length" "2")])
5631 (define_insn "*umulsi3_highpart_sp32"
5632 [(set (match_operand:SI 0 "register_operand" "=r")
5634 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5635 (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
5638 "umul\t%1, %2, %%g0\n\trd\t%%y, %0"
5639 [(set_attr "type" "multi")
5640 (set_attr "length" "2")])
5643 (define_insn "const_umulsi3_highpart"
5644 [(set (match_operand:SI 0 "register_operand" "=r")
5646 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5647 (match_operand:DI 2 "uns_small_int" ""))
5650 "umul\t%1, %s2, %%g0\n\trd\t%%y, %0"
5651 [(set_attr "type" "multi")
5652 (set_attr "length" "2")])
5654 ;; The v8 architecture specifies that there must be 3 instructions between
5655 ;; a y register write and a use of it for correct results.
5657 (define_expand "divsi3"
5658 [(parallel [(set (match_operand:SI 0 "register_operand" "=r,r")
5659 (div:SI (match_operand:SI 1 "register_operand" "r,r")
5660 (match_operand:SI 2 "input_operand" "rI,m")))
5661 (clobber (match_scratch:SI 3 "=&r,&r"))])]
5662 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
5666 operands[3] = gen_reg_rtx(SImode);
5667 emit_insn (gen_ashrsi3 (operands[3], operands[1], GEN_INT (31)));
5668 emit_insn (gen_divsi3_sp64 (operands[0], operands[1], operands[2],
5674 (define_insn "divsi3_sp32"
5675 [(set (match_operand:SI 0 "register_operand" "=r,r")
5676 (div:SI (match_operand:SI 1 "register_operand" "r,r")
5677 (match_operand:SI 2 "input_operand" "rI,m")))
5678 (clobber (match_scratch:SI 3 "=&r,&r"))]
5679 "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS)
5682 if (which_alternative == 0)
5684 return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tsdiv\t%1, %2, %0";
5686 return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tnop\n\tnop\n\tnop\n\tsdiv\t%1, %2, %0";
5689 return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tld\t%2, %3\n\tsdiv\t%1, %3, %0";
5691 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";
5693 [(set_attr "type" "multi")
5694 (set (attr "length")
5695 (if_then_else (eq_attr "isa" "v9")
5696 (const_int 4) (const_int 6)))])
5698 (define_insn "divsi3_sp64"
5699 [(set (match_operand:SI 0 "register_operand" "=r")
5700 (div:SI (match_operand:SI 1 "register_operand" "r")
5701 (match_operand:SI 2 "input_operand" "rI")))
5702 (use (match_operand:SI 3 "register_operand" "r"))]
5703 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5704 "wr\t%%g0, %3, %%y\n\tsdiv\t%1, %2, %0"
5705 [(set_attr "type" "multi")
5706 (set_attr "length" "2")])
5708 (define_insn "divdi3"
5709 [(set (match_operand:DI 0 "register_operand" "=r")
5710 (div:DI (match_operand:DI 1 "register_operand" "r")
5711 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5714 [(set_attr "type" "idiv")])
5716 (define_insn "*cmp_sdiv_cc_set"
5718 (compare:CC (div:SI (match_operand:SI 1 "register_operand" "r")
5719 (match_operand:SI 2 "arith_operand" "rI"))
5721 (set (match_operand:SI 0 "register_operand" "=r")
5722 (div:SI (match_dup 1) (match_dup 2)))
5723 (clobber (match_scratch:SI 3 "=&r"))]
5724 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
5727 return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tsdivcc\t%1, %2, %0";
5729 return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tnop\n\tnop\n\tnop\n\tsdivcc\t%1, %2, %0";
5731 [(set_attr "type" "multi")
5732 (set (attr "length")
5733 (if_then_else (eq_attr "isa" "v9")
5734 (const_int 3) (const_int 6)))])
5737 (define_expand "udivsi3"
5738 [(set (match_operand:SI 0 "register_operand" "")
5739 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "")
5740 (match_operand:SI 2 "input_operand" "")))]
5741 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
5744 (define_insn "udivsi3_sp32"
5745 [(set (match_operand:SI 0 "register_operand" "=r,&r,&r")
5746 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "r,r,m")
5747 (match_operand:SI 2 "input_operand" "rI,m,r")))]
5749 || TARGET_DEPRECATED_V8_INSNS)
5752 output_asm_insn ("wr\t%%g0, %%g0, %%y", operands);
5753 switch (which_alternative)
5756 return "nop\n\tnop\n\tnop\n\tudiv\t%1, %2, %0";
5758 return "ld\t%2, %0\n\tnop\n\tnop\n\tudiv\t%1, %0, %0";
5760 return "ld\t%1, %0\n\tnop\n\tnop\n\tudiv\t%0, %2, %0";
5763 [(set_attr "type" "multi")
5764 (set_attr "length" "5")])
5766 (define_insn "udivsi3_sp64"
5767 [(set (match_operand:SI 0 "register_operand" "=r")
5768 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "r")
5769 (match_operand:SI 2 "input_operand" "rI")))]
5770 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5771 "wr\t%%g0, 0, %%y\n\tudiv\t%1, %2, %0"
5772 [(set_attr "type" "multi")
5773 (set_attr "length" "2")])
5775 (define_insn "udivdi3"
5776 [(set (match_operand:DI 0 "register_operand" "=r")
5777 (udiv:DI (match_operand:DI 1 "register_operand" "r")
5778 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5781 [(set_attr "type" "idiv")])
5783 (define_insn "*cmp_udiv_cc_set"
5785 (compare:CC (udiv:SI (match_operand:SI 1 "register_operand" "r")
5786 (match_operand:SI 2 "arith_operand" "rI"))
5788 (set (match_operand:SI 0 "register_operand" "=r")
5789 (udiv:SI (match_dup 1) (match_dup 2)))]
5791 || TARGET_DEPRECATED_V8_INSNS"
5794 return "wr\t%%g0, %%g0, %%y\n\tudivcc\t%1, %2, %0";
5796 return "wr\t%%g0, %%g0, %%y\n\tnop\n\tnop\n\tnop\n\tudivcc\t%1, %2, %0";
5798 [(set_attr "type" "multi")
5799 (set (attr "length")
5800 (if_then_else (eq_attr "isa" "v9")
5801 (const_int 2) (const_int 5)))])
5803 ; sparclet multiply/accumulate insns
5805 (define_insn "*smacsi"
5806 [(set (match_operand:SI 0 "register_operand" "=r")
5807 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "%r")
5808 (match_operand:SI 2 "arith_operand" "rI"))
5809 (match_operand:SI 3 "register_operand" "0")))]
5812 [(set_attr "type" "imul")])
5814 (define_insn "*smacdi"
5815 [(set (match_operand:DI 0 "register_operand" "=r")
5816 (plus:DI (mult:DI (sign_extend:DI
5817 (match_operand:SI 1 "register_operand" "%r"))
5819 (match_operand:SI 2 "register_operand" "r")))
5820 (match_operand:DI 3 "register_operand" "0")))]
5822 "smacd\t%1, %2, %L0"
5823 [(set_attr "type" "imul")])
5825 (define_insn "*umacdi"
5826 [(set (match_operand:DI 0 "register_operand" "=r")
5827 (plus:DI (mult:DI (zero_extend:DI
5828 (match_operand:SI 1 "register_operand" "%r"))
5830 (match_operand:SI 2 "register_operand" "r")))
5831 (match_operand:DI 3 "register_operand" "0")))]
5833 "umacd\t%1, %2, %L0"
5834 [(set_attr "type" "imul")])
5836 ;;- Boolean instructions
5837 ;; We define DImode `and' so with DImode `not' we can get
5838 ;; DImode `andn'. Other combinations are possible.
5840 (define_expand "anddi3"
5841 [(set (match_operand:DI 0 "register_operand" "")
5842 (and:DI (match_operand:DI 1 "arith_double_operand" "")
5843 (match_operand:DI 2 "arith_double_operand" "")))]
5847 (define_insn "*anddi3_sp32"
5848 [(set (match_operand:DI 0 "register_operand" "=r,b")
5849 (and:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
5850 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
5855 [(set_attr "type" "*,fp")
5856 (set_attr "length" "2,*")
5857 (set_attr "fptype" "double")])
5859 (define_insn "*anddi3_sp64"
5860 [(set (match_operand:DI 0 "register_operand" "=r,b")
5861 (and:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
5862 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
5867 [(set_attr "type" "*,fp")
5868 (set_attr "fptype" "double")])
5870 (define_insn "andsi3"
5871 [(set (match_operand:SI 0 "register_operand" "=r,d")
5872 (and:SI (match_operand:SI 1 "arith_operand" "%r,d")
5873 (match_operand:SI 2 "arith_operand" "rI,d")))]
5878 [(set_attr "type" "*,fp")])
5881 [(set (match_operand:SI 0 "register_operand" "")
5882 (and:SI (match_operand:SI 1 "register_operand" "")
5883 (match_operand:SI 2 "" "")))
5884 (clobber (match_operand:SI 3 "register_operand" ""))]
5885 "GET_CODE (operands[2]) == CONST_INT
5886 && !SMALL_INT32 (operands[2])
5887 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
5888 [(set (match_dup 3) (match_dup 4))
5889 (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 1)))]
5891 operands[4] = GEN_INT (~INTVAL (operands[2]));
5894 ;; Split DImode logical operations requiring two instructions.
5896 [(set (match_operand:DI 0 "register_operand" "")
5897 (match_operator:DI 1 "cc_arithop" ; AND, IOR, XOR
5898 [(match_operand:DI 2 "register_operand" "")
5899 (match_operand:DI 3 "arith_double_operand" "")]))]
5902 && ((GET_CODE (operands[0]) == REG
5903 && REGNO (operands[0]) < 32)
5904 || (GET_CODE (operands[0]) == SUBREG
5905 && GET_CODE (SUBREG_REG (operands[0])) == REG
5906 && REGNO (SUBREG_REG (operands[0])) < 32))"
5907 [(set (match_dup 4) (match_op_dup:SI 1 [(match_dup 6) (match_dup 8)]))
5908 (set (match_dup 5) (match_op_dup:SI 1 [(match_dup 7) (match_dup 9)]))]
5910 operands[4] = gen_highpart (SImode, operands[0]);
5911 operands[5] = gen_lowpart (SImode, operands[0]);
5912 operands[6] = gen_highpart (SImode, operands[2]);
5913 operands[7] = gen_lowpart (SImode, operands[2]);
5914 #if HOST_BITS_PER_WIDE_INT == 32
5915 if (GET_CODE (operands[3]) == CONST_INT)
5917 if (INTVAL (operands[3]) < 0)
5918 operands[8] = constm1_rtx;
5920 operands[8] = const0_rtx;
5924 operands[8] = gen_highpart_mode (SImode, DImode, operands[3]);
5925 operands[9] = gen_lowpart (SImode, operands[3]);
5928 (define_insn_and_split "*and_not_di_sp32"
5929 [(set (match_operand:DI 0 "register_operand" "=r,b")
5930 (and:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
5931 (match_operand:DI 2 "register_operand" "r,b")))]
5935 fandnot1\t%1, %2, %0"
5936 "&& reload_completed
5937 && ((GET_CODE (operands[0]) == REG
5938 && REGNO (operands[0]) < 32)
5939 || (GET_CODE (operands[0]) == SUBREG
5940 && GET_CODE (SUBREG_REG (operands[0])) == REG
5941 && REGNO (SUBREG_REG (operands[0])) < 32))"
5942 [(set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))
5943 (set (match_dup 6) (and:SI (not:SI (match_dup 7)) (match_dup 8)))]
5944 "operands[3] = gen_highpart (SImode, operands[0]);
5945 operands[4] = gen_highpart (SImode, operands[1]);
5946 operands[5] = gen_highpart (SImode, operands[2]);
5947 operands[6] = gen_lowpart (SImode, operands[0]);
5948 operands[7] = gen_lowpart (SImode, operands[1]);
5949 operands[8] = gen_lowpart (SImode, operands[2]);"
5950 [(set_attr "type" "*,fp")
5951 (set_attr "length" "2,*")
5952 (set_attr "fptype" "double")])
5954 (define_insn "*and_not_di_sp64"
5955 [(set (match_operand:DI 0 "register_operand" "=r,b")
5956 (and:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
5957 (match_operand:DI 2 "register_operand" "r,b")))]
5961 fandnot1\t%1, %2, %0"
5962 [(set_attr "type" "*,fp")
5963 (set_attr "fptype" "double")])
5965 (define_insn "*and_not_si"
5966 [(set (match_operand:SI 0 "register_operand" "=r,d")
5967 (and:SI (not:SI (match_operand:SI 1 "register_operand" "r,d"))
5968 (match_operand:SI 2 "register_operand" "r,d")))]
5972 fandnot1s\t%1, %2, %0"
5973 [(set_attr "type" "*,fp")])
5975 (define_expand "iordi3"
5976 [(set (match_operand:DI 0 "register_operand" "")
5977 (ior:DI (match_operand:DI 1 "arith_double_operand" "")
5978 (match_operand:DI 2 "arith_double_operand" "")))]
5982 (define_insn "*iordi3_sp32"
5983 [(set (match_operand:DI 0 "register_operand" "=r,b")
5984 (ior:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
5985 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
5990 [(set_attr "type" "*,fp")
5991 (set_attr "length" "2,*")
5992 (set_attr "fptype" "double")])
5994 (define_insn "*iordi3_sp64"
5995 [(set (match_operand:DI 0 "register_operand" "=r,b")
5996 (ior:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
5997 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6002 [(set_attr "type" "*,fp")
6003 (set_attr "fptype" "double")])
6005 (define_insn "iorsi3"
6006 [(set (match_operand:SI 0 "register_operand" "=r,d")
6007 (ior:SI (match_operand:SI 1 "arith_operand" "%r,d")
6008 (match_operand:SI 2 "arith_operand" "rI,d")))]
6013 [(set_attr "type" "*,fp")])
6016 [(set (match_operand:SI 0 "register_operand" "")
6017 (ior:SI (match_operand:SI 1 "register_operand" "")
6018 (match_operand:SI 2 "" "")))
6019 (clobber (match_operand:SI 3 "register_operand" ""))]
6020 "GET_CODE (operands[2]) == CONST_INT
6021 && !SMALL_INT32 (operands[2])
6022 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6023 [(set (match_dup 3) (match_dup 4))
6024 (set (match_dup 0) (ior:SI (not:SI (match_dup 3)) (match_dup 1)))]
6026 operands[4] = GEN_INT (~INTVAL (operands[2]));
6029 (define_insn_and_split "*or_not_di_sp32"
6030 [(set (match_operand:DI 0 "register_operand" "=r,b")
6031 (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6032 (match_operand:DI 2 "register_operand" "r,b")))]
6036 fornot1\t%1, %2, %0"
6037 "&& reload_completed
6038 && ((GET_CODE (operands[0]) == REG
6039 && REGNO (operands[0]) < 32)
6040 || (GET_CODE (operands[0]) == SUBREG
6041 && GET_CODE (SUBREG_REG (operands[0])) == REG
6042 && REGNO (SUBREG_REG (operands[0])) < 32))"
6043 [(set (match_dup 3) (ior:SI (not:SI (match_dup 4)) (match_dup 5)))
6044 (set (match_dup 6) (ior:SI (not:SI (match_dup 7)) (match_dup 8)))]
6045 "operands[3] = gen_highpart (SImode, operands[0]);
6046 operands[4] = gen_highpart (SImode, operands[1]);
6047 operands[5] = gen_highpart (SImode, operands[2]);
6048 operands[6] = gen_lowpart (SImode, operands[0]);
6049 operands[7] = gen_lowpart (SImode, operands[1]);
6050 operands[8] = gen_lowpart (SImode, operands[2]);"
6051 [(set_attr "type" "*,fp")
6052 (set_attr "length" "2,*")
6053 (set_attr "fptype" "double")])
6055 (define_insn "*or_not_di_sp64"
6056 [(set (match_operand:DI 0 "register_operand" "=r,b")
6057 (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6058 (match_operand:DI 2 "register_operand" "r,b")))]
6062 fornot1\t%1, %2, %0"
6063 [(set_attr "type" "*,fp")
6064 (set_attr "fptype" "double")])
6066 (define_insn "*or_not_si"
6067 [(set (match_operand:SI 0 "register_operand" "=r,d")
6068 (ior:SI (not:SI (match_operand:SI 1 "register_operand" "r,d"))
6069 (match_operand:SI 2 "register_operand" "r,d")))]
6073 fornot1s\t%1, %2, %0"
6074 [(set_attr "type" "*,fp")])
6076 (define_expand "xordi3"
6077 [(set (match_operand:DI 0 "register_operand" "")
6078 (xor:DI (match_operand:DI 1 "arith_double_operand" "")
6079 (match_operand:DI 2 "arith_double_operand" "")))]
6083 (define_insn "*xordi3_sp32"
6084 [(set (match_operand:DI 0 "register_operand" "=r,b")
6085 (xor:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6086 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6091 [(set_attr "type" "*,fp")
6092 (set_attr "length" "2,*")
6093 (set_attr "fptype" "double")])
6095 (define_insn "*xordi3_sp64"
6096 [(set (match_operand:DI 0 "register_operand" "=r,b")
6097 (xor:DI (match_operand:DI 1 "arith_double_operand" "%rJ,b")
6098 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6103 [(set_attr "type" "*,fp")
6104 (set_attr "fptype" "double")])
6106 (define_insn "*xordi3_sp64_dbl"
6107 [(set (match_operand:DI 0 "register_operand" "=r")
6108 (xor:DI (match_operand:DI 1 "register_operand" "r")
6109 (match_operand:DI 2 "const64_operand" "")))]
6111 && HOST_BITS_PER_WIDE_INT != 64)"
6114 (define_insn "xorsi3"
6115 [(set (match_operand:SI 0 "register_operand" "=r,d")
6116 (xor:SI (match_operand:SI 1 "arith_operand" "%rJ,d")
6117 (match_operand:SI 2 "arith_operand" "rI,d")))]
6122 [(set_attr "type" "*,fp")])
6125 [(set (match_operand:SI 0 "register_operand" "")
6126 (xor:SI (match_operand:SI 1 "register_operand" "")
6127 (match_operand:SI 2 "" "")))
6128 (clobber (match_operand:SI 3 "register_operand" ""))]
6129 "GET_CODE (operands[2]) == CONST_INT
6130 && !SMALL_INT32 (operands[2])
6131 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6132 [(set (match_dup 3) (match_dup 4))
6133 (set (match_dup 0) (not:SI (xor:SI (match_dup 3) (match_dup 1))))]
6135 operands[4] = GEN_INT (~INTVAL (operands[2]));
6139 [(set (match_operand:SI 0 "register_operand" "")
6140 (not:SI (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) (xor:SI (match_dup 3) (match_dup 1)))]
6149 operands[4] = GEN_INT (~INTVAL (operands[2]));
6152 ;; xnor patterns. Note that (a ^ ~b) == (~a ^ b) == ~(a ^ b).
6153 ;; Combine now canonicalizes to the rightmost expression.
6154 (define_insn_and_split "*xor_not_di_sp32"
6155 [(set (match_operand:DI 0 "register_operand" "=r,b")
6156 (not:DI (xor:DI (match_operand:DI 1 "register_operand" "r,b")
6157 (match_operand:DI 2 "register_operand" "r,b"))))]
6162 "&& reload_completed
6163 && ((GET_CODE (operands[0]) == REG
6164 && REGNO (operands[0]) < 32)
6165 || (GET_CODE (operands[0]) == SUBREG
6166 && GET_CODE (SUBREG_REG (operands[0])) == REG
6167 && REGNO (SUBREG_REG (operands[0])) < 32))"
6168 [(set (match_dup 3) (not:SI (xor:SI (match_dup 4) (match_dup 5))))
6169 (set (match_dup 6) (not:SI (xor:SI (match_dup 7) (match_dup 8))))]
6170 "operands[3] = gen_highpart (SImode, operands[0]);
6171 operands[4] = gen_highpart (SImode, operands[1]);
6172 operands[5] = gen_highpart (SImode, operands[2]);
6173 operands[6] = gen_lowpart (SImode, operands[0]);
6174 operands[7] = gen_lowpart (SImode, operands[1]);
6175 operands[8] = gen_lowpart (SImode, operands[2]);"
6176 [(set_attr "type" "*,fp")
6177 (set_attr "length" "2,*")
6178 (set_attr "fptype" "double")])
6180 (define_insn "*xor_not_di_sp64"
6181 [(set (match_operand:DI 0 "register_operand" "=r,b")
6182 (not:DI (xor:DI (match_operand:DI 1 "reg_or_0_operand" "rJ,b")
6183 (match_operand:DI 2 "arith_double_operand" "rHI,b"))))]
6188 [(set_attr "type" "*,fp")
6189 (set_attr "fptype" "double")])
6191 (define_insn "*xor_not_si"
6192 [(set (match_operand:SI 0 "register_operand" "=r,d")
6193 (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "rJ,d")
6194 (match_operand:SI 2 "arith_operand" "rI,d"))))]
6199 [(set_attr "type" "*,fp")])
6201 ;; These correspond to the above in the case where we also (or only)
6202 ;; want to set the condition code.
6204 (define_insn "*cmp_cc_arith_op"
6207 (match_operator:SI 2 "cc_arithop"
6208 [(match_operand:SI 0 "arith_operand" "%r")
6209 (match_operand:SI 1 "arith_operand" "rI")])
6212 "%A2cc\t%0, %1, %%g0"
6213 [(set_attr "type" "compare")])
6215 (define_insn "*cmp_ccx_arith_op"
6218 (match_operator:DI 2 "cc_arithop"
6219 [(match_operand:DI 0 "arith_double_operand" "%r")
6220 (match_operand:DI 1 "arith_double_operand" "rHI")])
6223 "%A2cc\t%0, %1, %%g0"
6224 [(set_attr "type" "compare")])
6226 (define_insn "*cmp_cc_arith_op_set"
6229 (match_operator:SI 3 "cc_arithop"
6230 [(match_operand:SI 1 "arith_operand" "%r")
6231 (match_operand:SI 2 "arith_operand" "rI")])
6233 (set (match_operand:SI 0 "register_operand" "=r")
6234 (match_operator:SI 4 "cc_arithop" [(match_dup 1) (match_dup 2)]))]
6235 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
6237 [(set_attr "type" "compare")])
6239 (define_insn "*cmp_ccx_arith_op_set"
6242 (match_operator:DI 3 "cc_arithop"
6243 [(match_operand:DI 1 "arith_double_operand" "%r")
6244 (match_operand:DI 2 "arith_double_operand" "rHI")])
6246 (set (match_operand:DI 0 "register_operand" "=r")
6247 (match_operator:DI 4 "cc_arithop" [(match_dup 1) (match_dup 2)]))]
6248 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
6250 [(set_attr "type" "compare")])
6252 (define_insn "*cmp_cc_xor_not"
6255 (not:SI (xor:SI (match_operand:SI 0 "reg_or_0_operand" "%rJ")
6256 (match_operand:SI 1 "arith_operand" "rI")))
6259 "xnorcc\t%r0, %1, %%g0"
6260 [(set_attr "type" "compare")])
6262 (define_insn "*cmp_ccx_xor_not"
6265 (not:DI (xor:DI (match_operand:DI 0 "reg_or_0_operand" "%rJ")
6266 (match_operand:DI 1 "arith_double_operand" "rHI")))
6269 "xnorcc\t%r0, %1, %%g0"
6270 [(set_attr "type" "compare")])
6272 (define_insn "*cmp_cc_xor_not_set"
6275 (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
6276 (match_operand:SI 2 "arith_operand" "rI")))
6278 (set (match_operand:SI 0 "register_operand" "=r")
6279 (not:SI (xor:SI (match_dup 1) (match_dup 2))))]
6281 "xnorcc\t%r1, %2, %0"
6282 [(set_attr "type" "compare")])
6284 (define_insn "*cmp_ccx_xor_not_set"
6287 (not:DI (xor:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ")
6288 (match_operand:DI 2 "arith_double_operand" "rHI")))
6290 (set (match_operand:DI 0 "register_operand" "=r")
6291 (not:DI (xor:DI (match_dup 1) (match_dup 2))))]
6293 "xnorcc\t%r1, %2, %0"
6294 [(set_attr "type" "compare")])
6296 (define_insn "*cmp_cc_arith_op_not"
6299 (match_operator:SI 2 "cc_arithopn"
6300 [(not:SI (match_operand:SI 0 "arith_operand" "rI"))
6301 (match_operand:SI 1 "reg_or_0_operand" "rJ")])
6304 "%B2cc\t%r1, %0, %%g0"
6305 [(set_attr "type" "compare")])
6307 (define_insn "*cmp_ccx_arith_op_not"
6310 (match_operator:DI 2 "cc_arithopn"
6311 [(not:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
6312 (match_operand:DI 1 "reg_or_0_operand" "rJ")])
6315 "%B2cc\t%r1, %0, %%g0"
6316 [(set_attr "type" "compare")])
6318 (define_insn "*cmp_cc_arith_op_not_set"
6321 (match_operator:SI 3 "cc_arithopn"
6322 [(not:SI (match_operand:SI 1 "arith_operand" "rI"))
6323 (match_operand:SI 2 "reg_or_0_operand" "rJ")])
6325 (set (match_operand:SI 0 "register_operand" "=r")
6326 (match_operator:SI 4 "cc_arithopn"
6327 [(not:SI (match_dup 1)) (match_dup 2)]))]
6328 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
6329 "%B3cc\t%r2, %1, %0"
6330 [(set_attr "type" "compare")])
6332 (define_insn "*cmp_ccx_arith_op_not_set"
6335 (match_operator:DI 3 "cc_arithopn"
6336 [(not:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
6337 (match_operand:DI 2 "reg_or_0_operand" "rJ")])
6339 (set (match_operand:DI 0 "register_operand" "=r")
6340 (match_operator:DI 4 "cc_arithopn"
6341 [(not:DI (match_dup 1)) (match_dup 2)]))]
6342 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
6343 "%B3cc\t%r2, %1, %0"
6344 [(set_attr "type" "compare")])
6346 ;; We cannot use the "neg" pseudo insn because the Sun assembler
6347 ;; does not know how to make it work for constants.
6349 (define_expand "negdi2"
6350 [(set (match_operand:DI 0 "register_operand" "=r")
6351 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
6354 if (! TARGET_ARCH64)
6356 emit_insn (gen_rtx_PARALLEL
6359 gen_rtx_SET (VOIDmode, operand0,
6360 gen_rtx_NEG (DImode, operand1)),
6361 gen_rtx_CLOBBER (VOIDmode,
6362 gen_rtx_REG (CCmode,
6368 (define_insn_and_split "*negdi2_sp32"
6369 [(set (match_operand:DI 0 "register_operand" "=r")
6370 (neg:DI (match_operand:DI 1 "register_operand" "r")))
6371 (clobber (reg:CC 100))]
6374 "&& reload_completed"
6375 [(parallel [(set (reg:CC_NOOV 100)
6376 (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 5))
6378 (set (match_dup 4) (minus:SI (const_int 0) (match_dup 5)))])
6379 (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
6380 (ltu:SI (reg:CC 100) (const_int 0))))]
6381 "operands[2] = gen_highpart (SImode, operands[0]);
6382 operands[3] = gen_highpart (SImode, operands[1]);
6383 operands[4] = gen_lowpart (SImode, operands[0]);
6384 operands[5] = gen_lowpart (SImode, operands[1]);"
6385 [(set_attr "length" "2")])
6387 (define_insn "*negdi2_sp64"
6388 [(set (match_operand:DI 0 "register_operand" "=r")
6389 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
6391 "sub\t%%g0, %1, %0")
6393 (define_insn "negsi2"
6394 [(set (match_operand:SI 0 "register_operand" "=r")
6395 (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
6397 "sub\t%%g0, %1, %0")
6399 (define_insn "*cmp_cc_neg"
6400 [(set (reg:CC_NOOV 100)
6401 (compare:CC_NOOV (neg:SI (match_operand:SI 0 "arith_operand" "rI"))
6404 "subcc\t%%g0, %0, %%g0"
6405 [(set_attr "type" "compare")])
6407 (define_insn "*cmp_ccx_neg"
6408 [(set (reg:CCX_NOOV 100)
6409 (compare:CCX_NOOV (neg:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
6412 "subcc\t%%g0, %0, %%g0"
6413 [(set_attr "type" "compare")])
6415 (define_insn "*cmp_cc_set_neg"
6416 [(set (reg:CC_NOOV 100)
6417 (compare:CC_NOOV (neg:SI (match_operand:SI 1 "arith_operand" "rI"))
6419 (set (match_operand:SI 0 "register_operand" "=r")
6420 (neg:SI (match_dup 1)))]
6422 "subcc\t%%g0, %1, %0"
6423 [(set_attr "type" "compare")])
6425 (define_insn "*cmp_ccx_set_neg"
6426 [(set (reg:CCX_NOOV 100)
6427 (compare:CCX_NOOV (neg:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
6429 (set (match_operand:DI 0 "register_operand" "=r")
6430 (neg:DI (match_dup 1)))]
6432 "subcc\t%%g0, %1, %0"
6433 [(set_attr "type" "compare")])
6435 ;; We cannot use the "not" pseudo insn because the Sun assembler
6436 ;; does not know how to make it work for constants.
6437 (define_expand "one_cmpldi2"
6438 [(set (match_operand:DI 0 "register_operand" "")
6439 (not:DI (match_operand:DI 1 "register_operand" "")))]
6443 (define_insn_and_split "*one_cmpldi2_sp32"
6444 [(set (match_operand:DI 0 "register_operand" "=r,b")
6445 (not:DI (match_operand:DI 1 "register_operand" "r,b")))]
6450 "&& reload_completed
6451 && ((GET_CODE (operands[0]) == REG
6452 && REGNO (operands[0]) < 32)
6453 || (GET_CODE (operands[0]) == SUBREG
6454 && GET_CODE (SUBREG_REG (operands[0])) == REG
6455 && REGNO (SUBREG_REG (operands[0])) < 32))"
6456 [(set (match_dup 2) (not:SI (xor:SI (match_dup 3) (const_int 0))))
6457 (set (match_dup 4) (not:SI (xor:SI (match_dup 5) (const_int 0))))]
6458 "operands[2] = gen_highpart (SImode, operands[0]);
6459 operands[3] = gen_highpart (SImode, operands[1]);
6460 operands[4] = gen_lowpart (SImode, operands[0]);
6461 operands[5] = gen_lowpart (SImode, operands[1]);"
6462 [(set_attr "type" "*,fp")
6463 (set_attr "length" "2,*")
6464 (set_attr "fptype" "double")])
6466 (define_insn "*one_cmpldi2_sp64"
6467 [(set (match_operand:DI 0 "register_operand" "=r,b")
6468 (not:DI (match_operand:DI 1 "arith_double_operand" "rHI,b")))]
6473 [(set_attr "type" "*,fp")
6474 (set_attr "fptype" "double")])
6476 (define_insn "one_cmplsi2"
6477 [(set (match_operand:SI 0 "register_operand" "=r,d")
6478 (not:SI (match_operand:SI 1 "arith_operand" "rI,d")))]
6483 [(set_attr "type" "*,fp")])
6485 (define_insn "*cmp_cc_not"
6487 (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI"))
6490 "xnorcc\t%%g0, %0, %%g0"
6491 [(set_attr "type" "compare")])
6493 (define_insn "*cmp_ccx_not"
6495 (compare:CCX (not:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
6498 "xnorcc\t%%g0, %0, %%g0"
6499 [(set_attr "type" "compare")])
6501 (define_insn "*cmp_cc_set_not"
6503 (compare:CC (not:SI (match_operand:SI 1 "arith_operand" "rI"))
6505 (set (match_operand:SI 0 "register_operand" "=r")
6506 (not:SI (match_dup 1)))]
6508 "xnorcc\t%%g0, %1, %0"
6509 [(set_attr "type" "compare")])
6511 (define_insn "*cmp_ccx_set_not"
6513 (compare:CCX (not:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
6515 (set (match_operand:DI 0 "register_operand" "=r")
6516 (not:DI (match_dup 1)))]
6518 "xnorcc\t%%g0, %1, %0"
6519 [(set_attr "type" "compare")])
6521 (define_insn "*cmp_cc_set"
6522 [(set (match_operand:SI 0 "register_operand" "=r")
6523 (match_operand:SI 1 "register_operand" "r"))
6525 (compare:CC (match_dup 1)
6529 [(set_attr "type" "compare")])
6531 (define_insn "*cmp_ccx_set64"
6532 [(set (match_operand:DI 0 "register_operand" "=r")
6533 (match_operand:DI 1 "register_operand" "r"))
6535 (compare:CCX (match_dup 1)
6539 [(set_attr "type" "compare")])
6541 ;; Floating point arithmetic instructions.
6543 (define_expand "addtf3"
6544 [(set (match_operand:TF 0 "nonimmediate_operand" "")
6545 (plus:TF (match_operand:TF 1 "general_operand" "")
6546 (match_operand:TF 2 "general_operand" "")))]
6547 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6548 "emit_tfmode_binop (PLUS, operands); DONE;")
6550 (define_insn "*addtf3_hq"
6551 [(set (match_operand:TF 0 "register_operand" "=e")
6552 (plus:TF (match_operand:TF 1 "register_operand" "e")
6553 (match_operand:TF 2 "register_operand" "e")))]
6554 "TARGET_FPU && TARGET_HARD_QUAD"
6556 [(set_attr "type" "fp")])
6558 (define_insn "adddf3"
6559 [(set (match_operand:DF 0 "register_operand" "=e")
6560 (plus:DF (match_operand:DF 1 "register_operand" "e")
6561 (match_operand:DF 2 "register_operand" "e")))]
6564 [(set_attr "type" "fp")
6565 (set_attr "fptype" "double")])
6567 (define_insn "addsf3"
6568 [(set (match_operand:SF 0 "register_operand" "=f")
6569 (plus:SF (match_operand:SF 1 "register_operand" "f")
6570 (match_operand:SF 2 "register_operand" "f")))]
6573 [(set_attr "type" "fp")])
6575 (define_expand "subtf3"
6576 [(set (match_operand:TF 0 "nonimmediate_operand" "")
6577 (minus:TF (match_operand:TF 1 "general_operand" "")
6578 (match_operand:TF 2 "general_operand" "")))]
6579 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6580 "emit_tfmode_binop (MINUS, operands); DONE;")
6582 (define_insn "*subtf3_hq"
6583 [(set (match_operand:TF 0 "register_operand" "=e")
6584 (minus:TF (match_operand:TF 1 "register_operand" "e")
6585 (match_operand:TF 2 "register_operand" "e")))]
6586 "TARGET_FPU && TARGET_HARD_QUAD"
6588 [(set_attr "type" "fp")])
6590 (define_insn "subdf3"
6591 [(set (match_operand:DF 0 "register_operand" "=e")
6592 (minus:DF (match_operand:DF 1 "register_operand" "e")
6593 (match_operand:DF 2 "register_operand" "e")))]
6596 [(set_attr "type" "fp")
6597 (set_attr "fptype" "double")])
6599 (define_insn "subsf3"
6600 [(set (match_operand:SF 0 "register_operand" "=f")
6601 (minus:SF (match_operand:SF 1 "register_operand" "f")
6602 (match_operand:SF 2 "register_operand" "f")))]
6605 [(set_attr "type" "fp")])
6607 (define_expand "multf3"
6608 [(set (match_operand:TF 0 "nonimmediate_operand" "")
6609 (mult:TF (match_operand:TF 1 "general_operand" "")
6610 (match_operand:TF 2 "general_operand" "")))]
6611 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6612 "emit_tfmode_binop (MULT, operands); DONE;")
6614 (define_insn "*multf3_hq"
6615 [(set (match_operand:TF 0 "register_operand" "=e")
6616 (mult:TF (match_operand:TF 1 "register_operand" "e")
6617 (match_operand:TF 2 "register_operand" "e")))]
6618 "TARGET_FPU && TARGET_HARD_QUAD"
6620 [(set_attr "type" "fpmul")])
6622 (define_insn "muldf3"
6623 [(set (match_operand:DF 0 "register_operand" "=e")
6624 (mult:DF (match_operand:DF 1 "register_operand" "e")
6625 (match_operand:DF 2 "register_operand" "e")))]
6628 [(set_attr "type" "fpmul")
6629 (set_attr "fptype" "double")])
6631 (define_insn "mulsf3"
6632 [(set (match_operand:SF 0 "register_operand" "=f")
6633 (mult:SF (match_operand:SF 1 "register_operand" "f")
6634 (match_operand:SF 2 "register_operand" "f")))]
6637 [(set_attr "type" "fpmul")])
6639 (define_insn "*muldf3_extend"
6640 [(set (match_operand:DF 0 "register_operand" "=e")
6641 (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "f"))
6642 (float_extend:DF (match_operand:SF 2 "register_operand" "f"))))]
6643 "(TARGET_V8 || TARGET_V9) && TARGET_FPU"
6644 "fsmuld\t%1, %2, %0"
6645 [(set_attr "type" "fpmul")
6646 (set_attr "fptype" "double")])
6648 (define_insn "*multf3_extend"
6649 [(set (match_operand:TF 0 "register_operand" "=e")
6650 (mult:TF (float_extend:TF (match_operand:DF 1 "register_operand" "e"))
6651 (float_extend:TF (match_operand:DF 2 "register_operand" "e"))))]
6652 "(TARGET_V8 || TARGET_V9) && TARGET_FPU && TARGET_HARD_QUAD"
6653 "fdmulq\t%1, %2, %0"
6654 [(set_attr "type" "fpmul")])
6656 (define_expand "divtf3"
6657 [(set (match_operand:TF 0 "nonimmediate_operand" "")
6658 (div:TF (match_operand:TF 1 "general_operand" "")
6659 (match_operand:TF 2 "general_operand" "")))]
6660 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6661 "emit_tfmode_binop (DIV, operands); DONE;")
6663 ;; don't have timing for quad-prec. divide.
6664 (define_insn "*divtf3_hq"
6665 [(set (match_operand:TF 0 "register_operand" "=e")
6666 (div:TF (match_operand:TF 1 "register_operand" "e")
6667 (match_operand:TF 2 "register_operand" "e")))]
6668 "TARGET_FPU && TARGET_HARD_QUAD"
6670 [(set_attr "type" "fpdivd")])
6672 (define_insn "divdf3"
6673 [(set (match_operand:DF 0 "register_operand" "=e")
6674 (div:DF (match_operand:DF 1 "register_operand" "e")
6675 (match_operand:DF 2 "register_operand" "e")))]
6678 [(set_attr "type" "fpdivd")
6679 (set_attr "fptype" "double")])
6681 (define_insn "divsf3"
6682 [(set (match_operand:SF 0 "register_operand" "=f")
6683 (div:SF (match_operand:SF 1 "register_operand" "f")
6684 (match_operand:SF 2 "register_operand" "f")))]
6687 [(set_attr "type" "fpdivs")])
6689 (define_expand "negtf2"
6690 [(set (match_operand:TF 0 "register_operand" "=e,e")
6691 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
6695 (define_insn_and_split "*negtf2_notv9"
6696 [(set (match_operand:TF 0 "register_operand" "=e,e")
6697 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
6698 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
6704 "&& reload_completed
6705 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6706 [(set (match_dup 2) (neg:SF (match_dup 3)))
6707 (set (match_dup 4) (match_dup 5))
6708 (set (match_dup 6) (match_dup 7))]
6709 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6710 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6711 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6712 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
6713 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6714 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6715 [(set_attr "type" "fpmove,*")
6716 (set_attr "length" "*,2")])
6718 (define_insn_and_split "*negtf2_v9"
6719 [(set (match_operand:TF 0 "register_operand" "=e,e")
6720 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
6721 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
6722 "TARGET_FPU && TARGET_V9"
6726 "&& reload_completed
6727 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6728 [(set (match_dup 2) (neg:DF (match_dup 3)))
6729 (set (match_dup 4) (match_dup 5))]
6730 "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
6731 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
6732 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6733 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6734 [(set_attr "type" "fpmove,*")
6735 (set_attr "length" "*,2")
6736 (set_attr "fptype" "double")])
6738 (define_expand "negdf2"
6739 [(set (match_operand:DF 0 "register_operand" "")
6740 (neg:DF (match_operand:DF 1 "register_operand" "")))]
6744 (define_insn_and_split "*negdf2_notv9"
6745 [(set (match_operand:DF 0 "register_operand" "=e,e")
6746 (neg:DF (match_operand:DF 1 "register_operand" "0,e")))]
6747 "TARGET_FPU && ! TARGET_V9"
6751 "&& reload_completed
6752 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6753 [(set (match_dup 2) (neg:SF (match_dup 3)))
6754 (set (match_dup 4) (match_dup 5))]
6755 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6756 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6757 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6758 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);"
6759 [(set_attr "type" "fpmove,*")
6760 (set_attr "length" "*,2")])
6762 (define_insn "*negdf2_v9"
6763 [(set (match_operand:DF 0 "register_operand" "=e")
6764 (neg:DF (match_operand:DF 1 "register_operand" "e")))]
6765 "TARGET_FPU && TARGET_V9"
6767 [(set_attr "type" "fpmove")
6768 (set_attr "fptype" "double")])
6770 (define_insn "negsf2"
6771 [(set (match_operand:SF 0 "register_operand" "=f")
6772 (neg:SF (match_operand:SF 1 "register_operand" "f")))]
6775 [(set_attr "type" "fpmove")])
6777 (define_expand "abstf2"
6778 [(set (match_operand:TF 0 "register_operand" "")
6779 (abs:TF (match_operand:TF 1 "register_operand" "")))]
6783 (define_insn_and_split "*abstf2_notv9"
6784 [(set (match_operand:TF 0 "register_operand" "=e,e")
6785 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6786 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
6787 "TARGET_FPU && ! TARGET_V9"
6791 "&& reload_completed
6792 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6793 [(set (match_dup 2) (abs:SF (match_dup 3)))
6794 (set (match_dup 4) (match_dup 5))
6795 (set (match_dup 6) (match_dup 7))]
6796 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6797 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6798 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6799 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
6800 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6801 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6802 [(set_attr "type" "fpmove,*")
6803 (set_attr "length" "*,2")])
6805 (define_insn "*abstf2_hq_v9"
6806 [(set (match_operand:TF 0 "register_operand" "=e,e")
6807 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6808 "TARGET_FPU && TARGET_V9 && TARGET_HARD_QUAD"
6812 [(set_attr "type" "fpmove")
6813 (set_attr "fptype" "double,*")])
6815 (define_insn_and_split "*abstf2_v9"
6816 [(set (match_operand:TF 0 "register_operand" "=e,e")
6817 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6818 "TARGET_FPU && TARGET_V9 && !TARGET_HARD_QUAD"
6822 "&& reload_completed
6823 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6824 [(set (match_dup 2) (abs:DF (match_dup 3)))
6825 (set (match_dup 4) (match_dup 5))]
6826 "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
6827 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
6828 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6829 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6830 [(set_attr "type" "fpmove,*")
6831 (set_attr "length" "*,2")
6832 (set_attr "fptype" "double,*")])
6834 (define_expand "absdf2"
6835 [(set (match_operand:DF 0 "register_operand" "")
6836 (abs:DF (match_operand:DF 1 "register_operand" "")))]
6840 (define_insn_and_split "*absdf2_notv9"
6841 [(set (match_operand:DF 0 "register_operand" "=e,e")
6842 (abs:DF (match_operand:DF 1 "register_operand" "0,e")))]
6843 "TARGET_FPU && ! TARGET_V9"
6847 "&& reload_completed
6848 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6849 [(set (match_dup 2) (abs:SF (match_dup 3)))
6850 (set (match_dup 4) (match_dup 5))]
6851 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6852 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6853 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6854 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);"
6855 [(set_attr "type" "fpmove,*")
6856 (set_attr "length" "*,2")])
6858 (define_insn "*absdf2_v9"
6859 [(set (match_operand:DF 0 "register_operand" "=e")
6860 (abs:DF (match_operand:DF 1 "register_operand" "e")))]
6861 "TARGET_FPU && TARGET_V9"
6863 [(set_attr "type" "fpmove")
6864 (set_attr "fptype" "double")])
6866 (define_insn "abssf2"
6867 [(set (match_operand:SF 0 "register_operand" "=f")
6868 (abs:SF (match_operand:SF 1 "register_operand" "f")))]
6871 [(set_attr "type" "fpmove")])
6873 (define_expand "sqrttf2"
6874 [(set (match_operand:TF 0 "nonimmediate_operand" "")
6875 (sqrt:TF (match_operand:TF 1 "general_operand" "")))]
6876 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6877 "emit_tfmode_unop (SQRT, operands); DONE;")
6879 (define_insn "*sqrttf2_hq"
6880 [(set (match_operand:TF 0 "register_operand" "=e")
6881 (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
6882 "TARGET_FPU && TARGET_HARD_QUAD"
6884 [(set_attr "type" "fpsqrtd")])
6886 (define_insn "sqrtdf2"
6887 [(set (match_operand:DF 0 "register_operand" "=e")
6888 (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
6891 [(set_attr "type" "fpsqrtd")
6892 (set_attr "fptype" "double")])
6894 (define_insn "sqrtsf2"
6895 [(set (match_operand:SF 0 "register_operand" "=f")
6896 (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
6899 [(set_attr "type" "fpsqrts")])
6901 ;;- arithmetic shift instructions
6903 (define_insn "ashlsi3"
6904 [(set (match_operand:SI 0 "register_operand" "=r")
6905 (ashift:SI (match_operand:SI 1 "register_operand" "r")
6906 (match_operand:SI 2 "arith_operand" "rI")))]
6909 if (operands[2] == const1_rtx)
6910 return "add\t%1, %1, %0";
6911 return "sll\t%1, %2, %0";
6914 (if_then_else (match_operand 2 "const1_operand" "")
6915 (const_string "ialu") (const_string "shift")))])
6917 (define_expand "ashldi3"
6918 [(set (match_operand:DI 0 "register_operand" "=r")
6919 (ashift:DI (match_operand:DI 1 "register_operand" "r")
6920 (match_operand:SI 2 "arith_operand" "rI")))]
6921 "TARGET_ARCH64 || TARGET_V8PLUS"
6923 if (! TARGET_ARCH64)
6925 if (GET_CODE (operands[2]) == CONST_INT)
6927 emit_insn (gen_ashldi3_v8plus (operands[0], operands[1], operands[2]));
6932 (define_insn "*ashldi3_sp64"
6933 [(set (match_operand:DI 0 "register_operand" "=r")
6934 (ashift:DI (match_operand:DI 1 "register_operand" "r")
6935 (match_operand:SI 2 "arith_operand" "rI")))]
6938 if (operands[2] == const1_rtx)
6939 return "add\t%1, %1, %0";
6940 return "sllx\t%1, %2, %0";
6943 (if_then_else (match_operand 2 "const1_operand" "")
6944 (const_string "ialu") (const_string "shift")))])
6947 (define_insn "ashldi3_v8plus"
6948 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
6949 (ashift:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
6950 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
6951 (clobber (match_scratch:SI 3 "=X,X,&h"))]
6953 { return sparc_v8plus_shift (operands, insn, "sllx"); }
6954 [(set_attr "type" "multi")
6955 (set_attr "length" "5,5,6")])
6957 ;; Optimize (1LL<<x)-1
6958 ;; XXX this also needs to be fixed to handle equal subregs
6959 ;; XXX first before we could re-enable it.
6961 ; [(set (match_operand:DI 0 "register_operand" "=h")
6962 ; (plus:DI (ashift:DI (const_int 1)
6963 ; (match_operand:SI 1 "arith_operand" "rI"))
6965 ; "0 && TARGET_V8PLUS"
6967 ; if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == REGNO (operands[0]))
6968 ; return "mov\t1, %L0\;sllx\t%L0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
6969 ; return "mov\t1, %H0\;sllx\t%H0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
6971 ; [(set_attr "type" "multi")
6972 ; (set_attr "length" "4")])
6974 (define_insn "*cmp_cc_ashift_1"
6975 [(set (reg:CC_NOOV 100)
6976 (compare:CC_NOOV (ashift:SI (match_operand:SI 0 "register_operand" "r")
6980 "addcc\t%0, %0, %%g0"
6981 [(set_attr "type" "compare")])
6983 (define_insn "*cmp_cc_set_ashift_1"
6984 [(set (reg:CC_NOOV 100)
6985 (compare:CC_NOOV (ashift:SI (match_operand:SI 1 "register_operand" "r")
6988 (set (match_operand:SI 0 "register_operand" "=r")
6989 (ashift:SI (match_dup 1) (const_int 1)))]
6992 [(set_attr "type" "compare")])
6994 (define_insn "ashrsi3"
6995 [(set (match_operand:SI 0 "register_operand" "=r")
6996 (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
6997 (match_operand:SI 2 "arith_operand" "rI")))]
7000 [(set_attr "type" "shift")])
7002 (define_insn "*ashrsi3_extend"
7003 [(set (match_operand:DI 0 "register_operand" "=r")
7004 (sign_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
7005 (match_operand:SI 2 "arith_operand" "r"))))]
7008 [(set_attr "type" "shift")])
7010 ;; This handles the case as above, but with constant shift instead of
7011 ;; register. Combiner "simplifies" it for us a little bit though.
7012 (define_insn "*ashrsi3_extend2"
7013 [(set (match_operand:DI 0 "register_operand" "=r")
7014 (ashiftrt:DI (ashift:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
7016 (match_operand:SI 2 "small_int_or_double" "n")))]
7018 && ((GET_CODE (operands[2]) == CONST_INT
7019 && INTVAL (operands[2]) >= 32 && INTVAL (operands[2]) < 64)
7020 || (GET_CODE (operands[2]) == CONST_DOUBLE
7021 && !CONST_DOUBLE_HIGH (operands[2])
7022 && CONST_DOUBLE_LOW (operands[2]) >= 32
7023 && CONST_DOUBLE_LOW (operands[2]) < 64))"
7025 operands[2] = GEN_INT (INTVAL (operands[2]) - 32);
7027 return "sra\t%1, %2, %0";
7029 [(set_attr "type" "shift")])
7031 (define_expand "ashrdi3"
7032 [(set (match_operand:DI 0 "register_operand" "=r")
7033 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
7034 (match_operand:SI 2 "arith_operand" "rI")))]
7035 "TARGET_ARCH64 || TARGET_V8PLUS"
7037 if (! TARGET_ARCH64)
7039 if (GET_CODE (operands[2]) == CONST_INT)
7040 FAIL; /* prefer generic code in this case */
7041 emit_insn (gen_ashrdi3_v8plus (operands[0], operands[1], operands[2]));
7047 [(set (match_operand:DI 0 "register_operand" "=r")
7048 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
7049 (match_operand:SI 2 "arith_operand" "rI")))]
7052 [(set_attr "type" "shift")])
7055 (define_insn "ashrdi3_v8plus"
7056 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
7057 (ashiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
7058 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
7059 (clobber (match_scratch:SI 3 "=X,X,&h"))]
7061 { return sparc_v8plus_shift (operands, insn, "srax"); }
7062 [(set_attr "type" "multi")
7063 (set_attr "length" "5,5,6")])
7065 (define_insn "lshrsi3"
7066 [(set (match_operand:SI 0 "register_operand" "=r")
7067 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
7068 (match_operand:SI 2 "arith_operand" "rI")))]
7071 [(set_attr "type" "shift")])
7073 ;; This handles the case where
7074 ;; (zero_extend:DI (lshiftrt:SI (match_operand:SI) (match_operand:SI))),
7075 ;; but combiner "simplifies" it for us.
7076 (define_insn "*lshrsi3_extend"
7077 [(set (match_operand:DI 0 "register_operand" "=r")
7078 (and:DI (subreg:DI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
7079 (match_operand:SI 2 "arith_operand" "r")) 0)
7080 (match_operand 3 "" "")))]
7082 && ((GET_CODE (operands[3]) == CONST_DOUBLE
7083 && CONST_DOUBLE_HIGH (operands[3]) == 0
7084 && CONST_DOUBLE_LOW (operands[3]) == 0xffffffff)
7085 || (HOST_BITS_PER_WIDE_INT >= 64
7086 && GET_CODE (operands[3]) == CONST_INT
7087 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) == 0xffffffff))"
7089 [(set_attr "type" "shift")])
7091 ;; This handles the case where
7092 ;; (lshiftrt:DI (zero_extend:DI (match_operand:SI)) (const_int >=0 < 32))
7093 ;; but combiner "simplifies" it for us.
7094 (define_insn "*lshrsi3_extend2"
7095 [(set (match_operand:DI 0 "register_operand" "=r")
7096 (zero_extract:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
7097 (match_operand 2 "small_int_or_double" "n")
7100 && ((GET_CODE (operands[2]) == CONST_INT
7101 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
7102 || (GET_CODE (operands[2]) == CONST_DOUBLE
7103 && CONST_DOUBLE_HIGH (operands[2]) == 0
7104 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
7106 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
7108 return "srl\t%1, %2, %0";
7110 [(set_attr "type" "shift")])
7112 (define_expand "lshrdi3"
7113 [(set (match_operand:DI 0 "register_operand" "=r")
7114 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
7115 (match_operand:SI 2 "arith_operand" "rI")))]
7116 "TARGET_ARCH64 || TARGET_V8PLUS"
7118 if (! TARGET_ARCH64)
7120 if (GET_CODE (operands[2]) == CONST_INT)
7122 emit_insn (gen_lshrdi3_v8plus (operands[0], operands[1], operands[2]));
7128 [(set (match_operand:DI 0 "register_operand" "=r")
7129 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
7130 (match_operand:SI 2 "arith_operand" "rI")))]
7133 [(set_attr "type" "shift")])
7136 (define_insn "lshrdi3_v8plus"
7137 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
7138 (lshiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
7139 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
7140 (clobber (match_scratch:SI 3 "=X,X,&h"))]
7142 { return sparc_v8plus_shift (operands, insn, "srlx"); }
7143 [(set_attr "type" "multi")
7144 (set_attr "length" "5,5,6")])
7147 [(set (match_operand:SI 0 "register_operand" "=r")
7148 (ashiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
7150 (match_operand:SI 2 "small_int_or_double" "n")))]
7152 && ((GET_CODE (operands[2]) == CONST_INT
7153 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
7154 || (GET_CODE (operands[2]) == CONST_DOUBLE
7155 && !CONST_DOUBLE_HIGH (operands[2])
7156 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
7158 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
7160 return "srax\t%1, %2, %0";
7162 [(set_attr "type" "shift")])
7165 [(set (match_operand:SI 0 "register_operand" "=r")
7166 (lshiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
7168 (match_operand:SI 2 "small_int_or_double" "n")))]
7170 && ((GET_CODE (operands[2]) == CONST_INT
7171 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
7172 || (GET_CODE (operands[2]) == CONST_DOUBLE
7173 && !CONST_DOUBLE_HIGH (operands[2])
7174 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
7176 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
7178 return "srlx\t%1, %2, %0";
7180 [(set_attr "type" "shift")])
7183 [(set (match_operand:SI 0 "register_operand" "=r")
7184 (ashiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
7185 (match_operand:SI 2 "small_int_or_double" "n")) 4)
7186 (match_operand:SI 3 "small_int_or_double" "n")))]
7188 && GET_CODE (operands[2]) == CONST_INT && GET_CODE (operands[3]) == CONST_INT
7189 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
7190 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
7191 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
7193 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
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 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
7202 (match_operand:SI 2 "small_int_or_double" "n")) 4)
7203 (match_operand:SI 3 "small_int_or_double" "n")))]
7205 && GET_CODE (operands[2]) == CONST_INT && GET_CODE (operands[3]) == CONST_INT
7206 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
7207 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
7208 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
7210 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
7212 return "srlx\t%1, %2, %0";
7214 [(set_attr "type" "shift")])
7216 ;; Unconditional and other jump instructions
7217 ;; On the SPARC, by setting the annul bit on an unconditional branch, the
7218 ;; following insn is never executed. This saves us a nop. Dbx does not
7219 ;; handle such branches though, so we only use them when optimizing.
7221 [(set (pc) (label_ref (match_operand 0 "" "")))]
7224 /* TurboSPARC is reported to have problems with
7227 i.e. an empty loop with the annul bit set. The workaround is to use
7231 if (! TARGET_V9 && flag_delayed_branch
7232 && (INSN_ADDRESSES (INSN_UID (operands[0]))
7233 == INSN_ADDRESSES (INSN_UID (insn))))
7236 return TARGET_V9 ? "ba%*,pt\t%%xcc, %l0%(" : "b%*\t%l0%(";
7238 [(set_attr "type" "uncond_branch")])
7240 (define_expand "tablejump"
7241 [(parallel [(set (pc) (match_operand 0 "register_operand" "r"))
7242 (use (label_ref (match_operand 1 "" "")))])]
7245 if (GET_MODE (operands[0]) != CASE_VECTOR_MODE)
7248 /* In pic mode, our address differences are against the base of the
7249 table. Add that base value back in; CSE ought to be able to combine
7250 the two address loads. */
7254 tmp = gen_rtx_LABEL_REF (Pmode, operands[1]);
7256 if (CASE_VECTOR_MODE != Pmode)
7257 tmp2 = gen_rtx_SIGN_EXTEND (Pmode, tmp2);
7258 tmp = gen_rtx_PLUS (Pmode, tmp2, tmp);
7259 operands[0] = memory_address (Pmode, tmp);
7263 (define_insn "*tablejump_sp32"
7264 [(set (pc) (match_operand:SI 0 "address_operand" "p"))
7265 (use (label_ref (match_operand 1 "" "")))]
7268 [(set_attr "type" "uncond_branch")])
7270 (define_insn "*tablejump_sp64"
7271 [(set (pc) (match_operand:DI 0 "address_operand" "p"))
7272 (use (label_ref (match_operand 1 "" "")))]
7275 [(set_attr "type" "uncond_branch")])
7277 ;; This pattern recognizes the "instruction" that appears in
7278 ;; a function call that wants a structure value,
7279 ;; to inform the called function if compiled with Sun CC.
7280 ;(define_insn "*unimp_insn"
7281 ; [(match_operand:SI 0 "immediate_operand" "")]
7282 ; "GET_CODE (operands[0]) == CONST_INT && INTVAL (operands[0]) > 0"
7284 ; [(set_attr "type" "marker")])
7286 ;;- jump to subroutine
7287 (define_expand "call"
7288 ;; Note that this expression is not used for generating RTL.
7289 ;; All the RTL is generated explicitly below.
7290 [(call (match_operand 0 "call_operand" "")
7291 (match_operand 3 "" "i"))]
7292 ;; operands[2] is next_arg_register
7293 ;; operands[3] is struct_value_size_rtx.
7296 rtx fn_rtx, nregs_rtx;
7298 if (GET_MODE (operands[0]) != FUNCTION_MODE)
7301 if (GET_CODE (XEXP (operands[0], 0)) == LABEL_REF)
7303 /* This is really a PIC sequence. We want to represent
7304 it as a funny jump so its delay slots can be filled.
7306 ??? But if this really *is* a CALL, will not it clobber the
7307 call-clobbered registers? We lose this if it is a JUMP_INSN.
7308 Why cannot we have delay slots filled if it were a CALL? */
7310 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
7315 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
7317 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
7323 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
7324 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
7328 fn_rtx = operands[0];
7330 /* Count the number of parameter registers being used by this call.
7331 if that argument is NULL, it means we are using them all, which
7332 means 6 on the sparc. */
7335 nregs_rtx = GEN_INT (REGNO (operands[2]) - 8);
7337 nregs_rtx = GEN_INT (6);
7339 nregs_rtx = const0_rtx;
7342 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
7346 gen_rtvec (3, gen_rtx_CALL (VOIDmode, fn_rtx, nregs_rtx),
7348 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
7353 gen_rtvec (2, gen_rtx_CALL (VOIDmode, fn_rtx, nregs_rtx),
7354 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
7358 /* If this call wants a structure value,
7359 emit an unimp insn to let the called function know about this. */
7360 if (! TARGET_ARCH64 && INTVAL (operands[3]) > 0)
7362 rtx insn = emit_insn (operands[3]);
7363 SCHED_GROUP_P (insn) = 1;
7370 ;; We can't use the same pattern for these two insns, because then registers
7371 ;; in the address may not be properly reloaded.
7373 (define_insn "*call_address_sp32"
7374 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
7375 (match_operand 1 "" ""))
7376 (clobber (reg:SI 15))]
7377 ;;- Do not use operand 1 for most machines.
7380 [(set_attr "type" "call")])
7382 (define_insn "*call_symbolic_sp32"
7383 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
7384 (match_operand 1 "" ""))
7385 (clobber (reg:SI 15))]
7386 ;;- Do not use operand 1 for most machines.
7389 [(set_attr "type" "call")])
7391 (define_insn "*call_address_sp64"
7392 [(call (mem:DI (match_operand:DI 0 "address_operand" "p"))
7393 (match_operand 1 "" ""))
7394 (clobber (reg:DI 15))]
7395 ;;- Do not use operand 1 for most machines.
7398 [(set_attr "type" "call")])
7400 (define_insn "*call_symbolic_sp64"
7401 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
7402 (match_operand 1 "" ""))
7403 (clobber (reg:DI 15))]
7404 ;;- Do not use operand 1 for most machines.
7407 [(set_attr "type" "call")])
7409 ;; This is a call that wants a structure value.
7410 ;; There is no such critter for v9 (??? we may need one anyway).
7411 (define_insn "*call_address_struct_value_sp32"
7412 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
7413 (match_operand 1 "" ""))
7414 (match_operand 2 "immediate_operand" "")
7415 (clobber (reg:SI 15))]
7416 ;;- Do not use operand 1 for most machines.
7417 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 0"
7418 "call\t%a0, %1\n\tnop\n\tunimp\t%2"
7419 [(set_attr "type" "call_no_delay_slot")
7420 (set_attr "length" "3")])
7422 ;; This is a call that wants a structure value.
7423 ;; There is no such critter for v9 (??? we may need one anyway).
7424 (define_insn "*call_symbolic_struct_value_sp32"
7425 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
7426 (match_operand 1 "" ""))
7427 (match_operand 2 "immediate_operand" "")
7428 (clobber (reg:SI 15))]
7429 ;;- Do not use operand 1 for most machines.
7430 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 0"
7431 "call\t%a0, %1\n\tnop\n\tunimp\t%2"
7432 [(set_attr "type" "call_no_delay_slot")
7433 (set_attr "length" "3")])
7435 ;; This is a call that may want a structure value. This is used for
7437 (define_insn "*call_address_untyped_struct_value_sp32"
7438 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
7439 (match_operand 1 "" ""))
7440 (match_operand 2 "immediate_operand" "")
7441 (clobber (reg:SI 15))]
7442 ;;- Do not use operand 1 for most machines.
7443 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
7444 "call\t%a0, %1\n\tnop\n\tnop"
7445 [(set_attr "type" "call_no_delay_slot")
7446 (set_attr "length" "3")])
7448 ;; This is a call that wants a structure value.
7449 (define_insn "*call_symbolic_untyped_struct_value_sp32"
7450 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
7451 (match_operand 1 "" ""))
7452 (match_operand 2 "immediate_operand" "")
7453 (clobber (reg:SI 15))]
7454 ;;- Do not use operand 1 for most machines.
7455 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
7456 "call\t%a0, %1\n\tnop\n\tnop"
7457 [(set_attr "type" "call_no_delay_slot")
7458 (set_attr "length" "3")])
7460 (define_expand "call_value"
7461 ;; Note that this expression is not used for generating RTL.
7462 ;; All the RTL is generated explicitly below.
7463 [(set (match_operand 0 "register_operand" "=rf")
7464 (call (match_operand 1 "" "")
7465 (match_operand 4 "" "")))]
7466 ;; operand 2 is stack_size_rtx
7467 ;; operand 3 is next_arg_register
7470 rtx fn_rtx, nregs_rtx;
7473 if (GET_MODE (operands[1]) != FUNCTION_MODE)
7476 fn_rtx = operands[1];
7480 nregs_rtx = GEN_INT (REGNO (operands[3]) - 8);
7482 nregs_rtx = GEN_INT (6);
7484 nregs_rtx = const0_rtx;
7488 gen_rtx_SET (VOIDmode, operands[0],
7489 gen_rtx_CALL (VOIDmode, fn_rtx, nregs_rtx)),
7490 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)));
7492 emit_call_insn (gen_rtx_PARALLEL (VOIDmode, vec));
7497 (define_insn "*call_value_address_sp32"
7498 [(set (match_operand 0 "" "=rf")
7499 (call (mem:SI (match_operand:SI 1 "address_operand" "p"))
7500 (match_operand 2 "" "")))
7501 (clobber (reg:SI 15))]
7502 ;;- Do not use operand 2 for most machines.
7505 [(set_attr "type" "call")])
7507 (define_insn "*call_value_symbolic_sp32"
7508 [(set (match_operand 0 "" "=rf")
7509 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
7510 (match_operand 2 "" "")))
7511 (clobber (reg:SI 15))]
7512 ;;- Do not use operand 2 for most machines.
7515 [(set_attr "type" "call")])
7517 (define_insn "*call_value_address_sp64"
7518 [(set (match_operand 0 "" "")
7519 (call (mem:DI (match_operand:DI 1 "address_operand" "p"))
7520 (match_operand 2 "" "")))
7521 (clobber (reg:DI 15))]
7522 ;;- Do not use operand 2 for most machines.
7525 [(set_attr "type" "call")])
7527 (define_insn "*call_value_symbolic_sp64"
7528 [(set (match_operand 0 "" "")
7529 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
7530 (match_operand 2 "" "")))
7531 (clobber (reg:DI 15))]
7532 ;;- Do not use operand 2 for most machines.
7535 [(set_attr "type" "call")])
7537 (define_expand "untyped_call"
7538 [(parallel [(call (match_operand 0 "" "")
7540 (match_operand 1 "" "")
7541 (match_operand 2 "" "")])]
7546 /* Pass constm1 to indicate that it may expect a structure value, but
7547 we don't know what size it is. */
7548 emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, constm1_rtx));
7550 for (i = 0; i < XVECLEN (operands[2], 0); i++)
7552 rtx set = XVECEXP (operands[2], 0, i);
7553 emit_move_insn (SET_DEST (set), SET_SRC (set));
7556 /* The optimizer does not know that the call sets the function value
7557 registers we stored in the result block. We avoid problems by
7558 claiming that all hard registers are used and clobbered at this
7560 emit_insn (gen_blockage ());
7566 (define_expand "sibcall"
7567 [(parallel [(call (match_operand 0 "call_operand" "") (const_int 0))
7572 (define_insn "*sibcall_symbolic_sp32"
7573 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
7574 (match_operand 1 "" ""))
7577 "* return output_sibcall(insn, operands[0]);"
7578 [(set_attr "type" "sibcall")])
7580 (define_insn "*sibcall_symbolic_sp64"
7581 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
7582 (match_operand 1 "" ""))
7585 "* return output_sibcall(insn, operands[0]);"
7586 [(set_attr "type" "sibcall")])
7588 (define_expand "sibcall_value"
7589 [(parallel [(set (match_operand 0 "register_operand" "=rf")
7590 (call (match_operand 1 "" "") (const_int 0)))
7595 (define_insn "*sibcall_value_symbolic_sp32"
7596 [(set (match_operand 0 "" "=rf")
7597 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
7598 (match_operand 2 "" "")))
7601 "* return output_sibcall(insn, operands[1]);"
7602 [(set_attr "type" "sibcall")])
7604 (define_insn "*sibcall_value_symbolic_sp64"
7605 [(set (match_operand 0 "" "")
7606 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
7607 (match_operand 2 "" "")))
7610 "* return output_sibcall(insn, operands[1]);"
7611 [(set_attr "type" "sibcall")])
7613 (define_expand "sibcall_epilogue"
7618 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
7619 ;; all of memory. This blocks insns from being moved across this point.
7621 (define_insn "blockage"
7622 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
7625 [(set_attr "length" "0")])
7627 ;; Prepare to return any type including a structure value.
7629 (define_expand "untyped_return"
7630 [(match_operand:BLK 0 "memory_operand" "")
7631 (match_operand 1 "" "")]
7634 rtx valreg1 = gen_rtx_REG (DImode, 24);
7635 rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
7636 rtx result = operands[0];
7638 if (! TARGET_ARCH64)
7640 rtx rtnreg = gen_rtx_REG (SImode, (current_function_uses_only_leaf_regs
7642 rtx value = gen_reg_rtx (SImode);
7644 /* Fetch the instruction where we will return to and see if it's an unimp
7645 instruction (the most significant 10 bits will be zero). If so,
7646 update the return address to skip the unimp instruction. */
7647 emit_move_insn (value,
7648 gen_rtx_MEM (SImode, plus_constant (rtnreg, 8)));
7649 emit_insn (gen_lshrsi3 (value, value, GEN_INT (22)));
7650 emit_insn (gen_update_return (rtnreg, value));
7653 /* Reload the function value registers. */
7654 emit_move_insn (valreg1, adjust_address (result, DImode, 0));
7655 emit_move_insn (valreg2,
7656 adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8));
7658 /* Put USE insns before the return. */
7659 emit_insn (gen_rtx_USE (VOIDmode, valreg1));
7660 emit_insn (gen_rtx_USE (VOIDmode, valreg2));
7662 /* Construct the return. */
7663 expand_null_return ();
7668 ;; This is a bit of a hack. We're incrementing a fixed register (%i7),
7669 ;; and parts of the compiler don't want to believe that the add is needed.
7671 (define_insn "update_return"
7672 [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
7673 (match_operand:SI 1 "register_operand" "r")] UNSPEC_UPDATE_RETURN)]
7675 "cmp\t%1, 0\;be,a\t.+8\;add\t%0, 4, %0"
7676 [(set_attr "type" "multi")
7677 (set_attr "length" "3")])
7684 (define_expand "indirect_jump"
7685 [(set (pc) (match_operand 0 "address_operand" "p"))]
7689 (define_insn "*branch_sp32"
7690 [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
7693 [(set_attr "type" "uncond_branch")])
7695 (define_insn "*branch_sp64"
7696 [(set (pc) (match_operand:DI 0 "address_operand" "p"))]
7699 [(set_attr "type" "uncond_branch")])
7701 ;; ??? Doesn't work with -mflat.
7702 (define_expand "nonlocal_goto"
7703 [(match_operand:SI 0 "general_operand" "")
7704 (match_operand:SI 1 "general_operand" "")
7705 (match_operand:SI 2 "general_operand" "")
7706 (match_operand:SI 3 "" "")]
7710 rtx chain = operands[0];
7712 rtx lab = operands[1];
7713 rtx stack = operands[2];
7714 rtx fp = operands[3];
7717 /* Trap instruction to flush all the register windows. */
7718 emit_insn (gen_flush_register_windows ());
7720 /* Load the fp value for the containing fn into %fp. This is needed
7721 because STACK refers to %fp. Note that virtual register instantiation
7722 fails if the virtual %fp isn't set from a register. */
7723 if (GET_CODE (fp) != REG)
7724 fp = force_reg (Pmode, fp);
7725 emit_move_insn (virtual_stack_vars_rtx, fp);
7727 /* Find the containing function's current nonlocal goto handler,
7728 which will do any cleanups and then jump to the label. */
7729 labreg = gen_rtx_REG (Pmode, 8);
7730 emit_move_insn (labreg, lab);
7732 /* Restore %fp from stack pointer value for containing function.
7733 The restore insn that follows will move this to %sp,
7734 and reload the appropriate value into %fp. */
7735 emit_move_insn (hard_frame_pointer_rtx, stack);
7737 /* USE of frame_pointer_rtx added for consistency; not clear if
7739 /*emit_insn (gen_rtx_USE (VOIDmode, frame_pointer_rtx));*/
7740 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
7743 /* Return, restoring reg window and jumping to goto handler. */
7744 if (TARGET_V9 && GET_CODE (chain) == CONST_INT
7745 && ! (INTVAL (chain) & ~(HOST_WIDE_INT)0xffffffff))
7747 emit_jump_insn (gen_goto_handler_and_restore_v9 (labreg,
7753 /* Put in the static chain register the nonlocal label address. */
7754 emit_move_insn (static_chain_rtx, chain);
7757 emit_insn (gen_rtx_USE (VOIDmode, static_chain_rtx));
7758 emit_jump_insn (gen_goto_handler_and_restore (labreg));
7763 ;; Special trap insn to flush register windows.
7764 (define_insn "flush_register_windows"
7765 [(unspec_volatile [(const_int 0)] UNSPECV_FLUSHW)]
7767 { return TARGET_V9 ? "flushw" : "ta\t3"; }
7768 [(set_attr "type" "flushw")])
7770 (define_insn "goto_handler_and_restore"
7771 [(unspec_volatile [(match_operand 0 "register_operand" "=r")] UNSPECV_GOTO)]
7772 "GET_MODE (operands[0]) == Pmode"
7773 "jmp\t%0+0\n\trestore"
7774 [(set_attr "type" "multi")
7775 (set_attr "length" "2")])
7777 ;;(define_insn "goto_handler_and_restore_v9"
7778 ;; [(unspec_volatile [(match_operand:SI 0 "register_operand" "=r,r")
7779 ;; (match_operand:SI 1 "register_operand" "=r,r")
7780 ;; (match_operand:SI 2 "const_int_operand" "I,n")] UNSPECV_GOTO_V9)]
7781 ;; "TARGET_V9 && ! TARGET_ARCH64"
7783 ;; return\t%0+0\n\tmov\t%2, %Y1
7784 ;; sethi\t%%hi(%2), %1\n\treturn\t%0+0\n\tor\t%Y1, %%lo(%2), %Y1"
7785 ;; [(set_attr "type" "multi")
7786 ;; (set_attr "length" "2,3")])
7788 ;;(define_insn "*goto_handler_and_restore_v9_sp64"
7789 ;; [(unspec_volatile [(match_operand:DI 0 "register_operand" "=r,r")
7790 ;; (match_operand:DI 1 "register_operand" "=r,r")
7791 ;; (match_operand:SI 2 "const_int_operand" "I,n")] UNSPECV_GOTO_V9)]
7792 ;; "TARGET_V9 && TARGET_ARCH64"
7794 ;; return\t%0+0\n\tmov\t%2, %Y1
7795 ;; sethi\t%%hi(%2), %1\n\treturn\t%0+0\n\tor\t%Y1, %%lo(%2), %Y1"
7796 ;; [(set_attr "type" "multi")
7797 ;; (set_attr "length" "2,3")])
7799 ;; For __builtin_setjmp we need to flush register windows iff the function
7800 ;; calls alloca as well, because otherwise the register window might be
7801 ;; saved after %sp adjustment and thus setjmp would crash
7802 (define_expand "builtin_setjmp_setup"
7803 [(match_operand 0 "register_operand" "r")]
7806 emit_insn (gen_do_builtin_setjmp_setup ());
7810 (define_insn "do_builtin_setjmp_setup"
7811 [(unspec_volatile [(const_int 0)] UNSPECV_SETJMP)]
7814 if (! current_function_calls_alloca)
7816 if (! TARGET_V9 || TARGET_FLAT)
7818 fputs ("\tflushw\n", asm_out_file);
7820 fprintf (asm_out_file, "\tst%c\t%%l7, [%%sp+%d]\n",
7821 TARGET_ARCH64 ? 'x' : 'w',
7822 SPARC_STACK_BIAS + 7 * UNITS_PER_WORD);
7823 fprintf (asm_out_file, "\tst%c\t%%fp, [%%sp+%d]\n",
7824 TARGET_ARCH64 ? 'x' : 'w',
7825 SPARC_STACK_BIAS + 14 * UNITS_PER_WORD);
7826 fprintf (asm_out_file, "\tst%c\t%%i7, [%%sp+%d]\n",
7827 TARGET_ARCH64 ? 'x' : 'w',
7828 SPARC_STACK_BIAS + 15 * UNITS_PER_WORD);
7831 [(set_attr "type" "multi")
7832 (set (attr "length")
7833 (cond [(eq_attr "current_function_calls_alloca" "false")
7835 (eq_attr "flat" "true")
7837 (eq_attr "isa" "!v9")
7839 (eq_attr "pic" "true")
7840 (const_int 4)] (const_int 3)))])
7842 ;; Pattern for use after a setjmp to store FP and the return register
7843 ;; into the stack area.
7845 (define_expand "setjmp"
7850 emit_insn (gen_setjmp_64 ());
7852 emit_insn (gen_setjmp_32 ());
7856 (define_expand "setjmp_32"
7857 [(set (mem:SI (plus:SI (reg:SI 14) (const_int 56))) (match_dup 0))
7858 (set (mem:SI (plus:SI (reg:SI 14) (const_int 60))) (reg:SI 31))]
7860 { operands[0] = frame_pointer_rtx; })
7862 (define_expand "setjmp_64"
7863 [(set (mem:DI (plus:DI (reg:DI 14) (const_int 112))) (match_dup 0))
7864 (set (mem:DI (plus:DI (reg:DI 14) (const_int 120))) (reg:DI 31))]
7866 { operands[0] = frame_pointer_rtx; })
7868 ;; Special pattern for the FLUSH instruction.
7870 ; We do SImode and DImode versions of this to quiet down genrecog's complaints
7871 ; of the define_insn otherwise missing a mode. We make "flush", aka
7872 ; gen_flush, the default one since sparc_initialize_trampoline uses
7873 ; it on SImode mem values.
7875 (define_insn "flush"
7876 [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")] UNSPECV_FLUSH)]
7878 { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; }
7879 [(set_attr "type" "iflush")])
7881 (define_insn "flushdi"
7882 [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")] UNSPECV_FLUSH)]
7884 { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; }
7885 [(set_attr "type" "iflush")])
7890 ;; The scan instruction searches from the most significant bit while ffs
7891 ;; searches from the least significant bit. The bit index and treatment of
7892 ;; zero also differ. It takes at least 7 instructions to get the proper
7893 ;; result. Here is an obvious 8 instruction sequence.
7896 (define_insn "ffssi2"
7897 [(set (match_operand:SI 0 "register_operand" "=&r")
7898 (ffs:SI (match_operand:SI 1 "register_operand" "r")))
7899 (clobber (match_scratch:SI 2 "=&r"))]
7900 "TARGET_SPARCLITE || TARGET_SPARCLET"
7902 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";
7904 [(set_attr "type" "multi")
7905 (set_attr "length" "8")])
7907 ;; ??? This should be a define expand, so that the extra instruction have
7908 ;; a chance of being optimized away.
7910 ;; Disabled because none of the UltraSPARCs implement popc. The HAL R1
7911 ;; does, but no one uses that and we don't have a switch for it.
7913 ;(define_insn "ffsdi2"
7914 ; [(set (match_operand:DI 0 "register_operand" "=&r")
7915 ; (ffs:DI (match_operand:DI 1 "register_operand" "r")))
7916 ; (clobber (match_scratch:DI 2 "=&r"))]
7918 ; "neg\t%1, %2\;xnor\t%1, %2, %2\;popc\t%2, %0\;movzr\t%1, 0, %0"
7919 ; [(set_attr "type" "multi")
7920 ; (set_attr "length" "4")])
7924 ;; Peepholes go at the end.
7926 ;; Optimize consecutive loads or stores into ldd and std when possible.
7927 ;; The conditions in which we do this are very restricted and are
7928 ;; explained in the code for {registers,memory}_ok_for_ldd functions.
7931 [(set (match_operand:SI 0 "memory_operand" "")
7933 (set (match_operand:SI 1 "memory_operand" "")
7936 && mems_ok_for_ldd_peep (operands[0], operands[1], NULL_RTX)"
7939 "operands[0] = widen_memory_access (operands[0], DImode, 0);")
7942 [(set (match_operand:SI 0 "memory_operand" "")
7944 (set (match_operand:SI 1 "memory_operand" "")
7947 && mems_ok_for_ldd_peep (operands[1], operands[0], NULL_RTX)"
7950 "operands[1] = widen_memory_access (operands[1], DImode, 0);")
7953 [(set (match_operand:SI 0 "register_operand" "")
7954 (match_operand:SI 1 "memory_operand" ""))
7955 (set (match_operand:SI 2 "register_operand" "")
7956 (match_operand:SI 3 "memory_operand" ""))]
7957 "registers_ok_for_ldd_peep (operands[0], operands[2])
7958 && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
7961 "operands[1] = widen_memory_access (operands[1], DImode, 0);
7962 operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));")
7965 [(set (match_operand:SI 0 "memory_operand" "")
7966 (match_operand:SI 1 "register_operand" ""))
7967 (set (match_operand:SI 2 "memory_operand" "")
7968 (match_operand:SI 3 "register_operand" ""))]
7969 "registers_ok_for_ldd_peep (operands[1], operands[3])
7970 && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
7973 "operands[0] = widen_memory_access (operands[0], DImode, 0);
7974 operands[1] = gen_rtx_REG (DImode, REGNO (operands[1]));")
7977 [(set (match_operand:SF 0 "register_operand" "")
7978 (match_operand:SF 1 "memory_operand" ""))
7979 (set (match_operand:SF 2 "register_operand" "")
7980 (match_operand:SF 3 "memory_operand" ""))]
7981 "registers_ok_for_ldd_peep (operands[0], operands[2])
7982 && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
7985 "operands[1] = widen_memory_access (operands[1], DFmode, 0);
7986 operands[0] = gen_rtx_REG (DFmode, REGNO (operands[0]));")
7989 [(set (match_operand:SF 0 "memory_operand" "")
7990 (match_operand:SF 1 "register_operand" ""))
7991 (set (match_operand:SF 2 "memory_operand" "")
7992 (match_operand:SF 3 "register_operand" ""))]
7993 "registers_ok_for_ldd_peep (operands[1], operands[3])
7994 && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
7997 "operands[0] = widen_memory_access (operands[0], DFmode, 0);
7998 operands[1] = gen_rtx_REG (DFmode, REGNO (operands[1]));")
8001 [(set (match_operand:SI 0 "register_operand" "")
8002 (match_operand:SI 1 "memory_operand" ""))
8003 (set (match_operand:SI 2 "register_operand" "")
8004 (match_operand:SI 3 "memory_operand" ""))]
8005 "registers_ok_for_ldd_peep (operands[2], operands[0])
8006 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
8009 "operands[3] = widen_memory_access (operands[3], DImode, 0);
8010 operands[2] = gen_rtx_REG (DImode, REGNO (operands[2]));")
8013 [(set (match_operand:SI 0 "memory_operand" "")
8014 (match_operand:SI 1 "register_operand" ""))
8015 (set (match_operand:SI 2 "memory_operand" "")
8016 (match_operand:SI 3 "register_operand" ""))]
8017 "registers_ok_for_ldd_peep (operands[3], operands[1])
8018 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
8021 "operands[2] = widen_memory_access (operands[2], DImode, 0);
8022 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
8026 [(set (match_operand:SF 0 "register_operand" "")
8027 (match_operand:SF 1 "memory_operand" ""))
8028 (set (match_operand:SF 2 "register_operand" "")
8029 (match_operand:SF 3 "memory_operand" ""))]
8030 "registers_ok_for_ldd_peep (operands[2], operands[0])
8031 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
8034 "operands[3] = widen_memory_access (operands[3], DFmode, 0);
8035 operands[2] = gen_rtx_REG (DFmode, REGNO (operands[2]));")
8038 [(set (match_operand:SF 0 "memory_operand" "")
8039 (match_operand:SF 1 "register_operand" ""))
8040 (set (match_operand:SF 2 "memory_operand" "")
8041 (match_operand:SF 3 "register_operand" ""))]
8042 "registers_ok_for_ldd_peep (operands[3], operands[1])
8043 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
8046 "operands[2] = widen_memory_access (operands[2], DFmode, 0);
8047 operands[3] = gen_rtx_REG (DFmode, REGNO (operands[3]));")
8049 ;; Optimize the case of following a reg-reg move with a test
8050 ;; of reg just moved. Don't allow floating point regs for operand 0 or 1.
8051 ;; This can result from a float to fix conversion.
8054 [(set (match_operand:SI 0 "register_operand" "")
8055 (match_operand:SI 1 "register_operand" ""))
8057 (compare:CC (match_operand:SI 2 "register_operand" "")
8059 "(rtx_equal_p (operands[2], operands[0])
8060 || rtx_equal_p (operands[2], operands[1]))
8061 && ! SPARC_FP_REG_P (REGNO (operands[0]))
8062 && ! SPARC_FP_REG_P (REGNO (operands[1]))"
8063 [(parallel [(set (match_dup 0) (match_dup 1))
8065 (compare:CC (match_dup 1) (const_int 0)))])]
8069 [(set (match_operand:DI 0 "register_operand" "")
8070 (match_operand:DI 1 "register_operand" ""))
8072 (compare:CCX (match_operand:DI 2 "register_operand" "")
8075 && (rtx_equal_p (operands[2], operands[0])
8076 || rtx_equal_p (operands[2], operands[1]))
8077 && ! SPARC_FP_REG_P (REGNO (operands[0]))
8078 && ! SPARC_FP_REG_P (REGNO (operands[1]))"
8079 [(parallel [(set (match_dup 0) (match_dup 1))
8081 (compare:CCX (match_dup 1) (const_int 0)))])]
8084 ;; Return peepholes. These are generated by sparc_nonflat_function_epilogue
8085 ;; who then immediately calls final_scan_insn.
8087 (define_insn "*return_qi"
8088 [(set (match_operand:QI 0 "restore_operand" "")
8089 (match_operand:QI 1 "arith_operand" "rI"))
8091 "sparc_emitting_epilogue"
8093 if (! TARGET_ARCH64 && current_function_returns_struct)
8094 return "jmp\t%%i7+12\n\trestore %%g0, %1, %Y0";
8095 else if (TARGET_V9 && (GET_CODE (operands[1]) == CONST_INT
8096 || IN_OR_GLOBAL_P (operands[1])))
8097 return "return\t%%i7+8\n\tmov\t%Y1, %Y0";
8099 return "ret\n\trestore %%g0, %1, %Y0";
8101 [(set_attr "type" "multi")
8102 (set_attr "length" "2")])
8104 (define_insn "*return_hi"
8105 [(set (match_operand:HI 0 "restore_operand" "")
8106 (match_operand:HI 1 "arith_operand" "rI"))
8108 "sparc_emitting_epilogue"
8110 if (! TARGET_ARCH64 && current_function_returns_struct)
8111 return "jmp\t%%i7+12\n\trestore %%g0, %1, %Y0";
8112 else if (TARGET_V9 && (GET_CODE (operands[1]) == CONST_INT
8113 || IN_OR_GLOBAL_P (operands[1])))
8114 return "return\t%%i7+8\n\tmov\t%Y1, %Y0";
8116 return "ret\;restore %%g0, %1, %Y0";
8118 [(set_attr "type" "multi")
8119 (set_attr "length" "2")])
8121 (define_insn "*return_si"
8122 [(set (match_operand:SI 0 "restore_operand" "")
8123 (match_operand:SI 1 "arith_operand" "rI"))
8125 "sparc_emitting_epilogue"
8127 if (! TARGET_ARCH64 && current_function_returns_struct)
8128 return "jmp\t%%i7+12\n\trestore %%g0, %1, %Y0";
8129 else if (TARGET_V9 && (GET_CODE (operands[1]) == CONST_INT
8130 || IN_OR_GLOBAL_P (operands[1])))
8131 return "return\t%%i7+8\n\tmov\t%Y1, %Y0";
8133 return "ret\;restore %%g0, %1, %Y0";
8135 [(set_attr "type" "multi")
8136 (set_attr "length" "2")])
8138 (define_insn "*return_sf_no_fpu"
8139 [(set (match_operand:SF 0 "restore_operand" "=r")
8140 (match_operand:SF 1 "register_operand" "r"))
8142 "sparc_emitting_epilogue"
8144 if (! TARGET_ARCH64 && current_function_returns_struct)
8145 return "jmp\t%%i7+12\n\trestore %%g0, %1, %Y0";
8146 else if (TARGET_V9 && IN_OR_GLOBAL_P (operands[1]))
8147 return "return\t%%i7+8\n\tmov\t%Y1, %Y0";
8149 return "ret\;restore %%g0, %1, %Y0";
8151 [(set_attr "type" "multi")
8152 (set_attr "length" "2")])
8154 (define_insn "*return_df_no_fpu"
8155 [(set (match_operand:DF 0 "restore_operand" "=r")
8156 (match_operand:DF 1 "register_operand" "r"))
8158 "sparc_emitting_epilogue && TARGET_ARCH64"
8160 if (IN_OR_GLOBAL_P (operands[1]))
8161 return "return\t%%i7+8\n\tmov\t%Y1, %Y0";
8163 return "ret\;restore %%g0, %1, %Y0";
8165 [(set_attr "type" "multi")
8166 (set_attr "length" "2")])
8168 (define_insn "*return_addsi"
8169 [(set (match_operand:SI 0 "restore_operand" "")
8170 (plus:SI (match_operand:SI 1 "register_operand" "r")
8171 (match_operand:SI 2 "arith_operand" "rI")))
8173 "sparc_emitting_epilogue"
8175 if (! TARGET_ARCH64 && current_function_returns_struct)
8176 return "jmp\t%%i7+12\n\trestore %r1, %2, %Y0";
8177 /* If operands are global or in registers, can use return */
8178 else if (TARGET_V9 && IN_OR_GLOBAL_P (operands[1])
8179 && (GET_CODE (operands[2]) == CONST_INT
8180 || IN_OR_GLOBAL_P (operands[2])))
8181 return "return\t%%i7+8\n\tadd\t%Y1, %Y2, %Y0";
8183 return "ret\;restore %r1, %2, %Y0";
8185 [(set_attr "type" "multi")
8186 (set_attr "length" "2")])
8188 (define_insn "*return_losum_si"
8189 [(set (match_operand:SI 0 "restore_operand" "")
8190 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
8191 (match_operand:SI 2 "immediate_operand" "in")))
8193 "sparc_emitting_epilogue && ! TARGET_CM_MEDMID"
8195 if (! TARGET_ARCH64 && current_function_returns_struct)
8196 return "jmp\t%%i7+12\n\trestore %r1, %%lo(%a2), %Y0";
8197 /* If operands are global or in registers, can use return */
8198 else if (TARGET_V9 && IN_OR_GLOBAL_P (operands[1]))
8199 return "return\t%%i7+8\n\tor\t%Y1, %%lo(%a2), %Y0";
8201 return "ret\;restore %r1, %%lo(%a2), %Y0";
8203 [(set_attr "type" "multi")
8204 (set_attr "length" "2")])
8206 (define_insn "*return_di"
8207 [(set (match_operand:DI 0 "restore_operand" "")
8208 (match_operand:DI 1 "arith_double_operand" "rHI"))
8210 "sparc_emitting_epilogue && TARGET_ARCH64"
8211 "ret\;restore %%g0, %1, %Y0"
8212 [(set_attr "type" "multi")
8213 (set_attr "length" "2")])
8215 (define_insn "*return_adddi"
8216 [(set (match_operand:DI 0 "restore_operand" "")
8217 (plus:DI (match_operand:DI 1 "arith_operand" "%r")
8218 (match_operand:DI 2 "arith_double_operand" "rHI")))
8220 "sparc_emitting_epilogue && TARGET_ARCH64"
8221 "ret\;restore %r1, %2, %Y0"
8222 [(set_attr "type" "multi")
8223 (set_attr "length" "2")])
8225 (define_insn "*return_losum_di"
8226 [(set (match_operand:DI 0 "restore_operand" "")
8227 (lo_sum:DI (match_operand:DI 1 "arith_operand" "%r")
8228 (match_operand:DI 2 "immediate_operand" "in")))
8230 "sparc_emitting_epilogue && TARGET_ARCH64 && ! TARGET_CM_MEDMID"
8231 "ret\;restore %r1, %%lo(%a2), %Y0"
8232 [(set_attr "type" "multi")
8233 (set_attr "length" "2")])
8235 (define_insn "*return_sf"
8237 (match_operand:SF 0 "register_operand" "f"))
8239 "sparc_emitting_epilogue"
8240 "ret\;fmovs\t%0, %%f0"
8241 [(set_attr "type" "multi")
8242 (set_attr "length" "2")])
8244 ;; Now peepholes to do a call followed by a jump.
8247 [(parallel [(set (match_operand 0 "" "")
8248 (call (mem:SI (match_operand:SI 1 "call_operand_address" "ps"))
8249 (match_operand 2 "" "")))
8250 (clobber (reg:SI 15))])
8251 (set (pc) (label_ref (match_operand 3 "" "")))]
8252 "short_branch (INSN_UID (insn), INSN_UID (operands[3]))
8253 && (USING_SJLJ_EXCEPTIONS || ! can_throw_internal (ins1))
8254 && sparc_cpu != PROCESSOR_ULTRASPARC
8255 && sparc_cpu != PROCESSOR_ULTRASPARC3"
8256 "call\t%a1, %2\n\tadd\t%%o7, (%l3-.-4), %%o7")
8259 [(parallel [(call (mem:SI (match_operand:SI 0 "call_operand_address" "ps"))
8260 (match_operand 1 "" ""))
8261 (clobber (reg:SI 15))])
8262 (set (pc) (label_ref (match_operand 2 "" "")))]
8263 "short_branch (INSN_UID (insn), INSN_UID (operands[2]))
8264 && (USING_SJLJ_EXCEPTIONS || ! can_throw_internal (ins1))
8265 && sparc_cpu != PROCESSOR_ULTRASPARC
8266 && sparc_cpu != PROCESSOR_ULTRASPARC3"
8267 "call\t%a0, %1\n\tadd\t%%o7, (%l2-.-4), %%o7")
8269 ;; ??? UltraSPARC-III note: A memory operation loading into the floating point register
8270 ;; ??? file, if it hits the prefetch cache, has a chance to dual-issue with other memory
8271 ;; ??? operations. With DFA we might be able to model this, but it requires a lot of
8273 (define_expand "prefetch"
8274 [(match_operand 0 "address_operand" "")
8275 (match_operand 1 "const_int_operand" "")
8276 (match_operand 2 "const_int_operand" "")]
8280 emit_insn (gen_prefetch_64 (operands[0], operands[1], operands[2]));
8282 emit_insn (gen_prefetch_32 (operands[0], operands[1], operands[2]));
8286 (define_insn "prefetch_64"
8287 [(prefetch (match_operand:DI 0 "address_operand" "p")
8288 (match_operand:DI 1 "const_int_operand" "n")
8289 (match_operand:DI 2 "const_int_operand" "n"))]
8292 static const char * const prefetch_instr[2][2] = {
8294 "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
8295 "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
8298 "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
8299 "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
8302 int read_or_write = INTVAL (operands[1]);
8303 int locality = INTVAL (operands[2]);
8305 if (read_or_write != 0 && read_or_write != 1)
8307 if (locality < 0 || locality > 3)
8309 return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
8311 [(set_attr "type" "load")])
8313 (define_insn "prefetch_32"
8314 [(prefetch (match_operand:SI 0 "address_operand" "p")
8315 (match_operand:SI 1 "const_int_operand" "n")
8316 (match_operand:SI 2 "const_int_operand" "n"))]
8319 static const char * const prefetch_instr[2][2] = {
8321 "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
8322 "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
8325 "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
8326 "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
8329 int read_or_write = INTVAL (operands[1]);
8330 int locality = INTVAL (operands[2]);
8332 if (read_or_write != 0 && read_or_write != 1)
8334 if (locality < 0 || locality > 3)
8336 return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
8338 [(set_attr "type" "load")])
8340 (define_expand "prologue"
8342 "flag_pic && current_function_uses_pic_offset_table"
8344 load_pic_register ();
8348 ;; We need to reload %l7 for -mflat -fpic,
8349 ;; otherwise %l7 should be preserved simply
8350 ;; by loading the function's register window
8351 (define_expand "exception_receiver"
8353 "TARGET_FLAT && flag_pic"
8355 load_pic_register ();
8360 (define_expand "builtin_setjmp_receiver"
8361 [(label_ref (match_operand 0 "" ""))]
8362 "TARGET_FLAT && flag_pic"
8364 load_pic_register ();
8369 [(trap_if (const_int 1) (const_int 5))]
8372 [(set_attr "type" "trap")])
8374 (define_expand "conditional_trap"
8375 [(trap_if (match_operator 0 "noov_compare_op"
8376 [(match_dup 2) (match_dup 3)])
8377 (match_operand:SI 1 "arith_operand" ""))]
8379 "operands[2] = gen_compare_reg (GET_CODE (operands[0]),
8380 sparc_compare_op0, sparc_compare_op1);
8381 operands[3] = const0_rtx;")
8384 [(trap_if (match_operator 0 "noov_compare_op" [(reg:CC 100) (const_int 0)])
8385 (match_operand:SI 1 "arith_operand" "rM"))]
8388 [(set_attr "type" "trap")])
8391 [(trap_if (match_operator 0 "noov_compare_op" [(reg:CCX 100) (const_int 0)])
8392 (match_operand:SI 1 "arith_operand" "rM"))]
8395 [(set_attr "type" "trap")])
8398 (define_insn "tgd_hi22"
8399 [(set (match_operand:SI 0 "register_operand" "=r")
8400 (high:SI (unspec:SI [(match_operand 1 "tgd_symbolic_operand" "")]
8403 "sethi\\t%%tgd_hi22(%a1), %0")
8405 (define_insn "tgd_lo10"
8406 [(set (match_operand:SI 0 "register_operand" "=r")
8407 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
8408 (unspec:SI [(match_operand 2 "tgd_symbolic_operand" "")]
8411 "add\\t%1, %%tgd_lo10(%a2), %0")
8413 (define_insn "tgd_add32"
8414 [(set (match_operand:SI 0 "register_operand" "=r")
8415 (plus:SI (match_operand:SI 1 "register_operand" "r")
8416 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8417 (match_operand 3 "tgd_symbolic_operand" "")]
8419 "TARGET_TLS && TARGET_ARCH32"
8420 "add\\t%1, %2, %0, %%tgd_add(%a3)")
8422 (define_insn "tgd_add64"
8423 [(set (match_operand:DI 0 "register_operand" "=r")
8424 (plus:DI (match_operand:DI 1 "register_operand" "r")
8425 (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8426 (match_operand 3 "tgd_symbolic_operand" "")]
8428 "TARGET_TLS && TARGET_ARCH64"
8429 "add\\t%1, %2, %0, %%tgd_add(%a3)")
8431 (define_insn "tgd_call32"
8432 [(set (match_operand 0 "register_operand" "=r")
8433 (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")
8434 (match_operand 2 "tgd_symbolic_operand" "")]
8436 (match_operand 3 "" "")))
8437 (clobber (reg:SI 15))]
8438 "TARGET_TLS && TARGET_ARCH32"
8439 "call\t%a1, %%tgd_call(%a2)%#"
8440 [(set_attr "type" "call")])
8442 (define_insn "tgd_call64"
8443 [(set (match_operand 0 "register_operand" "=r")
8444 (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")
8445 (match_operand 2 "tgd_symbolic_operand" "")]
8447 (match_operand 3 "" "")))
8448 (clobber (reg:DI 15))]
8449 "TARGET_TLS && TARGET_ARCH64"
8450 "call\t%a1, %%tgd_call(%a2)%#"
8451 [(set_attr "type" "call")])
8453 (define_insn "tldm_hi22"
8454 [(set (match_operand:SI 0 "register_operand" "=r")
8455 (high:SI (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
8457 "sethi\\t%%tldm_hi22(%&), %0")
8459 (define_insn "tldm_lo10"
8460 [(set (match_operand:SI 0 "register_operand" "=r")
8461 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
8462 (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
8464 "add\\t%1, %%tldm_lo10(%&), %0")
8466 (define_insn "tldm_add32"
8467 [(set (match_operand:SI 0 "register_operand" "=r")
8468 (plus:SI (match_operand:SI 1 "register_operand" "r")
8469 (unspec:SI [(match_operand:SI 2 "register_operand" "r")]
8471 "TARGET_TLS && TARGET_ARCH32"
8472 "add\\t%1, %2, %0, %%tldm_add(%&)")
8474 (define_insn "tldm_add64"
8475 [(set (match_operand:DI 0 "register_operand" "=r")
8476 (plus:DI (match_operand:DI 1 "register_operand" "r")
8477 (unspec:DI [(match_operand:SI 2 "register_operand" "r")]
8479 "TARGET_TLS && TARGET_ARCH64"
8480 "add\\t%1, %2, %0, %%tldm_add(%&)")
8482 (define_insn "tldm_call32"
8483 [(set (match_operand 0 "register_operand" "=r")
8484 (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")]
8486 (match_operand 2 "" "")))
8487 (clobber (reg:SI 15))]
8488 "TARGET_TLS && TARGET_ARCH32"
8489 "call\t%a1, %%tldm_call(%&)%#"
8490 [(set_attr "type" "call")])
8492 (define_insn "tldm_call64"
8493 [(set (match_operand 0 "register_operand" "=r")
8494 (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")]
8496 (match_operand 2 "" "")))
8497 (clobber (reg:DI 15))]
8498 "TARGET_TLS && TARGET_ARCH64"
8499 "call\t%a1, %%tldm_call(%&)%#"
8500 [(set_attr "type" "call")])
8502 (define_insn "tldo_hix22"
8503 [(set (match_operand:SI 0 "register_operand" "=r")
8504 (high:SI (unspec:SI [(match_operand 1 "tld_symbolic_operand" "")]
8507 "sethi\\t%%tldo_hix22(%a1), %0")
8509 (define_insn "tldo_lox10"
8510 [(set (match_operand:SI 0 "register_operand" "=r")
8511 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
8512 (unspec:SI [(match_operand 2 "tld_symbolic_operand" "")]
8515 "xor\\t%1, %%tldo_lox10(%a2), %0")
8517 (define_insn "tldo_add32"
8518 [(set (match_operand:SI 0 "register_operand" "=r")
8519 (plus:SI (match_operand:SI 1 "register_operand" "r")
8520 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8521 (match_operand 3 "tld_symbolic_operand" "")]
8523 "TARGET_TLS && TARGET_ARCH32"
8524 "add\\t%1, %2, %0, %%tldo_add(%a3)")
8526 (define_insn "tldo_add64"
8527 [(set (match_operand:DI 0 "register_operand" "=r")
8528 (plus:DI (match_operand:DI 1 "register_operand" "r")
8529 (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8530 (match_operand 3 "tld_symbolic_operand" "")]
8532 "TARGET_TLS && TARGET_ARCH64"
8533 "add\\t%1, %2, %0, %%tldo_add(%a3)")
8535 (define_insn "tie_hi22"
8536 [(set (match_operand:SI 0 "register_operand" "=r")
8537 (high:SI (unspec:SI [(match_operand 1 "tie_symbolic_operand" "")]
8540 "sethi\\t%%tie_hi22(%a1), %0")
8542 (define_insn "tie_lo10"
8543 [(set (match_operand:SI 0 "register_operand" "=r")
8544 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
8545 (unspec:SI [(match_operand 2 "tie_symbolic_operand" "")]
8548 "add\\t%1, %%tie_lo10(%a2), %0")
8550 (define_insn "tie_ld32"
8551 [(set (match_operand:SI 0 "register_operand" "=r")
8552 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
8553 (match_operand:SI 2 "register_operand" "r")
8554 (match_operand 3 "tie_symbolic_operand" "")]
8556 "TARGET_TLS && TARGET_ARCH32"
8557 "ld\\t[%1 + %2], %0, %%tie_ld(%a3)"
8558 [(set_attr "type" "load")])
8560 (define_insn "tie_ld64"
8561 [(set (match_operand:DI 0 "register_operand" "=r")
8562 (unspec:DI [(match_operand:DI 1 "register_operand" "r")
8563 (match_operand:SI 2 "register_operand" "r")
8564 (match_operand 3 "tie_symbolic_operand" "")]
8566 "TARGET_TLS && TARGET_ARCH64"
8567 "ldx\\t[%1 + %2], %0, %%tie_ldx(%a3)"
8568 [(set_attr "type" "load")])
8570 (define_insn "tie_add32"
8571 [(set (match_operand:SI 0 "register_operand" "=r")
8572 (plus:SI (match_operand:SI 1 "register_operand" "r")
8573 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8574 (match_operand 3 "tld_symbolic_operand" "")]
8576 "TARGET_SUN_TLS && TARGET_ARCH32"
8577 "add\\t%1, %2, %0, %%tie_add(%a3)")
8579 (define_insn "tie_add64"
8580 [(set (match_operand:DI 0 "register_operand" "=r")
8581 (plus:DI (match_operand:DI 1 "register_operand" "r")
8582 (unspec:DI [(match_operand:DI 2 "register_operand" "r")
8583 (match_operand 3 "tld_symbolic_operand" "")]
8585 "TARGET_SUN_TLS && TARGET_ARCH64"
8586 "add\\t%1, %2, %0, %%tie_add(%a3)")
8588 (define_insn "tle_hix22_sp32"
8589 [(set (match_operand:SI 0 "register_operand" "=r")
8590 (high:SI (unspec:SI [(match_operand 1 "tle_symbolic_operand" "")]
8592 "TARGET_TLS && TARGET_ARCH32"
8593 "sethi\\t%%tle_hix22(%a1), %0")
8595 (define_insn "tle_lox10_sp32"
8596 [(set (match_operand:SI 0 "register_operand" "=r")
8597 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
8598 (unspec:SI [(match_operand 2 "tle_symbolic_operand" "")]
8600 "TARGET_TLS && TARGET_ARCH32"
8601 "xor\\t%1, %%tle_lox10(%a2), %0")
8603 (define_insn "tle_hix22_sp64"
8604 [(set (match_operand:DI 0 "register_operand" "=r")
8605 (high:DI (unspec:DI [(match_operand 1 "tle_symbolic_operand" "")]
8607 "TARGET_TLS && TARGET_ARCH64"
8608 "sethi\\t%%tle_hix22(%a1), %0")
8610 (define_insn "tle_lox10_sp64"
8611 [(set (match_operand:DI 0 "register_operand" "=r")
8612 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
8613 (unspec:DI [(match_operand 2 "tle_symbolic_operand" "")]
8615 "TARGET_TLS && TARGET_ARCH64"
8616 "xor\\t%1, %%tle_lox10(%a2), %0")
8618 ;; Now patterns combinding tldo_add{32,64} with some integer loads or stores
8619 (define_insn "*tldo_ldub_sp32"
8620 [(set (match_operand:QI 0 "register_operand" "=r")
8621 (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8622 (match_operand 3 "tld_symbolic_operand" "")]
8624 (match_operand:SI 1 "register_operand" "r"))))]
8625 "TARGET_TLS && TARGET_ARCH32"
8626 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8627 [(set_attr "type" "load")
8628 (set_attr "us3load_type" "3cycle")])
8630 (define_insn "*tldo_ldub1_sp32"
8631 [(set (match_operand:HI 0 "register_operand" "=r")
8632 (zero_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8633 (match_operand 3 "tld_symbolic_operand" "")]
8635 (match_operand:SI 1 "register_operand" "r")))))]
8636 "TARGET_TLS && TARGET_ARCH32"
8637 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8638 [(set_attr "type" "load")
8639 (set_attr "us3load_type" "3cycle")])
8641 (define_insn "*tldo_ldub2_sp32"
8642 [(set (match_operand:SI 0 "register_operand" "=r")
8643 (zero_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8644 (match_operand 3 "tld_symbolic_operand" "")]
8646 (match_operand:SI 1 "register_operand" "r")))))]
8647 "TARGET_TLS && TARGET_ARCH32"
8648 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8649 [(set_attr "type" "load")
8650 (set_attr "us3load_type" "3cycle")])
8652 (define_insn "*tldo_ldsb1_sp32"
8653 [(set (match_operand:HI 0 "register_operand" "=r")
8654 (sign_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8655 (match_operand 3 "tld_symbolic_operand" "")]
8657 (match_operand:SI 1 "register_operand" "r")))))]
8658 "TARGET_TLS && TARGET_ARCH32"
8659 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
8660 [(set_attr "type" "sload")
8661 (set_attr "us3load_type" "3cycle")])
8663 (define_insn "*tldo_ldsb2_sp32"
8664 [(set (match_operand:SI 0 "register_operand" "=r")
8665 (sign_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8666 (match_operand 3 "tld_symbolic_operand" "")]
8668 (match_operand:SI 1 "register_operand" "r")))))]
8669 "TARGET_TLS && TARGET_ARCH32"
8670 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
8671 [(set_attr "type" "sload")
8672 (set_attr "us3load_type" "3cycle")])
8674 (define_insn "*tldo_ldub_sp64"
8675 [(set (match_operand:QI 0 "register_operand" "=r")
8676 (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8677 (match_operand 3 "tld_symbolic_operand" "")]
8679 (match_operand:DI 1 "register_operand" "r"))))]
8680 "TARGET_TLS && TARGET_ARCH64"
8681 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8682 [(set_attr "type" "load")
8683 (set_attr "us3load_type" "3cycle")])
8685 (define_insn "*tldo_ldub1_sp64"
8686 [(set (match_operand:HI 0 "register_operand" "=r")
8687 (zero_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8688 (match_operand 3 "tld_symbolic_operand" "")]
8690 (match_operand:DI 1 "register_operand" "r")))))]
8691 "TARGET_TLS && TARGET_ARCH64"
8692 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8693 [(set_attr "type" "load")
8694 (set_attr "us3load_type" "3cycle")])
8696 (define_insn "*tldo_ldub2_sp64"
8697 [(set (match_operand:SI 0 "register_operand" "=r")
8698 (zero_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8699 (match_operand 3 "tld_symbolic_operand" "")]
8701 (match_operand:DI 1 "register_operand" "r")))))]
8702 "TARGET_TLS && TARGET_ARCH64"
8703 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8704 [(set_attr "type" "load")
8705 (set_attr "us3load_type" "3cycle")])
8707 (define_insn "*tldo_ldub3_sp64"
8708 [(set (match_operand:DI 0 "register_operand" "=r")
8709 (zero_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8710 (match_operand 3 "tld_symbolic_operand" "")]
8712 (match_operand:DI 1 "register_operand" "r")))))]
8713 "TARGET_TLS && TARGET_ARCH64"
8714 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8715 [(set_attr "type" "load")
8716 (set_attr "us3load_type" "3cycle")])
8718 (define_insn "*tldo_ldsb1_sp64"
8719 [(set (match_operand:HI 0 "register_operand" "=r")
8720 (sign_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8721 (match_operand 3 "tld_symbolic_operand" "")]
8723 (match_operand:DI 1 "register_operand" "r")))))]
8724 "TARGET_TLS && TARGET_ARCH64"
8725 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
8726 [(set_attr "type" "sload")
8727 (set_attr "us3load_type" "3cycle")])
8729 (define_insn "*tldo_ldsb2_sp64"
8730 [(set (match_operand:SI 0 "register_operand" "=r")
8731 (sign_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8732 (match_operand 3 "tld_symbolic_operand" "")]
8734 (match_operand:DI 1 "register_operand" "r")))))]
8735 "TARGET_TLS && TARGET_ARCH64"
8736 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
8737 [(set_attr "type" "sload")
8738 (set_attr "us3load_type" "3cycle")])
8740 (define_insn "*tldo_ldsb3_sp64"
8741 [(set (match_operand:DI 0 "register_operand" "=r")
8742 (sign_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8743 (match_operand 3 "tld_symbolic_operand" "")]
8745 (match_operand:DI 1 "register_operand" "r")))))]
8746 "TARGET_TLS && TARGET_ARCH64"
8747 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
8748 [(set_attr "type" "sload")
8749 (set_attr "us3load_type" "3cycle")])
8751 (define_insn "*tldo_lduh_sp32"
8752 [(set (match_operand:HI 0 "register_operand" "=r")
8753 (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8754 (match_operand 3 "tld_symbolic_operand" "")]
8756 (match_operand:SI 1 "register_operand" "r"))))]
8757 "TARGET_TLS && TARGET_ARCH32"
8758 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
8759 [(set_attr "type" "load")
8760 (set_attr "us3load_type" "3cycle")])
8762 (define_insn "*tldo_lduh1_sp32"
8763 [(set (match_operand:SI 0 "register_operand" "=r")
8764 (zero_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8765 (match_operand 3 "tld_symbolic_operand" "")]
8767 (match_operand:SI 1 "register_operand" "r")))))]
8768 "TARGET_TLS && TARGET_ARCH32"
8769 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
8770 [(set_attr "type" "load")
8771 (set_attr "us3load_type" "3cycle")])
8773 (define_insn "*tldo_ldsh1_sp32"
8774 [(set (match_operand:SI 0 "register_operand" "=r")
8775 (sign_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8776 (match_operand 3 "tld_symbolic_operand" "")]
8778 (match_operand:SI 1 "register_operand" "r")))))]
8779 "TARGET_TLS && TARGET_ARCH32"
8780 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
8781 [(set_attr "type" "sload")
8782 (set_attr "us3load_type" "3cycle")])
8784 (define_insn "*tldo_lduh_sp64"
8785 [(set (match_operand:HI 0 "register_operand" "=r")
8786 (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8787 (match_operand 3 "tld_symbolic_operand" "")]
8789 (match_operand:DI 1 "register_operand" "r"))))]
8790 "TARGET_TLS && TARGET_ARCH64"
8791 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
8792 [(set_attr "type" "load")
8793 (set_attr "us3load_type" "3cycle")])
8795 (define_insn "*tldo_lduh1_sp64"
8796 [(set (match_operand:SI 0 "register_operand" "=r")
8797 (zero_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8798 (match_operand 3 "tld_symbolic_operand" "")]
8800 (match_operand:DI 1 "register_operand" "r")))))]
8801 "TARGET_TLS && TARGET_ARCH64"
8802 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
8803 [(set_attr "type" "load")
8804 (set_attr "us3load_type" "3cycle")])
8806 (define_insn "*tldo_lduh2_sp64"
8807 [(set (match_operand:DI 0 "register_operand" "=r")
8808 (zero_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8809 (match_operand 3 "tld_symbolic_operand" "")]
8811 (match_operand:DI 1 "register_operand" "r")))))]
8812 "TARGET_TLS && TARGET_ARCH64"
8813 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
8814 [(set_attr "type" "load")
8815 (set_attr "us3load_type" "3cycle")])
8817 (define_insn "*tldo_ldsh1_sp64"
8818 [(set (match_operand:SI 0 "register_operand" "=r")
8819 (sign_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8820 (match_operand 3 "tld_symbolic_operand" "")]
8822 (match_operand:DI 1 "register_operand" "r")))))]
8823 "TARGET_TLS && TARGET_ARCH64"
8824 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
8825 [(set_attr "type" "sload")
8826 (set_attr "us3load_type" "3cycle")])
8828 (define_insn "*tldo_ldsh2_sp64"
8829 [(set (match_operand:DI 0 "register_operand" "=r")
8830 (sign_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8831 (match_operand 3 "tld_symbolic_operand" "")]
8833 (match_operand:DI 1 "register_operand" "r")))))]
8834 "TARGET_TLS && TARGET_ARCH64"
8835 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
8836 [(set_attr "type" "sload")
8837 (set_attr "us3load_type" "3cycle")])
8839 (define_insn "*tldo_lduw_sp32"
8840 [(set (match_operand:SI 0 "register_operand" "=r")
8841 (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8842 (match_operand 3 "tld_symbolic_operand" "")]
8844 (match_operand:SI 1 "register_operand" "r"))))]
8845 "TARGET_TLS && TARGET_ARCH32"
8846 "ld\t[%1 + %2], %0, %%tldo_add(%3)"
8847 [(set_attr "type" "load")])
8849 (define_insn "*tldo_lduw_sp64"
8850 [(set (match_operand:SI 0 "register_operand" "=r")
8851 (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8852 (match_operand 3 "tld_symbolic_operand" "")]
8854 (match_operand:DI 1 "register_operand" "r"))))]
8855 "TARGET_TLS && TARGET_ARCH64"
8856 "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
8857 [(set_attr "type" "load")])
8859 (define_insn "*tldo_lduw1_sp64"
8860 [(set (match_operand:DI 0 "register_operand" "=r")
8861 (zero_extend:DI (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8862 (match_operand 3 "tld_symbolic_operand" "")]
8864 (match_operand:DI 1 "register_operand" "r")))))]
8865 "TARGET_TLS && TARGET_ARCH64"
8866 "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
8867 [(set_attr "type" "load")])
8869 (define_insn "*tldo_ldsw1_sp64"
8870 [(set (match_operand:DI 0 "register_operand" "=r")
8871 (sign_extend:DI (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8872 (match_operand 3 "tld_symbolic_operand" "")]
8874 (match_operand:DI 1 "register_operand" "r")))))]
8875 "TARGET_TLS && TARGET_ARCH64"
8876 "ldsw\t[%1 + %2], %0, %%tldo_add(%3)"
8877 [(set_attr "type" "sload")
8878 (set_attr "us3load_type" "3cycle")])
8880 (define_insn "*tldo_ldx_sp64"
8881 [(set (match_operand:DI 0 "register_operand" "=r")
8882 (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8883 (match_operand 3 "tld_symbolic_operand" "")]
8885 (match_operand:DI 1 "register_operand" "r"))))]
8886 "TARGET_TLS && TARGET_ARCH64"
8887 "ldx\t[%1 + %2], %0, %%tldo_add(%3)"
8888 [(set_attr "type" "load")])
8890 (define_insn "*tldo_stb_sp32"
8891 [(set (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8892 (match_operand 3 "tld_symbolic_operand" "")]
8894 (match_operand:SI 1 "register_operand" "r")))
8895 (match_operand:QI 0 "register_operand" "=r"))]
8896 "TARGET_TLS && TARGET_ARCH32"
8897 "stb\t%0, [%1 + %2], %%tldo_add(%3)"
8898 [(set_attr "type" "store")])
8900 (define_insn "*tldo_stb_sp64"
8901 [(set (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8902 (match_operand 3 "tld_symbolic_operand" "")]
8904 (match_operand:DI 1 "register_operand" "r")))
8905 (match_operand:QI 0 "register_operand" "=r"))]
8906 "TARGET_TLS && TARGET_ARCH64"
8907 "stb\t%0, [%1 + %2], %%tldo_add(%3)"
8908 [(set_attr "type" "store")])
8910 (define_insn "*tldo_sth_sp32"
8911 [(set (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8912 (match_operand 3 "tld_symbolic_operand" "")]
8914 (match_operand:SI 1 "register_operand" "r")))
8915 (match_operand:HI 0 "register_operand" "=r"))]
8916 "TARGET_TLS && TARGET_ARCH32"
8917 "sth\t%0, [%1 + %2], %%tldo_add(%3)"
8918 [(set_attr "type" "store")])
8920 (define_insn "*tldo_sth_sp64"
8921 [(set (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8922 (match_operand 3 "tld_symbolic_operand" "")]
8924 (match_operand:DI 1 "register_operand" "r")))
8925 (match_operand:HI 0 "register_operand" "=r"))]
8926 "TARGET_TLS && TARGET_ARCH64"
8927 "sth\t%0, [%1 + %2], %%tldo_add(%3)"
8928 [(set_attr "type" "store")])
8930 (define_insn "*tldo_stw_sp32"
8931 [(set (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8932 (match_operand 3 "tld_symbolic_operand" "")]
8934 (match_operand:SI 1 "register_operand" "r")))
8935 (match_operand:SI 0 "register_operand" "=r"))]
8936 "TARGET_TLS && TARGET_ARCH32"
8937 "st\t%0, [%1 + %2], %%tldo_add(%3)"
8938 [(set_attr "type" "store")])
8940 (define_insn "*tldo_stw_sp64"
8941 [(set (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8942 (match_operand 3 "tld_symbolic_operand" "")]
8944 (match_operand:DI 1 "register_operand" "r")))
8945 (match_operand:SI 0 "register_operand" "=r"))]
8946 "TARGET_TLS && TARGET_ARCH64"
8947 "stw\t%0, [%1 + %2], %%tldo_add(%3)"
8948 [(set_attr "type" "store")])
8950 (define_insn "*tldo_stx_sp64"
8951 [(set (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8952 (match_operand 3 "tld_symbolic_operand" "")]
8954 (match_operand:DI 1 "register_operand" "r")))
8955 (match_operand:DI 0 "register_operand" "=r"))]
8956 "TARGET_TLS && TARGET_ARCH64"
8957 "stx\t%0, [%1 + %2], %%tldo_add(%3)"
8958 [(set_attr "type" "store")])