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 (define_mode_macro P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
73 ;; The upper 32 fp regs on the v9 can't hold SFmode values. To deal with this
74 ;; a second register class, EXTRA_FP_REGS, exists for the v9 chip. The name
75 ;; is a bit of a misnomer as it covers all 64 fp regs. The corresponding
76 ;; constraint letter is 'e'. To avoid any confusion, 'e' is used instead of
77 ;; 'f' for all DF/TFmode values, including those that are specific to the v8.
79 ;; Attribute for cpu type.
80 ;; These must match the values for enum processor_type in sparc.h.
87 hypersparc,sparclite86x,
92 (const (symbol_ref "sparc_cpu_attr")))
94 ;; Attribute for the instruction set.
95 ;; At present we only need to distinguish v9/!v9, but for clarity we
96 ;; test TARGET_V8 too.
97 (define_attr "isa" "v7,v8,v9,sparclet"
99 (cond [(symbol_ref "TARGET_V9") (const_string "v9")
100 (symbol_ref "TARGET_V8") (const_string "v8")
101 (symbol_ref "TARGET_SPARCLET") (const_string "sparclet")]
102 (const_string "v7"))))
108 uncond_branch,branch,call,sibcall,call_no_delay_slot,return,
116 fga,fgm_pack,fgm_mul,fgm_pdist,fgm_cmp,
119 multi,savew,flushw,iflush,trap"
120 (const_string "ialu"))
122 ;; True if branch/call has empty delay slot and will emit a nop in it
123 (define_attr "empty_delay_slot" "false,true"
124 (symbol_ref "empty_delay_slot (insn)"))
126 (define_attr "branch_type" "none,icc,fcc,reg"
127 (const_string "none"))
129 (define_attr "pic" "false,true"
130 (symbol_ref "flag_pic != 0"))
132 (define_attr "calls_alloca" "false,true"
133 (symbol_ref "current_function_calls_alloca != 0"))
135 (define_attr "calls_eh_return" "false,true"
136 (symbol_ref "current_function_calls_eh_return !=0 "))
138 (define_attr "leaf_function" "false,true"
139 (symbol_ref "current_function_uses_only_leaf_regs != 0"))
141 (define_attr "delayed_branch" "false,true"
142 (symbol_ref "flag_delayed_branch != 0"))
144 ;; Length (in # of insns).
145 ;; Beware that setting a length greater or equal to 3 for conditional branches
146 ;; has a side-effect (see output_cbranch and output_v9branch).
147 (define_attr "length" ""
148 (cond [(eq_attr "type" "uncond_branch,call")
149 (if_then_else (eq_attr "empty_delay_slot" "true")
152 (eq_attr "type" "sibcall")
153 (if_then_else (eq_attr "leaf_function" "true")
154 (if_then_else (eq_attr "empty_delay_slot" "true")
157 (if_then_else (eq_attr "empty_delay_slot" "true")
160 (eq_attr "branch_type" "icc")
161 (if_then_else (match_operand 0 "noov_compare64_op" "")
162 (if_then_else (lt (pc) (match_dup 1))
163 (if_then_else (lt (minus (match_dup 1) (pc)) (const_int 260000))
164 (if_then_else (eq_attr "empty_delay_slot" "true")
167 (if_then_else (eq_attr "empty_delay_slot" "true")
170 (if_then_else (lt (minus (pc) (match_dup 1)) (const_int 260000))
171 (if_then_else (eq_attr "empty_delay_slot" "true")
174 (if_then_else (eq_attr "empty_delay_slot" "true")
177 (if_then_else (eq_attr "empty_delay_slot" "true")
180 (eq_attr "branch_type" "fcc")
181 (if_then_else (match_operand 0 "fcc0_reg_operand" "")
182 (if_then_else (eq_attr "empty_delay_slot" "true")
183 (if_then_else (eq (symbol_ref "TARGET_V9") (const_int 0))
186 (if_then_else (eq (symbol_ref "TARGET_V9") (const_int 0))
189 (if_then_else (lt (pc) (match_dup 2))
190 (if_then_else (lt (minus (match_dup 2) (pc)) (const_int 260000))
191 (if_then_else (eq_attr "empty_delay_slot" "true")
194 (if_then_else (eq_attr "empty_delay_slot" "true")
197 (if_then_else (lt (minus (pc) (match_dup 2)) (const_int 260000))
198 (if_then_else (eq_attr "empty_delay_slot" "true")
201 (if_then_else (eq_attr "empty_delay_slot" "true")
204 (eq_attr "branch_type" "reg")
205 (if_then_else (lt (pc) (match_dup 2))
206 (if_then_else (lt (minus (match_dup 2) (pc)) (const_int 32000))
207 (if_then_else (eq_attr "empty_delay_slot" "true")
210 (if_then_else (eq_attr "empty_delay_slot" "true")
213 (if_then_else (lt (minus (pc) (match_dup 2)) (const_int 32000))
214 (if_then_else (eq_attr "empty_delay_slot" "true")
217 (if_then_else (eq_attr "empty_delay_slot" "true")
223 (define_attr "fptype" "single,double"
224 (const_string "single"))
226 ;; UltraSPARC-III integer load type.
227 (define_attr "us3load_type" "2cycle,3cycle"
228 (const_string "2cycle"))
230 (define_asm_attributes
231 [(set_attr "length" "2")
232 (set_attr "type" "multi")])
234 ;; Attributes for instruction and branch scheduling
235 (define_attr "tls_call_delay" "false,true"
236 (symbol_ref "tls_call_delay (insn)"))
238 (define_attr "in_call_delay" "false,true"
239 (cond [(eq_attr "type" "uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
240 (const_string "false")
241 (eq_attr "type" "load,fpload,store,fpstore")
242 (if_then_else (eq_attr "length" "1")
243 (const_string "true")
244 (const_string "false"))]
245 (if_then_else (and (eq_attr "length" "1")
246 (eq_attr "tls_call_delay" "true"))
247 (const_string "true")
248 (const_string "false"))))
250 (define_attr "eligible_for_sibcall_delay" "false,true"
251 (symbol_ref "eligible_for_sibcall_delay (insn)"))
253 (define_attr "eligible_for_return_delay" "false,true"
254 (symbol_ref "eligible_for_return_delay (insn)"))
256 ;; ??? !v9: Should implement the notion of predelay slots for floating-point
257 ;; branches. This would allow us to remove the nop always inserted before
258 ;; a floating point branch.
260 ;; ??? It is OK for fill_simple_delay_slots to put load/store instructions
261 ;; in a delay slot, but it is not OK for fill_eager_delay_slots to do so.
262 ;; This is because doing so will add several pipeline stalls to the path
263 ;; that the load/store did not come from. Unfortunately, there is no way
264 ;; to prevent fill_eager_delay_slots from using load/store without completely
265 ;; disabling them. For the SPEC benchmark set, this is a serious lose,
266 ;; because it prevents us from moving back the final store of inner loops.
268 (define_attr "in_branch_delay" "false,true"
269 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
270 (eq_attr "length" "1"))
271 (const_string "true")
272 (const_string "false")))
274 (define_attr "in_uncond_branch_delay" "false,true"
275 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
276 (eq_attr "length" "1"))
277 (const_string "true")
278 (const_string "false")))
280 (define_attr "in_annul_branch_delay" "false,true"
281 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
282 (eq_attr "length" "1"))
283 (const_string "true")
284 (const_string "false")))
286 (define_delay (eq_attr "type" "call")
287 [(eq_attr "in_call_delay" "true") (nil) (nil)])
289 (define_delay (eq_attr "type" "sibcall")
290 [(eq_attr "eligible_for_sibcall_delay" "true") (nil) (nil)])
292 (define_delay (eq_attr "type" "branch")
293 [(eq_attr "in_branch_delay" "true")
294 (nil) (eq_attr "in_annul_branch_delay" "true")])
296 (define_delay (eq_attr "type" "uncond_branch")
297 [(eq_attr "in_uncond_branch_delay" "true")
300 (define_delay (eq_attr "type" "return")
301 [(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 ;; Compare instructions.
314 ;; This controls RTL generation and register allocation.
316 ;; We generate RTL for comparisons and branches by having the cmpxx
317 ;; patterns store away the operands. Then, the scc and bcc patterns
318 ;; emit RTL for both the compare and the branch.
320 ;; We do this because we want to generate different code for an sne and
321 ;; seq insn. In those cases, if the second operand of the compare is not
322 ;; const0_rtx, we want to compute the xor of the two operands and test
325 ;; We start with the DEFINE_EXPANDs, then the DEFINE_INSNs to match
326 ;; the patterns. Finally, we have the DEFINE_SPLITs for some of the scc
327 ;; insns that actually require more than one machine instruction.
329 ;; Put cmpsi first among compare insns so it matches two CONST_INT operands.
331 (define_expand "cmpsi"
333 (compare:CC (match_operand:SI 0 "compare_operand" "")
334 (match_operand:SI 1 "arith_operand" "")))]
337 if (GET_CODE (operands[0]) == ZERO_EXTRACT && operands[1] != const0_rtx)
338 operands[0] = force_reg (SImode, operands[0]);
340 sparc_compare_op0 = operands[0];
341 sparc_compare_op1 = operands[1];
345 (define_expand "cmpdi"
347 (compare:CCX (match_operand:DI 0 "compare_operand" "")
348 (match_operand:DI 1 "arith_double_operand" "")))]
351 if (GET_CODE (operands[0]) == ZERO_EXTRACT && operands[1] != const0_rtx)
352 operands[0] = force_reg (DImode, operands[0]);
354 sparc_compare_op0 = operands[0];
355 sparc_compare_op1 = operands[1];
359 (define_expand "cmpsf"
360 ;; The 96 here isn't ever used by anyone.
362 (compare:CCFP (match_operand:SF 0 "register_operand" "")
363 (match_operand:SF 1 "register_operand" "")))]
366 sparc_compare_op0 = operands[0];
367 sparc_compare_op1 = operands[1];
371 (define_expand "cmpdf"
372 ;; The 96 here isn't ever used by anyone.
374 (compare:CCFP (match_operand:DF 0 "register_operand" "")
375 (match_operand:DF 1 "register_operand" "")))]
378 sparc_compare_op0 = operands[0];
379 sparc_compare_op1 = operands[1];
383 (define_expand "cmptf"
384 ;; The 96 here isn't ever used by anyone.
386 (compare:CCFP (match_operand:TF 0 "register_operand" "")
387 (match_operand:TF 1 "register_operand" "")))]
390 sparc_compare_op0 = operands[0];
391 sparc_compare_op1 = operands[1];
395 ;; Now the compare DEFINE_INSNs.
397 (define_insn "*cmpsi_insn"
399 (compare:CC (match_operand:SI 0 "register_operand" "r")
400 (match_operand:SI 1 "arith_operand" "rI")))]
403 [(set_attr "type" "compare")])
405 (define_insn "*cmpdi_sp64"
407 (compare:CCX (match_operand:DI 0 "register_operand" "r")
408 (match_operand:DI 1 "arith_double_operand" "rHI")))]
411 [(set_attr "type" "compare")])
413 (define_insn "*cmpsf_fpe"
414 [(set (match_operand:CCFPE 0 "fcc_reg_operand" "=c")
415 (compare:CCFPE (match_operand:SF 1 "register_operand" "f")
416 (match_operand:SF 2 "register_operand" "f")))]
420 return "fcmpes\t%0, %1, %2";
421 return "fcmpes\t%1, %2";
423 [(set_attr "type" "fpcmp")])
425 (define_insn "*cmpdf_fpe"
426 [(set (match_operand:CCFPE 0 "fcc_reg_operand" "=c")
427 (compare:CCFPE (match_operand:DF 1 "register_operand" "e")
428 (match_operand:DF 2 "register_operand" "e")))]
432 return "fcmped\t%0, %1, %2";
433 return "fcmped\t%1, %2";
435 [(set_attr "type" "fpcmp")
436 (set_attr "fptype" "double")])
438 (define_insn "*cmptf_fpe"
439 [(set (match_operand:CCFPE 0 "fcc_reg_operand" "=c")
440 (compare:CCFPE (match_operand:TF 1 "register_operand" "e")
441 (match_operand:TF 2 "register_operand" "e")))]
442 "TARGET_FPU && TARGET_HARD_QUAD"
445 return "fcmpeq\t%0, %1, %2";
446 return "fcmpeq\t%1, %2";
448 [(set_attr "type" "fpcmp")])
450 (define_insn "*cmpsf_fp"
451 [(set (match_operand:CCFP 0 "fcc_reg_operand" "=c")
452 (compare:CCFP (match_operand:SF 1 "register_operand" "f")
453 (match_operand:SF 2 "register_operand" "f")))]
457 return "fcmps\t%0, %1, %2";
458 return "fcmps\t%1, %2";
460 [(set_attr "type" "fpcmp")])
462 (define_insn "*cmpdf_fp"
463 [(set (match_operand:CCFP 0 "fcc_reg_operand" "=c")
464 (compare:CCFP (match_operand:DF 1 "register_operand" "e")
465 (match_operand:DF 2 "register_operand" "e")))]
469 return "fcmpd\t%0, %1, %2";
470 return "fcmpd\t%1, %2";
472 [(set_attr "type" "fpcmp")
473 (set_attr "fptype" "double")])
475 (define_insn "*cmptf_fp"
476 [(set (match_operand:CCFP 0 "fcc_reg_operand" "=c")
477 (compare:CCFP (match_operand:TF 1 "register_operand" "e")
478 (match_operand:TF 2 "register_operand" "e")))]
479 "TARGET_FPU && TARGET_HARD_QUAD"
482 return "fcmpq\t%0, %1, %2";
483 return "fcmpq\t%1, %2";
485 [(set_attr "type" "fpcmp")])
487 ;; Next come the scc insns. For seq, sne, sgeu, and sltu, we can do this
488 ;; without jumps using the addx/subx instructions. For seq/sne on v9 we use
489 ;; the same code as v8 (the addx/subx method has more applications). The
490 ;; exception to this is "reg != 0" which can be done in one instruction on v9
491 ;; (so we do it). For the rest, on v9 we use conditional moves; on v8, we do
494 ;; Seq_special[_xxx] and sne_special[_xxx] clobber the CC reg, because they
495 ;; generate addcc/subcc instructions.
497 (define_expand "seqsi_special"
499 (xor:SI (match_operand:SI 1 "register_operand" "")
500 (match_operand:SI 2 "register_operand" "")))
501 (parallel [(set (match_operand:SI 0 "register_operand" "")
502 (eq:SI (match_dup 3) (const_int 0)))
503 (clobber (reg:CC 100))])]
505 { operands[3] = gen_reg_rtx (SImode); })
507 (define_expand "seqdi_special"
509 (xor:DI (match_operand:DI 1 "register_operand" "")
510 (match_operand:DI 2 "register_operand" "")))
511 (set (match_operand:DI 0 "register_operand" "")
512 (eq:DI (match_dup 3) (const_int 0)))]
514 { operands[3] = gen_reg_rtx (DImode); })
516 (define_expand "snesi_special"
518 (xor:SI (match_operand:SI 1 "register_operand" "")
519 (match_operand:SI 2 "register_operand" "")))
520 (parallel [(set (match_operand:SI 0 "register_operand" "")
521 (ne:SI (match_dup 3) (const_int 0)))
522 (clobber (reg:CC 100))])]
524 { operands[3] = gen_reg_rtx (SImode); })
526 (define_expand "snedi_special"
528 (xor:DI (match_operand:DI 1 "register_operand" "")
529 (match_operand:DI 2 "register_operand" "")))
530 (set (match_operand:DI 0 "register_operand" "")
531 (ne:DI (match_dup 3) (const_int 0)))]
533 { operands[3] = gen_reg_rtx (DImode); })
535 (define_expand "seqdi_special_trunc"
537 (xor:DI (match_operand:DI 1 "register_operand" "")
538 (match_operand:DI 2 "register_operand" "")))
539 (set (match_operand:SI 0 "register_operand" "")
540 (eq:SI (match_dup 3) (const_int 0)))]
542 { operands[3] = gen_reg_rtx (DImode); })
544 (define_expand "snedi_special_trunc"
546 (xor:DI (match_operand:DI 1 "register_operand" "")
547 (match_operand:DI 2 "register_operand" "")))
548 (set (match_operand:SI 0 "register_operand" "")
549 (ne:SI (match_dup 3) (const_int 0)))]
551 { operands[3] = gen_reg_rtx (DImode); })
553 (define_expand "seqsi_special_extend"
555 (xor:SI (match_operand:SI 1 "register_operand" "")
556 (match_operand:SI 2 "register_operand" "")))
557 (parallel [(set (match_operand:DI 0 "register_operand" "")
558 (eq:DI (match_dup 3) (const_int 0)))
559 (clobber (reg:CC 100))])]
561 { operands[3] = gen_reg_rtx (SImode); })
563 (define_expand "snesi_special_extend"
565 (xor:SI (match_operand:SI 1 "register_operand" "")
566 (match_operand:SI 2 "register_operand" "")))
567 (parallel [(set (match_operand:DI 0 "register_operand" "")
568 (ne:DI (match_dup 3) (const_int 0)))
569 (clobber (reg:CC 100))])]
571 { operands[3] = gen_reg_rtx (SImode); })
573 ;; ??? v9: Operand 0 needs a mode, so SImode was chosen.
574 ;; However, the code handles both SImode and DImode.
576 [(set (match_operand:SI 0 "intreg_operand" "")
577 (eq:SI (match_dup 1) (const_int 0)))]
580 if (GET_MODE (sparc_compare_op0) == SImode)
584 if (GET_MODE (operands[0]) == SImode)
585 pat = gen_seqsi_special (operands[0], sparc_compare_op0,
587 else if (! TARGET_ARCH64)
590 pat = gen_seqsi_special_extend (operands[0], sparc_compare_op0,
595 else if (GET_MODE (sparc_compare_op0) == DImode)
601 else if (GET_MODE (operands[0]) == SImode)
602 pat = gen_seqdi_special_trunc (operands[0], sparc_compare_op0,
605 pat = gen_seqdi_special (operands[0], sparc_compare_op0,
610 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
612 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, EQ);
613 emit_jump_insn (gen_sne (operands[0]));
618 if (gen_v9_scc (EQ, operands))
625 ;; ??? v9: Operand 0 needs a mode, so SImode was chosen.
626 ;; However, the code handles both SImode and DImode.
628 [(set (match_operand:SI 0 "intreg_operand" "")
629 (ne:SI (match_dup 1) (const_int 0)))]
632 if (GET_MODE (sparc_compare_op0) == SImode)
636 if (GET_MODE (operands[0]) == SImode)
637 pat = gen_snesi_special (operands[0], sparc_compare_op0,
639 else if (! TARGET_ARCH64)
642 pat = gen_snesi_special_extend (operands[0], sparc_compare_op0,
647 else if (GET_MODE (sparc_compare_op0) == DImode)
653 else if (GET_MODE (operands[0]) == SImode)
654 pat = gen_snedi_special_trunc (operands[0], sparc_compare_op0,
657 pat = gen_snedi_special (operands[0], sparc_compare_op0,
662 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
664 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, NE);
665 emit_jump_insn (gen_sne (operands[0]));
670 if (gen_v9_scc (NE, operands))
678 [(set (match_operand:SI 0 "intreg_operand" "")
679 (gt:SI (match_dup 1) (const_int 0)))]
682 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
684 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GT);
685 emit_jump_insn (gen_sne (operands[0]));
690 if (gen_v9_scc (GT, operands))
698 [(set (match_operand:SI 0 "intreg_operand" "")
699 (lt:SI (match_dup 1) (const_int 0)))]
702 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
704 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LT);
705 emit_jump_insn (gen_sne (operands[0]));
710 if (gen_v9_scc (LT, operands))
718 [(set (match_operand:SI 0 "intreg_operand" "")
719 (ge:SI (match_dup 1) (const_int 0)))]
722 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
724 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GE);
725 emit_jump_insn (gen_sne (operands[0]));
730 if (gen_v9_scc (GE, operands))
738 [(set (match_operand:SI 0 "intreg_operand" "")
739 (le:SI (match_dup 1) (const_int 0)))]
742 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
744 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LE);
745 emit_jump_insn (gen_sne (operands[0]));
750 if (gen_v9_scc (LE, operands))
757 (define_expand "sgtu"
758 [(set (match_operand:SI 0 "intreg_operand" "")
759 (gtu:SI (match_dup 1) (const_int 0)))]
766 /* We can do ltu easily, so if both operands are registers, swap them and
768 if ((GET_CODE (sparc_compare_op0) == REG
769 || GET_CODE (sparc_compare_op0) == SUBREG)
770 && (GET_CODE (sparc_compare_op1) == REG
771 || GET_CODE (sparc_compare_op1) == SUBREG))
773 tem = sparc_compare_op0;
774 sparc_compare_op0 = sparc_compare_op1;
775 sparc_compare_op1 = tem;
776 pat = gen_sltu (operands[0]);
785 if (gen_v9_scc (GTU, operands))
791 (define_expand "sltu"
792 [(set (match_operand:SI 0 "intreg_operand" "")
793 (ltu:SI (match_dup 1) (const_int 0)))]
798 if (gen_v9_scc (LTU, operands))
801 operands[1] = gen_compare_reg (LTU, sparc_compare_op0, sparc_compare_op1);
804 (define_expand "sgeu"
805 [(set (match_operand:SI 0 "intreg_operand" "")
806 (geu:SI (match_dup 1) (const_int 0)))]
811 if (gen_v9_scc (GEU, operands))
814 operands[1] = gen_compare_reg (GEU, sparc_compare_op0, sparc_compare_op1);
817 (define_expand "sleu"
818 [(set (match_operand:SI 0 "intreg_operand" "")
819 (leu:SI (match_dup 1) (const_int 0)))]
826 /* We can do geu easily, so if both operands are registers, swap them and
828 if ((GET_CODE (sparc_compare_op0) == REG
829 || GET_CODE (sparc_compare_op0) == SUBREG)
830 && (GET_CODE (sparc_compare_op1) == REG
831 || GET_CODE (sparc_compare_op1) == SUBREG))
833 tem = sparc_compare_op0;
834 sparc_compare_op0 = sparc_compare_op1;
835 sparc_compare_op1 = tem;
836 pat = gen_sgeu (operands[0]);
845 if (gen_v9_scc (LEU, operands))
851 ;; Now the DEFINE_INSNs for the scc cases.
853 ;; The SEQ and SNE patterns are special because they can be done
854 ;; without any branching and do not involve a COMPARE. We want
855 ;; them to always use the splitz below so the results can be
858 (define_insn_and_split "*snesi_zero"
859 [(set (match_operand:SI 0 "register_operand" "=r")
860 (ne:SI (match_operand:SI 1 "register_operand" "r")
862 (clobber (reg:CC 100))]
866 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
868 (set (match_dup 0) (ltu:SI (reg:CC 100) (const_int 0)))]
870 [(set_attr "length" "2")])
872 (define_insn_and_split "*neg_snesi_zero"
873 [(set (match_operand:SI 0 "register_operand" "=r")
874 (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
876 (clobber (reg:CC 100))]
880 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
882 (set (match_dup 0) (neg:SI (ltu:SI (reg:CC 100) (const_int 0))))]
884 [(set_attr "length" "2")])
886 (define_insn_and_split "*snesi_zero_extend"
887 [(set (match_operand:DI 0 "register_operand" "=r")
888 (ne:DI (match_operand:SI 1 "register_operand" "r")
890 (clobber (reg:CC 100))]
894 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (minus:SI (const_int 0)
897 (set (match_dup 0) (zero_extend:DI (plus:SI (plus:SI (const_int 0)
899 (ltu:SI (reg:CC_NOOV 100)
902 [(set_attr "length" "2")])
904 (define_insn_and_split "*snedi_zero"
905 [(set (match_operand:DI 0 "register_operand" "=&r")
906 (ne:DI (match_operand:DI 1 "register_operand" "r")
910 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
911 [(set (match_dup 0) (const_int 0))
912 (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
917 [(set_attr "length" "2")])
919 (define_insn_and_split "*neg_snedi_zero"
920 [(set (match_operand:DI 0 "register_operand" "=&r")
921 (neg:DI (ne:DI (match_operand:DI 1 "register_operand" "r")
925 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
926 [(set (match_dup 0) (const_int 0))
927 (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
932 [(set_attr "length" "2")])
934 (define_insn_and_split "*snedi_zero_trunc"
935 [(set (match_operand:SI 0 "register_operand" "=&r")
936 (ne:SI (match_operand:DI 1 "register_operand" "r")
940 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
941 [(set (match_dup 0) (const_int 0))
942 (set (match_dup 0) (if_then_else:SI (ne:DI (match_dup 1)
947 [(set_attr "length" "2")])
949 (define_insn_and_split "*seqsi_zero"
950 [(set (match_operand:SI 0 "register_operand" "=r")
951 (eq:SI (match_operand:SI 1 "register_operand" "r")
953 (clobber (reg:CC 100))]
957 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
959 (set (match_dup 0) (geu:SI (reg:CC 100) (const_int 0)))]
961 [(set_attr "length" "2")])
963 (define_insn_and_split "*neg_seqsi_zero"
964 [(set (match_operand:SI 0 "register_operand" "=r")
965 (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
967 (clobber (reg:CC 100))]
971 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
973 (set (match_dup 0) (neg:SI (geu:SI (reg:CC 100) (const_int 0))))]
975 [(set_attr "length" "2")])
977 (define_insn_and_split "*seqsi_zero_extend"
978 [(set (match_operand:DI 0 "register_operand" "=r")
979 (eq:DI (match_operand:SI 1 "register_operand" "r")
981 (clobber (reg:CC 100))]
985 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (minus:SI (const_int 0)
988 (set (match_dup 0) (zero_extend:DI (minus:SI (minus:SI (const_int 0)
990 (ltu:SI (reg:CC_NOOV 100)
993 [(set_attr "length" "2")])
995 (define_insn_and_split "*seqdi_zero"
996 [(set (match_operand:DI 0 "register_operand" "=&r")
997 (eq:DI (match_operand:DI 1 "register_operand" "r")
1001 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
1002 [(set (match_dup 0) (const_int 0))
1003 (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
1008 [(set_attr "length" "2")])
1010 (define_insn_and_split "*neg_seqdi_zero"
1011 [(set (match_operand:DI 0 "register_operand" "=&r")
1012 (neg:DI (eq:DI (match_operand:DI 1 "register_operand" "r")
1016 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
1017 [(set (match_dup 0) (const_int 0))
1018 (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
1023 [(set_attr "length" "2")])
1025 (define_insn_and_split "*seqdi_zero_trunc"
1026 [(set (match_operand:SI 0 "register_operand" "=&r")
1027 (eq:SI (match_operand:DI 1 "register_operand" "r")
1031 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
1032 [(set (match_dup 0) (const_int 0))
1033 (set (match_dup 0) (if_then_else:SI (eq:DI (match_dup 1)
1038 [(set_attr "length" "2")])
1040 ;; We can also do (x + (i == 0)) and related, so put them in.
1041 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1044 (define_insn_and_split "*x_plus_i_ne_0"
1045 [(set (match_operand:SI 0 "register_operand" "=r")
1046 (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
1048 (match_operand:SI 2 "register_operand" "r")))
1049 (clobber (reg:CC 100))]
1053 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1055 (set (match_dup 0) (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1058 [(set_attr "length" "2")])
1060 (define_insn_and_split "*x_minus_i_ne_0"
1061 [(set (match_operand:SI 0 "register_operand" "=r")
1062 (minus:SI (match_operand:SI 2 "register_operand" "r")
1063 (ne:SI (match_operand:SI 1 "register_operand" "r")
1065 (clobber (reg:CC 100))]
1069 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1071 (set (match_dup 0) (minus:SI (match_dup 2)
1072 (ltu:SI (reg:CC 100) (const_int 0))))]
1074 [(set_attr "length" "2")])
1076 (define_insn_and_split "*x_plus_i_eq_0"
1077 [(set (match_operand:SI 0 "register_operand" "=r")
1078 (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
1080 (match_operand:SI 2 "register_operand" "r")))
1081 (clobber (reg:CC 100))]
1085 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1087 (set (match_dup 0) (plus:SI (geu:SI (reg:CC 100) (const_int 0))
1090 [(set_attr "length" "2")])
1092 (define_insn_and_split "*x_minus_i_eq_0"
1093 [(set (match_operand:SI 0 "register_operand" "=r")
1094 (minus:SI (match_operand:SI 2 "register_operand" "r")
1095 (eq:SI (match_operand:SI 1 "register_operand" "r")
1097 (clobber (reg:CC 100))]
1101 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1103 (set (match_dup 0) (minus:SI (match_dup 2)
1104 (geu:SI (reg:CC 100) (const_int 0))))]
1106 [(set_attr "length" "2")])
1108 ;; We can also do GEU and LTU directly, but these operate after a compare.
1109 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1112 (define_insn "*sltu_insn"
1113 [(set (match_operand:SI 0 "register_operand" "=r")
1114 (ltu:SI (reg:CC 100) (const_int 0)))]
1117 [(set_attr "type" "ialuX")])
1119 (define_insn "*neg_sltu_insn"
1120 [(set (match_operand:SI 0 "register_operand" "=r")
1121 (neg:SI (ltu:SI (reg:CC 100) (const_int 0))))]
1124 [(set_attr "type" "ialuX")])
1126 ;; ??? Combine should canonicalize these next two to the same pattern.
1127 (define_insn "*neg_sltu_minus_x"
1128 [(set (match_operand:SI 0 "register_operand" "=r")
1129 (minus:SI (neg:SI (ltu:SI (reg:CC 100) (const_int 0)))
1130 (match_operand:SI 1 "arith_operand" "rI")))]
1132 "subx\t%%g0, %1, %0"
1133 [(set_attr "type" "ialuX")])
1135 (define_insn "*neg_sltu_plus_x"
1136 [(set (match_operand:SI 0 "register_operand" "=r")
1137 (neg:SI (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1138 (match_operand:SI 1 "arith_operand" "rI"))))]
1140 "subx\t%%g0, %1, %0"
1141 [(set_attr "type" "ialuX")])
1143 (define_insn "*sgeu_insn"
1144 [(set (match_operand:SI 0 "register_operand" "=r")
1145 (geu:SI (reg:CC 100) (const_int 0)))]
1147 "subx\t%%g0, -1, %0"
1148 [(set_attr "type" "ialuX")])
1150 (define_insn "*neg_sgeu_insn"
1151 [(set (match_operand:SI 0 "register_operand" "=r")
1152 (neg:SI (geu:SI (reg:CC 100) (const_int 0))))]
1154 "addx\t%%g0, -1, %0"
1155 [(set_attr "type" "ialuX")])
1157 ;; We can also do (x + ((unsigned) i >= 0)) and related, so put them in.
1158 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1161 (define_insn "*sltu_plus_x"
1162 [(set (match_operand:SI 0 "register_operand" "=r")
1163 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1164 (match_operand:SI 1 "arith_operand" "rI")))]
1166 "addx\t%%g0, %1, %0"
1167 [(set_attr "type" "ialuX")])
1169 (define_insn "*sltu_plus_x_plus_y"
1170 [(set (match_operand:SI 0 "register_operand" "=r")
1171 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1172 (plus:SI (match_operand:SI 1 "arith_operand" "%r")
1173 (match_operand:SI 2 "arith_operand" "rI"))))]
1176 [(set_attr "type" "ialuX")])
1178 (define_insn "*x_minus_sltu"
1179 [(set (match_operand:SI 0 "register_operand" "=r")
1180 (minus:SI (match_operand:SI 1 "register_operand" "r")
1181 (ltu:SI (reg:CC 100) (const_int 0))))]
1184 [(set_attr "type" "ialuX")])
1186 ;; ??? Combine should canonicalize these next two to the same pattern.
1187 (define_insn "*x_minus_y_minus_sltu"
1188 [(set (match_operand:SI 0 "register_operand" "=r")
1189 (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
1190 (match_operand:SI 2 "arith_operand" "rI"))
1191 (ltu:SI (reg:CC 100) (const_int 0))))]
1194 [(set_attr "type" "ialuX")])
1196 (define_insn "*x_minus_sltu_plus_y"
1197 [(set (match_operand:SI 0 "register_operand" "=r")
1198 (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
1199 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1200 (match_operand:SI 2 "arith_operand" "rI"))))]
1203 [(set_attr "type" "ialuX")])
1205 (define_insn "*sgeu_plus_x"
1206 [(set (match_operand:SI 0 "register_operand" "=r")
1207 (plus:SI (geu:SI (reg:CC 100) (const_int 0))
1208 (match_operand:SI 1 "register_operand" "r")))]
1211 [(set_attr "type" "ialuX")])
1213 (define_insn "*x_minus_sgeu"
1214 [(set (match_operand:SI 0 "register_operand" "=r")
1215 (minus:SI (match_operand:SI 1 "register_operand" "r")
1216 (geu:SI (reg:CC 100) (const_int 0))))]
1219 [(set_attr "type" "ialuX")])
1222 [(set (match_operand:SI 0 "register_operand" "")
1223 (match_operator:SI 2 "noov_compare_op"
1224 [(match_operand 1 "icc_or_fcc_reg_operand" "")
1227 && REGNO (operands[1]) == SPARC_ICC_REG
1228 && (GET_MODE (operands[1]) == CCXmode
1229 /* 32 bit LTU/GEU are better implemented using addx/subx. */
1230 || (GET_CODE (operands[2]) != LTU && GET_CODE (operands[2]) != GEU))"
1231 [(set (match_dup 0) (const_int 0))
1233 (if_then_else:SI (match_op_dup:SI 2 [(match_dup 1) (const_int 0)])
1239 ;; These control RTL generation for conditional jump insns
1241 ;; The quad-word fp compare library routines all return nonzero to indicate
1242 ;; true, which is different from the equivalent libgcc routines, so we must
1243 ;; handle them specially here.
1245 (define_expand "beq"
1247 (if_then_else (eq (match_dup 1) (const_int 0))
1248 (label_ref (match_operand 0 "" ""))
1252 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1253 && GET_CODE (sparc_compare_op0) == REG
1254 && GET_MODE (sparc_compare_op0) == DImode)
1256 emit_v9_brxx_insn (EQ, sparc_compare_op0, operands[0]);
1259 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1261 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, EQ);
1262 emit_jump_insn (gen_bne (operands[0]));
1265 operands[1] = gen_compare_reg (EQ, sparc_compare_op0, sparc_compare_op1);
1268 (define_expand "bne"
1270 (if_then_else (ne (match_dup 1) (const_int 0))
1271 (label_ref (match_operand 0 "" ""))
1275 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1276 && GET_CODE (sparc_compare_op0) == REG
1277 && GET_MODE (sparc_compare_op0) == DImode)
1279 emit_v9_brxx_insn (NE, sparc_compare_op0, operands[0]);
1282 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1284 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, NE);
1285 emit_jump_insn (gen_bne (operands[0]));
1288 operands[1] = gen_compare_reg (NE, sparc_compare_op0, sparc_compare_op1);
1291 (define_expand "bgt"
1293 (if_then_else (gt (match_dup 1) (const_int 0))
1294 (label_ref (match_operand 0 "" ""))
1298 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1299 && GET_CODE (sparc_compare_op0) == REG
1300 && GET_MODE (sparc_compare_op0) == DImode)
1302 emit_v9_brxx_insn (GT, sparc_compare_op0, operands[0]);
1305 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1307 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GT);
1308 emit_jump_insn (gen_bne (operands[0]));
1311 operands[1] = gen_compare_reg (GT, sparc_compare_op0, sparc_compare_op1);
1314 (define_expand "bgtu"
1316 (if_then_else (gtu (match_dup 1) (const_int 0))
1317 (label_ref (match_operand 0 "" ""))
1321 operands[1] = gen_compare_reg (GTU, sparc_compare_op0, sparc_compare_op1);
1324 (define_expand "blt"
1326 (if_then_else (lt (match_dup 1) (const_int 0))
1327 (label_ref (match_operand 0 "" ""))
1331 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1332 && GET_CODE (sparc_compare_op0) == REG
1333 && GET_MODE (sparc_compare_op0) == DImode)
1335 emit_v9_brxx_insn (LT, sparc_compare_op0, operands[0]);
1338 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1340 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LT);
1341 emit_jump_insn (gen_bne (operands[0]));
1344 operands[1] = gen_compare_reg (LT, sparc_compare_op0, sparc_compare_op1);
1347 (define_expand "bltu"
1349 (if_then_else (ltu (match_dup 1) (const_int 0))
1350 (label_ref (match_operand 0 "" ""))
1354 operands[1] = gen_compare_reg (LTU, sparc_compare_op0, sparc_compare_op1);
1357 (define_expand "bge"
1359 (if_then_else (ge (match_dup 1) (const_int 0))
1360 (label_ref (match_operand 0 "" ""))
1364 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1365 && GET_CODE (sparc_compare_op0) == REG
1366 && GET_MODE (sparc_compare_op0) == DImode)
1368 emit_v9_brxx_insn (GE, sparc_compare_op0, operands[0]);
1371 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1373 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GE);
1374 emit_jump_insn (gen_bne (operands[0]));
1377 operands[1] = gen_compare_reg (GE, sparc_compare_op0, sparc_compare_op1);
1380 (define_expand "bgeu"
1382 (if_then_else (geu (match_dup 1) (const_int 0))
1383 (label_ref (match_operand 0 "" ""))
1387 operands[1] = gen_compare_reg (GEU, sparc_compare_op0, sparc_compare_op1);
1390 (define_expand "ble"
1392 (if_then_else (le (match_dup 1) (const_int 0))
1393 (label_ref (match_operand 0 "" ""))
1397 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1398 && GET_CODE (sparc_compare_op0) == REG
1399 && GET_MODE (sparc_compare_op0) == DImode)
1401 emit_v9_brxx_insn (LE, sparc_compare_op0, operands[0]);
1404 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1406 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LE);
1407 emit_jump_insn (gen_bne (operands[0]));
1410 operands[1] = gen_compare_reg (LE, sparc_compare_op0, sparc_compare_op1);
1413 (define_expand "bleu"
1415 (if_then_else (leu (match_dup 1) (const_int 0))
1416 (label_ref (match_operand 0 "" ""))
1420 operands[1] = gen_compare_reg (LEU, sparc_compare_op0, sparc_compare_op1);
1423 (define_expand "bunordered"
1425 (if_then_else (unordered (match_dup 1) (const_int 0))
1426 (label_ref (match_operand 0 "" ""))
1430 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1432 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1,
1434 emit_jump_insn (gen_beq (operands[0]));
1437 operands[1] = gen_compare_reg (UNORDERED, sparc_compare_op0,
1441 (define_expand "bordered"
1443 (if_then_else (ordered (match_dup 1) (const_int 0))
1444 (label_ref (match_operand 0 "" ""))
1448 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1450 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, ORDERED);
1451 emit_jump_insn (gen_bne (operands[0]));
1454 operands[1] = gen_compare_reg (ORDERED, sparc_compare_op0,
1458 (define_expand "bungt"
1460 (if_then_else (ungt (match_dup 1) (const_int 0))
1461 (label_ref (match_operand 0 "" ""))
1465 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1467 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNGT);
1468 emit_jump_insn (gen_bgt (operands[0]));
1471 operands[1] = gen_compare_reg (UNGT, sparc_compare_op0, sparc_compare_op1);
1474 (define_expand "bunlt"
1476 (if_then_else (unlt (match_dup 1) (const_int 0))
1477 (label_ref (match_operand 0 "" ""))
1481 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1483 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNLT);
1484 emit_jump_insn (gen_bne (operands[0]));
1487 operands[1] = gen_compare_reg (UNLT, sparc_compare_op0, sparc_compare_op1);
1490 (define_expand "buneq"
1492 (if_then_else (uneq (match_dup 1) (const_int 0))
1493 (label_ref (match_operand 0 "" ""))
1497 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1499 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNEQ);
1500 emit_jump_insn (gen_beq (operands[0]));
1503 operands[1] = gen_compare_reg (UNEQ, sparc_compare_op0, sparc_compare_op1);
1506 (define_expand "bunge"
1508 (if_then_else (unge (match_dup 1) (const_int 0))
1509 (label_ref (match_operand 0 "" ""))
1513 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1515 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNGE);
1516 emit_jump_insn (gen_bne (operands[0]));
1519 operands[1] = gen_compare_reg (UNGE, sparc_compare_op0, sparc_compare_op1);
1522 (define_expand "bunle"
1524 (if_then_else (unle (match_dup 1) (const_int 0))
1525 (label_ref (match_operand 0 "" ""))
1529 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1531 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNLE);
1532 emit_jump_insn (gen_bne (operands[0]));
1535 operands[1] = gen_compare_reg (UNLE, sparc_compare_op0, sparc_compare_op1);
1538 (define_expand "bltgt"
1540 (if_then_else (ltgt (match_dup 1) (const_int 0))
1541 (label_ref (match_operand 0 "" ""))
1545 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1547 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LTGT);
1548 emit_jump_insn (gen_bne (operands[0]));
1551 operands[1] = gen_compare_reg (LTGT, sparc_compare_op0, sparc_compare_op1);
1554 ;; Now match both normal and inverted jump.
1556 ;; XXX fpcmp nop braindamage
1557 (define_insn "*normal_branch"
1559 (if_then_else (match_operator 0 "noov_compare_op"
1560 [(reg 100) (const_int 0)])
1561 (label_ref (match_operand 1 "" ""))
1565 return output_cbranch (operands[0], operands[1], 1, 0,
1566 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1569 [(set_attr "type" "branch")
1570 (set_attr "branch_type" "icc")])
1572 ;; XXX fpcmp nop braindamage
1573 (define_insn "*inverted_branch"
1575 (if_then_else (match_operator 0 "noov_compare_op"
1576 [(reg 100) (const_int 0)])
1578 (label_ref (match_operand 1 "" ""))))]
1581 return output_cbranch (operands[0], operands[1], 1, 1,
1582 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1585 [(set_attr "type" "branch")
1586 (set_attr "branch_type" "icc")])
1588 ;; XXX fpcmp nop braindamage
1589 (define_insn "*normal_fp_branch"
1591 (if_then_else (match_operator 1 "comparison_operator"
1592 [(match_operand:CCFP 0 "fcc_reg_operand" "c")
1594 (label_ref (match_operand 2 "" ""))
1598 return output_cbranch (operands[1], operands[2], 2, 0,
1599 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1602 [(set_attr "type" "branch")
1603 (set_attr "branch_type" "fcc")])
1605 ;; XXX fpcmp nop braindamage
1606 (define_insn "*inverted_fp_branch"
1608 (if_then_else (match_operator 1 "comparison_operator"
1609 [(match_operand:CCFP 0 "fcc_reg_operand" "c")
1612 (label_ref (match_operand 2 "" ""))))]
1615 return output_cbranch (operands[1], operands[2], 2, 1,
1616 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1619 [(set_attr "type" "branch")
1620 (set_attr "branch_type" "fcc")])
1622 ;; XXX fpcmp nop braindamage
1623 (define_insn "*normal_fpe_branch"
1625 (if_then_else (match_operator 1 "comparison_operator"
1626 [(match_operand:CCFPE 0 "fcc_reg_operand" "c")
1628 (label_ref (match_operand 2 "" ""))
1632 return output_cbranch (operands[1], operands[2], 2, 0,
1633 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1636 [(set_attr "type" "branch")
1637 (set_attr "branch_type" "fcc")])
1639 ;; XXX fpcmp nop braindamage
1640 (define_insn "*inverted_fpe_branch"
1642 (if_then_else (match_operator 1 "comparison_operator"
1643 [(match_operand:CCFPE 0 "fcc_reg_operand" "c")
1646 (label_ref (match_operand 2 "" ""))))]
1649 return output_cbranch (operands[1], operands[2], 2, 1,
1650 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1653 [(set_attr "type" "branch")
1654 (set_attr "branch_type" "fcc")])
1656 ;; SPARC V9-specific jump insns. None of these are guaranteed to be
1657 ;; in the architecture.
1659 ;; There are no 32 bit brreg insns.
1662 (define_insn "*normal_int_branch_sp64"
1664 (if_then_else (match_operator 0 "v9_regcmp_op"
1665 [(match_operand:DI 1 "register_operand" "r")
1667 (label_ref (match_operand 2 "" ""))
1671 return output_v9branch (operands[0], operands[2], 1, 2, 0,
1672 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1675 [(set_attr "type" "branch")
1676 (set_attr "branch_type" "reg")])
1679 (define_insn "*inverted_int_branch_sp64"
1681 (if_then_else (match_operator 0 "v9_regcmp_op"
1682 [(match_operand:DI 1 "register_operand" "r")
1685 (label_ref (match_operand 2 "" ""))))]
1688 return output_v9branch (operands[0], operands[2], 1, 2, 1,
1689 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1692 [(set_attr "type" "branch")
1693 (set_attr "branch_type" "reg")])
1695 ;; Load in operand 0 the (absolute) address of operand 1, which is a symbolic
1696 ;; value subject to a PC-relative relocation. Operand 2 is a helper function
1697 ;; that adds the PC value at the call point to operand 0.
1699 (define_insn "load_pcrel_sym<P:mode>"
1700 [(set (match_operand:P 0 "register_operand" "=r")
1701 (unspec:P [(match_operand:P 1 "symbolic_operand" "")
1702 (match_operand:P 2 "call_operand_address" "")] UNSPEC_LOAD_PCREL_SYM))
1703 (clobber (reg:P 15))]
1706 if (flag_delayed_branch)
1707 return "sethi\t%%hi(%a1-4), %0\n\tcall\t%a2\n\t add\t%0, %%lo(%a1+4), %0";
1709 return "sethi\t%%hi(%a1-8), %0\n\tadd\t%0, %%lo(%a1-4), %0\n\tcall\t%a2\n\t nop";
1711 [(set (attr "type") (const_string "multi"))
1712 (set (attr "length")
1713 (if_then_else (eq_attr "delayed_branch" "true")
1717 ;; Move instructions
1719 (define_expand "movqi"
1720 [(set (match_operand:QI 0 "general_operand" "")
1721 (match_operand:QI 1 "general_operand" ""))]
1724 /* Working with CONST_INTs is easier, so convert
1725 a double if needed. */
1726 if (GET_CODE (operands[1]) == CONST_DOUBLE)
1728 operands[1] = GEN_INT (trunc_int_for_mode
1729 (CONST_DOUBLE_LOW (operands[1]), QImode));
1732 /* Handle sets of MEM first. */
1733 if (GET_CODE (operands[0]) == MEM)
1735 if (reg_or_0_operand (operands[1], QImode))
1738 if (! reload_in_progress)
1740 operands[0] = validize_mem (operands[0]);
1741 operands[1] = force_reg (QImode, operands[1]);
1745 /* Fixup TLS cases. */
1746 if (tls_symbolic_operand (operands [1]))
1747 operands[1] = legitimize_tls_address (operands[1]);
1749 /* Fixup PIC cases. */
1752 if (CONSTANT_P (operands[1])
1753 && pic_address_needs_scratch (operands[1]))
1754 operands[1] = legitimize_pic_address (operands[1], QImode, 0);
1756 if (symbolic_operand (operands[1], QImode))
1758 operands[1] = legitimize_pic_address (operands[1],
1760 (reload_in_progress ?
1767 /* All QI constants require only one insn, so proceed. */
1773 (define_insn "*movqi_insn"
1774 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m")
1775 (match_operand:QI 1 "input_operand" "rI,m,rJ"))]
1776 "(register_operand (operands[0], QImode)
1777 || reg_or_0_operand (operands[1], QImode))"
1782 [(set_attr "type" "*,load,store")
1783 (set_attr "us3load_type" "*,3cycle,*")])
1785 (define_expand "movhi"
1786 [(set (match_operand:HI 0 "general_operand" "")
1787 (match_operand:HI 1 "general_operand" ""))]
1790 /* Working with CONST_INTs is easier, so convert
1791 a double if needed. */
1792 if (GET_CODE (operands[1]) == CONST_DOUBLE)
1793 operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
1795 /* Handle sets of MEM first. */
1796 if (GET_CODE (operands[0]) == MEM)
1798 if (reg_or_0_operand (operands[1], HImode))
1801 if (! reload_in_progress)
1803 operands[0] = validize_mem (operands[0]);
1804 operands[1] = force_reg (HImode, operands[1]);
1808 /* Fixup TLS cases. */
1809 if (tls_symbolic_operand (operands [1]))
1810 operands[1] = legitimize_tls_address (operands[1]);
1812 /* Fixup PIC cases. */
1815 if (CONSTANT_P (operands[1])
1816 && pic_address_needs_scratch (operands[1]))
1817 operands[1] = legitimize_pic_address (operands[1], HImode, 0);
1819 if (symbolic_operand (operands[1], HImode))
1821 operands[1] = legitimize_pic_address (operands[1],
1823 (reload_in_progress ?
1830 /* This makes sure we will not get rematched due to splittage. */
1831 if (! CONSTANT_P (operands[1]) || input_operand (operands[1], HImode))
1833 else if (CONSTANT_P (operands[1])
1834 && GET_CODE (operands[1]) != HIGH
1835 && GET_CODE (operands[1]) != LO_SUM)
1837 sparc_emit_set_const32 (operands[0], operands[1]);
1844 (define_insn "*movhi_const64_special"
1845 [(set (match_operand:HI 0 "register_operand" "=r")
1846 (match_operand:HI 1 "const64_high_operand" ""))]
1848 "sethi\t%%hi(%a1), %0")
1850 (define_insn "*movhi_insn"
1851 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1852 (match_operand:HI 1 "input_operand" "rI,K,m,rJ"))]
1853 "(register_operand (operands[0], HImode)
1854 || reg_or_0_operand (operands[1], HImode))"
1857 sethi\t%%hi(%a1), %0
1860 [(set_attr "type" "*,*,load,store")
1861 (set_attr "us3load_type" "*,*,3cycle,*")])
1863 ;; We always work with constants here.
1864 (define_insn "*movhi_lo_sum"
1865 [(set (match_operand:HI 0 "register_operand" "=r")
1866 (ior:HI (match_operand:HI 1 "register_operand" "%r")
1867 (match_operand:HI 2 "small_int" "I")))]
1871 (define_expand "movsi"
1872 [(set (match_operand:SI 0 "general_operand" "")
1873 (match_operand:SI 1 "general_operand" ""))]
1876 /* Working with CONST_INTs is easier, so convert
1877 a double if needed. */
1878 if (GET_CODE (operands[1]) == CONST_DOUBLE)
1879 operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
1881 /* Handle sets of MEM first. */
1882 if (GET_CODE (operands[0]) == MEM)
1884 if (reg_or_0_operand (operands[1], SImode))
1887 if (! reload_in_progress)
1889 operands[0] = validize_mem (operands[0]);
1890 operands[1] = force_reg (SImode, operands[1]);
1894 /* Fixup TLS cases. */
1895 if (tls_symbolic_operand (operands [1]))
1896 operands[1] = legitimize_tls_address (operands[1]);
1898 /* Fixup PIC cases. */
1901 if (CONSTANT_P (operands[1])
1902 && pic_address_needs_scratch (operands[1]))
1903 operands[1] = legitimize_pic_address (operands[1], SImode, 0);
1905 if (GET_CODE (operands[1]) == LABEL_REF)
1908 emit_insn (gen_movsi_pic_label_ref (operands[0], operands[1]));
1912 if (symbolic_operand (operands[1], SImode))
1914 operands[1] = legitimize_pic_address (operands[1],
1916 (reload_in_progress ?
1923 /* If we are trying to toss an integer constant into the
1924 FPU registers, force it into memory. */
1925 if (GET_CODE (operands[0]) == REG
1926 && REGNO (operands[0]) >= SPARC_FIRST_FP_REG
1927 && REGNO (operands[0]) <= SPARC_LAST_V9_FP_REG
1928 && CONSTANT_P (operands[1]))
1929 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
1932 /* This makes sure we will not get rematched due to splittage. */
1933 if (! CONSTANT_P (operands[1]) || input_operand (operands[1], SImode))
1935 else if (CONSTANT_P (operands[1])
1936 && GET_CODE (operands[1]) != HIGH
1937 && GET_CODE (operands[1]) != LO_SUM)
1939 sparc_emit_set_const32 (operands[0], operands[1]);
1946 ;; This is needed to show CSE exactly which bits are set
1947 ;; in a 64-bit register by sethi instructions.
1948 (define_insn "*movsi_const64_special"
1949 [(set (match_operand:SI 0 "register_operand" "=r")
1950 (match_operand:SI 1 "const64_high_operand" ""))]
1952 "sethi\t%%hi(%a1), %0")
1954 (define_insn "*movsi_insn"
1955 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,f,r,r,r,f,m,m,d")
1956 (match_operand:SI 1 "input_operand" "rI,!f,K,J,m,!m,rJ,!f,J"))]
1957 "(register_operand (operands[0], SImode)
1958 || reg_or_0_operand (operands[1], SImode))"
1962 sethi\t%%hi(%a1), %0
1969 [(set_attr "type" "*,fpmove,*,*,load,fpload,store,fpstore,fga")])
1971 (define_insn "*movsi_lo_sum"
1972 [(set (match_operand:SI 0 "register_operand" "=r")
1973 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1974 (match_operand:SI 2 "immediate_operand" "in")))]
1976 "or\t%1, %%lo(%a2), %0")
1978 (define_insn "*movsi_high"
1979 [(set (match_operand:SI 0 "register_operand" "=r")
1980 (high:SI (match_operand:SI 1 "immediate_operand" "in")))]
1982 "sethi\t%%hi(%a1), %0")
1984 ;; The next two patterns must wrap the SYMBOL_REF in an UNSPEC
1985 ;; so that CSE won't optimize the address computation away.
1986 (define_insn "movsi_lo_sum_pic"
1987 [(set (match_operand:SI 0 "register_operand" "=r")
1988 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1989 (unspec:SI [(match_operand:SI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
1991 "or\t%1, %%lo(%a2), %0")
1993 (define_insn "movsi_high_pic"
1994 [(set (match_operand:SI 0 "register_operand" "=r")
1995 (high:SI (unspec:SI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
1996 "flag_pic && check_pic (1)"
1997 "sethi\t%%hi(%a1), %0")
1999 (define_expand "movsi_pic_label_ref"
2000 [(set (match_dup 3) (high:SI
2001 (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
2002 (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
2003 (set (match_dup 4) (lo_sum:SI (match_dup 3)
2004 (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
2005 (set (match_operand:SI 0 "register_operand" "=r")
2006 (minus:SI (match_dup 5) (match_dup 4)))]
2009 current_function_uses_pic_offset_table = 1;
2010 operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
2013 operands[3] = operands[0];
2014 operands[4] = operands[0];
2018 operands[3] = gen_reg_rtx (SImode);
2019 operands[4] = gen_reg_rtx (SImode);
2021 operands[5] = pic_offset_table_rtx;
2024 (define_insn "*movsi_high_pic_label_ref"
2025 [(set (match_operand:SI 0 "register_operand" "=r")
2027 (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
2028 (match_operand:SI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
2030 "sethi\t%%hi(%a2-(%a1-.)), %0")
2032 (define_insn "*movsi_lo_sum_pic_label_ref"
2033 [(set (match_operand:SI 0 "register_operand" "=r")
2034 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
2035 (unspec:SI [(match_operand:SI 2 "label_ref_operand" "")
2036 (match_operand:SI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
2038 "or\t%1, %%lo(%a3-(%a2-.)), %0")
2040 (define_expand "movdi"
2041 [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand" "")
2042 (match_operand:DI 1 "general_operand" ""))]
2045 /* Where possible, convert CONST_DOUBLE into a CONST_INT. */
2046 if (GET_CODE (operands[1]) == CONST_DOUBLE
2047 #if HOST_BITS_PER_WIDE_INT == 32
2048 && ((CONST_DOUBLE_HIGH (operands[1]) == 0
2049 && (CONST_DOUBLE_LOW (operands[1]) & 0x80000000) == 0)
2050 || (CONST_DOUBLE_HIGH (operands[1]) == (HOST_WIDE_INT) 0xffffffff
2051 && (CONST_DOUBLE_LOW (operands[1]) & 0x80000000) != 0))
2054 operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
2056 /* Handle MEM cases first. */
2057 if (GET_CODE (operands[0]) == MEM)
2059 /* If it's a REG, we can always do it.
2060 The const zero case is more complex, on v9
2061 we can always perform it. */
2062 if (register_operand (operands[1], DImode)
2064 && (operands[1] == const0_rtx)))
2067 if (! reload_in_progress)
2069 operands[0] = validize_mem (operands[0]);
2070 operands[1] = force_reg (DImode, operands[1]);
2074 /* Fixup TLS cases. */
2075 if (tls_symbolic_operand (operands [1]))
2076 operands[1] = legitimize_tls_address (operands[1]);
2080 if (CONSTANT_P (operands[1])
2081 && pic_address_needs_scratch (operands[1]))
2082 operands[1] = legitimize_pic_address (operands[1], DImode, 0);
2084 if (GET_CODE (operands[1]) == LABEL_REF)
2086 gcc_assert (TARGET_ARCH64);
2087 emit_insn (gen_movdi_pic_label_ref (operands[0], operands[1]));
2091 if (symbolic_operand (operands[1], DImode))
2093 operands[1] = legitimize_pic_address (operands[1],
2095 (reload_in_progress ?
2102 /* If we are trying to toss an integer constant into the
2103 FPU registers, force it into memory. */
2104 if (GET_CODE (operands[0]) == REG
2105 && REGNO (operands[0]) >= SPARC_FIRST_FP_REG
2106 && REGNO (operands[0]) <= SPARC_LAST_V9_FP_REG
2107 && CONSTANT_P (operands[1]))
2108 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
2111 /* This makes sure we will not get rematched due to splittage. */
2112 if (! CONSTANT_P (operands[1]) || input_operand (operands[1], DImode))
2114 else if (TARGET_ARCH64
2115 && GET_CODE (operands[1]) != HIGH
2116 && GET_CODE (operands[1]) != LO_SUM)
2118 sparc_emit_set_const64 (operands[0], operands[1]);
2126 ;; Be careful, fmovd does not exist when !v9.
2127 ;; We match MEM moves directly when we have correct even
2128 ;; numbered registers, but fall into splits otherwise.
2129 ;; The constraint ordering here is really important to
2130 ;; avoid insane problems in reload, especially for patterns
2133 ;; (set (mem:DI (plus:SI (reg:SI 30 %fp)
2134 ;; (const_int -5016)))
2138 (define_insn "*movdi_insn_sp32_v9"
2139 [(set (match_operand:DI 0 "nonimmediate_operand"
2140 "=T,o,T,U,o,r,r,r,?T,?f,?f,?o,?e,?e,?W")
2141 (match_operand:DI 1 "input_operand"
2142 " J,J,U,T,r,o,i,r, f, T, o, f, e, W, e"))]
2143 "! TARGET_ARCH64 && TARGET_V9
2144 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2161 [(set_attr "type" "store,store,store,load,*,*,*,*,fpstore,fpload,*,*,fpmove,fpload,fpstore")
2162 (set_attr "length" "*,2,*,*,2,2,2,2,*,*,2,2,*,*,*")
2163 (set_attr "fptype" "*,*,*,*,*,*,*,*,*,*,*,*,double,*,*")])
2165 (define_insn "*movdi_insn_sp32"
2166 [(set (match_operand:DI 0 "nonimmediate_operand"
2167 "=o,T,U,o,r,r,r,?T,?f,?f,?o,?f")
2168 (match_operand:DI 1 "input_operand"
2169 " J,U,T,r,o,i,r, f, T, o, f, f"))]
2171 && (register_operand (operands[0], DImode)
2172 || register_operand (operands[1], DImode))"
2186 [(set_attr "type" "store,store,load,*,*,*,*,fpstore,fpload,*,*,*")
2187 (set_attr "length" "2,*,*,2,2,2,2,*,*,2,2,2")])
2189 ;; The following are generated by sparc_emit_set_const64
2190 (define_insn "*movdi_sp64_dbl"
2191 [(set (match_operand:DI 0 "register_operand" "=r")
2192 (match_operand:DI 1 "const64_operand" ""))]
2194 && HOST_BITS_PER_WIDE_INT != 64)"
2197 ;; This is needed to show CSE exactly which bits are set
2198 ;; in a 64-bit register by sethi instructions.
2199 (define_insn "*movdi_const64_special"
2200 [(set (match_operand:DI 0 "register_operand" "=r")
2201 (match_operand:DI 1 "const64_high_operand" ""))]
2203 "sethi\t%%hi(%a1), %0")
2205 (define_insn "*movdi_insn_sp64_novis"
2206 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,m,?e,?e,?W")
2207 (match_operand:DI 1 "input_operand" "rI,N,J,m,rJ,e,W,e"))]
2208 "TARGET_ARCH64 && ! TARGET_VIS
2209 && (register_operand (operands[0], DImode)
2210 || reg_or_0_operand (operands[1], DImode))"
2213 sethi\t%%hi(%a1), %0
2220 [(set_attr "type" "*,*,*,load,store,fpmove,fpload,fpstore")
2221 (set_attr "fptype" "*,*,*,*,*,double,*,*")])
2223 ;; We don't define V1SI because SI should work just fine.
2224 (define_mode_macro V64 [DF V2SI V4HI V8QI])
2225 (define_mode_macro V32 [SF V2HI V4QI])
2227 (define_insn "*movdi_insn_sp64_vis"
2228 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,m,?e,?e,?W,b")
2229 (match_operand:DI 1 "input_operand" "rI,N,J,m,rJ,e,W,e,J"))]
2230 "TARGET_ARCH64 && TARGET_VIS &&
2231 (register_operand (operands[0], DImode)
2232 || reg_or_0_operand (operands[1], DImode))"
2235 sethi\t%%hi(%a1), %0
2243 [(set_attr "type" "*,*,*,load,store,fpmove,fpload,fpstore,fga")
2244 (set_attr "fptype" "*,*,*,*,*,double,*,*,double")])
2246 (define_expand "movdi_pic_label_ref"
2247 [(set (match_dup 3) (high:DI
2248 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
2249 (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
2250 (set (match_dup 4) (lo_sum:DI (match_dup 3)
2251 (unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
2252 (set (match_operand:DI 0 "register_operand" "=r")
2253 (minus:DI (match_dup 5) (match_dup 4)))]
2254 "TARGET_ARCH64 && flag_pic"
2256 current_function_uses_pic_offset_table = 1;
2257 operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
2260 operands[3] = operands[0];
2261 operands[4] = operands[0];
2265 operands[3] = gen_reg_rtx (DImode);
2266 operands[4] = gen_reg_rtx (DImode);
2268 operands[5] = pic_offset_table_rtx;
2271 (define_insn "*movdi_high_pic_label_ref"
2272 [(set (match_operand:DI 0 "register_operand" "=r")
2274 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
2275 (match_operand:DI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
2276 "TARGET_ARCH64 && flag_pic"
2277 "sethi\t%%hi(%a2-(%a1-.)), %0")
2279 (define_insn "*movdi_lo_sum_pic_label_ref"
2280 [(set (match_operand:DI 0 "register_operand" "=r")
2281 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2282 (unspec:DI [(match_operand:DI 2 "label_ref_operand" "")
2283 (match_operand:DI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
2284 "TARGET_ARCH64 && flag_pic"
2285 "or\t%1, %%lo(%a3-(%a2-.)), %0")
2287 ;; SPARC-v9 code model support insns. See sparc_emit_set_symbolic_const64
2288 ;; in sparc.c to see what is going on here... PIC stuff comes first.
2290 (define_insn "movdi_lo_sum_pic"
2291 [(set (match_operand:DI 0 "register_operand" "=r")
2292 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2293 (unspec:DI [(match_operand:DI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
2294 "TARGET_ARCH64 && flag_pic"
2295 "or\t%1, %%lo(%a2), %0")
2297 (define_insn "movdi_high_pic"
2298 [(set (match_operand:DI 0 "register_operand" "=r")
2299 (high:DI (unspec:DI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
2300 "TARGET_ARCH64 && flag_pic && check_pic (1)"
2301 "sethi\t%%hi(%a1), %0")
2303 (define_insn "*sethi_di_medlow_embmedany_pic"
2304 [(set (match_operand:DI 0 "register_operand" "=r")
2305 (high:DI (match_operand:DI 1 "sp64_medium_pic_operand" "")))]
2306 "(TARGET_CM_MEDLOW || TARGET_CM_EMBMEDANY) && check_pic (1)"
2307 "sethi\t%%hi(%a1), %0")
2309 (define_insn "*sethi_di_medlow"
2310 [(set (match_operand:DI 0 "register_operand" "=r")
2311 (high:DI (match_operand:DI 1 "symbolic_operand" "")))]
2312 "TARGET_CM_MEDLOW && check_pic (1)"
2313 "sethi\t%%hi(%a1), %0")
2315 (define_insn "*losum_di_medlow"
2316 [(set (match_operand:DI 0 "register_operand" "=r")
2317 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2318 (match_operand:DI 2 "symbolic_operand" "")))]
2320 "or\t%1, %%lo(%a2), %0")
2322 (define_insn "seth44"
2323 [(set (match_operand:DI 0 "register_operand" "=r")
2324 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETH44)))]
2326 "sethi\t%%h44(%a1), %0")
2328 (define_insn "setm44"
2329 [(set (match_operand:DI 0 "register_operand" "=r")
2330 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2331 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_SETM44)))]
2333 "or\t%1, %%m44(%a2), %0")
2335 (define_insn "setl44"
2336 [(set (match_operand:DI 0 "register_operand" "=r")
2337 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2338 (match_operand:DI 2 "symbolic_operand" "")))]
2340 "or\t%1, %%l44(%a2), %0")
2342 (define_insn "sethh"
2343 [(set (match_operand:DI 0 "register_operand" "=r")
2344 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETHH)))]
2346 "sethi\t%%hh(%a1), %0")
2348 (define_insn "setlm"
2349 [(set (match_operand:DI 0 "register_operand" "=r")
2350 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETLM)))]
2352 "sethi\t%%lm(%a1), %0")
2354 (define_insn "sethm"
2355 [(set (match_operand:DI 0 "register_operand" "=r")
2356 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2357 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_EMB_SETHM)))]
2359 "or\t%1, %%hm(%a2), %0")
2361 (define_insn "setlo"
2362 [(set (match_operand:DI 0 "register_operand" "=r")
2363 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2364 (match_operand:DI 2 "symbolic_operand" "")))]
2366 "or\t%1, %%lo(%a2), %0")
2368 (define_insn "embmedany_sethi"
2369 [(set (match_operand:DI 0 "register_operand" "=r")
2370 (high:DI (unspec:DI [(match_operand:DI 1 "data_segment_operand" "")] UNSPEC_EMB_HISUM)))]
2371 "TARGET_CM_EMBMEDANY && check_pic (1)"
2372 "sethi\t%%hi(%a1), %0")
2374 (define_insn "embmedany_losum"
2375 [(set (match_operand:DI 0 "register_operand" "=r")
2376 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2377 (match_operand:DI 2 "data_segment_operand" "")))]
2378 "TARGET_CM_EMBMEDANY"
2379 "add\t%1, %%lo(%a2), %0")
2381 (define_insn "embmedany_brsum"
2382 [(set (match_operand:DI 0 "register_operand" "=r")
2383 (unspec:DI [(match_operand:DI 1 "register_operand" "r")] UNSPEC_EMB_HISUM))]
2384 "TARGET_CM_EMBMEDANY"
2387 (define_insn "embmedany_textuhi"
2388 [(set (match_operand:DI 0 "register_operand" "=r")
2389 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTUHI)))]
2390 "TARGET_CM_EMBMEDANY && check_pic (1)"
2391 "sethi\t%%uhi(%a1), %0")
2393 (define_insn "embmedany_texthi"
2394 [(set (match_operand:DI 0 "register_operand" "=r")
2395 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTHI)))]
2396 "TARGET_CM_EMBMEDANY && check_pic (1)"
2397 "sethi\t%%hi(%a1), %0")
2399 (define_insn "embmedany_textulo"
2400 [(set (match_operand:DI 0 "register_operand" "=r")
2401 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2402 (unspec:DI [(match_operand:DI 2 "text_segment_operand" "")] UNSPEC_EMB_TEXTULO)))]
2403 "TARGET_CM_EMBMEDANY"
2404 "or\t%1, %%ulo(%a2), %0")
2406 (define_insn "embmedany_textlo"
2407 [(set (match_operand:DI 0 "register_operand" "=r")
2408 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2409 (match_operand:DI 2 "text_segment_operand" "")))]
2410 "TARGET_CM_EMBMEDANY"
2411 "or\t%1, %%lo(%a2), %0")
2413 ;; Now some patterns to help reload out a bit.
2414 (define_expand "reload_indi"
2415 [(parallel [(match_operand:DI 0 "register_operand" "=r")
2416 (match_operand:DI 1 "immediate_operand" "")
2417 (match_operand:TI 2 "register_operand" "=&r")])]
2419 || TARGET_CM_EMBMEDANY)
2422 sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
2426 (define_expand "reload_outdi"
2427 [(parallel [(match_operand:DI 0 "register_operand" "=r")
2428 (match_operand:DI 1 "immediate_operand" "")
2429 (match_operand:TI 2 "register_operand" "=&r")])]
2431 || TARGET_CM_EMBMEDANY)
2434 sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
2438 ;; Split up putting CONSTs and REGs into DI regs when !arch64
2440 [(set (match_operand:DI 0 "register_operand" "")
2441 (match_operand:DI 1 "const_int_operand" ""))]
2442 "! TARGET_ARCH64 && reload_completed"
2443 [(clobber (const_int 0))]
2445 #if HOST_BITS_PER_WIDE_INT == 32
2446 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
2447 (INTVAL (operands[1]) < 0) ?
2450 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2453 unsigned int low, high;
2455 low = trunc_int_for_mode (INTVAL (operands[1]), SImode);
2456 high = trunc_int_for_mode (INTVAL (operands[1]) >> 32, SImode);
2457 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), GEN_INT (high)));
2459 /* Slick... but this trick loses if this subreg constant part
2460 can be done in one insn. */
2461 if (low == high && (low & 0x3ff) != 0 && low + 0x1000 >= 0x2000)
2462 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2463 gen_highpart (SImode, operands[0])));
2465 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), GEN_INT (low)));
2471 [(set (match_operand:DI 0 "register_operand" "")
2472 (match_operand:DI 1 "const_double_operand" ""))]
2476 && ((GET_CODE (operands[0]) == REG
2477 && REGNO (operands[0]) < 32)
2478 || (GET_CODE (operands[0]) == SUBREG
2479 && GET_CODE (SUBREG_REG (operands[0])) == REG
2480 && REGNO (SUBREG_REG (operands[0])) < 32))))"
2481 [(clobber (const_int 0))]
2483 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
2484 GEN_INT (CONST_DOUBLE_HIGH (operands[1]))));
2486 /* Slick... but this trick loses if this subreg constant part
2487 can be done in one insn. */
2488 if (CONST_DOUBLE_LOW (operands[1]) == CONST_DOUBLE_HIGH (operands[1])
2489 && !(SPARC_SETHI32_P (CONST_DOUBLE_HIGH (operands[1]))
2490 || SPARC_SIMM13_P (CONST_DOUBLE_HIGH (operands[1]))))
2492 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2493 gen_highpart (SImode, operands[0])));
2497 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2498 GEN_INT (CONST_DOUBLE_LOW (operands[1]))));
2504 [(set (match_operand:DI 0 "register_operand" "")
2505 (match_operand:DI 1 "register_operand" ""))]
2509 && ((GET_CODE (operands[0]) == REG
2510 && REGNO (operands[0]) < 32)
2511 || (GET_CODE (operands[0]) == SUBREG
2512 && GET_CODE (SUBREG_REG (operands[0])) == REG
2513 && REGNO (SUBREG_REG (operands[0])) < 32))))"
2514 [(clobber (const_int 0))]
2516 rtx set_dest = operands[0];
2517 rtx set_src = operands[1];
2521 dest1 = gen_highpart (SImode, set_dest);
2522 dest2 = gen_lowpart (SImode, set_dest);
2523 src1 = gen_highpart (SImode, set_src);
2524 src2 = gen_lowpart (SImode, set_src);
2526 /* Now emit using the real source and destination we found, swapping
2527 the order if we detect overlap. */
2528 if (reg_overlap_mentioned_p (dest1, src2))
2530 emit_insn (gen_movsi (dest2, src2));
2531 emit_insn (gen_movsi (dest1, src1));
2535 emit_insn (gen_movsi (dest1, src1));
2536 emit_insn (gen_movsi (dest2, src2));
2541 ;; Now handle the cases of memory moves from/to non-even
2542 ;; DI mode register pairs.
2544 [(set (match_operand:DI 0 "register_operand" "")
2545 (match_operand:DI 1 "memory_operand" ""))]
2548 && sparc_splitdi_legitimate (operands[0], operands[1]))"
2549 [(clobber (const_int 0))]
2551 rtx word0 = adjust_address (operands[1], SImode, 0);
2552 rtx word1 = adjust_address (operands[1], SImode, 4);
2553 rtx high_part = gen_highpart (SImode, operands[0]);
2554 rtx low_part = gen_lowpart (SImode, operands[0]);
2556 if (reg_overlap_mentioned_p (high_part, word1))
2558 emit_insn (gen_movsi (low_part, word1));
2559 emit_insn (gen_movsi (high_part, word0));
2563 emit_insn (gen_movsi (high_part, word0));
2564 emit_insn (gen_movsi (low_part, word1));
2570 [(set (match_operand:DI 0 "memory_operand" "")
2571 (match_operand:DI 1 "register_operand" ""))]
2574 && sparc_splitdi_legitimate (operands[1], operands[0]))"
2575 [(clobber (const_int 0))]
2577 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0),
2578 gen_highpart (SImode, operands[1])));
2579 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4),
2580 gen_lowpart (SImode, operands[1])));
2585 [(set (match_operand:DI 0 "memory_operand" "")
2590 && ! mem_min_alignment (operands[0], 8)))
2591 && offsettable_memref_p (operands[0])"
2592 [(clobber (const_int 0))]
2594 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0), const0_rtx));
2595 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4), const0_rtx));
2599 ;; Floating point move insns
2601 (define_insn "*movsf_insn_novis"
2602 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,*r,*r,*r,*r,*r,f,m,m")
2603 (match_operand:SF 1 "input_operand" "f,G,Q,*rR,S,m,m,f,*rG"))]
2604 "(TARGET_FPU && ! TARGET_VIS)
2605 && (register_operand (operands[0], SFmode)
2606 || register_operand (operands[1], SFmode)
2607 || fp_zero_operand (operands[1], SFmode))"
2609 if (GET_CODE (operands[1]) == CONST_DOUBLE
2610 && (which_alternative == 2
2611 || which_alternative == 3
2612 || which_alternative == 4))
2617 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2618 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2619 operands[1] = GEN_INT (i);
2622 switch (which_alternative)
2625 return "fmovs\t%1, %0";
2629 return "sethi\t%%hi(%a1), %0";
2631 return "mov\t%1, %0";
2636 return "ld\t%1, %0";
2639 return "st\t%r1, %0";
2644 [(set_attr "type" "fpmove,*,*,*,*,load,fpload,fpstore,store")])
2646 (define_insn "*movsf_insn_vis"
2647 [(set (match_operand:V32 0 "nonimmediate_operand" "=f,f,*r,*r,*r,*r,*r,f,m,m")
2648 (match_operand:V32 1 "input_operand" "f,GY,GY,Q,*rR,S,m,m,f,*rGY"))]
2649 "(TARGET_FPU && TARGET_VIS)
2650 && (register_operand (operands[0], <V32:MODE>mode)
2651 || register_operand (operands[1], <V32:MODE>mode)
2652 || fp_zero_operand (operands[1], <V32:MODE>mode))"
2654 if (GET_CODE (operands[1]) == CONST_DOUBLE
2655 && (which_alternative == 3
2656 || which_alternative == 4
2657 || which_alternative == 5))
2662 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2663 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2664 operands[1] = GEN_INT (i);
2667 switch (which_alternative)
2670 return "fmovs\t%1, %0";
2672 return "fzeros\t%0";
2676 return "sethi\t%%hi(%a1), %0";
2678 return "mov\t%1, %0";
2683 return "ld\t%1, %0";
2686 return "st\t%r1, %0";
2691 [(set_attr "type" "fpmove,fga,*,*,*,*,load,fpload,fpstore,store")])
2693 ;; Exactly the same as above, except that all `f' cases are deleted.
2694 ;; This is necessary to prevent reload from ever trying to use a `f' reg
2697 (define_insn "*movsf_no_f_insn"
2698 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r,r,r,m")
2699 (match_operand:SF 1 "input_operand" "G,Q,rR,S,m,rG"))]
2701 && (register_operand (operands[0], SFmode)
2702 || register_operand (operands[1], SFmode)
2703 || fp_zero_operand (operands[1], SFmode))"
2705 if (GET_CODE (operands[1]) == CONST_DOUBLE
2706 && (which_alternative == 1
2707 || which_alternative == 2
2708 || which_alternative == 3))
2713 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2714 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2715 operands[1] = GEN_INT (i);
2718 switch (which_alternative)
2723 return "sethi\t%%hi(%a1), %0";
2725 return "mov\t%1, %0";
2729 return "ld\t%1, %0";
2731 return "st\t%r1, %0";
2736 [(set_attr "type" "*,*,*,*,load,store")])
2738 ;; The following 3 patterns build SFmode constants in integer registers.
2740 (define_insn "*movsf_lo_sum"
2741 [(set (match_operand:SF 0 "register_operand" "=r")
2742 (lo_sum:SF (match_operand:SF 1 "register_operand" "r")
2743 (match_operand:SF 2 "const_double_operand" "S")))]
2744 "fp_high_losum_p (operands[2])"
2749 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[2]);
2750 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2751 operands[2] = GEN_INT (i);
2752 return "or\t%1, %%lo(%a2), %0";
2755 (define_insn "*movsf_high"
2756 [(set (match_operand:SF 0 "register_operand" "=r")
2757 (high:SF (match_operand:SF 1 "const_double_operand" "S")))]
2758 "fp_high_losum_p (operands[1])"
2763 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2764 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2765 operands[1] = GEN_INT (i);
2766 return "sethi\t%%hi(%1), %0";
2770 [(set (match_operand:SF 0 "register_operand" "")
2771 (match_operand:SF 1 "const_double_operand" ""))]
2772 "fp_high_losum_p (operands[1])
2773 && (GET_CODE (operands[0]) == REG
2774 && REGNO (operands[0]) < 32)"
2775 [(set (match_dup 0) (high:SF (match_dup 1)))
2776 (set (match_dup 0) (lo_sum:SF (match_dup 0) (match_dup 1)))])
2778 ;; Yes, you guessed it right, the former movsf expander.
2779 (define_expand "mov<V32:mode>"
2780 [(set (match_operand:V32 0 "general_operand" "")
2781 (match_operand:V32 1 "general_operand" ""))]
2782 "<V32:MODE>mode == SFmode || TARGET_VIS"
2784 /* Force constants into memory. */
2785 if (GET_CODE (operands[0]) == REG && CONSTANT_P (operands[1]))
2787 /* emit_group_store will send such bogosity to us when it is
2788 not storing directly into memory. So fix this up to avoid
2789 crashes in output_constant_pool. */
2790 if (operands [1] == const0_rtx)
2791 operands[1] = CONST0_RTX (<V32:MODE>mode);
2793 if ((TARGET_VIS || REGNO (operands[0]) < 32)
2794 && fp_zero_operand (operands[1], <V32:MODE>mode))
2797 /* We are able to build any SF constant in integer registers
2798 with at most 2 instructions. */
2799 if (REGNO (operands[0]) < 32
2800 && <V32:MODE>mode == SFmode)
2803 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
2807 /* Handle sets of MEM first. */
2808 if (GET_CODE (operands[0]) == MEM)
2810 if (register_operand (operands[1], <V32:MODE>mode)
2811 || fp_zero_operand (operands[1], <V32:MODE>mode))
2814 if (! reload_in_progress)
2816 operands[0] = validize_mem (operands[0]);
2817 operands[1] = force_reg (<V32:MODE>mode, operands[1]);
2821 /* Fixup PIC cases. */
2824 if (CONSTANT_P (operands[1])
2825 && pic_address_needs_scratch (operands[1]))
2826 operands[1] = legitimize_pic_address (operands[1], <V32:MODE>mode, 0);
2828 if (symbolic_operand (operands[1], <V32:MODE>mode))
2830 operands[1] = legitimize_pic_address (operands[1],
2832 (reload_in_progress ?
2842 ;; Yes, you again guessed it right, the former movdf expander.
2843 (define_expand "mov<V64:mode>"
2844 [(set (match_operand:V64 0 "general_operand" "")
2845 (match_operand:V64 1 "general_operand" ""))]
2846 "<V64:MODE>mode == DFmode || TARGET_VIS"
2848 /* Force constants into memory. */
2849 if (GET_CODE (operands[0]) == REG && CONSTANT_P (operands[1]))
2851 /* emit_group_store will send such bogosity to us when it is
2852 not storing directly into memory. So fix this up to avoid
2853 crashes in output_constant_pool. */
2854 if (operands [1] == const0_rtx)
2855 operands[1] = CONST0_RTX (<V64:MODE>mode);
2857 if ((TARGET_VIS || REGNO (operands[0]) < 32)
2858 && fp_zero_operand (operands[1], <V64:MODE>mode))
2861 /* We are able to build any DF constant in integer registers. */
2862 if (REGNO (operands[0]) < 32
2863 && <V64:MODE>mode == DFmode
2864 && (reload_completed || reload_in_progress))
2867 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
2871 /* Handle MEM cases first. */
2872 if (GET_CODE (operands[0]) == MEM)
2874 if (register_operand (operands[1], <V64:MODE>mode)
2875 || fp_zero_operand (operands[1], <V64:MODE>mode))
2878 if (! reload_in_progress)
2880 operands[0] = validize_mem (operands[0]);
2881 operands[1] = force_reg (<V64:MODE>mode, operands[1]);
2885 /* Fixup PIC cases. */
2888 if (CONSTANT_P (operands[1])
2889 && pic_address_needs_scratch (operands[1]))
2890 operands[1] = legitimize_pic_address (operands[1], <V64:MODE>mode, 0);
2892 if (symbolic_operand (operands[1], <V64:MODE>mode))
2894 operands[1] = legitimize_pic_address (operands[1],
2896 (reload_in_progress ?
2906 ;; Be careful, fmovd does not exist when !v9.
2907 (define_insn "*movdf_insn_sp32"
2908 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,W,U,T,o,e,*r,o,e,o")
2909 (match_operand:DF 1 "input_operand" "W#F,e,T,U,G,e,*rFo,*r,o#F,e"))]
2912 && (register_operand (operands[0], DFmode)
2913 || register_operand (operands[1], DFmode)
2914 || fp_zero_operand (operands[1], DFmode))"
2926 [(set_attr "type" "fpload,fpstore,load,store,*,*,*,*,*,*")
2927 (set_attr "length" "*,*,*,*,2,2,2,2,2,2")])
2929 (define_insn "*movdf_no_e_insn_sp32"
2930 [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,o,r,o")
2931 (match_operand:DF 1 "input_operand" "T,U,G,ro,r"))]
2935 && (register_operand (operands[0], DFmode)
2936 || register_operand (operands[1], DFmode)
2937 || fp_zero_operand (operands[1], DFmode))"
2944 [(set_attr "type" "load,store,*,*,*")
2945 (set_attr "length" "*,*,2,2,2")])
2947 (define_insn "*movdf_no_e_insn_v9_sp32"
2948 [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,T,r,o")
2949 (match_operand:DF 1 "input_operand" "T,U,G,ro,rG"))]
2953 && (register_operand (operands[0], DFmode)
2954 || register_operand (operands[1], DFmode)
2955 || fp_zero_operand (operands[1], DFmode))"
2962 [(set_attr "type" "load,store,store,*,*")
2963 (set_attr "length" "*,*,*,2,2")])
2965 ;; We have available v9 double floats but not 64-bit
2966 ;; integer registers and no VIS.
2967 (define_insn "*movdf_insn_v9only_novis"
2968 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,T,W,U,T,f,*r,o")
2969 (match_operand:DF 1 "input_operand" "e,W#F,G,e,T,U,o#F,*roF,*rGf"))]
2974 && (register_operand (operands[0], DFmode)
2975 || register_operand (operands[1], DFmode)
2976 || fp_zero_operand (operands[1], DFmode))"
2987 [(set_attr "type" "fpmove,load,store,store,load,store,*,*,*")
2988 (set_attr "length" "*,*,*,*,*,*,2,2,2")
2989 (set_attr "fptype" "double,*,*,*,*,*,*,*,*")])
2991 ;; We have available v9 double floats but not 64-bit
2992 ;; integer registers but we have VIS.
2993 (define_insn "*movdf_insn_v9only_vis"
2994 [(set (match_operand:V64 0 "nonimmediate_operand" "=e,e,e,T,W,U,T,f,*r,o")
2995 (match_operand:V64 1 "input_operand" "GY,e,W#F,GY,e,T,U,o#F,*roGYF,*rGYf"))]
2999 && (register_operand (operands[0], <V64:MODE>mode)
3000 || register_operand (operands[1], <V64:MODE>mode)
3001 || fp_zero_operand (operands[1], <V64:MODE>mode))"
3013 [(set_attr "type" "fga,fpmove,load,store,store,load,store,*,*,*")
3014 (set_attr "length" "*,*,*,*,*,*,*,2,2,2")
3015 (set_attr "fptype" "double,double,*,*,*,*,*,*,*,*")])
3017 ;; We have available both v9 double floats and 64-bit
3018 ;; integer registers. No VIS though.
3019 (define_insn "*movdf_insn_sp64_novis"
3020 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,W,*r,*r,m,*r")
3021 (match_operand:DF 1 "input_operand" "e,W#F,e,*rG,m,*rG,F"))]
3025 && (register_operand (operands[0], DFmode)
3026 || register_operand (operands[1], DFmode)
3027 || fp_zero_operand (operands[1], DFmode))"
3036 [(set_attr "type" "fpmove,load,store,*,load,store,*")
3037 (set_attr "length" "*,*,*,*,*,*,2")
3038 (set_attr "fptype" "double,*,*,*,*,*,*")])
3040 ;; We have available both v9 double floats and 64-bit
3041 ;; integer registers. And we have VIS.
3042 (define_insn "*movdf_insn_sp64_vis"
3043 [(set (match_operand:V64 0 "nonimmediate_operand" "=e,e,e,W,*r,*r,m,*r")
3044 (match_operand:V64 1 "input_operand" "GY,e,W#F,e,*rGY,m,*rGY,F"))]
3048 && (register_operand (operands[0], <V64:MODE>mode)
3049 || register_operand (operands[1], <V64:MODE>mode)
3050 || fp_zero_operand (operands[1], <V64:MODE>mode))"
3060 [(set_attr "type" "fga,fpmove,load,store,*,load,store,*")
3061 (set_attr "length" "*,*,*,*,*,*,*,2")
3062 (set_attr "fptype" "double,double,*,*,*,*,*,*")])
3064 (define_insn "*movdf_no_e_insn_sp64"
3065 [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m")
3066 (match_operand:DF 1 "input_operand" "r,m,rG"))]
3069 && (register_operand (operands[0], DFmode)
3070 || register_operand (operands[1], DFmode)
3071 || fp_zero_operand (operands[1], DFmode))"
3076 [(set_attr "type" "*,load,store")])
3078 ;; This pattern build DFmode constants in integer registers.
3080 [(set (match_operand:DF 0 "register_operand" "")
3081 (match_operand:DF 1 "const_double_operand" ""))]
3083 && (GET_CODE (operands[0]) == REG
3084 && REGNO (operands[0]) < 32)
3085 && ! fp_zero_operand(operands[1], DFmode)
3086 && reload_completed"
3087 [(clobber (const_int 0))]
3092 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3093 REAL_VALUE_TO_TARGET_DOUBLE (r, l);
3094 operands[0] = gen_rtx_raw_REG (DImode, REGNO (operands[0]));
3098 #if HOST_BITS_PER_WIDE_INT == 64
3101 val = ((HOST_WIDE_INT)(unsigned long)l[1] |
3102 ((HOST_WIDE_INT)(unsigned long)l[0] << 32));
3103 emit_insn (gen_movdi (operands[0], GEN_INT (val)));
3105 emit_insn (gen_movdi (operands[0],
3106 immed_double_const (l[1], l[0], DImode)));
3111 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
3114 /* Slick... but this trick loses if this subreg constant part
3115 can be done in one insn. */
3117 && !(SPARC_SETHI32_P (l[0])
3118 || SPARC_SIMM13_P (l[0])))
3120 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
3121 gen_highpart (SImode, operands[0])));
3125 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
3132 ;; Ok, now the splits to handle all the multi insn and
3133 ;; mis-aligned memory address cases.
3134 ;; In these splits please take note that we must be
3135 ;; careful when V9 but not ARCH64 because the integer
3136 ;; register DFmode cases must be handled.
3138 [(set (match_operand:V64 0 "register_operand" "")
3139 (match_operand:V64 1 "register_operand" ""))]
3142 && ((GET_CODE (operands[0]) == REG
3143 && REGNO (operands[0]) < 32)
3144 || (GET_CODE (operands[0]) == SUBREG
3145 && GET_CODE (SUBREG_REG (operands[0])) == REG
3146 && REGNO (SUBREG_REG (operands[0])) < 32))))
3147 && reload_completed"
3148 [(clobber (const_int 0))]
3150 rtx set_dest = operands[0];
3151 rtx set_src = operands[1];
3154 enum machine_mode half_mode;
3156 /* We can be expanded for DFmode or integral vector modes. */
3157 if (<V64:MODE>mode == DFmode)
3162 dest1 = gen_highpart (half_mode, set_dest);
3163 dest2 = gen_lowpart (half_mode, set_dest);
3164 src1 = gen_highpart (half_mode, set_src);
3165 src2 = gen_lowpart (half_mode, set_src);
3167 /* Now emit using the real source and destination we found, swapping
3168 the order if we detect overlap. */
3169 if (reg_overlap_mentioned_p (dest1, src2))
3171 emit_move_insn_1 (dest2, src2);
3172 emit_move_insn_1 (dest1, src1);
3176 emit_move_insn_1 (dest1, src1);
3177 emit_move_insn_1 (dest2, src2);
3183 [(set (match_operand:V64 0 "register_operand" "")
3184 (match_operand:V64 1 "memory_operand" ""))]
3187 && (((REGNO (operands[0]) % 2) != 0)
3188 || ! mem_min_alignment (operands[1], 8))
3189 && offsettable_memref_p (operands[1])"
3190 [(clobber (const_int 0))]
3192 enum machine_mode half_mode;
3195 /* We can be expanded for DFmode or integral vector modes. */
3196 if (<V64:MODE>mode == DFmode)
3201 word0 = adjust_address (operands[1], half_mode, 0);
3202 word1 = adjust_address (operands[1], half_mode, 4);
3204 if (reg_overlap_mentioned_p (gen_highpart (half_mode, operands[0]), word1))
3206 emit_move_insn_1 (gen_lowpart (half_mode, operands[0]), word1);
3207 emit_move_insn_1 (gen_highpart (half_mode, operands[0]), word0);
3211 emit_move_insn_1 (gen_highpart (half_mode, operands[0]), word0);
3212 emit_move_insn_1 (gen_lowpart (half_mode, operands[0]), word1);
3218 [(set (match_operand:V64 0 "memory_operand" "")
3219 (match_operand:V64 1 "register_operand" ""))]
3222 && (((REGNO (operands[1]) % 2) != 0)
3223 || ! mem_min_alignment (operands[0], 8))
3224 && offsettable_memref_p (operands[0])"
3225 [(clobber (const_int 0))]
3227 enum machine_mode half_mode;
3230 /* We can be expanded for DFmode or integral vector modes. */
3231 if (<V64:MODE>mode == DFmode)
3236 word0 = adjust_address (operands[0], half_mode, 0);
3237 word1 = adjust_address (operands[0], half_mode, 4);
3239 emit_move_insn_1 (word0, gen_highpart (half_mode, operands[1]));
3240 emit_move_insn_1 (word1, gen_lowpart (half_mode, operands[1]));
3245 [(set (match_operand:V64 0 "memory_operand" "")
3246 (match_operand:V64 1 "fp_zero_operand" ""))]
3250 && ! mem_min_alignment (operands[0], 8)))
3251 && offsettable_memref_p (operands[0])"
3252 [(clobber (const_int 0))]
3254 enum machine_mode half_mode;
3257 /* We can be expanded for DFmode or integral vector modes. */
3258 if (<V64:MODE>mode == DFmode)
3263 dest1 = adjust_address (operands[0], half_mode, 0);
3264 dest2 = adjust_address (operands[0], half_mode, 4);
3266 emit_move_insn_1 (dest1, CONST0_RTX (half_mode));
3267 emit_move_insn_1 (dest2, CONST0_RTX (half_mode));
3272 [(set (match_operand:V64 0 "register_operand" "")
3273 (match_operand:V64 1 "fp_zero_operand" ""))]
3276 && ((GET_CODE (operands[0]) == REG
3277 && REGNO (operands[0]) < 32)
3278 || (GET_CODE (operands[0]) == SUBREG
3279 && GET_CODE (SUBREG_REG (operands[0])) == REG
3280 && REGNO (SUBREG_REG (operands[0])) < 32))"
3281 [(clobber (const_int 0))]
3283 enum machine_mode half_mode;
3284 rtx set_dest = operands[0];
3287 /* We can be expanded for DFmode or integral vector modes. */
3288 if (<V64:MODE>mode == DFmode)
3293 dest1 = gen_highpart (half_mode, set_dest);
3294 dest2 = gen_lowpart (half_mode, set_dest);
3295 emit_move_insn_1 (dest1, CONST0_RTX (half_mode));
3296 emit_move_insn_1 (dest2, CONST0_RTX (half_mode));
3300 (define_expand "movtf"
3301 [(set (match_operand:TF 0 "general_operand" "")
3302 (match_operand:TF 1 "general_operand" ""))]
3305 /* Force TFmode constants into memory. */
3306 if (GET_CODE (operands[0]) == REG
3307 && CONSTANT_P (operands[1]))
3309 /* emit_group_store will send such bogosity to us when it is
3310 not storing directly into memory. So fix this up to avoid
3311 crashes in output_constant_pool. */
3312 if (operands [1] == const0_rtx)
3313 operands[1] = CONST0_RTX (TFmode);
3315 if (TARGET_VIS && fp_zero_operand (operands[1], TFmode))
3318 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
3322 /* Handle MEM cases first, note that only v9 guarantees
3323 full 16-byte alignment for quads. */
3324 if (GET_CODE (operands[0]) == MEM)
3326 if (register_operand (operands[1], TFmode)
3327 || fp_zero_operand (operands[1], TFmode))
3330 if (! reload_in_progress)
3332 operands[0] = validize_mem (operands[0]);
3333 operands[1] = force_reg (TFmode, operands[1]);
3337 /* Fixup PIC cases. */
3340 if (CONSTANT_P (operands[1])
3341 && pic_address_needs_scratch (operands[1]))
3342 operands[1] = legitimize_pic_address (operands[1], TFmode, 0);
3344 if (symbolic_operand (operands[1], TFmode))
3346 operands[1] = legitimize_pic_address (operands[1],
3348 (reload_in_progress ?
3358 ;; Be careful, fmovq and {st,ld}{x,q} do not exist when !arch64 so
3359 ;; we must split them all. :-(
3360 (define_insn "*movtf_insn_sp32"
3361 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,U,r")
3362 (match_operand:TF 1 "input_operand" "oe,GeUr,o,roG"))]
3366 && (register_operand (operands[0], TFmode)
3367 || register_operand (operands[1], TFmode)
3368 || fp_zero_operand (operands[1], TFmode))"
3370 [(set_attr "length" "4")])
3372 (define_insn "*movtf_insn_vis_sp32"
3373 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,U,r")
3374 (match_operand:TF 1 "input_operand" "Goe,GeUr,o,roG"))]
3378 && (register_operand (operands[0], TFmode)
3379 || register_operand (operands[1], TFmode)
3380 || fp_zero_operand (operands[1], TFmode))"
3382 [(set_attr "length" "4")])
3384 ;; Exactly the same as above, except that all `e' cases are deleted.
3385 ;; This is necessary to prevent reload from ever trying to use a `e' reg
3388 (define_insn "*movtf_no_e_insn_sp32"
3389 [(set (match_operand:TF 0 "nonimmediate_operand" "=o,U,o,r,o")
3390 (match_operand:TF 1 "input_operand" "G,o,U,roG,r"))]
3393 && (register_operand (operands[0], TFmode)
3394 || register_operand (operands[1], TFmode)
3395 || fp_zero_operand (operands[1], TFmode))"
3397 [(set_attr "length" "4")])
3399 ;; Now handle the float reg cases directly when arch64,
3400 ;; hard_quad, and proper reg number alignment are all true.
3401 (define_insn "*movtf_insn_hq_sp64"
3402 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,e,m,o,r")
3403 (match_operand:TF 1 "input_operand" "e,m,e,Gr,roG"))]
3408 && (register_operand (operands[0], TFmode)
3409 || register_operand (operands[1], TFmode)
3410 || fp_zero_operand (operands[1], TFmode))"
3417 [(set_attr "type" "fpmove,fpload,fpstore,*,*")
3418 (set_attr "length" "*,*,*,2,2")])
3420 (define_insn "*movtf_insn_hq_vis_sp64"
3421 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,e,m,eo,r,o")
3422 (match_operand:TF 1 "input_operand" "e,m,e,G,roG,r"))]
3427 && (register_operand (operands[0], TFmode)
3428 || register_operand (operands[1], TFmode)
3429 || fp_zero_operand (operands[1], TFmode))"
3437 [(set_attr "type" "fpmove,fpload,fpstore,*,*,*")
3438 (set_attr "length" "*,*,*,2,2,2")])
3440 ;; Now we allow the integer register cases even when
3441 ;; only arch64 is true.
3442 (define_insn "*movtf_insn_sp64"
3443 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,r")
3444 (match_operand:TF 1 "input_operand" "oe,Ger,orG"))]
3448 && ! TARGET_HARD_QUAD
3449 && (register_operand (operands[0], TFmode)
3450 || register_operand (operands[1], TFmode)
3451 || fp_zero_operand (operands[1], TFmode))"
3453 [(set_attr "length" "2")])
3455 (define_insn "*movtf_insn_vis_sp64"
3456 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,r")
3457 (match_operand:TF 1 "input_operand" "Goe,Ger,orG"))]
3461 && ! TARGET_HARD_QUAD
3462 && (register_operand (operands[0], TFmode)
3463 || register_operand (operands[1], TFmode)
3464 || fp_zero_operand (operands[1], TFmode))"
3466 [(set_attr "length" "2")])
3468 (define_insn "*movtf_no_e_insn_sp64"
3469 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o")
3470 (match_operand:TF 1 "input_operand" "orG,rG"))]
3473 && (register_operand (operands[0], TFmode)
3474 || register_operand (operands[1], TFmode)
3475 || fp_zero_operand (operands[1], TFmode))"
3477 [(set_attr "length" "2")])
3479 ;; Now all the splits to handle multi-insn TF mode moves.
3481 [(set (match_operand:TF 0 "register_operand" "")
3482 (match_operand:TF 1 "register_operand" ""))]
3486 && ! TARGET_HARD_QUAD)
3487 || ! fp_register_operand (operands[0], TFmode))"
3488 [(clobber (const_int 0))]
3490 rtx set_dest = operands[0];
3491 rtx set_src = operands[1];
3495 dest1 = gen_df_reg (set_dest, 0);
3496 dest2 = gen_df_reg (set_dest, 1);
3497 src1 = gen_df_reg (set_src, 0);
3498 src2 = gen_df_reg (set_src, 1);
3500 /* Now emit using the real source and destination we found, swapping
3501 the order if we detect overlap. */
3502 if (reg_overlap_mentioned_p (dest1, src2))
3504 emit_insn (gen_movdf (dest2, src2));
3505 emit_insn (gen_movdf (dest1, src1));
3509 emit_insn (gen_movdf (dest1, src1));
3510 emit_insn (gen_movdf (dest2, src2));
3516 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3517 (match_operand:TF 1 "fp_zero_operand" ""))]
3519 [(clobber (const_int 0))]
3521 rtx set_dest = operands[0];
3524 switch (GET_CODE (set_dest))
3527 dest1 = gen_df_reg (set_dest, 0);
3528 dest2 = gen_df_reg (set_dest, 1);
3531 dest1 = adjust_address (set_dest, DFmode, 0);
3532 dest2 = adjust_address (set_dest, DFmode, 8);
3538 emit_insn (gen_movdf (dest1, CONST0_RTX (DFmode)));
3539 emit_insn (gen_movdf (dest2, CONST0_RTX (DFmode)));
3544 [(set (match_operand:TF 0 "register_operand" "")
3545 (match_operand:TF 1 "memory_operand" ""))]
3547 && offsettable_memref_p (operands[1])
3549 || ! TARGET_HARD_QUAD
3550 || ! fp_register_operand (operands[0], TFmode)))"
3551 [(clobber (const_int 0))]
3553 rtx word0 = adjust_address (operands[1], DFmode, 0);
3554 rtx word1 = adjust_address (operands[1], DFmode, 8);
3555 rtx set_dest, dest1, dest2;
3557 set_dest = operands[0];
3559 dest1 = gen_df_reg (set_dest, 0);
3560 dest2 = gen_df_reg (set_dest, 1);
3562 /* Now output, ordering such that we don't clobber any registers
3563 mentioned in the address. */
3564 if (reg_overlap_mentioned_p (dest1, word1))
3567 emit_insn (gen_movdf (dest2, word1));
3568 emit_insn (gen_movdf (dest1, word0));
3572 emit_insn (gen_movdf (dest1, word0));
3573 emit_insn (gen_movdf (dest2, word1));
3579 [(set (match_operand:TF 0 "memory_operand" "")
3580 (match_operand:TF 1 "register_operand" ""))]
3582 && offsettable_memref_p (operands[0])
3584 || ! TARGET_HARD_QUAD
3585 || ! fp_register_operand (operands[1], TFmode)))"
3586 [(clobber (const_int 0))]
3588 rtx set_src = operands[1];
3590 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 0),
3591 gen_df_reg (set_src, 0)));
3592 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 8),
3593 gen_df_reg (set_src, 1)));
3597 ;; SPARC V9 conditional move instructions.
3599 ;; We can handle larger constants here for some flavors, but for now we keep
3600 ;; it simple and only allow those constants supported by all flavors.
3601 ;; Note that emit_conditional_move canonicalizes operands 2,3 so that operand
3602 ;; 3 contains the constant if one is present, but we handle either for
3603 ;; generality (sparc.c puts a constant in operand 2).
3605 (define_expand "movqicc"
3606 [(set (match_operand:QI 0 "register_operand" "")
3607 (if_then_else:QI (match_operand 1 "comparison_operator" "")
3608 (match_operand:QI 2 "arith10_operand" "")
3609 (match_operand:QI 3 "arith10_operand" "")))]
3612 enum rtx_code code = GET_CODE (operands[1]);
3614 if (GET_MODE (sparc_compare_op0) == DImode
3618 if (sparc_compare_op1 == const0_rtx
3619 && GET_CODE (sparc_compare_op0) == REG
3620 && GET_MODE (sparc_compare_op0) == DImode
3621 && v9_regcmp_p (code))
3623 operands[1] = gen_rtx_fmt_ee (code, DImode,
3624 sparc_compare_op0, sparc_compare_op1);
3628 rtx cc_reg = gen_compare_reg (code,
3629 sparc_compare_op0, sparc_compare_op1);
3630 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3634 (define_expand "movhicc"
3635 [(set (match_operand:HI 0 "register_operand" "")
3636 (if_then_else:HI (match_operand 1 "comparison_operator" "")
3637 (match_operand:HI 2 "arith10_operand" "")
3638 (match_operand:HI 3 "arith10_operand" "")))]
3641 enum rtx_code code = GET_CODE (operands[1]);
3643 if (GET_MODE (sparc_compare_op0) == DImode
3647 if (sparc_compare_op1 == const0_rtx
3648 && GET_CODE (sparc_compare_op0) == REG
3649 && GET_MODE (sparc_compare_op0) == DImode
3650 && v9_regcmp_p (code))
3652 operands[1] = gen_rtx_fmt_ee (code, DImode,
3653 sparc_compare_op0, sparc_compare_op1);
3657 rtx cc_reg = gen_compare_reg (code,
3658 sparc_compare_op0, sparc_compare_op1);
3659 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3663 (define_expand "movsicc"
3664 [(set (match_operand:SI 0 "register_operand" "")
3665 (if_then_else:SI (match_operand 1 "comparison_operator" "")
3666 (match_operand:SI 2 "arith10_operand" "")
3667 (match_operand:SI 3 "arith10_operand" "")))]
3670 enum rtx_code code = GET_CODE (operands[1]);
3671 enum machine_mode op0_mode = GET_MODE (sparc_compare_op0);
3673 if (sparc_compare_op1 == const0_rtx
3674 && GET_CODE (sparc_compare_op0) == REG
3675 && (TARGET_ARCH64 && op0_mode == DImode && v9_regcmp_p (code)))
3677 operands[1] = gen_rtx_fmt_ee (code, op0_mode,
3678 sparc_compare_op0, sparc_compare_op1);
3682 rtx cc_reg = gen_compare_reg (code,
3683 sparc_compare_op0, sparc_compare_op1);
3684 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg),
3685 cc_reg, const0_rtx);
3689 (define_expand "movdicc"
3690 [(set (match_operand:DI 0 "register_operand" "")
3691 (if_then_else:DI (match_operand 1 "comparison_operator" "")
3692 (match_operand:DI 2 "arith10_double_operand" "")
3693 (match_operand:DI 3 "arith10_double_operand" "")))]
3696 enum rtx_code code = GET_CODE (operands[1]);
3698 if (sparc_compare_op1 == const0_rtx
3699 && GET_CODE (sparc_compare_op0) == REG
3700 && GET_MODE (sparc_compare_op0) == DImode
3701 && v9_regcmp_p (code))
3703 operands[1] = gen_rtx_fmt_ee (code, DImode,
3704 sparc_compare_op0, sparc_compare_op1);
3708 rtx cc_reg = gen_compare_reg (code,
3709 sparc_compare_op0, sparc_compare_op1);
3710 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg),
3711 cc_reg, const0_rtx);
3715 (define_expand "movsfcc"
3716 [(set (match_operand:SF 0 "register_operand" "")
3717 (if_then_else:SF (match_operand 1 "comparison_operator" "")
3718 (match_operand:SF 2 "register_operand" "")
3719 (match_operand:SF 3 "register_operand" "")))]
3720 "TARGET_V9 && TARGET_FPU"
3722 enum rtx_code code = GET_CODE (operands[1]);
3724 if (GET_MODE (sparc_compare_op0) == DImode
3728 if (sparc_compare_op1 == const0_rtx
3729 && GET_CODE (sparc_compare_op0) == REG
3730 && GET_MODE (sparc_compare_op0) == DImode
3731 && v9_regcmp_p (code))
3733 operands[1] = gen_rtx_fmt_ee (code, DImode,
3734 sparc_compare_op0, sparc_compare_op1);
3738 rtx cc_reg = gen_compare_reg (code,
3739 sparc_compare_op0, sparc_compare_op1);
3740 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3744 (define_expand "movdfcc"
3745 [(set (match_operand:DF 0 "register_operand" "")
3746 (if_then_else:DF (match_operand 1 "comparison_operator" "")
3747 (match_operand:DF 2 "register_operand" "")
3748 (match_operand:DF 3 "register_operand" "")))]
3749 "TARGET_V9 && TARGET_FPU"
3751 enum rtx_code code = GET_CODE (operands[1]);
3753 if (GET_MODE (sparc_compare_op0) == DImode
3757 if (sparc_compare_op1 == const0_rtx
3758 && GET_CODE (sparc_compare_op0) == REG
3759 && GET_MODE (sparc_compare_op0) == DImode
3760 && v9_regcmp_p (code))
3762 operands[1] = gen_rtx_fmt_ee (code, DImode,
3763 sparc_compare_op0, sparc_compare_op1);
3767 rtx cc_reg = gen_compare_reg (code,
3768 sparc_compare_op0, sparc_compare_op1);
3769 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3773 (define_expand "movtfcc"
3774 [(set (match_operand:TF 0 "register_operand" "")
3775 (if_then_else:TF (match_operand 1 "comparison_operator" "")
3776 (match_operand:TF 2 "register_operand" "")
3777 (match_operand:TF 3 "register_operand" "")))]
3778 "TARGET_V9 && TARGET_FPU"
3780 enum rtx_code code = GET_CODE (operands[1]);
3782 if (GET_MODE (sparc_compare_op0) == DImode
3786 if (sparc_compare_op1 == const0_rtx
3787 && GET_CODE (sparc_compare_op0) == REG
3788 && GET_MODE (sparc_compare_op0) == DImode
3789 && v9_regcmp_p (code))
3791 operands[1] = gen_rtx_fmt_ee (code, DImode,
3792 sparc_compare_op0, sparc_compare_op1);
3796 rtx cc_reg = gen_compare_reg (code,
3797 sparc_compare_op0, sparc_compare_op1);
3798 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3802 ;; Conditional move define_insns.
3804 (define_insn "*movqi_cc_sp64"
3805 [(set (match_operand:QI 0 "register_operand" "=r,r")
3806 (if_then_else:QI (match_operator 1 "comparison_operator"
3807 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3809 (match_operand:QI 3 "arith11_operand" "rL,0")
3810 (match_operand:QI 4 "arith11_operand" "0,rL")))]
3814 mov%c1\t%x2, %4, %0"
3815 [(set_attr "type" "cmove")])
3817 (define_insn "*movhi_cc_sp64"
3818 [(set (match_operand:HI 0 "register_operand" "=r,r")
3819 (if_then_else:HI (match_operator 1 "comparison_operator"
3820 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3822 (match_operand:HI 3 "arith11_operand" "rL,0")
3823 (match_operand:HI 4 "arith11_operand" "0,rL")))]
3827 mov%c1\t%x2, %4, %0"
3828 [(set_attr "type" "cmove")])
3830 (define_insn "*movsi_cc_sp64"
3831 [(set (match_operand:SI 0 "register_operand" "=r,r")
3832 (if_then_else:SI (match_operator 1 "comparison_operator"
3833 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3835 (match_operand:SI 3 "arith11_operand" "rL,0")
3836 (match_operand:SI 4 "arith11_operand" "0,rL")))]
3840 mov%c1\t%x2, %4, %0"
3841 [(set_attr "type" "cmove")])
3843 ;; ??? The constraints of operands 3,4 need work.
3844 (define_insn "*movdi_cc_sp64"
3845 [(set (match_operand:DI 0 "register_operand" "=r,r")
3846 (if_then_else:DI (match_operator 1 "comparison_operator"
3847 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3849 (match_operand:DI 3 "arith11_double_operand" "rLH,0")
3850 (match_operand:DI 4 "arith11_double_operand" "0,rLH")))]
3854 mov%c1\t%x2, %4, %0"
3855 [(set_attr "type" "cmove")])
3857 (define_insn "*movdi_cc_sp64_trunc"
3858 [(set (match_operand:SI 0 "register_operand" "=r,r")
3859 (if_then_else:SI (match_operator 1 "comparison_operator"
3860 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3862 (match_operand:SI 3 "arith11_double_operand" "rLH,0")
3863 (match_operand:SI 4 "arith11_double_operand" "0,rLH")))]
3867 mov%c1\t%x2, %4, %0"
3868 [(set_attr "type" "cmove")])
3870 (define_insn "*movsf_cc_sp64"
3871 [(set (match_operand:SF 0 "register_operand" "=f,f")
3872 (if_then_else:SF (match_operator 1 "comparison_operator"
3873 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3875 (match_operand:SF 3 "register_operand" "f,0")
3876 (match_operand:SF 4 "register_operand" "0,f")))]
3877 "TARGET_V9 && TARGET_FPU"
3879 fmovs%C1\t%x2, %3, %0
3880 fmovs%c1\t%x2, %4, %0"
3881 [(set_attr "type" "fpcmove")])
3883 (define_insn "movdf_cc_sp64"
3884 [(set (match_operand:DF 0 "register_operand" "=e,e")
3885 (if_then_else:DF (match_operator 1 "comparison_operator"
3886 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3888 (match_operand:DF 3 "register_operand" "e,0")
3889 (match_operand:DF 4 "register_operand" "0,e")))]
3890 "TARGET_V9 && TARGET_FPU"
3892 fmovd%C1\t%x2, %3, %0
3893 fmovd%c1\t%x2, %4, %0"
3894 [(set_attr "type" "fpcmove")
3895 (set_attr "fptype" "double")])
3897 (define_insn "*movtf_cc_hq_sp64"
3898 [(set (match_operand:TF 0 "register_operand" "=e,e")
3899 (if_then_else:TF (match_operator 1 "comparison_operator"
3900 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3902 (match_operand:TF 3 "register_operand" "e,0")
3903 (match_operand:TF 4 "register_operand" "0,e")))]
3904 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
3906 fmovq%C1\t%x2, %3, %0
3907 fmovq%c1\t%x2, %4, %0"
3908 [(set_attr "type" "fpcmove")])
3910 (define_insn_and_split "*movtf_cc_sp64"
3911 [(set (match_operand:TF 0 "register_operand" "=e,e")
3912 (if_then_else:TF (match_operator 1 "comparison_operator"
3913 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3915 (match_operand:TF 3 "register_operand" "e,0")
3916 (match_operand:TF 4 "register_operand" "0,e")))]
3917 "TARGET_V9 && TARGET_FPU && !TARGET_HARD_QUAD"
3919 "&& reload_completed"
3920 [(clobber (const_int 0))]
3922 rtx set_dest = operands[0];
3923 rtx set_srca = operands[3];
3924 rtx set_srcb = operands[4];
3925 int third = rtx_equal_p (set_dest, set_srca);
3927 rtx srca1, srca2, srcb1, srcb2;
3929 dest1 = gen_df_reg (set_dest, 0);
3930 dest2 = gen_df_reg (set_dest, 1);
3931 srca1 = gen_df_reg (set_srca, 0);
3932 srca2 = gen_df_reg (set_srca, 1);
3933 srcb1 = gen_df_reg (set_srcb, 0);
3934 srcb2 = gen_df_reg (set_srcb, 1);
3936 /* Now emit using the real source and destination we found, swapping
3937 the order if we detect overlap. */
3938 if ((third && reg_overlap_mentioned_p (dest1, srcb2))
3939 || (!third && reg_overlap_mentioned_p (dest1, srca2)))
3941 emit_insn (gen_movdf_cc_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
3942 emit_insn (gen_movdf_cc_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
3946 emit_insn (gen_movdf_cc_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
3947 emit_insn (gen_movdf_cc_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
3951 [(set_attr "length" "2")])
3953 (define_insn "*movqi_cc_reg_sp64"
3954 [(set (match_operand:QI 0 "register_operand" "=r,r")
3955 (if_then_else:QI (match_operator 1 "v9_regcmp_op"
3956 [(match_operand:DI 2 "register_operand" "r,r")
3958 (match_operand:QI 3 "arith10_operand" "rM,0")
3959 (match_operand:QI 4 "arith10_operand" "0,rM")))]
3962 movr%D1\t%2, %r3, %0
3963 movr%d1\t%2, %r4, %0"
3964 [(set_attr "type" "cmove")])
3966 (define_insn "*movhi_cc_reg_sp64"
3967 [(set (match_operand:HI 0 "register_operand" "=r,r")
3968 (if_then_else:HI (match_operator 1 "v9_regcmp_op"
3969 [(match_operand:DI 2 "register_operand" "r,r")
3971 (match_operand:HI 3 "arith10_operand" "rM,0")
3972 (match_operand:HI 4 "arith10_operand" "0,rM")))]
3975 movr%D1\t%2, %r3, %0
3976 movr%d1\t%2, %r4, %0"
3977 [(set_attr "type" "cmove")])
3979 (define_insn "*movsi_cc_reg_sp64"
3980 [(set (match_operand:SI 0 "register_operand" "=r,r")
3981 (if_then_else:SI (match_operator 1 "v9_regcmp_op"
3982 [(match_operand:DI 2 "register_operand" "r,r")
3984 (match_operand:SI 3 "arith10_operand" "rM,0")
3985 (match_operand:SI 4 "arith10_operand" "0,rM")))]
3988 movr%D1\t%2, %r3, %0
3989 movr%d1\t%2, %r4, %0"
3990 [(set_attr "type" "cmove")])
3992 ;; ??? The constraints of operands 3,4 need work.
3993 (define_insn "*movdi_cc_reg_sp64"
3994 [(set (match_operand:DI 0 "register_operand" "=r,r")
3995 (if_then_else:DI (match_operator 1 "v9_regcmp_op"
3996 [(match_operand:DI 2 "register_operand" "r,r")
3998 (match_operand:DI 3 "arith10_double_operand" "rMH,0")
3999 (match_operand:DI 4 "arith10_double_operand" "0,rMH")))]
4002 movr%D1\t%2, %r3, %0
4003 movr%d1\t%2, %r4, %0"
4004 [(set_attr "type" "cmove")])
4006 (define_insn "*movdi_cc_reg_sp64_trunc"
4007 [(set (match_operand:SI 0 "register_operand" "=r,r")
4008 (if_then_else:SI (match_operator 1 "v9_regcmp_op"
4009 [(match_operand:DI 2 "register_operand" "r,r")
4011 (match_operand:SI 3 "arith10_double_operand" "rMH,0")
4012 (match_operand:SI 4 "arith10_double_operand" "0,rMH")))]
4015 movr%D1\t%2, %r3, %0
4016 movr%d1\t%2, %r4, %0"
4017 [(set_attr "type" "cmove")])
4019 (define_insn "*movsf_cc_reg_sp64"
4020 [(set (match_operand:SF 0 "register_operand" "=f,f")
4021 (if_then_else:SF (match_operator 1 "v9_regcmp_op"
4022 [(match_operand:DI 2 "register_operand" "r,r")
4024 (match_operand:SF 3 "register_operand" "f,0")
4025 (match_operand:SF 4 "register_operand" "0,f")))]
4026 "TARGET_ARCH64 && TARGET_FPU"
4028 fmovrs%D1\t%2, %3, %0
4029 fmovrs%d1\t%2, %4, %0"
4030 [(set_attr "type" "fpcrmove")])
4032 (define_insn "movdf_cc_reg_sp64"
4033 [(set (match_operand:DF 0 "register_operand" "=e,e")
4034 (if_then_else:DF (match_operator 1 "v9_regcmp_op"
4035 [(match_operand:DI 2 "register_operand" "r,r")
4037 (match_operand:DF 3 "register_operand" "e,0")
4038 (match_operand:DF 4 "register_operand" "0,e")))]
4039 "TARGET_ARCH64 && TARGET_FPU"
4041 fmovrd%D1\t%2, %3, %0
4042 fmovrd%d1\t%2, %4, %0"
4043 [(set_attr "type" "fpcrmove")
4044 (set_attr "fptype" "double")])
4046 (define_insn "*movtf_cc_reg_hq_sp64"
4047 [(set (match_operand:TF 0 "register_operand" "=e,e")
4048 (if_then_else:TF (match_operator 1 "v9_regcmp_op"
4049 [(match_operand:DI 2 "register_operand" "r,r")
4051 (match_operand:TF 3 "register_operand" "e,0")
4052 (match_operand:TF 4 "register_operand" "0,e")))]
4053 "TARGET_ARCH64 && TARGET_FPU && TARGET_HARD_QUAD"
4055 fmovrq%D1\t%2, %3, %0
4056 fmovrq%d1\t%2, %4, %0"
4057 [(set_attr "type" "fpcrmove")])
4059 (define_insn_and_split "*movtf_cc_reg_sp64"
4060 [(set (match_operand:TF 0 "register_operand" "=e,e")
4061 (if_then_else:TF (match_operator 1 "v9_regcmp_op"
4062 [(match_operand:DI 2 "register_operand" "r,r")
4064 (match_operand:TF 3 "register_operand" "e,0")
4065 (match_operand:TF 4 "register_operand" "0,e")))]
4066 "TARGET_ARCH64 && TARGET_FPU && ! TARGET_HARD_QUAD"
4068 "&& reload_completed"
4069 [(clobber (const_int 0))]
4071 rtx set_dest = operands[0];
4072 rtx set_srca = operands[3];
4073 rtx set_srcb = operands[4];
4074 int third = rtx_equal_p (set_dest, set_srca);
4076 rtx srca1, srca2, srcb1, srcb2;
4078 dest1 = gen_df_reg (set_dest, 0);
4079 dest2 = gen_df_reg (set_dest, 1);
4080 srca1 = gen_df_reg (set_srca, 0);
4081 srca2 = gen_df_reg (set_srca, 1);
4082 srcb1 = gen_df_reg (set_srcb, 0);
4083 srcb2 = gen_df_reg (set_srcb, 1);
4085 /* Now emit using the real source and destination we found, swapping
4086 the order if we detect overlap. */
4087 if ((third && reg_overlap_mentioned_p (dest1, srcb2))
4088 || (!third && reg_overlap_mentioned_p (dest1, srca2)))
4090 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
4091 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
4095 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
4096 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
4100 [(set_attr "length" "2")])
4103 ;;- zero extension instructions
4105 ;; These patterns originally accepted general_operands, however, slightly
4106 ;; better code is generated by only accepting register_operands, and then
4107 ;; letting combine generate the ldu[hb] insns.
4109 (define_expand "zero_extendhisi2"
4110 [(set (match_operand:SI 0 "register_operand" "")
4111 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
4114 rtx temp = gen_reg_rtx (SImode);
4115 rtx shift_16 = GEN_INT (16);
4116 int op1_subbyte = 0;
4118 if (GET_CODE (operand1) == SUBREG)
4120 op1_subbyte = SUBREG_BYTE (operand1);
4121 op1_subbyte /= GET_MODE_SIZE (SImode);
4122 op1_subbyte *= GET_MODE_SIZE (SImode);
4123 operand1 = XEXP (operand1, 0);
4126 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4128 emit_insn (gen_lshrsi3 (operand0, temp, shift_16));
4132 (define_insn "*zero_extendhisi2_insn"
4133 [(set (match_operand:SI 0 "register_operand" "=r")
4134 (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
4137 [(set_attr "type" "load")
4138 (set_attr "us3load_type" "3cycle")])
4140 (define_expand "zero_extendqihi2"
4141 [(set (match_operand:HI 0 "register_operand" "")
4142 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
4146 (define_insn "*zero_extendqihi2_insn"
4147 [(set (match_operand:HI 0 "register_operand" "=r,r")
4148 (zero_extend:HI (match_operand:QI 1 "input_operand" "r,m")))]
4149 "GET_CODE (operands[1]) != CONST_INT"
4153 [(set_attr "type" "*,load")
4154 (set_attr "us3load_type" "*,3cycle")])
4156 (define_expand "zero_extendqisi2"
4157 [(set (match_operand:SI 0 "register_operand" "")
4158 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
4162 (define_insn "*zero_extendqisi2_insn"
4163 [(set (match_operand:SI 0 "register_operand" "=r,r")
4164 (zero_extend:SI (match_operand:QI 1 "input_operand" "r,m")))]
4165 "GET_CODE (operands[1]) != CONST_INT"
4169 [(set_attr "type" "*,load")
4170 (set_attr "us3load_type" "*,3cycle")])
4172 (define_expand "zero_extendqidi2"
4173 [(set (match_operand:DI 0 "register_operand" "")
4174 (zero_extend:DI (match_operand:QI 1 "register_operand" "")))]
4178 (define_insn "*zero_extendqidi2_insn"
4179 [(set (match_operand:DI 0 "register_operand" "=r,r")
4180 (zero_extend:DI (match_operand:QI 1 "input_operand" "r,m")))]
4181 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
4185 [(set_attr "type" "*,load")
4186 (set_attr "us3load_type" "*,3cycle")])
4188 (define_expand "zero_extendhidi2"
4189 [(set (match_operand:DI 0 "register_operand" "")
4190 (zero_extend:DI (match_operand:HI 1 "register_operand" "")))]
4193 rtx temp = gen_reg_rtx (DImode);
4194 rtx shift_48 = GEN_INT (48);
4195 int op1_subbyte = 0;
4197 if (GET_CODE (operand1) == SUBREG)
4199 op1_subbyte = SUBREG_BYTE (operand1);
4200 op1_subbyte /= GET_MODE_SIZE (DImode);
4201 op1_subbyte *= GET_MODE_SIZE (DImode);
4202 operand1 = XEXP (operand1, 0);
4205 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
4207 emit_insn (gen_lshrdi3 (operand0, temp, shift_48));
4211 (define_insn "*zero_extendhidi2_insn"
4212 [(set (match_operand:DI 0 "register_operand" "=r")
4213 (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
4216 [(set_attr "type" "load")
4217 (set_attr "us3load_type" "3cycle")])
4220 ;; ??? Write truncdisi pattern using sra?
4222 (define_expand "zero_extendsidi2"
4223 [(set (match_operand:DI 0 "register_operand" "")
4224 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
4228 (define_insn "*zero_extendsidi2_insn_sp64"
4229 [(set (match_operand:DI 0 "register_operand" "=r,r")
4230 (zero_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
4231 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
4235 [(set_attr "type" "shift,load")])
4237 (define_insn_and_split "*zero_extendsidi2_insn_sp32"
4238 [(set (match_operand:DI 0 "register_operand" "=r")
4239 (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
4242 "&& reload_completed"
4243 [(set (match_dup 2) (match_dup 3))
4244 (set (match_dup 4) (match_dup 5))]
4248 dest1 = gen_highpart (SImode, operands[0]);
4249 dest2 = gen_lowpart (SImode, operands[0]);
4251 /* Swap the order in case of overlap. */
4252 if (REGNO (dest1) == REGNO (operands[1]))
4254 operands[2] = dest2;
4255 operands[3] = operands[1];
4256 operands[4] = dest1;
4257 operands[5] = const0_rtx;
4261 operands[2] = dest1;
4262 operands[3] = const0_rtx;
4263 operands[4] = dest2;
4264 operands[5] = operands[1];
4267 [(set_attr "length" "2")])
4269 ;; Simplify comparisons of extended values.
4271 (define_insn "*cmp_zero_extendqisi2"
4273 (compare:CC (zero_extend:SI (match_operand:QI 0 "register_operand" "r"))
4276 "andcc\t%0, 0xff, %%g0"
4277 [(set_attr "type" "compare")])
4279 (define_insn "*cmp_zero_qi"
4281 (compare:CC (match_operand:QI 0 "register_operand" "r")
4284 "andcc\t%0, 0xff, %%g0"
4285 [(set_attr "type" "compare")])
4287 (define_insn "*cmp_zero_extendqisi2_set"
4289 (compare:CC (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
4291 (set (match_operand:SI 0 "register_operand" "=r")
4292 (zero_extend:SI (match_dup 1)))]
4294 "andcc\t%1, 0xff, %0"
4295 [(set_attr "type" "compare")])
4297 (define_insn "*cmp_zero_extendqisi2_andcc_set"
4299 (compare:CC (and:SI (match_operand:SI 1 "register_operand" "r")
4302 (set (match_operand:SI 0 "register_operand" "=r")
4303 (zero_extend:SI (subreg:QI (match_dup 1) 0)))]
4305 "andcc\t%1, 0xff, %0"
4306 [(set_attr "type" "compare")])
4308 (define_insn "*cmp_zero_extendqidi2"
4310 (compare:CCX (zero_extend:DI (match_operand:QI 0 "register_operand" "r"))
4313 "andcc\t%0, 0xff, %%g0"
4314 [(set_attr "type" "compare")])
4316 (define_insn "*cmp_zero_qi_sp64"
4318 (compare:CCX (match_operand:QI 0 "register_operand" "r")
4321 "andcc\t%0, 0xff, %%g0"
4322 [(set_attr "type" "compare")])
4324 (define_insn "*cmp_zero_extendqidi2_set"
4326 (compare:CCX (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
4328 (set (match_operand:DI 0 "register_operand" "=r")
4329 (zero_extend:DI (match_dup 1)))]
4331 "andcc\t%1, 0xff, %0"
4332 [(set_attr "type" "compare")])
4334 (define_insn "*cmp_zero_extendqidi2_andcc_set"
4336 (compare:CCX (and:DI (match_operand:DI 1 "register_operand" "r")
4339 (set (match_operand:DI 0 "register_operand" "=r")
4340 (zero_extend:DI (subreg:QI (match_dup 1) 0)))]
4342 "andcc\t%1, 0xff, %0"
4343 [(set_attr "type" "compare")])
4345 ;; Similarly, handle {SI,DI}->QI mode truncation followed by a compare.
4347 (define_insn "*cmp_siqi_trunc"
4349 (compare:CC (subreg:QI (match_operand:SI 0 "register_operand" "r") 3)
4352 "andcc\t%0, 0xff, %%g0"
4353 [(set_attr "type" "compare")])
4355 (define_insn "*cmp_siqi_trunc_set"
4357 (compare:CC (subreg:QI (match_operand:SI 1 "register_operand" "r") 3)
4359 (set (match_operand:QI 0 "register_operand" "=r")
4360 (subreg:QI (match_dup 1) 3))]
4362 "andcc\t%1, 0xff, %0"
4363 [(set_attr "type" "compare")])
4365 (define_insn "*cmp_diqi_trunc"
4367 (compare:CC (subreg:QI (match_operand:DI 0 "register_operand" "r") 7)
4370 "andcc\t%0, 0xff, %%g0"
4371 [(set_attr "type" "compare")])
4373 (define_insn "*cmp_diqi_trunc_set"
4375 (compare:CC (subreg:QI (match_operand:DI 1 "register_operand" "r") 7)
4377 (set (match_operand:QI 0 "register_operand" "=r")
4378 (subreg:QI (match_dup 1) 7))]
4380 "andcc\t%1, 0xff, %0"
4381 [(set_attr "type" "compare")])
4383 ;;- sign extension instructions
4385 ;; These patterns originally accepted general_operands, however, slightly
4386 ;; better code is generated by only accepting register_operands, and then
4387 ;; letting combine generate the lds[hb] insns.
4389 (define_expand "extendhisi2"
4390 [(set (match_operand:SI 0 "register_operand" "")
4391 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
4394 rtx temp = gen_reg_rtx (SImode);
4395 rtx shift_16 = GEN_INT (16);
4396 int op1_subbyte = 0;
4398 if (GET_CODE (operand1) == SUBREG)
4400 op1_subbyte = SUBREG_BYTE (operand1);
4401 op1_subbyte /= GET_MODE_SIZE (SImode);
4402 op1_subbyte *= GET_MODE_SIZE (SImode);
4403 operand1 = XEXP (operand1, 0);
4406 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4408 emit_insn (gen_ashrsi3 (operand0, temp, shift_16));
4412 (define_insn "*sign_extendhisi2_insn"
4413 [(set (match_operand:SI 0 "register_operand" "=r")
4414 (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
4417 [(set_attr "type" "sload")
4418 (set_attr "us3load_type" "3cycle")])
4420 (define_expand "extendqihi2"
4421 [(set (match_operand:HI 0 "register_operand" "")
4422 (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
4425 rtx temp = gen_reg_rtx (SImode);
4426 rtx shift_24 = GEN_INT (24);
4427 int op1_subbyte = 0;
4428 int op0_subbyte = 0;
4430 if (GET_CODE (operand1) == SUBREG)
4432 op1_subbyte = SUBREG_BYTE (operand1);
4433 op1_subbyte /= GET_MODE_SIZE (SImode);
4434 op1_subbyte *= GET_MODE_SIZE (SImode);
4435 operand1 = XEXP (operand1, 0);
4437 if (GET_CODE (operand0) == SUBREG)
4439 op0_subbyte = SUBREG_BYTE (operand0);
4440 op0_subbyte /= GET_MODE_SIZE (SImode);
4441 op0_subbyte *= GET_MODE_SIZE (SImode);
4442 operand0 = XEXP (operand0, 0);
4444 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4446 if (GET_MODE (operand0) != SImode)
4447 operand0 = gen_rtx_SUBREG (SImode, operand0, op0_subbyte);
4448 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
4452 (define_insn "*sign_extendqihi2_insn"
4453 [(set (match_operand:HI 0 "register_operand" "=r")
4454 (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
4457 [(set_attr "type" "sload")
4458 (set_attr "us3load_type" "3cycle")])
4460 (define_expand "extendqisi2"
4461 [(set (match_operand:SI 0 "register_operand" "")
4462 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
4465 rtx temp = gen_reg_rtx (SImode);
4466 rtx shift_24 = GEN_INT (24);
4467 int op1_subbyte = 0;
4469 if (GET_CODE (operand1) == SUBREG)
4471 op1_subbyte = SUBREG_BYTE (operand1);
4472 op1_subbyte /= GET_MODE_SIZE (SImode);
4473 op1_subbyte *= GET_MODE_SIZE (SImode);
4474 operand1 = XEXP (operand1, 0);
4477 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4479 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
4483 (define_insn "*sign_extendqisi2_insn"
4484 [(set (match_operand:SI 0 "register_operand" "=r")
4485 (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
4488 [(set_attr "type" "sload")
4489 (set_attr "us3load_type" "3cycle")])
4491 (define_expand "extendqidi2"
4492 [(set (match_operand:DI 0 "register_operand" "")
4493 (sign_extend:DI (match_operand:QI 1 "register_operand" "")))]
4496 rtx temp = gen_reg_rtx (DImode);
4497 rtx shift_56 = GEN_INT (56);
4498 int op1_subbyte = 0;
4500 if (GET_CODE (operand1) == SUBREG)
4502 op1_subbyte = SUBREG_BYTE (operand1);
4503 op1_subbyte /= GET_MODE_SIZE (DImode);
4504 op1_subbyte *= GET_MODE_SIZE (DImode);
4505 operand1 = XEXP (operand1, 0);
4508 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
4510 emit_insn (gen_ashrdi3 (operand0, temp, shift_56));
4514 (define_insn "*sign_extendqidi2_insn"
4515 [(set (match_operand:DI 0 "register_operand" "=r")
4516 (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
4519 [(set_attr "type" "sload")
4520 (set_attr "us3load_type" "3cycle")])
4522 (define_expand "extendhidi2"
4523 [(set (match_operand:DI 0 "register_operand" "")
4524 (sign_extend:DI (match_operand:HI 1 "register_operand" "")))]
4527 rtx temp = gen_reg_rtx (DImode);
4528 rtx shift_48 = GEN_INT (48);
4529 int op1_subbyte = 0;
4531 if (GET_CODE (operand1) == SUBREG)
4533 op1_subbyte = SUBREG_BYTE (operand1);
4534 op1_subbyte /= GET_MODE_SIZE (DImode);
4535 op1_subbyte *= GET_MODE_SIZE (DImode);
4536 operand1 = XEXP (operand1, 0);
4539 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
4541 emit_insn (gen_ashrdi3 (operand0, temp, shift_48));
4545 (define_insn "*sign_extendhidi2_insn"
4546 [(set (match_operand:DI 0 "register_operand" "=r")
4547 (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
4550 [(set_attr "type" "sload")
4551 (set_attr "us3load_type" "3cycle")])
4553 (define_expand "extendsidi2"
4554 [(set (match_operand:DI 0 "register_operand" "")
4555 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
4559 (define_insn "*sign_extendsidi2_insn"
4560 [(set (match_operand:DI 0 "register_operand" "=r,r")
4561 (sign_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
4566 [(set_attr "type" "shift,sload")
4567 (set_attr "us3load_type" "*,3cycle")])
4569 ;; Special pattern for optimizing bit-field compares. This is needed
4570 ;; because combine uses this as a canonical form.
4572 (define_insn "*cmp_zero_extract"
4575 (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
4576 (match_operand:SI 1 "small_int_or_double" "n")
4577 (match_operand:SI 2 "small_int_or_double" "n"))
4579 "(GET_CODE (operands[2]) == CONST_INT
4580 && INTVAL (operands[2]) > 19)
4581 || (GET_CODE (operands[2]) == CONST_DOUBLE
4582 && CONST_DOUBLE_LOW (operands[2]) > 19)"
4584 int len = (GET_CODE (operands[1]) == CONST_INT
4585 ? INTVAL (operands[1])
4586 : CONST_DOUBLE_LOW (operands[1]));
4588 (GET_CODE (operands[2]) == CONST_INT
4589 ? INTVAL (operands[2])
4590 : CONST_DOUBLE_LOW (operands[2])) - len;
4591 HOST_WIDE_INT mask = ((1 << len) - 1) << pos;
4593 operands[1] = GEN_INT (mask);
4594 return "andcc\t%0, %1, %%g0";
4596 [(set_attr "type" "compare")])
4598 (define_insn "*cmp_zero_extract_sp64"
4601 (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
4602 (match_operand:SI 1 "small_int_or_double" "n")
4603 (match_operand:SI 2 "small_int_or_double" "n"))
4606 && ((GET_CODE (operands[2]) == CONST_INT
4607 && INTVAL (operands[2]) > 51)
4608 || (GET_CODE (operands[2]) == CONST_DOUBLE
4609 && CONST_DOUBLE_LOW (operands[2]) > 51))"
4611 int len = (GET_CODE (operands[1]) == CONST_INT
4612 ? INTVAL (operands[1])
4613 : CONST_DOUBLE_LOW (operands[1]));
4615 (GET_CODE (operands[2]) == CONST_INT
4616 ? INTVAL (operands[2])
4617 : CONST_DOUBLE_LOW (operands[2])) - len;
4618 HOST_WIDE_INT mask = (((unsigned HOST_WIDE_INT) 1 << len) - 1) << pos;
4620 operands[1] = GEN_INT (mask);
4621 return "andcc\t%0, %1, %%g0";
4623 [(set_attr "type" "compare")])
4625 ;; Conversions between float, double and long double.
4627 (define_insn "extendsfdf2"
4628 [(set (match_operand:DF 0 "register_operand" "=e")
4630 (match_operand:SF 1 "register_operand" "f")))]
4633 [(set_attr "type" "fp")
4634 (set_attr "fptype" "double")])
4636 (define_expand "extendsftf2"
4637 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4639 (match_operand:SF 1 "register_operand" "")))]
4640 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4641 "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
4643 (define_insn "*extendsftf2_hq"
4644 [(set (match_operand:TF 0 "register_operand" "=e")
4646 (match_operand:SF 1 "register_operand" "f")))]
4647 "TARGET_FPU && TARGET_HARD_QUAD"
4649 [(set_attr "type" "fp")])
4651 (define_expand "extenddftf2"
4652 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4654 (match_operand:DF 1 "register_operand" "")))]
4655 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4656 "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
4658 (define_insn "*extenddftf2_hq"
4659 [(set (match_operand:TF 0 "register_operand" "=e")
4661 (match_operand:DF 1 "register_operand" "e")))]
4662 "TARGET_FPU && TARGET_HARD_QUAD"
4664 [(set_attr "type" "fp")])
4666 (define_insn "truncdfsf2"
4667 [(set (match_operand:SF 0 "register_operand" "=f")
4669 (match_operand:DF 1 "register_operand" "e")))]
4672 [(set_attr "type" "fp")
4673 (set_attr "fptype" "double")])
4675 (define_expand "trunctfsf2"
4676 [(set (match_operand:SF 0 "register_operand" "")
4678 (match_operand:TF 1 "general_operand" "")))]
4679 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4680 "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
4682 (define_insn "*trunctfsf2_hq"
4683 [(set (match_operand:SF 0 "register_operand" "=f")
4685 (match_operand:TF 1 "register_operand" "e")))]
4686 "TARGET_FPU && TARGET_HARD_QUAD"
4688 [(set_attr "type" "fp")])
4690 (define_expand "trunctfdf2"
4691 [(set (match_operand:DF 0 "register_operand" "")
4693 (match_operand:TF 1 "general_operand" "")))]
4694 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4695 "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
4697 (define_insn "*trunctfdf2_hq"
4698 [(set (match_operand:DF 0 "register_operand" "=e")
4700 (match_operand:TF 1 "register_operand" "e")))]
4701 "TARGET_FPU && TARGET_HARD_QUAD"
4703 [(set_attr "type" "fp")])
4705 ;; Conversion between fixed point and floating point.
4707 (define_insn "floatsisf2"
4708 [(set (match_operand:SF 0 "register_operand" "=f")
4709 (float:SF (match_operand:SI 1 "register_operand" "f")))]
4712 [(set_attr "type" "fp")
4713 (set_attr "fptype" "double")])
4715 (define_insn "floatsidf2"
4716 [(set (match_operand:DF 0 "register_operand" "=e")
4717 (float:DF (match_operand:SI 1 "register_operand" "f")))]
4720 [(set_attr "type" "fp")
4721 (set_attr "fptype" "double")])
4723 (define_expand "floatsitf2"
4724 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4725 (float:TF (match_operand:SI 1 "register_operand" "")))]
4726 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4727 "emit_tfmode_cvt (FLOAT, operands); DONE;")
4729 (define_insn "*floatsitf2_hq"
4730 [(set (match_operand:TF 0 "register_operand" "=e")
4731 (float:TF (match_operand:SI 1 "register_operand" "f")))]
4732 "TARGET_FPU && TARGET_HARD_QUAD"
4734 [(set_attr "type" "fp")])
4736 (define_expand "floatunssitf2"
4737 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4738 (unsigned_float:TF (match_operand:SI 1 "register_operand" "")))]
4739 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4740 "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
4742 ;; Now the same for 64 bit sources.
4744 (define_insn "floatdisf2"
4745 [(set (match_operand:SF 0 "register_operand" "=f")
4746 (float:SF (match_operand:DI 1 "register_operand" "e")))]
4747 "TARGET_V9 && TARGET_FPU"
4749 [(set_attr "type" "fp")
4750 (set_attr "fptype" "double")])
4752 (define_expand "floatunsdisf2"
4753 [(use (match_operand:SF 0 "register_operand" ""))
4754 (use (match_operand:DI 1 "general_operand" ""))]
4755 "TARGET_ARCH64 && TARGET_FPU"
4756 "sparc_emit_floatunsdi (operands, SFmode); DONE;")
4758 (define_insn "floatdidf2"
4759 [(set (match_operand:DF 0 "register_operand" "=e")
4760 (float:DF (match_operand:DI 1 "register_operand" "e")))]
4761 "TARGET_V9 && TARGET_FPU"
4763 [(set_attr "type" "fp")
4764 (set_attr "fptype" "double")])
4766 (define_expand "floatunsdidf2"
4767 [(use (match_operand:DF 0 "register_operand" ""))
4768 (use (match_operand:DI 1 "general_operand" ""))]
4769 "TARGET_ARCH64 && TARGET_FPU"
4770 "sparc_emit_floatunsdi (operands, DFmode); DONE;")
4772 (define_expand "floatditf2"
4773 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4774 (float:TF (match_operand:DI 1 "register_operand" "")))]
4775 "TARGET_FPU && TARGET_V9 && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4776 "emit_tfmode_cvt (FLOAT, operands); DONE;")
4778 (define_insn "*floatditf2_hq"
4779 [(set (match_operand:TF 0 "register_operand" "=e")
4780 (float:TF (match_operand:DI 1 "register_operand" "e")))]
4781 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
4783 [(set_attr "type" "fp")])
4785 (define_expand "floatunsditf2"
4786 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4787 (unsigned_float:TF (match_operand:DI 1 "register_operand" "")))]
4788 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4789 "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
4791 ;; Convert a float to an actual integer.
4792 ;; Truncation is performed as part of the conversion.
4794 (define_insn "fix_truncsfsi2"
4795 [(set (match_operand:SI 0 "register_operand" "=f")
4796 (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
4799 [(set_attr "type" "fp")
4800 (set_attr "fptype" "double")])
4802 (define_insn "fix_truncdfsi2"
4803 [(set (match_operand:SI 0 "register_operand" "=f")
4804 (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
4807 [(set_attr "type" "fp")
4808 (set_attr "fptype" "double")])
4810 (define_expand "fix_trunctfsi2"
4811 [(set (match_operand:SI 0 "register_operand" "")
4812 (fix:SI (match_operand:TF 1 "general_operand" "")))]
4813 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4814 "emit_tfmode_cvt (FIX, operands); DONE;")
4816 (define_insn "*fix_trunctfsi2_hq"
4817 [(set (match_operand:SI 0 "register_operand" "=f")
4818 (fix:SI (match_operand:TF 1 "register_operand" "e")))]
4819 "TARGET_FPU && TARGET_HARD_QUAD"
4821 [(set_attr "type" "fp")])
4823 (define_expand "fixuns_trunctfsi2"
4824 [(set (match_operand:SI 0 "register_operand" "")
4825 (unsigned_fix:SI (match_operand:TF 1 "general_operand" "")))]
4826 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4827 "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
4829 ;; Now the same, for V9 targets
4831 (define_insn "fix_truncsfdi2"
4832 [(set (match_operand:DI 0 "register_operand" "=e")
4833 (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
4834 "TARGET_V9 && TARGET_FPU"
4836 [(set_attr "type" "fp")
4837 (set_attr "fptype" "double")])
4839 (define_expand "fixuns_truncsfdi2"
4840 [(use (match_operand:DI 0 "register_operand" ""))
4841 (use (match_operand:SF 1 "general_operand" ""))]
4842 "TARGET_ARCH64 && TARGET_FPU"
4843 "sparc_emit_fixunsdi (operands, SFmode); DONE;")
4845 (define_insn "fix_truncdfdi2"
4846 [(set (match_operand:DI 0 "register_operand" "=e")
4847 (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
4848 "TARGET_V9 && TARGET_FPU"
4850 [(set_attr "type" "fp")
4851 (set_attr "fptype" "double")])
4853 (define_expand "fixuns_truncdfdi2"
4854 [(use (match_operand:DI 0 "register_operand" ""))
4855 (use (match_operand:DF 1 "general_operand" ""))]
4856 "TARGET_ARCH64 && TARGET_FPU"
4857 "sparc_emit_fixunsdi (operands, DFmode); DONE;")
4859 (define_expand "fix_trunctfdi2"
4860 [(set (match_operand:DI 0 "register_operand" "")
4861 (fix:DI (match_operand:TF 1 "general_operand" "")))]
4862 "TARGET_V9 && TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4863 "emit_tfmode_cvt (FIX, operands); DONE;")
4865 (define_insn "*fix_trunctfdi2_hq"
4866 [(set (match_operand:DI 0 "register_operand" "=e")
4867 (fix:DI (match_operand:TF 1 "register_operand" "e")))]
4868 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
4870 [(set_attr "type" "fp")])
4872 (define_expand "fixuns_trunctfdi2"
4873 [(set (match_operand:DI 0 "register_operand" "")
4874 (unsigned_fix:DI (match_operand:TF 1 "general_operand" "")))]
4875 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4876 "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
4878 ;;- arithmetic instructions
4880 (define_expand "adddi3"
4881 [(set (match_operand:DI 0 "register_operand" "")
4882 (plus:DI (match_operand:DI 1 "register_operand" "")
4883 (match_operand:DI 2 "arith_double_add_operand" "")))]
4886 if (! TARGET_ARCH64)
4888 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
4889 gen_rtx_SET (VOIDmode, operands[0],
4890 gen_rtx_PLUS (DImode, operands[1],
4892 gen_rtx_CLOBBER (VOIDmode,
4893 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
4898 (define_insn_and_split "adddi3_insn_sp32"
4899 [(set (match_operand:DI 0 "register_operand" "=r")
4900 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
4901 (match_operand:DI 2 "arith_double_operand" "rHI")))
4902 (clobber (reg:CC 100))]
4905 "&& reload_completed"
4906 [(parallel [(set (reg:CC_NOOV 100)
4907 (compare:CC_NOOV (plus:SI (match_dup 4)
4911 (plus:SI (match_dup 4) (match_dup 5)))])
4913 (plus:SI (plus:SI (match_dup 7)
4915 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4917 operands[3] = gen_lowpart (SImode, operands[0]);
4918 operands[4] = gen_lowpart (SImode, operands[1]);
4919 operands[5] = gen_lowpart (SImode, operands[2]);
4920 operands[6] = gen_highpart (SImode, operands[0]);
4921 operands[7] = gen_highpart_mode (SImode, DImode, operands[1]);
4922 #if HOST_BITS_PER_WIDE_INT == 32
4923 if (GET_CODE (operands[2]) == CONST_INT)
4925 if (INTVAL (operands[2]) < 0)
4926 operands[8] = constm1_rtx;
4928 operands[8] = const0_rtx;
4932 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
4934 [(set_attr "length" "2")])
4937 [(set (match_operand:DI 0 "register_operand" "")
4938 (minus:DI (match_operand:DI 1 "arith_double_operand" "")
4939 (match_operand:DI 2 "arith_double_operand" "")))
4940 (clobber (reg:CC 100))]
4941 "! TARGET_ARCH64 && reload_completed"
4942 [(parallel [(set (reg:CC_NOOV 100)
4943 (compare:CC_NOOV (minus:SI (match_dup 4)
4947 (minus:SI (match_dup 4) (match_dup 5)))])
4949 (minus:SI (minus:SI (match_dup 7)
4951 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4953 operands[3] = gen_lowpart (SImode, operands[0]);
4954 operands[4] = gen_lowpart (SImode, operands[1]);
4955 operands[5] = gen_lowpart (SImode, operands[2]);
4956 operands[6] = gen_highpart (SImode, operands[0]);
4957 operands[7] = gen_highpart (SImode, operands[1]);
4958 #if HOST_BITS_PER_WIDE_INT == 32
4959 if (GET_CODE (operands[2]) == CONST_INT)
4961 if (INTVAL (operands[2]) < 0)
4962 operands[8] = constm1_rtx;
4964 operands[8] = const0_rtx;
4968 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
4971 ;; LTU here means "carry set"
4973 [(set (match_operand:SI 0 "register_operand" "=r")
4974 (plus:SI (plus:SI (match_operand:SI 1 "arith_operand" "%r")
4975 (match_operand:SI 2 "arith_operand" "rI"))
4976 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4979 [(set_attr "type" "ialuX")])
4981 (define_insn_and_split "*addx_extend_sp32"
4982 [(set (match_operand:DI 0 "register_operand" "=r")
4983 (zero_extend:DI (plus:SI (plus:SI
4984 (match_operand:SI 1 "reg_or_0_operand" "%rJ")
4985 (match_operand:SI 2 "arith_operand" "rI"))
4986 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4989 "&& reload_completed"
4990 [(set (match_dup 3) (plus:SI (plus:SI (match_dup 1) (match_dup 2))
4991 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
4992 (set (match_dup 4) (const_int 0))]
4993 "operands[3] = gen_lowpart (SImode, operands[0]);
4994 operands[4] = gen_highpart_mode (SImode, DImode, operands[1]);"
4995 [(set_attr "length" "2")])
4997 (define_insn "*addx_extend_sp64"
4998 [(set (match_operand:DI 0 "register_operand" "=r")
4999 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
5000 (match_operand:SI 2 "arith_operand" "rI"))
5001 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5004 [(set_attr "type" "ialuX")])
5007 [(set (match_operand:SI 0 "register_operand" "=r")
5008 (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5009 (match_operand:SI 2 "arith_operand" "rI"))
5010 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5013 [(set_attr "type" "ialuX")])
5015 (define_insn "*subx_extend_sp64"
5016 [(set (match_operand:DI 0 "register_operand" "=r")
5017 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5018 (match_operand:SI 2 "arith_operand" "rI"))
5019 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5022 [(set_attr "type" "ialuX")])
5024 (define_insn_and_split "*subx_extend"
5025 [(set (match_operand:DI 0 "register_operand" "=r")
5026 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5027 (match_operand:SI 2 "arith_operand" "rI"))
5028 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5031 "&& reload_completed"
5032 [(set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 2))
5033 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
5034 (set (match_dup 4) (const_int 0))]
5035 "operands[3] = gen_lowpart (SImode, operands[0]);
5036 operands[4] = gen_highpart (SImode, operands[0]);"
5037 [(set_attr "length" "2")])
5039 (define_insn_and_split ""
5040 [(set (match_operand:DI 0 "register_operand" "=r")
5041 (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5042 (match_operand:DI 2 "register_operand" "r")))
5043 (clobber (reg:CC 100))]
5046 "&& reload_completed"
5047 [(parallel [(set (reg:CC_NOOV 100)
5048 (compare:CC_NOOV (plus:SI (match_dup 3) (match_dup 1))
5050 (set (match_dup 5) (plus:SI (match_dup 3) (match_dup 1)))])
5052 (plus:SI (plus:SI (match_dup 4) (const_int 0))
5053 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5054 "operands[3] = gen_lowpart (SImode, operands[2]);
5055 operands[4] = gen_highpart (SImode, operands[2]);
5056 operands[5] = gen_lowpart (SImode, operands[0]);
5057 operands[6] = gen_highpart (SImode, operands[0]);"
5058 [(set_attr "length" "2")])
5060 (define_insn "*adddi3_sp64"
5061 [(set (match_operand:DI 0 "register_operand" "=r,r")
5062 (plus:DI (match_operand:DI 1 "register_operand" "%r,r")
5063 (match_operand:DI 2 "arith_double_add_operand" "rHI,O")))]
5069 (define_insn "addsi3"
5070 [(set (match_operand:SI 0 "register_operand" "=r,r,d")
5071 (plus:SI (match_operand:SI 1 "register_operand" "%r,r,d")
5072 (match_operand:SI 2 "arith_add_operand" "rI,O,d")))]
5077 fpadd32s\t%1, %2, %0"
5078 [(set_attr "type" "*,*,fga")
5079 (set_attr "fptype" "*,*,single")])
5081 (define_insn "*cmp_cc_plus"
5082 [(set (reg:CC_NOOV 100)
5083 (compare:CC_NOOV (plus:SI (match_operand:SI 0 "arith_operand" "%r")
5084 (match_operand:SI 1 "arith_operand" "rI"))
5087 "addcc\t%0, %1, %%g0"
5088 [(set_attr "type" "compare")])
5090 (define_insn "*cmp_ccx_plus"
5091 [(set (reg:CCX_NOOV 100)
5092 (compare:CCX_NOOV (plus:DI (match_operand:DI 0 "arith_double_operand" "%r")
5093 (match_operand:DI 1 "arith_double_operand" "rHI"))
5096 "addcc\t%0, %1, %%g0"
5097 [(set_attr "type" "compare")])
5099 (define_insn "*cmp_cc_plus_set"
5100 [(set (reg:CC_NOOV 100)
5101 (compare:CC_NOOV (plus:SI (match_operand:SI 1 "arith_operand" "%r")
5102 (match_operand:SI 2 "arith_operand" "rI"))
5104 (set (match_operand:SI 0 "register_operand" "=r")
5105 (plus:SI (match_dup 1) (match_dup 2)))]
5108 [(set_attr "type" "compare")])
5110 (define_insn "*cmp_ccx_plus_set"
5111 [(set (reg:CCX_NOOV 100)
5112 (compare:CCX_NOOV (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
5113 (match_operand:DI 2 "arith_double_operand" "rHI"))
5115 (set (match_operand:DI 0 "register_operand" "=r")
5116 (plus:DI (match_dup 1) (match_dup 2)))]
5119 [(set_attr "type" "compare")])
5121 (define_expand "subdi3"
5122 [(set (match_operand:DI 0 "register_operand" "")
5123 (minus:DI (match_operand:DI 1 "register_operand" "")
5124 (match_operand:DI 2 "arith_double_add_operand" "")))]
5127 if (! TARGET_ARCH64)
5129 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
5130 gen_rtx_SET (VOIDmode, operands[0],
5131 gen_rtx_MINUS (DImode, operands[1],
5133 gen_rtx_CLOBBER (VOIDmode,
5134 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
5139 (define_insn_and_split "*subdi3_sp32"
5140 [(set (match_operand:DI 0 "register_operand" "=r")
5141 (minus:DI (match_operand:DI 1 "register_operand" "r")
5142 (match_operand:DI 2 "arith_double_operand" "rHI")))
5143 (clobber (reg:CC 100))]
5146 "&& reload_completed
5147 && (GET_CODE (operands[2]) == CONST_INT
5148 || GET_CODE (operands[2]) == CONST_DOUBLE)"
5149 [(clobber (const_int 0))]
5153 highp = gen_highpart_mode (SImode, DImode, operands[2]);
5154 lowp = gen_lowpart (SImode, operands[2]);
5155 if ((lowp == const0_rtx)
5156 && (operands[0] == operands[1]))
5158 emit_insn (gen_rtx_SET (VOIDmode,
5159 gen_highpart (SImode, operands[0]),
5160 gen_rtx_MINUS (SImode,
5161 gen_highpart_mode (SImode, DImode,
5167 emit_insn (gen_cmp_minus_cc_set (gen_lowpart (SImode, operands[0]),
5168 gen_lowpart (SImode, operands[1]),
5170 emit_insn (gen_subx (gen_highpart (SImode, operands[0]),
5171 gen_highpart_mode (SImode, DImode, operands[1]),
5176 [(set_attr "length" "2")])
5179 [(set (match_operand:DI 0 "register_operand" "")
5180 (minus:DI (match_operand:DI 1 "register_operand" "")
5181 (match_operand:DI 2 "register_operand" "")))
5182 (clobber (reg:CC 100))]
5184 && reload_completed"
5185 [(clobber (const_int 0))]
5187 emit_insn (gen_cmp_minus_cc_set (gen_lowpart (SImode, operands[0]),
5188 gen_lowpart (SImode, operands[1]),
5189 gen_lowpart (SImode, operands[2])));
5190 emit_insn (gen_subx (gen_highpart (SImode, operands[0]),
5191 gen_highpart (SImode, operands[1]),
5192 gen_highpart (SImode, operands[2])));
5196 (define_insn_and_split ""
5197 [(set (match_operand:DI 0 "register_operand" "=r")
5198 (minus:DI (match_operand:DI 1 "register_operand" "r")
5199 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))
5200 (clobber (reg:CC 100))]
5203 "&& reload_completed"
5204 [(parallel [(set (reg:CC_NOOV 100)
5205 (compare:CC_NOOV (minus:SI (match_dup 3) (match_dup 2))
5207 (set (match_dup 5) (minus:SI (match_dup 3) (match_dup 2)))])
5209 (minus:SI (minus:SI (match_dup 4) (const_int 0))
5210 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5211 "operands[3] = gen_lowpart (SImode, operands[1]);
5212 operands[4] = gen_highpart (SImode, operands[1]);
5213 operands[5] = gen_lowpart (SImode, operands[0]);
5214 operands[6] = gen_highpart (SImode, operands[0]);"
5215 [(set_attr "length" "2")])
5217 (define_insn "*subdi3_sp64"
5218 [(set (match_operand:DI 0 "register_operand" "=r,r")
5219 (minus:DI (match_operand:DI 1 "register_operand" "r,r")
5220 (match_operand:DI 2 "arith_double_add_operand" "rHI,O")))]
5226 (define_insn "subsi3"
5227 [(set (match_operand:SI 0 "register_operand" "=r,r,d")
5228 (minus:SI (match_operand:SI 1 "register_operand" "r,r,d")
5229 (match_operand:SI 2 "arith_add_operand" "rI,O,d")))]
5234 fpsub32s\t%1, %2, %0"
5235 [(set_attr "type" "*,*,fga")
5236 (set_attr "fptype" "*,*,single")])
5238 (define_insn "*cmp_minus_cc"
5239 [(set (reg:CC_NOOV 100)
5240 (compare:CC_NOOV (minus:SI (match_operand:SI 0 "reg_or_0_operand" "rJ")
5241 (match_operand:SI 1 "arith_operand" "rI"))
5244 "subcc\t%r0, %1, %%g0"
5245 [(set_attr "type" "compare")])
5247 (define_insn "*cmp_minus_ccx"
5248 [(set (reg:CCX_NOOV 100)
5249 (compare:CCX_NOOV (minus:DI (match_operand:DI 0 "register_operand" "r")
5250 (match_operand:DI 1 "arith_double_operand" "rHI"))
5253 "subcc\t%0, %1, %%g0"
5254 [(set_attr "type" "compare")])
5256 (define_insn "cmp_minus_cc_set"
5257 [(set (reg:CC_NOOV 100)
5258 (compare:CC_NOOV (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5259 (match_operand:SI 2 "arith_operand" "rI"))
5261 (set (match_operand:SI 0 "register_operand" "=r")
5262 (minus:SI (match_dup 1) (match_dup 2)))]
5264 "subcc\t%r1, %2, %0"
5265 [(set_attr "type" "compare")])
5267 (define_insn "*cmp_minus_ccx_set"
5268 [(set (reg:CCX_NOOV 100)
5269 (compare:CCX_NOOV (minus:DI (match_operand:DI 1 "register_operand" "r")
5270 (match_operand:DI 2 "arith_double_operand" "rHI"))
5272 (set (match_operand:DI 0 "register_operand" "=r")
5273 (minus:DI (match_dup 1) (match_dup 2)))]
5276 [(set_attr "type" "compare")])
5278 ;; Integer Multiply/Divide.
5280 ;; The 32 bit multiply/divide instructions are deprecated on v9, but at
5281 ;; least in UltraSPARC I, II and IIi it is a win tick-wise.
5283 (define_insn "mulsi3"
5284 [(set (match_operand:SI 0 "register_operand" "=r")
5285 (mult:SI (match_operand:SI 1 "arith_operand" "%r")
5286 (match_operand:SI 2 "arith_operand" "rI")))]
5289 [(set_attr "type" "imul")])
5291 (define_expand "muldi3"
5292 [(set (match_operand:DI 0 "register_operand" "=r")
5293 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r")
5294 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5295 "TARGET_ARCH64 || TARGET_V8PLUS"
5299 emit_insn (gen_muldi3_v8plus (operands[0], operands[1], operands[2]));
5304 (define_insn "*muldi3_sp64"
5305 [(set (match_operand:DI 0 "register_operand" "=r")
5306 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r")
5307 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5310 [(set_attr "type" "imul")])
5312 ;; V8plus wide multiply.
5314 (define_insn "muldi3_v8plus"
5315 [(set (match_operand:DI 0 "register_operand" "=r,h")
5316 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r,0")
5317 (match_operand:DI 2 "arith_double_operand" "rI,rI")))
5318 (clobber (match_scratch:SI 3 "=&h,X"))
5319 (clobber (match_scratch:SI 4 "=&h,X"))]
5322 if (sparc_check_64 (operands[1], insn) <= 0)
5323 output_asm_insn ("srl\t%L1, 0, %L1", operands);
5324 if (which_alternative == 1)
5325 output_asm_insn ("sllx\t%H1, 32, %H1", operands);
5326 if (GET_CODE (operands[2]) == CONST_INT)
5328 if (which_alternative == 1)
5329 return "or\t%L1, %H1, %H1\n\tmulx\t%H1, %2, %L0\;srlx\t%L0, 32, %H0";
5331 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";
5333 else if (rtx_equal_p (operands[1], operands[2]))
5335 if (which_alternative == 1)
5336 return "or\t%L1, %H1, %H1\n\tmulx\t%H1, %H1, %L0\;srlx\t%L0, 32, %H0";
5338 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";
5340 if (sparc_check_64 (operands[2], insn) <= 0)
5341 output_asm_insn ("srl\t%L2, 0, %L2", operands);
5342 if (which_alternative == 1)
5343 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";
5345 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";
5347 [(set_attr "type" "multi")
5348 (set_attr "length" "9,8")])
5350 (define_insn "*cmp_mul_set"
5352 (compare:CC (mult:SI (match_operand:SI 1 "arith_operand" "%r")
5353 (match_operand:SI 2 "arith_operand" "rI"))
5355 (set (match_operand:SI 0 "register_operand" "=r")
5356 (mult:SI (match_dup 1) (match_dup 2)))]
5357 "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS"
5358 "smulcc\t%1, %2, %0"
5359 [(set_attr "type" "imul")])
5361 (define_expand "mulsidi3"
5362 [(set (match_operand:DI 0 "register_operand" "")
5363 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
5364 (sign_extend:DI (match_operand:SI 2 "arith_operand" ""))))]
5367 if (CONSTANT_P (operands[2]))
5370 emit_insn (gen_const_mulsidi3_v8plus (operands[0], operands[1],
5372 else if (TARGET_ARCH32)
5373 emit_insn (gen_const_mulsidi3_sp32 (operands[0], operands[1],
5376 emit_insn (gen_const_mulsidi3_sp64 (operands[0], operands[1],
5382 emit_insn (gen_mulsidi3_v8plus (operands[0], operands[1], operands[2]));
5387 ;; V9 puts the 64 bit product in a 64 bit register. Only out or global
5388 ;; registers can hold 64 bit values in the V8plus environment.
5390 (define_insn "mulsidi3_v8plus"
5391 [(set (match_operand:DI 0 "register_operand" "=h,r")
5392 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5393 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
5394 (clobber (match_scratch:SI 3 "=X,&h"))]
5397 smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
5398 smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
5399 [(set_attr "type" "multi")
5400 (set_attr "length" "2,3")])
5403 (define_insn "const_mulsidi3_v8plus"
5404 [(set (match_operand:DI 0 "register_operand" "=h,r")
5405 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5406 (match_operand:DI 2 "small_int" "I,I")))
5407 (clobber (match_scratch:SI 3 "=X,&h"))]
5410 smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
5411 smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
5412 [(set_attr "type" "multi")
5413 (set_attr "length" "2,3")])
5416 (define_insn "*mulsidi3_sp32"
5417 [(set (match_operand:DI 0 "register_operand" "=r")
5418 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5419 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
5422 return TARGET_SPARCLET
5423 ? "smuld\t%1, %2, %L0"
5424 : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
5427 (if_then_else (eq_attr "isa" "sparclet")
5428 (const_string "imul") (const_string "multi")))
5429 (set (attr "length")
5430 (if_then_else (eq_attr "isa" "sparclet")
5431 (const_int 1) (const_int 2)))])
5433 (define_insn "*mulsidi3_sp64"
5434 [(set (match_operand:DI 0 "register_operand" "=r")
5435 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5436 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
5437 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5439 [(set_attr "type" "imul")])
5441 ;; Extra pattern, because sign_extend of a constant isn't valid.
5444 (define_insn "const_mulsidi3_sp32"
5445 [(set (match_operand:DI 0 "register_operand" "=r")
5446 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5447 (match_operand:DI 2 "small_int" "I")))]
5450 return TARGET_SPARCLET
5451 ? "smuld\t%1, %2, %L0"
5452 : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
5455 (if_then_else (eq_attr "isa" "sparclet")
5456 (const_string "imul") (const_string "multi")))
5457 (set (attr "length")
5458 (if_then_else (eq_attr "isa" "sparclet")
5459 (const_int 1) (const_int 2)))])
5461 (define_insn "const_mulsidi3_sp64"
5462 [(set (match_operand:DI 0 "register_operand" "=r")
5463 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5464 (match_operand:DI 2 "small_int" "I")))]
5465 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5467 [(set_attr "type" "imul")])
5469 (define_expand "smulsi3_highpart"
5470 [(set (match_operand:SI 0 "register_operand" "")
5472 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
5473 (sign_extend:DI (match_operand:SI 2 "arith_operand" "")))
5475 "TARGET_HARD_MUL && TARGET_ARCH32"
5477 if (CONSTANT_P (operands[2]))
5481 emit_insn (gen_const_smulsi3_highpart_v8plus (operands[0],
5487 emit_insn (gen_const_smulsi3_highpart (operands[0], operands[1], operands[2]));
5492 emit_insn (gen_smulsi3_highpart_v8plus (operands[0], operands[1],
5493 operands[2], GEN_INT (32)));
5499 (define_insn "smulsi3_highpart_v8plus"
5500 [(set (match_operand:SI 0 "register_operand" "=h,r")
5502 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5503 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
5504 (match_operand:SI 3 "const_int_operand" "i,i"))))
5505 (clobber (match_scratch:SI 4 "=X,&h"))]
5508 smul\t%1, %2, %0\;srlx\t%0, %3, %0
5509 smul\t%1, %2, %4\;srlx\t%4, %3, %0"
5510 [(set_attr "type" "multi")
5511 (set_attr "length" "2")])
5513 ;; The combiner changes TRUNCATE in the previous pattern to SUBREG.
5516 [(set (match_operand:SI 0 "register_operand" "=h,r")
5519 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5520 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
5521 (match_operand:SI 3 "const_int_operand" "i,i"))
5523 (clobber (match_scratch:SI 4 "=X,&h"))]
5526 smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
5527 smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
5528 [(set_attr "type" "multi")
5529 (set_attr "length" "2")])
5532 (define_insn "const_smulsi3_highpart_v8plus"
5533 [(set (match_operand:SI 0 "register_operand" "=h,r")
5535 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5536 (match_operand:DI 2 "small_int" "i,i"))
5537 (match_operand:SI 3 "const_int_operand" "i,i"))))
5538 (clobber (match_scratch:SI 4 "=X,&h"))]
5541 smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
5542 smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
5543 [(set_attr "type" "multi")
5544 (set_attr "length" "2")])
5547 (define_insn "*smulsi3_highpart_sp32"
5548 [(set (match_operand:SI 0 "register_operand" "=r")
5550 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5551 (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
5554 "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
5555 [(set_attr "type" "multi")
5556 (set_attr "length" "2")])
5559 (define_insn "const_smulsi3_highpart"
5560 [(set (match_operand:SI 0 "register_operand" "=r")
5562 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5563 (match_operand:DI 2 "small_int" "i"))
5566 "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
5567 [(set_attr "type" "multi")
5568 (set_attr "length" "2")])
5570 (define_expand "umulsidi3"
5571 [(set (match_operand:DI 0 "register_operand" "")
5572 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
5573 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" ""))))]
5576 if (CONSTANT_P (operands[2]))
5579 emit_insn (gen_const_umulsidi3_v8plus (operands[0], operands[1],
5581 else if (TARGET_ARCH32)
5582 emit_insn (gen_const_umulsidi3_sp32 (operands[0], operands[1],
5585 emit_insn (gen_const_umulsidi3_sp64 (operands[0], operands[1],
5591 emit_insn (gen_umulsidi3_v8plus (operands[0], operands[1], operands[2]));
5597 (define_insn "umulsidi3_v8plus"
5598 [(set (match_operand:DI 0 "register_operand" "=h,r")
5599 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5600 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
5601 (clobber (match_scratch:SI 3 "=X,&h"))]
5604 umul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
5605 umul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
5606 [(set_attr "type" "multi")
5607 (set_attr "length" "2,3")])
5610 (define_insn "*umulsidi3_sp32"
5611 [(set (match_operand:DI 0 "register_operand" "=r")
5612 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5613 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
5616 return TARGET_SPARCLET
5617 ? "umuld\t%1, %2, %L0"
5618 : "umul\t%1, %2, %L0\n\trd\t%%y, %H0";
5621 (if_then_else (eq_attr "isa" "sparclet")
5622 (const_string "imul") (const_string "multi")))
5623 (set (attr "length")
5624 (if_then_else (eq_attr "isa" "sparclet")
5625 (const_int 1) (const_int 2)))])
5627 (define_insn "*umulsidi3_sp64"
5628 [(set (match_operand:DI 0 "register_operand" "=r")
5629 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5630 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
5631 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5633 [(set_attr "type" "imul")])
5635 ;; Extra pattern, because sign_extend of a constant isn't valid.
5638 (define_insn "const_umulsidi3_sp32"
5639 [(set (match_operand:DI 0 "register_operand" "=r")
5640 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5641 (match_operand:DI 2 "uns_small_int" "")))]
5644 return TARGET_SPARCLET
5645 ? "umuld\t%1, %s2, %L0"
5646 : "umul\t%1, %s2, %L0\n\trd\t%%y, %H0";
5649 (if_then_else (eq_attr "isa" "sparclet")
5650 (const_string "imul") (const_string "multi")))
5651 (set (attr "length")
5652 (if_then_else (eq_attr "isa" "sparclet")
5653 (const_int 1) (const_int 2)))])
5655 (define_insn "const_umulsidi3_sp64"
5656 [(set (match_operand:DI 0 "register_operand" "=r")
5657 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5658 (match_operand:DI 2 "uns_small_int" "")))]
5659 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5661 [(set_attr "type" "imul")])
5664 (define_insn "const_umulsidi3_v8plus"
5665 [(set (match_operand:DI 0 "register_operand" "=h,r")
5666 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5667 (match_operand:DI 2 "uns_small_int" "")))
5668 (clobber (match_scratch:SI 3 "=X,h"))]
5671 umul\t%1, %s2, %L0\n\tsrlx\t%L0, 32, %H0
5672 umul\t%1, %s2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
5673 [(set_attr "type" "multi")
5674 (set_attr "length" "2,3")])
5676 (define_expand "umulsi3_highpart"
5677 [(set (match_operand:SI 0 "register_operand" "")
5679 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
5680 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" "")))
5682 "TARGET_HARD_MUL && TARGET_ARCH32"
5684 if (CONSTANT_P (operands[2]))
5688 emit_insn (gen_const_umulsi3_highpart_v8plus (operands[0],
5694 emit_insn (gen_const_umulsi3_highpart (operands[0], operands[1], operands[2]));
5699 emit_insn (gen_umulsi3_highpart_v8plus (operands[0], operands[1],
5700 operands[2], GEN_INT (32)));
5706 (define_insn "umulsi3_highpart_v8plus"
5707 [(set (match_operand:SI 0 "register_operand" "=h,r")
5709 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5710 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
5711 (match_operand:SI 3 "const_int_operand" "i,i"))))
5712 (clobber (match_scratch:SI 4 "=X,h"))]
5715 umul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
5716 umul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
5717 [(set_attr "type" "multi")
5718 (set_attr "length" "2")])
5721 (define_insn "const_umulsi3_highpart_v8plus"
5722 [(set (match_operand:SI 0 "register_operand" "=h,r")
5724 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5725 (match_operand:DI 2 "uns_small_int" ""))
5726 (match_operand:SI 3 "const_int_operand" "i,i"))))
5727 (clobber (match_scratch:SI 4 "=X,h"))]
5730 umul\t%1, %s2, %0\n\tsrlx\t%0, %3, %0
5731 umul\t%1, %s2, %4\n\tsrlx\t%4, %3, %0"
5732 [(set_attr "type" "multi")
5733 (set_attr "length" "2")])
5736 (define_insn "*umulsi3_highpart_sp32"
5737 [(set (match_operand:SI 0 "register_operand" "=r")
5739 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5740 (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
5743 "umul\t%1, %2, %%g0\n\trd\t%%y, %0"
5744 [(set_attr "type" "multi")
5745 (set_attr "length" "2")])
5748 (define_insn "const_umulsi3_highpart"
5749 [(set (match_operand:SI 0 "register_operand" "=r")
5751 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5752 (match_operand:DI 2 "uns_small_int" ""))
5755 "umul\t%1, %s2, %%g0\n\trd\t%%y, %0"
5756 [(set_attr "type" "multi")
5757 (set_attr "length" "2")])
5759 ;; The v8 architecture specifies that there must be 3 instructions between
5760 ;; a y register write and a use of it for correct results.
5762 (define_expand "divsi3"
5763 [(parallel [(set (match_operand:SI 0 "register_operand" "=r,r")
5764 (div:SI (match_operand:SI 1 "register_operand" "r,r")
5765 (match_operand:SI 2 "input_operand" "rI,m")))
5766 (clobber (match_scratch:SI 3 "=&r,&r"))])]
5767 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
5771 operands[3] = gen_reg_rtx(SImode);
5772 emit_insn (gen_ashrsi3 (operands[3], operands[1], GEN_INT (31)));
5773 emit_insn (gen_divsi3_sp64 (operands[0], operands[1], operands[2],
5779 (define_insn "divsi3_sp32"
5780 [(set (match_operand:SI 0 "register_operand" "=r,r")
5781 (div:SI (match_operand:SI 1 "register_operand" "r,r")
5782 (match_operand:SI 2 "input_operand" "rI,m")))
5783 (clobber (match_scratch:SI 3 "=&r,&r"))]
5784 "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS)
5787 if (which_alternative == 0)
5789 return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tsdiv\t%1, %2, %0";
5791 return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tnop\n\tnop\n\tnop\n\tsdiv\t%1, %2, %0";
5794 return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tld\t%2, %3\n\tsdiv\t%1, %3, %0";
5796 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";
5798 [(set_attr "type" "multi")
5799 (set (attr "length")
5800 (if_then_else (eq_attr "isa" "v9")
5801 (const_int 4) (const_int 6)))])
5803 (define_insn "divsi3_sp64"
5804 [(set (match_operand:SI 0 "register_operand" "=r")
5805 (div:SI (match_operand:SI 1 "register_operand" "r")
5806 (match_operand:SI 2 "input_operand" "rI")))
5807 (use (match_operand:SI 3 "register_operand" "r"))]
5808 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5809 "wr\t%%g0, %3, %%y\n\tsdiv\t%1, %2, %0"
5810 [(set_attr "type" "multi")
5811 (set_attr "length" "2")])
5813 (define_insn "divdi3"
5814 [(set (match_operand:DI 0 "register_operand" "=r")
5815 (div:DI (match_operand:DI 1 "register_operand" "r")
5816 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5819 [(set_attr "type" "idiv")])
5821 (define_insn "*cmp_sdiv_cc_set"
5823 (compare:CC (div:SI (match_operand:SI 1 "register_operand" "r")
5824 (match_operand:SI 2 "arith_operand" "rI"))
5826 (set (match_operand:SI 0 "register_operand" "=r")
5827 (div:SI (match_dup 1) (match_dup 2)))
5828 (clobber (match_scratch:SI 3 "=&r"))]
5829 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
5832 return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tsdivcc\t%1, %2, %0";
5834 return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tnop\n\tnop\n\tnop\n\tsdivcc\t%1, %2, %0";
5836 [(set_attr "type" "multi")
5837 (set (attr "length")
5838 (if_then_else (eq_attr "isa" "v9")
5839 (const_int 3) (const_int 6)))])
5842 (define_expand "udivsi3"
5843 [(set (match_operand:SI 0 "register_operand" "")
5844 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "")
5845 (match_operand:SI 2 "input_operand" "")))]
5846 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
5849 (define_insn "udivsi3_sp32"
5850 [(set (match_operand:SI 0 "register_operand" "=r,&r,&r")
5851 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "r,r,m")
5852 (match_operand:SI 2 "input_operand" "rI,m,r")))]
5854 || TARGET_DEPRECATED_V8_INSNS)
5857 output_asm_insn ("wr\t%%g0, %%g0, %%y", operands);
5858 switch (which_alternative)
5861 return "nop\n\tnop\n\tnop\n\tudiv\t%1, %2, %0";
5863 return "ld\t%2, %0\n\tnop\n\tnop\n\tudiv\t%1, %0, %0";
5865 return "ld\t%1, %0\n\tnop\n\tnop\n\tudiv\t%0, %2, %0";
5868 [(set_attr "type" "multi")
5869 (set_attr "length" "5")])
5871 (define_insn "udivsi3_sp64"
5872 [(set (match_operand:SI 0 "register_operand" "=r")
5873 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "r")
5874 (match_operand:SI 2 "input_operand" "rI")))]
5875 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5876 "wr\t%%g0, 0, %%y\n\tudiv\t%1, %2, %0"
5877 [(set_attr "type" "multi")
5878 (set_attr "length" "2")])
5880 (define_insn "udivdi3"
5881 [(set (match_operand:DI 0 "register_operand" "=r")
5882 (udiv:DI (match_operand:DI 1 "register_operand" "r")
5883 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5886 [(set_attr "type" "idiv")])
5888 (define_insn "*cmp_udiv_cc_set"
5890 (compare:CC (udiv:SI (match_operand:SI 1 "register_operand" "r")
5891 (match_operand:SI 2 "arith_operand" "rI"))
5893 (set (match_operand:SI 0 "register_operand" "=r")
5894 (udiv:SI (match_dup 1) (match_dup 2)))]
5896 || TARGET_DEPRECATED_V8_INSNS"
5899 return "wr\t%%g0, %%g0, %%y\n\tudivcc\t%1, %2, %0";
5901 return "wr\t%%g0, %%g0, %%y\n\tnop\n\tnop\n\tnop\n\tudivcc\t%1, %2, %0";
5903 [(set_attr "type" "multi")
5904 (set (attr "length")
5905 (if_then_else (eq_attr "isa" "v9")
5906 (const_int 2) (const_int 5)))])
5908 ; sparclet multiply/accumulate insns
5910 (define_insn "*smacsi"
5911 [(set (match_operand:SI 0 "register_operand" "=r")
5912 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "%r")
5913 (match_operand:SI 2 "arith_operand" "rI"))
5914 (match_operand:SI 3 "register_operand" "0")))]
5917 [(set_attr "type" "imul")])
5919 (define_insn "*smacdi"
5920 [(set (match_operand:DI 0 "register_operand" "=r")
5921 (plus:DI (mult:DI (sign_extend:DI
5922 (match_operand:SI 1 "register_operand" "%r"))
5924 (match_operand:SI 2 "register_operand" "r")))
5925 (match_operand:DI 3 "register_operand" "0")))]
5927 "smacd\t%1, %2, %L0"
5928 [(set_attr "type" "imul")])
5930 (define_insn "*umacdi"
5931 [(set (match_operand:DI 0 "register_operand" "=r")
5932 (plus:DI (mult:DI (zero_extend:DI
5933 (match_operand:SI 1 "register_operand" "%r"))
5935 (match_operand:SI 2 "register_operand" "r")))
5936 (match_operand:DI 3 "register_operand" "0")))]
5938 "umacd\t%1, %2, %L0"
5939 [(set_attr "type" "imul")])
5941 ;;- Boolean instructions
5942 ;; We define DImode `and' so with DImode `not' we can get
5943 ;; DImode `andn'. Other combinations are possible.
5945 (define_mode_macro V64I [DI V2SI V4HI V8QI])
5946 (define_mode_macro V32I [SI V2HI V4QI])
5948 (define_expand "and<V64I:mode>3"
5949 [(set (match_operand:V64I 0 "register_operand" "")
5950 (and:V64I (match_operand:V64I 1 "arith_double_operand" "")
5951 (match_operand:V64I 2 "arith_double_operand" "")))]
5955 (define_insn "*and<V64I:mode>3_sp32"
5956 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5957 (and:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
5958 (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
5963 [(set_attr "type" "*,fga")
5964 (set_attr "length" "2,*")
5965 (set_attr "fptype" "*,double")])
5967 (define_insn "*and<V64I:mode>3_sp64"
5968 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5969 (and:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
5970 (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
5975 [(set_attr "type" "*,fga")
5976 (set_attr "fptype" "*,double")])
5978 (define_insn "and<V32I:mode>3"
5979 [(set (match_operand:V32I 0 "register_operand" "=r,d")
5980 (and:V32I (match_operand:V32I 1 "arith_operand" "%r,d")
5981 (match_operand:V32I 2 "arith_operand" "rI,d")))]
5986 [(set_attr "type" "*,fga")
5987 (set_attr "fptype" "*,single")])
5990 [(set (match_operand:SI 0 "register_operand" "")
5991 (and:SI (match_operand:SI 1 "register_operand" "")
5992 (match_operand:SI 2 "" "")))
5993 (clobber (match_operand:SI 3 "register_operand" ""))]
5994 "GET_CODE (operands[2]) == CONST_INT
5995 && !SMALL_INT32 (operands[2])
5996 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
5997 [(set (match_dup 3) (match_dup 4))
5998 (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 1)))]
6000 operands[4] = GEN_INT (~INTVAL (operands[2]));
6003 (define_insn_and_split "*and_not_<V64I:mode>_sp32"
6004 [(set (match_operand:V64I 0 "register_operand" "=r,b")
6005 (and:V64I (not:V64I (match_operand:V64I 1 "register_operand" "%r,b"))
6006 (match_operand:V64I 2 "register_operand" "r,b")))]
6010 fandnot1\t%1, %2, %0"
6011 "&& reload_completed
6012 && ((GET_CODE (operands[0]) == REG
6013 && REGNO (operands[0]) < 32)
6014 || (GET_CODE (operands[0]) == SUBREG
6015 && GET_CODE (SUBREG_REG (operands[0])) == REG
6016 && REGNO (SUBREG_REG (operands[0])) < 32))"
6017 [(set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))
6018 (set (match_dup 6) (and:SI (not:SI (match_dup 7)) (match_dup 8)))]
6019 "operands[3] = gen_highpart (SImode, operands[0]);
6020 operands[4] = gen_highpart (SImode, operands[1]);
6021 operands[5] = gen_highpart (SImode, operands[2]);
6022 operands[6] = gen_lowpart (SImode, operands[0]);
6023 operands[7] = gen_lowpart (SImode, operands[1]);
6024 operands[8] = gen_lowpart (SImode, operands[2]);"
6025 [(set_attr "type" "*,fga")
6026 (set_attr "length" "2,*")
6027 (set_attr "fptype" "*,double")])
6029 (define_insn "*and_not_<V64I:mode>_sp64"
6030 [(set (match_operand:V64I 0 "register_operand" "=r,b")
6031 (and:V64I (not:V64I (match_operand:V64I 1 "register_operand" "%r,b"))
6032 (match_operand:V64I 2 "register_operand" "r,b")))]
6036 fandnot1\t%1, %2, %0"
6037 [(set_attr "type" "*,fga")
6038 (set_attr "fptype" "*,double")])
6040 (define_insn "*and_not_<V32I:mode>"
6041 [(set (match_operand:V32I 0 "register_operand" "=r,d")
6042 (and:V32I (not:V32I (match_operand:V32I 1 "register_operand" "%r,d"))
6043 (match_operand:V32I 2 "register_operand" "r,d")))]
6047 fandnot1s\t%1, %2, %0"
6048 [(set_attr "type" "*,fga")
6049 (set_attr "fptype" "*,single")])
6051 (define_expand "ior<V64I:mode>3"
6052 [(set (match_operand:V64I 0 "register_operand" "")
6053 (ior:V64I (match_operand:V64I 1 "arith_double_operand" "")
6054 (match_operand:V64I 2 "arith_double_operand" "")))]
6058 (define_insn "*ior<V64I:mode>3_sp32"
6059 [(set (match_operand:V64I 0 "register_operand" "=r,b")
6060 (ior:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
6061 (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
6066 [(set_attr "type" "*,fga")
6067 (set_attr "length" "2,*")
6068 (set_attr "fptype" "*,double")])
6070 (define_insn "*ior<V64I:mode>3_sp64"
6071 [(set (match_operand:V64I 0 "register_operand" "=r,b")
6072 (ior:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
6073 (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
6078 [(set_attr "type" "*,fga")
6079 (set_attr "fptype" "*,double")])
6081 (define_insn "ior<V32I:mode>3"
6082 [(set (match_operand:V32I 0 "register_operand" "=r,d")
6083 (ior:V32I (match_operand:V32I 1 "arith_operand" "%r,d")
6084 (match_operand:V32I 2 "arith_operand" "rI,d")))]
6089 [(set_attr "type" "*,fga")
6090 (set_attr "fptype" "*,single")])
6093 [(set (match_operand:SI 0 "register_operand" "")
6094 (ior:SI (match_operand:SI 1 "register_operand" "")
6095 (match_operand:SI 2 "" "")))
6096 (clobber (match_operand:SI 3 "register_operand" ""))]
6097 "GET_CODE (operands[2]) == CONST_INT
6098 && !SMALL_INT32 (operands[2])
6099 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6100 [(set (match_dup 3) (match_dup 4))
6101 (set (match_dup 0) (ior:SI (not:SI (match_dup 3)) (match_dup 1)))]
6103 operands[4] = GEN_INT (~INTVAL (operands[2]));
6106 (define_insn_and_split "*or_not_<V64I:mode>_sp32"
6107 [(set (match_operand:V64I 0 "register_operand" "=r,b")
6108 (ior:V64I (not:V64I (match_operand:V64I 1 "register_operand" "r,b"))
6109 (match_operand:V64I 2 "register_operand" "r,b")))]
6113 fornot1\t%1, %2, %0"
6114 "&& reload_completed
6115 && ((GET_CODE (operands[0]) == REG
6116 && REGNO (operands[0]) < 32)
6117 || (GET_CODE (operands[0]) == SUBREG
6118 && GET_CODE (SUBREG_REG (operands[0])) == REG
6119 && REGNO (SUBREG_REG (operands[0])) < 32))"
6120 [(set (match_dup 3) (ior:SI (not:SI (match_dup 4)) (match_dup 5)))
6121 (set (match_dup 6) (ior:SI (not:SI (match_dup 7)) (match_dup 8)))]
6122 "operands[3] = gen_highpart (SImode, operands[0]);
6123 operands[4] = gen_highpart (SImode, operands[1]);
6124 operands[5] = gen_highpart (SImode, operands[2]);
6125 operands[6] = gen_lowpart (SImode, operands[0]);
6126 operands[7] = gen_lowpart (SImode, operands[1]);
6127 operands[8] = gen_lowpart (SImode, operands[2]);"
6128 [(set_attr "type" "*,fga")
6129 (set_attr "length" "2,*")
6130 (set_attr "fptype" "*,double")])
6132 (define_insn "*or_not_<V64I:mode>_sp64"
6133 [(set (match_operand:V64I 0 "register_operand" "=r,b")
6134 (ior:V64I (not:V64I (match_operand:V64I 1 "register_operand" "r,b"))
6135 (match_operand:V64I 2 "register_operand" "r,b")))]
6139 fornot1\t%1, %2, %0"
6140 [(set_attr "type" "*,fga")
6141 (set_attr "fptype" "*,double")])
6143 (define_insn "*or_not_<V32I:mode>"
6144 [(set (match_operand:V32I 0 "register_operand" "=r,d")
6145 (ior:V32I (not:V32I (match_operand:V32I 1 "register_operand" "r,d"))
6146 (match_operand:V32I 2 "register_operand" "r,d")))]
6150 fornot1s\t%1, %2, %0"
6151 [(set_attr "type" "*,fga")
6152 (set_attr "fptype" "*,single")])
6154 (define_expand "xor<V64I:mode>3"
6155 [(set (match_operand:V64I 0 "register_operand" "")
6156 (xor:V64I (match_operand:V64I 1 "arith_double_operand" "")
6157 (match_operand:V64I 2 "arith_double_operand" "")))]
6161 (define_insn "*xor<V64I:mode>3_sp32"
6162 [(set (match_operand:V64I 0 "register_operand" "=r,b")
6163 (xor:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
6164 (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
6169 [(set_attr "type" "*,fga")
6170 (set_attr "length" "2,*")
6171 (set_attr "fptype" "*,double")])
6173 (define_insn "*xor<V64I:mode>3_sp64"
6174 [(set (match_operand:V64I 0 "register_operand" "=r,b")
6175 (xor:V64I (match_operand:V64I 1 "arith_double_operand" "%rJ,b")
6176 (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
6181 [(set_attr "type" "*,fga")
6182 (set_attr "fptype" "*,double")])
6184 (define_insn "*xordi3_sp64_dbl"
6185 [(set (match_operand:DI 0 "register_operand" "=r")
6186 (xor:DI (match_operand:DI 1 "register_operand" "r")
6187 (match_operand:DI 2 "const64_operand" "")))]
6189 && HOST_BITS_PER_WIDE_INT != 64)"
6192 (define_insn "xor<V32I:mode>3"
6193 [(set (match_operand:V32I 0 "register_operand" "=r,d")
6194 (xor:V32I (match_operand:V32I 1 "arith_operand" "%rJ,d")
6195 (match_operand:V32I 2 "arith_operand" "rI,d")))]
6200 [(set_attr "type" "*,fga")
6201 (set_attr "fptype" "*,single")])
6204 [(set (match_operand:SI 0 "register_operand" "")
6205 (xor:SI (match_operand:SI 1 "register_operand" "")
6206 (match_operand:SI 2 "" "")))
6207 (clobber (match_operand:SI 3 "register_operand" ""))]
6208 "GET_CODE (operands[2]) == CONST_INT
6209 && !SMALL_INT32 (operands[2])
6210 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6211 [(set (match_dup 3) (match_dup 4))
6212 (set (match_dup 0) (not:SI (xor:SI (match_dup 3) (match_dup 1))))]
6214 operands[4] = GEN_INT (~INTVAL (operands[2]));
6218 [(set (match_operand:SI 0 "register_operand" "")
6219 (not:SI (xor:SI (match_operand:SI 1 "register_operand" "")
6220 (match_operand:SI 2 "" ""))))
6221 (clobber (match_operand:SI 3 "register_operand" ""))]
6222 "GET_CODE (operands[2]) == CONST_INT
6223 && !SMALL_INT32 (operands[2])
6224 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6225 [(set (match_dup 3) (match_dup 4))
6226 (set (match_dup 0) (xor:SI (match_dup 3) (match_dup 1)))]
6228 operands[4] = GEN_INT (~INTVAL (operands[2]));
6231 ;; Split DImode logical operations requiring two instructions.
6233 [(set (match_operand:V64I 0 "register_operand" "")
6234 (match_operator:V64I 1 "cc_arithop" ; AND, IOR, XOR
6235 [(match_operand:V64I 2 "register_operand" "")
6236 (match_operand:V64I 3 "arith_double_operand" "")]))]
6239 && ((GET_CODE (operands[0]) == REG
6240 && REGNO (operands[0]) < 32)
6241 || (GET_CODE (operands[0]) == SUBREG
6242 && GET_CODE (SUBREG_REG (operands[0])) == REG
6243 && REGNO (SUBREG_REG (operands[0])) < 32))"
6244 [(set (match_dup 4) (match_op_dup:SI 1 [(match_dup 6) (match_dup 8)]))
6245 (set (match_dup 5) (match_op_dup:SI 1 [(match_dup 7) (match_dup 9)]))]
6247 operands[4] = gen_highpart (SImode, operands[0]);
6248 operands[5] = gen_lowpart (SImode, operands[0]);
6249 operands[6] = gen_highpart (SImode, operands[2]);
6250 operands[7] = gen_lowpart (SImode, operands[2]);
6251 #if HOST_BITS_PER_WIDE_INT == 32
6252 if (GET_CODE (operands[3]) == CONST_INT && <V64I:MODE>mode == DImode)
6254 if (INTVAL (operands[3]) < 0)
6255 operands[8] = constm1_rtx;
6257 operands[8] = const0_rtx;
6261 operands[8] = gen_highpart_mode (SImode, <V64I:MODE>mode, operands[3]);
6262 operands[9] = gen_lowpart (SImode, operands[3]);
6265 ;; xnor patterns. Note that (a ^ ~b) == (~a ^ b) == ~(a ^ b).
6266 ;; Combine now canonicalizes to the rightmost expression.
6267 (define_insn_and_split "*xor_not_<V64I:mode>_sp32"
6268 [(set (match_operand:V64I 0 "register_operand" "=r,b")
6269 (not:V64I (xor:V64I (match_operand:V64I 1 "register_operand" "r,b")
6270 (match_operand:V64I 2 "register_operand" "r,b"))))]
6275 "&& reload_completed
6276 && ((GET_CODE (operands[0]) == REG
6277 && REGNO (operands[0]) < 32)
6278 || (GET_CODE (operands[0]) == SUBREG
6279 && GET_CODE (SUBREG_REG (operands[0])) == REG
6280 && REGNO (SUBREG_REG (operands[0])) < 32))"
6281 [(set (match_dup 3) (not:SI (xor:SI (match_dup 4) (match_dup 5))))
6282 (set (match_dup 6) (not:SI (xor:SI (match_dup 7) (match_dup 8))))]
6283 "operands[3] = gen_highpart (SImode, operands[0]);
6284 operands[4] = gen_highpart (SImode, operands[1]);
6285 operands[5] = gen_highpart (SImode, operands[2]);
6286 operands[6] = gen_lowpart (SImode, operands[0]);
6287 operands[7] = gen_lowpart (SImode, operands[1]);
6288 operands[8] = gen_lowpart (SImode, operands[2]);"
6289 [(set_attr "type" "*,fga")
6290 (set_attr "length" "2,*")
6291 (set_attr "fptype" "*,double")])
6293 (define_insn "*xor_not_<V64I:mode>_sp64"
6294 [(set (match_operand:V64I 0 "register_operand" "=r,b")
6295 (not:V64I (xor:V64I (match_operand:V64I 1 "reg_or_0_operand" "rJ,b")
6296 (match_operand:V64I 2 "arith_double_operand" "rHI,b"))))]
6301 [(set_attr "type" "*,fga")
6302 (set_attr "fptype" "*,double")])
6304 (define_insn "*xor_not_<V32I:mode>"
6305 [(set (match_operand:V32I 0 "register_operand" "=r,d")
6306 (not:V32I (xor:V32I (match_operand:V32I 1 "reg_or_0_operand" "rJ,d")
6307 (match_operand:V32I 2 "arith_operand" "rI,d"))))]
6312 [(set_attr "type" "*,fga")
6313 (set_attr "fptype" "*,single")])
6315 ;; These correspond to the above in the case where we also (or only)
6316 ;; want to set the condition code.
6318 (define_insn "*cmp_cc_arith_op"
6321 (match_operator:SI 2 "cc_arithop"
6322 [(match_operand:SI 0 "arith_operand" "%r")
6323 (match_operand:SI 1 "arith_operand" "rI")])
6326 "%A2cc\t%0, %1, %%g0"
6327 [(set_attr "type" "compare")])
6329 (define_insn "*cmp_ccx_arith_op"
6332 (match_operator:DI 2 "cc_arithop"
6333 [(match_operand:DI 0 "arith_double_operand" "%r")
6334 (match_operand:DI 1 "arith_double_operand" "rHI")])
6337 "%A2cc\t%0, %1, %%g0"
6338 [(set_attr "type" "compare")])
6340 (define_insn "*cmp_cc_arith_op_set"
6343 (match_operator:SI 3 "cc_arithop"
6344 [(match_operand:SI 1 "arith_operand" "%r")
6345 (match_operand:SI 2 "arith_operand" "rI")])
6347 (set (match_operand:SI 0 "register_operand" "=r")
6348 (match_operator:SI 4 "cc_arithop" [(match_dup 1) (match_dup 2)]))]
6349 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
6351 [(set_attr "type" "compare")])
6353 (define_insn "*cmp_ccx_arith_op_set"
6356 (match_operator:DI 3 "cc_arithop"
6357 [(match_operand:DI 1 "arith_double_operand" "%r")
6358 (match_operand:DI 2 "arith_double_operand" "rHI")])
6360 (set (match_operand:DI 0 "register_operand" "=r")
6361 (match_operator:DI 4 "cc_arithop" [(match_dup 1) (match_dup 2)]))]
6362 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
6364 [(set_attr "type" "compare")])
6366 (define_insn "*cmp_cc_xor_not"
6369 (not:SI (xor:SI (match_operand:SI 0 "reg_or_0_operand" "%rJ")
6370 (match_operand:SI 1 "arith_operand" "rI")))
6373 "xnorcc\t%r0, %1, %%g0"
6374 [(set_attr "type" "compare")])
6376 (define_insn "*cmp_ccx_xor_not"
6379 (not:DI (xor:DI (match_operand:DI 0 "reg_or_0_operand" "%rJ")
6380 (match_operand:DI 1 "arith_double_operand" "rHI")))
6383 "xnorcc\t%r0, %1, %%g0"
6384 [(set_attr "type" "compare")])
6386 (define_insn "*cmp_cc_xor_not_set"
6389 (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
6390 (match_operand:SI 2 "arith_operand" "rI")))
6392 (set (match_operand:SI 0 "register_operand" "=r")
6393 (not:SI (xor:SI (match_dup 1) (match_dup 2))))]
6395 "xnorcc\t%r1, %2, %0"
6396 [(set_attr "type" "compare")])
6398 (define_insn "*cmp_ccx_xor_not_set"
6401 (not:DI (xor:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ")
6402 (match_operand:DI 2 "arith_double_operand" "rHI")))
6404 (set (match_operand:DI 0 "register_operand" "=r")
6405 (not:DI (xor:DI (match_dup 1) (match_dup 2))))]
6407 "xnorcc\t%r1, %2, %0"
6408 [(set_attr "type" "compare")])
6410 (define_insn "*cmp_cc_arith_op_not"
6413 (match_operator:SI 2 "cc_arithopn"
6414 [(not:SI (match_operand:SI 0 "arith_operand" "rI"))
6415 (match_operand:SI 1 "reg_or_0_operand" "rJ")])
6418 "%B2cc\t%r1, %0, %%g0"
6419 [(set_attr "type" "compare")])
6421 (define_insn "*cmp_ccx_arith_op_not"
6424 (match_operator:DI 2 "cc_arithopn"
6425 [(not:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
6426 (match_operand:DI 1 "reg_or_0_operand" "rJ")])
6429 "%B2cc\t%r1, %0, %%g0"
6430 [(set_attr "type" "compare")])
6432 (define_insn "*cmp_cc_arith_op_not_set"
6435 (match_operator:SI 3 "cc_arithopn"
6436 [(not:SI (match_operand:SI 1 "arith_operand" "rI"))
6437 (match_operand:SI 2 "reg_or_0_operand" "rJ")])
6439 (set (match_operand:SI 0 "register_operand" "=r")
6440 (match_operator:SI 4 "cc_arithopn"
6441 [(not:SI (match_dup 1)) (match_dup 2)]))]
6442 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
6443 "%B3cc\t%r2, %1, %0"
6444 [(set_attr "type" "compare")])
6446 (define_insn "*cmp_ccx_arith_op_not_set"
6449 (match_operator:DI 3 "cc_arithopn"
6450 [(not:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
6451 (match_operand:DI 2 "reg_or_0_operand" "rJ")])
6453 (set (match_operand:DI 0 "register_operand" "=r")
6454 (match_operator:DI 4 "cc_arithopn"
6455 [(not:DI (match_dup 1)) (match_dup 2)]))]
6456 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
6457 "%B3cc\t%r2, %1, %0"
6458 [(set_attr "type" "compare")])
6460 ;; We cannot use the "neg" pseudo insn because the Sun assembler
6461 ;; does not know how to make it work for constants.
6463 (define_expand "negdi2"
6464 [(set (match_operand:DI 0 "register_operand" "=r")
6465 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
6468 if (! TARGET_ARCH64)
6470 emit_insn (gen_rtx_PARALLEL
6473 gen_rtx_SET (VOIDmode, operand0,
6474 gen_rtx_NEG (DImode, operand1)),
6475 gen_rtx_CLOBBER (VOIDmode,
6476 gen_rtx_REG (CCmode,
6482 (define_insn_and_split "*negdi2_sp32"
6483 [(set (match_operand:DI 0 "register_operand" "=r")
6484 (neg:DI (match_operand:DI 1 "register_operand" "r")))
6485 (clobber (reg:CC 100))]
6488 "&& reload_completed"
6489 [(parallel [(set (reg:CC_NOOV 100)
6490 (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 5))
6492 (set (match_dup 4) (minus:SI (const_int 0) (match_dup 5)))])
6493 (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
6494 (ltu:SI (reg:CC 100) (const_int 0))))]
6495 "operands[2] = gen_highpart (SImode, operands[0]);
6496 operands[3] = gen_highpart (SImode, operands[1]);
6497 operands[4] = gen_lowpart (SImode, operands[0]);
6498 operands[5] = gen_lowpart (SImode, operands[1]);"
6499 [(set_attr "length" "2")])
6501 (define_insn "*negdi2_sp64"
6502 [(set (match_operand:DI 0 "register_operand" "=r")
6503 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
6505 "sub\t%%g0, %1, %0")
6507 (define_insn "negsi2"
6508 [(set (match_operand:SI 0 "register_operand" "=r")
6509 (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
6511 "sub\t%%g0, %1, %0")
6513 (define_insn "*cmp_cc_neg"
6514 [(set (reg:CC_NOOV 100)
6515 (compare:CC_NOOV (neg:SI (match_operand:SI 0 "arith_operand" "rI"))
6518 "subcc\t%%g0, %0, %%g0"
6519 [(set_attr "type" "compare")])
6521 (define_insn "*cmp_ccx_neg"
6522 [(set (reg:CCX_NOOV 100)
6523 (compare:CCX_NOOV (neg:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
6526 "subcc\t%%g0, %0, %%g0"
6527 [(set_attr "type" "compare")])
6529 (define_insn "*cmp_cc_set_neg"
6530 [(set (reg:CC_NOOV 100)
6531 (compare:CC_NOOV (neg:SI (match_operand:SI 1 "arith_operand" "rI"))
6533 (set (match_operand:SI 0 "register_operand" "=r")
6534 (neg:SI (match_dup 1)))]
6536 "subcc\t%%g0, %1, %0"
6537 [(set_attr "type" "compare")])
6539 (define_insn "*cmp_ccx_set_neg"
6540 [(set (reg:CCX_NOOV 100)
6541 (compare:CCX_NOOV (neg:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
6543 (set (match_operand:DI 0 "register_operand" "=r")
6544 (neg:DI (match_dup 1)))]
6546 "subcc\t%%g0, %1, %0"
6547 [(set_attr "type" "compare")])
6549 ;; We cannot use the "not" pseudo insn because the Sun assembler
6550 ;; does not know how to make it work for constants.
6551 (define_expand "one_cmpl<V64I:mode>2"
6552 [(set (match_operand:V64I 0 "register_operand" "")
6553 (not:V64I (match_operand:V64I 1 "register_operand" "")))]
6557 (define_insn_and_split "*one_cmpl<V64I:mode>2_sp32"
6558 [(set (match_operand:V64I 0 "register_operand" "=r,b")
6559 (not:V64I (match_operand:V64I 1 "register_operand" "r,b")))]
6564 "&& reload_completed
6565 && ((GET_CODE (operands[0]) == REG
6566 && REGNO (operands[0]) < 32)
6567 || (GET_CODE (operands[0]) == SUBREG
6568 && GET_CODE (SUBREG_REG (operands[0])) == REG
6569 && REGNO (SUBREG_REG (operands[0])) < 32))"
6570 [(set (match_dup 2) (not:SI (xor:SI (match_dup 3) (const_int 0))))
6571 (set (match_dup 4) (not:SI (xor:SI (match_dup 5) (const_int 0))))]
6572 "operands[2] = gen_highpart (SImode, operands[0]);
6573 operands[3] = gen_highpart (SImode, operands[1]);
6574 operands[4] = gen_lowpart (SImode, operands[0]);
6575 operands[5] = gen_lowpart (SImode, operands[1]);"
6576 [(set_attr "type" "*,fga")
6577 (set_attr "length" "2,*")
6578 (set_attr "fptype" "*,double")])
6580 (define_insn "*one_cmpl<V64I:mode>2_sp64"
6581 [(set (match_operand:V64I 0 "register_operand" "=r,b")
6582 (not:V64I (match_operand:V64I 1 "arith_double_operand" "rHI,b")))]
6587 [(set_attr "type" "*,fga")
6588 (set_attr "fptype" "*,double")])
6590 (define_insn "one_cmpl<V32I:mode>2"
6591 [(set (match_operand:V32I 0 "register_operand" "=r,d")
6592 (not:V32I (match_operand:V32I 1 "arith_operand" "rI,d")))]
6597 [(set_attr "type" "*,fga")
6598 (set_attr "fptype" "*,single")])
6600 (define_insn "*cmp_cc_not"
6602 (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI"))
6605 "xnorcc\t%%g0, %0, %%g0"
6606 [(set_attr "type" "compare")])
6608 (define_insn "*cmp_ccx_not"
6610 (compare:CCX (not:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
6613 "xnorcc\t%%g0, %0, %%g0"
6614 [(set_attr "type" "compare")])
6616 (define_insn "*cmp_cc_set_not"
6618 (compare:CC (not:SI (match_operand:SI 1 "arith_operand" "rI"))
6620 (set (match_operand:SI 0 "register_operand" "=r")
6621 (not:SI (match_dup 1)))]
6623 "xnorcc\t%%g0, %1, %0"
6624 [(set_attr "type" "compare")])
6626 (define_insn "*cmp_ccx_set_not"
6628 (compare:CCX (not:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
6630 (set (match_operand:DI 0 "register_operand" "=r")
6631 (not:DI (match_dup 1)))]
6633 "xnorcc\t%%g0, %1, %0"
6634 [(set_attr "type" "compare")])
6636 (define_insn "*cmp_cc_set"
6637 [(set (match_operand:SI 0 "register_operand" "=r")
6638 (match_operand:SI 1 "register_operand" "r"))
6640 (compare:CC (match_dup 1)
6644 [(set_attr "type" "compare")])
6646 (define_insn "*cmp_ccx_set64"
6647 [(set (match_operand:DI 0 "register_operand" "=r")
6648 (match_operand:DI 1 "register_operand" "r"))
6650 (compare:CCX (match_dup 1)
6654 [(set_attr "type" "compare")])
6656 ;; Floating point arithmetic instructions.
6658 (define_expand "addtf3"
6659 [(set (match_operand:TF 0 "nonimmediate_operand" "")
6660 (plus:TF (match_operand:TF 1 "general_operand" "")
6661 (match_operand:TF 2 "general_operand" "")))]
6662 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6663 "emit_tfmode_binop (PLUS, operands); DONE;")
6665 (define_insn "*addtf3_hq"
6666 [(set (match_operand:TF 0 "register_operand" "=e")
6667 (plus:TF (match_operand:TF 1 "register_operand" "e")
6668 (match_operand:TF 2 "register_operand" "e")))]
6669 "TARGET_FPU && TARGET_HARD_QUAD"
6671 [(set_attr "type" "fp")])
6673 (define_insn "adddf3"
6674 [(set (match_operand:DF 0 "register_operand" "=e")
6675 (plus:DF (match_operand:DF 1 "register_operand" "e")
6676 (match_operand:DF 2 "register_operand" "e")))]
6679 [(set_attr "type" "fp")
6680 (set_attr "fptype" "double")])
6682 (define_insn "addsf3"
6683 [(set (match_operand:SF 0 "register_operand" "=f")
6684 (plus:SF (match_operand:SF 1 "register_operand" "f")
6685 (match_operand:SF 2 "register_operand" "f")))]
6688 [(set_attr "type" "fp")])
6690 (define_expand "subtf3"
6691 [(set (match_operand:TF 0 "nonimmediate_operand" "")
6692 (minus:TF (match_operand:TF 1 "general_operand" "")
6693 (match_operand:TF 2 "general_operand" "")))]
6694 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6695 "emit_tfmode_binop (MINUS, operands); DONE;")
6697 (define_insn "*subtf3_hq"
6698 [(set (match_operand:TF 0 "register_operand" "=e")
6699 (minus:TF (match_operand:TF 1 "register_operand" "e")
6700 (match_operand:TF 2 "register_operand" "e")))]
6701 "TARGET_FPU && TARGET_HARD_QUAD"
6703 [(set_attr "type" "fp")])
6705 (define_insn "subdf3"
6706 [(set (match_operand:DF 0 "register_operand" "=e")
6707 (minus:DF (match_operand:DF 1 "register_operand" "e")
6708 (match_operand:DF 2 "register_operand" "e")))]
6711 [(set_attr "type" "fp")
6712 (set_attr "fptype" "double")])
6714 (define_insn "subsf3"
6715 [(set (match_operand:SF 0 "register_operand" "=f")
6716 (minus:SF (match_operand:SF 1 "register_operand" "f")
6717 (match_operand:SF 2 "register_operand" "f")))]
6720 [(set_attr "type" "fp")])
6722 (define_expand "multf3"
6723 [(set (match_operand:TF 0 "nonimmediate_operand" "")
6724 (mult:TF (match_operand:TF 1 "general_operand" "")
6725 (match_operand:TF 2 "general_operand" "")))]
6726 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6727 "emit_tfmode_binop (MULT, operands); DONE;")
6729 (define_insn "*multf3_hq"
6730 [(set (match_operand:TF 0 "register_operand" "=e")
6731 (mult:TF (match_operand:TF 1 "register_operand" "e")
6732 (match_operand:TF 2 "register_operand" "e")))]
6733 "TARGET_FPU && TARGET_HARD_QUAD"
6735 [(set_attr "type" "fpmul")])
6737 (define_insn "muldf3"
6738 [(set (match_operand:DF 0 "register_operand" "=e")
6739 (mult:DF (match_operand:DF 1 "register_operand" "e")
6740 (match_operand:DF 2 "register_operand" "e")))]
6743 [(set_attr "type" "fpmul")
6744 (set_attr "fptype" "double")])
6746 (define_insn "mulsf3"
6747 [(set (match_operand:SF 0 "register_operand" "=f")
6748 (mult:SF (match_operand:SF 1 "register_operand" "f")
6749 (match_operand:SF 2 "register_operand" "f")))]
6752 [(set_attr "type" "fpmul")])
6754 (define_insn "*muldf3_extend"
6755 [(set (match_operand:DF 0 "register_operand" "=e")
6756 (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "f"))
6757 (float_extend:DF (match_operand:SF 2 "register_operand" "f"))))]
6758 "(TARGET_V8 || TARGET_V9) && TARGET_FPU"
6759 "fsmuld\t%1, %2, %0"
6760 [(set_attr "type" "fpmul")
6761 (set_attr "fptype" "double")])
6763 (define_insn "*multf3_extend"
6764 [(set (match_operand:TF 0 "register_operand" "=e")
6765 (mult:TF (float_extend:TF (match_operand:DF 1 "register_operand" "e"))
6766 (float_extend:TF (match_operand:DF 2 "register_operand" "e"))))]
6767 "(TARGET_V8 || TARGET_V9) && TARGET_FPU && TARGET_HARD_QUAD"
6768 "fdmulq\t%1, %2, %0"
6769 [(set_attr "type" "fpmul")])
6771 (define_expand "divtf3"
6772 [(set (match_operand:TF 0 "nonimmediate_operand" "")
6773 (div:TF (match_operand:TF 1 "general_operand" "")
6774 (match_operand:TF 2 "general_operand" "")))]
6775 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6776 "emit_tfmode_binop (DIV, operands); DONE;")
6778 ;; don't have timing for quad-prec. divide.
6779 (define_insn "*divtf3_hq"
6780 [(set (match_operand:TF 0 "register_operand" "=e")
6781 (div:TF (match_operand:TF 1 "register_operand" "e")
6782 (match_operand:TF 2 "register_operand" "e")))]
6783 "TARGET_FPU && TARGET_HARD_QUAD"
6785 [(set_attr "type" "fpdivd")])
6787 (define_insn "divdf3"
6788 [(set (match_operand:DF 0 "register_operand" "=e")
6789 (div:DF (match_operand:DF 1 "register_operand" "e")
6790 (match_operand:DF 2 "register_operand" "e")))]
6793 [(set_attr "type" "fpdivd")
6794 (set_attr "fptype" "double")])
6796 (define_insn "divsf3"
6797 [(set (match_operand:SF 0 "register_operand" "=f")
6798 (div:SF (match_operand:SF 1 "register_operand" "f")
6799 (match_operand:SF 2 "register_operand" "f")))]
6802 [(set_attr "type" "fpdivs")])
6804 (define_expand "negtf2"
6805 [(set (match_operand:TF 0 "register_operand" "=e,e")
6806 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
6810 (define_insn_and_split "*negtf2_notv9"
6811 [(set (match_operand:TF 0 "register_operand" "=e,e")
6812 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
6813 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
6819 "&& reload_completed
6820 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6821 [(set (match_dup 2) (neg:SF (match_dup 3)))
6822 (set (match_dup 4) (match_dup 5))
6823 (set (match_dup 6) (match_dup 7))]
6824 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6825 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6826 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6827 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
6828 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6829 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6830 [(set_attr "type" "fpmove,*")
6831 (set_attr "length" "*,2")])
6833 (define_insn_and_split "*negtf2_v9"
6834 [(set (match_operand:TF 0 "register_operand" "=e,e")
6835 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
6836 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
6837 "TARGET_FPU && TARGET_V9"
6841 "&& reload_completed
6842 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6843 [(set (match_dup 2) (neg:DF (match_dup 3)))
6844 (set (match_dup 4) (match_dup 5))]
6845 "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
6846 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
6847 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6848 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6849 [(set_attr "type" "fpmove,*")
6850 (set_attr "length" "*,2")
6851 (set_attr "fptype" "double")])
6853 (define_expand "negdf2"
6854 [(set (match_operand:DF 0 "register_operand" "")
6855 (neg:DF (match_operand:DF 1 "register_operand" "")))]
6859 (define_insn_and_split "*negdf2_notv9"
6860 [(set (match_operand:DF 0 "register_operand" "=e,e")
6861 (neg:DF (match_operand:DF 1 "register_operand" "0,e")))]
6862 "TARGET_FPU && ! TARGET_V9"
6866 "&& reload_completed
6867 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6868 [(set (match_dup 2) (neg:SF (match_dup 3)))
6869 (set (match_dup 4) (match_dup 5))]
6870 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6871 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6872 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6873 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);"
6874 [(set_attr "type" "fpmove,*")
6875 (set_attr "length" "*,2")])
6877 (define_insn "*negdf2_v9"
6878 [(set (match_operand:DF 0 "register_operand" "=e")
6879 (neg:DF (match_operand:DF 1 "register_operand" "e")))]
6880 "TARGET_FPU && TARGET_V9"
6882 [(set_attr "type" "fpmove")
6883 (set_attr "fptype" "double")])
6885 (define_insn "negsf2"
6886 [(set (match_operand:SF 0 "register_operand" "=f")
6887 (neg:SF (match_operand:SF 1 "register_operand" "f")))]
6890 [(set_attr "type" "fpmove")])
6892 (define_expand "abstf2"
6893 [(set (match_operand:TF 0 "register_operand" "")
6894 (abs:TF (match_operand:TF 1 "register_operand" "")))]
6898 (define_insn_and_split "*abstf2_notv9"
6899 [(set (match_operand:TF 0 "register_operand" "=e,e")
6900 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6901 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
6902 "TARGET_FPU && ! TARGET_V9"
6906 "&& reload_completed
6907 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6908 [(set (match_dup 2) (abs:SF (match_dup 3)))
6909 (set (match_dup 4) (match_dup 5))
6910 (set (match_dup 6) (match_dup 7))]
6911 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6912 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6913 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6914 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
6915 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6916 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6917 [(set_attr "type" "fpmove,*")
6918 (set_attr "length" "*,2")])
6920 (define_insn "*abstf2_hq_v9"
6921 [(set (match_operand:TF 0 "register_operand" "=e,e")
6922 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6923 "TARGET_FPU && TARGET_V9 && TARGET_HARD_QUAD"
6927 [(set_attr "type" "fpmove")
6928 (set_attr "fptype" "double,*")])
6930 (define_insn_and_split "*abstf2_v9"
6931 [(set (match_operand:TF 0 "register_operand" "=e,e")
6932 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6933 "TARGET_FPU && TARGET_V9 && !TARGET_HARD_QUAD"
6937 "&& reload_completed
6938 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6939 [(set (match_dup 2) (abs:DF (match_dup 3)))
6940 (set (match_dup 4) (match_dup 5))]
6941 "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
6942 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
6943 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6944 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6945 [(set_attr "type" "fpmove,*")
6946 (set_attr "length" "*,2")
6947 (set_attr "fptype" "double,*")])
6949 (define_expand "absdf2"
6950 [(set (match_operand:DF 0 "register_operand" "")
6951 (abs:DF (match_operand:DF 1 "register_operand" "")))]
6955 (define_insn_and_split "*absdf2_notv9"
6956 [(set (match_operand:DF 0 "register_operand" "=e,e")
6957 (abs:DF (match_operand:DF 1 "register_operand" "0,e")))]
6958 "TARGET_FPU && ! TARGET_V9"
6962 "&& reload_completed
6963 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6964 [(set (match_dup 2) (abs:SF (match_dup 3)))
6965 (set (match_dup 4) (match_dup 5))]
6966 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6967 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6968 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6969 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);"
6970 [(set_attr "type" "fpmove,*")
6971 (set_attr "length" "*,2")])
6973 (define_insn "*absdf2_v9"
6974 [(set (match_operand:DF 0 "register_operand" "=e")
6975 (abs:DF (match_operand:DF 1 "register_operand" "e")))]
6976 "TARGET_FPU && TARGET_V9"
6978 [(set_attr "type" "fpmove")
6979 (set_attr "fptype" "double")])
6981 (define_insn "abssf2"
6982 [(set (match_operand:SF 0 "register_operand" "=f")
6983 (abs:SF (match_operand:SF 1 "register_operand" "f")))]
6986 [(set_attr "type" "fpmove")])
6988 (define_expand "sqrttf2"
6989 [(set (match_operand:TF 0 "nonimmediate_operand" "")
6990 (sqrt:TF (match_operand:TF 1 "general_operand" "")))]
6991 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6992 "emit_tfmode_unop (SQRT, operands); DONE;")
6994 (define_insn "*sqrttf2_hq"
6995 [(set (match_operand:TF 0 "register_operand" "=e")
6996 (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
6997 "TARGET_FPU && TARGET_HARD_QUAD"
6999 [(set_attr "type" "fpsqrtd")])
7001 (define_insn "sqrtdf2"
7002 [(set (match_operand:DF 0 "register_operand" "=e")
7003 (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
7006 [(set_attr "type" "fpsqrtd")
7007 (set_attr "fptype" "double")])
7009 (define_insn "sqrtsf2"
7010 [(set (match_operand:SF 0 "register_operand" "=f")
7011 (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
7014 [(set_attr "type" "fpsqrts")])
7016 ;;- arithmetic shift instructions
7018 (define_insn "ashlsi3"
7019 [(set (match_operand:SI 0 "register_operand" "=r")
7020 (ashift:SI (match_operand:SI 1 "register_operand" "r")
7021 (match_operand:SI 2 "arith_operand" "rI")))]
7024 if (GET_CODE (operands[2]) == CONST_INT)
7025 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
7026 return "sll\t%1, %2, %0";
7029 (if_then_else (match_operand 2 "const1_operand" "")
7030 (const_string "ialu") (const_string "shift")))])
7032 (define_expand "ashldi3"
7033 [(set (match_operand:DI 0 "register_operand" "=r")
7034 (ashift:DI (match_operand:DI 1 "register_operand" "r")
7035 (match_operand:SI 2 "arith_operand" "rI")))]
7036 "TARGET_ARCH64 || TARGET_V8PLUS"
7038 if (! TARGET_ARCH64)
7040 if (GET_CODE (operands[2]) == CONST_INT)
7042 emit_insn (gen_ashldi3_v8plus (operands[0], operands[1], operands[2]));
7047 (define_insn "*ashldi3_sp64"
7048 [(set (match_operand:DI 0 "register_operand" "=r")
7049 (ashift:DI (match_operand:DI 1 "register_operand" "r")
7050 (match_operand:SI 2 "arith_operand" "rI")))]
7053 if (GET_CODE (operands[2]) == CONST_INT)
7054 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
7055 return "sllx\t%1, %2, %0";
7058 (if_then_else (match_operand 2 "const1_operand" "")
7059 (const_string "ialu") (const_string "shift")))])
7062 (define_insn "ashldi3_v8plus"
7063 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
7064 (ashift:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
7065 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
7066 (clobber (match_scratch:SI 3 "=X,X,&h"))]
7068 "* return output_v8plus_shift (operands, insn, \"sllx\");"
7069 [(set_attr "type" "multi")
7070 (set_attr "length" "5,5,6")])
7072 ;; Optimize (1LL<<x)-1
7073 ;; XXX this also needs to be fixed to handle equal subregs
7074 ;; XXX first before we could re-enable it.
7076 ; [(set (match_operand:DI 0 "register_operand" "=h")
7077 ; (plus:DI (ashift:DI (const_int 1)
7078 ; (match_operand:SI 1 "arith_operand" "rI"))
7080 ; "0 && TARGET_V8PLUS"
7082 ; if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == REGNO (operands[0]))
7083 ; return "mov\t1, %L0\;sllx\t%L0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
7084 ; return "mov\t1, %H0\;sllx\t%H0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
7086 ; [(set_attr "type" "multi")
7087 ; (set_attr "length" "4")])
7089 (define_insn "*cmp_cc_ashift_1"
7090 [(set (reg:CC_NOOV 100)
7091 (compare:CC_NOOV (ashift:SI (match_operand:SI 0 "register_operand" "r")
7095 "addcc\t%0, %0, %%g0"
7096 [(set_attr "type" "compare")])
7098 (define_insn "*cmp_cc_set_ashift_1"
7099 [(set (reg:CC_NOOV 100)
7100 (compare:CC_NOOV (ashift:SI (match_operand:SI 1 "register_operand" "r")
7103 (set (match_operand:SI 0 "register_operand" "=r")
7104 (ashift:SI (match_dup 1) (const_int 1)))]
7107 [(set_attr "type" "compare")])
7109 (define_insn "ashrsi3"
7110 [(set (match_operand:SI 0 "register_operand" "=r")
7111 (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
7112 (match_operand:SI 2 "arith_operand" "rI")))]
7115 if (GET_CODE (operands[2]) == CONST_INT)
7116 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
7117 return "sra\t%1, %2, %0";
7119 [(set_attr "type" "shift")])
7121 (define_insn "*ashrsi3_extend"
7122 [(set (match_operand:DI 0 "register_operand" "=r")
7123 (sign_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
7124 (match_operand:SI 2 "arith_operand" "r"))))]
7127 [(set_attr "type" "shift")])
7129 ;; This handles the case as above, but with constant shift instead of
7130 ;; register. Combiner "simplifies" it for us a little bit though.
7131 (define_insn "*ashrsi3_extend2"
7132 [(set (match_operand:DI 0 "register_operand" "=r")
7133 (ashiftrt:DI (ashift:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
7135 (match_operand:SI 2 "small_int_or_double" "n")))]
7137 && ((GET_CODE (operands[2]) == CONST_INT
7138 && INTVAL (operands[2]) >= 32 && INTVAL (operands[2]) < 64)
7139 || (GET_CODE (operands[2]) == CONST_DOUBLE
7140 && !CONST_DOUBLE_HIGH (operands[2])
7141 && CONST_DOUBLE_LOW (operands[2]) >= 32
7142 && CONST_DOUBLE_LOW (operands[2]) < 64))"
7144 operands[2] = GEN_INT (INTVAL (operands[2]) - 32);
7146 return "sra\t%1, %2, %0";
7148 [(set_attr "type" "shift")])
7150 (define_expand "ashrdi3"
7151 [(set (match_operand:DI 0 "register_operand" "=r")
7152 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
7153 (match_operand:SI 2 "arith_operand" "rI")))]
7154 "TARGET_ARCH64 || TARGET_V8PLUS"
7156 if (! TARGET_ARCH64)
7158 if (GET_CODE (operands[2]) == CONST_INT)
7159 FAIL; /* prefer generic code in this case */
7160 emit_insn (gen_ashrdi3_v8plus (operands[0], operands[1], operands[2]));
7165 (define_insn "*ashrdi3_sp64"
7166 [(set (match_operand:DI 0 "register_operand" "=r")
7167 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
7168 (match_operand:SI 2 "arith_operand" "rI")))]
7172 if (GET_CODE (operands[2]) == CONST_INT)
7173 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
7174 return "srax\t%1, %2, %0";
7176 [(set_attr "type" "shift")])
7179 (define_insn "ashrdi3_v8plus"
7180 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
7181 (ashiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
7182 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
7183 (clobber (match_scratch:SI 3 "=X,X,&h"))]
7185 "* return output_v8plus_shift (operands, insn, \"srax\");"
7186 [(set_attr "type" "multi")
7187 (set_attr "length" "5,5,6")])
7189 (define_insn "lshrsi3"
7190 [(set (match_operand:SI 0 "register_operand" "=r")
7191 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
7192 (match_operand:SI 2 "arith_operand" "rI")))]
7195 if (GET_CODE (operands[2]) == CONST_INT)
7196 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
7197 return "srl\t%1, %2, %0";
7199 [(set_attr "type" "shift")])
7201 ;; This handles the case where
7202 ;; (zero_extend:DI (lshiftrt:SI (match_operand:SI) (match_operand:SI))),
7203 ;; but combiner "simplifies" it for us.
7204 (define_insn "*lshrsi3_extend"
7205 [(set (match_operand:DI 0 "register_operand" "=r")
7206 (and:DI (subreg:DI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
7207 (match_operand:SI 2 "arith_operand" "r")) 0)
7208 (match_operand 3 "" "")))]
7210 && ((GET_CODE (operands[3]) == CONST_DOUBLE
7211 && CONST_DOUBLE_HIGH (operands[3]) == 0
7212 && CONST_DOUBLE_LOW (operands[3]) == 0xffffffff)
7213 || (HOST_BITS_PER_WIDE_INT >= 64
7214 && GET_CODE (operands[3]) == CONST_INT
7215 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) == 0xffffffff))"
7217 [(set_attr "type" "shift")])
7219 ;; This handles the case where
7220 ;; (lshiftrt:DI (zero_extend:DI (match_operand:SI)) (const_int >=0 < 32))
7221 ;; but combiner "simplifies" it for us.
7222 (define_insn "*lshrsi3_extend2"
7223 [(set (match_operand:DI 0 "register_operand" "=r")
7224 (zero_extract:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
7225 (match_operand 2 "small_int_or_double" "n")
7228 && ((GET_CODE (operands[2]) == CONST_INT
7229 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
7230 || (GET_CODE (operands[2]) == CONST_DOUBLE
7231 && CONST_DOUBLE_HIGH (operands[2]) == 0
7232 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
7234 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
7236 return "srl\t%1, %2, %0";
7238 [(set_attr "type" "shift")])
7240 (define_expand "lshrdi3"
7241 [(set (match_operand:DI 0 "register_operand" "=r")
7242 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
7243 (match_operand:SI 2 "arith_operand" "rI")))]
7244 "TARGET_ARCH64 || TARGET_V8PLUS"
7246 if (! TARGET_ARCH64)
7248 if (GET_CODE (operands[2]) == CONST_INT)
7250 emit_insn (gen_lshrdi3_v8plus (operands[0], operands[1], operands[2]));
7255 (define_insn "*lshrdi3_sp64"
7256 [(set (match_operand:DI 0 "register_operand" "=r")
7257 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
7258 (match_operand:SI 2 "arith_operand" "rI")))]
7261 if (GET_CODE (operands[2]) == CONST_INT)
7262 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
7263 return "srlx\t%1, %2, %0";
7265 [(set_attr "type" "shift")])
7268 (define_insn "lshrdi3_v8plus"
7269 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
7270 (lshiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
7271 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
7272 (clobber (match_scratch:SI 3 "=X,X,&h"))]
7274 "* return output_v8plus_shift (operands, insn, \"srlx\");"
7275 [(set_attr "type" "multi")
7276 (set_attr "length" "5,5,6")])
7279 [(set (match_operand:SI 0 "register_operand" "=r")
7280 (ashiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
7282 (match_operand:SI 2 "small_int_or_double" "n")))]
7284 && ((GET_CODE (operands[2]) == CONST_INT
7285 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
7286 || (GET_CODE (operands[2]) == CONST_DOUBLE
7287 && !CONST_DOUBLE_HIGH (operands[2])
7288 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
7290 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
7292 return "srax\t%1, %2, %0";
7294 [(set_attr "type" "shift")])
7297 [(set (match_operand:SI 0 "register_operand" "=r")
7298 (lshiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
7300 (match_operand:SI 2 "small_int_or_double" "n")))]
7302 && ((GET_CODE (operands[2]) == CONST_INT
7303 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
7304 || (GET_CODE (operands[2]) == CONST_DOUBLE
7305 && !CONST_DOUBLE_HIGH (operands[2])
7306 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
7308 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
7310 return "srlx\t%1, %2, %0";
7312 [(set_attr "type" "shift")])
7315 [(set (match_operand:SI 0 "register_operand" "=r")
7316 (ashiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
7317 (match_operand:SI 2 "small_int_or_double" "n")) 4)
7318 (match_operand:SI 3 "small_int_or_double" "n")))]
7320 && GET_CODE (operands[2]) == CONST_INT && GET_CODE (operands[3]) == CONST_INT
7321 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
7322 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
7323 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
7325 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
7327 return "srax\t%1, %2, %0";
7329 [(set_attr "type" "shift")])
7332 [(set (match_operand:SI 0 "register_operand" "=r")
7333 (lshiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
7334 (match_operand:SI 2 "small_int_or_double" "n")) 4)
7335 (match_operand:SI 3 "small_int_or_double" "n")))]
7337 && GET_CODE (operands[2]) == CONST_INT && GET_CODE (operands[3]) == CONST_INT
7338 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
7339 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
7340 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
7342 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
7344 return "srlx\t%1, %2, %0";
7346 [(set_attr "type" "shift")])
7348 ;; Unconditional and other jump instructions
7350 [(set (pc) (label_ref (match_operand 0 "" "")))]
7352 "* return output_ubranch (operands[0], 0, insn);"
7353 [(set_attr "type" "uncond_branch")])
7355 (define_expand "tablejump"
7356 [(parallel [(set (pc) (match_operand 0 "register_operand" "r"))
7357 (use (label_ref (match_operand 1 "" "")))])]
7360 gcc_assert (GET_MODE (operands[0]) == CASE_VECTOR_MODE);
7362 /* In pic mode, our address differences are against the base of the
7363 table. Add that base value back in; CSE ought to be able to combine
7364 the two address loads. */
7368 tmp = gen_rtx_LABEL_REF (Pmode, operands[1]);
7370 if (CASE_VECTOR_MODE != Pmode)
7371 tmp2 = gen_rtx_SIGN_EXTEND (Pmode, tmp2);
7372 tmp = gen_rtx_PLUS (Pmode, tmp2, tmp);
7373 operands[0] = memory_address (Pmode, tmp);
7377 (define_insn "*tablejump_sp32"
7378 [(set (pc) (match_operand:SI 0 "address_operand" "p"))
7379 (use (label_ref (match_operand 1 "" "")))]
7382 [(set_attr "type" "uncond_branch")])
7384 (define_insn "*tablejump_sp64"
7385 [(set (pc) (match_operand:DI 0 "address_operand" "p"))
7386 (use (label_ref (match_operand 1 "" "")))]
7389 [(set_attr "type" "uncond_branch")])
7391 ;;- jump to subroutine
7392 (define_expand "call"
7393 ;; Note that this expression is not used for generating RTL.
7394 ;; All the RTL is generated explicitly below.
7395 [(call (match_operand 0 "call_operand" "")
7396 (match_operand 3 "" "i"))]
7397 ;; operands[2] is next_arg_register
7398 ;; operands[3] is struct_value_size_rtx.
7403 gcc_assert (GET_MODE (operands[0]) == FUNCTION_MODE);
7405 gcc_assert (GET_CODE (operands[3]) == CONST_INT);
7407 if (GET_CODE (XEXP (operands[0], 0)) == LABEL_REF)
7409 /* This is really a PIC sequence. We want to represent
7410 it as a funny jump so its delay slots can be filled.
7412 ??? But if this really *is* a CALL, will not it clobber the
7413 call-clobbered registers? We lose this if it is a JUMP_INSN.
7414 Why cannot we have delay slots filled if it were a CALL? */
7416 /* We accept negative sizes for untyped calls. */
7417 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
7422 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
7424 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
7430 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
7431 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
7435 fn_rtx = operands[0];
7437 /* We accept negative sizes for untyped calls. */
7438 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
7442 gen_rtvec (3, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx),
7444 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
7449 gen_rtvec (2, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx),
7450 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
7457 ;; We can't use the same pattern for these two insns, because then registers
7458 ;; in the address may not be properly reloaded.
7460 (define_insn "*call_address_sp32"
7461 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
7462 (match_operand 1 "" ""))
7463 (clobber (reg:SI 15))]
7464 ;;- Do not use operand 1 for most machines.
7467 [(set_attr "type" "call")])
7469 (define_insn "*call_symbolic_sp32"
7470 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
7471 (match_operand 1 "" ""))
7472 (clobber (reg:SI 15))]
7473 ;;- Do not use operand 1 for most machines.
7476 [(set_attr "type" "call")])
7478 (define_insn "*call_address_sp64"
7479 [(call (mem:DI (match_operand:DI 0 "address_operand" "p"))
7480 (match_operand 1 "" ""))
7481 (clobber (reg:DI 15))]
7482 ;;- Do not use operand 1 for most machines.
7485 [(set_attr "type" "call")])
7487 (define_insn "*call_symbolic_sp64"
7488 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
7489 (match_operand 1 "" ""))
7490 (clobber (reg:DI 15))]
7491 ;;- Do not use operand 1 for most machines.
7494 [(set_attr "type" "call")])
7496 ;; This is a call that wants a structure value.
7497 ;; There is no such critter for v9 (??? we may need one anyway).
7498 (define_insn "*call_address_struct_value_sp32"
7499 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
7500 (match_operand 1 "" ""))
7501 (match_operand 2 "immediate_operand" "")
7502 (clobber (reg:SI 15))]
7503 ;;- Do not use operand 1 for most machines.
7504 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
7506 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xfff);
7507 return "call\t%a0, %1\n\t nop\n\tunimp\t%2";
7509 [(set_attr "type" "call_no_delay_slot")
7510 (set_attr "length" "3")])
7512 ;; This is a call that wants a structure value.
7513 ;; There is no such critter for v9 (??? we may need one anyway).
7514 (define_insn "*call_symbolic_struct_value_sp32"
7515 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
7516 (match_operand 1 "" ""))
7517 (match_operand 2 "immediate_operand" "")
7518 (clobber (reg:SI 15))]
7519 ;;- Do not use operand 1 for most machines.
7520 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
7522 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xfff);
7523 return "call\t%a0, %1\n\t nop\n\tunimp\t%2";
7525 [(set_attr "type" "call_no_delay_slot")
7526 (set_attr "length" "3")])
7528 ;; This is a call that may want a structure value. This is used for
7530 (define_insn "*call_address_untyped_struct_value_sp32"
7531 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
7532 (match_operand 1 "" ""))
7533 (match_operand 2 "immediate_operand" "")
7534 (clobber (reg:SI 15))]
7535 ;;- Do not use operand 1 for most machines.
7536 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
7537 "call\t%a0, %1\n\t nop\n\tnop"
7538 [(set_attr "type" "call_no_delay_slot")
7539 (set_attr "length" "3")])
7541 ;; This is a call that may want a structure value. This is used for
7543 (define_insn "*call_symbolic_untyped_struct_value_sp32"
7544 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
7545 (match_operand 1 "" ""))
7546 (match_operand 2 "immediate_operand" "")
7547 (clobber (reg:SI 15))]
7548 ;;- Do not use operand 1 for most machines.
7549 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
7550 "call\t%a0, %1\n\t nop\n\tnop"
7551 [(set_attr "type" "call_no_delay_slot")
7552 (set_attr "length" "3")])
7554 (define_expand "call_value"
7555 ;; Note that this expression is not used for generating RTL.
7556 ;; All the RTL is generated explicitly below.
7557 [(set (match_operand 0 "register_operand" "=rf")
7558 (call (match_operand 1 "" "")
7559 (match_operand 4 "" "")))]
7560 ;; operand 2 is stack_size_rtx
7561 ;; operand 3 is next_arg_register
7567 gcc_assert (GET_MODE (operands[1]) == FUNCTION_MODE);
7569 fn_rtx = operands[1];
7572 gen_rtx_SET (VOIDmode, operands[0],
7573 gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx)),
7574 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)));
7576 emit_call_insn (gen_rtx_PARALLEL (VOIDmode, vec));
7581 (define_insn "*call_value_address_sp32"
7582 [(set (match_operand 0 "" "=rf")
7583 (call (mem:SI (match_operand:SI 1 "address_operand" "p"))
7584 (match_operand 2 "" "")))
7585 (clobber (reg:SI 15))]
7586 ;;- Do not use operand 2 for most machines.
7589 [(set_attr "type" "call")])
7591 (define_insn "*call_value_symbolic_sp32"
7592 [(set (match_operand 0 "" "=rf")
7593 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
7594 (match_operand 2 "" "")))
7595 (clobber (reg:SI 15))]
7596 ;;- Do not use operand 2 for most machines.
7599 [(set_attr "type" "call")])
7601 (define_insn "*call_value_address_sp64"
7602 [(set (match_operand 0 "" "")
7603 (call (mem:DI (match_operand:DI 1 "address_operand" "p"))
7604 (match_operand 2 "" "")))
7605 (clobber (reg:DI 15))]
7606 ;;- Do not use operand 2 for most machines.
7609 [(set_attr "type" "call")])
7611 (define_insn "*call_value_symbolic_sp64"
7612 [(set (match_operand 0 "" "")
7613 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
7614 (match_operand 2 "" "")))
7615 (clobber (reg:DI 15))]
7616 ;;- Do not use operand 2 for most machines.
7619 [(set_attr "type" "call")])
7621 (define_expand "untyped_call"
7622 [(parallel [(call (match_operand 0 "" "")
7624 (match_operand 1 "" "")
7625 (match_operand 2 "" "")])]
7630 /* Pass constm1 to indicate that it may expect a structure value, but
7631 we don't know what size it is. */
7632 emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, constm1_rtx));
7634 for (i = 0; i < XVECLEN (operands[2], 0); i++)
7636 rtx set = XVECEXP (operands[2], 0, i);
7637 emit_move_insn (SET_DEST (set), SET_SRC (set));
7640 /* The optimizer does not know that the call sets the function value
7641 registers we stored in the result block. We avoid problems by
7642 claiming that all hard registers are used and clobbered at this
7644 emit_insn (gen_blockage ());
7650 (define_expand "sibcall"
7651 [(parallel [(call (match_operand 0 "call_operand" "") (const_int 0))
7656 (define_insn "*sibcall_symbolic_sp32"
7657 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
7658 (match_operand 1 "" ""))
7661 "* return output_sibcall(insn, operands[0]);"
7662 [(set_attr "type" "sibcall")])
7664 (define_insn "*sibcall_symbolic_sp64"
7665 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
7666 (match_operand 1 "" ""))
7669 "* return output_sibcall(insn, operands[0]);"
7670 [(set_attr "type" "sibcall")])
7672 (define_expand "sibcall_value"
7673 [(parallel [(set (match_operand 0 "register_operand" "=rf")
7674 (call (match_operand 1 "" "") (const_int 0)))
7679 (define_insn "*sibcall_value_symbolic_sp32"
7680 [(set (match_operand 0 "" "=rf")
7681 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
7682 (match_operand 2 "" "")))
7685 "* return output_sibcall(insn, operands[1]);"
7686 [(set_attr "type" "sibcall")])
7688 (define_insn "*sibcall_value_symbolic_sp64"
7689 [(set (match_operand 0 "" "")
7690 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
7691 (match_operand 2 "" "")))
7694 "* return output_sibcall(insn, operands[1]);"
7695 [(set_attr "type" "sibcall")])
7697 (define_expand "sibcall_epilogue"
7701 sparc_expand_epilogue ();
7705 (define_expand "prologue"
7709 sparc_expand_prologue ();
7713 ;; The "save register window" insn is modelled as follows so that the DWARF-2
7714 ;; backend automatically emits the required call frame debugging information
7715 ;; while it is parsing it. Therefore, the pattern should not be modified
7716 ;; without first studying the impact of the changes on the debug info.
7717 ;; [(set (%fp) (%sp))
7718 ;; (set (%sp) (unspec_volatile [(%sp) (-frame_size)] UNSPECV_SAVEW))
7719 ;; (set (%i7) (%o7))]
7721 (define_insn "save_register_window<P:mode>"
7722 [(set (reg:P 30) (reg:P 14))
7723 (set (reg:P 14) (unspec_volatile:P [(reg:P 14)
7724 (match_operand:P 0 "arith_operand" "rI")] UNSPECV_SAVEW))
7725 (set (reg:P 31) (reg:P 15))]
7727 "save\t%%sp, %0, %%sp"
7728 [(set_attr "type" "savew")])
7730 (define_expand "epilogue"
7734 sparc_expand_epilogue ();
7737 (define_expand "return"
7739 "sparc_can_use_return_insn_p ()"
7742 (define_insn "*return_internal"
7745 "* return output_return (insn);"
7746 [(set_attr "type" "return")
7747 (set (attr "length")
7748 (cond [(eq_attr "leaf_function" "true")
7749 (if_then_else (eq_attr "empty_delay_slot" "true")
7752 (eq_attr "calls_eh_return" "true")
7753 (if_then_else (eq_attr "delayed_branch" "true")
7754 (if_then_else (eq_attr "isa" "v9")
7757 (if_then_else (eq_attr "isa" "v9")
7760 (eq_attr "empty_delay_slot" "true")
7761 (if_then_else (eq_attr "delayed_branch" "true")
7766 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
7767 ;; all of memory. This blocks insns from being moved across this point.
7769 (define_insn "blockage"
7770 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
7773 [(set_attr "length" "0")])
7775 ;; Prepare to return any type including a structure value.
7777 (define_expand "untyped_return"
7778 [(match_operand:BLK 0 "memory_operand" "")
7779 (match_operand 1 "" "")]
7782 rtx valreg1 = gen_rtx_REG (DImode, 24);
7783 rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
7784 rtx result = operands[0];
7786 if (! TARGET_ARCH64)
7788 rtx rtnreg = gen_rtx_REG (SImode, (current_function_uses_only_leaf_regs
7790 rtx value = gen_reg_rtx (SImode);
7792 /* Fetch the instruction where we will return to and see if it's an unimp
7793 instruction (the most significant 10 bits will be zero). If so,
7794 update the return address to skip the unimp instruction. */
7795 emit_move_insn (value,
7796 gen_rtx_MEM (SImode, plus_constant (rtnreg, 8)));
7797 emit_insn (gen_lshrsi3 (value, value, GEN_INT (22)));
7798 emit_insn (gen_update_return (rtnreg, value));
7801 /* Reload the function value registers. */
7802 emit_move_insn (valreg1, adjust_address (result, DImode, 0));
7803 emit_move_insn (valreg2,
7804 adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8));
7806 /* Put USE insns before the return. */
7807 emit_insn (gen_rtx_USE (VOIDmode, valreg1));
7808 emit_insn (gen_rtx_USE (VOIDmode, valreg2));
7810 /* Construct the return. */
7811 expand_naked_return ();
7816 ;; This is a bit of a hack. We're incrementing a fixed register (%i7),
7817 ;; and parts of the compiler don't want to believe that the add is needed.
7819 (define_insn "update_return"
7820 [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
7821 (match_operand:SI 1 "register_operand" "r")] UNSPEC_UPDATE_RETURN)]
7824 if (flag_delayed_branch)
7825 return "cmp\t%1, 0\n\tbe,a\t.+8\n\t add\t%0, 4, %0";
7827 return "cmp\t%1, 0\n\tbne\t.+12\n\t nop\n\tadd\t%0, 4, %0";
7829 [(set (attr "type") (const_string "multi"))
7830 (set (attr "length")
7831 (if_then_else (eq_attr "delayed_branch" "true")
7840 (define_expand "indirect_jump"
7841 [(set (pc) (match_operand 0 "address_operand" "p"))]
7845 (define_insn "*branch_sp32"
7846 [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
7849 [(set_attr "type" "uncond_branch")])
7851 (define_insn "*branch_sp64"
7852 [(set (pc) (match_operand:DI 0 "address_operand" "p"))]
7855 [(set_attr "type" "uncond_branch")])
7857 (define_expand "nonlocal_goto"
7858 [(match_operand:SI 0 "general_operand" "")
7859 (match_operand:SI 1 "general_operand" "")
7860 (match_operand:SI 2 "general_operand" "")
7861 (match_operand:SI 3 "" "")]
7864 rtx lab = operands[1];
7865 rtx stack = operands[2];
7866 rtx fp = operands[3];
7869 /* Trap instruction to flush all the register windows. */
7870 emit_insn (gen_flush_register_windows ());
7872 /* Load the fp value for the containing fn into %fp. This is needed
7873 because STACK refers to %fp. Note that virtual register instantiation
7874 fails if the virtual %fp isn't set from a register. */
7875 if (GET_CODE (fp) != REG)
7876 fp = force_reg (Pmode, fp);
7877 emit_move_insn (virtual_stack_vars_rtx, fp);
7879 /* Find the containing function's current nonlocal goto handler,
7880 which will do any cleanups and then jump to the label. */
7881 labreg = gen_rtx_REG (Pmode, 8);
7882 emit_move_insn (labreg, lab);
7884 /* Restore %fp from stack pointer value for containing function.
7885 The restore insn that follows will move this to %sp,
7886 and reload the appropriate value into %fp. */
7887 emit_move_insn (hard_frame_pointer_rtx, stack);
7889 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
7890 emit_insn (gen_rtx_USE (VOIDmode, static_chain_rtx));
7892 /* ??? The V9-specific version was disabled in rev 1.65. */
7893 emit_jump_insn (gen_goto_handler_and_restore (labreg));
7898 ;; Special trap insn to flush register windows.
7899 (define_insn "flush_register_windows"
7900 [(unspec_volatile [(const_int 0)] UNSPECV_FLUSHW)]
7902 { return TARGET_V9 ? "flushw" : "ta\t3"; }
7903 [(set_attr "type" "flushw")])
7905 (define_insn "goto_handler_and_restore"
7906 [(unspec_volatile [(match_operand 0 "register_operand" "=r")] UNSPECV_GOTO)]
7907 "GET_MODE (operands[0]) == Pmode"
7909 if (flag_delayed_branch)
7910 return "jmp\t%0\n\t restore";
7912 return "mov\t%0,%%g1\n\trestore\n\tjmp\t%%g1\n\t nop";
7914 [(set (attr "type") (const_string "multi"))
7915 (set (attr "length")
7916 (if_then_else (eq_attr "delayed_branch" "true")
7920 ;; For __builtin_setjmp we need to flush register windows iff the function
7921 ;; calls alloca as well, because otherwise the register window might be
7922 ;; saved after %sp adjustment and thus setjmp would crash
7923 (define_expand "builtin_setjmp_setup"
7924 [(match_operand 0 "register_operand" "r")]
7927 emit_insn (gen_do_builtin_setjmp_setup ());
7931 (define_insn "do_builtin_setjmp_setup"
7932 [(unspec_volatile [(const_int 0)] UNSPECV_SETJMP)]
7935 if (! current_function_calls_alloca)
7939 fputs ("\tflushw\n", asm_out_file);
7941 fprintf (asm_out_file, "\tst%c\t%%l7, [%%sp+%d]\n",
7942 TARGET_ARCH64 ? 'x' : 'w',
7943 SPARC_STACK_BIAS + 7 * UNITS_PER_WORD);
7944 fprintf (asm_out_file, "\tst%c\t%%fp, [%%sp+%d]\n",
7945 TARGET_ARCH64 ? 'x' : 'w',
7946 SPARC_STACK_BIAS + 14 * UNITS_PER_WORD);
7947 fprintf (asm_out_file, "\tst%c\t%%i7, [%%sp+%d]\n",
7948 TARGET_ARCH64 ? 'x' : 'w',
7949 SPARC_STACK_BIAS + 15 * UNITS_PER_WORD);
7952 [(set_attr "type" "multi")
7953 (set (attr "length")
7954 (cond [(eq_attr "calls_alloca" "false")
7956 (eq_attr "isa" "!v9")
7958 (eq_attr "pic" "true")
7959 (const_int 4)] (const_int 3)))])
7961 ;; Pattern for use after a setjmp to store FP and the return register
7962 ;; into the stack area.
7964 (define_expand "setjmp"
7969 emit_insn (gen_setjmp_64 ());
7971 emit_insn (gen_setjmp_32 ());
7975 (define_expand "setjmp_32"
7976 [(set (mem:SI (plus:SI (reg:SI 14) (const_int 56))) (match_dup 0))
7977 (set (mem:SI (plus:SI (reg:SI 14) (const_int 60))) (reg:SI 31))]
7979 { operands[0] = frame_pointer_rtx; })
7981 (define_expand "setjmp_64"
7982 [(set (mem:DI (plus:DI (reg:DI 14) (const_int 112))) (match_dup 0))
7983 (set (mem:DI (plus:DI (reg:DI 14) (const_int 120))) (reg:DI 31))]
7985 { operands[0] = frame_pointer_rtx; })
7987 ;; Special pattern for the FLUSH instruction.
7989 ; We do SImode and DImode versions of this to quiet down genrecog's complaints
7990 ; of the define_insn otherwise missing a mode. We make "flush", aka
7991 ; gen_flush, the default one since sparc_initialize_trampoline uses
7992 ; it on SImode mem values.
7994 (define_insn "flush"
7995 [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")] UNSPECV_FLUSH)]
7997 { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; }
7998 [(set_attr "type" "iflush")])
8000 (define_insn "flushdi"
8001 [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")] UNSPECV_FLUSH)]
8003 { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; }
8004 [(set_attr "type" "iflush")])
8009 ;; The scan instruction searches from the most significant bit while ffs
8010 ;; searches from the least significant bit. The bit index and treatment of
8011 ;; zero also differ. It takes at least 7 instructions to get the proper
8012 ;; result. Here is an obvious 8 instruction sequence.
8015 (define_insn "ffssi2"
8016 [(set (match_operand:SI 0 "register_operand" "=&r")
8017 (ffs:SI (match_operand:SI 1 "register_operand" "r")))
8018 (clobber (match_scratch:SI 2 "=&r"))]
8019 "TARGET_SPARCLITE || TARGET_SPARCLET"
8021 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";
8023 [(set_attr "type" "multi")
8024 (set_attr "length" "8")])
8026 ;; ??? This should be a define expand, so that the extra instruction have
8027 ;; a chance of being optimized away.
8029 ;; Disabled because none of the UltraSPARCs implement popc. The HAL R1
8030 ;; does, but no one uses that and we don't have a switch for it.
8032 ;(define_insn "ffsdi2"
8033 ; [(set (match_operand:DI 0 "register_operand" "=&r")
8034 ; (ffs:DI (match_operand:DI 1 "register_operand" "r")))
8035 ; (clobber (match_scratch:DI 2 "=&r"))]
8037 ; "neg\t%1, %2\;xnor\t%1, %2, %2\;popc\t%2, %0\;movzr\t%1, 0, %0"
8038 ; [(set_attr "type" "multi")
8039 ; (set_attr "length" "4")])
8043 ;; Peepholes go at the end.
8045 ;; Optimize consecutive loads or stores into ldd and std when possible.
8046 ;; The conditions in which we do this are very restricted and are
8047 ;; explained in the code for {registers,memory}_ok_for_ldd functions.
8050 [(set (match_operand:SI 0 "memory_operand" "")
8052 (set (match_operand:SI 1 "memory_operand" "")
8055 && mems_ok_for_ldd_peep (operands[0], operands[1], NULL_RTX)"
8058 "operands[0] = widen_memory_access (operands[0], DImode, 0);")
8061 [(set (match_operand:SI 0 "memory_operand" "")
8063 (set (match_operand:SI 1 "memory_operand" "")
8066 && mems_ok_for_ldd_peep (operands[1], operands[0], NULL_RTX)"
8069 "operands[1] = widen_memory_access (operands[1], DImode, 0);")
8072 [(set (match_operand:SI 0 "register_operand" "")
8073 (match_operand:SI 1 "memory_operand" ""))
8074 (set (match_operand:SI 2 "register_operand" "")
8075 (match_operand:SI 3 "memory_operand" ""))]
8076 "registers_ok_for_ldd_peep (operands[0], operands[2])
8077 && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
8080 "operands[1] = widen_memory_access (operands[1], DImode, 0);
8081 operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));")
8084 [(set (match_operand:SI 0 "memory_operand" "")
8085 (match_operand:SI 1 "register_operand" ""))
8086 (set (match_operand:SI 2 "memory_operand" "")
8087 (match_operand:SI 3 "register_operand" ""))]
8088 "registers_ok_for_ldd_peep (operands[1], operands[3])
8089 && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
8092 "operands[0] = widen_memory_access (operands[0], DImode, 0);
8093 operands[1] = gen_rtx_REG (DImode, REGNO (operands[1]));")
8096 [(set (match_operand:SF 0 "register_operand" "")
8097 (match_operand:SF 1 "memory_operand" ""))
8098 (set (match_operand:SF 2 "register_operand" "")
8099 (match_operand:SF 3 "memory_operand" ""))]
8100 "registers_ok_for_ldd_peep (operands[0], operands[2])
8101 && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
8104 "operands[1] = widen_memory_access (operands[1], DFmode, 0);
8105 operands[0] = gen_rtx_REG (DFmode, REGNO (operands[0]));")
8108 [(set (match_operand:SF 0 "memory_operand" "")
8109 (match_operand:SF 1 "register_operand" ""))
8110 (set (match_operand:SF 2 "memory_operand" "")
8111 (match_operand:SF 3 "register_operand" ""))]
8112 "registers_ok_for_ldd_peep (operands[1], operands[3])
8113 && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
8116 "operands[0] = widen_memory_access (operands[0], DFmode, 0);
8117 operands[1] = gen_rtx_REG (DFmode, REGNO (operands[1]));")
8120 [(set (match_operand:SI 0 "register_operand" "")
8121 (match_operand:SI 1 "memory_operand" ""))
8122 (set (match_operand:SI 2 "register_operand" "")
8123 (match_operand:SI 3 "memory_operand" ""))]
8124 "registers_ok_for_ldd_peep (operands[2], operands[0])
8125 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
8128 "operands[3] = widen_memory_access (operands[3], DImode, 0);
8129 operands[2] = gen_rtx_REG (DImode, REGNO (operands[2]));")
8132 [(set (match_operand:SI 0 "memory_operand" "")
8133 (match_operand:SI 1 "register_operand" ""))
8134 (set (match_operand:SI 2 "memory_operand" "")
8135 (match_operand:SI 3 "register_operand" ""))]
8136 "registers_ok_for_ldd_peep (operands[3], operands[1])
8137 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
8140 "operands[2] = widen_memory_access (operands[2], DImode, 0);
8141 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
8145 [(set (match_operand:SF 0 "register_operand" "")
8146 (match_operand:SF 1 "memory_operand" ""))
8147 (set (match_operand:SF 2 "register_operand" "")
8148 (match_operand:SF 3 "memory_operand" ""))]
8149 "registers_ok_for_ldd_peep (operands[2], operands[0])
8150 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
8153 "operands[3] = widen_memory_access (operands[3], DFmode, 0);
8154 operands[2] = gen_rtx_REG (DFmode, REGNO (operands[2]));")
8157 [(set (match_operand:SF 0 "memory_operand" "")
8158 (match_operand:SF 1 "register_operand" ""))
8159 (set (match_operand:SF 2 "memory_operand" "")
8160 (match_operand:SF 3 "register_operand" ""))]
8161 "registers_ok_for_ldd_peep (operands[3], operands[1])
8162 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
8165 "operands[2] = widen_memory_access (operands[2], DFmode, 0);
8166 operands[3] = gen_rtx_REG (DFmode, REGNO (operands[3]));")
8168 ;; Optimize the case of following a reg-reg move with a test
8169 ;; of reg just moved. Don't allow floating point regs for operand 0 or 1.
8170 ;; This can result from a float to fix conversion.
8173 [(set (match_operand:SI 0 "register_operand" "")
8174 (match_operand:SI 1 "register_operand" ""))
8176 (compare:CC (match_operand:SI 2 "register_operand" "")
8178 "(rtx_equal_p (operands[2], operands[0])
8179 || rtx_equal_p (operands[2], operands[1]))
8180 && ! SPARC_FP_REG_P (REGNO (operands[0]))
8181 && ! SPARC_FP_REG_P (REGNO (operands[1]))"
8182 [(parallel [(set (match_dup 0) (match_dup 1))
8184 (compare:CC (match_dup 1) (const_int 0)))])]
8188 [(set (match_operand:DI 0 "register_operand" "")
8189 (match_operand:DI 1 "register_operand" ""))
8191 (compare:CCX (match_operand:DI 2 "register_operand" "")
8194 && (rtx_equal_p (operands[2], operands[0])
8195 || rtx_equal_p (operands[2], operands[1]))
8196 && ! SPARC_FP_REG_P (REGNO (operands[0]))
8197 && ! SPARC_FP_REG_P (REGNO (operands[1]))"
8198 [(parallel [(set (match_dup 0) (match_dup 1))
8200 (compare:CCX (match_dup 1) (const_int 0)))])]
8203 ;; ??? UltraSPARC-III note: A memory operation loading into the floating point register
8204 ;; ??? file, if it hits the prefetch cache, has a chance to dual-issue with other memory
8205 ;; ??? operations. With DFA we might be able to model this, but it requires a lot of
8207 (define_expand "prefetch"
8208 [(match_operand 0 "address_operand" "")
8209 (match_operand 1 "const_int_operand" "")
8210 (match_operand 2 "const_int_operand" "")]
8214 emit_insn (gen_prefetch_64 (operands[0], operands[1], operands[2]));
8216 emit_insn (gen_prefetch_32 (operands[0], operands[1], operands[2]));
8220 (define_insn "prefetch_64"
8221 [(prefetch (match_operand:DI 0 "address_operand" "p")
8222 (match_operand:DI 1 "const_int_operand" "n")
8223 (match_operand:DI 2 "const_int_operand" "n"))]
8226 static const char * const prefetch_instr[2][2] = {
8228 "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
8229 "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
8232 "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
8233 "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
8236 int read_or_write = INTVAL (operands[1]);
8237 int locality = INTVAL (operands[2]);
8239 gcc_assert (read_or_write == 0 || read_or_write == 1);
8240 gcc_assert (locality >= 0 && locality < 4);
8241 return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
8243 [(set_attr "type" "load")])
8245 (define_insn "prefetch_32"
8246 [(prefetch (match_operand:SI 0 "address_operand" "p")
8247 (match_operand:SI 1 "const_int_operand" "n")
8248 (match_operand:SI 2 "const_int_operand" "n"))]
8251 static const char * const prefetch_instr[2][2] = {
8253 "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
8254 "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
8257 "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
8258 "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
8261 int read_or_write = INTVAL (operands[1]);
8262 int locality = INTVAL (operands[2]);
8264 gcc_assert (read_or_write == 0 || read_or_write == 1);
8265 gcc_assert (locality >= 0 && locality < 4);
8266 return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
8268 [(set_attr "type" "load")])
8271 [(trap_if (const_int 1) (const_int 5))]
8274 [(set_attr "type" "trap")])
8276 (define_expand "conditional_trap"
8277 [(trap_if (match_operator 0 "noov_compare_op" [(match_dup 2) (match_dup 3)])
8278 (match_operand:SI 1 "arith_operand" ""))]
8280 "operands[2] = gen_compare_reg (GET_CODE (operands[0]),
8281 sparc_compare_op0, sparc_compare_op1);
8282 if (GET_MODE (operands[2]) != CCmode && GET_MODE (operands[2]) != CCXmode)
8284 operands[3] = const0_rtx;")
8287 [(trap_if (match_operator 0 "noov_compare_op" [(reg:CC 100) (const_int 0)])
8288 (match_operand:SI 1 "arith_operand" "rM"))]
8292 return "t%C0\t%%icc, %1";
8296 [(set_attr "type" "trap")])
8299 [(trap_if (match_operator 0 "noov_compare_op" [(reg:CCX 100) (const_int 0)])
8300 (match_operand:SI 1 "arith_operand" "rM"))]
8303 [(set_attr "type" "trap")])
8306 (define_insn "tgd_hi22"
8307 [(set (match_operand:SI 0 "register_operand" "=r")
8308 (high:SI (unspec:SI [(match_operand 1 "tgd_symbolic_operand" "")]
8311 "sethi\\t%%tgd_hi22(%a1), %0")
8313 (define_insn "tgd_lo10"
8314 [(set (match_operand:SI 0 "register_operand" "=r")
8315 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
8316 (unspec:SI [(match_operand 2 "tgd_symbolic_operand" "")]
8319 "add\\t%1, %%tgd_lo10(%a2), %0")
8321 (define_insn "tgd_add32"
8322 [(set (match_operand:SI 0 "register_operand" "=r")
8323 (plus:SI (match_operand:SI 1 "register_operand" "r")
8324 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8325 (match_operand 3 "tgd_symbolic_operand" "")]
8327 "TARGET_TLS && TARGET_ARCH32"
8328 "add\\t%1, %2, %0, %%tgd_add(%a3)")
8330 (define_insn "tgd_add64"
8331 [(set (match_operand:DI 0 "register_operand" "=r")
8332 (plus:DI (match_operand:DI 1 "register_operand" "r")
8333 (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8334 (match_operand 3 "tgd_symbolic_operand" "")]
8336 "TARGET_TLS && TARGET_ARCH64"
8337 "add\\t%1, %2, %0, %%tgd_add(%a3)")
8339 (define_insn "tgd_call32"
8340 [(set (match_operand 0 "register_operand" "=r")
8341 (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")
8342 (match_operand 2 "tgd_symbolic_operand" "")]
8344 (match_operand 3 "" "")))
8345 (clobber (reg:SI 15))]
8346 "TARGET_TLS && TARGET_ARCH32"
8347 "call\t%a1, %%tgd_call(%a2)%#"
8348 [(set_attr "type" "call")])
8350 (define_insn "tgd_call64"
8351 [(set (match_operand 0 "register_operand" "=r")
8352 (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")
8353 (match_operand 2 "tgd_symbolic_operand" "")]
8355 (match_operand 3 "" "")))
8356 (clobber (reg:DI 15))]
8357 "TARGET_TLS && TARGET_ARCH64"
8358 "call\t%a1, %%tgd_call(%a2)%#"
8359 [(set_attr "type" "call")])
8361 (define_insn "tldm_hi22"
8362 [(set (match_operand:SI 0 "register_operand" "=r")
8363 (high:SI (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
8365 "sethi\\t%%tldm_hi22(%&), %0")
8367 (define_insn "tldm_lo10"
8368 [(set (match_operand:SI 0 "register_operand" "=r")
8369 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
8370 (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
8372 "add\\t%1, %%tldm_lo10(%&), %0")
8374 (define_insn "tldm_add32"
8375 [(set (match_operand:SI 0 "register_operand" "=r")
8376 (plus:SI (match_operand:SI 1 "register_operand" "r")
8377 (unspec:SI [(match_operand:SI 2 "register_operand" "r")]
8379 "TARGET_TLS && TARGET_ARCH32"
8380 "add\\t%1, %2, %0, %%tldm_add(%&)")
8382 (define_insn "tldm_add64"
8383 [(set (match_operand:DI 0 "register_operand" "=r")
8384 (plus:DI (match_operand:DI 1 "register_operand" "r")
8385 (unspec:DI [(match_operand:SI 2 "register_operand" "r")]
8387 "TARGET_TLS && TARGET_ARCH64"
8388 "add\\t%1, %2, %0, %%tldm_add(%&)")
8390 (define_insn "tldm_call32"
8391 [(set (match_operand 0 "register_operand" "=r")
8392 (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")]
8394 (match_operand 2 "" "")))
8395 (clobber (reg:SI 15))]
8396 "TARGET_TLS && TARGET_ARCH32"
8397 "call\t%a1, %%tldm_call(%&)%#"
8398 [(set_attr "type" "call")])
8400 (define_insn "tldm_call64"
8401 [(set (match_operand 0 "register_operand" "=r")
8402 (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")]
8404 (match_operand 2 "" "")))
8405 (clobber (reg:DI 15))]
8406 "TARGET_TLS && TARGET_ARCH64"
8407 "call\t%a1, %%tldm_call(%&)%#"
8408 [(set_attr "type" "call")])
8410 (define_insn "tldo_hix22"
8411 [(set (match_operand:SI 0 "register_operand" "=r")
8412 (high:SI (unspec:SI [(match_operand 1 "tld_symbolic_operand" "")]
8415 "sethi\\t%%tldo_hix22(%a1), %0")
8417 (define_insn "tldo_lox10"
8418 [(set (match_operand:SI 0 "register_operand" "=r")
8419 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
8420 (unspec:SI [(match_operand 2 "tld_symbolic_operand" "")]
8423 "xor\\t%1, %%tldo_lox10(%a2), %0")
8425 (define_insn "tldo_add32"
8426 [(set (match_operand:SI 0 "register_operand" "=r")
8427 (plus:SI (match_operand:SI 1 "register_operand" "r")
8428 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8429 (match_operand 3 "tld_symbolic_operand" "")]
8431 "TARGET_TLS && TARGET_ARCH32"
8432 "add\\t%1, %2, %0, %%tldo_add(%a3)")
8434 (define_insn "tldo_add64"
8435 [(set (match_operand:DI 0 "register_operand" "=r")
8436 (plus:DI (match_operand:DI 1 "register_operand" "r")
8437 (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8438 (match_operand 3 "tld_symbolic_operand" "")]
8440 "TARGET_TLS && TARGET_ARCH64"
8441 "add\\t%1, %2, %0, %%tldo_add(%a3)")
8443 (define_insn "tie_hi22"
8444 [(set (match_operand:SI 0 "register_operand" "=r")
8445 (high:SI (unspec:SI [(match_operand 1 "tie_symbolic_operand" "")]
8448 "sethi\\t%%tie_hi22(%a1), %0")
8450 (define_insn "tie_lo10"
8451 [(set (match_operand:SI 0 "register_operand" "=r")
8452 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
8453 (unspec:SI [(match_operand 2 "tie_symbolic_operand" "")]
8456 "add\\t%1, %%tie_lo10(%a2), %0")
8458 (define_insn "tie_ld32"
8459 [(set (match_operand:SI 0 "register_operand" "=r")
8460 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
8461 (match_operand:SI 2 "register_operand" "r")
8462 (match_operand 3 "tie_symbolic_operand" "")]
8464 "TARGET_TLS && TARGET_ARCH32"
8465 "ld\\t[%1 + %2], %0, %%tie_ld(%a3)"
8466 [(set_attr "type" "load")])
8468 (define_insn "tie_ld64"
8469 [(set (match_operand:DI 0 "register_operand" "=r")
8470 (unspec:DI [(match_operand:DI 1 "register_operand" "r")
8471 (match_operand:SI 2 "register_operand" "r")
8472 (match_operand 3 "tie_symbolic_operand" "")]
8474 "TARGET_TLS && TARGET_ARCH64"
8475 "ldx\\t[%1 + %2], %0, %%tie_ldx(%a3)"
8476 [(set_attr "type" "load")])
8478 (define_insn "tie_add32"
8479 [(set (match_operand:SI 0 "register_operand" "=r")
8480 (plus:SI (match_operand:SI 1 "register_operand" "r")
8481 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8482 (match_operand 3 "tie_symbolic_operand" "")]
8484 "TARGET_SUN_TLS && TARGET_ARCH32"
8485 "add\\t%1, %2, %0, %%tie_add(%a3)")
8487 (define_insn "tie_add64"
8488 [(set (match_operand:DI 0 "register_operand" "=r")
8489 (plus:DI (match_operand:DI 1 "register_operand" "r")
8490 (unspec:DI [(match_operand:DI 2 "register_operand" "r")
8491 (match_operand 3 "tie_symbolic_operand" "")]
8493 "TARGET_SUN_TLS && TARGET_ARCH64"
8494 "add\\t%1, %2, %0, %%tie_add(%a3)")
8496 (define_insn "tle_hix22_sp32"
8497 [(set (match_operand:SI 0 "register_operand" "=r")
8498 (high:SI (unspec:SI [(match_operand 1 "tle_symbolic_operand" "")]
8500 "TARGET_TLS && TARGET_ARCH32"
8501 "sethi\\t%%tle_hix22(%a1), %0")
8503 (define_insn "tle_lox10_sp32"
8504 [(set (match_operand:SI 0 "register_operand" "=r")
8505 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
8506 (unspec:SI [(match_operand 2 "tle_symbolic_operand" "")]
8508 "TARGET_TLS && TARGET_ARCH32"
8509 "xor\\t%1, %%tle_lox10(%a2), %0")
8511 (define_insn "tle_hix22_sp64"
8512 [(set (match_operand:DI 0 "register_operand" "=r")
8513 (high:DI (unspec:DI [(match_operand 1 "tle_symbolic_operand" "")]
8515 "TARGET_TLS && TARGET_ARCH64"
8516 "sethi\\t%%tle_hix22(%a1), %0")
8518 (define_insn "tle_lox10_sp64"
8519 [(set (match_operand:DI 0 "register_operand" "=r")
8520 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
8521 (unspec:DI [(match_operand 2 "tle_symbolic_operand" "")]
8523 "TARGET_TLS && TARGET_ARCH64"
8524 "xor\\t%1, %%tle_lox10(%a2), %0")
8526 ;; Now patterns combining tldo_add{32,64} with some integer loads or stores
8527 (define_insn "*tldo_ldub_sp32"
8528 [(set (match_operand:QI 0 "register_operand" "=r")
8529 (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8530 (match_operand 3 "tld_symbolic_operand" "")]
8532 (match_operand:SI 1 "register_operand" "r"))))]
8533 "TARGET_TLS && TARGET_ARCH32"
8534 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8535 [(set_attr "type" "load")
8536 (set_attr "us3load_type" "3cycle")])
8538 (define_insn "*tldo_ldub1_sp32"
8539 [(set (match_operand:HI 0 "register_operand" "=r")
8540 (zero_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8541 (match_operand 3 "tld_symbolic_operand" "")]
8543 (match_operand:SI 1 "register_operand" "r")))))]
8544 "TARGET_TLS && TARGET_ARCH32"
8545 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8546 [(set_attr "type" "load")
8547 (set_attr "us3load_type" "3cycle")])
8549 (define_insn "*tldo_ldub2_sp32"
8550 [(set (match_operand:SI 0 "register_operand" "=r")
8551 (zero_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8552 (match_operand 3 "tld_symbolic_operand" "")]
8554 (match_operand:SI 1 "register_operand" "r")))))]
8555 "TARGET_TLS && TARGET_ARCH32"
8556 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8557 [(set_attr "type" "load")
8558 (set_attr "us3load_type" "3cycle")])
8560 (define_insn "*tldo_ldsb1_sp32"
8561 [(set (match_operand:HI 0 "register_operand" "=r")
8562 (sign_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8563 (match_operand 3 "tld_symbolic_operand" "")]
8565 (match_operand:SI 1 "register_operand" "r")))))]
8566 "TARGET_TLS && TARGET_ARCH32"
8567 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
8568 [(set_attr "type" "sload")
8569 (set_attr "us3load_type" "3cycle")])
8571 (define_insn "*tldo_ldsb2_sp32"
8572 [(set (match_operand:SI 0 "register_operand" "=r")
8573 (sign_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8574 (match_operand 3 "tld_symbolic_operand" "")]
8576 (match_operand:SI 1 "register_operand" "r")))))]
8577 "TARGET_TLS && TARGET_ARCH32"
8578 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
8579 [(set_attr "type" "sload")
8580 (set_attr "us3load_type" "3cycle")])
8582 (define_insn "*tldo_ldub_sp64"
8583 [(set (match_operand:QI 0 "register_operand" "=r")
8584 (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8585 (match_operand 3 "tld_symbolic_operand" "")]
8587 (match_operand:DI 1 "register_operand" "r"))))]
8588 "TARGET_TLS && TARGET_ARCH64"
8589 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8590 [(set_attr "type" "load")
8591 (set_attr "us3load_type" "3cycle")])
8593 (define_insn "*tldo_ldub1_sp64"
8594 [(set (match_operand:HI 0 "register_operand" "=r")
8595 (zero_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8596 (match_operand 3 "tld_symbolic_operand" "")]
8598 (match_operand:DI 1 "register_operand" "r")))))]
8599 "TARGET_TLS && TARGET_ARCH64"
8600 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8601 [(set_attr "type" "load")
8602 (set_attr "us3load_type" "3cycle")])
8604 (define_insn "*tldo_ldub2_sp64"
8605 [(set (match_operand:SI 0 "register_operand" "=r")
8606 (zero_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8607 (match_operand 3 "tld_symbolic_operand" "")]
8609 (match_operand:DI 1 "register_operand" "r")))))]
8610 "TARGET_TLS && TARGET_ARCH64"
8611 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8612 [(set_attr "type" "load")
8613 (set_attr "us3load_type" "3cycle")])
8615 (define_insn "*tldo_ldub3_sp64"
8616 [(set (match_operand:DI 0 "register_operand" "=r")
8617 (zero_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8618 (match_operand 3 "tld_symbolic_operand" "")]
8620 (match_operand:DI 1 "register_operand" "r")))))]
8621 "TARGET_TLS && TARGET_ARCH64"
8622 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8623 [(set_attr "type" "load")
8624 (set_attr "us3load_type" "3cycle")])
8626 (define_insn "*tldo_ldsb1_sp64"
8627 [(set (match_operand:HI 0 "register_operand" "=r")
8628 (sign_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8629 (match_operand 3 "tld_symbolic_operand" "")]
8631 (match_operand:DI 1 "register_operand" "r")))))]
8632 "TARGET_TLS && TARGET_ARCH64"
8633 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
8634 [(set_attr "type" "sload")
8635 (set_attr "us3load_type" "3cycle")])
8637 (define_insn "*tldo_ldsb2_sp64"
8638 [(set (match_operand:SI 0 "register_operand" "=r")
8639 (sign_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8640 (match_operand 3 "tld_symbolic_operand" "")]
8642 (match_operand:DI 1 "register_operand" "r")))))]
8643 "TARGET_TLS && TARGET_ARCH64"
8644 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
8645 [(set_attr "type" "sload")
8646 (set_attr "us3load_type" "3cycle")])
8648 (define_insn "*tldo_ldsb3_sp64"
8649 [(set (match_operand:DI 0 "register_operand" "=r")
8650 (sign_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8651 (match_operand 3 "tld_symbolic_operand" "")]
8653 (match_operand:DI 1 "register_operand" "r")))))]
8654 "TARGET_TLS && TARGET_ARCH64"
8655 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
8656 [(set_attr "type" "sload")
8657 (set_attr "us3load_type" "3cycle")])
8659 (define_insn "*tldo_lduh_sp32"
8660 [(set (match_operand:HI 0 "register_operand" "=r")
8661 (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8662 (match_operand 3 "tld_symbolic_operand" "")]
8664 (match_operand:SI 1 "register_operand" "r"))))]
8665 "TARGET_TLS && TARGET_ARCH32"
8666 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
8667 [(set_attr "type" "load")
8668 (set_attr "us3load_type" "3cycle")])
8670 (define_insn "*tldo_lduh1_sp32"
8671 [(set (match_operand:SI 0 "register_operand" "=r")
8672 (zero_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8673 (match_operand 3 "tld_symbolic_operand" "")]
8675 (match_operand:SI 1 "register_operand" "r")))))]
8676 "TARGET_TLS && TARGET_ARCH32"
8677 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
8678 [(set_attr "type" "load")
8679 (set_attr "us3load_type" "3cycle")])
8681 (define_insn "*tldo_ldsh1_sp32"
8682 [(set (match_operand:SI 0 "register_operand" "=r")
8683 (sign_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8684 (match_operand 3 "tld_symbolic_operand" "")]
8686 (match_operand:SI 1 "register_operand" "r")))))]
8687 "TARGET_TLS && TARGET_ARCH32"
8688 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
8689 [(set_attr "type" "sload")
8690 (set_attr "us3load_type" "3cycle")])
8692 (define_insn "*tldo_lduh_sp64"
8693 [(set (match_operand:HI 0 "register_operand" "=r")
8694 (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8695 (match_operand 3 "tld_symbolic_operand" "")]
8697 (match_operand:DI 1 "register_operand" "r"))))]
8698 "TARGET_TLS && TARGET_ARCH64"
8699 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
8700 [(set_attr "type" "load")
8701 (set_attr "us3load_type" "3cycle")])
8703 (define_insn "*tldo_lduh1_sp64"
8704 [(set (match_operand:SI 0 "register_operand" "=r")
8705 (zero_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8706 (match_operand 3 "tld_symbolic_operand" "")]
8708 (match_operand:DI 1 "register_operand" "r")))))]
8709 "TARGET_TLS && TARGET_ARCH64"
8710 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
8711 [(set_attr "type" "load")
8712 (set_attr "us3load_type" "3cycle")])
8714 (define_insn "*tldo_lduh2_sp64"
8715 [(set (match_operand:DI 0 "register_operand" "=r")
8716 (zero_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8717 (match_operand 3 "tld_symbolic_operand" "")]
8719 (match_operand:DI 1 "register_operand" "r")))))]
8720 "TARGET_TLS && TARGET_ARCH64"
8721 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
8722 [(set_attr "type" "load")
8723 (set_attr "us3load_type" "3cycle")])
8725 (define_insn "*tldo_ldsh1_sp64"
8726 [(set (match_operand:SI 0 "register_operand" "=r")
8727 (sign_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8728 (match_operand 3 "tld_symbolic_operand" "")]
8730 (match_operand:DI 1 "register_operand" "r")))))]
8731 "TARGET_TLS && TARGET_ARCH64"
8732 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
8733 [(set_attr "type" "sload")
8734 (set_attr "us3load_type" "3cycle")])
8736 (define_insn "*tldo_ldsh2_sp64"
8737 [(set (match_operand:DI 0 "register_operand" "=r")
8738 (sign_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8739 (match_operand 3 "tld_symbolic_operand" "")]
8741 (match_operand:DI 1 "register_operand" "r")))))]
8742 "TARGET_TLS && TARGET_ARCH64"
8743 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
8744 [(set_attr "type" "sload")
8745 (set_attr "us3load_type" "3cycle")])
8747 (define_insn "*tldo_lduw_sp32"
8748 [(set (match_operand:SI 0 "register_operand" "=r")
8749 (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8750 (match_operand 3 "tld_symbolic_operand" "")]
8752 (match_operand:SI 1 "register_operand" "r"))))]
8753 "TARGET_TLS && TARGET_ARCH32"
8754 "ld\t[%1 + %2], %0, %%tldo_add(%3)"
8755 [(set_attr "type" "load")])
8757 (define_insn "*tldo_lduw_sp64"
8758 [(set (match_operand:SI 0 "register_operand" "=r")
8759 (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8760 (match_operand 3 "tld_symbolic_operand" "")]
8762 (match_operand:DI 1 "register_operand" "r"))))]
8763 "TARGET_TLS && TARGET_ARCH64"
8764 "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
8765 [(set_attr "type" "load")])
8767 (define_insn "*tldo_lduw1_sp64"
8768 [(set (match_operand:DI 0 "register_operand" "=r")
8769 (zero_extend:DI (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8770 (match_operand 3 "tld_symbolic_operand" "")]
8772 (match_operand:DI 1 "register_operand" "r")))))]
8773 "TARGET_TLS && TARGET_ARCH64"
8774 "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
8775 [(set_attr "type" "load")])
8777 (define_insn "*tldo_ldsw1_sp64"
8778 [(set (match_operand:DI 0 "register_operand" "=r")
8779 (sign_extend:DI (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8780 (match_operand 3 "tld_symbolic_operand" "")]
8782 (match_operand:DI 1 "register_operand" "r")))))]
8783 "TARGET_TLS && TARGET_ARCH64"
8784 "ldsw\t[%1 + %2], %0, %%tldo_add(%3)"
8785 [(set_attr "type" "sload")
8786 (set_attr "us3load_type" "3cycle")])
8788 (define_insn "*tldo_ldx_sp64"
8789 [(set (match_operand:DI 0 "register_operand" "=r")
8790 (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8791 (match_operand 3 "tld_symbolic_operand" "")]
8793 (match_operand:DI 1 "register_operand" "r"))))]
8794 "TARGET_TLS && TARGET_ARCH64"
8795 "ldx\t[%1 + %2], %0, %%tldo_add(%3)"
8796 [(set_attr "type" "load")])
8798 (define_insn "*tldo_stb_sp32"
8799 [(set (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8800 (match_operand 3 "tld_symbolic_operand" "")]
8802 (match_operand:SI 1 "register_operand" "r")))
8803 (match_operand:QI 0 "register_operand" "=r"))]
8804 "TARGET_TLS && TARGET_ARCH32"
8805 "stb\t%0, [%1 + %2], %%tldo_add(%3)"
8806 [(set_attr "type" "store")])
8808 (define_insn "*tldo_stb_sp64"
8809 [(set (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8810 (match_operand 3 "tld_symbolic_operand" "")]
8812 (match_operand:DI 1 "register_operand" "r")))
8813 (match_operand:QI 0 "register_operand" "=r"))]
8814 "TARGET_TLS && TARGET_ARCH64"
8815 "stb\t%0, [%1 + %2], %%tldo_add(%3)"
8816 [(set_attr "type" "store")])
8818 (define_insn "*tldo_sth_sp32"
8819 [(set (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8820 (match_operand 3 "tld_symbolic_operand" "")]
8822 (match_operand:SI 1 "register_operand" "r")))
8823 (match_operand:HI 0 "register_operand" "=r"))]
8824 "TARGET_TLS && TARGET_ARCH32"
8825 "sth\t%0, [%1 + %2], %%tldo_add(%3)"
8826 [(set_attr "type" "store")])
8828 (define_insn "*tldo_sth_sp64"
8829 [(set (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8830 (match_operand 3 "tld_symbolic_operand" "")]
8832 (match_operand:DI 1 "register_operand" "r")))
8833 (match_operand:HI 0 "register_operand" "=r"))]
8834 "TARGET_TLS && TARGET_ARCH64"
8835 "sth\t%0, [%1 + %2], %%tldo_add(%3)"
8836 [(set_attr "type" "store")])
8838 (define_insn "*tldo_stw_sp32"
8839 [(set (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8840 (match_operand 3 "tld_symbolic_operand" "")]
8842 (match_operand:SI 1 "register_operand" "r")))
8843 (match_operand:SI 0 "register_operand" "=r"))]
8844 "TARGET_TLS && TARGET_ARCH32"
8845 "st\t%0, [%1 + %2], %%tldo_add(%3)"
8846 [(set_attr "type" "store")])
8848 (define_insn "*tldo_stw_sp64"
8849 [(set (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8850 (match_operand 3 "tld_symbolic_operand" "")]
8852 (match_operand:DI 1 "register_operand" "r")))
8853 (match_operand:SI 0 "register_operand" "=r"))]
8854 "TARGET_TLS && TARGET_ARCH64"
8855 "stw\t%0, [%1 + %2], %%tldo_add(%3)"
8856 [(set_attr "type" "store")])
8858 (define_insn "*tldo_stx_sp64"
8859 [(set (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8860 (match_operand 3 "tld_symbolic_operand" "")]
8862 (match_operand:DI 1 "register_operand" "r")))
8863 (match_operand:DI 0 "register_operand" "=r"))]
8864 "TARGET_TLS && TARGET_ARCH64"
8865 "stx\t%0, [%1 + %2], %%tldo_add(%3)"
8866 [(set_attr "type" "store")])
8868 ;; Vector instructions.
8870 (define_insn "addv2si3"
8871 [(set (match_operand:V2SI 0 "register_operand" "=e")
8872 (plus:V2SI (match_operand:V2SI 1 "register_operand" "e")
8873 (match_operand:V2SI 2 "register_operand" "e")))]
8875 "fpadd32\t%1, %2, %0"
8876 [(set_attr "type" "fga")
8877 (set_attr "fptype" "double")])
8879 (define_insn "addv4hi3"
8880 [(set (match_operand:V4HI 0 "register_operand" "=e")
8881 (plus:V4HI (match_operand:V4HI 1 "register_operand" "e")
8882 (match_operand:V4HI 2 "register_operand" "e")))]
8884 "fpadd16\t%1, %2, %0"
8885 [(set_attr "type" "fga")
8886 (set_attr "fptype" "double")])
8888 ;; fpadd32s is emitted by the addsi3 pattern.
8890 (define_insn "addv2hi3"
8891 [(set (match_operand:V2HI 0 "register_operand" "=f")
8892 (plus:V2HI (match_operand:V2HI 1 "register_operand" "f")
8893 (match_operand:V2HI 2 "register_operand" "f")))]
8895 "fpadd16s\t%1, %2, %0"
8896 [(set_attr "type" "fga")
8897 (set_attr "fptype" "single")])
8899 (define_insn "subv2si3"
8900 [(set (match_operand:V2SI 0 "register_operand" "=e")
8901 (minus:V2SI (match_operand:V2SI 1 "register_operand" "e")
8902 (match_operand:V2SI 2 "register_operand" "e")))]
8904 "fpsub32\t%1, %2, %0"
8905 [(set_attr "type" "fga")
8906 (set_attr "fptype" "double")])
8908 (define_insn "subv4hi3"
8909 [(set (match_operand:V4HI 0 "register_operand" "=e")
8910 (minus:V4HI (match_operand:V4HI 1 "register_operand" "e")
8911 (match_operand:V4HI 2 "register_operand" "e")))]
8913 "fpsub16\t%1, %2, %0"
8914 [(set_attr "type" "fga")
8915 (set_attr "fptype" "double")])
8917 ;; fpsub32s is emitted by the subsi3 pattern.
8919 (define_insn "subv2hi3"
8920 [(set (match_operand:V2HI 0 "register_operand" "=f")
8921 (minus:V2HI (match_operand:V2HI 1 "register_operand" "f")
8922 (match_operand:V2HI 2 "register_operand" "f")))]
8924 "fpsub16s\t%1, %2, %0"
8925 [(set_attr "type" "fga")
8926 (set_attr "fptype" "single")])
8928 ;; All other logical instructions have integer equivalents so they
8929 ;; are defined together.
8931 ;; (ior (not (op1)) (not (op2))) is the canonical form of NAND.
8933 (define_insn "*nand<V64mode>_vis"
8934 [(set (match_operand:V64 0 "register_operand" "=e")
8935 (ior:V64 (not:V64 (match_operand:V64 1 "register_operand" "e"))
8936 (not:V64 (match_operand:V64 2 "register_operand" "e"))))]
8939 [(set_attr "type" "fga")
8940 (set_attr "fptype" "double")])
8942 (define_insn "*nand<V32mode>_vis"
8943 [(set (match_operand:V32 0 "register_operand" "=f")
8944 (ior:V32 (not:V32 (match_operand:V32 1 "register_operand" "f"))
8945 (not:V32 (match_operand:V32 2 "register_operand" "f"))))]
8947 "fnands\t%1, %2, %0"
8948 [(set_attr "type" "fga")
8949 (set_attr "fptype" "single")])
8951 ;; Hard to generate VIS instructions. We have builtins for these.
8953 (define_insn "fpack16_vis"
8954 [(set (match_operand:V4QI 0 "register_operand" "=f")
8955 (unspec:V4QI [(match_operand:V4HI 1 "register_operand" "e")]
8959 [(set_attr "type" "fga")
8960 (set_attr "fptype" "double")])
8962 (define_insn "fpackfix_vis"
8963 [(set (match_operand:V2HI 0 "register_operand" "=f")
8964 (unspec:V2HI [(match_operand:V2SI 1 "register_operand" "e")]
8968 [(set_attr "type" "fga")
8969 (set_attr "fptype" "double")])
8971 (define_insn "fpack32_vis"
8972 [(set (match_operand:V8QI 0 "register_operand" "=e")
8973 (unspec:V8QI [(match_operand:V2SI 1 "register_operand" "e")
8974 (match_operand:V8QI 2 "register_operand" "e")]
8977 "fpack32\t%1, %2, %0"
8978 [(set_attr "type" "fga")
8979 (set_attr "fptype" "double")])
8981 (define_insn "fexpand_vis"
8982 [(set (match_operand:V4HI 0 "register_operand" "=e")
8983 (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")]
8987 [(set_attr "type" "fga")
8988 (set_attr "fptype" "double")])
8990 ;; It may be possible to describe this operation as (1 indexed):
8991 ;; (vec_select (vec_duplicate (vec_duplicate (vec_concat 1 2)))
8992 ;; 1,5,10,14,19,23,28,32)
8993 ;; Note that (vec_merge:V8QI [(V4QI) (V4QI)] (10101010 = 170) doesn't work
8994 ;; because vec_merge expects all the operands to be of the same type.
8995 (define_insn "fpmerge_vis"
8996 [(set (match_operand:V8QI 0 "register_operand" "=e")
8997 (unspec:V8QI [(match_operand:V4QI 1 "register_operand" "f")
8998 (match_operand:V4QI 2 "register_operand" "f")]
9001 "fpmerge\t%1, %2, %0"
9002 [(set_attr "type" "fga")
9003 (set_attr "fptype" "double")])
9005 ;; Partitioned multiply instructions
9006 (define_insn "fmul8x16_vis"
9007 [(set (match_operand:V4HI 0 "register_operand" "=e")
9008 (mult:V4HI (match_operand:V4QI 1 "register_operand" "f")
9009 (match_operand:V4HI 2 "register_operand" "e")))]
9011 "fmul8x16\t%1, %2, %0"
9012 [(set_attr "type" "fpmul")
9013 (set_attr "fptype" "double")])
9015 ;; Only one of the following two insns can be a multiply.
9016 (define_insn "fmul8x16au_vis"
9017 [(set (match_operand:V4HI 0 "register_operand" "=e")
9018 (mult:V4HI (match_operand:V4QI 1 "register_operand" "f")
9019 (match_operand:V2HI 2 "register_operand" "f")))]
9021 "fmul8x16au\t%1, %2, %0"
9022 [(set_attr "type" "fpmul")
9023 (set_attr "fptype" "double")])
9025 (define_insn "fmul8x16al_vis"
9026 [(set (match_operand:V4HI 0 "register_operand" "=e")
9027 (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")
9028 (match_operand:V2HI 2 "register_operand" "f")]
9031 "fmul8x16al\t%1, %2, %0"
9032 [(set_attr "type" "fpmul")
9033 (set_attr "fptype" "double")])
9035 ;; Only one of the following two insns can be a multiply.
9036 (define_insn "fmul8sux16_vis"
9037 [(set (match_operand:V4HI 0 "register_operand" "=e")
9038 (mult:V4HI (match_operand:V8QI 1 "register_operand" "e")
9039 (match_operand:V4HI 2 "register_operand" "e")))]
9041 "fmul8sux16\t%1, %2, %0"
9042 [(set_attr "type" "fpmul")
9043 (set_attr "fptype" "double")])
9045 (define_insn "fmul8ulx16_vis"
9046 [(set (match_operand:V4HI 0 "register_operand" "=e")
9047 (unspec:V4HI [(match_operand:V8QI 1 "register_operand" "e")
9048 (match_operand:V4HI 2 "register_operand" "e")]
9051 "fmul8ulx16\t%1, %2, %0"
9052 [(set_attr "type" "fpmul")
9053 (set_attr "fptype" "double")])
9055 ;; Only one of the following two insns can be a multiply.
9056 (define_insn "fmuld8sux16_vis"
9057 [(set (match_operand:V2SI 0 "register_operand" "=e")
9058 (mult:V2SI (match_operand:V4QI 1 "register_operand" "f")
9059 (match_operand:V2HI 2 "register_operand" "f")))]
9061 "fmuld8sux16\t%1, %2, %0"
9062 [(set_attr "type" "fpmul")
9063 (set_attr "fptype" "double")])
9065 (define_insn "fmuld8ulx16_vis"
9066 [(set (match_operand:V2SI 0 "register_operand" "=e")
9067 (unspec:V2SI [(match_operand:V4QI 1 "register_operand" "f")
9068 (match_operand:V2HI 2 "register_operand" "f")]
9071 "fmuld8ulx16\t%1, %2, %0"
9072 [(set_attr "type" "fpmul")
9073 (set_attr "fptype" "double")])
9075 ;; Using faligndata only makes sense after an alignaddr since the choice of
9076 ;; bytes to take out of each operand is dependant on the results of the last
9078 (define_insn "faligndata<V64I:mode>_vis"
9079 [(set (match_operand:V64I 0 "register_operand" "=e")
9080 (unspec:V64I [(match_operand:V64I 1 "register_operand" "e")
9081 (match_operand:V64I 2 "register_operand" "e")]
9084 "faligndata\t%1, %2, %0"
9085 [(set_attr "type" "fga")
9086 (set_attr "fptype" "double")])
9088 (define_insn "alignaddr<P:mode>_vis"
9089 [(set (match_operand:P 0 "register_operand" "=r")
9090 (unspec:P [(match_operand:P 1 "reg_or_0_operand" "rJ")
9091 (match_operand:P 2 "reg_or_0_operand" "rJ")]
9094 "alignaddr\t%r1, %r2, %0")
9096 (define_insn "pdist_vis"
9097 [(set (match_operand:DI 0 "register_operand" "=e")
9098 (unspec:DI [(match_operand:V8QI 1 "register_operand" "e")
9099 (match_operand:V8QI 2 "register_operand" "e")
9100 (match_operand:DI 3 "register_operand" "0")]
9104 [(set_attr "type" "fga")
9105 (set_attr "fptype" "double")])