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, 2005 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)
71 ;; The upper 32 fp regs on the v9 can't hold SFmode values. To deal with this
72 ;; a second register class, EXTRA_FP_REGS, exists for the v9 chip. The name
73 ;; is a bit of a misnomer as it covers all 64 fp regs. The corresponding
74 ;; constraint letter is 'e'. To avoid any confusion, 'e' is used instead of
75 ;; 'f' for all DF/TFmode values, including those that are specific to the v8.
78 ;; Attribute for cpu type.
79 ;; These must match the values for enum processor_type in sparc.h.
86 hypersparc,sparclite86x,
91 (const (symbol_ref "sparc_cpu_attr")))
93 ;; Attribute for the instruction set.
94 ;; At present we only need to distinguish v9/!v9, but for clarity we
95 ;; test TARGET_V8 too.
96 (define_attr "isa" "v7,v8,v9,sparclet"
98 (cond [(symbol_ref "TARGET_V9") (const_string "v9")
99 (symbol_ref "TARGET_V8") (const_string "v8")
100 (symbol_ref "TARGET_SPARCLET") (const_string "sparclet")]
101 (const_string "v7"))))
107 uncond_branch,branch,call,sibcall,call_no_delay_slot,return,
115 fga,fgm_pack,fgm_mul,fgm_pdist,fgm_cmp,
118 multi,savew,flushw,iflush,trap"
119 (const_string "ialu"))
121 ;; True if branch/call has empty delay slot and will emit a nop in it
122 (define_attr "empty_delay_slot" "false,true"
123 (symbol_ref "empty_delay_slot (insn)"))
125 (define_attr "branch_type" "none,icc,fcc,reg"
126 (const_string "none"))
128 (define_attr "pic" "false,true"
129 (symbol_ref "flag_pic != 0"))
131 (define_attr "calls_alloca" "false,true"
132 (symbol_ref "current_function_calls_alloca != 0"))
134 (define_attr "calls_eh_return" "false,true"
135 (symbol_ref "current_function_calls_eh_return !=0 "))
137 (define_attr "leaf_function" "false,true"
138 (symbol_ref "current_function_uses_only_leaf_regs != 0"))
140 (define_attr "delayed_branch" "false,true"
141 (symbol_ref "flag_delayed_branch != 0"))
143 ;; Length (in # of insns).
144 ;; Beware that setting a length greater or equal to 3 for conditional branches
145 ;; has a side-effect (see output_cbranch and output_v9branch).
146 (define_attr "length" ""
147 (cond [(eq_attr "type" "uncond_branch,call")
148 (if_then_else (eq_attr "empty_delay_slot" "true")
151 (eq_attr "type" "sibcall")
152 (if_then_else (eq_attr "leaf_function" "true")
153 (if_then_else (eq_attr "empty_delay_slot" "true")
156 (if_then_else (eq_attr "empty_delay_slot" "true")
159 (eq_attr "branch_type" "icc")
160 (if_then_else (match_operand 0 "noov_compare64_operator" "")
161 (if_then_else (lt (pc) (match_dup 1))
162 (if_then_else (lt (minus (match_dup 1) (pc)) (const_int 260000))
163 (if_then_else (eq_attr "empty_delay_slot" "true")
166 (if_then_else (eq_attr "empty_delay_slot" "true")
169 (if_then_else (lt (minus (pc) (match_dup 1)) (const_int 260000))
170 (if_then_else (eq_attr "empty_delay_slot" "true")
173 (if_then_else (eq_attr "empty_delay_slot" "true")
176 (if_then_else (eq_attr "empty_delay_slot" "true")
179 (eq_attr "branch_type" "fcc")
180 (if_then_else (match_operand 0 "fcc0_register_operand" "")
181 (if_then_else (eq_attr "empty_delay_slot" "true")
182 (if_then_else (eq (symbol_ref "TARGET_V9") (const_int 0))
185 (if_then_else (eq (symbol_ref "TARGET_V9") (const_int 0))
188 (if_then_else (lt (pc) (match_dup 2))
189 (if_then_else (lt (minus (match_dup 2) (pc)) (const_int 260000))
190 (if_then_else (eq_attr "empty_delay_slot" "true")
193 (if_then_else (eq_attr "empty_delay_slot" "true")
196 (if_then_else (lt (minus (pc) (match_dup 2)) (const_int 260000))
197 (if_then_else (eq_attr "empty_delay_slot" "true")
200 (if_then_else (eq_attr "empty_delay_slot" "true")
203 (eq_attr "branch_type" "reg")
204 (if_then_else (lt (pc) (match_dup 2))
205 (if_then_else (lt (minus (match_dup 2) (pc)) (const_int 32000))
206 (if_then_else (eq_attr "empty_delay_slot" "true")
209 (if_then_else (eq_attr "empty_delay_slot" "true")
212 (if_then_else (lt (minus (pc) (match_dup 2)) (const_int 32000))
213 (if_then_else (eq_attr "empty_delay_slot" "true")
216 (if_then_else (eq_attr "empty_delay_slot" "true")
222 (define_attr "fptype" "single,double"
223 (const_string "single"))
225 ;; UltraSPARC-III integer load type.
226 (define_attr "us3load_type" "2cycle,3cycle"
227 (const_string "2cycle"))
229 (define_asm_attributes
230 [(set_attr "length" "2")
231 (set_attr "type" "multi")])
233 ;; Attributes for instruction and branch scheduling
234 (define_attr "tls_call_delay" "false,true"
235 (symbol_ref "tls_call_delay (insn)"))
237 (define_attr "in_call_delay" "false,true"
238 (cond [(eq_attr "type" "uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
239 (const_string "false")
240 (eq_attr "type" "load,fpload,store,fpstore")
241 (if_then_else (eq_attr "length" "1")
242 (const_string "true")
243 (const_string "false"))]
244 (if_then_else (and (eq_attr "length" "1")
245 (eq_attr "tls_call_delay" "true"))
246 (const_string "true")
247 (const_string "false"))))
249 (define_attr "eligible_for_sibcall_delay" "false,true"
250 (symbol_ref "eligible_for_sibcall_delay (insn)"))
252 (define_attr "eligible_for_return_delay" "false,true"
253 (symbol_ref "eligible_for_return_delay (insn)"))
255 ;; ??? !v9: Should implement the notion of predelay slots for floating-point
256 ;; branches. This would allow us to remove the nop always inserted before
257 ;; a floating point branch.
259 ;; ??? It is OK for fill_simple_delay_slots to put load/store instructions
260 ;; in a delay slot, but it is not OK for fill_eager_delay_slots to do so.
261 ;; This is because doing so will add several pipeline stalls to the path
262 ;; that the load/store did not come from. Unfortunately, there is no way
263 ;; to prevent fill_eager_delay_slots from using load/store without completely
264 ;; disabling them. For the SPEC benchmark set, this is a serious lose,
265 ;; because it prevents us from moving back the final store of inner loops.
267 (define_attr "in_branch_delay" "false,true"
268 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
269 (eq_attr "length" "1"))
270 (const_string "true")
271 (const_string "false")))
273 (define_attr "in_uncond_branch_delay" "false,true"
274 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
275 (eq_attr "length" "1"))
276 (const_string "true")
277 (const_string "false")))
279 (define_attr "in_annul_branch_delay" "false,true"
280 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
281 (eq_attr "length" "1"))
282 (const_string "true")
283 (const_string "false")))
285 (define_delay (eq_attr "type" "call")
286 [(eq_attr "in_call_delay" "true") (nil) (nil)])
288 (define_delay (eq_attr "type" "sibcall")
289 [(eq_attr "eligible_for_sibcall_delay" "true") (nil) (nil)])
291 (define_delay (eq_attr "type" "branch")
292 [(eq_attr "in_branch_delay" "true")
293 (nil) (eq_attr "in_annul_branch_delay" "true")])
295 (define_delay (eq_attr "type" "uncond_branch")
296 [(eq_attr "in_uncond_branch_delay" "true")
299 (define_delay (eq_attr "type" "return")
300 [(eq_attr "eligible_for_return_delay" "true") (nil) (nil)])
303 ;; Include SPARC DFA schedulers
305 (include "cypress.md")
306 (include "supersparc.md")
307 (include "hypersparc.md")
308 (include "sparclet.md")
309 (include "ultra1_2.md")
310 (include "ultra3.md")
313 ;; Operand and operator predicates.
315 (include "predicates.md")
318 ;; Compare instructions.
320 ;; We generate RTL for comparisons and branches by having the cmpxx
321 ;; patterns store away the operands. Then, the scc and bcc patterns
322 ;; emit RTL for both the compare and the branch.
324 ;; We do this because we want to generate different code for an sne and
325 ;; seq insn. In those cases, if the second operand of the compare is not
326 ;; const0_rtx, we want to compute the xor of the two operands and test
329 ;; We start with the DEFINE_EXPANDs, then the DEFINE_INSNs to match
330 ;; the patterns. Finally, we have the DEFINE_SPLITs for some of the scc
331 ;; insns that actually require more than one machine instruction.
333 (define_expand "cmpsi"
335 (compare:CC (match_operand:SI 0 "compare_operand" "")
336 (match_operand:SI 1 "arith_operand" "")))]
339 if (GET_CODE (operands[0]) == ZERO_EXTRACT && operands[1] != const0_rtx)
340 operands[0] = force_reg (SImode, operands[0]);
342 sparc_compare_op0 = operands[0];
343 sparc_compare_op1 = operands[1];
347 (define_expand "cmpdi"
349 (compare:CCX (match_operand:DI 0 "compare_operand" "")
350 (match_operand:DI 1 "arith_operand" "")))]
353 if (GET_CODE (operands[0]) == ZERO_EXTRACT && operands[1] != const0_rtx)
354 operands[0] = force_reg (DImode, operands[0]);
356 sparc_compare_op0 = operands[0];
357 sparc_compare_op1 = operands[1];
361 (define_expand "cmpsf"
362 ;; The 96 here isn't ever used by anyone.
364 (compare:CCFP (match_operand:SF 0 "register_operand" "")
365 (match_operand:SF 1 "register_operand" "")))]
368 sparc_compare_op0 = operands[0];
369 sparc_compare_op1 = operands[1];
373 (define_expand "cmpdf"
374 ;; The 96 here isn't ever used by anyone.
376 (compare:CCFP (match_operand:DF 0 "register_operand" "")
377 (match_operand:DF 1 "register_operand" "")))]
380 sparc_compare_op0 = operands[0];
381 sparc_compare_op1 = operands[1];
385 (define_expand "cmptf"
386 ;; The 96 here isn't ever used by anyone.
388 (compare:CCFP (match_operand:TF 0 "register_operand" "")
389 (match_operand:TF 1 "register_operand" "")))]
392 sparc_compare_op0 = operands[0];
393 sparc_compare_op1 = operands[1];
397 ;; Now the compare DEFINE_INSNs.
399 (define_insn "*cmpsi_insn"
401 (compare:CC (match_operand:SI 0 "register_operand" "r")
402 (match_operand:SI 1 "arith_operand" "rI")))]
405 [(set_attr "type" "compare")])
407 (define_insn "*cmpdi_sp64"
409 (compare:CCX (match_operand:DI 0 "register_operand" "r")
410 (match_operand:DI 1 "arith_operand" "rI")))]
413 [(set_attr "type" "compare")])
415 (define_insn "*cmpsf_fpe"
416 [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
417 (compare:CCFPE (match_operand:SF 1 "register_operand" "f")
418 (match_operand:SF 2 "register_operand" "f")))]
422 return "fcmpes\t%0, %1, %2";
423 return "fcmpes\t%1, %2";
425 [(set_attr "type" "fpcmp")])
427 (define_insn "*cmpdf_fpe"
428 [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
429 (compare:CCFPE (match_operand:DF 1 "register_operand" "e")
430 (match_operand:DF 2 "register_operand" "e")))]
434 return "fcmped\t%0, %1, %2";
435 return "fcmped\t%1, %2";
437 [(set_attr "type" "fpcmp")
438 (set_attr "fptype" "double")])
440 (define_insn "*cmptf_fpe"
441 [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
442 (compare:CCFPE (match_operand:TF 1 "register_operand" "e")
443 (match_operand:TF 2 "register_operand" "e")))]
444 "TARGET_FPU && TARGET_HARD_QUAD"
447 return "fcmpeq\t%0, %1, %2";
448 return "fcmpeq\t%1, %2";
450 [(set_attr "type" "fpcmp")])
452 (define_insn "*cmpsf_fp"
453 [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
454 (compare:CCFP (match_operand:SF 1 "register_operand" "f")
455 (match_operand:SF 2 "register_operand" "f")))]
459 return "fcmps\t%0, %1, %2";
460 return "fcmps\t%1, %2";
462 [(set_attr "type" "fpcmp")])
464 (define_insn "*cmpdf_fp"
465 [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
466 (compare:CCFP (match_operand:DF 1 "register_operand" "e")
467 (match_operand:DF 2 "register_operand" "e")))]
471 return "fcmpd\t%0, %1, %2";
472 return "fcmpd\t%1, %2";
474 [(set_attr "type" "fpcmp")
475 (set_attr "fptype" "double")])
477 (define_insn "*cmptf_fp"
478 [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
479 (compare:CCFP (match_operand:TF 1 "register_operand" "e")
480 (match_operand:TF 2 "register_operand" "e")))]
481 "TARGET_FPU && TARGET_HARD_QUAD"
484 return "fcmpq\t%0, %1, %2";
485 return "fcmpq\t%1, %2";
487 [(set_attr "type" "fpcmp")])
489 ;; Next come the scc insns. For seq, sne, sgeu, and sltu, we can do this
490 ;; without jumps using the addx/subx instructions. For seq/sne on v9 we use
491 ;; the same code as v8 (the addx/subx method has more applications). The
492 ;; exception to this is "reg != 0" which can be done in one instruction on v9
493 ;; (so we do it). For the rest, on v9 we use conditional moves; on v8, we do
496 ;; Seq_special[_xxx] and sne_special[_xxx] clobber the CC reg, because they
497 ;; generate addcc/subcc instructions.
499 (define_expand "seqsi_special"
501 (xor:SI (match_operand:SI 1 "register_operand" "")
502 (match_operand:SI 2 "register_operand" "")))
503 (parallel [(set (match_operand:SI 0 "register_operand" "")
504 (eq:SI (match_dup 3) (const_int 0)))
505 (clobber (reg:CC 100))])]
507 { operands[3] = gen_reg_rtx (SImode); })
509 (define_expand "seqdi_special"
511 (xor:DI (match_operand:DI 1 "register_operand" "")
512 (match_operand:DI 2 "register_operand" "")))
513 (set (match_operand:DI 0 "register_operand" "")
514 (eq:DI (match_dup 3) (const_int 0)))]
516 { operands[3] = gen_reg_rtx (DImode); })
518 (define_expand "snesi_special"
520 (xor:SI (match_operand:SI 1 "register_operand" "")
521 (match_operand:SI 2 "register_operand" "")))
522 (parallel [(set (match_operand:SI 0 "register_operand" "")
523 (ne:SI (match_dup 3) (const_int 0)))
524 (clobber (reg:CC 100))])]
526 { operands[3] = gen_reg_rtx (SImode); })
528 (define_expand "snedi_special"
530 (xor:DI (match_operand:DI 1 "register_operand" "")
531 (match_operand:DI 2 "register_operand" "")))
532 (set (match_operand:DI 0 "register_operand" "")
533 (ne:DI (match_dup 3) (const_int 0)))]
535 { operands[3] = gen_reg_rtx (DImode); })
537 (define_expand "seqdi_special_trunc"
539 (xor:DI (match_operand:DI 1 "register_operand" "")
540 (match_operand:DI 2 "register_operand" "")))
541 (set (match_operand:SI 0 "register_operand" "")
542 (eq:SI (match_dup 3) (const_int 0)))]
544 { operands[3] = gen_reg_rtx (DImode); })
546 (define_expand "snedi_special_trunc"
548 (xor:DI (match_operand:DI 1 "register_operand" "")
549 (match_operand:DI 2 "register_operand" "")))
550 (set (match_operand:SI 0 "register_operand" "")
551 (ne:SI (match_dup 3) (const_int 0)))]
553 { operands[3] = gen_reg_rtx (DImode); })
555 (define_expand "seqsi_special_extend"
557 (xor:SI (match_operand:SI 1 "register_operand" "")
558 (match_operand:SI 2 "register_operand" "")))
559 (parallel [(set (match_operand:DI 0 "register_operand" "")
560 (eq:DI (match_dup 3) (const_int 0)))
561 (clobber (reg:CC 100))])]
563 { operands[3] = gen_reg_rtx (SImode); })
565 (define_expand "snesi_special_extend"
567 (xor:SI (match_operand:SI 1 "register_operand" "")
568 (match_operand:SI 2 "register_operand" "")))
569 (parallel [(set (match_operand:DI 0 "register_operand" "")
570 (ne:DI (match_dup 3) (const_int 0)))
571 (clobber (reg:CC 100))])]
573 { operands[3] = gen_reg_rtx (SImode); })
575 ;; ??? v9: Operand 0 needs a mode, so SImode was chosen.
576 ;; However, the code handles both SImode and DImode.
578 [(set (match_operand:SI 0 "int_register_operand" "")
579 (eq:SI (match_dup 1) (const_int 0)))]
582 if (GET_MODE (sparc_compare_op0) == SImode)
586 if (GET_MODE (operands[0]) == SImode)
587 pat = gen_seqsi_special (operands[0], sparc_compare_op0,
589 else if (! TARGET_ARCH64)
592 pat = gen_seqsi_special_extend (operands[0], sparc_compare_op0,
597 else if (GET_MODE (sparc_compare_op0) == DImode)
603 else if (GET_MODE (operands[0]) == SImode)
604 pat = gen_seqdi_special_trunc (operands[0], sparc_compare_op0,
607 pat = gen_seqdi_special (operands[0], sparc_compare_op0,
612 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
614 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, EQ);
615 emit_jump_insn (gen_sne (operands[0]));
620 if (gen_v9_scc (EQ, operands))
627 ;; ??? v9: Operand 0 needs a mode, so SImode was chosen.
628 ;; However, the code handles both SImode and DImode.
630 [(set (match_operand:SI 0 "int_register_operand" "")
631 (ne:SI (match_dup 1) (const_int 0)))]
634 if (GET_MODE (sparc_compare_op0) == SImode)
638 if (GET_MODE (operands[0]) == SImode)
639 pat = gen_snesi_special (operands[0], sparc_compare_op0,
641 else if (! TARGET_ARCH64)
644 pat = gen_snesi_special_extend (operands[0], sparc_compare_op0,
649 else if (GET_MODE (sparc_compare_op0) == DImode)
655 else if (GET_MODE (operands[0]) == SImode)
656 pat = gen_snedi_special_trunc (operands[0], sparc_compare_op0,
659 pat = gen_snedi_special (operands[0], sparc_compare_op0,
664 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
666 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, NE);
667 emit_jump_insn (gen_sne (operands[0]));
672 if (gen_v9_scc (NE, operands))
680 [(set (match_operand:SI 0 "int_register_operand" "")
681 (gt:SI (match_dup 1) (const_int 0)))]
684 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
686 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GT);
687 emit_jump_insn (gen_sne (operands[0]));
692 if (gen_v9_scc (GT, operands))
700 [(set (match_operand:SI 0 "int_register_operand" "")
701 (lt:SI (match_dup 1) (const_int 0)))]
704 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
706 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LT);
707 emit_jump_insn (gen_sne (operands[0]));
712 if (gen_v9_scc (LT, operands))
720 [(set (match_operand:SI 0 "int_register_operand" "")
721 (ge:SI (match_dup 1) (const_int 0)))]
724 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
726 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GE);
727 emit_jump_insn (gen_sne (operands[0]));
732 if (gen_v9_scc (GE, operands))
740 [(set (match_operand:SI 0 "int_register_operand" "")
741 (le:SI (match_dup 1) (const_int 0)))]
744 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
746 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LE);
747 emit_jump_insn (gen_sne (operands[0]));
752 if (gen_v9_scc (LE, operands))
759 (define_expand "sgtu"
760 [(set (match_operand:SI 0 "int_register_operand" "")
761 (gtu:SI (match_dup 1) (const_int 0)))]
768 /* We can do ltu easily, so if both operands are registers, swap them and
770 if ((GET_CODE (sparc_compare_op0) == REG
771 || GET_CODE (sparc_compare_op0) == SUBREG)
772 && (GET_CODE (sparc_compare_op1) == REG
773 || GET_CODE (sparc_compare_op1) == SUBREG))
775 tem = sparc_compare_op0;
776 sparc_compare_op0 = sparc_compare_op1;
777 sparc_compare_op1 = tem;
778 pat = gen_sltu (operands[0]);
787 if (gen_v9_scc (GTU, operands))
793 (define_expand "sltu"
794 [(set (match_operand:SI 0 "int_register_operand" "")
795 (ltu:SI (match_dup 1) (const_int 0)))]
800 if (gen_v9_scc (LTU, operands))
803 operands[1] = gen_compare_reg (LTU, sparc_compare_op0, sparc_compare_op1);
806 (define_expand "sgeu"
807 [(set (match_operand:SI 0 "int_register_operand" "")
808 (geu:SI (match_dup 1) (const_int 0)))]
813 if (gen_v9_scc (GEU, operands))
816 operands[1] = gen_compare_reg (GEU, sparc_compare_op0, sparc_compare_op1);
819 (define_expand "sleu"
820 [(set (match_operand:SI 0 "int_register_operand" "")
821 (leu:SI (match_dup 1) (const_int 0)))]
828 /* We can do geu easily, so if both operands are registers, swap them and
830 if ((GET_CODE (sparc_compare_op0) == REG
831 || GET_CODE (sparc_compare_op0) == SUBREG)
832 && (GET_CODE (sparc_compare_op1) == REG
833 || GET_CODE (sparc_compare_op1) == SUBREG))
835 tem = sparc_compare_op0;
836 sparc_compare_op0 = sparc_compare_op1;
837 sparc_compare_op1 = tem;
838 pat = gen_sgeu (operands[0]);
847 if (gen_v9_scc (LEU, operands))
853 ;; Now the DEFINE_INSNs for the scc cases.
855 ;; The SEQ and SNE patterns are special because they can be done
856 ;; without any branching and do not involve a COMPARE. We want
857 ;; them to always use the splitz below so the results can be
860 (define_insn_and_split "*snesi_zero"
861 [(set (match_operand:SI 0 "register_operand" "=r")
862 (ne:SI (match_operand:SI 1 "register_operand" "r")
864 (clobber (reg:CC 100))]
868 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
870 (set (match_dup 0) (ltu:SI (reg:CC 100) (const_int 0)))]
872 [(set_attr "length" "2")])
874 (define_insn_and_split "*neg_snesi_zero"
875 [(set (match_operand:SI 0 "register_operand" "=r")
876 (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
878 (clobber (reg:CC 100))]
882 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
884 (set (match_dup 0) (neg:SI (ltu:SI (reg:CC 100) (const_int 0))))]
886 [(set_attr "length" "2")])
888 (define_insn_and_split "*snesi_zero_extend"
889 [(set (match_operand:DI 0 "register_operand" "=r")
890 (ne:DI (match_operand:SI 1 "register_operand" "r")
892 (clobber (reg:CC 100))]
896 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (minus:SI (const_int 0)
899 (set (match_dup 0) (zero_extend:DI (plus:SI (plus:SI (const_int 0)
901 (ltu:SI (reg:CC_NOOV 100)
904 [(set_attr "length" "2")])
906 (define_insn_and_split "*snedi_zero"
907 [(set (match_operand:DI 0 "register_operand" "=&r")
908 (ne:DI (match_operand:DI 1 "register_operand" "r")
912 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
913 [(set (match_dup 0) (const_int 0))
914 (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
919 [(set_attr "length" "2")])
921 (define_insn_and_split "*neg_snedi_zero"
922 [(set (match_operand:DI 0 "register_operand" "=&r")
923 (neg:DI (ne:DI (match_operand:DI 1 "register_operand" "r")
927 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
928 [(set (match_dup 0) (const_int 0))
929 (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
934 [(set_attr "length" "2")])
936 (define_insn_and_split "*snedi_zero_trunc"
937 [(set (match_operand:SI 0 "register_operand" "=&r")
938 (ne:SI (match_operand:DI 1 "register_operand" "r")
942 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
943 [(set (match_dup 0) (const_int 0))
944 (set (match_dup 0) (if_then_else:SI (ne:DI (match_dup 1)
949 [(set_attr "length" "2")])
951 (define_insn_and_split "*seqsi_zero"
952 [(set (match_operand:SI 0 "register_operand" "=r")
953 (eq:SI (match_operand:SI 1 "register_operand" "r")
955 (clobber (reg:CC 100))]
959 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
961 (set (match_dup 0) (geu:SI (reg:CC 100) (const_int 0)))]
963 [(set_attr "length" "2")])
965 (define_insn_and_split "*neg_seqsi_zero"
966 [(set (match_operand:SI 0 "register_operand" "=r")
967 (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
969 (clobber (reg:CC 100))]
973 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
975 (set (match_dup 0) (neg:SI (geu:SI (reg:CC 100) (const_int 0))))]
977 [(set_attr "length" "2")])
979 (define_insn_and_split "*seqsi_zero_extend"
980 [(set (match_operand:DI 0 "register_operand" "=r")
981 (eq:DI (match_operand:SI 1 "register_operand" "r")
983 (clobber (reg:CC 100))]
987 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (minus:SI (const_int 0)
990 (set (match_dup 0) (zero_extend:DI (minus:SI (minus:SI (const_int 0)
992 (ltu:SI (reg:CC_NOOV 100)
995 [(set_attr "length" "2")])
997 (define_insn_and_split "*seqdi_zero"
998 [(set (match_operand:DI 0 "register_operand" "=&r")
999 (eq:DI (match_operand:DI 1 "register_operand" "r")
1003 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
1004 [(set (match_dup 0) (const_int 0))
1005 (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
1010 [(set_attr "length" "2")])
1012 (define_insn_and_split "*neg_seqdi_zero"
1013 [(set (match_operand:DI 0 "register_operand" "=&r")
1014 (neg:DI (eq:DI (match_operand:DI 1 "register_operand" "r")
1018 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
1019 [(set (match_dup 0) (const_int 0))
1020 (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
1025 [(set_attr "length" "2")])
1027 (define_insn_and_split "*seqdi_zero_trunc"
1028 [(set (match_operand:SI 0 "register_operand" "=&r")
1029 (eq:SI (match_operand:DI 1 "register_operand" "r")
1033 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
1034 [(set (match_dup 0) (const_int 0))
1035 (set (match_dup 0) (if_then_else:SI (eq:DI (match_dup 1)
1040 [(set_attr "length" "2")])
1042 ;; We can also do (x + (i == 0)) and related, so put them in.
1043 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1046 (define_insn_and_split "*x_plus_i_ne_0"
1047 [(set (match_operand:SI 0 "register_operand" "=r")
1048 (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
1050 (match_operand:SI 2 "register_operand" "r")))
1051 (clobber (reg:CC 100))]
1055 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1057 (set (match_dup 0) (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1060 [(set_attr "length" "2")])
1062 (define_insn_and_split "*x_minus_i_ne_0"
1063 [(set (match_operand:SI 0 "register_operand" "=r")
1064 (minus:SI (match_operand:SI 2 "register_operand" "r")
1065 (ne:SI (match_operand:SI 1 "register_operand" "r")
1067 (clobber (reg:CC 100))]
1071 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1073 (set (match_dup 0) (minus:SI (match_dup 2)
1074 (ltu:SI (reg:CC 100) (const_int 0))))]
1076 [(set_attr "length" "2")])
1078 (define_insn_and_split "*x_plus_i_eq_0"
1079 [(set (match_operand:SI 0 "register_operand" "=r")
1080 (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
1082 (match_operand:SI 2 "register_operand" "r")))
1083 (clobber (reg:CC 100))]
1087 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1089 (set (match_dup 0) (plus:SI (geu:SI (reg:CC 100) (const_int 0))
1092 [(set_attr "length" "2")])
1094 (define_insn_and_split "*x_minus_i_eq_0"
1095 [(set (match_operand:SI 0 "register_operand" "=r")
1096 (minus:SI (match_operand:SI 2 "register_operand" "r")
1097 (eq:SI (match_operand:SI 1 "register_operand" "r")
1099 (clobber (reg:CC 100))]
1103 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1105 (set (match_dup 0) (minus:SI (match_dup 2)
1106 (geu:SI (reg:CC 100) (const_int 0))))]
1108 [(set_attr "length" "2")])
1110 ;; We can also do GEU and LTU directly, but these operate after a compare.
1111 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1114 (define_insn "*sltu_insn"
1115 [(set (match_operand:SI 0 "register_operand" "=r")
1116 (ltu:SI (reg:CC 100) (const_int 0)))]
1119 [(set_attr "type" "ialuX")])
1121 (define_insn "*neg_sltu_insn"
1122 [(set (match_operand:SI 0 "register_operand" "=r")
1123 (neg:SI (ltu:SI (reg:CC 100) (const_int 0))))]
1126 [(set_attr "type" "ialuX")])
1128 ;; ??? Combine should canonicalize these next two to the same pattern.
1129 (define_insn "*neg_sltu_minus_x"
1130 [(set (match_operand:SI 0 "register_operand" "=r")
1131 (minus:SI (neg:SI (ltu:SI (reg:CC 100) (const_int 0)))
1132 (match_operand:SI 1 "arith_operand" "rI")))]
1134 "subx\t%%g0, %1, %0"
1135 [(set_attr "type" "ialuX")])
1137 (define_insn "*neg_sltu_plus_x"
1138 [(set (match_operand:SI 0 "register_operand" "=r")
1139 (neg:SI (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1140 (match_operand:SI 1 "arith_operand" "rI"))))]
1142 "subx\t%%g0, %1, %0"
1143 [(set_attr "type" "ialuX")])
1145 (define_insn "*sgeu_insn"
1146 [(set (match_operand:SI 0 "register_operand" "=r")
1147 (geu:SI (reg:CC 100) (const_int 0)))]
1149 "subx\t%%g0, -1, %0"
1150 [(set_attr "type" "ialuX")])
1152 (define_insn "*neg_sgeu_insn"
1153 [(set (match_operand:SI 0 "register_operand" "=r")
1154 (neg:SI (geu:SI (reg:CC 100) (const_int 0))))]
1156 "addx\t%%g0, -1, %0"
1157 [(set_attr "type" "ialuX")])
1159 ;; We can also do (x + ((unsigned) i >= 0)) and related, so put them in.
1160 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1163 (define_insn "*sltu_plus_x"
1164 [(set (match_operand:SI 0 "register_operand" "=r")
1165 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1166 (match_operand:SI 1 "arith_operand" "rI")))]
1168 "addx\t%%g0, %1, %0"
1169 [(set_attr "type" "ialuX")])
1171 (define_insn "*sltu_plus_x_plus_y"
1172 [(set (match_operand:SI 0 "register_operand" "=r")
1173 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1174 (plus:SI (match_operand:SI 1 "arith_operand" "%r")
1175 (match_operand:SI 2 "arith_operand" "rI"))))]
1178 [(set_attr "type" "ialuX")])
1180 (define_insn "*x_minus_sltu"
1181 [(set (match_operand:SI 0 "register_operand" "=r")
1182 (minus:SI (match_operand:SI 1 "register_operand" "r")
1183 (ltu:SI (reg:CC 100) (const_int 0))))]
1186 [(set_attr "type" "ialuX")])
1188 ;; ??? Combine should canonicalize these next two to the same pattern.
1189 (define_insn "*x_minus_y_minus_sltu"
1190 [(set (match_operand:SI 0 "register_operand" "=r")
1191 (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
1192 (match_operand:SI 2 "arith_operand" "rI"))
1193 (ltu:SI (reg:CC 100) (const_int 0))))]
1196 [(set_attr "type" "ialuX")])
1198 (define_insn "*x_minus_sltu_plus_y"
1199 [(set (match_operand:SI 0 "register_operand" "=r")
1200 (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
1201 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1202 (match_operand:SI 2 "arith_operand" "rI"))))]
1205 [(set_attr "type" "ialuX")])
1207 (define_insn "*sgeu_plus_x"
1208 [(set (match_operand:SI 0 "register_operand" "=r")
1209 (plus:SI (geu:SI (reg:CC 100) (const_int 0))
1210 (match_operand:SI 1 "register_operand" "r")))]
1213 [(set_attr "type" "ialuX")])
1215 (define_insn "*x_minus_sgeu"
1216 [(set (match_operand:SI 0 "register_operand" "=r")
1217 (minus:SI (match_operand:SI 1 "register_operand" "r")
1218 (geu:SI (reg:CC 100) (const_int 0))))]
1221 [(set_attr "type" "ialuX")])
1224 [(set (match_operand:SI 0 "register_operand" "")
1225 (match_operator:SI 2 "noov_compare_operator"
1226 [(match_operand 1 "icc_or_fcc_register_operand" "")
1229 && REGNO (operands[1]) == SPARC_ICC_REG
1230 && (GET_MODE (operands[1]) == CCXmode
1231 /* 32 bit LTU/GEU are better implemented using addx/subx. */
1232 || (GET_CODE (operands[2]) != LTU && GET_CODE (operands[2]) != GEU))"
1233 [(set (match_dup 0) (const_int 0))
1235 (if_then_else:SI (match_op_dup:SI 2 [(match_dup 1) (const_int 0)])
1241 ;; These control RTL generation for conditional jump insns
1243 ;; The quad-word fp compare library routines all return nonzero to indicate
1244 ;; true, which is different from the equivalent libgcc routines, so we must
1245 ;; handle them specially here.
1247 (define_expand "beq"
1249 (if_then_else (eq (match_dup 1) (const_int 0))
1250 (label_ref (match_operand 0 "" ""))
1254 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1255 && GET_CODE (sparc_compare_op0) == REG
1256 && GET_MODE (sparc_compare_op0) == DImode)
1258 emit_v9_brxx_insn (EQ, sparc_compare_op0, operands[0]);
1261 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1263 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, EQ);
1264 emit_jump_insn (gen_bne (operands[0]));
1267 operands[1] = gen_compare_reg (EQ, sparc_compare_op0, sparc_compare_op1);
1270 (define_expand "bne"
1272 (if_then_else (ne (match_dup 1) (const_int 0))
1273 (label_ref (match_operand 0 "" ""))
1277 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1278 && GET_CODE (sparc_compare_op0) == REG
1279 && GET_MODE (sparc_compare_op0) == DImode)
1281 emit_v9_brxx_insn (NE, sparc_compare_op0, operands[0]);
1284 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1286 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, NE);
1287 emit_jump_insn (gen_bne (operands[0]));
1290 operands[1] = gen_compare_reg (NE, sparc_compare_op0, sparc_compare_op1);
1293 (define_expand "bgt"
1295 (if_then_else (gt (match_dup 1) (const_int 0))
1296 (label_ref (match_operand 0 "" ""))
1300 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1301 && GET_CODE (sparc_compare_op0) == REG
1302 && GET_MODE (sparc_compare_op0) == DImode)
1304 emit_v9_brxx_insn (GT, sparc_compare_op0, operands[0]);
1307 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1309 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GT);
1310 emit_jump_insn (gen_bne (operands[0]));
1313 operands[1] = gen_compare_reg (GT, sparc_compare_op0, sparc_compare_op1);
1316 (define_expand "bgtu"
1318 (if_then_else (gtu (match_dup 1) (const_int 0))
1319 (label_ref (match_operand 0 "" ""))
1323 operands[1] = gen_compare_reg (GTU, sparc_compare_op0, sparc_compare_op1);
1326 (define_expand "blt"
1328 (if_then_else (lt (match_dup 1) (const_int 0))
1329 (label_ref (match_operand 0 "" ""))
1333 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1334 && GET_CODE (sparc_compare_op0) == REG
1335 && GET_MODE (sparc_compare_op0) == DImode)
1337 emit_v9_brxx_insn (LT, sparc_compare_op0, operands[0]);
1340 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1342 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LT);
1343 emit_jump_insn (gen_bne (operands[0]));
1346 operands[1] = gen_compare_reg (LT, sparc_compare_op0, sparc_compare_op1);
1349 (define_expand "bltu"
1351 (if_then_else (ltu (match_dup 1) (const_int 0))
1352 (label_ref (match_operand 0 "" ""))
1356 operands[1] = gen_compare_reg (LTU, sparc_compare_op0, sparc_compare_op1);
1359 (define_expand "bge"
1361 (if_then_else (ge (match_dup 1) (const_int 0))
1362 (label_ref (match_operand 0 "" ""))
1366 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1367 && GET_CODE (sparc_compare_op0) == REG
1368 && GET_MODE (sparc_compare_op0) == DImode)
1370 emit_v9_brxx_insn (GE, sparc_compare_op0, operands[0]);
1373 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1375 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GE);
1376 emit_jump_insn (gen_bne (operands[0]));
1379 operands[1] = gen_compare_reg (GE, sparc_compare_op0, sparc_compare_op1);
1382 (define_expand "bgeu"
1384 (if_then_else (geu (match_dup 1) (const_int 0))
1385 (label_ref (match_operand 0 "" ""))
1389 operands[1] = gen_compare_reg (GEU, sparc_compare_op0, sparc_compare_op1);
1392 (define_expand "ble"
1394 (if_then_else (le (match_dup 1) (const_int 0))
1395 (label_ref (match_operand 0 "" ""))
1399 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1400 && GET_CODE (sparc_compare_op0) == REG
1401 && GET_MODE (sparc_compare_op0) == DImode)
1403 emit_v9_brxx_insn (LE, sparc_compare_op0, operands[0]);
1406 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1408 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LE);
1409 emit_jump_insn (gen_bne (operands[0]));
1412 operands[1] = gen_compare_reg (LE, sparc_compare_op0, sparc_compare_op1);
1415 (define_expand "bleu"
1417 (if_then_else (leu (match_dup 1) (const_int 0))
1418 (label_ref (match_operand 0 "" ""))
1422 operands[1] = gen_compare_reg (LEU, sparc_compare_op0, sparc_compare_op1);
1425 (define_expand "bunordered"
1427 (if_then_else (unordered (match_dup 1) (const_int 0))
1428 (label_ref (match_operand 0 "" ""))
1432 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1434 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1,
1436 emit_jump_insn (gen_beq (operands[0]));
1439 operands[1] = gen_compare_reg (UNORDERED, sparc_compare_op0,
1443 (define_expand "bordered"
1445 (if_then_else (ordered (match_dup 1) (const_int 0))
1446 (label_ref (match_operand 0 "" ""))
1450 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1452 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, ORDERED);
1453 emit_jump_insn (gen_bne (operands[0]));
1456 operands[1] = gen_compare_reg (ORDERED, sparc_compare_op0,
1460 (define_expand "bungt"
1462 (if_then_else (ungt (match_dup 1) (const_int 0))
1463 (label_ref (match_operand 0 "" ""))
1467 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1469 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNGT);
1470 emit_jump_insn (gen_bgt (operands[0]));
1473 operands[1] = gen_compare_reg (UNGT, sparc_compare_op0, sparc_compare_op1);
1476 (define_expand "bunlt"
1478 (if_then_else (unlt (match_dup 1) (const_int 0))
1479 (label_ref (match_operand 0 "" ""))
1483 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1485 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNLT);
1486 emit_jump_insn (gen_bne (operands[0]));
1489 operands[1] = gen_compare_reg (UNLT, sparc_compare_op0, sparc_compare_op1);
1492 (define_expand "buneq"
1494 (if_then_else (uneq (match_dup 1) (const_int 0))
1495 (label_ref (match_operand 0 "" ""))
1499 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1501 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNEQ);
1502 emit_jump_insn (gen_beq (operands[0]));
1505 operands[1] = gen_compare_reg (UNEQ, sparc_compare_op0, sparc_compare_op1);
1508 (define_expand "bunge"
1510 (if_then_else (unge (match_dup 1) (const_int 0))
1511 (label_ref (match_operand 0 "" ""))
1515 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1517 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNGE);
1518 emit_jump_insn (gen_bne (operands[0]));
1521 operands[1] = gen_compare_reg (UNGE, sparc_compare_op0, sparc_compare_op1);
1524 (define_expand "bunle"
1526 (if_then_else (unle (match_dup 1) (const_int 0))
1527 (label_ref (match_operand 0 "" ""))
1531 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1533 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNLE);
1534 emit_jump_insn (gen_bne (operands[0]));
1537 operands[1] = gen_compare_reg (UNLE, sparc_compare_op0, sparc_compare_op1);
1540 (define_expand "bltgt"
1542 (if_then_else (ltgt (match_dup 1) (const_int 0))
1543 (label_ref (match_operand 0 "" ""))
1547 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1549 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LTGT);
1550 emit_jump_insn (gen_bne (operands[0]));
1553 operands[1] = gen_compare_reg (LTGT, sparc_compare_op0, sparc_compare_op1);
1556 ;; Now match both normal and inverted jump.
1558 ;; XXX fpcmp nop braindamage
1559 (define_insn "*normal_branch"
1561 (if_then_else (match_operator 0 "noov_compare_operator"
1562 [(reg 100) (const_int 0)])
1563 (label_ref (match_operand 1 "" ""))
1567 return output_cbranch (operands[0], operands[1], 1, 0,
1568 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1571 [(set_attr "type" "branch")
1572 (set_attr "branch_type" "icc")])
1574 ;; XXX fpcmp nop braindamage
1575 (define_insn "*inverted_branch"
1577 (if_then_else (match_operator 0 "noov_compare_operator"
1578 [(reg 100) (const_int 0)])
1580 (label_ref (match_operand 1 "" ""))))]
1583 return output_cbranch (operands[0], operands[1], 1, 1,
1584 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1587 [(set_attr "type" "branch")
1588 (set_attr "branch_type" "icc")])
1590 ;; XXX fpcmp nop braindamage
1591 (define_insn "*normal_fp_branch"
1593 (if_then_else (match_operator 1 "comparison_operator"
1594 [(match_operand:CCFP 0 "fcc_register_operand" "c")
1596 (label_ref (match_operand 2 "" ""))
1600 return output_cbranch (operands[1], operands[2], 2, 0,
1601 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1604 [(set_attr "type" "branch")
1605 (set_attr "branch_type" "fcc")])
1607 ;; XXX fpcmp nop braindamage
1608 (define_insn "*inverted_fp_branch"
1610 (if_then_else (match_operator 1 "comparison_operator"
1611 [(match_operand:CCFP 0 "fcc_register_operand" "c")
1614 (label_ref (match_operand 2 "" ""))))]
1617 return output_cbranch (operands[1], operands[2], 2, 1,
1618 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1621 [(set_attr "type" "branch")
1622 (set_attr "branch_type" "fcc")])
1624 ;; XXX fpcmp nop braindamage
1625 (define_insn "*normal_fpe_branch"
1627 (if_then_else (match_operator 1 "comparison_operator"
1628 [(match_operand:CCFPE 0 "fcc_register_operand" "c")
1630 (label_ref (match_operand 2 "" ""))
1634 return output_cbranch (operands[1], operands[2], 2, 0,
1635 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1638 [(set_attr "type" "branch")
1639 (set_attr "branch_type" "fcc")])
1641 ;; XXX fpcmp nop braindamage
1642 (define_insn "*inverted_fpe_branch"
1644 (if_then_else (match_operator 1 "comparison_operator"
1645 [(match_operand:CCFPE 0 "fcc_register_operand" "c")
1648 (label_ref (match_operand 2 "" ""))))]
1651 return output_cbranch (operands[1], operands[2], 2, 1,
1652 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1655 [(set_attr "type" "branch")
1656 (set_attr "branch_type" "fcc")])
1658 ;; SPARC V9-specific jump insns. None of these are guaranteed to be
1659 ;; in the architecture.
1661 ;; There are no 32 bit brreg insns.
1664 (define_insn "*normal_int_branch_sp64"
1666 (if_then_else (match_operator 0 "v9_register_compare_operator"
1667 [(match_operand:DI 1 "register_operand" "r")
1669 (label_ref (match_operand 2 "" ""))
1673 return output_v9branch (operands[0], operands[2], 1, 2, 0,
1674 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1677 [(set_attr "type" "branch")
1678 (set_attr "branch_type" "reg")])
1681 (define_insn "*inverted_int_branch_sp64"
1683 (if_then_else (match_operator 0 "v9_register_compare_operator"
1684 [(match_operand:DI 1 "register_operand" "r")
1687 (label_ref (match_operand 2 "" ""))))]
1690 return output_v9branch (operands[0], operands[2], 1, 2, 1,
1691 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1694 [(set_attr "type" "branch")
1695 (set_attr "branch_type" "reg")])
1698 (define_mode_macro P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
1700 ;; Load in operand 0 the (absolute) address of operand 1, which is a symbolic
1701 ;; value subject to a PC-relative relocation. Operand 2 is a helper function
1702 ;; that adds the PC value at the call point to operand 0.
1704 (define_insn "load_pcrel_sym<P:mode>"
1705 [(set (match_operand:P 0 "register_operand" "=r")
1706 (unspec:P [(match_operand:P 1 "symbolic_operand" "")
1707 (match_operand:P 2 "call_address_operand" "")] UNSPEC_LOAD_PCREL_SYM))
1708 (clobber (reg:P 15))]
1711 if (flag_delayed_branch)
1712 return "sethi\t%%hi(%a1-4), %0\n\tcall\t%a2\n\t add\t%0, %%lo(%a1+4), %0";
1714 return "sethi\t%%hi(%a1-8), %0\n\tadd\t%0, %%lo(%a1-4), %0\n\tcall\t%a2\n\t nop";
1716 [(set (attr "type") (const_string "multi"))
1717 (set (attr "length")
1718 (if_then_else (eq_attr "delayed_branch" "true")
1723 ;; Integer move instructions
1725 (define_expand "movqi"
1726 [(set (match_operand:QI 0 "general_operand" "")
1727 (match_operand:QI 1 "general_operand" ""))]
1730 /* Working with CONST_INTs is easier, so convert
1731 a double if needed. */
1732 if (GET_CODE (operands[1]) == CONST_DOUBLE)
1733 operands[1] = gen_int_mode (CONST_DOUBLE_LOW (operands[1]), QImode);
1735 /* Handle sets of MEM first. */
1736 if (GET_CODE (operands[0]) == MEM)
1738 if (register_or_zero_operand (operands[1], QImode))
1741 if (! reload_in_progress)
1743 operands[0] = validize_mem (operands[0]);
1744 operands[1] = force_reg (QImode, operands[1]);
1748 /* Fixup TLS cases. */
1749 if (tls_symbolic_operand (operands [1]))
1750 operands[1] = legitimize_tls_address (operands[1]);
1752 /* Fixup PIC cases. */
1755 if (CONSTANT_P (operands[1])
1756 && pic_address_needs_scratch (operands[1]))
1757 operands[1] = legitimize_pic_address (operands[1], QImode, 0);
1759 if (symbolic_operand (operands[1], QImode))
1761 operands[1] = legitimize_pic_address (operands[1],
1763 (reload_in_progress ?
1770 /* All QI constants require only one insn, so proceed. */
1776 (define_insn "*movqi_insn"
1777 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m")
1778 (match_operand:QI 1 "input_operand" "rI,m,rJ"))]
1779 "(register_operand (operands[0], QImode)
1780 || register_or_zero_operand (operands[1], QImode))"
1785 [(set_attr "type" "*,load,store")
1786 (set_attr "us3load_type" "*,3cycle,*")])
1788 (define_expand "movhi"
1789 [(set (match_operand:HI 0 "general_operand" "")
1790 (match_operand:HI 1 "general_operand" ""))]
1793 /* Working with CONST_INTs is easier, so convert
1794 a double if needed. */
1795 if (GET_CODE (operands[1]) == CONST_DOUBLE)
1796 operands[1] = gen_int_mode (CONST_DOUBLE_LOW (operands[1]), HImode);
1798 /* Handle sets of MEM first. */
1799 if (GET_CODE (operands[0]) == MEM)
1801 if (register_or_zero_operand (operands[1], HImode))
1804 if (! reload_in_progress)
1806 operands[0] = validize_mem (operands[0]);
1807 operands[1] = force_reg (HImode, operands[1]);
1811 /* Fixup TLS cases. */
1812 if (tls_symbolic_operand (operands [1]))
1813 operands[1] = legitimize_tls_address (operands[1]);
1815 /* Fixup PIC cases. */
1818 if (CONSTANT_P (operands[1])
1819 && pic_address_needs_scratch (operands[1]))
1820 operands[1] = legitimize_pic_address (operands[1], HImode, 0);
1822 if (symbolic_operand (operands[1], HImode))
1824 operands[1] = legitimize_pic_address (operands[1],
1826 (reload_in_progress ?
1833 /* This makes sure we will not get rematched due to splittage. */
1834 if (! CONSTANT_P (operands[1]) || input_operand (operands[1], HImode))
1836 else if (CONSTANT_P (operands[1])
1837 && GET_CODE (operands[1]) != HIGH
1838 && GET_CODE (operands[1]) != LO_SUM)
1840 sparc_emit_set_const32 (operands[0], operands[1]);
1847 (define_insn "*movhi_insn"
1848 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1849 (match_operand:HI 1 "input_operand" "rI,K,m,rJ"))]
1850 "(register_operand (operands[0], HImode)
1851 || register_or_zero_operand (operands[1], HImode))"
1854 sethi\t%%hi(%a1), %0
1857 [(set_attr "type" "*,*,load,store")
1858 (set_attr "us3load_type" "*,*,3cycle,*")])
1860 ;; We always work with constants here.
1861 (define_insn "*movhi_lo_sum"
1862 [(set (match_operand:HI 0 "register_operand" "=r")
1863 (ior:HI (match_operand:HI 1 "register_operand" "%r")
1864 (match_operand:HI 2 "small_int_operand" "I")))]
1868 (define_expand "movsi"
1869 [(set (match_operand:SI 0 "general_operand" "")
1870 (match_operand:SI 1 "general_operand" ""))]
1873 /* Working with CONST_INTs is easier, so convert
1874 a double if needed. */
1875 if (GET_CODE (operands[1]) == CONST_DOUBLE)
1876 operands[1] = gen_int_mode (CONST_DOUBLE_LOW (operands[1]), SImode);
1878 /* Handle sets of MEM first. */
1879 if (GET_CODE (operands[0]) == MEM)
1881 if (register_or_zero_operand (operands[1], SImode))
1884 if (! reload_in_progress)
1886 operands[0] = validize_mem (operands[0]);
1887 operands[1] = force_reg (SImode, operands[1]);
1891 /* Fixup TLS cases. */
1892 if (tls_symbolic_operand (operands [1]))
1893 operands[1] = legitimize_tls_address (operands[1]);
1895 /* Fixup PIC cases. */
1898 if (CONSTANT_P (operands[1])
1899 && pic_address_needs_scratch (operands[1]))
1900 operands[1] = legitimize_pic_address (operands[1], SImode, 0);
1902 if (GET_CODE (operands[1]) == LABEL_REF)
1905 emit_insn (gen_movsi_pic_label_ref (operands[0], operands[1]));
1909 if (symbolic_operand (operands[1], SImode))
1911 operands[1] = legitimize_pic_address (operands[1],
1913 (reload_in_progress ?
1920 /* If we are trying to toss an integer constant into the
1921 FPU registers, force it into memory. */
1922 if (GET_CODE (operands[0]) == REG
1923 && REGNO (operands[0]) >= SPARC_FIRST_FP_REG
1924 && REGNO (operands[0]) <= SPARC_LAST_V9_FP_REG
1925 && CONSTANT_P (operands[1]))
1926 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
1929 /* This makes sure we will not get rematched due to splittage. */
1930 if (! CONSTANT_P (operands[1]) || input_operand (operands[1], SImode))
1932 else if (CONSTANT_P (operands[1])
1933 && GET_CODE (operands[1]) != HIGH
1934 && GET_CODE (operands[1]) != LO_SUM)
1936 sparc_emit_set_const32 (operands[0], operands[1]);
1943 (define_insn "*movsi_insn"
1944 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,m,!f,!f,!m,d")
1945 (match_operand:SI 1 "input_operand" "rI,K,m,rJ,f,m,f,J"))]
1946 "(register_operand (operands[0], SImode)
1947 || register_or_zero_operand (operands[1], SImode))"
1950 sethi\t%%hi(%a1), %0
1957 [(set_attr "type" "*,*,load,store,fpmove,fpload,fpstore,fga")])
1959 (define_insn "*movsi_lo_sum"
1960 [(set (match_operand:SI 0 "register_operand" "=r")
1961 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1962 (match_operand:SI 2 "immediate_operand" "in")))]
1964 "or\t%1, %%lo(%a2), %0")
1966 (define_insn "*movsi_high"
1967 [(set (match_operand:SI 0 "register_operand" "=r")
1968 (high:SI (match_operand:SI 1 "immediate_operand" "in")))]
1970 "sethi\t%%hi(%a1), %0")
1972 ;; The next two patterns must wrap the SYMBOL_REF in an UNSPEC
1973 ;; so that CSE won't optimize the address computation away.
1974 (define_insn "movsi_lo_sum_pic"
1975 [(set (match_operand:SI 0 "register_operand" "=r")
1976 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1977 (unspec:SI [(match_operand:SI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
1979 "or\t%1, %%lo(%a2), %0")
1981 (define_insn "movsi_high_pic"
1982 [(set (match_operand:SI 0 "register_operand" "=r")
1983 (high:SI (unspec:SI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
1984 "flag_pic && check_pic (1)"
1985 "sethi\t%%hi(%a1), %0")
1987 (define_expand "movsi_pic_label_ref"
1988 [(set (match_dup 3) (high:SI
1989 (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
1990 (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1991 (set (match_dup 4) (lo_sum:SI (match_dup 3)
1992 (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1993 (set (match_operand:SI 0 "register_operand" "=r")
1994 (minus:SI (match_dup 5) (match_dup 4)))]
1997 current_function_uses_pic_offset_table = 1;
1998 operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
2001 operands[3] = operands[0];
2002 operands[4] = operands[0];
2006 operands[3] = gen_reg_rtx (SImode);
2007 operands[4] = gen_reg_rtx (SImode);
2009 operands[5] = pic_offset_table_rtx;
2012 (define_insn "*movsi_high_pic_label_ref"
2013 [(set (match_operand:SI 0 "register_operand" "=r")
2015 (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
2016 (match_operand:SI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
2018 "sethi\t%%hi(%a2-(%a1-.)), %0")
2020 (define_insn "*movsi_lo_sum_pic_label_ref"
2021 [(set (match_operand:SI 0 "register_operand" "=r")
2022 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
2023 (unspec:SI [(match_operand:SI 2 "label_ref_operand" "")
2024 (match_operand:SI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
2026 "or\t%1, %%lo(%a3-(%a2-.)), %0")
2028 (define_expand "movdi"
2029 [(set (match_operand:DI 0 "general_operand" "")
2030 (match_operand:DI 1 "general_operand" ""))]
2033 /* Working with CONST_INTs is easier, so convert
2034 a double if needed. */
2035 if (GET_CODE (operands[1]) == CONST_DOUBLE
2036 #if HOST_BITS_PER_WIDE_INT == 32
2037 && ((CONST_DOUBLE_HIGH (operands[1]) == 0
2038 && (CONST_DOUBLE_LOW (operands[1]) & 0x80000000) == 0)
2039 || (CONST_DOUBLE_HIGH (operands[1]) == (HOST_WIDE_INT) 0xffffffff
2040 && (CONST_DOUBLE_LOW (operands[1]) & 0x80000000) != 0))
2043 operands[1] = gen_int_mode (CONST_DOUBLE_LOW (operands[1]), DImode);
2045 /* Handle MEM cases first. */
2046 if (GET_CODE (operands[0]) == MEM)
2048 /* If it's a REG, we can always do it.
2049 The const zero case is more complex, on v9
2050 we can always perform it. */
2051 if (register_operand (operands[1], DImode)
2053 && (operands[1] == const0_rtx)))
2056 if (! reload_in_progress)
2058 operands[0] = validize_mem (operands[0]);
2059 operands[1] = force_reg (DImode, operands[1]);
2063 /* Fixup TLS cases. */
2064 if (tls_symbolic_operand (operands [1]))
2065 operands[1] = legitimize_tls_address (operands[1]);
2069 if (CONSTANT_P (operands[1])
2070 && pic_address_needs_scratch (operands[1]))
2071 operands[1] = legitimize_pic_address (operands[1], DImode, 0);
2073 if (GET_CODE (operands[1]) == LABEL_REF)
2075 gcc_assert (TARGET_ARCH64);
2076 emit_insn (gen_movdi_pic_label_ref (operands[0], operands[1]));
2080 if (symbolic_operand (operands[1], DImode))
2082 operands[1] = legitimize_pic_address (operands[1],
2084 (reload_in_progress ?
2091 /* If we are trying to toss an integer constant into the
2092 FPU registers, force it into memory. */
2093 if (GET_CODE (operands[0]) == REG
2094 && REGNO (operands[0]) >= SPARC_FIRST_FP_REG
2095 && REGNO (operands[0]) <= SPARC_LAST_V9_FP_REG
2096 && CONSTANT_P (operands[1]))
2097 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
2100 /* This makes sure we will not get rematched due to splittage. */
2101 if (! CONSTANT_P (operands[1]) || input_operand (operands[1], DImode))
2103 else if (TARGET_ARCH64
2104 && GET_CODE (operands[1]) != HIGH
2105 && GET_CODE (operands[1]) != LO_SUM)
2107 sparc_emit_set_const64 (operands[0], operands[1]);
2115 ;; Be careful, fmovd does not exist when !v9.
2116 ;; We match MEM moves directly when we have correct even
2117 ;; numbered registers, but fall into splits otherwise.
2118 ;; The constraint ordering here is really important to
2119 ;; avoid insane problems in reload, especially for patterns
2122 ;; (set (mem:DI (plus:SI (reg:SI 30 %fp)
2123 ;; (const_int -5016)))
2127 (define_insn "*movdi_insn_sp32"
2128 [(set (match_operand:DI 0 "nonimmediate_operand"
2129 "=o,T,U,o,r,r,r,?T,?f,?f,?o,?f")
2130 (match_operand:DI 1 "input_operand"
2131 " J,U,T,r,o,i,r, f, T, o, f, f"))]
2133 && (register_operand (operands[0], DImode)
2134 || register_operand (operands[1], DImode))"
2148 [(set_attr "type" "store,store,load,*,*,*,*,fpstore,fpload,*,*,*")
2149 (set_attr "length" "2,*,*,2,2,2,2,*,*,2,2,2")])
2151 (define_insn "*movdi_insn_sp32_v9"
2152 [(set (match_operand:DI 0 "nonimmediate_operand"
2153 "=T,o,T,U,o,r,r,r,?T,?f,?f,?o,?e,?e,?W")
2154 (match_operand:DI 1 "input_operand"
2155 " J,J,U,T,r,o,i,r, f, T, o, f, e, W, e"))]
2158 && (register_operand (operands[0], DImode)
2159 || register_or_zero_operand (operands[1], DImode))"
2176 [(set_attr "type" "store,store,store,load,*,*,*,*,fpstore,fpload,*,*,fpmove,fpload,fpstore")
2177 (set_attr "length" "*,2,*,*,2,2,2,2,*,*,2,2,*,*,*")
2178 (set_attr "fptype" "*,*,*,*,*,*,*,*,*,*,*,*,double,*,*")])
2180 (define_insn "*movdi_insn_sp64"
2181 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,m,?e,?e,?W,b")
2182 (match_operand:DI 1 "input_operand" "rI,N,m,rJ,e,W,e,J"))]
2184 && (register_operand (operands[0], DImode)
2185 || register_or_zero_operand (operands[1], DImode))"
2188 sethi\t%%hi(%a1), %0
2195 [(set_attr "type" "*,*,load,store,fpmove,fpload,fpstore,fga")
2196 (set_attr "fptype" "*,*,*,*,double,*,*,double")])
2198 (define_expand "movdi_pic_label_ref"
2199 [(set (match_dup 3) (high:DI
2200 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
2201 (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
2202 (set (match_dup 4) (lo_sum:DI (match_dup 3)
2203 (unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
2204 (set (match_operand:DI 0 "register_operand" "=r")
2205 (minus:DI (match_dup 5) (match_dup 4)))]
2206 "TARGET_ARCH64 && flag_pic"
2208 current_function_uses_pic_offset_table = 1;
2209 operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
2212 operands[3] = operands[0];
2213 operands[4] = operands[0];
2217 operands[3] = gen_reg_rtx (DImode);
2218 operands[4] = gen_reg_rtx (DImode);
2220 operands[5] = pic_offset_table_rtx;
2223 (define_insn "*movdi_high_pic_label_ref"
2224 [(set (match_operand:DI 0 "register_operand" "=r")
2226 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
2227 (match_operand:DI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
2228 "TARGET_ARCH64 && flag_pic"
2229 "sethi\t%%hi(%a2-(%a1-.)), %0")
2231 (define_insn "*movdi_lo_sum_pic_label_ref"
2232 [(set (match_operand:DI 0 "register_operand" "=r")
2233 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2234 (unspec:DI [(match_operand:DI 2 "label_ref_operand" "")
2235 (match_operand:DI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
2236 "TARGET_ARCH64 && flag_pic"
2237 "or\t%1, %%lo(%a3-(%a2-.)), %0")
2239 ;; SPARC-v9 code model support insns. See sparc_emit_set_symbolic_const64
2240 ;; in sparc.c to see what is going on here... PIC stuff comes first.
2242 (define_insn "movdi_lo_sum_pic"
2243 [(set (match_operand:DI 0 "register_operand" "=r")
2244 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2245 (unspec:DI [(match_operand:DI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
2246 "TARGET_ARCH64 && flag_pic"
2247 "or\t%1, %%lo(%a2), %0")
2249 (define_insn "movdi_high_pic"
2250 [(set (match_operand:DI 0 "register_operand" "=r")
2251 (high:DI (unspec:DI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
2252 "TARGET_ARCH64 && flag_pic && check_pic (1)"
2253 "sethi\t%%hi(%a1), %0")
2255 (define_insn "*sethi_di_medlow_embmedany_pic"
2256 [(set (match_operand:DI 0 "register_operand" "=r")
2257 (high:DI (match_operand:DI 1 "medium_pic_operand" "")))]
2258 "(TARGET_CM_MEDLOW || TARGET_CM_EMBMEDANY) && check_pic (1)"
2259 "sethi\t%%hi(%a1), %0")
2261 (define_insn "*sethi_di_medlow"
2262 [(set (match_operand:DI 0 "register_operand" "=r")
2263 (high:DI (match_operand:DI 1 "symbolic_operand" "")))]
2264 "TARGET_CM_MEDLOW && check_pic (1)"
2265 "sethi\t%%hi(%a1), %0")
2267 (define_insn "*losum_di_medlow"
2268 [(set (match_operand:DI 0 "register_operand" "=r")
2269 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2270 (match_operand:DI 2 "symbolic_operand" "")))]
2272 "or\t%1, %%lo(%a2), %0")
2274 (define_insn "seth44"
2275 [(set (match_operand:DI 0 "register_operand" "=r")
2276 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETH44)))]
2278 "sethi\t%%h44(%a1), %0")
2280 (define_insn "setm44"
2281 [(set (match_operand:DI 0 "register_operand" "=r")
2282 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2283 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_SETM44)))]
2285 "or\t%1, %%m44(%a2), %0")
2287 (define_insn "setl44"
2288 [(set (match_operand:DI 0 "register_operand" "=r")
2289 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2290 (match_operand:DI 2 "symbolic_operand" "")))]
2292 "or\t%1, %%l44(%a2), %0")
2294 (define_insn "sethh"
2295 [(set (match_operand:DI 0 "register_operand" "=r")
2296 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETHH)))]
2298 "sethi\t%%hh(%a1), %0")
2300 (define_insn "setlm"
2301 [(set (match_operand:DI 0 "register_operand" "=r")
2302 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETLM)))]
2304 "sethi\t%%lm(%a1), %0")
2306 (define_insn "sethm"
2307 [(set (match_operand:DI 0 "register_operand" "=r")
2308 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2309 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_EMB_SETHM)))]
2311 "or\t%1, %%hm(%a2), %0")
2313 (define_insn "setlo"
2314 [(set (match_operand:DI 0 "register_operand" "=r")
2315 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2316 (match_operand:DI 2 "symbolic_operand" "")))]
2318 "or\t%1, %%lo(%a2), %0")
2320 (define_insn "embmedany_sethi"
2321 [(set (match_operand:DI 0 "register_operand" "=r")
2322 (high:DI (unspec:DI [(match_operand:DI 1 "data_segment_operand" "")] UNSPEC_EMB_HISUM)))]
2323 "TARGET_CM_EMBMEDANY && check_pic (1)"
2324 "sethi\t%%hi(%a1), %0")
2326 (define_insn "embmedany_losum"
2327 [(set (match_operand:DI 0 "register_operand" "=r")
2328 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2329 (match_operand:DI 2 "data_segment_operand" "")))]
2330 "TARGET_CM_EMBMEDANY"
2331 "add\t%1, %%lo(%a2), %0")
2333 (define_insn "embmedany_brsum"
2334 [(set (match_operand:DI 0 "register_operand" "=r")
2335 (unspec:DI [(match_operand:DI 1 "register_operand" "r")] UNSPEC_EMB_HISUM))]
2336 "TARGET_CM_EMBMEDANY"
2339 (define_insn "embmedany_textuhi"
2340 [(set (match_operand:DI 0 "register_operand" "=r")
2341 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTUHI)))]
2342 "TARGET_CM_EMBMEDANY && check_pic (1)"
2343 "sethi\t%%uhi(%a1), %0")
2345 (define_insn "embmedany_texthi"
2346 [(set (match_operand:DI 0 "register_operand" "=r")
2347 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTHI)))]
2348 "TARGET_CM_EMBMEDANY && check_pic (1)"
2349 "sethi\t%%hi(%a1), %0")
2351 (define_insn "embmedany_textulo"
2352 [(set (match_operand:DI 0 "register_operand" "=r")
2353 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2354 (unspec:DI [(match_operand:DI 2 "text_segment_operand" "")] UNSPEC_EMB_TEXTULO)))]
2355 "TARGET_CM_EMBMEDANY"
2356 "or\t%1, %%ulo(%a2), %0")
2358 (define_insn "embmedany_textlo"
2359 [(set (match_operand:DI 0 "register_operand" "=r")
2360 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2361 (match_operand:DI 2 "text_segment_operand" "")))]
2362 "TARGET_CM_EMBMEDANY"
2363 "or\t%1, %%lo(%a2), %0")
2365 ;; Now some patterns to help reload out a bit.
2366 (define_expand "reload_indi"
2367 [(parallel [(match_operand:DI 0 "register_operand" "=r")
2368 (match_operand:DI 1 "immediate_operand" "")
2369 (match_operand:TI 2 "register_operand" "=&r")])]
2371 || TARGET_CM_EMBMEDANY)
2374 sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
2378 (define_expand "reload_outdi"
2379 [(parallel [(match_operand:DI 0 "register_operand" "=r")
2380 (match_operand:DI 1 "immediate_operand" "")
2381 (match_operand:TI 2 "register_operand" "=&r")])]
2383 || TARGET_CM_EMBMEDANY)
2386 sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
2390 ;; Split up putting CONSTs and REGs into DI regs when !arch64
2392 [(set (match_operand:DI 0 "register_operand" "")
2393 (match_operand:DI 1 "const_int_operand" ""))]
2394 "! TARGET_ARCH64 && reload_completed"
2395 [(clobber (const_int 0))]
2397 #if HOST_BITS_PER_WIDE_INT == 32
2398 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
2399 (INTVAL (operands[1]) < 0) ?
2402 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2405 unsigned int low, high;
2407 low = trunc_int_for_mode (INTVAL (operands[1]), SImode);
2408 high = trunc_int_for_mode (INTVAL (operands[1]) >> 32, SImode);
2409 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), GEN_INT (high)));
2411 /* Slick... but this trick loses if this subreg constant part
2412 can be done in one insn. */
2413 if (low == high && (low & 0x3ff) != 0 && low + 0x1000 >= 0x2000)
2414 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2415 gen_highpart (SImode, operands[0])));
2417 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), GEN_INT (low)));
2423 [(set (match_operand:DI 0 "register_operand" "")
2424 (match_operand:DI 1 "const_double_operand" ""))]
2428 && ((GET_CODE (operands[0]) == REG
2429 && REGNO (operands[0]) < 32)
2430 || (GET_CODE (operands[0]) == SUBREG
2431 && GET_CODE (SUBREG_REG (operands[0])) == REG
2432 && REGNO (SUBREG_REG (operands[0])) < 32))))"
2433 [(clobber (const_int 0))]
2435 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
2436 GEN_INT (CONST_DOUBLE_HIGH (operands[1]))));
2438 /* Slick... but this trick loses if this subreg constant part
2439 can be done in one insn. */
2440 if (CONST_DOUBLE_LOW (operands[1]) == CONST_DOUBLE_HIGH (operands[1])
2441 && ! SPARC_SETHI32_P (CONST_DOUBLE_HIGH (operands[1]))
2442 && ! SPARC_SIMM13_P (CONST_DOUBLE_HIGH (operands[1])))
2444 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2445 gen_highpart (SImode, operands[0])));
2449 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2450 GEN_INT (CONST_DOUBLE_LOW (operands[1]))));
2456 [(set (match_operand:DI 0 "register_operand" "")
2457 (match_operand:DI 1 "register_operand" ""))]
2461 && ((GET_CODE (operands[0]) == REG
2462 && REGNO (operands[0]) < 32)
2463 || (GET_CODE (operands[0]) == SUBREG
2464 && GET_CODE (SUBREG_REG (operands[0])) == REG
2465 && REGNO (SUBREG_REG (operands[0])) < 32))))"
2466 [(clobber (const_int 0))]
2468 rtx set_dest = operands[0];
2469 rtx set_src = operands[1];
2473 dest1 = gen_highpart (SImode, set_dest);
2474 dest2 = gen_lowpart (SImode, set_dest);
2475 src1 = gen_highpart (SImode, set_src);
2476 src2 = gen_lowpart (SImode, set_src);
2478 /* Now emit using the real source and destination we found, swapping
2479 the order if we detect overlap. */
2480 if (reg_overlap_mentioned_p (dest1, src2))
2482 emit_insn (gen_movsi (dest2, src2));
2483 emit_insn (gen_movsi (dest1, src1));
2487 emit_insn (gen_movsi (dest1, src1));
2488 emit_insn (gen_movsi (dest2, src2));
2493 ;; Now handle the cases of memory moves from/to non-even
2494 ;; DI mode register pairs.
2496 [(set (match_operand:DI 0 "register_operand" "")
2497 (match_operand:DI 1 "memory_operand" ""))]
2500 && sparc_splitdi_legitimate (operands[0], operands[1]))"
2501 [(clobber (const_int 0))]
2503 rtx word0 = adjust_address (operands[1], SImode, 0);
2504 rtx word1 = adjust_address (operands[1], SImode, 4);
2505 rtx high_part = gen_highpart (SImode, operands[0]);
2506 rtx low_part = gen_lowpart (SImode, operands[0]);
2508 if (reg_overlap_mentioned_p (high_part, word1))
2510 emit_insn (gen_movsi (low_part, word1));
2511 emit_insn (gen_movsi (high_part, word0));
2515 emit_insn (gen_movsi (high_part, word0));
2516 emit_insn (gen_movsi (low_part, word1));
2522 [(set (match_operand:DI 0 "memory_operand" "")
2523 (match_operand:DI 1 "register_operand" ""))]
2526 && sparc_splitdi_legitimate (operands[1], operands[0]))"
2527 [(clobber (const_int 0))]
2529 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0),
2530 gen_highpart (SImode, operands[1])));
2531 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4),
2532 gen_lowpart (SImode, operands[1])));
2537 [(set (match_operand:DI 0 "memory_operand" "")
2542 && ! mem_min_alignment (operands[0], 8)))
2543 && offsettable_memref_p (operands[0])"
2544 [(clobber (const_int 0))]
2546 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0), const0_rtx));
2547 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4), const0_rtx));
2552 ;; Floating point and vector move instructions
2554 ;; We don't define V1SI because SI should work just fine.
2555 (define_mode_macro V32 [SF V2HI V4QI])
2557 ;; Yes, you guessed it right, the former movsf expander.
2558 (define_expand "mov<V32:mode>"
2559 [(set (match_operand:V32 0 "general_operand" "")
2560 (match_operand:V32 1 "general_operand" ""))]
2561 "<V32:MODE>mode == SFmode || TARGET_VIS"
2563 /* Force constants into memory. */
2564 if (GET_CODE (operands[0]) == REG && CONSTANT_P (operands[1]))
2566 /* emit_group_store will send such bogosity to us when it is
2567 not storing directly into memory. So fix this up to avoid
2568 crashes in output_constant_pool. */
2569 if (operands [1] == const0_rtx)
2570 operands[1] = CONST0_RTX (<V32:MODE>mode);
2572 if ((TARGET_VIS || REGNO (operands[0]) < 32)
2573 && const_zero_operand (operands[1], <V32:MODE>mode))
2576 /* We are able to build any SF constant in integer registers
2577 with at most 2 instructions. */
2578 if (REGNO (operands[0]) < 32
2579 && <V32:MODE>mode == SFmode)
2582 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
2586 /* Handle sets of MEM first. */
2587 if (GET_CODE (operands[0]) == MEM)
2589 if (register_or_zero_operand (operands[1], <V32:MODE>mode))
2592 if (! reload_in_progress)
2594 operands[0] = validize_mem (operands[0]);
2595 operands[1] = force_reg (<V32:MODE>mode, operands[1]);
2599 /* Fixup PIC cases. */
2602 if (CONSTANT_P (operands[1])
2603 && pic_address_needs_scratch (operands[1]))
2604 operands[1] = legitimize_pic_address (operands[1], <V32:MODE>mode, 0);
2606 if (symbolic_operand (operands[1], <V32:MODE>mode))
2608 operands[1] = legitimize_pic_address (operands[1],
2610 (reload_in_progress ?
2620 (define_insn "*movsf_insn"
2621 [(set (match_operand:V32 0 "nonimmediate_operand" "=d,f,*r,*r,*r,*r,f,m,m")
2622 (match_operand:V32 1 "input_operand" "GY,f,*rRY,Q,S,m,m,f,*rGY"))]
2624 && (register_operand (operands[0], <V32:MODE>mode)
2625 || register_or_zero_operand (operands[1], <V32:MODE>mode))"
2627 if (GET_CODE (operands[1]) == CONST_DOUBLE
2628 && (which_alternative == 2
2629 || which_alternative == 3
2630 || which_alternative == 4))
2635 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2636 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2637 operands[1] = GEN_INT (i);
2640 switch (which_alternative)
2643 return "fzeros\t%0";
2645 return "fmovs\t%1, %0";
2647 return "mov\t%1, %0";
2649 return "sethi\t%%hi(%a1), %0";
2654 return "ld\t%1, %0";
2657 return "st\t%r1, %0";
2662 [(set_attr "type" "fga,fpmove,*,*,*,load,fpload,fpstore,store")])
2664 ;; Exactly the same as above, except that all `f' cases are deleted.
2665 ;; This is necessary to prevent reload from ever trying to use a `f' reg
2668 (define_insn "*movsf_insn_no_fpu"
2669 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r,r,m")
2670 (match_operand:SF 1 "input_operand" "rR,Q,S,m,rG"))]
2672 && (register_operand (operands[0], SFmode)
2673 || register_or_zero_operand (operands[1], SFmode))"
2675 if (GET_CODE (operands[1]) == CONST_DOUBLE
2676 && (which_alternative == 0
2677 || which_alternative == 1
2678 || which_alternative == 2))
2683 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2684 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2685 operands[1] = GEN_INT (i);
2688 switch (which_alternative)
2691 return "mov\t%1, %0";
2693 return "sethi\t%%hi(%a1), %0";
2697 return "ld\t%1, %0";
2699 return "st\t%r1, %0";
2704 [(set_attr "type" "*,*,*,load,store")])
2706 ;; The following 3 patterns build SFmode constants in integer registers.
2708 (define_insn "*movsf_lo_sum"
2709 [(set (match_operand:SF 0 "register_operand" "=r")
2710 (lo_sum:SF (match_operand:SF 1 "register_operand" "r")
2711 (match_operand:SF 2 "fp_const_high_losum_operand" "S")))]
2717 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[2]);
2718 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2719 operands[2] = GEN_INT (i);
2720 return "or\t%1, %%lo(%a2), %0";
2723 (define_insn "*movsf_high"
2724 [(set (match_operand:SF 0 "register_operand" "=r")
2725 (high:SF (match_operand:SF 1 "fp_const_high_losum_operand" "S")))]
2731 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2732 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2733 operands[1] = GEN_INT (i);
2734 return "sethi\t%%hi(%1), %0";
2738 [(set (match_operand:SF 0 "register_operand" "")
2739 (match_operand:SF 1 "fp_const_high_losum_operand" ""))]
2740 "REG_P (operands[0]) && REGNO (operands[0]) < 32"
2741 [(set (match_dup 0) (high:SF (match_dup 1)))
2742 (set (match_dup 0) (lo_sum:SF (match_dup 0) (match_dup 1)))])
2744 (define_mode_macro V64 [DF V2SI V4HI V8QI])
2746 ;; Yes, you again guessed it right, the former movdf expander.
2747 (define_expand "mov<V64:mode>"
2748 [(set (match_operand:V64 0 "general_operand" "")
2749 (match_operand:V64 1 "general_operand" ""))]
2750 "<V64:MODE>mode == DFmode || TARGET_VIS"
2752 /* Force constants into memory. */
2753 if (GET_CODE (operands[0]) == REG && CONSTANT_P (operands[1]))
2755 /* emit_group_store will send such bogosity to us when it is
2756 not storing directly into memory. So fix this up to avoid
2757 crashes in output_constant_pool. */
2758 if (operands [1] == const0_rtx)
2759 operands[1] = CONST0_RTX (<V64:MODE>mode);
2761 if ((TARGET_VIS || REGNO (operands[0]) < 32)
2762 && const_zero_operand (operands[1], <V64:MODE>mode))
2765 /* We are able to build any DF constant in integer registers. */
2766 if (REGNO (operands[0]) < 32
2767 && <V64:MODE>mode == DFmode
2768 && (reload_completed || reload_in_progress))
2771 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
2775 /* Handle MEM cases first. */
2776 if (GET_CODE (operands[0]) == MEM)
2778 if (register_or_zero_operand (operands[1], <V64:MODE>mode))
2781 if (! reload_in_progress)
2783 operands[0] = validize_mem (operands[0]);
2784 operands[1] = force_reg (<V64:MODE>mode, operands[1]);
2788 /* Fixup PIC cases. */
2791 if (CONSTANT_P (operands[1])
2792 && pic_address_needs_scratch (operands[1]))
2793 operands[1] = legitimize_pic_address (operands[1], <V64:MODE>mode, 0);
2795 if (symbolic_operand (operands[1], <V64:MODE>mode))
2797 operands[1] = legitimize_pic_address (operands[1],
2799 (reload_in_progress ?
2809 ;; Be careful, fmovd does not exist when !v9.
2810 (define_insn "*movdf_insn_sp32"
2811 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,W,U,T,o,e,*r,o,e,o")
2812 (match_operand:DF 1 "input_operand" "W#F,e,T,U,G,e,*rFo,*r,o#F,e"))]
2815 && (register_operand (operands[0], DFmode)
2816 || register_or_zero_operand (operands[1], DFmode))"
2828 [(set_attr "type" "fpload,fpstore,load,store,*,*,*,*,*,*")
2829 (set_attr "length" "*,*,*,*,2,2,2,2,2,2")])
2831 (define_insn "*movdf_insn_sp32_no_fpu"
2832 [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,o,r,o")
2833 (match_operand:DF 1 "input_operand" "T,U,G,ro,r"))]
2836 && (register_operand (operands[0], DFmode)
2837 || register_or_zero_operand (operands[1], DFmode))"
2844 [(set_attr "type" "load,store,*,*,*")
2845 (set_attr "length" "*,*,2,2,2")])
2847 ;; We have available v9 double floats but not 64-bit integer registers.
2848 (define_insn "*movdf_insn_sp32_v9"
2849 [(set (match_operand:V64 0 "nonimmediate_operand" "=b,e,e,T,W,U,T,f,*r,o")
2850 (match_operand:V64 1 "input_operand" "GY,e,W#F,GY,e,T,U,o#F,*roGYF,*rGYf"))]
2854 && (register_operand (operands[0], <V64:MODE>mode)
2855 || register_or_zero_operand (operands[1], <V64:MODE>mode))"
2867 [(set_attr "type" "fga,fpmove,load,store,store,load,store,*,*,*")
2868 (set_attr "length" "*,*,*,*,*,*,*,2,2,2")
2869 (set_attr "fptype" "double,double,*,*,*,*,*,*,*,*")])
2871 (define_insn "*movdf_insn_sp32_v9_no_fpu"
2872 [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,T,r,o")
2873 (match_operand:DF 1 "input_operand" "T,U,G,ro,rG"))]
2877 && (register_operand (operands[0], DFmode)
2878 || register_or_zero_operand (operands[1], DFmode))"
2885 [(set_attr "type" "load,store,store,*,*")
2886 (set_attr "length" "*,*,*,2,2")])
2888 ;; We have available both v9 double floats and 64-bit integer registers.
2889 (define_insn "*movdf_insn_sp64"
2890 [(set (match_operand:V64 0 "nonimmediate_operand" "=b,e,e,W,*r,*r,m,*r")
2891 (match_operand:V64 1 "input_operand" "GY,e,W#F,e,*rGY,m,*rGY,F"))]
2894 && (register_operand (operands[0], <V64:MODE>mode)
2895 || register_or_zero_operand (operands[1], <V64:MODE>mode))"
2905 [(set_attr "type" "fga,fpmove,load,store,*,load,store,*")
2906 (set_attr "length" "*,*,*,*,*,*,*,2")
2907 (set_attr "fptype" "double,double,*,*,*,*,*,*")])
2909 (define_insn "*movdf_insn_sp64_no_fpu"
2910 [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m")
2911 (match_operand:DF 1 "input_operand" "r,m,rG"))]
2914 && (register_operand (operands[0], DFmode)
2915 || register_or_zero_operand (operands[1], DFmode))"
2920 [(set_attr "type" "*,load,store")])
2922 ;; This pattern build DFmode constants in integer registers.
2924 [(set (match_operand:DF 0 "register_operand" "")
2925 (match_operand:DF 1 "const_double_operand" ""))]
2927 && (GET_CODE (operands[0]) == REG
2928 && REGNO (operands[0]) < 32)
2929 && ! const_zero_operand(operands[1], DFmode)
2930 && reload_completed"
2931 [(clobber (const_int 0))]
2936 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2937 REAL_VALUE_TO_TARGET_DOUBLE (r, l);
2938 operands[0] = gen_rtx_raw_REG (DImode, REGNO (operands[0]));
2942 #if HOST_BITS_PER_WIDE_INT == 32
2947 val = ((HOST_WIDE_INT)(unsigned long)l[1] |
2948 ((HOST_WIDE_INT)(unsigned long)l[0] << 32));
2949 emit_insn (gen_movdi (operands[0], gen_int_mode (val, DImode)));
2954 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
2955 gen_int_mode (l[0], SImode)));
2957 /* Slick... but this trick loses if this subreg constant part
2958 can be done in one insn. */
2960 && ! SPARC_SETHI32_P (l[0])
2961 && ! SPARC_SIMM13_P (l[0]))
2963 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2964 gen_highpart (SImode, operands[0])));
2968 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2969 gen_int_mode (l[1], SImode)));
2975 ;; Ok, now the splits to handle all the multi insn and
2976 ;; mis-aligned memory address cases.
2977 ;; In these splits please take note that we must be
2978 ;; careful when V9 but not ARCH64 because the integer
2979 ;; register DFmode cases must be handled.
2981 [(set (match_operand:V64 0 "register_operand" "")
2982 (match_operand:V64 1 "register_operand" ""))]
2985 && ((GET_CODE (operands[0]) == REG
2986 && REGNO (operands[0]) < 32)
2987 || (GET_CODE (operands[0]) == SUBREG
2988 && GET_CODE (SUBREG_REG (operands[0])) == REG
2989 && REGNO (SUBREG_REG (operands[0])) < 32))))
2990 && reload_completed"
2991 [(clobber (const_int 0))]
2993 rtx set_dest = operands[0];
2994 rtx set_src = operands[1];
2997 enum machine_mode half_mode;
2999 /* We can be expanded for DFmode or integral vector modes. */
3000 if (<V64:MODE>mode == DFmode)
3005 dest1 = gen_highpart (half_mode, set_dest);
3006 dest2 = gen_lowpart (half_mode, set_dest);
3007 src1 = gen_highpart (half_mode, set_src);
3008 src2 = gen_lowpart (half_mode, set_src);
3010 /* Now emit using the real source and destination we found, swapping
3011 the order if we detect overlap. */
3012 if (reg_overlap_mentioned_p (dest1, src2))
3014 emit_move_insn_1 (dest2, src2);
3015 emit_move_insn_1 (dest1, src1);
3019 emit_move_insn_1 (dest1, src1);
3020 emit_move_insn_1 (dest2, src2);
3026 [(set (match_operand:V64 0 "register_operand" "")
3027 (match_operand:V64 1 "memory_operand" ""))]
3030 && (((REGNO (operands[0]) % 2) != 0)
3031 || ! mem_min_alignment (operands[1], 8))
3032 && offsettable_memref_p (operands[1])"
3033 [(clobber (const_int 0))]
3035 enum machine_mode half_mode;
3038 /* We can be expanded for DFmode or integral vector modes. */
3039 if (<V64:MODE>mode == DFmode)
3044 word0 = adjust_address (operands[1], half_mode, 0);
3045 word1 = adjust_address (operands[1], half_mode, 4);
3047 if (reg_overlap_mentioned_p (gen_highpart (half_mode, operands[0]), word1))
3049 emit_move_insn_1 (gen_lowpart (half_mode, operands[0]), word1);
3050 emit_move_insn_1 (gen_highpart (half_mode, operands[0]), word0);
3054 emit_move_insn_1 (gen_highpart (half_mode, operands[0]), word0);
3055 emit_move_insn_1 (gen_lowpart (half_mode, operands[0]), word1);
3061 [(set (match_operand:V64 0 "memory_operand" "")
3062 (match_operand:V64 1 "register_operand" ""))]
3065 && (((REGNO (operands[1]) % 2) != 0)
3066 || ! mem_min_alignment (operands[0], 8))
3067 && offsettable_memref_p (operands[0])"
3068 [(clobber (const_int 0))]
3070 enum machine_mode half_mode;
3073 /* We can be expanded for DFmode or integral vector modes. */
3074 if (<V64:MODE>mode == DFmode)
3079 word0 = adjust_address (operands[0], half_mode, 0);
3080 word1 = adjust_address (operands[0], half_mode, 4);
3082 emit_move_insn_1 (word0, gen_highpart (half_mode, operands[1]));
3083 emit_move_insn_1 (word1, gen_lowpart (half_mode, operands[1]));
3088 [(set (match_operand:V64 0 "memory_operand" "")
3089 (match_operand:V64 1 "const_zero_operand" ""))]
3093 && ! mem_min_alignment (operands[0], 8)))
3094 && offsettable_memref_p (operands[0])"
3095 [(clobber (const_int 0))]
3097 enum machine_mode half_mode;
3100 /* We can be expanded for DFmode or integral vector modes. */
3101 if (<V64:MODE>mode == DFmode)
3106 dest1 = adjust_address (operands[0], half_mode, 0);
3107 dest2 = adjust_address (operands[0], half_mode, 4);
3109 emit_move_insn_1 (dest1, CONST0_RTX (half_mode));
3110 emit_move_insn_1 (dest2, CONST0_RTX (half_mode));
3115 [(set (match_operand:V64 0 "register_operand" "")
3116 (match_operand:V64 1 "const_zero_operand" ""))]
3119 && ((GET_CODE (operands[0]) == REG
3120 && REGNO (operands[0]) < 32)
3121 || (GET_CODE (operands[0]) == SUBREG
3122 && GET_CODE (SUBREG_REG (operands[0])) == REG
3123 && REGNO (SUBREG_REG (operands[0])) < 32))"
3124 [(clobber (const_int 0))]
3126 enum machine_mode half_mode;
3127 rtx set_dest = operands[0];
3130 /* We can be expanded for DFmode or integral vector modes. */
3131 if (<V64:MODE>mode == DFmode)
3136 dest1 = gen_highpart (half_mode, set_dest);
3137 dest2 = gen_lowpart (half_mode, set_dest);
3138 emit_move_insn_1 (dest1, CONST0_RTX (half_mode));
3139 emit_move_insn_1 (dest2, CONST0_RTX (half_mode));
3143 (define_expand "movtf"
3144 [(set (match_operand:TF 0 "general_operand" "")
3145 (match_operand:TF 1 "general_operand" ""))]
3148 /* Force TFmode constants into memory. */
3149 if (GET_CODE (operands[0]) == REG
3150 && CONSTANT_P (operands[1]))
3152 /* emit_group_store will send such bogosity to us when it is
3153 not storing directly into memory. So fix this up to avoid
3154 crashes in output_constant_pool. */
3155 if (operands [1] == const0_rtx)
3156 operands[1] = CONST0_RTX (TFmode);
3158 if (TARGET_VIS && const_zero_operand (operands[1], TFmode))
3161 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
3165 /* Handle MEM cases first, note that only v9 guarantees
3166 full 16-byte alignment for quads. */
3167 if (GET_CODE (operands[0]) == MEM)
3169 if (register_or_zero_operand (operands[1], TFmode))
3172 if (! reload_in_progress)
3174 operands[0] = validize_mem (operands[0]);
3175 operands[1] = force_reg (TFmode, operands[1]);
3179 /* Fixup PIC cases. */
3182 if (CONSTANT_P (operands[1])
3183 && pic_address_needs_scratch (operands[1]))
3184 operands[1] = legitimize_pic_address (operands[1], TFmode, 0);
3186 if (symbolic_operand (operands[1], TFmode))
3188 operands[1] = legitimize_pic_address (operands[1],
3190 (reload_in_progress ?
3200 (define_insn "*movtf_insn_sp32"
3201 [(set (match_operand:TF 0 "nonimmediate_operand" "=b,e,o,U,r")
3202 (match_operand:TF 1 "input_operand" "G,oe,GeUr,o,roG"))]
3205 && (register_operand (operands[0], TFmode)
3206 || register_or_zero_operand (operands[1], TFmode))"
3208 [(set_attr "length" "4")])
3210 ;; Exactly the same as above, except that all `e' cases are deleted.
3211 ;; This is necessary to prevent reload from ever trying to use a `e' reg
3214 (define_insn "*movtf_insn_sp32_no_fpu"
3215 [(set (match_operand:TF 0 "nonimmediate_operand" "=o,U,o,r,o")
3216 (match_operand:TF 1 "input_operand" "G,o,U,roG,r"))]
3219 && (register_operand (operands[0], TFmode)
3220 || register_or_zero_operand (operands[1], TFmode))"
3222 [(set_attr "length" "4")])
3224 (define_insn "*movtf_insn_sp64"
3225 [(set (match_operand:TF 0 "nonimmediate_operand" "=b,e,o,r")
3226 (match_operand:TF 1 "input_operand" "G,oe,Ger,roG"))]
3229 && ! TARGET_HARD_QUAD
3230 && (register_operand (operands[0], TFmode)
3231 || register_or_zero_operand (operands[1], TFmode))"
3233 [(set_attr "length" "2")])
3235 (define_insn "*movtf_insn_sp64_hq"
3236 [(set (match_operand:TF 0 "nonimmediate_operand" "=b,e,e,m,o,r")
3237 (match_operand:TF 1 "input_operand" "G,e,m,e,rG,roG"))]
3241 && (register_operand (operands[0], TFmode)
3242 || register_or_zero_operand (operands[1], TFmode))"
3250 [(set_attr "type" "*,fpmove,fpload,fpstore,*,*")
3251 (set_attr "length" "2,*,*,*,2,2")])
3253 (define_insn "*movtf_insn_sp64_no_fpu"
3254 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o")
3255 (match_operand:TF 1 "input_operand" "orG,rG"))]
3258 && (register_operand (operands[0], TFmode)
3259 || register_or_zero_operand (operands[1], TFmode))"
3261 [(set_attr "length" "2")])
3263 ;; Now all the splits to handle multi-insn TF mode moves.
3265 [(set (match_operand:TF 0 "register_operand" "")
3266 (match_operand:TF 1 "register_operand" ""))]
3270 && ! TARGET_HARD_QUAD)
3271 || ! fp_register_operand (operands[0], TFmode))"
3272 [(clobber (const_int 0))]
3274 rtx set_dest = operands[0];
3275 rtx set_src = operands[1];
3279 dest1 = gen_df_reg (set_dest, 0);
3280 dest2 = gen_df_reg (set_dest, 1);
3281 src1 = gen_df_reg (set_src, 0);
3282 src2 = gen_df_reg (set_src, 1);
3284 /* Now emit using the real source and destination we found, swapping
3285 the order if we detect overlap. */
3286 if (reg_overlap_mentioned_p (dest1, src2))
3288 emit_insn (gen_movdf (dest2, src2));
3289 emit_insn (gen_movdf (dest1, src1));
3293 emit_insn (gen_movdf (dest1, src1));
3294 emit_insn (gen_movdf (dest2, src2));
3300 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3301 (match_operand:TF 1 "const_zero_operand" ""))]
3303 [(clobber (const_int 0))]
3305 rtx set_dest = operands[0];
3308 switch (GET_CODE (set_dest))
3311 dest1 = gen_df_reg (set_dest, 0);
3312 dest2 = gen_df_reg (set_dest, 1);
3315 dest1 = adjust_address (set_dest, DFmode, 0);
3316 dest2 = adjust_address (set_dest, DFmode, 8);
3322 emit_insn (gen_movdf (dest1, CONST0_RTX (DFmode)));
3323 emit_insn (gen_movdf (dest2, CONST0_RTX (DFmode)));
3328 [(set (match_operand:TF 0 "register_operand" "")
3329 (match_operand:TF 1 "memory_operand" ""))]
3331 && offsettable_memref_p (operands[1])
3333 || ! TARGET_HARD_QUAD
3334 || ! fp_register_operand (operands[0], TFmode)))"
3335 [(clobber (const_int 0))]
3337 rtx word0 = adjust_address (operands[1], DFmode, 0);
3338 rtx word1 = adjust_address (operands[1], DFmode, 8);
3339 rtx set_dest, dest1, dest2;
3341 set_dest = operands[0];
3343 dest1 = gen_df_reg (set_dest, 0);
3344 dest2 = gen_df_reg (set_dest, 1);
3346 /* Now output, ordering such that we don't clobber any registers
3347 mentioned in the address. */
3348 if (reg_overlap_mentioned_p (dest1, word1))
3351 emit_insn (gen_movdf (dest2, word1));
3352 emit_insn (gen_movdf (dest1, word0));
3356 emit_insn (gen_movdf (dest1, word0));
3357 emit_insn (gen_movdf (dest2, word1));
3363 [(set (match_operand:TF 0 "memory_operand" "")
3364 (match_operand:TF 1 "register_operand" ""))]
3366 && offsettable_memref_p (operands[0])
3368 || ! TARGET_HARD_QUAD
3369 || ! fp_register_operand (operands[1], TFmode)))"
3370 [(clobber (const_int 0))]
3372 rtx set_src = operands[1];
3374 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 0),
3375 gen_df_reg (set_src, 0)));
3376 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 8),
3377 gen_df_reg (set_src, 1)));
3382 ;; SPARC-V9 conditional move instructions.
3384 ;; We can handle larger constants here for some flavors, but for now we keep
3385 ;; it simple and only allow those constants supported by all flavors.
3386 ;; Note that emit_conditional_move canonicalizes operands 2,3 so that operand
3387 ;; 3 contains the constant if one is present, but we handle either for
3388 ;; generality (sparc.c puts a constant in operand 2).
3390 (define_expand "movqicc"
3391 [(set (match_operand:QI 0 "register_operand" "")
3392 (if_then_else:QI (match_operand 1 "comparison_operator" "")
3393 (match_operand:QI 2 "arith10_operand" "")
3394 (match_operand:QI 3 "arith10_operand" "")))]
3397 enum rtx_code code = GET_CODE (operands[1]);
3399 if (GET_MODE (sparc_compare_op0) == DImode
3403 if (sparc_compare_op1 == const0_rtx
3404 && GET_CODE (sparc_compare_op0) == REG
3405 && GET_MODE (sparc_compare_op0) == DImode
3406 && v9_regcmp_p (code))
3408 operands[1] = gen_rtx_fmt_ee (code, DImode,
3409 sparc_compare_op0, sparc_compare_op1);
3413 rtx cc_reg = gen_compare_reg (code,
3414 sparc_compare_op0, sparc_compare_op1);
3415 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3419 (define_expand "movhicc"
3420 [(set (match_operand:HI 0 "register_operand" "")
3421 (if_then_else:HI (match_operand 1 "comparison_operator" "")
3422 (match_operand:HI 2 "arith10_operand" "")
3423 (match_operand:HI 3 "arith10_operand" "")))]
3426 enum rtx_code code = GET_CODE (operands[1]);
3428 if (GET_MODE (sparc_compare_op0) == DImode
3432 if (sparc_compare_op1 == const0_rtx
3433 && GET_CODE (sparc_compare_op0) == REG
3434 && GET_MODE (sparc_compare_op0) == DImode
3435 && v9_regcmp_p (code))
3437 operands[1] = gen_rtx_fmt_ee (code, DImode,
3438 sparc_compare_op0, sparc_compare_op1);
3442 rtx cc_reg = gen_compare_reg (code,
3443 sparc_compare_op0, sparc_compare_op1);
3444 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3448 (define_expand "movsicc"
3449 [(set (match_operand:SI 0 "register_operand" "")
3450 (if_then_else:SI (match_operand 1 "comparison_operator" "")
3451 (match_operand:SI 2 "arith10_operand" "")
3452 (match_operand:SI 3 "arith10_operand" "")))]
3455 enum rtx_code code = GET_CODE (operands[1]);
3456 enum machine_mode op0_mode = GET_MODE (sparc_compare_op0);
3458 if (sparc_compare_op1 == const0_rtx
3459 && GET_CODE (sparc_compare_op0) == REG
3460 && (TARGET_ARCH64 && op0_mode == DImode && v9_regcmp_p (code)))
3462 operands[1] = gen_rtx_fmt_ee (code, op0_mode,
3463 sparc_compare_op0, sparc_compare_op1);
3467 rtx cc_reg = gen_compare_reg (code,
3468 sparc_compare_op0, sparc_compare_op1);
3469 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg),
3470 cc_reg, const0_rtx);
3474 (define_expand "movdicc"
3475 [(set (match_operand:DI 0 "register_operand" "")
3476 (if_then_else:DI (match_operand 1 "comparison_operator" "")
3477 (match_operand:DI 2 "arith10_operand" "")
3478 (match_operand:DI 3 "arith10_operand" "")))]
3481 enum rtx_code code = GET_CODE (operands[1]);
3483 if (sparc_compare_op1 == const0_rtx
3484 && GET_CODE (sparc_compare_op0) == REG
3485 && GET_MODE (sparc_compare_op0) == DImode
3486 && v9_regcmp_p (code))
3488 operands[1] = gen_rtx_fmt_ee (code, DImode,
3489 sparc_compare_op0, sparc_compare_op1);
3493 rtx cc_reg = gen_compare_reg (code,
3494 sparc_compare_op0, sparc_compare_op1);
3495 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg),
3496 cc_reg, const0_rtx);
3500 (define_expand "movsfcc"
3501 [(set (match_operand:SF 0 "register_operand" "")
3502 (if_then_else:SF (match_operand 1 "comparison_operator" "")
3503 (match_operand:SF 2 "register_operand" "")
3504 (match_operand:SF 3 "register_operand" "")))]
3505 "TARGET_V9 && TARGET_FPU"
3507 enum rtx_code code = GET_CODE (operands[1]);
3509 if (GET_MODE (sparc_compare_op0) == DImode
3513 if (sparc_compare_op1 == const0_rtx
3514 && GET_CODE (sparc_compare_op0) == REG
3515 && GET_MODE (sparc_compare_op0) == DImode
3516 && v9_regcmp_p (code))
3518 operands[1] = gen_rtx_fmt_ee (code, DImode,
3519 sparc_compare_op0, sparc_compare_op1);
3523 rtx cc_reg = gen_compare_reg (code,
3524 sparc_compare_op0, sparc_compare_op1);
3525 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3529 (define_expand "movdfcc"
3530 [(set (match_operand:DF 0 "register_operand" "")
3531 (if_then_else:DF (match_operand 1 "comparison_operator" "")
3532 (match_operand:DF 2 "register_operand" "")
3533 (match_operand:DF 3 "register_operand" "")))]
3534 "TARGET_V9 && TARGET_FPU"
3536 enum rtx_code code = GET_CODE (operands[1]);
3538 if (GET_MODE (sparc_compare_op0) == DImode
3542 if (sparc_compare_op1 == const0_rtx
3543 && GET_CODE (sparc_compare_op0) == REG
3544 && GET_MODE (sparc_compare_op0) == DImode
3545 && v9_regcmp_p (code))
3547 operands[1] = gen_rtx_fmt_ee (code, DImode,
3548 sparc_compare_op0, sparc_compare_op1);
3552 rtx cc_reg = gen_compare_reg (code,
3553 sparc_compare_op0, sparc_compare_op1);
3554 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3558 (define_expand "movtfcc"
3559 [(set (match_operand:TF 0 "register_operand" "")
3560 (if_then_else:TF (match_operand 1 "comparison_operator" "")
3561 (match_operand:TF 2 "register_operand" "")
3562 (match_operand:TF 3 "register_operand" "")))]
3563 "TARGET_V9 && TARGET_FPU"
3565 enum rtx_code code = GET_CODE (operands[1]);
3567 if (GET_MODE (sparc_compare_op0) == DImode
3571 if (sparc_compare_op1 == const0_rtx
3572 && GET_CODE (sparc_compare_op0) == REG
3573 && GET_MODE (sparc_compare_op0) == DImode
3574 && v9_regcmp_p (code))
3576 operands[1] = gen_rtx_fmt_ee (code, DImode,
3577 sparc_compare_op0, sparc_compare_op1);
3581 rtx cc_reg = gen_compare_reg (code,
3582 sparc_compare_op0, sparc_compare_op1);
3583 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3587 ;; Conditional move define_insns.
3589 (define_insn "*movqi_cc_sp64"
3590 [(set (match_operand:QI 0 "register_operand" "=r,r")
3591 (if_then_else:QI (match_operator 1 "comparison_operator"
3592 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
3594 (match_operand:QI 3 "arith11_operand" "rL,0")
3595 (match_operand:QI 4 "arith11_operand" "0,rL")))]
3599 mov%c1\t%x2, %4, %0"
3600 [(set_attr "type" "cmove")])
3602 (define_insn "*movhi_cc_sp64"
3603 [(set (match_operand:HI 0 "register_operand" "=r,r")
3604 (if_then_else:HI (match_operator 1 "comparison_operator"
3605 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
3607 (match_operand:HI 3 "arith11_operand" "rL,0")
3608 (match_operand:HI 4 "arith11_operand" "0,rL")))]
3612 mov%c1\t%x2, %4, %0"
3613 [(set_attr "type" "cmove")])
3615 (define_insn "*movsi_cc_sp64"
3616 [(set (match_operand:SI 0 "register_operand" "=r,r")
3617 (if_then_else:SI (match_operator 1 "comparison_operator"
3618 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
3620 (match_operand:SI 3 "arith11_operand" "rL,0")
3621 (match_operand:SI 4 "arith11_operand" "0,rL")))]
3625 mov%c1\t%x2, %4, %0"
3626 [(set_attr "type" "cmove")])
3628 (define_insn "*movdi_cc_sp64"
3629 [(set (match_operand:DI 0 "register_operand" "=r,r")
3630 (if_then_else:DI (match_operator 1 "comparison_operator"
3631 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
3633 (match_operand:DI 3 "arith11_operand" "rL,0")
3634 (match_operand:DI 4 "arith11_operand" "0,rL")))]
3638 mov%c1\t%x2, %4, %0"
3639 [(set_attr "type" "cmove")])
3641 (define_insn "*movdi_cc_sp64_trunc"
3642 [(set (match_operand:SI 0 "register_operand" "=r,r")
3643 (if_then_else:SI (match_operator 1 "comparison_operator"
3644 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
3646 (match_operand:SI 3 "arith11_operand" "rL,0")
3647 (match_operand:SI 4 "arith11_operand" "0,rL")))]
3651 mov%c1\t%x2, %4, %0"
3652 [(set_attr "type" "cmove")])
3654 (define_insn "*movsf_cc_sp64"
3655 [(set (match_operand:SF 0 "register_operand" "=f,f")
3656 (if_then_else:SF (match_operator 1 "comparison_operator"
3657 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
3659 (match_operand:SF 3 "register_operand" "f,0")
3660 (match_operand:SF 4 "register_operand" "0,f")))]
3661 "TARGET_V9 && TARGET_FPU"
3663 fmovs%C1\t%x2, %3, %0
3664 fmovs%c1\t%x2, %4, %0"
3665 [(set_attr "type" "fpcmove")])
3667 (define_insn "movdf_cc_sp64"
3668 [(set (match_operand:DF 0 "register_operand" "=e,e")
3669 (if_then_else:DF (match_operator 1 "comparison_operator"
3670 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
3672 (match_operand:DF 3 "register_operand" "e,0")
3673 (match_operand:DF 4 "register_operand" "0,e")))]
3674 "TARGET_V9 && TARGET_FPU"
3676 fmovd%C1\t%x2, %3, %0
3677 fmovd%c1\t%x2, %4, %0"
3678 [(set_attr "type" "fpcmove")
3679 (set_attr "fptype" "double")])
3681 (define_insn "*movtf_cc_hq_sp64"
3682 [(set (match_operand:TF 0 "register_operand" "=e,e")
3683 (if_then_else:TF (match_operator 1 "comparison_operator"
3684 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
3686 (match_operand:TF 3 "register_operand" "e,0")
3687 (match_operand:TF 4 "register_operand" "0,e")))]
3688 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
3690 fmovq%C1\t%x2, %3, %0
3691 fmovq%c1\t%x2, %4, %0"
3692 [(set_attr "type" "fpcmove")])
3694 (define_insn_and_split "*movtf_cc_sp64"
3695 [(set (match_operand:TF 0 "register_operand" "=e,e")
3696 (if_then_else:TF (match_operator 1 "comparison_operator"
3697 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
3699 (match_operand:TF 3 "register_operand" "e,0")
3700 (match_operand:TF 4 "register_operand" "0,e")))]
3701 "TARGET_V9 && TARGET_FPU && !TARGET_HARD_QUAD"
3703 "&& reload_completed"
3704 [(clobber (const_int 0))]
3706 rtx set_dest = operands[0];
3707 rtx set_srca = operands[3];
3708 rtx set_srcb = operands[4];
3709 int third = rtx_equal_p (set_dest, set_srca);
3711 rtx srca1, srca2, srcb1, srcb2;
3713 dest1 = gen_df_reg (set_dest, 0);
3714 dest2 = gen_df_reg (set_dest, 1);
3715 srca1 = gen_df_reg (set_srca, 0);
3716 srca2 = gen_df_reg (set_srca, 1);
3717 srcb1 = gen_df_reg (set_srcb, 0);
3718 srcb2 = gen_df_reg (set_srcb, 1);
3720 /* Now emit using the real source and destination we found, swapping
3721 the order if we detect overlap. */
3722 if ((third && reg_overlap_mentioned_p (dest1, srcb2))
3723 || (!third && reg_overlap_mentioned_p (dest1, srca2)))
3725 emit_insn (gen_movdf_cc_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
3726 emit_insn (gen_movdf_cc_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
3730 emit_insn (gen_movdf_cc_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
3731 emit_insn (gen_movdf_cc_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
3735 [(set_attr "length" "2")])
3737 (define_insn "*movqi_cc_reg_sp64"
3738 [(set (match_operand:QI 0 "register_operand" "=r,r")
3739 (if_then_else:QI (match_operator 1 "v9_register_compare_operator"
3740 [(match_operand:DI 2 "register_operand" "r,r")
3742 (match_operand:QI 3 "arith10_operand" "rM,0")
3743 (match_operand:QI 4 "arith10_operand" "0,rM")))]
3746 movr%D1\t%2, %r3, %0
3747 movr%d1\t%2, %r4, %0"
3748 [(set_attr "type" "cmove")])
3750 (define_insn "*movhi_cc_reg_sp64"
3751 [(set (match_operand:HI 0 "register_operand" "=r,r")
3752 (if_then_else:HI (match_operator 1 "v9_register_compare_operator"
3753 [(match_operand:DI 2 "register_operand" "r,r")
3755 (match_operand:HI 3 "arith10_operand" "rM,0")
3756 (match_operand:HI 4 "arith10_operand" "0,rM")))]
3759 movr%D1\t%2, %r3, %0
3760 movr%d1\t%2, %r4, %0"
3761 [(set_attr "type" "cmove")])
3763 (define_insn "*movsi_cc_reg_sp64"
3764 [(set (match_operand:SI 0 "register_operand" "=r,r")
3765 (if_then_else:SI (match_operator 1 "v9_register_compare_operator"
3766 [(match_operand:DI 2 "register_operand" "r,r")
3768 (match_operand:SI 3 "arith10_operand" "rM,0")
3769 (match_operand:SI 4 "arith10_operand" "0,rM")))]
3772 movr%D1\t%2, %r3, %0
3773 movr%d1\t%2, %r4, %0"
3774 [(set_attr "type" "cmove")])
3776 (define_insn "*movdi_cc_reg_sp64"
3777 [(set (match_operand:DI 0 "register_operand" "=r,r")
3778 (if_then_else:DI (match_operator 1 "v9_register_compare_operator"
3779 [(match_operand:DI 2 "register_operand" "r,r")
3781 (match_operand:DI 3 "arith10_operand" "rM,0")
3782 (match_operand:DI 4 "arith10_operand" "0,rM")))]
3785 movr%D1\t%2, %r3, %0
3786 movr%d1\t%2, %r4, %0"
3787 [(set_attr "type" "cmove")])
3789 (define_insn "*movsf_cc_reg_sp64"
3790 [(set (match_operand:SF 0 "register_operand" "=f,f")
3791 (if_then_else:SF (match_operator 1 "v9_register_compare_operator"
3792 [(match_operand:DI 2 "register_operand" "r,r")
3794 (match_operand:SF 3 "register_operand" "f,0")
3795 (match_operand:SF 4 "register_operand" "0,f")))]
3796 "TARGET_ARCH64 && TARGET_FPU"
3798 fmovrs%D1\t%2, %3, %0
3799 fmovrs%d1\t%2, %4, %0"
3800 [(set_attr "type" "fpcrmove")])
3802 (define_insn "movdf_cc_reg_sp64"
3803 [(set (match_operand:DF 0 "register_operand" "=e,e")
3804 (if_then_else:DF (match_operator 1 "v9_register_compare_operator"
3805 [(match_operand:DI 2 "register_operand" "r,r")
3807 (match_operand:DF 3 "register_operand" "e,0")
3808 (match_operand:DF 4 "register_operand" "0,e")))]
3809 "TARGET_ARCH64 && TARGET_FPU"
3811 fmovrd%D1\t%2, %3, %0
3812 fmovrd%d1\t%2, %4, %0"
3813 [(set_attr "type" "fpcrmove")
3814 (set_attr "fptype" "double")])
3816 (define_insn "*movtf_cc_reg_hq_sp64"
3817 [(set (match_operand:TF 0 "register_operand" "=e,e")
3818 (if_then_else:TF (match_operator 1 "v9_register_compare_operator"
3819 [(match_operand:DI 2 "register_operand" "r,r")
3821 (match_operand:TF 3 "register_operand" "e,0")
3822 (match_operand:TF 4 "register_operand" "0,e")))]
3823 "TARGET_ARCH64 && TARGET_FPU && TARGET_HARD_QUAD"
3825 fmovrq%D1\t%2, %3, %0
3826 fmovrq%d1\t%2, %4, %0"
3827 [(set_attr "type" "fpcrmove")])
3829 (define_insn_and_split "*movtf_cc_reg_sp64"
3830 [(set (match_operand:TF 0 "register_operand" "=e,e")
3831 (if_then_else:TF (match_operator 1 "v9_register_compare_operator"
3832 [(match_operand:DI 2 "register_operand" "r,r")
3834 (match_operand:TF 3 "register_operand" "e,0")
3835 (match_operand:TF 4 "register_operand" "0,e")))]
3836 "TARGET_ARCH64 && TARGET_FPU && ! TARGET_HARD_QUAD"
3838 "&& reload_completed"
3839 [(clobber (const_int 0))]
3841 rtx set_dest = operands[0];
3842 rtx set_srca = operands[3];
3843 rtx set_srcb = operands[4];
3844 int third = rtx_equal_p (set_dest, set_srca);
3846 rtx srca1, srca2, srcb1, srcb2;
3848 dest1 = gen_df_reg (set_dest, 0);
3849 dest2 = gen_df_reg (set_dest, 1);
3850 srca1 = gen_df_reg (set_srca, 0);
3851 srca2 = gen_df_reg (set_srca, 1);
3852 srcb1 = gen_df_reg (set_srcb, 0);
3853 srcb2 = gen_df_reg (set_srcb, 1);
3855 /* Now emit using the real source and destination we found, swapping
3856 the order if we detect overlap. */
3857 if ((third && reg_overlap_mentioned_p (dest1, srcb2))
3858 || (!third && reg_overlap_mentioned_p (dest1, srca2)))
3860 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
3861 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
3865 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
3866 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
3870 [(set_attr "length" "2")])
3873 ;; Zero-extension instructions
3875 ;; These patterns originally accepted general_operands, however, slightly
3876 ;; better code is generated by only accepting register_operands, and then
3877 ;; letting combine generate the ldu[hb] insns.
3879 (define_expand "zero_extendhisi2"
3880 [(set (match_operand:SI 0 "register_operand" "")
3881 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
3884 rtx temp = gen_reg_rtx (SImode);
3885 rtx shift_16 = GEN_INT (16);
3886 int op1_subbyte = 0;
3888 if (GET_CODE (operand1) == SUBREG)
3890 op1_subbyte = SUBREG_BYTE (operand1);
3891 op1_subbyte /= GET_MODE_SIZE (SImode);
3892 op1_subbyte *= GET_MODE_SIZE (SImode);
3893 operand1 = XEXP (operand1, 0);
3896 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3898 emit_insn (gen_lshrsi3 (operand0, temp, shift_16));
3902 (define_insn "*zero_extendhisi2_insn"
3903 [(set (match_operand:SI 0 "register_operand" "=r")
3904 (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
3907 [(set_attr "type" "load")
3908 (set_attr "us3load_type" "3cycle")])
3910 (define_expand "zero_extendqihi2"
3911 [(set (match_operand:HI 0 "register_operand" "")
3912 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
3916 (define_insn "*zero_extendqihi2_insn"
3917 [(set (match_operand:HI 0 "register_operand" "=r,r")
3918 (zero_extend:HI (match_operand:QI 1 "input_operand" "r,m")))]
3919 "GET_CODE (operands[1]) != CONST_INT"
3923 [(set_attr "type" "*,load")
3924 (set_attr "us3load_type" "*,3cycle")])
3926 (define_expand "zero_extendqisi2"
3927 [(set (match_operand:SI 0 "register_operand" "")
3928 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
3932 (define_insn "*zero_extendqisi2_insn"
3933 [(set (match_operand:SI 0 "register_operand" "=r,r")
3934 (zero_extend:SI (match_operand:QI 1 "input_operand" "r,m")))]
3935 "GET_CODE (operands[1]) != CONST_INT"
3939 [(set_attr "type" "*,load")
3940 (set_attr "us3load_type" "*,3cycle")])
3942 (define_expand "zero_extendqidi2"
3943 [(set (match_operand:DI 0 "register_operand" "")
3944 (zero_extend:DI (match_operand:QI 1 "register_operand" "")))]
3948 (define_insn "*zero_extendqidi2_insn"
3949 [(set (match_operand:DI 0 "register_operand" "=r,r")
3950 (zero_extend:DI (match_operand:QI 1 "input_operand" "r,m")))]
3951 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
3955 [(set_attr "type" "*,load")
3956 (set_attr "us3load_type" "*,3cycle")])
3958 (define_expand "zero_extendhidi2"
3959 [(set (match_operand:DI 0 "register_operand" "")
3960 (zero_extend:DI (match_operand:HI 1 "register_operand" "")))]
3963 rtx temp = gen_reg_rtx (DImode);
3964 rtx shift_48 = GEN_INT (48);
3965 int op1_subbyte = 0;
3967 if (GET_CODE (operand1) == SUBREG)
3969 op1_subbyte = SUBREG_BYTE (operand1);
3970 op1_subbyte /= GET_MODE_SIZE (DImode);
3971 op1_subbyte *= GET_MODE_SIZE (DImode);
3972 operand1 = XEXP (operand1, 0);
3975 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
3977 emit_insn (gen_lshrdi3 (operand0, temp, shift_48));
3981 (define_insn "*zero_extendhidi2_insn"
3982 [(set (match_operand:DI 0 "register_operand" "=r")
3983 (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
3986 [(set_attr "type" "load")
3987 (set_attr "us3load_type" "3cycle")])
3989 ;; ??? Write truncdisi pattern using sra?
3991 (define_expand "zero_extendsidi2"
3992 [(set (match_operand:DI 0 "register_operand" "")
3993 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
3997 (define_insn "*zero_extendsidi2_insn_sp64"
3998 [(set (match_operand:DI 0 "register_operand" "=r,r")
3999 (zero_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
4000 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
4004 [(set_attr "type" "shift,load")])
4006 (define_insn_and_split "*zero_extendsidi2_insn_sp32"
4007 [(set (match_operand:DI 0 "register_operand" "=r")
4008 (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
4011 "&& reload_completed"
4012 [(set (match_dup 2) (match_dup 3))
4013 (set (match_dup 4) (match_dup 5))]
4017 dest1 = gen_highpart (SImode, operands[0]);
4018 dest2 = gen_lowpart (SImode, operands[0]);
4020 /* Swap the order in case of overlap. */
4021 if (REGNO (dest1) == REGNO (operands[1]))
4023 operands[2] = dest2;
4024 operands[3] = operands[1];
4025 operands[4] = dest1;
4026 operands[5] = const0_rtx;
4030 operands[2] = dest1;
4031 operands[3] = const0_rtx;
4032 operands[4] = dest2;
4033 operands[5] = operands[1];
4036 [(set_attr "length" "2")])
4038 ;; Simplify comparisons of extended values.
4040 (define_insn "*cmp_zero_extendqisi2"
4042 (compare:CC (zero_extend:SI (match_operand:QI 0 "register_operand" "r"))
4045 "andcc\t%0, 0xff, %%g0"
4046 [(set_attr "type" "compare")])
4048 (define_insn "*cmp_zero_qi"
4050 (compare:CC (match_operand:QI 0 "register_operand" "r")
4053 "andcc\t%0, 0xff, %%g0"
4054 [(set_attr "type" "compare")])
4056 (define_insn "*cmp_zero_extendqisi2_set"
4058 (compare:CC (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
4060 (set (match_operand:SI 0 "register_operand" "=r")
4061 (zero_extend:SI (match_dup 1)))]
4063 "andcc\t%1, 0xff, %0"
4064 [(set_attr "type" "compare")])
4066 (define_insn "*cmp_zero_extendqisi2_andcc_set"
4068 (compare:CC (and:SI (match_operand:SI 1 "register_operand" "r")
4071 (set (match_operand:SI 0 "register_operand" "=r")
4072 (zero_extend:SI (subreg:QI (match_dup 1) 0)))]
4074 "andcc\t%1, 0xff, %0"
4075 [(set_attr "type" "compare")])
4077 (define_insn "*cmp_zero_extendqidi2"
4079 (compare:CCX (zero_extend:DI (match_operand:QI 0 "register_operand" "r"))
4082 "andcc\t%0, 0xff, %%g0"
4083 [(set_attr "type" "compare")])
4085 (define_insn "*cmp_zero_qi_sp64"
4087 (compare:CCX (match_operand:QI 0 "register_operand" "r")
4090 "andcc\t%0, 0xff, %%g0"
4091 [(set_attr "type" "compare")])
4093 (define_insn "*cmp_zero_extendqidi2_set"
4095 (compare:CCX (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
4097 (set (match_operand:DI 0 "register_operand" "=r")
4098 (zero_extend:DI (match_dup 1)))]
4100 "andcc\t%1, 0xff, %0"
4101 [(set_attr "type" "compare")])
4103 (define_insn "*cmp_zero_extendqidi2_andcc_set"
4105 (compare:CCX (and:DI (match_operand:DI 1 "register_operand" "r")
4108 (set (match_operand:DI 0 "register_operand" "=r")
4109 (zero_extend:DI (subreg:QI (match_dup 1) 0)))]
4111 "andcc\t%1, 0xff, %0"
4112 [(set_attr "type" "compare")])
4114 ;; Similarly, handle {SI,DI}->QI mode truncation followed by a compare.
4116 (define_insn "*cmp_siqi_trunc"
4118 (compare:CC (subreg:QI (match_operand:SI 0 "register_operand" "r") 3)
4121 "andcc\t%0, 0xff, %%g0"
4122 [(set_attr "type" "compare")])
4124 (define_insn "*cmp_siqi_trunc_set"
4126 (compare:CC (subreg:QI (match_operand:SI 1 "register_operand" "r") 3)
4128 (set (match_operand:QI 0 "register_operand" "=r")
4129 (subreg:QI (match_dup 1) 3))]
4131 "andcc\t%1, 0xff, %0"
4132 [(set_attr "type" "compare")])
4134 (define_insn "*cmp_diqi_trunc"
4136 (compare:CC (subreg:QI (match_operand:DI 0 "register_operand" "r") 7)
4139 "andcc\t%0, 0xff, %%g0"
4140 [(set_attr "type" "compare")])
4142 (define_insn "*cmp_diqi_trunc_set"
4144 (compare:CC (subreg:QI (match_operand:DI 1 "register_operand" "r") 7)
4146 (set (match_operand:QI 0 "register_operand" "=r")
4147 (subreg:QI (match_dup 1) 7))]
4149 "andcc\t%1, 0xff, %0"
4150 [(set_attr "type" "compare")])
4153 ;; Sign-extension instructions
4155 ;; These patterns originally accepted general_operands, however, slightly
4156 ;; better code is generated by only accepting register_operands, and then
4157 ;; letting combine generate the lds[hb] insns.
4159 (define_expand "extendhisi2"
4160 [(set (match_operand:SI 0 "register_operand" "")
4161 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
4164 rtx temp = gen_reg_rtx (SImode);
4165 rtx shift_16 = GEN_INT (16);
4166 int op1_subbyte = 0;
4168 if (GET_CODE (operand1) == SUBREG)
4170 op1_subbyte = SUBREG_BYTE (operand1);
4171 op1_subbyte /= GET_MODE_SIZE (SImode);
4172 op1_subbyte *= GET_MODE_SIZE (SImode);
4173 operand1 = XEXP (operand1, 0);
4176 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4178 emit_insn (gen_ashrsi3 (operand0, temp, shift_16));
4182 (define_insn "*sign_extendhisi2_insn"
4183 [(set (match_operand:SI 0 "register_operand" "=r")
4184 (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
4187 [(set_attr "type" "sload")
4188 (set_attr "us3load_type" "3cycle")])
4190 (define_expand "extendqihi2"
4191 [(set (match_operand:HI 0 "register_operand" "")
4192 (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
4195 rtx temp = gen_reg_rtx (SImode);
4196 rtx shift_24 = GEN_INT (24);
4197 int op1_subbyte = 0;
4198 int op0_subbyte = 0;
4200 if (GET_CODE (operand1) == SUBREG)
4202 op1_subbyte = SUBREG_BYTE (operand1);
4203 op1_subbyte /= GET_MODE_SIZE (SImode);
4204 op1_subbyte *= GET_MODE_SIZE (SImode);
4205 operand1 = XEXP (operand1, 0);
4207 if (GET_CODE (operand0) == SUBREG)
4209 op0_subbyte = SUBREG_BYTE (operand0);
4210 op0_subbyte /= GET_MODE_SIZE (SImode);
4211 op0_subbyte *= GET_MODE_SIZE (SImode);
4212 operand0 = XEXP (operand0, 0);
4214 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4216 if (GET_MODE (operand0) != SImode)
4217 operand0 = gen_rtx_SUBREG (SImode, operand0, op0_subbyte);
4218 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
4222 (define_insn "*sign_extendqihi2_insn"
4223 [(set (match_operand:HI 0 "register_operand" "=r")
4224 (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
4227 [(set_attr "type" "sload")
4228 (set_attr "us3load_type" "3cycle")])
4230 (define_expand "extendqisi2"
4231 [(set (match_operand:SI 0 "register_operand" "")
4232 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
4235 rtx temp = gen_reg_rtx (SImode);
4236 rtx shift_24 = GEN_INT (24);
4237 int op1_subbyte = 0;
4239 if (GET_CODE (operand1) == SUBREG)
4241 op1_subbyte = SUBREG_BYTE (operand1);
4242 op1_subbyte /= GET_MODE_SIZE (SImode);
4243 op1_subbyte *= GET_MODE_SIZE (SImode);
4244 operand1 = XEXP (operand1, 0);
4247 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4249 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
4253 (define_insn "*sign_extendqisi2_insn"
4254 [(set (match_operand:SI 0 "register_operand" "=r")
4255 (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
4258 [(set_attr "type" "sload")
4259 (set_attr "us3load_type" "3cycle")])
4261 (define_expand "extendqidi2"
4262 [(set (match_operand:DI 0 "register_operand" "")
4263 (sign_extend:DI (match_operand:QI 1 "register_operand" "")))]
4266 rtx temp = gen_reg_rtx (DImode);
4267 rtx shift_56 = GEN_INT (56);
4268 int op1_subbyte = 0;
4270 if (GET_CODE (operand1) == SUBREG)
4272 op1_subbyte = SUBREG_BYTE (operand1);
4273 op1_subbyte /= GET_MODE_SIZE (DImode);
4274 op1_subbyte *= GET_MODE_SIZE (DImode);
4275 operand1 = XEXP (operand1, 0);
4278 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
4280 emit_insn (gen_ashrdi3 (operand0, temp, shift_56));
4284 (define_insn "*sign_extendqidi2_insn"
4285 [(set (match_operand:DI 0 "register_operand" "=r")
4286 (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
4289 [(set_attr "type" "sload")
4290 (set_attr "us3load_type" "3cycle")])
4292 (define_expand "extendhidi2"
4293 [(set (match_operand:DI 0 "register_operand" "")
4294 (sign_extend:DI (match_operand:HI 1 "register_operand" "")))]
4297 rtx temp = gen_reg_rtx (DImode);
4298 rtx shift_48 = GEN_INT (48);
4299 int op1_subbyte = 0;
4301 if (GET_CODE (operand1) == SUBREG)
4303 op1_subbyte = SUBREG_BYTE (operand1);
4304 op1_subbyte /= GET_MODE_SIZE (DImode);
4305 op1_subbyte *= GET_MODE_SIZE (DImode);
4306 operand1 = XEXP (operand1, 0);
4309 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
4311 emit_insn (gen_ashrdi3 (operand0, temp, shift_48));
4315 (define_insn "*sign_extendhidi2_insn"
4316 [(set (match_operand:DI 0 "register_operand" "=r")
4317 (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
4320 [(set_attr "type" "sload")
4321 (set_attr "us3load_type" "3cycle")])
4323 (define_expand "extendsidi2"
4324 [(set (match_operand:DI 0 "register_operand" "")
4325 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
4329 (define_insn "*sign_extendsidi2_insn"
4330 [(set (match_operand:DI 0 "register_operand" "=r,r")
4331 (sign_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
4336 [(set_attr "type" "shift,sload")
4337 (set_attr "us3load_type" "*,3cycle")])
4340 ;; Special pattern for optimizing bit-field compares. This is needed
4341 ;; because combine uses this as a canonical form.
4343 (define_insn "*cmp_zero_extract"
4346 (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
4347 (match_operand:SI 1 "small_int_operand" "I")
4348 (match_operand:SI 2 "small_int_operand" "I"))
4350 "INTVAL (operands[2]) > 19"
4352 int len = INTVAL (operands[1]);
4353 int pos = 32 - INTVAL (operands[2]) - len;
4354 HOST_WIDE_INT mask = ((1 << len) - 1) << pos;
4355 operands[1] = GEN_INT (mask);
4356 return "andcc\t%0, %1, %%g0";
4358 [(set_attr "type" "compare")])
4360 (define_insn "*cmp_zero_extract_sp64"
4363 (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
4364 (match_operand:SI 1 "small_int_operand" "I")
4365 (match_operand:SI 2 "small_int_operand" "I"))
4367 "TARGET_ARCH64 && INTVAL (operands[2]) > 51"
4369 int len = INTVAL (operands[1]);
4370 int pos = 64 - INTVAL (operands[2]) - len;
4371 HOST_WIDE_INT mask = (((unsigned HOST_WIDE_INT) 1 << len) - 1) << pos;
4372 operands[1] = GEN_INT (mask);
4373 return "andcc\t%0, %1, %%g0";
4375 [(set_attr "type" "compare")])
4378 ;; Conversions between float, double and long double.
4380 (define_insn "extendsfdf2"
4381 [(set (match_operand:DF 0 "register_operand" "=e")
4383 (match_operand:SF 1 "register_operand" "f")))]
4386 [(set_attr "type" "fp")
4387 (set_attr "fptype" "double")])
4389 (define_expand "extendsftf2"
4390 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4392 (match_operand:SF 1 "register_operand" "")))]
4393 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4394 "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
4396 (define_insn "*extendsftf2_hq"
4397 [(set (match_operand:TF 0 "register_operand" "=e")
4399 (match_operand:SF 1 "register_operand" "f")))]
4400 "TARGET_FPU && TARGET_HARD_QUAD"
4402 [(set_attr "type" "fp")])
4404 (define_expand "extenddftf2"
4405 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4407 (match_operand:DF 1 "register_operand" "")))]
4408 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4409 "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
4411 (define_insn "*extenddftf2_hq"
4412 [(set (match_operand:TF 0 "register_operand" "=e")
4414 (match_operand:DF 1 "register_operand" "e")))]
4415 "TARGET_FPU && TARGET_HARD_QUAD"
4417 [(set_attr "type" "fp")])
4419 (define_insn "truncdfsf2"
4420 [(set (match_operand:SF 0 "register_operand" "=f")
4422 (match_operand:DF 1 "register_operand" "e")))]
4425 [(set_attr "type" "fp")
4426 (set_attr "fptype" "double")])
4428 (define_expand "trunctfsf2"
4429 [(set (match_operand:SF 0 "register_operand" "")
4431 (match_operand:TF 1 "general_operand" "")))]
4432 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4433 "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
4435 (define_insn "*trunctfsf2_hq"
4436 [(set (match_operand:SF 0 "register_operand" "=f")
4438 (match_operand:TF 1 "register_operand" "e")))]
4439 "TARGET_FPU && TARGET_HARD_QUAD"
4441 [(set_attr "type" "fp")])
4443 (define_expand "trunctfdf2"
4444 [(set (match_operand:DF 0 "register_operand" "")
4446 (match_operand:TF 1 "general_operand" "")))]
4447 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4448 "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
4450 (define_insn "*trunctfdf2_hq"
4451 [(set (match_operand:DF 0 "register_operand" "=e")
4453 (match_operand:TF 1 "register_operand" "e")))]
4454 "TARGET_FPU && TARGET_HARD_QUAD"
4456 [(set_attr "type" "fp")])
4459 ;; Conversion between fixed point and floating point.
4461 (define_insn "floatsisf2"
4462 [(set (match_operand:SF 0 "register_operand" "=f")
4463 (float:SF (match_operand:SI 1 "register_operand" "f")))]
4466 [(set_attr "type" "fp")
4467 (set_attr "fptype" "double")])
4469 (define_insn "floatsidf2"
4470 [(set (match_operand:DF 0 "register_operand" "=e")
4471 (float:DF (match_operand:SI 1 "register_operand" "f")))]
4474 [(set_attr "type" "fp")
4475 (set_attr "fptype" "double")])
4477 (define_expand "floatsitf2"
4478 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4479 (float:TF (match_operand:SI 1 "register_operand" "")))]
4480 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4481 "emit_tfmode_cvt (FLOAT, operands); DONE;")
4483 (define_insn "*floatsitf2_hq"
4484 [(set (match_operand:TF 0 "register_operand" "=e")
4485 (float:TF (match_operand:SI 1 "register_operand" "f")))]
4486 "TARGET_FPU && TARGET_HARD_QUAD"
4488 [(set_attr "type" "fp")])
4490 (define_expand "floatunssitf2"
4491 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4492 (unsigned_float:TF (match_operand:SI 1 "register_operand" "")))]
4493 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4494 "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
4496 ;; Now the same for 64 bit sources.
4498 (define_insn "floatdisf2"
4499 [(set (match_operand:SF 0 "register_operand" "=f")
4500 (float:SF (match_operand:DI 1 "register_operand" "e")))]
4501 "TARGET_V9 && TARGET_FPU"
4503 [(set_attr "type" "fp")
4504 (set_attr "fptype" "double")])
4506 (define_expand "floatunsdisf2"
4507 [(use (match_operand:SF 0 "register_operand" ""))
4508 (use (match_operand:DI 1 "general_operand" ""))]
4509 "TARGET_ARCH64 && TARGET_FPU"
4510 "sparc_emit_floatunsdi (operands, SFmode); DONE;")
4512 (define_insn "floatdidf2"
4513 [(set (match_operand:DF 0 "register_operand" "=e")
4514 (float:DF (match_operand:DI 1 "register_operand" "e")))]
4515 "TARGET_V9 && TARGET_FPU"
4517 [(set_attr "type" "fp")
4518 (set_attr "fptype" "double")])
4520 (define_expand "floatunsdidf2"
4521 [(use (match_operand:DF 0 "register_operand" ""))
4522 (use (match_operand:DI 1 "general_operand" ""))]
4523 "TARGET_ARCH64 && TARGET_FPU"
4524 "sparc_emit_floatunsdi (operands, DFmode); DONE;")
4526 (define_expand "floatditf2"
4527 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4528 (float:TF (match_operand:DI 1 "register_operand" "")))]
4529 "TARGET_FPU && TARGET_V9 && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4530 "emit_tfmode_cvt (FLOAT, operands); DONE;")
4532 (define_insn "*floatditf2_hq"
4533 [(set (match_operand:TF 0 "register_operand" "=e")
4534 (float:TF (match_operand:DI 1 "register_operand" "e")))]
4535 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
4537 [(set_attr "type" "fp")])
4539 (define_expand "floatunsditf2"
4540 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4541 (unsigned_float:TF (match_operand:DI 1 "register_operand" "")))]
4542 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4543 "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
4545 ;; Convert a float to an actual integer.
4546 ;; Truncation is performed as part of the conversion.
4548 (define_insn "fix_truncsfsi2"
4549 [(set (match_operand:SI 0 "register_operand" "=f")
4550 (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
4553 [(set_attr "type" "fp")
4554 (set_attr "fptype" "double")])
4556 (define_insn "fix_truncdfsi2"
4557 [(set (match_operand:SI 0 "register_operand" "=f")
4558 (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
4561 [(set_attr "type" "fp")
4562 (set_attr "fptype" "double")])
4564 (define_expand "fix_trunctfsi2"
4565 [(set (match_operand:SI 0 "register_operand" "")
4566 (fix:SI (match_operand:TF 1 "general_operand" "")))]
4567 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4568 "emit_tfmode_cvt (FIX, operands); DONE;")
4570 (define_insn "*fix_trunctfsi2_hq"
4571 [(set (match_operand:SI 0 "register_operand" "=f")
4572 (fix:SI (match_operand:TF 1 "register_operand" "e")))]
4573 "TARGET_FPU && TARGET_HARD_QUAD"
4575 [(set_attr "type" "fp")])
4577 (define_expand "fixuns_trunctfsi2"
4578 [(set (match_operand:SI 0 "register_operand" "")
4579 (unsigned_fix:SI (match_operand:TF 1 "general_operand" "")))]
4580 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4581 "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
4583 ;; Now the same, for V9 targets
4585 (define_insn "fix_truncsfdi2"
4586 [(set (match_operand:DI 0 "register_operand" "=e")
4587 (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
4588 "TARGET_V9 && TARGET_FPU"
4590 [(set_attr "type" "fp")
4591 (set_attr "fptype" "double")])
4593 (define_expand "fixuns_truncsfdi2"
4594 [(use (match_operand:DI 0 "register_operand" ""))
4595 (use (match_operand:SF 1 "general_operand" ""))]
4596 "TARGET_ARCH64 && TARGET_FPU"
4597 "sparc_emit_fixunsdi (operands, SFmode); DONE;")
4599 (define_insn "fix_truncdfdi2"
4600 [(set (match_operand:DI 0 "register_operand" "=e")
4601 (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
4602 "TARGET_V9 && TARGET_FPU"
4604 [(set_attr "type" "fp")
4605 (set_attr "fptype" "double")])
4607 (define_expand "fixuns_truncdfdi2"
4608 [(use (match_operand:DI 0 "register_operand" ""))
4609 (use (match_operand:DF 1 "general_operand" ""))]
4610 "TARGET_ARCH64 && TARGET_FPU"
4611 "sparc_emit_fixunsdi (operands, DFmode); DONE;")
4613 (define_expand "fix_trunctfdi2"
4614 [(set (match_operand:DI 0 "register_operand" "")
4615 (fix:DI (match_operand:TF 1 "general_operand" "")))]
4616 "TARGET_V9 && TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4617 "emit_tfmode_cvt (FIX, operands); DONE;")
4619 (define_insn "*fix_trunctfdi2_hq"
4620 [(set (match_operand:DI 0 "register_operand" "=e")
4621 (fix:DI (match_operand:TF 1 "register_operand" "e")))]
4622 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
4624 [(set_attr "type" "fp")])
4626 (define_expand "fixuns_trunctfdi2"
4627 [(set (match_operand:DI 0 "register_operand" "")
4628 (unsigned_fix:DI (match_operand:TF 1 "general_operand" "")))]
4629 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4630 "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
4633 ;; Integer addition/subtraction instructions.
4635 (define_expand "adddi3"
4636 [(set (match_operand:DI 0 "register_operand" "")
4637 (plus:DI (match_operand:DI 1 "register_operand" "")
4638 (match_operand:DI 2 "arith_double_add_operand" "")))]
4641 if (! TARGET_ARCH64)
4643 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
4644 gen_rtx_SET (VOIDmode, operands[0],
4645 gen_rtx_PLUS (DImode, operands[1],
4647 gen_rtx_CLOBBER (VOIDmode,
4648 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
4653 (define_insn_and_split "adddi3_insn_sp32"
4654 [(set (match_operand:DI 0 "register_operand" "=r")
4655 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
4656 (match_operand:DI 2 "arith_double_operand" "rHI")))
4657 (clobber (reg:CC 100))]
4660 "&& reload_completed"
4661 [(parallel [(set (reg:CC_NOOV 100)
4662 (compare:CC_NOOV (plus:SI (match_dup 4)
4666 (plus:SI (match_dup 4) (match_dup 5)))])
4668 (plus:SI (plus:SI (match_dup 7)
4670 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4672 operands[3] = gen_lowpart (SImode, operands[0]);
4673 operands[4] = gen_lowpart (SImode, operands[1]);
4674 operands[5] = gen_lowpart (SImode, operands[2]);
4675 operands[6] = gen_highpart (SImode, operands[0]);
4676 operands[7] = gen_highpart_mode (SImode, DImode, operands[1]);
4677 #if HOST_BITS_PER_WIDE_INT == 32
4678 if (GET_CODE (operands[2]) == CONST_INT)
4680 if (INTVAL (operands[2]) < 0)
4681 operands[8] = constm1_rtx;
4683 operands[8] = const0_rtx;
4687 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
4689 [(set_attr "length" "2")])
4691 ;; LTU here means "carry set"
4693 [(set (match_operand:SI 0 "register_operand" "=r")
4694 (plus:SI (plus:SI (match_operand:SI 1 "arith_operand" "%r")
4695 (match_operand:SI 2 "arith_operand" "rI"))
4696 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4699 [(set_attr "type" "ialuX")])
4701 (define_insn_and_split "*addx_extend_sp32"
4702 [(set (match_operand:DI 0 "register_operand" "=r")
4703 (zero_extend:DI (plus:SI (plus:SI
4704 (match_operand:SI 1 "register_or_zero_operand" "%rJ")
4705 (match_operand:SI 2 "arith_operand" "rI"))
4706 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4709 "&& reload_completed"
4710 [(set (match_dup 3) (plus:SI (plus:SI (match_dup 1) (match_dup 2))
4711 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
4712 (set (match_dup 4) (const_int 0))]
4713 "operands[3] = gen_lowpart (SImode, operands[0]);
4714 operands[4] = gen_highpart_mode (SImode, DImode, operands[1]);"
4715 [(set_attr "length" "2")])
4717 (define_insn "*addx_extend_sp64"
4718 [(set (match_operand:DI 0 "register_operand" "=r")
4719 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ")
4720 (match_operand:SI 2 "arith_operand" "rI"))
4721 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4724 [(set_attr "type" "ialuX")])
4726 (define_insn_and_split ""
4727 [(set (match_operand:DI 0 "register_operand" "=r")
4728 (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4729 (match_operand:DI 2 "register_operand" "r")))
4730 (clobber (reg:CC 100))]
4733 "&& reload_completed"
4734 [(parallel [(set (reg:CC_NOOV 100)
4735 (compare:CC_NOOV (plus:SI (match_dup 3) (match_dup 1))
4737 (set (match_dup 5) (plus:SI (match_dup 3) (match_dup 1)))])
4739 (plus:SI (plus:SI (match_dup 4) (const_int 0))
4740 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4741 "operands[3] = gen_lowpart (SImode, operands[2]);
4742 operands[4] = gen_highpart (SImode, operands[2]);
4743 operands[5] = gen_lowpart (SImode, operands[0]);
4744 operands[6] = gen_highpart (SImode, operands[0]);"
4745 [(set_attr "length" "2")])
4747 (define_insn "*adddi3_sp64"
4748 [(set (match_operand:DI 0 "register_operand" "=r,r")
4749 (plus:DI (match_operand:DI 1 "register_operand" "%r,r")
4750 (match_operand:DI 2 "arith_add_operand" "rI,O")))]
4756 (define_insn "addsi3"
4757 [(set (match_operand:SI 0 "register_operand" "=r,r,d")
4758 (plus:SI (match_operand:SI 1 "register_operand" "%r,r,d")
4759 (match_operand:SI 2 "arith_add_operand" "rI,O,d")))]
4764 fpadd32s\t%1, %2, %0"
4765 [(set_attr "type" "*,*,fga")
4766 (set_attr "fptype" "*,*,single")])
4768 (define_insn "*cmp_cc_plus"
4769 [(set (reg:CC_NOOV 100)
4770 (compare:CC_NOOV (plus:SI (match_operand:SI 0 "arith_operand" "%r")
4771 (match_operand:SI 1 "arith_operand" "rI"))
4774 "addcc\t%0, %1, %%g0"
4775 [(set_attr "type" "compare")])
4777 (define_insn "*cmp_ccx_plus"
4778 [(set (reg:CCX_NOOV 100)
4779 (compare:CCX_NOOV (plus:DI (match_operand:DI 0 "arith_operand" "%r")
4780 (match_operand:DI 1 "arith_operand" "rI"))
4783 "addcc\t%0, %1, %%g0"
4784 [(set_attr "type" "compare")])
4786 (define_insn "*cmp_cc_plus_set"
4787 [(set (reg:CC_NOOV 100)
4788 (compare:CC_NOOV (plus:SI (match_operand:SI 1 "arith_operand" "%r")
4789 (match_operand:SI 2 "arith_operand" "rI"))
4791 (set (match_operand:SI 0 "register_operand" "=r")
4792 (plus:SI (match_dup 1) (match_dup 2)))]
4795 [(set_attr "type" "compare")])
4797 (define_insn "*cmp_ccx_plus_set"
4798 [(set (reg:CCX_NOOV 100)
4799 (compare:CCX_NOOV (plus:DI (match_operand:DI 1 "arith_operand" "%r")
4800 (match_operand:DI 2 "arith_operand" "rI"))
4802 (set (match_operand:DI 0 "register_operand" "=r")
4803 (plus:DI (match_dup 1) (match_dup 2)))]
4806 [(set_attr "type" "compare")])
4808 (define_expand "subdi3"
4809 [(set (match_operand:DI 0 "register_operand" "")
4810 (minus:DI (match_operand:DI 1 "register_operand" "")
4811 (match_operand:DI 2 "arith_double_add_operand" "")))]
4814 if (! TARGET_ARCH64)
4816 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
4817 gen_rtx_SET (VOIDmode, operands[0],
4818 gen_rtx_MINUS (DImode, operands[1],
4820 gen_rtx_CLOBBER (VOIDmode,
4821 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
4826 (define_insn_and_split "subdi3_insn_sp32"
4827 [(set (match_operand:DI 0 "register_operand" "=r")
4828 (minus:DI (match_operand:DI 1 "register_operand" "r")
4829 (match_operand:DI 2 "arith_double_operand" "rHI")))
4830 (clobber (reg:CC 100))]
4833 "&& reload_completed"
4834 [(parallel [(set (reg:CC_NOOV 100)
4835 (compare:CC_NOOV (minus:SI (match_dup 4)
4839 (minus:SI (match_dup 4) (match_dup 5)))])
4841 (minus:SI (minus:SI (match_dup 7)
4843 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4845 operands[3] = gen_lowpart (SImode, operands[0]);
4846 operands[4] = gen_lowpart (SImode, operands[1]);
4847 operands[5] = gen_lowpart (SImode, operands[2]);
4848 operands[6] = gen_highpart (SImode, operands[0]);
4849 operands[7] = gen_highpart (SImode, operands[1]);
4850 #if HOST_BITS_PER_WIDE_INT == 32
4851 if (GET_CODE (operands[2]) == CONST_INT)
4853 if (INTVAL (operands[2]) < 0)
4854 operands[8] = constm1_rtx;
4856 operands[8] = const0_rtx;
4860 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
4862 [(set_attr "length" "2")])
4864 ;; LTU here means "carry set"
4866 [(set (match_operand:SI 0 "register_operand" "=r")
4867 (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
4868 (match_operand:SI 2 "arith_operand" "rI"))
4869 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4872 [(set_attr "type" "ialuX")])
4874 (define_insn "*subx_extend_sp64"
4875 [(set (match_operand:DI 0 "register_operand" "=r")
4876 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
4877 (match_operand:SI 2 "arith_operand" "rI"))
4878 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4881 [(set_attr "type" "ialuX")])
4883 (define_insn_and_split "*subx_extend"
4884 [(set (match_operand:DI 0 "register_operand" "=r")
4885 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
4886 (match_operand:SI 2 "arith_operand" "rI"))
4887 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4890 "&& reload_completed"
4891 [(set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 2))
4892 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
4893 (set (match_dup 4) (const_int 0))]
4894 "operands[3] = gen_lowpart (SImode, operands[0]);
4895 operands[4] = gen_highpart (SImode, operands[0]);"
4896 [(set_attr "length" "2")])
4898 (define_insn_and_split ""
4899 [(set (match_operand:DI 0 "register_operand" "=r")
4900 (minus:DI (match_operand:DI 1 "register_operand" "r")
4901 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))
4902 (clobber (reg:CC 100))]
4905 "&& reload_completed"
4906 [(parallel [(set (reg:CC_NOOV 100)
4907 (compare:CC_NOOV (minus:SI (match_dup 3) (match_dup 2))
4909 (set (match_dup 5) (minus:SI (match_dup 3) (match_dup 2)))])
4911 (minus:SI (minus:SI (match_dup 4) (const_int 0))
4912 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4913 "operands[3] = gen_lowpart (SImode, operands[1]);
4914 operands[4] = gen_highpart (SImode, operands[1]);
4915 operands[5] = gen_lowpart (SImode, operands[0]);
4916 operands[6] = gen_highpart (SImode, operands[0]);"
4917 [(set_attr "length" "2")])
4919 (define_insn "*subdi3_sp64"
4920 [(set (match_operand:DI 0 "register_operand" "=r,r")
4921 (minus:DI (match_operand:DI 1 "register_operand" "r,r")
4922 (match_operand:DI 2 "arith_add_operand" "rI,O")))]
4928 (define_insn "subsi3"
4929 [(set (match_operand:SI 0 "register_operand" "=r,r,d")
4930 (minus:SI (match_operand:SI 1 "register_operand" "r,r,d")
4931 (match_operand:SI 2 "arith_add_operand" "rI,O,d")))]
4936 fpsub32s\t%1, %2, %0"
4937 [(set_attr "type" "*,*,fga")
4938 (set_attr "fptype" "*,*,single")])
4940 (define_insn "*cmp_minus_cc"
4941 [(set (reg:CC_NOOV 100)
4942 (compare:CC_NOOV (minus:SI (match_operand:SI 0 "register_or_zero_operand" "rJ")
4943 (match_operand:SI 1 "arith_operand" "rI"))
4946 "subcc\t%r0, %1, %%g0"
4947 [(set_attr "type" "compare")])
4949 (define_insn "*cmp_minus_ccx"
4950 [(set (reg:CCX_NOOV 100)
4951 (compare:CCX_NOOV (minus:DI (match_operand:DI 0 "register_operand" "r")
4952 (match_operand:DI 1 "arith_operand" "rI"))
4955 "subcc\t%0, %1, %%g0"
4956 [(set_attr "type" "compare")])
4958 (define_insn "cmp_minus_cc_set"
4959 [(set (reg:CC_NOOV 100)
4960 (compare:CC_NOOV (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
4961 (match_operand:SI 2 "arith_operand" "rI"))
4963 (set (match_operand:SI 0 "register_operand" "=r")
4964 (minus:SI (match_dup 1) (match_dup 2)))]
4966 "subcc\t%r1, %2, %0"
4967 [(set_attr "type" "compare")])
4969 (define_insn "*cmp_minus_ccx_set"
4970 [(set (reg:CCX_NOOV 100)
4971 (compare:CCX_NOOV (minus:DI (match_operand:DI 1 "register_operand" "r")
4972 (match_operand:DI 2 "arith_operand" "rI"))
4974 (set (match_operand:DI 0 "register_operand" "=r")
4975 (minus:DI (match_dup 1) (match_dup 2)))]
4978 [(set_attr "type" "compare")])
4981 ;; Integer multiply/divide instructions.
4983 ;; The 32 bit multiply/divide instructions are deprecated on v9, but at
4984 ;; least in UltraSPARC I, II and IIi it is a win tick-wise.
4986 (define_insn "mulsi3"
4987 [(set (match_operand:SI 0 "register_operand" "=r")
4988 (mult:SI (match_operand:SI 1 "arith_operand" "%r")
4989 (match_operand:SI 2 "arith_operand" "rI")))]
4992 [(set_attr "type" "imul")])
4994 (define_expand "muldi3"
4995 [(set (match_operand:DI 0 "register_operand" "")
4996 (mult:DI (match_operand:DI 1 "arith_operand" "")
4997 (match_operand:DI 2 "arith_operand" "")))]
4998 "TARGET_ARCH64 || TARGET_V8PLUS"
5002 emit_insn (gen_muldi3_v8plus (operands[0], operands[1], operands[2]));
5007 (define_insn "*muldi3_sp64"
5008 [(set (match_operand:DI 0 "register_operand" "=r")
5009 (mult:DI (match_operand:DI 1 "arith_operand" "%r")
5010 (match_operand:DI 2 "arith_operand" "rI")))]
5013 [(set_attr "type" "imul")])
5015 ;; V8plus wide multiply.
5017 (define_insn "muldi3_v8plus"
5018 [(set (match_operand:DI 0 "register_operand" "=r,h")
5019 (mult:DI (match_operand:DI 1 "arith_operand" "%r,0")
5020 (match_operand:DI 2 "arith_operand" "rI,rI")))
5021 (clobber (match_scratch:SI 3 "=&h,X"))
5022 (clobber (match_scratch:SI 4 "=&h,X"))]
5025 if (sparc_check_64 (operands[1], insn) <= 0)
5026 output_asm_insn ("srl\t%L1, 0, %L1", operands);
5027 if (which_alternative == 1)
5028 output_asm_insn ("sllx\t%H1, 32, %H1", operands);
5029 if (GET_CODE (operands[2]) == CONST_INT)
5031 if (which_alternative == 1)
5032 return "or\t%L1, %H1, %H1\n\tmulx\t%H1, %2, %L0\;srlx\t%L0, 32, %H0";
5034 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";
5036 else if (rtx_equal_p (operands[1], operands[2]))
5038 if (which_alternative == 1)
5039 return "or\t%L1, %H1, %H1\n\tmulx\t%H1, %H1, %L0\;srlx\t%L0, 32, %H0";
5041 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";
5043 if (sparc_check_64 (operands[2], insn) <= 0)
5044 output_asm_insn ("srl\t%L2, 0, %L2", operands);
5045 if (which_alternative == 1)
5046 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";
5048 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";
5050 [(set_attr "type" "multi")
5051 (set_attr "length" "9,8")])
5053 (define_insn "*cmp_mul_set"
5055 (compare:CC (mult:SI (match_operand:SI 1 "arith_operand" "%r")
5056 (match_operand:SI 2 "arith_operand" "rI"))
5058 (set (match_operand:SI 0 "register_operand" "=r")
5059 (mult:SI (match_dup 1) (match_dup 2)))]
5060 "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS"
5061 "smulcc\t%1, %2, %0"
5062 [(set_attr "type" "imul")])
5064 (define_expand "mulsidi3"
5065 [(set (match_operand:DI 0 "register_operand" "")
5066 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
5067 (sign_extend:DI (match_operand:SI 2 "arith_operand" ""))))]
5070 if (CONSTANT_P (operands[2]))
5073 emit_insn (gen_const_mulsidi3_v8plus (operands[0], operands[1],
5075 else if (TARGET_ARCH32)
5076 emit_insn (gen_const_mulsidi3_sp32 (operands[0], operands[1],
5079 emit_insn (gen_const_mulsidi3_sp64 (operands[0], operands[1],
5085 emit_insn (gen_mulsidi3_v8plus (operands[0], operands[1], operands[2]));
5090 ;; V9 puts the 64 bit product in a 64 bit register. Only out or global
5091 ;; registers can hold 64 bit values in the V8plus environment.
5093 (define_insn "mulsidi3_v8plus"
5094 [(set (match_operand:DI 0 "register_operand" "=h,r")
5095 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5096 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
5097 (clobber (match_scratch:SI 3 "=X,&h"))]
5100 smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
5101 smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
5102 [(set_attr "type" "multi")
5103 (set_attr "length" "2,3")])
5106 (define_insn "const_mulsidi3_v8plus"
5107 [(set (match_operand:DI 0 "register_operand" "=h,r")
5108 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5109 (match_operand:DI 2 "small_int_operand" "I,I")))
5110 (clobber (match_scratch:SI 3 "=X,&h"))]
5113 smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
5114 smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
5115 [(set_attr "type" "multi")
5116 (set_attr "length" "2,3")])
5119 (define_insn "*mulsidi3_sp32"
5120 [(set (match_operand:DI 0 "register_operand" "=r")
5121 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5122 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
5125 return TARGET_SPARCLET
5126 ? "smuld\t%1, %2, %L0"
5127 : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
5130 (if_then_else (eq_attr "isa" "sparclet")
5131 (const_string "imul") (const_string "multi")))
5132 (set (attr "length")
5133 (if_then_else (eq_attr "isa" "sparclet")
5134 (const_int 1) (const_int 2)))])
5136 (define_insn "*mulsidi3_sp64"
5137 [(set (match_operand:DI 0 "register_operand" "=r")
5138 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5139 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
5140 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5142 [(set_attr "type" "imul")])
5144 ;; Extra pattern, because sign_extend of a constant isn't valid.
5147 (define_insn "const_mulsidi3_sp32"
5148 [(set (match_operand:DI 0 "register_operand" "=r")
5149 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5150 (match_operand:DI 2 "small_int_operand" "I")))]
5153 return TARGET_SPARCLET
5154 ? "smuld\t%1, %2, %L0"
5155 : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
5158 (if_then_else (eq_attr "isa" "sparclet")
5159 (const_string "imul") (const_string "multi")))
5160 (set (attr "length")
5161 (if_then_else (eq_attr "isa" "sparclet")
5162 (const_int 1) (const_int 2)))])
5164 (define_insn "const_mulsidi3_sp64"
5165 [(set (match_operand:DI 0 "register_operand" "=r")
5166 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5167 (match_operand:DI 2 "small_int_operand" "I")))]
5168 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5170 [(set_attr "type" "imul")])
5172 (define_expand "smulsi3_highpart"
5173 [(set (match_operand:SI 0 "register_operand" "")
5175 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
5176 (sign_extend:DI (match_operand:SI 2 "arith_operand" "")))
5178 "TARGET_HARD_MUL && TARGET_ARCH32"
5180 if (CONSTANT_P (operands[2]))
5184 emit_insn (gen_const_smulsi3_highpart_v8plus (operands[0],
5190 emit_insn (gen_const_smulsi3_highpart (operands[0], operands[1], operands[2]));
5195 emit_insn (gen_smulsi3_highpart_v8plus (operands[0], operands[1],
5196 operands[2], GEN_INT (32)));
5202 (define_insn "smulsi3_highpart_v8plus"
5203 [(set (match_operand:SI 0 "register_operand" "=h,r")
5205 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5206 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
5207 (match_operand:SI 3 "small_int_operand" "I,I"))))
5208 (clobber (match_scratch:SI 4 "=X,&h"))]
5211 smul\t%1, %2, %0\;srlx\t%0, %3, %0
5212 smul\t%1, %2, %4\;srlx\t%4, %3, %0"
5213 [(set_attr "type" "multi")
5214 (set_attr "length" "2")])
5216 ;; The combiner changes TRUNCATE in the previous pattern to SUBREG.
5219 [(set (match_operand:SI 0 "register_operand" "=h,r")
5222 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5223 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
5224 (match_operand:SI 3 "small_int_operand" "I,I"))
5226 (clobber (match_scratch:SI 4 "=X,&h"))]
5229 smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
5230 smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
5231 [(set_attr "type" "multi")
5232 (set_attr "length" "2")])
5235 (define_insn "const_smulsi3_highpart_v8plus"
5236 [(set (match_operand:SI 0 "register_operand" "=h,r")
5238 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5239 (match_operand:DI 2 "small_int_operand" "I,I"))
5240 (match_operand:SI 3 "small_int_operand" "I,I"))))
5241 (clobber (match_scratch:SI 4 "=X,&h"))]
5244 smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
5245 smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
5246 [(set_attr "type" "multi")
5247 (set_attr "length" "2")])
5250 (define_insn "*smulsi3_highpart_sp32"
5251 [(set (match_operand:SI 0 "register_operand" "=r")
5253 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5254 (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
5257 "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
5258 [(set_attr "type" "multi")
5259 (set_attr "length" "2")])
5262 (define_insn "const_smulsi3_highpart"
5263 [(set (match_operand:SI 0 "register_operand" "=r")
5265 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5266 (match_operand:DI 2 "small_int_operand" "i"))
5269 "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
5270 [(set_attr "type" "multi")
5271 (set_attr "length" "2")])
5273 (define_expand "umulsidi3"
5274 [(set (match_operand:DI 0 "register_operand" "")
5275 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
5276 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" ""))))]
5279 if (CONSTANT_P (operands[2]))
5282 emit_insn (gen_const_umulsidi3_v8plus (operands[0], operands[1],
5284 else if (TARGET_ARCH32)
5285 emit_insn (gen_const_umulsidi3_sp32 (operands[0], operands[1],
5288 emit_insn (gen_const_umulsidi3_sp64 (operands[0], operands[1],
5294 emit_insn (gen_umulsidi3_v8plus (operands[0], operands[1], operands[2]));
5300 (define_insn "umulsidi3_v8plus"
5301 [(set (match_operand:DI 0 "register_operand" "=h,r")
5302 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5303 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
5304 (clobber (match_scratch:SI 3 "=X,&h"))]
5307 umul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
5308 umul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
5309 [(set_attr "type" "multi")
5310 (set_attr "length" "2,3")])
5313 (define_insn "*umulsidi3_sp32"
5314 [(set (match_operand:DI 0 "register_operand" "=r")
5315 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5316 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
5319 return TARGET_SPARCLET
5320 ? "umuld\t%1, %2, %L0"
5321 : "umul\t%1, %2, %L0\n\trd\t%%y, %H0";
5324 (if_then_else (eq_attr "isa" "sparclet")
5325 (const_string "imul") (const_string "multi")))
5326 (set (attr "length")
5327 (if_then_else (eq_attr "isa" "sparclet")
5328 (const_int 1) (const_int 2)))])
5330 (define_insn "*umulsidi3_sp64"
5331 [(set (match_operand:DI 0 "register_operand" "=r")
5332 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5333 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
5334 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5336 [(set_attr "type" "imul")])
5338 ;; Extra pattern, because sign_extend of a constant isn't valid.
5341 (define_insn "const_umulsidi3_sp32"
5342 [(set (match_operand:DI 0 "register_operand" "=r")
5343 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5344 (match_operand:DI 2 "uns_small_int_operand" "")))]
5347 return TARGET_SPARCLET
5348 ? "umuld\t%1, %s2, %L0"
5349 : "umul\t%1, %s2, %L0\n\trd\t%%y, %H0";
5352 (if_then_else (eq_attr "isa" "sparclet")
5353 (const_string "imul") (const_string "multi")))
5354 (set (attr "length")
5355 (if_then_else (eq_attr "isa" "sparclet")
5356 (const_int 1) (const_int 2)))])
5358 (define_insn "const_umulsidi3_sp64"
5359 [(set (match_operand:DI 0 "register_operand" "=r")
5360 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5361 (match_operand:DI 2 "uns_small_int_operand" "")))]
5362 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5364 [(set_attr "type" "imul")])
5367 (define_insn "const_umulsidi3_v8plus"
5368 [(set (match_operand:DI 0 "register_operand" "=h,r")
5369 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5370 (match_operand:DI 2 "uns_small_int_operand" "")))
5371 (clobber (match_scratch:SI 3 "=X,h"))]
5374 umul\t%1, %s2, %L0\n\tsrlx\t%L0, 32, %H0
5375 umul\t%1, %s2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
5376 [(set_attr "type" "multi")
5377 (set_attr "length" "2,3")])
5379 (define_expand "umulsi3_highpart"
5380 [(set (match_operand:SI 0 "register_operand" "")
5382 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
5383 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" "")))
5385 "TARGET_HARD_MUL && TARGET_ARCH32"
5387 if (CONSTANT_P (operands[2]))
5391 emit_insn (gen_const_umulsi3_highpart_v8plus (operands[0],
5397 emit_insn (gen_const_umulsi3_highpart (operands[0], operands[1], operands[2]));
5402 emit_insn (gen_umulsi3_highpart_v8plus (operands[0], operands[1],
5403 operands[2], GEN_INT (32)));
5409 (define_insn "umulsi3_highpart_v8plus"
5410 [(set (match_operand:SI 0 "register_operand" "=h,r")
5412 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5413 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
5414 (match_operand:SI 3 "small_int_operand" "I,I"))))
5415 (clobber (match_scratch:SI 4 "=X,h"))]
5418 umul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
5419 umul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
5420 [(set_attr "type" "multi")
5421 (set_attr "length" "2")])
5424 (define_insn "const_umulsi3_highpart_v8plus"
5425 [(set (match_operand:SI 0 "register_operand" "=h,r")
5427 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5428 (match_operand:DI 2 "uns_small_int_operand" ""))
5429 (match_operand:SI 3 "small_int_operand" "I,I"))))
5430 (clobber (match_scratch:SI 4 "=X,h"))]
5433 umul\t%1, %s2, %0\n\tsrlx\t%0, %3, %0
5434 umul\t%1, %s2, %4\n\tsrlx\t%4, %3, %0"
5435 [(set_attr "type" "multi")
5436 (set_attr "length" "2")])
5439 (define_insn "*umulsi3_highpart_sp32"
5440 [(set (match_operand:SI 0 "register_operand" "=r")
5442 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5443 (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
5446 "umul\t%1, %2, %%g0\n\trd\t%%y, %0"
5447 [(set_attr "type" "multi")
5448 (set_attr "length" "2")])
5451 (define_insn "const_umulsi3_highpart"
5452 [(set (match_operand:SI 0 "register_operand" "=r")
5454 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5455 (match_operand:DI 2 "uns_small_int_operand" ""))
5458 "umul\t%1, %s2, %%g0\n\trd\t%%y, %0"
5459 [(set_attr "type" "multi")
5460 (set_attr "length" "2")])
5462 ;; The V8 architecture specifies that there must be 3 instructions between
5463 ;; a Y register write and a use of it for correct results.
5465 (define_expand "divsi3"
5466 [(parallel [(set (match_operand:SI 0 "register_operand" "=r,r")
5467 (div:SI (match_operand:SI 1 "register_operand" "r,r")
5468 (match_operand:SI 2 "input_operand" "rI,m")))
5469 (clobber (match_scratch:SI 3 "=&r,&r"))])]
5470 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
5474 operands[3] = gen_reg_rtx(SImode);
5475 emit_insn (gen_ashrsi3 (operands[3], operands[1], GEN_INT (31)));
5476 emit_insn (gen_divsi3_sp64 (operands[0], operands[1], operands[2],
5482 (define_insn "divsi3_sp32"
5483 [(set (match_operand:SI 0 "register_operand" "=r,r")
5484 (div:SI (match_operand:SI 1 "register_operand" "r,r")
5485 (match_operand:SI 2 "input_operand" "rI,m")))
5486 (clobber (match_scratch:SI 3 "=&r,&r"))]
5487 "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS)
5490 if (which_alternative == 0)
5492 return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tsdiv\t%1, %2, %0";
5494 return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tnop\n\tnop\n\tnop\n\tsdiv\t%1, %2, %0";
5497 return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tld\t%2, %3\n\tsdiv\t%1, %3, %0";
5499 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";
5501 [(set_attr "type" "multi")
5502 (set (attr "length")
5503 (if_then_else (eq_attr "isa" "v9")
5504 (const_int 4) (const_int 6)))])
5506 (define_insn "divsi3_sp64"
5507 [(set (match_operand:SI 0 "register_operand" "=r")
5508 (div:SI (match_operand:SI 1 "register_operand" "r")
5509 (match_operand:SI 2 "input_operand" "rI")))
5510 (use (match_operand:SI 3 "register_operand" "r"))]
5511 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5512 "wr\t%%g0, %3, %%y\n\tsdiv\t%1, %2, %0"
5513 [(set_attr "type" "multi")
5514 (set_attr "length" "2")])
5516 (define_insn "divdi3"
5517 [(set (match_operand:DI 0 "register_operand" "=r")
5518 (div:DI (match_operand:DI 1 "register_operand" "r")
5519 (match_operand:DI 2 "arith_operand" "rI")))]
5522 [(set_attr "type" "idiv")])
5524 (define_insn "*cmp_sdiv_cc_set"
5526 (compare:CC (div:SI (match_operand:SI 1 "register_operand" "r")
5527 (match_operand:SI 2 "arith_operand" "rI"))
5529 (set (match_operand:SI 0 "register_operand" "=r")
5530 (div:SI (match_dup 1) (match_dup 2)))
5531 (clobber (match_scratch:SI 3 "=&r"))]
5532 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
5535 return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tsdivcc\t%1, %2, %0";
5537 return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tnop\n\tnop\n\tnop\n\tsdivcc\t%1, %2, %0";
5539 [(set_attr "type" "multi")
5540 (set (attr "length")
5541 (if_then_else (eq_attr "isa" "v9")
5542 (const_int 3) (const_int 6)))])
5545 (define_expand "udivsi3"
5546 [(set (match_operand:SI 0 "register_operand" "")
5547 (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "")
5548 (match_operand:SI 2 "input_operand" "")))]
5549 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
5552 ;; The V8 architecture specifies that there must be 3 instructions between
5553 ;; a Y register write and a use of it for correct results.
5555 (define_insn "udivsi3_sp32"
5556 [(set (match_operand:SI 0 "register_operand" "=r,&r,&r")
5557 (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "r,r,m")
5558 (match_operand:SI 2 "input_operand" "rI,m,r")))]
5559 "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS)
5562 output_asm_insn ("wr\t%%g0, %%g0, %%y", operands);
5563 switch (which_alternative)
5566 return "nop\n\tnop\n\tnop\n\tudiv\t%1, %2, %0";
5568 return "ld\t%2, %0\n\tnop\n\tnop\n\tudiv\t%1, %0, %0";
5570 return "ld\t%1, %0\n\tnop\n\tnop\n\tudiv\t%0, %2, %0";
5573 [(set_attr "type" "multi")
5574 (set_attr "length" "5")])
5576 (define_insn "udivsi3_sp64"
5577 [(set (match_operand:SI 0 "register_operand" "=r")
5578 (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "r")
5579 (match_operand:SI 2 "input_operand" "rI")))]
5580 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5581 "wr\t%%g0, 0, %%y\n\tudiv\t%1, %2, %0"
5582 [(set_attr "type" "multi")
5583 (set_attr "length" "2")])
5585 (define_insn "udivdi3"
5586 [(set (match_operand:DI 0 "register_operand" "=r")
5587 (udiv:DI (match_operand:DI 1 "register_operand" "r")
5588 (match_operand:DI 2 "arith_operand" "rI")))]
5591 [(set_attr "type" "idiv")])
5593 (define_insn "*cmp_udiv_cc_set"
5595 (compare:CC (udiv:SI (match_operand:SI 1 "register_operand" "r")
5596 (match_operand:SI 2 "arith_operand" "rI"))
5598 (set (match_operand:SI 0 "register_operand" "=r")
5599 (udiv:SI (match_dup 1) (match_dup 2)))]
5601 || TARGET_DEPRECATED_V8_INSNS"
5604 return "wr\t%%g0, %%g0, %%y\n\tudivcc\t%1, %2, %0";
5606 return "wr\t%%g0, %%g0, %%y\n\tnop\n\tnop\n\tnop\n\tudivcc\t%1, %2, %0";
5608 [(set_attr "type" "multi")
5609 (set (attr "length")
5610 (if_then_else (eq_attr "isa" "v9")
5611 (const_int 2) (const_int 5)))])
5613 ; sparclet multiply/accumulate insns
5615 (define_insn "*smacsi"
5616 [(set (match_operand:SI 0 "register_operand" "=r")
5617 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "%r")
5618 (match_operand:SI 2 "arith_operand" "rI"))
5619 (match_operand:SI 3 "register_operand" "0")))]
5622 [(set_attr "type" "imul")])
5624 (define_insn "*smacdi"
5625 [(set (match_operand:DI 0 "register_operand" "=r")
5626 (plus:DI (mult:DI (sign_extend:DI
5627 (match_operand:SI 1 "register_operand" "%r"))
5629 (match_operand:SI 2 "register_operand" "r")))
5630 (match_operand:DI 3 "register_operand" "0")))]
5632 "smacd\t%1, %2, %L0"
5633 [(set_attr "type" "imul")])
5635 (define_insn "*umacdi"
5636 [(set (match_operand:DI 0 "register_operand" "=r")
5637 (plus:DI (mult:DI (zero_extend:DI
5638 (match_operand:SI 1 "register_operand" "%r"))
5640 (match_operand:SI 2 "register_operand" "r")))
5641 (match_operand:DI 3 "register_operand" "0")))]
5643 "umacd\t%1, %2, %L0"
5644 [(set_attr "type" "imul")])
5647 ;; Boolean instructions.
5649 ;; We define DImode `and' so with DImode `not' we can get
5650 ;; DImode `andn'. Other combinations are possible.
5652 (define_mode_macro V64I [DI V2SI V4HI V8QI])
5653 (define_mode_macro V32I [SI V2HI V4QI])
5655 (define_expand "and<V64I:mode>3"
5656 [(set (match_operand:V64I 0 "register_operand" "")
5657 (and:V64I (match_operand:V64I 1 "arith_double_operand" "")
5658 (match_operand:V64I 2 "arith_double_operand" "")))]
5662 (define_insn "*and<V64I:mode>3_sp32"
5663 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5664 (and:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
5665 (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
5670 [(set_attr "type" "*,fga")
5671 (set_attr "length" "2,*")
5672 (set_attr "fptype" "*,double")])
5674 (define_insn "*and<V64I:mode>3_sp64"
5675 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5676 (and:V64I (match_operand:V64I 1 "arith_operand" "%r,b")
5677 (match_operand:V64I 2 "arith_operand" "rI,b")))]
5682 [(set_attr "type" "*,fga")
5683 (set_attr "fptype" "*,double")])
5685 (define_insn "and<V32I:mode>3"
5686 [(set (match_operand:V32I 0 "register_operand" "=r,d")
5687 (and:V32I (match_operand:V32I 1 "arith_operand" "%r,d")
5688 (match_operand:V32I 2 "arith_operand" "rI,d")))]
5693 [(set_attr "type" "*,fga")
5694 (set_attr "fptype" "*,single")])
5697 [(set (match_operand:SI 0 "register_operand" "")
5698 (and:SI (match_operand:SI 1 "register_operand" "")
5699 (match_operand:SI 2 "const_compl_high_operand" "")))
5700 (clobber (match_operand:SI 3 "register_operand" ""))]
5702 [(set (match_dup 3) (match_dup 4))
5703 (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 1)))]
5705 operands[4] = GEN_INT (~INTVAL (operands[2]));
5708 (define_insn_and_split "*and_not_<V64I:mode>_sp32"
5709 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5710 (and:V64I (not:V64I (match_operand:V64I 1 "register_operand" "%r,b"))
5711 (match_operand:V64I 2 "register_operand" "r,b")))]
5715 fandnot1\t%1, %2, %0"
5716 "&& reload_completed
5717 && ((GET_CODE (operands[0]) == REG
5718 && REGNO (operands[0]) < 32)
5719 || (GET_CODE (operands[0]) == SUBREG
5720 && GET_CODE (SUBREG_REG (operands[0])) == REG
5721 && REGNO (SUBREG_REG (operands[0])) < 32))"
5722 [(set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))
5723 (set (match_dup 6) (and:SI (not:SI (match_dup 7)) (match_dup 8)))]
5724 "operands[3] = gen_highpart (SImode, operands[0]);
5725 operands[4] = gen_highpart (SImode, operands[1]);
5726 operands[5] = gen_highpart (SImode, operands[2]);
5727 operands[6] = gen_lowpart (SImode, operands[0]);
5728 operands[7] = gen_lowpart (SImode, operands[1]);
5729 operands[8] = gen_lowpart (SImode, operands[2]);"
5730 [(set_attr "type" "*,fga")
5731 (set_attr "length" "2,*")
5732 (set_attr "fptype" "*,double")])
5734 (define_insn "*and_not_<V64I:mode>_sp64"
5735 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5736 (and:V64I (not:V64I (match_operand:V64I 1 "register_operand" "%r,b"))
5737 (match_operand:V64I 2 "register_operand" "r,b")))]
5741 fandnot1\t%1, %2, %0"
5742 [(set_attr "type" "*,fga")
5743 (set_attr "fptype" "*,double")])
5745 (define_insn "*and_not_<V32I:mode>"
5746 [(set (match_operand:V32I 0 "register_operand" "=r,d")
5747 (and:V32I (not:V32I (match_operand:V32I 1 "register_operand" "%r,d"))
5748 (match_operand:V32I 2 "register_operand" "r,d")))]
5752 fandnot1s\t%1, %2, %0"
5753 [(set_attr "type" "*,fga")
5754 (set_attr "fptype" "*,single")])
5756 (define_expand "ior<V64I:mode>3"
5757 [(set (match_operand:V64I 0 "register_operand" "")
5758 (ior:V64I (match_operand:V64I 1 "arith_double_operand" "")
5759 (match_operand:V64I 2 "arith_double_operand" "")))]
5763 (define_insn "*ior<V64I:mode>3_sp32"
5764 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5765 (ior:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
5766 (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
5771 [(set_attr "type" "*,fga")
5772 (set_attr "length" "2,*")
5773 (set_attr "fptype" "*,double")])
5775 (define_insn "*ior<V64I:mode>3_sp64"
5776 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5777 (ior:V64I (match_operand:V64I 1 "arith_operand" "%r,b")
5778 (match_operand:V64I 2 "arith_operand" "rI,b")))]
5783 [(set_attr "type" "*,fga")
5784 (set_attr "fptype" "*,double")])
5786 (define_insn "ior<V32I:mode>3"
5787 [(set (match_operand:V32I 0 "register_operand" "=r,d")
5788 (ior:V32I (match_operand:V32I 1 "arith_operand" "%r,d")
5789 (match_operand:V32I 2 "arith_operand" "rI,d")))]
5794 [(set_attr "type" "*,fga")
5795 (set_attr "fptype" "*,single")])
5798 [(set (match_operand:SI 0 "register_operand" "")
5799 (ior:SI (match_operand:SI 1 "register_operand" "")
5800 (match_operand:SI 2 "const_compl_high_operand" "")))
5801 (clobber (match_operand:SI 3 "register_operand" ""))]
5803 [(set (match_dup 3) (match_dup 4))
5804 (set (match_dup 0) (ior:SI (not:SI (match_dup 3)) (match_dup 1)))]
5806 operands[4] = GEN_INT (~INTVAL (operands[2]));
5809 (define_insn_and_split "*or_not_<V64I:mode>_sp32"
5810 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5811 (ior:V64I (not:V64I (match_operand:V64I 1 "register_operand" "r,b"))
5812 (match_operand:V64I 2 "register_operand" "r,b")))]
5816 fornot1\t%1, %2, %0"
5817 "&& reload_completed
5818 && ((GET_CODE (operands[0]) == REG
5819 && REGNO (operands[0]) < 32)
5820 || (GET_CODE (operands[0]) == SUBREG
5821 && GET_CODE (SUBREG_REG (operands[0])) == REG
5822 && REGNO (SUBREG_REG (operands[0])) < 32))"
5823 [(set (match_dup 3) (ior:SI (not:SI (match_dup 4)) (match_dup 5)))
5824 (set (match_dup 6) (ior:SI (not:SI (match_dup 7)) (match_dup 8)))]
5825 "operands[3] = gen_highpart (SImode, operands[0]);
5826 operands[4] = gen_highpart (SImode, operands[1]);
5827 operands[5] = gen_highpart (SImode, operands[2]);
5828 operands[6] = gen_lowpart (SImode, operands[0]);
5829 operands[7] = gen_lowpart (SImode, operands[1]);
5830 operands[8] = gen_lowpart (SImode, operands[2]);"
5831 [(set_attr "type" "*,fga")
5832 (set_attr "length" "2,*")
5833 (set_attr "fptype" "*,double")])
5835 (define_insn "*or_not_<V64I:mode>_sp64"
5836 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5837 (ior:V64I (not:V64I (match_operand:V64I 1 "register_operand" "r,b"))
5838 (match_operand:V64I 2 "register_operand" "r,b")))]
5842 fornot1\t%1, %2, %0"
5843 [(set_attr "type" "*,fga")
5844 (set_attr "fptype" "*,double")])
5846 (define_insn "*or_not_<V32I:mode>"
5847 [(set (match_operand:V32I 0 "register_operand" "=r,d")
5848 (ior:V32I (not:V32I (match_operand:V32I 1 "register_operand" "r,d"))
5849 (match_operand:V32I 2 "register_operand" "r,d")))]
5853 fornot1s\t%1, %2, %0"
5854 [(set_attr "type" "*,fga")
5855 (set_attr "fptype" "*,single")])
5857 (define_expand "xor<V64I:mode>3"
5858 [(set (match_operand:V64I 0 "register_operand" "")
5859 (xor:V64I (match_operand:V64I 1 "arith_double_operand" "")
5860 (match_operand:V64I 2 "arith_double_operand" "")))]
5864 (define_insn "*xor<V64I:mode>3_sp32"
5865 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5866 (xor:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
5867 (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
5872 [(set_attr "type" "*,fga")
5873 (set_attr "length" "2,*")
5874 (set_attr "fptype" "*,double")])
5876 (define_insn "*xor<V64I:mode>3_sp64"
5877 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5878 (xor:V64I (match_operand:V64I 1 "arith_operand" "%rJ,b")
5879 (match_operand:V64I 2 "arith_operand" "rI,b")))]
5884 [(set_attr "type" "*,fga")
5885 (set_attr "fptype" "*,double")])
5887 (define_insn "xor<V32I:mode>3"
5888 [(set (match_operand:V32I 0 "register_operand" "=r,d")
5889 (xor:V32I (match_operand:V32I 1 "arith_operand" "%rJ,d")
5890 (match_operand:V32I 2 "arith_operand" "rI,d")))]
5895 [(set_attr "type" "*,fga")
5896 (set_attr "fptype" "*,single")])
5899 [(set (match_operand:SI 0 "register_operand" "")
5900 (xor:SI (match_operand:SI 1 "register_operand" "")
5901 (match_operand:SI 2 "const_compl_high_operand" "")))
5902 (clobber (match_operand:SI 3 "register_operand" ""))]
5904 [(set (match_dup 3) (match_dup 4))
5905 (set (match_dup 0) (not:SI (xor:SI (match_dup 3) (match_dup 1))))]
5907 operands[4] = GEN_INT (~INTVAL (operands[2]));
5911 [(set (match_operand:SI 0 "register_operand" "")
5912 (not:SI (xor:SI (match_operand:SI 1 "register_operand" "")
5913 (match_operand:SI 2 "const_compl_high_operand" ""))))
5914 (clobber (match_operand:SI 3 "register_operand" ""))]
5916 [(set (match_dup 3) (match_dup 4))
5917 (set (match_dup 0) (xor:SI (match_dup 3) (match_dup 1)))]
5919 operands[4] = GEN_INT (~INTVAL (operands[2]));
5922 ;; Split DImode logical operations requiring two instructions.
5924 [(set (match_operand:V64I 0 "register_operand" "")
5925 (match_operator:V64I 1 "cc_arith_operator" ; AND, IOR, XOR
5926 [(match_operand:V64I 2 "register_operand" "")
5927 (match_operand:V64I 3 "arith_double_operand" "")]))]
5930 && ((GET_CODE (operands[0]) == REG
5931 && REGNO (operands[0]) < 32)
5932 || (GET_CODE (operands[0]) == SUBREG
5933 && GET_CODE (SUBREG_REG (operands[0])) == REG
5934 && REGNO (SUBREG_REG (operands[0])) < 32))"
5935 [(set (match_dup 4) (match_op_dup:SI 1 [(match_dup 6) (match_dup 8)]))
5936 (set (match_dup 5) (match_op_dup:SI 1 [(match_dup 7) (match_dup 9)]))]
5938 operands[4] = gen_highpart (SImode, operands[0]);
5939 operands[5] = gen_lowpart (SImode, operands[0]);
5940 operands[6] = gen_highpart (SImode, operands[2]);
5941 operands[7] = gen_lowpart (SImode, operands[2]);
5942 #if HOST_BITS_PER_WIDE_INT == 32
5943 if (GET_CODE (operands[3]) == CONST_INT && <V64I:MODE>mode == DImode)
5945 if (INTVAL (operands[3]) < 0)
5946 operands[8] = constm1_rtx;
5948 operands[8] = const0_rtx;
5952 operands[8] = gen_highpart_mode (SImode, <V64I:MODE>mode, operands[3]);
5953 operands[9] = gen_lowpart (SImode, operands[3]);
5956 ;; xnor patterns. Note that (a ^ ~b) == (~a ^ b) == ~(a ^ b).
5957 ;; Combine now canonicalizes to the rightmost expression.
5958 (define_insn_and_split "*xor_not_<V64I:mode>_sp32"
5959 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5960 (not:V64I (xor:V64I (match_operand:V64I 1 "register_operand" "r,b")
5961 (match_operand:V64I 2 "register_operand" "r,b"))))]
5966 "&& reload_completed
5967 && ((GET_CODE (operands[0]) == REG
5968 && REGNO (operands[0]) < 32)
5969 || (GET_CODE (operands[0]) == SUBREG
5970 && GET_CODE (SUBREG_REG (operands[0])) == REG
5971 && REGNO (SUBREG_REG (operands[0])) < 32))"
5972 [(set (match_dup 3) (not:SI (xor:SI (match_dup 4) (match_dup 5))))
5973 (set (match_dup 6) (not:SI (xor:SI (match_dup 7) (match_dup 8))))]
5974 "operands[3] = gen_highpart (SImode, operands[0]);
5975 operands[4] = gen_highpart (SImode, operands[1]);
5976 operands[5] = gen_highpart (SImode, operands[2]);
5977 operands[6] = gen_lowpart (SImode, operands[0]);
5978 operands[7] = gen_lowpart (SImode, operands[1]);
5979 operands[8] = gen_lowpart (SImode, operands[2]);"
5980 [(set_attr "type" "*,fga")
5981 (set_attr "length" "2,*")
5982 (set_attr "fptype" "*,double")])
5984 (define_insn "*xor_not_<V64I:mode>_sp64"
5985 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5986 (not:V64I (xor:V64I (match_operand:V64I 1 "register_or_zero_operand" "rJ,b")
5987 (match_operand:V64I 2 "arith_operand" "rI,b"))))]
5992 [(set_attr "type" "*,fga")
5993 (set_attr "fptype" "*,double")])
5995 (define_insn "*xor_not_<V32I:mode>"
5996 [(set (match_operand:V32I 0 "register_operand" "=r,d")
5997 (not:V32I (xor:V32I (match_operand:V32I 1 "register_or_zero_operand" "rJ,d")
5998 (match_operand:V32I 2 "arith_operand" "rI,d"))))]
6003 [(set_attr "type" "*,fga")
6004 (set_attr "fptype" "*,single")])
6006 ;; These correspond to the above in the case where we also (or only)
6007 ;; want to set the condition code.
6009 (define_insn "*cmp_cc_arith_op"
6012 (match_operator:SI 2 "cc_arith_operator"
6013 [(match_operand:SI 0 "arith_operand" "%r")
6014 (match_operand:SI 1 "arith_operand" "rI")])
6017 "%A2cc\t%0, %1, %%g0"
6018 [(set_attr "type" "compare")])
6020 (define_insn "*cmp_ccx_arith_op"
6023 (match_operator:DI 2 "cc_arith_operator"
6024 [(match_operand:DI 0 "arith_operand" "%r")
6025 (match_operand:DI 1 "arith_operand" "rI")])
6028 "%A2cc\t%0, %1, %%g0"
6029 [(set_attr "type" "compare")])
6031 (define_insn "*cmp_cc_arith_op_set"
6034 (match_operator:SI 3 "cc_arith_operator"
6035 [(match_operand:SI 1 "arith_operand" "%r")
6036 (match_operand:SI 2 "arith_operand" "rI")])
6038 (set (match_operand:SI 0 "register_operand" "=r")
6039 (match_operator:SI 4 "cc_arith_operator" [(match_dup 1) (match_dup 2)]))]
6040 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
6042 [(set_attr "type" "compare")])
6044 (define_insn "*cmp_ccx_arith_op_set"
6047 (match_operator:DI 3 "cc_arith_operator"
6048 [(match_operand:DI 1 "arith_operand" "%r")
6049 (match_operand:DI 2 "arith_operand" "rI")])
6051 (set (match_operand:DI 0 "register_operand" "=r")
6052 (match_operator:DI 4 "cc_arith_operator" [(match_dup 1) (match_dup 2)]))]
6053 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
6055 [(set_attr "type" "compare")])
6057 (define_insn "*cmp_cc_xor_not"
6060 (not:SI (xor:SI (match_operand:SI 0 "register_or_zero_operand" "%rJ")
6061 (match_operand:SI 1 "arith_operand" "rI")))
6064 "xnorcc\t%r0, %1, %%g0"
6065 [(set_attr "type" "compare")])
6067 (define_insn "*cmp_ccx_xor_not"
6070 (not:DI (xor:DI (match_operand:DI 0 "register_or_zero_operand" "%rJ")
6071 (match_operand:DI 1 "arith_operand" "rI")))
6074 "xnorcc\t%r0, %1, %%g0"
6075 [(set_attr "type" "compare")])
6077 (define_insn "*cmp_cc_xor_not_set"
6080 (not:SI (xor:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ")
6081 (match_operand:SI 2 "arith_operand" "rI")))
6083 (set (match_operand:SI 0 "register_operand" "=r")
6084 (not:SI (xor:SI (match_dup 1) (match_dup 2))))]
6086 "xnorcc\t%r1, %2, %0"
6087 [(set_attr "type" "compare")])
6089 (define_insn "*cmp_ccx_xor_not_set"
6092 (not:DI (xor:DI (match_operand:DI 1 "register_or_zero_operand" "%rJ")
6093 (match_operand:DI 2 "arith_operand" "rI")))
6095 (set (match_operand:DI 0 "register_operand" "=r")
6096 (not:DI (xor:DI (match_dup 1) (match_dup 2))))]
6098 "xnorcc\t%r1, %2, %0"
6099 [(set_attr "type" "compare")])
6101 (define_insn "*cmp_cc_arith_op_not"
6104 (match_operator:SI 2 "cc_arith_not_operator"
6105 [(not:SI (match_operand:SI 0 "arith_operand" "rI"))
6106 (match_operand:SI 1 "register_or_zero_operand" "rJ")])
6109 "%B2cc\t%r1, %0, %%g0"
6110 [(set_attr "type" "compare")])
6112 (define_insn "*cmp_ccx_arith_op_not"
6115 (match_operator:DI 2 "cc_arith_not_operator"
6116 [(not:DI (match_operand:DI 0 "arith_operand" "rI"))
6117 (match_operand:DI 1 "register_or_zero_operand" "rJ")])
6120 "%B2cc\t%r1, %0, %%g0"
6121 [(set_attr "type" "compare")])
6123 (define_insn "*cmp_cc_arith_op_not_set"
6126 (match_operator:SI 3 "cc_arith_not_operator"
6127 [(not:SI (match_operand:SI 1 "arith_operand" "rI"))
6128 (match_operand:SI 2 "register_or_zero_operand" "rJ")])
6130 (set (match_operand:SI 0 "register_operand" "=r")
6131 (match_operator:SI 4 "cc_arith_not_operator"
6132 [(not:SI (match_dup 1)) (match_dup 2)]))]
6133 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
6134 "%B3cc\t%r2, %1, %0"
6135 [(set_attr "type" "compare")])
6137 (define_insn "*cmp_ccx_arith_op_not_set"
6140 (match_operator:DI 3 "cc_arith_not_operator"
6141 [(not:DI (match_operand:DI 1 "arith_operand" "rI"))
6142 (match_operand:DI 2 "register_or_zero_operand" "rJ")])
6144 (set (match_operand:DI 0 "register_operand" "=r")
6145 (match_operator:DI 4 "cc_arith_not_operator"
6146 [(not:DI (match_dup 1)) (match_dup 2)]))]
6147 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
6148 "%B3cc\t%r2, %1, %0"
6149 [(set_attr "type" "compare")])
6151 ;; We cannot use the "neg" pseudo insn because the Sun assembler
6152 ;; does not know how to make it work for constants.
6154 (define_expand "negdi2"
6155 [(set (match_operand:DI 0 "register_operand" "=r")
6156 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
6159 if (! TARGET_ARCH64)
6161 emit_insn (gen_rtx_PARALLEL
6164 gen_rtx_SET (VOIDmode, operand0,
6165 gen_rtx_NEG (DImode, operand1)),
6166 gen_rtx_CLOBBER (VOIDmode,
6167 gen_rtx_REG (CCmode,
6173 (define_insn_and_split "*negdi2_sp32"
6174 [(set (match_operand:DI 0 "register_operand" "=r")
6175 (neg:DI (match_operand:DI 1 "register_operand" "r")))
6176 (clobber (reg:CC 100))]
6179 "&& reload_completed"
6180 [(parallel [(set (reg:CC_NOOV 100)
6181 (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 5))
6183 (set (match_dup 4) (minus:SI (const_int 0) (match_dup 5)))])
6184 (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
6185 (ltu:SI (reg:CC 100) (const_int 0))))]
6186 "operands[2] = gen_highpart (SImode, operands[0]);
6187 operands[3] = gen_highpart (SImode, operands[1]);
6188 operands[4] = gen_lowpart (SImode, operands[0]);
6189 operands[5] = gen_lowpart (SImode, operands[1]);"
6190 [(set_attr "length" "2")])
6192 (define_insn "*negdi2_sp64"
6193 [(set (match_operand:DI 0 "register_operand" "=r")
6194 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
6196 "sub\t%%g0, %1, %0")
6198 (define_insn "negsi2"
6199 [(set (match_operand:SI 0 "register_operand" "=r")
6200 (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
6202 "sub\t%%g0, %1, %0")
6204 (define_insn "*cmp_cc_neg"
6205 [(set (reg:CC_NOOV 100)
6206 (compare:CC_NOOV (neg:SI (match_operand:SI 0 "arith_operand" "rI"))
6209 "subcc\t%%g0, %0, %%g0"
6210 [(set_attr "type" "compare")])
6212 (define_insn "*cmp_ccx_neg"
6213 [(set (reg:CCX_NOOV 100)
6214 (compare:CCX_NOOV (neg:DI (match_operand:DI 0 "arith_operand" "rI"))
6217 "subcc\t%%g0, %0, %%g0"
6218 [(set_attr "type" "compare")])
6220 (define_insn "*cmp_cc_set_neg"
6221 [(set (reg:CC_NOOV 100)
6222 (compare:CC_NOOV (neg:SI (match_operand:SI 1 "arith_operand" "rI"))
6224 (set (match_operand:SI 0 "register_operand" "=r")
6225 (neg:SI (match_dup 1)))]
6227 "subcc\t%%g0, %1, %0"
6228 [(set_attr "type" "compare")])
6230 (define_insn "*cmp_ccx_set_neg"
6231 [(set (reg:CCX_NOOV 100)
6232 (compare:CCX_NOOV (neg:DI (match_operand:DI 1 "arith_operand" "rI"))
6234 (set (match_operand:DI 0 "register_operand" "=r")
6235 (neg:DI (match_dup 1)))]
6237 "subcc\t%%g0, %1, %0"
6238 [(set_attr "type" "compare")])
6240 ;; We cannot use the "not" pseudo insn because the Sun assembler
6241 ;; does not know how to make it work for constants.
6242 (define_expand "one_cmpl<V64I:mode>2"
6243 [(set (match_operand:V64I 0 "register_operand" "")
6244 (not:V64I (match_operand:V64I 1 "register_operand" "")))]
6248 (define_insn_and_split "*one_cmpl<V64I:mode>2_sp32"
6249 [(set (match_operand:V64I 0 "register_operand" "=r,b")
6250 (not:V64I (match_operand:V64I 1 "register_operand" "r,b")))]
6255 "&& reload_completed
6256 && ((GET_CODE (operands[0]) == REG
6257 && REGNO (operands[0]) < 32)
6258 || (GET_CODE (operands[0]) == SUBREG
6259 && GET_CODE (SUBREG_REG (operands[0])) == REG
6260 && REGNO (SUBREG_REG (operands[0])) < 32))"
6261 [(set (match_dup 2) (not:SI (xor:SI (match_dup 3) (const_int 0))))
6262 (set (match_dup 4) (not:SI (xor:SI (match_dup 5) (const_int 0))))]
6263 "operands[2] = gen_highpart (SImode, operands[0]);
6264 operands[3] = gen_highpart (SImode, operands[1]);
6265 operands[4] = gen_lowpart (SImode, operands[0]);
6266 operands[5] = gen_lowpart (SImode, operands[1]);"
6267 [(set_attr "type" "*,fga")
6268 (set_attr "length" "2,*")
6269 (set_attr "fptype" "*,double")])
6271 (define_insn "*one_cmpl<V64I:mode>2_sp64"
6272 [(set (match_operand:V64I 0 "register_operand" "=r,b")
6273 (not:V64I (match_operand:V64I 1 "arith_operand" "rI,b")))]
6278 [(set_attr "type" "*,fga")
6279 (set_attr "fptype" "*,double")])
6281 (define_insn "one_cmpl<V32I:mode>2"
6282 [(set (match_operand:V32I 0 "register_operand" "=r,d")
6283 (not:V32I (match_operand:V32I 1 "arith_operand" "rI,d")))]
6288 [(set_attr "type" "*,fga")
6289 (set_attr "fptype" "*,single")])
6291 (define_insn "*cmp_cc_not"
6293 (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI"))
6296 "xnorcc\t%%g0, %0, %%g0"
6297 [(set_attr "type" "compare")])
6299 (define_insn "*cmp_ccx_not"
6301 (compare:CCX (not:DI (match_operand:DI 0 "arith_operand" "rI"))
6304 "xnorcc\t%%g0, %0, %%g0"
6305 [(set_attr "type" "compare")])
6307 (define_insn "*cmp_cc_set_not"
6309 (compare:CC (not:SI (match_operand:SI 1 "arith_operand" "rI"))
6311 (set (match_operand:SI 0 "register_operand" "=r")
6312 (not:SI (match_dup 1)))]
6314 "xnorcc\t%%g0, %1, %0"
6315 [(set_attr "type" "compare")])
6317 (define_insn "*cmp_ccx_set_not"
6319 (compare:CCX (not:DI (match_operand:DI 1 "arith_operand" "rI"))
6321 (set (match_operand:DI 0 "register_operand" "=r")
6322 (not:DI (match_dup 1)))]
6324 "xnorcc\t%%g0, %1, %0"
6325 [(set_attr "type" "compare")])
6327 (define_insn "*cmp_cc_set"
6328 [(set (match_operand:SI 0 "register_operand" "=r")
6329 (match_operand:SI 1 "register_operand" "r"))
6331 (compare:CC (match_dup 1)
6335 [(set_attr "type" "compare")])
6337 (define_insn "*cmp_ccx_set64"
6338 [(set (match_operand:DI 0 "register_operand" "=r")
6339 (match_operand:DI 1 "register_operand" "r"))
6341 (compare:CCX (match_dup 1)
6345 [(set_attr "type" "compare")])
6348 ;; Floating point arithmetic instructions.
6350 (define_expand "addtf3"
6351 [(set (match_operand:TF 0 "nonimmediate_operand" "")
6352 (plus:TF (match_operand:TF 1 "general_operand" "")
6353 (match_operand:TF 2 "general_operand" "")))]
6354 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6355 "emit_tfmode_binop (PLUS, operands); DONE;")
6357 (define_insn "*addtf3_hq"
6358 [(set (match_operand:TF 0 "register_operand" "=e")
6359 (plus:TF (match_operand:TF 1 "register_operand" "e")
6360 (match_operand:TF 2 "register_operand" "e")))]
6361 "TARGET_FPU && TARGET_HARD_QUAD"
6363 [(set_attr "type" "fp")])
6365 (define_insn "adddf3"
6366 [(set (match_operand:DF 0 "register_operand" "=e")
6367 (plus:DF (match_operand:DF 1 "register_operand" "e")
6368 (match_operand:DF 2 "register_operand" "e")))]
6371 [(set_attr "type" "fp")
6372 (set_attr "fptype" "double")])
6374 (define_insn "addsf3"
6375 [(set (match_operand:SF 0 "register_operand" "=f")
6376 (plus:SF (match_operand:SF 1 "register_operand" "f")
6377 (match_operand:SF 2 "register_operand" "f")))]
6380 [(set_attr "type" "fp")])
6382 (define_expand "subtf3"
6383 [(set (match_operand:TF 0 "nonimmediate_operand" "")
6384 (minus:TF (match_operand:TF 1 "general_operand" "")
6385 (match_operand:TF 2 "general_operand" "")))]
6386 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6387 "emit_tfmode_binop (MINUS, operands); DONE;")
6389 (define_insn "*subtf3_hq"
6390 [(set (match_operand:TF 0 "register_operand" "=e")
6391 (minus:TF (match_operand:TF 1 "register_operand" "e")
6392 (match_operand:TF 2 "register_operand" "e")))]
6393 "TARGET_FPU && TARGET_HARD_QUAD"
6395 [(set_attr "type" "fp")])
6397 (define_insn "subdf3"
6398 [(set (match_operand:DF 0 "register_operand" "=e")
6399 (minus:DF (match_operand:DF 1 "register_operand" "e")
6400 (match_operand:DF 2 "register_operand" "e")))]
6403 [(set_attr "type" "fp")
6404 (set_attr "fptype" "double")])
6406 (define_insn "subsf3"
6407 [(set (match_operand:SF 0 "register_operand" "=f")
6408 (minus:SF (match_operand:SF 1 "register_operand" "f")
6409 (match_operand:SF 2 "register_operand" "f")))]
6412 [(set_attr "type" "fp")])
6414 (define_expand "multf3"
6415 [(set (match_operand:TF 0 "nonimmediate_operand" "")
6416 (mult:TF (match_operand:TF 1 "general_operand" "")
6417 (match_operand:TF 2 "general_operand" "")))]
6418 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6419 "emit_tfmode_binop (MULT, operands); DONE;")
6421 (define_insn "*multf3_hq"
6422 [(set (match_operand:TF 0 "register_operand" "=e")
6423 (mult:TF (match_operand:TF 1 "register_operand" "e")
6424 (match_operand:TF 2 "register_operand" "e")))]
6425 "TARGET_FPU && TARGET_HARD_QUAD"
6427 [(set_attr "type" "fpmul")])
6429 (define_insn "muldf3"
6430 [(set (match_operand:DF 0 "register_operand" "=e")
6431 (mult:DF (match_operand:DF 1 "register_operand" "e")
6432 (match_operand:DF 2 "register_operand" "e")))]
6435 [(set_attr "type" "fpmul")
6436 (set_attr "fptype" "double")])
6438 (define_insn "mulsf3"
6439 [(set (match_operand:SF 0 "register_operand" "=f")
6440 (mult:SF (match_operand:SF 1 "register_operand" "f")
6441 (match_operand:SF 2 "register_operand" "f")))]
6444 [(set_attr "type" "fpmul")])
6446 (define_insn "*muldf3_extend"
6447 [(set (match_operand:DF 0 "register_operand" "=e")
6448 (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "f"))
6449 (float_extend:DF (match_operand:SF 2 "register_operand" "f"))))]
6450 "(TARGET_V8 || TARGET_V9) && TARGET_FPU"
6451 "fsmuld\t%1, %2, %0"
6452 [(set_attr "type" "fpmul")
6453 (set_attr "fptype" "double")])
6455 (define_insn "*multf3_extend"
6456 [(set (match_operand:TF 0 "register_operand" "=e")
6457 (mult:TF (float_extend:TF (match_operand:DF 1 "register_operand" "e"))
6458 (float_extend:TF (match_operand:DF 2 "register_operand" "e"))))]
6459 "(TARGET_V8 || TARGET_V9) && TARGET_FPU && TARGET_HARD_QUAD"
6460 "fdmulq\t%1, %2, %0"
6461 [(set_attr "type" "fpmul")])
6463 (define_expand "divtf3"
6464 [(set (match_operand:TF 0 "nonimmediate_operand" "")
6465 (div:TF (match_operand:TF 1 "general_operand" "")
6466 (match_operand:TF 2 "general_operand" "")))]
6467 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6468 "emit_tfmode_binop (DIV, operands); DONE;")
6470 ;; don't have timing for quad-prec. divide.
6471 (define_insn "*divtf3_hq"
6472 [(set (match_operand:TF 0 "register_operand" "=e")
6473 (div:TF (match_operand:TF 1 "register_operand" "e")
6474 (match_operand:TF 2 "register_operand" "e")))]
6475 "TARGET_FPU && TARGET_HARD_QUAD"
6477 [(set_attr "type" "fpdivd")])
6479 (define_insn "divdf3"
6480 [(set (match_operand:DF 0 "register_operand" "=e")
6481 (div:DF (match_operand:DF 1 "register_operand" "e")
6482 (match_operand:DF 2 "register_operand" "e")))]
6485 [(set_attr "type" "fpdivd")
6486 (set_attr "fptype" "double")])
6488 (define_insn "divsf3"
6489 [(set (match_operand:SF 0 "register_operand" "=f")
6490 (div:SF (match_operand:SF 1 "register_operand" "f")
6491 (match_operand:SF 2 "register_operand" "f")))]
6494 [(set_attr "type" "fpdivs")])
6496 (define_expand "negtf2"
6497 [(set (match_operand:TF 0 "register_operand" "=e,e")
6498 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
6502 (define_insn_and_split "*negtf2_notv9"
6503 [(set (match_operand:TF 0 "register_operand" "=e,e")
6504 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
6505 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
6511 "&& reload_completed
6512 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6513 [(set (match_dup 2) (neg:SF (match_dup 3)))
6514 (set (match_dup 4) (match_dup 5))
6515 (set (match_dup 6) (match_dup 7))]
6516 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6517 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6518 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6519 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
6520 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6521 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6522 [(set_attr "type" "fpmove,*")
6523 (set_attr "length" "*,2")])
6525 (define_insn_and_split "*negtf2_v9"
6526 [(set (match_operand:TF 0 "register_operand" "=e,e")
6527 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
6528 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
6529 "TARGET_FPU && TARGET_V9"
6533 "&& reload_completed
6534 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6535 [(set (match_dup 2) (neg:DF (match_dup 3)))
6536 (set (match_dup 4) (match_dup 5))]
6537 "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
6538 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
6539 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6540 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6541 [(set_attr "type" "fpmove,*")
6542 (set_attr "length" "*,2")
6543 (set_attr "fptype" "double")])
6545 (define_expand "negdf2"
6546 [(set (match_operand:DF 0 "register_operand" "")
6547 (neg:DF (match_operand:DF 1 "register_operand" "")))]
6551 (define_insn_and_split "*negdf2_notv9"
6552 [(set (match_operand:DF 0 "register_operand" "=e,e")
6553 (neg:DF (match_operand:DF 1 "register_operand" "0,e")))]
6554 "TARGET_FPU && ! TARGET_V9"
6558 "&& reload_completed
6559 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6560 [(set (match_dup 2) (neg:SF (match_dup 3)))
6561 (set (match_dup 4) (match_dup 5))]
6562 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6563 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6564 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6565 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);"
6566 [(set_attr "type" "fpmove,*")
6567 (set_attr "length" "*,2")])
6569 (define_insn "*negdf2_v9"
6570 [(set (match_operand:DF 0 "register_operand" "=e")
6571 (neg:DF (match_operand:DF 1 "register_operand" "e")))]
6572 "TARGET_FPU && TARGET_V9"
6574 [(set_attr "type" "fpmove")
6575 (set_attr "fptype" "double")])
6577 (define_insn "negsf2"
6578 [(set (match_operand:SF 0 "register_operand" "=f")
6579 (neg:SF (match_operand:SF 1 "register_operand" "f")))]
6582 [(set_attr "type" "fpmove")])
6584 (define_expand "abstf2"
6585 [(set (match_operand:TF 0 "register_operand" "")
6586 (abs:TF (match_operand:TF 1 "register_operand" "")))]
6590 (define_insn_and_split "*abstf2_notv9"
6591 [(set (match_operand:TF 0 "register_operand" "=e,e")
6592 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6593 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
6594 "TARGET_FPU && ! TARGET_V9"
6598 "&& reload_completed
6599 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6600 [(set (match_dup 2) (abs:SF (match_dup 3)))
6601 (set (match_dup 4) (match_dup 5))
6602 (set (match_dup 6) (match_dup 7))]
6603 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6604 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6605 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6606 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
6607 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6608 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6609 [(set_attr "type" "fpmove,*")
6610 (set_attr "length" "*,2")])
6612 (define_insn "*abstf2_hq_v9"
6613 [(set (match_operand:TF 0 "register_operand" "=e,e")
6614 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6615 "TARGET_FPU && TARGET_V9 && TARGET_HARD_QUAD"
6619 [(set_attr "type" "fpmove")
6620 (set_attr "fptype" "double,*")])
6622 (define_insn_and_split "*abstf2_v9"
6623 [(set (match_operand:TF 0 "register_operand" "=e,e")
6624 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6625 "TARGET_FPU && TARGET_V9 && !TARGET_HARD_QUAD"
6629 "&& reload_completed
6630 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6631 [(set (match_dup 2) (abs:DF (match_dup 3)))
6632 (set (match_dup 4) (match_dup 5))]
6633 "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
6634 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
6635 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6636 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6637 [(set_attr "type" "fpmove,*")
6638 (set_attr "length" "*,2")
6639 (set_attr "fptype" "double,*")])
6641 (define_expand "absdf2"
6642 [(set (match_operand:DF 0 "register_operand" "")
6643 (abs:DF (match_operand:DF 1 "register_operand" "")))]
6647 (define_insn_and_split "*absdf2_notv9"
6648 [(set (match_operand:DF 0 "register_operand" "=e,e")
6649 (abs:DF (match_operand:DF 1 "register_operand" "0,e")))]
6650 "TARGET_FPU && ! TARGET_V9"
6654 "&& reload_completed
6655 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6656 [(set (match_dup 2) (abs:SF (match_dup 3)))
6657 (set (match_dup 4) (match_dup 5))]
6658 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6659 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6660 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6661 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);"
6662 [(set_attr "type" "fpmove,*")
6663 (set_attr "length" "*,2")])
6665 (define_insn "*absdf2_v9"
6666 [(set (match_operand:DF 0 "register_operand" "=e")
6667 (abs:DF (match_operand:DF 1 "register_operand" "e")))]
6668 "TARGET_FPU && TARGET_V9"
6670 [(set_attr "type" "fpmove")
6671 (set_attr "fptype" "double")])
6673 (define_insn "abssf2"
6674 [(set (match_operand:SF 0 "register_operand" "=f")
6675 (abs:SF (match_operand:SF 1 "register_operand" "f")))]
6678 [(set_attr "type" "fpmove")])
6680 (define_expand "sqrttf2"
6681 [(set (match_operand:TF 0 "nonimmediate_operand" "")
6682 (sqrt:TF (match_operand:TF 1 "general_operand" "")))]
6683 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6684 "emit_tfmode_unop (SQRT, operands); DONE;")
6686 (define_insn "*sqrttf2_hq"
6687 [(set (match_operand:TF 0 "register_operand" "=e")
6688 (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
6689 "TARGET_FPU && TARGET_HARD_QUAD"
6691 [(set_attr "type" "fpsqrtd")])
6693 (define_insn "sqrtdf2"
6694 [(set (match_operand:DF 0 "register_operand" "=e")
6695 (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
6698 [(set_attr "type" "fpsqrtd")
6699 (set_attr "fptype" "double")])
6701 (define_insn "sqrtsf2"
6702 [(set (match_operand:SF 0 "register_operand" "=f")
6703 (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
6706 [(set_attr "type" "fpsqrts")])
6709 ;; Arithmetic shift instructions.
6711 (define_insn "ashlsi3"
6712 [(set (match_operand:SI 0 "register_operand" "=r")
6713 (ashift:SI (match_operand:SI 1 "register_operand" "r")
6714 (match_operand:SI 2 "arith_operand" "rI")))]
6717 if (GET_CODE (operands[2]) == CONST_INT)
6718 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6719 return "sll\t%1, %2, %0";
6722 (if_then_else (match_operand 2 "const_one_operand" "")
6723 (const_string "ialu") (const_string "shift")))])
6725 (define_expand "ashldi3"
6726 [(set (match_operand:DI 0 "register_operand" "=r")
6727 (ashift:DI (match_operand:DI 1 "register_operand" "r")
6728 (match_operand:SI 2 "arith_operand" "rI")))]
6729 "TARGET_ARCH64 || TARGET_V8PLUS"
6731 if (! TARGET_ARCH64)
6733 if (GET_CODE (operands[2]) == CONST_INT)
6735 emit_insn (gen_ashldi3_v8plus (operands[0], operands[1], operands[2]));
6740 (define_insn "*ashldi3_sp64"
6741 [(set (match_operand:DI 0 "register_operand" "=r")
6742 (ashift:DI (match_operand:DI 1 "register_operand" "r")
6743 (match_operand:SI 2 "arith_operand" "rI")))]
6746 if (GET_CODE (operands[2]) == CONST_INT)
6747 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
6748 return "sllx\t%1, %2, %0";
6751 (if_then_else (match_operand 2 "const_one_operand" "")
6752 (const_string "ialu") (const_string "shift")))])
6755 (define_insn "ashldi3_v8plus"
6756 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
6757 (ashift:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
6758 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
6759 (clobber (match_scratch:SI 3 "=X,X,&h"))]
6761 "* return output_v8plus_shift (operands, insn, \"sllx\");"
6762 [(set_attr "type" "multi")
6763 (set_attr "length" "5,5,6")])
6765 ;; Optimize (1LL<<x)-1
6766 ;; XXX this also needs to be fixed to handle equal subregs
6767 ;; XXX first before we could re-enable it.
6769 ; [(set (match_operand:DI 0 "register_operand" "=h")
6770 ; (plus:DI (ashift:DI (const_int 1)
6771 ; (match_operand:SI 1 "arith_operand" "rI"))
6773 ; "0 && TARGET_V8PLUS"
6775 ; if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == REGNO (operands[0]))
6776 ; return "mov\t1, %L0\;sllx\t%L0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
6777 ; return "mov\t1, %H0\;sllx\t%H0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
6779 ; [(set_attr "type" "multi")
6780 ; (set_attr "length" "4")])
6782 (define_insn "*cmp_cc_ashift_1"
6783 [(set (reg:CC_NOOV 100)
6784 (compare:CC_NOOV (ashift:SI (match_operand:SI 0 "register_operand" "r")
6788 "addcc\t%0, %0, %%g0"
6789 [(set_attr "type" "compare")])
6791 (define_insn "*cmp_cc_set_ashift_1"
6792 [(set (reg:CC_NOOV 100)
6793 (compare:CC_NOOV (ashift:SI (match_operand:SI 1 "register_operand" "r")
6796 (set (match_operand:SI 0 "register_operand" "=r")
6797 (ashift:SI (match_dup 1) (const_int 1)))]
6800 [(set_attr "type" "compare")])
6802 (define_insn "ashrsi3"
6803 [(set (match_operand:SI 0 "register_operand" "=r")
6804 (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
6805 (match_operand:SI 2 "arith_operand" "rI")))]
6808 if (GET_CODE (operands[2]) == CONST_INT)
6809 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6810 return "sra\t%1, %2, %0";
6812 [(set_attr "type" "shift")])
6814 (define_insn "*ashrsi3_extend"
6815 [(set (match_operand:DI 0 "register_operand" "=r")
6816 (sign_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
6817 (match_operand:SI 2 "arith_operand" "r"))))]
6820 [(set_attr "type" "shift")])
6822 ;; This handles the case as above, but with constant shift instead of
6823 ;; register. Combiner "simplifies" it for us a little bit though.
6824 (define_insn "*ashrsi3_extend2"
6825 [(set (match_operand:DI 0 "register_operand" "=r")
6826 (ashiftrt:DI (ashift:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
6828 (match_operand:SI 2 "small_int_operand" "I")))]
6829 "TARGET_ARCH64 && INTVAL (operands[2]) >= 32 && INTVAL (operands[2]) < 64"
6831 operands[2] = GEN_INT (INTVAL (operands[2]) - 32);
6832 return "sra\t%1, %2, %0";
6834 [(set_attr "type" "shift")])
6836 (define_expand "ashrdi3"
6837 [(set (match_operand:DI 0 "register_operand" "=r")
6838 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
6839 (match_operand:SI 2 "arith_operand" "rI")))]
6840 "TARGET_ARCH64 || TARGET_V8PLUS"
6842 if (! TARGET_ARCH64)
6844 if (GET_CODE (operands[2]) == CONST_INT)
6845 FAIL; /* prefer generic code in this case */
6846 emit_insn (gen_ashrdi3_v8plus (operands[0], operands[1], operands[2]));
6851 (define_insn "*ashrdi3_sp64"
6852 [(set (match_operand:DI 0 "register_operand" "=r")
6853 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
6854 (match_operand:SI 2 "arith_operand" "rI")))]
6858 if (GET_CODE (operands[2]) == CONST_INT)
6859 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
6860 return "srax\t%1, %2, %0";
6862 [(set_attr "type" "shift")])
6865 (define_insn "ashrdi3_v8plus"
6866 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
6867 (ashiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
6868 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
6869 (clobber (match_scratch:SI 3 "=X,X,&h"))]
6871 "* return output_v8plus_shift (operands, insn, \"srax\");"
6872 [(set_attr "type" "multi")
6873 (set_attr "length" "5,5,6")])
6875 (define_insn "lshrsi3"
6876 [(set (match_operand:SI 0 "register_operand" "=r")
6877 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
6878 (match_operand:SI 2 "arith_operand" "rI")))]
6881 if (GET_CODE (operands[2]) == CONST_INT)
6882 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6883 return "srl\t%1, %2, %0";
6885 [(set_attr "type" "shift")])
6887 ;; This handles the case where
6888 ;; (zero_extend:DI (lshiftrt:SI (match_operand:SI) (match_operand:SI))),
6889 ;; but combiner "simplifies" it for us.
6890 (define_insn "*lshrsi3_extend"
6891 [(set (match_operand:DI 0 "register_operand" "=r")
6892 (and:DI (subreg:DI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
6893 (match_operand:SI 2 "arith_operand" "r")) 0)
6894 (match_operand 3 "const_int_operand" "")))]
6895 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) == 0xffffffff"
6897 [(set_attr "type" "shift")])
6899 ;; This handles the case where
6900 ;; (lshiftrt:DI (zero_extend:DI (match_operand:SI)) (const_int >=0 < 32))
6901 ;; but combiner "simplifies" it for us.
6902 (define_insn "*lshrsi3_extend2"
6903 [(set (match_operand:DI 0 "register_operand" "=r")
6904 (zero_extract:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
6905 (match_operand 2 "small_int_operand" "I")
6907 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
6909 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
6910 return "srl\t%1, %2, %0";
6912 [(set_attr "type" "shift")])
6914 (define_expand "lshrdi3"
6915 [(set (match_operand:DI 0 "register_operand" "=r")
6916 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6917 (match_operand:SI 2 "arith_operand" "rI")))]
6918 "TARGET_ARCH64 || TARGET_V8PLUS"
6920 if (! TARGET_ARCH64)
6922 if (GET_CODE (operands[2]) == CONST_INT)
6924 emit_insn (gen_lshrdi3_v8plus (operands[0], operands[1], operands[2]));
6929 (define_insn "*lshrdi3_sp64"
6930 [(set (match_operand:DI 0 "register_operand" "=r")
6931 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6932 (match_operand:SI 2 "arith_operand" "rI")))]
6935 if (GET_CODE (operands[2]) == CONST_INT)
6936 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
6937 return "srlx\t%1, %2, %0";
6939 [(set_attr "type" "shift")])
6942 (define_insn "lshrdi3_v8plus"
6943 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
6944 (lshiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
6945 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
6946 (clobber (match_scratch:SI 3 "=X,X,&h"))]
6948 "* return output_v8plus_shift (operands, insn, \"srlx\");"
6949 [(set_attr "type" "multi")
6950 (set_attr "length" "5,5,6")])
6953 [(set (match_operand:SI 0 "register_operand" "=r")
6954 (ashiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6956 (match_operand:SI 2 "small_int_operand" "I")))]
6957 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
6959 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
6960 return "srax\t%1, %2, %0";
6962 [(set_attr "type" "shift")])
6965 [(set (match_operand:SI 0 "register_operand" "=r")
6966 (lshiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
6968 (match_operand:SI 2 "small_int_operand" "I")))]
6969 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
6971 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
6972 return "srlx\t%1, %2, %0";
6974 [(set_attr "type" "shift")])
6977 [(set (match_operand:SI 0 "register_operand" "=r")
6978 (ashiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
6979 (match_operand:SI 2 "small_int_operand" "I")) 4)
6980 (match_operand:SI 3 "small_int_operand" "I")))]
6982 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
6983 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
6984 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
6986 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
6988 return "srax\t%1, %2, %0";
6990 [(set_attr "type" "shift")])
6993 [(set (match_operand:SI 0 "register_operand" "=r")
6994 (lshiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6995 (match_operand:SI 2 "small_int_operand" "I")) 4)
6996 (match_operand:SI 3 "small_int_operand" "I")))]
6998 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
6999 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
7000 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
7002 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
7004 return "srlx\t%1, %2, %0";
7006 [(set_attr "type" "shift")])
7009 ;; Unconditional and other jump instructions.
7012 [(set (pc) (label_ref (match_operand 0 "" "")))]
7014 "* return output_ubranch (operands[0], 0, insn);"
7015 [(set_attr "type" "uncond_branch")])
7017 (define_expand "tablejump"
7018 [(parallel [(set (pc) (match_operand 0 "register_operand" "r"))
7019 (use (label_ref (match_operand 1 "" "")))])]
7022 gcc_assert (GET_MODE (operands[0]) == CASE_VECTOR_MODE);
7024 /* In pic mode, our address differences are against the base of the
7025 table. Add that base value back in; CSE ought to be able to combine
7026 the two address loads. */
7030 tmp = gen_rtx_LABEL_REF (Pmode, operands[1]);
7032 if (CASE_VECTOR_MODE != Pmode)
7033 tmp2 = gen_rtx_SIGN_EXTEND (Pmode, tmp2);
7034 tmp = gen_rtx_PLUS (Pmode, tmp2, tmp);
7035 operands[0] = memory_address (Pmode, tmp);
7039 (define_insn "*tablejump_sp32"
7040 [(set (pc) (match_operand:SI 0 "address_operand" "p"))
7041 (use (label_ref (match_operand 1 "" "")))]
7044 [(set_attr "type" "uncond_branch")])
7046 (define_insn "*tablejump_sp64"
7047 [(set (pc) (match_operand:DI 0 "address_operand" "p"))
7048 (use (label_ref (match_operand 1 "" "")))]
7051 [(set_attr "type" "uncond_branch")])
7054 ;; Jump to subroutine instructions.
7056 (define_expand "call"
7057 ;; Note that this expression is not used for generating RTL.
7058 ;; All the RTL is generated explicitly below.
7059 [(call (match_operand 0 "call_operand" "")
7060 (match_operand 3 "" "i"))]
7061 ;; operands[2] is next_arg_register
7062 ;; operands[3] is struct_value_size_rtx.
7067 gcc_assert (GET_MODE (operands[0]) == FUNCTION_MODE);
7069 gcc_assert (GET_CODE (operands[3]) == CONST_INT);
7071 if (GET_CODE (XEXP (operands[0], 0)) == LABEL_REF)
7073 /* This is really a PIC sequence. We want to represent
7074 it as a funny jump so its delay slots can be filled.
7076 ??? But if this really *is* a CALL, will not it clobber the
7077 call-clobbered registers? We lose this if it is a JUMP_INSN.
7078 Why cannot we have delay slots filled if it were a CALL? */
7080 /* We accept negative sizes for untyped calls. */
7081 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
7086 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
7088 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
7094 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
7095 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
7099 fn_rtx = operands[0];
7101 /* We accept negative sizes for untyped calls. */
7102 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
7106 gen_rtvec (3, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx),
7108 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
7113 gen_rtvec (2, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx),
7114 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
7121 ;; We can't use the same pattern for these two insns, because then registers
7122 ;; in the address may not be properly reloaded.
7124 (define_insn "*call_address_sp32"
7125 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
7126 (match_operand 1 "" ""))
7127 (clobber (reg:SI 15))]
7128 ;;- Do not use operand 1 for most machines.
7131 [(set_attr "type" "call")])
7133 (define_insn "*call_symbolic_sp32"
7134 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
7135 (match_operand 1 "" ""))
7136 (clobber (reg:SI 15))]
7137 ;;- Do not use operand 1 for most machines.
7140 [(set_attr "type" "call")])
7142 (define_insn "*call_address_sp64"
7143 [(call (mem:DI (match_operand:DI 0 "address_operand" "p"))
7144 (match_operand 1 "" ""))
7145 (clobber (reg:DI 15))]
7146 ;;- Do not use operand 1 for most machines.
7149 [(set_attr "type" "call")])
7151 (define_insn "*call_symbolic_sp64"
7152 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
7153 (match_operand 1 "" ""))
7154 (clobber (reg:DI 15))]
7155 ;;- Do not use operand 1 for most machines.
7158 [(set_attr "type" "call")])
7160 ;; This is a call that wants a structure value.
7161 ;; There is no such critter for v9 (??? we may need one anyway).
7162 (define_insn "*call_address_struct_value_sp32"
7163 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
7164 (match_operand 1 "" ""))
7165 (match_operand 2 "immediate_operand" "")
7166 (clobber (reg:SI 15))]
7167 ;;- Do not use operand 1 for most machines.
7168 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
7170 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xfff);
7171 return "call\t%a0, %1\n\t nop\n\tunimp\t%2";
7173 [(set_attr "type" "call_no_delay_slot")
7174 (set_attr "length" "3")])
7176 ;; This is a call that wants a structure value.
7177 ;; There is no such critter for v9 (??? we may need one anyway).
7178 (define_insn "*call_symbolic_struct_value_sp32"
7179 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
7180 (match_operand 1 "" ""))
7181 (match_operand 2 "immediate_operand" "")
7182 (clobber (reg:SI 15))]
7183 ;;- Do not use operand 1 for most machines.
7184 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
7186 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xfff);
7187 return "call\t%a0, %1\n\t nop\n\tunimp\t%2";
7189 [(set_attr "type" "call_no_delay_slot")
7190 (set_attr "length" "3")])
7192 ;; This is a call that may want a structure value. This is used for
7194 (define_insn "*call_address_untyped_struct_value_sp32"
7195 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
7196 (match_operand 1 "" ""))
7197 (match_operand 2 "immediate_operand" "")
7198 (clobber (reg:SI 15))]
7199 ;;- Do not use operand 1 for most machines.
7200 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
7201 "call\t%a0, %1\n\t nop\n\tnop"
7202 [(set_attr "type" "call_no_delay_slot")
7203 (set_attr "length" "3")])
7205 ;; This is a call that may want a structure value. This is used for
7207 (define_insn "*call_symbolic_untyped_struct_value_sp32"
7208 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
7209 (match_operand 1 "" ""))
7210 (match_operand 2 "immediate_operand" "")
7211 (clobber (reg:SI 15))]
7212 ;;- Do not use operand 1 for most machines.
7213 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
7214 "call\t%a0, %1\n\t nop\n\tnop"
7215 [(set_attr "type" "call_no_delay_slot")
7216 (set_attr "length" "3")])
7218 (define_expand "call_value"
7219 ;; Note that this expression is not used for generating RTL.
7220 ;; All the RTL is generated explicitly below.
7221 [(set (match_operand 0 "register_operand" "=rf")
7222 (call (match_operand 1 "" "")
7223 (match_operand 4 "" "")))]
7224 ;; operand 2 is stack_size_rtx
7225 ;; operand 3 is next_arg_register
7231 gcc_assert (GET_MODE (operands[1]) == FUNCTION_MODE);
7233 fn_rtx = operands[1];
7236 gen_rtx_SET (VOIDmode, operands[0],
7237 gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx)),
7238 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)));
7240 emit_call_insn (gen_rtx_PARALLEL (VOIDmode, vec));
7245 (define_insn "*call_value_address_sp32"
7246 [(set (match_operand 0 "" "=rf")
7247 (call (mem:SI (match_operand:SI 1 "address_operand" "p"))
7248 (match_operand 2 "" "")))
7249 (clobber (reg:SI 15))]
7250 ;;- Do not use operand 2 for most machines.
7253 [(set_attr "type" "call")])
7255 (define_insn "*call_value_symbolic_sp32"
7256 [(set (match_operand 0 "" "=rf")
7257 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
7258 (match_operand 2 "" "")))
7259 (clobber (reg:SI 15))]
7260 ;;- Do not use operand 2 for most machines.
7263 [(set_attr "type" "call")])
7265 (define_insn "*call_value_address_sp64"
7266 [(set (match_operand 0 "" "")
7267 (call (mem:DI (match_operand:DI 1 "address_operand" "p"))
7268 (match_operand 2 "" "")))
7269 (clobber (reg:DI 15))]
7270 ;;- Do not use operand 2 for most machines.
7273 [(set_attr "type" "call")])
7275 (define_insn "*call_value_symbolic_sp64"
7276 [(set (match_operand 0 "" "")
7277 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
7278 (match_operand 2 "" "")))
7279 (clobber (reg:DI 15))]
7280 ;;- Do not use operand 2 for most machines.
7283 [(set_attr "type" "call")])
7285 (define_expand "untyped_call"
7286 [(parallel [(call (match_operand 0 "" "")
7288 (match_operand:BLK 1 "memory_operand" "")
7289 (match_operand 2 "" "")])]
7292 rtx valreg1 = gen_rtx_REG (DImode, 8);
7293 rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
7294 rtx result = operands[1];
7296 /* Pass constm1 to indicate that it may expect a structure value, but
7297 we don't know what size it is. */
7298 emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, constm1_rtx));
7300 /* Save the function value registers. */
7301 emit_move_insn (adjust_address (result, DImode, 0), valreg1);
7302 emit_move_insn (adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8),
7305 /* The optimizer does not know that the call sets the function value
7306 registers we stored in the result block. We avoid problems by
7307 claiming that all hard registers are used and clobbered at this
7309 emit_insn (gen_blockage ());
7314 ;; Tail call instructions.
7316 (define_expand "sibcall"
7317 [(parallel [(call (match_operand 0 "call_operand" "") (const_int 0))
7322 (define_insn "*sibcall_symbolic_sp32"
7323 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
7324 (match_operand 1 "" ""))
7327 "* return output_sibcall(insn, operands[0]);"
7328 [(set_attr "type" "sibcall")])
7330 (define_insn "*sibcall_symbolic_sp64"
7331 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
7332 (match_operand 1 "" ""))
7335 "* return output_sibcall(insn, operands[0]);"
7336 [(set_attr "type" "sibcall")])
7338 (define_expand "sibcall_value"
7339 [(parallel [(set (match_operand 0 "register_operand" "=rf")
7340 (call (match_operand 1 "" "") (const_int 0)))
7345 (define_insn "*sibcall_value_symbolic_sp32"
7346 [(set (match_operand 0 "" "=rf")
7347 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
7348 (match_operand 2 "" "")))
7351 "* return output_sibcall(insn, operands[1]);"
7352 [(set_attr "type" "sibcall")])
7354 (define_insn "*sibcall_value_symbolic_sp64"
7355 [(set (match_operand 0 "" "")
7356 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
7357 (match_operand 2 "" "")))
7360 "* return output_sibcall(insn, operands[1]);"
7361 [(set_attr "type" "sibcall")])
7364 ;; Special instructions.
7366 (define_expand "prologue"
7370 sparc_expand_prologue ();
7374 ;; The "save register window" insn is modelled as follows so that the DWARF-2
7375 ;; backend automatically emits the required call frame debugging information
7376 ;; while it is parsing it. Therefore, the pattern should not be modified
7377 ;; without first studying the impact of the changes on the debug info.
7378 ;; [(set (%fp) (%sp))
7379 ;; (set (%sp) (unspec_volatile [(%sp) (-frame_size)] UNSPECV_SAVEW))
7380 ;; (set (%i7) (%o7))]
7382 (define_insn "save_register_window<P:mode>"
7383 [(set (reg:P 30) (reg:P 14))
7384 (set (reg:P 14) (unspec_volatile:P [(reg:P 14)
7385 (match_operand:P 0 "arith_operand" "rI")] UNSPECV_SAVEW))
7386 (set (reg:P 31) (reg:P 15))]
7388 "save\t%%sp, %0, %%sp"
7389 [(set_attr "type" "savew")])
7391 (define_expand "epilogue"
7395 sparc_expand_epilogue ();
7398 (define_expand "sibcall_epilogue"
7402 sparc_expand_epilogue ();
7406 (define_expand "return"
7408 "sparc_can_use_return_insn_p ()"
7411 (define_insn "*return_internal"
7414 "* return output_return (insn);"
7415 [(set_attr "type" "return")
7416 (set (attr "length")
7417 (cond [(eq_attr "leaf_function" "true")
7418 (if_then_else (eq_attr "empty_delay_slot" "true")
7421 (eq_attr "calls_eh_return" "true")
7422 (if_then_else (eq_attr "delayed_branch" "true")
7423 (if_then_else (eq_attr "isa" "v9")
7426 (if_then_else (eq_attr "isa" "v9")
7429 (eq_attr "empty_delay_slot" "true")
7430 (if_then_else (eq_attr "delayed_branch" "true")
7435 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
7436 ;; all of memory. This blocks insns from being moved across this point.
7438 (define_insn "blockage"
7439 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
7442 [(set_attr "length" "0")])
7444 ;; Prepare to return any type including a structure value.
7446 (define_expand "untyped_return"
7447 [(match_operand:BLK 0 "memory_operand" "")
7448 (match_operand 1 "" "")]
7451 rtx valreg1 = gen_rtx_REG (DImode, 24);
7452 rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
7453 rtx result = operands[0];
7455 if (! TARGET_ARCH64)
7457 rtx rtnreg = gen_rtx_REG (SImode, (current_function_uses_only_leaf_regs
7459 rtx value = gen_reg_rtx (SImode);
7461 /* Fetch the instruction where we will return to and see if it's an unimp
7462 instruction (the most significant 10 bits will be zero). If so,
7463 update the return address to skip the unimp instruction. */
7464 emit_move_insn (value,
7465 gen_rtx_MEM (SImode, plus_constant (rtnreg, 8)));
7466 emit_insn (gen_lshrsi3 (value, value, GEN_INT (22)));
7467 emit_insn (gen_update_return (rtnreg, value));
7470 /* Reload the function value registers. */
7471 emit_move_insn (valreg1, adjust_address (result, DImode, 0));
7472 emit_move_insn (valreg2,
7473 adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8));
7475 /* Put USE insns before the return. */
7476 emit_insn (gen_rtx_USE (VOIDmode, valreg1));
7477 emit_insn (gen_rtx_USE (VOIDmode, valreg2));
7479 /* Construct the return. */
7480 expand_naked_return ();
7485 ;; This is a bit of a hack. We're incrementing a fixed register (%i7),
7486 ;; and parts of the compiler don't want to believe that the add is needed.
7488 (define_insn "update_return"
7489 [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
7490 (match_operand:SI 1 "register_operand" "r")] UNSPEC_UPDATE_RETURN)]
7493 if (flag_delayed_branch)
7494 return "cmp\t%1, 0\n\tbe,a\t.+8\n\t add\t%0, 4, %0";
7496 return "cmp\t%1, 0\n\tbne\t.+12\n\t nop\n\tadd\t%0, 4, %0";
7498 [(set (attr "type") (const_string "multi"))
7499 (set (attr "length")
7500 (if_then_else (eq_attr "delayed_branch" "true")
7509 (define_expand "indirect_jump"
7510 [(set (pc) (match_operand 0 "address_operand" "p"))]
7514 (define_insn "*branch_sp32"
7515 [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
7518 [(set_attr "type" "uncond_branch")])
7520 (define_insn "*branch_sp64"
7521 [(set (pc) (match_operand:DI 0 "address_operand" "p"))]
7524 [(set_attr "type" "uncond_branch")])
7526 (define_expand "nonlocal_goto"
7527 [(match_operand:SI 0 "general_operand" "")
7528 (match_operand:SI 1 "general_operand" "")
7529 (match_operand:SI 2 "general_operand" "")
7530 (match_operand:SI 3 "" "")]
7533 rtx lab = operands[1];
7534 rtx stack = operands[2];
7535 rtx fp = operands[3];
7538 /* Trap instruction to flush all the register windows. */
7539 emit_insn (gen_flush_register_windows ());
7541 /* Load the fp value for the containing fn into %fp. This is needed
7542 because STACK refers to %fp. Note that virtual register instantiation
7543 fails if the virtual %fp isn't set from a register. */
7544 if (GET_CODE (fp) != REG)
7545 fp = force_reg (Pmode, fp);
7546 emit_move_insn (virtual_stack_vars_rtx, fp);
7548 /* Find the containing function's current nonlocal goto handler,
7549 which will do any cleanups and then jump to the label. */
7550 labreg = gen_rtx_REG (Pmode, 8);
7551 emit_move_insn (labreg, lab);
7553 /* Restore %fp from stack pointer value for containing function.
7554 The restore insn that follows will move this to %sp,
7555 and reload the appropriate value into %fp. */
7556 emit_move_insn (hard_frame_pointer_rtx, stack);
7558 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
7559 emit_insn (gen_rtx_USE (VOIDmode, static_chain_rtx));
7561 /* ??? The V9-specific version was disabled in rev 1.65. */
7562 emit_jump_insn (gen_goto_handler_and_restore (labreg));
7567 ;; Special trap insn to flush register windows.
7568 (define_insn "flush_register_windows"
7569 [(unspec_volatile [(const_int 0)] UNSPECV_FLUSHW)]
7571 { return TARGET_V9 ? "flushw" : "ta\t3"; }
7572 [(set_attr "type" "flushw")])
7574 (define_insn "goto_handler_and_restore"
7575 [(unspec_volatile [(match_operand 0 "register_operand" "=r")] UNSPECV_GOTO)]
7576 "GET_MODE (operands[0]) == Pmode"
7578 if (flag_delayed_branch)
7579 return "jmp\t%0\n\t restore";
7581 return "mov\t%0,%%g1\n\trestore\n\tjmp\t%%g1\n\t nop";
7583 [(set (attr "type") (const_string "multi"))
7584 (set (attr "length")
7585 (if_then_else (eq_attr "delayed_branch" "true")
7589 ;; For __builtin_setjmp we need to flush register windows iff the function
7590 ;; calls alloca as well, because otherwise the register window might be
7591 ;; saved after %sp adjustment and thus setjmp would crash
7592 (define_expand "builtin_setjmp_setup"
7593 [(match_operand 0 "register_operand" "r")]
7596 emit_insn (gen_do_builtin_setjmp_setup ());
7600 (define_insn "do_builtin_setjmp_setup"
7601 [(unspec_volatile [(const_int 0)] UNSPECV_SETJMP)]
7604 if (! current_function_calls_alloca)
7608 fputs ("\tflushw\n", asm_out_file);
7610 fprintf (asm_out_file, "\tst%c\t%%l7, [%%sp+%d]\n",
7611 TARGET_ARCH64 ? 'x' : 'w',
7612 SPARC_STACK_BIAS + 7 * UNITS_PER_WORD);
7613 fprintf (asm_out_file, "\tst%c\t%%fp, [%%sp+%d]\n",
7614 TARGET_ARCH64 ? 'x' : 'w',
7615 SPARC_STACK_BIAS + 14 * UNITS_PER_WORD);
7616 fprintf (asm_out_file, "\tst%c\t%%i7, [%%sp+%d]\n",
7617 TARGET_ARCH64 ? 'x' : 'w',
7618 SPARC_STACK_BIAS + 15 * UNITS_PER_WORD);
7621 [(set_attr "type" "multi")
7622 (set (attr "length")
7623 (cond [(eq_attr "calls_alloca" "false")
7625 (eq_attr "isa" "!v9")
7627 (eq_attr "pic" "true")
7628 (const_int 4)] (const_int 3)))])
7630 ;; Pattern for use after a setjmp to store FP and the return register
7631 ;; into the stack area.
7633 (define_expand "setjmp"
7638 emit_insn (gen_setjmp_64 ());
7640 emit_insn (gen_setjmp_32 ());
7644 (define_expand "setjmp_32"
7645 [(set (mem:SI (plus:SI (reg:SI 14) (const_int 56))) (match_dup 0))
7646 (set (mem:SI (plus:SI (reg:SI 14) (const_int 60))) (reg:SI 31))]
7648 { operands[0] = frame_pointer_rtx; })
7650 (define_expand "setjmp_64"
7651 [(set (mem:DI (plus:DI (reg:DI 14) (const_int 112))) (match_dup 0))
7652 (set (mem:DI (plus:DI (reg:DI 14) (const_int 120))) (reg:DI 31))]
7654 { operands[0] = frame_pointer_rtx; })
7656 ;; Special pattern for the FLUSH instruction.
7658 ; We do SImode and DImode versions of this to quiet down genrecog's complaints
7659 ; of the define_insn otherwise missing a mode. We make "flush", aka
7660 ; gen_flush, the default one since sparc_initialize_trampoline uses
7661 ; it on SImode mem values.
7663 (define_insn "flush"
7664 [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")] UNSPECV_FLUSH)]
7666 { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; }
7667 [(set_attr "type" "iflush")])
7669 (define_insn "flushdi"
7670 [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")] UNSPECV_FLUSH)]
7672 { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; }
7673 [(set_attr "type" "iflush")])
7676 ;; Find first set instructions.
7678 ;; The scan instruction searches from the most significant bit while ffs
7679 ;; searches from the least significant bit. The bit index and treatment of
7680 ;; zero also differ. It takes at least 7 instructions to get the proper
7681 ;; result. Here is an obvious 8 instruction sequence.
7684 (define_insn "ffssi2"
7685 [(set (match_operand:SI 0 "register_operand" "=&r")
7686 (ffs:SI (match_operand:SI 1 "register_operand" "r")))
7687 (clobber (match_scratch:SI 2 "=&r"))]
7688 "TARGET_SPARCLITE || TARGET_SPARCLET"
7690 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";
7692 [(set_attr "type" "multi")
7693 (set_attr "length" "8")])
7695 ;; ??? This should be a define expand, so that the extra instruction have
7696 ;; a chance of being optimized away.
7698 ;; Disabled because none of the UltraSPARCs implement popc. The HAL R1
7699 ;; does, but no one uses that and we don't have a switch for it.
7701 ;(define_insn "ffsdi2"
7702 ; [(set (match_operand:DI 0 "register_operand" "=&r")
7703 ; (ffs:DI (match_operand:DI 1 "register_operand" "r")))
7704 ; (clobber (match_scratch:DI 2 "=&r"))]
7706 ; "neg\t%1, %2\;xnor\t%1, %2, %2\;popc\t%2, %0\;movzr\t%1, 0, %0"
7707 ; [(set_attr "type" "multi")
7708 ; (set_attr "length" "4")])
7712 ;; Peepholes go at the end.
7714 ;; Optimize consecutive loads or stores into ldd and std when possible.
7715 ;; The conditions in which we do this are very restricted and are
7716 ;; explained in the code for {registers,memory}_ok_for_ldd functions.
7719 [(set (match_operand:SI 0 "memory_operand" "")
7721 (set (match_operand:SI 1 "memory_operand" "")
7724 && mems_ok_for_ldd_peep (operands[0], operands[1], NULL_RTX)"
7727 "operands[0] = widen_memory_access (operands[0], DImode, 0);")
7730 [(set (match_operand:SI 0 "memory_operand" "")
7732 (set (match_operand:SI 1 "memory_operand" "")
7735 && mems_ok_for_ldd_peep (operands[1], operands[0], NULL_RTX)"
7738 "operands[1] = widen_memory_access (operands[1], DImode, 0);")
7741 [(set (match_operand:SI 0 "register_operand" "")
7742 (match_operand:SI 1 "memory_operand" ""))
7743 (set (match_operand:SI 2 "register_operand" "")
7744 (match_operand:SI 3 "memory_operand" ""))]
7745 "registers_ok_for_ldd_peep (operands[0], operands[2])
7746 && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
7749 "operands[1] = widen_memory_access (operands[1], DImode, 0);
7750 operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));")
7753 [(set (match_operand:SI 0 "memory_operand" "")
7754 (match_operand:SI 1 "register_operand" ""))
7755 (set (match_operand:SI 2 "memory_operand" "")
7756 (match_operand:SI 3 "register_operand" ""))]
7757 "registers_ok_for_ldd_peep (operands[1], operands[3])
7758 && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
7761 "operands[0] = widen_memory_access (operands[0], DImode, 0);
7762 operands[1] = gen_rtx_REG (DImode, REGNO (operands[1]));")
7765 [(set (match_operand:SF 0 "register_operand" "")
7766 (match_operand:SF 1 "memory_operand" ""))
7767 (set (match_operand:SF 2 "register_operand" "")
7768 (match_operand:SF 3 "memory_operand" ""))]
7769 "registers_ok_for_ldd_peep (operands[0], operands[2])
7770 && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
7773 "operands[1] = widen_memory_access (operands[1], DFmode, 0);
7774 operands[0] = gen_rtx_REG (DFmode, REGNO (operands[0]));")
7777 [(set (match_operand:SF 0 "memory_operand" "")
7778 (match_operand:SF 1 "register_operand" ""))
7779 (set (match_operand:SF 2 "memory_operand" "")
7780 (match_operand:SF 3 "register_operand" ""))]
7781 "registers_ok_for_ldd_peep (operands[1], operands[3])
7782 && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
7785 "operands[0] = widen_memory_access (operands[0], DFmode, 0);
7786 operands[1] = gen_rtx_REG (DFmode, REGNO (operands[1]));")
7789 [(set (match_operand:SI 0 "register_operand" "")
7790 (match_operand:SI 1 "memory_operand" ""))
7791 (set (match_operand:SI 2 "register_operand" "")
7792 (match_operand:SI 3 "memory_operand" ""))]
7793 "registers_ok_for_ldd_peep (operands[2], operands[0])
7794 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
7797 "operands[3] = widen_memory_access (operands[3], DImode, 0);
7798 operands[2] = gen_rtx_REG (DImode, REGNO (operands[2]));")
7801 [(set (match_operand:SI 0 "memory_operand" "")
7802 (match_operand:SI 1 "register_operand" ""))
7803 (set (match_operand:SI 2 "memory_operand" "")
7804 (match_operand:SI 3 "register_operand" ""))]
7805 "registers_ok_for_ldd_peep (operands[3], operands[1])
7806 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
7809 "operands[2] = widen_memory_access (operands[2], DImode, 0);
7810 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
7814 [(set (match_operand:SF 0 "register_operand" "")
7815 (match_operand:SF 1 "memory_operand" ""))
7816 (set (match_operand:SF 2 "register_operand" "")
7817 (match_operand:SF 3 "memory_operand" ""))]
7818 "registers_ok_for_ldd_peep (operands[2], operands[0])
7819 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
7822 "operands[3] = widen_memory_access (operands[3], DFmode, 0);
7823 operands[2] = gen_rtx_REG (DFmode, REGNO (operands[2]));")
7826 [(set (match_operand:SF 0 "memory_operand" "")
7827 (match_operand:SF 1 "register_operand" ""))
7828 (set (match_operand:SF 2 "memory_operand" "")
7829 (match_operand:SF 3 "register_operand" ""))]
7830 "registers_ok_for_ldd_peep (operands[3], operands[1])
7831 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
7834 "operands[2] = widen_memory_access (operands[2], DFmode, 0);
7835 operands[3] = gen_rtx_REG (DFmode, REGNO (operands[3]));")
7837 ;; Optimize the case of following a reg-reg move with a test
7838 ;; of reg just moved. Don't allow floating point regs for operand 0 or 1.
7839 ;; This can result from a float to fix conversion.
7842 [(set (match_operand:SI 0 "register_operand" "")
7843 (match_operand:SI 1 "register_operand" ""))
7845 (compare:CC (match_operand:SI 2 "register_operand" "")
7847 "(rtx_equal_p (operands[2], operands[0])
7848 || rtx_equal_p (operands[2], operands[1]))
7849 && ! SPARC_FP_REG_P (REGNO (operands[0]))
7850 && ! SPARC_FP_REG_P (REGNO (operands[1]))"
7851 [(parallel [(set (match_dup 0) (match_dup 1))
7853 (compare:CC (match_dup 1) (const_int 0)))])]
7857 [(set (match_operand:DI 0 "register_operand" "")
7858 (match_operand:DI 1 "register_operand" ""))
7860 (compare:CCX (match_operand:DI 2 "register_operand" "")
7863 && (rtx_equal_p (operands[2], operands[0])
7864 || rtx_equal_p (operands[2], operands[1]))
7865 && ! SPARC_FP_REG_P (REGNO (operands[0]))
7866 && ! SPARC_FP_REG_P (REGNO (operands[1]))"
7867 [(parallel [(set (match_dup 0) (match_dup 1))
7869 (compare:CCX (match_dup 1) (const_int 0)))])]
7873 ;; Prefetch instructions.
7875 ;; ??? UltraSPARC-III note: A memory operation loading into the floating point register
7876 ;; ??? file, if it hits the prefetch cache, has a chance to dual-issue with other memory
7877 ;; ??? operations. With DFA we might be able to model this, but it requires a lot of
7879 (define_expand "prefetch"
7880 [(match_operand 0 "address_operand" "")
7881 (match_operand 1 "const_int_operand" "")
7882 (match_operand 2 "const_int_operand" "")]
7886 emit_insn (gen_prefetch_64 (operands[0], operands[1], operands[2]));
7888 emit_insn (gen_prefetch_32 (operands[0], operands[1], operands[2]));
7892 (define_insn "prefetch_64"
7893 [(prefetch (match_operand:DI 0 "address_operand" "p")
7894 (match_operand:DI 1 "const_int_operand" "n")
7895 (match_operand:DI 2 "const_int_operand" "n"))]
7898 static const char * const prefetch_instr[2][2] = {
7900 "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
7901 "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
7904 "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
7905 "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
7908 int read_or_write = INTVAL (operands[1]);
7909 int locality = INTVAL (operands[2]);
7911 gcc_assert (read_or_write == 0 || read_or_write == 1);
7912 gcc_assert (locality >= 0 && locality < 4);
7913 return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
7915 [(set_attr "type" "load")])
7917 (define_insn "prefetch_32"
7918 [(prefetch (match_operand:SI 0 "address_operand" "p")
7919 (match_operand:SI 1 "const_int_operand" "n")
7920 (match_operand:SI 2 "const_int_operand" "n"))]
7923 static const char * const prefetch_instr[2][2] = {
7925 "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
7926 "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
7929 "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
7930 "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
7933 int read_or_write = INTVAL (operands[1]);
7934 int locality = INTVAL (operands[2]);
7936 gcc_assert (read_or_write == 0 || read_or_write == 1);
7937 gcc_assert (locality >= 0 && locality < 4);
7938 return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
7940 [(set_attr "type" "load")])
7943 ;; Trap instructions.
7946 [(trap_if (const_int 1) (const_int 5))]
7949 [(set_attr "type" "trap")])
7951 (define_expand "conditional_trap"
7952 [(trap_if (match_operator 0 "noov_compare_operator" [(match_dup 2) (match_dup 3)])
7953 (match_operand:SI 1 "arith_operand" ""))]
7955 "operands[2] = gen_compare_reg (GET_CODE (operands[0]),
7956 sparc_compare_op0, sparc_compare_op1);
7957 if (GET_MODE (operands[2]) != CCmode && GET_MODE (operands[2]) != CCXmode)
7959 operands[3] = const0_rtx;")
7962 [(trap_if (match_operator 0 "noov_compare_operator" [(reg:CC 100) (const_int 0)])
7963 (match_operand:SI 1 "arith_operand" "rM"))]
7967 return "t%C0\t%%icc, %1";
7971 [(set_attr "type" "trap")])
7974 [(trap_if (match_operator 0 "noov_compare_operator" [(reg:CCX 100) (const_int 0)])
7975 (match_operand:SI 1 "arith_operand" "rM"))]
7978 [(set_attr "type" "trap")])
7981 ;; TLS support instructions.
7983 (define_insn "tgd_hi22"
7984 [(set (match_operand:SI 0 "register_operand" "=r")
7985 (high:SI (unspec:SI [(match_operand 1 "tgd_symbolic_operand" "")]
7988 "sethi\\t%%tgd_hi22(%a1), %0")
7990 (define_insn "tgd_lo10"
7991 [(set (match_operand:SI 0 "register_operand" "=r")
7992 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7993 (unspec:SI [(match_operand 2 "tgd_symbolic_operand" "")]
7996 "add\\t%1, %%tgd_lo10(%a2), %0")
7998 (define_insn "tgd_add32"
7999 [(set (match_operand:SI 0 "register_operand" "=r")
8000 (plus:SI (match_operand:SI 1 "register_operand" "r")
8001 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8002 (match_operand 3 "tgd_symbolic_operand" "")]
8004 "TARGET_TLS && TARGET_ARCH32"
8005 "add\\t%1, %2, %0, %%tgd_add(%a3)")
8007 (define_insn "tgd_add64"
8008 [(set (match_operand:DI 0 "register_operand" "=r")
8009 (plus:DI (match_operand:DI 1 "register_operand" "r")
8010 (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8011 (match_operand 3 "tgd_symbolic_operand" "")]
8013 "TARGET_TLS && TARGET_ARCH64"
8014 "add\\t%1, %2, %0, %%tgd_add(%a3)")
8016 (define_insn "tgd_call32"
8017 [(set (match_operand 0 "register_operand" "=r")
8018 (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")
8019 (match_operand 2 "tgd_symbolic_operand" "")]
8021 (match_operand 3 "" "")))
8022 (clobber (reg:SI 15))]
8023 "TARGET_TLS && TARGET_ARCH32"
8024 "call\t%a1, %%tgd_call(%a2)%#"
8025 [(set_attr "type" "call")])
8027 (define_insn "tgd_call64"
8028 [(set (match_operand 0 "register_operand" "=r")
8029 (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")
8030 (match_operand 2 "tgd_symbolic_operand" "")]
8032 (match_operand 3 "" "")))
8033 (clobber (reg:DI 15))]
8034 "TARGET_TLS && TARGET_ARCH64"
8035 "call\t%a1, %%tgd_call(%a2)%#"
8036 [(set_attr "type" "call")])
8038 (define_insn "tldm_hi22"
8039 [(set (match_operand:SI 0 "register_operand" "=r")
8040 (high:SI (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
8042 "sethi\\t%%tldm_hi22(%&), %0")
8044 (define_insn "tldm_lo10"
8045 [(set (match_operand:SI 0 "register_operand" "=r")
8046 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
8047 (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
8049 "add\\t%1, %%tldm_lo10(%&), %0")
8051 (define_insn "tldm_add32"
8052 [(set (match_operand:SI 0 "register_operand" "=r")
8053 (plus:SI (match_operand:SI 1 "register_operand" "r")
8054 (unspec:SI [(match_operand:SI 2 "register_operand" "r")]
8056 "TARGET_TLS && TARGET_ARCH32"
8057 "add\\t%1, %2, %0, %%tldm_add(%&)")
8059 (define_insn "tldm_add64"
8060 [(set (match_operand:DI 0 "register_operand" "=r")
8061 (plus:DI (match_operand:DI 1 "register_operand" "r")
8062 (unspec:DI [(match_operand:SI 2 "register_operand" "r")]
8064 "TARGET_TLS && TARGET_ARCH64"
8065 "add\\t%1, %2, %0, %%tldm_add(%&)")
8067 (define_insn "tldm_call32"
8068 [(set (match_operand 0 "register_operand" "=r")
8069 (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")]
8071 (match_operand 2 "" "")))
8072 (clobber (reg:SI 15))]
8073 "TARGET_TLS && TARGET_ARCH32"
8074 "call\t%a1, %%tldm_call(%&)%#"
8075 [(set_attr "type" "call")])
8077 (define_insn "tldm_call64"
8078 [(set (match_operand 0 "register_operand" "=r")
8079 (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")]
8081 (match_operand 2 "" "")))
8082 (clobber (reg:DI 15))]
8083 "TARGET_TLS && TARGET_ARCH64"
8084 "call\t%a1, %%tldm_call(%&)%#"
8085 [(set_attr "type" "call")])
8087 (define_insn "tldo_hix22"
8088 [(set (match_operand:SI 0 "register_operand" "=r")
8089 (high:SI (unspec:SI [(match_operand 1 "tld_symbolic_operand" "")]
8092 "sethi\\t%%tldo_hix22(%a1), %0")
8094 (define_insn "tldo_lox10"
8095 [(set (match_operand:SI 0 "register_operand" "=r")
8096 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
8097 (unspec:SI [(match_operand 2 "tld_symbolic_operand" "")]
8100 "xor\\t%1, %%tldo_lox10(%a2), %0")
8102 (define_insn "tldo_add32"
8103 [(set (match_operand:SI 0 "register_operand" "=r")
8104 (plus:SI (match_operand:SI 1 "register_operand" "r")
8105 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8106 (match_operand 3 "tld_symbolic_operand" "")]
8108 "TARGET_TLS && TARGET_ARCH32"
8109 "add\\t%1, %2, %0, %%tldo_add(%a3)")
8111 (define_insn "tldo_add64"
8112 [(set (match_operand:DI 0 "register_operand" "=r")
8113 (plus:DI (match_operand:DI 1 "register_operand" "r")
8114 (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8115 (match_operand 3 "tld_symbolic_operand" "")]
8117 "TARGET_TLS && TARGET_ARCH64"
8118 "add\\t%1, %2, %0, %%tldo_add(%a3)")
8120 (define_insn "tie_hi22"
8121 [(set (match_operand:SI 0 "register_operand" "=r")
8122 (high:SI (unspec:SI [(match_operand 1 "tie_symbolic_operand" "")]
8125 "sethi\\t%%tie_hi22(%a1), %0")
8127 (define_insn "tie_lo10"
8128 [(set (match_operand:SI 0 "register_operand" "=r")
8129 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
8130 (unspec:SI [(match_operand 2 "tie_symbolic_operand" "")]
8133 "add\\t%1, %%tie_lo10(%a2), %0")
8135 (define_insn "tie_ld32"
8136 [(set (match_operand:SI 0 "register_operand" "=r")
8137 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
8138 (match_operand:SI 2 "register_operand" "r")
8139 (match_operand 3 "tie_symbolic_operand" "")]
8141 "TARGET_TLS && TARGET_ARCH32"
8142 "ld\\t[%1 + %2], %0, %%tie_ld(%a3)"
8143 [(set_attr "type" "load")])
8145 (define_insn "tie_ld64"
8146 [(set (match_operand:DI 0 "register_operand" "=r")
8147 (unspec:DI [(match_operand:DI 1 "register_operand" "r")
8148 (match_operand:SI 2 "register_operand" "r")
8149 (match_operand 3 "tie_symbolic_operand" "")]
8151 "TARGET_TLS && TARGET_ARCH64"
8152 "ldx\\t[%1 + %2], %0, %%tie_ldx(%a3)"
8153 [(set_attr "type" "load")])
8155 (define_insn "tie_add32"
8156 [(set (match_operand:SI 0 "register_operand" "=r")
8157 (plus:SI (match_operand:SI 1 "register_operand" "r")
8158 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8159 (match_operand 3 "tie_symbolic_operand" "")]
8161 "TARGET_SUN_TLS && TARGET_ARCH32"
8162 "add\\t%1, %2, %0, %%tie_add(%a3)")
8164 (define_insn "tie_add64"
8165 [(set (match_operand:DI 0 "register_operand" "=r")
8166 (plus:DI (match_operand:DI 1 "register_operand" "r")
8167 (unspec:DI [(match_operand:DI 2 "register_operand" "r")
8168 (match_operand 3 "tie_symbolic_operand" "")]
8170 "TARGET_SUN_TLS && TARGET_ARCH64"
8171 "add\\t%1, %2, %0, %%tie_add(%a3)")
8173 (define_insn "tle_hix22_sp32"
8174 [(set (match_operand:SI 0 "register_operand" "=r")
8175 (high:SI (unspec:SI [(match_operand 1 "tle_symbolic_operand" "")]
8177 "TARGET_TLS && TARGET_ARCH32"
8178 "sethi\\t%%tle_hix22(%a1), %0")
8180 (define_insn "tle_lox10_sp32"
8181 [(set (match_operand:SI 0 "register_operand" "=r")
8182 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
8183 (unspec:SI [(match_operand 2 "tle_symbolic_operand" "")]
8185 "TARGET_TLS && TARGET_ARCH32"
8186 "xor\\t%1, %%tle_lox10(%a2), %0")
8188 (define_insn "tle_hix22_sp64"
8189 [(set (match_operand:DI 0 "register_operand" "=r")
8190 (high:DI (unspec:DI [(match_operand 1 "tle_symbolic_operand" "")]
8192 "TARGET_TLS && TARGET_ARCH64"
8193 "sethi\\t%%tle_hix22(%a1), %0")
8195 (define_insn "tle_lox10_sp64"
8196 [(set (match_operand:DI 0 "register_operand" "=r")
8197 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
8198 (unspec:DI [(match_operand 2 "tle_symbolic_operand" "")]
8200 "TARGET_TLS && TARGET_ARCH64"
8201 "xor\\t%1, %%tle_lox10(%a2), %0")
8203 ;; Now patterns combining tldo_add{32,64} with some integer loads or stores
8204 (define_insn "*tldo_ldub_sp32"
8205 [(set (match_operand:QI 0 "register_operand" "=r")
8206 (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8207 (match_operand 3 "tld_symbolic_operand" "")]
8209 (match_operand:SI 1 "register_operand" "r"))))]
8210 "TARGET_TLS && TARGET_ARCH32"
8211 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8212 [(set_attr "type" "load")
8213 (set_attr "us3load_type" "3cycle")])
8215 (define_insn "*tldo_ldub1_sp32"
8216 [(set (match_operand:HI 0 "register_operand" "=r")
8217 (zero_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8218 (match_operand 3 "tld_symbolic_operand" "")]
8220 (match_operand:SI 1 "register_operand" "r")))))]
8221 "TARGET_TLS && TARGET_ARCH32"
8222 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8223 [(set_attr "type" "load")
8224 (set_attr "us3load_type" "3cycle")])
8226 (define_insn "*tldo_ldub2_sp32"
8227 [(set (match_operand:SI 0 "register_operand" "=r")
8228 (zero_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8229 (match_operand 3 "tld_symbolic_operand" "")]
8231 (match_operand:SI 1 "register_operand" "r")))))]
8232 "TARGET_TLS && TARGET_ARCH32"
8233 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8234 [(set_attr "type" "load")
8235 (set_attr "us3load_type" "3cycle")])
8237 (define_insn "*tldo_ldsb1_sp32"
8238 [(set (match_operand:HI 0 "register_operand" "=r")
8239 (sign_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8240 (match_operand 3 "tld_symbolic_operand" "")]
8242 (match_operand:SI 1 "register_operand" "r")))))]
8243 "TARGET_TLS && TARGET_ARCH32"
8244 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
8245 [(set_attr "type" "sload")
8246 (set_attr "us3load_type" "3cycle")])
8248 (define_insn "*tldo_ldsb2_sp32"
8249 [(set (match_operand:SI 0 "register_operand" "=r")
8250 (sign_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8251 (match_operand 3 "tld_symbolic_operand" "")]
8253 (match_operand:SI 1 "register_operand" "r")))))]
8254 "TARGET_TLS && TARGET_ARCH32"
8255 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
8256 [(set_attr "type" "sload")
8257 (set_attr "us3load_type" "3cycle")])
8259 (define_insn "*tldo_ldub_sp64"
8260 [(set (match_operand:QI 0 "register_operand" "=r")
8261 (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8262 (match_operand 3 "tld_symbolic_operand" "")]
8264 (match_operand:DI 1 "register_operand" "r"))))]
8265 "TARGET_TLS && TARGET_ARCH64"
8266 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8267 [(set_attr "type" "load")
8268 (set_attr "us3load_type" "3cycle")])
8270 (define_insn "*tldo_ldub1_sp64"
8271 [(set (match_operand:HI 0 "register_operand" "=r")
8272 (zero_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8273 (match_operand 3 "tld_symbolic_operand" "")]
8275 (match_operand:DI 1 "register_operand" "r")))))]
8276 "TARGET_TLS && TARGET_ARCH64"
8277 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8278 [(set_attr "type" "load")
8279 (set_attr "us3load_type" "3cycle")])
8281 (define_insn "*tldo_ldub2_sp64"
8282 [(set (match_operand:SI 0 "register_operand" "=r")
8283 (zero_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8284 (match_operand 3 "tld_symbolic_operand" "")]
8286 (match_operand:DI 1 "register_operand" "r")))))]
8287 "TARGET_TLS && TARGET_ARCH64"
8288 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8289 [(set_attr "type" "load")
8290 (set_attr "us3load_type" "3cycle")])
8292 (define_insn "*tldo_ldub3_sp64"
8293 [(set (match_operand:DI 0 "register_operand" "=r")
8294 (zero_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8295 (match_operand 3 "tld_symbolic_operand" "")]
8297 (match_operand:DI 1 "register_operand" "r")))))]
8298 "TARGET_TLS && TARGET_ARCH64"
8299 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8300 [(set_attr "type" "load")
8301 (set_attr "us3load_type" "3cycle")])
8303 (define_insn "*tldo_ldsb1_sp64"
8304 [(set (match_operand:HI 0 "register_operand" "=r")
8305 (sign_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8306 (match_operand 3 "tld_symbolic_operand" "")]
8308 (match_operand:DI 1 "register_operand" "r")))))]
8309 "TARGET_TLS && TARGET_ARCH64"
8310 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
8311 [(set_attr "type" "sload")
8312 (set_attr "us3load_type" "3cycle")])
8314 (define_insn "*tldo_ldsb2_sp64"
8315 [(set (match_operand:SI 0 "register_operand" "=r")
8316 (sign_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8317 (match_operand 3 "tld_symbolic_operand" "")]
8319 (match_operand:DI 1 "register_operand" "r")))))]
8320 "TARGET_TLS && TARGET_ARCH64"
8321 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
8322 [(set_attr "type" "sload")
8323 (set_attr "us3load_type" "3cycle")])
8325 (define_insn "*tldo_ldsb3_sp64"
8326 [(set (match_operand:DI 0 "register_operand" "=r")
8327 (sign_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8328 (match_operand 3 "tld_symbolic_operand" "")]
8330 (match_operand:DI 1 "register_operand" "r")))))]
8331 "TARGET_TLS && TARGET_ARCH64"
8332 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
8333 [(set_attr "type" "sload")
8334 (set_attr "us3load_type" "3cycle")])
8336 (define_insn "*tldo_lduh_sp32"
8337 [(set (match_operand:HI 0 "register_operand" "=r")
8338 (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8339 (match_operand 3 "tld_symbolic_operand" "")]
8341 (match_operand:SI 1 "register_operand" "r"))))]
8342 "TARGET_TLS && TARGET_ARCH32"
8343 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
8344 [(set_attr "type" "load")
8345 (set_attr "us3load_type" "3cycle")])
8347 (define_insn "*tldo_lduh1_sp32"
8348 [(set (match_operand:SI 0 "register_operand" "=r")
8349 (zero_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8350 (match_operand 3 "tld_symbolic_operand" "")]
8352 (match_operand:SI 1 "register_operand" "r")))))]
8353 "TARGET_TLS && TARGET_ARCH32"
8354 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
8355 [(set_attr "type" "load")
8356 (set_attr "us3load_type" "3cycle")])
8358 (define_insn "*tldo_ldsh1_sp32"
8359 [(set (match_operand:SI 0 "register_operand" "=r")
8360 (sign_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8361 (match_operand 3 "tld_symbolic_operand" "")]
8363 (match_operand:SI 1 "register_operand" "r")))))]
8364 "TARGET_TLS && TARGET_ARCH32"
8365 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
8366 [(set_attr "type" "sload")
8367 (set_attr "us3load_type" "3cycle")])
8369 (define_insn "*tldo_lduh_sp64"
8370 [(set (match_operand:HI 0 "register_operand" "=r")
8371 (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8372 (match_operand 3 "tld_symbolic_operand" "")]
8374 (match_operand:DI 1 "register_operand" "r"))))]
8375 "TARGET_TLS && TARGET_ARCH64"
8376 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
8377 [(set_attr "type" "load")
8378 (set_attr "us3load_type" "3cycle")])
8380 (define_insn "*tldo_lduh1_sp64"
8381 [(set (match_operand:SI 0 "register_operand" "=r")
8382 (zero_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8383 (match_operand 3 "tld_symbolic_operand" "")]
8385 (match_operand:DI 1 "register_operand" "r")))))]
8386 "TARGET_TLS && TARGET_ARCH64"
8387 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
8388 [(set_attr "type" "load")
8389 (set_attr "us3load_type" "3cycle")])
8391 (define_insn "*tldo_lduh2_sp64"
8392 [(set (match_operand:DI 0 "register_operand" "=r")
8393 (zero_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8394 (match_operand 3 "tld_symbolic_operand" "")]
8396 (match_operand:DI 1 "register_operand" "r")))))]
8397 "TARGET_TLS && TARGET_ARCH64"
8398 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
8399 [(set_attr "type" "load")
8400 (set_attr "us3load_type" "3cycle")])
8402 (define_insn "*tldo_ldsh1_sp64"
8403 [(set (match_operand:SI 0 "register_operand" "=r")
8404 (sign_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8405 (match_operand 3 "tld_symbolic_operand" "")]
8407 (match_operand:DI 1 "register_operand" "r")))))]
8408 "TARGET_TLS && TARGET_ARCH64"
8409 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
8410 [(set_attr "type" "sload")
8411 (set_attr "us3load_type" "3cycle")])
8413 (define_insn "*tldo_ldsh2_sp64"
8414 [(set (match_operand:DI 0 "register_operand" "=r")
8415 (sign_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8416 (match_operand 3 "tld_symbolic_operand" "")]
8418 (match_operand:DI 1 "register_operand" "r")))))]
8419 "TARGET_TLS && TARGET_ARCH64"
8420 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
8421 [(set_attr "type" "sload")
8422 (set_attr "us3load_type" "3cycle")])
8424 (define_insn "*tldo_lduw_sp32"
8425 [(set (match_operand:SI 0 "register_operand" "=r")
8426 (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8427 (match_operand 3 "tld_symbolic_operand" "")]
8429 (match_operand:SI 1 "register_operand" "r"))))]
8430 "TARGET_TLS && TARGET_ARCH32"
8431 "ld\t[%1 + %2], %0, %%tldo_add(%3)"
8432 [(set_attr "type" "load")])
8434 (define_insn "*tldo_lduw_sp64"
8435 [(set (match_operand:SI 0 "register_operand" "=r")
8436 (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8437 (match_operand 3 "tld_symbolic_operand" "")]
8439 (match_operand:DI 1 "register_operand" "r"))))]
8440 "TARGET_TLS && TARGET_ARCH64"
8441 "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
8442 [(set_attr "type" "load")])
8444 (define_insn "*tldo_lduw1_sp64"
8445 [(set (match_operand:DI 0 "register_operand" "=r")
8446 (zero_extend:DI (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8447 (match_operand 3 "tld_symbolic_operand" "")]
8449 (match_operand:DI 1 "register_operand" "r")))))]
8450 "TARGET_TLS && TARGET_ARCH64"
8451 "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
8452 [(set_attr "type" "load")])
8454 (define_insn "*tldo_ldsw1_sp64"
8455 [(set (match_operand:DI 0 "register_operand" "=r")
8456 (sign_extend:DI (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8457 (match_operand 3 "tld_symbolic_operand" "")]
8459 (match_operand:DI 1 "register_operand" "r")))))]
8460 "TARGET_TLS && TARGET_ARCH64"
8461 "ldsw\t[%1 + %2], %0, %%tldo_add(%3)"
8462 [(set_attr "type" "sload")
8463 (set_attr "us3load_type" "3cycle")])
8465 (define_insn "*tldo_ldx_sp64"
8466 [(set (match_operand:DI 0 "register_operand" "=r")
8467 (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8468 (match_operand 3 "tld_symbolic_operand" "")]
8470 (match_operand:DI 1 "register_operand" "r"))))]
8471 "TARGET_TLS && TARGET_ARCH64"
8472 "ldx\t[%1 + %2], %0, %%tldo_add(%3)"
8473 [(set_attr "type" "load")])
8475 (define_insn "*tldo_stb_sp32"
8476 [(set (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8477 (match_operand 3 "tld_symbolic_operand" "")]
8479 (match_operand:SI 1 "register_operand" "r")))
8480 (match_operand:QI 0 "register_operand" "=r"))]
8481 "TARGET_TLS && TARGET_ARCH32"
8482 "stb\t%0, [%1 + %2], %%tldo_add(%3)"
8483 [(set_attr "type" "store")])
8485 (define_insn "*tldo_stb_sp64"
8486 [(set (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8487 (match_operand 3 "tld_symbolic_operand" "")]
8489 (match_operand:DI 1 "register_operand" "r")))
8490 (match_operand:QI 0 "register_operand" "=r"))]
8491 "TARGET_TLS && TARGET_ARCH64"
8492 "stb\t%0, [%1 + %2], %%tldo_add(%3)"
8493 [(set_attr "type" "store")])
8495 (define_insn "*tldo_sth_sp32"
8496 [(set (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8497 (match_operand 3 "tld_symbolic_operand" "")]
8499 (match_operand:SI 1 "register_operand" "r")))
8500 (match_operand:HI 0 "register_operand" "=r"))]
8501 "TARGET_TLS && TARGET_ARCH32"
8502 "sth\t%0, [%1 + %2], %%tldo_add(%3)"
8503 [(set_attr "type" "store")])
8505 (define_insn "*tldo_sth_sp64"
8506 [(set (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8507 (match_operand 3 "tld_symbolic_operand" "")]
8509 (match_operand:DI 1 "register_operand" "r")))
8510 (match_operand:HI 0 "register_operand" "=r"))]
8511 "TARGET_TLS && TARGET_ARCH64"
8512 "sth\t%0, [%1 + %2], %%tldo_add(%3)"
8513 [(set_attr "type" "store")])
8515 (define_insn "*tldo_stw_sp32"
8516 [(set (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8517 (match_operand 3 "tld_symbolic_operand" "")]
8519 (match_operand:SI 1 "register_operand" "r")))
8520 (match_operand:SI 0 "register_operand" "=r"))]
8521 "TARGET_TLS && TARGET_ARCH32"
8522 "st\t%0, [%1 + %2], %%tldo_add(%3)"
8523 [(set_attr "type" "store")])
8525 (define_insn "*tldo_stw_sp64"
8526 [(set (mem:SI (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 (match_operand:SI 0 "register_operand" "=r"))]
8531 "TARGET_TLS && TARGET_ARCH64"
8532 "stw\t%0, [%1 + %2], %%tldo_add(%3)"
8533 [(set_attr "type" "store")])
8535 (define_insn "*tldo_stx_sp64"
8536 [(set (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8537 (match_operand 3 "tld_symbolic_operand" "")]
8539 (match_operand:DI 1 "register_operand" "r")))
8540 (match_operand:DI 0 "register_operand" "=r"))]
8541 "TARGET_TLS && TARGET_ARCH64"
8542 "stx\t%0, [%1 + %2], %%tldo_add(%3)"
8543 [(set_attr "type" "store")])
8546 ;; Vector instructions.
8548 (define_insn "addv2si3"
8549 [(set (match_operand:V2SI 0 "register_operand" "=e")
8550 (plus:V2SI (match_operand:V2SI 1 "register_operand" "e")
8551 (match_operand:V2SI 2 "register_operand" "e")))]
8553 "fpadd32\t%1, %2, %0"
8554 [(set_attr "type" "fga")
8555 (set_attr "fptype" "double")])
8557 (define_insn "addv4hi3"
8558 [(set (match_operand:V4HI 0 "register_operand" "=e")
8559 (plus:V4HI (match_operand:V4HI 1 "register_operand" "e")
8560 (match_operand:V4HI 2 "register_operand" "e")))]
8562 "fpadd16\t%1, %2, %0"
8563 [(set_attr "type" "fga")
8564 (set_attr "fptype" "double")])
8566 ;; fpadd32s is emitted by the addsi3 pattern.
8568 (define_insn "addv2hi3"
8569 [(set (match_operand:V2HI 0 "register_operand" "=f")
8570 (plus:V2HI (match_operand:V2HI 1 "register_operand" "f")
8571 (match_operand:V2HI 2 "register_operand" "f")))]
8573 "fpadd16s\t%1, %2, %0"
8574 [(set_attr "type" "fga")
8575 (set_attr "fptype" "single")])
8577 (define_insn "subv2si3"
8578 [(set (match_operand:V2SI 0 "register_operand" "=e")
8579 (minus:V2SI (match_operand:V2SI 1 "register_operand" "e")
8580 (match_operand:V2SI 2 "register_operand" "e")))]
8582 "fpsub32\t%1, %2, %0"
8583 [(set_attr "type" "fga")
8584 (set_attr "fptype" "double")])
8586 (define_insn "subv4hi3"
8587 [(set (match_operand:V4HI 0 "register_operand" "=e")
8588 (minus:V4HI (match_operand:V4HI 1 "register_operand" "e")
8589 (match_operand:V4HI 2 "register_operand" "e")))]
8591 "fpsub16\t%1, %2, %0"
8592 [(set_attr "type" "fga")
8593 (set_attr "fptype" "double")])
8595 ;; fpsub32s is emitted by the subsi3 pattern.
8597 (define_insn "subv2hi3"
8598 [(set (match_operand:V2HI 0 "register_operand" "=f")
8599 (minus:V2HI (match_operand:V2HI 1 "register_operand" "f")
8600 (match_operand:V2HI 2 "register_operand" "f")))]
8602 "fpsub16s\t%1, %2, %0"
8603 [(set_attr "type" "fga")
8604 (set_attr "fptype" "single")])
8606 ;; All other logical instructions have integer equivalents so they
8607 ;; are defined together.
8609 ;; (ior (not (op1)) (not (op2))) is the canonical form of NAND.
8611 (define_insn "*nand<V64mode>_vis"
8612 [(set (match_operand:V64 0 "register_operand" "=e")
8613 (ior:V64 (not:V64 (match_operand:V64 1 "register_operand" "e"))
8614 (not:V64 (match_operand:V64 2 "register_operand" "e"))))]
8617 [(set_attr "type" "fga")
8618 (set_attr "fptype" "double")])
8620 (define_insn "*nand<V32mode>_vis"
8621 [(set (match_operand:V32 0 "register_operand" "=f")
8622 (ior:V32 (not:V32 (match_operand:V32 1 "register_operand" "f"))
8623 (not:V32 (match_operand:V32 2 "register_operand" "f"))))]
8625 "fnands\t%1, %2, %0"
8626 [(set_attr "type" "fga")
8627 (set_attr "fptype" "single")])
8629 ;; Hard to generate VIS instructions. We have builtins for these.
8631 (define_insn "fpack16_vis"
8632 [(set (match_operand:V4QI 0 "register_operand" "=f")
8633 (unspec:V4QI [(match_operand:V4HI 1 "register_operand" "e")]
8637 [(set_attr "type" "fga")
8638 (set_attr "fptype" "double")])
8640 (define_insn "fpackfix_vis"
8641 [(set (match_operand:V2HI 0 "register_operand" "=f")
8642 (unspec:V2HI [(match_operand:V2SI 1 "register_operand" "e")]
8646 [(set_attr "type" "fga")
8647 (set_attr "fptype" "double")])
8649 (define_insn "fpack32_vis"
8650 [(set (match_operand:V8QI 0 "register_operand" "=e")
8651 (unspec:V8QI [(match_operand:V2SI 1 "register_operand" "e")
8652 (match_operand:V8QI 2 "register_operand" "e")]
8655 "fpack32\t%1, %2, %0"
8656 [(set_attr "type" "fga")
8657 (set_attr "fptype" "double")])
8659 (define_insn "fexpand_vis"
8660 [(set (match_operand:V4HI 0 "register_operand" "=e")
8661 (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")]
8665 [(set_attr "type" "fga")
8666 (set_attr "fptype" "double")])
8668 ;; It may be possible to describe this operation as (1 indexed):
8669 ;; (vec_select (vec_duplicate (vec_duplicate (vec_concat 1 2)))
8670 ;; 1,5,10,14,19,23,28,32)
8671 ;; Note that (vec_merge:V8QI [(V4QI) (V4QI)] (10101010 = 170) doesn't work
8672 ;; because vec_merge expects all the operands to be of the same type.
8673 (define_insn "fpmerge_vis"
8674 [(set (match_operand:V8QI 0 "register_operand" "=e")
8675 (unspec:V8QI [(match_operand:V4QI 1 "register_operand" "f")
8676 (match_operand:V4QI 2 "register_operand" "f")]
8679 "fpmerge\t%1, %2, %0"
8680 [(set_attr "type" "fga")
8681 (set_attr "fptype" "double")])
8683 ;; Partitioned multiply instructions
8684 (define_insn "fmul8x16_vis"
8685 [(set (match_operand:V4HI 0 "register_operand" "=e")
8686 (mult:V4HI (match_operand:V4QI 1 "register_operand" "f")
8687 (match_operand:V4HI 2 "register_operand" "e")))]
8689 "fmul8x16\t%1, %2, %0"
8690 [(set_attr "type" "fpmul")
8691 (set_attr "fptype" "double")])
8693 ;; Only one of the following two insns can be a multiply.
8694 (define_insn "fmul8x16au_vis"
8695 [(set (match_operand:V4HI 0 "register_operand" "=e")
8696 (mult:V4HI (match_operand:V4QI 1 "register_operand" "f")
8697 (match_operand:V2HI 2 "register_operand" "f")))]
8699 "fmul8x16au\t%1, %2, %0"
8700 [(set_attr "type" "fpmul")
8701 (set_attr "fptype" "double")])
8703 (define_insn "fmul8x16al_vis"
8704 [(set (match_operand:V4HI 0 "register_operand" "=e")
8705 (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")
8706 (match_operand:V2HI 2 "register_operand" "f")]
8709 "fmul8x16al\t%1, %2, %0"
8710 [(set_attr "type" "fpmul")
8711 (set_attr "fptype" "double")])
8713 ;; Only one of the following two insns can be a multiply.
8714 (define_insn "fmul8sux16_vis"
8715 [(set (match_operand:V4HI 0 "register_operand" "=e")
8716 (mult:V4HI (match_operand:V8QI 1 "register_operand" "e")
8717 (match_operand:V4HI 2 "register_operand" "e")))]
8719 "fmul8sux16\t%1, %2, %0"
8720 [(set_attr "type" "fpmul")
8721 (set_attr "fptype" "double")])
8723 (define_insn "fmul8ulx16_vis"
8724 [(set (match_operand:V4HI 0 "register_operand" "=e")
8725 (unspec:V4HI [(match_operand:V8QI 1 "register_operand" "e")
8726 (match_operand:V4HI 2 "register_operand" "e")]
8729 "fmul8ulx16\t%1, %2, %0"
8730 [(set_attr "type" "fpmul")
8731 (set_attr "fptype" "double")])
8733 ;; Only one of the following two insns can be a multiply.
8734 (define_insn "fmuld8sux16_vis"
8735 [(set (match_operand:V2SI 0 "register_operand" "=e")
8736 (mult:V2SI (match_operand:V4QI 1 "register_operand" "f")
8737 (match_operand:V2HI 2 "register_operand" "f")))]
8739 "fmuld8sux16\t%1, %2, %0"
8740 [(set_attr "type" "fpmul")
8741 (set_attr "fptype" "double")])
8743 (define_insn "fmuld8ulx16_vis"
8744 [(set (match_operand:V2SI 0 "register_operand" "=e")
8745 (unspec:V2SI [(match_operand:V4QI 1 "register_operand" "f")
8746 (match_operand:V2HI 2 "register_operand" "f")]
8749 "fmuld8ulx16\t%1, %2, %0"
8750 [(set_attr "type" "fpmul")
8751 (set_attr "fptype" "double")])
8753 ;; Using faligndata only makes sense after an alignaddr since the choice of
8754 ;; bytes to take out of each operand is dependant on the results of the last
8756 (define_insn "faligndata<V64I:mode>_vis"
8757 [(set (match_operand:V64I 0 "register_operand" "=e")
8758 (unspec:V64I [(match_operand:V64I 1 "register_operand" "e")
8759 (match_operand:V64I 2 "register_operand" "e")]
8762 "faligndata\t%1, %2, %0"
8763 [(set_attr "type" "fga")
8764 (set_attr "fptype" "double")])
8766 (define_insn "alignaddr<P:mode>_vis"
8767 [(set (match_operand:P 0 "register_operand" "=r")
8768 (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
8769 (match_operand:P 2 "register_or_zero_operand" "rJ")]
8772 "alignaddr\t%r1, %r2, %0")
8774 (define_insn "pdist_vis"
8775 [(set (match_operand:DI 0 "register_operand" "=e")
8776 (unspec:DI [(match_operand:V8QI 1 "register_operand" "e")
8777 (match_operand:V8QI 2 "register_operand" "e")
8778 (match_operand:DI 3 "register_operand" "0")]
8782 [(set_attr "type" "fga")
8783 (set_attr "fptype" "double")])