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" "")))]
293 sparc_compare_op0 = operands[0];
294 sparc_compare_op1 = operands[1];
298 (define_expand "cmpdi"
300 (compare:CCX (match_operand:DI 0 "register_operand" "")
301 (match_operand:DI 1 "arith_double_operand" "")))]
304 sparc_compare_op0 = operands[0];
305 sparc_compare_op1 = operands[1];
309 (define_expand "cmpsf"
310 ;; The 96 here isn't ever used by anyone.
312 (compare:CCFP (match_operand:SF 0 "register_operand" "")
313 (match_operand:SF 1 "register_operand" "")))]
316 sparc_compare_op0 = operands[0];
317 sparc_compare_op1 = operands[1];
321 (define_expand "cmpdf"
322 ;; The 96 here isn't ever used by anyone.
324 (compare:CCFP (match_operand:DF 0 "register_operand" "")
325 (match_operand:DF 1 "register_operand" "")))]
328 sparc_compare_op0 = operands[0];
329 sparc_compare_op1 = operands[1];
333 (define_expand "cmptf"
334 ;; The 96 here isn't ever used by anyone.
336 (compare:CCFP (match_operand:TF 0 "register_operand" "")
337 (match_operand:TF 1 "register_operand" "")))]
340 sparc_compare_op0 = operands[0];
341 sparc_compare_op1 = operands[1];
345 ;; Now the compare DEFINE_INSNs.
347 (define_insn "*cmpsi_insn"
349 (compare:CC (match_operand:SI 0 "register_operand" "r")
350 (match_operand:SI 1 "arith_operand" "rI")))]
353 [(set_attr "type" "compare")])
355 (define_insn "*cmpdi_sp64"
357 (compare:CCX (match_operand:DI 0 "register_operand" "r")
358 (match_operand:DI 1 "arith_double_operand" "rHI")))]
361 [(set_attr "type" "compare")])
363 (define_insn "*cmpsf_fpe"
364 [(set (match_operand:CCFPE 0 "fcc_reg_operand" "=c")
365 (compare:CCFPE (match_operand:SF 1 "register_operand" "f")
366 (match_operand:SF 2 "register_operand" "f")))]
370 return "fcmpes\t%0, %1, %2";
371 return "fcmpes\t%1, %2";
373 [(set_attr "type" "fpcmp")])
375 (define_insn "*cmpdf_fpe"
376 [(set (match_operand:CCFPE 0 "fcc_reg_operand" "=c")
377 (compare:CCFPE (match_operand:DF 1 "register_operand" "e")
378 (match_operand:DF 2 "register_operand" "e")))]
382 return "fcmped\t%0, %1, %2";
383 return "fcmped\t%1, %2";
385 [(set_attr "type" "fpcmp")
386 (set_attr "fptype" "double")])
388 (define_insn "*cmptf_fpe"
389 [(set (match_operand:CCFPE 0 "fcc_reg_operand" "=c")
390 (compare:CCFPE (match_operand:TF 1 "register_operand" "e")
391 (match_operand:TF 2 "register_operand" "e")))]
392 "TARGET_FPU && TARGET_HARD_QUAD"
395 return "fcmpeq\t%0, %1, %2";
396 return "fcmpeq\t%1, %2";
398 [(set_attr "type" "fpcmp")])
400 (define_insn "*cmpsf_fp"
401 [(set (match_operand:CCFP 0 "fcc_reg_operand" "=c")
402 (compare:CCFP (match_operand:SF 1 "register_operand" "f")
403 (match_operand:SF 2 "register_operand" "f")))]
407 return "fcmps\t%0, %1, %2";
408 return "fcmps\t%1, %2";
410 [(set_attr "type" "fpcmp")])
412 (define_insn "*cmpdf_fp"
413 [(set (match_operand:CCFP 0 "fcc_reg_operand" "=c")
414 (compare:CCFP (match_operand:DF 1 "register_operand" "e")
415 (match_operand:DF 2 "register_operand" "e")))]
419 return "fcmpd\t%0, %1, %2";
420 return "fcmpd\t%1, %2";
422 [(set_attr "type" "fpcmp")
423 (set_attr "fptype" "double")])
425 (define_insn "*cmptf_fp"
426 [(set (match_operand:CCFP 0 "fcc_reg_operand" "=c")
427 (compare:CCFP (match_operand:TF 1 "register_operand" "e")
428 (match_operand:TF 2 "register_operand" "e")))]
429 "TARGET_FPU && TARGET_HARD_QUAD"
432 return "fcmpq\t%0, %1, %2";
433 return "fcmpq\t%1, %2";
435 [(set_attr "type" "fpcmp")])
437 ;; Next come the scc insns. For seq, sne, sgeu, and sltu, we can do this
438 ;; without jumps using the addx/subx instructions. For seq/sne on v9 we use
439 ;; the same code as v8 (the addx/subx method has more applications). The
440 ;; exception to this is "reg != 0" which can be done in one instruction on v9
441 ;; (so we do it). For the rest, on v9 we use conditional moves; on v8, we do
444 ;; Seq_special[_xxx] and sne_special[_xxx] clobber the CC reg, because they
445 ;; generate addcc/subcc instructions.
447 (define_expand "seqsi_special"
449 (xor:SI (match_operand:SI 1 "register_operand" "")
450 (match_operand:SI 2 "register_operand" "")))
451 (parallel [(set (match_operand:SI 0 "register_operand" "")
452 (eq:SI (match_dup 3) (const_int 0)))
453 (clobber (reg:CC 100))])]
455 { operands[3] = gen_reg_rtx (SImode); })
457 (define_expand "seqdi_special"
459 (xor:DI (match_operand:DI 1 "register_operand" "")
460 (match_operand:DI 2 "register_operand" "")))
461 (set (match_operand:DI 0 "register_operand" "")
462 (eq:DI (match_dup 3) (const_int 0)))]
464 { operands[3] = gen_reg_rtx (DImode); })
466 (define_expand "snesi_special"
468 (xor:SI (match_operand:SI 1 "register_operand" "")
469 (match_operand:SI 2 "register_operand" "")))
470 (parallel [(set (match_operand:SI 0 "register_operand" "")
471 (ne:SI (match_dup 3) (const_int 0)))
472 (clobber (reg:CC 100))])]
474 { operands[3] = gen_reg_rtx (SImode); })
476 (define_expand "snedi_special"
478 (xor:DI (match_operand:DI 1 "register_operand" "")
479 (match_operand:DI 2 "register_operand" "")))
480 (set (match_operand:DI 0 "register_operand" "")
481 (ne:DI (match_dup 3) (const_int 0)))]
483 { operands[3] = gen_reg_rtx (DImode); })
485 (define_expand "seqdi_special_trunc"
487 (xor:DI (match_operand:DI 1 "register_operand" "")
488 (match_operand:DI 2 "register_operand" "")))
489 (set (match_operand:SI 0 "register_operand" "")
490 (eq:SI (match_dup 3) (const_int 0)))]
492 { operands[3] = gen_reg_rtx (DImode); })
494 (define_expand "snedi_special_trunc"
496 (xor:DI (match_operand:DI 1 "register_operand" "")
497 (match_operand:DI 2 "register_operand" "")))
498 (set (match_operand:SI 0 "register_operand" "")
499 (ne:SI (match_dup 3) (const_int 0)))]
501 { operands[3] = gen_reg_rtx (DImode); })
503 (define_expand "seqsi_special_extend"
505 (xor:SI (match_operand:SI 1 "register_operand" "")
506 (match_operand:SI 2 "register_operand" "")))
507 (parallel [(set (match_operand:DI 0 "register_operand" "")
508 (eq:DI (match_dup 3) (const_int 0)))
509 (clobber (reg:CC 100))])]
511 { operands[3] = gen_reg_rtx (SImode); })
513 (define_expand "snesi_special_extend"
515 (xor:SI (match_operand:SI 1 "register_operand" "")
516 (match_operand:SI 2 "register_operand" "")))
517 (parallel [(set (match_operand:DI 0 "register_operand" "")
518 (ne:DI (match_dup 3) (const_int 0)))
519 (clobber (reg:CC 100))])]
521 { operands[3] = gen_reg_rtx (SImode); })
523 ;; ??? v9: Operand 0 needs a mode, so SImode was chosen.
524 ;; However, the code handles both SImode and DImode.
526 [(set (match_operand:SI 0 "intreg_operand" "")
527 (eq:SI (match_dup 1) (const_int 0)))]
530 if (GET_MODE (sparc_compare_op0) == SImode)
534 if (GET_MODE (operands[0]) == SImode)
535 pat = gen_seqsi_special (operands[0], sparc_compare_op0,
537 else if (! TARGET_ARCH64)
540 pat = gen_seqsi_special_extend (operands[0], sparc_compare_op0,
545 else if (GET_MODE (sparc_compare_op0) == DImode)
551 else if (GET_MODE (operands[0]) == SImode)
552 pat = gen_seqdi_special_trunc (operands[0], sparc_compare_op0,
555 pat = gen_seqdi_special (operands[0], sparc_compare_op0,
560 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
562 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, EQ);
563 emit_jump_insn (gen_sne (operands[0]));
568 if (gen_v9_scc (EQ, operands))
575 ;; ??? v9: Operand 0 needs a mode, so SImode was chosen.
576 ;; However, the code handles both SImode and DImode.
578 [(set (match_operand:SI 0 "intreg_operand" "")
579 (ne:SI (match_dup 1) (const_int 0)))]
582 if (GET_MODE (sparc_compare_op0) == SImode)
586 if (GET_MODE (operands[0]) == SImode)
587 pat = gen_snesi_special (operands[0], sparc_compare_op0,
589 else if (! TARGET_ARCH64)
592 pat = gen_snesi_special_extend (operands[0], sparc_compare_op0,
597 else if (GET_MODE (sparc_compare_op0) == DImode)
603 else if (GET_MODE (operands[0]) == SImode)
604 pat = gen_snedi_special_trunc (operands[0], sparc_compare_op0,
607 pat = gen_snedi_special (operands[0], sparc_compare_op0,
612 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
614 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, NE);
615 emit_jump_insn (gen_sne (operands[0]));
620 if (gen_v9_scc (NE, operands))
628 [(set (match_operand:SI 0 "intreg_operand" "")
629 (gt:SI (match_dup 1) (const_int 0)))]
632 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
634 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GT);
635 emit_jump_insn (gen_sne (operands[0]));
640 if (gen_v9_scc (GT, operands))
648 [(set (match_operand:SI 0 "intreg_operand" "")
649 (lt:SI (match_dup 1) (const_int 0)))]
652 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
654 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LT);
655 emit_jump_insn (gen_sne (operands[0]));
660 if (gen_v9_scc (LT, operands))
668 [(set (match_operand:SI 0 "intreg_operand" "")
669 (ge:SI (match_dup 1) (const_int 0)))]
672 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
674 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GE);
675 emit_jump_insn (gen_sne (operands[0]));
680 if (gen_v9_scc (GE, operands))
688 [(set (match_operand:SI 0 "intreg_operand" "")
689 (le:SI (match_dup 1) (const_int 0)))]
692 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
694 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LE);
695 emit_jump_insn (gen_sne (operands[0]));
700 if (gen_v9_scc (LE, operands))
707 (define_expand "sgtu"
708 [(set (match_operand:SI 0 "intreg_operand" "")
709 (gtu:SI (match_dup 1) (const_int 0)))]
716 /* We can do ltu easily, so if both operands are registers, swap them and
718 if ((GET_CODE (sparc_compare_op0) == REG
719 || GET_CODE (sparc_compare_op0) == SUBREG)
720 && (GET_CODE (sparc_compare_op1) == REG
721 || GET_CODE (sparc_compare_op1) == SUBREG))
723 tem = sparc_compare_op0;
724 sparc_compare_op0 = sparc_compare_op1;
725 sparc_compare_op1 = tem;
726 pat = gen_sltu (operands[0]);
735 if (gen_v9_scc (GTU, operands))
741 (define_expand "sltu"
742 [(set (match_operand:SI 0 "intreg_operand" "")
743 (ltu:SI (match_dup 1) (const_int 0)))]
748 if (gen_v9_scc (LTU, operands))
751 operands[1] = gen_compare_reg (LTU, sparc_compare_op0, sparc_compare_op1);
754 (define_expand "sgeu"
755 [(set (match_operand:SI 0 "intreg_operand" "")
756 (geu:SI (match_dup 1) (const_int 0)))]
761 if (gen_v9_scc (GEU, operands))
764 operands[1] = gen_compare_reg (GEU, sparc_compare_op0, sparc_compare_op1);
767 (define_expand "sleu"
768 [(set (match_operand:SI 0 "intreg_operand" "")
769 (leu:SI (match_dup 1) (const_int 0)))]
776 /* We can do geu easily, so if both operands are registers, swap them and
778 if ((GET_CODE (sparc_compare_op0) == REG
779 || GET_CODE (sparc_compare_op0) == SUBREG)
780 && (GET_CODE (sparc_compare_op1) == REG
781 || GET_CODE (sparc_compare_op1) == SUBREG))
783 tem = sparc_compare_op0;
784 sparc_compare_op0 = sparc_compare_op1;
785 sparc_compare_op1 = tem;
786 pat = gen_sgeu (operands[0]);
795 if (gen_v9_scc (LEU, operands))
801 ;; Now the DEFINE_INSNs for the scc cases.
803 ;; The SEQ and SNE patterns are special because they can be done
804 ;; without any branching and do not involve a COMPARE. We want
805 ;; them to always use the splitz below so the results can be
808 (define_insn_and_split "*snesi_zero"
809 [(set (match_operand:SI 0 "register_operand" "=r")
810 (ne:SI (match_operand:SI 1 "register_operand" "r")
812 (clobber (reg:CC 100))]
816 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
818 (set (match_dup 0) (ltu:SI (reg:CC 100) (const_int 0)))]
820 [(set_attr "length" "2")])
822 (define_insn_and_split "*neg_snesi_zero"
823 [(set (match_operand:SI 0 "register_operand" "=r")
824 (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
826 (clobber (reg:CC 100))]
830 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
832 (set (match_dup 0) (neg:SI (ltu:SI (reg:CC 100) (const_int 0))))]
834 [(set_attr "length" "2")])
836 (define_insn_and_split "*snesi_zero_extend"
837 [(set (match_operand:DI 0 "register_operand" "=r")
838 (ne:DI (match_operand:SI 1 "register_operand" "r")
840 (clobber (reg:CC 100))]
844 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (minus:SI (const_int 0)
847 (set (match_dup 0) (zero_extend:DI (plus:SI (plus:SI (const_int 0)
849 (ltu:SI (reg:CC_NOOV 100)
852 [(set_attr "length" "2")])
854 (define_insn_and_split "*snedi_zero"
855 [(set (match_operand:DI 0 "register_operand" "=&r")
856 (ne:DI (match_operand:DI 1 "register_operand" "r")
860 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
861 [(set (match_dup 0) (const_int 0))
862 (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
867 [(set_attr "length" "2")])
869 (define_insn_and_split "*neg_snedi_zero"
870 [(set (match_operand:DI 0 "register_operand" "=&r")
871 (neg:DI (ne:DI (match_operand:DI 1 "register_operand" "r")
875 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
876 [(set (match_dup 0) (const_int 0))
877 (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
882 [(set_attr "length" "2")])
884 (define_insn_and_split "*snedi_zero_trunc"
885 [(set (match_operand:SI 0 "register_operand" "=&r")
886 (ne:SI (match_operand:DI 1 "register_operand" "r")
890 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
891 [(set (match_dup 0) (const_int 0))
892 (set (match_dup 0) (if_then_else:SI (ne:DI (match_dup 1)
897 [(set_attr "length" "2")])
899 (define_insn_and_split "*seqsi_zero"
900 [(set (match_operand:SI 0 "register_operand" "=r")
901 (eq:SI (match_operand:SI 1 "register_operand" "r")
903 (clobber (reg:CC 100))]
907 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
909 (set (match_dup 0) (geu:SI (reg:CC 100) (const_int 0)))]
911 [(set_attr "length" "2")])
913 (define_insn_and_split "*neg_seqsi_zero"
914 [(set (match_operand:SI 0 "register_operand" "=r")
915 (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
917 (clobber (reg:CC 100))]
921 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
923 (set (match_dup 0) (neg:SI (geu:SI (reg:CC 100) (const_int 0))))]
925 [(set_attr "length" "2")])
927 (define_insn_and_split "*seqsi_zero_extend"
928 [(set (match_operand:DI 0 "register_operand" "=r")
929 (eq:DI (match_operand:SI 1 "register_operand" "r")
931 (clobber (reg:CC 100))]
935 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (minus:SI (const_int 0)
938 (set (match_dup 0) (zero_extend:DI (minus:SI (minus:SI (const_int 0)
940 (ltu:SI (reg:CC_NOOV 100)
943 [(set_attr "length" "2")])
945 (define_insn_and_split "*seqdi_zero"
946 [(set (match_operand:DI 0 "register_operand" "=&r")
947 (eq:DI (match_operand:DI 1 "register_operand" "r")
951 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
952 [(set (match_dup 0) (const_int 0))
953 (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
958 [(set_attr "length" "2")])
960 (define_insn_and_split "*neg_seqdi_zero"
961 [(set (match_operand:DI 0 "register_operand" "=&r")
962 (neg:DI (eq:DI (match_operand:DI 1 "register_operand" "r")
966 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
967 [(set (match_dup 0) (const_int 0))
968 (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
973 [(set_attr "length" "2")])
975 (define_insn_and_split "*seqdi_zero_trunc"
976 [(set (match_operand:SI 0 "register_operand" "=&r")
977 (eq:SI (match_operand:DI 1 "register_operand" "r")
981 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
982 [(set (match_dup 0) (const_int 0))
983 (set (match_dup 0) (if_then_else:SI (eq:DI (match_dup 1)
988 [(set_attr "length" "2")])
990 ;; We can also do (x + (i == 0)) and related, so put them in.
991 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
994 (define_insn_and_split "*x_plus_i_ne_0"
995 [(set (match_operand:SI 0 "register_operand" "=r")
996 (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
998 (match_operand:SI 2 "register_operand" "r")))
999 (clobber (reg:CC 100))]
1003 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1005 (set (match_dup 0) (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1008 [(set_attr "length" "2")])
1010 (define_insn_and_split "*x_minus_i_ne_0"
1011 [(set (match_operand:SI 0 "register_operand" "=r")
1012 (minus:SI (match_operand:SI 2 "register_operand" "r")
1013 (ne:SI (match_operand:SI 1 "register_operand" "r")
1015 (clobber (reg:CC 100))]
1019 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1021 (set (match_dup 0) (minus:SI (match_dup 2)
1022 (ltu:SI (reg:CC 100) (const_int 0))))]
1024 [(set_attr "length" "2")])
1026 (define_insn_and_split "*x_plus_i_eq_0"
1027 [(set (match_operand:SI 0 "register_operand" "=r")
1028 (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
1030 (match_operand:SI 2 "register_operand" "r")))
1031 (clobber (reg:CC 100))]
1035 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1037 (set (match_dup 0) (plus:SI (geu:SI (reg:CC 100) (const_int 0))
1040 [(set_attr "length" "2")])
1042 (define_insn_and_split "*x_minus_i_eq_0"
1043 [(set (match_operand:SI 0 "register_operand" "=r")
1044 (minus:SI (match_operand:SI 2 "register_operand" "r")
1045 (eq:SI (match_operand:SI 1 "register_operand" "r")
1047 (clobber (reg:CC 100))]
1051 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1053 (set (match_dup 0) (minus:SI (match_dup 2)
1054 (geu:SI (reg:CC 100) (const_int 0))))]
1056 [(set_attr "length" "2")])
1058 ;; We can also do GEU and LTU directly, but these operate after a compare.
1059 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1062 (define_insn "*sltu_insn"
1063 [(set (match_operand:SI 0 "register_operand" "=r")
1064 (ltu:SI (reg:CC 100) (const_int 0)))]
1067 [(set_attr "type" "ialuX")])
1069 (define_insn "*neg_sltu_insn"
1070 [(set (match_operand:SI 0 "register_operand" "=r")
1071 (neg:SI (ltu:SI (reg:CC 100) (const_int 0))))]
1074 [(set_attr "type" "ialuX")])
1076 ;; ??? Combine should canonicalize these next two to the same pattern.
1077 (define_insn "*neg_sltu_minus_x"
1078 [(set (match_operand:SI 0 "register_operand" "=r")
1079 (minus:SI (neg:SI (ltu:SI (reg:CC 100) (const_int 0)))
1080 (match_operand:SI 1 "arith_operand" "rI")))]
1082 "subx\t%%g0, %1, %0"
1083 [(set_attr "type" "ialuX")])
1085 (define_insn "*neg_sltu_plus_x"
1086 [(set (match_operand:SI 0 "register_operand" "=r")
1087 (neg:SI (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1088 (match_operand:SI 1 "arith_operand" "rI"))))]
1090 "subx\t%%g0, %1, %0"
1091 [(set_attr "type" "ialuX")])
1093 (define_insn "*sgeu_insn"
1094 [(set (match_operand:SI 0 "register_operand" "=r")
1095 (geu:SI (reg:CC 100) (const_int 0)))]
1097 "subx\t%%g0, -1, %0"
1098 [(set_attr "type" "ialuX")])
1100 (define_insn "*neg_sgeu_insn"
1101 [(set (match_operand:SI 0 "register_operand" "=r")
1102 (neg:SI (geu:SI (reg:CC 100) (const_int 0))))]
1104 "addx\t%%g0, -1, %0"
1105 [(set_attr "type" "ialuX")])
1107 ;; We can also do (x + ((unsigned) i >= 0)) and related, so put them in.
1108 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1111 (define_insn "*sltu_plus_x"
1112 [(set (match_operand:SI 0 "register_operand" "=r")
1113 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1114 (match_operand:SI 1 "arith_operand" "rI")))]
1116 "addx\t%%g0, %1, %0"
1117 [(set_attr "type" "ialuX")])
1119 (define_insn "*sltu_plus_x_plus_y"
1120 [(set (match_operand:SI 0 "register_operand" "=r")
1121 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1122 (plus:SI (match_operand:SI 1 "arith_operand" "%r")
1123 (match_operand:SI 2 "arith_operand" "rI"))))]
1126 [(set_attr "type" "ialuX")])
1128 (define_insn "*x_minus_sltu"
1129 [(set (match_operand:SI 0 "register_operand" "=r")
1130 (minus:SI (match_operand:SI 1 "register_operand" "r")
1131 (ltu:SI (reg:CC 100) (const_int 0))))]
1134 [(set_attr "type" "ialuX")])
1136 ;; ??? Combine should canonicalize these next two to the same pattern.
1137 (define_insn "*x_minus_y_minus_sltu"
1138 [(set (match_operand:SI 0 "register_operand" "=r")
1139 (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
1140 (match_operand:SI 2 "arith_operand" "rI"))
1141 (ltu:SI (reg:CC 100) (const_int 0))))]
1144 [(set_attr "type" "ialuX")])
1146 (define_insn "*x_minus_sltu_plus_y"
1147 [(set (match_operand:SI 0 "register_operand" "=r")
1148 (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
1149 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1150 (match_operand:SI 2 "arith_operand" "rI"))))]
1153 [(set_attr "type" "ialuX")])
1155 (define_insn "*sgeu_plus_x"
1156 [(set (match_operand:SI 0 "register_operand" "=r")
1157 (plus:SI (geu:SI (reg:CC 100) (const_int 0))
1158 (match_operand:SI 1 "register_operand" "r")))]
1161 [(set_attr "type" "ialuX")])
1163 (define_insn "*x_minus_sgeu"
1164 [(set (match_operand:SI 0 "register_operand" "=r")
1165 (minus:SI (match_operand:SI 1 "register_operand" "r")
1166 (geu:SI (reg:CC 100) (const_int 0))))]
1169 [(set_attr "type" "ialuX")])
1172 [(set (match_operand:SI 0 "register_operand" "")
1173 (match_operator:SI 2 "noov_compare_op"
1174 [(match_operand 1 "icc_or_fcc_reg_operand" "")
1176 ;; 32 bit LTU/GEU are better implemented using addx/subx
1177 "TARGET_V9 && REGNO (operands[1]) == SPARC_ICC_REG
1178 && (GET_MODE (operands[1]) == CCXmode
1179 || (GET_CODE (operands[2]) != LTU && GET_CODE (operands[2]) != GEU))"
1180 [(set (match_dup 0) (const_int 0))
1182 (if_then_else:SI (match_op_dup:SI 2 [(match_dup 1) (const_int 0)])
1188 ;; These control RTL generation for conditional jump insns
1190 ;; The quad-word fp compare library routines all return nonzero to indicate
1191 ;; true, which is different from the equivalent libgcc routines, so we must
1192 ;; handle them specially here.
1194 (define_expand "beq"
1196 (if_then_else (eq (match_dup 1) (const_int 0))
1197 (label_ref (match_operand 0 "" ""))
1201 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1202 && GET_CODE (sparc_compare_op0) == REG
1203 && GET_MODE (sparc_compare_op0) == DImode)
1205 emit_v9_brxx_insn (EQ, sparc_compare_op0, operands[0]);
1208 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1210 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, EQ);
1211 emit_jump_insn (gen_bne (operands[0]));
1214 operands[1] = gen_compare_reg (EQ, sparc_compare_op0, sparc_compare_op1);
1217 (define_expand "bne"
1219 (if_then_else (ne (match_dup 1) (const_int 0))
1220 (label_ref (match_operand 0 "" ""))
1224 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1225 && GET_CODE (sparc_compare_op0) == REG
1226 && GET_MODE (sparc_compare_op0) == DImode)
1228 emit_v9_brxx_insn (NE, sparc_compare_op0, operands[0]);
1231 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1233 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, NE);
1234 emit_jump_insn (gen_bne (operands[0]));
1237 operands[1] = gen_compare_reg (NE, sparc_compare_op0, sparc_compare_op1);
1240 (define_expand "bgt"
1242 (if_then_else (gt (match_dup 1) (const_int 0))
1243 (label_ref (match_operand 0 "" ""))
1247 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1248 && GET_CODE (sparc_compare_op0) == REG
1249 && GET_MODE (sparc_compare_op0) == DImode)
1251 emit_v9_brxx_insn (GT, sparc_compare_op0, operands[0]);
1254 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1256 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GT);
1257 emit_jump_insn (gen_bne (operands[0]));
1260 operands[1] = gen_compare_reg (GT, sparc_compare_op0, sparc_compare_op1);
1263 (define_expand "bgtu"
1265 (if_then_else (gtu (match_dup 1) (const_int 0))
1266 (label_ref (match_operand 0 "" ""))
1270 operands[1] = gen_compare_reg (GTU, sparc_compare_op0, sparc_compare_op1);
1273 (define_expand "blt"
1275 (if_then_else (lt (match_dup 1) (const_int 0))
1276 (label_ref (match_operand 0 "" ""))
1280 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1281 && GET_CODE (sparc_compare_op0) == REG
1282 && GET_MODE (sparc_compare_op0) == DImode)
1284 emit_v9_brxx_insn (LT, sparc_compare_op0, operands[0]);
1287 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1289 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LT);
1290 emit_jump_insn (gen_bne (operands[0]));
1293 operands[1] = gen_compare_reg (LT, sparc_compare_op0, sparc_compare_op1);
1296 (define_expand "bltu"
1298 (if_then_else (ltu (match_dup 1) (const_int 0))
1299 (label_ref (match_operand 0 "" ""))
1303 operands[1] = gen_compare_reg (LTU, sparc_compare_op0, sparc_compare_op1);
1306 (define_expand "bge"
1308 (if_then_else (ge (match_dup 1) (const_int 0))
1309 (label_ref (match_operand 0 "" ""))
1313 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1314 && GET_CODE (sparc_compare_op0) == REG
1315 && GET_MODE (sparc_compare_op0) == DImode)
1317 emit_v9_brxx_insn (GE, sparc_compare_op0, operands[0]);
1320 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1322 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GE);
1323 emit_jump_insn (gen_bne (operands[0]));
1326 operands[1] = gen_compare_reg (GE, sparc_compare_op0, sparc_compare_op1);
1329 (define_expand "bgeu"
1331 (if_then_else (geu (match_dup 1) (const_int 0))
1332 (label_ref (match_operand 0 "" ""))
1336 operands[1] = gen_compare_reg (GEU, sparc_compare_op0, sparc_compare_op1);
1339 (define_expand "ble"
1341 (if_then_else (le (match_dup 1) (const_int 0))
1342 (label_ref (match_operand 0 "" ""))
1346 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1347 && GET_CODE (sparc_compare_op0) == REG
1348 && GET_MODE (sparc_compare_op0) == DImode)
1350 emit_v9_brxx_insn (LE, sparc_compare_op0, operands[0]);
1353 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1355 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LE);
1356 emit_jump_insn (gen_bne (operands[0]));
1359 operands[1] = gen_compare_reg (LE, sparc_compare_op0, sparc_compare_op1);
1362 (define_expand "bleu"
1364 (if_then_else (leu (match_dup 1) (const_int 0))
1365 (label_ref (match_operand 0 "" ""))
1369 operands[1] = gen_compare_reg (LEU, sparc_compare_op0, sparc_compare_op1);
1372 (define_expand "bunordered"
1374 (if_then_else (unordered (match_dup 1) (const_int 0))
1375 (label_ref (match_operand 0 "" ""))
1379 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1381 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1,
1383 emit_jump_insn (gen_beq (operands[0]));
1386 operands[1] = gen_compare_reg (UNORDERED, sparc_compare_op0,
1390 (define_expand "bordered"
1392 (if_then_else (ordered (match_dup 1) (const_int 0))
1393 (label_ref (match_operand 0 "" ""))
1397 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1399 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, ORDERED);
1400 emit_jump_insn (gen_bne (operands[0]));
1403 operands[1] = gen_compare_reg (ORDERED, sparc_compare_op0,
1407 (define_expand "bungt"
1409 (if_then_else (ungt (match_dup 1) (const_int 0))
1410 (label_ref (match_operand 0 "" ""))
1414 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1416 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNGT);
1417 emit_jump_insn (gen_bgt (operands[0]));
1420 operands[1] = gen_compare_reg (UNGT, sparc_compare_op0, sparc_compare_op1);
1423 (define_expand "bunlt"
1425 (if_then_else (unlt (match_dup 1) (const_int 0))
1426 (label_ref (match_operand 0 "" ""))
1430 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1432 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNLT);
1433 emit_jump_insn (gen_bne (operands[0]));
1436 operands[1] = gen_compare_reg (UNLT, sparc_compare_op0, sparc_compare_op1);
1439 (define_expand "buneq"
1441 (if_then_else (uneq (match_dup 1) (const_int 0))
1442 (label_ref (match_operand 0 "" ""))
1446 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1448 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNEQ);
1449 emit_jump_insn (gen_beq (operands[0]));
1452 operands[1] = gen_compare_reg (UNEQ, sparc_compare_op0, sparc_compare_op1);
1455 (define_expand "bunge"
1457 (if_then_else (unge (match_dup 1) (const_int 0))
1458 (label_ref (match_operand 0 "" ""))
1462 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1464 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNGE);
1465 emit_jump_insn (gen_bne (operands[0]));
1468 operands[1] = gen_compare_reg (UNGE, sparc_compare_op0, sparc_compare_op1);
1471 (define_expand "bunle"
1473 (if_then_else (unle (match_dup 1) (const_int 0))
1474 (label_ref (match_operand 0 "" ""))
1478 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1480 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNLE);
1481 emit_jump_insn (gen_bne (operands[0]));
1484 operands[1] = gen_compare_reg (UNLE, sparc_compare_op0, sparc_compare_op1);
1487 (define_expand "bltgt"
1489 (if_then_else (ltgt (match_dup 1) (const_int 0))
1490 (label_ref (match_operand 0 "" ""))
1494 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1496 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LTGT);
1497 emit_jump_insn (gen_bne (operands[0]));
1500 operands[1] = gen_compare_reg (LTGT, sparc_compare_op0, sparc_compare_op1);
1503 ;; Now match both normal and inverted jump.
1505 ;; XXX fpcmp nop braindamage
1506 (define_insn "*normal_branch"
1508 (if_then_else (match_operator 0 "noov_compare_op"
1509 [(reg 100) (const_int 0)])
1510 (label_ref (match_operand 1 "" ""))
1514 return output_cbranch (operands[0], operands[1], 1, 0,
1515 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1516 ! final_sequence, insn);
1518 [(set_attr "type" "branch")
1519 (set_attr "branch_type" "icc")])
1521 ;; XXX fpcmp nop braindamage
1522 (define_insn "*inverted_branch"
1524 (if_then_else (match_operator 0 "noov_compare_op"
1525 [(reg 100) (const_int 0)])
1527 (label_ref (match_operand 1 "" ""))))]
1530 return output_cbranch (operands[0], operands[1], 1, 1,
1531 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1532 ! final_sequence, insn);
1534 [(set_attr "type" "branch")
1535 (set_attr "branch_type" "icc")])
1537 ;; XXX fpcmp nop braindamage
1538 (define_insn "*normal_fp_branch"
1540 (if_then_else (match_operator 1 "comparison_operator"
1541 [(match_operand:CCFP 0 "fcc_reg_operand" "c")
1543 (label_ref (match_operand 2 "" ""))
1547 return output_cbranch (operands[1], operands[2], 2, 0,
1548 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1549 ! final_sequence, insn);
1551 [(set_attr "type" "branch")
1552 (set_attr "branch_type" "fcc")])
1554 ;; XXX fpcmp nop braindamage
1555 (define_insn "*inverted_fp_branch"
1557 (if_then_else (match_operator 1 "comparison_operator"
1558 [(match_operand:CCFP 0 "fcc_reg_operand" "c")
1561 (label_ref (match_operand 2 "" ""))))]
1564 return output_cbranch (operands[1], operands[2], 2, 1,
1565 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1566 ! final_sequence, insn);
1568 [(set_attr "type" "branch")
1569 (set_attr "branch_type" "fcc")])
1571 ;; XXX fpcmp nop braindamage
1572 (define_insn "*normal_fpe_branch"
1574 (if_then_else (match_operator 1 "comparison_operator"
1575 [(match_operand:CCFPE 0 "fcc_reg_operand" "c")
1577 (label_ref (match_operand 2 "" ""))
1581 return output_cbranch (operands[1], operands[2], 2, 0,
1582 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1583 ! final_sequence, insn);
1585 [(set_attr "type" "branch")
1586 (set_attr "branch_type" "fcc")])
1588 ;; XXX fpcmp nop braindamage
1589 (define_insn "*inverted_fpe_branch"
1591 (if_then_else (match_operator 1 "comparison_operator"
1592 [(match_operand:CCFPE 0 "fcc_reg_operand" "c")
1595 (label_ref (match_operand 2 "" ""))))]
1598 return output_cbranch (operands[1], operands[2], 2, 1,
1599 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1600 ! final_sequence, insn);
1602 [(set_attr "type" "branch")
1603 (set_attr "branch_type" "fcc")])
1605 ;; SPARC V9-specific jump insns. None of these are guaranteed to be
1606 ;; in the architecture.
1608 ;; There are no 32 bit brreg insns.
1611 (define_insn "*normal_int_branch_sp64"
1613 (if_then_else (match_operator 0 "v9_regcmp_op"
1614 [(match_operand:DI 1 "register_operand" "r")
1616 (label_ref (match_operand 2 "" ""))
1620 return output_v9branch (operands[0], operands[2], 1, 2, 0,
1621 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1622 ! final_sequence, insn);
1624 [(set_attr "type" "branch")
1625 (set_attr "branch_type" "reg")])
1628 (define_insn "*inverted_int_branch_sp64"
1630 (if_then_else (match_operator 0 "v9_regcmp_op"
1631 [(match_operand:DI 1 "register_operand" "r")
1634 (label_ref (match_operand 2 "" ""))))]
1637 return output_v9branch (operands[0], operands[2], 1, 2, 1,
1638 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1639 ! final_sequence, insn);
1641 [(set_attr "type" "branch")
1642 (set_attr "branch_type" "reg")])
1644 ;; Load program counter insns.
1646 (define_insn "get_pc"
1647 [(clobber (reg:SI 15))
1648 (set (match_operand 0 "register_operand" "=r")
1649 (unspec [(match_operand 1 "" "") (match_operand 2 "" "")] UNSPEC_GET_PC))]
1650 "flag_pic && REGNO (operands[0]) == 23"
1651 "sethi\t%%hi(%a1-4), %0\n\tcall\t%a2\n\tadd\t%0, %%lo(%a1+4), %0"
1652 [(set_attr "type" "multi")
1653 (set_attr "length" "3")])
1656 ;; Move instructions
1658 (define_expand "movqi"
1659 [(set (match_operand:QI 0 "general_operand" "")
1660 (match_operand:QI 1 "general_operand" ""))]
1663 /* Working with CONST_INTs is easier, so convert
1664 a double if needed. */
1665 if (GET_CODE (operands[1]) == CONST_DOUBLE)
1667 operands[1] = GEN_INT (trunc_int_for_mode
1668 (CONST_DOUBLE_LOW (operands[1]), QImode));
1671 /* Handle sets of MEM first. */
1672 if (GET_CODE (operands[0]) == MEM)
1674 if (reg_or_0_operand (operands[1], QImode))
1677 if (! reload_in_progress)
1679 operands[0] = validize_mem (operands[0]);
1680 operands[1] = force_reg (QImode, operands[1]);
1684 /* Fixup PIC cases. */
1687 if (CONSTANT_P (operands[1])
1688 && pic_address_needs_scratch (operands[1]))
1689 operands[1] = legitimize_pic_address (operands[1], QImode, 0);
1691 if (symbolic_operand (operands[1], QImode))
1693 operands[1] = legitimize_pic_address (operands[1],
1695 (reload_in_progress ?
1702 /* All QI constants require only one insn, so proceed. */
1708 (define_insn "*movqi_insn"
1709 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m")
1710 (match_operand:QI 1 "input_operand" "rI,m,rJ"))]
1711 "(register_operand (operands[0], QImode)
1712 || reg_or_0_operand (operands[1], QImode))"
1717 [(set_attr "type" "*,load,store")
1718 (set_attr "us3load_type" "*,3cycle,*")])
1720 (define_expand "movhi"
1721 [(set (match_operand:HI 0 "general_operand" "")
1722 (match_operand:HI 1 "general_operand" ""))]
1725 /* Working with CONST_INTs is easier, so convert
1726 a double if needed. */
1727 if (GET_CODE (operands[1]) == CONST_DOUBLE)
1728 operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
1730 /* Handle sets of MEM first. */
1731 if (GET_CODE (operands[0]) == MEM)
1733 if (reg_or_0_operand (operands[1], HImode))
1736 if (! reload_in_progress)
1738 operands[0] = validize_mem (operands[0]);
1739 operands[1] = force_reg (HImode, operands[1]);
1743 /* Fixup PIC cases. */
1746 if (CONSTANT_P (operands[1])
1747 && pic_address_needs_scratch (operands[1]))
1748 operands[1] = legitimize_pic_address (operands[1], HImode, 0);
1750 if (symbolic_operand (operands[1], HImode))
1752 operands[1] = legitimize_pic_address (operands[1],
1754 (reload_in_progress ?
1761 /* This makes sure we will not get rematched due to splittage. */
1762 if (! CONSTANT_P (operands[1]) || input_operand (operands[1], HImode))
1764 else if (CONSTANT_P (operands[1])
1765 && GET_CODE (operands[1]) != HIGH
1766 && GET_CODE (operands[1]) != LO_SUM)
1768 sparc_emit_set_const32 (operands[0], operands[1]);
1775 (define_insn "*movhi_const64_special"
1776 [(set (match_operand:HI 0 "register_operand" "=r")
1777 (match_operand:HI 1 "const64_high_operand" ""))]
1779 "sethi\t%%hi(%a1), %0")
1781 (define_insn "*movhi_insn"
1782 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1783 (match_operand:HI 1 "input_operand" "rI,K,m,rJ"))]
1784 "(register_operand (operands[0], HImode)
1785 || reg_or_0_operand (operands[1], HImode))"
1788 sethi\t%%hi(%a1), %0
1791 [(set_attr "type" "*,*,load,store")
1792 (set_attr "us3load_type" "*,*,3cycle,*")])
1794 ;; We always work with constants here.
1795 (define_insn "*movhi_lo_sum"
1796 [(set (match_operand:HI 0 "register_operand" "=r")
1797 (ior:HI (match_operand:HI 1 "arith_operand" "%r")
1798 (match_operand:HI 2 "arith_operand" "I")))]
1802 (define_expand "movsi"
1803 [(set (match_operand:SI 0 "general_operand" "")
1804 (match_operand:SI 1 "general_operand" ""))]
1807 /* Working with CONST_INTs is easier, so convert
1808 a double if needed. */
1809 if (GET_CODE (operands[1]) == CONST_DOUBLE)
1810 operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
1812 /* Handle sets of MEM first. */
1813 if (GET_CODE (operands[0]) == MEM)
1815 if (reg_or_0_operand (operands[1], SImode))
1818 if (! reload_in_progress)
1820 operands[0] = validize_mem (operands[0]);
1821 operands[1] = force_reg (SImode, operands[1]);
1825 /* Fixup PIC cases. */
1828 if (CONSTANT_P (operands[1])
1829 && pic_address_needs_scratch (operands[1]))
1830 operands[1] = legitimize_pic_address (operands[1], SImode, 0);
1832 if (GET_CODE (operands[1]) == LABEL_REF)
1835 emit_insn (gen_movsi_pic_label_ref (operands[0], operands[1]));
1839 if (symbolic_operand (operands[1], SImode))
1841 operands[1] = legitimize_pic_address (operands[1],
1843 (reload_in_progress ?
1850 /* If we are trying to toss an integer constant into the
1851 FPU registers, force it into memory. */
1852 if (GET_CODE (operands[0]) == REG
1853 && REGNO (operands[0]) >= SPARC_FIRST_FP_REG
1854 && REGNO (operands[0]) <= SPARC_LAST_V9_FP_REG
1855 && CONSTANT_P (operands[1]))
1856 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
1859 /* This makes sure we will not get rematched due to splittage. */
1860 if (! CONSTANT_P (operands[1]) || input_operand (operands[1], SImode))
1862 else if (CONSTANT_P (operands[1])
1863 && GET_CODE (operands[1]) != HIGH
1864 && GET_CODE (operands[1]) != LO_SUM)
1866 sparc_emit_set_const32 (operands[0], operands[1]);
1873 ;; This is needed to show CSE exactly which bits are set
1874 ;; in a 64-bit register by sethi instructions.
1875 (define_insn "*movsi_const64_special"
1876 [(set (match_operand:SI 0 "register_operand" "=r")
1877 (match_operand:SI 1 "const64_high_operand" ""))]
1879 "sethi\t%%hi(%a1), %0")
1881 (define_insn "*movsi_insn"
1882 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,f,r,r,r,f,m,m,d")
1883 (match_operand:SI 1 "input_operand" "rI,!f,K,J,m,!m,rJ,!f,J"))]
1884 "(register_operand (operands[0], SImode)
1885 || reg_or_0_operand (operands[1], SImode))"
1889 sethi\t%%hi(%a1), %0
1896 [(set_attr "type" "*,fpmove,*,*,load,fpload,store,fpstore,fpmove")])
1898 (define_insn "*movsi_lo_sum"
1899 [(set (match_operand:SI 0 "register_operand" "=r")
1900 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1901 (match_operand:SI 2 "immediate_operand" "in")))]
1903 "or\t%1, %%lo(%a2), %0")
1905 (define_insn "*movsi_high"
1906 [(set (match_operand:SI 0 "register_operand" "=r")
1907 (high:SI (match_operand:SI 1 "immediate_operand" "in")))]
1909 "sethi\t%%hi(%a1), %0")
1911 ;; The next two patterns must wrap the SYMBOL_REF in an UNSPEC
1912 ;; so that CSE won't optimize the address computation away.
1913 (define_insn "movsi_lo_sum_pic"
1914 [(set (match_operand:SI 0 "register_operand" "=r")
1915 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1916 (unspec:SI [(match_operand:SI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
1918 "or\t%1, %%lo(%a2), %0")
1920 (define_insn "movsi_high_pic"
1921 [(set (match_operand:SI 0 "register_operand" "=r")
1922 (high:SI (unspec:SI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
1923 "flag_pic && check_pic (1)"
1924 "sethi\t%%hi(%a1), %0")
1926 (define_expand "movsi_pic_label_ref"
1927 [(set (match_dup 3) (high:SI
1928 (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
1929 (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1930 (set (match_dup 4) (lo_sum:SI (match_dup 3)
1931 (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1932 (set (match_operand:SI 0 "register_operand" "=r")
1933 (minus:SI (match_dup 5) (match_dup 4)))]
1936 current_function_uses_pic_offset_table = 1;
1937 operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
1940 operands[3] = operands[0];
1941 operands[4] = operands[0];
1945 operands[3] = gen_reg_rtx (SImode);
1946 operands[4] = gen_reg_rtx (SImode);
1948 operands[5] = pic_offset_table_rtx;
1951 (define_insn "*movsi_high_pic_label_ref"
1952 [(set (match_operand:SI 0 "register_operand" "=r")
1954 (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
1955 (match_operand:SI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1957 "sethi\t%%hi(%a2-(%a1-.)), %0")
1959 (define_insn "*movsi_lo_sum_pic_label_ref"
1960 [(set (match_operand:SI 0 "register_operand" "=r")
1961 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1962 (unspec:SI [(match_operand:SI 2 "label_ref_operand" "")
1963 (match_operand:SI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1965 "or\t%1, %%lo(%a3-(%a2-.)), %0")
1967 (define_expand "movdi"
1968 [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand" "")
1969 (match_operand:DI 1 "general_operand" ""))]
1972 /* Where possible, convert CONST_DOUBLE into a CONST_INT. */
1973 if (GET_CODE (operands[1]) == CONST_DOUBLE
1974 #if HOST_BITS_PER_WIDE_INT == 32
1975 && ((CONST_DOUBLE_HIGH (operands[1]) == 0
1976 && (CONST_DOUBLE_LOW (operands[1]) & 0x80000000) == 0)
1977 || (CONST_DOUBLE_HIGH (operands[1]) == (HOST_WIDE_INT) 0xffffffff
1978 && (CONST_DOUBLE_LOW (operands[1]) & 0x80000000) != 0))
1981 operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
1983 /* Handle MEM cases first. */
1984 if (GET_CODE (operands[0]) == MEM)
1986 /* If it's a REG, we can always do it.
1987 The const zero case is more complex, on v9
1988 we can always perform it. */
1989 if (register_operand (operands[1], DImode)
1991 && (operands[1] == const0_rtx)))
1994 if (! reload_in_progress)
1996 operands[0] = validize_mem (operands[0]);
1997 operands[1] = force_reg (DImode, operands[1]);
2003 if (CONSTANT_P (operands[1])
2004 && pic_address_needs_scratch (operands[1]))
2005 operands[1] = legitimize_pic_address (operands[1], DImode, 0);
2007 if (GET_CODE (operands[1]) == LABEL_REF)
2009 if (! TARGET_ARCH64)
2011 emit_insn (gen_movdi_pic_label_ref (operands[0], operands[1]));
2015 if (symbolic_operand (operands[1], DImode))
2017 operands[1] = legitimize_pic_address (operands[1],
2019 (reload_in_progress ?
2026 /* If we are trying to toss an integer constant into the
2027 FPU registers, force it into memory. */
2028 if (GET_CODE (operands[0]) == REG
2029 && REGNO (operands[0]) >= SPARC_FIRST_FP_REG
2030 && REGNO (operands[0]) <= SPARC_LAST_V9_FP_REG
2031 && CONSTANT_P (operands[1]))
2032 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
2035 /* This makes sure we will not get rematched due to splittage. */
2036 if (! CONSTANT_P (operands[1]) || input_operand (operands[1], DImode))
2038 else if (TARGET_ARCH64
2039 && CONSTANT_P (operands[1])
2040 && GET_CODE (operands[1]) != HIGH
2041 && GET_CODE (operands[1]) != LO_SUM)
2043 sparc_emit_set_const64 (operands[0], operands[1]);
2051 ;; Be careful, fmovd does not exist when !v9.
2052 ;; We match MEM moves directly when we have correct even
2053 ;; numbered registers, but fall into splits otherwise.
2054 ;; The constraint ordering here is really important to
2055 ;; avoid insane problems in reload, especially for patterns
2058 ;; (set (mem:DI (plus:SI (reg:SI 30 %fp)
2059 ;; (const_int -5016)))
2063 (define_insn "*movdi_insn_sp32_v9"
2064 [(set (match_operand:DI 0 "nonimmediate_operand"
2065 "=T,o,T,U,o,r,r,r,?T,?f,?f,?o,?f,?e,?e,?W")
2066 (match_operand:DI 1 "input_operand"
2067 " J,J,U,T,r,o,i,r, f, T, o, f, f, e, W, e"))]
2068 "! TARGET_ARCH64 && TARGET_V9
2069 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2087 [(set_attr "type" "store,store,store,load,*,*,*,*,fpstore,fpload,*,*,*,fpmove,fpload,fpstore")
2088 (set_attr "length" "*,2,*,*,2,2,2,2,*,*,2,2,2,*,*,*")
2089 (set_attr "fptype" "*,*,*,*,*,*,*,*,*,*,*,*,*,double,*,*")])
2091 (define_insn "*movdi_insn_sp32"
2092 [(set (match_operand:DI 0 "nonimmediate_operand"
2093 "=o,T,U,o,r,r,r,?T,?f,?f,?o,?f")
2094 (match_operand:DI 1 "input_operand"
2095 " J,U,T,r,o,i,r, f, T, o, f, f"))]
2097 && (register_operand (operands[0], DImode)
2098 || register_operand (operands[1], DImode))"
2112 [(set_attr "type" "store,store,load,*,*,*,*,fpstore,fpload,*,*,*")
2113 (set_attr "length" "2,*,*,2,2,2,2,*,*,2,2,2")])
2115 ;; The following are generated by sparc_emit_set_const64
2116 (define_insn "*movdi_sp64_dbl"
2117 [(set (match_operand:DI 0 "register_operand" "=r")
2118 (match_operand:DI 1 "const64_operand" ""))]
2120 && HOST_BITS_PER_WIDE_INT != 64)"
2123 ;; This is needed to show CSE exactly which bits are set
2124 ;; in a 64-bit register by sethi instructions.
2125 (define_insn "*movdi_const64_special"
2126 [(set (match_operand:DI 0 "register_operand" "=r")
2127 (match_operand:DI 1 "const64_high_operand" ""))]
2129 "sethi\t%%hi(%a1), %0")
2131 (define_insn "*movdi_insn_sp64_novis"
2132 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,m,?e,?e,?W")
2133 (match_operand:DI 1 "input_operand" "rI,N,J,m,rJ,e,W,e"))]
2134 "TARGET_ARCH64 && ! TARGET_VIS
2135 && (register_operand (operands[0], DImode)
2136 || reg_or_0_operand (operands[1], DImode))"
2139 sethi\t%%hi(%a1), %0
2146 [(set_attr "type" "*,*,*,load,store,fpmove,fpload,fpstore")
2147 (set_attr "fptype" "*,*,*,*,*,double,*,*")])
2149 (define_insn "*movdi_insn_sp64_vis"
2150 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,m,?e,?e,?W,b")
2151 (match_operand:DI 1 "input_operand" "rI,N,J,m,rJ,e,W,e,J"))]
2152 "TARGET_ARCH64 && TARGET_VIS &&
2153 (register_operand (operands[0], DImode)
2154 || reg_or_0_operand (operands[1], DImode))"
2157 sethi\t%%hi(%a1), %0
2165 [(set_attr "type" "*,*,*,load,store,fpmove,fpload,fpstore,fpmove")
2166 (set_attr "fptype" "*,*,*,*,*,double,*,*,double")])
2168 (define_expand "movdi_pic_label_ref"
2169 [(set (match_dup 3) (high:DI
2170 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
2171 (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
2172 (set (match_dup 4) (lo_sum:DI (match_dup 3)
2173 (unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
2174 (set (match_operand:DI 0 "register_operand" "=r")
2175 (minus:DI (match_dup 5) (match_dup 4)))]
2176 "TARGET_ARCH64 && flag_pic"
2178 current_function_uses_pic_offset_table = 1;
2179 operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
2182 operands[3] = operands[0];
2183 operands[4] = operands[0];
2187 operands[3] = gen_reg_rtx (DImode);
2188 operands[4] = gen_reg_rtx (DImode);
2190 operands[5] = pic_offset_table_rtx;
2193 (define_insn "*movdi_high_pic_label_ref"
2194 [(set (match_operand:DI 0 "register_operand" "=r")
2196 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
2197 (match_operand:DI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
2198 "TARGET_ARCH64 && flag_pic"
2199 "sethi\t%%hi(%a2-(%a1-.)), %0")
2201 (define_insn "*movdi_lo_sum_pic_label_ref"
2202 [(set (match_operand:DI 0 "register_operand" "=r")
2203 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2204 (unspec:DI [(match_operand:DI 2 "label_ref_operand" "")
2205 (match_operand:DI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
2206 "TARGET_ARCH64 && flag_pic"
2207 "or\t%1, %%lo(%a3-(%a2-.)), %0")
2209 ;; SPARC-v9 code model support insns. See sparc_emit_set_symbolic_const64
2210 ;; in sparc.c to see what is going on here... PIC stuff comes first.
2212 (define_insn "movdi_lo_sum_pic"
2213 [(set (match_operand:DI 0 "register_operand" "=r")
2214 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2215 (unspec:DI [(match_operand:DI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
2216 "TARGET_ARCH64 && flag_pic"
2217 "or\t%1, %%lo(%a2), %0")
2219 (define_insn "movdi_high_pic"
2220 [(set (match_operand:DI 0 "register_operand" "=r")
2221 (high:DI (unspec:DI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
2222 "TARGET_ARCH64 && flag_pic && check_pic (1)"
2223 "sethi\t%%hi(%a1), %0")
2225 (define_insn "*sethi_di_medlow_embmedany_pic"
2226 [(set (match_operand:DI 0 "register_operand" "=r")
2227 (high:DI (match_operand:DI 1 "sp64_medium_pic_operand" "")))]
2228 "(TARGET_CM_MEDLOW || TARGET_CM_EMBMEDANY) && check_pic (1)"
2229 "sethi\t%%hi(%a1), %0")
2231 (define_insn "*sethi_di_medlow"
2232 [(set (match_operand:DI 0 "register_operand" "=r")
2233 (high:DI (match_operand:DI 1 "symbolic_operand" "")))]
2234 "TARGET_CM_MEDLOW && check_pic (1)"
2235 "sethi\t%%hi(%a1), %0")
2237 (define_insn "*losum_di_medlow"
2238 [(set (match_operand:DI 0 "register_operand" "=r")
2239 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2240 (match_operand:DI 2 "symbolic_operand" "")))]
2242 "or\t%1, %%lo(%a2), %0")
2244 (define_insn "seth44"
2245 [(set (match_operand:DI 0 "register_operand" "=r")
2246 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETH44)))]
2248 "sethi\t%%h44(%a1), %0")
2250 (define_insn "setm44"
2251 [(set (match_operand:DI 0 "register_operand" "=r")
2252 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2253 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_SETM44)))]
2255 "or\t%1, %%m44(%a2), %0")
2257 (define_insn "setl44"
2258 [(set (match_operand:DI 0 "register_operand" "=r")
2259 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2260 (match_operand:DI 2 "symbolic_operand" "")))]
2262 "or\t%1, %%l44(%a2), %0")
2264 (define_insn "sethh"
2265 [(set (match_operand:DI 0 "register_operand" "=r")
2266 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETHH)))]
2268 "sethi\t%%hh(%a1), %0")
2270 (define_insn "setlm"
2271 [(set (match_operand:DI 0 "register_operand" "=r")
2272 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETLM)))]
2274 "sethi\t%%lm(%a1), %0")
2276 (define_insn "sethm"
2277 [(set (match_operand:DI 0 "register_operand" "=r")
2278 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2279 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_EMB_SETHM)))]
2281 "or\t%1, %%hm(%a2), %0")
2283 (define_insn "setlo"
2284 [(set (match_operand:DI 0 "register_operand" "=r")
2285 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2286 (match_operand:DI 2 "symbolic_operand" "")))]
2288 "or\t%1, %%lo(%a2), %0")
2290 (define_insn "embmedany_sethi"
2291 [(set (match_operand:DI 0 "register_operand" "=r")
2292 (high:DI (unspec:DI [(match_operand:DI 1 "data_segment_operand" "")] UNSPEC_EMB_HISUM)))]
2293 "TARGET_CM_EMBMEDANY && check_pic (1)"
2294 "sethi\t%%hi(%a1), %0")
2296 (define_insn "embmedany_losum"
2297 [(set (match_operand:DI 0 "register_operand" "=r")
2298 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2299 (match_operand:DI 2 "data_segment_operand" "")))]
2300 "TARGET_CM_EMBMEDANY"
2301 "add\t%1, %%lo(%a2), %0")
2303 (define_insn "embmedany_brsum"
2304 [(set (match_operand:DI 0 "register_operand" "=r")
2305 (unspec:DI [(match_operand:DI 1 "register_operand" "r")] UNSPEC_EMB_HISUM))]
2306 "TARGET_CM_EMBMEDANY"
2309 (define_insn "embmedany_textuhi"
2310 [(set (match_operand:DI 0 "register_operand" "=r")
2311 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTUHI)))]
2312 "TARGET_CM_EMBMEDANY && check_pic (1)"
2313 "sethi\t%%uhi(%a1), %0")
2315 (define_insn "embmedany_texthi"
2316 [(set (match_operand:DI 0 "register_operand" "=r")
2317 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTHI)))]
2318 "TARGET_CM_EMBMEDANY && check_pic (1)"
2319 "sethi\t%%hi(%a1), %0")
2321 (define_insn "embmedany_textulo"
2322 [(set (match_operand:DI 0 "register_operand" "=r")
2323 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2324 (unspec:DI [(match_operand:DI 2 "text_segment_operand" "")] UNSPEC_EMB_TEXTULO)))]
2325 "TARGET_CM_EMBMEDANY"
2326 "or\t%1, %%ulo(%a2), %0")
2328 (define_insn "embmedany_textlo"
2329 [(set (match_operand:DI 0 "register_operand" "=r")
2330 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2331 (match_operand:DI 2 "text_segment_operand" "")))]
2332 "TARGET_CM_EMBMEDANY"
2333 "or\t%1, %%lo(%a2), %0")
2335 ;; Now some patterns to help reload out a bit.
2336 (define_expand "reload_indi"
2337 [(parallel [(match_operand:DI 0 "register_operand" "=r")
2338 (match_operand:DI 1 "immediate_operand" "")
2339 (match_operand:TI 2 "register_operand" "=&r")])]
2341 || TARGET_CM_EMBMEDANY)
2344 sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
2348 (define_expand "reload_outdi"
2349 [(parallel [(match_operand:DI 0 "register_operand" "=r")
2350 (match_operand:DI 1 "immediate_operand" "")
2351 (match_operand:TI 2 "register_operand" "=&r")])]
2353 || TARGET_CM_EMBMEDANY)
2356 sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
2360 ;; Split up putting CONSTs and REGs into DI regs when !arch64
2362 [(set (match_operand:DI 0 "register_operand" "")
2363 (match_operand:DI 1 "const_int_operand" ""))]
2364 "! TARGET_ARCH64 && reload_completed"
2365 [(clobber (const_int 0))]
2367 #if HOST_BITS_PER_WIDE_INT == 32
2368 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
2369 (INTVAL (operands[1]) < 0) ?
2372 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2375 unsigned int low, high;
2377 low = trunc_int_for_mode (INTVAL (operands[1]), SImode);
2378 high = trunc_int_for_mode (INTVAL (operands[1]) >> 32, SImode);
2379 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), GEN_INT (high)));
2381 /* Slick... but this trick loses if this subreg constant part
2382 can be done in one insn. */
2383 if (low == high && (low & 0x3ff) != 0 && low + 0x1000 >= 0x2000)
2384 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2385 gen_highpart (SImode, operands[0])));
2387 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), GEN_INT (low)));
2393 [(set (match_operand:DI 0 "register_operand" "")
2394 (match_operand:DI 1 "const_double_operand" ""))]
2398 && ((GET_CODE (operands[0]) == REG
2399 && REGNO (operands[0]) < 32)
2400 || (GET_CODE (operands[0]) == SUBREG
2401 && GET_CODE (SUBREG_REG (operands[0])) == REG
2402 && REGNO (SUBREG_REG (operands[0])) < 32))))"
2403 [(clobber (const_int 0))]
2405 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
2406 GEN_INT (CONST_DOUBLE_HIGH (operands[1]))));
2408 /* Slick... but this trick loses if this subreg constant part
2409 can be done in one insn. */
2410 if (CONST_DOUBLE_LOW (operands[1]) == CONST_DOUBLE_HIGH (operands[1])
2411 && !(SPARC_SETHI32_P (CONST_DOUBLE_HIGH (operands[1]))
2412 || SPARC_SIMM13_P (CONST_DOUBLE_HIGH (operands[1]))))
2414 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2415 gen_highpart (SImode, operands[0])));
2419 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2420 GEN_INT (CONST_DOUBLE_LOW (operands[1]))));
2426 [(set (match_operand:DI 0 "register_operand" "")
2427 (match_operand:DI 1 "register_operand" ""))]
2428 "! TARGET_ARCH64 && reload_completed"
2429 [(clobber (const_int 0))]
2431 rtx set_dest = operands[0];
2432 rtx set_src = operands[1];
2436 dest1 = gen_highpart (SImode, set_dest);
2437 dest2 = gen_lowpart (SImode, set_dest);
2438 src1 = gen_highpart (SImode, set_src);
2439 src2 = gen_lowpart (SImode, set_src);
2441 /* Now emit using the real source and destination we found, swapping
2442 the order if we detect overlap. */
2443 if (reg_overlap_mentioned_p (dest1, src2))
2445 emit_insn (gen_movsi (dest2, src2));
2446 emit_insn (gen_movsi (dest1, src1));
2450 emit_insn (gen_movsi (dest1, src1));
2451 emit_insn (gen_movsi (dest2, src2));
2456 ;; Now handle the cases of memory moves from/to non-even
2457 ;; DI mode register pairs.
2459 [(set (match_operand:DI 0 "register_operand" "")
2460 (match_operand:DI 1 "memory_operand" ""))]
2463 && sparc_splitdi_legitimate (operands[0], operands[1]))"
2464 [(clobber (const_int 0))]
2466 rtx word0 = adjust_address (operands[1], SImode, 0);
2467 rtx word1 = adjust_address (operands[1], SImode, 4);
2468 rtx high_part = gen_highpart (SImode, operands[0]);
2469 rtx low_part = gen_lowpart (SImode, operands[0]);
2471 if (reg_overlap_mentioned_p (high_part, word1))
2473 emit_insn (gen_movsi (low_part, word1));
2474 emit_insn (gen_movsi (high_part, word0));
2478 emit_insn (gen_movsi (high_part, word0));
2479 emit_insn (gen_movsi (low_part, word1));
2485 [(set (match_operand:DI 0 "memory_operand" "")
2486 (match_operand:DI 1 "register_operand" ""))]
2489 && sparc_splitdi_legitimate (operands[1], operands[0]))"
2490 [(clobber (const_int 0))]
2492 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0),
2493 gen_highpart (SImode, operands[1])));
2494 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4),
2495 gen_lowpart (SImode, operands[1])));
2500 [(set (match_operand:DI 0 "memory_operand" "")
2505 && ! mem_min_alignment (operands[0], 8)))
2506 && offsettable_memref_p (operands[0])"
2507 [(clobber (const_int 0))]
2509 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0), const0_rtx));
2510 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4), const0_rtx));
2514 ;; Floating point move insns
2516 (define_insn "*movsf_insn_novis"
2517 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,*r,*r,*r,*r,*r,f,m,m")
2518 (match_operand:SF 1 "input_operand" "f,G,Q,*rR,S,m,m,f,*rG"))]
2519 "(TARGET_FPU && ! TARGET_VIS)
2520 && (register_operand (operands[0], SFmode)
2521 || register_operand (operands[1], SFmode)
2522 || fp_zero_operand (operands[1], SFmode))"
2524 if (GET_CODE (operands[1]) == CONST_DOUBLE
2525 && (which_alternative == 2
2526 || which_alternative == 3
2527 || which_alternative == 4))
2532 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2533 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2534 operands[1] = GEN_INT (i);
2537 switch (which_alternative)
2540 return "fmovs\t%1, %0";
2544 return "sethi\t%%hi(%a1), %0";
2546 return "mov\t%1, %0";
2551 return "ld\t%1, %0";
2554 return "st\t%r1, %0";
2559 [(set_attr "type" "fpmove,*,*,*,*,load,fpload,fpstore,store")])
2561 (define_insn "*movsf_insn_vis"
2562 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,*r,*r,*r,*r,*r,f,m,m")
2563 (match_operand:SF 1 "input_operand" "f,G,G,Q,*rR,S,m,m,f,*rG"))]
2564 "(TARGET_FPU && TARGET_VIS)
2565 && (register_operand (operands[0], SFmode)
2566 || register_operand (operands[1], SFmode)
2567 || fp_zero_operand (operands[1], SFmode))"
2569 if (GET_CODE (operands[1]) == CONST_DOUBLE
2570 && (which_alternative == 3
2571 || which_alternative == 4
2572 || which_alternative == 5))
2577 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2578 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2579 operands[1] = GEN_INT (i);
2582 switch (which_alternative)
2585 return "fmovs\t%1, %0";
2587 return "fzeros\t%0";
2591 return "sethi\t%%hi(%a1), %0";
2593 return "mov\t%1, %0";
2598 return "ld\t%1, %0";
2601 return "st\t%r1, %0";
2606 [(set_attr "type" "fpmove,fpmove,*,*,*,*,load,fpload,fpstore,store")])
2608 ;; Exactly the same as above, except that all `f' cases are deleted.
2609 ;; This is necessary to prevent reload from ever trying to use a `f' reg
2612 (define_insn "*movsf_no_f_insn"
2613 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r,r,r,m")
2614 (match_operand:SF 1 "input_operand" "G,Q,rR,S,m,rG"))]
2616 && (register_operand (operands[0], SFmode)
2617 || register_operand (operands[1], SFmode)
2618 || fp_zero_operand (operands[1], SFmode))"
2620 if (GET_CODE (operands[1]) == CONST_DOUBLE
2621 && (which_alternative == 1
2622 || which_alternative == 2
2623 || which_alternative == 3))
2628 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2629 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2630 operands[1] = GEN_INT (i);
2633 switch (which_alternative)
2638 return "sethi\t%%hi(%a1), %0";
2640 return "mov\t%1, %0";
2644 return "ld\t%1, %0";
2646 return "st\t%r1, %0";
2651 [(set_attr "type" "*,*,*,*,load,store")])
2653 (define_insn "*movsf_lo_sum"
2654 [(set (match_operand:SF 0 "register_operand" "=r")
2655 (lo_sum:SF (match_operand:SF 1 "register_operand" "r")
2656 (match_operand:SF 2 "const_double_operand" "S")))]
2657 "fp_high_losum_p (operands[2])"
2662 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[2]);
2663 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2664 operands[2] = GEN_INT (i);
2665 return "or\t%1, %%lo(%a2), %0";
2668 (define_insn "*movsf_high"
2669 [(set (match_operand:SF 0 "register_operand" "=r")
2670 (high:SF (match_operand:SF 1 "const_double_operand" "S")))]
2671 "fp_high_losum_p (operands[1])"
2676 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2677 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2678 operands[1] = GEN_INT (i);
2679 return "sethi\t%%hi(%1), %0";
2683 [(set (match_operand:SF 0 "register_operand" "")
2684 (match_operand:SF 1 "const_double_operand" ""))]
2685 "fp_high_losum_p (operands[1])
2686 && (GET_CODE (operands[0]) == REG
2687 && REGNO (operands[0]) < 32)"
2688 [(set (match_dup 0) (high:SF (match_dup 1)))
2689 (set (match_dup 0) (lo_sum:SF (match_dup 0) (match_dup 1)))])
2691 (define_expand "movsf"
2692 [(set (match_operand:SF 0 "general_operand" "")
2693 (match_operand:SF 1 "general_operand" ""))]
2696 /* Force SFmode constants into memory. */
2697 if (GET_CODE (operands[0]) == REG
2698 && CONSTANT_P (operands[1]))
2700 /* emit_group_store will send such bogosity to us when it is
2701 not storing directly into memory. So fix this up to avoid
2702 crashes in output_constant_pool. */
2703 if (operands [1] == const0_rtx)
2704 operands[1] = CONST0_RTX (SFmode);
2706 if (TARGET_VIS && fp_zero_operand (operands[1], SFmode))
2709 /* We are able to build any SF constant in integer registers
2710 with at most 2 instructions. */
2711 if (REGNO (operands[0]) < 32)
2714 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
2718 /* Handle sets of MEM first. */
2719 if (GET_CODE (operands[0]) == MEM)
2721 if (register_operand (operands[1], SFmode)
2722 || fp_zero_operand (operands[1], SFmode))
2725 if (! reload_in_progress)
2727 operands[0] = validize_mem (operands[0]);
2728 operands[1] = force_reg (SFmode, operands[1]);
2732 /* Fixup PIC cases. */
2735 if (CONSTANT_P (operands[1])
2736 && pic_address_needs_scratch (operands[1]))
2737 operands[1] = legitimize_pic_address (operands[1], SFmode, 0);
2739 if (symbolic_operand (operands[1], SFmode))
2741 operands[1] = legitimize_pic_address (operands[1],
2743 (reload_in_progress ?
2753 (define_expand "movdf"
2754 [(set (match_operand:DF 0 "general_operand" "")
2755 (match_operand:DF 1 "general_operand" ""))]
2758 /* Force DFmode constants into memory. */
2759 if (GET_CODE (operands[0]) == REG
2760 && CONSTANT_P (operands[1]))
2762 /* emit_group_store will send such bogosity to us when it is
2763 not storing directly into memory. So fix this up to avoid
2764 crashes in output_constant_pool. */
2765 if (operands [1] == const0_rtx)
2766 operands[1] = CONST0_RTX (DFmode);
2768 if ((TARGET_VIS || REGNO (operands[0]) < 32)
2769 && fp_zero_operand (operands[1], DFmode))
2772 /* We are able to build any DF constant in integer registers. */
2773 if (REGNO (operands[0]) < 32
2774 && (reload_completed || reload_in_progress))
2777 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
2781 /* Handle MEM cases first. */
2782 if (GET_CODE (operands[0]) == MEM)
2784 if (register_operand (operands[1], DFmode)
2785 || fp_zero_operand (operands[1], DFmode))
2788 if (! reload_in_progress)
2790 operands[0] = validize_mem (operands[0]);
2791 operands[1] = force_reg (DFmode, operands[1]);
2795 /* Fixup PIC cases. */
2798 if (CONSTANT_P (operands[1])
2799 && pic_address_needs_scratch (operands[1]))
2800 operands[1] = legitimize_pic_address (operands[1], DFmode, 0);
2802 if (symbolic_operand (operands[1], DFmode))
2804 operands[1] = legitimize_pic_address (operands[1],
2806 (reload_in_progress ?
2816 ;; Be careful, fmovd does not exist when !v9.
2817 (define_insn "*movdf_insn_sp32"
2818 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,W,U,T,o,e,*r,o,e,o")
2819 (match_operand:DF 1 "input_operand" "W#F,e,T,U,G,e,*rFo,*r,o#F,e"))]
2822 && (register_operand (operands[0], DFmode)
2823 || register_operand (operands[1], DFmode)
2824 || fp_zero_operand (operands[1], DFmode))"
2836 [(set_attr "type" "fpload,fpstore,load,store,*,*,*,*,*,*")
2837 (set_attr "length" "*,*,*,*,2,2,2,2,2,2")])
2839 (define_insn "*movdf_no_e_insn_sp32"
2840 [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,o,r,o")
2841 (match_operand:DF 1 "input_operand" "T,U,G,ro,r"))]
2845 && (register_operand (operands[0], DFmode)
2846 || register_operand (operands[1], DFmode)
2847 || fp_zero_operand (operands[1], DFmode))"
2854 [(set_attr "type" "load,store,*,*,*")
2855 (set_attr "length" "*,*,2,2,2")])
2857 (define_insn "*movdf_no_e_insn_v9_sp32"
2858 [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,T,r,o")
2859 (match_operand:DF 1 "input_operand" "T,U,G,ro,rG"))]
2863 && (register_operand (operands[0], DFmode)
2864 || register_operand (operands[1], DFmode)
2865 || fp_zero_operand (operands[1], DFmode))"
2872 [(set_attr "type" "load,store,store,*,*")
2873 (set_attr "length" "*,*,*,2,2")])
2875 ;; We have available v9 double floats but not 64-bit
2876 ;; integer registers and no VIS.
2877 (define_insn "*movdf_insn_v9only_novis"
2878 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,T,W,U,T,f,*r,o")
2879 (match_operand:DF 1 "input_operand" "e,W#F,G,e,T,U,o#F,*roF,*rGf"))]
2884 && (register_operand (operands[0], DFmode)
2885 || register_operand (operands[1], DFmode)
2886 || fp_zero_operand (operands[1], DFmode))"
2897 [(set_attr "type" "fpmove,load,store,store,load,store,*,*,*")
2898 (set_attr "length" "*,*,*,*,*,*,2,2,2")
2899 (set_attr "fptype" "double,*,*,*,*,*,*,*,*")])
2901 ;; We have available v9 double floats but not 64-bit
2902 ;; integer registers but we have VIS.
2903 (define_insn "*movdf_insn_v9only_vis"
2904 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,e,T,W,U,T,f,*r,o")
2905 (match_operand:DF 1 "input_operand" "G,e,W#F,G,e,T,U,o#F,*roGF,*rGf"))]
2909 && (register_operand (operands[0], DFmode)
2910 || register_operand (operands[1], DFmode)
2911 || fp_zero_operand (operands[1], DFmode))"
2923 [(set_attr "type" "fpmove,fpmove,load,store,store,load,store,*,*,*")
2924 (set_attr "length" "*,*,*,*,*,*,*,2,2,2")
2925 (set_attr "fptype" "double,double,*,*,*,*,*,*,*,*")])
2927 ;; We have available both v9 double floats and 64-bit
2928 ;; integer registers. No VIS though.
2929 (define_insn "*movdf_insn_sp64_novis"
2930 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,W,*r,*r,m,*r")
2931 (match_operand:DF 1 "input_operand" "e,W#F,e,*rG,m,*rG,F"))]
2935 && (register_operand (operands[0], DFmode)
2936 || register_operand (operands[1], DFmode)
2937 || fp_zero_operand (operands[1], DFmode))"
2946 [(set_attr "type" "fpmove,load,store,*,load,store,*")
2947 (set_attr "length" "*,*,*,*,*,*,2")
2948 (set_attr "fptype" "double,*,*,*,*,*,*")])
2950 ;; We have available both v9 double floats and 64-bit
2951 ;; integer registers. And we have VIS.
2952 (define_insn "*movdf_insn_sp64_vis"
2953 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,e,W,*r,*r,m,*r")
2954 (match_operand:DF 1 "input_operand" "G,e,W#F,e,*rG,m,*rG,F"))]
2958 && (register_operand (operands[0], DFmode)
2959 || register_operand (operands[1], DFmode)
2960 || fp_zero_operand (operands[1], DFmode))"
2970 [(set_attr "type" "fpmove,fpmove,load,store,*,load,store,*")
2971 (set_attr "length" "*,*,*,*,*,*,*,2")
2972 (set_attr "fptype" "double,double,*,*,*,*,*,*")])
2974 (define_insn "*movdf_no_e_insn_sp64"
2975 [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m")
2976 (match_operand:DF 1 "input_operand" "r,m,rG"))]
2979 && (register_operand (operands[0], DFmode)
2980 || register_operand (operands[1], DFmode)
2981 || fp_zero_operand (operands[1], DFmode))"
2986 [(set_attr "type" "*,load,store")])
2989 [(set (match_operand:DF 0 "register_operand" "")
2990 (match_operand:DF 1 "const_double_operand" ""))]
2992 && (GET_CODE (operands[0]) == REG
2993 && REGNO (operands[0]) < 32)
2994 && ! fp_zero_operand(operands[1], DFmode)
2995 && reload_completed"
2996 [(clobber (const_int 0))]
3001 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3002 REAL_VALUE_TO_TARGET_DOUBLE (r, l);
3003 operands[0] = gen_rtx_raw_REG (DImode, REGNO (operands[0]));
3007 #if HOST_BITS_PER_WIDE_INT == 64
3010 val = ((HOST_WIDE_INT)(unsigned long)l[1] |
3011 ((HOST_WIDE_INT)(unsigned long)l[0] << 32));
3012 emit_insn (gen_movdi (operands[0], GEN_INT (val)));
3014 emit_insn (gen_movdi (operands[0],
3015 immed_double_const (l[1], l[0], DImode)));
3020 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
3023 /* Slick... but this trick loses if this subreg constant part
3024 can be done in one insn. */
3026 && !(SPARC_SETHI32_P (l[0])
3027 || SPARC_SIMM13_P (l[0])))
3029 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
3030 gen_highpart (SImode, operands[0])));
3034 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
3041 ;; Ok, now the splits to handle all the multi insn and
3042 ;; mis-aligned memory address cases.
3043 ;; In these splits please take note that we must be
3044 ;; careful when V9 but not ARCH64 because the integer
3045 ;; register DFmode cases must be handled.
3047 [(set (match_operand:DF 0 "register_operand" "")
3048 (match_operand:DF 1 "register_operand" ""))]
3051 && ((GET_CODE (operands[0]) == REG
3052 && REGNO (operands[0]) < 32)
3053 || (GET_CODE (operands[0]) == SUBREG
3054 && GET_CODE (SUBREG_REG (operands[0])) == REG
3055 && REGNO (SUBREG_REG (operands[0])) < 32))))
3056 && reload_completed"
3057 [(clobber (const_int 0))]
3059 rtx set_dest = operands[0];
3060 rtx set_src = operands[1];
3064 dest1 = gen_highpart (SFmode, set_dest);
3065 dest2 = gen_lowpart (SFmode, set_dest);
3066 src1 = gen_highpart (SFmode, set_src);
3067 src2 = gen_lowpart (SFmode, set_src);
3069 /* Now emit using the real source and destination we found, swapping
3070 the order if we detect overlap. */
3071 if (reg_overlap_mentioned_p (dest1, src2))
3073 emit_insn (gen_movsf (dest2, src2));
3074 emit_insn (gen_movsf (dest1, src1));
3078 emit_insn (gen_movsf (dest1, src1));
3079 emit_insn (gen_movsf (dest2, src2));
3085 [(set (match_operand:DF 0 "register_operand" "")
3086 (match_operand:DF 1 "memory_operand" ""))]
3089 && (((REGNO (operands[0]) % 2) != 0)
3090 || ! mem_min_alignment (operands[1], 8))
3091 && offsettable_memref_p (operands[1])"
3092 [(clobber (const_int 0))]
3094 rtx word0 = adjust_address (operands[1], SFmode, 0);
3095 rtx word1 = adjust_address (operands[1], SFmode, 4);
3097 if (reg_overlap_mentioned_p (gen_highpart (SFmode, operands[0]), word1))
3099 emit_insn (gen_movsf (gen_lowpart (SFmode, operands[0]),
3101 emit_insn (gen_movsf (gen_highpart (SFmode, operands[0]),
3106 emit_insn (gen_movsf (gen_highpart (SFmode, operands[0]),
3108 emit_insn (gen_movsf (gen_lowpart (SFmode, operands[0]),
3115 [(set (match_operand:DF 0 "memory_operand" "")
3116 (match_operand:DF 1 "register_operand" ""))]
3119 && (((REGNO (operands[1]) % 2) != 0)
3120 || ! mem_min_alignment (operands[0], 8))
3121 && offsettable_memref_p (operands[0])"
3122 [(clobber (const_int 0))]
3124 rtx word0 = adjust_address (operands[0], SFmode, 0);
3125 rtx word1 = adjust_address (operands[0], SFmode, 4);
3127 emit_insn (gen_movsf (word0,
3128 gen_highpart (SFmode, operands[1])));
3129 emit_insn (gen_movsf (word1,
3130 gen_lowpart (SFmode, operands[1])));
3135 [(set (match_operand:DF 0 "memory_operand" "")
3136 (match_operand:DF 1 "fp_zero_operand" ""))]
3140 && ! mem_min_alignment (operands[0], 8)))
3141 && offsettable_memref_p (operands[0])"
3142 [(clobber (const_int 0))]
3146 dest1 = adjust_address (operands[0], SFmode, 0);
3147 dest2 = adjust_address (operands[0], SFmode, 4);
3149 emit_insn (gen_movsf (dest1, CONST0_RTX (SFmode)));
3150 emit_insn (gen_movsf (dest2, CONST0_RTX (SFmode)));
3155 [(set (match_operand:DF 0 "register_operand" "")
3156 (match_operand:DF 1 "fp_zero_operand" ""))]
3159 && ((GET_CODE (operands[0]) == REG
3160 && REGNO (operands[0]) < 32)
3161 || (GET_CODE (operands[0]) == SUBREG
3162 && GET_CODE (SUBREG_REG (operands[0])) == REG
3163 && REGNO (SUBREG_REG (operands[0])) < 32))"
3164 [(clobber (const_int 0))]
3166 rtx set_dest = operands[0];
3169 dest1 = gen_highpart (SFmode, set_dest);
3170 dest2 = gen_lowpart (SFmode, set_dest);
3171 emit_insn (gen_movsf (dest1, CONST0_RTX (SFmode)));
3172 emit_insn (gen_movsf (dest2, CONST0_RTX (SFmode)));
3176 (define_expand "movtf"
3177 [(set (match_operand:TF 0 "general_operand" "")
3178 (match_operand:TF 1 "general_operand" ""))]
3181 /* Force TFmode constants into memory. */
3182 if (GET_CODE (operands[0]) == REG
3183 && CONSTANT_P (operands[1]))
3185 /* emit_group_store will send such bogosity to us when it is
3186 not storing directly into memory. So fix this up to avoid
3187 crashes in output_constant_pool. */
3188 if (operands [1] == const0_rtx)
3189 operands[1] = CONST0_RTX (TFmode);
3191 if (TARGET_VIS && fp_zero_operand (operands[1], TFmode))
3194 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
3198 /* Handle MEM cases first, note that only v9 guarentees
3199 full 16-byte alignment for quads. */
3200 if (GET_CODE (operands[0]) == MEM)
3202 if (register_operand (operands[1], TFmode)
3203 || fp_zero_operand (operands[1], TFmode))
3206 if (! reload_in_progress)
3208 operands[0] = validize_mem (operands[0]);
3209 operands[1] = force_reg (TFmode, operands[1]);
3213 /* Fixup PIC cases. */
3216 if (CONSTANT_P (operands[1])
3217 && pic_address_needs_scratch (operands[1]))
3218 operands[1] = legitimize_pic_address (operands[1], TFmode, 0);
3220 if (symbolic_operand (operands[1], TFmode))
3222 operands[1] = legitimize_pic_address (operands[1],
3224 (reload_in_progress ?
3234 ;; Be careful, fmovq and {st,ld}{x,q} do not exist when !arch64 so
3235 ;; we must split them all. :-(
3236 (define_insn "*movtf_insn_sp32"
3237 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,U,r")
3238 (match_operand:TF 1 "input_operand" "oe,GeUr,o,roG"))]
3242 && (register_operand (operands[0], TFmode)
3243 || register_operand (operands[1], TFmode)
3244 || fp_zero_operand (operands[1], TFmode))"
3246 [(set_attr "length" "4")])
3248 (define_insn "*movtf_insn_vis_sp32"
3249 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,U,r")
3250 (match_operand:TF 1 "input_operand" "Goe,GeUr,o,roG"))]
3254 && (register_operand (operands[0], TFmode)
3255 || register_operand (operands[1], TFmode)
3256 || fp_zero_operand (operands[1], TFmode))"
3258 [(set_attr "length" "4")])
3260 ;; Exactly the same as above, except that all `e' cases are deleted.
3261 ;; This is necessary to prevent reload from ever trying to use a `e' reg
3264 (define_insn "*movtf_no_e_insn_sp32"
3265 [(set (match_operand:TF 0 "nonimmediate_operand" "=o,U,o,r,o")
3266 (match_operand:TF 1 "input_operand" "G,o,U,roG,r"))]
3269 && (register_operand (operands[0], TFmode)
3270 || register_operand (operands[1], TFmode)
3271 || fp_zero_operand (operands[1], TFmode))"
3273 [(set_attr "length" "4")])
3275 ;; Now handle the float reg cases directly when arch64,
3276 ;; hard_quad, and proper reg number alignment are all true.
3277 (define_insn "*movtf_insn_hq_sp64"
3278 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,e,m,o,r")
3279 (match_operand:TF 1 "input_operand" "e,m,e,Gr,roG"))]
3284 && (register_operand (operands[0], TFmode)
3285 || register_operand (operands[1], TFmode)
3286 || fp_zero_operand (operands[1], TFmode))"
3293 [(set_attr "type" "fpmove,fpload,fpstore,*,*")
3294 (set_attr "length" "*,*,*,2,2")])
3296 (define_insn "*movtf_insn_hq_vis_sp64"
3297 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,e,m,eo,r,o")
3298 (match_operand:TF 1 "input_operand" "e,m,e,G,roG,r"))]
3303 && (register_operand (operands[0], TFmode)
3304 || register_operand (operands[1], TFmode)
3305 || fp_zero_operand (operands[1], TFmode))"
3313 [(set_attr "type" "fpmove,fpload,fpstore,*,*,*")
3314 (set_attr "length" "*,*,*,2,2,2")])
3316 ;; Now we allow the integer register cases even when
3317 ;; only arch64 is true.
3318 (define_insn "*movtf_insn_sp64"
3319 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,r")
3320 (match_operand:TF 1 "input_operand" "oe,Ger,orG"))]
3324 && ! TARGET_HARD_QUAD
3325 && (register_operand (operands[0], TFmode)
3326 || register_operand (operands[1], TFmode)
3327 || fp_zero_operand (operands[1], TFmode))"
3329 [(set_attr "length" "2")])
3331 (define_insn "*movtf_insn_vis_sp64"
3332 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,r")
3333 (match_operand:TF 1 "input_operand" "Goe,Ger,orG"))]
3337 && ! TARGET_HARD_QUAD
3338 && (register_operand (operands[0], TFmode)
3339 || register_operand (operands[1], TFmode)
3340 || fp_zero_operand (operands[1], TFmode))"
3342 [(set_attr "length" "2")])
3344 (define_insn "*movtf_no_e_insn_sp64"
3345 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o")
3346 (match_operand:TF 1 "input_operand" "orG,rG"))]
3349 && (register_operand (operands[0], TFmode)
3350 || register_operand (operands[1], TFmode)
3351 || fp_zero_operand (operands[1], TFmode))"
3353 [(set_attr "length" "2")])
3355 ;; Now all the splits to handle multi-insn TF mode moves.
3357 [(set (match_operand:TF 0 "register_operand" "")
3358 (match_operand:TF 1 "register_operand" ""))]
3362 && ! TARGET_HARD_QUAD)
3363 || ! fp_register_operand (operands[0], TFmode))"
3364 [(clobber (const_int 0))]
3366 rtx set_dest = operands[0];
3367 rtx set_src = operands[1];
3371 dest1 = gen_df_reg (set_dest, 0);
3372 dest2 = gen_df_reg (set_dest, 1);
3373 src1 = gen_df_reg (set_src, 0);
3374 src2 = gen_df_reg (set_src, 1);
3376 /* Now emit using the real source and destination we found, swapping
3377 the order if we detect overlap. */
3378 if (reg_overlap_mentioned_p (dest1, src2))
3380 emit_insn (gen_movdf (dest2, src2));
3381 emit_insn (gen_movdf (dest1, src1));
3385 emit_insn (gen_movdf (dest1, src1));
3386 emit_insn (gen_movdf (dest2, src2));
3392 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3393 (match_operand:TF 1 "fp_zero_operand" ""))]
3395 [(clobber (const_int 0))]
3397 rtx set_dest = operands[0];
3400 switch (GET_CODE (set_dest))
3403 dest1 = gen_df_reg (set_dest, 0);
3404 dest2 = gen_df_reg (set_dest, 1);
3407 dest1 = adjust_address (set_dest, DFmode, 0);
3408 dest2 = adjust_address (set_dest, DFmode, 8);
3414 emit_insn (gen_movdf (dest1, CONST0_RTX (DFmode)));
3415 emit_insn (gen_movdf (dest2, CONST0_RTX (DFmode)));
3420 [(set (match_operand:TF 0 "register_operand" "")
3421 (match_operand:TF 1 "memory_operand" ""))]
3423 && offsettable_memref_p (operands[1])
3425 || ! TARGET_HARD_QUAD
3426 || ! fp_register_operand (operands[0], TFmode)))"
3427 [(clobber (const_int 0))]
3429 rtx word0 = adjust_address (operands[1], DFmode, 0);
3430 rtx word1 = adjust_address (operands[1], DFmode, 8);
3431 rtx set_dest, dest1, dest2;
3433 set_dest = operands[0];
3435 dest1 = gen_df_reg (set_dest, 0);
3436 dest2 = gen_df_reg (set_dest, 1);
3438 /* Now output, ordering such that we don't clobber any registers
3439 mentioned in the address. */
3440 if (reg_overlap_mentioned_p (dest1, word1))
3443 emit_insn (gen_movdf (dest2, word1));
3444 emit_insn (gen_movdf (dest1, word0));
3448 emit_insn (gen_movdf (dest1, word0));
3449 emit_insn (gen_movdf (dest2, word1));
3455 [(set (match_operand:TF 0 "memory_operand" "")
3456 (match_operand:TF 1 "register_operand" ""))]
3458 && offsettable_memref_p (operands[0])
3460 || ! TARGET_HARD_QUAD
3461 || ! fp_register_operand (operands[1], TFmode)))"
3462 [(clobber (const_int 0))]
3464 rtx set_src = operands[1];
3466 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 0),
3467 gen_df_reg (set_src, 0)));
3468 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 8),
3469 gen_df_reg (set_src, 1)));
3473 ;; SPARC V9 conditional move instructions.
3475 ;; We can handle larger constants here for some flavors, but for now we keep
3476 ;; it simple and only allow those constants supported by all flavors.
3477 ;; Note that emit_conditional_move canonicalizes operands 2,3 so that operand
3478 ;; 3 contains the constant if one is present, but we handle either for
3479 ;; generality (sparc.c puts a constant in operand 2).
3481 (define_expand "movqicc"
3482 [(set (match_operand:QI 0 "register_operand" "")
3483 (if_then_else:QI (match_operand 1 "comparison_operator" "")
3484 (match_operand:QI 2 "arith10_operand" "")
3485 (match_operand:QI 3 "arith10_operand" "")))]
3488 enum rtx_code code = GET_CODE (operands[1]);
3490 if (GET_MODE (sparc_compare_op0) == DImode
3494 if (sparc_compare_op1 == const0_rtx
3495 && GET_CODE (sparc_compare_op0) == REG
3496 && GET_MODE (sparc_compare_op0) == DImode
3497 && v9_regcmp_p (code))
3499 operands[1] = gen_rtx_fmt_ee (code, DImode,
3500 sparc_compare_op0, sparc_compare_op1);
3504 rtx cc_reg = gen_compare_reg (code,
3505 sparc_compare_op0, sparc_compare_op1);
3506 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3510 (define_expand "movhicc"
3511 [(set (match_operand:HI 0 "register_operand" "")
3512 (if_then_else:HI (match_operand 1 "comparison_operator" "")
3513 (match_operand:HI 2 "arith10_operand" "")
3514 (match_operand:HI 3 "arith10_operand" "")))]
3517 enum rtx_code code = GET_CODE (operands[1]);
3519 if (GET_MODE (sparc_compare_op0) == DImode
3523 if (sparc_compare_op1 == const0_rtx
3524 && GET_CODE (sparc_compare_op0) == REG
3525 && GET_MODE (sparc_compare_op0) == DImode
3526 && v9_regcmp_p (code))
3528 operands[1] = gen_rtx_fmt_ee (code, DImode,
3529 sparc_compare_op0, sparc_compare_op1);
3533 rtx cc_reg = gen_compare_reg (code,
3534 sparc_compare_op0, sparc_compare_op1);
3535 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3539 (define_expand "movsicc"
3540 [(set (match_operand:SI 0 "register_operand" "")
3541 (if_then_else:SI (match_operand 1 "comparison_operator" "")
3542 (match_operand:SI 2 "arith10_operand" "")
3543 (match_operand:SI 3 "arith10_operand" "")))]
3546 enum rtx_code code = GET_CODE (operands[1]);
3547 enum machine_mode op0_mode = GET_MODE (sparc_compare_op0);
3549 if (sparc_compare_op1 == const0_rtx
3550 && GET_CODE (sparc_compare_op0) == REG
3551 && (TARGET_ARCH64 && op0_mode == DImode && v9_regcmp_p (code)))
3553 operands[1] = gen_rtx_fmt_ee (code, op0_mode,
3554 sparc_compare_op0, sparc_compare_op1);
3558 rtx cc_reg = gen_compare_reg (code,
3559 sparc_compare_op0, sparc_compare_op1);
3560 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg),
3561 cc_reg, const0_rtx);
3565 (define_expand "movdicc"
3566 [(set (match_operand:DI 0 "register_operand" "")
3567 (if_then_else:DI (match_operand 1 "comparison_operator" "")
3568 (match_operand:DI 2 "arith10_double_operand" "")
3569 (match_operand:DI 3 "arith10_double_operand" "")))]
3572 enum rtx_code code = GET_CODE (operands[1]);
3574 if (sparc_compare_op1 == const0_rtx
3575 && GET_CODE (sparc_compare_op0) == REG
3576 && GET_MODE (sparc_compare_op0) == DImode
3577 && v9_regcmp_p (code))
3579 operands[1] = gen_rtx_fmt_ee (code, DImode,
3580 sparc_compare_op0, sparc_compare_op1);
3584 rtx cc_reg = gen_compare_reg (code,
3585 sparc_compare_op0, sparc_compare_op1);
3586 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg),
3587 cc_reg, const0_rtx);
3591 (define_expand "movsfcc"
3592 [(set (match_operand:SF 0 "register_operand" "")
3593 (if_then_else:SF (match_operand 1 "comparison_operator" "")
3594 (match_operand:SF 2 "register_operand" "")
3595 (match_operand:SF 3 "register_operand" "")))]
3596 "TARGET_V9 && TARGET_FPU"
3598 enum rtx_code code = GET_CODE (operands[1]);
3600 if (GET_MODE (sparc_compare_op0) == DImode
3604 if (sparc_compare_op1 == const0_rtx
3605 && GET_CODE (sparc_compare_op0) == REG
3606 && GET_MODE (sparc_compare_op0) == DImode
3607 && v9_regcmp_p (code))
3609 operands[1] = gen_rtx_fmt_ee (code, DImode,
3610 sparc_compare_op0, sparc_compare_op1);
3614 rtx cc_reg = gen_compare_reg (code,
3615 sparc_compare_op0, sparc_compare_op1);
3616 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3620 (define_expand "movdfcc"
3621 [(set (match_operand:DF 0 "register_operand" "")
3622 (if_then_else:DF (match_operand 1 "comparison_operator" "")
3623 (match_operand:DF 2 "register_operand" "")
3624 (match_operand:DF 3 "register_operand" "")))]
3625 "TARGET_V9 && TARGET_FPU"
3627 enum rtx_code code = GET_CODE (operands[1]);
3629 if (GET_MODE (sparc_compare_op0) == DImode
3633 if (sparc_compare_op1 == const0_rtx
3634 && GET_CODE (sparc_compare_op0) == REG
3635 && GET_MODE (sparc_compare_op0) == DImode
3636 && v9_regcmp_p (code))
3638 operands[1] = gen_rtx_fmt_ee (code, DImode,
3639 sparc_compare_op0, sparc_compare_op1);
3643 rtx cc_reg = gen_compare_reg (code,
3644 sparc_compare_op0, sparc_compare_op1);
3645 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3649 (define_expand "movtfcc"
3650 [(set (match_operand:TF 0 "register_operand" "")
3651 (if_then_else:TF (match_operand 1 "comparison_operator" "")
3652 (match_operand:TF 2 "register_operand" "")
3653 (match_operand:TF 3 "register_operand" "")))]
3654 "TARGET_V9 && TARGET_FPU"
3656 enum rtx_code code = GET_CODE (operands[1]);
3658 if (GET_MODE (sparc_compare_op0) == DImode
3662 if (sparc_compare_op1 == const0_rtx
3663 && GET_CODE (sparc_compare_op0) == REG
3664 && GET_MODE (sparc_compare_op0) == DImode
3665 && v9_regcmp_p (code))
3667 operands[1] = gen_rtx_fmt_ee (code, DImode,
3668 sparc_compare_op0, sparc_compare_op1);
3672 rtx cc_reg = gen_compare_reg (code,
3673 sparc_compare_op0, sparc_compare_op1);
3674 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3678 ;; Conditional move define_insns.
3680 (define_insn "*movqi_cc_sp64"
3681 [(set (match_operand:QI 0 "register_operand" "=r,r")
3682 (if_then_else:QI (match_operator 1 "comparison_operator"
3683 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3685 (match_operand:QI 3 "arith11_operand" "rL,0")
3686 (match_operand:QI 4 "arith11_operand" "0,rL")))]
3690 mov%c1\t%x2, %4, %0"
3691 [(set_attr "type" "cmove")])
3693 (define_insn "*movhi_cc_sp64"
3694 [(set (match_operand:HI 0 "register_operand" "=r,r")
3695 (if_then_else:HI (match_operator 1 "comparison_operator"
3696 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3698 (match_operand:HI 3 "arith11_operand" "rL,0")
3699 (match_operand:HI 4 "arith11_operand" "0,rL")))]
3703 mov%c1\t%x2, %4, %0"
3704 [(set_attr "type" "cmove")])
3706 (define_insn "*movsi_cc_sp64"
3707 [(set (match_operand:SI 0 "register_operand" "=r,r")
3708 (if_then_else:SI (match_operator 1 "comparison_operator"
3709 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3711 (match_operand:SI 3 "arith11_operand" "rL,0")
3712 (match_operand:SI 4 "arith11_operand" "0,rL")))]
3716 mov%c1\t%x2, %4, %0"
3717 [(set_attr "type" "cmove")])
3719 ;; ??? The constraints of operands 3,4 need work.
3720 (define_insn "*movdi_cc_sp64"
3721 [(set (match_operand:DI 0 "register_operand" "=r,r")
3722 (if_then_else:DI (match_operator 1 "comparison_operator"
3723 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3725 (match_operand:DI 3 "arith11_double_operand" "rLH,0")
3726 (match_operand:DI 4 "arith11_double_operand" "0,rLH")))]
3730 mov%c1\t%x2, %4, %0"
3731 [(set_attr "type" "cmove")])
3733 (define_insn "*movdi_cc_sp64_trunc"
3734 [(set (match_operand:SI 0 "register_operand" "=r,r")
3735 (if_then_else:SI (match_operator 1 "comparison_operator"
3736 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3738 (match_operand:SI 3 "arith11_double_operand" "rLH,0")
3739 (match_operand:SI 4 "arith11_double_operand" "0,rLH")))]
3743 mov%c1\t%x2, %4, %0"
3744 [(set_attr "type" "cmove")])
3746 (define_insn "*movsf_cc_sp64"
3747 [(set (match_operand:SF 0 "register_operand" "=f,f")
3748 (if_then_else:SF (match_operator 1 "comparison_operator"
3749 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3751 (match_operand:SF 3 "register_operand" "f,0")
3752 (match_operand:SF 4 "register_operand" "0,f")))]
3753 "TARGET_V9 && TARGET_FPU"
3755 fmovs%C1\t%x2, %3, %0
3756 fmovs%c1\t%x2, %4, %0"
3757 [(set_attr "type" "fpcmove")])
3759 (define_insn "movdf_cc_sp64"
3760 [(set (match_operand:DF 0 "register_operand" "=e,e")
3761 (if_then_else:DF (match_operator 1 "comparison_operator"
3762 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3764 (match_operand:DF 3 "register_operand" "e,0")
3765 (match_operand:DF 4 "register_operand" "0,e")))]
3766 "TARGET_V9 && TARGET_FPU"
3768 fmovd%C1\t%x2, %3, %0
3769 fmovd%c1\t%x2, %4, %0"
3770 [(set_attr "type" "fpcmove")
3771 (set_attr "fptype" "double")])
3773 (define_insn "*movtf_cc_hq_sp64"
3774 [(set (match_operand:TF 0 "register_operand" "=e,e")
3775 (if_then_else:TF (match_operator 1 "comparison_operator"
3776 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3778 (match_operand:TF 3 "register_operand" "e,0")
3779 (match_operand:TF 4 "register_operand" "0,e")))]
3780 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
3782 fmovq%C1\t%x2, %3, %0
3783 fmovq%c1\t%x2, %4, %0"
3784 [(set_attr "type" "fpcmove")])
3786 (define_insn_and_split "*movtf_cc_sp64"
3787 [(set (match_operand:TF 0 "register_operand" "=e,e")
3788 (if_then_else:TF (match_operator 1 "comparison_operator"
3789 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3791 (match_operand:TF 3 "register_operand" "e,0")
3792 (match_operand:TF 4 "register_operand" "0,e")))]
3793 "TARGET_V9 && TARGET_FPU && !TARGET_HARD_QUAD"
3795 "&& reload_completed"
3796 [(clobber (const_int 0))]
3798 rtx set_dest = operands[0];
3799 rtx set_srca = operands[3];
3800 rtx set_srcb = operands[4];
3801 int third = rtx_equal_p (set_dest, set_srca);
3803 rtx srca1, srca2, srcb1, srcb2;
3805 dest1 = gen_df_reg (set_dest, 0);
3806 dest2 = gen_df_reg (set_dest, 1);
3807 srca1 = gen_df_reg (set_srca, 0);
3808 srca2 = gen_df_reg (set_srca, 1);
3809 srcb1 = gen_df_reg (set_srcb, 0);
3810 srcb2 = gen_df_reg (set_srcb, 1);
3812 /* Now emit using the real source and destination we found, swapping
3813 the order if we detect overlap. */
3814 if ((third && reg_overlap_mentioned_p (dest1, srcb2))
3815 || (!third && reg_overlap_mentioned_p (dest1, srca2)))
3817 emit_insn (gen_movdf_cc_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
3818 emit_insn (gen_movdf_cc_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
3822 emit_insn (gen_movdf_cc_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
3823 emit_insn (gen_movdf_cc_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
3827 [(set_attr "length" "2")])
3829 (define_insn "*movqi_cc_reg_sp64"
3830 [(set (match_operand:QI 0 "register_operand" "=r,r")
3831 (if_then_else:QI (match_operator 1 "v9_regcmp_op"
3832 [(match_operand:DI 2 "register_operand" "r,r")
3834 (match_operand:QI 3 "arith10_operand" "rM,0")
3835 (match_operand:QI 4 "arith10_operand" "0,rM")))]
3838 movr%D1\t%2, %r3, %0
3839 movr%d1\t%2, %r4, %0"
3840 [(set_attr "type" "cmove")])
3842 (define_insn "*movhi_cc_reg_sp64"
3843 [(set (match_operand:HI 0 "register_operand" "=r,r")
3844 (if_then_else:HI (match_operator 1 "v9_regcmp_op"
3845 [(match_operand:DI 2 "register_operand" "r,r")
3847 (match_operand:HI 3 "arith10_operand" "rM,0")
3848 (match_operand:HI 4 "arith10_operand" "0,rM")))]
3851 movr%D1\t%2, %r3, %0
3852 movr%d1\t%2, %r4, %0"
3853 [(set_attr "type" "cmove")])
3855 (define_insn "*movsi_cc_reg_sp64"
3856 [(set (match_operand:SI 0 "register_operand" "=r,r")
3857 (if_then_else:SI (match_operator 1 "v9_regcmp_op"
3858 [(match_operand:DI 2 "register_operand" "r,r")
3860 (match_operand:SI 3 "arith10_operand" "rM,0")
3861 (match_operand:SI 4 "arith10_operand" "0,rM")))]
3864 movr%D1\t%2, %r3, %0
3865 movr%d1\t%2, %r4, %0"
3866 [(set_attr "type" "cmove")])
3868 ;; ??? The constraints of operands 3,4 need work.
3869 (define_insn "*movdi_cc_reg_sp64"
3870 [(set (match_operand:DI 0 "register_operand" "=r,r")
3871 (if_then_else:DI (match_operator 1 "v9_regcmp_op"
3872 [(match_operand:DI 2 "register_operand" "r,r")
3874 (match_operand:DI 3 "arith10_double_operand" "rMH,0")
3875 (match_operand:DI 4 "arith10_double_operand" "0,rMH")))]
3878 movr%D1\t%2, %r3, %0
3879 movr%d1\t%2, %r4, %0"
3880 [(set_attr "type" "cmove")])
3882 (define_insn "*movdi_cc_reg_sp64_trunc"
3883 [(set (match_operand:SI 0 "register_operand" "=r,r")
3884 (if_then_else:SI (match_operator 1 "v9_regcmp_op"
3885 [(match_operand:DI 2 "register_operand" "r,r")
3887 (match_operand:SI 3 "arith10_double_operand" "rMH,0")
3888 (match_operand:SI 4 "arith10_double_operand" "0,rMH")))]
3891 movr%D1\t%2, %r3, %0
3892 movr%d1\t%2, %r4, %0"
3893 [(set_attr "type" "cmove")])
3895 (define_insn "*movsf_cc_reg_sp64"
3896 [(set (match_operand:SF 0 "register_operand" "=f,f")
3897 (if_then_else:SF (match_operator 1 "v9_regcmp_op"
3898 [(match_operand:DI 2 "register_operand" "r,r")
3900 (match_operand:SF 3 "register_operand" "f,0")
3901 (match_operand:SF 4 "register_operand" "0,f")))]
3902 "TARGET_ARCH64 && TARGET_FPU"
3904 fmovrs%D1\t%2, %3, %0
3905 fmovrs%d1\t%2, %4, %0"
3906 [(set_attr "type" "fpcrmove")])
3908 (define_insn "movdf_cc_reg_sp64"
3909 [(set (match_operand:DF 0 "register_operand" "=e,e")
3910 (if_then_else:DF (match_operator 1 "v9_regcmp_op"
3911 [(match_operand:DI 2 "register_operand" "r,r")
3913 (match_operand:DF 3 "register_operand" "e,0")
3914 (match_operand:DF 4 "register_operand" "0,e")))]
3915 "TARGET_ARCH64 && TARGET_FPU"
3917 fmovrd%D1\t%2, %3, %0
3918 fmovrd%d1\t%2, %4, %0"
3919 [(set_attr "type" "fpcrmove")
3920 (set_attr "fptype" "double")])
3922 (define_insn "*movtf_cc_reg_hq_sp64"
3923 [(set (match_operand:TF 0 "register_operand" "=e,e")
3924 (if_then_else:TF (match_operator 1 "v9_regcmp_op"
3925 [(match_operand:DI 2 "register_operand" "r,r")
3927 (match_operand:TF 3 "register_operand" "e,0")
3928 (match_operand:TF 4 "register_operand" "0,e")))]
3929 "TARGET_ARCH64 && TARGET_FPU && TARGET_HARD_QUAD"
3931 fmovrq%D1\t%2, %3, %0
3932 fmovrq%d1\t%2, %4, %0"
3933 [(set_attr "type" "fpcrmove")])
3935 (define_insn_and_split "*movtf_cc_reg_sp64"
3936 [(set (match_operand:TF 0 "register_operand" "=e,e")
3937 (if_then_else:TF (match_operator 1 "v9_regcmp_op"
3938 [(match_operand:DI 2 "register_operand" "r,r")
3940 (match_operand:TF 3 "register_operand" "e,0")
3941 (match_operand:TF 4 "register_operand" "0,e")))]
3942 "TARGET_ARCH64 && TARGET_FPU && ! TARGET_HARD_QUAD"
3944 "&& reload_completed"
3945 [(clobber (const_int 0))]
3947 rtx set_dest = operands[0];
3948 rtx set_srca = operands[3];
3949 rtx set_srcb = operands[4];
3950 int third = rtx_equal_p (set_dest, set_srca);
3952 rtx srca1, srca2, srcb1, srcb2;
3954 dest1 = gen_df_reg (set_dest, 0);
3955 dest2 = gen_df_reg (set_dest, 1);
3956 srca1 = gen_df_reg (set_srca, 0);
3957 srca2 = gen_df_reg (set_srca, 1);
3958 srcb1 = gen_df_reg (set_srcb, 0);
3959 srcb2 = gen_df_reg (set_srcb, 1);
3961 /* Now emit using the real source and destination we found, swapping
3962 the order if we detect overlap. */
3963 if ((third && reg_overlap_mentioned_p (dest1, srcb2))
3964 || (!third && reg_overlap_mentioned_p (dest1, srca2)))
3966 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
3967 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
3971 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
3972 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
3976 [(set_attr "length" "2")])
3979 ;;- zero extension instructions
3981 ;; These patterns originally accepted general_operands, however, slightly
3982 ;; better code is generated by only accepting register_operands, and then
3983 ;; letting combine generate the ldu[hb] insns.
3985 (define_expand "zero_extendhisi2"
3986 [(set (match_operand:SI 0 "register_operand" "")
3987 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
3990 rtx temp = gen_reg_rtx (SImode);
3991 rtx shift_16 = GEN_INT (16);
3992 int op1_subbyte = 0;
3994 if (GET_CODE (operand1) == SUBREG)
3996 op1_subbyte = SUBREG_BYTE (operand1);
3997 op1_subbyte /= GET_MODE_SIZE (SImode);
3998 op1_subbyte *= GET_MODE_SIZE (SImode);
3999 operand1 = XEXP (operand1, 0);
4002 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4004 emit_insn (gen_lshrsi3 (operand0, temp, shift_16));
4008 (define_insn "*zero_extendhisi2_insn"
4009 [(set (match_operand:SI 0 "register_operand" "=r")
4010 (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
4013 [(set_attr "type" "load")
4014 (set_attr "us3load_type" "3cycle")])
4016 (define_expand "zero_extendqihi2"
4017 [(set (match_operand:HI 0 "register_operand" "")
4018 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
4022 (define_insn "*zero_extendqihi2_insn"
4023 [(set (match_operand:HI 0 "register_operand" "=r,r")
4024 (zero_extend:HI (match_operand:QI 1 "input_operand" "r,m")))]
4025 "GET_CODE (operands[1]) != CONST_INT"
4029 [(set_attr "type" "*,load")
4030 (set_attr "us3load_type" "*,3cycle")])
4032 (define_expand "zero_extendqisi2"
4033 [(set (match_operand:SI 0 "register_operand" "")
4034 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
4038 (define_insn "*zero_extendqisi2_insn"
4039 [(set (match_operand:SI 0 "register_operand" "=r,r")
4040 (zero_extend:SI (match_operand:QI 1 "input_operand" "r,m")))]
4041 "GET_CODE (operands[1]) != CONST_INT"
4045 [(set_attr "type" "*,load")
4046 (set_attr "us3load_type" "*,3cycle")])
4048 (define_expand "zero_extendqidi2"
4049 [(set (match_operand:DI 0 "register_operand" "")
4050 (zero_extend:DI (match_operand:QI 1 "register_operand" "")))]
4054 (define_insn "*zero_extendqidi2_insn"
4055 [(set (match_operand:DI 0 "register_operand" "=r,r")
4056 (zero_extend:DI (match_operand:QI 1 "input_operand" "r,m")))]
4057 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
4061 [(set_attr "type" "*,load")
4062 (set_attr "us3load_type" "*,3cycle")])
4064 (define_expand "zero_extendhidi2"
4065 [(set (match_operand:DI 0 "register_operand" "")
4066 (zero_extend:DI (match_operand:HI 1 "register_operand" "")))]
4069 rtx temp = gen_reg_rtx (DImode);
4070 rtx shift_48 = GEN_INT (48);
4071 int op1_subbyte = 0;
4073 if (GET_CODE (operand1) == SUBREG)
4075 op1_subbyte = SUBREG_BYTE (operand1);
4076 op1_subbyte /= GET_MODE_SIZE (DImode);
4077 op1_subbyte *= GET_MODE_SIZE (DImode);
4078 operand1 = XEXP (operand1, 0);
4081 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
4083 emit_insn (gen_lshrdi3 (operand0, temp, shift_48));
4087 (define_insn "*zero_extendhidi2_insn"
4088 [(set (match_operand:DI 0 "register_operand" "=r")
4089 (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
4092 [(set_attr "type" "load")
4093 (set_attr "us3load_type" "3cycle")])
4096 ;; ??? Write truncdisi pattern using sra?
4098 (define_expand "zero_extendsidi2"
4099 [(set (match_operand:DI 0 "register_operand" "")
4100 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
4104 (define_insn "*zero_extendsidi2_insn_sp64"
4105 [(set (match_operand:DI 0 "register_operand" "=r,r")
4106 (zero_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
4107 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
4111 [(set_attr "type" "shift,load")])
4113 (define_insn_and_split "*zero_extendsidi2_insn_sp32"
4114 [(set (match_operand:DI 0 "register_operand" "=r")
4115 (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
4118 "&& reload_completed"
4119 [(set (match_dup 2) (match_dup 3))
4120 (set (match_dup 4) (match_dup 5))]
4124 dest1 = gen_highpart (SImode, operands[0]);
4125 dest2 = gen_lowpart (SImode, operands[0]);
4127 /* Swap the order in case of overlap. */
4128 if (REGNO (dest1) == REGNO (operands[1]))
4130 operands[2] = dest2;
4131 operands[3] = operands[1];
4132 operands[4] = dest1;
4133 operands[5] = const0_rtx;
4137 operands[2] = dest1;
4138 operands[3] = const0_rtx;
4139 operands[4] = dest2;
4140 operands[5] = operands[1];
4143 [(set_attr "length" "2")])
4145 ;; Simplify comparisons of extended values.
4147 (define_insn "*cmp_zero_extendqisi2"
4149 (compare:CC (zero_extend:SI (match_operand:QI 0 "register_operand" "r"))
4152 "andcc\t%0, 0xff, %%g0"
4153 [(set_attr "type" "compare")])
4155 (define_insn "*cmp_zero_qi"
4157 (compare:CC (match_operand:QI 0 "register_operand" "r")
4160 "andcc\t%0, 0xff, %%g0"
4161 [(set_attr "type" "compare")])
4163 (define_insn "*cmp_zero_extendqisi2_set"
4165 (compare:CC (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
4167 (set (match_operand:SI 0 "register_operand" "=r")
4168 (zero_extend:SI (match_dup 1)))]
4170 "andcc\t%1, 0xff, %0"
4171 [(set_attr "type" "compare")])
4173 (define_insn "*cmp_zero_extendqisi2_andcc_set"
4175 (compare:CC (and:SI (match_operand:SI 1 "register_operand" "r")
4178 (set (match_operand:SI 0 "register_operand" "=r")
4179 (zero_extend:SI (subreg:QI (match_dup 1) 0)))]
4181 "andcc\t%1, 0xff, %0"
4182 [(set_attr "type" "compare")])
4184 (define_insn "*cmp_zero_extendqidi2"
4186 (compare:CCX (zero_extend:DI (match_operand:QI 0 "register_operand" "r"))
4189 "andcc\t%0, 0xff, %%g0"
4190 [(set_attr "type" "compare")])
4192 (define_insn "*cmp_zero_qi_sp64"
4194 (compare:CCX (match_operand:QI 0 "register_operand" "r")
4197 "andcc\t%0, 0xff, %%g0"
4198 [(set_attr "type" "compare")])
4200 (define_insn "*cmp_zero_extendqidi2_set"
4202 (compare:CCX (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
4204 (set (match_operand:DI 0 "register_operand" "=r")
4205 (zero_extend:DI (match_dup 1)))]
4207 "andcc\t%1, 0xff, %0"
4208 [(set_attr "type" "compare")])
4210 (define_insn "*cmp_zero_extendqidi2_andcc_set"
4212 (compare:CCX (and:DI (match_operand:DI 1 "register_operand" "r")
4215 (set (match_operand:DI 0 "register_operand" "=r")
4216 (zero_extend:DI (subreg:QI (match_dup 1) 0)))]
4218 "andcc\t%1, 0xff, %0"
4219 [(set_attr "type" "compare")])
4221 ;; Similarly, handle {SI,DI}->QI mode truncation followed by a compare.
4223 (define_insn "*cmp_siqi_trunc"
4225 (compare:CC (subreg:QI (match_operand:SI 0 "register_operand" "r") 3)
4228 "andcc\t%0, 0xff, %%g0"
4229 [(set_attr "type" "compare")])
4231 (define_insn "*cmp_siqi_trunc_set"
4233 (compare:CC (subreg:QI (match_operand:SI 1 "register_operand" "r") 3)
4235 (set (match_operand:QI 0 "register_operand" "=r")
4236 (subreg:QI (match_dup 1) 3))]
4238 "andcc\t%1, 0xff, %0"
4239 [(set_attr "type" "compare")])
4241 (define_insn "*cmp_diqi_trunc"
4243 (compare:CC (subreg:QI (match_operand:DI 0 "register_operand" "r") 7)
4246 "andcc\t%0, 0xff, %%g0"
4247 [(set_attr "type" "compare")])
4249 (define_insn "*cmp_diqi_trunc_set"
4251 (compare:CC (subreg:QI (match_operand:DI 1 "register_operand" "r") 7)
4253 (set (match_operand:QI 0 "register_operand" "=r")
4254 (subreg:QI (match_dup 1) 7))]
4256 "andcc\t%1, 0xff, %0"
4257 [(set_attr "type" "compare")])
4259 ;;- sign extension instructions
4261 ;; These patterns originally accepted general_operands, however, slightly
4262 ;; better code is generated by only accepting register_operands, and then
4263 ;; letting combine generate the lds[hb] insns.
4265 (define_expand "extendhisi2"
4266 [(set (match_operand:SI 0 "register_operand" "")
4267 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
4270 rtx temp = gen_reg_rtx (SImode);
4271 rtx shift_16 = GEN_INT (16);
4272 int op1_subbyte = 0;
4274 if (GET_CODE (operand1) == SUBREG)
4276 op1_subbyte = SUBREG_BYTE (operand1);
4277 op1_subbyte /= GET_MODE_SIZE (SImode);
4278 op1_subbyte *= GET_MODE_SIZE (SImode);
4279 operand1 = XEXP (operand1, 0);
4282 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4284 emit_insn (gen_ashrsi3 (operand0, temp, shift_16));
4288 (define_insn "*sign_extendhisi2_insn"
4289 [(set (match_operand:SI 0 "register_operand" "=r")
4290 (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
4293 [(set_attr "type" "sload")
4294 (set_attr "us3load_type" "3cycle")])
4296 (define_expand "extendqihi2"
4297 [(set (match_operand:HI 0 "register_operand" "")
4298 (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
4301 rtx temp = gen_reg_rtx (SImode);
4302 rtx shift_24 = GEN_INT (24);
4303 int op1_subbyte = 0;
4304 int op0_subbyte = 0;
4306 if (GET_CODE (operand1) == SUBREG)
4308 op1_subbyte = SUBREG_BYTE (operand1);
4309 op1_subbyte /= GET_MODE_SIZE (SImode);
4310 op1_subbyte *= GET_MODE_SIZE (SImode);
4311 operand1 = XEXP (operand1, 0);
4313 if (GET_CODE (operand0) == SUBREG)
4315 op0_subbyte = SUBREG_BYTE (operand0);
4316 op0_subbyte /= GET_MODE_SIZE (SImode);
4317 op0_subbyte *= GET_MODE_SIZE (SImode);
4318 operand0 = XEXP (operand0, 0);
4320 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4322 if (GET_MODE (operand0) != SImode)
4323 operand0 = gen_rtx_SUBREG (SImode, operand0, op0_subbyte);
4324 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
4328 (define_insn "*sign_extendqihi2_insn"
4329 [(set (match_operand:HI 0 "register_operand" "=r")
4330 (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
4333 [(set_attr "type" "sload")
4334 (set_attr "us3load_type" "3cycle")])
4336 (define_expand "extendqisi2"
4337 [(set (match_operand:SI 0 "register_operand" "")
4338 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
4341 rtx temp = gen_reg_rtx (SImode);
4342 rtx shift_24 = GEN_INT (24);
4343 int op1_subbyte = 0;
4345 if (GET_CODE (operand1) == SUBREG)
4347 op1_subbyte = SUBREG_BYTE (operand1);
4348 op1_subbyte /= GET_MODE_SIZE (SImode);
4349 op1_subbyte *= GET_MODE_SIZE (SImode);
4350 operand1 = XEXP (operand1, 0);
4353 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4355 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
4359 (define_insn "*sign_extendqisi2_insn"
4360 [(set (match_operand:SI 0 "register_operand" "=r")
4361 (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
4364 [(set_attr "type" "sload")
4365 (set_attr "us3load_type" "3cycle")])
4367 (define_expand "extendqidi2"
4368 [(set (match_operand:DI 0 "register_operand" "")
4369 (sign_extend:DI (match_operand:QI 1 "register_operand" "")))]
4372 rtx temp = gen_reg_rtx (DImode);
4373 rtx shift_56 = GEN_INT (56);
4374 int op1_subbyte = 0;
4376 if (GET_CODE (operand1) == SUBREG)
4378 op1_subbyte = SUBREG_BYTE (operand1);
4379 op1_subbyte /= GET_MODE_SIZE (DImode);
4380 op1_subbyte *= GET_MODE_SIZE (DImode);
4381 operand1 = XEXP (operand1, 0);
4384 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
4386 emit_insn (gen_ashrdi3 (operand0, temp, shift_56));
4390 (define_insn "*sign_extendqidi2_insn"
4391 [(set (match_operand:DI 0 "register_operand" "=r")
4392 (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
4395 [(set_attr "type" "sload")
4396 (set_attr "us3load_type" "3cycle")])
4398 (define_expand "extendhidi2"
4399 [(set (match_operand:DI 0 "register_operand" "")
4400 (sign_extend:DI (match_operand:HI 1 "register_operand" "")))]
4403 rtx temp = gen_reg_rtx (DImode);
4404 rtx shift_48 = GEN_INT (48);
4405 int op1_subbyte = 0;
4407 if (GET_CODE (operand1) == SUBREG)
4409 op1_subbyte = SUBREG_BYTE (operand1);
4410 op1_subbyte /= GET_MODE_SIZE (DImode);
4411 op1_subbyte *= GET_MODE_SIZE (DImode);
4412 operand1 = XEXP (operand1, 0);
4415 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
4417 emit_insn (gen_ashrdi3 (operand0, temp, shift_48));
4421 (define_insn "*sign_extendhidi2_insn"
4422 [(set (match_operand:DI 0 "register_operand" "=r")
4423 (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
4426 [(set_attr "type" "sload")
4427 (set_attr "us3load_type" "3cycle")])
4429 (define_expand "extendsidi2"
4430 [(set (match_operand:DI 0 "register_operand" "")
4431 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
4435 (define_insn "*sign_extendsidi2_insn"
4436 [(set (match_operand:DI 0 "register_operand" "=r,r")
4437 (sign_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
4442 [(set_attr "type" "shift,sload")
4443 (set_attr "us3load_type" "*,3cycle")])
4445 ;; Special pattern for optimizing bit-field compares. This is needed
4446 ;; because combine uses this as a canonical form.
4448 (define_insn "*cmp_zero_extract"
4451 (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
4452 (match_operand:SI 1 "small_int_or_double" "n")
4453 (match_operand:SI 2 "small_int_or_double" "n"))
4455 "(GET_CODE (operands[2]) == CONST_INT
4456 && INTVAL (operands[2]) > 19)
4457 || (GET_CODE (operands[2]) == CONST_DOUBLE
4458 && CONST_DOUBLE_LOW (operands[2]) > 19)"
4460 int len = (GET_CODE (operands[1]) == CONST_INT
4461 ? INTVAL (operands[1])
4462 : CONST_DOUBLE_LOW (operands[1]));
4464 (GET_CODE (operands[2]) == CONST_INT
4465 ? INTVAL (operands[2])
4466 : CONST_DOUBLE_LOW (operands[2])) - len;
4467 HOST_WIDE_INT mask = ((1 << len) - 1) << pos;
4469 operands[1] = GEN_INT (mask);
4470 return "andcc\t%0, %1, %%g0";
4472 [(set_attr "type" "compare")])
4474 (define_insn "*cmp_zero_extract_sp64"
4477 (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
4478 (match_operand:SI 1 "small_int_or_double" "n")
4479 (match_operand:SI 2 "small_int_or_double" "n"))
4482 && ((GET_CODE (operands[2]) == CONST_INT
4483 && INTVAL (operands[2]) > 51)
4484 || (GET_CODE (operands[2]) == CONST_DOUBLE
4485 && CONST_DOUBLE_LOW (operands[2]) > 51))"
4487 int len = (GET_CODE (operands[1]) == CONST_INT
4488 ? INTVAL (operands[1])
4489 : CONST_DOUBLE_LOW (operands[1]));
4491 (GET_CODE (operands[2]) == CONST_INT
4492 ? INTVAL (operands[2])
4493 : CONST_DOUBLE_LOW (operands[2])) - len;
4494 HOST_WIDE_INT mask = (((unsigned HOST_WIDE_INT) 1 << len) - 1) << pos;
4496 operands[1] = GEN_INT (mask);
4497 return "andcc\t%0, %1, %%g0";
4499 [(set_attr "type" "compare")])
4501 ;; Conversions between float, double and long double.
4503 (define_insn "extendsfdf2"
4504 [(set (match_operand:DF 0 "register_operand" "=e")
4506 (match_operand:SF 1 "register_operand" "f")))]
4509 [(set_attr "type" "fp")
4510 (set_attr "fptype" "double")])
4512 (define_expand "extendsftf2"
4513 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4515 (match_operand:SF 1 "register_operand" "")))]
4516 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4517 "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
4519 (define_insn "*extendsftf2_hq"
4520 [(set (match_operand:TF 0 "register_operand" "=e")
4522 (match_operand:SF 1 "register_operand" "f")))]
4523 "TARGET_FPU && TARGET_HARD_QUAD"
4525 [(set_attr "type" "fp")])
4527 (define_expand "extenddftf2"
4528 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4530 (match_operand:DF 1 "register_operand" "")))]
4531 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4532 "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
4534 (define_insn "*extenddftf2_hq"
4535 [(set (match_operand:TF 0 "register_operand" "=e")
4537 (match_operand:DF 1 "register_operand" "e")))]
4538 "TARGET_FPU && TARGET_HARD_QUAD"
4540 [(set_attr "type" "fp")])
4542 (define_insn "truncdfsf2"
4543 [(set (match_operand:SF 0 "register_operand" "=f")
4545 (match_operand:DF 1 "register_operand" "e")))]
4548 [(set_attr "type" "fp")
4549 (set_attr "fptype" "double")])
4551 (define_expand "trunctfsf2"
4552 [(set (match_operand:SF 0 "register_operand" "")
4554 (match_operand:TF 1 "general_operand" "")))]
4555 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4556 "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
4558 (define_insn "*trunctfsf2_hq"
4559 [(set (match_operand:SF 0 "register_operand" "=f")
4561 (match_operand:TF 1 "register_operand" "e")))]
4562 "TARGET_FPU && TARGET_HARD_QUAD"
4564 [(set_attr "type" "fp")])
4566 (define_expand "trunctfdf2"
4567 [(set (match_operand:DF 0 "register_operand" "")
4569 (match_operand:TF 1 "general_operand" "")))]
4570 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4571 "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
4573 (define_insn "*trunctfdf2_hq"
4574 [(set (match_operand:DF 0 "register_operand" "=e")
4576 (match_operand:TF 1 "register_operand" "e")))]
4577 "TARGET_FPU && TARGET_HARD_QUAD"
4579 [(set_attr "type" "fp")])
4581 ;; Conversion between fixed point and floating point.
4583 (define_insn "floatsisf2"
4584 [(set (match_operand:SF 0 "register_operand" "=f")
4585 (float:SF (match_operand:SI 1 "register_operand" "f")))]
4588 [(set_attr "type" "fp")
4589 (set_attr "fptype" "double")])
4591 (define_insn "floatsidf2"
4592 [(set (match_operand:DF 0 "register_operand" "=e")
4593 (float:DF (match_operand:SI 1 "register_operand" "f")))]
4596 [(set_attr "type" "fp")
4597 (set_attr "fptype" "double")])
4599 (define_expand "floatsitf2"
4600 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4601 (float:TF (match_operand:SI 1 "register_operand" "")))]
4602 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4603 "emit_tfmode_cvt (FLOAT, operands); DONE;")
4605 (define_insn "*floatsitf2_hq"
4606 [(set (match_operand:TF 0 "register_operand" "=e")
4607 (float:TF (match_operand:SI 1 "register_operand" "f")))]
4608 "TARGET_FPU && TARGET_HARD_QUAD"
4610 [(set_attr "type" "fp")])
4612 (define_expand "floatunssitf2"
4613 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4614 (unsigned_float:TF (match_operand:SI 1 "register_operand" "")))]
4615 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4616 "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
4618 ;; Now the same for 64 bit sources.
4620 (define_insn "floatdisf2"
4621 [(set (match_operand:SF 0 "register_operand" "=f")
4622 (float:SF (match_operand:DI 1 "register_operand" "e")))]
4623 "TARGET_V9 && TARGET_FPU"
4625 [(set_attr "type" "fp")
4626 (set_attr "fptype" "double")])
4628 (define_expand "floatunsdisf2"
4629 [(use (match_operand:SF 0 "register_operand" ""))
4630 (use (match_operand:DI 1 "register_operand" ""))]
4631 "TARGET_ARCH64 && TARGET_FPU"
4632 "sparc_emit_floatunsdi (operands); DONE;")
4634 (define_insn "floatdidf2"
4635 [(set (match_operand:DF 0 "register_operand" "=e")
4636 (float:DF (match_operand:DI 1 "register_operand" "e")))]
4637 "TARGET_V9 && TARGET_FPU"
4639 [(set_attr "type" "fp")
4640 (set_attr "fptype" "double")])
4642 (define_expand "floatunsdidf2"
4643 [(use (match_operand:DF 0 "register_operand" ""))
4644 (use (match_operand:DI 1 "register_operand" ""))]
4645 "TARGET_ARCH64 && TARGET_FPU"
4646 "sparc_emit_floatunsdi (operands); DONE;")
4648 (define_expand "floatditf2"
4649 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4650 (float:TF (match_operand:DI 1 "register_operand" "")))]
4651 "TARGET_FPU && TARGET_V9 && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4652 "emit_tfmode_cvt (FLOAT, operands); DONE;")
4654 (define_insn "*floatditf2_hq"
4655 [(set (match_operand:TF 0 "register_operand" "=e")
4656 (float:TF (match_operand:DI 1 "register_operand" "e")))]
4657 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
4659 [(set_attr "type" "fp")])
4661 (define_expand "floatunsditf2"
4662 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4663 (unsigned_float:TF (match_operand:DI 1 "register_operand" "")))]
4664 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4665 "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
4667 ;; Convert a float to an actual integer.
4668 ;; Truncation is performed as part of the conversion.
4670 (define_insn "fix_truncsfsi2"
4671 [(set (match_operand:SI 0 "register_operand" "=f")
4672 (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
4675 [(set_attr "type" "fp")
4676 (set_attr "fptype" "double")])
4678 (define_insn "fix_truncdfsi2"
4679 [(set (match_operand:SI 0 "register_operand" "=f")
4680 (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
4683 [(set_attr "type" "fp")
4684 (set_attr "fptype" "double")])
4686 (define_expand "fix_trunctfsi2"
4687 [(set (match_operand:SI 0 "register_operand" "")
4688 (fix:SI (match_operand:TF 1 "general_operand" "")))]
4689 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4690 "emit_tfmode_cvt (FIX, operands); DONE;")
4692 (define_insn "*fix_trunctfsi2_hq"
4693 [(set (match_operand:SI 0 "register_operand" "=f")
4694 (fix:SI (match_operand:TF 1 "register_operand" "e")))]
4695 "TARGET_FPU && TARGET_HARD_QUAD"
4697 [(set_attr "type" "fp")])
4699 (define_expand "fixuns_trunctfsi2"
4700 [(set (match_operand:SI 0 "register_operand" "")
4701 (unsigned_fix:SI (match_operand:TF 1 "general_operand" "")))]
4702 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4703 "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
4705 ;; Now the same, for V9 targets
4707 (define_insn "fix_truncsfdi2"
4708 [(set (match_operand:DI 0 "register_operand" "=e")
4709 (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
4710 "TARGET_V9 && TARGET_FPU"
4712 [(set_attr "type" "fp")
4713 (set_attr "fptype" "double")])
4715 (define_insn "fix_truncdfdi2"
4716 [(set (match_operand:DI 0 "register_operand" "=e")
4717 (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
4718 "TARGET_V9 && TARGET_FPU"
4720 [(set_attr "type" "fp")
4721 (set_attr "fptype" "double")])
4723 (define_expand "fix_trunctfdi2"
4724 [(set (match_operand:DI 0 "register_operand" "")
4725 (fix:DI (match_operand:TF 1 "general_operand" "")))]
4726 "TARGET_V9 && TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4727 "emit_tfmode_cvt (FIX, operands); DONE;")
4729 (define_insn "*fix_trunctfdi2_hq"
4730 [(set (match_operand:DI 0 "register_operand" "=e")
4731 (fix:DI (match_operand:TF 1 "register_operand" "e")))]
4732 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
4734 [(set_attr "type" "fp")])
4736 (define_expand "fixuns_trunctfdi2"
4737 [(set (match_operand:DI 0 "register_operand" "")
4738 (unsigned_fix:DI (match_operand:TF 1 "general_operand" "")))]
4739 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4740 "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
4742 ;;- arithmetic instructions
4744 (define_expand "adddi3"
4745 [(set (match_operand:DI 0 "register_operand" "=r")
4746 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
4747 (match_operand:DI 2 "arith_double_add_operand" "rHI")))]
4752 if (! TARGET_ARCH64)
4754 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
4755 gen_rtx_SET (VOIDmode, operands[0],
4756 gen_rtx_PLUS (DImode, operands[1],
4758 gen_rtx_CLOBBER (VOIDmode,
4759 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
4762 if (arith_double_4096_operand(operands[2], DImode))
4764 switch (GET_CODE (operands[1]))
4766 case CONST_INT: i = INTVAL (operands[1]); break;
4767 case CONST_DOUBLE: i = CONST_DOUBLE_LOW (operands[1]); break;
4769 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
4770 gen_rtx_MINUS (DImode, operands[1],
4774 emit_insn (gen_movdi (operands[0], GEN_INT (i + 4096)));
4779 (define_insn_and_split "adddi3_insn_sp32"
4780 [(set (match_operand:DI 0 "register_operand" "=r")
4781 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
4782 (match_operand:DI 2 "arith_double_operand" "rHI")))
4783 (clobber (reg:CC 100))]
4786 "&& reload_completed"
4787 [(parallel [(set (reg:CC_NOOV 100)
4788 (compare:CC_NOOV (plus:SI (match_dup 4)
4792 (plus:SI (match_dup 4) (match_dup 5)))])
4794 (plus:SI (plus:SI (match_dup 7)
4796 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4798 operands[3] = gen_lowpart (SImode, operands[0]);
4799 operands[4] = gen_lowpart (SImode, operands[1]);
4800 operands[5] = gen_lowpart (SImode, operands[2]);
4801 operands[6] = gen_highpart (SImode, operands[0]);
4802 operands[7] = gen_highpart_mode (SImode, DImode, operands[1]);
4803 #if HOST_BITS_PER_WIDE_INT == 32
4804 if (GET_CODE (operands[2]) == CONST_INT)
4806 if (INTVAL (operands[2]) < 0)
4807 operands[8] = constm1_rtx;
4809 operands[8] = const0_rtx;
4813 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
4815 [(set_attr "length" "2")])
4818 [(set (match_operand:DI 0 "register_operand" "")
4819 (minus:DI (match_operand:DI 1 "arith_double_operand" "")
4820 (match_operand:DI 2 "arith_double_operand" "")))
4821 (clobber (reg:CC 100))]
4822 "! TARGET_ARCH64 && reload_completed"
4823 [(parallel [(set (reg:CC_NOOV 100)
4824 (compare:CC_NOOV (minus:SI (match_dup 4)
4828 (minus:SI (match_dup 4) (match_dup 5)))])
4830 (minus:SI (minus:SI (match_dup 7)
4832 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4834 operands[3] = gen_lowpart (SImode, operands[0]);
4835 operands[4] = gen_lowpart (SImode, operands[1]);
4836 operands[5] = gen_lowpart (SImode, operands[2]);
4837 operands[6] = gen_highpart (SImode, operands[0]);
4838 operands[7] = gen_highpart (SImode, operands[1]);
4839 #if HOST_BITS_PER_WIDE_INT == 32
4840 if (GET_CODE (operands[2]) == CONST_INT)
4842 if (INTVAL (operands[2]) < 0)
4843 operands[8] = constm1_rtx;
4845 operands[8] = const0_rtx;
4849 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
4852 ;; LTU here means "carry set"
4854 [(set (match_operand:SI 0 "register_operand" "=r")
4855 (plus:SI (plus:SI (match_operand:SI 1 "arith_operand" "%r")
4856 (match_operand:SI 2 "arith_operand" "rI"))
4857 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4860 [(set_attr "type" "ialuX")])
4862 (define_insn_and_split "*addx_extend_sp32"
4863 [(set (match_operand:DI 0 "register_operand" "=r")
4864 (zero_extend:DI (plus:SI (plus:SI
4865 (match_operand:SI 1 "reg_or_0_operand" "%rJ")
4866 (match_operand:SI 2 "arith_operand" "rI"))
4867 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4870 "&& reload_completed"
4871 [(set (match_dup 3) (plus:SI (plus:SI (match_dup 1) (match_dup 2))
4872 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
4873 (set (match_dup 4) (const_int 0))]
4874 "operands[3] = gen_lowpart (SImode, operands[0]);
4875 operands[4] = gen_highpart_mode (SImode, DImode, operands[1]);"
4876 [(set_attr "length" "2")])
4878 (define_insn "*addx_extend_sp64"
4879 [(set (match_operand:DI 0 "register_operand" "=r")
4880 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
4881 (match_operand:SI 2 "arith_operand" "rI"))
4882 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4885 [(set_attr "type" "ialuX")])
4888 [(set (match_operand:SI 0 "register_operand" "=r")
4889 (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
4890 (match_operand:SI 2 "arith_operand" "rI"))
4891 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4894 [(set_attr "type" "ialuX")])
4896 (define_insn "*subx_extend_sp64"
4897 [(set (match_operand:DI 0 "register_operand" "=r")
4898 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
4899 (match_operand:SI 2 "arith_operand" "rI"))
4900 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4903 [(set_attr "type" "ialuX")])
4905 (define_insn_and_split "*subx_extend"
4906 [(set (match_operand:DI 0 "register_operand" "=r")
4907 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
4908 (match_operand:SI 2 "arith_operand" "rI"))
4909 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4912 "&& reload_completed"
4913 [(set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 2))
4914 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
4915 (set (match_dup 4) (const_int 0))]
4916 "operands[3] = gen_lowpart (SImode, operands[0]);
4917 operands[4] = gen_highpart (SImode, operands[0]);"
4918 [(set_attr "length" "2")])
4920 (define_insn_and_split ""
4921 [(set (match_operand:DI 0 "register_operand" "=r")
4922 (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4923 (match_operand:DI 2 "register_operand" "r")))
4924 (clobber (reg:CC 100))]
4927 "&& reload_completed"
4928 [(parallel [(set (reg:CC_NOOV 100)
4929 (compare:CC_NOOV (plus:SI (match_dup 3) (match_dup 1))
4931 (set (match_dup 5) (plus:SI (match_dup 3) (match_dup 1)))])
4933 (plus:SI (plus:SI (match_dup 4) (const_int 0))
4934 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4935 "operands[3] = gen_lowpart (SImode, operands[2]);
4936 operands[4] = gen_highpart (SImode, operands[2]);
4937 operands[5] = gen_lowpart (SImode, operands[0]);
4938 operands[6] = gen_highpart (SImode, operands[0]);"
4939 [(set_attr "length" "2")])
4941 (define_insn "*adddi3_sp64"
4942 [(set (match_operand:DI 0 "register_operand" "=r")
4943 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
4944 (match_operand:DI 2 "arith_double_operand" "rHI")))]
4948 (define_expand "addsi3"
4949 [(set (match_operand:SI 0 "register_operand" "=r,d")
4950 (plus:SI (match_operand:SI 1 "arith_operand" "%r,d")
4951 (match_operand:SI 2 "arith_add_operand" "rI,d")))]
4954 if (arith_4096_operand(operands[2], SImode))
4956 if (GET_CODE (operands[1]) == CONST_INT)
4957 emit_insn (gen_movsi (operands[0],
4958 GEN_INT (INTVAL (operands[1]) + 4096)));
4960 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
4961 gen_rtx_MINUS (SImode, operands[1],
4967 (define_insn "*addsi3"
4968 [(set (match_operand:SI 0 "register_operand" "=r,d")
4969 (plus:SI (match_operand:SI 1 "arith_operand" "%r,d")
4970 (match_operand:SI 2 "arith_operand" "rI,d")))]
4974 fpadd32s\t%1, %2, %0"
4975 [(set_attr "type" "*,fp")])
4977 (define_insn "*cmp_cc_plus"
4978 [(set (reg:CC_NOOV 100)
4979 (compare:CC_NOOV (plus:SI (match_operand:SI 0 "arith_operand" "%r")
4980 (match_operand:SI 1 "arith_operand" "rI"))
4983 "addcc\t%0, %1, %%g0"
4984 [(set_attr "type" "compare")])
4986 (define_insn "*cmp_ccx_plus"
4987 [(set (reg:CCX_NOOV 100)
4988 (compare:CCX_NOOV (plus:DI (match_operand:DI 0 "arith_double_operand" "%r")
4989 (match_operand:DI 1 "arith_double_operand" "rHI"))
4992 "addcc\t%0, %1, %%g0"
4993 [(set_attr "type" "compare")])
4995 (define_insn "*cmp_cc_plus_set"
4996 [(set (reg:CC_NOOV 100)
4997 (compare:CC_NOOV (plus:SI (match_operand:SI 1 "arith_operand" "%r")
4998 (match_operand:SI 2 "arith_operand" "rI"))
5000 (set (match_operand:SI 0 "register_operand" "=r")
5001 (plus:SI (match_dup 1) (match_dup 2)))]
5004 [(set_attr "type" "compare")])
5006 (define_insn "*cmp_ccx_plus_set"
5007 [(set (reg:CCX_NOOV 100)
5008 (compare:CCX_NOOV (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
5009 (match_operand:DI 2 "arith_double_operand" "rHI"))
5011 (set (match_operand:DI 0 "register_operand" "=r")
5012 (plus:DI (match_dup 1) (match_dup 2)))]
5015 [(set_attr "type" "compare")])
5017 (define_expand "subdi3"
5018 [(set (match_operand:DI 0 "register_operand" "=r")
5019 (minus:DI (match_operand:DI 1 "register_operand" "r")
5020 (match_operand:DI 2 "arith_double_add_operand" "rHI")))]
5023 if (! TARGET_ARCH64)
5025 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
5026 gen_rtx_SET (VOIDmode, operands[0],
5027 gen_rtx_MINUS (DImode, operands[1],
5029 gen_rtx_CLOBBER (VOIDmode,
5030 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
5033 if (arith_double_4096_operand(operands[2], DImode))
5035 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
5036 gen_rtx_PLUS (DImode, operands[1],
5042 (define_insn_and_split "*subdi3_sp32"
5043 [(set (match_operand:DI 0 "register_operand" "=r")
5044 (minus:DI (match_operand:DI 1 "register_operand" "r")
5045 (match_operand:DI 2 "arith_double_operand" "rHI")))
5046 (clobber (reg:CC 100))]
5049 "&& reload_completed
5050 && (GET_CODE (operands[2]) == CONST_INT
5051 || GET_CODE (operands[2]) == CONST_DOUBLE)"
5052 [(clobber (const_int 0))]
5056 highp = gen_highpart_mode (SImode, DImode, operands[2]);
5057 lowp = gen_lowpart (SImode, operands[2]);
5058 if ((lowp == const0_rtx)
5059 && (operands[0] == operands[1]))
5061 emit_insn (gen_rtx_SET (VOIDmode,
5062 gen_highpart (SImode, operands[0]),
5063 gen_rtx_MINUS (SImode,
5064 gen_highpart_mode (SImode, DImode,
5070 emit_insn (gen_cmp_minus_cc_set (gen_lowpart (SImode, operands[0]),
5071 gen_lowpart (SImode, operands[1]),
5073 emit_insn (gen_subx (gen_highpart (SImode, operands[0]),
5074 gen_highpart_mode (SImode, DImode, operands[1]),
5079 [(set_attr "length" "2")])
5082 [(set (match_operand:DI 0 "register_operand" "")
5083 (minus:DI (match_operand:DI 1 "register_operand" "")
5084 (match_operand:DI 2 "register_operand" "")))
5085 (clobber (reg:CC 100))]
5087 && reload_completed"
5088 [(clobber (const_int 0))]
5090 emit_insn (gen_cmp_minus_cc_set (gen_lowpart (SImode, operands[0]),
5091 gen_lowpart (SImode, operands[1]),
5092 gen_lowpart (SImode, operands[2])));
5093 emit_insn (gen_subx (gen_highpart (SImode, operands[0]),
5094 gen_highpart (SImode, operands[1]),
5095 gen_highpart (SImode, operands[2])));
5099 (define_insn_and_split ""
5100 [(set (match_operand:DI 0 "register_operand" "=r")
5101 (minus:DI (match_operand:DI 1 "register_operand" "r")
5102 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))
5103 (clobber (reg:CC 100))]
5106 "&& reload_completed"
5107 [(parallel [(set (reg:CC_NOOV 100)
5108 (compare:CC_NOOV (minus:SI (match_dup 3) (match_dup 2))
5110 (set (match_dup 5) (minus:SI (match_dup 3) (match_dup 2)))])
5112 (minus:SI (minus:SI (match_dup 4) (const_int 0))
5113 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5114 "operands[3] = gen_lowpart (SImode, operands[1]);
5115 operands[4] = gen_highpart (SImode, operands[1]);
5116 operands[5] = gen_lowpart (SImode, operands[0]);
5117 operands[6] = gen_highpart (SImode, operands[0]);"
5118 [(set_attr "length" "2")])
5120 (define_insn "*subdi3_sp64"
5121 [(set (match_operand:DI 0 "register_operand" "=r")
5122 (minus:DI (match_operand:DI 1 "register_operand" "r")
5123 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5127 (define_expand "subsi3"
5128 [(set (match_operand:SI 0 "register_operand" "=r,d")
5129 (minus:SI (match_operand:SI 1 "register_operand" "r,d")
5130 (match_operand:SI 2 "arith_add_operand" "rI,d")))]
5133 if (arith_4096_operand(operands[2], SImode))
5135 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
5136 gen_rtx_PLUS (SImode, operands[1],
5142 (define_insn "*subsi3"
5143 [(set (match_operand:SI 0 "register_operand" "=r,d")
5144 (minus:SI (match_operand:SI 1 "register_operand" "r,d")
5145 (match_operand:SI 2 "arith_operand" "rI,d")))]
5149 fpsub32s\t%1, %2, %0"
5150 [(set_attr "type" "*,fp")])
5152 (define_insn "*cmp_minus_cc"
5153 [(set (reg:CC_NOOV 100)
5154 (compare:CC_NOOV (minus:SI (match_operand:SI 0 "reg_or_0_operand" "rJ")
5155 (match_operand:SI 1 "arith_operand" "rI"))
5158 "subcc\t%r0, %1, %%g0"
5159 [(set_attr "type" "compare")])
5161 (define_insn "*cmp_minus_ccx"
5162 [(set (reg:CCX_NOOV 100)
5163 (compare:CCX_NOOV (minus:DI (match_operand:DI 0 "register_operand" "r")
5164 (match_operand:DI 1 "arith_double_operand" "rHI"))
5167 "subcc\t%0, %1, %%g0"
5168 [(set_attr "type" "compare")])
5170 (define_insn "cmp_minus_cc_set"
5171 [(set (reg:CC_NOOV 100)
5172 (compare:CC_NOOV (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5173 (match_operand:SI 2 "arith_operand" "rI"))
5175 (set (match_operand:SI 0 "register_operand" "=r")
5176 (minus:SI (match_dup 1) (match_dup 2)))]
5178 "subcc\t%r1, %2, %0"
5179 [(set_attr "type" "compare")])
5181 (define_insn "*cmp_minus_ccx_set"
5182 [(set (reg:CCX_NOOV 100)
5183 (compare:CCX_NOOV (minus:DI (match_operand:DI 1 "register_operand" "r")
5184 (match_operand:DI 2 "arith_double_operand" "rHI"))
5186 (set (match_operand:DI 0 "register_operand" "=r")
5187 (minus:DI (match_dup 1) (match_dup 2)))]
5190 [(set_attr "type" "compare")])
5192 ;; Integer Multiply/Divide.
5194 ;; The 32 bit multiply/divide instructions are deprecated on v9, but at
5195 ;; least in UltraSPARC I, II and IIi it is a win tick-wise.
5197 (define_insn "mulsi3"
5198 [(set (match_operand:SI 0 "register_operand" "=r")
5199 (mult:SI (match_operand:SI 1 "arith_operand" "%r")
5200 (match_operand:SI 2 "arith_operand" "rI")))]
5203 [(set_attr "type" "imul")])
5205 (define_expand "muldi3"
5206 [(set (match_operand:DI 0 "register_operand" "=r")
5207 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r")
5208 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5209 "TARGET_ARCH64 || TARGET_V8PLUS"
5213 emit_insn (gen_muldi3_v8plus (operands[0], operands[1], operands[2]));
5218 (define_insn "*muldi3_sp64"
5219 [(set (match_operand:DI 0 "register_operand" "=r")
5220 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r")
5221 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5224 [(set_attr "type" "imul")])
5226 ;; V8plus wide multiply.
5228 (define_insn "muldi3_v8plus"
5229 [(set (match_operand:DI 0 "register_operand" "=r,h")
5230 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r,0")
5231 (match_operand:DI 2 "arith_double_operand" "rI,rI")))
5232 (clobber (match_scratch:SI 3 "=&h,X"))
5233 (clobber (match_scratch:SI 4 "=&h,X"))]
5236 if (sparc_check_64 (operands[1], insn) <= 0)
5237 output_asm_insn ("srl\t%L1, 0, %L1", operands);
5238 if (which_alternative == 1)
5239 output_asm_insn ("sllx\t%H1, 32, %H1", operands);
5240 if (GET_CODE (operands[2]) == CONST_INT)
5242 if (which_alternative == 1)
5243 return "or\t%L1, %H1, %H1\n\tmulx\t%H1, %2, %L0\;srlx\t%L0, 32, %H0";
5245 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";
5247 else if (rtx_equal_p (operands[1], operands[2]))
5249 if (which_alternative == 1)
5250 return "or\t%L1, %H1, %H1\n\tmulx\t%H1, %H1, %L0\;srlx\t%L0, 32, %H0";
5252 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";
5254 if (sparc_check_64 (operands[2], insn) <= 0)
5255 output_asm_insn ("srl\t%L2, 0, %L2", operands);
5256 if (which_alternative == 1)
5257 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";
5259 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";
5261 [(set_attr "type" "multi")
5262 (set_attr "length" "9,8")])
5264 (define_insn "*cmp_mul_set"
5266 (compare:CC (mult:SI (match_operand:SI 1 "arith_operand" "%r")
5267 (match_operand:SI 2 "arith_operand" "rI"))
5269 (set (match_operand:SI 0 "register_operand" "=r")
5270 (mult:SI (match_dup 1) (match_dup 2)))]
5271 "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS"
5272 "smulcc\t%1, %2, %0"
5273 [(set_attr "type" "imul")])
5275 (define_expand "mulsidi3"
5276 [(set (match_operand:DI 0 "register_operand" "")
5277 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
5278 (sign_extend:DI (match_operand:SI 2 "arith_operand" ""))))]
5281 if (CONSTANT_P (operands[2]))
5284 emit_insn (gen_const_mulsidi3_v8plus (operands[0], operands[1],
5287 emit_insn (gen_const_mulsidi3_sp32 (operands[0], operands[1],
5293 emit_insn (gen_mulsidi3_v8plus (operands[0], operands[1], operands[2]));
5298 ;; V9 puts the 64 bit product in a 64 bit register. Only out or global
5299 ;; registers can hold 64 bit values in the V8plus environment.
5301 (define_insn "mulsidi3_v8plus"
5302 [(set (match_operand:DI 0 "register_operand" "=h,r")
5303 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5304 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
5305 (clobber (match_scratch:SI 3 "=X,&h"))]
5308 smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
5309 smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
5310 [(set_attr "type" "multi")
5311 (set_attr "length" "2,3")])
5314 (define_insn "const_mulsidi3_v8plus"
5315 [(set (match_operand:DI 0 "register_operand" "=h,r")
5316 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5317 (match_operand:SI 2 "small_int" "I,I")))
5318 (clobber (match_scratch:SI 3 "=X,&h"))]
5321 smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
5322 smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
5323 [(set_attr "type" "multi")
5324 (set_attr "length" "2,3")])
5327 (define_insn "*mulsidi3_sp32"
5328 [(set (match_operand:DI 0 "register_operand" "=r")
5329 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5330 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
5333 return TARGET_SPARCLET
5334 ? "smuld\t%1, %2, %L0"
5335 : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
5338 (if_then_else (eq_attr "isa" "sparclet")
5339 (const_string "imul") (const_string "multi")))
5340 (set (attr "length")
5341 (if_then_else (eq_attr "isa" "sparclet")
5342 (const_int 1) (const_int 2)))])
5344 (define_insn "*mulsidi3_sp64"
5345 [(set (match_operand:DI 0 "register_operand" "=r")
5346 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5347 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
5348 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5350 [(set_attr "type" "imul")])
5352 ;; Extra pattern, because sign_extend of a constant isn't valid.
5355 (define_insn "const_mulsidi3_sp32"
5356 [(set (match_operand:DI 0 "register_operand" "=r")
5357 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5358 (match_operand:SI 2 "small_int" "I")))]
5361 return TARGET_SPARCLET
5362 ? "smuld\t%1, %2, %L0"
5363 : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
5366 (if_then_else (eq_attr "isa" "sparclet")
5367 (const_string "imul") (const_string "multi")))
5368 (set (attr "length")
5369 (if_then_else (eq_attr "isa" "sparclet")
5370 (const_int 1) (const_int 2)))])
5372 (define_insn "const_mulsidi3_sp64"
5373 [(set (match_operand:DI 0 "register_operand" "=r")
5374 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5375 (match_operand:SI 2 "small_int" "I")))]
5376 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5378 [(set_attr "type" "imul")])
5380 (define_expand "smulsi3_highpart"
5381 [(set (match_operand:SI 0 "register_operand" "")
5383 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
5384 (sign_extend:DI (match_operand:SI 2 "arith_operand" "")))
5386 "TARGET_HARD_MUL && TARGET_ARCH32"
5388 if (CONSTANT_P (operands[2]))
5392 emit_insn (gen_const_smulsi3_highpart_v8plus (operands[0],
5398 emit_insn (gen_const_smulsi3_highpart (operands[0], operands[1], operands[2]));
5403 emit_insn (gen_smulsi3_highpart_v8plus (operands[0], operands[1],
5404 operands[2], GEN_INT (32)));
5410 (define_insn "smulsi3_highpart_v8plus"
5411 [(set (match_operand:SI 0 "register_operand" "=h,r")
5413 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5414 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
5415 (match_operand:SI 3 "const_int_operand" "i,i"))))
5416 (clobber (match_scratch:SI 4 "=X,&h"))]
5419 smul\t%1, %2, %0\;srlx\t%0, %3, %0
5420 smul\t%1, %2, %4\;srlx\t%4, %3, %0"
5421 [(set_attr "type" "multi")
5422 (set_attr "length" "2")])
5424 ;; The combiner changes TRUNCATE in the previous pattern to SUBREG.
5427 [(set (match_operand:SI 0 "register_operand" "=h,r")
5430 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5431 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
5432 (match_operand:SI 3 "const_int_operand" "i,i"))
5434 (clobber (match_scratch:SI 4 "=X,&h"))]
5437 smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
5438 smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
5439 [(set_attr "type" "multi")
5440 (set_attr "length" "2")])
5443 (define_insn "const_smulsi3_highpart_v8plus"
5444 [(set (match_operand:SI 0 "register_operand" "=h,r")
5446 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5447 (match_operand 2 "small_int" "i,i"))
5448 (match_operand:SI 3 "const_int_operand" "i,i"))))
5449 (clobber (match_scratch:SI 4 "=X,&h"))]
5452 smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
5453 smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
5454 [(set_attr "type" "multi")
5455 (set_attr "length" "2")])
5458 (define_insn "*smulsi3_highpart_sp32"
5459 [(set (match_operand:SI 0 "register_operand" "=r")
5461 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5462 (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
5465 "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
5466 [(set_attr "type" "multi")
5467 (set_attr "length" "2")])
5470 (define_insn "const_smulsi3_highpart"
5471 [(set (match_operand:SI 0 "register_operand" "=r")
5473 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5474 (match_operand:SI 2 "register_operand" "r"))
5477 "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
5478 [(set_attr "type" "multi")
5479 (set_attr "length" "2")])
5481 (define_expand "umulsidi3"
5482 [(set (match_operand:DI 0 "register_operand" "")
5483 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
5484 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" ""))))]
5487 if (CONSTANT_P (operands[2]))
5490 emit_insn (gen_const_umulsidi3_v8plus (operands[0], operands[1],
5493 emit_insn (gen_const_umulsidi3_sp32 (operands[0], operands[1],
5499 emit_insn (gen_umulsidi3_v8plus (operands[0], operands[1], operands[2]));
5505 (define_insn "umulsidi3_v8plus"
5506 [(set (match_operand:DI 0 "register_operand" "=h,r")
5507 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5508 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
5509 (clobber (match_scratch:SI 3 "=X,&h"))]
5512 umul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
5513 umul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
5514 [(set_attr "type" "multi")
5515 (set_attr "length" "2,3")])
5518 (define_insn "*umulsidi3_sp32"
5519 [(set (match_operand:DI 0 "register_operand" "=r")
5520 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5521 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
5524 return TARGET_SPARCLET
5525 ? "umuld\t%1, %2, %L0"
5526 : "umul\t%1, %2, %L0\n\trd\t%%y, %H0";
5529 (if_then_else (eq_attr "isa" "sparclet")
5530 (const_string "imul") (const_string "multi")))
5531 (set (attr "length")
5532 (if_then_else (eq_attr "isa" "sparclet")
5533 (const_int 1) (const_int 2)))])
5535 (define_insn "*umulsidi3_sp64"
5536 [(set (match_operand:DI 0 "register_operand" "=r")
5537 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5538 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
5539 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5541 [(set_attr "type" "imul")])
5543 ;; Extra pattern, because sign_extend of a constant isn't valid.
5546 (define_insn "const_umulsidi3_sp32"
5547 [(set (match_operand:DI 0 "register_operand" "=r")
5548 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5549 (match_operand:SI 2 "uns_small_int" "")))]
5552 return TARGET_SPARCLET
5553 ? "umuld\t%1, %2, %L0"
5554 : "umul\t%1, %2, %L0\n\trd\t%%y, %H0";
5557 (if_then_else (eq_attr "isa" "sparclet")
5558 (const_string "imul") (const_string "multi")))
5559 (set (attr "length")
5560 (if_then_else (eq_attr "isa" "sparclet")
5561 (const_int 1) (const_int 2)))])
5563 (define_insn "const_umulsidi3_sp64"
5564 [(set (match_operand:DI 0 "register_operand" "=r")
5565 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5566 (match_operand:SI 2 "uns_small_int" "")))]
5567 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5569 [(set_attr "type" "imul")])
5572 (define_insn "const_umulsidi3_v8plus"
5573 [(set (match_operand:DI 0 "register_operand" "=h,r")
5574 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5575 (match_operand:SI 2 "uns_small_int" "")))
5576 (clobber (match_scratch:SI 3 "=X,h"))]
5579 umul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
5580 umul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
5581 [(set_attr "type" "multi")
5582 (set_attr "length" "2,3")])
5584 (define_expand "umulsi3_highpart"
5585 [(set (match_operand:SI 0 "register_operand" "")
5587 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
5588 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" "")))
5590 "TARGET_HARD_MUL && TARGET_ARCH32"
5592 if (CONSTANT_P (operands[2]))
5596 emit_insn (gen_const_umulsi3_highpart_v8plus (operands[0],
5602 emit_insn (gen_const_umulsi3_highpart (operands[0], operands[1], operands[2]));
5607 emit_insn (gen_umulsi3_highpart_v8plus (operands[0], operands[1],
5608 operands[2], GEN_INT (32)));
5614 (define_insn "umulsi3_highpart_v8plus"
5615 [(set (match_operand:SI 0 "register_operand" "=h,r")
5617 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5618 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
5619 (match_operand:SI 3 "const_int_operand" "i,i"))))
5620 (clobber (match_scratch:SI 4 "=X,h"))]
5623 umul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
5624 umul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
5625 [(set_attr "type" "multi")
5626 (set_attr "length" "2")])
5629 (define_insn "const_umulsi3_highpart_v8plus"
5630 [(set (match_operand:SI 0 "register_operand" "=h,r")
5632 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5633 (match_operand:SI 2 "uns_small_int" ""))
5634 (match_operand:SI 3 "const_int_operand" "i,i"))))
5635 (clobber (match_scratch:SI 4 "=X,h"))]
5638 umul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
5639 umul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
5640 [(set_attr "type" "multi")
5641 (set_attr "length" "2")])
5644 (define_insn "*umulsi3_highpart_sp32"
5645 [(set (match_operand:SI 0 "register_operand" "=r")
5647 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5648 (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
5651 "umul\t%1, %2, %%g0\n\trd\t%%y, %0"
5652 [(set_attr "type" "multi")
5653 (set_attr "length" "2")])
5656 (define_insn "const_umulsi3_highpart"
5657 [(set (match_operand:SI 0 "register_operand" "=r")
5659 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5660 (match_operand:SI 2 "uns_small_int" ""))
5663 "umul\t%1, %2, %%g0\n\trd\t%%y, %0"
5664 [(set_attr "type" "multi")
5665 (set_attr "length" "2")])
5667 ;; The v8 architecture specifies that there must be 3 instructions between
5668 ;; a y register write and a use of it for correct results.
5670 (define_expand "divsi3"
5671 [(parallel [(set (match_operand:SI 0 "register_operand" "=r,r")
5672 (div:SI (match_operand:SI 1 "register_operand" "r,r")
5673 (match_operand:SI 2 "input_operand" "rI,m")))
5674 (clobber (match_scratch:SI 3 "=&r,&r"))])]
5675 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
5679 operands[3] = gen_reg_rtx(SImode);
5680 emit_insn (gen_ashrsi3 (operands[3], operands[1], GEN_INT (31)));
5681 emit_insn (gen_divsi3_sp64 (operands[0], operands[1], operands[2],
5687 (define_insn "divsi3_sp32"
5688 [(set (match_operand:SI 0 "register_operand" "=r,r")
5689 (div:SI (match_operand:SI 1 "register_operand" "r,r")
5690 (match_operand:SI 2 "input_operand" "rI,m")))
5691 (clobber (match_scratch:SI 3 "=&r,&r"))]
5692 "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS)
5695 if (which_alternative == 0)
5697 return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tsdiv\t%1, %2, %0";
5699 return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tnop\n\tnop\n\tnop\n\tsdiv\t%1, %2, %0";
5702 return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tld\t%2, %3\n\tsdiv\t%1, %3, %0";
5704 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";
5706 [(set_attr "type" "multi")
5707 (set (attr "length")
5708 (if_then_else (eq_attr "isa" "v9")
5709 (const_int 4) (const_int 6)))])
5711 (define_insn "divsi3_sp64"
5712 [(set (match_operand:SI 0 "register_operand" "=r")
5713 (div:SI (match_operand:SI 1 "register_operand" "r")
5714 (match_operand:SI 2 "input_operand" "rI")))
5715 (use (match_operand:SI 3 "register_operand" "r"))]
5716 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5717 "wr\t%%g0, %3, %%y\n\tsdiv\t%1, %2, %0"
5718 [(set_attr "type" "multi")
5719 (set_attr "length" "2")])
5721 (define_insn "divdi3"
5722 [(set (match_operand:DI 0 "register_operand" "=r")
5723 (div:DI (match_operand:DI 1 "register_operand" "r")
5724 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5727 [(set_attr "type" "idiv")])
5729 (define_insn "*cmp_sdiv_cc_set"
5731 (compare:CC (div:SI (match_operand:SI 1 "register_operand" "r")
5732 (match_operand:SI 2 "arith_operand" "rI"))
5734 (set (match_operand:SI 0 "register_operand" "=r")
5735 (div:SI (match_dup 1) (match_dup 2)))
5736 (clobber (match_scratch:SI 3 "=&r"))]
5737 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
5740 return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tsdivcc\t%1, %2, %0";
5742 return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tnop\n\tnop\n\tnop\n\tsdivcc\t%1, %2, %0";
5744 [(set_attr "type" "multi")
5745 (set (attr "length")
5746 (if_then_else (eq_attr "isa" "v9")
5747 (const_int 3) (const_int 6)))])
5750 (define_expand "udivsi3"
5751 [(set (match_operand:SI 0 "register_operand" "")
5752 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "")
5753 (match_operand:SI 2 "input_operand" "")))]
5754 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
5757 (define_insn "udivsi3_sp32"
5758 [(set (match_operand:SI 0 "register_operand" "=r,&r,&r")
5759 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "r,r,m")
5760 (match_operand:SI 2 "input_operand" "rI,m,r")))]
5762 || TARGET_DEPRECATED_V8_INSNS)
5765 output_asm_insn ("wr\t%%g0, %%g0, %%y", operands);
5766 switch (which_alternative)
5769 return "nop\n\tnop\n\tnop\n\tudiv\t%1, %2, %0";
5771 return "ld\t%2, %0\n\tnop\n\tnop\n\tudiv\t%1, %0, %0";
5773 return "ld\t%1, %0\n\tnop\n\tnop\n\tudiv\t%0, %2, %0";
5776 [(set_attr "type" "multi")
5777 (set_attr "length" "5")])
5779 (define_insn "udivsi3_sp64"
5780 [(set (match_operand:SI 0 "register_operand" "=r")
5781 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "r")
5782 (match_operand:SI 2 "input_operand" "rI")))]
5783 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5784 "wr\t%%g0, 0, %%y\n\tudiv\t%1, %2, %0"
5785 [(set_attr "type" "multi")
5786 (set_attr "length" "2")])
5788 (define_insn "udivdi3"
5789 [(set (match_operand:DI 0 "register_operand" "=r")
5790 (udiv:DI (match_operand:DI 1 "register_operand" "r")
5791 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5794 [(set_attr "type" "idiv")])
5796 (define_insn "*cmp_udiv_cc_set"
5798 (compare:CC (udiv:SI (match_operand:SI 1 "register_operand" "r")
5799 (match_operand:SI 2 "arith_operand" "rI"))
5801 (set (match_operand:SI 0 "register_operand" "=r")
5802 (udiv:SI (match_dup 1) (match_dup 2)))]
5804 || TARGET_DEPRECATED_V8_INSNS"
5807 return "wr\t%%g0, %%g0, %%y\n\tudivcc\t%1, %2, %0";
5809 return "wr\t%%g0, %%g0, %%y\n\tnop\n\tnop\n\tnop\n\tudivcc\t%1, %2, %0";
5811 [(set_attr "type" "multi")
5812 (set (attr "length")
5813 (if_then_else (eq_attr "isa" "v9")
5814 (const_int 2) (const_int 5)))])
5816 ; sparclet multiply/accumulate insns
5818 (define_insn "*smacsi"
5819 [(set (match_operand:SI 0 "register_operand" "=r")
5820 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "%r")
5821 (match_operand:SI 2 "arith_operand" "rI"))
5822 (match_operand:SI 3 "register_operand" "0")))]
5825 [(set_attr "type" "imul")])
5827 (define_insn "*smacdi"
5828 [(set (match_operand:DI 0 "register_operand" "=r")
5829 (plus:DI (mult:DI (sign_extend:DI
5830 (match_operand:SI 1 "register_operand" "%r"))
5832 (match_operand:SI 2 "register_operand" "r")))
5833 (match_operand:DI 3 "register_operand" "0")))]
5835 "smacd\t%1, %2, %L0"
5836 [(set_attr "type" "imul")])
5838 (define_insn "*umacdi"
5839 [(set (match_operand:DI 0 "register_operand" "=r")
5840 (plus:DI (mult:DI (zero_extend:DI
5841 (match_operand:SI 1 "register_operand" "%r"))
5843 (match_operand:SI 2 "register_operand" "r")))
5844 (match_operand:DI 3 "register_operand" "0")))]
5846 "umacd\t%1, %2, %L0"
5847 [(set_attr "type" "imul")])
5849 ;;- Boolean instructions
5850 ;; We define DImode `and' so with DImode `not' we can get
5851 ;; DImode `andn'. Other combinations are possible.
5853 (define_expand "anddi3"
5854 [(set (match_operand:DI 0 "register_operand" "")
5855 (and:DI (match_operand:DI 1 "arith_double_operand" "")
5856 (match_operand:DI 2 "arith_double_operand" "")))]
5860 (define_insn "*anddi3_sp32"
5861 [(set (match_operand:DI 0 "register_operand" "=r,b")
5862 (and:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
5863 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
5868 [(set_attr "type" "*,fp")
5869 (set_attr "length" "2,*")
5870 (set_attr "fptype" "double")])
5872 (define_insn "*anddi3_sp64"
5873 [(set (match_operand:DI 0 "register_operand" "=r,b")
5874 (and:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
5875 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
5880 [(set_attr "type" "*,fp")
5881 (set_attr "fptype" "double")])
5883 (define_insn "andsi3"
5884 [(set (match_operand:SI 0 "register_operand" "=r,d")
5885 (and:SI (match_operand:SI 1 "arith_operand" "%r,d")
5886 (match_operand:SI 2 "arith_operand" "rI,d")))]
5891 [(set_attr "type" "*,fp")])
5894 [(set (match_operand:SI 0 "register_operand" "")
5895 (and:SI (match_operand:SI 1 "register_operand" "")
5896 (match_operand:SI 2 "" "")))
5897 (clobber (match_operand:SI 3 "register_operand" ""))]
5898 "GET_CODE (operands[2]) == CONST_INT
5899 && !SMALL_INT32 (operands[2])
5900 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
5901 [(set (match_dup 3) (match_dup 4))
5902 (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 1)))]
5904 operands[4] = GEN_INT (~INTVAL (operands[2]));
5907 ;; Split DImode logical operations requiring two instructions.
5909 [(set (match_operand:DI 0 "register_operand" "")
5910 (match_operator:DI 1 "cc_arithop" ; AND, IOR, XOR
5911 [(match_operand:DI 2 "register_operand" "")
5912 (match_operand:DI 3 "arith_double_operand" "")]))]
5915 && ((GET_CODE (operands[0]) == REG
5916 && REGNO (operands[0]) < 32)
5917 || (GET_CODE (operands[0]) == SUBREG
5918 && GET_CODE (SUBREG_REG (operands[0])) == REG
5919 && REGNO (SUBREG_REG (operands[0])) < 32))"
5920 [(set (match_dup 4) (match_op_dup:SI 1 [(match_dup 6) (match_dup 8)]))
5921 (set (match_dup 5) (match_op_dup:SI 1 [(match_dup 7) (match_dup 9)]))]
5923 operands[4] = gen_highpart (SImode, operands[0]);
5924 operands[5] = gen_lowpart (SImode, operands[0]);
5925 operands[6] = gen_highpart (SImode, operands[2]);
5926 operands[7] = gen_lowpart (SImode, operands[2]);
5927 #if HOST_BITS_PER_WIDE_INT == 32
5928 if (GET_CODE (operands[3]) == CONST_INT)
5930 if (INTVAL (operands[3]) < 0)
5931 operands[8] = constm1_rtx;
5933 operands[8] = const0_rtx;
5937 operands[8] = gen_highpart_mode (SImode, DImode, operands[3]);
5938 operands[9] = gen_lowpart (SImode, operands[3]);
5941 (define_insn_and_split "*and_not_di_sp32"
5942 [(set (match_operand:DI 0 "register_operand" "=r,b")
5943 (and:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
5944 (match_operand:DI 2 "register_operand" "r,b")))]
5948 fandnot1\t%1, %2, %0"
5949 "&& reload_completed
5950 && ((GET_CODE (operands[0]) == REG
5951 && REGNO (operands[0]) < 32)
5952 || (GET_CODE (operands[0]) == SUBREG
5953 && GET_CODE (SUBREG_REG (operands[0])) == REG
5954 && REGNO (SUBREG_REG (operands[0])) < 32))"
5955 [(set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))
5956 (set (match_dup 6) (and:SI (not:SI (match_dup 7)) (match_dup 8)))]
5957 "operands[3] = gen_highpart (SImode, operands[0]);
5958 operands[4] = gen_highpart (SImode, operands[1]);
5959 operands[5] = gen_highpart (SImode, operands[2]);
5960 operands[6] = gen_lowpart (SImode, operands[0]);
5961 operands[7] = gen_lowpart (SImode, operands[1]);
5962 operands[8] = gen_lowpart (SImode, operands[2]);"
5963 [(set_attr "type" "*,fp")
5964 (set_attr "length" "2,*")
5965 (set_attr "fptype" "double")])
5967 (define_insn "*and_not_di_sp64"
5968 [(set (match_operand:DI 0 "register_operand" "=r,b")
5969 (and:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
5970 (match_operand:DI 2 "register_operand" "r,b")))]
5974 fandnot1\t%1, %2, %0"
5975 [(set_attr "type" "*,fp")
5976 (set_attr "fptype" "double")])
5978 (define_insn "*and_not_si"
5979 [(set (match_operand:SI 0 "register_operand" "=r,d")
5980 (and:SI (not:SI (match_operand:SI 1 "register_operand" "r,d"))
5981 (match_operand:SI 2 "register_operand" "r,d")))]
5985 fandnot1s\t%1, %2, %0"
5986 [(set_attr "type" "*,fp")])
5988 (define_expand "iordi3"
5989 [(set (match_operand:DI 0 "register_operand" "")
5990 (ior:DI (match_operand:DI 1 "arith_double_operand" "")
5991 (match_operand:DI 2 "arith_double_operand" "")))]
5995 (define_insn "*iordi3_sp32"
5996 [(set (match_operand:DI 0 "register_operand" "=r,b")
5997 (ior:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
5998 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6003 [(set_attr "type" "*,fp")
6004 (set_attr "length" "2,*")
6005 (set_attr "fptype" "double")])
6007 (define_insn "*iordi3_sp64"
6008 [(set (match_operand:DI 0 "register_operand" "=r,b")
6009 (ior:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6010 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6015 [(set_attr "type" "*,fp")
6016 (set_attr "fptype" "double")])
6018 (define_insn "iorsi3"
6019 [(set (match_operand:SI 0 "register_operand" "=r,d")
6020 (ior:SI (match_operand:SI 1 "arith_operand" "%r,d")
6021 (match_operand:SI 2 "arith_operand" "rI,d")))]
6026 [(set_attr "type" "*,fp")])
6029 [(set (match_operand:SI 0 "register_operand" "")
6030 (ior:SI (match_operand:SI 1 "register_operand" "")
6031 (match_operand:SI 2 "" "")))
6032 (clobber (match_operand:SI 3 "register_operand" ""))]
6033 "GET_CODE (operands[2]) == CONST_INT
6034 && !SMALL_INT32 (operands[2])
6035 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6036 [(set (match_dup 3) (match_dup 4))
6037 (set (match_dup 0) (ior:SI (not:SI (match_dup 3)) (match_dup 1)))]
6039 operands[4] = GEN_INT (~INTVAL (operands[2]));
6042 (define_insn_and_split "*or_not_di_sp32"
6043 [(set (match_operand:DI 0 "register_operand" "=r,b")
6044 (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6045 (match_operand:DI 2 "register_operand" "r,b")))]
6049 fornot1\t%1, %2, %0"
6050 "&& reload_completed
6051 && ((GET_CODE (operands[0]) == REG
6052 && REGNO (operands[0]) < 32)
6053 || (GET_CODE (operands[0]) == SUBREG
6054 && GET_CODE (SUBREG_REG (operands[0])) == REG
6055 && REGNO (SUBREG_REG (operands[0])) < 32))"
6056 [(set (match_dup 3) (ior:SI (not:SI (match_dup 4)) (match_dup 5)))
6057 (set (match_dup 6) (ior:SI (not:SI (match_dup 7)) (match_dup 8)))]
6058 "operands[3] = gen_highpart (SImode, operands[0]);
6059 operands[4] = gen_highpart (SImode, operands[1]);
6060 operands[5] = gen_highpart (SImode, operands[2]);
6061 operands[6] = gen_lowpart (SImode, operands[0]);
6062 operands[7] = gen_lowpart (SImode, operands[1]);
6063 operands[8] = gen_lowpart (SImode, operands[2]);"
6064 [(set_attr "type" "*,fp")
6065 (set_attr "length" "2,*")
6066 (set_attr "fptype" "double")])
6068 (define_insn "*or_not_di_sp64"
6069 [(set (match_operand:DI 0 "register_operand" "=r,b")
6070 (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6071 (match_operand:DI 2 "register_operand" "r,b")))]
6075 fornot1\t%1, %2, %0"
6076 [(set_attr "type" "*,fp")
6077 (set_attr "fptype" "double")])
6079 (define_insn "*or_not_si"
6080 [(set (match_operand:SI 0 "register_operand" "=r,d")
6081 (ior:SI (not:SI (match_operand:SI 1 "register_operand" "r,d"))
6082 (match_operand:SI 2 "register_operand" "r,d")))]
6086 fornot1s\t%1, %2, %0"
6087 [(set_attr "type" "*,fp")])
6089 (define_expand "xordi3"
6090 [(set (match_operand:DI 0 "register_operand" "")
6091 (xor:DI (match_operand:DI 1 "arith_double_operand" "")
6092 (match_operand:DI 2 "arith_double_operand" "")))]
6096 (define_insn "*xordi3_sp32"
6097 [(set (match_operand:DI 0 "register_operand" "=r,b")
6098 (xor:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6099 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6104 [(set_attr "type" "*,fp")
6105 (set_attr "length" "2,*")
6106 (set_attr "fptype" "double")])
6108 (define_insn "*xordi3_sp64"
6109 [(set (match_operand:DI 0 "register_operand" "=r,b")
6110 (xor:DI (match_operand:DI 1 "arith_double_operand" "%rJ,b")
6111 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6116 [(set_attr "type" "*,fp")
6117 (set_attr "fptype" "double")])
6119 (define_insn "*xordi3_sp64_dbl"
6120 [(set (match_operand:DI 0 "register_operand" "=r")
6121 (xor:DI (match_operand:DI 1 "register_operand" "r")
6122 (match_operand:DI 2 "const64_operand" "")))]
6124 && HOST_BITS_PER_WIDE_INT != 64)"
6127 (define_insn "xorsi3"
6128 [(set (match_operand:SI 0 "register_operand" "=r,d")
6129 (xor:SI (match_operand:SI 1 "arith_operand" "%rJ,d")
6130 (match_operand:SI 2 "arith_operand" "rI,d")))]
6135 [(set_attr "type" "*,fp")])
6138 [(set (match_operand:SI 0 "register_operand" "")
6139 (xor:SI (match_operand:SI 1 "register_operand" "")
6140 (match_operand:SI 2 "" "")))
6141 (clobber (match_operand:SI 3 "register_operand" ""))]
6142 "GET_CODE (operands[2]) == CONST_INT
6143 && !SMALL_INT32 (operands[2])
6144 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6145 [(set (match_dup 3) (match_dup 4))
6146 (set (match_dup 0) (not:SI (xor:SI (match_dup 3) (match_dup 1))))]
6148 operands[4] = GEN_INT (~INTVAL (operands[2]));
6152 [(set (match_operand:SI 0 "register_operand" "")
6153 (not:SI (xor:SI (match_operand:SI 1 "register_operand" "")
6154 (match_operand:SI 2 "" ""))))
6155 (clobber (match_operand:SI 3 "register_operand" ""))]
6156 "GET_CODE (operands[2]) == CONST_INT
6157 && !SMALL_INT32 (operands[2])
6158 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6159 [(set (match_dup 3) (match_dup 4))
6160 (set (match_dup 0) (xor:SI (match_dup 3) (match_dup 1)))]
6162 operands[4] = GEN_INT (~INTVAL (operands[2]));
6165 ;; xnor patterns. Note that (a ^ ~b) == (~a ^ b) == ~(a ^ b).
6166 ;; Combine now canonicalizes to the rightmost expression.
6167 (define_insn_and_split "*xor_not_di_sp32"
6168 [(set (match_operand:DI 0 "register_operand" "=r,b")
6169 (not:DI (xor:DI (match_operand:DI 1 "register_operand" "r,b")
6170 (match_operand:DI 2 "register_operand" "r,b"))))]
6175 "&& reload_completed
6176 && ((GET_CODE (operands[0]) == REG
6177 && REGNO (operands[0]) < 32)
6178 || (GET_CODE (operands[0]) == SUBREG
6179 && GET_CODE (SUBREG_REG (operands[0])) == REG
6180 && REGNO (SUBREG_REG (operands[0])) < 32))"
6181 [(set (match_dup 3) (not:SI (xor:SI (match_dup 4) (match_dup 5))))
6182 (set (match_dup 6) (not:SI (xor:SI (match_dup 7) (match_dup 8))))]
6183 "operands[3] = gen_highpart (SImode, operands[0]);
6184 operands[4] = gen_highpart (SImode, operands[1]);
6185 operands[5] = gen_highpart (SImode, operands[2]);
6186 operands[6] = gen_lowpart (SImode, operands[0]);
6187 operands[7] = gen_lowpart (SImode, operands[1]);
6188 operands[8] = gen_lowpart (SImode, operands[2]);"
6189 [(set_attr "type" "*,fp")
6190 (set_attr "length" "2,*")
6191 (set_attr "fptype" "double")])
6193 (define_insn "*xor_not_di_sp64"
6194 [(set (match_operand:DI 0 "register_operand" "=r,b")
6195 (not:DI (xor:DI (match_operand:DI 1 "reg_or_0_operand" "rJ,b")
6196 (match_operand:DI 2 "arith_double_operand" "rHI,b"))))]
6201 [(set_attr "type" "*,fp")
6202 (set_attr "fptype" "double")])
6204 (define_insn "*xor_not_si"
6205 [(set (match_operand:SI 0 "register_operand" "=r,d")
6206 (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "rJ,d")
6207 (match_operand:SI 2 "arith_operand" "rI,d"))))]
6212 [(set_attr "type" "*,fp")])
6214 ;; These correspond to the above in the case where we also (or only)
6215 ;; want to set the condition code.
6217 (define_insn "*cmp_cc_arith_op"
6220 (match_operator:SI 2 "cc_arithop"
6221 [(match_operand:SI 0 "arith_operand" "%r")
6222 (match_operand:SI 1 "arith_operand" "rI")])
6225 "%A2cc\t%0, %1, %%g0"
6226 [(set_attr "type" "compare")])
6228 (define_insn "*cmp_ccx_arith_op"
6231 (match_operator:DI 2 "cc_arithop"
6232 [(match_operand:DI 0 "arith_double_operand" "%r")
6233 (match_operand:DI 1 "arith_double_operand" "rHI")])
6236 "%A2cc\t%0, %1, %%g0"
6237 [(set_attr "type" "compare")])
6239 (define_insn "*cmp_cc_arith_op_set"
6242 (match_operator:SI 3 "cc_arithop"
6243 [(match_operand:SI 1 "arith_operand" "%r")
6244 (match_operand:SI 2 "arith_operand" "rI")])
6246 (set (match_operand:SI 0 "register_operand" "=r")
6247 (match_operator:SI 4 "cc_arithop" [(match_dup 1) (match_dup 2)]))]
6248 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
6250 [(set_attr "type" "compare")])
6252 (define_insn "*cmp_ccx_arith_op_set"
6255 (match_operator:DI 3 "cc_arithop"
6256 [(match_operand:DI 1 "arith_double_operand" "%r")
6257 (match_operand:DI 2 "arith_double_operand" "rHI")])
6259 (set (match_operand:DI 0 "register_operand" "=r")
6260 (match_operator:DI 4 "cc_arithop" [(match_dup 1) (match_dup 2)]))]
6261 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
6263 [(set_attr "type" "compare")])
6265 (define_insn "*cmp_cc_xor_not"
6268 (not:SI (xor:SI (match_operand:SI 0 "reg_or_0_operand" "%rJ")
6269 (match_operand:SI 1 "arith_operand" "rI")))
6272 "xnorcc\t%r0, %1, %%g0"
6273 [(set_attr "type" "compare")])
6275 (define_insn "*cmp_ccx_xor_not"
6278 (not:DI (xor:DI (match_operand:DI 0 "reg_or_0_operand" "%rJ")
6279 (match_operand:DI 1 "arith_double_operand" "rHI")))
6282 "xnorcc\t%r0, %1, %%g0"
6283 [(set_attr "type" "compare")])
6285 (define_insn "*cmp_cc_xor_not_set"
6288 (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
6289 (match_operand:SI 2 "arith_operand" "rI")))
6291 (set (match_operand:SI 0 "register_operand" "=r")
6292 (not:SI (xor:SI (match_dup 1) (match_dup 2))))]
6294 "xnorcc\t%r1, %2, %0"
6295 [(set_attr "type" "compare")])
6297 (define_insn "*cmp_ccx_xor_not_set"
6300 (not:DI (xor:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ")
6301 (match_operand:DI 2 "arith_double_operand" "rHI")))
6303 (set (match_operand:DI 0 "register_operand" "=r")
6304 (not:DI (xor:DI (match_dup 1) (match_dup 2))))]
6306 "xnorcc\t%r1, %2, %0"
6307 [(set_attr "type" "compare")])
6309 (define_insn "*cmp_cc_arith_op_not"
6312 (match_operator:SI 2 "cc_arithopn"
6313 [(not:SI (match_operand:SI 0 "arith_operand" "rI"))
6314 (match_operand:SI 1 "reg_or_0_operand" "rJ")])
6317 "%B2cc\t%r1, %0, %%g0"
6318 [(set_attr "type" "compare")])
6320 (define_insn "*cmp_ccx_arith_op_not"
6323 (match_operator:DI 2 "cc_arithopn"
6324 [(not:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
6325 (match_operand:DI 1 "reg_or_0_operand" "rJ")])
6328 "%B2cc\t%r1, %0, %%g0"
6329 [(set_attr "type" "compare")])
6331 (define_insn "*cmp_cc_arith_op_not_set"
6334 (match_operator:SI 3 "cc_arithopn"
6335 [(not:SI (match_operand:SI 1 "arith_operand" "rI"))
6336 (match_operand:SI 2 "reg_or_0_operand" "rJ")])
6338 (set (match_operand:SI 0 "register_operand" "=r")
6339 (match_operator:SI 4 "cc_arithopn"
6340 [(not:SI (match_dup 1)) (match_dup 2)]))]
6341 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
6342 "%B3cc\t%r2, %1, %0"
6343 [(set_attr "type" "compare")])
6345 (define_insn "*cmp_ccx_arith_op_not_set"
6348 (match_operator:DI 3 "cc_arithopn"
6349 [(not:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
6350 (match_operand:DI 2 "reg_or_0_operand" "rJ")])
6352 (set (match_operand:DI 0 "register_operand" "=r")
6353 (match_operator:DI 4 "cc_arithopn"
6354 [(not:DI (match_dup 1)) (match_dup 2)]))]
6355 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
6356 "%B3cc\t%r2, %1, %0"
6357 [(set_attr "type" "compare")])
6359 ;; We cannot use the "neg" pseudo insn because the Sun assembler
6360 ;; does not know how to make it work for constants.
6362 (define_expand "negdi2"
6363 [(set (match_operand:DI 0 "register_operand" "=r")
6364 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
6367 if (! TARGET_ARCH64)
6369 emit_insn (gen_rtx_PARALLEL
6372 gen_rtx_SET (VOIDmode, operand0,
6373 gen_rtx_NEG (DImode, operand1)),
6374 gen_rtx_CLOBBER (VOIDmode,
6375 gen_rtx_REG (CCmode,
6381 (define_insn_and_split "*negdi2_sp32"
6382 [(set (match_operand:DI 0 "register_operand" "=r")
6383 (neg:DI (match_operand:DI 1 "register_operand" "r")))
6384 (clobber (reg:CC 100))]
6387 "&& reload_completed"
6388 [(parallel [(set (reg:CC_NOOV 100)
6389 (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 5))
6391 (set (match_dup 4) (minus:SI (const_int 0) (match_dup 5)))])
6392 (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
6393 (ltu:SI (reg:CC 100) (const_int 0))))]
6394 "operands[2] = gen_highpart (SImode, operands[0]);
6395 operands[3] = gen_highpart (SImode, operands[1]);
6396 operands[4] = gen_lowpart (SImode, operands[0]);
6397 operands[5] = gen_lowpart (SImode, operands[1]);"
6398 [(set_attr "length" "2")])
6400 (define_insn "*negdi2_sp64"
6401 [(set (match_operand:DI 0 "register_operand" "=r")
6402 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
6404 "sub\t%%g0, %1, %0")
6406 (define_insn "negsi2"
6407 [(set (match_operand:SI 0 "register_operand" "=r")
6408 (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
6410 "sub\t%%g0, %1, %0")
6412 (define_insn "*cmp_cc_neg"
6413 [(set (reg:CC_NOOV 100)
6414 (compare:CC_NOOV (neg:SI (match_operand:SI 0 "arith_operand" "rI"))
6417 "subcc\t%%g0, %0, %%g0"
6418 [(set_attr "type" "compare")])
6420 (define_insn "*cmp_ccx_neg"
6421 [(set (reg:CCX_NOOV 100)
6422 (compare:CCX_NOOV (neg:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
6425 "subcc\t%%g0, %0, %%g0"
6426 [(set_attr "type" "compare")])
6428 (define_insn "*cmp_cc_set_neg"
6429 [(set (reg:CC_NOOV 100)
6430 (compare:CC_NOOV (neg:SI (match_operand:SI 1 "arith_operand" "rI"))
6432 (set (match_operand:SI 0 "register_operand" "=r")
6433 (neg:SI (match_dup 1)))]
6435 "subcc\t%%g0, %1, %0"
6436 [(set_attr "type" "compare")])
6438 (define_insn "*cmp_ccx_set_neg"
6439 [(set (reg:CCX_NOOV 100)
6440 (compare:CCX_NOOV (neg:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
6442 (set (match_operand:DI 0 "register_operand" "=r")
6443 (neg:DI (match_dup 1)))]
6445 "subcc\t%%g0, %1, %0"
6446 [(set_attr "type" "compare")])
6448 ;; We cannot use the "not" pseudo insn because the Sun assembler
6449 ;; does not know how to make it work for constants.
6450 (define_expand "one_cmpldi2"
6451 [(set (match_operand:DI 0 "register_operand" "")
6452 (not:DI (match_operand:DI 1 "register_operand" "")))]
6456 (define_insn_and_split "*one_cmpldi2_sp32"
6457 [(set (match_operand:DI 0 "register_operand" "=r,b")
6458 (not:DI (match_operand:DI 1 "register_operand" "r,b")))]
6463 "&& reload_completed
6464 && ((GET_CODE (operands[0]) == REG
6465 && REGNO (operands[0]) < 32)
6466 || (GET_CODE (operands[0]) == SUBREG
6467 && GET_CODE (SUBREG_REG (operands[0])) == REG
6468 && REGNO (SUBREG_REG (operands[0])) < 32))"
6469 [(set (match_dup 2) (not:SI (xor:SI (match_dup 3) (const_int 0))))
6470 (set (match_dup 4) (not:SI (xor:SI (match_dup 5) (const_int 0))))]
6471 "operands[2] = gen_highpart (SImode, operands[0]);
6472 operands[3] = gen_highpart (SImode, operands[1]);
6473 operands[4] = gen_lowpart (SImode, operands[0]);
6474 operands[5] = gen_lowpart (SImode, operands[1]);"
6475 [(set_attr "type" "*,fp")
6476 (set_attr "length" "2,*")
6477 (set_attr "fptype" "double")])
6479 (define_insn "*one_cmpldi2_sp64"
6480 [(set (match_operand:DI 0 "register_operand" "=r,b")
6481 (not:DI (match_operand:DI 1 "arith_double_operand" "rHI,b")))]
6486 [(set_attr "type" "*,fp")
6487 (set_attr "fptype" "double")])
6489 (define_insn "one_cmplsi2"
6490 [(set (match_operand:SI 0 "register_operand" "=r,d")
6491 (not:SI (match_operand:SI 1 "arith_operand" "rI,d")))]
6496 [(set_attr "type" "*,fp")])
6498 (define_insn "*cmp_cc_not"
6500 (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI"))
6503 "xnorcc\t%%g0, %0, %%g0"
6504 [(set_attr "type" "compare")])
6506 (define_insn "*cmp_ccx_not"
6508 (compare:CCX (not:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
6511 "xnorcc\t%%g0, %0, %%g0"
6512 [(set_attr "type" "compare")])
6514 (define_insn "*cmp_cc_set_not"
6516 (compare:CC (not:SI (match_operand:SI 1 "arith_operand" "rI"))
6518 (set (match_operand:SI 0 "register_operand" "=r")
6519 (not:SI (match_dup 1)))]
6521 "xnorcc\t%%g0, %1, %0"
6522 [(set_attr "type" "compare")])
6524 (define_insn "*cmp_ccx_set_not"
6526 (compare:CCX (not:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
6528 (set (match_operand:DI 0 "register_operand" "=r")
6529 (not:DI (match_dup 1)))]
6531 "xnorcc\t%%g0, %1, %0"
6532 [(set_attr "type" "compare")])
6534 (define_insn "*cmp_cc_set"
6535 [(set (match_operand:SI 0 "register_operand" "=r")
6536 (match_operand:SI 1 "register_operand" "r"))
6538 (compare:CC (match_dup 1)
6542 [(set_attr "type" "compare")])
6544 (define_insn "*cmp_ccx_set64"
6545 [(set (match_operand:DI 0 "register_operand" "=r")
6546 (match_operand:DI 1 "register_operand" "r"))
6548 (compare:CCX (match_dup 1)
6552 [(set_attr "type" "compare")])
6554 ;; Floating point arithmetic instructions.
6556 (define_expand "addtf3"
6557 [(set (match_operand:TF 0 "nonimmediate_operand" "")
6558 (plus:TF (match_operand:TF 1 "general_operand" "")
6559 (match_operand:TF 2 "general_operand" "")))]
6560 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6561 "emit_tfmode_binop (PLUS, operands); DONE;")
6563 (define_insn "*addtf3_hq"
6564 [(set (match_operand:TF 0 "register_operand" "=e")
6565 (plus:TF (match_operand:TF 1 "register_operand" "e")
6566 (match_operand:TF 2 "register_operand" "e")))]
6567 "TARGET_FPU && TARGET_HARD_QUAD"
6569 [(set_attr "type" "fp")])
6571 (define_insn "adddf3"
6572 [(set (match_operand:DF 0 "register_operand" "=e")
6573 (plus:DF (match_operand:DF 1 "register_operand" "e")
6574 (match_operand:DF 2 "register_operand" "e")))]
6577 [(set_attr "type" "fp")
6578 (set_attr "fptype" "double")])
6580 (define_insn "addsf3"
6581 [(set (match_operand:SF 0 "register_operand" "=f")
6582 (plus:SF (match_operand:SF 1 "register_operand" "f")
6583 (match_operand:SF 2 "register_operand" "f")))]
6586 [(set_attr "type" "fp")])
6588 (define_expand "subtf3"
6589 [(set (match_operand:TF 0 "nonimmediate_operand" "")
6590 (minus:TF (match_operand:TF 1 "general_operand" "")
6591 (match_operand:TF 2 "general_operand" "")))]
6592 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6593 "emit_tfmode_binop (MINUS, operands); DONE;")
6595 (define_insn "*subtf3_hq"
6596 [(set (match_operand:TF 0 "register_operand" "=e")
6597 (minus:TF (match_operand:TF 1 "register_operand" "e")
6598 (match_operand:TF 2 "register_operand" "e")))]
6599 "TARGET_FPU && TARGET_HARD_QUAD"
6601 [(set_attr "type" "fp")])
6603 (define_insn "subdf3"
6604 [(set (match_operand:DF 0 "register_operand" "=e")
6605 (minus:DF (match_operand:DF 1 "register_operand" "e")
6606 (match_operand:DF 2 "register_operand" "e")))]
6609 [(set_attr "type" "fp")
6610 (set_attr "fptype" "double")])
6612 (define_insn "subsf3"
6613 [(set (match_operand:SF 0 "register_operand" "=f")
6614 (minus:SF (match_operand:SF 1 "register_operand" "f")
6615 (match_operand:SF 2 "register_operand" "f")))]
6618 [(set_attr "type" "fp")])
6620 (define_expand "multf3"
6621 [(set (match_operand:TF 0 "nonimmediate_operand" "")
6622 (mult:TF (match_operand:TF 1 "general_operand" "")
6623 (match_operand:TF 2 "general_operand" "")))]
6624 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6625 "emit_tfmode_binop (MULT, operands); DONE;")
6627 (define_insn "*multf3_hq"
6628 [(set (match_operand:TF 0 "register_operand" "=e")
6629 (mult:TF (match_operand:TF 1 "register_operand" "e")
6630 (match_operand:TF 2 "register_operand" "e")))]
6631 "TARGET_FPU && TARGET_HARD_QUAD"
6633 [(set_attr "type" "fpmul")])
6635 (define_insn "muldf3"
6636 [(set (match_operand:DF 0 "register_operand" "=e")
6637 (mult:DF (match_operand:DF 1 "register_operand" "e")
6638 (match_operand:DF 2 "register_operand" "e")))]
6641 [(set_attr "type" "fpmul")
6642 (set_attr "fptype" "double")])
6644 (define_insn "mulsf3"
6645 [(set (match_operand:SF 0 "register_operand" "=f")
6646 (mult:SF (match_operand:SF 1 "register_operand" "f")
6647 (match_operand:SF 2 "register_operand" "f")))]
6650 [(set_attr "type" "fpmul")])
6652 (define_insn "*muldf3_extend"
6653 [(set (match_operand:DF 0 "register_operand" "=e")
6654 (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "f"))
6655 (float_extend:DF (match_operand:SF 2 "register_operand" "f"))))]
6656 "(TARGET_V8 || TARGET_V9) && TARGET_FPU"
6657 "fsmuld\t%1, %2, %0"
6658 [(set_attr "type" "fpmul")
6659 (set_attr "fptype" "double")])
6661 (define_insn "*multf3_extend"
6662 [(set (match_operand:TF 0 "register_operand" "=e")
6663 (mult:TF (float_extend:TF (match_operand:DF 1 "register_operand" "e"))
6664 (float_extend:TF (match_operand:DF 2 "register_operand" "e"))))]
6665 "(TARGET_V8 || TARGET_V9) && TARGET_FPU && TARGET_HARD_QUAD"
6666 "fdmulq\t%1, %2, %0"
6667 [(set_attr "type" "fpmul")])
6669 (define_expand "divtf3"
6670 [(set (match_operand:TF 0 "nonimmediate_operand" "")
6671 (div:TF (match_operand:TF 1 "general_operand" "")
6672 (match_operand:TF 2 "general_operand" "")))]
6673 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6674 "emit_tfmode_binop (DIV, operands); DONE;")
6676 ;; don't have timing for quad-prec. divide.
6677 (define_insn "*divtf3_hq"
6678 [(set (match_operand:TF 0 "register_operand" "=e")
6679 (div:TF (match_operand:TF 1 "register_operand" "e")
6680 (match_operand:TF 2 "register_operand" "e")))]
6681 "TARGET_FPU && TARGET_HARD_QUAD"
6683 [(set_attr "type" "fpdivd")])
6685 (define_insn "divdf3"
6686 [(set (match_operand:DF 0 "register_operand" "=e")
6687 (div:DF (match_operand:DF 1 "register_operand" "e")
6688 (match_operand:DF 2 "register_operand" "e")))]
6691 [(set_attr "type" "fpdivd")
6692 (set_attr "fptype" "double")])
6694 (define_insn "divsf3"
6695 [(set (match_operand:SF 0 "register_operand" "=f")
6696 (div:SF (match_operand:SF 1 "register_operand" "f")
6697 (match_operand:SF 2 "register_operand" "f")))]
6700 [(set_attr "type" "fpdivs")])
6702 (define_expand "negtf2"
6703 [(set (match_operand:TF 0 "register_operand" "=e,e")
6704 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
6708 (define_insn_and_split "*negtf2_notv9"
6709 [(set (match_operand:TF 0 "register_operand" "=e,e")
6710 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
6711 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
6717 "&& reload_completed
6718 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6719 [(set (match_dup 2) (neg:SF (match_dup 3)))
6720 (set (match_dup 4) (match_dup 5))
6721 (set (match_dup 6) (match_dup 7))]
6722 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6723 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6724 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6725 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
6726 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6727 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6728 [(set_attr "type" "fpmove,*")
6729 (set_attr "length" "*,2")])
6731 (define_insn_and_split "*negtf2_v9"
6732 [(set (match_operand:TF 0 "register_operand" "=e,e")
6733 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
6734 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
6735 "TARGET_FPU && TARGET_V9"
6739 "&& reload_completed
6740 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6741 [(set (match_dup 2) (neg:DF (match_dup 3)))
6742 (set (match_dup 4) (match_dup 5))]
6743 "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
6744 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
6745 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6746 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6747 [(set_attr "type" "fpmove,*")
6748 (set_attr "length" "*,2")
6749 (set_attr "fptype" "double")])
6751 (define_expand "negdf2"
6752 [(set (match_operand:DF 0 "register_operand" "")
6753 (neg:DF (match_operand:DF 1 "register_operand" "")))]
6757 (define_insn_and_split "*negdf2_notv9"
6758 [(set (match_operand:DF 0 "register_operand" "=e,e")
6759 (neg:DF (match_operand:DF 1 "register_operand" "0,e")))]
6760 "TARGET_FPU && ! TARGET_V9"
6764 "&& reload_completed
6765 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6766 [(set (match_dup 2) (neg:SF (match_dup 3)))
6767 (set (match_dup 4) (match_dup 5))]
6768 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6769 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6770 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6771 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);"
6772 [(set_attr "type" "fpmove,*")
6773 (set_attr "length" "*,2")])
6775 (define_insn "*negdf2_v9"
6776 [(set (match_operand:DF 0 "register_operand" "=e")
6777 (neg:DF (match_operand:DF 1 "register_operand" "e")))]
6778 "TARGET_FPU && TARGET_V9"
6780 [(set_attr "type" "fpmove")
6781 (set_attr "fptype" "double")])
6783 (define_insn "negsf2"
6784 [(set (match_operand:SF 0 "register_operand" "=f")
6785 (neg:SF (match_operand:SF 1 "register_operand" "f")))]
6788 [(set_attr "type" "fpmove")])
6790 (define_expand "abstf2"
6791 [(set (match_operand:TF 0 "register_operand" "")
6792 (abs:TF (match_operand:TF 1 "register_operand" "")))]
6796 (define_insn_and_split "*abstf2_notv9"
6797 [(set (match_operand:TF 0 "register_operand" "=e,e")
6798 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6799 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
6800 "TARGET_FPU && ! TARGET_V9"
6804 "&& reload_completed
6805 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6806 [(set (match_dup 2) (abs:SF (match_dup 3)))
6807 (set (match_dup 4) (match_dup 5))
6808 (set (match_dup 6) (match_dup 7))]
6809 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6810 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6811 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6812 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
6813 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6814 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6815 [(set_attr "type" "fpmove,*")
6816 (set_attr "length" "*,2")])
6818 (define_insn "*abstf2_hq_v9"
6819 [(set (match_operand:TF 0 "register_operand" "=e,e")
6820 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6821 "TARGET_FPU && TARGET_V9 && TARGET_HARD_QUAD"
6825 [(set_attr "type" "fpmove")
6826 (set_attr "fptype" "double,*")])
6828 (define_insn_and_split "*abstf2_v9"
6829 [(set (match_operand:TF 0 "register_operand" "=e,e")
6830 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6831 "TARGET_FPU && TARGET_V9 && !TARGET_HARD_QUAD"
6835 "&& reload_completed
6836 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6837 [(set (match_dup 2) (abs:DF (match_dup 3)))
6838 (set (match_dup 4) (match_dup 5))]
6839 "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
6840 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
6841 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6842 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6843 [(set_attr "type" "fpmove,*")
6844 (set_attr "length" "*,2")
6845 (set_attr "fptype" "double,*")])
6847 (define_expand "absdf2"
6848 [(set (match_operand:DF 0 "register_operand" "")
6849 (abs:DF (match_operand:DF 1 "register_operand" "")))]
6853 (define_insn_and_split "*absdf2_notv9"
6854 [(set (match_operand:DF 0 "register_operand" "=e,e")
6855 (abs:DF (match_operand:DF 1 "register_operand" "0,e")))]
6856 "TARGET_FPU && ! TARGET_V9"
6860 "&& reload_completed
6861 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6862 [(set (match_dup 2) (abs:SF (match_dup 3)))
6863 (set (match_dup 4) (match_dup 5))]
6864 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6865 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6866 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6867 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);"
6868 [(set_attr "type" "fpmove,*")
6869 (set_attr "length" "*,2")])
6871 (define_insn "*absdf2_v9"
6872 [(set (match_operand:DF 0 "register_operand" "=e")
6873 (abs:DF (match_operand:DF 1 "register_operand" "e")))]
6874 "TARGET_FPU && TARGET_V9"
6876 [(set_attr "type" "fpmove")
6877 (set_attr "fptype" "double")])
6879 (define_insn "abssf2"
6880 [(set (match_operand:SF 0 "register_operand" "=f")
6881 (abs:SF (match_operand:SF 1 "register_operand" "f")))]
6884 [(set_attr "type" "fpmove")])
6886 (define_expand "sqrttf2"
6887 [(set (match_operand:TF 0 "nonimmediate_operand" "")
6888 (sqrt:TF (match_operand:TF 1 "general_operand" "")))]
6889 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6890 "emit_tfmode_unop (SQRT, operands); DONE;")
6892 (define_insn "*sqrttf2_hq"
6893 [(set (match_operand:TF 0 "register_operand" "=e")
6894 (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
6895 "TARGET_FPU && TARGET_HARD_QUAD"
6897 [(set_attr "type" "fpsqrtd")])
6899 (define_insn "sqrtdf2"
6900 [(set (match_operand:DF 0 "register_operand" "=e")
6901 (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
6904 [(set_attr "type" "fpsqrtd")
6905 (set_attr "fptype" "double")])
6907 (define_insn "sqrtsf2"
6908 [(set (match_operand:SF 0 "register_operand" "=f")
6909 (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
6912 [(set_attr "type" "fpsqrts")])
6914 ;;- arithmetic shift instructions
6916 (define_insn "ashlsi3"
6917 [(set (match_operand:SI 0 "register_operand" "=r")
6918 (ashift:SI (match_operand:SI 1 "register_operand" "r")
6919 (match_operand:SI 2 "arith_operand" "rI")))]
6922 if (operands[2] == const1_rtx)
6923 return "add\t%1, %1, %0";
6924 return "sll\t%1, %2, %0";
6927 (if_then_else (match_operand 2 "const1_operand" "")
6928 (const_string "ialu") (const_string "shift")))])
6930 (define_expand "ashldi3"
6931 [(set (match_operand:DI 0 "register_operand" "=r")
6932 (ashift:DI (match_operand:DI 1 "register_operand" "r")
6933 (match_operand:SI 2 "arith_operand" "rI")))]
6934 "TARGET_ARCH64 || TARGET_V8PLUS"
6936 if (! TARGET_ARCH64)
6938 if (GET_CODE (operands[2]) == CONST_INT)
6940 emit_insn (gen_ashldi3_v8plus (operands[0], operands[1], operands[2]));
6945 (define_insn "*ashldi3_sp64"
6946 [(set (match_operand:DI 0 "register_operand" "=r")
6947 (ashift:DI (match_operand:DI 1 "register_operand" "r")
6948 (match_operand:SI 2 "arith_operand" "rI")))]
6951 if (operands[2] == const1_rtx)
6952 return "add\t%1, %1, %0";
6953 return "sllx\t%1, %2, %0";
6956 (if_then_else (match_operand 2 "const1_operand" "")
6957 (const_string "ialu") (const_string "shift")))])
6960 (define_insn "ashldi3_v8plus"
6961 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
6962 (ashift:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
6963 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
6964 (clobber (match_scratch:SI 3 "=X,X,&h"))]
6966 { return sparc_v8plus_shift (operands, insn, "sllx"); }
6967 [(set_attr "type" "multi")
6968 (set_attr "length" "5,5,6")])
6970 ;; Optimize (1LL<<x)-1
6971 ;; XXX this also needs to be fixed to handle equal subregs
6972 ;; XXX first before we could re-enable it.
6974 ; [(set (match_operand:DI 0 "register_operand" "=h")
6975 ; (plus:DI (ashift:DI (const_int 1)
6976 ; (match_operand:SI 1 "arith_operand" "rI"))
6978 ; "0 && TARGET_V8PLUS"
6980 ; if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == REGNO (operands[0]))
6981 ; return "mov\t1, %L0\;sllx\t%L0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
6982 ; return "mov\t1, %H0\;sllx\t%H0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
6984 ; [(set_attr "type" "multi")
6985 ; (set_attr "length" "4")])
6987 (define_insn "*cmp_cc_ashift_1"
6988 [(set (reg:CC_NOOV 100)
6989 (compare:CC_NOOV (ashift:SI (match_operand:SI 0 "register_operand" "r")
6993 "addcc\t%0, %0, %%g0"
6994 [(set_attr "type" "compare")])
6996 (define_insn "*cmp_cc_set_ashift_1"
6997 [(set (reg:CC_NOOV 100)
6998 (compare:CC_NOOV (ashift:SI (match_operand:SI 1 "register_operand" "r")
7001 (set (match_operand:SI 0 "register_operand" "=r")
7002 (ashift:SI (match_dup 1) (const_int 1)))]
7005 [(set_attr "type" "compare")])
7007 (define_insn "ashrsi3"
7008 [(set (match_operand:SI 0 "register_operand" "=r")
7009 (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
7010 (match_operand:SI 2 "arith_operand" "rI")))]
7013 [(set_attr "type" "shift")])
7015 (define_insn "*ashrsi3_extend"
7016 [(set (match_operand:DI 0 "register_operand" "=r")
7017 (sign_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
7018 (match_operand:SI 2 "arith_operand" "r"))))]
7021 [(set_attr "type" "shift")])
7023 ;; This handles the case as above, but with constant shift instead of
7024 ;; register. Combiner "simplifies" it for us a little bit though.
7025 (define_insn "*ashrsi3_extend2"
7026 [(set (match_operand:DI 0 "register_operand" "=r")
7027 (ashiftrt:DI (ashift:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
7029 (match_operand:SI 2 "small_int_or_double" "n")))]
7031 && ((GET_CODE (operands[2]) == CONST_INT
7032 && INTVAL (operands[2]) >= 32 && INTVAL (operands[2]) < 64)
7033 || (GET_CODE (operands[2]) == CONST_DOUBLE
7034 && !CONST_DOUBLE_HIGH (operands[2])
7035 && CONST_DOUBLE_LOW (operands[2]) >= 32
7036 && CONST_DOUBLE_LOW (operands[2]) < 64))"
7038 operands[2] = GEN_INT (INTVAL (operands[2]) - 32);
7040 return "sra\t%1, %2, %0";
7042 [(set_attr "type" "shift")])
7044 (define_expand "ashrdi3"
7045 [(set (match_operand:DI 0 "register_operand" "=r")
7046 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
7047 (match_operand:SI 2 "arith_operand" "rI")))]
7048 "TARGET_ARCH64 || TARGET_V8PLUS"
7050 if (! TARGET_ARCH64)
7052 if (GET_CODE (operands[2]) == CONST_INT)
7053 FAIL; /* prefer generic code in this case */
7054 emit_insn (gen_ashrdi3_v8plus (operands[0], operands[1], operands[2]));
7060 [(set (match_operand:DI 0 "register_operand" "=r")
7061 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
7062 (match_operand:SI 2 "arith_operand" "rI")))]
7065 [(set_attr "type" "shift")])
7068 (define_insn "ashrdi3_v8plus"
7069 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
7070 (ashiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
7071 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
7072 (clobber (match_scratch:SI 3 "=X,X,&h"))]
7074 { return sparc_v8plus_shift (operands, insn, "srax"); }
7075 [(set_attr "type" "multi")
7076 (set_attr "length" "5,5,6")])
7078 (define_insn "lshrsi3"
7079 [(set (match_operand:SI 0 "register_operand" "=r")
7080 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
7081 (match_operand:SI 2 "arith_operand" "rI")))]
7084 [(set_attr "type" "shift")])
7086 ;; This handles the case where
7087 ;; (zero_extend:DI (lshiftrt:SI (match_operand:SI) (match_operand:SI))),
7088 ;; but combiner "simplifies" it for us.
7089 (define_insn "*lshrsi3_extend"
7090 [(set (match_operand:DI 0 "register_operand" "=r")
7091 (and:DI (subreg:DI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
7092 (match_operand:SI 2 "arith_operand" "r")) 0)
7093 (match_operand 3 "" "")))]
7095 && ((GET_CODE (operands[3]) == CONST_DOUBLE
7096 && CONST_DOUBLE_HIGH (operands[3]) == 0
7097 && CONST_DOUBLE_LOW (operands[3]) == 0xffffffff)
7098 || (HOST_BITS_PER_WIDE_INT >= 64
7099 && GET_CODE (operands[3]) == CONST_INT
7100 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) == 0xffffffff))"
7102 [(set_attr "type" "shift")])
7104 ;; This handles the case where
7105 ;; (lshiftrt:DI (zero_extend:DI (match_operand:SI)) (const_int >=0 < 32))
7106 ;; but combiner "simplifies" it for us.
7107 (define_insn "*lshrsi3_extend2"
7108 [(set (match_operand:DI 0 "register_operand" "=r")
7109 (zero_extract:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
7110 (match_operand 2 "small_int_or_double" "n")
7113 && ((GET_CODE (operands[2]) == CONST_INT
7114 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
7115 || (GET_CODE (operands[2]) == CONST_DOUBLE
7116 && CONST_DOUBLE_HIGH (operands[2]) == 0
7117 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
7119 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
7121 return "srl\t%1, %2, %0";
7123 [(set_attr "type" "shift")])
7125 (define_expand "lshrdi3"
7126 [(set (match_operand:DI 0 "register_operand" "=r")
7127 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
7128 (match_operand:SI 2 "arith_operand" "rI")))]
7129 "TARGET_ARCH64 || TARGET_V8PLUS"
7131 if (! TARGET_ARCH64)
7133 if (GET_CODE (operands[2]) == CONST_INT)
7135 emit_insn (gen_lshrdi3_v8plus (operands[0], operands[1], operands[2]));
7141 [(set (match_operand:DI 0 "register_operand" "=r")
7142 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
7143 (match_operand:SI 2 "arith_operand" "rI")))]
7146 [(set_attr "type" "shift")])
7149 (define_insn "lshrdi3_v8plus"
7150 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
7151 (lshiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
7152 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
7153 (clobber (match_scratch:SI 3 "=X,X,&h"))]
7155 { return sparc_v8plus_shift (operands, insn, "srlx"); }
7156 [(set_attr "type" "multi")
7157 (set_attr "length" "5,5,6")])
7160 [(set (match_operand:SI 0 "register_operand" "=r")
7161 (ashiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
7163 (match_operand:SI 2 "small_int_or_double" "n")))]
7165 && ((GET_CODE (operands[2]) == CONST_INT
7166 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
7167 || (GET_CODE (operands[2]) == CONST_DOUBLE
7168 && !CONST_DOUBLE_HIGH (operands[2])
7169 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
7171 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
7173 return "srax\t%1, %2, %0";
7175 [(set_attr "type" "shift")])
7178 [(set (match_operand:SI 0 "register_operand" "=r")
7179 (lshiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
7181 (match_operand:SI 2 "small_int_or_double" "n")))]
7183 && ((GET_CODE (operands[2]) == CONST_INT
7184 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
7185 || (GET_CODE (operands[2]) == CONST_DOUBLE
7186 && !CONST_DOUBLE_HIGH (operands[2])
7187 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
7189 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
7191 return "srlx\t%1, %2, %0";
7193 [(set_attr "type" "shift")])
7196 [(set (match_operand:SI 0 "register_operand" "=r")
7197 (ashiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
7198 (match_operand:SI 2 "small_int_or_double" "n")) 4)
7199 (match_operand:SI 3 "small_int_or_double" "n")))]
7201 && GET_CODE (operands[2]) == CONST_INT && GET_CODE (operands[3]) == CONST_INT
7202 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
7203 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
7204 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
7206 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
7208 return "srax\t%1, %2, %0";
7210 [(set_attr "type" "shift")])
7213 [(set (match_operand:SI 0 "register_operand" "=r")
7214 (lshiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
7215 (match_operand:SI 2 "small_int_or_double" "n")) 4)
7216 (match_operand:SI 3 "small_int_or_double" "n")))]
7218 && GET_CODE (operands[2]) == CONST_INT && GET_CODE (operands[3]) == CONST_INT
7219 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
7220 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
7221 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
7223 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
7225 return "srlx\t%1, %2, %0";
7227 [(set_attr "type" "shift")])
7229 ;; Unconditional and other jump instructions
7230 ;; On the SPARC, by setting the annul bit on an unconditional branch, the
7231 ;; following insn is never executed. This saves us a nop. Dbx does not
7232 ;; handle such branches though, so we only use them when optimizing.
7234 [(set (pc) (label_ref (match_operand 0 "" "")))]
7237 /* TurboSPARC is reported to have problems with
7240 i.e. an empty loop with the annul bit set. The workaround is to use
7244 if (! TARGET_V9 && flag_delayed_branch
7245 && (INSN_ADDRESSES (INSN_UID (operands[0]))
7246 == INSN_ADDRESSES (INSN_UID (insn))))
7249 return TARGET_V9 ? "ba,pt%*\t%%xcc, %l0%(" : "b%*\t%l0%(";
7251 [(set_attr "type" "uncond_branch")])
7253 (define_expand "tablejump"
7254 [(parallel [(set (pc) (match_operand 0 "register_operand" "r"))
7255 (use (label_ref (match_operand 1 "" "")))])]
7258 if (GET_MODE (operands[0]) != CASE_VECTOR_MODE)
7261 /* In pic mode, our address differences are against the base of the
7262 table. Add that base value back in; CSE ought to be able to combine
7263 the two address loads. */
7267 tmp = gen_rtx_LABEL_REF (Pmode, operands[1]);
7269 if (CASE_VECTOR_MODE != Pmode)
7270 tmp2 = gen_rtx_SIGN_EXTEND (Pmode, tmp2);
7271 tmp = gen_rtx_PLUS (Pmode, tmp2, tmp);
7272 operands[0] = memory_address (Pmode, tmp);
7276 (define_insn "*tablejump_sp32"
7277 [(set (pc) (match_operand:SI 0 "address_operand" "p"))
7278 (use (label_ref (match_operand 1 "" "")))]
7281 [(set_attr "type" "uncond_branch")])
7283 (define_insn "*tablejump_sp64"
7284 [(set (pc) (match_operand:DI 0 "address_operand" "p"))
7285 (use (label_ref (match_operand 1 "" "")))]
7288 [(set_attr "type" "uncond_branch")])
7290 ;; This pattern recognizes the "instruction" that appears in
7291 ;; a function call that wants a structure value,
7292 ;; to inform the called function if compiled with Sun CC.
7293 ;(define_insn "*unimp_insn"
7294 ; [(match_operand:SI 0 "immediate_operand" "")]
7295 ; "GET_CODE (operands[0]) == CONST_INT && INTVAL (operands[0]) > 0"
7297 ; [(set_attr "type" "marker")])
7299 ;;- jump to subroutine
7300 (define_expand "call"
7301 ;; Note that this expression is not used for generating RTL.
7302 ;; All the RTL is generated explicitly below.
7303 [(call (match_operand 0 "call_operand" "")
7304 (match_operand 3 "" "i"))]
7305 ;; operands[2] is next_arg_register
7306 ;; operands[3] is struct_value_size_rtx.
7309 rtx fn_rtx, nregs_rtx;
7311 if (GET_MODE (operands[0]) != FUNCTION_MODE)
7314 if (GET_CODE (XEXP (operands[0], 0)) == LABEL_REF)
7316 /* This is really a PIC sequence. We want to represent
7317 it as a funny jump so its delay slots can be filled.
7319 ??? But if this really *is* a CALL, will not it clobber the
7320 call-clobbered registers? We lose this if it is a JUMP_INSN.
7321 Why cannot we have delay slots filled if it were a CALL? */
7323 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
7328 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
7330 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
7336 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
7337 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
7341 fn_rtx = operands[0];
7343 /* Count the number of parameter registers being used by this call.
7344 if that argument is NULL, it means we are using them all, which
7345 means 6 on the sparc. */
7348 nregs_rtx = GEN_INT (REGNO (operands[2]) - 8);
7350 nregs_rtx = GEN_INT (6);
7352 nregs_rtx = const0_rtx;
7355 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
7359 gen_rtvec (3, gen_rtx_CALL (VOIDmode, fn_rtx, nregs_rtx),
7361 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
7366 gen_rtvec (2, gen_rtx_CALL (VOIDmode, fn_rtx, nregs_rtx),
7367 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
7371 /* If this call wants a structure value,
7372 emit an unimp insn to let the called function know about this. */
7373 if (! TARGET_ARCH64 && INTVAL (operands[3]) > 0)
7375 rtx insn = emit_insn (operands[3]);
7376 SCHED_GROUP_P (insn) = 1;
7383 ;; We can't use the same pattern for these two insns, because then registers
7384 ;; in the address may not be properly reloaded.
7386 (define_insn "*call_address_sp32"
7387 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
7388 (match_operand 1 "" ""))
7389 (clobber (reg:SI 15))]
7390 ;;- Do not use operand 1 for most machines.
7393 [(set_attr "type" "call")])
7395 (define_insn "*call_symbolic_sp32"
7396 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
7397 (match_operand 1 "" ""))
7398 (clobber (reg:SI 15))]
7399 ;;- Do not use operand 1 for most machines.
7402 [(set_attr "type" "call")])
7404 (define_insn "*call_address_sp64"
7405 [(call (mem:DI (match_operand:DI 0 "address_operand" "p"))
7406 (match_operand 1 "" ""))
7407 (clobber (reg:DI 15))]
7408 ;;- Do not use operand 1 for most machines.
7411 [(set_attr "type" "call")])
7413 (define_insn "*call_symbolic_sp64"
7414 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
7415 (match_operand 1 "" ""))
7416 (clobber (reg:DI 15))]
7417 ;;- Do not use operand 1 for most machines.
7420 [(set_attr "type" "call")])
7422 ;; This is a call that wants a structure value.
7423 ;; There is no such critter for v9 (??? we may need one anyway).
7424 (define_insn "*call_address_struct_value_sp32"
7425 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
7426 (match_operand 1 "" ""))
7427 (match_operand 2 "immediate_operand" "")
7428 (clobber (reg:SI 15))]
7429 ;;- Do not use operand 1 for most machines.
7430 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 0"
7431 "call\t%a0, %1\n\tnop\n\tunimp\t%2"
7432 [(set_attr "type" "call_no_delay_slot")
7433 (set_attr "length" "3")])
7435 ;; This is a call that wants a structure value.
7436 ;; There is no such critter for v9 (??? we may need one anyway).
7437 (define_insn "*call_symbolic_struct_value_sp32"
7438 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
7439 (match_operand 1 "" ""))
7440 (match_operand 2 "immediate_operand" "")
7441 (clobber (reg:SI 15))]
7442 ;;- Do not use operand 1 for most machines.
7443 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 0"
7444 "call\t%a0, %1\n\tnop\n\tunimp\t%2"
7445 [(set_attr "type" "call_no_delay_slot")
7446 (set_attr "length" "3")])
7448 ;; This is a call that may want a structure value. This is used for
7450 (define_insn "*call_address_untyped_struct_value_sp32"
7451 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
7452 (match_operand 1 "" ""))
7453 (match_operand 2 "immediate_operand" "")
7454 (clobber (reg:SI 15))]
7455 ;;- Do not use operand 1 for most machines.
7456 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
7457 "call\t%a0, %1\n\tnop\n\tnop"
7458 [(set_attr "type" "call_no_delay_slot")
7459 (set_attr "length" "3")])
7461 ;; This is a call that wants a structure value.
7462 (define_insn "*call_symbolic_untyped_struct_value_sp32"
7463 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
7464 (match_operand 1 "" ""))
7465 (match_operand 2 "immediate_operand" "")
7466 (clobber (reg:SI 15))]
7467 ;;- Do not use operand 1 for most machines.
7468 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
7469 "call\t%a0, %1\n\tnop\n\tnop"
7470 [(set_attr "type" "call_no_delay_slot")
7471 (set_attr "length" "3")])
7473 (define_expand "call_value"
7474 ;; Note that this expression is not used for generating RTL.
7475 ;; All the RTL is generated explicitly below.
7476 [(set (match_operand 0 "register_operand" "=rf")
7477 (call (match_operand 1 "" "")
7478 (match_operand 4 "" "")))]
7479 ;; operand 2 is stack_size_rtx
7480 ;; operand 3 is next_arg_register
7483 rtx fn_rtx, nregs_rtx;
7486 if (GET_MODE (operands[1]) != FUNCTION_MODE)
7489 fn_rtx = operands[1];
7493 nregs_rtx = GEN_INT (REGNO (operands[3]) - 8);
7495 nregs_rtx = GEN_INT (6);
7497 nregs_rtx = const0_rtx;
7501 gen_rtx_SET (VOIDmode, operands[0],
7502 gen_rtx_CALL (VOIDmode, fn_rtx, nregs_rtx)),
7503 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)));
7505 emit_call_insn (gen_rtx_PARALLEL (VOIDmode, vec));
7510 (define_insn "*call_value_address_sp32"
7511 [(set (match_operand 0 "" "=rf")
7512 (call (mem:SI (match_operand:SI 1 "address_operand" "p"))
7513 (match_operand 2 "" "")))
7514 (clobber (reg:SI 15))]
7515 ;;- Do not use operand 2 for most machines.
7518 [(set_attr "type" "call")])
7520 (define_insn "*call_value_symbolic_sp32"
7521 [(set (match_operand 0 "" "=rf")
7522 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
7523 (match_operand 2 "" "")))
7524 (clobber (reg:SI 15))]
7525 ;;- Do not use operand 2 for most machines.
7528 [(set_attr "type" "call")])
7530 (define_insn "*call_value_address_sp64"
7531 [(set (match_operand 0 "" "")
7532 (call (mem:DI (match_operand:DI 1 "address_operand" "p"))
7533 (match_operand 2 "" "")))
7534 (clobber (reg:DI 15))]
7535 ;;- Do not use operand 2 for most machines.
7538 [(set_attr "type" "call")])
7540 (define_insn "*call_value_symbolic_sp64"
7541 [(set (match_operand 0 "" "")
7542 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
7543 (match_operand 2 "" "")))
7544 (clobber (reg:DI 15))]
7545 ;;- Do not use operand 2 for most machines.
7548 [(set_attr "type" "call")])
7550 (define_expand "untyped_call"
7551 [(parallel [(call (match_operand 0 "" "")
7553 (match_operand 1 "" "")
7554 (match_operand 2 "" "")])]
7559 /* Pass constm1 to indicate that it may expect a structure value, but
7560 we don't know what size it is. */
7561 emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, constm1_rtx));
7563 for (i = 0; i < XVECLEN (operands[2], 0); i++)
7565 rtx set = XVECEXP (operands[2], 0, i);
7566 emit_move_insn (SET_DEST (set), SET_SRC (set));
7569 /* The optimizer does not know that the call sets the function value
7570 registers we stored in the result block. We avoid problems by
7571 claiming that all hard registers are used and clobbered at this
7573 emit_insn (gen_blockage ());
7579 (define_expand "sibcall"
7580 [(parallel [(call (match_operand 0 "call_operand" "") (const_int 0))
7585 (define_insn "*sibcall_symbolic_sp32"
7586 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
7587 (match_operand 1 "" ""))
7590 "* return output_sibcall(insn, operands[0]);"
7591 [(set_attr "type" "sibcall")])
7593 (define_insn "*sibcall_symbolic_sp64"
7594 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
7595 (match_operand 1 "" ""))
7598 "* return output_sibcall(insn, operands[0]);"
7599 [(set_attr "type" "sibcall")])
7601 (define_expand "sibcall_value"
7602 [(parallel [(set (match_operand 0 "register_operand" "=rf")
7603 (call (match_operand 1 "" "") (const_int 0)))
7608 (define_insn "*sibcall_value_symbolic_sp32"
7609 [(set (match_operand 0 "" "=rf")
7610 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
7611 (match_operand 2 "" "")))
7614 "* return output_sibcall(insn, operands[1]);"
7615 [(set_attr "type" "sibcall")])
7617 (define_insn "*sibcall_value_symbolic_sp64"
7618 [(set (match_operand 0 "" "")
7619 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
7620 (match_operand 2 "" "")))
7623 "* return output_sibcall(insn, operands[1]);"
7624 [(set_attr "type" "sibcall")])
7626 (define_expand "sibcall_epilogue"
7631 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
7632 ;; all of memory. This blocks insns from being moved across this point.
7634 (define_insn "blockage"
7635 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
7638 [(set_attr "length" "0")])
7640 ;; Prepare to return any type including a structure value.
7642 (define_expand "untyped_return"
7643 [(match_operand:BLK 0 "memory_operand" "")
7644 (match_operand 1 "" "")]
7647 rtx valreg1 = gen_rtx_REG (DImode, 24);
7648 rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
7649 rtx result = operands[0];
7651 if (! TARGET_ARCH64)
7653 rtx rtnreg = gen_rtx_REG (SImode, (current_function_uses_only_leaf_regs
7655 rtx value = gen_reg_rtx (SImode);
7657 /* Fetch the instruction where we will return to and see if it's an unimp
7658 instruction (the most significant 10 bits will be zero). If so,
7659 update the return address to skip the unimp instruction. */
7660 emit_move_insn (value,
7661 gen_rtx_MEM (SImode, plus_constant (rtnreg, 8)));
7662 emit_insn (gen_lshrsi3 (value, value, GEN_INT (22)));
7663 emit_insn (gen_update_return (rtnreg, value));
7666 /* Reload the function value registers. */
7667 emit_move_insn (valreg1, adjust_address (result, DImode, 0));
7668 emit_move_insn (valreg2,
7669 adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8));
7671 /* Put USE insns before the return. */
7672 emit_insn (gen_rtx_USE (VOIDmode, valreg1));
7673 emit_insn (gen_rtx_USE (VOIDmode, valreg2));
7675 /* Construct the return. */
7676 expand_null_return ();
7681 ;; This is a bit of a hack. We're incrementing a fixed register (%i7),
7682 ;; and parts of the compiler don't want to believe that the add is needed.
7684 (define_insn "update_return"
7685 [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
7686 (match_operand:SI 1 "register_operand" "r")] UNSPEC_UPDATE_RETURN)]
7688 "cmp\t%1, 0\;be,a\t.+8\;add\t%0, 4, %0"
7689 [(set_attr "type" "multi")
7690 (set_attr "length" "3")])
7697 (define_expand "indirect_jump"
7698 [(set (pc) (match_operand 0 "address_operand" "p"))]
7702 (define_insn "*branch_sp32"
7703 [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
7706 [(set_attr "type" "uncond_branch")])
7708 (define_insn "*branch_sp64"
7709 [(set (pc) (match_operand:DI 0 "address_operand" "p"))]
7712 [(set_attr "type" "uncond_branch")])
7714 ;; ??? Doesn't work with -mflat.
7715 (define_expand "nonlocal_goto"
7716 [(match_operand:SI 0 "general_operand" "")
7717 (match_operand:SI 1 "general_operand" "")
7718 (match_operand:SI 2 "general_operand" "")
7719 (match_operand:SI 3 "" "")]
7723 rtx chain = operands[0];
7725 rtx lab = operands[1];
7726 rtx stack = operands[2];
7727 rtx fp = operands[3];
7730 /* Trap instruction to flush all the register windows. */
7731 emit_insn (gen_flush_register_windows ());
7733 /* Load the fp value for the containing fn into %fp. This is needed
7734 because STACK refers to %fp. Note that virtual register instantiation
7735 fails if the virtual %fp isn't set from a register. */
7736 if (GET_CODE (fp) != REG)
7737 fp = force_reg (Pmode, fp);
7738 emit_move_insn (virtual_stack_vars_rtx, fp);
7740 /* Find the containing function's current nonlocal goto handler,
7741 which will do any cleanups and then jump to the label. */
7742 labreg = gen_rtx_REG (Pmode, 8);
7743 emit_move_insn (labreg, lab);
7745 /* Restore %fp from stack pointer value for containing function.
7746 The restore insn that follows will move this to %sp,
7747 and reload the appropriate value into %fp. */
7748 emit_move_insn (hard_frame_pointer_rtx, stack);
7750 /* USE of frame_pointer_rtx added for consistency; not clear if
7752 /*emit_insn (gen_rtx_USE (VOIDmode, frame_pointer_rtx));*/
7753 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
7756 /* Return, restoring reg window and jumping to goto handler. */
7757 if (TARGET_V9 && GET_CODE (chain) == CONST_INT
7758 && ! (INTVAL (chain) & ~(HOST_WIDE_INT)0xffffffff))
7760 emit_jump_insn (gen_goto_handler_and_restore_v9 (labreg,
7766 /* Put in the static chain register the nonlocal label address. */
7767 emit_move_insn (static_chain_rtx, chain);
7770 emit_insn (gen_rtx_USE (VOIDmode, static_chain_rtx));
7771 emit_jump_insn (gen_goto_handler_and_restore (labreg));
7776 ;; Special trap insn to flush register windows.
7777 (define_insn "flush_register_windows"
7778 [(unspec_volatile [(const_int 0)] UNSPECV_FLUSHW)]
7780 { return TARGET_V9 ? "flushw" : "ta\t3"; }
7781 [(set_attr "type" "flushw")])
7783 (define_insn "goto_handler_and_restore"
7784 [(unspec_volatile [(match_operand 0 "register_operand" "=r")] UNSPECV_GOTO)]
7785 "GET_MODE (operands[0]) == Pmode"
7786 "jmp\t%0+0\n\trestore"
7787 [(set_attr "type" "multi")
7788 (set_attr "length" "2")])
7790 ;;(define_insn "goto_handler_and_restore_v9"
7791 ;; [(unspec_volatile [(match_operand:SI 0 "register_operand" "=r,r")
7792 ;; (match_operand:SI 1 "register_operand" "=r,r")
7793 ;; (match_operand:SI 2 "const_int_operand" "I,n")] UNSPECV_GOTO_V9)]
7794 ;; "TARGET_V9 && ! TARGET_ARCH64"
7796 ;; return\t%0+0\n\tmov\t%2, %Y1
7797 ;; sethi\t%%hi(%2), %1\n\treturn\t%0+0\n\tor\t%Y1, %%lo(%2), %Y1"
7798 ;; [(set_attr "type" "multi")
7799 ;; (set_attr "length" "2,3")])
7801 ;;(define_insn "*goto_handler_and_restore_v9_sp64"
7802 ;; [(unspec_volatile [(match_operand:DI 0 "register_operand" "=r,r")
7803 ;; (match_operand:DI 1 "register_operand" "=r,r")
7804 ;; (match_operand:SI 2 "const_int_operand" "I,n")] UNSPECV_GOTO_V9)]
7805 ;; "TARGET_V9 && TARGET_ARCH64"
7807 ;; return\t%0+0\n\tmov\t%2, %Y1
7808 ;; sethi\t%%hi(%2), %1\n\treturn\t%0+0\n\tor\t%Y1, %%lo(%2), %Y1"
7809 ;; [(set_attr "type" "multi")
7810 ;; (set_attr "length" "2,3")])
7812 ;; For __builtin_setjmp we need to flush register windows iff the function
7813 ;; calls alloca as well, because otherwise the register window might be
7814 ;; saved after %sp adjustement and thus setjmp would crash
7815 (define_expand "builtin_setjmp_setup"
7816 [(match_operand 0 "register_operand" "r")]
7819 emit_insn (gen_do_builtin_setjmp_setup ());
7823 (define_insn "do_builtin_setjmp_setup"
7824 [(unspec_volatile [(const_int 0)] UNSPECV_SETJMP)]
7827 if (! current_function_calls_alloca)
7829 if (! TARGET_V9 || TARGET_FLAT)
7831 fputs ("\tflushw\n", asm_out_file);
7833 fprintf (asm_out_file, "\tst%c\t%%l7, [%%sp+%d]\n",
7834 TARGET_ARCH64 ? 'x' : 'w',
7835 SPARC_STACK_BIAS + 7 * UNITS_PER_WORD);
7836 fprintf (asm_out_file, "\tst%c\t%%fp, [%%sp+%d]\n",
7837 TARGET_ARCH64 ? 'x' : 'w',
7838 SPARC_STACK_BIAS + 14 * UNITS_PER_WORD);
7839 fprintf (asm_out_file, "\tst%c\t%%i7, [%%sp+%d]\n",
7840 TARGET_ARCH64 ? 'x' : 'w',
7841 SPARC_STACK_BIAS + 15 * UNITS_PER_WORD);
7844 [(set_attr "type" "multi")
7845 (set (attr "length")
7846 (cond [(eq_attr "current_function_calls_alloca" "false")
7848 (eq_attr "flat" "true")
7850 (eq_attr "isa" "!v9")
7852 (eq_attr "pic" "true")
7853 (const_int 4)] (const_int 3)))])
7855 ;; Pattern for use after a setjmp to store FP and the return register
7856 ;; into the stack area.
7858 (define_expand "setjmp"
7863 emit_insn (gen_setjmp_64 ());
7865 emit_insn (gen_setjmp_32 ());
7869 (define_expand "setjmp_32"
7870 [(set (mem:SI (plus:SI (reg:SI 14) (const_int 56))) (match_dup 0))
7871 (set (mem:SI (plus:SI (reg:SI 14) (const_int 60))) (reg:SI 31))]
7873 { operands[0] = frame_pointer_rtx; })
7875 (define_expand "setjmp_64"
7876 [(set (mem:DI (plus:DI (reg:DI 14) (const_int 112))) (match_dup 0))
7877 (set (mem:DI (plus:DI (reg:DI 14) (const_int 120))) (reg:DI 31))]
7879 { operands[0] = frame_pointer_rtx; })
7881 ;; Special pattern for the FLUSH instruction.
7883 ; We do SImode and DImode versions of this to quiet down genrecog's complaints
7884 ; of the define_insn otherwise missing a mode. We make "flush", aka
7885 ; gen_flush, the default one since sparc_initialize_trampoline uses
7886 ; it on SImode mem values.
7888 (define_insn "flush"
7889 [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")] UNSPECV_FLUSH)]
7891 { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; }
7892 [(set_attr "type" "iflush")])
7894 (define_insn "flushdi"
7895 [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")] UNSPECV_FLUSH)]
7897 { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; }
7898 [(set_attr "type" "iflush")])
7903 ;; The scan instruction searches from the most significant bit while ffs
7904 ;; searches from the least significant bit. The bit index and treatment of
7905 ;; zero also differ. It takes at least 7 instructions to get the proper
7906 ;; result. Here is an obvious 8 instruction sequence.
7909 (define_insn "ffssi2"
7910 [(set (match_operand:SI 0 "register_operand" "=&r")
7911 (ffs:SI (match_operand:SI 1 "register_operand" "r")))
7912 (clobber (match_scratch:SI 2 "=&r"))]
7913 "TARGET_SPARCLITE || TARGET_SPARCLET"
7915 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";
7917 [(set_attr "type" "multi")
7918 (set_attr "length" "8")])
7920 ;; ??? This should be a define expand, so that the extra instruction have
7921 ;; a chance of being optimized away.
7923 ;; Disabled because none of the UltraSPARCs implement popc. The HAL R1
7924 ;; does, but no one uses that and we don't have a switch for it.
7926 ;(define_insn "ffsdi2"
7927 ; [(set (match_operand:DI 0 "register_operand" "=&r")
7928 ; (ffs:DI (match_operand:DI 1 "register_operand" "r")))
7929 ; (clobber (match_scratch:DI 2 "=&r"))]
7931 ; "neg\t%1, %2\;xnor\t%1, %2, %2\;popc\t%2, %0\;movzr\t%1, 0, %0"
7932 ; [(set_attr "type" "multi")
7933 ; (set_attr "length" "4")])
7937 ;; Peepholes go at the end.
7939 ;; Optimize consecutive loads or stores into ldd and std when possible.
7940 ;; The conditions in which we do this are very restricted and are
7941 ;; explained in the code for {registers,memory}_ok_for_ldd functions.
7944 [(set (match_operand:SI 0 "memory_operand" "")
7946 (set (match_operand:SI 1 "memory_operand" "")
7949 && mems_ok_for_ldd_peep (operands[0], operands[1], NULL_RTX)"
7952 "operands[0] = widen_memory_access (operands[0], DImode, 0);")
7955 [(set (match_operand:SI 0 "memory_operand" "")
7957 (set (match_operand:SI 1 "memory_operand" "")
7960 && mems_ok_for_ldd_peep (operands[1], operands[0], NULL_RTX)"
7963 "operands[1] = widen_memory_access (operands[1], DImode, 0);")
7966 [(set (match_operand:SI 0 "register_operand" "")
7967 (match_operand:SI 1 "memory_operand" ""))
7968 (set (match_operand:SI 2 "register_operand" "")
7969 (match_operand:SI 3 "memory_operand" ""))]
7970 "registers_ok_for_ldd_peep (operands[0], operands[2])
7971 && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
7974 "operands[1] = widen_memory_access (operands[1], DImode, 0);
7975 operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));")
7978 [(set (match_operand:SI 0 "memory_operand" "")
7979 (match_operand:SI 1 "register_operand" ""))
7980 (set (match_operand:SI 2 "memory_operand" "")
7981 (match_operand:SI 3 "register_operand" ""))]
7982 "registers_ok_for_ldd_peep (operands[1], operands[3])
7983 && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
7986 "operands[0] = widen_memory_access (operands[0], DImode, 0);
7987 operands[1] = gen_rtx_REG (DImode, REGNO (operands[1]));")
7990 [(set (match_operand:SF 0 "register_operand" "")
7991 (match_operand:SF 1 "memory_operand" ""))
7992 (set (match_operand:SF 2 "register_operand" "")
7993 (match_operand:SF 3 "memory_operand" ""))]
7994 "registers_ok_for_ldd_peep (operands[0], operands[2])
7995 && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
7998 "operands[1] = widen_memory_access (operands[1], DFmode, 0);
7999 operands[0] = gen_rtx_REG (DFmode, REGNO (operands[0]));")
8002 [(set (match_operand:SF 0 "memory_operand" "")
8003 (match_operand:SF 1 "register_operand" ""))
8004 (set (match_operand:SF 2 "memory_operand" "")
8005 (match_operand:SF 3 "register_operand" ""))]
8006 "registers_ok_for_ldd_peep (operands[1], operands[3])
8007 && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
8010 "operands[0] = widen_memory_access (operands[0], DFmode, 0);
8011 operands[1] = gen_rtx_REG (DFmode, REGNO (operands[1]));")
8014 [(set (match_operand:SI 0 "register_operand" "")
8015 (match_operand:SI 1 "memory_operand" ""))
8016 (set (match_operand:SI 2 "register_operand" "")
8017 (match_operand:SI 3 "memory_operand" ""))]
8018 "registers_ok_for_ldd_peep (operands[2], operands[0])
8019 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
8022 "operands[3] = widen_memory_access (operands[3], DImode, 0);
8023 operands[2] = gen_rtx_REG (DImode, REGNO (operands[2]));")
8026 [(set (match_operand:SI 0 "memory_operand" "")
8027 (match_operand:SI 1 "register_operand" ""))
8028 (set (match_operand:SI 2 "memory_operand" "")
8029 (match_operand:SI 3 "register_operand" ""))]
8030 "registers_ok_for_ldd_peep (operands[3], operands[1])
8031 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
8034 "operands[2] = widen_memory_access (operands[2], DImode, 0);
8035 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
8039 [(set (match_operand:SF 0 "register_operand" "")
8040 (match_operand:SF 1 "memory_operand" ""))
8041 (set (match_operand:SF 2 "register_operand" "")
8042 (match_operand:SF 3 "memory_operand" ""))]
8043 "registers_ok_for_ldd_peep (operands[2], operands[0])
8044 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
8047 "operands[3] = widen_memory_access (operands[3], DFmode, 0);
8048 operands[2] = gen_rtx_REG (DFmode, REGNO (operands[2]));")
8051 [(set (match_operand:SF 0 "memory_operand" "")
8052 (match_operand:SF 1 "register_operand" ""))
8053 (set (match_operand:SF 2 "memory_operand" "")
8054 (match_operand:SF 3 "register_operand" ""))]
8055 "registers_ok_for_ldd_peep (operands[3], operands[1])
8056 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
8059 "operands[2] = widen_memory_access (operands[2], DFmode, 0);
8060 operands[3] = gen_rtx_REG (DFmode, REGNO (operands[3]));")
8062 ;; Optimize the case of following a reg-reg move with a test
8063 ;; of reg just moved. Don't allow floating point regs for operand 0 or 1.
8064 ;; This can result from a float to fix conversion.
8067 [(set (match_operand:SI 0 "register_operand" "")
8068 (match_operand:SI 1 "register_operand" ""))
8070 (compare:CC (match_operand:SI 2 "register_operand" "")
8072 "(rtx_equal_p (operands[2], operands[0])
8073 || rtx_equal_p (operands[2], operands[1]))
8074 && ! SPARC_FP_REG_P (REGNO (operands[0]))
8075 && ! SPARC_FP_REG_P (REGNO (operands[1]))"
8076 [(parallel [(set (match_dup 0) (match_dup 1))
8078 (compare:CC (match_dup 1) (const_int 0)))])]
8082 [(set (match_operand:DI 0 "register_operand" "")
8083 (match_operand:DI 1 "register_operand" ""))
8085 (compare:CCX (match_operand:DI 2 "register_operand" "")
8088 && (rtx_equal_p (operands[2], operands[0])
8089 || rtx_equal_p (operands[2], operands[1]))
8090 && ! SPARC_FP_REG_P (REGNO (operands[0]))
8091 && ! SPARC_FP_REG_P (REGNO (operands[1]))"
8092 [(parallel [(set (match_dup 0) (match_dup 1))
8094 (compare:CCX (match_dup 1) (const_int 0)))])]
8097 ;; Return peepholes. These are generated by sparc_nonflat_function_epilogue
8098 ;; who then immediately calls final_scan_insn.
8100 (define_insn "*return_qi"
8101 [(set (match_operand:QI 0 "restore_operand" "")
8102 (match_operand:QI 1 "arith_operand" "rI"))
8104 "sparc_emitting_epilogue"
8106 if (! TARGET_ARCH64 && current_function_returns_struct)
8107 return "jmp\t%%i7+12\n\trestore %%g0, %1, %Y0";
8108 else if (TARGET_V9 && (GET_CODE (operands[1]) == CONST_INT
8109 || IN_OR_GLOBAL_P (operands[1])))
8110 return "return\t%%i7+8\n\tmov\t%Y1, %Y0";
8112 return "ret\n\trestore %%g0, %1, %Y0";
8114 [(set_attr "type" "multi")
8115 (set_attr "length" "2")])
8117 (define_insn "*return_hi"
8118 [(set (match_operand:HI 0 "restore_operand" "")
8119 (match_operand:HI 1 "arith_operand" "rI"))
8121 "sparc_emitting_epilogue"
8123 if (! TARGET_ARCH64 && current_function_returns_struct)
8124 return "jmp\t%%i7+12\n\trestore %%g0, %1, %Y0";
8125 else if (TARGET_V9 && (GET_CODE (operands[1]) == CONST_INT
8126 || IN_OR_GLOBAL_P (operands[1])))
8127 return "return\t%%i7+8\n\tmov\t%Y1, %Y0";
8129 return "ret\;restore %%g0, %1, %Y0";
8131 [(set_attr "type" "multi")
8132 (set_attr "length" "2")])
8134 (define_insn "*return_si"
8135 [(set (match_operand:SI 0 "restore_operand" "")
8136 (match_operand:SI 1 "arith_operand" "rI"))
8138 "sparc_emitting_epilogue"
8140 if (! TARGET_ARCH64 && current_function_returns_struct)
8141 return "jmp\t%%i7+12\n\trestore %%g0, %1, %Y0";
8142 else if (TARGET_V9 && (GET_CODE (operands[1]) == CONST_INT
8143 || IN_OR_GLOBAL_P (operands[1])))
8144 return "return\t%%i7+8\n\tmov\t%Y1, %Y0";
8146 return "ret\;restore %%g0, %1, %Y0";
8148 [(set_attr "type" "multi")
8149 (set_attr "length" "2")])
8151 (define_insn "*return_sf_no_fpu"
8152 [(set (match_operand:SF 0 "restore_operand" "=r")
8153 (match_operand:SF 1 "register_operand" "r"))
8155 "sparc_emitting_epilogue"
8157 if (! TARGET_ARCH64 && current_function_returns_struct)
8158 return "jmp\t%%i7+12\n\trestore %%g0, %1, %Y0";
8159 else if (TARGET_V9 && IN_OR_GLOBAL_P (operands[1]))
8160 return "return\t%%i7+8\n\tmov\t%Y1, %Y0";
8162 return "ret\;restore %%g0, %1, %Y0";
8164 [(set_attr "type" "multi")
8165 (set_attr "length" "2")])
8167 (define_insn "*return_df_no_fpu"
8168 [(set (match_operand:DF 0 "restore_operand" "=r")
8169 (match_operand:DF 1 "register_operand" "r"))
8171 "sparc_emitting_epilogue && TARGET_ARCH64"
8173 if (IN_OR_GLOBAL_P (operands[1]))
8174 return "return\t%%i7+8\n\tmov\t%Y1, %Y0";
8176 return "ret\;restore %%g0, %1, %Y0";
8178 [(set_attr "type" "multi")
8179 (set_attr "length" "2")])
8181 (define_insn "*return_addsi"
8182 [(set (match_operand:SI 0 "restore_operand" "")
8183 (plus:SI (match_operand:SI 1 "register_operand" "r")
8184 (match_operand:SI 2 "arith_operand" "rI")))
8186 "sparc_emitting_epilogue"
8188 if (! TARGET_ARCH64 && current_function_returns_struct)
8189 return "jmp\t%%i7+12\n\trestore %r1, %2, %Y0";
8190 /* If operands are global or in registers, can use return */
8191 else if (TARGET_V9 && IN_OR_GLOBAL_P (operands[1])
8192 && (GET_CODE (operands[2]) == CONST_INT
8193 || IN_OR_GLOBAL_P (operands[2])))
8194 return "return\t%%i7+8\n\tadd\t%Y1, %Y2, %Y0";
8196 return "ret\;restore %r1, %2, %Y0";
8198 [(set_attr "type" "multi")
8199 (set_attr "length" "2")])
8201 (define_insn "*return_losum_si"
8202 [(set (match_operand:SI 0 "restore_operand" "")
8203 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
8204 (match_operand:SI 2 "immediate_operand" "in")))
8206 "sparc_emitting_epilogue && ! TARGET_CM_MEDMID"
8208 if (! TARGET_ARCH64 && current_function_returns_struct)
8209 return "jmp\t%%i7+12\n\trestore %r1, %%lo(%a2), %Y0";
8210 /* If operands are global or in registers, can use return */
8211 else if (TARGET_V9 && IN_OR_GLOBAL_P (operands[1]))
8212 return "return\t%%i7+8\n\tor\t%Y1, %%lo(%a2), %Y0";
8214 return "ret\;restore %r1, %%lo(%a2), %Y0";
8216 [(set_attr "type" "multi")
8217 (set_attr "length" "2")])
8219 (define_insn "*return_di"
8220 [(set (match_operand:DI 0 "restore_operand" "")
8221 (match_operand:DI 1 "arith_double_operand" "rHI"))
8223 "sparc_emitting_epilogue && TARGET_ARCH64"
8224 "ret\;restore %%g0, %1, %Y0"
8225 [(set_attr "type" "multi")
8226 (set_attr "length" "2")])
8228 (define_insn "*return_adddi"
8229 [(set (match_operand:DI 0 "restore_operand" "")
8230 (plus:DI (match_operand:DI 1 "arith_operand" "%r")
8231 (match_operand:DI 2 "arith_double_operand" "rHI")))
8233 "sparc_emitting_epilogue && TARGET_ARCH64"
8234 "ret\;restore %r1, %2, %Y0"
8235 [(set_attr "type" "multi")
8236 (set_attr "length" "2")])
8238 (define_insn "*return_losum_di"
8239 [(set (match_operand:DI 0 "restore_operand" "")
8240 (lo_sum:DI (match_operand:DI 1 "arith_operand" "%r")
8241 (match_operand:DI 2 "immediate_operand" "in")))
8243 "sparc_emitting_epilogue && TARGET_ARCH64 && ! TARGET_CM_MEDMID"
8244 "ret\;restore %r1, %%lo(%a2), %Y0"
8245 [(set_attr "type" "multi")
8246 (set_attr "length" "2")])
8248 (define_insn "*return_sf"
8250 (match_operand:SF 0 "register_operand" "f"))
8252 "sparc_emitting_epilogue"
8253 "ret\;fmovs\t%0, %%f0"
8254 [(set_attr "type" "multi")
8255 (set_attr "length" "2")])
8257 ;; Now peepholes to do a call followed by a jump.
8260 [(parallel [(set (match_operand 0 "" "")
8261 (call (mem:SI (match_operand:SI 1 "call_operand_address" "ps"))
8262 (match_operand 2 "" "")))
8263 (clobber (reg:SI 15))])
8264 (set (pc) (label_ref (match_operand 3 "" "")))]
8265 "short_branch (INSN_UID (insn), INSN_UID (operands[3]))
8266 && (USING_SJLJ_EXCEPTIONS || ! can_throw_internal (ins1))
8267 && sparc_cpu != PROCESSOR_ULTRASPARC
8268 && sparc_cpu != PROCESSOR_ULTRASPARC3"
8269 "call\t%a1, %2\n\tadd\t%%o7, (%l3-.-4), %%o7")
8272 [(parallel [(call (mem:SI (match_operand:SI 0 "call_operand_address" "ps"))
8273 (match_operand 1 "" ""))
8274 (clobber (reg:SI 15))])
8275 (set (pc) (label_ref (match_operand 2 "" "")))]
8276 "short_branch (INSN_UID (insn), INSN_UID (operands[2]))
8277 && (USING_SJLJ_EXCEPTIONS || ! can_throw_internal (ins1))
8278 && sparc_cpu != PROCESSOR_ULTRASPARC
8279 && sparc_cpu != PROCESSOR_ULTRASPARC3"
8280 "call\t%a0, %1\n\tadd\t%%o7, (%l2-.-4), %%o7")
8282 ;; ??? UltraSPARC-III note: A memory operation loading into the floating point register
8283 ;; ??? file, if it hits the prefetch cache, has a chance to dual-issue with other memory
8284 ;; ??? operations. With DFA we might be able to model this, but it requires a lot of
8286 (define_expand "prefetch"
8287 [(match_operand 0 "address_operand" "")
8288 (match_operand 1 "const_int_operand" "")
8289 (match_operand 2 "const_int_operand" "")]
8293 emit_insn (gen_prefetch_64 (operands[0], operands[1], operands[2]));
8295 emit_insn (gen_prefetch_32 (operands[0], operands[1], operands[2]));
8299 (define_insn "prefetch_64"
8300 [(prefetch (match_operand:DI 0 "address_operand" "p")
8301 (match_operand:DI 1 "const_int_operand" "n")
8302 (match_operand:DI 2 "const_int_operand" "n"))]
8305 static const char * const prefetch_instr[2][2] = {
8307 "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
8308 "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
8311 "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
8312 "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
8315 int read_or_write = INTVAL (operands[1]);
8316 int locality = INTVAL (operands[2]);
8318 if (read_or_write != 0 && read_or_write != 1)
8320 if (locality < 0 || locality > 3)
8322 return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
8324 [(set_attr "type" "load")])
8326 (define_insn "prefetch_32"
8327 [(prefetch (match_operand:SI 0 "address_operand" "p")
8328 (match_operand:SI 1 "const_int_operand" "n")
8329 (match_operand:SI 2 "const_int_operand" "n"))]
8332 static const char * const prefetch_instr[2][2] = {
8334 "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
8335 "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
8338 "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
8339 "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
8342 int read_or_write = INTVAL (operands[1]);
8343 int locality = INTVAL (operands[2]);
8345 if (read_or_write != 0 && read_or_write != 1)
8347 if (locality < 0 || locality > 3)
8349 return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
8351 [(set_attr "type" "load")])
8353 (define_expand "prologue"
8355 "flag_pic && current_function_uses_pic_offset_table"
8357 load_pic_register ();
8361 ;; We need to reload %l7 for -mflat -fpic,
8362 ;; otherwise %l7 should be preserved simply
8363 ;; by loading the function's register window
8364 (define_expand "exception_receiver"
8366 "TARGET_FLAT && flag_pic"
8368 load_pic_register ();
8373 (define_expand "builtin_setjmp_receiver"
8374 [(label_ref (match_operand 0 "" ""))]
8375 "TARGET_FLAT && flag_pic"
8377 load_pic_register ();
8382 [(trap_if (const_int 1) (const_int 5))]
8385 [(set_attr "type" "trap")])
8387 (define_expand "conditional_trap"
8388 [(trap_if (match_operator 0 "noov_compare_op"
8389 [(match_dup 2) (match_dup 3)])
8390 (match_operand:SI 1 "arith_operand" ""))]
8392 "operands[2] = gen_compare_reg (GET_CODE (operands[0]),
8393 sparc_compare_op0, sparc_compare_op1);
8394 operands[3] = const0_rtx;")
8397 [(trap_if (match_operator 0 "noov_compare_op" [(reg:CC 100) (const_int 0)])
8398 (match_operand:SI 1 "arith_operand" "rM"))]
8401 [(set_attr "type" "trap")])
8404 [(trap_if (match_operator 0 "noov_compare_op" [(reg:CCX 100) (const_int 0)])
8405 (match_operand:SI 1 "arith_operand" "rM"))]
8408 [(set_attr "type" "trap")])