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 !arch64.
2052 ;; We match MEM moves directly when we have correct even
2053 ;; numbered registers, but fall into splits otherwise.
2054 ;; The constraint ordering here is really important to
2055 ;; avoid insane problems in reload, especially for patterns
2058 ;; (set (mem:DI (plus:SI (reg:SI 30 %fp)
2059 ;; (const_int -5016)))
2063 (define_insn "*movdi_insn_sp32_v9"
2064 [(set (match_operand:DI 0 "nonimmediate_operand"
2065 "=T,o,T,U,o,r,r,r,?T,?f,?f,?o,?f")
2066 (match_operand:DI 1 "input_operand"
2067 " J,J,U,T,r,o,i,r, f, T, o, f, f"))]
2068 "! TARGET_ARCH64 && TARGET_V9
2069 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2084 [(set_attr "type" "store,store,store,load,*,*,*,*,fpstore,fpload,*,*,*")
2085 (set_attr "length" "*,2,*,*,2,2,2,2,*,*,2,2,2")])
2087 (define_insn "*movdi_insn_sp32"
2088 [(set (match_operand:DI 0 "nonimmediate_operand"
2089 "=o,T,U,o,r,r,r,?T,?f,?f,?o,?f")
2090 (match_operand:DI 1 "input_operand"
2091 " J,U,T,r,o,i,r, f, T, o, f, f"))]
2093 && (register_operand (operands[0], DImode)
2094 || register_operand (operands[1], DImode))"
2108 [(set_attr "type" "store,store,load,*,*,*,*,fpstore,fpload,*,*,*")
2109 (set_attr "length" "2,*,*,2,2,2,2,*,*,2,2,2")])
2111 ;; The following are generated by sparc_emit_set_const64
2112 (define_insn "*movdi_sp64_dbl"
2113 [(set (match_operand:DI 0 "register_operand" "=r")
2114 (match_operand:DI 1 "const64_operand" ""))]
2116 && HOST_BITS_PER_WIDE_INT != 64)"
2119 ;; This is needed to show CSE exactly which bits are set
2120 ;; in a 64-bit register by sethi instructions.
2121 (define_insn "*movdi_const64_special"
2122 [(set (match_operand:DI 0 "register_operand" "=r")
2123 (match_operand:DI 1 "const64_high_operand" ""))]
2125 "sethi\t%%hi(%a1), %0")
2127 (define_insn "*movdi_insn_sp64_novis"
2128 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,m,?e,?e,?W")
2129 (match_operand:DI 1 "input_operand" "rI,N,J,m,rJ,e,W,e"))]
2130 "TARGET_ARCH64 && ! TARGET_VIS
2131 && (register_operand (operands[0], DImode)
2132 || reg_or_0_operand (operands[1], DImode))"
2135 sethi\t%%hi(%a1), %0
2142 [(set_attr "type" "*,*,*,load,store,fpmove,fpload,fpstore")
2143 (set_attr "fptype" "*,*,*,*,*,double,*,*")])
2145 (define_insn "*movdi_insn_sp64_vis"
2146 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,m,?e,?e,?W,b")
2147 (match_operand:DI 1 "input_operand" "rI,N,J,m,rJ,e,W,e,J"))]
2148 "TARGET_ARCH64 && TARGET_VIS &&
2149 (register_operand (operands[0], DImode)
2150 || reg_or_0_operand (operands[1], DImode))"
2153 sethi\t%%hi(%a1), %0
2161 [(set_attr "type" "*,*,*,load,store,fpmove,fpload,fpstore,fpmove")
2162 (set_attr "fptype" "*,*,*,*,*,double,*,*,double")])
2164 (define_expand "movdi_pic_label_ref"
2165 [(set (match_dup 3) (high:DI
2166 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
2167 (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
2168 (set (match_dup 4) (lo_sum:DI (match_dup 3)
2169 (unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
2170 (set (match_operand:DI 0 "register_operand" "=r")
2171 (minus:DI (match_dup 5) (match_dup 4)))]
2172 "TARGET_ARCH64 && flag_pic"
2174 current_function_uses_pic_offset_table = 1;
2175 operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
2178 operands[3] = operands[0];
2179 operands[4] = operands[0];
2183 operands[3] = gen_reg_rtx (DImode);
2184 operands[4] = gen_reg_rtx (DImode);
2186 operands[5] = pic_offset_table_rtx;
2189 (define_insn "*movdi_high_pic_label_ref"
2190 [(set (match_operand:DI 0 "register_operand" "=r")
2192 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
2193 (match_operand:DI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
2194 "TARGET_ARCH64 && flag_pic"
2195 "sethi\t%%hi(%a2-(%a1-.)), %0")
2197 (define_insn "*movdi_lo_sum_pic_label_ref"
2198 [(set (match_operand:DI 0 "register_operand" "=r")
2199 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2200 (unspec:DI [(match_operand:DI 2 "label_ref_operand" "")
2201 (match_operand:DI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
2202 "TARGET_ARCH64 && flag_pic"
2203 "or\t%1, %%lo(%a3-(%a2-.)), %0")
2205 ;; SPARC-v9 code model support insns. See sparc_emit_set_symbolic_const64
2206 ;; in sparc.c to see what is going on here... PIC stuff comes first.
2208 (define_insn "movdi_lo_sum_pic"
2209 [(set (match_operand:DI 0 "register_operand" "=r")
2210 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2211 (unspec:DI [(match_operand:DI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
2212 "TARGET_ARCH64 && flag_pic"
2213 "or\t%1, %%lo(%a2), %0")
2215 (define_insn "movdi_high_pic"
2216 [(set (match_operand:DI 0 "register_operand" "=r")
2217 (high:DI (unspec:DI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
2218 "TARGET_ARCH64 && flag_pic && check_pic (1)"
2219 "sethi\t%%hi(%a1), %0")
2221 (define_insn "*sethi_di_medlow_embmedany_pic"
2222 [(set (match_operand:DI 0 "register_operand" "=r")
2223 (high:DI (match_operand:DI 1 "sp64_medium_pic_operand" "")))]
2224 "(TARGET_CM_MEDLOW || TARGET_CM_EMBMEDANY) && check_pic (1)"
2225 "sethi\t%%hi(%a1), %0")
2227 (define_insn "*sethi_di_medlow"
2228 [(set (match_operand:DI 0 "register_operand" "=r")
2229 (high:DI (match_operand:DI 1 "symbolic_operand" "")))]
2230 "TARGET_CM_MEDLOW && check_pic (1)"
2231 "sethi\t%%hi(%a1), %0")
2233 (define_insn "*losum_di_medlow"
2234 [(set (match_operand:DI 0 "register_operand" "=r")
2235 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2236 (match_operand:DI 2 "symbolic_operand" "")))]
2238 "or\t%1, %%lo(%a2), %0")
2240 (define_insn "seth44"
2241 [(set (match_operand:DI 0 "register_operand" "=r")
2242 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETH44)))]
2244 "sethi\t%%h44(%a1), %0")
2246 (define_insn "setm44"
2247 [(set (match_operand:DI 0 "register_operand" "=r")
2248 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2249 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_SETM44)))]
2251 "or\t%1, %%m44(%a2), %0")
2253 (define_insn "setl44"
2254 [(set (match_operand:DI 0 "register_operand" "=r")
2255 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2256 (match_operand:DI 2 "symbolic_operand" "")))]
2258 "or\t%1, %%l44(%a2), %0")
2260 (define_insn "sethh"
2261 [(set (match_operand:DI 0 "register_operand" "=r")
2262 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETHH)))]
2264 "sethi\t%%hh(%a1), %0")
2266 (define_insn "setlm"
2267 [(set (match_operand:DI 0 "register_operand" "=r")
2268 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETLM)))]
2270 "sethi\t%%lm(%a1), %0")
2272 (define_insn "sethm"
2273 [(set (match_operand:DI 0 "register_operand" "=r")
2274 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2275 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_EMB_SETHM)))]
2277 "or\t%1, %%hm(%a2), %0")
2279 (define_insn "setlo"
2280 [(set (match_operand:DI 0 "register_operand" "=r")
2281 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2282 (match_operand:DI 2 "symbolic_operand" "")))]
2284 "or\t%1, %%lo(%a2), %0")
2286 (define_insn "embmedany_sethi"
2287 [(set (match_operand:DI 0 "register_operand" "=r")
2288 (high:DI (unspec:DI [(match_operand:DI 1 "data_segment_operand" "")] UNSPEC_EMB_HISUM)))]
2289 "TARGET_CM_EMBMEDANY && check_pic (1)"
2290 "sethi\t%%hi(%a1), %0")
2292 (define_insn "embmedany_losum"
2293 [(set (match_operand:DI 0 "register_operand" "=r")
2294 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2295 (match_operand:DI 2 "data_segment_operand" "")))]
2296 "TARGET_CM_EMBMEDANY"
2297 "add\t%1, %%lo(%a2), %0")
2299 (define_insn "embmedany_brsum"
2300 [(set (match_operand:DI 0 "register_operand" "=r")
2301 (unspec:DI [(match_operand:DI 1 "register_operand" "r")] UNSPEC_EMB_HISUM))]
2302 "TARGET_CM_EMBMEDANY"
2305 (define_insn "embmedany_textuhi"
2306 [(set (match_operand:DI 0 "register_operand" "=r")
2307 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTUHI)))]
2308 "TARGET_CM_EMBMEDANY && check_pic (1)"
2309 "sethi\t%%uhi(%a1), %0")
2311 (define_insn "embmedany_texthi"
2312 [(set (match_operand:DI 0 "register_operand" "=r")
2313 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTHI)))]
2314 "TARGET_CM_EMBMEDANY && check_pic (1)"
2315 "sethi\t%%hi(%a1), %0")
2317 (define_insn "embmedany_textulo"
2318 [(set (match_operand:DI 0 "register_operand" "=r")
2319 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2320 (unspec:DI [(match_operand:DI 2 "text_segment_operand" "")] UNSPEC_EMB_TEXTULO)))]
2321 "TARGET_CM_EMBMEDANY"
2322 "or\t%1, %%ulo(%a2), %0")
2324 (define_insn "embmedany_textlo"
2325 [(set (match_operand:DI 0 "register_operand" "=r")
2326 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2327 (match_operand:DI 2 "text_segment_operand" "")))]
2328 "TARGET_CM_EMBMEDANY"
2329 "or\t%1, %%lo(%a2), %0")
2331 ;; Now some patterns to help reload out a bit.
2332 (define_expand "reload_indi"
2333 [(parallel [(match_operand:DI 0 "register_operand" "=r")
2334 (match_operand:DI 1 "immediate_operand" "")
2335 (match_operand:TI 2 "register_operand" "=&r")])]
2337 || TARGET_CM_EMBMEDANY)
2340 sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
2344 (define_expand "reload_outdi"
2345 [(parallel [(match_operand:DI 0 "register_operand" "=r")
2346 (match_operand:DI 1 "immediate_operand" "")
2347 (match_operand:TI 2 "register_operand" "=&r")])]
2349 || TARGET_CM_EMBMEDANY)
2352 sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
2356 ;; Split up putting CONSTs and REGs into DI regs when !arch64
2358 [(set (match_operand:DI 0 "register_operand" "")
2359 (match_operand:DI 1 "const_int_operand" ""))]
2360 "! TARGET_ARCH64 && reload_completed"
2361 [(clobber (const_int 0))]
2363 #if HOST_BITS_PER_WIDE_INT == 32
2364 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
2365 (INTVAL (operands[1]) < 0) ?
2368 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2371 unsigned int low, high;
2373 low = trunc_int_for_mode (INTVAL (operands[1]), SImode);
2374 high = trunc_int_for_mode (INTVAL (operands[1]) >> 32, SImode);
2375 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), GEN_INT (high)));
2377 /* Slick... but this trick loses if this subreg constant part
2378 can be done in one insn. */
2379 if (low == high && (low & 0x3ff) != 0 && low + 0x1000 >= 0x2000)
2380 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2381 gen_highpart (SImode, operands[0])));
2383 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), GEN_INT (low)));
2389 [(set (match_operand:DI 0 "register_operand" "")
2390 (match_operand:DI 1 "const_double_operand" ""))]
2391 "! TARGET_ARCH64 && reload_completed"
2392 [(clobber (const_int 0))]
2394 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
2395 GEN_INT (CONST_DOUBLE_HIGH (operands[1]))));
2397 /* Slick... but this trick loses if this subreg constant part
2398 can be done in one insn. */
2399 if (CONST_DOUBLE_LOW (operands[1]) == CONST_DOUBLE_HIGH (operands[1])
2400 && !(SPARC_SETHI32_P (CONST_DOUBLE_HIGH (operands[1]))
2401 || SPARC_SIMM13_P (CONST_DOUBLE_HIGH (operands[1]))))
2403 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2404 gen_highpart (SImode, operands[0])));
2408 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2409 GEN_INT (CONST_DOUBLE_LOW (operands[1]))));
2415 [(set (match_operand:DI 0 "register_operand" "")
2416 (match_operand:DI 1 "register_operand" ""))]
2417 "! TARGET_ARCH64 && reload_completed"
2418 [(clobber (const_int 0))]
2420 rtx set_dest = operands[0];
2421 rtx set_src = operands[1];
2425 dest1 = gen_highpart (SImode, set_dest);
2426 dest2 = gen_lowpart (SImode, set_dest);
2427 src1 = gen_highpart (SImode, set_src);
2428 src2 = gen_lowpart (SImode, set_src);
2430 /* Now emit using the real source and destination we found, swapping
2431 the order if we detect overlap. */
2432 if (reg_overlap_mentioned_p (dest1, src2))
2434 emit_insn (gen_movsi (dest2, src2));
2435 emit_insn (gen_movsi (dest1, src1));
2439 emit_insn (gen_movsi (dest1, src1));
2440 emit_insn (gen_movsi (dest2, src2));
2445 ;; Now handle the cases of memory moves from/to non-even
2446 ;; DI mode register pairs.
2448 [(set (match_operand:DI 0 "register_operand" "")
2449 (match_operand:DI 1 "memory_operand" ""))]
2452 && sparc_splitdi_legitimate (operands[0], operands[1]))"
2453 [(clobber (const_int 0))]
2455 rtx word0 = adjust_address (operands[1], SImode, 0);
2456 rtx word1 = adjust_address (operands[1], SImode, 4);
2457 rtx high_part = gen_highpart (SImode, operands[0]);
2458 rtx low_part = gen_lowpart (SImode, operands[0]);
2460 if (reg_overlap_mentioned_p (high_part, word1))
2462 emit_insn (gen_movsi (low_part, word1));
2463 emit_insn (gen_movsi (high_part, word0));
2467 emit_insn (gen_movsi (high_part, word0));
2468 emit_insn (gen_movsi (low_part, word1));
2474 [(set (match_operand:DI 0 "memory_operand" "")
2475 (match_operand:DI 1 "register_operand" ""))]
2478 && sparc_splitdi_legitimate (operands[1], operands[0]))"
2479 [(clobber (const_int 0))]
2481 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0),
2482 gen_highpart (SImode, operands[1])));
2483 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4),
2484 gen_lowpart (SImode, operands[1])));
2489 [(set (match_operand:DI 0 "memory_operand" "")
2494 && ! mem_min_alignment (operands[0], 8)))
2495 && offsettable_memref_p (operands[0])"
2496 [(clobber (const_int 0))]
2498 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0), const0_rtx));
2499 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4), const0_rtx));
2503 ;; Floating point move insns
2505 (define_insn "*movsf_insn_novis"
2506 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,*r,*r,*r,*r,*r,f,m,m")
2507 (match_operand:SF 1 "input_operand" "f,G,Q,*rR,S,m,m,f,*rG"))]
2508 "(TARGET_FPU && ! TARGET_VIS)
2509 && (register_operand (operands[0], SFmode)
2510 || register_operand (operands[1], SFmode)
2511 || fp_zero_operand (operands[1], SFmode))"
2513 if (GET_CODE (operands[1]) == CONST_DOUBLE
2514 && (which_alternative == 2
2515 || which_alternative == 3
2516 || which_alternative == 4))
2521 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2522 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2523 operands[1] = GEN_INT (i);
2526 switch (which_alternative)
2529 return "fmovs\t%1, %0";
2533 return "sethi\t%%hi(%a1), %0";
2535 return "mov\t%1, %0";
2540 return "ld\t%1, %0";
2543 return "st\t%r1, %0";
2548 [(set_attr "type" "fpmove,*,*,*,*,load,fpload,fpstore,store")])
2550 (define_insn "*movsf_insn_vis"
2551 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,*r,*r,*r,*r,*r,f,m,m")
2552 (match_operand:SF 1 "input_operand" "f,G,G,Q,*rR,S,m,m,f,*rG"))]
2553 "(TARGET_FPU && TARGET_VIS)
2554 && (register_operand (operands[0], SFmode)
2555 || register_operand (operands[1], SFmode)
2556 || fp_zero_operand (operands[1], SFmode))"
2558 if (GET_CODE (operands[1]) == CONST_DOUBLE
2559 && (which_alternative == 3
2560 || which_alternative == 4
2561 || which_alternative == 5))
2566 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2567 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2568 operands[1] = GEN_INT (i);
2571 switch (which_alternative)
2574 return "fmovs\t%1, %0";
2576 return "fzeros\t%0";
2580 return "sethi\t%%hi(%a1), %0";
2582 return "mov\t%1, %0";
2587 return "ld\t%1, %0";
2590 return "st\t%r1, %0";
2595 [(set_attr "type" "fpmove,fpmove,*,*,*,*,load,fpload,fpstore,store")])
2597 ;; Exactly the same as above, except that all `f' cases are deleted.
2598 ;; This is necessary to prevent reload from ever trying to use a `f' reg
2601 (define_insn "*movsf_no_f_insn"
2602 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r,r,r,m")
2603 (match_operand:SF 1 "input_operand" "G,Q,rR,S,m,rG"))]
2605 && (register_operand (operands[0], SFmode)
2606 || register_operand (operands[1], SFmode)
2607 || fp_zero_operand (operands[1], SFmode))"
2609 if (GET_CODE (operands[1]) == CONST_DOUBLE
2610 && (which_alternative == 1
2611 || which_alternative == 2
2612 || which_alternative == 3))
2617 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2618 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2619 operands[1] = GEN_INT (i);
2622 switch (which_alternative)
2627 return "sethi\t%%hi(%a1), %0";
2629 return "mov\t%1, %0";
2633 return "ld\t%1, %0";
2635 return "st\t%r1, %0";
2640 [(set_attr "type" "*,*,*,*,load,store")])
2642 (define_insn "*movsf_lo_sum"
2643 [(set (match_operand:SF 0 "register_operand" "=r")
2644 (lo_sum:SF (match_operand:SF 1 "register_operand" "r")
2645 (match_operand:SF 2 "const_double_operand" "S")))]
2646 "fp_high_losum_p (operands[2])"
2651 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[2]);
2652 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2653 operands[2] = GEN_INT (i);
2654 return "or\t%1, %%lo(%a2), %0";
2657 (define_insn "*movsf_high"
2658 [(set (match_operand:SF 0 "register_operand" "=r")
2659 (high:SF (match_operand:SF 1 "const_double_operand" "S")))]
2660 "fp_high_losum_p (operands[1])"
2665 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2666 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2667 operands[1] = GEN_INT (i);
2668 return "sethi\t%%hi(%1), %0";
2672 [(set (match_operand:SF 0 "register_operand" "")
2673 (match_operand:SF 1 "const_double_operand" ""))]
2674 "fp_high_losum_p (operands[1])
2675 && (GET_CODE (operands[0]) == REG
2676 && REGNO (operands[0]) < 32)"
2677 [(set (match_dup 0) (high:SF (match_dup 1)))
2678 (set (match_dup 0) (lo_sum:SF (match_dup 0) (match_dup 1)))])
2680 (define_expand "movsf"
2681 [(set (match_operand:SF 0 "general_operand" "")
2682 (match_operand:SF 1 "general_operand" ""))]
2685 /* Force SFmode constants into memory. */
2686 if (GET_CODE (operands[0]) == REG
2687 && CONSTANT_P (operands[1]))
2689 /* emit_group_store will send such bogosity to us when it is
2690 not storing directly into memory. So fix this up to avoid
2691 crashes in output_constant_pool. */
2692 if (operands [1] == const0_rtx)
2693 operands[1] = CONST0_RTX (SFmode);
2695 if (TARGET_VIS && fp_zero_operand (operands[1], SFmode))
2698 /* We are able to build any SF constant in integer registers
2699 with at most 2 instructions. */
2700 if (REGNO (operands[0]) < 32)
2703 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
2707 /* Handle sets of MEM first. */
2708 if (GET_CODE (operands[0]) == MEM)
2710 if (register_operand (operands[1], SFmode)
2711 || fp_zero_operand (operands[1], SFmode))
2714 if (! reload_in_progress)
2716 operands[0] = validize_mem (operands[0]);
2717 operands[1] = force_reg (SFmode, operands[1]);
2721 /* Fixup PIC cases. */
2724 if (CONSTANT_P (operands[1])
2725 && pic_address_needs_scratch (operands[1]))
2726 operands[1] = legitimize_pic_address (operands[1], SFmode, 0);
2728 if (symbolic_operand (operands[1], SFmode))
2730 operands[1] = legitimize_pic_address (operands[1],
2732 (reload_in_progress ?
2742 (define_expand "movdf"
2743 [(set (match_operand:DF 0 "general_operand" "")
2744 (match_operand:DF 1 "general_operand" ""))]
2747 /* Force DFmode constants into memory. */
2748 if (GET_CODE (operands[0]) == REG
2749 && CONSTANT_P (operands[1]))
2751 /* emit_group_store will send such bogosity to us when it is
2752 not storing directly into memory. So fix this up to avoid
2753 crashes in output_constant_pool. */
2754 if (operands [1] == const0_rtx)
2755 operands[1] = CONST0_RTX (DFmode);
2757 if ((TARGET_VIS || REGNO (operands[0]) < 32)
2758 && fp_zero_operand (operands[1], DFmode))
2761 /* We are able to build any DF constant in integer registers. */
2762 if (REGNO (operands[0]) < 32
2763 && (reload_completed || reload_in_progress))
2766 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
2770 /* Handle MEM cases first. */
2771 if (GET_CODE (operands[0]) == MEM)
2773 if (register_operand (operands[1], DFmode)
2774 || fp_zero_operand (operands[1], DFmode))
2777 if (! reload_in_progress)
2779 operands[0] = validize_mem (operands[0]);
2780 operands[1] = force_reg (DFmode, operands[1]);
2784 /* Fixup PIC cases. */
2787 if (CONSTANT_P (operands[1])
2788 && pic_address_needs_scratch (operands[1]))
2789 operands[1] = legitimize_pic_address (operands[1], DFmode, 0);
2791 if (symbolic_operand (operands[1], DFmode))
2793 operands[1] = legitimize_pic_address (operands[1],
2795 (reload_in_progress ?
2805 ;; Be careful, fmovd does not exist when !v9.
2806 (define_insn "*movdf_insn_sp32"
2807 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,W,U,T,o,e,*r,o,e,o")
2808 (match_operand:DF 1 "input_operand" "W#F,e,T,U,G,e,*rFo,*r,o#F,e"))]
2811 && (register_operand (operands[0], DFmode)
2812 || register_operand (operands[1], DFmode)
2813 || fp_zero_operand (operands[1], DFmode))"
2825 [(set_attr "type" "fpload,fpstore,load,store,*,*,*,*,*,*")
2826 (set_attr "length" "*,*,*,*,2,2,2,2,2,2")])
2828 (define_insn "*movdf_no_e_insn_sp32"
2829 [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,o,r,o")
2830 (match_operand:DF 1 "input_operand" "T,U,G,ro,r"))]
2834 && (register_operand (operands[0], DFmode)
2835 || register_operand (operands[1], DFmode)
2836 || fp_zero_operand (operands[1], DFmode))"
2843 [(set_attr "type" "load,store,*,*,*")
2844 (set_attr "length" "*,*,2,2,2")])
2846 (define_insn "*movdf_no_e_insn_v9_sp32"
2847 [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,T,r,o")
2848 (match_operand:DF 1 "input_operand" "T,U,G,ro,rG"))]
2852 && (register_operand (operands[0], DFmode)
2853 || register_operand (operands[1], DFmode)
2854 || fp_zero_operand (operands[1], DFmode))"
2861 [(set_attr "type" "load,store,store,*,*")
2862 (set_attr "length" "*,*,*,2,2")])
2864 ;; We have available v9 double floats but not 64-bit
2865 ;; integer registers and no VIS.
2866 (define_insn "*movdf_insn_v9only_novis"
2867 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,T,W,U,T,f,*r,o")
2868 (match_operand:DF 1 "input_operand" "e,W#F,G,e,T,U,o#F,*roF,*rGf"))]
2873 && (register_operand (operands[0], DFmode)
2874 || register_operand (operands[1], DFmode)
2875 || fp_zero_operand (operands[1], DFmode))"
2886 [(set_attr "type" "fpmove,load,store,store,load,store,*,*,*")
2887 (set_attr "length" "*,*,*,*,*,*,2,2,2")
2888 (set_attr "fptype" "double,*,*,*,*,*,*,*,*")])
2890 ;; We have available v9 double floats but not 64-bit
2891 ;; integer registers but we have VIS.
2892 (define_insn "*movdf_insn_v9only_vis"
2893 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,e,T,W,U,T,f,*r,o")
2894 (match_operand:DF 1 "input_operand" "G,e,W#F,G,e,T,U,o#F,*roGF,*rGf"))]
2898 && (register_operand (operands[0], DFmode)
2899 || register_operand (operands[1], DFmode)
2900 || fp_zero_operand (operands[1], DFmode))"
2912 [(set_attr "type" "fpmove,fpmove,load,store,store,load,store,*,*,*")
2913 (set_attr "length" "*,*,*,*,*,*,*,2,2,2")
2914 (set_attr "fptype" "double,double,*,*,*,*,*,*,*,*")])
2916 ;; We have available both v9 double floats and 64-bit
2917 ;; integer registers. No VIS though.
2918 (define_insn "*movdf_insn_sp64_novis"
2919 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,W,*r,*r,m,*r")
2920 (match_operand:DF 1 "input_operand" "e,W#F,e,*rG,m,*rG,F"))]
2924 && (register_operand (operands[0], DFmode)
2925 || register_operand (operands[1], DFmode)
2926 || fp_zero_operand (operands[1], DFmode))"
2935 [(set_attr "type" "fpmove,load,store,*,load,store,*")
2936 (set_attr "length" "*,*,*,*,*,*,2")
2937 (set_attr "fptype" "double,*,*,*,*,*,*")])
2939 ;; We have available both v9 double floats and 64-bit
2940 ;; integer registers. And we have VIS.
2941 (define_insn "*movdf_insn_sp64_vis"
2942 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,e,W,*r,*r,m,*r")
2943 (match_operand:DF 1 "input_operand" "G,e,W#F,e,*rG,m,*rG,F"))]
2947 && (register_operand (operands[0], DFmode)
2948 || register_operand (operands[1], DFmode)
2949 || fp_zero_operand (operands[1], DFmode))"
2959 [(set_attr "type" "fpmove,fpmove,load,store,*,load,store,*")
2960 (set_attr "length" "*,*,*,*,*,*,*,2")
2961 (set_attr "fptype" "double,double,*,*,*,*,*,*")])
2963 (define_insn "*movdf_no_e_insn_sp64"
2964 [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m")
2965 (match_operand:DF 1 "input_operand" "r,m,rG"))]
2968 && (register_operand (operands[0], DFmode)
2969 || register_operand (operands[1], DFmode)
2970 || fp_zero_operand (operands[1], DFmode))"
2975 [(set_attr "type" "*,load,store")])
2978 [(set (match_operand:DF 0 "register_operand" "")
2979 (match_operand:DF 1 "const_double_operand" ""))]
2981 && (GET_CODE (operands[0]) == REG
2982 && REGNO (operands[0]) < 32)
2983 && ! fp_zero_operand(operands[1], DFmode)
2984 && reload_completed"
2985 [(clobber (const_int 0))]
2990 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2991 REAL_VALUE_TO_TARGET_DOUBLE (r, l);
2992 operands[0] = gen_rtx_raw_REG (DImode, REGNO (operands[0]));
2996 #if HOST_BITS_PER_WIDE_INT == 64
2999 val = ((HOST_WIDE_INT)(unsigned long)l[1] |
3000 ((HOST_WIDE_INT)(unsigned long)l[0] << 32));
3001 emit_insn (gen_movdi (operands[0], GEN_INT (val)));
3003 emit_insn (gen_movdi (operands[0],
3004 immed_double_const (l[1], l[0], DImode)));
3009 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
3012 /* Slick... but this trick loses if this subreg constant part
3013 can be done in one insn. */
3015 && !(SPARC_SETHI32_P (l[0])
3016 || SPARC_SIMM13_P (l[0])))
3018 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
3019 gen_highpart (SImode, operands[0])));
3023 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
3030 ;; Ok, now the splits to handle all the multi insn and
3031 ;; mis-aligned memory address cases.
3032 ;; In these splits please take note that we must be
3033 ;; careful when V9 but not ARCH64 because the integer
3034 ;; register DFmode cases must be handled.
3036 [(set (match_operand:DF 0 "register_operand" "")
3037 (match_operand:DF 1 "register_operand" ""))]
3040 && ((GET_CODE (operands[0]) == REG
3041 && REGNO (operands[0]) < 32)
3042 || (GET_CODE (operands[0]) == SUBREG
3043 && GET_CODE (SUBREG_REG (operands[0])) == REG
3044 && REGNO (SUBREG_REG (operands[0])) < 32))))
3045 && reload_completed"
3046 [(clobber (const_int 0))]
3048 rtx set_dest = operands[0];
3049 rtx set_src = operands[1];
3053 dest1 = gen_highpart (SFmode, set_dest);
3054 dest2 = gen_lowpart (SFmode, set_dest);
3055 src1 = gen_highpart (SFmode, set_src);
3056 src2 = gen_lowpart (SFmode, set_src);
3058 /* Now emit using the real source and destination we found, swapping
3059 the order if we detect overlap. */
3060 if (reg_overlap_mentioned_p (dest1, src2))
3062 emit_insn (gen_movsf (dest2, src2));
3063 emit_insn (gen_movsf (dest1, src1));
3067 emit_insn (gen_movsf (dest1, src1));
3068 emit_insn (gen_movsf (dest2, src2));
3074 [(set (match_operand:DF 0 "register_operand" "")
3075 (match_operand:DF 1 "memory_operand" ""))]
3078 && (((REGNO (operands[0]) % 2) != 0)
3079 || ! mem_min_alignment (operands[1], 8))
3080 && offsettable_memref_p (operands[1])"
3081 [(clobber (const_int 0))]
3083 rtx word0 = adjust_address (operands[1], SFmode, 0);
3084 rtx word1 = adjust_address (operands[1], SFmode, 4);
3086 if (reg_overlap_mentioned_p (gen_highpart (SFmode, operands[0]), word1))
3088 emit_insn (gen_movsf (gen_lowpart (SFmode, operands[0]),
3090 emit_insn (gen_movsf (gen_highpart (SFmode, operands[0]),
3095 emit_insn (gen_movsf (gen_highpart (SFmode, operands[0]),
3097 emit_insn (gen_movsf (gen_lowpart (SFmode, operands[0]),
3104 [(set (match_operand:DF 0 "memory_operand" "")
3105 (match_operand:DF 1 "register_operand" ""))]
3108 && (((REGNO (operands[1]) % 2) != 0)
3109 || ! mem_min_alignment (operands[0], 8))
3110 && offsettable_memref_p (operands[0])"
3111 [(clobber (const_int 0))]
3113 rtx word0 = adjust_address (operands[0], SFmode, 0);
3114 rtx word1 = adjust_address (operands[0], SFmode, 4);
3116 emit_insn (gen_movsf (word0,
3117 gen_highpart (SFmode, operands[1])));
3118 emit_insn (gen_movsf (word1,
3119 gen_lowpart (SFmode, operands[1])));
3124 [(set (match_operand:DF 0 "memory_operand" "")
3125 (match_operand:DF 1 "fp_zero_operand" ""))]
3129 && ! mem_min_alignment (operands[0], 8)))
3130 && offsettable_memref_p (operands[0])"
3131 [(clobber (const_int 0))]
3135 dest1 = adjust_address (operands[0], SFmode, 0);
3136 dest2 = adjust_address (operands[0], SFmode, 4);
3138 emit_insn (gen_movsf (dest1, CONST0_RTX (SFmode)));
3139 emit_insn (gen_movsf (dest2, CONST0_RTX (SFmode)));
3144 [(set (match_operand:DF 0 "register_operand" "")
3145 (match_operand:DF 1 "fp_zero_operand" ""))]
3148 && ((GET_CODE (operands[0]) == REG
3149 && REGNO (operands[0]) < 32)
3150 || (GET_CODE (operands[0]) == SUBREG
3151 && GET_CODE (SUBREG_REG (operands[0])) == REG
3152 && REGNO (SUBREG_REG (operands[0])) < 32))"
3153 [(clobber (const_int 0))]
3155 rtx set_dest = operands[0];
3158 dest1 = gen_highpart (SFmode, set_dest);
3159 dest2 = gen_lowpart (SFmode, set_dest);
3160 emit_insn (gen_movsf (dest1, CONST0_RTX (SFmode)));
3161 emit_insn (gen_movsf (dest2, CONST0_RTX (SFmode)));
3165 (define_expand "movtf"
3166 [(set (match_operand:TF 0 "general_operand" "")
3167 (match_operand:TF 1 "general_operand" ""))]
3170 /* Force TFmode constants into memory. */
3171 if (GET_CODE (operands[0]) == REG
3172 && CONSTANT_P (operands[1]))
3174 /* emit_group_store will send such bogosity to us when it is
3175 not storing directly into memory. So fix this up to avoid
3176 crashes in output_constant_pool. */
3177 if (operands [1] == const0_rtx)
3178 operands[1] = CONST0_RTX (TFmode);
3180 if (TARGET_VIS && fp_zero_operand (operands[1], TFmode))
3183 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
3187 /* Handle MEM cases first, note that only v9 guarentees
3188 full 16-byte alignment for quads. */
3189 if (GET_CODE (operands[0]) == MEM)
3191 if (register_operand (operands[1], TFmode)
3192 || fp_zero_operand (operands[1], TFmode))
3195 if (! reload_in_progress)
3197 operands[0] = validize_mem (operands[0]);
3198 operands[1] = force_reg (TFmode, operands[1]);
3202 /* Fixup PIC cases. */
3205 if (CONSTANT_P (operands[1])
3206 && pic_address_needs_scratch (operands[1]))
3207 operands[1] = legitimize_pic_address (operands[1], TFmode, 0);
3209 if (symbolic_operand (operands[1], TFmode))
3211 operands[1] = legitimize_pic_address (operands[1],
3213 (reload_in_progress ?
3223 ;; Be careful, fmovq and {st,ld}{x,q} do not exist when !arch64 so
3224 ;; we must split them all. :-(
3225 (define_insn "*movtf_insn_sp32"
3226 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,U,r")
3227 (match_operand:TF 1 "input_operand" "oe,GeUr,o,roG"))]
3231 && (register_operand (operands[0], TFmode)
3232 || register_operand (operands[1], TFmode)
3233 || fp_zero_operand (operands[1], TFmode))"
3235 [(set_attr "length" "4")])
3237 (define_insn "*movtf_insn_vis_sp32"
3238 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,U,r")
3239 (match_operand:TF 1 "input_operand" "Goe,GeUr,o,roG"))]
3243 && (register_operand (operands[0], TFmode)
3244 || register_operand (operands[1], TFmode)
3245 || fp_zero_operand (operands[1], TFmode))"
3247 [(set_attr "length" "4")])
3249 ;; Exactly the same as above, except that all `e' cases are deleted.
3250 ;; This is necessary to prevent reload from ever trying to use a `e' reg
3253 (define_insn "*movtf_no_e_insn_sp32"
3254 [(set (match_operand:TF 0 "nonimmediate_operand" "=o,U,o,r,o")
3255 (match_operand:TF 1 "input_operand" "G,o,U,roG,r"))]
3258 && (register_operand (operands[0], TFmode)
3259 || register_operand (operands[1], TFmode)
3260 || fp_zero_operand (operands[1], TFmode))"
3262 [(set_attr "length" "4")])
3264 ;; Now handle the float reg cases directly when arch64,
3265 ;; hard_quad, and proper reg number alignment are all true.
3266 (define_insn "*movtf_insn_hq_sp64"
3267 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,e,m,o,r")
3268 (match_operand:TF 1 "input_operand" "e,m,e,Gr,roG"))]
3273 && (register_operand (operands[0], TFmode)
3274 || register_operand (operands[1], TFmode)
3275 || fp_zero_operand (operands[1], TFmode))"
3282 [(set_attr "type" "fpmove,fpload,fpstore,*,*")
3283 (set_attr "length" "*,*,*,2,2")])
3285 (define_insn "*movtf_insn_hq_vis_sp64"
3286 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,e,m,eo,r,o")
3287 (match_operand:TF 1 "input_operand" "e,m,e,G,roG,r"))]
3292 && (register_operand (operands[0], TFmode)
3293 || register_operand (operands[1], TFmode)
3294 || fp_zero_operand (operands[1], TFmode))"
3302 [(set_attr "type" "fpmove,fpload,fpstore,*,*,*")
3303 (set_attr "length" "*,*,*,2,2,2")])
3305 ;; Now we allow the integer register cases even when
3306 ;; only arch64 is true.
3307 (define_insn "*movtf_insn_sp64"
3308 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,r")
3309 (match_operand:TF 1 "input_operand" "oe,Ger,orG"))]
3313 && ! TARGET_HARD_QUAD
3314 && (register_operand (operands[0], TFmode)
3315 || register_operand (operands[1], TFmode)
3316 || fp_zero_operand (operands[1], TFmode))"
3318 [(set_attr "length" "2")])
3320 (define_insn "*movtf_insn_vis_sp64"
3321 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,r")
3322 (match_operand:TF 1 "input_operand" "Goe,Ger,orG"))]
3326 && ! TARGET_HARD_QUAD
3327 && (register_operand (operands[0], TFmode)
3328 || register_operand (operands[1], TFmode)
3329 || fp_zero_operand (operands[1], TFmode))"
3331 [(set_attr "length" "2")])
3333 (define_insn "*movtf_no_e_insn_sp64"
3334 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o")
3335 (match_operand:TF 1 "input_operand" "orG,rG"))]
3338 && (register_operand (operands[0], TFmode)
3339 || register_operand (operands[1], TFmode)
3340 || fp_zero_operand (operands[1], TFmode))"
3342 [(set_attr "length" "2")])
3344 ;; Now all the splits to handle multi-insn TF mode moves.
3346 [(set (match_operand:TF 0 "register_operand" "")
3347 (match_operand:TF 1 "register_operand" ""))]
3351 && ! TARGET_HARD_QUAD)
3352 || ! fp_register_operand (operands[0], TFmode))"
3353 [(clobber (const_int 0))]
3355 rtx set_dest = operands[0];
3356 rtx set_src = operands[1];
3360 dest1 = gen_df_reg (set_dest, 0);
3361 dest2 = gen_df_reg (set_dest, 1);
3362 src1 = gen_df_reg (set_src, 0);
3363 src2 = gen_df_reg (set_src, 1);
3365 /* Now emit using the real source and destination we found, swapping
3366 the order if we detect overlap. */
3367 if (reg_overlap_mentioned_p (dest1, src2))
3369 emit_insn (gen_movdf (dest2, src2));
3370 emit_insn (gen_movdf (dest1, src1));
3374 emit_insn (gen_movdf (dest1, src1));
3375 emit_insn (gen_movdf (dest2, src2));
3381 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3382 (match_operand:TF 1 "fp_zero_operand" ""))]
3384 [(clobber (const_int 0))]
3386 rtx set_dest = operands[0];
3389 switch (GET_CODE (set_dest))
3392 dest1 = gen_df_reg (set_dest, 0);
3393 dest2 = gen_df_reg (set_dest, 1);
3396 dest1 = adjust_address (set_dest, DFmode, 0);
3397 dest2 = adjust_address (set_dest, DFmode, 8);
3403 emit_insn (gen_movdf (dest1, CONST0_RTX (DFmode)));
3404 emit_insn (gen_movdf (dest2, CONST0_RTX (DFmode)));
3409 [(set (match_operand:TF 0 "register_operand" "")
3410 (match_operand:TF 1 "memory_operand" ""))]
3412 && offsettable_memref_p (operands[1])
3414 || ! TARGET_HARD_QUAD
3415 || ! fp_register_operand (operands[0], TFmode)))"
3416 [(clobber (const_int 0))]
3418 rtx word0 = adjust_address (operands[1], DFmode, 0);
3419 rtx word1 = adjust_address (operands[1], DFmode, 8);
3420 rtx set_dest, dest1, dest2;
3422 set_dest = operands[0];
3424 dest1 = gen_df_reg (set_dest, 0);
3425 dest2 = gen_df_reg (set_dest, 1);
3427 /* Now output, ordering such that we don't clobber any registers
3428 mentioned in the address. */
3429 if (reg_overlap_mentioned_p (dest1, word1))
3432 emit_insn (gen_movdf (dest2, word1));
3433 emit_insn (gen_movdf (dest1, word0));
3437 emit_insn (gen_movdf (dest1, word0));
3438 emit_insn (gen_movdf (dest2, word1));
3444 [(set (match_operand:TF 0 "memory_operand" "")
3445 (match_operand:TF 1 "register_operand" ""))]
3447 && offsettable_memref_p (operands[0])
3449 || ! TARGET_HARD_QUAD
3450 || ! fp_register_operand (operands[1], TFmode)))"
3451 [(clobber (const_int 0))]
3453 rtx set_src = operands[1];
3455 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 0),
3456 gen_df_reg (set_src, 0)));
3457 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 8),
3458 gen_df_reg (set_src, 1)));
3462 ;; SPARC V9 conditional move instructions.
3464 ;; We can handle larger constants here for some flavors, but for now we keep
3465 ;; it simple and only allow those constants supported by all flavors.
3466 ;; Note that emit_conditional_move canonicalizes operands 2,3 so that operand
3467 ;; 3 contains the constant if one is present, but we handle either for
3468 ;; generality (sparc.c puts a constant in operand 2).
3470 (define_expand "movqicc"
3471 [(set (match_operand:QI 0 "register_operand" "")
3472 (if_then_else:QI (match_operand 1 "comparison_operator" "")
3473 (match_operand:QI 2 "arith10_operand" "")
3474 (match_operand:QI 3 "arith10_operand" "")))]
3477 enum rtx_code code = GET_CODE (operands[1]);
3479 if (GET_MODE (sparc_compare_op0) == DImode
3483 if (sparc_compare_op1 == const0_rtx
3484 && GET_CODE (sparc_compare_op0) == REG
3485 && GET_MODE (sparc_compare_op0) == DImode
3486 && v9_regcmp_p (code))
3488 operands[1] = gen_rtx_fmt_ee (code, DImode,
3489 sparc_compare_op0, sparc_compare_op1);
3493 rtx cc_reg = gen_compare_reg (code,
3494 sparc_compare_op0, sparc_compare_op1);
3495 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3499 (define_expand "movhicc"
3500 [(set (match_operand:HI 0 "register_operand" "")
3501 (if_then_else:HI (match_operand 1 "comparison_operator" "")
3502 (match_operand:HI 2 "arith10_operand" "")
3503 (match_operand:HI 3 "arith10_operand" "")))]
3506 enum rtx_code code = GET_CODE (operands[1]);
3508 if (GET_MODE (sparc_compare_op0) == DImode
3512 if (sparc_compare_op1 == const0_rtx
3513 && GET_CODE (sparc_compare_op0) == REG
3514 && GET_MODE (sparc_compare_op0) == DImode
3515 && v9_regcmp_p (code))
3517 operands[1] = gen_rtx_fmt_ee (code, DImode,
3518 sparc_compare_op0, sparc_compare_op1);
3522 rtx cc_reg = gen_compare_reg (code,
3523 sparc_compare_op0, sparc_compare_op1);
3524 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3528 (define_expand "movsicc"
3529 [(set (match_operand:SI 0 "register_operand" "")
3530 (if_then_else:SI (match_operand 1 "comparison_operator" "")
3531 (match_operand:SI 2 "arith10_operand" "")
3532 (match_operand:SI 3 "arith10_operand" "")))]
3535 enum rtx_code code = GET_CODE (operands[1]);
3536 enum machine_mode op0_mode = GET_MODE (sparc_compare_op0);
3538 if (sparc_compare_op1 == const0_rtx
3539 && GET_CODE (sparc_compare_op0) == REG
3540 && (TARGET_ARCH64 && op0_mode == DImode && v9_regcmp_p (code)))
3542 operands[1] = gen_rtx_fmt_ee (code, op0_mode,
3543 sparc_compare_op0, sparc_compare_op1);
3547 rtx cc_reg = gen_compare_reg (code,
3548 sparc_compare_op0, sparc_compare_op1);
3549 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg),
3550 cc_reg, const0_rtx);
3554 (define_expand "movdicc"
3555 [(set (match_operand:DI 0 "register_operand" "")
3556 (if_then_else:DI (match_operand 1 "comparison_operator" "")
3557 (match_operand:DI 2 "arith10_double_operand" "")
3558 (match_operand:DI 3 "arith10_double_operand" "")))]
3561 enum rtx_code code = GET_CODE (operands[1]);
3563 if (sparc_compare_op1 == const0_rtx
3564 && GET_CODE (sparc_compare_op0) == REG
3565 && GET_MODE (sparc_compare_op0) == DImode
3566 && v9_regcmp_p (code))
3568 operands[1] = gen_rtx_fmt_ee (code, DImode,
3569 sparc_compare_op0, sparc_compare_op1);
3573 rtx cc_reg = gen_compare_reg (code,
3574 sparc_compare_op0, sparc_compare_op1);
3575 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg),
3576 cc_reg, const0_rtx);
3580 (define_expand "movsfcc"
3581 [(set (match_operand:SF 0 "register_operand" "")
3582 (if_then_else:SF (match_operand 1 "comparison_operator" "")
3583 (match_operand:SF 2 "register_operand" "")
3584 (match_operand:SF 3 "register_operand" "")))]
3585 "TARGET_V9 && TARGET_FPU"
3587 enum rtx_code code = GET_CODE (operands[1]);
3589 if (GET_MODE (sparc_compare_op0) == DImode
3593 if (sparc_compare_op1 == const0_rtx
3594 && GET_CODE (sparc_compare_op0) == REG
3595 && GET_MODE (sparc_compare_op0) == DImode
3596 && v9_regcmp_p (code))
3598 operands[1] = gen_rtx_fmt_ee (code, DImode,
3599 sparc_compare_op0, sparc_compare_op1);
3603 rtx cc_reg = gen_compare_reg (code,
3604 sparc_compare_op0, sparc_compare_op1);
3605 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3609 (define_expand "movdfcc"
3610 [(set (match_operand:DF 0 "register_operand" "")
3611 (if_then_else:DF (match_operand 1 "comparison_operator" "")
3612 (match_operand:DF 2 "register_operand" "")
3613 (match_operand:DF 3 "register_operand" "")))]
3614 "TARGET_V9 && TARGET_FPU"
3616 enum rtx_code code = GET_CODE (operands[1]);
3618 if (GET_MODE (sparc_compare_op0) == DImode
3622 if (sparc_compare_op1 == const0_rtx
3623 && GET_CODE (sparc_compare_op0) == REG
3624 && GET_MODE (sparc_compare_op0) == DImode
3625 && v9_regcmp_p (code))
3627 operands[1] = gen_rtx_fmt_ee (code, DImode,
3628 sparc_compare_op0, sparc_compare_op1);
3632 rtx cc_reg = gen_compare_reg (code,
3633 sparc_compare_op0, sparc_compare_op1);
3634 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3638 (define_expand "movtfcc"
3639 [(set (match_operand:TF 0 "register_operand" "")
3640 (if_then_else:TF (match_operand 1 "comparison_operator" "")
3641 (match_operand:TF 2 "register_operand" "")
3642 (match_operand:TF 3 "register_operand" "")))]
3643 "TARGET_V9 && TARGET_FPU"
3645 enum rtx_code code = GET_CODE (operands[1]);
3647 if (GET_MODE (sparc_compare_op0) == DImode
3651 if (sparc_compare_op1 == const0_rtx
3652 && GET_CODE (sparc_compare_op0) == REG
3653 && GET_MODE (sparc_compare_op0) == DImode
3654 && v9_regcmp_p (code))
3656 operands[1] = gen_rtx_fmt_ee (code, DImode,
3657 sparc_compare_op0, sparc_compare_op1);
3661 rtx cc_reg = gen_compare_reg (code,
3662 sparc_compare_op0, sparc_compare_op1);
3663 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3667 ;; Conditional move define_insns.
3669 (define_insn "*movqi_cc_sp64"
3670 [(set (match_operand:QI 0 "register_operand" "=r,r")
3671 (if_then_else:QI (match_operator 1 "comparison_operator"
3672 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3674 (match_operand:QI 3 "arith11_operand" "rL,0")
3675 (match_operand:QI 4 "arith11_operand" "0,rL")))]
3679 mov%c1\t%x2, %4, %0"
3680 [(set_attr "type" "cmove")])
3682 (define_insn "*movhi_cc_sp64"
3683 [(set (match_operand:HI 0 "register_operand" "=r,r")
3684 (if_then_else:HI (match_operator 1 "comparison_operator"
3685 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3687 (match_operand:HI 3 "arith11_operand" "rL,0")
3688 (match_operand:HI 4 "arith11_operand" "0,rL")))]
3692 mov%c1\t%x2, %4, %0"
3693 [(set_attr "type" "cmove")])
3695 (define_insn "*movsi_cc_sp64"
3696 [(set (match_operand:SI 0 "register_operand" "=r,r")
3697 (if_then_else:SI (match_operator 1 "comparison_operator"
3698 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3700 (match_operand:SI 3 "arith11_operand" "rL,0")
3701 (match_operand:SI 4 "arith11_operand" "0,rL")))]
3705 mov%c1\t%x2, %4, %0"
3706 [(set_attr "type" "cmove")])
3708 ;; ??? The constraints of operands 3,4 need work.
3709 (define_insn "*movdi_cc_sp64"
3710 [(set (match_operand:DI 0 "register_operand" "=r,r")
3711 (if_then_else:DI (match_operator 1 "comparison_operator"
3712 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3714 (match_operand:DI 3 "arith11_double_operand" "rLH,0")
3715 (match_operand:DI 4 "arith11_double_operand" "0,rLH")))]
3719 mov%c1\t%x2, %4, %0"
3720 [(set_attr "type" "cmove")])
3722 (define_insn "*movdi_cc_sp64_trunc"
3723 [(set (match_operand:SI 0 "register_operand" "=r,r")
3724 (if_then_else:SI (match_operator 1 "comparison_operator"
3725 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3727 (match_operand:SI 3 "arith11_double_operand" "rLH,0")
3728 (match_operand:SI 4 "arith11_double_operand" "0,rLH")))]
3732 mov%c1\t%x2, %4, %0"
3733 [(set_attr "type" "cmove")])
3735 (define_insn "*movsf_cc_sp64"
3736 [(set (match_operand:SF 0 "register_operand" "=f,f")
3737 (if_then_else:SF (match_operator 1 "comparison_operator"
3738 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3740 (match_operand:SF 3 "register_operand" "f,0")
3741 (match_operand:SF 4 "register_operand" "0,f")))]
3742 "TARGET_V9 && TARGET_FPU"
3744 fmovs%C1\t%x2, %3, %0
3745 fmovs%c1\t%x2, %4, %0"
3746 [(set_attr "type" "fpcmove")])
3748 (define_insn "movdf_cc_sp64"
3749 [(set (match_operand:DF 0 "register_operand" "=e,e")
3750 (if_then_else:DF (match_operator 1 "comparison_operator"
3751 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3753 (match_operand:DF 3 "register_operand" "e,0")
3754 (match_operand:DF 4 "register_operand" "0,e")))]
3755 "TARGET_V9 && TARGET_FPU"
3757 fmovd%C1\t%x2, %3, %0
3758 fmovd%c1\t%x2, %4, %0"
3759 [(set_attr "type" "fpcmove")
3760 (set_attr "fptype" "double")])
3762 (define_insn "*movtf_cc_hq_sp64"
3763 [(set (match_operand:TF 0 "register_operand" "=e,e")
3764 (if_then_else:TF (match_operator 1 "comparison_operator"
3765 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3767 (match_operand:TF 3 "register_operand" "e,0")
3768 (match_operand:TF 4 "register_operand" "0,e")))]
3769 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
3771 fmovq%C1\t%x2, %3, %0
3772 fmovq%c1\t%x2, %4, %0"
3773 [(set_attr "type" "fpcmove")])
3775 (define_insn_and_split "*movtf_cc_sp64"
3776 [(set (match_operand:TF 0 "register_operand" "=e,e")
3777 (if_then_else:TF (match_operator 1 "comparison_operator"
3778 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3780 (match_operand:TF 3 "register_operand" "e,0")
3781 (match_operand:TF 4 "register_operand" "0,e")))]
3782 "TARGET_V9 && TARGET_FPU && !TARGET_HARD_QUAD"
3784 "&& reload_completed"
3785 [(clobber (const_int 0))]
3787 rtx set_dest = operands[0];
3788 rtx set_srca = operands[3];
3789 rtx set_srcb = operands[4];
3790 int third = rtx_equal_p (set_dest, set_srca);
3792 rtx srca1, srca2, srcb1, srcb2;
3794 dest1 = gen_df_reg (set_dest, 0);
3795 dest2 = gen_df_reg (set_dest, 1);
3796 srca1 = gen_df_reg (set_srca, 0);
3797 srca2 = gen_df_reg (set_srca, 1);
3798 srcb1 = gen_df_reg (set_srcb, 0);
3799 srcb2 = gen_df_reg (set_srcb, 1);
3801 /* Now emit using the real source and destination we found, swapping
3802 the order if we detect overlap. */
3803 if ((third && reg_overlap_mentioned_p (dest1, srcb2))
3804 || (!third && reg_overlap_mentioned_p (dest1, srca2)))
3806 emit_insn (gen_movdf_cc_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
3807 emit_insn (gen_movdf_cc_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
3811 emit_insn (gen_movdf_cc_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
3812 emit_insn (gen_movdf_cc_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
3816 [(set_attr "length" "2")])
3818 (define_insn "*movqi_cc_reg_sp64"
3819 [(set (match_operand:QI 0 "register_operand" "=r,r")
3820 (if_then_else:QI (match_operator 1 "v9_regcmp_op"
3821 [(match_operand:DI 2 "register_operand" "r,r")
3823 (match_operand:QI 3 "arith10_operand" "rM,0")
3824 (match_operand:QI 4 "arith10_operand" "0,rM")))]
3827 movr%D1\t%2, %r3, %0
3828 movr%d1\t%2, %r4, %0"
3829 [(set_attr "type" "cmove")])
3831 (define_insn "*movhi_cc_reg_sp64"
3832 [(set (match_operand:HI 0 "register_operand" "=r,r")
3833 (if_then_else:HI (match_operator 1 "v9_regcmp_op"
3834 [(match_operand:DI 2 "register_operand" "r,r")
3836 (match_operand:HI 3 "arith10_operand" "rM,0")
3837 (match_operand:HI 4 "arith10_operand" "0,rM")))]
3840 movr%D1\t%2, %r3, %0
3841 movr%d1\t%2, %r4, %0"
3842 [(set_attr "type" "cmove")])
3844 (define_insn "*movsi_cc_reg_sp64"
3845 [(set (match_operand:SI 0 "register_operand" "=r,r")
3846 (if_then_else:SI (match_operator 1 "v9_regcmp_op"
3847 [(match_operand:DI 2 "register_operand" "r,r")
3849 (match_operand:SI 3 "arith10_operand" "rM,0")
3850 (match_operand:SI 4 "arith10_operand" "0,rM")))]
3853 movr%D1\t%2, %r3, %0
3854 movr%d1\t%2, %r4, %0"
3855 [(set_attr "type" "cmove")])
3857 ;; ??? The constraints of operands 3,4 need work.
3858 (define_insn "*movdi_cc_reg_sp64"
3859 [(set (match_operand:DI 0 "register_operand" "=r,r")
3860 (if_then_else:DI (match_operator 1 "v9_regcmp_op"
3861 [(match_operand:DI 2 "register_operand" "r,r")
3863 (match_operand:DI 3 "arith10_double_operand" "rMH,0")
3864 (match_operand:DI 4 "arith10_double_operand" "0,rMH")))]
3867 movr%D1\t%2, %r3, %0
3868 movr%d1\t%2, %r4, %0"
3869 [(set_attr "type" "cmove")])
3871 (define_insn "*movdi_cc_reg_sp64_trunc"
3872 [(set (match_operand:SI 0 "register_operand" "=r,r")
3873 (if_then_else:SI (match_operator 1 "v9_regcmp_op"
3874 [(match_operand:DI 2 "register_operand" "r,r")
3876 (match_operand:SI 3 "arith10_double_operand" "rMH,0")
3877 (match_operand:SI 4 "arith10_double_operand" "0,rMH")))]
3880 movr%D1\t%2, %r3, %0
3881 movr%d1\t%2, %r4, %0"
3882 [(set_attr "type" "cmove")])
3884 (define_insn "*movsf_cc_reg_sp64"
3885 [(set (match_operand:SF 0 "register_operand" "=f,f")
3886 (if_then_else:SF (match_operator 1 "v9_regcmp_op"
3887 [(match_operand:DI 2 "register_operand" "r,r")
3889 (match_operand:SF 3 "register_operand" "f,0")
3890 (match_operand:SF 4 "register_operand" "0,f")))]
3891 "TARGET_ARCH64 && TARGET_FPU"
3893 fmovrs%D1\t%2, %3, %0
3894 fmovrs%d1\t%2, %4, %0"
3895 [(set_attr "type" "fpcrmove")])
3897 (define_insn "movdf_cc_reg_sp64"
3898 [(set (match_operand:DF 0 "register_operand" "=e,e")
3899 (if_then_else:DF (match_operator 1 "v9_regcmp_op"
3900 [(match_operand:DI 2 "register_operand" "r,r")
3902 (match_operand:DF 3 "register_operand" "e,0")
3903 (match_operand:DF 4 "register_operand" "0,e")))]
3904 "TARGET_ARCH64 && TARGET_FPU"
3906 fmovrd%D1\t%2, %3, %0
3907 fmovrd%d1\t%2, %4, %0"
3908 [(set_attr "type" "fpcrmove")
3909 (set_attr "fptype" "double")])
3911 (define_insn "*movtf_cc_reg_hq_sp64"
3912 [(set (match_operand:TF 0 "register_operand" "=e,e")
3913 (if_then_else:TF (match_operator 1 "v9_regcmp_op"
3914 [(match_operand:DI 2 "register_operand" "r,r")
3916 (match_operand:TF 3 "register_operand" "e,0")
3917 (match_operand:TF 4 "register_operand" "0,e")))]
3918 "TARGET_ARCH64 && TARGET_FPU && TARGET_HARD_QUAD"
3920 fmovrq%D1\t%2, %3, %0
3921 fmovrq%d1\t%2, %4, %0"
3922 [(set_attr "type" "fpcrmove")])
3924 (define_insn_and_split "*movtf_cc_reg_sp64"
3925 [(set (match_operand:TF 0 "register_operand" "=e,e")
3926 (if_then_else:TF (match_operator 1 "v9_regcmp_op"
3927 [(match_operand:DI 2 "register_operand" "r,r")
3929 (match_operand:TF 3 "register_operand" "e,0")
3930 (match_operand:TF 4 "register_operand" "0,e")))]
3931 "TARGET_ARCH64 && TARGET_FPU && ! TARGET_HARD_QUAD"
3933 "&& reload_completed"
3934 [(clobber (const_int 0))]
3936 rtx set_dest = operands[0];
3937 rtx set_srca = operands[3];
3938 rtx set_srcb = operands[4];
3939 int third = rtx_equal_p (set_dest, set_srca);
3941 rtx srca1, srca2, srcb1, srcb2;
3943 dest1 = gen_df_reg (set_dest, 0);
3944 dest2 = gen_df_reg (set_dest, 1);
3945 srca1 = gen_df_reg (set_srca, 0);
3946 srca2 = gen_df_reg (set_srca, 1);
3947 srcb1 = gen_df_reg (set_srcb, 0);
3948 srcb2 = gen_df_reg (set_srcb, 1);
3950 /* Now emit using the real source and destination we found, swapping
3951 the order if we detect overlap. */
3952 if ((third && reg_overlap_mentioned_p (dest1, srcb2))
3953 || (!third && reg_overlap_mentioned_p (dest1, srca2)))
3955 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
3956 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
3960 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
3961 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
3965 [(set_attr "length" "2")])
3968 ;;- zero extension instructions
3970 ;; These patterns originally accepted general_operands, however, slightly
3971 ;; better code is generated by only accepting register_operands, and then
3972 ;; letting combine generate the ldu[hb] insns.
3974 (define_expand "zero_extendhisi2"
3975 [(set (match_operand:SI 0 "register_operand" "")
3976 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
3979 rtx temp = gen_reg_rtx (SImode);
3980 rtx shift_16 = GEN_INT (16);
3981 int op1_subbyte = 0;
3983 if (GET_CODE (operand1) == SUBREG)
3985 op1_subbyte = SUBREG_BYTE (operand1);
3986 op1_subbyte /= GET_MODE_SIZE (SImode);
3987 op1_subbyte *= GET_MODE_SIZE (SImode);
3988 operand1 = XEXP (operand1, 0);
3991 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3993 emit_insn (gen_lshrsi3 (operand0, temp, shift_16));
3997 (define_insn "*zero_extendhisi2_insn"
3998 [(set (match_operand:SI 0 "register_operand" "=r")
3999 (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
4002 [(set_attr "type" "load")
4003 (set_attr "us3load_type" "3cycle")])
4005 (define_expand "zero_extendqihi2"
4006 [(set (match_operand:HI 0 "register_operand" "")
4007 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
4011 (define_insn "*zero_extendqihi2_insn"
4012 [(set (match_operand:HI 0 "register_operand" "=r,r")
4013 (zero_extend:HI (match_operand:QI 1 "input_operand" "r,m")))]
4014 "GET_CODE (operands[1]) != CONST_INT"
4018 [(set_attr "type" "*,load")
4019 (set_attr "us3load_type" "*,3cycle")])
4021 (define_expand "zero_extendqisi2"
4022 [(set (match_operand:SI 0 "register_operand" "")
4023 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
4027 (define_insn "*zero_extendqisi2_insn"
4028 [(set (match_operand:SI 0 "register_operand" "=r,r")
4029 (zero_extend:SI (match_operand:QI 1 "input_operand" "r,m")))]
4030 "GET_CODE (operands[1]) != CONST_INT"
4034 [(set_attr "type" "*,load")
4035 (set_attr "us3load_type" "*,3cycle")])
4037 (define_expand "zero_extendqidi2"
4038 [(set (match_operand:DI 0 "register_operand" "")
4039 (zero_extend:DI (match_operand:QI 1 "register_operand" "")))]
4043 (define_insn "*zero_extendqidi2_insn"
4044 [(set (match_operand:DI 0 "register_operand" "=r,r")
4045 (zero_extend:DI (match_operand:QI 1 "input_operand" "r,m")))]
4046 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
4050 [(set_attr "type" "*,load")
4051 (set_attr "us3load_type" "*,3cycle")])
4053 (define_expand "zero_extendhidi2"
4054 [(set (match_operand:DI 0 "register_operand" "")
4055 (zero_extend:DI (match_operand:HI 1 "register_operand" "")))]
4058 rtx temp = gen_reg_rtx (DImode);
4059 rtx shift_48 = GEN_INT (48);
4060 int op1_subbyte = 0;
4062 if (GET_CODE (operand1) == SUBREG)
4064 op1_subbyte = SUBREG_BYTE (operand1);
4065 op1_subbyte /= GET_MODE_SIZE (DImode);
4066 op1_subbyte *= GET_MODE_SIZE (DImode);
4067 operand1 = XEXP (operand1, 0);
4070 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
4072 emit_insn (gen_lshrdi3 (operand0, temp, shift_48));
4076 (define_insn "*zero_extendhidi2_insn"
4077 [(set (match_operand:DI 0 "register_operand" "=r")
4078 (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
4081 [(set_attr "type" "load")
4082 (set_attr "us3load_type" "3cycle")])
4085 ;; ??? Write truncdisi pattern using sra?
4087 (define_expand "zero_extendsidi2"
4088 [(set (match_operand:DI 0 "register_operand" "")
4089 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
4093 (define_insn "*zero_extendsidi2_insn_sp64"
4094 [(set (match_operand:DI 0 "register_operand" "=r,r")
4095 (zero_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
4096 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
4100 [(set_attr "type" "shift,load")])
4102 (define_insn_and_split "*zero_extendsidi2_insn_sp32"
4103 [(set (match_operand:DI 0 "register_operand" "=r")
4104 (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
4107 "&& reload_completed"
4108 [(set (match_dup 2) (match_dup 3))
4109 (set (match_dup 4) (match_dup 5))]
4113 dest1 = gen_highpart (SImode, operands[0]);
4114 dest2 = gen_lowpart (SImode, operands[0]);
4116 /* Swap the order in case of overlap. */
4117 if (REGNO (dest1) == REGNO (operands[1]))
4119 operands[2] = dest2;
4120 operands[3] = operands[1];
4121 operands[4] = dest1;
4122 operands[5] = const0_rtx;
4126 operands[2] = dest1;
4127 operands[3] = const0_rtx;
4128 operands[4] = dest2;
4129 operands[5] = operands[1];
4132 [(set_attr "length" "2")])
4134 ;; Simplify comparisons of extended values.
4136 (define_insn "*cmp_zero_extendqisi2"
4138 (compare:CC (zero_extend:SI (match_operand:QI 0 "register_operand" "r"))
4141 "andcc\t%0, 0xff, %%g0"
4142 [(set_attr "type" "compare")])
4144 (define_insn "*cmp_zero_qi"
4146 (compare:CC (match_operand:QI 0 "register_operand" "r")
4149 "andcc\t%0, 0xff, %%g0"
4150 [(set_attr "type" "compare")])
4152 (define_insn "*cmp_zero_extendqisi2_set"
4154 (compare:CC (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
4156 (set (match_operand:SI 0 "register_operand" "=r")
4157 (zero_extend:SI (match_dup 1)))]
4159 "andcc\t%1, 0xff, %0"
4160 [(set_attr "type" "compare")])
4162 (define_insn "*cmp_zero_extendqisi2_andcc_set"
4164 (compare:CC (and:SI (match_operand:SI 1 "register_operand" "r")
4167 (set (match_operand:SI 0 "register_operand" "=r")
4168 (zero_extend:SI (subreg:QI (match_dup 1) 0)))]
4170 "andcc\t%1, 0xff, %0"
4171 [(set_attr "type" "compare")])
4173 (define_insn "*cmp_zero_extendqidi2"
4175 (compare:CCX (zero_extend:DI (match_operand:QI 0 "register_operand" "r"))
4178 "andcc\t%0, 0xff, %%g0"
4179 [(set_attr "type" "compare")])
4181 (define_insn "*cmp_zero_qi_sp64"
4183 (compare:CCX (match_operand:QI 0 "register_operand" "r")
4186 "andcc\t%0, 0xff, %%g0"
4187 [(set_attr "type" "compare")])
4189 (define_insn "*cmp_zero_extendqidi2_set"
4191 (compare:CCX (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
4193 (set (match_operand:DI 0 "register_operand" "=r")
4194 (zero_extend:DI (match_dup 1)))]
4196 "andcc\t%1, 0xff, %0"
4197 [(set_attr "type" "compare")])
4199 (define_insn "*cmp_zero_extendqidi2_andcc_set"
4201 (compare:CCX (and:DI (match_operand:DI 1 "register_operand" "r")
4204 (set (match_operand:DI 0 "register_operand" "=r")
4205 (zero_extend:DI (subreg:QI (match_dup 1) 0)))]
4207 "andcc\t%1, 0xff, %0"
4208 [(set_attr "type" "compare")])
4210 ;; Similarly, handle {SI,DI}->QI mode truncation followed by a compare.
4212 (define_insn "*cmp_siqi_trunc"
4214 (compare:CC (subreg:QI (match_operand:SI 0 "register_operand" "r") 3)
4217 "andcc\t%0, 0xff, %%g0"
4218 [(set_attr "type" "compare")])
4220 (define_insn "*cmp_siqi_trunc_set"
4222 (compare:CC (subreg:QI (match_operand:SI 1 "register_operand" "r") 3)
4224 (set (match_operand:QI 0 "register_operand" "=r")
4225 (subreg:QI (match_dup 1) 3))]
4227 "andcc\t%1, 0xff, %0"
4228 [(set_attr "type" "compare")])
4230 (define_insn "*cmp_diqi_trunc"
4232 (compare:CC (subreg:QI (match_operand:DI 0 "register_operand" "r") 7)
4235 "andcc\t%0, 0xff, %%g0"
4236 [(set_attr "type" "compare")])
4238 (define_insn "*cmp_diqi_trunc_set"
4240 (compare:CC (subreg:QI (match_operand:DI 1 "register_operand" "r") 7)
4242 (set (match_operand:QI 0 "register_operand" "=r")
4243 (subreg:QI (match_dup 1) 7))]
4245 "andcc\t%1, 0xff, %0"
4246 [(set_attr "type" "compare")])
4248 ;;- sign extension instructions
4250 ;; These patterns originally accepted general_operands, however, slightly
4251 ;; better code is generated by only accepting register_operands, and then
4252 ;; letting combine generate the lds[hb] insns.
4254 (define_expand "extendhisi2"
4255 [(set (match_operand:SI 0 "register_operand" "")
4256 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
4259 rtx temp = gen_reg_rtx (SImode);
4260 rtx shift_16 = GEN_INT (16);
4261 int op1_subbyte = 0;
4263 if (GET_CODE (operand1) == SUBREG)
4265 op1_subbyte = SUBREG_BYTE (operand1);
4266 op1_subbyte /= GET_MODE_SIZE (SImode);
4267 op1_subbyte *= GET_MODE_SIZE (SImode);
4268 operand1 = XEXP (operand1, 0);
4271 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4273 emit_insn (gen_ashrsi3 (operand0, temp, shift_16));
4277 (define_insn "*sign_extendhisi2_insn"
4278 [(set (match_operand:SI 0 "register_operand" "=r")
4279 (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
4282 [(set_attr "type" "sload")
4283 (set_attr "us3load_type" "3cycle")])
4285 (define_expand "extendqihi2"
4286 [(set (match_operand:HI 0 "register_operand" "")
4287 (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
4290 rtx temp = gen_reg_rtx (SImode);
4291 rtx shift_24 = GEN_INT (24);
4292 int op1_subbyte = 0;
4293 int op0_subbyte = 0;
4295 if (GET_CODE (operand1) == SUBREG)
4297 op1_subbyte = SUBREG_BYTE (operand1);
4298 op1_subbyte /= GET_MODE_SIZE (SImode);
4299 op1_subbyte *= GET_MODE_SIZE (SImode);
4300 operand1 = XEXP (operand1, 0);
4302 if (GET_CODE (operand0) == SUBREG)
4304 op0_subbyte = SUBREG_BYTE (operand0);
4305 op0_subbyte /= GET_MODE_SIZE (SImode);
4306 op0_subbyte *= GET_MODE_SIZE (SImode);
4307 operand0 = XEXP (operand0, 0);
4309 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4311 if (GET_MODE (operand0) != SImode)
4312 operand0 = gen_rtx_SUBREG (SImode, operand0, op0_subbyte);
4313 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
4317 (define_insn "*sign_extendqihi2_insn"
4318 [(set (match_operand:HI 0 "register_operand" "=r")
4319 (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
4322 [(set_attr "type" "sload")
4323 (set_attr "us3load_type" "3cycle")])
4325 (define_expand "extendqisi2"
4326 [(set (match_operand:SI 0 "register_operand" "")
4327 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
4330 rtx temp = gen_reg_rtx (SImode);
4331 rtx shift_24 = GEN_INT (24);
4332 int op1_subbyte = 0;
4334 if (GET_CODE (operand1) == SUBREG)
4336 op1_subbyte = SUBREG_BYTE (operand1);
4337 op1_subbyte /= GET_MODE_SIZE (SImode);
4338 op1_subbyte *= GET_MODE_SIZE (SImode);
4339 operand1 = XEXP (operand1, 0);
4342 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4344 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
4348 (define_insn "*sign_extendqisi2_insn"
4349 [(set (match_operand:SI 0 "register_operand" "=r")
4350 (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
4353 [(set_attr "type" "sload")
4354 (set_attr "us3load_type" "3cycle")])
4356 (define_expand "extendqidi2"
4357 [(set (match_operand:DI 0 "register_operand" "")
4358 (sign_extend:DI (match_operand:QI 1 "register_operand" "")))]
4361 rtx temp = gen_reg_rtx (DImode);
4362 rtx shift_56 = GEN_INT (56);
4363 int op1_subbyte = 0;
4365 if (GET_CODE (operand1) == SUBREG)
4367 op1_subbyte = SUBREG_BYTE (operand1);
4368 op1_subbyte /= GET_MODE_SIZE (DImode);
4369 op1_subbyte *= GET_MODE_SIZE (DImode);
4370 operand1 = XEXP (operand1, 0);
4373 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
4375 emit_insn (gen_ashrdi3 (operand0, temp, shift_56));
4379 (define_insn "*sign_extendqidi2_insn"
4380 [(set (match_operand:DI 0 "register_operand" "=r")
4381 (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
4384 [(set_attr "type" "sload")
4385 (set_attr "us3load_type" "3cycle")])
4387 (define_expand "extendhidi2"
4388 [(set (match_operand:DI 0 "register_operand" "")
4389 (sign_extend:DI (match_operand:HI 1 "register_operand" "")))]
4392 rtx temp = gen_reg_rtx (DImode);
4393 rtx shift_48 = GEN_INT (48);
4394 int op1_subbyte = 0;
4396 if (GET_CODE (operand1) == SUBREG)
4398 op1_subbyte = SUBREG_BYTE (operand1);
4399 op1_subbyte /= GET_MODE_SIZE (DImode);
4400 op1_subbyte *= GET_MODE_SIZE (DImode);
4401 operand1 = XEXP (operand1, 0);
4404 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
4406 emit_insn (gen_ashrdi3 (operand0, temp, shift_48));
4410 (define_insn "*sign_extendhidi2_insn"
4411 [(set (match_operand:DI 0 "register_operand" "=r")
4412 (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
4415 [(set_attr "type" "sload")
4416 (set_attr "us3load_type" "3cycle")])
4418 (define_expand "extendsidi2"
4419 [(set (match_operand:DI 0 "register_operand" "")
4420 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
4424 (define_insn "*sign_extendsidi2_insn"
4425 [(set (match_operand:DI 0 "register_operand" "=r,r")
4426 (sign_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
4431 [(set_attr "type" "shift,sload")
4432 (set_attr "us3load_type" "*,3cycle")])
4434 ;; Special pattern for optimizing bit-field compares. This is needed
4435 ;; because combine uses this as a canonical form.
4437 (define_insn "*cmp_zero_extract"
4440 (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
4441 (match_operand:SI 1 "small_int_or_double" "n")
4442 (match_operand:SI 2 "small_int_or_double" "n"))
4444 "(GET_CODE (operands[2]) == CONST_INT
4445 && INTVAL (operands[2]) > 19)
4446 || (GET_CODE (operands[2]) == CONST_DOUBLE
4447 && CONST_DOUBLE_LOW (operands[2]) > 19)"
4449 int len = (GET_CODE (operands[1]) == CONST_INT
4450 ? INTVAL (operands[1])
4451 : CONST_DOUBLE_LOW (operands[1]));
4453 (GET_CODE (operands[2]) == CONST_INT
4454 ? INTVAL (operands[2])
4455 : CONST_DOUBLE_LOW (operands[2])) - len;
4456 HOST_WIDE_INT mask = ((1 << len) - 1) << pos;
4458 operands[1] = GEN_INT (mask);
4459 return "andcc\t%0, %1, %%g0";
4461 [(set_attr "type" "compare")])
4463 (define_insn "*cmp_zero_extract_sp64"
4466 (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
4467 (match_operand:SI 1 "small_int_or_double" "n")
4468 (match_operand:SI 2 "small_int_or_double" "n"))
4471 && ((GET_CODE (operands[2]) == CONST_INT
4472 && INTVAL (operands[2]) > 51)
4473 || (GET_CODE (operands[2]) == CONST_DOUBLE
4474 && CONST_DOUBLE_LOW (operands[2]) > 51))"
4476 int len = (GET_CODE (operands[1]) == CONST_INT
4477 ? INTVAL (operands[1])
4478 : CONST_DOUBLE_LOW (operands[1]));
4480 (GET_CODE (operands[2]) == CONST_INT
4481 ? INTVAL (operands[2])
4482 : CONST_DOUBLE_LOW (operands[2])) - len;
4483 HOST_WIDE_INT mask = (((unsigned HOST_WIDE_INT) 1 << len) - 1) << pos;
4485 operands[1] = GEN_INT (mask);
4486 return "andcc\t%0, %1, %%g0";
4488 [(set_attr "type" "compare")])
4490 ;; Conversions between float, double and long double.
4492 (define_insn "extendsfdf2"
4493 [(set (match_operand:DF 0 "register_operand" "=e")
4495 (match_operand:SF 1 "register_operand" "f")))]
4498 [(set_attr "type" "fp")
4499 (set_attr "fptype" "double")])
4501 (define_expand "extendsftf2"
4502 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4504 (match_operand:SF 1 "register_operand" "")))]
4505 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4506 "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
4508 (define_insn "*extendsftf2_hq"
4509 [(set (match_operand:TF 0 "register_operand" "=e")
4511 (match_operand:SF 1 "register_operand" "f")))]
4512 "TARGET_FPU && TARGET_HARD_QUAD"
4514 [(set_attr "type" "fp")])
4516 (define_expand "extenddftf2"
4517 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4519 (match_operand:DF 1 "register_operand" "")))]
4520 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4521 "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
4523 (define_insn "*extenddftf2_hq"
4524 [(set (match_operand:TF 0 "register_operand" "=e")
4526 (match_operand:DF 1 "register_operand" "e")))]
4527 "TARGET_FPU && TARGET_HARD_QUAD"
4529 [(set_attr "type" "fp")])
4531 (define_insn "truncdfsf2"
4532 [(set (match_operand:SF 0 "register_operand" "=f")
4534 (match_operand:DF 1 "register_operand" "e")))]
4537 [(set_attr "type" "fp")
4538 (set_attr "fptype" "double")])
4540 (define_expand "trunctfsf2"
4541 [(set (match_operand:SF 0 "register_operand" "")
4543 (match_operand:TF 1 "general_operand" "")))]
4544 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4545 "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
4547 (define_insn "*trunctfsf2_hq"
4548 [(set (match_operand:SF 0 "register_operand" "=f")
4550 (match_operand:TF 1 "register_operand" "e")))]
4551 "TARGET_FPU && TARGET_HARD_QUAD"
4553 [(set_attr "type" "fp")])
4555 (define_expand "trunctfdf2"
4556 [(set (match_operand:DF 0 "register_operand" "")
4558 (match_operand:TF 1 "general_operand" "")))]
4559 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4560 "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
4562 (define_insn "*trunctfdf2_hq"
4563 [(set (match_operand:DF 0 "register_operand" "=e")
4565 (match_operand:TF 1 "register_operand" "e")))]
4566 "TARGET_FPU && TARGET_HARD_QUAD"
4568 [(set_attr "type" "fp")])
4570 ;; Conversion between fixed point and floating point.
4572 (define_insn "floatsisf2"
4573 [(set (match_operand:SF 0 "register_operand" "=f")
4574 (float:SF (match_operand:SI 1 "register_operand" "f")))]
4577 [(set_attr "type" "fp")
4578 (set_attr "fptype" "double")])
4580 (define_insn "floatsidf2"
4581 [(set (match_operand:DF 0 "register_operand" "=e")
4582 (float:DF (match_operand:SI 1 "register_operand" "f")))]
4585 [(set_attr "type" "fp")
4586 (set_attr "fptype" "double")])
4588 (define_expand "floatsitf2"
4589 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4590 (float:TF (match_operand:SI 1 "register_operand" "")))]
4591 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4592 "emit_tfmode_cvt (FLOAT, operands); DONE;")
4594 (define_insn "*floatsitf2_hq"
4595 [(set (match_operand:TF 0 "register_operand" "=e")
4596 (float:TF (match_operand:SI 1 "register_operand" "f")))]
4597 "TARGET_FPU && TARGET_HARD_QUAD"
4599 [(set_attr "type" "fp")])
4601 (define_expand "floatunssitf2"
4602 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4603 (unsigned_float:TF (match_operand:SI 1 "register_operand" "")))]
4604 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4605 "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
4607 ;; Now the same for 64 bit sources.
4609 (define_insn "floatdisf2"
4610 [(set (match_operand:SF 0 "register_operand" "=f")
4611 (float:SF (match_operand:DI 1 "register_operand" "e")))]
4612 "TARGET_V9 && TARGET_FPU"
4614 [(set_attr "type" "fp")
4615 (set_attr "fptype" "double")])
4617 (define_expand "floatunsdisf2"
4618 [(use (match_operand:SF 0 "register_operand" ""))
4619 (use (match_operand:DI 1 "register_operand" ""))]
4620 "TARGET_ARCH64 && TARGET_FPU"
4621 "sparc_emit_floatunsdi (operands); DONE;")
4623 (define_insn "floatdidf2"
4624 [(set (match_operand:DF 0 "register_operand" "=e")
4625 (float:DF (match_operand:DI 1 "register_operand" "e")))]
4626 "TARGET_V9 && TARGET_FPU"
4628 [(set_attr "type" "fp")
4629 (set_attr "fptype" "double")])
4631 (define_expand "floatunsdidf2"
4632 [(use (match_operand:DF 0 "register_operand" ""))
4633 (use (match_operand:DI 1 "register_operand" ""))]
4634 "TARGET_ARCH64 && TARGET_FPU"
4635 "sparc_emit_floatunsdi (operands); DONE;")
4637 (define_expand "floatditf2"
4638 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4639 (float:TF (match_operand:DI 1 "register_operand" "")))]
4640 "TARGET_FPU && TARGET_V9 && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4641 "emit_tfmode_cvt (FLOAT, operands); DONE;")
4643 (define_insn "*floatditf2_hq"
4644 [(set (match_operand:TF 0 "register_operand" "=e")
4645 (float:TF (match_operand:DI 1 "register_operand" "e")))]
4646 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
4648 [(set_attr "type" "fp")])
4650 (define_expand "floatunsditf2"
4651 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4652 (unsigned_float:TF (match_operand:DI 1 "register_operand" "")))]
4653 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4654 "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
4656 ;; Convert a float to an actual integer.
4657 ;; Truncation is performed as part of the conversion.
4659 (define_insn "fix_truncsfsi2"
4660 [(set (match_operand:SI 0 "register_operand" "=f")
4661 (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
4664 [(set_attr "type" "fp")
4665 (set_attr "fptype" "double")])
4667 (define_insn "fix_truncdfsi2"
4668 [(set (match_operand:SI 0 "register_operand" "=f")
4669 (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
4672 [(set_attr "type" "fp")
4673 (set_attr "fptype" "double")])
4675 (define_expand "fix_trunctfsi2"
4676 [(set (match_operand:SI 0 "register_operand" "")
4677 (fix:SI (match_operand:TF 1 "general_operand" "")))]
4678 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4679 "emit_tfmode_cvt (FIX, operands); DONE;")
4681 (define_insn "*fix_trunctfsi2_hq"
4682 [(set (match_operand:SI 0 "register_operand" "=f")
4683 (fix:SI (match_operand:TF 1 "register_operand" "e")))]
4684 "TARGET_FPU && TARGET_HARD_QUAD"
4686 [(set_attr "type" "fp")])
4688 (define_expand "fixuns_trunctfsi2"
4689 [(set (match_operand:SI 0 "register_operand" "")
4690 (unsigned_fix:SI (match_operand:TF 1 "general_operand" "")))]
4691 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4692 "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
4694 ;; Now the same, for V9 targets
4696 (define_insn "fix_truncsfdi2"
4697 [(set (match_operand:DI 0 "register_operand" "=e")
4698 (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
4699 "TARGET_V9 && TARGET_FPU"
4701 [(set_attr "type" "fp")
4702 (set_attr "fptype" "double")])
4704 (define_insn "fix_truncdfdi2"
4705 [(set (match_operand:DI 0 "register_operand" "=e")
4706 (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
4707 "TARGET_V9 && TARGET_FPU"
4709 [(set_attr "type" "fp")
4710 (set_attr "fptype" "double")])
4712 (define_expand "fix_trunctfdi2"
4713 [(set (match_operand:DI 0 "register_operand" "")
4714 (fix:DI (match_operand:TF 1 "general_operand" "")))]
4715 "TARGET_V9 && TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4716 "emit_tfmode_cvt (FIX, operands); DONE;")
4718 (define_insn "*fix_trunctfdi2_hq"
4719 [(set (match_operand:DI 0 "register_operand" "=e")
4720 (fix:DI (match_operand:TF 1 "register_operand" "e")))]
4721 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
4723 [(set_attr "type" "fp")])
4725 (define_expand "fixuns_trunctfdi2"
4726 [(set (match_operand:DI 0 "register_operand" "")
4727 (unsigned_fix:DI (match_operand:TF 1 "general_operand" "")))]
4728 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4729 "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
4731 ;;- arithmetic instructions
4733 (define_expand "adddi3"
4734 [(set (match_operand:DI 0 "register_operand" "=r")
4735 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
4736 (match_operand:DI 2 "arith_double_add_operand" "rHI")))]
4741 if (! TARGET_ARCH64)
4743 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
4744 gen_rtx_SET (VOIDmode, operands[0],
4745 gen_rtx_PLUS (DImode, operands[1],
4747 gen_rtx_CLOBBER (VOIDmode,
4748 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
4751 if (arith_double_4096_operand(operands[2], DImode))
4753 switch (GET_CODE (operands[1]))
4755 case CONST_INT: i = INTVAL (operands[1]); break;
4756 case CONST_DOUBLE: i = CONST_DOUBLE_LOW (operands[1]); break;
4758 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
4759 gen_rtx_MINUS (DImode, operands[1],
4763 emit_insn (gen_movdi (operands[0], GEN_INT (i + 4096)));
4768 (define_insn_and_split "adddi3_insn_sp32"
4769 [(set (match_operand:DI 0 "register_operand" "=r")
4770 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
4771 (match_operand:DI 2 "arith_double_operand" "rHI")))
4772 (clobber (reg:CC 100))]
4775 "&& reload_completed"
4776 [(parallel [(set (reg:CC_NOOV 100)
4777 (compare:CC_NOOV (plus:SI (match_dup 4)
4781 (plus:SI (match_dup 4) (match_dup 5)))])
4783 (plus:SI (plus:SI (match_dup 7)
4785 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4787 operands[3] = gen_lowpart (SImode, operands[0]);
4788 operands[4] = gen_lowpart (SImode, operands[1]);
4789 operands[5] = gen_lowpart (SImode, operands[2]);
4790 operands[6] = gen_highpart (SImode, operands[0]);
4791 operands[7] = gen_highpart_mode (SImode, DImode, operands[1]);
4792 #if HOST_BITS_PER_WIDE_INT == 32
4793 if (GET_CODE (operands[2]) == CONST_INT)
4795 if (INTVAL (operands[2]) < 0)
4796 operands[8] = constm1_rtx;
4798 operands[8] = const0_rtx;
4802 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
4804 [(set_attr "length" "2")])
4807 [(set (match_operand:DI 0 "register_operand" "")
4808 (minus:DI (match_operand:DI 1 "arith_double_operand" "")
4809 (match_operand:DI 2 "arith_double_operand" "")))
4810 (clobber (reg:CC 100))]
4811 "! TARGET_ARCH64 && reload_completed"
4812 [(parallel [(set (reg:CC_NOOV 100)
4813 (compare:CC_NOOV (minus:SI (match_dup 4)
4817 (minus:SI (match_dup 4) (match_dup 5)))])
4819 (minus:SI (minus:SI (match_dup 7)
4821 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4823 operands[3] = gen_lowpart (SImode, operands[0]);
4824 operands[4] = gen_lowpart (SImode, operands[1]);
4825 operands[5] = gen_lowpart (SImode, operands[2]);
4826 operands[6] = gen_highpart (SImode, operands[0]);
4827 operands[7] = gen_highpart (SImode, operands[1]);
4828 #if HOST_BITS_PER_WIDE_INT == 32
4829 if (GET_CODE (operands[2]) == CONST_INT)
4831 if (INTVAL (operands[2]) < 0)
4832 operands[8] = constm1_rtx;
4834 operands[8] = const0_rtx;
4838 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
4841 ;; LTU here means "carry set"
4843 [(set (match_operand:SI 0 "register_operand" "=r")
4844 (plus:SI (plus:SI (match_operand:SI 1 "arith_operand" "%r")
4845 (match_operand:SI 2 "arith_operand" "rI"))
4846 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4849 [(set_attr "type" "ialuX")])
4851 (define_insn_and_split "*addx_extend_sp32"
4852 [(set (match_operand:DI 0 "register_operand" "=r")
4853 (zero_extend:DI (plus:SI (plus:SI
4854 (match_operand:SI 1 "reg_or_0_operand" "%rJ")
4855 (match_operand:SI 2 "arith_operand" "rI"))
4856 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4859 "&& reload_completed"
4860 [(set (match_dup 3) (plus:SI (plus:SI (match_dup 1) (match_dup 2))
4861 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
4862 (set (match_dup 4) (const_int 0))]
4863 "operands[3] = gen_lowpart (SImode, operands[0]);
4864 operands[4] = gen_highpart_mode (SImode, DImode, operands[1]);"
4865 [(set_attr "length" "2")])
4867 (define_insn "*addx_extend_sp64"
4868 [(set (match_operand:DI 0 "register_operand" "=r")
4869 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
4870 (match_operand:SI 2 "arith_operand" "rI"))
4871 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4874 [(set_attr "type" "ialuX")])
4877 [(set (match_operand:SI 0 "register_operand" "=r")
4878 (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
4879 (match_operand:SI 2 "arith_operand" "rI"))
4880 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4883 [(set_attr "type" "ialuX")])
4885 (define_insn "*subx_extend_sp64"
4886 [(set (match_operand:DI 0 "register_operand" "=r")
4887 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
4888 (match_operand:SI 2 "arith_operand" "rI"))
4889 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4892 [(set_attr "type" "ialuX")])
4894 (define_insn_and_split "*subx_extend"
4895 [(set (match_operand:DI 0 "register_operand" "=r")
4896 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
4897 (match_operand:SI 2 "arith_operand" "rI"))
4898 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4901 "&& reload_completed"
4902 [(set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 2))
4903 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
4904 (set (match_dup 4) (const_int 0))]
4905 "operands[3] = gen_lowpart (SImode, operands[0]);
4906 operands[4] = gen_highpart (SImode, operands[0]);"
4907 [(set_attr "length" "2")])
4909 (define_insn_and_split ""
4910 [(set (match_operand:DI 0 "register_operand" "=r")
4911 (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4912 (match_operand:DI 2 "register_operand" "r")))
4913 (clobber (reg:CC 100))]
4916 "&& reload_completed"
4917 [(parallel [(set (reg:CC_NOOV 100)
4918 (compare:CC_NOOV (plus:SI (match_dup 3) (match_dup 1))
4920 (set (match_dup 5) (plus:SI (match_dup 3) (match_dup 1)))])
4922 (plus:SI (plus:SI (match_dup 4) (const_int 0))
4923 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4924 "operands[3] = gen_lowpart (SImode, operands[2]);
4925 operands[4] = gen_highpart (SImode, operands[2]);
4926 operands[5] = gen_lowpart (SImode, operands[0]);
4927 operands[6] = gen_highpart (SImode, operands[0]);"
4928 [(set_attr "length" "2")])
4930 (define_insn "*adddi3_sp64"
4931 [(set (match_operand:DI 0 "register_operand" "=r")
4932 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
4933 (match_operand:DI 2 "arith_double_operand" "rHI")))]
4937 (define_expand "addsi3"
4938 [(set (match_operand:SI 0 "register_operand" "=r,d")
4939 (plus:SI (match_operand:SI 1 "arith_operand" "%r,d")
4940 (match_operand:SI 2 "arith_add_operand" "rI,d")))]
4943 if (arith_4096_operand(operands[2], SImode))
4945 if (GET_CODE (operands[1]) == CONST_INT)
4946 emit_insn (gen_movsi (operands[0],
4947 GEN_INT (INTVAL (operands[1]) + 4096)));
4949 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
4950 gen_rtx_MINUS (SImode, operands[1],
4956 (define_insn "*addsi3"
4957 [(set (match_operand:SI 0 "register_operand" "=r,d")
4958 (plus:SI (match_operand:SI 1 "arith_operand" "%r,d")
4959 (match_operand:SI 2 "arith_operand" "rI,d")))]
4963 fpadd32s\t%1, %2, %0"
4964 [(set_attr "type" "*,fp")])
4966 (define_insn "*cmp_cc_plus"
4967 [(set (reg:CC_NOOV 100)
4968 (compare:CC_NOOV (plus:SI (match_operand:SI 0 "arith_operand" "%r")
4969 (match_operand:SI 1 "arith_operand" "rI"))
4972 "addcc\t%0, %1, %%g0"
4973 [(set_attr "type" "compare")])
4975 (define_insn "*cmp_ccx_plus"
4976 [(set (reg:CCX_NOOV 100)
4977 (compare:CCX_NOOV (plus:DI (match_operand:DI 0 "arith_double_operand" "%r")
4978 (match_operand:DI 1 "arith_double_operand" "rHI"))
4981 "addcc\t%0, %1, %%g0"
4982 [(set_attr "type" "compare")])
4984 (define_insn "*cmp_cc_plus_set"
4985 [(set (reg:CC_NOOV 100)
4986 (compare:CC_NOOV (plus:SI (match_operand:SI 1 "arith_operand" "%r")
4987 (match_operand:SI 2 "arith_operand" "rI"))
4989 (set (match_operand:SI 0 "register_operand" "=r")
4990 (plus:SI (match_dup 1) (match_dup 2)))]
4993 [(set_attr "type" "compare")])
4995 (define_insn "*cmp_ccx_plus_set"
4996 [(set (reg:CCX_NOOV 100)
4997 (compare:CCX_NOOV (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
4998 (match_operand:DI 2 "arith_double_operand" "rHI"))
5000 (set (match_operand:DI 0 "register_operand" "=r")
5001 (plus:DI (match_dup 1) (match_dup 2)))]
5004 [(set_attr "type" "compare")])
5006 (define_expand "subdi3"
5007 [(set (match_operand:DI 0 "register_operand" "=r")
5008 (minus:DI (match_operand:DI 1 "register_operand" "r")
5009 (match_operand:DI 2 "arith_double_add_operand" "rHI")))]
5012 if (! TARGET_ARCH64)
5014 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
5015 gen_rtx_SET (VOIDmode, operands[0],
5016 gen_rtx_MINUS (DImode, operands[1],
5018 gen_rtx_CLOBBER (VOIDmode,
5019 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
5022 if (arith_double_4096_operand(operands[2], DImode))
5024 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
5025 gen_rtx_PLUS (DImode, operands[1],
5031 (define_insn_and_split "*subdi3_sp32"
5032 [(set (match_operand:DI 0 "register_operand" "=r")
5033 (minus:DI (match_operand:DI 1 "register_operand" "r")
5034 (match_operand:DI 2 "arith_double_operand" "rHI")))
5035 (clobber (reg:CC 100))]
5038 "&& reload_completed
5039 && (GET_CODE (operands[2]) == CONST_INT
5040 || GET_CODE (operands[2]) == CONST_DOUBLE)"
5041 [(clobber (const_int 0))]
5045 highp = gen_highpart_mode (SImode, DImode, operands[2]);
5046 lowp = gen_lowpart (SImode, operands[2]);
5047 if ((lowp == const0_rtx)
5048 && (operands[0] == operands[1]))
5050 emit_insn (gen_rtx_SET (VOIDmode,
5051 gen_highpart (SImode, operands[0]),
5052 gen_rtx_MINUS (SImode,
5053 gen_highpart_mode (SImode, DImode,
5059 emit_insn (gen_cmp_minus_cc_set (gen_lowpart (SImode, operands[0]),
5060 gen_lowpart (SImode, operands[1]),
5062 emit_insn (gen_subx (gen_highpart (SImode, operands[0]),
5063 gen_highpart_mode (SImode, DImode, operands[1]),
5068 [(set_attr "length" "2")])
5071 [(set (match_operand:DI 0 "register_operand" "")
5072 (minus:DI (match_operand:DI 1 "register_operand" "")
5073 (match_operand:DI 2 "register_operand" "")))
5074 (clobber (reg:CC 100))]
5076 && reload_completed"
5077 [(clobber (const_int 0))]
5079 emit_insn (gen_cmp_minus_cc_set (gen_lowpart (SImode, operands[0]),
5080 gen_lowpart (SImode, operands[1]),
5081 gen_lowpart (SImode, operands[2])));
5082 emit_insn (gen_subx (gen_highpart (SImode, operands[0]),
5083 gen_highpart (SImode, operands[1]),
5084 gen_highpart (SImode, operands[2])));
5088 (define_insn_and_split ""
5089 [(set (match_operand:DI 0 "register_operand" "=r")
5090 (minus:DI (match_operand:DI 1 "register_operand" "r")
5091 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))
5092 (clobber (reg:CC 100))]
5095 "&& reload_completed"
5096 [(parallel [(set (reg:CC_NOOV 100)
5097 (compare:CC_NOOV (minus:SI (match_dup 3) (match_dup 2))
5099 (set (match_dup 5) (minus:SI (match_dup 3) (match_dup 2)))])
5101 (minus:SI (minus:SI (match_dup 4) (const_int 0))
5102 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5103 "operands[3] = gen_lowpart (SImode, operands[1]);
5104 operands[4] = gen_highpart (SImode, operands[1]);
5105 operands[5] = gen_lowpart (SImode, operands[0]);
5106 operands[6] = gen_highpart (SImode, operands[0]);"
5107 [(set_attr "length" "2")])
5109 (define_insn "*subdi3_sp64"
5110 [(set (match_operand:DI 0 "register_operand" "=r")
5111 (minus:DI (match_operand:DI 1 "register_operand" "r")
5112 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5116 (define_expand "subsi3"
5117 [(set (match_operand:SI 0 "register_operand" "=r,d")
5118 (minus:SI (match_operand:SI 1 "register_operand" "r,d")
5119 (match_operand:SI 2 "arith_add_operand" "rI,d")))]
5122 if (arith_4096_operand(operands[2], SImode))
5124 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
5125 gen_rtx_PLUS (SImode, operands[1],
5131 (define_insn "*subsi3"
5132 [(set (match_operand:SI 0 "register_operand" "=r,d")
5133 (minus:SI (match_operand:SI 1 "register_operand" "r,d")
5134 (match_operand:SI 2 "arith_operand" "rI,d")))]
5138 fpsub32s\t%1, %2, %0"
5139 [(set_attr "type" "*,fp")])
5141 (define_insn "*cmp_minus_cc"
5142 [(set (reg:CC_NOOV 100)
5143 (compare:CC_NOOV (minus:SI (match_operand:SI 0 "reg_or_0_operand" "rJ")
5144 (match_operand:SI 1 "arith_operand" "rI"))
5147 "subcc\t%r0, %1, %%g0"
5148 [(set_attr "type" "compare")])
5150 (define_insn "*cmp_minus_ccx"
5151 [(set (reg:CCX_NOOV 100)
5152 (compare:CCX_NOOV (minus:DI (match_operand:DI 0 "register_operand" "r")
5153 (match_operand:DI 1 "arith_double_operand" "rHI"))
5156 "subcc\t%0, %1, %%g0"
5157 [(set_attr "type" "compare")])
5159 (define_insn "cmp_minus_cc_set"
5160 [(set (reg:CC_NOOV 100)
5161 (compare:CC_NOOV (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5162 (match_operand:SI 2 "arith_operand" "rI"))
5164 (set (match_operand:SI 0 "register_operand" "=r")
5165 (minus:SI (match_dup 1) (match_dup 2)))]
5167 "subcc\t%r1, %2, %0"
5168 [(set_attr "type" "compare")])
5170 (define_insn "*cmp_minus_ccx_set"
5171 [(set (reg:CCX_NOOV 100)
5172 (compare:CCX_NOOV (minus:DI (match_operand:DI 1 "register_operand" "r")
5173 (match_operand:DI 2 "arith_double_operand" "rHI"))
5175 (set (match_operand:DI 0 "register_operand" "=r")
5176 (minus:DI (match_dup 1) (match_dup 2)))]
5179 [(set_attr "type" "compare")])
5181 ;; Integer Multiply/Divide.
5183 ;; The 32 bit multiply/divide instructions are deprecated on v9, but at
5184 ;; least in UltraSPARC I, II and IIi it is a win tick-wise.
5186 (define_insn "mulsi3"
5187 [(set (match_operand:SI 0 "register_operand" "=r")
5188 (mult:SI (match_operand:SI 1 "arith_operand" "%r")
5189 (match_operand:SI 2 "arith_operand" "rI")))]
5192 [(set_attr "type" "imul")])
5194 (define_expand "muldi3"
5195 [(set (match_operand:DI 0 "register_operand" "=r")
5196 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r")
5197 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5198 "TARGET_ARCH64 || TARGET_V8PLUS"
5202 emit_insn (gen_muldi3_v8plus (operands[0], operands[1], operands[2]));
5207 (define_insn "*muldi3_sp64"
5208 [(set (match_operand:DI 0 "register_operand" "=r")
5209 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r")
5210 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5213 [(set_attr "type" "imul")])
5215 ;; V8plus wide multiply.
5217 (define_insn "muldi3_v8plus"
5218 [(set (match_operand:DI 0 "register_operand" "=r,h")
5219 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r,0")
5220 (match_operand:DI 2 "arith_double_operand" "rI,rI")))
5221 (clobber (match_scratch:SI 3 "=&h,X"))
5222 (clobber (match_scratch:SI 4 "=&h,X"))]
5225 if (sparc_check_64 (operands[1], insn) <= 0)
5226 output_asm_insn ("srl\t%L1, 0, %L1", operands);
5227 if (which_alternative == 1)
5228 output_asm_insn ("sllx\t%H1, 32, %H1", operands);
5229 if (GET_CODE (operands[2]) == CONST_INT)
5231 if (which_alternative == 1)
5232 return "or\t%L1, %H1, %H1\n\tmulx\t%H1, %2, %L0\;srlx\t%L0, 32, %H0";
5234 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";
5236 else if (rtx_equal_p (operands[1], operands[2]))
5238 if (which_alternative == 1)
5239 return "or\t%L1, %H1, %H1\n\tmulx\t%H1, %H1, %L0\;srlx\t%L0, 32, %H0";
5241 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";
5243 if (sparc_check_64 (operands[2], insn) <= 0)
5244 output_asm_insn ("srl\t%L2, 0, %L2", operands);
5245 if (which_alternative == 1)
5246 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";
5248 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";
5250 [(set_attr "type" "multi")
5251 (set_attr "length" "9,8")])
5253 (define_insn "*cmp_mul_set"
5255 (compare:CC (mult:SI (match_operand:SI 1 "arith_operand" "%r")
5256 (match_operand:SI 2 "arith_operand" "rI"))
5258 (set (match_operand:SI 0 "register_operand" "=r")
5259 (mult:SI (match_dup 1) (match_dup 2)))]
5260 "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS"
5261 "smulcc\t%1, %2, %0"
5262 [(set_attr "type" "imul")])
5264 (define_expand "mulsidi3"
5265 [(set (match_operand:DI 0 "register_operand" "")
5266 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
5267 (sign_extend:DI (match_operand:SI 2 "arith_operand" ""))))]
5270 if (CONSTANT_P (operands[2]))
5273 emit_insn (gen_const_mulsidi3_v8plus (operands[0], operands[1],
5276 emit_insn (gen_const_mulsidi3_sp32 (operands[0], operands[1],
5282 emit_insn (gen_mulsidi3_v8plus (operands[0], operands[1], operands[2]));
5287 ;; V9 puts the 64 bit product in a 64 bit register. Only out or global
5288 ;; registers can hold 64 bit values in the V8plus environment.
5290 (define_insn "mulsidi3_v8plus"
5291 [(set (match_operand:DI 0 "register_operand" "=h,r")
5292 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5293 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
5294 (clobber (match_scratch:SI 3 "=X,&h"))]
5297 smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
5298 smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
5299 [(set_attr "type" "multi")
5300 (set_attr "length" "2,3")])
5303 (define_insn "const_mulsidi3_v8plus"
5304 [(set (match_operand:DI 0 "register_operand" "=h,r")
5305 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5306 (match_operand:SI 2 "small_int" "I,I")))
5307 (clobber (match_scratch:SI 3 "=X,&h"))]
5310 smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
5311 smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
5312 [(set_attr "type" "multi")
5313 (set_attr "length" "2,3")])
5316 (define_insn "*mulsidi3_sp32"
5317 [(set (match_operand:DI 0 "register_operand" "=r")
5318 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5319 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
5322 return TARGET_SPARCLET
5323 ? "smuld\t%1, %2, %L0"
5324 : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
5327 (if_then_else (eq_attr "isa" "sparclet")
5328 (const_string "imul") (const_string "multi")))
5329 (set (attr "length")
5330 (if_then_else (eq_attr "isa" "sparclet")
5331 (const_int 1) (const_int 2)))])
5333 (define_insn "*mulsidi3_sp64"
5334 [(set (match_operand:DI 0 "register_operand" "=r")
5335 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5336 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
5337 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5339 [(set_attr "type" "imul")])
5341 ;; Extra pattern, because sign_extend of a constant isn't valid.
5344 (define_insn "const_mulsidi3_sp32"
5345 [(set (match_operand:DI 0 "register_operand" "=r")
5346 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5347 (match_operand:SI 2 "small_int" "I")))]
5350 return TARGET_SPARCLET
5351 ? "smuld\t%1, %2, %L0"
5352 : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
5355 (if_then_else (eq_attr "isa" "sparclet")
5356 (const_string "imul") (const_string "multi")))
5357 (set (attr "length")
5358 (if_then_else (eq_attr "isa" "sparclet")
5359 (const_int 1) (const_int 2)))])
5361 (define_insn "const_mulsidi3_sp64"
5362 [(set (match_operand:DI 0 "register_operand" "=r")
5363 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5364 (match_operand:SI 2 "small_int" "I")))]
5365 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5367 [(set_attr "type" "imul")])
5369 (define_expand "smulsi3_highpart"
5370 [(set (match_operand:SI 0 "register_operand" "")
5372 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
5373 (sign_extend:DI (match_operand:SI 2 "arith_operand" "")))
5375 "TARGET_HARD_MUL && TARGET_ARCH32"
5377 if (CONSTANT_P (operands[2]))
5381 emit_insn (gen_const_smulsi3_highpart_v8plus (operands[0],
5387 emit_insn (gen_const_smulsi3_highpart (operands[0], operands[1], operands[2]));
5392 emit_insn (gen_smulsi3_highpart_v8plus (operands[0], operands[1],
5393 operands[2], GEN_INT (32)));
5399 (define_insn "smulsi3_highpart_v8plus"
5400 [(set (match_operand:SI 0 "register_operand" "=h,r")
5402 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5403 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
5404 (match_operand:SI 3 "const_int_operand" "i,i"))))
5405 (clobber (match_scratch:SI 4 "=X,&h"))]
5408 smul\t%1, %2, %0\;srlx\t%0, %3, %0
5409 smul\t%1, %2, %4\;srlx\t%4, %3, %0"
5410 [(set_attr "type" "multi")
5411 (set_attr "length" "2")])
5413 ;; The combiner changes TRUNCATE in the previous pattern to SUBREG.
5416 [(set (match_operand:SI 0 "register_operand" "=h,r")
5419 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5420 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
5421 (match_operand:SI 3 "const_int_operand" "i,i"))
5423 (clobber (match_scratch:SI 4 "=X,&h"))]
5426 smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
5427 smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
5428 [(set_attr "type" "multi")
5429 (set_attr "length" "2")])
5432 (define_insn "const_smulsi3_highpart_v8plus"
5433 [(set (match_operand:SI 0 "register_operand" "=h,r")
5435 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5436 (match_operand 2 "small_int" "i,i"))
5437 (match_operand:SI 3 "const_int_operand" "i,i"))))
5438 (clobber (match_scratch:SI 4 "=X,&h"))]
5441 smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
5442 smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
5443 [(set_attr "type" "multi")
5444 (set_attr "length" "2")])
5447 (define_insn "*smulsi3_highpart_sp32"
5448 [(set (match_operand:SI 0 "register_operand" "=r")
5450 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5451 (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
5454 "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
5455 [(set_attr "type" "multi")
5456 (set_attr "length" "2")])
5459 (define_insn "const_smulsi3_highpart"
5460 [(set (match_operand:SI 0 "register_operand" "=r")
5462 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5463 (match_operand:SI 2 "register_operand" "r"))
5466 "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
5467 [(set_attr "type" "multi")
5468 (set_attr "length" "2")])
5470 (define_expand "umulsidi3"
5471 [(set (match_operand:DI 0 "register_operand" "")
5472 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
5473 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" ""))))]
5476 if (CONSTANT_P (operands[2]))
5479 emit_insn (gen_const_umulsidi3_v8plus (operands[0], operands[1],
5482 emit_insn (gen_const_umulsidi3_sp32 (operands[0], operands[1],
5488 emit_insn (gen_umulsidi3_v8plus (operands[0], operands[1], operands[2]));
5494 (define_insn "umulsidi3_v8plus"
5495 [(set (match_operand:DI 0 "register_operand" "=h,r")
5496 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5497 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
5498 (clobber (match_scratch:SI 3 "=X,&h"))]
5501 umul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
5502 umul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
5503 [(set_attr "type" "multi")
5504 (set_attr "length" "2,3")])
5507 (define_insn "*umulsidi3_sp32"
5508 [(set (match_operand:DI 0 "register_operand" "=r")
5509 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5510 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
5513 return TARGET_SPARCLET
5514 ? "umuld\t%1, %2, %L0"
5515 : "umul\t%1, %2, %L0\n\trd\t%%y, %H0";
5518 (if_then_else (eq_attr "isa" "sparclet")
5519 (const_string "imul") (const_string "multi")))
5520 (set (attr "length")
5521 (if_then_else (eq_attr "isa" "sparclet")
5522 (const_int 1) (const_int 2)))])
5524 (define_insn "*umulsidi3_sp64"
5525 [(set (match_operand:DI 0 "register_operand" "=r")
5526 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5527 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
5528 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5530 [(set_attr "type" "imul")])
5532 ;; Extra pattern, because sign_extend of a constant isn't valid.
5535 (define_insn "const_umulsidi3_sp32"
5536 [(set (match_operand:DI 0 "register_operand" "=r")
5537 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5538 (match_operand:SI 2 "uns_small_int" "")))]
5541 return TARGET_SPARCLET
5542 ? "umuld\t%1, %2, %L0"
5543 : "umul\t%1, %2, %L0\n\trd\t%%y, %H0";
5546 (if_then_else (eq_attr "isa" "sparclet")
5547 (const_string "imul") (const_string "multi")))
5548 (set (attr "length")
5549 (if_then_else (eq_attr "isa" "sparclet")
5550 (const_int 1) (const_int 2)))])
5552 (define_insn "const_umulsidi3_sp64"
5553 [(set (match_operand:DI 0 "register_operand" "=r")
5554 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5555 (match_operand:SI 2 "uns_small_int" "")))]
5556 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5558 [(set_attr "type" "imul")])
5561 (define_insn "const_umulsidi3_v8plus"
5562 [(set (match_operand:DI 0 "register_operand" "=h,r")
5563 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5564 (match_operand:SI 2 "uns_small_int" "")))
5565 (clobber (match_scratch:SI 3 "=X,h"))]
5568 umul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
5569 umul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
5570 [(set_attr "type" "multi")
5571 (set_attr "length" "2,3")])
5573 (define_expand "umulsi3_highpart"
5574 [(set (match_operand:SI 0 "register_operand" "")
5576 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
5577 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" "")))
5579 "TARGET_HARD_MUL && TARGET_ARCH32"
5581 if (CONSTANT_P (operands[2]))
5585 emit_insn (gen_const_umulsi3_highpart_v8plus (operands[0],
5591 emit_insn (gen_const_umulsi3_highpart (operands[0], operands[1], operands[2]));
5596 emit_insn (gen_umulsi3_highpart_v8plus (operands[0], operands[1],
5597 operands[2], GEN_INT (32)));
5603 (define_insn "umulsi3_highpart_v8plus"
5604 [(set (match_operand:SI 0 "register_operand" "=h,r")
5606 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5607 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
5608 (match_operand:SI 3 "const_int_operand" "i,i"))))
5609 (clobber (match_scratch:SI 4 "=X,h"))]
5612 umul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
5613 umul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
5614 [(set_attr "type" "multi")
5615 (set_attr "length" "2")])
5618 (define_insn "const_umulsi3_highpart_v8plus"
5619 [(set (match_operand:SI 0 "register_operand" "=h,r")
5621 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5622 (match_operand:SI 2 "uns_small_int" ""))
5623 (match_operand:SI 3 "const_int_operand" "i,i"))))
5624 (clobber (match_scratch:SI 4 "=X,h"))]
5627 umul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
5628 umul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
5629 [(set_attr "type" "multi")
5630 (set_attr "length" "2")])
5633 (define_insn "*umulsi3_highpart_sp32"
5634 [(set (match_operand:SI 0 "register_operand" "=r")
5636 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5637 (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
5640 "umul\t%1, %2, %%g0\n\trd\t%%y, %0"
5641 [(set_attr "type" "multi")
5642 (set_attr "length" "2")])
5645 (define_insn "const_umulsi3_highpart"
5646 [(set (match_operand:SI 0 "register_operand" "=r")
5648 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5649 (match_operand:SI 2 "uns_small_int" ""))
5652 "umul\t%1, %2, %%g0\n\trd\t%%y, %0"
5653 [(set_attr "type" "multi")
5654 (set_attr "length" "2")])
5656 ;; The v8 architecture specifies that there must be 3 instructions between
5657 ;; a y register write and a use of it for correct results.
5659 (define_expand "divsi3"
5660 [(parallel [(set (match_operand:SI 0 "register_operand" "=r,r")
5661 (div:SI (match_operand:SI 1 "register_operand" "r,r")
5662 (match_operand:SI 2 "input_operand" "rI,m")))
5663 (clobber (match_scratch:SI 3 "=&r,&r"))])]
5664 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
5668 operands[3] = gen_reg_rtx(SImode);
5669 emit_insn (gen_ashrsi3 (operands[3], operands[1], GEN_INT (31)));
5670 emit_insn (gen_divsi3_sp64 (operands[0], operands[1], operands[2],
5676 (define_insn "divsi3_sp32"
5677 [(set (match_operand:SI 0 "register_operand" "=r,r")
5678 (div:SI (match_operand:SI 1 "register_operand" "r,r")
5679 (match_operand:SI 2 "input_operand" "rI,m")))
5680 (clobber (match_scratch:SI 3 "=&r,&r"))]
5681 "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS)
5684 if (which_alternative == 0)
5686 return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tsdiv\t%1, %2, %0";
5688 return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tnop\n\tnop\n\tnop\n\tsdiv\t%1, %2, %0";
5691 return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tld\t%2, %3\n\tsdiv\t%1, %3, %0";
5693 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";
5695 [(set_attr "type" "multi")
5696 (set (attr "length")
5697 (if_then_else (eq_attr "isa" "v9")
5698 (const_int 4) (const_int 6)))])
5700 (define_insn "divsi3_sp64"
5701 [(set (match_operand:SI 0 "register_operand" "=r")
5702 (div:SI (match_operand:SI 1 "register_operand" "r")
5703 (match_operand:SI 2 "input_operand" "rI")))
5704 (use (match_operand:SI 3 "register_operand" "r"))]
5705 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5706 "wr\t%%g0, %3, %%y\n\tsdiv\t%1, %2, %0"
5707 [(set_attr "type" "multi")
5708 (set_attr "length" "2")])
5710 (define_insn "divdi3"
5711 [(set (match_operand:DI 0 "register_operand" "=r")
5712 (div:DI (match_operand:DI 1 "register_operand" "r")
5713 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5716 [(set_attr "type" "idiv")])
5718 (define_insn "*cmp_sdiv_cc_set"
5720 (compare:CC (div:SI (match_operand:SI 1 "register_operand" "r")
5721 (match_operand:SI 2 "arith_operand" "rI"))
5723 (set (match_operand:SI 0 "register_operand" "=r")
5724 (div:SI (match_dup 1) (match_dup 2)))
5725 (clobber (match_scratch:SI 3 "=&r"))]
5726 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
5729 return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tsdivcc\t%1, %2, %0";
5731 return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tnop\n\tnop\n\tnop\n\tsdivcc\t%1, %2, %0";
5733 [(set_attr "type" "multi")
5734 (set (attr "length")
5735 (if_then_else (eq_attr "isa" "v9")
5736 (const_int 3) (const_int 6)))])
5739 (define_expand "udivsi3"
5740 [(set (match_operand:SI 0 "register_operand" "")
5741 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "")
5742 (match_operand:SI 2 "input_operand" "")))]
5743 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
5746 (define_insn "udivsi3_sp32"
5747 [(set (match_operand:SI 0 "register_operand" "=r,&r,&r")
5748 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "r,r,m")
5749 (match_operand:SI 2 "input_operand" "rI,m,r")))]
5751 || TARGET_DEPRECATED_V8_INSNS)
5754 output_asm_insn ("wr\t%%g0, %%g0, %%y", operands);
5755 switch (which_alternative)
5758 return "nop\n\tnop\n\tnop\n\tudiv\t%1, %2, %0";
5760 return "ld\t%2, %0\n\tnop\n\tnop\n\tudiv\t%1, %0, %0";
5762 return "ld\t%1, %0\n\tnop\n\tnop\n\tudiv\t%0, %2, %0";
5765 [(set_attr "type" "multi")
5766 (set_attr "length" "5")])
5768 (define_insn "udivsi3_sp64"
5769 [(set (match_operand:SI 0 "register_operand" "=r")
5770 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "r")
5771 (match_operand:SI 2 "input_operand" "rI")))]
5772 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5773 "wr\t%%g0, 0, %%y\n\tudiv\t%1, %2, %0"
5774 [(set_attr "type" "multi")
5775 (set_attr "length" "2")])
5777 (define_insn "udivdi3"
5778 [(set (match_operand:DI 0 "register_operand" "=r")
5779 (udiv:DI (match_operand:DI 1 "register_operand" "r")
5780 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5783 [(set_attr "type" "idiv")])
5785 (define_insn "*cmp_udiv_cc_set"
5787 (compare:CC (udiv:SI (match_operand:SI 1 "register_operand" "r")
5788 (match_operand:SI 2 "arith_operand" "rI"))
5790 (set (match_operand:SI 0 "register_operand" "=r")
5791 (udiv:SI (match_dup 1) (match_dup 2)))]
5793 || TARGET_DEPRECATED_V8_INSNS"
5796 return "wr\t%%g0, %%g0, %%y\n\tudivcc\t%1, %2, %0";
5798 return "wr\t%%g0, %%g0, %%y\n\tnop\n\tnop\n\tnop\n\tudivcc\t%1, %2, %0";
5800 [(set_attr "type" "multi")
5801 (set (attr "length")
5802 (if_then_else (eq_attr "isa" "v9")
5803 (const_int 2) (const_int 5)))])
5805 ; sparclet multiply/accumulate insns
5807 (define_insn "*smacsi"
5808 [(set (match_operand:SI 0 "register_operand" "=r")
5809 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "%r")
5810 (match_operand:SI 2 "arith_operand" "rI"))
5811 (match_operand:SI 3 "register_operand" "0")))]
5814 [(set_attr "type" "imul")])
5816 (define_insn "*smacdi"
5817 [(set (match_operand:DI 0 "register_operand" "=r")
5818 (plus:DI (mult:DI (sign_extend:DI
5819 (match_operand:SI 1 "register_operand" "%r"))
5821 (match_operand:SI 2 "register_operand" "r")))
5822 (match_operand:DI 3 "register_operand" "0")))]
5824 "smacd\t%1, %2, %L0"
5825 [(set_attr "type" "imul")])
5827 (define_insn "*umacdi"
5828 [(set (match_operand:DI 0 "register_operand" "=r")
5829 (plus:DI (mult:DI (zero_extend:DI
5830 (match_operand:SI 1 "register_operand" "%r"))
5832 (match_operand:SI 2 "register_operand" "r")))
5833 (match_operand:DI 3 "register_operand" "0")))]
5835 "umacd\t%1, %2, %L0"
5836 [(set_attr "type" "imul")])
5838 ;;- Boolean instructions
5839 ;; We define DImode `and' so with DImode `not' we can get
5840 ;; DImode `andn'. Other combinations are possible.
5842 (define_expand "anddi3"
5843 [(set (match_operand:DI 0 "register_operand" "")
5844 (and:DI (match_operand:DI 1 "arith_double_operand" "")
5845 (match_operand:DI 2 "arith_double_operand" "")))]
5849 (define_insn "*anddi3_sp32"
5850 [(set (match_operand:DI 0 "register_operand" "=r,b")
5851 (and:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
5852 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
5857 [(set_attr "type" "*,fp")
5858 (set_attr "length" "2,*")
5859 (set_attr "fptype" "double")])
5861 (define_insn "*anddi3_sp64"
5862 [(set (match_operand:DI 0 "register_operand" "=r,b")
5863 (and:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
5864 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
5869 [(set_attr "type" "*,fp")
5870 (set_attr "fptype" "double")])
5872 (define_insn "andsi3"
5873 [(set (match_operand:SI 0 "register_operand" "=r,d")
5874 (and:SI (match_operand:SI 1 "arith_operand" "%r,d")
5875 (match_operand:SI 2 "arith_operand" "rI,d")))]
5880 [(set_attr "type" "*,fp")])
5883 [(set (match_operand:SI 0 "register_operand" "")
5884 (and:SI (match_operand:SI 1 "register_operand" "")
5885 (match_operand:SI 2 "" "")))
5886 (clobber (match_operand:SI 3 "register_operand" ""))]
5887 "GET_CODE (operands[2]) == CONST_INT
5888 && !SMALL_INT32 (operands[2])
5889 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
5890 [(set (match_dup 3) (match_dup 4))
5891 (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 1)))]
5893 operands[4] = GEN_INT (~INTVAL (operands[2]));
5896 ;; Split DImode logical operations requiring two instructions.
5898 [(set (match_operand:DI 0 "register_operand" "")
5899 (match_operator:DI 1 "cc_arithop" ; AND, IOR, XOR
5900 [(match_operand:DI 2 "register_operand" "")
5901 (match_operand:DI 3 "arith_double_operand" "")]))]
5904 && ((GET_CODE (operands[0]) == REG
5905 && REGNO (operands[0]) < 32)
5906 || (GET_CODE (operands[0]) == SUBREG
5907 && GET_CODE (SUBREG_REG (operands[0])) == REG
5908 && REGNO (SUBREG_REG (operands[0])) < 32))"
5909 [(set (match_dup 4) (match_op_dup:SI 1 [(match_dup 6) (match_dup 8)]))
5910 (set (match_dup 5) (match_op_dup:SI 1 [(match_dup 7) (match_dup 9)]))]
5912 operands[4] = gen_highpart (SImode, operands[0]);
5913 operands[5] = gen_lowpart (SImode, operands[0]);
5914 operands[6] = gen_highpart (SImode, operands[2]);
5915 operands[7] = gen_lowpart (SImode, operands[2]);
5916 #if HOST_BITS_PER_WIDE_INT == 32
5917 if (GET_CODE (operands[3]) == CONST_INT)
5919 if (INTVAL (operands[3]) < 0)
5920 operands[8] = constm1_rtx;
5922 operands[8] = const0_rtx;
5926 operands[8] = gen_highpart_mode (SImode, DImode, operands[3]);
5927 operands[9] = gen_lowpart (SImode, operands[3]);
5930 (define_insn_and_split "*and_not_di_sp32"
5931 [(set (match_operand:DI 0 "register_operand" "=r,b")
5932 (and:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
5933 (match_operand:DI 2 "register_operand" "r,b")))]
5937 fandnot1\t%1, %2, %0"
5938 "&& reload_completed
5939 && ((GET_CODE (operands[0]) == REG
5940 && REGNO (operands[0]) < 32)
5941 || (GET_CODE (operands[0]) == SUBREG
5942 && GET_CODE (SUBREG_REG (operands[0])) == REG
5943 && REGNO (SUBREG_REG (operands[0])) < 32))"
5944 [(set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))
5945 (set (match_dup 6) (and:SI (not:SI (match_dup 7)) (match_dup 8)))]
5946 "operands[3] = gen_highpart (SImode, operands[0]);
5947 operands[4] = gen_highpart (SImode, operands[1]);
5948 operands[5] = gen_highpart (SImode, operands[2]);
5949 operands[6] = gen_lowpart (SImode, operands[0]);
5950 operands[7] = gen_lowpart (SImode, operands[1]);
5951 operands[8] = gen_lowpart (SImode, operands[2]);"
5952 [(set_attr "type" "*,fp")
5953 (set_attr "length" "2,*")
5954 (set_attr "fptype" "double")])
5956 (define_insn "*and_not_di_sp64"
5957 [(set (match_operand:DI 0 "register_operand" "=r,b")
5958 (and:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
5959 (match_operand:DI 2 "register_operand" "r,b")))]
5963 fandnot1\t%1, %2, %0"
5964 [(set_attr "type" "*,fp")
5965 (set_attr "fptype" "double")])
5967 (define_insn "*and_not_si"
5968 [(set (match_operand:SI 0 "register_operand" "=r,d")
5969 (and:SI (not:SI (match_operand:SI 1 "register_operand" "r,d"))
5970 (match_operand:SI 2 "register_operand" "r,d")))]
5974 fandnot1s\t%1, %2, %0"
5975 [(set_attr "type" "*,fp")])
5977 (define_expand "iordi3"
5978 [(set (match_operand:DI 0 "register_operand" "")
5979 (ior:DI (match_operand:DI 1 "arith_double_operand" "")
5980 (match_operand:DI 2 "arith_double_operand" "")))]
5984 (define_insn "*iordi3_sp32"
5985 [(set (match_operand:DI 0 "register_operand" "=r,b")
5986 (ior:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
5987 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
5992 [(set_attr "type" "*,fp")
5993 (set_attr "length" "2,*")
5994 (set_attr "fptype" "double")])
5996 (define_insn "*iordi3_sp64"
5997 [(set (match_operand:DI 0 "register_operand" "=r,b")
5998 (ior:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
5999 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6004 [(set_attr "type" "*,fp")
6005 (set_attr "fptype" "double")])
6007 (define_insn "iorsi3"
6008 [(set (match_operand:SI 0 "register_operand" "=r,d")
6009 (ior:SI (match_operand:SI 1 "arith_operand" "%r,d")
6010 (match_operand:SI 2 "arith_operand" "rI,d")))]
6015 [(set_attr "type" "*,fp")])
6018 [(set (match_operand:SI 0 "register_operand" "")
6019 (ior:SI (match_operand:SI 1 "register_operand" "")
6020 (match_operand:SI 2 "" "")))
6021 (clobber (match_operand:SI 3 "register_operand" ""))]
6022 "GET_CODE (operands[2]) == CONST_INT
6023 && !SMALL_INT32 (operands[2])
6024 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6025 [(set (match_dup 3) (match_dup 4))
6026 (set (match_dup 0) (ior:SI (not:SI (match_dup 3)) (match_dup 1)))]
6028 operands[4] = GEN_INT (~INTVAL (operands[2]));
6031 (define_insn_and_split "*or_not_di_sp32"
6032 [(set (match_operand:DI 0 "register_operand" "=r,b")
6033 (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6034 (match_operand:DI 2 "register_operand" "r,b")))]
6038 fornot1\t%1, %2, %0"
6039 "&& reload_completed
6040 && ((GET_CODE (operands[0]) == REG
6041 && REGNO (operands[0]) < 32)
6042 || (GET_CODE (operands[0]) == SUBREG
6043 && GET_CODE (SUBREG_REG (operands[0])) == REG
6044 && REGNO (SUBREG_REG (operands[0])) < 32))"
6045 [(set (match_dup 3) (ior:SI (not:SI (match_dup 4)) (match_dup 5)))
6046 (set (match_dup 6) (ior:SI (not:SI (match_dup 7)) (match_dup 8)))]
6047 "operands[3] = gen_highpart (SImode, operands[0]);
6048 operands[4] = gen_highpart (SImode, operands[1]);
6049 operands[5] = gen_highpart (SImode, operands[2]);
6050 operands[6] = gen_lowpart (SImode, operands[0]);
6051 operands[7] = gen_lowpart (SImode, operands[1]);
6052 operands[8] = gen_lowpart (SImode, operands[2]);"
6053 [(set_attr "type" "*,fp")
6054 (set_attr "length" "2,*")
6055 (set_attr "fptype" "double")])
6057 (define_insn "*or_not_di_sp64"
6058 [(set (match_operand:DI 0 "register_operand" "=r,b")
6059 (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6060 (match_operand:DI 2 "register_operand" "r,b")))]
6064 fornot1\t%1, %2, %0"
6065 [(set_attr "type" "*,fp")
6066 (set_attr "fptype" "double")])
6068 (define_insn "*or_not_si"
6069 [(set (match_operand:SI 0 "register_operand" "=r,d")
6070 (ior:SI (not:SI (match_operand:SI 1 "register_operand" "r,d"))
6071 (match_operand:SI 2 "register_operand" "r,d")))]
6075 fornot1s\t%1, %2, %0"
6076 [(set_attr "type" "*,fp")])
6078 (define_expand "xordi3"
6079 [(set (match_operand:DI 0 "register_operand" "")
6080 (xor:DI (match_operand:DI 1 "arith_double_operand" "")
6081 (match_operand:DI 2 "arith_double_operand" "")))]
6085 (define_insn "*xordi3_sp32"
6086 [(set (match_operand:DI 0 "register_operand" "=r,b")
6087 (xor:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6088 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6093 [(set_attr "type" "*,fp")
6094 (set_attr "length" "2,*")
6095 (set_attr "fptype" "double")])
6097 (define_insn "*xordi3_sp64"
6098 [(set (match_operand:DI 0 "register_operand" "=r,b")
6099 (xor:DI (match_operand:DI 1 "arith_double_operand" "%rJ,b")
6100 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6105 [(set_attr "type" "*,fp")
6106 (set_attr "fptype" "double")])
6108 (define_insn "*xordi3_sp64_dbl"
6109 [(set (match_operand:DI 0 "register_operand" "=r")
6110 (xor:DI (match_operand:DI 1 "register_operand" "r")
6111 (match_operand:DI 2 "const64_operand" "")))]
6113 && HOST_BITS_PER_WIDE_INT != 64)"
6116 (define_insn "xorsi3"
6117 [(set (match_operand:SI 0 "register_operand" "=r,d")
6118 (xor:SI (match_operand:SI 1 "arith_operand" "%rJ,d")
6119 (match_operand:SI 2 "arith_operand" "rI,d")))]
6124 [(set_attr "type" "*,fp")])
6127 [(set (match_operand:SI 0 "register_operand" "")
6128 (xor:SI (match_operand:SI 1 "register_operand" "")
6129 (match_operand:SI 2 "" "")))
6130 (clobber (match_operand:SI 3 "register_operand" ""))]
6131 "GET_CODE (operands[2]) == CONST_INT
6132 && !SMALL_INT32 (operands[2])
6133 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6134 [(set (match_dup 3) (match_dup 4))
6135 (set (match_dup 0) (not:SI (xor:SI (match_dup 3) (match_dup 1))))]
6137 operands[4] = GEN_INT (~INTVAL (operands[2]));
6141 [(set (match_operand:SI 0 "register_operand" "")
6142 (not:SI (xor:SI (match_operand:SI 1 "register_operand" "")
6143 (match_operand:SI 2 "" ""))))
6144 (clobber (match_operand:SI 3 "register_operand" ""))]
6145 "GET_CODE (operands[2]) == CONST_INT
6146 && !SMALL_INT32 (operands[2])
6147 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6148 [(set (match_dup 3) (match_dup 4))
6149 (set (match_dup 0) (xor:SI (match_dup 3) (match_dup 1)))]
6151 operands[4] = GEN_INT (~INTVAL (operands[2]));
6154 ;; xnor patterns. Note that (a ^ ~b) == (~a ^ b) == ~(a ^ b).
6155 ;; Combine now canonicalizes to the rightmost expression.
6156 (define_insn_and_split "*xor_not_di_sp32"
6157 [(set (match_operand:DI 0 "register_operand" "=r,b")
6158 (not:DI (xor:DI (match_operand:DI 1 "register_operand" "r,b")
6159 (match_operand:DI 2 "register_operand" "r,b"))))]
6164 "&& reload_completed
6165 && ((GET_CODE (operands[0]) == REG
6166 && REGNO (operands[0]) < 32)
6167 || (GET_CODE (operands[0]) == SUBREG
6168 && GET_CODE (SUBREG_REG (operands[0])) == REG
6169 && REGNO (SUBREG_REG (operands[0])) < 32))"
6170 [(set (match_dup 3) (not:SI (xor:SI (match_dup 4) (match_dup 5))))
6171 (set (match_dup 6) (not:SI (xor:SI (match_dup 7) (match_dup 8))))]
6172 "operands[3] = gen_highpart (SImode, operands[0]);
6173 operands[4] = gen_highpart (SImode, operands[1]);
6174 operands[5] = gen_highpart (SImode, operands[2]);
6175 operands[6] = gen_lowpart (SImode, operands[0]);
6176 operands[7] = gen_lowpart (SImode, operands[1]);
6177 operands[8] = gen_lowpart (SImode, operands[2]);"
6178 [(set_attr "type" "*,fp")
6179 (set_attr "length" "2,*")
6180 (set_attr "fptype" "double")])
6182 (define_insn "*xor_not_di_sp64"
6183 [(set (match_operand:DI 0 "register_operand" "=r,b")
6184 (not:DI (xor:DI (match_operand:DI 1 "reg_or_0_operand" "rJ,b")
6185 (match_operand:DI 2 "arith_double_operand" "rHI,b"))))]
6190 [(set_attr "type" "*,fp")
6191 (set_attr "fptype" "double")])
6193 (define_insn "*xor_not_si"
6194 [(set (match_operand:SI 0 "register_operand" "=r,d")
6195 (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "rJ,d")
6196 (match_operand:SI 2 "arith_operand" "rI,d"))))]
6201 [(set_attr "type" "*,fp")])
6203 ;; These correspond to the above in the case where we also (or only)
6204 ;; want to set the condition code.
6206 (define_insn "*cmp_cc_arith_op"
6209 (match_operator:SI 2 "cc_arithop"
6210 [(match_operand:SI 0 "arith_operand" "%r")
6211 (match_operand:SI 1 "arith_operand" "rI")])
6214 "%A2cc\t%0, %1, %%g0"
6215 [(set_attr "type" "compare")])
6217 (define_insn "*cmp_ccx_arith_op"
6220 (match_operator:DI 2 "cc_arithop"
6221 [(match_operand:DI 0 "arith_double_operand" "%r")
6222 (match_operand:DI 1 "arith_double_operand" "rHI")])
6225 "%A2cc\t%0, %1, %%g0"
6226 [(set_attr "type" "compare")])
6228 (define_insn "*cmp_cc_arith_op_set"
6231 (match_operator:SI 3 "cc_arithop"
6232 [(match_operand:SI 1 "arith_operand" "%r")
6233 (match_operand:SI 2 "arith_operand" "rI")])
6235 (set (match_operand:SI 0 "register_operand" "=r")
6236 (match_operator:SI 4 "cc_arithop" [(match_dup 1) (match_dup 2)]))]
6237 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
6239 [(set_attr "type" "compare")])
6241 (define_insn "*cmp_ccx_arith_op_set"
6244 (match_operator:DI 3 "cc_arithop"
6245 [(match_operand:DI 1 "arith_double_operand" "%r")
6246 (match_operand:DI 2 "arith_double_operand" "rHI")])
6248 (set (match_operand:DI 0 "register_operand" "=r")
6249 (match_operator:DI 4 "cc_arithop" [(match_dup 1) (match_dup 2)]))]
6250 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
6252 [(set_attr "type" "compare")])
6254 (define_insn "*cmp_cc_xor_not"
6257 (not:SI (xor:SI (match_operand:SI 0 "reg_or_0_operand" "%rJ")
6258 (match_operand:SI 1 "arith_operand" "rI")))
6261 "xnorcc\t%r0, %1, %%g0"
6262 [(set_attr "type" "compare")])
6264 (define_insn "*cmp_ccx_xor_not"
6267 (not:DI (xor:DI (match_operand:DI 0 "reg_or_0_operand" "%rJ")
6268 (match_operand:DI 1 "arith_double_operand" "rHI")))
6271 "xnorcc\t%r0, %1, %%g0"
6272 [(set_attr "type" "compare")])
6274 (define_insn "*cmp_cc_xor_not_set"
6277 (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
6278 (match_operand:SI 2 "arith_operand" "rI")))
6280 (set (match_operand:SI 0 "register_operand" "=r")
6281 (not:SI (xor:SI (match_dup 1) (match_dup 2))))]
6283 "xnorcc\t%r1, %2, %0"
6284 [(set_attr "type" "compare")])
6286 (define_insn "*cmp_ccx_xor_not_set"
6289 (not:DI (xor:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ")
6290 (match_operand:DI 2 "arith_double_operand" "rHI")))
6292 (set (match_operand:DI 0 "register_operand" "=r")
6293 (not:DI (xor:DI (match_dup 1) (match_dup 2))))]
6295 "xnorcc\t%r1, %2, %0"
6296 [(set_attr "type" "compare")])
6298 (define_insn "*cmp_cc_arith_op_not"
6301 (match_operator:SI 2 "cc_arithopn"
6302 [(not:SI (match_operand:SI 0 "arith_operand" "rI"))
6303 (match_operand:SI 1 "reg_or_0_operand" "rJ")])
6306 "%B2cc\t%r1, %0, %%g0"
6307 [(set_attr "type" "compare")])
6309 (define_insn "*cmp_ccx_arith_op_not"
6312 (match_operator:DI 2 "cc_arithopn"
6313 [(not:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
6314 (match_operand:DI 1 "reg_or_0_operand" "rJ")])
6317 "%B2cc\t%r1, %0, %%g0"
6318 [(set_attr "type" "compare")])
6320 (define_insn "*cmp_cc_arith_op_not_set"
6323 (match_operator:SI 3 "cc_arithopn"
6324 [(not:SI (match_operand:SI 1 "arith_operand" "rI"))
6325 (match_operand:SI 2 "reg_or_0_operand" "rJ")])
6327 (set (match_operand:SI 0 "register_operand" "=r")
6328 (match_operator:SI 4 "cc_arithopn"
6329 [(not:SI (match_dup 1)) (match_dup 2)]))]
6330 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
6331 "%B3cc\t%r2, %1, %0"
6332 [(set_attr "type" "compare")])
6334 (define_insn "*cmp_ccx_arith_op_not_set"
6337 (match_operator:DI 3 "cc_arithopn"
6338 [(not:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
6339 (match_operand:DI 2 "reg_or_0_operand" "rJ")])
6341 (set (match_operand:DI 0 "register_operand" "=r")
6342 (match_operator:DI 4 "cc_arithopn"
6343 [(not:DI (match_dup 1)) (match_dup 2)]))]
6344 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
6345 "%B3cc\t%r2, %1, %0"
6346 [(set_attr "type" "compare")])
6348 ;; We cannot use the "neg" pseudo insn because the Sun assembler
6349 ;; does not know how to make it work for constants.
6351 (define_expand "negdi2"
6352 [(set (match_operand:DI 0 "register_operand" "=r")
6353 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
6356 if (! TARGET_ARCH64)
6358 emit_insn (gen_rtx_PARALLEL
6361 gen_rtx_SET (VOIDmode, operand0,
6362 gen_rtx_NEG (DImode, operand1)),
6363 gen_rtx_CLOBBER (VOIDmode,
6364 gen_rtx_REG (CCmode,
6370 (define_insn_and_split "*negdi2_sp32"
6371 [(set (match_operand:DI 0 "register_operand" "=r")
6372 (neg:DI (match_operand:DI 1 "register_operand" "r")))
6373 (clobber (reg:CC 100))]
6376 "&& reload_completed"
6377 [(parallel [(set (reg:CC_NOOV 100)
6378 (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 5))
6380 (set (match_dup 4) (minus:SI (const_int 0) (match_dup 5)))])
6381 (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
6382 (ltu:SI (reg:CC 100) (const_int 0))))]
6383 "operands[2] = gen_highpart (SImode, operands[0]);
6384 operands[3] = gen_highpart (SImode, operands[1]);
6385 operands[4] = gen_lowpart (SImode, operands[0]);
6386 operands[5] = gen_lowpart (SImode, operands[1]);"
6387 [(set_attr "length" "2")])
6389 (define_insn "*negdi2_sp64"
6390 [(set (match_operand:DI 0 "register_operand" "=r")
6391 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
6393 "sub\t%%g0, %1, %0")
6395 (define_insn "negsi2"
6396 [(set (match_operand:SI 0 "register_operand" "=r")
6397 (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
6399 "sub\t%%g0, %1, %0")
6401 (define_insn "*cmp_cc_neg"
6402 [(set (reg:CC_NOOV 100)
6403 (compare:CC_NOOV (neg:SI (match_operand:SI 0 "arith_operand" "rI"))
6406 "subcc\t%%g0, %0, %%g0"
6407 [(set_attr "type" "compare")])
6409 (define_insn "*cmp_ccx_neg"
6410 [(set (reg:CCX_NOOV 100)
6411 (compare:CCX_NOOV (neg:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
6414 "subcc\t%%g0, %0, %%g0"
6415 [(set_attr "type" "compare")])
6417 (define_insn "*cmp_cc_set_neg"
6418 [(set (reg:CC_NOOV 100)
6419 (compare:CC_NOOV (neg:SI (match_operand:SI 1 "arith_operand" "rI"))
6421 (set (match_operand:SI 0 "register_operand" "=r")
6422 (neg:SI (match_dup 1)))]
6424 "subcc\t%%g0, %1, %0"
6425 [(set_attr "type" "compare")])
6427 (define_insn "*cmp_ccx_set_neg"
6428 [(set (reg:CCX_NOOV 100)
6429 (compare:CCX_NOOV (neg:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
6431 (set (match_operand:DI 0 "register_operand" "=r")
6432 (neg:DI (match_dup 1)))]
6434 "subcc\t%%g0, %1, %0"
6435 [(set_attr "type" "compare")])
6437 ;; We cannot use the "not" pseudo insn because the Sun assembler
6438 ;; does not know how to make it work for constants.
6439 (define_expand "one_cmpldi2"
6440 [(set (match_operand:DI 0 "register_operand" "")
6441 (not:DI (match_operand:DI 1 "register_operand" "")))]
6445 (define_insn_and_split "*one_cmpldi2_sp32"
6446 [(set (match_operand:DI 0 "register_operand" "=r,b")
6447 (not:DI (match_operand:DI 1 "register_operand" "r,b")))]
6452 "&& reload_completed
6453 && ((GET_CODE (operands[0]) == REG
6454 && REGNO (operands[0]) < 32)
6455 || (GET_CODE (operands[0]) == SUBREG
6456 && GET_CODE (SUBREG_REG (operands[0])) == REG
6457 && REGNO (SUBREG_REG (operands[0])) < 32))"
6458 [(set (match_dup 2) (not:SI (xor:SI (match_dup 3) (const_int 0))))
6459 (set (match_dup 4) (not:SI (xor:SI (match_dup 5) (const_int 0))))]
6460 "operands[2] = gen_highpart (SImode, operands[0]);
6461 operands[3] = gen_highpart (SImode, operands[1]);
6462 operands[4] = gen_lowpart (SImode, operands[0]);
6463 operands[5] = gen_lowpart (SImode, operands[1]);"
6464 [(set_attr "type" "*,fp")
6465 (set_attr "length" "2,*")
6466 (set_attr "fptype" "double")])
6468 (define_insn "*one_cmpldi2_sp64"
6469 [(set (match_operand:DI 0 "register_operand" "=r,b")
6470 (not:DI (match_operand:DI 1 "arith_double_operand" "rHI,b")))]
6475 [(set_attr "type" "*,fp")
6476 (set_attr "fptype" "double")])
6478 (define_insn "one_cmplsi2"
6479 [(set (match_operand:SI 0 "register_operand" "=r,d")
6480 (not:SI (match_operand:SI 1 "arith_operand" "rI,d")))]
6485 [(set_attr "type" "*,fp")])
6487 (define_insn "*cmp_cc_not"
6489 (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI"))
6492 "xnorcc\t%%g0, %0, %%g0"
6493 [(set_attr "type" "compare")])
6495 (define_insn "*cmp_ccx_not"
6497 (compare:CCX (not:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
6500 "xnorcc\t%%g0, %0, %%g0"
6501 [(set_attr "type" "compare")])
6503 (define_insn "*cmp_cc_set_not"
6505 (compare:CC (not:SI (match_operand:SI 1 "arith_operand" "rI"))
6507 (set (match_operand:SI 0 "register_operand" "=r")
6508 (not:SI (match_dup 1)))]
6510 "xnorcc\t%%g0, %1, %0"
6511 [(set_attr "type" "compare")])
6513 (define_insn "*cmp_ccx_set_not"
6515 (compare:CCX (not:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
6517 (set (match_operand:DI 0 "register_operand" "=r")
6518 (not:DI (match_dup 1)))]
6520 "xnorcc\t%%g0, %1, %0"
6521 [(set_attr "type" "compare")])
6523 (define_insn "*cmp_cc_set"
6524 [(set (match_operand:SI 0 "register_operand" "=r")
6525 (match_operand:SI 1 "register_operand" "r"))
6527 (compare:CC (match_dup 1)
6531 [(set_attr "type" "compare")])
6533 (define_insn "*cmp_ccx_set64"
6534 [(set (match_operand:DI 0 "register_operand" "=r")
6535 (match_operand:DI 1 "register_operand" "r"))
6537 (compare:CCX (match_dup 1)
6541 [(set_attr "type" "compare")])
6543 ;; Floating point arithmetic instructions.
6545 (define_expand "addtf3"
6546 [(set (match_operand:TF 0 "nonimmediate_operand" "")
6547 (plus:TF (match_operand:TF 1 "general_operand" "")
6548 (match_operand:TF 2 "general_operand" "")))]
6549 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6550 "emit_tfmode_binop (PLUS, operands); DONE;")
6552 (define_insn "*addtf3_hq"
6553 [(set (match_operand:TF 0 "register_operand" "=e")
6554 (plus:TF (match_operand:TF 1 "register_operand" "e")
6555 (match_operand:TF 2 "register_operand" "e")))]
6556 "TARGET_FPU && TARGET_HARD_QUAD"
6558 [(set_attr "type" "fp")])
6560 (define_insn "adddf3"
6561 [(set (match_operand:DF 0 "register_operand" "=e")
6562 (plus:DF (match_operand:DF 1 "register_operand" "e")
6563 (match_operand:DF 2 "register_operand" "e")))]
6566 [(set_attr "type" "fp")
6567 (set_attr "fptype" "double")])
6569 (define_insn "addsf3"
6570 [(set (match_operand:SF 0 "register_operand" "=f")
6571 (plus:SF (match_operand:SF 1 "register_operand" "f")
6572 (match_operand:SF 2 "register_operand" "f")))]
6575 [(set_attr "type" "fp")])
6577 (define_expand "subtf3"
6578 [(set (match_operand:TF 0 "nonimmediate_operand" "")
6579 (minus:TF (match_operand:TF 1 "general_operand" "")
6580 (match_operand:TF 2 "general_operand" "")))]
6581 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6582 "emit_tfmode_binop (MINUS, operands); DONE;")
6584 (define_insn "*subtf3_hq"
6585 [(set (match_operand:TF 0 "register_operand" "=e")
6586 (minus:TF (match_operand:TF 1 "register_operand" "e")
6587 (match_operand:TF 2 "register_operand" "e")))]
6588 "TARGET_FPU && TARGET_HARD_QUAD"
6590 [(set_attr "type" "fp")])
6592 (define_insn "subdf3"
6593 [(set (match_operand:DF 0 "register_operand" "=e")
6594 (minus:DF (match_operand:DF 1 "register_operand" "e")
6595 (match_operand:DF 2 "register_operand" "e")))]
6598 [(set_attr "type" "fp")
6599 (set_attr "fptype" "double")])
6601 (define_insn "subsf3"
6602 [(set (match_operand:SF 0 "register_operand" "=f")
6603 (minus:SF (match_operand:SF 1 "register_operand" "f")
6604 (match_operand:SF 2 "register_operand" "f")))]
6607 [(set_attr "type" "fp")])
6609 (define_expand "multf3"
6610 [(set (match_operand:TF 0 "nonimmediate_operand" "")
6611 (mult:TF (match_operand:TF 1 "general_operand" "")
6612 (match_operand:TF 2 "general_operand" "")))]
6613 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6614 "emit_tfmode_binop (MULT, operands); DONE;")
6616 (define_insn "*multf3_hq"
6617 [(set (match_operand:TF 0 "register_operand" "=e")
6618 (mult:TF (match_operand:TF 1 "register_operand" "e")
6619 (match_operand:TF 2 "register_operand" "e")))]
6620 "TARGET_FPU && TARGET_HARD_QUAD"
6622 [(set_attr "type" "fpmul")])
6624 (define_insn "muldf3"
6625 [(set (match_operand:DF 0 "register_operand" "=e")
6626 (mult:DF (match_operand:DF 1 "register_operand" "e")
6627 (match_operand:DF 2 "register_operand" "e")))]
6630 [(set_attr "type" "fpmul")
6631 (set_attr "fptype" "double")])
6633 (define_insn "mulsf3"
6634 [(set (match_operand:SF 0 "register_operand" "=f")
6635 (mult:SF (match_operand:SF 1 "register_operand" "f")
6636 (match_operand:SF 2 "register_operand" "f")))]
6639 [(set_attr "type" "fpmul")])
6641 (define_insn "*muldf3_extend"
6642 [(set (match_operand:DF 0 "register_operand" "=e")
6643 (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "f"))
6644 (float_extend:DF (match_operand:SF 2 "register_operand" "f"))))]
6645 "(TARGET_V8 || TARGET_V9) && TARGET_FPU"
6646 "fsmuld\t%1, %2, %0"
6647 [(set_attr "type" "fpmul")
6648 (set_attr "fptype" "double")])
6650 (define_insn "*multf3_extend"
6651 [(set (match_operand:TF 0 "register_operand" "=e")
6652 (mult:TF (float_extend:TF (match_operand:DF 1 "register_operand" "e"))
6653 (float_extend:TF (match_operand:DF 2 "register_operand" "e"))))]
6654 "(TARGET_V8 || TARGET_V9) && TARGET_FPU && TARGET_HARD_QUAD"
6655 "fdmulq\t%1, %2, %0"
6656 [(set_attr "type" "fpmul")])
6658 (define_expand "divtf3"
6659 [(set (match_operand:TF 0 "nonimmediate_operand" "")
6660 (div:TF (match_operand:TF 1 "general_operand" "")
6661 (match_operand:TF 2 "general_operand" "")))]
6662 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6663 "emit_tfmode_binop (DIV, operands); DONE;")
6665 ;; don't have timing for quad-prec. divide.
6666 (define_insn "*divtf3_hq"
6667 [(set (match_operand:TF 0 "register_operand" "=e")
6668 (div:TF (match_operand:TF 1 "register_operand" "e")
6669 (match_operand:TF 2 "register_operand" "e")))]
6670 "TARGET_FPU && TARGET_HARD_QUAD"
6672 [(set_attr "type" "fpdivd")])
6674 (define_insn "divdf3"
6675 [(set (match_operand:DF 0 "register_operand" "=e")
6676 (div:DF (match_operand:DF 1 "register_operand" "e")
6677 (match_operand:DF 2 "register_operand" "e")))]
6680 [(set_attr "type" "fpdivd")
6681 (set_attr "fptype" "double")])
6683 (define_insn "divsf3"
6684 [(set (match_operand:SF 0 "register_operand" "=f")
6685 (div:SF (match_operand:SF 1 "register_operand" "f")
6686 (match_operand:SF 2 "register_operand" "f")))]
6689 [(set_attr "type" "fpdivs")])
6691 (define_expand "negtf2"
6692 [(set (match_operand:TF 0 "register_operand" "=e,e")
6693 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
6697 (define_insn_and_split "*negtf2_notv9"
6698 [(set (match_operand:TF 0 "register_operand" "=e,e")
6699 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
6700 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
6706 "&& reload_completed
6707 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6708 [(set (match_dup 2) (neg:SF (match_dup 3)))
6709 (set (match_dup 4) (match_dup 5))
6710 (set (match_dup 6) (match_dup 7))]
6711 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6712 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6713 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6714 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
6715 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6716 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6717 [(set_attr "type" "fpmove,*")
6718 (set_attr "length" "*,2")])
6720 (define_insn_and_split "*negtf2_v9"
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.
6724 "TARGET_FPU && TARGET_V9"
6728 "&& reload_completed
6729 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6730 [(set (match_dup 2) (neg:DF (match_dup 3)))
6731 (set (match_dup 4) (match_dup 5))]
6732 "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
6733 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
6734 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6735 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6736 [(set_attr "type" "fpmove,*")
6737 (set_attr "length" "*,2")
6738 (set_attr "fptype" "double")])
6740 (define_expand "negdf2"
6741 [(set (match_operand:DF 0 "register_operand" "")
6742 (neg:DF (match_operand:DF 1 "register_operand" "")))]
6746 (define_insn_and_split "*negdf2_notv9"
6747 [(set (match_operand:DF 0 "register_operand" "=e,e")
6748 (neg:DF (match_operand:DF 1 "register_operand" "0,e")))]
6749 "TARGET_FPU && ! TARGET_V9"
6753 "&& reload_completed
6754 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6755 [(set (match_dup 2) (neg:SF (match_dup 3)))
6756 (set (match_dup 4) (match_dup 5))]
6757 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6758 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6759 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6760 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);"
6761 [(set_attr "type" "fpmove,*")
6762 (set_attr "length" "*,2")])
6764 (define_insn "*negdf2_v9"
6765 [(set (match_operand:DF 0 "register_operand" "=e")
6766 (neg:DF (match_operand:DF 1 "register_operand" "e")))]
6767 "TARGET_FPU && TARGET_V9"
6769 [(set_attr "type" "fpmove")
6770 (set_attr "fptype" "double")])
6772 (define_insn "negsf2"
6773 [(set (match_operand:SF 0 "register_operand" "=f")
6774 (neg:SF (match_operand:SF 1 "register_operand" "f")))]
6777 [(set_attr "type" "fpmove")])
6779 (define_expand "abstf2"
6780 [(set (match_operand:TF 0 "register_operand" "")
6781 (abs:TF (match_operand:TF 1 "register_operand" "")))]
6785 (define_insn_and_split "*abstf2_notv9"
6786 [(set (match_operand:TF 0 "register_operand" "=e,e")
6787 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6788 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
6789 "TARGET_FPU && ! TARGET_V9"
6793 "&& reload_completed
6794 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6795 [(set (match_dup 2) (abs:SF (match_dup 3)))
6796 (set (match_dup 4) (match_dup 5))
6797 (set (match_dup 6) (match_dup 7))]
6798 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6799 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6800 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6801 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
6802 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6803 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6804 [(set_attr "type" "fpmove,*")
6805 (set_attr "length" "*,2")])
6807 (define_insn "*abstf2_hq_v9"
6808 [(set (match_operand:TF 0 "register_operand" "=e,e")
6809 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6810 "TARGET_FPU && TARGET_V9 && TARGET_HARD_QUAD"
6814 [(set_attr "type" "fpmove")
6815 (set_attr "fptype" "double,*")])
6817 (define_insn_and_split "*abstf2_v9"
6818 [(set (match_operand:TF 0 "register_operand" "=e,e")
6819 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6820 "TARGET_FPU && TARGET_V9 && !TARGET_HARD_QUAD"
6824 "&& reload_completed
6825 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6826 [(set (match_dup 2) (abs:DF (match_dup 3)))
6827 (set (match_dup 4) (match_dup 5))]
6828 "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
6829 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
6830 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6831 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6832 [(set_attr "type" "fpmove,*")
6833 (set_attr "length" "*,2")
6834 (set_attr "fptype" "double,*")])
6836 (define_expand "absdf2"
6837 [(set (match_operand:DF 0 "register_operand" "")
6838 (abs:DF (match_operand:DF 1 "register_operand" "")))]
6842 (define_insn_and_split "*absdf2_notv9"
6843 [(set (match_operand:DF 0 "register_operand" "=e,e")
6844 (abs:DF (match_operand:DF 1 "register_operand" "0,e")))]
6845 "TARGET_FPU && ! TARGET_V9"
6849 "&& reload_completed
6850 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6851 [(set (match_dup 2) (abs:SF (match_dup 3)))
6852 (set (match_dup 4) (match_dup 5))]
6853 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6854 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6855 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6856 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);"
6857 [(set_attr "type" "fpmove,*")
6858 (set_attr "length" "*,2")])
6860 (define_insn "*absdf2_v9"
6861 [(set (match_operand:DF 0 "register_operand" "=e")
6862 (abs:DF (match_operand:DF 1 "register_operand" "e")))]
6863 "TARGET_FPU && TARGET_V9"
6865 [(set_attr "type" "fpmove")
6866 (set_attr "fptype" "double")])
6868 (define_insn "abssf2"
6869 [(set (match_operand:SF 0 "register_operand" "=f")
6870 (abs:SF (match_operand:SF 1 "register_operand" "f")))]
6873 [(set_attr "type" "fpmove")])
6875 (define_expand "sqrttf2"
6876 [(set (match_operand:TF 0 "nonimmediate_operand" "")
6877 (sqrt:TF (match_operand:TF 1 "general_operand" "")))]
6878 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6879 "emit_tfmode_unop (SQRT, operands); DONE;")
6881 (define_insn "*sqrttf2_hq"
6882 [(set (match_operand:TF 0 "register_operand" "=e")
6883 (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
6884 "TARGET_FPU && TARGET_HARD_QUAD"
6886 [(set_attr "type" "fpsqrtd")])
6888 (define_insn "sqrtdf2"
6889 [(set (match_operand:DF 0 "register_operand" "=e")
6890 (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
6893 [(set_attr "type" "fpsqrtd")
6894 (set_attr "fptype" "double")])
6896 (define_insn "sqrtsf2"
6897 [(set (match_operand:SF 0 "register_operand" "=f")
6898 (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
6901 [(set_attr "type" "fpsqrts")])
6903 ;;- arithmetic shift instructions
6905 (define_insn "ashlsi3"
6906 [(set (match_operand:SI 0 "register_operand" "=r")
6907 (ashift:SI (match_operand:SI 1 "register_operand" "r")
6908 (match_operand:SI 2 "arith_operand" "rI")))]
6911 if (operands[2] == const1_rtx)
6912 return "add\t%1, %1, %0";
6913 return "sll\t%1, %2, %0";
6916 (if_then_else (match_operand 2 "const1_operand" "")
6917 (const_string "ialu") (const_string "shift")))])
6919 (define_expand "ashldi3"
6920 [(set (match_operand:DI 0 "register_operand" "=r")
6921 (ashift:DI (match_operand:DI 1 "register_operand" "r")
6922 (match_operand:SI 2 "arith_operand" "rI")))]
6923 "TARGET_ARCH64 || TARGET_V8PLUS"
6925 if (! TARGET_ARCH64)
6927 if (GET_CODE (operands[2]) == CONST_INT)
6929 emit_insn (gen_ashldi3_v8plus (operands[0], operands[1], operands[2]));
6934 (define_insn "*ashldi3_sp64"
6935 [(set (match_operand:DI 0 "register_operand" "=r")
6936 (ashift:DI (match_operand:DI 1 "register_operand" "r")
6937 (match_operand:SI 2 "arith_operand" "rI")))]
6940 if (operands[2] == const1_rtx)
6941 return "add\t%1, %1, %0";
6942 return "sllx\t%1, %2, %0";
6945 (if_then_else (match_operand 2 "const1_operand" "")
6946 (const_string "ialu") (const_string "shift")))])
6949 (define_insn "ashldi3_v8plus"
6950 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
6951 (ashift:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
6952 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
6953 (clobber (match_scratch:SI 3 "=X,X,&h"))]
6955 { return sparc_v8plus_shift (operands, insn, "sllx"); }
6956 [(set_attr "type" "multi")
6957 (set_attr "length" "5,5,6")])
6959 ;; Optimize (1LL<<x)-1
6960 ;; XXX this also needs to be fixed to handle equal subregs
6961 ;; XXX first before we could re-enable it.
6963 ; [(set (match_operand:DI 0 "register_operand" "=h")
6964 ; (plus:DI (ashift:DI (const_int 1)
6965 ; (match_operand:SI 1 "arith_operand" "rI"))
6967 ; "0 && TARGET_V8PLUS"
6969 ; if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == REGNO (operands[0]))
6970 ; return "mov\t1, %L0\;sllx\t%L0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
6971 ; return "mov\t1, %H0\;sllx\t%H0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
6973 ; [(set_attr "type" "multi")
6974 ; (set_attr "length" "4")])
6976 (define_insn "*cmp_cc_ashift_1"
6977 [(set (reg:CC_NOOV 100)
6978 (compare:CC_NOOV (ashift:SI (match_operand:SI 0 "register_operand" "r")
6982 "addcc\t%0, %0, %%g0"
6983 [(set_attr "type" "compare")])
6985 (define_insn "*cmp_cc_set_ashift_1"
6986 [(set (reg:CC_NOOV 100)
6987 (compare:CC_NOOV (ashift:SI (match_operand:SI 1 "register_operand" "r")
6990 (set (match_operand:SI 0 "register_operand" "=r")
6991 (ashift:SI (match_dup 1) (const_int 1)))]
6994 [(set_attr "type" "compare")])
6996 (define_insn "ashrsi3"
6997 [(set (match_operand:SI 0 "register_operand" "=r")
6998 (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
6999 (match_operand:SI 2 "arith_operand" "rI")))]
7002 [(set_attr "type" "shift")])
7004 (define_insn "*ashrsi3_extend"
7005 [(set (match_operand:DI 0 "register_operand" "=r")
7006 (sign_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
7007 (match_operand:SI 2 "arith_operand" "r"))))]
7010 [(set_attr "type" "shift")])
7012 ;; This handles the case as above, but with constant shift instead of
7013 ;; register. Combiner "simplifies" it for us a little bit though.
7014 (define_insn "*ashrsi3_extend2"
7015 [(set (match_operand:DI 0 "register_operand" "=r")
7016 (ashiftrt:DI (ashift:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
7018 (match_operand:SI 2 "small_int_or_double" "n")))]
7020 && ((GET_CODE (operands[2]) == CONST_INT
7021 && INTVAL (operands[2]) >= 32 && INTVAL (operands[2]) < 64)
7022 || (GET_CODE (operands[2]) == CONST_DOUBLE
7023 && !CONST_DOUBLE_HIGH (operands[2])
7024 && CONST_DOUBLE_LOW (operands[2]) >= 32
7025 && CONST_DOUBLE_LOW (operands[2]) < 64))"
7027 operands[2] = GEN_INT (INTVAL (operands[2]) - 32);
7029 return "sra\t%1, %2, %0";
7031 [(set_attr "type" "shift")])
7033 (define_expand "ashrdi3"
7034 [(set (match_operand:DI 0 "register_operand" "=r")
7035 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
7036 (match_operand:SI 2 "arith_operand" "rI")))]
7037 "TARGET_ARCH64 || TARGET_V8PLUS"
7039 if (! TARGET_ARCH64)
7041 if (GET_CODE (operands[2]) == CONST_INT)
7042 FAIL; /* prefer generic code in this case */
7043 emit_insn (gen_ashrdi3_v8plus (operands[0], operands[1], operands[2]));
7049 [(set (match_operand:DI 0 "register_operand" "=r")
7050 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
7051 (match_operand:SI 2 "arith_operand" "rI")))]
7054 [(set_attr "type" "shift")])
7057 (define_insn "ashrdi3_v8plus"
7058 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
7059 (ashiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
7060 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
7061 (clobber (match_scratch:SI 3 "=X,X,&h"))]
7063 { return sparc_v8plus_shift (operands, insn, "srax"); }
7064 [(set_attr "type" "multi")
7065 (set_attr "length" "5,5,6")])
7067 (define_insn "lshrsi3"
7068 [(set (match_operand:SI 0 "register_operand" "=r")
7069 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
7070 (match_operand:SI 2 "arith_operand" "rI")))]
7073 [(set_attr "type" "shift")])
7075 ;; This handles the case where
7076 ;; (zero_extend:DI (lshiftrt:SI (match_operand:SI) (match_operand:SI))),
7077 ;; but combiner "simplifies" it for us.
7078 (define_insn "*lshrsi3_extend"
7079 [(set (match_operand:DI 0 "register_operand" "=r")
7080 (and:DI (subreg:DI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
7081 (match_operand:SI 2 "arith_operand" "r")) 0)
7082 (match_operand 3 "" "")))]
7084 && ((GET_CODE (operands[3]) == CONST_DOUBLE
7085 && CONST_DOUBLE_HIGH (operands[3]) == 0
7086 && CONST_DOUBLE_LOW (operands[3]) == 0xffffffff)
7087 || (HOST_BITS_PER_WIDE_INT >= 64
7088 && GET_CODE (operands[3]) == CONST_INT
7089 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) == 0xffffffff))"
7091 [(set_attr "type" "shift")])
7093 ;; This handles the case where
7094 ;; (lshiftrt:DI (zero_extend:DI (match_operand:SI)) (const_int >=0 < 32))
7095 ;; but combiner "simplifies" it for us.
7096 (define_insn "*lshrsi3_extend2"
7097 [(set (match_operand:DI 0 "register_operand" "=r")
7098 (zero_extract:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
7099 (match_operand 2 "small_int_or_double" "n")
7102 && ((GET_CODE (operands[2]) == CONST_INT
7103 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
7104 || (GET_CODE (operands[2]) == CONST_DOUBLE
7105 && CONST_DOUBLE_HIGH (operands[2]) == 0
7106 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
7108 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
7110 return "srl\t%1, %2, %0";
7112 [(set_attr "type" "shift")])
7114 (define_expand "lshrdi3"
7115 [(set (match_operand:DI 0 "register_operand" "=r")
7116 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
7117 (match_operand:SI 2 "arith_operand" "rI")))]
7118 "TARGET_ARCH64 || TARGET_V8PLUS"
7120 if (! TARGET_ARCH64)
7122 if (GET_CODE (operands[2]) == CONST_INT)
7124 emit_insn (gen_lshrdi3_v8plus (operands[0], operands[1], operands[2]));
7130 [(set (match_operand:DI 0 "register_operand" "=r")
7131 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
7132 (match_operand:SI 2 "arith_operand" "rI")))]
7135 [(set_attr "type" "shift")])
7138 (define_insn "lshrdi3_v8plus"
7139 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
7140 (lshiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
7141 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
7142 (clobber (match_scratch:SI 3 "=X,X,&h"))]
7144 { return sparc_v8plus_shift (operands, insn, "srlx"); }
7145 [(set_attr "type" "multi")
7146 (set_attr "length" "5,5,6")])
7149 [(set (match_operand:SI 0 "register_operand" "=r")
7150 (ashiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
7152 (match_operand:SI 2 "small_int_or_double" "n")))]
7154 && ((GET_CODE (operands[2]) == CONST_INT
7155 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
7156 || (GET_CODE (operands[2]) == CONST_DOUBLE
7157 && !CONST_DOUBLE_HIGH (operands[2])
7158 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
7160 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
7162 return "srax\t%1, %2, %0";
7164 [(set_attr "type" "shift")])
7167 [(set (match_operand:SI 0 "register_operand" "=r")
7168 (lshiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
7170 (match_operand:SI 2 "small_int_or_double" "n")))]
7172 && ((GET_CODE (operands[2]) == CONST_INT
7173 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
7174 || (GET_CODE (operands[2]) == CONST_DOUBLE
7175 && !CONST_DOUBLE_HIGH (operands[2])
7176 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
7178 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
7180 return "srlx\t%1, %2, %0";
7182 [(set_attr "type" "shift")])
7185 [(set (match_operand:SI 0 "register_operand" "=r")
7186 (ashiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
7187 (match_operand:SI 2 "small_int_or_double" "n")) 4)
7188 (match_operand:SI 3 "small_int_or_double" "n")))]
7190 && GET_CODE (operands[2]) == CONST_INT && GET_CODE (operands[3]) == CONST_INT
7191 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
7192 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
7193 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
7195 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
7197 return "srax\t%1, %2, %0";
7199 [(set_attr "type" "shift")])
7202 [(set (match_operand:SI 0 "register_operand" "=r")
7203 (lshiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
7204 (match_operand:SI 2 "small_int_or_double" "n")) 4)
7205 (match_operand:SI 3 "small_int_or_double" "n")))]
7207 && GET_CODE (operands[2]) == CONST_INT && GET_CODE (operands[3]) == CONST_INT
7208 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
7209 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
7210 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
7212 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
7214 return "srlx\t%1, %2, %0";
7216 [(set_attr "type" "shift")])
7218 ;; Unconditional and other jump instructions
7219 ;; On the SPARC, by setting the annul bit on an unconditional branch, the
7220 ;; following insn is never executed. This saves us a nop. Dbx does not
7221 ;; handle such branches though, so we only use them when optimizing.
7223 [(set (pc) (label_ref (match_operand 0 "" "")))]
7226 /* TurboSPARC is reported to have problems with
7229 i.e. an empty loop with the annul bit set. The workaround is to use
7233 if (! TARGET_V9 && flag_delayed_branch
7234 && (INSN_ADDRESSES (INSN_UID (operands[0]))
7235 == INSN_ADDRESSES (INSN_UID (insn))))
7238 return TARGET_V9 ? "ba,pt%*\t%%xcc, %l0%(" : "b%*\t%l0%(";
7240 [(set_attr "type" "uncond_branch")])
7242 (define_expand "tablejump"
7243 [(parallel [(set (pc) (match_operand 0 "register_operand" "r"))
7244 (use (label_ref (match_operand 1 "" "")))])]
7247 if (GET_MODE (operands[0]) != CASE_VECTOR_MODE)
7250 /* In pic mode, our address differences are against the base of the
7251 table. Add that base value back in; CSE ought to be able to combine
7252 the two address loads. */
7256 tmp = gen_rtx_LABEL_REF (Pmode, operands[1]);
7258 if (CASE_VECTOR_MODE != Pmode)
7259 tmp2 = gen_rtx_SIGN_EXTEND (Pmode, tmp2);
7260 tmp = gen_rtx_PLUS (Pmode, tmp2, tmp);
7261 operands[0] = memory_address (Pmode, tmp);
7265 (define_insn "*tablejump_sp32"
7266 [(set (pc) (match_operand:SI 0 "address_operand" "p"))
7267 (use (label_ref (match_operand 1 "" "")))]
7270 [(set_attr "type" "uncond_branch")])
7272 (define_insn "*tablejump_sp64"
7273 [(set (pc) (match_operand:DI 0 "address_operand" "p"))
7274 (use (label_ref (match_operand 1 "" "")))]
7277 [(set_attr "type" "uncond_branch")])
7279 ;; This pattern recognizes the "instruction" that appears in
7280 ;; a function call that wants a structure value,
7281 ;; to inform the called function if compiled with Sun CC.
7282 ;(define_insn "*unimp_insn"
7283 ; [(match_operand:SI 0 "immediate_operand" "")]
7284 ; "GET_CODE (operands[0]) == CONST_INT && INTVAL (operands[0]) > 0"
7286 ; [(set_attr "type" "marker")])
7288 ;;- jump to subroutine
7289 (define_expand "call"
7290 ;; Note that this expression is not used for generating RTL.
7291 ;; All the RTL is generated explicitly below.
7292 [(call (match_operand 0 "call_operand" "")
7293 (match_operand 3 "" "i"))]
7294 ;; operands[2] is next_arg_register
7295 ;; operands[3] is struct_value_size_rtx.
7298 rtx fn_rtx, nregs_rtx;
7300 if (GET_MODE (operands[0]) != FUNCTION_MODE)
7303 if (GET_CODE (XEXP (operands[0], 0)) == LABEL_REF)
7305 /* This is really a PIC sequence. We want to represent
7306 it as a funny jump so its delay slots can be filled.
7308 ??? But if this really *is* a CALL, will not it clobber the
7309 call-clobbered registers? We lose this if it is a JUMP_INSN.
7310 Why cannot we have delay slots filled if it were a CALL? */
7312 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
7317 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
7319 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
7325 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
7326 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
7330 fn_rtx = operands[0];
7332 /* Count the number of parameter registers being used by this call.
7333 if that argument is NULL, it means we are using them all, which
7334 means 6 on the sparc. */
7337 nregs_rtx = GEN_INT (REGNO (operands[2]) - 8);
7339 nregs_rtx = GEN_INT (6);
7341 nregs_rtx = const0_rtx;
7344 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
7348 gen_rtvec (3, gen_rtx_CALL (VOIDmode, fn_rtx, nregs_rtx),
7350 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
7355 gen_rtvec (2, gen_rtx_CALL (VOIDmode, fn_rtx, nregs_rtx),
7356 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
7360 /* If this call wants a structure value,
7361 emit an unimp insn to let the called function know about this. */
7362 if (! TARGET_ARCH64 && INTVAL (operands[3]) > 0)
7364 rtx insn = emit_insn (operands[3]);
7365 SCHED_GROUP_P (insn) = 1;
7372 ;; We can't use the same pattern for these two insns, because then registers
7373 ;; in the address may not be properly reloaded.
7375 (define_insn "*call_address_sp32"
7376 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
7377 (match_operand 1 "" ""))
7378 (clobber (reg:SI 15))]
7379 ;;- Do not use operand 1 for most machines.
7382 [(set_attr "type" "call")])
7384 (define_insn "*call_symbolic_sp32"
7385 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
7386 (match_operand 1 "" ""))
7387 (clobber (reg:SI 15))]
7388 ;;- Do not use operand 1 for most machines.
7391 [(set_attr "type" "call")])
7393 (define_insn "*call_address_sp64"
7394 [(call (mem:DI (match_operand:DI 0 "address_operand" "p"))
7395 (match_operand 1 "" ""))
7396 (clobber (reg:DI 15))]
7397 ;;- Do not use operand 1 for most machines.
7400 [(set_attr "type" "call")])
7402 (define_insn "*call_symbolic_sp64"
7403 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
7404 (match_operand 1 "" ""))
7405 (clobber (reg:DI 15))]
7406 ;;- Do not use operand 1 for most machines.
7409 [(set_attr "type" "call")])
7411 ;; This is a call that wants a structure value.
7412 ;; There is no such critter for v9 (??? we may need one anyway).
7413 (define_insn "*call_address_struct_value_sp32"
7414 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
7415 (match_operand 1 "" ""))
7416 (match_operand 2 "immediate_operand" "")
7417 (clobber (reg:SI 15))]
7418 ;;- Do not use operand 1 for most machines.
7419 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 0"
7420 "call\t%a0, %1\n\tnop\n\tunimp\t%2"
7421 [(set_attr "type" "call_no_delay_slot")
7422 (set_attr "length" "3")])
7424 ;; This is a call that wants a structure value.
7425 ;; There is no such critter for v9 (??? we may need one anyway).
7426 (define_insn "*call_symbolic_struct_value_sp32"
7427 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
7428 (match_operand 1 "" ""))
7429 (match_operand 2 "immediate_operand" "")
7430 (clobber (reg:SI 15))]
7431 ;;- Do not use operand 1 for most machines.
7432 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 0"
7433 "call\t%a0, %1\n\tnop\n\tunimp\t%2"
7434 [(set_attr "type" "call_no_delay_slot")
7435 (set_attr "length" "3")])
7437 ;; This is a call that may want a structure value. This is used for
7439 (define_insn "*call_address_untyped_struct_value_sp32"
7440 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
7441 (match_operand 1 "" ""))
7442 (match_operand 2 "immediate_operand" "")
7443 (clobber (reg:SI 15))]
7444 ;;- Do not use operand 1 for most machines.
7445 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
7446 "call\t%a0, %1\n\tnop\n\tnop"
7447 [(set_attr "type" "call_no_delay_slot")
7448 (set_attr "length" "3")])
7450 ;; This is a call that wants a structure value.
7451 (define_insn "*call_symbolic_untyped_struct_value_sp32"
7452 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
7453 (match_operand 1 "" ""))
7454 (match_operand 2 "immediate_operand" "")
7455 (clobber (reg:SI 15))]
7456 ;;- Do not use operand 1 for most machines.
7457 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
7458 "call\t%a0, %1\n\tnop\n\tnop"
7459 [(set_attr "type" "call_no_delay_slot")
7460 (set_attr "length" "3")])
7462 (define_expand "call_value"
7463 ;; Note that this expression is not used for generating RTL.
7464 ;; All the RTL is generated explicitly below.
7465 [(set (match_operand 0 "register_operand" "=rf")
7466 (call (match_operand 1 "" "")
7467 (match_operand 4 "" "")))]
7468 ;; operand 2 is stack_size_rtx
7469 ;; operand 3 is next_arg_register
7472 rtx fn_rtx, nregs_rtx;
7475 if (GET_MODE (operands[1]) != FUNCTION_MODE)
7478 fn_rtx = operands[1];
7482 nregs_rtx = GEN_INT (REGNO (operands[3]) - 8);
7484 nregs_rtx = GEN_INT (6);
7486 nregs_rtx = const0_rtx;
7490 gen_rtx_SET (VOIDmode, operands[0],
7491 gen_rtx_CALL (VOIDmode, fn_rtx, nregs_rtx)),
7492 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)));
7494 emit_call_insn (gen_rtx_PARALLEL (VOIDmode, vec));
7499 (define_insn "*call_value_address_sp32"
7500 [(set (match_operand 0 "" "=rf")
7501 (call (mem:SI (match_operand:SI 1 "address_operand" "p"))
7502 (match_operand 2 "" "")))
7503 (clobber (reg:SI 15))]
7504 ;;- Do not use operand 2 for most machines.
7507 [(set_attr "type" "call")])
7509 (define_insn "*call_value_symbolic_sp32"
7510 [(set (match_operand 0 "" "=rf")
7511 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
7512 (match_operand 2 "" "")))
7513 (clobber (reg:SI 15))]
7514 ;;- Do not use operand 2 for most machines.
7517 [(set_attr "type" "call")])
7519 (define_insn "*call_value_address_sp64"
7520 [(set (match_operand 0 "" "")
7521 (call (mem:DI (match_operand:DI 1 "address_operand" "p"))
7522 (match_operand 2 "" "")))
7523 (clobber (reg:DI 15))]
7524 ;;- Do not use operand 2 for most machines.
7527 [(set_attr "type" "call")])
7529 (define_insn "*call_value_symbolic_sp64"
7530 [(set (match_operand 0 "" "")
7531 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
7532 (match_operand 2 "" "")))
7533 (clobber (reg:DI 15))]
7534 ;;- Do not use operand 2 for most machines.
7537 [(set_attr "type" "call")])
7539 (define_expand "untyped_call"
7540 [(parallel [(call (match_operand 0 "" "")
7542 (match_operand 1 "" "")
7543 (match_operand 2 "" "")])]
7548 /* Pass constm1 to indicate that it may expect a structure value, but
7549 we don't know what size it is. */
7550 emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, constm1_rtx));
7552 for (i = 0; i < XVECLEN (operands[2], 0); i++)
7554 rtx set = XVECEXP (operands[2], 0, i);
7555 emit_move_insn (SET_DEST (set), SET_SRC (set));
7558 /* The optimizer does not know that the call sets the function value
7559 registers we stored in the result block. We avoid problems by
7560 claiming that all hard registers are used and clobbered at this
7562 emit_insn (gen_blockage ());
7568 (define_expand "sibcall"
7569 [(parallel [(call (match_operand 0 "call_operand" "") (const_int 0))
7574 (define_insn "*sibcall_symbolic_sp32"
7575 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
7576 (match_operand 1 "" ""))
7579 "* return output_sibcall(insn, operands[0]);"
7580 [(set_attr "type" "sibcall")])
7582 (define_insn "*sibcall_symbolic_sp64"
7583 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
7584 (match_operand 1 "" ""))
7587 "* return output_sibcall(insn, operands[0]);"
7588 [(set_attr "type" "sibcall")])
7590 (define_expand "sibcall_value"
7591 [(parallel [(set (match_operand 0 "register_operand" "=rf")
7592 (call (match_operand 1 "" "") (const_int 0)))
7597 (define_insn "*sibcall_value_symbolic_sp32"
7598 [(set (match_operand 0 "" "=rf")
7599 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
7600 (match_operand 2 "" "")))
7603 "* return output_sibcall(insn, operands[1]);"
7604 [(set_attr "type" "sibcall")])
7606 (define_insn "*sibcall_value_symbolic_sp64"
7607 [(set (match_operand 0 "" "")
7608 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
7609 (match_operand 2 "" "")))
7612 "* return output_sibcall(insn, operands[1]);"
7613 [(set_attr "type" "sibcall")])
7615 (define_expand "sibcall_epilogue"
7620 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
7621 ;; all of memory. This blocks insns from being moved across this point.
7623 (define_insn "blockage"
7624 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
7627 [(set_attr "length" "0")])
7629 ;; Prepare to return any type including a structure value.
7631 (define_expand "untyped_return"
7632 [(match_operand:BLK 0 "memory_operand" "")
7633 (match_operand 1 "" "")]
7636 rtx valreg1 = gen_rtx_REG (DImode, 24);
7637 rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
7638 rtx result = operands[0];
7640 if (! TARGET_ARCH64)
7642 rtx rtnreg = gen_rtx_REG (SImode, (current_function_uses_only_leaf_regs
7644 rtx value = gen_reg_rtx (SImode);
7646 /* Fetch the instruction where we will return to and see if it's an unimp
7647 instruction (the most significant 10 bits will be zero). If so,
7648 update the return address to skip the unimp instruction. */
7649 emit_move_insn (value,
7650 gen_rtx_MEM (SImode, plus_constant (rtnreg, 8)));
7651 emit_insn (gen_lshrsi3 (value, value, GEN_INT (22)));
7652 emit_insn (gen_update_return (rtnreg, value));
7655 /* Reload the function value registers. */
7656 emit_move_insn (valreg1, adjust_address (result, DImode, 0));
7657 emit_move_insn (valreg2,
7658 adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8));
7660 /* Put USE insns before the return. */
7661 emit_insn (gen_rtx_USE (VOIDmode, valreg1));
7662 emit_insn (gen_rtx_USE (VOIDmode, valreg2));
7664 /* Construct the return. */
7665 expand_null_return ();
7670 ;; This is a bit of a hack. We're incrementing a fixed register (%i7),
7671 ;; and parts of the compiler don't want to believe that the add is needed.
7673 (define_insn "update_return"
7674 [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
7675 (match_operand:SI 1 "register_operand" "r")] UNSPEC_UPDATE_RETURN)]
7677 "cmp\t%1, 0\;be,a\t.+8\;add\t%0, 4, %0"
7678 [(set_attr "type" "multi")
7679 (set_attr "length" "3")])
7686 (define_expand "indirect_jump"
7687 [(set (pc) (match_operand 0 "address_operand" "p"))]
7691 (define_insn "*branch_sp32"
7692 [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
7695 [(set_attr "type" "uncond_branch")])
7697 (define_insn "*branch_sp64"
7698 [(set (pc) (match_operand:DI 0 "address_operand" "p"))]
7701 [(set_attr "type" "uncond_branch")])
7703 ;; ??? Doesn't work with -mflat.
7704 (define_expand "nonlocal_goto"
7705 [(match_operand:SI 0 "general_operand" "")
7706 (match_operand:SI 1 "general_operand" "")
7707 (match_operand:SI 2 "general_operand" "")
7708 (match_operand:SI 3 "" "")]
7712 rtx chain = operands[0];
7714 rtx lab = operands[1];
7715 rtx stack = operands[2];
7716 rtx fp = operands[3];
7719 /* Trap instruction to flush all the register windows. */
7720 emit_insn (gen_flush_register_windows ());
7722 /* Load the fp value for the containing fn into %fp. This is needed
7723 because STACK refers to %fp. Note that virtual register instantiation
7724 fails if the virtual %fp isn't set from a register. */
7725 if (GET_CODE (fp) != REG)
7726 fp = force_reg (Pmode, fp);
7727 emit_move_insn (virtual_stack_vars_rtx, fp);
7729 /* Find the containing function's current nonlocal goto handler,
7730 which will do any cleanups and then jump to the label. */
7731 labreg = gen_rtx_REG (Pmode, 8);
7732 emit_move_insn (labreg, lab);
7734 /* Restore %fp from stack pointer value for containing function.
7735 The restore insn that follows will move this to %sp,
7736 and reload the appropriate value into %fp. */
7737 emit_move_insn (hard_frame_pointer_rtx, stack);
7739 /* USE of frame_pointer_rtx added for consistency; not clear if
7741 /*emit_insn (gen_rtx_USE (VOIDmode, frame_pointer_rtx));*/
7742 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
7745 /* Return, restoring reg window and jumping to goto handler. */
7746 if (TARGET_V9 && GET_CODE (chain) == CONST_INT
7747 && ! (INTVAL (chain) & ~(HOST_WIDE_INT)0xffffffff))
7749 emit_jump_insn (gen_goto_handler_and_restore_v9 (labreg,
7755 /* Put in the static chain register the nonlocal label address. */
7756 emit_move_insn (static_chain_rtx, chain);
7759 emit_insn (gen_rtx_USE (VOIDmode, static_chain_rtx));
7760 emit_jump_insn (gen_goto_handler_and_restore (labreg));
7765 ;; Special trap insn to flush register windows.
7766 (define_insn "flush_register_windows"
7767 [(unspec_volatile [(const_int 0)] UNSPECV_FLUSHW)]
7769 { return TARGET_V9 ? "flushw" : "ta\t3"; }
7770 [(set_attr "type" "flushw")])
7772 (define_insn "goto_handler_and_restore"
7773 [(unspec_volatile [(match_operand 0 "register_operand" "=r")] UNSPECV_GOTO)]
7774 "GET_MODE (operands[0]) == Pmode"
7775 "jmp\t%0+0\n\trestore"
7776 [(set_attr "type" "multi")
7777 (set_attr "length" "2")])
7779 ;;(define_insn "goto_handler_and_restore_v9"
7780 ;; [(unspec_volatile [(match_operand:SI 0 "register_operand" "=r,r")
7781 ;; (match_operand:SI 1 "register_operand" "=r,r")
7782 ;; (match_operand:SI 2 "const_int_operand" "I,n")] UNSPECV_GOTO_V9)]
7783 ;; "TARGET_V9 && ! TARGET_ARCH64"
7785 ;; return\t%0+0\n\tmov\t%2, %Y1
7786 ;; sethi\t%%hi(%2), %1\n\treturn\t%0+0\n\tor\t%Y1, %%lo(%2), %Y1"
7787 ;; [(set_attr "type" "multi")
7788 ;; (set_attr "length" "2,3")])
7790 ;;(define_insn "*goto_handler_and_restore_v9_sp64"
7791 ;; [(unspec_volatile [(match_operand:DI 0 "register_operand" "=r,r")
7792 ;; (match_operand:DI 1 "register_operand" "=r,r")
7793 ;; (match_operand:SI 2 "const_int_operand" "I,n")] UNSPECV_GOTO_V9)]
7794 ;; "TARGET_V9 && TARGET_ARCH64"
7796 ;; return\t%0+0\n\tmov\t%2, %Y1
7797 ;; sethi\t%%hi(%2), %1\n\treturn\t%0+0\n\tor\t%Y1, %%lo(%2), %Y1"
7798 ;; [(set_attr "type" "multi")
7799 ;; (set_attr "length" "2,3")])
7801 ;; For __builtin_setjmp we need to flush register windows iff the function
7802 ;; calls alloca as well, because otherwise the register window might be
7803 ;; saved after %sp adjustement and thus setjmp would crash
7804 (define_expand "builtin_setjmp_setup"
7805 [(match_operand 0 "register_operand" "r")]
7808 emit_insn (gen_do_builtin_setjmp_setup ());
7812 (define_insn "do_builtin_setjmp_setup"
7813 [(unspec_volatile [(const_int 0)] UNSPECV_SETJMP)]
7816 if (! current_function_calls_alloca)
7818 if (! TARGET_V9 || TARGET_FLAT)
7820 fputs ("\tflushw\n", asm_out_file);
7822 fprintf (asm_out_file, "\tst%c\t%%l7, [%%sp+%d]\n",
7823 TARGET_ARCH64 ? 'x' : 'w',
7824 SPARC_STACK_BIAS + 7 * UNITS_PER_WORD);
7825 fprintf (asm_out_file, "\tst%c\t%%fp, [%%sp+%d]\n",
7826 TARGET_ARCH64 ? 'x' : 'w',
7827 SPARC_STACK_BIAS + 14 * UNITS_PER_WORD);
7828 fprintf (asm_out_file, "\tst%c\t%%i7, [%%sp+%d]\n",
7829 TARGET_ARCH64 ? 'x' : 'w',
7830 SPARC_STACK_BIAS + 15 * UNITS_PER_WORD);
7833 [(set_attr "type" "multi")
7834 (set (attr "length")
7835 (cond [(eq_attr "current_function_calls_alloca" "false")
7837 (eq_attr "flat" "true")
7839 (eq_attr "isa" "!v9")
7841 (eq_attr "pic" "true")
7842 (const_int 4)] (const_int 3)))])
7844 ;; Pattern for use after a setjmp to store FP and the return register
7845 ;; into the stack area.
7847 (define_expand "setjmp"
7852 emit_insn (gen_setjmp_64 ());
7854 emit_insn (gen_setjmp_32 ());
7858 (define_expand "setjmp_32"
7859 [(set (mem:SI (plus:SI (reg:SI 14) (const_int 56))) (match_dup 0))
7860 (set (mem:SI (plus:SI (reg:SI 14) (const_int 60))) (reg:SI 31))]
7862 { operands[0] = frame_pointer_rtx; })
7864 (define_expand "setjmp_64"
7865 [(set (mem:DI (plus:DI (reg:DI 14) (const_int 112))) (match_dup 0))
7866 (set (mem:DI (plus:DI (reg:DI 14) (const_int 120))) (reg:DI 31))]
7868 { operands[0] = frame_pointer_rtx; })
7870 ;; Special pattern for the FLUSH instruction.
7872 ; We do SImode and DImode versions of this to quiet down genrecog's complaints
7873 ; of the define_insn otherwise missing a mode. We make "flush", aka
7874 ; gen_flush, the default one since sparc_initialize_trampoline uses
7875 ; it on SImode mem values.
7877 (define_insn "flush"
7878 [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")] UNSPECV_FLUSH)]
7880 { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; }
7881 [(set_attr "type" "iflush")])
7883 (define_insn "flushdi"
7884 [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")] UNSPECV_FLUSH)]
7886 { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; }
7887 [(set_attr "type" "iflush")])
7892 ;; The scan instruction searches from the most significant bit while ffs
7893 ;; searches from the least significant bit. The bit index and treatment of
7894 ;; zero also differ. It takes at least 7 instructions to get the proper
7895 ;; result. Here is an obvious 8 instruction sequence.
7898 (define_insn "ffssi2"
7899 [(set (match_operand:SI 0 "register_operand" "=&r")
7900 (ffs:SI (match_operand:SI 1 "register_operand" "r")))
7901 (clobber (match_scratch:SI 2 "=&r"))]
7902 "TARGET_SPARCLITE || TARGET_SPARCLET"
7904 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";
7906 [(set_attr "type" "multi")
7907 (set_attr "length" "8")])
7909 ;; ??? This should be a define expand, so that the extra instruction have
7910 ;; a chance of being optimized away.
7912 ;; Disabled because none of the UltraSPARCs implement popc. The HAL R1
7913 ;; does, but no one uses that and we don't have a switch for it.
7915 ;(define_insn "ffsdi2"
7916 ; [(set (match_operand:DI 0 "register_operand" "=&r")
7917 ; (ffs:DI (match_operand:DI 1 "register_operand" "r")))
7918 ; (clobber (match_scratch:DI 2 "=&r"))]
7920 ; "neg\t%1, %2\;xnor\t%1, %2, %2\;popc\t%2, %0\;movzr\t%1, 0, %0"
7921 ; [(set_attr "type" "multi")
7922 ; (set_attr "length" "4")])
7926 ;; Peepholes go at the end.
7928 ;; Optimize consecutive loads or stores into ldd and std when possible.
7929 ;; The conditions in which we do this are very restricted and are
7930 ;; explained in the code for {registers,memory}_ok_for_ldd functions.
7933 [(set (match_operand:SI 0 "memory_operand" "")
7935 (set (match_operand:SI 1 "memory_operand" "")
7938 && mems_ok_for_ldd_peep (operands[0], operands[1], NULL_RTX)"
7941 "operands[0] = change_address (operands[0], DImode, NULL);")
7944 [(set (match_operand:SI 0 "memory_operand" "")
7946 (set (match_operand:SI 1 "memory_operand" "")
7949 && mems_ok_for_ldd_peep (operands[1], operands[0], NULL_RTX)"
7952 "operands[1] = change_address (operands[1], DImode, NULL);")
7955 [(set (match_operand:SI 0 "register_operand" "")
7956 (match_operand:SI 1 "memory_operand" ""))
7957 (set (match_operand:SI 2 "register_operand" "")
7958 (match_operand:SI 3 "memory_operand" ""))]
7959 "registers_ok_for_ldd_peep (operands[0], operands[2])
7960 && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
7963 "operands[1] = change_address (operands[1], DImode, NULL);
7964 operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));")
7967 [(set (match_operand:SI 0 "memory_operand" "")
7968 (match_operand:SI 1 "register_operand" ""))
7969 (set (match_operand:SI 2 "memory_operand" "")
7970 (match_operand:SI 3 "register_operand" ""))]
7971 "registers_ok_for_ldd_peep (operands[1], operands[3])
7972 && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
7975 "operands[0] = change_address (operands[0], DImode, NULL);
7976 operands[1] = gen_rtx_REG (DImode, REGNO (operands[1]));")
7979 [(set (match_operand:SF 0 "register_operand" "")
7980 (match_operand:SF 1 "memory_operand" ""))
7981 (set (match_operand:SF 2 "register_operand" "")
7982 (match_operand:SF 3 "memory_operand" ""))]
7983 "registers_ok_for_ldd_peep (operands[0], operands[2])
7984 && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
7987 "operands[1] = change_address (operands[1], DFmode, NULL);
7988 operands[0] = gen_rtx_REG (DFmode, REGNO (operands[0]));")
7991 [(set (match_operand:SF 0 "memory_operand" "")
7992 (match_operand:SF 1 "register_operand" ""))
7993 (set (match_operand:SF 2 "memory_operand" "")
7994 (match_operand:SF 3 "register_operand" ""))]
7995 "registers_ok_for_ldd_peep (operands[1], operands[3])
7996 && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
7999 "operands[0] = change_address (operands[0], DFmode, NULL);
8000 operands[1] = gen_rtx_REG (DFmode, REGNO (operands[1]));")
8003 [(set (match_operand:SI 0 "register_operand" "")
8004 (match_operand:SI 1 "memory_operand" ""))
8005 (set (match_operand:SI 2 "register_operand" "")
8006 (match_operand:SI 3 "memory_operand" ""))]
8007 "registers_ok_for_ldd_peep (operands[2], operands[0])
8008 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
8011 "operands[3] = change_address (operands[3], DImode, NULL);
8012 operands[2] = gen_rtx_REG (DImode, REGNO (operands[2]));")
8015 [(set (match_operand:SI 0 "memory_operand" "")
8016 (match_operand:SI 1 "register_operand" ""))
8017 (set (match_operand:SI 2 "memory_operand" "")
8018 (match_operand:SI 3 "register_operand" ""))]
8019 "registers_ok_for_ldd_peep (operands[3], operands[1])
8020 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
8023 "operands[2] = change_address (operands[2], DImode, NULL);
8024 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
8028 [(set (match_operand:SF 0 "register_operand" "")
8029 (match_operand:SF 1 "memory_operand" ""))
8030 (set (match_operand:SF 2 "register_operand" "")
8031 (match_operand:SF 3 "memory_operand" ""))]
8032 "registers_ok_for_ldd_peep (operands[2], operands[0])
8033 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
8036 "operands[3] = change_address (operands[3], DFmode, NULL);
8037 operands[2] = gen_rtx_REG (DFmode, REGNO (operands[2]));")
8040 [(set (match_operand:SF 0 "memory_operand" "")
8041 (match_operand:SF 1 "register_operand" ""))
8042 (set (match_operand:SF 2 "memory_operand" "")
8043 (match_operand:SF 3 "register_operand" ""))]
8044 "registers_ok_for_ldd_peep (operands[3], operands[1])
8045 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
8048 "operands[2] = change_address (operands[2], DFmode, NULL);
8049 operands[3] = gen_rtx_REG (DFmode, REGNO (operands[3]));")
8051 ;; Optimize the case of following a reg-reg move with a test
8052 ;; of reg just moved. Don't allow floating point regs for operand 0 or 1.
8053 ;; This can result from a float to fix conversion.
8056 [(set (match_operand:SI 0 "register_operand" "")
8057 (match_operand:SI 1 "register_operand" ""))
8059 (compare:CC (match_operand:SI 2 "register_operand" "")
8061 "(rtx_equal_p (operands[2], operands[0])
8062 || rtx_equal_p (operands[2], operands[1]))
8063 && ! SPARC_FP_REG_P (REGNO (operands[0]))
8064 && ! SPARC_FP_REG_P (REGNO (operands[1]))"
8065 [(parallel [(set (match_dup 0) (match_dup 1))
8067 (compare:CC (match_dup 1) (const_int 0)))])]
8071 [(set (match_operand:DI 0 "register_operand" "")
8072 (match_operand:DI 1 "register_operand" ""))
8074 (compare:CCX (match_operand:DI 2 "register_operand" "")
8077 && (rtx_equal_p (operands[2], operands[0])
8078 || rtx_equal_p (operands[2], operands[1]))
8079 && ! SPARC_FP_REG_P (REGNO (operands[0]))
8080 && ! SPARC_FP_REG_P (REGNO (operands[1]))"
8081 [(parallel [(set (match_dup 0) (match_dup 1))
8083 (compare:CCX (match_dup 1) (const_int 0)))])]
8086 ;; Return peepholes. These are generated by sparc_nonflat_function_epilogue
8087 ;; who then immediately calls final_scan_insn.
8089 (define_insn "*return_qi"
8090 [(set (match_operand:QI 0 "restore_operand" "")
8091 (match_operand:QI 1 "arith_operand" "rI"))
8093 "sparc_emitting_epilogue"
8095 if (! TARGET_ARCH64 && current_function_returns_struct)
8096 return "jmp\t%%i7+12\n\trestore %%g0, %1, %Y0";
8097 else if (TARGET_V9 && (GET_CODE (operands[1]) == CONST_INT
8098 || IN_OR_GLOBAL_P (operands[1])))
8099 return "return\t%%i7+8\n\tmov\t%Y1, %Y0";
8101 return "ret\n\trestore %%g0, %1, %Y0";
8103 [(set_attr "type" "multi")
8104 (set_attr "length" "2")])
8106 (define_insn "*return_hi"
8107 [(set (match_operand:HI 0 "restore_operand" "")
8108 (match_operand:HI 1 "arith_operand" "rI"))
8110 "sparc_emitting_epilogue"
8112 if (! TARGET_ARCH64 && current_function_returns_struct)
8113 return "jmp\t%%i7+12\n\trestore %%g0, %1, %Y0";
8114 else if (TARGET_V9 && (GET_CODE (operands[1]) == CONST_INT
8115 || IN_OR_GLOBAL_P (operands[1])))
8116 return "return\t%%i7+8\n\tmov\t%Y1, %Y0";
8118 return "ret\;restore %%g0, %1, %Y0";
8120 [(set_attr "type" "multi")
8121 (set_attr "length" "2")])
8123 (define_insn "*return_si"
8124 [(set (match_operand:SI 0 "restore_operand" "")
8125 (match_operand:SI 1 "arith_operand" "rI"))
8127 "sparc_emitting_epilogue"
8129 if (! TARGET_ARCH64 && current_function_returns_struct)
8130 return "jmp\t%%i7+12\n\trestore %%g0, %1, %Y0";
8131 else if (TARGET_V9 && (GET_CODE (operands[1]) == CONST_INT
8132 || IN_OR_GLOBAL_P (operands[1])))
8133 return "return\t%%i7+8\n\tmov\t%Y1, %Y0";
8135 return "ret\;restore %%g0, %1, %Y0";
8137 [(set_attr "type" "multi")
8138 (set_attr "length" "2")])
8140 (define_insn "*return_sf_no_fpu"
8141 [(set (match_operand:SF 0 "restore_operand" "=r")
8142 (match_operand:SF 1 "register_operand" "r"))
8144 "sparc_emitting_epilogue"
8146 if (! TARGET_ARCH64 && current_function_returns_struct)
8147 return "jmp\t%%i7+12\n\trestore %%g0, %1, %Y0";
8148 else if (TARGET_V9 && IN_OR_GLOBAL_P (operands[1]))
8149 return "return\t%%i7+8\n\tmov\t%Y1, %Y0";
8151 return "ret\;restore %%g0, %1, %Y0";
8153 [(set_attr "type" "multi")
8154 (set_attr "length" "2")])
8156 (define_insn "*return_df_no_fpu"
8157 [(set (match_operand:DF 0 "restore_operand" "=r")
8158 (match_operand:DF 1 "register_operand" "r"))
8160 "sparc_emitting_epilogue && TARGET_ARCH64"
8162 if (IN_OR_GLOBAL_P (operands[1]))
8163 return "return\t%%i7+8\n\tmov\t%Y1, %Y0";
8165 return "ret\;restore %%g0, %1, %Y0";
8167 [(set_attr "type" "multi")
8168 (set_attr "length" "2")])
8170 (define_insn "*return_addsi"
8171 [(set (match_operand:SI 0 "restore_operand" "")
8172 (plus:SI (match_operand:SI 1 "register_operand" "r")
8173 (match_operand:SI 2 "arith_operand" "rI")))
8175 "sparc_emitting_epilogue"
8177 if (! TARGET_ARCH64 && current_function_returns_struct)
8178 return "jmp\t%%i7+12\n\trestore %r1, %2, %Y0";
8179 /* If operands are global or in registers, can use return */
8180 else if (TARGET_V9 && IN_OR_GLOBAL_P (operands[1])
8181 && (GET_CODE (operands[2]) == CONST_INT
8182 || IN_OR_GLOBAL_P (operands[2])))
8183 return "return\t%%i7+8\n\tadd\t%Y1, %Y2, %Y0";
8185 return "ret\;restore %r1, %2, %Y0";
8187 [(set_attr "type" "multi")
8188 (set_attr "length" "2")])
8190 (define_insn "*return_losum_si"
8191 [(set (match_operand:SI 0 "restore_operand" "")
8192 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
8193 (match_operand:SI 2 "immediate_operand" "in")))
8195 "sparc_emitting_epilogue && ! TARGET_CM_MEDMID"
8197 if (! TARGET_ARCH64 && current_function_returns_struct)
8198 return "jmp\t%%i7+12\n\trestore %r1, %%lo(%a2), %Y0";
8199 /* If operands are global or in registers, can use return */
8200 else if (TARGET_V9 && IN_OR_GLOBAL_P (operands[1]))
8201 return "return\t%%i7+8\n\tor\t%Y1, %%lo(%a2), %Y0";
8203 return "ret\;restore %r1, %%lo(%a2), %Y0";
8205 [(set_attr "type" "multi")
8206 (set_attr "length" "2")])
8208 (define_insn "*return_di"
8209 [(set (match_operand:DI 0 "restore_operand" "")
8210 (match_operand:DI 1 "arith_double_operand" "rHI"))
8212 "sparc_emitting_epilogue && TARGET_ARCH64"
8213 "ret\;restore %%g0, %1, %Y0"
8214 [(set_attr "type" "multi")
8215 (set_attr "length" "2")])
8217 (define_insn "*return_adddi"
8218 [(set (match_operand:DI 0 "restore_operand" "")
8219 (plus:DI (match_operand:DI 1 "arith_operand" "%r")
8220 (match_operand:DI 2 "arith_double_operand" "rHI")))
8222 "sparc_emitting_epilogue && TARGET_ARCH64"
8223 "ret\;restore %r1, %2, %Y0"
8224 [(set_attr "type" "multi")
8225 (set_attr "length" "2")])
8227 (define_insn "*return_losum_di"
8228 [(set (match_operand:DI 0 "restore_operand" "")
8229 (lo_sum:DI (match_operand:DI 1 "arith_operand" "%r")
8230 (match_operand:DI 2 "immediate_operand" "in")))
8232 "sparc_emitting_epilogue && TARGET_ARCH64 && ! TARGET_CM_MEDMID"
8233 "ret\;restore %r1, %%lo(%a2), %Y0"
8234 [(set_attr "type" "multi")
8235 (set_attr "length" "2")])
8237 (define_insn "*return_sf"
8239 (match_operand:SF 0 "register_operand" "f"))
8241 "sparc_emitting_epilogue"
8242 "ret\;fmovs\t%0, %%f0"
8243 [(set_attr "type" "multi")
8244 (set_attr "length" "2")])
8246 ;; Now peepholes to do a call followed by a jump.
8249 [(parallel [(set (match_operand 0 "" "")
8250 (call (mem:SI (match_operand:SI 1 "call_operand_address" "ps"))
8251 (match_operand 2 "" "")))
8252 (clobber (reg:SI 15))])
8253 (set (pc) (label_ref (match_operand 3 "" "")))]
8254 "short_branch (INSN_UID (insn), INSN_UID (operands[3]))
8255 && (USING_SJLJ_EXCEPTIONS || ! can_throw_internal (ins1))
8256 && sparc_cpu != PROCESSOR_ULTRASPARC
8257 && sparc_cpu != PROCESSOR_ULTRASPARC3"
8258 "call\t%a1, %2\n\tadd\t%%o7, (%l3-.-4), %%o7")
8261 [(parallel [(call (mem:SI (match_operand:SI 0 "call_operand_address" "ps"))
8262 (match_operand 1 "" ""))
8263 (clobber (reg:SI 15))])
8264 (set (pc) (label_ref (match_operand 2 "" "")))]
8265 "short_branch (INSN_UID (insn), INSN_UID (operands[2]))
8266 && (USING_SJLJ_EXCEPTIONS || ! can_throw_internal (ins1))
8267 && sparc_cpu != PROCESSOR_ULTRASPARC
8268 && sparc_cpu != PROCESSOR_ULTRASPARC3"
8269 "call\t%a0, %1\n\tadd\t%%o7, (%l2-.-4), %%o7")
8271 ;; ??? UltraSPARC-III note: A memory operation loading into the floating point register
8272 ;; ??? file, if it hits the prefetch cache, has a chance to dual-issue with other memory
8273 ;; ??? operations. With DFA we might be able to model this, but it requires a lot of
8275 (define_expand "prefetch"
8276 [(match_operand 0 "address_operand" "")
8277 (match_operand 1 "const_int_operand" "")
8278 (match_operand 2 "const_int_operand" "")]
8282 emit_insn (gen_prefetch_64 (operands[0], operands[1], operands[2]));
8284 emit_insn (gen_prefetch_32 (operands[0], operands[1], operands[2]));
8288 (define_insn "prefetch_64"
8289 [(prefetch (match_operand:DI 0 "address_operand" "p")
8290 (match_operand:DI 1 "const_int_operand" "n")
8291 (match_operand:DI 2 "const_int_operand" "n"))]
8294 static const char * const prefetch_instr[2][2] = {
8296 "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
8297 "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
8300 "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
8301 "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
8304 int read_or_write = INTVAL (operands[1]);
8305 int locality = INTVAL (operands[2]);
8307 if (read_or_write != 0 && read_or_write != 1)
8309 if (locality < 0 || locality > 3)
8311 return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
8313 [(set_attr "type" "load")])
8315 (define_insn "prefetch_32"
8316 [(prefetch (match_operand:SI 0 "address_operand" "p")
8317 (match_operand:SI 1 "const_int_operand" "n")
8318 (match_operand:SI 2 "const_int_operand" "n"))]
8321 static const char * const prefetch_instr[2][2] = {
8323 "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
8324 "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
8327 "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
8328 "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
8331 int read_or_write = INTVAL (operands[1]);
8332 int locality = INTVAL (operands[2]);
8334 if (read_or_write != 0 && read_or_write != 1)
8336 if (locality < 0 || locality > 3)
8338 return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
8340 [(set_attr "type" "load")])
8342 (define_expand "prologue"
8344 "flag_pic && current_function_uses_pic_offset_table"
8346 load_pic_register ();
8350 ;; We need to reload %l7 for -mflat -fpic,
8351 ;; otherwise %l7 should be preserved simply
8352 ;; by loading the function's register window
8353 (define_expand "exception_receiver"
8355 "TARGET_FLAT && flag_pic"
8357 load_pic_register ();
8362 (define_expand "builtin_setjmp_receiver"
8363 [(label_ref (match_operand 0 "" ""))]
8364 "TARGET_FLAT && flag_pic"
8366 load_pic_register ();
8371 [(trap_if (const_int 1) (const_int 5))]
8374 [(set_attr "type" "trap")])
8376 (define_expand "conditional_trap"
8377 [(trap_if (match_operator 0 "noov_compare_op"
8378 [(match_dup 2) (match_dup 3)])
8379 (match_operand:SI 1 "arith_operand" ""))]
8381 "operands[2] = gen_compare_reg (GET_CODE (operands[0]),
8382 sparc_compare_op0, sparc_compare_op1);
8383 operands[3] = const0_rtx;")
8386 [(trap_if (match_operator 0 "noov_compare_op" [(reg:CC 100) (const_int 0)])
8387 (match_operand:SI 1 "arith_operand" "rM"))]
8390 [(set_attr "type" "trap")])
8393 [(trap_if (match_operator 0 "noov_compare_op" [(reg:CCX 100) (const_int 0)])
8394 (match_operand:SI 1 "arith_operand" "rM"))]
8397 [(set_attr "type" "trap")])