1 ;; Machine description for SPARC chip for GCC
2 ;; Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
3 ;; 1999, 2000, 2001, 2002, 2003, 2004 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 GCC.
10 ;; GCC 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 ;; GCC 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 GCC; 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)
30 (UNSPEC_LOAD_PCREL_SYM 2)
31 (UNSPEC_MOVE_PIC_LABEL 5)
37 (UNSPEC_EMB_TEXTUHI 13)
38 (UNSPEC_EMB_TEXTHI 14)
39 (UNSPEC_EMB_TEXTULO 15)
47 (UNSPEC_TLSLD_BASE 35)
59 ;; The upper 32 fp regs on the v9 can't hold SFmode values. To deal with this
60 ;; a second register class, EXTRA_FP_REGS, exists for the v9 chip. The name
61 ;; is a bit of a misnomer as it covers all 64 fp regs. The corresponding
62 ;; constraint letter is 'e'. To avoid any confusion, 'e' is used instead of
63 ;; 'f' for all DF/TFmode values, including those that are specific to the v8.
65 ;; Attribute for cpu type.
66 ;; These must match the values for enum processor_type in sparc.h.
73 hypersparc,sparclite86x,
78 (const (symbol_ref "sparc_cpu_attr")))
80 ;; Attribute for the instruction set.
81 ;; At present we only need to distinguish v9/!v9, but for clarity we
82 ;; test TARGET_V8 too.
83 (define_attr "isa" "v7,v8,v9,sparclet"
85 (cond [(symbol_ref "TARGET_V9") (const_string "v9")
86 (symbol_ref "TARGET_V8") (const_string "v8")
87 (symbol_ref "TARGET_SPARCLET") (const_string "sparclet")]
88 (const_string "v7"))))
94 uncond_branch,branch,call,sibcall,call_no_delay_slot,return,
102 fga,fgm_pack,fgm_mul,fgm_pdist,fgm_cmp,
105 multi,savew,flushw,iflush,trap"
106 (const_string "ialu"))
108 ;; True if branch/call has empty delay slot and will emit a nop in it
109 (define_attr "empty_delay_slot" "false,true"
110 (symbol_ref "empty_delay_slot (insn)"))
112 (define_attr "branch_type" "none,icc,fcc,reg"
113 (const_string "none"))
115 (define_attr "pic" "false,true"
116 (symbol_ref "flag_pic != 0"))
118 (define_attr "calls_alloca" "false,true"
119 (symbol_ref "current_function_calls_alloca != 0"))
121 (define_attr "calls_eh_return" "false,true"
122 (symbol_ref "current_function_calls_eh_return !=0 "))
124 (define_attr "leaf_function" "false,true"
125 (symbol_ref "current_function_uses_only_leaf_regs != 0"))
127 (define_attr "delayed_branch" "false,true"
128 (symbol_ref "flag_delayed_branch != 0"))
130 ;; Length (in # of insns).
131 (define_attr "length" ""
132 (cond [(eq_attr "type" "uncond_branch,call")
133 (if_then_else (eq_attr "empty_delay_slot" "true")
136 (eq_attr "type" "sibcall")
137 (if_then_else (eq_attr "leaf_function" "true")
138 (if_then_else (eq_attr "empty_delay_slot" "true")
141 (if_then_else (eq_attr "empty_delay_slot" "true")
144 (eq_attr "branch_type" "icc")
145 (if_then_else (match_operand 0 "noov_compare64_op" "")
146 (if_then_else (lt (pc) (match_dup 1))
147 (if_then_else (lt (minus (match_dup 1) (pc)) (const_int 260000))
148 (if_then_else (eq_attr "empty_delay_slot" "true")
151 (if_then_else (eq_attr "empty_delay_slot" "true")
154 (if_then_else (lt (minus (pc) (match_dup 1)) (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 (eq_attr "empty_delay_slot" "true")
164 (eq_attr "branch_type" "fcc")
165 (if_then_else (match_operand 0 "fcc0_reg_operand" "")
166 (if_then_else (eq_attr "empty_delay_slot" "true")
167 (if_then_else (eq (symbol_ref "TARGET_V9") (const_int 0))
170 (if_then_else (eq (symbol_ref "TARGET_V9") (const_int 0))
173 (if_then_else (lt (pc) (match_dup 2))
174 (if_then_else (lt (minus (match_dup 2) (pc)) (const_int 260000))
175 (if_then_else (eq_attr "empty_delay_slot" "true")
178 (if_then_else (eq_attr "empty_delay_slot" "true")
181 (if_then_else (lt (minus (pc) (match_dup 2)) (const_int 260000))
182 (if_then_else (eq_attr "empty_delay_slot" "true")
185 (if_then_else (eq_attr "empty_delay_slot" "true")
188 (eq_attr "branch_type" "reg")
189 (if_then_else (lt (pc) (match_dup 2))
190 (if_then_else (lt (minus (match_dup 2) (pc)) (const_int 32000))
191 (if_then_else (eq_attr "empty_delay_slot" "true")
194 (if_then_else (eq_attr "empty_delay_slot" "true")
197 (if_then_else (lt (minus (pc) (match_dup 2)) (const_int 32000))
198 (if_then_else (eq_attr "empty_delay_slot" "true")
201 (if_then_else (eq_attr "empty_delay_slot" "true")
207 (define_attr "fptype" "single,double"
208 (const_string "single"))
210 ;; UltraSPARC-III integer load type.
211 (define_attr "us3load_type" "2cycle,3cycle"
212 (const_string "2cycle"))
214 (define_asm_attributes
215 [(set_attr "length" "2")
216 (set_attr "type" "multi")])
218 ;; Attributes for instruction and branch scheduling
219 (define_attr "tls_call_delay" "false,true"
220 (symbol_ref "tls_call_delay (insn)"))
222 (define_attr "in_call_delay" "false,true"
223 (cond [(eq_attr "type" "uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
224 (const_string "false")
225 (eq_attr "type" "load,fpload,store,fpstore")
226 (if_then_else (eq_attr "length" "1")
227 (const_string "true")
228 (const_string "false"))]
229 (if_then_else (and (eq_attr "length" "1")
230 (eq_attr "tls_call_delay" "true"))
231 (const_string "true")
232 (const_string "false"))))
234 (define_attr "eligible_for_sibcall_delay" "false,true"
235 (symbol_ref "eligible_for_sibcall_delay (insn)"))
237 (define_attr "eligible_for_return_delay" "false,true"
238 (symbol_ref "eligible_for_return_delay (insn)"))
240 ;; ??? !v9: Should implement the notion of predelay slots for floating-point
241 ;; branches. This would allow us to remove the nop always inserted before
242 ;; a floating point branch.
244 ;; ??? It is OK for fill_simple_delay_slots to put load/store instructions
245 ;; in a delay slot, but it is not OK for fill_eager_delay_slots to do so.
246 ;; This is because doing so will add several pipeline stalls to the path
247 ;; that the load/store did not come from. Unfortunately, there is no way
248 ;; to prevent fill_eager_delay_slots from using load/store without completely
249 ;; disabling them. For the SPEC benchmark set, this is a serious lose,
250 ;; because it prevents us from moving back the final store of inner loops.
252 (define_attr "in_branch_delay" "false,true"
253 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
254 (eq_attr "length" "1"))
255 (const_string "true")
256 (const_string "false")))
258 (define_attr "in_uncond_branch_delay" "false,true"
259 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
260 (eq_attr "length" "1"))
261 (const_string "true")
262 (const_string "false")))
264 (define_attr "in_annul_branch_delay" "false,true"
265 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
266 (eq_attr "length" "1"))
267 (const_string "true")
268 (const_string "false")))
270 (define_delay (eq_attr "type" "call")
271 [(eq_attr "in_call_delay" "true") (nil) (nil)])
273 (define_delay (eq_attr "type" "sibcall")
274 [(eq_attr "eligible_for_sibcall_delay" "true") (nil) (nil)])
276 (define_delay (eq_attr "type" "branch")
277 [(eq_attr "in_branch_delay" "true")
278 (nil) (eq_attr "in_annul_branch_delay" "true")])
280 (define_delay (eq_attr "type" "uncond_branch")
281 [(eq_attr "in_uncond_branch_delay" "true")
284 (define_delay (eq_attr "type" "return")
285 [(eq_attr "eligible_for_return_delay" "true") (nil) (nil)])
287 ;; Include SPARC DFA schedulers
289 (include "cypress.md")
290 (include "supersparc.md")
291 (include "hypersparc.md")
292 (include "sparclet.md")
293 (include "ultra1_2.md")
294 (include "ultra3.md")
297 ;; Compare instructions.
298 ;; This controls RTL generation and register allocation.
300 ;; We generate RTL for comparisons and branches by having the cmpxx
301 ;; patterns store away the operands. Then, the scc and bcc patterns
302 ;; emit RTL for both the compare and the branch.
304 ;; We do this because we want to generate different code for an sne and
305 ;; seq insn. In those cases, if the second operand of the compare is not
306 ;; const0_rtx, we want to compute the xor of the two operands and test
309 ;; We start with the DEFINE_EXPANDs, then the DEFINE_INSNs to match
310 ;; the patterns. Finally, we have the DEFINE_SPLITs for some of the scc
311 ;; insns that actually require more than one machine instruction.
313 ;; Put cmpsi first among compare insns so it matches two CONST_INT operands.
315 (define_expand "cmpsi"
317 (compare:CC (match_operand:SI 0 "compare_operand" "")
318 (match_operand:SI 1 "arith_operand" "")))]
321 if (GET_CODE (operands[0]) == ZERO_EXTRACT && operands[1] != const0_rtx)
322 operands[0] = force_reg (SImode, operands[0]);
324 sparc_compare_op0 = operands[0];
325 sparc_compare_op1 = operands[1];
329 (define_expand "cmpdi"
331 (compare:CCX (match_operand:DI 0 "compare_operand" "")
332 (match_operand:DI 1 "arith_double_operand" "")))]
335 if (GET_CODE (operands[0]) == ZERO_EXTRACT && operands[1] != const0_rtx)
336 operands[0] = force_reg (DImode, operands[0]);
338 sparc_compare_op0 = operands[0];
339 sparc_compare_op1 = operands[1];
343 (define_expand "cmpsf"
344 ;; The 96 here isn't ever used by anyone.
346 (compare:CCFP (match_operand:SF 0 "register_operand" "")
347 (match_operand:SF 1 "register_operand" "")))]
350 sparc_compare_op0 = operands[0];
351 sparc_compare_op1 = operands[1];
355 (define_expand "cmpdf"
356 ;; The 96 here isn't ever used by anyone.
358 (compare:CCFP (match_operand:DF 0 "register_operand" "")
359 (match_operand:DF 1 "register_operand" "")))]
362 sparc_compare_op0 = operands[0];
363 sparc_compare_op1 = operands[1];
367 (define_expand "cmptf"
368 ;; The 96 here isn't ever used by anyone.
370 (compare:CCFP (match_operand:TF 0 "register_operand" "")
371 (match_operand:TF 1 "register_operand" "")))]
374 sparc_compare_op0 = operands[0];
375 sparc_compare_op1 = operands[1];
379 ;; Now the compare DEFINE_INSNs.
381 (define_insn "*cmpsi_insn"
383 (compare:CC (match_operand:SI 0 "register_operand" "r")
384 (match_operand:SI 1 "arith_operand" "rI")))]
387 [(set_attr "type" "compare")])
389 (define_insn "*cmpdi_sp64"
391 (compare:CCX (match_operand:DI 0 "register_operand" "r")
392 (match_operand:DI 1 "arith_double_operand" "rHI")))]
395 [(set_attr "type" "compare")])
397 (define_insn "*cmpsf_fpe"
398 [(set (match_operand:CCFPE 0 "fcc_reg_operand" "=c")
399 (compare:CCFPE (match_operand:SF 1 "register_operand" "f")
400 (match_operand:SF 2 "register_operand" "f")))]
404 return "fcmpes\t%0, %1, %2";
405 return "fcmpes\t%1, %2";
407 [(set_attr "type" "fpcmp")])
409 (define_insn "*cmpdf_fpe"
410 [(set (match_operand:CCFPE 0 "fcc_reg_operand" "=c")
411 (compare:CCFPE (match_operand:DF 1 "register_operand" "e")
412 (match_operand:DF 2 "register_operand" "e")))]
416 return "fcmped\t%0, %1, %2";
417 return "fcmped\t%1, %2";
419 [(set_attr "type" "fpcmp")
420 (set_attr "fptype" "double")])
422 (define_insn "*cmptf_fpe"
423 [(set (match_operand:CCFPE 0 "fcc_reg_operand" "=c")
424 (compare:CCFPE (match_operand:TF 1 "register_operand" "e")
425 (match_operand:TF 2 "register_operand" "e")))]
426 "TARGET_FPU && TARGET_HARD_QUAD"
429 return "fcmpeq\t%0, %1, %2";
430 return "fcmpeq\t%1, %2";
432 [(set_attr "type" "fpcmp")])
434 (define_insn "*cmpsf_fp"
435 [(set (match_operand:CCFP 0 "fcc_reg_operand" "=c")
436 (compare:CCFP (match_operand:SF 1 "register_operand" "f")
437 (match_operand:SF 2 "register_operand" "f")))]
441 return "fcmps\t%0, %1, %2";
442 return "fcmps\t%1, %2";
444 [(set_attr "type" "fpcmp")])
446 (define_insn "*cmpdf_fp"
447 [(set (match_operand:CCFP 0 "fcc_reg_operand" "=c")
448 (compare:CCFP (match_operand:DF 1 "register_operand" "e")
449 (match_operand:DF 2 "register_operand" "e")))]
453 return "fcmpd\t%0, %1, %2";
454 return "fcmpd\t%1, %2";
456 [(set_attr "type" "fpcmp")
457 (set_attr "fptype" "double")])
459 (define_insn "*cmptf_fp"
460 [(set (match_operand:CCFP 0 "fcc_reg_operand" "=c")
461 (compare:CCFP (match_operand:TF 1 "register_operand" "e")
462 (match_operand:TF 2 "register_operand" "e")))]
463 "TARGET_FPU && TARGET_HARD_QUAD"
466 return "fcmpq\t%0, %1, %2";
467 return "fcmpq\t%1, %2";
469 [(set_attr "type" "fpcmp")])
471 ;; Next come the scc insns. For seq, sne, sgeu, and sltu, we can do this
472 ;; without jumps using the addx/subx instructions. For seq/sne on v9 we use
473 ;; the same code as v8 (the addx/subx method has more applications). The
474 ;; exception to this is "reg != 0" which can be done in one instruction on v9
475 ;; (so we do it). For the rest, on v9 we use conditional moves; on v8, we do
478 ;; Seq_special[_xxx] and sne_special[_xxx] clobber the CC reg, because they
479 ;; generate addcc/subcc instructions.
481 (define_expand "seqsi_special"
483 (xor:SI (match_operand:SI 1 "register_operand" "")
484 (match_operand:SI 2 "register_operand" "")))
485 (parallel [(set (match_operand:SI 0 "register_operand" "")
486 (eq:SI (match_dup 3) (const_int 0)))
487 (clobber (reg:CC 100))])]
489 { operands[3] = gen_reg_rtx (SImode); })
491 (define_expand "seqdi_special"
493 (xor:DI (match_operand:DI 1 "register_operand" "")
494 (match_operand:DI 2 "register_operand" "")))
495 (set (match_operand:DI 0 "register_operand" "")
496 (eq:DI (match_dup 3) (const_int 0)))]
498 { operands[3] = gen_reg_rtx (DImode); })
500 (define_expand "snesi_special"
502 (xor:SI (match_operand:SI 1 "register_operand" "")
503 (match_operand:SI 2 "register_operand" "")))
504 (parallel [(set (match_operand:SI 0 "register_operand" "")
505 (ne:SI (match_dup 3) (const_int 0)))
506 (clobber (reg:CC 100))])]
508 { operands[3] = gen_reg_rtx (SImode); })
510 (define_expand "snedi_special"
512 (xor:DI (match_operand:DI 1 "register_operand" "")
513 (match_operand:DI 2 "register_operand" "")))
514 (set (match_operand:DI 0 "register_operand" "")
515 (ne:DI (match_dup 3) (const_int 0)))]
517 { operands[3] = gen_reg_rtx (DImode); })
519 (define_expand "seqdi_special_trunc"
521 (xor:DI (match_operand:DI 1 "register_operand" "")
522 (match_operand:DI 2 "register_operand" "")))
523 (set (match_operand:SI 0 "register_operand" "")
524 (eq:SI (match_dup 3) (const_int 0)))]
526 { operands[3] = gen_reg_rtx (DImode); })
528 (define_expand "snedi_special_trunc"
530 (xor:DI (match_operand:DI 1 "register_operand" "")
531 (match_operand:DI 2 "register_operand" "")))
532 (set (match_operand:SI 0 "register_operand" "")
533 (ne:SI (match_dup 3) (const_int 0)))]
535 { operands[3] = gen_reg_rtx (DImode); })
537 (define_expand "seqsi_special_extend"
539 (xor:SI (match_operand:SI 1 "register_operand" "")
540 (match_operand:SI 2 "register_operand" "")))
541 (parallel [(set (match_operand:DI 0 "register_operand" "")
542 (eq:DI (match_dup 3) (const_int 0)))
543 (clobber (reg:CC 100))])]
545 { operands[3] = gen_reg_rtx (SImode); })
547 (define_expand "snesi_special_extend"
549 (xor:SI (match_operand:SI 1 "register_operand" "")
550 (match_operand:SI 2 "register_operand" "")))
551 (parallel [(set (match_operand:DI 0 "register_operand" "")
552 (ne:DI (match_dup 3) (const_int 0)))
553 (clobber (reg:CC 100))])]
555 { operands[3] = gen_reg_rtx (SImode); })
557 ;; ??? v9: Operand 0 needs a mode, so SImode was chosen.
558 ;; However, the code handles both SImode and DImode.
560 [(set (match_operand:SI 0 "intreg_operand" "")
561 (eq:SI (match_dup 1) (const_int 0)))]
564 if (GET_MODE (sparc_compare_op0) == SImode)
568 if (GET_MODE (operands[0]) == SImode)
569 pat = gen_seqsi_special (operands[0], sparc_compare_op0,
571 else if (! TARGET_ARCH64)
574 pat = gen_seqsi_special_extend (operands[0], sparc_compare_op0,
579 else if (GET_MODE (sparc_compare_op0) == DImode)
585 else if (GET_MODE (operands[0]) == SImode)
586 pat = gen_seqdi_special_trunc (operands[0], sparc_compare_op0,
589 pat = gen_seqdi_special (operands[0], sparc_compare_op0,
594 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
596 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, EQ);
597 emit_jump_insn (gen_sne (operands[0]));
602 if (gen_v9_scc (EQ, operands))
609 ;; ??? v9: Operand 0 needs a mode, so SImode was chosen.
610 ;; However, the code handles both SImode and DImode.
612 [(set (match_operand:SI 0 "intreg_operand" "")
613 (ne:SI (match_dup 1) (const_int 0)))]
616 if (GET_MODE (sparc_compare_op0) == SImode)
620 if (GET_MODE (operands[0]) == SImode)
621 pat = gen_snesi_special (operands[0], sparc_compare_op0,
623 else if (! TARGET_ARCH64)
626 pat = gen_snesi_special_extend (operands[0], sparc_compare_op0,
631 else if (GET_MODE (sparc_compare_op0) == DImode)
637 else if (GET_MODE (operands[0]) == SImode)
638 pat = gen_snedi_special_trunc (operands[0], sparc_compare_op0,
641 pat = gen_snedi_special (operands[0], sparc_compare_op0,
646 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
648 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, NE);
649 emit_jump_insn (gen_sne (operands[0]));
654 if (gen_v9_scc (NE, operands))
662 [(set (match_operand:SI 0 "intreg_operand" "")
663 (gt:SI (match_dup 1) (const_int 0)))]
666 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
668 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GT);
669 emit_jump_insn (gen_sne (operands[0]));
674 if (gen_v9_scc (GT, operands))
682 [(set (match_operand:SI 0 "intreg_operand" "")
683 (lt:SI (match_dup 1) (const_int 0)))]
686 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
688 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LT);
689 emit_jump_insn (gen_sne (operands[0]));
694 if (gen_v9_scc (LT, operands))
702 [(set (match_operand:SI 0 "intreg_operand" "")
703 (ge:SI (match_dup 1) (const_int 0)))]
706 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
708 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GE);
709 emit_jump_insn (gen_sne (operands[0]));
714 if (gen_v9_scc (GE, operands))
722 [(set (match_operand:SI 0 "intreg_operand" "")
723 (le:SI (match_dup 1) (const_int 0)))]
726 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
728 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LE);
729 emit_jump_insn (gen_sne (operands[0]));
734 if (gen_v9_scc (LE, operands))
741 (define_expand "sgtu"
742 [(set (match_operand:SI 0 "intreg_operand" "")
743 (gtu:SI (match_dup 1) (const_int 0)))]
750 /* We can do ltu easily, so if both operands are registers, swap them and
752 if ((GET_CODE (sparc_compare_op0) == REG
753 || GET_CODE (sparc_compare_op0) == SUBREG)
754 && (GET_CODE (sparc_compare_op1) == REG
755 || GET_CODE (sparc_compare_op1) == SUBREG))
757 tem = sparc_compare_op0;
758 sparc_compare_op0 = sparc_compare_op1;
759 sparc_compare_op1 = tem;
760 pat = gen_sltu (operands[0]);
769 if (gen_v9_scc (GTU, operands))
775 (define_expand "sltu"
776 [(set (match_operand:SI 0 "intreg_operand" "")
777 (ltu:SI (match_dup 1) (const_int 0)))]
782 if (gen_v9_scc (LTU, operands))
785 operands[1] = gen_compare_reg (LTU, sparc_compare_op0, sparc_compare_op1);
788 (define_expand "sgeu"
789 [(set (match_operand:SI 0 "intreg_operand" "")
790 (geu:SI (match_dup 1) (const_int 0)))]
795 if (gen_v9_scc (GEU, operands))
798 operands[1] = gen_compare_reg (GEU, sparc_compare_op0, sparc_compare_op1);
801 (define_expand "sleu"
802 [(set (match_operand:SI 0 "intreg_operand" "")
803 (leu:SI (match_dup 1) (const_int 0)))]
810 /* We can do geu easily, so if both operands are registers, swap them and
812 if ((GET_CODE (sparc_compare_op0) == REG
813 || GET_CODE (sparc_compare_op0) == SUBREG)
814 && (GET_CODE (sparc_compare_op1) == REG
815 || GET_CODE (sparc_compare_op1) == SUBREG))
817 tem = sparc_compare_op0;
818 sparc_compare_op0 = sparc_compare_op1;
819 sparc_compare_op1 = tem;
820 pat = gen_sgeu (operands[0]);
829 if (gen_v9_scc (LEU, operands))
835 ;; Now the DEFINE_INSNs for the scc cases.
837 ;; The SEQ and SNE patterns are special because they can be done
838 ;; without any branching and do not involve a COMPARE. We want
839 ;; them to always use the splitz below so the results can be
842 (define_insn_and_split "*snesi_zero"
843 [(set (match_operand:SI 0 "register_operand" "=r")
844 (ne:SI (match_operand:SI 1 "register_operand" "r")
846 (clobber (reg:CC 100))]
850 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
852 (set (match_dup 0) (ltu:SI (reg:CC 100) (const_int 0)))]
854 [(set_attr "length" "2")])
856 (define_insn_and_split "*neg_snesi_zero"
857 [(set (match_operand:SI 0 "register_operand" "=r")
858 (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
860 (clobber (reg:CC 100))]
864 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
866 (set (match_dup 0) (neg:SI (ltu:SI (reg:CC 100) (const_int 0))))]
868 [(set_attr "length" "2")])
870 (define_insn_and_split "*snesi_zero_extend"
871 [(set (match_operand:DI 0 "register_operand" "=r")
872 (ne:DI (match_operand:SI 1 "register_operand" "r")
874 (clobber (reg:CC 100))]
878 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (minus:SI (const_int 0)
881 (set (match_dup 0) (zero_extend:DI (plus:SI (plus:SI (const_int 0)
883 (ltu:SI (reg:CC_NOOV 100)
886 [(set_attr "length" "2")])
888 (define_insn_and_split "*snedi_zero"
889 [(set (match_operand:DI 0 "register_operand" "=&r")
890 (ne:DI (match_operand:DI 1 "register_operand" "r")
894 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
895 [(set (match_dup 0) (const_int 0))
896 (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
901 [(set_attr "length" "2")])
903 (define_insn_and_split "*neg_snedi_zero"
904 [(set (match_operand:DI 0 "register_operand" "=&r")
905 (neg:DI (ne:DI (match_operand:DI 1 "register_operand" "r")
909 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
910 [(set (match_dup 0) (const_int 0))
911 (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
916 [(set_attr "length" "2")])
918 (define_insn_and_split "*snedi_zero_trunc"
919 [(set (match_operand:SI 0 "register_operand" "=&r")
920 (ne:SI (match_operand:DI 1 "register_operand" "r")
924 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
925 [(set (match_dup 0) (const_int 0))
926 (set (match_dup 0) (if_then_else:SI (ne:DI (match_dup 1)
931 [(set_attr "length" "2")])
933 (define_insn_and_split "*seqsi_zero"
934 [(set (match_operand:SI 0 "register_operand" "=r")
935 (eq:SI (match_operand:SI 1 "register_operand" "r")
937 (clobber (reg:CC 100))]
941 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
943 (set (match_dup 0) (geu:SI (reg:CC 100) (const_int 0)))]
945 [(set_attr "length" "2")])
947 (define_insn_and_split "*neg_seqsi_zero"
948 [(set (match_operand:SI 0 "register_operand" "=r")
949 (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
951 (clobber (reg:CC 100))]
955 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
957 (set (match_dup 0) (neg:SI (geu:SI (reg:CC 100) (const_int 0))))]
959 [(set_attr "length" "2")])
961 (define_insn_and_split "*seqsi_zero_extend"
962 [(set (match_operand:DI 0 "register_operand" "=r")
963 (eq:DI (match_operand:SI 1 "register_operand" "r")
965 (clobber (reg:CC 100))]
969 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (minus:SI (const_int 0)
972 (set (match_dup 0) (zero_extend:DI (minus:SI (minus:SI (const_int 0)
974 (ltu:SI (reg:CC_NOOV 100)
977 [(set_attr "length" "2")])
979 (define_insn_and_split "*seqdi_zero"
980 [(set (match_operand:DI 0 "register_operand" "=&r")
981 (eq:DI (match_operand:DI 1 "register_operand" "r")
985 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
986 [(set (match_dup 0) (const_int 0))
987 (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
992 [(set_attr "length" "2")])
994 (define_insn_and_split "*neg_seqdi_zero"
995 [(set (match_operand:DI 0 "register_operand" "=&r")
996 (neg:DI (eq:DI (match_operand:DI 1 "register_operand" "r")
1000 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
1001 [(set (match_dup 0) (const_int 0))
1002 (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
1007 [(set_attr "length" "2")])
1009 (define_insn_and_split "*seqdi_zero_trunc"
1010 [(set (match_operand:SI 0 "register_operand" "=&r")
1011 (eq:SI (match_operand:DI 1 "register_operand" "r")
1015 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
1016 [(set (match_dup 0) (const_int 0))
1017 (set (match_dup 0) (if_then_else:SI (eq:DI (match_dup 1)
1022 [(set_attr "length" "2")])
1024 ;; We can also do (x + (i == 0)) and related, so put them in.
1025 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1028 (define_insn_and_split "*x_plus_i_ne_0"
1029 [(set (match_operand:SI 0 "register_operand" "=r")
1030 (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
1032 (match_operand:SI 2 "register_operand" "r")))
1033 (clobber (reg:CC 100))]
1037 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1039 (set (match_dup 0) (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1042 [(set_attr "length" "2")])
1044 (define_insn_and_split "*x_minus_i_ne_0"
1045 [(set (match_operand:SI 0 "register_operand" "=r")
1046 (minus:SI (match_operand:SI 2 "register_operand" "r")
1047 (ne:SI (match_operand:SI 1 "register_operand" "r")
1049 (clobber (reg:CC 100))]
1053 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1055 (set (match_dup 0) (minus:SI (match_dup 2)
1056 (ltu:SI (reg:CC 100) (const_int 0))))]
1058 [(set_attr "length" "2")])
1060 (define_insn_and_split "*x_plus_i_eq_0"
1061 [(set (match_operand:SI 0 "register_operand" "=r")
1062 (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
1064 (match_operand:SI 2 "register_operand" "r")))
1065 (clobber (reg:CC 100))]
1069 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1071 (set (match_dup 0) (plus:SI (geu:SI (reg:CC 100) (const_int 0))
1074 [(set_attr "length" "2")])
1076 (define_insn_and_split "*x_minus_i_eq_0"
1077 [(set (match_operand:SI 0 "register_operand" "=r")
1078 (minus:SI (match_operand:SI 2 "register_operand" "r")
1079 (eq:SI (match_operand:SI 1 "register_operand" "r")
1081 (clobber (reg:CC 100))]
1085 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1087 (set (match_dup 0) (minus:SI (match_dup 2)
1088 (geu:SI (reg:CC 100) (const_int 0))))]
1090 [(set_attr "length" "2")])
1092 ;; We can also do GEU and LTU directly, but these operate after a compare.
1093 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1096 (define_insn "*sltu_insn"
1097 [(set (match_operand:SI 0 "register_operand" "=r")
1098 (ltu:SI (reg:CC 100) (const_int 0)))]
1101 [(set_attr "type" "ialuX")])
1103 (define_insn "*neg_sltu_insn"
1104 [(set (match_operand:SI 0 "register_operand" "=r")
1105 (neg:SI (ltu:SI (reg:CC 100) (const_int 0))))]
1108 [(set_attr "type" "ialuX")])
1110 ;; ??? Combine should canonicalize these next two to the same pattern.
1111 (define_insn "*neg_sltu_minus_x"
1112 [(set (match_operand:SI 0 "register_operand" "=r")
1113 (minus:SI (neg:SI (ltu:SI (reg:CC 100) (const_int 0)))
1114 (match_operand:SI 1 "arith_operand" "rI")))]
1116 "subx\t%%g0, %1, %0"
1117 [(set_attr "type" "ialuX")])
1119 (define_insn "*neg_sltu_plus_x"
1120 [(set (match_operand:SI 0 "register_operand" "=r")
1121 (neg:SI (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1122 (match_operand:SI 1 "arith_operand" "rI"))))]
1124 "subx\t%%g0, %1, %0"
1125 [(set_attr "type" "ialuX")])
1127 (define_insn "*sgeu_insn"
1128 [(set (match_operand:SI 0 "register_operand" "=r")
1129 (geu:SI (reg:CC 100) (const_int 0)))]
1131 "subx\t%%g0, -1, %0"
1132 [(set_attr "type" "ialuX")])
1134 (define_insn "*neg_sgeu_insn"
1135 [(set (match_operand:SI 0 "register_operand" "=r")
1136 (neg:SI (geu:SI (reg:CC 100) (const_int 0))))]
1138 "addx\t%%g0, -1, %0"
1139 [(set_attr "type" "ialuX")])
1141 ;; We can also do (x + ((unsigned) i >= 0)) and related, so put them in.
1142 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1145 (define_insn "*sltu_plus_x"
1146 [(set (match_operand:SI 0 "register_operand" "=r")
1147 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1148 (match_operand:SI 1 "arith_operand" "rI")))]
1150 "addx\t%%g0, %1, %0"
1151 [(set_attr "type" "ialuX")])
1153 (define_insn "*sltu_plus_x_plus_y"
1154 [(set (match_operand:SI 0 "register_operand" "=r")
1155 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1156 (plus:SI (match_operand:SI 1 "arith_operand" "%r")
1157 (match_operand:SI 2 "arith_operand" "rI"))))]
1160 [(set_attr "type" "ialuX")])
1162 (define_insn "*x_minus_sltu"
1163 [(set (match_operand:SI 0 "register_operand" "=r")
1164 (minus:SI (match_operand:SI 1 "register_operand" "r")
1165 (ltu:SI (reg:CC 100) (const_int 0))))]
1168 [(set_attr "type" "ialuX")])
1170 ;; ??? Combine should canonicalize these next two to the same pattern.
1171 (define_insn "*x_minus_y_minus_sltu"
1172 [(set (match_operand:SI 0 "register_operand" "=r")
1173 (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
1174 (match_operand:SI 2 "arith_operand" "rI"))
1175 (ltu:SI (reg:CC 100) (const_int 0))))]
1178 [(set_attr "type" "ialuX")])
1180 (define_insn "*x_minus_sltu_plus_y"
1181 [(set (match_operand:SI 0 "register_operand" "=r")
1182 (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
1183 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1184 (match_operand:SI 2 "arith_operand" "rI"))))]
1187 [(set_attr "type" "ialuX")])
1189 (define_insn "*sgeu_plus_x"
1190 [(set (match_operand:SI 0 "register_operand" "=r")
1191 (plus:SI (geu:SI (reg:CC 100) (const_int 0))
1192 (match_operand:SI 1 "register_operand" "r")))]
1195 [(set_attr "type" "ialuX")])
1197 (define_insn "*x_minus_sgeu"
1198 [(set (match_operand:SI 0 "register_operand" "=r")
1199 (minus:SI (match_operand:SI 1 "register_operand" "r")
1200 (geu:SI (reg:CC 100) (const_int 0))))]
1203 [(set_attr "type" "ialuX")])
1206 [(set (match_operand:SI 0 "register_operand" "")
1207 (match_operator:SI 2 "noov_compare_op"
1208 [(match_operand 1 "icc_or_fcc_reg_operand" "")
1210 ;; 32 bit LTU/GEU are better implemented using addx/subx
1211 "TARGET_V9 && REGNO (operands[1]) == SPARC_ICC_REG
1212 && (GET_MODE (operands[1]) == CCXmode
1213 || (GET_CODE (operands[2]) != LTU && GET_CODE (operands[2]) != GEU))"
1214 [(set (match_dup 0) (const_int 0))
1216 (if_then_else:SI (match_op_dup:SI 2 [(match_dup 1) (const_int 0)])
1222 ;; These control RTL generation for conditional jump insns
1224 ;; The quad-word fp compare library routines all return nonzero to indicate
1225 ;; true, which is different from the equivalent libgcc routines, so we must
1226 ;; handle them specially here.
1228 (define_expand "beq"
1230 (if_then_else (eq (match_dup 1) (const_int 0))
1231 (label_ref (match_operand 0 "" ""))
1235 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1236 && GET_CODE (sparc_compare_op0) == REG
1237 && GET_MODE (sparc_compare_op0) == DImode)
1239 emit_v9_brxx_insn (EQ, sparc_compare_op0, operands[0]);
1242 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1244 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, EQ);
1245 emit_jump_insn (gen_bne (operands[0]));
1248 operands[1] = gen_compare_reg (EQ, sparc_compare_op0, sparc_compare_op1);
1251 (define_expand "bne"
1253 (if_then_else (ne (match_dup 1) (const_int 0))
1254 (label_ref (match_operand 0 "" ""))
1258 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1259 && GET_CODE (sparc_compare_op0) == REG
1260 && GET_MODE (sparc_compare_op0) == DImode)
1262 emit_v9_brxx_insn (NE, sparc_compare_op0, operands[0]);
1265 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1267 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, NE);
1268 emit_jump_insn (gen_bne (operands[0]));
1271 operands[1] = gen_compare_reg (NE, sparc_compare_op0, sparc_compare_op1);
1274 (define_expand "bgt"
1276 (if_then_else (gt (match_dup 1) (const_int 0))
1277 (label_ref (match_operand 0 "" ""))
1281 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1282 && GET_CODE (sparc_compare_op0) == REG
1283 && GET_MODE (sparc_compare_op0) == DImode)
1285 emit_v9_brxx_insn (GT, sparc_compare_op0, operands[0]);
1288 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1290 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GT);
1291 emit_jump_insn (gen_bne (operands[0]));
1294 operands[1] = gen_compare_reg (GT, sparc_compare_op0, sparc_compare_op1);
1297 (define_expand "bgtu"
1299 (if_then_else (gtu (match_dup 1) (const_int 0))
1300 (label_ref (match_operand 0 "" ""))
1304 operands[1] = gen_compare_reg (GTU, sparc_compare_op0, sparc_compare_op1);
1307 (define_expand "blt"
1309 (if_then_else (lt (match_dup 1) (const_int 0))
1310 (label_ref (match_operand 0 "" ""))
1314 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1315 && GET_CODE (sparc_compare_op0) == REG
1316 && GET_MODE (sparc_compare_op0) == DImode)
1318 emit_v9_brxx_insn (LT, sparc_compare_op0, operands[0]);
1321 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1323 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LT);
1324 emit_jump_insn (gen_bne (operands[0]));
1327 operands[1] = gen_compare_reg (LT, sparc_compare_op0, sparc_compare_op1);
1330 (define_expand "bltu"
1332 (if_then_else (ltu (match_dup 1) (const_int 0))
1333 (label_ref (match_operand 0 "" ""))
1337 operands[1] = gen_compare_reg (LTU, sparc_compare_op0, sparc_compare_op1);
1340 (define_expand "bge"
1342 (if_then_else (ge (match_dup 1) (const_int 0))
1343 (label_ref (match_operand 0 "" ""))
1347 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1348 && GET_CODE (sparc_compare_op0) == REG
1349 && GET_MODE (sparc_compare_op0) == DImode)
1351 emit_v9_brxx_insn (GE, sparc_compare_op0, operands[0]);
1354 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1356 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GE);
1357 emit_jump_insn (gen_bne (operands[0]));
1360 operands[1] = gen_compare_reg (GE, sparc_compare_op0, sparc_compare_op1);
1363 (define_expand "bgeu"
1365 (if_then_else (geu (match_dup 1) (const_int 0))
1366 (label_ref (match_operand 0 "" ""))
1370 operands[1] = gen_compare_reg (GEU, sparc_compare_op0, sparc_compare_op1);
1373 (define_expand "ble"
1375 (if_then_else (le (match_dup 1) (const_int 0))
1376 (label_ref (match_operand 0 "" ""))
1380 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1381 && GET_CODE (sparc_compare_op0) == REG
1382 && GET_MODE (sparc_compare_op0) == DImode)
1384 emit_v9_brxx_insn (LE, sparc_compare_op0, operands[0]);
1387 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1389 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LE);
1390 emit_jump_insn (gen_bne (operands[0]));
1393 operands[1] = gen_compare_reg (LE, sparc_compare_op0, sparc_compare_op1);
1396 (define_expand "bleu"
1398 (if_then_else (leu (match_dup 1) (const_int 0))
1399 (label_ref (match_operand 0 "" ""))
1403 operands[1] = gen_compare_reg (LEU, sparc_compare_op0, sparc_compare_op1);
1406 (define_expand "bunordered"
1408 (if_then_else (unordered (match_dup 1) (const_int 0))
1409 (label_ref (match_operand 0 "" ""))
1413 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1415 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1,
1417 emit_jump_insn (gen_beq (operands[0]));
1420 operands[1] = gen_compare_reg (UNORDERED, sparc_compare_op0,
1424 (define_expand "bordered"
1426 (if_then_else (ordered (match_dup 1) (const_int 0))
1427 (label_ref (match_operand 0 "" ""))
1431 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1433 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, ORDERED);
1434 emit_jump_insn (gen_bne (operands[0]));
1437 operands[1] = gen_compare_reg (ORDERED, sparc_compare_op0,
1441 (define_expand "bungt"
1443 (if_then_else (ungt (match_dup 1) (const_int 0))
1444 (label_ref (match_operand 0 "" ""))
1448 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1450 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNGT);
1451 emit_jump_insn (gen_bgt (operands[0]));
1454 operands[1] = gen_compare_reg (UNGT, sparc_compare_op0, sparc_compare_op1);
1457 (define_expand "bunlt"
1459 (if_then_else (unlt (match_dup 1) (const_int 0))
1460 (label_ref (match_operand 0 "" ""))
1464 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1466 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNLT);
1467 emit_jump_insn (gen_bne (operands[0]));
1470 operands[1] = gen_compare_reg (UNLT, sparc_compare_op0, sparc_compare_op1);
1473 (define_expand "buneq"
1475 (if_then_else (uneq (match_dup 1) (const_int 0))
1476 (label_ref (match_operand 0 "" ""))
1480 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1482 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNEQ);
1483 emit_jump_insn (gen_beq (operands[0]));
1486 operands[1] = gen_compare_reg (UNEQ, sparc_compare_op0, sparc_compare_op1);
1489 (define_expand "bunge"
1491 (if_then_else (unge (match_dup 1) (const_int 0))
1492 (label_ref (match_operand 0 "" ""))
1496 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1498 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNGE);
1499 emit_jump_insn (gen_bne (operands[0]));
1502 operands[1] = gen_compare_reg (UNGE, sparc_compare_op0, sparc_compare_op1);
1505 (define_expand "bunle"
1507 (if_then_else (unle (match_dup 1) (const_int 0))
1508 (label_ref (match_operand 0 "" ""))
1512 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1514 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNLE);
1515 emit_jump_insn (gen_bne (operands[0]));
1518 operands[1] = gen_compare_reg (UNLE, sparc_compare_op0, sparc_compare_op1);
1521 (define_expand "bltgt"
1523 (if_then_else (ltgt (match_dup 1) (const_int 0))
1524 (label_ref (match_operand 0 "" ""))
1528 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1530 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LTGT);
1531 emit_jump_insn (gen_bne (operands[0]));
1534 operands[1] = gen_compare_reg (LTGT, sparc_compare_op0, sparc_compare_op1);
1537 ;; Now match both normal and inverted jump.
1539 ;; XXX fpcmp nop braindamage
1540 (define_insn "*normal_branch"
1542 (if_then_else (match_operator 0 "noov_compare_op"
1543 [(reg 100) (const_int 0)])
1544 (label_ref (match_operand 1 "" ""))
1548 return output_cbranch (operands[0], operands[1], 1, 0,
1549 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1550 ! final_sequence, insn);
1552 [(set_attr "type" "branch")
1553 (set_attr "branch_type" "icc")])
1555 ;; XXX fpcmp nop braindamage
1556 (define_insn "*inverted_branch"
1558 (if_then_else (match_operator 0 "noov_compare_op"
1559 [(reg 100) (const_int 0)])
1561 (label_ref (match_operand 1 "" ""))))]
1564 return output_cbranch (operands[0], operands[1], 1, 1,
1565 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1566 ! final_sequence, insn);
1568 [(set_attr "type" "branch")
1569 (set_attr "branch_type" "icc")])
1571 ;; XXX fpcmp nop braindamage
1572 (define_insn "*normal_fp_branch"
1574 (if_then_else (match_operator 1 "comparison_operator"
1575 [(match_operand:CCFP 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_fp_branch"
1591 (if_then_else (match_operator 1 "comparison_operator"
1592 [(match_operand:CCFP 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 ;; XXX fpcmp nop braindamage
1606 (define_insn "*normal_fpe_branch"
1608 (if_then_else (match_operator 1 "comparison_operator"
1609 [(match_operand:CCFPE 0 "fcc_reg_operand" "c")
1611 (label_ref (match_operand 2 "" ""))
1615 return output_cbranch (operands[1], operands[2], 2, 0,
1616 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1617 ! final_sequence, insn);
1619 [(set_attr "type" "branch")
1620 (set_attr "branch_type" "fcc")])
1622 ;; XXX fpcmp nop braindamage
1623 (define_insn "*inverted_fpe_branch"
1625 (if_then_else (match_operator 1 "comparison_operator"
1626 [(match_operand:CCFPE 0 "fcc_reg_operand" "c")
1629 (label_ref (match_operand 2 "" ""))))]
1632 return output_cbranch (operands[1], operands[2], 2, 1,
1633 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1634 ! final_sequence, insn);
1636 [(set_attr "type" "branch")
1637 (set_attr "branch_type" "fcc")])
1639 ;; SPARC V9-specific jump insns. None of these are guaranteed to be
1640 ;; in the architecture.
1642 ;; There are no 32 bit brreg insns.
1645 (define_insn "*normal_int_branch_sp64"
1647 (if_then_else (match_operator 0 "v9_regcmp_op"
1648 [(match_operand:DI 1 "register_operand" "r")
1650 (label_ref (match_operand 2 "" ""))
1654 return output_v9branch (operands[0], operands[2], 1, 2, 0,
1655 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1656 ! final_sequence, insn);
1658 [(set_attr "type" "branch")
1659 (set_attr "branch_type" "reg")])
1662 (define_insn "*inverted_int_branch_sp64"
1664 (if_then_else (match_operator 0 "v9_regcmp_op"
1665 [(match_operand:DI 1 "register_operand" "r")
1668 (label_ref (match_operand 2 "" ""))))]
1671 return output_v9branch (operands[0], operands[2], 1, 2, 1,
1672 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1673 ! final_sequence, insn);
1675 [(set_attr "type" "branch")
1676 (set_attr "branch_type" "reg")])
1678 ;; Load in operand 0 the (absolute) address of operand 1, which is a symbolic
1679 ;; value subject to a PC-relative relocation. Operand 2 is a helper function
1680 ;; that adds the PC value at the call point to operand 0.
1682 (define_insn "load_pcrel_sym"
1683 [(set (match_operand 0 "register_operand" "=r")
1684 (unspec [(match_operand 1 "symbolic_operand" "")
1685 (match_operand 2 "call_operand_address" "")] UNSPEC_LOAD_PCREL_SYM))
1686 (clobber (reg:SI 15))]
1689 if (flag_delayed_branch)
1690 return "sethi\t%%hi(%a1-4), %0\n\tcall\t%a2\n\t add\t%0, %%lo(%a1+4), %0";
1692 return "sethi\t%%hi(%a1-8), %0\n\tadd\t%0, %%lo(%a1-4), %0\n\tcall\t%a2\n\t nop";
1694 [(set (attr "type") (const_string "multi"))
1695 (set (attr "length")
1696 (if_then_else (eq_attr "delayed_branch" "true")
1700 ;; Move instructions
1702 (define_expand "movqi"
1703 [(set (match_operand:QI 0 "general_operand" "")
1704 (match_operand:QI 1 "general_operand" ""))]
1707 /* Working with CONST_INTs is easier, so convert
1708 a double if needed. */
1709 if (GET_CODE (operands[1]) == CONST_DOUBLE)
1711 operands[1] = GEN_INT (trunc_int_for_mode
1712 (CONST_DOUBLE_LOW (operands[1]), QImode));
1715 /* Handle sets of MEM first. */
1716 if (GET_CODE (operands[0]) == MEM)
1718 if (reg_or_0_operand (operands[1], QImode))
1721 if (! reload_in_progress)
1723 operands[0] = validize_mem (operands[0]);
1724 operands[1] = force_reg (QImode, operands[1]);
1728 /* Fixup TLS cases. */
1729 if (tls_symbolic_operand (operands [1]))
1730 operands[1] = legitimize_tls_address (operands[1]);
1732 /* Fixup PIC cases. */
1735 if (CONSTANT_P (operands[1])
1736 && pic_address_needs_scratch (operands[1]))
1737 operands[1] = legitimize_pic_address (operands[1], QImode, 0);
1739 if (symbolic_operand (operands[1], QImode))
1741 operands[1] = legitimize_pic_address (operands[1],
1743 (reload_in_progress ?
1750 /* All QI constants require only one insn, so proceed. */
1756 (define_insn "*movqi_insn"
1757 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m")
1758 (match_operand:QI 1 "input_operand" "rI,m,rJ"))]
1759 "(register_operand (operands[0], QImode)
1760 || reg_or_0_operand (operands[1], QImode))"
1765 [(set_attr "type" "*,load,store")
1766 (set_attr "us3load_type" "*,3cycle,*")])
1768 (define_expand "movhi"
1769 [(set (match_operand:HI 0 "general_operand" "")
1770 (match_operand:HI 1 "general_operand" ""))]
1773 /* Working with CONST_INTs is easier, so convert
1774 a double if needed. */
1775 if (GET_CODE (operands[1]) == CONST_DOUBLE)
1776 operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
1778 /* Handle sets of MEM first. */
1779 if (GET_CODE (operands[0]) == MEM)
1781 if (reg_or_0_operand (operands[1], HImode))
1784 if (! reload_in_progress)
1786 operands[0] = validize_mem (operands[0]);
1787 operands[1] = force_reg (HImode, operands[1]);
1791 /* Fixup TLS cases. */
1792 if (tls_symbolic_operand (operands [1]))
1793 operands[1] = legitimize_tls_address (operands[1]);
1795 /* Fixup PIC cases. */
1798 if (CONSTANT_P (operands[1])
1799 && pic_address_needs_scratch (operands[1]))
1800 operands[1] = legitimize_pic_address (operands[1], HImode, 0);
1802 if (symbolic_operand (operands[1], HImode))
1804 operands[1] = legitimize_pic_address (operands[1],
1806 (reload_in_progress ?
1813 /* This makes sure we will not get rematched due to splittage. */
1814 if (! CONSTANT_P (operands[1]) || input_operand (operands[1], HImode))
1816 else if (CONSTANT_P (operands[1])
1817 && GET_CODE (operands[1]) != HIGH
1818 && GET_CODE (operands[1]) != LO_SUM)
1820 sparc_emit_set_const32 (operands[0], operands[1]);
1827 (define_insn "*movhi_const64_special"
1828 [(set (match_operand:HI 0 "register_operand" "=r")
1829 (match_operand:HI 1 "const64_high_operand" ""))]
1831 "sethi\t%%hi(%a1), %0")
1833 (define_insn "*movhi_insn"
1834 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1835 (match_operand:HI 1 "input_operand" "rI,K,m,rJ"))]
1836 "(register_operand (operands[0], HImode)
1837 || reg_or_0_operand (operands[1], HImode))"
1840 sethi\t%%hi(%a1), %0
1843 [(set_attr "type" "*,*,load,store")
1844 (set_attr "us3load_type" "*,*,3cycle,*")])
1846 ;; We always work with constants here.
1847 (define_insn "*movhi_lo_sum"
1848 [(set (match_operand:HI 0 "register_operand" "=r")
1849 (ior:HI (match_operand:HI 1 "register_operand" "%r")
1850 (match_operand:HI 2 "small_int" "I")))]
1854 (define_expand "movsi"
1855 [(set (match_operand:SI 0 "general_operand" "")
1856 (match_operand:SI 1 "general_operand" ""))]
1859 /* Working with CONST_INTs is easier, so convert
1860 a double if needed. */
1861 if (GET_CODE (operands[1]) == CONST_DOUBLE)
1862 operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
1864 /* Handle sets of MEM first. */
1865 if (GET_CODE (operands[0]) == MEM)
1867 if (reg_or_0_operand (operands[1], SImode))
1870 if (! reload_in_progress)
1872 operands[0] = validize_mem (operands[0]);
1873 operands[1] = force_reg (SImode, operands[1]);
1877 /* Fixup TLS cases. */
1878 if (tls_symbolic_operand (operands [1]))
1879 operands[1] = legitimize_tls_address (operands[1]);
1881 /* Fixup PIC cases. */
1884 if (CONSTANT_P (operands[1])
1885 && pic_address_needs_scratch (operands[1]))
1886 operands[1] = legitimize_pic_address (operands[1], SImode, 0);
1888 if (GET_CODE (operands[1]) == LABEL_REF)
1891 emit_insn (gen_movsi_pic_label_ref (operands[0], operands[1]));
1895 if (symbolic_operand (operands[1], SImode))
1897 operands[1] = legitimize_pic_address (operands[1],
1899 (reload_in_progress ?
1906 /* If we are trying to toss an integer constant into the
1907 FPU registers, force it into memory. */
1908 if (GET_CODE (operands[0]) == REG
1909 && REGNO (operands[0]) >= SPARC_FIRST_FP_REG
1910 && REGNO (operands[0]) <= SPARC_LAST_V9_FP_REG
1911 && CONSTANT_P (operands[1]))
1912 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
1915 /* This makes sure we will not get rematched due to splittage. */
1916 if (! CONSTANT_P (operands[1]) || input_operand (operands[1], SImode))
1918 else if (CONSTANT_P (operands[1])
1919 && GET_CODE (operands[1]) != HIGH
1920 && GET_CODE (operands[1]) != LO_SUM)
1922 sparc_emit_set_const32 (operands[0], operands[1]);
1929 ;; This is needed to show CSE exactly which bits are set
1930 ;; in a 64-bit register by sethi instructions.
1931 (define_insn "*movsi_const64_special"
1932 [(set (match_operand:SI 0 "register_operand" "=r")
1933 (match_operand:SI 1 "const64_high_operand" ""))]
1935 "sethi\t%%hi(%a1), %0")
1937 (define_insn "*movsi_insn"
1938 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,f,r,r,r,f,m,m,d")
1939 (match_operand:SI 1 "input_operand" "rI,!f,K,J,m,!m,rJ,!f,J"))]
1940 "(register_operand (operands[0], SImode)
1941 || reg_or_0_operand (operands[1], SImode))"
1945 sethi\t%%hi(%a1), %0
1952 [(set_attr "type" "*,fpmove,*,*,load,fpload,store,fpstore,fga")])
1954 (define_insn "*movsi_lo_sum"
1955 [(set (match_operand:SI 0 "register_operand" "=r")
1956 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1957 (match_operand:SI 2 "immediate_operand" "in")))]
1959 "or\t%1, %%lo(%a2), %0")
1961 (define_insn "*movsi_high"
1962 [(set (match_operand:SI 0 "register_operand" "=r")
1963 (high:SI (match_operand:SI 1 "immediate_operand" "in")))]
1965 "sethi\t%%hi(%a1), %0")
1967 ;; The next two patterns must wrap the SYMBOL_REF in an UNSPEC
1968 ;; so that CSE won't optimize the address computation away.
1969 (define_insn "movsi_lo_sum_pic"
1970 [(set (match_operand:SI 0 "register_operand" "=r")
1971 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1972 (unspec:SI [(match_operand:SI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
1974 "or\t%1, %%lo(%a2), %0")
1976 (define_insn "movsi_high_pic"
1977 [(set (match_operand:SI 0 "register_operand" "=r")
1978 (high:SI (unspec:SI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
1979 "flag_pic && check_pic (1)"
1980 "sethi\t%%hi(%a1), %0")
1982 (define_expand "movsi_pic_label_ref"
1983 [(set (match_dup 3) (high:SI
1984 (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
1985 (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1986 (set (match_dup 4) (lo_sum:SI (match_dup 3)
1987 (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1988 (set (match_operand:SI 0 "register_operand" "=r")
1989 (minus:SI (match_dup 5) (match_dup 4)))]
1992 current_function_uses_pic_offset_table = 1;
1993 operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
1996 operands[3] = operands[0];
1997 operands[4] = operands[0];
2001 operands[3] = gen_reg_rtx (SImode);
2002 operands[4] = gen_reg_rtx (SImode);
2004 operands[5] = pic_offset_table_rtx;
2007 (define_insn "*movsi_high_pic_label_ref"
2008 [(set (match_operand:SI 0 "register_operand" "=r")
2010 (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
2011 (match_operand:SI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
2013 "sethi\t%%hi(%a2-(%a1-.)), %0")
2015 (define_insn "*movsi_lo_sum_pic_label_ref"
2016 [(set (match_operand:SI 0 "register_operand" "=r")
2017 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
2018 (unspec:SI [(match_operand:SI 2 "label_ref_operand" "")
2019 (match_operand:SI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
2021 "or\t%1, %%lo(%a3-(%a2-.)), %0")
2023 (define_expand "movdi"
2024 [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand" "")
2025 (match_operand:DI 1 "general_operand" ""))]
2028 /* Where possible, convert CONST_DOUBLE into a CONST_INT. */
2029 if (GET_CODE (operands[1]) == CONST_DOUBLE
2030 #if HOST_BITS_PER_WIDE_INT == 32
2031 && ((CONST_DOUBLE_HIGH (operands[1]) == 0
2032 && (CONST_DOUBLE_LOW (operands[1]) & 0x80000000) == 0)
2033 || (CONST_DOUBLE_HIGH (operands[1]) == (HOST_WIDE_INT) 0xffffffff
2034 && (CONST_DOUBLE_LOW (operands[1]) & 0x80000000) != 0))
2037 operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
2039 /* Handle MEM cases first. */
2040 if (GET_CODE (operands[0]) == MEM)
2042 /* If it's a REG, we can always do it.
2043 The const zero case is more complex, on v9
2044 we can always perform it. */
2045 if (register_operand (operands[1], DImode)
2047 && (operands[1] == const0_rtx)))
2050 if (! reload_in_progress)
2052 operands[0] = validize_mem (operands[0]);
2053 operands[1] = force_reg (DImode, operands[1]);
2057 /* Fixup TLS cases. */
2058 if (tls_symbolic_operand (operands [1]))
2059 operands[1] = legitimize_tls_address (operands[1]);
2063 if (CONSTANT_P (operands[1])
2064 && pic_address_needs_scratch (operands[1]))
2065 operands[1] = legitimize_pic_address (operands[1], DImode, 0);
2067 if (GET_CODE (operands[1]) == LABEL_REF)
2069 if (! TARGET_ARCH64)
2071 emit_insn (gen_movdi_pic_label_ref (operands[0], operands[1]));
2075 if (symbolic_operand (operands[1], DImode))
2077 operands[1] = legitimize_pic_address (operands[1],
2079 (reload_in_progress ?
2086 /* If we are trying to toss an integer constant into the
2087 FPU registers, force it into memory. */
2088 if (GET_CODE (operands[0]) == REG
2089 && REGNO (operands[0]) >= SPARC_FIRST_FP_REG
2090 && REGNO (operands[0]) <= SPARC_LAST_V9_FP_REG
2091 && CONSTANT_P (operands[1]))
2092 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
2095 /* This makes sure we will not get rematched due to splittage. */
2096 if (! CONSTANT_P (operands[1]) || input_operand (operands[1], DImode))
2098 else if (TARGET_ARCH64
2099 && CONSTANT_P (operands[1])
2100 && GET_CODE (operands[1]) != HIGH
2101 && GET_CODE (operands[1]) != LO_SUM)
2103 sparc_emit_set_const64 (operands[0], operands[1]);
2111 ;; Be careful, fmovd does not exist when !v9.
2112 ;; We match MEM moves directly when we have correct even
2113 ;; numbered registers, but fall into splits otherwise.
2114 ;; The constraint ordering here is really important to
2115 ;; avoid insane problems in reload, especially for patterns
2118 ;; (set (mem:DI (plus:SI (reg:SI 30 %fp)
2119 ;; (const_int -5016)))
2123 (define_insn "*movdi_insn_sp32_v9"
2124 [(set (match_operand:DI 0 "nonimmediate_operand"
2125 "=T,o,T,U,o,r,r,r,?T,?f,?f,?o,?e,?e,?W")
2126 (match_operand:DI 1 "input_operand"
2127 " J,J,U,T,r,o,i,r, f, T, o, f, e, W, e"))]
2128 "! TARGET_ARCH64 && TARGET_V9
2129 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2146 [(set_attr "type" "store,store,store,load,*,*,*,*,fpstore,fpload,*,*,fpmove,fpload,fpstore")
2147 (set_attr "length" "*,2,*,*,2,2,2,2,*,*,2,2,*,*,*")
2148 (set_attr "fptype" "*,*,*,*,*,*,*,*,*,*,*,*,double,*,*")])
2150 (define_insn "*movdi_insn_sp32"
2151 [(set (match_operand:DI 0 "nonimmediate_operand"
2152 "=o,T,U,o,r,r,r,?T,?f,?f,?o,?f")
2153 (match_operand:DI 1 "input_operand"
2154 " J,U,T,r,o,i,r, f, T, o, f, f"))]
2156 && (register_operand (operands[0], DImode)
2157 || register_operand (operands[1], DImode))"
2171 [(set_attr "type" "store,store,load,*,*,*,*,fpstore,fpload,*,*,*")
2172 (set_attr "length" "2,*,*,2,2,2,2,*,*,2,2,2")])
2174 ;; The following are generated by sparc_emit_set_const64
2175 (define_insn "*movdi_sp64_dbl"
2176 [(set (match_operand:DI 0 "register_operand" "=r")
2177 (match_operand:DI 1 "const64_operand" ""))]
2179 && HOST_BITS_PER_WIDE_INT != 64)"
2182 ;; This is needed to show CSE exactly which bits are set
2183 ;; in a 64-bit register by sethi instructions.
2184 (define_insn "*movdi_const64_special"
2185 [(set (match_operand:DI 0 "register_operand" "=r")
2186 (match_operand:DI 1 "const64_high_operand" ""))]
2188 "sethi\t%%hi(%a1), %0")
2190 (define_insn "*movdi_insn_sp64_novis"
2191 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,m,?e,?e,?W")
2192 (match_operand:DI 1 "input_operand" "rI,N,J,m,rJ,e,W,e"))]
2193 "TARGET_ARCH64 && ! TARGET_VIS
2194 && (register_operand (operands[0], DImode)
2195 || reg_or_0_operand (operands[1], DImode))"
2198 sethi\t%%hi(%a1), %0
2205 [(set_attr "type" "*,*,*,load,store,fpmove,fpload,fpstore")
2206 (set_attr "fptype" "*,*,*,*,*,double,*,*")])
2208 (define_insn "*movdi_insn_sp64_vis"
2209 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,m,?e,?e,?W,b")
2210 (match_operand:DI 1 "input_operand" "rI,N,J,m,rJ,e,W,e,J"))]
2211 "TARGET_ARCH64 && TARGET_VIS &&
2212 (register_operand (operands[0], DImode)
2213 || reg_or_0_operand (operands[1], DImode))"
2216 sethi\t%%hi(%a1), %0
2224 [(set_attr "type" "*,*,*,load,store,fpmove,fpload,fpstore,fga")
2225 (set_attr "fptype" "*,*,*,*,*,double,*,*,double")])
2227 (define_expand "movdi_pic_label_ref"
2228 [(set (match_dup 3) (high:DI
2229 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
2230 (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
2231 (set (match_dup 4) (lo_sum:DI (match_dup 3)
2232 (unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
2233 (set (match_operand:DI 0 "register_operand" "=r")
2234 (minus:DI (match_dup 5) (match_dup 4)))]
2235 "TARGET_ARCH64 && flag_pic"
2237 current_function_uses_pic_offset_table = 1;
2238 operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
2241 operands[3] = operands[0];
2242 operands[4] = operands[0];
2246 operands[3] = gen_reg_rtx (DImode);
2247 operands[4] = gen_reg_rtx (DImode);
2249 operands[5] = pic_offset_table_rtx;
2252 (define_insn "*movdi_high_pic_label_ref"
2253 [(set (match_operand:DI 0 "register_operand" "=r")
2255 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
2256 (match_operand:DI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
2257 "TARGET_ARCH64 && flag_pic"
2258 "sethi\t%%hi(%a2-(%a1-.)), %0")
2260 (define_insn "*movdi_lo_sum_pic_label_ref"
2261 [(set (match_operand:DI 0 "register_operand" "=r")
2262 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2263 (unspec:DI [(match_operand:DI 2 "label_ref_operand" "")
2264 (match_operand:DI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
2265 "TARGET_ARCH64 && flag_pic"
2266 "or\t%1, %%lo(%a3-(%a2-.)), %0")
2268 ;; SPARC-v9 code model support insns. See sparc_emit_set_symbolic_const64
2269 ;; in sparc.c to see what is going on here... PIC stuff comes first.
2271 (define_insn "movdi_lo_sum_pic"
2272 [(set (match_operand:DI 0 "register_operand" "=r")
2273 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2274 (unspec:DI [(match_operand:DI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
2275 "TARGET_ARCH64 && flag_pic"
2276 "or\t%1, %%lo(%a2), %0")
2278 (define_insn "movdi_high_pic"
2279 [(set (match_operand:DI 0 "register_operand" "=r")
2280 (high:DI (unspec:DI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
2281 "TARGET_ARCH64 && flag_pic && check_pic (1)"
2282 "sethi\t%%hi(%a1), %0")
2284 (define_insn "*sethi_di_medlow_embmedany_pic"
2285 [(set (match_operand:DI 0 "register_operand" "=r")
2286 (high:DI (match_operand:DI 1 "sp64_medium_pic_operand" "")))]
2287 "(TARGET_CM_MEDLOW || TARGET_CM_EMBMEDANY) && check_pic (1)"
2288 "sethi\t%%hi(%a1), %0")
2290 (define_insn "*sethi_di_medlow"
2291 [(set (match_operand:DI 0 "register_operand" "=r")
2292 (high:DI (match_operand:DI 1 "symbolic_operand" "")))]
2293 "TARGET_CM_MEDLOW && check_pic (1)"
2294 "sethi\t%%hi(%a1), %0")
2296 (define_insn "*losum_di_medlow"
2297 [(set (match_operand:DI 0 "register_operand" "=r")
2298 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2299 (match_operand:DI 2 "symbolic_operand" "")))]
2301 "or\t%1, %%lo(%a2), %0")
2303 (define_insn "seth44"
2304 [(set (match_operand:DI 0 "register_operand" "=r")
2305 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETH44)))]
2307 "sethi\t%%h44(%a1), %0")
2309 (define_insn "setm44"
2310 [(set (match_operand:DI 0 "register_operand" "=r")
2311 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2312 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_SETM44)))]
2314 "or\t%1, %%m44(%a2), %0")
2316 (define_insn "setl44"
2317 [(set (match_operand:DI 0 "register_operand" "=r")
2318 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2319 (match_operand:DI 2 "symbolic_operand" "")))]
2321 "or\t%1, %%l44(%a2), %0")
2323 (define_insn "sethh"
2324 [(set (match_operand:DI 0 "register_operand" "=r")
2325 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETHH)))]
2327 "sethi\t%%hh(%a1), %0")
2329 (define_insn "setlm"
2330 [(set (match_operand:DI 0 "register_operand" "=r")
2331 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETLM)))]
2333 "sethi\t%%lm(%a1), %0")
2335 (define_insn "sethm"
2336 [(set (match_operand:DI 0 "register_operand" "=r")
2337 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2338 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_EMB_SETHM)))]
2340 "or\t%1, %%hm(%a2), %0")
2342 (define_insn "setlo"
2343 [(set (match_operand:DI 0 "register_operand" "=r")
2344 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2345 (match_operand:DI 2 "symbolic_operand" "")))]
2347 "or\t%1, %%lo(%a2), %0")
2349 (define_insn "embmedany_sethi"
2350 [(set (match_operand:DI 0 "register_operand" "=r")
2351 (high:DI (unspec:DI [(match_operand:DI 1 "data_segment_operand" "")] UNSPEC_EMB_HISUM)))]
2352 "TARGET_CM_EMBMEDANY && check_pic (1)"
2353 "sethi\t%%hi(%a1), %0")
2355 (define_insn "embmedany_losum"
2356 [(set (match_operand:DI 0 "register_operand" "=r")
2357 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2358 (match_operand:DI 2 "data_segment_operand" "")))]
2359 "TARGET_CM_EMBMEDANY"
2360 "add\t%1, %%lo(%a2), %0")
2362 (define_insn "embmedany_brsum"
2363 [(set (match_operand:DI 0 "register_operand" "=r")
2364 (unspec:DI [(match_operand:DI 1 "register_operand" "r")] UNSPEC_EMB_HISUM))]
2365 "TARGET_CM_EMBMEDANY"
2368 (define_insn "embmedany_textuhi"
2369 [(set (match_operand:DI 0 "register_operand" "=r")
2370 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTUHI)))]
2371 "TARGET_CM_EMBMEDANY && check_pic (1)"
2372 "sethi\t%%uhi(%a1), %0")
2374 (define_insn "embmedany_texthi"
2375 [(set (match_operand:DI 0 "register_operand" "=r")
2376 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTHI)))]
2377 "TARGET_CM_EMBMEDANY && check_pic (1)"
2378 "sethi\t%%hi(%a1), %0")
2380 (define_insn "embmedany_textulo"
2381 [(set (match_operand:DI 0 "register_operand" "=r")
2382 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2383 (unspec:DI [(match_operand:DI 2 "text_segment_operand" "")] UNSPEC_EMB_TEXTULO)))]
2384 "TARGET_CM_EMBMEDANY"
2385 "or\t%1, %%ulo(%a2), %0")
2387 (define_insn "embmedany_textlo"
2388 [(set (match_operand:DI 0 "register_operand" "=r")
2389 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2390 (match_operand:DI 2 "text_segment_operand" "")))]
2391 "TARGET_CM_EMBMEDANY"
2392 "or\t%1, %%lo(%a2), %0")
2394 ;; Now some patterns to help reload out a bit.
2395 (define_expand "reload_indi"
2396 [(parallel [(match_operand:DI 0 "register_operand" "=r")
2397 (match_operand:DI 1 "immediate_operand" "")
2398 (match_operand:TI 2 "register_operand" "=&r")])]
2400 || TARGET_CM_EMBMEDANY)
2403 sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
2407 (define_expand "reload_outdi"
2408 [(parallel [(match_operand:DI 0 "register_operand" "=r")
2409 (match_operand:DI 1 "immediate_operand" "")
2410 (match_operand:TI 2 "register_operand" "=&r")])]
2412 || TARGET_CM_EMBMEDANY)
2415 sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
2419 ;; Split up putting CONSTs and REGs into DI regs when !arch64
2421 [(set (match_operand:DI 0 "register_operand" "")
2422 (match_operand:DI 1 "const_int_operand" ""))]
2423 "! TARGET_ARCH64 && reload_completed"
2424 [(clobber (const_int 0))]
2426 #if HOST_BITS_PER_WIDE_INT == 32
2427 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
2428 (INTVAL (operands[1]) < 0) ?
2431 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2434 unsigned int low, high;
2436 low = trunc_int_for_mode (INTVAL (operands[1]), SImode);
2437 high = trunc_int_for_mode (INTVAL (operands[1]) >> 32, SImode);
2438 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), GEN_INT (high)));
2440 /* Slick... but this trick loses if this subreg constant part
2441 can be done in one insn. */
2442 if (low == high && (low & 0x3ff) != 0 && low + 0x1000 >= 0x2000)
2443 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2444 gen_highpart (SImode, operands[0])));
2446 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), GEN_INT (low)));
2452 [(set (match_operand:DI 0 "register_operand" "")
2453 (match_operand:DI 1 "const_double_operand" ""))]
2457 && ((GET_CODE (operands[0]) == REG
2458 && REGNO (operands[0]) < 32)
2459 || (GET_CODE (operands[0]) == SUBREG
2460 && GET_CODE (SUBREG_REG (operands[0])) == REG
2461 && REGNO (SUBREG_REG (operands[0])) < 32))))"
2462 [(clobber (const_int 0))]
2464 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
2465 GEN_INT (CONST_DOUBLE_HIGH (operands[1]))));
2467 /* Slick... but this trick loses if this subreg constant part
2468 can be done in one insn. */
2469 if (CONST_DOUBLE_LOW (operands[1]) == CONST_DOUBLE_HIGH (operands[1])
2470 && !(SPARC_SETHI32_P (CONST_DOUBLE_HIGH (operands[1]))
2471 || SPARC_SIMM13_P (CONST_DOUBLE_HIGH (operands[1]))))
2473 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2474 gen_highpart (SImode, operands[0])));
2478 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2479 GEN_INT (CONST_DOUBLE_LOW (operands[1]))));
2485 [(set (match_operand:DI 0 "register_operand" "")
2486 (match_operand:DI 1 "register_operand" ""))]
2490 && ((GET_CODE (operands[0]) == REG
2491 && REGNO (operands[0]) < 32)
2492 || (GET_CODE (operands[0]) == SUBREG
2493 && GET_CODE (SUBREG_REG (operands[0])) == REG
2494 && REGNO (SUBREG_REG (operands[0])) < 32))))"
2495 [(clobber (const_int 0))]
2497 rtx set_dest = operands[0];
2498 rtx set_src = operands[1];
2502 dest1 = gen_highpart (SImode, set_dest);
2503 dest2 = gen_lowpart (SImode, set_dest);
2504 src1 = gen_highpart (SImode, set_src);
2505 src2 = gen_lowpart (SImode, set_src);
2507 /* Now emit using the real source and destination we found, swapping
2508 the order if we detect overlap. */
2509 if (reg_overlap_mentioned_p (dest1, src2))
2511 emit_insn (gen_movsi (dest2, src2));
2512 emit_insn (gen_movsi (dest1, src1));
2516 emit_insn (gen_movsi (dest1, src1));
2517 emit_insn (gen_movsi (dest2, src2));
2522 ;; Now handle the cases of memory moves from/to non-even
2523 ;; DI mode register pairs.
2525 [(set (match_operand:DI 0 "register_operand" "")
2526 (match_operand:DI 1 "memory_operand" ""))]
2529 && sparc_splitdi_legitimate (operands[0], operands[1]))"
2530 [(clobber (const_int 0))]
2532 rtx word0 = adjust_address (operands[1], SImode, 0);
2533 rtx word1 = adjust_address (operands[1], SImode, 4);
2534 rtx high_part = gen_highpart (SImode, operands[0]);
2535 rtx low_part = gen_lowpart (SImode, operands[0]);
2537 if (reg_overlap_mentioned_p (high_part, word1))
2539 emit_insn (gen_movsi (low_part, word1));
2540 emit_insn (gen_movsi (high_part, word0));
2544 emit_insn (gen_movsi (high_part, word0));
2545 emit_insn (gen_movsi (low_part, word1));
2551 [(set (match_operand:DI 0 "memory_operand" "")
2552 (match_operand:DI 1 "register_operand" ""))]
2555 && sparc_splitdi_legitimate (operands[1], operands[0]))"
2556 [(clobber (const_int 0))]
2558 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0),
2559 gen_highpart (SImode, operands[1])));
2560 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4),
2561 gen_lowpart (SImode, operands[1])));
2566 [(set (match_operand:DI 0 "memory_operand" "")
2571 && ! mem_min_alignment (operands[0], 8)))
2572 && offsettable_memref_p (operands[0])"
2573 [(clobber (const_int 0))]
2575 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0), const0_rtx));
2576 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4), const0_rtx));
2580 ;; Floating point move insns
2582 (define_insn "*movsf_insn_novis"
2583 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,*r,*r,*r,*r,*r,f,m,m")
2584 (match_operand:SF 1 "input_operand" "f,G,Q,*rR,S,m,m,f,*rG"))]
2585 "(TARGET_FPU && ! TARGET_VIS)
2586 && (register_operand (operands[0], SFmode)
2587 || register_operand (operands[1], SFmode)
2588 || fp_zero_operand (operands[1], SFmode))"
2590 if (GET_CODE (operands[1]) == CONST_DOUBLE
2591 && (which_alternative == 2
2592 || which_alternative == 3
2593 || which_alternative == 4))
2598 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2599 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2600 operands[1] = GEN_INT (i);
2603 switch (which_alternative)
2606 return "fmovs\t%1, %0";
2610 return "sethi\t%%hi(%a1), %0";
2612 return "mov\t%1, %0";
2617 return "ld\t%1, %0";
2620 return "st\t%r1, %0";
2625 [(set_attr "type" "fpmove,*,*,*,*,load,fpload,fpstore,store")])
2627 (define_insn "*movsf_insn_vis"
2628 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,*r,*r,*r,*r,*r,f,m,m")
2629 (match_operand:SF 1 "input_operand" "f,G,G,Q,*rR,S,m,m,f,*rG"))]
2630 "(TARGET_FPU && TARGET_VIS)
2631 && (register_operand (operands[0], SFmode)
2632 || register_operand (operands[1], SFmode)
2633 || fp_zero_operand (operands[1], SFmode))"
2635 if (GET_CODE (operands[1]) == CONST_DOUBLE
2636 && (which_alternative == 3
2637 || which_alternative == 4
2638 || which_alternative == 5))
2643 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2644 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2645 operands[1] = GEN_INT (i);
2648 switch (which_alternative)
2651 return "fmovs\t%1, %0";
2653 return "fzeros\t%0";
2657 return "sethi\t%%hi(%a1), %0";
2659 return "mov\t%1, %0";
2664 return "ld\t%1, %0";
2667 return "st\t%r1, %0";
2672 [(set_attr "type" "fpmove,fga,*,*,*,*,load,fpload,fpstore,store")])
2674 ;; Exactly the same as above, except that all `f' cases are deleted.
2675 ;; This is necessary to prevent reload from ever trying to use a `f' reg
2678 (define_insn "*movsf_no_f_insn"
2679 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r,r,r,m")
2680 (match_operand:SF 1 "input_operand" "G,Q,rR,S,m,rG"))]
2682 && (register_operand (operands[0], SFmode)
2683 || register_operand (operands[1], SFmode)
2684 || fp_zero_operand (operands[1], SFmode))"
2686 if (GET_CODE (operands[1]) == CONST_DOUBLE
2687 && (which_alternative == 1
2688 || which_alternative == 2
2689 || which_alternative == 3))
2694 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2695 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2696 operands[1] = GEN_INT (i);
2699 switch (which_alternative)
2704 return "sethi\t%%hi(%a1), %0";
2706 return "mov\t%1, %0";
2710 return "ld\t%1, %0";
2712 return "st\t%r1, %0";
2717 [(set_attr "type" "*,*,*,*,load,store")])
2719 (define_insn "*movsf_lo_sum"
2720 [(set (match_operand:SF 0 "register_operand" "=r")
2721 (lo_sum:SF (match_operand:SF 1 "register_operand" "r")
2722 (match_operand:SF 2 "const_double_operand" "S")))]
2723 "fp_high_losum_p (operands[2])"
2728 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[2]);
2729 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2730 operands[2] = GEN_INT (i);
2731 return "or\t%1, %%lo(%a2), %0";
2734 (define_insn "*movsf_high"
2735 [(set (match_operand:SF 0 "register_operand" "=r")
2736 (high:SF (match_operand:SF 1 "const_double_operand" "S")))]
2737 "fp_high_losum_p (operands[1])"
2742 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2743 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2744 operands[1] = GEN_INT (i);
2745 return "sethi\t%%hi(%1), %0";
2749 [(set (match_operand:SF 0 "register_operand" "")
2750 (match_operand:SF 1 "const_double_operand" ""))]
2751 "fp_high_losum_p (operands[1])
2752 && (GET_CODE (operands[0]) == REG
2753 && REGNO (operands[0]) < 32)"
2754 [(set (match_dup 0) (high:SF (match_dup 1)))
2755 (set (match_dup 0) (lo_sum:SF (match_dup 0) (match_dup 1)))])
2757 (define_expand "movsf"
2758 [(set (match_operand:SF 0 "general_operand" "")
2759 (match_operand:SF 1 "general_operand" ""))]
2762 /* Force SFmode constants into memory. */
2763 if (GET_CODE (operands[0]) == REG
2764 && CONSTANT_P (operands[1]))
2766 /* emit_group_store will send such bogosity to us when it is
2767 not storing directly into memory. So fix this up to avoid
2768 crashes in output_constant_pool. */
2769 if (operands [1] == const0_rtx)
2770 operands[1] = CONST0_RTX (SFmode);
2772 if (TARGET_VIS && fp_zero_operand (operands[1], SFmode))
2775 /* We are able to build any SF constant in integer registers
2776 with at most 2 instructions. */
2777 if (REGNO (operands[0]) < 32)
2780 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
2784 /* Handle sets of MEM first. */
2785 if (GET_CODE (operands[0]) == MEM)
2787 if (register_operand (operands[1], SFmode)
2788 || fp_zero_operand (operands[1], SFmode))
2791 if (! reload_in_progress)
2793 operands[0] = validize_mem (operands[0]);
2794 operands[1] = force_reg (SFmode, operands[1]);
2798 /* Fixup PIC cases. */
2801 if (CONSTANT_P (operands[1])
2802 && pic_address_needs_scratch (operands[1]))
2803 operands[1] = legitimize_pic_address (operands[1], SFmode, 0);
2805 if (symbolic_operand (operands[1], SFmode))
2807 operands[1] = legitimize_pic_address (operands[1],
2809 (reload_in_progress ?
2819 (define_expand "movdf"
2820 [(set (match_operand:DF 0 "general_operand" "")
2821 (match_operand:DF 1 "general_operand" ""))]
2824 /* Force DFmode constants into memory. */
2825 if (GET_CODE (operands[0]) == REG
2826 && CONSTANT_P (operands[1]))
2828 /* emit_group_store will send such bogosity to us when it is
2829 not storing directly into memory. So fix this up to avoid
2830 crashes in output_constant_pool. */
2831 if (operands [1] == const0_rtx)
2832 operands[1] = CONST0_RTX (DFmode);
2834 if ((TARGET_VIS || REGNO (operands[0]) < 32)
2835 && fp_zero_operand (operands[1], DFmode))
2838 /* We are able to build any DF constant in integer registers. */
2839 if (REGNO (operands[0]) < 32
2840 && (reload_completed || reload_in_progress))
2843 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
2847 /* Handle MEM cases first. */
2848 if (GET_CODE (operands[0]) == MEM)
2850 if (register_operand (operands[1], DFmode)
2851 || fp_zero_operand (operands[1], DFmode))
2854 if (! reload_in_progress)
2856 operands[0] = validize_mem (operands[0]);
2857 operands[1] = force_reg (DFmode, operands[1]);
2861 /* Fixup PIC cases. */
2864 if (CONSTANT_P (operands[1])
2865 && pic_address_needs_scratch (operands[1]))
2866 operands[1] = legitimize_pic_address (operands[1], DFmode, 0);
2868 if (symbolic_operand (operands[1], DFmode))
2870 operands[1] = legitimize_pic_address (operands[1],
2872 (reload_in_progress ?
2882 ;; Be careful, fmovd does not exist when !v9.
2883 (define_insn "*movdf_insn_sp32"
2884 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,W,U,T,o,e,*r,o,e,o")
2885 (match_operand:DF 1 "input_operand" "W#F,e,T,U,G,e,*rFo,*r,o#F,e"))]
2888 && (register_operand (operands[0], DFmode)
2889 || register_operand (operands[1], DFmode)
2890 || fp_zero_operand (operands[1], DFmode))"
2902 [(set_attr "type" "fpload,fpstore,load,store,*,*,*,*,*,*")
2903 (set_attr "length" "*,*,*,*,2,2,2,2,2,2")])
2905 (define_insn "*movdf_no_e_insn_sp32"
2906 [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,o,r,o")
2907 (match_operand:DF 1 "input_operand" "T,U,G,ro,r"))]
2911 && (register_operand (operands[0], DFmode)
2912 || register_operand (operands[1], DFmode)
2913 || fp_zero_operand (operands[1], DFmode))"
2920 [(set_attr "type" "load,store,*,*,*")
2921 (set_attr "length" "*,*,2,2,2")])
2923 (define_insn "*movdf_no_e_insn_v9_sp32"
2924 [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,T,r,o")
2925 (match_operand:DF 1 "input_operand" "T,U,G,ro,rG"))]
2929 && (register_operand (operands[0], DFmode)
2930 || register_operand (operands[1], DFmode)
2931 || fp_zero_operand (operands[1], DFmode))"
2938 [(set_attr "type" "load,store,store,*,*")
2939 (set_attr "length" "*,*,*,2,2")])
2941 ;; We have available v9 double floats but not 64-bit
2942 ;; integer registers and no VIS.
2943 (define_insn "*movdf_insn_v9only_novis"
2944 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,T,W,U,T,f,*r,o")
2945 (match_operand:DF 1 "input_operand" "e,W#F,G,e,T,U,o#F,*roF,*rGf"))]
2950 && (register_operand (operands[0], DFmode)
2951 || register_operand (operands[1], DFmode)
2952 || fp_zero_operand (operands[1], DFmode))"
2963 [(set_attr "type" "fpmove,load,store,store,load,store,*,*,*")
2964 (set_attr "length" "*,*,*,*,*,*,2,2,2")
2965 (set_attr "fptype" "double,*,*,*,*,*,*,*,*")])
2967 ;; We have available v9 double floats but not 64-bit
2968 ;; integer registers but we have VIS.
2969 (define_insn "*movdf_insn_v9only_vis"
2970 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,e,T,W,U,T,f,*r,o")
2971 (match_operand:DF 1 "input_operand" "G,e,W#F,G,e,T,U,o#F,*roGF,*rGf"))]
2975 && (register_operand (operands[0], DFmode)
2976 || register_operand (operands[1], DFmode)
2977 || fp_zero_operand (operands[1], DFmode))"
2989 [(set_attr "type" "fga,fpmove,load,store,store,load,store,*,*,*")
2990 (set_attr "length" "*,*,*,*,*,*,*,2,2,2")
2991 (set_attr "fptype" "double,double,*,*,*,*,*,*,*,*")])
2993 ;; We have available both v9 double floats and 64-bit
2994 ;; integer registers. No VIS though.
2995 (define_insn "*movdf_insn_sp64_novis"
2996 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,W,*r,*r,m,*r")
2997 (match_operand:DF 1 "input_operand" "e,W#F,e,*rG,m,*rG,F"))]
3001 && (register_operand (operands[0], DFmode)
3002 || register_operand (operands[1], DFmode)
3003 || fp_zero_operand (operands[1], DFmode))"
3012 [(set_attr "type" "fpmove,load,store,*,load,store,*")
3013 (set_attr "length" "*,*,*,*,*,*,2")
3014 (set_attr "fptype" "double,*,*,*,*,*,*")])
3016 ;; We have available both v9 double floats and 64-bit
3017 ;; integer registers. And we have VIS.
3018 (define_insn "*movdf_insn_sp64_vis"
3019 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,e,W,*r,*r,m,*r")
3020 (match_operand:DF 1 "input_operand" "G,e,W#F,e,*rG,m,*rG,F"))]
3024 && (register_operand (operands[0], DFmode)
3025 || register_operand (operands[1], DFmode)
3026 || fp_zero_operand (operands[1], DFmode))"
3036 [(set_attr "type" "fga,fpmove,load,store,*,load,store,*")
3037 (set_attr "length" "*,*,*,*,*,*,*,2")
3038 (set_attr "fptype" "double,double,*,*,*,*,*,*")])
3040 (define_insn "*movdf_no_e_insn_sp64"
3041 [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m")
3042 (match_operand:DF 1 "input_operand" "r,m,rG"))]
3045 && (register_operand (operands[0], DFmode)
3046 || register_operand (operands[1], DFmode)
3047 || fp_zero_operand (operands[1], DFmode))"
3052 [(set_attr "type" "*,load,store")])
3055 [(set (match_operand:DF 0 "register_operand" "")
3056 (match_operand:DF 1 "const_double_operand" ""))]
3058 && (GET_CODE (operands[0]) == REG
3059 && REGNO (operands[0]) < 32)
3060 && ! fp_zero_operand(operands[1], DFmode)
3061 && reload_completed"
3062 [(clobber (const_int 0))]
3067 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3068 REAL_VALUE_TO_TARGET_DOUBLE (r, l);
3069 operands[0] = gen_rtx_raw_REG (DImode, REGNO (operands[0]));
3073 #if HOST_BITS_PER_WIDE_INT == 64
3076 val = ((HOST_WIDE_INT)(unsigned long)l[1] |
3077 ((HOST_WIDE_INT)(unsigned long)l[0] << 32));
3078 emit_insn (gen_movdi (operands[0], GEN_INT (val)));
3080 emit_insn (gen_movdi (operands[0],
3081 immed_double_const (l[1], l[0], DImode)));
3086 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
3089 /* Slick... but this trick loses if this subreg constant part
3090 can be done in one insn. */
3092 && !(SPARC_SETHI32_P (l[0])
3093 || SPARC_SIMM13_P (l[0])))
3095 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
3096 gen_highpart (SImode, operands[0])));
3100 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
3107 ;; Ok, now the splits to handle all the multi insn and
3108 ;; mis-aligned memory address cases.
3109 ;; In these splits please take note that we must be
3110 ;; careful when V9 but not ARCH64 because the integer
3111 ;; register DFmode cases must be handled.
3113 [(set (match_operand:DF 0 "register_operand" "")
3114 (match_operand:DF 1 "register_operand" ""))]
3117 && ((GET_CODE (operands[0]) == REG
3118 && REGNO (operands[0]) < 32)
3119 || (GET_CODE (operands[0]) == SUBREG
3120 && GET_CODE (SUBREG_REG (operands[0])) == REG
3121 && REGNO (SUBREG_REG (operands[0])) < 32))))
3122 && reload_completed"
3123 [(clobber (const_int 0))]
3125 rtx set_dest = operands[0];
3126 rtx set_src = operands[1];
3130 dest1 = gen_highpart (SFmode, set_dest);
3131 dest2 = gen_lowpart (SFmode, set_dest);
3132 src1 = gen_highpart (SFmode, set_src);
3133 src2 = gen_lowpart (SFmode, set_src);
3135 /* Now emit using the real source and destination we found, swapping
3136 the order if we detect overlap. */
3137 if (reg_overlap_mentioned_p (dest1, src2))
3139 emit_insn (gen_movsf (dest2, src2));
3140 emit_insn (gen_movsf (dest1, src1));
3144 emit_insn (gen_movsf (dest1, src1));
3145 emit_insn (gen_movsf (dest2, src2));
3151 [(set (match_operand:DF 0 "register_operand" "")
3152 (match_operand:DF 1 "memory_operand" ""))]
3155 && (((REGNO (operands[0]) % 2) != 0)
3156 || ! mem_min_alignment (operands[1], 8))
3157 && offsettable_memref_p (operands[1])"
3158 [(clobber (const_int 0))]
3160 rtx word0 = adjust_address (operands[1], SFmode, 0);
3161 rtx word1 = adjust_address (operands[1], SFmode, 4);
3163 if (reg_overlap_mentioned_p (gen_highpart (SFmode, operands[0]), word1))
3165 emit_insn (gen_movsf (gen_lowpart (SFmode, operands[0]),
3167 emit_insn (gen_movsf (gen_highpart (SFmode, operands[0]),
3172 emit_insn (gen_movsf (gen_highpart (SFmode, operands[0]),
3174 emit_insn (gen_movsf (gen_lowpart (SFmode, operands[0]),
3181 [(set (match_operand:DF 0 "memory_operand" "")
3182 (match_operand:DF 1 "register_operand" ""))]
3185 && (((REGNO (operands[1]) % 2) != 0)
3186 || ! mem_min_alignment (operands[0], 8))
3187 && offsettable_memref_p (operands[0])"
3188 [(clobber (const_int 0))]
3190 rtx word0 = adjust_address (operands[0], SFmode, 0);
3191 rtx word1 = adjust_address (operands[0], SFmode, 4);
3193 emit_insn (gen_movsf (word0,
3194 gen_highpart (SFmode, operands[1])));
3195 emit_insn (gen_movsf (word1,
3196 gen_lowpart (SFmode, operands[1])));
3201 [(set (match_operand:DF 0 "memory_operand" "")
3202 (match_operand:DF 1 "fp_zero_operand" ""))]
3206 && ! mem_min_alignment (operands[0], 8)))
3207 && offsettable_memref_p (operands[0])"
3208 [(clobber (const_int 0))]
3212 dest1 = adjust_address (operands[0], SFmode, 0);
3213 dest2 = adjust_address (operands[0], SFmode, 4);
3215 emit_insn (gen_movsf (dest1, CONST0_RTX (SFmode)));
3216 emit_insn (gen_movsf (dest2, CONST0_RTX (SFmode)));
3221 [(set (match_operand:DF 0 "register_operand" "")
3222 (match_operand:DF 1 "fp_zero_operand" ""))]
3225 && ((GET_CODE (operands[0]) == REG
3226 && REGNO (operands[0]) < 32)
3227 || (GET_CODE (operands[0]) == SUBREG
3228 && GET_CODE (SUBREG_REG (operands[0])) == REG
3229 && REGNO (SUBREG_REG (operands[0])) < 32))"
3230 [(clobber (const_int 0))]
3232 rtx set_dest = operands[0];
3235 dest1 = gen_highpart (SFmode, set_dest);
3236 dest2 = gen_lowpart (SFmode, set_dest);
3237 emit_insn (gen_movsf (dest1, CONST0_RTX (SFmode)));
3238 emit_insn (gen_movsf (dest2, CONST0_RTX (SFmode)));
3242 (define_expand "movtf"
3243 [(set (match_operand:TF 0 "general_operand" "")
3244 (match_operand:TF 1 "general_operand" ""))]
3247 /* Force TFmode constants into memory. */
3248 if (GET_CODE (operands[0]) == REG
3249 && CONSTANT_P (operands[1]))
3251 /* emit_group_store will send such bogosity to us when it is
3252 not storing directly into memory. So fix this up to avoid
3253 crashes in output_constant_pool. */
3254 if (operands [1] == const0_rtx)
3255 operands[1] = CONST0_RTX (TFmode);
3257 if (TARGET_VIS && fp_zero_operand (operands[1], TFmode))
3260 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
3264 /* Handle MEM cases first, note that only v9 guarantees
3265 full 16-byte alignment for quads. */
3266 if (GET_CODE (operands[0]) == MEM)
3268 if (register_operand (operands[1], TFmode)
3269 || fp_zero_operand (operands[1], TFmode))
3272 if (! reload_in_progress)
3274 operands[0] = validize_mem (operands[0]);
3275 operands[1] = force_reg (TFmode, operands[1]);
3279 /* Fixup PIC cases. */
3282 if (CONSTANT_P (operands[1])
3283 && pic_address_needs_scratch (operands[1]))
3284 operands[1] = legitimize_pic_address (operands[1], TFmode, 0);
3286 if (symbolic_operand (operands[1], TFmode))
3288 operands[1] = legitimize_pic_address (operands[1],
3290 (reload_in_progress ?
3300 ;; Be careful, fmovq and {st,ld}{x,q} do not exist when !arch64 so
3301 ;; we must split them all. :-(
3302 (define_insn "*movtf_insn_sp32"
3303 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,U,r")
3304 (match_operand:TF 1 "input_operand" "oe,GeUr,o,roG"))]
3308 && (register_operand (operands[0], TFmode)
3309 || register_operand (operands[1], TFmode)
3310 || fp_zero_operand (operands[1], TFmode))"
3312 [(set_attr "length" "4")])
3314 (define_insn "*movtf_insn_vis_sp32"
3315 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,U,r")
3316 (match_operand:TF 1 "input_operand" "Goe,GeUr,o,roG"))]
3320 && (register_operand (operands[0], TFmode)
3321 || register_operand (operands[1], TFmode)
3322 || fp_zero_operand (operands[1], TFmode))"
3324 [(set_attr "length" "4")])
3326 ;; Exactly the same as above, except that all `e' cases are deleted.
3327 ;; This is necessary to prevent reload from ever trying to use a `e' reg
3330 (define_insn "*movtf_no_e_insn_sp32"
3331 [(set (match_operand:TF 0 "nonimmediate_operand" "=o,U,o,r,o")
3332 (match_operand:TF 1 "input_operand" "G,o,U,roG,r"))]
3335 && (register_operand (operands[0], TFmode)
3336 || register_operand (operands[1], TFmode)
3337 || fp_zero_operand (operands[1], TFmode))"
3339 [(set_attr "length" "4")])
3341 ;; Now handle the float reg cases directly when arch64,
3342 ;; hard_quad, and proper reg number alignment are all true.
3343 (define_insn "*movtf_insn_hq_sp64"
3344 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,e,m,o,r")
3345 (match_operand:TF 1 "input_operand" "e,m,e,Gr,roG"))]
3350 && (register_operand (operands[0], TFmode)
3351 || register_operand (operands[1], TFmode)
3352 || fp_zero_operand (operands[1], TFmode))"
3359 [(set_attr "type" "fpmove,fpload,fpstore,*,*")
3360 (set_attr "length" "*,*,*,2,2")])
3362 (define_insn "*movtf_insn_hq_vis_sp64"
3363 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,e,m,eo,r,o")
3364 (match_operand:TF 1 "input_operand" "e,m,e,G,roG,r"))]
3369 && (register_operand (operands[0], TFmode)
3370 || register_operand (operands[1], TFmode)
3371 || fp_zero_operand (operands[1], TFmode))"
3379 [(set_attr "type" "fpmove,fpload,fpstore,*,*,*")
3380 (set_attr "length" "*,*,*,2,2,2")])
3382 ;; Now we allow the integer register cases even when
3383 ;; only arch64 is true.
3384 (define_insn "*movtf_insn_sp64"
3385 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,r")
3386 (match_operand:TF 1 "input_operand" "oe,Ger,orG"))]
3390 && ! TARGET_HARD_QUAD
3391 && (register_operand (operands[0], TFmode)
3392 || register_operand (operands[1], TFmode)
3393 || fp_zero_operand (operands[1], TFmode))"
3395 [(set_attr "length" "2")])
3397 (define_insn "*movtf_insn_vis_sp64"
3398 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,r")
3399 (match_operand:TF 1 "input_operand" "Goe,Ger,orG"))]
3403 && ! TARGET_HARD_QUAD
3404 && (register_operand (operands[0], TFmode)
3405 || register_operand (operands[1], TFmode)
3406 || fp_zero_operand (operands[1], TFmode))"
3408 [(set_attr "length" "2")])
3410 (define_insn "*movtf_no_e_insn_sp64"
3411 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o")
3412 (match_operand:TF 1 "input_operand" "orG,rG"))]
3415 && (register_operand (operands[0], TFmode)
3416 || register_operand (operands[1], TFmode)
3417 || fp_zero_operand (operands[1], TFmode))"
3419 [(set_attr "length" "2")])
3421 ;; Now all the splits to handle multi-insn TF mode moves.
3423 [(set (match_operand:TF 0 "register_operand" "")
3424 (match_operand:TF 1 "register_operand" ""))]
3428 && ! TARGET_HARD_QUAD)
3429 || ! fp_register_operand (operands[0], TFmode))"
3430 [(clobber (const_int 0))]
3432 rtx set_dest = operands[0];
3433 rtx set_src = operands[1];
3437 dest1 = gen_df_reg (set_dest, 0);
3438 dest2 = gen_df_reg (set_dest, 1);
3439 src1 = gen_df_reg (set_src, 0);
3440 src2 = gen_df_reg (set_src, 1);
3442 /* Now emit using the real source and destination we found, swapping
3443 the order if we detect overlap. */
3444 if (reg_overlap_mentioned_p (dest1, src2))
3446 emit_insn (gen_movdf (dest2, src2));
3447 emit_insn (gen_movdf (dest1, src1));
3451 emit_insn (gen_movdf (dest1, src1));
3452 emit_insn (gen_movdf (dest2, src2));
3458 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3459 (match_operand:TF 1 "fp_zero_operand" ""))]
3461 [(clobber (const_int 0))]
3463 rtx set_dest = operands[0];
3466 switch (GET_CODE (set_dest))
3469 dest1 = gen_df_reg (set_dest, 0);
3470 dest2 = gen_df_reg (set_dest, 1);
3473 dest1 = adjust_address (set_dest, DFmode, 0);
3474 dest2 = adjust_address (set_dest, DFmode, 8);
3480 emit_insn (gen_movdf (dest1, CONST0_RTX (DFmode)));
3481 emit_insn (gen_movdf (dest2, CONST0_RTX (DFmode)));
3486 [(set (match_operand:TF 0 "register_operand" "")
3487 (match_operand:TF 1 "memory_operand" ""))]
3489 && offsettable_memref_p (operands[1])
3491 || ! TARGET_HARD_QUAD
3492 || ! fp_register_operand (operands[0], TFmode)))"
3493 [(clobber (const_int 0))]
3495 rtx word0 = adjust_address (operands[1], DFmode, 0);
3496 rtx word1 = adjust_address (operands[1], DFmode, 8);
3497 rtx set_dest, dest1, dest2;
3499 set_dest = operands[0];
3501 dest1 = gen_df_reg (set_dest, 0);
3502 dest2 = gen_df_reg (set_dest, 1);
3504 /* Now output, ordering such that we don't clobber any registers
3505 mentioned in the address. */
3506 if (reg_overlap_mentioned_p (dest1, word1))
3509 emit_insn (gen_movdf (dest2, word1));
3510 emit_insn (gen_movdf (dest1, word0));
3514 emit_insn (gen_movdf (dest1, word0));
3515 emit_insn (gen_movdf (dest2, word1));
3521 [(set (match_operand:TF 0 "memory_operand" "")
3522 (match_operand:TF 1 "register_operand" ""))]
3524 && offsettable_memref_p (operands[0])
3526 || ! TARGET_HARD_QUAD
3527 || ! fp_register_operand (operands[1], TFmode)))"
3528 [(clobber (const_int 0))]
3530 rtx set_src = operands[1];
3532 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 0),
3533 gen_df_reg (set_src, 0)));
3534 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 8),
3535 gen_df_reg (set_src, 1)));
3539 ;; SPARC V9 conditional move instructions.
3541 ;; We can handle larger constants here for some flavors, but for now we keep
3542 ;; it simple and only allow those constants supported by all flavors.
3543 ;; Note that emit_conditional_move canonicalizes operands 2,3 so that operand
3544 ;; 3 contains the constant if one is present, but we handle either for
3545 ;; generality (sparc.c puts a constant in operand 2).
3547 (define_expand "movqicc"
3548 [(set (match_operand:QI 0 "register_operand" "")
3549 (if_then_else:QI (match_operand 1 "comparison_operator" "")
3550 (match_operand:QI 2 "arith10_operand" "")
3551 (match_operand:QI 3 "arith10_operand" "")))]
3554 enum rtx_code code = GET_CODE (operands[1]);
3556 if (GET_MODE (sparc_compare_op0) == DImode
3560 if (sparc_compare_op1 == const0_rtx
3561 && GET_CODE (sparc_compare_op0) == REG
3562 && GET_MODE (sparc_compare_op0) == DImode
3563 && v9_regcmp_p (code))
3565 operands[1] = gen_rtx_fmt_ee (code, DImode,
3566 sparc_compare_op0, sparc_compare_op1);
3570 rtx cc_reg = gen_compare_reg (code,
3571 sparc_compare_op0, sparc_compare_op1);
3572 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3576 (define_expand "movhicc"
3577 [(set (match_operand:HI 0 "register_operand" "")
3578 (if_then_else:HI (match_operand 1 "comparison_operator" "")
3579 (match_operand:HI 2 "arith10_operand" "")
3580 (match_operand:HI 3 "arith10_operand" "")))]
3583 enum rtx_code code = GET_CODE (operands[1]);
3585 if (GET_MODE (sparc_compare_op0) == DImode
3589 if (sparc_compare_op1 == const0_rtx
3590 && GET_CODE (sparc_compare_op0) == REG
3591 && GET_MODE (sparc_compare_op0) == DImode
3592 && v9_regcmp_p (code))
3594 operands[1] = gen_rtx_fmt_ee (code, DImode,
3595 sparc_compare_op0, sparc_compare_op1);
3599 rtx cc_reg = gen_compare_reg (code,
3600 sparc_compare_op0, sparc_compare_op1);
3601 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3605 (define_expand "movsicc"
3606 [(set (match_operand:SI 0 "register_operand" "")
3607 (if_then_else:SI (match_operand 1 "comparison_operator" "")
3608 (match_operand:SI 2 "arith10_operand" "")
3609 (match_operand:SI 3 "arith10_operand" "")))]
3612 enum rtx_code code = GET_CODE (operands[1]);
3613 enum machine_mode op0_mode = GET_MODE (sparc_compare_op0);
3615 if (sparc_compare_op1 == const0_rtx
3616 && GET_CODE (sparc_compare_op0) == REG
3617 && (TARGET_ARCH64 && op0_mode == DImode && v9_regcmp_p (code)))
3619 operands[1] = gen_rtx_fmt_ee (code, op0_mode,
3620 sparc_compare_op0, sparc_compare_op1);
3624 rtx cc_reg = gen_compare_reg (code,
3625 sparc_compare_op0, sparc_compare_op1);
3626 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg),
3627 cc_reg, const0_rtx);
3631 (define_expand "movdicc"
3632 [(set (match_operand:DI 0 "register_operand" "")
3633 (if_then_else:DI (match_operand 1 "comparison_operator" "")
3634 (match_operand:DI 2 "arith10_double_operand" "")
3635 (match_operand:DI 3 "arith10_double_operand" "")))]
3638 enum rtx_code code = GET_CODE (operands[1]);
3640 if (sparc_compare_op1 == const0_rtx
3641 && GET_CODE (sparc_compare_op0) == REG
3642 && GET_MODE (sparc_compare_op0) == DImode
3643 && v9_regcmp_p (code))
3645 operands[1] = gen_rtx_fmt_ee (code, DImode,
3646 sparc_compare_op0, sparc_compare_op1);
3650 rtx cc_reg = gen_compare_reg (code,
3651 sparc_compare_op0, sparc_compare_op1);
3652 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg),
3653 cc_reg, const0_rtx);
3657 (define_expand "movsfcc"
3658 [(set (match_operand:SF 0 "register_operand" "")
3659 (if_then_else:SF (match_operand 1 "comparison_operator" "")
3660 (match_operand:SF 2 "register_operand" "")
3661 (match_operand:SF 3 "register_operand" "")))]
3662 "TARGET_V9 && TARGET_FPU"
3664 enum rtx_code code = GET_CODE (operands[1]);
3666 if (GET_MODE (sparc_compare_op0) == DImode
3670 if (sparc_compare_op1 == const0_rtx
3671 && GET_CODE (sparc_compare_op0) == REG
3672 && GET_MODE (sparc_compare_op0) == DImode
3673 && v9_regcmp_p (code))
3675 operands[1] = gen_rtx_fmt_ee (code, DImode,
3676 sparc_compare_op0, sparc_compare_op1);
3680 rtx cc_reg = gen_compare_reg (code,
3681 sparc_compare_op0, sparc_compare_op1);
3682 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3686 (define_expand "movdfcc"
3687 [(set (match_operand:DF 0 "register_operand" "")
3688 (if_then_else:DF (match_operand 1 "comparison_operator" "")
3689 (match_operand:DF 2 "register_operand" "")
3690 (match_operand:DF 3 "register_operand" "")))]
3691 "TARGET_V9 && TARGET_FPU"
3693 enum rtx_code code = GET_CODE (operands[1]);
3695 if (GET_MODE (sparc_compare_op0) == DImode
3699 if (sparc_compare_op1 == const0_rtx
3700 && GET_CODE (sparc_compare_op0) == REG
3701 && GET_MODE (sparc_compare_op0) == DImode
3702 && v9_regcmp_p (code))
3704 operands[1] = gen_rtx_fmt_ee (code, DImode,
3705 sparc_compare_op0, sparc_compare_op1);
3709 rtx cc_reg = gen_compare_reg (code,
3710 sparc_compare_op0, sparc_compare_op1);
3711 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3715 (define_expand "movtfcc"
3716 [(set (match_operand:TF 0 "register_operand" "")
3717 (if_then_else:TF (match_operand 1 "comparison_operator" "")
3718 (match_operand:TF 2 "register_operand" "")
3719 (match_operand:TF 3 "register_operand" "")))]
3720 "TARGET_V9 && TARGET_FPU"
3722 enum rtx_code code = GET_CODE (operands[1]);
3724 if (GET_MODE (sparc_compare_op0) == DImode
3728 if (sparc_compare_op1 == const0_rtx
3729 && GET_CODE (sparc_compare_op0) == REG
3730 && GET_MODE (sparc_compare_op0) == DImode
3731 && v9_regcmp_p (code))
3733 operands[1] = gen_rtx_fmt_ee (code, DImode,
3734 sparc_compare_op0, sparc_compare_op1);
3738 rtx cc_reg = gen_compare_reg (code,
3739 sparc_compare_op0, sparc_compare_op1);
3740 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3744 ;; Conditional move define_insns.
3746 (define_insn "*movqi_cc_sp64"
3747 [(set (match_operand:QI 0 "register_operand" "=r,r")
3748 (if_then_else:QI (match_operator 1 "comparison_operator"
3749 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3751 (match_operand:QI 3 "arith11_operand" "rL,0")
3752 (match_operand:QI 4 "arith11_operand" "0,rL")))]
3756 mov%c1\t%x2, %4, %0"
3757 [(set_attr "type" "cmove")])
3759 (define_insn "*movhi_cc_sp64"
3760 [(set (match_operand:HI 0 "register_operand" "=r,r")
3761 (if_then_else:HI (match_operator 1 "comparison_operator"
3762 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3764 (match_operand:HI 3 "arith11_operand" "rL,0")
3765 (match_operand:HI 4 "arith11_operand" "0,rL")))]
3769 mov%c1\t%x2, %4, %0"
3770 [(set_attr "type" "cmove")])
3772 (define_insn "*movsi_cc_sp64"
3773 [(set (match_operand:SI 0 "register_operand" "=r,r")
3774 (if_then_else:SI (match_operator 1 "comparison_operator"
3775 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3777 (match_operand:SI 3 "arith11_operand" "rL,0")
3778 (match_operand:SI 4 "arith11_operand" "0,rL")))]
3782 mov%c1\t%x2, %4, %0"
3783 [(set_attr "type" "cmove")])
3785 ;; ??? The constraints of operands 3,4 need work.
3786 (define_insn "*movdi_cc_sp64"
3787 [(set (match_operand:DI 0 "register_operand" "=r,r")
3788 (if_then_else:DI (match_operator 1 "comparison_operator"
3789 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3791 (match_operand:DI 3 "arith11_double_operand" "rLH,0")
3792 (match_operand:DI 4 "arith11_double_operand" "0,rLH")))]
3796 mov%c1\t%x2, %4, %0"
3797 [(set_attr "type" "cmove")])
3799 (define_insn "*movdi_cc_sp64_trunc"
3800 [(set (match_operand:SI 0 "register_operand" "=r,r")
3801 (if_then_else:SI (match_operator 1 "comparison_operator"
3802 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3804 (match_operand:SI 3 "arith11_double_operand" "rLH,0")
3805 (match_operand:SI 4 "arith11_double_operand" "0,rLH")))]
3809 mov%c1\t%x2, %4, %0"
3810 [(set_attr "type" "cmove")])
3812 (define_insn "*movsf_cc_sp64"
3813 [(set (match_operand:SF 0 "register_operand" "=f,f")
3814 (if_then_else:SF (match_operator 1 "comparison_operator"
3815 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3817 (match_operand:SF 3 "register_operand" "f,0")
3818 (match_operand:SF 4 "register_operand" "0,f")))]
3819 "TARGET_V9 && TARGET_FPU"
3821 fmovs%C1\t%x2, %3, %0
3822 fmovs%c1\t%x2, %4, %0"
3823 [(set_attr "type" "fpcmove")])
3825 (define_insn "movdf_cc_sp64"
3826 [(set (match_operand:DF 0 "register_operand" "=e,e")
3827 (if_then_else:DF (match_operator 1 "comparison_operator"
3828 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3830 (match_operand:DF 3 "register_operand" "e,0")
3831 (match_operand:DF 4 "register_operand" "0,e")))]
3832 "TARGET_V9 && TARGET_FPU"
3834 fmovd%C1\t%x2, %3, %0
3835 fmovd%c1\t%x2, %4, %0"
3836 [(set_attr "type" "fpcmove")
3837 (set_attr "fptype" "double")])
3839 (define_insn "*movtf_cc_hq_sp64"
3840 [(set (match_operand:TF 0 "register_operand" "=e,e")
3841 (if_then_else:TF (match_operator 1 "comparison_operator"
3842 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3844 (match_operand:TF 3 "register_operand" "e,0")
3845 (match_operand:TF 4 "register_operand" "0,e")))]
3846 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
3848 fmovq%C1\t%x2, %3, %0
3849 fmovq%c1\t%x2, %4, %0"
3850 [(set_attr "type" "fpcmove")])
3852 (define_insn_and_split "*movtf_cc_sp64"
3853 [(set (match_operand:TF 0 "register_operand" "=e,e")
3854 (if_then_else:TF (match_operator 1 "comparison_operator"
3855 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3857 (match_operand:TF 3 "register_operand" "e,0")
3858 (match_operand:TF 4 "register_operand" "0,e")))]
3859 "TARGET_V9 && TARGET_FPU && !TARGET_HARD_QUAD"
3861 "&& reload_completed"
3862 [(clobber (const_int 0))]
3864 rtx set_dest = operands[0];
3865 rtx set_srca = operands[3];
3866 rtx set_srcb = operands[4];
3867 int third = rtx_equal_p (set_dest, set_srca);
3869 rtx srca1, srca2, srcb1, srcb2;
3871 dest1 = gen_df_reg (set_dest, 0);
3872 dest2 = gen_df_reg (set_dest, 1);
3873 srca1 = gen_df_reg (set_srca, 0);
3874 srca2 = gen_df_reg (set_srca, 1);
3875 srcb1 = gen_df_reg (set_srcb, 0);
3876 srcb2 = gen_df_reg (set_srcb, 1);
3878 /* Now emit using the real source and destination we found, swapping
3879 the order if we detect overlap. */
3880 if ((third && reg_overlap_mentioned_p (dest1, srcb2))
3881 || (!third && reg_overlap_mentioned_p (dest1, srca2)))
3883 emit_insn (gen_movdf_cc_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
3884 emit_insn (gen_movdf_cc_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
3888 emit_insn (gen_movdf_cc_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
3889 emit_insn (gen_movdf_cc_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
3893 [(set_attr "length" "2")])
3895 (define_insn "*movqi_cc_reg_sp64"
3896 [(set (match_operand:QI 0 "register_operand" "=r,r")
3897 (if_then_else:QI (match_operator 1 "v9_regcmp_op"
3898 [(match_operand:DI 2 "register_operand" "r,r")
3900 (match_operand:QI 3 "arith10_operand" "rM,0")
3901 (match_operand:QI 4 "arith10_operand" "0,rM")))]
3904 movr%D1\t%2, %r3, %0
3905 movr%d1\t%2, %r4, %0"
3906 [(set_attr "type" "cmove")])
3908 (define_insn "*movhi_cc_reg_sp64"
3909 [(set (match_operand:HI 0 "register_operand" "=r,r")
3910 (if_then_else:HI (match_operator 1 "v9_regcmp_op"
3911 [(match_operand:DI 2 "register_operand" "r,r")
3913 (match_operand:HI 3 "arith10_operand" "rM,0")
3914 (match_operand:HI 4 "arith10_operand" "0,rM")))]
3917 movr%D1\t%2, %r3, %0
3918 movr%d1\t%2, %r4, %0"
3919 [(set_attr "type" "cmove")])
3921 (define_insn "*movsi_cc_reg_sp64"
3922 [(set (match_operand:SI 0 "register_operand" "=r,r")
3923 (if_then_else:SI (match_operator 1 "v9_regcmp_op"
3924 [(match_operand:DI 2 "register_operand" "r,r")
3926 (match_operand:SI 3 "arith10_operand" "rM,0")
3927 (match_operand:SI 4 "arith10_operand" "0,rM")))]
3930 movr%D1\t%2, %r3, %0
3931 movr%d1\t%2, %r4, %0"
3932 [(set_attr "type" "cmove")])
3934 ;; ??? The constraints of operands 3,4 need work.
3935 (define_insn "*movdi_cc_reg_sp64"
3936 [(set (match_operand:DI 0 "register_operand" "=r,r")
3937 (if_then_else:DI (match_operator 1 "v9_regcmp_op"
3938 [(match_operand:DI 2 "register_operand" "r,r")
3940 (match_operand:DI 3 "arith10_double_operand" "rMH,0")
3941 (match_operand:DI 4 "arith10_double_operand" "0,rMH")))]
3944 movr%D1\t%2, %r3, %0
3945 movr%d1\t%2, %r4, %0"
3946 [(set_attr "type" "cmove")])
3948 (define_insn "*movdi_cc_reg_sp64_trunc"
3949 [(set (match_operand:SI 0 "register_operand" "=r,r")
3950 (if_then_else:SI (match_operator 1 "v9_regcmp_op"
3951 [(match_operand:DI 2 "register_operand" "r,r")
3953 (match_operand:SI 3 "arith10_double_operand" "rMH,0")
3954 (match_operand:SI 4 "arith10_double_operand" "0,rMH")))]
3957 movr%D1\t%2, %r3, %0
3958 movr%d1\t%2, %r4, %0"
3959 [(set_attr "type" "cmove")])
3961 (define_insn "*movsf_cc_reg_sp64"
3962 [(set (match_operand:SF 0 "register_operand" "=f,f")
3963 (if_then_else:SF (match_operator 1 "v9_regcmp_op"