1 ;; Machine description for SPARC chip for GCC
2 ;; Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
3 ;; 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
4 ;; Contributed by Michael Tiemann (tiemann@cygnus.com)
5 ;; 64-bit SPARC-V9 support by Michael Tiemann, Jim Wilson, and Doug Evans,
8 ;; This file is part of GCC.
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 2, or (at your option)
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 ;; GNU General Public License for more details.
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING. If not, write to
22 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
23 ;; Boston, MA 02111-1307, USA.
25 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
29 (UNSPEC_UPDATE_RETURN 1)
30 (UNSPEC_LOAD_PCREL_SYM 2)
31 (UNSPEC_MOVE_PIC_LABEL 5)
37 (UNSPEC_EMB_TEXTUHI 13)
38 (UNSPEC_EMB_TEXTHI 14)
39 (UNSPEC_EMB_TEXTULO 15)
47 (UNSPEC_TLSLD_BASE 35)
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 in operand 0 the (absolute) address of operand 1, which is a symbolic
1668 ;; value subject to a PC-relative relocation. Operand 2 is a helper function
1669 ;; that adds the PC value at the call point to operand 0.
1671 (define_insn "load_pcrel_sym"
1672 [(set (match_operand 0 "register_operand" "=r")
1673 (unspec [(match_operand 1 "symbolic_operand" "")
1674 (match_operand 2 "call_operand_address" "")] UNSPEC_LOAD_PCREL_SYM))
1675 (clobber (reg:SI 15))]
1677 "sethi\t%%hi(%a1-4), %0\n\tcall\t%a2\n\tadd\t%0, %%lo(%a1+4), %0"
1678 [(set_attr "type" "multi")
1679 (set_attr "length" "3")])
1681 ;; Move instructions
1683 (define_expand "movqi"
1684 [(set (match_operand:QI 0 "general_operand" "")
1685 (match_operand:QI 1 "general_operand" ""))]
1688 /* Working with CONST_INTs is easier, so convert
1689 a double if needed. */
1690 if (GET_CODE (operands[1]) == CONST_DOUBLE)
1692 operands[1] = GEN_INT (trunc_int_for_mode
1693 (CONST_DOUBLE_LOW (operands[1]), QImode));
1696 /* Handle sets of MEM first. */
1697 if (GET_CODE (operands[0]) == MEM)
1699 if (reg_or_0_operand (operands[1], QImode))
1702 if (! reload_in_progress)
1704 operands[0] = validize_mem (operands[0]);
1705 operands[1] = force_reg (QImode, operands[1]);
1709 /* Fixup TLS cases. */
1710 if (tls_symbolic_operand (operands [1]))
1711 operands[1] = legitimize_tls_address (operands[1]);
1713 /* Fixup PIC cases. */
1716 if (CONSTANT_P (operands[1])
1717 && pic_address_needs_scratch (operands[1]))
1718 operands[1] = legitimize_pic_address (operands[1], QImode, 0);
1720 if (symbolic_operand (operands[1], QImode))
1722 operands[1] = legitimize_pic_address (operands[1],
1724 (reload_in_progress ?
1731 /* All QI constants require only one insn, so proceed. */
1737 (define_insn "*movqi_insn"
1738 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m")
1739 (match_operand:QI 1 "input_operand" "rI,m,rJ"))]
1740 "(register_operand (operands[0], QImode)
1741 || reg_or_0_operand (operands[1], QImode))"
1746 [(set_attr "type" "*,load,store")
1747 (set_attr "us3load_type" "*,3cycle,*")])
1749 (define_expand "movhi"
1750 [(set (match_operand:HI 0 "general_operand" "")
1751 (match_operand:HI 1 "general_operand" ""))]
1754 /* Working with CONST_INTs is easier, so convert
1755 a double if needed. */
1756 if (GET_CODE (operands[1]) == CONST_DOUBLE)
1757 operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
1759 /* Handle sets of MEM first. */
1760 if (GET_CODE (operands[0]) == MEM)
1762 if (reg_or_0_operand (operands[1], HImode))
1765 if (! reload_in_progress)
1767 operands[0] = validize_mem (operands[0]);
1768 operands[1] = force_reg (HImode, operands[1]);
1772 /* Fixup TLS cases. */
1773 if (tls_symbolic_operand (operands [1]))
1774 operands[1] = legitimize_tls_address (operands[1]);
1776 /* Fixup PIC cases. */
1779 if (CONSTANT_P (operands[1])
1780 && pic_address_needs_scratch (operands[1]))
1781 operands[1] = legitimize_pic_address (operands[1], HImode, 0);
1783 if (symbolic_operand (operands[1], HImode))
1785 operands[1] = legitimize_pic_address (operands[1],
1787 (reload_in_progress ?
1794 /* This makes sure we will not get rematched due to splittage. */
1795 if (! CONSTANT_P (operands[1]) || input_operand (operands[1], HImode))
1797 else if (CONSTANT_P (operands[1])
1798 && GET_CODE (operands[1]) != HIGH
1799 && GET_CODE (operands[1]) != LO_SUM)
1801 sparc_emit_set_const32 (operands[0], operands[1]);
1808 (define_insn "*movhi_const64_special"
1809 [(set (match_operand:HI 0 "register_operand" "=r")
1810 (match_operand:HI 1 "const64_high_operand" ""))]
1812 "sethi\t%%hi(%a1), %0")
1814 (define_insn "*movhi_insn"
1815 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1816 (match_operand:HI 1 "input_operand" "rI,K,m,rJ"))]
1817 "(register_operand (operands[0], HImode)
1818 || reg_or_0_operand (operands[1], HImode))"
1821 sethi\t%%hi(%a1), %0
1824 [(set_attr "type" "*,*,load,store")
1825 (set_attr "us3load_type" "*,*,3cycle,*")])
1827 ;; We always work with constants here.
1828 (define_insn "*movhi_lo_sum"
1829 [(set (match_operand:HI 0 "register_operand" "=r")
1830 (ior:HI (match_operand:HI 1 "register_operand" "%r")
1831 (match_operand:HI 2 "small_int" "I")))]
1835 (define_expand "movsi"
1836 [(set (match_operand:SI 0 "general_operand" "")
1837 (match_operand:SI 1 "general_operand" ""))]
1840 /* Working with CONST_INTs is easier, so convert
1841 a double if needed. */
1842 if (GET_CODE (operands[1]) == CONST_DOUBLE)
1843 operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
1845 /* Handle sets of MEM first. */
1846 if (GET_CODE (operands[0]) == MEM)
1848 if (reg_or_0_operand (operands[1], SImode))
1851 if (! reload_in_progress)
1853 operands[0] = validize_mem (operands[0]);
1854 operands[1] = force_reg (SImode, operands[1]);
1858 /* Fixup TLS cases. */
1859 if (tls_symbolic_operand (operands [1]))
1860 operands[1] = legitimize_tls_address (operands[1]);
1862 /* Fixup PIC cases. */
1865 if (CONSTANT_P (operands[1])
1866 && pic_address_needs_scratch (operands[1]))
1867 operands[1] = legitimize_pic_address (operands[1], SImode, 0);
1869 if (GET_CODE (operands[1]) == LABEL_REF)
1872 emit_insn (gen_movsi_pic_label_ref (operands[0], operands[1]));
1876 if (symbolic_operand (operands[1], SImode))
1878 operands[1] = legitimize_pic_address (operands[1],
1880 (reload_in_progress ?
1887 /* If we are trying to toss an integer constant into the
1888 FPU registers, force it into memory. */
1889 if (GET_CODE (operands[0]) == REG
1890 && REGNO (operands[0]) >= SPARC_FIRST_FP_REG
1891 && REGNO (operands[0]) <= SPARC_LAST_V9_FP_REG
1892 && CONSTANT_P (operands[1]))
1893 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
1896 /* This makes sure we will not get rematched due to splittage. */
1897 if (! CONSTANT_P (operands[1]) || input_operand (operands[1], SImode))
1899 else if (CONSTANT_P (operands[1])
1900 && GET_CODE (operands[1]) != HIGH
1901 && GET_CODE (operands[1]) != LO_SUM)
1903 sparc_emit_set_const32 (operands[0], operands[1]);
1910 ;; This is needed to show CSE exactly which bits are set
1911 ;; in a 64-bit register by sethi instructions.
1912 (define_insn "*movsi_const64_special"
1913 [(set (match_operand:SI 0 "register_operand" "=r")
1914 (match_operand:SI 1 "const64_high_operand" ""))]
1916 "sethi\t%%hi(%a1), %0")
1918 (define_insn "*movsi_insn"
1919 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,f,r,r,r,f,m,m,d")
1920 (match_operand:SI 1 "input_operand" "rI,!f,K,J,m,!m,rJ,!f,J"))]
1921 "(register_operand (operands[0], SImode)
1922 || reg_or_0_operand (operands[1], SImode))"
1926 sethi\t%%hi(%a1), %0
1933 [(set_attr "type" "*,fpmove,*,*,load,fpload,store,fpstore,fga")])
1935 (define_insn "*movsi_lo_sum"
1936 [(set (match_operand:SI 0 "register_operand" "=r")
1937 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1938 (match_operand:SI 2 "immediate_operand" "in")))]
1940 "or\t%1, %%lo(%a2), %0")
1942 (define_insn "*movsi_high"
1943 [(set (match_operand:SI 0 "register_operand" "=r")
1944 (high:SI (match_operand:SI 1 "immediate_operand" "in")))]
1946 "sethi\t%%hi(%a1), %0")
1948 ;; The next two patterns must wrap the SYMBOL_REF in an UNSPEC
1949 ;; so that CSE won't optimize the address computation away.
1950 (define_insn "movsi_lo_sum_pic"
1951 [(set (match_operand:SI 0 "register_operand" "=r")
1952 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1953 (unspec:SI [(match_operand:SI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
1955 "or\t%1, %%lo(%a2), %0")
1957 (define_insn "movsi_high_pic"
1958 [(set (match_operand:SI 0 "register_operand" "=r")
1959 (high:SI (unspec:SI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
1960 "flag_pic && check_pic (1)"
1961 "sethi\t%%hi(%a1), %0")
1963 (define_expand "movsi_pic_label_ref"
1964 [(set (match_dup 3) (high:SI
1965 (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
1966 (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1967 (set (match_dup 4) (lo_sum:SI (match_dup 3)
1968 (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1969 (set (match_operand:SI 0 "register_operand" "=r")
1970 (minus:SI (match_dup 5) (match_dup 4)))]
1973 current_function_uses_pic_offset_table = 1;
1974 operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
1977 operands[3] = operands[0];
1978 operands[4] = operands[0];
1982 operands[3] = gen_reg_rtx (SImode);
1983 operands[4] = gen_reg_rtx (SImode);
1985 operands[5] = pic_offset_table_rtx;
1988 (define_insn "*movsi_high_pic_label_ref"
1989 [(set (match_operand:SI 0 "register_operand" "=r")
1991 (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
1992 (match_operand:SI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1994 "sethi\t%%hi(%a2-(%a1-.)), %0")
1996 (define_insn "*movsi_lo_sum_pic_label_ref"
1997 [(set (match_operand:SI 0 "register_operand" "=r")
1998 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1999 (unspec:SI [(match_operand:SI 2 "label_ref_operand" "")
2000 (match_operand:SI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
2002 "or\t%1, %%lo(%a3-(%a2-.)), %0")
2004 (define_expand "movdi"
2005 [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand" "")
2006 (match_operand:DI 1 "general_operand" ""))]
2009 /* Where possible, convert CONST_DOUBLE into a CONST_INT. */
2010 if (GET_CODE (operands[1]) == CONST_DOUBLE
2011 #if HOST_BITS_PER_WIDE_INT == 32
2012 && ((CONST_DOUBLE_HIGH (operands[1]) == 0
2013 && (CONST_DOUBLE_LOW (operands[1]) & 0x80000000) == 0)
2014 || (CONST_DOUBLE_HIGH (operands[1]) == (HOST_WIDE_INT) 0xffffffff
2015 && (CONST_DOUBLE_LOW (operands[1]) & 0x80000000) != 0))
2018 operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
2020 /* Handle MEM cases first. */
2021 if (GET_CODE (operands[0]) == MEM)
2023 /* If it's a REG, we can always do it.
2024 The const zero case is more complex, on v9
2025 we can always perform it. */
2026 if (register_operand (operands[1], DImode)
2028 && (operands[1] == const0_rtx)))
2031 if (! reload_in_progress)
2033 operands[0] = validize_mem (operands[0]);
2034 operands[1] = force_reg (DImode, operands[1]);
2038 /* Fixup TLS cases. */
2039 if (tls_symbolic_operand (operands [1]))
2040 operands[1] = legitimize_tls_address (operands[1]);
2044 if (CONSTANT_P (operands[1])
2045 && pic_address_needs_scratch (operands[1]))
2046 operands[1] = legitimize_pic_address (operands[1], DImode, 0);
2048 if (GET_CODE (operands[1]) == LABEL_REF)
2050 if (! TARGET_ARCH64)
2052 emit_insn (gen_movdi_pic_label_ref (operands[0], operands[1]));
2056 if (symbolic_operand (operands[1], DImode))
2058 operands[1] = legitimize_pic_address (operands[1],
2060 (reload_in_progress ?
2067 /* If we are trying to toss an integer constant into the
2068 FPU registers, force it into memory. */
2069 if (GET_CODE (operands[0]) == REG
2070 && REGNO (operands[0]) >= SPARC_FIRST_FP_REG
2071 && REGNO (operands[0]) <= SPARC_LAST_V9_FP_REG
2072 && CONSTANT_P (operands[1]))
2073 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
2076 /* This makes sure we will not get rematched due to splittage. */
2077 if (! CONSTANT_P (operands[1]) || input_operand (operands[1], DImode))
2079 else if (TARGET_ARCH64
2080 && CONSTANT_P (operands[1])
2081 && GET_CODE (operands[1]) != HIGH
2082 && GET_CODE (operands[1]) != LO_SUM)
2084 sparc_emit_set_const64 (operands[0], operands[1]);
2092 ;; Be careful, fmovd does not exist when !v9.
2093 ;; We match MEM moves directly when we have correct even
2094 ;; numbered registers, but fall into splits otherwise.
2095 ;; The constraint ordering here is really important to
2096 ;; avoid insane problems in reload, especially for patterns
2099 ;; (set (mem:DI (plus:SI (reg:SI 30 %fp)
2100 ;; (const_int -5016)))
2104 (define_insn "*movdi_insn_sp32_v9"
2105 [(set (match_operand:DI 0 "nonimmediate_operand"
2106 "=T,o,T,U,o,r,r,r,?T,?f,?f,?o,?e,?e,?W")
2107 (match_operand:DI 1 "input_operand"
2108 " J,J,U,T,r,o,i,r, f, T, o, f, e, W, e"))]
2109 "! TARGET_ARCH64 && TARGET_V9
2110 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2127 [(set_attr "type" "store,store,store,load,*,*,*,*,fpstore,fpload,*,*,fpmove,fpload,fpstore")
2128 (set_attr "length" "*,2,*,*,2,2,2,2,*,*,2,2,*,*,*")
2129 (set_attr "fptype" "*,*,*,*,*,*,*,*,*,*,*,*,double,*,*")])
2131 (define_insn "*movdi_insn_sp32"
2132 [(set (match_operand:DI 0 "nonimmediate_operand"
2133 "=o,T,U,o,r,r,r,?T,?f,?f,?o,?f")
2134 (match_operand:DI 1 "input_operand"
2135 " J,U,T,r,o,i,r, f, T, o, f, f"))]
2137 && (register_operand (operands[0], DImode)
2138 || register_operand (operands[1], DImode))"
2152 [(set_attr "type" "store,store,load,*,*,*,*,fpstore,fpload,*,*,*")
2153 (set_attr "length" "2,*,*,2,2,2,2,*,*,2,2,2")])
2155 ;; The following are generated by sparc_emit_set_const64
2156 (define_insn "*movdi_sp64_dbl"
2157 [(set (match_operand:DI 0 "register_operand" "=r")
2158 (match_operand:DI 1 "const64_operand" ""))]
2160 && HOST_BITS_PER_WIDE_INT != 64)"
2163 ;; This is needed to show CSE exactly which bits are set
2164 ;; in a 64-bit register by sethi instructions.
2165 (define_insn "*movdi_const64_special"
2166 [(set (match_operand:DI 0 "register_operand" "=r")
2167 (match_operand:DI 1 "const64_high_operand" ""))]
2169 "sethi\t%%hi(%a1), %0")
2171 (define_insn "*movdi_insn_sp64_novis"
2172 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,m,?e,?e,?W")
2173 (match_operand:DI 1 "input_operand" "rI,N,J,m,rJ,e,W,e"))]
2174 "TARGET_ARCH64 && ! TARGET_VIS
2175 && (register_operand (operands[0], DImode)
2176 || reg_or_0_operand (operands[1], DImode))"
2179 sethi\t%%hi(%a1), %0
2186 [(set_attr "type" "*,*,*,load,store,fpmove,fpload,fpstore")
2187 (set_attr "fptype" "*,*,*,*,*,double,*,*")])
2189 (define_insn "*movdi_insn_sp64_vis"
2190 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,m,?e,?e,?W,b")
2191 (match_operand:DI 1 "input_operand" "rI,N,J,m,rJ,e,W,e,J"))]
2192 "TARGET_ARCH64 && TARGET_VIS &&
2193 (register_operand (operands[0], DImode)
2194 || reg_or_0_operand (operands[1], DImode))"
2197 sethi\t%%hi(%a1), %0
2205 [(set_attr "type" "*,*,*,load,store,fpmove,fpload,fpstore,fga")
2206 (set_attr "fptype" "*,*,*,*,*,double,*,*,double")])
2208 (define_expand "movdi_pic_label_ref"
2209 [(set (match_dup 3) (high:DI
2210 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
2211 (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
2212 (set (match_dup 4) (lo_sum:DI (match_dup 3)
2213 (unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
2214 (set (match_operand:DI 0 "register_operand" "=r")
2215 (minus:DI (match_dup 5) (match_dup 4)))]
2216 "TARGET_ARCH64 && flag_pic"
2218 current_function_uses_pic_offset_table = 1;
2219 operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
2222 operands[3] = operands[0];
2223 operands[4] = operands[0];
2227 operands[3] = gen_reg_rtx (DImode);
2228 operands[4] = gen_reg_rtx (DImode);
2230 operands[5] = pic_offset_table_rtx;
2233 (define_insn "*movdi_high_pic_label_ref"
2234 [(set (match_operand:DI 0 "register_operand" "=r")
2236 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
2237 (match_operand:DI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
2238 "TARGET_ARCH64 && flag_pic"
2239 "sethi\t%%hi(%a2-(%a1-.)), %0")
2241 (define_insn "*movdi_lo_sum_pic_label_ref"
2242 [(set (match_operand:DI 0 "register_operand" "=r")
2243 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2244 (unspec:DI [(match_operand:DI 2 "label_ref_operand" "")
2245 (match_operand:DI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
2246 "TARGET_ARCH64 && flag_pic"
2247 "or\t%1, %%lo(%a3-(%a2-.)), %0")
2249 ;; SPARC-v9 code model support insns. See sparc_emit_set_symbolic_const64
2250 ;; in sparc.c to see what is going on here... PIC stuff comes first.
2252 (define_insn "movdi_lo_sum_pic"
2253 [(set (match_operand:DI 0 "register_operand" "=r")
2254 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2255 (unspec:DI [(match_operand:DI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
2256 "TARGET_ARCH64 && flag_pic"
2257 "or\t%1, %%lo(%a2), %0")
2259 (define_insn "movdi_high_pic"
2260 [(set (match_operand:DI 0 "register_operand" "=r")
2261 (high:DI (unspec:DI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
2262 "TARGET_ARCH64 && flag_pic && check_pic (1)"
2263 "sethi\t%%hi(%a1), %0")
2265 (define_insn "*sethi_di_medlow_embmedany_pic"
2266 [(set (match_operand:DI 0 "register_operand" "=r")
2267 (high:DI (match_operand:DI 1 "sp64_medium_pic_operand" "")))]
2268 "(TARGET_CM_MEDLOW || TARGET_CM_EMBMEDANY) && check_pic (1)"
2269 "sethi\t%%hi(%a1), %0")
2271 (define_insn "*sethi_di_medlow"
2272 [(set (match_operand:DI 0 "register_operand" "=r")
2273 (high:DI (match_operand:DI 1 "symbolic_operand" "")))]
2274 "TARGET_CM_MEDLOW && check_pic (1)"
2275 "sethi\t%%hi(%a1), %0")
2277 (define_insn "*losum_di_medlow"
2278 [(set (match_operand:DI 0 "register_operand" "=r")
2279 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2280 (match_operand:DI 2 "symbolic_operand" "")))]
2282 "or\t%1, %%lo(%a2), %0")
2284 (define_insn "seth44"
2285 [(set (match_operand:DI 0 "register_operand" "=r")
2286 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETH44)))]
2288 "sethi\t%%h44(%a1), %0")
2290 (define_insn "setm44"
2291 [(set (match_operand:DI 0 "register_operand" "=r")
2292 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2293 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_SETM44)))]
2295 "or\t%1, %%m44(%a2), %0")
2297 (define_insn "setl44"
2298 [(set (match_operand:DI 0 "register_operand" "=r")
2299 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2300 (match_operand:DI 2 "symbolic_operand" "")))]
2302 "or\t%1, %%l44(%a2), %0")
2304 (define_insn "sethh"
2305 [(set (match_operand:DI 0 "register_operand" "=r")
2306 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETHH)))]
2308 "sethi\t%%hh(%a1), %0")
2310 (define_insn "setlm"
2311 [(set (match_operand:DI 0 "register_operand" "=r")
2312 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETLM)))]
2314 "sethi\t%%lm(%a1), %0")
2316 (define_insn "sethm"
2317 [(set (match_operand:DI 0 "register_operand" "=r")
2318 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2319 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_EMB_SETHM)))]
2321 "or\t%1, %%hm(%a2), %0")
2323 (define_insn "setlo"
2324 [(set (match_operand:DI 0 "register_operand" "=r")
2325 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2326 (match_operand:DI 2 "symbolic_operand" "")))]
2328 "or\t%1, %%lo(%a2), %0")
2330 (define_insn "embmedany_sethi"
2331 [(set (match_operand:DI 0 "register_operand" "=r")
2332 (high:DI (unspec:DI [(match_operand:DI 1 "data_segment_operand" "")] UNSPEC_EMB_HISUM)))]
2333 "TARGET_CM_EMBMEDANY && check_pic (1)"
2334 "sethi\t%%hi(%a1), %0")
2336 (define_insn "embmedany_losum"
2337 [(set (match_operand:DI 0 "register_operand" "=r")
2338 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2339 (match_operand:DI 2 "data_segment_operand" "")))]
2340 "TARGET_CM_EMBMEDANY"
2341 "add\t%1, %%lo(%a2), %0")
2343 (define_insn "embmedany_brsum"
2344 [(set (match_operand:DI 0 "register_operand" "=r")
2345 (unspec:DI [(match_operand:DI 1 "register_operand" "r")] UNSPEC_EMB_HISUM))]
2346 "TARGET_CM_EMBMEDANY"
2349 (define_insn "embmedany_textuhi"
2350 [(set (match_operand:DI 0 "register_operand" "=r")
2351 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTUHI)))]
2352 "TARGET_CM_EMBMEDANY && check_pic (1)"
2353 "sethi\t%%uhi(%a1), %0")
2355 (define_insn "embmedany_texthi"
2356 [(set (match_operand:DI 0 "register_operand" "=r")
2357 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTHI)))]
2358 "TARGET_CM_EMBMEDANY && check_pic (1)"
2359 "sethi\t%%hi(%a1), %0")
2361 (define_insn "embmedany_textulo"
2362 [(set (match_operand:DI 0 "register_operand" "=r")
2363 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2364 (unspec:DI [(match_operand:DI 2 "text_segment_operand" "")] UNSPEC_EMB_TEXTULO)))]
2365 "TARGET_CM_EMBMEDANY"
2366 "or\t%1, %%ulo(%a2), %0")
2368 (define_insn "embmedany_textlo"
2369 [(set (match_operand:DI 0 "register_operand" "=r")
2370 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2371 (match_operand:DI 2 "text_segment_operand" "")))]
2372 "TARGET_CM_EMBMEDANY"
2373 "or\t%1, %%lo(%a2), %0")
2375 ;; Now some patterns to help reload out a bit.
2376 (define_expand "reload_indi"
2377 [(parallel [(match_operand:DI 0 "register_operand" "=r")
2378 (match_operand:DI 1 "immediate_operand" "")
2379 (match_operand:TI 2 "register_operand" "=&r")])]
2381 || TARGET_CM_EMBMEDANY)
2384 sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
2388 (define_expand "reload_outdi"
2389 [(parallel [(match_operand:DI 0 "register_operand" "=r")
2390 (match_operand:DI 1 "immediate_operand" "")
2391 (match_operand:TI 2 "register_operand" "=&r")])]
2393 || TARGET_CM_EMBMEDANY)
2396 sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
2400 ;; Split up putting CONSTs and REGs into DI regs when !arch64
2402 [(set (match_operand:DI 0 "register_operand" "")
2403 (match_operand:DI 1 "const_int_operand" ""))]
2404 "! TARGET_ARCH64 && reload_completed"
2405 [(clobber (const_int 0))]
2407 #if HOST_BITS_PER_WIDE_INT == 32
2408 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
2409 (INTVAL (operands[1]) < 0) ?
2412 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2415 unsigned int low, high;
2417 low = trunc_int_for_mode (INTVAL (operands[1]), SImode);
2418 high = trunc_int_for_mode (INTVAL (operands[1]) >> 32, SImode);
2419 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), GEN_INT (high)));
2421 /* Slick... but this trick loses if this subreg constant part
2422 can be done in one insn. */
2423 if (low == high && (low & 0x3ff) != 0 && low + 0x1000 >= 0x2000)
2424 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2425 gen_highpart (SImode, operands[0])));
2427 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), GEN_INT (low)));
2433 [(set (match_operand:DI 0 "register_operand" "")
2434 (match_operand:DI 1 "const_double_operand" ""))]
2438 && ((GET_CODE (operands[0]) == REG
2439 && REGNO (operands[0]) < 32)
2440 || (GET_CODE (operands[0]) == SUBREG
2441 && GET_CODE (SUBREG_REG (operands[0])) == REG
2442 && REGNO (SUBREG_REG (operands[0])) < 32))))"
2443 [(clobber (const_int 0))]
2445 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
2446 GEN_INT (CONST_DOUBLE_HIGH (operands[1]))));
2448 /* Slick... but this trick loses if this subreg constant part
2449 can be done in one insn. */
2450 if (CONST_DOUBLE_LOW (operands[1]) == CONST_DOUBLE_HIGH (operands[1])
2451 && !(SPARC_SETHI32_P (CONST_DOUBLE_HIGH (operands[1]))
2452 || SPARC_SIMM13_P (CONST_DOUBLE_HIGH (operands[1]))))
2454 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2455 gen_highpart (SImode, operands[0])));
2459 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2460 GEN_INT (CONST_DOUBLE_LOW (operands[1]))));
2466 [(set (match_operand:DI 0 "register_operand" "")
2467 (match_operand:DI 1 "register_operand" ""))]
2471 && ((GET_CODE (operands[0]) == REG
2472 && REGNO (operands[0]) < 32)
2473 || (GET_CODE (operands[0]) == SUBREG
2474 && GET_CODE (SUBREG_REG (operands[0])) == REG
2475 && REGNO (SUBREG_REG (operands[0])) < 32))))"
2476 [(clobber (const_int 0))]
2478 rtx set_dest = operands[0];
2479 rtx set_src = operands[1];
2483 dest1 = gen_highpart (SImode, set_dest);
2484 dest2 = gen_lowpart (SImode, set_dest);
2485 src1 = gen_highpart (SImode, set_src);
2486 src2 = gen_lowpart (SImode, set_src);
2488 /* Now emit using the real source and destination we found, swapping
2489 the order if we detect overlap. */
2490 if (reg_overlap_mentioned_p (dest1, src2))
2492 emit_insn (gen_movsi (dest2, src2));
2493 emit_insn (gen_movsi (dest1, src1));
2497 emit_insn (gen_movsi (dest1, src1));
2498 emit_insn (gen_movsi (dest2, src2));
2503 ;; Now handle the cases of memory moves from/to non-even
2504 ;; DI mode register pairs.
2506 [(set (match_operand:DI 0 "register_operand" "")
2507 (match_operand:DI 1 "memory_operand" ""))]
2510 && sparc_splitdi_legitimate (operands[0], operands[1]))"
2511 [(clobber (const_int 0))]
2513 rtx word0 = adjust_address (operands[1], SImode, 0);
2514 rtx word1 = adjust_address (operands[1], SImode, 4);
2515 rtx high_part = gen_highpart (SImode, operands[0]);
2516 rtx low_part = gen_lowpart (SImode, operands[0]);
2518 if (reg_overlap_mentioned_p (high_part, word1))
2520 emit_insn (gen_movsi (low_part, word1));
2521 emit_insn (gen_movsi (high_part, word0));
2525 emit_insn (gen_movsi (high_part, word0));
2526 emit_insn (gen_movsi (low_part, word1));
2532 [(set (match_operand:DI 0 "memory_operand" "")
2533 (match_operand:DI 1 "register_operand" ""))]
2536 && sparc_splitdi_legitimate (operands[1], operands[0]))"
2537 [(clobber (const_int 0))]
2539 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0),
2540 gen_highpart (SImode, operands[1])));
2541 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4),
2542 gen_lowpart (SImode, operands[1])));
2547 [(set (match_operand:DI 0 "memory_operand" "")
2552 && ! mem_min_alignment (operands[0], 8)))
2553 && offsettable_memref_p (operands[0])"
2554 [(clobber (const_int 0))]
2556 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0), const0_rtx));
2557 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4), const0_rtx));
2561 ;; Floating point move insns
2563 (define_insn "*movsf_insn_novis"
2564 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,*r,*r,*r,*r,*r,f,m,m")
2565 (match_operand:SF 1 "input_operand" "f,G,Q,*rR,S,m,m,f,*rG"))]
2566 "(TARGET_FPU && ! TARGET_VIS)
2567 && (register_operand (operands[0], SFmode)
2568 || register_operand (operands[1], SFmode)
2569 || fp_zero_operand (operands[1], SFmode))"
2571 if (GET_CODE (operands[1]) == CONST_DOUBLE
2572 && (which_alternative == 2
2573 || which_alternative == 3
2574 || which_alternative == 4))
2579 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2580 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2581 operands[1] = GEN_INT (i);
2584 switch (which_alternative)
2587 return "fmovs\t%1, %0";
2591 return "sethi\t%%hi(%a1), %0";
2593 return "mov\t%1, %0";
2598 return "ld\t%1, %0";
2601 return "st\t%r1, %0";
2606 [(set_attr "type" "fpmove,*,*,*,*,load,fpload,fpstore,store")])
2608 (define_insn "*movsf_insn_vis"
2609 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,*r,*r,*r,*r,*r,f,m,m")
2610 (match_operand:SF 1 "input_operand" "f,G,G,Q,*rR,S,m,m,f,*rG"))]
2611 "(TARGET_FPU && TARGET_VIS)
2612 && (register_operand (operands[0], SFmode)
2613 || register_operand (operands[1], SFmode)
2614 || fp_zero_operand (operands[1], SFmode))"
2616 if (GET_CODE (operands[1]) == CONST_DOUBLE
2617 && (which_alternative == 3
2618 || which_alternative == 4
2619 || which_alternative == 5))
2624 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2625 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2626 operands[1] = GEN_INT (i);
2629 switch (which_alternative)
2632 return "fmovs\t%1, %0";
2634 return "fzeros\t%0";
2638 return "sethi\t%%hi(%a1), %0";
2640 return "mov\t%1, %0";
2645 return "ld\t%1, %0";
2648 return "st\t%r1, %0";
2653 [(set_attr "type" "fpmove,fga,*,*,*,*,load,fpload,fpstore,store")])
2655 ;; Exactly the same as above, except that all `f' cases are deleted.
2656 ;; This is necessary to prevent reload from ever trying to use a `f' reg
2659 (define_insn "*movsf_no_f_insn"
2660 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r,r,r,m")
2661 (match_operand:SF 1 "input_operand" "G,Q,rR,S,m,rG"))]
2663 && (register_operand (operands[0], SFmode)
2664 || register_operand (operands[1], SFmode)
2665 || fp_zero_operand (operands[1], SFmode))"
2667 if (GET_CODE (operands[1]) == CONST_DOUBLE
2668 && (which_alternative == 1
2669 || which_alternative == 2
2670 || which_alternative == 3))
2675 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2676 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2677 operands[1] = GEN_INT (i);
2680 switch (which_alternative)
2685 return "sethi\t%%hi(%a1), %0";
2687 return "mov\t%1, %0";
2691 return "ld\t%1, %0";
2693 return "st\t%r1, %0";
2698 [(set_attr "type" "*,*,*,*,load,store")])
2700 (define_insn "*movsf_lo_sum"
2701 [(set (match_operand:SF 0 "register_operand" "=r")
2702 (lo_sum:SF (match_operand:SF 1 "register_operand" "r")
2703 (match_operand:SF 2 "const_double_operand" "S")))]
2704 "fp_high_losum_p (operands[2])"
2709 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[2]);
2710 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2711 operands[2] = GEN_INT (i);
2712 return "or\t%1, %%lo(%a2), %0";
2715 (define_insn "*movsf_high"
2716 [(set (match_operand:SF 0 "register_operand" "=r")
2717 (high:SF (match_operand:SF 1 "const_double_operand" "S")))]
2718 "fp_high_losum_p (operands[1])"
2723 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2724 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2725 operands[1] = GEN_INT (i);
2726 return "sethi\t%%hi(%1), %0";
2730 [(set (match_operand:SF 0 "register_operand" "")
2731 (match_operand:SF 1 "const_double_operand" ""))]
2732 "fp_high_losum_p (operands[1])
2733 && (GET_CODE (operands[0]) == REG
2734 && REGNO (operands[0]) < 32)"
2735 [(set (match_dup 0) (high:SF (match_dup 1)))
2736 (set (match_dup 0) (lo_sum:SF (match_dup 0) (match_dup 1)))])
2738 (define_expand "movsf"
2739 [(set (match_operand:SF 0 "general_operand" "")
2740 (match_operand:SF 1 "general_operand" ""))]
2743 /* Force SFmode constants into memory. */
2744 if (GET_CODE (operands[0]) == REG
2745 && CONSTANT_P (operands[1]))
2747 /* emit_group_store will send such bogosity to us when it is
2748 not storing directly into memory. So fix this up to avoid
2749 crashes in output_constant_pool. */
2750 if (operands [1] == const0_rtx)
2751 operands[1] = CONST0_RTX (SFmode);
2753 if (TARGET_VIS && fp_zero_operand (operands[1], SFmode))
2756 /* We are able to build any SF constant in integer registers
2757 with at most 2 instructions. */
2758 if (REGNO (operands[0]) < 32)
2761 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
2765 /* Handle sets of MEM first. */
2766 if (GET_CODE (operands[0]) == MEM)
2768 if (register_operand (operands[1], SFmode)
2769 || fp_zero_operand (operands[1], SFmode))
2772 if (! reload_in_progress)
2774 operands[0] = validize_mem (operands[0]);
2775 operands[1] = force_reg (SFmode, operands[1]);
2779 /* Fixup PIC cases. */
2782 if (CONSTANT_P (operands[1])
2783 && pic_address_needs_scratch (operands[1]))
2784 operands[1] = legitimize_pic_address (operands[1], SFmode, 0);
2786 if (symbolic_operand (operands[1], SFmode))
2788 operands[1] = legitimize_pic_address (operands[1],
2790 (reload_in_progress ?
2800 (define_expand "movdf"
2801 [(set (match_operand:DF 0 "general_operand" "")
2802 (match_operand:DF 1 "general_operand" ""))]
2805 /* Force DFmode constants into memory. */
2806 if (GET_CODE (operands[0]) == REG
2807 && CONSTANT_P (operands[1]))
2809 /* emit_group_store will send such bogosity to us when it is
2810 not storing directly into memory. So fix this up to avoid
2811 crashes in output_constant_pool. */
2812 if (operands [1] == const0_rtx)
2813 operands[1] = CONST0_RTX (DFmode);
2815 if ((TARGET_VIS || REGNO (operands[0]) < 32)
2816 && fp_zero_operand (operands[1], DFmode))
2819 /* We are able to build any DF constant in integer registers. */
2820 if (REGNO (operands[0]) < 32
2821 && (reload_completed || reload_in_progress))
2824 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
2828 /* Handle MEM cases first. */
2829 if (GET_CODE (operands[0]) == MEM)
2831 if (register_operand (operands[1], DFmode)
2832 || fp_zero_operand (operands[1], DFmode))
2835 if (! reload_in_progress)
2837 operands[0] = validize_mem (operands[0]);
2838 operands[1] = force_reg (DFmode, operands[1]);
2842 /* Fixup PIC cases. */
2845 if (CONSTANT_P (operands[1])
2846 && pic_address_needs_scratch (operands[1]))
2847 operands[1] = legitimize_pic_address (operands[1], DFmode, 0);
2849 if (symbolic_operand (operands[1], DFmode))
2851 operands[1] = legitimize_pic_address (operands[1],
2853 (reload_in_progress ?
2863 ;; Be careful, fmovd does not exist when !v9.
2864 (define_insn "*movdf_insn_sp32"
2865 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,W,U,T,o,e,*r,o,e,o")
2866 (match_operand:DF 1 "input_operand" "W#F,e,T,U,G,e,*rFo,*r,o#F,e"))]
2869 && (register_operand (operands[0], DFmode)
2870 || register_operand (operands[1], DFmode)
2871 || fp_zero_operand (operands[1], DFmode))"
2883 [(set_attr "type" "fpload,fpstore,load,store,*,*,*,*,*,*")
2884 (set_attr "length" "*,*,*,*,2,2,2,2,2,2")])
2886 (define_insn "*movdf_no_e_insn_sp32"
2887 [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,o,r,o")
2888 (match_operand:DF 1 "input_operand" "T,U,G,ro,r"))]
2892 && (register_operand (operands[0], DFmode)
2893 || register_operand (operands[1], DFmode)
2894 || fp_zero_operand (operands[1], DFmode))"
2901 [(set_attr "type" "load,store,*,*,*")
2902 (set_attr "length" "*,*,2,2,2")])
2904 (define_insn "*movdf_no_e_insn_v9_sp32"
2905 [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,T,r,o")
2906 (match_operand:DF 1 "input_operand" "T,U,G,ro,rG"))]
2910 && (register_operand (operands[0], DFmode)
2911 || register_operand (operands[1], DFmode)
2912 || fp_zero_operand (operands[1], DFmode))"
2919 [(set_attr "type" "load,store,store,*,*")
2920 (set_attr "length" "*,*,*,2,2")])
2922 ;; We have available v9 double floats but not 64-bit
2923 ;; integer registers and no VIS.
2924 (define_insn "*movdf_insn_v9only_novis"
2925 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,T,W,U,T,f,*r,o")
2926 (match_operand:DF 1 "input_operand" "e,W#F,G,e,T,U,o#F,*roF,*rGf"))]
2931 && (register_operand (operands[0], DFmode)
2932 || register_operand (operands[1], DFmode)
2933 || fp_zero_operand (operands[1], DFmode))"
2944 [(set_attr "type" "fpmove,load,store,store,load,store,*,*,*")
2945 (set_attr "length" "*,*,*,*,*,*,2,2,2")
2946 (set_attr "fptype" "double,*,*,*,*,*,*,*,*")])
2948 ;; We have available v9 double floats but not 64-bit
2949 ;; integer registers but we have VIS.
2950 (define_insn "*movdf_insn_v9only_vis"
2951 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,e,T,W,U,T,f,*r,o")
2952 (match_operand:DF 1 "input_operand" "G,e,W#F,G,e,T,U,o#F,*roGF,*rGf"))]
2956 && (register_operand (operands[0], DFmode)
2957 || register_operand (operands[1], DFmode)
2958 || fp_zero_operand (operands[1], DFmode))"
2970 [(set_attr "type" "fga,fpmove,load,store,store,load,store,*,*,*")
2971 (set_attr "length" "*,*,*,*,*,*,*,2,2,2")
2972 (set_attr "fptype" "double,double,*,*,*,*,*,*,*,*")])
2974 ;; We have available both v9 double floats and 64-bit
2975 ;; integer registers. No VIS though.
2976 (define_insn "*movdf_insn_sp64_novis"
2977 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,W,*r,*r,m,*r")
2978 (match_operand:DF 1 "input_operand" "e,W#F,e,*rG,m,*rG,F"))]
2982 && (register_operand (operands[0], DFmode)
2983 || register_operand (operands[1], DFmode)
2984 || fp_zero_operand (operands[1], DFmode))"
2993 [(set_attr "type" "fpmove,load,store,*,load,store,*")
2994 (set_attr "length" "*,*,*,*,*,*,2")
2995 (set_attr "fptype" "double,*,*,*,*,*,*")])
2997 ;; We have available both v9 double floats and 64-bit
2998 ;; integer registers. And we have VIS.
2999 (define_insn "*movdf_insn_sp64_vis"
3000 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,e,W,*r,*r,m,*r")
3001 (match_operand:DF 1 "input_operand" "G,e,W#F,e,*rG,m,*rG,F"))]
3005 && (register_operand (operands[0], DFmode)
3006 || register_operand (operands[1], DFmode)
3007 || fp_zero_operand (operands[1], DFmode))"
3017 [(set_attr "type" "fga,fpmove,load,store,*,load,store,*")
3018 (set_attr "length" "*,*,*,*,*,*,*,2")
3019 (set_attr "fptype" "double,double,*,*,*,*,*,*")])
3021 (define_insn "*movdf_no_e_insn_sp64"
3022 [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m")
3023 (match_operand:DF 1 "input_operand" "r,m,rG"))]
3026 && (register_operand (operands[0], DFmode)
3027 || register_operand (operands[1], DFmode)
3028 || fp_zero_operand (operands[1], DFmode))"
3033 [(set_attr "type" "*,load,store")])
3036 [(set (match_operand:DF 0 "register_operand" "")
3037 (match_operand:DF 1 "const_double_operand" ""))]
3039 && (GET_CODE (operands[0]) == REG
3040 && REGNO (operands[0]) < 32)
3041 && ! fp_zero_operand(operands[1], DFmode)
3042 && reload_completed"
3043 [(clobber (const_int 0))]
3048 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3049 REAL_VALUE_TO_TARGET_DOUBLE (r, l);
3050 operands[0] = gen_rtx_raw_REG (DImode, REGNO (operands[0]));
3054 #if HOST_BITS_PER_WIDE_INT == 64
3057 val = ((HOST_WIDE_INT)(unsigned long)l[1] |
3058 ((HOST_WIDE_INT)(unsigned long)l[0] << 32));
3059 emit_insn (gen_movdi (operands[0], GEN_INT (val)));
3061 emit_insn (gen_movdi (operands[0],
3062 immed_double_const (l[1], l[0], DImode)));
3067 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
3070 /* Slick... but this trick loses if this subreg constant part
3071 can be done in one insn. */
3073 && !(SPARC_SETHI32_P (l[0])
3074 || SPARC_SIMM13_P (l[0])))
3076 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
3077 gen_highpart (SImode, operands[0])));
3081 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
3088 ;; Ok, now the splits to handle all the multi insn and
3089 ;; mis-aligned memory address cases.
3090 ;; In these splits please take note that we must be
3091 ;; careful when V9 but not ARCH64 because the integer
3092 ;; register DFmode cases must be handled.
3094 [(set (match_operand:DF 0 "register_operand" "")
3095 (match_operand:DF 1 "register_operand" ""))]
3098 && ((GET_CODE (operands[0]) == REG
3099 && REGNO (operands[0]) < 32)
3100 || (GET_CODE (operands[0]) == SUBREG
3101 && GET_CODE (SUBREG_REG (operands[0])) == REG
3102 && REGNO (SUBREG_REG (operands[0])) < 32))))
3103 && reload_completed"
3104 [(clobber (const_int 0))]
3106 rtx set_dest = operands[0];
3107 rtx set_src = operands[1];
3111 dest1 = gen_highpart (SFmode, set_dest);
3112 dest2 = gen_lowpart (SFmode, set_dest);
3113 src1 = gen_highpart (SFmode, set_src);
3114 src2 = gen_lowpart (SFmode, set_src);
3116 /* Now emit using the real source and destination we found, swapping
3117 the order if we detect overlap. */
3118 if (reg_overlap_mentioned_p (dest1, src2))
3120 emit_insn (gen_movsf (dest2, src2));
3121 emit_insn (gen_movsf (dest1, src1));
3125 emit_insn (gen_movsf (dest1, src1));
3126 emit_insn (gen_movsf (dest2, src2));
3132 [(set (match_operand:DF 0 "register_operand" "")
3133 (match_operand:DF 1 "memory_operand" ""))]
3136 && (((REGNO (operands[0]) % 2) != 0)
3137 || ! mem_min_alignment (operands[1], 8))
3138 && offsettable_memref_p (operands[1])"
3139 [(clobber (const_int 0))]
3141 rtx word0 = adjust_address (operands[1], SFmode, 0);
3142 rtx word1 = adjust_address (operands[1], SFmode, 4);
3144 if (reg_overlap_mentioned_p (gen_highpart (SFmode, operands[0]), word1))
3146 emit_insn (gen_movsf (gen_lowpart (SFmode, operands[0]),
3148 emit_insn (gen_movsf (gen_highpart (SFmode, operands[0]),
3153 emit_insn (gen_movsf (gen_highpart (SFmode, operands[0]),
3155 emit_insn (gen_movsf (gen_lowpart (SFmode, operands[0]),
3162 [(set (match_operand:DF 0 "memory_operand" "")
3163 (match_operand:DF 1 "register_operand" ""))]
3166 && (((REGNO (operands[1]) % 2) != 0)
3167 || ! mem_min_alignment (operands[0], 8))
3168 && offsettable_memref_p (operands[0])"
3169 [(clobber (const_int 0))]
3171 rtx word0 = adjust_address (operands[0], SFmode, 0);
3172 rtx word1 = adjust_address (operands[0], SFmode, 4);
3174 emit_insn (gen_movsf (word0,
3175 gen_highpart (SFmode, operands[1])));
3176 emit_insn (gen_movsf (word1,
3177 gen_lowpart (SFmode, operands[1])));
3182 [(set (match_operand:DF 0 "memory_operand" "")
3183 (match_operand:DF 1 "fp_zero_operand" ""))]
3187 && ! mem_min_alignment (operands[0], 8)))
3188 && offsettable_memref_p (operands[0])"
3189 [(clobber (const_int 0))]
3193 dest1 = adjust_address (operands[0], SFmode, 0);
3194 dest2 = adjust_address (operands[0], SFmode, 4);
3196 emit_insn (gen_movsf (dest1, CONST0_RTX (SFmode)));
3197 emit_insn (gen_movsf (dest2, CONST0_RTX (SFmode)));
3202 [(set (match_operand:DF 0 "register_operand" "")
3203 (match_operand:DF 1 "fp_zero_operand" ""))]
3206 && ((GET_CODE (operands[0]) == REG
3207 && REGNO (operands[0]) < 32)
3208 || (GET_CODE (operands[0]) == SUBREG
3209 && GET_CODE (SUBREG_REG (operands[0])) == REG
3210 && REGNO (SUBREG_REG (operands[0])) < 32))"
3211 [(clobber (const_int 0))]
3213 rtx set_dest = operands[0];
3216 dest1 = gen_highpart (SFmode, set_dest);
3217 dest2 = gen_lowpart (SFmode, set_dest);
3218 emit_insn (gen_movsf (dest1, CONST0_RTX (SFmode)));
3219 emit_insn (gen_movsf (dest2, CONST0_RTX (SFmode)));
3223 (define_expand "movtf"
3224 [(set (match_operand:TF 0 "general_operand" "")
3225 (match_operand:TF 1 "general_operand" ""))]
3228 /* Force TFmode constants into memory. */
3229 if (GET_CODE (operands[0]) == REG
3230 && CONSTANT_P (operands[1]))
3232 /* emit_group_store will send such bogosity to us when it is
3233 not storing directly into memory. So fix this up to avoid
3234 crashes in output_constant_pool. */
3235 if (operands [1] == const0_rtx)
3236 operands[1] = CONST0_RTX (TFmode);
3238 if (TARGET_VIS && fp_zero_operand (operands[1], TFmode))
3241 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
3245 /* Handle MEM cases first, note that only v9 guarantees
3246 full 16-byte alignment for quads. */
3247 if (GET_CODE (operands[0]) == MEM)
3249 if (register_operand (operands[1], TFmode)
3250 || fp_zero_operand (operands[1], TFmode))
3253 if (! reload_in_progress)
3255 operands[0] = validize_mem (operands[0]);
3256 operands[1] = force_reg (TFmode, operands[1]);
3260 /* Fixup PIC cases. */
3263 if (CONSTANT_P (operands[1])
3264 && pic_address_needs_scratch (operands[1]))
3265 operands[1] = legitimize_pic_address (operands[1], TFmode, 0);
3267 if (symbolic_operand (operands[1], TFmode))
3269 operands[1] = legitimize_pic_address (operands[1],
3271 (reload_in_progress ?
3281 ;; Be careful, fmovq and {st,ld}{x,q} do not exist when !arch64 so
3282 ;; we must split them all. :-(
3283 (define_insn "*movtf_insn_sp32"
3284 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,U,r")
3285 (match_operand:TF 1 "input_operand" "oe,GeUr,o,roG"))]
3289 && (register_operand (operands[0], TFmode)
3290 || register_operand (operands[1], TFmode)
3291 || fp_zero_operand (operands[1], TFmode))"
3293 [(set_attr "length" "4")])
3295 (define_insn "*movtf_insn_vis_sp32"
3296 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,U,r")
3297 (match_operand:TF 1 "input_operand" "Goe,GeUr,o,roG"))]
3301 && (register_operand (operands[0], TFmode)
3302 || register_operand (operands[1], TFmode)
3303 || fp_zero_operand (operands[1], TFmode))"
3305 [(set_attr "length" "4")])
3307 ;; Exactly the same as above, except that all `e' cases are deleted.
3308 ;; This is necessary to prevent reload from ever trying to use a `e' reg
3311 (define_insn "*movtf_no_e_insn_sp32"
3312 [(set (match_operand:TF 0 "nonimmediate_operand" "=o,U,o,r,o")
3313 (match_operand:TF 1 "input_operand" "G,o,U,roG,r"))]
3316 && (register_operand (operands[0], TFmode)
3317 || register_operand (operands[1], TFmode)
3318 || fp_zero_operand (operands[1], TFmode))"
3320 [(set_attr "length" "4")])
3322 ;; Now handle the float reg cases directly when arch64,
3323 ;; hard_quad, and proper reg number alignment are all true.
3324 (define_insn "*movtf_insn_hq_sp64"
3325 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,e,m,o,r")
3326 (match_operand:TF 1 "input_operand" "e,m,e,Gr,roG"))]
3331 && (register_operand (operands[0], TFmode)
3332 || register_operand (operands[1], TFmode)
3333 || fp_zero_operand (operands[1], TFmode))"
3340 [(set_attr "type" "fpmove,fpload,fpstore,*,*")
3341 (set_attr "length" "*,*,*,2,2")])
3343 (define_insn "*movtf_insn_hq_vis_sp64"
3344 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,e,m,eo,r,o")
3345 (match_operand:TF 1 "input_operand" "e,m,e,G,roG,r"))]
3350 && (register_operand (operands[0], TFmode)
3351 || register_operand (operands[1], TFmode)
3352 || fp_zero_operand (operands[1], TFmode))"
3360 [(set_attr "type" "fpmove,fpload,fpstore,*,*,*")
3361 (set_attr "length" "*,*,*,2,2,2")])
3363 ;; Now we allow the integer register cases even when
3364 ;; only arch64 is true.
3365 (define_insn "*movtf_insn_sp64"
3366 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,r")
3367 (match_operand:TF 1 "input_operand" "oe,Ger,orG"))]
3371 && ! TARGET_HARD_QUAD
3372 && (register_operand (operands[0], TFmode)
3373 || register_operand (operands[1], TFmode)
3374 || fp_zero_operand (operands[1], TFmode))"
3376 [(set_attr "length" "2")])
3378 (define_insn "*movtf_insn_vis_sp64"
3379 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,r")
3380 (match_operand:TF 1 "input_operand" "Goe,Ger,orG"))]
3384 && ! TARGET_HARD_QUAD
3385 && (register_operand (operands[0], TFmode)
3386 || register_operand (operands[1], TFmode)
3387 || fp_zero_operand (operands[1], TFmode))"
3389 [(set_attr "length" "2")])
3391 (define_insn "*movtf_no_e_insn_sp64"
3392 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o")
3393 (match_operand:TF 1 "input_operand" "orG,rG"))]
3396 && (register_operand (operands[0], TFmode)
3397 || register_operand (operands[1], TFmode)
3398 || fp_zero_operand (operands[1], TFmode))"
3400 [(set_attr "length" "2")])
3402 ;; Now all the splits to handle multi-insn TF mode moves.
3404 [(set (match_operand:TF 0 "register_operand" "")
3405 (match_operand:TF 1 "register_operand" ""))]
3409 && ! TARGET_HARD_QUAD)
3410 || ! fp_register_operand (operands[0], TFmode))"
3411 [(clobber (const_int 0))]
3413 rtx set_dest = operands[0];
3414 rtx set_src = operands[1];
3418 dest1 = gen_df_reg (set_dest, 0);
3419 dest2 = gen_df_reg (set_dest, 1);
3420 src1 = gen_df_reg (set_src, 0);
3421 src2 = gen_df_reg (set_src, 1);
3423 /* Now emit using the real source and destination we found, swapping
3424 the order if we detect overlap. */
3425 if (reg_overlap_mentioned_p (dest1, src2))
3427 emit_insn (gen_movdf (dest2, src2));
3428 emit_insn (gen_movdf (dest1, src1));
3432 emit_insn (gen_movdf (dest1, src1));
3433 emit_insn (gen_movdf (dest2, src2));
3439 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3440 (match_operand:TF 1 "fp_zero_operand" ""))]
3442 [(clobber (const_int 0))]
3444 rtx set_dest = operands[0];
3447 switch (GET_CODE (set_dest))
3450 dest1 = gen_df_reg (set_dest, 0);
3451 dest2 = gen_df_reg (set_dest, 1);
3454 dest1 = adjust_address (set_dest, DFmode, 0);
3455 dest2 = adjust_address (set_dest, DFmode, 8);
3461 emit_insn (gen_movdf (dest1, CONST0_RTX (DFmode)));
3462 emit_insn (gen_movdf (dest2, CONST0_RTX (DFmode)));
3467 [(set (match_operand:TF 0 "register_operand" "")
3468 (match_operand:TF 1 "memory_operand" ""))]
3470 && offsettable_memref_p (operands[1])
3472 || ! TARGET_HARD_QUAD
3473 || ! fp_register_operand (operands[0], TFmode)))"
3474 [(clobber (const_int 0))]
3476 rtx word0 = adjust_address (operands[1], DFmode, 0);
3477 rtx word1 = adjust_address (operands[1], DFmode, 8);
3478 rtx set_dest, dest1, dest2;
3480 set_dest = operands[0];
3482 dest1 = gen_df_reg (set_dest, 0);
3483 dest2 = gen_df_reg (set_dest, 1);
3485 /* Now output, ordering such that we don't clobber any registers
3486 mentioned in the address. */
3487 if (reg_overlap_mentioned_p (dest1, word1))
3490 emit_insn (gen_movdf (dest2, word1));
3491 emit_insn (gen_movdf (dest1, word0));
3495 emit_insn (gen_movdf (dest1, word0));
3496 emit_insn (gen_movdf (dest2, word1));
3502 [(set (match_operand:TF 0 "memory_operand" "")
3503 (match_operand:TF 1 "register_operand" ""))]
3505 && offsettable_memref_p (operands[0])
3507 || ! TARGET_HARD_QUAD
3508 || ! fp_register_operand (operands[1], TFmode)))"
3509 [(clobber (const_int 0))]
3511 rtx set_src = operands[1];
3513 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 0),
3514 gen_df_reg (set_src, 0)));
3515 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 8),
3516 gen_df_reg (set_src, 1)));
3520 ;; SPARC V9 conditional move instructions.
3522 ;; We can handle larger constants here for some flavors, but for now we keep
3523 ;; it simple and only allow those constants supported by all flavors.
3524 ;; Note that emit_conditional_move canonicalizes operands 2,3 so that operand
3525 ;; 3 contains the constant if one is present, but we handle either for
3526 ;; generality (sparc.c puts a constant in operand 2).
3528 (define_expand "movqicc"
3529 [(set (match_operand:QI 0 "register_operand" "")
3530 (if_then_else:QI (match_operand 1 "comparison_operator" "")
3531 (match_operand:QI 2 "arith10_operand" "")
3532 (match_operand:QI 3 "arith10_operand" "")))]
3535 enum rtx_code code = GET_CODE (operands[1]);
3537 if (GET_MODE (sparc_compare_op0) == DImode
3541 if (sparc_compare_op1 == const0_rtx
3542 && GET_CODE (sparc_compare_op0) == REG
3543 && GET_MODE (sparc_compare_op0) == DImode
3544 && v9_regcmp_p (code))
3546 operands[1] = gen_rtx_fmt_ee (code, DImode,
3547 sparc_compare_op0, sparc_compare_op1);
3551 rtx cc_reg = gen_compare_reg (code,
3552 sparc_compare_op0, sparc_compare_op1);
3553 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3557 (define_expand "movhicc"
3558 [(set (match_operand:HI 0 "register_operand" "")
3559 (if_then_else:HI (match_operand 1 "comparison_operator" "")
3560 (match_operand:HI 2 "arith10_operand" "")
3561 (match_operand:HI 3 "arith10_operand" "")))]
3564 enum rtx_code code = GET_CODE (operands[1]);
3566 if (GET_MODE (sparc_compare_op0) == DImode
3570 if (sparc_compare_op1 == const0_rtx
3571 && GET_CODE (sparc_compare_op0) == REG
3572 && GET_MODE (sparc_compare_op0) == DImode
3573 && v9_regcmp_p (code))
3575 operands[1] = gen_rtx_fmt_ee (code, DImode,
3576 sparc_compare_op0, sparc_compare_op1);
3580 rtx cc_reg = gen_compare_reg (code,
3581 sparc_compare_op0, sparc_compare_op1);
3582 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3586 (define_expand "movsicc"
3587 [(set (match_operand:SI 0 "register_operand" "")
3588 (if_then_else:SI (match_operand 1 "comparison_operator" "")
3589 (match_operand:SI 2 "arith10_operand" "")
3590 (match_operand:SI 3 "arith10_operand" "")))]
3593 enum rtx_code code = GET_CODE (operands[1]);
3594 enum machine_mode op0_mode = GET_MODE (sparc_compare_op0);
3596 if (sparc_compare_op1 == const0_rtx
3597 && GET_CODE (sparc_compare_op0) == REG
3598 && (TARGET_ARCH64 && op0_mode == DImode && v9_regcmp_p (code)))
3600 operands[1] = gen_rtx_fmt_ee (code, op0_mode,
3601 sparc_compare_op0, sparc_compare_op1);
3605 rtx cc_reg = gen_compare_reg (code,
3606 sparc_compare_op0, sparc_compare_op1);
3607 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg),
3608 cc_reg, const0_rtx);
3612 (define_expand "movdicc"
3613 [(set (match_operand:DI 0 "register_operand" "")
3614 (if_then_else:DI (match_operand 1 "comparison_operator" "")
3615 (match_operand:DI 2 "arith10_double_operand" "")
3616 (match_operand:DI 3 "arith10_double_operand" "")))]
3619 enum rtx_code code = GET_CODE (operands[1]);
3621 if (sparc_compare_op1 == const0_rtx
3622 && GET_CODE (sparc_compare_op0) == REG
3623 && GET_MODE (sparc_compare_op0) == DImode
3624 && v9_regcmp_p (code))
3626 operands[1] = gen_rtx_fmt_ee (code, DImode,
3627 sparc_compare_op0, sparc_compare_op1);
3631 rtx cc_reg = gen_compare_reg (code,
3632 sparc_compare_op0, sparc_compare_op1);
3633 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg),
3634 cc_reg, const0_rtx);
3638 (define_expand "movsfcc"
3639 [(set (match_operand:SF 0 "register_operand" "")
3640 (if_then_else:SF (match_operand 1 "comparison_operator" "")
3641 (match_operand:SF 2 "register_operand" "")
3642 (match_operand:SF 3 "register_operand" "")))]
3643 "TARGET_V9 && TARGET_FPU"
3645 enum rtx_code code = GET_CODE (operands[1]);
3647 if (GET_MODE (sparc_compare_op0) == DImode
3651 if (sparc_compare_op1 == const0_rtx
3652 && GET_CODE (sparc_compare_op0) == REG
3653 && GET_MODE (sparc_compare_op0) == DImode
3654 && v9_regcmp_p (code))
3656 operands[1] = gen_rtx_fmt_ee (code, DImode,
3657 sparc_compare_op0, sparc_compare_op1);
3661 rtx cc_reg = gen_compare_reg (code,
3662 sparc_compare_op0, sparc_compare_op1);
3663 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3667 (define_expand "movdfcc"
3668 [(set (match_operand:DF 0 "register_operand" "")
3669 (if_then_else:DF (match_operand 1 "comparison_operator" "")
3670 (match_operand:DF 2 "register_operand" "")
3671 (match_operand:DF 3 "register_operand" "")))]
3672 "TARGET_V9 && TARGET_FPU"
3674 enum rtx_code code = GET_CODE (operands[1]);
3676 if (GET_MODE (sparc_compare_op0) == DImode
3680 if (sparc_compare_op1 == const0_rtx
3681 && GET_CODE (sparc_compare_op0) == REG
3682 && GET_MODE (sparc_compare_op0) == DImode
3683 && v9_regcmp_p (code))
3685 operands[1] = gen_rtx_fmt_ee (code, DImode,
3686 sparc_compare_op0, sparc_compare_op1);
3690 rtx cc_reg = gen_compare_reg (code,
3691 sparc_compare_op0, sparc_compare_op1);
3692 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3696 (define_expand "movtfcc"
3697 [(set (match_operand:TF 0 "register_operand" "")
3698 (if_then_else:TF (match_operand 1 "comparison_operator" "")
3699 (match_operand:TF 2 "register_operand" "")
3700 (match_operand:TF 3 "register_operand" "")))]
3701 "TARGET_V9 && TARGET_FPU"
3703 enum rtx_code code = GET_CODE (operands[1]);
3705 if (GET_MODE (sparc_compare_op0) == DImode
3709 if (sparc_compare_op1 == const0_rtx
3710 && GET_CODE (sparc_compare_op0) == REG
3711 && GET_MODE (sparc_compare_op0) == DImode
3712 && v9_regcmp_p (code))
3714 operands[1] = gen_rtx_fmt_ee (code, DImode,
3715 sparc_compare_op0, sparc_compare_op1);
3719 rtx cc_reg = gen_compare_reg (code,
3720 sparc_compare_op0, sparc_compare_op1);
3721 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3725 ;; Conditional move define_insns.
3727 (define_insn "*movqi_cc_sp64"
3728 [(set (match_operand:QI 0 "register_operand" "=r,r")
3729 (if_then_else:QI (match_operator 1 "comparison_operator"
3730 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3732 (match_operand:QI 3 "arith11_operand" "rL,0")
3733 (match_operand:QI 4 "arith11_operand" "0,rL")))]
3737 mov%c1\t%x2, %4, %0"
3738 [(set_attr "type" "cmove")])
3740 (define_insn "*movhi_cc_sp64"
3741 [(set (match_operand:HI 0 "register_operand" "=r,r")
3742 (if_then_else:HI (match_operator 1 "comparison_operator"
3743 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3745 (match_operand:HI 3 "arith11_operand" "rL,0")
3746 (match_operand:HI 4 "arith11_operand" "0,rL")))]
3750 mov%c1\t%x2, %4, %0"
3751 [(set_attr "type" "cmove")])
3753 (define_insn "*movsi_cc_sp64"
3754 [(set (match_operand:SI 0 "register_operand" "=r,r")
3755 (if_then_else:SI (match_operator 1 "comparison_operator"
3756 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3758 (match_operand:SI 3 "arith11_operand" "rL,0")
3759 (match_operand:SI 4 "arith11_operand" "0,rL")))]
3763 mov%c1\t%x2, %4, %0"
3764 [(set_attr "type" "cmove")])
3766 ;; ??? The constraints of operands 3,4 need work.
3767 (define_insn "*movdi_cc_sp64"
3768 [(set (match_operand:DI 0 "register_operand" "=r,r")
3769 (if_then_else:DI (match_operator 1 "comparison_operator"
3770 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3772 (match_operand:DI 3 "arith11_double_operand" "rLH,0")
3773 (match_operand:DI 4 "arith11_double_operand" "0,rLH")))]
3777 mov%c1\t%x2, %4, %0"
3778 [(set_attr "type" "cmove")])
3780 (define_insn "*movdi_cc_sp64_trunc"
3781 [(set (match_operand:SI 0 "register_operand" "=r,r")
3782 (if_then_else:SI (match_operator 1 "comparison_operator"
3783 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3785 (match_operand:SI 3 "arith11_double_operand" "rLH,0")
3786 (match_operand:SI 4 "arith11_double_operand" "0,rLH")))]
3790 mov%c1\t%x2, %4, %0"
3791 [(set_attr "type" "cmove")])
3793 (define_insn "*movsf_cc_sp64"
3794 [(set (match_operand:SF 0 "register_operand" "=f,f")
3795 (if_then_else:SF (match_operator 1 "comparison_operator"
3796 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3798 (match_operand:SF 3 "register_operand" "f,0")
3799 (match_operand:SF 4 "register_operand" "0,f")))]
3800 "TARGET_V9 && TARGET_FPU"
3802 fmovs%C1\t%x2, %3, %0
3803 fmovs%c1\t%x2, %4, %0"
3804 [(set_attr "type" "fpcmove")])
3806 (define_insn "movdf_cc_sp64"
3807 [(set (match_operand:DF 0 "register_operand" "=e,e")
3808 (if_then_else:DF (match_operator 1 "comparison_operator"
3809 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3811 (match_operand:DF 3 "register_operand" "e,0")
3812 (match_operand:DF 4 "register_operand" "0,e")))]
3813 "TARGET_V9 && TARGET_FPU"
3815 fmovd%C1\t%x2, %3, %0
3816 fmovd%c1\t%x2, %4, %0"
3817 [(set_attr "type" "fpcmove")
3818 (set_attr "fptype" "double")])
3820 (define_insn "*movtf_cc_hq_sp64"
3821 [(set (match_operand:TF 0 "register_operand" "=e,e")
3822 (if_then_else:TF (match_operator 1 "comparison_operator"
3823 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3825 (match_operand:TF 3 "register_operand" "e,0")
3826 (match_operand:TF 4 "register_operand" "0,e")))]
3827 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
3829 fmovq%C1\t%x2, %3, %0
3830 fmovq%c1\t%x2, %4, %0"
3831 [(set_attr "type" "fpcmove")])
3833 (define_insn_and_split "*movtf_cc_sp64"
3834 [(set (match_operand:TF 0 "register_operand" "=e,e")
3835 (if_then_else:TF (match_operator 1 "comparison_operator"
3836 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3838 (match_operand:TF 3 "register_operand" "e,0")
3839 (match_operand:TF 4 "register_operand" "0,e")))]
3840 "TARGET_V9 && TARGET_FPU && !TARGET_HARD_QUAD"
3842 "&& reload_completed"
3843 [(clobber (const_int 0))]
3845 rtx set_dest = operands[0];
3846 rtx set_srca = operands[3];
3847 rtx set_srcb = operands[4];
3848 int third = rtx_equal_p (set_dest, set_srca);
3850 rtx srca1, srca2, srcb1, srcb2;
3852 dest1 = gen_df_reg (set_dest, 0);
3853 dest2 = gen_df_reg (set_dest, 1);
3854 srca1 = gen_df_reg (set_srca, 0);
3855 srca2 = gen_df_reg (set_srca, 1);
3856 srcb1 = gen_df_reg (set_srcb, 0);
3857 srcb2 = gen_df_reg (set_srcb, 1);
3859 /* Now emit using the real source and destination we found, swapping
3860 the order if we detect overlap. */
3861 if ((third && reg_overlap_mentioned_p (dest1, srcb2))
3862 || (!third && reg_overlap_mentioned_p (dest1, srca2)))
3864 emit_insn (gen_movdf_cc_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
3865 emit_insn (gen_movdf_cc_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
3869 emit_insn (gen_movdf_cc_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
3870 emit_insn (gen_movdf_cc_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
3874 [(set_attr "length" "2")])
3876 (define_insn "*movqi_cc_reg_sp64"
3877 [(set (match_operand:QI 0 "register_operand" "=r,r")
3878 (if_then_else:QI (match_operator 1 "v9_regcmp_op"
3879 [(match_operand:DI 2 "register_operand" "r,r")
3881 (match_operand:QI 3 "arith10_operand" "rM,0")
3882 (match_operand:QI 4 "arith10_operand" "0,rM")))]
3885 movr%D1\t%2, %r3, %0
3886 movr%d1\t%2, %r4, %0"
3887 [(set_attr "type" "cmove")])
3889 (define_insn "*movhi_cc_reg_sp64"
3890 [(set (match_operand:HI 0 "register_operand" "=r,r")
3891 (if_then_else:HI (match_operator 1 "v9_regcmp_op"
3892 [(match_operand:DI 2 "register_operand" "r,r")
3894 (match_operand:HI 3 "arith10_operand" "rM,0")
3895 (match_operand:HI 4 "arith10_operand" "0,rM")))]
3898 movr%D1\t%2, %r3, %0
3899 movr%d1\t%2, %r4, %0"
3900 [(set_attr "type" "cmove")])
3902 (define_insn "*movsi_cc_reg_sp64"
3903 [(set (match_operand:SI 0 "register_operand" "=r,r")
3904 (if_then_else:SI (match_operator 1 "v9_regcmp_op"
3905 [(match_operand:DI 2 "register_operand" "r,r")
3907 (match_operand:SI 3 "arith10_operand" "rM,0")
3908 (match_operand:SI 4 "arith10_operand" "0,rM")))]
3911 movr%D1\t%2, %r3, %0
3912 movr%d1\t%2, %r4, %0"
3913 [(set_attr "type" "cmove")])
3915 ;; ??? The constraints of operands 3,4 need work.
3916 (define_insn "*movdi_cc_reg_sp64"
3917 [(set (match_operand:DI 0 "register_operand" "=r,r")
3918 (if_then_else:DI (match_operator 1 "v9_regcmp_op"
3919 [(match_operand:DI 2 "register_operand" "r,r")
3921 (match_operand:DI 3 "arith10_double_operand" "rMH,0")
3922 (match_operand:DI 4 "arith10_double_operand" "0,rMH")))]
3925 movr%D1\t%2, %r3, %0
3926 movr%d1\t%2, %r4, %0"
3927 [(set_attr "type" "cmove")])
3929 (define_insn "*movdi_cc_reg_sp64_trunc"
3930 [(set (match_operand:SI 0 "register_operand" "=r,r")
3931 (if_then_else:SI (match_operator 1 "v9_regcmp_op"
3932 [(match_operand:DI 2 "register_operand" "r,r")
3934 (match_operand:SI 3 "arith10_double_operand" "rMH,0")
3935 (match_operand:SI 4 "arith10_double_operand" "0,rMH")))]
3938 movr%D1\t%2, %r3, %0
3939 movr%d1\t%2, %r4, %0"
3940 [(set_attr "type" "cmove")])
3942 (define_insn "*movsf_cc_reg_sp64"
3943 [(set (match_operand:SF 0 "register_operand" "=f,f")
3944 (if_then_else:SF (match_operator 1 "v9_regcmp_op"
3945 [(match_operand:DI 2 "register_operand" "r,r")
3947 (match_operand:SF 3 "register_operand" "f,0")
3948 (match_operand:SF 4 "register_operand" "0,f")))]
3949 "TARGET_ARCH64 && TARGET_FPU"
3951 fmovrs%D1\t%2, %3, %0
3952 fmovrs%d1\t%2, %4, %0"
3953 [(set_attr "type" "fpcrmove")])
3955 (define_insn "movdf_cc_reg_sp64"
3956 [(set (match_operand:DF 0 "register_operand" "=e,e")
3957 (if_then_else:DF (match_operator 1 "v9_regcmp_op"
3958 [(match_operand:DI 2 "register_operand" "r,r")
3960 (match_operand:DF 3 "register_operand" "e,0")
3961 (match_operand:DF 4 "register_operand" "0,e")))]
3962 "TARGET_ARCH64 && TARGET_FPU"
3964 fmovrd%D1\t%2, %3, %0
3965 fmovrd%d1\t%2, %4, %0"
3966 [(set_attr "type" "fpcrmove")
3967 (set_attr "fptype" "double")])
3969 (define_insn "*movtf_cc_reg_hq_sp64"
3970 [(set (match_operand:TF 0 "register_operand" "=e,e")
3971 (if_then_else:TF (match_operator 1 "v9_regcmp_op"
3972 [(match_operand:DI 2 "register_operand" "r,r")
3974 (match_operand:TF 3 "register_operand" "e,0")
3975 (match_operand:TF 4 "register_operand" "0,e")))]
3976 "TARGET_ARCH64 && TARGET_FPU && TARGET_HARD_QUAD"
3978 fmovrq%D1\t%2, %3, %0
3979 fmovrq%d1\t%2, %4, %0"
3980 [(set_attr "type" "fpcrmove")])
3982 (define_insn_and_split "*movtf_cc_reg_sp64"
3983 [(set (match_operand:TF 0 "register_operand" "=e,e")
3984 (if_then_else:TF (match_operator 1 "v9_regcmp_op"
3985 [(match_operand:DI 2 "register_operand" "r,r")
3987 (match_operand:TF 3 "register_operand" "e,0")
3988 (match_operand:TF 4 "register_operand" "0,e")))]
3989 "TARGET_ARCH64 && TARGET_FPU && ! TARGET_HARD_QUAD"
3991 "&& reload_completed"
3992 [(clobber (const_int 0))]
3994 rtx set_dest = operands[0];
3995 rtx set_srca = operands[3];
3996 rtx set_srcb = operands[4];
3997 int third = rtx_equal_p (set_dest, set_srca);
3999 rtx srca1, srca2, srcb1, srcb2;
4001 dest1 = gen_df_reg (set_dest, 0);
4002 dest2 = gen_df_reg (set_dest, 1);
4003 srca1 = gen_df_reg (set_srca, 0);
4004 srca2 = gen_df_reg (set_srca, 1);
4005 srcb1 = gen_df_reg (set_srcb, 0);
4006 srcb2 = gen_df_reg (set_srcb, 1);
4008 /* Now emit using the real source and destination we found, swapping
4009 the order if we detect overlap. */
4010 if ((third && reg_overlap_mentioned_p (dest1, srcb2))
4011 || (!third && reg_overlap_mentioned_p (dest1, srca2)))
4013 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
4014 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
4018 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
4019 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
4023 [(set_attr "length" "2")])
4026 ;;- zero extension instructions
4028 ;; These patterns originally accepted general_operands, however, slightly
4029 ;; better code is generated by only accepting register_operands, and then
4030 ;; letting combine generate the ldu[hb] insns.
4032 (define_expand "zero_extendhisi2"
4033 [(set (match_operand:SI 0 "register_operand" "")
4034 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
4037 rtx temp = gen_reg_rtx (SImode);
4038 rtx shift_16 = GEN_INT (16);
4039 int op1_subbyte = 0;
4041 if (GET_CODE (operand1) == SUBREG)
4043 op1_subbyte = SUBREG_BYTE (operand1);
4044 op1_subbyte /= GET_MODE_SIZE (SImode);
4045 op1_subbyte *= GET_MODE_SIZE (SImode);
4046 operand1 = XEXP (operand1, 0);
4049 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4051 emit_insn (gen_lshrsi3 (operand0, temp, shift_16));
4055 (define_insn "*zero_extendhisi2_insn"
4056 [(set (match_operand:SI 0 "register_operand" "=r")
4057 (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
4060 [(set_attr "type" "load")
4061 (set_attr "us3load_type" "3cycle")])
4063 (define_expand "zero_extendqihi2"
4064 [(set (match_operand:HI 0 "register_operand" "")
4065 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
4069 (define_insn "*zero_extendqihi2_insn"
4070 [(set (match_operand:HI 0 "register_operand" "=r,r")
4071 (zero_extend:HI (match_operand:QI 1 "input_operand" "r,m")))]
4072 "GET_CODE (operands[1]) != CONST_INT"
4076 [(set_attr "type" "*,load")
4077 (set_attr "us3load_type" "*,3cycle")])
4079 (define_expand "zero_extendqisi2"
4080 [(set (match_operand:SI 0 "register_operand" "")
4081 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
4085 (define_insn "*zero_extendqisi2_insn"
4086 [(set (match_operand:SI 0 "register_operand" "=r,r")
4087 (zero_extend:SI (match_operand:QI 1 "input_operand" "r,m")))]
4088 "GET_CODE (operands[1]) != CONST_INT"
4092 [(set_attr "type" "*,load")
4093 (set_attr "us3load_type" "*,3cycle")])
4095 (define_expand "zero_extendqidi2"
4096 [(set (match_operand:DI 0 "register_operand" "")
4097 (zero_extend:DI (match_operand:QI 1 "register_operand" "")))]
4101 (define_insn "*zero_extendqidi2_insn"
4102 [(set (match_operand:DI 0 "register_operand" "=r,r")
4103 (zero_extend:DI (match_operand:QI 1 "input_operand" "r,m")))]
4104 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
4108 [(set_attr "type" "*,load")
4109 (set_attr "us3load_type" "*,3cycle")])
4111 (define_expand "zero_extendhidi2"
4112 [(set (match_operand:DI 0 "register_operand" "")
4113 (zero_extend:DI (match_operand:HI 1 "register_operand" "")))]
4116 rtx temp = gen_reg_rtx (DImode);
4117 rtx shift_48 = GEN_INT (48);
4118 int op1_subbyte = 0;
4120 if (GET_CODE (operand1) == SUBREG)
4122 op1_subbyte = SUBREG_BYTE (operand1);
4123 op1_subbyte /= GET_MODE_SIZE (DImode);
4124 op1_subbyte *= GET_MODE_SIZE (DImode);
4125 operand1 = XEXP (operand1, 0);
4128 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
4130 emit_insn (gen_lshrdi3 (operand0, temp, shift_48));
4134 (define_insn "*zero_extendhidi2_insn"
4135 [(set (match_operand:DI 0 "register_operand" "=r")
4136 (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
4139 [(set_attr "type" "load")
4140 (set_attr "us3load_type" "3cycle")])
4143 ;; ??? Write truncdisi pattern using sra?
4145 (define_expand "zero_extendsidi2"
4146 [(set (match_operand:DI 0 "register_operand" "")
4147 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
4151 (define_insn "*zero_extendsidi2_insn_sp64"
4152 [(set (match_operand:DI 0 "register_operand" "=r,r")
4153 (zero_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
4154 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
4158 [(set_attr "type" "shift,load")])
4160 (define_insn_and_split "*zero_extendsidi2_insn_sp32"
4161 [(set (match_operand:DI 0 "register_operand" "=r")
4162 (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
4165 "&& reload_completed"
4166 [(set (match_dup 2) (match_dup 3))
4167 (set (match_dup 4) (match_dup 5))]
4171 dest1 = gen_highpart (SImode, operands[0]);
4172 dest2 = gen_lowpart (SImode, operands[0]);
4174 /* Swap the order in case of overlap. */
4175 if (REGNO (dest1) == REGNO (operands[1]))
4177 operands[2] = dest2;
4178 operands[3] = operands[1];
4179 operands[4] = dest1;
4180 operands[5] = const0_rtx;
4184 operands[2] = dest1;
4185 operands[3] = const0_rtx;
4186 operands[4] = dest2;
4187 operands[5] = operands[1];
4190 [(set_attr "length" "2")])
4192 ;; Simplify comparisons of extended values.
4194 (define_insn "*cmp_zero_extendqisi2"
4196 (compare:CC (zero_extend:SI (match_operand:QI 0 "register_operand" "r"))
4199 "andcc\t%0, 0xff, %%g0"
4200 [(set_attr "type" "compare")])
4202 (define_insn "*cmp_zero_qi"
4204 (compare:CC (match_operand:QI 0 "register_operand" "r")
4207 "andcc\t%0, 0xff, %%g0"
4208 [(set_attr "type" "compare")])
4210 (define_insn "*cmp_zero_extendqisi2_set"
4212 (compare:CC (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
4214 (set (match_operand:SI 0 "register_operand" "=r")
4215 (zero_extend:SI (match_dup 1)))]
4217 "andcc\t%1, 0xff, %0"
4218 [(set_attr "type" "compare")])
4220 (define_insn "*cmp_zero_extendqisi2_andcc_set"
4222 (compare:CC (and:SI (match_operand:SI 1 "register_operand" "r")
4225 (set (match_operand:SI 0 "register_operand" "=r")
4226 (zero_extend:SI (subreg:QI (match_dup 1) 0)))]
4228 "andcc\t%1, 0xff, %0"
4229 [(set_attr "type" "compare")])
4231 (define_insn "*cmp_zero_extendqidi2"
4233 (compare:CCX (zero_extend:DI (match_operand:QI 0 "register_operand" "r"))
4236 "andcc\t%0, 0xff, %%g0"
4237 [(set_attr "type" "compare")])
4239 (define_insn "*cmp_zero_qi_sp64"
4241 (compare:CCX (match_operand:QI 0 "register_operand" "r")
4244 "andcc\t%0, 0xff, %%g0"
4245 [(set_attr "type" "compare")])
4247 (define_insn "*cmp_zero_extendqidi2_set"
4249 (compare:CCX (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
4251 (set (match_operand:DI 0 "register_operand" "=r")
4252 (zero_extend:DI (match_dup 1)))]
4254 "andcc\t%1, 0xff, %0"
4255 [(set_attr "type" "compare")])
4257 (define_insn "*cmp_zero_extendqidi2_andcc_set"
4259 (compare:CCX (and:DI (match_operand:DI 1 "register_operand" "r")
4262 (set (match_operand:DI 0 "register_operand" "=r")
4263 (zero_extend:DI (subreg:QI (match_dup 1) 0)))]
4265 "andcc\t%1, 0xff, %0"
4266 [(set_attr "type" "compare")])
4268 ;; Similarly, handle {SI,DI}->QI mode truncation followed by a compare.
4270 (define_insn "*cmp_siqi_trunc"
4272 (compare:CC (subreg:QI (match_operand:SI 0 "register_operand" "r") 3)
4275 "andcc\t%0, 0xff, %%g0"
4276 [(set_attr "type" "compare")])
4278 (define_insn "*cmp_siqi_trunc_set"
4280 (compare:CC (subreg:QI (match_operand:SI 1 "register_operand" "r") 3)
4282 (set (match_operand:QI 0 "register_operand" "=r")
4283 (subreg:QI (match_dup 1) 3))]
4285 "andcc\t%1, 0xff, %0"
4286 [(set_attr "type" "compare")])
4288 (define_insn "*cmp_diqi_trunc"
4290 (compare:CC (subreg:QI (match_operand:DI 0 "register_operand" "r") 7)
4293 "andcc\t%0, 0xff, %%g0"
4294 [(set_attr "type" "compare")])
4296 (define_insn "*cmp_diqi_trunc_set"
4298 (compare:CC (subreg:QI (match_operand:DI 1 "register_operand" "r") 7)
4300 (set (match_operand:QI 0 "register_operand" "=r")
4301 (subreg:QI (match_dup 1) 7))]
4303 "andcc\t%1, 0xff, %0"
4304 [(set_attr "type" "compare")])
4306 ;;- sign extension instructions
4308 ;; These patterns originally accepted general_operands, however, slightly
4309 ;; better code is generated by only accepting register_operands, and then
4310 ;; letting combine generate the lds[hb] insns.
4312 (define_expand "extendhisi2"
4313 [(set (match_operand:SI 0 "register_operand" "")
4314 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
4317 rtx temp = gen_reg_rtx (SImode);
4318 rtx shift_16 = GEN_INT (16);
4319 int op1_subbyte = 0;
4321 if (GET_CODE (operand1) == SUBREG)
4323 op1_subbyte = SUBREG_BYTE (operand1);
4324 op1_subbyte /= GET_MODE_SIZE (SImode);
4325 op1_subbyte *= GET_MODE_SIZE (SImode);
4326 operand1 = XEXP (operand1, 0);
4329 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4331 emit_insn (gen_ashrsi3 (operand0, temp, shift_16));
4335 (define_insn "*sign_extendhisi2_insn"
4336 [(set (match_operand:SI 0 "register_operand" "=r")
4337 (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
4340 [(set_attr "type" "sload")
4341 (set_attr "us3load_type" "3cycle")])
4343 (define_expand "extendqihi2"
4344 [(set (match_operand:HI 0 "register_operand" "")
4345 (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
4348 rtx temp = gen_reg_rtx (SImode);
4349 rtx shift_24 = GEN_INT (24);
4350 int op1_subbyte = 0;
4351 int op0_subbyte = 0;
4353 if (GET_CODE (operand1) == SUBREG)
4355 op1_subbyte = SUBREG_BYTE (operand1);
4356 op1_subbyte /= GET_MODE_SIZE (SImode);
4357 op1_subbyte *= GET_MODE_SIZE (SImode);
4358 operand1 = XEXP (operand1, 0);
4360 if (GET_CODE (operand0) == SUBREG)
4362 op0_subbyte = SUBREG_BYTE (operand0);
4363 op0_subbyte /= GET_MODE_SIZE (SImode);
4364 op0_subbyte *= GET_MODE_SIZE (SImode);
4365 operand0 = XEXP (operand0, 0);
4367 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4369 if (GET_MODE (operand0) != SImode)
4370 operand0 = gen_rtx_SUBREG (SImode, operand0, op0_subbyte);
4371 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
4375 (define_insn "*sign_extendqihi2_insn"
4376 [(set (match_operand:HI 0 "register_operand" "=r")
4377 (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
4380 [(set_attr "type" "sload")
4381 (set_attr "us3load_type" "3cycle")])
4383 (define_expand "extendqisi2"
4384 [(set (match_operand:SI 0 "register_operand" "")
4385 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
4388 rtx temp = gen_reg_rtx (SImode);
4389 rtx shift_24 = GEN_INT (24);
4390 int op1_subbyte = 0;
4392 if (GET_CODE (operand1) == SUBREG)
4394 op1_subbyte = SUBREG_BYTE (operand1);
4395 op1_subbyte /= GET_MODE_SIZE (SImode);
4396 op1_subbyte *= GET_MODE_SIZE (SImode);
4397 operand1 = XEXP (operand1, 0);
4400 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4402 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
4406 (define_insn "*sign_extendqisi2_insn"
4407 [(set (match_operand:SI 0 "register_operand" "=r")
4408 (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
4411 [(set_attr "type" "sload")
4412 (set_attr "us3load_type" "3cycle")])
4414 (define_expand "extendqidi2"
4415 [(set (match_operand:DI 0 "register_operand" "")
4416 (sign_extend:DI (match_operand:QI 1 "register_operand" "")))]
4419 rtx temp = gen_reg_rtx (DImode);
4420 rtx shift_56 = GEN_INT (56);
4421 int op1_subbyte = 0;
4423 if (GET_CODE (operand1) == SUBREG)
4425 op1_subbyte = SUBREG_BYTE (operand1);
4426 op1_subbyte /= GET_MODE_SIZE (DImode);
4427 op1_subbyte *= GET_MODE_SIZE (DImode);
4428 operand1 = XEXP (operand1, 0);
4431 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
4433 emit_insn (gen_ashrdi3 (operand0, temp, shift_56));
4437 (define_insn "*sign_extendqidi2_insn"
4438 [(set (match_operand:DI 0 "register_operand" "=r")
4439 (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
4442 [(set_attr "type" "sload")
4443 (set_attr "us3load_type" "3cycle")])
4445 (define_expand "extendhidi2"
4446 [(set (match_operand:DI 0 "register_operand" "")
4447 (sign_extend:DI (match_operand:HI 1 "register_operand" "")))]
4450 rtx temp = gen_reg_rtx (DImode);
4451 rtx shift_48 = GEN_INT (48);
4452 int op1_subbyte = 0;
4454 if (GET_CODE (operand1) == SUBREG)
4456 op1_subbyte = SUBREG_BYTE (operand1);
4457 op1_subbyte /= GET_MODE_SIZE (DImode);
4458 op1_subbyte *= GET_MODE_SIZE (DImode);
4459 operand1 = XEXP (operand1, 0);
4462 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
4464 emit_insn (gen_ashrdi3 (operand0, temp, shift_48));
4468 (define_insn "*sign_extendhidi2_insn"
4469 [(set (match_operand:DI 0 "register_operand" "=r")
4470 (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
4473 [(set_attr "type" "sload")
4474 (set_attr "us3load_type" "3cycle")])
4476 (define_expand "extendsidi2"
4477 [(set (match_operand:DI 0 "register_operand" "")
4478 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
4482 (define_insn "*sign_extendsidi2_insn"
4483 [(set (match_operand:DI 0 "register_operand" "=r,r")
4484 (sign_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
4489 [(set_attr "type" "shift,sload")
4490 (set_attr "us3load_type" "*,3cycle")])
4492 ;; Special pattern for optimizing bit-field compares. This is needed
4493 ;; because combine uses this as a canonical form.
4495 (define_insn "*cmp_zero_extract"
4498 (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
4499 (match_operand:SI 1 "small_int_or_double" "n")
4500 (match_operand:SI 2 "small_int_or_double" "n"))
4502 "(GET_CODE (operands[2]) == CONST_INT
4503 && INTVAL (operands[2]) > 19)
4504 || (GET_CODE (operands[2]) == CONST_DOUBLE
4505 && CONST_DOUBLE_LOW (operands[2]) > 19)"
4507 int len = (GET_CODE (operands[1]) == CONST_INT
4508 ? INTVAL (operands[1])
4509 : CONST_DOUBLE_LOW (operands[1]));
4511 (GET_CODE (operands[2]) == CONST_INT
4512 ? INTVAL (operands[2])
4513 : CONST_DOUBLE_LOW (operands[2])) - len;
4514 HOST_WIDE_INT mask = ((1 << len) - 1) << pos;
4516 operands[1] = GEN_INT (mask);
4517 return "andcc\t%0, %1, %%g0";
4519 [(set_attr "type" "compare")])
4521 (define_insn "*cmp_zero_extract_sp64"
4524 (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
4525 (match_operand:SI 1 "small_int_or_double" "n")
4526 (match_operand:SI 2 "small_int_or_double" "n"))
4529 && ((GET_CODE (operands[2]) == CONST_INT
4530 && INTVAL (operands[2]) > 51)
4531 || (GET_CODE (operands[2]) == CONST_DOUBLE
4532 && CONST_DOUBLE_LOW (operands[2]) > 51))"
4534 int len = (GET_CODE (operands[1]) == CONST_INT
4535 ? INTVAL (operands[1])
4536 : CONST_DOUBLE_LOW (operands[1]));
4538 (GET_CODE (operands[2]) == CONST_INT
4539 ? INTVAL (operands[2])
4540 : CONST_DOUBLE_LOW (operands[2])) - len;
4541 HOST_WIDE_INT mask = (((unsigned HOST_WIDE_INT) 1 << len) - 1) << pos;
4543 operands[1] = GEN_INT (mask);
4544 return "andcc\t%0, %1, %%g0";
4546 [(set_attr "type" "compare")])
4548 ;; Conversions between float, double and long double.
4550 (define_insn "extendsfdf2"
4551 [(set (match_operand:DF 0 "register_operand" "=e")
4553 (match_operand:SF 1 "register_operand" "f")))]
4556 [(set_attr "type" "fp")
4557 (set_attr "fptype" "double")])
4559 (define_expand "extendsftf2"
4560 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4562 (match_operand:SF 1 "register_operand" "")))]
4563 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4564 "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
4566 (define_insn "*extendsftf2_hq"
4567 [(set (match_operand:TF 0 "register_operand" "=e")
4569 (match_operand:SF 1 "register_operand" "f")))]
4570 "TARGET_FPU && TARGET_HARD_QUAD"
4572 [(set_attr "type" "fp")])
4574 (define_expand "extenddftf2"
4575 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4577 (match_operand:DF 1 "register_operand" "")))]
4578 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4579 "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
4581 (define_insn "*extenddftf2_hq"
4582 [(set (match_operand:TF 0 "register_operand" "=e")
4584 (match_operand:DF 1 "register_operand" "e")))]
4585 "TARGET_FPU && TARGET_HARD_QUAD"
4587 [(set_attr "type" "fp")])
4589 (define_insn "truncdfsf2"
4590 [(set (match_operand:SF 0 "register_operand" "=f")
4592 (match_operand:DF 1 "register_operand" "e")))]
4595 [(set_attr "type" "fp")
4596 (set_attr "fptype" "double")])
4598 (define_expand "trunctfsf2"
4599 [(set (match_operand:SF 0 "register_operand" "")
4601 (match_operand:TF 1 "general_operand" "")))]
4602 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4603 "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
4605 (define_insn "*trunctfsf2_hq"
4606 [(set (match_operand:SF 0 "register_operand" "=f")
4608 (match_operand:TF 1 "register_operand" "e")))]
4609 "TARGET_FPU && TARGET_HARD_QUAD"
4611 [(set_attr "type" "fp")])
4613 (define_expand "trunctfdf2"
4614 [(set (match_operand:DF 0 "register_operand" "")
4616 (match_operand:TF 1 "general_operand" "")))]
4617 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4618 "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
4620 (define_insn "*trunctfdf2_hq"
4621 [(set (match_operand:DF 0 "register_operand" "=e")
4623 (match_operand:TF 1 "register_operand" "e")))]
4624 "TARGET_FPU && TARGET_HARD_QUAD"
4626 [(set_attr "type" "fp")])
4628 ;; Conversion between fixed point and floating point.
4630 (define_insn "floatsisf2"
4631 [(set (match_operand:SF 0 "register_operand" "=f")
4632 (float:SF (match_operand:SI 1 "register_operand" "f")))]
4635 [(set_attr "type" "fp")
4636 (set_attr "fptype" "double")])
4638 (define_insn "floatsidf2"
4639 [(set (match_operand:DF 0 "register_operand" "=e")
4640 (float:DF (match_operand:SI 1 "register_operand" "f")))]
4643 [(set_attr "type" "fp")
4644 (set_attr "fptype" "double")])
4646 (define_expand "floatsitf2"
4647 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4648 (float:TF (match_operand:SI 1 "register_operand" "")))]
4649 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4650 "emit_tfmode_cvt (FLOAT, operands); DONE;")
4652 (define_insn "*floatsitf2_hq"
4653 [(set (match_operand:TF 0 "register_operand" "=e")
4654 (float:TF (match_operand:SI 1 "register_operand" "f")))]
4655 "TARGET_FPU && TARGET_HARD_QUAD"
4657 [(set_attr "type" "fp")])
4659 (define_expand "floatunssitf2"
4660 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4661 (unsigned_float:TF (match_operand:SI 1 "register_operand" "")))]
4662 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4663 "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
4665 ;; Now the same for 64 bit sources.
4667 (define_insn "floatdisf2"
4668 [(set (match_operand:SF 0 "register_operand" "=f")
4669 (float:SF (match_operand:DI 1 "register_operand" "e")))]
4670 "TARGET_V9 && TARGET_FPU"
4672 [(set_attr "type" "fp")
4673 (set_attr "fptype" "double")])
4675 (define_expand "floatunsdisf2"
4676 [(use (match_operand:SF 0 "register_operand" ""))
4677 (use (match_operand:DI 1 "general_operand" ""))]
4678 "TARGET_ARCH64 && TARGET_FPU"
4679 "sparc_emit_floatunsdi (operands, SFmode); DONE;")
4681 (define_insn "floatdidf2"
4682 [(set (match_operand:DF 0 "register_operand" "=e")
4683 (float:DF (match_operand:DI 1 "register_operand" "e")))]
4684 "TARGET_V9 && TARGET_FPU"
4686 [(set_attr "type" "fp")
4687 (set_attr "fptype" "double")])
4689 (define_expand "floatunsdidf2"
4690 [(use (match_operand:DF 0 "register_operand" ""))
4691 (use (match_operand:DI 1 "general_operand" ""))]
4692 "TARGET_ARCH64 && TARGET_FPU"
4693 "sparc_emit_floatunsdi (operands, DFmode); DONE;")
4695 (define_expand "floatditf2"
4696 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4697 (float:TF (match_operand:DI 1 "register_operand" "")))]
4698 "TARGET_FPU && TARGET_V9 && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4699 "emit_tfmode_cvt (FLOAT, operands); DONE;")
4701 (define_insn "*floatditf2_hq"
4702 [(set (match_operand:TF 0 "register_operand" "=e")
4703 (float:TF (match_operand:DI 1 "register_operand" "e")))]
4704 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
4706 [(set_attr "type" "fp")])
4708 (define_expand "floatunsditf2"
4709 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4710 (unsigned_float:TF (match_operand:DI 1 "register_operand" "")))]
4711 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4712 "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
4714 ;; Convert a float to an actual integer.
4715 ;; Truncation is performed as part of the conversion.
4717 (define_insn "fix_truncsfsi2"
4718 [(set (match_operand:SI 0 "register_operand" "=f")
4719 (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
4722 [(set_attr "type" "fp")
4723 (set_attr "fptype" "double")])
4725 (define_insn "fix_truncdfsi2"
4726 [(set (match_operand:SI 0 "register_operand" "=f")
4727 (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
4730 [(set_attr "type" "fp")
4731 (set_attr "fptype" "double")])
4733 (define_expand "fix_trunctfsi2"
4734 [(set (match_operand:SI 0 "register_operand" "")
4735 (fix:SI (match_operand:TF 1 "general_operand" "")))]
4736 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4737 "emit_tfmode_cvt (FIX, operands); DONE;")
4739 (define_insn "*fix_trunctfsi2_hq"
4740 [(set (match_operand:SI 0 "register_operand" "=f")
4741 (fix:SI (match_operand:TF 1 "register_operand" "e")))]
4742 "TARGET_FPU && TARGET_HARD_QUAD"
4744 [(set_attr "type" "fp")])
4746 (define_expand "fixuns_trunctfsi2"
4747 [(set (match_operand:SI 0 "register_operand" "")
4748 (unsigned_fix:SI (match_operand:TF 1 "general_operand" "")))]
4749 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4750 "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
4752 ;; Now the same, for V9 targets
4754 (define_insn "fix_truncsfdi2"
4755 [(set (match_operand:DI 0 "register_operand" "=e")
4756 (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
4757 "TARGET_V9 && TARGET_FPU"
4759 [(set_attr "type" "fp")
4760 (set_attr "fptype" "double")])
4762 (define_expand "fixuns_truncsfdi2"
4763 [(use (match_operand:DI 0 "register_operand" ""))
4764 (use (match_operand:SF 1 "general_operand" ""))]
4765 "TARGET_ARCH64 && TARGET_FPU"
4766 "sparc_emit_fixunsdi (operands, SFmode); DONE;")
4768 (define_insn "fix_truncdfdi2"
4769 [(set (match_operand:DI 0 "register_operand" "=e")
4770 (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
4771 "TARGET_V9 && TARGET_FPU"
4773 [(set_attr "type" "fp")
4774 (set_attr "fptype" "double")])
4776 (define_expand "fixuns_truncdfdi2"
4777 [(use (match_operand:DI 0 "register_operand" ""))
4778 (use (match_operand:DF 1 "general_operand" ""))]
4779 "TARGET_ARCH64 && TARGET_FPU"
4780 "sparc_emit_fixunsdi (operands, DFmode); DONE;")
4782 (define_expand "fix_trunctfdi2"
4783 [(set (match_operand:DI 0 "register_operand" "")
4784 (fix:DI (match_operand:TF 1 "general_operand" "")))]
4785 "TARGET_V9 && TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4786 "emit_tfmode_cvt (FIX, operands); DONE;")
4788 (define_insn "*fix_trunctfdi2_hq"
4789 [(set (match_operand:DI 0 "register_operand" "=e")
4790 (fix:DI (match_operand:TF 1 "register_operand" "e")))]
4791 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
4793 [(set_attr "type" "fp")])
4795 (define_expand "fixuns_trunctfdi2"
4796 [(set (match_operand:DI 0 "register_operand" "")
4797 (unsigned_fix:DI (match_operand:TF 1 "general_operand" "")))]
4798 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4799 "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
4801 ;;- arithmetic instructions
4803 (define_expand "adddi3"
4804 [(set (match_operand:DI 0 "register_operand" "")
4805 (plus:DI (match_operand:DI 1 "register_operand" "")
4806 (match_operand:DI 2 "arith_double_add_operand" "")))]
4809 if (! TARGET_ARCH64)
4811 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
4812 gen_rtx_SET (VOIDmode, operands[0],
4813 gen_rtx_PLUS (DImode, operands[1],
4815 gen_rtx_CLOBBER (VOIDmode,
4816 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
4821 (define_insn_and_split "adddi3_insn_sp32"
4822 [(set (match_operand:DI 0 "register_operand" "=r")
4823 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
4824 (match_operand:DI 2 "arith_double_operand" "rHI")))
4825 (clobber (reg:CC 100))]
4828 "&& reload_completed"
4829 [(parallel [(set (reg:CC_NOOV 100)
4830 (compare:CC_NOOV (plus:SI (match_dup 4)
4834 (plus:SI (match_dup 4) (match_dup 5)))])
4836 (plus:SI (plus:SI (match_dup 7)
4838 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4840 operands[3] = gen_lowpart (SImode, operands[0]);
4841 operands[4] = gen_lowpart (SImode, operands[1]);
4842 operands[5] = gen_lowpart (SImode, operands[2]);
4843 operands[6] = gen_highpart (SImode, operands[0]);
4844 operands[7] = gen_highpart_mode (SImode, DImode, operands[1]);
4845 #if HOST_BITS_PER_WIDE_INT == 32
4846 if (GET_CODE (operands[2]) == CONST_INT)
4848 if (INTVAL (operands[2]) < 0)
4849 operands[8] = constm1_rtx;
4851 operands[8] = const0_rtx;
4855 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
4857 [(set_attr "length" "2")])
4860 [(set (match_operand:DI 0 "register_operand" "")
4861 (minus:DI (match_operand:DI 1 "arith_double_operand" "")
4862 (match_operand:DI 2 "arith_double_operand" "")))
4863 (clobber (reg:CC 100))]
4864 "! TARGET_ARCH64 && reload_completed"
4865 [(parallel [(set (reg:CC_NOOV 100)
4866 (compare:CC_NOOV (minus:SI (match_dup 4)
4870 (minus:SI (match_dup 4) (match_dup 5)))])
4872 (minus:SI (minus:SI (match_dup 7)
4874 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4876 operands[3] = gen_lowpart (SImode, operands[0]);
4877 operands[4] = gen_lowpart (SImode, operands[1]);
4878 operands[5] = gen_lowpart (SImode, operands[2]);
4879 operands[6] = gen_highpart (SImode, operands[0]);
4880 operands[7] = gen_highpart (SImode, operands[1]);
4881 #if HOST_BITS_PER_WIDE_INT == 32
4882 if (GET_CODE (operands[2]) == CONST_INT)
4884 if (INTVAL (operands[2]) < 0)
4885 operands[8] = constm1_rtx;
4887 operands[8] = const0_rtx;
4891 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
4894 ;; LTU here means "carry set"
4896 [(set (match_operand:SI 0 "register_operand" "=r")
4897 (plus:SI (plus:SI (match_operand:SI 1 "arith_operand" "%r")
4898 (match_operand:SI 2 "arith_operand" "rI"))
4899 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4902 [(set_attr "type" "ialuX")])
4904 (define_insn_and_split "*addx_extend_sp32"
4905 [(set (match_operand:DI 0 "register_operand" "=r")
4906 (zero_extend:DI (plus:SI (plus:SI
4907 (match_operand:SI 1 "reg_or_0_operand" "%rJ")
4908 (match_operand:SI 2 "arith_operand" "rI"))
4909 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4912 "&& reload_completed"
4913 [(set (match_dup 3) (plus:SI (plus:SI (match_dup 1) (match_dup 2))
4914 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
4915 (set (match_dup 4) (const_int 0))]
4916 "operands[3] = gen_lowpart (SImode, operands[0]);
4917 operands[4] = gen_highpart_mode (SImode, DImode, operands[1]);"
4918 [(set_attr "length" "2")])
4920 (define_insn "*addx_extend_sp64"
4921 [(set (match_operand:DI 0 "register_operand" "=r")
4922 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
4923 (match_operand:SI 2 "arith_operand" "rI"))
4924 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4927 [(set_attr "type" "ialuX")])
4930 [(set (match_operand:SI 0 "register_operand" "=r")
4931 (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
4932 (match_operand:SI 2 "arith_operand" "rI"))
4933 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4936 [(set_attr "type" "ialuX")])
4938 (define_insn "*subx_extend_sp64"
4939 [(set (match_operand:DI 0 "register_operand" "=r")
4940 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
4941 (match_operand:SI 2 "arith_operand" "rI"))
4942 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4945 [(set_attr "type" "ialuX")])
4947 (define_insn_and_split "*subx_extend"
4948 [(set (match_operand:DI 0 "register_operand" "=r")
4949 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
4950 (match_operand:SI 2 "arith_operand" "rI"))
4951 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4954 "&& reload_completed"
4955 [(set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 2))
4956 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
4957 (set (match_dup 4) (const_int 0))]
4958 "operands[3] = gen_lowpart (SImode, operands[0]);
4959 operands[4] = gen_highpart (SImode, operands[0]);"
4960 [(set_attr "length" "2")])
4962 (define_insn_and_split ""
4963 [(set (match_operand:DI 0 "register_operand" "=r")
4964 (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4965 (match_operand:DI 2 "register_operand" "r")))
4966 (clobber (reg:CC 100))]
4969 "&& reload_completed"
4970 [(parallel [(set (reg:CC_NOOV 100)
4971 (compare:CC_NOOV (plus:SI (match_dup 3) (match_dup 1))
4973 (set (match_dup 5) (plus:SI (match_dup 3) (match_dup 1)))])
4975 (plus:SI (plus:SI (match_dup 4) (const_int 0))
4976 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4977 "operands[3] = gen_lowpart (SImode, operands[2]);
4978 operands[4] = gen_highpart (SImode, operands[2]);
4979 operands[5] = gen_lowpart (SImode, operands[0]);
4980 operands[6] = gen_highpart (SImode, operands[0]);"
4981 [(set_attr "length" "2")])
4983 (define_insn "*adddi3_sp64"
4984 [(set (match_operand:DI 0 "register_operand" "=r,r")
4985 (plus:DI (match_operand:DI 1 "register_operand" "%r,r")
4986 (match_operand:DI 2 "arith_double_add_operand" "rHI,O")))]
4992 (define_insn "addsi3"
4993 [(set (match_operand:SI 0 "register_operand" "=r,r,d")
4994 (plus:SI (match_operand:SI 1 "register_operand" "%r,r,d")
4995 (match_operand:SI 2 "arith_add_operand" "rI,O,d")))]
5000 fpadd32s\t%1, %2, %0"
5001 [(set_attr "type" "*,*,fga")])
5003 (define_insn "*cmp_cc_plus"
5004 [(set (reg:CC_NOOV 100)
5005 (compare:CC_NOOV (plus:SI (match_operand:SI 0 "arith_operand" "%r")
5006 (match_operand:SI 1 "arith_operand" "rI"))
5009 "addcc\t%0, %1, %%g0"
5010 [(set_attr "type" "compare")])
5012 (define_insn "*cmp_ccx_plus"
5013 [(set (reg:CCX_NOOV 100)
5014 (compare:CCX_NOOV (plus:DI (match_operand:DI 0 "arith_double_operand" "%r")
5015 (match_operand:DI 1 "arith_double_operand" "rHI"))
5018 "addcc\t%0, %1, %%g0"
5019 [(set_attr "type" "compare")])
5021 (define_insn "*cmp_cc_plus_set"
5022 [(set (reg:CC_NOOV 100)
5023 (compare:CC_NOOV (plus:SI (match_operand:SI 1 "arith_operand" "%r")
5024 (match_operand:SI 2 "arith_operand" "rI"))
5026 (set (match_operand:SI 0 "register_operand" "=r")
5027 (plus:SI (match_dup 1) (match_dup 2)))]
5030 [(set_attr "type" "compare")])
5032 (define_insn "*cmp_ccx_plus_set"
5033 [(set (reg:CCX_NOOV 100)
5034 (compare:CCX_NOOV (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
5035 (match_operand:DI 2 "arith_double_operand" "rHI"))
5037 (set (match_operand:DI 0 "register_operand" "=r")
5038 (plus:DI (match_dup 1) (match_dup 2)))]
5041 [(set_attr "type" "compare")])
5043 (define_expand "subdi3"
5044 [(set (match_operand:DI 0 "register_operand" "")
5045 (minus:DI (match_operand:DI 1 "register_operand" "")
5046 (match_operand:DI 2 "arith_double_add_operand" "")))]
5049 if (! TARGET_ARCH64)
5051 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
5052 gen_rtx_SET (VOIDmode, operands[0],
5053 gen_rtx_MINUS (DImode, operands[1],
5055 gen_rtx_CLOBBER (VOIDmode,
5056 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
5061 (define_insn_and_split "*subdi3_sp32"
5062 [(set (match_operand:DI 0 "register_operand" "=r")
5063 (minus:DI (match_operand:DI 1 "register_operand" "r")
5064 (match_operand:DI 2 "arith_double_operand" "rHI")))
5065 (clobber (reg:CC 100))]
5068 "&& reload_completed
5069 && (GET_CODE (operands[2]) == CONST_INT
5070 || GET_CODE (operands[2]) == CONST_DOUBLE)"
5071 [(clobber (const_int 0))]
5075 highp = gen_highpart_mode (SImode, DImode, operands[2]);
5076 lowp = gen_lowpart (SImode, operands[2]);
5077 if ((lowp == const0_rtx)
5078 && (operands[0] == operands[1]))
5080 emit_insn (gen_rtx_SET (VOIDmode,
5081 gen_highpart (SImode, operands[0]),
5082 gen_rtx_MINUS (SImode,
5083 gen_highpart_mode (SImode, DImode,
5089 emit_insn (gen_cmp_minus_cc_set (gen_lowpart (SImode, operands[0]),
5090 gen_lowpart (SImode, operands[1]),
5092 emit_insn (gen_subx (gen_highpart (SImode, operands[0]),
5093 gen_highpart_mode (SImode, DImode, operands[1]),
5098 [(set_attr "length" "2")])
5101 [(set (match_operand:DI 0 "register_operand" "")
5102 (minus:DI (match_operand:DI 1 "register_operand" "")
5103 (match_operand:DI 2 "register_operand" "")))
5104 (clobber (reg:CC 100))]
5106 && reload_completed"
5107 [(clobber (const_int 0))]
5109 emit_insn (gen_cmp_minus_cc_set (gen_lowpart (SImode, operands[0]),
5110 gen_lowpart (SImode, operands[1]),
5111 gen_lowpart (SImode, operands[2])));
5112 emit_insn (gen_subx (gen_highpart (SImode, operands[0]),
5113 gen_highpart (SImode, operands[1]),
5114 gen_highpart (SImode, operands[2])));
5118 (define_insn_and_split ""
5119 [(set (match_operand:DI 0 "register_operand" "=r")
5120 (minus:DI (match_operand:DI 1 "register_operand" "r")
5121 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))
5122 (clobber (reg:CC 100))]
5125 "&& reload_completed"
5126 [(parallel [(set (reg:CC_NOOV 100)
5127 (compare:CC_NOOV (minus:SI (match_dup 3) (match_dup 2))
5129 (set (match_dup 5) (minus:SI (match_dup 3) (match_dup 2)))])
5131 (minus:SI (minus:SI (match_dup 4) (const_int 0))
5132 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5133 "operands[3] = gen_lowpart (SImode, operands[1]);
5134 operands[4] = gen_highpart (SImode, operands[1]);
5135 operands[5] = gen_lowpart (SImode, operands[0]);
5136 operands[6] = gen_highpart (SImode, operands[0]);"
5137 [(set_attr "length" "2")])
5139 (define_insn "*subdi3_sp64"
5140 [(set (match_operand:DI 0 "register_operand" "=r,r")
5141 (minus:DI (match_operand:DI 1 "register_operand" "r,r")
5142 (match_operand:DI 2 "arith_double_add_operand" "rHI,O")))]
5148 (define_insn "subsi3"
5149 [(set (match_operand:SI 0 "register_operand" "=r,r,d")
5150 (minus:SI (match_operand:SI 1 "register_operand" "r,r,d")
5151 (match_operand:SI 2 "arith_add_operand" "rI,O,d")))]
5156 fpsub32s\t%1, %2, %0"
5157 [(set_attr "type" "*,*,fga")])
5159 (define_insn "*cmp_minus_cc"
5160 [(set (reg:CC_NOOV 100)
5161 (compare:CC_NOOV (minus:SI (match_operand:SI 0 "reg_or_0_operand" "rJ")
5162 (match_operand:SI 1 "arith_operand" "rI"))
5165 "subcc\t%r0, %1, %%g0"
5166 [(set_attr "type" "compare")])
5168 (define_insn "*cmp_minus_ccx"
5169 [(set (reg:CCX_NOOV 100)
5170 (compare:CCX_NOOV (minus:DI (match_operand:DI 0 "register_operand" "r")
5171 (match_operand:DI 1 "arith_double_operand" "rHI"))
5174 "subcc\t%0, %1, %%g0"
5175 [(set_attr "type" "compare")])
5177 (define_insn "cmp_minus_cc_set"
5178 [(set (reg:CC_NOOV 100)
5179 (compare:CC_NOOV (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5180 (match_operand:SI 2 "arith_operand" "rI"))
5182 (set (match_operand:SI 0 "register_operand" "=r")
5183 (minus:SI (match_dup 1) (match_dup 2)))]
5185 "subcc\t%r1, %2, %0"
5186 [(set_attr "type" "compare")])
5188 (define_insn "*cmp_minus_ccx_set"
5189 [(set (reg:CCX_NOOV 100)
5190 (compare:CCX_NOOV (minus:DI (match_operand:DI 1 "register_operand" "r")
5191 (match_operand:DI 2 "arith_double_operand" "rHI"))
5193 (set (match_operand:DI 0 "register_operand" "=r")
5194 (minus:DI (match_dup 1) (match_dup 2)))]
5197 [(set_attr "type" "compare")])
5199 ;; Integer Multiply/Divide.
5201 ;; The 32 bit multiply/divide instructions are deprecated on v9, but at
5202 ;; least in UltraSPARC I, II and IIi it is a win tick-wise.
5204 (define_insn "mulsi3"
5205 [(set (match_operand:SI 0 "register_operand" "=r")
5206 (mult:SI (match_operand:SI 1 "arith_operand" "%r")
5207 (match_operand:SI 2 "arith_operand" "rI")))]
5210 [(set_attr "type" "imul")])
5212 (define_expand "muldi3"
5213 [(set (match_operand:DI 0 "register_operand" "=r")
5214 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r")
5215 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5216 "TARGET_ARCH64 || TARGET_V8PLUS"
5220 emit_insn (gen_muldi3_v8plus (operands[0], operands[1], operands[2]));
5225 (define_insn "*muldi3_sp64"
5226 [(set (match_operand:DI 0 "register_operand" "=r")
5227 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r")
5228 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5231 [(set_attr "type" "imul")])
5233 ;; V8plus wide multiply.
5235 (define_insn "muldi3_v8plus"
5236 [(set (match_operand:DI 0 "register_operand" "=r,h")
5237 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r,0")
5238 (match_operand:DI 2 "arith_double_operand" "rI,rI")))
5239 (clobber (match_scratch:SI 3 "=&h,X"))
5240 (clobber (match_scratch:SI 4 "=&h,X"))]
5243 if (sparc_check_64 (operands[1], insn) <= 0)
5244 output_asm_insn ("srl\t%L1, 0, %L1", operands);
5245 if (which_alternative == 1)
5246 output_asm_insn ("sllx\t%H1, 32, %H1", operands);
5247 if (GET_CODE (operands[2]) == CONST_INT)
5249 if (which_alternative == 1)
5250 return "or\t%L1, %H1, %H1\n\tmulx\t%H1, %2, %L0\;srlx\t%L0, 32, %H0";
5252 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";
5254 else if (rtx_equal_p (operands[1], operands[2]))
5256 if (which_alternative == 1)
5257 return "or\t%L1, %H1, %H1\n\tmulx\t%H1, %H1, %L0\;srlx\t%L0, 32, %H0";
5259 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";
5261 if (sparc_check_64 (operands[2], insn) <= 0)
5262 output_asm_insn ("srl\t%L2, 0, %L2", operands);
5263 if (which_alternative == 1)
5264 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";
5266 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";
5268 [(set_attr "type" "multi")
5269 (set_attr "length" "9,8")])
5271 (define_insn "*cmp_mul_set"
5273 (compare:CC (mult:SI (match_operand:SI 1 "arith_operand" "%r")
5274 (match_operand:SI 2 "arith_operand" "rI"))
5276 (set (match_operand:SI 0 "register_operand" "=r")
5277 (mult:SI (match_dup 1) (match_dup 2)))]
5278 "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS"
5279 "smulcc\t%1, %2, %0"
5280 [(set_attr "type" "imul")])
5282 (define_expand "mulsidi3"
5283 [(set (match_operand:DI 0 "register_operand" "")
5284 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
5285 (sign_extend:DI (match_operand:SI 2 "arith_operand" ""))))]
5288 if (CONSTANT_P (operands[2]))
5291 emit_insn (gen_const_mulsidi3_v8plus (operands[0], operands[1],
5293 else if (TARGET_ARCH32)
5294 emit_insn (gen_const_mulsidi3_sp32 (operands[0], operands[1],
5297 emit_insn (gen_const_mulsidi3_sp64 (operands[0], operands[1],
5303 emit_insn (gen_mulsidi3_v8plus (operands[0], operands[1], operands[2]));
5308 ;; V9 puts the 64 bit product in a 64 bit register. Only out or global
5309 ;; registers can hold 64 bit values in the V8plus environment.
5311 (define_insn "mulsidi3_v8plus"
5312 [(set (match_operand:DI 0 "register_operand" "=h,r")
5313 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5314 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
5315 (clobber (match_scratch:SI 3 "=X,&h"))]
5318 smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
5319 smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
5320 [(set_attr "type" "multi")
5321 (set_attr "length" "2,3")])
5324 (define_insn "const_mulsidi3_v8plus"
5325 [(set (match_operand:DI 0 "register_operand" "=h,r")
5326 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5327 (match_operand:DI 2 "small_int" "I,I")))
5328 (clobber (match_scratch:SI 3 "=X,&h"))]
5331 smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
5332 smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
5333 [(set_attr "type" "multi")
5334 (set_attr "length" "2,3")])
5337 (define_insn "*mulsidi3_sp32"
5338 [(set (match_operand:DI 0 "register_operand" "=r")
5339 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5340 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
5343 return TARGET_SPARCLET
5344 ? "smuld\t%1, %2, %L0"
5345 : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
5348 (if_then_else (eq_attr "isa" "sparclet")
5349 (const_string "imul") (const_string "multi")))
5350 (set (attr "length")
5351 (if_then_else (eq_attr "isa" "sparclet")
5352 (const_int 1) (const_int 2)))])
5354 (define_insn "*mulsidi3_sp64"
5355 [(set (match_operand:DI 0 "register_operand" "=r")
5356 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5357 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
5358 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5360 [(set_attr "type" "imul")])
5362 ;; Extra pattern, because sign_extend of a constant isn't valid.
5365 (define_insn "const_mulsidi3_sp32"
5366 [(set (match_operand:DI 0 "register_operand" "=r")
5367 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5368 (match_operand:DI 2 "small_int" "I")))]
5371 return TARGET_SPARCLET
5372 ? "smuld\t%1, %2, %L0"
5373 : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
5376 (if_then_else (eq_attr "isa" "sparclet")
5377 (const_string "imul") (const_string "multi")))
5378 (set (attr "length")
5379 (if_then_else (eq_attr "isa" "sparclet")
5380 (const_int 1) (const_int 2)))])
5382 (define_insn "const_mulsidi3_sp64"
5383 [(set (match_operand:DI 0 "register_operand" "=r")
5384 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5385 (match_operand:DI 2 "small_int" "I")))]
5386 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5388 [(set_attr "type" "imul")])
5390 (define_expand "smulsi3_highpart"
5391 [(set (match_operand:SI 0 "register_operand" "")
5393 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
5394 (sign_extend:DI (match_operand:SI 2 "arith_operand" "")))
5396 "TARGET_HARD_MUL && TARGET_ARCH32"
5398 if (CONSTANT_P (operands[2]))
5402 emit_insn (gen_const_smulsi3_highpart_v8plus (operands[0],
5408 emit_insn (gen_const_smulsi3_highpart (operands[0], operands[1], operands[2]));
5413 emit_insn (gen_smulsi3_highpart_v8plus (operands[0], operands[1],
5414 operands[2], GEN_INT (32)));
5420 (define_insn "smulsi3_highpart_v8plus"
5421 [(set (match_operand:SI 0 "register_operand" "=h,r")
5423 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5424 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
5425 (match_operand:SI 3 "const_int_operand" "i,i"))))
5426 (clobber (match_scratch:SI 4 "=X,&h"))]
5429 smul\t%1, %2, %0\;srlx\t%0, %3, %0
5430 smul\t%1, %2, %4\;srlx\t%4, %3, %0"
5431 [(set_attr "type" "multi")
5432 (set_attr "length" "2")])
5434 ;; The combiner changes TRUNCATE in the previous pattern to SUBREG.
5437 [(set (match_operand:SI 0 "register_operand" "=h,r")
5440 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5441 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
5442 (match_operand:SI 3 "const_int_operand" "i,i"))
5444 (clobber (match_scratch:SI 4 "=X,&h"))]
5447 smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
5448 smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
5449 [(set_attr "type" "multi")
5450 (set_attr "length" "2")])
5453 (define_insn "const_smulsi3_highpart_v8plus"
5454 [(set (match_operand:SI 0 "register_operand" "=h,r")
5456 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5457 (match_operand:DI 2 "small_int" "i,i"))
5458 (match_operand:SI 3 "const_int_operand" "i,i"))))
5459 (clobber (match_scratch:SI 4 "=X,&h"))]
5462 smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
5463 smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
5464 [(set_attr "type" "multi")
5465 (set_attr "length" "2")])
5468 (define_insn "*smulsi3_highpart_sp32"
5469 [(set (match_operand:SI 0 "register_operand" "=r")
5471 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5472 (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
5475 "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
5476 [(set_attr "type" "multi")
5477 (set_attr "length" "2")])
5480 (define_insn "const_smulsi3_highpart"
5481 [(set (match_operand:SI 0 "register_operand" "=r")
5483 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5484 (match_operand:DI 2 "small_int" "i"))
5487 "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
5488 [(set_attr "type" "multi")
5489 (set_attr "length" "2")])
5491 (define_expand "umulsidi3"
5492 [(set (match_operand:DI 0 "register_operand" "")
5493 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
5494 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" ""))))]
5497 if (CONSTANT_P (operands[2]))
5500 emit_insn (gen_const_umulsidi3_v8plus (operands[0], operands[1],
5502 else if (TARGET_ARCH32)
5503 emit_insn (gen_const_umulsidi3_sp32 (operands[0], operands[1],
5506 emit_insn (gen_const_umulsidi3_sp64 (operands[0], operands[1],
5512 emit_insn (gen_umulsidi3_v8plus (operands[0], operands[1], operands[2]));
5518 (define_insn "umulsidi3_v8plus"
5519 [(set (match_operand:DI 0 "register_operand" "=h,r")
5520 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5521 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
5522 (clobber (match_scratch:SI 3 "=X,&h"))]
5525 umul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
5526 umul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
5527 [(set_attr "type" "multi")
5528 (set_attr "length" "2,3")])
5531 (define_insn "*umulsidi3_sp32"
5532 [(set (match_operand:DI 0 "register_operand" "=r")
5533 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5534 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
5537 return TARGET_SPARCLET
5538 ? "umuld\t%1, %2, %L0"
5539 : "umul\t%1, %2, %L0\n\trd\t%%y, %H0";
5542 (if_then_else (eq_attr "isa" "sparclet")
5543 (const_string "imul") (const_string "multi")))
5544 (set (attr "length")
5545 (if_then_else (eq_attr "isa" "sparclet")
5546 (const_int 1) (const_int 2)))])
5548 (define_insn "*umulsidi3_sp64"
5549 [(set (match_operand:DI 0 "register_operand" "=r")
5550 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5551 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
5552 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5554 [(set_attr "type" "imul")])
5556 ;; Extra pattern, because sign_extend of a constant isn't valid.
5559 (define_insn "const_umulsidi3_sp32"
5560 [(set (match_operand:DI 0 "register_operand" "=r")
5561 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5562 (match_operand:DI 2 "uns_small_int" "")))]
5565 return TARGET_SPARCLET
5566 ? "umuld\t%1, %s2, %L0"
5567 : "umul\t%1, %s2, %L0\n\trd\t%%y, %H0";
5570 (if_then_else (eq_attr "isa" "sparclet")
5571 (const_string "imul") (const_string "multi")))
5572 (set (attr "length")
5573 (if_then_else (eq_attr "isa" "sparclet")
5574 (const_int 1) (const_int 2)))])
5576 (define_insn "const_umulsidi3_sp64"
5577 [(set (match_operand:DI 0 "register_operand" "=r")
5578 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5579 (match_operand:DI 2 "uns_small_int" "")))]
5580 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5582 [(set_attr "type" "imul")])
5585 (define_insn "const_umulsidi3_v8plus"
5586 [(set (match_operand:DI 0 "register_operand" "=h,r")
5587 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5588 (match_operand:DI 2 "uns_small_int" "")))
5589 (clobber (match_scratch:SI 3 "=X,h"))]
5592 umul\t%1, %s2, %L0\n\tsrlx\t%L0, 32, %H0
5593 umul\t%1, %s2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
5594 [(set_attr "type" "multi")
5595 (set_attr "length" "2,3")])
5597 (define_expand "umulsi3_highpart"
5598 [(set (match_operand:SI 0 "register_operand" "")
5600 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
5601 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" "")))
5603 "TARGET_HARD_MUL && TARGET_ARCH32"
5605 if (CONSTANT_P (operands[2]))
5609 emit_insn (gen_const_umulsi3_highpart_v8plus (operands[0],
5615 emit_insn (gen_const_umulsi3_highpart (operands[0], operands[1], operands[2]));
5620 emit_insn (gen_umulsi3_highpart_v8plus (operands[0], operands[1],
5621 operands[2], GEN_INT (32)));
5627 (define_insn "umulsi3_highpart_v8plus"
5628 [(set (match_operand:SI 0 "register_operand" "=h,r")
5630 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5631 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
5632 (match_operand:SI 3 "const_int_operand" "i,i"))))
5633 (clobber (match_scratch:SI 4 "=X,h"))]
5636 umul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
5637 umul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
5638 [(set_attr "type" "multi")
5639 (set_attr "length" "2")])
5642 (define_insn "const_umulsi3_highpart_v8plus"
5643 [(set (match_operand:SI 0 "register_operand" "=h,r")
5645 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5646 (match_operand:DI 2 "uns_small_int" ""))
5647 (match_operand:SI 3 "const_int_operand" "i,i"))))
5648 (clobber (match_scratch:SI 4 "=X,h"))]
5651 umul\t%1, %s2, %0\n\tsrlx\t%0, %3, %0
5652 umul\t%1, %s2, %4\n\tsrlx\t%4, %3, %0"
5653 [(set_attr "type" "multi")
5654 (set_attr "length" "2")])
5657 (define_insn "*umulsi3_highpart_sp32"
5658 [(set (match_operand:SI 0 "register_operand" "=r")
5660 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5661 (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
5664 "umul\t%1, %2, %%g0\n\trd\t%%y, %0"
5665 [(set_attr "type" "multi")
5666 (set_attr "length" "2")])
5669 (define_insn "const_umulsi3_highpart"
5670 [(set (match_operand:SI 0 "register_operand" "=r")
5672 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5673 (match_operand:DI 2 "uns_small_int" ""))
5676 "umul\t%1, %s2, %%g0\n\trd\t%%y, %0"
5677 [(set_attr "type" "multi")
5678 (set_attr "length" "2")])
5680 ;; The v8 architecture specifies that there must be 3 instructions between
5681 ;; a y register write and a use of it for correct results.
5683 (define_expand "divsi3"
5684 [(parallel [(set (match_operand:SI 0 "register_operand" "=r,r")
5685 (div:SI (match_operand:SI 1 "register_operand" "r,r")
5686 (match_operand:SI 2 "input_operand" "rI,m")))
5687 (clobber (match_scratch:SI 3 "=&r,&r"))])]
5688 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
5692 operands[3] = gen_reg_rtx(SImode);
5693 emit_insn (gen_ashrsi3 (operands[3], operands[1], GEN_INT (31)));
5694 emit_insn (gen_divsi3_sp64 (operands[0], operands[1], operands[2],
5700 (define_insn "divsi3_sp32"
5701 [(set (match_operand:SI 0 "register_operand" "=r,r")
5702 (div:SI (match_operand:SI 1 "register_operand" "r,r")
5703 (match_operand:SI 2 "input_operand" "rI,m")))
5704 (clobber (match_scratch:SI 3 "=&r,&r"))]
5705 "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS)
5708 if (which_alternative == 0)
5710 return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tsdiv\t%1, %2, %0";
5712 return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tnop\n\tnop\n\tnop\n\tsdiv\t%1, %2, %0";
5715 return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tld\t%2, %3\n\tsdiv\t%1, %3, %0";
5717 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";
5719 [(set_attr "type" "multi")
5720 (set (attr "length")
5721 (if_then_else (eq_attr "isa" "v9")
5722 (const_int 4) (const_int 6)))])
5724 (define_insn "divsi3_sp64"
5725 [(set (match_operand:SI 0 "register_operand" "=r")
5726 (div:SI (match_operand:SI 1 "register_operand" "r")
5727 (match_operand:SI 2 "input_operand" "rI")))
5728 (use (match_operand:SI 3 "register_operand" "r"))]
5729 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5730 "wr\t%%g0, %3, %%y\n\tsdiv\t%1, %2, %0"
5731 [(set_attr "type" "multi")
5732 (set_attr "length" "2")])
5734 (define_insn "divdi3"
5735 [(set (match_operand:DI 0 "register_operand" "=r")
5736 (div:DI (match_operand:DI 1 "register_operand" "r")
5737 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5740 [(set_attr "type" "idiv")])
5742 (define_insn "*cmp_sdiv_cc_set"
5744 (compare:CC (div:SI (match_operand:SI 1 "register_operand" "r")
5745 (match_operand:SI 2 "arith_operand" "rI"))
5747 (set (match_operand:SI 0 "register_operand" "=r")
5748 (div:SI (match_dup 1) (match_dup 2)))
5749 (clobber (match_scratch:SI 3 "=&r"))]
5750 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
5753 return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tsdivcc\t%1, %2, %0";
5755 return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tnop\n\tnop\n\tnop\n\tsdivcc\t%1, %2, %0";
5757 [(set_attr "type" "multi")
5758 (set (attr "length")
5759 (if_then_else (eq_attr "isa" "v9")
5760 (const_int 3) (const_int 6)))])
5763 (define_expand "udivsi3"
5764 [(set (match_operand:SI 0 "register_operand" "")
5765 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "")
5766 (match_operand:SI 2 "input_operand" "")))]
5767 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
5770 (define_insn "udivsi3_sp32"
5771 [(set (match_operand:SI 0 "register_operand" "=r,&r,&r")
5772 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "r,r,m")
5773 (match_operand:SI 2 "input_operand" "rI,m,r")))]
5775 || TARGET_DEPRECATED_V8_INSNS)
5778 output_asm_insn ("wr\t%%g0, %%g0, %%y", operands);
5779 switch (which_alternative)
5782 return "nop\n\tnop\n\tnop\n\tudiv\t%1, %2, %0";
5784 return "ld\t%2, %0\n\tnop\n\tnop\n\tudiv\t%1, %0, %0";
5786 return "ld\t%1, %0\n\tnop\n\tnop\n\tudiv\t%0, %2, %0";
5789 [(set_attr "type" "multi")
5790 (set_attr "length" "5")])
5792 (define_insn "udivsi3_sp64"
5793 [(set (match_operand:SI 0 "register_operand" "=r")
5794 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "r")
5795 (match_operand:SI 2 "input_operand" "rI")))]
5796 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5797 "wr\t%%g0, 0, %%y\n\tudiv\t%1, %2, %0"
5798 [(set_attr "type" "multi")
5799 (set_attr "length" "2")])
5801 (define_insn "udivdi3"
5802 [(set (match_operand:DI 0 "register_operand" "=r")
5803 (udiv:DI (match_operand:DI 1 "register_operand" "r")
5804 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5807 [(set_attr "type" "idiv")])
5809 (define_insn "*cmp_udiv_cc_set"
5811 (compare:CC (udiv:SI (match_operand:SI 1 "register_operand" "r")
5812 (match_operand:SI 2 "arith_operand" "rI"))
5814 (set (match_operand:SI 0 "register_operand" "=r")
5815 (udiv:SI (match_dup 1) (match_dup 2)))]
5817 || TARGET_DEPRECATED_V8_INSNS"
5820 return "wr\t%%g0, %%g0, %%y\n\tudivcc\t%1, %2, %0";
5822 return "wr\t%%g0, %%g0, %%y\n\tnop\n\tnop\n\tnop\n\tudivcc\t%1, %2, %0";
5824 [(set_attr "type" "multi")
5825 (set (attr "length")
5826 (if_then_else (eq_attr "isa" "v9")
5827 (const_int 2) (const_int 5)))])
5829 ; sparclet multiply/accumulate insns
5831 (define_insn "*smacsi"
5832 [(set (match_operand:SI 0 "register_operand" "=r")
5833 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "%r")
5834 (match_operand:SI 2 "arith_operand" "rI"))
5835 (match_operand:SI 3 "register_operand" "0")))]
5838 [(set_attr "type" "imul")])
5840 (define_insn "*smacdi"
5841 [(set (match_operand:DI 0 "register_operand" "=r")
5842 (plus:DI (mult:DI (sign_extend:DI
5843 (match_operand:SI 1 "register_operand" "%r"))
5845 (match_operand:SI 2 "register_operand" "r")))
5846 (match_operand:DI 3 "register_operand" "0")))]
5848 "smacd\t%1, %2, %L0"
5849 [(set_attr "type" "imul")])
5851 (define_insn "*umacdi"
5852 [(set (match_operand:DI 0 "register_operand" "=r")
5853 (plus:DI (mult:DI (zero_extend:DI
5854 (match_operand:SI 1 "register_operand" "%r"))
5856 (match_operand:SI 2 "register_operand" "r")))
5857 (match_operand:DI 3 "register_operand" "0")))]
5859 "umacd\t%1, %2, %L0"
5860 [(set_attr "type" "imul")])
5862 ;;- Boolean instructions
5863 ;; We define DImode `and' so with DImode `not' we can get
5864 ;; DImode `andn'. Other combinations are possible.
5866 (define_expand "anddi3"
5867 [(set (match_operand:DI 0 "register_operand" "")
5868 (and:DI (match_operand:DI 1 "arith_double_operand" "")
5869 (match_operand:DI 2 "arith_double_operand" "")))]
5873 (define_insn "*anddi3_sp32"
5874 [(set (match_operand:DI 0 "register_operand" "=r,b")
5875 (and:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
5876 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
5881 [(set_attr "type" "*,fga")
5882 (set_attr "length" "2,*")
5883 (set_attr "fptype" "double")])
5885 (define_insn "*anddi3_sp64"
5886 [(set (match_operand:DI 0 "register_operand" "=r,b")
5887 (and:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
5888 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
5893 [(set_attr "type" "*,fga")
5894 (set_attr "fptype" "double")])
5896 (define_insn "andsi3"
5897 [(set (match_operand:SI 0 "register_operand" "=r,d")
5898 (and:SI (match_operand:SI 1 "arith_operand" "%r,d")
5899 (match_operand:SI 2 "arith_operand" "rI,d")))]
5904 [(set_attr "type" "*,fga")])
5907 [(set (match_operand:SI 0 "register_operand" "")
5908 (and:SI (match_operand:SI 1 "register_operand" "")
5909 (match_operand:SI 2 "" "")))
5910 (clobber (match_operand:SI 3 "register_operand" ""))]
5911 "GET_CODE (operands[2]) == CONST_INT
5912 && !SMALL_INT32 (operands[2])
5913 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
5914 [(set (match_dup 3) (match_dup 4))
5915 (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 1)))]
5917 operands[4] = GEN_INT (~INTVAL (operands[2]));
5920 ;; Split DImode logical operations requiring two instructions.
5922 [(set (match_operand:DI 0 "register_operand" "")
5923 (match_operator:DI 1 "cc_arithop" ; AND, IOR, XOR
5924 [(match_operand:DI 2 "register_operand" "")
5925 (match_operand:DI 3 "arith_double_operand" "")]))]
5928 && ((GET_CODE (operands[0]) == REG
5929 && REGNO (operands[0]) < 32)
5930 || (GET_CODE (operands[0]) == SUBREG
5931 && GET_CODE (SUBREG_REG (operands[0])) == REG
5932 && REGNO (SUBREG_REG (operands[0])) < 32))"
5933 [(set (match_dup 4) (match_op_dup:SI 1 [(match_dup 6) (match_dup 8)]))
5934 (set (match_dup 5) (match_op_dup:SI 1 [(match_dup 7) (match_dup 9)]))]
5936 operands[4] = gen_highpart (SImode, operands[0]);
5937 operands[5] = gen_lowpart (SImode, operands[0]);
5938 operands[6] = gen_highpart (SImode, operands[2]);
5939 operands[7] = gen_lowpart (SImode, operands[2]);
5940 #if HOST_BITS_PER_WIDE_INT == 32
5941 if (GET_CODE (operands[3]) == CONST_INT)
5943 if (INTVAL (operands[3]) < 0)
5944 operands[8] = constm1_rtx;
5946 operands[8] = const0_rtx;
5950 operands[8] = gen_highpart_mode (SImode, DImode, operands[3]);
5951 operands[9] = gen_lowpart (SImode, operands[3]);
5954 (define_insn_and_split "*and_not_di_sp32"
5955 [(set (match_operand:DI 0 "register_operand" "=r,b")
5956 (and:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
5957 (match_operand:DI 2 "register_operand" "r,b")))]
5961 fandnot1\t%1, %2, %0"
5962 "&& reload_completed
5963 && ((GET_CODE (operands[0]) == REG
5964 && REGNO (operands[0]) < 32)
5965 || (GET_CODE (operands[0]) == SUBREG
5966 && GET_CODE (SUBREG_REG (operands[0])) == REG
5967 && REGNO (SUBREG_REG (operands[0])) < 32))"
5968 [(set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))
5969 (set (match_dup 6) (and:SI (not:SI (match_dup 7)) (match_dup 8)))]
5970 "operands[3] = gen_highpart (SImode, operands[0]);
5971 operands[4] = gen_highpart (SImode, operands[1]);
5972 operands[5] = gen_highpart (SImode, operands[2]);
5973 operands[6] = gen_lowpart (SImode, operands[0]);
5974 operands[7] = gen_lowpart (SImode, operands[1]);
5975 operands[8] = gen_lowpart (SImode, operands[2]);"
5976 [(set_attr "type" "*,fga")
5977 (set_attr "length" "2,*")
5978 (set_attr "fptype" "double")])
5980 (define_insn "*and_not_di_sp64"
5981 [(set (match_operand:DI 0 "register_operand" "=r,b")
5982 (and:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
5983 (match_operand:DI 2 "register_operand" "r,b")))]
5987 fandnot1\t%1, %2, %0"
5988 [(set_attr "type" "*,fga")
5989 (set_attr "fptype" "double")])
5991 (define_insn "*and_not_si"
5992 [(set (match_operand:SI 0 "register_operand" "=r,d")
5993 (and:SI (not:SI (match_operand:SI 1 "register_operand" "r,d"))
5994 (match_operand:SI 2 "register_operand" "r,d")))]
5998 fandnot1s\t%1, %2, %0"
5999 [(set_attr "type" "*,fga")])
6001 (define_expand "iordi3"
6002 [(set (match_operand:DI 0 "register_operand" "")
6003 (ior:DI (match_operand:DI 1 "arith_double_operand" "")
6004 (match_operand:DI 2 "arith_double_operand" "")))]
6008 (define_insn "*iordi3_sp32"
6009 [(set (match_operand:DI 0 "register_operand" "=r,b")
6010 (ior:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6011 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6016 [(set_attr "type" "*,fga")
6017 (set_attr "length" "2,*")
6018 (set_attr "fptype" "double")])
6020 (define_insn "*iordi3_sp64"
6021 [(set (match_operand:DI 0 "register_operand" "=r,b")
6022 (ior:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6023 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6028 [(set_attr "type" "*,fga")
6029 (set_attr "fptype" "double")])
6031 (define_insn "iorsi3"
6032 [(set (match_operand:SI 0 "register_operand" "=r,d")
6033 (ior:SI (match_operand:SI 1 "arith_operand" "%r,d")
6034 (match_operand:SI 2 "arith_operand" "rI,d")))]
6039 [(set_attr "type" "*,fga")])
6042 [(set (match_operand:SI 0 "register_operand" "")
6043 (ior:SI (match_operand:SI 1 "register_operand" "")
6044 (match_operand:SI 2 "" "")))
6045 (clobber (match_operand:SI 3 "register_operand" ""))]
6046 "GET_CODE (operands[2]) == CONST_INT
6047 && !SMALL_INT32 (operands[2])
6048 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6049 [(set (match_dup 3) (match_dup 4))
6050 (set (match_dup 0) (ior:SI (not:SI (match_dup 3)) (match_dup 1)))]
6052 operands[4] = GEN_INT (~INTVAL (operands[2]));
6055 (define_insn_and_split "*or_not_di_sp32"
6056 [(set (match_operand:DI 0 "register_operand" "=r,b")
6057 (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6058 (match_operand:DI 2 "register_operand" "r,b")))]
6062 fornot1\t%1, %2, %0"
6063 "&& reload_completed
6064 && ((GET_CODE (operands[0]) == REG
6065 && REGNO (operands[0]) < 32)
6066 || (GET_CODE (operands[0]) == SUBREG
6067 && GET_CODE (SUBREG_REG (operands[0])) == REG
6068 && REGNO (SUBREG_REG (operands[0])) < 32))"
6069 [(set (match_dup 3) (ior:SI (not:SI (match_dup 4)) (match_dup 5)))
6070 (set (match_dup 6) (ior:SI (not:SI (match_dup 7)) (match_dup 8)))]
6071 "operands[3] = gen_highpart (SImode, operands[0]);
6072 operands[4] = gen_highpart (SImode, operands[1]);
6073 operands[5] = gen_highpart (SImode, operands[2]);
6074 operands[6] = gen_lowpart (SImode, operands[0]);
6075 operands[7] = gen_lowpart (SImode, operands[1]);
6076 operands[8] = gen_lowpart (SImode, operands[2]);"
6077 [(set_attr "type" "*,fga")
6078 (set_attr "length" "2,*")
6079 (set_attr "fptype" "double")])
6081 (define_insn "*or_not_di_sp64"
6082 [(set (match_operand:DI 0 "register_operand" "=r,b")
6083 (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6084 (match_operand:DI 2 "register_operand" "r,b")))]
6088 fornot1\t%1, %2, %0"
6089 [(set_attr "type" "*,fga")
6090 (set_attr "fptype" "double")])
6092 (define_insn "*or_not_si"
6093 [(set (match_operand:SI 0 "register_operand" "=r,d")
6094 (ior:SI (not:SI (match_operand:SI 1 "register_operand" "r,d"))
6095 (match_operand:SI 2 "register_operand" "r,d")))]
6099 fornot1s\t%1, %2, %0"
6100 [(set_attr "type" "*,fga")])
6102 (define_expand "xordi3"
6103 [(set (match_operand:DI 0 "register_operand" "")
6104 (xor:DI (match_operand:DI 1 "arith_double_operand" "")
6105 (match_operand:DI 2 "arith_double_operand" "")))]
6109 (define_insn "*xordi3_sp32"
6110 [(set (match_operand:DI 0 "register_operand" "=r,b")
6111 (xor:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6112 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6117 [(set_attr "type" "*,fga")
6118 (set_attr "length" "2,*")
6119 (set_attr "fptype" "double")])
6121 (define_insn "*xordi3_sp64"
6122 [(set (match_operand:DI 0 "register_operand" "=r,b")
6123 (xor:DI (match_operand:DI 1 "arith_double_operand" "%rJ,b")
6124 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6129 [(set_attr "type" "*,fga")
6130 (set_attr "fptype" "double")])
6132 (define_insn "*xordi3_sp64_dbl"
6133 [(set (match_operand:DI 0 "register_operand" "=r")
6134 (xor:DI (match_operand:DI 1 "register_operand" "r")
6135 (match_operand:DI 2 "const64_operand" "")))]
6137 && HOST_BITS_PER_WIDE_INT != 64)"
6140 (define_insn "xorsi3"
6141 [(set (match_operand:SI 0 "register_operand" "=r,d")
6142 (xor:SI (match_operand:SI 1 "arith_operand" "%rJ,d")
6143 (match_operand:SI 2 "arith_operand" "rI,d")))]
6148 [(set_attr "type" "*,fga")])
6151 [(set (match_operand:SI 0 "register_operand" "")
6152 (xor:SI (match_operand:SI 1 "register_operand" "")
6153 (match_operand:SI 2 "" "")))
6154 (clobber (match_operand:SI 3 "register_operand" ""))]
6155 "GET_CODE (operands[2]) == CONST_INT
6156 && !SMALL_INT32 (operands[2])
6157 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6158 [(set (match_dup 3) (match_dup 4))
6159 (set (match_dup 0) (not:SI (xor:SI (match_dup 3) (match_dup 1))))]
6161 operands[4] = GEN_INT (~INTVAL (operands[2]));
6165 [(set (match_operand:SI 0 "register_operand" "")
6166 (not:SI (xor:SI (match_operand:SI 1 "register_operand" "")
6167 (match_operand:SI 2 "" ""))))
6168 (clobber (match_operand:SI 3 "register_operand" ""))]
6169 "GET_CODE (operands[2]) == CONST_INT
6170 && !SMALL_INT32 (operands[2])
6171 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6172 [(set (match_dup 3) (match_dup 4))
6173 (set (match_dup 0) (xor:SI (match_dup 3) (match_dup 1)))]
6175 operands[4] = GEN_INT (~INTVAL (operands[2]));
6178 ;; xnor patterns. Note that (a ^ ~b) == (~a ^ b) == ~(a ^ b).
6179 ;; Combine now canonicalizes to the rightmost expression.
6180 (define_insn_and_split "*xor_not_di_sp32"
6181 [(set (match_operand:DI 0 "register_operand" "=r,b")
6182 (not:DI (xor:DI (match_operand:DI 1 "register_operand" "r,b")
6183 (match_operand:DI 2 "register_operand" "r,b"))))]
6188 "&& reload_completed
6189 && ((GET_CODE (operands[0]) == REG
6190 && REGNO (operands[0]) < 32)
6191 || (GET_CODE (operands[0]) == SUBREG
6192 && GET_CODE (SUBREG_REG (operands[0])) == REG
6193 && REGNO (SUBREG_REG (operands[0])) < 32))"
6194 [(set (match_dup 3) (not:SI (xor:SI (match_dup 4) (match_dup 5))))
6195 (set (match_dup 6) (not:SI (xor:SI (match_dup 7) (match_dup 8))))]
6196 "operands[3] = gen_highpart (SImode, operands[0]);
6197 operands[4] = gen_highpart (SImode, operands[1]);
6198 operands[5] = gen_highpart (SImode, operands[2]);
6199 operands[6] = gen_lowpart (SImode, operands[0]);
6200 operands[7] = gen_lowpart (SImode, operands[1]);
6201 operands[8] = gen_lowpart (SImode, operands[2]);"
6202 [(set_attr "type" "*,fga")
6203 (set_attr "length" "2,*")
6204 (set_attr "fptype" "double")])
6206 (define_insn "*xor_not_di_sp64"
6207 [(set (match_operand:DI 0 "register_operand" "=r,b")
6208 (not:DI (xor:DI (match_operand:DI 1 "reg_or_0_operand" "rJ,b")
6209 (match_operand:DI 2 "arith_double_operand" "rHI,b"))))]
6214 [(set_attr "type" "*,fga")
6215 (set_attr "fptype" "double")])
6217 (define_insn "*xor_not_si"
6218 [(set (match_operand:SI 0 "register_operand" "=r,d")
6219 (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "rJ,d")
6220 (match_operand:SI 2 "arith_operand" "rI,d"))))]
6225 [(set_attr "type" "*,fga")])
6227 ;; These correspond to the above in the case where we also (or only)
6228 ;; want to set the condition code.
6230 (define_insn "*cmp_cc_arith_op"
6233 (match_operator:SI 2 "cc_arithop"
6234 [(match_operand:SI 0 "arith_operand" "%r")
6235 (match_operand:SI 1 "arith_operand" "rI")])
6238 "%A2cc\t%0, %1, %%g0"
6239 [(set_attr "type" "compare")])
6241 (define_insn "*cmp_ccx_arith_op"
6244 (match_operator:DI 2 "cc_arithop"
6245 [(match_operand:DI 0 "arith_double_operand" "%r")
6246 (match_operand:DI 1 "arith_double_operand" "rHI")])
6249 "%A2cc\t%0, %1, %%g0"
6250 [(set_attr "type" "compare")])
6252 (define_insn "*cmp_cc_arith_op_set"
6255 (match_operator:SI 3 "cc_arithop"
6256 [(match_operand:SI 1 "arith_operand" "%r")
6257 (match_operand:SI 2 "arith_operand" "rI")])
6259 (set (match_operand:SI 0 "register_operand" "=r")
6260 (match_operator:SI 4 "cc_arithop" [(match_dup 1) (match_dup 2)]))]
6261 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
6263 [(set_attr "type" "compare")])
6265 (define_insn "*cmp_ccx_arith_op_set"
6268 (match_operator:DI 3 "cc_arithop"
6269 [(match_operand:DI 1 "arith_double_operand" "%r")
6270 (match_operand:DI 2 "arith_double_operand" "rHI")])
6272 (set (match_operand:DI 0 "register_operand" "=r")
6273 (match_operator:DI 4 "cc_arithop" [(match_dup 1) (match_dup 2)]))]
6274 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
6276 [(set_attr "type" "compare")])
6278 (define_insn "*cmp_cc_xor_not"
6281 (not:SI (xor:SI (match_operand:SI 0 "reg_or_0_operand" "%rJ")
6282 (match_operand:SI 1 "arith_operand" "rI")))
6285 "xnorcc\t%r0, %1, %%g0"
6286 [(set_attr "type" "compare")])
6288 (define_insn "*cmp_ccx_xor_not"
6291 (not:DI (xor:DI (match_operand:DI 0 "reg_or_0_operand" "%rJ")
6292 (match_operand:DI 1 "arith_double_operand" "rHI")))
6295 "xnorcc\t%r0, %1, %%g0"
6296 [(set_attr "type" "compare")])
6298 (define_insn "*cmp_cc_xor_not_set"
6301 (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
6302 (match_operand:SI 2 "arith_operand" "rI")))
6304 (set (match_operand:SI 0 "register_operand" "=r")
6305 (not:SI (xor:SI (match_dup 1) (match_dup 2))))]
6307 "xnorcc\t%r1, %2, %0"
6308 [(set_attr "type" "compare")])
6310 (define_insn "*cmp_ccx_xor_not_set"
6313 (not:DI (xor:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ")
6314 (match_operand:DI 2 "arith_double_operand" "rHI")))
6316 (set (match_operand:DI 0 "register_operand" "=r")
6317 (not:DI (xor:DI (match_dup 1) (match_dup 2))))]
6319 "xnorcc\t%r1, %2, %0"
6320 [(set_attr "type" "compare")])
6322 (define_insn "*cmp_cc_arith_op_not"
6325 (match_operator:SI 2 "cc_arithopn"
6326 [(not:SI (match_operand:SI 0 "arith_operand" "rI"))
6327 (match_operand:SI 1 "reg_or_0_operand" "rJ")])
6330 "%B2cc\t%r1, %0, %%g0"
6331 [(set_attr "type" "compare")])
6333 (define_insn "*cmp_ccx_arith_op_not"
6336 (match_operator:DI 2 "cc_arithopn"
6337 [(not:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
6338 (match_operand:DI 1 "reg_or_0_operand" "rJ")])
6341 "%B2cc\t%r1, %0, %%g0"
6342 [(set_attr "type" "compare")])
6344 (define_insn "*cmp_cc_arith_op_not_set"
6347 (match_operator:SI 3 "cc_arithopn"
6348 [(not:SI (match_operand:SI 1 "arith_operand" "rI"))
6349 (match_operand:SI 2 "reg_or_0_operand" "rJ")])
6351 (set (match_operand:SI 0 "register_operand" "=r")
6352 (match_operator:SI 4 "cc_arithopn"
6353 [(not:SI (match_dup 1)) (match_dup 2)]))]
6354 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
6355 "%B3cc\t%r2, %1, %0"
6356 [(set_attr "type" "compare")])
6358 (define_insn "*cmp_ccx_arith_op_not_set"
6361 (match_operator:DI 3 "cc_arithopn"
6362 [(not:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
6363 (match_operand:DI 2 "reg_or_0_operand" "rJ")])
6365 (set (match_operand:DI 0 "register_operand" "=r")
6366 (match_operator:DI 4 "cc_arithopn"
6367 [(not:DI (match_dup 1)) (match_dup 2)]))]
6368 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
6369 "%B3cc\t%r2, %1, %0"
6370 [(set_attr "type" "compare")])
6372 ;; We cannot use the "neg" pseudo insn because the Sun assembler
6373 ;; does not know how to make it work for constants.
6375 (define_expand "negdi2"
6376 [(set (match_operand:DI 0 "register_operand" "=r")
6377 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
6380 if (! TARGET_ARCH64)
6382 emit_insn (gen_rtx_PARALLEL
6385 gen_rtx_SET (VOIDmode, operand0,
6386 gen_rtx_NEG (DImode, operand1)),
6387 gen_rtx_CLOBBER (VOIDmode,
6388 gen_rtx_REG (CCmode,
6394 (define_insn_and_split "*negdi2_sp32"
6395 [(set (match_operand:DI 0 "register_operand" "=r")
6396 (neg:DI (match_operand:DI 1 "register_operand" "r")))
6397 (clobber (reg:CC 100))]
6400 "&& reload_completed"
6401 [(parallel [(set (reg:CC_NOOV 100)
6402 (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 5))
6404 (set (match_dup 4) (minus:SI (const_int 0) (match_dup 5)))])
6405 (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
6406 (ltu:SI (reg:CC 100) (const_int 0))))]
6407 "operands[2] = gen_highpart (SImode, operands[0]);
6408 operands[3] = gen_highpart (SImode, operands[1]);
6409 operands[4] = gen_lowpart (SImode, operands[0]);
6410 operands[5] = gen_lowpart (SImode, operands[1]);"
6411 [(set_attr "length" "2")])
6413 (define_insn "*negdi2_sp64"
6414 [(set (match_operand:DI 0 "register_operand" "=r")
6415 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
6417 "sub\t%%g0, %1, %0")
6419 (define_insn "negsi2"
6420 [(set (match_operand:SI 0 "register_operand" "=r")
6421 (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
6423 "sub\t%%g0, %1, %0")
6425 (define_insn "*cmp_cc_neg"
6426 [(set (reg:CC_NOOV 100)
6427 (compare:CC_NOOV (neg:SI (match_operand:SI 0 "arith_operand" "rI"))
6430 "subcc\t%%g0, %0, %%g0"
6431 [(set_attr "type" "compare")])
6433 (define_insn "*cmp_ccx_neg"
6434 [(set (reg:CCX_NOOV 100)
6435 (compare:CCX_NOOV (neg:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
6438 "subcc\t%%g0, %0, %%g0"
6439 [(set_attr "type" "compare")])
6441 (define_insn "*cmp_cc_set_neg"
6442 [(set (reg:CC_NOOV 100)
6443 (compare:CC_NOOV (neg:SI (match_operand:SI 1 "arith_operand" "rI"))
6445 (set (match_operand:SI 0 "register_operand" "=r")
6446 (neg:SI (match_dup 1)))]
6448 "subcc\t%%g0, %1, %0"
6449 [(set_attr "type" "compare")])
6451 (define_insn "*cmp_ccx_set_neg"
6452 [(set (reg:CCX_NOOV 100)
6453 (compare:CCX_NOOV (neg:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
6455 (set (match_operand:DI 0 "register_operand" "=r")
6456 (neg:DI (match_dup 1)))]
6458 "subcc\t%%g0, %1, %0"
6459 [(set_attr "type" "compare")])
6461 ;; We cannot use the "not" pseudo insn because the Sun assembler
6462 ;; does not know how to make it work for constants.
6463 (define_expand "one_cmpldi2"
6464 [(set (match_operand:DI 0 "register_operand" "")
6465 (not:DI (match_operand:DI 1 "register_operand" "")))]
6469 (define_insn_and_split "*one_cmpldi2_sp32"
6470 [(set (match_operand:DI 0 "register_operand" "=r,b")
6471 (not:DI (match_operand:DI 1 "register_operand" "r,b")))]
6476 "&& reload_completed
6477 && ((GET_CODE (operands[0]) == REG
6478 && REGNO (operands[0]) < 32)
6479 || (GET_CODE (operands[0]) == SUBREG
6480 && GET_CODE (SUBREG_REG (operands[0])) == REG
6481 && REGNO (SUBREG_REG (operands[0])) < 32))"
6482 [(set (match_dup 2) (not:SI (xor:SI (match_dup 3) (const_int 0))))
6483 (set (match_dup 4) (not:SI (xor:SI (match_dup 5) (const_int 0))))]
6484 "operands[2] = gen_highpart (SImode, operands[0]);
6485 operands[3] = gen_highpart (SImode, operands[1]);
6486 operands[4] = gen_lowpart (SImode, operands[0]);
6487 operands[5] = gen_lowpart (SImode, operands[1]);"
6488 [(set_attr "type" "*,fga")
6489 (set_attr "length" "2,*")
6490 (set_attr "fptype" "double")])
6492 (define_insn "*one_cmpldi2_sp64"
6493 [(set (match_operand:DI 0 "register_operand" "=r,b")
6494 (not:DI (match_operand:DI 1 "arith_double_operand" "rHI,b")))]
6499 [(set_attr "type" "*,fga")
6500 (set_attr "fptype" "double")])
6502 (define_insn "one_cmplsi2"
6503 [(set (match_operand:SI 0 "register_operand" "=r,d")
6504 (not:SI (match_operand:SI 1 "arith_operand" "rI,d")))]
6509 [(set_attr "type" "*,fga")])
6511 (define_insn "*cmp_cc_not"
6513 (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI"))
6516 "xnorcc\t%%g0, %0, %%g0"
6517 [(set_attr "type" "compare")])
6519 (define_insn "*cmp_ccx_not"
6521 (compare:CCX (not:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
6524 "xnorcc\t%%g0, %0, %%g0"
6525 [(set_attr "type" "compare")])
6527 (define_insn "*cmp_cc_set_not"
6529 (compare:CC (not:SI (match_operand:SI 1 "arith_operand" "rI"))
6531 (set (match_operand:SI 0 "register_operand" "=r")
6532 (not:SI (match_dup 1)))]
6534 "xnorcc\t%%g0, %1, %0"
6535 [(set_attr "type" "compare")])
6537 (define_insn "*cmp_ccx_set_not"
6539 (compare:CCX (not:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
6541 (set (match_operand:DI 0 "register_operand" "=r")
6542 (not:DI (match_dup 1)))]
6544 "xnorcc\t%%g0, %1, %0"
6545 [(set_attr "type" "compare")])
6547 (define_insn "*cmp_cc_set"
6548 [(set (match_operand:SI 0 "register_operand" "=r")
6549 (match_operand:SI 1 "register_operand" "r"))
6551 (compare:CC (match_dup 1)
6555 [(set_attr "type" "compare")])
6557 (define_insn "*cmp_ccx_set64"
6558 [(set (match_operand:DI 0 "register_operand" "=r")
6559 (match_operand:DI 1 "register_operand" "r"))
6561 (compare:CCX (match_dup 1)
6565 [(set_attr "type" "compare")])
6567 ;; Floating point arithmetic instructions.
6569 (define_expand "addtf3"
6570 [(set (match_operand:TF 0 "nonimmediate_operand" "")
6571 (plus:TF (match_operand:TF 1 "general_operand" "")
6572 (match_operand:TF 2 "general_operand" "")))]
6573 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6574 "emit_tfmode_binop (PLUS, operands); DONE;")
6576 (define_insn "*addtf3_hq"
6577 [(set (match_operand:TF 0 "register_operand" "=e")
6578 (plus:TF (match_operand:TF 1 "register_operand" "e")
6579 (match_operand:TF 2 "register_operand" "e")))]
6580 "TARGET_FPU && TARGET_HARD_QUAD"
6582 [(set_attr "type" "fp")])
6584 (define_insn "adddf3"
6585 [(set (match_operand:DF 0 "register_operand" "=e")
6586 (plus:DF (match_operand:DF 1 "register_operand" "e")
6587 (match_operand:DF 2 "register_operand" "e")))]
6590 [(set_attr "type" "fp")
6591 (set_attr "fptype" "double")])
6593 (define_insn "addsf3"
6594 [(set (match_operand:SF 0 "register_operand" "=f")
6595 (plus:SF (match_operand:SF 1 "register_operand" "f")
6596 (match_operand:SF 2 "register_operand" "f")))]
6599 [(set_attr "type" "fp")])
6601 (define_expand "subtf3"
6602 [(set (match_operand:TF 0 "nonimmediate_operand" "")
6603 (minus:TF (match_operand:TF 1 "general_operand" "")
6604 (match_operand:TF 2 "general_operand" "")))]
6605 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6606 "emit_tfmode_binop (MINUS, operands); DONE;")
6608 (define_insn "*subtf3_hq"
6609 [(set (match_operand:TF 0 "register_operand" "=e")
6610 (minus:TF (match_operand:TF 1 "register_operand" "e")
6611 (match_operand:TF 2 "register_operand" "e")))]
6612 "TARGET_FPU && TARGET_HARD_QUAD"
6614 [(set_attr "type" "fp")])
6616 (define_insn "subdf3"
6617 [(set (match_operand:DF 0 "register_operand" "=e")
6618 (minus:DF (match_operand:DF 1 "register_operand" "e")
6619 (match_operand:DF 2 "register_operand" "e")))]
6622 [(set_attr "type" "fp")
6623 (set_attr "fptype" "double")])
6625 (define_insn "subsf3"
6626 [(set (match_operand:SF 0 "register_operand" "=f")
6627 (minus:SF (match_operand:SF 1 "register_operand" "f")
6628 (match_operand:SF 2 "register_operand" "f")))]
6631 [(set_attr "type" "fp")])
6633 (define_expand "multf3"
6634 [(set (match_operand:TF 0 "nonimmediate_operand" "")
6635 (mult:TF (match_operand:TF 1 "general_operand" "")
6636 (match_operand:TF 2 "general_operand" "")))]
6637 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6638 "emit_tfmode_binop (MULT, operands); DONE;")
6640 (define_insn "*multf3_hq"
6641 [(set (match_operand:TF 0 "register_operand" "=e")
6642 (mult:TF (match_operand:TF 1 "register_operand" "e")
6643 (match_operand:TF 2 "register_operand" "e")))]
6644 "TARGET_FPU && TARGET_HARD_QUAD"
6646 [(set_attr "type" "fpmul")])
6648 (define_insn "muldf3"
6649 [(set (match_operand:DF 0 "register_operand" "=e")
6650 (mult:DF (match_operand:DF 1 "register_operand" "e")
6651 (match_operand:DF 2 "register_operand" "e")))]
6654 [(set_attr "type" "fpmul")
6655 (set_attr "fptype" "double")])
6657 (define_insn "mulsf3"
6658 [(set (match_operand:SF 0 "register_operand" "=f")
6659 (mult:SF (match_operand:SF 1 "register_operand" "f")
6660 (match_operand:SF 2 "register_operand" "f")))]
6663 [(set_attr "type" "fpmul")])
6665 (define_insn "*muldf3_extend"
6666 [(set (match_operand:DF 0 "register_operand" "=e")
6667 (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "f"))
6668 (float_extend:DF (match_operand:SF 2 "register_operand" "f"))))]
6669 "(TARGET_V8 || TARGET_V9) && TARGET_FPU"
6670 "fsmuld\t%1, %2, %0"
6671 [(set_attr "type" "fpmul")
6672 (set_attr "fptype" "double")])
6674 (define_insn "*multf3_extend"
6675 [(set (match_operand:TF 0 "register_operand" "=e")
6676 (mult:TF (float_extend:TF (match_operand:DF 1 "register_operand" "e"))
6677 (float_extend:TF (match_operand:DF 2 "register_operand" "e"))))]
6678 "(TARGET_V8 || TARGET_V9) && TARGET_FPU && TARGET_HARD_QUAD"
6679 "fdmulq\t%1, %2, %0"
6680 [(set_attr "type" "fpmul")])
6682 (define_expand "divtf3"
6683 [(set (match_operand:TF 0 "nonimmediate_operand" "")
6684 (div:TF (match_operand:TF 1 "general_operand" "")
6685 (match_operand:TF 2 "general_operand" "")))]
6686 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6687 "emit_tfmode_binop (DIV, operands); DONE;")
6689 ;; don't have timing for quad-prec. divide.
6690 (define_insn "*divtf3_hq"
6691 [(set (match_operand:TF 0 "register_operand" "=e")
6692 (div:TF (match_operand:TF 1 "register_operand" "e")
6693 (match_operand:TF 2 "register_operand" "e")))]
6694 "TARGET_FPU && TARGET_HARD_QUAD"
6696 [(set_attr "type" "fpdivd")])
6698 (define_insn "divdf3"
6699 [(set (match_operand:DF 0 "register_operand" "=e")
6700 (div:DF (match_operand:DF 1 "register_operand" "e")
6701 (match_operand:DF 2 "register_operand" "e")))]
6704 [(set_attr "type" "fpdivd")
6705 (set_attr "fptype" "double")])
6707 (define_insn "divsf3"
6708 [(set (match_operand:SF 0 "register_operand" "=f")
6709 (div:SF (match_operand:SF 1 "register_operand" "f")
6710 (match_operand:SF 2 "register_operand" "f")))]
6713 [(set_attr "type" "fpdivs")])
6715 (define_expand "negtf2"
6716 [(set (match_operand:TF 0 "register_operand" "=e,e")
6717 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
6721 (define_insn_and_split "*negtf2_notv9"
6722 [(set (match_operand:TF 0 "register_operand" "=e,e")
6723 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
6724 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
6730 "&& reload_completed
6731 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6732 [(set (match_dup 2) (neg:SF (match_dup 3)))
6733 (set (match_dup 4) (match_dup 5))
6734 (set (match_dup 6) (match_dup 7))]
6735 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6736 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6737 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6738 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
6739 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6740 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6741 [(set_attr "type" "fpmove,*")
6742 (set_attr "length" "*,2")])
6744 (define_insn_and_split "*negtf2_v9"
6745 [(set (match_operand:TF 0 "register_operand" "=e,e")
6746 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
6747 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
6748 "TARGET_FPU && TARGET_V9"
6752 "&& reload_completed
6753 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6754 [(set (match_dup 2) (neg:DF (match_dup 3)))
6755 (set (match_dup 4) (match_dup 5))]
6756 "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
6757 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
6758 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6759 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6760 [(set_attr "type" "fpmove,*")
6761 (set_attr "length" "*,2")
6762 (set_attr "fptype" "double")])
6764 (define_expand "negdf2"
6765 [(set (match_operand:DF 0 "register_operand" "")
6766 (neg:DF (match_operand:DF 1 "register_operand" "")))]
6770 (define_insn_and_split "*negdf2_notv9"
6771 [(set (match_operand:DF 0 "register_operand" "=e,e")
6772 (neg:DF (match_operand:DF 1 "register_operand" "0,e")))]
6773 "TARGET_FPU && ! TARGET_V9"
6777 "&& reload_completed
6778 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6779 [(set (match_dup 2) (neg:SF (match_dup 3)))
6780 (set (match_dup 4) (match_dup 5))]
6781 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6782 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6783 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6784 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);"
6785 [(set_attr "type" "fpmove,*")
6786 (set_attr "length" "*,2")])
6788 (define_insn "*negdf2_v9"
6789 [(set (match_operand:DF 0 "register_operand" "=e")
6790 (neg:DF (match_operand:DF 1 "register_operand" "e")))]
6791 "TARGET_FPU && TARGET_V9"
6793 [(set_attr "type" "fpmove")
6794 (set_attr "fptype" "double")])
6796 (define_insn "negsf2"
6797 [(set (match_operand:SF 0 "register_operand" "=f")
6798 (neg:SF (match_operand:SF 1 "register_operand" "f")))]
6801 [(set_attr "type" "fpmove")])
6803 (define_expand "abstf2"
6804 [(set (match_operand:TF 0 "register_operand" "")
6805 (abs:TF (match_operand:TF 1 "register_operand" "")))]
6809 (define_insn_and_split "*abstf2_notv9"
6810 [(set (match_operand:TF 0 "register_operand" "=e,e")
6811 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6812 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
6813 "TARGET_FPU && ! TARGET_V9"
6817 "&& reload_completed
6818 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6819 [(set (match_dup 2) (abs:SF (match_dup 3)))
6820 (set (match_dup 4) (match_dup 5))
6821 (set (match_dup 6) (match_dup 7))]
6822 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6823 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6824 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6825 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
6826 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6827 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6828 [(set_attr "type" "fpmove,*")
6829 (set_attr "length" "*,2")])
6831 (define_insn "*abstf2_hq_v9"
6832 [(set (match_operand:TF 0 "register_operand" "=e,e")
6833 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6834 "TARGET_FPU && TARGET_V9 && TARGET_HARD_QUAD"
6838 [(set_attr "type" "fpmove")
6839 (set_attr "fptype" "double,*")])
6841 (define_insn_and_split "*abstf2_v9"
6842 [(set (match_operand:TF 0 "register_operand" "=e,e")
6843 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6844 "TARGET_FPU && TARGET_V9 && !TARGET_HARD_QUAD"
6848 "&& reload_completed
6849 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6850 [(set (match_dup 2) (abs:DF (match_dup 3)))
6851 (set (match_dup 4) (match_dup 5))]
6852 "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
6853 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
6854 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6855 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6856 [(set_attr "type" "fpmove,*")
6857 (set_attr "length" "*,2")
6858 (set_attr "fptype" "double,*")])
6860 (define_expand "absdf2"
6861 [(set (match_operand:DF 0 "register_operand" "")
6862 (abs:DF (match_operand:DF 1 "register_operand" "")))]
6866 (define_insn_and_split "*absdf2_notv9"
6867 [(set (match_operand:DF 0 "register_operand" "=e,e")
6868 (abs:DF (match_operand:DF 1 "register_operand" "0,e")))]
6869 "TARGET_FPU && ! TARGET_V9"
6873 "&& reload_completed
6874 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6875 [(set (match_dup 2) (abs:SF (match_dup 3)))
6876 (set (match_dup 4) (match_dup 5))]
6877 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6878 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6879 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6880 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);"
6881 [(set_attr "type" "fpmove,*")
6882 (set_attr "length" "*,2")])
6884 (define_insn "*absdf2_v9"
6885 [(set (match_operand:DF 0 "register_operand" "=e")
6886 (abs:DF (match_operand:DF 1 "register_operand" "e")))]
6887 "TARGET_FPU && TARGET_V9"
6889 [(set_attr "type" "fpmove")
6890 (set_attr "fptype" "double")])
6892 (define_insn "abssf2"
6893 [(set (match_operand:SF 0 "register_operand" "=f")
6894 (abs:SF (match_operand:SF 1 "register_operand" "f")))]
6897 [(set_attr "type" "fpmove")])
6899 (define_expand "sqrttf2"
6900 [(set (match_operand:TF 0 "nonimmediate_operand" "")
6901 (sqrt:TF (match_operand:TF 1 "general_operand" "")))]
6902 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6903 "emit_tfmode_unop (SQRT, operands); DONE;")
6905 (define_insn "*sqrttf2_hq"
6906 [(set (match_operand:TF 0 "register_operand" "=e")
6907 (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
6908 "TARGET_FPU && TARGET_HARD_QUAD"
6910 [(set_attr "type" "fpsqrtd")])
6912 (define_insn "sqrtdf2"
6913 [(set (match_operand:DF 0 "register_operand" "=e")
6914 (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
6917 [(set_attr "type" "fpsqrtd")
6918 (set_attr "fptype" "double")])
6920 (define_insn "sqrtsf2"
6921 [(set (match_operand:SF 0 "register_operand" "=f")
6922 (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
6925 [(set_attr "type" "fpsqrts")])
6927 ;;- arithmetic shift instructions
6929 (define_insn "ashlsi3"
6930 [(set (match_operand:SI 0 "register_operand" "=r")
6931 (ashift:SI (match_operand:SI 1 "register_operand" "r")
6932 (match_operand:SI 2 "arith_operand" "rI")))]
6935 if (operands[2] == const1_rtx)
6936 return "add\t%1, %1, %0";
6937 if (GET_CODE (operands[2]) == CONST_INT)
6938 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6939 return "sll\t%1, %2, %0";
6942 (if_then_else (match_operand 2 "const1_operand" "")
6943 (const_string "ialu") (const_string "shift")))])
6945 (define_expand "ashldi3"
6946 [(set (match_operand:DI 0 "register_operand" "=r")
6947 (ashift:DI (match_operand:DI 1 "register_operand" "r")
6948 (match_operand:SI 2 "arith_operand" "rI")))]
6949 "TARGET_ARCH64 || TARGET_V8PLUS"
6951 if (! TARGET_ARCH64)
6953 if (GET_CODE (operands[2]) == CONST_INT)
6955 emit_insn (gen_ashldi3_v8plus (operands[0], operands[1], operands[2]));
6960 (define_insn "*ashldi3_sp64"
6961 [(set (match_operand:DI 0 "register_operand" "=r")
6962 (ashift:DI (match_operand:DI 1 "register_operand" "r")
6963 (match_operand:SI 2 "arith_operand" "rI")))]
6966 if (operands[2] == const1_rtx)
6967 return "add\t%1, %1, %0";
6968 if (GET_CODE (operands[2]) == CONST_INT)
6969 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
6970 return "sllx\t%1, %2, %0";
6973 (if_then_else (match_operand 2 "const1_operand" "")
6974 (const_string "ialu") (const_string "shift")))])
6977 (define_insn "ashldi3_v8plus"
6978 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
6979 (ashift:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
6980 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
6981 (clobber (match_scratch:SI 3 "=X,X,&h"))]
6983 "* return output_v8plus_shift (operands, insn, \"sllx\");"
6984 [(set_attr "type" "multi")
6985 (set_attr "length" "5,5,6")])
6987 ;; Optimize (1LL<<x)-1
6988 ;; XXX this also needs to be fixed to handle equal subregs
6989 ;; XXX first before we could re-enable it.
6991 ; [(set (match_operand:DI 0 "register_operand" "=h")
6992 ; (plus:DI (ashift:DI (const_int 1)
6993 ; (match_operand:SI 1 "arith_operand" "rI"))
6995 ; "0 && TARGET_V8PLUS"
6997 ; if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == REGNO (operands[0]))
6998 ; return "mov\t1, %L0\;sllx\t%L0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
6999 ; return "mov\t1, %H0\;sllx\t%H0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
7001 ; [(set_attr "type" "multi")
7002 ; (set_attr "length" "4")])
7004 (define_insn "*cmp_cc_ashift_1"
7005 [(set (reg:CC_NOOV 100)
7006 (compare:CC_NOOV (ashift:SI (match_operand:SI 0 "register_operand" "r")
7010 "addcc\t%0, %0, %%g0"
7011 [(set_attr "type" "compare")])
7013 (define_insn "*cmp_cc_set_ashift_1"
7014 [(set (reg:CC_NOOV 100)
7015 (compare:CC_NOOV (ashift:SI (match_operand:SI 1 "register_operand" "r")
7018 (set (match_operand:SI 0 "register_operand" "=r")
7019 (ashift:SI (match_dup 1) (const_int 1)))]
7022 [(set_attr "type" "compare")])
7024 (define_insn "ashrsi3"
7025 [(set (match_operand:SI 0 "register_operand" "=r")
7026 (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
7027 (match_operand:SI 2 "arith_operand" "rI")))]
7030 if (GET_CODE (operands[2]) == CONST_INT)
7031 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
7032 return "sra\t%1, %2, %0";
7034 [(set_attr "type" "shift")])
7036 (define_insn "*ashrsi3_extend"
7037 [(set (match_operand:DI 0 "register_operand" "=r")
7038 (sign_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
7039 (match_operand:SI 2 "arith_operand" "r"))))]
7042 [(set_attr "type" "shift")])
7044 ;; This handles the case as above, but with constant shift instead of
7045 ;; register. Combiner "simplifies" it for us a little bit though.
7046 (define_insn "*ashrsi3_extend2"
7047 [(set (match_operand:DI 0 "register_operand" "=r")
7048 (ashiftrt:DI (ashift:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
7050 (match_operand:SI 2 "small_int_or_double" "n")))]
7052 && ((GET_CODE (operands[2]) == CONST_INT
7053 && INTVAL (operands[2]) >= 32 && INTVAL (operands[2]) < 64)
7054 || (GET_CODE (operands[2]) == CONST_DOUBLE
7055 && !CONST_DOUBLE_HIGH (operands[2])
7056 && CONST_DOUBLE_LOW (operands[2]) >= 32
7057 && CONST_DOUBLE_LOW (operands[2]) < 64))"
7059 operands[2] = GEN_INT (INTVAL (operands[2]) - 32);
7061 return "sra\t%1, %2, %0";
7063 [(set_attr "type" "shift")])
7065 (define_expand "ashrdi3"
7066 [(set (match_operand:DI 0 "register_operand" "=r")
7067 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
7068 (match_operand:SI 2 "arith_operand" "rI")))]
7069 "TARGET_ARCH64 || TARGET_V8PLUS"
7071 if (! TARGET_ARCH64)
7073 if (GET_CODE (operands[2]) == CONST_INT)
7074 FAIL; /* prefer generic code in this case */
7075 emit_insn (gen_ashrdi3_v8plus (operands[0], operands[1], operands[2]));
7080 (define_insn "*ashrdi3_sp64"
7081 [(set (match_operand:DI 0 "register_operand" "=r")
7082 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
7083 (match_operand:SI 2 "arith_operand" "rI")))]
7087 if (GET_CODE (operands[2]) == CONST_INT)
7088 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
7089 return "srax\t%1, %2, %0";
7091 [(set_attr "type" "shift")])
7094 (define_insn "ashrdi3_v8plus"
7095 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
7096 (ashiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
7097 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
7098 (clobber (match_scratch:SI 3 "=X,X,&h"))]
7100 "* return output_v8plus_shift (operands, insn, \"srax\");"
7101 [(set_attr "type" "multi")
7102 (set_attr "length" "5,5,6")])
7104 (define_insn "lshrsi3"
7105 [(set (match_operand:SI 0 "register_operand" "=r")
7106 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
7107 (match_operand:SI 2 "arith_operand" "rI")))]
7110 if (GET_CODE (operands[2]) == CONST_INT)
7111 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
7112 return "srl\t%1, %2, %0";
7114 [(set_attr "type" "shift")])
7116 ;; This handles the case where
7117 ;; (zero_extend:DI (lshiftrt:SI (match_operand:SI) (match_operand:SI))),
7118 ;; but combiner "simplifies" it for us.
7119 (define_insn "*lshrsi3_extend"
7120 [(set (match_operand:DI 0 "register_operand" "=r")
7121 (and:DI (subreg:DI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
7122 (match_operand:SI 2 "arith_operand" "r")) 0)
7123 (match_operand 3 "" "")))]
7125 && ((GET_CODE (operands[3]) == CONST_DOUBLE
7126 && CONST_DOUBLE_HIGH (operands[3]) == 0
7127 && CONST_DOUBLE_LOW (operands[3]) == 0xffffffff)
7128 || (HOST_BITS_PER_WIDE_INT >= 64
7129 && GET_CODE (operands[3]) == CONST_INT
7130 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) == 0xffffffff))"
7132 [(set_attr "type" "shift")])
7134 ;; This handles the case where
7135 ;; (lshiftrt:DI (zero_extend:DI (match_operand:SI)) (const_int >=0 < 32))
7136 ;; but combiner "simplifies" it for us.
7137 (define_insn "*lshrsi3_extend2"
7138 [(set (match_operand:DI 0 "register_operand" "=r")
7139 (zero_extract:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
7140 (match_operand 2 "small_int_or_double" "n")
7143 && ((GET_CODE (operands[2]) == CONST_INT
7144 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
7145 || (GET_CODE (operands[2]) == CONST_DOUBLE
7146 && CONST_DOUBLE_HIGH (operands[2]) == 0
7147 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
7149 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
7151 return "srl\t%1, %2, %0";
7153 [(set_attr "type" "shift")])
7155 (define_expand "lshrdi3"
7156 [(set (match_operand:DI 0 "register_operand" "=r")
7157 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
7158 (match_operand:SI 2 "arith_operand" "rI")))]
7159 "TARGET_ARCH64 || TARGET_V8PLUS"
7161 if (! TARGET_ARCH64)
7163 if (GET_CODE (operands[2]) == CONST_INT)
7165 emit_insn (gen_lshrdi3_v8plus (operands[0], operands[1], operands[2]));
7170 (define_insn "*lshrdi3_sp64"
7171 [(set (match_operand:DI 0 "register_operand" "=r")
7172 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
7173 (match_operand:SI 2 "arith_operand" "rI")))]
7176 if (GET_CODE (operands[2]) == CONST_INT)
7177 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
7178 return "srlx\t%1, %2, %0";
7180 [(set_attr "type" "shift")])
7183 (define_insn "lshrdi3_v8plus"
7184 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
7185 (lshiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
7186 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
7187 (clobber (match_scratch:SI 3 "=X,X,&h"))]
7189 "* return output_v8plus_shift (operands, insn, \"srlx\");"
7190 [(set_attr "type" "multi")
7191 (set_attr "length" "5,5,6")])
7194 [(set (match_operand:SI 0 "register_operand" "=r")
7195 (ashiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
7197 (match_operand:SI 2 "small_int_or_double" "n")))]
7199 && ((GET_CODE (operands[2]) == CONST_INT
7200 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
7201 || (GET_CODE (operands[2]) == CONST_DOUBLE
7202 && !CONST_DOUBLE_HIGH (operands[2])
7203 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
7205 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
7207 return "srax\t%1, %2, %0";
7209 [(set_attr "type" "shift")])
7212 [(set (match_operand:SI 0 "register_operand" "=r")
7213 (lshiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
7215 (match_operand:SI 2 "small_int_or_double" "n")))]
7217 && ((GET_CODE (operands[2]) == CONST_INT
7218 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
7219 || (GET_CODE (operands[2]) == CONST_DOUBLE
7220 && !CONST_DOUBLE_HIGH (operands[2])
7221 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
7223 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
7225 return "srlx\t%1, %2, %0";
7227 [(set_attr "type" "shift")])
7230 [(set (match_operand:SI 0 "register_operand" "=r")
7231 (ashiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
7232 (match_operand:SI 2 "small_int_or_double" "n")) 4)
7233 (match_operand:SI 3 "small_int_or_double" "n")))]
7235 && GET_CODE (operands[2]) == CONST_INT && GET_CODE (operands[3]) == CONST_INT
7236 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
7237 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
7238 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
7240 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
7242 return "srax\t%1, %2, %0";
7244 [(set_attr "type" "shift")])
7247 [(set (match_operand:SI 0 "register_operand" "=r")
7248 (lshiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
7249 (match_operand:SI 2 "small_int_or_double" "n")) 4)
7250 (match_operand:SI 3 "small_int_or_double" "n")))]
7252 && GET_CODE (operands[2]) == CONST_INT && GET_CODE (operands[3]) == CONST_INT
7253 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
7254 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
7255 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
7257 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
7259 return "srlx\t%1, %2, %0";
7261 [(set_attr "type" "shift")])
7263 ;; Unconditional and other jump instructions
7264 ;; On the SPARC, by setting the annul bit on an unconditional branch, the
7265 ;; following insn is never executed. This saves us a nop. Dbx does not
7266 ;; handle such branches though, so we only use them when optimizing.
7268 [(set (pc) (label_ref (match_operand 0 "" "")))]
7271 /* TurboSPARC is reported to have problems with
7274 i.e. an empty loop with the annul bit set. The workaround is to use
7278 if (! TARGET_V9 && flag_delayed_branch
7279 && (INSN_ADDRESSES (INSN_UID (operands[0]))
7280 == INSN_ADDRESSES (INSN_UID (insn))))
7283 return TARGET_V9 ? "ba%*,pt\t%%xcc, %l0%(" : "b%*\t%l0%(";
7285 [(set_attr "type" "uncond_branch")])
7287 (define_expand "tablejump"
7288 [(parallel [(set (pc) (match_operand 0 "register_operand" "r"))
7289 (use (label_ref (match_operand 1 "" "")))])]
7292 if (GET_MODE (operands[0]) != CASE_VECTOR_MODE)
7295 /* In pic mode, our address differences are against the base of the
7296 table. Add that base value back in; CSE ought to be able to combine
7297 the two address loads. */
7301 tmp = gen_rtx_LABEL_REF (Pmode, operands[1]);
7303 if (CASE_VECTOR_MODE != Pmode)
7304 tmp2 = gen_rtx_SIGN_EXTEND (Pmode, tmp2);
7305 tmp = gen_rtx_PLUS (Pmode, tmp2, tmp);
7306 operands[0] = memory_address (Pmode, tmp);
7310 (define_insn "*tablejump_sp32"
7311 [(set (pc) (match_operand:SI 0 "address_operand" "p"))
7312 (use (label_ref (match_operand 1 "" "")))]
7315 [(set_attr "type" "uncond_branch")])
7317 (define_insn "*tablejump_sp64"
7318 [(set (pc) (match_operand:DI 0 "address_operand" "p"))
7319 (use (label_ref (match_operand 1 "" "")))]
7322 [(set_attr "type" "uncond_branch")])
7324 ;;- jump to subroutine
7325 (define_expand "call"
7326 ;; Note that this expression is not used for generating RTL.
7327 ;; All the RTL is generated explicitly below.
7328 [(call (match_operand 0 "call_operand" "")
7329 (match_operand 3 "" "i"))]
7330 ;; operands[2] is next_arg_register
7331 ;; operands[3] is struct_value_size_rtx.
7336 if (GET_MODE (operands[0]) != FUNCTION_MODE)
7339 if (GET_CODE (operands[3]) != CONST_INT)
7342 if (GET_CODE (XEXP (operands[0], 0)) == LABEL_REF)
7344 /* This is really a PIC sequence. We want to represent
7345 it as a funny jump so its delay slots can be filled.
7347 ??? But if this really *is* a CALL, will not it clobber the
7348 call-clobbered registers? We lose this if it is a JUMP_INSN.
7349 Why cannot we have delay slots filled if it were a CALL? */
7351 /* We accept negative sizes for untyped calls. */
7352 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
7357 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
7359 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
7365 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
7366 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
7370 fn_rtx = operands[0];
7372 /* We accept negative sizes for untyped calls. */
7373 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
7377 gen_rtvec (3, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx),
7379 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
7384 gen_rtvec (2, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx),
7385 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
7392 ;; We can't use the same pattern for these two insns, because then registers
7393 ;; in the address may not be properly reloaded.
7395 (define_insn "*call_address_sp32"
7396 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
7397 (match_operand 1 "" ""))
7398 (clobber (reg:SI 15))]
7399 ;;- Do not use operand 1 for most machines.
7402 [(set_attr "type" "call")])
7404 (define_insn "*call_symbolic_sp32"
7405 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
7406 (match_operand 1 "" ""))
7407 (clobber (reg:SI 15))]
7408 ;;- Do not use operand 1 for most machines.
7411 [(set_attr "type" "call")])
7413 (define_insn "*call_address_sp64"
7414 [(call (mem:DI (match_operand:DI 0 "address_operand" "p"))
7415 (match_operand 1 "" ""))
7416 (clobber (reg:DI 15))]
7417 ;;- Do not use operand 1 for most machines.
7420 [(set_attr "type" "call")])
7422 (define_insn "*call_symbolic_sp64"
7423 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
7424 (match_operand 1 "" ""))
7425 (clobber (reg:DI 15))]
7426 ;;- Do not use operand 1 for most machines.
7429 [(set_attr "type" "call")])
7431 ;; This is a call that wants a structure value.
7432 ;; There is no such critter for v9 (??? we may need one anyway).
7433 (define_insn "*call_address_struct_value_sp32"
7434 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
7435 (match_operand 1 "" ""))
7436 (match_operand 2 "immediate_operand" "")
7437 (clobber (reg:SI 15))]
7438 ;;- Do not use operand 1 for most machines.
7439 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
7440 "call\t%a0, %1\n\t nop\n\tunimp\t%2"
7441 [(set_attr "type" "call_no_delay_slot")
7442 (set_attr "length" "3")])
7444 ;; This is a call that wants a structure value.
7445 ;; There is no such critter for v9 (??? we may need one anyway).
7446 (define_insn "*call_symbolic_struct_value_sp32"
7447 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
7448 (match_operand 1 "" ""))
7449 (match_operand 2 "immediate_operand" "")
7450 (clobber (reg:SI 15))]
7451 ;;- Do not use operand 1 for most machines.
7452 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
7453 "call\t%a0, %1\n\t nop\n\tunimp\t%2"
7454 [(set_attr "type" "call_no_delay_slot")
7455 (set_attr "length" "3")])
7457 ;; This is a call that may want a structure value. This is used for
7459 (define_insn "*call_address_untyped_struct_value_sp32"
7460 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
7461 (match_operand 1 "" ""))
7462 (match_operand 2 "immediate_operand" "")
7463 (clobber (reg:SI 15))]
7464 ;;- Do not use operand 1 for most machines.
7465 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
7466 "call\t%a0, %1\n\t nop\n\tnop"
7467 [(set_attr "type" "call_no_delay_slot")
7468 (set_attr "length" "3")])
7470 ;; This is a call that may want a structure value. This is used for
7472 (define_insn "*call_symbolic_untyped_struct_value_sp32"
7473 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
7474 (match_operand 1 "" ""))
7475 (match_operand 2 "immediate_operand" "")
7476 (clobber (reg:SI 15))]
7477 ;;- Do not use operand 1 for most machines.
7478 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
7479 "call\t%a0, %1\n\t nop\n\tnop"
7480 [(set_attr "type" "call_no_delay_slot")
7481 (set_attr "length" "3")])
7483 (define_expand "call_value"
7484 ;; Note that this expression is not used for generating RTL.
7485 ;; All the RTL is generated explicitly below.
7486 [(set (match_operand 0 "register_operand" "=rf")
7487 (call (match_operand 1 "" "")
7488 (match_operand 4 "" "")))]
7489 ;; operand 2 is stack_size_rtx
7490 ;; operand 3 is next_arg_register
7496 if (GET_MODE (operands[1]) != FUNCTION_MODE)
7499 fn_rtx = operands[1];
7502 gen_rtx_SET (VOIDmode, operands[0],
7503 gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx)),
7504 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)));
7506 emit_call_insn (gen_rtx_PARALLEL (VOIDmode, vec));
7511 (define_insn "*call_value_address_sp32"
7512 [(set (match_operand 0 "" "=rf")
7513 (call (mem:SI (match_operand:SI 1 "address_operand" "p"))
7514 (match_operand 2 "" "")))
7515 (clobber (reg:SI 15))]
7516 ;;- Do not use operand 2 for most machines.
7519 [(set_attr "type" "call")])
7521 (define_insn "*call_value_symbolic_sp32"
7522 [(set (match_operand 0 "" "=rf")
7523 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
7524 (match_operand 2 "" "")))
7525 (clobber (reg:SI 15))]
7526 ;;- Do not use operand 2 for most machines.
7529 [(set_attr "type" "call")])
7531 (define_insn "*call_value_address_sp64"
7532 [(set (match_operand 0 "" "")
7533 (call (mem:DI (match_operand:DI 1 "address_operand" "p"))
7534 (match_operand 2 "" "")))
7535 (clobber (reg:DI 15))]
7536 ;;- Do not use operand 2 for most machines.
7539 [(set_attr "type" "call")])
7541 (define_insn "*call_value_symbolic_sp64"
7542 [(set (match_operand 0 "" "")
7543 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
7544 (match_operand 2 "" "")))
7545 (clobber (reg:DI 15))]
7546 ;;- Do not use operand 2 for most machines.
7549 [(set_attr "type" "call")])
7551 (define_expand "untyped_call"
7552 [(parallel [(call (match_operand 0 "" "")
7554 (match_operand 1 "" "")
7555 (match_operand 2 "" "")])]
7560 /* Pass constm1 to indicate that it may expect a structure value, but
7561 we don't know what size it is. */
7562 emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, constm1_rtx));
7564 for (i = 0; i < XVECLEN (operands[2], 0); i++)
7566 rtx set = XVECEXP (operands[2], 0, i);
7567 emit_move_insn (SET_DEST (set), SET_SRC (set));
7570 /* The optimizer does not know that the call sets the function value
7571 registers we stored in the result block. We avoid problems by
7572 claiming that all hard registers are used and clobbered at this
7574 emit_insn (gen_blockage ());
7580 (define_expand "sibcall"
7581 [(parallel [(call (match_operand 0 "call_operand" "") (const_int 0))
7586 (define_insn "*sibcall_symbolic_sp32"
7587 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
7588 (match_operand 1 "" ""))
7591 "* return output_sibcall(insn, operands[0]);"
7592 [(set_attr "type" "sibcall")])
7594 (define_insn "*sibcall_symbolic_sp64"
7595 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
7596 (match_operand 1 "" ""))
7599 "* return output_sibcall(insn, operands[0]);"
7600 [(set_attr "type" "sibcall")])
7602 (define_expand "sibcall_value"
7603 [(parallel [(set (match_operand 0 "register_operand" "=rf")
7604 (call (match_operand 1 "" "") (const_int 0)))
7609 (define_insn "*sibcall_value_symbolic_sp32"
7610 [(set (match_operand 0 "" "=rf")
7611 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
7612 (match_operand 2 "" "")))
7615 "* return output_sibcall(insn, operands[1]);"
7616 [(set_attr "type" "sibcall")])
7618 (define_insn "*sibcall_value_symbolic_sp64"
7619 [(set (match_operand 0 "" "")
7620 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
7621 (match_operand 2 "" "")))
7624 "* return output_sibcall(insn, operands[1]);"
7625 [(set_attr "type" "sibcall")])
7627 (define_expand "sibcall_epilogue"
7631 sparc_expand_epilogue ();
7635 (define_expand "prologue"
7639 sparc_expand_prologue ();
7643 (define_expand "save_register_window"
7644 [(use (match_operand 0 "arith_operand" ""))]
7650 gen_rtx_SET (VOIDmode,
7652 gen_rtx_PLUS (Pmode,
7653 hard_frame_pointer_rtx,
7655 gen_rtx_UNSPEC_VOLATILE (VOIDmode,
7656 gen_rtvec (1, const0_rtx),
7659 emit_insn (gen_rtx_PARALLEL (VOIDmode, vec));
7663 (define_insn "*save_register_windowsi"
7664 [(set (reg:SI 14) (plus:SI (reg:SI 30)
7665 (match_operand:SI 0 "arith_operand" "rI")))
7666 (unspec_volatile [(const_int 0)] UNSPECV_SAVEW)]
7668 "save\t%%sp, %0, %%sp"
7669 [(set_attr "type" "savew")])
7671 (define_insn "*save_register_windowdi"
7672 [(set (reg:DI 14) (plus:DI (reg:DI 30)
7673 (match_operand:DI 0 "arith_operand" "rI")))
7674 (unspec_volatile [(const_int 0)] UNSPECV_SAVEW)]
7676 "save\t%%sp, %0, %%sp"
7677 [(set_attr "type" "savew")])
7679 (define_expand "epilogue"
7683 sparc_expand_epilogue ();
7686 (define_insn "*return_internal"
7689 "* return output_return (insn);"
7690 [(set_attr "type" "return")
7691 (set_attr "length" "2")])
7693 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
7694 ;; all of memory. This blocks insns from being moved across this point.
7696 (define_insn "blockage"
7697 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
7700 [(set_attr "length" "0")])
7702 ;; Prepare to return any type including a structure value.
7704 (define_expand "untyped_return"
7705 [(match_operand:BLK 0 "memory_operand" "")
7706 (match_operand 1 "" "")]
7709 rtx valreg1 = gen_rtx_REG (DImode, 24);
7710 rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
7711 rtx result = operands[0];
7713 if (! TARGET_ARCH64)
7715 rtx rtnreg = gen_rtx_REG (SImode, (current_function_uses_only_leaf_regs
7717 rtx value = gen_reg_rtx (SImode);
7719 /* Fetch the instruction where we will return to and see if it's an unimp
7720 instruction (the most significant 10 bits will be zero). If so,
7721 update the return address to skip the unimp instruction. */
7722 emit_move_insn (value,
7723 gen_rtx_MEM (SImode, plus_constant (rtnreg, 8)));
7724 emit_insn (gen_lshrsi3 (value, value, GEN_INT (22)));
7725 emit_insn (gen_update_return (rtnreg, value));
7728 /* Reload the function value registers. */
7729 emit_move_insn (valreg1, adjust_address (result, DImode, 0));
7730 emit_move_insn (valreg2,
7731 adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8));
7733 /* Put USE insns before the return. */
7734 emit_insn (gen_rtx_USE (VOIDmode, valreg1));
7735 emit_insn (gen_rtx_USE (VOIDmode, valreg2));
7737 /* Construct the return. */
7738 expand_naked_return ();
7743 ;; This is a bit of a hack. We're incrementing a fixed register (%i7),
7744 ;; and parts of the compiler don't want to believe that the add is needed.
7746 (define_insn "update_return"
7747 [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
7748 (match_operand:SI 1 "register_operand" "r")] UNSPEC_UPDATE_RETURN)]
7750 "cmp\t%1, 0\;be,a\t.+8\;add\t%0, 4, %0"
7751 [(set_attr "type" "multi")
7752 (set_attr "length" "3")])
7759 (define_expand "indirect_jump"
7760 [(set (pc) (match_operand 0 "address_operand" "p"))]
7764 (define_insn "*branch_sp32"
7765 [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
7768 [(set_attr "type" "uncond_branch")])
7770 (define_insn "*branch_sp64"
7771 [(set (pc) (match_operand:DI 0 "address_operand" "p"))]
7774 [(set_attr "type" "uncond_branch")])
7776 (define_expand "nonlocal_goto"
7777 [(match_operand:SI 0 "general_operand" "")
7778 (match_operand:SI 1 "general_operand" "")
7779 (match_operand:SI 2 "general_operand" "")
7780 (match_operand:SI 3 "" "")]
7783 rtx lab = operands[1];
7784 rtx stack = operands[2];
7785 rtx fp = operands[3];
7788 /* Trap instruction to flush all the register windows. */
7789 emit_insn (gen_flush_register_windows ());
7791 /* Load the fp value for the containing fn into %fp. This is needed
7792 because STACK refers to %fp. Note that virtual register instantiation
7793 fails if the virtual %fp isn't set from a register. */
7794 if (GET_CODE (fp) != REG)
7795 fp = force_reg (Pmode, fp);
7796 emit_move_insn (virtual_stack_vars_rtx, fp);
7798 /* Find the containing function's current nonlocal goto handler,
7799 which will do any cleanups and then jump to the label. */
7800 labreg = gen_rtx_REG (Pmode, 8);
7801 emit_move_insn (labreg, lab);
7803 /* Restore %fp from stack pointer value for containing function.
7804 The restore insn that follows will move this to %sp,
7805 and reload the appropriate value into %fp. */
7806 emit_move_insn (hard_frame_pointer_rtx, stack);
7808 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
7809 emit_insn (gen_rtx_USE (VOIDmode, static_chain_rtx));
7811 /* ??? The V9-specific version was disabled in rev 1.65. */
7812 emit_jump_insn (gen_goto_handler_and_restore (labreg));
7817 ;; Special trap insn to flush register windows.
7818 (define_insn "flush_register_windows"
7819 [(unspec_volatile [(const_int 0)] UNSPECV_FLUSHW)]
7821 { return TARGET_V9 ? "flushw" : "ta\t3"; }
7822 [(set_attr "type" "flushw")])
7824 (define_insn "goto_handler_and_restore"
7825 [(unspec_volatile [(match_operand 0 "register_operand" "=r")] UNSPECV_GOTO)]
7826 "GET_MODE (operands[0]) == Pmode"
7827 "jmp\t%0+0\n\trestore"
7828 [(set_attr "type" "multi")
7829 (set_attr "length" "2")])
7831 ;; For __builtin_setjmp we need to flush register windows iff the function
7832 ;; calls alloca as well, because otherwise the register window might be
7833 ;; saved after %sp adjustment and thus setjmp would crash
7834 (define_expand "builtin_setjmp_setup"
7835 [(match_operand 0 "register_operand" "r")]
7838 emit_insn (gen_do_builtin_setjmp_setup ());
7842 (define_insn "do_builtin_setjmp_setup"
7843 [(unspec_volatile [(const_int 0)] UNSPECV_SETJMP)]
7846 if (! current_function_calls_alloca)
7850 fputs ("\tflushw\n", asm_out_file);
7852 fprintf (asm_out_file, "\tst%c\t%%l7, [%%sp+%d]\n",
7853 TARGET_ARCH64 ? 'x' : 'w',
7854 SPARC_STACK_BIAS + 7 * UNITS_PER_WORD);
7855 fprintf (asm_out_file, "\tst%c\t%%fp, [%%sp+%d]\n",
7856 TARGET_ARCH64 ? 'x' : 'w',
7857 SPARC_STACK_BIAS + 14 * UNITS_PER_WORD);
7858 fprintf (asm_out_file, "\tst%c\t%%i7, [%%sp+%d]\n",
7859 TARGET_ARCH64 ? 'x' : 'w',
7860 SPARC_STACK_BIAS + 15 * UNITS_PER_WORD);
7863 [(set_attr "type" "multi")
7864 (set (attr "length")
7865 (cond [(eq_attr "current_function_calls_alloca" "false")
7867 (eq_attr "isa" "!v9")
7869 (eq_attr "pic" "true")
7870 (const_int 4)] (const_int 3)))])
7872 ;; Pattern for use after a setjmp to store FP and the return register
7873 ;; into the stack area.
7875 (define_expand "setjmp"
7880 emit_insn (gen_setjmp_64 ());
7882 emit_insn (gen_setjmp_32 ());
7886 (define_expand "setjmp_32"
7887 [(set (mem:SI (plus:SI (reg:SI 14) (const_int 56))) (match_dup 0))
7888 (set (mem:SI (plus:SI (reg:SI 14) (const_int 60))) (reg:SI 31))]
7890 { operands[0] = frame_pointer_rtx; })
7892 (define_expand "setjmp_64"
7893 [(set (mem:DI (plus:DI (reg:DI 14) (const_int 112))) (match_dup 0))
7894 (set (mem:DI (plus:DI (reg:DI 14) (const_int 120))) (reg:DI 31))]
7896 { operands[0] = frame_pointer_rtx; })
7898 ;; Special pattern for the FLUSH instruction.
7900 ; We do SImode and DImode versions of this to quiet down genrecog's complaints
7901 ; of the define_insn otherwise missing a mode. We make "flush", aka
7902 ; gen_flush, the default one since sparc_initialize_trampoline uses
7903 ; it on SImode mem values.
7905 (define_insn "flush"
7906 [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")] UNSPECV_FLUSH)]
7908 { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; }
7909 [(set_attr "type" "iflush")])
7911 (define_insn "flushdi"
7912 [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")] UNSPECV_FLUSH)]
7914 { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; }
7915 [(set_attr "type" "iflush")])
7920 ;; The scan instruction searches from the most significant bit while ffs
7921 ;; searches from the least significant bit. The bit index and treatment of
7922 ;; zero also differ. It takes at least 7 instructions to get the proper
7923 ;; result. Here is an obvious 8 instruction sequence.
7926 (define_insn "ffssi2"
7927 [(set (match_operand:SI 0 "register_operand" "=&r")
7928 (ffs:SI (match_operand:SI 1 "register_operand" "r")))
7929 (clobber (match_scratch:SI 2 "=&r"))]
7930 "TARGET_SPARCLITE || TARGET_SPARCLET"
7932 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";
7934 [(set_attr "type" "multi")
7935 (set_attr "length" "8")])
7937 ;; ??? This should be a define expand, so that the extra instruction have
7938 ;; a chance of being optimized away.
7940 ;; Disabled because none of the UltraSPARCs implement popc. The HAL R1
7941 ;; does, but no one uses that and we don't have a switch for it.
7943 ;(define_insn "ffsdi2"
7944 ; [(set (match_operand:DI 0 "register_operand" "=&r")
7945 ; (ffs:DI (match_operand:DI 1 "register_operand" "r")))
7946 ; (clobber (match_scratch:DI 2 "=&r"))]
7948 ; "neg\t%1, %2\;xnor\t%1, %2, %2\;popc\t%2, %0\;movzr\t%1, 0, %0"
7949 ; [(set_attr "type" "multi")
7950 ; (set_attr "length" "4")])
7954 ;; Peepholes go at the end.
7956 ;; Optimize consecutive loads or stores into ldd and std when possible.
7957 ;; The conditions in which we do this are very restricted and are
7958 ;; explained in the code for {registers,memory}_ok_for_ldd functions.
7961 [(set (match_operand:SI 0 "memory_operand" "")
7963 (set (match_operand:SI 1 "memory_operand" "")
7966 && mems_ok_for_ldd_peep (operands[0], operands[1], NULL_RTX)"
7969 "operands[0] = widen_memory_access (operands[0], DImode, 0);")
7972 [(set (match_operand:SI 0 "memory_operand" "")
7974 (set (match_operand:SI 1 "memory_operand" "")
7977 && mems_ok_for_ldd_peep (operands[1], operands[0], NULL_RTX)"
7980 "operands[1] = widen_memory_access (operands[1], DImode, 0);")
7983 [(set (match_operand:SI 0 "register_operand" "")
7984 (match_operand:SI 1 "memory_operand" ""))
7985 (set (match_operand:SI 2 "register_operand" "")
7986 (match_operand:SI 3 "memory_operand" ""))]
7987 "registers_ok_for_ldd_peep (operands[0], operands[2])
7988 && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
7991 "operands[1] = widen_memory_access (operands[1], DImode, 0);
7992 operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));")
7995 [(set (match_operand:SI 0 "memory_operand" "")
7996 (match_operand:SI 1 "register_operand" ""))
7997 (set (match_operand:SI 2 "memory_operand" "")
7998 (match_operand:SI 3 "register_operand" ""))]
7999 "registers_ok_for_ldd_peep (operands[1], operands[3])
8000 && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
8003 "operands[0] = widen_memory_access (operands[0], DImode, 0);
8004 operands[1] = gen_rtx_REG (DImode, REGNO (operands[1]));")
8007 [(set (match_operand:SF 0 "register_operand" "")
8008 (match_operand:SF 1 "memory_operand" ""))
8009 (set (match_operand:SF 2 "register_operand" "")
8010 (match_operand:SF 3 "memory_operand" ""))]
8011 "registers_ok_for_ldd_peep (operands[0], operands[2])
8012 && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
8015 "operands[1] = widen_memory_access (operands[1], DFmode, 0);
8016 operands[0] = gen_rtx_REG (DFmode, REGNO (operands[0]));")
8019 [(set (match_operand:SF 0 "memory_operand" "")
8020 (match_operand:SF 1 "register_operand" ""))
8021 (set (match_operand:SF 2 "memory_operand" "")
8022 (match_operand:SF 3 "register_operand" ""))]
8023 "registers_ok_for_ldd_peep (operands[1], operands[3])
8024 && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
8027 "operands[0] = widen_memory_access (operands[0], DFmode, 0);
8028 operands[1] = gen_rtx_REG (DFmode, REGNO (operands[1]));")
8031 [(set (match_operand:SI 0 "register_operand" "")
8032 (match_operand:SI 1 "memory_operand" ""))
8033 (set (match_operand:SI 2 "register_operand" "")
8034 (match_operand:SI 3 "memory_operand" ""))]
8035 "registers_ok_for_ldd_peep (operands[2], operands[0])
8036 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
8039 "operands[3] = widen_memory_access (operands[3], DImode, 0);
8040 operands[2] = gen_rtx_REG (DImode, REGNO (operands[2]));")
8043 [(set (match_operand:SI 0 "memory_operand" "")
8044 (match_operand:SI 1 "register_operand" ""))
8045 (set (match_operand:SI 2 "memory_operand" "")
8046 (match_operand:SI 3 "register_operand" ""))]
8047 "registers_ok_for_ldd_peep (operands[3], operands[1])
8048 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
8051 "operands[2] = widen_memory_access (operands[2], DImode, 0);
8052 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
8056 [(set (match_operand:SF 0 "register_operand" "")
8057 (match_operand:SF 1 "memory_operand" ""))
8058 (set (match_operand:SF 2 "register_operand" "")
8059 (match_operand:SF 3 "memory_operand" ""))]
8060 "registers_ok_for_ldd_peep (operands[2], operands[0])
8061 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
8064 "operands[3] = widen_memory_access (operands[3], DFmode, 0);
8065 operands[2] = gen_rtx_REG (DFmode, REGNO (operands[2]));")
8068 [(set (match_operand:SF 0 "memory_operand" "")
8069 (match_operand:SF 1 "register_operand" ""))
8070 (set (match_operand:SF 2 "memory_operand" "")
8071 (match_operand:SF 3 "register_operand" ""))]
8072 "registers_ok_for_ldd_peep (operands[3], operands[1])
8073 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
8076 "operands[2] = widen_memory_access (operands[2], DFmode, 0);
8077 operands[3] = gen_rtx_REG (DFmode, REGNO (operands[3]));")
8079 ;; Optimize the case of following a reg-reg move with a test
8080 ;; of reg just moved. Don't allow floating point regs for operand 0 or 1.
8081 ;; This can result from a float to fix conversion.
8084 [(set (match_operand:SI 0 "register_operand" "")
8085 (match_operand:SI 1 "register_operand" ""))
8087 (compare:CC (match_operand:SI 2 "register_operand" "")
8089 "(rtx_equal_p (operands[2], operands[0])
8090 || rtx_equal_p (operands[2], operands[1]))
8091 && ! SPARC_FP_REG_P (REGNO (operands[0]))
8092 && ! SPARC_FP_REG_P (REGNO (operands[1]))"
8093 [(parallel [(set (match_dup 0) (match_dup 1))
8095 (compare:CC (match_dup 1) (const_int 0)))])]
8099 [(set (match_operand:DI 0 "register_operand" "")
8100 (match_operand:DI 1 "register_operand" ""))
8102 (compare:CCX (match_operand:DI 2 "register_operand" "")
8105 && (rtx_equal_p (operands[2], operands[0])
8106 || rtx_equal_p (operands[2], operands[1]))
8107 && ! SPARC_FP_REG_P (REGNO (operands[0]))
8108 && ! SPARC_FP_REG_P (REGNO (operands[1]))"
8109 [(parallel [(set (match_dup 0) (match_dup 1))
8111 (compare:CCX (match_dup 1) (const_int 0)))])]
8114 ;; ??? UltraSPARC-III note: A memory operation loading into the floating point register
8115 ;; ??? file, if it hits the prefetch cache, has a chance to dual-issue with other memory
8116 ;; ??? operations. With DFA we might be able to model this, but it requires a lot of
8118 (define_expand "prefetch"
8119 [(match_operand 0 "address_operand" "")
8120 (match_operand 1 "const_int_operand" "")
8121 (match_operand 2 "const_int_operand" "")]
8125 emit_insn (gen_prefetch_64 (operands[0], operands[1], operands[2]));
8127 emit_insn (gen_prefetch_32 (operands[0], operands[1], operands[2]));
8131 (define_insn "prefetch_64"
8132 [(prefetch (match_operand:DI 0 "address_operand" "p")
8133 (match_operand:DI 1 "const_int_operand" "n")
8134 (match_operand:DI 2 "const_int_operand" "n"))]
8137 static const char * const prefetch_instr[2][2] = {
8139 "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
8140 "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
8143 "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
8144 "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
8147 int read_or_write = INTVAL (operands[1]);
8148 int locality = INTVAL (operands[2]);
8150 if (read_or_write != 0 && read_or_write != 1)
8152 if (locality < 0 || locality > 3)
8154 return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
8156 [(set_attr "type" "load")])
8158 (define_insn "prefetch_32"
8159 [(prefetch (match_operand:SI 0 "address_operand" "p")
8160 (match_operand:SI 1 "const_int_operand" "n")
8161 (match_operand:SI 2 "const_int_operand" "n"))]
8164 static const char * const prefetch_instr[2][2] = {
8166 "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
8167 "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
8170 "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
8171 "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
8174 int read_or_write = INTVAL (operands[1]);
8175 int locality = INTVAL (operands[2]);
8177 if (read_or_write != 0 && read_or_write != 1)
8179 if (locality < 0 || locality > 3)
8181 return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
8183 [(set_attr "type" "load")])
8186 [(trap_if (const_int 1) (const_int 5))]
8189 [(set_attr "type" "trap")])
8191 (define_expand "conditional_trap"
8192 [(trap_if (match_operator 0 "noov_compare_op"
8193 [(match_dup 2) (match_dup 3)])
8194 (match_operand:SI 1 "arith_operand" ""))]
8196 "operands[2] = gen_compare_reg (GET_CODE (operands[0]),
8197 sparc_compare_op0, sparc_compare_op1);
8198 operands[3] = const0_rtx;")
8201 [(trap_if (match_operator 0 "noov_compare_op" [(reg:CC 100) (const_int 0)])
8202 (match_operand:SI 1 "arith_operand" "rM"))]
8205 [(set_attr "type" "trap")])
8208 [(trap_if (match_operator 0 "noov_compare_op" [(reg:CCX 100) (const_int 0)])
8209 (match_operand:SI 1 "arith_operand" "rM"))]
8212 [(set_attr "type" "trap")])
8215 (define_insn "tgd_hi22"
8216 [(set (match_operand:SI 0 "register_operand" "=r")
8217 (high:SI (unspec:SI [(match_operand 1 "tgd_symbolic_operand" "")]
8220 "sethi\\t%%tgd_hi22(%a1), %0")
8222 (define_insn "tgd_lo10"
8223 [(set (match_operand:SI 0 "register_operand" "=r")
8224 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
8225 (unspec:SI [(match_operand 2 "tgd_symbolic_operand" "")]
8228 "add\\t%1, %%tgd_lo10(%a2), %0")
8230 (define_insn "tgd_add32"
8231 [(set (match_operand:SI 0 "register_operand" "=r")
8232 (plus:SI (match_operand:SI 1 "register_operand" "r")
8233 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8234 (match_operand 3 "tgd_symbolic_operand" "")]
8236 "TARGET_TLS && TARGET_ARCH32"
8237 "add\\t%1, %2, %0, %%tgd_add(%a3)")
8239 (define_insn "tgd_add64"
8240 [(set (match_operand:DI 0 "register_operand" "=r")
8241 (plus:DI (match_operand:DI 1 "register_operand" "r")
8242 (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8243 (match_operand 3 "tgd_symbolic_operand" "")]
8245 "TARGET_TLS && TARGET_ARCH64"
8246 "add\\t%1, %2, %0, %%tgd_add(%a3)")
8248 (define_insn "tgd_call32"
8249 [(set (match_operand 0 "register_operand" "=r")
8250 (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")
8251 (match_operand 2 "tgd_symbolic_operand" "")]
8253 (match_operand 3 "" "")))
8254 (clobber (reg:SI 15))]
8255 "TARGET_TLS && TARGET_ARCH32"
8256 "call\t%a1, %%tgd_call(%a2)%#"
8257 [(set_attr "type" "call")])
8259 (define_insn "tgd_call64"
8260 [(set (match_operand 0 "register_operand" "=r")
8261 (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")
8262 (match_operand 2 "tgd_symbolic_operand" "")]
8264 (match_operand 3 "" "")))
8265 (clobber (reg:DI 15))]
8266 "TARGET_TLS && TARGET_ARCH64"
8267 "call\t%a1, %%tgd_call(%a2)%#"
8268 [(set_attr "type" "call")])
8270 (define_insn "tldm_hi22"
8271 [(set (match_operand:SI 0 "register_operand" "=r")
8272 (high:SI (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
8274 "sethi\\t%%tldm_hi22(%&), %0")
8276 (define_insn "tldm_lo10"
8277 [(set (match_operand:SI 0 "register_operand" "=r")
8278 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
8279 (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
8281 "add\\t%1, %%tldm_lo10(%&), %0")
8283 (define_insn "tldm_add32"
8284 [(set (match_operand:SI 0 "register_operand" "=r")
8285 (plus:SI (match_operand:SI 1 "register_operand" "r")
8286 (unspec:SI [(match_operand:SI 2 "register_operand" "r")]
8288 "TARGET_TLS && TARGET_ARCH32"
8289 "add\\t%1, %2, %0, %%tldm_add(%&)")
8291 (define_insn "tldm_add64"
8292 [(set (match_operand:DI 0 "register_operand" "=r")
8293 (plus:DI (match_operand:DI 1 "register_operand" "r")
8294 (unspec:DI [(match_operand:SI 2 "register_operand" "r")]
8296 "TARGET_TLS && TARGET_ARCH64"
8297 "add\\t%1, %2, %0, %%tldm_add(%&)")
8299 (define_insn "tldm_call32"
8300 [(set (match_operand 0 "register_operand" "=r")
8301 (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")]
8303 (match_operand 2 "" "")))
8304 (clobber (reg:SI 15))]
8305 "TARGET_TLS && TARGET_ARCH32"
8306 "call\t%a1, %%tldm_call(%&)%#"
8307 [(set_attr "type" "call")])
8309 (define_insn "tldm_call64"
8310 [(set (match_operand 0 "register_operand" "=r")
8311 (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")]
8313 (match_operand 2 "" "")))
8314 (clobber (reg:DI 15))]
8315 "TARGET_TLS && TARGET_ARCH64"
8316 "call\t%a1, %%tldm_call(%&)%#"
8317 [(set_attr "type" "call")])
8319 (define_insn "tldo_hix22"
8320 [(set (match_operand:SI 0 "register_operand" "=r")
8321 (high:SI (unspec:SI [(match_operand 1 "tld_symbolic_operand" "")]
8324 "sethi\\t%%tldo_hix22(%a1), %0")
8326 (define_insn "tldo_lox10"
8327 [(set (match_operand:SI 0 "register_operand" "=r")
8328 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
8329 (unspec:SI [(match_operand 2 "tld_symbolic_operand" "")]
8332 "xor\\t%1, %%tldo_lox10(%a2), %0")
8334 (define_insn "tldo_add32"
8335 [(set (match_operand:SI 0 "register_operand" "=r")
8336 (plus:SI (match_operand:SI 1 "register_operand" "r")
8337 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8338 (match_operand 3 "tld_symbolic_operand" "")]
8340 "TARGET_TLS && TARGET_ARCH32"
8341 "add\\t%1, %2, %0, %%tldo_add(%a3)")
8343 (define_insn "tldo_add64"
8344 [(set (match_operand:DI 0 "register_operand" "=r")
8345 (plus:DI (match_operand:DI 1 "register_operand" "r")
8346 (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8347 (match_operand 3 "tld_symbolic_operand" "")]
8349 "TARGET_TLS && TARGET_ARCH64"
8350 "add\\t%1, %2, %0, %%tldo_add(%a3)")
8352 (define_insn "tie_hi22"
8353 [(set (match_operand:SI 0 "register_operand" "=r")
8354 (high:SI (unspec:SI [(match_operand 1 "tie_symbolic_operand" "")]
8357 "sethi\\t%%tie_hi22(%a1), %0")
8359 (define_insn "tie_lo10"
8360 [(set (match_operand:SI 0 "register_operand" "=r")
8361 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
8362 (unspec:SI [(match_operand 2 "tie_symbolic_operand" "")]
8365 "add\\t%1, %%tie_lo10(%a2), %0")
8367 (define_insn "tie_ld32"
8368 [(set (match_operand:SI 0 "register_operand" "=r")
8369 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
8370 (match_operand:SI 2 "register_operand" "r")
8371 (match_operand 3 "tie_symbolic_operand" "")]
8373 "TARGET_TLS && TARGET_ARCH32"
8374 "ld\\t[%1 + %2], %0, %%tie_ld(%a3)"
8375 [(set_attr "type" "load")])
8377 (define_insn "tie_ld64"
8378 [(set (match_operand:DI 0 "register_operand" "=r")
8379 (unspec:DI [(match_operand:DI 1 "register_operand" "r")
8380 (match_operand:SI 2 "register_operand" "r")
8381 (match_operand 3 "tie_symbolic_operand" "")]
8383 "TARGET_TLS && TARGET_ARCH64"
8384 "ldx\\t[%1 + %2], %0, %%tie_ldx(%a3)"
8385 [(set_attr "type" "load")])
8387 (define_insn "tie_add32"
8388 [(set (match_operand:SI 0 "register_operand" "=r")
8389 (plus:SI (match_operand:SI 1 "register_operand" "r")
8390 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8391 (match_operand 3 "tie_symbolic_operand" "")]
8393 "TARGET_SUN_TLS && TARGET_ARCH32"
8394 "add\\t%1, %2, %0, %%tie_add(%a3)")
8396 (define_insn "tie_add64"
8397 [(set (match_operand:DI 0 "register_operand" "=r")
8398 (plus:DI (match_operand:DI 1 "register_operand" "r")
8399 (unspec:DI [(match_operand:DI 2 "register_operand" "r")
8400 (match_operand 3 "tie_symbolic_operand" "")]
8402 "TARGET_SUN_TLS && TARGET_ARCH64"
8403 "add\\t%1, %2, %0, %%tie_add(%a3)")
8405 (define_insn "tle_hix22_sp32"
8406 [(set (match_operand:SI 0 "register_operand" "=r")
8407 (high:SI (unspec:SI [(match_operand 1 "tle_symbolic_operand" "")]
8409 "TARGET_TLS && TARGET_ARCH32"
8410 "sethi\\t%%tle_hix22(%a1), %0")
8412 (define_insn "tle_lox10_sp32"
8413 [(set (match_operand:SI 0 "register_operand" "=r")
8414 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
8415 (unspec:SI [(match_operand 2 "tle_symbolic_operand" "")]
8417 "TARGET_TLS && TARGET_ARCH32"
8418 "xor\\t%1, %%tle_lox10(%a2), %0")
8420 (define_insn "tle_hix22_sp64"
8421 [(set (match_operand:DI 0 "register_operand" "=r")
8422 (high:DI (unspec:DI [(match_operand 1 "tle_symbolic_operand" "")]
8424 "TARGET_TLS && TARGET_ARCH64"
8425 "sethi\\t%%tle_hix22(%a1), %0")
8427 (define_insn "tle_lox10_sp64"
8428 [(set (match_operand:DI 0 "register_operand" "=r")
8429 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
8430 (unspec:DI [(match_operand 2 "tle_symbolic_operand" "")]
8432 "TARGET_TLS && TARGET_ARCH64"
8433 "xor\\t%1, %%tle_lox10(%a2), %0")
8435 ;; Now patterns combining tldo_add{32,64} with some integer loads or stores
8436 (define_insn "*tldo_ldub_sp32"
8437 [(set (match_operand:QI 0 "register_operand" "=r")
8438 (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8439 (match_operand 3 "tld_symbolic_operand" "")]
8441 (match_operand:SI 1 "register_operand" "r"))))]
8442 "TARGET_TLS && TARGET_ARCH32"
8443 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8444 [(set_attr "type" "load")
8445 (set_attr "us3load_type" "3cycle")])
8447 (define_insn "*tldo_ldub1_sp32"
8448 [(set (match_operand:HI 0 "register_operand" "=r")
8449 (zero_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8450 (match_operand 3 "tld_symbolic_operand" "")]
8452 (match_operand:SI 1 "register_operand" "r")))))]
8453 "TARGET_TLS && TARGET_ARCH32"
8454 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8455 [(set_attr "type" "load")
8456 (set_attr "us3load_type" "3cycle")])
8458 (define_insn "*tldo_ldub2_sp32"
8459 [(set (match_operand:SI 0 "register_operand" "=r")
8460 (zero_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8461 (match_operand 3 "tld_symbolic_operand" "")]
8463 (match_operand:SI 1 "register_operand" "r")))))]
8464 "TARGET_TLS && TARGET_ARCH32"
8465 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8466 [(set_attr "type" "load")
8467 (set_attr "us3load_type" "3cycle")])
8469 (define_insn "*tldo_ldsb1_sp32"
8470 [(set (match_operand:HI 0 "register_operand" "=r")
8471 (sign_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8472 (match_operand 3 "tld_symbolic_operand" "")]
8474 (match_operand:SI 1 "register_operand" "r")))))]
8475 "TARGET_TLS && TARGET_ARCH32"
8476 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
8477 [(set_attr "type" "sload")
8478 (set_attr "us3load_type" "3cycle")])
8480 (define_insn "*tldo_ldsb2_sp32"
8481 [(set (match_operand:SI 0 "register_operand" "=r")
8482 (sign_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8483 (match_operand 3 "tld_symbolic_operand" "")]
8485 (match_operand:SI 1 "register_operand" "r")))))]
8486 "TARGET_TLS && TARGET_ARCH32"
8487 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
8488 [(set_attr "type" "sload")
8489 (set_attr "us3load_type" "3cycle")])
8491 (define_insn "*tldo_ldub_sp64"
8492 [(set (match_operand:QI 0 "register_operand" "=r")
8493 (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8494 (match_operand 3 "tld_symbolic_operand" "")]
8496 (match_operand:DI 1 "register_operand" "r"))))]
8497 "TARGET_TLS && TARGET_ARCH64"
8498 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8499 [(set_attr "type" "load")
8500 (set_attr "us3load_type" "3cycle")])
8502 (define_insn "*tldo_ldub1_sp64"
8503 [(set (match_operand:HI 0 "register_operand" "=r")
8504 (zero_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8505 (match_operand 3 "tld_symbolic_operand" "")]
8507 (match_operand:DI 1 "register_operand" "r")))))]
8508 "TARGET_TLS && TARGET_ARCH64"
8509 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8510 [(set_attr "type" "load")
8511 (set_attr "us3load_type" "3cycle")])
8513 (define_insn "*tldo_ldub2_sp64"
8514 [(set (match_operand:SI 0 "register_operand" "=r")
8515 (zero_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8516 (match_operand 3 "tld_symbolic_operand" "")]
8518 (match_operand:DI 1 "register_operand" "r")))))]
8519 "TARGET_TLS && TARGET_ARCH64"
8520 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8521 [(set_attr "type" "load")
8522 (set_attr "us3load_type" "3cycle")])
8524 (define_insn "*tldo_ldub3_sp64"
8525 [(set (match_operand:DI 0 "register_operand" "=r")
8526 (zero_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8527 (match_operand 3 "tld_symbolic_operand" "")]
8529 (match_operand:DI 1 "register_operand" "r")))))]
8530 "TARGET_TLS && TARGET_ARCH64"
8531 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8532 [(set_attr "type" "load")
8533 (set_attr "us3load_type" "3cycle")])
8535 (define_insn "*tldo_ldsb1_sp64"
8536 [(set (match_operand:HI 0 "register_operand" "=r")
8537 (sign_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8538 (match_operand 3 "tld_symbolic_operand" "")]
8540 (match_operand:DI 1 "register_operand" "r")))))]
8541 "TARGET_TLS && TARGET_ARCH64"
8542 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
8543 [(set_attr "type" "sload")
8544 (set_attr "us3load_type" "3cycle")])
8546 (define_insn "*tldo_ldsb2_sp64"
8547 [(set (match_operand:SI 0 "register_operand" "=r")
8548 (sign_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8549 (match_operand 3 "tld_symbolic_operand" "")]
8551 (match_operand:DI 1 "register_operand" "r")))))]
8552 "TARGET_TLS && TARGET_ARCH64"
8553 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
8554 [(set_attr "type" "sload")
8555 (set_attr "us3load_type" "3cycle")])
8557 (define_insn "*tldo_ldsb3_sp64"
8558 [(set (match_operand:DI 0 "register_operand" "=r")
8559 (sign_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8560 (match_operand 3 "tld_symbolic_operand" "")]
8562 (match_operand:DI 1 "register_operand" "r")))))]
8563 "TARGET_TLS && TARGET_ARCH64"
8564 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
8565 [(set_attr "type" "sload")
8566 (set_attr "us3load_type" "3cycle")])
8568 (define_insn "*tldo_lduh_sp32"
8569 [(set (match_operand:HI 0 "register_operand" "=r")
8570 (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8571 (match_operand 3 "tld_symbolic_operand" "")]
8573 (match_operand:SI 1 "register_operand" "r"))))]
8574 "TARGET_TLS && TARGET_ARCH32"
8575 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
8576 [(set_attr "type" "load")
8577 (set_attr "us3load_type" "3cycle")])
8579 (define_insn "*tldo_lduh1_sp32"
8580 [(set (match_operand:SI 0 "register_operand" "=r")
8581 (zero_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8582 (match_operand 3 "tld_symbolic_operand" "")]
8584 (match_operand:SI 1 "register_operand" "r")))))]
8585 "TARGET_TLS && TARGET_ARCH32"
8586 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
8587 [(set_attr "type" "load")
8588 (set_attr "us3load_type" "3cycle")])
8590 (define_insn "*tldo_ldsh1_sp32"
8591 [(set (match_operand:SI 0 "register_operand" "=r")
8592 (sign_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8593 (match_operand 3 "tld_symbolic_operand" "")]
8595 (match_operand:SI 1 "register_operand" "r")))))]
8596 "TARGET_TLS && TARGET_ARCH32"
8597 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
8598 [(set_attr "type" "sload")
8599 (set_attr "us3load_type" "3cycle")])
8601 (define_insn "*tldo_lduh_sp64"
8602 [(set (match_operand:HI 0 "register_operand" "=r")
8603 (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8604 (match_operand 3 "tld_symbolic_operand" "")]
8606 (match_operand:DI 1 "register_operand" "r"))))]
8607 "TARGET_TLS && TARGET_ARCH64"
8608 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
8609 [(set_attr "type" "load")
8610 (set_attr "us3load_type" "3cycle")])
8612 (define_insn "*tldo_lduh1_sp64"
8613 [(set (match_operand:SI 0 "register_operand" "=r")
8614 (zero_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8615 (match_operand 3 "tld_symbolic_operand" "")]
8617 (match_operand:DI 1 "register_operand" "r")))))]
8618 "TARGET_TLS && TARGET_ARCH64"
8619 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
8620 [(set_attr "type" "load")
8621 (set_attr "us3load_type" "3cycle")])
8623 (define_insn "*tldo_lduh2_sp64"
8624 [(set (match_operand:DI 0 "register_operand" "=r")
8625 (zero_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8626 (match_operand 3 "tld_symbolic_operand" "")]
8628 (match_operand:DI 1 "register_operand" "r")))))]
8629 "TARGET_TLS && TARGET_ARCH64"
8630 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
8631 [(set_attr "type" "load")
8632 (set_attr "us3load_type" "3cycle")])
8634 (define_insn "*tldo_ldsh1_sp64"
8635 [(set (match_operand:SI 0 "register_operand" "=r")
8636 (sign_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8637 (match_operand 3 "tld_symbolic_operand" "")]
8639 (match_operand:DI 1 "register_operand" "r")))))]
8640 "TARGET_TLS && TARGET_ARCH64"
8641 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
8642 [(set_attr "type" "sload")
8643 (set_attr "us3load_type" "3cycle")])
8645 (define_insn "*tldo_ldsh2_sp64"
8646 [(set (match_operand:DI 0 "register_operand" "=r")
8647 (sign_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8648 (match_operand 3 "tld_symbolic_operand" "")]
8650 (match_operand:DI 1 "register_operand" "r")))))]
8651 "TARGET_TLS && TARGET_ARCH64"
8652 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
8653 [(set_attr "type" "sload")
8654 (set_attr "us3load_type" "3cycle")])
8656 (define_insn "*tldo_lduw_sp32"
8657 [(set (match_operand:SI 0 "register_operand" "=r")
8658 (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8659 (match_operand 3 "tld_symbolic_operand" "")]
8661 (match_operand:SI 1 "register_operand" "r"))))]
8662 "TARGET_TLS && TARGET_ARCH32"
8663 "ld\t[%1 + %2], %0, %%tldo_add(%3)"
8664 [(set_attr "type" "load")])
8666 (define_insn "*tldo_lduw_sp64"
8667 [(set (match_operand:SI 0 "register_operand" "=r")
8668 (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8669 (match_operand 3 "tld_symbolic_operand" "")]
8671 (match_operand:DI 1 "register_operand" "r"))))]
8672 "TARGET_TLS && TARGET_ARCH64"
8673 "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
8674 [(set_attr "type" "load")])
8676 (define_insn "*tldo_lduw1_sp64"
8677 [(set (match_operand:DI 0 "register_operand" "=r")
8678 (zero_extend:DI (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8679 (match_operand 3 "tld_symbolic_operand" "")]
8681 (match_operand:DI 1 "register_operand" "r")))))]
8682 "TARGET_TLS && TARGET_ARCH64"
8683 "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
8684 [(set_attr "type" "load")])
8686 (define_insn "*tldo_ldsw1_sp64"
8687 [(set (match_operand:DI 0 "register_operand" "=r")
8688 (sign_extend:DI (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8689 (match_operand 3 "tld_symbolic_operand" "")]
8691 (match_operand:DI 1 "register_operand" "r")))))]
8692 "TARGET_TLS && TARGET_ARCH64"
8693 "ldsw\t[%1 + %2], %0, %%tldo_add(%3)"
8694 [(set_attr "type" "sload")
8695 (set_attr "us3load_type" "3cycle")])
8697 (define_insn "*tldo_ldx_sp64"
8698 [(set (match_operand:DI 0 "register_operand" "=r")
8699 (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8700 (match_operand 3 "tld_symbolic_operand" "")]
8702 (match_operand:DI 1 "register_operand" "r"))))]
8703 "TARGET_TLS && TARGET_ARCH64"
8704 "ldx\t[%1 + %2], %0, %%tldo_add(%3)"
8705 [(set_attr "type" "load")])
8707 (define_insn "*tldo_stb_sp32"
8708 [(set (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8709 (match_operand 3 "tld_symbolic_operand" "")]
8711 (match_operand:SI 1 "register_operand" "r")))
8712 (match_operand:QI 0 "register_operand" "=r"))]
8713 "TARGET_TLS && TARGET_ARCH32"
8714 "stb\t%0, [%1 + %2], %%tldo_add(%3)"
8715 [(set_attr "type" "store")])
8717 (define_insn "*tldo_stb_sp64"
8718 [(set (mem:QI (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 (match_operand:QI 0 "register_operand" "=r"))]
8723 "TARGET_TLS && TARGET_ARCH64"
8724 "stb\t%0, [%1 + %2], %%tldo_add(%3)"
8725 [(set_attr "type" "store")])
8727 (define_insn "*tldo_sth_sp32"
8728 [(set (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8729 (match_operand 3 "tld_symbolic_operand" "")]
8731 (match_operand:SI 1 "register_operand" "r")))
8732 (match_operand:HI 0 "register_operand" "=r"))]
8733 "TARGET_TLS && TARGET_ARCH32"
8734 "sth\t%0, [%1 + %2], %%tldo_add(%3)"
8735 [(set_attr "type" "store")])
8737 (define_insn "*tldo_sth_sp64"
8738 [(set (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8739 (match_operand 3 "tld_symbolic_operand" "")]
8741 (match_operand:DI 1 "register_operand" "r")))
8742 (match_operand:HI 0 "register_operand" "=r"))]
8743 "TARGET_TLS && TARGET_ARCH64"
8744 "sth\t%0, [%1 + %2], %%tldo_add(%3)"
8745 [(set_attr "type" "store")])
8747 (define_insn "*tldo_stw_sp32"
8748 [(set (mem:SI (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:SI 0 "register_operand" "=r"))]
8753 "TARGET_TLS && TARGET_ARCH32"
8754 "st\t%0, [%1 + %2], %%tldo_add(%3)"
8755 [(set_attr "type" "store")])
8757 (define_insn "*tldo_stw_sp64"
8758 [(set (mem:SI (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:SI 0 "register_operand" "=r"))]
8763 "TARGET_TLS && TARGET_ARCH64"
8764 "stw\t%0, [%1 + %2], %%tldo_add(%3)"
8765 [(set_attr "type" "store")])
8767 (define_insn "*tldo_stx_sp64"
8768 [(set (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8769 (match_operand 3 "tld_symbolic_operand" "")]
8771 (match_operand:DI 1 "register_operand" "r")))
8772 (match_operand:DI 0 "register_operand" "=r"))]
8773 "TARGET_TLS && TARGET_ARCH64"
8774 "stx\t%0, [%1 + %2], %%tldo_add(%3)"
8775 [(set_attr "type" "store")])