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,?e,?e,?W")
2066 (match_operand:DI 1 "input_operand"
2067 " J,J,U,T,r,o,i,r, f, T, o, f, e, W, e"))]
2068 "! TARGET_ARCH64 && TARGET_V9
2069 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2086 [(set_attr "type" "store,store,store,load,*,*,*,*,fpstore,fpload,*,*,fpmove,fpload,fpstore")
2087 (set_attr "length" "*,2,*,*,2,2,2,2,*,*,2,2,*,*,*")
2088 (set_attr "fptype" "*,*,*,*,*,*,*,*,*,*,*,*,double,*,*")])
2090 (define_insn "*movdi_insn_sp32"
2091 [(set (match_operand:DI 0 "nonimmediate_operand"
2092 "=o,T,U,o,r,r,r,?T,?f,?f,?o,?f")
2093 (match_operand:DI 1 "input_operand"
2094 " J,U,T,r,o,i,r, f, T, o, f, f"))]
2096 && (register_operand (operands[0], DImode)
2097 || register_operand (operands[1], DImode))"
2111 [(set_attr "type" "store,store,load,*,*,*,*,fpstore,fpload,*,*,*")
2112 (set_attr "length" "2,*,*,2,2,2,2,*,*,2,2,2")])
2114 ;; The following are generated by sparc_emit_set_const64
2115 (define_insn "*movdi_sp64_dbl"
2116 [(set (match_operand:DI 0 "register_operand" "=r")
2117 (match_operand:DI 1 "const64_operand" ""))]
2119 && HOST_BITS_PER_WIDE_INT != 64)"
2122 ;; This is needed to show CSE exactly which bits are set
2123 ;; in a 64-bit register by sethi instructions.
2124 (define_insn "*movdi_const64_special"
2125 [(set (match_operand:DI 0 "register_operand" "=r")
2126 (match_operand:DI 1 "const64_high_operand" ""))]
2128 "sethi\t%%hi(%a1), %0")
2130 (define_insn "*movdi_insn_sp64_novis"
2131 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,m,?e,?e,?W")
2132 (match_operand:DI 1 "input_operand" "rI,N,J,m,rJ,e,W,e"))]
2133 "TARGET_ARCH64 && ! TARGET_VIS
2134 && (register_operand (operands[0], DImode)
2135 || reg_or_0_operand (operands[1], DImode))"
2138 sethi\t%%hi(%a1), %0
2145 [(set_attr "type" "*,*,*,load,store,fpmove,fpload,fpstore")
2146 (set_attr "fptype" "*,*,*,*,*,double,*,*")])
2148 (define_insn "*movdi_insn_sp64_vis"
2149 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,m,?e,?e,?W,b")
2150 (match_operand:DI 1 "input_operand" "rI,N,J,m,rJ,e,W,e,J"))]
2151 "TARGET_ARCH64 && TARGET_VIS &&
2152 (register_operand (operands[0], DImode)
2153 || reg_or_0_operand (operands[1], DImode))"
2156 sethi\t%%hi(%a1), %0
2164 [(set_attr "type" "*,*,*,load,store,fpmove,fpload,fpstore,fpmove")
2165 (set_attr "fptype" "*,*,*,*,*,double,*,*,double")])
2167 (define_expand "movdi_pic_label_ref"
2168 [(set (match_dup 3) (high:DI
2169 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
2170 (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
2171 (set (match_dup 4) (lo_sum:DI (match_dup 3)
2172 (unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
2173 (set (match_operand:DI 0 "register_operand" "=r")
2174 (minus:DI (match_dup 5) (match_dup 4)))]
2175 "TARGET_ARCH64 && flag_pic"
2177 current_function_uses_pic_offset_table = 1;
2178 operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
2181 operands[3] = operands[0];
2182 operands[4] = operands[0];
2186 operands[3] = gen_reg_rtx (DImode);
2187 operands[4] = gen_reg_rtx (DImode);
2189 operands[5] = pic_offset_table_rtx;
2192 (define_insn "*movdi_high_pic_label_ref"
2193 [(set (match_operand:DI 0 "register_operand" "=r")
2195 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
2196 (match_operand:DI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
2197 "TARGET_ARCH64 && flag_pic"
2198 "sethi\t%%hi(%a2-(%a1-.)), %0")
2200 (define_insn "*movdi_lo_sum_pic_label_ref"
2201 [(set (match_operand:DI 0 "register_operand" "=r")
2202 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2203 (unspec:DI [(match_operand:DI 2 "label_ref_operand" "")
2204 (match_operand:DI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
2205 "TARGET_ARCH64 && flag_pic"
2206 "or\t%1, %%lo(%a3-(%a2-.)), %0")
2208 ;; SPARC-v9 code model support insns. See sparc_emit_set_symbolic_const64
2209 ;; in sparc.c to see what is going on here... PIC stuff comes first.
2211 (define_insn "movdi_lo_sum_pic"
2212 [(set (match_operand:DI 0 "register_operand" "=r")
2213 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2214 (unspec:DI [(match_operand:DI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
2215 "TARGET_ARCH64 && flag_pic"
2216 "or\t%1, %%lo(%a2), %0")
2218 (define_insn "movdi_high_pic"
2219 [(set (match_operand:DI 0 "register_operand" "=r")
2220 (high:DI (unspec:DI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
2221 "TARGET_ARCH64 && flag_pic && check_pic (1)"
2222 "sethi\t%%hi(%a1), %0")
2224 (define_insn "*sethi_di_medlow_embmedany_pic"
2225 [(set (match_operand:DI 0 "register_operand" "=r")
2226 (high:DI (match_operand:DI 1 "sp64_medium_pic_operand" "")))]
2227 "(TARGET_CM_MEDLOW || TARGET_CM_EMBMEDANY) && check_pic (1)"
2228 "sethi\t%%hi(%a1), %0")
2230 (define_insn "*sethi_di_medlow"
2231 [(set (match_operand:DI 0 "register_operand" "=r")
2232 (high:DI (match_operand:DI 1 "symbolic_operand" "")))]
2233 "TARGET_CM_MEDLOW && check_pic (1)"
2234 "sethi\t%%hi(%a1), %0")
2236 (define_insn "*losum_di_medlow"
2237 [(set (match_operand:DI 0 "register_operand" "=r")
2238 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2239 (match_operand:DI 2 "symbolic_operand" "")))]
2241 "or\t%1, %%lo(%a2), %0")
2243 (define_insn "seth44"
2244 [(set (match_operand:DI 0 "register_operand" "=r")
2245 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETH44)))]
2247 "sethi\t%%h44(%a1), %0")
2249 (define_insn "setm44"
2250 [(set (match_operand:DI 0 "register_operand" "=r")
2251 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2252 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_SETM44)))]
2254 "or\t%1, %%m44(%a2), %0")
2256 (define_insn "setl44"
2257 [(set (match_operand:DI 0 "register_operand" "=r")
2258 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2259 (match_operand:DI 2 "symbolic_operand" "")))]
2261 "or\t%1, %%l44(%a2), %0")
2263 (define_insn "sethh"
2264 [(set (match_operand:DI 0 "register_operand" "=r")
2265 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETHH)))]
2267 "sethi\t%%hh(%a1), %0")
2269 (define_insn "setlm"
2270 [(set (match_operand:DI 0 "register_operand" "=r")
2271 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETLM)))]
2273 "sethi\t%%lm(%a1), %0")
2275 (define_insn "sethm"
2276 [(set (match_operand:DI 0 "register_operand" "=r")
2277 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2278 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_EMB_SETHM)))]
2280 "or\t%1, %%hm(%a2), %0")
2282 (define_insn "setlo"
2283 [(set (match_operand:DI 0 "register_operand" "=r")
2284 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2285 (match_operand:DI 2 "symbolic_operand" "")))]
2287 "or\t%1, %%lo(%a2), %0")
2289 (define_insn "embmedany_sethi"
2290 [(set (match_operand:DI 0 "register_operand" "=r")
2291 (high:DI (unspec:DI [(match_operand:DI 1 "data_segment_operand" "")] UNSPEC_EMB_HISUM)))]
2292 "TARGET_CM_EMBMEDANY && check_pic (1)"
2293 "sethi\t%%hi(%a1), %0")
2295 (define_insn "embmedany_losum"
2296 [(set (match_operand:DI 0 "register_operand" "=r")
2297 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2298 (match_operand:DI 2 "data_segment_operand" "")))]
2299 "TARGET_CM_EMBMEDANY"
2300 "add\t%1, %%lo(%a2), %0")
2302 (define_insn "embmedany_brsum"
2303 [(set (match_operand:DI 0 "register_operand" "=r")
2304 (unspec:DI [(match_operand:DI 1 "register_operand" "r")] UNSPEC_EMB_HISUM))]
2305 "TARGET_CM_EMBMEDANY"
2308 (define_insn "embmedany_textuhi"
2309 [(set (match_operand:DI 0 "register_operand" "=r")
2310 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTUHI)))]
2311 "TARGET_CM_EMBMEDANY && check_pic (1)"
2312 "sethi\t%%uhi(%a1), %0")
2314 (define_insn "embmedany_texthi"
2315 [(set (match_operand:DI 0 "register_operand" "=r")
2316 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTHI)))]
2317 "TARGET_CM_EMBMEDANY && check_pic (1)"
2318 "sethi\t%%hi(%a1), %0")
2320 (define_insn "embmedany_textulo"
2321 [(set (match_operand:DI 0 "register_operand" "=r")
2322 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2323 (unspec:DI [(match_operand:DI 2 "text_segment_operand" "")] UNSPEC_EMB_TEXTULO)))]
2324 "TARGET_CM_EMBMEDANY"
2325 "or\t%1, %%ulo(%a2), %0")
2327 (define_insn "embmedany_textlo"
2328 [(set (match_operand:DI 0 "register_operand" "=r")
2329 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2330 (match_operand:DI 2 "text_segment_operand" "")))]
2331 "TARGET_CM_EMBMEDANY"
2332 "or\t%1, %%lo(%a2), %0")
2334 ;; Now some patterns to help reload out a bit.
2335 (define_expand "reload_indi"
2336 [(parallel [(match_operand:DI 0 "register_operand" "=r")
2337 (match_operand:DI 1 "immediate_operand" "")
2338 (match_operand:TI 2 "register_operand" "=&r")])]
2340 || TARGET_CM_EMBMEDANY)
2343 sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
2347 (define_expand "reload_outdi"
2348 [(parallel [(match_operand:DI 0 "register_operand" "=r")
2349 (match_operand:DI 1 "immediate_operand" "")
2350 (match_operand:TI 2 "register_operand" "=&r")])]
2352 || TARGET_CM_EMBMEDANY)
2355 sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
2359 ;; Split up putting CONSTs and REGs into DI regs when !arch64
2361 [(set (match_operand:DI 0 "register_operand" "")
2362 (match_operand:DI 1 "const_int_operand" ""))]
2363 "! TARGET_ARCH64 && reload_completed"
2364 [(clobber (const_int 0))]
2366 #if HOST_BITS_PER_WIDE_INT == 32
2367 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
2368 (INTVAL (operands[1]) < 0) ?
2371 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2374 unsigned int low, high;
2376 low = trunc_int_for_mode (INTVAL (operands[1]), SImode);
2377 high = trunc_int_for_mode (INTVAL (operands[1]) >> 32, SImode);
2378 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), GEN_INT (high)));
2380 /* Slick... but this trick loses if this subreg constant part
2381 can be done in one insn. */
2382 if (low == high && (low & 0x3ff) != 0 && low + 0x1000 >= 0x2000)
2383 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2384 gen_highpart (SImode, operands[0])));
2386 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), GEN_INT (low)));
2392 [(set (match_operand:DI 0 "register_operand" "")
2393 (match_operand:DI 1 "const_double_operand" ""))]
2397 && ((GET_CODE (operands[0]) == REG
2398 && REGNO (operands[0]) < 32)
2399 || (GET_CODE (operands[0]) == SUBREG
2400 && GET_CODE (SUBREG_REG (operands[0])) == REG
2401 && REGNO (SUBREG_REG (operands[0])) < 32))))"
2402 [(clobber (const_int 0))]
2404 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
2405 GEN_INT (CONST_DOUBLE_HIGH (operands[1]))));
2407 /* Slick... but this trick loses if this subreg constant part
2408 can be done in one insn. */
2409 if (CONST_DOUBLE_LOW (operands[1]) == CONST_DOUBLE_HIGH (operands[1])
2410 && !(SPARC_SETHI32_P (CONST_DOUBLE_HIGH (operands[1]))
2411 || SPARC_SIMM13_P (CONST_DOUBLE_HIGH (operands[1]))))
2413 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2414 gen_highpart (SImode, operands[0])));
2418 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2419 GEN_INT (CONST_DOUBLE_LOW (operands[1]))));
2425 [(set (match_operand:DI 0 "register_operand" "")
2426 (match_operand:DI 1 "register_operand" ""))]
2430 && ((GET_CODE (operands[0]) == REG
2431 && REGNO (operands[0]) < 32)
2432 || (GET_CODE (operands[0]) == SUBREG
2433 && GET_CODE (SUBREG_REG (operands[0])) == REG
2434 && REGNO (SUBREG_REG (operands[0])) < 32))))"
2435 [(clobber (const_int 0))]
2437 rtx set_dest = operands[0];
2438 rtx set_src = operands[1];
2442 dest1 = gen_highpart (SImode, set_dest);
2443 dest2 = gen_lowpart (SImode, set_dest);
2444 src1 = gen_highpart (SImode, set_src);
2445 src2 = gen_lowpart (SImode, set_src);
2447 /* Now emit using the real source and destination we found, swapping
2448 the order if we detect overlap. */
2449 if (reg_overlap_mentioned_p (dest1, src2))
2451 emit_insn (gen_movsi (dest2, src2));
2452 emit_insn (gen_movsi (dest1, src1));
2456 emit_insn (gen_movsi (dest1, src1));
2457 emit_insn (gen_movsi (dest2, src2));
2462 ;; Now handle the cases of memory moves from/to non-even
2463 ;; DI mode register pairs.
2465 [(set (match_operand:DI 0 "register_operand" "")
2466 (match_operand:DI 1 "memory_operand" ""))]
2469 && sparc_splitdi_legitimate (operands[0], operands[1]))"
2470 [(clobber (const_int 0))]
2472 rtx word0 = adjust_address (operands[1], SImode, 0);
2473 rtx word1 = adjust_address (operands[1], SImode, 4);
2474 rtx high_part = gen_highpart (SImode, operands[0]);
2475 rtx low_part = gen_lowpart (SImode, operands[0]);
2477 if (reg_overlap_mentioned_p (high_part, word1))
2479 emit_insn (gen_movsi (low_part, word1));
2480 emit_insn (gen_movsi (high_part, word0));
2484 emit_insn (gen_movsi (high_part, word0));
2485 emit_insn (gen_movsi (low_part, word1));
2491 [(set (match_operand:DI 0 "memory_operand" "")
2492 (match_operand:DI 1 "register_operand" ""))]
2495 && sparc_splitdi_legitimate (operands[1], operands[0]))"
2496 [(clobber (const_int 0))]
2498 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0),
2499 gen_highpart (SImode, operands[1])));
2500 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4),
2501 gen_lowpart (SImode, operands[1])));
2506 [(set (match_operand:DI 0 "memory_operand" "")
2511 && ! mem_min_alignment (operands[0], 8)))
2512 && offsettable_memref_p (operands[0])"
2513 [(clobber (const_int 0))]
2515 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0), const0_rtx));
2516 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4), const0_rtx));
2520 ;; Floating point move insns
2522 (define_insn "*movsf_insn_novis"
2523 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,*r,*r,*r,*r,*r,f,m,m")
2524 (match_operand:SF 1 "input_operand" "f,G,Q,*rR,S,m,m,f,*rG"))]
2525 "(TARGET_FPU && ! TARGET_VIS)
2526 && (register_operand (operands[0], SFmode)
2527 || register_operand (operands[1], SFmode)
2528 || fp_zero_operand (operands[1], SFmode))"
2530 if (GET_CODE (operands[1]) == CONST_DOUBLE
2531 && (which_alternative == 2
2532 || which_alternative == 3
2533 || which_alternative == 4))
2538 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2539 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2540 operands[1] = GEN_INT (i);
2543 switch (which_alternative)
2546 return "fmovs\t%1, %0";
2550 return "sethi\t%%hi(%a1), %0";
2552 return "mov\t%1, %0";
2557 return "ld\t%1, %0";
2560 return "st\t%r1, %0";
2565 [(set_attr "type" "fpmove,*,*,*,*,load,fpload,fpstore,store")])
2567 (define_insn "*movsf_insn_vis"
2568 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,*r,*r,*r,*r,*r,f,m,m")
2569 (match_operand:SF 1 "input_operand" "f,G,G,Q,*rR,S,m,m,f,*rG"))]
2570 "(TARGET_FPU && TARGET_VIS)
2571 && (register_operand (operands[0], SFmode)
2572 || register_operand (operands[1], SFmode)
2573 || fp_zero_operand (operands[1], SFmode))"
2575 if (GET_CODE (operands[1]) == CONST_DOUBLE
2576 && (which_alternative == 3
2577 || which_alternative == 4
2578 || which_alternative == 5))
2583 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2584 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2585 operands[1] = GEN_INT (i);
2588 switch (which_alternative)
2591 return "fmovs\t%1, %0";
2593 return "fzeros\t%0";
2597 return "sethi\t%%hi(%a1), %0";
2599 return "mov\t%1, %0";
2604 return "ld\t%1, %0";
2607 return "st\t%r1, %0";
2612 [(set_attr "type" "fpmove,fpmove,*,*,*,*,load,fpload,fpstore,store")])
2614 ;; Exactly the same as above, except that all `f' cases are deleted.
2615 ;; This is necessary to prevent reload from ever trying to use a `f' reg
2618 (define_insn "*movsf_no_f_insn"
2619 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r,r,r,m")
2620 (match_operand:SF 1 "input_operand" "G,Q,rR,S,m,rG"))]
2622 && (register_operand (operands[0], SFmode)
2623 || register_operand (operands[1], SFmode)
2624 || fp_zero_operand (operands[1], SFmode))"
2626 if (GET_CODE (operands[1]) == CONST_DOUBLE
2627 && (which_alternative == 1
2628 || which_alternative == 2
2629 || which_alternative == 3))
2634 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2635 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2636 operands[1] = GEN_INT (i);
2639 switch (which_alternative)
2644 return "sethi\t%%hi(%a1), %0";
2646 return "mov\t%1, %0";
2650 return "ld\t%1, %0";
2652 return "st\t%r1, %0";
2657 [(set_attr "type" "*,*,*,*,load,store")])
2659 (define_insn "*movsf_lo_sum"
2660 [(set (match_operand:SF 0 "register_operand" "=r")
2661 (lo_sum:SF (match_operand:SF 1 "register_operand" "r")
2662 (match_operand:SF 2 "const_double_operand" "S")))]
2663 "fp_high_losum_p (operands[2])"
2668 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[2]);
2669 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2670 operands[2] = GEN_INT (i);
2671 return "or\t%1, %%lo(%a2), %0";
2674 (define_insn "*movsf_high"
2675 [(set (match_operand:SF 0 "register_operand" "=r")
2676 (high:SF (match_operand:SF 1 "const_double_operand" "S")))]
2677 "fp_high_losum_p (operands[1])"
2682 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2683 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2684 operands[1] = GEN_INT (i);
2685 return "sethi\t%%hi(%1), %0";
2689 [(set (match_operand:SF 0 "register_operand" "")
2690 (match_operand:SF 1 "const_double_operand" ""))]
2691 "fp_high_losum_p (operands[1])
2692 && (GET_CODE (operands[0]) == REG
2693 && REGNO (operands[0]) < 32)"
2694 [(set (match_dup 0) (high:SF (match_dup 1)))
2695 (set (match_dup 0) (lo_sum:SF (match_dup 0) (match_dup 1)))])
2697 (define_expand "movsf"
2698 [(set (match_operand:SF 0 "general_operand" "")
2699 (match_operand:SF 1 "general_operand" ""))]
2702 /* Force SFmode constants into memory. */
2703 if (GET_CODE (operands[0]) == REG
2704 && CONSTANT_P (operands[1]))
2706 /* emit_group_store will send such bogosity to us when it is
2707 not storing directly into memory. So fix this up to avoid
2708 crashes in output_constant_pool. */
2709 if (operands [1] == const0_rtx)
2710 operands[1] = CONST0_RTX (SFmode);
2712 if (TARGET_VIS && fp_zero_operand (operands[1], SFmode))
2715 /* We are able to build any SF constant in integer registers
2716 with at most 2 instructions. */
2717 if (REGNO (operands[0]) < 32)
2720 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
2724 /* Handle sets of MEM first. */
2725 if (GET_CODE (operands[0]) == MEM)
2727 if (register_operand (operands[1], SFmode)
2728 || fp_zero_operand (operands[1], SFmode))
2731 if (! reload_in_progress)
2733 operands[0] = validize_mem (operands[0]);
2734 operands[1] = force_reg (SFmode, operands[1]);
2738 /* Fixup PIC cases. */
2741 if (CONSTANT_P (operands[1])
2742 && pic_address_needs_scratch (operands[1]))
2743 operands[1] = legitimize_pic_address (operands[1], SFmode, 0);
2745 if (symbolic_operand (operands[1], SFmode))
2747 operands[1] = legitimize_pic_address (operands[1],
2749 (reload_in_progress ?
2759 (define_expand "movdf"
2760 [(set (match_operand:DF 0 "general_operand" "")
2761 (match_operand:DF 1 "general_operand" ""))]
2764 /* Force DFmode constants into memory. */
2765 if (GET_CODE (operands[0]) == REG
2766 && CONSTANT_P (operands[1]))
2768 /* emit_group_store will send such bogosity to us when it is
2769 not storing directly into memory. So fix this up to avoid
2770 crashes in output_constant_pool. */
2771 if (operands [1] == const0_rtx)
2772 operands[1] = CONST0_RTX (DFmode);
2774 if ((TARGET_VIS || REGNO (operands[0]) < 32)
2775 && fp_zero_operand (operands[1], DFmode))
2778 /* We are able to build any DF constant in integer registers. */
2779 if (REGNO (operands[0]) < 32
2780 && (reload_completed || reload_in_progress))
2783 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
2787 /* Handle MEM cases first. */
2788 if (GET_CODE (operands[0]) == MEM)
2790 if (register_operand (operands[1], DFmode)
2791 || fp_zero_operand (operands[1], DFmode))
2794 if (! reload_in_progress)
2796 operands[0] = validize_mem (operands[0]);
2797 operands[1] = force_reg (DFmode, operands[1]);
2801 /* Fixup PIC cases. */
2804 if (CONSTANT_P (operands[1])
2805 && pic_address_needs_scratch (operands[1]))
2806 operands[1] = legitimize_pic_address (operands[1], DFmode, 0);
2808 if (symbolic_operand (operands[1], DFmode))
2810 operands[1] = legitimize_pic_address (operands[1],
2812 (reload_in_progress ?
2822 ;; Be careful, fmovd does not exist when !v9.
2823 (define_insn "*movdf_insn_sp32"
2824 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,W,U,T,o,e,*r,o,e,o")
2825 (match_operand:DF 1 "input_operand" "W#F,e,T,U,G,e,*rFo,*r,o#F,e"))]
2828 && (register_operand (operands[0], DFmode)
2829 || register_operand (operands[1], DFmode)
2830 || fp_zero_operand (operands[1], DFmode))"
2842 [(set_attr "type" "fpload,fpstore,load,store,*,*,*,*,*,*")
2843 (set_attr "length" "*,*,*,*,2,2,2,2,2,2")])
2845 (define_insn "*movdf_no_e_insn_sp32"
2846 [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,o,r,o")
2847 (match_operand:DF 1 "input_operand" "T,U,G,ro,r"))]
2851 && (register_operand (operands[0], DFmode)
2852 || register_operand (operands[1], DFmode)
2853 || fp_zero_operand (operands[1], DFmode))"
2860 [(set_attr "type" "load,store,*,*,*")
2861 (set_attr "length" "*,*,2,2,2")])
2863 (define_insn "*movdf_no_e_insn_v9_sp32"
2864 [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,T,r,o")
2865 (match_operand:DF 1 "input_operand" "T,U,G,ro,rG"))]
2869 && (register_operand (operands[0], DFmode)
2870 || register_operand (operands[1], DFmode)
2871 || fp_zero_operand (operands[1], DFmode))"
2878 [(set_attr "type" "load,store,store,*,*")
2879 (set_attr "length" "*,*,*,2,2")])
2881 ;; We have available v9 double floats but not 64-bit
2882 ;; integer registers and no VIS.
2883 (define_insn "*movdf_insn_v9only_novis"
2884 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,T,W,U,T,f,*r,o")
2885 (match_operand:DF 1 "input_operand" "e,W#F,G,e,T,U,o#F,*roF,*rGf"))]
2890 && (register_operand (operands[0], DFmode)
2891 || register_operand (operands[1], DFmode)
2892 || fp_zero_operand (operands[1], DFmode))"
2903 [(set_attr "type" "fpmove,load,store,store,load,store,*,*,*")
2904 (set_attr "length" "*,*,*,*,*,*,2,2,2")
2905 (set_attr "fptype" "double,*,*,*,*,*,*,*,*")])
2907 ;; We have available v9 double floats but not 64-bit
2908 ;; integer registers but we have VIS.
2909 (define_insn "*movdf_insn_v9only_vis"
2910 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,e,T,W,U,T,f,*r,o")
2911 (match_operand:DF 1 "input_operand" "G,e,W#F,G,e,T,U,o#F,*roGF,*rGf"))]
2915 && (register_operand (operands[0], DFmode)
2916 || register_operand (operands[1], DFmode)
2917 || fp_zero_operand (operands[1], DFmode))"
2929 [(set_attr "type" "fpmove,fpmove,load,store,store,load,store,*,*,*")
2930 (set_attr "length" "*,*,*,*,*,*,*,2,2,2")
2931 (set_attr "fptype" "double,double,*,*,*,*,*,*,*,*")])
2933 ;; We have available both v9 double floats and 64-bit
2934 ;; integer registers. No VIS though.
2935 (define_insn "*movdf_insn_sp64_novis"
2936 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,W,*r,*r,m,*r")
2937 (match_operand:DF 1 "input_operand" "e,W#F,e,*rG,m,*rG,F"))]
2941 && (register_operand (operands[0], DFmode)
2942 || register_operand (operands[1], DFmode)
2943 || fp_zero_operand (operands[1], DFmode))"
2952 [(set_attr "type" "fpmove,load,store,*,load,store,*")
2953 (set_attr "length" "*,*,*,*,*,*,2")
2954 (set_attr "fptype" "double,*,*,*,*,*,*")])
2956 ;; We have available both v9 double floats and 64-bit
2957 ;; integer registers. And we have VIS.
2958 (define_insn "*movdf_insn_sp64_vis"
2959 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,e,W,*r,*r,m,*r")
2960 (match_operand:DF 1 "input_operand" "G,e,W#F,e,*rG,m,*rG,F"))]
2964 && (register_operand (operands[0], DFmode)
2965 || register_operand (operands[1], DFmode)
2966 || fp_zero_operand (operands[1], DFmode))"
2976 [(set_attr "type" "fpmove,fpmove,load,store,*,load,store,*")
2977 (set_attr "length" "*,*,*,*,*,*,*,2")
2978 (set_attr "fptype" "double,double,*,*,*,*,*,*")])
2980 (define_insn "*movdf_no_e_insn_sp64"
2981 [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m")
2982 (match_operand:DF 1 "input_operand" "r,m,rG"))]
2985 && (register_operand (operands[0], DFmode)
2986 || register_operand (operands[1], DFmode)
2987 || fp_zero_operand (operands[1], DFmode))"
2992 [(set_attr "type" "*,load,store")])
2995 [(set (match_operand:DF 0 "register_operand" "")
2996 (match_operand:DF 1 "const_double_operand" ""))]
2998 && (GET_CODE (operands[0]) == REG
2999 && REGNO (operands[0]) < 32)
3000 && ! fp_zero_operand(operands[1], DFmode)
3001 && reload_completed"
3002 [(clobber (const_int 0))]
3007 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3008 REAL_VALUE_TO_TARGET_DOUBLE (r, l);
3009 operands[0] = gen_rtx_raw_REG (DImode, REGNO (operands[0]));
3013 #if HOST_BITS_PER_WIDE_INT == 64
3016 val = ((HOST_WIDE_INT)(unsigned long)l[1] |
3017 ((HOST_WIDE_INT)(unsigned long)l[0] << 32));
3018 emit_insn (gen_movdi (operands[0], GEN_INT (val)));
3020 emit_insn (gen_movdi (operands[0],
3021 immed_double_const (l[1], l[0], DImode)));
3026 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
3029 /* Slick... but this trick loses if this subreg constant part
3030 can be done in one insn. */
3032 && !(SPARC_SETHI32_P (l[0])
3033 || SPARC_SIMM13_P (l[0])))
3035 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
3036 gen_highpart (SImode, operands[0])));
3040 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
3047 ;; Ok, now the splits to handle all the multi insn and
3048 ;; mis-aligned memory address cases.
3049 ;; In these splits please take note that we must be
3050 ;; careful when V9 but not ARCH64 because the integer
3051 ;; register DFmode cases must be handled.
3053 [(set (match_operand:DF 0 "register_operand" "")
3054 (match_operand:DF 1 "register_operand" ""))]
3057 && ((GET_CODE (operands[0]) == REG
3058 && REGNO (operands[0]) < 32)
3059 || (GET_CODE (operands[0]) == SUBREG
3060 && GET_CODE (SUBREG_REG (operands[0])) == REG
3061 && REGNO (SUBREG_REG (operands[0])) < 32))))
3062 && reload_completed"
3063 [(clobber (const_int 0))]
3065 rtx set_dest = operands[0];
3066 rtx set_src = operands[1];
3070 dest1 = gen_highpart (SFmode, set_dest);
3071 dest2 = gen_lowpart (SFmode, set_dest);
3072 src1 = gen_highpart (SFmode, set_src);
3073 src2 = gen_lowpart (SFmode, set_src);
3075 /* Now emit using the real source and destination we found, swapping
3076 the order if we detect overlap. */
3077 if (reg_overlap_mentioned_p (dest1, src2))
3079 emit_insn (gen_movsf (dest2, src2));
3080 emit_insn (gen_movsf (dest1, src1));
3084 emit_insn (gen_movsf (dest1, src1));
3085 emit_insn (gen_movsf (dest2, src2));
3091 [(set (match_operand:DF 0 "register_operand" "")
3092 (match_operand:DF 1 "memory_operand" ""))]
3095 && (((REGNO (operands[0]) % 2) != 0)
3096 || ! mem_min_alignment (operands[1], 8))
3097 && offsettable_memref_p (operands[1])"
3098 [(clobber (const_int 0))]
3100 rtx word0 = adjust_address (operands[1], SFmode, 0);
3101 rtx word1 = adjust_address (operands[1], SFmode, 4);
3103 if (reg_overlap_mentioned_p (gen_highpart (SFmode, operands[0]), word1))
3105 emit_insn (gen_movsf (gen_lowpart (SFmode, operands[0]),
3107 emit_insn (gen_movsf (gen_highpart (SFmode, operands[0]),
3112 emit_insn (gen_movsf (gen_highpart (SFmode, operands[0]),
3114 emit_insn (gen_movsf (gen_lowpart (SFmode, operands[0]),
3121 [(set (match_operand:DF 0 "memory_operand" "")
3122 (match_operand:DF 1 "register_operand" ""))]
3125 && (((REGNO (operands[1]) % 2) != 0)
3126 || ! mem_min_alignment (operands[0], 8))
3127 && offsettable_memref_p (operands[0])"
3128 [(clobber (const_int 0))]
3130 rtx word0 = adjust_address (operands[0], SFmode, 0);
3131 rtx word1 = adjust_address (operands[0], SFmode, 4);
3133 emit_insn (gen_movsf (word0,
3134 gen_highpart (SFmode, operands[1])));
3135 emit_insn (gen_movsf (word1,
3136 gen_lowpart (SFmode, operands[1])));
3141 [(set (match_operand:DF 0 "memory_operand" "")
3142 (match_operand:DF 1 "fp_zero_operand" ""))]
3146 && ! mem_min_alignment (operands[0], 8)))
3147 && offsettable_memref_p (operands[0])"
3148 [(clobber (const_int 0))]
3152 dest1 = adjust_address (operands[0], SFmode, 0);
3153 dest2 = adjust_address (operands[0], SFmode, 4);
3155 emit_insn (gen_movsf (dest1, CONST0_RTX (SFmode)));
3156 emit_insn (gen_movsf (dest2, CONST0_RTX (SFmode)));
3161 [(set (match_operand:DF 0 "register_operand" "")
3162 (match_operand:DF 1 "fp_zero_operand" ""))]
3165 && ((GET_CODE (operands[0]) == REG
3166 && REGNO (operands[0]) < 32)
3167 || (GET_CODE (operands[0]) == SUBREG
3168 && GET_CODE (SUBREG_REG (operands[0])) == REG
3169 && REGNO (SUBREG_REG (operands[0])) < 32))"
3170 [(clobber (const_int 0))]
3172 rtx set_dest = operands[0];
3175 dest1 = gen_highpart (SFmode, set_dest);
3176 dest2 = gen_lowpart (SFmode, set_dest);
3177 emit_insn (gen_movsf (dest1, CONST0_RTX (SFmode)));
3178 emit_insn (gen_movsf (dest2, CONST0_RTX (SFmode)));
3182 (define_expand "movtf"
3183 [(set (match_operand:TF 0 "general_operand" "")
3184 (match_operand:TF 1 "general_operand" ""))]
3187 /* Force TFmode constants into memory. */
3188 if (GET_CODE (operands[0]) == REG
3189 && CONSTANT_P (operands[1]))
3191 /* emit_group_store will send such bogosity to us when it is
3192 not storing directly into memory. So fix this up to avoid
3193 crashes in output_constant_pool. */
3194 if (operands [1] == const0_rtx)
3195 operands[1] = CONST0_RTX (TFmode);
3197 if (TARGET_VIS && fp_zero_operand (operands[1], TFmode))
3200 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
3204 /* Handle MEM cases first, note that only v9 guarentees
3205 full 16-byte alignment for quads. */
3206 if (GET_CODE (operands[0]) == MEM)
3208 if (register_operand (operands[1], TFmode)
3209 || fp_zero_operand (operands[1], TFmode))
3212 if (! reload_in_progress)
3214 operands[0] = validize_mem (operands[0]);
3215 operands[1] = force_reg (TFmode, operands[1]);
3219 /* Fixup PIC cases. */
3222 if (CONSTANT_P (operands[1])
3223 && pic_address_needs_scratch (operands[1]))
3224 operands[1] = legitimize_pic_address (operands[1], TFmode, 0);
3226 if (symbolic_operand (operands[1], TFmode))
3228 operands[1] = legitimize_pic_address (operands[1],
3230 (reload_in_progress ?
3240 ;; Be careful, fmovq and {st,ld}{x,q} do not exist when !arch64 so
3241 ;; we must split them all. :-(
3242 (define_insn "*movtf_insn_sp32"
3243 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,U,r")
3244 (match_operand:TF 1 "input_operand" "oe,GeUr,o,roG"))]
3248 && (register_operand (operands[0], TFmode)
3249 || register_operand (operands[1], TFmode)
3250 || fp_zero_operand (operands[1], TFmode))"
3252 [(set_attr "length" "4")])
3254 (define_insn "*movtf_insn_vis_sp32"
3255 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,U,r")
3256 (match_operand:TF 1 "input_operand" "Goe,GeUr,o,roG"))]
3260 && (register_operand (operands[0], TFmode)
3261 || register_operand (operands[1], TFmode)
3262 || fp_zero_operand (operands[1], TFmode))"
3264 [(set_attr "length" "4")])
3266 ;; Exactly the same as above, except that all `e' cases are deleted.
3267 ;; This is necessary to prevent reload from ever trying to use a `e' reg
3270 (define_insn "*movtf_no_e_insn_sp32"
3271 [(set (match_operand:TF 0 "nonimmediate_operand" "=o,U,o,r,o")
3272 (match_operand:TF 1 "input_operand" "G,o,U,roG,r"))]
3275 && (register_operand (operands[0], TFmode)
3276 || register_operand (operands[1], TFmode)
3277 || fp_zero_operand (operands[1], TFmode))"
3279 [(set_attr "length" "4")])
3281 ;; Now handle the float reg cases directly when arch64,
3282 ;; hard_quad, and proper reg number alignment are all true.
3283 (define_insn "*movtf_insn_hq_sp64"
3284 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,e,m,o,r")
3285 (match_operand:TF 1 "input_operand" "e,m,e,Gr,roG"))]
3290 && (register_operand (operands[0], TFmode)
3291 || register_operand (operands[1], TFmode)
3292 || fp_zero_operand (operands[1], TFmode))"
3299 [(set_attr "type" "fpmove,fpload,fpstore,*,*")
3300 (set_attr "length" "*,*,*,2,2")])
3302 (define_insn "*movtf_insn_hq_vis_sp64"
3303 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,e,m,eo,r,o")
3304 (match_operand:TF 1 "input_operand" "e,m,e,G,roG,r"))]
3309 && (register_operand (operands[0], TFmode)
3310 || register_operand (operands[1], TFmode)
3311 || fp_zero_operand (operands[1], TFmode))"
3319 [(set_attr "type" "fpmove,fpload,fpstore,*,*,*")
3320 (set_attr "length" "*,*,*,2,2,2")])
3322 ;; Now we allow the integer register cases even when
3323 ;; only arch64 is true.
3324 (define_insn "*movtf_insn_sp64"
3325 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,r")
3326 (match_operand:TF 1 "input_operand" "oe,Ger,orG"))]
3330 && ! TARGET_HARD_QUAD
3331 && (register_operand (operands[0], TFmode)
3332 || register_operand (operands[1], TFmode)
3333 || fp_zero_operand (operands[1], TFmode))"
3335 [(set_attr "length" "2")])
3337 (define_insn "*movtf_insn_vis_sp64"
3338 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,r")
3339 (match_operand:TF 1 "input_operand" "Goe,Ger,orG"))]
3343 && ! TARGET_HARD_QUAD
3344 && (register_operand (operands[0], TFmode)
3345 || register_operand (operands[1], TFmode)
3346 || fp_zero_operand (operands[1], TFmode))"
3348 [(set_attr "length" "2")])
3350 (define_insn "*movtf_no_e_insn_sp64"
3351 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o")
3352 (match_operand:TF 1 "input_operand" "orG,rG"))]
3355 && (register_operand (operands[0], TFmode)
3356 || register_operand (operands[1], TFmode)
3357 || fp_zero_operand (operands[1], TFmode))"
3359 [(set_attr "length" "2")])
3361 ;; Now all the splits to handle multi-insn TF mode moves.
3363 [(set (match_operand:TF 0 "register_operand" "")
3364 (match_operand:TF 1 "register_operand" ""))]
3368 && ! TARGET_HARD_QUAD)
3369 || ! fp_register_operand (operands[0], TFmode))"
3370 [(clobber (const_int 0))]
3372 rtx set_dest = operands[0];
3373 rtx set_src = operands[1];
3377 dest1 = gen_df_reg (set_dest, 0);
3378 dest2 = gen_df_reg (set_dest, 1);
3379 src1 = gen_df_reg (set_src, 0);
3380 src2 = gen_df_reg (set_src, 1);
3382 /* Now emit using the real source and destination we found, swapping
3383 the order if we detect overlap. */
3384 if (reg_overlap_mentioned_p (dest1, src2))
3386 emit_insn (gen_movdf (dest2, src2));
3387 emit_insn (gen_movdf (dest1, src1));
3391 emit_insn (gen_movdf (dest1, src1));
3392 emit_insn (gen_movdf (dest2, src2));
3398 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3399 (match_operand:TF 1 "fp_zero_operand" ""))]
3401 [(clobber (const_int 0))]
3403 rtx set_dest = operands[0];
3406 switch (GET_CODE (set_dest))
3409 dest1 = gen_df_reg (set_dest, 0);
3410 dest2 = gen_df_reg (set_dest, 1);
3413 dest1 = adjust_address (set_dest, DFmode, 0);
3414 dest2 = adjust_address (set_dest, DFmode, 8);
3420 emit_insn (gen_movdf (dest1, CONST0_RTX (DFmode)));
3421 emit_insn (gen_movdf (dest2, CONST0_RTX (DFmode)));
3426 [(set (match_operand:TF 0 "register_operand" "")
3427 (match_operand:TF 1 "memory_operand" ""))]
3429 && offsettable_memref_p (operands[1])
3431 || ! TARGET_HARD_QUAD
3432 || ! fp_register_operand (operands[0], TFmode)))"
3433 [(clobber (const_int 0))]
3435 rtx word0 = adjust_address (operands[1], DFmode, 0);
3436 rtx word1 = adjust_address (operands[1], DFmode, 8);
3437 rtx set_dest, dest1, dest2;
3439 set_dest = operands[0];
3441 dest1 = gen_df_reg (set_dest, 0);
3442 dest2 = gen_df_reg (set_dest, 1);
3444 /* Now output, ordering such that we don't clobber any registers
3445 mentioned in the address. */
3446 if (reg_overlap_mentioned_p (dest1, word1))
3449 emit_insn (gen_movdf (dest2, word1));
3450 emit_insn (gen_movdf (dest1, word0));
3454 emit_insn (gen_movdf (dest1, word0));
3455 emit_insn (gen_movdf (dest2, word1));
3461 [(set (match_operand:TF 0 "memory_operand" "")
3462 (match_operand:TF 1 "register_operand" ""))]
3464 && offsettable_memref_p (operands[0])
3466 || ! TARGET_HARD_QUAD
3467 || ! fp_register_operand (operands[1], TFmode)))"
3468 [(clobber (const_int 0))]
3470 rtx set_src = operands[1];
3472 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 0),
3473 gen_df_reg (set_src, 0)));
3474 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 8),
3475 gen_df_reg (set_src, 1)));
3479 ;; SPARC V9 conditional move instructions.
3481 ;; We can handle larger constants here for some flavors, but for now we keep
3482 ;; it simple and only allow those constants supported by all flavors.
3483 ;; Note that emit_conditional_move canonicalizes operands 2,3 so that operand
3484 ;; 3 contains the constant if one is present, but we handle either for
3485 ;; generality (sparc.c puts a constant in operand 2).
3487 (define_expand "movqicc"
3488 [(set (match_operand:QI 0 "register_operand" "")
3489 (if_then_else:QI (match_operand 1 "comparison_operator" "")
3490 (match_operand:QI 2 "arith10_operand" "")
3491 (match_operand:QI 3 "arith10_operand" "")))]
3494 enum rtx_code code = GET_CODE (operands[1]);
3496 if (GET_MODE (sparc_compare_op0) == DImode
3500 if (sparc_compare_op1 == const0_rtx
3501 && GET_CODE (sparc_compare_op0) == REG
3502 && GET_MODE (sparc_compare_op0) == DImode
3503 && v9_regcmp_p (code))
3505 operands[1] = gen_rtx_fmt_ee (code, DImode,
3506 sparc_compare_op0, sparc_compare_op1);
3510 rtx cc_reg = gen_compare_reg (code,
3511 sparc_compare_op0, sparc_compare_op1);
3512 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3516 (define_expand "movhicc"
3517 [(set (match_operand:HI 0 "register_operand" "")
3518 (if_then_else:HI (match_operand 1 "comparison_operator" "")
3519 (match_operand:HI 2 "arith10_operand" "")
3520 (match_operand:HI 3 "arith10_operand" "")))]
3523 enum rtx_code code = GET_CODE (operands[1]);
3525 if (GET_MODE (sparc_compare_op0) == DImode
3529 if (sparc_compare_op1 == const0_rtx
3530 && GET_CODE (sparc_compare_op0) == REG
3531 && GET_MODE (sparc_compare_op0) == DImode
3532 && v9_regcmp_p (code))
3534 operands[1] = gen_rtx_fmt_ee (code, DImode,
3535 sparc_compare_op0, sparc_compare_op1);
3539 rtx cc_reg = gen_compare_reg (code,
3540 sparc_compare_op0, sparc_compare_op1);
3541 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3545 (define_expand "movsicc"
3546 [(set (match_operand:SI 0 "register_operand" "")
3547 (if_then_else:SI (match_operand 1 "comparison_operator" "")
3548 (match_operand:SI 2 "arith10_operand" "")
3549 (match_operand:SI 3 "arith10_operand" "")))]
3552 enum rtx_code code = GET_CODE (operands[1]);
3553 enum machine_mode op0_mode = GET_MODE (sparc_compare_op0);
3555 if (sparc_compare_op1 == const0_rtx
3556 && GET_CODE (sparc_compare_op0) == REG
3557 && (TARGET_ARCH64 && op0_mode == DImode && v9_regcmp_p (code)))
3559 operands[1] = gen_rtx_fmt_ee (code, op0_mode,
3560 sparc_compare_op0, sparc_compare_op1);
3564 rtx cc_reg = gen_compare_reg (code,
3565 sparc_compare_op0, sparc_compare_op1);
3566 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg),
3567 cc_reg, const0_rtx);
3571 (define_expand "movdicc"
3572 [(set (match_operand:DI 0 "register_operand" "")
3573 (if_then_else:DI (match_operand 1 "comparison_operator" "")
3574 (match_operand:DI 2 "arith10_double_operand" "")
3575 (match_operand:DI 3 "arith10_double_operand" "")))]
3578 enum rtx_code code = GET_CODE (operands[1]);
3580 if (sparc_compare_op1 == const0_rtx
3581 && GET_CODE (sparc_compare_op0) == REG
3582 && GET_MODE (sparc_compare_op0) == DImode
3583 && v9_regcmp_p (code))
3585 operands[1] = gen_rtx_fmt_ee (code, DImode,
3586 sparc_compare_op0, sparc_compare_op1);
3590 rtx cc_reg = gen_compare_reg (code,
3591 sparc_compare_op0, sparc_compare_op1);
3592 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg),
3593 cc_reg, const0_rtx);
3597 (define_expand "movsfcc"
3598 [(set (match_operand:SF 0 "register_operand" "")
3599 (if_then_else:SF (match_operand 1 "comparison_operator" "")
3600 (match_operand:SF 2 "register_operand" "")
3601 (match_operand:SF 3 "register_operand" "")))]
3602 "TARGET_V9 && TARGET_FPU"
3604 enum rtx_code code = GET_CODE (operands[1]);
3606 if (GET_MODE (sparc_compare_op0) == DImode
3610 if (sparc_compare_op1 == const0_rtx
3611 && GET_CODE (sparc_compare_op0) == REG
3612 && GET_MODE (sparc_compare_op0) == DImode
3613 && v9_regcmp_p (code))
3615 operands[1] = gen_rtx_fmt_ee (code, DImode,
3616 sparc_compare_op0, sparc_compare_op1);
3620 rtx cc_reg = gen_compare_reg (code,
3621 sparc_compare_op0, sparc_compare_op1);
3622 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3626 (define_expand "movdfcc"
3627 [(set (match_operand:DF 0 "register_operand" "")
3628 (if_then_else:DF (match_operand 1 "comparison_operator" "")
3629 (match_operand:DF 2 "register_operand" "")
3630 (match_operand:DF 3 "register_operand" "")))]
3631 "TARGET_V9 && TARGET_FPU"
3633 enum rtx_code code = GET_CODE (operands[1]);
3635 if (GET_MODE (sparc_compare_op0) == DImode
3639 if (sparc_compare_op1 == const0_rtx
3640 && GET_CODE (sparc_compare_op0) == REG
3641 && GET_MODE (sparc_compare_op0) == DImode
3642 && v9_regcmp_p (code))
3644 operands[1] = gen_rtx_fmt_ee (code, DImode,
3645 sparc_compare_op0, sparc_compare_op1);
3649 rtx cc_reg = gen_compare_reg (code,
3650 sparc_compare_op0, sparc_compare_op1);
3651 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3655 (define_expand "movtfcc"
3656 [(set (match_operand:TF 0 "register_operand" "")
3657 (if_then_else:TF (match_operand 1 "comparison_operator" "")
3658 (match_operand:TF 2 "register_operand" "")
3659 (match_operand:TF 3 "register_operand" "")))]
3660 "TARGET_V9 && TARGET_FPU"
3662 enum rtx_code code = GET_CODE (operands[1]);
3664 if (GET_MODE (sparc_compare_op0) == DImode
3668 if (sparc_compare_op1 == const0_rtx
3669 && GET_CODE (sparc_compare_op0) == REG
3670 && GET_MODE (sparc_compare_op0) == DImode
3671 && v9_regcmp_p (code))
3673 operands[1] = gen_rtx_fmt_ee (code, DImode,
3674 sparc_compare_op0, sparc_compare_op1);
3678 rtx cc_reg = gen_compare_reg (code,
3679 sparc_compare_op0, sparc_compare_op1);
3680 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3684 ;; Conditional move define_insns.
3686 (define_insn "*movqi_cc_sp64"
3687 [(set (match_operand:QI 0 "register_operand" "=r,r")
3688 (if_then_else:QI (match_operator 1 "comparison_operator"
3689 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3691 (match_operand:QI 3 "arith11_operand" "rL,0")
3692 (match_operand:QI 4 "arith11_operand" "0,rL")))]
3696 mov%c1\t%x2, %4, %0"
3697 [(set_attr "type" "cmove")])
3699 (define_insn "*movhi_cc_sp64"
3700 [(set (match_operand:HI 0 "register_operand" "=r,r")
3701 (if_then_else:HI (match_operator 1 "comparison_operator"
3702 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3704 (match_operand:HI 3 "arith11_operand" "rL,0")
3705 (match_operand:HI 4 "arith11_operand" "0,rL")))]
3709 mov%c1\t%x2, %4, %0"
3710 [(set_attr "type" "cmove")])
3712 (define_insn "*movsi_cc_sp64"
3713 [(set (match_operand:SI 0 "register_operand" "=r,r")
3714 (if_then_else:SI (match_operator 1 "comparison_operator"
3715 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3717 (match_operand:SI 3 "arith11_operand" "rL,0")
3718 (match_operand:SI 4 "arith11_operand" "0,rL")))]
3722 mov%c1\t%x2, %4, %0"
3723 [(set_attr "type" "cmove")])
3725 ;; ??? The constraints of operands 3,4 need work.
3726 (define_insn "*movdi_cc_sp64"
3727 [(set (match_operand:DI 0 "register_operand" "=r,r")
3728 (if_then_else:DI (match_operator 1 "comparison_operator"
3729 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3731 (match_operand:DI 3 "arith11_double_operand" "rLH,0")
3732 (match_operand:DI 4 "arith11_double_operand" "0,rLH")))]
3736 mov%c1\t%x2, %4, %0"
3737 [(set_attr "type" "cmove")])
3739 (define_insn "*movdi_cc_sp64_trunc"
3740 [(set (match_operand:SI 0 "register_operand" "=r,r")
3741 (if_then_else:SI (match_operator 1 "comparison_operator"
3742 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3744 (match_operand:SI 3 "arith11_double_operand" "rLH,0")
3745 (match_operand:SI 4 "arith11_double_operand" "0,rLH")))]
3749 mov%c1\t%x2, %4, %0"
3750 [(set_attr "type" "cmove")])
3752 (define_insn "*movsf_cc_sp64"
3753 [(set (match_operand:SF 0 "register_operand" "=f,f")
3754 (if_then_else:SF (match_operator 1 "comparison_operator"
3755 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3757 (match_operand:SF 3 "register_operand" "f,0")
3758 (match_operand:SF 4 "register_operand" "0,f")))]
3759 "TARGET_V9 && TARGET_FPU"
3761 fmovs%C1\t%x2, %3, %0
3762 fmovs%c1\t%x2, %4, %0"
3763 [(set_attr "type" "fpcmove")])
3765 (define_insn "movdf_cc_sp64"
3766 [(set (match_operand:DF 0 "register_operand" "=e,e")
3767 (if_then_else:DF (match_operator 1 "comparison_operator"
3768 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3770 (match_operand:DF 3 "register_operand" "e,0")
3771 (match_operand:DF 4 "register_operand" "0,e")))]
3772 "TARGET_V9 && TARGET_FPU"
3774 fmovd%C1\t%x2, %3, %0
3775 fmovd%c1\t%x2, %4, %0"
3776 [(set_attr "type" "fpcmove")
3777 (set_attr "fptype" "double")])
3779 (define_insn "*movtf_cc_hq_sp64"
3780 [(set (match_operand:TF 0 "register_operand" "=e,e")
3781 (if_then_else:TF (match_operator 1 "comparison_operator"
3782 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3784 (match_operand:TF 3 "register_operand" "e,0")
3785 (match_operand:TF 4 "register_operand" "0,e")))]
3786 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
3788 fmovq%C1\t%x2, %3, %0
3789 fmovq%c1\t%x2, %4, %0"
3790 [(set_attr "type" "fpcmove")])
3792 (define_insn_and_split "*movtf_cc_sp64"
3793 [(set (match_operand:TF 0 "register_operand" "=e,e")
3794 (if_then_else:TF (match_operator 1 "comparison_operator"
3795 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3797 (match_operand:TF 3 "register_operand" "e,0")
3798 (match_operand:TF 4 "register_operand" "0,e")))]
3799 "TARGET_V9 && TARGET_FPU && !TARGET_HARD_QUAD"
3801 "&& reload_completed"
3802 [(clobber (const_int 0))]
3804 rtx set_dest = operands[0];
3805 rtx set_srca = operands[3];
3806 rtx set_srcb = operands[4];
3807 int third = rtx_equal_p (set_dest, set_srca);
3809 rtx srca1, srca2, srcb1, srcb2;
3811 dest1 = gen_df_reg (set_dest, 0);
3812 dest2 = gen_df_reg (set_dest, 1);
3813 srca1 = gen_df_reg (set_srca, 0);
3814 srca2 = gen_df_reg (set_srca, 1);
3815 srcb1 = gen_df_reg (set_srcb, 0);
3816 srcb2 = gen_df_reg (set_srcb, 1);
3818 /* Now emit using the real source and destination we found, swapping
3819 the order if we detect overlap. */
3820 if ((third && reg_overlap_mentioned_p (dest1, srcb2))
3821 || (!third && reg_overlap_mentioned_p (dest1, srca2)))
3823 emit_insn (gen_movdf_cc_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
3824 emit_insn (gen_movdf_cc_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
3828 emit_insn (gen_movdf_cc_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
3829 emit_insn (gen_movdf_cc_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
3833 [(set_attr "length" "2")])
3835 (define_insn "*movqi_cc_reg_sp64"
3836 [(set (match_operand:QI 0 "register_operand" "=r,r")
3837 (if_then_else:QI (match_operator 1 "v9_regcmp_op"
3838 [(match_operand:DI 2 "register_operand" "r,r")
3840 (match_operand:QI 3 "arith10_operand" "rM,0")
3841 (match_operand:QI 4 "arith10_operand" "0,rM")))]
3844 movr%D1\t%2, %r3, %0
3845 movr%d1\t%2, %r4, %0"
3846 [(set_attr "type" "cmove")])
3848 (define_insn "*movhi_cc_reg_sp64"
3849 [(set (match_operand:HI 0 "register_operand" "=r,r")
3850 (if_then_else:HI (match_operator 1 "v9_regcmp_op"
3851 [(match_operand:DI 2 "register_operand" "r,r")
3853 (match_operand:HI 3 "arith10_operand" "rM,0")
3854 (match_operand:HI 4 "arith10_operand" "0,rM")))]
3857 movr%D1\t%2, %r3, %0
3858 movr%d1\t%2, %r4, %0"
3859 [(set_attr "type" "cmove")])
3861 (define_insn "*movsi_cc_reg_sp64"
3862 [(set (match_operand:SI 0 "register_operand" "=r,r")
3863 (if_then_else:SI (match_operator 1 "v9_regcmp_op"
3864 [(match_operand:DI 2 "register_operand" "r,r")
3866 (match_operand:SI 3 "arith10_operand" "rM,0")
3867 (match_operand:SI 4 "arith10_operand" "0,rM")))]
3870 movr%D1\t%2, %r3, %0
3871 movr%d1\t%2, %r4, %0"
3872 [(set_attr "type" "cmove")])
3874 ;; ??? The constraints of operands 3,4 need work.
3875 (define_insn "*movdi_cc_reg_sp64"
3876 [(set (match_operand:DI 0 "register_operand" "=r,r")
3877 (if_then_else:DI (match_operator 1 "v9_regcmp_op"
3878 [(match_operand:DI 2 "register_operand" "r,r")
3880 (match_operand:DI 3 "arith10_double_operand" "rMH,0")
3881 (match_operand:DI 4 "arith10_double_operand" "0,rMH")))]
3884 movr%D1\t%2, %r3, %0
3885 movr%d1\t%2, %r4, %0"
3886 [(set_attr "type" "cmove")])
3888 (define_insn "*movdi_cc_reg_sp64_trunc"
3889 [(set (match_operand:SI 0 "register_operand" "=r,r")
3890 (if_then_else:SI (match_operator 1 "v9_regcmp_op"
3891 [(match_operand:DI 2 "register_operand" "r,r")
3893 (match_operand:SI 3 "arith10_double_operand" "rMH,0")
3894 (match_operand:SI 4 "arith10_double_operand" "0,rMH")))]
3897 movr%D1\t%2, %r3, %0
3898 movr%d1\t%2, %r4, %0"
3899 [(set_attr "type" "cmove")])
3901 (define_insn "*movsf_cc_reg_sp64"
3902 [(set (match_operand:SF 0 "register_operand" "=f,f")
3903 (if_then_else:SF (match_operator 1 "v9_regcmp_op"
3904 [(match_operand:DI 2 "register_operand" "r,r")
3906 (match_operand:SF 3 "register_operand" "f,0")
3907 (match_operand:SF 4 "register_operand" "0,f")))]
3908 "TARGET_ARCH64 && TARGET_FPU"
3910 fmovrs%D1\t%2, %3, %0
3911 fmovrs%d1\t%2, %4, %0"
3912 [(set_attr "type" "fpcrmove")])
3914 (define_insn "movdf_cc_reg_sp64"
3915 [(set (match_operand:DF 0 "register_operand" "=e,e")
3916 (if_then_else:DF (match_operator 1 "v9_regcmp_op"
3917 [(match_operand:DI 2 "register_operand" "r,r")
3919 (match_operand:DF 3 "register_operand" "e,0")
3920 (match_operand:DF 4 "register_operand" "0,e")))]
3921 "TARGET_ARCH64 && TARGET_FPU"
3923 fmovrd%D1\t%2, %3, %0
3924 fmovrd%d1\t%2, %4, %0"
3925 [(set_attr "type" "fpcrmove")
3926 (set_attr "fptype" "double")])
3928 (define_insn "*movtf_cc_reg_hq_sp64"
3929 [(set (match_operand:TF 0 "register_operand" "=e,e")
3930 (if_then_else:TF (match_operator 1 "v9_regcmp_op"
3931 [(match_operand:DI 2 "register_operand" "r,r")
3933 (match_operand:TF 3 "register_operand" "e,0")
3934 (match_operand:TF 4 "register_operand" "0,e")))]
3935 "TARGET_ARCH64 && TARGET_FPU && TARGET_HARD_QUAD"
3937 fmovrq%D1\t%2, %3, %0
3938 fmovrq%d1\t%2, %4, %0"
3939 [(set_attr "type" "fpcrmove")])
3941 (define_insn_and_split "*movtf_cc_reg_sp64"
3942 [(set (match_operand:TF 0 "register_operand" "=e,e")
3943 (if_then_else:TF (match_operator 1 "v9_regcmp_op"
3944 [(match_operand:DI 2 "register_operand" "r,r")
3946 (match_operand:TF 3 "register_operand" "e,0")
3947 (match_operand:TF 4 "register_operand" "0,e")))]
3948 "TARGET_ARCH64 && TARGET_FPU && ! TARGET_HARD_QUAD"
3950 "&& reload_completed"
3951 [(clobber (const_int 0))]
3953 rtx set_dest = operands[0];
3954 rtx set_srca = operands[3];
3955 rtx set_srcb = operands[4];
3956 int third = rtx_equal_p (set_dest, set_srca);
3958 rtx srca1, srca2, srcb1, srcb2;
3960 dest1 = gen_df_reg (set_dest, 0);
3961 dest2 = gen_df_reg (set_dest, 1);
3962 srca1 = gen_df_reg (set_srca, 0);
3963 srca2 = gen_df_reg (set_srca, 1);
3964 srcb1 = gen_df_reg (set_srcb, 0);
3965 srcb2 = gen_df_reg (set_srcb, 1);
3967 /* Now emit using the real source and destination we found, swapping
3968 the order if we detect overlap. */
3969 if ((third && reg_overlap_mentioned_p (dest1, srcb2))
3970 || (!third && reg_overlap_mentioned_p (dest1, srca2)))
3972 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
3973 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
3977 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
3978 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
3982 [(set_attr "length" "2")])
3985 ;;- zero extension instructions
3987 ;; These patterns originally accepted general_operands, however, slightly
3988 ;; better code is generated by only accepting register_operands, and then
3989 ;; letting combine generate the ldu[hb] insns.
3991 (define_expand "zero_extendhisi2"
3992 [(set (match_operand:SI 0 "register_operand" "")
3993 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
3996 rtx temp = gen_reg_rtx (SImode);
3997 rtx shift_16 = GEN_INT (16);
3998 int op1_subbyte = 0;
4000 if (GET_CODE (operand1) == SUBREG)
4002 op1_subbyte = SUBREG_BYTE (operand1);
4003 op1_subbyte /= GET_MODE_SIZE (SImode);
4004 op1_subbyte *= GET_MODE_SIZE (SImode);
4005 operand1 = XEXP (operand1, 0);
4008 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4010 emit_insn (gen_lshrsi3 (operand0, temp, shift_16));
4014 (define_insn "*zero_extendhisi2_insn"
4015 [(set (match_operand:SI 0 "register_operand" "=r")
4016 (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
4019 [(set_attr "type" "load")
4020 (set_attr "us3load_type" "3cycle")])
4022 (define_expand "zero_extendqihi2"
4023 [(set (match_operand:HI 0 "register_operand" "")
4024 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
4028 (define_insn "*zero_extendqihi2_insn"
4029 [(set (match_operand:HI 0 "register_operand" "=r,r")
4030 (zero_extend:HI (match_operand:QI 1 "input_operand" "r,m")))]
4031 "GET_CODE (operands[1]) != CONST_INT"
4035 [(set_attr "type" "*,load")
4036 (set_attr "us3load_type" "*,3cycle")])
4038 (define_expand "zero_extendqisi2"
4039 [(set (match_operand:SI 0 "register_operand" "")
4040 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
4044 (define_insn "*zero_extendqisi2_insn"
4045 [(set (match_operand:SI 0 "register_operand" "=r,r")
4046 (zero_extend:SI (match_operand:QI 1 "input_operand" "r,m")))]
4047 "GET_CODE (operands[1]) != CONST_INT"
4051 [(set_attr "type" "*,load")
4052 (set_attr "us3load_type" "*,3cycle")])
4054 (define_expand "zero_extendqidi2"
4055 [(set (match_operand:DI 0 "register_operand" "")
4056 (zero_extend:DI (match_operand:QI 1 "register_operand" "")))]
4060 (define_insn "*zero_extendqidi2_insn"
4061 [(set (match_operand:DI 0 "register_operand" "=r,r")
4062 (zero_extend:DI (match_operand:QI 1 "input_operand" "r,m")))]
4063 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
4067 [(set_attr "type" "*,load")
4068 (set_attr "us3load_type" "*,3cycle")])
4070 (define_expand "zero_extendhidi2"
4071 [(set (match_operand:DI 0 "register_operand" "")
4072 (zero_extend:DI (match_operand:HI 1 "register_operand" "")))]
4075 rtx temp = gen_reg_rtx (DImode);
4076 rtx shift_48 = GEN_INT (48);
4077 int op1_subbyte = 0;
4079 if (GET_CODE (operand1) == SUBREG)
4081 op1_subbyte = SUBREG_BYTE (operand1);
4082 op1_subbyte /= GET_MODE_SIZE (DImode);
4083 op1_subbyte *= GET_MODE_SIZE (DImode);
4084 operand1 = XEXP (operand1, 0);
4087 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
4089 emit_insn (gen_lshrdi3 (operand0, temp, shift_48));
4093 (define_insn "*zero_extendhidi2_insn"
4094 [(set (match_operand:DI 0 "register_operand" "=r")
4095 (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
4098 [(set_attr "type" "load")
4099 (set_attr "us3load_type" "3cycle")])
4102 ;; ??? Write truncdisi pattern using sra?
4104 (define_expand "zero_extendsidi2"
4105 [(set (match_operand:DI 0 "register_operand" "")
4106 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
4110 (define_insn "*zero_extendsidi2_insn_sp64"
4111 [(set (match_operand:DI 0 "register_operand" "=r,r")
4112 (zero_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
4113 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
4117 [(set_attr "type" "shift,load")])
4119 (define_insn_and_split "*zero_extendsidi2_insn_sp32"
4120 [(set (match_operand:DI 0 "register_operand" "=r")
4121 (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
4124 "&& reload_completed"
4125 [(set (match_dup 2) (match_dup 3))
4126 (set (match_dup 4) (match_dup 5))]
4130 dest1 = gen_highpart (SImode, operands[0]);
4131 dest2 = gen_lowpart (SImode, operands[0]);
4133 /* Swap the order in case of overlap. */
4134 if (REGNO (dest1) == REGNO (operands[1]))
4136 operands[2] = dest2;
4137 operands[3] = operands[1];
4138 operands[4] = dest1;
4139 operands[5] = const0_rtx;
4143 operands[2] = dest1;
4144 operands[3] = const0_rtx;
4145 operands[4] = dest2;
4146 operands[5] = operands[1];
4149 [(set_attr "length" "2")])
4151 ;; Simplify comparisons of extended values.
4153 (define_insn "*cmp_zero_extendqisi2"
4155 (compare:CC (zero_extend:SI (match_operand:QI 0 "register_operand" "r"))
4158 "andcc\t%0, 0xff, %%g0"
4159 [(set_attr "type" "compare")])
4161 (define_insn "*cmp_zero_qi"
4163 (compare:CC (match_operand:QI 0 "register_operand" "r")
4166 "andcc\t%0, 0xff, %%g0"
4167 [(set_attr "type" "compare")])
4169 (define_insn "*cmp_zero_extendqisi2_set"
4171 (compare:CC (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
4173 (set (match_operand:SI 0 "register_operand" "=r")
4174 (zero_extend:SI (match_dup 1)))]
4176 "andcc\t%1, 0xff, %0"
4177 [(set_attr "type" "compare")])
4179 (define_insn "*cmp_zero_extendqisi2_andcc_set"
4181 (compare:CC (and:SI (match_operand:SI 1 "register_operand" "r")
4184 (set (match_operand:SI 0 "register_operand" "=r")
4185 (zero_extend:SI (subreg:QI (match_dup 1) 0)))]
4187 "andcc\t%1, 0xff, %0"
4188 [(set_attr "type" "compare")])
4190 (define_insn "*cmp_zero_extendqidi2"
4192 (compare:CCX (zero_extend:DI (match_operand:QI 0 "register_operand" "r"))
4195 "andcc\t%0, 0xff, %%g0"
4196 [(set_attr "type" "compare")])
4198 (define_insn "*cmp_zero_qi_sp64"
4200 (compare:CCX (match_operand:QI 0 "register_operand" "r")
4203 "andcc\t%0, 0xff, %%g0"
4204 [(set_attr "type" "compare")])
4206 (define_insn "*cmp_zero_extendqidi2_set"
4208 (compare:CCX (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
4210 (set (match_operand:DI 0 "register_operand" "=r")
4211 (zero_extend:DI (match_dup 1)))]
4213 "andcc\t%1, 0xff, %0"
4214 [(set_attr "type" "compare")])
4216 (define_insn "*cmp_zero_extendqidi2_andcc_set"
4218 (compare:CCX (and:DI (match_operand:DI 1 "register_operand" "r")
4221 (set (match_operand:DI 0 "register_operand" "=r")
4222 (zero_extend:DI (subreg:QI (match_dup 1) 0)))]
4224 "andcc\t%1, 0xff, %0"
4225 [(set_attr "type" "compare")])
4227 ;; Similarly, handle {SI,DI}->QI mode truncation followed by a compare.
4229 (define_insn "*cmp_siqi_trunc"
4231 (compare:CC (subreg:QI (match_operand:SI 0 "register_operand" "r") 3)
4234 "andcc\t%0, 0xff, %%g0"
4235 [(set_attr "type" "compare")])
4237 (define_insn "*cmp_siqi_trunc_set"
4239 (compare:CC (subreg:QI (match_operand:SI 1 "register_operand" "r") 3)
4241 (set (match_operand:QI 0 "register_operand" "=r")
4242 (subreg:QI (match_dup 1) 3))]
4244 "andcc\t%1, 0xff, %0"
4245 [(set_attr "type" "compare")])
4247 (define_insn "*cmp_diqi_trunc"
4249 (compare:CC (subreg:QI (match_operand:DI 0 "register_operand" "r") 7)
4252 "andcc\t%0, 0xff, %%g0"
4253 [(set_attr "type" "compare")])
4255 (define_insn "*cmp_diqi_trunc_set"
4257 (compare:CC (subreg:QI (match_operand:DI 1 "register_operand" "r") 7)
4259 (set (match_operand:QI 0 "register_operand" "=r")
4260 (subreg:QI (match_dup 1) 7))]
4262 "andcc\t%1, 0xff, %0"
4263 [(set_attr "type" "compare")])
4265 ;;- sign extension instructions
4267 ;; These patterns originally accepted general_operands, however, slightly
4268 ;; better code is generated by only accepting register_operands, and then
4269 ;; letting combine generate the lds[hb] insns.
4271 (define_expand "extendhisi2"
4272 [(set (match_operand:SI 0 "register_operand" "")
4273 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
4276 rtx temp = gen_reg_rtx (SImode);
4277 rtx shift_16 = GEN_INT (16);
4278 int op1_subbyte = 0;
4280 if (GET_CODE (operand1) == SUBREG)
4282 op1_subbyte = SUBREG_BYTE (operand1);
4283 op1_subbyte /= GET_MODE_SIZE (SImode);
4284 op1_subbyte *= GET_MODE_SIZE (SImode);
4285 operand1 = XEXP (operand1, 0);
4288 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4290 emit_insn (gen_ashrsi3 (operand0, temp, shift_16));
4294 (define_insn "*sign_extendhisi2_insn"
4295 [(set (match_operand:SI 0 "register_operand" "=r")
4296 (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
4299 [(set_attr "type" "sload")
4300 (set_attr "us3load_type" "3cycle")])
4302 (define_expand "extendqihi2"
4303 [(set (match_operand:HI 0 "register_operand" "")
4304 (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
4307 rtx temp = gen_reg_rtx (SImode);
4308 rtx shift_24 = GEN_INT (24);
4309 int op1_subbyte = 0;
4310 int op0_subbyte = 0;
4312 if (GET_CODE (operand1) == SUBREG)
4314 op1_subbyte = SUBREG_BYTE (operand1);
4315 op1_subbyte /= GET_MODE_SIZE (SImode);
4316 op1_subbyte *= GET_MODE_SIZE (SImode);
4317 operand1 = XEXP (operand1, 0);
4319 if (GET_CODE (operand0) == SUBREG)
4321 op0_subbyte = SUBREG_BYTE (operand0);
4322 op0_subbyte /= GET_MODE_SIZE (SImode);
4323 op0_subbyte *= GET_MODE_SIZE (SImode);
4324 operand0 = XEXP (operand0, 0);
4326 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4328 if (GET_MODE (operand0) != SImode)
4329 operand0 = gen_rtx_SUBREG (SImode, operand0, op0_subbyte);
4330 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
4334 (define_insn "*sign_extendqihi2_insn"
4335 [(set (match_operand:HI 0 "register_operand" "=r")
4336 (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
4339 [(set_attr "type" "sload")
4340 (set_attr "us3load_type" "3cycle")])
4342 (define_expand "extendqisi2"
4343 [(set (match_operand:SI 0 "register_operand" "")
4344 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
4347 rtx temp = gen_reg_rtx (SImode);
4348 rtx shift_24 = GEN_INT (24);
4349 int op1_subbyte = 0;
4351 if (GET_CODE (operand1) == SUBREG)
4353 op1_subbyte = SUBREG_BYTE (operand1);
4354 op1_subbyte /= GET_MODE_SIZE (SImode);
4355 op1_subbyte *= GET_MODE_SIZE (SImode);
4356 operand1 = XEXP (operand1, 0);
4359 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4361 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
4365 (define_insn "*sign_extendqisi2_insn"
4366 [(set (match_operand:SI 0 "register_operand" "=r")
4367 (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
4370 [(set_attr "type" "sload")
4371 (set_attr "us3load_type" "3cycle")])
4373 (define_expand "extendqidi2"
4374 [(set (match_operand:DI 0 "register_operand" "")
4375 (sign_extend:DI (match_operand:QI 1 "register_operand" "")))]
4378 rtx temp = gen_reg_rtx (DImode);
4379 rtx shift_56 = GEN_INT (56);
4380 int op1_subbyte = 0;
4382 if (GET_CODE (operand1) == SUBREG)
4384 op1_subbyte = SUBREG_BYTE (operand1);
4385 op1_subbyte /= GET_MODE_SIZE (DImode);
4386 op1_subbyte *= GET_MODE_SIZE (DImode);
4387 operand1 = XEXP (operand1, 0);
4390 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
4392 emit_insn (gen_ashrdi3 (operand0, temp, shift_56));
4396 (define_insn "*sign_extendqidi2_insn"
4397 [(set (match_operand:DI 0 "register_operand" "=r")
4398 (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
4401 [(set_attr "type" "sload")
4402 (set_attr "us3load_type" "3cycle")])
4404 (define_expand "extendhidi2"
4405 [(set (match_operand:DI 0 "register_operand" "")
4406 (sign_extend:DI (match_operand:HI 1 "register_operand" "")))]
4409 rtx temp = gen_reg_rtx (DImode);
4410 rtx shift_48 = GEN_INT (48);
4411 int op1_subbyte = 0;
4413 if (GET_CODE (operand1) == SUBREG)
4415 op1_subbyte = SUBREG_BYTE (operand1);
4416 op1_subbyte /= GET_MODE_SIZE (DImode);
4417 op1_subbyte *= GET_MODE_SIZE (DImode);
4418 operand1 = XEXP (operand1, 0);
4421 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
4423 emit_insn (gen_ashrdi3 (operand0, temp, shift_48));
4427 (define_insn "*sign_extendhidi2_insn"
4428 [(set (match_operand:DI 0 "register_operand" "=r")
4429 (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
4432 [(set_attr "type" "sload")
4433 (set_attr "us3load_type" "3cycle")])
4435 (define_expand "extendsidi2"
4436 [(set (match_operand:DI 0 "register_operand" "")
4437 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
4441 (define_insn "*sign_extendsidi2_insn"
4442 [(set (match_operand:DI 0 "register_operand" "=r,r")
4443 (sign_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
4448 [(set_attr "type" "shift,sload")
4449 (set_attr "us3load_type" "*,3cycle")])
4451 ;; Special pattern for optimizing bit-field compares. This is needed
4452 ;; because combine uses this as a canonical form.
4454 (define_insn "*cmp_zero_extract"
4457 (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
4458 (match_operand:SI 1 "small_int_or_double" "n")
4459 (match_operand:SI 2 "small_int_or_double" "n"))
4461 "(GET_CODE (operands[2]) == CONST_INT
4462 && INTVAL (operands[2]) > 19)
4463 || (GET_CODE (operands[2]) == CONST_DOUBLE
4464 && CONST_DOUBLE_LOW (operands[2]) > 19)"
4466 int len = (GET_CODE (operands[1]) == CONST_INT
4467 ? INTVAL (operands[1])
4468 : CONST_DOUBLE_LOW (operands[1]));
4470 (GET_CODE (operands[2]) == CONST_INT
4471 ? INTVAL (operands[2])
4472 : CONST_DOUBLE_LOW (operands[2])) - len;
4473 HOST_WIDE_INT mask = ((1 << len) - 1) << pos;
4475 operands[1] = GEN_INT (mask);
4476 return "andcc\t%0, %1, %%g0";
4478 [(set_attr "type" "compare")])
4480 (define_insn "*cmp_zero_extract_sp64"
4483 (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
4484 (match_operand:SI 1 "small_int_or_double" "n")
4485 (match_operand:SI 2 "small_int_or_double" "n"))
4488 && ((GET_CODE (operands[2]) == CONST_INT
4489 && INTVAL (operands[2]) > 51)
4490 || (GET_CODE (operands[2]) == CONST_DOUBLE
4491 && CONST_DOUBLE_LOW (operands[2]) > 51))"
4493 int len = (GET_CODE (operands[1]) == CONST_INT
4494 ? INTVAL (operands[1])
4495 : CONST_DOUBLE_LOW (operands[1]));
4497 (GET_CODE (operands[2]) == CONST_INT
4498 ? INTVAL (operands[2])
4499 : CONST_DOUBLE_LOW (operands[2])) - len;
4500 HOST_WIDE_INT mask = (((unsigned HOST_WIDE_INT) 1 << len) - 1) << pos;
4502 operands[1] = GEN_INT (mask);
4503 return "andcc\t%0, %1, %%g0";
4505 [(set_attr "type" "compare")])
4507 ;; Conversions between float, double and long double.
4509 (define_insn "extendsfdf2"
4510 [(set (match_operand:DF 0 "register_operand" "=e")
4512 (match_operand:SF 1 "register_operand" "f")))]
4515 [(set_attr "type" "fp")
4516 (set_attr "fptype" "double")])
4518 (define_expand "extendsftf2"
4519 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4521 (match_operand:SF 1 "register_operand" "")))]
4522 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4523 "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
4525 (define_insn "*extendsftf2_hq"
4526 [(set (match_operand:TF 0 "register_operand" "=e")
4528 (match_operand:SF 1 "register_operand" "f")))]
4529 "TARGET_FPU && TARGET_HARD_QUAD"
4531 [(set_attr "type" "fp")])
4533 (define_expand "extenddftf2"
4534 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4536 (match_operand:DF 1 "register_operand" "")))]
4537 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4538 "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
4540 (define_insn "*extenddftf2_hq"
4541 [(set (match_operand:TF 0 "register_operand" "=e")
4543 (match_operand:DF 1 "register_operand" "e")))]
4544 "TARGET_FPU && TARGET_HARD_QUAD"
4546 [(set_attr "type" "fp")])
4548 (define_insn "truncdfsf2"
4549 [(set (match_operand:SF 0 "register_operand" "=f")
4551 (match_operand:DF 1 "register_operand" "e")))]
4554 [(set_attr "type" "fp")
4555 (set_attr "fptype" "double")])
4557 (define_expand "trunctfsf2"
4558 [(set (match_operand:SF 0 "register_operand" "")
4560 (match_operand:TF 1 "general_operand" "")))]
4561 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4562 "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
4564 (define_insn "*trunctfsf2_hq"
4565 [(set (match_operand:SF 0 "register_operand" "=f")
4567 (match_operand:TF 1 "register_operand" "e")))]
4568 "TARGET_FPU && TARGET_HARD_QUAD"
4570 [(set_attr "type" "fp")])
4572 (define_expand "trunctfdf2"
4573 [(set (match_operand:DF 0 "register_operand" "")
4575 (match_operand:TF 1 "general_operand" "")))]
4576 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4577 "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
4579 (define_insn "*trunctfdf2_hq"
4580 [(set (match_operand:DF 0 "register_operand" "=e")
4582 (match_operand:TF 1 "register_operand" "e")))]
4583 "TARGET_FPU && TARGET_HARD_QUAD"
4585 [(set_attr "type" "fp")])
4587 ;; Conversion between fixed point and floating point.
4589 (define_insn "floatsisf2"
4590 [(set (match_operand:SF 0 "register_operand" "=f")
4591 (float:SF (match_operand:SI 1 "register_operand" "f")))]
4594 [(set_attr "type" "fp")
4595 (set_attr "fptype" "double")])
4597 (define_insn "floatsidf2"
4598 [(set (match_operand:DF 0 "register_operand" "=e")
4599 (float:DF (match_operand:SI 1 "register_operand" "f")))]
4602 [(set_attr "type" "fp")
4603 (set_attr "fptype" "double")])
4605 (define_expand "floatsitf2"
4606 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4607 (float:TF (match_operand:SI 1 "register_operand" "")))]
4608 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4609 "emit_tfmode_cvt (FLOAT, operands); DONE;")
4611 (define_insn "*floatsitf2_hq"
4612 [(set (match_operand:TF 0 "register_operand" "=e")
4613 (float:TF (match_operand:SI 1 "register_operand" "f")))]
4614 "TARGET_FPU && TARGET_HARD_QUAD"
4616 [(set_attr "type" "fp")])
4618 (define_expand "floatunssitf2"
4619 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4620 (unsigned_float:TF (match_operand:SI 1 "register_operand" "")))]
4621 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4622 "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
4624 ;; Now the same for 64 bit sources.
4626 (define_insn "floatdisf2"
4627 [(set (match_operand:SF 0 "register_operand" "=f")
4628 (float:SF (match_operand:DI 1 "register_operand" "e")))]
4629 "TARGET_V9 && TARGET_FPU"
4631 [(set_attr "type" "fp")
4632 (set_attr "fptype" "double")])
4634 (define_expand "floatunsdisf2"
4635 [(use (match_operand:SF 0 "register_operand" ""))
4636 (use (match_operand:DI 1 "register_operand" ""))]
4637 "TARGET_ARCH64 && TARGET_FPU"
4638 "sparc_emit_floatunsdi (operands); DONE;")
4640 (define_insn "floatdidf2"
4641 [(set (match_operand:DF 0 "register_operand" "=e")
4642 (float:DF (match_operand:DI 1 "register_operand" "e")))]
4643 "TARGET_V9 && TARGET_FPU"
4645 [(set_attr "type" "fp")
4646 (set_attr "fptype" "double")])
4648 (define_expand "floatunsdidf2"
4649 [(use (match_operand:DF 0 "register_operand" ""))
4650 (use (match_operand:DI 1 "register_operand" ""))]
4651 "TARGET_ARCH64 && TARGET_FPU"
4652 "sparc_emit_floatunsdi (operands); DONE;")
4654 (define_expand "floatditf2"
4655 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4656 (float:TF (match_operand:DI 1 "register_operand" "")))]
4657 "TARGET_FPU && TARGET_V9 && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4658 "emit_tfmode_cvt (FLOAT, operands); DONE;")
4660 (define_insn "*floatditf2_hq"
4661 [(set (match_operand:TF 0 "register_operand" "=e")
4662 (float:TF (match_operand:DI 1 "register_operand" "e")))]
4663 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
4665 [(set_attr "type" "fp")])
4667 (define_expand "floatunsditf2"
4668 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4669 (unsigned_float:TF (match_operand:DI 1 "register_operand" "")))]
4670 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4671 "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
4673 ;; Convert a float to an actual integer.
4674 ;; Truncation is performed as part of the conversion.
4676 (define_insn "fix_truncsfsi2"
4677 [(set (match_operand:SI 0 "register_operand" "=f")
4678 (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
4681 [(set_attr "type" "fp")
4682 (set_attr "fptype" "double")])
4684 (define_insn "fix_truncdfsi2"
4685 [(set (match_operand:SI 0 "register_operand" "=f")
4686 (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
4689 [(set_attr "type" "fp")
4690 (set_attr "fptype" "double")])
4692 (define_expand "fix_trunctfsi2"
4693 [(set (match_operand:SI 0 "register_operand" "")
4694 (fix:SI (match_operand:TF 1 "general_operand" "")))]
4695 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4696 "emit_tfmode_cvt (FIX, operands); DONE;")
4698 (define_insn "*fix_trunctfsi2_hq"
4699 [(set (match_operand:SI 0 "register_operand" "=f")
4700 (fix:SI (match_operand:TF 1 "register_operand" "e")))]
4701 "TARGET_FPU && TARGET_HARD_QUAD"
4703 [(set_attr "type" "fp")])
4705 (define_expand "fixuns_trunctfsi2"
4706 [(set (match_operand:SI 0 "register_operand" "")
4707 (unsigned_fix:SI (match_operand:TF 1 "general_operand" "")))]
4708 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4709 "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
4711 ;; Now the same, for V9 targets
4713 (define_insn "fix_truncsfdi2"
4714 [(set (match_operand:DI 0 "register_operand" "=e")
4715 (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
4716 "TARGET_V9 && TARGET_FPU"
4718 [(set_attr "type" "fp")
4719 (set_attr "fptype" "double")])
4721 (define_insn "fix_truncdfdi2"
4722 [(set (match_operand:DI 0 "register_operand" "=e")
4723 (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
4724 "TARGET_V9 && TARGET_FPU"
4726 [(set_attr "type" "fp")
4727 (set_attr "fptype" "double")])
4729 (define_expand "fix_trunctfdi2"
4730 [(set (match_operand:DI 0 "register_operand" "")
4731 (fix:DI (match_operand:TF 1 "general_operand" "")))]
4732 "TARGET_V9 && TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4733 "emit_tfmode_cvt (FIX, operands); DONE;")
4735 (define_insn "*fix_trunctfdi2_hq"
4736 [(set (match_operand:DI 0 "register_operand" "=e")
4737 (fix:DI (match_operand:TF 1 "register_operand" "e")))]
4738 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
4740 [(set_attr "type" "fp")])
4742 (define_expand "fixuns_trunctfdi2"
4743 [(set (match_operand:DI 0 "register_operand" "")
4744 (unsigned_fix:DI (match_operand:TF 1 "general_operand" "")))]
4745 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4746 "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
4748 ;;- arithmetic instructions
4750 (define_expand "adddi3"
4751 [(set (match_operand:DI 0 "register_operand" "=r")
4752 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
4753 (match_operand:DI 2 "arith_double_add_operand" "rHI")))]
4758 if (! TARGET_ARCH64)
4760 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
4761 gen_rtx_SET (VOIDmode, operands[0],
4762 gen_rtx_PLUS (DImode, operands[1],
4764 gen_rtx_CLOBBER (VOIDmode,
4765 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
4768 if (arith_double_4096_operand(operands[2], DImode))
4770 switch (GET_CODE (operands[1]))
4772 case CONST_INT: i = INTVAL (operands[1]); break;
4773 case CONST_DOUBLE: i = CONST_DOUBLE_LOW (operands[1]); break;
4775 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
4776 gen_rtx_MINUS (DImode, operands[1],
4780 emit_insn (gen_movdi (operands[0], GEN_INT (i + 4096)));
4785 (define_insn_and_split "adddi3_insn_sp32"
4786 [(set (match_operand:DI 0 "register_operand" "=r")
4787 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
4788 (match_operand:DI 2 "arith_double_operand" "rHI")))
4789 (clobber (reg:CC 100))]
4792 "&& reload_completed"
4793 [(parallel [(set (reg:CC_NOOV 100)
4794 (compare:CC_NOOV (plus:SI (match_dup 4)
4798 (plus:SI (match_dup 4) (match_dup 5)))])
4800 (plus:SI (plus:SI (match_dup 7)
4802 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4804 operands[3] = gen_lowpart (SImode, operands[0]);
4805 operands[4] = gen_lowpart (SImode, operands[1]);
4806 operands[5] = gen_lowpart (SImode, operands[2]);
4807 operands[6] = gen_highpart (SImode, operands[0]);
4808 operands[7] = gen_highpart_mode (SImode, DImode, operands[1]);
4809 #if HOST_BITS_PER_WIDE_INT == 32
4810 if (GET_CODE (operands[2]) == CONST_INT)
4812 if (INTVAL (operands[2]) < 0)
4813 operands[8] = constm1_rtx;
4815 operands[8] = const0_rtx;
4819 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
4821 [(set_attr "length" "2")])
4824 [(set (match_operand:DI 0 "register_operand" "")
4825 (minus:DI (match_operand:DI 1 "arith_double_operand" "")
4826 (match_operand:DI 2 "arith_double_operand" "")))
4827 (clobber (reg:CC 100))]
4828 "! TARGET_ARCH64 && reload_completed"
4829 [(parallel [(set (reg:CC_NOOV 100)
4830 (compare:CC_NOOV (minus:SI (match_dup 4)
4834 (minus:SI (match_dup 4) (match_dup 5)))])
4836 (minus:SI (minus:SI (match_dup 7)
4838 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4840 operands[3] = gen_lowpart (SImode, operands[0]);
4841 operands[4] = gen_lowpart (SImode, operands[1]);
4842 operands[5] = gen_lowpart (SImode, operands[2]);
4843 operands[6] = gen_highpart (SImode, operands[0]);
4844 operands[7] = gen_highpart (SImode, operands[1]);
4845 #if HOST_BITS_PER_WIDE_INT == 32
4846 if (GET_CODE (operands[2]) == CONST_INT)
4848 if (INTVAL (operands[2]) < 0)
4849 operands[8] = constm1_rtx;
4851 operands[8] = const0_rtx;
4855 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
4858 ;; LTU here means "carry set"
4860 [(set (match_operand:SI 0 "register_operand" "=r")
4861 (plus:SI (plus:SI (match_operand:SI 1 "arith_operand" "%r")
4862 (match_operand:SI 2 "arith_operand" "rI"))
4863 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4866 [(set_attr "type" "ialuX")])
4868 (define_insn_and_split "*addx_extend_sp32"
4869 [(set (match_operand:DI 0 "register_operand" "=r")
4870 (zero_extend:DI (plus:SI (plus:SI
4871 (match_operand:SI 1 "reg_or_0_operand" "%rJ")
4872 (match_operand:SI 2 "arith_operand" "rI"))
4873 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4876 "&& reload_completed"
4877 [(set (match_dup 3) (plus:SI (plus:SI (match_dup 1) (match_dup 2))
4878 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
4879 (set (match_dup 4) (const_int 0))]
4880 "operands[3] = gen_lowpart (SImode, operands[0]);
4881 operands[4] = gen_highpart_mode (SImode, DImode, operands[1]);"
4882 [(set_attr "length" "2")])
4884 (define_insn "*addx_extend_sp64"
4885 [(set (match_operand:DI 0 "register_operand" "=r")
4886 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
4887 (match_operand:SI 2 "arith_operand" "rI"))
4888 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4891 [(set_attr "type" "ialuX")])
4894 [(set (match_operand:SI 0 "register_operand" "=r")
4895 (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
4896 (match_operand:SI 2 "arith_operand" "rI"))
4897 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4900 [(set_attr "type" "ialuX")])
4902 (define_insn "*subx_extend_sp64"
4903 [(set (match_operand:DI 0 "register_operand" "=r")
4904 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
4905 (match_operand:SI 2 "arith_operand" "rI"))
4906 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4909 [(set_attr "type" "ialuX")])
4911 (define_insn_and_split "*subx_extend"
4912 [(set (match_operand:DI 0 "register_operand" "=r")
4913 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
4914 (match_operand:SI 2 "arith_operand" "rI"))
4915 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4918 "&& reload_completed"
4919 [(set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 2))
4920 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
4921 (set (match_dup 4) (const_int 0))]
4922 "operands[3] = gen_lowpart (SImode, operands[0]);
4923 operands[4] = gen_highpart (SImode, operands[0]);"
4924 [(set_attr "length" "2")])
4926 (define_insn_and_split ""
4927 [(set (match_operand:DI 0 "register_operand" "=r")
4928 (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4929 (match_operand:DI 2 "register_operand" "r")))
4930 (clobber (reg:CC 100))]
4933 "&& reload_completed"
4934 [(parallel [(set (reg:CC_NOOV 100)
4935 (compare:CC_NOOV (plus:SI (match_dup 3) (match_dup 1))
4937 (set (match_dup 5) (plus:SI (match_dup 3) (match_dup 1)))])
4939 (plus:SI (plus:SI (match_dup 4) (const_int 0))
4940 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4941 "operands[3] = gen_lowpart (SImode, operands[2]);
4942 operands[4] = gen_highpart (SImode, operands[2]);
4943 operands[5] = gen_lowpart (SImode, operands[0]);
4944 operands[6] = gen_highpart (SImode, operands[0]);"
4945 [(set_attr "length" "2")])
4947 (define_insn "*adddi3_sp64"
4948 [(set (match_operand:DI 0 "register_operand" "=r")
4949 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
4950 (match_operand:DI 2 "arith_double_operand" "rHI")))]
4954 (define_expand "addsi3"
4955 [(set (match_operand:SI 0 "register_operand" "=r,d")
4956 (plus:SI (match_operand:SI 1 "arith_operand" "%r,d")
4957 (match_operand:SI 2 "arith_add_operand" "rI,d")))]
4960 if (arith_4096_operand(operands[2], SImode))
4962 if (GET_CODE (operands[1]) == CONST_INT)
4963 emit_insn (gen_movsi (operands[0],
4964 GEN_INT (INTVAL (operands[1]) + 4096)));
4966 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
4967 gen_rtx_MINUS (SImode, operands[1],
4973 (define_insn "*addsi3"
4974 [(set (match_operand:SI 0 "register_operand" "=r,d")
4975 (plus:SI (match_operand:SI 1 "arith_operand" "%r,d")
4976 (match_operand:SI 2 "arith_operand" "rI,d")))]
4980 fpadd32s\t%1, %2, %0"
4981 [(set_attr "type" "*,fp")])
4983 (define_insn "*cmp_cc_plus"
4984 [(set (reg:CC_NOOV 100)
4985 (compare:CC_NOOV (plus:SI (match_operand:SI 0 "arith_operand" "%r")
4986 (match_operand:SI 1 "arith_operand" "rI"))
4989 "addcc\t%0, %1, %%g0"
4990 [(set_attr "type" "compare")])
4992 (define_insn "*cmp_ccx_plus"
4993 [(set (reg:CCX_NOOV 100)
4994 (compare:CCX_NOOV (plus:DI (match_operand:DI 0 "arith_double_operand" "%r")
4995 (match_operand:DI 1 "arith_double_operand" "rHI"))
4998 "addcc\t%0, %1, %%g0"
4999 [(set_attr "type" "compare")])
5001 (define_insn "*cmp_cc_plus_set"
5002 [(set (reg:CC_NOOV 100)
5003 (compare:CC_NOOV (plus:SI (match_operand:SI 1 "arith_operand" "%r")
5004 (match_operand:SI 2 "arith_operand" "rI"))
5006 (set (match_operand:SI 0 "register_operand" "=r")
5007 (plus:SI (match_dup 1) (match_dup 2)))]
5010 [(set_attr "type" "compare")])
5012 (define_insn "*cmp_ccx_plus_set"
5013 [(set (reg:CCX_NOOV 100)
5014 (compare:CCX_NOOV (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
5015 (match_operand:DI 2 "arith_double_operand" "rHI"))
5017 (set (match_operand:DI 0 "register_operand" "=r")
5018 (plus:DI (match_dup 1) (match_dup 2)))]
5021 [(set_attr "type" "compare")])
5023 (define_expand "subdi3"
5024 [(set (match_operand:DI 0 "register_operand" "=r")
5025 (minus:DI (match_operand:DI 1 "register_operand" "r")
5026 (match_operand:DI 2 "arith_double_add_operand" "rHI")))]
5029 if (! TARGET_ARCH64)
5031 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
5032 gen_rtx_SET (VOIDmode, operands[0],
5033 gen_rtx_MINUS (DImode, operands[1],
5035 gen_rtx_CLOBBER (VOIDmode,
5036 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
5039 if (arith_double_4096_operand(operands[2], DImode))
5041 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
5042 gen_rtx_PLUS (DImode, operands[1],
5048 (define_insn_and_split "*subdi3_sp32"
5049 [(set (match_operand:DI 0 "register_operand" "=r")
5050 (minus:DI (match_operand:DI 1 "register_operand" "r")
5051 (match_operand:DI 2 "arith_double_operand" "rHI")))
5052 (clobber (reg:CC 100))]
5055 "&& reload_completed
5056 && (GET_CODE (operands[2]) == CONST_INT
5057 || GET_CODE (operands[2]) == CONST_DOUBLE)"
5058 [(clobber (const_int 0))]
5062 highp = gen_highpart_mode (SImode, DImode, operands[2]);
5063 lowp = gen_lowpart (SImode, operands[2]);
5064 if ((lowp == const0_rtx)
5065 && (operands[0] == operands[1]))
5067 emit_insn (gen_rtx_SET (VOIDmode,
5068 gen_highpart (SImode, operands[0]),
5069 gen_rtx_MINUS (SImode,
5070 gen_highpart_mode (SImode, DImode,
5076 emit_insn (gen_cmp_minus_cc_set (gen_lowpart (SImode, operands[0]),
5077 gen_lowpart (SImode, operands[1]),
5079 emit_insn (gen_subx (gen_highpart (SImode, operands[0]),
5080 gen_highpart_mode (SImode, DImode, operands[1]),
5085 [(set_attr "length" "2")])
5088 [(set (match_operand:DI 0 "register_operand" "")
5089 (minus:DI (match_operand:DI 1 "register_operand" "")
5090 (match_operand:DI 2 "register_operand" "")))
5091 (clobber (reg:CC 100))]
5093 && reload_completed"
5094 [(clobber (const_int 0))]
5096 emit_insn (gen_cmp_minus_cc_set (gen_lowpart (SImode, operands[0]),
5097 gen_lowpart (SImode, operands[1]),
5098 gen_lowpart (SImode, operands[2])));
5099 emit_insn (gen_subx (gen_highpart (SImode, operands[0]),
5100 gen_highpart (SImode, operands[1]),
5101 gen_highpart (SImode, operands[2])));
5105 (define_insn_and_split ""
5106 [(set (match_operand:DI 0 "register_operand" "=r")
5107 (minus:DI (match_operand:DI 1 "register_operand" "r")
5108 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))
5109 (clobber (reg:CC 100))]
5112 "&& reload_completed"
5113 [(parallel [(set (reg:CC_NOOV 100)
5114 (compare:CC_NOOV (minus:SI (match_dup 3) (match_dup 2))
5116 (set (match_dup 5) (minus:SI (match_dup 3) (match_dup 2)))])
5118 (minus:SI (minus:SI (match_dup 4) (const_int 0))
5119 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5120 "operands[3] = gen_lowpart (SImode, operands[1]);
5121 operands[4] = gen_highpart (SImode, operands[1]);
5122 operands[5] = gen_lowpart (SImode, operands[0]);
5123 operands[6] = gen_highpart (SImode, operands[0]);"
5124 [(set_attr "length" "2")])
5126 (define_insn "*subdi3_sp64"
5127 [(set (match_operand:DI 0 "register_operand" "=r")
5128 (minus:DI (match_operand:DI 1 "register_operand" "r")
5129 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5133 (define_expand "subsi3"
5134 [(set (match_operand:SI 0 "register_operand" "=r,d")
5135 (minus:SI (match_operand:SI 1 "register_operand" "r,d")
5136 (match_operand:SI 2 "arith_add_operand" "rI,d")))]
5139 if (arith_4096_operand(operands[2], SImode))
5141 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
5142 gen_rtx_PLUS (SImode, operands[1],
5148 (define_insn "*subsi3"
5149 [(set (match_operand:SI 0 "register_operand" "=r,d")
5150 (minus:SI (match_operand:SI 1 "register_operand" "r,d")
5151 (match_operand:SI 2 "arith_operand" "rI,d")))]
5155 fpsub32s\t%1, %2, %0"
5156 [(set_attr "type" "*,fp")])
5158 (define_insn "*cmp_minus_cc"
5159 [(set (reg:CC_NOOV 100)
5160 (compare:CC_NOOV (minus:SI (match_operand:SI 0 "reg_or_0_operand" "rJ")
5161 (match_operand:SI 1 "arith_operand" "rI"))
5164 "subcc\t%r0, %1, %%g0"
5165 [(set_attr "type" "compare")])
5167 (define_insn "*cmp_minus_ccx"
5168 [(set (reg:CCX_NOOV 100)
5169 (compare:CCX_NOOV (minus:DI (match_operand:DI 0 "register_operand" "r")
5170 (match_operand:DI 1 "arith_double_operand" "rHI"))
5173 "subcc\t%0, %1, %%g0"
5174 [(set_attr "type" "compare")])
5176 (define_insn "cmp_minus_cc_set"
5177 [(set (reg:CC_NOOV 100)
5178 (compare:CC_NOOV (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5179 (match_operand:SI 2 "arith_operand" "rI"))
5181 (set (match_operand:SI 0 "register_operand" "=r")
5182 (minus:SI (match_dup 1) (match_dup 2)))]
5184 "subcc\t%r1, %2, %0"
5185 [(set_attr "type" "compare")])
5187 (define_insn "*cmp_minus_ccx_set"
5188 [(set (reg:CCX_NOOV 100)
5189 (compare:CCX_NOOV (minus:DI (match_operand:DI 1 "register_operand" "r")
5190 (match_operand:DI 2 "arith_double_operand" "rHI"))
5192 (set (match_operand:DI 0 "register_operand" "=r")
5193 (minus:DI (match_dup 1) (match_dup 2)))]
5196 [(set_attr "type" "compare")])
5198 ;; Integer Multiply/Divide.
5200 ;; The 32 bit multiply/divide instructions are deprecated on v9, but at
5201 ;; least in UltraSPARC I, II and IIi it is a win tick-wise.
5203 (define_insn "mulsi3"
5204 [(set (match_operand:SI 0 "register_operand" "=r")
5205 (mult:SI (match_operand:SI 1 "arith_operand" "%r")
5206 (match_operand:SI 2 "arith_operand" "rI")))]
5209 [(set_attr "type" "imul")])
5211 (define_expand "muldi3"
5212 [(set (match_operand:DI 0 "register_operand" "=r")
5213 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r")
5214 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5215 "TARGET_ARCH64 || TARGET_V8PLUS"
5219 emit_insn (gen_muldi3_v8plus (operands[0], operands[1], operands[2]));
5224 (define_insn "*muldi3_sp64"
5225 [(set (match_operand:DI 0 "register_operand" "=r")
5226 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r")
5227 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5230 [(set_attr "type" "imul")])
5232 ;; V8plus wide multiply.
5234 (define_insn "muldi3_v8plus"
5235 [(set (match_operand:DI 0 "register_operand" "=r,h")
5236 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r,0")
5237 (match_operand:DI 2 "arith_double_operand" "rI,rI")))
5238 (clobber (match_scratch:SI 3 "=&h,X"))
5239 (clobber (match_scratch:SI 4 "=&h,X"))]
5242 if (sparc_check_64 (operands[1], insn) <= 0)
5243 output_asm_insn ("srl\t%L1, 0, %L1", operands);
5244 if (which_alternative == 1)
5245 output_asm_insn ("sllx\t%H1, 32, %H1", operands);
5246 if (GET_CODE (operands[2]) == CONST_INT)
5248 if (which_alternative == 1)
5249 return "or\t%L1, %H1, %H1\n\tmulx\t%H1, %2, %L0\;srlx\t%L0, 32, %H0";
5251 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";
5253 else if (rtx_equal_p (operands[1], operands[2]))
5255 if (which_alternative == 1)
5256 return "or\t%L1, %H1, %H1\n\tmulx\t%H1, %H1, %L0\;srlx\t%L0, 32, %H0";
5258 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";
5260 if (sparc_check_64 (operands[2], insn) <= 0)
5261 output_asm_insn ("srl\t%L2, 0, %L2", operands);
5262 if (which_alternative == 1)
5263 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";
5265 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";
5267 [(set_attr "type" "multi")
5268 (set_attr "length" "9,8")])
5270 (define_insn "*cmp_mul_set"
5272 (compare:CC (mult:SI (match_operand:SI 1 "arith_operand" "%r")
5273 (match_operand:SI 2 "arith_operand" "rI"))
5275 (set (match_operand:SI 0 "register_operand" "=r")
5276 (mult:SI (match_dup 1) (match_dup 2)))]
5277 "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS"
5278 "smulcc\t%1, %2, %0"
5279 [(set_attr "type" "imul")])
5281 (define_expand "mulsidi3"
5282 [(set (match_operand:DI 0 "register_operand" "")
5283 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
5284 (sign_extend:DI (match_operand:SI 2 "arith_operand" ""))))]
5287 if (CONSTANT_P (operands[2]))
5290 emit_insn (gen_const_mulsidi3_v8plus (operands[0], operands[1],
5292 else if (TARGET_ARCH32)
5293 emit_insn (gen_const_mulsidi3_sp32 (operands[0], operands[1],
5296 emit_insn (gen_const_mulsidi3_sp64 (operands[0], operands[1],
5302 emit_insn (gen_mulsidi3_v8plus (operands[0], operands[1], operands[2]));
5307 ;; V9 puts the 64 bit product in a 64 bit register. Only out or global
5308 ;; registers can hold 64 bit values in the V8plus environment.
5310 (define_insn "mulsidi3_v8plus"
5311 [(set (match_operand:DI 0 "register_operand" "=h,r")
5312 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5313 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
5314 (clobber (match_scratch:SI 3 "=X,&h"))]
5317 smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
5318 smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
5319 [(set_attr "type" "multi")
5320 (set_attr "length" "2,3")])
5323 (define_insn "const_mulsidi3_v8plus"
5324 [(set (match_operand:DI 0 "register_operand" "=h,r")
5325 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5326 (match_operand:DI 2 "small_int" "I,I")))
5327 (clobber (match_scratch:SI 3 "=X,&h"))]
5330 smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
5331 smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
5332 [(set_attr "type" "multi")
5333 (set_attr "length" "2,3")])
5336 (define_insn "*mulsidi3_sp32"
5337 [(set (match_operand:DI 0 "register_operand" "=r")
5338 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5339 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
5342 return TARGET_SPARCLET
5343 ? "smuld\t%1, %2, %L0"
5344 : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
5347 (if_then_else (eq_attr "isa" "sparclet")
5348 (const_string "imul") (const_string "multi")))
5349 (set (attr "length")
5350 (if_then_else (eq_attr "isa" "sparclet")
5351 (const_int 1) (const_int 2)))])
5353 (define_insn "*mulsidi3_sp64"
5354 [(set (match_operand:DI 0 "register_operand" "=r")
5355 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5356 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
5357 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5359 [(set_attr "type" "imul")])
5361 ;; Extra pattern, because sign_extend of a constant isn't valid.
5364 (define_insn "const_mulsidi3_sp32"
5365 [(set (match_operand:DI 0 "register_operand" "=r")
5366 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5367 (match_operand:DI 2 "small_int" "I")))]
5370 return TARGET_SPARCLET
5371 ? "smuld\t%1, %2, %L0"
5372 : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
5375 (if_then_else (eq_attr "isa" "sparclet")
5376 (const_string "imul") (const_string "multi")))
5377 (set (attr "length")
5378 (if_then_else (eq_attr "isa" "sparclet")
5379 (const_int 1) (const_int 2)))])
5381 (define_insn "const_mulsidi3_sp64"
5382 [(set (match_operand:DI 0 "register_operand" "=r")
5383 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5384 (match_operand:DI 2 "small_int" "I")))]
5385 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5387 [(set_attr "type" "imul")])
5389 (define_expand "smulsi3_highpart"
5390 [(set (match_operand:SI 0 "register_operand" "")
5392 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
5393 (sign_extend:DI (match_operand:SI 2 "arith_operand" "")))
5395 "TARGET_HARD_MUL && TARGET_ARCH32"
5397 if (CONSTANT_P (operands[2]))
5401 emit_insn (gen_const_smulsi3_highpart_v8plus (operands[0],
5407 emit_insn (gen_const_smulsi3_highpart (operands[0], operands[1], operands[2]));
5412 emit_insn (gen_smulsi3_highpart_v8plus (operands[0], operands[1],
5413 operands[2], GEN_INT (32)));
5419 (define_insn "smulsi3_highpart_v8plus"
5420 [(set (match_operand:SI 0 "register_operand" "=h,r")
5422 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5423 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
5424 (match_operand:SI 3 "const_int_operand" "i,i"))))
5425 (clobber (match_scratch:SI 4 "=X,&h"))]
5428 smul\t%1, %2, %0\;srlx\t%0, %3, %0
5429 smul\t%1, %2, %4\;srlx\t%4, %3, %0"
5430 [(set_attr "type" "multi")
5431 (set_attr "length" "2")])
5433 ;; The combiner changes TRUNCATE in the previous pattern to SUBREG.
5436 [(set (match_operand:SI 0 "register_operand" "=h,r")
5439 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5440 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
5441 (match_operand:SI 3 "const_int_operand" "i,i"))
5443 (clobber (match_scratch:SI 4 "=X,&h"))]
5446 smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
5447 smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
5448 [(set_attr "type" "multi")
5449 (set_attr "length" "2")])
5452 (define_insn "const_smulsi3_highpart_v8plus"
5453 [(set (match_operand:SI 0 "register_operand" "=h,r")
5455 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5456 (match_operand:DI 2 "small_int" "i,i"))
5457 (match_operand:SI 3 "const_int_operand" "i,i"))))
5458 (clobber (match_scratch:SI 4 "=X,&h"))]
5461 smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
5462 smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
5463 [(set_attr "type" "multi")
5464 (set_attr "length" "2")])
5467 (define_insn "*smulsi3_highpart_sp32"
5468 [(set (match_operand:SI 0 "register_operand" "=r")
5470 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5471 (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
5474 "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
5475 [(set_attr "type" "multi")
5476 (set_attr "length" "2")])
5479 (define_insn "const_smulsi3_highpart"
5480 [(set (match_operand:SI 0 "register_operand" "=r")
5482 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5483 (match_operand:DI 2 "small_int" "i"))
5486 "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
5487 [(set_attr "type" "multi")
5488 (set_attr "length" "2")])
5490 (define_expand "umulsidi3"
5491 [(set (match_operand:DI 0 "register_operand" "")
5492 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
5493 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" ""))))]
5496 if (CONSTANT_P (operands[2]))
5499 emit_insn (gen_const_umulsidi3_v8plus (operands[0], operands[1],
5501 else if (TARGET_ARCH32)
5502 emit_insn (gen_const_umulsidi3_sp32 (operands[0], operands[1],
5505 emit_insn (gen_const_umulsidi3_sp64 (operands[0], operands[1],
5511 emit_insn (gen_umulsidi3_v8plus (operands[0], operands[1], operands[2]));
5517 (define_insn "umulsidi3_v8plus"
5518 [(set (match_operand:DI 0 "register_operand" "=h,r")
5519 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5520 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
5521 (clobber (match_scratch:SI 3 "=X,&h"))]
5524 umul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
5525 umul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
5526 [(set_attr "type" "multi")
5527 (set_attr "length" "2,3")])
5530 (define_insn "*umulsidi3_sp32"
5531 [(set (match_operand:DI 0 "register_operand" "=r")
5532 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5533 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
5536 return TARGET_SPARCLET
5537 ? "umuld\t%1, %2, %L0"
5538 : "umul\t%1, %2, %L0\n\trd\t%%y, %H0";
5541 (if_then_else (eq_attr "isa" "sparclet")
5542 (const_string "imul") (const_string "multi")))
5543 (set (attr "length")
5544 (if_then_else (eq_attr "isa" "sparclet")
5545 (const_int 1) (const_int 2)))])
5547 (define_insn "*umulsidi3_sp64"
5548 [(set (match_operand:DI 0 "register_operand" "=r")
5549 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5550 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
5551 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5553 [(set_attr "type" "imul")])
5555 ;; Extra pattern, because sign_extend of a constant isn't valid.
5558 (define_insn "const_umulsidi3_sp32"
5559 [(set (match_operand:DI 0 "register_operand" "=r")
5560 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5561 (match_operand:DI 2 "uns_small_int" "")))]
5564 return TARGET_SPARCLET
5565 ? "umuld\t%1, %s2, %L0"
5566 : "umul\t%1, %s2, %L0\n\trd\t%%y, %H0";
5569 (if_then_else (eq_attr "isa" "sparclet")
5570 (const_string "imul") (const_string "multi")))
5571 (set (attr "length")
5572 (if_then_else (eq_attr "isa" "sparclet")
5573 (const_int 1) (const_int 2)))])
5575 (define_insn "const_umulsidi3_sp64"
5576 [(set (match_operand:DI 0 "register_operand" "=r")
5577 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5578 (match_operand:DI 2 "uns_small_int" "")))]
5579 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5581 [(set_attr "type" "imul")])
5584 (define_insn "const_umulsidi3_v8plus"
5585 [(set (match_operand:DI 0 "register_operand" "=h,r")
5586 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5587 (match_operand:DI 2 "uns_small_int" "")))
5588 (clobber (match_scratch:SI 3 "=X,h"))]
5591 umul\t%1, %s2, %L0\n\tsrlx\t%L0, 32, %H0
5592 umul\t%1, %s2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
5593 [(set_attr "type" "multi")
5594 (set_attr "length" "2,3")])
5596 (define_expand "umulsi3_highpart"
5597 [(set (match_operand:SI 0 "register_operand" "")
5599 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
5600 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" "")))
5602 "TARGET_HARD_MUL && TARGET_ARCH32"
5604 if (CONSTANT_P (operands[2]))
5608 emit_insn (gen_const_umulsi3_highpart_v8plus (operands[0],
5614 emit_insn (gen_const_umulsi3_highpart (operands[0], operands[1], operands[2]));
5619 emit_insn (gen_umulsi3_highpart_v8plus (operands[0], operands[1],
5620 operands[2], GEN_INT (32)));
5626 (define_insn "umulsi3_highpart_v8plus"
5627 [(set (match_operand:SI 0 "register_operand" "=h,r")
5629 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5630 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
5631 (match_operand:SI 3 "const_int_operand" "i,i"))))
5632 (clobber (match_scratch:SI 4 "=X,h"))]
5635 umul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
5636 umul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
5637 [(set_attr "type" "multi")
5638 (set_attr "length" "2")])
5641 (define_insn "const_umulsi3_highpart_v8plus"
5642 [(set (match_operand:SI 0 "register_operand" "=h,r")
5644 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5645 (match_operand:DI 2 "uns_small_int" ""))
5646 (match_operand:SI 3 "const_int_operand" "i,i"))))
5647 (clobber (match_scratch:SI 4 "=X,h"))]
5650 umul\t%1, %s2, %0\n\tsrlx\t%0, %3, %0
5651 umul\t%1, %s2, %4\n\tsrlx\t%4, %3, %0"
5652 [(set_attr "type" "multi")
5653 (set_attr "length" "2")])
5656 (define_insn "*umulsi3_highpart_sp32"
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 (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
5663 "umul\t%1, %2, %%g0\n\trd\t%%y, %0"
5664 [(set_attr "type" "multi")
5665 (set_attr "length" "2")])
5668 (define_insn "const_umulsi3_highpart"
5669 [(set (match_operand:SI 0 "register_operand" "=r")
5671 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5672 (match_operand:DI 2 "uns_small_int" ""))
5675 "umul\t%1, %s2, %%g0\n\trd\t%%y, %0"
5676 [(set_attr "type" "multi")
5677 (set_attr "length" "2")])
5679 ;; The v8 architecture specifies that there must be 3 instructions between
5680 ;; a y register write and a use of it for correct results.
5682 (define_expand "divsi3"
5683 [(parallel [(set (match_operand:SI 0 "register_operand" "=r,r")
5684 (div:SI (match_operand:SI 1 "register_operand" "r,r")
5685 (match_operand:SI 2 "input_operand" "rI,m")))
5686 (clobber (match_scratch:SI 3 "=&r,&r"))])]
5687 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
5691 operands[3] = gen_reg_rtx(SImode);
5692 emit_insn (gen_ashrsi3 (operands[3], operands[1], GEN_INT (31)));
5693 emit_insn (gen_divsi3_sp64 (operands[0], operands[1], operands[2],
5699 (define_insn "divsi3_sp32"
5700 [(set (match_operand:SI 0 "register_operand" "=r,r")
5701 (div:SI (match_operand:SI 1 "register_operand" "r,r")
5702 (match_operand:SI 2 "input_operand" "rI,m")))
5703 (clobber (match_scratch:SI 3 "=&r,&r"))]
5704 "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS)
5707 if (which_alternative == 0)
5709 return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tsdiv\t%1, %2, %0";
5711 return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tnop\n\tnop\n\tnop\n\tsdiv\t%1, %2, %0";
5714 return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tld\t%2, %3\n\tsdiv\t%1, %3, %0";
5716 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";
5718 [(set_attr "type" "multi")
5719 (set (attr "length")
5720 (if_then_else (eq_attr "isa" "v9")
5721 (const_int 4) (const_int 6)))])
5723 (define_insn "divsi3_sp64"
5724 [(set (match_operand:SI 0 "register_operand" "=r")
5725 (div:SI (match_operand:SI 1 "register_operand" "r")
5726 (match_operand:SI 2 "input_operand" "rI")))
5727 (use (match_operand:SI 3 "register_operand" "r"))]
5728 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5729 "wr\t%%g0, %3, %%y\n\tsdiv\t%1, %2, %0"
5730 [(set_attr "type" "multi")
5731 (set_attr "length" "2")])
5733 (define_insn "divdi3"
5734 [(set (match_operand:DI 0 "register_operand" "=r")
5735 (div:DI (match_operand:DI 1 "register_operand" "r")
5736 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5739 [(set_attr "type" "idiv")])
5741 (define_insn "*cmp_sdiv_cc_set"
5743 (compare:CC (div:SI (match_operand:SI 1 "register_operand" "r")
5744 (match_operand:SI 2 "arith_operand" "rI"))
5746 (set (match_operand:SI 0 "register_operand" "=r")
5747 (div:SI (match_dup 1) (match_dup 2)))
5748 (clobber (match_scratch:SI 3 "=&r"))]
5749 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
5752 return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tsdivcc\t%1, %2, %0";
5754 return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tnop\n\tnop\n\tnop\n\tsdivcc\t%1, %2, %0";
5756 [(set_attr "type" "multi")
5757 (set (attr "length")
5758 (if_then_else (eq_attr "isa" "v9")
5759 (const_int 3) (const_int 6)))])
5762 (define_expand "udivsi3"
5763 [(set (match_operand:SI 0 "register_operand" "")
5764 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "")
5765 (match_operand:SI 2 "input_operand" "")))]
5766 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
5769 (define_insn "udivsi3_sp32"
5770 [(set (match_operand:SI 0 "register_operand" "=r,&r,&r")
5771 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "r,r,m")
5772 (match_operand:SI 2 "input_operand" "rI,m,r")))]
5774 || TARGET_DEPRECATED_V8_INSNS)
5777 output_asm_insn ("wr\t%%g0, %%g0, %%y", operands);
5778 switch (which_alternative)
5781 return "nop\n\tnop\n\tnop\n\tudiv\t%1, %2, %0";
5783 return "ld\t%2, %0\n\tnop\n\tnop\n\tudiv\t%1, %0, %0";
5785 return "ld\t%1, %0\n\tnop\n\tnop\n\tudiv\t%0, %2, %0";
5788 [(set_attr "type" "multi")
5789 (set_attr "length" "5")])
5791 (define_insn "udivsi3_sp64"
5792 [(set (match_operand:SI 0 "register_operand" "=r")
5793 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "r")
5794 (match_operand:SI 2 "input_operand" "rI")))]
5795 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5796 "wr\t%%g0, 0, %%y\n\tudiv\t%1, %2, %0"
5797 [(set_attr "type" "multi")
5798 (set_attr "length" "2")])
5800 (define_insn "udivdi3"
5801 [(set (match_operand:DI 0 "register_operand" "=r")
5802 (udiv:DI (match_operand:DI 1 "register_operand" "r")
5803 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5806 [(set_attr "type" "idiv")])
5808 (define_insn "*cmp_udiv_cc_set"
5810 (compare:CC (udiv:SI (match_operand:SI 1 "register_operand" "r")
5811 (match_operand:SI 2 "arith_operand" "rI"))
5813 (set (match_operand:SI 0 "register_operand" "=r")
5814 (udiv:SI (match_dup 1) (match_dup 2)))]
5816 || TARGET_DEPRECATED_V8_INSNS"
5819 return "wr\t%%g0, %%g0, %%y\n\tudivcc\t%1, %2, %0";
5821 return "wr\t%%g0, %%g0, %%y\n\tnop\n\tnop\n\tnop\n\tudivcc\t%1, %2, %0";
5823 [(set_attr "type" "multi")
5824 (set (attr "length")
5825 (if_then_else (eq_attr "isa" "v9")
5826 (const_int 2) (const_int 5)))])
5828 ; sparclet multiply/accumulate insns
5830 (define_insn "*smacsi"
5831 [(set (match_operand:SI 0 "register_operand" "=r")
5832 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "%r")
5833 (match_operand:SI 2 "arith_operand" "rI"))
5834 (match_operand:SI 3 "register_operand" "0")))]
5837 [(set_attr "type" "imul")])
5839 (define_insn "*smacdi"
5840 [(set (match_operand:DI 0 "register_operand" "=r")
5841 (plus:DI (mult:DI (sign_extend:DI
5842 (match_operand:SI 1 "register_operand" "%r"))
5844 (match_operand:SI 2 "register_operand" "r")))
5845 (match_operand:DI 3 "register_operand" "0")))]
5847 "smacd\t%1, %2, %L0"
5848 [(set_attr "type" "imul")])
5850 (define_insn "*umacdi"
5851 [(set (match_operand:DI 0 "register_operand" "=r")
5852 (plus:DI (mult:DI (zero_extend:DI
5853 (match_operand:SI 1 "register_operand" "%r"))
5855 (match_operand:SI 2 "register_operand" "r")))
5856 (match_operand:DI 3 "register_operand" "0")))]
5858 "umacd\t%1, %2, %L0"
5859 [(set_attr "type" "imul")])
5861 ;;- Boolean instructions
5862 ;; We define DImode `and' so with DImode `not' we can get
5863 ;; DImode `andn'. Other combinations are possible.
5865 (define_expand "anddi3"
5866 [(set (match_operand:DI 0 "register_operand" "")
5867 (and:DI (match_operand:DI 1 "arith_double_operand" "")
5868 (match_operand:DI 2 "arith_double_operand" "")))]
5872 (define_insn "*anddi3_sp32"
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 "length" "2,*")
5882 (set_attr "fptype" "double")])
5884 (define_insn "*anddi3_sp64"
5885 [(set (match_operand:DI 0 "register_operand" "=r,b")
5886 (and:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
5887 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
5892 [(set_attr "type" "*,fp")
5893 (set_attr "fptype" "double")])
5895 (define_insn "andsi3"
5896 [(set (match_operand:SI 0 "register_operand" "=r,d")
5897 (and:SI (match_operand:SI 1 "arith_operand" "%r,d")
5898 (match_operand:SI 2 "arith_operand" "rI,d")))]
5903 [(set_attr "type" "*,fp")])
5906 [(set (match_operand:SI 0 "register_operand" "")
5907 (and:SI (match_operand:SI 1 "register_operand" "")
5908 (match_operand:SI 2 "" "")))
5909 (clobber (match_operand:SI 3 "register_operand" ""))]
5910 "GET_CODE (operands[2]) == CONST_INT
5911 && !SMALL_INT32 (operands[2])
5912 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
5913 [(set (match_dup 3) (match_dup 4))
5914 (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 1)))]
5916 operands[4] = GEN_INT (~INTVAL (operands[2]));
5919 ;; Split DImode logical operations requiring two instructions.
5921 [(set (match_operand:DI 0 "register_operand" "")
5922 (match_operator:DI 1 "cc_arithop" ; AND, IOR, XOR
5923 [(match_operand:DI 2 "register_operand" "")
5924 (match_operand:DI 3 "arith_double_operand" "")]))]
5927 && ((GET_CODE (operands[0]) == REG
5928 && REGNO (operands[0]) < 32)
5929 || (GET_CODE (operands[0]) == SUBREG
5930 && GET_CODE (SUBREG_REG (operands[0])) == REG
5931 && REGNO (SUBREG_REG (operands[0])) < 32))"
5932 [(set (match_dup 4) (match_op_dup:SI 1 [(match_dup 6) (match_dup 8)]))
5933 (set (match_dup 5) (match_op_dup:SI 1 [(match_dup 7) (match_dup 9)]))]
5935 operands[4] = gen_highpart (SImode, operands[0]);
5936 operands[5] = gen_lowpart (SImode, operands[0]);
5937 operands[6] = gen_highpart (SImode, operands[2]);
5938 operands[7] = gen_lowpart (SImode, operands[2]);
5939 #if HOST_BITS_PER_WIDE_INT == 32
5940 if (GET_CODE (operands[3]) == CONST_INT)
5942 if (INTVAL (operands[3]) < 0)
5943 operands[8] = constm1_rtx;
5945 operands[8] = const0_rtx;
5949 operands[8] = gen_highpart_mode (SImode, DImode, operands[3]);
5950 operands[9] = gen_lowpart (SImode, operands[3]);
5953 (define_insn_and_split "*and_not_di_sp32"
5954 [(set (match_operand:DI 0 "register_operand" "=r,b")
5955 (and:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
5956 (match_operand:DI 2 "register_operand" "r,b")))]
5960 fandnot1\t%1, %2, %0"
5961 "&& reload_completed
5962 && ((GET_CODE (operands[0]) == REG
5963 && REGNO (operands[0]) < 32)
5964 || (GET_CODE (operands[0]) == SUBREG
5965 && GET_CODE (SUBREG_REG (operands[0])) == REG
5966 && REGNO (SUBREG_REG (operands[0])) < 32))"
5967 [(set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))
5968 (set (match_dup 6) (and:SI (not:SI (match_dup 7)) (match_dup 8)))]
5969 "operands[3] = gen_highpart (SImode, operands[0]);
5970 operands[4] = gen_highpart (SImode, operands[1]);
5971 operands[5] = gen_highpart (SImode, operands[2]);
5972 operands[6] = gen_lowpart (SImode, operands[0]);
5973 operands[7] = gen_lowpart (SImode, operands[1]);
5974 operands[8] = gen_lowpart (SImode, operands[2]);"
5975 [(set_attr "type" "*,fp")
5976 (set_attr "length" "2,*")
5977 (set_attr "fptype" "double")])
5979 (define_insn "*and_not_di_sp64"
5980 [(set (match_operand:DI 0 "register_operand" "=r,b")
5981 (and:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
5982 (match_operand:DI 2 "register_operand" "r,b")))]
5986 fandnot1\t%1, %2, %0"
5987 [(set_attr "type" "*,fp")
5988 (set_attr "fptype" "double")])
5990 (define_insn "*and_not_si"
5991 [(set (match_operand:SI 0 "register_operand" "=r,d")
5992 (and:SI (not:SI (match_operand:SI 1 "register_operand" "r,d"))
5993 (match_operand:SI 2 "register_operand" "r,d")))]
5997 fandnot1s\t%1, %2, %0"
5998 [(set_attr "type" "*,fp")])
6000 (define_expand "iordi3"
6001 [(set (match_operand:DI 0 "register_operand" "")
6002 (ior:DI (match_operand:DI 1 "arith_double_operand" "")
6003 (match_operand:DI 2 "arith_double_operand" "")))]
6007 (define_insn "*iordi3_sp32"
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 "length" "2,*")
6017 (set_attr "fptype" "double")])
6019 (define_insn "*iordi3_sp64"
6020 [(set (match_operand:DI 0 "register_operand" "=r,b")
6021 (ior:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6022 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6027 [(set_attr "type" "*,fp")
6028 (set_attr "fptype" "double")])
6030 (define_insn "iorsi3"
6031 [(set (match_operand:SI 0 "register_operand" "=r,d")
6032 (ior:SI (match_operand:SI 1 "arith_operand" "%r,d")
6033 (match_operand:SI 2 "arith_operand" "rI,d")))]
6038 [(set_attr "type" "*,fp")])
6041 [(set (match_operand:SI 0 "register_operand" "")
6042 (ior:SI (match_operand:SI 1 "register_operand" "")
6043 (match_operand:SI 2 "" "")))
6044 (clobber (match_operand:SI 3 "register_operand" ""))]
6045 "GET_CODE (operands[2]) == CONST_INT
6046 && !SMALL_INT32 (operands[2])
6047 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6048 [(set (match_dup 3) (match_dup 4))
6049 (set (match_dup 0) (ior:SI (not:SI (match_dup 3)) (match_dup 1)))]
6051 operands[4] = GEN_INT (~INTVAL (operands[2]));
6054 (define_insn_and_split "*or_not_di_sp32"
6055 [(set (match_operand:DI 0 "register_operand" "=r,b")
6056 (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6057 (match_operand:DI 2 "register_operand" "r,b")))]
6061 fornot1\t%1, %2, %0"
6062 "&& reload_completed
6063 && ((GET_CODE (operands[0]) == REG
6064 && REGNO (operands[0]) < 32)
6065 || (GET_CODE (operands[0]) == SUBREG
6066 && GET_CODE (SUBREG_REG (operands[0])) == REG
6067 && REGNO (SUBREG_REG (operands[0])) < 32))"
6068 [(set (match_dup 3) (ior:SI (not:SI (match_dup 4)) (match_dup 5)))
6069 (set (match_dup 6) (ior:SI (not:SI (match_dup 7)) (match_dup 8)))]
6070 "operands[3] = gen_highpart (SImode, operands[0]);
6071 operands[4] = gen_highpart (SImode, operands[1]);
6072 operands[5] = gen_highpart (SImode, operands[2]);
6073 operands[6] = gen_lowpart (SImode, operands[0]);
6074 operands[7] = gen_lowpart (SImode, operands[1]);
6075 operands[8] = gen_lowpart (SImode, operands[2]);"
6076 [(set_attr "type" "*,fp")
6077 (set_attr "length" "2,*")
6078 (set_attr "fptype" "double")])
6080 (define_insn "*or_not_di_sp64"
6081 [(set (match_operand:DI 0 "register_operand" "=r,b")
6082 (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6083 (match_operand:DI 2 "register_operand" "r,b")))]
6087 fornot1\t%1, %2, %0"
6088 [(set_attr "type" "*,fp")
6089 (set_attr "fptype" "double")])
6091 (define_insn "*or_not_si"
6092 [(set (match_operand:SI 0 "register_operand" "=r,d")
6093 (ior:SI (not:SI (match_operand:SI 1 "register_operand" "r,d"))
6094 (match_operand:SI 2 "register_operand" "r,d")))]
6098 fornot1s\t%1, %2, %0"
6099 [(set_attr "type" "*,fp")])
6101 (define_expand "xordi3"
6102 [(set (match_operand:DI 0 "register_operand" "")
6103 (xor:DI (match_operand:DI 1 "arith_double_operand" "")
6104 (match_operand:DI 2 "arith_double_operand" "")))]
6108 (define_insn "*xordi3_sp32"
6109 [(set (match_operand:DI 0 "register_operand" "=r,b")
6110 (xor:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6111 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6116 [(set_attr "type" "*,fp")
6117 (set_attr "length" "2,*")
6118 (set_attr "fptype" "double")])
6120 (define_insn "*xordi3_sp64"
6121 [(set (match_operand:DI 0 "register_operand" "=r,b")
6122 (xor:DI (match_operand:DI 1 "arith_double_operand" "%rJ,b")
6123 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6128 [(set_attr "type" "*,fp")
6129 (set_attr "fptype" "double")])
6131 (define_insn "*xordi3_sp64_dbl"
6132 [(set (match_operand:DI 0 "register_operand" "=r")
6133 (xor:DI (match_operand:DI 1 "register_operand" "r")
6134 (match_operand:DI 2 "const64_operand" "")))]
6136 && HOST_BITS_PER_WIDE_INT != 64)"
6139 (define_insn "xorsi3"
6140 [(set (match_operand:SI 0 "register_operand" "=r,d")
6141 (xor:SI (match_operand:SI 1 "arith_operand" "%rJ,d")
6142 (match_operand:SI 2 "arith_operand" "rI,d")))]
6147 [(set_attr "type" "*,fp")])
6150 [(set (match_operand:SI 0 "register_operand" "")
6151 (xor:SI (match_operand:SI 1 "register_operand" "")
6152 (match_operand:SI 2 "" "")))
6153 (clobber (match_operand:SI 3 "register_operand" ""))]
6154 "GET_CODE (operands[2]) == CONST_INT
6155 && !SMALL_INT32 (operands[2])
6156 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6157 [(set (match_dup 3) (match_dup 4))
6158 (set (match_dup 0) (not:SI (xor:SI (match_dup 3) (match_dup 1))))]
6160 operands[4] = GEN_INT (~INTVAL (operands[2]));
6164 [(set (match_operand:SI 0 "register_operand" "")
6165 (not:SI (xor:SI (match_operand:SI 1 "register_operand" "")
6166 (match_operand:SI 2 "" ""))))
6167 (clobber (match_operand:SI 3 "register_operand" ""))]
6168 "GET_CODE (operands[2]) == CONST_INT
6169 && !SMALL_INT32 (operands[2])
6170 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6171 [(set (match_dup 3) (match_dup 4))
6172 (set (match_dup 0) (xor:SI (match_dup 3) (match_dup 1)))]
6174 operands[4] = GEN_INT (~INTVAL (operands[2]));
6177 ;; xnor patterns. Note that (a ^ ~b) == (~a ^ b) == ~(a ^ b).
6178 ;; Combine now canonicalizes to the rightmost expression.
6179 (define_insn_and_split "*xor_not_di_sp32"
6180 [(set (match_operand:DI 0 "register_operand" "=r,b")
6181 (not:DI (xor:DI (match_operand:DI 1 "register_operand" "r,b")
6182 (match_operand:DI 2 "register_operand" "r,b"))))]
6187 "&& reload_completed
6188 && ((GET_CODE (operands[0]) == REG
6189 && REGNO (operands[0]) < 32)
6190 || (GET_CODE (operands[0]) == SUBREG
6191 && GET_CODE (SUBREG_REG (operands[0])) == REG
6192 && REGNO (SUBREG_REG (operands[0])) < 32))"
6193 [(set (match_dup 3) (not:SI (xor:SI (match_dup 4) (match_dup 5))))
6194 (set (match_dup 6) (not:SI (xor:SI (match_dup 7) (match_dup 8))))]
6195 "operands[3] = gen_highpart (SImode, operands[0]);
6196 operands[4] = gen_highpart (SImode, operands[1]);
6197 operands[5] = gen_highpart (SImode, operands[2]);
6198 operands[6] = gen_lowpart (SImode, operands[0]);
6199 operands[7] = gen_lowpart (SImode, operands[1]);
6200 operands[8] = gen_lowpart (SImode, operands[2]);"
6201 [(set_attr "type" "*,fp")
6202 (set_attr "length" "2,*")
6203 (set_attr "fptype" "double")])
6205 (define_insn "*xor_not_di_sp64"
6206 [(set (match_operand:DI 0 "register_operand" "=r,b")
6207 (not:DI (xor:DI (match_operand:DI 1 "reg_or_0_operand" "rJ,b")
6208 (match_operand:DI 2 "arith_double_operand" "rHI,b"))))]
6213 [(set_attr "type" "*,fp")
6214 (set_attr "fptype" "double")])
6216 (define_insn "*xor_not_si"
6217 [(set (match_operand:SI 0 "register_operand" "=r,d")
6218 (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "rJ,d")
6219 (match_operand:SI 2 "arith_operand" "rI,d"))))]
6224 [(set_attr "type" "*,fp")])
6226 ;; These correspond to the above in the case where we also (or only)
6227 ;; want to set the condition code.
6229 (define_insn "*cmp_cc_arith_op"
6232 (match_operator:SI 2 "cc_arithop"
6233 [(match_operand:SI 0 "arith_operand" "%r")
6234 (match_operand:SI 1 "arith_operand" "rI")])
6237 "%A2cc\t%0, %1, %%g0"
6238 [(set_attr "type" "compare")])
6240 (define_insn "*cmp_ccx_arith_op"
6243 (match_operator:DI 2 "cc_arithop"
6244 [(match_operand:DI 0 "arith_double_operand" "%r")
6245 (match_operand:DI 1 "arith_double_operand" "rHI")])
6248 "%A2cc\t%0, %1, %%g0"
6249 [(set_attr "type" "compare")])
6251 (define_insn "*cmp_cc_arith_op_set"
6254 (match_operator:SI 3 "cc_arithop"
6255 [(match_operand:SI 1 "arith_operand" "%r")
6256 (match_operand:SI 2 "arith_operand" "rI")])
6258 (set (match_operand:SI 0 "register_operand" "=r")
6259 (match_operator:SI 4 "cc_arithop" [(match_dup 1) (match_dup 2)]))]
6260 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
6262 [(set_attr "type" "compare")])
6264 (define_insn "*cmp_ccx_arith_op_set"
6267 (match_operator:DI 3 "cc_arithop"
6268 [(match_operand:DI 1 "arith_double_operand" "%r")
6269 (match_operand:DI 2 "arith_double_operand" "rHI")])
6271 (set (match_operand:DI 0 "register_operand" "=r")
6272 (match_operator:DI 4 "cc_arithop" [(match_dup 1) (match_dup 2)]))]
6273 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
6275 [(set_attr "type" "compare")])
6277 (define_insn "*cmp_cc_xor_not"
6280 (not:SI (xor:SI (match_operand:SI 0 "reg_or_0_operand" "%rJ")
6281 (match_operand:SI 1 "arith_operand" "rI")))
6284 "xnorcc\t%r0, %1, %%g0"
6285 [(set_attr "type" "compare")])
6287 (define_insn "*cmp_ccx_xor_not"
6290 (not:DI (xor:DI (match_operand:DI 0 "reg_or_0_operand" "%rJ")
6291 (match_operand:DI 1 "arith_double_operand" "rHI")))
6294 "xnorcc\t%r0, %1, %%g0"
6295 [(set_attr "type" "compare")])
6297 (define_insn "*cmp_cc_xor_not_set"
6300 (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
6301 (match_operand:SI 2 "arith_operand" "rI")))
6303 (set (match_operand:SI 0 "register_operand" "=r")
6304 (not:SI (xor:SI (match_dup 1) (match_dup 2))))]
6306 "xnorcc\t%r1, %2, %0"
6307 [(set_attr "type" "compare")])
6309 (define_insn "*cmp_ccx_xor_not_set"
6312 (not:DI (xor:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ")
6313 (match_operand:DI 2 "arith_double_operand" "rHI")))
6315 (set (match_operand:DI 0 "register_operand" "=r")
6316 (not:DI (xor:DI (match_dup 1) (match_dup 2))))]
6318 "xnorcc\t%r1, %2, %0"
6319 [(set_attr "type" "compare")])
6321 (define_insn "*cmp_cc_arith_op_not"
6324 (match_operator:SI 2 "cc_arithopn"
6325 [(not:SI (match_operand:SI 0 "arith_operand" "rI"))
6326 (match_operand:SI 1 "reg_or_0_operand" "rJ")])
6329 "%B2cc\t%r1, %0, %%g0"
6330 [(set_attr "type" "compare")])
6332 (define_insn "*cmp_ccx_arith_op_not"
6335 (match_operator:DI 2 "cc_arithopn"
6336 [(not:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
6337 (match_operand:DI 1 "reg_or_0_operand" "rJ")])
6340 "%B2cc\t%r1, %0, %%g0"
6341 [(set_attr "type" "compare")])
6343 (define_insn "*cmp_cc_arith_op_not_set"
6346 (match_operator:SI 3 "cc_arithopn"
6347 [(not:SI (match_operand:SI 1 "arith_operand" "rI"))
6348 (match_operand:SI 2 "reg_or_0_operand" "rJ")])
6350 (set (match_operand:SI 0 "register_operand" "=r")
6351 (match_operator:SI 4 "cc_arithopn"
6352 [(not:SI (match_dup 1)) (match_dup 2)]))]
6353 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
6354 "%B3cc\t%r2, %1, %0"
6355 [(set_attr "type" "compare")])
6357 (define_insn "*cmp_ccx_arith_op_not_set"
6360 (match_operator:DI 3 "cc_arithopn"
6361 [(not:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
6362 (match_operand:DI 2 "reg_or_0_operand" "rJ")])
6364 (set (match_operand:DI 0 "register_operand" "=r")
6365 (match_operator:DI 4 "cc_arithopn"
6366 [(not:DI (match_dup 1)) (match_dup 2)]))]
6367 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
6368 "%B3cc\t%r2, %1, %0"
6369 [(set_attr "type" "compare")])
6371 ;; We cannot use the "neg" pseudo insn because the Sun assembler
6372 ;; does not know how to make it work for constants.
6374 (define_expand "negdi2"
6375 [(set (match_operand:DI 0 "register_operand" "=r")
6376 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
6379 if (! TARGET_ARCH64)
6381 emit_insn (gen_rtx_PARALLEL
6384 gen_rtx_SET (VOIDmode, operand0,
6385 gen_rtx_NEG (DImode, operand1)),
6386 gen_rtx_CLOBBER (VOIDmode,
6387 gen_rtx_REG (CCmode,
6393 (define_insn_and_split "*negdi2_sp32"
6394 [(set (match_operand:DI 0 "register_operand" "=r")
6395 (neg:DI (match_operand:DI 1 "register_operand" "r")))
6396 (clobber (reg:CC 100))]
6399 "&& reload_completed"
6400 [(parallel [(set (reg:CC_NOOV 100)
6401 (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 5))
6403 (set (match_dup 4) (minus:SI (const_int 0) (match_dup 5)))])
6404 (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
6405 (ltu:SI (reg:CC 100) (const_int 0))))]
6406 "operands[2] = gen_highpart (SImode, operands[0]);
6407 operands[3] = gen_highpart (SImode, operands[1]);
6408 operands[4] = gen_lowpart (SImode, operands[0]);
6409 operands[5] = gen_lowpart (SImode, operands[1]);"
6410 [(set_attr "length" "2")])
6412 (define_insn "*negdi2_sp64"
6413 [(set (match_operand:DI 0 "register_operand" "=r")
6414 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
6416 "sub\t%%g0, %1, %0")
6418 (define_insn "negsi2"
6419 [(set (match_operand:SI 0 "register_operand" "=r")
6420 (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
6422 "sub\t%%g0, %1, %0")
6424 (define_insn "*cmp_cc_neg"
6425 [(set (reg:CC_NOOV 100)
6426 (compare:CC_NOOV (neg:SI (match_operand:SI 0 "arith_operand" "rI"))
6429 "subcc\t%%g0, %0, %%g0"
6430 [(set_attr "type" "compare")])
6432 (define_insn "*cmp_ccx_neg"
6433 [(set (reg:CCX_NOOV 100)
6434 (compare:CCX_NOOV (neg:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
6437 "subcc\t%%g0, %0, %%g0"
6438 [(set_attr "type" "compare")])
6440 (define_insn "*cmp_cc_set_neg"
6441 [(set (reg:CC_NOOV 100)
6442 (compare:CC_NOOV (neg:SI (match_operand:SI 1 "arith_operand" "rI"))
6444 (set (match_operand:SI 0 "register_operand" "=r")
6445 (neg:SI (match_dup 1)))]
6447 "subcc\t%%g0, %1, %0"
6448 [(set_attr "type" "compare")])
6450 (define_insn "*cmp_ccx_set_neg"
6451 [(set (reg:CCX_NOOV 100)
6452 (compare:CCX_NOOV (neg:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
6454 (set (match_operand:DI 0 "register_operand" "=r")
6455 (neg:DI (match_dup 1)))]
6457 "subcc\t%%g0, %1, %0"
6458 [(set_attr "type" "compare")])
6460 ;; We cannot use the "not" pseudo insn because the Sun assembler
6461 ;; does not know how to make it work for constants.
6462 (define_expand "one_cmpldi2"
6463 [(set (match_operand:DI 0 "register_operand" "")
6464 (not:DI (match_operand:DI 1 "register_operand" "")))]
6468 (define_insn_and_split "*one_cmpldi2_sp32"
6469 [(set (match_operand:DI 0 "register_operand" "=r,b")
6470 (not:DI (match_operand:DI 1 "register_operand" "r,b")))]
6475 "&& reload_completed
6476 && ((GET_CODE (operands[0]) == REG
6477 && REGNO (operands[0]) < 32)
6478 || (GET_CODE (operands[0]) == SUBREG
6479 && GET_CODE (SUBREG_REG (operands[0])) == REG
6480 && REGNO (SUBREG_REG (operands[0])) < 32))"
6481 [(set (match_dup 2) (not:SI (xor:SI (match_dup 3) (const_int 0))))
6482 (set (match_dup 4) (not:SI (xor:SI (match_dup 5) (const_int 0))))]
6483 "operands[2] = gen_highpart (SImode, operands[0]);
6484 operands[3] = gen_highpart (SImode, operands[1]);
6485 operands[4] = gen_lowpart (SImode, operands[0]);
6486 operands[5] = gen_lowpart (SImode, operands[1]);"
6487 [(set_attr "type" "*,fp")
6488 (set_attr "length" "2,*")
6489 (set_attr "fptype" "double")])
6491 (define_insn "*one_cmpldi2_sp64"
6492 [(set (match_operand:DI 0 "register_operand" "=r,b")
6493 (not:DI (match_operand:DI 1 "arith_double_operand" "rHI,b")))]
6498 [(set_attr "type" "*,fp")
6499 (set_attr "fptype" "double")])
6501 (define_insn "one_cmplsi2"
6502 [(set (match_operand:SI 0 "register_operand" "=r,d")
6503 (not:SI (match_operand:SI 1 "arith_operand" "rI,d")))]
6508 [(set_attr "type" "*,fp")])
6510 (define_insn "*cmp_cc_not"
6512 (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI"))
6515 "xnorcc\t%%g0, %0, %%g0"
6516 [(set_attr "type" "compare")])
6518 (define_insn "*cmp_ccx_not"
6520 (compare:CCX (not:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
6523 "xnorcc\t%%g0, %0, %%g0"
6524 [(set_attr "type" "compare")])
6526 (define_insn "*cmp_cc_set_not"
6528 (compare:CC (not:SI (match_operand:SI 1 "arith_operand" "rI"))
6530 (set (match_operand:SI 0 "register_operand" "=r")
6531 (not:SI (match_dup 1)))]
6533 "xnorcc\t%%g0, %1, %0"
6534 [(set_attr "type" "compare")])
6536 (define_insn "*cmp_ccx_set_not"
6538 (compare:CCX (not:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
6540 (set (match_operand:DI 0 "register_operand" "=r")
6541 (not:DI (match_dup 1)))]
6543 "xnorcc\t%%g0, %1, %0"
6544 [(set_attr "type" "compare")])
6546 (define_insn "*cmp_cc_set"
6547 [(set (match_operand:SI 0 "register_operand" "=r")
6548 (match_operand:SI 1 "register_operand" "r"))
6550 (compare:CC (match_dup 1)
6554 [(set_attr "type" "compare")])
6556 (define_insn "*cmp_ccx_set64"
6557 [(set (match_operand:DI 0 "register_operand" "=r")
6558 (match_operand:DI 1 "register_operand" "r"))
6560 (compare:CCX (match_dup 1)
6564 [(set_attr "type" "compare")])
6566 ;; Floating point arithmetic instructions.
6568 (define_expand "addtf3"
6569 [(set (match_operand:TF 0 "nonimmediate_operand" "")
6570 (plus:TF (match_operand:TF 1 "general_operand" "")
6571 (match_operand:TF 2 "general_operand" "")))]
6572 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6573 "emit_tfmode_binop (PLUS, operands); DONE;")
6575 (define_insn "*addtf3_hq"
6576 [(set (match_operand:TF 0 "register_operand" "=e")
6577 (plus:TF (match_operand:TF 1 "register_operand" "e")
6578 (match_operand:TF 2 "register_operand" "e")))]
6579 "TARGET_FPU && TARGET_HARD_QUAD"
6581 [(set_attr "type" "fp")])
6583 (define_insn "adddf3"
6584 [(set (match_operand:DF 0 "register_operand" "=e")
6585 (plus:DF (match_operand:DF 1 "register_operand" "e")
6586 (match_operand:DF 2 "register_operand" "e")))]
6589 [(set_attr "type" "fp")
6590 (set_attr "fptype" "double")])
6592 (define_insn "addsf3"
6593 [(set (match_operand:SF 0 "register_operand" "=f")
6594 (plus:SF (match_operand:SF 1 "register_operand" "f")
6595 (match_operand:SF 2 "register_operand" "f")))]
6598 [(set_attr "type" "fp")])
6600 (define_expand "subtf3"
6601 [(set (match_operand:TF 0 "nonimmediate_operand" "")
6602 (minus:TF (match_operand:TF 1 "general_operand" "")
6603 (match_operand:TF 2 "general_operand" "")))]
6604 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6605 "emit_tfmode_binop (MINUS, operands); DONE;")
6607 (define_insn "*subtf3_hq"
6608 [(set (match_operand:TF 0 "register_operand" "=e")
6609 (minus:TF (match_operand:TF 1 "register_operand" "e")
6610 (match_operand:TF 2 "register_operand" "e")))]
6611 "TARGET_FPU && TARGET_HARD_QUAD"
6613 [(set_attr "type" "fp")])
6615 (define_insn "subdf3"
6616 [(set (match_operand:DF 0 "register_operand" "=e")
6617 (minus:DF (match_operand:DF 1 "register_operand" "e")
6618 (match_operand:DF 2 "register_operand" "e")))]
6621 [(set_attr "type" "fp")
6622 (set_attr "fptype" "double")])
6624 (define_insn "subsf3"
6625 [(set (match_operand:SF 0 "register_operand" "=f")
6626 (minus:SF (match_operand:SF 1 "register_operand" "f")
6627 (match_operand:SF 2 "register_operand" "f")))]
6630 [(set_attr "type" "fp")])
6632 (define_expand "multf3"
6633 [(set (match_operand:TF 0 "nonimmediate_operand" "")
6634 (mult:TF (match_operand:TF 1 "general_operand" "")
6635 (match_operand:TF 2 "general_operand" "")))]
6636 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6637 "emit_tfmode_binop (MULT, operands); DONE;")
6639 (define_insn "*multf3_hq"
6640 [(set (match_operand:TF 0 "register_operand" "=e")
6641 (mult:TF (match_operand:TF 1 "register_operand" "e")
6642 (match_operand:TF 2 "register_operand" "e")))]
6643 "TARGET_FPU && TARGET_HARD_QUAD"
6645 [(set_attr "type" "fpmul")])
6647 (define_insn "muldf3"
6648 [(set (match_operand:DF 0 "register_operand" "=e")
6649 (mult:DF (match_operand:DF 1 "register_operand" "e")
6650 (match_operand:DF 2 "register_operand" "e")))]
6653 [(set_attr "type" "fpmul")
6654 (set_attr "fptype" "double")])
6656 (define_insn "mulsf3"
6657 [(set (match_operand:SF 0 "register_operand" "=f")
6658 (mult:SF (match_operand:SF 1 "register_operand" "f")
6659 (match_operand:SF 2 "register_operand" "f")))]
6662 [(set_attr "type" "fpmul")])
6664 (define_insn "*muldf3_extend"
6665 [(set (match_operand:DF 0 "register_operand" "=e")
6666 (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "f"))
6667 (float_extend:DF (match_operand:SF 2 "register_operand" "f"))))]
6668 "(TARGET_V8 || TARGET_V9) && TARGET_FPU"
6669 "fsmuld\t%1, %2, %0"
6670 [(set_attr "type" "fpmul")
6671 (set_attr "fptype" "double")])
6673 (define_insn "*multf3_extend"
6674 [(set (match_operand:TF 0 "register_operand" "=e")
6675 (mult:TF (float_extend:TF (match_operand:DF 1 "register_operand" "e"))
6676 (float_extend:TF (match_operand:DF 2 "register_operand" "e"))))]
6677 "(TARGET_V8 || TARGET_V9) && TARGET_FPU && TARGET_HARD_QUAD"
6678 "fdmulq\t%1, %2, %0"
6679 [(set_attr "type" "fpmul")])
6681 (define_expand "divtf3"
6682 [(set (match_operand:TF 0 "nonimmediate_operand" "")
6683 (div:TF (match_operand:TF 1 "general_operand" "")
6684 (match_operand:TF 2 "general_operand" "")))]
6685 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6686 "emit_tfmode_binop (DIV, operands); DONE;")
6688 ;; don't have timing for quad-prec. divide.
6689 (define_insn "*divtf3_hq"
6690 [(set (match_operand:TF 0 "register_operand" "=e")
6691 (div:TF (match_operand:TF 1 "register_operand" "e")
6692 (match_operand:TF 2 "register_operand" "e")))]
6693 "TARGET_FPU && TARGET_HARD_QUAD"
6695 [(set_attr "type" "fpdivd")])
6697 (define_insn "divdf3"
6698 [(set (match_operand:DF 0 "register_operand" "=e")
6699 (div:DF (match_operand:DF 1 "register_operand" "e")
6700 (match_operand:DF 2 "register_operand" "e")))]
6703 [(set_attr "type" "fpdivd")
6704 (set_attr "fptype" "double")])
6706 (define_insn "divsf3"
6707 [(set (match_operand:SF 0 "register_operand" "=f")
6708 (div:SF (match_operand:SF 1 "register_operand" "f")
6709 (match_operand:SF 2 "register_operand" "f")))]
6712 [(set_attr "type" "fpdivs")])
6714 (define_expand "negtf2"
6715 [(set (match_operand:TF 0 "register_operand" "=e,e")
6716 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
6720 (define_insn_and_split "*negtf2_notv9"
6721 [(set (match_operand:TF 0 "register_operand" "=e,e")
6722 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
6723 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
6729 "&& reload_completed
6730 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6731 [(set (match_dup 2) (neg:SF (match_dup 3)))
6732 (set (match_dup 4) (match_dup 5))
6733 (set (match_dup 6) (match_dup 7))]
6734 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6735 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6736 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6737 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
6738 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6739 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6740 [(set_attr "type" "fpmove,*")
6741 (set_attr "length" "*,2")])
6743 (define_insn_and_split "*negtf2_v9"
6744 [(set (match_operand:TF 0 "register_operand" "=e,e")
6745 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
6746 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
6747 "TARGET_FPU && TARGET_V9"
6751 "&& reload_completed
6752 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6753 [(set (match_dup 2) (neg:DF (match_dup 3)))
6754 (set (match_dup 4) (match_dup 5))]
6755 "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
6756 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
6757 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6758 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6759 [(set_attr "type" "fpmove,*")
6760 (set_attr "length" "*,2")
6761 (set_attr "fptype" "double")])
6763 (define_expand "negdf2"
6764 [(set (match_operand:DF 0 "register_operand" "")
6765 (neg:DF (match_operand:DF 1 "register_operand" "")))]
6769 (define_insn_and_split "*negdf2_notv9"
6770 [(set (match_operand:DF 0 "register_operand" "=e,e")
6771 (neg:DF (match_operand:DF 1 "register_operand" "0,e")))]
6772 "TARGET_FPU && ! TARGET_V9"
6776 "&& reload_completed
6777 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6778 [(set (match_dup 2) (neg:SF (match_dup 3)))
6779 (set (match_dup 4) (match_dup 5))]
6780 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6781 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6782 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6783 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);"
6784 [(set_attr "type" "fpmove,*")
6785 (set_attr "length" "*,2")])
6787 (define_insn "*negdf2_v9"
6788 [(set (match_operand:DF 0 "register_operand" "=e")
6789 (neg:DF (match_operand:DF 1 "register_operand" "e")))]
6790 "TARGET_FPU && TARGET_V9"
6792 [(set_attr "type" "fpmove")
6793 (set_attr "fptype" "double")])
6795 (define_insn "negsf2"
6796 [(set (match_operand:SF 0 "register_operand" "=f")
6797 (neg:SF (match_operand:SF 1 "register_operand" "f")))]
6800 [(set_attr "type" "fpmove")])
6802 (define_expand "abstf2"
6803 [(set (match_operand:TF 0 "register_operand" "")
6804 (abs:TF (match_operand:TF 1 "register_operand" "")))]
6808 (define_insn_and_split "*abstf2_notv9"
6809 [(set (match_operand:TF 0 "register_operand" "=e,e")
6810 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6811 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
6812 "TARGET_FPU && ! TARGET_V9"
6816 "&& reload_completed
6817 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6818 [(set (match_dup 2) (abs:SF (match_dup 3)))
6819 (set (match_dup 4) (match_dup 5))
6820 (set (match_dup 6) (match_dup 7))]
6821 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6822 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6823 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6824 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
6825 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6826 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6827 [(set_attr "type" "fpmove,*")
6828 (set_attr "length" "*,2")])
6830 (define_insn "*abstf2_hq_v9"
6831 [(set (match_operand:TF 0 "register_operand" "=e,e")
6832 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6833 "TARGET_FPU && TARGET_V9 && TARGET_HARD_QUAD"
6837 [(set_attr "type" "fpmove")
6838 (set_attr "fptype" "double,*")])
6840 (define_insn_and_split "*abstf2_v9"
6841 [(set (match_operand:TF 0 "register_operand" "=e,e")
6842 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6843 "TARGET_FPU && TARGET_V9 && !TARGET_HARD_QUAD"
6847 "&& reload_completed
6848 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6849 [(set (match_dup 2) (abs:DF (match_dup 3)))
6850 (set (match_dup 4) (match_dup 5))]
6851 "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
6852 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
6853 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6854 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6855 [(set_attr "type" "fpmove,*")
6856 (set_attr "length" "*,2")
6857 (set_attr "fptype" "double,*")])
6859 (define_expand "absdf2"
6860 [(set (match_operand:DF 0 "register_operand" "")
6861 (abs:DF (match_operand:DF 1 "register_operand" "")))]
6865 (define_insn_and_split "*absdf2_notv9"
6866 [(set (match_operand:DF 0 "register_operand" "=e,e")
6867 (abs:DF (match_operand:DF 1 "register_operand" "0,e")))]
6868 "TARGET_FPU && ! TARGET_V9"
6872 "&& reload_completed
6873 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6874 [(set (match_dup 2) (abs:SF (match_dup 3)))
6875 (set (match_dup 4) (match_dup 5))]
6876 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6877 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6878 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6879 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);"
6880 [(set_attr "type" "fpmove,*")
6881 (set_attr "length" "*,2")])
6883 (define_insn "*absdf2_v9"
6884 [(set (match_operand:DF 0 "register_operand" "=e")
6885 (abs:DF (match_operand:DF 1 "register_operand" "e")))]
6886 "TARGET_FPU && TARGET_V9"
6888 [(set_attr "type" "fpmove")
6889 (set_attr "fptype" "double")])
6891 (define_insn "abssf2"
6892 [(set (match_operand:SF 0 "register_operand" "=f")
6893 (abs:SF (match_operand:SF 1 "register_operand" "f")))]
6896 [(set_attr "type" "fpmove")])
6898 (define_expand "sqrttf2"
6899 [(set (match_operand:TF 0 "nonimmediate_operand" "")
6900 (sqrt:TF (match_operand:TF 1 "general_operand" "")))]
6901 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6902 "emit_tfmode_unop (SQRT, operands); DONE;")
6904 (define_insn "*sqrttf2_hq"
6905 [(set (match_operand:TF 0 "register_operand" "=e")
6906 (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
6907 "TARGET_FPU && TARGET_HARD_QUAD"
6909 [(set_attr "type" "fpsqrtd")])
6911 (define_insn "sqrtdf2"
6912 [(set (match_operand:DF 0 "register_operand" "=e")
6913 (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
6916 [(set_attr "type" "fpsqrtd")
6917 (set_attr "fptype" "double")])
6919 (define_insn "sqrtsf2"
6920 [(set (match_operand:SF 0 "register_operand" "=f")
6921 (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
6924 [(set_attr "type" "fpsqrts")])
6926 ;;- arithmetic shift instructions
6928 (define_insn "ashlsi3"
6929 [(set (match_operand:SI 0 "register_operand" "=r")
6930 (ashift:SI (match_operand:SI 1 "register_operand" "r")
6931 (match_operand:SI 2 "arith_operand" "rI")))]
6934 if (operands[2] == const1_rtx)
6935 return "add\t%1, %1, %0";
6936 return "sll\t%1, %2, %0";
6939 (if_then_else (match_operand 2 "const1_operand" "")
6940 (const_string "ialu") (const_string "shift")))])
6942 (define_expand "ashldi3"
6943 [(set (match_operand:DI 0 "register_operand" "=r")
6944 (ashift:DI (match_operand:DI 1 "register_operand" "r")
6945 (match_operand:SI 2 "arith_operand" "rI")))]
6946 "TARGET_ARCH64 || TARGET_V8PLUS"
6948 if (! TARGET_ARCH64)
6950 if (GET_CODE (operands[2]) == CONST_INT)
6952 emit_insn (gen_ashldi3_v8plus (operands[0], operands[1], operands[2]));
6957 (define_insn "*ashldi3_sp64"
6958 [(set (match_operand:DI 0 "register_operand" "=r")
6959 (ashift:DI (match_operand:DI 1 "register_operand" "r")
6960 (match_operand:SI 2 "arith_operand" "rI")))]
6963 if (operands[2] == const1_rtx)
6964 return "add\t%1, %1, %0";
6965 return "sllx\t%1, %2, %0";
6968 (if_then_else (match_operand 2 "const1_operand" "")
6969 (const_string "ialu") (const_string "shift")))])
6972 (define_insn "ashldi3_v8plus"
6973 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
6974 (ashift:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
6975 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
6976 (clobber (match_scratch:SI 3 "=X,X,&h"))]
6978 { return sparc_v8plus_shift (operands, insn, "sllx"); }
6979 [(set_attr "type" "multi")
6980 (set_attr "length" "5,5,6")])
6982 ;; Optimize (1LL<<x)-1
6983 ;; XXX this also needs to be fixed to handle equal subregs
6984 ;; XXX first before we could re-enable it.
6986 ; [(set (match_operand:DI 0 "register_operand" "=h")
6987 ; (plus:DI (ashift:DI (const_int 1)
6988 ; (match_operand:SI 1 "arith_operand" "rI"))
6990 ; "0 && TARGET_V8PLUS"
6992 ; if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == REGNO (operands[0]))
6993 ; return "mov\t1, %L0\;sllx\t%L0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
6994 ; return "mov\t1, %H0\;sllx\t%H0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
6996 ; [(set_attr "type" "multi")
6997 ; (set_attr "length" "4")])
6999 (define_insn "*cmp_cc_ashift_1"
7000 [(set (reg:CC_NOOV 100)
7001 (compare:CC_NOOV (ashift:SI (match_operand:SI 0 "register_operand" "r")
7005 "addcc\t%0, %0, %%g0"
7006 [(set_attr "type" "compare")])
7008 (define_insn "*cmp_cc_set_ashift_1"
7009 [(set (reg:CC_NOOV 100)
7010 (compare:CC_NOOV (ashift:SI (match_operand:SI 1 "register_operand" "r")
7013 (set (match_operand:SI 0 "register_operand" "=r")
7014 (ashift:SI (match_dup 1) (const_int 1)))]
7017 [(set_attr "type" "compare")])
7019 (define_insn "ashrsi3"
7020 [(set (match_operand:SI 0 "register_operand" "=r")
7021 (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
7022 (match_operand:SI 2 "arith_operand" "rI")))]
7025 [(set_attr "type" "shift")])
7027 (define_insn "*ashrsi3_extend"
7028 [(set (match_operand:DI 0 "register_operand" "=r")
7029 (sign_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
7030 (match_operand:SI 2 "arith_operand" "r"))))]
7033 [(set_attr "type" "shift")])
7035 ;; This handles the case as above, but with constant shift instead of
7036 ;; register. Combiner "simplifies" it for us a little bit though.
7037 (define_insn "*ashrsi3_extend2"
7038 [(set (match_operand:DI 0 "register_operand" "=r")
7039 (ashiftrt:DI (ashift:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
7041 (match_operand:SI 2 "small_int_or_double" "n")))]
7043 && ((GET_CODE (operands[2]) == CONST_INT
7044 && INTVAL (operands[2]) >= 32 && INTVAL (operands[2]) < 64)
7045 || (GET_CODE (operands[2]) == CONST_DOUBLE
7046 && !CONST_DOUBLE_HIGH (operands[2])
7047 && CONST_DOUBLE_LOW (operands[2]) >= 32
7048 && CONST_DOUBLE_LOW (operands[2]) < 64))"
7050 operands[2] = GEN_INT (INTVAL (operands[2]) - 32);
7052 return "sra\t%1, %2, %0";
7054 [(set_attr "type" "shift")])
7056 (define_expand "ashrdi3"
7057 [(set (match_operand:DI 0 "register_operand" "=r")
7058 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
7059 (match_operand:SI 2 "arith_operand" "rI")))]
7060 "TARGET_ARCH64 || TARGET_V8PLUS"
7062 if (! TARGET_ARCH64)
7064 if (GET_CODE (operands[2]) == CONST_INT)
7065 FAIL; /* prefer generic code in this case */
7066 emit_insn (gen_ashrdi3_v8plus (operands[0], operands[1], operands[2]));
7072 [(set (match_operand:DI 0 "register_operand" "=r")
7073 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
7074 (match_operand:SI 2 "arith_operand" "rI")))]
7077 [(set_attr "type" "shift")])
7080 (define_insn "ashrdi3_v8plus"
7081 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
7082 (ashiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
7083 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
7084 (clobber (match_scratch:SI 3 "=X,X,&h"))]
7086 { return sparc_v8plus_shift (operands, insn, "srax"); }
7087 [(set_attr "type" "multi")
7088 (set_attr "length" "5,5,6")])
7090 (define_insn "lshrsi3"
7091 [(set (match_operand:SI 0 "register_operand" "=r")
7092 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
7093 (match_operand:SI 2 "arith_operand" "rI")))]
7096 [(set_attr "type" "shift")])
7098 ;; This handles the case where
7099 ;; (zero_extend:DI (lshiftrt:SI (match_operand:SI) (match_operand:SI))),
7100 ;; but combiner "simplifies" it for us.
7101 (define_insn "*lshrsi3_extend"
7102 [(set (match_operand:DI 0 "register_operand" "=r")
7103 (and:DI (subreg:DI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
7104 (match_operand:SI 2 "arith_operand" "r")) 0)
7105 (match_operand 3 "" "")))]
7107 && ((GET_CODE (operands[3]) == CONST_DOUBLE
7108 && CONST_DOUBLE_HIGH (operands[3]) == 0
7109 && CONST_DOUBLE_LOW (operands[3]) == 0xffffffff)
7110 || (HOST_BITS_PER_WIDE_INT >= 64
7111 && GET_CODE (operands[3]) == CONST_INT
7112 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) == 0xffffffff))"
7114 [(set_attr "type" "shift")])
7116 ;; This handles the case where
7117 ;; (lshiftrt:DI (zero_extend:DI (match_operand:SI)) (const_int >=0 < 32))
7118 ;; but combiner "simplifies" it for us.
7119 (define_insn "*lshrsi3_extend2"
7120 [(set (match_operand:DI 0 "register_operand" "=r")
7121 (zero_extract:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
7122 (match_operand 2 "small_int_or_double" "n")
7125 && ((GET_CODE (operands[2]) == CONST_INT
7126 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
7127 || (GET_CODE (operands[2]) == CONST_DOUBLE
7128 && CONST_DOUBLE_HIGH (operands[2]) == 0
7129 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
7131 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
7133 return "srl\t%1, %2, %0";
7135 [(set_attr "type" "shift")])
7137 (define_expand "lshrdi3"
7138 [(set (match_operand:DI 0 "register_operand" "=r")
7139 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
7140 (match_operand:SI 2 "arith_operand" "rI")))]
7141 "TARGET_ARCH64 || TARGET_V8PLUS"
7143 if (! TARGET_ARCH64)
7145 if (GET_CODE (operands[2]) == CONST_INT)
7147 emit_insn (gen_lshrdi3_v8plus (operands[0], operands[1], operands[2]));
7153 [(set (match_operand:DI 0 "register_operand" "=r")
7154 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
7155 (match_operand:SI 2 "arith_operand" "rI")))]
7158 [(set_attr "type" "shift")])
7161 (define_insn "lshrdi3_v8plus"
7162 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
7163 (lshiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
7164 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
7165 (clobber (match_scratch:SI 3 "=X,X,&h"))]
7167 { return sparc_v8plus_shift (operands, insn, "srlx"); }
7168 [(set_attr "type" "multi")
7169 (set_attr "length" "5,5,6")])
7172 [(set (match_operand:SI 0 "register_operand" "=r")
7173 (ashiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
7175 (match_operand:SI 2 "small_int_or_double" "n")))]
7177 && ((GET_CODE (operands[2]) == CONST_INT
7178 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
7179 || (GET_CODE (operands[2]) == CONST_DOUBLE
7180 && !CONST_DOUBLE_HIGH (operands[2])
7181 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
7183 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
7185 return "srax\t%1, %2, %0";
7187 [(set_attr "type" "shift")])
7190 [(set (match_operand:SI 0 "register_operand" "=r")
7191 (lshiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
7193 (match_operand:SI 2 "small_int_or_double" "n")))]
7195 && ((GET_CODE (operands[2]) == CONST_INT
7196 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
7197 || (GET_CODE (operands[2]) == CONST_DOUBLE
7198 && !CONST_DOUBLE_HIGH (operands[2])
7199 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
7201 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
7203 return "srlx\t%1, %2, %0";
7205 [(set_attr "type" "shift")])
7208 [(set (match_operand:SI 0 "register_operand" "=r")
7209 (ashiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
7210 (match_operand:SI 2 "small_int_or_double" "n")) 4)
7211 (match_operand:SI 3 "small_int_or_double" "n")))]
7213 && GET_CODE (operands[2]) == CONST_INT && GET_CODE (operands[3]) == CONST_INT
7214 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
7215 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
7216 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
7218 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
7220 return "srax\t%1, %2, %0";
7222 [(set_attr "type" "shift")])
7225 [(set (match_operand:SI 0 "register_operand" "=r")
7226 (lshiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
7227 (match_operand:SI 2 "small_int_or_double" "n")) 4)
7228 (match_operand:SI 3 "small_int_or_double" "n")))]
7230 && GET_CODE (operands[2]) == CONST_INT && GET_CODE (operands[3]) == CONST_INT
7231 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
7232 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
7233 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
7235 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
7237 return "srlx\t%1, %2, %0";
7239 [(set_attr "type" "shift")])
7241 ;; Unconditional and other jump instructions
7242 ;; On the SPARC, by setting the annul bit on an unconditional branch, the
7243 ;; following insn is never executed. This saves us a nop. Dbx does not
7244 ;; handle such branches though, so we only use them when optimizing.
7246 [(set (pc) (label_ref (match_operand 0 "" "")))]
7249 /* TurboSPARC is reported to have problems with
7252 i.e. an empty loop with the annul bit set. The workaround is to use
7256 if (! TARGET_V9 && flag_delayed_branch
7257 && (INSN_ADDRESSES (INSN_UID (operands[0]))
7258 == INSN_ADDRESSES (INSN_UID (insn))))
7261 return TARGET_V9 ? "ba%*,pt\t%%xcc, %l0%(" : "b%*\t%l0%(";
7263 [(set_attr "type" "uncond_branch")])
7265 (define_expand "tablejump"
7266 [(parallel [(set (pc) (match_operand 0 "register_operand" "r"))
7267 (use (label_ref (match_operand 1 "" "")))])]
7270 if (GET_MODE (operands[0]) != CASE_VECTOR_MODE)
7273 /* In pic mode, our address differences are against the base of the
7274 table. Add that base value back in; CSE ought to be able to combine
7275 the two address loads. */
7279 tmp = gen_rtx_LABEL_REF (Pmode, operands[1]);
7281 if (CASE_VECTOR_MODE != Pmode)
7282 tmp2 = gen_rtx_SIGN_EXTEND (Pmode, tmp2);
7283 tmp = gen_rtx_PLUS (Pmode, tmp2, tmp);
7284 operands[0] = memory_address (Pmode, tmp);
7288 (define_insn "*tablejump_sp32"
7289 [(set (pc) (match_operand:SI 0 "address_operand" "p"))
7290 (use (label_ref (match_operand 1 "" "")))]
7293 [(set_attr "type" "uncond_branch")])
7295 (define_insn "*tablejump_sp64"
7296 [(set (pc) (match_operand:DI 0 "address_operand" "p"))
7297 (use (label_ref (match_operand 1 "" "")))]
7300 [(set_attr "type" "uncond_branch")])
7302 ;; This pattern recognizes the "instruction" that appears in
7303 ;; a function call that wants a structure value,
7304 ;; to inform the called function if compiled with Sun CC.
7305 ;(define_insn "*unimp_insn"
7306 ; [(match_operand:SI 0 "immediate_operand" "")]
7307 ; "GET_CODE (operands[0]) == CONST_INT && INTVAL (operands[0]) > 0"
7309 ; [(set_attr "type" "marker")])
7311 ;;- jump to subroutine
7312 (define_expand "call"
7313 ;; Note that this expression is not used for generating RTL.
7314 ;; All the RTL is generated explicitly below.
7315 [(call (match_operand 0 "call_operand" "")
7316 (match_operand 3 "" "i"))]
7317 ;; operands[2] is next_arg_register
7318 ;; operands[3] is struct_value_size_rtx.
7321 rtx fn_rtx, nregs_rtx;
7323 if (GET_MODE (operands[0]) != FUNCTION_MODE)
7326 if (GET_CODE (XEXP (operands[0], 0)) == LABEL_REF)
7328 /* This is really a PIC sequence. We want to represent
7329 it as a funny jump so its delay slots can be filled.
7331 ??? But if this really *is* a CALL, will not it clobber the
7332 call-clobbered registers? We lose this if it is a JUMP_INSN.
7333 Why cannot we have delay slots filled if it were a CALL? */
7335 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
7340 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
7342 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
7348 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
7349 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
7353 fn_rtx = operands[0];
7355 /* Count the number of parameter registers being used by this call.
7356 if that argument is NULL, it means we are using them all, which
7357 means 6 on the sparc. */
7360 nregs_rtx = GEN_INT (REGNO (operands[2]) - 8);
7362 nregs_rtx = GEN_INT (6);
7364 nregs_rtx = const0_rtx;
7367 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
7371 gen_rtvec (3, gen_rtx_CALL (VOIDmode, fn_rtx, nregs_rtx),
7373 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
7378 gen_rtvec (2, gen_rtx_CALL (VOIDmode, fn_rtx, nregs_rtx),
7379 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
7383 /* If this call wants a structure value,
7384 emit an unimp insn to let the called function know about this. */
7385 if (! TARGET_ARCH64 && INTVAL (operands[3]) > 0)
7387 rtx insn = emit_insn (operands[3]);
7388 SCHED_GROUP_P (insn) = 1;
7395 ;; We can't use the same pattern for these two insns, because then registers
7396 ;; in the address may not be properly reloaded.
7398 (define_insn "*call_address_sp32"
7399 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
7400 (match_operand 1 "" ""))
7401 (clobber (reg:SI 15))]
7402 ;;- Do not use operand 1 for most machines.
7405 [(set_attr "type" "call")])
7407 (define_insn "*call_symbolic_sp32"
7408 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
7409 (match_operand 1 "" ""))
7410 (clobber (reg:SI 15))]
7411 ;;- Do not use operand 1 for most machines.
7414 [(set_attr "type" "call")])
7416 (define_insn "*call_address_sp64"
7417 [(call (mem:DI (match_operand:DI 0 "address_operand" "p"))
7418 (match_operand 1 "" ""))
7419 (clobber (reg:DI 15))]
7420 ;;- Do not use operand 1 for most machines.
7423 [(set_attr "type" "call")])
7425 (define_insn "*call_symbolic_sp64"
7426 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
7427 (match_operand 1 "" ""))
7428 (clobber (reg:DI 15))]
7429 ;;- Do not use operand 1 for most machines.
7432 [(set_attr "type" "call")])
7434 ;; This is a call that wants a structure value.
7435 ;; There is no such critter for v9 (??? we may need one anyway).
7436 (define_insn "*call_address_struct_value_sp32"
7437 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
7438 (match_operand 1 "" ""))
7439 (match_operand 2 "immediate_operand" "")
7440 (clobber (reg:SI 15))]
7441 ;;- Do not use operand 1 for most machines.
7442 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 0"
7443 "call\t%a0, %1\n\tnop\n\tunimp\t%2"
7444 [(set_attr "type" "call_no_delay_slot")
7445 (set_attr "length" "3")])
7447 ;; This is a call that wants a structure value.
7448 ;; There is no such critter for v9 (??? we may need one anyway).
7449 (define_insn "*call_symbolic_struct_value_sp32"
7450 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
7451 (match_operand 1 "" ""))
7452 (match_operand 2 "immediate_operand" "")
7453 (clobber (reg:SI 15))]
7454 ;;- Do not use operand 1 for most machines.
7455 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 0"
7456 "call\t%a0, %1\n\tnop\n\tunimp\t%2"
7457 [(set_attr "type" "call_no_delay_slot")
7458 (set_attr "length" "3")])
7460 ;; This is a call that may want a structure value. This is used for
7462 (define_insn "*call_address_untyped_struct_value_sp32"
7463 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
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 ;; This is a call that wants a structure value.
7474 (define_insn "*call_symbolic_untyped_struct_value_sp32"
7475 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
7476 (match_operand 1 "" ""))
7477 (match_operand 2 "immediate_operand" "")
7478 (clobber (reg:SI 15))]
7479 ;;- Do not use operand 1 for most machines.
7480 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
7481 "call\t%a0, %1\n\tnop\n\tnop"
7482 [(set_attr "type" "call_no_delay_slot")
7483 (set_attr "length" "3")])
7485 (define_expand "call_value"
7486 ;; Note that this expression is not used for generating RTL.
7487 ;; All the RTL is generated explicitly below.
7488 [(set (match_operand 0 "register_operand" "=rf")
7489 (call (match_operand 1 "" "")
7490 (match_operand 4 "" "")))]
7491 ;; operand 2 is stack_size_rtx
7492 ;; operand 3 is next_arg_register
7495 rtx fn_rtx, nregs_rtx;
7498 if (GET_MODE (operands[1]) != FUNCTION_MODE)
7501 fn_rtx = operands[1];
7505 nregs_rtx = GEN_INT (REGNO (operands[3]) - 8);
7507 nregs_rtx = GEN_INT (6);
7509 nregs_rtx = const0_rtx;
7513 gen_rtx_SET (VOIDmode, operands[0],
7514 gen_rtx_CALL (VOIDmode, fn_rtx, nregs_rtx)),
7515 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)));
7517 emit_call_insn (gen_rtx_PARALLEL (VOIDmode, vec));
7522 (define_insn "*call_value_address_sp32"
7523 [(set (match_operand 0 "" "=rf")
7524 (call (mem:SI (match_operand:SI 1 "address_operand" "p"))
7525 (match_operand 2 "" "")))
7526 (clobber (reg:SI 15))]
7527 ;;- Do not use operand 2 for most machines.
7530 [(set_attr "type" "call")])
7532 (define_insn "*call_value_symbolic_sp32"
7533 [(set (match_operand 0 "" "=rf")
7534 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
7535 (match_operand 2 "" "")))
7536 (clobber (reg:SI 15))]
7537 ;;- Do not use operand 2 for most machines.
7540 [(set_attr "type" "call")])
7542 (define_insn "*call_value_address_sp64"
7543 [(set (match_operand 0 "" "")
7544 (call (mem:DI (match_operand:DI 1 "address_operand" "p"))
7545 (match_operand 2 "" "")))
7546 (clobber (reg:DI 15))]
7547 ;;- Do not use operand 2 for most machines.
7550 [(set_attr "type" "call")])
7552 (define_insn "*call_value_symbolic_sp64"
7553 [(set (match_operand 0 "" "")
7554 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
7555 (match_operand 2 "" "")))
7556 (clobber (reg:DI 15))]
7557 ;;- Do not use operand 2 for most machines.
7560 [(set_attr "type" "call")])
7562 (define_expand "untyped_call"
7563 [(parallel [(call (match_operand 0 "" "")
7565 (match_operand 1 "" "")
7566 (match_operand 2 "" "")])]
7571 /* Pass constm1 to indicate that it may expect a structure value, but
7572 we don't know what size it is. */
7573 emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, constm1_rtx));
7575 for (i = 0; i < XVECLEN (operands[2], 0); i++)
7577 rtx set = XVECEXP (operands[2], 0, i);
7578 emit_move_insn (SET_DEST (set), SET_SRC (set));
7581 /* The optimizer does not know that the call sets the function value
7582 registers we stored in the result block. We avoid problems by
7583 claiming that all hard registers are used and clobbered at this
7585 emit_insn (gen_blockage ());
7591 (define_expand "sibcall"
7592 [(parallel [(call (match_operand 0 "call_operand" "") (const_int 0))
7597 (define_insn "*sibcall_symbolic_sp32"
7598 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
7599 (match_operand 1 "" ""))
7602 "* return output_sibcall(insn, operands[0]);"
7603 [(set_attr "type" "sibcall")])
7605 (define_insn "*sibcall_symbolic_sp64"
7606 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
7607 (match_operand 1 "" ""))
7610 "* return output_sibcall(insn, operands[0]);"
7611 [(set_attr "type" "sibcall")])
7613 (define_expand "sibcall_value"
7614 [(parallel [(set (match_operand 0 "register_operand" "=rf")
7615 (call (match_operand 1 "" "") (const_int 0)))
7620 (define_insn "*sibcall_value_symbolic_sp32"
7621 [(set (match_operand 0 "" "=rf")
7622 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
7623 (match_operand 2 "" "")))
7626 "* return output_sibcall(insn, operands[1]);"
7627 [(set_attr "type" "sibcall")])
7629 (define_insn "*sibcall_value_symbolic_sp64"
7630 [(set (match_operand 0 "" "")
7631 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
7632 (match_operand 2 "" "")))
7635 "* return output_sibcall(insn, operands[1]);"
7636 [(set_attr "type" "sibcall")])
7638 (define_expand "sibcall_epilogue"
7643 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
7644 ;; all of memory. This blocks insns from being moved across this point.
7646 (define_insn "blockage"
7647 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
7650 [(set_attr "length" "0")])
7652 ;; Prepare to return any type including a structure value.
7654 (define_expand "untyped_return"
7655 [(match_operand:BLK 0 "memory_operand" "")
7656 (match_operand 1 "" "")]
7659 rtx valreg1 = gen_rtx_REG (DImode, 24);
7660 rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
7661 rtx result = operands[0];
7663 if (! TARGET_ARCH64)
7665 rtx rtnreg = gen_rtx_REG (SImode, (current_function_uses_only_leaf_regs
7667 rtx value = gen_reg_rtx (SImode);
7669 /* Fetch the instruction where we will return to and see if it's an unimp
7670 instruction (the most significant 10 bits will be zero). If so,
7671 update the return address to skip the unimp instruction. */
7672 emit_move_insn (value,
7673 gen_rtx_MEM (SImode, plus_constant (rtnreg, 8)));
7674 emit_insn (gen_lshrsi3 (value, value, GEN_INT (22)));
7675 emit_insn (gen_update_return (rtnreg, value));
7678 /* Reload the function value registers. */
7679 emit_move_insn (valreg1, adjust_address (result, DImode, 0));
7680 emit_move_insn (valreg2,
7681 adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8));
7683 /* Put USE insns before the return. */
7684 emit_insn (gen_rtx_USE (VOIDmode, valreg1));
7685 emit_insn (gen_rtx_USE (VOIDmode, valreg2));
7687 /* Construct the return. */
7688 expand_null_return ();
7693 ;; This is a bit of a hack. We're incrementing a fixed register (%i7),
7694 ;; and parts of the compiler don't want to believe that the add is needed.
7696 (define_insn "update_return"
7697 [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
7698 (match_operand:SI 1 "register_operand" "r")] UNSPEC_UPDATE_RETURN)]
7700 "cmp\t%1, 0\;be,a\t.+8\;add\t%0, 4, %0"
7701 [(set_attr "type" "multi")
7702 (set_attr "length" "3")])
7709 (define_expand "indirect_jump"
7710 [(set (pc) (match_operand 0 "address_operand" "p"))]
7714 (define_insn "*branch_sp32"
7715 [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
7718 [(set_attr "type" "uncond_branch")])
7720 (define_insn "*branch_sp64"
7721 [(set (pc) (match_operand:DI 0 "address_operand" "p"))]
7724 [(set_attr "type" "uncond_branch")])
7726 ;; ??? Doesn't work with -mflat.
7727 (define_expand "nonlocal_goto"
7728 [(match_operand:SI 0 "general_operand" "")
7729 (match_operand:SI 1 "general_operand" "")
7730 (match_operand:SI 2 "general_operand" "")
7731 (match_operand:SI 3 "" "")]
7735 rtx chain = operands[0];
7737 rtx lab = operands[1];
7738 rtx stack = operands[2];
7739 rtx fp = operands[3];
7742 /* Trap instruction to flush all the register windows. */
7743 emit_insn (gen_flush_register_windows ());
7745 /* Load the fp value for the containing fn into %fp. This is needed
7746 because STACK refers to %fp. Note that virtual register instantiation
7747 fails if the virtual %fp isn't set from a register. */
7748 if (GET_CODE (fp) != REG)
7749 fp = force_reg (Pmode, fp);
7750 emit_move_insn (virtual_stack_vars_rtx, fp);
7752 /* Find the containing function's current nonlocal goto handler,
7753 which will do any cleanups and then jump to the label. */
7754 labreg = gen_rtx_REG (Pmode, 8);
7755 emit_move_insn (labreg, lab);
7757 /* Restore %fp from stack pointer value for containing function.
7758 The restore insn that follows will move this to %sp,
7759 and reload the appropriate value into %fp. */
7760 emit_move_insn (hard_frame_pointer_rtx, stack);
7762 /* USE of frame_pointer_rtx added for consistency; not clear if
7764 /*emit_insn (gen_rtx_USE (VOIDmode, frame_pointer_rtx));*/
7765 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
7768 /* Return, restoring reg window and jumping to goto handler. */
7769 if (TARGET_V9 && GET_CODE (chain) == CONST_INT
7770 && ! (INTVAL (chain) & ~(HOST_WIDE_INT)0xffffffff))
7772 emit_jump_insn (gen_goto_handler_and_restore_v9 (labreg,
7778 /* Put in the static chain register the nonlocal label address. */
7779 emit_move_insn (static_chain_rtx, chain);
7782 emit_insn (gen_rtx_USE (VOIDmode, static_chain_rtx));
7783 emit_jump_insn (gen_goto_handler_and_restore (labreg));
7788 ;; Special trap insn to flush register windows.
7789 (define_insn "flush_register_windows"
7790 [(unspec_volatile [(const_int 0)] UNSPECV_FLUSHW)]
7792 { return TARGET_V9 ? "flushw" : "ta\t3"; }
7793 [(set_attr "type" "flushw")])
7795 (define_insn "goto_handler_and_restore"
7796 [(unspec_volatile [(match_operand 0 "register_operand" "=r")] UNSPECV_GOTO)]
7797 "GET_MODE (operands[0]) == Pmode"
7798 "jmp\t%0+0\n\trestore"
7799 [(set_attr "type" "multi")
7800 (set_attr "length" "2")])
7802 ;;(define_insn "goto_handler_and_restore_v9"
7803 ;; [(unspec_volatile [(match_operand:SI 0 "register_operand" "=r,r")
7804 ;; (match_operand:SI 1 "register_operand" "=r,r")
7805 ;; (match_operand:SI 2 "const_int_operand" "I,n")] UNSPECV_GOTO_V9)]
7806 ;; "TARGET_V9 && ! TARGET_ARCH64"
7808 ;; return\t%0+0\n\tmov\t%2, %Y1
7809 ;; sethi\t%%hi(%2), %1\n\treturn\t%0+0\n\tor\t%Y1, %%lo(%2), %Y1"
7810 ;; [(set_attr "type" "multi")
7811 ;; (set_attr "length" "2,3")])
7813 ;;(define_insn "*goto_handler_and_restore_v9_sp64"
7814 ;; [(unspec_volatile [(match_operand:DI 0 "register_operand" "=r,r")
7815 ;; (match_operand:DI 1 "register_operand" "=r,r")
7816 ;; (match_operand:SI 2 "const_int_operand" "I,n")] UNSPECV_GOTO_V9)]
7817 ;; "TARGET_V9 && TARGET_ARCH64"
7819 ;; return\t%0+0\n\tmov\t%2, %Y1
7820 ;; sethi\t%%hi(%2), %1\n\treturn\t%0+0\n\tor\t%Y1, %%lo(%2), %Y1"
7821 ;; [(set_attr "type" "multi")
7822 ;; (set_attr "length" "2,3")])
7824 ;; For __builtin_setjmp we need to flush register windows iff the function
7825 ;; calls alloca as well, because otherwise the register window might be
7826 ;; saved after %sp adjustement and thus setjmp would crash
7827 (define_expand "builtin_setjmp_setup"
7828 [(match_operand 0 "register_operand" "r")]
7831 emit_insn (gen_do_builtin_setjmp_setup ());
7835 (define_insn "do_builtin_setjmp_setup"
7836 [(unspec_volatile [(const_int 0)] UNSPECV_SETJMP)]
7839 if (! current_function_calls_alloca)
7841 if (! TARGET_V9 || TARGET_FLAT)
7843 fputs ("\tflushw\n", asm_out_file);
7845 fprintf (asm_out_file, "\tst%c\t%%l7, [%%sp+%d]\n",
7846 TARGET_ARCH64 ? 'x' : 'w',
7847 SPARC_STACK_BIAS + 7 * UNITS_PER_WORD);
7848 fprintf (asm_out_file, "\tst%c\t%%fp, [%%sp+%d]\n",
7849 TARGET_ARCH64 ? 'x' : 'w',
7850 SPARC_STACK_BIAS + 14 * UNITS_PER_WORD);
7851 fprintf (asm_out_file, "\tst%c\t%%i7, [%%sp+%d]\n",
7852 TARGET_ARCH64 ? 'x' : 'w',
7853 SPARC_STACK_BIAS + 15 * UNITS_PER_WORD);
7856 [(set_attr "type" "multi")
7857 (set (attr "length")
7858 (cond [(eq_attr "current_function_calls_alloca" "false")
7860 (eq_attr "flat" "true")
7862 (eq_attr "isa" "!v9")
7864 (eq_attr "pic" "true")
7865 (const_int 4)] (const_int 3)))])
7867 ;; Pattern for use after a setjmp to store FP and the return register
7868 ;; into the stack area.
7870 (define_expand "setjmp"
7875 emit_insn (gen_setjmp_64 ());
7877 emit_insn (gen_setjmp_32 ());
7881 (define_expand "setjmp_32"
7882 [(set (mem:SI (plus:SI (reg:SI 14) (const_int 56))) (match_dup 0))
7883 (set (mem:SI (plus:SI (reg:SI 14) (const_int 60))) (reg:SI 31))]
7885 { operands[0] = frame_pointer_rtx; })
7887 (define_expand "setjmp_64"
7888 [(set (mem:DI (plus:DI (reg:DI 14) (const_int 112))) (match_dup 0))
7889 (set (mem:DI (plus:DI (reg:DI 14) (const_int 120))) (reg:DI 31))]
7891 { operands[0] = frame_pointer_rtx; })
7893 ;; Special pattern for the FLUSH instruction.
7895 ; We do SImode and DImode versions of this to quiet down genrecog's complaints
7896 ; of the define_insn otherwise missing a mode. We make "flush", aka
7897 ; gen_flush, the default one since sparc_initialize_trampoline uses
7898 ; it on SImode mem values.
7900 (define_insn "flush"
7901 [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")] UNSPECV_FLUSH)]
7903 { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; }
7904 [(set_attr "type" "iflush")])
7906 (define_insn "flushdi"
7907 [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")] UNSPECV_FLUSH)]
7909 { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; }
7910 [(set_attr "type" "iflush")])
7915 ;; The scan instruction searches from the most significant bit while ffs
7916 ;; searches from the least significant bit. The bit index and treatment of
7917 ;; zero also differ. It takes at least 7 instructions to get the proper
7918 ;; result. Here is an obvious 8 instruction sequence.
7921 (define_insn "ffssi2"
7922 [(set (match_operand:SI 0 "register_operand" "=&r")
7923 (ffs:SI (match_operand:SI 1 "register_operand" "r")))
7924 (clobber (match_scratch:SI 2 "=&r"))]
7925 "TARGET_SPARCLITE || TARGET_SPARCLET"
7927 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";
7929 [(set_attr "type" "multi")
7930 (set_attr "length" "8")])
7932 ;; ??? This should be a define expand, so that the extra instruction have
7933 ;; a chance of being optimized away.
7935 ;; Disabled because none of the UltraSPARCs implement popc. The HAL R1
7936 ;; does, but no one uses that and we don't have a switch for it.
7938 ;(define_insn "ffsdi2"
7939 ; [(set (match_operand:DI 0 "register_operand" "=&r")
7940 ; (ffs:DI (match_operand:DI 1 "register_operand" "r")))
7941 ; (clobber (match_scratch:DI 2 "=&r"))]
7943 ; "neg\t%1, %2\;xnor\t%1, %2, %2\;popc\t%2, %0\;movzr\t%1, 0, %0"
7944 ; [(set_attr "type" "multi")
7945 ; (set_attr "length" "4")])
7949 ;; Peepholes go at the end.
7951 ;; Optimize consecutive loads or stores into ldd and std when possible.
7952 ;; The conditions in which we do this are very restricted and are
7953 ;; explained in the code for {registers,memory}_ok_for_ldd functions.
7956 [(set (match_operand:SI 0 "memory_operand" "")
7958 (set (match_operand:SI 1 "memory_operand" "")
7961 && mems_ok_for_ldd_peep (operands[0], operands[1], NULL_RTX)"
7964 "operands[0] = widen_memory_access (operands[0], DImode, 0);")
7967 [(set (match_operand:SI 0 "memory_operand" "")
7969 (set (match_operand:SI 1 "memory_operand" "")
7972 && mems_ok_for_ldd_peep (operands[1], operands[0], NULL_RTX)"
7975 "operands[1] = widen_memory_access (operands[1], DImode, 0);")
7978 [(set (match_operand:SI 0 "register_operand" "")
7979 (match_operand:SI 1 "memory_operand" ""))
7980 (set (match_operand:SI 2 "register_operand" "")
7981 (match_operand:SI 3 "memory_operand" ""))]
7982 "registers_ok_for_ldd_peep (operands[0], operands[2])
7983 && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
7986 "operands[1] = widen_memory_access (operands[1], DImode, 0);
7987 operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));")
7990 [(set (match_operand:SI 0 "memory_operand" "")
7991 (match_operand:SI 1 "register_operand" ""))
7992 (set (match_operand:SI 2 "memory_operand" "")
7993 (match_operand:SI 3 "register_operand" ""))]
7994 "registers_ok_for_ldd_peep (operands[1], operands[3])
7995 && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
7998 "operands[0] = widen_memory_access (operands[0], DImode, 0);
7999 operands[1] = gen_rtx_REG (DImode, REGNO (operands[1]));")
8002 [(set (match_operand:SF 0 "register_operand" "")
8003 (match_operand:SF 1 "memory_operand" ""))
8004 (set (match_operand:SF 2 "register_operand" "")
8005 (match_operand:SF 3 "memory_operand" ""))]
8006 "registers_ok_for_ldd_peep (operands[0], operands[2])
8007 && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
8010 "operands[1] = widen_memory_access (operands[1], DFmode, 0);
8011 operands[0] = gen_rtx_REG (DFmode, REGNO (operands[0]));")
8014 [(set (match_operand:SF 0 "memory_operand" "")
8015 (match_operand:SF 1 "register_operand" ""))
8016 (set (match_operand:SF 2 "memory_operand" "")
8017 (match_operand:SF 3 "register_operand" ""))]
8018 "registers_ok_for_ldd_peep (operands[1], operands[3])
8019 && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
8022 "operands[0] = widen_memory_access (operands[0], DFmode, 0);
8023 operands[1] = gen_rtx_REG (DFmode, REGNO (operands[1]));")
8026 [(set (match_operand:SI 0 "register_operand" "")
8027 (match_operand:SI 1 "memory_operand" ""))
8028 (set (match_operand:SI 2 "register_operand" "")
8029 (match_operand:SI 3 "memory_operand" ""))]
8030 "registers_ok_for_ldd_peep (operands[2], operands[0])
8031 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
8034 "operands[3] = widen_memory_access (operands[3], DImode, 0);
8035 operands[2] = gen_rtx_REG (DImode, REGNO (operands[2]));")
8038 [(set (match_operand:SI 0 "memory_operand" "")
8039 (match_operand:SI 1 "register_operand" ""))
8040 (set (match_operand:SI 2 "memory_operand" "")
8041 (match_operand:SI 3 "register_operand" ""))]
8042 "registers_ok_for_ldd_peep (operands[3], operands[1])
8043 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
8046 "operands[2] = widen_memory_access (operands[2], DImode, 0);
8047 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
8051 [(set (match_operand:SF 0 "register_operand" "")
8052 (match_operand:SF 1 "memory_operand" ""))
8053 (set (match_operand:SF 2 "register_operand" "")
8054 (match_operand:SF 3 "memory_operand" ""))]
8055 "registers_ok_for_ldd_peep (operands[2], operands[0])
8056 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
8059 "operands[3] = widen_memory_access (operands[3], DFmode, 0);
8060 operands[2] = gen_rtx_REG (DFmode, REGNO (operands[2]));")
8063 [(set (match_operand:SF 0 "memory_operand" "")
8064 (match_operand:SF 1 "register_operand" ""))
8065 (set (match_operand:SF 2 "memory_operand" "")
8066 (match_operand:SF 3 "register_operand" ""))]
8067 "registers_ok_for_ldd_peep (operands[3], operands[1])
8068 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
8071 "operands[2] = widen_memory_access (operands[2], DFmode, 0);
8072 operands[3] = gen_rtx_REG (DFmode, REGNO (operands[3]));")
8074 ;; Optimize the case of following a reg-reg move with a test
8075 ;; of reg just moved. Don't allow floating point regs for operand 0 or 1.
8076 ;; This can result from a float to fix conversion.
8079 [(set (match_operand:SI 0 "register_operand" "")
8080 (match_operand:SI 1 "register_operand" ""))
8082 (compare:CC (match_operand:SI 2 "register_operand" "")
8084 "(rtx_equal_p (operands[2], operands[0])
8085 || rtx_equal_p (operands[2], operands[1]))
8086 && ! SPARC_FP_REG_P (REGNO (operands[0]))
8087 && ! SPARC_FP_REG_P (REGNO (operands[1]))"
8088 [(parallel [(set (match_dup 0) (match_dup 1))
8090 (compare:CC (match_dup 1) (const_int 0)))])]
8094 [(set (match_operand:DI 0 "register_operand" "")
8095 (match_operand:DI 1 "register_operand" ""))
8097 (compare:CCX (match_operand:DI 2 "register_operand" "")
8100 && (rtx_equal_p (operands[2], operands[0])
8101 || rtx_equal_p (operands[2], operands[1]))
8102 && ! SPARC_FP_REG_P (REGNO (operands[0]))
8103 && ! SPARC_FP_REG_P (REGNO (operands[1]))"
8104 [(parallel [(set (match_dup 0) (match_dup 1))
8106 (compare:CCX (match_dup 1) (const_int 0)))])]
8109 ;; Return peepholes. These are generated by sparc_nonflat_function_epilogue
8110 ;; who then immediately calls final_scan_insn.
8112 (define_insn "*return_qi"
8113 [(set (match_operand:QI 0 "restore_operand" "")
8114 (match_operand:QI 1 "arith_operand" "rI"))
8116 "sparc_emitting_epilogue"
8118 if (! TARGET_ARCH64 && current_function_returns_struct)
8119 return "jmp\t%%i7+12\n\trestore %%g0, %1, %Y0";
8120 else if (TARGET_V9 && (GET_CODE (operands[1]) == CONST_INT
8121 || IN_OR_GLOBAL_P (operands[1])))
8122 return "return\t%%i7+8\n\tmov\t%Y1, %Y0";
8124 return "ret\n\trestore %%g0, %1, %Y0";
8126 [(set_attr "type" "multi")
8127 (set_attr "length" "2")])
8129 (define_insn "*return_hi"
8130 [(set (match_operand:HI 0 "restore_operand" "")
8131 (match_operand:HI 1 "arith_operand" "rI"))
8133 "sparc_emitting_epilogue"
8135 if (! TARGET_ARCH64 && current_function_returns_struct)
8136 return "jmp\t%%i7+12\n\trestore %%g0, %1, %Y0";
8137 else if (TARGET_V9 && (GET_CODE (operands[1]) == CONST_INT
8138 || IN_OR_GLOBAL_P (operands[1])))
8139 return "return\t%%i7+8\n\tmov\t%Y1, %Y0";
8141 return "ret\;restore %%g0, %1, %Y0";
8143 [(set_attr "type" "multi")
8144 (set_attr "length" "2")])
8146 (define_insn "*return_si"
8147 [(set (match_operand:SI 0 "restore_operand" "")
8148 (match_operand:SI 1 "arith_operand" "rI"))
8150 "sparc_emitting_epilogue"
8152 if (! TARGET_ARCH64 && current_function_returns_struct)
8153 return "jmp\t%%i7+12\n\trestore %%g0, %1, %Y0";
8154 else if (TARGET_V9 && (GET_CODE (operands[1]) == CONST_INT
8155 || IN_OR_GLOBAL_P (operands[1])))
8156 return "return\t%%i7+8\n\tmov\t%Y1, %Y0";
8158 return "ret\;restore %%g0, %1, %Y0";
8160 [(set_attr "type" "multi")
8161 (set_attr "length" "2")])
8163 (define_insn "*return_sf_no_fpu"
8164 [(set (match_operand:SF 0 "restore_operand" "=r")
8165 (match_operand:SF 1 "register_operand" "r"))
8167 "sparc_emitting_epilogue"
8169 if (! TARGET_ARCH64 && current_function_returns_struct)
8170 return "jmp\t%%i7+12\n\trestore %%g0, %1, %Y0";
8171 else if (TARGET_V9 && IN_OR_GLOBAL_P (operands[1]))
8172 return "return\t%%i7+8\n\tmov\t%Y1, %Y0";
8174 return "ret\;restore %%g0, %1, %Y0";
8176 [(set_attr "type" "multi")
8177 (set_attr "length" "2")])
8179 (define_insn "*return_df_no_fpu"
8180 [(set (match_operand:DF 0 "restore_operand" "=r")
8181 (match_operand:DF 1 "register_operand" "r"))
8183 "sparc_emitting_epilogue && TARGET_ARCH64"
8185 if (IN_OR_GLOBAL_P (operands[1]))
8186 return "return\t%%i7+8\n\tmov\t%Y1, %Y0";
8188 return "ret\;restore %%g0, %1, %Y0";
8190 [(set_attr "type" "multi")
8191 (set_attr "length" "2")])
8193 (define_insn "*return_addsi"
8194 [(set (match_operand:SI 0 "restore_operand" "")
8195 (plus:SI (match_operand:SI 1 "register_operand" "r")
8196 (match_operand:SI 2 "arith_operand" "rI")))
8198 "sparc_emitting_epilogue"
8200 if (! TARGET_ARCH64 && current_function_returns_struct)
8201 return "jmp\t%%i7+12\n\trestore %r1, %2, %Y0";
8202 /* If operands are global or in registers, can use return */
8203 else if (TARGET_V9 && IN_OR_GLOBAL_P (operands[1])
8204 && (GET_CODE (operands[2]) == CONST_INT
8205 || IN_OR_GLOBAL_P (operands[2])))
8206 return "return\t%%i7+8\n\tadd\t%Y1, %Y2, %Y0";
8208 return "ret\;restore %r1, %2, %Y0";
8210 [(set_attr "type" "multi")
8211 (set_attr "length" "2")])
8213 (define_insn "*return_losum_si"
8214 [(set (match_operand:SI 0 "restore_operand" "")
8215 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
8216 (match_operand:SI 2 "immediate_operand" "in")))
8218 "sparc_emitting_epilogue && ! TARGET_CM_MEDMID"
8220 if (! TARGET_ARCH64 && current_function_returns_struct)
8221 return "jmp\t%%i7+12\n\trestore %r1, %%lo(%a2), %Y0";
8222 /* If operands are global or in registers, can use return */
8223 else if (TARGET_V9 && IN_OR_GLOBAL_P (operands[1]))
8224 return "return\t%%i7+8\n\tor\t%Y1, %%lo(%a2), %Y0";
8226 return "ret\;restore %r1, %%lo(%a2), %Y0";
8228 [(set_attr "type" "multi")
8229 (set_attr "length" "2")])
8231 (define_insn "*return_di"
8232 [(set (match_operand:DI 0 "restore_operand" "")
8233 (match_operand:DI 1 "arith_double_operand" "rHI"))
8235 "sparc_emitting_epilogue && TARGET_ARCH64"
8236 "ret\;restore %%g0, %1, %Y0"
8237 [(set_attr "type" "multi")
8238 (set_attr "length" "2")])
8240 (define_insn "*return_adddi"
8241 [(set (match_operand:DI 0 "restore_operand" "")
8242 (plus:DI (match_operand:DI 1 "arith_operand" "%r")
8243 (match_operand:DI 2 "arith_double_operand" "rHI")))
8245 "sparc_emitting_epilogue && TARGET_ARCH64"
8246 "ret\;restore %r1, %2, %Y0"
8247 [(set_attr "type" "multi")
8248 (set_attr "length" "2")])
8250 (define_insn "*return_losum_di"
8251 [(set (match_operand:DI 0 "restore_operand" "")
8252 (lo_sum:DI (match_operand:DI 1 "arith_operand" "%r")
8253 (match_operand:DI 2 "immediate_operand" "in")))
8255 "sparc_emitting_epilogue && TARGET_ARCH64 && ! TARGET_CM_MEDMID"
8256 "ret\;restore %r1, %%lo(%a2), %Y0"
8257 [(set_attr "type" "multi")
8258 (set_attr "length" "2")])
8260 (define_insn "*return_sf"
8262 (match_operand:SF 0 "register_operand" "f"))
8264 "sparc_emitting_epilogue"
8265 "ret\;fmovs\t%0, %%f0"
8266 [(set_attr "type" "multi")
8267 (set_attr "length" "2")])
8269 ;; Now peepholes to do a call followed by a jump.
8272 [(parallel [(set (match_operand 0 "" "")
8273 (call (mem:SI (match_operand:SI 1 "call_operand_address" "ps"))
8274 (match_operand 2 "" "")))
8275 (clobber (reg:SI 15))])
8276 (set (pc) (label_ref (match_operand 3 "" "")))]
8277 "short_branch (INSN_UID (insn), INSN_UID (operands[3]))
8278 && (USING_SJLJ_EXCEPTIONS || ! can_throw_internal (ins1))
8279 && sparc_cpu != PROCESSOR_ULTRASPARC
8280 && sparc_cpu != PROCESSOR_ULTRASPARC3"
8281 "call\t%a1, %2\n\tadd\t%%o7, (%l3-.-4), %%o7")
8284 [(parallel [(call (mem:SI (match_operand:SI 0 "call_operand_address" "ps"))
8285 (match_operand 1 "" ""))
8286 (clobber (reg:SI 15))])
8287 (set (pc) (label_ref (match_operand 2 "" "")))]
8288 "short_branch (INSN_UID (insn), INSN_UID (operands[2]))
8289 && (USING_SJLJ_EXCEPTIONS || ! can_throw_internal (ins1))
8290 && sparc_cpu != PROCESSOR_ULTRASPARC
8291 && sparc_cpu != PROCESSOR_ULTRASPARC3"
8292 "call\t%a0, %1\n\tadd\t%%o7, (%l2-.-4), %%o7")
8294 ;; ??? UltraSPARC-III note: A memory operation loading into the floating point register
8295 ;; ??? file, if it hits the prefetch cache, has a chance to dual-issue with other memory
8296 ;; ??? operations. With DFA we might be able to model this, but it requires a lot of
8298 (define_expand "prefetch"
8299 [(match_operand 0 "address_operand" "")
8300 (match_operand 1 "const_int_operand" "")
8301 (match_operand 2 "const_int_operand" "")]
8305 emit_insn (gen_prefetch_64 (operands[0], operands[1], operands[2]));
8307 emit_insn (gen_prefetch_32 (operands[0], operands[1], operands[2]));
8311 (define_insn "prefetch_64"
8312 [(prefetch (match_operand:DI 0 "address_operand" "p")
8313 (match_operand:DI 1 "const_int_operand" "n")
8314 (match_operand:DI 2 "const_int_operand" "n"))]
8317 static const char * const prefetch_instr[2][2] = {
8319 "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
8320 "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
8323 "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
8324 "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
8327 int read_or_write = INTVAL (operands[1]);
8328 int locality = INTVAL (operands[2]);
8330 if (read_or_write != 0 && read_or_write != 1)
8332 if (locality < 0 || locality > 3)
8334 return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
8336 [(set_attr "type" "load")])
8338 (define_insn "prefetch_32"
8339 [(prefetch (match_operand:SI 0 "address_operand" "p")
8340 (match_operand:SI 1 "const_int_operand" "n")
8341 (match_operand:SI 2 "const_int_operand" "n"))]
8344 static const char * const prefetch_instr[2][2] = {
8346 "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
8347 "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
8350 "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
8351 "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
8354 int read_or_write = INTVAL (operands[1]);
8355 int locality = INTVAL (operands[2]);
8357 if (read_or_write != 0 && read_or_write != 1)
8359 if (locality < 0 || locality > 3)
8361 return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
8363 [(set_attr "type" "load")])
8365 (define_expand "prologue"
8367 "flag_pic && current_function_uses_pic_offset_table"
8369 load_pic_register ();
8373 ;; We need to reload %l7 for -mflat -fpic,
8374 ;; otherwise %l7 should be preserved simply
8375 ;; by loading the function's register window
8376 (define_expand "exception_receiver"
8378 "TARGET_FLAT && flag_pic"
8380 load_pic_register ();
8385 (define_expand "builtin_setjmp_receiver"
8386 [(label_ref (match_operand 0 "" ""))]
8387 "TARGET_FLAT && flag_pic"
8389 load_pic_register ();
8394 [(trap_if (const_int 1) (const_int 5))]
8397 [(set_attr "type" "trap")])
8399 (define_expand "conditional_trap"
8400 [(trap_if (match_operator 0 "noov_compare_op"
8401 [(match_dup 2) (match_dup 3)])
8402 (match_operand:SI 1 "arith_operand" ""))]
8404 "operands[2] = gen_compare_reg (GET_CODE (operands[0]),
8405 sparc_compare_op0, sparc_compare_op1);
8406 operands[3] = const0_rtx;")
8409 [(trap_if (match_operator 0 "noov_compare_op" [(reg:CC 100) (const_int 0)])
8410 (match_operand:SI 1 "arith_operand" "rM"))]
8413 [(set_attr "type" "trap")])
8416 [(trap_if (match_operator 0 "noov_compare_op" [(reg:CCX 100) (const_int 0)])
8417 (match_operand:SI 1 "arith_operand" "rM"))]
8420 [(set_attr "type" "trap")])