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 "*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))]
836 [(set_attr "length" "2")])
839 [(set (match_operand:SI 0 "register_operand" "")
840 (ne:SI (match_operand:SI 1 "register_operand" "")
842 (clobber (reg:CC 100))]
844 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
846 (set (match_dup 0) (ltu:SI (reg:CC 100) (const_int 0)))]
849 (define_insn "*neg_snesi_zero"
850 [(set (match_operand:SI 0 "register_operand" "=r")
851 (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
853 (clobber (reg:CC 100))]
856 [(set_attr "length" "2")])
859 [(set (match_operand:SI 0 "register_operand" "")
860 (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "")
862 (clobber (reg:CC 100))]
864 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
866 (set (match_dup 0) (neg:SI (ltu:SI (reg:CC 100) (const_int 0))))]
869 (define_insn "*snesi_zero_extend"
870 [(set (match_operand:DI 0 "register_operand" "=r")
871 (ne:DI (match_operand:SI 1 "register_operand" "r")
873 (clobber (reg:CC 100))]
876 [(set_attr "length" "2")])
879 [(set (match_operand:DI 0 "register_operand" "")
880 (ne:DI (match_operand:SI 1 "register_operand" "")
882 (clobber (reg:CC 100))]
884 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 1))
886 (set (match_dup 0) (zero_extend:DI (plus:SI (plus:SI (const_int 0)
888 (ltu:SI (reg:CC_NOOV 100)
892 (define_insn "*snedi_zero"
893 [(set (match_operand:DI 0 "register_operand" "=&r")
894 (ne:DI (match_operand:DI 1 "register_operand" "r")
898 [(set_attr "length" "2")])
901 [(set (match_operand:DI 0 "register_operand" "")
902 (ne:DI (match_operand:DI 1 "register_operand" "")
905 && ! reg_overlap_mentioned_p (operands[1], operands[0])"
906 [(set (match_dup 0) (const_int 0))
907 (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
913 (define_insn "*neg_snedi_zero"
914 [(set (match_operand:DI 0 "register_operand" "=&r")
915 (neg:DI (ne:DI (match_operand:DI 1 "register_operand" "r")
919 [(set_attr "length" "2")])
922 [(set (match_operand:DI 0 "register_operand" "")
923 (neg:DI (ne:DI (match_operand:DI 1 "register_operand" "")
926 && ! reg_overlap_mentioned_p (operands[1], operands[0])"
927 [(set (match_dup 0) (const_int 0))
928 (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
934 (define_insn "*snedi_zero_trunc"
935 [(set (match_operand:SI 0 "register_operand" "=&r")
936 (ne:SI (match_operand:DI 1 "register_operand" "r")
940 [(set_attr "length" "2")])
943 [(set (match_operand:SI 0 "register_operand" "")
944 (ne:SI (match_operand:DI 1 "register_operand" "")
947 && ! reg_overlap_mentioned_p (operands[1], operands[0])"
948 [(set (match_dup 0) (const_int 0))
949 (set (match_dup 0) (if_then_else:SI (ne:DI (match_dup 1)
955 (define_insn "*seqsi_zero"
956 [(set (match_operand:SI 0 "register_operand" "=r")
957 (eq:SI (match_operand:SI 1 "register_operand" "r")
959 (clobber (reg:CC 100))]
962 [(set_attr "length" "2")])
965 [(set (match_operand:SI 0 "register_operand" "")
966 (eq:SI (match_operand:SI 1 "register_operand" "")
968 (clobber (reg:CC 100))]
970 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
972 (set (match_dup 0) (geu:SI (reg:CC 100) (const_int 0)))]
975 (define_insn "*neg_seqsi_zero"
976 [(set (match_operand:SI 0 "register_operand" "=r")
977 (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
979 (clobber (reg:CC 100))]
982 [(set_attr "length" "2")])
985 [(set (match_operand:SI 0 "register_operand" "")
986 (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "")
988 (clobber (reg:CC 100))]
990 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
992 (set (match_dup 0) (neg:SI (geu:SI (reg:CC 100) (const_int 0))))]
995 (define_insn "*seqsi_zero_extend"
996 [(set (match_operand:DI 0 "register_operand" "=r")
997 (eq:DI (match_operand:SI 1 "register_operand" "r")
999 (clobber (reg:CC 100))]
1002 [(set_attr "length" "2")])
1005 [(set (match_operand:DI 0 "register_operand" "")
1006 (eq:DI (match_operand:SI 1 "register_operand" "")
1008 (clobber (reg:CC 100))]
1010 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 1))
1012 (set (match_dup 0) (zero_extend:DI (minus:SI (minus:SI (const_int 0)
1014 (ltu:SI (reg:CC_NOOV 100)
1018 (define_insn "*seqdi_zero"
1019 [(set (match_operand:DI 0 "register_operand" "=&r")
1020 (eq:DI (match_operand:DI 1 "register_operand" "r")
1024 [(set_attr "length" "2")])
1027 [(set (match_operand:DI 0 "register_operand" "")
1028 (eq:DI (match_operand:DI 1 "register_operand" "")
1031 && ! reg_overlap_mentioned_p (operands[1], operands[0])"
1032 [(set (match_dup 0) (const_int 0))
1033 (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
1039 (define_insn "*neg_seqdi_zero"
1040 [(set (match_operand:DI 0 "register_operand" "=&r")
1041 (neg:DI (eq:DI (match_operand:DI 1 "register_operand" "r")
1045 [(set_attr "length" "2")])
1048 [(set (match_operand:DI 0 "register_operand" "")
1049 (neg:DI (eq:DI (match_operand:DI 1 "register_operand" "")
1052 && ! reg_overlap_mentioned_p (operands[1], operands[0])"
1053 [(set (match_dup 0) (const_int 0))
1054 (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
1060 (define_insn "*seqdi_zero_trunc"
1061 [(set (match_operand:SI 0 "register_operand" "=&r")
1062 (eq:SI (match_operand:DI 1 "register_operand" "r")
1066 [(set_attr "length" "2")])
1069 [(set (match_operand:SI 0 "register_operand" "")
1070 (eq:SI (match_operand:DI 1 "register_operand" "")
1073 && ! reg_overlap_mentioned_p (operands[1], operands[0])"
1074 [(set (match_dup 0) (const_int 0))
1075 (set (match_dup 0) (if_then_else:SI (eq:DI (match_dup 1)
1081 ;; We can also do (x + (i == 0)) and related, so put them in.
1082 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1085 (define_insn "*x_plus_i_ne_0"
1086 [(set (match_operand:SI 0 "register_operand" "=r")
1087 (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
1089 (match_operand:SI 2 "register_operand" "r")))
1090 (clobber (reg:CC 100))]
1093 [(set_attr "length" "2")])
1096 [(set (match_operand:SI 0 "register_operand" "")
1097 (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "")
1099 (match_operand:SI 2 "register_operand" "")))
1100 (clobber (reg:CC 100))]
1102 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1104 (set (match_dup 0) (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1108 (define_insn "*x_minus_i_ne_0"
1109 [(set (match_operand:SI 0 "register_operand" "=r")
1110 (minus:SI (match_operand:SI 2 "register_operand" "r")
1111 (ne:SI (match_operand:SI 1 "register_operand" "r")
1113 (clobber (reg:CC 100))]
1116 [(set_attr "length" "2")])
1119 [(set (match_operand:SI 0 "register_operand" "")
1120 (minus:SI (match_operand:SI 2 "register_operand" "")
1121 (ne:SI (match_operand:SI 1 "register_operand" "")
1123 (clobber (reg:CC 100))]
1125 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1127 (set (match_dup 0) (minus:SI (match_dup 2)
1128 (ltu:SI (reg:CC 100) (const_int 0))))]
1131 (define_insn "*x_plus_i_eq_0"
1132 [(set (match_operand:SI 0 "register_operand" "=r")
1133 (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
1135 (match_operand:SI 2 "register_operand" "r")))
1136 (clobber (reg:CC 100))]
1139 [(set_attr "length" "2")])
1142 [(set (match_operand:SI 0 "register_operand" "")
1143 (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "")
1145 (match_operand:SI 2 "register_operand" "")))
1146 (clobber (reg:CC 100))]
1148 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1150 (set (match_dup 0) (plus:SI (geu:SI (reg:CC 100) (const_int 0))
1154 (define_insn "*x_minus_i_eq_0"
1155 [(set (match_operand:SI 0 "register_operand" "=r")
1156 (minus:SI (match_operand:SI 2 "register_operand" "r")
1157 (eq:SI (match_operand:SI 1 "register_operand" "r")
1159 (clobber (reg:CC 100))]
1162 [(set_attr "length" "2")])
1165 [(set (match_operand:SI 0 "register_operand" "")
1166 (minus:SI (match_operand:SI 2 "register_operand" "")
1167 (eq:SI (match_operand:SI 1 "register_operand" "")
1169 (clobber (reg:CC 100))]
1171 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1173 (set (match_dup 0) (minus:SI (match_dup 2)
1174 (geu:SI (reg:CC 100) (const_int 0))))]
1177 ;; We can also do GEU and LTU directly, but these operate after a compare.
1178 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1181 (define_insn "*sltu_insn"
1182 [(set (match_operand:SI 0 "register_operand" "=r")
1183 (ltu:SI (reg:CC 100) (const_int 0)))]
1185 "addx\\t%%g0, 0, %0"
1186 [(set_attr "type" "ialuX")])
1188 (define_insn "*neg_sltu_insn"
1189 [(set (match_operand:SI 0 "register_operand" "=r")
1190 (neg:SI (ltu:SI (reg:CC 100) (const_int 0))))]
1192 "subx\\t%%g0, 0, %0"
1193 [(set_attr "type" "ialuX")])
1195 ;; ??? Combine should canonicalize these next two to the same pattern.
1196 (define_insn "*neg_sltu_minus_x"
1197 [(set (match_operand:SI 0 "register_operand" "=r")
1198 (minus:SI (neg:SI (ltu:SI (reg:CC 100) (const_int 0)))
1199 (match_operand:SI 1 "arith_operand" "rI")))]
1201 "subx\\t%%g0, %1, %0"
1202 [(set_attr "type" "ialuX")])
1204 (define_insn "*neg_sltu_plus_x"
1205 [(set (match_operand:SI 0 "register_operand" "=r")
1206 (neg:SI (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1207 (match_operand:SI 1 "arith_operand" "rI"))))]
1209 "subx\\t%%g0, %1, %0"
1210 [(set_attr "type" "ialuX")])
1212 (define_insn "*sgeu_insn"
1213 [(set (match_operand:SI 0 "register_operand" "=r")
1214 (geu:SI (reg:CC 100) (const_int 0)))]
1216 "subx\\t%%g0, -1, %0"
1217 [(set_attr "type" "ialuX")])
1219 (define_insn "*neg_sgeu_insn"
1220 [(set (match_operand:SI 0 "register_operand" "=r")
1221 (neg:SI (geu:SI (reg:CC 100) (const_int 0))))]
1223 "addx\\t%%g0, -1, %0"
1224 [(set_attr "type" "ialuX")])
1226 ;; We can also do (x + ((unsigned) i >= 0)) and related, so put them in.
1227 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1230 (define_insn "*sltu_plus_x"
1231 [(set (match_operand:SI 0 "register_operand" "=r")
1232 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1233 (match_operand:SI 1 "arith_operand" "rI")))]
1235 "addx\\t%%g0, %1, %0"
1236 [(set_attr "type" "ialuX")])
1238 (define_insn "*sltu_plus_x_plus_y"
1239 [(set (match_operand:SI 0 "register_operand" "=r")
1240 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1241 (plus:SI (match_operand:SI 1 "arith_operand" "%r")
1242 (match_operand:SI 2 "arith_operand" "rI"))))]
1245 [(set_attr "type" "ialuX")])
1247 (define_insn "*x_minus_sltu"
1248 [(set (match_operand:SI 0 "register_operand" "=r")
1249 (minus:SI (match_operand:SI 1 "register_operand" "r")
1250 (ltu:SI (reg:CC 100) (const_int 0))))]
1253 [(set_attr "type" "ialuX")])
1255 ;; ??? Combine should canonicalize these next two to the same pattern.
1256 (define_insn "*x_minus_y_minus_sltu"
1257 [(set (match_operand:SI 0 "register_operand" "=r")
1258 (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
1259 (match_operand:SI 2 "arith_operand" "rI"))
1260 (ltu:SI (reg:CC 100) (const_int 0))))]
1262 "subx\\t%r1, %2, %0"
1263 [(set_attr "type" "ialuX")])
1265 (define_insn "*x_minus_sltu_plus_y"
1266 [(set (match_operand:SI 0 "register_operand" "=r")
1267 (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
1268 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1269 (match_operand:SI 2 "arith_operand" "rI"))))]
1271 "subx\\t%r1, %2, %0"
1272 [(set_attr "type" "ialuX")])
1274 (define_insn "*sgeu_plus_x"
1275 [(set (match_operand:SI 0 "register_operand" "=r")
1276 (plus:SI (geu:SI (reg:CC 100) (const_int 0))
1277 (match_operand:SI 1 "register_operand" "r")))]
1280 [(set_attr "type" "ialuX")])
1282 (define_insn "*x_minus_sgeu"
1283 [(set (match_operand:SI 0 "register_operand" "=r")
1284 (minus:SI (match_operand:SI 1 "register_operand" "r")
1285 (geu:SI (reg:CC 100) (const_int 0))))]
1288 [(set_attr "type" "ialuX")])
1291 [(set (match_operand:SI 0 "register_operand" "")
1292 (match_operator:SI 2 "noov_compare_op"
1293 [(match_operand 1 "icc_or_fcc_reg_operand" "")
1295 ;; 32 bit LTU/GEU are better implemented using addx/subx
1296 "TARGET_V9 && REGNO (operands[1]) == SPARC_ICC_REG
1297 && (GET_MODE (operands[1]) == CCXmode
1298 || (GET_CODE (operands[2]) != LTU && GET_CODE (operands[2]) != GEU))"
1299 [(set (match_dup 0) (const_int 0))
1301 (if_then_else:SI (match_op_dup:SI 2 [(match_dup 1) (const_int 0)])
1307 ;; These control RTL generation for conditional jump insns
1309 ;; The quad-word fp compare library routines all return nonzero to indicate
1310 ;; true, which is different from the equivalent libgcc routines, so we must
1311 ;; handle them specially here.
1313 (define_expand "beq"
1315 (if_then_else (eq (match_dup 1) (const_int 0))
1316 (label_ref (match_operand 0 "" ""))
1321 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1322 && GET_CODE (sparc_compare_op0) == REG
1323 && GET_MODE (sparc_compare_op0) == DImode)
1325 emit_v9_brxx_insn (EQ, sparc_compare_op0, operands[0]);
1328 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1330 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, EQ);
1331 emit_jump_insn (gen_bne (operands[0]));
1334 operands[1] = gen_compare_reg (EQ, sparc_compare_op0, sparc_compare_op1);
1337 (define_expand "bne"
1339 (if_then_else (ne (match_dup 1) (const_int 0))
1340 (label_ref (match_operand 0 "" ""))
1345 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1346 && GET_CODE (sparc_compare_op0) == REG
1347 && GET_MODE (sparc_compare_op0) == DImode)
1349 emit_v9_brxx_insn (NE, sparc_compare_op0, operands[0]);
1352 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1354 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, NE);
1355 emit_jump_insn (gen_bne (operands[0]));
1358 operands[1] = gen_compare_reg (NE, sparc_compare_op0, sparc_compare_op1);
1361 (define_expand "bgt"
1363 (if_then_else (gt (match_dup 1) (const_int 0))
1364 (label_ref (match_operand 0 "" ""))
1369 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1370 && GET_CODE (sparc_compare_op0) == REG
1371 && GET_MODE (sparc_compare_op0) == DImode)
1373 emit_v9_brxx_insn (GT, sparc_compare_op0, operands[0]);
1376 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1378 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GT);
1379 emit_jump_insn (gen_bne (operands[0]));
1382 operands[1] = gen_compare_reg (GT, sparc_compare_op0, sparc_compare_op1);
1385 (define_expand "bgtu"
1387 (if_then_else (gtu (match_dup 1) (const_int 0))
1388 (label_ref (match_operand 0 "" ""))
1392 { operands[1] = gen_compare_reg (GTU, sparc_compare_op0, sparc_compare_op1);
1395 (define_expand "blt"
1397 (if_then_else (lt (match_dup 1) (const_int 0))
1398 (label_ref (match_operand 0 "" ""))
1403 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1404 && GET_CODE (sparc_compare_op0) == REG
1405 && GET_MODE (sparc_compare_op0) == DImode)
1407 emit_v9_brxx_insn (LT, sparc_compare_op0, operands[0]);
1410 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1412 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LT);
1413 emit_jump_insn (gen_bne (operands[0]));
1416 operands[1] = gen_compare_reg (LT, sparc_compare_op0, sparc_compare_op1);
1419 (define_expand "bltu"
1421 (if_then_else (ltu (match_dup 1) (const_int 0))
1422 (label_ref (match_operand 0 "" ""))
1426 { operands[1] = gen_compare_reg (LTU, sparc_compare_op0, sparc_compare_op1);
1429 (define_expand "bge"
1431 (if_then_else (ge (match_dup 1) (const_int 0))
1432 (label_ref (match_operand 0 "" ""))
1437 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1438 && GET_CODE (sparc_compare_op0) == REG
1439 && GET_MODE (sparc_compare_op0) == DImode)
1441 emit_v9_brxx_insn (GE, sparc_compare_op0, operands[0]);
1444 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1446 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GE);
1447 emit_jump_insn (gen_bne (operands[0]));
1450 operands[1] = gen_compare_reg (GE, sparc_compare_op0, sparc_compare_op1);
1453 (define_expand "bgeu"
1455 (if_then_else (geu (match_dup 1) (const_int 0))
1456 (label_ref (match_operand 0 "" ""))
1460 { operands[1] = gen_compare_reg (GEU, sparc_compare_op0, sparc_compare_op1);
1463 (define_expand "ble"
1465 (if_then_else (le (match_dup 1) (const_int 0))
1466 (label_ref (match_operand 0 "" ""))
1471 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1472 && GET_CODE (sparc_compare_op0) == REG
1473 && GET_MODE (sparc_compare_op0) == DImode)
1475 emit_v9_brxx_insn (LE, sparc_compare_op0, operands[0]);
1478 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1480 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LE);
1481 emit_jump_insn (gen_bne (operands[0]));
1484 operands[1] = gen_compare_reg (LE, sparc_compare_op0, sparc_compare_op1);
1487 (define_expand "bleu"
1489 (if_then_else (leu (match_dup 1) (const_int 0))
1490 (label_ref (match_operand 0 "" ""))
1494 { operands[1] = gen_compare_reg (LEU, sparc_compare_op0, sparc_compare_op1);
1497 (define_expand "bunordered"
1499 (if_then_else (unordered (match_dup 1) (const_int 0))
1500 (label_ref (match_operand 0 "" ""))
1505 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1507 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1,
1509 emit_jump_insn (gen_beq (operands[0]));
1512 operands[1] = gen_compare_reg (UNORDERED, sparc_compare_op0,
1516 (define_expand "bordered"
1518 (if_then_else (ordered (match_dup 1) (const_int 0))
1519 (label_ref (match_operand 0 "" ""))
1524 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1526 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, ORDERED);
1527 emit_jump_insn (gen_bne (operands[0]));
1530 operands[1] = gen_compare_reg (ORDERED, sparc_compare_op0,
1534 (define_expand "bungt"
1536 (if_then_else (ungt (match_dup 1) (const_int 0))
1537 (label_ref (match_operand 0 "" ""))
1542 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1544 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNGT);
1545 emit_jump_insn (gen_bgt (operands[0]));
1548 operands[1] = gen_compare_reg (UNGT, sparc_compare_op0, sparc_compare_op1);
1551 (define_expand "bunlt"
1553 (if_then_else (unlt (match_dup 1) (const_int 0))
1554 (label_ref (match_operand 0 "" ""))
1559 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1561 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNLT);
1562 emit_jump_insn (gen_bne (operands[0]));
1565 operands[1] = gen_compare_reg (UNLT, sparc_compare_op0, sparc_compare_op1);
1568 (define_expand "buneq"
1570 (if_then_else (uneq (match_dup 1) (const_int 0))
1571 (label_ref (match_operand 0 "" ""))
1576 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1578 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNEQ);
1579 emit_jump_insn (gen_beq (operands[0]));
1582 operands[1] = gen_compare_reg (UNEQ, sparc_compare_op0, sparc_compare_op1);
1585 (define_expand "bunge"
1587 (if_then_else (unge (match_dup 1) (const_int 0))
1588 (label_ref (match_operand 0 "" ""))
1593 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1595 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNGE);
1596 emit_jump_insn (gen_bne (operands[0]));
1599 operands[1] = gen_compare_reg (UNGE, sparc_compare_op0, sparc_compare_op1);
1602 (define_expand "bunle"
1604 (if_then_else (unle (match_dup 1) (const_int 0))
1605 (label_ref (match_operand 0 "" ""))
1610 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1612 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNLE);
1613 emit_jump_insn (gen_bne (operands[0]));
1616 operands[1] = gen_compare_reg (UNLE, sparc_compare_op0, sparc_compare_op1);
1619 (define_expand "bltgt"
1621 (if_then_else (ltgt (match_dup 1) (const_int 0))
1622 (label_ref (match_operand 0 "" ""))
1627 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1629 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LTGT);
1630 emit_jump_insn (gen_bne (operands[0]));
1633 operands[1] = gen_compare_reg (LTGT, sparc_compare_op0, sparc_compare_op1);
1636 ;; Now match both normal and inverted jump.
1638 ;; XXX fpcmp nop braindamage
1639 (define_insn "*normal_branch"
1641 (if_then_else (match_operator 0 "noov_compare_op"
1642 [(reg 100) (const_int 0)])
1643 (label_ref (match_operand 1 "" ""))
1648 return output_cbranch (operands[0], operands[1], 1, 0,
1649 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1650 ! final_sequence, insn);
1652 [(set_attr "type" "branch")
1653 (set_attr "branch_type" "icc")])
1655 ;; XXX fpcmp nop braindamage
1656 (define_insn "*inverted_branch"
1658 (if_then_else (match_operator 0 "noov_compare_op"
1659 [(reg 100) (const_int 0)])
1661 (label_ref (match_operand 1 "" ""))))]
1665 return output_cbranch (operands[0], operands[1], 1, 1,
1666 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1667 ! final_sequence, insn);
1669 [(set_attr "type" "branch")
1670 (set_attr "branch_type" "icc")])
1672 ;; XXX fpcmp nop braindamage
1673 (define_insn "*normal_fp_branch"
1675 (if_then_else (match_operator 1 "comparison_operator"
1676 [(match_operand:CCFP 0 "fcc_reg_operand" "c")
1678 (label_ref (match_operand 2 "" ""))
1683 return output_cbranch (operands[1], operands[2], 2, 0,
1684 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1685 ! final_sequence, insn);
1687 [(set_attr "type" "branch")
1688 (set_attr "branch_type" "fcc")])
1690 ;; XXX fpcmp nop braindamage
1691 (define_insn "*inverted_fp_branch"
1693 (if_then_else (match_operator 1 "comparison_operator"
1694 [(match_operand:CCFP 0 "fcc_reg_operand" "c")
1697 (label_ref (match_operand 2 "" ""))))]
1701 return output_cbranch (operands[1], operands[2], 2, 1,
1702 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1703 ! final_sequence, insn);
1705 [(set_attr "type" "branch")
1706 (set_attr "branch_type" "fcc")])
1708 ;; XXX fpcmp nop braindamage
1709 (define_insn "*normal_fpe_branch"
1711 (if_then_else (match_operator 1 "comparison_operator"
1712 [(match_operand:CCFPE 0 "fcc_reg_operand" "c")
1714 (label_ref (match_operand 2 "" ""))
1719 return output_cbranch (operands[1], operands[2], 2, 0,
1720 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1721 ! final_sequence, insn);
1723 [(set_attr "type" "branch")
1724 (set_attr "branch_type" "fcc")])
1726 ;; XXX fpcmp nop braindamage
1727 (define_insn "*inverted_fpe_branch"
1729 (if_then_else (match_operator 1 "comparison_operator"
1730 [(match_operand:CCFPE 0 "fcc_reg_operand" "c")
1733 (label_ref (match_operand 2 "" ""))))]
1737 return output_cbranch (operands[1], operands[2], 2, 1,
1738 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1739 ! final_sequence, insn);
1741 [(set_attr "type" "branch")
1742 (set_attr "branch_type" "fcc")])
1744 ;; Sparc V9-specific jump insns. None of these are guaranteed to be
1745 ;; in the architecture.
1747 ;; There are no 32 bit brreg insns.
1750 (define_insn "*normal_int_branch_sp64"
1752 (if_then_else (match_operator 0 "v9_regcmp_op"
1753 [(match_operand:DI 1 "register_operand" "r")
1755 (label_ref (match_operand 2 "" ""))
1760 return output_v9branch (operands[0], operands[2], 1, 2, 0,
1761 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1762 ! final_sequence, insn);
1764 [(set_attr "type" "branch")
1765 (set_attr "branch_type" "reg")])
1768 (define_insn "*inverted_int_branch_sp64"
1770 (if_then_else (match_operator 0 "v9_regcmp_op"
1771 [(match_operand:DI 1 "register_operand" "r")
1774 (label_ref (match_operand 2 "" ""))))]
1778 return output_v9branch (operands[0], operands[2], 1, 2, 1,
1779 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1780 ! final_sequence, insn);
1782 [(set_attr "type" "branch")
1783 (set_attr "branch_type" "reg")])
1785 ;; Load program counter insns.
1787 (define_insn "get_pc"
1788 [(clobber (reg:SI 15))
1789 (set (match_operand 0 "register_operand" "=r")
1790 (unspec [(match_operand 1 "" "") (match_operand 2 "" "")] UNSPEC_GET_PC))]
1791 "flag_pic && REGNO (operands[0]) == 23"
1792 "sethi\\t%%hi(%a1-4), %0\\n\\tcall\\t%a2\\n\\tadd\\t%0, %%lo(%a1+4), %0"
1793 [(set_attr "type" "multi")
1794 (set_attr "length" "3")])
1797 ;; Move instructions
1799 (define_expand "movqi"
1800 [(set (match_operand:QI 0 "general_operand" "")
1801 (match_operand:QI 1 "general_operand" ""))]
1805 /* Working with CONST_INTs is easier, so convert
1806 a double if needed. */
1807 if (GET_CODE (operands[1]) == CONST_DOUBLE)
1809 operands[1] = GEN_INT (trunc_int_for_mode
1810 (CONST_DOUBLE_LOW (operands[1]), QImode));
1813 /* Handle sets of MEM first. */
1814 if (GET_CODE (operands[0]) == MEM)
1816 if (reg_or_0_operand (operands[1], QImode))
1819 if (! reload_in_progress)
1821 operands[0] = validize_mem (operands[0]);
1822 operands[1] = force_reg (QImode, operands[1]);
1826 /* Fixup PIC cases. */
1829 if (CONSTANT_P (operands[1])
1830 && pic_address_needs_scratch (operands[1]))
1831 operands[1] = legitimize_pic_address (operands[1], QImode, 0);
1833 if (symbolic_operand (operands[1], QImode))
1835 operands[1] = legitimize_pic_address (operands[1],
1837 (reload_in_progress ?
1844 /* All QI constants require only one insn, so proceed. */
1850 (define_insn "*movqi_insn"
1851 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m")
1852 (match_operand:QI 1 "input_operand" "rI,m,rJ"))]
1853 "(register_operand (operands[0], QImode)
1854 || reg_or_0_operand (operands[1], QImode))"
1859 [(set_attr "type" "*,load,store")
1860 (set_attr "us3load_type" "*,3cycle,*")])
1862 (define_expand "movhi"
1863 [(set (match_operand:HI 0 "general_operand" "")
1864 (match_operand:HI 1 "general_operand" ""))]
1868 /* Working with CONST_INTs is easier, so convert
1869 a double if needed. */
1870 if (GET_CODE (operands[1]) == CONST_DOUBLE)
1871 operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
1873 /* Handle sets of MEM first. */
1874 if (GET_CODE (operands[0]) == MEM)
1876 if (reg_or_0_operand (operands[1], HImode))
1879 if (! reload_in_progress)
1881 operands[0] = validize_mem (operands[0]);
1882 operands[1] = force_reg (HImode, operands[1]);
1886 /* Fixup PIC cases. */
1889 if (CONSTANT_P (operands[1])
1890 && pic_address_needs_scratch (operands[1]))
1891 operands[1] = legitimize_pic_address (operands[1], HImode, 0);
1893 if (symbolic_operand (operands[1], HImode))
1895 operands[1] = legitimize_pic_address (operands[1],
1897 (reload_in_progress ?
1904 /* This makes sure we will not get rematched due to splittage. */
1905 if (! CONSTANT_P (operands[1]) || input_operand (operands[1], HImode))
1907 else if (CONSTANT_P (operands[1])
1908 && GET_CODE (operands[1]) != HIGH
1909 && GET_CODE (operands[1]) != LO_SUM)
1911 sparc_emit_set_const32 (operands[0], operands[1]);
1918 (define_insn "*movhi_const64_special"
1919 [(set (match_operand:HI 0 "register_operand" "=r")
1920 (match_operand:HI 1 "const64_high_operand" ""))]
1922 "sethi\\t%%hi(%a1), %0")
1924 (define_insn "*movhi_insn"
1925 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1926 (match_operand:HI 1 "input_operand" "rI,K,m,rJ"))]
1927 "(register_operand (operands[0], HImode)
1928 || reg_or_0_operand (operands[1], HImode))"
1931 sethi\\t%%hi(%a1), %0
1934 [(set_attr "type" "*,*,load,store")
1935 (set_attr "us3load_type" "*,*,3cycle,*")])
1937 ;; We always work with constants here.
1938 (define_insn "*movhi_lo_sum"
1939 [(set (match_operand:HI 0 "register_operand" "=r")
1940 (ior:HI (match_operand:HI 1 "arith_operand" "%r")
1941 (match_operand:HI 2 "arith_operand" "I")))]
1945 (define_expand "movsi"
1946 [(set (match_operand:SI 0 "general_operand" "")
1947 (match_operand:SI 1 "general_operand" ""))]
1951 /* Working with CONST_INTs is easier, so convert
1952 a double if needed. */
1953 if (GET_CODE (operands[1]) == CONST_DOUBLE)
1954 operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
1956 /* Handle sets of MEM first. */
1957 if (GET_CODE (operands[0]) == MEM)
1959 if (reg_or_0_operand (operands[1], SImode))
1962 if (! reload_in_progress)
1964 operands[0] = validize_mem (operands[0]);
1965 operands[1] = force_reg (SImode, operands[1]);
1969 /* Fixup PIC cases. */
1972 if (CONSTANT_P (operands[1])
1973 && pic_address_needs_scratch (operands[1]))
1974 operands[1] = legitimize_pic_address (operands[1], SImode, 0);
1976 if (GET_CODE (operands[1]) == LABEL_REF)
1979 emit_insn (gen_movsi_pic_label_ref (operands[0], operands[1]));
1983 if (symbolic_operand (operands[1], SImode))
1985 operands[1] = legitimize_pic_address (operands[1],
1987 (reload_in_progress ?
1994 /* If we are trying to toss an integer constant into the
1995 FPU registers, force it into memory. */
1996 if (GET_CODE (operands[0]) == REG
1997 && REGNO (operands[0]) >= SPARC_FIRST_FP_REG
1998 && REGNO (operands[0]) <= SPARC_LAST_V9_FP_REG
1999 && CONSTANT_P (operands[1]))
2000 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
2003 /* This makes sure we will not get rematched due to splittage. */
2004 if (! CONSTANT_P (operands[1]) || input_operand (operands[1], SImode))
2006 else if (CONSTANT_P (operands[1])
2007 && GET_CODE (operands[1]) != HIGH
2008 && GET_CODE (operands[1]) != LO_SUM)
2010 sparc_emit_set_const32 (operands[0], operands[1]);
2017 ;; This is needed to show CSE exactly which bits are set
2018 ;; in a 64-bit register by sethi instructions.
2019 (define_insn "*movsi_const64_special"
2020 [(set (match_operand:SI 0 "register_operand" "=r")
2021 (match_operand:SI 1 "const64_high_operand" ""))]
2023 "sethi\\t%%hi(%a1), %0")
2025 (define_insn "*movsi_insn"
2026 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,f,r,r,r,f,m,m,d")
2027 (match_operand:SI 1 "input_operand" "rI,!f,K,J,m,!m,rJ,!f,J"))]
2028 "(register_operand (operands[0], SImode)
2029 || reg_or_0_operand (operands[1], SImode))"
2033 sethi\\t%%hi(%a1), %0
2040 [(set_attr "type" "*,fpmove,*,*,load,fpload,store,fpstore,fpmove")])
2042 (define_insn "*movsi_lo_sum"
2043 [(set (match_operand:SI 0 "register_operand" "=r")
2044 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
2045 (match_operand:SI 2 "immediate_operand" "in")))]
2047 "or\\t%1, %%lo(%a2), %0")
2049 (define_insn "*movsi_high"
2050 [(set (match_operand:SI 0 "register_operand" "=r")
2051 (high:SI (match_operand:SI 1 "immediate_operand" "in")))]
2053 "sethi\\t%%hi(%a1), %0")
2055 ;; The next two patterns must wrap the SYMBOL_REF in an UNSPEC
2056 ;; so that CSE won't optimize the address computation away.
2057 (define_insn "movsi_lo_sum_pic"
2058 [(set (match_operand:SI 0 "register_operand" "=r")
2059 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
2060 (unspec:SI [(match_operand:SI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
2062 "or\\t%1, %%lo(%a2), %0")
2064 (define_insn "movsi_high_pic"
2065 [(set (match_operand:SI 0 "register_operand" "=r")
2066 (high:SI (unspec:SI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
2067 "flag_pic && check_pic (1)"
2068 "sethi\\t%%hi(%a1), %0")
2070 (define_expand "movsi_pic_label_ref"
2071 [(set (match_dup 3) (high:SI
2072 (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
2073 (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
2074 (set (match_dup 4) (lo_sum:SI (match_dup 3)
2075 (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
2076 (set (match_operand:SI 0 "register_operand" "=r")
2077 (minus:SI (match_dup 5) (match_dup 4)))]
2081 current_function_uses_pic_offset_table = 1;
2082 operands[2] = gen_rtx_SYMBOL_REF (Pmode, \"_GLOBAL_OFFSET_TABLE_\");
2085 operands[3] = operands[0];
2086 operands[4] = operands[0];
2090 operands[3] = gen_reg_rtx (SImode);
2091 operands[4] = gen_reg_rtx (SImode);
2093 operands[5] = pic_offset_table_rtx;
2096 (define_insn "*movsi_high_pic_label_ref"
2097 [(set (match_operand:SI 0 "register_operand" "=r")
2099 (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
2100 (match_operand:SI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
2102 "sethi\\t%%hi(%a2-(%a1-.)), %0")
2104 (define_insn "*movsi_lo_sum_pic_label_ref"
2105 [(set (match_operand:SI 0 "register_operand" "=r")
2106 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
2107 (unspec:SI [(match_operand:SI 2 "label_ref_operand" "")
2108 (match_operand:SI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
2110 "or\\t%1, %%lo(%a3-(%a2-.)), %0")
2112 (define_expand "movdi"
2113 [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand" "")
2114 (match_operand:DI 1 "general_operand" ""))]
2118 /* Where possible, convert CONST_DOUBLE into a CONST_INT. */
2119 if (GET_CODE (operands[1]) == CONST_DOUBLE
2120 #if HOST_BITS_PER_WIDE_INT == 32
2121 && ((CONST_DOUBLE_HIGH (operands[1]) == 0
2122 && (CONST_DOUBLE_LOW (operands[1]) & 0x80000000) == 0)
2123 || (CONST_DOUBLE_HIGH (operands[1]) == (HOST_WIDE_INT) 0xffffffff
2124 && (CONST_DOUBLE_LOW (operands[1]) & 0x80000000) != 0))
2127 operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
2129 /* Handle MEM cases first. */
2130 if (GET_CODE (operands[0]) == MEM)
2132 /* If it's a REG, we can always do it.
2133 The const zero case is more complex, on v9
2134 we can always perform it. */
2135 if (register_operand (operands[1], DImode)
2137 && (operands[1] == const0_rtx)))
2140 if (! reload_in_progress)
2142 operands[0] = validize_mem (operands[0]);
2143 operands[1] = force_reg (DImode, operands[1]);
2149 if (CONSTANT_P (operands[1])
2150 && pic_address_needs_scratch (operands[1]))
2151 operands[1] = legitimize_pic_address (operands[1], DImode, 0);
2153 if (GET_CODE (operands[1]) == LABEL_REF)
2155 if (! TARGET_ARCH64)
2157 emit_insn (gen_movdi_pic_label_ref (operands[0], operands[1]));
2161 if (symbolic_operand (operands[1], DImode))
2163 operands[1] = legitimize_pic_address (operands[1],
2165 (reload_in_progress ?
2172 /* If we are trying to toss an integer constant into the
2173 FPU registers, force it into memory. */
2174 if (GET_CODE (operands[0]) == REG
2175 && REGNO (operands[0]) >= SPARC_FIRST_FP_REG
2176 && REGNO (operands[0]) <= SPARC_LAST_V9_FP_REG
2177 && CONSTANT_P (operands[1]))
2178 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
2181 /* This makes sure we will not get rematched due to splittage. */
2182 if (! CONSTANT_P (operands[1]) || input_operand (operands[1], DImode))
2184 else if (TARGET_ARCH64
2185 && CONSTANT_P (operands[1])
2186 && GET_CODE (operands[1]) != HIGH
2187 && GET_CODE (operands[1]) != LO_SUM)
2189 sparc_emit_set_const64 (operands[0], operands[1]);
2197 ;; Be careful, fmovd does not exist when !arch64.
2198 ;; We match MEM moves directly when we have correct even
2199 ;; numbered registers, but fall into splits otherwise.
2200 ;; The constraint ordering here is really important to
2201 ;; avoid insane problems in reload, especially for patterns
2204 ;; (set (mem:DI (plus:SI (reg:SI 30 %fp)
2205 ;; (const_int -5016)))
2209 (define_insn "*movdi_insn_sp32_v9"
2210 [(set (match_operand:DI 0 "nonimmediate_operand"
2211 "=T,o,T,U,o,r,r,r,?T,?f,?f,?o,?f")
2212 (match_operand:DI 1 "input_operand"
2213 " J,J,U,T,r,o,i,r, f, T, o, f, f"))]
2214 "! TARGET_ARCH64 && TARGET_V9
2215 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2230 [(set_attr "type" "store,store,store,load,*,*,*,*,fpstore,fpload,*,*,*")
2231 (set_attr "length" "*,2,*,*,2,2,2,2,*,*,2,2,2")])
2233 (define_insn "*movdi_insn_sp32"
2234 [(set (match_operand:DI 0 "nonimmediate_operand"
2235 "=o,T,U,o,r,r,r,?T,?f,?f,?o,?f")
2236 (match_operand:DI 1 "input_operand"
2237 " J,U,T,r,o,i,r, f, T, o, f, f"))]
2239 && (register_operand (operands[0], DImode)
2240 || register_operand (operands[1], DImode))"
2254 [(set_attr "type" "store,store,load,*,*,*,*,fpstore,fpload,*,*,*")
2255 (set_attr "length" "2,*,*,2,2,2,2,*,*,2,2,2")])
2257 ;; The following are generated by sparc_emit_set_const64
2258 (define_insn "*movdi_sp64_dbl"
2259 [(set (match_operand:DI 0 "register_operand" "=r")
2260 (match_operand:DI 1 "const64_operand" ""))]
2262 && HOST_BITS_PER_WIDE_INT != 64)"
2265 ;; This is needed to show CSE exactly which bits are set
2266 ;; in a 64-bit register by sethi instructions.
2267 (define_insn "*movdi_const64_special"
2268 [(set (match_operand:DI 0 "register_operand" "=r")
2269 (match_operand:DI 1 "const64_high_operand" ""))]
2271 "sethi\\t%%hi(%a1), %0")
2273 (define_insn "*movdi_insn_sp64_novis"
2274 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,m,?e,?e,?W")
2275 (match_operand:DI 1 "input_operand" "rI,N,J,m,rJ,e,W,e"))]
2276 "TARGET_ARCH64 && ! TARGET_VIS
2277 && (register_operand (operands[0], DImode)
2278 || reg_or_0_operand (operands[1], DImode))"
2281 sethi\\t%%hi(%a1), %0
2288 [(set_attr "type" "*,*,*,load,store,fpmove,fpload,fpstore")
2289 (set_attr "fptype" "*,*,*,*,*,double,*,*")])
2291 (define_insn "*movdi_insn_sp64_vis"
2292 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,m,?e,?e,?W,b")
2293 (match_operand:DI 1 "input_operand" "rI,N,J,m,rJ,e,W,e,J"))]
2294 "TARGET_ARCH64 && TARGET_VIS &&
2295 (register_operand (operands[0], DImode)
2296 || reg_or_0_operand (operands[1], DImode))"
2299 sethi\\t%%hi(%a1), %0
2307 [(set_attr "type" "*,*,*,load,store,fpmove,fpload,fpstore,fpmove")
2308 (set_attr "fptype" "*,*,*,*,*,double,*,*,double")])
2310 (define_expand "movdi_pic_label_ref"
2311 [(set (match_dup 3) (high:DI
2312 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
2313 (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
2314 (set (match_dup 4) (lo_sum:DI (match_dup 3)
2315 (unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
2316 (set (match_operand:DI 0 "register_operand" "=r")
2317 (minus:DI (match_dup 5) (match_dup 4)))]
2318 "TARGET_ARCH64 && flag_pic"
2321 current_function_uses_pic_offset_table = 1;
2322 operands[2] = gen_rtx_SYMBOL_REF (Pmode, \"_GLOBAL_OFFSET_TABLE_\");
2325 operands[3] = operands[0];
2326 operands[4] = operands[0];
2330 operands[3] = gen_reg_rtx (DImode);
2331 operands[4] = gen_reg_rtx (DImode);
2333 operands[5] = pic_offset_table_rtx;
2336 (define_insn "*movdi_high_pic_label_ref"
2337 [(set (match_operand:DI 0 "register_operand" "=r")
2339 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
2340 (match_operand:DI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
2341 "TARGET_ARCH64 && flag_pic"
2342 "sethi\\t%%hi(%a2-(%a1-.)), %0")
2344 (define_insn "*movdi_lo_sum_pic_label_ref"
2345 [(set (match_operand:DI 0 "register_operand" "=r")
2346 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2347 (unspec:DI [(match_operand:DI 2 "label_ref_operand" "")
2348 (match_operand:DI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
2349 "TARGET_ARCH64 && flag_pic"
2350 "or\\t%1, %%lo(%a3-(%a2-.)), %0")
2352 ;; Sparc-v9 code model support insns. See sparc_emit_set_symbolic_const64
2353 ;; in sparc.c to see what is going on here... PIC stuff comes first.
2355 (define_insn "movdi_lo_sum_pic"
2356 [(set (match_operand:DI 0 "register_operand" "=r")
2357 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2358 (unspec:DI [(match_operand:DI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
2359 "TARGET_ARCH64 && flag_pic"
2360 "or\\t%1, %%lo(%a2), %0")
2362 (define_insn "movdi_high_pic"
2363 [(set (match_operand:DI 0 "register_operand" "=r")
2364 (high:DI (unspec:DI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
2365 "TARGET_ARCH64 && flag_pic && check_pic (1)"
2366 "sethi\\t%%hi(%a1), %0")
2368 (define_insn "*sethi_di_medlow_embmedany_pic"
2369 [(set (match_operand:DI 0 "register_operand" "=r")
2370 (high:DI (match_operand:DI 1 "sp64_medium_pic_operand" "")))]
2371 "(TARGET_CM_MEDLOW || TARGET_CM_EMBMEDANY) && check_pic (1)"
2372 "sethi\\t%%hi(%a1), %0")
2374 (define_insn "*sethi_di_medlow"
2375 [(set (match_operand:DI 0 "register_operand" "=r")
2376 (high:DI (match_operand:DI 1 "symbolic_operand" "")))]
2377 "TARGET_CM_MEDLOW && check_pic (1)"
2378 "sethi\\t%%hi(%a1), %0")
2380 (define_insn "*losum_di_medlow"
2381 [(set (match_operand:DI 0 "register_operand" "=r")
2382 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2383 (match_operand:DI 2 "symbolic_operand" "")))]
2385 "or\\t%1, %%lo(%a2), %0")
2387 (define_insn "seth44"
2388 [(set (match_operand:DI 0 "register_operand" "=r")
2389 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETH44)))]
2391 "sethi\\t%%h44(%a1), %0")
2393 (define_insn "setm44"
2394 [(set (match_operand:DI 0 "register_operand" "=r")
2395 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2396 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_SETM44)))]
2398 "or\\t%1, %%m44(%a2), %0")
2400 (define_insn "setl44"
2401 [(set (match_operand:DI 0 "register_operand" "=r")
2402 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2403 (match_operand:DI 2 "symbolic_operand" "")))]
2405 "or\\t%1, %%l44(%a2), %0")
2407 (define_insn "sethh"
2408 [(set (match_operand:DI 0 "register_operand" "=r")
2409 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETHH)))]
2411 "sethi\\t%%hh(%a1), %0")
2413 (define_insn "setlm"
2414 [(set (match_operand:DI 0 "register_operand" "=r")
2415 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETLM)))]
2417 "sethi\\t%%lm(%a1), %0")
2419 (define_insn "sethm"
2420 [(set (match_operand:DI 0 "register_operand" "=r")
2421 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2422 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_EMB_SETHM)))]
2424 "or\\t%1, %%hm(%a2), %0")
2426 (define_insn "setlo"
2427 [(set (match_operand:DI 0 "register_operand" "=r")
2428 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2429 (match_operand:DI 2 "symbolic_operand" "")))]
2431 "or\\t%1, %%lo(%a2), %0")
2433 (define_insn "embmedany_sethi"
2434 [(set (match_operand:DI 0 "register_operand" "=r")
2435 (high:DI (unspec:DI [(match_operand:DI 1 "data_segment_operand" "")] UNSPEC_EMB_HISUM)))]
2436 "TARGET_CM_EMBMEDANY && check_pic (1)"
2437 "sethi\\t%%hi(%a1), %0")
2439 (define_insn "embmedany_losum"
2440 [(set (match_operand:DI 0 "register_operand" "=r")
2441 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2442 (match_operand:DI 2 "data_segment_operand" "")))]
2443 "TARGET_CM_EMBMEDANY"
2444 "add\\t%1, %%lo(%a2), %0")
2446 (define_insn "embmedany_brsum"
2447 [(set (match_operand:DI 0 "register_operand" "=r")
2448 (unspec:DI [(match_operand:DI 1 "register_operand" "r")] UNSPEC_EMB_HISUM))]
2449 "TARGET_CM_EMBMEDANY"
2452 (define_insn "embmedany_textuhi"
2453 [(set (match_operand:DI 0 "register_operand" "=r")
2454 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTUHI)))]
2455 "TARGET_CM_EMBMEDANY && check_pic (1)"
2456 "sethi\\t%%uhi(%a1), %0")
2458 (define_insn "embmedany_texthi"
2459 [(set (match_operand:DI 0 "register_operand" "=r")
2460 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTHI)))]
2461 "TARGET_CM_EMBMEDANY && check_pic (1)"
2462 "sethi\\t%%hi(%a1), %0")
2464 (define_insn "embmedany_textulo"
2465 [(set (match_operand:DI 0 "register_operand" "=r")
2466 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2467 (unspec:DI [(match_operand:DI 2 "text_segment_operand" "")] UNSPEC_EMB_TEXTULO)))]
2468 "TARGET_CM_EMBMEDANY"
2469 "or\\t%1, %%ulo(%a2), %0")
2471 (define_insn "embmedany_textlo"
2472 [(set (match_operand:DI 0 "register_operand" "=r")
2473 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2474 (match_operand:DI 2 "text_segment_operand" "")))]
2475 "TARGET_CM_EMBMEDANY"
2476 "or\\t%1, %%lo(%a2), %0")
2478 ;; Now some patterns to help reload out a bit.
2479 (define_expand "reload_indi"
2480 [(parallel [(match_operand:DI 0 "register_operand" "=r")
2481 (match_operand:DI 1 "immediate_operand" "")
2482 (match_operand:TI 2 "register_operand" "=&r")])]
2484 || TARGET_CM_EMBMEDANY)
2488 sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
2492 (define_expand "reload_outdi"
2493 [(parallel [(match_operand:DI 0 "register_operand" "=r")
2494 (match_operand:DI 1 "immediate_operand" "")
2495 (match_operand:TI 2 "register_operand" "=&r")])]
2497 || TARGET_CM_EMBMEDANY)
2501 sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
2505 ;; Split up putting CONSTs and REGs into DI regs when !arch64
2507 [(set (match_operand:DI 0 "register_operand" "")
2508 (match_operand:DI 1 "const_int_operand" ""))]
2509 "! TARGET_ARCH64 && reload_completed"
2510 [(clobber (const_int 0))]
2513 #if HOST_BITS_PER_WIDE_INT == 32
2514 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
2515 (INTVAL (operands[1]) < 0) ?
2518 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2521 unsigned int low, high;
2523 low = trunc_int_for_mode (INTVAL (operands[1]), SImode);
2524 high = trunc_int_for_mode (INTVAL (operands[1]) >> 32, SImode);
2525 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), GEN_INT (high)));
2527 /* Slick... but this trick loses if this subreg constant part
2528 can be done in one insn. */
2529 if (low == high && (low & 0x3ff) != 0 && low + 0x1000 >= 0x2000)
2530 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2531 gen_highpart (SImode, operands[0])));
2533 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), GEN_INT (low)));
2539 [(set (match_operand:DI 0 "register_operand" "")
2540 (match_operand:DI 1 "const_double_operand" ""))]
2541 "! TARGET_ARCH64 && reload_completed"
2542 [(clobber (const_int 0))]
2545 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
2546 GEN_INT (CONST_DOUBLE_HIGH (operands[1]))));
2548 /* Slick... but this trick loses if this subreg constant part
2549 can be done in one insn. */
2550 if (CONST_DOUBLE_LOW (operands[1]) == CONST_DOUBLE_HIGH (operands[1])
2551 && !(SPARC_SETHI32_P (CONST_DOUBLE_HIGH (operands[1]))
2552 || SPARC_SIMM13_P (CONST_DOUBLE_HIGH (operands[1]))))
2554 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2555 gen_highpart (SImode, operands[0])));
2559 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2560 GEN_INT (CONST_DOUBLE_LOW (operands[1]))));
2566 [(set (match_operand:DI 0 "register_operand" "")
2567 (match_operand:DI 1 "register_operand" ""))]
2568 "! TARGET_ARCH64 && reload_completed"
2569 [(clobber (const_int 0))]
2572 rtx set_dest = operands[0];
2573 rtx set_src = operands[1];
2577 dest1 = gen_highpart (SImode, set_dest);
2578 dest2 = gen_lowpart (SImode, set_dest);
2579 src1 = gen_highpart (SImode, set_src);
2580 src2 = gen_lowpart (SImode, set_src);
2582 /* Now emit using the real source and destination we found, swapping
2583 the order if we detect overlap. */
2584 if (reg_overlap_mentioned_p (dest1, src2))
2586 emit_insn (gen_movsi (dest2, src2));
2587 emit_insn (gen_movsi (dest1, src1));
2591 emit_insn (gen_movsi (dest1, src1));
2592 emit_insn (gen_movsi (dest2, src2));
2597 ;; Now handle the cases of memory moves from/to non-even
2598 ;; DI mode register pairs.
2600 [(set (match_operand:DI 0 "register_operand" "")
2601 (match_operand:DI 1 "memory_operand" ""))]
2604 && sparc_splitdi_legitimate (operands[0], operands[1]))"
2605 [(clobber (const_int 0))]
2608 rtx word0 = adjust_address (operands[1], SImode, 0);
2609 rtx word1 = adjust_address (operands[1], SImode, 4);
2610 rtx high_part = gen_highpart (SImode, operands[0]);
2611 rtx low_part = gen_lowpart (SImode, operands[0]);
2613 if (reg_overlap_mentioned_p (high_part, word1))
2615 emit_insn (gen_movsi (low_part, word1));
2616 emit_insn (gen_movsi (high_part, word0));
2620 emit_insn (gen_movsi (high_part, word0));
2621 emit_insn (gen_movsi (low_part, word1));
2627 [(set (match_operand:DI 0 "memory_operand" "")
2628 (match_operand:DI 1 "register_operand" ""))]
2631 && sparc_splitdi_legitimate (operands[1], operands[0]))"
2632 [(clobber (const_int 0))]
2635 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0),
2636 gen_highpart (SImode, operands[1])));
2637 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4),
2638 gen_lowpart (SImode, operands[1])));
2643 [(set (match_operand:DI 0 "memory_operand" "")
2648 && ! mem_min_alignment (operands[0], 8)))
2649 && offsettable_memref_p (operands[0])"
2650 [(clobber (const_int 0))]
2653 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0), const0_rtx));
2654 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4), const0_rtx));
2658 ;; Floating point move insns
2660 (define_insn "*movsf_insn_novis"
2661 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,*r,*r,*r,*r,*r,f,m,m")
2662 (match_operand:SF 1 "input_operand" "f,G,Q,*rR,S,m,m,f,*rG"))]
2663 "(TARGET_FPU && ! TARGET_VIS)
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 == 2
2671 || which_alternative == 3
2672 || which_alternative == 4))
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 \"fmovs\\t%1, %0\";
2687 return \"clr\\t%0\";
2689 return \"sethi\\t%%hi(%a1), %0\";
2691 return \"mov\\t%1, %0\";
2696 return \"ld\\t%1, %0\";
2699 return \"st\\t%r1, %0\";
2704 [(set_attr "type" "fpmove,*,*,*,*,load,fpload,fpstore,store")])
2706 (define_insn "*movsf_insn_vis"
2707 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,*r,*r,*r,*r,*r,f,m,m")
2708 (match_operand:SF 1 "input_operand" "f,G,G,Q,*rR,S,m,m,f,*rG"))]
2709 "(TARGET_FPU && TARGET_VIS)
2710 && (register_operand (operands[0], SFmode)
2711 || register_operand (operands[1], SFmode)
2712 || fp_zero_operand (operands[1], SFmode))"
2715 if (GET_CODE (operands[1]) == CONST_DOUBLE
2716 && (which_alternative == 3
2717 || which_alternative == 4
2718 || which_alternative == 5))
2723 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2724 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2725 operands[1] = GEN_INT (i);
2728 switch (which_alternative)
2731 return \"fmovs\\t%1, %0\";
2733 return \"fzeros\\t%0\";
2735 return \"clr\\t%0\";
2737 return \"sethi\\t%%hi(%a1), %0\";
2739 return \"mov\\t%1, %0\";
2744 return \"ld\\t%1, %0\";
2747 return \"st\\t%r1, %0\";
2752 [(set_attr "type" "fpmove,fpmove,*,*,*,*,load,fpload,fpstore,store")])
2754 ;; Exactly the same as above, except that all `f' cases are deleted.
2755 ;; This is necessary to prevent reload from ever trying to use a `f' reg
2758 (define_insn "*movsf_no_f_insn"
2759 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r,r,r,m")
2760 (match_operand:SF 1 "input_operand" "G,Q,rR,S,m,rG"))]
2762 && (register_operand (operands[0], SFmode)
2763 || register_operand (operands[1], SFmode)
2764 || fp_zero_operand (operands[1], SFmode))"
2767 if (GET_CODE (operands[1]) == CONST_DOUBLE
2768 && (which_alternative == 1
2769 || which_alternative == 2
2770 || which_alternative == 3))
2775 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2776 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2777 operands[1] = GEN_INT (i);
2780 switch (which_alternative)
2783 return \"clr\\t%0\";
2785 return \"sethi\\t%%hi(%a1), %0\";
2787 return \"mov\\t%1, %0\";
2791 return \"ld\\t%1, %0\";
2793 return \"st\\t%r1, %0\";
2798 [(set_attr "type" "*,*,*,*,load,store")])
2800 (define_insn "*movsf_lo_sum"
2801 [(set (match_operand:SF 0 "register_operand" "=r")
2802 (lo_sum:SF (match_operand:SF 1 "register_operand" "r")
2803 (match_operand:SF 2 "const_double_operand" "S")))]
2804 "fp_high_losum_p (operands[2])"
2810 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[2]);
2811 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2812 operands[2] = GEN_INT (i);
2813 return \"or\\t%1, %%lo(%a2), %0\";
2816 (define_insn "*movsf_high"
2817 [(set (match_operand:SF 0 "register_operand" "=r")
2818 (high:SF (match_operand:SF 1 "const_double_operand" "S")))]
2819 "fp_high_losum_p (operands[1])"
2825 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2826 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2827 operands[1] = GEN_INT (i);
2828 return \"sethi\\t%%hi(%1), %0\";
2832 [(set (match_operand:SF 0 "register_operand" "")
2833 (match_operand:SF 1 "const_double_operand" ""))]
2834 "fp_high_losum_p (operands[1])
2835 && (GET_CODE (operands[0]) == REG
2836 && REGNO (operands[0]) < 32)"
2837 [(set (match_dup 0) (high:SF (match_dup 1)))
2838 (set (match_dup 0) (lo_sum:SF (match_dup 0) (match_dup 1)))])
2840 (define_expand "movsf"
2841 [(set (match_operand:SF 0 "general_operand" "")
2842 (match_operand:SF 1 "general_operand" ""))]
2846 /* Force SFmode constants into memory. */
2847 if (GET_CODE (operands[0]) == REG
2848 && CONSTANT_P (operands[1]))
2850 /* emit_group_store will send such bogosity to us when it is
2851 not storing directly into memory. So fix this up to avoid
2852 crashes in output_constant_pool. */
2853 if (operands [1] == const0_rtx)
2854 operands[1] = CONST0_RTX (SFmode);
2856 if (TARGET_VIS && fp_zero_operand (operands[1], SFmode))
2859 /* We are able to build any SF constant in integer registers
2860 with at most 2 instructions. */
2861 if (REGNO (operands[0]) < 32)
2864 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
2868 /* Handle sets of MEM first. */
2869 if (GET_CODE (operands[0]) == MEM)
2871 if (register_operand (operands[1], SFmode)
2872 || fp_zero_operand (operands[1], SFmode))
2875 if (! reload_in_progress)
2877 operands[0] = validize_mem (operands[0]);
2878 operands[1] = force_reg (SFmode, operands[1]);
2882 /* Fixup PIC cases. */
2885 if (CONSTANT_P (operands[1])
2886 && pic_address_needs_scratch (operands[1]))
2887 operands[1] = legitimize_pic_address (operands[1], SFmode, 0);
2889 if (symbolic_operand (operands[1], SFmode))
2891 operands[1] = legitimize_pic_address (operands[1],
2893 (reload_in_progress ?
2903 (define_expand "movdf"
2904 [(set (match_operand:DF 0 "general_operand" "")
2905 (match_operand:DF 1 "general_operand" ""))]
2909 /* Force DFmode constants into memory. */
2910 if (GET_CODE (operands[0]) == REG
2911 && CONSTANT_P (operands[1]))
2913 /* emit_group_store will send such bogosity to us when it is
2914 not storing directly into memory. So fix this up to avoid
2915 crashes in output_constant_pool. */
2916 if (operands [1] == const0_rtx)
2917 operands[1] = CONST0_RTX (DFmode);
2919 if ((TARGET_VIS || REGNO (operands[0]) < 32)
2920 && fp_zero_operand (operands[1], DFmode))
2923 /* We are able to build any DF constant in integer registers. */
2924 if (REGNO (operands[0]) < 32
2925 && (reload_completed || reload_in_progress))
2928 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
2932 /* Handle MEM cases first. */
2933 if (GET_CODE (operands[0]) == MEM)
2935 if (register_operand (operands[1], DFmode)
2936 || fp_zero_operand (operands[1], DFmode))
2939 if (! reload_in_progress)
2941 operands[0] = validize_mem (operands[0]);
2942 operands[1] = force_reg (DFmode, operands[1]);
2946 /* Fixup PIC cases. */
2949 if (CONSTANT_P (operands[1])
2950 && pic_address_needs_scratch (operands[1]))
2951 operands[1] = legitimize_pic_address (operands[1], DFmode, 0);
2953 if (symbolic_operand (operands[1], DFmode))
2955 operands[1] = legitimize_pic_address (operands[1],
2957 (reload_in_progress ?
2967 ;; Be careful, fmovd does not exist when !v9.
2968 (define_insn "*movdf_insn_sp32"
2969 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,W,U,T,o,e,*r,o,e,o")
2970 (match_operand:DF 1 "input_operand" "W#F,e,T,U,G,e,*rFo,*r,o#F,e"))]
2973 && (register_operand (operands[0], DFmode)
2974 || register_operand (operands[1], DFmode)
2975 || fp_zero_operand (operands[1], DFmode))"
2987 [(set_attr "type" "fpload,fpstore,load,store,*,*,*,*,*,*")
2988 (set_attr "length" "*,*,*,*,2,2,2,2,2,2")])
2990 (define_insn "*movdf_no_e_insn_sp32"
2991 [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,o,r,o")
2992 (match_operand:DF 1 "input_operand" "T,U,G,ro,r"))]
2996 && (register_operand (operands[0], DFmode)
2997 || register_operand (operands[1], DFmode)
2998 || fp_zero_operand (operands[1], DFmode))"
3005 [(set_attr "type" "load,store,*,*,*")
3006 (set_attr "length" "*,*,2,2,2")])
3008 (define_insn "*movdf_no_e_insn_v9_sp32"
3009 [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,T,r,o")
3010 (match_operand:DF 1 "input_operand" "T,U,G,ro,rG"))]
3014 && (register_operand (operands[0], DFmode)
3015 || register_operand (operands[1], DFmode)
3016 || fp_zero_operand (operands[1], DFmode))"
3023 [(set_attr "type" "load,store,store,*,*")
3024 (set_attr "length" "*,*,*,2,2")])
3026 ;; We have available v9 double floats but not 64-bit
3027 ;; integer registers and no VIS.
3028 (define_insn "*movdf_insn_v9only_novis"
3029 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,T,W,U,T,f,*r,o")
3030 (match_operand:DF 1 "input_operand" "e,W#F,G,e,T,U,o#F,*roF,*rGf"))]
3035 && (register_operand (operands[0], DFmode)
3036 || register_operand (operands[1], DFmode)
3037 || fp_zero_operand (operands[1], DFmode))"
3048 [(set_attr "type" "fpmove,load,store,store,load,store,*,*,*")
3049 (set_attr "length" "*,*,*,*,*,*,2,2,2")
3050 (set_attr "fptype" "double,*,*,*,*,*,*,*,*")])
3052 ;; We have available v9 double floats but not 64-bit
3053 ;; integer registers but we have VIS.
3054 (define_insn "*movdf_insn_v9only_vis"
3055 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,e,T,W,U,T,f,*r,o")
3056 (match_operand:DF 1 "input_operand" "G,e,W#F,G,e,T,U,o#F,*roGF,*rGf"))]
3060 && (register_operand (operands[0], DFmode)
3061 || register_operand (operands[1], DFmode)
3062 || fp_zero_operand (operands[1], DFmode))"
3074 [(set_attr "type" "fpmove,fpmove,load,store,store,load,store,*,*,*")
3075 (set_attr "length" "*,*,*,*,*,*,*,2,2,2")
3076 (set_attr "fptype" "double,double,*,*,*,*,*,*,*,*")])
3078 ;; We have available both v9 double floats and 64-bit
3079 ;; integer registers. No VIS though.
3080 (define_insn "*movdf_insn_sp64_novis"
3081 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,W,*r,*r,m,*r")
3082 (match_operand:DF 1 "input_operand" "e,W#F,e,*rG,m,*rG,F"))]
3086 && (register_operand (operands[0], DFmode)
3087 || register_operand (operands[1], DFmode)
3088 || fp_zero_operand (operands[1], DFmode))"
3097 [(set_attr "type" "fpmove,load,store,*,load,store,*")
3098 (set_attr "length" "*,*,*,*,*,*,2")
3099 (set_attr "fptype" "double,*,*,*,*,*,*")])
3101 ;; We have available both v9 double floats and 64-bit
3102 ;; integer registers. And we have VIS.
3103 (define_insn "*movdf_insn_sp64_vis"
3104 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,e,W,*r,*r,m,*r")
3105 (match_operand:DF 1 "input_operand" "G,e,W#F,e,*rG,m,*rG,F"))]
3109 && (register_operand (operands[0], DFmode)
3110 || register_operand (operands[1], DFmode)
3111 || fp_zero_operand (operands[1], DFmode))"
3121 [(set_attr "type" "fpmove,fpmove,load,store,*,load,store,*")
3122 (set_attr "length" "*,*,*,*,*,*,*,2")
3123 (set_attr "fptype" "double,double,*,*,*,*,*,*")])
3125 (define_insn "*movdf_no_e_insn_sp64"
3126 [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m")
3127 (match_operand:DF 1 "input_operand" "r,m,rG"))]
3130 && (register_operand (operands[0], DFmode)
3131 || register_operand (operands[1], DFmode)
3132 || fp_zero_operand (operands[1], DFmode))"
3137 [(set_attr "type" "*,load,store")])
3140 [(set (match_operand:DF 0 "register_operand" "")
3141 (match_operand:DF 1 "const_double_operand" ""))]
3143 && (GET_CODE (operands[0]) == REG
3144 && REGNO (operands[0]) < 32)
3145 && ! fp_zero_operand(operands[1], DFmode)
3146 && reload_completed"
3147 [(clobber (const_int 0))]
3153 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3154 REAL_VALUE_TO_TARGET_DOUBLE (r, l);
3155 operands[0] = gen_rtx_raw_REG (DImode, REGNO (operands[0]));
3159 #if HOST_BITS_PER_WIDE_INT == 64
3162 val = ((HOST_WIDE_INT)(unsigned long)l[1] |
3163 ((HOST_WIDE_INT)(unsigned long)l[0] << 32));
3164 emit_insn (gen_movdi (operands[0], GEN_INT (val)));
3166 emit_insn (gen_movdi (operands[0],
3167 immed_double_const (l[1], l[0], DImode)));
3172 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
3175 /* Slick... but this trick loses if this subreg constant part
3176 can be done in one insn. */
3178 && !(SPARC_SETHI32_P (l[0])
3179 || SPARC_SIMM13_P (l[0])))
3181 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
3182 gen_highpart (SImode, operands[0])));
3186 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
3193 ;; Ok, now the splits to handle all the multi insn and
3194 ;; mis-aligned memory address cases.
3195 ;; In these splits please take note that we must be
3196 ;; careful when V9 but not ARCH64 because the integer
3197 ;; register DFmode cases must be handled.
3199 [(set (match_operand:DF 0 "register_operand" "")
3200 (match_operand:DF 1 "register_operand" ""))]
3203 && ((GET_CODE (operands[0]) == REG
3204 && REGNO (operands[0]) < 32)
3205 || (GET_CODE (operands[0]) == SUBREG
3206 && GET_CODE (SUBREG_REG (operands[0])) == REG
3207 && REGNO (SUBREG_REG (operands[0])) < 32))))
3208 && reload_completed"
3209 [(clobber (const_int 0))]
3212 rtx set_dest = operands[0];
3213 rtx set_src = operands[1];
3217 dest1 = gen_highpart (SFmode, set_dest);
3218 dest2 = gen_lowpart (SFmode, set_dest);
3219 src1 = gen_highpart (SFmode, set_src);
3220 src2 = gen_lowpart (SFmode, set_src);
3222 /* Now emit using the real source and destination we found, swapping
3223 the order if we detect overlap. */
3224 if (reg_overlap_mentioned_p (dest1, src2))
3226 emit_insn (gen_movsf (dest2, src2));
3227 emit_insn (gen_movsf (dest1, src1));
3231 emit_insn (gen_movsf (dest1, src1));
3232 emit_insn (gen_movsf (dest2, src2));
3238 [(set (match_operand:DF 0 "register_operand" "")
3239 (match_operand:DF 1 "memory_operand" ""))]
3242 && (((REGNO (operands[0]) % 2) != 0)
3243 || ! mem_min_alignment (operands[1], 8))
3244 && offsettable_memref_p (operands[1])"
3245 [(clobber (const_int 0))]
3248 rtx word0 = adjust_address (operands[1], SFmode, 0);
3249 rtx word1 = adjust_address (operands[1], SFmode, 4);
3251 if (reg_overlap_mentioned_p (gen_highpart (SFmode, operands[0]), word1))
3253 emit_insn (gen_movsf (gen_lowpart (SFmode, operands[0]),
3255 emit_insn (gen_movsf (gen_highpart (SFmode, operands[0]),
3260 emit_insn (gen_movsf (gen_highpart (SFmode, operands[0]),
3262 emit_insn (gen_movsf (gen_lowpart (SFmode, operands[0]),
3269 [(set (match_operand:DF 0 "memory_operand" "")
3270 (match_operand:DF 1 "register_operand" ""))]
3273 && (((REGNO (operands[1]) % 2) != 0)
3274 || ! mem_min_alignment (operands[0], 8))
3275 && offsettable_memref_p (operands[0])"
3276 [(clobber (const_int 0))]
3279 rtx word0 = adjust_address (operands[0], SFmode, 0);
3280 rtx word1 = adjust_address (operands[0], SFmode, 4);
3282 emit_insn (gen_movsf (word0,
3283 gen_highpart (SFmode, operands[1])));
3284 emit_insn (gen_movsf (word1,
3285 gen_lowpart (SFmode, operands[1])));
3290 [(set (match_operand:DF 0 "memory_operand" "")
3291 (match_operand:DF 1 "fp_zero_operand" ""))]
3295 && ! mem_min_alignment (operands[0], 8)))
3296 && offsettable_memref_p (operands[0])"
3297 [(clobber (const_int 0))]
3302 dest1 = adjust_address (operands[0], SFmode, 0);
3303 dest2 = adjust_address (operands[0], SFmode, 4);
3305 emit_insn (gen_movsf (dest1, CONST0_RTX (SFmode)));
3306 emit_insn (gen_movsf (dest2, CONST0_RTX (SFmode)));
3311 [(set (match_operand:DF 0 "register_operand" "")
3312 (match_operand:DF 1 "fp_zero_operand" ""))]
3315 && ((GET_CODE (operands[0]) == REG
3316 && REGNO (operands[0]) < 32)
3317 || (GET_CODE (operands[0]) == SUBREG
3318 && GET_CODE (SUBREG_REG (operands[0])) == REG
3319 && REGNO (SUBREG_REG (operands[0])) < 32))"
3320 [(clobber (const_int 0))]
3323 rtx set_dest = operands[0];
3326 dest1 = gen_highpart (SFmode, set_dest);
3327 dest2 = gen_lowpart (SFmode, set_dest);
3328 emit_insn (gen_movsf (dest1, CONST0_RTX (SFmode)));
3329 emit_insn (gen_movsf (dest2, CONST0_RTX (SFmode)));
3333 (define_expand "movtf"
3334 [(set (match_operand:TF 0 "general_operand" "")
3335 (match_operand:TF 1 "general_operand" ""))]
3339 /* Force TFmode constants into memory. */
3340 if (GET_CODE (operands[0]) == REG
3341 && CONSTANT_P (operands[1]))
3343 /* emit_group_store will send such bogosity to us when it is
3344 not storing directly into memory. So fix this up to avoid
3345 crashes in output_constant_pool. */
3346 if (operands [1] == const0_rtx)
3347 operands[1] = CONST0_RTX (TFmode);
3349 if (TARGET_VIS && fp_zero_operand (operands[1], TFmode))
3352 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
3356 /* Handle MEM cases first, note that only v9 guarentees
3357 full 16-byte alignment for quads. */
3358 if (GET_CODE (operands[0]) == MEM)
3360 if (register_operand (operands[1], TFmode)
3361 || fp_zero_operand (operands[1], TFmode))
3364 if (! reload_in_progress)
3366 operands[0] = validize_mem (operands[0]);
3367 operands[1] = force_reg (TFmode, operands[1]);
3371 /* Fixup PIC cases. */
3374 if (CONSTANT_P (operands[1])
3375 && pic_address_needs_scratch (operands[1]))
3376 operands[1] = legitimize_pic_address (operands[1], TFmode, 0);
3378 if (symbolic_operand (operands[1], TFmode))
3380 operands[1] = legitimize_pic_address (operands[1],
3382 (reload_in_progress ?
3392 ;; Be careful, fmovq and {st,ld}{x,q} do not exist when !arch64 so
3393 ;; we must split them all. :-(
3394 (define_insn "*movtf_insn_sp32"
3395 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,U,r")
3396 (match_operand:TF 1 "input_operand" "oe,GeUr,o,roG"))]
3400 && (register_operand (operands[0], TFmode)
3401 || register_operand (operands[1], TFmode)
3402 || fp_zero_operand (operands[1], TFmode))"
3404 [(set_attr "length" "4")])
3406 (define_insn "*movtf_insn_vis_sp32"
3407 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,U,r")
3408 (match_operand:TF 1 "input_operand" "Goe,GeUr,o,roG"))]
3412 && (register_operand (operands[0], TFmode)
3413 || register_operand (operands[1], TFmode)
3414 || fp_zero_operand (operands[1], TFmode))"
3416 [(set_attr "length" "4")])
3418 ;; Exactly the same as above, except that all `e' cases are deleted.
3419 ;; This is necessary to prevent reload from ever trying to use a `e' reg
3422 (define_insn "*movtf_no_e_insn_sp32"
3423 [(set (match_operand:TF 0 "nonimmediate_operand" "=o,U,o,r,o")
3424 (match_operand:TF 1 "input_operand" "G,o,U,roG,r"))]
3427 && (register_operand (operands[0], TFmode)
3428 || register_operand (operands[1], TFmode)
3429 || fp_zero_operand (operands[1], TFmode))"
3431 [(set_attr "length" "4")])
3433 ;; Now handle the float reg cases directly when arch64,
3434 ;; hard_quad, and proper reg number alignment are all true.
3435 (define_insn "*movtf_insn_hq_sp64"
3436 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,e,m,o,r")
3437 (match_operand:TF 1 "input_operand" "e,m,e,Gr,roG"))]
3442 && (register_operand (operands[0], TFmode)
3443 || register_operand (operands[1], TFmode)
3444 || fp_zero_operand (operands[1], TFmode))"
3451 [(set_attr "type" "fpmove,fpload,fpstore,*,*")
3452 (set_attr "length" "*,*,*,2,2")])
3454 (define_insn "*movtf_insn_hq_vis_sp64"
3455 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,e,m,eo,r,o")
3456 (match_operand:TF 1 "input_operand" "e,m,e,G,roG,r"))]
3461 && (register_operand (operands[0], TFmode)
3462 || register_operand (operands[1], TFmode)
3463 || fp_zero_operand (operands[1], TFmode))"
3471 [(set_attr "type" "fpmove,fpload,fpstore,*,*,*")
3472 (set_attr "length" "*,*,*,2,2,2")])
3474 ;; Now we allow the integer register cases even when
3475 ;; only arch64 is true.
3476 (define_insn "*movtf_insn_sp64"
3477 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,r")
3478 (match_operand:TF 1 "input_operand" "oe,Ger,orG"))]
3482 && ! TARGET_HARD_QUAD
3483 && (register_operand (operands[0], TFmode)
3484 || register_operand (operands[1], TFmode)
3485 || fp_zero_operand (operands[1], TFmode))"
3487 [(set_attr "length" "2")])
3489 (define_insn "*movtf_insn_vis_sp64"
3490 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,r")
3491 (match_operand:TF 1 "input_operand" "Goe,Ger,orG"))]
3495 && ! TARGET_HARD_QUAD
3496 && (register_operand (operands[0], TFmode)
3497 || register_operand (operands[1], TFmode)
3498 || fp_zero_operand (operands[1], TFmode))"
3500 [(set_attr "length" "2")])
3502 (define_insn "*movtf_no_e_insn_sp64"
3503 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o")
3504 (match_operand:TF 1 "input_operand" "orG,rG"))]
3507 && (register_operand (operands[0], TFmode)
3508 || register_operand (operands[1], TFmode)
3509 || fp_zero_operand (operands[1], TFmode))"
3511 [(set_attr "length" "2")])
3513 ;; Now all the splits to handle multi-insn TF mode moves.
3515 [(set (match_operand:TF 0 "register_operand" "")
3516 (match_operand:TF 1 "register_operand" ""))]
3520 && ! TARGET_HARD_QUAD)
3521 || ! fp_register_operand (operands[0], TFmode))"
3522 [(clobber (const_int 0))]
3525 rtx set_dest = operands[0];
3526 rtx set_src = operands[1];
3530 dest1 = gen_df_reg (set_dest, 0);
3531 dest2 = gen_df_reg (set_dest, 1);
3532 src1 = gen_df_reg (set_src, 0);
3533 src2 = gen_df_reg (set_src, 1);
3535 /* Now emit using the real source and destination we found, swapping
3536 the order if we detect overlap. */
3537 if (reg_overlap_mentioned_p (dest1, src2))
3539 emit_insn (gen_movdf (dest2, src2));
3540 emit_insn (gen_movdf (dest1, src1));
3544 emit_insn (gen_movdf (dest1, src1));
3545 emit_insn (gen_movdf (dest2, src2));
3551 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3552 (match_operand:TF 1 "fp_zero_operand" ""))]
3554 [(clobber (const_int 0))]
3557 rtx set_dest = operands[0];
3560 switch (GET_CODE (set_dest))
3563 dest1 = gen_df_reg (set_dest, 0);
3564 dest2 = gen_df_reg (set_dest, 1);
3567 dest1 = adjust_address (set_dest, DFmode, 0);
3568 dest2 = adjust_address (set_dest, DFmode, 8);
3574 emit_insn (gen_movdf (dest1, CONST0_RTX (DFmode)));
3575 emit_insn (gen_movdf (dest2, CONST0_RTX (DFmode)));
3580 [(set (match_operand:TF 0 "register_operand" "")
3581 (match_operand:TF 1 "memory_operand" ""))]
3583 && offsettable_memref_p (operands[1])
3585 || ! TARGET_HARD_QUAD
3586 || ! fp_register_operand (operands[0], TFmode)))"
3587 [(clobber (const_int 0))]
3590 rtx word0 = adjust_address (operands[1], DFmode, 0);
3591 rtx word1 = adjust_address (operands[1], DFmode, 8);
3592 rtx set_dest, dest1, dest2;
3594 set_dest = operands[0];
3596 dest1 = gen_df_reg (set_dest, 0);
3597 dest2 = gen_df_reg (set_dest, 1);
3599 /* Now output, ordering such that we don't clobber any registers
3600 mentioned in the address. */
3601 if (reg_overlap_mentioned_p (dest1, word1))
3604 emit_insn (gen_movdf (dest2, word1));
3605 emit_insn (gen_movdf (dest1, word0));
3609 emit_insn (gen_movdf (dest1, word0));
3610 emit_insn (gen_movdf (dest2, word1));
3616 [(set (match_operand:TF 0 "memory_operand" "")
3617 (match_operand:TF 1 "register_operand" ""))]
3619 && offsettable_memref_p (operands[0])
3621 || ! TARGET_HARD_QUAD
3622 || ! fp_register_operand (operands[1], TFmode)))"
3623 [(clobber (const_int 0))]
3626 rtx set_src = operands[1];
3628 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 0),
3629 gen_df_reg (set_src, 0)));
3630 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 8),
3631 gen_df_reg (set_src, 1)));
3635 ;; Sparc V9 conditional move instructions.
3637 ;; We can handle larger constants here for some flavors, but for now we keep
3638 ;; it simple and only allow those constants supported by all flavours.
3639 ;; Note that emit_conditional_move canonicalizes operands 2,3 so that operand
3640 ;; 3 contains the constant if one is present, but we handle either for
3641 ;; generality (sparc.c puts a constant in operand 2).
3643 (define_expand "movqicc"
3644 [(set (match_operand:QI 0 "register_operand" "")
3645 (if_then_else:QI (match_operand 1 "comparison_operator" "")
3646 (match_operand:QI 2 "arith10_operand" "")
3647 (match_operand:QI 3 "arith10_operand" "")))]
3651 enum rtx_code code = GET_CODE (operands[1]);
3653 if (GET_MODE (sparc_compare_op0) == DImode
3657 if (sparc_compare_op1 == const0_rtx
3658 && GET_CODE (sparc_compare_op0) == REG
3659 && GET_MODE (sparc_compare_op0) == DImode
3660 && v9_regcmp_p (code))
3662 operands[1] = gen_rtx_fmt_ee (code, DImode,
3663 sparc_compare_op0, sparc_compare_op1);
3667 rtx cc_reg = gen_compare_reg (code,
3668 sparc_compare_op0, sparc_compare_op1);
3669 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3673 (define_expand "movhicc"
3674 [(set (match_operand:HI 0 "register_operand" "")
3675 (if_then_else:HI (match_operand 1 "comparison_operator" "")
3676 (match_operand:HI 2 "arith10_operand" "")
3677 (match_operand:HI 3 "arith10_operand" "")))]
3681 enum rtx_code code = GET_CODE (operands[1]);
3683 if (GET_MODE (sparc_compare_op0) == DImode
3687 if (sparc_compare_op1 == const0_rtx
3688 && GET_CODE (sparc_compare_op0) == REG
3689 && GET_MODE (sparc_compare_op0) == DImode
3690 && v9_regcmp_p (code))
3692 operands[1] = gen_rtx_fmt_ee (code, DImode,
3693 sparc_compare_op0, sparc_compare_op1);
3697 rtx cc_reg = gen_compare_reg (code,
3698 sparc_compare_op0, sparc_compare_op1);
3699 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3703 (define_expand "movsicc"
3704 [(set (match_operand:SI 0 "register_operand" "")
3705 (if_then_else:SI (match_operand 1 "comparison_operator" "")
3706 (match_operand:SI 2 "arith10_operand" "")
3707 (match_operand:SI 3 "arith10_operand" "")))]
3711 enum rtx_code code = GET_CODE (operands[1]);
3712 enum machine_mode op0_mode = GET_MODE (sparc_compare_op0);
3714 if (sparc_compare_op1 == const0_rtx
3715 && GET_CODE (sparc_compare_op0) == REG
3716 && (TARGET_ARCH64 && op0_mode == DImode && v9_regcmp_p (code)))
3718 operands[1] = gen_rtx_fmt_ee (code, op0_mode,
3719 sparc_compare_op0, sparc_compare_op1);
3723 rtx cc_reg = gen_compare_reg (code,
3724 sparc_compare_op0, sparc_compare_op1);
3725 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg),
3726 cc_reg, const0_rtx);
3730 (define_expand "movdicc"
3731 [(set (match_operand:DI 0 "register_operand" "")
3732 (if_then_else:DI (match_operand 1 "comparison_operator" "")
3733 (match_operand:DI 2 "arith10_double_operand" "")
3734 (match_operand:DI 3 "arith10_double_operand" "")))]
3738 enum rtx_code code = GET_CODE (operands[1]);
3740 if (sparc_compare_op1 == const0_rtx
3741 && GET_CODE (sparc_compare_op0) == REG
3742 && GET_MODE (sparc_compare_op0) == DImode
3743 && v9_regcmp_p (code))
3745 operands[1] = gen_rtx_fmt_ee (code, DImode,
3746 sparc_compare_op0, sparc_compare_op1);
3750 rtx cc_reg = gen_compare_reg (code,
3751 sparc_compare_op0, sparc_compare_op1);
3752 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg),
3753 cc_reg, const0_rtx);
3757 (define_expand "movsfcc"
3758 [(set (match_operand:SF 0 "register_operand" "")
3759 (if_then_else:SF (match_operand 1 "comparison_operator" "")
3760 (match_operand:SF 2 "register_operand" "")
3761 (match_operand:SF 3 "register_operand" "")))]
3762 "TARGET_V9 && TARGET_FPU"
3765 enum rtx_code code = GET_CODE (operands[1]);
3767 if (GET_MODE (sparc_compare_op0) == DImode
3771 if (sparc_compare_op1 == const0_rtx
3772 && GET_CODE (sparc_compare_op0) == REG
3773 && GET_MODE (sparc_compare_op0) == DImode
3774 && v9_regcmp_p (code))
3776 operands[1] = gen_rtx_fmt_ee (code, DImode,
3777 sparc_compare_op0, sparc_compare_op1);
3781 rtx cc_reg = gen_compare_reg (code,
3782 sparc_compare_op0, sparc_compare_op1);
3783 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3787 (define_expand "movdfcc"
3788 [(set (match_operand:DF 0 "register_operand" "")
3789 (if_then_else:DF (match_operand 1 "comparison_operator" "")
3790 (match_operand:DF 2 "register_operand" "")
3791 (match_operand:DF 3 "register_operand" "")))]
3792 "TARGET_V9 && TARGET_FPU"
3795 enum rtx_code code = GET_CODE (operands[1]);
3797 if (GET_MODE (sparc_compare_op0) == DImode
3801 if (sparc_compare_op1 == const0_rtx
3802 && GET_CODE (sparc_compare_op0) == REG
3803 && GET_MODE (sparc_compare_op0) == DImode
3804 && v9_regcmp_p (code))
3806 operands[1] = gen_rtx_fmt_ee (code, DImode,
3807 sparc_compare_op0, sparc_compare_op1);
3811 rtx cc_reg = gen_compare_reg (code,
3812 sparc_compare_op0, sparc_compare_op1);
3813 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3817 (define_expand "movtfcc"
3818 [(set (match_operand:TF 0 "register_operand" "")
3819 (if_then_else:TF (match_operand 1 "comparison_operator" "")
3820 (match_operand:TF 2 "register_operand" "")
3821 (match_operand:TF 3 "register_operand" "")))]
3822 "TARGET_V9 && TARGET_FPU"
3825 enum rtx_code code = GET_CODE (operands[1]);
3827 if (GET_MODE (sparc_compare_op0) == DImode
3831 if (sparc_compare_op1 == const0_rtx
3832 && GET_CODE (sparc_compare_op0) == REG
3833 && GET_MODE (sparc_compare_op0) == DImode
3834 && v9_regcmp_p (code))
3836 operands[1] = gen_rtx_fmt_ee (code, DImode,
3837 sparc_compare_op0, sparc_compare_op1);
3841 rtx cc_reg = gen_compare_reg (code,
3842 sparc_compare_op0, sparc_compare_op1);
3843 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3847 ;; Conditional move define_insns.
3849 (define_insn "*movqi_cc_sp64"
3850 [(set (match_operand:QI 0 "register_operand" "=r,r")
3851 (if_then_else:QI (match_operator 1 "comparison_operator"
3852 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3854 (match_operand:QI 3 "arith11_operand" "rL,0")
3855 (match_operand:QI 4 "arith11_operand" "0,rL")))]
3858 mov%C1\\t%x2, %3, %0
3859 mov%c1\\t%x2, %4, %0"
3860 [(set_attr "type" "cmove")])
3862 (define_insn "*movhi_cc_sp64"
3863 [(set (match_operand:HI 0 "register_operand" "=r,r")
3864 (if_then_else:HI (match_operator 1 "comparison_operator"
3865 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3867 (match_operand:HI 3 "arith11_operand" "rL,0")
3868 (match_operand:HI 4 "arith11_operand" "0,rL")))]
3871 mov%C1\\t%x2, %3, %0
3872 mov%c1\\t%x2, %4, %0"
3873 [(set_attr "type" "cmove")])
3875 (define_insn "*movsi_cc_sp64"
3876 [(set (match_operand:SI 0 "register_operand" "=r,r")
3877 (if_then_else:SI (match_operator 1 "comparison_operator"
3878 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3880 (match_operand:SI 3 "arith11_operand" "rL,0")
3881 (match_operand:SI 4 "arith11_operand" "0,rL")))]
3884 mov%C1\\t%x2, %3, %0
3885 mov%c1\\t%x2, %4, %0"
3886 [(set_attr "type" "cmove")])
3888 ;; ??? The constraints of operands 3,4 need work.
3889 (define_insn "*movdi_cc_sp64"
3890 [(set (match_operand:DI 0 "register_operand" "=r,r")
3891 (if_then_else:DI (match_operator 1 "comparison_operator"
3892 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3894 (match_operand:DI 3 "arith11_double_operand" "rLH,0")
3895 (match_operand:DI 4 "arith11_double_operand" "0,rLH")))]
3898 mov%C1\\t%x2, %3, %0
3899 mov%c1\\t%x2, %4, %0"
3900 [(set_attr "type" "cmove")])
3902 (define_insn "*movdi_cc_sp64_trunc"
3903 [(set (match_operand:SI 0 "register_operand" "=r,r")
3904 (if_then_else:SI (match_operator 1 "comparison_operator"
3905 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3907 (match_operand:SI 3 "arith11_double_operand" "rLH,0")
3908 (match_operand:SI 4 "arith11_double_operand" "0,rLH")))]
3911 mov%C1\\t%x2, %3, %0
3912 mov%c1\\t%x2, %4, %0"
3913 [(set_attr "type" "cmove")])
3915 (define_insn "*movsf_cc_sp64"
3916 [(set (match_operand:SF 0 "register_operand" "=f,f")
3917 (if_then_else:SF (match_operator 1 "comparison_operator"
3918 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3920 (match_operand:SF 3 "register_operand" "f,0")
3921 (match_operand:SF 4 "register_operand" "0,f")))]
3922 "TARGET_V9 && TARGET_FPU"
3924 fmovs%C1\\t%x2, %3, %0
3925 fmovs%c1\\t%x2, %4, %0"
3926 [(set_attr "type" "fpcmove")])
3928 (define_insn "movdf_cc_sp64"
3929 [(set (match_operand:DF 0 "register_operand" "=e,e")
3930 (if_then_else:DF (match_operator 1 "comparison_operator"
3931 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3933 (match_operand:DF 3 "register_operand" "e,0")
3934 (match_operand:DF 4 "register_operand" "0,e")))]
3935 "TARGET_V9 && TARGET_FPU"
3937 fmovd%C1\\t%x2, %3, %0
3938 fmovd%c1\\t%x2, %4, %0"
3939 [(set_attr "type" "fpcmove")
3940 (set_attr "fptype" "double")])
3942 (define_insn "*movtf_cc_hq_sp64"
3943 [(set (match_operand:TF 0 "register_operand" "=e,e")
3944 (if_then_else:TF (match_operator 1 "comparison_operator"
3945 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3947 (match_operand:TF 3 "register_operand" "e,0")
3948 (match_operand:TF 4 "register_operand" "0,e")))]
3949 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
3951 fmovq%C1\\t%x2, %3, %0
3952 fmovq%c1\\t%x2, %4, %0"
3953 [(set_attr "type" "fpcmove")])
3955 (define_insn "*movtf_cc_sp64"
3956 [(set (match_operand:TF 0 "register_operand" "=e,e")
3957 (if_then_else:TF (match_operator 1 "comparison_operator"
3958 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3960 (match_operand:TF 3 "register_operand" "e,0")
3961 (match_operand:TF 4 "register_operand" "0,e")))]
3962 "TARGET_V9 && TARGET_FPU && !TARGET_HARD_QUAD"
3964 [(set_attr "length" "2")])
3967 [(set (match_operand:TF 0 "register_operand" "")
3968 (if_then_else:TF (match_operator 1 "comparison_operator"
3969 [(match_operand 2 "icc_or_fcc_reg_operand" "")
3971 (match_operand:TF 3 "register_operand" "")
3972 (match_operand:TF 4 "register_operand" "")))]
3973 "reload_completed && TARGET_V9 && TARGET_FPU && !TARGET_HARD_QUAD"
3974 [(clobber (const_int 0))]
3977 rtx set_dest = operands[0];
3978 rtx set_srca = operands[3];
3979 rtx set_srcb = operands[4];
3980 int third = rtx_equal_p (set_dest, set_srca);
3982 rtx srca1, srca2, srcb1, srcb2;
3984 dest1 = gen_df_reg (set_dest, 0);
3985 dest2 = gen_df_reg (set_dest, 1);
3986 srca1 = gen_df_reg (set_srca, 0);
3987 srca2 = gen_df_reg (set_srca, 1);
3988 srcb1 = gen_df_reg (set_srcb, 0);
3989 srcb2 = gen_df_reg (set_srcb, 1);
3991 /* Now emit using the real source and destination we found, swapping
3992 the order if we detect overlap. */
3993 if ((third && reg_overlap_mentioned_p (dest1, srcb2))
3994 || (!third && reg_overlap_mentioned_p (dest1, srca2)))
3996 emit_insn (gen_movdf_cc_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
3997 emit_insn (gen_movdf_cc_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
4001 emit_insn (gen_movdf_cc_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
4002 emit_insn (gen_movdf_cc_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
4007 (define_insn "*movqi_cc_reg_sp64"
4008 [(set (match_operand:QI 0 "register_operand" "=r,r")
4009 (if_then_else:QI (match_operator 1 "v9_regcmp_op"
4010 [(match_operand:DI 2 "register_operand" "r,r")
4012 (match_operand:QI 3 "arith10_operand" "rM,0")
4013 (match_operand:QI 4 "arith10_operand" "0,rM")))]
4016 movr%D1\\t%2, %r3, %0
4017 movr%d1\\t%2, %r4, %0"
4018 [(set_attr "type" "cmove")])
4020 (define_insn "*movhi_cc_reg_sp64"
4021 [(set (match_operand:HI 0 "register_operand" "=r,r")
4022 (if_then_else:HI (match_operator 1 "v9_regcmp_op"
4023 [(match_operand:DI 2 "register_operand" "r,r")
4025 (match_operand:HI 3 "arith10_operand" "rM,0")
4026 (match_operand:HI 4 "arith10_operand" "0,rM")))]
4029 movr%D1\\t%2, %r3, %0
4030 movr%d1\\t%2, %r4, %0"
4031 [(set_attr "type" "cmove")])
4033 (define_insn "*movsi_cc_reg_sp64"
4034 [(set (match_operand:SI 0 "register_operand" "=r,r")
4035 (if_then_else:SI (match_operator 1 "v9_regcmp_op"
4036 [(match_operand:DI 2 "register_operand" "r,r")
4038 (match_operand:SI 3 "arith10_operand" "rM,0")
4039 (match_operand:SI 4 "arith10_operand" "0,rM")))]
4042 movr%D1\\t%2, %r3, %0
4043 movr%d1\\t%2, %r4, %0"
4044 [(set_attr "type" "cmove")])
4046 ;; ??? The constraints of operands 3,4 need work.
4047 (define_insn "*movdi_cc_reg_sp64"
4048 [(set (match_operand:DI 0 "register_operand" "=r,r")
4049 (if_then_else:DI (match_operator 1 "v9_regcmp_op"
4050 [(match_operand:DI 2 "register_operand" "r,r")
4052 (match_operand:DI 3 "arith10_double_operand" "rMH,0")
4053 (match_operand:DI 4 "arith10_double_operand" "0,rMH")))]
4056 movr%D1\\t%2, %r3, %0
4057 movr%d1\\t%2, %r4, %0"
4058 [(set_attr "type" "cmove")])
4060 (define_insn "*movdi_cc_reg_sp64_trunc"
4061 [(set (match_operand:SI 0 "register_operand" "=r,r")
4062 (if_then_else:SI (match_operator 1 "v9_regcmp_op"
4063 [(match_operand:DI 2 "register_operand" "r,r")
4065 (match_operand:SI 3 "arith10_double_operand" "rMH,0")
4066 (match_operand:SI 4 "arith10_double_operand" "0,rMH")))]
4069 movr%D1\\t%2, %r3, %0
4070 movr%d1\\t%2, %r4, %0"
4071 [(set_attr "type" "cmove")])
4073 (define_insn "*movsf_cc_reg_sp64"
4074 [(set (match_operand:SF 0 "register_operand" "=f,f")
4075 (if_then_else:SF (match_operator 1 "v9_regcmp_op"
4076 [(match_operand:DI 2 "register_operand" "r,r")
4078 (match_operand:SF 3 "register_operand" "f,0")
4079 (match_operand:SF 4 "register_operand" "0,f")))]
4080 "TARGET_ARCH64 && TARGET_FPU"
4082 fmovrs%D1\\t%2, %3, %0
4083 fmovrs%d1\\t%2, %4, %0"
4084 [(set_attr "type" "fpcrmove")])
4086 (define_insn "movdf_cc_reg_sp64"
4087 [(set (match_operand:DF 0 "register_operand" "=e,e")
4088 (if_then_else:DF (match_operator 1 "v9_regcmp_op"
4089 [(match_operand:DI 2 "register_operand" "r,r")
4091 (match_operand:DF 3 "register_operand" "e,0")
4092 (match_operand:DF 4 "register_operand" "0,e")))]
4093 "TARGET_ARCH64 && TARGET_FPU"
4095 fmovrd%D1\\t%2, %3, %0
4096 fmovrd%d1\\t%2, %4, %0"
4097 [(set_attr "type" "fpcrmove")
4098 (set_attr "fptype" "double")])
4100 (define_insn "*movtf_cc_reg_hq_sp64"
4101 [(set (match_operand:TF 0 "register_operand" "=e,e")
4102 (if_then_else:TF (match_operator 1 "v9_regcmp_op"
4103 [(match_operand:DI 2 "register_operand" "r,r")
4105 (match_operand:TF 3 "register_operand" "e,0")
4106 (match_operand:TF 4 "register_operand" "0,e")))]
4107 "TARGET_ARCH64 && TARGET_FPU && TARGET_HARD_QUAD"
4109 fmovrq%D1\\t%2, %3, %0
4110 fmovrq%d1\\t%2, %4, %0"
4111 [(set_attr "type" "fpcrmove")])
4113 (define_insn "*movtf_cc_reg_sp64"
4114 [(set (match_operand:TF 0 "register_operand" "=e,e")
4115 (if_then_else:TF (match_operator 1 "v9_regcmp_op"
4116 [(match_operand:DI 2 "register_operand" "r,r")
4118 (match_operand:TF 3 "register_operand" "e,0")
4119 (match_operand:TF 4 "register_operand" "0,e")))]
4120 "TARGET_ARCH64 && TARGET_FPU && ! TARGET_HARD_QUAD"
4122 [(set_attr "length" "2")])
4125 [(set (match_operand:TF 0 "register_operand" "")
4126 (if_then_else:TF (match_operator 1 "v9_regcmp_op"
4127 [(match_operand:DI 2 "register_operand" "")
4129 (match_operand:TF 3 "register_operand" "")
4130 (match_operand:TF 4 "register_operand" "")))]
4131 "reload_completed && TARGET_ARCH64 && TARGET_FPU && ! TARGET_HARD_QUAD"
4132 [(clobber (const_int 0))]
4135 rtx set_dest = operands[0];
4136 rtx set_srca = operands[3];
4137 rtx set_srcb = operands[4];
4138 int third = rtx_equal_p (set_dest, set_srca);
4140 rtx srca1, srca2, srcb1, srcb2;
4142 dest1 = gen_df_reg (set_dest, 0);
4143 dest2 = gen_df_reg (set_dest, 1);
4144 srca1 = gen_df_reg (set_srca, 0);
4145 srca2 = gen_df_reg (set_srca, 1);
4146 srcb1 = gen_df_reg (set_srcb, 0);
4147 srcb2 = gen_df_reg (set_srcb, 1);
4149 /* Now emit using the real source and destination we found, swapping
4150 the order if we detect overlap. */
4151 if ((third && reg_overlap_mentioned_p (dest1, srcb2))
4152 || (!third && reg_overlap_mentioned_p (dest1, srca2)))
4154 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
4155 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
4159 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
4160 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
4166 ;;- zero extension instructions
4168 ;; These patterns originally accepted general_operands, however, slightly
4169 ;; better code is generated by only accepting register_operands, and then
4170 ;; letting combine generate the ldu[hb] insns.
4172 (define_expand "zero_extendhisi2"
4173 [(set (match_operand:SI 0 "register_operand" "")
4174 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
4178 rtx temp = gen_reg_rtx (SImode);
4179 rtx shift_16 = GEN_INT (16);
4180 int op1_subbyte = 0;
4182 if (GET_CODE (operand1) == SUBREG)
4184 op1_subbyte = SUBREG_BYTE (operand1);
4185 op1_subbyte /= GET_MODE_SIZE (SImode);
4186 op1_subbyte *= GET_MODE_SIZE (SImode);
4187 operand1 = XEXP (operand1, 0);
4190 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4192 emit_insn (gen_lshrsi3 (operand0, temp, shift_16));
4196 (define_insn "*zero_extendhisi2_insn"
4197 [(set (match_operand:SI 0 "register_operand" "=r")
4198 (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
4201 [(set_attr "type" "load")
4202 (set_attr "us3load_type" "3cycle")])
4204 (define_expand "zero_extendqihi2"
4205 [(set (match_operand:HI 0 "register_operand" "")
4206 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
4210 (define_insn "*zero_extendqihi2_insn"
4211 [(set (match_operand:HI 0 "register_operand" "=r,r")
4212 (zero_extend:HI (match_operand:QI 1 "input_operand" "r,m")))]
4213 "GET_CODE (operands[1]) != CONST_INT"
4217 [(set_attr "type" "*,load")
4218 (set_attr "us3load_type" "*,3cycle")])
4220 (define_expand "zero_extendqisi2"
4221 [(set (match_operand:SI 0 "register_operand" "")
4222 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
4226 (define_insn "*zero_extendqisi2_insn"
4227 [(set (match_operand:SI 0 "register_operand" "=r,r")
4228 (zero_extend:SI (match_operand:QI 1 "input_operand" "r,m")))]
4229 "GET_CODE (operands[1]) != CONST_INT"
4233 [(set_attr "type" "*,load")
4234 (set_attr "us3load_type" "*,3cycle")])
4236 (define_expand "zero_extendqidi2"
4237 [(set (match_operand:DI 0 "register_operand" "")
4238 (zero_extend:DI (match_operand:QI 1 "register_operand" "")))]
4242 (define_insn "*zero_extendqidi2_insn"
4243 [(set (match_operand:DI 0 "register_operand" "=r,r")
4244 (zero_extend:DI (match_operand:QI 1 "input_operand" "r,m")))]
4245 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
4249 [(set_attr "type" "*,load")
4250 (set_attr "us3load_type" "*,3cycle")])
4252 (define_expand "zero_extendhidi2"
4253 [(set (match_operand:DI 0 "register_operand" "")
4254 (zero_extend:DI (match_operand:HI 1 "register_operand" "")))]
4258 rtx temp = gen_reg_rtx (DImode);
4259 rtx shift_48 = GEN_INT (48);
4260 int op1_subbyte = 0;
4262 if (GET_CODE (operand1) == SUBREG)
4264 op1_subbyte = SUBREG_BYTE (operand1);
4265 op1_subbyte /= GET_MODE_SIZE (DImode);
4266 op1_subbyte *= GET_MODE_SIZE (DImode);
4267 operand1 = XEXP (operand1, 0);
4270 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
4272 emit_insn (gen_lshrdi3 (operand0, temp, shift_48));
4276 (define_insn "*zero_extendhidi2_insn"
4277 [(set (match_operand:DI 0 "register_operand" "=r")
4278 (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
4281 [(set_attr "type" "load")
4282 (set_attr "us3load_type" "3cycle")])
4285 ;; ??? Write truncdisi pattern using sra?
4287 (define_expand "zero_extendsidi2"
4288 [(set (match_operand:DI 0 "register_operand" "")
4289 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
4293 (define_insn "*zero_extendsidi2_insn_sp64"
4294 [(set (match_operand:DI 0 "register_operand" "=r,r")
4295 (zero_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
4296 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
4300 [(set_attr "type" "shift,load")])
4302 (define_insn "*zero_extendsidi2_insn_sp32"
4303 [(set (match_operand:DI 0 "register_operand" "=r")
4304 (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
4307 [(set_attr "length" "2")])
4310 [(set (match_operand:DI 0 "register_operand" "")
4311 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
4312 "! TARGET_ARCH64 && reload_completed"
4313 [(set (match_dup 2) (match_dup 3))
4314 (set (match_dup 4) (match_dup 5))]
4319 dest1 = gen_highpart (SImode, operands[0]);
4320 dest2 = gen_lowpart (SImode, operands[0]);
4322 /* Swap the order in case of overlap. */
4323 if (REGNO (dest1) == REGNO (operands[1]))
4325 operands[2] = dest2;
4326 operands[3] = operands[1];
4327 operands[4] = dest1;
4328 operands[5] = const0_rtx;
4332 operands[2] = dest1;
4333 operands[3] = const0_rtx;
4334 operands[4] = dest2;
4335 operands[5] = operands[1];
4339 ;; Simplify comparisons of extended values.
4341 (define_insn "*cmp_zero_extendqisi2"
4343 (compare:CC (zero_extend:SI (match_operand:QI 0 "register_operand" "r"))
4346 "andcc\\t%0, 0xff, %%g0"
4347 [(set_attr "type" "compare")])
4349 (define_insn "*cmp_zero_qi"
4351 (compare:CC (match_operand:QI 0 "register_operand" "r")
4354 "andcc\\t%0, 0xff, %%g0"
4355 [(set_attr "type" "compare")])
4357 (define_insn "*cmp_zero_extendqisi2_set"
4359 (compare:CC (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
4361 (set (match_operand:SI 0 "register_operand" "=r")
4362 (zero_extend:SI (match_dup 1)))]
4364 "andcc\\t%1, 0xff, %0"
4365 [(set_attr "type" "compare")])
4367 (define_insn "*cmp_zero_extendqisi2_andcc_set"
4369 (compare:CC (and:SI (match_operand:SI 1 "register_operand" "r")
4372 (set (match_operand:SI 0 "register_operand" "=r")
4373 (zero_extend:SI (subreg:QI (match_dup 1) 0)))]
4375 "andcc\\t%1, 0xff, %0"
4376 [(set_attr "type" "compare")])
4378 (define_insn "*cmp_zero_extendqidi2"
4380 (compare:CCX (zero_extend:DI (match_operand:QI 0 "register_operand" "r"))
4383 "andcc\\t%0, 0xff, %%g0"
4384 [(set_attr "type" "compare")])
4386 (define_insn "*cmp_zero_qi_sp64"
4388 (compare:CCX (match_operand:QI 0 "register_operand" "r")
4391 "andcc\\t%0, 0xff, %%g0"
4392 [(set_attr "type" "compare")])
4394 (define_insn "*cmp_zero_extendqidi2_set"
4396 (compare:CCX (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
4398 (set (match_operand:DI 0 "register_operand" "=r")
4399 (zero_extend:DI (match_dup 1)))]
4401 "andcc\\t%1, 0xff, %0"
4402 [(set_attr "type" "compare")])
4404 (define_insn "*cmp_zero_extendqidi2_andcc_set"
4406 (compare:CCX (and:DI (match_operand:DI 1 "register_operand" "r")
4409 (set (match_operand:DI 0 "register_operand" "=r")
4410 (zero_extend:DI (subreg:QI (match_dup 1) 0)))]
4412 "andcc\\t%1, 0xff, %0"
4413 [(set_attr "type" "compare")])
4415 ;; Similarly, handle {SI,DI}->QI mode truncation followed by a compare.
4417 (define_insn "*cmp_siqi_trunc"
4419 (compare:CC (subreg:QI (match_operand:SI 0 "register_operand" "r") 3)
4422 "andcc\\t%0, 0xff, %%g0"
4423 [(set_attr "type" "compare")])
4425 (define_insn "*cmp_siqi_trunc_set"
4427 (compare:CC (subreg:QI (match_operand:SI 1 "register_operand" "r") 3)
4429 (set (match_operand:QI 0 "register_operand" "=r")
4430 (subreg:QI (match_dup 1) 3))]
4432 "andcc\\t%1, 0xff, %0"
4433 [(set_attr "type" "compare")])
4435 (define_insn "*cmp_diqi_trunc"
4437 (compare:CC (subreg:QI (match_operand:DI 0 "register_operand" "r") 7)
4440 "andcc\\t%0, 0xff, %%g0"
4441 [(set_attr "type" "compare")])
4443 (define_insn "*cmp_diqi_trunc_set"
4445 (compare:CC (subreg:QI (match_operand:DI 1 "register_operand" "r") 7)
4447 (set (match_operand:QI 0 "register_operand" "=r")
4448 (subreg:QI (match_dup 1) 7))]
4450 "andcc\\t%1, 0xff, %0"
4451 [(set_attr "type" "compare")])
4453 ;;- sign extension instructions
4455 ;; These patterns originally accepted general_operands, however, slightly
4456 ;; better code is generated by only accepting register_operands, and then
4457 ;; letting combine generate the lds[hb] insns.
4459 (define_expand "extendhisi2"
4460 [(set (match_operand:SI 0 "register_operand" "")
4461 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
4465 rtx temp = gen_reg_rtx (SImode);
4466 rtx shift_16 = GEN_INT (16);
4467 int op1_subbyte = 0;
4469 if (GET_CODE (operand1) == SUBREG)
4471 op1_subbyte = SUBREG_BYTE (operand1);
4472 op1_subbyte /= GET_MODE_SIZE (SImode);
4473 op1_subbyte *= GET_MODE_SIZE (SImode);
4474 operand1 = XEXP (operand1, 0);
4477 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4479 emit_insn (gen_ashrsi3 (operand0, temp, shift_16));
4483 (define_insn "*sign_extendhisi2_insn"
4484 [(set (match_operand:SI 0 "register_operand" "=r")
4485 (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
4488 [(set_attr "type" "sload")
4489 (set_attr "us3load_type" "3cycle")])
4491 (define_expand "extendqihi2"
4492 [(set (match_operand:HI 0 "register_operand" "")
4493 (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
4497 rtx temp = gen_reg_rtx (SImode);
4498 rtx shift_24 = GEN_INT (24);
4499 int op1_subbyte = 0;
4500 int op0_subbyte = 0;
4502 if (GET_CODE (operand1) == SUBREG)
4504 op1_subbyte = SUBREG_BYTE (operand1);
4505 op1_subbyte /= GET_MODE_SIZE (SImode);
4506 op1_subbyte *= GET_MODE_SIZE (SImode);
4507 operand1 = XEXP (operand1, 0);
4509 if (GET_CODE (operand0) == SUBREG)
4511 op0_subbyte = SUBREG_BYTE (operand0);
4512 op0_subbyte /= GET_MODE_SIZE (SImode);
4513 op0_subbyte *= GET_MODE_SIZE (SImode);
4514 operand0 = XEXP (operand0, 0);
4516 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4518 if (GET_MODE (operand0) != SImode)
4519 operand0 = gen_rtx_SUBREG (SImode, operand0, op0_subbyte);
4520 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
4524 (define_insn "*sign_extendqihi2_insn"
4525 [(set (match_operand:HI 0 "register_operand" "=r")
4526 (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
4529 [(set_attr "type" "sload")
4530 (set_attr "us3load_type" "3cycle")])
4532 (define_expand "extendqisi2"
4533 [(set (match_operand:SI 0 "register_operand" "")
4534 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
4538 rtx temp = gen_reg_rtx (SImode);
4539 rtx shift_24 = GEN_INT (24);
4540 int op1_subbyte = 0;
4542 if (GET_CODE (operand1) == SUBREG)
4544 op1_subbyte = SUBREG_BYTE (operand1);
4545 op1_subbyte /= GET_MODE_SIZE (SImode);
4546 op1_subbyte *= GET_MODE_SIZE (SImode);
4547 operand1 = XEXP (operand1, 0);
4550 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4552 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
4556 (define_insn "*sign_extendqisi2_insn"
4557 [(set (match_operand:SI 0 "register_operand" "=r")
4558 (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
4561 [(set_attr "type" "sload")
4562 (set_attr "us3load_type" "3cycle")])
4564 (define_expand "extendqidi2"
4565 [(set (match_operand:DI 0 "register_operand" "")
4566 (sign_extend:DI (match_operand:QI 1 "register_operand" "")))]
4570 rtx temp = gen_reg_rtx (DImode);
4571 rtx shift_56 = GEN_INT (56);
4572 int op1_subbyte = 0;
4574 if (GET_CODE (operand1) == SUBREG)
4576 op1_subbyte = SUBREG_BYTE (operand1);
4577 op1_subbyte /= GET_MODE_SIZE (DImode);
4578 op1_subbyte *= GET_MODE_SIZE (DImode);
4579 operand1 = XEXP (operand1, 0);
4582 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
4584 emit_insn (gen_ashrdi3 (operand0, temp, shift_56));
4588 (define_insn "*sign_extendqidi2_insn"
4589 [(set (match_operand:DI 0 "register_operand" "=r")
4590 (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
4593 [(set_attr "type" "sload")
4594 (set_attr "us3load_type" "3cycle")])
4596 (define_expand "extendhidi2"
4597 [(set (match_operand:DI 0 "register_operand" "")
4598 (sign_extend:DI (match_operand:HI 1 "register_operand" "")))]
4602 rtx temp = gen_reg_rtx (DImode);
4603 rtx shift_48 = GEN_INT (48);
4604 int op1_subbyte = 0;
4606 if (GET_CODE (operand1) == SUBREG)
4608 op1_subbyte = SUBREG_BYTE (operand1);
4609 op1_subbyte /= GET_MODE_SIZE (DImode);
4610 op1_subbyte *= GET_MODE_SIZE (DImode);
4611 operand1 = XEXP (operand1, 0);
4614 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
4616 emit_insn (gen_ashrdi3 (operand0, temp, shift_48));
4620 (define_insn "*sign_extendhidi2_insn"
4621 [(set (match_operand:DI 0 "register_operand" "=r")
4622 (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
4625 [(set_attr "type" "sload")
4626 (set_attr "us3load_type" "3cycle")])
4628 (define_expand "extendsidi2"
4629 [(set (match_operand:DI 0 "register_operand" "")
4630 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
4634 (define_insn "*sign_extendsidi2_insn"
4635 [(set (match_operand:DI 0 "register_operand" "=r,r")
4636 (sign_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
4641 [(set_attr "type" "shift,sload")
4642 (set_attr "us3load_type" "*,3cycle")])
4644 ;; Special pattern for optimizing bit-field compares. This is needed
4645 ;; because combine uses this as a canonical form.
4647 (define_insn "*cmp_zero_extract"
4650 (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
4651 (match_operand:SI 1 "small_int_or_double" "n")
4652 (match_operand:SI 2 "small_int_or_double" "n"))
4654 "(GET_CODE (operands[2]) == CONST_INT
4655 && INTVAL (operands[2]) > 19)
4656 || (GET_CODE (operands[2]) == CONST_DOUBLE
4657 && CONST_DOUBLE_LOW (operands[2]) > 19)"
4660 int len = (GET_CODE (operands[1]) == CONST_INT
4661 ? INTVAL (operands[1])
4662 : CONST_DOUBLE_LOW (operands[1]));
4664 (GET_CODE (operands[2]) == CONST_INT
4665 ? INTVAL (operands[2])
4666 : CONST_DOUBLE_LOW (operands[2])) - len;
4667 HOST_WIDE_INT mask = ((1 << len) - 1) << pos;
4669 operands[1] = GEN_INT (mask);
4670 return \"andcc\\t%0, %1, %%g0\";
4672 [(set_attr "type" "compare")])
4674 (define_insn "*cmp_zero_extract_sp64"
4677 (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
4678 (match_operand:SI 1 "small_int_or_double" "n")
4679 (match_operand:SI 2 "small_int_or_double" "n"))
4682 && ((GET_CODE (operands[2]) == CONST_INT
4683 && INTVAL (operands[2]) > 51)
4684 || (GET_CODE (operands[2]) == CONST_DOUBLE
4685 && CONST_DOUBLE_LOW (operands[2]) > 51))"
4688 int len = (GET_CODE (operands[1]) == CONST_INT
4689 ? INTVAL (operands[1])
4690 : CONST_DOUBLE_LOW (operands[1]));
4692 (GET_CODE (operands[2]) == CONST_INT
4693 ? INTVAL (operands[2])
4694 : CONST_DOUBLE_LOW (operands[2])) - len;
4695 HOST_WIDE_INT mask = (((unsigned HOST_WIDE_INT) 1 << len) - 1) << pos;
4697 operands[1] = GEN_INT (mask);
4698 return \"andcc\\t%0, %1, %%g0\";
4700 [(set_attr "type" "compare")])
4702 ;; Conversions between float, double and long double.
4704 (define_insn "extendsfdf2"
4705 [(set (match_operand:DF 0 "register_operand" "=e")
4707 (match_operand:SF 1 "register_operand" "f")))]
4710 [(set_attr "type" "fp")
4711 (set_attr "fptype" "double")])
4713 (define_expand "extendsftf2"
4714 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4716 (match_operand:SF 1 "register_operand" "")))]
4717 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4718 "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
4720 (define_insn "*extendsftf2_hq"
4721 [(set (match_operand:TF 0 "register_operand" "=e")
4723 (match_operand:SF 1 "register_operand" "f")))]
4724 "TARGET_FPU && TARGET_HARD_QUAD"
4726 [(set_attr "type" "fp")])
4728 (define_expand "extenddftf2"
4729 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4731 (match_operand:DF 1 "register_operand" "")))]
4732 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4733 "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
4735 (define_insn "*extenddftf2_hq"
4736 [(set (match_operand:TF 0 "register_operand" "=e")
4738 (match_operand:DF 1 "register_operand" "e")))]
4739 "TARGET_FPU && TARGET_HARD_QUAD"
4741 [(set_attr "type" "fp")])
4743 (define_insn "truncdfsf2"
4744 [(set (match_operand:SF 0 "register_operand" "=f")
4746 (match_operand:DF 1 "register_operand" "e")))]
4749 [(set_attr "type" "fp")
4750 (set_attr "fptype" "double")])
4752 (define_expand "trunctfsf2"
4753 [(set (match_operand:SF 0 "register_operand" "")
4755 (match_operand:TF 1 "general_operand" "")))]
4756 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4757 "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
4759 (define_insn "*trunctfsf2_hq"
4760 [(set (match_operand:SF 0 "register_operand" "=f")
4762 (match_operand:TF 1 "register_operand" "e")))]
4763 "TARGET_FPU && TARGET_HARD_QUAD"
4765 [(set_attr "type" "fp")])
4767 (define_expand "trunctfdf2"
4768 [(set (match_operand:DF 0 "register_operand" "")
4770 (match_operand:TF 1 "general_operand" "")))]
4771 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4772 "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
4774 (define_insn "*trunctfdf2_hq"
4775 [(set (match_operand:DF 0 "register_operand" "=e")
4777 (match_operand:TF 1 "register_operand" "e")))]
4778 "TARGET_FPU && TARGET_HARD_QUAD"
4780 [(set_attr "type" "fp")])
4782 ;; Conversion between fixed point and floating point.
4784 (define_insn "floatsisf2"
4785 [(set (match_operand:SF 0 "register_operand" "=f")
4786 (float:SF (match_operand:SI 1 "register_operand" "f")))]
4789 [(set_attr "type" "fp")
4790 (set_attr "fptype" "double")])
4792 (define_insn "floatsidf2"
4793 [(set (match_operand:DF 0 "register_operand" "=e")
4794 (float:DF (match_operand:SI 1 "register_operand" "f")))]
4797 [(set_attr "type" "fp")
4798 (set_attr "fptype" "double")])
4800 (define_expand "floatsitf2"
4801 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4802 (float:TF (match_operand:SI 1 "register_operand" "")))]
4803 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4804 "emit_tfmode_cvt (FLOAT, operands); DONE;")
4806 (define_insn "*floatsitf2_hq"
4807 [(set (match_operand:TF 0 "register_operand" "=e")
4808 (float:TF (match_operand:SI 1 "register_operand" "f")))]
4809 "TARGET_FPU && TARGET_HARD_QUAD"
4811 [(set_attr "type" "fp")])
4813 (define_expand "floatunssitf2"
4814 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4815 (unsigned_float:TF (match_operand:SI 1 "register_operand" "")))]
4816 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4817 "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
4819 ;; Now the same for 64 bit sources.
4821 (define_insn "floatdisf2"
4822 [(set (match_operand:SF 0 "register_operand" "=f")
4823 (float:SF (match_operand:DI 1 "register_operand" "e")))]
4824 "TARGET_V9 && TARGET_FPU"
4826 [(set_attr "type" "fp")
4827 (set_attr "fptype" "double")])
4829 (define_expand "floatunsdisf2"
4830 [(use (match_operand:SF 0 "register_operand" ""))
4831 (use (match_operand:DI 1 "register_operand" ""))]
4832 "TARGET_ARCH64 && TARGET_FPU"
4833 "sparc_emit_floatunsdi (operands); DONE;")
4835 (define_insn "floatdidf2"
4836 [(set (match_operand:DF 0 "register_operand" "=e")
4837 (float:DF (match_operand:DI 1 "register_operand" "e")))]
4838 "TARGET_V9 && TARGET_FPU"
4840 [(set_attr "type" "fp")
4841 (set_attr "fptype" "double")])
4843 (define_expand "floatunsdidf2"
4844 [(use (match_operand:DF 0 "register_operand" ""))
4845 (use (match_operand:DI 1 "register_operand" ""))]
4846 "TARGET_ARCH64 && TARGET_FPU"
4847 "sparc_emit_floatunsdi (operands); DONE;")
4849 (define_expand "floatditf2"
4850 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4851 (float:TF (match_operand:DI 1 "register_operand" "")))]
4852 "TARGET_FPU && TARGET_V9 && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4853 "emit_tfmode_cvt (FLOAT, operands); DONE;")
4855 (define_insn "*floatditf2_hq"
4856 [(set (match_operand:TF 0 "register_operand" "=e")
4857 (float:TF (match_operand:DI 1 "register_operand" "e")))]
4858 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
4860 [(set_attr "type" "fp")])
4862 (define_expand "floatunsditf2"
4863 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4864 (unsigned_float:TF (match_operand:DI 1 "register_operand" "")))]
4865 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4866 "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
4868 ;; Convert a float to an actual integer.
4869 ;; Truncation is performed as part of the conversion.
4871 (define_insn "fix_truncsfsi2"
4872 [(set (match_operand:SI 0 "register_operand" "=f")
4873 (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
4876 [(set_attr "type" "fp")
4877 (set_attr "fptype" "double")])
4879 (define_insn "fix_truncdfsi2"
4880 [(set (match_operand:SI 0 "register_operand" "=f")
4881 (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
4884 [(set_attr "type" "fp")
4885 (set_attr "fptype" "double")])
4887 (define_expand "fix_trunctfsi2"
4888 [(set (match_operand:SI 0 "register_operand" "")
4889 (fix:SI (match_operand:TF 1 "general_operand" "")))]
4890 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4891 "emit_tfmode_cvt (FIX, operands); DONE;")
4893 (define_insn "*fix_trunctfsi2_hq"
4894 [(set (match_operand:SI 0 "register_operand" "=f")
4895 (fix:SI (match_operand:TF 1 "register_operand" "e")))]
4896 "TARGET_FPU && TARGET_HARD_QUAD"
4898 [(set_attr "type" "fp")])
4900 (define_expand "fixuns_trunctfsi2"
4901 [(set (match_operand:SI 0 "register_operand" "")
4902 (unsigned_fix:SI (match_operand:TF 1 "general_operand" "")))]
4903 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4904 "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
4906 ;; Now the same, for V9 targets
4908 (define_insn "fix_truncsfdi2"
4909 [(set (match_operand:DI 0 "register_operand" "=e")
4910 (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
4911 "TARGET_V9 && TARGET_FPU"
4913 [(set_attr "type" "fp")
4914 (set_attr "fptype" "double")])
4916 (define_insn "fix_truncdfdi2"
4917 [(set (match_operand:DI 0 "register_operand" "=e")
4918 (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
4919 "TARGET_V9 && TARGET_FPU"
4921 [(set_attr "type" "fp")
4922 (set_attr "fptype" "double")])
4924 (define_expand "fix_trunctfdi2"
4925 [(set (match_operand:DI 0 "register_operand" "")
4926 (fix:DI (match_operand:TF 1 "general_operand" "")))]
4927 "TARGET_V9 && TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4928 "emit_tfmode_cvt (FIX, operands); DONE;")
4930 (define_insn "*fix_trunctfdi2_hq"
4931 [(set (match_operand:DI 0 "register_operand" "=e")
4932 (fix:DI (match_operand:TF 1 "register_operand" "e")))]
4933 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
4935 [(set_attr "type" "fp")])
4937 (define_expand "fixuns_trunctfdi2"
4938 [(set (match_operand:DI 0 "register_operand" "")
4939 (unsigned_fix:DI (match_operand:TF 1 "general_operand" "")))]
4940 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4941 "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
4943 ;;- arithmetic instructions
4945 (define_expand "adddi3"
4946 [(set (match_operand:DI 0 "register_operand" "=r")
4947 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
4948 (match_operand:DI 2 "arith_double_add_operand" "rHI")))]
4954 if (! TARGET_ARCH64)
4956 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
4957 gen_rtx_SET (VOIDmode, operands[0],
4958 gen_rtx_PLUS (DImode, operands[1],
4960 gen_rtx_CLOBBER (VOIDmode,
4961 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
4964 if (arith_double_4096_operand(operands[2], DImode))
4966 switch (GET_CODE (operands[1]))
4968 case CONST_INT: i = INTVAL (operands[1]); break;
4969 case CONST_DOUBLE: i = CONST_DOUBLE_LOW (operands[1]); break;
4971 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
4972 gen_rtx_MINUS (DImode, operands[1],
4976 emit_insn (gen_movdi (operands[0], GEN_INT (i + 4096)));
4981 (define_insn "adddi3_insn_sp32"
4982 [(set (match_operand:DI 0 "register_operand" "=r")
4983 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
4984 (match_operand:DI 2 "arith_double_operand" "rHI")))
4985 (clobber (reg:CC 100))]
4988 [(set_attr "length" "2")])
4991 [(set (match_operand:DI 0 "register_operand" "")
4992 (plus:DI (match_operand:DI 1 "arith_double_operand" "")
4993 (match_operand:DI 2 "arith_double_operand" "")))
4994 (clobber (reg:CC 100))]
4995 "! TARGET_ARCH64 && reload_completed"
4996 [(parallel [(set (reg:CC_NOOV 100)
4997 (compare:CC_NOOV (plus:SI (match_dup 4)
5001 (plus:SI (match_dup 4) (match_dup 5)))])
5003 (plus:SI (plus:SI (match_dup 7)
5005 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5008 operands[3] = gen_lowpart (SImode, operands[0]);
5009 operands[4] = gen_lowpart (SImode, operands[1]);
5010 operands[5] = gen_lowpart (SImode, operands[2]);
5011 operands[6] = gen_highpart (SImode, operands[0]);
5012 operands[7] = gen_highpart_mode (SImode, DImode, operands[1]);
5013 #if HOST_BITS_PER_WIDE_INT == 32
5014 if (GET_CODE (operands[2]) == CONST_INT)
5016 if (INTVAL (operands[2]) < 0)
5017 operands[8] = constm1_rtx;
5019 operands[8] = const0_rtx;
5023 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
5027 [(set (match_operand:DI 0 "register_operand" "")
5028 (minus:DI (match_operand:DI 1 "arith_double_operand" "")
5029 (match_operand:DI 2 "arith_double_operand" "")))
5030 (clobber (reg:CC 100))]
5031 "! TARGET_ARCH64 && reload_completed"
5032 [(parallel [(set (reg:CC_NOOV 100)
5033 (compare:CC_NOOV (minus:SI (match_dup 4)
5037 (minus:SI (match_dup 4) (match_dup 5)))])
5039 (minus:SI (minus:SI (match_dup 7)
5041 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5044 operands[3] = gen_lowpart (SImode, operands[0]);
5045 operands[4] = gen_lowpart (SImode, operands[1]);
5046 operands[5] = gen_lowpart (SImode, operands[2]);
5047 operands[6] = gen_highpart (SImode, operands[0]);
5048 operands[7] = gen_highpart (SImode, operands[1]);
5049 #if HOST_BITS_PER_WIDE_INT == 32
5050 if (GET_CODE (operands[2]) == CONST_INT)
5052 if (INTVAL (operands[2]) < 0)
5053 operands[8] = constm1_rtx;
5055 operands[8] = const0_rtx;
5059 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
5062 ;; LTU here means "carry set"
5064 [(set (match_operand:SI 0 "register_operand" "=r")
5065 (plus:SI (plus:SI (match_operand:SI 1 "arith_operand" "%r")
5066 (match_operand:SI 2 "arith_operand" "rI"))
5067 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5070 [(set_attr "type" "ialuX")])
5072 (define_insn "*addx_extend_sp32"
5073 [(set (match_operand:DI 0 "register_operand" "=r")
5074 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
5075 (match_operand:SI 2 "arith_operand" "rI"))
5076 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5079 [(set_attr "length" "2")])
5082 [(set (match_operand:DI 0 "register_operand" "")
5083 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "")
5084 (match_operand:SI 2 "arith_operand" ""))
5085 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5086 "! TARGET_ARCH64 && reload_completed"
5087 [(set (match_dup 3) (plus:SI (plus:SI (match_dup 1) (match_dup 2))
5088 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
5089 (set (match_dup 4) (const_int 0))]
5090 "operands[3] = gen_lowpart (SImode, operands[0]);
5091 operands[4] = gen_highpart_mode (SImode, DImode, operands[1]);")
5093 (define_insn "*addx_extend_sp64"
5094 [(set (match_operand:DI 0 "register_operand" "=r")
5095 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
5096 (match_operand:SI 2 "arith_operand" "rI"))
5097 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5099 "addx\\t%r1, %2, %0"
5100 [(set_attr "type" "ialuX")])
5103 [(set (match_operand:SI 0 "register_operand" "=r")
5104 (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5105 (match_operand:SI 2 "arith_operand" "rI"))
5106 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5108 "subx\\t%r1, %2, %0"
5109 [(set_attr "type" "ialuX")])
5111 (define_insn "*subx_extend_sp64"
5112 [(set (match_operand:DI 0 "register_operand" "=r")
5113 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5114 (match_operand:SI 2 "arith_operand" "rI"))
5115 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5117 "subx\\t%r1, %2, %0"
5118 [(set_attr "type" "ialuX")])
5120 (define_insn "*subx_extend"
5121 [(set (match_operand:DI 0 "register_operand" "=r")
5122 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5123 (match_operand:SI 2 "arith_operand" "rI"))
5124 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5127 [(set_attr "length" "2")])
5130 [(set (match_operand:DI 0 "register_operand" "")
5131 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "")
5132 (match_operand:SI 2 "arith_operand" ""))
5133 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5134 "! TARGET_ARCH64 && reload_completed"
5135 [(set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 2))
5136 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
5137 (set (match_dup 4) (const_int 0))]
5138 "operands[3] = gen_lowpart (SImode, operands[0]);
5139 operands[4] = gen_highpart (SImode, operands[0]);")
5142 [(set (match_operand:DI 0 "register_operand" "=r")
5143 (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5144 (match_operand:DI 2 "register_operand" "r")))
5145 (clobber (reg:CC 100))]
5148 [(set_attr "length" "2")])
5151 [(set (match_operand:DI 0 "register_operand" "")
5152 (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
5153 (match_operand:DI 2 "register_operand" "")))
5154 (clobber (reg:CC 100))]
5155 "! TARGET_ARCH64 && reload_completed"
5156 [(parallel [(set (reg:CC_NOOV 100)
5157 (compare:CC_NOOV (plus:SI (match_dup 3) (match_dup 1))
5159 (set (match_dup 5) (plus:SI (match_dup 3) (match_dup 1)))])
5161 (plus:SI (plus:SI (match_dup 4) (const_int 0))
5162 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5163 "operands[3] = gen_lowpart (SImode, operands[2]);
5164 operands[4] = gen_highpart (SImode, operands[2]);
5165 operands[5] = gen_lowpart (SImode, operands[0]);
5166 operands[6] = gen_highpart (SImode, operands[0]);")
5168 (define_insn "*adddi3_sp64"
5169 [(set (match_operand:DI 0 "register_operand" "=r")
5170 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
5171 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5175 (define_expand "addsi3"
5176 [(set (match_operand:SI 0 "register_operand" "=r,d")
5177 (plus:SI (match_operand:SI 1 "arith_operand" "%r,d")
5178 (match_operand:SI 2 "arith_add_operand" "rI,d")))]
5182 if (arith_4096_operand(operands[2], SImode))
5184 if (GET_CODE (operands[1]) == CONST_INT)
5185 emit_insn (gen_movsi (operands[0],
5186 GEN_INT (INTVAL (operands[1]) + 4096)));
5188 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
5189 gen_rtx_MINUS (SImode, operands[1],
5195 (define_insn "*addsi3"
5196 [(set (match_operand:SI 0 "register_operand" "=r,d")
5197 (plus:SI (match_operand:SI 1 "arith_operand" "%r,d")
5198 (match_operand:SI 2 "arith_operand" "rI,d")))]
5202 fpadd32s\\t%1, %2, %0"
5203 [(set_attr "type" "*,fp")])
5205 (define_insn "*cmp_cc_plus"
5206 [(set (reg:CC_NOOV 100)
5207 (compare:CC_NOOV (plus:SI (match_operand:SI 0 "arith_operand" "%r")
5208 (match_operand:SI 1 "arith_operand" "rI"))
5211 "addcc\\t%0, %1, %%g0"
5212 [(set_attr "type" "compare")])
5214 (define_insn "*cmp_ccx_plus"
5215 [(set (reg:CCX_NOOV 100)
5216 (compare:CCX_NOOV (plus:DI (match_operand:DI 0 "arith_double_operand" "%r")
5217 (match_operand:DI 1 "arith_double_operand" "rHI"))
5220 "addcc\\t%0, %1, %%g0"
5221 [(set_attr "type" "compare")])
5223 (define_insn "*cmp_cc_plus_set"
5224 [(set (reg:CC_NOOV 100)
5225 (compare:CC_NOOV (plus:SI (match_operand:SI 1 "arith_operand" "%r")
5226 (match_operand:SI 2 "arith_operand" "rI"))
5228 (set (match_operand:SI 0 "register_operand" "=r")
5229 (plus:SI (match_dup 1) (match_dup 2)))]
5231 "addcc\\t%1, %2, %0"
5232 [(set_attr "type" "compare")])
5234 (define_insn "*cmp_ccx_plus_set"
5235 [(set (reg:CCX_NOOV 100)
5236 (compare:CCX_NOOV (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
5237 (match_operand:DI 2 "arith_double_operand" "rHI"))
5239 (set (match_operand:DI 0 "register_operand" "=r")
5240 (plus:DI (match_dup 1) (match_dup 2)))]
5242 "addcc\\t%1, %2, %0"
5243 [(set_attr "type" "compare")])
5245 (define_expand "subdi3"
5246 [(set (match_operand:DI 0 "register_operand" "=r")
5247 (minus:DI (match_operand:DI 1 "register_operand" "r")
5248 (match_operand:DI 2 "arith_double_add_operand" "rHI")))]
5252 if (! TARGET_ARCH64)
5254 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
5255 gen_rtx_SET (VOIDmode, operands[0],
5256 gen_rtx_MINUS (DImode, operands[1],
5258 gen_rtx_CLOBBER (VOIDmode,
5259 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
5262 if (arith_double_4096_operand(operands[2], DImode))
5264 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
5265 gen_rtx_PLUS (DImode, operands[1],
5271 (define_insn "*subdi3_sp32"
5272 [(set (match_operand:DI 0 "register_operand" "=r")
5273 (minus:DI (match_operand:DI 1 "register_operand" "r")
5274 (match_operand:DI 2 "arith_double_operand" "rHI")))
5275 (clobber (reg:CC 100))]
5278 [(set_attr "length" "2")])
5281 [(set (match_operand:DI 0 "register_operand" "")
5282 (minus:DI (match_operand:DI 1 "register_operand" "")
5283 (match_operand:DI 2 "arith_double_operand" "")))
5284 (clobber (reg:CC 100))]
5287 && (GET_CODE (operands[2]) == CONST_INT
5288 || GET_CODE (operands[2]) == CONST_DOUBLE)"
5289 [(clobber (const_int 0))]
5294 highp = gen_highpart_mode (SImode, DImode, operands[2]);
5295 lowp = gen_lowpart (SImode, operands[2]);
5296 if ((lowp == const0_rtx)
5297 && (operands[0] == operands[1]))
5299 emit_insn (gen_rtx_SET (VOIDmode,
5300 gen_highpart (SImode, operands[0]),
5301 gen_rtx_MINUS (SImode,
5302 gen_highpart_mode (SImode, DImode,
5308 emit_insn (gen_cmp_minus_cc_set (gen_lowpart (SImode, operands[0]),
5309 gen_lowpart (SImode, operands[1]),
5311 emit_insn (gen_subx (gen_highpart (SImode, operands[0]),
5312 gen_highpart_mode (SImode, DImode, operands[1]),
5319 [(set (match_operand:DI 0 "register_operand" "")
5320 (minus:DI (match_operand:DI 1 "register_operand" "")
5321 (match_operand:DI 2 "register_operand" "")))
5322 (clobber (reg:CC 100))]
5324 && reload_completed"
5325 [(clobber (const_int 0))]
5328 emit_insn (gen_cmp_minus_cc_set (gen_lowpart (SImode, operands[0]),
5329 gen_lowpart (SImode, operands[1]),
5330 gen_lowpart (SImode, operands[2])));
5331 emit_insn (gen_subx (gen_highpart (SImode, operands[0]),
5332 gen_highpart (SImode, operands[1]),
5333 gen_highpart (SImode, operands[2])));
5338 [(set (match_operand:DI 0 "register_operand" "=r")
5339 (minus:DI (match_operand:DI 1 "register_operand" "r")
5340 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))
5341 (clobber (reg:CC 100))]
5344 [(set_attr "length" "2")])
5347 [(set (match_operand:DI 0 "register_operand" "")
5348 (minus:DI (match_operand:DI 1 "register_operand" "")
5349 (zero_extend:DI (match_operand:SI 2 "register_operand" ""))))
5350 (clobber (reg:CC 100))]
5351 "! TARGET_ARCH64 && reload_completed"
5352 [(parallel [(set (reg:CC_NOOV 100)
5353 (compare:CC_NOOV (minus:SI (match_dup 3) (match_dup 2))
5355 (set (match_dup 5) (minus:SI (match_dup 3) (match_dup 2)))])
5357 (minus:SI (minus:SI (match_dup 4) (const_int 0))
5358 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5359 "operands[3] = gen_lowpart (SImode, operands[1]);
5360 operands[4] = gen_highpart (SImode, operands[1]);
5361 operands[5] = gen_lowpart (SImode, operands[0]);
5362 operands[6] = gen_highpart (SImode, operands[0]);")
5364 (define_insn "*subdi3_sp64"
5365 [(set (match_operand:DI 0 "register_operand" "=r")
5366 (minus:DI (match_operand:DI 1 "register_operand" "r")
5367 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5371 (define_expand "subsi3"
5372 [(set (match_operand:SI 0 "register_operand" "=r,d")
5373 (minus:SI (match_operand:SI 1 "register_operand" "r,d")
5374 (match_operand:SI 2 "arith_add_operand" "rI,d")))]
5378 if (arith_4096_operand(operands[2], SImode))
5380 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
5381 gen_rtx_PLUS (SImode, operands[1],
5387 (define_insn "*subsi3"
5388 [(set (match_operand:SI 0 "register_operand" "=r,d")
5389 (minus:SI (match_operand:SI 1 "register_operand" "r,d")
5390 (match_operand:SI 2 "arith_operand" "rI,d")))]
5394 fpsub32s\\t%1, %2, %0"
5395 [(set_attr "type" "*,fp")])
5397 (define_insn "*cmp_minus_cc"
5398 [(set (reg:CC_NOOV 100)
5399 (compare:CC_NOOV (minus:SI (match_operand:SI 0 "reg_or_0_operand" "rJ")
5400 (match_operand:SI 1 "arith_operand" "rI"))
5403 "subcc\\t%r0, %1, %%g0"
5404 [(set_attr "type" "compare")])
5406 (define_insn "*cmp_minus_ccx"
5407 [(set (reg:CCX_NOOV 100)
5408 (compare:CCX_NOOV (minus:DI (match_operand:DI 0 "register_operand" "r")
5409 (match_operand:DI 1 "arith_double_operand" "rHI"))
5412 "subcc\\t%0, %1, %%g0"
5413 [(set_attr "type" "compare")])
5415 (define_insn "cmp_minus_cc_set"
5416 [(set (reg:CC_NOOV 100)
5417 (compare:CC_NOOV (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5418 (match_operand:SI 2 "arith_operand" "rI"))
5420 (set (match_operand:SI 0 "register_operand" "=r")
5421 (minus:SI (match_dup 1) (match_dup 2)))]
5423 "subcc\\t%r1, %2, %0"
5424 [(set_attr "type" "compare")])
5426 (define_insn "*cmp_minus_ccx_set"
5427 [(set (reg:CCX_NOOV 100)
5428 (compare:CCX_NOOV (minus:DI (match_operand:DI 1 "register_operand" "r")
5429 (match_operand:DI 2 "arith_double_operand" "rHI"))
5431 (set (match_operand:DI 0 "register_operand" "=r")
5432 (minus:DI (match_dup 1) (match_dup 2)))]
5434 "subcc\\t%1, %2, %0"
5435 [(set_attr "type" "compare")])
5437 ;; Integer Multiply/Divide.
5439 ;; The 32 bit multiply/divide instructions are deprecated on v9, but at
5440 ;; least in UltraSPARC I, II and IIi it is a win tick-wise.
5442 (define_insn "mulsi3"
5443 [(set (match_operand:SI 0 "register_operand" "=r")
5444 (mult:SI (match_operand:SI 1 "arith_operand" "%r")
5445 (match_operand:SI 2 "arith_operand" "rI")))]
5448 [(set_attr "type" "imul")])
5450 (define_expand "muldi3"
5451 [(set (match_operand:DI 0 "register_operand" "=r")
5452 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r")
5453 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5454 "TARGET_ARCH64 || TARGET_V8PLUS"
5459 emit_insn (gen_muldi3_v8plus (operands[0], operands[1], operands[2]));
5464 (define_insn "*muldi3_sp64"
5465 [(set (match_operand:DI 0 "register_operand" "=r")
5466 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r")
5467 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5470 [(set_attr "type" "imul")])
5472 ;; V8plus wide multiply.
5474 (define_insn "muldi3_v8plus"
5475 [(set (match_operand:DI 0 "register_operand" "=r,h")
5476 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r,0")
5477 (match_operand:DI 2 "arith_double_operand" "rI,rI")))
5478 (clobber (match_scratch:SI 3 "=&h,X"))
5479 (clobber (match_scratch:SI 4 "=&h,X"))]
5483 if (sparc_check_64 (operands[1], insn) <= 0)
5484 output_asm_insn (\"srl\\t%L1, 0, %L1\", operands);
5485 if (which_alternative == 1)
5486 output_asm_insn (\"sllx\\t%H1, 32, %H1\", operands);
5487 if (GET_CODE (operands[2]) == CONST_INT)
5489 if (which_alternative == 1)
5490 return \"or\\t%L1, %H1, %H1\\n\\tmulx\\t%H1, %2, %L0\;srlx\\t%L0, 32, %H0\";
5492 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\";
5494 else if (rtx_equal_p (operands[1], operands[2]))
5496 if (which_alternative == 1)
5497 return \"or\\t%L1, %H1, %H1\\n\\tmulx\\t%H1, %H1, %L0\;srlx\\t%L0, 32, %H0\";
5499 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\";
5501 if (sparc_check_64 (operands[2], insn) <= 0)
5502 output_asm_insn (\"srl\\t%L2, 0, %L2\", operands);
5503 if (which_alternative == 1)
5504 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\";
5506 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\";
5508 [(set_attr "type" "multi")
5509 (set_attr "length" "9,8")])
5511 (define_insn "*cmp_mul_set"
5513 (compare:CC (mult:SI (match_operand:SI 1 "arith_operand" "%r")
5514 (match_operand:SI 2 "arith_operand" "rI"))
5516 (set (match_operand:SI 0 "register_operand" "=r")
5517 (mult:SI (match_dup 1) (match_dup 2)))]
5518 "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS"
5519 "smulcc\\t%1, %2, %0"
5520 [(set_attr "type" "imul")])
5522 (define_expand "mulsidi3"
5523 [(set (match_operand:DI 0 "register_operand" "")
5524 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
5525 (sign_extend:DI (match_operand:SI 2 "arith_operand" ""))))]
5529 if (CONSTANT_P (operands[2]))
5532 emit_insn (gen_const_mulsidi3_v8plus (operands[0], operands[1],
5535 emit_insn (gen_const_mulsidi3_sp32 (operands[0], operands[1],
5541 emit_insn (gen_mulsidi3_v8plus (operands[0], operands[1], operands[2]));
5546 ;; V9 puts the 64 bit product in a 64 bit register. Only out or global
5547 ;; registers can hold 64 bit values in the V8plus environment.
5549 (define_insn "mulsidi3_v8plus"
5550 [(set (match_operand:DI 0 "register_operand" "=h,r")
5551 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5552 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
5553 (clobber (match_scratch:SI 3 "=X,&h"))]
5556 smul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
5557 smul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
5558 [(set_attr "type" "multi")
5559 (set_attr "length" "2,3")])
5562 (define_insn "const_mulsidi3_v8plus"
5563 [(set (match_operand:DI 0 "register_operand" "=h,r")
5564 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5565 (match_operand:SI 2 "small_int" "I,I")))
5566 (clobber (match_scratch:SI 3 "=X,&h"))]
5569 smul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
5570 smul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
5571 [(set_attr "type" "multi")
5572 (set_attr "length" "2,3")])
5575 (define_insn "*mulsidi3_sp32"
5576 [(set (match_operand:DI 0 "register_operand" "=r")
5577 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5578 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
5582 return TARGET_SPARCLET ? \"smuld\\t%1, %2, %L0\" : \"smul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
5585 (if_then_else (eq_attr "isa" "sparclet")
5586 (const_string "imul") (const_string "multi")))
5587 (set (attr "length")
5588 (if_then_else (eq_attr "isa" "sparclet")
5589 (const_int 1) (const_int 2)))])
5591 (define_insn "*mulsidi3_sp64"
5592 [(set (match_operand:DI 0 "register_operand" "=r")
5593 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5594 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
5595 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5597 [(set_attr "type" "imul")])
5599 ;; Extra pattern, because sign_extend of a constant isn't valid.
5602 (define_insn "const_mulsidi3_sp32"
5603 [(set (match_operand:DI 0 "register_operand" "=r")
5604 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5605 (match_operand:SI 2 "small_int" "I")))]
5609 return TARGET_SPARCLET ? \"smuld\\t%1, %2, %L0\" : \"smul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
5612 (if_then_else (eq_attr "isa" "sparclet")
5613 (const_string "imul") (const_string "multi")))
5614 (set (attr "length")
5615 (if_then_else (eq_attr "isa" "sparclet")
5616 (const_int 1) (const_int 2)))])
5618 (define_insn "const_mulsidi3_sp64"
5619 [(set (match_operand:DI 0 "register_operand" "=r")
5620 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5621 (match_operand:SI 2 "small_int" "I")))]
5622 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5624 [(set_attr "type" "imul")])
5626 (define_expand "smulsi3_highpart"
5627 [(set (match_operand:SI 0 "register_operand" "")
5629 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
5630 (sign_extend:DI (match_operand:SI 2 "arith_operand" "")))
5632 "TARGET_HARD_MUL && TARGET_ARCH32"
5635 if (CONSTANT_P (operands[2]))
5639 emit_insn (gen_const_smulsi3_highpart_v8plus (operands[0],
5645 emit_insn (gen_const_smulsi3_highpart (operands[0], operands[1], operands[2]));
5650 emit_insn (gen_smulsi3_highpart_v8plus (operands[0], operands[1],
5651 operands[2], GEN_INT (32)));
5657 (define_insn "smulsi3_highpart_v8plus"
5658 [(set (match_operand:SI 0 "register_operand" "=h,r")
5660 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5661 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
5662 (match_operand:SI 3 "const_int_operand" "i,i"))))
5663 (clobber (match_scratch:SI 4 "=X,&h"))]
5666 smul\\t%1, %2, %0\;srlx\\t%0, %3, %0
5667 smul\\t%1, %2, %4\;srlx\\t%4, %3, %0"
5668 [(set_attr "type" "multi")
5669 (set_attr "length" "2")])
5671 ;; The combiner changes TRUNCATE in the previous pattern to SUBREG.
5674 [(set (match_operand:SI 0 "register_operand" "=h,r")
5677 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5678 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
5679 (match_operand:SI 3 "const_int_operand" "i,i"))
5681 (clobber (match_scratch:SI 4 "=X,&h"))]
5684 smul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
5685 smul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
5686 [(set_attr "type" "multi")
5687 (set_attr "length" "2")])
5690 (define_insn "const_smulsi3_highpart_v8plus"
5691 [(set (match_operand:SI 0 "register_operand" "=h,r")
5693 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5694 (match_operand 2 "small_int" "i,i"))
5695 (match_operand:SI 3 "const_int_operand" "i,i"))))
5696 (clobber (match_scratch:SI 4 "=X,&h"))]
5699 smul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
5700 smul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
5701 [(set_attr "type" "multi")
5702 (set_attr "length" "2")])
5705 (define_insn "*smulsi3_highpart_sp32"
5706 [(set (match_operand:SI 0 "register_operand" "=r")
5708 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5709 (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
5712 "smul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
5713 [(set_attr "type" "multi")
5714 (set_attr "length" "2")])
5717 (define_insn "const_smulsi3_highpart"
5718 [(set (match_operand:SI 0 "register_operand" "=r")
5720 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5721 (match_operand:SI 2 "register_operand" "r"))
5724 "smul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
5725 [(set_attr "type" "multi")
5726 (set_attr "length" "2")])
5728 (define_expand "umulsidi3"
5729 [(set (match_operand:DI 0 "register_operand" "")
5730 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
5731 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" ""))))]
5735 if (CONSTANT_P (operands[2]))
5738 emit_insn (gen_const_umulsidi3_v8plus (operands[0], operands[1],
5741 emit_insn (gen_const_umulsidi3_sp32 (operands[0], operands[1],
5747 emit_insn (gen_umulsidi3_v8plus (operands[0], operands[1], operands[2]));
5753 (define_insn "umulsidi3_v8plus"
5754 [(set (match_operand:DI 0 "register_operand" "=h,r")
5755 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5756 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
5757 (clobber (match_scratch:SI 3 "=X,&h"))]
5760 umul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
5761 umul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
5762 [(set_attr "type" "multi")
5763 (set_attr "length" "2,3")])
5766 (define_insn "*umulsidi3_sp32"
5767 [(set (match_operand:DI 0 "register_operand" "=r")
5768 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5769 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
5773 return TARGET_SPARCLET ? \"umuld\\t%1, %2, %L0\" : \"umul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
5776 (if_then_else (eq_attr "isa" "sparclet")
5777 (const_string "imul") (const_string "multi")))
5778 (set (attr "length")
5779 (if_then_else (eq_attr "isa" "sparclet")
5780 (const_int 1) (const_int 2)))])
5782 (define_insn "*umulsidi3_sp64"
5783 [(set (match_operand:DI 0 "register_operand" "=r")
5784 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5785 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
5786 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5788 [(set_attr "type" "imul")])
5790 ;; Extra pattern, because sign_extend of a constant isn't valid.
5793 (define_insn "const_umulsidi3_sp32"
5794 [(set (match_operand:DI 0 "register_operand" "=r")
5795 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5796 (match_operand:SI 2 "uns_small_int" "")))]
5800 return TARGET_SPARCLET ? \"umuld\\t%1, %2, %L0\" : \"umul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
5803 (if_then_else (eq_attr "isa" "sparclet")
5804 (const_string "imul") (const_string "multi")))
5805 (set (attr "length")
5806 (if_then_else (eq_attr "isa" "sparclet")
5807 (const_int 1) (const_int 2)))])
5809 (define_insn "const_umulsidi3_sp64"
5810 [(set (match_operand:DI 0 "register_operand" "=r")
5811 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5812 (match_operand:SI 2 "uns_small_int" "")))]
5813 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5815 [(set_attr "type" "imul")])
5818 (define_insn "const_umulsidi3_v8plus"
5819 [(set (match_operand:DI 0 "register_operand" "=h,r")
5820 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5821 (match_operand:SI 2 "uns_small_int" "")))
5822 (clobber (match_scratch:SI 3 "=X,h"))]
5825 umul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
5826 umul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
5827 [(set_attr "type" "multi")
5828 (set_attr "length" "2,3")])
5830 (define_expand "umulsi3_highpart"
5831 [(set (match_operand:SI 0 "register_operand" "")
5833 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
5834 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" "")))
5836 "TARGET_HARD_MUL && TARGET_ARCH32"
5839 if (CONSTANT_P (operands[2]))
5843 emit_insn (gen_const_umulsi3_highpart_v8plus (operands[0],
5849 emit_insn (gen_const_umulsi3_highpart (operands[0], operands[1], operands[2]));
5854 emit_insn (gen_umulsi3_highpart_v8plus (operands[0], operands[1],
5855 operands[2], GEN_INT (32)));
5861 (define_insn "umulsi3_highpart_v8plus"
5862 [(set (match_operand:SI 0 "register_operand" "=h,r")
5864 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5865 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
5866 (match_operand:SI 3 "const_int_operand" "i,i"))))
5867 (clobber (match_scratch:SI 4 "=X,h"))]
5870 umul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
5871 umul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
5872 [(set_attr "type" "multi")
5873 (set_attr "length" "2")])
5876 (define_insn "const_umulsi3_highpart_v8plus"
5877 [(set (match_operand:SI 0 "register_operand" "=h,r")
5879 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5880 (match_operand:SI 2 "uns_small_int" ""))
5881 (match_operand:SI 3 "const_int_operand" "i,i"))))
5882 (clobber (match_scratch:SI 4 "=X,h"))]
5885 umul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
5886 umul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
5887 [(set_attr "type" "multi")
5888 (set_attr "length" "2")])
5891 (define_insn "*umulsi3_highpart_sp32"
5892 [(set (match_operand:SI 0 "register_operand" "=r")
5894 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5895 (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
5898 "umul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
5899 [(set_attr "type" "multi")
5900 (set_attr "length" "2")])
5903 (define_insn "const_umulsi3_highpart"
5904 [(set (match_operand:SI 0 "register_operand" "=r")
5906 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5907 (match_operand:SI 2 "uns_small_int" ""))
5910 "umul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
5911 [(set_attr "type" "multi")
5912 (set_attr "length" "2")])
5914 ;; The v8 architecture specifies that there must be 3 instructions between
5915 ;; a y register write and a use of it for correct results.
5917 (define_expand "divsi3"
5918 [(parallel [(set (match_operand:SI 0 "register_operand" "=r,r")
5919 (div:SI (match_operand:SI 1 "register_operand" "r,r")
5920 (match_operand:SI 2 "input_operand" "rI,m")))
5921 (clobber (match_scratch:SI 3 "=&r,&r"))])]
5922 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
5927 operands[3] = gen_reg_rtx(SImode);
5928 emit_insn (gen_ashrsi3 (operands[3], operands[1], GEN_INT (31)));
5929 emit_insn (gen_divsi3_sp64 (operands[0], operands[1], operands[2],
5935 (define_insn "divsi3_sp32"
5936 [(set (match_operand:SI 0 "register_operand" "=r,r")
5937 (div:SI (match_operand:SI 1 "register_operand" "r,r")
5938 (match_operand:SI 2 "input_operand" "rI,m")))
5939 (clobber (match_scratch:SI 3 "=&r,&r"))]
5940 "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS)
5944 if (which_alternative == 0)
5946 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tsdiv\\t%1, %2, %0\";
5948 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tnop\\n\\tnop\\n\\tnop\\n\\tsdiv\\t%1, %2, %0\";
5951 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tld\\t%2, %3\\n\\tsdiv\\t%1, %3, %0\";
5953 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\";
5955 [(set_attr "type" "multi")
5956 (set (attr "length")
5957 (if_then_else (eq_attr "isa" "v9")
5958 (const_int 4) (const_int 6)))])
5960 (define_insn "divsi3_sp64"
5961 [(set (match_operand:SI 0 "register_operand" "=r")
5962 (div:SI (match_operand:SI 1 "register_operand" "r")
5963 (match_operand:SI 2 "input_operand" "rI")))
5964 (use (match_operand:SI 3 "register_operand" "r"))]
5965 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5966 "wr\\t%%g0, %3, %%y\\n\\tsdiv\\t%1, %2, %0"
5967 [(set_attr "type" "multi")
5968 (set_attr "length" "2")])
5970 (define_insn "divdi3"
5971 [(set (match_operand:DI 0 "register_operand" "=r")
5972 (div:DI (match_operand:DI 1 "register_operand" "r")
5973 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5975 "sdivx\\t%1, %2, %0"
5976 [(set_attr "type" "idiv")])
5978 (define_insn "*cmp_sdiv_cc_set"
5980 (compare:CC (div:SI (match_operand:SI 1 "register_operand" "r")
5981 (match_operand:SI 2 "arith_operand" "rI"))
5983 (set (match_operand:SI 0 "register_operand" "=r")
5984 (div:SI (match_dup 1) (match_dup 2)))
5985 (clobber (match_scratch:SI 3 "=&r"))]
5986 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
5990 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tsdivcc\\t%1, %2, %0\";
5992 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tnop\\n\\tnop\\n\\tnop\\n\\tsdivcc\\t%1, %2, %0\";
5994 [(set_attr "type" "multi")
5995 (set (attr "length")
5996 (if_then_else (eq_attr "isa" "v9")
5997 (const_int 3) (const_int 6)))])
6000 (define_expand "udivsi3"
6001 [(set (match_operand:SI 0 "register_operand" "")
6002 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "")
6003 (match_operand:SI 2 "input_operand" "")))]
6004 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
6007 (define_insn "udivsi3_sp32"
6008 [(set (match_operand:SI 0 "register_operand" "=r,&r,&r")
6009 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "r,r,m")
6010 (match_operand:SI 2 "input_operand" "rI,m,r")))]
6012 || TARGET_DEPRECATED_V8_INSNS)
6016 output_asm_insn (\"wr\\t%%g0, %%g0, %%y\", operands);
6017 switch (which_alternative)
6020 return \"nop\\n\\tnop\\n\\tnop\\n\\tudiv\\t%1, %2, %0\";
6022 return \"ld\\t%2, %0\\n\\tnop\\n\\tnop\\n\\tudiv\\t%1, %0, %0\";
6024 return \"ld\\t%1, %0\\n\\tnop\\n\\tnop\\n\\tudiv\\t%0, %2, %0\";
6027 [(set_attr "type" "multi")
6028 (set_attr "length" "5")])
6030 (define_insn "udivsi3_sp64"
6031 [(set (match_operand:SI 0 "register_operand" "=r")
6032 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "r")
6033 (match_operand:SI 2 "input_operand" "rI")))]
6034 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6035 "wr\\t%%g0, 0, %%y\\n\\tudiv\\t%1, %2, %0"
6036 [(set_attr "type" "multi")
6037 (set_attr "length" "2")])
6039 (define_insn "udivdi3"
6040 [(set (match_operand:DI 0 "register_operand" "=r")
6041 (udiv:DI (match_operand:DI 1 "register_operand" "r")
6042 (match_operand:DI 2 "arith_double_operand" "rHI")))]
6044 "udivx\\t%1, %2, %0"
6045 [(set_attr "type" "idiv")])
6047 (define_insn "*cmp_udiv_cc_set"
6049 (compare:CC (udiv:SI (match_operand:SI 1 "register_operand" "r")
6050 (match_operand:SI 2 "arith_operand" "rI"))
6052 (set (match_operand:SI 0 "register_operand" "=r")
6053 (udiv:SI (match_dup 1) (match_dup 2)))]
6055 || TARGET_DEPRECATED_V8_INSNS"
6059 return \"wr\\t%%g0, %%g0, %%y\\n\\tudivcc\\t%1, %2, %0\";
6061 return \"wr\\t%%g0, %%g0, %%y\\n\\tnop\\n\\tnop\\n\\tnop\\n\\tudivcc\\t%1, %2, %0\";
6063 [(set_attr "type" "multi")
6064 (set (attr "length")
6065 (if_then_else (eq_attr "isa" "v9")
6066 (const_int 2) (const_int 5)))])
6068 ; sparclet multiply/accumulate insns
6070 (define_insn "*smacsi"
6071 [(set (match_operand:SI 0 "register_operand" "=r")
6072 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "%r")
6073 (match_operand:SI 2 "arith_operand" "rI"))
6074 (match_operand:SI 3 "register_operand" "0")))]
6077 [(set_attr "type" "imul")])
6079 (define_insn "*smacdi"
6080 [(set (match_operand:DI 0 "register_operand" "=r")
6081 (plus:DI (mult:DI (sign_extend:DI
6082 (match_operand:SI 1 "register_operand" "%r"))
6084 (match_operand:SI 2 "register_operand" "r")))
6085 (match_operand:DI 3 "register_operand" "0")))]
6087 "smacd\\t%1, %2, %L0"
6088 [(set_attr "type" "imul")])
6090 (define_insn "*umacdi"
6091 [(set (match_operand:DI 0 "register_operand" "=r")
6092 (plus:DI (mult:DI (zero_extend:DI
6093 (match_operand:SI 1 "register_operand" "%r"))
6095 (match_operand:SI 2 "register_operand" "r")))
6096 (match_operand:DI 3 "register_operand" "0")))]
6098 "umacd\\t%1, %2, %L0"
6099 [(set_attr "type" "imul")])
6101 ;;- Boolean instructions
6102 ;; We define DImode `and' so with DImode `not' we can get
6103 ;; DImode `andn'. Other combinations are possible.
6105 (define_expand "anddi3"
6106 [(set (match_operand:DI 0 "register_operand" "")
6107 (and:DI (match_operand:DI 1 "arith_double_operand" "")
6108 (match_operand:DI 2 "arith_double_operand" "")))]
6112 (define_insn "*anddi3_sp32"
6113 [(set (match_operand:DI 0 "register_operand" "=r,b")
6114 (and:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6115 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6120 [(set_attr "type" "*,fp")
6121 (set_attr "length" "2,*")
6122 (set_attr "fptype" "double")])
6124 (define_insn "*anddi3_sp64"
6125 [(set (match_operand:DI 0 "register_operand" "=r,b")
6126 (and:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6127 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6132 [(set_attr "type" "*,fp")
6133 (set_attr "fptype" "double")])
6135 (define_insn "andsi3"
6136 [(set (match_operand:SI 0 "register_operand" "=r,d")
6137 (and:SI (match_operand:SI 1 "arith_operand" "%r,d")
6138 (match_operand:SI 2 "arith_operand" "rI,d")))]
6143 [(set_attr "type" "*,fp")])
6146 [(set (match_operand:SI 0 "register_operand" "")
6147 (and:SI (match_operand:SI 1 "register_operand" "")
6148 (match_operand:SI 2 "" "")))
6149 (clobber (match_operand:SI 3 "register_operand" ""))]
6150 "GET_CODE (operands[2]) == CONST_INT
6151 && !SMALL_INT32 (operands[2])
6152 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6153 [(set (match_dup 3) (match_dup 4))
6154 (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 1)))]
6157 operands[4] = GEN_INT (~INTVAL (operands[2]));
6160 ;; Split DImode logical operations requiring two instructions.
6162 [(set (match_operand:DI 0 "register_operand" "")
6163 (match_operator:DI 1 "cc_arithop" ; AND, IOR, XOR
6164 [(match_operand:DI 2 "register_operand" "")
6165 (match_operand:DI 3 "arith_double_operand" "")]))]
6168 && ((GET_CODE (operands[0]) == REG
6169 && REGNO (operands[0]) < 32)
6170 || (GET_CODE (operands[0]) == SUBREG
6171 && GET_CODE (SUBREG_REG (operands[0])) == REG
6172 && REGNO (SUBREG_REG (operands[0])) < 32))"
6173 [(set (match_dup 4) (match_op_dup:SI 1 [(match_dup 6) (match_dup 8)]))
6174 (set (match_dup 5) (match_op_dup:SI 1 [(match_dup 7) (match_dup 9)]))]
6177 operands[4] = gen_highpart (SImode, operands[0]);
6178 operands[5] = gen_lowpart (SImode, operands[0]);
6179 operands[6] = gen_highpart (SImode, operands[2]);
6180 operands[7] = gen_lowpart (SImode, operands[2]);
6181 #if HOST_BITS_PER_WIDE_INT == 32
6182 if (GET_CODE (operands[3]) == CONST_INT)
6184 if (INTVAL (operands[3]) < 0)
6185 operands[8] = constm1_rtx;
6187 operands[8] = const0_rtx;
6191 operands[8] = gen_highpart_mode (SImode, DImode, operands[3]);
6192 operands[9] = gen_lowpart (SImode, operands[3]);
6195 (define_insn "*and_not_di_sp32"
6196 [(set (match_operand:DI 0 "register_operand" "=r,b")
6197 (and:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6198 (match_operand:DI 2 "register_operand" "r,b")))]
6202 fandnot1\\t%1, %2, %0"
6203 [(set_attr "type" "*,fp")
6204 (set_attr "length" "2,*")
6205 (set_attr "fptype" "double")])
6208 [(set (match_operand:DI 0 "register_operand" "")
6209 (and:DI (not:DI (match_operand:DI 1 "register_operand" ""))
6210 (match_operand:DI 2 "register_operand" "")))]
6213 && ((GET_CODE (operands[0]) == REG
6214 && REGNO (operands[0]) < 32)
6215 || (GET_CODE (operands[0]) == SUBREG
6216 && GET_CODE (SUBREG_REG (operands[0])) == REG
6217 && REGNO (SUBREG_REG (operands[0])) < 32))"
6218 [(set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))
6219 (set (match_dup 6) (and:SI (not:SI (match_dup 7)) (match_dup 8)))]
6220 "operands[3] = gen_highpart (SImode, operands[0]);
6221 operands[4] = gen_highpart (SImode, operands[1]);
6222 operands[5] = gen_highpart (SImode, operands[2]);
6223 operands[6] = gen_lowpart (SImode, operands[0]);
6224 operands[7] = gen_lowpart (SImode, operands[1]);
6225 operands[8] = gen_lowpart (SImode, operands[2]);")
6227 (define_insn "*and_not_di_sp64"
6228 [(set (match_operand:DI 0 "register_operand" "=r,b")
6229 (and:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6230 (match_operand:DI 2 "register_operand" "r,b")))]
6234 fandnot1\\t%1, %2, %0"
6235 [(set_attr "type" "*,fp")
6236 (set_attr "fptype" "double")])
6238 (define_insn "*and_not_si"
6239 [(set (match_operand:SI 0 "register_operand" "=r,d")
6240 (and:SI (not:SI (match_operand:SI 1 "register_operand" "r,d"))
6241 (match_operand:SI 2 "register_operand" "r,d")))]
6245 fandnot1s\\t%1, %2, %0"
6246 [(set_attr "type" "*,fp")])
6248 (define_expand "iordi3"
6249 [(set (match_operand:DI 0 "register_operand" "")
6250 (ior:DI (match_operand:DI 1 "arith_double_operand" "")
6251 (match_operand:DI 2 "arith_double_operand" "")))]
6255 (define_insn "*iordi3_sp32"
6256 [(set (match_operand:DI 0 "register_operand" "=r,b")
6257 (ior:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6258 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6263 [(set_attr "type" "*,fp")
6264 (set_attr "length" "2,*")
6265 (set_attr "fptype" "double")])
6267 (define_insn "*iordi3_sp64"
6268 [(set (match_operand:DI 0 "register_operand" "=r,b")
6269 (ior:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6270 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6275 [(set_attr "type" "*,fp")
6276 (set_attr "fptype" "double")])
6278 (define_insn "iorsi3"
6279 [(set (match_operand:SI 0 "register_operand" "=r,d")
6280 (ior:SI (match_operand:SI 1 "arith_operand" "%r,d")
6281 (match_operand:SI 2 "arith_operand" "rI,d")))]
6286 [(set_attr "type" "*,fp")])
6289 [(set (match_operand:SI 0 "register_operand" "")
6290 (ior:SI (match_operand:SI 1 "register_operand" "")
6291 (match_operand:SI 2 "" "")))
6292 (clobber (match_operand:SI 3 "register_operand" ""))]
6293 "GET_CODE (operands[2]) == CONST_INT
6294 && !SMALL_INT32 (operands[2])
6295 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6296 [(set (match_dup 3) (match_dup 4))
6297 (set (match_dup 0) (ior:SI (not:SI (match_dup 3)) (match_dup 1)))]
6300 operands[4] = GEN_INT (~INTVAL (operands[2]));
6303 (define_insn "*or_not_di_sp32"
6304 [(set (match_operand:DI 0 "register_operand" "=r,b")
6305 (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6306 (match_operand:DI 2 "register_operand" "r,b")))]
6310 fornot1\\t%1, %2, %0"
6311 [(set_attr "type" "*,fp")
6312 (set_attr "length" "2,*")
6313 (set_attr "fptype" "double")])
6316 [(set (match_operand:DI 0 "register_operand" "")
6317 (ior:DI (not:DI (match_operand:DI 1 "register_operand" ""))
6318 (match_operand:DI 2 "register_operand" "")))]
6321 && ((GET_CODE (operands[0]) == REG
6322 && REGNO (operands[0]) < 32)
6323 || (GET_CODE (operands[0]) == SUBREG
6324 && GET_CODE (SUBREG_REG (operands[0])) == REG
6325 && REGNO (SUBREG_REG (operands[0])) < 32))"
6326 [(set (match_dup 3) (ior:SI (not:SI (match_dup 4)) (match_dup 5)))
6327 (set (match_dup 6) (ior:SI (not:SI (match_dup 7)) (match_dup 8)))]
6328 "operands[3] = gen_highpart (SImode, operands[0]);
6329 operands[4] = gen_highpart (SImode, operands[1]);
6330 operands[5] = gen_highpart (SImode, operands[2]);
6331 operands[6] = gen_lowpart (SImode, operands[0]);
6332 operands[7] = gen_lowpart (SImode, operands[1]);
6333 operands[8] = gen_lowpart (SImode, operands[2]);")
6335 (define_insn "*or_not_di_sp64"
6336 [(set (match_operand:DI 0 "register_operand" "=r,b")
6337 (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6338 (match_operand:DI 2 "register_operand" "r,b")))]
6342 fornot1\\t%1, %2, %0"
6343 [(set_attr "type" "*,fp")
6344 (set_attr "fptype" "double")])
6346 (define_insn "*or_not_si"
6347 [(set (match_operand:SI 0 "register_operand" "=r,d")
6348 (ior:SI (not:SI (match_operand:SI 1 "register_operand" "r,d"))
6349 (match_operand:SI 2 "register_operand" "r,d")))]
6353 fornot1s\\t%1, %2, %0"
6354 [(set_attr "type" "*,fp")])
6356 (define_expand "xordi3"
6357 [(set (match_operand:DI 0 "register_operand" "")
6358 (xor:DI (match_operand:DI 1 "arith_double_operand" "")
6359 (match_operand:DI 2 "arith_double_operand" "")))]
6363 (define_insn "*xordi3_sp32"
6364 [(set (match_operand:DI 0 "register_operand" "=r,b")
6365 (xor:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6366 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6371 [(set_attr "type" "*,fp")
6372 (set_attr "length" "2,*")
6373 (set_attr "fptype" "double")])
6375 (define_insn "*xordi3_sp64"
6376 [(set (match_operand:DI 0 "register_operand" "=r,b")
6377 (xor:DI (match_operand:DI 1 "arith_double_operand" "%rJ,b")
6378 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6383 [(set_attr "type" "*,fp")
6384 (set_attr "fptype" "double")])
6386 (define_insn "*xordi3_sp64_dbl"
6387 [(set (match_operand:DI 0 "register_operand" "=r")
6388 (xor:DI (match_operand:DI 1 "register_operand" "r")
6389 (match_operand:DI 2 "const64_operand" "")))]
6391 && HOST_BITS_PER_WIDE_INT != 64)"
6394 (define_insn "xorsi3"
6395 [(set (match_operand:SI 0 "register_operand" "=r,d")
6396 (xor:SI (match_operand:SI 1 "arith_operand" "%rJ,d")
6397 (match_operand:SI 2 "arith_operand" "rI,d")))]
6402 [(set_attr "type" "*,fp")])
6405 [(set (match_operand:SI 0 "register_operand" "")
6406 (xor:SI (match_operand:SI 1 "register_operand" "")
6407 (match_operand:SI 2 "" "")))
6408 (clobber (match_operand:SI 3 "register_operand" ""))]
6409 "GET_CODE (operands[2]) == CONST_INT
6410 && !SMALL_INT32 (operands[2])
6411 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6412 [(set (match_dup 3) (match_dup 4))
6413 (set (match_dup 0) (not:SI (xor:SI (match_dup 3) (match_dup 1))))]
6416 operands[4] = GEN_INT (~INTVAL (operands[2]));
6420 [(set (match_operand:SI 0 "register_operand" "")
6421 (not:SI (xor:SI (match_operand:SI 1 "register_operand" "")
6422 (match_operand:SI 2 "" ""))))
6423 (clobber (match_operand:SI 3 "register_operand" ""))]
6424 "GET_CODE (operands[2]) == CONST_INT
6425 && !SMALL_INT32 (operands[2])
6426 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6427 [(set (match_dup 3) (match_dup 4))
6428 (set (match_dup 0) (xor:SI (match_dup 3) (match_dup 1)))]
6431 operands[4] = GEN_INT (~INTVAL (operands[2]));
6434 ;; xnor patterns. Note that (a ^ ~b) == (~a ^ b) == ~(a ^ b).
6435 ;; Combine now canonicalizes to the rightmost expression.
6436 (define_insn "*xor_not_di_sp32"
6437 [(set (match_operand:DI 0 "register_operand" "=r,b")
6438 (not:DI (xor:DI (match_operand:DI 1 "register_operand" "r,b")
6439 (match_operand:DI 2 "register_operand" "r,b"))))]
6444 [(set_attr "type" "*,fp")
6445 (set_attr "length" "2,*")
6446 (set_attr "fptype" "double")])
6449 [(set (match_operand:DI 0 "register_operand" "")
6450 (not:DI (xor:DI (match_operand:DI 1 "register_operand" "")
6451 (match_operand:DI 2 "register_operand" ""))))]
6454 && ((GET_CODE (operands[0]) == REG
6455 && REGNO (operands[0]) < 32)
6456 || (GET_CODE (operands[0]) == SUBREG
6457 && GET_CODE (SUBREG_REG (operands[0])) == REG
6458 && REGNO (SUBREG_REG (operands[0])) < 32))"
6459 [(set (match_dup 3) (not:SI (xor:SI (match_dup 4) (match_dup 5))))
6460 (set (match_dup 6) (not:SI (xor:SI (match_dup 7) (match_dup 8))))]
6461 "operands[3] = gen_highpart (SImode, operands[0]);
6462 operands[4] = gen_highpart (SImode, operands[1]);
6463 operands[5] = gen_highpart (SImode, operands[2]);
6464 operands[6] = gen_lowpart (SImode, operands[0]);
6465 operands[7] = gen_lowpart (SImode, operands[1]);
6466 operands[8] = gen_lowpart (SImode, operands[2]);")
6468 (define_insn "*xor_not_di_sp64"
6469 [(set (match_operand:DI 0 "register_operand" "=r,b")
6470 (not:DI (xor:DI (match_operand:DI 1 "reg_or_0_operand" "rJ,b")
6471 (match_operand:DI 2 "arith_double_operand" "rHI,b"))))]
6476 [(set_attr "type" "*,fp")
6477 (set_attr "fptype" "double")])
6479 (define_insn "*xor_not_si"
6480 [(set (match_operand:SI 0 "register_operand" "=r,d")
6481 (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "rJ,d")
6482 (match_operand:SI 2 "arith_operand" "rI,d"))))]
6486 fxnors\\t%1, %2, %0"
6487 [(set_attr "type" "*,fp")])
6489 ;; These correspond to the above in the case where we also (or only)
6490 ;; want to set the condition code.
6492 (define_insn "*cmp_cc_arith_op"
6495 (match_operator:SI 2 "cc_arithop"
6496 [(match_operand:SI 0 "arith_operand" "%r")
6497 (match_operand:SI 1 "arith_operand" "rI")])
6500 "%A2cc\\t%0, %1, %%g0"
6501 [(set_attr "type" "compare")])
6503 (define_insn "*cmp_ccx_arith_op"
6506 (match_operator:DI 2 "cc_arithop"
6507 [(match_operand:DI 0 "arith_double_operand" "%r")
6508 (match_operand:DI 1 "arith_double_operand" "rHI")])
6511 "%A2cc\\t%0, %1, %%g0"
6512 [(set_attr "type" "compare")])
6514 (define_insn "*cmp_cc_arith_op_set"
6517 (match_operator:SI 3 "cc_arithop"
6518 [(match_operand:SI 1 "arith_operand" "%r")
6519 (match_operand:SI 2 "arith_operand" "rI")])
6521 (set (match_operand:SI 0 "register_operand" "=r")
6522 (match_operator:SI 4 "cc_arithop" [(match_dup 1) (match_dup 2)]))]
6523 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
6524 "%A3cc\\t%1, %2, %0"
6525 [(set_attr "type" "compare")])
6527 (define_insn "*cmp_ccx_arith_op_set"
6530 (match_operator:DI 3 "cc_arithop"
6531 [(match_operand:DI 1 "arith_double_operand" "%r")
6532 (match_operand:DI 2 "arith_double_operand" "rHI")])
6534 (set (match_operand:DI 0 "register_operand" "=r")
6535 (match_operator:DI 4 "cc_arithop" [(match_dup 1) (match_dup 2)]))]
6536 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
6537 "%A3cc\\t%1, %2, %0"
6538 [(set_attr "type" "compare")])
6540 (define_insn "*cmp_cc_xor_not"
6543 (not:SI (xor:SI (match_operand:SI 0 "reg_or_0_operand" "%rJ")
6544 (match_operand:SI 1 "arith_operand" "rI")))
6547 "xnorcc\\t%r0, %1, %%g0"
6548 [(set_attr "type" "compare")])
6550 (define_insn "*cmp_ccx_xor_not"
6553 (not:DI (xor:DI (match_operand:DI 0 "reg_or_0_operand" "%rJ")
6554 (match_operand:DI 1 "arith_double_operand" "rHI")))
6557 "xnorcc\\t%r0, %1, %%g0"
6558 [(set_attr "type" "compare")])
6560 (define_insn "*cmp_cc_xor_not_set"
6563 (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
6564 (match_operand:SI 2 "arith_operand" "rI")))
6566 (set (match_operand:SI 0 "register_operand" "=r")
6567 (not:SI (xor:SI (match_dup 1) (match_dup 2))))]
6569 "xnorcc\\t%r1, %2, %0"
6570 [(set_attr "type" "compare")])
6572 (define_insn "*cmp_ccx_xor_not_set"
6575 (not:DI (xor:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ")
6576 (match_operand:DI 2 "arith_double_operand" "rHI")))
6578 (set (match_operand:DI 0 "register_operand" "=r")
6579 (not:DI (xor:DI (match_dup 1) (match_dup 2))))]
6581 "xnorcc\\t%r1, %2, %0"
6582 [(set_attr "type" "compare")])
6584 (define_insn "*cmp_cc_arith_op_not"
6587 (match_operator:SI 2 "cc_arithopn"
6588 [(not:SI (match_operand:SI 0 "arith_operand" "rI"))
6589 (match_operand:SI 1 "reg_or_0_operand" "rJ")])
6592 "%B2cc\\t%r1, %0, %%g0"
6593 [(set_attr "type" "compare")])
6595 (define_insn "*cmp_ccx_arith_op_not"
6598 (match_operator:DI 2 "cc_arithopn"
6599 [(not:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
6600 (match_operand:DI 1 "reg_or_0_operand" "rJ")])
6603 "%B2cc\\t%r1, %0, %%g0"
6604 [(set_attr "type" "compare")])
6606 (define_insn "*cmp_cc_arith_op_not_set"
6609 (match_operator:SI 3 "cc_arithopn"
6610 [(not:SI (match_operand:SI 1 "arith_operand" "rI"))
6611 (match_operand:SI 2 "reg_or_0_operand" "rJ")])
6613 (set (match_operand:SI 0 "register_operand" "=r")
6614 (match_operator:SI 4 "cc_arithopn"
6615 [(not:SI (match_dup 1)) (match_dup 2)]))]
6616 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
6617 "%B3cc\\t%r2, %1, %0"
6618 [(set_attr "type" "compare")])
6620 (define_insn "*cmp_ccx_arith_op_not_set"
6623 (match_operator:DI 3 "cc_arithopn"
6624 [(not:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
6625 (match_operand:DI 2 "reg_or_0_operand" "rJ")])
6627 (set (match_operand:DI 0 "register_operand" "=r")
6628 (match_operator:DI 4 "cc_arithopn"
6629 [(not:DI (match_dup 1)) (match_dup 2)]))]
6630 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
6631 "%B3cc\\t%r2, %1, %0"
6632 [(set_attr "type" "compare")])
6634 ;; We cannot use the "neg" pseudo insn because the Sun assembler
6635 ;; does not know how to make it work for constants.
6637 (define_expand "negdi2"
6638 [(set (match_operand:DI 0 "register_operand" "=r")
6639 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
6643 if (! TARGET_ARCH64)
6645 emit_insn (gen_rtx_PARALLEL
6648 gen_rtx_SET (VOIDmode, operand0,
6649 gen_rtx_NEG (DImode, operand1)),
6650 gen_rtx_CLOBBER (VOIDmode,
6651 gen_rtx_REG (CCmode,
6657 (define_insn "*negdi2_sp32"
6658 [(set (match_operand:DI 0 "register_operand" "=r")
6659 (neg:DI (match_operand:DI 1 "register_operand" "r")))
6660 (clobber (reg:CC 100))]
6663 [(set_attr "length" "2")])
6666 [(set (match_operand:DI 0 "register_operand" "")
6667 (neg:DI (match_operand:DI 1 "register_operand" "")))
6668 (clobber (reg:CC 100))]
6670 && reload_completed"
6671 [(parallel [(set (reg:CC_NOOV 100)
6672 (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 5))
6674 (set (match_dup 4) (minus:SI (const_int 0) (match_dup 5)))])
6675 (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
6676 (ltu:SI (reg:CC 100) (const_int 0))))]
6677 "operands[2] = gen_highpart (SImode, operands[0]);
6678 operands[3] = gen_highpart (SImode, operands[1]);
6679 operands[4] = gen_lowpart (SImode, operands[0]);
6680 operands[5] = gen_lowpart (SImode, operands[1]);")
6682 (define_insn "*negdi2_sp64"
6683 [(set (match_operand:DI 0 "register_operand" "=r")
6684 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
6686 "sub\\t%%g0, %1, %0")
6688 (define_insn "negsi2"
6689 [(set (match_operand:SI 0 "register_operand" "=r")
6690 (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
6692 "sub\\t%%g0, %1, %0")
6694 (define_insn "*cmp_cc_neg"
6695 [(set (reg:CC_NOOV 100)
6696 (compare:CC_NOOV (neg:SI (match_operand:SI 0 "arith_operand" "rI"))
6699 "subcc\\t%%g0, %0, %%g0"
6700 [(set_attr "type" "compare")])
6702 (define_insn "*cmp_ccx_neg"
6703 [(set (reg:CCX_NOOV 100)
6704 (compare:CCX_NOOV (neg:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
6707 "subcc\\t%%g0, %0, %%g0"
6708 [(set_attr "type" "compare")])
6710 (define_insn "*cmp_cc_set_neg"
6711 [(set (reg:CC_NOOV 100)
6712 (compare:CC_NOOV (neg:SI (match_operand:SI 1 "arith_operand" "rI"))
6714 (set (match_operand:SI 0 "register_operand" "=r")
6715 (neg:SI (match_dup 1)))]
6717 "subcc\\t%%g0, %1, %0"
6718 [(set_attr "type" "compare")])
6720 (define_insn "*cmp_ccx_set_neg"
6721 [(set (reg:CCX_NOOV 100)
6722 (compare:CCX_NOOV (neg:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
6724 (set (match_operand:DI 0 "register_operand" "=r")
6725 (neg:DI (match_dup 1)))]
6727 "subcc\\t%%g0, %1, %0"
6728 [(set_attr "type" "compare")])
6730 ;; We cannot use the "not" pseudo insn because the Sun assembler
6731 ;; does not know how to make it work for constants.
6732 (define_expand "one_cmpldi2"
6733 [(set (match_operand:DI 0 "register_operand" "")
6734 (not:DI (match_operand:DI 1 "register_operand" "")))]
6738 (define_insn "*one_cmpldi2_sp32"
6739 [(set (match_operand:DI 0 "register_operand" "=r,b")
6740 (not:DI (match_operand:DI 1 "register_operand" "r,b")))]
6745 [(set_attr "type" "*,fp")
6746 (set_attr "length" "2,*")
6747 (set_attr "fptype" "double")])
6750 [(set (match_operand:DI 0 "register_operand" "")
6751 (not:DI (match_operand:DI 1 "register_operand" "")))]
6754 && ((GET_CODE (operands[0]) == REG
6755 && REGNO (operands[0]) < 32)
6756 || (GET_CODE (operands[0]) == SUBREG
6757 && GET_CODE (SUBREG_REG (operands[0])) == REG
6758 && REGNO (SUBREG_REG (operands[0])) < 32))"
6759 [(set (match_dup 2) (not:SI (xor:SI (match_dup 3) (const_int 0))))
6760 (set (match_dup 4) (not:SI (xor:SI (match_dup 5) (const_int 0))))]
6761 "operands[2] = gen_highpart (SImode, operands[0]);
6762 operands[3] = gen_highpart (SImode, operands[1]);
6763 operands[4] = gen_lowpart (SImode, operands[0]);
6764 operands[5] = gen_lowpart (SImode, operands[1]);")
6766 (define_insn "*one_cmpldi2_sp64"
6767 [(set (match_operand:DI 0 "register_operand" "=r,b")
6768 (not:DI (match_operand:DI 1 "arith_double_operand" "rHI,b")))]
6773 [(set_attr "type" "*,fp")
6774 (set_attr "fptype" "double")])
6776 (define_insn "one_cmplsi2"
6777 [(set (match_operand:SI 0 "register_operand" "=r,d")
6778 (not:SI (match_operand:SI 1 "arith_operand" "rI,d")))]
6783 [(set_attr "type" "*,fp")])
6785 (define_insn "*cmp_cc_not"
6787 (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI"))
6790 "xnorcc\\t%%g0, %0, %%g0"
6791 [(set_attr "type" "compare")])
6793 (define_insn "*cmp_ccx_not"
6795 (compare:CCX (not:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
6798 "xnorcc\\t%%g0, %0, %%g0"
6799 [(set_attr "type" "compare")])
6801 (define_insn "*cmp_cc_set_not"
6803 (compare:CC (not:SI (match_operand:SI 1 "arith_operand" "rI"))
6805 (set (match_operand:SI 0 "register_operand" "=r")
6806 (not:SI (match_dup 1)))]
6808 "xnorcc\\t%%g0, %1, %0"
6809 [(set_attr "type" "compare")])
6811 (define_insn "*cmp_ccx_set_not"
6813 (compare:CCX (not:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
6815 (set (match_operand:DI 0 "register_operand" "=r")
6816 (not:DI (match_dup 1)))]
6818 "xnorcc\\t%%g0, %1, %0"
6819 [(set_attr "type" "compare")])
6821 (define_insn "*cmp_cc_set"
6822 [(set (match_operand:SI 0 "register_operand" "=r")
6823 (match_operand:SI 1 "register_operand" "r"))
6825 (compare:CC (match_dup 1)
6829 [(set_attr "type" "compare")])
6831 (define_insn "*cmp_ccx_set64"
6832 [(set (match_operand:DI 0 "register_operand" "=r")
6833 (match_operand:DI 1 "register_operand" "r"))
6835 (compare:CCX (match_dup 1)
6839 [(set_attr "type" "compare")])
6841 ;; Floating point arithmetic instructions.
6843 (define_expand "addtf3"
6844 [(set (match_operand:TF 0 "nonimmediate_operand" "")
6845 (plus:TF (match_operand:TF 1 "general_operand" "")
6846 (match_operand:TF 2 "general_operand" "")))]
6847 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6848 "emit_tfmode_binop (PLUS, operands); DONE;")
6850 (define_insn "*addtf3_hq"
6851 [(set (match_operand:TF 0 "register_operand" "=e")
6852 (plus:TF (match_operand:TF 1 "register_operand" "e")
6853 (match_operand:TF 2 "register_operand" "e")))]
6854 "TARGET_FPU && TARGET_HARD_QUAD"
6855 "faddq\\t%1, %2, %0"
6856 [(set_attr "type" "fp")])
6858 (define_insn "adddf3"
6859 [(set (match_operand:DF 0 "register_operand" "=e")
6860 (plus:DF (match_operand:DF 1 "register_operand" "e")
6861 (match_operand:DF 2 "register_operand" "e")))]
6863 "faddd\\t%1, %2, %0"
6864 [(set_attr "type" "fp")
6865 (set_attr "fptype" "double")])
6867 (define_insn "addsf3"
6868 [(set (match_operand:SF 0 "register_operand" "=f")
6869 (plus:SF (match_operand:SF 1 "register_operand" "f")
6870 (match_operand:SF 2 "register_operand" "f")))]
6872 "fadds\\t%1, %2, %0"
6873 [(set_attr "type" "fp")])
6875 (define_expand "subtf3"
6876 [(set (match_operand:TF 0 "nonimmediate_operand" "")
6877 (minus:TF (match_operand:TF 1 "general_operand" "")
6878 (match_operand:TF 2 "general_operand" "")))]
6879 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6880 "emit_tfmode_binop (MINUS, operands); DONE;")
6882 (define_insn "*subtf3_hq"
6883 [(set (match_operand:TF 0 "register_operand" "=e")
6884 (minus:TF (match_operand:TF 1 "register_operand" "e")
6885 (match_operand:TF 2 "register_operand" "e")))]
6886 "TARGET_FPU && TARGET_HARD_QUAD"
6887 "fsubq\\t%1, %2, %0"
6888 [(set_attr "type" "fp")])
6890 (define_insn "subdf3"
6891 [(set (match_operand:DF 0 "register_operand" "=e")
6892 (minus:DF (match_operand:DF 1 "register_operand" "e")
6893 (match_operand:DF 2 "register_operand" "e")))]
6895 "fsubd\\t%1, %2, %0"
6896 [(set_attr "type" "fp")
6897 (set_attr "fptype" "double")])
6899 (define_insn "subsf3"
6900 [(set (match_operand:SF 0 "register_operand" "=f")
6901 (minus:SF (match_operand:SF 1 "register_operand" "f")
6902 (match_operand:SF 2 "register_operand" "f")))]
6904 "fsubs\\t%1, %2, %0"
6905 [(set_attr "type" "fp")])
6907 (define_expand "multf3"
6908 [(set (match_operand:TF 0 "nonimmediate_operand" "")
6909 (mult:TF (match_operand:TF 1 "general_operand" "")
6910 (match_operand:TF 2 "general_operand" "")))]
6911 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6912 "emit_tfmode_binop (MULT, operands); DONE;")
6914 (define_insn "*multf3_hq"
6915 [(set (match_operand:TF 0 "register_operand" "=e")
6916 (mult:TF (match_operand:TF 1 "register_operand" "e")
6917 (match_operand:TF 2 "register_operand" "e")))]
6918 "TARGET_FPU && TARGET_HARD_QUAD"
6919 "fmulq\\t%1, %2, %0"
6920 [(set_attr "type" "fpmul")])
6922 (define_insn "muldf3"
6923 [(set (match_operand:DF 0 "register_operand" "=e")
6924 (mult:DF (match_operand:DF 1 "register_operand" "e")
6925 (match_operand:DF 2 "register_operand" "e")))]
6927 "fmuld\\t%1, %2, %0"
6928 [(set_attr "type" "fpmul")
6929 (set_attr "fptype" "double")])
6931 (define_insn "mulsf3"
6932 [(set (match_operand:SF 0 "register_operand" "=f")
6933 (mult:SF (match_operand:SF 1 "register_operand" "f")
6934 (match_operand:SF 2 "register_operand" "f")))]
6936 "fmuls\\t%1, %2, %0"
6937 [(set_attr "type" "fpmul")])
6939 (define_insn "*muldf3_extend"
6940 [(set (match_operand:DF 0 "register_operand" "=e")
6941 (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "f"))
6942 (float_extend:DF (match_operand:SF 2 "register_operand" "f"))))]
6943 "(TARGET_V8 || TARGET_V9) && TARGET_FPU"
6944 "fsmuld\\t%1, %2, %0"
6945 [(set_attr "type" "fpmul")
6946 (set_attr "fptype" "double")])
6948 (define_insn "*multf3_extend"
6949 [(set (match_operand:TF 0 "register_operand" "=e")
6950 (mult:TF (float_extend:TF (match_operand:DF 1 "register_operand" "e"))
6951 (float_extend:TF (match_operand:DF 2 "register_operand" "e"))))]
6952 "(TARGET_V8 || TARGET_V9) && TARGET_FPU && TARGET_HARD_QUAD"
6953 "fdmulq\\t%1, %2, %0"
6954 [(set_attr "type" "fpmul")])
6956 (define_expand "divtf3"
6957 [(set (match_operand:TF 0 "nonimmediate_operand" "")
6958 (div:TF (match_operand:TF 1 "general_operand" "")
6959 (match_operand:TF 2 "general_operand" "")))]
6960 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6961 "emit_tfmode_binop (DIV, operands); DONE;")
6963 ;; don't have timing for quad-prec. divide.
6964 (define_insn "*divtf3_hq"
6965 [(set (match_operand:TF 0 "register_operand" "=e")
6966 (div:TF (match_operand:TF 1 "register_operand" "e")
6967 (match_operand:TF 2 "register_operand" "e")))]
6968 "TARGET_FPU && TARGET_HARD_QUAD"
6969 "fdivq\\t%1, %2, %0"
6970 [(set_attr "type" "fpdivd")])
6972 (define_insn "divdf3"
6973 [(set (match_operand:DF 0 "register_operand" "=e")
6974 (div:DF (match_operand:DF 1 "register_operand" "e")
6975 (match_operand:DF 2 "register_operand" "e")))]
6977 "fdivd\\t%1, %2, %0"
6978 [(set_attr "type" "fpdivd")
6979 (set_attr "fptype" "double")])
6981 (define_insn "divsf3"
6982 [(set (match_operand:SF 0 "register_operand" "=f")
6983 (div:SF (match_operand:SF 1 "register_operand" "f")
6984 (match_operand:SF 2 "register_operand" "f")))]
6986 "fdivs\\t%1, %2, %0"
6987 [(set_attr "type" "fpdivs")])
6989 (define_expand "negtf2"
6990 [(set (match_operand:TF 0 "register_operand" "=e,e")
6991 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
6995 (define_insn "*negtf2_notv9"
6996 [(set (match_operand:TF 0 "register_operand" "=e,e")
6997 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
6998 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
7004 [(set_attr "type" "fpmove,*")
7005 (set_attr "length" "*,2")])
7008 [(set (match_operand:TF 0 "register_operand" "")
7009 (neg:TF (match_operand:TF 1 "register_operand" "")))]
7013 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7014 [(set (match_dup 2) (neg:SF (match_dup 3)))
7015 (set (match_dup 4) (match_dup 5))
7016 (set (match_dup 6) (match_dup 7))]
7017 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
7018 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
7019 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
7020 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
7021 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
7022 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);")
7024 (define_insn "*negtf2_v9"
7025 [(set (match_operand:TF 0 "register_operand" "=e,e")
7026 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
7027 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
7028 "TARGET_FPU && TARGET_V9"
7032 [(set_attr "type" "fpmove,*")
7033 (set_attr "length" "*,2")
7034 (set_attr "fptype" "double")])
7037 [(set (match_operand:TF 0 "register_operand" "")
7038 (neg:TF (match_operand:TF 1 "register_operand" "")))]
7042 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7043 [(set (match_dup 2) (neg:DF (match_dup 3)))
7044 (set (match_dup 4) (match_dup 5))]
7045 "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
7046 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
7047 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
7048 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);")
7050 (define_expand "negdf2"
7051 [(set (match_operand:DF 0 "register_operand" "")
7052 (neg:DF (match_operand:DF 1 "register_operand" "")))]
7056 (define_insn "*negdf2_notv9"
7057 [(set (match_operand:DF 0 "register_operand" "=e,e")
7058 (neg:DF (match_operand:DF 1 "register_operand" "0,e")))]
7059 "TARGET_FPU && ! TARGET_V9"
7063 [(set_attr "type" "fpmove,*")
7064 (set_attr "length" "*,2")])
7067 [(set (match_operand:DF 0 "register_operand" "")
7068 (neg:DF (match_operand:DF 1 "register_operand" "")))]
7072 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7073 [(set (match_dup 2) (neg:SF (match_dup 3)))
7074 (set (match_dup 4) (match_dup 5))]
7075 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
7076 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
7077 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
7078 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);")
7080 (define_insn "*negdf2_v9"
7081 [(set (match_operand:DF 0 "register_operand" "=e")
7082 (neg:DF (match_operand:DF 1 "register_operand" "e")))]
7083 "TARGET_FPU && TARGET_V9"
7085 [(set_attr "type" "fpmove")
7086 (set_attr "fptype" "double")])
7088 (define_insn "negsf2"
7089 [(set (match_operand:SF 0 "register_operand" "=f")
7090 (neg:SF (match_operand:SF 1 "register_operand" "f")))]
7093 [(set_attr "type" "fpmove")])
7095 (define_expand "abstf2"
7096 [(set (match_operand:TF 0 "register_operand" "")
7097 (abs:TF (match_operand:TF 1 "register_operand" "")))]
7101 (define_insn "*abstf2_notv9"
7102 [(set (match_operand:TF 0 "register_operand" "=e,e")
7103 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
7104 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
7105 "TARGET_FPU && ! TARGET_V9"
7109 [(set_attr "type" "fpmove,*")
7110 (set_attr "length" "*,2")])
7113 [(set (match_operand:TF 0 "register_operand" "")
7114 (abs:TF (match_operand:TF 1 "register_operand" "")))]
7118 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7119 [(set (match_dup 2) (abs:SF (match_dup 3)))
7120 (set (match_dup 4) (match_dup 5))
7121 (set (match_dup 6) (match_dup 7))]
7122 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
7123 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
7124 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
7125 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
7126 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
7127 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);")
7129 (define_insn "*abstf2_hq_v9"
7130 [(set (match_operand:TF 0 "register_operand" "=e,e")
7131 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
7132 "TARGET_FPU && TARGET_V9 && TARGET_HARD_QUAD"
7136 [(set_attr "type" "fpmove")
7137 (set_attr "fptype" "double,*")])
7139 (define_insn "*abstf2_v9"
7140 [(set (match_operand:TF 0 "register_operand" "=e,e")
7141 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
7142 "TARGET_FPU && TARGET_V9 && !TARGET_HARD_QUAD"
7146 [(set_attr "type" "fpmove,*")
7147 (set_attr "length" "*,2")
7148 (set_attr "fptype" "double,*")])
7151 [(set (match_operand:TF 0 "register_operand" "")
7152 (abs:TF (match_operand:TF 1 "register_operand" "")))]
7156 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7157 [(set (match_dup 2) (abs:DF (match_dup 3)))
7158 (set (match_dup 4) (match_dup 5))]
7159 "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
7160 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
7161 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
7162 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);")
7164 (define_expand "absdf2"
7165 [(set (match_operand:DF 0 "register_operand" "")
7166 (abs:DF (match_operand:DF 1 "register_operand" "")))]
7170 (define_insn "*absdf2_notv9"
7171 [(set (match_operand:DF 0 "register_operand" "=e,e")
7172 (abs:DF (match_operand:DF 1 "register_operand" "0,e")))]
7173 "TARGET_FPU && ! TARGET_V9"
7177 [(set_attr "type" "fpmove,*")
7178 (set_attr "length" "*,2")])
7181 [(set (match_operand:DF 0 "register_operand" "")
7182 (abs:DF (match_operand:DF 1 "register_operand" "")))]
7186 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7187 [(set (match_dup 2) (abs:SF (match_dup 3)))
7188 (set (match_dup 4) (match_dup 5))]
7189 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
7190 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
7191 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
7192 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);")
7194 (define_insn "*absdf2_v9"
7195 [(set (match_operand:DF 0 "register_operand" "=e")
7196 (abs:DF (match_operand:DF 1 "register_operand" "e")))]
7197 "TARGET_FPU && TARGET_V9"
7199 [(set_attr "type" "fpmove")
7200 (set_attr "fptype" "double")])
7202 (define_insn "abssf2"
7203 [(set (match_operand:SF 0 "register_operand" "=f")
7204 (abs:SF (match_operand:SF 1 "register_operand" "f")))]
7207 [(set_attr "type" "fpmove")])
7209 (define_expand "sqrttf2"
7210 [(set (match_operand:TF 0 "nonimmediate_operand" "")
7211 (sqrt:TF (match_operand:TF 1 "general_operand" "")))]
7212 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
7213 "emit_tfmode_unop (SQRT, operands); DONE;")
7215 (define_insn "*sqrttf2_hq"
7216 [(set (match_operand:TF 0 "register_operand" "=e")
7217 (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
7218 "TARGET_FPU && TARGET_HARD_QUAD"
7220 [(set_attr "type" "fpsqrtd")])
7222 (define_insn "sqrtdf2"
7223 [(set (match_operand:DF 0 "register_operand" "=e")
7224 (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
7227 [(set_attr "type" "fpsqrtd")
7228 (set_attr "fptype" "double")])
7230 (define_insn "sqrtsf2"
7231 [(set (match_operand:SF 0 "register_operand" "=f")
7232 (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
7235 [(set_attr "type" "fpsqrts")])
7237 ;;- arithmetic shift instructions
7239 (define_insn "ashlsi3"
7240 [(set (match_operand:SI 0 "register_operand" "=r")
7241 (ashift:SI (match_operand:SI 1 "register_operand" "r")
7242 (match_operand:SI 2 "arith_operand" "rI")))]
7246 if (operands[2] == const1_rtx)
7247 return \"add\\t%1, %1, %0\";
7248 return \"sll\\t%1, %2, %0\";
7251 (if_then_else (match_operand 2 "const1_operand" "")
7252 (const_string "ialu") (const_string "shift")))])
7254 (define_expand "ashldi3"
7255 [(set (match_operand:DI 0 "register_operand" "=r")
7256 (ashift:DI (match_operand:DI 1 "register_operand" "r")
7257 (match_operand:SI 2 "arith_operand" "rI")))]
7258 "TARGET_ARCH64 || TARGET_V8PLUS"
7261 if (! TARGET_ARCH64)
7263 if (GET_CODE (operands[2]) == CONST_INT)
7265 emit_insn (gen_ashldi3_v8plus (operands[0], operands[1], operands[2]));
7270 (define_insn "*ashldi3_sp64"
7271 [(set (match_operand:DI 0 "register_operand" "=r")
7272 (ashift:DI (match_operand:DI 1 "register_operand" "r")
7273 (match_operand:SI 2 "arith_operand" "rI")))]
7277 if (operands[2] == const1_rtx)
7278 return \"add\\t%1, %1, %0\";
7279 return \"sllx\\t%1, %2, %0\";
7282 (if_then_else (match_operand 2 "const1_operand" "")
7283 (const_string "ialu") (const_string "shift")))])
7286 (define_insn "ashldi3_v8plus"
7287 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
7288 (ashift:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
7289 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
7290 (clobber (match_scratch:SI 3 "=X,X,&h"))]
7292 "*return sparc_v8plus_shift (operands, insn, \"sllx\");"
7293 [(set_attr "type" "multi")
7294 (set_attr "length" "5,5,6")])
7296 ;; Optimize (1LL<<x)-1
7297 ;; XXX this also needs to be fixed to handle equal subregs
7298 ;; XXX first before we could re-enable it.
7300 ; [(set (match_operand:DI 0 "register_operand" "=h")
7301 ; (plus:DI (ashift:DI (const_int 1)
7302 ; (match_operand:SI 1 "arith_operand" "rI"))
7304 ; "0 && TARGET_V8PLUS"
7307 ; if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == REGNO (operands[0]))
7308 ; return \"mov\\t1, %L0\;sllx\\t%L0, %1, %L0\;sub\\t%L0, 1, %L0\;srlx\\t%L0, 32, %H0\";
7309 ; return \"mov\\t1, %H0\;sllx\\t%H0, %1, %L0\;sub\\t%L0, 1, %L0\;srlx\\t%L0, 32, %H0\";
7311 ; [(set_attr "type" "multi")
7312 ; (set_attr "length" "4")])
7314 (define_insn "*cmp_cc_ashift_1"
7315 [(set (reg:CC_NOOV 100)
7316 (compare:CC_NOOV (ashift:SI (match_operand:SI 0 "register_operand" "r")
7320 "addcc\\t%0, %0, %%g0"
7321 [(set_attr "type" "compare")])
7323 (define_insn "*cmp_cc_set_ashift_1"
7324 [(set (reg:CC_NOOV 100)
7325 (compare:CC_NOOV (ashift:SI (match_operand:SI 1 "register_operand" "r")
7328 (set (match_operand:SI 0 "register_operand" "=r")
7329 (ashift:SI (match_dup 1) (const_int 1)))]
7331 "addcc\\t%1, %1, %0"
7332 [(set_attr "type" "compare")])
7334 (define_insn "ashrsi3"
7335 [(set (match_operand:SI 0 "register_operand" "=r")
7336 (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
7337 (match_operand:SI 2 "arith_operand" "rI")))]
7341 return \"sra\\t%1, %2, %0\";
7343 [(set_attr "type" "shift")])
7345 (define_insn "*ashrsi3_extend"
7346 [(set (match_operand:DI 0 "register_operand" "=r")
7347 (sign_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
7348 (match_operand:SI 2 "arith_operand" "r"))))]
7351 [(set_attr "type" "shift")])
7353 ;; This handles the case as above, but with constant shift instead of
7354 ;; register. Combiner "simplifies" it for us a little bit though.
7355 (define_insn "*ashrsi3_extend2"
7356 [(set (match_operand:DI 0 "register_operand" "=r")
7357 (ashiftrt:DI (ashift:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
7359 (match_operand:SI 2 "small_int_or_double" "n")))]
7361 && ((GET_CODE (operands[2]) == CONST_INT
7362 && INTVAL (operands[2]) >= 32 && INTVAL (operands[2]) < 64)
7363 || (GET_CODE (operands[2]) == CONST_DOUBLE
7364 && !CONST_DOUBLE_HIGH (operands[2])
7365 && CONST_DOUBLE_LOW (operands[2]) >= 32
7366 && CONST_DOUBLE_LOW (operands[2]) < 64))"
7369 operands[2] = GEN_INT (INTVAL (operands[2]) - 32);
7371 return \"sra\\t%1, %2, %0\";
7373 [(set_attr "type" "shift")])
7375 (define_expand "ashrdi3"
7376 [(set (match_operand:DI 0 "register_operand" "=r")
7377 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
7378 (match_operand:SI 2 "arith_operand" "rI")))]
7379 "TARGET_ARCH64 || TARGET_V8PLUS"
7382 if (! TARGET_ARCH64)
7384 if (GET_CODE (operands[2]) == CONST_INT)
7385 FAIL; /* prefer generic code in this case */
7386 emit_insn (gen_ashrdi3_v8plus (operands[0], operands[1], operands[2]));
7392 [(set (match_operand:DI 0 "register_operand" "=r")
7393 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
7394 (match_operand:SI 2 "arith_operand" "rI")))]
7398 return \"srax\\t%1, %2, %0\";
7400 [(set_attr "type" "shift")])
7403 (define_insn "ashrdi3_v8plus"
7404 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
7405 (ashiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
7406 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
7407 (clobber (match_scratch:SI 3 "=X,X,&h"))]
7409 "*return sparc_v8plus_shift (operands, insn, \"srax\");"
7410 [(set_attr "type" "multi")
7411 (set_attr "length" "5,5,6")])
7413 (define_insn "lshrsi3"
7414 [(set (match_operand:SI 0 "register_operand" "=r")
7415 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
7416 (match_operand:SI 2 "arith_operand" "rI")))]
7420 return \"srl\\t%1, %2, %0\";
7422 [(set_attr "type" "shift")])
7424 ;; This handles the case where
7425 ;; (zero_extend:DI (lshiftrt:SI (match_operand:SI) (match_operand:SI))),
7426 ;; but combiner "simplifies" it for us.
7427 (define_insn "*lshrsi3_extend"
7428 [(set (match_operand:DI 0 "register_operand" "=r")
7429 (and:DI (subreg:DI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
7430 (match_operand:SI 2 "arith_operand" "r")) 0)
7431 (match_operand 3 "" "")))]
7433 && ((GET_CODE (operands[3]) == CONST_DOUBLE
7434 && CONST_DOUBLE_HIGH (operands[3]) == 0
7435 && CONST_DOUBLE_LOW (operands[3]) == 0xffffffff)
7436 || (HOST_BITS_PER_WIDE_INT >= 64
7437 && GET_CODE (operands[3]) == CONST_INT
7438 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) == 0xffffffff))"
7440 [(set_attr "type" "shift")])
7442 ;; This handles the case where
7443 ;; (lshiftrt:DI (zero_extend:DI (match_operand:SI)) (const_int >=0 < 32))
7444 ;; but combiner "simplifies" it for us.
7445 (define_insn "*lshrsi3_extend2"
7446 [(set (match_operand:DI 0 "register_operand" "=r")
7447 (zero_extract:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
7448 (match_operand 2 "small_int_or_double" "n")
7451 && ((GET_CODE (operands[2]) == CONST_INT
7452 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
7453 || (GET_CODE (operands[2]) == CONST_DOUBLE
7454 && CONST_DOUBLE_HIGH (operands[2]) == 0
7455 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
7458 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
7460 return \"srl\\t%1, %2, %0\";
7462 [(set_attr "type" "shift")])
7464 (define_expand "lshrdi3"
7465 [(set (match_operand:DI 0 "register_operand" "=r")
7466 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
7467 (match_operand:SI 2 "arith_operand" "rI")))]
7468 "TARGET_ARCH64 || TARGET_V8PLUS"
7471 if (! TARGET_ARCH64)
7473 if (GET_CODE (operands[2]) == CONST_INT)
7475 emit_insn (gen_lshrdi3_v8plus (operands[0], operands[1], operands[2]));
7481 [(set (match_operand:DI 0 "register_operand" "=r")
7482 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
7483 (match_operand:SI 2 "arith_operand" "rI")))]
7487 return \"srlx\\t%1, %2, %0\";
7489 [(set_attr "type" "shift")])
7492 (define_insn "lshrdi3_v8plus"
7493 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
7494 (lshiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
7495 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
7496 (clobber (match_scratch:SI 3 "=X,X,&h"))]
7498 "*return sparc_v8plus_shift (operands, insn, \"srlx\");"
7499 [(set_attr "type" "multi")
7500 (set_attr "length" "5,5,6")])
7503 [(set (match_operand:SI 0 "register_operand" "=r")
7504 (ashiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
7506 (match_operand:SI 2 "small_int_or_double" "n")))]
7508 && ((GET_CODE (operands[2]) == CONST_INT
7509 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
7510 || (GET_CODE (operands[2]) == CONST_DOUBLE
7511 && !CONST_DOUBLE_HIGH (operands[2])
7512 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
7515 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
7517 return \"srax\\t%1, %2, %0\";
7519 [(set_attr "type" "shift")])
7522 [(set (match_operand:SI 0 "register_operand" "=r")
7523 (lshiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
7525 (match_operand:SI 2 "small_int_or_double" "n")))]
7527 && ((GET_CODE (operands[2]) == CONST_INT
7528 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
7529 || (GET_CODE (operands[2]) == CONST_DOUBLE
7530 && !CONST_DOUBLE_HIGH (operands[2])
7531 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
7534 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
7536 return \"srlx\\t%1, %2, %0\";
7538 [(set_attr "type" "shift")])
7541 [(set (match_operand:SI 0 "register_operand" "=r")
7542 (ashiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
7543 (match_operand:SI 2 "small_int_or_double" "n")) 4)
7544 (match_operand:SI 3 "small_int_or_double" "n")))]
7546 && GET_CODE (operands[2]) == CONST_INT && GET_CODE (operands[3]) == CONST_INT
7547 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
7548 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
7549 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
7552 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
7554 return \"srax\\t%1, %2, %0\";
7556 [(set_attr "type" "shift")])
7559 [(set (match_operand:SI 0 "register_operand" "=r")
7560 (lshiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
7561 (match_operand:SI 2 "small_int_or_double" "n")) 4)
7562 (match_operand:SI 3 "small_int_or_double" "n")))]
7564 && GET_CODE (operands[2]) == CONST_INT && GET_CODE (operands[3]) == CONST_INT
7565 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
7566 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
7567 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
7570 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
7572 return \"srlx\\t%1, %2, %0\";
7574 [(set_attr "type" "shift")])
7576 ;; Unconditional and other jump instructions
7577 ;; On the Sparc, by setting the annul bit on an unconditional branch, the
7578 ;; following insn is never executed. This saves us a nop. Dbx does not
7579 ;; handle such branches though, so we only use them when optimizing.
7581 [(set (pc) (label_ref (match_operand 0 "" "")))]
7585 /* TurboSparc is reported to have problems with
7588 i.e. an empty loop with the annul bit set. The workaround is to use
7592 if (! TARGET_V9 && flag_delayed_branch
7593 && (INSN_ADDRESSES (INSN_UID (operands[0]))
7594 == INSN_ADDRESSES (INSN_UID (insn))))
7595 return \"b\\t%l0%#\";
7597 return TARGET_V9 ? \"ba,pt%*\\t%%xcc, %l0%(\" : \"b%*\\t%l0%(\";
7599 [(set_attr "type" "uncond_branch")])
7601 (define_expand "tablejump"
7602 [(parallel [(set (pc) (match_operand 0 "register_operand" "r"))
7603 (use (label_ref (match_operand 1 "" "")))])]
7607 if (GET_MODE (operands[0]) != CASE_VECTOR_MODE)
7610 /* In pic mode, our address differences are against the base of the
7611 table. Add that base value back in; CSE ought to be able to combine
7612 the two address loads. */
7616 tmp = gen_rtx_LABEL_REF (Pmode, operands[1]);
7618 if (CASE_VECTOR_MODE != Pmode)
7619 tmp2 = gen_rtx_SIGN_EXTEND (Pmode, tmp2);
7620 tmp = gen_rtx_PLUS (Pmode, tmp2, tmp);
7621 operands[0] = memory_address (Pmode, tmp);
7625 (define_insn "*tablejump_sp32"
7626 [(set (pc) (match_operand:SI 0 "address_operand" "p"))
7627 (use (label_ref (match_operand 1 "" "")))]
7630 [(set_attr "type" "uncond_branch")])
7632 (define_insn "*tablejump_sp64"
7633 [(set (pc) (match_operand:DI 0 "address_operand" "p"))
7634 (use (label_ref (match_operand 1 "" "")))]
7637 [(set_attr "type" "uncond_branch")])
7639 ;; This pattern recognizes the "instruction" that appears in
7640 ;; a function call that wants a structure value,
7641 ;; to inform the called function if compiled with Sun CC.
7642 ;(define_insn "*unimp_insn"
7643 ; [(match_operand:SI 0 "immediate_operand" "")]
7644 ; "GET_CODE (operands[0]) == CONST_INT && INTVAL (operands[0]) > 0"
7646 ; [(set_attr "type" "marker")])
7648 ;;- jump to subroutine
7649 (define_expand "call"
7650 ;; Note that this expression is not used for generating RTL.
7651 ;; All the RTL is generated explicitly below.
7652 [(call (match_operand 0 "call_operand" "")
7653 (match_operand 3 "" "i"))]
7654 ;; operands[2] is next_arg_register
7655 ;; operands[3] is struct_value_size_rtx.
7659 rtx fn_rtx, nregs_rtx;
7661 if (GET_MODE (operands[0]) != FUNCTION_MODE)
7664 if (GET_CODE (XEXP (operands[0], 0)) == LABEL_REF)
7666 /* This is really a PIC sequence. We want to represent
7667 it as a funny jump so its delay slots can be filled.
7669 ??? But if this really *is* a CALL, will not it clobber the
7670 call-clobbered registers? We lose this if it is a JUMP_INSN.
7671 Why cannot we have delay slots filled if it were a CALL? */
7673 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
7678 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
7680 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
7686 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
7687 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
7691 fn_rtx = operands[0];
7693 /* Count the number of parameter registers being used by this call.
7694 if that argument is NULL, it means we are using them all, which
7695 means 6 on the sparc. */
7698 nregs_rtx = GEN_INT (REGNO (operands[2]) - 8);
7700 nregs_rtx = GEN_INT (6);
7702 nregs_rtx = const0_rtx;
7705 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
7709 gen_rtvec (3, gen_rtx_CALL (VOIDmode, fn_rtx, nregs_rtx),
7711 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
7716 gen_rtvec (2, gen_rtx_CALL (VOIDmode, fn_rtx, nregs_rtx),
7717 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
7721 /* If this call wants a structure value,
7722 emit an unimp insn to let the called function know about this. */
7723 if (! TARGET_ARCH64 && INTVAL (operands[3]) > 0)
7725 rtx insn = emit_insn (operands[3]);
7726 SCHED_GROUP_P (insn) = 1;
7733 ;; We can't use the same pattern for these two insns, because then registers
7734 ;; in the address may not be properly reloaded.
7736 (define_insn "*call_address_sp32"
7737 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
7738 (match_operand 1 "" ""))
7739 (clobber (reg:SI 15))]
7740 ;;- Do not use operand 1 for most machines.
7743 [(set_attr "type" "call")])
7745 (define_insn "*call_symbolic_sp32"
7746 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
7747 (match_operand 1 "" ""))
7748 (clobber (reg:SI 15))]
7749 ;;- Do not use operand 1 for most machines.
7752 [(set_attr "type" "call")])
7754 (define_insn "*call_address_sp64"
7755 [(call (mem:DI (match_operand:DI 0 "address_operand" "p"))
7756 (match_operand 1 "" ""))
7757 (clobber (reg:DI 15))]
7758 ;;- Do not use operand 1 for most machines.
7761 [(set_attr "type" "call")])
7763 (define_insn "*call_symbolic_sp64"
7764 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
7765 (match_operand 1 "" ""))
7766 (clobber (reg:DI 15))]
7767 ;;- Do not use operand 1 for most machines.
7770 [(set_attr "type" "call")])
7772 ;; This is a call that wants a structure value.
7773 ;; There is no such critter for v9 (??? we may need one anyway).
7774 (define_insn "*call_address_struct_value_sp32"
7775 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
7776 (match_operand 1 "" ""))
7777 (match_operand 2 "immediate_operand" "")
7778 (clobber (reg:SI 15))]
7779 ;;- Do not use operand 1 for most machines.
7780 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 0"
7781 "call\\t%a0, %1\\n\\tnop\\n\\tunimp\\t%2"
7782 [(set_attr "type" "call_no_delay_slot")
7783 (set_attr "length" "3")])
7785 ;; This is a call that wants a structure value.
7786 ;; There is no such critter for v9 (??? we may need one anyway).
7787 (define_insn "*call_symbolic_struct_value_sp32"
7788 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
7789 (match_operand 1 "" ""))
7790 (match_operand 2 "immediate_operand" "")
7791 (clobber (reg:SI 15))]
7792 ;;- Do not use operand 1 for most machines.
7793 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 0"
7794 "call\\t%a0, %1\\n\\tnop\\n\\tunimp\\t%2"
7795 [(set_attr "type" "call_no_delay_slot")
7796 (set_attr "length" "3")])
7798 ;; This is a call that may want a structure value. This is used for
7800 (define_insn "*call_address_untyped_struct_value_sp32"
7801 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
7802 (match_operand 1 "" ""))
7803 (match_operand 2 "immediate_operand" "")
7804 (clobber (reg:SI 15))]
7805 ;;- Do not use operand 1 for most machines.
7806 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
7807 "call\\t%a0, %1\\n\\tnop\\n\\tnop"
7808 [(set_attr "type" "call_no_delay_slot")
7809 (set_attr "length" "3")])
7811 ;; This is a call that wants a structure value.
7812 (define_insn "*call_symbolic_untyped_struct_value_sp32"
7813 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
7814 (match_operand 1 "" ""))
7815 (match_operand 2 "immediate_operand" "")
7816 (clobber (reg:SI 15))]
7817 ;;- Do not use operand 1 for most machines.
7818 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
7819 "call\\t%a0, %1\\n\\tnop\\n\\tnop"
7820 [(set_attr "type" "call_no_delay_slot")
7821 (set_attr "length" "3")])
7823 (define_expand "call_value"
7824 ;; Note that this expression is not used for generating RTL.
7825 ;; All the RTL is generated explicitly below.
7826 [(set (match_operand 0 "register_operand" "=rf")
7827 (call (match_operand 1 "" "")
7828 (match_operand 4 "" "")))]
7829 ;; operand 2 is stack_size_rtx
7830 ;; operand 3 is next_arg_register
7834 rtx fn_rtx, nregs_rtx;
7837 if (GET_MODE (operands[1]) != FUNCTION_MODE)
7840 fn_rtx = operands[1];
7844 nregs_rtx = GEN_INT (REGNO (operands[3]) - 8);
7846 nregs_rtx = GEN_INT (6);
7848 nregs_rtx = const0_rtx;
7852 gen_rtx_SET (VOIDmode, operands[0],
7853 gen_rtx_CALL (VOIDmode, fn_rtx, nregs_rtx)),
7854 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)));
7856 emit_call_insn (gen_rtx_PARALLEL (VOIDmode, vec));
7861 (define_insn "*call_value_address_sp32"
7862 [(set (match_operand 0 "" "=rf")
7863 (call (mem:SI (match_operand:SI 1 "address_operand" "p"))
7864 (match_operand 2 "" "")))
7865 (clobber (reg:SI 15))]
7866 ;;- Do not use operand 2 for most machines.
7869 [(set_attr "type" "call")])
7871 (define_insn "*call_value_symbolic_sp32"
7872 [(set (match_operand 0 "" "=rf")
7873 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
7874 (match_operand 2 "" "")))
7875 (clobber (reg:SI 15))]
7876 ;;- Do not use operand 2 for most machines.
7879 [(set_attr "type" "call")])
7881 (define_insn "*call_value_address_sp64"
7882 [(set (match_operand 0 "" "")
7883 (call (mem:DI (match_operand:DI 1 "address_operand" "p"))
7884 (match_operand 2 "" "")))
7885 (clobber (reg:DI 15))]
7886 ;;- Do not use operand 2 for most machines.
7889 [(set_attr "type" "call")])
7891 (define_insn "*call_value_symbolic_sp64"
7892 [(set (match_operand 0 "" "")
7893 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
7894 (match_operand 2 "" "")))
7895 (clobber (reg:DI 15))]
7896 ;;- Do not use operand 2 for most machines.
7899 [(set_attr "type" "call")])
7901 (define_expand "untyped_call"
7902 [(parallel [(call (match_operand 0 "" "")
7904 (match_operand 1 "" "")
7905 (match_operand 2 "" "")])]
7911 /* Pass constm1 to indicate that it may expect a structure value, but
7912 we don't know what size it is. */
7913 emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, constm1_rtx));
7915 for (i = 0; i < XVECLEN (operands[2], 0); i++)
7917 rtx set = XVECEXP (operands[2], 0, i);
7918 emit_move_insn (SET_DEST (set), SET_SRC (set));
7921 /* The optimizer does not know that the call sets the function value
7922 registers we stored in the result block. We avoid problems by
7923 claiming that all hard registers are used and clobbered at this
7925 emit_insn (gen_blockage ());
7931 (define_expand "sibcall"
7932 [(parallel [(call (match_operand 0 "call_operand" "") (const_int 0))
7937 (define_insn "*sibcall_symbolic_sp32"
7938 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
7939 (match_operand 1 "" ""))
7942 "* return output_sibcall(insn, operands[0]);"
7943 [(set_attr "type" "sibcall")])
7945 (define_insn "*sibcall_symbolic_sp64"
7946 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
7947 (match_operand 1 "" ""))
7950 "* return output_sibcall(insn, operands[0]);"
7951 [(set_attr "type" "sibcall")])
7953 (define_expand "sibcall_value"
7954 [(parallel [(set (match_operand 0 "register_operand" "=rf")
7955 (call (match_operand 1 "" "") (const_int 0)))
7960 (define_insn "*sibcall_value_symbolic_sp32"
7961 [(set (match_operand 0 "" "=rf")
7962 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
7963 (match_operand 2 "" "")))
7966 "* return output_sibcall(insn, operands[1]);"
7967 [(set_attr "type" "sibcall")])
7969 (define_insn "*sibcall_value_symbolic_sp64"
7970 [(set (match_operand 0 "" "")
7971 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
7972 (match_operand 2 "" "")))
7975 "* return output_sibcall(insn, operands[1]);"
7976 [(set_attr "type" "sibcall")])
7978 (define_expand "sibcall_epilogue"
7983 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
7984 ;; all of memory. This blocks insns from being moved across this point.
7986 (define_insn "blockage"
7987 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
7990 [(set_attr "length" "0")])
7992 ;; Prepare to return any type including a structure value.
7994 (define_expand "untyped_return"
7995 [(match_operand:BLK 0 "memory_operand" "")
7996 (match_operand 1 "" "")]
8000 rtx valreg1 = gen_rtx_REG (DImode, 24);
8001 rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
8002 rtx result = operands[0];
8004 if (! TARGET_ARCH64)
8006 rtx rtnreg = gen_rtx_REG (SImode, (current_function_uses_only_leaf_regs
8008 rtx value = gen_reg_rtx (SImode);
8010 /* Fetch the instruction where we will return to and see if it's an unimp
8011 instruction (the most significant 10 bits will be zero). If so,
8012 update the return address to skip the unimp instruction. */
8013 emit_move_insn (value,
8014 gen_rtx_MEM (SImode, plus_constant (rtnreg, 8)));
8015 emit_insn (gen_lshrsi3 (value, value, GEN_INT (22)));
8016 emit_insn (gen_update_return (rtnreg, value));
8019 /* Reload the function value registers. */
8020 emit_move_insn (valreg1, adjust_address (result, DImode, 0));
8021 emit_move_insn (valreg2,
8022 adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8));
8024 /* Put USE insns before the return. */
8025 emit_insn (gen_rtx_USE (VOIDmode, valreg1));
8026 emit_insn (gen_rtx_USE (VOIDmode, valreg2));
8028 /* Construct the return. */
8029 expand_null_return ();
8034 ;; This is a bit of a hack. We're incrementing a fixed register (%i7),
8035 ;; and parts of the compiler don't want to believe that the add is needed.
8037 (define_insn "update_return"
8038 [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
8039 (match_operand:SI 1 "register_operand" "r")] UNSPEC_UPDATE_RETURN)]
8041 "cmp\\t%1, 0\;be,a\\t.+8\;add\\t%0, 4, %0"
8042 [(set_attr "type" "multi")
8043 (set_attr "length" "3")])
8050 (define_expand "indirect_jump"
8051 [(set (pc) (match_operand 0 "address_operand" "p"))]
8055 (define_insn "*branch_sp32"
8056 [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
8059 [(set_attr "type" "uncond_branch")])
8061 (define_insn "*branch_sp64"
8062 [(set (pc) (match_operand:DI 0 "address_operand" "p"))]
8065 [(set_attr "type" "uncond_branch")])
8067 ;; ??? Doesn't work with -mflat.
8068 (define_expand "nonlocal_goto"
8069 [(match_operand:SI 0 "general_operand" "")
8070 (match_operand:SI 1 "general_operand" "")
8071 (match_operand:SI 2 "general_operand" "")
8072 (match_operand:SI 3 "" "")]
8077 rtx chain = operands[0];
8079 rtx lab = operands[1];
8080 rtx stack = operands[2];
8081 rtx fp = operands[3];
8084 /* Trap instruction to flush all the register windows. */
8085 emit_insn (gen_flush_register_windows ());
8087 /* Load the fp value for the containing fn into %fp. This is needed
8088 because STACK refers to %fp. Note that virtual register instantiation
8089 fails if the virtual %fp isn't set from a register. */
8090 if (GET_CODE (fp) != REG)
8091 fp = force_reg (Pmode, fp);
8092 emit_move_insn (virtual_stack_vars_rtx, fp);
8094 /* Find the containing function's current nonlocal goto handler,
8095 which will do any cleanups and then jump to the label. */
8096 labreg = gen_rtx_REG (Pmode, 8);
8097 emit_move_insn (labreg, lab);
8099 /* Restore %fp from stack pointer value for containing function.
8100 The restore insn that follows will move this to %sp,
8101 and reload the appropriate value into %fp. */
8102 emit_move_insn (hard_frame_pointer_rtx, stack);
8104 /* USE of frame_pointer_rtx added for consistency; not clear if
8106 /*emit_insn (gen_rtx_USE (VOIDmode, frame_pointer_rtx));*/
8107 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
8110 /* Return, restoring reg window and jumping to goto handler. */
8111 if (TARGET_V9 && GET_CODE (chain) == CONST_INT
8112 && ! (INTVAL (chain) & ~(HOST_WIDE_INT)0xffffffff))
8114 emit_jump_insn (gen_goto_handler_and_restore_v9 (labreg,
8120 /* Put in the static chain register the nonlocal label address. */
8121 emit_move_insn (static_chain_rtx, chain);
8124 emit_insn (gen_rtx_USE (VOIDmode, static_chain_rtx));
8125 emit_jump_insn (gen_goto_handler_and_restore (labreg));
8130 ;; Special trap insn to flush register windows.
8131 (define_insn "flush_register_windows"
8132 [(unspec_volatile [(const_int 0)] UNSPECV_FLUSHW)]
8134 "* return TARGET_V9 ? \"flushw\" : \"ta\\t3\";"
8135 [(set_attr "type" "flushw")])
8137 (define_insn "goto_handler_and_restore"
8138 [(unspec_volatile [(match_operand 0 "register_operand" "=r")] UNSPECV_GOTO)]
8139 "GET_MODE (operands[0]) == Pmode"
8140 "jmp\\t%0+0\\n\\trestore"
8141 [(set_attr "type" "multi")
8142 (set_attr "length" "2")])
8144 ;;(define_insn "goto_handler_and_restore_v9"
8145 ;; [(unspec_volatile [(match_operand:SI 0 "register_operand" "=r,r")
8146 ;; (match_operand:SI 1 "register_operand" "=r,r")
8147 ;; (match_operand:SI 2 "const_int_operand" "I,n")] UNSPECV_GOTO_V9)]
8148 ;; "TARGET_V9 && ! TARGET_ARCH64"
8150 ;; return\\t%0+0\\n\\tmov\\t%2, %Y1
8151 ;; sethi\\t%%hi(%2), %1\\n\\treturn\\t%0+0\\n\\tor\\t%Y1, %%lo(%2), %Y1"
8152 ;; [(set_attr "type" "multi")
8153 ;; (set_attr "length" "2,3")])
8155 ;;(define_insn "*goto_handler_and_restore_v9_sp64"
8156 ;; [(unspec_volatile [(match_operand:DI 0 "register_operand" "=r,r")
8157 ;; (match_operand:DI 1 "register_operand" "=r,r")
8158 ;; (match_operand:SI 2 "const_int_operand" "I,n")] UNSPECV_GOTO_V9)]
8159 ;; "TARGET_V9 && TARGET_ARCH64"
8161 ;; return\\t%0+0\\n\\tmov\\t%2, %Y1
8162 ;; sethi\\t%%hi(%2), %1\\n\\treturn\\t%0+0\\n\\tor\\t%Y1, %%lo(%2), %Y1"
8163 ;; [(set_attr "type" "multi")
8164 ;; (set_attr "length" "2,3")])
8166 ;; For __builtin_setjmp we need to flush register windows iff the function
8167 ;; calls alloca as well, because otherwise the register window might be
8168 ;; saved after %sp adjustement and thus setjmp would crash
8169 (define_expand "builtin_setjmp_setup"
8170 [(match_operand 0 "register_operand" "r")]
8174 emit_insn (gen_do_builtin_setjmp_setup ());
8178 (define_insn "do_builtin_setjmp_setup"
8179 [(unspec_volatile [(const_int 0)] UNSPECV_SETJMP)]
8183 if (! current_function_calls_alloca)
8185 if (! TARGET_V9 || TARGET_FLAT)
8186 return \"\tta\t3\n\";
8187 fputs (\"\tflushw\n\", asm_out_file);
8189 fprintf (asm_out_file, \"\tst%c\t%%l7, [%%sp+%d]\n\",
8190 TARGET_ARCH64 ? 'x' : 'w',
8191 SPARC_STACK_BIAS + 7 * UNITS_PER_WORD);
8192 fprintf (asm_out_file, \"\tst%c\t%%fp, [%%sp+%d]\n\",
8193 TARGET_ARCH64 ? 'x' : 'w',
8194 SPARC_STACK_BIAS + 14 * UNITS_PER_WORD);
8195 fprintf (asm_out_file, \"\tst%c\t%%i7, [%%sp+%d]\n\",
8196 TARGET_ARCH64 ? 'x' : 'w',
8197 SPARC_STACK_BIAS + 15 * UNITS_PER_WORD);
8200 [(set_attr "type" "multi")
8201 (set (attr "length")
8202 (cond [(eq_attr "current_function_calls_alloca" "false")
8204 (eq_attr "flat" "true")
8206 (eq_attr "isa" "!v9")
8208 (eq_attr "pic" "true")
8209 (const_int 4)] (const_int 3)))])
8211 ;; Pattern for use after a setjmp to store FP and the return register
8212 ;; into the stack area.
8214 (define_expand "setjmp"
8220 emit_insn (gen_setjmp_64 ());
8222 emit_insn (gen_setjmp_32 ());
8226 (define_expand "setjmp_32"
8227 [(set (mem:SI (plus:SI (reg:SI 14) (const_int 56))) (match_dup 0))
8228 (set (mem:SI (plus:SI (reg:SI 14) (const_int 60))) (reg:SI 31))]
8231 { operands[0] = frame_pointer_rtx; }")
8233 (define_expand "setjmp_64"
8234 [(set (mem:DI (plus:DI (reg:DI 14) (const_int 112))) (match_dup 0))
8235 (set (mem:DI (plus:DI (reg:DI 14) (const_int 120))) (reg:DI 31))]
8238 { operands[0] = frame_pointer_rtx; }")
8240 ;; Special pattern for the FLUSH instruction.
8242 ; We do SImode and DImode versions of this to quiet down genrecog's complaints
8243 ; of the define_insn otherwise missing a mode. We make "flush", aka
8244 ; gen_flush, the default one since sparc_initialize_trampoline uses
8245 ; it on SImode mem values.
8247 (define_insn "flush"
8248 [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")] UNSPECV_FLUSH)]
8250 "* return TARGET_V9 ? \"flush\\t%f0\" : \"iflush\\t%f0\";"
8251 [(set_attr "type" "iflush")])
8253 (define_insn "flushdi"
8254 [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")] UNSPECV_FLUSH)]
8256 "* return TARGET_V9 ? \"flush\\t%f0\" : \"iflush\\t%f0\";"
8257 [(set_attr "type" "iflush")])
8262 ;; The scan instruction searches from the most significant bit while ffs
8263 ;; searches from the least significant bit. The bit index and treatment of
8264 ;; zero also differ. It takes at least 7 instructions to get the proper
8265 ;; result. Here is an obvious 8 instruction sequence.
8268 (define_insn "ffssi2"
8269 [(set (match_operand:SI 0 "register_operand" "=&r")
8270 (ffs:SI (match_operand:SI 1 "register_operand" "r")))
8271 (clobber (match_scratch:SI 2 "=&r"))]
8272 "TARGET_SPARCLITE || TARGET_SPARCLET"
8275 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\";
8277 [(set_attr "type" "multi")
8278 (set_attr "length" "8")])
8280 ;; ??? This should be a define expand, so that the extra instruction have
8281 ;; a chance of being optimized away.
8283 ;; Disabled because none of the UltraSparcs implement popc. The HAL R1
8284 ;; does, but no one uses that and we don't have a switch for it.
8286 ;(define_insn "ffsdi2"
8287 ; [(set (match_operand:DI 0 "register_operand" "=&r")
8288 ; (ffs:DI (match_operand:DI 1 "register_operand" "r")))
8289 ; (clobber (match_scratch:DI 2 "=&r"))]
8291 ; "neg\\t%1, %2\;xnor\\t%1, %2, %2\;popc\\t%2, %0\;movzr\\t%1, 0, %0"
8292 ; [(set_attr "type" "multi")
8293 ; (set_attr "length" "4")])
8297 ;; Peepholes go at the end.
8299 ;; Optimize consecutive loads or stores into ldd and std when possible.
8300 ;; The conditions in which we do this are very restricted and are
8301 ;; explained in the code for {registers,memory}_ok_for_ldd functions.
8304 [(set (match_operand:SI 0 "memory_operand" "")
8306 (set (match_operand:SI 1 "memory_operand" "")
8309 && mems_ok_for_ldd_peep (operands[0], operands[1], NULL_RTX)"
8312 "operands[0] = change_address (operands[0], DImode, NULL);")
8315 [(set (match_operand:SI 0 "memory_operand" "")
8317 (set (match_operand:SI 1 "memory_operand" "")
8320 && mems_ok_for_ldd_peep (operands[1], operands[0], NULL_RTX)"
8323 "operands[1] = change_address (operands[1], DImode, NULL);")
8326 [(set (match_operand:SI 0 "register_operand" "")
8327 (match_operand:SI 1 "memory_operand" ""))
8328 (set (match_operand:SI 2 "register_operand" "")
8329 (match_operand:SI 3 "memory_operand" ""))]
8330 "registers_ok_for_ldd_peep (operands[0], operands[2])
8331 && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
8334 "operands[1] = change_address (operands[1], DImode, NULL);
8335 operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));")
8338 [(set (match_operand:SI 0 "memory_operand" "")
8339 (match_operand:SI 1 "register_operand" ""))
8340 (set (match_operand:SI 2 "memory_operand" "")
8341 (match_operand:SI 3 "register_operand" ""))]
8342 "registers_ok_for_ldd_peep (operands[1], operands[3])
8343 && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
8346 "operands[0] = change_address (operands[0], DImode, NULL);
8347 operands[1] = gen_rtx_REG (DImode, REGNO (operands[1]));")
8350 [(set (match_operand:SF 0 "register_operand" "")
8351 (match_operand:SF 1 "memory_operand" ""))
8352 (set (match_operand:SF 2 "register_operand" "")
8353 (match_operand:SF 3 "memory_operand" ""))]
8354 "registers_ok_for_ldd_peep (operands[0], operands[2])
8355 && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
8358 "operands[1] = change_address (operands[1], DFmode, NULL);
8359 operands[0] = gen_rtx_REG (DFmode, REGNO (operands[0]));")
8362 [(set (match_operand:SF 0 "memory_operand" "")
8363 (match_operand:SF 1 "register_operand" ""))
8364 (set (match_operand:SF 2 "memory_operand" "")
8365 (match_operand:SF 3 "register_operand" ""))]
8366 "registers_ok_for_ldd_peep (operands[1], operands[3])
8367 && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
8370 "operands[0] = change_address (operands[0], DFmode, NULL);
8371 operands[1] = gen_rtx_REG (DFmode, REGNO (operands[1]));")
8374 [(set (match_operand:SI 0 "register_operand" "")
8375 (match_operand:SI 1 "memory_operand" ""))
8376 (set (match_operand:SI 2 "register_operand" "")
8377 (match_operand:SI 3 "memory_operand" ""))]
8378 "registers_ok_for_ldd_peep (operands[2], operands[0])
8379 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
8382 "operands[3] = change_address (operands[3], DImode, NULL);
8383 operands[2] = gen_rtx_REG (DImode, REGNO (operands[2]));")
8386 [(set (match_operand:SI 0 "memory_operand" "")
8387 (match_operand:SI 1 "register_operand" ""))
8388 (set (match_operand:SI 2 "memory_operand" "")
8389 (match_operand:SI 3 "register_operand" ""))]
8390 "registers_ok_for_ldd_peep (operands[3], operands[1])
8391 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
8394 "operands[2] = change_address (operands[2], DImode, NULL);
8395 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
8399 [(set (match_operand:SF 0 "register_operand" "")
8400 (match_operand:SF 1 "memory_operand" ""))
8401 (set (match_operand:SF 2 "register_operand" "")
8402 (match_operand:SF 3 "memory_operand" ""))]
8403 "registers_ok_for_ldd_peep (operands[2], operands[0])
8404 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
8407 "operands[3] = change_address (operands[3], DFmode, NULL);
8408 operands[2] = gen_rtx_REG (DFmode, REGNO (operands[2]));")
8411 [(set (match_operand:SF 0 "memory_operand" "")
8412 (match_operand:SF 1 "register_operand" ""))
8413 (set (match_operand:SF 2 "memory_operand" "")
8414 (match_operand:SF 3 "register_operand" ""))]
8415 "registers_ok_for_ldd_peep (operands[3], operands[1])
8416 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
8419 "operands[2] = change_address (operands[2], DFmode, NULL);
8420 operands[3] = gen_rtx_REG (DFmode, REGNO (operands[3]));")
8422 ;; Optimize the case of following a reg-reg move with a test
8423 ;; of reg just moved. Don't allow floating point regs for operand 0 or 1.
8424 ;; This can result from a float to fix conversion.
8427 [(set (match_operand:SI 0 "register_operand" "")
8428 (match_operand:SI 1 "register_operand" ""))
8430 (compare:CC (match_operand:SI 2 "register_operand" "")
8432 "(rtx_equal_p (operands[2], operands[0])
8433 || rtx_equal_p (operands[2], operands[1]))
8434 && ! SPARC_FP_REG_P (REGNO (operands[0]))
8435 && ! SPARC_FP_REG_P (REGNO (operands[1]))"
8436 [(parallel [(set (match_dup 0) (match_dup 1))
8438 (compare:CC (match_dup 1) (const_int 0)))])]
8442 [(set (match_operand:DI 0 "register_operand" "")
8443 (match_operand:DI 1 "register_operand" ""))
8445 (compare:CCX (match_operand:DI 2 "register_operand" "")
8448 && (rtx_equal_p (operands[2], operands[0])
8449 || rtx_equal_p (operands[2], operands[1]))
8450 && ! SPARC_FP_REG_P (REGNO (operands[0]))
8451 && ! SPARC_FP_REG_P (REGNO (operands[1]))"
8452 [(parallel [(set (match_dup 0) (match_dup 1))
8454 (compare:CCX (match_dup 1) (const_int 0)))])]
8457 ;; Return peepholes. These are generated by sparc_nonflat_function_epilogue
8458 ;; who then immediately calls final_scan_insn.
8460 (define_insn "*return_qi"
8461 [(set (match_operand:QI 0 "restore_operand" "")
8462 (match_operand:QI 1 "arith_operand" "rI"))
8464 "sparc_emitting_epilogue"
8467 if (! TARGET_ARCH64 && current_function_returns_struct)
8468 return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\";
8469 else if (TARGET_V9 && (GET_CODE (operands[1]) == CONST_INT
8470 || IN_OR_GLOBAL_P (operands[1])))
8471 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
8473 return \"ret\\n\\trestore %%g0, %1, %Y0\";
8475 [(set_attr "type" "multi")
8476 (set_attr "length" "2")])
8478 (define_insn "*return_hi"
8479 [(set (match_operand:HI 0 "restore_operand" "")
8480 (match_operand:HI 1 "arith_operand" "rI"))
8482 "sparc_emitting_epilogue"
8485 if (! TARGET_ARCH64 && current_function_returns_struct)
8486 return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\";
8487 else if (TARGET_V9 && (GET_CODE (operands[1]) == CONST_INT
8488 || IN_OR_GLOBAL_P (operands[1])))
8489 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
8491 return \"ret\;restore %%g0, %1, %Y0\";
8493 [(set_attr "type" "multi")
8494 (set_attr "length" "2")])
8496 (define_insn "*return_si"
8497 [(set (match_operand:SI 0 "restore_operand" "")
8498 (match_operand:SI 1 "arith_operand" "rI"))
8500 "sparc_emitting_epilogue"
8503 if (! TARGET_ARCH64 && current_function_returns_struct)
8504 return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\";
8505 else if (TARGET_V9 && (GET_CODE (operands[1]) == CONST_INT
8506 || IN_OR_GLOBAL_P (operands[1])))
8507 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
8509 return \"ret\;restore %%g0, %1, %Y0\";
8511 [(set_attr "type" "multi")
8512 (set_attr "length" "2")])
8514 (define_insn "*return_sf_no_fpu"
8515 [(set (match_operand:SF 0 "restore_operand" "=r")
8516 (match_operand:SF 1 "register_operand" "r"))
8518 "sparc_emitting_epilogue"
8521 if (! TARGET_ARCH64 && current_function_returns_struct)
8522 return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\";
8523 else if (TARGET_V9 && IN_OR_GLOBAL_P (operands[1]))
8524 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
8526 return \"ret\;restore %%g0, %1, %Y0\";
8528 [(set_attr "type" "multi")
8529 (set_attr "length" "2")])
8531 (define_insn "*return_df_no_fpu"
8532 [(set (match_operand:DF 0 "restore_operand" "=r")
8533 (match_operand:DF 1 "register_operand" "r"))
8535 "sparc_emitting_epilogue && TARGET_ARCH64"
8538 if (IN_OR_GLOBAL_P (operands[1]))
8539 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
8541 return \"ret\;restore %%g0, %1, %Y0\";
8543 [(set_attr "type" "multi")
8544 (set_attr "length" "2")])
8546 (define_insn "*return_addsi"
8547 [(set (match_operand:SI 0 "restore_operand" "")
8548 (plus:SI (match_operand:SI 1 "register_operand" "r")
8549 (match_operand:SI 2 "arith_operand" "rI")))
8551 "sparc_emitting_epilogue"
8554 if (! TARGET_ARCH64 && current_function_returns_struct)
8555 return \"jmp\\t%%i7+12\\n\\trestore %r1, %2, %Y0\";
8556 /* If operands are global or in registers, can use return */
8557 else if (TARGET_V9 && IN_OR_GLOBAL_P (operands[1])
8558 && (GET_CODE (operands[2]) == CONST_INT
8559 || IN_OR_GLOBAL_P (operands[2])))
8560 return \"return\\t%%i7+8\\n\\tadd\\t%Y1, %Y2, %Y0\";
8562 return \"ret\;restore %r1, %2, %Y0\";
8564 [(set_attr "type" "multi")
8565 (set_attr "length" "2")])
8567 (define_insn "*return_losum_si"
8568 [(set (match_operand:SI 0 "restore_operand" "")
8569 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
8570 (match_operand:SI 2 "immediate_operand" "in")))
8572 "sparc_emitting_epilogue && ! TARGET_CM_MEDMID"
8575 if (! TARGET_ARCH64 && current_function_returns_struct)
8576 return \"jmp\\t%%i7+12\\n\\trestore %r1, %%lo(%a2), %Y0\";
8577 /* If operands are global or in registers, can use return */
8578 else if (TARGET_V9 && IN_OR_GLOBAL_P (operands[1]))
8579 return \"return\\t%%i7+8\\n\\tor\\t%Y1, %%lo(%a2), %Y0\";
8581 return \"ret\;restore %r1, %%lo(%a2), %Y0\";
8583 [(set_attr "type" "multi")
8584 (set_attr "length" "2")])
8586 (define_insn "*return_di"
8587 [(set (match_operand:DI 0 "restore_operand" "")
8588 (match_operand:DI 1 "arith_double_operand" "rHI"))
8590 "sparc_emitting_epilogue && TARGET_ARCH64"
8591 "ret\;restore %%g0, %1, %Y0"
8592 [(set_attr "type" "multi")
8593 (set_attr "length" "2")])
8595 (define_insn "*return_adddi"
8596 [(set (match_operand:DI 0 "restore_operand" "")
8597 (plus:DI (match_operand:DI 1 "arith_operand" "%r")
8598 (match_operand:DI 2 "arith_double_operand" "rHI")))
8600 "sparc_emitting_epilogue && TARGET_ARCH64"
8601 "ret\;restore %r1, %2, %Y0"
8602 [(set_attr "type" "multi")
8603 (set_attr "length" "2")])
8605 (define_insn "*return_losum_di"
8606 [(set (match_operand:DI 0 "restore_operand" "")
8607 (lo_sum:DI (match_operand:DI 1 "arith_operand" "%r")
8608 (match_operand:DI 2 "immediate_operand" "in")))
8610 "sparc_emitting_epilogue && TARGET_ARCH64 && ! TARGET_CM_MEDMID"
8611 "ret\;restore %r1, %%lo(%a2), %Y0"
8612 [(set_attr "type" "multi")
8613 (set_attr "length" "2")])
8615 (define_insn "*return_sf"
8617 (match_operand:SF 0 "register_operand" "f"))
8619 "sparc_emitting_epilogue"
8620 "ret\;fmovs\\t%0, %%f0"
8621 [(set_attr "type" "multi")
8622 (set_attr "length" "2")])
8624 ;; Now peepholes to do a call followed by a jump.
8627 [(parallel [(set (match_operand 0 "" "")
8628 (call (mem:SI (match_operand:SI 1 "call_operand_address" "ps"))
8629 (match_operand 2 "" "")))
8630 (clobber (reg:SI 15))])
8631 (set (pc) (label_ref (match_operand 3 "" "")))]
8632 "short_branch (INSN_UID (insn), INSN_UID (operands[3]))
8633 && (USING_SJLJ_EXCEPTIONS || ! can_throw_internal (ins1))
8634 && sparc_cpu != PROCESSOR_ULTRASPARC
8635 && sparc_cpu != PROCESSOR_ULTRASPARC3"
8636 "call\\t%a1, %2\\n\\tadd\\t%%o7, (%l3-.-4), %%o7")
8639 [(parallel [(call (mem:SI (match_operand:SI 0 "call_operand_address" "ps"))
8640 (match_operand 1 "" ""))
8641 (clobber (reg:SI 15))])
8642 (set (pc) (label_ref (match_operand 2 "" "")))]
8643 "short_branch (INSN_UID (insn), INSN_UID (operands[2]))
8644 && (USING_SJLJ_EXCEPTIONS || ! can_throw_internal (ins1))
8645 && sparc_cpu != PROCESSOR_ULTRASPARC
8646 && sparc_cpu != PROCESSOR_ULTRASPARC3"
8647 "call\\t%a0, %1\\n\\tadd\\t%%o7, (%l2-.-4), %%o7")
8649 ;; ??? UltraSPARC-III note: A memory operation loading into the floating point register
8650 ;; ??? file, if it hits the prefetch cache, has a chance to dual-issue with other memory
8651 ;; ??? operations. With DFA we might be able to model this, but it requires a lot of
8653 (define_expand "prefetch"
8654 [(match_operand 0 "address_operand" "")
8655 (match_operand 1 "const_int_operand" "")
8656 (match_operand 2 "const_int_operand" "")]
8661 emit_insn (gen_prefetch_64 (operands[0], operands[1], operands[2]));
8663 emit_insn (gen_prefetch_32 (operands[0], operands[1], operands[2]));
8667 (define_insn "prefetch_64"
8668 [(prefetch (match_operand:DI 0 "address_operand" "p")
8669 (match_operand:DI 1 "const_int_operand" "n")
8670 (match_operand:DI 2 "const_int_operand" "n"))]
8673 static const char * const prefetch_instr[2][2] = {
8675 "prefetch\\t[%a0], 1", /* no locality: prefetch for one read */
8676 "prefetch\\t[%a0], 0", /* medium to high locality: prefetch for several reads */
8679 "prefetch\\t[%a0], 3", /* no locality: prefetch for one write */
8680 "prefetch\\t[%a0], 2", /* medium to high locality: prefetch for several writes */
8683 int read_or_write = INTVAL (operands[1]);
8684 int locality = INTVAL (operands[2]);
8686 if (read_or_write != 0 && read_or_write != 1)
8688 if (locality < 0 || locality > 3)
8690 return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
8692 [(set_attr "type" "load")])
8694 (define_insn "prefetch_32"
8695 [(prefetch (match_operand:SI 0 "address_operand" "p")
8696 (match_operand:SI 1 "const_int_operand" "n")
8697 (match_operand:SI 2 "const_int_operand" "n"))]
8700 static const char * const prefetch_instr[2][2] = {
8702 "prefetch\\t[%a0], 1", /* no locality: prefetch for one read */
8703 "prefetch\\t[%a0], 0", /* medium to high locality: prefetch for several reads */
8706 "prefetch\\t[%a0], 3", /* no locality: prefetch for one write */
8707 "prefetch\\t[%a0], 2", /* medium to high locality: prefetch for several writes */
8710 int read_or_write = INTVAL (operands[1]);
8711 int locality = INTVAL (operands[2]);
8713 if (read_or_write != 0 && read_or_write != 1)
8715 if (locality < 0 || locality > 3)
8717 return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
8719 [(set_attr "type" "load")])
8721 (define_expand "prologue"
8723 "flag_pic && current_function_uses_pic_offset_table"
8726 load_pic_register ();
8730 ;; We need to reload %l7 for -mflat -fpic,
8731 ;; otherwise %l7 should be preserved simply
8732 ;; by loading the function's register window
8733 (define_expand "exception_receiver"
8735 "TARGET_FLAT && flag_pic"
8738 load_pic_register ();
8743 (define_expand "builtin_setjmp_receiver"
8744 [(label_ref (match_operand 0 "" ""))]
8745 "TARGET_FLAT && flag_pic"
8748 load_pic_register ();
8753 [(trap_if (const_int 1) (const_int 5))]
8756 [(set_attr "type" "trap")])
8758 (define_expand "conditional_trap"
8759 [(trap_if (match_operator 0 "noov_compare_op"
8760 [(match_dup 2) (match_dup 3)])
8761 (match_operand:SI 1 "arith_operand" ""))]
8763 "operands[2] = gen_compare_reg (GET_CODE (operands[0]),
8764 sparc_compare_op0, sparc_compare_op1);
8765 operands[3] = const0_rtx;")
8768 [(trap_if (match_operator 0 "noov_compare_op" [(reg:CC 100) (const_int 0)])
8769 (match_operand:SI 1 "arith_operand" "rM"))]
8772 [(set_attr "type" "trap")])
8775 [(trap_if (match_operator 0 "noov_compare_op" [(reg:CCX 100) (const_int 0)])
8776 (match_operand:SI 1 "arith_operand" "rM"))]
8779 [(set_attr "type" "trap")])