1 ;; Machine description for SPARC chip for GNU C compiler
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 GNU CC.
10 ;; GNU CC 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 ;; GNU CC 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 GNU CC; 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)
52 ;; The upper 32 fp regs on the v9 can't hold SFmode values. To deal with this
53 ;; a second register class, EXTRA_FP_REGS, exists for the v9 chip. The name
54 ;; is a bit of a misnomer as it covers all 64 fp regs. The corresponding
55 ;; constraint letter is 'e'. To avoid any confusion, 'e' is used instead of
56 ;; 'f' for all DF/TFmode values, including those that are specific to the v8.
58 ;; Attribute for cpu type.
59 ;; These must match the values for enum processor_type in sparc.h.
66 hypersparc,sparclite86x,
71 (const (symbol_ref "sparc_cpu_attr")))
73 ;; Attribute for the instruction set.
74 ;; At present we only need to distinguish v9/!v9, but for clarity we
75 ;; test TARGET_V8 too.
76 (define_attr "isa" "v6,v8,v9,sparclet"
78 (cond [(symbol_ref "TARGET_V9") (const_string "v9")
79 (symbol_ref "TARGET_V8") (const_string "v8")
80 (symbol_ref "TARGET_SPARCLET") (const_string "sparclet")]
81 (const_string "v6"))))
84 (define_attr "arch" "arch32bit,arch64bit"
86 (cond [(symbol_ref "TARGET_ARCH64") (const_string "arch64bit")]
87 (const_string "arch32bit"))))
94 uncond_branch,branch,call,sibcall,call_no_delay_slot,
104 multi,flushw,iflush,trap"
105 (const_string "ialu"))
107 ;; true if branch/call has empty delay slot and will emit a nop in it
108 (define_attr "empty_delay_slot" "false,true"
109 (symbol_ref "empty_delay_slot (insn)"))
111 (define_attr "branch_type" "none,icc,fcc,reg" (const_string "none"))
113 (define_attr "pic" "false,true"
114 (symbol_ref "flag_pic != 0"))
116 (define_attr "current_function_calls_alloca" "false,true"
117 (symbol_ref "current_function_calls_alloca != 0"))
119 (define_attr "flat" "false,true"
120 (symbol_ref "TARGET_FLAT != 0"))
122 ;; Length (in # of insns).
123 (define_attr "length" ""
124 (cond [(eq_attr "type" "uncond_branch,call,sibcall")
125 (if_then_else (eq_attr "empty_delay_slot" "true")
128 (eq_attr "branch_type" "icc")
129 (if_then_else (match_operand 0 "noov_compare64_op" "")
130 (if_then_else (lt (pc) (match_dup 1))
131 (if_then_else (lt (minus (match_dup 1) (pc)) (const_int 260000))
132 (if_then_else (eq_attr "empty_delay_slot" "true")
135 (if_then_else (eq_attr "empty_delay_slot" "true")
138 (if_then_else (lt (minus (pc) (match_dup 1)) (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 (eq_attr "empty_delay_slot" "true")
148 (eq_attr "branch_type" "fcc")
149 (if_then_else (match_operand 0 "fcc0_reg_operand" "")
150 (if_then_else (eq_attr "empty_delay_slot" "true")
153 (if_then_else (lt (pc) (match_dup 2))
154 (if_then_else (lt (minus (match_dup 2) (pc)) (const_int 260000))
155 (if_then_else (eq_attr "empty_delay_slot" "true")
158 (if_then_else (eq_attr "empty_delay_slot" "true")
161 (if_then_else (lt (minus (pc) (match_dup 2)) (const_int 260000))
162 (if_then_else (eq_attr "empty_delay_slot" "true")
165 (if_then_else (eq_attr "empty_delay_slot" "true")
168 (eq_attr "branch_type" "reg")
169 (if_then_else (lt (pc) (match_dup 2))
170 (if_then_else (lt (minus (match_dup 2) (pc)) (const_int 32000))
171 (if_then_else (eq_attr "empty_delay_slot" "true")
174 (if_then_else (eq_attr "empty_delay_slot" "true")
177 (if_then_else (lt (minus (pc) (match_dup 2)) (const_int 32000))
178 (if_then_else (eq_attr "empty_delay_slot" "true")
181 (if_then_else (eq_attr "empty_delay_slot" "true")
187 (define_attr "fptype" "single,double" (const_string "single"))
189 ;; UltraSPARC-III integer load type.
190 (define_attr "us3load_type" "2cycle,3cycle" (const_string "2cycle"))
192 (define_asm_attributes
193 [(set_attr "length" "2")
194 (set_attr "type" "multi")])
196 ;; Attributes for instruction and branch scheduling
198 (define_attr "in_call_delay" "false,true"
199 (cond [(eq_attr "type" "uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
200 (const_string "false")
201 (eq_attr "type" "load,fpload,store,fpstore")
202 (if_then_else (eq_attr "length" "1")
203 (const_string "true")
204 (const_string "false"))]
205 (if_then_else (eq_attr "length" "1")
206 (const_string "true")
207 (const_string "false"))))
209 (define_delay (eq_attr "type" "call")
210 [(eq_attr "in_call_delay" "true") (nil) (nil)])
212 (define_attr "eligible_for_sibcall_delay" "false,true"
213 (symbol_ref "eligible_for_sibcall_delay (insn)"))
215 (define_delay (eq_attr "type" "sibcall")
216 [(eq_attr "eligible_for_sibcall_delay" "true") (nil) (nil)])
218 (define_attr "leaf_function" "false,true"
219 (const (symbol_ref "current_function_uses_only_leaf_regs")))
221 ;; ??? Should implement the notion of predelay slots for floating point
222 ;; branches. This would allow us to remove the nop always inserted before
223 ;; a floating point branch.
225 ;; ??? It is OK for fill_simple_delay_slots to put load/store instructions
226 ;; in a delay slot, but it is not OK for fill_eager_delay_slots to do so.
227 ;; This is because doing so will add several pipeline stalls to the path
228 ;; that the load/store did not come from. Unfortunately, there is no way
229 ;; to prevent fill_eager_delay_slots from using load/store without completely
230 ;; disabling them. For the SPEC benchmark set, this is a serious lose,
231 ;; because it prevents us from moving back the final store of inner loops.
233 (define_attr "in_branch_delay" "false,true"
234 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
235 (eq_attr "length" "1"))
236 (const_string "true")
237 (const_string "false")))
239 (define_attr "in_uncond_branch_delay" "false,true"
240 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
241 (eq_attr "length" "1"))
242 (const_string "true")
243 (const_string "false")))
245 (define_attr "in_annul_branch_delay" "false,true"
246 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
247 (eq_attr "length" "1"))
248 (const_string "true")
249 (const_string "false")))
251 (define_delay (eq_attr "type" "branch")
252 [(eq_attr "in_branch_delay" "true")
253 (nil) (eq_attr "in_annul_branch_delay" "true")])
255 (define_delay (eq_attr "type" "uncond_branch")
256 [(eq_attr "in_uncond_branch_delay" "true")
259 ;; Include SPARC DFA schedulers
261 (include "cypress.md")
262 (include "supersparc.md")
263 (include "hypersparc.md")
264 (include "sparclet.md")
265 (include "ultra1_2.md")
266 (include "ultra3.md")
269 ;; Compare instructions.
270 ;; This controls RTL generation and register allocation.
272 ;; We generate RTL for comparisons and branches by having the cmpxx
273 ;; patterns store away the operands. Then, the scc and bcc patterns
274 ;; emit RTL for both the compare and the branch.
276 ;; We do this because we want to generate different code for an sne and
277 ;; seq insn. In those cases, if the second operand of the compare is not
278 ;; const0_rtx, we want to compute the xor of the two operands and test
281 ;; We start with the DEFINE_EXPANDs, then the DEFINE_INSNs to match
282 ;; the patterns. Finally, we have the DEFINE_SPLITs for some of the scc
283 ;; insns that actually require more than one machine instruction.
285 ;; Put cmpsi first among compare insns so it matches two CONST_INT operands.
287 (define_expand "cmpsi"
289 (compare:CC (match_operand:SI 0 "register_operand" "")
290 (match_operand:SI 1 "arith_operand" "")))]
294 sparc_compare_op0 = operands[0];
295 sparc_compare_op1 = operands[1];
299 (define_expand "cmpdi"
301 (compare:CCX (match_operand:DI 0 "register_operand" "")
302 (match_operand:DI 1 "arith_double_operand" "")))]
306 sparc_compare_op0 = operands[0];
307 sparc_compare_op1 = operands[1];
311 (define_expand "cmpsf"
312 ;; The 96 here isn't ever used by anyone.
314 (compare:CCFP (match_operand:SF 0 "register_operand" "")
315 (match_operand:SF 1 "register_operand" "")))]
319 sparc_compare_op0 = operands[0];
320 sparc_compare_op1 = operands[1];
324 (define_expand "cmpdf"
325 ;; The 96 here isn't ever used by anyone.
327 (compare:CCFP (match_operand:DF 0 "register_operand" "")
328 (match_operand:DF 1 "register_operand" "")))]
332 sparc_compare_op0 = operands[0];
333 sparc_compare_op1 = operands[1];
337 (define_expand "cmptf"
338 ;; The 96 here isn't ever used by anyone.
340 (compare:CCFP (match_operand:TF 0 "register_operand" "")
341 (match_operand:TF 1 "register_operand" "")))]
345 sparc_compare_op0 = operands[0];
346 sparc_compare_op1 = operands[1];
350 ;; Now the compare DEFINE_INSNs.
352 (define_insn "*cmpsi_insn"
354 (compare:CC (match_operand:SI 0 "register_operand" "r")
355 (match_operand:SI 1 "arith_operand" "rI")))]
358 [(set_attr "type" "compare")])
360 (define_insn "*cmpdi_sp64"
362 (compare:CCX (match_operand:DI 0 "register_operand" "r")
363 (match_operand:DI 1 "arith_double_operand" "rHI")))]
366 [(set_attr "type" "compare")])
368 (define_insn "*cmpsf_fpe"
369 [(set (match_operand:CCFPE 0 "fcc_reg_operand" "=c")
370 (compare:CCFPE (match_operand:SF 1 "register_operand" "f")
371 (match_operand:SF 2 "register_operand" "f")))]
376 return \"fcmpes\\t%0, %1, %2\";
377 return \"fcmpes\\t%1, %2\";
379 [(set_attr "type" "fpcmp")])
381 (define_insn "*cmpdf_fpe"
382 [(set (match_operand:CCFPE 0 "fcc_reg_operand" "=c")
383 (compare:CCFPE (match_operand:DF 1 "register_operand" "e")
384 (match_operand:DF 2 "register_operand" "e")))]
389 return \"fcmped\\t%0, %1, %2\";
390 return \"fcmped\\t%1, %2\";
392 [(set_attr "type" "fpcmp")
393 (set_attr "fptype" "double")])
395 (define_insn "*cmptf_fpe"
396 [(set (match_operand:CCFPE 0 "fcc_reg_operand" "=c")
397 (compare:CCFPE (match_operand:TF 1 "register_operand" "e")
398 (match_operand:TF 2 "register_operand" "e")))]
399 "TARGET_FPU && TARGET_HARD_QUAD"
403 return \"fcmpeq\\t%0, %1, %2\";
404 return \"fcmpeq\\t%1, %2\";
406 [(set_attr "type" "fpcmp")])
408 (define_insn "*cmpsf_fp"
409 [(set (match_operand:CCFP 0 "fcc_reg_operand" "=c")
410 (compare:CCFP (match_operand:SF 1 "register_operand" "f")
411 (match_operand:SF 2 "register_operand" "f")))]
416 return \"fcmps\\t%0, %1, %2\";
417 return \"fcmps\\t%1, %2\";
419 [(set_attr "type" "fpcmp")])
421 (define_insn "*cmpdf_fp"
422 [(set (match_operand:CCFP 0 "fcc_reg_operand" "=c")
423 (compare:CCFP (match_operand:DF 1 "register_operand" "e")
424 (match_operand:DF 2 "register_operand" "e")))]
429 return \"fcmpd\\t%0, %1, %2\";
430 return \"fcmpd\\t%1, %2\";
432 [(set_attr "type" "fpcmp")
433 (set_attr "fptype" "double")])
435 (define_insn "*cmptf_fp"
436 [(set (match_operand:CCFP 0 "fcc_reg_operand" "=c")
437 (compare:CCFP (match_operand:TF 1 "register_operand" "e")
438 (match_operand:TF 2 "register_operand" "e")))]
439 "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)))]
542 if (GET_MODE (sparc_compare_op0) == SImode)
546 if (GET_MODE (operands[0]) == SImode)
547 pat = gen_seqsi_special (operands[0], sparc_compare_op0,
549 else if (! TARGET_ARCH64)
552 pat = gen_seqsi_special_extend (operands[0], sparc_compare_op0,
557 else if (GET_MODE (sparc_compare_op0) == DImode)
563 else if (GET_MODE (operands[0]) == SImode)
564 pat = gen_seqdi_special_trunc (operands[0], sparc_compare_op0,
567 pat = gen_seqdi_special (operands[0], sparc_compare_op0,
572 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
574 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, EQ);
575 emit_jump_insn (gen_sne (operands[0]));
580 if (gen_v9_scc (EQ, operands))
587 ;; ??? v9: Operand 0 needs a mode, so SImode was chosen.
588 ;; However, the code handles both SImode and DImode.
590 [(set (match_operand:SI 0 "intreg_operand" "")
591 (ne:SI (match_dup 1) (const_int 0)))]
595 if (GET_MODE (sparc_compare_op0) == SImode)
599 if (GET_MODE (operands[0]) == SImode)
600 pat = gen_snesi_special (operands[0], sparc_compare_op0,
602 else if (! TARGET_ARCH64)
605 pat = gen_snesi_special_extend (operands[0], sparc_compare_op0,
610 else if (GET_MODE (sparc_compare_op0) == DImode)
616 else if (GET_MODE (operands[0]) == SImode)
617 pat = gen_snedi_special_trunc (operands[0], sparc_compare_op0,
620 pat = gen_snedi_special (operands[0], sparc_compare_op0,
625 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
627 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, NE);
628 emit_jump_insn (gen_sne (operands[0]));
633 if (gen_v9_scc (NE, operands))
641 [(set (match_operand:SI 0 "intreg_operand" "")
642 (gt:SI (match_dup 1) (const_int 0)))]
646 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
648 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GT);
649 emit_jump_insn (gen_sne (operands[0]));
654 if (gen_v9_scc (GT, operands))
662 [(set (match_operand:SI 0 "intreg_operand" "")
663 (lt:SI (match_dup 1) (const_int 0)))]
667 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
669 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LT);
670 emit_jump_insn (gen_sne (operands[0]));
675 if (gen_v9_scc (LT, operands))
683 [(set (match_operand:SI 0 "intreg_operand" "")
684 (ge:SI (match_dup 1) (const_int 0)))]
688 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
690 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GE);
691 emit_jump_insn (gen_sne (operands[0]));
696 if (gen_v9_scc (GE, operands))
704 [(set (match_operand:SI 0 "intreg_operand" "")
705 (le:SI (match_dup 1) (const_int 0)))]
709 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
711 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LE);
712 emit_jump_insn (gen_sne (operands[0]));
717 if (gen_v9_scc (LE, operands))
724 (define_expand "sgtu"
725 [(set (match_operand:SI 0 "intreg_operand" "")
726 (gtu:SI (match_dup 1) (const_int 0)))]
734 /* We can do ltu easily, so if both operands are registers, swap them and
736 if ((GET_CODE (sparc_compare_op0) == REG
737 || GET_CODE (sparc_compare_op0) == SUBREG)
738 && (GET_CODE (sparc_compare_op1) == REG
739 || GET_CODE (sparc_compare_op1) == SUBREG))
741 tem = sparc_compare_op0;
742 sparc_compare_op0 = sparc_compare_op1;
743 sparc_compare_op1 = tem;
744 pat = gen_sltu (operands[0]);
753 if (gen_v9_scc (GTU, operands))
759 (define_expand "sltu"
760 [(set (match_operand:SI 0 "intreg_operand" "")
761 (ltu:SI (match_dup 1) (const_int 0)))]
767 if (gen_v9_scc (LTU, operands))
770 operands[1] = gen_compare_reg (LTU, sparc_compare_op0, sparc_compare_op1);
773 (define_expand "sgeu"
774 [(set (match_operand:SI 0 "intreg_operand" "")
775 (geu:SI (match_dup 1) (const_int 0)))]
781 if (gen_v9_scc (GEU, operands))
784 operands[1] = gen_compare_reg (GEU, sparc_compare_op0, sparc_compare_op1);
787 (define_expand "sleu"
788 [(set (match_operand:SI 0 "intreg_operand" "")
789 (leu:SI (match_dup 1) (const_int 0)))]
797 /* We can do geu easily, so if both operands are registers, swap them and
799 if ((GET_CODE (sparc_compare_op0) == REG
800 || GET_CODE (sparc_compare_op0) == SUBREG)
801 && (GET_CODE (sparc_compare_op1) == REG
802 || GET_CODE (sparc_compare_op1) == SUBREG))
804 tem = sparc_compare_op0;
805 sparc_compare_op0 = sparc_compare_op1;
806 sparc_compare_op1 = tem;
807 pat = gen_sgeu (operands[0]);
816 if (gen_v9_scc (LEU, operands))
822 ;; Now the DEFINE_INSNs for the scc cases.
824 ;; The SEQ and SNE patterns are special because they can be done
825 ;; without any branching and do not involve a COMPARE. We want
826 ;; them to always use the splitz below so the results can be
829 (define_insn_and_split "*snesi_zero"
830 [(set (match_operand:SI 0 "register_operand" "=r")
831 (ne:SI (match_operand:SI 1 "register_operand" "r")
833 (clobber (reg:CC 100))]
837 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
839 (set (match_dup 0) (ltu:SI (reg:CC 100) (const_int 0)))]
841 [(set_attr "length" "2")])
843 (define_insn_and_split "*neg_snesi_zero"
844 [(set (match_operand:SI 0 "register_operand" "=r")
845 (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
847 (clobber (reg:CC 100))]
851 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
853 (set (match_dup 0) (neg:SI (ltu:SI (reg:CC 100) (const_int 0))))]
855 [(set_attr "length" "2")])
857 (define_insn_and_split "*snesi_zero_extend"
858 [(set (match_operand:DI 0 "register_operand" "=r")
859 (ne:DI (match_operand:SI 1 "register_operand" "r")
861 (clobber (reg:CC 100))]
865 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (minus:SI (const_int 0)
868 (set (match_dup 0) (zero_extend:DI (plus:SI (plus:SI (const_int 0)
870 (ltu:SI (reg:CC_NOOV 100)
873 [(set_attr "length" "2")])
875 (define_insn_and_split "*snedi_zero"
876 [(set (match_operand:DI 0 "register_operand" "=&r")
877 (ne:DI (match_operand:DI 1 "register_operand" "r")
881 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
882 [(set (match_dup 0) (const_int 0))
883 (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
888 [(set_attr "length" "2")])
890 (define_insn_and_split "*neg_snedi_zero"
891 [(set (match_operand:DI 0 "register_operand" "=&r")
892 (neg:DI (ne:DI (match_operand:DI 1 "register_operand" "r")
896 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
897 [(set (match_dup 0) (const_int 0))
898 (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
903 [(set_attr "length" "2")])
905 (define_insn_and_split "*snedi_zero_trunc"
906 [(set (match_operand:SI 0 "register_operand" "=&r")
907 (ne:SI (match_operand:DI 1 "register_operand" "r")
911 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
912 [(set (match_dup 0) (const_int 0))
913 (set (match_dup 0) (if_then_else:SI (ne:DI (match_dup 1)
918 [(set_attr "length" "2")])
920 (define_insn_and_split "*seqsi_zero"
921 [(set (match_operand:SI 0 "register_operand" "=r")
922 (eq:SI (match_operand:SI 1 "register_operand" "r")
924 (clobber (reg:CC 100))]
928 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
930 (set (match_dup 0) (geu:SI (reg:CC 100) (const_int 0)))]
932 [(set_attr "length" "2")])
934 (define_insn_and_split "*neg_seqsi_zero"
935 [(set (match_operand:SI 0 "register_operand" "=r")
936 (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
938 (clobber (reg:CC 100))]
942 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
944 (set (match_dup 0) (neg:SI (geu:SI (reg:CC 100) (const_int 0))))]
946 [(set_attr "length" "2")])
948 (define_insn_and_split "*seqsi_zero_extend"
949 [(set (match_operand:DI 0 "register_operand" "=r")
950 (eq:DI (match_operand:SI 1 "register_operand" "r")
952 (clobber (reg:CC 100))]
956 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (minus:SI (const_int 0)
959 (set (match_dup 0) (zero_extend:DI (minus:SI (minus:SI (const_int 0)
961 (ltu:SI (reg:CC_NOOV 100)
964 [(set_attr "length" "2")])
966 (define_insn_and_split "*seqdi_zero"
967 [(set (match_operand:DI 0 "register_operand" "=&r")
968 (eq:DI (match_operand:DI 1 "register_operand" "r")
972 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
973 [(set (match_dup 0) (const_int 0))
974 (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
979 [(set_attr "length" "2")])
981 (define_insn_and_split "*neg_seqdi_zero"
982 [(set (match_operand:DI 0 "register_operand" "=&r")
983 (neg:DI (eq:DI (match_operand:DI 1 "register_operand" "r")
987 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
988 [(set (match_dup 0) (const_int 0))
989 (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
994 [(set_attr "length" "2")])
996 (define_insn_and_split "*seqdi_zero_trunc"
997 [(set (match_operand:SI 0 "register_operand" "=&r")
998 (eq:SI (match_operand:DI 1 "register_operand" "r")
1002 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
1003 [(set (match_dup 0) (const_int 0))
1004 (set (match_dup 0) (if_then_else:SI (eq:DI (match_dup 1)
1009 [(set_attr "length" "2")])
1011 ;; We can also do (x + (i == 0)) and related, so put them in.
1012 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1015 (define_insn_and_split "*x_plus_i_ne_0"
1016 [(set (match_operand:SI 0 "register_operand" "=r")
1017 (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
1019 (match_operand:SI 2 "register_operand" "r")))
1020 (clobber (reg:CC 100))]
1024 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1026 (set (match_dup 0) (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1029 [(set_attr "length" "2")])
1031 (define_insn_and_split "*x_minus_i_ne_0"
1032 [(set (match_operand:SI 0 "register_operand" "=r")
1033 (minus:SI (match_operand:SI 2 "register_operand" "r")
1034 (ne:SI (match_operand:SI 1 "register_operand" "r")
1036 (clobber (reg:CC 100))]
1040 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1042 (set (match_dup 0) (minus:SI (match_dup 2)
1043 (ltu:SI (reg:CC 100) (const_int 0))))]
1045 [(set_attr "length" "2")])
1047 (define_insn_and_split "*x_plus_i_eq_0"
1048 [(set (match_operand:SI 0 "register_operand" "=r")
1049 (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
1051 (match_operand:SI 2 "register_operand" "r")))
1052 (clobber (reg:CC 100))]
1056 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1058 (set (match_dup 0) (plus:SI (geu:SI (reg:CC 100) (const_int 0))
1061 [(set_attr "length" "2")])
1063 (define_insn_and_split "*x_minus_i_eq_0"
1064 [(set (match_operand:SI 0 "register_operand" "=r")
1065 (minus:SI (match_operand:SI 2 "register_operand" "r")
1066 (eq:SI (match_operand:SI 1 "register_operand" "r")
1068 (clobber (reg:CC 100))]
1072 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1074 (set (match_dup 0) (minus:SI (match_dup 2)
1075 (geu:SI (reg:CC 100) (const_int 0))))]
1077 [(set_attr "length" "2")])
1079 ;; We can also do GEU and LTU directly, but these operate after a compare.
1080 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1083 (define_insn "*sltu_insn"
1084 [(set (match_operand:SI 0 "register_operand" "=r")
1085 (ltu:SI (reg:CC 100) (const_int 0)))]
1087 "addx\\t%%g0, 0, %0"
1088 [(set_attr "type" "ialuX")])
1090 (define_insn "*neg_sltu_insn"
1091 [(set (match_operand:SI 0 "register_operand" "=r")
1092 (neg:SI (ltu:SI (reg:CC 100) (const_int 0))))]
1094 "subx\\t%%g0, 0, %0"
1095 [(set_attr "type" "ialuX")])
1097 ;; ??? Combine should canonicalize these next two to the same pattern.
1098 (define_insn "*neg_sltu_minus_x"
1099 [(set (match_operand:SI 0 "register_operand" "=r")
1100 (minus:SI (neg:SI (ltu:SI (reg:CC 100) (const_int 0)))
1101 (match_operand:SI 1 "arith_operand" "rI")))]
1103 "subx\\t%%g0, %1, %0"
1104 [(set_attr "type" "ialuX")])
1106 (define_insn "*neg_sltu_plus_x"
1107 [(set (match_operand:SI 0 "register_operand" "=r")
1108 (neg:SI (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1109 (match_operand:SI 1 "arith_operand" "rI"))))]
1111 "subx\\t%%g0, %1, %0"
1112 [(set_attr "type" "ialuX")])
1114 (define_insn "*sgeu_insn"
1115 [(set (match_operand:SI 0 "register_operand" "=r")
1116 (geu:SI (reg:CC 100) (const_int 0)))]
1118 "subx\\t%%g0, -1, %0"
1119 [(set_attr "type" "ialuX")])
1121 (define_insn "*neg_sgeu_insn"
1122 [(set (match_operand:SI 0 "register_operand" "=r")
1123 (neg:SI (geu:SI (reg:CC 100) (const_int 0))))]
1125 "addx\\t%%g0, -1, %0"
1126 [(set_attr "type" "ialuX")])
1128 ;; We can also do (x + ((unsigned) i >= 0)) and related, so put them in.
1129 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1132 (define_insn "*sltu_plus_x"
1133 [(set (match_operand:SI 0 "register_operand" "=r")
1134 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1135 (match_operand:SI 1 "arith_operand" "rI")))]
1137 "addx\\t%%g0, %1, %0"
1138 [(set_attr "type" "ialuX")])
1140 (define_insn "*sltu_plus_x_plus_y"
1141 [(set (match_operand:SI 0 "register_operand" "=r")
1142 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1143 (plus:SI (match_operand:SI 1 "arith_operand" "%r")
1144 (match_operand:SI 2 "arith_operand" "rI"))))]
1147 [(set_attr "type" "ialuX")])
1149 (define_insn "*x_minus_sltu"
1150 [(set (match_operand:SI 0 "register_operand" "=r")
1151 (minus:SI (match_operand:SI 1 "register_operand" "r")
1152 (ltu:SI (reg:CC 100) (const_int 0))))]
1155 [(set_attr "type" "ialuX")])
1157 ;; ??? Combine should canonicalize these next two to the same pattern.
1158 (define_insn "*x_minus_y_minus_sltu"
1159 [(set (match_operand:SI 0 "register_operand" "=r")
1160 (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
1161 (match_operand:SI 2 "arith_operand" "rI"))
1162 (ltu:SI (reg:CC 100) (const_int 0))))]
1164 "subx\\t%r1, %2, %0"
1165 [(set_attr "type" "ialuX")])
1167 (define_insn "*x_minus_sltu_plus_y"
1168 [(set (match_operand:SI 0 "register_operand" "=r")
1169 (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
1170 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1171 (match_operand:SI 2 "arith_operand" "rI"))))]
1173 "subx\\t%r1, %2, %0"
1174 [(set_attr "type" "ialuX")])
1176 (define_insn "*sgeu_plus_x"
1177 [(set (match_operand:SI 0 "register_operand" "=r")
1178 (plus:SI (geu:SI (reg:CC 100) (const_int 0))
1179 (match_operand:SI 1 "register_operand" "r")))]
1182 [(set_attr "type" "ialuX")])
1184 (define_insn "*x_minus_sgeu"
1185 [(set (match_operand:SI 0 "register_operand" "=r")
1186 (minus:SI (match_operand:SI 1 "register_operand" "r")
1187 (geu:SI (reg:CC 100) (const_int 0))))]
1190 [(set_attr "type" "ialuX")])
1193 [(set (match_operand:SI 0 "register_operand" "")
1194 (match_operator:SI 2 "noov_compare_op"
1195 [(match_operand 1 "icc_or_fcc_reg_operand" "")
1197 ;; 32 bit LTU/GEU are better implemented using addx/subx
1198 "TARGET_V9 && REGNO (operands[1]) == SPARC_ICC_REG
1199 && (GET_MODE (operands[1]) == CCXmode
1200 || (GET_CODE (operands[2]) != LTU && GET_CODE (operands[2]) != GEU))"
1201 [(set (match_dup 0) (const_int 0))
1203 (if_then_else:SI (match_op_dup:SI 2 [(match_dup 1) (const_int 0)])
1209 ;; These control RTL generation for conditional jump insns
1211 ;; The quad-word fp compare library routines all return nonzero to indicate
1212 ;; true, which is different from the equivalent libgcc routines, so we must
1213 ;; handle them specially here.
1215 (define_expand "beq"
1217 (if_then_else (eq (match_dup 1) (const_int 0))
1218 (label_ref (match_operand 0 "" ""))
1223 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1224 && GET_CODE (sparc_compare_op0) == REG
1225 && GET_MODE (sparc_compare_op0) == DImode)
1227 emit_v9_brxx_insn (EQ, sparc_compare_op0, operands[0]);
1230 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1232 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, EQ);
1233 emit_jump_insn (gen_bne (operands[0]));
1236 operands[1] = gen_compare_reg (EQ, sparc_compare_op0, sparc_compare_op1);
1239 (define_expand "bne"
1241 (if_then_else (ne (match_dup 1) (const_int 0))
1242 (label_ref (match_operand 0 "" ""))
1247 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1248 && GET_CODE (sparc_compare_op0) == REG
1249 && GET_MODE (sparc_compare_op0) == DImode)
1251 emit_v9_brxx_insn (NE, sparc_compare_op0, operands[0]);
1254 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1256 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, NE);
1257 emit_jump_insn (gen_bne (operands[0]));
1260 operands[1] = gen_compare_reg (NE, sparc_compare_op0, sparc_compare_op1);
1263 (define_expand "bgt"
1265 (if_then_else (gt (match_dup 1) (const_int 0))
1266 (label_ref (match_operand 0 "" ""))
1271 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1272 && GET_CODE (sparc_compare_op0) == REG
1273 && GET_MODE (sparc_compare_op0) == DImode)
1275 emit_v9_brxx_insn (GT, sparc_compare_op0, operands[0]);
1278 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1280 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GT);
1281 emit_jump_insn (gen_bne (operands[0]));
1284 operands[1] = gen_compare_reg (GT, sparc_compare_op0, sparc_compare_op1);
1287 (define_expand "bgtu"
1289 (if_then_else (gtu (match_dup 1) (const_int 0))
1290 (label_ref (match_operand 0 "" ""))
1294 { operands[1] = gen_compare_reg (GTU, sparc_compare_op0, sparc_compare_op1);
1297 (define_expand "blt"
1299 (if_then_else (lt (match_dup 1) (const_int 0))
1300 (label_ref (match_operand 0 "" ""))
1305 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1306 && GET_CODE (sparc_compare_op0) == REG
1307 && GET_MODE (sparc_compare_op0) == DImode)
1309 emit_v9_brxx_insn (LT, sparc_compare_op0, operands[0]);
1312 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1314 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LT);
1315 emit_jump_insn (gen_bne (operands[0]));
1318 operands[1] = gen_compare_reg (LT, sparc_compare_op0, sparc_compare_op1);
1321 (define_expand "bltu"
1323 (if_then_else (ltu (match_dup 1) (const_int 0))
1324 (label_ref (match_operand 0 "" ""))
1328 { operands[1] = gen_compare_reg (LTU, sparc_compare_op0, sparc_compare_op1);
1331 (define_expand "bge"
1333 (if_then_else (ge (match_dup 1) (const_int 0))
1334 (label_ref (match_operand 0 "" ""))
1339 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1340 && GET_CODE (sparc_compare_op0) == REG
1341 && GET_MODE (sparc_compare_op0) == DImode)
1343 emit_v9_brxx_insn (GE, sparc_compare_op0, operands[0]);
1346 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1348 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GE);
1349 emit_jump_insn (gen_bne (operands[0]));
1352 operands[1] = gen_compare_reg (GE, sparc_compare_op0, sparc_compare_op1);
1355 (define_expand "bgeu"
1357 (if_then_else (geu (match_dup 1) (const_int 0))
1358 (label_ref (match_operand 0 "" ""))
1362 { operands[1] = gen_compare_reg (GEU, sparc_compare_op0, sparc_compare_op1);
1365 (define_expand "ble"
1367 (if_then_else (le (match_dup 1) (const_int 0))
1368 (label_ref (match_operand 0 "" ""))
1373 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1374 && GET_CODE (sparc_compare_op0) == REG
1375 && GET_MODE (sparc_compare_op0) == DImode)
1377 emit_v9_brxx_insn (LE, sparc_compare_op0, operands[0]);
1380 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1382 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LE);
1383 emit_jump_insn (gen_bne (operands[0]));
1386 operands[1] = gen_compare_reg (LE, sparc_compare_op0, sparc_compare_op1);
1389 (define_expand "bleu"
1391 (if_then_else (leu (match_dup 1) (const_int 0))
1392 (label_ref (match_operand 0 "" ""))
1396 { operands[1] = gen_compare_reg (LEU, sparc_compare_op0, sparc_compare_op1);
1399 (define_expand "bunordered"
1401 (if_then_else (unordered (match_dup 1) (const_int 0))
1402 (label_ref (match_operand 0 "" ""))
1407 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1409 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1,
1411 emit_jump_insn (gen_beq (operands[0]));
1414 operands[1] = gen_compare_reg (UNORDERED, sparc_compare_op0,
1418 (define_expand "bordered"
1420 (if_then_else (ordered (match_dup 1) (const_int 0))
1421 (label_ref (match_operand 0 "" ""))
1426 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1428 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, ORDERED);
1429 emit_jump_insn (gen_bne (operands[0]));
1432 operands[1] = gen_compare_reg (ORDERED, sparc_compare_op0,
1436 (define_expand "bungt"
1438 (if_then_else (ungt (match_dup 1) (const_int 0))
1439 (label_ref (match_operand 0 "" ""))
1444 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1446 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNGT);
1447 emit_jump_insn (gen_bgt (operands[0]));
1450 operands[1] = gen_compare_reg (UNGT, sparc_compare_op0, sparc_compare_op1);
1453 (define_expand "bunlt"
1455 (if_then_else (unlt (match_dup 1) (const_int 0))
1456 (label_ref (match_operand 0 "" ""))
1461 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1463 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNLT);
1464 emit_jump_insn (gen_bne (operands[0]));
1467 operands[1] = gen_compare_reg (UNLT, sparc_compare_op0, sparc_compare_op1);
1470 (define_expand "buneq"
1472 (if_then_else (uneq (match_dup 1) (const_int 0))
1473 (label_ref (match_operand 0 "" ""))
1478 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1480 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNEQ);
1481 emit_jump_insn (gen_beq (operands[0]));
1484 operands[1] = gen_compare_reg (UNEQ, sparc_compare_op0, sparc_compare_op1);
1487 (define_expand "bunge"
1489 (if_then_else (unge (match_dup 1) (const_int 0))
1490 (label_ref (match_operand 0 "" ""))
1495 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1497 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNGE);
1498 emit_jump_insn (gen_bne (operands[0]));
1501 operands[1] = gen_compare_reg (UNGE, sparc_compare_op0, sparc_compare_op1);
1504 (define_expand "bunle"
1506 (if_then_else (unle (match_dup 1) (const_int 0))
1507 (label_ref (match_operand 0 "" ""))
1512 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1514 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNLE);
1515 emit_jump_insn (gen_bne (operands[0]));
1518 operands[1] = gen_compare_reg (UNLE, sparc_compare_op0, sparc_compare_op1);
1521 (define_expand "bltgt"
1523 (if_then_else (ltgt (match_dup 1) (const_int 0))
1524 (label_ref (match_operand 0 "" ""))
1529 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1531 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LTGT);
1532 emit_jump_insn (gen_bne (operands[0]));
1535 operands[1] = gen_compare_reg (LTGT, sparc_compare_op0, sparc_compare_op1);
1538 ;; Now match both normal and inverted jump.
1540 ;; XXX fpcmp nop braindamage
1541 (define_insn "*normal_branch"
1543 (if_then_else (match_operator 0 "noov_compare_op"
1544 [(reg 100) (const_int 0)])
1545 (label_ref (match_operand 1 "" ""))
1550 return output_cbranch (operands[0], operands[1], 1, 0,
1551 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1552 ! final_sequence, insn);
1554 [(set_attr "type" "branch")
1555 (set_attr "branch_type" "icc")])
1557 ;; XXX fpcmp nop braindamage
1558 (define_insn "*inverted_branch"
1560 (if_then_else (match_operator 0 "noov_compare_op"
1561 [(reg 100) (const_int 0)])
1563 (label_ref (match_operand 1 "" ""))))]
1567 return output_cbranch (operands[0], operands[1], 1, 1,
1568 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1569 ! final_sequence, insn);
1571 [(set_attr "type" "branch")
1572 (set_attr "branch_type" "icc")])
1574 ;; XXX fpcmp nop braindamage
1575 (define_insn "*normal_fp_branch"
1577 (if_then_else (match_operator 1 "comparison_operator"
1578 [(match_operand:CCFP 0 "fcc_reg_operand" "c")
1580 (label_ref (match_operand 2 "" ""))
1585 return output_cbranch (operands[1], operands[2], 2, 0,
1586 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1587 ! final_sequence, insn);
1589 [(set_attr "type" "branch")
1590 (set_attr "branch_type" "fcc")])
1592 ;; XXX fpcmp nop braindamage
1593 (define_insn "*inverted_fp_branch"
1595 (if_then_else (match_operator 1 "comparison_operator"
1596 [(match_operand:CCFP 0 "fcc_reg_operand" "c")
1599 (label_ref (match_operand 2 "" ""))))]
1603 return output_cbranch (operands[1], operands[2], 2, 1,
1604 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1605 ! final_sequence, insn);
1607 [(set_attr "type" "branch")
1608 (set_attr "branch_type" "fcc")])
1610 ;; XXX fpcmp nop braindamage
1611 (define_insn "*normal_fpe_branch"
1613 (if_then_else (match_operator 1 "comparison_operator"
1614 [(match_operand:CCFPE 0 "fcc_reg_operand" "c")
1616 (label_ref (match_operand 2 "" ""))
1621 return output_cbranch (operands[1], operands[2], 2, 0,
1622 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1623 ! final_sequence, insn);
1625 [(set_attr "type" "branch")
1626 (set_attr "branch_type" "fcc")])
1628 ;; XXX fpcmp nop braindamage
1629 (define_insn "*inverted_fpe_branch"
1631 (if_then_else (match_operator 1 "comparison_operator"
1632 [(match_operand:CCFPE 0 "fcc_reg_operand" "c")
1635 (label_ref (match_operand 2 "" ""))))]
1639 return output_cbranch (operands[1], operands[2], 2, 1,
1640 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1641 ! final_sequence, insn);
1643 [(set_attr "type" "branch")
1644 (set_attr "branch_type" "fcc")])
1646 ;; Sparc V9-specific jump insns. None of these are guaranteed to be
1647 ;; in the architecture.
1649 ;; There are no 32 bit brreg insns.
1652 (define_insn "*normal_int_branch_sp64"
1654 (if_then_else (match_operator 0 "v9_regcmp_op"
1655 [(match_operand:DI 1 "register_operand" "r")
1657 (label_ref (match_operand 2 "" ""))
1662 return output_v9branch (operands[0], operands[2], 1, 2, 0,
1663 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1664 ! final_sequence, insn);
1666 [(set_attr "type" "branch")
1667 (set_attr "branch_type" "reg")])
1670 (define_insn "*inverted_int_branch_sp64"
1672 (if_then_else (match_operator 0 "v9_regcmp_op"
1673 [(match_operand:DI 1 "register_operand" "r")
1676 (label_ref (match_operand 2 "" ""))))]
1680 return output_v9branch (operands[0], operands[2], 1, 2, 1,
1681 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1682 ! final_sequence, insn);
1684 [(set_attr "type" "branch")
1685 (set_attr "branch_type" "reg")])
1687 ;; Load program counter insns.
1689 (define_insn "get_pc"
1690 [(clobber (reg:SI 15))
1691 (set (match_operand 0 "register_operand" "=r")
1692 (unspec [(match_operand 1 "" "") (match_operand 2 "" "")] UNSPEC_GET_PC))]
1693 "flag_pic && REGNO (operands[0]) == 23"
1694 "sethi\\t%%hi(%a1-4), %0\\n\\tcall\\t%a2\\n\\tadd\\t%0, %%lo(%a1+4), %0"
1695 [(set_attr "type" "multi")
1696 (set_attr "length" "3")])
1699 ;; Move instructions
1701 (define_expand "movqi"
1702 [(set (match_operand:QI 0 "general_operand" "")
1703 (match_operand:QI 1 "general_operand" ""))]
1707 /* Working with CONST_INTs is easier, so convert
1708 a double if needed. */
1709 if (GET_CODE (operands[1]) == CONST_DOUBLE)
1711 operands[1] = GEN_INT (trunc_int_for_mode
1712 (CONST_DOUBLE_LOW (operands[1]), QImode));
1715 /* Handle sets of MEM first. */
1716 if (GET_CODE (operands[0]) == MEM)
1718 if (reg_or_0_operand (operands[1], QImode))
1721 if (! reload_in_progress)
1723 operands[0] = validize_mem (operands[0]);
1724 operands[1] = force_reg (QImode, operands[1]);
1728 /* Fixup PIC cases. */
1731 if (CONSTANT_P (operands[1])
1732 && pic_address_needs_scratch (operands[1]))
1733 operands[1] = legitimize_pic_address (operands[1], QImode, 0);
1735 if (symbolic_operand (operands[1], QImode))
1737 operands[1] = legitimize_pic_address (operands[1],
1739 (reload_in_progress ?
1746 /* All QI constants require only one insn, so proceed. */
1752 (define_insn "*movqi_insn"
1753 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m")
1754 (match_operand:QI 1 "input_operand" "rI,m,rJ"))]
1755 "(register_operand (operands[0], QImode)
1756 || reg_or_0_operand (operands[1], QImode))"
1761 [(set_attr "type" "*,load,store")
1762 (set_attr "us3load_type" "*,3cycle,*")])
1764 (define_expand "movhi"
1765 [(set (match_operand:HI 0 "general_operand" "")
1766 (match_operand:HI 1 "general_operand" ""))]
1770 /* Working with CONST_INTs is easier, so convert
1771 a double if needed. */
1772 if (GET_CODE (operands[1]) == CONST_DOUBLE)
1773 operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
1775 /* Handle sets of MEM first. */
1776 if (GET_CODE (operands[0]) == MEM)
1778 if (reg_or_0_operand (operands[1], HImode))
1781 if (! reload_in_progress)
1783 operands[0] = validize_mem (operands[0]);
1784 operands[1] = force_reg (HImode, operands[1]);
1788 /* Fixup PIC cases. */
1791 if (CONSTANT_P (operands[1])
1792 && pic_address_needs_scratch (operands[1]))
1793 operands[1] = legitimize_pic_address (operands[1], HImode, 0);
1795 if (symbolic_operand (operands[1], HImode))
1797 operands[1] = legitimize_pic_address (operands[1],
1799 (reload_in_progress ?
1806 /* This makes sure we will not get rematched due to splittage. */
1807 if (! CONSTANT_P (operands[1]) || input_operand (operands[1], HImode))
1809 else if (CONSTANT_P (operands[1])
1810 && GET_CODE (operands[1]) != HIGH
1811 && GET_CODE (operands[1]) != LO_SUM)
1813 sparc_emit_set_const32 (operands[0], operands[1]);
1820 (define_insn "*movhi_const64_special"
1821 [(set (match_operand:HI 0 "register_operand" "=r")
1822 (match_operand:HI 1 "const64_high_operand" ""))]
1824 "sethi\\t%%hi(%a1), %0")
1826 (define_insn "*movhi_insn"
1827 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1828 (match_operand:HI 1 "input_operand" "rI,K,m,rJ"))]
1829 "(register_operand (operands[0], HImode)
1830 || reg_or_0_operand (operands[1], HImode))"
1833 sethi\\t%%hi(%a1), %0
1836 [(set_attr "type" "*,*,load,store")
1837 (set_attr "us3load_type" "*,*,3cycle,*")])
1839 ;; We always work with constants here.
1840 (define_insn "*movhi_lo_sum"
1841 [(set (match_operand:HI 0 "register_operand" "=r")
1842 (ior:HI (match_operand:HI 1 "arith_operand" "%r")
1843 (match_operand:HI 2 "arith_operand" "I")))]
1847 (define_expand "movsi"
1848 [(set (match_operand:SI 0 "general_operand" "")
1849 (match_operand:SI 1 "general_operand" ""))]
1853 /* Working with CONST_INTs is easier, so convert
1854 a double if needed. */
1855 if (GET_CODE (operands[1]) == CONST_DOUBLE)
1856 operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
1858 /* Handle sets of MEM first. */
1859 if (GET_CODE (operands[0]) == MEM)
1861 if (reg_or_0_operand (operands[1], SImode))
1864 if (! reload_in_progress)
1866 operands[0] = validize_mem (operands[0]);
1867 operands[1] = force_reg (SImode, operands[1]);
1871 /* Fixup PIC cases. */
1874 if (CONSTANT_P (operands[1])
1875 && pic_address_needs_scratch (operands[1]))
1876 operands[1] = legitimize_pic_address (operands[1], SImode, 0);
1878 if (GET_CODE (operands[1]) == LABEL_REF)
1881 emit_insn (gen_movsi_pic_label_ref (operands[0], operands[1]));
1885 if (symbolic_operand (operands[1], SImode))
1887 operands[1] = legitimize_pic_address (operands[1],
1889 (reload_in_progress ?
1896 /* If we are trying to toss an integer constant into the
1897 FPU registers, force it into memory. */
1898 if (GET_CODE (operands[0]) == REG
1899 && REGNO (operands[0]) >= SPARC_FIRST_FP_REG
1900 && REGNO (operands[0]) <= SPARC_LAST_V9_FP_REG
1901 && CONSTANT_P (operands[1]))
1902 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
1905 /* This makes sure we will not get rematched due to splittage. */
1906 if (! CONSTANT_P (operands[1]) || input_operand (operands[1], SImode))
1908 else if (CONSTANT_P (operands[1])
1909 && GET_CODE (operands[1]) != HIGH
1910 && GET_CODE (operands[1]) != LO_SUM)
1912 sparc_emit_set_const32 (operands[0], operands[1]);
1919 ;; This is needed to show CSE exactly which bits are set
1920 ;; in a 64-bit register by sethi instructions.
1921 (define_insn "*movsi_const64_special"
1922 [(set (match_operand:SI 0 "register_operand" "=r")
1923 (match_operand:SI 1 "const64_high_operand" ""))]
1925 "sethi\\t%%hi(%a1), %0")
1927 (define_insn "*movsi_insn"
1928 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,f,r,r,r,f,m,m,d")
1929 (match_operand:SI 1 "input_operand" "rI,!f,K,J,m,!m,rJ,!f,J"))]
1930 "(register_operand (operands[0], SImode)
1931 || reg_or_0_operand (operands[1], SImode))"
1935 sethi\\t%%hi(%a1), %0
1942 [(set_attr "type" "*,fpmove,*,*,load,fpload,store,fpstore,fpmove")])
1944 (define_insn "*movsi_lo_sum"
1945 [(set (match_operand:SI 0 "register_operand" "=r")
1946 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1947 (match_operand:SI 2 "immediate_operand" "in")))]
1949 "or\\t%1, %%lo(%a2), %0")
1951 (define_insn "*movsi_high"
1952 [(set (match_operand:SI 0 "register_operand" "=r")
1953 (high:SI (match_operand:SI 1 "immediate_operand" "in")))]
1955 "sethi\\t%%hi(%a1), %0")
1957 ;; The next two patterns must wrap the SYMBOL_REF in an UNSPEC
1958 ;; so that CSE won't optimize the address computation away.
1959 (define_insn "movsi_lo_sum_pic"
1960 [(set (match_operand:SI 0 "register_operand" "=r")
1961 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1962 (unspec:SI [(match_operand:SI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
1964 "or\\t%1, %%lo(%a2), %0")
1966 (define_insn "movsi_high_pic"
1967 [(set (match_operand:SI 0 "register_operand" "=r")
1968 (high:SI (unspec:SI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
1969 "flag_pic && check_pic (1)"
1970 "sethi\\t%%hi(%a1), %0")
1972 (define_expand "movsi_pic_label_ref"
1973 [(set (match_dup 3) (high:SI
1974 (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
1975 (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1976 (set (match_dup 4) (lo_sum:SI (match_dup 3)
1977 (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1978 (set (match_operand:SI 0 "register_operand" "=r")
1979 (minus:SI (match_dup 5) (match_dup 4)))]
1983 current_function_uses_pic_offset_table = 1;
1984 operands[2] = gen_rtx_SYMBOL_REF (Pmode, \"_GLOBAL_OFFSET_TABLE_\");
1987 operands[3] = operands[0];
1988 operands[4] = operands[0];
1992 operands[3] = gen_reg_rtx (SImode);
1993 operands[4] = gen_reg_rtx (SImode);
1995 operands[5] = pic_offset_table_rtx;
1998 (define_insn "*movsi_high_pic_label_ref"
1999 [(set (match_operand:SI 0 "register_operand" "=r")
2001 (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
2002 (match_operand:SI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
2004 "sethi\\t%%hi(%a2-(%a1-.)), %0")
2006 (define_insn "*movsi_lo_sum_pic_label_ref"
2007 [(set (match_operand:SI 0 "register_operand" "=r")
2008 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
2009 (unspec:SI [(match_operand:SI 2 "label_ref_operand" "")
2010 (match_operand:SI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
2012 "or\\t%1, %%lo(%a3-(%a2-.)), %0")
2014 (define_expand "movdi"
2015 [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand" "")
2016 (match_operand:DI 1 "general_operand" ""))]
2020 /* Where possible, convert CONST_DOUBLE into a CONST_INT. */
2021 if (GET_CODE (operands[1]) == CONST_DOUBLE
2022 #if HOST_BITS_PER_WIDE_INT == 32
2023 && ((CONST_DOUBLE_HIGH (operands[1]) == 0
2024 && (CONST_DOUBLE_LOW (operands[1]) & 0x80000000) == 0)
2025 || (CONST_DOUBLE_HIGH (operands[1]) == (HOST_WIDE_INT) 0xffffffff
2026 && (CONST_DOUBLE_LOW (operands[1]) & 0x80000000) != 0))
2029 operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
2031 /* Handle MEM cases first. */
2032 if (GET_CODE (operands[0]) == MEM)
2034 /* If it's a REG, we can always do it.
2035 The const zero case is more complex, on v9
2036 we can always perform it. */
2037 if (register_operand (operands[1], DImode)
2039 && (operands[1] == const0_rtx)))
2042 if (! reload_in_progress)
2044 operands[0] = validize_mem (operands[0]);
2045 operands[1] = force_reg (DImode, operands[1]);
2051 if (CONSTANT_P (operands[1])
2052 && pic_address_needs_scratch (operands[1]))
2053 operands[1] = legitimize_pic_address (operands[1], DImode, 0);
2055 if (GET_CODE (operands[1]) == LABEL_REF)
2057 if (! TARGET_ARCH64)
2059 emit_insn (gen_movdi_pic_label_ref (operands[0], operands[1]));
2063 if (symbolic_operand (operands[1], DImode))
2065 operands[1] = legitimize_pic_address (operands[1],
2067 (reload_in_progress ?
2074 /* If we are trying to toss an integer constant into the
2075 FPU registers, force it into memory. */
2076 if (GET_CODE (operands[0]) == REG
2077 && REGNO (operands[0]) >= SPARC_FIRST_FP_REG
2078 && REGNO (operands[0]) <= SPARC_LAST_V9_FP_REG
2079 && CONSTANT_P (operands[1]))
2080 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
2083 /* This makes sure we will not get rematched due to splittage. */
2084 if (! CONSTANT_P (operands[1]) || input_operand (operands[1], DImode))
2086 else if (TARGET_ARCH64
2087 && CONSTANT_P (operands[1])
2088 && GET_CODE (operands[1]) != HIGH
2089 && GET_CODE (operands[1]) != LO_SUM)
2091 sparc_emit_set_const64 (operands[0], operands[1]);
2099 ;; Be careful, fmovd does not exist when !arch64.
2100 ;; We match MEM moves directly when we have correct even
2101 ;; numbered registers, but fall into splits otherwise.
2102 ;; The constraint ordering here is really important to
2103 ;; avoid insane problems in reload, especially for patterns
2106 ;; (set (mem:DI (plus:SI (reg:SI 30 %fp)
2107 ;; (const_int -5016)))
2111 (define_insn "*movdi_insn_sp32_v9"
2112 [(set (match_operand:DI 0 "nonimmediate_operand"
2113 "=T,o,T,U,o,r,r,r,?T,?f,?f,?o,?f")
2114 (match_operand:DI 1 "input_operand"
2115 " J,J,U,T,r,o,i,r, f, T, o, f, f"))]
2116 "! TARGET_ARCH64 && TARGET_V9
2117 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2132 [(set_attr "type" "store,store,store,load,*,*,*,*,fpstore,fpload,*,*,*")
2133 (set_attr "length" "*,2,*,*,2,2,2,2,*,*,2,2,2")])
2135 (define_insn "*movdi_insn_sp32"
2136 [(set (match_operand:DI 0 "nonimmediate_operand"
2137 "=o,T,U,o,r,r,r,?T,?f,?f,?o,?f")
2138 (match_operand:DI 1 "input_operand"
2139 " J,U,T,r,o,i,r, f, T, o, f, f"))]
2141 && (register_operand (operands[0], DImode)
2142 || register_operand (operands[1], DImode))"
2156 [(set_attr "type" "store,store,load,*,*,*,*,fpstore,fpload,*,*,*")
2157 (set_attr "length" "2,*,*,2,2,2,2,*,*,2,2,2")])
2159 ;; The following are generated by sparc_emit_set_const64
2160 (define_insn "*movdi_sp64_dbl"
2161 [(set (match_operand:DI 0 "register_operand" "=r")
2162 (match_operand:DI 1 "const64_operand" ""))]
2164 && HOST_BITS_PER_WIDE_INT != 64)"
2167 ;; This is needed to show CSE exactly which bits are set
2168 ;; in a 64-bit register by sethi instructions.
2169 (define_insn "*movdi_const64_special"
2170 [(set (match_operand:DI 0 "register_operand" "=r")
2171 (match_operand:DI 1 "const64_high_operand" ""))]
2173 "sethi\\t%%hi(%a1), %0")
2175 (define_insn "*movdi_insn_sp64_novis"
2176 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,m,?e,?e,?W")
2177 (match_operand:DI 1 "input_operand" "rI,N,J,m,rJ,e,W,e"))]
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
2190 [(set_attr "type" "*,*,*,load,store,fpmove,fpload,fpstore")
2191 (set_attr "fptype" "*,*,*,*,*,double,*,*")])
2193 (define_insn "*movdi_insn_sp64_vis"
2194 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,m,?e,?e,?W,b")
2195 (match_operand:DI 1 "input_operand" "rI,N,J,m,rJ,e,W,e,J"))]
2196 "TARGET_ARCH64 && TARGET_VIS &&
2197 (register_operand (operands[0], DImode)
2198 || reg_or_0_operand (operands[1], DImode))"
2201 sethi\\t%%hi(%a1), %0
2209 [(set_attr "type" "*,*,*,load,store,fpmove,fpload,fpstore,fpmove")
2210 (set_attr "fptype" "*,*,*,*,*,double,*,*,double")])
2212 (define_expand "movdi_pic_label_ref"
2213 [(set (match_dup 3) (high:DI
2214 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
2215 (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
2216 (set (match_dup 4) (lo_sum:DI (match_dup 3)
2217 (unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
2218 (set (match_operand:DI 0 "register_operand" "=r")
2219 (minus:DI (match_dup 5) (match_dup 4)))]
2220 "TARGET_ARCH64 && flag_pic"
2223 current_function_uses_pic_offset_table = 1;
2224 operands[2] = gen_rtx_SYMBOL_REF (Pmode, \"_GLOBAL_OFFSET_TABLE_\");
2227 operands[3] = operands[0];
2228 operands[4] = operands[0];
2232 operands[3] = gen_reg_rtx (DImode);
2233 operands[4] = gen_reg_rtx (DImode);
2235 operands[5] = pic_offset_table_rtx;
2238 (define_insn "*movdi_high_pic_label_ref"
2239 [(set (match_operand:DI 0 "register_operand" "=r")
2241 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
2242 (match_operand:DI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
2243 "TARGET_ARCH64 && flag_pic"
2244 "sethi\\t%%hi(%a2-(%a1-.)), %0")
2246 (define_insn "*movdi_lo_sum_pic_label_ref"
2247 [(set (match_operand:DI 0 "register_operand" "=r")
2248 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2249 (unspec:DI [(match_operand:DI 2 "label_ref_operand" "")
2250 (match_operand:DI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
2251 "TARGET_ARCH64 && flag_pic"
2252 "or\\t%1, %%lo(%a3-(%a2-.)), %0")
2254 ;; Sparc-v9 code model support insns. See sparc_emit_set_symbolic_const64
2255 ;; in sparc.c to see what is going on here... PIC stuff comes first.
2257 (define_insn "movdi_lo_sum_pic"
2258 [(set (match_operand:DI 0 "register_operand" "=r")
2259 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2260 (unspec:DI [(match_operand:DI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
2261 "TARGET_ARCH64 && flag_pic"
2262 "or\\t%1, %%lo(%a2), %0")
2264 (define_insn "movdi_high_pic"
2265 [(set (match_operand:DI 0 "register_operand" "=r")
2266 (high:DI (unspec:DI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
2267 "TARGET_ARCH64 && flag_pic && check_pic (1)"
2268 "sethi\\t%%hi(%a1), %0")
2270 (define_insn "*sethi_di_medlow_embmedany_pic"
2271 [(set (match_operand:DI 0 "register_operand" "=r")
2272 (high:DI (match_operand:DI 1 "sp64_medium_pic_operand" "")))]
2273 "(TARGET_CM_MEDLOW || TARGET_CM_EMBMEDANY) && check_pic (1)"
2274 "sethi\\t%%hi(%a1), %0")
2276 (define_insn "*sethi_di_medlow"
2277 [(set (match_operand:DI 0 "register_operand" "=r")
2278 (high:DI (match_operand:DI 1 "symbolic_operand" "")))]
2279 "TARGET_CM_MEDLOW && check_pic (1)"
2280 "sethi\\t%%hi(%a1), %0")
2282 (define_insn "*losum_di_medlow"
2283 [(set (match_operand:DI 0 "register_operand" "=r")
2284 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2285 (match_operand:DI 2 "symbolic_operand" "")))]
2287 "or\\t%1, %%lo(%a2), %0")
2289 (define_insn "seth44"
2290 [(set (match_operand:DI 0 "register_operand" "=r")
2291 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETH44)))]
2293 "sethi\\t%%h44(%a1), %0")
2295 (define_insn "setm44"
2296 [(set (match_operand:DI 0 "register_operand" "=r")
2297 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2298 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_SETM44)))]
2300 "or\\t%1, %%m44(%a2), %0")
2302 (define_insn "setl44"
2303 [(set (match_operand:DI 0 "register_operand" "=r")
2304 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2305 (match_operand:DI 2 "symbolic_operand" "")))]
2307 "or\\t%1, %%l44(%a2), %0")
2309 (define_insn "sethh"
2310 [(set (match_operand:DI 0 "register_operand" "=r")
2311 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETHH)))]
2313 "sethi\\t%%hh(%a1), %0")
2315 (define_insn "setlm"
2316 [(set (match_operand:DI 0 "register_operand" "=r")
2317 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETLM)))]
2319 "sethi\\t%%lm(%a1), %0")
2321 (define_insn "sethm"
2322 [(set (match_operand:DI 0 "register_operand" "=r")
2323 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2324 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_EMB_SETHM)))]
2326 "or\\t%1, %%hm(%a2), %0")
2328 (define_insn "setlo"
2329 [(set (match_operand:DI 0 "register_operand" "=r")
2330 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2331 (match_operand:DI 2 "symbolic_operand" "")))]
2333 "or\\t%1, %%lo(%a2), %0")
2335 (define_insn "embmedany_sethi"
2336 [(set (match_operand:DI 0 "register_operand" "=r")
2337 (high:DI (unspec:DI [(match_operand:DI 1 "data_segment_operand" "")] UNSPEC_EMB_HISUM)))]
2338 "TARGET_CM_EMBMEDANY && check_pic (1)"
2339 "sethi\\t%%hi(%a1), %0")
2341 (define_insn "embmedany_losum"
2342 [(set (match_operand:DI 0 "register_operand" "=r")
2343 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2344 (match_operand:DI 2 "data_segment_operand" "")))]
2345 "TARGET_CM_EMBMEDANY"
2346 "add\\t%1, %%lo(%a2), %0")
2348 (define_insn "embmedany_brsum"
2349 [(set (match_operand:DI 0 "register_operand" "=r")
2350 (unspec:DI [(match_operand:DI 1 "register_operand" "r")] UNSPEC_EMB_HISUM))]
2351 "TARGET_CM_EMBMEDANY"
2354 (define_insn "embmedany_textuhi"
2355 [(set (match_operand:DI 0 "register_operand" "=r")
2356 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTUHI)))]
2357 "TARGET_CM_EMBMEDANY && check_pic (1)"
2358 "sethi\\t%%uhi(%a1), %0")
2360 (define_insn "embmedany_texthi"
2361 [(set (match_operand:DI 0 "register_operand" "=r")
2362 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTHI)))]
2363 "TARGET_CM_EMBMEDANY && check_pic (1)"
2364 "sethi\\t%%hi(%a1), %0")
2366 (define_insn "embmedany_textulo"
2367 [(set (match_operand:DI 0 "register_operand" "=r")
2368 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2369 (unspec:DI [(match_operand:DI 2 "text_segment_operand" "")] UNSPEC_EMB_TEXTULO)))]
2370 "TARGET_CM_EMBMEDANY"
2371 "or\\t%1, %%ulo(%a2), %0")
2373 (define_insn "embmedany_textlo"
2374 [(set (match_operand:DI 0 "register_operand" "=r")
2375 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2376 (match_operand:DI 2 "text_segment_operand" "")))]
2377 "TARGET_CM_EMBMEDANY"
2378 "or\\t%1, %%lo(%a2), %0")
2380 ;; Now some patterns to help reload out a bit.
2381 (define_expand "reload_indi"
2382 [(parallel [(match_operand:DI 0 "register_operand" "=r")
2383 (match_operand:DI 1 "immediate_operand" "")
2384 (match_operand:TI 2 "register_operand" "=&r")])]
2386 || TARGET_CM_EMBMEDANY)
2390 sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
2394 (define_expand "reload_outdi"
2395 [(parallel [(match_operand:DI 0 "register_operand" "=r")
2396 (match_operand:DI 1 "immediate_operand" "")
2397 (match_operand:TI 2 "register_operand" "=&r")])]
2399 || TARGET_CM_EMBMEDANY)
2403 sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
2407 ;; Split up putting CONSTs and REGs into DI regs when !arch64
2409 [(set (match_operand:DI 0 "register_operand" "")
2410 (match_operand:DI 1 "const_int_operand" ""))]
2411 "! TARGET_ARCH64 && reload_completed"
2412 [(clobber (const_int 0))]
2415 #if HOST_BITS_PER_WIDE_INT == 32
2416 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
2417 (INTVAL (operands[1]) < 0) ?
2420 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2423 unsigned int low, high;
2425 low = trunc_int_for_mode (INTVAL (operands[1]), SImode);
2426 high = trunc_int_for_mode (INTVAL (operands[1]) >> 32, SImode);
2427 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), GEN_INT (high)));
2429 /* Slick... but this trick loses if this subreg constant part
2430 can be done in one insn. */
2431 if (low == high && (low & 0x3ff) != 0 && low + 0x1000 >= 0x2000)
2432 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2433 gen_highpart (SImode, operands[0])));
2435 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), GEN_INT (low)));
2441 [(set (match_operand:DI 0 "register_operand" "")
2442 (match_operand:DI 1 "const_double_operand" ""))]
2443 "! TARGET_ARCH64 && reload_completed"
2444 [(clobber (const_int 0))]
2447 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
2448 GEN_INT (CONST_DOUBLE_HIGH (operands[1]))));
2450 /* Slick... but this trick loses if this subreg constant part
2451 can be done in one insn. */
2452 if (CONST_DOUBLE_LOW (operands[1]) == CONST_DOUBLE_HIGH (operands[1])
2453 && !(SPARC_SETHI32_P (CONST_DOUBLE_HIGH (operands[1]))
2454 || SPARC_SIMM13_P (CONST_DOUBLE_HIGH (operands[1]))))
2456 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2457 gen_highpart (SImode, operands[0])));
2461 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2462 GEN_INT (CONST_DOUBLE_LOW (operands[1]))));
2468 [(set (match_operand:DI 0 "register_operand" "")
2469 (match_operand:DI 1 "register_operand" ""))]
2470 "! TARGET_ARCH64 && reload_completed"
2471 [(clobber (const_int 0))]
2474 rtx set_dest = operands[0];
2475 rtx set_src = operands[1];
2479 dest1 = gen_highpart (SImode, set_dest);
2480 dest2 = gen_lowpart (SImode, set_dest);
2481 src1 = gen_highpart (SImode, set_src);
2482 src2 = gen_lowpart (SImode, set_src);
2484 /* Now emit using the real source and destination we found, swapping
2485 the order if we detect overlap. */
2486 if (reg_overlap_mentioned_p (dest1, src2))
2488 emit_insn (gen_movsi (dest2, src2));
2489 emit_insn (gen_movsi (dest1, src1));
2493 emit_insn (gen_movsi (dest1, src1));
2494 emit_insn (gen_movsi (dest2, src2));
2499 ;; Now handle the cases of memory moves from/to non-even
2500 ;; DI mode register pairs.
2502 [(set (match_operand:DI 0 "register_operand" "")
2503 (match_operand:DI 1 "memory_operand" ""))]
2506 && sparc_splitdi_legitimate (operands[0], operands[1]))"
2507 [(clobber (const_int 0))]
2510 rtx word0 = adjust_address (operands[1], SImode, 0);
2511 rtx word1 = adjust_address (operands[1], SImode, 4);
2512 rtx high_part = gen_highpart (SImode, operands[0]);
2513 rtx low_part = gen_lowpart (SImode, operands[0]);
2515 if (reg_overlap_mentioned_p (high_part, word1))
2517 emit_insn (gen_movsi (low_part, word1));
2518 emit_insn (gen_movsi (high_part, word0));
2522 emit_insn (gen_movsi (high_part, word0));
2523 emit_insn (gen_movsi (low_part, word1));
2529 [(set (match_operand:DI 0 "memory_operand" "")
2530 (match_operand:DI 1 "register_operand" ""))]
2533 && sparc_splitdi_legitimate (operands[1], operands[0]))"
2534 [(clobber (const_int 0))]
2537 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0),
2538 gen_highpart (SImode, operands[1])));
2539 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4),
2540 gen_lowpart (SImode, operands[1])));
2545 [(set (match_operand:DI 0 "memory_operand" "")
2550 && ! mem_min_alignment (operands[0], 8)))
2551 && offsettable_memref_p (operands[0])"
2552 [(clobber (const_int 0))]
2555 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0), const0_rtx));
2556 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4), const0_rtx));
2560 ;; Floating point move insns
2562 (define_insn "*movsf_insn_novis"
2563 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,*r,*r,*r,*r,*r,f,m,m")
2564 (match_operand:SF 1 "input_operand" "f,G,Q,*rR,S,m,m,f,*rG"))]
2565 "(TARGET_FPU && ! TARGET_VIS)
2566 && (register_operand (operands[0], SFmode)
2567 || register_operand (operands[1], SFmode)
2568 || fp_zero_operand (operands[1], SFmode))"
2571 if (GET_CODE (operands[1]) == CONST_DOUBLE
2572 && (which_alternative == 2
2573 || which_alternative == 3
2574 || which_alternative == 4))
2579 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2580 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2581 operands[1] = GEN_INT (i);
2584 switch (which_alternative)
2587 return \"fmovs\\t%1, %0\";
2589 return \"clr\\t%0\";
2591 return \"sethi\\t%%hi(%a1), %0\";
2593 return \"mov\\t%1, %0\";
2598 return \"ld\\t%1, %0\";
2601 return \"st\\t%r1, %0\";
2606 [(set_attr "type" "fpmove,*,*,*,*,load,fpload,fpstore,store")])
2608 (define_insn "*movsf_insn_vis"
2609 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,*r,*r,*r,*r,*r,f,m,m")
2610 (match_operand:SF 1 "input_operand" "f,G,G,Q,*rR,S,m,m,f,*rG"))]
2611 "(TARGET_FPU && TARGET_VIS)
2612 && (register_operand (operands[0], SFmode)
2613 || register_operand (operands[1], SFmode)
2614 || fp_zero_operand (operands[1], SFmode))"
2617 if (GET_CODE (operands[1]) == CONST_DOUBLE
2618 && (which_alternative == 3
2619 || which_alternative == 4
2620 || which_alternative == 5))
2625 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2626 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2627 operands[1] = GEN_INT (i);
2630 switch (which_alternative)
2633 return \"fmovs\\t%1, %0\";
2635 return \"fzeros\\t%0\";
2637 return \"clr\\t%0\";
2639 return \"sethi\\t%%hi(%a1), %0\";
2641 return \"mov\\t%1, %0\";
2646 return \"ld\\t%1, %0\";
2649 return \"st\\t%r1, %0\";
2654 [(set_attr "type" "fpmove,fpmove,*,*,*,*,load,fpload,fpstore,store")])
2656 ;; Exactly the same as above, except that all `f' cases are deleted.
2657 ;; This is necessary to prevent reload from ever trying to use a `f' reg
2660 (define_insn "*movsf_no_f_insn"
2661 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r,r,r,m")
2662 (match_operand:SF 1 "input_operand" "G,Q,rR,S,m,rG"))]
2664 && (register_operand (operands[0], SFmode)
2665 || register_operand (operands[1], SFmode)
2666 || fp_zero_operand (operands[1], SFmode))"
2669 if (GET_CODE (operands[1]) == CONST_DOUBLE
2670 && (which_alternative == 1
2671 || which_alternative == 2
2672 || which_alternative == 3))
2677 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2678 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2679 operands[1] = GEN_INT (i);
2682 switch (which_alternative)
2685 return \"clr\\t%0\";
2687 return \"sethi\\t%%hi(%a1), %0\";
2689 return \"mov\\t%1, %0\";
2693 return \"ld\\t%1, %0\";
2695 return \"st\\t%r1, %0\";
2700 [(set_attr "type" "*,*,*,*,load,store")])
2702 (define_insn "*movsf_lo_sum"
2703 [(set (match_operand:SF 0 "register_operand" "=r")
2704 (lo_sum:SF (match_operand:SF 1 "register_operand" "r")
2705 (match_operand:SF 2 "const_double_operand" "S")))]
2706 "fp_high_losum_p (operands[2])"
2712 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[2]);
2713 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2714 operands[2] = GEN_INT (i);
2715 return \"or\\t%1, %%lo(%a2), %0\";
2718 (define_insn "*movsf_high"
2719 [(set (match_operand:SF 0 "register_operand" "=r")
2720 (high:SF (match_operand:SF 1 "const_double_operand" "S")))]
2721 "fp_high_losum_p (operands[1])"
2727 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2728 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2729 operands[1] = GEN_INT (i);
2730 return \"sethi\\t%%hi(%1), %0\";
2734 [(set (match_operand:SF 0 "register_operand" "")
2735 (match_operand:SF 1 "const_double_operand" ""))]
2736 "fp_high_losum_p (operands[1])
2737 && (GET_CODE (operands[0]) == REG
2738 && REGNO (operands[0]) < 32)"
2739 [(set (match_dup 0) (high:SF (match_dup 1)))
2740 (set (match_dup 0) (lo_sum:SF (match_dup 0) (match_dup 1)))])
2742 (define_expand "movsf"
2743 [(set (match_operand:SF 0 "general_operand" "")
2744 (match_operand:SF 1 "general_operand" ""))]
2748 /* Force SFmode constants into memory. */
2749 if (GET_CODE (operands[0]) == REG
2750 && CONSTANT_P (operands[1]))
2752 /* emit_group_store will send such bogosity to us when it is
2753 not storing directly into memory. So fix this up to avoid
2754 crashes in output_constant_pool. */
2755 if (operands [1] == const0_rtx)
2756 operands[1] = CONST0_RTX (SFmode);
2758 if (TARGET_VIS && fp_zero_operand (operands[1], SFmode))
2761 /* We are able to build any SF constant in integer registers
2762 with at most 2 instructions. */
2763 if (REGNO (operands[0]) < 32)
2766 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
2770 /* Handle sets of MEM first. */
2771 if (GET_CODE (operands[0]) == MEM)
2773 if (register_operand (operands[1], SFmode)
2774 || fp_zero_operand (operands[1], SFmode))
2777 if (! reload_in_progress)
2779 operands[0] = validize_mem (operands[0]);
2780 operands[1] = force_reg (SFmode, operands[1]);
2784 /* Fixup PIC cases. */
2787 if (CONSTANT_P (operands[1])
2788 && pic_address_needs_scratch (operands[1]))
2789 operands[1] = legitimize_pic_address (operands[1], SFmode, 0);
2791 if (symbolic_operand (operands[1], SFmode))
2793 operands[1] = legitimize_pic_address (operands[1],
2795 (reload_in_progress ?
2805 (define_expand "movdf"
2806 [(set (match_operand:DF 0 "general_operand" "")
2807 (match_operand:DF 1 "general_operand" ""))]
2811 /* Force DFmode constants into memory. */
2812 if (GET_CODE (operands[0]) == REG
2813 && CONSTANT_P (operands[1]))
2815 /* emit_group_store will send such bogosity to us when it is
2816 not storing directly into memory. So fix this up to avoid
2817 crashes in output_constant_pool. */
2818 if (operands [1] == const0_rtx)
2819 operands[1] = CONST0_RTX (DFmode);
2821 if ((TARGET_VIS || REGNO (operands[0]) < 32)
2822 && fp_zero_operand (operands[1], DFmode))
2825 /* We are able to build any DF constant in integer registers. */
2826 if (REGNO (operands[0]) < 32
2827 && (reload_completed || reload_in_progress))
2830 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
2834 /* Handle MEM cases first. */
2835 if (GET_CODE (operands[0]) == MEM)
2837 if (register_operand (operands[1], DFmode)
2838 || fp_zero_operand (operands[1], DFmode))
2841 if (! reload_in_progress)
2843 operands[0] = validize_mem (operands[0]);
2844 operands[1] = force_reg (DFmode, operands[1]);
2848 /* Fixup PIC cases. */
2851 if (CONSTANT_P (operands[1])
2852 && pic_address_needs_scratch (operands[1]))
2853 operands[1] = legitimize_pic_address (operands[1], DFmode, 0);
2855 if (symbolic_operand (operands[1], DFmode))
2857 operands[1] = legitimize_pic_address (operands[1],
2859 (reload_in_progress ?
2869 ;; Be careful, fmovd does not exist when !v9.
2870 (define_insn "*movdf_insn_sp32"
2871 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,W,U,T,o,e,*r,o,e,o")
2872 (match_operand:DF 1 "input_operand" "W#F,e,T,U,G,e,*rFo,*r,o#F,e"))]
2875 && (register_operand (operands[0], DFmode)
2876 || register_operand (operands[1], DFmode)
2877 || fp_zero_operand (operands[1], DFmode))"
2889 [(set_attr "type" "fpload,fpstore,load,store,*,*,*,*,*,*")
2890 (set_attr "length" "*,*,*,*,2,2,2,2,2,2")])
2892 (define_insn "*movdf_no_e_insn_sp32"
2893 [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,o,r,o")
2894 (match_operand:DF 1 "input_operand" "T,U,G,ro,r"))]
2898 && (register_operand (operands[0], DFmode)
2899 || register_operand (operands[1], DFmode)
2900 || fp_zero_operand (operands[1], DFmode))"
2907 [(set_attr "type" "load,store,*,*,*")
2908 (set_attr "length" "*,*,2,2,2")])
2910 (define_insn "*movdf_no_e_insn_v9_sp32"
2911 [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,T,r,o")
2912 (match_operand:DF 1 "input_operand" "T,U,G,ro,rG"))]
2916 && (register_operand (operands[0], DFmode)
2917 || register_operand (operands[1], DFmode)
2918 || fp_zero_operand (operands[1], DFmode))"
2925 [(set_attr "type" "load,store,store,*,*")
2926 (set_attr "length" "*,*,*,2,2")])
2928 ;; We have available v9 double floats but not 64-bit
2929 ;; integer registers and no VIS.
2930 (define_insn "*movdf_insn_v9only_novis"
2931 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,T,W,U,T,f,*r,o")
2932 (match_operand:DF 1 "input_operand" "e,W#F,G,e,T,U,o#F,*roF,*rGf"))]
2937 && (register_operand (operands[0], DFmode)
2938 || register_operand (operands[1], DFmode)
2939 || fp_zero_operand (operands[1], DFmode))"
2950 [(set_attr "type" "fpmove,load,store,store,load,store,*,*,*")
2951 (set_attr "length" "*,*,*,*,*,*,2,2,2")
2952 (set_attr "fptype" "double,*,*,*,*,*,*,*,*")])
2954 ;; We have available v9 double floats but not 64-bit
2955 ;; integer registers but we have VIS.
2956 (define_insn "*movdf_insn_v9only_vis"
2957 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,e,T,W,U,T,f,*r,o")
2958 (match_operand:DF 1 "input_operand" "G,e,W#F,G,e,T,U,o#F,*roGF,*rGf"))]
2962 && (register_operand (operands[0], DFmode)
2963 || register_operand (operands[1], DFmode)
2964 || fp_zero_operand (operands[1], DFmode))"
2976 [(set_attr "type" "fpmove,fpmove,load,store,store,load,store,*,*,*")
2977 (set_attr "length" "*,*,*,*,*,*,*,2,2,2")
2978 (set_attr "fptype" "double,double,*,*,*,*,*,*,*,*")])
2980 ;; We have available both v9 double floats and 64-bit
2981 ;; integer registers. No VIS though.
2982 (define_insn "*movdf_insn_sp64_novis"
2983 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,W,*r,*r,m,*r")
2984 (match_operand:DF 1 "input_operand" "e,W#F,e,*rG,m,*rG,F"))]
2988 && (register_operand (operands[0], DFmode)
2989 || register_operand (operands[1], DFmode)
2990 || fp_zero_operand (operands[1], DFmode))"
2999 [(set_attr "type" "fpmove,load,store,*,load,store,*")
3000 (set_attr "length" "*,*,*,*,*,*,2")
3001 (set_attr "fptype" "double,*,*,*,*,*,*")])
3003 ;; We have available both v9 double floats and 64-bit
3004 ;; integer registers. And we have VIS.
3005 (define_insn "*movdf_insn_sp64_vis"
3006 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,e,W,*r,*r,m,*r")
3007 (match_operand:DF 1 "input_operand" "G,e,W#F,e,*rG,m,*rG,F"))]
3011 && (register_operand (operands[0], DFmode)
3012 || register_operand (operands[1], DFmode)
3013 || fp_zero_operand (operands[1], DFmode))"
3023 [(set_attr "type" "fpmove,fpmove,load,store,*,load,store,*")
3024 (set_attr "length" "*,*,*,*,*,*,*,2")
3025 (set_attr "fptype" "double,double,*,*,*,*,*,*")])
3027 (define_insn "*movdf_no_e_insn_sp64"
3028 [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m")
3029 (match_operand:DF 1 "input_operand" "r,m,rG"))]
3032 && (register_operand (operands[0], DFmode)
3033 || register_operand (operands[1], DFmode)
3034 || fp_zero_operand (operands[1], DFmode))"
3039 [(set_attr "type" "*,load,store")])
3042 [(set (match_operand:DF 0 "register_operand" "")
3043 (match_operand:DF 1 "const_double_operand" ""))]
3045 && (GET_CODE (operands[0]) == REG
3046 && REGNO (operands[0]) < 32)
3047 && ! fp_zero_operand(operands[1], DFmode)
3048 && reload_completed"
3049 [(clobber (const_int 0))]
3055 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3056 REAL_VALUE_TO_TARGET_DOUBLE (r, l);
3057 operands[0] = gen_rtx_raw_REG (DImode, REGNO (operands[0]));
3061 #if HOST_BITS_PER_WIDE_INT == 64
3064 val = ((HOST_WIDE_INT)(unsigned long)l[1] |
3065 ((HOST_WIDE_INT)(unsigned long)l[0] << 32));
3066 emit_insn (gen_movdi (operands[0], GEN_INT (val)));
3068 emit_insn (gen_movdi (operands[0],
3069 immed_double_const (l[1], l[0], DImode)));
3074 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
3077 /* Slick... but this trick loses if this subreg constant part
3078 can be done in one insn. */
3080 && !(SPARC_SETHI32_P (l[0])
3081 || SPARC_SIMM13_P (l[0])))
3083 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
3084 gen_highpart (SImode, operands[0])));
3088 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
3095 ;; Ok, now the splits to handle all the multi insn and
3096 ;; mis-aligned memory address cases.
3097 ;; In these splits please take note that we must be
3098 ;; careful when V9 but not ARCH64 because the integer
3099 ;; register DFmode cases must be handled.
3101 [(set (match_operand:DF 0 "register_operand" "")
3102 (match_operand:DF 1 "register_operand" ""))]
3105 && ((GET_CODE (operands[0]) == REG
3106 && REGNO (operands[0]) < 32)
3107 || (GET_CODE (operands[0]) == SUBREG
3108 && GET_CODE (SUBREG_REG (operands[0])) == REG
3109 && REGNO (SUBREG_REG (operands[0])) < 32))))
3110 && reload_completed"
3111 [(clobber (const_int 0))]
3114 rtx set_dest = operands[0];
3115 rtx set_src = operands[1];
3119 dest1 = gen_highpart (SFmode, set_dest);
3120 dest2 = gen_lowpart (SFmode, set_dest);
3121 src1 = gen_highpart (SFmode, set_src);
3122 src2 = gen_lowpart (SFmode, set_src);
3124 /* Now emit using the real source and destination we found, swapping
3125 the order if we detect overlap. */
3126 if (reg_overlap_mentioned_p (dest1, src2))
3128 emit_insn (gen_movsf (dest2, src2));
3129 emit_insn (gen_movsf (dest1, src1));
3133 emit_insn (gen_movsf (dest1, src1));
3134 emit_insn (gen_movsf (dest2, src2));
3140 [(set (match_operand:DF 0 "register_operand" "")
3141 (match_operand:DF 1 "memory_operand" ""))]
3144 && (((REGNO (operands[0]) % 2) != 0)
3145 || ! mem_min_alignment (operands[1], 8))
3146 && offsettable_memref_p (operands[1])"
3147 [(clobber (const_int 0))]
3150 rtx word0 = adjust_address (operands[1], SFmode, 0);
3151 rtx word1 = adjust_address (operands[1], SFmode, 4);
3153 if (reg_overlap_mentioned_p (gen_highpart (SFmode, operands[0]), word1))
3155 emit_insn (gen_movsf (gen_lowpart (SFmode, operands[0]),
3157 emit_insn (gen_movsf (gen_highpart (SFmode, operands[0]),
3162 emit_insn (gen_movsf (gen_highpart (SFmode, operands[0]),
3164 emit_insn (gen_movsf (gen_lowpart (SFmode, operands[0]),
3171 [(set (match_operand:DF 0 "memory_operand" "")
3172 (match_operand:DF 1 "register_operand" ""))]
3175 && (((REGNO (operands[1]) % 2) != 0)
3176 || ! mem_min_alignment (operands[0], 8))
3177 && offsettable_memref_p (operands[0])"
3178 [(clobber (const_int 0))]
3181 rtx word0 = adjust_address (operands[0], SFmode, 0);
3182 rtx word1 = adjust_address (operands[0], SFmode, 4);
3184 emit_insn (gen_movsf (word0,
3185 gen_highpart (SFmode, operands[1])));
3186 emit_insn (gen_movsf (word1,
3187 gen_lowpart (SFmode, operands[1])));
3192 [(set (match_operand:DF 0 "memory_operand" "")
3193 (match_operand:DF 1 "fp_zero_operand" ""))]
3197 && ! mem_min_alignment (operands[0], 8)))
3198 && offsettable_memref_p (operands[0])"
3199 [(clobber (const_int 0))]
3204 dest1 = adjust_address (operands[0], SFmode, 0);
3205 dest2 = adjust_address (operands[0], SFmode, 4);
3207 emit_insn (gen_movsf (dest1, CONST0_RTX (SFmode)));
3208 emit_insn (gen_movsf (dest2, CONST0_RTX (SFmode)));
3213 [(set (match_operand:DF 0 "register_operand" "")
3214 (match_operand:DF 1 "fp_zero_operand" ""))]
3217 && ((GET_CODE (operands[0]) == REG
3218 && REGNO (operands[0]) < 32)
3219 || (GET_CODE (operands[0]) == SUBREG
3220 && GET_CODE (SUBREG_REG (operands[0])) == REG
3221 && REGNO (SUBREG_REG (operands[0])) < 32))"
3222 [(clobber (const_int 0))]
3225 rtx set_dest = operands[0];
3228 dest1 = gen_highpart (SFmode, set_dest);
3229 dest2 = gen_lowpart (SFmode, set_dest);
3230 emit_insn (gen_movsf (dest1, CONST0_RTX (SFmode)));
3231 emit_insn (gen_movsf (dest2, CONST0_RTX (SFmode)));
3235 (define_expand "movtf"
3236 [(set (match_operand:TF 0 "general_operand" "")
3237 (match_operand:TF 1 "general_operand" ""))]
3241 /* Force TFmode constants into memory. */
3242 if (GET_CODE (operands[0]) == REG
3243 && CONSTANT_P (operands[1]))
3245 /* emit_group_store will send such bogosity to us when it is
3246 not storing directly into memory. So fix this up to avoid
3247 crashes in output_constant_pool. */
3248 if (operands [1] == const0_rtx)
3249 operands[1] = CONST0_RTX (TFmode);
3251 if (TARGET_VIS && fp_zero_operand (operands[1], TFmode))
3254 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
3258 /* Handle MEM cases first, note that only v9 guarentees
3259 full 16-byte alignment for quads. */
3260 if (GET_CODE (operands[0]) == MEM)
3262 if (register_operand (operands[1], TFmode)
3263 || fp_zero_operand (operands[1], TFmode))
3266 if (! reload_in_progress)
3268 operands[0] = validize_mem (operands[0]);
3269 operands[1] = force_reg (TFmode, operands[1]);
3273 /* Fixup PIC cases. */
3276 if (CONSTANT_P (operands[1])
3277 && pic_address_needs_scratch (operands[1]))
3278 operands[1] = legitimize_pic_address (operands[1], TFmode, 0);
3280 if (symbolic_operand (operands[1], TFmode))
3282 operands[1] = legitimize_pic_address (operands[1],
3284 (reload_in_progress ?
3294 ;; Be careful, fmovq and {st,ld}{x,q} do not exist when !arch64 so
3295 ;; we must split them all. :-(
3296 (define_insn "*movtf_insn_sp32"
3297 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,U,r")
3298 (match_operand:TF 1 "input_operand" "oe,GeUr,o,roG"))]
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 (define_insn "*movtf_insn_vis_sp32"
3309 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,U,r")
3310 (match_operand:TF 1 "input_operand" "Goe,GeUr,o,roG"))]
3314 && (register_operand (operands[0], TFmode)
3315 || register_operand (operands[1], TFmode)
3316 || fp_zero_operand (operands[1], TFmode))"
3318 [(set_attr "length" "4")])
3320 ;; Exactly the same as above, except that all `e' cases are deleted.
3321 ;; This is necessary to prevent reload from ever trying to use a `e' reg
3324 (define_insn "*movtf_no_e_insn_sp32"
3325 [(set (match_operand:TF 0 "nonimmediate_operand" "=o,U,o,r,o")
3326 (match_operand:TF 1 "input_operand" "G,o,U,roG,r"))]
3329 && (register_operand (operands[0], TFmode)
3330 || register_operand (operands[1], TFmode)
3331 || fp_zero_operand (operands[1], TFmode))"
3333 [(set_attr "length" "4")])
3335 ;; Now handle the float reg cases directly when arch64,
3336 ;; hard_quad, and proper reg number alignment are all true.
3337 (define_insn "*movtf_insn_hq_sp64"
3338 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,e,m,o,r")
3339 (match_operand:TF 1 "input_operand" "e,m,e,Gr,roG"))]
3344 && (register_operand (operands[0], TFmode)
3345 || register_operand (operands[1], TFmode)
3346 || fp_zero_operand (operands[1], TFmode))"
3353 [(set_attr "type" "fpmove,fpload,fpstore,*,*")
3354 (set_attr "length" "*,*,*,2,2")])
3356 (define_insn "*movtf_insn_hq_vis_sp64"
3357 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,e,m,eo,r,o")
3358 (match_operand:TF 1 "input_operand" "e,m,e,G,roG,r"))]
3363 && (register_operand (operands[0], TFmode)
3364 || register_operand (operands[1], TFmode)
3365 || fp_zero_operand (operands[1], TFmode))"
3373 [(set_attr "type" "fpmove,fpload,fpstore,*,*,*")
3374 (set_attr "length" "*,*,*,2,2,2")])
3376 ;; Now we allow the integer register cases even when
3377 ;; only arch64 is true.
3378 (define_insn "*movtf_insn_sp64"
3379 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,r")
3380 (match_operand:TF 1 "input_operand" "oe,Ger,orG"))]
3384 && ! TARGET_HARD_QUAD
3385 && (register_operand (operands[0], TFmode)
3386 || register_operand (operands[1], TFmode)
3387 || fp_zero_operand (operands[1], TFmode))"
3389 [(set_attr "length" "2")])
3391 (define_insn "*movtf_insn_vis_sp64"
3392 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,r")
3393 (match_operand:TF 1 "input_operand" "Goe,Ger,orG"))]
3397 && ! TARGET_HARD_QUAD
3398 && (register_operand (operands[0], TFmode)
3399 || register_operand (operands[1], TFmode)
3400 || fp_zero_operand (operands[1], TFmode))"
3402 [(set_attr "length" "2")])
3404 (define_insn "*movtf_no_e_insn_sp64"
3405 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o")
3406 (match_operand:TF 1 "input_operand" "orG,rG"))]
3409 && (register_operand (operands[0], TFmode)
3410 || register_operand (operands[1], TFmode)
3411 || fp_zero_operand (operands[1], TFmode))"
3413 [(set_attr "length" "2")])
3415 ;; Now all the splits to handle multi-insn TF mode moves.
3417 [(set (match_operand:TF 0 "register_operand" "")
3418 (match_operand:TF 1 "register_operand" ""))]
3422 && ! TARGET_HARD_QUAD)
3423 || ! fp_register_operand (operands[0], TFmode))"
3424 [(clobber (const_int 0))]
3427 rtx set_dest = operands[0];
3428 rtx set_src = operands[1];
3432 dest1 = gen_df_reg (set_dest, 0);
3433 dest2 = gen_df_reg (set_dest, 1);
3434 src1 = gen_df_reg (set_src, 0);
3435 src2 = gen_df_reg (set_src, 1);
3437 /* Now emit using the real source and destination we found, swapping
3438 the order if we detect overlap. */
3439 if (reg_overlap_mentioned_p (dest1, src2))
3441 emit_insn (gen_movdf (dest2, src2));
3442 emit_insn (gen_movdf (dest1, src1));
3446 emit_insn (gen_movdf (dest1, src1));
3447 emit_insn (gen_movdf (dest2, src2));
3453 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3454 (match_operand:TF 1 "fp_zero_operand" ""))]
3456 [(clobber (const_int 0))]
3459 rtx set_dest = operands[0];
3462 switch (GET_CODE (set_dest))
3465 dest1 = gen_df_reg (set_dest, 0);
3466 dest2 = gen_df_reg (set_dest, 1);
3469 dest1 = adjust_address (set_dest, DFmode, 0);
3470 dest2 = adjust_address (set_dest, DFmode, 8);
3476 emit_insn (gen_movdf (dest1, CONST0_RTX (DFmode)));
3477 emit_insn (gen_movdf (dest2, CONST0_RTX (DFmode)));
3482 [(set (match_operand:TF 0 "register_operand" "")
3483 (match_operand:TF 1 "memory_operand" ""))]
3485 && offsettable_memref_p (operands[1])
3487 || ! TARGET_HARD_QUAD
3488 || ! fp_register_operand (operands[0], TFmode)))"
3489 [(clobber (const_int 0))]
3492 rtx word0 = adjust_address (operands[1], DFmode, 0);
3493 rtx word1 = adjust_address (operands[1], DFmode, 8);
3494 rtx set_dest, dest1, dest2;
3496 set_dest = operands[0];
3498 dest1 = gen_df_reg (set_dest, 0);
3499 dest2 = gen_df_reg (set_dest, 1);
3501 /* Now output, ordering such that we don't clobber any registers
3502 mentioned in the address. */
3503 if (reg_overlap_mentioned_p (dest1, word1))
3506 emit_insn (gen_movdf (dest2, word1));
3507 emit_insn (gen_movdf (dest1, word0));
3511 emit_insn (gen_movdf (dest1, word0));
3512 emit_insn (gen_movdf (dest2, word1));
3518 [(set (match_operand:TF 0 "memory_operand" "")
3519 (match_operand:TF 1 "register_operand" ""))]
3521 && offsettable_memref_p (operands[0])
3523 || ! TARGET_HARD_QUAD
3524 || ! fp_register_operand (operands[1], TFmode)))"
3525 [(clobber (const_int 0))]
3528 rtx set_src = operands[1];
3530 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 0),
3531 gen_df_reg (set_src, 0)));
3532 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 8),
3533 gen_df_reg (set_src, 1)));
3537 ;; Sparc V9 conditional move instructions.
3539 ;; We can handle larger constants here for some flavors, but for now we keep
3540 ;; it simple and only allow those constants supported by all flavours.
3541 ;; Note that emit_conditional_move canonicalizes operands 2,3 so that operand
3542 ;; 3 contains the constant if one is present, but we handle either for
3543 ;; generality (sparc.c puts a constant in operand 2).
3545 (define_expand "movqicc"
3546 [(set (match_operand:QI 0 "register_operand" "")
3547 (if_then_else:QI (match_operand 1 "comparison_operator" "")
3548 (match_operand:QI 2 "arith10_operand" "")
3549 (match_operand:QI 3 "arith10_operand" "")))]
3553 enum rtx_code code = GET_CODE (operands[1]);
3555 if (GET_MODE (sparc_compare_op0) == DImode
3559 if (sparc_compare_op1 == const0_rtx
3560 && GET_CODE (sparc_compare_op0) == REG
3561 && GET_MODE (sparc_compare_op0) == DImode
3562 && v9_regcmp_p (code))
3564 operands[1] = gen_rtx_fmt_ee (code, DImode,
3565 sparc_compare_op0, sparc_compare_op1);
3569 rtx cc_reg = gen_compare_reg (code,
3570 sparc_compare_op0, sparc_compare_op1);
3571 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3575 (define_expand "movhicc"
3576 [(set (match_operand:HI 0 "register_operand" "")
3577 (if_then_else:HI (match_operand 1 "comparison_operator" "")
3578 (match_operand:HI 2 "arith10_operand" "")
3579 (match_operand:HI 3 "arith10_operand" "")))]
3583 enum rtx_code code = GET_CODE (operands[1]);
3585 if (GET_MODE (sparc_compare_op0) == DImode
3589 if (sparc_compare_op1 == const0_rtx
3590 && GET_CODE (sparc_compare_op0) == REG
3591 && GET_MODE (sparc_compare_op0) == DImode
3592 && v9_regcmp_p (code))
3594 operands[1] = gen_rtx_fmt_ee (code, DImode,
3595 sparc_compare_op0, sparc_compare_op1);
3599 rtx cc_reg = gen_compare_reg (code,
3600 sparc_compare_op0, sparc_compare_op1);
3601 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3605 (define_expand "movsicc"
3606 [(set (match_operand:SI 0 "register_operand" "")
3607 (if_then_else:SI (match_operand 1 "comparison_operator" "")
3608 (match_operand:SI 2 "arith10_operand" "")
3609 (match_operand:SI 3 "arith10_operand" "")))]
3613 enum rtx_code code = GET_CODE (operands[1]);
3614 enum machine_mode op0_mode = GET_MODE (sparc_compare_op0);
3616 if (sparc_compare_op1 == const0_rtx
3617 && GET_CODE (sparc_compare_op0) == REG
3618 && (TARGET_ARCH64 && op0_mode == DImode && v9_regcmp_p (code)))
3620 operands[1] = gen_rtx_fmt_ee (code, op0_mode,
3621 sparc_compare_op0, sparc_compare_op1);
3625 rtx cc_reg = gen_compare_reg (code,
3626 sparc_compare_op0, sparc_compare_op1);
3627 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg),
3628 cc_reg, const0_rtx);
3632 (define_expand "movdicc"
3633 [(set (match_operand:DI 0 "register_operand" "")
3634 (if_then_else:DI (match_operand 1 "comparison_operator" "")
3635 (match_operand:DI 2 "arith10_double_operand" "")
3636 (match_operand:DI 3 "arith10_double_operand" "")))]
3640 enum rtx_code code = GET_CODE (operands[1]);
3642 if (sparc_compare_op1 == const0_rtx
3643 && GET_CODE (sparc_compare_op0) == REG
3644 && GET_MODE (sparc_compare_op0) == DImode
3645 && v9_regcmp_p (code))
3647 operands[1] = gen_rtx_fmt_ee (code, DImode,
3648 sparc_compare_op0, sparc_compare_op1);
3652 rtx cc_reg = gen_compare_reg (code,
3653 sparc_compare_op0, sparc_compare_op1);
3654 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg),
3655 cc_reg, const0_rtx);
3659 (define_expand "movsfcc"
3660 [(set (match_operand:SF 0 "register_operand" "")
3661 (if_then_else:SF (match_operand 1 "comparison_operator" "")
3662 (match_operand:SF 2 "register_operand" "")
3663 (match_operand:SF 3 "register_operand" "")))]
3664 "TARGET_V9 && TARGET_FPU"
3667 enum rtx_code code = GET_CODE (operands[1]);
3669 if (GET_MODE (sparc_compare_op0) == DImode
3673 if (sparc_compare_op1 == const0_rtx
3674 && GET_CODE (sparc_compare_op0) == REG
3675 && GET_MODE (sparc_compare_op0) == DImode
3676 && v9_regcmp_p (code))
3678 operands[1] = gen_rtx_fmt_ee (code, DImode,
3679 sparc_compare_op0, sparc_compare_op1);
3683 rtx cc_reg = gen_compare_reg (code,
3684 sparc_compare_op0, sparc_compare_op1);
3685 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3689 (define_expand "movdfcc"
3690 [(set (match_operand:DF 0 "register_operand" "")
3691 (if_then_else:DF (match_operand 1 "comparison_operator" "")
3692 (match_operand:DF 2 "register_operand" "")
3693 (match_operand:DF 3 "register_operand" "")))]
3694 "TARGET_V9 && TARGET_FPU"
3697 enum rtx_code code = GET_CODE (operands[1]);
3699 if (GET_MODE (sparc_compare_op0) == DImode
3703 if (sparc_compare_op1 == const0_rtx
3704 && GET_CODE (sparc_compare_op0) == REG
3705 && GET_MODE (sparc_compare_op0) == DImode
3706 && v9_regcmp_p (code))
3708 operands[1] = gen_rtx_fmt_ee (code, DImode,
3709 sparc_compare_op0, sparc_compare_op1);
3713 rtx cc_reg = gen_compare_reg (code,
3714 sparc_compare_op0, sparc_compare_op1);
3715 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3719 (define_expand "movtfcc"
3720 [(set (match_operand:TF 0 "register_operand" "")
3721 (if_then_else:TF (match_operand 1 "comparison_operator" "")
3722 (match_operand:TF 2 "register_operand" "")
3723 (match_operand:TF 3 "register_operand" "")))]
3724 "TARGET_V9 && TARGET_FPU"
3727 enum rtx_code code = GET_CODE (operands[1]);
3729 if (GET_MODE (sparc_compare_op0) == DImode
3733 if (sparc_compare_op1 == const0_rtx
3734 && GET_CODE (sparc_compare_op0) == REG
3735 && GET_MODE (sparc_compare_op0) == DImode
3736 && v9_regcmp_p (code))
3738 operands[1] = gen_rtx_fmt_ee (code, DImode,
3739 sparc_compare_op0, sparc_compare_op1);
3743 rtx cc_reg = gen_compare_reg (code,
3744 sparc_compare_op0, sparc_compare_op1);
3745 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3749 ;; Conditional move define_insns.
3751 (define_insn "*movqi_cc_sp64"
3752 [(set (match_operand:QI 0 "register_operand" "=r,r")
3753 (if_then_else:QI (match_operator 1 "comparison_operator"
3754 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3756 (match_operand:QI 3 "arith11_operand" "rL,0")
3757 (match_operand:QI 4 "arith11_operand" "0,rL")))]
3760 mov%C1\\t%x2, %3, %0
3761 mov%c1\\t%x2, %4, %0"
3762 [(set_attr "type" "cmove")])
3764 (define_insn "*movhi_cc_sp64"
3765 [(set (match_operand:HI 0 "register_operand" "=r,r")
3766 (if_then_else:HI (match_operator 1 "comparison_operator"
3767 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3769 (match_operand:HI 3 "arith11_operand" "rL,0")
3770 (match_operand:HI 4 "arith11_operand" "0,rL")))]
3773 mov%C1\\t%x2, %3, %0
3774 mov%c1\\t%x2, %4, %0"
3775 [(set_attr "type" "cmove")])
3777 (define_insn "*movsi_cc_sp64"
3778 [(set (match_operand:SI 0 "register_operand" "=r,r")
3779 (if_then_else:SI (match_operator 1 "comparison_operator"
3780 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3782 (match_operand:SI 3 "arith11_operand" "rL,0")
3783 (match_operand:SI 4 "arith11_operand" "0,rL")))]
3786 mov%C1\\t%x2, %3, %0
3787 mov%c1\\t%x2, %4, %0"
3788 [(set_attr "type" "cmove")])
3790 ;; ??? The constraints of operands 3,4 need work.
3791 (define_insn "*movdi_cc_sp64"
3792 [(set (match_operand:DI 0 "register_operand" "=r,r")
3793 (if_then_else:DI (match_operator 1 "comparison_operator"
3794 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3796 (match_operand:DI 3 "arith11_double_operand" "rLH,0")
3797 (match_operand:DI 4 "arith11_double_operand" "0,rLH")))]
3800 mov%C1\\t%x2, %3, %0
3801 mov%c1\\t%x2, %4, %0"
3802 [(set_attr "type" "cmove")])
3804 (define_insn "*movdi_cc_sp64_trunc"
3805 [(set (match_operand:SI 0 "register_operand" "=r,r")
3806 (if_then_else:SI (match_operator 1 "comparison_operator"
3807 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3809 (match_operand:SI 3 "arith11_double_operand" "rLH,0")
3810 (match_operand:SI 4 "arith11_double_operand" "0,rLH")))]
3813 mov%C1\\t%x2, %3, %0
3814 mov%c1\\t%x2, %4, %0"
3815 [(set_attr "type" "cmove")])
3817 (define_insn "*movsf_cc_sp64"
3818 [(set (match_operand:SF 0 "register_operand" "=f,f")
3819 (if_then_else:SF (match_operator 1 "comparison_operator"
3820 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3822 (match_operand:SF 3 "register_operand" "f,0")
3823 (match_operand:SF 4 "register_operand" "0,f")))]
3824 "TARGET_V9 && TARGET_FPU"
3826 fmovs%C1\\t%x2, %3, %0
3827 fmovs%c1\\t%x2, %4, %0"
3828 [(set_attr "type" "fpcmove")])
3830 (define_insn "movdf_cc_sp64"
3831 [(set (match_operand:DF 0 "register_operand" "=e,e")
3832 (if_then_else:DF (match_operator 1 "comparison_operator"
3833 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3835 (match_operand:DF 3 "register_operand" "e,0")
3836 (match_operand:DF 4 "register_operand" "0,e")))]
3837 "TARGET_V9 && TARGET_FPU"
3839 fmovd%C1\\t%x2, %3, %0
3840 fmovd%c1\\t%x2, %4, %0"
3841 [(set_attr "type" "fpcmove")
3842 (set_attr "fptype" "double")])
3844 (define_insn "*movtf_cc_hq_sp64"
3845 [(set (match_operand:TF 0 "register_operand" "=e,e")
3846 (if_then_else:TF (match_operator 1 "comparison_operator"
3847 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3849 (match_operand:TF 3 "register_operand" "e,0")
3850 (match_operand:TF 4 "register_operand" "0,e")))]
3851 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
3853 fmovq%C1\\t%x2, %3, %0
3854 fmovq%c1\\t%x2, %4, %0"
3855 [(set_attr "type" "fpcmove")])
3857 (define_insn_and_split "*movtf_cc_sp64"
3858 [(set (match_operand:TF 0 "register_operand" "=e,e")
3859 (if_then_else:TF (match_operator 1 "comparison_operator"
3860 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3862 (match_operand:TF 3 "register_operand" "e,0")
3863 (match_operand:TF 4 "register_operand" "0,e")))]
3864 "TARGET_V9 && TARGET_FPU && !TARGET_HARD_QUAD"
3866 "&& reload_completed"
3867 [(clobber (const_int 0))]
3870 rtx set_dest = operands[0];
3871 rtx set_srca = operands[3];
3872 rtx set_srcb = operands[4];
3873 int third = rtx_equal_p (set_dest, set_srca);
3875 rtx srca1, srca2, srcb1, srcb2;
3877 dest1 = gen_df_reg (set_dest, 0);
3878 dest2 = gen_df_reg (set_dest, 1);
3879 srca1 = gen_df_reg (set_srca, 0);
3880 srca2 = gen_df_reg (set_srca, 1);
3881 srcb1 = gen_df_reg (set_srcb, 0);
3882 srcb2 = gen_df_reg (set_srcb, 1);
3884 /* Now emit using the real source and destination we found, swapping
3885 the order if we detect overlap. */
3886 if ((third && reg_overlap_mentioned_p (dest1, srcb2))
3887 || (!third && reg_overlap_mentioned_p (dest1, srca2)))
3889 emit_insn (gen_movdf_cc_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
3890 emit_insn (gen_movdf_cc_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
3894 emit_insn (gen_movdf_cc_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
3895 emit_insn (gen_movdf_cc_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
3899 [(set_attr "length" "2")])
3901 (define_insn "*movqi_cc_reg_sp64"
3902 [(set (match_operand:QI 0 "register_operand" "=r,r")
3903 (if_then_else:QI (match_operator 1 "v9_regcmp_op"
3904 [(match_operand:DI 2 "register_operand" "r,r")
3906 (match_operand:QI 3 "arith10_operand" "rM,0")
3907 (match_operand:QI 4 "arith10_operand" "0,rM")))]
3910 movr%D1\\t%2, %r3, %0
3911 movr%d1\\t%2, %r4, %0"
3912 [(set_attr "type" "cmove")])
3914 (define_insn "*movhi_cc_reg_sp64"
3915 [(set (match_operand:HI 0 "register_operand" "=r,r")
3916 (if_then_else:HI (match_operator 1 "v9_regcmp_op"
3917 [(match_operand:DI 2 "register_operand" "r,r")
3919 (match_operand:HI 3 "arith10_operand" "rM,0")
3920 (match_operand:HI 4 "arith10_operand" "0,rM")))]
3923 movr%D1\\t%2, %r3, %0
3924 movr%d1\\t%2, %r4, %0"
3925 [(set_attr "type" "cmove")])
3927 (define_insn "*movsi_cc_reg_sp64"
3928 [(set (match_operand:SI 0 "register_operand" "=r,r")
3929 (if_then_else:SI (match_operator 1 "v9_regcmp_op"
3930 [(match_operand:DI 2 "register_operand" "r,r")
3932 (match_operand:SI 3 "arith10_operand" "rM,0")
3933 (match_operand:SI 4 "arith10_operand" "0,rM")))]
3936 movr%D1\\t%2, %r3, %0
3937 movr%d1\\t%2, %r4, %0"
3938 [(set_attr "type" "cmove")])
3940 ;; ??? The constraints of operands 3,4 need work.
3941 (define_insn "*movdi_cc_reg_sp64"
3942 [(set (match_operand:DI 0 "register_operand" "=r,r")
3943 (if_then_else:DI (match_operator 1 "v9_regcmp_op"
3944 [(match_operand:DI 2 "register_operand" "r,r")
3946 (match_operand:DI 3 "arith10_double_operand" "rMH,0")
3947 (match_operand:DI 4 "arith10_double_operand" "0,rMH")))]
3950 movr%D1\\t%2, %r3, %0
3951 movr%d1\\t%2, %r4, %0"
3952 [(set_attr "type" "cmove")])
3954 (define_insn "*movdi_cc_reg_sp64_trunc"
3955 [(set (match_operand:SI 0 "register_operand" "=r,r")
3956 (if_then_else:SI (match_operator 1 "v9_regcmp_op"
3957 [(match_operand:DI 2 "register_operand" "r,r")
3959 (match_operand:SI 3 "arith10_double_operand" "rMH,0")
3960 (match_operand:SI 4 "arith10_double_operand" "0,rMH")))]
3963 movr%D1\\t%2, %r3, %0
3964 movr%d1\\t%2, %r4, %0"
3965 [(set_attr "type" "cmove")])
3967 (define_insn "*movsf_cc_reg_sp64"
3968 [(set (match_operand:SF 0 "register_operand" "=f,f")
3969 (if_then_else:SF (match_operator 1 "v9_regcmp_op"
3970 [(match_operand:DI 2 "register_operand" "r,r")
3972 (match_operand:SF 3 "register_operand" "f,0")
3973 (match_operand:SF 4 "register_operand" "0,f")))]
3974 "TARGET_ARCH64 && TARGET_FPU"
3976 fmovrs%D1\\t%2, %3, %0
3977 fmovrs%d1\\t%2, %4, %0"
3978 [(set_attr "type" "fpcrmove")])
3980 (define_insn "movdf_cc_reg_sp64"
3981 [(set (match_operand:DF 0 "register_operand" "=e,e")
3982 (if_then_else:DF (match_operator 1 "v9_regcmp_op"
3983 [(match_operand:DI 2 "register_operand" "r,r")
3985 (match_operand:DF 3 "register_operand" "e,0")
3986 (match_operand:DF 4 "register_operand" "0,e")))]
3987 "TARGET_ARCH64 && TARGET_FPU"
3989 fmovrd%D1\\t%2, %3, %0
3990 fmovrd%d1\\t%2, %4, %0"
3991 [(set_attr "type" "fpcrmove")
3992 (set_attr "fptype" "double")])
3994 (define_insn "*movtf_cc_reg_hq_sp64"
3995 [(set (match_operand:TF 0 "register_operand" "=e,e")
3996 (if_then_else:TF (match_operator 1 "v9_regcmp_op"
3997 [(match_operand:DI 2 "register_operand" "r,r")
3999 (match_operand:TF 3 "register_operand" "e,0")
4000 (match_operand:TF 4 "register_operand" "0,e")))]
4001 "TARGET_ARCH64 && TARGET_FPU && TARGET_HARD_QUAD"
4003 fmovrq%D1\\t%2, %3, %0
4004 fmovrq%d1\\t%2, %4, %0"
4005 [(set_attr "type" "fpcrmove")])
4007 (define_insn_and_split "*movtf_cc_reg_sp64"
4008 [(set (match_operand:TF 0 "register_operand" "=e,e")
4009 (if_then_else:TF (match_operator 1 "v9_regcmp_op"
4010 [(match_operand:DI 2 "register_operand" "r,r")
4012 (match_operand:TF 3 "register_operand" "e,0")
4013 (match_operand:TF 4 "register_operand" "0,e")))]
4014 "TARGET_ARCH64 && TARGET_FPU && ! TARGET_HARD_QUAD"
4016 "&& reload_completed"
4017 [(clobber (const_int 0))]
4020 rtx set_dest = operands[0];
4021 rtx set_srca = operands[3];
4022 rtx set_srcb = operands[4];
4023 int third = rtx_equal_p (set_dest, set_srca);
4025 rtx srca1, srca2, srcb1, srcb2;
4027 dest1 = gen_df_reg (set_dest, 0);
4028 dest2 = gen_df_reg (set_dest, 1);
4029 srca1 = gen_df_reg (set_srca, 0);
4030 srca2 = gen_df_reg (set_srca, 1);
4031 srcb1 = gen_df_reg (set_srcb, 0);
4032 srcb2 = gen_df_reg (set_srcb, 1);
4034 /* Now emit using the real source and destination we found, swapping
4035 the order if we detect overlap. */
4036 if ((third && reg_overlap_mentioned_p (dest1, srcb2))
4037 || (!third && reg_overlap_mentioned_p (dest1, srca2)))
4039 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
4040 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
4044 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
4045 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
4049 [(set_attr "length" "2")])
4052 ;;- zero extension instructions
4054 ;; These patterns originally accepted general_operands, however, slightly
4055 ;; better code is generated by only accepting register_operands, and then
4056 ;; letting combine generate the ldu[hb] insns.
4058 (define_expand "zero_extendhisi2"
4059 [(set (match_operand:SI 0 "register_operand" "")
4060 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
4064 rtx temp = gen_reg_rtx (SImode);
4065 rtx shift_16 = GEN_INT (16);
4066 int op1_subbyte = 0;
4068 if (GET_CODE (operand1) == SUBREG)
4070 op1_subbyte = SUBREG_BYTE (operand1);
4071 op1_subbyte /= GET_MODE_SIZE (SImode);
4072 op1_subbyte *= GET_MODE_SIZE (SImode);
4073 operand1 = XEXP (operand1, 0);
4076 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4078 emit_insn (gen_lshrsi3 (operand0, temp, shift_16));
4082 (define_insn "*zero_extendhisi2_insn"
4083 [(set (match_operand:SI 0 "register_operand" "=r")
4084 (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
4087 [(set_attr "type" "load")
4088 (set_attr "us3load_type" "3cycle")])
4090 (define_expand "zero_extendqihi2"
4091 [(set (match_operand:HI 0 "register_operand" "")
4092 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
4096 (define_insn "*zero_extendqihi2_insn"
4097 [(set (match_operand:HI 0 "register_operand" "=r,r")
4098 (zero_extend:HI (match_operand:QI 1 "input_operand" "r,m")))]
4099 "GET_CODE (operands[1]) != CONST_INT"
4103 [(set_attr "type" "*,load")
4104 (set_attr "us3load_type" "*,3cycle")])
4106 (define_expand "zero_extendqisi2"
4107 [(set (match_operand:SI 0 "register_operand" "")
4108 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
4112 (define_insn "*zero_extendqisi2_insn"
4113 [(set (match_operand:SI 0 "register_operand" "=r,r")
4114 (zero_extend:SI (match_operand:QI 1 "input_operand" "r,m")))]
4115 "GET_CODE (operands[1]) != CONST_INT"
4119 [(set_attr "type" "*,load")
4120 (set_attr "us3load_type" "*,3cycle")])
4122 (define_expand "zero_extendqidi2"
4123 [(set (match_operand:DI 0 "register_operand" "")
4124 (zero_extend:DI (match_operand:QI 1 "register_operand" "")))]
4128 (define_insn "*zero_extendqidi2_insn"
4129 [(set (match_operand:DI 0 "register_operand" "=r,r")
4130 (zero_extend:DI (match_operand:QI 1 "input_operand" "r,m")))]
4131 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
4135 [(set_attr "type" "*,load")
4136 (set_attr "us3load_type" "*,3cycle")])
4138 (define_expand "zero_extendhidi2"
4139 [(set (match_operand:DI 0 "register_operand" "")
4140 (zero_extend:DI (match_operand:HI 1 "register_operand" "")))]
4144 rtx temp = gen_reg_rtx (DImode);
4145 rtx shift_48 = GEN_INT (48);
4146 int op1_subbyte = 0;
4148 if (GET_CODE (operand1) == SUBREG)
4150 op1_subbyte = SUBREG_BYTE (operand1);
4151 op1_subbyte /= GET_MODE_SIZE (DImode);
4152 op1_subbyte *= GET_MODE_SIZE (DImode);
4153 operand1 = XEXP (operand1, 0);
4156 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
4158 emit_insn (gen_lshrdi3 (operand0, temp, shift_48));
4162 (define_insn "*zero_extendhidi2_insn"
4163 [(set (match_operand:DI 0 "register_operand" "=r")
4164 (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
4167 [(set_attr "type" "load")
4168 (set_attr "us3load_type" "3cycle")])
4171 ;; ??? Write truncdisi pattern using sra?
4173 (define_expand "zero_extendsidi2"
4174 [(set (match_operand:DI 0 "register_operand" "")
4175 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
4179 (define_insn "*zero_extendsidi2_insn_sp64"
4180 [(set (match_operand:DI 0 "register_operand" "=r,r")
4181 (zero_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
4182 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
4186 [(set_attr "type" "shift,load")])
4188 (define_insn_and_split "*zero_extendsidi2_insn_sp32"
4189 [(set (match_operand:DI 0 "register_operand" "=r")
4190 (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
4193 "&& reload_completed"
4194 [(set (match_dup 2) (match_dup 3))
4195 (set (match_dup 4) (match_dup 5))]
4200 dest1 = gen_highpart (SImode, operands[0]);
4201 dest2 = gen_lowpart (SImode, operands[0]);
4203 /* Swap the order in case of overlap. */
4204 if (REGNO (dest1) == REGNO (operands[1]))
4206 operands[2] = dest2;
4207 operands[3] = operands[1];
4208 operands[4] = dest1;
4209 operands[5] = const0_rtx;
4213 operands[2] = dest1;
4214 operands[3] = const0_rtx;
4215 operands[4] = dest2;
4216 operands[5] = operands[1];
4219 [(set_attr "length" "2")])
4221 ;; Simplify comparisons of extended values.
4223 (define_insn "*cmp_zero_extendqisi2"
4225 (compare:CC (zero_extend:SI (match_operand:QI 0 "register_operand" "r"))
4228 "andcc\\t%0, 0xff, %%g0"
4229 [(set_attr "type" "compare")])
4231 (define_insn "*cmp_zero_qi"
4233 (compare:CC (match_operand:QI 0 "register_operand" "r")
4236 "andcc\\t%0, 0xff, %%g0"
4237 [(set_attr "type" "compare")])
4239 (define_insn "*cmp_zero_extendqisi2_set"
4241 (compare:CC (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
4243 (set (match_operand:SI 0 "register_operand" "=r")
4244 (zero_extend:SI (match_dup 1)))]
4246 "andcc\\t%1, 0xff, %0"
4247 [(set_attr "type" "compare")])
4249 (define_insn "*cmp_zero_extendqisi2_andcc_set"
4251 (compare:CC (and:SI (match_operand:SI 1 "register_operand" "r")
4254 (set (match_operand:SI 0 "register_operand" "=r")
4255 (zero_extend:SI (subreg:QI (match_dup 1) 0)))]
4257 "andcc\\t%1, 0xff, %0"
4258 [(set_attr "type" "compare")])
4260 (define_insn "*cmp_zero_extendqidi2"
4262 (compare:CCX (zero_extend:DI (match_operand:QI 0 "register_operand" "r"))
4265 "andcc\\t%0, 0xff, %%g0"
4266 [(set_attr "type" "compare")])
4268 (define_insn "*cmp_zero_qi_sp64"
4270 (compare:CCX (match_operand:QI 0 "register_operand" "r")
4273 "andcc\\t%0, 0xff, %%g0"
4274 [(set_attr "type" "compare")])
4276 (define_insn "*cmp_zero_extendqidi2_set"
4278 (compare:CCX (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
4280 (set (match_operand:DI 0 "register_operand" "=r")
4281 (zero_extend:DI (match_dup 1)))]
4283 "andcc\\t%1, 0xff, %0"
4284 [(set_attr "type" "compare")])
4286 (define_insn "*cmp_zero_extendqidi2_andcc_set"
4288 (compare:CCX (and:DI (match_operand:DI 1 "register_operand" "r")
4291 (set (match_operand:DI 0 "register_operand" "=r")
4292 (zero_extend:DI (subreg:QI (match_dup 1) 0)))]
4294 "andcc\\t%1, 0xff, %0"
4295 [(set_attr "type" "compare")])
4297 ;; Similarly, handle {SI,DI}->QI mode truncation followed by a compare.
4299 (define_insn "*cmp_siqi_trunc"
4301 (compare:CC (subreg:QI (match_operand:SI 0 "register_operand" "r") 3)
4304 "andcc\\t%0, 0xff, %%g0"
4305 [(set_attr "type" "compare")])
4307 (define_insn "*cmp_siqi_trunc_set"
4309 (compare:CC (subreg:QI (match_operand:SI 1 "register_operand" "r") 3)
4311 (set (match_operand:QI 0 "register_operand" "=r")
4312 (subreg:QI (match_dup 1) 3))]
4314 "andcc\\t%1, 0xff, %0"
4315 [(set_attr "type" "compare")])
4317 (define_insn "*cmp_diqi_trunc"
4319 (compare:CC (subreg:QI (match_operand:DI 0 "register_operand" "r") 7)
4322 "andcc\\t%0, 0xff, %%g0"
4323 [(set_attr "type" "compare")])
4325 (define_insn "*cmp_diqi_trunc_set"
4327 (compare:CC (subreg:QI (match_operand:DI 1 "register_operand" "r") 7)
4329 (set (match_operand:QI 0 "register_operand" "=r")
4330 (subreg:QI (match_dup 1) 7))]
4332 "andcc\\t%1, 0xff, %0"
4333 [(set_attr "type" "compare")])
4335 ;;- sign extension instructions
4337 ;; These patterns originally accepted general_operands, however, slightly
4338 ;; better code is generated by only accepting register_operands, and then
4339 ;; letting combine generate the lds[hb] insns.
4341 (define_expand "extendhisi2"
4342 [(set (match_operand:SI 0 "register_operand" "")
4343 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
4347 rtx temp = gen_reg_rtx (SImode);
4348 rtx shift_16 = GEN_INT (16);
4349 int op1_subbyte = 0;
4351 if (GET_CODE (operand1) == SUBREG)
4353 op1_subbyte = SUBREG_BYTE (operand1);
4354 op1_subbyte /= GET_MODE_SIZE (SImode);
4355 op1_subbyte *= GET_MODE_SIZE (SImode);
4356 operand1 = XEXP (operand1, 0);
4359 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4361 emit_insn (gen_ashrsi3 (operand0, temp, shift_16));
4365 (define_insn "*sign_extendhisi2_insn"
4366 [(set (match_operand:SI 0 "register_operand" "=r")
4367 (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
4370 [(set_attr "type" "sload")
4371 (set_attr "us3load_type" "3cycle")])
4373 (define_expand "extendqihi2"
4374 [(set (match_operand:HI 0 "register_operand" "")
4375 (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
4379 rtx temp = gen_reg_rtx (SImode);
4380 rtx shift_24 = GEN_INT (24);
4381 int op1_subbyte = 0;
4382 int op0_subbyte = 0;
4384 if (GET_CODE (operand1) == SUBREG)
4386 op1_subbyte = SUBREG_BYTE (operand1);
4387 op1_subbyte /= GET_MODE_SIZE (SImode);
4388 op1_subbyte *= GET_MODE_SIZE (SImode);
4389 operand1 = XEXP (operand1, 0);
4391 if (GET_CODE (operand0) == SUBREG)
4393 op0_subbyte = SUBREG_BYTE (operand0);
4394 op0_subbyte /= GET_MODE_SIZE (SImode);
4395 op0_subbyte *= GET_MODE_SIZE (SImode);
4396 operand0 = XEXP (operand0, 0);
4398 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4400 if (GET_MODE (operand0) != SImode)
4401 operand0 = gen_rtx_SUBREG (SImode, operand0, op0_subbyte);
4402 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
4406 (define_insn "*sign_extendqihi2_insn"
4407 [(set (match_operand:HI 0 "register_operand" "=r")
4408 (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
4411 [(set_attr "type" "sload")
4412 (set_attr "us3load_type" "3cycle")])
4414 (define_expand "extendqisi2"
4415 [(set (match_operand:SI 0 "register_operand" "")
4416 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
4420 rtx temp = gen_reg_rtx (SImode);
4421 rtx shift_24 = GEN_INT (24);
4422 int op1_subbyte = 0;
4424 if (GET_CODE (operand1) == SUBREG)
4426 op1_subbyte = SUBREG_BYTE (operand1);
4427 op1_subbyte /= GET_MODE_SIZE (SImode);
4428 op1_subbyte *= GET_MODE_SIZE (SImode);
4429 operand1 = XEXP (operand1, 0);
4432 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4434 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
4438 (define_insn "*sign_extendqisi2_insn"
4439 [(set (match_operand:SI 0 "register_operand" "=r")
4440 (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
4443 [(set_attr "type" "sload")
4444 (set_attr "us3load_type" "3cycle")])
4446 (define_expand "extendqidi2"
4447 [(set (match_operand:DI 0 "register_operand" "")
4448 (sign_extend:DI (match_operand:QI 1 "register_operand" "")))]
4452 rtx temp = gen_reg_rtx (DImode);
4453 rtx shift_56 = GEN_INT (56);
4454 int op1_subbyte = 0;
4456 if (GET_CODE (operand1) == SUBREG)
4458 op1_subbyte = SUBREG_BYTE (operand1);
4459 op1_subbyte /= GET_MODE_SIZE (DImode);
4460 op1_subbyte *= GET_MODE_SIZE (DImode);
4461 operand1 = XEXP (operand1, 0);
4464 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
4466 emit_insn (gen_ashrdi3 (operand0, temp, shift_56));
4470 (define_insn "*sign_extendqidi2_insn"
4471 [(set (match_operand:DI 0 "register_operand" "=r")
4472 (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
4475 [(set_attr "type" "sload")
4476 (set_attr "us3load_type" "3cycle")])
4478 (define_expand "extendhidi2"
4479 [(set (match_operand:DI 0 "register_operand" "")
4480 (sign_extend:DI (match_operand:HI 1 "register_operand" "")))]
4484 rtx temp = gen_reg_rtx (DImode);
4485 rtx shift_48 = GEN_INT (48);
4486 int op1_subbyte = 0;
4488 if (GET_CODE (operand1) == SUBREG)
4490 op1_subbyte = SUBREG_BYTE (operand1);
4491 op1_subbyte /= GET_MODE_SIZE (DImode);
4492 op1_subbyte *= GET_MODE_SIZE (DImode);
4493 operand1 = XEXP (operand1, 0);
4496 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
4498 emit_insn (gen_ashrdi3 (operand0, temp, shift_48));
4502 (define_insn "*sign_extendhidi2_insn"
4503 [(set (match_operand:DI 0 "register_operand" "=r")
4504 (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
4507 [(set_attr "type" "sload")
4508 (set_attr "us3load_type" "3cycle")])
4510 (define_expand "extendsidi2"
4511 [(set (match_operand:DI 0 "register_operand" "")
4512 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
4516 (define_insn "*sign_extendsidi2_insn"
4517 [(set (match_operand:DI 0 "register_operand" "=r,r")
4518 (sign_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
4523 [(set_attr "type" "shift,sload")
4524 (set_attr "us3load_type" "*,3cycle")])
4526 ;; Special pattern for optimizing bit-field compares. This is needed
4527 ;; because combine uses this as a canonical form.
4529 (define_insn "*cmp_zero_extract"
4532 (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
4533 (match_operand:SI 1 "small_int_or_double" "n")
4534 (match_operand:SI 2 "small_int_or_double" "n"))
4536 "(GET_CODE (operands[2]) == CONST_INT
4537 && INTVAL (operands[2]) > 19)
4538 || (GET_CODE (operands[2]) == CONST_DOUBLE
4539 && CONST_DOUBLE_LOW (operands[2]) > 19)"
4542 int len = (GET_CODE (operands[1]) == CONST_INT
4543 ? INTVAL (operands[1])
4544 : CONST_DOUBLE_LOW (operands[1]));
4546 (GET_CODE (operands[2]) == CONST_INT
4547 ? INTVAL (operands[2])
4548 : CONST_DOUBLE_LOW (operands[2])) - len;
4549 HOST_WIDE_INT mask = ((1 << len) - 1) << pos;
4551 operands[1] = GEN_INT (mask);
4552 return \"andcc\\t%0, %1, %%g0\";
4554 [(set_attr "type" "compare")])
4556 (define_insn "*cmp_zero_extract_sp64"
4559 (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
4560 (match_operand:SI 1 "small_int_or_double" "n")
4561 (match_operand:SI 2 "small_int_or_double" "n"))
4564 && ((GET_CODE (operands[2]) == CONST_INT
4565 && INTVAL (operands[2]) > 51)
4566 || (GET_CODE (operands[2]) == CONST_DOUBLE
4567 && CONST_DOUBLE_LOW (operands[2]) > 51))"
4570 int len = (GET_CODE (operands[1]) == CONST_INT
4571 ? INTVAL (operands[1])
4572 : CONST_DOUBLE_LOW (operands[1]));
4574 (GET_CODE (operands[2]) == CONST_INT
4575 ? INTVAL (operands[2])
4576 : CONST_DOUBLE_LOW (operands[2])) - len;
4577 HOST_WIDE_INT mask = (((unsigned HOST_WIDE_INT) 1 << len) - 1) << pos;
4579 operands[1] = GEN_INT (mask);
4580 return \"andcc\\t%0, %1, %%g0\";
4582 [(set_attr "type" "compare")])
4584 ;; Conversions between float, double and long double.
4586 (define_insn "extendsfdf2"
4587 [(set (match_operand:DF 0 "register_operand" "=e")
4589 (match_operand:SF 1 "register_operand" "f")))]
4592 [(set_attr "type" "fp")
4593 (set_attr "fptype" "double")])
4595 (define_expand "extendsftf2"
4596 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4598 (match_operand:SF 1 "register_operand" "")))]
4599 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4600 "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
4602 (define_insn "*extendsftf2_hq"
4603 [(set (match_operand:TF 0 "register_operand" "=e")
4605 (match_operand:SF 1 "register_operand" "f")))]
4606 "TARGET_FPU && TARGET_HARD_QUAD"
4608 [(set_attr "type" "fp")])
4610 (define_expand "extenddftf2"
4611 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4613 (match_operand:DF 1 "register_operand" "")))]
4614 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4615 "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
4617 (define_insn "*extenddftf2_hq"
4618 [(set (match_operand:TF 0 "register_operand" "=e")
4620 (match_operand:DF 1 "register_operand" "e")))]
4621 "TARGET_FPU && TARGET_HARD_QUAD"
4623 [(set_attr "type" "fp")])
4625 (define_insn "truncdfsf2"
4626 [(set (match_operand:SF 0 "register_operand" "=f")
4628 (match_operand:DF 1 "register_operand" "e")))]
4631 [(set_attr "type" "fp")
4632 (set_attr "fptype" "double")])
4634 (define_expand "trunctfsf2"
4635 [(set (match_operand:SF 0 "register_operand" "")
4637 (match_operand:TF 1 "general_operand" "")))]
4638 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4639 "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
4641 (define_insn "*trunctfsf2_hq"
4642 [(set (match_operand:SF 0 "register_operand" "=f")
4644 (match_operand:TF 1 "register_operand" "e")))]
4645 "TARGET_FPU && TARGET_HARD_QUAD"
4647 [(set_attr "type" "fp")])
4649 (define_expand "trunctfdf2"
4650 [(set (match_operand:DF 0 "register_operand" "")
4652 (match_operand:TF 1 "general_operand" "")))]
4653 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4654 "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
4656 (define_insn "*trunctfdf2_hq"
4657 [(set (match_operand:DF 0 "register_operand" "=e")
4659 (match_operand:TF 1 "register_operand" "e")))]
4660 "TARGET_FPU && TARGET_HARD_QUAD"
4662 [(set_attr "type" "fp")])
4664 ;; Conversion between fixed point and floating point.
4666 (define_insn "floatsisf2"
4667 [(set (match_operand:SF 0 "register_operand" "=f")
4668 (float:SF (match_operand:SI 1 "register_operand" "f")))]
4671 [(set_attr "type" "fp")
4672 (set_attr "fptype" "double")])
4674 (define_insn "floatsidf2"
4675 [(set (match_operand:DF 0 "register_operand" "=e")
4676 (float:DF (match_operand:SI 1 "register_operand" "f")))]
4679 [(set_attr "type" "fp")
4680 (set_attr "fptype" "double")])
4682 (define_expand "floatsitf2"
4683 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4684 (float:TF (match_operand:SI 1 "register_operand" "")))]
4685 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4686 "emit_tfmode_cvt (FLOAT, operands); DONE;")
4688 (define_insn "*floatsitf2_hq"
4689 [(set (match_operand:TF 0 "register_operand" "=e")
4690 (float:TF (match_operand:SI 1 "register_operand" "f")))]
4691 "TARGET_FPU && TARGET_HARD_QUAD"
4693 [(set_attr "type" "fp")])
4695 (define_expand "floatunssitf2"
4696 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4697 (unsigned_float:TF (match_operand:SI 1 "register_operand" "")))]
4698 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4699 "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
4701 ;; Now the same for 64 bit sources.
4703 (define_insn "floatdisf2"
4704 [(set (match_operand:SF 0 "register_operand" "=f")
4705 (float:SF (match_operand:DI 1 "register_operand" "e")))]
4706 "TARGET_V9 && TARGET_FPU"
4708 [(set_attr "type" "fp")
4709 (set_attr "fptype" "double")])
4711 (define_expand "floatunsdisf2"
4712 [(use (match_operand:SF 0 "register_operand" ""))
4713 (use (match_operand:DI 1 "register_operand" ""))]
4714 "TARGET_ARCH64 && TARGET_FPU"
4715 "sparc_emit_floatunsdi (operands); DONE;")
4717 (define_insn "floatdidf2"
4718 [(set (match_operand:DF 0 "register_operand" "=e")
4719 (float:DF (match_operand:DI 1 "register_operand" "e")))]
4720 "TARGET_V9 && TARGET_FPU"
4722 [(set_attr "type" "fp")
4723 (set_attr "fptype" "double")])
4725 (define_expand "floatunsdidf2"
4726 [(use (match_operand:DF 0 "register_operand" ""))
4727 (use (match_operand:DI 1 "register_operand" ""))]
4728 "TARGET_ARCH64 && TARGET_FPU"
4729 "sparc_emit_floatunsdi (operands); DONE;")
4731 (define_expand "floatditf2"
4732 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4733 (float:TF (match_operand:DI 1 "register_operand" "")))]
4734 "TARGET_FPU && TARGET_V9 && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4735 "emit_tfmode_cvt (FLOAT, operands); DONE;")
4737 (define_insn "*floatditf2_hq"
4738 [(set (match_operand:TF 0 "register_operand" "=e")
4739 (float:TF (match_operand:DI 1 "register_operand" "e")))]
4740 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
4742 [(set_attr "type" "fp")])
4744 (define_expand "floatunsditf2"
4745 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4746 (unsigned_float:TF (match_operand:DI 1 "register_operand" "")))]
4747 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4748 "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
4750 ;; Convert a float to an actual integer.
4751 ;; Truncation is performed as part of the conversion.
4753 (define_insn "fix_truncsfsi2"
4754 [(set (match_operand:SI 0 "register_operand" "=f")
4755 (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
4758 [(set_attr "type" "fp")
4759 (set_attr "fptype" "double")])
4761 (define_insn "fix_truncdfsi2"
4762 [(set (match_operand:SI 0 "register_operand" "=f")
4763 (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
4766 [(set_attr "type" "fp")
4767 (set_attr "fptype" "double")])
4769 (define_expand "fix_trunctfsi2"
4770 [(set (match_operand:SI 0 "register_operand" "")
4771 (fix:SI (match_operand:TF 1 "general_operand" "")))]
4772 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4773 "emit_tfmode_cvt (FIX, operands); DONE;")
4775 (define_insn "*fix_trunctfsi2_hq"
4776 [(set (match_operand:SI 0 "register_operand" "=f")
4777 (fix:SI (match_operand:TF 1 "register_operand" "e")))]
4778 "TARGET_FPU && TARGET_HARD_QUAD"
4780 [(set_attr "type" "fp")])
4782 (define_expand "fixuns_trunctfsi2"
4783 [(set (match_operand:SI 0 "register_operand" "")
4784 (unsigned_fix:SI (match_operand:TF 1 "general_operand" "")))]
4785 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4786 "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
4788 ;; Now the same, for V9 targets
4790 (define_insn "fix_truncsfdi2"
4791 [(set (match_operand:DI 0 "register_operand" "=e")
4792 (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
4793 "TARGET_V9 && TARGET_FPU"
4795 [(set_attr "type" "fp")
4796 (set_attr "fptype" "double")])
4798 (define_insn "fix_truncdfdi2"
4799 [(set (match_operand:DI 0 "register_operand" "=e")
4800 (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
4801 "TARGET_V9 && TARGET_FPU"
4803 [(set_attr "type" "fp")
4804 (set_attr "fptype" "double")])
4806 (define_expand "fix_trunctfdi2"
4807 [(set (match_operand:DI 0 "register_operand" "")
4808 (fix:DI (match_operand:TF 1 "general_operand" "")))]
4809 "TARGET_V9 && TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4810 "emit_tfmode_cvt (FIX, operands); DONE;")
4812 (define_insn "*fix_trunctfdi2_hq"
4813 [(set (match_operand:DI 0 "register_operand" "=e")
4814 (fix:DI (match_operand:TF 1 "register_operand" "e")))]
4815 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
4817 [(set_attr "type" "fp")])
4819 (define_expand "fixuns_trunctfdi2"
4820 [(set (match_operand:DI 0 "register_operand" "")
4821 (unsigned_fix:DI (match_operand:TF 1 "general_operand" "")))]
4822 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4823 "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
4825 ;;- arithmetic instructions
4827 (define_expand "adddi3"
4828 [(set (match_operand:DI 0 "register_operand" "=r")
4829 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
4830 (match_operand:DI 2 "arith_double_add_operand" "rHI")))]
4836 if (! TARGET_ARCH64)
4838 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
4839 gen_rtx_SET (VOIDmode, operands[0],
4840 gen_rtx_PLUS (DImode, operands[1],
4842 gen_rtx_CLOBBER (VOIDmode,
4843 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
4846 if (arith_double_4096_operand(operands[2], DImode))
4848 switch (GET_CODE (operands[1]))
4850 case CONST_INT: i = INTVAL (operands[1]); break;
4851 case CONST_DOUBLE: i = CONST_DOUBLE_LOW (operands[1]); break;
4853 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
4854 gen_rtx_MINUS (DImode, operands[1],
4858 emit_insn (gen_movdi (operands[0], GEN_INT (i + 4096)));
4863 (define_insn_and_split "adddi3_insn_sp32"
4864 [(set (match_operand:DI 0 "register_operand" "=r")
4865 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
4866 (match_operand:DI 2 "arith_double_operand" "rHI")))
4867 (clobber (reg:CC 100))]
4870 "&& reload_completed"
4871 [(parallel [(set (reg:CC_NOOV 100)
4872 (compare:CC_NOOV (plus:SI (match_dup 4)
4876 (plus:SI (match_dup 4) (match_dup 5)))])
4878 (plus:SI (plus:SI (match_dup 7)
4880 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4883 operands[3] = gen_lowpart (SImode, operands[0]);
4884 operands[4] = gen_lowpart (SImode, operands[1]);
4885 operands[5] = gen_lowpart (SImode, operands[2]);
4886 operands[6] = gen_highpart (SImode, operands[0]);
4887 operands[7] = gen_highpart_mode (SImode, DImode, operands[1]);
4888 #if HOST_BITS_PER_WIDE_INT == 32
4889 if (GET_CODE (operands[2]) == CONST_INT)
4891 if (INTVAL (operands[2]) < 0)
4892 operands[8] = constm1_rtx;
4894 operands[8] = const0_rtx;
4898 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
4900 [(set_attr "length" "2")])
4903 [(set (match_operand:DI 0 "register_operand" "")
4904 (minus:DI (match_operand:DI 1 "arith_double_operand" "")
4905 (match_operand:DI 2 "arith_double_operand" "")))
4906 (clobber (reg:CC 100))]
4907 "! TARGET_ARCH64 && reload_completed"
4908 [(parallel [(set (reg:CC_NOOV 100)
4909 (compare:CC_NOOV (minus:SI (match_dup 4)
4913 (minus:SI (match_dup 4) (match_dup 5)))])
4915 (minus:SI (minus:SI (match_dup 7)
4917 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4920 operands[3] = gen_lowpart (SImode, operands[0]);
4921 operands[4] = gen_lowpart (SImode, operands[1]);
4922 operands[5] = gen_lowpart (SImode, operands[2]);
4923 operands[6] = gen_highpart (SImode, operands[0]);
4924 operands[7] = gen_highpart (SImode, operands[1]);
4925 #if HOST_BITS_PER_WIDE_INT == 32
4926 if (GET_CODE (operands[2]) == CONST_INT)
4928 if (INTVAL (operands[2]) < 0)
4929 operands[8] = constm1_rtx;
4931 operands[8] = const0_rtx;
4935 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
4938 ;; LTU here means "carry set"
4940 [(set (match_operand:SI 0 "register_operand" "=r")
4941 (plus:SI (plus:SI (match_operand:SI 1 "arith_operand" "%r")
4942 (match_operand:SI 2 "arith_operand" "rI"))
4943 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4946 [(set_attr "type" "ialuX")])
4948 (define_insn_and_split "*addx_extend_sp32"
4949 [(set (match_operand:DI 0 "register_operand" "=r")
4950 (zero_extend:DI (plus:SI (plus:SI
4951 (match_operand:SI 1 "reg_or_0_operand" "%rJ")
4952 (match_operand:SI 2 "arith_operand" "rI"))
4953 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4956 "&& reload_completed"
4957 [(set (match_dup 3) (plus:SI (plus:SI (match_dup 1) (match_dup 2))
4958 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
4959 (set (match_dup 4) (const_int 0))]
4960 "operands[3] = gen_lowpart (SImode, operands[0]);
4961 operands[4] = gen_highpart_mode (SImode, DImode, operands[1]);"
4962 [(set_attr "length" "2")])
4964 (define_insn "*addx_extend_sp64"
4965 [(set (match_operand:DI 0 "register_operand" "=r")
4966 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
4967 (match_operand:SI 2 "arith_operand" "rI"))
4968 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4970 "addx\\t%r1, %2, %0"
4971 [(set_attr "type" "ialuX")])
4974 [(set (match_operand:SI 0 "register_operand" "=r")
4975 (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
4976 (match_operand:SI 2 "arith_operand" "rI"))
4977 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4979 "subx\\t%r1, %2, %0"
4980 [(set_attr "type" "ialuX")])
4982 (define_insn "*subx_extend_sp64"
4983 [(set (match_operand:DI 0 "register_operand" "=r")
4984 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
4985 (match_operand:SI 2 "arith_operand" "rI"))
4986 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4988 "subx\\t%r1, %2, %0"
4989 [(set_attr "type" "ialuX")])
4991 (define_insn_and_split "*subx_extend"
4992 [(set (match_operand:DI 0 "register_operand" "=r")
4993 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
4994 (match_operand:SI 2 "arith_operand" "rI"))
4995 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4998 "&& reload_completed"
4999 [(set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 2))
5000 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
5001 (set (match_dup 4) (const_int 0))]
5002 "operands[3] = gen_lowpart (SImode, operands[0]);
5003 operands[4] = gen_highpart (SImode, operands[0]);"
5004 [(set_attr "length" "2")])
5006 (define_insn_and_split ""
5007 [(set (match_operand:DI 0 "register_operand" "=r")
5008 (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5009 (match_operand:DI 2 "register_operand" "r")))
5010 (clobber (reg:CC 100))]
5013 "&& reload_completed"
5014 [(parallel [(set (reg:CC_NOOV 100)
5015 (compare:CC_NOOV (plus:SI (match_dup 3) (match_dup 1))
5017 (set (match_dup 5) (plus:SI (match_dup 3) (match_dup 1)))])
5019 (plus:SI (plus:SI (match_dup 4) (const_int 0))
5020 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5021 "operands[3] = gen_lowpart (SImode, operands[2]);
5022 operands[4] = gen_highpart (SImode, operands[2]);
5023 operands[5] = gen_lowpart (SImode, operands[0]);
5024 operands[6] = gen_highpart (SImode, operands[0]);"
5025 [(set_attr "length" "2")])
5027 (define_insn "*adddi3_sp64"
5028 [(set (match_operand:DI 0 "register_operand" "=r")
5029 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
5030 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5034 (define_expand "addsi3"
5035 [(set (match_operand:SI 0 "register_operand" "=r,d")
5036 (plus:SI (match_operand:SI 1 "arith_operand" "%r,d")
5037 (match_operand:SI 2 "arith_add_operand" "rI,d")))]
5041 if (arith_4096_operand(operands[2], SImode))
5043 if (GET_CODE (operands[1]) == CONST_INT)
5044 emit_insn (gen_movsi (operands[0],
5045 GEN_INT (INTVAL (operands[1]) + 4096)));
5047 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
5048 gen_rtx_MINUS (SImode, operands[1],
5054 (define_insn "*addsi3"
5055 [(set (match_operand:SI 0 "register_operand" "=r,d")
5056 (plus:SI (match_operand:SI 1 "arith_operand" "%r,d")
5057 (match_operand:SI 2 "arith_operand" "rI,d")))]
5061 fpadd32s\\t%1, %2, %0"
5062 [(set_attr "type" "*,fp")])
5064 (define_insn "*cmp_cc_plus"
5065 [(set (reg:CC_NOOV 100)
5066 (compare:CC_NOOV (plus:SI (match_operand:SI 0 "arith_operand" "%r")
5067 (match_operand:SI 1 "arith_operand" "rI"))
5070 "addcc\\t%0, %1, %%g0"
5071 [(set_attr "type" "compare")])
5073 (define_insn "*cmp_ccx_plus"
5074 [(set (reg:CCX_NOOV 100)
5075 (compare:CCX_NOOV (plus:DI (match_operand:DI 0 "arith_double_operand" "%r")
5076 (match_operand:DI 1 "arith_double_operand" "rHI"))
5079 "addcc\\t%0, %1, %%g0"
5080 [(set_attr "type" "compare")])
5082 (define_insn "*cmp_cc_plus_set"
5083 [(set (reg:CC_NOOV 100)
5084 (compare:CC_NOOV (plus:SI (match_operand:SI 1 "arith_operand" "%r")
5085 (match_operand:SI 2 "arith_operand" "rI"))
5087 (set (match_operand:SI 0 "register_operand" "=r")
5088 (plus:SI (match_dup 1) (match_dup 2)))]
5090 "addcc\\t%1, %2, %0"
5091 [(set_attr "type" "compare")])
5093 (define_insn "*cmp_ccx_plus_set"
5094 [(set (reg:CCX_NOOV 100)
5095 (compare:CCX_NOOV (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
5096 (match_operand:DI 2 "arith_double_operand" "rHI"))
5098 (set (match_operand:DI 0 "register_operand" "=r")
5099 (plus:DI (match_dup 1) (match_dup 2)))]
5101 "addcc\\t%1, %2, %0"
5102 [(set_attr "type" "compare")])
5104 (define_expand "subdi3"
5105 [(set (match_operand:DI 0 "register_operand" "=r")
5106 (minus:DI (match_operand:DI 1 "register_operand" "r")
5107 (match_operand:DI 2 "arith_double_add_operand" "rHI")))]
5111 if (! TARGET_ARCH64)
5113 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
5114 gen_rtx_SET (VOIDmode, operands[0],
5115 gen_rtx_MINUS (DImode, operands[1],
5117 gen_rtx_CLOBBER (VOIDmode,
5118 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
5121 if (arith_double_4096_operand(operands[2], DImode))
5123 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
5124 gen_rtx_PLUS (DImode, operands[1],
5130 (define_insn_and_split "*subdi3_sp32"
5131 [(set (match_operand:DI 0 "register_operand" "=r")
5132 (minus:DI (match_operand:DI 1 "register_operand" "r")
5133 (match_operand:DI 2 "arith_double_operand" "rHI")))
5134 (clobber (reg:CC 100))]
5137 "&& reload_completed
5138 && (GET_CODE (operands[2]) == CONST_INT
5139 || GET_CODE (operands[2]) == CONST_DOUBLE)"
5140 [(clobber (const_int 0))]
5145 highp = gen_highpart_mode (SImode, DImode, operands[2]);
5146 lowp = gen_lowpart (SImode, operands[2]);
5147 if ((lowp == const0_rtx)
5148 && (operands[0] == operands[1]))
5150 emit_insn (gen_rtx_SET (VOIDmode,
5151 gen_highpart (SImode, operands[0]),
5152 gen_rtx_MINUS (SImode,
5153 gen_highpart_mode (SImode, DImode,
5159 emit_insn (gen_cmp_minus_cc_set (gen_lowpart (SImode, operands[0]),
5160 gen_lowpart (SImode, operands[1]),
5162 emit_insn (gen_subx (gen_highpart (SImode, operands[0]),
5163 gen_highpart_mode (SImode, DImode, operands[1]),
5168 [(set_attr "length" "2")])
5171 [(set (match_operand:DI 0 "register_operand" "")
5172 (minus:DI (match_operand:DI 1 "register_operand" "")
5173 (match_operand:DI 2 "register_operand" "")))
5174 (clobber (reg:CC 100))]
5176 && reload_completed"
5177 [(clobber (const_int 0))]
5180 emit_insn (gen_cmp_minus_cc_set (gen_lowpart (SImode, operands[0]),
5181 gen_lowpart (SImode, operands[1]),
5182 gen_lowpart (SImode, operands[2])));
5183 emit_insn (gen_subx (gen_highpart (SImode, operands[0]),
5184 gen_highpart (SImode, operands[1]),
5185 gen_highpart (SImode, operands[2])));
5189 (define_insn_and_split ""
5190 [(set (match_operand:DI 0 "register_operand" "=r")
5191 (minus:DI (match_operand:DI 1 "register_operand" "r")
5192 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))
5193 (clobber (reg:CC 100))]
5196 "&& reload_completed"
5197 [(parallel [(set (reg:CC_NOOV 100)
5198 (compare:CC_NOOV (minus:SI (match_dup 3) (match_dup 2))
5200 (set (match_dup 5) (minus:SI (match_dup 3) (match_dup 2)))])
5202 (minus:SI (minus:SI (match_dup 4) (const_int 0))
5203 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5204 "operands[3] = gen_lowpart (SImode, operands[1]);
5205 operands[4] = gen_highpart (SImode, operands[1]);
5206 operands[5] = gen_lowpart (SImode, operands[0]);
5207 operands[6] = gen_highpart (SImode, operands[0]);"
5208 [(set_attr "length" "2")])
5210 (define_insn "*subdi3_sp64"
5211 [(set (match_operand:DI 0 "register_operand" "=r")
5212 (minus:DI (match_operand:DI 1 "register_operand" "r")
5213 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5217 (define_expand "subsi3"
5218 [(set (match_operand:SI 0 "register_operand" "=r,d")
5219 (minus:SI (match_operand:SI 1 "register_operand" "r,d")
5220 (match_operand:SI 2 "arith_add_operand" "rI,d")))]
5224 if (arith_4096_operand(operands[2], SImode))
5226 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
5227 gen_rtx_PLUS (SImode, operands[1],
5233 (define_insn "*subsi3"
5234 [(set (match_operand:SI 0 "register_operand" "=r,d")
5235 (minus:SI (match_operand:SI 1 "register_operand" "r,d")
5236 (match_operand:SI 2 "arith_operand" "rI,d")))]
5240 fpsub32s\\t%1, %2, %0"
5241 [(set_attr "type" "*,fp")])
5243 (define_insn "*cmp_minus_cc"
5244 [(set (reg:CC_NOOV 100)
5245 (compare:CC_NOOV (minus:SI (match_operand:SI 0 "reg_or_0_operand" "rJ")
5246 (match_operand:SI 1 "arith_operand" "rI"))
5249 "subcc\\t%r0, %1, %%g0"
5250 [(set_attr "type" "compare")])
5252 (define_insn "*cmp_minus_ccx"
5253 [(set (reg:CCX_NOOV 100)
5254 (compare:CCX_NOOV (minus:DI (match_operand:DI 0 "register_operand" "r")
5255 (match_operand:DI 1 "arith_double_operand" "rHI"))
5258 "subcc\\t%0, %1, %%g0"
5259 [(set_attr "type" "compare")])
5261 (define_insn "cmp_minus_cc_set"
5262 [(set (reg:CC_NOOV 100)
5263 (compare:CC_NOOV (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5264 (match_operand:SI 2 "arith_operand" "rI"))
5266 (set (match_operand:SI 0 "register_operand" "=r")
5267 (minus:SI (match_dup 1) (match_dup 2)))]
5269 "subcc\\t%r1, %2, %0"
5270 [(set_attr "type" "compare")])
5272 (define_insn "*cmp_minus_ccx_set"
5273 [(set (reg:CCX_NOOV 100)
5274 (compare:CCX_NOOV (minus:DI (match_operand:DI 1 "register_operand" "r")
5275 (match_operand:DI 2 "arith_double_operand" "rHI"))
5277 (set (match_operand:DI 0 "register_operand" "=r")
5278 (minus:DI (match_dup 1) (match_dup 2)))]
5280 "subcc\\t%1, %2, %0"
5281 [(set_attr "type" "compare")])
5283 ;; Integer Multiply/Divide.
5285 ;; The 32 bit multiply/divide instructions are deprecated on v9, but at
5286 ;; least in UltraSPARC I, II and IIi it is a win tick-wise.
5288 (define_insn "mulsi3"
5289 [(set (match_operand:SI 0 "register_operand" "=r")
5290 (mult:SI (match_operand:SI 1 "arith_operand" "%r")
5291 (match_operand:SI 2 "arith_operand" "rI")))]
5294 [(set_attr "type" "imul")])
5296 (define_expand "muldi3"
5297 [(set (match_operand:DI 0 "register_operand" "=r")
5298 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r")
5299 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5300 "TARGET_ARCH64 || TARGET_V8PLUS"
5305 emit_insn (gen_muldi3_v8plus (operands[0], operands[1], operands[2]));
5310 (define_insn "*muldi3_sp64"
5311 [(set (match_operand:DI 0 "register_operand" "=r")
5312 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r")
5313 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5316 [(set_attr "type" "imul")])
5318 ;; V8plus wide multiply.
5320 (define_insn "muldi3_v8plus"
5321 [(set (match_operand:DI 0 "register_operand" "=r,h")
5322 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r,0")
5323 (match_operand:DI 2 "arith_double_operand" "rI,rI")))
5324 (clobber (match_scratch:SI 3 "=&h,X"))
5325 (clobber (match_scratch:SI 4 "=&h,X"))]
5329 if (sparc_check_64 (operands[1], insn) <= 0)
5330 output_asm_insn (\"srl\\t%L1, 0, %L1\", operands);
5331 if (which_alternative == 1)
5332 output_asm_insn (\"sllx\\t%H1, 32, %H1\", operands);
5333 if (GET_CODE (operands[2]) == CONST_INT)
5335 if (which_alternative == 1)
5336 return \"or\\t%L1, %H1, %H1\\n\\tmulx\\t%H1, %2, %L0\;srlx\\t%L0, 32, %H0\";
5338 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\";
5340 else if (rtx_equal_p (operands[1], operands[2]))
5342 if (which_alternative == 1)
5343 return \"or\\t%L1, %H1, %H1\\n\\tmulx\\t%H1, %H1, %L0\;srlx\\t%L0, 32, %H0\";
5345 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\";
5347 if (sparc_check_64 (operands[2], insn) <= 0)
5348 output_asm_insn (\"srl\\t%L2, 0, %L2\", operands);
5349 if (which_alternative == 1)
5350 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\";
5352 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\";
5354 [(set_attr "type" "multi")
5355 (set_attr "length" "9,8")])
5357 (define_insn "*cmp_mul_set"
5359 (compare:CC (mult:SI (match_operand:SI 1 "arith_operand" "%r")
5360 (match_operand:SI 2 "arith_operand" "rI"))
5362 (set (match_operand:SI 0 "register_operand" "=r")
5363 (mult:SI (match_dup 1) (match_dup 2)))]
5364 "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS"
5365 "smulcc\\t%1, %2, %0"
5366 [(set_attr "type" "imul")])
5368 (define_expand "mulsidi3"
5369 [(set (match_operand:DI 0 "register_operand" "")
5370 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
5371 (sign_extend:DI (match_operand:SI 2 "arith_operand" ""))))]
5375 if (CONSTANT_P (operands[2]))
5378 emit_insn (gen_const_mulsidi3_v8plus (operands[0], operands[1],
5381 emit_insn (gen_const_mulsidi3_sp32 (operands[0], operands[1],
5387 emit_insn (gen_mulsidi3_v8plus (operands[0], operands[1], operands[2]));
5392 ;; V9 puts the 64 bit product in a 64 bit register. Only out or global
5393 ;; registers can hold 64 bit values in the V8plus environment.
5395 (define_insn "mulsidi3_v8plus"
5396 [(set (match_operand:DI 0 "register_operand" "=h,r")
5397 (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 (clobber (match_scratch:SI 3 "=X,&h"))]
5402 smul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
5403 smul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
5404 [(set_attr "type" "multi")
5405 (set_attr "length" "2,3")])
5408 (define_insn "const_mulsidi3_v8plus"
5409 [(set (match_operand:DI 0 "register_operand" "=h,r")
5410 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5411 (match_operand:SI 2 "small_int" "I,I")))
5412 (clobber (match_scratch:SI 3 "=X,&h"))]
5415 smul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
5416 smul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
5417 [(set_attr "type" "multi")
5418 (set_attr "length" "2,3")])
5421 (define_insn "*mulsidi3_sp32"
5422 [(set (match_operand:DI 0 "register_operand" "=r")
5423 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5424 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
5428 return TARGET_SPARCLET ? \"smuld\\t%1, %2, %L0\" : \"smul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
5431 (if_then_else (eq_attr "isa" "sparclet")
5432 (const_string "imul") (const_string "multi")))
5433 (set (attr "length")
5434 (if_then_else (eq_attr "isa" "sparclet")
5435 (const_int 1) (const_int 2)))])
5437 (define_insn "*mulsidi3_sp64"
5438 [(set (match_operand:DI 0 "register_operand" "=r")
5439 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5440 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
5441 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5443 [(set_attr "type" "imul")])
5445 ;; Extra pattern, because sign_extend of a constant isn't valid.
5448 (define_insn "const_mulsidi3_sp32"
5449 [(set (match_operand:DI 0 "register_operand" "=r")
5450 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5451 (match_operand:SI 2 "small_int" "I")))]
5455 return TARGET_SPARCLET ? \"smuld\\t%1, %2, %L0\" : \"smul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
5458 (if_then_else (eq_attr "isa" "sparclet")
5459 (const_string "imul") (const_string "multi")))
5460 (set (attr "length")
5461 (if_then_else (eq_attr "isa" "sparclet")
5462 (const_int 1) (const_int 2)))])
5464 (define_insn "const_mulsidi3_sp64"
5465 [(set (match_operand:DI 0 "register_operand" "=r")
5466 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5467 (match_operand:SI 2 "small_int" "I")))]
5468 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5470 [(set_attr "type" "imul")])
5472 (define_expand "smulsi3_highpart"
5473 [(set (match_operand:SI 0 "register_operand" "")
5475 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
5476 (sign_extend:DI (match_operand:SI 2 "arith_operand" "")))
5478 "TARGET_HARD_MUL && TARGET_ARCH32"
5481 if (CONSTANT_P (operands[2]))
5485 emit_insn (gen_const_smulsi3_highpart_v8plus (operands[0],
5491 emit_insn (gen_const_smulsi3_highpart (operands[0], operands[1], operands[2]));
5496 emit_insn (gen_smulsi3_highpart_v8plus (operands[0], operands[1],
5497 operands[2], GEN_INT (32)));
5503 (define_insn "smulsi3_highpart_v8plus"
5504 [(set (match_operand:SI 0 "register_operand" "=h,r")
5506 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5507 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
5508 (match_operand:SI 3 "const_int_operand" "i,i"))))
5509 (clobber (match_scratch:SI 4 "=X,&h"))]
5512 smul\\t%1, %2, %0\;srlx\\t%0, %3, %0
5513 smul\\t%1, %2, %4\;srlx\\t%4, %3, %0"
5514 [(set_attr "type" "multi")
5515 (set_attr "length" "2")])
5517 ;; The combiner changes TRUNCATE in the previous pattern to SUBREG.
5520 [(set (match_operand:SI 0 "register_operand" "=h,r")
5523 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5524 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
5525 (match_operand:SI 3 "const_int_operand" "i,i"))
5527 (clobber (match_scratch:SI 4 "=X,&h"))]
5530 smul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
5531 smul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
5532 [(set_attr "type" "multi")
5533 (set_attr "length" "2")])
5536 (define_insn "const_smulsi3_highpart_v8plus"
5537 [(set (match_operand:SI 0 "register_operand" "=h,r")
5539 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5540 (match_operand 2 "small_int" "i,i"))
5541 (match_operand:SI 3 "const_int_operand" "i,i"))))
5542 (clobber (match_scratch:SI 4 "=X,&h"))]
5545 smul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
5546 smul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
5547 [(set_attr "type" "multi")
5548 (set_attr "length" "2")])
5551 (define_insn "*smulsi3_highpart_sp32"
5552 [(set (match_operand:SI 0 "register_operand" "=r")
5554 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5555 (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
5558 "smul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
5559 [(set_attr "type" "multi")
5560 (set_attr "length" "2")])
5563 (define_insn "const_smulsi3_highpart"
5564 [(set (match_operand:SI 0 "register_operand" "=r")
5566 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5567 (match_operand:SI 2 "register_operand" "r"))
5570 "smul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
5571 [(set_attr "type" "multi")
5572 (set_attr "length" "2")])
5574 (define_expand "umulsidi3"
5575 [(set (match_operand:DI 0 "register_operand" "")
5576 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
5577 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" ""))))]
5581 if (CONSTANT_P (operands[2]))
5584 emit_insn (gen_const_umulsidi3_v8plus (operands[0], operands[1],
5587 emit_insn (gen_const_umulsidi3_sp32 (operands[0], operands[1],
5593 emit_insn (gen_umulsidi3_v8plus (operands[0], operands[1], operands[2]));
5599 (define_insn "umulsidi3_v8plus"
5600 [(set (match_operand:DI 0 "register_operand" "=h,r")
5601 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5602 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
5603 (clobber (match_scratch:SI 3 "=X,&h"))]
5606 umul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
5607 umul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
5608 [(set_attr "type" "multi")
5609 (set_attr "length" "2,3")])
5612 (define_insn "*umulsidi3_sp32"
5613 [(set (match_operand:DI 0 "register_operand" "=r")
5614 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5615 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
5619 return TARGET_SPARCLET ? \"umuld\\t%1, %2, %L0\" : \"umul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
5622 (if_then_else (eq_attr "isa" "sparclet")
5623 (const_string "imul") (const_string "multi")))
5624 (set (attr "length")
5625 (if_then_else (eq_attr "isa" "sparclet")
5626 (const_int 1) (const_int 2)))])
5628 (define_insn "*umulsidi3_sp64"
5629 [(set (match_operand:DI 0 "register_operand" "=r")
5630 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5631 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
5632 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5634 [(set_attr "type" "imul")])
5636 ;; Extra pattern, because sign_extend of a constant isn't valid.
5639 (define_insn "const_umulsidi3_sp32"
5640 [(set (match_operand:DI 0 "register_operand" "=r")
5641 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5642 (match_operand:SI 2 "uns_small_int" "")))]
5646 return TARGET_SPARCLET ? \"umuld\\t%1, %2, %L0\" : \"umul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
5649 (if_then_else (eq_attr "isa" "sparclet")
5650 (const_string "imul") (const_string "multi")))
5651 (set (attr "length")
5652 (if_then_else (eq_attr "isa" "sparclet")
5653 (const_int 1) (const_int 2)))])
5655 (define_insn "const_umulsidi3_sp64"
5656 [(set (match_operand:DI 0 "register_operand" "=r")
5657 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5658 (match_operand:SI 2 "uns_small_int" "")))]
5659 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5661 [(set_attr "type" "imul")])
5664 (define_insn "const_umulsidi3_v8plus"
5665 [(set (match_operand:DI 0 "register_operand" "=h,r")
5666 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5667 (match_operand:SI 2 "uns_small_int" "")))
5668 (clobber (match_scratch:SI 3 "=X,h"))]
5671 umul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
5672 umul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
5673 [(set_attr "type" "multi")
5674 (set_attr "length" "2,3")])
5676 (define_expand "umulsi3_highpart"
5677 [(set (match_operand:SI 0 "register_operand" "")
5679 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
5680 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" "")))
5682 "TARGET_HARD_MUL && TARGET_ARCH32"
5685 if (CONSTANT_P (operands[2]))
5689 emit_insn (gen_const_umulsi3_highpart_v8plus (operands[0],
5695 emit_insn (gen_const_umulsi3_highpart (operands[0], operands[1], operands[2]));
5700 emit_insn (gen_umulsi3_highpart_v8plus (operands[0], operands[1],
5701 operands[2], GEN_INT (32)));
5707 (define_insn "umulsi3_highpart_v8plus"
5708 [(set (match_operand:SI 0 "register_operand" "=h,r")
5710 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5711 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
5712 (match_operand:SI 3 "const_int_operand" "i,i"))))
5713 (clobber (match_scratch:SI 4 "=X,h"))]
5716 umul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
5717 umul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
5718 [(set_attr "type" "multi")
5719 (set_attr "length" "2")])
5722 (define_insn "const_umulsi3_highpart_v8plus"
5723 [(set (match_operand:SI 0 "register_operand" "=h,r")
5725 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5726 (match_operand:SI 2 "uns_small_int" ""))
5727 (match_operand:SI 3 "const_int_operand" "i,i"))))
5728 (clobber (match_scratch:SI 4 "=X,h"))]
5731 umul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
5732 umul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
5733 [(set_attr "type" "multi")
5734 (set_attr "length" "2")])
5737 (define_insn "*umulsi3_highpart_sp32"
5738 [(set (match_operand:SI 0 "register_operand" "=r")
5740 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5741 (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
5744 "umul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
5745 [(set_attr "type" "multi")
5746 (set_attr "length" "2")])
5749 (define_insn "const_umulsi3_highpart"
5750 [(set (match_operand:SI 0 "register_operand" "=r")
5752 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5753 (match_operand:SI 2 "uns_small_int" ""))
5756 "umul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
5757 [(set_attr "type" "multi")
5758 (set_attr "length" "2")])
5760 ;; The v8 architecture specifies that there must be 3 instructions between
5761 ;; a y register write and a use of it for correct results.
5763 (define_expand "divsi3"
5764 [(parallel [(set (match_operand:SI 0 "register_operand" "=r,r")
5765 (div:SI (match_operand:SI 1 "register_operand" "r,r")
5766 (match_operand:SI 2 "input_operand" "rI,m")))
5767 (clobber (match_scratch:SI 3 "=&r,&r"))])]
5768 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
5773 operands[3] = gen_reg_rtx(SImode);
5774 emit_insn (gen_ashrsi3 (operands[3], operands[1], GEN_INT (31)));
5775 emit_insn (gen_divsi3_sp64 (operands[0], operands[1], operands[2],
5781 (define_insn "divsi3_sp32"
5782 [(set (match_operand:SI 0 "register_operand" "=r,r")
5783 (div:SI (match_operand:SI 1 "register_operand" "r,r")
5784 (match_operand:SI 2 "input_operand" "rI,m")))
5785 (clobber (match_scratch:SI 3 "=&r,&r"))]
5786 "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS)
5790 if (which_alternative == 0)
5792 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tsdiv\\t%1, %2, %0\";
5794 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tnop\\n\\tnop\\n\\tnop\\n\\tsdiv\\t%1, %2, %0\";
5797 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tld\\t%2, %3\\n\\tsdiv\\t%1, %3, %0\";
5799 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\";
5801 [(set_attr "type" "multi")
5802 (set (attr "length")
5803 (if_then_else (eq_attr "isa" "v9")
5804 (const_int 4) (const_int 6)))])
5806 (define_insn "divsi3_sp64"
5807 [(set (match_operand:SI 0 "register_operand" "=r")
5808 (div:SI (match_operand:SI 1 "register_operand" "r")
5809 (match_operand:SI 2 "input_operand" "rI")))
5810 (use (match_operand:SI 3 "register_operand" "r"))]
5811 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5812 "wr\\t%%g0, %3, %%y\\n\\tsdiv\\t%1, %2, %0"
5813 [(set_attr "type" "multi")
5814 (set_attr "length" "2")])
5816 (define_insn "divdi3"
5817 [(set (match_operand:DI 0 "register_operand" "=r")
5818 (div:DI (match_operand:DI 1 "register_operand" "r")
5819 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5821 "sdivx\\t%1, %2, %0"
5822 [(set_attr "type" "idiv")])
5824 (define_insn "*cmp_sdiv_cc_set"
5826 (compare:CC (div:SI (match_operand:SI 1 "register_operand" "r")
5827 (match_operand:SI 2 "arith_operand" "rI"))
5829 (set (match_operand:SI 0 "register_operand" "=r")
5830 (div:SI (match_dup 1) (match_dup 2)))
5831 (clobber (match_scratch:SI 3 "=&r"))]
5832 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
5836 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tsdivcc\\t%1, %2, %0\";
5838 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tnop\\n\\tnop\\n\\tnop\\n\\tsdivcc\\t%1, %2, %0\";
5840 [(set_attr "type" "multi")
5841 (set (attr "length")
5842 (if_then_else (eq_attr "isa" "v9")
5843 (const_int 3) (const_int 6)))])
5846 (define_expand "udivsi3"
5847 [(set (match_operand:SI 0 "register_operand" "")
5848 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "")
5849 (match_operand:SI 2 "input_operand" "")))]
5850 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
5853 (define_insn "udivsi3_sp32"
5854 [(set (match_operand:SI 0 "register_operand" "=r,&r,&r")
5855 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "r,r,m")
5856 (match_operand:SI 2 "input_operand" "rI,m,r")))]
5858 || TARGET_DEPRECATED_V8_INSNS)
5862 output_asm_insn (\"wr\\t%%g0, %%g0, %%y\", operands);
5863 switch (which_alternative)
5866 return \"nop\\n\\tnop\\n\\tnop\\n\\tudiv\\t%1, %2, %0\";
5868 return \"ld\\t%2, %0\\n\\tnop\\n\\tnop\\n\\tudiv\\t%1, %0, %0\";
5870 return \"ld\\t%1, %0\\n\\tnop\\n\\tnop\\n\\tudiv\\t%0, %2, %0\";
5873 [(set_attr "type" "multi")
5874 (set_attr "length" "5")])
5876 (define_insn "udivsi3_sp64"
5877 [(set (match_operand:SI 0 "register_operand" "=r")
5878 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "r")
5879 (match_operand:SI 2 "input_operand" "rI")))]
5880 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5881 "wr\\t%%g0, 0, %%y\\n\\tudiv\\t%1, %2, %0"
5882 [(set_attr "type" "multi")
5883 (set_attr "length" "2")])
5885 (define_insn "udivdi3"
5886 [(set (match_operand:DI 0 "register_operand" "=r")
5887 (udiv:DI (match_operand:DI 1 "register_operand" "r")
5888 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5890 "udivx\\t%1, %2, %0"
5891 [(set_attr "type" "idiv")])
5893 (define_insn "*cmp_udiv_cc_set"
5895 (compare:CC (udiv:SI (match_operand:SI 1 "register_operand" "r")
5896 (match_operand:SI 2 "arith_operand" "rI"))
5898 (set (match_operand:SI 0 "register_operand" "=r")
5899 (udiv:SI (match_dup 1) (match_dup 2)))]
5901 || TARGET_DEPRECATED_V8_INSNS"
5905 return \"wr\\t%%g0, %%g0, %%y\\n\\tudivcc\\t%1, %2, %0\";
5907 return \"wr\\t%%g0, %%g0, %%y\\n\\tnop\\n\\tnop\\n\\tnop\\n\\tudivcc\\t%1, %2, %0\";
5909 [(set_attr "type" "multi")
5910 (set (attr "length")
5911 (if_then_else (eq_attr "isa" "v9")
5912 (const_int 2) (const_int 5)))])
5914 ; sparclet multiply/accumulate insns
5916 (define_insn "*smacsi"
5917 [(set (match_operand:SI 0 "register_operand" "=r")
5918 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "%r")
5919 (match_operand:SI 2 "arith_operand" "rI"))
5920 (match_operand:SI 3 "register_operand" "0")))]
5923 [(set_attr "type" "imul")])
5925 (define_insn "*smacdi"
5926 [(set (match_operand:DI 0 "register_operand" "=r")
5927 (plus:DI (mult:DI (sign_extend:DI
5928 (match_operand:SI 1 "register_operand" "%r"))
5930 (match_operand:SI 2 "register_operand" "r")))
5931 (match_operand:DI 3 "register_operand" "0")))]
5933 "smacd\\t%1, %2, %L0"
5934 [(set_attr "type" "imul")])
5936 (define_insn "*umacdi"
5937 [(set (match_operand:DI 0 "register_operand" "=r")
5938 (plus:DI (mult:DI (zero_extend:DI
5939 (match_operand:SI 1 "register_operand" "%r"))
5941 (match_operand:SI 2 "register_operand" "r")))
5942 (match_operand:DI 3 "register_operand" "0")))]
5944 "umacd\\t%1, %2, %L0"
5945 [(set_attr "type" "imul")])
5947 ;;- Boolean instructions
5948 ;; We define DImode `and' so with DImode `not' we can get
5949 ;; DImode `andn'. Other combinations are possible.
5951 (define_expand "anddi3"
5952 [(set (match_operand:DI 0 "register_operand" "")
5953 (and:DI (match_operand:DI 1 "arith_double_operand" "")
5954 (match_operand:DI 2 "arith_double_operand" "")))]
5958 (define_insn "*anddi3_sp32"
5959 [(set (match_operand:DI 0 "register_operand" "=r,b")
5960 (and:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
5961 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
5966 [(set_attr "type" "*,fp")
5967 (set_attr "length" "2,*")
5968 (set_attr "fptype" "double")])
5970 (define_insn "*anddi3_sp64"
5971 [(set (match_operand:DI 0 "register_operand" "=r,b")
5972 (and:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
5973 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
5978 [(set_attr "type" "*,fp")
5979 (set_attr "fptype" "double")])
5981 (define_insn "andsi3"
5982 [(set (match_operand:SI 0 "register_operand" "=r,d")
5983 (and:SI (match_operand:SI 1 "arith_operand" "%r,d")
5984 (match_operand:SI 2 "arith_operand" "rI,d")))]
5989 [(set_attr "type" "*,fp")])
5992 [(set (match_operand:SI 0 "register_operand" "")
5993 (and:SI (match_operand:SI 1 "register_operand" "")
5994 (match_operand:SI 2 "" "")))
5995 (clobber (match_operand:SI 3 "register_operand" ""))]
5996 "GET_CODE (operands[2]) == CONST_INT
5997 && !SMALL_INT32 (operands[2])
5998 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
5999 [(set (match_dup 3) (match_dup 4))
6000 (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 1)))]
6003 operands[4] = GEN_INT (~INTVAL (operands[2]));
6006 ;; Split DImode logical operations requiring two instructions.
6008 [(set (match_operand:DI 0 "register_operand" "")
6009 (match_operator:DI 1 "cc_arithop" ; AND, IOR, XOR
6010 [(match_operand:DI 2 "register_operand" "")
6011 (match_operand:DI 3 "arith_double_operand" "")]))]
6014 && ((GET_CODE (operands[0]) == REG
6015 && REGNO (operands[0]) < 32)
6016 || (GET_CODE (operands[0]) == SUBREG
6017 && GET_CODE (SUBREG_REG (operands[0])) == REG
6018 && REGNO (SUBREG_REG (operands[0])) < 32))"
6019 [(set (match_dup 4) (match_op_dup:SI 1 [(match_dup 6) (match_dup 8)]))
6020 (set (match_dup 5) (match_op_dup:SI 1 [(match_dup 7) (match_dup 9)]))]
6023 operands[4] = gen_highpart (SImode, operands[0]);
6024 operands[5] = gen_lowpart (SImode, operands[0]);
6025 operands[6] = gen_highpart (SImode, operands[2]);
6026 operands[7] = gen_lowpart (SImode, operands[2]);
6027 #if HOST_BITS_PER_WIDE_INT == 32
6028 if (GET_CODE (operands[3]) == CONST_INT)
6030 if (INTVAL (operands[3]) < 0)
6031 operands[8] = constm1_rtx;
6033 operands[8] = const0_rtx;
6037 operands[8] = gen_highpart_mode (SImode, DImode, operands[3]);
6038 operands[9] = gen_lowpart (SImode, operands[3]);
6041 (define_insn_and_split "*and_not_di_sp32"
6042 [(set (match_operand:DI 0 "register_operand" "=r,b")
6043 (and:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6044 (match_operand:DI 2 "register_operand" "r,b")))]
6048 fandnot1\\t%1, %2, %0"
6049 "&& reload_completed
6050 && ((GET_CODE (operands[0]) == REG
6051 && REGNO (operands[0]) < 32)
6052 || (GET_CODE (operands[0]) == SUBREG
6053 && GET_CODE (SUBREG_REG (operands[0])) == REG
6054 && REGNO (SUBREG_REG (operands[0])) < 32))"
6055 [(set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))
6056 (set (match_dup 6) (and:SI (not:SI (match_dup 7)) (match_dup 8)))]
6057 "operands[3] = gen_highpart (SImode, operands[0]);
6058 operands[4] = gen_highpart (SImode, operands[1]);
6059 operands[5] = gen_highpart (SImode, operands[2]);
6060 operands[6] = gen_lowpart (SImode, operands[0]);
6061 operands[7] = gen_lowpart (SImode, operands[1]);
6062 operands[8] = gen_lowpart (SImode, operands[2]);"
6063 [(set_attr "type" "*,fp")
6064 (set_attr "length" "2,*")
6065 (set_attr "fptype" "double")])
6067 (define_insn "*and_not_di_sp64"
6068 [(set (match_operand:DI 0 "register_operand" "=r,b")
6069 (and:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6070 (match_operand:DI 2 "register_operand" "r,b")))]
6074 fandnot1\\t%1, %2, %0"
6075 [(set_attr "type" "*,fp")
6076 (set_attr "fptype" "double")])
6078 (define_insn "*and_not_si"
6079 [(set (match_operand:SI 0 "register_operand" "=r,d")
6080 (and:SI (not:SI (match_operand:SI 1 "register_operand" "r,d"))
6081 (match_operand:SI 2 "register_operand" "r,d")))]
6085 fandnot1s\\t%1, %2, %0"
6086 [(set_attr "type" "*,fp")])
6088 (define_expand "iordi3"
6089 [(set (match_operand:DI 0 "register_operand" "")
6090 (ior:DI (match_operand:DI 1 "arith_double_operand" "")
6091 (match_operand:DI 2 "arith_double_operand" "")))]
6095 (define_insn "*iordi3_sp32"
6096 [(set (match_operand:DI 0 "register_operand" "=r,b")
6097 (ior:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6098 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6103 [(set_attr "type" "*,fp")
6104 (set_attr "length" "2,*")
6105 (set_attr "fptype" "double")])
6107 (define_insn "*iordi3_sp64"
6108 [(set (match_operand:DI 0 "register_operand" "=r,b")
6109 (ior:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6110 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6115 [(set_attr "type" "*,fp")
6116 (set_attr "fptype" "double")])
6118 (define_insn "iorsi3"
6119 [(set (match_operand:SI 0 "register_operand" "=r,d")
6120 (ior:SI (match_operand:SI 1 "arith_operand" "%r,d")
6121 (match_operand:SI 2 "arith_operand" "rI,d")))]
6126 [(set_attr "type" "*,fp")])
6129 [(set (match_operand:SI 0 "register_operand" "")
6130 (ior:SI (match_operand:SI 1 "register_operand" "")
6131 (match_operand:SI 2 "" "")))
6132 (clobber (match_operand:SI 3 "register_operand" ""))]
6133 "GET_CODE (operands[2]) == CONST_INT
6134 && !SMALL_INT32 (operands[2])
6135 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6136 [(set (match_dup 3) (match_dup 4))
6137 (set (match_dup 0) (ior:SI (not:SI (match_dup 3)) (match_dup 1)))]
6140 operands[4] = GEN_INT (~INTVAL (operands[2]));
6143 (define_insn_and_split "*or_not_di_sp32"
6144 [(set (match_operand:DI 0 "register_operand" "=r,b")
6145 (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6146 (match_operand:DI 2 "register_operand" "r,b")))]
6150 fornot1\\t%1, %2, %0"
6151 "&& reload_completed
6152 && ((GET_CODE (operands[0]) == REG
6153 && REGNO (operands[0]) < 32)
6154 || (GET_CODE (operands[0]) == SUBREG
6155 && GET_CODE (SUBREG_REG (operands[0])) == REG
6156 && REGNO (SUBREG_REG (operands[0])) < 32))"
6157 [(set (match_dup 3) (ior:SI (not:SI (match_dup 4)) (match_dup 5)))
6158 (set (match_dup 6) (ior:SI (not:SI (match_dup 7)) (match_dup 8)))]
6159 "operands[3] = gen_highpart (SImode, operands[0]);
6160 operands[4] = gen_highpart (SImode, operands[1]);
6161 operands[5] = gen_highpart (SImode, operands[2]);
6162 operands[6] = gen_lowpart (SImode, operands[0]);
6163 operands[7] = gen_lowpart (SImode, operands[1]);
6164 operands[8] = gen_lowpart (SImode, operands[2]);"
6165 [(set_attr "type" "*,fp")
6166 (set_attr "length" "2,*")
6167 (set_attr "fptype" "double")])
6169 (define_insn "*or_not_di_sp64"
6170 [(set (match_operand:DI 0 "register_operand" "=r,b")
6171 (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6172 (match_operand:DI 2 "register_operand" "r,b")))]
6176 fornot1\\t%1, %2, %0"
6177 [(set_attr "type" "*,fp")
6178 (set_attr "fptype" "double")])
6180 (define_insn "*or_not_si"
6181 [(set (match_operand:SI 0 "register_operand" "=r,d")
6182 (ior:SI (not:SI (match_operand:SI 1 "register_operand" "r,d"))
6183 (match_operand:SI 2 "register_operand" "r,d")))]
6187 fornot1s\\t%1, %2, %0"
6188 [(set_attr "type" "*,fp")])
6190 (define_expand "xordi3"
6191 [(set (match_operand:DI 0 "register_operand" "")
6192 (xor:DI (match_operand:DI 1 "arith_double_operand" "")
6193 (match_operand:DI 2 "arith_double_operand" "")))]
6197 (define_insn "*xordi3_sp32"
6198 [(set (match_operand:DI 0 "register_operand" "=r,b")
6199 (xor:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6200 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6205 [(set_attr "type" "*,fp")
6206 (set_attr "length" "2,*")
6207 (set_attr "fptype" "double")])
6209 (define_insn "*xordi3_sp64"
6210 [(set (match_operand:DI 0 "register_operand" "=r,b")
6211 (xor:DI (match_operand:DI 1 "arith_double_operand" "%rJ,b")
6212 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6217 [(set_attr "type" "*,fp")
6218 (set_attr "fptype" "double")])
6220 (define_insn "*xordi3_sp64_dbl"
6221 [(set (match_operand:DI 0 "register_operand" "=r")
6222 (xor:DI (match_operand:DI 1 "register_operand" "r")
6223 (match_operand:DI 2 "const64_operand" "")))]
6225 && HOST_BITS_PER_WIDE_INT != 64)"
6228 (define_insn "xorsi3"
6229 [(set (match_operand:SI 0 "register_operand" "=r,d")
6230 (xor:SI (match_operand:SI 1 "arith_operand" "%rJ,d")
6231 (match_operand:SI 2 "arith_operand" "rI,d")))]
6236 [(set_attr "type" "*,fp")])
6239 [(set (match_operand:SI 0 "register_operand" "")
6240 (xor:SI (match_operand:SI 1 "register_operand" "")
6241 (match_operand:SI 2 "" "")))
6242 (clobber (match_operand:SI 3 "register_operand" ""))]
6243 "GET_CODE (operands[2]) == CONST_INT
6244 && !SMALL_INT32 (operands[2])
6245 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6246 [(set (match_dup 3) (match_dup 4))
6247 (set (match_dup 0) (not:SI (xor:SI (match_dup 3) (match_dup 1))))]
6250 operands[4] = GEN_INT (~INTVAL (operands[2]));
6254 [(set (match_operand:SI 0 "register_operand" "")
6255 (not:SI (xor:SI (match_operand:SI 1 "register_operand" "")
6256 (match_operand:SI 2 "" ""))))
6257 (clobber (match_operand:SI 3 "register_operand" ""))]
6258 "GET_CODE (operands[2]) == CONST_INT
6259 && !SMALL_INT32 (operands[2])
6260 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6261 [(set (match_dup 3) (match_dup 4))
6262 (set (match_dup 0) (xor:SI (match_dup 3) (match_dup 1)))]
6265 operands[4] = GEN_INT (~INTVAL (operands[2]));
6268 ;; xnor patterns. Note that (a ^ ~b) == (~a ^ b) == ~(a ^ b).
6269 ;; Combine now canonicalizes to the rightmost expression.
6270 (define_insn_and_split "*xor_not_di_sp32"
6271 [(set (match_operand:DI 0 "register_operand" "=r,b")
6272 (not:DI (xor:DI (match_operand:DI 1 "register_operand" "r,b")
6273 (match_operand:DI 2 "register_operand" "r,b"))))]
6278 "&& reload_completed
6279 && ((GET_CODE (operands[0]) == REG
6280 && REGNO (operands[0]) < 32)
6281 || (GET_CODE (operands[0]) == SUBREG
6282 && GET_CODE (SUBREG_REG (operands[0])) == REG
6283 && REGNO (SUBREG_REG (operands[0])) < 32))"
6284 [(set (match_dup 3) (not:SI (xor:SI (match_dup 4) (match_dup 5))))
6285 (set (match_dup 6) (not:SI (xor:SI (match_dup 7) (match_dup 8))))]
6286 "operands[3] = gen_highpart (SImode, operands[0]);
6287 operands[4] = gen_highpart (SImode, operands[1]);
6288 operands[5] = gen_highpart (SImode, operands[2]);
6289 operands[6] = gen_lowpart (SImode, operands[0]);
6290 operands[7] = gen_lowpart (SImode, operands[1]);
6291 operands[8] = gen_lowpart (SImode, operands[2]);"
6292 [(set_attr "type" "*,fp")
6293 (set_attr "length" "2,*")
6294 (set_attr "fptype" "double")])
6296 (define_insn "*xor_not_di_sp64"
6297 [(set (match_operand:DI 0 "register_operand" "=r,b")
6298 (not:DI (xor:DI (match_operand:DI 1 "reg_or_0_operand" "rJ,b")
6299 (match_operand:DI 2 "arith_double_operand" "rHI,b"))))]
6304 [(set_attr "type" "*,fp")
6305 (set_attr "fptype" "double")])
6307 (define_insn "*xor_not_si"
6308 [(set (match_operand:SI 0 "register_operand" "=r,d")
6309 (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "rJ,d")
6310 (match_operand:SI 2 "arith_operand" "rI,d"))))]
6314 fxnors\\t%1, %2, %0"
6315 [(set_attr "type" "*,fp")])
6317 ;; These correspond to the above in the case where we also (or only)
6318 ;; want to set the condition code.
6320 (define_insn "*cmp_cc_arith_op"
6323 (match_operator:SI 2 "cc_arithop"
6324 [(match_operand:SI 0 "arith_operand" "%r")
6325 (match_operand:SI 1 "arith_operand" "rI")])
6328 "%A2cc\\t%0, %1, %%g0"
6329 [(set_attr "type" "compare")])
6331 (define_insn "*cmp_ccx_arith_op"
6334 (match_operator:DI 2 "cc_arithop"
6335 [(match_operand:DI 0 "arith_double_operand" "%r")
6336 (match_operand:DI 1 "arith_double_operand" "rHI")])
6339 "%A2cc\\t%0, %1, %%g0"
6340 [(set_attr "type" "compare")])
6342 (define_insn "*cmp_cc_arith_op_set"
6345 (match_operator:SI 3 "cc_arithop"
6346 [(match_operand:SI 1 "arith_operand" "%r")
6347 (match_operand:SI 2 "arith_operand" "rI")])
6349 (set (match_operand:SI 0 "register_operand" "=r")
6350 (match_operator:SI 4 "cc_arithop" [(match_dup 1) (match_dup 2)]))]
6351 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
6352 "%A3cc\\t%1, %2, %0"
6353 [(set_attr "type" "compare")])
6355 (define_insn "*cmp_ccx_arith_op_set"
6358 (match_operator:DI 3 "cc_arithop"
6359 [(match_operand:DI 1 "arith_double_operand" "%r")
6360 (match_operand:DI 2 "arith_double_operand" "rHI")])
6362 (set (match_operand:DI 0 "register_operand" "=r")
6363 (match_operator:DI 4 "cc_arithop" [(match_dup 1) (match_dup 2)]))]
6364 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
6365 "%A3cc\\t%1, %2, %0"
6366 [(set_attr "type" "compare")])
6368 (define_insn "*cmp_cc_xor_not"
6371 (not:SI (xor:SI (match_operand:SI 0 "reg_or_0_operand" "%rJ")
6372 (match_operand:SI 1 "arith_operand" "rI")))
6375 "xnorcc\\t%r0, %1, %%g0"
6376 [(set_attr "type" "compare")])
6378 (define_insn "*cmp_ccx_xor_not"
6381 (not:DI (xor:DI (match_operand:DI 0 "reg_or_0_operand" "%rJ")
6382 (match_operand:DI 1 "arith_double_operand" "rHI")))
6385 "xnorcc\\t%r0, %1, %%g0"
6386 [(set_attr "type" "compare")])
6388 (define_insn "*cmp_cc_xor_not_set"
6391 (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
6392 (match_operand:SI 2 "arith_operand" "rI")))
6394 (set (match_operand:SI 0 "register_operand" "=r")
6395 (not:SI (xor:SI (match_dup 1) (match_dup 2))))]
6397 "xnorcc\\t%r1, %2, %0"
6398 [(set_attr "type" "compare")])
6400 (define_insn "*cmp_ccx_xor_not_set"
6403 (not:DI (xor:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ")
6404 (match_operand:DI 2 "arith_double_operand" "rHI")))
6406 (set (match_operand:DI 0 "register_operand" "=r")
6407 (not:DI (xor:DI (match_dup 1) (match_dup 2))))]
6409 "xnorcc\\t%r1, %2, %0"
6410 [(set_attr "type" "compare")])
6412 (define_insn "*cmp_cc_arith_op_not"
6415 (match_operator:SI 2 "cc_arithopn"
6416 [(not:SI (match_operand:SI 0 "arith_operand" "rI"))
6417 (match_operand:SI 1 "reg_or_0_operand" "rJ")])
6420 "%B2cc\\t%r1, %0, %%g0"
6421 [(set_attr "type" "compare")])
6423 (define_insn "*cmp_ccx_arith_op_not"
6426 (match_operator:DI 2 "cc_arithopn"
6427 [(not:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
6428 (match_operand:DI 1 "reg_or_0_operand" "rJ")])
6431 "%B2cc\\t%r1, %0, %%g0"
6432 [(set_attr "type" "compare")])
6434 (define_insn "*cmp_cc_arith_op_not_set"
6437 (match_operator:SI 3 "cc_arithopn"
6438 [(not:SI (match_operand:SI 1 "arith_operand" "rI"))
6439 (match_operand:SI 2 "reg_or_0_operand" "rJ")])
6441 (set (match_operand:SI 0 "register_operand" "=r")
6442 (match_operator:SI 4 "cc_arithopn"
6443 [(not:SI (match_dup 1)) (match_dup 2)]))]
6444 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
6445 "%B3cc\\t%r2, %1, %0"
6446 [(set_attr "type" "compare")])
6448 (define_insn "*cmp_ccx_arith_op_not_set"
6451 (match_operator:DI 3 "cc_arithopn"
6452 [(not:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
6453 (match_operand:DI 2 "reg_or_0_operand" "rJ")])
6455 (set (match_operand:DI 0 "register_operand" "=r")
6456 (match_operator:DI 4 "cc_arithopn"
6457 [(not:DI (match_dup 1)) (match_dup 2)]))]
6458 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
6459 "%B3cc\\t%r2, %1, %0"
6460 [(set_attr "type" "compare")])
6462 ;; We cannot use the "neg" pseudo insn because the Sun assembler
6463 ;; does not know how to make it work for constants.
6465 (define_expand "negdi2"
6466 [(set (match_operand:DI 0 "register_operand" "=r")
6467 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
6471 if (! TARGET_ARCH64)
6473 emit_insn (gen_rtx_PARALLEL
6476 gen_rtx_SET (VOIDmode, operand0,
6477 gen_rtx_NEG (DImode, operand1)),
6478 gen_rtx_CLOBBER (VOIDmode,
6479 gen_rtx_REG (CCmode,
6485 (define_insn_and_split "*negdi2_sp32"
6486 [(set (match_operand:DI 0 "register_operand" "=r")
6487 (neg:DI (match_operand:DI 1 "register_operand" "r")))
6488 (clobber (reg:CC 100))]
6491 "&& reload_completed"
6492 [(parallel [(set (reg:CC_NOOV 100)
6493 (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 5))
6495 (set (match_dup 4) (minus:SI (const_int 0) (match_dup 5)))])
6496 (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
6497 (ltu:SI (reg:CC 100) (const_int 0))))]
6498 "operands[2] = gen_highpart (SImode, operands[0]);
6499 operands[3] = gen_highpart (SImode, operands[1]);
6500 operands[4] = gen_lowpart (SImode, operands[0]);
6501 operands[5] = gen_lowpart (SImode, operands[1]);"
6502 [(set_attr "length" "2")])
6504 (define_insn "*negdi2_sp64"
6505 [(set (match_operand:DI 0 "register_operand" "=r")
6506 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
6508 "sub\\t%%g0, %1, %0")
6510 (define_insn "negsi2"
6511 [(set (match_operand:SI 0 "register_operand" "=r")
6512 (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
6514 "sub\\t%%g0, %1, %0")
6516 (define_insn "*cmp_cc_neg"
6517 [(set (reg:CC_NOOV 100)
6518 (compare:CC_NOOV (neg:SI (match_operand:SI 0 "arith_operand" "rI"))
6521 "subcc\\t%%g0, %0, %%g0"
6522 [(set_attr "type" "compare")])
6524 (define_insn "*cmp_ccx_neg"
6525 [(set (reg:CCX_NOOV 100)
6526 (compare:CCX_NOOV (neg:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
6529 "subcc\\t%%g0, %0, %%g0"
6530 [(set_attr "type" "compare")])
6532 (define_insn "*cmp_cc_set_neg"
6533 [(set (reg:CC_NOOV 100)
6534 (compare:CC_NOOV (neg:SI (match_operand:SI 1 "arith_operand" "rI"))
6536 (set (match_operand:SI 0 "register_operand" "=r")
6537 (neg:SI (match_dup 1)))]
6539 "subcc\\t%%g0, %1, %0"
6540 [(set_attr "type" "compare")])
6542 (define_insn "*cmp_ccx_set_neg"
6543 [(set (reg:CCX_NOOV 100)
6544 (compare:CCX_NOOV (neg:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
6546 (set (match_operand:DI 0 "register_operand" "=r")
6547 (neg:DI (match_dup 1)))]
6549 "subcc\\t%%g0, %1, %0"
6550 [(set_attr "type" "compare")])
6552 ;; We cannot use the "not" pseudo insn because the Sun assembler
6553 ;; does not know how to make it work for constants.
6554 (define_expand "one_cmpldi2"
6555 [(set (match_operand:DI 0 "register_operand" "")
6556 (not:DI (match_operand:DI 1 "register_operand" "")))]
6560 (define_insn_and_split "*one_cmpldi2_sp32"
6561 [(set (match_operand:DI 0 "register_operand" "=r,b")
6562 (not:DI (match_operand:DI 1 "register_operand" "r,b")))]
6567 "&& reload_completed
6568 && ((GET_CODE (operands[0]) == REG
6569 && REGNO (operands[0]) < 32)
6570 || (GET_CODE (operands[0]) == SUBREG
6571 && GET_CODE (SUBREG_REG (operands[0])) == REG
6572 && REGNO (SUBREG_REG (operands[0])) < 32))"
6573 [(set (match_dup 2) (not:SI (xor:SI (match_dup 3) (const_int 0))))
6574 (set (match_dup 4) (not:SI (xor:SI (match_dup 5) (const_int 0))))]
6575 "operands[2] = gen_highpart (SImode, operands[0]);
6576 operands[3] = gen_highpart (SImode, operands[1]);
6577 operands[4] = gen_lowpart (SImode, operands[0]);
6578 operands[5] = gen_lowpart (SImode, operands[1]);"
6579 [(set_attr "type" "*,fp")
6580 (set_attr "length" "2,*")
6581 (set_attr "fptype" "double")])
6583 (define_insn "*one_cmpldi2_sp64"
6584 [(set (match_operand:DI 0 "register_operand" "=r,b")
6585 (not:DI (match_operand:DI 1 "arith_double_operand" "rHI,b")))]
6590 [(set_attr "type" "*,fp")
6591 (set_attr "fptype" "double")])
6593 (define_insn "one_cmplsi2"
6594 [(set (match_operand:SI 0 "register_operand" "=r,d")
6595 (not:SI (match_operand:SI 1 "arith_operand" "rI,d")))]
6600 [(set_attr "type" "*,fp")])
6602 (define_insn "*cmp_cc_not"
6604 (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI"))
6607 "xnorcc\\t%%g0, %0, %%g0"
6608 [(set_attr "type" "compare")])
6610 (define_insn "*cmp_ccx_not"
6612 (compare:CCX (not:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
6615 "xnorcc\\t%%g0, %0, %%g0"
6616 [(set_attr "type" "compare")])
6618 (define_insn "*cmp_cc_set_not"
6620 (compare:CC (not:SI (match_operand:SI 1 "arith_operand" "rI"))
6622 (set (match_operand:SI 0 "register_operand" "=r")
6623 (not:SI (match_dup 1)))]
6625 "xnorcc\\t%%g0, %1, %0"
6626 [(set_attr "type" "compare")])
6628 (define_insn "*cmp_ccx_set_not"
6630 (compare:CCX (not:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
6632 (set (match_operand:DI 0 "register_operand" "=r")
6633 (not:DI (match_dup 1)))]
6635 "xnorcc\\t%%g0, %1, %0"
6636 [(set_attr "type" "compare")])
6638 (define_insn "*cmp_cc_set"
6639 [(set (match_operand:SI 0 "register_operand" "=r")
6640 (match_operand:SI 1 "register_operand" "r"))
6642 (compare:CC (match_dup 1)
6646 [(set_attr "type" "compare")])
6648 (define_insn "*cmp_ccx_set64"
6649 [(set (match_operand:DI 0 "register_operand" "=r")
6650 (match_operand:DI 1 "register_operand" "r"))
6652 (compare:CCX (match_dup 1)
6656 [(set_attr "type" "compare")])
6658 ;; Floating point arithmetic instructions.
6660 (define_expand "addtf3"
6661 [(set (match_operand:TF 0 "nonimmediate_operand" "")
6662 (plus:TF (match_operand:TF 1 "general_operand" "")
6663 (match_operand:TF 2 "general_operand" "")))]
6664 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6665 "emit_tfmode_binop (PLUS, operands); DONE;")
6667 (define_insn "*addtf3_hq"
6668 [(set (match_operand:TF 0 "register_operand" "=e")
6669 (plus:TF (match_operand:TF 1 "register_operand" "e")
6670 (match_operand:TF 2 "register_operand" "e")))]
6671 "TARGET_FPU && TARGET_HARD_QUAD"
6672 "faddq\\t%1, %2, %0"
6673 [(set_attr "type" "fp")])
6675 (define_insn "adddf3"
6676 [(set (match_operand:DF 0 "register_operand" "=e")
6677 (plus:DF (match_operand:DF 1 "register_operand" "e")
6678 (match_operand:DF 2 "register_operand" "e")))]
6680 "faddd\\t%1, %2, %0"
6681 [(set_attr "type" "fp")
6682 (set_attr "fptype" "double")])
6684 (define_insn "addsf3"
6685 [(set (match_operand:SF 0 "register_operand" "=f")
6686 (plus:SF (match_operand:SF 1 "register_operand" "f")
6687 (match_operand:SF 2 "register_operand" "f")))]
6689 "fadds\\t%1, %2, %0"
6690 [(set_attr "type" "fp")])
6692 (define_expand "subtf3"
6693 [(set (match_operand:TF 0 "nonimmediate_operand" "")
6694 (minus:TF (match_operand:TF 1 "general_operand" "")
6695 (match_operand:TF 2 "general_operand" "")))]
6696 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6697 "emit_tfmode_binop (MINUS, operands); DONE;")
6699 (define_insn "*subtf3_hq"
6700 [(set (match_operand:TF 0 "register_operand" "=e")
6701 (minus:TF (match_operand:TF 1 "register_operand" "e")
6702 (match_operand:TF 2 "register_operand" "e")))]
6703 "TARGET_FPU && TARGET_HARD_QUAD"
6704 "fsubq\\t%1, %2, %0"
6705 [(set_attr "type" "fp")])
6707 (define_insn "subdf3"
6708 [(set (match_operand:DF 0 "register_operand" "=e")
6709 (minus:DF (match_operand:DF 1 "register_operand" "e")
6710 (match_operand:DF 2 "register_operand" "e")))]
6712 "fsubd\\t%1, %2, %0"
6713 [(set_attr "type" "fp")
6714 (set_attr "fptype" "double")])
6716 (define_insn "subsf3"
6717 [(set (match_operand:SF 0 "register_operand" "=f")
6718 (minus:SF (match_operand:SF 1 "register_operand" "f")
6719 (match_operand:SF 2 "register_operand" "f")))]
6721 "fsubs\\t%1, %2, %0"
6722 [(set_attr "type" "fp")])
6724 (define_expand "multf3"
6725 [(set (match_operand:TF 0 "nonimmediate_operand" "")
6726 (mult:TF (match_operand:TF 1 "general_operand" "")
6727 (match_operand:TF 2 "general_operand" "")))]
6728 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6729 "emit_tfmode_binop (MULT, operands); DONE;")
6731 (define_insn "*multf3_hq"
6732 [(set (match_operand:TF 0 "register_operand" "=e")
6733 (mult:TF (match_operand:TF 1 "register_operand" "e")
6734 (match_operand:TF 2 "register_operand" "e")))]
6735 "TARGET_FPU && TARGET_HARD_QUAD"
6736 "fmulq\\t%1, %2, %0"
6737 [(set_attr "type" "fpmul")])
6739 (define_insn "muldf3"
6740 [(set (match_operand:DF 0 "register_operand" "=e")
6741 (mult:DF (match_operand:DF 1 "register_operand" "e")
6742 (match_operand:DF 2 "register_operand" "e")))]
6744 "fmuld\\t%1, %2, %0"
6745 [(set_attr "type" "fpmul")
6746 (set_attr "fptype" "double")])
6748 (define_insn "mulsf3"
6749 [(set (match_operand:SF 0 "register_operand" "=f")
6750 (mult:SF (match_operand:SF 1 "register_operand" "f")
6751 (match_operand:SF 2 "register_operand" "f")))]
6753 "fmuls\\t%1, %2, %0"
6754 [(set_attr "type" "fpmul")])
6756 (define_insn "*muldf3_extend"
6757 [(set (match_operand:DF 0 "register_operand" "=e")
6758 (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "f"))
6759 (float_extend:DF (match_operand:SF 2 "register_operand" "f"))))]
6760 "(TARGET_V8 || TARGET_V9) && TARGET_FPU"
6761 "fsmuld\\t%1, %2, %0"
6762 [(set_attr "type" "fpmul")
6763 (set_attr "fptype" "double")])
6765 (define_insn "*multf3_extend"
6766 [(set (match_operand:TF 0 "register_operand" "=e")
6767 (mult:TF (float_extend:TF (match_operand:DF 1 "register_operand" "e"))
6768 (float_extend:TF (match_operand:DF 2 "register_operand" "e"))))]
6769 "(TARGET_V8 || TARGET_V9) && TARGET_FPU && TARGET_HARD_QUAD"
6770 "fdmulq\\t%1, %2, %0"
6771 [(set_attr "type" "fpmul")])
6773 (define_expand "divtf3"
6774 [(set (match_operand:TF 0 "nonimmediate_operand" "")
6775 (div:TF (match_operand:TF 1 "general_operand" "")
6776 (match_operand:TF 2 "general_operand" "")))]
6777 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6778 "emit_tfmode_binop (DIV, operands); DONE;")
6780 ;; don't have timing for quad-prec. divide.
6781 (define_insn "*divtf3_hq"
6782 [(set (match_operand:TF 0 "register_operand" "=e")
6783 (div:TF (match_operand:TF 1 "register_operand" "e")
6784 (match_operand:TF 2 "register_operand" "e")))]
6785 "TARGET_FPU && TARGET_HARD_QUAD"
6786 "fdivq\\t%1, %2, %0"
6787 [(set_attr "type" "fpdivd")])
6789 (define_insn "divdf3"
6790 [(set (match_operand:DF 0 "register_operand" "=e")
6791 (div:DF (match_operand:DF 1 "register_operand" "e")
6792 (match_operand:DF 2 "register_operand" "e")))]
6794 "fdivd\\t%1, %2, %0"
6795 [(set_attr "type" "fpdivd")
6796 (set_attr "fptype" "double")])
6798 (define_insn "divsf3"
6799 [(set (match_operand:SF 0 "register_operand" "=f")
6800 (div:SF (match_operand:SF 1 "register_operand" "f")
6801 (match_operand:SF 2 "register_operand" "f")))]
6803 "fdivs\\t%1, %2, %0"
6804 [(set_attr "type" "fpdivs")])
6806 (define_expand "negtf2"
6807 [(set (match_operand:TF 0 "register_operand" "=e,e")
6808 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
6812 (define_insn_and_split "*negtf2_notv9"
6813 [(set (match_operand:TF 0 "register_operand" "=e,e")
6814 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
6815 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
6821 "&& reload_completed
6822 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6823 [(set (match_dup 2) (neg:SF (match_dup 3)))
6824 (set (match_dup 4) (match_dup 5))
6825 (set (match_dup 6) (match_dup 7))]
6826 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6827 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6828 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6829 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
6830 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6831 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6832 [(set_attr "type" "fpmove,*")
6833 (set_attr "length" "*,2")])
6835 (define_insn_and_split "*negtf2_v9"
6836 [(set (match_operand:TF 0 "register_operand" "=e,e")
6837 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
6838 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
6839 "TARGET_FPU && TARGET_V9"
6843 "&& reload_completed
6844 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6845 [(set (match_dup 2) (neg:DF (match_dup 3)))
6846 (set (match_dup 4) (match_dup 5))]
6847 "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
6848 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
6849 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6850 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6851 [(set_attr "type" "fpmove,*")
6852 (set_attr "length" "*,2")
6853 (set_attr "fptype" "double")])
6855 (define_expand "negdf2"
6856 [(set (match_operand:DF 0 "register_operand" "")
6857 (neg:DF (match_operand:DF 1 "register_operand" "")))]
6861 (define_insn_and_split "*negdf2_notv9"
6862 [(set (match_operand:DF 0 "register_operand" "=e,e")
6863 (neg:DF (match_operand:DF 1 "register_operand" "0,e")))]
6864 "TARGET_FPU && ! TARGET_V9"
6868 "&& reload_completed
6869 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6870 [(set (match_dup 2) (neg:SF (match_dup 3)))
6871 (set (match_dup 4) (match_dup 5))]
6872 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6873 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6874 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6875 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);"
6876 [(set_attr "type" "fpmove,*")
6877 (set_attr "length" "*,2")])
6879 (define_insn "*negdf2_v9"
6880 [(set (match_operand:DF 0 "register_operand" "=e")
6881 (neg:DF (match_operand:DF 1 "register_operand" "e")))]
6882 "TARGET_FPU && TARGET_V9"
6884 [(set_attr "type" "fpmove")
6885 (set_attr "fptype" "double")])
6887 (define_insn "negsf2"
6888 [(set (match_operand:SF 0 "register_operand" "=f")
6889 (neg:SF (match_operand:SF 1 "register_operand" "f")))]
6892 [(set_attr "type" "fpmove")])
6894 (define_expand "abstf2"
6895 [(set (match_operand:TF 0 "register_operand" "")
6896 (abs:TF (match_operand:TF 1 "register_operand" "")))]
6900 (define_insn_and_split "*abstf2_notv9"
6901 [(set (match_operand:TF 0 "register_operand" "=e,e")
6902 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6903 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
6904 "TARGET_FPU && ! TARGET_V9"
6908 "&& reload_completed
6909 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6910 [(set (match_dup 2) (abs:SF (match_dup 3)))
6911 (set (match_dup 4) (match_dup 5))
6912 (set (match_dup 6) (match_dup 7))]
6913 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6914 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6915 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6916 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
6917 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6918 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6919 [(set_attr "type" "fpmove,*")
6920 (set_attr "length" "*,2")])
6922 (define_insn "*abstf2_hq_v9"
6923 [(set (match_operand:TF 0 "register_operand" "=e,e")
6924 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6925 "TARGET_FPU && TARGET_V9 && TARGET_HARD_QUAD"
6929 [(set_attr "type" "fpmove")
6930 (set_attr "fptype" "double,*")])
6932 (define_insn_and_split "*abstf2_v9"
6933 [(set (match_operand:TF 0 "register_operand" "=e,e")
6934 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6935 "TARGET_FPU && TARGET_V9 && !TARGET_HARD_QUAD"
6939 "&& reload_completed
6940 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6941 [(set (match_dup 2) (abs:DF (match_dup 3)))
6942 (set (match_dup 4) (match_dup 5))]
6943 "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
6944 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
6945 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6946 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6947 [(set_attr "type" "fpmove,*")
6948 (set_attr "length" "*,2")
6949 (set_attr "fptype" "double,*")])
6951 (define_expand "absdf2"
6952 [(set (match_operand:DF 0 "register_operand" "")
6953 (abs:DF (match_operand:DF 1 "register_operand" "")))]
6957 (define_insn_and_split "*absdf2_notv9"
6958 [(set (match_operand:DF 0 "register_operand" "=e,e")
6959 (abs:DF (match_operand:DF 1 "register_operand" "0,e")))]
6960 "TARGET_FPU && ! TARGET_V9"
6964 "&& reload_completed
6965 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6966 [(set (match_dup 2) (abs:SF (match_dup 3)))
6967 (set (match_dup 4) (match_dup 5))]
6968 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6969 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6970 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6971 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);"
6972 [(set_attr "type" "fpmove,*")
6973 (set_attr "length" "*,2")])
6975 (define_insn "*absdf2_v9"
6976 [(set (match_operand:DF 0 "register_operand" "=e")
6977 (abs:DF (match_operand:DF 1 "register_operand" "e")))]
6978 "TARGET_FPU && TARGET_V9"
6980 [(set_attr "type" "fpmove")
6981 (set_attr "fptype" "double")])
6983 (define_insn "abssf2"
6984 [(set (match_operand:SF 0 "register_operand" "=f")
6985 (abs:SF (match_operand:SF 1 "register_operand" "f")))]
6988 [(set_attr "type" "fpmove")])
6990 (define_expand "sqrttf2"
6991 [(set (match_operand:TF 0 "nonimmediate_operand" "")
6992 (sqrt:TF (match_operand:TF 1 "general_operand" "")))]
6993 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6994 "emit_tfmode_unop (SQRT, operands); DONE;")
6996 (define_insn "*sqrttf2_hq"
6997 [(set (match_operand:TF 0 "register_operand" "=e")
6998 (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
6999 "TARGET_FPU && TARGET_HARD_QUAD"
7001 [(set_attr "type" "fpsqrtd")])
7003 (define_insn "sqrtdf2"
7004 [(set (match_operand:DF 0 "register_operand" "=e")
7005 (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
7008 [(set_attr "type" "fpsqrtd")
7009 (set_attr "fptype" "double")])
7011 (define_insn "sqrtsf2"
7012 [(set (match_operand:SF 0 "register_operand" "=f")
7013 (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
7016 [(set_attr "type" "fpsqrts")])
7018 ;;- arithmetic shift instructions
7020 (define_insn "ashlsi3"
7021 [(set (match_operand:SI 0 "register_operand" "=r")
7022 (ashift:SI (match_operand:SI 1 "register_operand" "r")
7023 (match_operand:SI 2 "arith_operand" "rI")))]
7027 if (operands[2] == const1_rtx)
7028 return \"add\\t%1, %1, %0\";
7029 return \"sll\\t%1, %2, %0\";
7032 (if_then_else (match_operand 2 "const1_operand" "")
7033 (const_string "ialu") (const_string "shift")))])
7035 (define_expand "ashldi3"
7036 [(set (match_operand:DI 0 "register_operand" "=r")
7037 (ashift:DI (match_operand:DI 1 "register_operand" "r")
7038 (match_operand:SI 2 "arith_operand" "rI")))]
7039 "TARGET_ARCH64 || TARGET_V8PLUS"
7042 if (! TARGET_ARCH64)
7044 if (GET_CODE (operands[2]) == CONST_INT)
7046 emit_insn (gen_ashldi3_v8plus (operands[0], operands[1], operands[2]));
7051 (define_insn "*ashldi3_sp64"
7052 [(set (match_operand:DI 0 "register_operand" "=r")
7053 (ashift:DI (match_operand:DI 1 "register_operand" "r")
7054 (match_operand:SI 2 "arith_operand" "rI")))]
7058 if (operands[2] == const1_rtx)
7059 return \"add\\t%1, %1, %0\";
7060 return \"sllx\\t%1, %2, %0\";
7063 (if_then_else (match_operand 2 "const1_operand" "")
7064 (const_string "ialu") (const_string "shift")))])
7067 (define_insn "ashldi3_v8plus"
7068 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
7069 (ashift:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
7070 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
7071 (clobber (match_scratch:SI 3 "=X,X,&h"))]
7073 "*return sparc_v8plus_shift (operands, insn, \"sllx\");"
7074 [(set_attr "type" "multi")
7075 (set_attr "length" "5,5,6")])
7077 ;; Optimize (1LL<<x)-1
7078 ;; XXX this also needs to be fixed to handle equal subregs
7079 ;; XXX first before we could re-enable it.
7081 ; [(set (match_operand:DI 0 "register_operand" "=h")
7082 ; (plus:DI (ashift:DI (const_int 1)
7083 ; (match_operand:SI 1 "arith_operand" "rI"))
7085 ; "0 && TARGET_V8PLUS"
7088 ; if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == REGNO (operands[0]))
7089 ; return \"mov\\t1, %L0\;sllx\\t%L0, %1, %L0\;sub\\t%L0, 1, %L0\;srlx\\t%L0, 32, %H0\";
7090 ; return \"mov\\t1, %H0\;sllx\\t%H0, %1, %L0\;sub\\t%L0, 1, %L0\;srlx\\t%L0, 32, %H0\";
7092 ; [(set_attr "type" "multi")
7093 ; (set_attr "length" "4")])
7095 (define_insn "*cmp_cc_ashift_1"
7096 [(set (reg:CC_NOOV 100)
7097 (compare:CC_NOOV (ashift:SI (match_operand:SI 0 "register_operand" "r")
7101 "addcc\\t%0, %0, %%g0"
7102 [(set_attr "type" "compare")])
7104 (define_insn "*cmp_cc_set_ashift_1"
7105 [(set (reg:CC_NOOV 100)
7106 (compare:CC_NOOV (ashift:SI (match_operand:SI 1 "register_operand" "r")
7109 (set (match_operand:SI 0 "register_operand" "=r")
7110 (ashift:SI (match_dup 1) (const_int 1)))]
7112 "addcc\\t%1, %1, %0"
7113 [(set_attr "type" "compare")])
7115 (define_insn "ashrsi3"
7116 [(set (match_operand:SI 0 "register_operand" "=r")
7117 (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
7118 (match_operand:SI 2 "arith_operand" "rI")))]
7122 return \"sra\\t%1, %2, %0\";
7124 [(set_attr "type" "shift")])
7126 (define_insn "*ashrsi3_extend"
7127 [(set (match_operand:DI 0 "register_operand" "=r")
7128 (sign_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
7129 (match_operand:SI 2 "arith_operand" "r"))))]
7132 [(set_attr "type" "shift")])
7134 ;; This handles the case as above, but with constant shift instead of
7135 ;; register. Combiner "simplifies" it for us a little bit though.
7136 (define_insn "*ashrsi3_extend2"
7137 [(set (match_operand:DI 0 "register_operand" "=r")
7138 (ashiftrt:DI (ashift:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
7140 (match_operand:SI 2 "small_int_or_double" "n")))]
7142 && ((GET_CODE (operands[2]) == CONST_INT
7143 && INTVAL (operands[2]) >= 32 && INTVAL (operands[2]) < 64)
7144 || (GET_CODE (operands[2]) == CONST_DOUBLE
7145 && !CONST_DOUBLE_HIGH (operands[2])
7146 && CONST_DOUBLE_LOW (operands[2]) >= 32
7147 && CONST_DOUBLE_LOW (operands[2]) < 64))"
7150 operands[2] = GEN_INT (INTVAL (operands[2]) - 32);
7152 return \"sra\\t%1, %2, %0\";
7154 [(set_attr "type" "shift")])
7156 (define_expand "ashrdi3"
7157 [(set (match_operand:DI 0 "register_operand" "=r")
7158 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
7159 (match_operand:SI 2 "arith_operand" "rI")))]
7160 "TARGET_ARCH64 || TARGET_V8PLUS"
7163 if (! TARGET_ARCH64)
7165 if (GET_CODE (operands[2]) == CONST_INT)
7166 FAIL; /* prefer generic code in this case */
7167 emit_insn (gen_ashrdi3_v8plus (operands[0], operands[1], operands[2]));
7173 [(set (match_operand:DI 0 "register_operand" "=r")
7174 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
7175 (match_operand:SI 2 "arith_operand" "rI")))]
7179 return \"srax\\t%1, %2, %0\";
7181 [(set_attr "type" "shift")])
7184 (define_insn "ashrdi3_v8plus"
7185 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
7186 (ashiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
7187 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
7188 (clobber (match_scratch:SI 3 "=X,X,&h"))]
7190 "*return sparc_v8plus_shift (operands, insn, \"srax\");"
7191 [(set_attr "type" "multi")
7192 (set_attr "length" "5,5,6")])
7194 (define_insn "lshrsi3"
7195 [(set (match_operand:SI 0 "register_operand" "=r")
7196 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
7197 (match_operand:SI 2 "arith_operand" "rI")))]
7201 return \"srl\\t%1, %2, %0\";
7203 [(set_attr "type" "shift")])
7205 ;; This handles the case where
7206 ;; (zero_extend:DI (lshiftrt:SI (match_operand:SI) (match_operand:SI))),
7207 ;; but combiner "simplifies" it for us.
7208 (define_insn "*lshrsi3_extend"
7209 [(set (match_operand:DI 0 "register_operand" "=r")
7210 (and:DI (subreg:DI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
7211 (match_operand:SI 2 "arith_operand" "r")) 0)
7212 (match_operand 3 "" "")))]
7214 && ((GET_CODE (operands[3]) == CONST_DOUBLE
7215 && CONST_DOUBLE_HIGH (operands[3]) == 0
7216 && CONST_DOUBLE_LOW (operands[3]) == 0xffffffff)
7217 || (HOST_BITS_PER_WIDE_INT >= 64
7218 && GET_CODE (operands[3]) == CONST_INT
7219 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) == 0xffffffff))"
7221 [(set_attr "type" "shift")])
7223 ;; This handles the case where
7224 ;; (lshiftrt:DI (zero_extend:DI (match_operand:SI)) (const_int >=0 < 32))
7225 ;; but combiner "simplifies" it for us.
7226 (define_insn "*lshrsi3_extend2"
7227 [(set (match_operand:DI 0 "register_operand" "=r")
7228 (zero_extract:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
7229 (match_operand 2 "small_int_or_double" "n")
7232 && ((GET_CODE (operands[2]) == CONST_INT
7233 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
7234 || (GET_CODE (operands[2]) == CONST_DOUBLE
7235 && CONST_DOUBLE_HIGH (operands[2]) == 0
7236 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
7239 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
7241 return \"srl\\t%1, %2, %0\";
7243 [(set_attr "type" "shift")])
7245 (define_expand "lshrdi3"
7246 [(set (match_operand:DI 0 "register_operand" "=r")
7247 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
7248 (match_operand:SI 2 "arith_operand" "rI")))]
7249 "TARGET_ARCH64 || TARGET_V8PLUS"
7252 if (! TARGET_ARCH64)
7254 if (GET_CODE (operands[2]) == CONST_INT)
7256 emit_insn (gen_lshrdi3_v8plus (operands[0], operands[1], operands[2]));
7262 [(set (match_operand:DI 0 "register_operand" "=r")
7263 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
7264 (match_operand:SI 2 "arith_operand" "rI")))]
7268 return \"srlx\\t%1, %2, %0\";
7270 [(set_attr "type" "shift")])
7273 (define_insn "lshrdi3_v8plus"
7274 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
7275 (lshiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
7276 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
7277 (clobber (match_scratch:SI 3 "=X,X,&h"))]
7279 "*return sparc_v8plus_shift (operands, insn, \"srlx\");"
7280 [(set_attr "type" "multi")
7281 (set_attr "length" "5,5,6")])
7284 [(set (match_operand:SI 0 "register_operand" "=r")
7285 (ashiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
7287 (match_operand:SI 2 "small_int_or_double" "n")))]
7289 && ((GET_CODE (operands[2]) == CONST_INT
7290 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
7291 || (GET_CODE (operands[2]) == CONST_DOUBLE
7292 && !CONST_DOUBLE_HIGH (operands[2])
7293 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
7296 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
7298 return \"srax\\t%1, %2, %0\";
7300 [(set_attr "type" "shift")])
7303 [(set (match_operand:SI 0 "register_operand" "=r")
7304 (lshiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
7306 (match_operand:SI 2 "small_int_or_double" "n")))]
7308 && ((GET_CODE (operands[2]) == CONST_INT
7309 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
7310 || (GET_CODE (operands[2]) == CONST_DOUBLE
7311 && !CONST_DOUBLE_HIGH (operands[2])
7312 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
7315 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
7317 return \"srlx\\t%1, %2, %0\";
7319 [(set_attr "type" "shift")])
7322 [(set (match_operand:SI 0 "register_operand" "=r")
7323 (ashiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
7324 (match_operand:SI 2 "small_int_or_double" "n")) 4)
7325 (match_operand:SI 3 "small_int_or_double" "n")))]
7327 && GET_CODE (operands[2]) == CONST_INT && GET_CODE (operands[3]) == CONST_INT
7328 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
7329 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
7330 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
7333 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
7335 return \"srax\\t%1, %2, %0\";
7337 [(set_attr "type" "shift")])
7340 [(set (match_operand:SI 0 "register_operand" "=r")
7341 (lshiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
7342 (match_operand:SI 2 "small_int_or_double" "n")) 4)
7343 (match_operand:SI 3 "small_int_or_double" "n")))]
7345 && GET_CODE (operands[2]) == CONST_INT && GET_CODE (operands[3]) == CONST_INT
7346 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
7347 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
7348 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
7351 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
7353 return \"srlx\\t%1, %2, %0\";
7355 [(set_attr "type" "shift")])
7357 ;; Unconditional and other jump instructions
7358 ;; On the Sparc, by setting the annul bit on an unconditional branch, the
7359 ;; following insn is never executed. This saves us a nop. Dbx does not
7360 ;; handle such branches though, so we only use them when optimizing.
7362 [(set (pc) (label_ref (match_operand 0 "" "")))]
7366 /* TurboSparc is reported to have problems with
7369 i.e. an empty loop with the annul bit set. The workaround is to use
7373 if (! TARGET_V9 && flag_delayed_branch
7374 && (INSN_ADDRESSES (INSN_UID (operands[0]))
7375 == INSN_ADDRESSES (INSN_UID (insn))))
7376 return \"b\\t%l0%#\";
7378 return TARGET_V9 ? \"ba,pt%*\\t%%xcc, %l0%(\" : \"b%*\\t%l0%(\";
7380 [(set_attr "type" "uncond_branch")])
7382 (define_expand "tablejump"
7383 [(parallel [(set (pc) (match_operand 0 "register_operand" "r"))
7384 (use (label_ref (match_operand 1 "" "")))])]
7388 if (GET_MODE (operands[0]) != CASE_VECTOR_MODE)
7391 /* In pic mode, our address differences are against the base of the
7392 table. Add that base value back in; CSE ought to be able to combine
7393 the two address loads. */
7397 tmp = gen_rtx_LABEL_REF (Pmode, operands[1]);
7399 if (CASE_VECTOR_MODE != Pmode)
7400 tmp2 = gen_rtx_SIGN_EXTEND (Pmode, tmp2);
7401 tmp = gen_rtx_PLUS (Pmode, tmp2, tmp);
7402 operands[0] = memory_address (Pmode, tmp);
7406 (define_insn "*tablejump_sp32"
7407 [(set (pc) (match_operand:SI 0 "address_operand" "p"))
7408 (use (label_ref (match_operand 1 "" "")))]
7411 [(set_attr "type" "uncond_branch")])
7413 (define_insn "*tablejump_sp64"
7414 [(set (pc) (match_operand:DI 0 "address_operand" "p"))
7415 (use (label_ref (match_operand 1 "" "")))]
7418 [(set_attr "type" "uncond_branch")])
7420 ;; This pattern recognizes the "instruction" that appears in
7421 ;; a function call that wants a structure value,
7422 ;; to inform the called function if compiled with Sun CC.
7423 ;(define_insn "*unimp_insn"
7424 ; [(match_operand:SI 0 "immediate_operand" "")]
7425 ; "GET_CODE (operands[0]) == CONST_INT && INTVAL (operands[0]) > 0"
7427 ; [(set_attr "type" "marker")])
7429 ;;- jump to subroutine
7430 (define_expand "call"
7431 ;; Note that this expression is not used for generating RTL.
7432 ;; All the RTL is generated explicitly below.
7433 [(call (match_operand 0 "call_operand" "")
7434 (match_operand 3 "" "i"))]
7435 ;; operands[2] is next_arg_register
7436 ;; operands[3] is struct_value_size_rtx.
7440 rtx fn_rtx, nregs_rtx;
7442 if (GET_MODE (operands[0]) != FUNCTION_MODE)
7445 if (GET_CODE (XEXP (operands[0], 0)) == LABEL_REF)
7447 /* This is really a PIC sequence. We want to represent
7448 it as a funny jump so its delay slots can be filled.
7450 ??? But if this really *is* a CALL, will not it clobber the
7451 call-clobbered registers? We lose this if it is a JUMP_INSN.
7452 Why cannot we have delay slots filled if it were a CALL? */
7454 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
7459 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
7461 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
7467 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
7468 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
7472 fn_rtx = operands[0];
7474 /* Count the number of parameter registers being used by this call.
7475 if that argument is NULL, it means we are using them all, which
7476 means 6 on the sparc. */
7479 nregs_rtx = GEN_INT (REGNO (operands[2]) - 8);
7481 nregs_rtx = GEN_INT (6);
7483 nregs_rtx = const0_rtx;
7486 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
7490 gen_rtvec (3, gen_rtx_CALL (VOIDmode, fn_rtx, nregs_rtx),
7492 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
7497 gen_rtvec (2, gen_rtx_CALL (VOIDmode, fn_rtx, nregs_rtx),
7498 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
7502 /* If this call wants a structure value,
7503 emit an unimp insn to let the called function know about this. */
7504 if (! TARGET_ARCH64 && INTVAL (operands[3]) > 0)
7506 rtx insn = emit_insn (operands[3]);
7507 SCHED_GROUP_P (insn) = 1;
7514 ;; We can't use the same pattern for these two insns, because then registers
7515 ;; in the address may not be properly reloaded.
7517 (define_insn "*call_address_sp32"
7518 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
7519 (match_operand 1 "" ""))
7520 (clobber (reg:SI 15))]
7521 ;;- Do not use operand 1 for most machines.
7524 [(set_attr "type" "call")])
7526 (define_insn "*call_symbolic_sp32"
7527 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
7528 (match_operand 1 "" ""))
7529 (clobber (reg:SI 15))]
7530 ;;- Do not use operand 1 for most machines.
7533 [(set_attr "type" "call")])
7535 (define_insn "*call_address_sp64"
7536 [(call (mem:DI (match_operand:DI 0 "address_operand" "p"))
7537 (match_operand 1 "" ""))
7538 (clobber (reg:DI 15))]
7539 ;;- Do not use operand 1 for most machines.
7542 [(set_attr "type" "call")])
7544 (define_insn "*call_symbolic_sp64"
7545 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
7546 (match_operand 1 "" ""))
7547 (clobber (reg:DI 15))]
7548 ;;- Do not use operand 1 for most machines.
7551 [(set_attr "type" "call")])
7553 ;; This is a call that wants a structure value.
7554 ;; There is no such critter for v9 (??? we may need one anyway).
7555 (define_insn "*call_address_struct_value_sp32"
7556 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
7557 (match_operand 1 "" ""))
7558 (match_operand 2 "immediate_operand" "")
7559 (clobber (reg:SI 15))]
7560 ;;- Do not use operand 1 for most machines.
7561 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 0"
7562 "call\\t%a0, %1\\n\\tnop\\n\\tunimp\\t%2"
7563 [(set_attr "type" "call_no_delay_slot")
7564 (set_attr "length" "3")])
7566 ;; This is a call that wants a structure value.
7567 ;; There is no such critter for v9 (??? we may need one anyway).
7568 (define_insn "*call_symbolic_struct_value_sp32"
7569 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
7570 (match_operand 1 "" ""))
7571 (match_operand 2 "immediate_operand" "")
7572 (clobber (reg:SI 15))]
7573 ;;- Do not use operand 1 for most machines.
7574 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 0"
7575 "call\\t%a0, %1\\n\\tnop\\n\\tunimp\\t%2"
7576 [(set_attr "type" "call_no_delay_slot")
7577 (set_attr "length" "3")])
7579 ;; This is a call that may want a structure value. This is used for
7581 (define_insn "*call_address_untyped_struct_value_sp32"
7582 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
7583 (match_operand 1 "" ""))
7584 (match_operand 2 "immediate_operand" "")
7585 (clobber (reg:SI 15))]
7586 ;;- Do not use operand 1 for most machines.
7587 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
7588 "call\\t%a0, %1\\n\\tnop\\n\\tnop"
7589 [(set_attr "type" "call_no_delay_slot")
7590 (set_attr "length" "3")])
7592 ;; This is a call that wants a structure value.
7593 (define_insn "*call_symbolic_untyped_struct_value_sp32"
7594 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
7595 (match_operand 1 "" ""))
7596 (match_operand 2 "immediate_operand" "")
7597 (clobber (reg:SI 15))]
7598 ;;- Do not use operand 1 for most machines.
7599 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
7600 "call\\t%a0, %1\\n\\tnop\\n\\tnop"
7601 [(set_attr "type" "call_no_delay_slot")
7602 (set_attr "length" "3")])
7604 (define_expand "call_value"
7605 ;; Note that this expression is not used for generating RTL.
7606 ;; All the RTL is generated explicitly below.
7607 [(set (match_operand 0 "register_operand" "=rf")
7608 (call (match_operand 1 "" "")
7609 (match_operand 4 "" "")))]
7610 ;; operand 2 is stack_size_rtx
7611 ;; operand 3 is next_arg_register
7615 rtx fn_rtx, nregs_rtx;
7618 if (GET_MODE (operands[1]) != FUNCTION_MODE)
7621 fn_rtx = operands[1];
7625 nregs_rtx = GEN_INT (REGNO (operands[3]) - 8);
7627 nregs_rtx = GEN_INT (6);
7629 nregs_rtx = const0_rtx;
7633 gen_rtx_SET (VOIDmode, operands[0],
7634 gen_rtx_CALL (VOIDmode, fn_rtx, nregs_rtx)),
7635 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)));
7637 emit_call_insn (gen_rtx_PARALLEL (VOIDmode, vec));
7642 (define_insn "*call_value_address_sp32"
7643 [(set (match_operand 0 "" "=rf")
7644 (call (mem:SI (match_operand:SI 1 "address_operand" "p"))
7645 (match_operand 2 "" "")))
7646 (clobber (reg:SI 15))]
7647 ;;- Do not use operand 2 for most machines.
7650 [(set_attr "type" "call")])
7652 (define_insn "*call_value_symbolic_sp32"
7653 [(set (match_operand 0 "" "=rf")
7654 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
7655 (match_operand 2 "" "")))
7656 (clobber (reg:SI 15))]
7657 ;;- Do not use operand 2 for most machines.
7660 [(set_attr "type" "call")])
7662 (define_insn "*call_value_address_sp64"
7663 [(set (match_operand 0 "" "")
7664 (call (mem:DI (match_operand:DI 1 "address_operand" "p"))
7665 (match_operand 2 "" "")))
7666 (clobber (reg:DI 15))]
7667 ;;- Do not use operand 2 for most machines.
7670 [(set_attr "type" "call")])
7672 (define_insn "*call_value_symbolic_sp64"
7673 [(set (match_operand 0 "" "")
7674 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
7675 (match_operand 2 "" "")))
7676 (clobber (reg:DI 15))]
7677 ;;- Do not use operand 2 for most machines.
7680 [(set_attr "type" "call")])
7682 (define_expand "untyped_call"
7683 [(parallel [(call (match_operand 0 "" "")
7685 (match_operand 1 "" "")
7686 (match_operand 2 "" "")])]
7692 /* Pass constm1 to indicate that it may expect a structure value, but
7693 we don't know what size it is. */
7694 emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, constm1_rtx));
7696 for (i = 0; i < XVECLEN (operands[2], 0); i++)
7698 rtx set = XVECEXP (operands[2], 0, i);
7699 emit_move_insn (SET_DEST (set), SET_SRC (set));
7702 /* The optimizer does not know that the call sets the function value
7703 registers we stored in the result block. We avoid problems by
7704 claiming that all hard registers are used and clobbered at this
7706 emit_insn (gen_blockage ());
7712 (define_expand "sibcall"
7713 [(parallel [(call (match_operand 0 "call_operand" "") (const_int 0))
7718 (define_insn "*sibcall_symbolic_sp32"
7719 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
7720 (match_operand 1 "" ""))
7723 "* return output_sibcall(insn, operands[0]);"
7724 [(set_attr "type" "sibcall")])
7726 (define_insn "*sibcall_symbolic_sp64"
7727 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
7728 (match_operand 1 "" ""))
7731 "* return output_sibcall(insn, operands[0]);"
7732 [(set_attr "type" "sibcall")])
7734 (define_expand "sibcall_value"
7735 [(parallel [(set (match_operand 0 "register_operand" "=rf")
7736 (call (match_operand 1 "" "") (const_int 0)))
7741 (define_insn "*sibcall_value_symbolic_sp32"
7742 [(set (match_operand 0 "" "=rf")
7743 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
7744 (match_operand 2 "" "")))
7747 "* return output_sibcall(insn, operands[1]);"
7748 [(set_attr "type" "sibcall")])
7750 (define_insn "*sibcall_value_symbolic_sp64"
7751 [(set (match_operand 0 "" "")
7752 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
7753 (match_operand 2 "" "")))
7756 "* return output_sibcall(insn, operands[1]);"
7757 [(set_attr "type" "sibcall")])
7759 (define_expand "sibcall_epilogue"
7764 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
7765 ;; all of memory. This blocks insns from being moved across this point.
7767 (define_insn "blockage"
7768 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
7771 [(set_attr "length" "0")])
7773 ;; Prepare to return any type including a structure value.
7775 (define_expand "untyped_return"
7776 [(match_operand:BLK 0 "memory_operand" "")
7777 (match_operand 1 "" "")]
7781 rtx valreg1 = gen_rtx_REG (DImode, 24);
7782 rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
7783 rtx result = operands[0];
7785 if (! TARGET_ARCH64)
7787 rtx rtnreg = gen_rtx_REG (SImode, (current_function_uses_only_leaf_regs
7789 rtx value = gen_reg_rtx (SImode);
7791 /* Fetch the instruction where we will return to and see if it's an unimp
7792 instruction (the most significant 10 bits will be zero). If so,
7793 update the return address to skip the unimp instruction. */
7794 emit_move_insn (value,
7795 gen_rtx_MEM (SImode, plus_constant (rtnreg, 8)));
7796 emit_insn (gen_lshrsi3 (value, value, GEN_INT (22)));
7797 emit_insn (gen_update_return (rtnreg, value));
7800 /* Reload the function value registers. */
7801 emit_move_insn (valreg1, adjust_address (result, DImode, 0));
7802 emit_move_insn (valreg2,
7803 adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8));
7805 /* Put USE insns before the return. */
7806 emit_insn (gen_rtx_USE (VOIDmode, valreg1));
7807 emit_insn (gen_rtx_USE (VOIDmode, valreg2));
7809 /* Construct the return. */
7810 expand_null_return ();
7815 ;; This is a bit of a hack. We're incrementing a fixed register (%i7),
7816 ;; and parts of the compiler don't want to believe that the add is needed.
7818 (define_insn "update_return"
7819 [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
7820 (match_operand:SI 1 "register_operand" "r")] UNSPEC_UPDATE_RETURN)]
7822 "cmp\\t%1, 0\;be,a\\t.+8\;add\\t%0, 4, %0"
7823 [(set_attr "type" "multi")
7824 (set_attr "length" "3")])
7831 (define_expand "indirect_jump"
7832 [(set (pc) (match_operand 0 "address_operand" "p"))]
7836 (define_insn "*branch_sp32"
7837 [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
7840 [(set_attr "type" "uncond_branch")])
7842 (define_insn "*branch_sp64"
7843 [(set (pc) (match_operand:DI 0 "address_operand" "p"))]
7846 [(set_attr "type" "uncond_branch")])
7848 ;; ??? Doesn't work with -mflat.
7849 (define_expand "nonlocal_goto"
7850 [(match_operand:SI 0 "general_operand" "")
7851 (match_operand:SI 1 "general_operand" "")
7852 (match_operand:SI 2 "general_operand" "")
7853 (match_operand:SI 3 "" "")]
7858 rtx chain = operands[0];
7860 rtx lab = operands[1];
7861 rtx stack = operands[2];
7862 rtx fp = operands[3];
7865 /* Trap instruction to flush all the register windows. */
7866 emit_insn (gen_flush_register_windows ());
7868 /* Load the fp value for the containing fn into %fp. This is needed
7869 because STACK refers to %fp. Note that virtual register instantiation
7870 fails if the virtual %fp isn't set from a register. */
7871 if (GET_CODE (fp) != REG)
7872 fp = force_reg (Pmode, fp);
7873 emit_move_insn (virtual_stack_vars_rtx, fp);
7875 /* Find the containing function's current nonlocal goto handler,
7876 which will do any cleanups and then jump to the label. */
7877 labreg = gen_rtx_REG (Pmode, 8);
7878 emit_move_insn (labreg, lab);
7880 /* Restore %fp from stack pointer value for containing function.
7881 The restore insn that follows will move this to %sp,
7882 and reload the appropriate value into %fp. */
7883 emit_move_insn (hard_frame_pointer_rtx, stack);
7885 /* USE of frame_pointer_rtx added for consistency; not clear if
7887 /*emit_insn (gen_rtx_USE (VOIDmode, frame_pointer_rtx));*/
7888 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
7891 /* Return, restoring reg window and jumping to goto handler. */
7892 if (TARGET_V9 && GET_CODE (chain) == CONST_INT
7893 && ! (INTVAL (chain) & ~(HOST_WIDE_INT)0xffffffff))
7895 emit_jump_insn (gen_goto_handler_and_restore_v9 (labreg,
7901 /* Put in the static chain register the nonlocal label address. */
7902 emit_move_insn (static_chain_rtx, chain);
7905 emit_insn (gen_rtx_USE (VOIDmode, static_chain_rtx));
7906 emit_jump_insn (gen_goto_handler_and_restore (labreg));
7911 ;; Special trap insn to flush register windows.
7912 (define_insn "flush_register_windows"
7913 [(unspec_volatile [(const_int 0)] UNSPECV_FLUSHW)]
7915 "* return TARGET_V9 ? \"flushw\" : \"ta\\t3\";"
7916 [(set_attr "type" "flushw")])
7918 (define_insn "goto_handler_and_restore"
7919 [(unspec_volatile [(match_operand 0 "register_operand" "=r")] UNSPECV_GOTO)]
7920 "GET_MODE (operands[0]) == Pmode"
7921 "jmp\\t%0+0\\n\\trestore"
7922 [(set_attr "type" "multi")
7923 (set_attr "length" "2")])
7925 ;;(define_insn "goto_handler_and_restore_v9"
7926 ;; [(unspec_volatile [(match_operand:SI 0 "register_operand" "=r,r")
7927 ;; (match_operand:SI 1 "register_operand" "=r,r")
7928 ;; (match_operand:SI 2 "const_int_operand" "I,n")] UNSPECV_GOTO_V9)]
7929 ;; "TARGET_V9 && ! TARGET_ARCH64"
7931 ;; return\\t%0+0\\n\\tmov\\t%2, %Y1
7932 ;; sethi\\t%%hi(%2), %1\\n\\treturn\\t%0+0\\n\\tor\\t%Y1, %%lo(%2), %Y1"
7933 ;; [(set_attr "type" "multi")
7934 ;; (set_attr "length" "2,3")])
7936 ;;(define_insn "*goto_handler_and_restore_v9_sp64"
7937 ;; [(unspec_volatile [(match_operand:DI 0 "register_operand" "=r,r")
7938 ;; (match_operand:DI 1 "register_operand" "=r,r")
7939 ;; (match_operand:SI 2 "const_int_operand" "I,n")] UNSPECV_GOTO_V9)]
7940 ;; "TARGET_V9 && TARGET_ARCH64"
7942 ;; return\\t%0+0\\n\\tmov\\t%2, %Y1
7943 ;; sethi\\t%%hi(%2), %1\\n\\treturn\\t%0+0\\n\\tor\\t%Y1, %%lo(%2), %Y1"
7944 ;; [(set_attr "type" "multi")
7945 ;; (set_attr "length" "2,3")])
7947 ;; For __builtin_setjmp we need to flush register windows iff the function
7948 ;; calls alloca as well, because otherwise the register window might be
7949 ;; saved after %sp adjustement and thus setjmp would crash
7950 (define_expand "builtin_setjmp_setup"
7951 [(match_operand 0 "register_operand" "r")]
7955 emit_insn (gen_do_builtin_setjmp_setup ());
7959 (define_insn "do_builtin_setjmp_setup"
7960 [(unspec_volatile [(const_int 0)] UNSPECV_SETJMP)]
7964 if (! current_function_calls_alloca)
7966 if (! TARGET_V9 || TARGET_FLAT)
7967 return \"\tta\t3\n\";
7968 fputs (\"\tflushw\n\", asm_out_file);
7970 fprintf (asm_out_file, \"\tst%c\t%%l7, [%%sp+%d]\n\",
7971 TARGET_ARCH64 ? 'x' : 'w',
7972 SPARC_STACK_BIAS + 7 * UNITS_PER_WORD);
7973 fprintf (asm_out_file, \"\tst%c\t%%fp, [%%sp+%d]\n\",
7974 TARGET_ARCH64 ? 'x' : 'w',
7975 SPARC_STACK_BIAS + 14 * UNITS_PER_WORD);
7976 fprintf (asm_out_file, \"\tst%c\t%%i7, [%%sp+%d]\n\",
7977 TARGET_ARCH64 ? 'x' : 'w',
7978 SPARC_STACK_BIAS + 15 * UNITS_PER_WORD);
7981 [(set_attr "type" "multi")
7982 (set (attr "length")
7983 (cond [(eq_attr "current_function_calls_alloca" "false")
7985 (eq_attr "flat" "true")
7987 (eq_attr "isa" "!v9")
7989 (eq_attr "pic" "true")
7990 (const_int 4)] (const_int 3)))])
7992 ;; Pattern for use after a setjmp to store FP and the return register
7993 ;; into the stack area.
7995 (define_expand "setjmp"
8001 emit_insn (gen_setjmp_64 ());
8003 emit_insn (gen_setjmp_32 ());
8007 (define_expand "setjmp_32"
8008 [(set (mem:SI (plus:SI (reg:SI 14) (const_int 56))) (match_dup 0))
8009 (set (mem:SI (plus:SI (reg:SI 14) (const_int 60))) (reg:SI 31))]
8012 { operands[0] = frame_pointer_rtx; }")
8014 (define_expand "setjmp_64"
8015 [(set (mem:DI (plus:DI (reg:DI 14) (const_int 112))) (match_dup 0))
8016 (set (mem:DI (plus:DI (reg:DI 14) (const_int 120))) (reg:DI 31))]
8019 { operands[0] = frame_pointer_rtx; }")
8021 ;; Special pattern for the FLUSH instruction.
8023 ; We do SImode and DImode versions of this to quiet down genrecog's complaints
8024 ; of the define_insn otherwise missing a mode. We make "flush", aka
8025 ; gen_flush, the default one since sparc_initialize_trampoline uses
8026 ; it on SImode mem values.
8028 (define_insn "flush"
8029 [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")] UNSPECV_FLUSH)]
8031 "* return TARGET_V9 ? \"flush\\t%f0\" : \"iflush\\t%f0\";"
8032 [(set_attr "type" "iflush")])
8034 (define_insn "flushdi"
8035 [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")] UNSPECV_FLUSH)]
8037 "* return TARGET_V9 ? \"flush\\t%f0\" : \"iflush\\t%f0\";"
8038 [(set_attr "type" "iflush")])
8043 ;; The scan instruction searches from the most significant bit while ffs
8044 ;; searches from the least significant bit. The bit index and treatment of
8045 ;; zero also differ. It takes at least 7 instructions to get the proper
8046 ;; result. Here is an obvious 8 instruction sequence.
8049 (define_insn "ffssi2"
8050 [(set (match_operand:SI 0 "register_operand" "=&r")
8051 (ffs:SI (match_operand:SI 1 "register_operand" "r")))
8052 (clobber (match_scratch:SI 2 "=&r"))]
8053 "TARGET_SPARCLITE || TARGET_SPARCLET"
8056 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\";
8058 [(set_attr "type" "multi")
8059 (set_attr "length" "8")])
8061 ;; ??? This should be a define expand, so that the extra instruction have
8062 ;; a chance of being optimized away.
8064 ;; Disabled because none of the UltraSparcs implement popc. The HAL R1
8065 ;; does, but no one uses that and we don't have a switch for it.
8067 ;(define_insn "ffsdi2"
8068 ; [(set (match_operand:DI 0 "register_operand" "=&r")
8069 ; (ffs:DI (match_operand:DI 1 "register_operand" "r")))
8070 ; (clobber (match_scratch:DI 2 "=&r"))]
8072 ; "neg\\t%1, %2\;xnor\\t%1, %2, %2\;popc\\t%2, %0\;movzr\\t%1, 0, %0"
8073 ; [(set_attr "type" "multi")
8074 ; (set_attr "length" "4")])
8078 ;; Peepholes go at the end.
8080 ;; Optimize consecutive loads or stores into ldd and std when possible.
8081 ;; The conditions in which we do this are very restricted and are
8082 ;; explained in the code for {registers,memory}_ok_for_ldd functions.
8085 [(set (match_operand:SI 0 "memory_operand" "")
8087 (set (match_operand:SI 1 "memory_operand" "")
8090 && mems_ok_for_ldd_peep (operands[0], operands[1], NULL_RTX)"
8093 "operands[0] = change_address (operands[0], DImode, NULL);")
8096 [(set (match_operand:SI 0 "memory_operand" "")
8098 (set (match_operand:SI 1 "memory_operand" "")
8101 && mems_ok_for_ldd_peep (operands[1], operands[0], NULL_RTX)"
8104 "operands[1] = change_address (operands[1], DImode, NULL);")
8107 [(set (match_operand:SI 0 "register_operand" "")
8108 (match_operand:SI 1 "memory_operand" ""))
8109 (set (match_operand:SI 2 "register_operand" "")
8110 (match_operand:SI 3 "memory_operand" ""))]
8111 "registers_ok_for_ldd_peep (operands[0], operands[2])
8112 && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
8115 "operands[1] = change_address (operands[1], DImode, NULL);
8116 operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));")
8119 [(set (match_operand:SI 0 "memory_operand" "")
8120 (match_operand:SI 1 "register_operand" ""))
8121 (set (match_operand:SI 2 "memory_operand" "")
8122 (match_operand:SI 3 "register_operand" ""))]
8123 "registers_ok_for_ldd_peep (operands[1], operands[3])
8124 && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
8127 "operands[0] = change_address (operands[0], DImode, NULL);
8128 operands[1] = gen_rtx_REG (DImode, REGNO (operands[1]));")
8131 [(set (match_operand:SF 0 "register_operand" "")
8132 (match_operand:SF 1 "memory_operand" ""))
8133 (set (match_operand:SF 2 "register_operand" "")
8134 (match_operand:SF 3 "memory_operand" ""))]
8135 "registers_ok_for_ldd_peep (operands[0], operands[2])
8136 && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
8139 "operands[1] = change_address (operands[1], DFmode, NULL);
8140 operands[0] = gen_rtx_REG (DFmode, REGNO (operands[0]));")
8143 [(set (match_operand:SF 0 "memory_operand" "")
8144 (match_operand:SF 1 "register_operand" ""))
8145 (set (match_operand:SF 2 "memory_operand" "")
8146 (match_operand:SF 3 "register_operand" ""))]
8147 "registers_ok_for_ldd_peep (operands[1], operands[3])
8148 && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
8151 "operands[0] = change_address (operands[0], DFmode, NULL);
8152 operands[1] = gen_rtx_REG (DFmode, REGNO (operands[1]));")
8155 [(set (match_operand:SI 0 "register_operand" "")
8156 (match_operand:SI 1 "memory_operand" ""))
8157 (set (match_operand:SI 2 "register_operand" "")
8158 (match_operand:SI 3 "memory_operand" ""))]
8159 "registers_ok_for_ldd_peep (operands[2], operands[0])
8160 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
8163 "operands[3] = change_address (operands[3], DImode, NULL);
8164 operands[2] = gen_rtx_REG (DImode, REGNO (operands[2]));")
8167 [(set (match_operand:SI 0 "memory_operand" "")
8168 (match_operand:SI 1 "register_operand" ""))
8169 (set (match_operand:SI 2 "memory_operand" "")
8170 (match_operand:SI 3 "register_operand" ""))]
8171 "registers_ok_for_ldd_peep (operands[3], operands[1])
8172 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
8175 "operands[2] = change_address (operands[2], DImode, NULL);
8176 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
8180 [(set (match_operand:SF 0 "register_operand" "")
8181 (match_operand:SF 1 "memory_operand" ""))
8182 (set (match_operand:SF 2 "register_operand" "")
8183 (match_operand:SF 3 "memory_operand" ""))]
8184 "registers_ok_for_ldd_peep (operands[2], operands[0])
8185 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
8188 "operands[3] = change_address (operands[3], DFmode, NULL);
8189 operands[2] = gen_rtx_REG (DFmode, REGNO (operands[2]));")
8192 [(set (match_operand:SF 0 "memory_operand" "")
8193 (match_operand:SF 1 "register_operand" ""))
8194 (set (match_operand:SF 2 "memory_operand" "")
8195 (match_operand:SF 3 "register_operand" ""))]
8196 "registers_ok_for_ldd_peep (operands[3], operands[1])
8197 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
8200 "operands[2] = change_address (operands[2], DFmode, NULL);
8201 operands[3] = gen_rtx_REG (DFmode, REGNO (operands[3]));")
8203 ;; Optimize the case of following a reg-reg move with a test
8204 ;; of reg just moved. Don't allow floating point regs for operand 0 or 1.
8205 ;; This can result from a float to fix conversion.
8208 [(set (match_operand:SI 0 "register_operand" "")
8209 (match_operand:SI 1 "register_operand" ""))
8211 (compare:CC (match_operand:SI 2 "register_operand" "")
8213 "(rtx_equal_p (operands[2], operands[0])
8214 || rtx_equal_p (operands[2], operands[1]))
8215 && ! SPARC_FP_REG_P (REGNO (operands[0]))
8216 && ! SPARC_FP_REG_P (REGNO (operands[1]))"
8217 [(parallel [(set (match_dup 0) (match_dup 1))
8219 (compare:CC (match_dup 1) (const_int 0)))])]
8223 [(set (match_operand:DI 0 "register_operand" "")
8224 (match_operand:DI 1 "register_operand" ""))
8226 (compare:CCX (match_operand:DI 2 "register_operand" "")
8229 && (rtx_equal_p (operands[2], operands[0])
8230 || rtx_equal_p (operands[2], operands[1]))
8231 && ! SPARC_FP_REG_P (REGNO (operands[0]))
8232 && ! SPARC_FP_REG_P (REGNO (operands[1]))"
8233 [(parallel [(set (match_dup 0) (match_dup 1))
8235 (compare:CCX (match_dup 1) (const_int 0)))])]
8238 ;; Return peepholes. These are generated by sparc_nonflat_function_epilogue
8239 ;; who then immediately calls final_scan_insn.
8241 (define_insn "*return_qi"
8242 [(set (match_operand:QI 0 "restore_operand" "")
8243 (match_operand:QI 1 "arith_operand" "rI"))
8245 "sparc_emitting_epilogue"
8248 if (! TARGET_ARCH64 && current_function_returns_struct)
8249 return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\";
8250 else if (TARGET_V9 && (GET_CODE (operands[1]) == CONST_INT
8251 || IN_OR_GLOBAL_P (operands[1])))
8252 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
8254 return \"ret\\n\\trestore %%g0, %1, %Y0\";
8256 [(set_attr "type" "multi")
8257 (set_attr "length" "2")])
8259 (define_insn "*return_hi"
8260 [(set (match_operand:HI 0 "restore_operand" "")
8261 (match_operand:HI 1 "arith_operand" "rI"))
8263 "sparc_emitting_epilogue"
8266 if (! TARGET_ARCH64 && current_function_returns_struct)
8267 return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\";
8268 else if (TARGET_V9 && (GET_CODE (operands[1]) == CONST_INT
8269 || IN_OR_GLOBAL_P (operands[1])))
8270 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
8272 return \"ret\;restore %%g0, %1, %Y0\";
8274 [(set_attr "type" "multi")
8275 (set_attr "length" "2")])
8277 (define_insn "*return_si"
8278 [(set (match_operand:SI 0 "restore_operand" "")
8279 (match_operand:SI 1 "arith_operand" "rI"))
8281 "sparc_emitting_epilogue"
8284 if (! TARGET_ARCH64 && current_function_returns_struct)
8285 return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\";
8286 else if (TARGET_V9 && (GET_CODE (operands[1]) == CONST_INT
8287 || IN_OR_GLOBAL_P (operands[1])))
8288 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
8290 return \"ret\;restore %%g0, %1, %Y0\";
8292 [(set_attr "type" "multi")
8293 (set_attr "length" "2")])
8295 (define_insn "*return_sf_no_fpu"
8296 [(set (match_operand:SF 0 "restore_operand" "=r")
8297 (match_operand:SF 1 "register_operand" "r"))
8299 "sparc_emitting_epilogue"
8302 if (! TARGET_ARCH64 && current_function_returns_struct)
8303 return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\";
8304 else if (TARGET_V9 && IN_OR_GLOBAL_P (operands[1]))
8305 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
8307 return \"ret\;restore %%g0, %1, %Y0\";
8309 [(set_attr "type" "multi")
8310 (set_attr "length" "2")])
8312 (define_insn "*return_df_no_fpu"
8313 [(set (match_operand:DF 0 "restore_operand" "=r")
8314 (match_operand:DF 1 "register_operand" "r"))
8316 "sparc_emitting_epilogue && TARGET_ARCH64"
8319 if (IN_OR_GLOBAL_P (operands[1]))
8320 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
8322 return \"ret\;restore %%g0, %1, %Y0\";
8324 [(set_attr "type" "multi")
8325 (set_attr "length" "2")])
8327 (define_insn "*return_addsi"
8328 [(set (match_operand:SI 0 "restore_operand" "")
8329 (plus:SI (match_operand:SI 1 "register_operand" "r")
8330 (match_operand:SI 2 "arith_operand" "rI")))
8332 "sparc_emitting_epilogue"
8335 if (! TARGET_ARCH64 && current_function_returns_struct)
8336 return \"jmp\\t%%i7+12\\n\\trestore %r1, %2, %Y0\";
8337 /* If operands are global or in registers, can use return */
8338 else if (TARGET_V9 && IN_OR_GLOBAL_P (operands[1])
8339 && (GET_CODE (operands[2]) == CONST_INT
8340 || IN_OR_GLOBAL_P (operands[2])))
8341 return \"return\\t%%i7+8\\n\\tadd\\t%Y1, %Y2, %Y0\";
8343 return \"ret\;restore %r1, %2, %Y0\";
8345 [(set_attr "type" "multi")
8346 (set_attr "length" "2")])
8348 (define_insn "*return_losum_si"
8349 [(set (match_operand:SI 0 "restore_operand" "")
8350 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
8351 (match_operand:SI 2 "immediate_operand" "in")))
8353 "sparc_emitting_epilogue && ! TARGET_CM_MEDMID"
8356 if (! TARGET_ARCH64 && current_function_returns_struct)
8357 return \"jmp\\t%%i7+12\\n\\trestore %r1, %%lo(%a2), %Y0\";
8358 /* If operands are global or in registers, can use return */
8359 else if (TARGET_V9 && IN_OR_GLOBAL_P (operands[1]))
8360 return \"return\\t%%i7+8\\n\\tor\\t%Y1, %%lo(%a2), %Y0\";
8362 return \"ret\;restore %r1, %%lo(%a2), %Y0\";
8364 [(set_attr "type" "multi")
8365 (set_attr "length" "2")])
8367 (define_insn "*return_di"
8368 [(set (match_operand:DI 0 "restore_operand" "")
8369 (match_operand:DI 1 "arith_double_operand" "rHI"))
8371 "sparc_emitting_epilogue && TARGET_ARCH64"
8372 "ret\;restore %%g0, %1, %Y0"
8373 [(set_attr "type" "multi")
8374 (set_attr "length" "2")])
8376 (define_insn "*return_adddi"
8377 [(set (match_operand:DI 0 "restore_operand" "")
8378 (plus:DI (match_operand:DI 1 "arith_operand" "%r")
8379 (match_operand:DI 2 "arith_double_operand" "rHI")))
8381 "sparc_emitting_epilogue && TARGET_ARCH64"
8382 "ret\;restore %r1, %2, %Y0"
8383 [(set_attr "type" "multi")
8384 (set_attr "length" "2")])
8386 (define_insn "*return_losum_di"
8387 [(set (match_operand:DI 0 "restore_operand" "")
8388 (lo_sum:DI (match_operand:DI 1 "arith_operand" "%r")
8389 (match_operand:DI 2 "immediate_operand" "in")))
8391 "sparc_emitting_epilogue && TARGET_ARCH64 && ! TARGET_CM_MEDMID"
8392 "ret\;restore %r1, %%lo(%a2), %Y0"
8393 [(set_attr "type" "multi")
8394 (set_attr "length" "2")])
8396 (define_insn "*return_sf"
8398 (match_operand:SF 0 "register_operand" "f"))
8400 "sparc_emitting_epilogue"
8401 "ret\;fmovs\\t%0, %%f0"
8402 [(set_attr "type" "multi")
8403 (set_attr "length" "2")])
8405 ;; Now peepholes to do a call followed by a jump.
8408 [(parallel [(set (match_operand 0 "" "")
8409 (call (mem:SI (match_operand:SI 1 "call_operand_address" "ps"))
8410 (match_operand 2 "" "")))
8411 (clobber (reg:SI 15))])
8412 (set (pc) (label_ref (match_operand 3 "" "")))]
8413 "short_branch (INSN_UID (insn), INSN_UID (operands[3]))
8414 && (USING_SJLJ_EXCEPTIONS || ! can_throw_internal (ins1))
8415 && sparc_cpu != PROCESSOR_ULTRASPARC
8416 && sparc_cpu != PROCESSOR_ULTRASPARC3"
8417 "call\\t%a1, %2\\n\\tadd\\t%%o7, (%l3-.-4), %%o7")
8420 [(parallel [(call (mem:SI (match_operand:SI 0 "call_operand_address" "ps"))
8421 (match_operand 1 "" ""))
8422 (clobber (reg:SI 15))])
8423 (set (pc) (label_ref (match_operand 2 "" "")))]
8424 "short_branch (INSN_UID (insn), INSN_UID (operands[2]))
8425 && (USING_SJLJ_EXCEPTIONS || ! can_throw_internal (ins1))
8426 && sparc_cpu != PROCESSOR_ULTRASPARC
8427 && sparc_cpu != PROCESSOR_ULTRASPARC3"
8428 "call\\t%a0, %1\\n\\tadd\\t%%o7, (%l2-.-4), %%o7")
8430 ;; ??? UltraSPARC-III note: A memory operation loading into the floating point register
8431 ;; ??? file, if it hits the prefetch cache, has a chance to dual-issue with other memory
8432 ;; ??? operations. With DFA we might be able to model this, but it requires a lot of
8434 (define_expand "prefetch"
8435 [(match_operand 0 "address_operand" "")
8436 (match_operand 1 "const_int_operand" "")
8437 (match_operand 2 "const_int_operand" "")]
8442 emit_insn (gen_prefetch_64 (operands[0], operands[1], operands[2]));
8444 emit_insn (gen_prefetch_32 (operands[0], operands[1], operands[2]));
8448 (define_insn "prefetch_64"
8449 [(prefetch (match_operand:DI 0 "address_operand" "p")
8450 (match_operand:DI 1 "const_int_operand" "n")
8451 (match_operand:DI 2 "const_int_operand" "n"))]
8454 static const char * const prefetch_instr[2][2] = {
8456 "prefetch\\t[%a0], 1", /* no locality: prefetch for one read */
8457 "prefetch\\t[%a0], 0", /* medium to high locality: prefetch for several reads */
8460 "prefetch\\t[%a0], 3", /* no locality: prefetch for one write */
8461 "prefetch\\t[%a0], 2", /* medium to high locality: prefetch for several writes */
8464 int read_or_write = INTVAL (operands[1]);
8465 int locality = INTVAL (operands[2]);
8467 if (read_or_write != 0 && read_or_write != 1)
8469 if (locality < 0 || locality > 3)
8471 return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
8473 [(set_attr "type" "load")])
8475 (define_insn "prefetch_32"
8476 [(prefetch (match_operand:SI 0 "address_operand" "p")
8477 (match_operand:SI 1 "const_int_operand" "n")
8478 (match_operand:SI 2 "const_int_operand" "n"))]
8481 static const char * const prefetch_instr[2][2] = {
8483 "prefetch\\t[%a0], 1", /* no locality: prefetch for one read */
8484 "prefetch\\t[%a0], 0", /* medium to high locality: prefetch for several reads */
8487 "prefetch\\t[%a0], 3", /* no locality: prefetch for one write */
8488 "prefetch\\t[%a0], 2", /* medium to high locality: prefetch for several writes */
8491 int read_or_write = INTVAL (operands[1]);
8492 int locality = INTVAL (operands[2]);
8494 if (read_or_write != 0 && read_or_write != 1)
8496 if (locality < 0 || locality > 3)
8498 return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
8500 [(set_attr "type" "load")])
8502 (define_expand "prologue"
8504 "flag_pic && current_function_uses_pic_offset_table"
8507 load_pic_register ();
8511 ;; We need to reload %l7 for -mflat -fpic,
8512 ;; otherwise %l7 should be preserved simply
8513 ;; by loading the function's register window
8514 (define_expand "exception_receiver"
8516 "TARGET_FLAT && flag_pic"
8519 load_pic_register ();
8524 (define_expand "builtin_setjmp_receiver"
8525 [(label_ref (match_operand 0 "" ""))]
8526 "TARGET_FLAT && flag_pic"
8529 load_pic_register ();
8534 [(trap_if (const_int 1) (const_int 5))]
8537 [(set_attr "type" "trap")])
8539 (define_expand "conditional_trap"
8540 [(trap_if (match_operator 0 "noov_compare_op"
8541 [(match_dup 2) (match_dup 3)])
8542 (match_operand:SI 1 "arith_operand" ""))]
8544 "operands[2] = gen_compare_reg (GET_CODE (operands[0]),
8545 sparc_compare_op0, sparc_compare_op1);
8546 operands[3] = const0_rtx;")
8549 [(trap_if (match_operator 0 "noov_compare_op" [(reg:CC 100) (const_int 0)])
8550 (match_operand:SI 1 "arith_operand" "rM"))]
8553 [(set_attr "type" "trap")])
8556 [(trap_if (match_operator 0 "noov_compare_op" [(reg:CCX 100) (const_int 0)])
8557 (match_operand:SI 1 "arith_operand" "rM"))]
8560 [(set_attr "type" "trap")])