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)
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)
60 ;; The upper 32 fp regs on the v9 can't hold SFmode values. To deal with this
61 ;; a second register class, EXTRA_FP_REGS, exists for the v9 chip. The name
62 ;; is a bit of a misnomer as it covers all 64 fp regs. The corresponding
63 ;; constraint letter is 'e'. To avoid any confusion, 'e' is used instead of
64 ;; 'f' for all DF/TFmode values, including those that are specific to the v8.
66 ;; Attribute for cpu type.
67 ;; These must match the values for enum processor_type in sparc.h.
74 hypersparc,sparclite86x,
79 (const (symbol_ref "sparc_cpu_attr")))
81 ;; Attribute for the instruction set.
82 ;; At present we only need to distinguish v9/!v9, but for clarity we
83 ;; test TARGET_V8 too.
84 (define_attr "isa" "v7,v8,v9,sparclet"
86 (cond [(symbol_ref "TARGET_V9") (const_string "v9")
87 (symbol_ref "TARGET_V8") (const_string "v8")
88 (symbol_ref "TARGET_SPARCLET") (const_string "sparclet")]
89 (const_string "v7"))))
92 (define_attr "arch" "arch32bit,arch64bit"
94 (cond [(symbol_ref "TARGET_ARCH64") (const_string "arch64bit")]
95 (const_string "arch32bit"))))
102 uncond_branch,branch,call,sibcall,call_no_delay_slot,return,
110 fga,fgm_pack,fgm_mul,fgm_pdist,fgm_cmp,
113 multi,savew,flushw,iflush,trap"
114 (const_string "ialu"))
116 ;; true if branch/call has empty delay slot and will emit a nop in it
117 (define_attr "empty_delay_slot" "false,true"
118 (symbol_ref "empty_delay_slot (insn)"))
120 (define_attr "branch_type" "none,icc,fcc,reg" (const_string "none"))
122 (define_attr "pic" "false,true"
123 (symbol_ref "flag_pic != 0"))
125 (define_attr "current_function_calls_alloca" "false,true"
126 (symbol_ref "current_function_calls_alloca != 0"))
128 ;; Length (in # of insns).
129 (define_attr "length" ""
130 (cond [(eq_attr "type" "uncond_branch,call,sibcall")
131 (if_then_else (eq_attr "empty_delay_slot" "true")
134 (eq_attr "branch_type" "icc")
135 (if_then_else (match_operand 0 "noov_compare64_op" "")
136 (if_then_else (lt (pc) (match_dup 1))
137 (if_then_else (lt (minus (match_dup 1) (pc)) (const_int 260000))
138 (if_then_else (eq_attr "empty_delay_slot" "true")
141 (if_then_else (eq_attr "empty_delay_slot" "true")
144 (if_then_else (lt (minus (pc) (match_dup 1)) (const_int 260000))
145 (if_then_else (eq_attr "empty_delay_slot" "true")
148 (if_then_else (eq_attr "empty_delay_slot" "true")
151 (if_then_else (eq_attr "empty_delay_slot" "true")
154 (eq_attr "branch_type" "fcc")
155 (if_then_else (match_operand 0 "fcc0_reg_operand" "")
156 (if_then_else (eq_attr "empty_delay_slot" "true")
157 (if_then_else (eq (symbol_ref "TARGET_V9") (const_int 0))
160 (if_then_else (eq (symbol_ref "TARGET_V9") (const_int 0))
163 (if_then_else (lt (pc) (match_dup 2))
164 (if_then_else (lt (minus (match_dup 2) (pc)) (const_int 260000))
165 (if_then_else (eq_attr "empty_delay_slot" "true")
168 (if_then_else (eq_attr "empty_delay_slot" "true")
171 (if_then_else (lt (minus (pc) (match_dup 2)) (const_int 260000))
172 (if_then_else (eq_attr "empty_delay_slot" "true")
175 (if_then_else (eq_attr "empty_delay_slot" "true")
178 (eq_attr "branch_type" "reg")
179 (if_then_else (lt (pc) (match_dup 2))
180 (if_then_else (lt (minus (match_dup 2) (pc)) (const_int 32000))
181 (if_then_else (eq_attr "empty_delay_slot" "true")
184 (if_then_else (eq_attr "empty_delay_slot" "true")
187 (if_then_else (lt (minus (pc) (match_dup 2)) (const_int 32000))
188 (if_then_else (eq_attr "empty_delay_slot" "true")
191 (if_then_else (eq_attr "empty_delay_slot" "true")
197 (define_attr "fptype" "single,double" (const_string "single"))
199 ;; UltraSPARC-III integer load type.
200 (define_attr "us3load_type" "2cycle,3cycle" (const_string "2cycle"))
202 (define_asm_attributes
203 [(set_attr "length" "2")
204 (set_attr "type" "multi")])
206 ;; Attributes for instruction and branch scheduling
208 (define_attr "tls_call_delay" "false,true"
209 (symbol_ref "tls_call_delay (insn)"))
211 (define_attr "in_call_delay" "false,true"
212 (cond [(eq_attr "type" "uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
213 (const_string "false")
214 (eq_attr "type" "load,fpload,store,fpstore")
215 (if_then_else (eq_attr "length" "1")
216 (const_string "true")
217 (const_string "false"))]
218 (if_then_else (and (eq_attr "length" "1")
219 (eq_attr "tls_call_delay" "true"))
220 (const_string "true")
221 (const_string "false"))))
223 (define_attr "eligible_for_sibcall_delay" "false,true"
224 (symbol_ref "eligible_for_sibcall_delay (insn)"))
226 (define_attr "eligible_for_return_delay" "false,true"
227 (symbol_ref "eligible_for_return_delay (insn)"))
229 ;; ??? !v9: Should implement the notion of predelay slots for floating-point
230 ;; branches. This would allow us to remove the nop always inserted before
231 ;; a floating point branch.
233 ;; ??? It is OK for fill_simple_delay_slots to put load/store instructions
234 ;; in a delay slot, but it is not OK for fill_eager_delay_slots to do so.
235 ;; This is because doing so will add several pipeline stalls to the path
236 ;; that the load/store did not come from. Unfortunately, there is no way
237 ;; to prevent fill_eager_delay_slots from using load/store without completely
238 ;; disabling them. For the SPEC benchmark set, this is a serious lose,
239 ;; because it prevents us from moving back the final store of inner loops.
241 (define_attr "in_branch_delay" "false,true"
242 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
243 (eq_attr "length" "1"))
244 (const_string "true")
245 (const_string "false")))
247 (define_attr "in_uncond_branch_delay" "false,true"
248 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
249 (eq_attr "length" "1"))
250 (const_string "true")
251 (const_string "false")))
253 (define_attr "in_annul_branch_delay" "false,true"
254 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
255 (eq_attr "length" "1"))
256 (const_string "true")
257 (const_string "false")))
259 (define_delay (eq_attr "type" "call")
260 [(eq_attr "in_call_delay" "true") (nil) (nil)])
262 (define_delay (eq_attr "type" "sibcall")
263 [(eq_attr "eligible_for_sibcall_delay" "true") (nil) (nil)])
265 (define_delay (eq_attr "type" "branch")
266 [(eq_attr "in_branch_delay" "true")
267 (nil) (eq_attr "in_annul_branch_delay" "true")])
269 (define_delay (eq_attr "type" "uncond_branch")
270 [(eq_attr "in_uncond_branch_delay" "true")
273 (define_delay (eq_attr "type" "return")
274 [(eq_attr "eligible_for_return_delay" "true") (nil) (nil)])
276 ;; Include SPARC DFA schedulers
278 (include "cypress.md")
279 (include "supersparc.md")
280 (include "hypersparc.md")
281 (include "sparclet.md")
282 (include "ultra1_2.md")
283 (include "ultra3.md")
286 ;; Compare instructions.
287 ;; This controls RTL generation and register allocation.
289 ;; We generate RTL for comparisons and branches by having the cmpxx
290 ;; patterns store away the operands. Then, the scc and bcc patterns
291 ;; emit RTL for both the compare and the branch.
293 ;; We do this because we want to generate different code for an sne and
294 ;; seq insn. In those cases, if the second operand of the compare is not
295 ;; const0_rtx, we want to compute the xor of the two operands and test
298 ;; We start with the DEFINE_EXPANDs, then the DEFINE_INSNs to match
299 ;; the patterns. Finally, we have the DEFINE_SPLITs for some of the scc
300 ;; insns that actually require more than one machine instruction.
302 ;; Put cmpsi first among compare insns so it matches two CONST_INT operands.
304 (define_expand "cmpsi"
306 (compare:CC (match_operand:SI 0 "compare_operand" "")
307 (match_operand:SI 1 "arith_operand" "")))]
310 if (GET_CODE (operands[0]) == ZERO_EXTRACT && operands[1] != const0_rtx)
311 operands[0] = force_reg (SImode, operands[0]);
313 sparc_compare_op0 = operands[0];
314 sparc_compare_op1 = operands[1];
318 (define_expand "cmpdi"
320 (compare:CCX (match_operand:DI 0 "compare_operand" "")
321 (match_operand:DI 1 "arith_double_operand" "")))]
324 if (GET_CODE (operands[0]) == ZERO_EXTRACT && operands[1] != const0_rtx)
325 operands[0] = force_reg (DImode, operands[0]);
327 sparc_compare_op0 = operands[0];
328 sparc_compare_op1 = operands[1];
332 (define_expand "cmpsf"
333 ;; The 96 here isn't ever used by anyone.
335 (compare:CCFP (match_operand:SF 0 "register_operand" "")
336 (match_operand:SF 1 "register_operand" "")))]
339 sparc_compare_op0 = operands[0];
340 sparc_compare_op1 = operands[1];
344 (define_expand "cmpdf"
345 ;; The 96 here isn't ever used by anyone.
347 (compare:CCFP (match_operand:DF 0 "register_operand" "")
348 (match_operand:DF 1 "register_operand" "")))]
351 sparc_compare_op0 = operands[0];
352 sparc_compare_op1 = operands[1];
356 (define_expand "cmptf"
357 ;; The 96 here isn't ever used by anyone.
359 (compare:CCFP (match_operand:TF 0 "register_operand" "")
360 (match_operand:TF 1 "register_operand" "")))]
363 sparc_compare_op0 = operands[0];
364 sparc_compare_op1 = operands[1];
368 ;; Now the compare DEFINE_INSNs.
370 (define_insn "*cmpsi_insn"
372 (compare:CC (match_operand:SI 0 "register_operand" "r")
373 (match_operand:SI 1 "arith_operand" "rI")))]
376 [(set_attr "type" "compare")])
378 (define_insn "*cmpdi_sp64"
380 (compare:CCX (match_operand:DI 0 "register_operand" "r")
381 (match_operand:DI 1 "arith_double_operand" "rHI")))]
384 [(set_attr "type" "compare")])
386 (define_insn "*cmpsf_fpe"
387 [(set (match_operand:CCFPE 0 "fcc_reg_operand" "=c")
388 (compare:CCFPE (match_operand:SF 1 "register_operand" "f")
389 (match_operand:SF 2 "register_operand" "f")))]
393 return "fcmpes\t%0, %1, %2";
394 return "fcmpes\t%1, %2";
396 [(set_attr "type" "fpcmp")])
398 (define_insn "*cmpdf_fpe"
399 [(set (match_operand:CCFPE 0 "fcc_reg_operand" "=c")
400 (compare:CCFPE (match_operand:DF 1 "register_operand" "e")
401 (match_operand:DF 2 "register_operand" "e")))]
405 return "fcmped\t%0, %1, %2";
406 return "fcmped\t%1, %2";
408 [(set_attr "type" "fpcmp")
409 (set_attr "fptype" "double")])
411 (define_insn "*cmptf_fpe"
412 [(set (match_operand:CCFPE 0 "fcc_reg_operand" "=c")
413 (compare:CCFPE (match_operand:TF 1 "register_operand" "e")
414 (match_operand:TF 2 "register_operand" "e")))]
415 "TARGET_FPU && TARGET_HARD_QUAD"
418 return "fcmpeq\t%0, %1, %2";
419 return "fcmpeq\t%1, %2";
421 [(set_attr "type" "fpcmp")])
423 (define_insn "*cmpsf_fp"
424 [(set (match_operand:CCFP 0 "fcc_reg_operand" "=c")
425 (compare:CCFP (match_operand:SF 1 "register_operand" "f")
426 (match_operand:SF 2 "register_operand" "f")))]
430 return "fcmps\t%0, %1, %2";
431 return "fcmps\t%1, %2";
433 [(set_attr "type" "fpcmp")])
435 (define_insn "*cmpdf_fp"
436 [(set (match_operand:CCFP 0 "fcc_reg_operand" "=c")
437 (compare:CCFP (match_operand:DF 1 "register_operand" "e")
438 (match_operand:DF 2 "register_operand" "e")))]
442 return "fcmpd\t%0, %1, %2";
443 return "fcmpd\t%1, %2";
445 [(set_attr "type" "fpcmp")
446 (set_attr "fptype" "double")])
448 (define_insn "*cmptf_fp"
449 [(set (match_operand:CCFP 0 "fcc_reg_operand" "=c")
450 (compare:CCFP (match_operand:TF 1 "register_operand" "e")
451 (match_operand:TF 2 "register_operand" "e")))]
452 "TARGET_FPU && TARGET_HARD_QUAD"
455 return "fcmpq\t%0, %1, %2";
456 return "fcmpq\t%1, %2";
458 [(set_attr "type" "fpcmp")])
460 ;; Next come the scc insns. For seq, sne, sgeu, and sltu, we can do this
461 ;; without jumps using the addx/subx instructions. For seq/sne on v9 we use
462 ;; the same code as v8 (the addx/subx method has more applications). The
463 ;; exception to this is "reg != 0" which can be done in one instruction on v9
464 ;; (so we do it). For the rest, on v9 we use conditional moves; on v8, we do
467 ;; Seq_special[_xxx] and sne_special[_xxx] clobber the CC reg, because they
468 ;; generate addcc/subcc instructions.
470 (define_expand "seqsi_special"
472 (xor:SI (match_operand:SI 1 "register_operand" "")
473 (match_operand:SI 2 "register_operand" "")))
474 (parallel [(set (match_operand:SI 0 "register_operand" "")
475 (eq:SI (match_dup 3) (const_int 0)))
476 (clobber (reg:CC 100))])]
478 { operands[3] = gen_reg_rtx (SImode); })
480 (define_expand "seqdi_special"
482 (xor:DI (match_operand:DI 1 "register_operand" "")
483 (match_operand:DI 2 "register_operand" "")))
484 (set (match_operand:DI 0 "register_operand" "")
485 (eq:DI (match_dup 3) (const_int 0)))]
487 { operands[3] = gen_reg_rtx (DImode); })
489 (define_expand "snesi_special"
491 (xor:SI (match_operand:SI 1 "register_operand" "")
492 (match_operand:SI 2 "register_operand" "")))
493 (parallel [(set (match_operand:SI 0 "register_operand" "")
494 (ne:SI (match_dup 3) (const_int 0)))
495 (clobber (reg:CC 100))])]
497 { operands[3] = gen_reg_rtx (SImode); })
499 (define_expand "snedi_special"
501 (xor:DI (match_operand:DI 1 "register_operand" "")
502 (match_operand:DI 2 "register_operand" "")))
503 (set (match_operand:DI 0 "register_operand" "")
504 (ne:DI (match_dup 3) (const_int 0)))]
506 { operands[3] = gen_reg_rtx (DImode); })
508 (define_expand "seqdi_special_trunc"
510 (xor:DI (match_operand:DI 1 "register_operand" "")
511 (match_operand:DI 2 "register_operand" "")))
512 (set (match_operand:SI 0 "register_operand" "")
513 (eq:SI (match_dup 3) (const_int 0)))]
515 { operands[3] = gen_reg_rtx (DImode); })
517 (define_expand "snedi_special_trunc"
519 (xor:DI (match_operand:DI 1 "register_operand" "")
520 (match_operand:DI 2 "register_operand" "")))
521 (set (match_operand:SI 0 "register_operand" "")
522 (ne:SI (match_dup 3) (const_int 0)))]
524 { operands[3] = gen_reg_rtx (DImode); })
526 (define_expand "seqsi_special_extend"
528 (xor:SI (match_operand:SI 1 "register_operand" "")
529 (match_operand:SI 2 "register_operand" "")))
530 (parallel [(set (match_operand:DI 0 "register_operand" "")
531 (eq:DI (match_dup 3) (const_int 0)))
532 (clobber (reg:CC 100))])]
534 { operands[3] = gen_reg_rtx (SImode); })
536 (define_expand "snesi_special_extend"
538 (xor:SI (match_operand:SI 1 "register_operand" "")
539 (match_operand:SI 2 "register_operand" "")))
540 (parallel [(set (match_operand:DI 0 "register_operand" "")
541 (ne:DI (match_dup 3) (const_int 0)))
542 (clobber (reg:CC 100))])]
544 { operands[3] = gen_reg_rtx (SImode); })
546 ;; ??? v9: Operand 0 needs a mode, so SImode was chosen.
547 ;; However, the code handles both SImode and DImode.
549 [(set (match_operand:SI 0 "intreg_operand" "")
550 (eq:SI (match_dup 1) (const_int 0)))]
553 if (GET_MODE (sparc_compare_op0) == SImode)
557 if (GET_MODE (operands[0]) == SImode)
558 pat = gen_seqsi_special (operands[0], sparc_compare_op0,
560 else if (! TARGET_ARCH64)
563 pat = gen_seqsi_special_extend (operands[0], sparc_compare_op0,
568 else if (GET_MODE (sparc_compare_op0) == DImode)
574 else if (GET_MODE (operands[0]) == SImode)
575 pat = gen_seqdi_special_trunc (operands[0], sparc_compare_op0,
578 pat = gen_seqdi_special (operands[0], sparc_compare_op0,
583 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
585 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, EQ);
586 emit_jump_insn (gen_sne (operands[0]));
591 if (gen_v9_scc (EQ, operands))
598 ;; ??? v9: Operand 0 needs a mode, so SImode was chosen.
599 ;; However, the code handles both SImode and DImode.
601 [(set (match_operand:SI 0 "intreg_operand" "")
602 (ne:SI (match_dup 1) (const_int 0)))]
605 if (GET_MODE (sparc_compare_op0) == SImode)
609 if (GET_MODE (operands[0]) == SImode)
610 pat = gen_snesi_special (operands[0], sparc_compare_op0,
612 else if (! TARGET_ARCH64)
615 pat = gen_snesi_special_extend (operands[0], sparc_compare_op0,
620 else if (GET_MODE (sparc_compare_op0) == DImode)
626 else if (GET_MODE (operands[0]) == SImode)
627 pat = gen_snedi_special_trunc (operands[0], sparc_compare_op0,
630 pat = gen_snedi_special (operands[0], sparc_compare_op0,
635 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
637 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, NE);
638 emit_jump_insn (gen_sne (operands[0]));
643 if (gen_v9_scc (NE, operands))
651 [(set (match_operand:SI 0 "intreg_operand" "")
652 (gt:SI (match_dup 1) (const_int 0)))]
655 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
657 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GT);
658 emit_jump_insn (gen_sne (operands[0]));
663 if (gen_v9_scc (GT, operands))
671 [(set (match_operand:SI 0 "intreg_operand" "")
672 (lt:SI (match_dup 1) (const_int 0)))]
675 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
677 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LT);
678 emit_jump_insn (gen_sne (operands[0]));
683 if (gen_v9_scc (LT, operands))
691 [(set (match_operand:SI 0 "intreg_operand" "")
692 (ge:SI (match_dup 1) (const_int 0)))]
695 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
697 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GE);
698 emit_jump_insn (gen_sne (operands[0]));
703 if (gen_v9_scc (GE, operands))
711 [(set (match_operand:SI 0 "intreg_operand" "")
712 (le:SI (match_dup 1) (const_int 0)))]
715 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
717 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LE);
718 emit_jump_insn (gen_sne (operands[0]));
723 if (gen_v9_scc (LE, operands))
730 (define_expand "sgtu"
731 [(set (match_operand:SI 0 "intreg_operand" "")
732 (gtu:SI (match_dup 1) (const_int 0)))]
739 /* We can do ltu easily, so if both operands are registers, swap them and
741 if ((GET_CODE (sparc_compare_op0) == REG
742 || GET_CODE (sparc_compare_op0) == SUBREG)
743 && (GET_CODE (sparc_compare_op1) == REG
744 || GET_CODE (sparc_compare_op1) == SUBREG))
746 tem = sparc_compare_op0;
747 sparc_compare_op0 = sparc_compare_op1;
748 sparc_compare_op1 = tem;
749 pat = gen_sltu (operands[0]);
758 if (gen_v9_scc (GTU, operands))
764 (define_expand "sltu"
765 [(set (match_operand:SI 0 "intreg_operand" "")
766 (ltu:SI (match_dup 1) (const_int 0)))]
771 if (gen_v9_scc (LTU, operands))
774 operands[1] = gen_compare_reg (LTU, sparc_compare_op0, sparc_compare_op1);
777 (define_expand "sgeu"
778 [(set (match_operand:SI 0 "intreg_operand" "")
779 (geu:SI (match_dup 1) (const_int 0)))]
784 if (gen_v9_scc (GEU, operands))
787 operands[1] = gen_compare_reg (GEU, sparc_compare_op0, sparc_compare_op1);
790 (define_expand "sleu"
791 [(set (match_operand:SI 0 "intreg_operand" "")
792 (leu:SI (match_dup 1) (const_int 0)))]
799 /* We can do geu easily, so if both operands are registers, swap them and
801 if ((GET_CODE (sparc_compare_op0) == REG
802 || GET_CODE (sparc_compare_op0) == SUBREG)
803 && (GET_CODE (sparc_compare_op1) == REG
804 || GET_CODE (sparc_compare_op1) == SUBREG))
806 tem = sparc_compare_op0;
807 sparc_compare_op0 = sparc_compare_op1;
808 sparc_compare_op1 = tem;
809 pat = gen_sgeu (operands[0]);
818 if (gen_v9_scc (LEU, operands))
824 ;; Now the DEFINE_INSNs for the scc cases.
826 ;; The SEQ and SNE patterns are special because they can be done
827 ;; without any branching and do not involve a COMPARE. We want
828 ;; them to always use the splitz below so the results can be
831 (define_insn_and_split "*snesi_zero"
832 [(set (match_operand:SI 0 "register_operand" "=r")
833 (ne:SI (match_operand:SI 1 "register_operand" "r")
835 (clobber (reg:CC 100))]
839 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
841 (set (match_dup 0) (ltu:SI (reg:CC 100) (const_int 0)))]
843 [(set_attr "length" "2")])
845 (define_insn_and_split "*neg_snesi_zero"
846 [(set (match_operand:SI 0 "register_operand" "=r")
847 (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
849 (clobber (reg:CC 100))]
853 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
855 (set (match_dup 0) (neg:SI (ltu:SI (reg:CC 100) (const_int 0))))]
857 [(set_attr "length" "2")])
859 (define_insn_and_split "*snesi_zero_extend"
860 [(set (match_operand:DI 0 "register_operand" "=r")
861 (ne:DI (match_operand:SI 1 "register_operand" "r")
863 (clobber (reg:CC 100))]
867 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (minus:SI (const_int 0)
870 (set (match_dup 0) (zero_extend:DI (plus:SI (plus:SI (const_int 0)
872 (ltu:SI (reg:CC_NOOV 100)
875 [(set_attr "length" "2")])
877 (define_insn_and_split "*snedi_zero"
878 [(set (match_operand:DI 0 "register_operand" "=&r")
879 (ne:DI (match_operand:DI 1 "register_operand" "r")
883 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
884 [(set (match_dup 0) (const_int 0))
885 (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
890 [(set_attr "length" "2")])
892 (define_insn_and_split "*neg_snedi_zero"
893 [(set (match_operand:DI 0 "register_operand" "=&r")
894 (neg:DI (ne:DI (match_operand:DI 1 "register_operand" "r")
898 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
899 [(set (match_dup 0) (const_int 0))
900 (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
905 [(set_attr "length" "2")])
907 (define_insn_and_split "*snedi_zero_trunc"
908 [(set (match_operand:SI 0 "register_operand" "=&r")
909 (ne:SI (match_operand:DI 1 "register_operand" "r")
913 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
914 [(set (match_dup 0) (const_int 0))
915 (set (match_dup 0) (if_then_else:SI (ne:DI (match_dup 1)
920 [(set_attr "length" "2")])
922 (define_insn_and_split "*seqsi_zero"
923 [(set (match_operand:SI 0 "register_operand" "=r")
924 (eq:SI (match_operand:SI 1 "register_operand" "r")
926 (clobber (reg:CC 100))]
930 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
932 (set (match_dup 0) (geu:SI (reg:CC 100) (const_int 0)))]
934 [(set_attr "length" "2")])
936 (define_insn_and_split "*neg_seqsi_zero"
937 [(set (match_operand:SI 0 "register_operand" "=r")
938 (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
940 (clobber (reg:CC 100))]
944 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
946 (set (match_dup 0) (neg:SI (geu:SI (reg:CC 100) (const_int 0))))]
948 [(set_attr "length" "2")])
950 (define_insn_and_split "*seqsi_zero_extend"
951 [(set (match_operand:DI 0 "register_operand" "=r")
952 (eq:DI (match_operand:SI 1 "register_operand" "r")
954 (clobber (reg:CC 100))]
958 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (minus:SI (const_int 0)
961 (set (match_dup 0) (zero_extend:DI (minus:SI (minus:SI (const_int 0)
963 (ltu:SI (reg:CC_NOOV 100)
966 [(set_attr "length" "2")])
968 (define_insn_and_split "*seqdi_zero"
969 [(set (match_operand:DI 0 "register_operand" "=&r")
970 (eq:DI (match_operand:DI 1 "register_operand" "r")
974 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
975 [(set (match_dup 0) (const_int 0))
976 (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
981 [(set_attr "length" "2")])
983 (define_insn_and_split "*neg_seqdi_zero"
984 [(set (match_operand:DI 0 "register_operand" "=&r")
985 (neg:DI (eq:DI (match_operand:DI 1 "register_operand" "r")
989 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
990 [(set (match_dup 0) (const_int 0))
991 (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
996 [(set_attr "length" "2")])
998 (define_insn_and_split "*seqdi_zero_trunc"
999 [(set (match_operand:SI 0 "register_operand" "=&r")
1000 (eq:SI (match_operand:DI 1 "register_operand" "r")
1004 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
1005 [(set (match_dup 0) (const_int 0))
1006 (set (match_dup 0) (if_then_else:SI (eq:DI (match_dup 1)
1011 [(set_attr "length" "2")])
1013 ;; We can also do (x + (i == 0)) and related, so put them in.
1014 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1017 (define_insn_and_split "*x_plus_i_ne_0"
1018 [(set (match_operand:SI 0 "register_operand" "=r")
1019 (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
1021 (match_operand:SI 2 "register_operand" "r")))
1022 (clobber (reg:CC 100))]
1026 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1028 (set (match_dup 0) (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1031 [(set_attr "length" "2")])
1033 (define_insn_and_split "*x_minus_i_ne_0"
1034 [(set (match_operand:SI 0 "register_operand" "=r")
1035 (minus:SI (match_operand:SI 2 "register_operand" "r")
1036 (ne:SI (match_operand:SI 1 "register_operand" "r")
1038 (clobber (reg:CC 100))]
1042 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1044 (set (match_dup 0) (minus:SI (match_dup 2)
1045 (ltu:SI (reg:CC 100) (const_int 0))))]
1047 [(set_attr "length" "2")])
1049 (define_insn_and_split "*x_plus_i_eq_0"
1050 [(set (match_operand:SI 0 "register_operand" "=r")
1051 (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
1053 (match_operand:SI 2 "register_operand" "r")))
1054 (clobber (reg:CC 100))]
1058 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1060 (set (match_dup 0) (plus:SI (geu:SI (reg:CC 100) (const_int 0))
1063 [(set_attr "length" "2")])
1065 (define_insn_and_split "*x_minus_i_eq_0"
1066 [(set (match_operand:SI 0 "register_operand" "=r")
1067 (minus:SI (match_operand:SI 2 "register_operand" "r")
1068 (eq:SI (match_operand:SI 1 "register_operand" "r")
1070 (clobber (reg:CC 100))]
1074 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1076 (set (match_dup 0) (minus:SI (match_dup 2)
1077 (geu:SI (reg:CC 100) (const_int 0))))]
1079 [(set_attr "length" "2")])
1081 ;; We can also do GEU and LTU directly, but these operate after a compare.
1082 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1085 (define_insn "*sltu_insn"
1086 [(set (match_operand:SI 0 "register_operand" "=r")
1087 (ltu:SI (reg:CC 100) (const_int 0)))]
1090 [(set_attr "type" "ialuX")])
1092 (define_insn "*neg_sltu_insn"
1093 [(set (match_operand:SI 0 "register_operand" "=r")
1094 (neg:SI (ltu:SI (reg:CC 100) (const_int 0))))]
1097 [(set_attr "type" "ialuX")])
1099 ;; ??? Combine should canonicalize these next two to the same pattern.
1100 (define_insn "*neg_sltu_minus_x"
1101 [(set (match_operand:SI 0 "register_operand" "=r")
1102 (minus:SI (neg:SI (ltu:SI (reg:CC 100) (const_int 0)))
1103 (match_operand:SI 1 "arith_operand" "rI")))]
1105 "subx\t%%g0, %1, %0"
1106 [(set_attr "type" "ialuX")])
1108 (define_insn "*neg_sltu_plus_x"
1109 [(set (match_operand:SI 0 "register_operand" "=r")
1110 (neg:SI (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1111 (match_operand:SI 1 "arith_operand" "rI"))))]
1113 "subx\t%%g0, %1, %0"
1114 [(set_attr "type" "ialuX")])
1116 (define_insn "*sgeu_insn"
1117 [(set (match_operand:SI 0 "register_operand" "=r")
1118 (geu:SI (reg:CC 100) (const_int 0)))]
1120 "subx\t%%g0, -1, %0"
1121 [(set_attr "type" "ialuX")])
1123 (define_insn "*neg_sgeu_insn"
1124 [(set (match_operand:SI 0 "register_operand" "=r")
1125 (neg:SI (geu:SI (reg:CC 100) (const_int 0))))]
1127 "addx\t%%g0, -1, %0"
1128 [(set_attr "type" "ialuX")])
1130 ;; We can also do (x + ((unsigned) i >= 0)) and related, so put them in.
1131 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1134 (define_insn "*sltu_plus_x"
1135 [(set (match_operand:SI 0 "register_operand" "=r")
1136 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1137 (match_operand:SI 1 "arith_operand" "rI")))]
1139 "addx\t%%g0, %1, %0"
1140 [(set_attr "type" "ialuX")])
1142 (define_insn "*sltu_plus_x_plus_y"
1143 [(set (match_operand:SI 0 "register_operand" "=r")
1144 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1145 (plus:SI (match_operand:SI 1 "arith_operand" "%r")
1146 (match_operand:SI 2 "arith_operand" "rI"))))]
1149 [(set_attr "type" "ialuX")])
1151 (define_insn "*x_minus_sltu"
1152 [(set (match_operand:SI 0 "register_operand" "=r")
1153 (minus:SI (match_operand:SI 1 "register_operand" "r")
1154 (ltu:SI (reg:CC 100) (const_int 0))))]
1157 [(set_attr "type" "ialuX")])
1159 ;; ??? Combine should canonicalize these next two to the same pattern.
1160 (define_insn "*x_minus_y_minus_sltu"
1161 [(set (match_operand:SI 0 "register_operand" "=r")
1162 (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
1163 (match_operand:SI 2 "arith_operand" "rI"))
1164 (ltu:SI (reg:CC 100) (const_int 0))))]
1167 [(set_attr "type" "ialuX")])
1169 (define_insn "*x_minus_sltu_plus_y"
1170 [(set (match_operand:SI 0 "register_operand" "=r")
1171 (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
1172 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1173 (match_operand:SI 2 "arith_operand" "rI"))))]
1176 [(set_attr "type" "ialuX")])
1178 (define_insn "*sgeu_plus_x"
1179 [(set (match_operand:SI 0 "register_operand" "=r")
1180 (plus:SI (geu:SI (reg:CC 100) (const_int 0))
1181 (match_operand:SI 1 "register_operand" "r")))]
1184 [(set_attr "type" "ialuX")])
1186 (define_insn "*x_minus_sgeu"
1187 [(set (match_operand:SI 0 "register_operand" "=r")
1188 (minus:SI (match_operand:SI 1 "register_operand" "r")
1189 (geu:SI (reg:CC 100) (const_int 0))))]
1192 [(set_attr "type" "ialuX")])
1195 [(set (match_operand:SI 0 "register_operand" "")
1196 (match_operator:SI 2 "noov_compare_op"
1197 [(match_operand 1 "icc_or_fcc_reg_operand" "")
1199 ;; 32 bit LTU/GEU are better implemented using addx/subx
1200 "TARGET_V9 && REGNO (operands[1]) == SPARC_ICC_REG
1201 && (GET_MODE (operands[1]) == CCXmode
1202 || (GET_CODE (operands[2]) != LTU && GET_CODE (operands[2]) != GEU))"
1203 [(set (match_dup 0) (const_int 0))
1205 (if_then_else:SI (match_op_dup:SI 2 [(match_dup 1) (const_int 0)])
1211 ;; These control RTL generation for conditional jump insns
1213 ;; The quad-word fp compare library routines all return nonzero to indicate
1214 ;; true, which is different from the equivalent libgcc routines, so we must
1215 ;; handle them specially here.
1217 (define_expand "beq"
1219 (if_then_else (eq (match_dup 1) (const_int 0))
1220 (label_ref (match_operand 0 "" ""))
1224 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1225 && GET_CODE (sparc_compare_op0) == REG
1226 && GET_MODE (sparc_compare_op0) == DImode)
1228 emit_v9_brxx_insn (EQ, sparc_compare_op0, operands[0]);
1231 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1233 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, EQ);
1234 emit_jump_insn (gen_bne (operands[0]));
1237 operands[1] = gen_compare_reg (EQ, sparc_compare_op0, sparc_compare_op1);
1240 (define_expand "bne"
1242 (if_then_else (ne (match_dup 1) (const_int 0))
1243 (label_ref (match_operand 0 "" ""))
1247 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1248 && GET_CODE (sparc_compare_op0) == REG
1249 && GET_MODE (sparc_compare_op0) == DImode)
1251 emit_v9_brxx_insn (NE, sparc_compare_op0, operands[0]);
1254 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1256 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, NE);
1257 emit_jump_insn (gen_bne (operands[0]));
1260 operands[1] = gen_compare_reg (NE, sparc_compare_op0, sparc_compare_op1);
1263 (define_expand "bgt"
1265 (if_then_else (gt (match_dup 1) (const_int 0))
1266 (label_ref (match_operand 0 "" ""))
1270 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1271 && GET_CODE (sparc_compare_op0) == REG
1272 && GET_MODE (sparc_compare_op0) == DImode)
1274 emit_v9_brxx_insn (GT, sparc_compare_op0, operands[0]);
1277 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1279 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GT);
1280 emit_jump_insn (gen_bne (operands[0]));
1283 operands[1] = gen_compare_reg (GT, sparc_compare_op0, sparc_compare_op1);
1286 (define_expand "bgtu"
1288 (if_then_else (gtu (match_dup 1) (const_int 0))
1289 (label_ref (match_operand 0 "" ""))
1293 operands[1] = gen_compare_reg (GTU, sparc_compare_op0, sparc_compare_op1);
1296 (define_expand "blt"
1298 (if_then_else (lt (match_dup 1) (const_int 0))
1299 (label_ref (match_operand 0 "" ""))
1303 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1304 && GET_CODE (sparc_compare_op0) == REG
1305 && GET_MODE (sparc_compare_op0) == DImode)
1307 emit_v9_brxx_insn (LT, sparc_compare_op0, operands[0]);
1310 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1312 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LT);
1313 emit_jump_insn (gen_bne (operands[0]));
1316 operands[1] = gen_compare_reg (LT, sparc_compare_op0, sparc_compare_op1);
1319 (define_expand "bltu"
1321 (if_then_else (ltu (match_dup 1) (const_int 0))
1322 (label_ref (match_operand 0 "" ""))
1326 operands[1] = gen_compare_reg (LTU, sparc_compare_op0, sparc_compare_op1);
1329 (define_expand "bge"
1331 (if_then_else (ge (match_dup 1) (const_int 0))
1332 (label_ref (match_operand 0 "" ""))
1336 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1337 && GET_CODE (sparc_compare_op0) == REG
1338 && GET_MODE (sparc_compare_op0) == DImode)
1340 emit_v9_brxx_insn (GE, sparc_compare_op0, operands[0]);
1343 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1345 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GE);
1346 emit_jump_insn (gen_bne (operands[0]));
1349 operands[1] = gen_compare_reg (GE, sparc_compare_op0, sparc_compare_op1);
1352 (define_expand "bgeu"
1354 (if_then_else (geu (match_dup 1) (const_int 0))
1355 (label_ref (match_operand 0 "" ""))
1359 operands[1] = gen_compare_reg (GEU, sparc_compare_op0, sparc_compare_op1);
1362 (define_expand "ble"
1364 (if_then_else (le (match_dup 1) (const_int 0))
1365 (label_ref (match_operand 0 "" ""))
1369 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1370 && GET_CODE (sparc_compare_op0) == REG
1371 && GET_MODE (sparc_compare_op0) == DImode)
1373 emit_v9_brxx_insn (LE, sparc_compare_op0, operands[0]);
1376 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1378 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LE);
1379 emit_jump_insn (gen_bne (operands[0]));
1382 operands[1] = gen_compare_reg (LE, sparc_compare_op0, sparc_compare_op1);
1385 (define_expand "bleu"
1387 (if_then_else (leu (match_dup 1) (const_int 0))
1388 (label_ref (match_operand 0 "" ""))
1392 operands[1] = gen_compare_reg (LEU, sparc_compare_op0, sparc_compare_op1);
1395 (define_expand "bunordered"
1397 (if_then_else (unordered (match_dup 1) (const_int 0))
1398 (label_ref (match_operand 0 "" ""))
1402 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1404 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1,
1406 emit_jump_insn (gen_beq (operands[0]));
1409 operands[1] = gen_compare_reg (UNORDERED, sparc_compare_op0,
1413 (define_expand "bordered"
1415 (if_then_else (ordered (match_dup 1) (const_int 0))
1416 (label_ref (match_operand 0 "" ""))
1420 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1422 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, ORDERED);
1423 emit_jump_insn (gen_bne (operands[0]));
1426 operands[1] = gen_compare_reg (ORDERED, sparc_compare_op0,
1430 (define_expand "bungt"
1432 (if_then_else (ungt (match_dup 1) (const_int 0))
1433 (label_ref (match_operand 0 "" ""))
1437 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1439 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNGT);
1440 emit_jump_insn (gen_bgt (operands[0]));
1443 operands[1] = gen_compare_reg (UNGT, sparc_compare_op0, sparc_compare_op1);
1446 (define_expand "bunlt"
1448 (if_then_else (unlt (match_dup 1) (const_int 0))
1449 (label_ref (match_operand 0 "" ""))
1453 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1455 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNLT);
1456 emit_jump_insn (gen_bne (operands[0]));
1459 operands[1] = gen_compare_reg (UNLT, sparc_compare_op0, sparc_compare_op1);
1462 (define_expand "buneq"
1464 (if_then_else (uneq (match_dup 1) (const_int 0))
1465 (label_ref (match_operand 0 "" ""))
1469 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1471 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNEQ);
1472 emit_jump_insn (gen_beq (operands[0]));
1475 operands[1] = gen_compare_reg (UNEQ, sparc_compare_op0, sparc_compare_op1);
1478 (define_expand "bunge"
1480 (if_then_else (unge (match_dup 1) (const_int 0))
1481 (label_ref (match_operand 0 "" ""))
1485 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1487 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNGE);
1488 emit_jump_insn (gen_bne (operands[0]));
1491 operands[1] = gen_compare_reg (UNGE, sparc_compare_op0, sparc_compare_op1);
1494 (define_expand "bunle"
1496 (if_then_else (unle (match_dup 1) (const_int 0))
1497 (label_ref (match_operand 0 "" ""))
1501 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1503 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNLE);
1504 emit_jump_insn (gen_bne (operands[0]));
1507 operands[1] = gen_compare_reg (UNLE, sparc_compare_op0, sparc_compare_op1);
1510 (define_expand "bltgt"
1512 (if_then_else (ltgt (match_dup 1) (const_int 0))
1513 (label_ref (match_operand 0 "" ""))
1517 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1519 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LTGT);
1520 emit_jump_insn (gen_bne (operands[0]));
1523 operands[1] = gen_compare_reg (LTGT, sparc_compare_op0, sparc_compare_op1);
1526 ;; Now match both normal and inverted jump.
1528 ;; XXX fpcmp nop braindamage
1529 (define_insn "*normal_branch"
1531 (if_then_else (match_operator 0 "noov_compare_op"
1532 [(reg 100) (const_int 0)])
1533 (label_ref (match_operand 1 "" ""))
1537 return output_cbranch (operands[0], operands[1], 1, 0,
1538 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1539 ! final_sequence, insn);
1541 [(set_attr "type" "branch")
1542 (set_attr "branch_type" "icc")])
1544 ;; XXX fpcmp nop braindamage
1545 (define_insn "*inverted_branch"
1547 (if_then_else (match_operator 0 "noov_compare_op"
1548 [(reg 100) (const_int 0)])
1550 (label_ref (match_operand 1 "" ""))))]
1553 return output_cbranch (operands[0], operands[1], 1, 1,
1554 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1555 ! final_sequence, insn);
1557 [(set_attr "type" "branch")
1558 (set_attr "branch_type" "icc")])
1560 ;; XXX fpcmp nop braindamage
1561 (define_insn "*normal_fp_branch"
1563 (if_then_else (match_operator 1 "comparison_operator"
1564 [(match_operand:CCFP 0 "fcc_reg_operand" "c")
1566 (label_ref (match_operand 2 "" ""))
1570 return output_cbranch (operands[1], operands[2], 2, 0,
1571 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1572 ! final_sequence, insn);
1574 [(set_attr "type" "branch")
1575 (set_attr "branch_type" "fcc")])
1577 ;; XXX fpcmp nop braindamage
1578 (define_insn "*inverted_fp_branch"
1580 (if_then_else (match_operator 1 "comparison_operator"
1581 [(match_operand:CCFP 0 "fcc_reg_operand" "c")
1584 (label_ref (match_operand 2 "" ""))))]
1587 return output_cbranch (operands[1], operands[2], 2, 1,
1588 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1589 ! final_sequence, insn);
1591 [(set_attr "type" "branch")
1592 (set_attr "branch_type" "fcc")])
1594 ;; XXX fpcmp nop braindamage
1595 (define_insn "*normal_fpe_branch"
1597 (if_then_else (match_operator 1 "comparison_operator"
1598 [(match_operand:CCFPE 0 "fcc_reg_operand" "c")
1600 (label_ref (match_operand 2 "" ""))
1604 return output_cbranch (operands[1], operands[2], 2, 0,
1605 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1606 ! final_sequence, insn);
1608 [(set_attr "type" "branch")
1609 (set_attr "branch_type" "fcc")])
1611 ;; XXX fpcmp nop braindamage
1612 (define_insn "*inverted_fpe_branch"
1614 (if_then_else (match_operator 1 "comparison_operator"
1615 [(match_operand:CCFPE 0 "fcc_reg_operand" "c")
1618 (label_ref (match_operand 2 "" ""))))]
1621 return output_cbranch (operands[1], operands[2], 2, 1,
1622 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1623 ! final_sequence, insn);
1625 [(set_attr "type" "branch")
1626 (set_attr "branch_type" "fcc")])
1628 ;; SPARC V9-specific jump insns. None of these are guaranteed to be
1629 ;; in the architecture.
1631 ;; There are no 32 bit brreg insns.
1634 (define_insn "*normal_int_branch_sp64"
1636 (if_then_else (match_operator 0 "v9_regcmp_op"
1637 [(match_operand:DI 1 "register_operand" "r")
1639 (label_ref (match_operand 2 "" ""))
1643 return output_v9branch (operands[0], operands[2], 1, 2, 0,
1644 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1645 ! final_sequence, insn);
1647 [(set_attr "type" "branch")
1648 (set_attr "branch_type" "reg")])
1651 (define_insn "*inverted_int_branch_sp64"
1653 (if_then_else (match_operator 0 "v9_regcmp_op"
1654 [(match_operand:DI 1 "register_operand" "r")
1657 (label_ref (match_operand 2 "" ""))))]
1660 return output_v9branch (operands[0], operands[2], 1, 2, 1,
1661 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1662 ! final_sequence, insn);
1664 [(set_attr "type" "branch")
1665 (set_attr "branch_type" "reg")])
1667 ;; Load program counter insns.
1669 (define_insn "get_pc"
1670 [(clobber (reg:SI 15))
1671 (set (match_operand 0 "register_operand" "=r")
1672 (unspec [(match_operand 1 "" "") (match_operand 2 "" "")] UNSPEC_GET_PC))]
1673 "flag_pic && REGNO (operands[0]) == 23"
1674 "sethi\t%%hi(%a1-4), %0\n\tcall\t%a2\n\tadd\t%0, %%lo(%a1+4), %0"
1675 [(set_attr "type" "multi")
1676 (set_attr "length" "3")])
1679 ;; Move instructions
1681 (define_expand "movqi"
1682 [(set (match_operand:QI 0 "general_operand" "")
1683 (match_operand:QI 1 "general_operand" ""))]
1686 /* Working with CONST_INTs is easier, so convert
1687 a double if needed. */
1688 if (GET_CODE (operands[1]) == CONST_DOUBLE)
1690 operands[1] = GEN_INT (trunc_int_for_mode
1691 (CONST_DOUBLE_LOW (operands[1]), QImode));
1694 /* Handle sets of MEM first. */
1695 if (GET_CODE (operands[0]) == MEM)
1697 if (reg_or_0_operand (operands[1], QImode))
1700 if (! reload_in_progress)
1702 operands[0] = validize_mem (operands[0]);
1703 operands[1] = force_reg (QImode, operands[1]);
1707 /* Fixup TLS cases. */
1708 if (tls_symbolic_operand (operands [1]))
1709 operands[1] = legitimize_tls_address (operands[1]);
1711 /* Fixup PIC cases. */
1714 if (CONSTANT_P (operands[1])
1715 && pic_address_needs_scratch (operands[1]))
1716 operands[1] = legitimize_pic_address (operands[1], QImode, 0);
1718 if (symbolic_operand (operands[1], QImode))
1720 operands[1] = legitimize_pic_address (operands[1],
1722 (reload_in_progress ?
1729 /* All QI constants require only one insn, so proceed. */
1735 (define_insn "*movqi_insn"
1736 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m")
1737 (match_operand:QI 1 "input_operand" "rI,m,rJ"))]
1738 "(register_operand (operands[0], QImode)
1739 || reg_or_0_operand (operands[1], QImode))"
1744 [(set_attr "type" "*,load,store")
1745 (set_attr "us3load_type" "*,3cycle,*")])
1747 (define_expand "movhi"
1748 [(set (match_operand:HI 0 "general_operand" "")
1749 (match_operand:HI 1 "general_operand" ""))]
1752 /* Working with CONST_INTs is easier, so convert
1753 a double if needed. */
1754 if (GET_CODE (operands[1]) == CONST_DOUBLE)
1755 operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
1757 /* Handle sets of MEM first. */
1758 if (GET_CODE (operands[0]) == MEM)
1760 if (reg_or_0_operand (operands[1], HImode))
1763 if (! reload_in_progress)
1765 operands[0] = validize_mem (operands[0]);
1766 operands[1] = force_reg (HImode, operands[1]);
1770 /* Fixup TLS cases. */
1771 if (tls_symbolic_operand (operands [1]))
1772 operands[1] = legitimize_tls_address (operands[1]);
1774 /* Fixup PIC cases. */
1777 if (CONSTANT_P (operands[1])
1778 && pic_address_needs_scratch (operands[1]))
1779 operands[1] = legitimize_pic_address (operands[1], HImode, 0);
1781 if (symbolic_operand (operands[1], HImode))
1783 operands[1] = legitimize_pic_address (operands[1],
1785 (reload_in_progress ?
1792 /* This makes sure we will not get rematched due to splittage. */
1793 if (! CONSTANT_P (operands[1]) || input_operand (operands[1], HImode))
1795 else if (CONSTANT_P (operands[1])
1796 && GET_CODE (operands[1]) != HIGH
1797 && GET_CODE (operands[1]) != LO_SUM)
1799 sparc_emit_set_const32 (operands[0], operands[1]);
1806 (define_insn "*movhi_const64_special"
1807 [(set (match_operand:HI 0 "register_operand" "=r")
1808 (match_operand:HI 1 "const64_high_operand" ""))]
1810 "sethi\t%%hi(%a1), %0")
1812 (define_insn "*movhi_insn"
1813 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1814 (match_operand:HI 1 "input_operand" "rI,K,m,rJ"))]
1815 "(register_operand (operands[0], HImode)
1816 || reg_or_0_operand (operands[1], HImode))"
1819 sethi\t%%hi(%a1), %0
1822 [(set_attr "type" "*,*,load,store")
1823 (set_attr "us3load_type" "*,*,3cycle,*")])
1825 ;; We always work with constants here.
1826 (define_insn "*movhi_lo_sum"
1827 [(set (match_operand:HI 0 "register_operand" "=r")
1828 (ior:HI (match_operand:HI 1 "register_operand" "%r")
1829 (match_operand:HI 2 "small_int" "I")))]
1833 (define_expand "movsi"
1834 [(set (match_operand:SI 0 "general_operand" "")
1835 (match_operand:SI 1 "general_operand" ""))]
1838 /* Working with CONST_INTs is easier, so convert
1839 a double if needed. */
1840 if (GET_CODE (operands[1]) == CONST_DOUBLE)
1841 operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
1843 /* Handle sets of MEM first. */
1844 if (GET_CODE (operands[0]) == MEM)
1846 if (reg_or_0_operand (operands[1], SImode))
1849 if (! reload_in_progress)
1851 operands[0] = validize_mem (operands[0]);
1852 operands[1] = force_reg (SImode, operands[1]);
1856 /* Fixup TLS cases. */
1857 if (tls_symbolic_operand (operands [1]))
1858 operands[1] = legitimize_tls_address (operands[1]);
1860 /* Fixup PIC cases. */
1863 if (CONSTANT_P (operands[1])
1864 && pic_address_needs_scratch (operands[1]))
1865 operands[1] = legitimize_pic_address (operands[1], SImode, 0);
1867 if (GET_CODE (operands[1]) == LABEL_REF)
1870 emit_insn (gen_movsi_pic_label_ref (operands[0], operands[1]));
1874 if (symbolic_operand (operands[1], SImode))
1876 operands[1] = legitimize_pic_address (operands[1],
1878 (reload_in_progress ?
1885 /* If we are trying to toss an integer constant into the
1886 FPU registers, force it into memory. */
1887 if (GET_CODE (operands[0]) == REG
1888 && REGNO (operands[0]) >= SPARC_FIRST_FP_REG
1889 && REGNO (operands[0]) <= SPARC_LAST_V9_FP_REG
1890 && CONSTANT_P (operands[1]))
1891 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
1894 /* This makes sure we will not get rematched due to splittage. */
1895 if (! CONSTANT_P (operands[1]) || input_operand (operands[1], SImode))
1897 else if (CONSTANT_P (operands[1])
1898 && GET_CODE (operands[1]) != HIGH
1899 && GET_CODE (operands[1]) != LO_SUM)
1901 sparc_emit_set_const32 (operands[0], operands[1]);
1908 ;; This is needed to show CSE exactly which bits are set
1909 ;; in a 64-bit register by sethi instructions.
1910 (define_insn "*movsi_const64_special"
1911 [(set (match_operand:SI 0 "register_operand" "=r")
1912 (match_operand:SI 1 "const64_high_operand" ""))]
1914 "sethi\t%%hi(%a1), %0")
1916 (define_insn "*movsi_insn"
1917 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,f,r,r,r,f,m,m,d")
1918 (match_operand:SI 1 "input_operand" "rI,!f,K,J,m,!m,rJ,!f,J"))]
1919 "(register_operand (operands[0], SImode)
1920 || reg_or_0_operand (operands[1], SImode))"
1924 sethi\t%%hi(%a1), %0
1931 [(set_attr "type" "*,fpmove,*,*,load,fpload,store,fpstore,fga")])
1933 (define_insn "*movsi_lo_sum"
1934 [(set (match_operand:SI 0 "register_operand" "=r")
1935 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1936 (match_operand:SI 2 "immediate_operand" "in")))]
1938 "or\t%1, %%lo(%a2), %0")
1940 (define_insn "*movsi_high"
1941 [(set (match_operand:SI 0 "register_operand" "=r")
1942 (high:SI (match_operand:SI 1 "immediate_operand" "in")))]
1944 "sethi\t%%hi(%a1), %0")
1946 ;; The next two patterns must wrap the SYMBOL_REF in an UNSPEC
1947 ;; so that CSE won't optimize the address computation away.
1948 (define_insn "movsi_lo_sum_pic"
1949 [(set (match_operand:SI 0 "register_operand" "=r")
1950 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1951 (unspec:SI [(match_operand:SI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
1953 "or\t%1, %%lo(%a2), %0")
1955 (define_insn "movsi_high_pic"
1956 [(set (match_operand:SI 0 "register_operand" "=r")
1957 (high:SI (unspec:SI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
1958 "flag_pic && check_pic (1)"
1959 "sethi\t%%hi(%a1), %0")
1961 (define_expand "movsi_pic_label_ref"
1962 [(set (match_dup 3) (high:SI
1963 (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
1964 (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1965 (set (match_dup 4) (lo_sum:SI (match_dup 3)
1966 (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1967 (set (match_operand:SI 0 "register_operand" "=r")
1968 (minus:SI (match_dup 5) (match_dup 4)))]
1971 current_function_uses_pic_offset_table = 1;
1972 operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
1975 operands[3] = operands[0];
1976 operands[4] = operands[0];
1980 operands[3] = gen_reg_rtx (SImode);
1981 operands[4] = gen_reg_rtx (SImode);
1983 operands[5] = pic_offset_table_rtx;
1986 (define_insn "*movsi_high_pic_label_ref"
1987 [(set (match_operand:SI 0 "register_operand" "=r")
1989 (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
1990 (match_operand:SI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1992 "sethi\t%%hi(%a2-(%a1-.)), %0")
1994 (define_insn "*movsi_lo_sum_pic_label_ref"
1995 [(set (match_operand:SI 0 "register_operand" "=r")
1996 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1997 (unspec:SI [(match_operand:SI 2 "label_ref_operand" "")
1998 (match_operand:SI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
2000 "or\t%1, %%lo(%a3-(%a2-.)), %0")
2002 (define_expand "movdi"
2003 [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand" "")
2004 (match_operand:DI 1 "general_operand" ""))]
2007 /* Where possible, convert CONST_DOUBLE into a CONST_INT. */
2008 if (GET_CODE (operands[1]) == CONST_DOUBLE
2009 #if HOST_BITS_PER_WIDE_INT == 32
2010 && ((CONST_DOUBLE_HIGH (operands[1]) == 0
2011 && (CONST_DOUBLE_LOW (operands[1]) & 0x80000000) == 0)
2012 || (CONST_DOUBLE_HIGH (operands[1]) == (HOST_WIDE_INT) 0xffffffff
2013 && (CONST_DOUBLE_LOW (operands[1]) & 0x80000000) != 0))
2016 operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
2018 /* Handle MEM cases first. */
2019 if (GET_CODE (operands[0]) == MEM)
2021 /* If it's a REG, we can always do it.
2022 The const zero case is more complex, on v9
2023 we can always perform it. */
2024 if (register_operand (operands[1], DImode)
2026 && (operands[1] == const0_rtx)))
2029 if (! reload_in_progress)
2031 operands[0] = validize_mem (operands[0]);
2032 operands[1] = force_reg (DImode, operands[1]);
2036 /* Fixup TLS cases. */
2037 if (tls_symbolic_operand (operands [1]))
2038 operands[1] = legitimize_tls_address (operands[1]);
2042 if (CONSTANT_P (operands[1])
2043 && pic_address_needs_scratch (operands[1]))
2044 operands[1] = legitimize_pic_address (operands[1], DImode, 0);
2046 if (GET_CODE (operands[1]) == LABEL_REF)
2048 if (! TARGET_ARCH64)
2050 emit_insn (gen_movdi_pic_label_ref (operands[0], operands[1]));
2054 if (symbolic_operand (operands[1], DImode))
2056 operands[1] = legitimize_pic_address (operands[1],
2058 (reload_in_progress ?
2065 /* If we are trying to toss an integer constant into the
2066 FPU registers, force it into memory. */
2067 if (GET_CODE (operands[0]) == REG
2068 && REGNO (operands[0]) >= SPARC_FIRST_FP_REG
2069 && REGNO (operands[0]) <= SPARC_LAST_V9_FP_REG
2070 && CONSTANT_P (operands[1]))
2071 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
2074 /* This makes sure we will not get rematched due to splittage. */
2075 if (! CONSTANT_P (operands[1]) || input_operand (operands[1], DImode))
2077 else if (TARGET_ARCH64
2078 && CONSTANT_P (operands[1])
2079 && GET_CODE (operands[1]) != HIGH
2080 && GET_CODE (operands[1]) != LO_SUM)
2082 sparc_emit_set_const64 (operands[0], operands[1]);
2090 ;; Be careful, fmovd does not exist when !v9.
2091 ;; We match MEM moves directly when we have correct even
2092 ;; numbered registers, but fall into splits otherwise.
2093 ;; The constraint ordering here is really important to
2094 ;; avoid insane problems in reload, especially for patterns
2097 ;; (set (mem:DI (plus:SI (reg:SI 30 %fp)
2098 ;; (const_int -5016)))
2102 (define_insn "*movdi_insn_sp32_v9"
2103 [(set (match_operand:DI 0 "nonimmediate_operand"
2104 "=T,o,T,U,o,r,r,r,?T,?f,?f,?o,?e,?e,?W")
2105 (match_operand:DI 1 "input_operand"
2106 " J,J,U,T,r,o,i,r, f, T, o, f, e, W, e"))]
2107 "! TARGET_ARCH64 && TARGET_V9
2108 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2125 [(set_attr "type" "store,store,store,load,*,*,*,*,fpstore,fpload,*,*,fpmove,fpload,fpstore")
2126 (set_attr "length" "*,2,*,*,2,2,2,2,*,*,2,2,*,*,*")
2127 (set_attr "fptype" "*,*,*,*,*,*,*,*,*,*,*,*,double,*,*")])
2129 (define_insn "*movdi_insn_sp32"
2130 [(set (match_operand:DI 0 "nonimmediate_operand"
2131 "=o,T,U,o,r,r,r,?T,?f,?f,?o,?f")
2132 (match_operand:DI 1 "input_operand"
2133 " J,U,T,r,o,i,r, f, T, o, f, f"))]
2135 && (register_operand (operands[0], DImode)
2136 || register_operand (operands[1], DImode))"
2150 [(set_attr "type" "store,store,load,*,*,*,*,fpstore,fpload,*,*,*")
2151 (set_attr "length" "2,*,*,2,2,2,2,*,*,2,2,2")])
2153 ;; The following are generated by sparc_emit_set_const64
2154 (define_insn "*movdi_sp64_dbl"
2155 [(set (match_operand:DI 0 "register_operand" "=r")
2156 (match_operand:DI 1 "const64_operand" ""))]
2158 && HOST_BITS_PER_WIDE_INT != 64)"
2161 ;; This is needed to show CSE exactly which bits are set
2162 ;; in a 64-bit register by sethi instructions.
2163 (define_insn "*movdi_const64_special"
2164 [(set (match_operand:DI 0 "register_operand" "=r")
2165 (match_operand:DI 1 "const64_high_operand" ""))]
2167 "sethi\t%%hi(%a1), %0")
2169 (define_insn "*movdi_insn_sp64_novis"
2170 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,m,?e,?e,?W")
2171 (match_operand:DI 1 "input_operand" "rI,N,J,m,rJ,e,W,e"))]
2172 "TARGET_ARCH64 && ! TARGET_VIS
2173 && (register_operand (operands[0], DImode)
2174 || reg_or_0_operand (operands[1], DImode))"
2177 sethi\t%%hi(%a1), %0
2184 [(set_attr "type" "*,*,*,load,store,fpmove,fpload,fpstore")
2185 (set_attr "fptype" "*,*,*,*,*,double,*,*")])
2187 (define_insn "*movdi_insn_sp64_vis"
2188 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,m,?e,?e,?W,b")
2189 (match_operand:DI 1 "input_operand" "rI,N,J,m,rJ,e,W,e,J"))]
2190 "TARGET_ARCH64 && TARGET_VIS &&
2191 (register_operand (operands[0], DImode)
2192 || reg_or_0_operand (operands[1], DImode))"
2195 sethi\t%%hi(%a1), %0
2203 [(set_attr "type" "*,*,*,load,store,fpmove,fpload,fpstore,fga")
2204 (set_attr "fptype" "*,*,*,*,*,double,*,*,double")])
2206 (define_expand "movdi_pic_label_ref"
2207 [(set (match_dup 3) (high:DI
2208 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
2209 (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
2210 (set (match_dup 4) (lo_sum:DI (match_dup 3)
2211 (unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
2212 (set (match_operand:DI 0 "register_operand" "=r")
2213 (minus:DI (match_dup 5) (match_dup 4)))]
2214 "TARGET_ARCH64 && flag_pic"
2216 current_function_uses_pic_offset_table = 1;
2217 operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
2220 operands[3] = operands[0];
2221 operands[4] = operands[0];
2225 operands[3] = gen_reg_rtx (DImode);
2226 operands[4] = gen_reg_rtx (DImode);
2228 operands[5] = pic_offset_table_rtx;
2231 (define_insn "*movdi_high_pic_label_ref"
2232 [(set (match_operand:DI 0 "register_operand" "=r")
2234 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
2235 (match_operand:DI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
2236 "TARGET_ARCH64 && flag_pic"
2237 "sethi\t%%hi(%a2-(%a1-.)), %0")
2239 (define_insn "*movdi_lo_sum_pic_label_ref"
2240 [(set (match_operand:DI 0 "register_operand" "=r")
2241 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2242 (unspec:DI [(match_operand:DI 2 "label_ref_operand" "")
2243 (match_operand:DI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
2244 "TARGET_ARCH64 && flag_pic"
2245 "or\t%1, %%lo(%a3-(%a2-.)), %0")
2247 ;; SPARC-v9 code model support insns. See sparc_emit_set_symbolic_const64
2248 ;; in sparc.c to see what is going on here... PIC stuff comes first.
2250 (define_insn "movdi_lo_sum_pic"
2251 [(set (match_operand:DI 0 "register_operand" "=r")
2252 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2253 (unspec:DI [(match_operand:DI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
2254 "TARGET_ARCH64 && flag_pic"
2255 "or\t%1, %%lo(%a2), %0")
2257 (define_insn "movdi_high_pic"
2258 [(set (match_operand:DI 0 "register_operand" "=r")
2259 (high:DI (unspec:DI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
2260 "TARGET_ARCH64 && flag_pic && check_pic (1)"
2261 "sethi\t%%hi(%a1), %0")
2263 (define_insn "*sethi_di_medlow_embmedany_pic"
2264 [(set (match_operand:DI 0 "register_operand" "=r")
2265 (high:DI (match_operand:DI 1 "sp64_medium_pic_operand" "")))]
2266 "(TARGET_CM_MEDLOW || TARGET_CM_EMBMEDANY) && check_pic (1)"
2267 "sethi\t%%hi(%a1), %0")
2269 (define_insn "*sethi_di_medlow"
2270 [(set (match_operand:DI 0 "register_operand" "=r")
2271 (high:DI (match_operand:DI 1 "symbolic_operand" "")))]
2272 "TARGET_CM_MEDLOW && check_pic (1)"
2273 "sethi\t%%hi(%a1), %0")
2275 (define_insn "*losum_di_medlow"
2276 [(set (match_operand:DI 0 "register_operand" "=r")
2277 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2278 (match_operand:DI 2 "symbolic_operand" "")))]
2280 "or\t%1, %%lo(%a2), %0")
2282 (define_insn "seth44"
2283 [(set (match_operand:DI 0 "register_operand" "=r")
2284 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETH44)))]
2286 "sethi\t%%h44(%a1), %0")
2288 (define_insn "setm44"
2289 [(set (match_operand:DI 0 "register_operand" "=r")
2290 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2291 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_SETM44)))]
2293 "or\t%1, %%m44(%a2), %0")
2295 (define_insn "setl44"
2296 [(set (match_operand:DI 0 "register_operand" "=r")
2297 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2298 (match_operand:DI 2 "symbolic_operand" "")))]
2300 "or\t%1, %%l44(%a2), %0")
2302 (define_insn "sethh"
2303 [(set (match_operand:DI 0 "register_operand" "=r")
2304 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETHH)))]
2306 "sethi\t%%hh(%a1), %0")
2308 (define_insn "setlm"
2309 [(set (match_operand:DI 0 "register_operand" "=r")
2310 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETLM)))]
2312 "sethi\t%%lm(%a1), %0")
2314 (define_insn "sethm"
2315 [(set (match_operand:DI 0 "register_operand" "=r")
2316 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2317 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_EMB_SETHM)))]
2319 "or\t%1, %%hm(%a2), %0")
2321 (define_insn "setlo"
2322 [(set (match_operand:DI 0 "register_operand" "=r")
2323 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2324 (match_operand:DI 2 "symbolic_operand" "")))]
2326 "or\t%1, %%lo(%a2), %0")
2328 (define_insn "embmedany_sethi"
2329 [(set (match_operand:DI 0 "register_operand" "=r")
2330 (high:DI (unspec:DI [(match_operand:DI 1 "data_segment_operand" "")] UNSPEC_EMB_HISUM)))]
2331 "TARGET_CM_EMBMEDANY && check_pic (1)"
2332 "sethi\t%%hi(%a1), %0")
2334 (define_insn "embmedany_losum"
2335 [(set (match_operand:DI 0 "register_operand" "=r")
2336 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2337 (match_operand:DI 2 "data_segment_operand" "")))]
2338 "TARGET_CM_EMBMEDANY"
2339 "add\t%1, %%lo(%a2), %0")
2341 (define_insn "embmedany_brsum"
2342 [(set (match_operand:DI 0 "register_operand" "=r")
2343 (unspec:DI [(match_operand:DI 1 "register_operand" "r")] UNSPEC_EMB_HISUM))]
2344 "TARGET_CM_EMBMEDANY"
2347 (define_insn "embmedany_textuhi"
2348 [(set (match_operand:DI 0 "register_operand" "=r")
2349 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTUHI)))]
2350 "TARGET_CM_EMBMEDANY && check_pic (1)"
2351 "sethi\t%%uhi(%a1), %0")
2353 (define_insn "embmedany_texthi"
2354 [(set (match_operand:DI 0 "register_operand" "=r")
2355 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTHI)))]
2356 "TARGET_CM_EMBMEDANY && check_pic (1)"
2357 "sethi\t%%hi(%a1), %0")
2359 (define_insn "embmedany_textulo"
2360 [(set (match_operand:DI 0 "register_operand" "=r")
2361 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2362 (unspec:DI [(match_operand:DI 2 "text_segment_operand" "")] UNSPEC_EMB_TEXTULO)))]
2363 "TARGET_CM_EMBMEDANY"
2364 "or\t%1, %%ulo(%a2), %0")
2366 (define_insn "embmedany_textlo"
2367 [(set (match_operand:DI 0 "register_operand" "=r")
2368 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2369 (match_operand:DI 2 "text_segment_operand" "")))]
2370 "TARGET_CM_EMBMEDANY"
2371 "or\t%1, %%lo(%a2), %0")
2373 ;; Now some patterns to help reload out a bit.
2374 (define_expand "reload_indi"
2375 [(parallel [(match_operand:DI 0 "register_operand" "=r")
2376 (match_operand:DI 1 "immediate_operand" "")
2377 (match_operand:TI 2 "register_operand" "=&r")])]
2379 || TARGET_CM_EMBMEDANY)
2382 sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
2386 (define_expand "reload_outdi"
2387 [(parallel [(match_operand:DI 0 "register_operand" "=r")
2388 (match_operand:DI 1 "immediate_operand" "")
2389 (match_operand:TI 2 "register_operand" "=&r")])]
2391 || TARGET_CM_EMBMEDANY)
2394 sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
2398 ;; Split up putting CONSTs and REGs into DI regs when !arch64
2400 [(set (match_operand:DI 0 "register_operand" "")
2401 (match_operand:DI 1 "const_int_operand" ""))]
2402 "! TARGET_ARCH64 && reload_completed"
2403 [(clobber (const_int 0))]
2405 #if HOST_BITS_PER_WIDE_INT == 32
2406 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
2407 (INTVAL (operands[1]) < 0) ?
2410 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2413 unsigned int low, high;
2415 low = trunc_int_for_mode (INTVAL (operands[1]), SImode);
2416 high = trunc_int_for_mode (INTVAL (operands[1]) >> 32, SImode);
2417 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), GEN_INT (high)));
2419 /* Slick... but this trick loses if this subreg constant part
2420 can be done in one insn. */
2421 if (low == high && (low & 0x3ff) != 0 && low + 0x1000 >= 0x2000)
2422 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2423 gen_highpart (SImode, operands[0])));
2425 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), GEN_INT (low)));
2431 [(set (match_operand:DI 0 "register_operand" "")
2432 (match_operand:DI 1 "const_double_operand" ""))]
2436 && ((GET_CODE (operands[0]) == REG
2437 && REGNO (operands[0]) < 32)
2438 || (GET_CODE (operands[0]) == SUBREG
2439 && GET_CODE (SUBREG_REG (operands[0])) == REG
2440 && REGNO (SUBREG_REG (operands[0])) < 32))))"
2441 [(clobber (const_int 0))]
2443 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
2444 GEN_INT (CONST_DOUBLE_HIGH (operands[1]))));
2446 /* Slick... but this trick loses if this subreg constant part
2447 can be done in one insn. */
2448 if (CONST_DOUBLE_LOW (operands[1]) == CONST_DOUBLE_HIGH (operands[1])
2449 && !(SPARC_SETHI32_P (CONST_DOUBLE_HIGH (operands[1]))
2450 || SPARC_SIMM13_P (CONST_DOUBLE_HIGH (operands[1]))))
2452 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2453 gen_highpart (SImode, operands[0])));
2457 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2458 GEN_INT (CONST_DOUBLE_LOW (operands[1]))));
2464 [(set (match_operand:DI 0 "register_operand" "")
2465 (match_operand:DI 1 "register_operand" ""))]
2469 && ((GET_CODE (operands[0]) == REG
2470 && REGNO (operands[0]) < 32)
2471 || (GET_CODE (operands[0]) == SUBREG
2472 && GET_CODE (SUBREG_REG (operands[0])) == REG
2473 && REGNO (SUBREG_REG (operands[0])) < 32))))"
2474 [(clobber (const_int 0))]
2476 rtx set_dest = operands[0];
2477 rtx set_src = operands[1];
2481 dest1 = gen_highpart (SImode, set_dest);
2482 dest2 = gen_lowpart (SImode, set_dest);
2483 src1 = gen_highpart (SImode, set_src);
2484 src2 = gen_lowpart (SImode, set_src);
2486 /* Now emit using the real source and destination we found, swapping
2487 the order if we detect overlap. */
2488 if (reg_overlap_mentioned_p (dest1, src2))
2490 emit_insn (gen_movsi (dest2, src2));
2491 emit_insn (gen_movsi (dest1, src1));
2495 emit_insn (gen_movsi (dest1, src1));
2496 emit_insn (gen_movsi (dest2, src2));
2501 ;; Now handle the cases of memory moves from/to non-even
2502 ;; DI mode register pairs.
2504 [(set (match_operand:DI 0 "register_operand" "")
2505 (match_operand:DI 1 "memory_operand" ""))]
2508 && sparc_splitdi_legitimate (operands[0], operands[1]))"
2509 [(clobber (const_int 0))]
2511 rtx word0 = adjust_address (operands[1], SImode, 0);
2512 rtx word1 = adjust_address (operands[1], SImode, 4);
2513 rtx high_part = gen_highpart (SImode, operands[0]);
2514 rtx low_part = gen_lowpart (SImode, operands[0]);
2516 if (reg_overlap_mentioned_p (high_part, word1))
2518 emit_insn (gen_movsi (low_part, word1));
2519 emit_insn (gen_movsi (high_part, word0));
2523 emit_insn (gen_movsi (high_part, word0));
2524 emit_insn (gen_movsi (low_part, word1));
2530 [(set (match_operand:DI 0 "memory_operand" "")
2531 (match_operand:DI 1 "register_operand" ""))]
2534 && sparc_splitdi_legitimate (operands[1], operands[0]))"
2535 [(clobber (const_int 0))]
2537 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0),
2538 gen_highpart (SImode, operands[1])));
2539 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4),
2540 gen_lowpart (SImode, operands[1])));
2545 [(set (match_operand:DI 0 "memory_operand" "")
2550 && ! mem_min_alignment (operands[0], 8)))
2551 && offsettable_memref_p (operands[0])"
2552 [(clobber (const_int 0))]
2554 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0), const0_rtx));
2555 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4), const0_rtx));
2559 ;; Floating point move insns
2561 (define_insn "*movsf_insn_novis"
2562 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,*r,*r,*r,*r,*r,f,m,m")
2563 (match_operand:SF 1 "input_operand" "f,G,Q,*rR,S,m,m,f,*rG"))]
2564 "(TARGET_FPU && ! TARGET_VIS)
2565 && (register_operand (operands[0], SFmode)
2566 || register_operand (operands[1], SFmode)
2567 || fp_zero_operand (operands[1], SFmode))"
2569 if (GET_CODE (operands[1]) == CONST_DOUBLE
2570 && (which_alternative == 2
2571 || which_alternative == 3
2572 || which_alternative == 4))
2577 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2578 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2579 operands[1] = GEN_INT (i);
2582 switch (which_alternative)
2585 return "fmovs\t%1, %0";
2589 return "sethi\t%%hi(%a1), %0";
2591 return "mov\t%1, %0";
2596 return "ld\t%1, %0";
2599 return "st\t%r1, %0";
2604 [(set_attr "type" "fpmove,*,*,*,*,load,fpload,fpstore,store")])
2606 (define_insn "*movsf_insn_vis"
2607 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,*r,*r,*r,*r,*r,f,m,m")
2608 (match_operand:SF 1 "input_operand" "f,G,G,Q,*rR,S,m,m,f,*rG"))]
2609 "(TARGET_FPU && TARGET_VIS)
2610 && (register_operand (operands[0], SFmode)
2611 || register_operand (operands[1], SFmode)
2612 || fp_zero_operand (operands[1], SFmode))"
2614 if (GET_CODE (operands[1]) == CONST_DOUBLE
2615 && (which_alternative == 3
2616 || which_alternative == 4
2617 || which_alternative == 5))
2622 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2623 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2624 operands[1] = GEN_INT (i);
2627 switch (which_alternative)
2630 return "fmovs\t%1, %0";
2632 return "fzeros\t%0";
2636 return "sethi\t%%hi(%a1), %0";
2638 return "mov\t%1, %0";
2643 return "ld\t%1, %0";
2646 return "st\t%r1, %0";
2651 [(set_attr "type" "fpmove,fga,*,*,*,*,load,fpload,fpstore,store")])
2653 ;; Exactly the same as above, except that all `f' cases are deleted.
2654 ;; This is necessary to prevent reload from ever trying to use a `f' reg
2657 (define_insn "*movsf_no_f_insn"
2658 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r,r,r,m")
2659 (match_operand:SF 1 "input_operand" "G,Q,rR,S,m,rG"))]
2661 && (register_operand (operands[0], SFmode)
2662 || register_operand (operands[1], SFmode)
2663 || fp_zero_operand (operands[1], SFmode))"
2665 if (GET_CODE (operands[1]) == CONST_DOUBLE
2666 && (which_alternative == 1
2667 || which_alternative == 2
2668 || which_alternative == 3))
2673 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2674 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2675 operands[1] = GEN_INT (i);
2678 switch (which_alternative)
2683 return "sethi\t%%hi(%a1), %0";
2685 return "mov\t%1, %0";
2689 return "ld\t%1, %0";
2691 return "st\t%r1, %0";
2696 [(set_attr "type" "*,*,*,*,load,store")])
2698 (define_insn "*movsf_lo_sum"
2699 [(set (match_operand:SF 0 "register_operand" "=r")
2700 (lo_sum:SF (match_operand:SF 1 "register_operand" "r")
2701 (match_operand:SF 2 "const_double_operand" "S")))]
2702 "fp_high_losum_p (operands[2])"
2707 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[2]);
2708 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2709 operands[2] = GEN_INT (i);
2710 return "or\t%1, %%lo(%a2), %0";
2713 (define_insn "*movsf_high"
2714 [(set (match_operand:SF 0 "register_operand" "=r")
2715 (high:SF (match_operand:SF 1 "const_double_operand" "S")))]
2716 "fp_high_losum_p (operands[1])"
2721 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2722 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2723 operands[1] = GEN_INT (i);
2724 return "sethi\t%%hi(%1), %0";
2728 [(set (match_operand:SF 0 "register_operand" "")
2729 (match_operand:SF 1 "const_double_operand" ""))]
2730 "fp_high_losum_p (operands[1])
2731 && (GET_CODE (operands[0]) == REG
2732 && REGNO (operands[0]) < 32)"
2733 [(set (match_dup 0) (high:SF (match_dup 1)))
2734 (set (match_dup 0) (lo_sum:SF (match_dup 0) (match_dup 1)))])
2736 (define_expand "movsf"
2737 [(set (match_operand:SF 0 "general_operand" "")
2738 (match_operand:SF 1 "general_operand" ""))]
2741 /* Force SFmode constants into memory. */
2742 if (GET_CODE (operands[0]) == REG
2743 && CONSTANT_P (operands[1]))
2745 /* emit_group_store will send such bogosity to us when it is
2746 not storing directly into memory. So fix this up to avoid
2747 crashes in output_constant_pool. */
2748 if (operands [1] == const0_rtx)
2749 operands[1] = CONST0_RTX (SFmode);
2751 if (TARGET_VIS && fp_zero_operand (operands[1], SFmode))
2754 /* We are able to build any SF constant in integer registers
2755 with at most 2 instructions. */
2756 if (REGNO (operands[0]) < 32)
2759 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
2763 /* Handle sets of MEM first. */
2764 if (GET_CODE (operands[0]) == MEM)
2766 if (register_operand (operands[1], SFmode)
2767 || fp_zero_operand (operands[1], SFmode))
2770 if (! reload_in_progress)
2772 operands[0] = validize_mem (operands[0]);
2773 operands[1] = force_reg (SFmode, operands[1]);
2777 /* Fixup PIC cases. */
2780 if (CONSTANT_P (operands[1])
2781 && pic_address_needs_scratch (operands[1]))
2782 operands[1] = legitimize_pic_address (operands[1], SFmode, 0);
2784 if (symbolic_operand (operands[1], SFmode))
2786 operands[1] = legitimize_pic_address (operands[1],
2788 (reload_in_progress ?
2798 (define_expand "movdf"
2799 [(set (match_operand:DF 0 "general_operand" "")
2800 (match_operand:DF 1 "general_operand" ""))]
2803 /* Force DFmode constants into memory. */
2804 if (GET_CODE (operands[0]) == REG
2805 && CONSTANT_P (operands[1]))
2807 /* emit_group_store will send such bogosity to us when it is
2808 not storing directly into memory. So fix this up to avoid
2809 crashes in output_constant_pool. */
2810 if (operands [1] == const0_rtx)
2811 operands[1] = CONST0_RTX (DFmode);
2813 if ((TARGET_VIS || REGNO (operands[0]) < 32)
2814 && fp_zero_operand (operands[1], DFmode))
2817 /* We are able to build any DF constant in integer registers. */
2818 if (REGNO (operands[0]) < 32
2819 && (reload_completed || reload_in_progress))
2822 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
2826 /* Handle MEM cases first. */
2827 if (GET_CODE (operands[0]) == MEM)
2829 if (register_operand (operands[1], DFmode)
2830 || fp_zero_operand (operands[1], DFmode))
2833 if (! reload_in_progress)
2835 operands[0] = validize_mem (operands[0]);
2836 operands[1] = force_reg (DFmode, operands[1]);
2840 /* Fixup PIC cases. */
2843 if (CONSTANT_P (operands[1])
2844 && pic_address_needs_scratch (operands[1]))
2845 operands[1] = legitimize_pic_address (operands[1], DFmode, 0);
2847 if (symbolic_operand (operands[1], DFmode))
2849 operands[1] = legitimize_pic_address (operands[1],
2851 (reload_in_progress ?
2861 ;; Be careful, fmovd does not exist when !v9.
2862 (define_insn "*movdf_insn_sp32"
2863 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,W,U,T,o,e,*r,o,e,o")
2864 (match_operand:DF 1 "input_operand" "W#F,e,T,U,G,e,*rFo,*r,o#F,e"))]
2867 && (register_operand (operands[0], DFmode)
2868 || register_operand (operands[1], DFmode)
2869 || fp_zero_operand (operands[1], DFmode))"
2881 [(set_attr "type" "fpload,fpstore,load,store,*,*,*,*,*,*")
2882 (set_attr "length" "*,*,*,*,2,2,2,2,2,2")])
2884 (define_insn "*movdf_no_e_insn_sp32"
2885 [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,o,r,o")
2886 (match_operand:DF 1 "input_operand" "T,U,G,ro,r"))]
2890 && (register_operand (operands[0], DFmode)
2891 || register_operand (operands[1], DFmode)
2892 || fp_zero_operand (operands[1], DFmode))"
2899 [(set_attr "type" "load,store,*,*,*")
2900 (set_attr "length" "*,*,2,2,2")])
2902 (define_insn "*movdf_no_e_insn_v9_sp32"
2903 [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,T,r,o")
2904 (match_operand:DF 1 "input_operand" "T,U,G,ro,rG"))]
2908 && (register_operand (operands[0], DFmode)
2909 || register_operand (operands[1], DFmode)
2910 || fp_zero_operand (operands[1], DFmode))"
2917 [(set_attr "type" "load,store,store,*,*")
2918 (set_attr "length" "*,*,*,2,2")])
2920 ;; We have available v9 double floats but not 64-bit
2921 ;; integer registers and no VIS.
2922 (define_insn "*movdf_insn_v9only_novis"
2923 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,T,W,U,T,f,*r,o")
2924 (match_operand:DF 1 "input_operand" "e,W#F,G,e,T,U,o#F,*roF,*rGf"))]
2929 && (register_operand (operands[0], DFmode)
2930 || register_operand (operands[1], DFmode)
2931 || fp_zero_operand (operands[1], DFmode))"
2942 [(set_attr "type" "fpmove,load,store,store,load,store,*,*,*")
2943 (set_attr "length" "*,*,*,*,*,*,2,2,2")
2944 (set_attr "fptype" "double,*,*,*,*,*,*,*,*")])
2946 ;; We have available v9 double floats but not 64-bit
2947 ;; integer registers but we have VIS.
2948 (define_insn "*movdf_insn_v9only_vis"
2949 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,e,T,W,U,T,f,*r,o")
2950 (match_operand:DF 1 "input_operand" "G,e,W#F,G,e,T,U,o#F,*roGF,*rGf"))]
2954 && (register_operand (operands[0], DFmode)
2955 || register_operand (operands[1], DFmode)
2956 || fp_zero_operand (operands[1], DFmode))"
2968 [(set_attr "type" "fga,fpmove,load,store,store,load,store,*,*,*")
2969 (set_attr "length" "*,*,*,*,*,*,*,2,2,2")
2970 (set_attr "fptype" "double,double,*,*,*,*,*,*,*,*")])
2972 ;; We have available both v9 double floats and 64-bit
2973 ;; integer registers. No VIS though.
2974 (define_insn "*movdf_insn_sp64_novis"
2975 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,W,*r,*r,m,*r")
2976 (match_operand:DF 1 "input_operand" "e,W#F,e,*rG,m,*rG,F"))]
2980 && (register_operand (operands[0], DFmode)
2981 || register_operand (operands[1], DFmode)
2982 || fp_zero_operand (operands[1], DFmode))"
2991 [(set_attr "type" "fpmove,load,store,*,load,store,*")
2992 (set_attr "length" "*,*,*,*,*,*,2")
2993 (set_attr "fptype" "double,*,*,*,*,*,*")])
2995 ;; We have available both v9 double floats and 64-bit
2996 ;; integer registers. And we have VIS.
2997 (define_insn "*movdf_insn_sp64_vis"
2998 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,e,W,*r,*r,m,*r")
2999 (match_operand:DF 1 "input_operand" "G,e,W#F,e,*rG,m,*rG,F"))]
3003 && (register_operand (operands[0], DFmode)
3004 || register_operand (operands[1], DFmode)
3005 || fp_zero_operand (operands[1], DFmode))"
3015 [(set_attr "type" "fga,fpmove,load,store,*,load,store,*")
3016 (set_attr "length" "*,*,*,*,*,*,*,2")
3017 (set_attr "fptype" "double,double,*,*,*,*,*,*")])
3019 (define_insn "*movdf_no_e_insn_sp64"
3020 [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m")
3021 (match_operand:DF 1 "input_operand" "r,m,rG"))]
3024 && (register_operand (operands[0], DFmode)
3025 || register_operand (operands[1], DFmode)
3026 || fp_zero_operand (operands[1], DFmode))"
3031 [(set_attr "type" "*,load,store")])
3034 [(set (match_operand:DF 0 "register_operand" "")
3035 (match_operand:DF 1 "const_double_operand" ""))]
3037 && (GET_CODE (operands[0]) == REG
3038 && REGNO (operands[0]) < 32)
3039 && ! fp_zero_operand(operands[1], DFmode)
3040 && reload_completed"
3041 [(clobber (const_int 0))]
3046 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3047 REAL_VALUE_TO_TARGET_DOUBLE (r, l);
3048 operands[0] = gen_rtx_raw_REG (DImode, REGNO (operands[0]));
3052 #if HOST_BITS_PER_WIDE_INT == 64
3055 val = ((HOST_WIDE_INT)(unsigned long)l[1] |
3056 ((HOST_WIDE_INT)(unsigned long)l[0] << 32));
3057 emit_insn (gen_movdi (operands[0], GEN_INT (val)));
3059 emit_insn (gen_movdi (operands[0],
3060 immed_double_const (l[1], l[0], DImode)));
3065 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
3068 /* Slick... but this trick loses if this subreg constant part
3069 can be done in one insn. */
3071 && !(SPARC_SETHI32_P (l[0])
3072 || SPARC_SIMM13_P (l[0])))
3074 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
3075 gen_highpart (SImode, operands[0])));
3079 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
3086 ;; Ok, now the splits to handle all the multi insn and
3087 ;; mis-aligned memory address cases.
3088 ;; In these splits please take note that we must be
3089 ;; careful when V9 but not ARCH64 because the integer
3090 ;; register DFmode cases must be handled.
3092 [(set (match_operand:DF 0 "register_operand" "")
3093 (match_operand:DF 1 "register_operand" ""))]
3096 && ((GET_CODE (operands[0]) == REG
3097 && REGNO (operands[0]) < 32)
3098 || (GET_CODE (operands[0]) == SUBREG
3099 && GET_CODE (SUBREG_REG (operands[0])) == REG
3100 && REGNO (SUBREG_REG (operands[0])) < 32))))
3101 && reload_completed"
3102 [(clobber (const_int 0))]
3104 rtx set_dest = operands[0];
3105 rtx set_src = operands[1];
3109 dest1 = gen_highpart (SFmode, set_dest);
3110 dest2 = gen_lowpart (SFmode, set_dest);
3111 src1 = gen_highpart (SFmode, set_src);
3112 src2 = gen_lowpart (SFmode, set_src);
3114 /* Now emit using the real source and destination we found, swapping
3115 the order if we detect overlap. */
3116 if (reg_overlap_mentioned_p (dest1, src2))
3118 emit_insn (gen_movsf (dest2, src2));
3119 emit_insn (gen_movsf (dest1, src1));
3123 emit_insn (gen_movsf (dest1, src1));
3124 emit_insn (gen_movsf (dest2, src2));
3130 [(set (match_operand:DF 0 "register_operand" "")
3131 (match_operand:DF 1 "memory_operand" ""))]
3134 && (((REGNO (operands[0]) % 2) != 0)
3135 || ! mem_min_alignment (operands[1], 8))
3136 && offsettable_memref_p (operands[1])"
3137 [(clobber (const_int 0))]
3139 rtx word0 = adjust_address (operands[1], SFmode, 0);
3140 rtx word1 = adjust_address (operands[1], SFmode, 4);
3142 if (reg_overlap_mentioned_p (gen_highpart (SFmode, operands[0]), word1))
3144 emit_insn (gen_movsf (gen_lowpart (SFmode, operands[0]),
3146 emit_insn (gen_movsf (gen_highpart (SFmode, operands[0]),
3151 emit_insn (gen_movsf (gen_highpart (SFmode, operands[0]),
3153 emit_insn (gen_movsf (gen_lowpart (SFmode, operands[0]),
3160 [(set (match_operand:DF 0 "memory_operand" "")
3161 (match_operand:DF 1 "register_operand" ""))]
3164 && (((REGNO (operands[1]) % 2) != 0)
3165 || ! mem_min_alignment (operands[0], 8))
3166 && offsettable_memref_p (operands[0])"
3167 [(clobber (const_int 0))]
3169 rtx word0 = adjust_address (operands[0], SFmode, 0);
3170 rtx word1 = adjust_address (operands[0], SFmode, 4);
3172 emit_insn (gen_movsf (word0,
3173 gen_highpart (SFmode, operands[1])));
3174 emit_insn (gen_movsf (word1,
3175 gen_lowpart (SFmode, operands[1])));
3180 [(set (match_operand:DF 0 "memory_operand" "")
3181 (match_operand:DF 1 "fp_zero_operand" ""))]
3185 && ! mem_min_alignment (operands[0], 8)))
3186 && offsettable_memref_p (operands[0])"
3187 [(clobber (const_int 0))]
3191 dest1 = adjust_address (operands[0], SFmode, 0);
3192 dest2 = adjust_address (operands[0], SFmode, 4);
3194 emit_insn (gen_movsf (dest1, CONST0_RTX (SFmode)));
3195 emit_insn (gen_movsf (dest2, CONST0_RTX (SFmode)));
3200 [(set (match_operand:DF 0 "register_operand" "")
3201 (match_operand:DF 1 "fp_zero_operand" ""))]
3204 && ((GET_CODE (operands[0]) == REG
3205 && REGNO (operands[0]) < 32)
3206 || (GET_CODE (operands[0]) == SUBREG
3207 && GET_CODE (SUBREG_REG (operands[0])) == REG
3208 && REGNO (SUBREG_REG (operands[0])) < 32))"
3209 [(clobber (const_int 0))]
3211 rtx set_dest = operands[0];
3214 dest1 = gen_highpart (SFmode, set_dest);
3215 dest2 = gen_lowpart (SFmode, set_dest);
3216 emit_insn (gen_movsf (dest1, CONST0_RTX (SFmode)));
3217 emit_insn (gen_movsf (dest2, CONST0_RTX (SFmode)));
3221 (define_expand "movtf"
3222 [(set (match_operand:TF 0 "general_operand" "")
3223 (match_operand:TF 1 "general_operand" ""))]
3226 /* Force TFmode constants into memory. */
3227 if (GET_CODE (operands[0]) == REG
3228 && CONSTANT_P (operands[1]))
3230 /* emit_group_store will send such bogosity to us when it is
3231 not storing directly into memory. So fix this up to avoid
3232 crashes in output_constant_pool. */
3233 if (operands [1] == const0_rtx)
3234 operands[1] = CONST0_RTX (TFmode);
3236 if (TARGET_VIS && fp_zero_operand (operands[1], TFmode))
3239 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
3243 /* Handle MEM cases first, note that only v9 guarantees
3244 full 16-byte alignment for quads. */
3245 if (GET_CODE (operands[0]) == MEM)
3247 if (register_operand (operands[1], TFmode)
3248 || fp_zero_operand (operands[1], TFmode))
3251 if (! reload_in_progress)
3253 operands[0] = validize_mem (operands[0]);
3254 operands[1] = force_reg (TFmode, operands[1]);
3258 /* Fixup PIC cases. */
3261 if (CONSTANT_P (operands[1])
3262 && pic_address_needs_scratch (operands[1]))
3263 operands[1] = legitimize_pic_address (operands[1], TFmode, 0);
3265 if (symbolic_operand (operands[1], TFmode))
3267 operands[1] = legitimize_pic_address (operands[1],
3269 (reload_in_progress ?
3279 ;; Be careful, fmovq and {st,ld}{x,q} do not exist when !arch64 so
3280 ;; we must split them all. :-(
3281 (define_insn "*movtf_insn_sp32"
3282 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,U,r")
3283 (match_operand:TF 1 "input_operand" "oe,GeUr,o,roG"))]
3287 && (register_operand (operands[0], TFmode)
3288 || register_operand (operands[1], TFmode)
3289 || fp_zero_operand (operands[1], TFmode))"
3291 [(set_attr "length" "4")])
3293 (define_insn "*movtf_insn_vis_sp32"
3294 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,U,r")
3295 (match_operand:TF 1 "input_operand" "Goe,GeUr,o,roG"))]
3299 && (register_operand (operands[0], TFmode)
3300 || register_operand (operands[1], TFmode)
3301 || fp_zero_operand (operands[1], TFmode))"
3303 [(set_attr "length" "4")])
3305 ;; Exactly the same as above, except that all `e' cases are deleted.
3306 ;; This is necessary to prevent reload from ever trying to use a `e' reg
3309 (define_insn "*movtf_no_e_insn_sp32"
3310 [(set (match_operand:TF 0 "nonimmediate_operand" "=o,U,o,r,o")
3311 (match_operand:TF 1 "input_operand" "G,o,U,roG,r"))]
3314 && (register_operand (operands[0], TFmode)
3315 || register_operand (operands[1], TFmode)
3316 || fp_zero_operand (operands[1], TFmode))"
3318 [(set_attr "length" "4")])
3320 ;; Now handle the float reg cases directly when arch64,
3321 ;; hard_quad, and proper reg number alignment are all true.
3322 (define_insn "*movtf_insn_hq_sp64"
3323 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,e,m,o,r")
3324 (match_operand:TF 1 "input_operand" "e,m,e,Gr,roG"))]
3329 && (register_operand (operands[0], TFmode)
3330 || register_operand (operands[1], TFmode)
3331 || fp_zero_operand (operands[1], TFmode))"
3338 [(set_attr "type" "fpmove,fpload,fpstore,*,*")
3339 (set_attr "length" "*,*,*,2,2")])
3341 (define_insn "*movtf_insn_hq_vis_sp64"
3342 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,e,m,eo,r,o")
3343 (match_operand:TF 1 "input_operand" "e,m,e,G,roG,r"))]
3348 && (register_operand (operands[0], TFmode)
3349 || register_operand (operands[1], TFmode)
3350 || fp_zero_operand (operands[1], TFmode))"
3358 [(set_attr "type" "fpmove,fpload,fpstore,*,*,*")
3359 (set_attr "length" "*,*,*,2,2,2")])
3361 ;; Now we allow the integer register cases even when
3362 ;; only arch64 is true.
3363 (define_insn "*movtf_insn_sp64"
3364 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,r")
3365 (match_operand:TF 1 "input_operand" "oe,Ger,orG"))]
3369 && ! TARGET_HARD_QUAD
3370 && (register_operand (operands[0], TFmode)
3371 || register_operand (operands[1], TFmode)
3372 || fp_zero_operand (operands[1], TFmode))"
3374 [(set_attr "length" "2")])
3376 (define_insn "*movtf_insn_vis_sp64"
3377 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,r")
3378 (match_operand:TF 1 "input_operand" "Goe,Ger,orG"))]
3382 && ! TARGET_HARD_QUAD
3383 && (register_operand (operands[0], TFmode)
3384 || register_operand (operands[1], TFmode)
3385 || fp_zero_operand (operands[1], TFmode))"
3387 [(set_attr "length" "2")])
3389 (define_insn "*movtf_no_e_insn_sp64"
3390 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o")
3391 (match_operand:TF 1 "input_operand" "orG,rG"))]
3394 && (register_operand (operands[0], TFmode)
3395 || register_operand (operands[1], TFmode)
3396 || fp_zero_operand (operands[1], TFmode))"
3398 [(set_attr "length" "2")])
3400 ;; Now all the splits to handle multi-insn TF mode moves.
3402 [(set (match_operand:TF 0 "register_operand" "")
3403 (match_operand:TF 1 "register_operand" ""))]
3407 && ! TARGET_HARD_QUAD)
3408 || ! fp_register_operand (operands[0], TFmode))"
3409 [(clobber (const_int 0))]
3411 rtx set_dest = operands[0];
3412 rtx set_src = operands[1];
3416 dest1 = gen_df_reg (set_dest, 0);
3417 dest2 = gen_df_reg (set_dest, 1);
3418 src1 = gen_df_reg (set_src, 0);
3419 src2 = gen_df_reg (set_src, 1);
3421 /* Now emit using the real source and destination we found, swapping
3422 the order if we detect overlap. */
3423 if (reg_overlap_mentioned_p (dest1, src2))
3425 emit_insn (gen_movdf (dest2, src2));
3426 emit_insn (gen_movdf (dest1, src1));
3430 emit_insn (gen_movdf (dest1, src1));
3431 emit_insn (gen_movdf (dest2, src2));
3437 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3438 (match_operand:TF 1 "fp_zero_operand" ""))]
3440 [(clobber (const_int 0))]
3442 rtx set_dest = operands[0];
3445 switch (GET_CODE (set_dest))
3448 dest1 = gen_df_reg (set_dest, 0);
3449 dest2 = gen_df_reg (set_dest, 1);
3452 dest1 = adjust_address (set_dest, DFmode, 0);
3453 dest2 = adjust_address (set_dest, DFmode, 8);
3459 emit_insn (gen_movdf (dest1, CONST0_RTX (DFmode)));
3460 emit_insn (gen_movdf (dest2, CONST0_RTX (DFmode)));
3465 [(set (match_operand:TF 0 "register_operand" "")
3466 (match_operand:TF 1 "memory_operand" ""))]
3468 && offsettable_memref_p (operands[1])
3470 || ! TARGET_HARD_QUAD
3471 || ! fp_register_operand (operands[0], TFmode)))"
3472 [(clobber (const_int 0))]
3474 rtx word0 = adjust_address (operands[1], DFmode, 0);
3475 rtx word1 = adjust_address (operands[1], DFmode, 8);
3476 rtx set_dest, dest1, dest2;
3478 set_dest = operands[0];
3480 dest1 = gen_df_reg (set_dest, 0);
3481 dest2 = gen_df_reg (set_dest, 1);
3483 /* Now output, ordering such that we don't clobber any registers
3484 mentioned in the address. */
3485 if (reg_overlap_mentioned_p (dest1, word1))
3488 emit_insn (gen_movdf (dest2, word1));
3489 emit_insn (gen_movdf (dest1, word0));
3493 emit_insn (gen_movdf (dest1, word0));
3494 emit_insn (gen_movdf (dest2, word1));
3500 [(set (match_operand:TF 0 "memory_operand" "")
3501 (match_operand:TF 1 "register_operand" ""))]
3503 && offsettable_memref_p (operands[0])
3505 || ! TARGET_HARD_QUAD
3506 || ! fp_register_operand (operands[1], TFmode)))"
3507 [(clobber (const_int 0))]
3509 rtx set_src = operands[1];
3511 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 0),
3512 gen_df_reg (set_src, 0)));
3513 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 8),
3514 gen_df_reg (set_src, 1)));
3518 ;; SPARC V9 conditional move instructions.
3520 ;; We can handle larger constants here for some flavors, but for now we keep
3521 ;; it simple and only allow those constants supported by all flavors.
3522 ;; Note that emit_conditional_move canonicalizes operands 2,3 so that operand
3523 ;; 3 contains the constant if one is present, but we handle either for
3524 ;; generality (sparc.c puts a constant in operand 2).
3526 (define_expand "movqicc"
3527 [(set (match_operand:QI 0 "register_operand" "")
3528 (if_then_else:QI (match_operand 1 "comparison_operator" "")
3529 (match_operand:QI 2 "arith10_operand" "")
3530 (match_operand:QI 3 "arith10_operand" "")))]
3533 enum rtx_code code = GET_CODE (operands[1]);
3535 if (GET_MODE (sparc_compare_op0) == DImode
3539 if (sparc_compare_op1 == const0_rtx
3540 && GET_CODE (sparc_compare_op0) == REG
3541 && GET_MODE (sparc_compare_op0) == DImode
3542 && v9_regcmp_p (code))
3544 operands[1] = gen_rtx_fmt_ee (code, DImode,
3545 sparc_compare_op0, sparc_compare_op1);
3549 rtx cc_reg = gen_compare_reg (code,
3550 sparc_compare_op0, sparc_compare_op1);
3551 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3555 (define_expand "movhicc"
3556 [(set (match_operand:HI 0 "register_operand" "")
3557 (if_then_else:HI (match_operand 1 "comparison_operator" "")
3558 (match_operand:HI 2 "arith10_operand" "")
3559 (match_operand:HI 3 "arith10_operand" "")))]
3562 enum rtx_code code = GET_CODE (operands[1]);
3564 if (GET_MODE (sparc_compare_op0) == DImode
3568 if (sparc_compare_op1 == const0_rtx
3569 && GET_CODE (sparc_compare_op0) == REG
3570 && GET_MODE (sparc_compare_op0) == DImode
3571 && v9_regcmp_p (code))
3573 operands[1] = gen_rtx_fmt_ee (code, DImode,
3574 sparc_compare_op0, sparc_compare_op1);
3578 rtx cc_reg = gen_compare_reg (code,
3579 sparc_compare_op0, sparc_compare_op1);
3580 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3584 (define_expand "movsicc"
3585 [(set (match_operand:SI 0 "register_operand" "")
3586 (if_then_else:SI (match_operand 1 "comparison_operator" "")
3587 (match_operand:SI 2 "arith10_operand" "")
3588 (match_operand:SI 3 "arith10_operand" "")))]
3591 enum rtx_code code = GET_CODE (operands[1]);
3592 enum machine_mode op0_mode = GET_MODE (sparc_compare_op0);
3594 if (sparc_compare_op1 == const0_rtx
3595 && GET_CODE (sparc_compare_op0) == REG
3596 && (TARGET_ARCH64 && op0_mode == DImode && v9_regcmp_p (code)))
3598 operands[1] = gen_rtx_fmt_ee (code, op0_mode,
3599 sparc_compare_op0, sparc_compare_op1);
3603 rtx cc_reg = gen_compare_reg (code,
3604 sparc_compare_op0, sparc_compare_op1);
3605 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg),
3606 cc_reg, const0_rtx);
3610 (define_expand "movdicc"
3611 [(set (match_operand:DI 0 "register_operand" "")
3612 (if_then_else:DI (match_operand 1 "comparison_operator" "")
3613 (match_operand:DI 2 "arith10_double_operand" "")
3614 (match_operand:DI 3 "arith10_double_operand" "")))]
3617 enum rtx_code code = GET_CODE (operands[1]);
3619 if (sparc_compare_op1 == const0_rtx
3620 && GET_CODE (sparc_compare_op0) == REG
3621 && GET_MODE (sparc_compare_op0) == DImode
3622 && v9_regcmp_p (code))
3624 operands[1] = gen_rtx_fmt_ee (code, DImode,
3625 sparc_compare_op0, sparc_compare_op1);
3629 rtx cc_reg = gen_compare_reg (code,
3630 sparc_compare_op0, sparc_compare_op1);
3631 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg),
3632 cc_reg, const0_rtx);
3636 (define_expand "movsfcc"
3637 [(set (match_operand:SF 0 "register_operand" "")
3638 (if_then_else:SF (match_operand 1 "comparison_operator" "")
3639 (match_operand:SF 2 "register_operand" "")
3640 (match_operand:SF 3 "register_operand" "")))]
3641 "TARGET_V9 && TARGET_FPU"
3643 enum rtx_code code = GET_CODE (operands[1]);
3645 if (GET_MODE (sparc_compare_op0) == DImode
3649 if (sparc_compare_op1 == const0_rtx
3650 && GET_CODE (sparc_compare_op0) == REG
3651 && GET_MODE (sparc_compare_op0) == DImode
3652 && v9_regcmp_p (code))
3654 operands[1] = gen_rtx_fmt_ee (code, DImode,
3655 sparc_compare_op0, sparc_compare_op1);
3659 rtx cc_reg = gen_compare_reg (code,
3660 sparc_compare_op0, sparc_compare_op1);
3661 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3665 (define_expand "movdfcc"
3666 [(set (match_operand:DF 0 "register_operand" "")
3667 (if_then_else:DF (match_operand 1 "comparison_operator" "")
3668 (match_operand:DF 2 "register_operand" "")
3669 (match_operand:DF 3 "register_operand" "")))]
3670 "TARGET_V9 && TARGET_FPU"
3672 enum rtx_code code = GET_CODE (operands[1]);
3674 if (GET_MODE (sparc_compare_op0) == DImode
3678 if (sparc_compare_op1 == const0_rtx
3679 && GET_CODE (sparc_compare_op0) == REG
3680 && GET_MODE (sparc_compare_op0) == DImode
3681 && v9_regcmp_p (code))
3683 operands[1] = gen_rtx_fmt_ee (code, DImode,
3684 sparc_compare_op0, sparc_compare_op1);
3688 rtx cc_reg = gen_compare_reg (code,
3689 sparc_compare_op0, sparc_compare_op1);
3690 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3694 (define_expand "movtfcc"
3695 [(set (match_operand:TF 0 "register_operand" "")
3696 (if_then_else:TF (match_operand 1 "comparison_operator" "")
3697 (match_operand:TF 2 "register_operand" "")
3698 (match_operand:TF 3 "register_operand" "")))]
3699 "TARGET_V9 && TARGET_FPU"
3701 enum rtx_code code = GET_CODE (operands[1]);
3703 if (GET_MODE (sparc_compare_op0) == DImode
3707 if (sparc_compare_op1 == const0_rtx
3708 && GET_CODE (sparc_compare_op0) == REG
3709 && GET_MODE (sparc_compare_op0) == DImode
3710 && v9_regcmp_p (code))
3712 operands[1] = gen_rtx_fmt_ee (code, DImode,
3713 sparc_compare_op0, sparc_compare_op1);
3717 rtx cc_reg = gen_compare_reg (code,
3718 sparc_compare_op0, sparc_compare_op1);
3719 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3723 ;; Conditional move define_insns.
3725 (define_insn "*movqi_cc_sp64"
3726 [(set (match_operand:QI 0 "register_operand" "=r,r")
3727 (if_then_else:QI (match_operator 1 "comparison_operator"
3728 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3730 (match_operand:QI 3 "arith11_operand" "rL,0")
3731 (match_operand:QI 4 "arith11_operand" "0,rL")))]
3735 mov%c1\t%x2, %4, %0"
3736 [(set_attr "type" "cmove")])
3738 (define_insn "*movhi_cc_sp64"
3739 [(set (match_operand:HI 0 "register_operand" "=r,r")
3740 (if_then_else:HI (match_operator 1 "comparison_operator"
3741 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3743 (match_operand:HI 3 "arith11_operand" "rL,0")
3744 (match_operand:HI 4 "arith11_operand" "0,rL")))]
3748 mov%c1\t%x2, %4, %0"
3749 [(set_attr "type" "cmove")])
3751 (define_insn "*movsi_cc_sp64"
3752 [(set (match_operand:SI 0 "register_operand" "=r,r")
3753 (if_then_else:SI (match_operator 1 "comparison_operator"
3754 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3756 (match_operand:SI 3 "arith11_operand" "rL,0")
3757 (match_operand:SI 4 "arith11_operand" "0,rL")))]
3761 mov%c1\t%x2, %4, %0"
3762 [(set_attr "type" "cmove")])
3764 ;; ??? The constraints of operands 3,4 need work.
3765 (define_insn "*movdi_cc_sp64"
3766 [(set (match_operand:DI 0 "register_operand" "=r,r")
3767 (if_then_else:DI (match_operator 1 "comparison_operator"
3768 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3770 (match_operand:DI 3 "arith11_double_operand" "rLH,0")
3771 (match_operand:DI 4 "arith11_double_operand" "0,rLH")))]
3775 mov%c1\t%x2, %4, %0"
3776 [(set_attr "type" "cmove")])
3778 (define_insn "*movdi_cc_sp64_trunc"
3779 [(set (match_operand:SI 0 "register_operand" "=r,r")
3780 (if_then_else:SI (match_operator 1 "comparison_operator"
3781 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3783 (match_operand:SI 3 "arith11_double_operand" "rLH,0")
3784 (match_operand:SI 4 "arith11_double_operand" "0,rLH")))]
3788 mov%c1\t%x2, %4, %0"
3789 [(set_attr "type" "cmove")])
3791 (define_insn "*movsf_cc_sp64"
3792 [(set (match_operand:SF 0 "register_operand" "=f,f")
3793 (if_then_else:SF (match_operator 1 "comparison_operator"
3794 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3796 (match_operand:SF 3 "register_operand" "f,0")
3797 (match_operand:SF 4 "register_operand" "0,f")))]
3798 "TARGET_V9 && TARGET_FPU"
3800 fmovs%C1\t%x2, %3, %0
3801 fmovs%c1\t%x2, %4, %0"
3802 [(set_attr "type" "fpcmove")])
3804 (define_insn "movdf_cc_sp64"
3805 [(set (match_operand:DF 0 "register_operand" "=e,e")
3806 (if_then_else:DF (match_operator 1 "comparison_operator"
3807 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3809 (match_operand:DF 3 "register_operand" "e,0")
3810 (match_operand:DF 4 "register_operand" "0,e")))]
3811 "TARGET_V9 && TARGET_FPU"
3813 fmovd%C1\t%x2, %3, %0
3814 fmovd%c1\t%x2, %4, %0"
3815 [(set_attr "type" "fpcmove")
3816 (set_attr "fptype" "double")])
3818 (define_insn "*movtf_cc_hq_sp64"
3819 [(set (match_operand:TF 0 "register_operand" "=e,e")
3820 (if_then_else:TF (match_operator 1 "comparison_operator"
3821 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3823 (match_operand:TF 3 "register_operand" "e,0")
3824 (match_operand:TF 4 "register_operand" "0,e")))]
3825 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
3827 fmovq%C1\t%x2, %3, %0
3828 fmovq%c1\t%x2, %4, %0"
3829 [(set_attr "type" "fpcmove")])
3831 (define_insn_and_split "*movtf_cc_sp64"
3832 [(set (match_operand:TF 0 "register_operand" "=e,e")
3833 (if_then_else:TF (match_operator 1 "comparison_operator"
3834 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3836 (match_operand:TF 3 "register_operand" "e,0")
3837 (match_operand:TF 4 "register_operand" "0,e")))]
3838 "TARGET_V9 && TARGET_FPU && !TARGET_HARD_QUAD"
3840 "&& reload_completed"
3841 [(clobber (const_int 0))]
3843 rtx set_dest = operands[0];
3844 rtx set_srca = operands[3];
3845 rtx set_srcb = operands[4];
3846 int third = rtx_equal_p (set_dest, set_srca);
3848 rtx srca1, srca2, srcb1, srcb2;
3850 dest1 = gen_df_reg (set_dest, 0);
3851 dest2 = gen_df_reg (set_dest, 1);
3852 srca1 = gen_df_reg (set_srca, 0);
3853 srca2 = gen_df_reg (set_srca, 1);
3854 srcb1 = gen_df_reg (set_srcb, 0);
3855 srcb2 = gen_df_reg (set_srcb, 1);
3857 /* Now emit using the real source and destination we found, swapping
3858 the order if we detect overlap. */
3859 if ((third && reg_overlap_mentioned_p (dest1, srcb2))
3860 || (!third && reg_overlap_mentioned_p (dest1, srca2)))
3862 emit_insn (gen_movdf_cc_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
3863 emit_insn (gen_movdf_cc_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
3867 emit_insn (gen_movdf_cc_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
3868 emit_insn (gen_movdf_cc_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
3872 [(set_attr "length" "2")])
3874 (define_insn "*movqi_cc_reg_sp64"
3875 [(set (match_operand:QI 0 "register_operand" "=r,r")
3876 (if_then_else:QI (match_operator 1 "v9_regcmp_op"
3877 [(match_operand:DI 2 "register_operand" "r,r")
3879 (match_operand:QI 3 "arith10_operand" "rM,0")
3880 (match_operand:QI 4 "arith10_operand" "0,rM")))]
3883 movr%D1\t%2, %r3, %0
3884 movr%d1\t%2, %r4, %0"
3885 [(set_attr "type" "cmove")])
3887 (define_insn "*movhi_cc_reg_sp64"
3888 [(set (match_operand:HI 0 "register_operand" "=r,r")
3889 (if_then_else:HI (match_operator 1 "v9_regcmp_op"
3890 [(match_operand:DI 2 "register_operand" "r,r")
3892 (match_operand:HI 3 "arith10_operand" "rM,0")
3893 (match_operand:HI 4 "arith10_operand" "0,rM")))]
3896 movr%D1\t%2, %r3, %0
3897 movr%d1\t%2, %r4, %0"
3898 [(set_attr "type" "cmove")])
3900 (define_insn "*movsi_cc_reg_sp64"
3901 [(set (match_operand:SI 0 "register_operand" "=r,r")
3902 (if_then_else:SI (match_operator 1 "v9_regcmp_op"
3903 [(match_operand:DI 2 "register_operand" "r,r")
3905 (match_operand:SI 3 "arith10_operand" "rM,0")
3906 (match_operand:SI 4 "arith10_operand" "0,rM")))]
3909 movr%D1\t%2, %r3, %0
3910 movr%d1\t%2, %r4, %0"
3911 [(set_attr "type" "cmove")])
3913 ;; ??? The constraints of operands 3,4 need work.
3914 (define_insn "*movdi_cc_reg_sp64"
3915 [(set (match_operand:DI 0 "register_operand" "=r,r")
3916 (if_then_else:DI (match_operator 1 "v9_regcmp_op"
3917 [(match_operand:DI 2 "register_operand" "r,r")
3919 (match_operand:DI 3 "arith10_double_operand" "rMH,0")
3920 (match_operand:DI 4 "arith10_double_operand" "0,rMH")))]
3923 movr%D1\t%2, %r3, %0
3924 movr%d1\t%2, %r4, %0"
3925 [(set_attr "type" "cmove")])
3927 (define_insn "*movdi_cc_reg_sp64_trunc"
3928 [(set (match_operand:SI 0 "register_operand" "=r,r")
3929 (if_then_else:SI (match_operator 1 "v9_regcmp_op"
3930 [(match_operand:DI 2 "register_operand" "r,r")
3932 (match_operand:SI 3 "arith10_double_operand" "rMH,0")
3933 (match_operand:SI 4 "arith10_double_operand" "0,rMH")))]
3936 movr%D1\t%2, %r3, %0
3937 movr%d1\t%2, %r4, %0"
3938 [(set_attr "type" "cmove")])
3940 (define_insn "*movsf_cc_reg_sp64"
3941 [(set (match_operand:SF 0 "register_operand" "=f,f")
3942 (if_then_else:SF (match_operator 1 "v9_regcmp_op"
3943 [(match_operand:DI 2 "register_operand" "r,r")
3945 (match_operand:SF 3 "register_operand" "f,0")
3946 (match_operand:SF 4 "register_operand" "0,f")))]
3947 "TARGET_ARCH64 && TARGET_FPU"
3949 fmovrs%D1\t%2, %3, %0
3950 fmovrs%d1\t%2, %4, %0"
3951 [(set_attr "type" "fpcrmove")])
3953 (define_insn "movdf_cc_reg_sp64"
3954 [(set (match_operand:DF 0 "register_operand" "=e,e")
3955 (if_then_else:DF (match_operator 1 "v9_regcmp_op"
3956 [(match_operand:DI 2 "register_operand" "r,r")
3958 (match_operand:DF 3 "register_operand" "e,0")
3959 (match_operand:DF 4 "register_operand" "0,e")))]
3960 "TARGET_ARCH64 && TARGET_FPU"
3962 fmovrd%D1\t%2, %3, %0
3963 fmovrd%d1\t%2, %4, %0"
3964 [(set_attr "type" "fpcrmove")
3965 (set_attr "fptype" "double")])
3967 (define_insn "*movtf_cc_reg_hq_sp64"
3968 [(set (match_operand:TF 0 "register_operand" "=e,e")
3969 (if_then_else:TF (match_operator 1 "v9_regcmp_op"
3970 [(match_operand:DI 2 "register_operand" "r,r")
3972 (match_operand:TF 3 "register_operand" "e,0")
3973 (match_operand:TF 4 "register_operand" "0,e")))]
3974 "TARGET_ARCH64 && TARGET_FPU && TARGET_HARD_QUAD"
3976 fmovrq%D1\t%2, %3, %0
3977 fmovrq%d1\t%2, %4, %0"
3978 [(set_attr "type" "fpcrmove")])
3980 (define_insn_and_split "*movtf_cc_reg_sp64"
3981 [(set (match_operand:TF 0 "register_operand" "=e,e")
3982 (if_then_else:TF (match_operator 1 "v9_regcmp_op"
3983 [(match_operand:DI 2 "register_operand" "r,r")
3985 (match_operand:TF 3 "register_operand" "e,0")
3986 (match_operand:TF 4 "register_operand" "0,e")))]
3987 "TARGET_ARCH64 && TARGET_FPU && ! TARGET_HARD_QUAD"
3989 "&& reload_completed"
3990 [(clobber (const_int 0))]
3992 rtx set_dest = operands[0];
3993 rtx set_srca = operands[3];
3994 rtx set_srcb = operands[4];
3995 int third = rtx_equal_p (set_dest, set_srca);
3997 rtx srca1, srca2, srcb1, srcb2;
3999 dest1 = gen_df_reg (set_dest, 0);
4000 dest2 = gen_df_reg (set_dest, 1);
4001 srca1 = gen_df_reg (set_srca, 0);
4002 srca2 = gen_df_reg (set_srca, 1);
4003 srcb1 = gen_df_reg (set_srcb, 0);
4004 srcb2 = gen_df_reg (set_srcb, 1);
4006 /* Now emit using the real source and destination we found, swapping
4007 the order if we detect overlap. */
4008 if ((third && reg_overlap_mentioned_p (dest1, srcb2))
4009 || (!third && reg_overlap_mentioned_p (dest1, srca2)))
4011 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
4012 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
4016 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
4017 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
4021 [(set_attr "length" "2")])
4024 ;;- zero extension instructions
4026 ;; These patterns originally accepted general_operands, however, slightly
4027 ;; better code is generated by only accepting register_operands, and then
4028 ;; letting combine generate the ldu[hb] insns.
4030 (define_expand "zero_extendhisi2"
4031 [(set (match_operand:SI 0 "register_operand" "")
4032 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
4035 rtx temp = gen_reg_rtx (SImode);
4036 rtx shift_16 = GEN_INT (16);
4037 int op1_subbyte = 0;
4039 if (GET_CODE (operand1) == SUBREG)
4041 op1_subbyte = SUBREG_BYTE (operand1);
4042 op1_subbyte /= GET_MODE_SIZE (SImode);
4043 op1_subbyte *= GET_MODE_SIZE (SImode);
4044 operand1 = XEXP (operand1, 0);
4047 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4049 emit_insn (gen_lshrsi3 (operand0, temp, shift_16));
4053 (define_insn "*zero_extendhisi2_insn"
4054 [(set (match_operand:SI 0 "register_operand" "=r")
4055 (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
4058 [(set_attr "type" "load")
4059 (set_attr "us3load_type" "3cycle")])
4061 (define_expand "zero_extendqihi2"
4062 [(set (match_operand:HI 0 "register_operand" "")
4063 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
4067 (define_insn "*zero_extendqihi2_insn"
4068 [(set (match_operand:HI 0 "register_operand" "=r,r")
4069 (zero_extend:HI (match_operand:QI 1 "input_operand" "r,m")))]
4070 "GET_CODE (operands[1]) != CONST_INT"
4074 [(set_attr "type" "*,load")
4075 (set_attr "us3load_type" "*,3cycle")])
4077 (define_expand "zero_extendqisi2"
4078 [(set (match_operand:SI 0 "register_operand" "")
4079 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
4083 (define_insn "*zero_extendqisi2_insn"
4084 [(set (match_operand:SI 0 "register_operand" "=r,r")
4085 (zero_extend:SI (match_operand:QI 1 "input_operand" "r,m")))]
4086 "GET_CODE (operands[1]) != CONST_INT"
4090 [(set_attr "type" "*,load")
4091 (set_attr "us3load_type" "*,3cycle")])
4093 (define_expand "zero_extendqidi2"
4094 [(set (match_operand:DI 0 "register_operand" "")
4095 (zero_extend:DI (match_operand:QI 1 "register_operand" "")))]
4099 (define_insn "*zero_extendqidi2_insn"
4100 [(set (match_operand:DI 0 "register_operand" "=r,r")
4101 (zero_extend:DI (match_operand:QI 1 "input_operand" "r,m")))]
4102 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
4106 [(set_attr "type" "*,load")
4107 (set_attr "us3load_type" "*,3cycle")])
4109 (define_expand "zero_extendhidi2"
4110 [(set (match_operand:DI 0 "register_operand" "")
4111 (zero_extend:DI (match_operand:HI 1 "register_operand" "")))]
4114 rtx temp = gen_reg_rtx (DImode);
4115 rtx shift_48 = GEN_INT (48);
4116 int op1_subbyte = 0;
4118 if (GET_CODE (operand1) == SUBREG)
4120 op1_subbyte = SUBREG_BYTE (operand1);
4121 op1_subbyte /= GET_MODE_SIZE (DImode);
4122 op1_subbyte *= GET_MODE_SIZE (DImode);
4123 operand1 = XEXP (operand1, 0);
4126 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
4128 emit_insn (gen_lshrdi3 (operand0, temp, shift_48));
4132 (define_insn "*zero_extendhidi2_insn"
4133 [(set (match_operand:DI 0 "register_operand" "=r")
4134 (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
4137 [(set_attr "type" "load")
4138 (set_attr "us3load_type" "3cycle")])
4141 ;; ??? Write truncdisi pattern using sra?
4143 (define_expand "zero_extendsidi2"
4144 [(set (match_operand:DI 0 "register_operand" "")
4145 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
4149 (define_insn "*zero_extendsidi2_insn_sp64"
4150 [(set (match_operand:DI 0 "register_operand" "=r,r")
4151 (zero_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
4152 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
4156 [(set_attr "type" "shift,load")])
4158 (define_insn_and_split "*zero_extendsidi2_insn_sp32"
4159 [(set (match_operand:DI 0 "register_operand" "=r")
4160 (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
4163 "&& reload_completed"
4164 [(set (match_dup 2) (match_dup 3))
4165 (set (match_dup 4) (match_dup 5))]
4169 dest1 = gen_highpart (SImode, operands[0]);
4170 dest2 = gen_lowpart (SImode, operands[0]);
4172 /* Swap the order in case of overlap. */
4173 if (REGNO (dest1) == REGNO (operands[1]))
4175 operands[2] = dest2;
4176 operands[3] = operands[1];
4177 operands[4] = dest1;
4178 operands[5] = const0_rtx;
4182 operands[2] = dest1;
4183 operands[3] = const0_rtx;
4184 operands[4] = dest2;
4185 operands[5] = operands[1];
4188 [(set_attr "length" "2")])
4190 ;; Simplify comparisons of extended values.
4192 (define_insn "*cmp_zero_extendqisi2"
4194 (compare:CC (zero_extend:SI (match_operand:QI 0 "register_operand" "r"))
4197 "andcc\t%0, 0xff, %%g0"
4198 [(set_attr "type" "compare")])
4200 (define_insn "*cmp_zero_qi"
4202 (compare:CC (match_operand:QI 0 "register_operand" "r")
4205 "andcc\t%0, 0xff, %%g0"
4206 [(set_attr "type" "compare")])
4208 (define_insn "*cmp_zero_extendqisi2_set"
4210 (compare:CC (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
4212 (set (match_operand:SI 0 "register_operand" "=r")
4213 (zero_extend:SI (match_dup 1)))]
4215 "andcc\t%1, 0xff, %0"
4216 [(set_attr "type" "compare")])
4218 (define_insn "*cmp_zero_extendqisi2_andcc_set"
4220 (compare:CC (and:SI (match_operand:SI 1 "register_operand" "r")
4223 (set (match_operand:SI 0 "register_operand" "=r")
4224 (zero_extend:SI (subreg:QI (match_dup 1) 0)))]
4226 "andcc\t%1, 0xff, %0"
4227 [(set_attr "type" "compare")])
4229 (define_insn "*cmp_zero_extendqidi2"
4231 (compare:CCX (zero_extend:DI (match_operand:QI 0 "register_operand" "r"))
4234 "andcc\t%0, 0xff, %%g0"
4235 [(set_attr "type" "compare")])
4237 (define_insn "*cmp_zero_qi_sp64"
4239 (compare:CCX (match_operand:QI 0 "register_operand" "r")
4242 "andcc\t%0, 0xff, %%g0"
4243 [(set_attr "type" "compare")])
4245 (define_insn "*cmp_zero_extendqidi2_set"
4247 (compare:CCX (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
4249 (set (match_operand:DI 0 "register_operand" "=r")
4250 (zero_extend:DI (match_dup 1)))]
4252 "andcc\t%1, 0xff, %0"
4253 [(set_attr "type" "compare")])
4255 (define_insn "*cmp_zero_extendqidi2_andcc_set"
4257 (compare:CCX (and:DI (match_operand:DI 1 "register_operand" "r")
4260 (set (match_operand:DI 0 "register_operand" "=r")
4261 (zero_extend:DI (subreg:QI (match_dup 1) 0)))]
4263 "andcc\t%1, 0xff, %0"
4264 [(set_attr "type" "compare")])
4266 ;; Similarly, handle {SI,DI}->QI mode truncation followed by a compare.
4268 (define_insn "*cmp_siqi_trunc"
4270 (compare:CC (subreg:QI (match_operand:SI 0 "register_operand" "r") 3)
4273 "andcc\t%0, 0xff, %%g0"
4274 [(set_attr "type" "compare")])
4276 (define_insn "*cmp_siqi_trunc_set"
4278 (compare:CC (subreg:QI (match_operand:SI 1 "register_operand" "r") 3)
4280 (set (match_operand:QI 0 "register_operand" "=r")
4281 (subreg:QI (match_dup 1) 3))]
4283 "andcc\t%1, 0xff, %0"
4284 [(set_attr "type" "compare")])
4286 (define_insn "*cmp_diqi_trunc"
4288 (compare:CC (subreg:QI (match_operand:DI 0 "register_operand" "r") 7)
4291 "andcc\t%0, 0xff, %%g0"
4292 [(set_attr "type" "compare")])
4294 (define_insn "*cmp_diqi_trunc_set"
4296 (compare:CC (subreg:QI (match_operand:DI 1 "register_operand" "r") 7)
4298 (set (match_operand:QI 0 "register_operand" "=r")
4299 (subreg:QI (match_dup 1) 7))]
4301 "andcc\t%1, 0xff, %0"
4302 [(set_attr "type" "compare")])
4304 ;;- sign extension instructions
4306 ;; These patterns originally accepted general_operands, however, slightly
4307 ;; better code is generated by only accepting register_operands, and then
4308 ;; letting combine generate the lds[hb] insns.
4310 (define_expand "extendhisi2"
4311 [(set (match_operand:SI 0 "register_operand" "")
4312 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
4315 rtx temp = gen_reg_rtx (SImode);
4316 rtx shift_16 = GEN_INT (16);
4317 int op1_subbyte = 0;
4319 if (GET_CODE (operand1) == SUBREG)
4321 op1_subbyte = SUBREG_BYTE (operand1);
4322 op1_subbyte /= GET_MODE_SIZE (SImode);
4323 op1_subbyte *= GET_MODE_SIZE (SImode);
4324 operand1 = XEXP (operand1, 0);
4327 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4329 emit_insn (gen_ashrsi3 (operand0, temp, shift_16));
4333 (define_insn "*sign_extendhisi2_insn"
4334 [(set (match_operand:SI 0 "register_operand" "=r")
4335 (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
4338 [(set_attr "type" "sload")
4339 (set_attr "us3load_type" "3cycle")])
4341 (define_expand "extendqihi2"
4342 [(set (match_operand:HI 0 "register_operand" "")
4343 (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
4346 rtx temp = gen_reg_rtx (SImode);
4347 rtx shift_24 = GEN_INT (24);
4348 int op1_subbyte = 0;
4349 int op0_subbyte = 0;
4351 if (GET_CODE (operand1) == SUBREG)
4353 op1_subbyte = SUBREG_BYTE (operand1);
4354 op1_subbyte /= GET_MODE_SIZE (SImode);
4355 op1_subbyte *= GET_MODE_SIZE (SImode);
4356 operand1 = XEXP (operand1, 0);
4358 if (GET_CODE (operand0) == SUBREG)
4360 op0_subbyte = SUBREG_BYTE (operand0);
4361 op0_subbyte /= GET_MODE_SIZE (SImode);
4362 op0_subbyte *= GET_MODE_SIZE (SImode);
4363 operand0 = XEXP (operand0, 0);
4365 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4367 if (GET_MODE (operand0) != SImode)
4368 operand0 = gen_rtx_SUBREG (SImode, operand0, op0_subbyte);
4369 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
4373 (define_insn "*sign_extendqihi2_insn"
4374 [(set (match_operand:HI 0 "register_operand" "=r")
4375 (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
4378 [(set_attr "type" "sload")
4379 (set_attr "us3load_type" "3cycle")])
4381 (define_expand "extendqisi2"
4382 [(set (match_operand:SI 0 "register_operand" "")
4383 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
4386 rtx temp = gen_reg_rtx (SImode);
4387 rtx shift_24 = GEN_INT (24);
4388 int op1_subbyte = 0;
4390 if (GET_CODE (operand1) == SUBREG)
4392 op1_subbyte = SUBREG_BYTE (operand1);
4393 op1_subbyte /= GET_MODE_SIZE (SImode);
4394 op1_subbyte *= GET_MODE_SIZE (SImode);
4395 operand1 = XEXP (operand1, 0);
4398 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4400 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
4404 (define_insn "*sign_extendqisi2_insn"
4405 [(set (match_operand:SI 0 "register_operand" "=r")
4406 (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
4409 [(set_attr "type" "sload")
4410 (set_attr "us3load_type" "3cycle")])
4412 (define_expand "extendqidi2"
4413 [(set (match_operand:DI 0 "register_operand" "")
4414 (sign_extend:DI (match_operand:QI 1 "register_operand" "")))]
4417 rtx temp = gen_reg_rtx (DImode);
4418 rtx shift_56 = GEN_INT (56);
4419 int op1_subbyte = 0;
4421 if (GET_CODE (operand1) == SUBREG)
4423 op1_subbyte = SUBREG_BYTE (operand1);
4424 op1_subbyte /= GET_MODE_SIZE (DImode);
4425 op1_subbyte *= GET_MODE_SIZE (DImode);
4426 operand1 = XEXP (operand1, 0);
4429 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
4431 emit_insn (gen_ashrdi3 (operand0, temp, shift_56));
4435 (define_insn "*sign_extendqidi2_insn"
4436 [(set (match_operand:DI 0 "register_operand" "=r")
4437 (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
4440 [(set_attr "type" "sload")
4441 (set_attr "us3load_type" "3cycle")])
4443 (define_expand "extendhidi2"
4444 [(set (match_operand:DI 0 "register_operand" "")
4445 (sign_extend:DI (match_operand:HI 1 "register_operand" "")))]
4448 rtx temp = gen_reg_rtx (DImode);
4449 rtx shift_48 = GEN_INT (48);
4450 int op1_subbyte = 0;
4452 if (GET_CODE (operand1) == SUBREG)
4454 op1_subbyte = SUBREG_BYTE (operand1);
4455 op1_subbyte /= GET_MODE_SIZE (DImode);
4456 op1_subbyte *= GET_MODE_SIZE (DImode);
4457 operand1 = XEXP (operand1, 0);
4460 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
4462 emit_insn (gen_ashrdi3 (operand0, temp, shift_48));
4466 (define_insn "*sign_extendhidi2_insn"
4467 [(set (match_operand:DI 0 "register_operand" "=r")
4468 (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
4471 [(set_attr "type" "sload")
4472 (set_attr "us3load_type" "3cycle")])
4474 (define_expand "extendsidi2"
4475 [(set (match_operand:DI 0 "register_operand" "")
4476 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
4480 (define_insn "*sign_extendsidi2_insn"
4481 [(set (match_operand:DI 0 "register_operand" "=r,r")
4482 (sign_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
4487 [(set_attr "type" "shift,sload")
4488 (set_attr "us3load_type" "*,3cycle")])
4490 ;; Special pattern for optimizing bit-field compares. This is needed
4491 ;; because combine uses this as a canonical form.
4493 (define_insn "*cmp_zero_extract"
4496 (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
4497 (match_operand:SI 1 "small_int_or_double" "n")
4498 (match_operand:SI 2 "small_int_or_double" "n"))
4500 "(GET_CODE (operands[2]) == CONST_INT
4501 && INTVAL (operands[2]) > 19)
4502 || (GET_CODE (operands[2]) == CONST_DOUBLE
4503 && CONST_DOUBLE_LOW (operands[2]) > 19)"
4505 int len = (GET_CODE (operands[1]) == CONST_INT
4506 ? INTVAL (operands[1])
4507 : CONST_DOUBLE_LOW (operands[1]));
4509 (GET_CODE (operands[2]) == CONST_INT
4510 ? INTVAL (operands[2])
4511 : CONST_DOUBLE_LOW (operands[2])) - len;
4512 HOST_WIDE_INT mask = ((1 << len) - 1) << pos;
4514 operands[1] = GEN_INT (mask);
4515 return "andcc\t%0, %1, %%g0";
4517 [(set_attr "type" "compare")])
4519 (define_insn "*cmp_zero_extract_sp64"
4522 (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
4523 (match_operand:SI 1 "small_int_or_double" "n")
4524 (match_operand:SI 2 "small_int_or_double" "n"))
4527 && ((GET_CODE (operands[2]) == CONST_INT
4528 && INTVAL (operands[2]) > 51)
4529 || (GET_CODE (operands[2]) == CONST_DOUBLE
4530 && CONST_DOUBLE_LOW (operands[2]) > 51))"
4532 int len = (GET_CODE (operands[1]) == CONST_INT
4533 ? INTVAL (operands[1])
4534 : CONST_DOUBLE_LOW (operands[1]));
4536 (GET_CODE (operands[2]) == CONST_INT
4537 ? INTVAL (operands[2])
4538 : CONST_DOUBLE_LOW (operands[2])) - len;
4539 HOST_WIDE_INT mask = (((unsigned HOST_WIDE_INT) 1 << len) - 1) << pos;
4541 operands[1] = GEN_INT (mask);
4542 return "andcc\t%0, %1, %%g0";
4544 [(set_attr "type" "compare")])
4546 ;; Conversions between float, double and long double.
4548 (define_insn "extendsfdf2"
4549 [(set (match_operand:DF 0 "register_operand" "=e")
4551 (match_operand:SF 1 "register_operand" "f")))]
4554 [(set_attr "type" "fp")
4555 (set_attr "fptype" "double")])
4557 (define_expand "extendsftf2"
4558 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4560 (match_operand:SF 1 "register_operand" "")))]
4561 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4562 "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
4564 (define_insn "*extendsftf2_hq"
4565 [(set (match_operand:TF 0 "register_operand" "=e")
4567 (match_operand:SF 1 "register_operand" "f")))]
4568 "TARGET_FPU && TARGET_HARD_QUAD"
4570 [(set_attr "type" "fp")])
4572 (define_expand "extenddftf2"
4573 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4575 (match_operand:DF 1 "register_operand" "")))]
4576 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4577 "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
4579 (define_insn "*extenddftf2_hq"
4580 [(set (match_operand:TF 0 "register_operand" "=e")
4582 (match_operand:DF 1 "register_operand" "e")))]
4583 "TARGET_FPU && TARGET_HARD_QUAD"
4585 [(set_attr "type" "fp")])
4587 (define_insn "truncdfsf2"
4588 [(set (match_operand:SF 0 "register_operand" "=f")
4590 (match_operand:DF 1 "register_operand" "e")))]
4593 [(set_attr "type" "fp")
4594 (set_attr "fptype" "double")])
4596 (define_expand "trunctfsf2"
4597 [(set (match_operand:SF 0 "register_operand" "")
4599 (match_operand:TF 1 "general_operand" "")))]
4600 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4601 "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
4603 (define_insn "*trunctfsf2_hq"
4604 [(set (match_operand:SF 0 "register_operand" "=f")
4606 (match_operand:TF 1 "register_operand" "e")))]
4607 "TARGET_FPU && TARGET_HARD_QUAD"
4609 [(set_attr "type" "fp")])
4611 (define_expand "trunctfdf2"
4612 [(set (match_operand:DF 0 "register_operand" "")
4614 (match_operand:TF 1 "general_operand" "")))]
4615 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4616 "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
4618 (define_insn "*trunctfdf2_hq"
4619 [(set (match_operand:DF 0 "register_operand" "=e")
4621 (match_operand:TF 1 "register_operand" "e")))]
4622 "TARGET_FPU && TARGET_HARD_QUAD"
4624 [(set_attr "type" "fp")])
4626 ;; Conversion between fixed point and floating point.
4628 (define_insn "floatsisf2"
4629 [(set (match_operand:SF 0 "register_operand" "=f")
4630 (float:SF (match_operand:SI 1 "register_operand" "f")))]
4633 [(set_attr "type" "fp")
4634 (set_attr "fptype" "double")])
4636 (define_insn "floatsidf2"
4637 [(set (match_operand:DF 0 "register_operand" "=e")
4638 (float:DF (match_operand:SI 1 "register_operand" "f")))]
4641 [(set_attr "type" "fp")
4642 (set_attr "fptype" "double")])
4644 (define_expand "floatsitf2"
4645 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4646 (float:TF (match_operand:SI 1 "register_operand" "")))]
4647 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4648 "emit_tfmode_cvt (FLOAT, operands); DONE;")
4650 (define_insn "*floatsitf2_hq"
4651 [(set (match_operand:TF 0 "register_operand" "=e")
4652 (float:TF (match_operand:SI 1 "register_operand" "f")))]
4653 "TARGET_FPU && TARGET_HARD_QUAD"
4655 [(set_attr "type" "fp")])
4657 (define_expand "floatunssitf2"
4658 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4659 (unsigned_float:TF (match_operand:SI 1 "register_operand" "")))]
4660 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4661 "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
4663 ;; Now the same for 64 bit sources.
4665 (define_insn "floatdisf2"
4666 [(set (match_operand:SF 0 "register_operand" "=f")
4667 (float:SF (match_operand:DI 1 "register_operand" "e")))]
4668 "TARGET_V9 && TARGET_FPU"
4670 [(set_attr "type" "fp")
4671 (set_attr "fptype" "double")])
4673 (define_expand "floatunsdisf2"
4674 [(use (match_operand:SF 0 "register_operand" ""))
4675 (use (match_operand:DI 1 "general_operand" ""))]
4676 "TARGET_ARCH64 && TARGET_FPU"
4677 "sparc_emit_floatunsdi (operands, SFmode); DONE;")
4679 (define_insn "floatdidf2"
4680 [(set (match_operand:DF 0 "register_operand" "=e")
4681 (float:DF (match_operand:DI 1 "register_operand" "e")))]
4682 "TARGET_V9 && TARGET_FPU"
4684 [(set_attr "type" "fp")
4685 (set_attr "fptype" "double")])
4687 (define_expand "floatunsdidf2"
4688 [(use (match_operand:DF 0 "register_operand" ""))
4689 (use (match_operand:DI 1 "general_operand" ""))]
4690 "TARGET_ARCH64 && TARGET_FPU"
4691 "sparc_emit_floatunsdi (operands, DFmode); DONE;")
4693 (define_expand "floatditf2"
4694 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4695 (float:TF (match_operand:DI 1 "register_operand" "")))]
4696 "TARGET_FPU && TARGET_V9 && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4697 "emit_tfmode_cvt (FLOAT, operands); DONE;")
4699 (define_insn "*floatditf2_hq"
4700 [(set (match_operand:TF 0 "register_operand" "=e")
4701 (float:TF (match_operand:DI 1 "register_operand" "e")))]
4702 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
4704 [(set_attr "type" "fp")])
4706 (define_expand "floatunsditf2"
4707 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4708 (unsigned_float:TF (match_operand:DI 1 "register_operand" "")))]
4709 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4710 "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
4712 ;; Convert a float to an actual integer.
4713 ;; Truncation is performed as part of the conversion.
4715 (define_insn "fix_truncsfsi2"
4716 [(set (match_operand:SI 0 "register_operand" "=f")
4717 (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
4720 [(set_attr "type" "fp")
4721 (set_attr "fptype" "double")])
4723 (define_insn "fix_truncdfsi2"
4724 [(set (match_operand:SI 0 "register_operand" "=f")
4725 (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
4728 [(set_attr "type" "fp")
4729 (set_attr "fptype" "double")])
4731 (define_expand "fix_trunctfsi2"
4732 [(set (match_operand:SI 0 "register_operand" "")
4733 (fix:SI (match_operand:TF 1 "general_operand" "")))]
4734 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4735 "emit_tfmode_cvt (FIX, operands); DONE;")
4737 (define_insn "*fix_trunctfsi2_hq"
4738 [(set (match_operand:SI 0 "register_operand" "=f")
4739 (fix:SI (match_operand:TF 1 "register_operand" "e")))]
4740 "TARGET_FPU && TARGET_HARD_QUAD"
4742 [(set_attr "type" "fp")])
4744 (define_expand "fixuns_trunctfsi2"
4745 [(set (match_operand:SI 0 "register_operand" "")
4746 (unsigned_fix:SI (match_operand:TF 1 "general_operand" "")))]
4747 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4748 "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
4750 ;; Now the same, for V9 targets
4752 (define_insn "fix_truncsfdi2"
4753 [(set (match_operand:DI 0 "register_operand" "=e")
4754 (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
4755 "TARGET_V9 && TARGET_FPU"
4757 [(set_attr "type" "fp")
4758 (set_attr "fptype" "double")])
4760 (define_expand "fixuns_truncsfdi2"
4761 [(use (match_operand:DI 0 "register_operand" ""))
4762 (use (match_operand:SF 1 "general_operand" ""))]
4763 "TARGET_ARCH64 && TARGET_FPU"
4764 "sparc_emit_fixunsdi (operands, SFmode); DONE;")
4766 (define_insn "fix_truncdfdi2"
4767 [(set (match_operand:DI 0 "register_operand" "=e")
4768 (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
4769 "TARGET_V9 && TARGET_FPU"
4771 [(set_attr "type" "fp")
4772 (set_attr "fptype" "double")])
4774 (define_expand "fixuns_truncdfdi2"
4775 [(use (match_operand:DI 0 "register_operand" ""))
4776 (use (match_operand:DF 1 "general_operand" ""))]
4777 "TARGET_ARCH64 && TARGET_FPU"
4778 "sparc_emit_fixunsdi (operands, DFmode); DONE;")
4780 (define_expand "fix_trunctfdi2"
4781 [(set (match_operand:DI 0 "register_operand" "")
4782 (fix:DI (match_operand:TF 1 "general_operand" "")))]
4783 "TARGET_V9 && TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4784 "emit_tfmode_cvt (FIX, operands); DONE;")
4786 (define_insn "*fix_trunctfdi2_hq"
4787 [(set (match_operand:DI 0 "register_operand" "=e")
4788 (fix:DI (match_operand:TF 1 "register_operand" "e")))]
4789 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
4791 [(set_attr "type" "fp")])
4793 (define_expand "fixuns_trunctfdi2"
4794 [(set (match_operand:DI 0 "register_operand" "")
4795 (unsigned_fix:DI (match_operand:TF 1 "general_operand" "")))]
4796 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4797 "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
4799 ;;- arithmetic instructions
4801 (define_expand "adddi3"
4802 [(set (match_operand:DI 0 "register_operand" "")
4803 (plus:DI (match_operand:DI 1 "register_operand" "")
4804 (match_operand:DI 2 "arith_double_add_operand" "")))]
4807 if (! TARGET_ARCH64)
4809 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
4810 gen_rtx_SET (VOIDmode, operands[0],
4811 gen_rtx_PLUS (DImode, operands[1],
4813 gen_rtx_CLOBBER (VOIDmode,
4814 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
4819 (define_insn_and_split "adddi3_insn_sp32"
4820 [(set (match_operand:DI 0 "register_operand" "=r")
4821 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
4822 (match_operand:DI 2 "arith_double_operand" "rHI")))
4823 (clobber (reg:CC 100))]
4826 "&& reload_completed"
4827 [(parallel [(set (reg:CC_NOOV 100)
4828 (compare:CC_NOOV (plus:SI (match_dup 4)
4832 (plus:SI (match_dup 4) (match_dup 5)))])
4834 (plus:SI (plus:SI (match_dup 7)
4836 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4838 operands[3] = gen_lowpart (SImode, operands[0]);
4839 operands[4] = gen_lowpart (SImode, operands[1]);
4840 operands[5] = gen_lowpart (SImode, operands[2]);
4841 operands[6] = gen_highpart (SImode, operands[0]);
4842 operands[7] = gen_highpart_mode (SImode, DImode, operands[1]);
4843 #if HOST_BITS_PER_WIDE_INT == 32
4844 if (GET_CODE (operands[2]) == CONST_INT)
4846 if (INTVAL (operands[2]) < 0)
4847 operands[8] = constm1_rtx;
4849 operands[8] = const0_rtx;
4853 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
4855 [(set_attr "length" "2")])
4858 [(set (match_operand:DI 0 "register_operand" "")
4859 (minus:DI (match_operand:DI 1 "arith_double_operand" "")
4860 (match_operand:DI 2 "arith_double_operand" "")))
4861 (clobber (reg:CC 100))]
4862 "! TARGET_ARCH64 && reload_completed"
4863 [(parallel [(set (reg:CC_NOOV 100)
4864 (compare:CC_NOOV (minus:SI (match_dup 4)
4868 (minus:SI (match_dup 4) (match_dup 5)))])
4870 (minus:SI (minus:SI (match_dup 7)
4872 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4874 operands[3] = gen_lowpart (SImode, operands[0]);
4875 operands[4] = gen_lowpart (SImode, operands[1]);
4876 operands[5] = gen_lowpart (SImode, operands[2]);
4877 operands[6] = gen_highpart (SImode, operands[0]);
4878 operands[7] = gen_highpart (SImode, operands[1]);
4879 #if HOST_BITS_PER_WIDE_INT == 32
4880 if (GET_CODE (operands[2]) == CONST_INT)
4882 if (INTVAL (operands[2]) < 0)
4883 operands[8] = constm1_rtx;
4885 operands[8] = const0_rtx;
4889 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
4892 ;; LTU here means "carry set"
4894 [(set (match_operand:SI 0 "register_operand" "=r")
4895 (plus:SI (plus:SI (match_operand:SI 1 "arith_operand" "%r")
4896 (match_operand:SI 2 "arith_operand" "rI"))
4897 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4900 [(set_attr "type" "ialuX")])
4902 (define_insn_and_split "*addx_extend_sp32"
4903 [(set (match_operand:DI 0 "register_operand" "=r")
4904 (zero_extend:DI (plus:SI (plus:SI
4905 (match_operand:SI 1 "reg_or_0_operand" "%rJ")
4906 (match_operand:SI 2 "arith_operand" "rI"))
4907 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4910 "&& reload_completed"
4911 [(set (match_dup 3) (plus:SI (plus:SI (match_dup 1) (match_dup 2))
4912 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
4913 (set (match_dup 4) (const_int 0))]
4914 "operands[3] = gen_lowpart (SImode, operands[0]);
4915 operands[4] = gen_highpart_mode (SImode, DImode, operands[1]);"
4916 [(set_attr "length" "2")])
4918 (define_insn "*addx_extend_sp64"
4919 [(set (match_operand:DI 0 "register_operand" "=r")
4920 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
4921 (match_operand:SI 2 "arith_operand" "rI"))
4922 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4925 [(set_attr "type" "ialuX")])
4928 [(set (match_operand:SI 0 "register_operand" "=r")
4929 (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
4930 (match_operand:SI 2 "arith_operand" "rI"))
4931 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4934 [(set_attr "type" "ialuX")])
4936 (define_insn "*subx_extend_sp64"
4937 [(set (match_operand:DI 0 "register_operand" "=r")
4938 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
4939 (match_operand:SI 2 "arith_operand" "rI"))
4940 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4943 [(set_attr "type" "ialuX")])
4945 (define_insn_and_split "*subx_extend"
4946 [(set (match_operand:DI 0 "register_operand" "=r")
4947 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
4948 (match_operand:SI 2 "arith_operand" "rI"))
4949 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4952 "&& reload_completed"
4953 [(set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 2))
4954 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
4955 (set (match_dup 4) (const_int 0))]
4956 "operands[3] = gen_lowpart (SImode, operands[0]);
4957 operands[4] = gen_highpart (SImode, operands[0]);"
4958 [(set_attr "length" "2")])
4960 (define_insn_and_split ""
4961 [(set (match_operand:DI 0 "register_operand" "=r")
4962 (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4963 (match_operand:DI 2 "register_operand" "r")))
4964 (clobber (reg:CC 100))]
4967 "&& reload_completed"
4968 [(parallel [(set (reg:CC_NOOV 100)
4969 (compare:CC_NOOV (plus:SI (match_dup 3) (match_dup 1))
4971 (set (match_dup 5) (plus:SI (match_dup 3) (match_dup 1)))])
4973 (plus:SI (plus:SI (match_dup 4) (const_int 0))
4974 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4975 "operands[3] = gen_lowpart (SImode, operands[2]);
4976 operands[4] = gen_highpart (SImode, operands[2]);
4977 operands[5] = gen_lowpart (SImode, operands[0]);
4978 operands[6] = gen_highpart (SImode, operands[0]);"
4979 [(set_attr "length" "2")])
4981 (define_insn "*adddi3_sp64"
4982 [(set (match_operand:DI 0 "register_operand" "=r,r")
4983 (plus:DI (match_operand:DI 1 "register_operand" "%r,r")
4984 (match_operand:DI 2 "arith_double_add_operand" "rHI,O")))]
4990 (define_insn "addsi3"
4991 [(set (match_operand:SI 0 "register_operand" "=r,r,d")
4992 (plus:SI (match_operand:SI 1 "register_operand" "%r,r,d")
4993 (match_operand:SI 2 "arith_add_operand" "rI,O,d")))]
4998 fpadd32s\t%1, %2, %0"
4999 [(set_attr "type" "*,*,fga")])
5001 (define_insn "*cmp_cc_plus"
5002 [(set (reg:CC_NOOV 100)
5003 (compare:CC_NOOV (plus:SI (match_operand:SI 0 "arith_operand" "%r")
5004 (match_operand:SI 1 "arith_operand" "rI"))
5007 "addcc\t%0, %1, %%g0"
5008 [(set_attr "type" "compare")])
5010 (define_insn "*cmp_ccx_plus"
5011 [(set (reg:CCX_NOOV 100)
5012 (compare:CCX_NOOV (plus:DI (match_operand:DI 0 "arith_double_operand" "%r")
5013 (match_operand:DI 1 "arith_double_operand" "rHI"))
5016 "addcc\t%0, %1, %%g0"
5017 [(set_attr "type" "compare")])
5019 (define_insn "*cmp_cc_plus_set"
5020 [(set (reg:CC_NOOV 100)
5021 (compare:CC_NOOV (plus:SI (match_operand:SI 1 "arith_operand" "%r")
5022 (match_operand:SI 2 "arith_operand" "rI"))
5024 (set (match_operand:SI 0 "register_operand" "=r")
5025 (plus:SI (match_dup 1) (match_dup 2)))]
5028 [(set_attr "type" "compare")])
5030 (define_insn "*cmp_ccx_plus_set"
5031 [(set (reg:CCX_NOOV 100)
5032 (compare:CCX_NOOV (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
5033 (match_operand:DI 2 "arith_double_operand" "rHI"))
5035 (set (match_operand:DI 0 "register_operand" "=r")
5036 (plus:DI (match_dup 1) (match_dup 2)))]
5039 [(set_attr "type" "compare")])
5041 (define_expand "subdi3"
5042 [(set (match_operand:DI 0 "register_operand" "")
5043 (minus:DI (match_operand:DI 1 "register_operand" "")
5044 (match_operand:DI 2 "arith_double_add_operand" "")))]
5047 if (! TARGET_ARCH64)
5049 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
5050 gen_rtx_SET (VOIDmode, operands[0],
5051 gen_rtx_MINUS (DImode, operands[1],
5053 gen_rtx_CLOBBER (VOIDmode,
5054 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
5059 (define_insn_and_split "*subdi3_sp32"
5060 [(set (match_operand:DI 0 "register_operand" "=r")
5061 (minus:DI (match_operand:DI 1 "register_operand" "r")
5062 (match_operand:DI 2 "arith_double_operand" "rHI")))
5063 (clobber (reg:CC 100))]
5066 "&& reload_completed
5067 && (GET_CODE (operands[2]) == CONST_INT
5068 || GET_CODE (operands[2]) == CONST_DOUBLE)"
5069 [(clobber (const_int 0))]
5073 highp = gen_highpart_mode (SImode, DImode, operands[2]);
5074 lowp = gen_lowpart (SImode, operands[2]);
5075 if ((lowp == const0_rtx)
5076 && (operands[0] == operands[1]))
5078 emit_insn (gen_rtx_SET (VOIDmode,
5079 gen_highpart (SImode, operands[0]),
5080 gen_rtx_MINUS (SImode,
5081 gen_highpart_mode (SImode, DImode,
5087 emit_insn (gen_cmp_minus_cc_set (gen_lowpart (SImode, operands[0]),
5088 gen_lowpart (SImode, operands[1]),
5090 emit_insn (gen_subx (gen_highpart (SImode, operands[0]),
5091 gen_highpart_mode (SImode, DImode, operands[1]),
5096 [(set_attr "length" "2")])
5099 [(set (match_operand:DI 0 "register_operand" "")
5100 (minus:DI (match_operand:DI 1 "register_operand" "")
5101 (match_operand:DI 2 "register_operand" "")))
5102 (clobber (reg:CC 100))]
5104 && reload_completed"
5105 [(clobber (const_int 0))]
5107 emit_insn (gen_cmp_minus_cc_set (gen_lowpart (SImode, operands[0]),
5108 gen_lowpart (SImode, operands[1]),
5109 gen_lowpart (SImode, operands[2])));
5110 emit_insn (gen_subx (gen_highpart (SImode, operands[0]),
5111 gen_highpart (SImode, operands[1]),
5112 gen_highpart (SImode, operands[2])));
5116 (define_insn_and_split ""
5117 [(set (match_operand:DI 0 "register_operand" "=r")
5118 (minus:DI (match_operand:DI 1 "register_operand" "r")
5119 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))
5120 (clobber (reg:CC 100))]
5123 "&& reload_completed"
5124 [(parallel [(set (reg:CC_NOOV 100)
5125 (compare:CC_NOOV (minus:SI (match_dup 3) (match_dup 2))
5127 (set (match_dup 5) (minus:SI (match_dup 3) (match_dup 2)))])
5129 (minus:SI (minus:SI (match_dup 4) (const_int 0))
5130 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5131 "operands[3] = gen_lowpart (SImode, operands[1]);
5132 operands[4] = gen_highpart (SImode, operands[1]);
5133 operands[5] = gen_lowpart (SImode, operands[0]);
5134 operands[6] = gen_highpart (SImode, operands[0]);"
5135 [(set_attr "length" "2")])
5137 (define_insn "*subdi3_sp64"
5138 [(set (match_operand:DI 0 "register_operand" "=r,r")
5139 (minus:DI (match_operand:DI 1 "register_operand" "r,r")
5140 (match_operand:DI 2 "arith_double_add_operand" "rHI,O")))]
5146 (define_insn "subsi3"
5147 [(set (match_operand:SI 0 "register_operand" "=r,r,d")
5148 (minus:SI (match_operand:SI 1 "register_operand" "r,r,d")
5149 (match_operand:SI 2 "arith_add_operand" "rI,O,d")))]
5154 fpsub32s\t%1, %2, %0"
5155 [(set_attr "type" "*,*,fga")])
5157 (define_insn "*cmp_minus_cc"
5158 [(set (reg:CC_NOOV 100)
5159 (compare:CC_NOOV (minus:SI (match_operand:SI 0 "reg_or_0_operand" "rJ")
5160 (match_operand:SI 1 "arith_operand" "rI"))
5163 "subcc\t%r0, %1, %%g0"
5164 [(set_attr "type" "compare")])
5166 (define_insn "*cmp_minus_ccx"
5167 [(set (reg:CCX_NOOV 100)
5168 (compare:CCX_NOOV (minus:DI (match_operand:DI 0 "register_operand" "r")
5169 (match_operand:DI 1 "arith_double_operand" "rHI"))
5172 "subcc\t%0, %1, %%g0"
5173 [(set_attr "type" "compare")])
5175 (define_insn "cmp_minus_cc_set"
5176 [(set (reg:CC_NOOV 100)
5177 (compare:CC_NOOV (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5178 (match_operand:SI 2 "arith_operand" "rI"))
5180 (set (match_operand:SI 0 "register_operand" "=r")
5181 (minus:SI (match_dup 1) (match_dup 2)))]
5183 "subcc\t%r1, %2, %0"
5184 [(set_attr "type" "compare")])
5186 (define_insn "*cmp_minus_ccx_set"
5187 [(set (reg:CCX_NOOV 100)
5188 (compare:CCX_NOOV (minus:DI (match_operand:DI 1 "register_operand" "r")
5189 (match_operand:DI 2 "arith_double_operand" "rHI"))
5191 (set (match_operand:DI 0 "register_operand" "=r")
5192 (minus:DI (match_dup 1) (match_dup 2)))]
5195 [(set_attr "type" "compare")])
5197 ;; Integer Multiply/Divide.
5199 ;; The 32 bit multiply/divide instructions are deprecated on v9, but at
5200 ;; least in UltraSPARC I, II and IIi it is a win tick-wise.
5202 (define_insn "mulsi3"
5203 [(set (match_operand:SI 0 "register_operand" "=r")
5204 (mult:SI (match_operand:SI 1 "arith_operand" "%r")
5205 (match_operand:SI 2 "arith_operand" "rI")))]
5208 [(set_attr "type" "imul")])
5210 (define_expand "muldi3"
5211 [(set (match_operand:DI 0 "register_operand" "=r")
5212 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r")
5213 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5214 "TARGET_ARCH64 || TARGET_V8PLUS"
5218 emit_insn (gen_muldi3_v8plus (operands[0], operands[1], operands[2]));
5223 (define_insn "*muldi3_sp64"
5224 [(set (match_operand:DI 0 "register_operand" "=r")
5225 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r")
5226 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5229 [(set_attr "type" "imul")])
5231 ;; V8plus wide multiply.
5233 (define_insn "muldi3_v8plus"
5234 [(set (match_operand:DI 0 "register_operand" "=r,h")
5235 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r,0")
5236 (match_operand:DI 2 "arith_double_operand" "rI,rI")))
5237 (clobber (match_scratch:SI 3 "=&h,X"))
5238 (clobber (match_scratch:SI 4 "=&h,X"))]
5241 if (sparc_check_64 (operands[1], insn) <= 0)
5242 output_asm_insn ("srl\t%L1, 0, %L1", operands);
5243 if (which_alternative == 1)
5244 output_asm_insn ("sllx\t%H1, 32, %H1", operands);
5245 if (GET_CODE (operands[2]) == CONST_INT)
5247 if (which_alternative == 1)
5248 return "or\t%L1, %H1, %H1\n\tmulx\t%H1, %2, %L0\;srlx\t%L0, 32, %H0";
5250 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";
5252 else if (rtx_equal_p (operands[1], operands[2]))
5254 if (which_alternative == 1)
5255 return "or\t%L1, %H1, %H1\n\tmulx\t%H1, %H1, %L0\;srlx\t%L0, 32, %H0";
5257 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";
5259 if (sparc_check_64 (operands[2], insn) <= 0)
5260 output_asm_insn ("srl\t%L2, 0, %L2", operands);
5261 if (which_alternative == 1)
5262 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";
5264 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";
5266 [(set_attr "type" "multi")
5267 (set_attr "length" "9,8")])
5269 (define_insn "*cmp_mul_set"
5271 (compare:CC (mult:SI (match_operand:SI 1 "arith_operand" "%r")
5272 (match_operand:SI 2 "arith_operand" "rI"))
5274 (set (match_operand:SI 0 "register_operand" "=r")
5275 (mult:SI (match_dup 1) (match_dup 2)))]
5276 "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS"
5277 "smulcc\t%1, %2, %0"
5278 [(set_attr "type" "imul")])
5280 (define_expand "mulsidi3"
5281 [(set (match_operand:DI 0 "register_operand" "")
5282 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
5283 (sign_extend:DI (match_operand:SI 2 "arith_operand" ""))))]
5286 if (CONSTANT_P (operands[2]))
5289 emit_insn (gen_const_mulsidi3_v8plus (operands[0], operands[1],
5291 else if (TARGET_ARCH32)
5292 emit_insn (gen_const_mulsidi3_sp32 (operands[0], operands[1],
5295 emit_insn (gen_const_mulsidi3_sp64 (operands[0], operands[1],
5301 emit_insn (gen_mulsidi3_v8plus (operands[0], operands[1], operands[2]));
5306 ;; V9 puts the 64 bit product in a 64 bit register. Only out or global
5307 ;; registers can hold 64 bit values in the V8plus environment.
5309 (define_insn "mulsidi3_v8plus"
5310 [(set (match_operand:DI 0 "register_operand" "=h,r")
5311 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5312 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
5313 (clobber (match_scratch:SI 3 "=X,&h"))]
5316 smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
5317 smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
5318 [(set_attr "type" "multi")
5319 (set_attr "length" "2,3")])
5322 (define_insn "const_mulsidi3_v8plus"
5323 [(set (match_operand:DI 0 "register_operand" "=h,r")
5324 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5325 (match_operand:DI 2 "small_int" "I,I")))
5326 (clobber (match_scratch:SI 3 "=X,&h"))]
5329 smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
5330 smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
5331 [(set_attr "type" "multi")
5332 (set_attr "length" "2,3")])
5335 (define_insn "*mulsidi3_sp32"
5336 [(set (match_operand:DI 0 "register_operand" "=r")
5337 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5338 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
5341 return TARGET_SPARCLET
5342 ? "smuld\t%1, %2, %L0"
5343 : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
5346 (if_then_else (eq_attr "isa" "sparclet")
5347 (const_string "imul") (const_string "multi")))
5348 (set (attr "length")
5349 (if_then_else (eq_attr "isa" "sparclet")
5350 (const_int 1) (const_int 2)))])
5352 (define_insn "*mulsidi3_sp64"
5353 [(set (match_operand:DI 0 "register_operand" "=r")
5354 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5355 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
5356 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5358 [(set_attr "type" "imul")])
5360 ;; Extra pattern, because sign_extend of a constant isn't valid.
5363 (define_insn "const_mulsidi3_sp32"
5364 [(set (match_operand:DI 0 "register_operand" "=r")
5365 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5366 (match_operand:DI 2 "small_int" "I")))]
5369 return TARGET_SPARCLET
5370 ? "smuld\t%1, %2, %L0"
5371 : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
5374 (if_then_else (eq_attr "isa" "sparclet")
5375 (const_string "imul") (const_string "multi")))
5376 (set (attr "length")
5377 (if_then_else (eq_attr "isa" "sparclet")
5378 (const_int 1) (const_int 2)))])
5380 (define_insn "const_mulsidi3_sp64"
5381 [(set (match_operand:DI 0 "register_operand" "=r")
5382 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5383 (match_operand:DI 2 "small_int" "I")))]
5384 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5386 [(set_attr "type" "imul")])
5388 (define_expand "smulsi3_highpart"
5389 [(set (match_operand:SI 0 "register_operand" "")
5391 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
5392 (sign_extend:DI (match_operand:SI 2 "arith_operand" "")))
5394 "TARGET_HARD_MUL && TARGET_ARCH32"
5396 if (CONSTANT_P (operands[2]))
5400 emit_insn (gen_const_smulsi3_highpart_v8plus (operands[0],
5406 emit_insn (gen_const_smulsi3_highpart (operands[0], operands[1], operands[2]));
5411 emit_insn (gen_smulsi3_highpart_v8plus (operands[0], operands[1],
5412 operands[2], GEN_INT (32)));
5418 (define_insn "smulsi3_highpart_v8plus"
5419 [(set (match_operand:SI 0 "register_operand" "=h,r")
5421 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5422 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
5423 (match_operand:SI 3 "const_int_operand" "i,i"))))
5424 (clobber (match_scratch:SI 4 "=X,&h"))]
5427 smul\t%1, %2, %0\;srlx\t%0, %3, %0
5428 smul\t%1, %2, %4\;srlx\t%4, %3, %0"
5429 [(set_attr "type" "multi")
5430 (set_attr "length" "2")])
5432 ;; The combiner changes TRUNCATE in the previous pattern to SUBREG.
5435 [(set (match_operand:SI 0 "register_operand" "=h,r")
5438 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5439 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
5440 (match_operand:SI 3 "const_int_operand" "i,i"))
5442 (clobber (match_scratch:SI 4 "=X,&h"))]
5445 smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
5446 smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
5447 [(set_attr "type" "multi")
5448 (set_attr "length" "2")])
5451 (define_insn "const_smulsi3_highpart_v8plus"
5452 [(set (match_operand:SI 0 "register_operand" "=h,r")
5454 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5455 (match_operand:DI 2 "small_int" "i,i"))
5456 (match_operand:SI 3 "const_int_operand" "i,i"))))
5457 (clobber (match_scratch:SI 4 "=X,&h"))]
5460 smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
5461 smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
5462 [(set_attr "type" "multi")
5463 (set_attr "length" "2")])
5466 (define_insn "*smulsi3_highpart_sp32"
5467 [(set (match_operand:SI 0 "register_operand" "=r")
5469 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5470 (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
5473 "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
5474 [(set_attr "type" "multi")
5475 (set_attr "length" "2")])
5478 (define_insn "const_smulsi3_highpart"
5479 [(set (match_operand:SI 0 "register_operand" "=r")
5481 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5482 (match_operand:DI 2 "small_int" "i"))
5485 "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
5486 [(set_attr "type" "multi")
5487 (set_attr "length" "2")])
5489 (define_expand "umulsidi3"
5490 [(set (match_operand:DI 0 "register_operand" "")
5491 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
5492 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" ""))))]
5495 if (CONSTANT_P (operands[2]))
5498 emit_insn (gen_const_umulsidi3_v8plus (operands[0], operands[1],
5500 else if (TARGET_ARCH32)
5501 emit_insn (gen_const_umulsidi3_sp32 (operands[0], operands[1],
5504 emit_insn (gen_const_umulsidi3_sp64 (operands[0], operands[1],
5510 emit_insn (gen_umulsidi3_v8plus (operands[0], operands[1], operands[2]));
5516 (define_insn "umulsidi3_v8plus"
5517 [(set (match_operand:DI 0 "register_operand" "=h,r")
5518 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5519 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
5520 (clobber (match_scratch:SI 3 "=X,&h"))]
5523 umul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
5524 umul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
5525 [(set_attr "type" "multi")
5526 (set_attr "length" "2,3")])
5529 (define_insn "*umulsidi3_sp32"
5530 [(set (match_operand:DI 0 "register_operand" "=r")
5531 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5532 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
5535 return TARGET_SPARCLET
5536 ? "umuld\t%1, %2, %L0"
5537 : "umul\t%1, %2, %L0\n\trd\t%%y, %H0";
5540 (if_then_else (eq_attr "isa" "sparclet")
5541 (const_string "imul") (const_string "multi")))
5542 (set (attr "length")
5543 (if_then_else (eq_attr "isa" "sparclet")
5544 (const_int 1) (const_int 2)))])
5546 (define_insn "*umulsidi3_sp64"
5547 [(set (match_operand:DI 0 "register_operand" "=r")
5548 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5549 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
5550 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5552 [(set_attr "type" "imul")])
5554 ;; Extra pattern, because sign_extend of a constant isn't valid.
5557 (define_insn "const_umulsidi3_sp32"
5558 [(set (match_operand:DI 0 "register_operand" "=r")
5559 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5560 (match_operand:DI 2 "uns_small_int" "")))]
5563 return TARGET_SPARCLET
5564 ? "umuld\t%1, %s2, %L0"
5565 : "umul\t%1, %s2, %L0\n\trd\t%%y, %H0";
5568 (if_then_else (eq_attr "isa" "sparclet")
5569 (const_string "imul") (const_string "multi")))
5570 (set (attr "length")
5571 (if_then_else (eq_attr "isa" "sparclet")
5572 (const_int 1) (const_int 2)))])
5574 (define_insn "const_umulsidi3_sp64"
5575 [(set (match_operand:DI 0 "register_operand" "=r")
5576 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5577 (match_operand:DI 2 "uns_small_int" "")))]
5578 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5580 [(set_attr "type" "imul")])
5583 (define_insn "const_umulsidi3_v8plus"
5584 [(set (match_operand:DI 0 "register_operand" "=h,r")
5585 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5586 (match_operand:DI 2 "uns_small_int" "")))
5587 (clobber (match_scratch:SI 3 "=X,h"))]
5590 umul\t%1, %s2, %L0\n\tsrlx\t%L0, 32, %H0
5591 umul\t%1, %s2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
5592 [(set_attr "type" "multi")
5593 (set_attr "length" "2,3")])
5595 (define_expand "umulsi3_highpart"
5596 [(set (match_operand:SI 0 "register_operand" "")
5598 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
5599 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" "")))
5601 "TARGET_HARD_MUL && TARGET_ARCH32"
5603 if (CONSTANT_P (operands[2]))
5607 emit_insn (gen_const_umulsi3_highpart_v8plus (operands[0],
5613 emit_insn (gen_const_umulsi3_highpart (operands[0], operands[1], operands[2]));
5618 emit_insn (gen_umulsi3_highpart_v8plus (operands[0], operands[1],
5619 operands[2], GEN_INT (32)));
5625 (define_insn "umulsi3_highpart_v8plus"
5626 [(set (match_operand:SI 0 "register_operand" "=h,r")
5628 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5629 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
5630 (match_operand:SI 3 "const_int_operand" "i,i"))))
5631 (clobber (match_scratch:SI 4 "=X,h"))]
5634 umul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
5635 umul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
5636 [(set_attr "type" "multi")
5637 (set_attr "length" "2")])
5640 (define_insn "const_umulsi3_highpart_v8plus"
5641 [(set (match_operand:SI 0 "register_operand" "=h,r")
5643 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5644 (match_operand:DI 2 "uns_small_int" ""))
5645 (match_operand:SI 3 "const_int_operand" "i,i"))))
5646 (clobber (match_scratch:SI 4 "=X,h"))]
5649 umul\t%1, %s2, %0\n\tsrlx\t%0, %3, %0
5650 umul\t%1, %s2, %4\n\tsrlx\t%4, %3, %0"
5651 [(set_attr "type" "multi")
5652 (set_attr "length" "2")])
5655 (define_insn "*umulsi3_highpart_sp32"
5656 [(set (match_operand:SI 0 "register_operand" "=r")
5658 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5659 (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
5662 "umul\t%1, %2, %%g0\n\trd\t%%y, %0"
5663 [(set_attr "type" "multi")
5664 (set_attr "length" "2")])
5667 (define_insn "const_umulsi3_highpart"
5668 [(set (match_operand:SI 0 "register_operand" "=r")
5670 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5671 (match_operand:DI 2 "uns_small_int" ""))
5674 "umul\t%1, %s2, %%g0\n\trd\t%%y, %0"
5675 [(set_attr "type" "multi")
5676 (set_attr "length" "2")])
5678 ;; The v8 architecture specifies that there must be 3 instructions between
5679 ;; a y register write and a use of it for correct results.
5681 (define_expand "divsi3"
5682 [(parallel [(set (match_operand:SI 0 "register_operand" "=r,r")
5683 (div:SI (match_operand:SI 1 "register_operand" "r,r")
5684 (match_operand:SI 2 "input_operand" "rI,m")))
5685 (clobber (match_scratch:SI 3 "=&r,&r"))])]
5686 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
5690 operands[3] = gen_reg_rtx(SImode);
5691 emit_insn (gen_ashrsi3 (operands[3], operands[1], GEN_INT (31)));
5692 emit_insn (gen_divsi3_sp64 (operands[0], operands[1], operands[2],
5698 (define_insn "divsi3_sp32"
5699 [(set (match_operand:SI 0 "register_operand" "=r,r")
5700 (div:SI (match_operand:SI 1 "register_operand" "r,r")
5701 (match_operand:SI 2 "input_operand" "rI,m")))
5702 (clobber (match_scratch:SI 3 "=&r,&r"))]
5703 "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS)
5706 if (which_alternative == 0)
5708 return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tsdiv\t%1, %2, %0";
5710 return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tnop\n\tnop\n\tnop\n\tsdiv\t%1, %2, %0";
5713 return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tld\t%2, %3\n\tsdiv\t%1, %3, %0";
5715 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";
5717 [(set_attr "type" "multi")
5718 (set (attr "length")
5719 (if_then_else (eq_attr "isa" "v9")
5720 (const_int 4) (const_int 6)))])
5722 (define_insn "divsi3_sp64"
5723 [(set (match_operand:SI 0 "register_operand" "=r")
5724 (div:SI (match_operand:SI 1 "register_operand" "r")
5725 (match_operand:SI 2 "input_operand" "rI")))
5726 (use (match_operand:SI 3 "register_operand" "r"))]
5727 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5728 "wr\t%%g0, %3, %%y\n\tsdiv\t%1, %2, %0"
5729 [(set_attr "type" "multi")
5730 (set_attr "length" "2")])
5732 (define_insn "divdi3"
5733 [(set (match_operand:DI 0 "register_operand" "=r")
5734 (div:DI (match_operand:DI 1 "register_operand" "r")
5735 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5738 [(set_attr "type" "idiv")])
5740 (define_insn "*cmp_sdiv_cc_set"
5742 (compare:CC (div:SI (match_operand:SI 1 "register_operand" "r")
5743 (match_operand:SI 2 "arith_operand" "rI"))
5745 (set (match_operand:SI 0 "register_operand" "=r")
5746 (div:SI (match_dup 1) (match_dup 2)))
5747 (clobber (match_scratch:SI 3 "=&r"))]
5748 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
5751 return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tsdivcc\t%1, %2, %0";
5753 return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tnop\n\tnop\n\tnop\n\tsdivcc\t%1, %2, %0";
5755 [(set_attr "type" "multi")
5756 (set (attr "length")
5757 (if_then_else (eq_attr "isa" "v9")
5758 (const_int 3) (const_int 6)))])
5761 (define_expand "udivsi3"
5762 [(set (match_operand:SI 0 "register_operand" "")
5763 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "")
5764 (match_operand:SI 2 "input_operand" "")))]
5765 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
5768 (define_insn "udivsi3_sp32"
5769 [(set (match_operand:SI 0 "register_operand" "=r,&r,&r")
5770 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "r,r,m")
5771 (match_operand:SI 2 "input_operand" "rI,m,r")))]
5773 || TARGET_DEPRECATED_V8_INSNS)
5776 output_asm_insn ("wr\t%%g0, %%g0, %%y", operands);
5777 switch (which_alternative)
5780 return "nop\n\tnop\n\tnop\n\tudiv\t%1, %2, %0";
5782 return "ld\t%2, %0\n\tnop\n\tnop\n\tudiv\t%1, %0, %0";
5784 return "ld\t%1, %0\n\tnop\n\tnop\n\tudiv\t%0, %2, %0";
5787 [(set_attr "type" "multi")
5788 (set_attr "length" "5")])
5790 (define_insn "udivsi3_sp64"
5791 [(set (match_operand:SI 0 "register_operand" "=r")
5792 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "r")
5793 (match_operand:SI 2 "input_operand" "rI")))]
5794 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5795 "wr\t%%g0, 0, %%y\n\tudiv\t%1, %2, %0"
5796 [(set_attr "type" "multi")
5797 (set_attr "length" "2")])
5799 (define_insn "udivdi3"
5800 [(set (match_operand:DI 0 "register_operand" "=r")
5801 (udiv:DI (match_operand:DI 1 "register_operand" "r")
5802 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5805 [(set_attr "type" "idiv")])
5807 (define_insn "*cmp_udiv_cc_set"
5809 (compare:CC (udiv:SI (match_operand:SI 1 "register_operand" "r")
5810 (match_operand:SI 2 "arith_operand" "rI"))
5812 (set (match_operand:SI 0 "register_operand" "=r")
5813 (udiv:SI (match_dup 1) (match_dup 2)))]
5815 || TARGET_DEPRECATED_V8_INSNS"
5818 return "wr\t%%g0, %%g0, %%y\n\tudivcc\t%1, %2, %0";
5820 return "wr\t%%g0, %%g0, %%y\n\tnop\n\tnop\n\tnop\n\tudivcc\t%1, %2, %0";
5822 [(set_attr "type" "multi")
5823 (set (attr "length")
5824 (if_then_else (eq_attr "isa" "v9")
5825 (const_int 2) (const_int 5)))])
5827 ; sparclet multiply/accumulate insns
5829 (define_insn "*smacsi"
5830 [(set (match_operand:SI 0 "register_operand" "=r")
5831 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "%r")
5832 (match_operand:SI 2 "arith_operand" "rI"))
5833 (match_operand:SI 3 "register_operand" "0")))]
5836 [(set_attr "type" "imul")])
5838 (define_insn "*smacdi"
5839 [(set (match_operand:DI 0 "register_operand" "=r")
5840 (plus:DI (mult:DI (sign_extend:DI
5841 (match_operand:SI 1 "register_operand" "%r"))
5843 (match_operand:SI 2 "register_operand" "r")))
5844 (match_operand:DI 3 "register_operand" "0")))]
5846 "smacd\t%1, %2, %L0"
5847 [(set_attr "type" "imul")])
5849 (define_insn "*umacdi"
5850 [(set (match_operand:DI 0 "register_operand" "=r")
5851 (plus:DI (mult:DI (zero_extend:DI
5852 (match_operand:SI 1 "register_operand" "%r"))
5854 (match_operand:SI 2 "register_operand" "r")))
5855 (match_operand:DI 3 "register_operand" "0")))]
5857 "umacd\t%1, %2, %L0"
5858 [(set_attr "type" "imul")])
5860 ;;- Boolean instructions
5861 ;; We define DImode `and' so with DImode `not' we can get
5862 ;; DImode `andn'. Other combinations are possible.
5864 (define_expand "anddi3"
5865 [(set (match_operand:DI 0 "register_operand" "")
5866 (and:DI (match_operand:DI 1 "arith_double_operand" "")
5867 (match_operand:DI 2 "arith_double_operand" "")))]
5871 (define_insn "*anddi3_sp32"
5872 [(set (match_operand:DI 0 "register_operand" "=r,b")
5873 (and:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
5874 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
5879 [(set_attr "type" "*,fga")
5880 (set_attr "length" "2,*")
5881 (set_attr "fptype" "double")])
5883 (define_insn "*anddi3_sp64"
5884 [(set (match_operand:DI 0 "register_operand" "=r,b")
5885 (and:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
5886 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
5891 [(set_attr "type" "*,fga")
5892 (set_attr "fptype" "double")])
5894 (define_insn "andsi3"
5895 [(set (match_operand:SI 0 "register_operand" "=r,d")
5896 (and:SI (match_operand:SI 1 "arith_operand" "%r,d")
5897 (match_operand:SI 2 "arith_operand" "rI,d")))]
5902 [(set_attr "type" "*,fga")])
5905 [(set (match_operand:SI 0 "register_operand" "")
5906 (and:SI (match_operand:SI 1 "register_operand" "")
5907 (match_operand:SI 2 "" "")))
5908 (clobber (match_operand:SI 3 "register_operand" ""))]
5909 "GET_CODE (operands[2]) == CONST_INT
5910 && !SMALL_INT32 (operands[2])
5911 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
5912 [(set (match_dup 3) (match_dup 4))
5913 (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 1)))]
5915 operands[4] = GEN_INT (~INTVAL (operands[2]));
5918 ;; Split DImode logical operations requiring two instructions.
5920 [(set (match_operand:DI 0 "register_operand" "")
5921 (match_operator:DI 1 "cc_arithop" ; AND, IOR, XOR
5922 [(match_operand:DI 2 "register_operand" "")
5923 (match_operand:DI 3 "arith_double_operand" "")]))]
5926 && ((GET_CODE (operands[0]) == REG
5927 && REGNO (operands[0]) < 32)
5928 || (GET_CODE (operands[0]) == SUBREG
5929 && GET_CODE (SUBREG_REG (operands[0])) == REG
5930 && REGNO (SUBREG_REG (operands[0])) < 32))"
5931 [(set (match_dup 4) (match_op_dup:SI 1 [(match_dup 6) (match_dup 8)]))
5932 (set (match_dup 5) (match_op_dup:SI 1 [(match_dup 7) (match_dup 9)]))]
5934 operands[4] = gen_highpart (SImode, operands[0]);
5935 operands[5] = gen_lowpart (SImode, operands[0]);
5936 operands[6] = gen_highpart (SImode, operands[2]);
5937 operands[7] = gen_lowpart (SImode, operands[2]);
5938 #if HOST_BITS_PER_WIDE_INT == 32
5939 if (GET_CODE (operands[3]) == CONST_INT)
5941 if (INTVAL (operands[3]) < 0)
5942 operands[8] = constm1_rtx;
5944 operands[8] = const0_rtx;
5948 operands[8] = gen_highpart_mode (SImode, DImode, operands[3]);
5949 operands[9] = gen_lowpart (SImode, operands[3]);
5952 (define_insn_and_split "*and_not_di_sp32"
5953 [(set (match_operand:DI 0 "register_operand" "=r,b")
5954 (and:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
5955 (match_operand:DI 2 "register_operand" "r,b")))]
5959 fandnot1\t%1, %2, %0"
5960 "&& reload_completed
5961 && ((GET_CODE (operands[0]) == REG
5962 && REGNO (operands[0]) < 32)
5963 || (GET_CODE (operands[0]) == SUBREG
5964 && GET_CODE (SUBREG_REG (operands[0])) == REG
5965 && REGNO (SUBREG_REG (operands[0])) < 32))"
5966 [(set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))
5967 (set (match_dup 6) (and:SI (not:SI (match_dup 7)) (match_dup 8)))]
5968 "operands[3] = gen_highpart (SImode, operands[0]);
5969 operands[4] = gen_highpart (SImode, operands[1]);
5970 operands[5] = gen_highpart (SImode, operands[2]);
5971 operands[6] = gen_lowpart (SImode, operands[0]);
5972 operands[7] = gen_lowpart (SImode, operands[1]);
5973 operands[8] = gen_lowpart (SImode, operands[2]);"
5974 [(set_attr "type" "*,fga")
5975 (set_attr "length" "2,*")
5976 (set_attr "fptype" "double")])
5978 (define_insn "*and_not_di_sp64"
5979 [(set (match_operand:DI 0 "register_operand" "=r,b")
5980 (and:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
5981 (match_operand:DI 2 "register_operand" "r,b")))]
5985 fandnot1\t%1, %2, %0"
5986 [(set_attr "type" "*,fga")
5987 (set_attr "fptype" "double")])
5989 (define_insn "*and_not_si"
5990 [(set (match_operand:SI 0 "register_operand" "=r,d")
5991 (and:SI (not:SI (match_operand:SI 1 "register_operand" "r,d"))
5992 (match_operand:SI 2 "register_operand" "r,d")))]
5996 fandnot1s\t%1, %2, %0"
5997 [(set_attr "type" "*,fga")])
5999 (define_expand "iordi3"
6000 [(set (match_operand:DI 0 "register_operand" "")
6001 (ior:DI (match_operand:DI 1 "arith_double_operand" "")
6002 (match_operand:DI 2 "arith_double_operand" "")))]
6006 (define_insn "*iordi3_sp32"
6007 [(set (match_operand:DI 0 "register_operand" "=r,b")
6008 (ior:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6009 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6014 [(set_attr "type" "*,fga")
6015 (set_attr "length" "2,*")
6016 (set_attr "fptype" "double")])
6018 (define_insn "*iordi3_sp64"
6019 [(set (match_operand:DI 0 "register_operand" "=r,b")
6020 (ior:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6021 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6026 [(set_attr "type" "*,fga")
6027 (set_attr "fptype" "double")])
6029 (define_insn "iorsi3"
6030 [(set (match_operand:SI 0 "register_operand" "=r,d")
6031 (ior:SI (match_operand:SI 1 "arith_operand" "%r,d")
6032 (match_operand:SI 2 "arith_operand" "rI,d")))]
6037 [(set_attr "type" "*,fga")])
6040 [(set (match_operand:SI 0 "register_operand" "")
6041 (ior:SI (match_operand:SI 1 "register_operand" "")
6042 (match_operand:SI 2 "" "")))
6043 (clobber (match_operand:SI 3 "register_operand" ""))]
6044 "GET_CODE (operands[2]) == CONST_INT
6045 && !SMALL_INT32 (operands[2])
6046 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6047 [(set (match_dup 3) (match_dup 4))
6048 (set (match_dup 0) (ior:SI (not:SI (match_dup 3)) (match_dup 1)))]
6050 operands[4] = GEN_INT (~INTVAL (operands[2]));
6053 (define_insn_and_split "*or_not_di_sp32"
6054 [(set (match_operand:DI 0 "register_operand" "=r,b")
6055 (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6056 (match_operand:DI 2 "register_operand" "r,b")))]
6060 fornot1\t%1, %2, %0"
6061 "&& reload_completed
6062 && ((GET_CODE (operands[0]) == REG
6063 && REGNO (operands[0]) < 32)
6064 || (GET_CODE (operands[0]) == SUBREG
6065 && GET_CODE (SUBREG_REG (operands[0])) == REG
6066 && REGNO (SUBREG_REG (operands[0])) < 32))"
6067 [(set (match_dup 3) (ior:SI (not:SI (match_dup 4)) (match_dup 5)))
6068 (set (match_dup 6) (ior:SI (not:SI (match_dup 7)) (match_dup 8)))]
6069 "operands[3] = gen_highpart (SImode, operands[0]);
6070 operands[4] = gen_highpart (SImode, operands[1]);
6071 operands[5] = gen_highpart (SImode, operands[2]);
6072 operands[6] = gen_lowpart (SImode, operands[0]);
6073 operands[7] = gen_lowpart (SImode, operands[1]);
6074 operands[8] = gen_lowpart (SImode, operands[2]);"
6075 [(set_attr "type" "*,fga")
6076 (set_attr "length" "2,*")
6077 (set_attr "fptype" "double")])
6079 (define_insn "*or_not_di_sp64"
6080 [(set (match_operand:DI 0 "register_operand" "=r,b")
6081 (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6082 (match_operand:DI 2 "register_operand" "r,b")))]
6086 fornot1\t%1, %2, %0"
6087 [(set_attr "type" "*,fga")
6088 (set_attr "fptype" "double")])
6090 (define_insn "*or_not_si"
6091 [(set (match_operand:SI 0 "register_operand" "=r,d")
6092 (ior:SI (not:SI (match_operand:SI 1 "register_operand" "r,d"))
6093 (match_operand:SI 2 "register_operand" "r,d")))]
6097 fornot1s\t%1, %2, %0"
6098 [(set_attr "type" "*,fga")])
6100 (define_expand "xordi3"
6101 [(set (match_operand:DI 0 "register_operand" "")
6102 (xor:DI (match_operand:DI 1 "arith_double_operand" "")
6103 (match_operand:DI 2 "arith_double_operand" "")))]
6107 (define_insn "*xordi3_sp32"
6108 [(set (match_operand:DI 0 "register_operand" "=r,b")
6109 (xor:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6110 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6115 [(set_attr "type" "*,fga")
6116 (set_attr "length" "2,*")
6117 (set_attr "fptype" "double")])
6119 (define_insn "*xordi3_sp64"
6120 [(set (match_operand:DI 0 "register_operand" "=r,b")
6121 (xor:DI (match_operand:DI 1 "arith_double_operand" "%rJ,b")
6122 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6127 [(set_attr "type" "*,fga")
6128 (set_attr "fptype" "double")])
6130 (define_insn "*xordi3_sp64_dbl"
6131 [(set (match_operand:DI 0 "register_operand" "=r")
6132 (xor:DI (match_operand:DI 1 "register_operand" "r")
6133 (match_operand:DI 2 "const64_operand" "")))]
6135 && HOST_BITS_PER_WIDE_INT != 64)"
6138 (define_insn "xorsi3"
6139 [(set (match_operand:SI 0 "register_operand" "=r,d")
6140 (xor:SI (match_operand:SI 1 "arith_operand" "%rJ,d")
6141 (match_operand:SI 2 "arith_operand" "rI,d")))]
6146 [(set_attr "type" "*,fga")])
6149 [(set (match_operand:SI 0 "register_operand" "")
6150 (xor:SI (match_operand:SI 1 "register_operand" "")
6151 (match_operand:SI 2 "" "")))
6152 (clobber (match_operand:SI 3 "register_operand" ""))]
6153 "GET_CODE (operands[2]) == CONST_INT
6154 && !SMALL_INT32 (operands[2])
6155 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6156 [(set (match_dup 3) (match_dup 4))
6157 (set (match_dup 0) (not:SI (xor:SI (match_dup 3) (match_dup 1))))]
6159 operands[4] = GEN_INT (~INTVAL (operands[2]));
6163 [(set (match_operand:SI 0 "register_operand" "")
6164 (not:SI (xor:SI (match_operand:SI 1 "register_operand" "")
6165 (match_operand:SI 2 "" ""))))
6166 (clobber (match_operand:SI 3 "register_operand" ""))]
6167 "GET_CODE (operands[2]) == CONST_INT
6168 && !SMALL_INT32 (operands[2])
6169 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6170 [(set (match_dup 3) (match_dup 4))
6171 (set (match_dup 0) (xor:SI (match_dup 3) (match_dup 1)))]
6173 operands[4] = GEN_INT (~INTVAL (operands[2]));
6176 ;; xnor patterns. Note that (a ^ ~b) == (~a ^ b) == ~(a ^ b).
6177 ;; Combine now canonicalizes to the rightmost expression.
6178 (define_insn_and_split "*xor_not_di_sp32"
6179 [(set (match_operand:DI 0 "register_operand" "=r,b")
6180 (not:DI (xor:DI (match_operand:DI 1 "register_operand" "r,b")
6181 (match_operand:DI 2 "register_operand" "r,b"))))]
6186 "&& reload_completed
6187 && ((GET_CODE (operands[0]) == REG
6188 && REGNO (operands[0]) < 32)
6189 || (GET_CODE (operands[0]) == SUBREG
6190 && GET_CODE (SUBREG_REG (operands[0])) == REG
6191 && REGNO (SUBREG_REG (operands[0])) < 32))"
6192 [(set (match_dup 3) (not:SI (xor:SI (match_dup 4) (match_dup 5))))
6193 (set (match_dup 6) (not:SI (xor:SI (match_dup 7) (match_dup 8))))]
6194 "operands[3] = gen_highpart (SImode, operands[0]);
6195 operands[4] = gen_highpart (SImode, operands[1]);
6196 operands[5] = gen_highpart (SImode, operands[2]);
6197 operands[6] = gen_lowpart (SImode, operands[0]);
6198 operands[7] = gen_lowpart (SImode, operands[1]);
6199 operands[8] = gen_lowpart (SImode, operands[2]);"
6200 [(set_attr "type" "*,fga")
6201 (set_attr "length" "2,*")
6202 (set_attr "fptype" "double")])
6204 (define_insn "*xor_not_di_sp64"
6205 [(set (match_operand:DI 0 "register_operand" "=r,b")
6206 (not:DI (xor:DI (match_operand:DI 1 "reg_or_0_operand" "rJ,b")
6207 (match_operand:DI 2 "arith_double_operand" "rHI,b"))))]
6212 [(set_attr "type" "*,fga")
6213 (set_attr "fptype" "double")])
6215 (define_insn "*xor_not_si"
6216 [(set (match_operand:SI 0 "register_operand" "=r,d")
6217 (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "rJ,d")
6218 (match_operand:SI 2 "arith_operand" "rI,d"))))]
6223 [(set_attr "type" "*,fga")])
6225 ;; These correspond to the above in the case where we also (or only)
6226 ;; want to set the condition code.
6228 (define_insn "*cmp_cc_arith_op"
6231 (match_operator:SI 2 "cc_arithop"
6232 [(match_operand:SI 0 "arith_operand" "%r")
6233 (match_operand:SI 1 "arith_operand" "rI")])
6236 "%A2cc\t%0, %1, %%g0"
6237 [(set_attr "type" "compare")])
6239 (define_insn "*cmp_ccx_arith_op"
6242 (match_operator:DI 2 "cc_arithop"
6243 [(match_operand:DI 0 "arith_double_operand" "%r")
6244 (match_operand:DI 1 "arith_double_operand" "rHI")])
6247 "%A2cc\t%0, %1, %%g0"
6248 [(set_attr "type" "compare")])
6250 (define_insn "*cmp_cc_arith_op_set"
6253 (match_operator:SI 3 "cc_arithop"
6254 [(match_operand:SI 1 "arith_operand" "%r")
6255 (match_operand:SI 2 "arith_operand" "rI")])
6257 (set (match_operand:SI 0 "register_operand" "=r")
6258 (match_operator:SI 4 "cc_arithop" [(match_dup 1) (match_dup 2)]))]
6259 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
6261 [(set_attr "type" "compare")])
6263 (define_insn "*cmp_ccx_arith_op_set"
6266 (match_operator:DI 3 "cc_arithop"
6267 [(match_operand:DI 1 "arith_double_operand" "%r")
6268 (match_operand:DI 2 "arith_double_operand" "rHI")])
6270 (set (match_operand:DI 0 "register_operand" "=r")
6271 (match_operator:DI 4 "cc_arithop" [(match_dup 1) (match_dup 2)]))]
6272 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
6274 [(set_attr "type" "compare")])
6276 (define_insn "*cmp_cc_xor_not"
6279 (not:SI (xor:SI (match_operand:SI 0 "reg_or_0_operand" "%rJ")
6280 (match_operand:SI 1 "arith_operand" "rI")))
6283 "xnorcc\t%r0, %1, %%g0"
6284 [(set_attr "type" "compare")])
6286 (define_insn "*cmp_ccx_xor_not"
6289 (not:DI (xor:DI (match_operand:DI 0 "reg_or_0_operand" "%rJ")
6290 (match_operand:DI 1 "arith_double_operand" "rHI")))
6293 "xnorcc\t%r0, %1, %%g0"
6294 [(set_attr "type" "compare")])
6296 (define_insn "*cmp_cc_xor_not_set"
6299 (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
6300 (match_operand:SI 2 "arith_operand" "rI")))
6302 (set (match_operand:SI 0 "register_operand" "=r")
6303 (not:SI (xor:SI (match_dup 1) (match_dup 2))))]
6305 "xnorcc\t%r1, %2, %0"
6306 [(set_attr "type" "compare")])
6308 (define_insn "*cmp_ccx_xor_not_set"
6311 (not:DI (xor:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ")
6312 (match_operand:DI 2 "arith_double_operand" "rHI")))
6314 (set (match_operand:DI 0 "register_operand" "=r")
6315 (not:DI (xor:DI (match_dup 1) (match_dup 2))))]
6317 "xnorcc\t%r1, %2, %0"
6318 [(set_attr "type" "compare")])
6320 (define_insn "*cmp_cc_arith_op_not"
6323 (match_operator:SI 2 "cc_arithopn"
6324 [(not:SI (match_operand:SI 0 "arith_operand" "rI"))
6325 (match_operand:SI 1 "reg_or_0_operand" "rJ")])
6328 "%B2cc\t%r1, %0, %%g0"
6329 [(set_attr "type" "compare")])
6331 (define_insn "*cmp_ccx_arith_op_not"
6334 (match_operator:DI 2 "cc_arithopn"
6335 [(not:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
6336 (match_operand:DI 1 "reg_or_0_operand" "rJ")])
6339 "%B2cc\t%r1, %0, %%g0"
6340 [(set_attr "type" "compare")])
6342 (define_insn "*cmp_cc_arith_op_not_set"
6345 (match_operator:SI 3 "cc_arithopn"
6346 [(not:SI (match_operand:SI 1 "arith_operand" "rI"))
6347 (match_operand:SI 2 "reg_or_0_operand" "rJ")])
6349 (set (match_operand:SI 0 "register_operand" "=r")
6350 (match_operator:SI 4 "cc_arithopn"
6351 [(not:SI (match_dup 1)) (match_dup 2)]))]
6352 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
6353 "%B3cc\t%r2, %1, %0"
6354 [(set_attr "type" "compare")])
6356 (define_insn "*cmp_ccx_arith_op_not_set"
6359 (match_operator:DI 3 "cc_arithopn"
6360 [(not:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
6361 (match_operand:DI 2 "reg_or_0_operand" "rJ")])
6363 (set (match_operand:DI 0 "register_operand" "=r")
6364 (match_operator:DI 4 "cc_arithopn"
6365 [(not:DI (match_dup 1)) (match_dup 2)]))]
6366 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
6367 "%B3cc\t%r2, %1, %0"
6368 [(set_attr "type" "compare")])
6370 ;; We cannot use the "neg" pseudo insn because the Sun assembler
6371 ;; does not know how to make it work for constants.
6373 (define_expand "negdi2"
6374 [(set (match_operand:DI 0 "register_operand" "=r")
6375 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
6378 if (! TARGET_ARCH64)
6380 emit_insn (gen_rtx_PARALLEL
6383 gen_rtx_SET (VOIDmode, operand0,
6384 gen_rtx_NEG (DImode, operand1)),
6385 gen_rtx_CLOBBER (VOIDmode,
6386 gen_rtx_REG (CCmode,
6392 (define_insn_and_split "*negdi2_sp32"
6393 [(set (match_operand:DI 0 "register_operand" "=r")
6394 (neg:DI (match_operand:DI 1 "register_operand" "r")))
6395 (clobber (reg:CC 100))]
6398 "&& reload_completed"
6399 [(parallel [(set (reg:CC_NOOV 100)
6400 (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 5))
6402 (set (match_dup 4) (minus:SI (const_int 0) (match_dup 5)))])
6403 (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
6404 (ltu:SI (reg:CC 100) (const_int 0))))]
6405 "operands[2] = gen_highpart (SImode, operands[0]);
6406 operands[3] = gen_highpart (SImode, operands[1]);
6407 operands[4] = gen_lowpart (SImode, operands[0]);
6408 operands[5] = gen_lowpart (SImode, operands[1]);"
6409 [(set_attr "length" "2")])
6411 (define_insn "*negdi2_sp64"
6412 [(set (match_operand:DI 0 "register_operand" "=r")
6413 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
6415 "sub\t%%g0, %1, %0")
6417 (define_insn "negsi2"
6418 [(set (match_operand:SI 0 "register_operand" "=r")
6419 (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
6421 "sub\t%%g0, %1, %0")
6423 (define_insn "*cmp_cc_neg"
6424 [(set (reg:CC_NOOV 100)
6425 (compare:CC_NOOV (neg:SI (match_operand:SI 0 "arith_operand" "rI"))
6428 "subcc\t%%g0, %0, %%g0"
6429 [(set_attr "type" "compare")])
6431 (define_insn "*cmp_ccx_neg"
6432 [(set (reg:CCX_NOOV 100)
6433 (compare:CCX_NOOV (neg:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
6436 "subcc\t%%g0, %0, %%g0"
6437 [(set_attr "type" "compare")])
6439 (define_insn "*cmp_cc_set_neg"
6440 [(set (reg:CC_NOOV 100)
6441 (compare:CC_NOOV (neg:SI (match_operand:SI 1 "arith_operand" "rI"))
6443 (set (match_operand:SI 0 "register_operand" "=r")
6444 (neg:SI (match_dup 1)))]
6446 "subcc\t%%g0, %1, %0"
6447 [(set_attr "type" "compare")])
6449 (define_insn "*cmp_ccx_set_neg"
6450 [(set (reg:CCX_NOOV 100)
6451 (compare:CCX_NOOV (neg:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
6453 (set (match_operand:DI 0 "register_operand" "=r")
6454 (neg:DI (match_dup 1)))]
6456 "subcc\t%%g0, %1, %0"
6457 [(set_attr "type" "compare")])
6459 ;; We cannot use the "not" pseudo insn because the Sun assembler
6460 ;; does not know how to make it work for constants.
6461 (define_expand "one_cmpldi2"
6462 [(set (match_operand:DI 0 "register_operand" "")
6463 (not:DI (match_operand:DI 1 "register_operand" "")))]
6467 (define_insn_and_split "*one_cmpldi2_sp32"
6468 [(set (match_operand:DI 0 "register_operand" "=r,b")
6469 (not:DI (match_operand:DI 1 "register_operand" "r,b")))]
6474 "&& reload_completed
6475 && ((GET_CODE (operands[0]) == REG
6476 && REGNO (operands[0]) < 32)
6477 || (GET_CODE (operands[0]) == SUBREG
6478 && GET_CODE (SUBREG_REG (operands[0])) == REG
6479 && REGNO (SUBREG_REG (operands[0])) < 32))"
6480 [(set (match_dup 2) (not:SI (xor:SI (match_dup 3) (const_int 0))))
6481 (set (match_dup 4) (not:SI (xor:SI (match_dup 5) (const_int 0))))]
6482 "operands[2] = gen_highpart (SImode, operands[0]);
6483 operands[3] = gen_highpart (SImode, operands[1]);
6484 operands[4] = gen_lowpart (SImode, operands[0]);
6485 operands[5] = gen_lowpart (SImode, operands[1]);"
6486 [(set_attr "type" "*,fga")
6487 (set_attr "length" "2,*")
6488 (set_attr "fptype" "double")])
6490 (define_insn "*one_cmpldi2_sp64"
6491 [(set (match_operand:DI 0 "register_operand" "=r,b")
6492 (not:DI (match_operand:DI 1 "arith_double_operand" "rHI,b")))]
6497 [(set_attr "type" "*,fga")
6498 (set_attr "fptype" "double")])
6500 (define_insn "one_cmplsi2"
6501 [(set (match_operand:SI 0 "register_operand" "=r,d")
6502 (not:SI (match_operand:SI 1 "arith_operand" "rI,d")))]
6507 [(set_attr "type" "*,fga")])
6509 (define_insn "*cmp_cc_not"
6511 (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI"))
6514 "xnorcc\t%%g0, %0, %%g0"
6515 [(set_attr "type" "compare")])
6517 (define_insn "*cmp_ccx_not"
6519 (compare:CCX (not:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
6522 "xnorcc\t%%g0, %0, %%g0"
6523 [(set_attr "type" "compare")])
6525 (define_insn "*cmp_cc_set_not"
6527 (compare:CC (not:SI (match_operand:SI 1 "arith_operand" "rI"))
6529 (set (match_operand:SI 0 "register_operand" "=r")
6530 (not:SI (match_dup 1)))]
6532 "xnorcc\t%%g0, %1, %0"
6533 [(set_attr "type" "compare")])
6535 (define_insn "*cmp_ccx_set_not"
6537 (compare:CCX (not:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
6539 (set (match_operand:DI 0 "register_operand" "=r")
6540 (not:DI (match_dup 1)))]
6542 "xnorcc\t%%g0, %1, %0"
6543 [(set_attr "type" "compare")])
6545 (define_insn "*cmp_cc_set"
6546 [(set (match_operand:SI 0 "register_operand" "=r")
6547 (match_operand:SI 1 "register_operand" "r"))
6549 (compare:CC (match_dup 1)
6553 [(set_attr "type" "compare")])
6555 (define_insn "*cmp_ccx_set64"
6556 [(set (match_operand:DI 0 "register_operand" "=r")
6557 (match_operand:DI 1 "register_operand" "r"))
6559 (compare:CCX (match_dup 1)
6563 [(set_attr "type" "compare")])
6565 ;; Floating point arithmetic instructions.
6567 (define_expand "addtf3"
6568 [(set (match_operand:TF 0 "nonimmediate_operand" "")
6569 (plus:TF (match_operand:TF 1 "general_operand" "")
6570 (match_operand:TF 2 "general_operand" "")))]
6571 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6572 "emit_tfmode_binop (PLUS, operands); DONE;")
6574 (define_insn "*addtf3_hq"
6575 [(set (match_operand:TF 0 "register_operand" "=e")
6576 (plus:TF (match_operand:TF 1 "register_operand" "e")
6577 (match_operand:TF 2 "register_operand" "e")))]
6578 "TARGET_FPU && TARGET_HARD_QUAD"
6580 [(set_attr "type" "fp")])
6582 (define_insn "adddf3"
6583 [(set (match_operand:DF 0 "register_operand" "=e")
6584 (plus:DF (match_operand:DF 1 "register_operand" "e")
6585 (match_operand:DF 2 "register_operand" "e")))]
6588 [(set_attr "type" "fp")
6589 (set_attr "fptype" "double")])
6591 (define_insn "addsf3"
6592 [(set (match_operand:SF 0 "register_operand" "=f")
6593 (plus:SF (match_operand:SF 1 "register_operand" "f")
6594 (match_operand:SF 2 "register_operand" "f")))]
6597 [(set_attr "type" "fp")])
6599 (define_expand "subtf3"
6600 [(set (match_operand:TF 0 "nonimmediate_operand" "")
6601 (minus:TF (match_operand:TF 1 "general_operand" "")
6602 (match_operand:TF 2 "general_operand" "")))]
6603 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6604 "emit_tfmode_binop (MINUS, operands); DONE;")
6606 (define_insn "*subtf3_hq"
6607 [(set (match_operand:TF 0 "register_operand" "=e")
6608 (minus:TF (match_operand:TF 1 "register_operand" "e")
6609 (match_operand:TF 2 "register_operand" "e")))]
6610 "TARGET_FPU && TARGET_HARD_QUAD"
6612 [(set_attr "type" "fp")])
6614 (define_insn "subdf3"
6615 [(set (match_operand:DF 0 "register_operand" "=e")
6616 (minus:DF (match_operand:DF 1 "register_operand" "e")
6617 (match_operand:DF 2 "register_operand" "e")))]
6620 [(set_attr "type" "fp")
6621 (set_attr "fptype" "double")])
6623 (define_insn "subsf3"
6624 [(set (match_operand:SF 0 "register_operand" "=f")
6625 (minus:SF (match_operand:SF 1 "register_operand" "f")
6626 (match_operand:SF 2 "register_operand" "f")))]
6629 [(set_attr "type" "fp")])
6631 (define_expand "multf3"
6632 [(set (match_operand:TF 0 "nonimmediate_operand" "")
6633 (mult:TF (match_operand:TF 1 "general_operand" "")
6634 (match_operand:TF 2 "general_operand" "")))]
6635 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6636 "emit_tfmode_binop (MULT, operands); DONE;")
6638 (define_insn "*multf3_hq"
6639 [(set (match_operand:TF 0 "register_operand" "=e")
6640 (mult:TF (match_operand:TF 1 "register_operand" "e")
6641 (match_operand:TF 2 "register_operand" "e")))]
6642 "TARGET_FPU && TARGET_HARD_QUAD"
6644 [(set_attr "type" "fpmul")])
6646 (define_insn "muldf3"
6647 [(set (match_operand:DF 0 "register_operand" "=e")
6648 (mult:DF (match_operand:DF 1 "register_operand" "e")
6649 (match_operand:DF 2 "register_operand" "e")))]
6652 [(set_attr "type" "fpmul")
6653 (set_attr "fptype" "double")])
6655 (define_insn "mulsf3"
6656 [(set (match_operand:SF 0 "register_operand" "=f")
6657 (mult:SF (match_operand:SF 1 "register_operand" "f")
6658 (match_operand:SF 2 "register_operand" "f")))]
6661 [(set_attr "type" "fpmul")])
6663 (define_insn "*muldf3_extend"
6664 [(set (match_operand:DF 0 "register_operand" "=e")
6665 (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "f"))
6666 (float_extend:DF (match_operand:SF 2 "register_operand" "f"))))]
6667 "(TARGET_V8 || TARGET_V9) && TARGET_FPU"
6668 "fsmuld\t%1, %2, %0"
6669 [(set_attr "type" "fpmul")
6670 (set_attr "fptype" "double")])
6672 (define_insn "*multf3_extend"
6673 [(set (match_operand:TF 0 "register_operand" "=e")
6674 (mult:TF (float_extend:TF (match_operand:DF 1 "register_operand" "e"))
6675 (float_extend:TF (match_operand:DF 2 "register_operand" "e"))))]
6676 "(TARGET_V8 || TARGET_V9) && TARGET_FPU && TARGET_HARD_QUAD"
6677 "fdmulq\t%1, %2, %0"
6678 [(set_attr "type" "fpmul")])
6680 (define_expand "divtf3"
6681 [(set (match_operand:TF 0 "nonimmediate_operand" "")
6682 (div:TF (match_operand:TF 1 "general_operand" "")
6683 (match_operand:TF 2 "general_operand" "")))]
6684 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6685 "emit_tfmode_binop (DIV, operands); DONE;")
6687 ;; don't have timing for quad-prec. divide.
6688 (define_insn "*divtf3_hq"
6689 [(set (match_operand:TF 0 "register_operand" "=e")
6690 (div:TF (match_operand:TF 1 "register_operand" "e")
6691 (match_operand:TF 2 "register_operand" "e")))]
6692 "TARGET_FPU && TARGET_HARD_QUAD"
6694 [(set_attr "type" "fpdivd")])
6696 (define_insn "divdf3"
6697 [(set (match_operand:DF 0 "register_operand" "=e")
6698 (div:DF (match_operand:DF 1 "register_operand" "e")
6699 (match_operand:DF 2 "register_operand" "e")))]
6702 [(set_attr "type" "fpdivd")
6703 (set_attr "fptype" "double")])
6705 (define_insn "divsf3"
6706 [(set (match_operand:SF 0 "register_operand" "=f")
6707 (div:SF (match_operand:SF 1 "register_operand" "f")
6708 (match_operand:SF 2 "register_operand" "f")))]
6711 [(set_attr "type" "fpdivs")])
6713 (define_expand "negtf2"
6714 [(set (match_operand:TF 0 "register_operand" "=e,e")
6715 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
6719 (define_insn_and_split "*negtf2_notv9"
6720 [(set (match_operand:TF 0 "register_operand" "=e,e")
6721 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
6722 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
6728 "&& reload_completed
6729 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6730 [(set (match_dup 2) (neg:SF (match_dup 3)))
6731 (set (match_dup 4) (match_dup 5))
6732 (set (match_dup 6) (match_dup 7))]
6733 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6734 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6735 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6736 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
6737 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6738 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6739 [(set_attr "type" "fpmove,*")
6740 (set_attr "length" "*,2")])
6742 (define_insn_and_split "*negtf2_v9"
6743 [(set (match_operand:TF 0 "register_operand" "=e,e")
6744 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
6745 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
6746 "TARGET_FPU && TARGET_V9"
6750 "&& reload_completed
6751 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6752 [(set (match_dup 2) (neg:DF (match_dup 3)))
6753 (set (match_dup 4) (match_dup 5))]
6754 "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
6755 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
6756 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6757 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6758 [(set_attr "type" "fpmove,*")
6759 (set_attr "length" "*,2")
6760 (set_attr "fptype" "double")])
6762 (define_expand "negdf2"
6763 [(set (match_operand:DF 0 "register_operand" "")
6764 (neg:DF (match_operand:DF 1 "register_operand" "")))]
6768 (define_insn_and_split "*negdf2_notv9"
6769 [(set (match_operand:DF 0 "register_operand" "=e,e")
6770 (neg:DF (match_operand:DF 1 "register_operand" "0,e")))]
6771 "TARGET_FPU && ! TARGET_V9"
6775 "&& reload_completed
6776 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6777 [(set (match_dup 2) (neg:SF (match_dup 3)))
6778 (set (match_dup 4) (match_dup 5))]
6779 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6780 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6781 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6782 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);"
6783 [(set_attr "type" "fpmove,*")
6784 (set_attr "length" "*,2")])
6786 (define_insn "*negdf2_v9"
6787 [(set (match_operand:DF 0 "register_operand" "=e")
6788 (neg:DF (match_operand:DF 1 "register_operand" "e")))]
6789 "TARGET_FPU && TARGET_V9"
6791 [(set_attr "type" "fpmove")
6792 (set_attr "fptype" "double")])
6794 (define_insn "negsf2"
6795 [(set (match_operand:SF 0 "register_operand" "=f")
6796 (neg:SF (match_operand:SF 1 "register_operand" "f")))]
6799 [(set_attr "type" "fpmove")])
6801 (define_expand "abstf2"
6802 [(set (match_operand:TF 0 "register_operand" "")
6803 (abs:TF (match_operand:TF 1 "register_operand" "")))]
6807 (define_insn_and_split "*abstf2_notv9"
6808 [(set (match_operand:TF 0 "register_operand" "=e,e")
6809 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6810 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
6811 "TARGET_FPU && ! TARGET_V9"
6815 "&& reload_completed
6816 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6817 [(set (match_dup 2) (abs:SF (match_dup 3)))
6818 (set (match_dup 4) (match_dup 5))
6819 (set (match_dup 6) (match_dup 7))]
6820 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6821 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6822 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6823 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
6824 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6825 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6826 [(set_attr "type" "fpmove,*")
6827 (set_attr "length" "*,2")])
6829 (define_insn "*abstf2_hq_v9"
6830 [(set (match_operand:TF 0 "register_operand" "=e,e")
6831 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6832 "TARGET_FPU && TARGET_V9 && TARGET_HARD_QUAD"
6836 [(set_attr "type" "fpmove")
6837 (set_attr "fptype" "double,*")])
6839 (define_insn_and_split "*abstf2_v9"
6840 [(set (match_operand:TF 0 "register_operand" "=e,e")
6841 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6842 "TARGET_FPU && TARGET_V9 && !TARGET_HARD_QUAD"
6846 "&& reload_completed
6847 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6848 [(set (match_dup 2) (abs:DF (match_dup 3)))
6849 (set (match_dup 4) (match_dup 5))]
6850 "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
6851 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
6852 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6853 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6854 [(set_attr "type" "fpmove,*")
6855 (set_attr "length" "*,2")
6856 (set_attr "fptype" "double,*")])
6858 (define_expand "absdf2"
6859 [(set (match_operand:DF 0 "register_operand" "")
6860 (abs:DF (match_operand:DF 1 "register_operand" "")))]
6864 (define_insn_and_split "*absdf2_notv9"
6865 [(set (match_operand:DF 0 "register_operand" "=e,e")
6866 (abs:DF (match_operand:DF 1 "register_operand" "0,e")))]
6867 "TARGET_FPU && ! TARGET_V9"
6871 "&& reload_completed
6872 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6873 [(set (match_dup 2) (abs:SF (match_dup 3)))
6874 (set (match_dup 4) (match_dup 5))]
6875 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6876 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6877 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6878 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);"
6879 [(set_attr "type" "fpmove,*")
6880 (set_attr "length" "*,2")])
6882 (define_insn "*absdf2_v9"
6883 [(set (match_operand:DF 0 "register_operand" "=e")
6884 (abs:DF (match_operand:DF 1 "register_operand" "e")))]
6885 "TARGET_FPU && TARGET_V9"
6887 [(set_attr "type" "fpmove")
6888 (set_attr "fptype" "double")])
6890 (define_insn "abssf2"
6891 [(set (match_operand:SF 0 "register_operand" "=f")
6892 (abs:SF (match_operand:SF 1 "register_operand" "f")))]
6895 [(set_attr "type" "fpmove")])
6897 (define_expand "sqrttf2"
6898 [(set (match_operand:TF 0 "nonimmediate_operand" "")
6899 (sqrt:TF (match_operand:TF 1 "general_operand" "")))]
6900 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6901 "emit_tfmode_unop (SQRT, operands); DONE;")
6903 (define_insn "*sqrttf2_hq"
6904 [(set (match_operand:TF 0 "register_operand" "=e")
6905 (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
6906 "TARGET_FPU && TARGET_HARD_QUAD"
6908 [(set_attr "type" "fpsqrtd")])
6910 (define_insn "sqrtdf2"
6911 [(set (match_operand:DF 0 "register_operand" "=e")
6912 (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
6915 [(set_attr "type" "fpsqrtd")
6916 (set_attr "fptype" "double")])
6918 (define_insn "sqrtsf2"
6919 [(set (match_operand:SF 0 "register_operand" "=f")
6920 (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
6923 [(set_attr "type" "fpsqrts")])
6925 ;;- arithmetic shift instructions
6927 (define_insn "ashlsi3"
6928 [(set (match_operand:SI 0 "register_operand" "=r")
6929 (ashift:SI (match_operand:SI 1 "register_operand" "r")
6930 (match_operand:SI 2 "arith_operand" "rI")))]
6933 if (operands[2] == const1_rtx)
6934 return "add\t%1, %1, %0";
6935 if (GET_CODE (operands[2]) == CONST_INT)
6936 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6937 return "sll\t%1, %2, %0";
6940 (if_then_else (match_operand 2 "const1_operand" "")
6941 (const_string "ialu") (const_string "shift")))])
6943 (define_expand "ashldi3"
6944 [(set (match_operand:DI 0 "register_operand" "=r")
6945 (ashift:DI (match_operand:DI 1 "register_operand" "r")
6946 (match_operand:SI 2 "arith_operand" "rI")))]
6947 "TARGET_ARCH64 || TARGET_V8PLUS"
6949 if (! TARGET_ARCH64)
6951 if (GET_CODE (operands[2]) == CONST_INT)
6953 emit_insn (gen_ashldi3_v8plus (operands[0], operands[1], operands[2]));
6958 (define_insn "*ashldi3_sp64"
6959 [(set (match_operand:DI 0 "register_operand" "=r")
6960 (ashift:DI (match_operand:DI 1 "register_operand" "r")
6961 (match_operand:SI 2 "arith_operand" "rI")))]
6964 if (operands[2] == const1_rtx)
6965 return "add\t%1, %1, %0";
6966 if (GET_CODE (operands[2]) == CONST_INT)
6967 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
6968 return "sllx\t%1, %2, %0";
6971 (if_then_else (match_operand 2 "const1_operand" "")
6972 (const_string "ialu") (const_string "shift")))])
6975 (define_insn "ashldi3_v8plus"
6976 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
6977 (ashift:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
6978 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
6979 (clobber (match_scratch:SI 3 "=X,X,&h"))]
6981 "* return output_v8plus_shift (operands, insn, \"sllx\");"
6982 [(set_attr "type" "multi")
6983 (set_attr "length" "5,5,6")])
6985 ;; Optimize (1LL<<x)-1
6986 ;; XXX this also needs to be fixed to handle equal subregs
6987 ;; XXX first before we could re-enable it.
6989 ; [(set (match_operand:DI 0 "register_operand" "=h")
6990 ; (plus:DI (ashift:DI (const_int 1)
6991 ; (match_operand:SI 1 "arith_operand" "rI"))
6993 ; "0 && TARGET_V8PLUS"
6995 ; if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == REGNO (operands[0]))
6996 ; return "mov\t1, %L0\;sllx\t%L0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
6997 ; return "mov\t1, %H0\;sllx\t%H0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
6999 ; [(set_attr "type" "multi")
7000 ; (set_attr "length" "4")])
7002 (define_insn "*cmp_cc_ashift_1"
7003 [(set (reg:CC_NOOV 100)
7004 (compare:CC_NOOV (ashift:SI (match_operand:SI 0 "register_operand" "r")
7008 "addcc\t%0, %0, %%g0"
7009 [(set_attr "type" "compare")])
7011 (define_insn "*cmp_cc_set_ashift_1"
7012 [(set (reg:CC_NOOV 100)
7013 (compare:CC_NOOV (ashift:SI (match_operand:SI 1 "register_operand" "r")
7016 (set (match_operand:SI 0 "register_operand" "=r")
7017 (ashift:SI (match_dup 1) (const_int 1)))]
7020 [(set_attr "type" "compare")])
7022 (define_insn "ashrsi3"
7023 [(set (match_operand:SI 0 "register_operand" "=r")
7024 (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
7025 (match_operand:SI 2 "arith_operand" "rI")))]
7028 if (GET_CODE (operands[2]) == CONST_INT)
7029 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
7030 return "sra\t%1, %2, %0";
7032 [(set_attr "type" "shift")])
7034 (define_insn "*ashrsi3_extend"
7035 [(set (match_operand:DI 0 "register_operand" "=r")
7036 (sign_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
7037 (match_operand:SI 2 "arith_operand" "r"))))]
7040 [(set_attr "type" "shift")])
7042 ;; This handles the case as above, but with constant shift instead of
7043 ;; register. Combiner "simplifies" it for us a little bit though.
7044 (define_insn "*ashrsi3_extend2"
7045 [(set (match_operand:DI 0 "register_operand" "=r")
7046 (ashiftrt:DI (ashift:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
7048 (match_operand:SI 2 "small_int_or_double" "n")))]
7050 && ((GET_CODE (operands[2]) == CONST_INT
7051 && INTVAL (operands[2]) >= 32 && INTVAL (operands[2]) < 64)
7052 || (GET_CODE (operands[2]) == CONST_DOUBLE
7053 && !CONST_DOUBLE_HIGH (operands[2])
7054 && CONST_DOUBLE_LOW (operands[2]) >= 32
7055 && CONST_DOUBLE_LOW (operands[2]) < 64))"
7057 operands[2] = GEN_INT (INTVAL (operands[2]) - 32);
7059 return "sra\t%1, %2, %0";
7061 [(set_attr "type" "shift")])
7063 (define_expand "ashrdi3"
7064 [(set (match_operand:DI 0 "register_operand" "=r")
7065 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
7066 (match_operand:SI 2 "arith_operand" "rI")))]
7067 "TARGET_ARCH64 || TARGET_V8PLUS"
7069 if (! TARGET_ARCH64)
7071 if (GET_CODE (operands[2]) == CONST_INT)
7072 FAIL; /* prefer generic code in this case */
7073 emit_insn (gen_ashrdi3_v8plus (operands[0], operands[1], operands[2]));
7078 (define_insn "*ashrdi3_sp64"
7079 [(set (match_operand:DI 0 "register_operand" "=r")
7080 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
7081 (match_operand:SI 2 "arith_operand" "rI")))]
7085 if (GET_CODE (operands[2]) == CONST_INT)
7086 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
7087 return "srax\t%1, %2, %0";
7089 [(set_attr "type" "shift")])
7092 (define_insn "ashrdi3_v8plus"
7093 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
7094 (ashiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
7095 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
7096 (clobber (match_scratch:SI 3 "=X,X,&h"))]
7098 "* return output_v8plus_shift (operands, insn, \"srax\");"
7099 [(set_attr "type" "multi")
7100 (set_attr "length" "5,5,6")])
7102 (define_insn "lshrsi3"
7103 [(set (match_operand:SI 0 "register_operand" "=r")
7104 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
7105 (match_operand:SI 2 "arith_operand" "rI")))]
7108 if (GET_CODE (operands[2]) == CONST_INT)
7109 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
7110 return "srl\t%1, %2, %0";
7112 [(set_attr "type" "shift")])
7114 ;; This handles the case where
7115 ;; (zero_extend:DI (lshiftrt:SI (match_operand:SI) (match_operand:SI))),
7116 ;; but combiner "simplifies" it for us.
7117 (define_insn "*lshrsi3_extend"
7118 [(set (match_operand:DI 0 "register_operand" "=r")
7119 (and:DI (subreg:DI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
7120 (match_operand:SI 2 "arith_operand" "r")) 0)
7121 (match_operand 3 "" "")))]
7123 && ((GET_CODE (operands[3]) == CONST_DOUBLE
7124 && CONST_DOUBLE_HIGH (operands[3]) == 0
7125 && CONST_DOUBLE_LOW (operands[3]) == 0xffffffff)
7126 || (HOST_BITS_PER_WIDE_INT >= 64
7127 && GET_CODE (operands[3]) == CONST_INT
7128 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) == 0xffffffff))"
7130 [(set_attr "type" "shift")])
7132 ;; This handles the case where
7133 ;; (lshiftrt:DI (zero_extend:DI (match_operand:SI)) (const_int >=0 < 32))
7134 ;; but combiner "simplifies" it for us.
7135 (define_insn "*lshrsi3_extend2"
7136 [(set (match_operand:DI 0 "register_operand" "=r")
7137 (zero_extract:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
7138 (match_operand 2 "small_int_or_double" "n")
7141 && ((GET_CODE (operands[2]) == CONST_INT
7142 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
7143 || (GET_CODE (operands[2]) == CONST_DOUBLE
7144 && CONST_DOUBLE_HIGH (operands[2]) == 0
7145 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
7147 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
7149 return "srl\t%1, %2, %0";
7151 [(set_attr "type" "shift")])
7153 (define_expand "lshrdi3"
7154 [(set (match_operand:DI 0 "register_operand" "=r")
7155 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
7156 (match_operand:SI 2 "arith_operand" "rI")))]
7157 "TARGET_ARCH64 || TARGET_V8PLUS"
7159 if (! TARGET_ARCH64)
7161 if (GET_CODE (operands[2]) == CONST_INT)
7163 emit_insn (gen_lshrdi3_v8plus (operands[0], operands[1], operands[2]));
7168 (define_insn "*lshrdi3_sp64"
7169 [(set (match_operand:DI 0 "register_operand" "=r")
7170 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
7171 (match_operand:SI 2 "arith_operand" "rI")))]
7174 if (GET_CODE (operands[2]) == CONST_INT)
7175 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
7176 return "srlx\t%1, %2, %0";
7178 [(set_attr "type" "shift")])
7181 (define_insn "lshrdi3_v8plus"
7182 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
7183 (lshiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
7184 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
7185 (clobber (match_scratch:SI 3 "=X,X,&h"))]
7187 "* return output_v8plus_shift (operands, insn, \"srlx\");"
7188 [(set_attr "type" "multi")
7189 (set_attr "length" "5,5,6")])
7192 [(set (match_operand:SI 0 "register_operand" "=r")
7193 (ashiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
7195 (match_operand:SI 2 "small_int_or_double" "n")))]
7197 && ((GET_CODE (operands[2]) == CONST_INT
7198 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
7199 || (GET_CODE (operands[2]) == CONST_DOUBLE
7200 && !CONST_DOUBLE_HIGH (operands[2])
7201 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
7203 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
7205 return "srax\t%1, %2, %0";
7207 [(set_attr "type" "shift")])
7210 [(set (match_operand:SI 0 "register_operand" "=r")
7211 (lshiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
7213 (match_operand:SI 2 "small_int_or_double" "n")))]
7215 && ((GET_CODE (operands[2]) == CONST_INT
7216 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
7217 || (GET_CODE (operands[2]) == CONST_DOUBLE
7218 && !CONST_DOUBLE_HIGH (operands[2])
7219 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
7221 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
7223 return "srlx\t%1, %2, %0";
7225 [(set_attr "type" "shift")])
7228 [(set (match_operand:SI 0 "register_operand" "=r")
7229 (ashiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
7230 (match_operand:SI 2 "small_int_or_double" "n")) 4)
7231 (match_operand:SI 3 "small_int_or_double" "n")))]
7233 && GET_CODE (operands[2]) == CONST_INT && GET_CODE (operands[3]) == CONST_INT
7234 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
7235 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
7236 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
7238 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
7240 return "srax\t%1, %2, %0";
7242 [(set_attr "type" "shift")])
7245 [(set (match_operand:SI 0 "register_operand" "=r")
7246 (lshiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
7247 (match_operand:SI 2 "small_int_or_double" "n")) 4)
7248 (match_operand:SI 3 "small_int_or_double" "n")))]
7250 && GET_CODE (operands[2]) == CONST_INT && GET_CODE (operands[3]) == CONST_INT
7251 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
7252 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
7253 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
7255 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
7257 return "srlx\t%1, %2, %0";
7259 [(set_attr "type" "shift")])
7261 ;; Unconditional and other jump instructions
7262 ;; On the SPARC, by setting the annul bit on an unconditional branch, the
7263 ;; following insn is never executed. This saves us a nop. Dbx does not
7264 ;; handle such branches though, so we only use them when optimizing.
7266 [(set (pc) (label_ref (match_operand 0 "" "")))]
7269 /* TurboSPARC is reported to have problems with
7272 i.e. an empty loop with the annul bit set. The workaround is to use
7276 if (! TARGET_V9 && flag_delayed_branch
7277 && (INSN_ADDRESSES (INSN_UID (operands[0]))
7278 == INSN_ADDRESSES (INSN_UID (insn))))
7281 return TARGET_V9 ? "ba%*,pt\t%%xcc, %l0%(" : "b%*\t%l0%(";
7283 [(set_attr "type" "uncond_branch")])
7285 (define_expand "tablejump"
7286 [(parallel [(set (pc) (match_operand 0 "register_operand" "r"))
7287 (use (label_ref (match_operand 1 "" "")))])]
7290 if (GET_MODE (operands[0]) != CASE_VECTOR_MODE)
7293 /* In pic mode, our address differences are against the base of the
7294 table. Add that base value back in; CSE ought to be able to combine
7295 the two address loads. */
7299 tmp = gen_rtx_LABEL_REF (Pmode, operands[1]);
7301 if (CASE_VECTOR_MODE != Pmode)
7302 tmp2 = gen_rtx_SIGN_EXTEND (Pmode, tmp2);
7303 tmp = gen_rtx_PLUS (Pmode, tmp2, tmp);
7304 operands[0] = memory_address (Pmode, tmp);
7308 (define_insn "*tablejump_sp32"
7309 [(set (pc) (match_operand:SI 0 "address_operand" "p"))
7310 (use (label_ref (match_operand 1 "" "")))]
7313 [(set_attr "type" "uncond_branch")])
7315 (define_insn "*tablejump_sp64"
7316 [(set (pc) (match_operand:DI 0 "address_operand" "p"))
7317 (use (label_ref (match_operand 1 "" "")))]
7320 [(set_attr "type" "uncond_branch")])
7322 ;;- jump to subroutine
7323 (define_expand "call"
7324 ;; Note that this expression is not used for generating RTL.
7325 ;; All the RTL is generated explicitly below.
7326 [(call (match_operand 0 "call_operand" "")
7327 (match_operand 3 "" "i"))]
7328 ;; operands[2] is next_arg_register
7329 ;; operands[3] is struct_value_size_rtx.
7334 if (GET_MODE (operands[0]) != FUNCTION_MODE)
7337 if (GET_CODE (operands[3]) != CONST_INT)
7340 if (GET_CODE (XEXP (operands[0], 0)) == LABEL_REF)
7342 /* This is really a PIC sequence. We want to represent
7343 it as a funny jump so its delay slots can be filled.
7345 ??? But if this really *is* a CALL, will not it clobber the
7346 call-clobbered registers? We lose this if it is a JUMP_INSN.
7347 Why cannot we have delay slots filled if it were a CALL? */
7349 /* We accept negative sizes for untyped calls. */
7350 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
7355 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
7357 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
7363 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
7364 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
7368 fn_rtx = operands[0];
7370 /* We accept negative sizes for untyped calls. */
7371 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
7375 gen_rtvec (3, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx),
7377 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
7382 gen_rtvec (2, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx),
7383 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
7390 ;; We can't use the same pattern for these two insns, because then registers
7391 ;; in the address may not be properly reloaded.
7393 (define_insn "*call_address_sp32"
7394 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
7395 (match_operand 1 "" ""))
7396 (clobber (reg:SI 15))]
7397 ;;- Do not use operand 1 for most machines.
7400 [(set_attr "type" "call")])
7402 (define_insn "*call_symbolic_sp32"
7403 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
7404 (match_operand 1 "" ""))
7405 (clobber (reg:SI 15))]
7406 ;;- Do not use operand 1 for most machines.
7409 [(set_attr "type" "call")])
7411 (define_insn "*call_address_sp64"
7412 [(call (mem:DI (match_operand:DI 0 "address_operand" "p"))
7413 (match_operand 1 "" ""))
7414 (clobber (reg:DI 15))]
7415 ;;- Do not use operand 1 for most machines.
7418 [(set_attr "type" "call")])
7420 (define_insn "*call_symbolic_sp64"
7421 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
7422 (match_operand 1 "" ""))
7423 (clobber (reg:DI 15))]
7424 ;;- Do not use operand 1 for most machines.
7427 [(set_attr "type" "call")])
7429 ;; This is a call that wants a structure value.
7430 ;; There is no such critter for v9 (??? we may need one anyway).
7431 (define_insn "*call_address_struct_value_sp32"
7432 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
7433 (match_operand 1 "" ""))
7434 (match_operand 2 "immediate_operand" "")
7435 (clobber (reg:SI 15))]
7436 ;;- Do not use operand 1 for most machines.
7437 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
7438 "call\t%a0, %1\n\t nop\n\tunimp\t%2"
7439 [(set_attr "type" "call_no_delay_slot")
7440 (set_attr "length" "3")])
7442 ;; This is a call that wants a structure value.
7443 ;; There is no such critter for v9 (??? we may need one anyway).
7444 (define_insn "*call_symbolic_struct_value_sp32"
7445 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
7446 (match_operand 1 "" ""))
7447 (match_operand 2 "immediate_operand" "")
7448 (clobber (reg:SI 15))]
7449 ;;- Do not use operand 1 for most machines.
7450 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
7451 "call\t%a0, %1\n\t nop\n\tunimp\t%2"
7452 [(set_attr "type" "call_no_delay_slot")
7453 (set_attr "length" "3")])
7455 ;; This is a call that may want a structure value. This is used for
7457 (define_insn "*call_address_untyped_struct_value_sp32"
7458 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
7459 (match_operand 1 "" ""))
7460 (match_operand 2 "immediate_operand" "")
7461 (clobber (reg:SI 15))]
7462 ;;- Do not use operand 1 for most machines.
7463 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
7464 "call\t%a0, %1\n\t nop\n\tnop"
7465 [(set_attr "type" "call_no_delay_slot")
7466 (set_attr "length" "3")])
7468 ;; This is a call that may want a structure value. This is used for
7470 (define_insn "*call_symbolic_untyped_struct_value_sp32"
7471 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
7472 (match_operand 1 "" ""))
7473 (match_operand 2 "immediate_operand" "")
7474 (clobber (reg:SI 15))]
7475 ;;- Do not use operand 1 for most machines.
7476 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
7477 "call\t%a0, %1\n\t nop\n\tnop"
7478 [(set_attr "type" "call_no_delay_slot")
7479 (set_attr "length" "3")])
7481 (define_expand "call_value"
7482 ;; Note that this expression is not used for generating RTL.
7483 ;; All the RTL is generated explicitly below.
7484 [(set (match_operand 0 "register_operand" "=rf")
7485 (call (match_operand 1 "" "")
7486 (match_operand 4 "" "")))]
7487 ;; operand 2 is stack_size_rtx
7488 ;; operand 3 is next_arg_register
7494 if (GET_MODE (operands[1]) != FUNCTION_MODE)
7497 fn_rtx = operands[1];
7500 gen_rtx_SET (VOIDmode, operands[0],
7501 gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx)),
7502 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)));
7504 emit_call_insn (gen_rtx_PARALLEL (VOIDmode, vec));
7509 (define_insn "*call_value_address_sp32"
7510 [(set (match_operand 0 "" "=rf")
7511 (call (mem:SI (match_operand:SI 1 "address_operand" "p"))
7512 (match_operand 2 "" "")))
7513 (clobber (reg:SI 15))]
7514 ;;- Do not use operand 2 for most machines.
7517 [(set_attr "type" "call")])
7519 (define_insn "*call_value_symbolic_sp32"
7520 [(set (match_operand 0 "" "=rf")
7521 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
7522 (match_operand 2 "" "")))
7523 (clobber (reg:SI 15))]
7524 ;;- Do not use operand 2 for most machines.
7527 [(set_attr "type" "call")])
7529 (define_insn "*call_value_address_sp64"
7530 [(set (match_operand 0 "" "")
7531 (call (mem:DI (match_operand:DI 1 "address_operand" "p"))
7532 (match_operand 2 "" "")))
7533 (clobber (reg:DI 15))]
7534 ;;- Do not use operand 2 for most machines.
7537 [(set_attr "type" "call")])
7539 (define_insn "*call_value_symbolic_sp64"
7540 [(set (match_operand 0 "" "")
7541 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
7542 (match_operand 2 "" "")))
7543 (clobber (reg:DI 15))]
7544 ;;- Do not use operand 2 for most machines.
7547 [(set_attr "type" "call")])
7549 (define_expand "untyped_call"
7550 [(parallel [(call (match_operand 0 "" "")
7552 (match_operand 1 "" "")
7553 (match_operand 2 "" "")])]
7558 /* Pass constm1 to indicate that it may expect a structure value, but
7559 we don't know what size it is. */
7560 emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, constm1_rtx));
7562 for (i = 0; i < XVECLEN (operands[2], 0); i++)
7564 rtx set = XVECEXP (operands[2], 0, i);
7565 emit_move_insn (SET_DEST (set), SET_SRC (set));
7568 /* The optimizer does not know that the call sets the function value
7569 registers we stored in the result block. We avoid problems by
7570 claiming that all hard registers are used and clobbered at this
7572 emit_insn (gen_blockage ());
7578 (define_expand "sibcall"
7579 [(parallel [(call (match_operand 0 "call_operand" "") (const_int 0))
7584 (define_insn "*sibcall_symbolic_sp32"
7585 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
7586 (match_operand 1 "" ""))
7589 "* return output_sibcall(insn, operands[0]);"
7590 [(set_attr "type" "sibcall")])
7592 (define_insn "*sibcall_symbolic_sp64"
7593 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
7594 (match_operand 1 "" ""))
7597 "* return output_sibcall(insn, operands[0]);"
7598 [(set_attr "type" "sibcall")])
7600 (define_expand "sibcall_value"
7601 [(parallel [(set (match_operand 0 "register_operand" "=rf")
7602 (call (match_operand 1 "" "") (const_int 0)))
7607 (define_insn "*sibcall_value_symbolic_sp32"
7608 [(set (match_operand 0 "" "=rf")
7609 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
7610 (match_operand 2 "" "")))
7613 "* return output_sibcall(insn, operands[1]);"
7614 [(set_attr "type" "sibcall")])
7616 (define_insn "*sibcall_value_symbolic_sp64"
7617 [(set (match_operand 0 "" "")
7618 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
7619 (match_operand 2 "" "")))
7622 "* return output_sibcall(insn, operands[1]);"
7623 [(set_attr "type" "sibcall")])
7625 (define_expand "sibcall_epilogue"
7629 sparc_expand_epilogue ();
7633 (define_expand "prologue"
7637 sparc_expand_prologue ();
7641 (define_expand "save_register_window"
7642 [(use (match_operand 0 "arith_operand" ""))]
7648 gen_rtx_SET (VOIDmode,
7650 gen_rtx_PLUS (Pmode,
7651 hard_frame_pointer_rtx,
7653 gen_rtx_UNSPEC_VOLATILE (VOIDmode,
7654 gen_rtvec (1, const0_rtx),
7657 emit_insn (gen_rtx_PARALLEL (VOIDmode, vec));
7661 (define_insn "*save_register_windowsi"
7662 [(set (reg:SI 14) (plus:SI (reg:SI 30)
7663 (match_operand:SI 0 "arith_operand" "rI")))
7664 (unspec_volatile [(const_int 0)] UNSPECV_SAVEW)]
7666 "save\t%%sp, %0, %%sp"
7667 [(set_attr "type" "savew")])
7669 (define_insn "*save_register_windowdi"
7670 [(set (reg:DI 14) (plus:DI (reg:DI 30)
7671 (match_operand:DI 0 "arith_operand" "rI")))
7672 (unspec_volatile [(const_int 0)] UNSPECV_SAVEW)]
7674 "save\t%%sp, %0, %%sp"
7675 [(set_attr "type" "savew")])
7677 (define_expand "epilogue"
7681 sparc_expand_epilogue ();
7684 (define_insn "*return_internal"
7687 "* return output_return (insn);"
7688 [(set_attr "type" "return")
7689 (set_attr "length" "2")])
7691 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
7692 ;; all of memory. This blocks insns from being moved across this point.
7694 (define_insn "blockage"
7695 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
7698 [(set_attr "length" "0")])
7700 ;; Prepare to return any type including a structure value.
7702 (define_expand "untyped_return"
7703 [(match_operand:BLK 0 "memory_operand" "")
7704 (match_operand 1 "" "")]
7707 rtx valreg1 = gen_rtx_REG (DImode, 24);
7708 rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
7709 rtx result = operands[0];
7711 if (! TARGET_ARCH64)
7713 rtx rtnreg = gen_rtx_REG (SImode, (current_function_uses_only_leaf_regs
7715 rtx value = gen_reg_rtx (SImode);
7717 /* Fetch the instruction where we will return to and see if it's an unimp
7718 instruction (the most significant 10 bits will be zero). If so,
7719 update the return address to skip the unimp instruction. */
7720 emit_move_insn (value,
7721 gen_rtx_MEM (SImode, plus_constant (rtnreg, 8)));
7722 emit_insn (gen_lshrsi3 (value, value, GEN_INT (22)));
7723 emit_insn (gen_update_return (rtnreg, value));
7726 /* Reload the function value registers. */
7727 emit_move_insn (valreg1, adjust_address (result, DImode, 0));
7728 emit_move_insn (valreg2,
7729 adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8));
7731 /* Put USE insns before the return. */
7732 emit_insn (gen_rtx_USE (VOIDmode, valreg1));
7733 emit_insn (gen_rtx_USE (VOIDmode, valreg2));
7735 /* Construct the return. */
7736 expand_naked_return ();
7741 ;; This is a bit of a hack. We're incrementing a fixed register (%i7),
7742 ;; and parts of the compiler don't want to believe that the add is needed.
7744 (define_insn "update_return"
7745 [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
7746 (match_operand:SI 1 "register_operand" "r")] UNSPEC_UPDATE_RETURN)]
7748 "cmp\t%1, 0\;be,a\t.+8\;add\t%0, 4, %0"
7749 [(set_attr "type" "multi")
7750 (set_attr "length" "3")])
7757 (define_expand "indirect_jump"
7758 [(set (pc) (match_operand 0 "address_operand" "p"))]
7762 (define_insn "*branch_sp32"
7763 [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
7766 [(set_attr "type" "uncond_branch")])
7768 (define_insn "*branch_sp64"
7769 [(set (pc) (match_operand:DI 0 "address_operand" "p"))]
7772 [(set_attr "type" "uncond_branch")])
7774 (define_expand "nonlocal_goto"
7775 [(match_operand:SI 0 "general_operand" "")
7776 (match_operand:SI 1 "general_operand" "")
7777 (match_operand:SI 2 "general_operand" "")
7778 (match_operand:SI 3 "" "")]
7782 rtx chain = operands[0];
7784 rtx lab = operands[1];
7785 rtx stack = operands[2];
7786 rtx fp = operands[3];
7789 /* Trap instruction to flush all the register windows. */
7790 emit_insn (gen_flush_register_windows ());
7792 /* Load the fp value for the containing fn into %fp. This is needed
7793 because STACK refers to %fp. Note that virtual register instantiation
7794 fails if the virtual %fp isn't set from a register. */
7795 if (GET_CODE (fp) != REG)
7796 fp = force_reg (Pmode, fp);
7797 emit_move_insn (virtual_stack_vars_rtx, fp);
7799 /* Find the containing function's current nonlocal goto handler,
7800 which will do any cleanups and then jump to the label. */
7801 labreg = gen_rtx_REG (Pmode, 8);
7802 emit_move_insn (labreg, lab);
7804 /* Restore %fp from stack pointer value for containing function.
7805 The restore insn that follows will move this to %sp,
7806 and reload the appropriate value into %fp. */
7807 emit_move_insn (hard_frame_pointer_rtx, stack);
7809 /* USE of frame_pointer_rtx added for consistency; not clear if
7811 /*emit_insn (gen_rtx_USE (VOIDmode, frame_pointer_rtx));*/
7812 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
7815 /* Return, restoring reg window and jumping to goto handler. */
7816 if (TARGET_V9 && GET_CODE (chain) == CONST_INT
7817 && ! (INTVAL (chain) & ~(HOST_WIDE_INT)0xffffffff))
7819 emit_jump_insn (gen_goto_handler_and_restore_v9 (labreg,
7825 /* Put in the static chain register the nonlocal label address. */
7826 emit_move_insn (static_chain_rtx, chain);
7829 emit_insn (gen_rtx_USE (VOIDmode, static_chain_rtx));
7830 emit_jump_insn (gen_goto_handler_and_restore (labreg));
7835 ;; Special trap insn to flush register windows.
7836 (define_insn "flush_register_windows"
7837 [(unspec_volatile [(const_int 0)] UNSPECV_FLUSHW)]
7839 { return TARGET_V9 ? "flushw" : "ta\t3"; }
7840 [(set_attr "type" "flushw")])
7842 (define_insn "goto_handler_and_restore"
7843 [(unspec_volatile [(match_operand 0 "register_operand" "=r")] UNSPECV_GOTO)]
7844 "GET_MODE (operands[0]) == Pmode"
7845 "jmp\t%0+0\n\trestore"
7846 [(set_attr "type" "multi")
7847 (set_attr "length" "2")])
7849 ;;(define_insn "goto_handler_and_restore_v9"
7850 ;; [(unspec_volatile [(match_operand:SI 0 "register_operand" "=r,r")
7851 ;; (match_operand:SI 1 "register_operand" "=r,r")
7852 ;; (match_operand:SI 2 "const_int_operand" "I,n")] UNSPECV_GOTO_V9)]
7853 ;; "TARGET_V9 && ! TARGET_ARCH64"
7855 ;; return\t%0+0\n\tmov\t%2, %Y1
7856 ;; sethi\t%%hi(%2), %1\n\treturn\t%0+0\n\tor\t%Y1, %%lo(%2), %Y1"
7857 ;; [(set_attr "type" "multi")
7858 ;; (set_attr "length" "2,3")])
7860 ;;(define_insn "*goto_handler_and_restore_v9_sp64"
7861 ;; [(unspec_volatile [(match_operand:DI 0 "register_operand" "=r,r")
7862 ;; (match_operand:DI 1 "register_operand" "=r,r")
7863 ;; (match_operand:SI 2 "const_int_operand" "I,n")] UNSPECV_GOTO_V9)]
7864 ;; "TARGET_V9 && TARGET_ARCH64"
7866 ;; return\t%0+0\n\tmov\t%2, %Y1
7867 ;; sethi\t%%hi(%2), %1\n\treturn\t%0+0\n\tor\t%Y1, %%lo(%2), %Y1"
7868 ;; [(set_attr "type" "multi")
7869 ;; (set_attr "length" "2,3")])
7871 ;; For __builtin_setjmp we need to flush register windows iff the function
7872 ;; calls alloca as well, because otherwise the register window might be
7873 ;; saved after %sp adjustment and thus setjmp would crash
7874 (define_expand "builtin_setjmp_setup"
7875 [(match_operand 0 "register_operand" "r")]
7878 emit_insn (gen_do_builtin_setjmp_setup ());
7882 (define_insn "do_builtin_setjmp_setup"
7883 [(unspec_volatile [(const_int 0)] UNSPECV_SETJMP)]
7886 if (! current_function_calls_alloca)
7890 fputs ("\tflushw\n", asm_out_file);
7892 fprintf (asm_out_file, "\tst%c\t%%l7, [%%sp+%d]\n",
7893 TARGET_ARCH64 ? 'x' : 'w',
7894 SPARC_STACK_BIAS + 7 * UNITS_PER_WORD);
7895 fprintf (asm_out_file, "\tst%c\t%%fp, [%%sp+%d]\n",
7896 TARGET_ARCH64 ? 'x' : 'w',
7897 SPARC_STACK_BIAS + 14 * UNITS_PER_WORD);
7898 fprintf (asm_out_file, "\tst%c\t%%i7, [%%sp+%d]\n",
7899 TARGET_ARCH64 ? 'x' : 'w',
7900 SPARC_STACK_BIAS + 15 * UNITS_PER_WORD);
7903 [(set_attr "type" "multi")
7904 (set (attr "length")
7905 (cond [(eq_attr "current_function_calls_alloca" "false")
7907 (eq_attr "isa" "!v9")
7909 (eq_attr "pic" "true")
7910 (const_int 4)] (const_int 3)))])
7912 ;; Pattern for use after a setjmp to store FP and the return register
7913 ;; into the stack area.
7915 (define_expand "setjmp"
7920 emit_insn (gen_setjmp_64 ());
7922 emit_insn (gen_setjmp_32 ());
7926 (define_expand "setjmp_32"
7927 [(set (mem:SI (plus:SI (reg:SI 14) (const_int 56))) (match_dup 0))
7928 (set (mem:SI (plus:SI (reg:SI 14) (const_int 60))) (reg:SI 31))]
7930 { operands[0] = frame_pointer_rtx; })
7932 (define_expand "setjmp_64"
7933 [(set (mem:DI (plus:DI (reg:DI 14) (const_int 112))) (match_dup 0))
7934 (set (mem:DI (plus:DI (reg:DI 14) (const_int 120))) (reg:DI 31))]
7936 { operands[0] = frame_pointer_rtx; })
7938 ;; Special pattern for the FLUSH instruction.
7940 ; We do SImode and DImode versions of this to quiet down genrecog's complaints
7941 ; of the define_insn otherwise missing a mode. We make "flush", aka
7942 ; gen_flush, the default one since sparc_initialize_trampoline uses
7943 ; it on SImode mem values.
7945 (define_insn "flush"
7946 [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")] UNSPECV_FLUSH)]
7948 { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; }
7949 [(set_attr "type" "iflush")])
7951 (define_insn "flushdi"
7952 [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")] UNSPECV_FLUSH)]
7954 { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; }
7955 [(set_attr "type" "iflush")])
7960 ;; The scan instruction searches from the most significant bit while ffs
7961 ;; searches from the least significant bit. The bit index and treatment of
7962 ;; zero also differ. It takes at least 7 instructions to get the proper
7963 ;; result. Here is an obvious 8 instruction sequence.
7966 (define_insn "ffssi2"
7967 [(set (match_operand:SI 0 "register_operand" "=&r")
7968 (ffs:SI (match_operand:SI 1 "register_operand" "r")))
7969 (clobber (match_scratch:SI 2 "=&r"))]
7970 "TARGET_SPARCLITE || TARGET_SPARCLET"
7972 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";
7974 [(set_attr "type" "multi")
7975 (set_attr "length" "8")])
7977 ;; ??? This should be a define expand, so that the extra instruction have
7978 ;; a chance of being optimized away.
7980 ;; Disabled because none of the UltraSPARCs implement popc. The HAL R1
7981 ;; does, but no one uses that and we don't have a switch for it.
7983 ;(define_insn "ffsdi2"
7984 ; [(set (match_operand:DI 0 "register_operand" "=&r")
7985 ; (ffs:DI (match_operand:DI 1 "register_operand" "r")))
7986 ; (clobber (match_scratch:DI 2 "=&r"))]
7988 ; "neg\t%1, %2\;xnor\t%1, %2, %2\;popc\t%2, %0\;movzr\t%1, 0, %0"
7989 ; [(set_attr "type" "multi")
7990 ; (set_attr "length" "4")])
7994 ;; Peepholes go at the end.
7996 ;; Optimize consecutive loads or stores into ldd and std when possible.
7997 ;; The conditions in which we do this are very restricted and are
7998 ;; explained in the code for {registers,memory}_ok_for_ldd functions.
8001 [(set (match_operand:SI 0 "memory_operand" "")
8003 (set (match_operand:SI 1 "memory_operand" "")
8006 && mems_ok_for_ldd_peep (operands[0], operands[1], NULL_RTX)"
8009 "operands[0] = widen_memory_access (operands[0], DImode, 0);")
8012 [(set (match_operand:SI 0 "memory_operand" "")
8014 (set (match_operand:SI 1 "memory_operand" "")
8017 && mems_ok_for_ldd_peep (operands[1], operands[0], NULL_RTX)"
8020 "operands[1] = widen_memory_access (operands[1], DImode, 0);")
8023 [(set (match_operand:SI 0 "register_operand" "")
8024 (match_operand:SI 1 "memory_operand" ""))
8025 (set (match_operand:SI 2 "register_operand" "")
8026 (match_operand:SI 3 "memory_operand" ""))]
8027 "registers_ok_for_ldd_peep (operands[0], operands[2])
8028 && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
8031 "operands[1] = widen_memory_access (operands[1], DImode, 0);
8032 operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));")
8035 [(set (match_operand:SI 0 "memory_operand" "")
8036 (match_operand:SI 1 "register_operand" ""))
8037 (set (match_operand:SI 2 "memory_operand" "")
8038 (match_operand:SI 3 "register_operand" ""))]
8039 "registers_ok_for_ldd_peep (operands[1], operands[3])
8040 && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
8043 "operands[0] = widen_memory_access (operands[0], DImode, 0);
8044 operands[1] = gen_rtx_REG (DImode, REGNO (operands[1]));")
8047 [(set (match_operand:SF 0 "register_operand" "")
8048 (match_operand:SF 1 "memory_operand" ""))
8049 (set (match_operand:SF 2 "register_operand" "")
8050 (match_operand:SF 3 "memory_operand" ""))]
8051 "registers_ok_for_ldd_peep (operands[0], operands[2])
8052 && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
8055 "operands[1] = widen_memory_access (operands[1], DFmode, 0);
8056 operands[0] = gen_rtx_REG (DFmode, REGNO (operands[0]));")
8059 [(set (match_operand:SF 0 "memory_operand" "")
8060 (match_operand:SF 1 "register_operand" ""))
8061 (set (match_operand:SF 2 "memory_operand" "")
8062 (match_operand:SF 3 "register_operand" ""))]
8063 "registers_ok_for_ldd_peep (operands[1], operands[3])
8064 && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
8067 "operands[0] = widen_memory_access (operands[0], DFmode, 0);
8068 operands[1] = gen_rtx_REG (DFmode, REGNO (operands[1]));")
8071 [(set (match_operand:SI 0 "register_operand" "")
8072 (match_operand:SI 1 "memory_operand" ""))
8073 (set (match_operand:SI 2 "register_operand" "")
8074 (match_operand:SI 3 "memory_operand" ""))]
8075 "registers_ok_for_ldd_peep (operands[2], operands[0])
8076 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
8079 "operands[3] = widen_memory_access (operands[3], DImode, 0);
8080 operands[2] = gen_rtx_REG (DImode, REGNO (operands[2]));")
8083 [(set (match_operand:SI 0 "memory_operand" "")
8084 (match_operand:SI 1 "register_operand" ""))
8085 (set (match_operand:SI 2 "memory_operand" "")
8086 (match_operand:SI 3 "register_operand" ""))]
8087 "registers_ok_for_ldd_peep (operands[3], operands[1])
8088 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
8091 "operands[2] = widen_memory_access (operands[2], DImode, 0);
8092 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
8096 [(set (match_operand:SF 0 "register_operand" "")
8097 (match_operand:SF 1 "memory_operand" ""))
8098 (set (match_operand:SF 2 "register_operand" "")
8099 (match_operand:SF 3 "memory_operand" ""))]
8100 "registers_ok_for_ldd_peep (operands[2], operands[0])
8101 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
8104 "operands[3] = widen_memory_access (operands[3], DFmode, 0);
8105 operands[2] = gen_rtx_REG (DFmode, REGNO (operands[2]));")
8108 [(set (match_operand:SF 0 "memory_operand" "")
8109 (match_operand:SF 1 "register_operand" ""))
8110 (set (match_operand:SF 2 "memory_operand" "")
8111 (match_operand:SF 3 "register_operand" ""))]
8112 "registers_ok_for_ldd_peep (operands[3], operands[1])
8113 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
8116 "operands[2] = widen_memory_access (operands[2], DFmode, 0);
8117 operands[3] = gen_rtx_REG (DFmode, REGNO (operands[3]));")
8119 ;; Optimize the case of following a reg-reg move with a test
8120 ;; of reg just moved. Don't allow floating point regs for operand 0 or 1.
8121 ;; This can result from a float to fix conversion.
8124 [(set (match_operand:SI 0 "register_operand" "")
8125 (match_operand:SI 1 "register_operand" ""))
8127 (compare:CC (match_operand:SI 2 "register_operand" "")
8129 "(rtx_equal_p (operands[2], operands[0])
8130 || rtx_equal_p (operands[2], operands[1]))
8131 && ! SPARC_FP_REG_P (REGNO (operands[0]))
8132 && ! SPARC_FP_REG_P (REGNO (operands[1]))"
8133 [(parallel [(set (match_dup 0) (match_dup 1))
8135 (compare:CC (match_dup 1) (const_int 0)))])]
8139 [(set (match_operand:DI 0 "register_operand" "")
8140 (match_operand:DI 1 "register_operand" ""))
8142 (compare:CCX (match_operand:DI 2 "register_operand" "")
8145 && (rtx_equal_p (operands[2], operands[0])
8146 || rtx_equal_p (operands[2], operands[1]))
8147 && ! SPARC_FP_REG_P (REGNO (operands[0]))
8148 && ! SPARC_FP_REG_P (REGNO (operands[1]))"
8149 [(parallel [(set (match_dup 0) (match_dup 1))
8151 (compare:CCX (match_dup 1) (const_int 0)))])]
8154 ;; ??? UltraSPARC-III note: A memory operation loading into the floating point register
8155 ;; ??? file, if it hits the prefetch cache, has a chance to dual-issue with other memory
8156 ;; ??? operations. With DFA we might be able to model this, but it requires a lot of
8158 (define_expand "prefetch"
8159 [(match_operand 0 "address_operand" "")
8160 (match_operand 1 "const_int_operand" "")
8161 (match_operand 2 "const_int_operand" "")]
8165 emit_insn (gen_prefetch_64 (operands[0], operands[1], operands[2]));
8167 emit_insn (gen_prefetch_32 (operands[0], operands[1], operands[2]));
8171 (define_insn "prefetch_64"
8172 [(prefetch (match_operand:DI 0 "address_operand" "p")
8173 (match_operand:DI 1 "const_int_operand" "n")
8174 (match_operand:DI 2 "const_int_operand" "n"))]
8177 static const char * const prefetch_instr[2][2] = {
8179 "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
8180 "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
8183 "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
8184 "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
8187 int read_or_write = INTVAL (operands[1]);
8188 int locality = INTVAL (operands[2]);
8190 if (read_or_write != 0 && read_or_write != 1)
8192 if (locality < 0 || locality > 3)
8194 return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
8196 [(set_attr "type" "load")])
8198 (define_insn "prefetch_32"
8199 [(prefetch (match_operand:SI 0 "address_operand" "p")
8200 (match_operand:SI 1 "const_int_operand" "n")
8201 (match_operand:SI 2 "const_int_operand" "n"))]
8204 static const char * const prefetch_instr[2][2] = {
8206 "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
8207 "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
8210 "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
8211 "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
8214 int read_or_write = INTVAL (operands[1]);
8215 int locality = INTVAL (operands[2]);
8217 if (read_or_write != 0 && read_or_write != 1)
8219 if (locality < 0 || locality > 3)
8221 return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
8223 [(set_attr "type" "load")])
8226 [(trap_if (const_int 1) (const_int 5))]
8229 [(set_attr "type" "trap")])
8231 (define_expand "conditional_trap"
8232 [(trap_if (match_operator 0 "noov_compare_op"
8233 [(match_dup 2) (match_dup 3)])
8234 (match_operand:SI 1 "arith_operand" ""))]
8236 "operands[2] = gen_compare_reg (GET_CODE (operands[0]),
8237 sparc_compare_op0, sparc_compare_op1);
8238 operands[3] = const0_rtx;")
8241 [(trap_if (match_operator 0 "noov_compare_op" [(reg:CC 100) (const_int 0)])
8242 (match_operand:SI 1 "arith_operand" "rM"))]
8245 [(set_attr "type" "trap")])
8248 [(trap_if (match_operator 0 "noov_compare_op" [(reg:CCX 100) (const_int 0)])
8249 (match_operand:SI 1 "arith_operand" "rM"))]
8252 [(set_attr "type" "trap")])
8255 (define_insn "tgd_hi22"
8256 [(set (match_operand:SI 0 "register_operand" "=r")
8257 (high:SI (unspec:SI [(match_operand 1 "tgd_symbolic_operand" "")]
8260 "sethi\\t%%tgd_hi22(%a1), %0")
8262 (define_insn "tgd_lo10"
8263 [(set (match_operand:SI 0 "register_operand" "=r")
8264 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
8265 (unspec:SI [(match_operand 2 "tgd_symbolic_operand" "")]
8268 "add\\t%1, %%tgd_lo10(%a2), %0")
8270 (define_insn "tgd_add32"
8271 [(set (match_operand:SI 0 "register_operand" "=r")
8272 (plus:SI (match_operand:SI 1 "register_operand" "r")
8273 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8274 (match_operand 3 "tgd_symbolic_operand" "")]
8276 "TARGET_TLS && TARGET_ARCH32"
8277 "add\\t%1, %2, %0, %%tgd_add(%a3)")
8279 (define_insn "tgd_add64"
8280 [(set (match_operand:DI 0 "register_operand" "=r")
8281 (plus:DI (match_operand:DI 1 "register_operand" "r")
8282 (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8283 (match_operand 3 "tgd_symbolic_operand" "")]
8285 "TARGET_TLS && TARGET_ARCH64"
8286 "add\\t%1, %2, %0, %%tgd_add(%a3)")
8288 (define_insn "tgd_call32"
8289 [(set (match_operand 0 "register_operand" "=r")
8290 (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")
8291 (match_operand 2 "tgd_symbolic_operand" "")]
8293 (match_operand 3 "" "")))
8294 (clobber (reg:SI 15))]
8295 "TARGET_TLS && TARGET_ARCH32"
8296 "call\t%a1, %%tgd_call(%a2)%#"
8297 [(set_attr "type" "call")])
8299 (define_insn "tgd_call64"
8300 [(set (match_operand 0 "register_operand" "=r")
8301 (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")
8302 (match_operand 2 "tgd_symbolic_operand" "")]
8304 (match_operand 3 "" "")))
8305 (clobber (reg:DI 15))]
8306 "TARGET_TLS && TARGET_ARCH64"
8307 "call\t%a1, %%tgd_call(%a2)%#"
8308 [(set_attr "type" "call")])
8310 (define_insn "tldm_hi22"
8311 [(set (match_operand:SI 0 "register_operand" "=r")
8312 (high:SI (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
8314 "sethi\\t%%tldm_hi22(%&), %0")
8316 (define_insn "tldm_lo10"
8317 [(set (match_operand:SI 0 "register_operand" "=r")
8318 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
8319 (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
8321 "add\\t%1, %%tldm_lo10(%&), %0")
8323 (define_insn "tldm_add32"
8324 [(set (match_operand:SI 0 "register_operand" "=r")
8325 (plus:SI (match_operand:SI 1 "register_operand" "r")
8326 (unspec:SI [(match_operand:SI 2 "register_operand" "r")]
8328 "TARGET_TLS && TARGET_ARCH32"
8329 "add\\t%1, %2, %0, %%tldm_add(%&)")
8331 (define_insn "tldm_add64"
8332 [(set (match_operand:DI 0 "register_operand" "=r")
8333 (plus:DI (match_operand:DI 1 "register_operand" "r")
8334 (unspec:DI [(match_operand:SI 2 "register_operand" "r")]
8336 "TARGET_TLS && TARGET_ARCH64"
8337 "add\\t%1, %2, %0, %%tldm_add(%&)")
8339 (define_insn "tldm_call32"
8340 [(set (match_operand 0 "register_operand" "=r")
8341 (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")]
8343 (match_operand 2 "" "")))
8344 (clobber (reg:SI 15))]
8345 "TARGET_TLS && TARGET_ARCH32"
8346 "call\t%a1, %%tldm_call(%&)%#"
8347 [(set_attr "type" "call")])
8349 (define_insn "tldm_call64"
8350 [(set (match_operand 0 "register_operand" "=r")
8351 (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")]
8353 (match_operand 2 "" "")))
8354 (clobber (reg:DI 15))]
8355 "TARGET_TLS && TARGET_ARCH64"
8356 "call\t%a1, %%tldm_call(%&)%#"
8357 [(set_attr "type" "call")])
8359 (define_insn "tldo_hix22"
8360 [(set (match_operand:SI 0 "register_operand" "=r")
8361 (high:SI (unspec:SI [(match_operand 1 "tld_symbolic_operand" "")]
8364 "sethi\\t%%tldo_hix22(%a1), %0")
8366 (define_insn "tldo_lox10"
8367 [(set (match_operand:SI 0 "register_operand" "=r")
8368 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
8369 (unspec:SI [(match_operand 2 "tld_symbolic_operand" "")]
8372 "xor\\t%1, %%tldo_lox10(%a2), %0")
8374 (define_insn "tldo_add32"
8375 [(set (match_operand:SI 0 "register_operand" "=r")
8376 (plus:SI (match_operand:SI 1 "register_operand" "r")
8377 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8378 (match_operand 3 "tld_symbolic_operand" "")]
8380 "TARGET_TLS && TARGET_ARCH32"
8381 "add\\t%1, %2, %0, %%tldo_add(%a3)")
8383 (define_insn "tldo_add64"
8384 [(set (match_operand:DI 0 "register_operand" "=r")
8385 (plus:DI (match_operand:DI 1 "register_operand" "r")
8386 (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8387 (match_operand 3 "tld_symbolic_operand" "")]
8389 "TARGET_TLS && TARGET_ARCH64"
8390 "add\\t%1, %2, %0, %%tldo_add(%a3)")
8392 (define_insn "tie_hi22"
8393 [(set (match_operand:SI 0 "register_operand" "=r")
8394 (high:SI (unspec:SI [(match_operand 1 "tie_symbolic_operand" "")]
8397 "sethi\\t%%tie_hi22(%a1), %0")
8399 (define_insn "tie_lo10"
8400 [(set (match_operand:SI 0 "register_operand" "=r")
8401 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
8402 (unspec:SI [(match_operand 2 "tie_symbolic_operand" "")]
8405 "add\\t%1, %%tie_lo10(%a2), %0")
8407 (define_insn "tie_ld32"
8408 [(set (match_operand:SI 0 "register_operand" "=r")
8409 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
8410 (match_operand:SI 2 "register_operand" "r")
8411 (match_operand 3 "tie_symbolic_operand" "")]
8413 "TARGET_TLS && TARGET_ARCH32"
8414 "ld\\t[%1 + %2], %0, %%tie_ld(%a3)"
8415 [(set_attr "type" "load")])
8417 (define_insn "tie_ld64"
8418 [(set (match_operand:DI 0 "register_operand" "=r")
8419 (unspec:DI [(match_operand:DI 1 "register_operand" "r")
8420 (match_operand:SI 2 "register_operand" "r")
8421 (match_operand 3 "tie_symbolic_operand" "")]
8423 "TARGET_TLS && TARGET_ARCH64"
8424 "ldx\\t[%1 + %2], %0, %%tie_ldx(%a3)"
8425 [(set_attr "type" "load")])
8427 (define_insn "tie_add32"
8428 [(set (match_operand:SI 0 "register_operand" "=r")
8429 (plus:SI (match_operand:SI 1 "register_operand" "r")
8430 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8431 (match_operand 3 "tie_symbolic_operand" "")]
8433 "TARGET_SUN_TLS && TARGET_ARCH32"
8434 "add\\t%1, %2, %0, %%tie_add(%a3)")
8436 (define_insn "tie_add64"
8437 [(set (match_operand:DI 0 "register_operand" "=r")
8438 (plus:DI (match_operand:DI 1 "register_operand" "r")
8439 (unspec:DI [(match_operand:DI 2 "register_operand" "r")
8440 (match_operand 3 "tie_symbolic_operand" "")]
8442 "TARGET_SUN_TLS && TARGET_ARCH64"
8443 "add\\t%1, %2, %0, %%tie_add(%a3)")
8445 (define_insn "tle_hix22_sp32"
8446 [(set (match_operand:SI 0 "register_operand" "=r")
8447 (high:SI (unspec:SI [(match_operand 1 "tle_symbolic_operand" "")]
8449 "TARGET_TLS && TARGET_ARCH32"
8450 "sethi\\t%%tle_hix22(%a1), %0")
8452 (define_insn "tle_lox10_sp32"
8453 [(set (match_operand:SI 0 "register_operand" "=r")
8454 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
8455 (unspec:SI [(match_operand 2 "tle_symbolic_operand" "")]
8457 "TARGET_TLS && TARGET_ARCH32"
8458 "xor\\t%1, %%tle_lox10(%a2), %0")
8460 (define_insn "tle_hix22_sp64"
8461 [(set (match_operand:DI 0 "register_operand" "=r")
8462 (high:DI (unspec:DI [(match_operand 1 "tle_symbolic_operand" "")]
8464 "TARGET_TLS && TARGET_ARCH64"
8465 "sethi\\t%%tle_hix22(%a1), %0")
8467 (define_insn "tle_lox10_sp64"
8468 [(set (match_operand:DI 0 "register_operand" "=r")
8469 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
8470 (unspec:DI [(match_operand 2 "tle_symbolic_operand" "")]
8472 "TARGET_TLS && TARGET_ARCH64"
8473 "xor\\t%1, %%tle_lox10(%a2), %0")
8475 ;; Now patterns combining tldo_add{32,64} with some integer loads or stores
8476 (define_insn "*tldo_ldub_sp32"
8477 [(set (match_operand:QI 0 "register_operand" "=r")
8478 (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8479 (match_operand 3 "tld_symbolic_operand" "")]
8481 (match_operand:SI 1 "register_operand" "r"))))]
8482 "TARGET_TLS && TARGET_ARCH32"
8483 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8484 [(set_attr "type" "load")
8485 (set_attr "us3load_type" "3cycle")])
8487 (define_insn "*tldo_ldub1_sp32"
8488 [(set (match_operand:HI 0 "register_operand" "=r")
8489 (zero_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8490 (match_operand 3 "tld_symbolic_operand" "")]
8492 (match_operand:SI 1 "register_operand" "r")))))]
8493 "TARGET_TLS && TARGET_ARCH32"
8494 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8495 [(set_attr "type" "load")
8496 (set_attr "us3load_type" "3cycle")])
8498 (define_insn "*tldo_ldub2_sp32"
8499 [(set (match_operand:SI 0 "register_operand" "=r")
8500 (zero_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8501 (match_operand 3 "tld_symbolic_operand" "")]
8503 (match_operand:SI 1 "register_operand" "r")))))]
8504 "TARGET_TLS && TARGET_ARCH32"
8505 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8506 [(set_attr "type" "load")
8507 (set_attr "us3load_type" "3cycle")])
8509 (define_insn "*tldo_ldsb1_sp32"
8510 [(set (match_operand:HI 0 "register_operand" "=r")
8511 (sign_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8512 (match_operand 3 "tld_symbolic_operand" "")]
8514 (match_operand:SI 1 "register_operand" "r")))))]
8515 "TARGET_TLS && TARGET_ARCH32"
8516 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
8517 [(set_attr "type" "sload")
8518 (set_attr "us3load_type" "3cycle")])
8520 (define_insn "*tldo_ldsb2_sp32"
8521 [(set (match_operand:SI 0 "register_operand" "=r")
8522 (sign_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8523 (match_operand 3 "tld_symbolic_operand" "")]
8525 (match_operand:SI 1 "register_operand" "r")))))]
8526 "TARGET_TLS && TARGET_ARCH32"
8527 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
8528 [(set_attr "type" "sload")
8529 (set_attr "us3load_type" "3cycle")])
8531 (define_insn "*tldo_ldub_sp64"
8532 [(set (match_operand:QI 0 "register_operand" "=r")
8533 (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8534 (match_operand 3 "tld_symbolic_operand" "")]
8536 (match_operand:DI 1 "register_operand" "r"))))]
8537 "TARGET_TLS && TARGET_ARCH64"
8538 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8539 [(set_attr "type" "load")
8540 (set_attr "us3load_type" "3cycle")])
8542 (define_insn "*tldo_ldub1_sp64"
8543 [(set (match_operand:HI 0 "register_operand" "=r")
8544 (zero_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8545 (match_operand 3 "tld_symbolic_operand" "")]
8547 (match_operand:DI 1 "register_operand" "r")))))]
8548 "TARGET_TLS && TARGET_ARCH64"
8549 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8550 [(set_attr "type" "load")
8551 (set_attr "us3load_type" "3cycle")])
8553 (define_insn "*tldo_ldub2_sp64"
8554 [(set (match_operand:SI 0 "register_operand" "=r")
8555 (zero_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8556 (match_operand 3 "tld_symbolic_operand" "")]
8558 (match_operand:DI 1 "register_operand" "r")))))]
8559 "TARGET_TLS && TARGET_ARCH64"
8560 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8561 [(set_attr "type" "load")
8562 (set_attr "us3load_type" "3cycle")])
8564 (define_insn "*tldo_ldub3_sp64"
8565 [(set (match_operand:DI 0 "register_operand" "=r")
8566 (zero_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8567 (match_operand 3 "tld_symbolic_operand" "")]
8569 (match_operand:DI 1 "register_operand" "r")))))]
8570 "TARGET_TLS && TARGET_ARCH64"
8571 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8572 [(set_attr "type" "load")
8573 (set_attr "us3load_type" "3cycle")])
8575 (define_insn "*tldo_ldsb1_sp64"
8576 [(set (match_operand:HI 0 "register_operand" "=r")
8577 (sign_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8578 (match_operand 3 "tld_symbolic_operand" "")]
8580 (match_operand:DI 1 "register_operand" "r")))))]
8581 "TARGET_TLS && TARGET_ARCH64"
8582 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
8583 [(set_attr "type" "sload")
8584 (set_attr "us3load_type" "3cycle")])
8586 (define_insn "*tldo_ldsb2_sp64"
8587 [(set (match_operand:SI 0 "register_operand" "=r")
8588 (sign_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8589 (match_operand 3 "tld_symbolic_operand" "")]
8591 (match_operand:DI 1 "register_operand" "r")))))]
8592 "TARGET_TLS && TARGET_ARCH64"
8593 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
8594 [(set_attr "type" "sload")
8595 (set_attr "us3load_type" "3cycle")])
8597 (define_insn "*tldo_ldsb3_sp64"
8598 [(set (match_operand:DI 0 "register_operand" "=r")
8599 (sign_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8600 (match_operand 3 "tld_symbolic_operand" "")]
8602 (match_operand:DI 1 "register_operand" "r")))))]
8603 "TARGET_TLS && TARGET_ARCH64"
8604 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
8605 [(set_attr "type" "sload")
8606 (set_attr "us3load_type" "3cycle")])
8608 (define_insn "*tldo_lduh_sp32"
8609 [(set (match_operand:HI 0 "register_operand" "=r")
8610 (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8611 (match_operand 3 "tld_symbolic_operand" "")]
8613 (match_operand:SI 1 "register_operand" "r"))))]
8614 "TARGET_TLS && TARGET_ARCH32"
8615 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
8616 [(set_attr "type" "load")
8617 (set_attr "us3load_type" "3cycle")])
8619 (define_insn "*tldo_lduh1_sp32"
8620 [(set (match_operand:SI 0 "register_operand" "=r")
8621 (zero_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8622 (match_operand 3 "tld_symbolic_operand" "")]
8624 (match_operand:SI 1 "register_operand" "r")))))]
8625 "TARGET_TLS && TARGET_ARCH32"
8626 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
8627 [(set_attr "type" "load")
8628 (set_attr "us3load_type" "3cycle")])
8630 (define_insn "*tldo_ldsh1_sp32"
8631 [(set (match_operand:SI 0 "register_operand" "=r")
8632 (sign_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8633 (match_operand 3 "tld_symbolic_operand" "")]
8635 (match_operand:SI 1 "register_operand" "r")))))]
8636 "TARGET_TLS && TARGET_ARCH32"
8637 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
8638 [(set_attr "type" "sload")
8639 (set_attr "us3load_type" "3cycle")])
8641 (define_insn "*tldo_lduh_sp64"
8642 [(set (match_operand:HI 0 "register_operand" "=r")
8643 (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8644 (match_operand 3 "tld_symbolic_operand" "")]
8646 (match_operand:DI 1 "register_operand" "r"))))]
8647 "TARGET_TLS && TARGET_ARCH64"
8648 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
8649 [(set_attr "type" "load")
8650 (set_attr "us3load_type" "3cycle")])
8652 (define_insn "*tldo_lduh1_sp64"
8653 [(set (match_operand:SI 0 "register_operand" "=r")
8654 (zero_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8655 (match_operand 3 "tld_symbolic_operand" "")]
8657 (match_operand:DI 1 "register_operand" "r")))))]
8658 "TARGET_TLS && TARGET_ARCH64"
8659 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
8660 [(set_attr "type" "load")
8661 (set_attr "us3load_type" "3cycle")])
8663 (define_insn "*tldo_lduh2_sp64"
8664 [(set (match_operand:DI 0 "register_operand" "=r")
8665 (zero_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8666 (match_operand 3 "tld_symbolic_operand" "")]
8668 (match_operand:DI 1 "register_operand" "r")))))]
8669 "TARGET_TLS && TARGET_ARCH64"
8670 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
8671 [(set_attr "type" "load")
8672 (set_attr "us3load_type" "3cycle")])
8674 (define_insn "*tldo_ldsh1_sp64"
8675 [(set (match_operand:SI 0 "register_operand" "=r")
8676 (sign_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8677 (match_operand 3 "tld_symbolic_operand" "")]
8679 (match_operand:DI 1 "register_operand" "r")))))]
8680 "TARGET_TLS && TARGET_ARCH64"
8681 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
8682 [(set_attr "type" "sload")
8683 (set_attr "us3load_type" "3cycle")])
8685 (define_insn "*tldo_ldsh2_sp64"
8686 [(set (match_operand:DI 0 "register_operand" "=r")
8687 (sign_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8688 (match_operand 3 "tld_symbolic_operand" "")]
8690 (match_operand:DI 1 "register_operand" "r")))))]
8691 "TARGET_TLS && TARGET_ARCH64"
8692 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
8693 [(set_attr "type" "sload")
8694 (set_attr "us3load_type" "3cycle")])
8696 (define_insn "*tldo_lduw_sp32"
8697 [(set (match_operand:SI 0 "register_operand" "=r")
8698 (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8699 (match_operand 3 "tld_symbolic_operand" "")]
8701 (match_operand:SI 1 "register_operand" "r"))))]
8702 "TARGET_TLS && TARGET_ARCH32"
8703 "ld\t[%1 + %2], %0, %%tldo_add(%3)"
8704 [(set_attr "type" "load")])
8706 (define_insn "*tldo_lduw_sp64"
8707 [(set (match_operand:SI 0 "register_operand" "=r")
8708 (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8709 (match_operand 3 "tld_symbolic_operand" "")]
8711 (match_operand:DI 1 "register_operand" "r"))))]
8712 "TARGET_TLS && TARGET_ARCH64"
8713 "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
8714 [(set_attr "type" "load")])
8716 (define_insn "*tldo_lduw1_sp64"
8717 [(set (match_operand:DI 0 "register_operand" "=r")
8718 (zero_extend:DI (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8719 (match_operand 3 "tld_symbolic_operand" "")]
8721 (match_operand:DI 1 "register_operand" "r")))))]
8722 "TARGET_TLS && TARGET_ARCH64"
8723 "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
8724 [(set_attr "type" "load")])
8726 (define_insn "*tldo_ldsw1_sp64"
8727 [(set (match_operand:DI 0 "register_operand" "=r")
8728 (sign_extend:DI (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8729 (match_operand 3 "tld_symbolic_operand" "")]
8731 (match_operand:DI 1 "register_operand" "r")))))]
8732 "TARGET_TLS && TARGET_ARCH64"
8733 "ldsw\t[%1 + %2], %0, %%tldo_add(%3)"
8734 [(set_attr "type" "sload")
8735 (set_attr "us3load_type" "3cycle")])
8737 (define_insn "*tldo_ldx_sp64"
8738 [(set (match_operand:DI 0 "register_operand" "=r")
8739 (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8740 (match_operand 3 "tld_symbolic_operand" "")]
8742 (match_operand:DI 1 "register_operand" "r"))))]
8743 "TARGET_TLS && TARGET_ARCH64"
8744 "ldx\t[%1 + %2], %0, %%tldo_add(%3)"
8745 [(set_attr "type" "load")])
8747 (define_insn "*tldo_stb_sp32"
8748 [(set (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8749 (match_operand 3 "tld_symbolic_operand" "")]
8751 (match_operand:SI 1 "register_operand" "r")))
8752 (match_operand:QI 0 "register_operand" "=r"))]
8753 "TARGET_TLS && TARGET_ARCH32"
8754 "stb\t%0, [%1 + %2], %%tldo_add(%3)"
8755 [(set_attr "type" "store")])
8757 (define_insn "*tldo_stb_sp64"
8758 [(set (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8759 (match_operand 3 "tld_symbolic_operand" "")]
8761 (match_operand:DI 1 "register_operand" "r")))
8762 (match_operand:QI 0 "register_operand" "=r"))]
8763 "TARGET_TLS && TARGET_ARCH64"
8764 "stb\t%0, [%1 + %2], %%tldo_add(%3)"
8765 [(set_attr "type" "store")])
8767 (define_insn "*tldo_sth_sp32"
8768 [(set (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8769 (match_operand 3 "tld_symbolic_operand" "")]
8771 (match_operand:SI 1 "register_operand" "r")))
8772 (match_operand:HI 0 "register_operand" "=r"))]
8773 "TARGET_TLS && TARGET_ARCH32"
8774 "sth\t%0, [%1 + %2], %%tldo_add(%3)"
8775 [(set_attr "type" "store")])
8777 (define_insn "*tldo_sth_sp64"
8778 [(set (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8779 (match_operand 3 "tld_symbolic_operand" "")]
8781 (match_operand:DI 1 "register_operand" "r")))
8782 (match_operand:HI 0 "register_operand" "=r"))]
8783 "TARGET_TLS && TARGET_ARCH64"
8784 "sth\t%0, [%1 + %2], %%tldo_add(%3)"
8785 [(set_attr "type" "store")])
8787 (define_insn "*tldo_stw_sp32"
8788 [(set (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8789 (match_operand 3 "tld_symbolic_operand" "")]
8791 (match_operand:SI 1 "register_operand" "r")))
8792 (match_operand:SI 0 "register_operand" "=r"))]
8793 "TARGET_TLS && TARGET_ARCH32"
8794 "st\t%0, [%1 + %2], %%tldo_add(%3)"
8795 [(set_attr "type" "store")])
8797 (define_insn "*tldo_stw_sp64"
8798 [(set (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8799 (match_operand 3 "tld_symbolic_operand" "")]
8801 (match_operand:DI 1 "register_operand" "r")))
8802 (match_operand:SI 0 "register_operand" "=r"))]
8803 "TARGET_TLS && TARGET_ARCH64"
8804 "stw\t%0, [%1 + %2], %%tldo_add(%3)"
8805 [(set_attr "type" "store")])
8807 (define_insn "*tldo_stx_sp64"
8808 [(set (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8809 (match_operand 3 "tld_symbolic_operand" "")]
8811 (match_operand:DI 1 "register_operand" "r")))
8812 (match_operand:DI 0 "register_operand" "=r"))]
8813 "TARGET_TLS && TARGET_ARCH64"
8814 "stx\t%0, [%1 + %2], %%tldo_add(%3)"
8815 [(set_attr "type" "store")])