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"
3964 [(match_operand:DI 2 "register_operand" "r,r")
3966 (match_operand:SF 3 "register_operand" "f,0")
3967 (match_operand:SF 4 "register_operand" "0,f")))]
3968 "TARGET_ARCH64 && TARGET_FPU"
3970 fmovrs%D1\t%2, %3, %0
3971 fmovrs%d1\t%2, %4, %0"
3972 [(set_attr "type" "fpcrmove")])
3974 (define_insn "movdf_cc_reg_sp64"
3975 [(set (match_operand:DF 0 "register_operand" "=e,e")
3976 (if_then_else:DF (match_operator 1 "v9_regcmp_op"
3977 [(match_operand:DI 2 "register_operand" "r,r")
3979 (match_operand:DF 3 "register_operand" "e,0")
3980 (match_operand:DF 4 "register_operand" "0,e")))]
3981 "TARGET_ARCH64 && TARGET_FPU"
3983 fmovrd%D1\t%2, %3, %0
3984 fmovrd%d1\t%2, %4, %0"
3985 [(set_attr "type" "fpcrmove")
3986 (set_attr "fptype" "double")])
3988 (define_insn "*movtf_cc_reg_hq_sp64"
3989 [(set (match_operand:TF 0 "register_operand" "=e,e")
3990 (if_then_else:TF (match_operator 1 "v9_regcmp_op"
3991 [(match_operand:DI 2 "register_operand" "r,r")
3993 (match_operand:TF 3 "register_operand" "e,0")
3994 (match_operand:TF 4 "register_operand" "0,e")))]
3995 "TARGET_ARCH64 && TARGET_FPU && TARGET_HARD_QUAD"
3997 fmovrq%D1\t%2, %3, %0
3998 fmovrq%d1\t%2, %4, %0"
3999 [(set_attr "type" "fpcrmove")])
4001 (define_insn_and_split "*movtf_cc_reg_sp64"
4002 [(set (match_operand:TF 0 "register_operand" "=e,e")
4003 (if_then_else:TF (match_operator 1 "v9_regcmp_op"
4004 [(match_operand:DI 2 "register_operand" "r,r")
4006 (match_operand:TF 3 "register_operand" "e,0")
4007 (match_operand:TF 4 "register_operand" "0,e")))]
4008 "TARGET_ARCH64 && TARGET_FPU && ! TARGET_HARD_QUAD"
4010 "&& reload_completed"
4011 [(clobber (const_int 0))]
4013 rtx set_dest = operands[0];
4014 rtx set_srca = operands[3];
4015 rtx set_srcb = operands[4];
4016 int third = rtx_equal_p (set_dest, set_srca);
4018 rtx srca1, srca2, srcb1, srcb2;
4020 dest1 = gen_df_reg (set_dest, 0);
4021 dest2 = gen_df_reg (set_dest, 1);
4022 srca1 = gen_df_reg (set_srca, 0);
4023 srca2 = gen_df_reg (set_srca, 1);
4024 srcb1 = gen_df_reg (set_srcb, 0);
4025 srcb2 = gen_df_reg (set_srcb, 1);
4027 /* Now emit using the real source and destination we found, swapping
4028 the order if we detect overlap. */
4029 if ((third && reg_overlap_mentioned_p (dest1, srcb2))
4030 || (!third && reg_overlap_mentioned_p (dest1, srca2)))
4032 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
4033 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
4037 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
4038 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
4042 [(set_attr "length" "2")])
4045 ;;- zero extension instructions
4047 ;; These patterns originally accepted general_operands, however, slightly
4048 ;; better code is generated by only accepting register_operands, and then
4049 ;; letting combine generate the ldu[hb] insns.
4051 (define_expand "zero_extendhisi2"
4052 [(set (match_operand:SI 0 "register_operand" "")
4053 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
4056 rtx temp = gen_reg_rtx (SImode);
4057 rtx shift_16 = GEN_INT (16);
4058 int op1_subbyte = 0;
4060 if (GET_CODE (operand1) == SUBREG)
4062 op1_subbyte = SUBREG_BYTE (operand1);
4063 op1_subbyte /= GET_MODE_SIZE (SImode);
4064 op1_subbyte *= GET_MODE_SIZE (SImode);
4065 operand1 = XEXP (operand1, 0);
4068 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4070 emit_insn (gen_lshrsi3 (operand0, temp, shift_16));
4074 (define_insn "*zero_extendhisi2_insn"
4075 [(set (match_operand:SI 0 "register_operand" "=r")
4076 (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
4079 [(set_attr "type" "load")
4080 (set_attr "us3load_type" "3cycle")])
4082 (define_expand "zero_extendqihi2"
4083 [(set (match_operand:HI 0 "register_operand" "")
4084 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
4088 (define_insn "*zero_extendqihi2_insn"
4089 [(set (match_operand:HI 0 "register_operand" "=r,r")
4090 (zero_extend:HI (match_operand:QI 1 "input_operand" "r,m")))]
4091 "GET_CODE (operands[1]) != CONST_INT"
4095 [(set_attr "type" "*,load")
4096 (set_attr "us3load_type" "*,3cycle")])
4098 (define_expand "zero_extendqisi2"
4099 [(set (match_operand:SI 0 "register_operand" "")
4100 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
4104 (define_insn "*zero_extendqisi2_insn"
4105 [(set (match_operand:SI 0 "register_operand" "=r,r")
4106 (zero_extend:SI (match_operand:QI 1 "input_operand" "r,m")))]
4107 "GET_CODE (operands[1]) != CONST_INT"
4111 [(set_attr "type" "*,load")
4112 (set_attr "us3load_type" "*,3cycle")])
4114 (define_expand "zero_extendqidi2"
4115 [(set (match_operand:DI 0 "register_operand" "")
4116 (zero_extend:DI (match_operand:QI 1 "register_operand" "")))]
4120 (define_insn "*zero_extendqidi2_insn"
4121 [(set (match_operand:DI 0 "register_operand" "=r,r")
4122 (zero_extend:DI (match_operand:QI 1 "input_operand" "r,m")))]
4123 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
4127 [(set_attr "type" "*,load")
4128 (set_attr "us3load_type" "*,3cycle")])
4130 (define_expand "zero_extendhidi2"
4131 [(set (match_operand:DI 0 "register_operand" "")
4132 (zero_extend:DI (match_operand:HI 1 "register_operand" "")))]
4135 rtx temp = gen_reg_rtx (DImode);
4136 rtx shift_48 = GEN_INT (48);
4137 int op1_subbyte = 0;
4139 if (GET_CODE (operand1) == SUBREG)
4141 op1_subbyte = SUBREG_BYTE (operand1);
4142 op1_subbyte /= GET_MODE_SIZE (DImode);
4143 op1_subbyte *= GET_MODE_SIZE (DImode);
4144 operand1 = XEXP (operand1, 0);
4147 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
4149 emit_insn (gen_lshrdi3 (operand0, temp, shift_48));
4153 (define_insn "*zero_extendhidi2_insn"
4154 [(set (match_operand:DI 0 "register_operand" "=r")
4155 (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
4158 [(set_attr "type" "load")
4159 (set_attr "us3load_type" "3cycle")])
4162 ;; ??? Write truncdisi pattern using sra?
4164 (define_expand "zero_extendsidi2"
4165 [(set (match_operand:DI 0 "register_operand" "")
4166 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
4170 (define_insn "*zero_extendsidi2_insn_sp64"
4171 [(set (match_operand:DI 0 "register_operand" "=r,r")
4172 (zero_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
4173 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
4177 [(set_attr "type" "shift,load")])
4179 (define_insn_and_split "*zero_extendsidi2_insn_sp32"
4180 [(set (match_operand:DI 0 "register_operand" "=r")
4181 (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
4184 "&& reload_completed"
4185 [(set (match_dup 2) (match_dup 3))
4186 (set (match_dup 4) (match_dup 5))]
4190 dest1 = gen_highpart (SImode, operands[0]);
4191 dest2 = gen_lowpart (SImode, operands[0]);
4193 /* Swap the order in case of overlap. */
4194 if (REGNO (dest1) == REGNO (operands[1]))
4196 operands[2] = dest2;
4197 operands[3] = operands[1];
4198 operands[4] = dest1;
4199 operands[5] = const0_rtx;
4203 operands[2] = dest1;
4204 operands[3] = const0_rtx;
4205 operands[4] = dest2;
4206 operands[5] = operands[1];
4209 [(set_attr "length" "2")])
4211 ;; Simplify comparisons of extended values.
4213 (define_insn "*cmp_zero_extendqisi2"
4215 (compare:CC (zero_extend:SI (match_operand:QI 0 "register_operand" "r"))
4218 "andcc\t%0, 0xff, %%g0"
4219 [(set_attr "type" "compare")])
4221 (define_insn "*cmp_zero_qi"
4223 (compare:CC (match_operand:QI 0 "register_operand" "r")
4226 "andcc\t%0, 0xff, %%g0"
4227 [(set_attr "type" "compare")])
4229 (define_insn "*cmp_zero_extendqisi2_set"
4231 (compare:CC (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
4233 (set (match_operand:SI 0 "register_operand" "=r")
4234 (zero_extend:SI (match_dup 1)))]
4236 "andcc\t%1, 0xff, %0"
4237 [(set_attr "type" "compare")])
4239 (define_insn "*cmp_zero_extendqisi2_andcc_set"
4241 (compare:CC (and:SI (match_operand:SI 1 "register_operand" "r")
4244 (set (match_operand:SI 0 "register_operand" "=r")
4245 (zero_extend:SI (subreg:QI (match_dup 1) 0)))]
4247 "andcc\t%1, 0xff, %0"
4248 [(set_attr "type" "compare")])
4250 (define_insn "*cmp_zero_extendqidi2"
4252 (compare:CCX (zero_extend:DI (match_operand:QI 0 "register_operand" "r"))
4255 "andcc\t%0, 0xff, %%g0"
4256 [(set_attr "type" "compare")])
4258 (define_insn "*cmp_zero_qi_sp64"
4260 (compare:CCX (match_operand:QI 0 "register_operand" "r")
4263 "andcc\t%0, 0xff, %%g0"
4264 [(set_attr "type" "compare")])
4266 (define_insn "*cmp_zero_extendqidi2_set"
4268 (compare:CCX (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
4270 (set (match_operand:DI 0 "register_operand" "=r")
4271 (zero_extend:DI (match_dup 1)))]
4273 "andcc\t%1, 0xff, %0"
4274 [(set_attr "type" "compare")])
4276 (define_insn "*cmp_zero_extendqidi2_andcc_set"
4278 (compare:CCX (and:DI (match_operand:DI 1 "register_operand" "r")
4281 (set (match_operand:DI 0 "register_operand" "=r")
4282 (zero_extend:DI (subreg:QI (match_dup 1) 0)))]
4284 "andcc\t%1, 0xff, %0"
4285 [(set_attr "type" "compare")])
4287 ;; Similarly, handle {SI,DI}->QI mode truncation followed by a compare.
4289 (define_insn "*cmp_siqi_trunc"
4291 (compare:CC (subreg:QI (match_operand:SI 0 "register_operand" "r") 3)
4294 "andcc\t%0, 0xff, %%g0"
4295 [(set_attr "type" "compare")])
4297 (define_insn "*cmp_siqi_trunc_set"
4299 (compare:CC (subreg:QI (match_operand:SI 1 "register_operand" "r") 3)
4301 (set (match_operand:QI 0 "register_operand" "=r")
4302 (subreg:QI (match_dup 1) 3))]
4304 "andcc\t%1, 0xff, %0"
4305 [(set_attr "type" "compare")])
4307 (define_insn "*cmp_diqi_trunc"
4309 (compare:CC (subreg:QI (match_operand:DI 0 "register_operand" "r") 7)
4312 "andcc\t%0, 0xff, %%g0"
4313 [(set_attr "type" "compare")])
4315 (define_insn "*cmp_diqi_trunc_set"
4317 (compare:CC (subreg:QI (match_operand:DI 1 "register_operand" "r") 7)
4319 (set (match_operand:QI 0 "register_operand" "=r")
4320 (subreg:QI (match_dup 1) 7))]
4322 "andcc\t%1, 0xff, %0"
4323 [(set_attr "type" "compare")])
4325 ;;- sign extension instructions
4327 ;; These patterns originally accepted general_operands, however, slightly
4328 ;; better code is generated by only accepting register_operands, and then
4329 ;; letting combine generate the lds[hb] insns.
4331 (define_expand "extendhisi2"
4332 [(set (match_operand:SI 0 "register_operand" "")
4333 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
4336 rtx temp = gen_reg_rtx (SImode);
4337 rtx shift_16 = GEN_INT (16);
4338 int op1_subbyte = 0;
4340 if (GET_CODE (operand1) == SUBREG)
4342 op1_subbyte = SUBREG_BYTE (operand1);
4343 op1_subbyte /= GET_MODE_SIZE (SImode);
4344 op1_subbyte *= GET_MODE_SIZE (SImode);
4345 operand1 = XEXP (operand1, 0);
4348 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4350 emit_insn (gen_ashrsi3 (operand0, temp, shift_16));
4354 (define_insn "*sign_extendhisi2_insn"
4355 [(set (match_operand:SI 0 "register_operand" "=r")
4356 (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
4359 [(set_attr "type" "sload")
4360 (set_attr "us3load_type" "3cycle")])
4362 (define_expand "extendqihi2"
4363 [(set (match_operand:HI 0 "register_operand" "")
4364 (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
4367 rtx temp = gen_reg_rtx (SImode);
4368 rtx shift_24 = GEN_INT (24);
4369 int op1_subbyte = 0;
4370 int op0_subbyte = 0;
4372 if (GET_CODE (operand1) == SUBREG)
4374 op1_subbyte = SUBREG_BYTE (operand1);
4375 op1_subbyte /= GET_MODE_SIZE (SImode);
4376 op1_subbyte *= GET_MODE_SIZE (SImode);
4377 operand1 = XEXP (operand1, 0);
4379 if (GET_CODE (operand0) == SUBREG)
4381 op0_subbyte = SUBREG_BYTE (operand0);
4382 op0_subbyte /= GET_MODE_SIZE (SImode);
4383 op0_subbyte *= GET_MODE_SIZE (SImode);
4384 operand0 = XEXP (operand0, 0);
4386 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4388 if (GET_MODE (operand0) != SImode)
4389 operand0 = gen_rtx_SUBREG (SImode, operand0, op0_subbyte);
4390 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
4394 (define_insn "*sign_extendqihi2_insn"
4395 [(set (match_operand:HI 0 "register_operand" "=r")
4396 (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
4399 [(set_attr "type" "sload")
4400 (set_attr "us3load_type" "3cycle")])
4402 (define_expand "extendqisi2"
4403 [(set (match_operand:SI 0 "register_operand" "")
4404 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
4407 rtx temp = gen_reg_rtx (SImode);
4408 rtx shift_24 = GEN_INT (24);
4409 int op1_subbyte = 0;
4411 if (GET_CODE (operand1) == SUBREG)
4413 op1_subbyte = SUBREG_BYTE (operand1);
4414 op1_subbyte /= GET_MODE_SIZE (SImode);
4415 op1_subbyte *= GET_MODE_SIZE (SImode);
4416 operand1 = XEXP (operand1, 0);
4419 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4421 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
4425 (define_insn "*sign_extendqisi2_insn"
4426 [(set (match_operand:SI 0 "register_operand" "=r")
4427 (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
4430 [(set_attr "type" "sload")
4431 (set_attr "us3load_type" "3cycle")])
4433 (define_expand "extendqidi2"
4434 [(set (match_operand:DI 0 "register_operand" "")
4435 (sign_extend:DI (match_operand:QI 1 "register_operand" "")))]
4438 rtx temp = gen_reg_rtx (DImode);
4439 rtx shift_56 = GEN_INT (56);
4440 int op1_subbyte = 0;
4442 if (GET_CODE (operand1) == SUBREG)
4444 op1_subbyte = SUBREG_BYTE (operand1);
4445 op1_subbyte /= GET_MODE_SIZE (DImode);
4446 op1_subbyte *= GET_MODE_SIZE (DImode);
4447 operand1 = XEXP (operand1, 0);
4450 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
4452 emit_insn (gen_ashrdi3 (operand0, temp, shift_56));
4456 (define_insn "*sign_extendqidi2_insn"
4457 [(set (match_operand:DI 0 "register_operand" "=r")
4458 (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
4461 [(set_attr "type" "sload")
4462 (set_attr "us3load_type" "3cycle")])
4464 (define_expand "extendhidi2"
4465 [(set (match_operand:DI 0 "register_operand" "")
4466 (sign_extend:DI (match_operand:HI 1 "register_operand" "")))]
4469 rtx temp = gen_reg_rtx (DImode);
4470 rtx shift_48 = GEN_INT (48);
4471 int op1_subbyte = 0;
4473 if (GET_CODE (operand1) == SUBREG)
4475 op1_subbyte = SUBREG_BYTE (operand1);
4476 op1_subbyte /= GET_MODE_SIZE (DImode);
4477 op1_subbyte *= GET_MODE_SIZE (DImode);
4478 operand1 = XEXP (operand1, 0);
4481 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
4483 emit_insn (gen_ashrdi3 (operand0, temp, shift_48));
4487 (define_insn "*sign_extendhidi2_insn"
4488 [(set (match_operand:DI 0 "register_operand" "=r")
4489 (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
4492 [(set_attr "type" "sload")
4493 (set_attr "us3load_type" "3cycle")])
4495 (define_expand "extendsidi2"
4496 [(set (match_operand:DI 0 "register_operand" "")
4497 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
4501 (define_insn "*sign_extendsidi2_insn"
4502 [(set (match_operand:DI 0 "register_operand" "=r,r")
4503 (sign_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
4508 [(set_attr "type" "shift,sload")
4509 (set_attr "us3load_type" "*,3cycle")])
4511 ;; Special pattern for optimizing bit-field compares. This is needed
4512 ;; because combine uses this as a canonical form.
4514 (define_insn "*cmp_zero_extract"
4517 (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
4518 (match_operand:SI 1 "small_int_or_double" "n")
4519 (match_operand:SI 2 "small_int_or_double" "n"))
4521 "(GET_CODE (operands[2]) == CONST_INT
4522 && INTVAL (operands[2]) > 19)
4523 || (GET_CODE (operands[2]) == CONST_DOUBLE
4524 && CONST_DOUBLE_LOW (operands[2]) > 19)"
4526 int len = (GET_CODE (operands[1]) == CONST_INT
4527 ? INTVAL (operands[1])
4528 : CONST_DOUBLE_LOW (operands[1]));
4530 (GET_CODE (operands[2]) == CONST_INT
4531 ? INTVAL (operands[2])
4532 : CONST_DOUBLE_LOW (operands[2])) - len;
4533 HOST_WIDE_INT mask = ((1 << len) - 1) << pos;
4535 operands[1] = GEN_INT (mask);
4536 return "andcc\t%0, %1, %%g0";
4538 [(set_attr "type" "compare")])
4540 (define_insn "*cmp_zero_extract_sp64"
4543 (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
4544 (match_operand:SI 1 "small_int_or_double" "n")
4545 (match_operand:SI 2 "small_int_or_double" "n"))
4548 && ((GET_CODE (operands[2]) == CONST_INT
4549 && INTVAL (operands[2]) > 51)
4550 || (GET_CODE (operands[2]) == CONST_DOUBLE
4551 && CONST_DOUBLE_LOW (operands[2]) > 51))"
4553 int len = (GET_CODE (operands[1]) == CONST_INT
4554 ? INTVAL (operands[1])
4555 : CONST_DOUBLE_LOW (operands[1]));
4557 (GET_CODE (operands[2]) == CONST_INT
4558 ? INTVAL (operands[2])
4559 : CONST_DOUBLE_LOW (operands[2])) - len;
4560 HOST_WIDE_INT mask = (((unsigned HOST_WIDE_INT) 1 << len) - 1) << pos;
4562 operands[1] = GEN_INT (mask);
4563 return "andcc\t%0, %1, %%g0";
4565 [(set_attr "type" "compare")])
4567 ;; Conversions between float, double and long double.
4569 (define_insn "extendsfdf2"
4570 [(set (match_operand:DF 0 "register_operand" "=e")
4572 (match_operand:SF 1 "register_operand" "f")))]
4575 [(set_attr "type" "fp")
4576 (set_attr "fptype" "double")])
4578 (define_expand "extendsftf2"
4579 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4581 (match_operand:SF 1 "register_operand" "")))]
4582 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4583 "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
4585 (define_insn "*extendsftf2_hq"
4586 [(set (match_operand:TF 0 "register_operand" "=e")
4588 (match_operand:SF 1 "register_operand" "f")))]
4589 "TARGET_FPU && TARGET_HARD_QUAD"
4591 [(set_attr "type" "fp")])
4593 (define_expand "extenddftf2"
4594 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4596 (match_operand:DF 1 "register_operand" "")))]
4597 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4598 "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
4600 (define_insn "*extenddftf2_hq"
4601 [(set (match_operand:TF 0 "register_operand" "=e")
4603 (match_operand:DF 1 "register_operand" "e")))]
4604 "TARGET_FPU && TARGET_HARD_QUAD"
4606 [(set_attr "type" "fp")])
4608 (define_insn "truncdfsf2"
4609 [(set (match_operand:SF 0 "register_operand" "=f")
4611 (match_operand:DF 1 "register_operand" "e")))]
4614 [(set_attr "type" "fp")
4615 (set_attr "fptype" "double")])
4617 (define_expand "trunctfsf2"
4618 [(set (match_operand:SF 0 "register_operand" "")
4620 (match_operand:TF 1 "general_operand" "")))]
4621 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4622 "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
4624 (define_insn "*trunctfsf2_hq"
4625 [(set (match_operand:SF 0 "register_operand" "=f")
4627 (match_operand:TF 1 "register_operand" "e")))]
4628 "TARGET_FPU && TARGET_HARD_QUAD"
4630 [(set_attr "type" "fp")])
4632 (define_expand "trunctfdf2"
4633 [(set (match_operand:DF 0 "register_operand" "")
4635 (match_operand:TF 1 "general_operand" "")))]
4636 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4637 "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
4639 (define_insn "*trunctfdf2_hq"
4640 [(set (match_operand:DF 0 "register_operand" "=e")
4642 (match_operand:TF 1 "register_operand" "e")))]
4643 "TARGET_FPU && TARGET_HARD_QUAD"
4645 [(set_attr "type" "fp")])
4647 ;; Conversion between fixed point and floating point.
4649 (define_insn "floatsisf2"
4650 [(set (match_operand:SF 0 "register_operand" "=f")
4651 (float:SF (match_operand:SI 1 "register_operand" "f")))]
4654 [(set_attr "type" "fp")
4655 (set_attr "fptype" "double")])
4657 (define_insn "floatsidf2"
4658 [(set (match_operand:DF 0 "register_operand" "=e")
4659 (float:DF (match_operand:SI 1 "register_operand" "f")))]
4662 [(set_attr "type" "fp")
4663 (set_attr "fptype" "double")])
4665 (define_expand "floatsitf2"
4666 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4667 (float:TF (match_operand:SI 1 "register_operand" "")))]
4668 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4669 "emit_tfmode_cvt (FLOAT, operands); DONE;")
4671 (define_insn "*floatsitf2_hq"
4672 [(set (match_operand:TF 0 "register_operand" "=e")
4673 (float:TF (match_operand:SI 1 "register_operand" "f")))]
4674 "TARGET_FPU && TARGET_HARD_QUAD"
4676 [(set_attr "type" "fp")])
4678 (define_expand "floatunssitf2"
4679 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4680 (unsigned_float:TF (match_operand:SI 1 "register_operand" "")))]
4681 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4682 "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
4684 ;; Now the same for 64 bit sources.
4686 (define_insn "floatdisf2"
4687 [(set (match_operand:SF 0 "register_operand" "=f")
4688 (float:SF (match_operand:DI 1 "register_operand" "e")))]
4689 "TARGET_V9 && TARGET_FPU"
4691 [(set_attr "type" "fp")
4692 (set_attr "fptype" "double")])
4694 (define_expand "floatunsdisf2"
4695 [(use (match_operand:SF 0 "register_operand" ""))
4696 (use (match_operand:DI 1 "general_operand" ""))]
4697 "TARGET_ARCH64 && TARGET_FPU"
4698 "sparc_emit_floatunsdi (operands, SFmode); DONE;")
4700 (define_insn "floatdidf2"
4701 [(set (match_operand:DF 0 "register_operand" "=e")
4702 (float:DF (match_operand:DI 1 "register_operand" "e")))]
4703 "TARGET_V9 && TARGET_FPU"
4705 [(set_attr "type" "fp")
4706 (set_attr "fptype" "double")])
4708 (define_expand "floatunsdidf2"
4709 [(use (match_operand:DF 0 "register_operand" ""))
4710 (use (match_operand:DI 1 "general_operand" ""))]
4711 "TARGET_ARCH64 && TARGET_FPU"
4712 "sparc_emit_floatunsdi (operands, DFmode); DONE;")
4714 (define_expand "floatditf2"
4715 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4716 (float:TF (match_operand:DI 1 "register_operand" "")))]
4717 "TARGET_FPU && TARGET_V9 && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4718 "emit_tfmode_cvt (FLOAT, operands); DONE;")
4720 (define_insn "*floatditf2_hq"
4721 [(set (match_operand:TF 0 "register_operand" "=e")
4722 (float:TF (match_operand:DI 1 "register_operand" "e")))]
4723 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
4725 [(set_attr "type" "fp")])
4727 (define_expand "floatunsditf2"
4728 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4729 (unsigned_float:TF (match_operand:DI 1 "register_operand" "")))]
4730 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4731 "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
4733 ;; Convert a float to an actual integer.
4734 ;; Truncation is performed as part of the conversion.
4736 (define_insn "fix_truncsfsi2"
4737 [(set (match_operand:SI 0 "register_operand" "=f")
4738 (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
4741 [(set_attr "type" "fp")
4742 (set_attr "fptype" "double")])
4744 (define_insn "fix_truncdfsi2"
4745 [(set (match_operand:SI 0 "register_operand" "=f")
4746 (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
4749 [(set_attr "type" "fp")
4750 (set_attr "fptype" "double")])
4752 (define_expand "fix_trunctfsi2"
4753 [(set (match_operand:SI 0 "register_operand" "")
4754 (fix:SI (match_operand:TF 1 "general_operand" "")))]
4755 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4756 "emit_tfmode_cvt (FIX, operands); DONE;")
4758 (define_insn "*fix_trunctfsi2_hq"
4759 [(set (match_operand:SI 0 "register_operand" "=f")
4760 (fix:SI (match_operand:TF 1 "register_operand" "e")))]
4761 "TARGET_FPU && TARGET_HARD_QUAD"
4763 [(set_attr "type" "fp")])
4765 (define_expand "fixuns_trunctfsi2"
4766 [(set (match_operand:SI 0 "register_operand" "")
4767 (unsigned_fix:SI (match_operand:TF 1 "general_operand" "")))]
4768 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4769 "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
4771 ;; Now the same, for V9 targets
4773 (define_insn "fix_truncsfdi2"
4774 [(set (match_operand:DI 0 "register_operand" "=e")
4775 (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
4776 "TARGET_V9 && TARGET_FPU"
4778 [(set_attr "type" "fp")
4779 (set_attr "fptype" "double")])
4781 (define_expand "fixuns_truncsfdi2"
4782 [(use (match_operand:DI 0 "register_operand" ""))
4783 (use (match_operand:SF 1 "general_operand" ""))]
4784 "TARGET_ARCH64 && TARGET_FPU"
4785 "sparc_emit_fixunsdi (operands, SFmode); DONE;")
4787 (define_insn "fix_truncdfdi2"
4788 [(set (match_operand:DI 0 "register_operand" "=e")
4789 (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
4790 "TARGET_V9 && TARGET_FPU"
4792 [(set_attr "type" "fp")
4793 (set_attr "fptype" "double")])
4795 (define_expand "fixuns_truncdfdi2"
4796 [(use (match_operand:DI 0 "register_operand" ""))
4797 (use (match_operand:DF 1 "general_operand" ""))]
4798 "TARGET_ARCH64 && TARGET_FPU"
4799 "sparc_emit_fixunsdi (operands, DFmode); DONE;")
4801 (define_expand "fix_trunctfdi2"
4802 [(set (match_operand:DI 0 "register_operand" "")
4803 (fix:DI (match_operand:TF 1 "general_operand" "")))]
4804 "TARGET_V9 && TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4805 "emit_tfmode_cvt (FIX, operands); DONE;")
4807 (define_insn "*fix_trunctfdi2_hq"
4808 [(set (match_operand:DI 0 "register_operand" "=e")
4809 (fix:DI (match_operand:TF 1 "register_operand" "e")))]
4810 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
4812 [(set_attr "type" "fp")])
4814 (define_expand "fixuns_trunctfdi2"
4815 [(set (match_operand:DI 0 "register_operand" "")
4816 (unsigned_fix:DI (match_operand:TF 1 "general_operand" "")))]
4817 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4818 "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
4820 ;;- arithmetic instructions
4822 (define_expand "adddi3"
4823 [(set (match_operand:DI 0 "register_operand" "")
4824 (plus:DI (match_operand:DI 1 "register_operand" "")
4825 (match_operand:DI 2 "arith_double_add_operand" "")))]
4828 if (! TARGET_ARCH64)
4830 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
4831 gen_rtx_SET (VOIDmode, operands[0],
4832 gen_rtx_PLUS (DImode, operands[1],
4834 gen_rtx_CLOBBER (VOIDmode,
4835 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
4840 (define_insn_and_split "adddi3_insn_sp32"
4841 [(set (match_operand:DI 0 "register_operand" "=r")
4842 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
4843 (match_operand:DI 2 "arith_double_operand" "rHI")))
4844 (clobber (reg:CC 100))]
4847 "&& reload_completed"
4848 [(parallel [(set (reg:CC_NOOV 100)
4849 (compare:CC_NOOV (plus:SI (match_dup 4)
4853 (plus:SI (match_dup 4) (match_dup 5)))])
4855 (plus:SI (plus:SI (match_dup 7)
4857 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4859 operands[3] = gen_lowpart (SImode, operands[0]);
4860 operands[4] = gen_lowpart (SImode, operands[1]);
4861 operands[5] = gen_lowpart (SImode, operands[2]);
4862 operands[6] = gen_highpart (SImode, operands[0]);
4863 operands[7] = gen_highpart_mode (SImode, DImode, operands[1]);
4864 #if HOST_BITS_PER_WIDE_INT == 32
4865 if (GET_CODE (operands[2]) == CONST_INT)
4867 if (INTVAL (operands[2]) < 0)
4868 operands[8] = constm1_rtx;
4870 operands[8] = const0_rtx;
4874 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
4876 [(set_attr "length" "2")])
4879 [(set (match_operand:DI 0 "register_operand" "")
4880 (minus:DI (match_operand:DI 1 "arith_double_operand" "")
4881 (match_operand:DI 2 "arith_double_operand" "")))
4882 (clobber (reg:CC 100))]
4883 "! TARGET_ARCH64 && reload_completed"
4884 [(parallel [(set (reg:CC_NOOV 100)
4885 (compare:CC_NOOV (minus:SI (match_dup 4)
4889 (minus:SI (match_dup 4) (match_dup 5)))])
4891 (minus:SI (minus:SI (match_dup 7)
4893 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4895 operands[3] = gen_lowpart (SImode, operands[0]);
4896 operands[4] = gen_lowpart (SImode, operands[1]);
4897 operands[5] = gen_lowpart (SImode, operands[2]);
4898 operands[6] = gen_highpart (SImode, operands[0]);
4899 operands[7] = gen_highpart (SImode, operands[1]);
4900 #if HOST_BITS_PER_WIDE_INT == 32
4901 if (GET_CODE (operands[2]) == CONST_INT)
4903 if (INTVAL (operands[2]) < 0)
4904 operands[8] = constm1_rtx;
4906 operands[8] = const0_rtx;
4910 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
4913 ;; LTU here means "carry set"
4915 [(set (match_operand:SI 0 "register_operand" "=r")
4916 (plus:SI (plus:SI (match_operand:SI 1 "arith_operand" "%r")
4917 (match_operand:SI 2 "arith_operand" "rI"))
4918 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4921 [(set_attr "type" "ialuX")])
4923 (define_insn_and_split "*addx_extend_sp32"
4924 [(set (match_operand:DI 0 "register_operand" "=r")
4925 (zero_extend:DI (plus:SI (plus:SI
4926 (match_operand:SI 1 "reg_or_0_operand" "%rJ")
4927 (match_operand:SI 2 "arith_operand" "rI"))
4928 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4931 "&& reload_completed"
4932 [(set (match_dup 3) (plus:SI (plus:SI (match_dup 1) (match_dup 2))
4933 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
4934 (set (match_dup 4) (const_int 0))]
4935 "operands[3] = gen_lowpart (SImode, operands[0]);
4936 operands[4] = gen_highpart_mode (SImode, DImode, operands[1]);"
4937 [(set_attr "length" "2")])
4939 (define_insn "*addx_extend_sp64"
4940 [(set (match_operand:DI 0 "register_operand" "=r")
4941 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
4942 (match_operand:SI 2 "arith_operand" "rI"))
4943 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4946 [(set_attr "type" "ialuX")])
4949 [(set (match_operand:SI 0 "register_operand" "=r")
4950 (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
4951 (match_operand:SI 2 "arith_operand" "rI"))
4952 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4955 [(set_attr "type" "ialuX")])
4957 (define_insn "*subx_extend_sp64"
4958 [(set (match_operand:DI 0 "register_operand" "=r")
4959 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
4960 (match_operand:SI 2 "arith_operand" "rI"))
4961 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4964 [(set_attr "type" "ialuX")])
4966 (define_insn_and_split "*subx_extend"
4967 [(set (match_operand:DI 0 "register_operand" "=r")
4968 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
4969 (match_operand:SI 2 "arith_operand" "rI"))
4970 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4973 "&& reload_completed"
4974 [(set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 2))
4975 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
4976 (set (match_dup 4) (const_int 0))]
4977 "operands[3] = gen_lowpart (SImode, operands[0]);
4978 operands[4] = gen_highpart (SImode, operands[0]);"
4979 [(set_attr "length" "2")])
4981 (define_insn_and_split ""
4982 [(set (match_operand:DI 0 "register_operand" "=r")
4983 (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4984 (match_operand:DI 2 "register_operand" "r")))
4985 (clobber (reg:CC 100))]
4988 "&& reload_completed"
4989 [(parallel [(set (reg:CC_NOOV 100)
4990 (compare:CC_NOOV (plus:SI (match_dup 3) (match_dup 1))
4992 (set (match_dup 5) (plus:SI (match_dup 3) (match_dup 1)))])
4994 (plus:SI (plus:SI (match_dup 4) (const_int 0))
4995 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4996 "operands[3] = gen_lowpart (SImode, operands[2]);
4997 operands[4] = gen_highpart (SImode, operands[2]);
4998 operands[5] = gen_lowpart (SImode, operands[0]);
4999 operands[6] = gen_highpart (SImode, operands[0]);"
5000 [(set_attr "length" "2")])
5002 (define_insn "*adddi3_sp64"
5003 [(set (match_operand:DI 0 "register_operand" "=r,r")
5004 (plus:DI (match_operand:DI 1 "register_operand" "%r,r")
5005 (match_operand:DI 2 "arith_double_add_operand" "rHI,O")))]
5011 (define_insn "addsi3"
5012 [(set (match_operand:SI 0 "register_operand" "=r,r,d")
5013 (plus:SI (match_operand:SI 1 "register_operand" "%r,r,d")
5014 (match_operand:SI 2 "arith_add_operand" "rI,O,d")))]
5019 fpadd32s\t%1, %2, %0"
5020 [(set_attr "type" "*,*,fga")])
5022 (define_insn "*cmp_cc_plus"
5023 [(set (reg:CC_NOOV 100)
5024 (compare:CC_NOOV (plus:SI (match_operand:SI 0 "arith_operand" "%r")
5025 (match_operand:SI 1 "arith_operand" "rI"))
5028 "addcc\t%0, %1, %%g0"
5029 [(set_attr "type" "compare")])
5031 (define_insn "*cmp_ccx_plus"
5032 [(set (reg:CCX_NOOV 100)
5033 (compare:CCX_NOOV (plus:DI (match_operand:DI 0 "arith_double_operand" "%r")
5034 (match_operand:DI 1 "arith_double_operand" "rHI"))
5037 "addcc\t%0, %1, %%g0"
5038 [(set_attr "type" "compare")])
5040 (define_insn "*cmp_cc_plus_set"
5041 [(set (reg:CC_NOOV 100)
5042 (compare:CC_NOOV (plus:SI (match_operand:SI 1 "arith_operand" "%r")
5043 (match_operand:SI 2 "arith_operand" "rI"))
5045 (set (match_operand:SI 0 "register_operand" "=r")
5046 (plus:SI (match_dup 1) (match_dup 2)))]
5049 [(set_attr "type" "compare")])
5051 (define_insn "*cmp_ccx_plus_set"
5052 [(set (reg:CCX_NOOV 100)
5053 (compare:CCX_NOOV (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
5054 (match_operand:DI 2 "arith_double_operand" "rHI"))
5056 (set (match_operand:DI 0 "register_operand" "=r")
5057 (plus:DI (match_dup 1) (match_dup 2)))]
5060 [(set_attr "type" "compare")])
5062 (define_expand "subdi3"
5063 [(set (match_operand:DI 0 "register_operand" "")
5064 (minus:DI (match_operand:DI 1 "register_operand" "")
5065 (match_operand:DI 2 "arith_double_add_operand" "")))]
5068 if (! TARGET_ARCH64)
5070 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
5071 gen_rtx_SET (VOIDmode, operands[0],
5072 gen_rtx_MINUS (DImode, operands[1],
5074 gen_rtx_CLOBBER (VOIDmode,
5075 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
5080 (define_insn_and_split "*subdi3_sp32"
5081 [(set (match_operand:DI 0 "register_operand" "=r")
5082 (minus:DI (match_operand:DI 1 "register_operand" "r")
5083 (match_operand:DI 2 "arith_double_operand" "rHI")))
5084 (clobber (reg:CC 100))]
5087 "&& reload_completed
5088 && (GET_CODE (operands[2]) == CONST_INT
5089 || GET_CODE (operands[2]) == CONST_DOUBLE)"
5090 [(clobber (const_int 0))]
5094 highp = gen_highpart_mode (SImode, DImode, operands[2]);
5095 lowp = gen_lowpart (SImode, operands[2]);
5096 if ((lowp == const0_rtx)
5097 && (operands[0] == operands[1]))
5099 emit_insn (gen_rtx_SET (VOIDmode,
5100 gen_highpart (SImode, operands[0]),
5101 gen_rtx_MINUS (SImode,
5102 gen_highpart_mode (SImode, DImode,
5108 emit_insn (gen_cmp_minus_cc_set (gen_lowpart (SImode, operands[0]),
5109 gen_lowpart (SImode, operands[1]),
5111 emit_insn (gen_subx (gen_highpart (SImode, operands[0]),
5112 gen_highpart_mode (SImode, DImode, operands[1]),
5117 [(set_attr "length" "2")])
5120 [(set (match_operand:DI 0 "register_operand" "")
5121 (minus:DI (match_operand:DI 1 "register_operand" "")
5122 (match_operand:DI 2 "register_operand" "")))
5123 (clobber (reg:CC 100))]
5125 && reload_completed"
5126 [(clobber (const_int 0))]
5128 emit_insn (gen_cmp_minus_cc_set (gen_lowpart (SImode, operands[0]),
5129 gen_lowpart (SImode, operands[1]),
5130 gen_lowpart (SImode, operands[2])));
5131 emit_insn (gen_subx (gen_highpart (SImode, operands[0]),
5132 gen_highpart (SImode, operands[1]),
5133 gen_highpart (SImode, operands[2])));
5137 (define_insn_and_split ""
5138 [(set (match_operand:DI 0 "register_operand" "=r")
5139 (minus:DI (match_operand:DI 1 "register_operand" "r")
5140 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))
5141 (clobber (reg:CC 100))]
5144 "&& reload_completed"
5145 [(parallel [(set (reg:CC_NOOV 100)
5146 (compare:CC_NOOV (minus:SI (match_dup 3) (match_dup 2))
5148 (set (match_dup 5) (minus:SI (match_dup 3) (match_dup 2)))])
5150 (minus:SI (minus:SI (match_dup 4) (const_int 0))
5151 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5152 "operands[3] = gen_lowpart (SImode, operands[1]);
5153 operands[4] = gen_highpart (SImode, operands[1]);
5154 operands[5] = gen_lowpart (SImode, operands[0]);
5155 operands[6] = gen_highpart (SImode, operands[0]);"
5156 [(set_attr "length" "2")])
5158 (define_insn "*subdi3_sp64"
5159 [(set (match_operand:DI 0 "register_operand" "=r,r")
5160 (minus:DI (match_operand:DI 1 "register_operand" "r,r")
5161 (match_operand:DI 2 "arith_double_add_operand" "rHI,O")))]
5167 (define_insn "subsi3"
5168 [(set (match_operand:SI 0 "register_operand" "=r,r,d")
5169 (minus:SI (match_operand:SI 1 "register_operand" "r,r,d")
5170 (match_operand:SI 2 "arith_add_operand" "rI,O,d")))]
5175 fpsub32s\t%1, %2, %0"
5176 [(set_attr "type" "*,*,fga")])
5178 (define_insn "*cmp_minus_cc"
5179 [(set (reg:CC_NOOV 100)
5180 (compare:CC_NOOV (minus:SI (match_operand:SI 0 "reg_or_0_operand" "rJ")
5181 (match_operand:SI 1 "arith_operand" "rI"))
5184 "subcc\t%r0, %1, %%g0"
5185 [(set_attr "type" "compare")])
5187 (define_insn "*cmp_minus_ccx"
5188 [(set (reg:CCX_NOOV 100)
5189 (compare:CCX_NOOV (minus:DI (match_operand:DI 0 "register_operand" "r")
5190 (match_operand:DI 1 "arith_double_operand" "rHI"))
5193 "subcc\t%0, %1, %%g0"
5194 [(set_attr "type" "compare")])
5196 (define_insn "cmp_minus_cc_set"
5197 [(set (reg:CC_NOOV 100)
5198 (compare:CC_NOOV (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5199 (match_operand:SI 2 "arith_operand" "rI"))
5201 (set (match_operand:SI 0 "register_operand" "=r")
5202 (minus:SI (match_dup 1) (match_dup 2)))]
5204 "subcc\t%r1, %2, %0"
5205 [(set_attr "type" "compare")])
5207 (define_insn "*cmp_minus_ccx_set"
5208 [(set (reg:CCX_NOOV 100)
5209 (compare:CCX_NOOV (minus:DI (match_operand:DI 1 "register_operand" "r")
5210 (match_operand:DI 2 "arith_double_operand" "rHI"))
5212 (set (match_operand:DI 0 "register_operand" "=r")
5213 (minus:DI (match_dup 1) (match_dup 2)))]
5216 [(set_attr "type" "compare")])
5218 ;; Integer Multiply/Divide.
5220 ;; The 32 bit multiply/divide instructions are deprecated on v9, but at
5221 ;; least in UltraSPARC I, II and IIi it is a win tick-wise.
5223 (define_insn "mulsi3"
5224 [(set (match_operand:SI 0 "register_operand" "=r")
5225 (mult:SI (match_operand:SI 1 "arith_operand" "%r")
5226 (match_operand:SI 2 "arith_operand" "rI")))]
5229 [(set_attr "type" "imul")])
5231 (define_expand "muldi3"
5232 [(set (match_operand:DI 0 "register_operand" "=r")
5233 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r")
5234 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5235 "TARGET_ARCH64 || TARGET_V8PLUS"
5239 emit_insn (gen_muldi3_v8plus (operands[0], operands[1], operands[2]));
5244 (define_insn "*muldi3_sp64"
5245 [(set (match_operand:DI 0 "register_operand" "=r")
5246 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r")
5247 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5250 [(set_attr "type" "imul")])
5252 ;; V8plus wide multiply.
5254 (define_insn "muldi3_v8plus"
5255 [(set (match_operand:DI 0 "register_operand" "=r,h")
5256 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r,0")
5257 (match_operand:DI 2 "arith_double_operand" "rI,rI")))
5258 (clobber (match_scratch:SI 3 "=&h,X"))
5259 (clobber (match_scratch:SI 4 "=&h,X"))]
5262 if (sparc_check_64 (operands[1], insn) <= 0)
5263 output_asm_insn ("srl\t%L1, 0, %L1", operands);
5264 if (which_alternative == 1)
5265 output_asm_insn ("sllx\t%H1, 32, %H1", operands);
5266 if (GET_CODE (operands[2]) == CONST_INT)
5268 if (which_alternative == 1)
5269 return "or\t%L1, %H1, %H1\n\tmulx\t%H1, %2, %L0\;srlx\t%L0, 32, %H0";
5271 return "sllx\t%H1, 32, %3\n\tor\t%L1, %3, %3\n\tmulx\t%3, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0";
5273 else if (rtx_equal_p (operands[1], operands[2]))
5275 if (which_alternative == 1)
5276 return "or\t%L1, %H1, %H1\n\tmulx\t%H1, %H1, %L0\;srlx\t%L0, 32, %H0";
5278 return "sllx\t%H1, 32, %3\n\tor\t%L1, %3, %3\n\tmulx\t%3, %3, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0";
5280 if (sparc_check_64 (operands[2], insn) <= 0)
5281 output_asm_insn ("srl\t%L2, 0, %L2", operands);
5282 if (which_alternative == 1)
5283 return "or\t%L1, %H1, %H1\n\tsllx\t%H2, 32, %L1\n\tor\t%L2, %L1, %L1\n\tmulx\t%H1, %L1, %L0\;srlx\t%L0, 32, %H0";
5285 return "sllx\t%H1, 32, %3\n\tsllx\t%H2, 32, %4\n\tor\t%L1, %3, %3\n\tor\t%L2, %4, %4\n\tmulx\t%3, %4, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0";
5287 [(set_attr "type" "multi")
5288 (set_attr "length" "9,8")])
5290 (define_insn "*cmp_mul_set"
5292 (compare:CC (mult:SI (match_operand:SI 1 "arith_operand" "%r")
5293 (match_operand:SI 2 "arith_operand" "rI"))
5295 (set (match_operand:SI 0 "register_operand" "=r")
5296 (mult:SI (match_dup 1) (match_dup 2)))]
5297 "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS"
5298 "smulcc\t%1, %2, %0"
5299 [(set_attr "type" "imul")])
5301 (define_expand "mulsidi3"
5302 [(set (match_operand:DI 0 "register_operand" "")
5303 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
5304 (sign_extend:DI (match_operand:SI 2 "arith_operand" ""))))]
5307 if (CONSTANT_P (operands[2]))
5310 emit_insn (gen_const_mulsidi3_v8plus (operands[0], operands[1],
5312 else if (TARGET_ARCH32)
5313 emit_insn (gen_const_mulsidi3_sp32 (operands[0], operands[1],
5316 emit_insn (gen_const_mulsidi3_sp64 (operands[0], operands[1],
5322 emit_insn (gen_mulsidi3_v8plus (operands[0], operands[1], operands[2]));
5327 ;; V9 puts the 64 bit product in a 64 bit register. Only out or global
5328 ;; registers can hold 64 bit values in the V8plus environment.
5330 (define_insn "mulsidi3_v8plus"
5331 [(set (match_operand:DI 0 "register_operand" "=h,r")
5332 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5333 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
5334 (clobber (match_scratch:SI 3 "=X,&h"))]
5337 smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
5338 smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
5339 [(set_attr "type" "multi")
5340 (set_attr "length" "2,3")])
5343 (define_insn "const_mulsidi3_v8plus"
5344 [(set (match_operand:DI 0 "register_operand" "=h,r")
5345 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5346 (match_operand:DI 2 "small_int" "I,I")))
5347 (clobber (match_scratch:SI 3 "=X,&h"))]
5350 smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
5351 smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
5352 [(set_attr "type" "multi")
5353 (set_attr "length" "2,3")])
5356 (define_insn "*mulsidi3_sp32"
5357 [(set (match_operand:DI 0 "register_operand" "=r")
5358 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5359 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
5362 return TARGET_SPARCLET
5363 ? "smuld\t%1, %2, %L0"
5364 : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
5367 (if_then_else (eq_attr "isa" "sparclet")
5368 (const_string "imul") (const_string "multi")))
5369 (set (attr "length")
5370 (if_then_else (eq_attr "isa" "sparclet")
5371 (const_int 1) (const_int 2)))])
5373 (define_insn "*mulsidi3_sp64"
5374 [(set (match_operand:DI 0 "register_operand" "=r")
5375 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5376 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
5377 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5379 [(set_attr "type" "imul")])
5381 ;; Extra pattern, because sign_extend of a constant isn't valid.
5384 (define_insn "const_mulsidi3_sp32"
5385 [(set (match_operand:DI 0 "register_operand" "=r")
5386 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5387 (match_operand:DI 2 "small_int" "I")))]
5390 return TARGET_SPARCLET
5391 ? "smuld\t%1, %2, %L0"
5392 : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
5395 (if_then_else (eq_attr "isa" "sparclet")
5396 (const_string "imul") (const_string "multi")))
5397 (set (attr "length")
5398 (if_then_else (eq_attr "isa" "sparclet")
5399 (const_int 1) (const_int 2)))])
5401 (define_insn "const_mulsidi3_sp64"
5402 [(set (match_operand:DI 0 "register_operand" "=r")
5403 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5404 (match_operand:DI 2 "small_int" "I")))]
5405 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5407 [(set_attr "type" "imul")])
5409 (define_expand "smulsi3_highpart"
5410 [(set (match_operand:SI 0 "register_operand" "")
5412 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
5413 (sign_extend:DI (match_operand:SI 2 "arith_operand" "")))
5415 "TARGET_HARD_MUL && TARGET_ARCH32"
5417 if (CONSTANT_P (operands[2]))
5421 emit_insn (gen_const_smulsi3_highpart_v8plus (operands[0],
5427 emit_insn (gen_const_smulsi3_highpart (operands[0], operands[1], operands[2]));
5432 emit_insn (gen_smulsi3_highpart_v8plus (operands[0], operands[1],
5433 operands[2], GEN_INT (32)));
5439 (define_insn "smulsi3_highpart_v8plus"
5440 [(set (match_operand:SI 0 "register_operand" "=h,r")
5442 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5443 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
5444 (match_operand:SI 3 "const_int_operand" "i,i"))))
5445 (clobber (match_scratch:SI 4 "=X,&h"))]
5448 smul\t%1, %2, %0\;srlx\t%0, %3, %0
5449 smul\t%1, %2, %4\;srlx\t%4, %3, %0"
5450 [(set_attr "type" "multi")
5451 (set_attr "length" "2")])
5453 ;; The combiner changes TRUNCATE in the previous pattern to SUBREG.
5456 [(set (match_operand:SI 0 "register_operand" "=h,r")
5459 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5460 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
5461 (match_operand:SI 3 "const_int_operand" "i,i"))
5463 (clobber (match_scratch:SI 4 "=X,&h"))]
5466 smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
5467 smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
5468 [(set_attr "type" "multi")
5469 (set_attr "length" "2")])
5472 (define_insn "const_smulsi3_highpart_v8plus"
5473 [(set (match_operand:SI 0 "register_operand" "=h,r")
5475 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5476 (match_operand:DI 2 "small_int" "i,i"))
5477 (match_operand:SI 3 "const_int_operand" "i,i"))))
5478 (clobber (match_scratch:SI 4 "=X,&h"))]
5481 smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
5482 smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
5483 [(set_attr "type" "multi")
5484 (set_attr "length" "2")])
5487 (define_insn "*smulsi3_highpart_sp32"
5488 [(set (match_operand:SI 0 "register_operand" "=r")
5490 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5491 (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
5494 "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
5495 [(set_attr "type" "multi")
5496 (set_attr "length" "2")])
5499 (define_insn "const_smulsi3_highpart"
5500 [(set (match_operand:SI 0 "register_operand" "=r")
5502 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5503 (match_operand:DI 2 "small_int" "i"))
5506 "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
5507 [(set_attr "type" "multi")
5508 (set_attr "length" "2")])
5510 (define_expand "umulsidi3"
5511 [(set (match_operand:DI 0 "register_operand" "")
5512 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
5513 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" ""))))]
5516 if (CONSTANT_P (operands[2]))
5519 emit_insn (gen_const_umulsidi3_v8plus (operands[0], operands[1],
5521 else if (TARGET_ARCH32)
5522 emit_insn (gen_const_umulsidi3_sp32 (operands[0], operands[1],
5525 emit_insn (gen_const_umulsidi3_sp64 (operands[0], operands[1],
5531 emit_insn (gen_umulsidi3_v8plus (operands[0], operands[1], operands[2]));
5537 (define_insn "umulsidi3_v8plus"
5538 [(set (match_operand:DI 0 "register_operand" "=h,r")
5539 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5540 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
5541 (clobber (match_scratch:SI 3 "=X,&h"))]
5544 umul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
5545 umul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
5546 [(set_attr "type" "multi")
5547 (set_attr "length" "2,3")])
5550 (define_insn "*umulsidi3_sp32"
5551 [(set (match_operand:DI 0 "register_operand" "=r")
5552 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5553 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
5556 return TARGET_SPARCLET
5557 ? "umuld\t%1, %2, %L0"
5558 : "umul\t%1, %2, %L0\n\trd\t%%y, %H0";
5561 (if_then_else (eq_attr "isa" "sparclet")
5562 (const_string "imul") (const_string "multi")))
5563 (set (attr "length")
5564 (if_then_else (eq_attr "isa" "sparclet")
5565 (const_int 1) (const_int 2)))])
5567 (define_insn "*umulsidi3_sp64"
5568 [(set (match_operand:DI 0 "register_operand" "=r")
5569 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5570 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
5571 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5573 [(set_attr "type" "imul")])
5575 ;; Extra pattern, because sign_extend of a constant isn't valid.
5578 (define_insn "const_umulsidi3_sp32"
5579 [(set (match_operand:DI 0 "register_operand" "=r")
5580 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5581 (match_operand:DI 2 "uns_small_int" "")))]
5584 return TARGET_SPARCLET
5585 ? "umuld\t%1, %s2, %L0"
5586 : "umul\t%1, %s2, %L0\n\trd\t%%y, %H0";
5589 (if_then_else (eq_attr "isa" "sparclet")
5590 (const_string "imul") (const_string "multi")))
5591 (set (attr "length")
5592 (if_then_else (eq_attr "isa" "sparclet")
5593 (const_int 1) (const_int 2)))])
5595 (define_insn "const_umulsidi3_sp64"
5596 [(set (match_operand:DI 0 "register_operand" "=r")
5597 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5598 (match_operand:DI 2 "uns_small_int" "")))]
5599 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5601 [(set_attr "type" "imul")])
5604 (define_insn "const_umulsidi3_v8plus"
5605 [(set (match_operand:DI 0 "register_operand" "=h,r")
5606 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5607 (match_operand:DI 2 "uns_small_int" "")))
5608 (clobber (match_scratch:SI 3 "=X,h"))]
5611 umul\t%1, %s2, %L0\n\tsrlx\t%L0, 32, %H0
5612 umul\t%1, %s2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
5613 [(set_attr "type" "multi")
5614 (set_attr "length" "2,3")])
5616 (define_expand "umulsi3_highpart"
5617 [(set (match_operand:SI 0 "register_operand" "")
5619 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
5620 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" "")))
5622 "TARGET_HARD_MUL && TARGET_ARCH32"
5624 if (CONSTANT_P (operands[2]))
5628 emit_insn (gen_const_umulsi3_highpart_v8plus (operands[0],
5634 emit_insn (gen_const_umulsi3_highpart (operands[0], operands[1], operands[2]));
5639 emit_insn (gen_umulsi3_highpart_v8plus (operands[0], operands[1],
5640 operands[2], GEN_INT (32)));
5646 (define_insn "umulsi3_highpart_v8plus"
5647 [(set (match_operand:SI 0 "register_operand" "=h,r")
5649 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5650 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
5651 (match_operand:SI 3 "const_int_operand" "i,i"))))
5652 (clobber (match_scratch:SI 4 "=X,h"))]
5655 umul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
5656 umul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
5657 [(set_attr "type" "multi")
5658 (set_attr "length" "2")])
5661 (define_insn "const_umulsi3_highpart_v8plus"
5662 [(set (match_operand:SI 0 "register_operand" "=h,r")
5664 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5665 (match_operand:DI 2 "uns_small_int" ""))
5666 (match_operand:SI 3 "const_int_operand" "i,i"))))
5667 (clobber (match_scratch:SI 4 "=X,h"))]
5670 umul\t%1, %s2, %0\n\tsrlx\t%0, %3, %0
5671 umul\t%1, %s2, %4\n\tsrlx\t%4, %3, %0"
5672 [(set_attr "type" "multi")
5673 (set_attr "length" "2")])
5676 (define_insn "*umulsi3_highpart_sp32"
5677 [(set (match_operand:SI 0 "register_operand" "=r")
5679 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5680 (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
5683 "umul\t%1, %2, %%g0\n\trd\t%%y, %0"
5684 [(set_attr "type" "multi")
5685 (set_attr "length" "2")])
5688 (define_insn "const_umulsi3_highpart"
5689 [(set (match_operand:SI 0 "register_operand" "=r")
5691 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5692 (match_operand:DI 2 "uns_small_int" ""))
5695 "umul\t%1, %s2, %%g0\n\trd\t%%y, %0"
5696 [(set_attr "type" "multi")
5697 (set_attr "length" "2")])
5699 ;; The v8 architecture specifies that there must be 3 instructions between
5700 ;; a y register write and a use of it for correct results.
5702 (define_expand "divsi3"
5703 [(parallel [(set (match_operand:SI 0 "register_operand" "=r,r")
5704 (div:SI (match_operand:SI 1 "register_operand" "r,r")
5705 (match_operand:SI 2 "input_operand" "rI,m")))
5706 (clobber (match_scratch:SI 3 "=&r,&r"))])]
5707 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
5711 operands[3] = gen_reg_rtx(SImode);
5712 emit_insn (gen_ashrsi3 (operands[3], operands[1], GEN_INT (31)));
5713 emit_insn (gen_divsi3_sp64 (operands[0], operands[1], operands[2],
5719 (define_insn "divsi3_sp32"
5720 [(set (match_operand:SI 0 "register_operand" "=r,r")
5721 (div:SI (match_operand:SI 1 "register_operand" "r,r")
5722 (match_operand:SI 2 "input_operand" "rI,m")))
5723 (clobber (match_scratch:SI 3 "=&r,&r"))]
5724 "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS)
5727 if (which_alternative == 0)
5729 return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tsdiv\t%1, %2, %0";
5731 return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tnop\n\tnop\n\tnop\n\tsdiv\t%1, %2, %0";
5734 return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tld\t%2, %3\n\tsdiv\t%1, %3, %0";
5736 return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tld\t%2, %3\n\tnop\n\tnop\n\tsdiv\t%1, %3, %0";
5738 [(set_attr "type" "multi")
5739 (set (attr "length")
5740 (if_then_else (eq_attr "isa" "v9")
5741 (const_int 4) (const_int 6)))])
5743 (define_insn "divsi3_sp64"
5744 [(set (match_operand:SI 0 "register_operand" "=r")
5745 (div:SI (match_operand:SI 1 "register_operand" "r")
5746 (match_operand:SI 2 "input_operand" "rI")))
5747 (use (match_operand:SI 3 "register_operand" "r"))]
5748 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5749 "wr\t%%g0, %3, %%y\n\tsdiv\t%1, %2, %0"
5750 [(set_attr "type" "multi")
5751 (set_attr "length" "2")])
5753 (define_insn "divdi3"
5754 [(set (match_operand:DI 0 "register_operand" "=r")
5755 (div:DI (match_operand:DI 1 "register_operand" "r")
5756 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5759 [(set_attr "type" "idiv")])
5761 (define_insn "*cmp_sdiv_cc_set"
5763 (compare:CC (div:SI (match_operand:SI 1 "register_operand" "r")
5764 (match_operand:SI 2 "arith_operand" "rI"))
5766 (set (match_operand:SI 0 "register_operand" "=r")
5767 (div:SI (match_dup 1) (match_dup 2)))
5768 (clobber (match_scratch:SI 3 "=&r"))]
5769 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
5772 return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tsdivcc\t%1, %2, %0";
5774 return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tnop\n\tnop\n\tnop\n\tsdivcc\t%1, %2, %0";
5776 [(set_attr "type" "multi")
5777 (set (attr "length")
5778 (if_then_else (eq_attr "isa" "v9")
5779 (const_int 3) (const_int 6)))])
5782 (define_expand "udivsi3"
5783 [(set (match_operand:SI 0 "register_operand" "")
5784 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "")
5785 (match_operand:SI 2 "input_operand" "")))]
5786 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
5789 (define_insn "udivsi3_sp32"
5790 [(set (match_operand:SI 0 "register_operand" "=r,&r,&r")
5791 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "r,r,m")
5792 (match_operand:SI 2 "input_operand" "rI,m,r")))]
5794 || TARGET_DEPRECATED_V8_INSNS)
5797 output_asm_insn ("wr\t%%g0, %%g0, %%y", operands);
5798 switch (which_alternative)
5801 return "nop\n\tnop\n\tnop\n\tudiv\t%1, %2, %0";
5803 return "ld\t%2, %0\n\tnop\n\tnop\n\tudiv\t%1, %0, %0";
5805 return "ld\t%1, %0\n\tnop\n\tnop\n\tudiv\t%0, %2, %0";
5808 [(set_attr "type" "multi")
5809 (set_attr "length" "5")])
5811 (define_insn "udivsi3_sp64"
5812 [(set (match_operand:SI 0 "register_operand" "=r")
5813 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "r")
5814 (match_operand:SI 2 "input_operand" "rI")))]
5815 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5816 "wr\t%%g0, 0, %%y\n\tudiv\t%1, %2, %0"
5817 [(set_attr "type" "multi")
5818 (set_attr "length" "2")])
5820 (define_insn "udivdi3"
5821 [(set (match_operand:DI 0 "register_operand" "=r")
5822 (udiv:DI (match_operand:DI 1 "register_operand" "r")
5823 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5826 [(set_attr "type" "idiv")])
5828 (define_insn "*cmp_udiv_cc_set"
5830 (compare:CC (udiv:SI (match_operand:SI 1 "register_operand" "r")
5831 (match_operand:SI 2 "arith_operand" "rI"))
5833 (set (match_operand:SI 0 "register_operand" "=r")
5834 (udiv:SI (match_dup 1) (match_dup 2)))]
5836 || TARGET_DEPRECATED_V8_INSNS"
5839 return "wr\t%%g0, %%g0, %%y\n\tudivcc\t%1, %2, %0";
5841 return "wr\t%%g0, %%g0, %%y\n\tnop\n\tnop\n\tnop\n\tudivcc\t%1, %2, %0";
5843 [(set_attr "type" "multi")
5844 (set (attr "length")
5845 (if_then_else (eq_attr "isa" "v9")
5846 (const_int 2) (const_int 5)))])
5848 ; sparclet multiply/accumulate insns
5850 (define_insn "*smacsi"
5851 [(set (match_operand:SI 0 "register_operand" "=r")
5852 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "%r")
5853 (match_operand:SI 2 "arith_operand" "rI"))
5854 (match_operand:SI 3 "register_operand" "0")))]
5857 [(set_attr "type" "imul")])
5859 (define_insn "*smacdi"
5860 [(set (match_operand:DI 0 "register_operand" "=r")
5861 (plus:DI (mult:DI (sign_extend:DI
5862 (match_operand:SI 1 "register_operand" "%r"))
5864 (match_operand:SI 2 "register_operand" "r")))
5865 (match_operand:DI 3 "register_operand" "0")))]
5867 "smacd\t%1, %2, %L0"
5868 [(set_attr "type" "imul")])
5870 (define_insn "*umacdi"
5871 [(set (match_operand:DI 0 "register_operand" "=r")
5872 (plus:DI (mult:DI (zero_extend:DI
5873 (match_operand:SI 1 "register_operand" "%r"))
5875 (match_operand:SI 2 "register_operand" "r")))
5876 (match_operand:DI 3 "register_operand" "0")))]
5878 "umacd\t%1, %2, %L0"
5879 [(set_attr "type" "imul")])
5881 ;;- Boolean instructions
5882 ;; We define DImode `and' so with DImode `not' we can get
5883 ;; DImode `andn'. Other combinations are possible.
5885 (define_expand "anddi3"
5886 [(set (match_operand:DI 0 "register_operand" "")
5887 (and:DI (match_operand:DI 1 "arith_double_operand" "")
5888 (match_operand:DI 2 "arith_double_operand" "")))]
5892 (define_insn "*anddi3_sp32"
5893 [(set (match_operand:DI 0 "register_operand" "=r,b")
5894 (and:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
5895 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
5900 [(set_attr "type" "*,fga")
5901 (set_attr "length" "2,*")
5902 (set_attr "fptype" "double")])
5904 (define_insn "*anddi3_sp64"
5905 [(set (match_operand:DI 0 "register_operand" "=r,b")
5906 (and:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
5907 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
5912 [(set_attr "type" "*,fga")
5913 (set_attr "fptype" "double")])
5915 (define_insn "andsi3"
5916 [(set (match_operand:SI 0 "register_operand" "=r,d")
5917 (and:SI (match_operand:SI 1 "arith_operand" "%r,d")
5918 (match_operand:SI 2 "arith_operand" "rI,d")))]
5923 [(set_attr "type" "*,fga")])
5926 [(set (match_operand:SI 0 "register_operand" "")
5927 (and:SI (match_operand:SI 1 "register_operand" "")
5928 (match_operand:SI 2 "" "")))
5929 (clobber (match_operand:SI 3 "register_operand" ""))]
5930 "GET_CODE (operands[2]) == CONST_INT
5931 && !SMALL_INT32 (operands[2])
5932 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
5933 [(set (match_dup 3) (match_dup 4))
5934 (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 1)))]
5936 operands[4] = GEN_INT (~INTVAL (operands[2]));
5939 ;; Split DImode logical operations requiring two instructions.
5941 [(set (match_operand:DI 0 "register_operand" "")
5942 (match_operator:DI 1 "cc_arithop" ; AND, IOR, XOR
5943 [(match_operand:DI 2 "register_operand" "")
5944 (match_operand:DI 3 "arith_double_operand" "")]))]
5947 && ((GET_CODE (operands[0]) == REG
5948 && REGNO (operands[0]) < 32)
5949 || (GET_CODE (operands[0]) == SUBREG
5950 && GET_CODE (SUBREG_REG (operands[0])) == REG
5951 && REGNO (SUBREG_REG (operands[0])) < 32))"
5952 [(set (match_dup 4) (match_op_dup:SI 1 [(match_dup 6) (match_dup 8)]))
5953 (set (match_dup 5) (match_op_dup:SI 1 [(match_dup 7) (match_dup 9)]))]
5955 operands[4] = gen_highpart (SImode, operands[0]);
5956 operands[5] = gen_lowpart (SImode, operands[0]);
5957 operands[6] = gen_highpart (SImode, operands[2]);
5958 operands[7] = gen_lowpart (SImode, operands[2]);
5959 #if HOST_BITS_PER_WIDE_INT == 32
5960 if (GET_CODE (operands[3]) == CONST_INT)
5962 if (INTVAL (operands[3]) < 0)
5963 operands[8] = constm1_rtx;
5965 operands[8] = const0_rtx;
5969 operands[8] = gen_highpart_mode (SImode, DImode, operands[3]);
5970 operands[9] = gen_lowpart (SImode, operands[3]);
5973 (define_insn_and_split "*and_not_di_sp32"
5974 [(set (match_operand:DI 0 "register_operand" "=r,b")
5975 (and:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
5976 (match_operand:DI 2 "register_operand" "r,b")))]
5980 fandnot1\t%1, %2, %0"
5981 "&& reload_completed
5982 && ((GET_CODE (operands[0]) == REG
5983 && REGNO (operands[0]) < 32)
5984 || (GET_CODE (operands[0]) == SUBREG
5985 && GET_CODE (SUBREG_REG (operands[0])) == REG
5986 && REGNO (SUBREG_REG (operands[0])) < 32))"
5987 [(set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))
5988 (set (match_dup 6) (and:SI (not:SI (match_dup 7)) (match_dup 8)))]
5989 "operands[3] = gen_highpart (SImode, operands[0]);
5990 operands[4] = gen_highpart (SImode, operands[1]);
5991 operands[5] = gen_highpart (SImode, operands[2]);
5992 operands[6] = gen_lowpart (SImode, operands[0]);
5993 operands[7] = gen_lowpart (SImode, operands[1]);
5994 operands[8] = gen_lowpart (SImode, operands[2]);"
5995 [(set_attr "type" "*,fga")
5996 (set_attr "length" "2,*")
5997 (set_attr "fptype" "double")])
5999 (define_insn "*and_not_di_sp64"
6000 [(set (match_operand:DI 0 "register_operand" "=r,b")
6001 (and:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6002 (match_operand:DI 2 "register_operand" "r,b")))]
6006 fandnot1\t%1, %2, %0"
6007 [(set_attr "type" "*,fga")
6008 (set_attr "fptype" "double")])
6010 (define_insn "*and_not_si"
6011 [(set (match_operand:SI 0 "register_operand" "=r,d")
6012 (and:SI (not:SI (match_operand:SI 1 "register_operand" "r,d"))
6013 (match_operand:SI 2 "register_operand" "r,d")))]
6017 fandnot1s\t%1, %2, %0"
6018 [(set_attr "type" "*,fga")])
6020 (define_expand "iordi3"
6021 [(set (match_operand:DI 0 "register_operand" "")
6022 (ior:DI (match_operand:DI 1 "arith_double_operand" "")
6023 (match_operand:DI 2 "arith_double_operand" "")))]
6027 (define_insn "*iordi3_sp32"
6028 [(set (match_operand:DI 0 "register_operand" "=r,b")
6029 (ior:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6030 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6035 [(set_attr "type" "*,fga")
6036 (set_attr "length" "2,*")
6037 (set_attr "fptype" "double")])
6039 (define_insn "*iordi3_sp64"
6040 [(set (match_operand:DI 0 "register_operand" "=r,b")
6041 (ior:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6042 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6047 [(set_attr "type" "*,fga")
6048 (set_attr "fptype" "double")])
6050 (define_insn "iorsi3"
6051 [(set (match_operand:SI 0 "register_operand" "=r,d")
6052 (ior:SI (match_operand:SI 1 "arith_operand" "%r,d")
6053 (match_operand:SI 2 "arith_operand" "rI,d")))]
6058 [(set_attr "type" "*,fga")])
6061 [(set (match_operand:SI 0 "register_operand" "")
6062 (ior:SI (match_operand:SI 1 "register_operand" "")
6063 (match_operand:SI 2 "" "")))
6064 (clobber (match_operand:SI 3 "register_operand" ""))]
6065 "GET_CODE (operands[2]) == CONST_INT
6066 && !SMALL_INT32 (operands[2])
6067 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6068 [(set (match_dup 3) (match_dup 4))
6069 (set (match_dup 0) (ior:SI (not:SI (match_dup 3)) (match_dup 1)))]
6071 operands[4] = GEN_INT (~INTVAL (operands[2]));
6074 (define_insn_and_split "*or_not_di_sp32"
6075 [(set (match_operand:DI 0 "register_operand" "=r,b")
6076 (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6077 (match_operand:DI 2 "register_operand" "r,b")))]
6081 fornot1\t%1, %2, %0"
6082 "&& reload_completed
6083 && ((GET_CODE (operands[0]) == REG
6084 && REGNO (operands[0]) < 32)
6085 || (GET_CODE (operands[0]) == SUBREG
6086 && GET_CODE (SUBREG_REG (operands[0])) == REG
6087 && REGNO (SUBREG_REG (operands[0])) < 32))"
6088 [(set (match_dup 3) (ior:SI (not:SI (match_dup 4)) (match_dup 5)))
6089 (set (match_dup 6) (ior:SI (not:SI (match_dup 7)) (match_dup 8)))]
6090 "operands[3] = gen_highpart (SImode, operands[0]);
6091 operands[4] = gen_highpart (SImode, operands[1]);
6092 operands[5] = gen_highpart (SImode, operands[2]);
6093 operands[6] = gen_lowpart (SImode, operands[0]);
6094 operands[7] = gen_lowpart (SImode, operands[1]);
6095 operands[8] = gen_lowpart (SImode, operands[2]);"
6096 [(set_attr "type" "*,fga")
6097 (set_attr "length" "2,*")
6098 (set_attr "fptype" "double")])
6100 (define_insn "*or_not_di_sp64"
6101 [(set (match_operand:DI 0 "register_operand" "=r,b")
6102 (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6103 (match_operand:DI 2 "register_operand" "r,b")))]
6107 fornot1\t%1, %2, %0"
6108 [(set_attr "type" "*,fga")
6109 (set_attr "fptype" "double")])
6111 (define_insn "*or_not_si"
6112 [(set (match_operand:SI 0 "register_operand" "=r,d")
6113 (ior:SI (not:SI (match_operand:SI 1 "register_operand" "r,d"))
6114 (match_operand:SI 2 "register_operand" "r,d")))]
6118 fornot1s\t%1, %2, %0"
6119 [(set_attr "type" "*,fga")])
6121 (define_expand "xordi3"
6122 [(set (match_operand:DI 0 "register_operand" "")
6123 (xor:DI (match_operand:DI 1 "arith_double_operand" "")
6124 (match_operand:DI 2 "arith_double_operand" "")))]
6128 (define_insn "*xordi3_sp32"
6129 [(set (match_operand:DI 0 "register_operand" "=r,b")
6130 (xor:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6131 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6136 [(set_attr "type" "*,fga")
6137 (set_attr "length" "2,*")
6138 (set_attr "fptype" "double")])
6140 (define_insn "*xordi3_sp64"
6141 [(set (match_operand:DI 0 "register_operand" "=r,b")
6142 (xor:DI (match_operand:DI 1 "arith_double_operand" "%rJ,b")
6143 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6148 [(set_attr "type" "*,fga")
6149 (set_attr "fptype" "double")])
6151 (define_insn "*xordi3_sp64_dbl"
6152 [(set (match_operand:DI 0 "register_operand" "=r")
6153 (xor:DI (match_operand:DI 1 "register_operand" "r")
6154 (match_operand:DI 2 "const64_operand" "")))]
6156 && HOST_BITS_PER_WIDE_INT != 64)"
6159 (define_insn "xorsi3"
6160 [(set (match_operand:SI 0 "register_operand" "=r,d")
6161 (xor:SI (match_operand:SI 1 "arith_operand" "%rJ,d")
6162 (match_operand:SI 2 "arith_operand" "rI,d")))]
6167 [(set_attr "type" "*,fga")])
6170 [(set (match_operand:SI 0 "register_operand" "")
6171 (xor:SI (match_operand:SI 1 "register_operand" "")
6172 (match_operand:SI 2 "" "")))
6173 (clobber (match_operand:SI 3 "register_operand" ""))]
6174 "GET_CODE (operands[2]) == CONST_INT
6175 && !SMALL_INT32 (operands[2])
6176 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6177 [(set (match_dup 3) (match_dup 4))
6178 (set (match_dup 0) (not:SI (xor:SI (match_dup 3) (match_dup 1))))]
6180 operands[4] = GEN_INT (~INTVAL (operands[2]));
6184 [(set (match_operand:SI 0 "register_operand" "")
6185 (not:SI (xor:SI (match_operand:SI 1 "register_operand" "")
6186 (match_operand:SI 2 "" ""))))
6187 (clobber (match_operand:SI 3 "register_operand" ""))]
6188 "GET_CODE (operands[2]) == CONST_INT
6189 && !SMALL_INT32 (operands[2])
6190 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6191 [(set (match_dup 3) (match_dup 4))
6192 (set (match_dup 0) (xor:SI (match_dup 3) (match_dup 1)))]
6194 operands[4] = GEN_INT (~INTVAL (operands[2]));
6197 ;; xnor patterns. Note that (a ^ ~b) == (~a ^ b) == ~(a ^ b).
6198 ;; Combine now canonicalizes to the rightmost expression.
6199 (define_insn_and_split "*xor_not_di_sp32"
6200 [(set (match_operand:DI 0 "register_operand" "=r,b")
6201 (not:DI (xor:DI (match_operand:DI 1 "register_operand" "r,b")
6202 (match_operand:DI 2 "register_operand" "r,b"))))]
6207 "&& reload_completed
6208 && ((GET_CODE (operands[0]) == REG
6209 && REGNO (operands[0]) < 32)
6210 || (GET_CODE (operands[0]) == SUBREG
6211 && GET_CODE (SUBREG_REG (operands[0])) == REG
6212 && REGNO (SUBREG_REG (operands[0])) < 32))"
6213 [(set (match_dup 3) (not:SI (xor:SI (match_dup 4) (match_dup 5))))
6214 (set (match_dup 6) (not:SI (xor:SI (match_dup 7) (match_dup 8))))]
6215 "operands[3] = gen_highpart (SImode, operands[0]);
6216 operands[4] = gen_highpart (SImode, operands[1]);
6217 operands[5] = gen_highpart (SImode, operands[2]);
6218 operands[6] = gen_lowpart (SImode, operands[0]);
6219 operands[7] = gen_lowpart (SImode, operands[1]);
6220 operands[8] = gen_lowpart (SImode, operands[2]);"
6221 [(set_attr "type" "*,fga")
6222 (set_attr "length" "2,*")
6223 (set_attr "fptype" "double")])
6225 (define_insn "*xor_not_di_sp64"
6226 [(set (match_operand:DI 0 "register_operand" "=r,b")
6227 (not:DI (xor:DI (match_operand:DI 1 "reg_or_0_operand" "rJ,b")
6228 (match_operand:DI 2 "arith_double_operand" "rHI,b"))))]
6233 [(set_attr "type" "*,fga")
6234 (set_attr "fptype" "double")])
6236 (define_insn "*xor_not_si"
6237 [(set (match_operand:SI 0 "register_operand" "=r,d")
6238 (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "rJ,d")
6239 (match_operand:SI 2 "arith_operand" "rI,d"))))]
6244 [(set_attr "type" "*,fga")])
6246 ;; These correspond to the above in the case where we also (or only)
6247 ;; want to set the condition code.
6249 (define_insn "*cmp_cc_arith_op"
6252 (match_operator:SI 2 "cc_arithop"
6253 [(match_operand:SI 0 "arith_operand" "%r")
6254 (match_operand:SI 1 "arith_operand" "rI")])
6257 "%A2cc\t%0, %1, %%g0"
6258 [(set_attr "type" "compare")])
6260 (define_insn "*cmp_ccx_arith_op"
6263 (match_operator:DI 2 "cc_arithop"
6264 [(match_operand:DI 0 "arith_double_operand" "%r")
6265 (match_operand:DI 1 "arith_double_operand" "rHI")])
6268 "%A2cc\t%0, %1, %%g0"
6269 [(set_attr "type" "compare")])
6271 (define_insn "*cmp_cc_arith_op_set"
6274 (match_operator:SI 3 "cc_arithop"
6275 [(match_operand:SI 1 "arith_operand" "%r")
6276 (match_operand:SI 2 "arith_operand" "rI")])
6278 (set (match_operand:SI 0 "register_operand" "=r")
6279 (match_operator:SI 4 "cc_arithop" [(match_dup 1) (match_dup 2)]))]
6280 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
6282 [(set_attr "type" "compare")])
6284 (define_insn "*cmp_ccx_arith_op_set"
6287 (match_operator:DI 3 "cc_arithop"
6288 [(match_operand:DI 1 "arith_double_operand" "%r")
6289 (match_operand:DI 2 "arith_double_operand" "rHI")])
6291 (set (match_operand:DI 0 "register_operand" "=r")
6292 (match_operator:DI 4 "cc_arithop" [(match_dup 1) (match_dup 2)]))]
6293 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
6295 [(set_attr "type" "compare")])
6297 (define_insn "*cmp_cc_xor_not"
6300 (not:SI (xor:SI (match_operand:SI 0 "reg_or_0_operand" "%rJ")
6301 (match_operand:SI 1 "arith_operand" "rI")))
6304 "xnorcc\t%r0, %1, %%g0"
6305 [(set_attr "type" "compare")])
6307 (define_insn "*cmp_ccx_xor_not"
6310 (not:DI (xor:DI (match_operand:DI 0 "reg_or_0_operand" "%rJ")
6311 (match_operand:DI 1 "arith_double_operand" "rHI")))
6314 "xnorcc\t%r0, %1, %%g0"
6315 [(set_attr "type" "compare")])
6317 (define_insn "*cmp_cc_xor_not_set"
6320 (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
6321 (match_operand:SI 2 "arith_operand" "rI")))
6323 (set (match_operand:SI 0 "register_operand" "=r")
6324 (not:SI (xor:SI (match_dup 1) (match_dup 2))))]
6326 "xnorcc\t%r1, %2, %0"
6327 [(set_attr "type" "compare")])
6329 (define_insn "*cmp_ccx_xor_not_set"
6332 (not:DI (xor:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ")
6333 (match_operand:DI 2 "arith_double_operand" "rHI")))
6335 (set (match_operand:DI 0 "register_operand" "=r")
6336 (not:DI (xor:DI (match_dup 1) (match_dup 2))))]
6338 "xnorcc\t%r1, %2, %0"
6339 [(set_attr "type" "compare")])
6341 (define_insn "*cmp_cc_arith_op_not"
6344 (match_operator:SI 2 "cc_arithopn"
6345 [(not:SI (match_operand:SI 0 "arith_operand" "rI"))
6346 (match_operand:SI 1 "reg_or_0_operand" "rJ")])
6349 "%B2cc\t%r1, %0, %%g0"
6350 [(set_attr "type" "compare")])
6352 (define_insn "*cmp_ccx_arith_op_not"
6355 (match_operator:DI 2 "cc_arithopn"
6356 [(not:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
6357 (match_operand:DI 1 "reg_or_0_operand" "rJ")])
6360 "%B2cc\t%r1, %0, %%g0"
6361 [(set_attr "type" "compare")])
6363 (define_insn "*cmp_cc_arith_op_not_set"
6366 (match_operator:SI 3 "cc_arithopn"
6367 [(not:SI (match_operand:SI 1 "arith_operand" "rI"))
6368 (match_operand:SI 2 "reg_or_0_operand" "rJ")])
6370 (set (match_operand:SI 0 "register_operand" "=r")
6371 (match_operator:SI 4 "cc_arithopn"
6372 [(not:SI (match_dup 1)) (match_dup 2)]))]
6373 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
6374 "%B3cc\t%r2, %1, %0"
6375 [(set_attr "type" "compare")])
6377 (define_insn "*cmp_ccx_arith_op_not_set"
6380 (match_operator:DI 3 "cc_arithopn"
6381 [(not:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
6382 (match_operand:DI 2 "reg_or_0_operand" "rJ")])
6384 (set (match_operand:DI 0 "register_operand" "=r")
6385 (match_operator:DI 4 "cc_arithopn"
6386 [(not:DI (match_dup 1)) (match_dup 2)]))]
6387 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
6388 "%B3cc\t%r2, %1, %0"
6389 [(set_attr "type" "compare")])
6391 ;; We cannot use the "neg" pseudo insn because the Sun assembler
6392 ;; does not know how to make it work for constants.
6394 (define_expand "negdi2"
6395 [(set (match_operand:DI 0 "register_operand" "=r")
6396 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
6399 if (! TARGET_ARCH64)
6401 emit_insn (gen_rtx_PARALLEL
6404 gen_rtx_SET (VOIDmode, operand0,
6405 gen_rtx_NEG (DImode, operand1)),
6406 gen_rtx_CLOBBER (VOIDmode,
6407 gen_rtx_REG (CCmode,
6413 (define_insn_and_split "*negdi2_sp32"
6414 [(set (match_operand:DI 0 "register_operand" "=r")
6415 (neg:DI (match_operand:DI 1 "register_operand" "r")))
6416 (clobber (reg:CC 100))]
6419 "&& reload_completed"
6420 [(parallel [(set (reg:CC_NOOV 100)
6421 (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 5))
6423 (set (match_dup 4) (minus:SI (const_int 0) (match_dup 5)))])
6424 (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
6425 (ltu:SI (reg:CC 100) (const_int 0))))]
6426 "operands[2] = gen_highpart (SImode, operands[0]);
6427 operands[3] = gen_highpart (SImode, operands[1]);
6428 operands[4] = gen_lowpart (SImode, operands[0]);
6429 operands[5] = gen_lowpart (SImode, operands[1]);"
6430 [(set_attr "length" "2")])
6432 (define_insn "*negdi2_sp64"
6433 [(set (match_operand:DI 0 "register_operand" "=r")
6434 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
6436 "sub\t%%g0, %1, %0")
6438 (define_insn "negsi2"
6439 [(set (match_operand:SI 0 "register_operand" "=r")
6440 (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
6442 "sub\t%%g0, %1, %0")
6444 (define_insn "*cmp_cc_neg"
6445 [(set (reg:CC_NOOV 100)
6446 (compare:CC_NOOV (neg:SI (match_operand:SI 0 "arith_operand" "rI"))
6449 "subcc\t%%g0, %0, %%g0"
6450 [(set_attr "type" "compare")])
6452 (define_insn "*cmp_ccx_neg"
6453 [(set (reg:CCX_NOOV 100)
6454 (compare:CCX_NOOV (neg:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
6457 "subcc\t%%g0, %0, %%g0"
6458 [(set_attr "type" "compare")])
6460 (define_insn "*cmp_cc_set_neg"
6461 [(set (reg:CC_NOOV 100)
6462 (compare:CC_NOOV (neg:SI (match_operand:SI 1 "arith_operand" "rI"))
6464 (set (match_operand:SI 0 "register_operand" "=r")
6465 (neg:SI (match_dup 1)))]
6467 "subcc\t%%g0, %1, %0"
6468 [(set_attr "type" "compare")])
6470 (define_insn "*cmp_ccx_set_neg"
6471 [(set (reg:CCX_NOOV 100)
6472 (compare:CCX_NOOV (neg:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
6474 (set (match_operand:DI 0 "register_operand" "=r")
6475 (neg:DI (match_dup 1)))]
6477 "subcc\t%%g0, %1, %0"
6478 [(set_attr "type" "compare")])
6480 ;; We cannot use the "not" pseudo insn because the Sun assembler
6481 ;; does not know how to make it work for constants.
6482 (define_expand "one_cmpldi2"
6483 [(set (match_operand:DI 0 "register_operand" "")
6484 (not:DI (match_operand:DI 1 "register_operand" "")))]
6488 (define_insn_and_split "*one_cmpldi2_sp32"
6489 [(set (match_operand:DI 0 "register_operand" "=r,b")
6490 (not:DI (match_operand:DI 1 "register_operand" "r,b")))]
6495 "&& reload_completed
6496 && ((GET_CODE (operands[0]) == REG
6497 && REGNO (operands[0]) < 32)
6498 || (GET_CODE (operands[0]) == SUBREG
6499 && GET_CODE (SUBREG_REG (operands[0])) == REG
6500 && REGNO (SUBREG_REG (operands[0])) < 32))"
6501 [(set (match_dup 2) (not:SI (xor:SI (match_dup 3) (const_int 0))))
6502 (set (match_dup 4) (not:SI (xor:SI (match_dup 5) (const_int 0))))]
6503 "operands[2] = gen_highpart (SImode, operands[0]);
6504 operands[3] = gen_highpart (SImode, operands[1]);
6505 operands[4] = gen_lowpart (SImode, operands[0]);
6506 operands[5] = gen_lowpart (SImode, operands[1]);"
6507 [(set_attr "type" "*,fga")
6508 (set_attr "length" "2,*")
6509 (set_attr "fptype" "double")])
6511 (define_insn "*one_cmpldi2_sp64"
6512 [(set (match_operand:DI 0 "register_operand" "=r,b")
6513 (not:DI (match_operand:DI 1 "arith_double_operand" "rHI,b")))]
6518 [(set_attr "type" "*,fga")
6519 (set_attr "fptype" "double")])
6521 (define_insn "one_cmplsi2"
6522 [(set (match_operand:SI 0 "register_operand" "=r,d")
6523 (not:SI (match_operand:SI 1 "arith_operand" "rI,d")))]
6528 [(set_attr "type" "*,fga")])
6530 (define_insn "*cmp_cc_not"
6532 (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI"))
6535 "xnorcc\t%%g0, %0, %%g0"
6536 [(set_attr "type" "compare")])
6538 (define_insn "*cmp_ccx_not"
6540 (compare:CCX (not:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
6543 "xnorcc\t%%g0, %0, %%g0"
6544 [(set_attr "type" "compare")])
6546 (define_insn "*cmp_cc_set_not"
6548 (compare:CC (not:SI (match_operand:SI 1 "arith_operand" "rI"))
6550 (set (match_operand:SI 0 "register_operand" "=r")
6551 (not:SI (match_dup 1)))]
6553 "xnorcc\t%%g0, %1, %0"
6554 [(set_attr "type" "compare")])
6556 (define_insn "*cmp_ccx_set_not"
6558 (compare:CCX (not:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
6560 (set (match_operand:DI 0 "register_operand" "=r")
6561 (not:DI (match_dup 1)))]
6563 "xnorcc\t%%g0, %1, %0"
6564 [(set_attr "type" "compare")])
6566 (define_insn "*cmp_cc_set"
6567 [(set (match_operand:SI 0 "register_operand" "=r")
6568 (match_operand:SI 1 "register_operand" "r"))
6570 (compare:CC (match_dup 1)
6574 [(set_attr "type" "compare")])
6576 (define_insn "*cmp_ccx_set64"
6577 [(set (match_operand:DI 0 "register_operand" "=r")
6578 (match_operand:DI 1 "register_operand" "r"))
6580 (compare:CCX (match_dup 1)
6584 [(set_attr "type" "compare")])
6586 ;; Floating point arithmetic instructions.
6588 (define_expand "addtf3"
6589 [(set (match_operand:TF 0 "nonimmediate_operand" "")
6590 (plus:TF (match_operand:TF 1 "general_operand" "")
6591 (match_operand:TF 2 "general_operand" "")))]
6592 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6593 "emit_tfmode_binop (PLUS, operands); DONE;")
6595 (define_insn "*addtf3_hq"
6596 [(set (match_operand:TF 0 "register_operand" "=e")
6597 (plus:TF (match_operand:TF 1 "register_operand" "e")
6598 (match_operand:TF 2 "register_operand" "e")))]
6599 "TARGET_FPU && TARGET_HARD_QUAD"
6601 [(set_attr "type" "fp")])
6603 (define_insn "adddf3"
6604 [(set (match_operand:DF 0 "register_operand" "=e")
6605 (plus:DF (match_operand:DF 1 "register_operand" "e")
6606 (match_operand:DF 2 "register_operand" "e")))]
6609 [(set_attr "type" "fp")
6610 (set_attr "fptype" "double")])
6612 (define_insn "addsf3"
6613 [(set (match_operand:SF 0 "register_operand" "=f")
6614 (plus:SF (match_operand:SF 1 "register_operand" "f")
6615 (match_operand:SF 2 "register_operand" "f")))]
6618 [(set_attr "type" "fp")])
6620 (define_expand "subtf3"
6621 [(set (match_operand:TF 0 "nonimmediate_operand" "")
6622 (minus:TF (match_operand:TF 1 "general_operand" "")
6623 (match_operand:TF 2 "general_operand" "")))]
6624 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6625 "emit_tfmode_binop (MINUS, operands); DONE;")
6627 (define_insn "*subtf3_hq"
6628 [(set (match_operand:TF 0 "register_operand" "=e")
6629 (minus:TF (match_operand:TF 1 "register_operand" "e")
6630 (match_operand:TF 2 "register_operand" "e")))]
6631 "TARGET_FPU && TARGET_HARD_QUAD"
6633 [(set_attr "type" "fp")])
6635 (define_insn "subdf3"
6636 [(set (match_operand:DF 0 "register_operand" "=e")
6637 (minus:DF (match_operand:DF 1 "register_operand" "e")
6638 (match_operand:DF 2 "register_operand" "e")))]
6641 [(set_attr "type" "fp")
6642 (set_attr "fptype" "double")])
6644 (define_insn "subsf3"
6645 [(set (match_operand:SF 0 "register_operand" "=f")
6646 (minus:SF (match_operand:SF 1 "register_operand" "f")
6647 (match_operand:SF 2 "register_operand" "f")))]
6650 [(set_attr "type" "fp")])
6652 (define_expand "multf3"
6653 [(set (match_operand:TF 0 "nonimmediate_operand" "")
6654 (mult:TF (match_operand:TF 1 "general_operand" "")
6655 (match_operand:TF 2 "general_operand" "")))]
6656 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6657 "emit_tfmode_binop (MULT, operands); DONE;")
6659 (define_insn "*multf3_hq"
6660 [(set (match_operand:TF 0 "register_operand" "=e")
6661 (mult:TF (match_operand:TF 1 "register_operand" "e")
6662 (match_operand:TF 2 "register_operand" "e")))]
6663 "TARGET_FPU && TARGET_HARD_QUAD"
6665 [(set_attr "type" "fpmul")])
6667 (define_insn "muldf3"
6668 [(set (match_operand:DF 0 "register_operand" "=e")
6669 (mult:DF (match_operand:DF 1 "register_operand" "e")
6670 (match_operand:DF 2 "register_operand" "e")))]
6673 [(set_attr "type" "fpmul")
6674 (set_attr "fptype" "double")])
6676 (define_insn "mulsf3"
6677 [(set (match_operand:SF 0 "register_operand" "=f")
6678 (mult:SF (match_operand:SF 1 "register_operand" "f")
6679 (match_operand:SF 2 "register_operand" "f")))]
6682 [(set_attr "type" "fpmul")])
6684 (define_insn "*muldf3_extend"
6685 [(set (match_operand:DF 0 "register_operand" "=e")
6686 (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "f"))
6687 (float_extend:DF (match_operand:SF 2 "register_operand" "f"))))]
6688 "(TARGET_V8 || TARGET_V9) && TARGET_FPU"
6689 "fsmuld\t%1, %2, %0"
6690 [(set_attr "type" "fpmul")
6691 (set_attr "fptype" "double")])
6693 (define_insn "*multf3_extend"
6694 [(set (match_operand:TF 0 "register_operand" "=e")
6695 (mult:TF (float_extend:TF (match_operand:DF 1 "register_operand" "e"))
6696 (float_extend:TF (match_operand:DF 2 "register_operand" "e"))))]
6697 "(TARGET_V8 || TARGET_V9) && TARGET_FPU && TARGET_HARD_QUAD"
6698 "fdmulq\t%1, %2, %0"
6699 [(set_attr "type" "fpmul")])
6701 (define_expand "divtf3"
6702 [(set (match_operand:TF 0 "nonimmediate_operand" "")
6703 (div:TF (match_operand:TF 1 "general_operand" "")
6704 (match_operand:TF 2 "general_operand" "")))]
6705 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6706 "emit_tfmode_binop (DIV, operands); DONE;")
6708 ;; don't have timing for quad-prec. divide.
6709 (define_insn "*divtf3_hq"
6710 [(set (match_operand:TF 0 "register_operand" "=e")
6711 (div:TF (match_operand:TF 1 "register_operand" "e")
6712 (match_operand:TF 2 "register_operand" "e")))]
6713 "TARGET_FPU && TARGET_HARD_QUAD"
6715 [(set_attr "type" "fpdivd")])
6717 (define_insn "divdf3"
6718 [(set (match_operand:DF 0 "register_operand" "=e")
6719 (div:DF (match_operand:DF 1 "register_operand" "e")
6720 (match_operand:DF 2 "register_operand" "e")))]
6723 [(set_attr "type" "fpdivd")
6724 (set_attr "fptype" "double")])
6726 (define_insn "divsf3"
6727 [(set (match_operand:SF 0 "register_operand" "=f")
6728 (div:SF (match_operand:SF 1 "register_operand" "f")
6729 (match_operand:SF 2 "register_operand" "f")))]
6732 [(set_attr "type" "fpdivs")])
6734 (define_expand "negtf2"
6735 [(set (match_operand:TF 0 "register_operand" "=e,e")
6736 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
6740 (define_insn_and_split "*negtf2_notv9"
6741 [(set (match_operand:TF 0 "register_operand" "=e,e")
6742 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
6743 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
6749 "&& reload_completed
6750 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6751 [(set (match_dup 2) (neg:SF (match_dup 3)))
6752 (set (match_dup 4) (match_dup 5))
6753 (set (match_dup 6) (match_dup 7))]
6754 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6755 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6756 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6757 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
6758 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6759 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6760 [(set_attr "type" "fpmove,*")
6761 (set_attr "length" "*,2")])
6763 (define_insn_and_split "*negtf2_v9"
6764 [(set (match_operand:TF 0 "register_operand" "=e,e")
6765 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
6766 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
6767 "TARGET_FPU && TARGET_V9"
6771 "&& reload_completed
6772 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6773 [(set (match_dup 2) (neg:DF (match_dup 3)))
6774 (set (match_dup 4) (match_dup 5))]
6775 "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
6776 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
6777 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6778 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6779 [(set_attr "type" "fpmove,*")
6780 (set_attr "length" "*,2")
6781 (set_attr "fptype" "double")])
6783 (define_expand "negdf2"
6784 [(set (match_operand:DF 0 "register_operand" "")
6785 (neg:DF (match_operand:DF 1 "register_operand" "")))]
6789 (define_insn_and_split "*negdf2_notv9"
6790 [(set (match_operand:DF 0 "register_operand" "=e,e")
6791 (neg:DF (match_operand:DF 1 "register_operand" "0,e")))]
6792 "TARGET_FPU && ! TARGET_V9"
6796 "&& reload_completed
6797 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6798 [(set (match_dup 2) (neg:SF (match_dup 3)))
6799 (set (match_dup 4) (match_dup 5))]
6800 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6801 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6802 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6803 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);"
6804 [(set_attr "type" "fpmove,*")
6805 (set_attr "length" "*,2")])
6807 (define_insn "*negdf2_v9"
6808 [(set (match_operand:DF 0 "register_operand" "=e")
6809 (neg:DF (match_operand:DF 1 "register_operand" "e")))]
6810 "TARGET_FPU && TARGET_V9"
6812 [(set_attr "type" "fpmove")
6813 (set_attr "fptype" "double")])
6815 (define_insn "negsf2"
6816 [(set (match_operand:SF 0 "register_operand" "=f")
6817 (neg:SF (match_operand:SF 1 "register_operand" "f")))]
6820 [(set_attr "type" "fpmove")])
6822 (define_expand "abstf2"
6823 [(set (match_operand:TF 0 "register_operand" "")
6824 (abs:TF (match_operand:TF 1 "register_operand" "")))]
6828 (define_insn_and_split "*abstf2_notv9"
6829 [(set (match_operand:TF 0 "register_operand" "=e,e")
6830 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6831 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
6832 "TARGET_FPU && ! TARGET_V9"
6836 "&& reload_completed
6837 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6838 [(set (match_dup 2) (abs:SF (match_dup 3)))
6839 (set (match_dup 4) (match_dup 5))
6840 (set (match_dup 6) (match_dup 7))]
6841 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6842 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6843 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6844 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
6845 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6846 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6847 [(set_attr "type" "fpmove,*")
6848 (set_attr "length" "*,2")])
6850 (define_insn "*abstf2_hq_v9"
6851 [(set (match_operand:TF 0 "register_operand" "=e,e")
6852 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6853 "TARGET_FPU && TARGET_V9 && TARGET_HARD_QUAD"
6857 [(set_attr "type" "fpmove")
6858 (set_attr "fptype" "double,*")])
6860 (define_insn_and_split "*abstf2_v9"
6861 [(set (match_operand:TF 0 "register_operand" "=e,e")
6862 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6863 "TARGET_FPU && TARGET_V9 && !TARGET_HARD_QUAD"
6867 "&& reload_completed
6868 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6869 [(set (match_dup 2) (abs:DF (match_dup 3)))
6870 (set (match_dup 4) (match_dup 5))]
6871 "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
6872 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
6873 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6874 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6875 [(set_attr "type" "fpmove,*")
6876 (set_attr "length" "*,2")
6877 (set_attr "fptype" "double,*")])
6879 (define_expand "absdf2"
6880 [(set (match_operand:DF 0 "register_operand" "")
6881 (abs:DF (match_operand:DF 1 "register_operand" "")))]
6885 (define_insn_and_split "*absdf2_notv9"
6886 [(set (match_operand:DF 0 "register_operand" "=e,e")
6887 (abs:DF (match_operand:DF 1 "register_operand" "0,e")))]
6888 "TARGET_FPU && ! TARGET_V9"
6892 "&& reload_completed
6893 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6894 [(set (match_dup 2) (abs:SF (match_dup 3)))
6895 (set (match_dup 4) (match_dup 5))]
6896 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6897 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6898 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6899 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);"
6900 [(set_attr "type" "fpmove,*")
6901 (set_attr "length" "*,2")])
6903 (define_insn "*absdf2_v9"
6904 [(set (match_operand:DF 0 "register_operand" "=e")
6905 (abs:DF (match_operand:DF 1 "register_operand" "e")))]
6906 "TARGET_FPU && TARGET_V9"
6908 [(set_attr "type" "fpmove")
6909 (set_attr "fptype" "double")])
6911 (define_insn "abssf2"
6912 [(set (match_operand:SF 0 "register_operand" "=f")
6913 (abs:SF (match_operand:SF 1 "register_operand" "f")))]
6916 [(set_attr "type" "fpmove")])
6918 (define_expand "sqrttf2"
6919 [(set (match_operand:TF 0 "nonimmediate_operand" "")
6920 (sqrt:TF (match_operand:TF 1 "general_operand" "")))]
6921 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6922 "emit_tfmode_unop (SQRT, operands); DONE;")
6924 (define_insn "*sqrttf2_hq"
6925 [(set (match_operand:TF 0 "register_operand" "=e")
6926 (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
6927 "TARGET_FPU && TARGET_HARD_QUAD"
6929 [(set_attr "type" "fpsqrtd")])
6931 (define_insn "sqrtdf2"
6932 [(set (match_operand:DF 0 "register_operand" "=e")
6933 (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
6936 [(set_attr "type" "fpsqrtd")
6937 (set_attr "fptype" "double")])
6939 (define_insn "sqrtsf2"
6940 [(set (match_operand:SF 0 "register_operand" "=f")
6941 (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
6944 [(set_attr "type" "fpsqrts")])
6946 ;;- arithmetic shift instructions
6948 (define_insn "ashlsi3"
6949 [(set (match_operand:SI 0 "register_operand" "=r")
6950 (ashift:SI (match_operand:SI 1 "register_operand" "r")
6951 (match_operand:SI 2 "arith_operand" "rI")))]
6954 if (operands[2] == const1_rtx)
6955 return "add\t%1, %1, %0";
6956 if (GET_CODE (operands[2]) == CONST_INT)
6957 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6958 return "sll\t%1, %2, %0";
6961 (if_then_else (match_operand 2 "const1_operand" "")
6962 (const_string "ialu") (const_string "shift")))])
6964 (define_expand "ashldi3"
6965 [(set (match_operand:DI 0 "register_operand" "=r")
6966 (ashift:DI (match_operand:DI 1 "register_operand" "r")
6967 (match_operand:SI 2 "arith_operand" "rI")))]
6968 "TARGET_ARCH64 || TARGET_V8PLUS"
6970 if (! TARGET_ARCH64)
6972 if (GET_CODE (operands[2]) == CONST_INT)
6974 emit_insn (gen_ashldi3_v8plus (operands[0], operands[1], operands[2]));
6979 (define_insn "*ashldi3_sp64"
6980 [(set (match_operand:DI 0 "register_operand" "=r")
6981 (ashift:DI (match_operand:DI 1 "register_operand" "r")
6982 (match_operand:SI 2 "arith_operand" "rI")))]
6985 if (operands[2] == const1_rtx)
6986 return "add\t%1, %1, %0";
6987 if (GET_CODE (operands[2]) == CONST_INT)
6988 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
6989 return "sllx\t%1, %2, %0";
6992 (if_then_else (match_operand 2 "const1_operand" "")
6993 (const_string "ialu") (const_string "shift")))])
6996 (define_insn "ashldi3_v8plus"
6997 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
6998 (ashift:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
6999 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
7000 (clobber (match_scratch:SI 3 "=X,X,&h"))]
7002 "* return output_v8plus_shift (operands, insn, \"sllx\");"
7003 [(set_attr "type" "multi")
7004 (set_attr "length" "5,5,6")])
7006 ;; Optimize (1LL<<x)-1
7007 ;; XXX this also needs to be fixed to handle equal subregs
7008 ;; XXX first before we could re-enable it.
7010 ; [(set (match_operand:DI 0 "register_operand" "=h")
7011 ; (plus:DI (ashift:DI (const_int 1)
7012 ; (match_operand:SI 1 "arith_operand" "rI"))
7014 ; "0 && TARGET_V8PLUS"
7016 ; if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == REGNO (operands[0]))
7017 ; return "mov\t1, %L0\;sllx\t%L0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
7018 ; return "mov\t1, %H0\;sllx\t%H0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
7020 ; [(set_attr "type" "multi")
7021 ; (set_attr "length" "4")])
7023 (define_insn "*cmp_cc_ashift_1"
7024 [(set (reg:CC_NOOV 100)
7025 (compare:CC_NOOV (ashift:SI (match_operand:SI 0 "register_operand" "r")
7029 "addcc\t%0, %0, %%g0"
7030 [(set_attr "type" "compare")])
7032 (define_insn "*cmp_cc_set_ashift_1"
7033 [(set (reg:CC_NOOV 100)
7034 (compare:CC_NOOV (ashift:SI (match_operand:SI 1 "register_operand" "r")
7037 (set (match_operand:SI 0 "register_operand" "=r")
7038 (ashift:SI (match_dup 1) (const_int 1)))]
7041 [(set_attr "type" "compare")])
7043 (define_insn "ashrsi3"
7044 [(set (match_operand:SI 0 "register_operand" "=r")
7045 (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
7046 (match_operand:SI 2 "arith_operand" "rI")))]
7049 if (GET_CODE (operands[2]) == CONST_INT)
7050 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
7051 return "sra\t%1, %2, %0";
7053 [(set_attr "type" "shift")])
7055 (define_insn "*ashrsi3_extend"
7056 [(set (match_operand:DI 0 "register_operand" "=r")
7057 (sign_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
7058 (match_operand:SI 2 "arith_operand" "r"))))]
7061 [(set_attr "type" "shift")])
7063 ;; This handles the case as above, but with constant shift instead of
7064 ;; register. Combiner "simplifies" it for us a little bit though.
7065 (define_insn "*ashrsi3_extend2"
7066 [(set (match_operand:DI 0 "register_operand" "=r")
7067 (ashiftrt:DI (ashift:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
7069 (match_operand:SI 2 "small_int_or_double" "n")))]
7071 && ((GET_CODE (operands[2]) == CONST_INT
7072 && INTVAL (operands[2]) >= 32 && INTVAL (operands[2]) < 64)
7073 || (GET_CODE (operands[2]) == CONST_DOUBLE
7074 && !CONST_DOUBLE_HIGH (operands[2])
7075 && CONST_DOUBLE_LOW (operands[2]) >= 32
7076 && CONST_DOUBLE_LOW (operands[2]) < 64))"
7078 operands[2] = GEN_INT (INTVAL (operands[2]) - 32);
7080 return "sra\t%1, %2, %0";
7082 [(set_attr "type" "shift")])
7084 (define_expand "ashrdi3"
7085 [(set (match_operand:DI 0 "register_operand" "=r")
7086 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
7087 (match_operand:SI 2 "arith_operand" "rI")))]
7088 "TARGET_ARCH64 || TARGET_V8PLUS"
7090 if (! TARGET_ARCH64)
7092 if (GET_CODE (operands[2]) == CONST_INT)
7093 FAIL; /* prefer generic code in this case */
7094 emit_insn (gen_ashrdi3_v8plus (operands[0], operands[1], operands[2]));
7099 (define_insn "*ashrdi3_sp64"
7100 [(set (match_operand:DI 0 "register_operand" "=r")
7101 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
7102 (match_operand:SI 2 "arith_operand" "rI")))]
7106 if (GET_CODE (operands[2]) == CONST_INT)
7107 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
7108 return "srax\t%1, %2, %0";
7110 [(set_attr "type" "shift")])
7113 (define_insn "ashrdi3_v8plus"
7114 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
7115 (ashiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
7116 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
7117 (clobber (match_scratch:SI 3 "=X,X,&h"))]
7119 "* return output_v8plus_shift (operands, insn, \"srax\");"
7120 [(set_attr "type" "multi")
7121 (set_attr "length" "5,5,6")])
7123 (define_insn "lshrsi3"
7124 [(set (match_operand:SI 0 "register_operand" "=r")
7125 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
7126 (match_operand:SI 2 "arith_operand" "rI")))]
7129 if (GET_CODE (operands[2]) == CONST_INT)
7130 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
7131 return "srl\t%1, %2, %0";
7133 [(set_attr "type" "shift")])
7135 ;; This handles the case where
7136 ;; (zero_extend:DI (lshiftrt:SI (match_operand:SI) (match_operand:SI))),
7137 ;; but combiner "simplifies" it for us.
7138 (define_insn "*lshrsi3_extend"
7139 [(set (match_operand:DI 0 "register_operand" "=r")
7140 (and:DI (subreg:DI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
7141 (match_operand:SI 2 "arith_operand" "r")) 0)
7142 (match_operand 3 "" "")))]
7144 && ((GET_CODE (operands[3]) == CONST_DOUBLE
7145 && CONST_DOUBLE_HIGH (operands[3]) == 0
7146 && CONST_DOUBLE_LOW (operands[3]) == 0xffffffff)
7147 || (HOST_BITS_PER_WIDE_INT >= 64
7148 && GET_CODE (operands[3]) == CONST_INT
7149 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) == 0xffffffff))"
7151 [(set_attr "type" "shift")])
7153 ;; This handles the case where
7154 ;; (lshiftrt:DI (zero_extend:DI (match_operand:SI)) (const_int >=0 < 32))
7155 ;; but combiner "simplifies" it for us.
7156 (define_insn "*lshrsi3_extend2"
7157 [(set (match_operand:DI 0 "register_operand" "=r")
7158 (zero_extract:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
7159 (match_operand 2 "small_int_or_double" "n")
7162 && ((GET_CODE (operands[2]) == CONST_INT
7163 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
7164 || (GET_CODE (operands[2]) == CONST_DOUBLE
7165 && CONST_DOUBLE_HIGH (operands[2]) == 0
7166 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
7168 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
7170 return "srl\t%1, %2, %0";
7172 [(set_attr "type" "shift")])
7174 (define_expand "lshrdi3"
7175 [(set (match_operand:DI 0 "register_operand" "=r")
7176 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
7177 (match_operand:SI 2 "arith_operand" "rI")))]
7178 "TARGET_ARCH64 || TARGET_V8PLUS"
7180 if (! TARGET_ARCH64)
7182 if (GET_CODE (operands[2]) == CONST_INT)
7184 emit_insn (gen_lshrdi3_v8plus (operands[0], operands[1], operands[2]));
7189 (define_insn "*lshrdi3_sp64"
7190 [(set (match_operand:DI 0 "register_operand" "=r")
7191 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
7192 (match_operand:SI 2 "arith_operand" "rI")))]
7195 if (GET_CODE (operands[2]) == CONST_INT)
7196 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
7197 return "srlx\t%1, %2, %0";
7199 [(set_attr "type" "shift")])
7202 (define_insn "lshrdi3_v8plus"
7203 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
7204 (lshiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
7205 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
7206 (clobber (match_scratch:SI 3 "=X,X,&h"))]
7208 "* return output_v8plus_shift (operands, insn, \"srlx\");"
7209 [(set_attr "type" "multi")
7210 (set_attr "length" "5,5,6")])
7213 [(set (match_operand:SI 0 "register_operand" "=r")
7214 (ashiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
7216 (match_operand:SI 2 "small_int_or_double" "n")))]
7218 && ((GET_CODE (operands[2]) == CONST_INT
7219 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
7220 || (GET_CODE (operands[2]) == CONST_DOUBLE
7221 && !CONST_DOUBLE_HIGH (operands[2])
7222 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
7224 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
7226 return "srax\t%1, %2, %0";
7228 [(set_attr "type" "shift")])
7231 [(set (match_operand:SI 0 "register_operand" "=r")
7232 (lshiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
7234 (match_operand:SI 2 "small_int_or_double" "n")))]
7236 && ((GET_CODE (operands[2]) == CONST_INT
7237 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
7238 || (GET_CODE (operands[2]) == CONST_DOUBLE
7239 && !CONST_DOUBLE_HIGH (operands[2])
7240 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
7242 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
7244 return "srlx\t%1, %2, %0";
7246 [(set_attr "type" "shift")])
7249 [(set (match_operand:SI 0 "register_operand" "=r")
7250 (ashiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
7251 (match_operand:SI 2 "small_int_or_double" "n")) 4)
7252 (match_operand:SI 3 "small_int_or_double" "n")))]
7254 && GET_CODE (operands[2]) == CONST_INT && GET_CODE (operands[3]) == CONST_INT
7255 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
7256 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
7257 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
7259 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
7261 return "srax\t%1, %2, %0";
7263 [(set_attr "type" "shift")])
7266 [(set (match_operand:SI 0 "register_operand" "=r")
7267 (lshiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
7268 (match_operand:SI 2 "small_int_or_double" "n")) 4)
7269 (match_operand:SI 3 "small_int_or_double" "n")))]
7271 && GET_CODE (operands[2]) == CONST_INT && GET_CODE (operands[3]) == CONST_INT
7272 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
7273 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
7274 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
7276 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
7278 return "srlx\t%1, %2, %0";
7280 [(set_attr "type" "shift")])
7282 ;; Unconditional and other jump instructions
7283 ;; On the SPARC, by setting the annul bit on an unconditional branch, the
7284 ;; following insn is never executed. This saves us a nop. Dbx does not
7285 ;; handle such branches though, so we only use them when optimizing.
7287 [(set (pc) (label_ref (match_operand 0 "" "")))]
7290 /* TurboSPARC is reported to have problems with
7293 i.e. an empty loop with the annul bit set. The workaround is to use
7297 if (! TARGET_V9 && flag_delayed_branch
7298 && (INSN_ADDRESSES (INSN_UID (operands[0]))
7299 == INSN_ADDRESSES (INSN_UID (insn))))
7302 return TARGET_V9 ? "ba%*,pt\t%%xcc, %l0%(" : "b%*\t%l0%(";
7304 [(set_attr "type" "uncond_branch")])
7306 (define_expand "tablejump"
7307 [(parallel [(set (pc) (match_operand 0 "register_operand" "r"))
7308 (use (label_ref (match_operand 1 "" "")))])]
7311 if (GET_MODE (operands[0]) != CASE_VECTOR_MODE)
7314 /* In pic mode, our address differences are against the base of the
7315 table. Add that base value back in; CSE ought to be able to combine
7316 the two address loads. */
7320 tmp = gen_rtx_LABEL_REF (Pmode, operands[1]);
7322 if (CASE_VECTOR_MODE != Pmode)
7323 tmp2 = gen_rtx_SIGN_EXTEND (Pmode, tmp2);
7324 tmp = gen_rtx_PLUS (Pmode, tmp2, tmp);
7325 operands[0] = memory_address (Pmode, tmp);
7329 (define_insn "*tablejump_sp32"
7330 [(set (pc) (match_operand:SI 0 "address_operand" "p"))
7331 (use (label_ref (match_operand 1 "" "")))]
7334 [(set_attr "type" "uncond_branch")])
7336 (define_insn "*tablejump_sp64"
7337 [(set (pc) (match_operand:DI 0 "address_operand" "p"))
7338 (use (label_ref (match_operand 1 "" "")))]
7341 [(set_attr "type" "uncond_branch")])
7343 ;;- jump to subroutine
7344 (define_expand "call"
7345 ;; Note that this expression is not used for generating RTL.
7346 ;; All the RTL is generated explicitly below.
7347 [(call (match_operand 0 "call_operand" "")
7348 (match_operand 3 "" "i"))]
7349 ;; operands[2] is next_arg_register
7350 ;; operands[3] is struct_value_size_rtx.
7355 if (GET_MODE (operands[0]) != FUNCTION_MODE)
7358 if (GET_CODE (operands[3]) != CONST_INT)
7361 if (GET_CODE (XEXP (operands[0], 0)) == LABEL_REF)
7363 /* This is really a PIC sequence. We want to represent
7364 it as a funny jump so its delay slots can be filled.
7366 ??? But if this really *is* a CALL, will not it clobber the
7367 call-clobbered registers? We lose this if it is a JUMP_INSN.
7368 Why cannot we have delay slots filled if it were a CALL? */
7370 /* We accept negative sizes for untyped calls. */
7371 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
7376 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
7378 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
7384 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
7385 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
7389 fn_rtx = operands[0];
7391 /* We accept negative sizes for untyped calls. */
7392 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
7396 gen_rtvec (3, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx),
7398 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
7403 gen_rtvec (2, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx),
7404 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
7411 ;; We can't use the same pattern for these two insns, because then registers
7412 ;; in the address may not be properly reloaded.
7414 (define_insn "*call_address_sp32"
7415 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
7416 (match_operand 1 "" ""))
7417 (clobber (reg:SI 15))]
7418 ;;- Do not use operand 1 for most machines.
7421 [(set_attr "type" "call")])
7423 (define_insn "*call_symbolic_sp32"
7424 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
7425 (match_operand 1 "" ""))
7426 (clobber (reg:SI 15))]
7427 ;;- Do not use operand 1 for most machines.
7430 [(set_attr "type" "call")])
7432 (define_insn "*call_address_sp64"
7433 [(call (mem:DI (match_operand:DI 0 "address_operand" "p"))
7434 (match_operand 1 "" ""))
7435 (clobber (reg:DI 15))]
7436 ;;- Do not use operand 1 for most machines.
7439 [(set_attr "type" "call")])
7441 (define_insn "*call_symbolic_sp64"
7442 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
7443 (match_operand 1 "" ""))
7444 (clobber (reg:DI 15))]
7445 ;;- Do not use operand 1 for most machines.
7448 [(set_attr "type" "call")])
7450 ;; This is a call that wants a structure value.
7451 ;; There is no such critter for v9 (??? we may need one anyway).
7452 (define_insn "*call_address_struct_value_sp32"
7453 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
7454 (match_operand 1 "" ""))
7455 (match_operand 2 "immediate_operand" "")
7456 (clobber (reg:SI 15))]
7457 ;;- Do not use operand 1 for most machines.
7458 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
7459 "call\t%a0, %1\n\t nop\n\tunimp\t%2"
7460 [(set_attr "type" "call_no_delay_slot")
7461 (set_attr "length" "3")])
7463 ;; This is a call that wants a structure value.
7464 ;; There is no such critter for v9 (??? we may need one anyway).
7465 (define_insn "*call_symbolic_struct_value_sp32"
7466 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
7467 (match_operand 1 "" ""))
7468 (match_operand 2 "immediate_operand" "")
7469 (clobber (reg:SI 15))]
7470 ;;- Do not use operand 1 for most machines.
7471 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
7472 "call\t%a0, %1\n\t nop\n\tunimp\t%2"
7473 [(set_attr "type" "call_no_delay_slot")
7474 (set_attr "length" "3")])
7476 ;; This is a call that may want a structure value. This is used for
7478 (define_insn "*call_address_untyped_struct_value_sp32"
7479 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
7480 (match_operand 1 "" ""))
7481 (match_operand 2 "immediate_operand" "")
7482 (clobber (reg:SI 15))]
7483 ;;- Do not use operand 1 for most machines.
7484 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
7485 "call\t%a0, %1\n\t nop\n\tnop"
7486 [(set_attr "type" "call_no_delay_slot")
7487 (set_attr "length" "3")])
7489 ;; This is a call that may want a structure value. This is used for
7491 (define_insn "*call_symbolic_untyped_struct_value_sp32"
7492 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
7493 (match_operand 1 "" ""))
7494 (match_operand 2 "immediate_operand" "")
7495 (clobber (reg:SI 15))]
7496 ;;- Do not use operand 1 for most machines.
7497 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
7498 "call\t%a0, %1\n\t nop\n\tnop"
7499 [(set_attr "type" "call_no_delay_slot")
7500 (set_attr "length" "3")])
7502 (define_expand "call_value"
7503 ;; Note that this expression is not used for generating RTL.
7504 ;; All the RTL is generated explicitly below.
7505 [(set (match_operand 0 "register_operand" "=rf")
7506 (call (match_operand 1 "" "")
7507 (match_operand 4 "" "")))]
7508 ;; operand 2 is stack_size_rtx
7509 ;; operand 3 is next_arg_register
7515 if (GET_MODE (operands[1]) != FUNCTION_MODE)
7518 fn_rtx = operands[1];
7521 gen_rtx_SET (VOIDmode, operands[0],
7522 gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx)),
7523 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)));
7525 emit_call_insn (gen_rtx_PARALLEL (VOIDmode, vec));
7530 (define_insn "*call_value_address_sp32"
7531 [(set (match_operand 0 "" "=rf")
7532 (call (mem:SI (match_operand:SI 1 "address_operand" "p"))
7533 (match_operand 2 "" "")))
7534 (clobber (reg:SI 15))]
7535 ;;- Do not use operand 2 for most machines.
7538 [(set_attr "type" "call")])
7540 (define_insn "*call_value_symbolic_sp32"
7541 [(set (match_operand 0 "" "=rf")
7542 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
7543 (match_operand 2 "" "")))
7544 (clobber (reg:SI 15))]
7545 ;;- Do not use operand 2 for most machines.
7548 [(set_attr "type" "call")])
7550 (define_insn "*call_value_address_sp64"
7551 [(set (match_operand 0 "" "")
7552 (call (mem:DI (match_operand:DI 1 "address_operand" "p"))
7553 (match_operand 2 "" "")))
7554 (clobber (reg:DI 15))]
7555 ;;- Do not use operand 2 for most machines.
7558 [(set_attr "type" "call")])
7560 (define_insn "*call_value_symbolic_sp64"
7561 [(set (match_operand 0 "" "")
7562 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
7563 (match_operand 2 "" "")))
7564 (clobber (reg:DI 15))]
7565 ;;- Do not use operand 2 for most machines.
7568 [(set_attr "type" "call")])
7570 (define_expand "untyped_call"
7571 [(parallel [(call (match_operand 0 "" "")
7573 (match_operand 1 "" "")
7574 (match_operand 2 "" "")])]
7579 /* Pass constm1 to indicate that it may expect a structure value, but
7580 we don't know what size it is. */
7581 emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, constm1_rtx));
7583 for (i = 0; i < XVECLEN (operands[2], 0); i++)
7585 rtx set = XVECEXP (operands[2], 0, i);
7586 emit_move_insn (SET_DEST (set), SET_SRC (set));
7589 /* The optimizer does not know that the call sets the function value
7590 registers we stored in the result block. We avoid problems by
7591 claiming that all hard registers are used and clobbered at this
7593 emit_insn (gen_blockage ());
7599 (define_expand "sibcall"
7600 [(parallel [(call (match_operand 0 "call_operand" "") (const_int 0))
7605 (define_insn "*sibcall_symbolic_sp32"
7606 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
7607 (match_operand 1 "" ""))
7610 "* return output_sibcall(insn, operands[0]);"
7611 [(set_attr "type" "sibcall")])
7613 (define_insn "*sibcall_symbolic_sp64"
7614 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
7615 (match_operand 1 "" ""))
7618 "* return output_sibcall(insn, operands[0]);"
7619 [(set_attr "type" "sibcall")])
7621 (define_expand "sibcall_value"
7622 [(parallel [(set (match_operand 0 "register_operand" "=rf")
7623 (call (match_operand 1 "" "") (const_int 0)))
7628 (define_insn "*sibcall_value_symbolic_sp32"
7629 [(set (match_operand 0 "" "=rf")
7630 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
7631 (match_operand 2 "" "")))
7634 "* return output_sibcall(insn, operands[1]);"
7635 [(set_attr "type" "sibcall")])
7637 (define_insn "*sibcall_value_symbolic_sp64"
7638 [(set (match_operand 0 "" "")
7639 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
7640 (match_operand 2 "" "")))
7643 "* return output_sibcall(insn, operands[1]);"
7644 [(set_attr "type" "sibcall")])
7646 (define_expand "sibcall_epilogue"
7650 sparc_expand_epilogue ();
7654 (define_expand "prologue"
7658 sparc_expand_prologue ();
7662 (define_expand "save_register_window"
7663 [(use (match_operand 0 "arith_operand" ""))]
7669 gen_rtx_SET (VOIDmode,
7671 gen_rtx_PLUS (Pmode,
7672 hard_frame_pointer_rtx,
7674 gen_rtx_UNSPEC_VOLATILE (VOIDmode,
7675 gen_rtvec (1, const0_rtx),
7678 emit_insn (gen_rtx_PARALLEL (VOIDmode, vec));
7682 (define_insn "*save_register_windowsi"
7683 [(set (reg:SI 14) (plus:SI (reg:SI 30)
7684 (match_operand:SI 0 "arith_operand" "rI")))
7685 (unspec_volatile [(const_int 0)] UNSPECV_SAVEW)]
7687 "save\t%%sp, %0, %%sp"
7688 [(set_attr "type" "savew")])
7690 (define_insn "*save_register_windowdi"
7691 [(set (reg:DI 14) (plus:DI (reg:DI 30)
7692 (match_operand:DI 0 "arith_operand" "rI")))
7693 (unspec_volatile [(const_int 0)] UNSPECV_SAVEW)]
7695 "save\t%%sp, %0, %%sp"
7696 [(set_attr "type" "savew")])
7698 (define_expand "epilogue"
7702 sparc_expand_epilogue ();
7705 (define_insn "*return_internal"
7708 "* return output_return (insn);"
7709 [(set_attr "type" "return")
7710 (set (attr "length")
7711 (cond [(eq_attr "leaf_function" "true")
7712 (if_then_else (eq_attr "empty_delay_slot" "true")
7715 (eq_attr "calls_eh_return" "true")
7716 (if_then_else (eq_attr "delayed_branch" "true")
7717 (if_then_else (eq_attr "isa" "v9")
7720 (if_then_else (eq_attr "isa" "v9")
7723 (eq_attr "empty_delay_slot" "true")
7724 (if_then_else (eq_attr "delayed_branch" "true")
7729 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
7730 ;; all of memory. This blocks insns from being moved across this point.
7732 (define_insn "blockage"
7733 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
7736 [(set_attr "length" "0")])
7738 ;; Prepare to return any type including a structure value.
7740 (define_expand "untyped_return"
7741 [(match_operand:BLK 0 "memory_operand" "")
7742 (match_operand 1 "" "")]
7745 rtx valreg1 = gen_rtx_REG (DImode, 24);
7746 rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
7747 rtx result = operands[0];
7749 if (! TARGET_ARCH64)
7751 rtx rtnreg = gen_rtx_REG (SImode, (current_function_uses_only_leaf_regs
7753 rtx value = gen_reg_rtx (SImode);
7755 /* Fetch the instruction where we will return to and see if it's an unimp
7756 instruction (the most significant 10 bits will be zero). If so,
7757 update the return address to skip the unimp instruction. */
7758 emit_move_insn (value,
7759 gen_rtx_MEM (SImode, plus_constant (rtnreg, 8)));
7760 emit_insn (gen_lshrsi3 (value, value, GEN_INT (22)));
7761 emit_insn (gen_update_return (rtnreg, value));
7764 /* Reload the function value registers. */
7765 emit_move_insn (valreg1, adjust_address (result, DImode, 0));
7766 emit_move_insn (valreg2,
7767 adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8));
7769 /* Put USE insns before the return. */
7770 emit_insn (gen_rtx_USE (VOIDmode, valreg1));
7771 emit_insn (gen_rtx_USE (VOIDmode, valreg2));
7773 /* Construct the return. */
7774 expand_naked_return ();
7779 ;; This is a bit of a hack. We're incrementing a fixed register (%i7),
7780 ;; and parts of the compiler don't want to believe that the add is needed.
7782 (define_insn "update_return"
7783 [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
7784 (match_operand:SI 1 "register_operand" "r")] UNSPEC_UPDATE_RETURN)]
7787 if (flag_delayed_branch)
7788 return "cmp\t%1, 0\n\tbe,a\t.+8\n\t add\t%0, 4, %0";
7790 return "cmp\t%1, 0\n\tbne\t.+12\n\t nop\n\tadd\t%0, 4, %0";
7792 [(set (attr "type") (const_string "multi"))
7793 (set (attr "length")
7794 (if_then_else (eq_attr "delayed_branch" "true")
7803 (define_expand "indirect_jump"
7804 [(set (pc) (match_operand 0 "address_operand" "p"))]
7808 (define_insn "*branch_sp32"
7809 [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
7812 [(set_attr "type" "uncond_branch")])
7814 (define_insn "*branch_sp64"
7815 [(set (pc) (match_operand:DI 0 "address_operand" "p"))]
7818 [(set_attr "type" "uncond_branch")])
7820 (define_expand "nonlocal_goto"
7821 [(match_operand:SI 0 "general_operand" "")
7822 (match_operand:SI 1 "general_operand" "")
7823 (match_operand:SI 2 "general_operand" "")
7824 (match_operand:SI 3 "" "")]
7827 rtx lab = operands[1];
7828 rtx stack = operands[2];
7829 rtx fp = operands[3];
7832 /* Trap instruction to flush all the register windows. */
7833 emit_insn (gen_flush_register_windows ());
7835 /* Load the fp value for the containing fn into %fp. This is needed
7836 because STACK refers to %fp. Note that virtual register instantiation
7837 fails if the virtual %fp isn't set from a register. */
7838 if (GET_CODE (fp) != REG)
7839 fp = force_reg (Pmode, fp);
7840 emit_move_insn (virtual_stack_vars_rtx, fp);
7842 /* Find the containing function's current nonlocal goto handler,
7843 which will do any cleanups and then jump to the label. */
7844 labreg = gen_rtx_REG (Pmode, 8);
7845 emit_move_insn (labreg, lab);
7847 /* Restore %fp from stack pointer value for containing function.
7848 The restore insn that follows will move this to %sp,
7849 and reload the appropriate value into %fp. */
7850 emit_move_insn (hard_frame_pointer_rtx, stack);
7852 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
7853 emit_insn (gen_rtx_USE (VOIDmode, static_chain_rtx));
7855 /* ??? The V9-specific version was disabled in rev 1.65. */
7856 emit_jump_insn (gen_goto_handler_and_restore (labreg));
7861 ;; Special trap insn to flush register windows.
7862 (define_insn "flush_register_windows"
7863 [(unspec_volatile [(const_int 0)] UNSPECV_FLUSHW)]
7865 { return TARGET_V9 ? "flushw" : "ta\t3"; }
7866 [(set_attr "type" "flushw")])
7868 (define_insn "goto_handler_and_restore"
7869 [(unspec_volatile [(match_operand 0 "register_operand" "=r")] UNSPECV_GOTO)]
7870 "GET_MODE (operands[0]) == Pmode"
7872 if (flag_delayed_branch)
7873 return "jmp\t%0\n\t restore";
7875 return "mov\t%0,%%g1\n\trestore\n\tjmp\t%%g1\n\t nop";
7877 [(set (attr "type") (const_string "multi"))
7878 (set (attr "length")
7879 (if_then_else (eq_attr "delayed_branch" "true")
7883 ;; For __builtin_setjmp we need to flush register windows iff the function
7884 ;; calls alloca as well, because otherwise the register window might be
7885 ;; saved after %sp adjustment and thus setjmp would crash
7886 (define_expand "builtin_setjmp_setup"
7887 [(match_operand 0 "register_operand" "r")]
7890 emit_insn (gen_do_builtin_setjmp_setup ());
7894 (define_insn "do_builtin_setjmp_setup"
7895 [(unspec_volatile [(const_int 0)] UNSPECV_SETJMP)]
7898 if (! current_function_calls_alloca)
7902 fputs ("\tflushw\n", asm_out_file);
7904 fprintf (asm_out_file, "\tst%c\t%%l7, [%%sp+%d]\n",
7905 TARGET_ARCH64 ? 'x' : 'w',
7906 SPARC_STACK_BIAS + 7 * UNITS_PER_WORD);
7907 fprintf (asm_out_file, "\tst%c\t%%fp, [%%sp+%d]\n",
7908 TARGET_ARCH64 ? 'x' : 'w',
7909 SPARC_STACK_BIAS + 14 * UNITS_PER_WORD);
7910 fprintf (asm_out_file, "\tst%c\t%%i7, [%%sp+%d]\n",
7911 TARGET_ARCH64 ? 'x' : 'w',
7912 SPARC_STACK_BIAS + 15 * UNITS_PER_WORD);
7915 [(set_attr "type" "multi")
7916 (set (attr "length")
7917 (cond [(eq_attr "calls_alloca" "false")
7919 (eq_attr "isa" "!v9")
7921 (eq_attr "pic" "true")
7922 (const_int 4)] (const_int 3)))])
7924 ;; Pattern for use after a setjmp to store FP and the return register
7925 ;; into the stack area.
7927 (define_expand "setjmp"
7932 emit_insn (gen_setjmp_64 ());
7934 emit_insn (gen_setjmp_32 ());
7938 (define_expand "setjmp_32"
7939 [(set (mem:SI (plus:SI (reg:SI 14) (const_int 56))) (match_dup 0))
7940 (set (mem:SI (plus:SI (reg:SI 14) (const_int 60))) (reg:SI 31))]
7942 { operands[0] = frame_pointer_rtx; })
7944 (define_expand "setjmp_64"
7945 [(set (mem:DI (plus:DI (reg:DI 14) (const_int 112))) (match_dup 0))
7946 (set (mem:DI (plus:DI (reg:DI 14) (const_int 120))) (reg:DI 31))]
7948 { operands[0] = frame_pointer_rtx; })
7950 ;; Special pattern for the FLUSH instruction.
7952 ; We do SImode and DImode versions of this to quiet down genrecog's complaints
7953 ; of the define_insn otherwise missing a mode. We make "flush", aka
7954 ; gen_flush, the default one since sparc_initialize_trampoline uses
7955 ; it on SImode mem values.
7957 (define_insn "flush"
7958 [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")] UNSPECV_FLUSH)]
7960 { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; }
7961 [(set_attr "type" "iflush")])
7963 (define_insn "flushdi"
7964 [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")] UNSPECV_FLUSH)]
7966 { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; }
7967 [(set_attr "type" "iflush")])
7972 ;; The scan instruction searches from the most significant bit while ffs
7973 ;; searches from the least significant bit. The bit index and treatment of
7974 ;; zero also differ. It takes at least 7 instructions to get the proper
7975 ;; result. Here is an obvious 8 instruction sequence.
7978 (define_insn "ffssi2"
7979 [(set (match_operand:SI 0 "register_operand" "=&r")
7980 (ffs:SI (match_operand:SI 1 "register_operand" "r")))
7981 (clobber (match_scratch:SI 2 "=&r"))]
7982 "TARGET_SPARCLITE || TARGET_SPARCLET"
7984 return "sub\t%%g0, %1, %0\;and\t%0, %1, %0\;scan\t%0, 0, %0\;mov\t32, %2\;sub\t%2, %0, %0\;sra\t%0, 31, %2\;and\t%2, 31, %2\;add\t%2, %0, %0";
7986 [(set_attr "type" "multi")
7987 (set_attr "length" "8")])
7989 ;; ??? This should be a define expand, so that the extra instruction have
7990 ;; a chance of being optimized away.
7992 ;; Disabled because none of the UltraSPARCs implement popc. The HAL R1
7993 ;; does, but no one uses that and we don't have a switch for it.
7995 ;(define_insn "ffsdi2"
7996 ; [(set (match_operand:DI 0 "register_operand" "=&r")
7997 ; (ffs:DI (match_operand:DI 1 "register_operand" "r")))
7998 ; (clobber (match_scratch:DI 2 "=&r"))]
8000 ; "neg\t%1, %2\;xnor\t%1, %2, %2\;popc\t%2, %0\;movzr\t%1, 0, %0"
8001 ; [(set_attr "type" "multi")
8002 ; (set_attr "length" "4")])
8006 ;; Peepholes go at the end.
8008 ;; Optimize consecutive loads or stores into ldd and std when possible.
8009 ;; The conditions in which we do this are very restricted and are
8010 ;; explained in the code for {registers,memory}_ok_for_ldd functions.
8013 [(set (match_operand:SI 0 "memory_operand" "")
8015 (set (match_operand:SI 1 "memory_operand" "")
8018 && mems_ok_for_ldd_peep (operands[0], operands[1], NULL_RTX)"
8021 "operands[0] = widen_memory_access (operands[0], DImode, 0);")
8024 [(set (match_operand:SI 0 "memory_operand" "")
8026 (set (match_operand:SI 1 "memory_operand" "")
8029 && mems_ok_for_ldd_peep (operands[1], operands[0], NULL_RTX)"
8032 "operands[1] = widen_memory_access (operands[1], DImode, 0);")
8035 [(set (match_operand:SI 0 "register_operand" "")
8036 (match_operand:SI 1 "memory_operand" ""))
8037 (set (match_operand:SI 2 "register_operand" "")
8038 (match_operand:SI 3 "memory_operand" ""))]
8039 "registers_ok_for_ldd_peep (operands[0], operands[2])
8040 && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
8043 "operands[1] = widen_memory_access (operands[1], DImode, 0);
8044 operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));")
8047 [(set (match_operand:SI 0 "memory_operand" "")
8048 (match_operand:SI 1 "register_operand" ""))
8049 (set (match_operand:SI 2 "memory_operand" "")
8050 (match_operand:SI 3 "register_operand" ""))]
8051 "registers_ok_for_ldd_peep (operands[1], operands[3])
8052 && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
8055 "operands[0] = widen_memory_access (operands[0], DImode, 0);
8056 operands[1] = gen_rtx_REG (DImode, REGNO (operands[1]));")
8059 [(set (match_operand:SF 0 "register_operand" "")
8060 (match_operand:SF 1 "memory_operand" ""))
8061 (set (match_operand:SF 2 "register_operand" "")
8062 (match_operand:SF 3 "memory_operand" ""))]
8063 "registers_ok_for_ldd_peep (operands[0], operands[2])
8064 && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
8067 "operands[1] = widen_memory_access (operands[1], DFmode, 0);
8068 operands[0] = gen_rtx_REG (DFmode, REGNO (operands[0]));")
8071 [(set (match_operand:SF 0 "memory_operand" "")
8072 (match_operand:SF 1 "register_operand" ""))
8073 (set (match_operand:SF 2 "memory_operand" "")
8074 (match_operand:SF 3 "register_operand" ""))]
8075 "registers_ok_for_ldd_peep (operands[1], operands[3])
8076 && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
8079 "operands[0] = widen_memory_access (operands[0], DFmode, 0);
8080 operands[1] = gen_rtx_REG (DFmode, REGNO (operands[1]));")
8083 [(set (match_operand:SI 0 "register_operand" "")
8084 (match_operand:SI 1 "memory_operand" ""))
8085 (set (match_operand:SI 2 "register_operand" "")
8086 (match_operand:SI 3 "memory_operand" ""))]
8087 "registers_ok_for_ldd_peep (operands[2], operands[0])
8088 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
8091 "operands[3] = widen_memory_access (operands[3], DImode, 0);
8092 operands[2] = gen_rtx_REG (DImode, REGNO (operands[2]));")
8095 [(set (match_operand:SI 0 "memory_operand" "")
8096 (match_operand:SI 1 "register_operand" ""))
8097 (set (match_operand:SI 2 "memory_operand" "")
8098 (match_operand:SI 3 "register_operand" ""))]
8099 "registers_ok_for_ldd_peep (operands[3], operands[1])
8100 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
8103 "operands[2] = widen_memory_access (operands[2], DImode, 0);
8104 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
8108 [(set (match_operand:SF 0 "register_operand" "")
8109 (match_operand:SF 1 "memory_operand" ""))
8110 (set (match_operand:SF 2 "register_operand" "")
8111 (match_operand:SF 3 "memory_operand" ""))]
8112 "registers_ok_for_ldd_peep (operands[2], operands[0])
8113 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
8116 "operands[3] = widen_memory_access (operands[3], DFmode, 0);
8117 operands[2] = gen_rtx_REG (DFmode, REGNO (operands[2]));")
8120 [(set (match_operand:SF 0 "memory_operand" "")
8121 (match_operand:SF 1 "register_operand" ""))
8122 (set (match_operand:SF 2 "memory_operand" "")
8123 (match_operand:SF 3 "register_operand" ""))]
8124 "registers_ok_for_ldd_peep (operands[3], operands[1])
8125 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
8128 "operands[2] = widen_memory_access (operands[2], DFmode, 0);
8129 operands[3] = gen_rtx_REG (DFmode, REGNO (operands[3]));")
8131 ;; Optimize the case of following a reg-reg move with a test
8132 ;; of reg just moved. Don't allow floating point regs for operand 0 or 1.
8133 ;; This can result from a float to fix conversion.
8136 [(set (match_operand:SI 0 "register_operand" "")
8137 (match_operand:SI 1 "register_operand" ""))
8139 (compare:CC (match_operand:SI 2 "register_operand" "")
8141 "(rtx_equal_p (operands[2], operands[0])
8142 || rtx_equal_p (operands[2], operands[1]))
8143 && ! SPARC_FP_REG_P (REGNO (operands[0]))
8144 && ! SPARC_FP_REG_P (REGNO (operands[1]))"
8145 [(parallel [(set (match_dup 0) (match_dup 1))
8147 (compare:CC (match_dup 1) (const_int 0)))])]
8151 [(set (match_operand:DI 0 "register_operand" "")
8152 (match_operand:DI 1 "register_operand" ""))
8154 (compare:CCX (match_operand:DI 2 "register_operand" "")
8157 && (rtx_equal_p (operands[2], operands[0])
8158 || rtx_equal_p (operands[2], operands[1]))
8159 && ! SPARC_FP_REG_P (REGNO (operands[0]))
8160 && ! SPARC_FP_REG_P (REGNO (operands[1]))"
8161 [(parallel [(set (match_dup 0) (match_dup 1))
8163 (compare:CCX (match_dup 1) (const_int 0)))])]
8166 ;; ??? UltraSPARC-III note: A memory operation loading into the floating point register
8167 ;; ??? file, if it hits the prefetch cache, has a chance to dual-issue with other memory
8168 ;; ??? operations. With DFA we might be able to model this, but it requires a lot of
8170 (define_expand "prefetch"
8171 [(match_operand 0 "address_operand" "")
8172 (match_operand 1 "const_int_operand" "")
8173 (match_operand 2 "const_int_operand" "")]
8177 emit_insn (gen_prefetch_64 (operands[0], operands[1], operands[2]));
8179 emit_insn (gen_prefetch_32 (operands[0], operands[1], operands[2]));
8183 (define_insn "prefetch_64"
8184 [(prefetch (match_operand:DI 0 "address_operand" "p")
8185 (match_operand:DI 1 "const_int_operand" "n")
8186 (match_operand:DI 2 "const_int_operand" "n"))]
8189 static const char * const prefetch_instr[2][2] = {
8191 "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
8192 "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
8195 "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
8196 "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
8199 int read_or_write = INTVAL (operands[1]);
8200 int locality = INTVAL (operands[2]);
8202 if (read_or_write != 0 && read_or_write != 1)
8204 if (locality < 0 || locality > 3)
8206 return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
8208 [(set_attr "type" "load")])
8210 (define_insn "prefetch_32"
8211 [(prefetch (match_operand:SI 0 "address_operand" "p")
8212 (match_operand:SI 1 "const_int_operand" "n")
8213 (match_operand:SI 2 "const_int_operand" "n"))]
8216 static const char * const prefetch_instr[2][2] = {
8218 "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
8219 "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
8222 "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
8223 "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
8226 int read_or_write = INTVAL (operands[1]);
8227 int locality = INTVAL (operands[2]);
8229 if (read_or_write != 0 && read_or_write != 1)
8231 if (locality < 0 || locality > 3)
8233 return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
8235 [(set_attr "type" "load")])
8238 [(trap_if (const_int 1) (const_int 5))]
8241 [(set_attr "type" "trap")])
8243 (define_expand "conditional_trap"
8244 [(trap_if (match_operator 0 "noov_compare_op"
8245 [(match_dup 2) (match_dup 3)])
8246 (match_operand:SI 1 "arith_operand" ""))]
8248 "operands[2] = gen_compare_reg (GET_CODE (operands[0]),
8249 sparc_compare_op0, sparc_compare_op1);
8250 operands[3] = const0_rtx;")
8253 [(trap_if (match_operator 0 "noov_compare_op" [(reg:CC 100) (const_int 0)])
8254 (match_operand:SI 1 "arith_operand" "rM"))]
8257 [(set_attr "type" "trap")])
8260 [(trap_if (match_operator 0 "noov_compare_op" [(reg:CCX 100) (const_int 0)])
8261 (match_operand:SI 1 "arith_operand" "rM"))]
8264 [(set_attr "type" "trap")])
8267 (define_insn "tgd_hi22"
8268 [(set (match_operand:SI 0 "register_operand" "=r")
8269 (high:SI (unspec:SI [(match_operand 1 "tgd_symbolic_operand" "")]
8272 "sethi\\t%%tgd_hi22(%a1), %0")
8274 (define_insn "tgd_lo10"
8275 [(set (match_operand:SI 0 "register_operand" "=r")
8276 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
8277 (unspec:SI [(match_operand 2 "tgd_symbolic_operand" "")]
8280 "add\\t%1, %%tgd_lo10(%a2), %0")
8282 (define_insn "tgd_add32"
8283 [(set (match_operand:SI 0 "register_operand" "=r")
8284 (plus:SI (match_operand:SI 1 "register_operand" "r")
8285 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8286 (match_operand 3 "tgd_symbolic_operand" "")]
8288 "TARGET_TLS && TARGET_ARCH32"
8289 "add\\t%1, %2, %0, %%tgd_add(%a3)")
8291 (define_insn "tgd_add64"
8292 [(set (match_operand:DI 0 "register_operand" "=r")
8293 (plus:DI (match_operand:DI 1 "register_operand" "r")
8294 (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8295 (match_operand 3 "tgd_symbolic_operand" "")]
8297 "TARGET_TLS && TARGET_ARCH64"
8298 "add\\t%1, %2, %0, %%tgd_add(%a3)")
8300 (define_insn "tgd_call32"
8301 [(set (match_operand 0 "register_operand" "=r")
8302 (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")
8303 (match_operand 2 "tgd_symbolic_operand" "")]
8305 (match_operand 3 "" "")))
8306 (clobber (reg:SI 15))]
8307 "TARGET_TLS && TARGET_ARCH32"
8308 "call\t%a1, %%tgd_call(%a2)%#"
8309 [(set_attr "type" "call")])
8311 (define_insn "tgd_call64"
8312 [(set (match_operand 0 "register_operand" "=r")
8313 (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")
8314 (match_operand 2 "tgd_symbolic_operand" "")]
8316 (match_operand 3 "" "")))
8317 (clobber (reg:DI 15))]
8318 "TARGET_TLS && TARGET_ARCH64"
8319 "call\t%a1, %%tgd_call(%a2)%#"
8320 [(set_attr "type" "call")])
8322 (define_insn "tldm_hi22"
8323 [(set (match_operand:SI 0 "register_operand" "=r")
8324 (high:SI (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
8326 "sethi\\t%%tldm_hi22(%&), %0")
8328 (define_insn "tldm_lo10"
8329 [(set (match_operand:SI 0 "register_operand" "=r")
8330 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
8331 (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
8333 "add\\t%1, %%tldm_lo10(%&), %0")
8335 (define_insn "tldm_add32"
8336 [(set (match_operand:SI 0 "register_operand" "=r")
8337 (plus:SI (match_operand:SI 1 "register_operand" "r")
8338 (unspec:SI [(match_operand:SI 2 "register_operand" "r")]
8340 "TARGET_TLS && TARGET_ARCH32"
8341 "add\\t%1, %2, %0, %%tldm_add(%&)")
8343 (define_insn "tldm_add64"
8344 [(set (match_operand:DI 0 "register_operand" "=r")
8345 (plus:DI (match_operand:DI 1 "register_operand" "r")
8346 (unspec:DI [(match_operand:SI 2 "register_operand" "r")]
8348 "TARGET_TLS && TARGET_ARCH64"
8349 "add\\t%1, %2, %0, %%tldm_add(%&)")
8351 (define_insn "tldm_call32"
8352 [(set (match_operand 0 "register_operand" "=r")
8353 (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")]
8355 (match_operand 2 "" "")))
8356 (clobber (reg:SI 15))]
8357 "TARGET_TLS && TARGET_ARCH32"
8358 "call\t%a1, %%tldm_call(%&)%#"
8359 [(set_attr "type" "call")])
8361 (define_insn "tldm_call64"
8362 [(set (match_operand 0 "register_operand" "=r")
8363 (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")]
8365 (match_operand 2 "" "")))
8366 (clobber (reg:DI 15))]
8367 "TARGET_TLS && TARGET_ARCH64"
8368 "call\t%a1, %%tldm_call(%&)%#"
8369 [(set_attr "type" "call")])
8371 (define_insn "tldo_hix22"
8372 [(set (match_operand:SI 0 "register_operand" "=r")
8373 (high:SI (unspec:SI [(match_operand 1 "tld_symbolic_operand" "")]
8376 "sethi\\t%%tldo_hix22(%a1), %0")
8378 (define_insn "tldo_lox10"
8379 [(set (match_operand:SI 0 "register_operand" "=r")
8380 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
8381 (unspec:SI [(match_operand 2 "tld_symbolic_operand" "")]
8384 "xor\\t%1, %%tldo_lox10(%a2), %0")
8386 (define_insn "tldo_add32"
8387 [(set (match_operand:SI 0 "register_operand" "=r")
8388 (plus:SI (match_operand:SI 1 "register_operand" "r")
8389 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8390 (match_operand 3 "tld_symbolic_operand" "")]
8392 "TARGET_TLS && TARGET_ARCH32"
8393 "add\\t%1, %2, %0, %%tldo_add(%a3)")
8395 (define_insn "tldo_add64"
8396 [(set (match_operand:DI 0 "register_operand" "=r")
8397 (plus:DI (match_operand:DI 1 "register_operand" "r")
8398 (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8399 (match_operand 3 "tld_symbolic_operand" "")]
8401 "TARGET_TLS && TARGET_ARCH64"
8402 "add\\t%1, %2, %0, %%tldo_add(%a3)")
8404 (define_insn "tie_hi22"
8405 [(set (match_operand:SI 0 "register_operand" "=r")
8406 (high:SI (unspec:SI [(match_operand 1 "tie_symbolic_operand" "")]
8409 "sethi\\t%%tie_hi22(%a1), %0")
8411 (define_insn "tie_lo10"
8412 [(set (match_operand:SI 0 "register_operand" "=r")
8413 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
8414 (unspec:SI [(match_operand 2 "tie_symbolic_operand" "")]
8417 "add\\t%1, %%tie_lo10(%a2), %0")
8419 (define_insn "tie_ld32"
8420 [(set (match_operand:SI 0 "register_operand" "=r")
8421 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
8422 (match_operand:SI 2 "register_operand" "r")
8423 (match_operand 3 "tie_symbolic_operand" "")]
8425 "TARGET_TLS && TARGET_ARCH32"
8426 "ld\\t[%1 + %2], %0, %%tie_ld(%a3)"
8427 [(set_attr "type" "load")])
8429 (define_insn "tie_ld64"
8430 [(set (match_operand:DI 0 "register_operand" "=r")
8431 (unspec:DI [(match_operand:DI 1 "register_operand" "r")
8432 (match_operand:SI 2 "register_operand" "r")
8433 (match_operand 3 "tie_symbolic_operand" "")]
8435 "TARGET_TLS && TARGET_ARCH64"
8436 "ldx\\t[%1 + %2], %0, %%tie_ldx(%a3)"
8437 [(set_attr "type" "load")])
8439 (define_insn "tie_add32"
8440 [(set (match_operand:SI 0 "register_operand" "=r")
8441 (plus:SI (match_operand:SI 1 "register_operand" "r")
8442 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8443 (match_operand 3 "tie_symbolic_operand" "")]
8445 "TARGET_SUN_TLS && TARGET_ARCH32"
8446 "add\\t%1, %2, %0, %%tie_add(%a3)")
8448 (define_insn "tie_add64"
8449 [(set (match_operand:DI 0 "register_operand" "=r")
8450 (plus:DI (match_operand:DI 1 "register_operand" "r")
8451 (unspec:DI [(match_operand:DI 2 "register_operand" "r")
8452 (match_operand 3 "tie_symbolic_operand" "")]
8454 "TARGET_SUN_TLS && TARGET_ARCH64"
8455 "add\\t%1, %2, %0, %%tie_add(%a3)")
8457 (define_insn "tle_hix22_sp32"
8458 [(set (match_operand:SI 0 "register_operand" "=r")
8459 (high:SI (unspec:SI [(match_operand 1 "tle_symbolic_operand" "")]
8461 "TARGET_TLS && TARGET_ARCH32"
8462 "sethi\\t%%tle_hix22(%a1), %0")
8464 (define_insn "tle_lox10_sp32"
8465 [(set (match_operand:SI 0 "register_operand" "=r")
8466 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
8467 (unspec:SI [(match_operand 2 "tle_symbolic_operand" "")]
8469 "TARGET_TLS && TARGET_ARCH32"
8470 "xor\\t%1, %%tle_lox10(%a2), %0")
8472 (define_insn "tle_hix22_sp64"
8473 [(set (match_operand:DI 0 "register_operand" "=r")
8474 (high:DI (unspec:DI [(match_operand 1 "tle_symbolic_operand" "")]
8476 "TARGET_TLS && TARGET_ARCH64"
8477 "sethi\\t%%tle_hix22(%a1), %0")
8479 (define_insn "tle_lox10_sp64"
8480 [(set (match_operand:DI 0 "register_operand" "=r")
8481 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
8482 (unspec:DI [(match_operand 2 "tle_symbolic_operand" "")]
8484 "TARGET_TLS && TARGET_ARCH64"
8485 "xor\\t%1, %%tle_lox10(%a2), %0")
8487 ;; Now patterns combining tldo_add{32,64} with some integer loads or stores
8488 (define_insn "*tldo_ldub_sp32"
8489 [(set (match_operand:QI 0 "register_operand" "=r")
8490 (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8491 (match_operand 3 "tld_symbolic_operand" "")]
8493 (match_operand:SI 1 "register_operand" "r"))))]
8494 "TARGET_TLS && TARGET_ARCH32"
8495 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8496 [(set_attr "type" "load")
8497 (set_attr "us3load_type" "3cycle")])
8499 (define_insn "*tldo_ldub1_sp32"
8500 [(set (match_operand:HI 0 "register_operand" "=r")
8501 (zero_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8502 (match_operand 3 "tld_symbolic_operand" "")]
8504 (match_operand:SI 1 "register_operand" "r")))))]
8505 "TARGET_TLS && TARGET_ARCH32"
8506 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8507 [(set_attr "type" "load")
8508 (set_attr "us3load_type" "3cycle")])
8510 (define_insn "*tldo_ldub2_sp32"
8511 [(set (match_operand:SI 0 "register_operand" "=r")
8512 (zero_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8513 (match_operand 3 "tld_symbolic_operand" "")]
8515 (match_operand:SI 1 "register_operand" "r")))))]
8516 "TARGET_TLS && TARGET_ARCH32"
8517 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8518 [(set_attr "type" "load")
8519 (set_attr "us3load_type" "3cycle")])
8521 (define_insn "*tldo_ldsb1_sp32"
8522 [(set (match_operand:HI 0 "register_operand" "=r")
8523 (sign_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8524 (match_operand 3 "tld_symbolic_operand" "")]
8526 (match_operand:SI 1 "register_operand" "r")))))]
8527 "TARGET_TLS && TARGET_ARCH32"
8528 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
8529 [(set_attr "type" "sload")
8530 (set_attr "us3load_type" "3cycle")])
8532 (define_insn "*tldo_ldsb2_sp32"
8533 [(set (match_operand:SI 0 "register_operand" "=r")
8534 (sign_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8535 (match_operand 3 "tld_symbolic_operand" "")]
8537 (match_operand:SI 1 "register_operand" "r")))))]
8538 "TARGET_TLS && TARGET_ARCH32"
8539 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
8540 [(set_attr "type" "sload")
8541 (set_attr "us3load_type" "3cycle")])
8543 (define_insn "*tldo_ldub_sp64"
8544 [(set (match_operand:QI 0 "register_operand" "=r")
8545 (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8546 (match_operand 3 "tld_symbolic_operand" "")]
8548 (match_operand:DI 1 "register_operand" "r"))))]
8549 "TARGET_TLS && TARGET_ARCH64"
8550 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8551 [(set_attr "type" "load")
8552 (set_attr "us3load_type" "3cycle")])
8554 (define_insn "*tldo_ldub1_sp64"
8555 [(set (match_operand:HI 0 "register_operand" "=r")
8556 (zero_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8557 (match_operand 3 "tld_symbolic_operand" "")]
8559 (match_operand:DI 1 "register_operand" "r")))))]
8560 "TARGET_TLS && TARGET_ARCH64"
8561 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8562 [(set_attr "type" "load")
8563 (set_attr "us3load_type" "3cycle")])
8565 (define_insn "*tldo_ldub2_sp64"
8566 [(set (match_operand:SI 0 "register_operand" "=r")
8567 (zero_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8568 (match_operand 3 "tld_symbolic_operand" "")]
8570 (match_operand:DI 1 "register_operand" "r")))))]
8571 "TARGET_TLS && TARGET_ARCH64"
8572 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8573 [(set_attr "type" "load")
8574 (set_attr "us3load_type" "3cycle")])
8576 (define_insn "*tldo_ldub3_sp64"
8577 [(set (match_operand:DI 0 "register_operand" "=r")
8578 (zero_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8579 (match_operand 3 "tld_symbolic_operand" "")]
8581 (match_operand:DI 1 "register_operand" "r")))))]
8582 "TARGET_TLS && TARGET_ARCH64"
8583 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8584 [(set_attr "type" "load")
8585 (set_attr "us3load_type" "3cycle")])
8587 (define_insn "*tldo_ldsb1_sp64"
8588 [(set (match_operand:HI 0 "register_operand" "=r")
8589 (sign_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8590 (match_operand 3 "tld_symbolic_operand" "")]
8592 (match_operand:DI 1 "register_operand" "r")))))]
8593 "TARGET_TLS && TARGET_ARCH64"
8594 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
8595 [(set_attr "type" "sload")
8596 (set_attr "us3load_type" "3cycle")])
8598 (define_insn "*tldo_ldsb2_sp64"
8599 [(set (match_operand:SI 0 "register_operand" "=r")
8600 (sign_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8601 (match_operand 3 "tld_symbolic_operand" "")]
8603 (match_operand:DI 1 "register_operand" "r")))))]
8604 "TARGET_TLS && TARGET_ARCH64"
8605 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
8606 [(set_attr "type" "sload")
8607 (set_attr "us3load_type" "3cycle")])
8609 (define_insn "*tldo_ldsb3_sp64"
8610 [(set (match_operand:DI 0 "register_operand" "=r")
8611 (sign_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8612 (match_operand 3 "tld_symbolic_operand" "")]
8614 (match_operand:DI 1 "register_operand" "r")))))]
8615 "TARGET_TLS && TARGET_ARCH64"
8616 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
8617 [(set_attr "type" "sload")
8618 (set_attr "us3load_type" "3cycle")])
8620 (define_insn "*tldo_lduh_sp32"
8621 [(set (match_operand:HI 0 "register_operand" "=r")
8622 (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8623 (match_operand 3 "tld_symbolic_operand" "")]
8625 (match_operand:SI 1 "register_operand" "r"))))]
8626 "TARGET_TLS && TARGET_ARCH32"
8627 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
8628 [(set_attr "type" "load")
8629 (set_attr "us3load_type" "3cycle")])
8631 (define_insn "*tldo_lduh1_sp32"
8632 [(set (match_operand:SI 0 "register_operand" "=r")
8633 (zero_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8634 (match_operand 3 "tld_symbolic_operand" "")]
8636 (match_operand:SI 1 "register_operand" "r")))))]
8637 "TARGET_TLS && TARGET_ARCH32"
8638 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
8639 [(set_attr "type" "load")
8640 (set_attr "us3load_type" "3cycle")])
8642 (define_insn "*tldo_ldsh1_sp32"
8643 [(set (match_operand:SI 0 "register_operand" "=r")
8644 (sign_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8645 (match_operand 3 "tld_symbolic_operand" "")]
8647 (match_operand:SI 1 "register_operand" "r")))))]
8648 "TARGET_TLS && TARGET_ARCH32"
8649 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
8650 [(set_attr "type" "sload")
8651 (set_attr "us3load_type" "3cycle")])
8653 (define_insn "*tldo_lduh_sp64"
8654 [(set (match_operand:HI 0 "register_operand" "=r")
8655 (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8656 (match_operand 3 "tld_symbolic_operand" "")]
8658 (match_operand:DI 1 "register_operand" "r"))))]
8659 "TARGET_TLS && TARGET_ARCH64"
8660 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
8661 [(set_attr "type" "load")
8662 (set_attr "us3load_type" "3cycle")])
8664 (define_insn "*tldo_lduh1_sp64"
8665 [(set (match_operand:SI 0 "register_operand" "=r")
8666 (zero_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8667 (match_operand 3 "tld_symbolic_operand" "")]
8669 (match_operand:DI 1 "register_operand" "r")))))]
8670 "TARGET_TLS && TARGET_ARCH64"
8671 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
8672 [(set_attr "type" "load")
8673 (set_attr "us3load_type" "3cycle")])
8675 (define_insn "*tldo_lduh2_sp64"
8676 [(set (match_operand:DI 0 "register_operand" "=r")
8677 (zero_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8678 (match_operand 3 "tld_symbolic_operand" "")]
8680 (match_operand:DI 1 "register_operand" "r")))))]
8681 "TARGET_TLS && TARGET_ARCH64"
8682 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
8683 [(set_attr "type" "load")
8684 (set_attr "us3load_type" "3cycle")])
8686 (define_insn "*tldo_ldsh1_sp64"
8687 [(set (match_operand:SI 0 "register_operand" "=r")
8688 (sign_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8689 (match_operand 3 "tld_symbolic_operand" "")]
8691 (match_operand:DI 1 "register_operand" "r")))))]
8692 "TARGET_TLS && TARGET_ARCH64"
8693 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
8694 [(set_attr "type" "sload")
8695 (set_attr "us3load_type" "3cycle")])
8697 (define_insn "*tldo_ldsh2_sp64"
8698 [(set (match_operand:DI 0 "register_operand" "=r")
8699 (sign_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8700 (match_operand 3 "tld_symbolic_operand" "")]
8702 (match_operand:DI 1 "register_operand" "r")))))]
8703 "TARGET_TLS && TARGET_ARCH64"
8704 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
8705 [(set_attr "type" "sload")
8706 (set_attr "us3load_type" "3cycle")])
8708 (define_insn "*tldo_lduw_sp32"
8709 [(set (match_operand:SI 0 "register_operand" "=r")
8710 (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8711 (match_operand 3 "tld_symbolic_operand" "")]
8713 (match_operand:SI 1 "register_operand" "r"))))]
8714 "TARGET_TLS && TARGET_ARCH32"
8715 "ld\t[%1 + %2], %0, %%tldo_add(%3)"
8716 [(set_attr "type" "load")])
8718 (define_insn "*tldo_lduw_sp64"
8719 [(set (match_operand:SI 0 "register_operand" "=r")
8720 (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8721 (match_operand 3 "tld_symbolic_operand" "")]
8723 (match_operand:DI 1 "register_operand" "r"))))]
8724 "TARGET_TLS && TARGET_ARCH64"
8725 "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
8726 [(set_attr "type" "load")])
8728 (define_insn "*tldo_lduw1_sp64"
8729 [(set (match_operand:DI 0 "register_operand" "=r")
8730 (zero_extend:DI (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8731 (match_operand 3 "tld_symbolic_operand" "")]
8733 (match_operand:DI 1 "register_operand" "r")))))]
8734 "TARGET_TLS && TARGET_ARCH64"
8735 "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
8736 [(set_attr "type" "load")])
8738 (define_insn "*tldo_ldsw1_sp64"
8739 [(set (match_operand:DI 0 "register_operand" "=r")
8740 (sign_extend:DI (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8741 (match_operand 3 "tld_symbolic_operand" "")]
8743 (match_operand:DI 1 "register_operand" "r")))))]
8744 "TARGET_TLS && TARGET_ARCH64"
8745 "ldsw\t[%1 + %2], %0, %%tldo_add(%3)"
8746 [(set_attr "type" "sload")
8747 (set_attr "us3load_type" "3cycle")])
8749 (define_insn "*tldo_ldx_sp64"
8750 [(set (match_operand:DI 0 "register_operand" "=r")
8751 (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8752 (match_operand 3 "tld_symbolic_operand" "")]
8754 (match_operand:DI 1 "register_operand" "r"))))]
8755 "TARGET_TLS && TARGET_ARCH64"
8756 "ldx\t[%1 + %2], %0, %%tldo_add(%3)"
8757 [(set_attr "type" "load")])
8759 (define_insn "*tldo_stb_sp32"
8760 [(set (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8761 (match_operand 3 "tld_symbolic_operand" "")]
8763 (match_operand:SI 1 "register_operand" "r")))
8764 (match_operand:QI 0 "register_operand" "=r"))]
8765 "TARGET_TLS && TARGET_ARCH32"
8766 "stb\t%0, [%1 + %2], %%tldo_add(%3)"
8767 [(set_attr "type" "store")])
8769 (define_insn "*tldo_stb_sp64"
8770 [(set (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8771 (match_operand 3 "tld_symbolic_operand" "")]
8773 (match_operand:DI 1 "register_operand" "r")))
8774 (match_operand:QI 0 "register_operand" "=r"))]
8775 "TARGET_TLS && TARGET_ARCH64"
8776 "stb\t%0, [%1 + %2], %%tldo_add(%3)"
8777 [(set_attr "type" "store")])
8779 (define_insn "*tldo_sth_sp32"
8780 [(set (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8781 (match_operand 3 "tld_symbolic_operand" "")]
8783 (match_operand:SI 1 "register_operand" "r")))
8784 (match_operand:HI 0 "register_operand" "=r"))]
8785 "TARGET_TLS && TARGET_ARCH32"
8786 "sth\t%0, [%1 + %2], %%tldo_add(%3)"
8787 [(set_attr "type" "store")])
8789 (define_insn "*tldo_sth_sp64"
8790 [(set (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8791 (match_operand 3 "tld_symbolic_operand" "")]
8793 (match_operand:DI 1 "register_operand" "r")))
8794 (match_operand:HI 0 "register_operand" "=r"))]
8795 "TARGET_TLS && TARGET_ARCH64"
8796 "sth\t%0, [%1 + %2], %%tldo_add(%3)"
8797 [(set_attr "type" "store")])
8799 (define_insn "*tldo_stw_sp32"
8800 [(set (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8801 (match_operand 3 "tld_symbolic_operand" "")]
8803 (match_operand:SI 1 "register_operand" "r")))
8804 (match_operand:SI 0 "register_operand" "=r"))]
8805 "TARGET_TLS && TARGET_ARCH32"
8806 "st\t%0, [%1 + %2], %%tldo_add(%3)"
8807 [(set_attr "type" "store")])
8809 (define_insn "*tldo_stw_sp64"
8810 [(set (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8811 (match_operand 3 "tld_symbolic_operand" "")]
8813 (match_operand:DI 1 "register_operand" "r")))
8814 (match_operand:SI 0 "register_operand" "=r"))]
8815 "TARGET_TLS && TARGET_ARCH64"
8816 "stw\t%0, [%1 + %2], %%tldo_add(%3)"
8817 [(set_attr "type" "store")])
8819 (define_insn "*tldo_stx_sp64"
8820 [(set (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8821 (match_operand 3 "tld_symbolic_operand" "")]
8823 (match_operand:DI 1 "register_operand" "r")))
8824 (match_operand:DI 0 "register_operand" "=r"))]
8825 "TARGET_TLS && TARGET_ARCH64"
8826 "stx\t%0, [%1 + %2], %%tldo_add(%3)"
8827 [(set_attr "type" "store")])