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 if (! TARGET_ARCH64)
2088 emit_insn (gen_movdi_pic_label_ref (operands[0], operands[1]));
2092 if (symbolic_operand (operands[1], DImode))
2094 operands[1] = legitimize_pic_address (operands[1],
2096 (reload_in_progress ?
2103 /* If we are trying to toss an integer constant into the
2104 FPU registers, force it into memory. */
2105 if (GET_CODE (operands[0]) == REG
2106 && REGNO (operands[0]) >= SPARC_FIRST_FP_REG
2107 && REGNO (operands[0]) <= SPARC_LAST_V9_FP_REG
2108 && CONSTANT_P (operands[1]))
2109 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
2112 /* This makes sure we will not get rematched due to splittage. */
2113 if (! CONSTANT_P (operands[1]) || input_operand (operands[1], DImode))
2115 else if (TARGET_ARCH64
2116 && GET_CODE (operands[1]) != HIGH
2117 && GET_CODE (operands[1]) != LO_SUM)
2119 sparc_emit_set_const64 (operands[0], operands[1]);
2127 ;; Be careful, fmovd does not exist when !v9.
2128 ;; We match MEM moves directly when we have correct even
2129 ;; numbered registers, but fall into splits otherwise.
2130 ;; The constraint ordering here is really important to
2131 ;; avoid insane problems in reload, especially for patterns
2134 ;; (set (mem:DI (plus:SI (reg:SI 30 %fp)
2135 ;; (const_int -5016)))
2139 (define_insn "*movdi_insn_sp32_v9"
2140 [(set (match_operand:DI 0 "nonimmediate_operand"
2141 "=T,o,T,U,o,r,r,r,?T,?f,?f,?o,?e,?e,?W")
2142 (match_operand:DI 1 "input_operand"
2143 " J,J,U,T,r,o,i,r, f, T, o, f, e, W, e"))]
2144 "! TARGET_ARCH64 && TARGET_V9
2145 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2162 [(set_attr "type" "store,store,store,load,*,*,*,*,fpstore,fpload,*,*,fpmove,fpload,fpstore")
2163 (set_attr "length" "*,2,*,*,2,2,2,2,*,*,2,2,*,*,*")
2164 (set_attr "fptype" "*,*,*,*,*,*,*,*,*,*,*,*,double,*,*")])
2166 (define_insn "*movdi_insn_sp32"
2167 [(set (match_operand:DI 0 "nonimmediate_operand"
2168 "=o,T,U,o,r,r,r,?T,?f,?f,?o,?f")
2169 (match_operand:DI 1 "input_operand"
2170 " J,U,T,r,o,i,r, f, T, o, f, f"))]
2172 && (register_operand (operands[0], DImode)
2173 || register_operand (operands[1], DImode))"
2187 [(set_attr "type" "store,store,load,*,*,*,*,fpstore,fpload,*,*,*")
2188 (set_attr "length" "2,*,*,2,2,2,2,*,*,2,2,2")])
2190 ;; The following are generated by sparc_emit_set_const64
2191 (define_insn "*movdi_sp64_dbl"
2192 [(set (match_operand:DI 0 "register_operand" "=r")
2193 (match_operand:DI 1 "const64_operand" ""))]
2195 && HOST_BITS_PER_WIDE_INT != 64)"
2198 ;; This is needed to show CSE exactly which bits are set
2199 ;; in a 64-bit register by sethi instructions.
2200 (define_insn "*movdi_const64_special"
2201 [(set (match_operand:DI 0 "register_operand" "=r")
2202 (match_operand:DI 1 "const64_high_operand" ""))]
2204 "sethi\t%%hi(%a1), %0")
2206 (define_insn "*movdi_insn_sp64_novis"
2207 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,m,?e,?e,?W")
2208 (match_operand:DI 1 "input_operand" "rI,N,J,m,rJ,e,W,e"))]
2209 "TARGET_ARCH64 && ! TARGET_VIS
2210 && (register_operand (operands[0], DImode)
2211 || reg_or_0_operand (operands[1], DImode))"
2214 sethi\t%%hi(%a1), %0
2221 [(set_attr "type" "*,*,*,load,store,fpmove,fpload,fpstore")
2222 (set_attr "fptype" "*,*,*,*,*,double,*,*")])
2224 ;; We don't define V1SI because SI should work just fine.
2225 (define_mode_macro V64 [DF V2SI V4HI V8QI])
2226 (define_mode_macro V32 [SF V2HI V4QI])
2228 (define_insn "*movdi_insn_sp64_vis"
2229 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,m,?e,?e,?W,b")
2230 (match_operand:DI 1 "input_operand" "rI,N,J,m,rJ,e,W,e,J"))]
2231 "TARGET_ARCH64 && TARGET_VIS &&
2232 (register_operand (operands[0], DImode)
2233 || reg_or_0_operand (operands[1], DImode))"
2236 sethi\t%%hi(%a1), %0
2244 [(set_attr "type" "*,*,*,load,store,fpmove,fpload,fpstore,fga")
2245 (set_attr "fptype" "*,*,*,*,*,double,*,*,double")])
2247 (define_expand "movdi_pic_label_ref"
2248 [(set (match_dup 3) (high:DI
2249 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
2250 (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
2251 (set (match_dup 4) (lo_sum:DI (match_dup 3)
2252 (unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
2253 (set (match_operand:DI 0 "register_operand" "=r")
2254 (minus:DI (match_dup 5) (match_dup 4)))]
2255 "TARGET_ARCH64 && flag_pic"
2257 current_function_uses_pic_offset_table = 1;
2258 operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
2261 operands[3] = operands[0];
2262 operands[4] = operands[0];
2266 operands[3] = gen_reg_rtx (DImode);
2267 operands[4] = gen_reg_rtx (DImode);
2269 operands[5] = pic_offset_table_rtx;
2272 (define_insn "*movdi_high_pic_label_ref"
2273 [(set (match_operand:DI 0 "register_operand" "=r")
2275 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
2276 (match_operand:DI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
2277 "TARGET_ARCH64 && flag_pic"
2278 "sethi\t%%hi(%a2-(%a1-.)), %0")
2280 (define_insn "*movdi_lo_sum_pic_label_ref"
2281 [(set (match_operand:DI 0 "register_operand" "=r")
2282 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2283 (unspec:DI [(match_operand:DI 2 "label_ref_operand" "")
2284 (match_operand:DI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
2285 "TARGET_ARCH64 && flag_pic"
2286 "or\t%1, %%lo(%a3-(%a2-.)), %0")
2288 ;; SPARC-v9 code model support insns. See sparc_emit_set_symbolic_const64
2289 ;; in sparc.c to see what is going on here... PIC stuff comes first.
2291 (define_insn "movdi_lo_sum_pic"
2292 [(set (match_operand:DI 0 "register_operand" "=r")
2293 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2294 (unspec:DI [(match_operand:DI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
2295 "TARGET_ARCH64 && flag_pic"
2296 "or\t%1, %%lo(%a2), %0")
2298 (define_insn "movdi_high_pic"
2299 [(set (match_operand:DI 0 "register_operand" "=r")
2300 (high:DI (unspec:DI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
2301 "TARGET_ARCH64 && flag_pic && check_pic (1)"
2302 "sethi\t%%hi(%a1), %0")
2304 (define_insn "*sethi_di_medlow_embmedany_pic"
2305 [(set (match_operand:DI 0 "register_operand" "=r")
2306 (high:DI (match_operand:DI 1 "sp64_medium_pic_operand" "")))]
2307 "(TARGET_CM_MEDLOW || TARGET_CM_EMBMEDANY) && check_pic (1)"
2308 "sethi\t%%hi(%a1), %0")
2310 (define_insn "*sethi_di_medlow"
2311 [(set (match_operand:DI 0 "register_operand" "=r")
2312 (high:DI (match_operand:DI 1 "symbolic_operand" "")))]
2313 "TARGET_CM_MEDLOW && check_pic (1)"
2314 "sethi\t%%hi(%a1), %0")
2316 (define_insn "*losum_di_medlow"
2317 [(set (match_operand:DI 0 "register_operand" "=r")
2318 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2319 (match_operand:DI 2 "symbolic_operand" "")))]
2321 "or\t%1, %%lo(%a2), %0")
2323 (define_insn "seth44"
2324 [(set (match_operand:DI 0 "register_operand" "=r")
2325 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETH44)))]
2327 "sethi\t%%h44(%a1), %0")
2329 (define_insn "setm44"
2330 [(set (match_operand:DI 0 "register_operand" "=r")
2331 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2332 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_SETM44)))]
2334 "or\t%1, %%m44(%a2), %0")
2336 (define_insn "setl44"
2337 [(set (match_operand:DI 0 "register_operand" "=r")
2338 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2339 (match_operand:DI 2 "symbolic_operand" "")))]
2341 "or\t%1, %%l44(%a2), %0")
2343 (define_insn "sethh"
2344 [(set (match_operand:DI 0 "register_operand" "=r")
2345 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETHH)))]
2347 "sethi\t%%hh(%a1), %0")
2349 (define_insn "setlm"
2350 [(set (match_operand:DI 0 "register_operand" "=r")
2351 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETLM)))]
2353 "sethi\t%%lm(%a1), %0")
2355 (define_insn "sethm"
2356 [(set (match_operand:DI 0 "register_operand" "=r")
2357 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2358 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_EMB_SETHM)))]
2360 "or\t%1, %%hm(%a2), %0")
2362 (define_insn "setlo"
2363 [(set (match_operand:DI 0 "register_operand" "=r")
2364 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2365 (match_operand:DI 2 "symbolic_operand" "")))]
2367 "or\t%1, %%lo(%a2), %0")
2369 (define_insn "embmedany_sethi"
2370 [(set (match_operand:DI 0 "register_operand" "=r")
2371 (high:DI (unspec:DI [(match_operand:DI 1 "data_segment_operand" "")] UNSPEC_EMB_HISUM)))]
2372 "TARGET_CM_EMBMEDANY && check_pic (1)"
2373 "sethi\t%%hi(%a1), %0")
2375 (define_insn "embmedany_losum"
2376 [(set (match_operand:DI 0 "register_operand" "=r")
2377 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2378 (match_operand:DI 2 "data_segment_operand" "")))]
2379 "TARGET_CM_EMBMEDANY"
2380 "add\t%1, %%lo(%a2), %0")
2382 (define_insn "embmedany_brsum"
2383 [(set (match_operand:DI 0 "register_operand" "=r")
2384 (unspec:DI [(match_operand:DI 1 "register_operand" "r")] UNSPEC_EMB_HISUM))]
2385 "TARGET_CM_EMBMEDANY"
2388 (define_insn "embmedany_textuhi"
2389 [(set (match_operand:DI 0 "register_operand" "=r")
2390 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTUHI)))]
2391 "TARGET_CM_EMBMEDANY && check_pic (1)"
2392 "sethi\t%%uhi(%a1), %0")
2394 (define_insn "embmedany_texthi"
2395 [(set (match_operand:DI 0 "register_operand" "=r")
2396 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTHI)))]
2397 "TARGET_CM_EMBMEDANY && check_pic (1)"
2398 "sethi\t%%hi(%a1), %0")
2400 (define_insn "embmedany_textulo"
2401 [(set (match_operand:DI 0 "register_operand" "=r")
2402 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2403 (unspec:DI [(match_operand:DI 2 "text_segment_operand" "")] UNSPEC_EMB_TEXTULO)))]
2404 "TARGET_CM_EMBMEDANY"
2405 "or\t%1, %%ulo(%a2), %0")
2407 (define_insn "embmedany_textlo"
2408 [(set (match_operand:DI 0 "register_operand" "=r")
2409 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2410 (match_operand:DI 2 "text_segment_operand" "")))]
2411 "TARGET_CM_EMBMEDANY"
2412 "or\t%1, %%lo(%a2), %0")
2414 ;; Now some patterns to help reload out a bit.
2415 (define_expand "reload_indi"
2416 [(parallel [(match_operand:DI 0 "register_operand" "=r")
2417 (match_operand:DI 1 "immediate_operand" "")
2418 (match_operand:TI 2 "register_operand" "=&r")])]
2420 || TARGET_CM_EMBMEDANY)
2423 sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
2427 (define_expand "reload_outdi"
2428 [(parallel [(match_operand:DI 0 "register_operand" "=r")
2429 (match_operand:DI 1 "immediate_operand" "")
2430 (match_operand:TI 2 "register_operand" "=&r")])]
2432 || TARGET_CM_EMBMEDANY)
2435 sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
2439 ;; Split up putting CONSTs and REGs into DI regs when !arch64
2441 [(set (match_operand:DI 0 "register_operand" "")
2442 (match_operand:DI 1 "const_int_operand" ""))]
2443 "! TARGET_ARCH64 && reload_completed"
2444 [(clobber (const_int 0))]
2446 #if HOST_BITS_PER_WIDE_INT == 32
2447 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
2448 (INTVAL (operands[1]) < 0) ?
2451 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2454 unsigned int low, high;
2456 low = trunc_int_for_mode (INTVAL (operands[1]), SImode);
2457 high = trunc_int_for_mode (INTVAL (operands[1]) >> 32, SImode);
2458 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), GEN_INT (high)));
2460 /* Slick... but this trick loses if this subreg constant part
2461 can be done in one insn. */
2462 if (low == high && (low & 0x3ff) != 0 && low + 0x1000 >= 0x2000)
2463 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2464 gen_highpart (SImode, operands[0])));
2466 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), GEN_INT (low)));
2472 [(set (match_operand:DI 0 "register_operand" "")
2473 (match_operand:DI 1 "const_double_operand" ""))]
2477 && ((GET_CODE (operands[0]) == REG
2478 && REGNO (operands[0]) < 32)
2479 || (GET_CODE (operands[0]) == SUBREG
2480 && GET_CODE (SUBREG_REG (operands[0])) == REG
2481 && REGNO (SUBREG_REG (operands[0])) < 32))))"
2482 [(clobber (const_int 0))]
2484 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
2485 GEN_INT (CONST_DOUBLE_HIGH (operands[1]))));
2487 /* Slick... but this trick loses if this subreg constant part
2488 can be done in one insn. */
2489 if (CONST_DOUBLE_LOW (operands[1]) == CONST_DOUBLE_HIGH (operands[1])
2490 && !(SPARC_SETHI32_P (CONST_DOUBLE_HIGH (operands[1]))
2491 || SPARC_SIMM13_P (CONST_DOUBLE_HIGH (operands[1]))))
2493 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2494 gen_highpart (SImode, operands[0])));
2498 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2499 GEN_INT (CONST_DOUBLE_LOW (operands[1]))));
2505 [(set (match_operand:DI 0 "register_operand" "")
2506 (match_operand:DI 1 "register_operand" ""))]
2510 && ((GET_CODE (operands[0]) == REG
2511 && REGNO (operands[0]) < 32)
2512 || (GET_CODE (operands[0]) == SUBREG
2513 && GET_CODE (SUBREG_REG (operands[0])) == REG
2514 && REGNO (SUBREG_REG (operands[0])) < 32))))"
2515 [(clobber (const_int 0))]
2517 rtx set_dest = operands[0];
2518 rtx set_src = operands[1];
2522 dest1 = gen_highpart (SImode, set_dest);
2523 dest2 = gen_lowpart (SImode, set_dest);
2524 src1 = gen_highpart (SImode, set_src);
2525 src2 = gen_lowpart (SImode, set_src);
2527 /* Now emit using the real source and destination we found, swapping
2528 the order if we detect overlap. */
2529 if (reg_overlap_mentioned_p (dest1, src2))
2531 emit_insn (gen_movsi (dest2, src2));
2532 emit_insn (gen_movsi (dest1, src1));
2536 emit_insn (gen_movsi (dest1, src1));
2537 emit_insn (gen_movsi (dest2, src2));
2542 ;; Now handle the cases of memory moves from/to non-even
2543 ;; DI mode register pairs.
2545 [(set (match_operand:DI 0 "register_operand" "")
2546 (match_operand:DI 1 "memory_operand" ""))]
2549 && sparc_splitdi_legitimate (operands[0], operands[1]))"
2550 [(clobber (const_int 0))]
2552 rtx word0 = adjust_address (operands[1], SImode, 0);
2553 rtx word1 = adjust_address (operands[1], SImode, 4);
2554 rtx high_part = gen_highpart (SImode, operands[0]);
2555 rtx low_part = gen_lowpart (SImode, operands[0]);
2557 if (reg_overlap_mentioned_p (high_part, word1))
2559 emit_insn (gen_movsi (low_part, word1));
2560 emit_insn (gen_movsi (high_part, word0));
2564 emit_insn (gen_movsi (high_part, word0));
2565 emit_insn (gen_movsi (low_part, word1));
2571 [(set (match_operand:DI 0 "memory_operand" "")
2572 (match_operand:DI 1 "register_operand" ""))]
2575 && sparc_splitdi_legitimate (operands[1], operands[0]))"
2576 [(clobber (const_int 0))]
2578 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0),
2579 gen_highpart (SImode, operands[1])));
2580 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4),
2581 gen_lowpart (SImode, operands[1])));
2586 [(set (match_operand:DI 0 "memory_operand" "")
2591 && ! mem_min_alignment (operands[0], 8)))
2592 && offsettable_memref_p (operands[0])"
2593 [(clobber (const_int 0))]
2595 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0), const0_rtx));
2596 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4), const0_rtx));
2600 ;; Floating point move insns
2602 (define_insn "*movsf_insn_novis"
2603 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,*r,*r,*r,*r,*r,f,m,m")
2604 (match_operand:SF 1 "input_operand" "f,G,Q,*rR,S,m,m,f,*rG"))]
2605 "(TARGET_FPU && ! TARGET_VIS)
2606 && (register_operand (operands[0], SFmode)
2607 || register_operand (operands[1], SFmode)
2608 || fp_zero_operand (operands[1], SFmode))"
2610 if (GET_CODE (operands[1]) == CONST_DOUBLE
2611 && (which_alternative == 2
2612 || which_alternative == 3
2613 || which_alternative == 4))
2618 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2619 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2620 operands[1] = GEN_INT (i);
2623 switch (which_alternative)
2626 return "fmovs\t%1, %0";
2630 return "sethi\t%%hi(%a1), %0";
2632 return "mov\t%1, %0";
2637 return "ld\t%1, %0";
2640 return "st\t%r1, %0";
2645 [(set_attr "type" "fpmove,*,*,*,*,load,fpload,fpstore,store")])
2647 (define_insn "*movsf_insn_vis"
2648 [(set (match_operand:V32 0 "nonimmediate_operand" "=f,f,*r,*r,*r,*r,*r,f,m,m")
2649 (match_operand:V32 1 "input_operand" "f,GY,GY,Q,*rR,S,m,m,f,*rGY"))]
2650 "(TARGET_FPU && TARGET_VIS)
2651 && (register_operand (operands[0], <V32:MODE>mode)
2652 || register_operand (operands[1], <V32:MODE>mode)
2653 || fp_zero_operand (operands[1], <V32:MODE>mode))"
2655 if (GET_CODE (operands[1]) == CONST_DOUBLE
2656 && (which_alternative == 3
2657 || which_alternative == 4
2658 || which_alternative == 5))
2663 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2664 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2665 operands[1] = GEN_INT (i);
2668 switch (which_alternative)
2671 return "fmovs\t%1, %0";
2673 return "fzeros\t%0";
2677 return "sethi\t%%hi(%a1), %0";
2679 return "mov\t%1, %0";
2684 return "ld\t%1, %0";
2687 return "st\t%r1, %0";
2692 [(set_attr "type" "fpmove,fga,*,*,*,*,load,fpload,fpstore,store")])
2694 ;; Exactly the same as above, except that all `f' cases are deleted.
2695 ;; This is necessary to prevent reload from ever trying to use a `f' reg
2698 (define_insn "*movsf_no_f_insn"
2699 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r,r,r,m")
2700 (match_operand:SF 1 "input_operand" "G,Q,rR,S,m,rG"))]
2702 && (register_operand (operands[0], SFmode)
2703 || register_operand (operands[1], SFmode)
2704 || fp_zero_operand (operands[1], SFmode))"
2706 if (GET_CODE (operands[1]) == CONST_DOUBLE
2707 && (which_alternative == 1
2708 || which_alternative == 2
2709 || which_alternative == 3))
2714 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2715 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2716 operands[1] = GEN_INT (i);
2719 switch (which_alternative)
2724 return "sethi\t%%hi(%a1), %0";
2726 return "mov\t%1, %0";
2730 return "ld\t%1, %0";
2732 return "st\t%r1, %0";
2737 [(set_attr "type" "*,*,*,*,load,store")])
2739 ;; The following 3 patterns build SFmode constants in integer registers.
2741 (define_insn "*movsf_lo_sum"
2742 [(set (match_operand:SF 0 "register_operand" "=r")
2743 (lo_sum:SF (match_operand:SF 1 "register_operand" "r")
2744 (match_operand:SF 2 "const_double_operand" "S")))]
2745 "fp_high_losum_p (operands[2])"
2750 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[2]);
2751 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2752 operands[2] = GEN_INT (i);
2753 return "or\t%1, %%lo(%a2), %0";
2756 (define_insn "*movsf_high"
2757 [(set (match_operand:SF 0 "register_operand" "=r")
2758 (high:SF (match_operand:SF 1 "const_double_operand" "S")))]
2759 "fp_high_losum_p (operands[1])"
2764 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2765 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2766 operands[1] = GEN_INT (i);
2767 return "sethi\t%%hi(%1), %0";
2771 [(set (match_operand:SF 0 "register_operand" "")
2772 (match_operand:SF 1 "const_double_operand" ""))]
2773 "fp_high_losum_p (operands[1])
2774 && (GET_CODE (operands[0]) == REG
2775 && REGNO (operands[0]) < 32)"
2776 [(set (match_dup 0) (high:SF (match_dup 1)))
2777 (set (match_dup 0) (lo_sum:SF (match_dup 0) (match_dup 1)))])
2779 ;; Yes, you guessed it right, the former movsf expander.
2780 (define_expand "mov<V32:mode>"
2781 [(set (match_operand:V32 0 "general_operand" "")
2782 (match_operand:V32 1 "general_operand" ""))]
2783 "<V32:MODE>mode == SFmode || TARGET_VIS"
2785 /* Force constants into memory. */
2786 if (GET_CODE (operands[0]) == REG && CONSTANT_P (operands[1]))
2788 /* emit_group_store will send such bogosity to us when it is
2789 not storing directly into memory. So fix this up to avoid
2790 crashes in output_constant_pool. */
2791 if (operands [1] == const0_rtx)
2792 operands[1] = CONST0_RTX (<V32:MODE>mode);
2794 if ((TARGET_VIS || REGNO (operands[0]) < 32)
2795 && fp_zero_operand (operands[1], <V32:MODE>mode))
2798 /* We are able to build any SF constant in integer registers
2799 with at most 2 instructions. */
2800 if (REGNO (operands[0]) < 32
2801 && <V32:MODE>mode == SFmode)
2804 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
2808 /* Handle sets of MEM first. */
2809 if (GET_CODE (operands[0]) == MEM)
2811 if (register_operand (operands[1], <V32:MODE>mode)
2812 || fp_zero_operand (operands[1], <V32:MODE>mode))
2815 if (! reload_in_progress)
2817 operands[0] = validize_mem (operands[0]);
2818 operands[1] = force_reg (<V32:MODE>mode, operands[1]);
2822 /* Fixup PIC cases. */
2825 if (CONSTANT_P (operands[1])
2826 && pic_address_needs_scratch (operands[1]))
2827 operands[1] = legitimize_pic_address (operands[1], <V32:MODE>mode, 0);
2829 if (symbolic_operand (operands[1], <V32:MODE>mode))
2831 operands[1] = legitimize_pic_address (operands[1],
2833 (reload_in_progress ?
2843 ;; Yes, you again guessed it right, the former movdf expander.
2844 (define_expand "mov<V64:mode>"
2845 [(set (match_operand:V64 0 "general_operand" "")
2846 (match_operand:V64 1 "general_operand" ""))]
2847 "<V64:MODE>mode == DFmode || TARGET_VIS"
2849 /* Force constants into memory. */
2850 if (GET_CODE (operands[0]) == REG && CONSTANT_P (operands[1]))
2852 /* emit_group_store will send such bogosity to us when it is
2853 not storing directly into memory. So fix this up to avoid
2854 crashes in output_constant_pool. */
2855 if (operands [1] == const0_rtx)
2856 operands[1] = CONST0_RTX (<V64:MODE>mode);
2858 if ((TARGET_VIS || REGNO (operands[0]) < 32)
2859 && fp_zero_operand (operands[1], <V64:MODE>mode))
2862 /* We are able to build any DF constant in integer registers. */
2863 if (REGNO (operands[0]) < 32
2864 && <V64:MODE>mode == DFmode
2865 && (reload_completed || reload_in_progress))
2868 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
2872 /* Handle MEM cases first. */
2873 if (GET_CODE (operands[0]) == MEM)
2875 if (register_operand (operands[1], <V64:MODE>mode)
2876 || fp_zero_operand (operands[1], <V64:MODE>mode))
2879 if (! reload_in_progress)
2881 operands[0] = validize_mem (operands[0]);
2882 operands[1] = force_reg (<V64:MODE>mode, operands[1]);
2886 /* Fixup PIC cases. */
2889 if (CONSTANT_P (operands[1])
2890 && pic_address_needs_scratch (operands[1]))
2891 operands[1] = legitimize_pic_address (operands[1], <V64:MODE>mode, 0);
2893 if (symbolic_operand (operands[1], <V64:MODE>mode))
2895 operands[1] = legitimize_pic_address (operands[1],
2897 (reload_in_progress ?
2907 ;; Be careful, fmovd does not exist when !v9.
2908 (define_insn "*movdf_insn_sp32"
2909 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,W,U,T,o,e,*r,o,e,o")
2910 (match_operand:DF 1 "input_operand" "W#F,e,T,U,G,e,*rFo,*r,o#F,e"))]
2913 && (register_operand (operands[0], DFmode)
2914 || register_operand (operands[1], DFmode)
2915 || fp_zero_operand (operands[1], DFmode))"
2927 [(set_attr "type" "fpload,fpstore,load,store,*,*,*,*,*,*")
2928 (set_attr "length" "*,*,*,*,2,2,2,2,2,2")])
2930 (define_insn "*movdf_no_e_insn_sp32"
2931 [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,o,r,o")
2932 (match_operand:DF 1 "input_operand" "T,U,G,ro,r"))]
2936 && (register_operand (operands[0], DFmode)
2937 || register_operand (operands[1], DFmode)
2938 || fp_zero_operand (operands[1], DFmode))"
2945 [(set_attr "type" "load,store,*,*,*")
2946 (set_attr "length" "*,*,2,2,2")])
2948 (define_insn "*movdf_no_e_insn_v9_sp32"
2949 [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,T,r,o")
2950 (match_operand:DF 1 "input_operand" "T,U,G,ro,rG"))]
2954 && (register_operand (operands[0], DFmode)
2955 || register_operand (operands[1], DFmode)
2956 || fp_zero_operand (operands[1], DFmode))"
2963 [(set_attr "type" "load,store,store,*,*")
2964 (set_attr "length" "*,*,*,2,2")])
2966 ;; We have available v9 double floats but not 64-bit
2967 ;; integer registers and no VIS.
2968 (define_insn "*movdf_insn_v9only_novis"
2969 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,T,W,U,T,f,*r,o")
2970 (match_operand:DF 1 "input_operand" "e,W#F,G,e,T,U,o#F,*roF,*rGf"))]
2975 && (register_operand (operands[0], DFmode)
2976 || register_operand (operands[1], DFmode)
2977 || fp_zero_operand (operands[1], DFmode))"
2988 [(set_attr "type" "fpmove,load,store,store,load,store,*,*,*")
2989 (set_attr "length" "*,*,*,*,*,*,2,2,2")
2990 (set_attr "fptype" "double,*,*,*,*,*,*,*,*")])
2992 ;; We have available v9 double floats but not 64-bit
2993 ;; integer registers but we have VIS.
2994 (define_insn "*movdf_insn_v9only_vis"
2995 [(set (match_operand:V64 0 "nonimmediate_operand" "=e,e,e,T,W,U,T,f,*r,o")
2996 (match_operand:V64 1 "input_operand" "GY,e,W#F,GY,e,T,U,o#F,*roGYF,*rGYf"))]
3000 && (register_operand (operands[0], <V64:MODE>mode)
3001 || register_operand (operands[1], <V64:MODE>mode)
3002 || fp_zero_operand (operands[1], <V64:MODE>mode))"
3014 [(set_attr "type" "fga,fpmove,load,store,store,load,store,*,*,*")
3015 (set_attr "length" "*,*,*,*,*,*,*,2,2,2")
3016 (set_attr "fptype" "double,double,*,*,*,*,*,*,*,*")])
3018 ;; We have available both v9 double floats and 64-bit
3019 ;; integer registers. No VIS though.
3020 (define_insn "*movdf_insn_sp64_novis"
3021 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,W,*r,*r,m,*r")
3022 (match_operand:DF 1 "input_operand" "e,W#F,e,*rG,m,*rG,F"))]
3026 && (register_operand (operands[0], DFmode)
3027 || register_operand (operands[1], DFmode)
3028 || fp_zero_operand (operands[1], DFmode))"
3037 [(set_attr "type" "fpmove,load,store,*,load,store,*")
3038 (set_attr "length" "*,*,*,*,*,*,2")
3039 (set_attr "fptype" "double,*,*,*,*,*,*")])
3041 ;; We have available both v9 double floats and 64-bit
3042 ;; integer registers. And we have VIS.
3043 (define_insn "*movdf_insn_sp64_vis"
3044 [(set (match_operand:V64 0 "nonimmediate_operand" "=e,e,e,W,*r,*r,m,*r")
3045 (match_operand:V64 1 "input_operand" "GY,e,W#F,e,*rGY,m,*rGY,F"))]
3049 && (register_operand (operands[0], <V64:MODE>mode)
3050 || register_operand (operands[1], <V64:MODE>mode)
3051 || fp_zero_operand (operands[1], <V64:MODE>mode))"
3061 [(set_attr "type" "fga,fpmove,load,store,*,load,store,*")
3062 (set_attr "length" "*,*,*,*,*,*,*,2")
3063 (set_attr "fptype" "double,double,*,*,*,*,*,*")])
3065 (define_insn "*movdf_no_e_insn_sp64"
3066 [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m")
3067 (match_operand:DF 1 "input_operand" "r,m,rG"))]
3070 && (register_operand (operands[0], DFmode)
3071 || register_operand (operands[1], DFmode)
3072 || fp_zero_operand (operands[1], DFmode))"
3077 [(set_attr "type" "*,load,store")])
3079 ;; This pattern build DFmode constants in integer registers.
3081 [(set (match_operand:DF 0 "register_operand" "")
3082 (match_operand:DF 1 "const_double_operand" ""))]
3084 && (GET_CODE (operands[0]) == REG
3085 && REGNO (operands[0]) < 32)
3086 && ! fp_zero_operand(operands[1], DFmode)
3087 && reload_completed"
3088 [(clobber (const_int 0))]
3093 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3094 REAL_VALUE_TO_TARGET_DOUBLE (r, l);
3095 operands[0] = gen_rtx_raw_REG (DImode, REGNO (operands[0]));
3099 #if HOST_BITS_PER_WIDE_INT == 64
3102 val = ((HOST_WIDE_INT)(unsigned long)l[1] |
3103 ((HOST_WIDE_INT)(unsigned long)l[0] << 32));
3104 emit_insn (gen_movdi (operands[0], GEN_INT (val)));
3106 emit_insn (gen_movdi (operands[0],
3107 immed_double_const (l[1], l[0], DImode)));
3112 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
3115 /* Slick... but this trick loses if this subreg constant part
3116 can be done in one insn. */
3118 && !(SPARC_SETHI32_P (l[0])
3119 || SPARC_SIMM13_P (l[0])))
3121 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
3122 gen_highpart (SImode, operands[0])));
3126 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
3133 ;; Ok, now the splits to handle all the multi insn and
3134 ;; mis-aligned memory address cases.
3135 ;; In these splits please take note that we must be
3136 ;; careful when V9 but not ARCH64 because the integer
3137 ;; register DFmode cases must be handled.
3139 [(set (match_operand:V64 0 "register_operand" "")
3140 (match_operand:V64 1 "register_operand" ""))]
3143 && ((GET_CODE (operands[0]) == REG
3144 && REGNO (operands[0]) < 32)
3145 || (GET_CODE (operands[0]) == SUBREG
3146 && GET_CODE (SUBREG_REG (operands[0])) == REG
3147 && REGNO (SUBREG_REG (operands[0])) < 32))))
3148 && reload_completed"
3149 [(clobber (const_int 0))]
3151 rtx set_dest = operands[0];
3152 rtx set_src = operands[1];
3155 enum machine_mode half_mode;
3157 /* We can be expanded for DFmode or integral vector modes. */
3158 if (<V64:MODE>mode == DFmode)
3163 dest1 = gen_highpart (half_mode, set_dest);
3164 dest2 = gen_lowpart (half_mode, set_dest);
3165 src1 = gen_highpart (half_mode, set_src);
3166 src2 = gen_lowpart (half_mode, set_src);
3168 /* Now emit using the real source and destination we found, swapping
3169 the order if we detect overlap. */
3170 if (reg_overlap_mentioned_p (dest1, src2))
3172 emit_move_insn_1 (dest2, src2);
3173 emit_move_insn_1 (dest1, src1);
3177 emit_move_insn_1 (dest1, src1);
3178 emit_move_insn_1 (dest2, src2);
3184 [(set (match_operand:V64 0 "register_operand" "")
3185 (match_operand:V64 1 "memory_operand" ""))]
3188 && (((REGNO (operands[0]) % 2) != 0)
3189 || ! mem_min_alignment (operands[1], 8))
3190 && offsettable_memref_p (operands[1])"
3191 [(clobber (const_int 0))]
3193 enum machine_mode half_mode;
3196 /* We can be expanded for DFmode or integral vector modes. */
3197 if (<V64:MODE>mode == DFmode)
3202 word0 = adjust_address (operands[1], half_mode, 0);
3203 word1 = adjust_address (operands[1], half_mode, 4);
3205 if (reg_overlap_mentioned_p (gen_highpart (half_mode, operands[0]), word1))
3207 emit_move_insn_1 (gen_lowpart (half_mode, operands[0]), word1);
3208 emit_move_insn_1 (gen_highpart (half_mode, operands[0]), word0);
3212 emit_move_insn_1 (gen_highpart (half_mode, operands[0]), word0);
3213 emit_move_insn_1 (gen_lowpart (half_mode, operands[0]), word1);
3219 [(set (match_operand:V64 0 "memory_operand" "")
3220 (match_operand:V64 1 "register_operand" ""))]
3223 && (((REGNO (operands[1]) % 2) != 0)
3224 || ! mem_min_alignment (operands[0], 8))
3225 && offsettable_memref_p (operands[0])"
3226 [(clobber (const_int 0))]
3228 enum machine_mode half_mode;
3231 /* We can be expanded for DFmode or integral vector modes. */
3232 if (<V64:MODE>mode == DFmode)
3237 word0 = adjust_address (operands[0], half_mode, 0);
3238 word1 = adjust_address (operands[0], half_mode, 4);
3240 emit_move_insn_1 (word0, gen_highpart (half_mode, operands[1]));
3241 emit_move_insn_1 (word1, gen_lowpart (half_mode, operands[1]));
3246 [(set (match_operand:V64 0 "memory_operand" "")
3247 (match_operand:V64 1 "fp_zero_operand" ""))]
3251 && ! mem_min_alignment (operands[0], 8)))
3252 && offsettable_memref_p (operands[0])"
3253 [(clobber (const_int 0))]
3255 enum machine_mode half_mode;
3258 /* We can be expanded for DFmode or integral vector modes. */
3259 if (<V64:MODE>mode == DFmode)
3264 dest1 = adjust_address (operands[0], half_mode, 0);
3265 dest2 = adjust_address (operands[0], half_mode, 4);
3267 emit_move_insn_1 (dest1, CONST0_RTX (half_mode));
3268 emit_move_insn_1 (dest2, CONST0_RTX (half_mode));
3273 [(set (match_operand:V64 0 "register_operand" "")
3274 (match_operand:V64 1 "fp_zero_operand" ""))]
3277 && ((GET_CODE (operands[0]) == REG
3278 && REGNO (operands[0]) < 32)
3279 || (GET_CODE (operands[0]) == SUBREG
3280 && GET_CODE (SUBREG_REG (operands[0])) == REG
3281 && REGNO (SUBREG_REG (operands[0])) < 32))"
3282 [(clobber (const_int 0))]
3284 enum machine_mode half_mode;
3285 rtx set_dest = operands[0];
3288 /* We can be expanded for DFmode or integral vector modes. */
3289 if (<V64:MODE>mode == DFmode)
3294 dest1 = gen_highpart (half_mode, set_dest);
3295 dest2 = gen_lowpart (half_mode, set_dest);
3296 emit_move_insn_1 (dest1, CONST0_RTX (half_mode));
3297 emit_move_insn_1 (dest2, CONST0_RTX (half_mode));
3301 (define_expand "movtf"
3302 [(set (match_operand:TF 0 "general_operand" "")
3303 (match_operand:TF 1 "general_operand" ""))]
3306 /* Force TFmode constants into memory. */
3307 if (GET_CODE (operands[0]) == REG
3308 && CONSTANT_P (operands[1]))
3310 /* emit_group_store will send such bogosity to us when it is
3311 not storing directly into memory. So fix this up to avoid
3312 crashes in output_constant_pool. */
3313 if (operands [1] == const0_rtx)
3314 operands[1] = CONST0_RTX (TFmode);
3316 if (TARGET_VIS && fp_zero_operand (operands[1], TFmode))
3319 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
3323 /* Handle MEM cases first, note that only v9 guarantees
3324 full 16-byte alignment for quads. */
3325 if (GET_CODE (operands[0]) == MEM)
3327 if (register_operand (operands[1], TFmode)
3328 || fp_zero_operand (operands[1], TFmode))
3331 if (! reload_in_progress)
3333 operands[0] = validize_mem (operands[0]);
3334 operands[1] = force_reg (TFmode, operands[1]);
3338 /* Fixup PIC cases. */
3341 if (CONSTANT_P (operands[1])
3342 && pic_address_needs_scratch (operands[1]))
3343 operands[1] = legitimize_pic_address (operands[1], TFmode, 0);
3345 if (symbolic_operand (operands[1], TFmode))
3347 operands[1] = legitimize_pic_address (operands[1],
3349 (reload_in_progress ?
3359 ;; Be careful, fmovq and {st,ld}{x,q} do not exist when !arch64 so
3360 ;; we must split them all. :-(
3361 (define_insn "*movtf_insn_sp32"
3362 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,U,r")
3363 (match_operand:TF 1 "input_operand" "oe,GeUr,o,roG"))]
3367 && (register_operand (operands[0], TFmode)
3368 || register_operand (operands[1], TFmode)
3369 || fp_zero_operand (operands[1], TFmode))"
3371 [(set_attr "length" "4")])
3373 (define_insn "*movtf_insn_vis_sp32"
3374 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,U,r")
3375 (match_operand:TF 1 "input_operand" "Goe,GeUr,o,roG"))]
3379 && (register_operand (operands[0], TFmode)
3380 || register_operand (operands[1], TFmode)
3381 || fp_zero_operand (operands[1], TFmode))"
3383 [(set_attr "length" "4")])
3385 ;; Exactly the same as above, except that all `e' cases are deleted.
3386 ;; This is necessary to prevent reload from ever trying to use a `e' reg
3389 (define_insn "*movtf_no_e_insn_sp32"
3390 [(set (match_operand:TF 0 "nonimmediate_operand" "=o,U,o,r,o")
3391 (match_operand:TF 1 "input_operand" "G,o,U,roG,r"))]
3394 && (register_operand (operands[0], TFmode)
3395 || register_operand (operands[1], TFmode)
3396 || fp_zero_operand (operands[1], TFmode))"
3398 [(set_attr "length" "4")])
3400 ;; Now handle the float reg cases directly when arch64,
3401 ;; hard_quad, and proper reg number alignment are all true.
3402 (define_insn "*movtf_insn_hq_sp64"
3403 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,e,m,o,r")
3404 (match_operand:TF 1 "input_operand" "e,m,e,Gr,roG"))]
3409 && (register_operand (operands[0], TFmode)
3410 || register_operand (operands[1], TFmode)
3411 || fp_zero_operand (operands[1], TFmode))"
3418 [(set_attr "type" "fpmove,fpload,fpstore,*,*")
3419 (set_attr "length" "*,*,*,2,2")])
3421 (define_insn "*movtf_insn_hq_vis_sp64"
3422 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,e,m,eo,r,o")
3423 (match_operand:TF 1 "input_operand" "e,m,e,G,roG,r"))]
3428 && (register_operand (operands[0], TFmode)
3429 || register_operand (operands[1], TFmode)
3430 || fp_zero_operand (operands[1], TFmode))"
3438 [(set_attr "type" "fpmove,fpload,fpstore,*,*,*")
3439 (set_attr "length" "*,*,*,2,2,2")])
3441 ;; Now we allow the integer register cases even when
3442 ;; only arch64 is true.
3443 (define_insn "*movtf_insn_sp64"
3444 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,r")
3445 (match_operand:TF 1 "input_operand" "oe,Ger,orG"))]
3449 && ! TARGET_HARD_QUAD
3450 && (register_operand (operands[0], TFmode)
3451 || register_operand (operands[1], TFmode)
3452 || fp_zero_operand (operands[1], TFmode))"
3454 [(set_attr "length" "2")])
3456 (define_insn "*movtf_insn_vis_sp64"
3457 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,r")
3458 (match_operand:TF 1 "input_operand" "Goe,Ger,orG"))]
3462 && ! TARGET_HARD_QUAD
3463 && (register_operand (operands[0], TFmode)
3464 || register_operand (operands[1], TFmode)
3465 || fp_zero_operand (operands[1], TFmode))"
3467 [(set_attr "length" "2")])
3469 (define_insn "*movtf_no_e_insn_sp64"
3470 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o")
3471 (match_operand:TF 1 "input_operand" "orG,rG"))]
3474 && (register_operand (operands[0], TFmode)
3475 || register_operand (operands[1], TFmode)
3476 || fp_zero_operand (operands[1], TFmode))"
3478 [(set_attr "length" "2")])
3480 ;; Now all the splits to handle multi-insn TF mode moves.
3482 [(set (match_operand:TF 0 "register_operand" "")
3483 (match_operand:TF 1 "register_operand" ""))]
3487 && ! TARGET_HARD_QUAD)
3488 || ! fp_register_operand (operands[0], TFmode))"
3489 [(clobber (const_int 0))]
3491 rtx set_dest = operands[0];
3492 rtx set_src = operands[1];
3496 dest1 = gen_df_reg (set_dest, 0);
3497 dest2 = gen_df_reg (set_dest, 1);
3498 src1 = gen_df_reg (set_src, 0);
3499 src2 = gen_df_reg (set_src, 1);
3501 /* Now emit using the real source and destination we found, swapping
3502 the order if we detect overlap. */
3503 if (reg_overlap_mentioned_p (dest1, src2))
3505 emit_insn (gen_movdf (dest2, src2));
3506 emit_insn (gen_movdf (dest1, src1));
3510 emit_insn (gen_movdf (dest1, src1));
3511 emit_insn (gen_movdf (dest2, src2));
3517 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3518 (match_operand:TF 1 "fp_zero_operand" ""))]
3520 [(clobber (const_int 0))]
3522 rtx set_dest = operands[0];
3525 switch (GET_CODE (set_dest))
3528 dest1 = gen_df_reg (set_dest, 0);
3529 dest2 = gen_df_reg (set_dest, 1);
3532 dest1 = adjust_address (set_dest, DFmode, 0);
3533 dest2 = adjust_address (set_dest, DFmode, 8);
3539 emit_insn (gen_movdf (dest1, CONST0_RTX (DFmode)));
3540 emit_insn (gen_movdf (dest2, CONST0_RTX (DFmode)));
3545 [(set (match_operand:TF 0 "register_operand" "")
3546 (match_operand:TF 1 "memory_operand" ""))]
3548 && offsettable_memref_p (operands[1])
3550 || ! TARGET_HARD_QUAD
3551 || ! fp_register_operand (operands[0], TFmode)))"
3552 [(clobber (const_int 0))]
3554 rtx word0 = adjust_address (operands[1], DFmode, 0);
3555 rtx word1 = adjust_address (operands[1], DFmode, 8);
3556 rtx set_dest, dest1, dest2;
3558 set_dest = operands[0];
3560 dest1 = gen_df_reg (set_dest, 0);
3561 dest2 = gen_df_reg (set_dest, 1);
3563 /* Now output, ordering such that we don't clobber any registers
3564 mentioned in the address. */
3565 if (reg_overlap_mentioned_p (dest1, word1))
3568 emit_insn (gen_movdf (dest2, word1));
3569 emit_insn (gen_movdf (dest1, word0));
3573 emit_insn (gen_movdf (dest1, word0));
3574 emit_insn (gen_movdf (dest2, word1));
3580 [(set (match_operand:TF 0 "memory_operand" "")
3581 (match_operand:TF 1 "register_operand" ""))]
3583 && offsettable_memref_p (operands[0])
3585 || ! TARGET_HARD_QUAD
3586 || ! fp_register_operand (operands[1], TFmode)))"
3587 [(clobber (const_int 0))]
3589 rtx set_src = operands[1];
3591 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 0),
3592 gen_df_reg (set_src, 0)));
3593 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 8),
3594 gen_df_reg (set_src, 1)));
3598 ;; SPARC V9 conditional move instructions.
3600 ;; We can handle larger constants here for some flavors, but for now we keep
3601 ;; it simple and only allow those constants supported by all flavors.
3602 ;; Note that emit_conditional_move canonicalizes operands 2,3 so that operand
3603 ;; 3 contains the constant if one is present, but we handle either for
3604 ;; generality (sparc.c puts a constant in operand 2).
3606 (define_expand "movqicc"
3607 [(set (match_operand:QI 0 "register_operand" "")
3608 (if_then_else:QI (match_operand 1 "comparison_operator" "")
3609 (match_operand:QI 2 "arith10_operand" "")
3610 (match_operand:QI 3 "arith10_operand" "")))]
3613 enum rtx_code code = GET_CODE (operands[1]);
3615 if (GET_MODE (sparc_compare_op0) == DImode
3619 if (sparc_compare_op1 == const0_rtx
3620 && GET_CODE (sparc_compare_op0) == REG
3621 && GET_MODE (sparc_compare_op0) == DImode
3622 && v9_regcmp_p (code))
3624 operands[1] = gen_rtx_fmt_ee (code, DImode,
3625 sparc_compare_op0, sparc_compare_op1);
3629 rtx cc_reg = gen_compare_reg (code,
3630 sparc_compare_op0, sparc_compare_op1);
3631 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3635 (define_expand "movhicc"
3636 [(set (match_operand:HI 0 "register_operand" "")
3637 (if_then_else:HI (match_operand 1 "comparison_operator" "")
3638 (match_operand:HI 2 "arith10_operand" "")
3639 (match_operand:HI 3 "arith10_operand" "")))]
3642 enum rtx_code code = GET_CODE (operands[1]);
3644 if (GET_MODE (sparc_compare_op0) == DImode
3648 if (sparc_compare_op1 == const0_rtx
3649 && GET_CODE (sparc_compare_op0) == REG
3650 && GET_MODE (sparc_compare_op0) == DImode
3651 && v9_regcmp_p (code))
3653 operands[1] = gen_rtx_fmt_ee (code, DImode,
3654 sparc_compare_op0, sparc_compare_op1);
3658 rtx cc_reg = gen_compare_reg (code,
3659 sparc_compare_op0, sparc_compare_op1);
3660 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3664 (define_expand "movsicc"
3665 [(set (match_operand:SI 0 "register_operand" "")
3666 (if_then_else:SI (match_operand 1 "comparison_operator" "")
3667 (match_operand:SI 2 "arith10_operand" "")
3668 (match_operand:SI 3 "arith10_operand" "")))]
3671 enum rtx_code code = GET_CODE (operands[1]);
3672 enum machine_mode op0_mode = GET_MODE (sparc_compare_op0);
3674 if (sparc_compare_op1 == const0_rtx
3675 && GET_CODE (sparc_compare_op0) == REG
3676 && (TARGET_ARCH64 && op0_mode == DImode && v9_regcmp_p (code)))
3678 operands[1] = gen_rtx_fmt_ee (code, op0_mode,
3679 sparc_compare_op0, sparc_compare_op1);
3683 rtx cc_reg = gen_compare_reg (code,
3684 sparc_compare_op0, sparc_compare_op1);
3685 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg),
3686 cc_reg, const0_rtx);
3690 (define_expand "movdicc"
3691 [(set (match_operand:DI 0 "register_operand" "")
3692 (if_then_else:DI (match_operand 1 "comparison_operator" "")
3693 (match_operand:DI 2 "arith10_double_operand" "")
3694 (match_operand:DI 3 "arith10_double_operand" "")))]
3697 enum rtx_code code = GET_CODE (operands[1]);
3699 if (sparc_compare_op1 == const0_rtx
3700 && GET_CODE (sparc_compare_op0) == REG
3701 && GET_MODE (sparc_compare_op0) == DImode
3702 && v9_regcmp_p (code))
3704 operands[1] = gen_rtx_fmt_ee (code, DImode,
3705 sparc_compare_op0, sparc_compare_op1);
3709 rtx cc_reg = gen_compare_reg (code,
3710 sparc_compare_op0, sparc_compare_op1);
3711 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg),
3712 cc_reg, const0_rtx);
3716 (define_expand "movsfcc"
3717 [(set (match_operand:SF 0 "register_operand" "")
3718 (if_then_else:SF (match_operand 1 "comparison_operator" "")
3719 (match_operand:SF 2 "register_operand" "")
3720 (match_operand:SF 3 "register_operand" "")))]
3721 "TARGET_V9 && TARGET_FPU"
3723 enum rtx_code code = GET_CODE (operands[1]);
3725 if (GET_MODE (sparc_compare_op0) == DImode
3729 if (sparc_compare_op1 == const0_rtx
3730 && GET_CODE (sparc_compare_op0) == REG
3731 && GET_MODE (sparc_compare_op0) == DImode
3732 && v9_regcmp_p (code))
3734 operands[1] = gen_rtx_fmt_ee (code, DImode,
3735 sparc_compare_op0, sparc_compare_op1);
3739 rtx cc_reg = gen_compare_reg (code,
3740 sparc_compare_op0, sparc_compare_op1);
3741 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3745 (define_expand "movdfcc"
3746 [(set (match_operand:DF 0 "register_operand" "")
3747 (if_then_else:DF (match_operand 1 "comparison_operator" "")
3748 (match_operand:DF 2 "register_operand" "")
3749 (match_operand:DF 3 "register_operand" "")))]
3750 "TARGET_V9 && TARGET_FPU"
3752 enum rtx_code code = GET_CODE (operands[1]);
3754 if (GET_MODE (sparc_compare_op0) == DImode
3758 if (sparc_compare_op1 == const0_rtx
3759 && GET_CODE (sparc_compare_op0) == REG
3760 && GET_MODE (sparc_compare_op0) == DImode
3761 && v9_regcmp_p (code))
3763 operands[1] = gen_rtx_fmt_ee (code, DImode,
3764 sparc_compare_op0, sparc_compare_op1);
3768 rtx cc_reg = gen_compare_reg (code,
3769 sparc_compare_op0, sparc_compare_op1);
3770 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3774 (define_expand "movtfcc"
3775 [(set (match_operand:TF 0 "register_operand" "")
3776 (if_then_else:TF (match_operand 1 "comparison_operator" "")
3777 (match_operand:TF 2 "register_operand" "")
3778 (match_operand:TF 3 "register_operand" "")))]
3779 "TARGET_V9 && TARGET_FPU"
3781 enum rtx_code code = GET_CODE (operands[1]);
3783 if (GET_MODE (sparc_compare_op0) == DImode
3787 if (sparc_compare_op1 == const0_rtx
3788 && GET_CODE (sparc_compare_op0) == REG
3789 && GET_MODE (sparc_compare_op0) == DImode
3790 && v9_regcmp_p (code))
3792 operands[1] = gen_rtx_fmt_ee (code, DImode,
3793 sparc_compare_op0, sparc_compare_op1);
3797 rtx cc_reg = gen_compare_reg (code,
3798 sparc_compare_op0, sparc_compare_op1);
3799 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3803 ;; Conditional move define_insns.
3805 (define_insn "*movqi_cc_sp64"
3806 [(set (match_operand:QI 0 "register_operand" "=r,r")
3807 (if_then_else:QI (match_operator 1 "comparison_operator"
3808 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3810 (match_operand:QI 3 "arith11_operand" "rL,0")
3811 (match_operand:QI 4 "arith11_operand" "0,rL")))]
3815 mov%c1\t%x2, %4, %0"
3816 [(set_attr "type" "cmove")])
3818 (define_insn "*movhi_cc_sp64"
3819 [(set (match_operand:HI 0 "register_operand" "=r,r")
3820 (if_then_else:HI (match_operator 1 "comparison_operator"
3821 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3823 (match_operand:HI 3 "arith11_operand" "rL,0")
3824 (match_operand:HI 4 "arith11_operand" "0,rL")))]
3828 mov%c1\t%x2, %4, %0"
3829 [(set_attr "type" "cmove")])
3831 (define_insn "*movsi_cc_sp64"
3832 [(set (match_operand:SI 0 "register_operand" "=r,r")
3833 (if_then_else:SI (match_operator 1 "comparison_operator"
3834 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3836 (match_operand:SI 3 "arith11_operand" "rL,0")
3837 (match_operand:SI 4 "arith11_operand" "0,rL")))]
3841 mov%c1\t%x2, %4, %0"
3842 [(set_attr "type" "cmove")])
3844 ;; ??? The constraints of operands 3,4 need work.
3845 (define_insn "*movdi_cc_sp64"
3846 [(set (match_operand:DI 0 "register_operand" "=r,r")
3847 (if_then_else:DI (match_operator 1 "comparison_operator"
3848 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3850 (match_operand:DI 3 "arith11_double_operand" "rLH,0")
3851 (match_operand:DI 4 "arith11_double_operand" "0,rLH")))]
3855 mov%c1\t%x2, %4, %0"
3856 [(set_attr "type" "cmove")])
3858 (define_insn "*movdi_cc_sp64_trunc"
3859 [(set (match_operand:SI 0 "register_operand" "=r,r")
3860 (if_then_else:SI (match_operator 1 "comparison_operator"
3861 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3863 (match_operand:SI 3 "arith11_double_operand" "rLH,0")
3864 (match_operand:SI 4 "arith11_double_operand" "0,rLH")))]
3868 mov%c1\t%x2, %4, %0"
3869 [(set_attr "type" "cmove")])
3871 (define_insn "*movsf_cc_sp64"
3872 [(set (match_operand:SF 0 "register_operand" "=f,f")
3873 (if_then_else:SF (match_operator 1 "comparison_operator"
3874 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3876 (match_operand:SF 3 "register_operand" "f,0")
3877 (match_operand:SF 4 "register_operand" "0,f")))]
3878 "TARGET_V9 && TARGET_FPU"
3880 fmovs%C1\t%x2, %3, %0
3881 fmovs%c1\t%x2, %4, %0"
3882 [(set_attr "type" "fpcmove")])
3884 (define_insn "movdf_cc_sp64"
3885 [(set (match_operand:DF 0 "register_operand" "=e,e")
3886 (if_then_else:DF (match_operator 1 "comparison_operator"
3887 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3889 (match_operand:DF 3 "register_operand" "e,0")
3890 (match_operand:DF 4 "register_operand" "0,e")))]
3891 "TARGET_V9 && TARGET_FPU"
3893 fmovd%C1\t%x2, %3, %0
3894 fmovd%c1\t%x2, %4, %0"
3895 [(set_attr "type" "fpcmove")
3896 (set_attr "fptype" "double")])
3898 (define_insn "*movtf_cc_hq_sp64"
3899 [(set (match_operand:TF 0 "register_operand" "=e,e")
3900 (if_then_else:TF (match_operator 1 "comparison_operator"
3901 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3903 (match_operand:TF 3 "register_operand" "e,0")
3904 (match_operand:TF 4 "register_operand" "0,e")))]
3905 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
3907 fmovq%C1\t%x2, %3, %0
3908 fmovq%c1\t%x2, %4, %0"
3909 [(set_attr "type" "fpcmove")])
3911 (define_insn_and_split "*movtf_cc_sp64"
3912 [(set (match_operand:TF 0 "register_operand" "=e,e")
3913 (if_then_else:TF (match_operator 1 "comparison_operator"
3914 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3916 (match_operand:TF 3 "register_operand" "e,0")
3917 (match_operand:TF 4 "register_operand" "0,e")))]
3918 "TARGET_V9 && TARGET_FPU && !TARGET_HARD_QUAD"
3920 "&& reload_completed"
3921 [(clobber (const_int 0))]
3923 rtx set_dest = operands[0];
3924 rtx set_srca = operands[3];
3925 rtx set_srcb = operands[4];
3926 int third = rtx_equal_p (set_dest, set_srca);
3928 rtx srca1, srca2, srcb1, srcb2;
3930 dest1 = gen_df_reg (set_dest, 0);
3931 dest2 = gen_df_reg (set_dest, 1);
3932 srca1 = gen_df_reg (set_srca, 0);
3933 srca2 = gen_df_reg (set_srca, 1);
3934 srcb1 = gen_df_reg (set_srcb, 0);
3935 srcb2 = gen_df_reg (set_srcb, 1);
3937 /* Now emit using the real source and destination we found, swapping
3938 the order if we detect overlap. */
3939 if ((third && reg_overlap_mentioned_p (dest1, srcb2))
3940 || (!third && reg_overlap_mentioned_p (dest1, srca2)))
3942 emit_insn (gen_movdf_cc_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
3943 emit_insn (gen_movdf_cc_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
3947 emit_insn (gen_movdf_cc_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
3948 emit_insn (gen_movdf_cc_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
3952 [(set_attr "length" "2")])
3954 (define_insn "*movqi_cc_reg_sp64"
3955 [(set (match_operand:QI 0 "register_operand" "=r,r")
3956 (if_then_else:QI (match_operator 1 "v9_regcmp_op"
3957 [(match_operand:DI 2 "register_operand" "r,r")
3959 (match_operand:QI 3 "arith10_operand" "rM,0")
3960 (match_operand:QI 4 "arith10_operand" "0,rM")))]
3963 movr%D1\t%2, %r3, %0
3964 movr%d1\t%2, %r4, %0"
3965 [(set_attr "type" "cmove")])
3967 (define_insn "*movhi_cc_reg_sp64"
3968 [(set (match_operand:HI 0 "register_operand" "=r,r")
3969 (if_then_else:HI (match_operator 1 "v9_regcmp_op"
3970 [(match_operand:DI 2 "register_operand" "r,r")
3972 (match_operand:HI 3 "arith10_operand" "rM,0")
3973 (match_operand:HI 4 "arith10_operand" "0,rM")))]
3976 movr%D1\t%2, %r3, %0
3977 movr%d1\t%2, %r4, %0"
3978 [(set_attr "type" "cmove")])
3980 (define_insn "*movsi_cc_reg_sp64"
3981 [(set (match_operand:SI 0 "register_operand" "=r,r")
3982 (if_then_else:SI (match_operator 1 "v9_regcmp_op"
3983 [(match_operand:DI 2 "register_operand" "r,r")
3985 (match_operand:SI 3 "arith10_operand" "rM,0")
3986 (match_operand:SI 4 "arith10_operand" "0,rM")))]
3989 movr%D1\t%2, %r3, %0
3990 movr%d1\t%2, %r4, %0"
3991 [(set_attr "type" "cmove")])
3993 ;; ??? The constraints of operands 3,4 need work.
3994 (define_insn "*movdi_cc_reg_sp64"
3995 [(set (match_operand:DI 0 "register_operand" "=r,r")
3996 (if_then_else:DI (match_operator 1 "v9_regcmp_op"
3997 [(match_operand:DI 2 "register_operand" "r,r")
3999 (match_operand:DI 3 "arith10_double_operand" "rMH,0")
4000 (match_operand:DI 4 "arith10_double_operand" "0,rMH")))]
4003 movr%D1\t%2, %r3, %0
4004 movr%d1\t%2, %r4, %0"
4005 [(set_attr "type" "cmove")])
4007 (define_insn "*movdi_cc_reg_sp64_trunc"
4008 [(set (match_operand:SI 0 "register_operand" "=r,r")
4009 (if_then_else:SI (match_operator 1 "v9_regcmp_op"
4010 [(match_operand:DI 2 "register_operand" "r,r")
4012 (match_operand:SI 3 "arith10_double_operand" "rMH,0")
4013 (match_operand:SI 4 "arith10_double_operand" "0,rMH")))]
4016 movr%D1\t%2, %r3, %0
4017 movr%d1\t%2, %r4, %0"
4018 [(set_attr "type" "cmove")])
4020 (define_insn "*movsf_cc_reg_sp64"
4021 [(set (match_operand:SF 0 "register_operand" "=f,f")
4022 (if_then_else:SF (match_operator 1 "v9_regcmp_op"
4023 [(match_operand:DI 2 "register_operand" "r,r")
4025 (match_operand:SF 3 "register_operand" "f,0")
4026 (match_operand:SF 4 "register_operand" "0,f")))]
4027 "TARGET_ARCH64 && TARGET_FPU"
4029 fmovrs%D1\t%2, %3, %0
4030 fmovrs%d1\t%2, %4, %0"
4031 [(set_attr "type" "fpcrmove")])
4033 (define_insn "movdf_cc_reg_sp64"
4034 [(set (match_operand:DF 0 "register_operand" "=e,e")
4035 (if_then_else:DF (match_operator 1 "v9_regcmp_op"
4036 [(match_operand:DI 2 "register_operand" "r,r")
4038 (match_operand:DF 3 "register_operand" "e,0")
4039 (match_operand:DF 4 "register_operand" "0,e")))]
4040 "TARGET_ARCH64 && TARGET_FPU"
4042 fmovrd%D1\t%2, %3, %0
4043 fmovrd%d1\t%2, %4, %0"
4044 [(set_attr "type" "fpcrmove")
4045 (set_attr "fptype" "double")])
4047 (define_insn "*movtf_cc_reg_hq_sp64"
4048 [(set (match_operand:TF 0 "register_operand" "=e,e")
4049 (if_then_else:TF (match_operator 1 "v9_regcmp_op"
4050 [(match_operand:DI 2 "register_operand" "r,r")
4052 (match_operand:TF 3 "register_operand" "e,0")
4053 (match_operand:TF 4 "register_operand" "0,e")))]
4054 "TARGET_ARCH64 && TARGET_FPU && TARGET_HARD_QUAD"
4056 fmovrq%D1\t%2, %3, %0
4057 fmovrq%d1\t%2, %4, %0"
4058 [(set_attr "type" "fpcrmove")])
4060 (define_insn_and_split "*movtf_cc_reg_sp64"
4061 [(set (match_operand:TF 0 "register_operand" "=e,e")
4062 (if_then_else:TF (match_operator 1 "v9_regcmp_op"
4063 [(match_operand:DI 2 "register_operand" "r,r")
4065 (match_operand:TF 3 "register_operand" "e,0")
4066 (match_operand:TF 4 "register_operand" "0,e")))]
4067 "TARGET_ARCH64 && TARGET_FPU && ! TARGET_HARD_QUAD"
4069 "&& reload_completed"
4070 [(clobber (const_int 0))]
4072 rtx set_dest = operands[0];
4073 rtx set_srca = operands[3];
4074 rtx set_srcb = operands[4];
4075 int third = rtx_equal_p (set_dest, set_srca);
4077 rtx srca1, srca2, srcb1, srcb2;
4079 dest1 = gen_df_reg (set_dest, 0);
4080 dest2 = gen_df_reg (set_dest, 1);
4081 srca1 = gen_df_reg (set_srca, 0);
4082 srca2 = gen_df_reg (set_srca, 1);
4083 srcb1 = gen_df_reg (set_srcb, 0);
4084 srcb2 = gen_df_reg (set_srcb, 1);
4086 /* Now emit using the real source and destination we found, swapping
4087 the order if we detect overlap. */
4088 if ((third && reg_overlap_mentioned_p (dest1, srcb2))
4089 || (!third && reg_overlap_mentioned_p (dest1, srca2)))
4091 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
4092 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
4096 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
4097 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
4101 [(set_attr "length" "2")])
4104 ;;- zero extension instructions
4106 ;; These patterns originally accepted general_operands, however, slightly
4107 ;; better code is generated by only accepting register_operands, and then
4108 ;; letting combine generate the ldu[hb] insns.
4110 (define_expand "zero_extendhisi2"
4111 [(set (match_operand:SI 0 "register_operand" "")
4112 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
4115 rtx temp = gen_reg_rtx (SImode);
4116 rtx shift_16 = GEN_INT (16);
4117 int op1_subbyte = 0;
4119 if (GET_CODE (operand1) == SUBREG)
4121 op1_subbyte = SUBREG_BYTE (operand1);
4122 op1_subbyte /= GET_MODE_SIZE (SImode);
4123 op1_subbyte *= GET_MODE_SIZE (SImode);
4124 operand1 = XEXP (operand1, 0);
4127 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4129 emit_insn (gen_lshrsi3 (operand0, temp, shift_16));
4133 (define_insn "*zero_extendhisi2_insn"
4134 [(set (match_operand:SI 0 "register_operand" "=r")
4135 (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
4138 [(set_attr "type" "load")
4139 (set_attr "us3load_type" "3cycle")])
4141 (define_expand "zero_extendqihi2"
4142 [(set (match_operand:HI 0 "register_operand" "")
4143 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
4147 (define_insn "*zero_extendqihi2_insn"
4148 [(set (match_operand:HI 0 "register_operand" "=r,r")
4149 (zero_extend:HI (match_operand:QI 1 "input_operand" "r,m")))]
4150 "GET_CODE (operands[1]) != CONST_INT"
4154 [(set_attr "type" "*,load")
4155 (set_attr "us3load_type" "*,3cycle")])
4157 (define_expand "zero_extendqisi2"
4158 [(set (match_operand:SI 0 "register_operand" "")
4159 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
4163 (define_insn "*zero_extendqisi2_insn"
4164 [(set (match_operand:SI 0 "register_operand" "=r,r")
4165 (zero_extend:SI (match_operand:QI 1 "input_operand" "r,m")))]
4166 "GET_CODE (operands[1]) != CONST_INT"
4170 [(set_attr "type" "*,load")
4171 (set_attr "us3load_type" "*,3cycle")])
4173 (define_expand "zero_extendqidi2"
4174 [(set (match_operand:DI 0 "register_operand" "")
4175 (zero_extend:DI (match_operand:QI 1 "register_operand" "")))]
4179 (define_insn "*zero_extendqidi2_insn"
4180 [(set (match_operand:DI 0 "register_operand" "=r,r")
4181 (zero_extend:DI (match_operand:QI 1 "input_operand" "r,m")))]
4182 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
4186 [(set_attr "type" "*,load")
4187 (set_attr "us3load_type" "*,3cycle")])
4189 (define_expand "zero_extendhidi2"
4190 [(set (match_operand:DI 0 "register_operand" "")
4191 (zero_extend:DI (match_operand:HI 1 "register_operand" "")))]
4194 rtx temp = gen_reg_rtx (DImode);
4195 rtx shift_48 = GEN_INT (48);
4196 int op1_subbyte = 0;
4198 if (GET_CODE (operand1) == SUBREG)
4200 op1_subbyte = SUBREG_BYTE (operand1);
4201 op1_subbyte /= GET_MODE_SIZE (DImode);
4202 op1_subbyte *= GET_MODE_SIZE (DImode);
4203 operand1 = XEXP (operand1, 0);
4206 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
4208 emit_insn (gen_lshrdi3 (operand0, temp, shift_48));
4212 (define_insn "*zero_extendhidi2_insn"
4213 [(set (match_operand:DI 0 "register_operand" "=r")
4214 (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
4217 [(set_attr "type" "load")
4218 (set_attr "us3load_type" "3cycle")])
4221 ;; ??? Write truncdisi pattern using sra?
4223 (define_expand "zero_extendsidi2"
4224 [(set (match_operand:DI 0 "register_operand" "")
4225 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
4229 (define_insn "*zero_extendsidi2_insn_sp64"
4230 [(set (match_operand:DI 0 "register_operand" "=r,r")
4231 (zero_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
4232 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
4236 [(set_attr "type" "shift,load")])
4238 (define_insn_and_split "*zero_extendsidi2_insn_sp32"
4239 [(set (match_operand:DI 0 "register_operand" "=r")
4240 (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
4243 "&& reload_completed"
4244 [(set (match_dup 2) (match_dup 3))
4245 (set (match_dup 4) (match_dup 5))]
4249 dest1 = gen_highpart (SImode, operands[0]);
4250 dest2 = gen_lowpart (SImode, operands[0]);
4252 /* Swap the order in case of overlap. */
4253 if (REGNO (dest1) == REGNO (operands[1]))
4255 operands[2] = dest2;
4256 operands[3] = operands[1];
4257 operands[4] = dest1;
4258 operands[5] = const0_rtx;
4262 operands[2] = dest1;
4263 operands[3] = const0_rtx;
4264 operands[4] = dest2;
4265 operands[5] = operands[1];
4268 [(set_attr "length" "2")])
4270 ;; Simplify comparisons of extended values.
4272 (define_insn "*cmp_zero_extendqisi2"
4274 (compare:CC (zero_extend:SI (match_operand:QI 0 "register_operand" "r"))
4277 "andcc\t%0, 0xff, %%g0"
4278 [(set_attr "type" "compare")])
4280 (define_insn "*cmp_zero_qi"
4282 (compare:CC (match_operand:QI 0 "register_operand" "r")
4285 "andcc\t%0, 0xff, %%g0"
4286 [(set_attr "type" "compare")])
4288 (define_insn "*cmp_zero_extendqisi2_set"
4290 (compare:CC (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
4292 (set (match_operand:SI 0 "register_operand" "=r")
4293 (zero_extend:SI (match_dup 1)))]
4295 "andcc\t%1, 0xff, %0"
4296 [(set_attr "type" "compare")])
4298 (define_insn "*cmp_zero_extendqisi2_andcc_set"
4300 (compare:CC (and:SI (match_operand:SI 1 "register_operand" "r")
4303 (set (match_operand:SI 0 "register_operand" "=r")
4304 (zero_extend:SI (subreg:QI (match_dup 1) 0)))]
4306 "andcc\t%1, 0xff, %0"
4307 [(set_attr "type" "compare")])
4309 (define_insn "*cmp_zero_extendqidi2"
4311 (compare:CCX (zero_extend:DI (match_operand:QI 0 "register_operand" "r"))
4314 "andcc\t%0, 0xff, %%g0"
4315 [(set_attr "type" "compare")])
4317 (define_insn "*cmp_zero_qi_sp64"
4319 (compare:CCX (match_operand:QI 0 "register_operand" "r")
4322 "andcc\t%0, 0xff, %%g0"
4323 [(set_attr "type" "compare")])
4325 (define_insn "*cmp_zero_extendqidi2_set"
4327 (compare:CCX (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
4329 (set (match_operand:DI 0 "register_operand" "=r")
4330 (zero_extend:DI (match_dup 1)))]
4332 "andcc\t%1, 0xff, %0"
4333 [(set_attr "type" "compare")])
4335 (define_insn "*cmp_zero_extendqidi2_andcc_set"
4337 (compare:CCX (and:DI (match_operand:DI 1 "register_operand" "r")
4340 (set (match_operand:DI 0 "register_operand" "=r")
4341 (zero_extend:DI (subreg:QI (match_dup 1) 0)))]
4343 "andcc\t%1, 0xff, %0"
4344 [(set_attr "type" "compare")])
4346 ;; Similarly, handle {SI,DI}->QI mode truncation followed by a compare.
4348 (define_insn "*cmp_siqi_trunc"
4350 (compare:CC (subreg:QI (match_operand:SI 0 "register_operand" "r") 3)
4353 "andcc\t%0, 0xff, %%g0"
4354 [(set_attr "type" "compare")])
4356 (define_insn "*cmp_siqi_trunc_set"
4358 (compare:CC (subreg:QI (match_operand:SI 1 "register_operand" "r") 3)
4360 (set (match_operand:QI 0 "register_operand" "=r")
4361 (subreg:QI (match_dup 1) 3))]
4363 "andcc\t%1, 0xff, %0"
4364 [(set_attr "type" "compare")])
4366 (define_insn "*cmp_diqi_trunc"
4368 (compare:CC (subreg:QI (match_operand:DI 0 "register_operand" "r") 7)
4371 "andcc\t%0, 0xff, %%g0"
4372 [(set_attr "type" "compare")])
4374 (define_insn "*cmp_diqi_trunc_set"
4376 (compare:CC (subreg:QI (match_operand:DI 1 "register_operand" "r") 7)
4378 (set (match_operand:QI 0 "register_operand" "=r")
4379 (subreg:QI (match_dup 1) 7))]
4381 "andcc\t%1, 0xff, %0"
4382 [(set_attr "type" "compare")])
4384 ;;- sign extension instructions
4386 ;; These patterns originally accepted general_operands, however, slightly
4387 ;; better code is generated by only accepting register_operands, and then
4388 ;; letting combine generate the lds[hb] insns.
4390 (define_expand "extendhisi2"
4391 [(set (match_operand:SI 0 "register_operand" "")
4392 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
4395 rtx temp = gen_reg_rtx (SImode);
4396 rtx shift_16 = GEN_INT (16);
4397 int op1_subbyte = 0;
4399 if (GET_CODE (operand1) == SUBREG)
4401 op1_subbyte = SUBREG_BYTE (operand1);
4402 op1_subbyte /= GET_MODE_SIZE (SImode);
4403 op1_subbyte *= GET_MODE_SIZE (SImode);
4404 operand1 = XEXP (operand1, 0);
4407 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4409 emit_insn (gen_ashrsi3 (operand0, temp, shift_16));
4413 (define_insn "*sign_extendhisi2_insn"
4414 [(set (match_operand:SI 0 "register_operand" "=r")
4415 (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
4418 [(set_attr "type" "sload")
4419 (set_attr "us3load_type" "3cycle")])
4421 (define_expand "extendqihi2"
4422 [(set (match_operand:HI 0 "register_operand" "")
4423 (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
4426 rtx temp = gen_reg_rtx (SImode);
4427 rtx shift_24 = GEN_INT (24);
4428 int op1_subbyte = 0;
4429 int op0_subbyte = 0;
4431 if (GET_CODE (operand1) == SUBREG)
4433 op1_subbyte = SUBREG_BYTE (operand1);
4434 op1_subbyte /= GET_MODE_SIZE (SImode);
4435 op1_subbyte *= GET_MODE_SIZE (SImode);
4436 operand1 = XEXP (operand1, 0);
4438 if (GET_CODE (operand0) == SUBREG)
4440 op0_subbyte = SUBREG_BYTE (operand0);
4441 op0_subbyte /= GET_MODE_SIZE (SImode);
4442 op0_subbyte *= GET_MODE_SIZE (SImode);
4443 operand0 = XEXP (operand0, 0);
4445 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4447 if (GET_MODE (operand0) != SImode)
4448 operand0 = gen_rtx_SUBREG (SImode, operand0, op0_subbyte);
4449 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
4453 (define_insn "*sign_extendqihi2_insn"
4454 [(set (match_operand:HI 0 "register_operand" "=r")
4455 (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
4458 [(set_attr "type" "sload")
4459 (set_attr "us3load_type" "3cycle")])
4461 (define_expand "extendqisi2"
4462 [(set (match_operand:SI 0 "register_operand" "")
4463 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
4466 rtx temp = gen_reg_rtx (SImode);
4467 rtx shift_24 = GEN_INT (24);
4468 int op1_subbyte = 0;
4470 if (GET_CODE (operand1) == SUBREG)
4472 op1_subbyte = SUBREG_BYTE (operand1);
4473 op1_subbyte /= GET_MODE_SIZE (SImode);
4474 op1_subbyte *= GET_MODE_SIZE (SImode);
4475 operand1 = XEXP (operand1, 0);
4478 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4480 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
4484 (define_insn "*sign_extendqisi2_insn"
4485 [(set (match_operand:SI 0 "register_operand" "=r")
4486 (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
4489 [(set_attr "type" "sload")
4490 (set_attr "us3load_type" "3cycle")])
4492 (define_expand "extendqidi2"
4493 [(set (match_operand:DI 0 "register_operand" "")
4494 (sign_extend:DI (match_operand:QI 1 "register_operand" "")))]
4497 rtx temp = gen_reg_rtx (DImode);
4498 rtx shift_56 = GEN_INT (56);
4499 int op1_subbyte = 0;
4501 if (GET_CODE (operand1) == SUBREG)
4503 op1_subbyte = SUBREG_BYTE (operand1);
4504 op1_subbyte /= GET_MODE_SIZE (DImode);
4505 op1_subbyte *= GET_MODE_SIZE (DImode);
4506 operand1 = XEXP (operand1, 0);
4509 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
4511 emit_insn (gen_ashrdi3 (operand0, temp, shift_56));
4515 (define_insn "*sign_extendqidi2_insn"
4516 [(set (match_operand:DI 0 "register_operand" "=r")
4517 (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
4520 [(set_attr "type" "sload")
4521 (set_attr "us3load_type" "3cycle")])
4523 (define_expand "extendhidi2"
4524 [(set (match_operand:DI 0 "register_operand" "")
4525 (sign_extend:DI (match_operand:HI 1 "register_operand" "")))]
4528 rtx temp = gen_reg_rtx (DImode);
4529 rtx shift_48 = GEN_INT (48);
4530 int op1_subbyte = 0;
4532 if (GET_CODE (operand1) == SUBREG)
4534 op1_subbyte = SUBREG_BYTE (operand1);
4535 op1_subbyte /= GET_MODE_SIZE (DImode);
4536 op1_subbyte *= GET_MODE_SIZE (DImode);
4537 operand1 = XEXP (operand1, 0);
4540 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
4542 emit_insn (gen_ashrdi3 (operand0, temp, shift_48));
4546 (define_insn "*sign_extendhidi2_insn"
4547 [(set (match_operand:DI 0 "register_operand" "=r")
4548 (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
4551 [(set_attr "type" "sload")
4552 (set_attr "us3load_type" "3cycle")])
4554 (define_expand "extendsidi2"
4555 [(set (match_operand:DI 0 "register_operand" "")
4556 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
4560 (define_insn "*sign_extendsidi2_insn"
4561 [(set (match_operand:DI 0 "register_operand" "=r,r")
4562 (sign_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
4567 [(set_attr "type" "shift,sload")
4568 (set_attr "us3load_type" "*,3cycle")])
4570 ;; Special pattern for optimizing bit-field compares. This is needed
4571 ;; because combine uses this as a canonical form.
4573 (define_insn "*cmp_zero_extract"
4576 (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
4577 (match_operand:SI 1 "small_int_or_double" "n")
4578 (match_operand:SI 2 "small_int_or_double" "n"))
4580 "(GET_CODE (operands[2]) == CONST_INT
4581 && INTVAL (operands[2]) > 19)
4582 || (GET_CODE (operands[2]) == CONST_DOUBLE
4583 && CONST_DOUBLE_LOW (operands[2]) > 19)"
4585 int len = (GET_CODE (operands[1]) == CONST_INT
4586 ? INTVAL (operands[1])
4587 : CONST_DOUBLE_LOW (operands[1]));
4589 (GET_CODE (operands[2]) == CONST_INT
4590 ? INTVAL (operands[2])
4591 : CONST_DOUBLE_LOW (operands[2])) - len;
4592 HOST_WIDE_INT mask = ((1 << len) - 1) << pos;
4594 operands[1] = GEN_INT (mask);
4595 return "andcc\t%0, %1, %%g0";
4597 [(set_attr "type" "compare")])
4599 (define_insn "*cmp_zero_extract_sp64"
4602 (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
4603 (match_operand:SI 1 "small_int_or_double" "n")
4604 (match_operand:SI 2 "small_int_or_double" "n"))
4607 && ((GET_CODE (operands[2]) == CONST_INT
4608 && INTVAL (operands[2]) > 51)
4609 || (GET_CODE (operands[2]) == CONST_DOUBLE
4610 && CONST_DOUBLE_LOW (operands[2]) > 51))"
4612 int len = (GET_CODE (operands[1]) == CONST_INT
4613 ? INTVAL (operands[1])
4614 : CONST_DOUBLE_LOW (operands[1]));
4616 (GET_CODE (operands[2]) == CONST_INT
4617 ? INTVAL (operands[2])
4618 : CONST_DOUBLE_LOW (operands[2])) - len;
4619 HOST_WIDE_INT mask = (((unsigned HOST_WIDE_INT) 1 << len) - 1) << pos;
4621 operands[1] = GEN_INT (mask);
4622 return "andcc\t%0, %1, %%g0";
4624 [(set_attr "type" "compare")])
4626 ;; Conversions between float, double and long double.
4628 (define_insn "extendsfdf2"
4629 [(set (match_operand:DF 0 "register_operand" "=e")
4631 (match_operand:SF 1 "register_operand" "f")))]
4634 [(set_attr "type" "fp")
4635 (set_attr "fptype" "double")])
4637 (define_expand "extendsftf2"
4638 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4640 (match_operand:SF 1 "register_operand" "")))]
4641 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4642 "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
4644 (define_insn "*extendsftf2_hq"
4645 [(set (match_operand:TF 0 "register_operand" "=e")
4647 (match_operand:SF 1 "register_operand" "f")))]
4648 "TARGET_FPU && TARGET_HARD_QUAD"
4650 [(set_attr "type" "fp")])
4652 (define_expand "extenddftf2"
4653 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4655 (match_operand:DF 1 "register_operand" "")))]
4656 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4657 "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
4659 (define_insn "*extenddftf2_hq"
4660 [(set (match_operand:TF 0 "register_operand" "=e")
4662 (match_operand:DF 1 "register_operand" "e")))]
4663 "TARGET_FPU && TARGET_HARD_QUAD"
4665 [(set_attr "type" "fp")])
4667 (define_insn "truncdfsf2"
4668 [(set (match_operand:SF 0 "register_operand" "=f")
4670 (match_operand:DF 1 "register_operand" "e")))]
4673 [(set_attr "type" "fp")
4674 (set_attr "fptype" "double")])
4676 (define_expand "trunctfsf2"
4677 [(set (match_operand:SF 0 "register_operand" "")
4679 (match_operand:TF 1 "general_operand" "")))]
4680 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4681 "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
4683 (define_insn "*trunctfsf2_hq"
4684 [(set (match_operand:SF 0 "register_operand" "=f")
4686 (match_operand:TF 1 "register_operand" "e")))]
4687 "TARGET_FPU && TARGET_HARD_QUAD"
4689 [(set_attr "type" "fp")])
4691 (define_expand "trunctfdf2"
4692 [(set (match_operand:DF 0 "register_operand" "")
4694 (match_operand:TF 1 "general_operand" "")))]
4695 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4696 "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
4698 (define_insn "*trunctfdf2_hq"
4699 [(set (match_operand:DF 0 "register_operand" "=e")
4701 (match_operand:TF 1 "register_operand" "e")))]
4702 "TARGET_FPU && TARGET_HARD_QUAD"
4704 [(set_attr "type" "fp")])
4706 ;; Conversion between fixed point and floating point.
4708 (define_insn "floatsisf2"
4709 [(set (match_operand:SF 0 "register_operand" "=f")
4710 (float:SF (match_operand:SI 1 "register_operand" "f")))]
4713 [(set_attr "type" "fp")
4714 (set_attr "fptype" "double")])
4716 (define_insn "floatsidf2"
4717 [(set (match_operand:DF 0 "register_operand" "=e")
4718 (float:DF (match_operand:SI 1 "register_operand" "f")))]
4721 [(set_attr "type" "fp")
4722 (set_attr "fptype" "double")])
4724 (define_expand "floatsitf2"
4725 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4726 (float:TF (match_operand:SI 1 "register_operand" "")))]
4727 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4728 "emit_tfmode_cvt (FLOAT, operands); DONE;")
4730 (define_insn "*floatsitf2_hq"
4731 [(set (match_operand:TF 0 "register_operand" "=e")
4732 (float:TF (match_operand:SI 1 "register_operand" "f")))]
4733 "TARGET_FPU && TARGET_HARD_QUAD"
4735 [(set_attr "type" "fp")])
4737 (define_expand "floatunssitf2"
4738 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4739 (unsigned_float:TF (match_operand:SI 1 "register_operand" "")))]
4740 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4741 "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
4743 ;; Now the same for 64 bit sources.
4745 (define_insn "floatdisf2"
4746 [(set (match_operand:SF 0 "register_operand" "=f")
4747 (float:SF (match_operand:DI 1 "register_operand" "e")))]
4748 "TARGET_V9 && TARGET_FPU"
4750 [(set_attr "type" "fp")
4751 (set_attr "fptype" "double")])
4753 (define_expand "floatunsdisf2"
4754 [(use (match_operand:SF 0 "register_operand" ""))
4755 (use (match_operand:DI 1 "general_operand" ""))]
4756 "TARGET_ARCH64 && TARGET_FPU"
4757 "sparc_emit_floatunsdi (operands, SFmode); DONE;")
4759 (define_insn "floatdidf2"
4760 [(set (match_operand:DF 0 "register_operand" "=e")
4761 (float:DF (match_operand:DI 1 "register_operand" "e")))]
4762 "TARGET_V9 && TARGET_FPU"
4764 [(set_attr "type" "fp")
4765 (set_attr "fptype" "double")])
4767 (define_expand "floatunsdidf2"
4768 [(use (match_operand:DF 0 "register_operand" ""))
4769 (use (match_operand:DI 1 "general_operand" ""))]
4770 "TARGET_ARCH64 && TARGET_FPU"
4771 "sparc_emit_floatunsdi (operands, DFmode); DONE;")
4773 (define_expand "floatditf2"
4774 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4775 (float:TF (match_operand:DI 1 "register_operand" "")))]
4776 "TARGET_FPU && TARGET_V9 && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4777 "emit_tfmode_cvt (FLOAT, operands); DONE;")
4779 (define_insn "*floatditf2_hq"
4780 [(set (match_operand:TF 0 "register_operand" "=e")
4781 (float:TF (match_operand:DI 1 "register_operand" "e")))]
4782 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
4784 [(set_attr "type" "fp")])
4786 (define_expand "floatunsditf2"
4787 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4788 (unsigned_float:TF (match_operand:DI 1 "register_operand" "")))]
4789 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4790 "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
4792 ;; Convert a float to an actual integer.
4793 ;; Truncation is performed as part of the conversion.
4795 (define_insn "fix_truncsfsi2"
4796 [(set (match_operand:SI 0 "register_operand" "=f")
4797 (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
4800 [(set_attr "type" "fp")
4801 (set_attr "fptype" "double")])
4803 (define_insn "fix_truncdfsi2"
4804 [(set (match_operand:SI 0 "register_operand" "=f")
4805 (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
4808 [(set_attr "type" "fp")
4809 (set_attr "fptype" "double")])
4811 (define_expand "fix_trunctfsi2"
4812 [(set (match_operand:SI 0 "register_operand" "")
4813 (fix:SI (match_operand:TF 1 "general_operand" "")))]
4814 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4815 "emit_tfmode_cvt (FIX, operands); DONE;")
4817 (define_insn "*fix_trunctfsi2_hq"
4818 [(set (match_operand:SI 0 "register_operand" "=f")
4819 (fix:SI (match_operand:TF 1 "register_operand" "e")))]
4820 "TARGET_FPU && TARGET_HARD_QUAD"
4822 [(set_attr "type" "fp")])
4824 (define_expand "fixuns_trunctfsi2"
4825 [(set (match_operand:SI 0 "register_operand" "")
4826 (unsigned_fix:SI (match_operand:TF 1 "general_operand" "")))]
4827 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4828 "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
4830 ;; Now the same, for V9 targets
4832 (define_insn "fix_truncsfdi2"
4833 [(set (match_operand:DI 0 "register_operand" "=e")
4834 (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
4835 "TARGET_V9 && TARGET_FPU"
4837 [(set_attr "type" "fp")
4838 (set_attr "fptype" "double")])
4840 (define_expand "fixuns_truncsfdi2"
4841 [(use (match_operand:DI 0 "register_operand" ""))
4842 (use (match_operand:SF 1 "general_operand" ""))]
4843 "TARGET_ARCH64 && TARGET_FPU"
4844 "sparc_emit_fixunsdi (operands, SFmode); DONE;")
4846 (define_insn "fix_truncdfdi2"
4847 [(set (match_operand:DI 0 "register_operand" "=e")
4848 (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
4849 "TARGET_V9 && TARGET_FPU"
4851 [(set_attr "type" "fp")
4852 (set_attr "fptype" "double")])
4854 (define_expand "fixuns_truncdfdi2"
4855 [(use (match_operand:DI 0 "register_operand" ""))
4856 (use (match_operand:DF 1 "general_operand" ""))]
4857 "TARGET_ARCH64 && TARGET_FPU"
4858 "sparc_emit_fixunsdi (operands, DFmode); DONE;")
4860 (define_expand "fix_trunctfdi2"
4861 [(set (match_operand:DI 0 "register_operand" "")
4862 (fix:DI (match_operand:TF 1 "general_operand" "")))]
4863 "TARGET_V9 && TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4864 "emit_tfmode_cvt (FIX, operands); DONE;")
4866 (define_insn "*fix_trunctfdi2_hq"
4867 [(set (match_operand:DI 0 "register_operand" "=e")
4868 (fix:DI (match_operand:TF 1 "register_operand" "e")))]
4869 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
4871 [(set_attr "type" "fp")])
4873 (define_expand "fixuns_trunctfdi2"
4874 [(set (match_operand:DI 0 "register_operand" "")
4875 (unsigned_fix:DI (match_operand:TF 1 "general_operand" "")))]
4876 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4877 "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
4879 ;;- arithmetic instructions
4881 (define_expand "adddi3"
4882 [(set (match_operand:DI 0 "register_operand" "")
4883 (plus:DI (match_operand:DI 1 "register_operand" "")
4884 (match_operand:DI 2 "arith_double_add_operand" "")))]
4887 if (! TARGET_ARCH64)
4889 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
4890 gen_rtx_SET (VOIDmode, operands[0],
4891 gen_rtx_PLUS (DImode, operands[1],
4893 gen_rtx_CLOBBER (VOIDmode,
4894 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
4899 (define_insn_and_split "adddi3_insn_sp32"
4900 [(set (match_operand:DI 0 "register_operand" "=r")
4901 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
4902 (match_operand:DI 2 "arith_double_operand" "rHI")))
4903 (clobber (reg:CC 100))]
4906 "&& reload_completed"
4907 [(parallel [(set (reg:CC_NOOV 100)
4908 (compare:CC_NOOV (plus:SI (match_dup 4)
4912 (plus:SI (match_dup 4) (match_dup 5)))])
4914 (plus:SI (plus:SI (match_dup 7)
4916 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4918 operands[3] = gen_lowpart (SImode, operands[0]);
4919 operands[4] = gen_lowpart (SImode, operands[1]);
4920 operands[5] = gen_lowpart (SImode, operands[2]);
4921 operands[6] = gen_highpart (SImode, operands[0]);
4922 operands[7] = gen_highpart_mode (SImode, DImode, operands[1]);
4923 #if HOST_BITS_PER_WIDE_INT == 32
4924 if (GET_CODE (operands[2]) == CONST_INT)
4926 if (INTVAL (operands[2]) < 0)
4927 operands[8] = constm1_rtx;
4929 operands[8] = const0_rtx;
4933 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
4935 [(set_attr "length" "2")])
4938 [(set (match_operand:DI 0 "register_operand" "")
4939 (minus:DI (match_operand:DI 1 "arith_double_operand" "")
4940 (match_operand:DI 2 "arith_double_operand" "")))
4941 (clobber (reg:CC 100))]
4942 "! TARGET_ARCH64 && reload_completed"
4943 [(parallel [(set (reg:CC_NOOV 100)
4944 (compare:CC_NOOV (minus:SI (match_dup 4)
4948 (minus:SI (match_dup 4) (match_dup 5)))])
4950 (minus:SI (minus:SI (match_dup 7)
4952 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4954 operands[3] = gen_lowpart (SImode, operands[0]);
4955 operands[4] = gen_lowpart (SImode, operands[1]);
4956 operands[5] = gen_lowpart (SImode, operands[2]);
4957 operands[6] = gen_highpart (SImode, operands[0]);
4958 operands[7] = gen_highpart (SImode, operands[1]);
4959 #if HOST_BITS_PER_WIDE_INT == 32
4960 if (GET_CODE (operands[2]) == CONST_INT)
4962 if (INTVAL (operands[2]) < 0)
4963 operands[8] = constm1_rtx;
4965 operands[8] = const0_rtx;
4969 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
4972 ;; LTU here means "carry set"
4974 [(set (match_operand:SI 0 "register_operand" "=r")
4975 (plus:SI (plus:SI (match_operand:SI 1 "arith_operand" "%r")
4976 (match_operand:SI 2 "arith_operand" "rI"))
4977 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4980 [(set_attr "type" "ialuX")])
4982 (define_insn_and_split "*addx_extend_sp32"
4983 [(set (match_operand:DI 0 "register_operand" "=r")
4984 (zero_extend:DI (plus:SI (plus:SI
4985 (match_operand:SI 1 "reg_or_0_operand" "%rJ")
4986 (match_operand:SI 2 "arith_operand" "rI"))
4987 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4990 "&& reload_completed"
4991 [(set (match_dup 3) (plus:SI (plus:SI (match_dup 1) (match_dup 2))
4992 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
4993 (set (match_dup 4) (const_int 0))]
4994 "operands[3] = gen_lowpart (SImode, operands[0]);
4995 operands[4] = gen_highpart_mode (SImode, DImode, operands[1]);"
4996 [(set_attr "length" "2")])
4998 (define_insn "*addx_extend_sp64"
4999 [(set (match_operand:DI 0 "register_operand" "=r")
5000 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
5001 (match_operand:SI 2 "arith_operand" "rI"))
5002 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5005 [(set_attr "type" "ialuX")])
5008 [(set (match_operand:SI 0 "register_operand" "=r")
5009 (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5010 (match_operand:SI 2 "arith_operand" "rI"))
5011 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5014 [(set_attr "type" "ialuX")])
5016 (define_insn "*subx_extend_sp64"
5017 [(set (match_operand:DI 0 "register_operand" "=r")
5018 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5019 (match_operand:SI 2 "arith_operand" "rI"))
5020 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5023 [(set_attr "type" "ialuX")])
5025 (define_insn_and_split "*subx_extend"
5026 [(set (match_operand:DI 0 "register_operand" "=r")
5027 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5028 (match_operand:SI 2 "arith_operand" "rI"))
5029 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5032 "&& reload_completed"
5033 [(set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 2))
5034 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
5035 (set (match_dup 4) (const_int 0))]
5036 "operands[3] = gen_lowpart (SImode, operands[0]);
5037 operands[4] = gen_highpart (SImode, operands[0]);"
5038 [(set_attr "length" "2")])
5040 (define_insn_and_split ""
5041 [(set (match_operand:DI 0 "register_operand" "=r")
5042 (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5043 (match_operand:DI 2 "register_operand" "r")))
5044 (clobber (reg:CC 100))]
5047 "&& reload_completed"
5048 [(parallel [(set (reg:CC_NOOV 100)
5049 (compare:CC_NOOV (plus:SI (match_dup 3) (match_dup 1))
5051 (set (match_dup 5) (plus:SI (match_dup 3) (match_dup 1)))])
5053 (plus:SI (plus:SI (match_dup 4) (const_int 0))
5054 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5055 "operands[3] = gen_lowpart (SImode, operands[2]);
5056 operands[4] = gen_highpart (SImode, operands[2]);
5057 operands[5] = gen_lowpart (SImode, operands[0]);
5058 operands[6] = gen_highpart (SImode, operands[0]);"
5059 [(set_attr "length" "2")])
5061 (define_insn "*adddi3_sp64"
5062 [(set (match_operand:DI 0 "register_operand" "=r,r")
5063 (plus:DI (match_operand:DI 1 "register_operand" "%r,r")
5064 (match_operand:DI 2 "arith_double_add_operand" "rHI,O")))]
5070 (define_insn "addsi3"
5071 [(set (match_operand:SI 0 "register_operand" "=r,r,d")
5072 (plus:SI (match_operand:SI 1 "register_operand" "%r,r,d")
5073 (match_operand:SI 2 "arith_add_operand" "rI,O,d")))]
5078 fpadd32s\t%1, %2, %0"
5079 [(set_attr "type" "*,*,fga")
5080 (set_attr "fptype" "*,*,single")])
5082 (define_insn "*cmp_cc_plus"
5083 [(set (reg:CC_NOOV 100)
5084 (compare:CC_NOOV (plus:SI (match_operand:SI 0 "arith_operand" "%r")
5085 (match_operand:SI 1 "arith_operand" "rI"))
5088 "addcc\t%0, %1, %%g0"
5089 [(set_attr "type" "compare")])
5091 (define_insn "*cmp_ccx_plus"
5092 [(set (reg:CCX_NOOV 100)
5093 (compare:CCX_NOOV (plus:DI (match_operand:DI 0 "arith_double_operand" "%r")
5094 (match_operand:DI 1 "arith_double_operand" "rHI"))
5097 "addcc\t%0, %1, %%g0"
5098 [(set_attr "type" "compare")])
5100 (define_insn "*cmp_cc_plus_set"
5101 [(set (reg:CC_NOOV 100)
5102 (compare:CC_NOOV (plus:SI (match_operand:SI 1 "arith_operand" "%r")
5103 (match_operand:SI 2 "arith_operand" "rI"))
5105 (set (match_operand:SI 0 "register_operand" "=r")
5106 (plus:SI (match_dup 1) (match_dup 2)))]
5109 [(set_attr "type" "compare")])
5111 (define_insn "*cmp_ccx_plus_set"
5112 [(set (reg:CCX_NOOV 100)
5113 (compare:CCX_NOOV (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
5114 (match_operand:DI 2 "arith_double_operand" "rHI"))
5116 (set (match_operand:DI 0 "register_operand" "=r")
5117 (plus:DI (match_dup 1) (match_dup 2)))]
5120 [(set_attr "type" "compare")])
5122 (define_expand "subdi3"
5123 [(set (match_operand:DI 0 "register_operand" "")
5124 (minus:DI (match_operand:DI 1 "register_operand" "")
5125 (match_operand:DI 2 "arith_double_add_operand" "")))]
5128 if (! TARGET_ARCH64)
5130 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
5131 gen_rtx_SET (VOIDmode, operands[0],
5132 gen_rtx_MINUS (DImode, operands[1],
5134 gen_rtx_CLOBBER (VOIDmode,
5135 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
5140 (define_insn_and_split "*subdi3_sp32"
5141 [(set (match_operand:DI 0 "register_operand" "=r")
5142 (minus:DI (match_operand:DI 1 "register_operand" "r")
5143 (match_operand:DI 2 "arith_double_operand" "rHI")))
5144 (clobber (reg:CC 100))]
5147 "&& reload_completed
5148 && (GET_CODE (operands[2]) == CONST_INT
5149 || GET_CODE (operands[2]) == CONST_DOUBLE)"
5150 [(clobber (const_int 0))]
5154 highp = gen_highpart_mode (SImode, DImode, operands[2]);
5155 lowp = gen_lowpart (SImode, operands[2]);
5156 if ((lowp == const0_rtx)
5157 && (operands[0] == operands[1]))
5159 emit_insn (gen_rtx_SET (VOIDmode,
5160 gen_highpart (SImode, operands[0]),
5161 gen_rtx_MINUS (SImode,
5162 gen_highpart_mode (SImode, DImode,
5168 emit_insn (gen_cmp_minus_cc_set (gen_lowpart (SImode, operands[0]),
5169 gen_lowpart (SImode, operands[1]),
5171 emit_insn (gen_subx (gen_highpart (SImode, operands[0]),
5172 gen_highpart_mode (SImode, DImode, operands[1]),
5177 [(set_attr "length" "2")])
5180 [(set (match_operand:DI 0 "register_operand" "")
5181 (minus:DI (match_operand:DI 1 "register_operand" "")
5182 (match_operand:DI 2 "register_operand" "")))
5183 (clobber (reg:CC 100))]
5185 && reload_completed"
5186 [(clobber (const_int 0))]
5188 emit_insn (gen_cmp_minus_cc_set (gen_lowpart (SImode, operands[0]),
5189 gen_lowpart (SImode, operands[1]),
5190 gen_lowpart (SImode, operands[2])));
5191 emit_insn (gen_subx (gen_highpart (SImode, operands[0]),
5192 gen_highpart (SImode, operands[1]),
5193 gen_highpart (SImode, operands[2])));
5197 (define_insn_and_split ""
5198 [(set (match_operand:DI 0 "register_operand" "=r")
5199 (minus:DI (match_operand:DI 1 "register_operand" "r")
5200 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))
5201 (clobber (reg:CC 100))]
5204 "&& reload_completed"
5205 [(parallel [(set (reg:CC_NOOV 100)
5206 (compare:CC_NOOV (minus:SI (match_dup 3) (match_dup 2))
5208 (set (match_dup 5) (minus:SI (match_dup 3) (match_dup 2)))])
5210 (minus:SI (minus:SI (match_dup 4) (const_int 0))
5211 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5212 "operands[3] = gen_lowpart (SImode, operands[1]);
5213 operands[4] = gen_highpart (SImode, operands[1]);
5214 operands[5] = gen_lowpart (SImode, operands[0]);
5215 operands[6] = gen_highpart (SImode, operands[0]);"
5216 [(set_attr "length" "2")])
5218 (define_insn "*subdi3_sp64"
5219 [(set (match_operand:DI 0 "register_operand" "=r,r")
5220 (minus:DI (match_operand:DI 1 "register_operand" "r,r")
5221 (match_operand:DI 2 "arith_double_add_operand" "rHI,O")))]
5227 (define_insn "subsi3"
5228 [(set (match_operand:SI 0 "register_operand" "=r,r,d")
5229 (minus:SI (match_operand:SI 1 "register_operand" "r,r,d")
5230 (match_operand:SI 2 "arith_add_operand" "rI,O,d")))]
5235 fpsub32s\t%1, %2, %0"
5236 [(set_attr "type" "*,*,fga")
5237 (set_attr "fptype" "*,*,single")])
5239 (define_insn "*cmp_minus_cc"
5240 [(set (reg:CC_NOOV 100)
5241 (compare:CC_NOOV (minus:SI (match_operand:SI 0 "reg_or_0_operand" "rJ")
5242 (match_operand:SI 1 "arith_operand" "rI"))
5245 "subcc\t%r0, %1, %%g0"
5246 [(set_attr "type" "compare")])
5248 (define_insn "*cmp_minus_ccx"
5249 [(set (reg:CCX_NOOV 100)
5250 (compare:CCX_NOOV (minus:DI (match_operand:DI 0 "register_operand" "r")
5251 (match_operand:DI 1 "arith_double_operand" "rHI"))
5254 "subcc\t%0, %1, %%g0"
5255 [(set_attr "type" "compare")])
5257 (define_insn "cmp_minus_cc_set"
5258 [(set (reg:CC_NOOV 100)
5259 (compare:CC_NOOV (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5260 (match_operand:SI 2 "arith_operand" "rI"))
5262 (set (match_operand:SI 0 "register_operand" "=r")
5263 (minus:SI (match_dup 1) (match_dup 2)))]
5265 "subcc\t%r1, %2, %0"
5266 [(set_attr "type" "compare")])
5268 (define_insn "*cmp_minus_ccx_set"
5269 [(set (reg:CCX_NOOV 100)
5270 (compare:CCX_NOOV (minus:DI (match_operand:DI 1 "register_operand" "r")
5271 (match_operand:DI 2 "arith_double_operand" "rHI"))
5273 (set (match_operand:DI 0 "register_operand" "=r")
5274 (minus:DI (match_dup 1) (match_dup 2)))]
5277 [(set_attr "type" "compare")])
5279 ;; Integer Multiply/Divide.
5281 ;; The 32 bit multiply/divide instructions are deprecated on v9, but at
5282 ;; least in UltraSPARC I, II and IIi it is a win tick-wise.
5284 (define_insn "mulsi3"
5285 [(set (match_operand:SI 0 "register_operand" "=r")
5286 (mult:SI (match_operand:SI 1 "arith_operand" "%r")
5287 (match_operand:SI 2 "arith_operand" "rI")))]
5290 [(set_attr "type" "imul")])
5292 (define_expand "muldi3"
5293 [(set (match_operand:DI 0 "register_operand" "=r")
5294 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r")
5295 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5296 "TARGET_ARCH64 || TARGET_V8PLUS"
5300 emit_insn (gen_muldi3_v8plus (operands[0], operands[1], operands[2]));
5305 (define_insn "*muldi3_sp64"
5306 [(set (match_operand:DI 0 "register_operand" "=r")
5307 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r")
5308 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5311 [(set_attr "type" "imul")])
5313 ;; V8plus wide multiply.
5315 (define_insn "muldi3_v8plus"
5316 [(set (match_operand:DI 0 "register_operand" "=r,h")
5317 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r,0")
5318 (match_operand:DI 2 "arith_double_operand" "rI,rI")))
5319 (clobber (match_scratch:SI 3 "=&h,X"))
5320 (clobber (match_scratch:SI 4 "=&h,X"))]
5323 if (sparc_check_64 (operands[1], insn) <= 0)
5324 output_asm_insn ("srl\t%L1, 0, %L1", operands);
5325 if (which_alternative == 1)
5326 output_asm_insn ("sllx\t%H1, 32, %H1", operands);
5327 if (GET_CODE (operands[2]) == CONST_INT)
5329 if (which_alternative == 1)
5330 return "or\t%L1, %H1, %H1\n\tmulx\t%H1, %2, %L0\;srlx\t%L0, 32, %H0";
5332 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";
5334 else if (rtx_equal_p (operands[1], operands[2]))
5336 if (which_alternative == 1)
5337 return "or\t%L1, %H1, %H1\n\tmulx\t%H1, %H1, %L0\;srlx\t%L0, 32, %H0";
5339 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";
5341 if (sparc_check_64 (operands[2], insn) <= 0)
5342 output_asm_insn ("srl\t%L2, 0, %L2", operands);
5343 if (which_alternative == 1)
5344 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";
5346 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";
5348 [(set_attr "type" "multi")
5349 (set_attr "length" "9,8")])
5351 (define_insn "*cmp_mul_set"
5353 (compare:CC (mult:SI (match_operand:SI 1 "arith_operand" "%r")
5354 (match_operand:SI 2 "arith_operand" "rI"))
5356 (set (match_operand:SI 0 "register_operand" "=r")
5357 (mult:SI (match_dup 1) (match_dup 2)))]
5358 "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS"
5359 "smulcc\t%1, %2, %0"
5360 [(set_attr "type" "imul")])
5362 (define_expand "mulsidi3"
5363 [(set (match_operand:DI 0 "register_operand" "")
5364 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
5365 (sign_extend:DI (match_operand:SI 2 "arith_operand" ""))))]
5368 if (CONSTANT_P (operands[2]))
5371 emit_insn (gen_const_mulsidi3_v8plus (operands[0], operands[1],
5373 else if (TARGET_ARCH32)
5374 emit_insn (gen_const_mulsidi3_sp32 (operands[0], operands[1],
5377 emit_insn (gen_const_mulsidi3_sp64 (operands[0], operands[1],
5383 emit_insn (gen_mulsidi3_v8plus (operands[0], operands[1], operands[2]));
5388 ;; V9 puts the 64 bit product in a 64 bit register. Only out or global
5389 ;; registers can hold 64 bit values in the V8plus environment.
5391 (define_insn "mulsidi3_v8plus"
5392 [(set (match_operand:DI 0 "register_operand" "=h,r")
5393 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5394 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
5395 (clobber (match_scratch:SI 3 "=X,&h"))]
5398 smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
5399 smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
5400 [(set_attr "type" "multi")
5401 (set_attr "length" "2,3")])
5404 (define_insn "const_mulsidi3_v8plus"
5405 [(set (match_operand:DI 0 "register_operand" "=h,r")
5406 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5407 (match_operand:DI 2 "small_int" "I,I")))
5408 (clobber (match_scratch:SI 3 "=X,&h"))]
5411 smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
5412 smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
5413 [(set_attr "type" "multi")
5414 (set_attr "length" "2,3")])
5417 (define_insn "*mulsidi3_sp32"
5418 [(set (match_operand:DI 0 "register_operand" "=r")
5419 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5420 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
5423 return TARGET_SPARCLET
5424 ? "smuld\t%1, %2, %L0"
5425 : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
5428 (if_then_else (eq_attr "isa" "sparclet")
5429 (const_string "imul") (const_string "multi")))
5430 (set (attr "length")
5431 (if_then_else (eq_attr "isa" "sparclet")
5432 (const_int 1) (const_int 2)))])
5434 (define_insn "*mulsidi3_sp64"
5435 [(set (match_operand:DI 0 "register_operand" "=r")
5436 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5437 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
5438 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5440 [(set_attr "type" "imul")])
5442 ;; Extra pattern, because sign_extend of a constant isn't valid.
5445 (define_insn "const_mulsidi3_sp32"
5446 [(set (match_operand:DI 0 "register_operand" "=r")
5447 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5448 (match_operand:DI 2 "small_int" "I")))]
5451 return TARGET_SPARCLET
5452 ? "smuld\t%1, %2, %L0"
5453 : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
5456 (if_then_else (eq_attr "isa" "sparclet")
5457 (const_string "imul") (const_string "multi")))
5458 (set (attr "length")
5459 (if_then_else (eq_attr "isa" "sparclet")
5460 (const_int 1) (const_int 2)))])
5462 (define_insn "const_mulsidi3_sp64"
5463 [(set (match_operand:DI 0 "register_operand" "=r")
5464 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5465 (match_operand:DI 2 "small_int" "I")))]
5466 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5468 [(set_attr "type" "imul")])
5470 (define_expand "smulsi3_highpart"
5471 [(set (match_operand:SI 0 "register_operand" "")
5473 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
5474 (sign_extend:DI (match_operand:SI 2 "arith_operand" "")))
5476 "TARGET_HARD_MUL && TARGET_ARCH32"
5478 if (CONSTANT_P (operands[2]))
5482 emit_insn (gen_const_smulsi3_highpart_v8plus (operands[0],
5488 emit_insn (gen_const_smulsi3_highpart (operands[0], operands[1], operands[2]));
5493 emit_insn (gen_smulsi3_highpart_v8plus (operands[0], operands[1],
5494 operands[2], GEN_INT (32)));
5500 (define_insn "smulsi3_highpart_v8plus"
5501 [(set (match_operand:SI 0 "register_operand" "=h,r")
5503 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5504 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
5505 (match_operand:SI 3 "const_int_operand" "i,i"))))
5506 (clobber (match_scratch:SI 4 "=X,&h"))]
5509 smul\t%1, %2, %0\;srlx\t%0, %3, %0
5510 smul\t%1, %2, %4\;srlx\t%4, %3, %0"
5511 [(set_attr "type" "multi")
5512 (set_attr "length" "2")])
5514 ;; The combiner changes TRUNCATE in the previous pattern to SUBREG.
5517 [(set (match_operand:SI 0 "register_operand" "=h,r")
5520 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5521 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
5522 (match_operand:SI 3 "const_int_operand" "i,i"))
5524 (clobber (match_scratch:SI 4 "=X,&h"))]
5527 smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
5528 smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
5529 [(set_attr "type" "multi")
5530 (set_attr "length" "2")])
5533 (define_insn "const_smulsi3_highpart_v8plus"
5534 [(set (match_operand:SI 0 "register_operand" "=h,r")
5536 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5537 (match_operand:DI 2 "small_int" "i,i"))
5538 (match_operand:SI 3 "const_int_operand" "i,i"))))
5539 (clobber (match_scratch:SI 4 "=X,&h"))]
5542 smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
5543 smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
5544 [(set_attr "type" "multi")
5545 (set_attr "length" "2")])
5548 (define_insn "*smulsi3_highpart_sp32"
5549 [(set (match_operand:SI 0 "register_operand" "=r")
5551 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5552 (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
5555 "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
5556 [(set_attr "type" "multi")
5557 (set_attr "length" "2")])
5560 (define_insn "const_smulsi3_highpart"
5561 [(set (match_operand:SI 0 "register_operand" "=r")
5563 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5564 (match_operand:DI 2 "small_int" "i"))
5567 "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
5568 [(set_attr "type" "multi")
5569 (set_attr "length" "2")])
5571 (define_expand "umulsidi3"
5572 [(set (match_operand:DI 0 "register_operand" "")
5573 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
5574 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" ""))))]
5577 if (CONSTANT_P (operands[2]))
5580 emit_insn (gen_const_umulsidi3_v8plus (operands[0], operands[1],
5582 else if (TARGET_ARCH32)
5583 emit_insn (gen_const_umulsidi3_sp32 (operands[0], operands[1],
5586 emit_insn (gen_const_umulsidi3_sp64 (operands[0], operands[1],
5592 emit_insn (gen_umulsidi3_v8plus (operands[0], operands[1], operands[2]));
5598 (define_insn "umulsidi3_v8plus"
5599 [(set (match_operand:DI 0 "register_operand" "=h,r")
5600 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5601 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
5602 (clobber (match_scratch:SI 3 "=X,&h"))]
5605 umul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
5606 umul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
5607 [(set_attr "type" "multi")
5608 (set_attr "length" "2,3")])
5611 (define_insn "*umulsidi3_sp32"
5612 [(set (match_operand:DI 0 "register_operand" "=r")
5613 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5614 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
5617 return TARGET_SPARCLET
5618 ? "umuld\t%1, %2, %L0"
5619 : "umul\t%1, %2, %L0\n\trd\t%%y, %H0";
5622 (if_then_else (eq_attr "isa" "sparclet")
5623 (const_string "imul") (const_string "multi")))
5624 (set (attr "length")
5625 (if_then_else (eq_attr "isa" "sparclet")
5626 (const_int 1) (const_int 2)))])
5628 (define_insn "*umulsidi3_sp64"
5629 [(set (match_operand:DI 0 "register_operand" "=r")
5630 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5631 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
5632 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5634 [(set_attr "type" "imul")])
5636 ;; Extra pattern, because sign_extend of a constant isn't valid.
5639 (define_insn "const_umulsidi3_sp32"
5640 [(set (match_operand:DI 0 "register_operand" "=r")
5641 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5642 (match_operand:DI 2 "uns_small_int" "")))]
5645 return TARGET_SPARCLET
5646 ? "umuld\t%1, %s2, %L0"
5647 : "umul\t%1, %s2, %L0\n\trd\t%%y, %H0";
5650 (if_then_else (eq_attr "isa" "sparclet")
5651 (const_string "imul") (const_string "multi")))
5652 (set (attr "length")
5653 (if_then_else (eq_attr "isa" "sparclet")
5654 (const_int 1) (const_int 2)))])
5656 (define_insn "const_umulsidi3_sp64"
5657 [(set (match_operand:DI 0 "register_operand" "=r")
5658 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5659 (match_operand:DI 2 "uns_small_int" "")))]
5660 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5662 [(set_attr "type" "imul")])
5665 (define_insn "const_umulsidi3_v8plus"
5666 [(set (match_operand:DI 0 "register_operand" "=h,r")
5667 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5668 (match_operand:DI 2 "uns_small_int" "")))
5669 (clobber (match_scratch:SI 3 "=X,h"))]
5672 umul\t%1, %s2, %L0\n\tsrlx\t%L0, 32, %H0
5673 umul\t%1, %s2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
5674 [(set_attr "type" "multi")
5675 (set_attr "length" "2,3")])
5677 (define_expand "umulsi3_highpart"
5678 [(set (match_operand:SI 0 "register_operand" "")
5680 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
5681 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" "")))
5683 "TARGET_HARD_MUL && TARGET_ARCH32"
5685 if (CONSTANT_P (operands[2]))
5689 emit_insn (gen_const_umulsi3_highpart_v8plus (operands[0],
5695 emit_insn (gen_const_umulsi3_highpart (operands[0], operands[1], operands[2]));
5700 emit_insn (gen_umulsi3_highpart_v8plus (operands[0], operands[1],
5701 operands[2], GEN_INT (32)));
5707 (define_insn "umulsi3_highpart_v8plus"
5708 [(set (match_operand:SI 0 "register_operand" "=h,r")
5710 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5711 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
5712 (match_operand:SI 3 "const_int_operand" "i,i"))))
5713 (clobber (match_scratch:SI 4 "=X,h"))]
5716 umul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
5717 umul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
5718 [(set_attr "type" "multi")
5719 (set_attr "length" "2")])
5722 (define_insn "const_umulsi3_highpart_v8plus"
5723 [(set (match_operand:SI 0 "register_operand" "=h,r")
5725 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5726 (match_operand:DI 2 "uns_small_int" ""))
5727 (match_operand:SI 3 "const_int_operand" "i,i"))))
5728 (clobber (match_scratch:SI 4 "=X,h"))]
5731 umul\t%1, %s2, %0\n\tsrlx\t%0, %3, %0
5732 umul\t%1, %s2, %4\n\tsrlx\t%4, %3, %0"
5733 [(set_attr "type" "multi")
5734 (set_attr "length" "2")])
5737 (define_insn "*umulsi3_highpart_sp32"
5738 [(set (match_operand:SI 0 "register_operand" "=r")
5740 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5741 (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
5744 "umul\t%1, %2, %%g0\n\trd\t%%y, %0"
5745 [(set_attr "type" "multi")
5746 (set_attr "length" "2")])
5749 (define_insn "const_umulsi3_highpart"
5750 [(set (match_operand:SI 0 "register_operand" "=r")
5752 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5753 (match_operand:DI 2 "uns_small_int" ""))
5756 "umul\t%1, %s2, %%g0\n\trd\t%%y, %0"
5757 [(set_attr "type" "multi")
5758 (set_attr "length" "2")])
5760 ;; The v8 architecture specifies that there must be 3 instructions between
5761 ;; a y register write and a use of it for correct results.
5763 (define_expand "divsi3"
5764 [(parallel [(set (match_operand:SI 0 "register_operand" "=r,r")
5765 (div:SI (match_operand:SI 1 "register_operand" "r,r")
5766 (match_operand:SI 2 "input_operand" "rI,m")))
5767 (clobber (match_scratch:SI 3 "=&r,&r"))])]
5768 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
5772 operands[3] = gen_reg_rtx(SImode);
5773 emit_insn (gen_ashrsi3 (operands[3], operands[1], GEN_INT (31)));
5774 emit_insn (gen_divsi3_sp64 (operands[0], operands[1], operands[2],
5780 (define_insn "divsi3_sp32"
5781 [(set (match_operand:SI 0 "register_operand" "=r,r")
5782 (div:SI (match_operand:SI 1 "register_operand" "r,r")
5783 (match_operand:SI 2 "input_operand" "rI,m")))
5784 (clobber (match_scratch:SI 3 "=&r,&r"))]
5785 "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS)
5788 if (which_alternative == 0)
5790 return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tsdiv\t%1, %2, %0";
5792 return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tnop\n\tnop\n\tnop\n\tsdiv\t%1, %2, %0";
5795 return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tld\t%2, %3\n\tsdiv\t%1, %3, %0";
5797 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";
5799 [(set_attr "type" "multi")
5800 (set (attr "length")
5801 (if_then_else (eq_attr "isa" "v9")
5802 (const_int 4) (const_int 6)))])
5804 (define_insn "divsi3_sp64"
5805 [(set (match_operand:SI 0 "register_operand" "=r")
5806 (div:SI (match_operand:SI 1 "register_operand" "r")
5807 (match_operand:SI 2 "input_operand" "rI")))
5808 (use (match_operand:SI 3 "register_operand" "r"))]
5809 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5810 "wr\t%%g0, %3, %%y\n\tsdiv\t%1, %2, %0"
5811 [(set_attr "type" "multi")
5812 (set_attr "length" "2")])
5814 (define_insn "divdi3"
5815 [(set (match_operand:DI 0 "register_operand" "=r")
5816 (div:DI (match_operand:DI 1 "register_operand" "r")
5817 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5820 [(set_attr "type" "idiv")])
5822 (define_insn "*cmp_sdiv_cc_set"
5824 (compare:CC (div:SI (match_operand:SI 1 "register_operand" "r")
5825 (match_operand:SI 2 "arith_operand" "rI"))
5827 (set (match_operand:SI 0 "register_operand" "=r")
5828 (div:SI (match_dup 1) (match_dup 2)))
5829 (clobber (match_scratch:SI 3 "=&r"))]
5830 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
5833 return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tsdivcc\t%1, %2, %0";
5835 return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tnop\n\tnop\n\tnop\n\tsdivcc\t%1, %2, %0";
5837 [(set_attr "type" "multi")
5838 (set (attr "length")
5839 (if_then_else (eq_attr "isa" "v9")
5840 (const_int 3) (const_int 6)))])
5843 (define_expand "udivsi3"
5844 [(set (match_operand:SI 0 "register_operand" "")
5845 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "")
5846 (match_operand:SI 2 "input_operand" "")))]
5847 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
5850 (define_insn "udivsi3_sp32"
5851 [(set (match_operand:SI 0 "register_operand" "=r,&r,&r")
5852 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "r,r,m")
5853 (match_operand:SI 2 "input_operand" "rI,m,r")))]
5855 || TARGET_DEPRECATED_V8_INSNS)
5858 output_asm_insn ("wr\t%%g0, %%g0, %%y", operands);
5859 switch (which_alternative)
5862 return "nop\n\tnop\n\tnop\n\tudiv\t%1, %2, %0";
5864 return "ld\t%2, %0\n\tnop\n\tnop\n\tudiv\t%1, %0, %0";
5866 return "ld\t%1, %0\n\tnop\n\tnop\n\tudiv\t%0, %2, %0";
5869 [(set_attr "type" "multi")
5870 (set_attr "length" "5")])
5872 (define_insn "udivsi3_sp64"
5873 [(set (match_operand:SI 0 "register_operand" "=r")
5874 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "r")
5875 (match_operand:SI 2 "input_operand" "rI")))]
5876 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5877 "wr\t%%g0, 0, %%y\n\tudiv\t%1, %2, %0"
5878 [(set_attr "type" "multi")
5879 (set_attr "length" "2")])
5881 (define_insn "udivdi3"
5882 [(set (match_operand:DI 0 "register_operand" "=r")
5883 (udiv:DI (match_operand:DI 1 "register_operand" "r")
5884 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5887 [(set_attr "type" "idiv")])
5889 (define_insn "*cmp_udiv_cc_set"
5891 (compare:CC (udiv:SI (match_operand:SI 1 "register_operand" "r")
5892 (match_operand:SI 2 "arith_operand" "rI"))
5894 (set (match_operand:SI 0 "register_operand" "=r")
5895 (udiv:SI (match_dup 1) (match_dup 2)))]
5897 || TARGET_DEPRECATED_V8_INSNS"
5900 return "wr\t%%g0, %%g0, %%y\n\tudivcc\t%1, %2, %0";
5902 return "wr\t%%g0, %%g0, %%y\n\tnop\n\tnop\n\tnop\n\tudivcc\t%1, %2, %0";
5904 [(set_attr "type" "multi")
5905 (set (attr "length")
5906 (if_then_else (eq_attr "isa" "v9")
5907 (const_int 2) (const_int 5)))])
5909 ; sparclet multiply/accumulate insns
5911 (define_insn "*smacsi"
5912 [(set (match_operand:SI 0 "register_operand" "=r")
5913 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "%r")
5914 (match_operand:SI 2 "arith_operand" "rI"))
5915 (match_operand:SI 3 "register_operand" "0")))]
5918 [(set_attr "type" "imul")])
5920 (define_insn "*smacdi"
5921 [(set (match_operand:DI 0 "register_operand" "=r")
5922 (plus:DI (mult:DI (sign_extend:DI
5923 (match_operand:SI 1 "register_operand" "%r"))
5925 (match_operand:SI 2 "register_operand" "r")))
5926 (match_operand:DI 3 "register_operand" "0")))]
5928 "smacd\t%1, %2, %L0"
5929 [(set_attr "type" "imul")])
5931 (define_insn "*umacdi"
5932 [(set (match_operand:DI 0 "register_operand" "=r")
5933 (plus:DI (mult:DI (zero_extend:DI
5934 (match_operand:SI 1 "register_operand" "%r"))
5936 (match_operand:SI 2 "register_operand" "r")))
5937 (match_operand:DI 3 "register_operand" "0")))]
5939 "umacd\t%1, %2, %L0"
5940 [(set_attr "type" "imul")])
5942 ;;- Boolean instructions
5943 ;; We define DImode `and' so with DImode `not' we can get
5944 ;; DImode `andn'. Other combinations are possible.
5946 (define_mode_macro V64I [DI V2SI V4HI V8QI])
5947 (define_mode_macro V32I [SI V2HI V4QI])
5949 (define_expand "and<V64I:mode>3"
5950 [(set (match_operand:V64I 0 "register_operand" "")
5951 (and:V64I (match_operand:V64I 1 "arith_double_operand" "")
5952 (match_operand:V64I 2 "arith_double_operand" "")))]
5956 (define_insn "*and<V64I:mode>3_sp32"
5957 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5958 (and:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
5959 (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
5964 [(set_attr "type" "*,fga")
5965 (set_attr "length" "2,*")
5966 (set_attr "fptype" "*,double")])
5968 (define_insn "*and<V64I:mode>3_sp64"
5969 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5970 (and:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
5971 (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
5976 [(set_attr "type" "*,fga")
5977 (set_attr "fptype" "*,double")])
5979 (define_insn "and<V32I:mode>3"
5980 [(set (match_operand:V32I 0 "register_operand" "=r,d")
5981 (and:V32I (match_operand:V32I 1 "arith_operand" "%r,d")
5982 (match_operand:V32I 2 "arith_operand" "rI,d")))]
5987 [(set_attr "type" "*,fga")
5988 (set_attr "fptype" "*,single")])
5991 [(set (match_operand:SI 0 "register_operand" "")
5992 (and:SI (match_operand:SI 1 "register_operand" "")
5993 (match_operand:SI 2 "" "")))
5994 (clobber (match_operand:SI 3 "register_operand" ""))]
5995 "GET_CODE (operands[2]) == CONST_INT
5996 && !SMALL_INT32 (operands[2])
5997 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
5998 [(set (match_dup 3) (match_dup 4))
5999 (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 1)))]
6001 operands[4] = GEN_INT (~INTVAL (operands[2]));
6004 (define_insn_and_split "*and_not_<V64I:mode>_sp32"
6005 [(set (match_operand:V64I 0 "register_operand" "=r,b")
6006 (and:V64I (not:V64I (match_operand:V64I 1 "register_operand" "%r,b"))
6007 (match_operand:V64I 2 "register_operand" "r,b")))]
6011 fandnot1\t%1, %2, %0"
6012 "&& reload_completed
6013 && ((GET_CODE (operands[0]) == REG
6014 && REGNO (operands[0]) < 32)
6015 || (GET_CODE (operands[0]) == SUBREG
6016 && GET_CODE (SUBREG_REG (operands[0])) == REG
6017 && REGNO (SUBREG_REG (operands[0])) < 32))"
6018 [(set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))
6019 (set (match_dup 6) (and:SI (not:SI (match_dup 7)) (match_dup 8)))]
6020 "operands[3] = gen_highpart (SImode, operands[0]);
6021 operands[4] = gen_highpart (SImode, operands[1]);
6022 operands[5] = gen_highpart (SImode, operands[2]);
6023 operands[6] = gen_lowpart (SImode, operands[0]);
6024 operands[7] = gen_lowpart (SImode, operands[1]);
6025 operands[8] = gen_lowpart (SImode, operands[2]);"
6026 [(set_attr "type" "*,fga")
6027 (set_attr "length" "2,*")
6028 (set_attr "fptype" "*,double")])
6030 (define_insn "*and_not_<V64I:mode>_sp64"
6031 [(set (match_operand:V64I 0 "register_operand" "=r,b")
6032 (and:V64I (not:V64I (match_operand:V64I 1 "register_operand" "%r,b"))
6033 (match_operand:V64I 2 "register_operand" "r,b")))]
6037 fandnot1\t%1, %2, %0"
6038 [(set_attr "type" "*,fga")
6039 (set_attr "fptype" "*,double")])
6041 (define_insn "*and_not_<V32I:mode>"
6042 [(set (match_operand:V32I 0 "register_operand" "=r,d")
6043 (and:V32I (not:V32I (match_operand:V32I 1 "register_operand" "%r,d"))
6044 (match_operand:V32I 2 "register_operand" "r,d")))]
6048 fandnot1s\t%1, %2, %0"
6049 [(set_attr "type" "*,fga")
6050 (set_attr "fptype" "*,single")])
6052 (define_expand "ior<V64I:mode>3"
6053 [(set (match_operand:V64I 0 "register_operand" "")
6054 (ior:V64I (match_operand:V64I 1 "arith_double_operand" "")
6055 (match_operand:V64I 2 "arith_double_operand" "")))]
6059 (define_insn "*ior<V64I:mode>3_sp32"
6060 [(set (match_operand:V64I 0 "register_operand" "=r,b")
6061 (ior:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
6062 (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
6067 [(set_attr "type" "*,fga")
6068 (set_attr "length" "2,*")
6069 (set_attr "fptype" "*,double")])
6071 (define_insn "*ior<V64I:mode>3_sp64"
6072 [(set (match_operand:V64I 0 "register_operand" "=r,b")
6073 (ior:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
6074 (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
6079 [(set_attr "type" "*,fga")
6080 (set_attr "fptype" "*,double")])
6082 (define_insn "ior<V32I:mode>3"
6083 [(set (match_operand:V32I 0 "register_operand" "=r,d")
6084 (ior:V32I (match_operand:V32I 1 "arith_operand" "%r,d")
6085 (match_operand:V32I 2 "arith_operand" "rI,d")))]
6090 [(set_attr "type" "*,fga")
6091 (set_attr "fptype" "*,single")])
6094 [(set (match_operand:SI 0 "register_operand" "")
6095 (ior:SI (match_operand:SI 1 "register_operand" "")
6096 (match_operand:SI 2 "" "")))
6097 (clobber (match_operand:SI 3 "register_operand" ""))]
6098 "GET_CODE (operands[2]) == CONST_INT
6099 && !SMALL_INT32 (operands[2])
6100 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6101 [(set (match_dup 3) (match_dup 4))
6102 (set (match_dup 0) (ior:SI (not:SI (match_dup 3)) (match_dup 1)))]
6104 operands[4] = GEN_INT (~INTVAL (operands[2]));
6107 (define_insn_and_split "*or_not_<V64I:mode>_sp32"
6108 [(set (match_operand:V64I 0 "register_operand" "=r,b")
6109 (ior:V64I (not:V64I (match_operand:V64I 1 "register_operand" "r,b"))
6110 (match_operand:V64I 2 "register_operand" "r,b")))]
6114 fornot1\t%1, %2, %0"
6115 "&& reload_completed
6116 && ((GET_CODE (operands[0]) == REG
6117 && REGNO (operands[0]) < 32)
6118 || (GET_CODE (operands[0]) == SUBREG
6119 && GET_CODE (SUBREG_REG (operands[0])) == REG
6120 && REGNO (SUBREG_REG (operands[0])) < 32))"
6121 [(set (match_dup 3) (ior:SI (not:SI (match_dup 4)) (match_dup 5)))
6122 (set (match_dup 6) (ior:SI (not:SI (match_dup 7)) (match_dup 8)))]
6123 "operands[3] = gen_highpart (SImode, operands[0]);
6124 operands[4] = gen_highpart (SImode, operands[1]);
6125 operands[5] = gen_highpart (SImode, operands[2]);
6126 operands[6] = gen_lowpart (SImode, operands[0]);
6127 operands[7] = gen_lowpart (SImode, operands[1]);
6128 operands[8] = gen_lowpart (SImode, operands[2]);"
6129 [(set_attr "type" "*,fga")
6130 (set_attr "length" "2,*")
6131 (set_attr "fptype" "*,double")])
6133 (define_insn "*or_not_<V64I:mode>_sp64"
6134 [(set (match_operand:V64I 0 "register_operand" "=r,b")
6135 (ior:V64I (not:V64I (match_operand:V64I 1 "register_operand" "r,b"))
6136 (match_operand:V64I 2 "register_operand" "r,b")))]
6140 fornot1\t%1, %2, %0"
6141 [(set_attr "type" "*,fga")
6142 (set_attr "fptype" "*,double")])
6144 (define_insn "*or_not_<V32I:mode>"
6145 [(set (match_operand:V32I 0 "register_operand" "=r,d")
6146 (ior:V32I (not:V32I (match_operand:V32I 1 "register_operand" "r,d"))
6147 (match_operand:V32I 2 "register_operand" "r,d")))]
6151 fornot1s\t%1, %2, %0"
6152 [(set_attr "type" "*,fga")
6153 (set_attr "fptype" "*,single")])
6155 (define_expand "xor<V64I:mode>3"
6156 [(set (match_operand:V64I 0 "register_operand" "")
6157 (xor:V64I (match_operand:V64I 1 "arith_double_operand" "")
6158 (match_operand:V64I 2 "arith_double_operand" "")))]
6162 (define_insn "*xor<V64I:mode>3_sp32"
6163 [(set (match_operand:V64I 0 "register_operand" "=r,b")
6164 (xor:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
6165 (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
6170 [(set_attr "type" "*,fga")
6171 (set_attr "length" "2,*")
6172 (set_attr "fptype" "*,double")])
6174 (define_insn "*xor<V64I:mode>3_sp64"
6175 [(set (match_operand:V64I 0 "register_operand" "=r,b")
6176 (xor:V64I (match_operand:V64I 1 "arith_double_operand" "%rJ,b")
6177 (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
6182 [(set_attr "type" "*,fga")
6183 (set_attr "fptype" "*,double")])
6185 (define_insn "*xordi3_sp64_dbl"
6186 [(set (match_operand:DI 0 "register_operand" "=r")
6187 (xor:DI (match_operand:DI 1 "register_operand" "r")
6188 (match_operand:DI 2 "const64_operand" "")))]
6190 && HOST_BITS_PER_WIDE_INT != 64)"
6193 (define_insn "xor<V32I:mode>3"
6194 [(set (match_operand:V32I 0 "register_operand" "=r,d")
6195 (xor:V32I (match_operand:V32I 1 "arith_operand" "%rJ,d")
6196 (match_operand:V32I 2 "arith_operand" "rI,d")))]
6201 [(set_attr "type" "*,fga")
6202 (set_attr "fptype" "*,single")])
6205 [(set (match_operand:SI 0 "register_operand" "")
6206 (xor:SI (match_operand:SI 1 "register_operand" "")
6207 (match_operand:SI 2 "" "")))
6208 (clobber (match_operand:SI 3 "register_operand" ""))]
6209 "GET_CODE (operands[2]) == CONST_INT
6210 && !SMALL_INT32 (operands[2])
6211 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6212 [(set (match_dup 3) (match_dup 4))
6213 (set (match_dup 0) (not:SI (xor:SI (match_dup 3) (match_dup 1))))]
6215 operands[4] = GEN_INT (~INTVAL (operands[2]));
6219 [(set (match_operand:SI 0 "register_operand" "")
6220 (not:SI (xor:SI (match_operand:SI 1 "register_operand" "")
6221 (match_operand:SI 2 "" ""))))
6222 (clobber (match_operand:SI 3 "register_operand" ""))]
6223 "GET_CODE (operands[2]) == CONST_INT
6224 && !SMALL_INT32 (operands[2])
6225 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6226 [(set (match_dup 3) (match_dup 4))
6227 (set (match_dup 0) (xor:SI (match_dup 3) (match_dup 1)))]
6229 operands[4] = GEN_INT (~INTVAL (operands[2]));
6232 ;; Split DImode logical operations requiring two instructions.
6234 [(set (match_operand:V64I 0 "register_operand" "")
6235 (match_operator:V64I 1 "cc_arithop" ; AND, IOR, XOR
6236 [(match_operand:V64I 2 "register_operand" "")
6237 (match_operand:V64I 3 "arith_double_operand" "")]))]
6240 && ((GET_CODE (operands[0]) == REG
6241 && REGNO (operands[0]) < 32)
6242 || (GET_CODE (operands[0]) == SUBREG
6243 && GET_CODE (SUBREG_REG (operands[0])) == REG
6244 && REGNO (SUBREG_REG (operands[0])) < 32))"
6245 [(set (match_dup 4) (match_op_dup:SI 1 [(match_dup 6) (match_dup 8)]))
6246 (set (match_dup 5) (match_op_dup:SI 1 [(match_dup 7) (match_dup 9)]))]
6248 operands[4] = gen_highpart (SImode, operands[0]);
6249 operands[5] = gen_lowpart (SImode, operands[0]);
6250 operands[6] = gen_highpart (SImode, operands[2]);
6251 operands[7] = gen_lowpart (SImode, operands[2]);
6252 #if HOST_BITS_PER_WIDE_INT == 32
6253 if (GET_CODE (operands[3]) == CONST_INT && <V64I:MODE>mode == DImode)
6255 if (INTVAL (operands[3]) < 0)
6256 operands[8] = constm1_rtx;
6258 operands[8] = const0_rtx;
6262 operands[8] = gen_highpart_mode (SImode, <V64I:MODE>mode, operands[3]);
6263 operands[9] = gen_lowpart (SImode, operands[3]);
6266 ;; xnor patterns. Note that (a ^ ~b) == (~a ^ b) == ~(a ^ b).
6267 ;; Combine now canonicalizes to the rightmost expression.
6268 (define_insn_and_split "*xor_not_<V64I:mode>_sp32"
6269 [(set (match_operand:V64I 0 "register_operand" "=r,b")
6270 (not:V64I (xor:V64I (match_operand:V64I 1 "register_operand" "r,b")
6271 (match_operand:V64I 2 "register_operand" "r,b"))))]
6276 "&& reload_completed
6277 && ((GET_CODE (operands[0]) == REG
6278 && REGNO (operands[0]) < 32)
6279 || (GET_CODE (operands[0]) == SUBREG
6280 && GET_CODE (SUBREG_REG (operands[0])) == REG
6281 && REGNO (SUBREG_REG (operands[0])) < 32))"
6282 [(set (match_dup 3) (not:SI (xor:SI (match_dup 4) (match_dup 5))))
6283 (set (match_dup 6) (not:SI (xor:SI (match_dup 7) (match_dup 8))))]
6284 "operands[3] = gen_highpart (SImode, operands[0]);
6285 operands[4] = gen_highpart (SImode, operands[1]);
6286 operands[5] = gen_highpart (SImode, operands[2]);
6287 operands[6] = gen_lowpart (SImode, operands[0]);
6288 operands[7] = gen_lowpart (SImode, operands[1]);
6289 operands[8] = gen_lowpart (SImode, operands[2]);"
6290 [(set_attr "type" "*,fga")
6291 (set_attr "length" "2,*")
6292 (set_attr "fptype" "*,double")])
6294 (define_insn "*xor_not_<V64I:mode>_sp64"
6295 [(set (match_operand:V64I 0 "register_operand" "=r,b")
6296 (not:V64I (xor:V64I (match_operand:V64I 1 "reg_or_0_operand" "rJ,b")
6297 (match_operand:V64I 2 "arith_double_operand" "rHI,b"))))]
6302 [(set_attr "type" "*,fga")
6303 (set_attr "fptype" "*,double")])
6305 (define_insn "*xor_not_<V32I:mode>"
6306 [(set (match_operand:V32I 0 "register_operand" "=r,d")
6307 (not:V32I (xor:V32I (match_operand:V32I 1 "reg_or_0_operand" "rJ,d")
6308 (match_operand:V32I 2 "arith_operand" "rI,d"))))]
6313 [(set_attr "type" "*,fga")
6314 (set_attr "fptype" "*,single")])
6316 ;; These correspond to the above in the case where we also (or only)
6317 ;; want to set the condition code.
6319 (define_insn "*cmp_cc_arith_op"
6322 (match_operator:SI 2 "cc_arithop"
6323 [(match_operand:SI 0 "arith_operand" "%r")
6324 (match_operand:SI 1 "arith_operand" "rI")])
6327 "%A2cc\t%0, %1, %%g0"
6328 [(set_attr "type" "compare")])
6330 (define_insn "*cmp_ccx_arith_op"
6333 (match_operator:DI 2 "cc_arithop"
6334 [(match_operand:DI 0 "arith_double_operand" "%r")
6335 (match_operand:DI 1 "arith_double_operand" "rHI")])
6338 "%A2cc\t%0, %1, %%g0"
6339 [(set_attr "type" "compare")])
6341 (define_insn "*cmp_cc_arith_op_set"
6344 (match_operator:SI 3 "cc_arithop"
6345 [(match_operand:SI 1 "arith_operand" "%r")
6346 (match_operand:SI 2 "arith_operand" "rI")])
6348 (set (match_operand:SI 0 "register_operand" "=r")
6349 (match_operator:SI 4 "cc_arithop" [(match_dup 1) (match_dup 2)]))]
6350 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
6352 [(set_attr "type" "compare")])
6354 (define_insn "*cmp_ccx_arith_op_set"
6357 (match_operator:DI 3 "cc_arithop"
6358 [(match_operand:DI 1 "arith_double_operand" "%r")
6359 (match_operand:DI 2 "arith_double_operand" "rHI")])
6361 (set (match_operand:DI 0 "register_operand" "=r")
6362 (match_operator:DI 4 "cc_arithop" [(match_dup 1) (match_dup 2)]))]
6363 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
6365 [(set_attr "type" "compare")])
6367 (define_insn "*cmp_cc_xor_not"
6370 (not:SI (xor:SI (match_operand:SI 0 "reg_or_0_operand" "%rJ")
6371 (match_operand:SI 1 "arith_operand" "rI")))
6374 "xnorcc\t%r0, %1, %%g0"
6375 [(set_attr "type" "compare")])
6377 (define_insn "*cmp_ccx_xor_not"
6380 (not:DI (xor:DI (match_operand:DI 0 "reg_or_0_operand" "%rJ")
6381 (match_operand:DI 1 "arith_double_operand" "rHI")))
6384 "xnorcc\t%r0, %1, %%g0"
6385 [(set_attr "type" "compare")])
6387 (define_insn "*cmp_cc_xor_not_set"
6390 (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
6391 (match_operand:SI 2 "arith_operand" "rI")))
6393 (set (match_operand:SI 0 "register_operand" "=r")
6394 (not:SI (xor:SI (match_dup 1) (match_dup 2))))]
6396 "xnorcc\t%r1, %2, %0"
6397 [(set_attr "type" "compare")])
6399 (define_insn "*cmp_ccx_xor_not_set"
6402 (not:DI (xor:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ")
6403 (match_operand:DI 2 "arith_double_operand" "rHI")))
6405 (set (match_operand:DI 0 "register_operand" "=r")
6406 (not:DI (xor:DI (match_dup 1) (match_dup 2))))]
6408 "xnorcc\t%r1, %2, %0"
6409 [(set_attr "type" "compare")])
6411 (define_insn "*cmp_cc_arith_op_not"
6414 (match_operator:SI 2 "cc_arithopn"
6415 [(not:SI (match_operand:SI 0 "arith_operand" "rI"))
6416 (match_operand:SI 1 "reg_or_0_operand" "rJ")])
6419 "%B2cc\t%r1, %0, %%g0"
6420 [(set_attr "type" "compare")])
6422 (define_insn "*cmp_ccx_arith_op_not"
6425 (match_operator:DI 2 "cc_arithopn"
6426 [(not:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
6427 (match_operand:DI 1 "reg_or_0_operand" "rJ")])
6430 "%B2cc\t%r1, %0, %%g0"
6431 [(set_attr "type" "compare")])
6433 (define_insn "*cmp_cc_arith_op_not_set"
6436 (match_operator:SI 3 "cc_arithopn"
6437 [(not:SI (match_operand:SI 1 "arith_operand" "rI"))
6438 (match_operand:SI 2 "reg_or_0_operand" "rJ")])
6440 (set (match_operand:SI 0 "register_operand" "=r")
6441 (match_operator:SI 4 "cc_arithopn"
6442 [(not:SI (match_dup 1)) (match_dup 2)]))]
6443 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
6444 "%B3cc\t%r2, %1, %0"
6445 [(set_attr "type" "compare")])
6447 (define_insn "*cmp_ccx_arith_op_not_set"
6450 (match_operator:DI 3 "cc_arithopn"
6451 [(not:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
6452 (match_operand:DI 2 "reg_or_0_operand" "rJ")])
6454 (set (match_operand:DI 0 "register_operand" "=r")
6455 (match_operator:DI 4 "cc_arithopn"
6456 [(not:DI (match_dup 1)) (match_dup 2)]))]
6457 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
6458 "%B3cc\t%r2, %1, %0"
6459 [(set_attr "type" "compare")])
6461 ;; We cannot use the "neg" pseudo insn because the Sun assembler
6462 ;; does not know how to make it work for constants.
6464 (define_expand "negdi2"
6465 [(set (match_operand:DI 0 "register_operand" "=r")
6466 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
6469 if (! TARGET_ARCH64)
6471 emit_insn (gen_rtx_PARALLEL
6474 gen_rtx_SET (VOIDmode, operand0,
6475 gen_rtx_NEG (DImode, operand1)),
6476 gen_rtx_CLOBBER (VOIDmode,
6477 gen_rtx_REG (CCmode,
6483 (define_insn_and_split "*negdi2_sp32"
6484 [(set (match_operand:DI 0 "register_operand" "=r")
6485 (neg:DI (match_operand:DI 1 "register_operand" "r")))
6486 (clobber (reg:CC 100))]
6489 "&& reload_completed"
6490 [(parallel [(set (reg:CC_NOOV 100)
6491 (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 5))
6493 (set (match_dup 4) (minus:SI (const_int 0) (match_dup 5)))])
6494 (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
6495 (ltu:SI (reg:CC 100) (const_int 0))))]
6496 "operands[2] = gen_highpart (SImode, operands[0]);
6497 operands[3] = gen_highpart (SImode, operands[1]);
6498 operands[4] = gen_lowpart (SImode, operands[0]);
6499 operands[5] = gen_lowpart (SImode, operands[1]);"
6500 [(set_attr "length" "2")])
6502 (define_insn "*negdi2_sp64"
6503 [(set (match_operand:DI 0 "register_operand" "=r")
6504 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
6506 "sub\t%%g0, %1, %0")
6508 (define_insn "negsi2"
6509 [(set (match_operand:SI 0 "register_operand" "=r")
6510 (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
6512 "sub\t%%g0, %1, %0")
6514 (define_insn "*cmp_cc_neg"
6515 [(set (reg:CC_NOOV 100)
6516 (compare:CC_NOOV (neg:SI (match_operand:SI 0 "arith_operand" "rI"))
6519 "subcc\t%%g0, %0, %%g0"
6520 [(set_attr "type" "compare")])
6522 (define_insn "*cmp_ccx_neg"
6523 [(set (reg:CCX_NOOV 100)
6524 (compare:CCX_NOOV (neg:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
6527 "subcc\t%%g0, %0, %%g0"
6528 [(set_attr "type" "compare")])
6530 (define_insn "*cmp_cc_set_neg"
6531 [(set (reg:CC_NOOV 100)
6532 (compare:CC_NOOV (neg:SI (match_operand:SI 1 "arith_operand" "rI"))
6534 (set (match_operand:SI 0 "register_operand" "=r")
6535 (neg:SI (match_dup 1)))]
6537 "subcc\t%%g0, %1, %0"
6538 [(set_attr "type" "compare")])
6540 (define_insn "*cmp_ccx_set_neg"
6541 [(set (reg:CCX_NOOV 100)
6542 (compare:CCX_NOOV (neg:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
6544 (set (match_operand:DI 0 "register_operand" "=r")
6545 (neg:DI (match_dup 1)))]
6547 "subcc\t%%g0, %1, %0"
6548 [(set_attr "type" "compare")])
6550 ;; We cannot use the "not" pseudo insn because the Sun assembler
6551 ;; does not know how to make it work for constants.
6552 (define_expand "one_cmpl<V64I:mode>2"
6553 [(set (match_operand:V64I 0 "register_operand" "")
6554 (not:V64I (match_operand:V64I 1 "register_operand" "")))]
6558 (define_insn_and_split "*one_cmpl<V64I:mode>2_sp32"
6559 [(set (match_operand:V64I 0 "register_operand" "=r,b")
6560 (not:V64I (match_operand:V64I 1 "register_operand" "r,b")))]
6565 "&& reload_completed
6566 && ((GET_CODE (operands[0]) == REG
6567 && REGNO (operands[0]) < 32)
6568 || (GET_CODE (operands[0]) == SUBREG
6569 && GET_CODE (SUBREG_REG (operands[0])) == REG
6570 && REGNO (SUBREG_REG (operands[0])) < 32))"
6571 [(set (match_dup 2) (not:SI (xor:SI (match_dup 3) (const_int 0))))
6572 (set (match_dup 4) (not:SI (xor:SI (match_dup 5) (const_int 0))))]
6573 "operands[2] = gen_highpart (SImode, operands[0]);
6574 operands[3] = gen_highpart (SImode, operands[1]);
6575 operands[4] = gen_lowpart (SImode, operands[0]);
6576 operands[5] = gen_lowpart (SImode, operands[1]);"
6577 [(set_attr "type" "*,fga")
6578 (set_attr "length" "2,*")
6579 (set_attr "fptype" "*,double")])
6581 (define_insn "*one_cmpl<V64I:mode>2_sp64"
6582 [(set (match_operand:V64I 0 "register_operand" "=r,b")
6583 (not:V64I (match_operand:V64I 1 "arith_double_operand" "rHI,b")))]
6588 [(set_attr "type" "*,fga")
6589 (set_attr "fptype" "*,double")])
6591 (define_insn "one_cmpl<V32I:mode>2"
6592 [(set (match_operand:V32I 0 "register_operand" "=r,d")
6593 (not:V32I (match_operand:V32I 1 "arith_operand" "rI,d")))]
6598 [(set_attr "type" "*,fga")
6599 (set_attr "fptype" "*,single")])
6601 (define_insn "*cmp_cc_not"
6603 (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI"))
6606 "xnorcc\t%%g0, %0, %%g0"
6607 [(set_attr "type" "compare")])
6609 (define_insn "*cmp_ccx_not"
6611 (compare:CCX (not:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
6614 "xnorcc\t%%g0, %0, %%g0"
6615 [(set_attr "type" "compare")])
6617 (define_insn "*cmp_cc_set_not"
6619 (compare:CC (not:SI (match_operand:SI 1 "arith_operand" "rI"))
6621 (set (match_operand:SI 0 "register_operand" "=r")
6622 (not:SI (match_dup 1)))]
6624 "xnorcc\t%%g0, %1, %0"
6625 [(set_attr "type" "compare")])
6627 (define_insn "*cmp_ccx_set_not"
6629 (compare:CCX (not:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
6631 (set (match_operand:DI 0 "register_operand" "=r")
6632 (not:DI (match_dup 1)))]
6634 "xnorcc\t%%g0, %1, %0"
6635 [(set_attr "type" "compare")])
6637 (define_insn "*cmp_cc_set"
6638 [(set (match_operand:SI 0 "register_operand" "=r")
6639 (match_operand:SI 1 "register_operand" "r"))
6641 (compare:CC (match_dup 1)
6645 [(set_attr "type" "compare")])
6647 (define_insn "*cmp_ccx_set64"
6648 [(set (match_operand:DI 0 "register_operand" "=r")
6649 (match_operand:DI 1 "register_operand" "r"))
6651 (compare:CCX (match_dup 1)
6655 [(set_attr "type" "compare")])
6657 ;; Floating point arithmetic instructions.
6659 (define_expand "addtf3"
6660 [(set (match_operand:TF 0 "nonimmediate_operand" "")
6661 (plus:TF (match_operand:TF 1 "general_operand" "")
6662 (match_operand:TF 2 "general_operand" "")))]
6663 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6664 "emit_tfmode_binop (PLUS, operands); DONE;")
6666 (define_insn "*addtf3_hq"
6667 [(set (match_operand:TF 0 "register_operand" "=e")
6668 (plus:TF (match_operand:TF 1 "register_operand" "e")
6669 (match_operand:TF 2 "register_operand" "e")))]
6670 "TARGET_FPU && TARGET_HARD_QUAD"
6672 [(set_attr "type" "fp")])
6674 (define_insn "adddf3"
6675 [(set (match_operand:DF 0 "register_operand" "=e")
6676 (plus:DF (match_operand:DF 1 "register_operand" "e")
6677 (match_operand:DF 2 "register_operand" "e")))]
6680 [(set_attr "type" "fp")
6681 (set_attr "fptype" "double")])
6683 (define_insn "addsf3"
6684 [(set (match_operand:SF 0 "register_operand" "=f")
6685 (plus:SF (match_operand:SF 1 "register_operand" "f")
6686 (match_operand:SF 2 "register_operand" "f")))]
6689 [(set_attr "type" "fp")])
6691 (define_expand "subtf3"
6692 [(set (match_operand:TF 0 "nonimmediate_operand" "")
6693 (minus:TF (match_operand:TF 1 "general_operand" "")
6694 (match_operand:TF 2 "general_operand" "")))]
6695 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6696 "emit_tfmode_binop (MINUS, operands); DONE;")
6698 (define_insn "*subtf3_hq"
6699 [(set (match_operand:TF 0 "register_operand" "=e")
6700 (minus:TF (match_operand:TF 1 "register_operand" "e")
6701 (match_operand:TF 2 "register_operand" "e")))]
6702 "TARGET_FPU && TARGET_HARD_QUAD"
6704 [(set_attr "type" "fp")])
6706 (define_insn "subdf3"
6707 [(set (match_operand:DF 0 "register_operand" "=e")
6708 (minus:DF (match_operand:DF 1 "register_operand" "e")
6709 (match_operand:DF 2 "register_operand" "e")))]
6712 [(set_attr "type" "fp")
6713 (set_attr "fptype" "double")])
6715 (define_insn "subsf3"
6716 [(set (match_operand:SF 0 "register_operand" "=f")
6717 (minus:SF (match_operand:SF 1 "register_operand" "f")
6718 (match_operand:SF 2 "register_operand" "f")))]
6721 [(set_attr "type" "fp")])
6723 (define_expand "multf3"
6724 [(set (match_operand:TF 0 "nonimmediate_operand" "")
6725 (mult:TF (match_operand:TF 1 "general_operand" "")
6726 (match_operand:TF 2 "general_operand" "")))]
6727 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6728 "emit_tfmode_binop (MULT, operands); DONE;")
6730 (define_insn "*multf3_hq"
6731 [(set (match_operand:TF 0 "register_operand" "=e")
6732 (mult:TF (match_operand:TF 1 "register_operand" "e")
6733 (match_operand:TF 2 "register_operand" "e")))]
6734 "TARGET_FPU && TARGET_HARD_QUAD"
6736 [(set_attr "type" "fpmul")])
6738 (define_insn "muldf3"
6739 [(set (match_operand:DF 0 "register_operand" "=e")
6740 (mult:DF (match_operand:DF 1 "register_operand" "e")
6741 (match_operand:DF 2 "register_operand" "e")))]
6744 [(set_attr "type" "fpmul")
6745 (set_attr "fptype" "double")])
6747 (define_insn "mulsf3"
6748 [(set (match_operand:SF 0 "register_operand" "=f")
6749 (mult:SF (match_operand:SF 1 "register_operand" "f")
6750 (match_operand:SF 2 "register_operand" "f")))]
6753 [(set_attr "type" "fpmul")])
6755 (define_insn "*muldf3_extend"
6756 [(set (match_operand:DF 0 "register_operand" "=e")
6757 (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "f"))
6758 (float_extend:DF (match_operand:SF 2 "register_operand" "f"))))]
6759 "(TARGET_V8 || TARGET_V9) && TARGET_FPU"
6760 "fsmuld\t%1, %2, %0"
6761 [(set_attr "type" "fpmul")
6762 (set_attr "fptype" "double")])
6764 (define_insn "*multf3_extend"
6765 [(set (match_operand:TF 0 "register_operand" "=e")
6766 (mult:TF (float_extend:TF (match_operand:DF 1 "register_operand" "e"))
6767 (float_extend:TF (match_operand:DF 2 "register_operand" "e"))))]
6768 "(TARGET_V8 || TARGET_V9) && TARGET_FPU && TARGET_HARD_QUAD"
6769 "fdmulq\t%1, %2, %0"
6770 [(set_attr "type" "fpmul")])
6772 (define_expand "divtf3"
6773 [(set (match_operand:TF 0 "nonimmediate_operand" "")
6774 (div:TF (match_operand:TF 1 "general_operand" "")
6775 (match_operand:TF 2 "general_operand" "")))]
6776 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6777 "emit_tfmode_binop (DIV, operands); DONE;")
6779 ;; don't have timing for quad-prec. divide.
6780 (define_insn "*divtf3_hq"
6781 [(set (match_operand:TF 0 "register_operand" "=e")
6782 (div:TF (match_operand:TF 1 "register_operand" "e")
6783 (match_operand:TF 2 "register_operand" "e")))]
6784 "TARGET_FPU && TARGET_HARD_QUAD"
6786 [(set_attr "type" "fpdivd")])
6788 (define_insn "divdf3"
6789 [(set (match_operand:DF 0 "register_operand" "=e")
6790 (div:DF (match_operand:DF 1 "register_operand" "e")
6791 (match_operand:DF 2 "register_operand" "e")))]
6794 [(set_attr "type" "fpdivd")
6795 (set_attr "fptype" "double")])
6797 (define_insn "divsf3"
6798 [(set (match_operand:SF 0 "register_operand" "=f")
6799 (div:SF (match_operand:SF 1 "register_operand" "f")
6800 (match_operand:SF 2 "register_operand" "f")))]
6803 [(set_attr "type" "fpdivs")])
6805 (define_expand "negtf2"
6806 [(set (match_operand:TF 0 "register_operand" "=e,e")
6807 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
6811 (define_insn_and_split "*negtf2_notv9"
6812 [(set (match_operand:TF 0 "register_operand" "=e,e")
6813 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
6814 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
6820 "&& reload_completed
6821 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6822 [(set (match_dup 2) (neg:SF (match_dup 3)))
6823 (set (match_dup 4) (match_dup 5))
6824 (set (match_dup 6) (match_dup 7))]
6825 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6826 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6827 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6828 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
6829 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6830 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6831 [(set_attr "type" "fpmove,*")
6832 (set_attr "length" "*,2")])
6834 (define_insn_and_split "*negtf2_v9"
6835 [(set (match_operand:TF 0 "register_operand" "=e,e")
6836 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
6837 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
6838 "TARGET_FPU && TARGET_V9"
6842 "&& reload_completed
6843 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6844 [(set (match_dup 2) (neg:DF (match_dup 3)))
6845 (set (match_dup 4) (match_dup 5))]
6846 "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
6847 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
6848 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6849 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6850 [(set_attr "type" "fpmove,*")
6851 (set_attr "length" "*,2")
6852 (set_attr "fptype" "double")])
6854 (define_expand "negdf2"
6855 [(set (match_operand:DF 0 "register_operand" "")
6856 (neg:DF (match_operand:DF 1 "register_operand" "")))]
6860 (define_insn_and_split "*negdf2_notv9"
6861 [(set (match_operand:DF 0 "register_operand" "=e,e")
6862 (neg:DF (match_operand:DF 1 "register_operand" "0,e")))]
6863 "TARGET_FPU && ! TARGET_V9"
6867 "&& reload_completed
6868 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6869 [(set (match_dup 2) (neg:SF (match_dup 3)))
6870 (set (match_dup 4) (match_dup 5))]
6871 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6872 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6873 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6874 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);"
6875 [(set_attr "type" "fpmove,*")
6876 (set_attr "length" "*,2")])
6878 (define_insn "*negdf2_v9"
6879 [(set (match_operand:DF 0 "register_operand" "=e")
6880 (neg:DF (match_operand:DF 1 "register_operand" "e")))]
6881 "TARGET_FPU && TARGET_V9"
6883 [(set_attr "type" "fpmove")
6884 (set_attr "fptype" "double")])
6886 (define_insn "negsf2"
6887 [(set (match_operand:SF 0 "register_operand" "=f")
6888 (neg:SF (match_operand:SF 1 "register_operand" "f")))]
6891 [(set_attr "type" "fpmove")])
6893 (define_expand "abstf2"
6894 [(set (match_operand:TF 0 "register_operand" "")
6895 (abs:TF (match_operand:TF 1 "register_operand" "")))]
6899 (define_insn_and_split "*abstf2_notv9"
6900 [(set (match_operand:TF 0 "register_operand" "=e,e")
6901 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6902 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
6903 "TARGET_FPU && ! TARGET_V9"
6907 "&& reload_completed
6908 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6909 [(set (match_dup 2) (abs:SF (match_dup 3)))
6910 (set (match_dup 4) (match_dup 5))
6911 (set (match_dup 6) (match_dup 7))]
6912 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6913 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6914 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6915 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
6916 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6917 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6918 [(set_attr "type" "fpmove,*")
6919 (set_attr "length" "*,2")])
6921 (define_insn "*abstf2_hq_v9"
6922 [(set (match_operand:TF 0 "register_operand" "=e,e")
6923 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6924 "TARGET_FPU && TARGET_V9 && TARGET_HARD_QUAD"
6928 [(set_attr "type" "fpmove")
6929 (set_attr "fptype" "double,*")])
6931 (define_insn_and_split "*abstf2_v9"
6932 [(set (match_operand:TF 0 "register_operand" "=e,e")
6933 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6934 "TARGET_FPU && TARGET_V9 && !TARGET_HARD_QUAD"
6938 "&& reload_completed
6939 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6940 [(set (match_dup 2) (abs:DF (match_dup 3)))
6941 (set (match_dup 4) (match_dup 5))]
6942 "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
6943 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
6944 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6945 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6946 [(set_attr "type" "fpmove,*")
6947 (set_attr "length" "*,2")
6948 (set_attr "fptype" "double,*")])
6950 (define_expand "absdf2"
6951 [(set (match_operand:DF 0 "register_operand" "")
6952 (abs:DF (match_operand:DF 1 "register_operand" "")))]
6956 (define_insn_and_split "*absdf2_notv9"
6957 [(set (match_operand:DF 0 "register_operand" "=e,e")
6958 (abs:DF (match_operand:DF 1 "register_operand" "0,e")))]
6959 "TARGET_FPU && ! TARGET_V9"
6963 "&& reload_completed
6964 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6965 [(set (match_dup 2) (abs:SF (match_dup 3)))
6966 (set (match_dup 4) (match_dup 5))]
6967 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6968 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6969 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6970 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);"
6971 [(set_attr "type" "fpmove,*")
6972 (set_attr "length" "*,2")])
6974 (define_insn "*absdf2_v9"
6975 [(set (match_operand:DF 0 "register_operand" "=e")
6976 (abs:DF (match_operand:DF 1 "register_operand" "e")))]
6977 "TARGET_FPU && TARGET_V9"
6979 [(set_attr "type" "fpmove")
6980 (set_attr "fptype" "double")])
6982 (define_insn "abssf2"
6983 [(set (match_operand:SF 0 "register_operand" "=f")
6984 (abs:SF (match_operand:SF 1 "register_operand" "f")))]
6987 [(set_attr "type" "fpmove")])
6989 (define_expand "sqrttf2"
6990 [(set (match_operand:TF 0 "nonimmediate_operand" "")
6991 (sqrt:TF (match_operand:TF 1 "general_operand" "")))]
6992 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6993 "emit_tfmode_unop (SQRT, operands); DONE;")
6995 (define_insn "*sqrttf2_hq"
6996 [(set (match_operand:TF 0 "register_operand" "=e")
6997 (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
6998 "TARGET_FPU && TARGET_HARD_QUAD"
7000 [(set_attr "type" "fpsqrtd")])
7002 (define_insn "sqrtdf2"
7003 [(set (match_operand:DF 0 "register_operand" "=e")
7004 (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
7007 [(set_attr "type" "fpsqrtd")
7008 (set_attr "fptype" "double")])
7010 (define_insn "sqrtsf2"
7011 [(set (match_operand:SF 0 "register_operand" "=f")
7012 (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
7015 [(set_attr "type" "fpsqrts")])
7017 ;;- arithmetic shift instructions
7019 (define_insn "ashlsi3"
7020 [(set (match_operand:SI 0 "register_operand" "=r")
7021 (ashift:SI (match_operand:SI 1 "register_operand" "r")
7022 (match_operand:SI 2 "arith_operand" "rI")))]
7025 if (GET_CODE (operands[2]) == CONST_INT)
7026 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
7027 return "sll\t%1, %2, %0";
7030 (if_then_else (match_operand 2 "const1_operand" "")
7031 (const_string "ialu") (const_string "shift")))])
7033 (define_expand "ashldi3"
7034 [(set (match_operand:DI 0 "register_operand" "=r")
7035 (ashift:DI (match_operand:DI 1 "register_operand" "r")
7036 (match_operand:SI 2 "arith_operand" "rI")))]
7037 "TARGET_ARCH64 || TARGET_V8PLUS"
7039 if (! TARGET_ARCH64)
7041 if (GET_CODE (operands[2]) == CONST_INT)
7043 emit_insn (gen_ashldi3_v8plus (operands[0], operands[1], operands[2]));
7048 (define_insn "*ashldi3_sp64"
7049 [(set (match_operand:DI 0 "register_operand" "=r")
7050 (ashift:DI (match_operand:DI 1 "register_operand" "r")
7051 (match_operand:SI 2 "arith_operand" "rI")))]
7054 if (GET_CODE (operands[2]) == CONST_INT)
7055 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
7056 return "sllx\t%1, %2, %0";
7059 (if_then_else (match_operand 2 "const1_operand" "")
7060 (const_string "ialu") (const_string "shift")))])
7063 (define_insn "ashldi3_v8plus"
7064 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
7065 (ashift:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
7066 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
7067 (clobber (match_scratch:SI 3 "=X,X,&h"))]
7069 "* return output_v8plus_shift (operands, insn, \"sllx\");"
7070 [(set_attr "type" "multi")
7071 (set_attr "length" "5,5,6")])
7073 ;; Optimize (1LL<<x)-1
7074 ;; XXX this also needs to be fixed to handle equal subregs
7075 ;; XXX first before we could re-enable it.
7077 ; [(set (match_operand:DI 0 "register_operand" "=h")
7078 ; (plus:DI (ashift:DI (const_int 1)
7079 ; (match_operand:SI 1 "arith_operand" "rI"))
7081 ; "0 && TARGET_V8PLUS"
7083 ; if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == REGNO (operands[0]))
7084 ; return "mov\t1, %L0\;sllx\t%L0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
7085 ; return "mov\t1, %H0\;sllx\t%H0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
7087 ; [(set_attr "type" "multi")
7088 ; (set_attr "length" "4")])
7090 (define_insn "*cmp_cc_ashift_1"
7091 [(set (reg:CC_NOOV 100)
7092 (compare:CC_NOOV (ashift:SI (match_operand:SI 0 "register_operand" "r")
7096 "addcc\t%0, %0, %%g0"
7097 [(set_attr "type" "compare")])
7099 (define_insn "*cmp_cc_set_ashift_1"
7100 [(set (reg:CC_NOOV 100)
7101 (compare:CC_NOOV (ashift:SI (match_operand:SI 1 "register_operand" "r")
7104 (set (match_operand:SI 0 "register_operand" "=r")
7105 (ashift:SI (match_dup 1) (const_int 1)))]
7108 [(set_attr "type" "compare")])
7110 (define_insn "ashrsi3"
7111 [(set (match_operand:SI 0 "register_operand" "=r")
7112 (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
7113 (match_operand:SI 2 "arith_operand" "rI")))]
7116 if (GET_CODE (operands[2]) == CONST_INT)
7117 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
7118 return "sra\t%1, %2, %0";
7120 [(set_attr "type" "shift")])
7122 (define_insn "*ashrsi3_extend"
7123 [(set (match_operand:DI 0 "register_operand" "=r")
7124 (sign_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
7125 (match_operand:SI 2 "arith_operand" "r"))))]
7128 [(set_attr "type" "shift")])
7130 ;; This handles the case as above, but with constant shift instead of
7131 ;; register. Combiner "simplifies" it for us a little bit though.
7132 (define_insn "*ashrsi3_extend2"
7133 [(set (match_operand:DI 0 "register_operand" "=r")
7134 (ashiftrt:DI (ashift:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
7136 (match_operand:SI 2 "small_int_or_double" "n")))]
7138 && ((GET_CODE (operands[2]) == CONST_INT
7139 && INTVAL (operands[2]) >= 32 && INTVAL (operands[2]) < 64)
7140 || (GET_CODE (operands[2]) == CONST_DOUBLE
7141 && !CONST_DOUBLE_HIGH (operands[2])
7142 && CONST_DOUBLE_LOW (operands[2]) >= 32
7143 && CONST_DOUBLE_LOW (operands[2]) < 64))"
7145 operands[2] = GEN_INT (INTVAL (operands[2]) - 32);
7147 return "sra\t%1, %2, %0";
7149 [(set_attr "type" "shift")])
7151 (define_expand "ashrdi3"
7152 [(set (match_operand:DI 0 "register_operand" "=r")
7153 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
7154 (match_operand:SI 2 "arith_operand" "rI")))]
7155 "TARGET_ARCH64 || TARGET_V8PLUS"
7157 if (! TARGET_ARCH64)
7159 if (GET_CODE (operands[2]) == CONST_INT)
7160 FAIL; /* prefer generic code in this case */
7161 emit_insn (gen_ashrdi3_v8plus (operands[0], operands[1], operands[2]));
7166 (define_insn "*ashrdi3_sp64"
7167 [(set (match_operand:DI 0 "register_operand" "=r")
7168 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
7169 (match_operand:SI 2 "arith_operand" "rI")))]
7173 if (GET_CODE (operands[2]) == CONST_INT)
7174 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
7175 return "srax\t%1, %2, %0";
7177 [(set_attr "type" "shift")])
7180 (define_insn "ashrdi3_v8plus"
7181 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
7182 (ashiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
7183 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
7184 (clobber (match_scratch:SI 3 "=X,X,&h"))]
7186 "* return output_v8plus_shift (operands, insn, \"srax\");"
7187 [(set_attr "type" "multi")
7188 (set_attr "length" "5,5,6")])
7190 (define_insn "lshrsi3"
7191 [(set (match_operand:SI 0 "register_operand" "=r")
7192 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
7193 (match_operand:SI 2 "arith_operand" "rI")))]
7196 if (GET_CODE (operands[2]) == CONST_INT)
7197 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
7198 return "srl\t%1, %2, %0";
7200 [(set_attr "type" "shift")])
7202 ;; This handles the case where
7203 ;; (zero_extend:DI (lshiftrt:SI (match_operand:SI) (match_operand:SI))),
7204 ;; but combiner "simplifies" it for us.
7205 (define_insn "*lshrsi3_extend"
7206 [(set (match_operand:DI 0 "register_operand" "=r")
7207 (and:DI (subreg:DI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
7208 (match_operand:SI 2 "arith_operand" "r")) 0)
7209 (match_operand 3 "" "")))]
7211 && ((GET_CODE (operands[3]) == CONST_DOUBLE
7212 && CONST_DOUBLE_HIGH (operands[3]) == 0
7213 && CONST_DOUBLE_LOW (operands[3]) == 0xffffffff)
7214 || (HOST_BITS_PER_WIDE_INT >= 64
7215 && GET_CODE (operands[3]) == CONST_INT
7216 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) == 0xffffffff))"
7218 [(set_attr "type" "shift")])
7220 ;; This handles the case where
7221 ;; (lshiftrt:DI (zero_extend:DI (match_operand:SI)) (const_int >=0 < 32))
7222 ;; but combiner "simplifies" it for us.
7223 (define_insn "*lshrsi3_extend2"
7224 [(set (match_operand:DI 0 "register_operand" "=r")
7225 (zero_extract:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
7226 (match_operand 2 "small_int_or_double" "n")
7229 && ((GET_CODE (operands[2]) == CONST_INT
7230 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
7231 || (GET_CODE (operands[2]) == CONST_DOUBLE
7232 && CONST_DOUBLE_HIGH (operands[2]) == 0
7233 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
7235 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
7237 return "srl\t%1, %2, %0";
7239 [(set_attr "type" "shift")])
7241 (define_expand "lshrdi3"
7242 [(set (match_operand:DI 0 "register_operand" "=r")
7243 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
7244 (match_operand:SI 2 "arith_operand" "rI")))]
7245 "TARGET_ARCH64 || TARGET_V8PLUS"
7247 if (! TARGET_ARCH64)
7249 if (GET_CODE (operands[2]) == CONST_INT)
7251 emit_insn (gen_lshrdi3_v8plus (operands[0], operands[1], operands[2]));
7256 (define_insn "*lshrdi3_sp64"
7257 [(set (match_operand:DI 0 "register_operand" "=r")
7258 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
7259 (match_operand:SI 2 "arith_operand" "rI")))]
7262 if (GET_CODE (operands[2]) == CONST_INT)
7263 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
7264 return "srlx\t%1, %2, %0";
7266 [(set_attr "type" "shift")])
7269 (define_insn "lshrdi3_v8plus"
7270 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
7271 (lshiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
7272 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
7273 (clobber (match_scratch:SI 3 "=X,X,&h"))]
7275 "* return output_v8plus_shift (operands, insn, \"srlx\");"
7276 [(set_attr "type" "multi")
7277 (set_attr "length" "5,5,6")])
7280 [(set (match_operand:SI 0 "register_operand" "=r")
7281 (ashiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
7283 (match_operand:SI 2 "small_int_or_double" "n")))]
7285 && ((GET_CODE (operands[2]) == CONST_INT
7286 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
7287 || (GET_CODE (operands[2]) == CONST_DOUBLE
7288 && !CONST_DOUBLE_HIGH (operands[2])
7289 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
7291 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
7293 return "srax\t%1, %2, %0";
7295 [(set_attr "type" "shift")])
7298 [(set (match_operand:SI 0 "register_operand" "=r")
7299 (lshiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
7301 (match_operand:SI 2 "small_int_or_double" "n")))]
7303 && ((GET_CODE (operands[2]) == CONST_INT
7304 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
7305 || (GET_CODE (operands[2]) == CONST_DOUBLE
7306 && !CONST_DOUBLE_HIGH (operands[2])
7307 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
7309 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
7311 return "srlx\t%1, %2, %0";
7313 [(set_attr "type" "shift")])
7316 [(set (match_operand:SI 0 "register_operand" "=r")
7317 (ashiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
7318 (match_operand:SI 2 "small_int_or_double" "n")) 4)
7319 (match_operand:SI 3 "small_int_or_double" "n")))]
7321 && GET_CODE (operands[2]) == CONST_INT && GET_CODE (operands[3]) == CONST_INT
7322 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
7323 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
7324 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
7326 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
7328 return "srax\t%1, %2, %0";
7330 [(set_attr "type" "shift")])
7333 [(set (match_operand:SI 0 "register_operand" "=r")
7334 (lshiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
7335 (match_operand:SI 2 "small_int_or_double" "n")) 4)
7336 (match_operand:SI 3 "small_int_or_double" "n")))]
7338 && GET_CODE (operands[2]) == CONST_INT && GET_CODE (operands[3]) == CONST_INT
7339 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
7340 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
7341 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
7343 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
7345 return "srlx\t%1, %2, %0";
7347 [(set_attr "type" "shift")])
7349 ;; Unconditional and other jump instructions
7351 [(set (pc) (label_ref (match_operand 0 "" "")))]
7353 "* return output_ubranch (operands[0], 0, insn);"
7354 [(set_attr "type" "uncond_branch")])
7356 (define_expand "tablejump"
7357 [(parallel [(set (pc) (match_operand 0 "register_operand" "r"))
7358 (use (label_ref (match_operand 1 "" "")))])]
7361 if (GET_MODE (operands[0]) != CASE_VECTOR_MODE)
7364 /* In pic mode, our address differences are against the base of the
7365 table. Add that base value back in; CSE ought to be able to combine
7366 the two address loads. */
7370 tmp = gen_rtx_LABEL_REF (Pmode, operands[1]);
7372 if (CASE_VECTOR_MODE != Pmode)
7373 tmp2 = gen_rtx_SIGN_EXTEND (Pmode, tmp2);
7374 tmp = gen_rtx_PLUS (Pmode, tmp2, tmp);
7375 operands[0] = memory_address (Pmode, tmp);
7379 (define_insn "*tablejump_sp32"
7380 [(set (pc) (match_operand:SI 0 "address_operand" "p"))
7381 (use (label_ref (match_operand 1 "" "")))]
7384 [(set_attr "type" "uncond_branch")])
7386 (define_insn "*tablejump_sp64"
7387 [(set (pc) (match_operand:DI 0 "address_operand" "p"))
7388 (use (label_ref (match_operand 1 "" "")))]
7391 [(set_attr "type" "uncond_branch")])
7393 ;;- jump to subroutine
7394 (define_expand "call"
7395 ;; Note that this expression is not used for generating RTL.
7396 ;; All the RTL is generated explicitly below.
7397 [(call (match_operand 0 "call_operand" "")
7398 (match_operand 3 "" "i"))]
7399 ;; operands[2] is next_arg_register
7400 ;; operands[3] is struct_value_size_rtx.
7405 if (GET_MODE (operands[0]) != FUNCTION_MODE)
7408 if (GET_CODE (operands[3]) != CONST_INT)
7411 if (GET_CODE (XEXP (operands[0], 0)) == LABEL_REF)
7413 /* This is really a PIC sequence. We want to represent
7414 it as a funny jump so its delay slots can be filled.
7416 ??? But if this really *is* a CALL, will not it clobber the
7417 call-clobbered registers? We lose this if it is a JUMP_INSN.
7418 Why cannot we have delay slots filled if it were a CALL? */
7420 /* We accept negative sizes for untyped calls. */
7421 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
7426 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
7428 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
7434 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
7435 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
7439 fn_rtx = operands[0];
7441 /* We accept negative sizes for untyped calls. */
7442 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
7446 gen_rtvec (3, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx),
7448 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
7453 gen_rtvec (2, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx),
7454 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
7461 ;; We can't use the same pattern for these two insns, because then registers
7462 ;; in the address may not be properly reloaded.
7464 (define_insn "*call_address_sp32"
7465 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
7466 (match_operand 1 "" ""))
7467 (clobber (reg:SI 15))]
7468 ;;- Do not use operand 1 for most machines.
7471 [(set_attr "type" "call")])
7473 (define_insn "*call_symbolic_sp32"
7474 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
7475 (match_operand 1 "" ""))
7476 (clobber (reg:SI 15))]
7477 ;;- Do not use operand 1 for most machines.
7480 [(set_attr "type" "call")])
7482 (define_insn "*call_address_sp64"
7483 [(call (mem:DI (match_operand:DI 0 "address_operand" "p"))
7484 (match_operand 1 "" ""))
7485 (clobber (reg:DI 15))]
7486 ;;- Do not use operand 1 for most machines.
7489 [(set_attr "type" "call")])
7491 (define_insn "*call_symbolic_sp64"
7492 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
7493 (match_operand 1 "" ""))
7494 (clobber (reg:DI 15))]
7495 ;;- Do not use operand 1 for most machines.
7498 [(set_attr "type" "call")])
7500 ;; This is a call that wants a structure value.
7501 ;; There is no such critter for v9 (??? we may need one anyway).
7502 (define_insn "*call_address_struct_value_sp32"
7503 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
7504 (match_operand 1 "" ""))
7505 (match_operand 2 "immediate_operand" "")
7506 (clobber (reg:SI 15))]
7507 ;;- Do not use operand 1 for most machines.
7508 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
7510 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xfff);
7511 return "call\t%a0, %1\n\t nop\n\tunimp\t%2";
7513 [(set_attr "type" "call_no_delay_slot")
7514 (set_attr "length" "3")])
7516 ;; This is a call that wants a structure value.
7517 ;; There is no such critter for v9 (??? we may need one anyway).
7518 (define_insn "*call_symbolic_struct_value_sp32"
7519 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
7520 (match_operand 1 "" ""))
7521 (match_operand 2 "immediate_operand" "")
7522 (clobber (reg:SI 15))]
7523 ;;- Do not use operand 1 for most machines.
7524 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
7526 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xfff);
7527 return "call\t%a0, %1\n\t nop\n\tunimp\t%2";
7529 [(set_attr "type" "call_no_delay_slot")
7530 (set_attr "length" "3")])
7532 ;; This is a call that may want a structure value. This is used for
7534 (define_insn "*call_address_untyped_struct_value_sp32"
7535 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
7536 (match_operand 1 "" ""))
7537 (match_operand 2 "immediate_operand" "")
7538 (clobber (reg:SI 15))]
7539 ;;- Do not use operand 1 for most machines.
7540 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
7541 "call\t%a0, %1\n\t nop\n\tnop"
7542 [(set_attr "type" "call_no_delay_slot")
7543 (set_attr "length" "3")])
7545 ;; This is a call that may want a structure value. This is used for
7547 (define_insn "*call_symbolic_untyped_struct_value_sp32"
7548 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
7549 (match_operand 1 "" ""))
7550 (match_operand 2 "immediate_operand" "")
7551 (clobber (reg:SI 15))]
7552 ;;- Do not use operand 1 for most machines.
7553 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
7554 "call\t%a0, %1\n\t nop\n\tnop"
7555 [(set_attr "type" "call_no_delay_slot")
7556 (set_attr "length" "3")])
7558 (define_expand "call_value"
7559 ;; Note that this expression is not used for generating RTL.
7560 ;; All the RTL is generated explicitly below.
7561 [(set (match_operand 0 "register_operand" "=rf")
7562 (call (match_operand 1 "" "")
7563 (match_operand 4 "" "")))]
7564 ;; operand 2 is stack_size_rtx
7565 ;; operand 3 is next_arg_register
7571 if (GET_MODE (operands[1]) != FUNCTION_MODE)
7574 fn_rtx = operands[1];
7577 gen_rtx_SET (VOIDmode, operands[0],
7578 gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx)),
7579 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)));
7581 emit_call_insn (gen_rtx_PARALLEL (VOIDmode, vec));
7586 (define_insn "*call_value_address_sp32"
7587 [(set (match_operand 0 "" "=rf")
7588 (call (mem:SI (match_operand:SI 1 "address_operand" "p"))
7589 (match_operand 2 "" "")))
7590 (clobber (reg:SI 15))]
7591 ;;- Do not use operand 2 for most machines.
7594 [(set_attr "type" "call")])
7596 (define_insn "*call_value_symbolic_sp32"
7597 [(set (match_operand 0 "" "=rf")
7598 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
7599 (match_operand 2 "" "")))
7600 (clobber (reg:SI 15))]
7601 ;;- Do not use operand 2 for most machines.
7604 [(set_attr "type" "call")])
7606 (define_insn "*call_value_address_sp64"
7607 [(set (match_operand 0 "" "")
7608 (call (mem:DI (match_operand:DI 1 "address_operand" "p"))
7609 (match_operand 2 "" "")))
7610 (clobber (reg:DI 15))]
7611 ;;- Do not use operand 2 for most machines.
7614 [(set_attr "type" "call")])
7616 (define_insn "*call_value_symbolic_sp64"
7617 [(set (match_operand 0 "" "")
7618 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
7619 (match_operand 2 "" "")))
7620 (clobber (reg:DI 15))]
7621 ;;- Do not use operand 2 for most machines.
7624 [(set_attr "type" "call")])
7626 (define_expand "untyped_call"
7627 [(parallel [(call (match_operand 0 "" "")
7629 (match_operand 1 "" "")
7630 (match_operand 2 "" "")])]
7635 /* Pass constm1 to indicate that it may expect a structure value, but
7636 we don't know what size it is. */
7637 emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, constm1_rtx));
7639 for (i = 0; i < XVECLEN (operands[2], 0); i++)
7641 rtx set = XVECEXP (operands[2], 0, i);
7642 emit_move_insn (SET_DEST (set), SET_SRC (set));
7645 /* The optimizer does not know that the call sets the function value
7646 registers we stored in the result block. We avoid problems by
7647 claiming that all hard registers are used and clobbered at this
7649 emit_insn (gen_blockage ());
7655 (define_expand "sibcall"
7656 [(parallel [(call (match_operand 0 "call_operand" "") (const_int 0))
7661 (define_insn "*sibcall_symbolic_sp32"
7662 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
7663 (match_operand 1 "" ""))
7666 "* return output_sibcall(insn, operands[0]);"
7667 [(set_attr "type" "sibcall")])
7669 (define_insn "*sibcall_symbolic_sp64"
7670 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
7671 (match_operand 1 "" ""))
7674 "* return output_sibcall(insn, operands[0]);"
7675 [(set_attr "type" "sibcall")])
7677 (define_expand "sibcall_value"
7678 [(parallel [(set (match_operand 0 "register_operand" "=rf")
7679 (call (match_operand 1 "" "") (const_int 0)))
7684 (define_insn "*sibcall_value_symbolic_sp32"
7685 [(set (match_operand 0 "" "=rf")
7686 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
7687 (match_operand 2 "" "")))
7690 "* return output_sibcall(insn, operands[1]);"
7691 [(set_attr "type" "sibcall")])
7693 (define_insn "*sibcall_value_symbolic_sp64"
7694 [(set (match_operand 0 "" "")
7695 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
7696 (match_operand 2 "" "")))
7699 "* return output_sibcall(insn, operands[1]);"
7700 [(set_attr "type" "sibcall")])
7702 (define_expand "sibcall_epilogue"
7706 sparc_expand_epilogue ();
7710 (define_expand "prologue"
7714 sparc_expand_prologue ();
7718 ;; The "save register window" insn is modelled as follows so that the DWARF-2
7719 ;; backend automatically emits the required call frame debugging information
7720 ;; while it is parsing it. Therefore, the pattern should not be modified
7721 ;; without first studying the impact of the changes on the debug info.
7722 ;; [(set (%fp) (%sp))
7723 ;; (set (%sp) (unspec_volatile [(%sp) (-frame_size)] UNSPECV_SAVEW))
7724 ;; (set (%i7) (%o7))]
7726 (define_insn "save_register_window<P:mode>"
7727 [(set (reg:P 30) (reg:P 14))
7728 (set (reg:P 14) (unspec_volatile:P [(reg:P 14)
7729 (match_operand:P 0 "arith_operand" "rI")] UNSPECV_SAVEW))
7730 (set (reg:P 31) (reg:P 15))]
7732 "save\t%%sp, %0, %%sp"
7733 [(set_attr "type" "savew")])
7735 (define_expand "epilogue"
7739 sparc_expand_epilogue ();
7742 (define_expand "return"
7744 "sparc_can_use_return_insn_p ()"
7747 (define_insn "*return_internal"
7750 "* return output_return (insn);"
7751 [(set_attr "type" "return")
7752 (set (attr "length")
7753 (cond [(eq_attr "leaf_function" "true")
7754 (if_then_else (eq_attr "empty_delay_slot" "true")
7757 (eq_attr "calls_eh_return" "true")
7758 (if_then_else (eq_attr "delayed_branch" "true")
7759 (if_then_else (eq_attr "isa" "v9")
7762 (if_then_else (eq_attr "isa" "v9")
7765 (eq_attr "empty_delay_slot" "true")
7766 (if_then_else (eq_attr "delayed_branch" "true")
7771 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
7772 ;; all of memory. This blocks insns from being moved across this point.
7774 (define_insn "blockage"
7775 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
7778 [(set_attr "length" "0")])
7780 ;; Prepare to return any type including a structure value.
7782 (define_expand "untyped_return"
7783 [(match_operand:BLK 0 "memory_operand" "")
7784 (match_operand 1 "" "")]
7787 rtx valreg1 = gen_rtx_REG (DImode, 24);
7788 rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
7789 rtx result = operands[0];
7791 if (! TARGET_ARCH64)
7793 rtx rtnreg = gen_rtx_REG (SImode, (current_function_uses_only_leaf_regs
7795 rtx value = gen_reg_rtx (SImode);
7797 /* Fetch the instruction where we will return to and see if it's an unimp
7798 instruction (the most significant 10 bits will be zero). If so,
7799 update the return address to skip the unimp instruction. */
7800 emit_move_insn (value,
7801 gen_rtx_MEM (SImode, plus_constant (rtnreg, 8)));
7802 emit_insn (gen_lshrsi3 (value, value, GEN_INT (22)));
7803 emit_insn (gen_update_return (rtnreg, value));
7806 /* Reload the function value registers. */
7807 emit_move_insn (valreg1, adjust_address (result, DImode, 0));
7808 emit_move_insn (valreg2,
7809 adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8));
7811 /* Put USE insns before the return. */
7812 emit_insn (gen_rtx_USE (VOIDmode, valreg1));
7813 emit_insn (gen_rtx_USE (VOIDmode, valreg2));
7815 /* Construct the return. */
7816 expand_naked_return ();
7821 ;; This is a bit of a hack. We're incrementing a fixed register (%i7),
7822 ;; and parts of the compiler don't want to believe that the add is needed.
7824 (define_insn "update_return"
7825 [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
7826 (match_operand:SI 1 "register_operand" "r")] UNSPEC_UPDATE_RETURN)]
7829 if (flag_delayed_branch)
7830 return "cmp\t%1, 0\n\tbe,a\t.+8\n\t add\t%0, 4, %0";
7832 return "cmp\t%1, 0\n\tbne\t.+12\n\t nop\n\tadd\t%0, 4, %0";
7834 [(set (attr "type") (const_string "multi"))
7835 (set (attr "length")
7836 (if_then_else (eq_attr "delayed_branch" "true")
7845 (define_expand "indirect_jump"
7846 [(set (pc) (match_operand 0 "address_operand" "p"))]
7850 (define_insn "*branch_sp32"
7851 [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
7854 [(set_attr "type" "uncond_branch")])
7856 (define_insn "*branch_sp64"
7857 [(set (pc) (match_operand:DI 0 "address_operand" "p"))]
7860 [(set_attr "type" "uncond_branch")])
7862 (define_expand "nonlocal_goto"
7863 [(match_operand:SI 0 "general_operand" "")
7864 (match_operand:SI 1 "general_operand" "")
7865 (match_operand:SI 2 "general_operand" "")
7866 (match_operand:SI 3 "" "")]
7869 rtx lab = operands[1];
7870 rtx stack = operands[2];
7871 rtx fp = operands[3];
7874 /* Trap instruction to flush all the register windows. */
7875 emit_insn (gen_flush_register_windows ());
7877 /* Load the fp value for the containing fn into %fp. This is needed
7878 because STACK refers to %fp. Note that virtual register instantiation
7879 fails if the virtual %fp isn't set from a register. */
7880 if (GET_CODE (fp) != REG)
7881 fp = force_reg (Pmode, fp);
7882 emit_move_insn (virtual_stack_vars_rtx, fp);
7884 /* Find the containing function's current nonlocal goto handler,
7885 which will do any cleanups and then jump to the label. */
7886 labreg = gen_rtx_REG (Pmode, 8);
7887 emit_move_insn (labreg, lab);
7889 /* Restore %fp from stack pointer value for containing function.
7890 The restore insn that follows will move this to %sp,
7891 and reload the appropriate value into %fp. */
7892 emit_move_insn (hard_frame_pointer_rtx, stack);
7894 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
7895 emit_insn (gen_rtx_USE (VOIDmode, static_chain_rtx));
7897 /* ??? The V9-specific version was disabled in rev 1.65. */
7898 emit_jump_insn (gen_goto_handler_and_restore (labreg));
7903 ;; Special trap insn to flush register windows.
7904 (define_insn "flush_register_windows"
7905 [(unspec_volatile [(const_int 0)] UNSPECV_FLUSHW)]
7907 { return TARGET_V9 ? "flushw" : "ta\t3"; }
7908 [(set_attr "type" "flushw")])
7910 (define_insn "goto_handler_and_restore"
7911 [(unspec_volatile [(match_operand 0 "register_operand" "=r")] UNSPECV_GOTO)]
7912 "GET_MODE (operands[0]) == Pmode"
7914 if (flag_delayed_branch)
7915 return "jmp\t%0\n\t restore";
7917 return "mov\t%0,%%g1\n\trestore\n\tjmp\t%%g1\n\t nop";
7919 [(set (attr "type") (const_string "multi"))
7920 (set (attr "length")
7921 (if_then_else (eq_attr "delayed_branch" "true")
7925 ;; For __builtin_setjmp we need to flush register windows iff the function
7926 ;; calls alloca as well, because otherwise the register window might be
7927 ;; saved after %sp adjustment and thus setjmp would crash
7928 (define_expand "builtin_setjmp_setup"
7929 [(match_operand 0 "register_operand" "r")]
7932 emit_insn (gen_do_builtin_setjmp_setup ());
7936 (define_insn "do_builtin_setjmp_setup"
7937 [(unspec_volatile [(const_int 0)] UNSPECV_SETJMP)]
7940 if (! current_function_calls_alloca)
7944 fputs ("\tflushw\n", asm_out_file);
7946 fprintf (asm_out_file, "\tst%c\t%%l7, [%%sp+%d]\n",
7947 TARGET_ARCH64 ? 'x' : 'w',
7948 SPARC_STACK_BIAS + 7 * UNITS_PER_WORD);
7949 fprintf (asm_out_file, "\tst%c\t%%fp, [%%sp+%d]\n",
7950 TARGET_ARCH64 ? 'x' : 'w',
7951 SPARC_STACK_BIAS + 14 * UNITS_PER_WORD);
7952 fprintf (asm_out_file, "\tst%c\t%%i7, [%%sp+%d]\n",
7953 TARGET_ARCH64 ? 'x' : 'w',
7954 SPARC_STACK_BIAS + 15 * UNITS_PER_WORD);
7957 [(set_attr "type" "multi")
7958 (set (attr "length")
7959 (cond [(eq_attr "calls_alloca" "false")
7961 (eq_attr "isa" "!v9")
7963 (eq_attr "pic" "true")
7964 (const_int 4)] (const_int 3)))])
7966 ;; Pattern for use after a setjmp to store FP and the return register
7967 ;; into the stack area.
7969 (define_expand "setjmp"
7974 emit_insn (gen_setjmp_64 ());
7976 emit_insn (gen_setjmp_32 ());
7980 (define_expand "setjmp_32"
7981 [(set (mem:SI (plus:SI (reg:SI 14) (const_int 56))) (match_dup 0))
7982 (set (mem:SI (plus:SI (reg:SI 14) (const_int 60))) (reg:SI 31))]
7984 { operands[0] = frame_pointer_rtx; })
7986 (define_expand "setjmp_64"
7987 [(set (mem:DI (plus:DI (reg:DI 14) (const_int 112))) (match_dup 0))
7988 (set (mem:DI (plus:DI (reg:DI 14) (const_int 120))) (reg:DI 31))]
7990 { operands[0] = frame_pointer_rtx; })
7992 ;; Special pattern for the FLUSH instruction.
7994 ; We do SImode and DImode versions of this to quiet down genrecog's complaints
7995 ; of the define_insn otherwise missing a mode. We make "flush", aka
7996 ; gen_flush, the default one since sparc_initialize_trampoline uses
7997 ; it on SImode mem values.
7999 (define_insn "flush"
8000 [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")] UNSPECV_FLUSH)]
8002 { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; }
8003 [(set_attr "type" "iflush")])
8005 (define_insn "flushdi"
8006 [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")] UNSPECV_FLUSH)]
8008 { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; }
8009 [(set_attr "type" "iflush")])
8014 ;; The scan instruction searches from the most significant bit while ffs
8015 ;; searches from the least significant bit. The bit index and treatment of
8016 ;; zero also differ. It takes at least 7 instructions to get the proper
8017 ;; result. Here is an obvious 8 instruction sequence.
8020 (define_insn "ffssi2"
8021 [(set (match_operand:SI 0 "register_operand" "=&r")
8022 (ffs:SI (match_operand:SI 1 "register_operand" "r")))
8023 (clobber (match_scratch:SI 2 "=&r"))]
8024 "TARGET_SPARCLITE || TARGET_SPARCLET"
8026 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";
8028 [(set_attr "type" "multi")
8029 (set_attr "length" "8")])
8031 ;; ??? This should be a define expand, so that the extra instruction have
8032 ;; a chance of being optimized away.
8034 ;; Disabled because none of the UltraSPARCs implement popc. The HAL R1
8035 ;; does, but no one uses that and we don't have a switch for it.
8037 ;(define_insn "ffsdi2"
8038 ; [(set (match_operand:DI 0 "register_operand" "=&r")
8039 ; (ffs:DI (match_operand:DI 1 "register_operand" "r")))
8040 ; (clobber (match_scratch:DI 2 "=&r"))]
8042 ; "neg\t%1, %2\;xnor\t%1, %2, %2\;popc\t%2, %0\;movzr\t%1, 0, %0"
8043 ; [(set_attr "type" "multi")
8044 ; (set_attr "length" "4")])
8048 ;; Peepholes go at the end.
8050 ;; Optimize consecutive loads or stores into ldd and std when possible.
8051 ;; The conditions in which we do this are very restricted and are
8052 ;; explained in the code for {registers,memory}_ok_for_ldd functions.
8055 [(set (match_operand:SI 0 "memory_operand" "")
8057 (set (match_operand:SI 1 "memory_operand" "")
8060 && mems_ok_for_ldd_peep (operands[0], operands[1], NULL_RTX)"
8063 "operands[0] = widen_memory_access (operands[0], DImode, 0);")
8066 [(set (match_operand:SI 0 "memory_operand" "")
8068 (set (match_operand:SI 1 "memory_operand" "")
8071 && mems_ok_for_ldd_peep (operands[1], operands[0], NULL_RTX)"
8074 "operands[1] = widen_memory_access (operands[1], DImode, 0);")
8077 [(set (match_operand:SI 0 "register_operand" "")
8078 (match_operand:SI 1 "memory_operand" ""))
8079 (set (match_operand:SI 2 "register_operand" "")
8080 (match_operand:SI 3 "memory_operand" ""))]
8081 "registers_ok_for_ldd_peep (operands[0], operands[2])
8082 && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
8085 "operands[1] = widen_memory_access (operands[1], DImode, 0);
8086 operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));")
8089 [(set (match_operand:SI 0 "memory_operand" "")
8090 (match_operand:SI 1 "register_operand" ""))
8091 (set (match_operand:SI 2 "memory_operand" "")
8092 (match_operand:SI 3 "register_operand" ""))]
8093 "registers_ok_for_ldd_peep (operands[1], operands[3])
8094 && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
8097 "operands[0] = widen_memory_access (operands[0], DImode, 0);
8098 operands[1] = gen_rtx_REG (DImode, REGNO (operands[1]));")
8101 [(set (match_operand:SF 0 "register_operand" "")
8102 (match_operand:SF 1 "memory_operand" ""))
8103 (set (match_operand:SF 2 "register_operand" "")
8104 (match_operand:SF 3 "memory_operand" ""))]
8105 "registers_ok_for_ldd_peep (operands[0], operands[2])
8106 && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
8109 "operands[1] = widen_memory_access (operands[1], DFmode, 0);
8110 operands[0] = gen_rtx_REG (DFmode, REGNO (operands[0]));")
8113 [(set (match_operand:SF 0 "memory_operand" "")
8114 (match_operand:SF 1 "register_operand" ""))
8115 (set (match_operand:SF 2 "memory_operand" "")
8116 (match_operand:SF 3 "register_operand" ""))]
8117 "registers_ok_for_ldd_peep (operands[1], operands[3])
8118 && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
8121 "operands[0] = widen_memory_access (operands[0], DFmode, 0);
8122 operands[1] = gen_rtx_REG (DFmode, REGNO (operands[1]));")
8125 [(set (match_operand:SI 0 "register_operand" "")
8126 (match_operand:SI 1 "memory_operand" ""))
8127 (set (match_operand:SI 2 "register_operand" "")
8128 (match_operand:SI 3 "memory_operand" ""))]
8129 "registers_ok_for_ldd_peep (operands[2], operands[0])
8130 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
8133 "operands[3] = widen_memory_access (operands[3], DImode, 0);
8134 operands[2] = gen_rtx_REG (DImode, REGNO (operands[2]));")
8137 [(set (match_operand:SI 0 "memory_operand" "")
8138 (match_operand:SI 1 "register_operand" ""))
8139 (set (match_operand:SI 2 "memory_operand" "")
8140 (match_operand:SI 3 "register_operand" ""))]
8141 "registers_ok_for_ldd_peep (operands[3], operands[1])
8142 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
8145 "operands[2] = widen_memory_access (operands[2], DImode, 0);
8146 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
8150 [(set (match_operand:SF 0 "register_operand" "")
8151 (match_operand:SF 1 "memory_operand" ""))
8152 (set (match_operand:SF 2 "register_operand" "")
8153 (match_operand:SF 3 "memory_operand" ""))]
8154 "registers_ok_for_ldd_peep (operands[2], operands[0])
8155 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
8158 "operands[3] = widen_memory_access (operands[3], DFmode, 0);
8159 operands[2] = gen_rtx_REG (DFmode, REGNO (operands[2]));")
8162 [(set (match_operand:SF 0 "memory_operand" "")
8163 (match_operand:SF 1 "register_operand" ""))
8164 (set (match_operand:SF 2 "memory_operand" "")
8165 (match_operand:SF 3 "register_operand" ""))]
8166 "registers_ok_for_ldd_peep (operands[3], operands[1])
8167 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
8170 "operands[2] = widen_memory_access (operands[2], DFmode, 0);
8171 operands[3] = gen_rtx_REG (DFmode, REGNO (operands[3]));")
8173 ;; Optimize the case of following a reg-reg move with a test
8174 ;; of reg just moved. Don't allow floating point regs for operand 0 or 1.
8175 ;; This can result from a float to fix conversion.
8178 [(set (match_operand:SI 0 "register_operand" "")
8179 (match_operand:SI 1 "register_operand" ""))
8181 (compare:CC (match_operand:SI 2 "register_operand" "")
8183 "(rtx_equal_p (operands[2], operands[0])
8184 || rtx_equal_p (operands[2], operands[1]))
8185 && ! SPARC_FP_REG_P (REGNO (operands[0]))
8186 && ! SPARC_FP_REG_P (REGNO (operands[1]))"
8187 [(parallel [(set (match_dup 0) (match_dup 1))
8189 (compare:CC (match_dup 1) (const_int 0)))])]
8193 [(set (match_operand:DI 0 "register_operand" "")
8194 (match_operand:DI 1 "register_operand" ""))
8196 (compare:CCX (match_operand:DI 2 "register_operand" "")
8199 && (rtx_equal_p (operands[2], operands[0])
8200 || rtx_equal_p (operands[2], operands[1]))
8201 && ! SPARC_FP_REG_P (REGNO (operands[0]))
8202 && ! SPARC_FP_REG_P (REGNO (operands[1]))"
8203 [(parallel [(set (match_dup 0) (match_dup 1))
8205 (compare:CCX (match_dup 1) (const_int 0)))])]
8208 ;; ??? UltraSPARC-III note: A memory operation loading into the floating point register
8209 ;; ??? file, if it hits the prefetch cache, has a chance to dual-issue with other memory
8210 ;; ??? operations. With DFA we might be able to model this, but it requires a lot of
8212 (define_expand "prefetch"
8213 [(match_operand 0 "address_operand" "")
8214 (match_operand 1 "const_int_operand" "")
8215 (match_operand 2 "const_int_operand" "")]
8219 emit_insn (gen_prefetch_64 (operands[0], operands[1], operands[2]));
8221 emit_insn (gen_prefetch_32 (operands[0], operands[1], operands[2]));
8225 (define_insn "prefetch_64"
8226 [(prefetch (match_operand:DI 0 "address_operand" "p")
8227 (match_operand:DI 1 "const_int_operand" "n")
8228 (match_operand:DI 2 "const_int_operand" "n"))]
8231 static const char * const prefetch_instr[2][2] = {
8233 "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
8234 "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
8237 "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
8238 "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
8241 int read_or_write = INTVAL (operands[1]);
8242 int locality = INTVAL (operands[2]);
8244 if (read_or_write != 0 && read_or_write != 1)
8246 if (locality < 0 || locality > 3)
8248 return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
8250 [(set_attr "type" "load")])
8252 (define_insn "prefetch_32"
8253 [(prefetch (match_operand:SI 0 "address_operand" "p")
8254 (match_operand:SI 1 "const_int_operand" "n")
8255 (match_operand:SI 2 "const_int_operand" "n"))]
8258 static const char * const prefetch_instr[2][2] = {
8260 "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
8261 "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
8264 "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
8265 "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
8268 int read_or_write = INTVAL (operands[1]);
8269 int locality = INTVAL (operands[2]);
8271 if (read_or_write != 0 && read_or_write != 1)
8273 if (locality < 0 || locality > 3)
8275 return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
8277 [(set_attr "type" "load")])
8280 [(trap_if (const_int 1) (const_int 5))]
8283 [(set_attr "type" "trap")])
8285 (define_expand "conditional_trap"
8286 [(trap_if (match_operator 0 "noov_compare_op" [(match_dup 2) (match_dup 3)])
8287 (match_operand:SI 1 "arith_operand" ""))]
8289 "operands[2] = gen_compare_reg (GET_CODE (operands[0]),
8290 sparc_compare_op0, sparc_compare_op1);
8291 if (GET_MODE (operands[2]) != CCmode && GET_MODE (operands[2]) != CCXmode)
8293 operands[3] = const0_rtx;")
8296 [(trap_if (match_operator 0 "noov_compare_op" [(reg:CC 100) (const_int 0)])
8297 (match_operand:SI 1 "arith_operand" "rM"))]
8301 return "t%C0\t%%icc, %1";
8305 [(set_attr "type" "trap")])
8308 [(trap_if (match_operator 0 "noov_compare_op" [(reg:CCX 100) (const_int 0)])
8309 (match_operand:SI 1 "arith_operand" "rM"))]
8312 [(set_attr "type" "trap")])
8315 (define_insn "tgd_hi22"
8316 [(set (match_operand:SI 0 "register_operand" "=r")
8317 (high:SI (unspec:SI [(match_operand 1 "tgd_symbolic_operand" "")]
8320 "sethi\\t%%tgd_hi22(%a1), %0")
8322 (define_insn "tgd_lo10"
8323 [(set (match_operand:SI 0 "register_operand" "=r")
8324 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
8325 (unspec:SI [(match_operand 2 "tgd_symbolic_operand" "")]
8328 "add\\t%1, %%tgd_lo10(%a2), %0")
8330 (define_insn "tgd_add32"
8331 [(set (match_operand:SI 0 "register_operand" "=r")
8332 (plus:SI (match_operand:SI 1 "register_operand" "r")
8333 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8334 (match_operand 3 "tgd_symbolic_operand" "")]
8336 "TARGET_TLS && TARGET_ARCH32"
8337 "add\\t%1, %2, %0, %%tgd_add(%a3)")
8339 (define_insn "tgd_add64"
8340 [(set (match_operand:DI 0 "register_operand" "=r")
8341 (plus:DI (match_operand:DI 1 "register_operand" "r")
8342 (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8343 (match_operand 3 "tgd_symbolic_operand" "")]
8345 "TARGET_TLS && TARGET_ARCH64"
8346 "add\\t%1, %2, %0, %%tgd_add(%a3)")
8348 (define_insn "tgd_call32"
8349 [(set (match_operand 0 "register_operand" "=r")
8350 (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")
8351 (match_operand 2 "tgd_symbolic_operand" "")]
8353 (match_operand 3 "" "")))
8354 (clobber (reg:SI 15))]
8355 "TARGET_TLS && TARGET_ARCH32"
8356 "call\t%a1, %%tgd_call(%a2)%#"
8357 [(set_attr "type" "call")])
8359 (define_insn "tgd_call64"
8360 [(set (match_operand 0 "register_operand" "=r")
8361 (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")
8362 (match_operand 2 "tgd_symbolic_operand" "")]
8364 (match_operand 3 "" "")))
8365 (clobber (reg:DI 15))]
8366 "TARGET_TLS && TARGET_ARCH64"
8367 "call\t%a1, %%tgd_call(%a2)%#"
8368 [(set_attr "type" "call")])
8370 (define_insn "tldm_hi22"
8371 [(set (match_operand:SI 0 "register_operand" "=r")
8372 (high:SI (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
8374 "sethi\\t%%tldm_hi22(%&), %0")
8376 (define_insn "tldm_lo10"
8377 [(set (match_operand:SI 0 "register_operand" "=r")
8378 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
8379 (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
8381 "add\\t%1, %%tldm_lo10(%&), %0")
8383 (define_insn "tldm_add32"
8384 [(set (match_operand:SI 0 "register_operand" "=r")
8385 (plus:SI (match_operand:SI 1 "register_operand" "r")
8386 (unspec:SI [(match_operand:SI 2 "register_operand" "r")]
8388 "TARGET_TLS && TARGET_ARCH32"
8389 "add\\t%1, %2, %0, %%tldm_add(%&)")
8391 (define_insn "tldm_add64"
8392 [(set (match_operand:DI 0 "register_operand" "=r")
8393 (plus:DI (match_operand:DI 1 "register_operand" "r")
8394 (unspec:DI [(match_operand:SI 2 "register_operand" "r")]
8396 "TARGET_TLS && TARGET_ARCH64"
8397 "add\\t%1, %2, %0, %%tldm_add(%&)")
8399 (define_insn "tldm_call32"
8400 [(set (match_operand 0 "register_operand" "=r")
8401 (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")]
8403 (match_operand 2 "" "")))
8404 (clobber (reg:SI 15))]
8405 "TARGET_TLS && TARGET_ARCH32"
8406 "call\t%a1, %%tldm_call(%&)%#"
8407 [(set_attr "type" "call")])
8409 (define_insn "tldm_call64"
8410 [(set (match_operand 0 "register_operand" "=r")
8411 (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")]
8413 (match_operand 2 "" "")))
8414 (clobber (reg:DI 15))]
8415 "TARGET_TLS && TARGET_ARCH64"
8416 "call\t%a1, %%tldm_call(%&)%#"
8417 [(set_attr "type" "call")])
8419 (define_insn "tldo_hix22"
8420 [(set (match_operand:SI 0 "register_operand" "=r")
8421 (high:SI (unspec:SI [(match_operand 1 "tld_symbolic_operand" "")]
8424 "sethi\\t%%tldo_hix22(%a1), %0")
8426 (define_insn "tldo_lox10"
8427 [(set (match_operand:SI 0 "register_operand" "=r")
8428 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
8429 (unspec:SI [(match_operand 2 "tld_symbolic_operand" "")]
8432 "xor\\t%1, %%tldo_lox10(%a2), %0")
8434 (define_insn "tldo_add32"
8435 [(set (match_operand:SI 0 "register_operand" "=r")
8436 (plus:SI (match_operand:SI 1 "register_operand" "r")
8437 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8438 (match_operand 3 "tld_symbolic_operand" "")]
8440 "TARGET_TLS && TARGET_ARCH32"
8441 "add\\t%1, %2, %0, %%tldo_add(%a3)")
8443 (define_insn "tldo_add64"
8444 [(set (match_operand:DI 0 "register_operand" "=r")
8445 (plus:DI (match_operand:DI 1 "register_operand" "r")
8446 (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8447 (match_operand 3 "tld_symbolic_operand" "")]
8449 "TARGET_TLS && TARGET_ARCH64"
8450 "add\\t%1, %2, %0, %%tldo_add(%a3)")
8452 (define_insn "tie_hi22"
8453 [(set (match_operand:SI 0 "register_operand" "=r")
8454 (high:SI (unspec:SI [(match_operand 1 "tie_symbolic_operand" "")]
8457 "sethi\\t%%tie_hi22(%a1), %0")
8459 (define_insn "tie_lo10"
8460 [(set (match_operand:SI 0 "register_operand" "=r")
8461 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
8462 (unspec:SI [(match_operand 2 "tie_symbolic_operand" "")]
8465 "add\\t%1, %%tie_lo10(%a2), %0")
8467 (define_insn "tie_ld32"
8468 [(set (match_operand:SI 0 "register_operand" "=r")
8469 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
8470 (match_operand:SI 2 "register_operand" "r")
8471 (match_operand 3 "tie_symbolic_operand" "")]
8473 "TARGET_TLS && TARGET_ARCH32"
8474 "ld\\t[%1 + %2], %0, %%tie_ld(%a3)"
8475 [(set_attr "type" "load")])
8477 (define_insn "tie_ld64"
8478 [(set (match_operand:DI 0 "register_operand" "=r")
8479 (unspec:DI [(match_operand:DI 1 "register_operand" "r")
8480 (match_operand:SI 2 "register_operand" "r")
8481 (match_operand 3 "tie_symbolic_operand" "")]
8483 "TARGET_TLS && TARGET_ARCH64"
8484 "ldx\\t[%1 + %2], %0, %%tie_ldx(%a3)"
8485 [(set_attr "type" "load")])
8487 (define_insn "tie_add32"
8488 [(set (match_operand:SI 0 "register_operand" "=r")
8489 (plus:SI (match_operand:SI 1 "register_operand" "r")
8490 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8491 (match_operand 3 "tie_symbolic_operand" "")]
8493 "TARGET_SUN_TLS && TARGET_ARCH32"
8494 "add\\t%1, %2, %0, %%tie_add(%a3)")
8496 (define_insn "tie_add64"
8497 [(set (match_operand:DI 0 "register_operand" "=r")
8498 (plus:DI (match_operand:DI 1 "register_operand" "r")
8499 (unspec:DI [(match_operand:DI 2 "register_operand" "r")
8500 (match_operand 3 "tie_symbolic_operand" "")]
8502 "TARGET_SUN_TLS && TARGET_ARCH64"
8503 "add\\t%1, %2, %0, %%tie_add(%a3)")
8505 (define_insn "tle_hix22_sp32"
8506 [(set (match_operand:SI 0 "register_operand" "=r")
8507 (high:SI (unspec:SI [(match_operand 1 "tle_symbolic_operand" "")]
8509 "TARGET_TLS && TARGET_ARCH32"
8510 "sethi\\t%%tle_hix22(%a1), %0")
8512 (define_insn "tle_lox10_sp32"
8513 [(set (match_operand:SI 0 "register_operand" "=r")
8514 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
8515 (unspec:SI [(match_operand 2 "tle_symbolic_operand" "")]
8517 "TARGET_TLS && TARGET_ARCH32"
8518 "xor\\t%1, %%tle_lox10(%a2), %0")
8520 (define_insn "tle_hix22_sp64"
8521 [(set (match_operand:DI 0 "register_operand" "=r")
8522 (high:DI (unspec:DI [(match_operand 1 "tle_symbolic_operand" "")]
8524 "TARGET_TLS && TARGET_ARCH64"
8525 "sethi\\t%%tle_hix22(%a1), %0")
8527 (define_insn "tle_lox10_sp64"
8528 [(set (match_operand:DI 0 "register_operand" "=r")
8529 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
8530 (unspec:DI [(match_operand 2 "tle_symbolic_operand" "")]
8532 "TARGET_TLS && TARGET_ARCH64"
8533 "xor\\t%1, %%tle_lox10(%a2), %0")
8535 ;; Now patterns combining tldo_add{32,64} with some integer loads or stores
8536 (define_insn "*tldo_ldub_sp32"
8537 [(set (match_operand:QI 0 "register_operand" "=r")
8538 (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8539 (match_operand 3 "tld_symbolic_operand" "")]
8541 (match_operand:SI 1 "register_operand" "r"))))]
8542 "TARGET_TLS && TARGET_ARCH32"
8543 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8544 [(set_attr "type" "load")
8545 (set_attr "us3load_type" "3cycle")])
8547 (define_insn "*tldo_ldub1_sp32"
8548 [(set (match_operand:HI 0 "register_operand" "=r")
8549 (zero_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8550 (match_operand 3 "tld_symbolic_operand" "")]
8552 (match_operand:SI 1 "register_operand" "r")))))]
8553 "TARGET_TLS && TARGET_ARCH32"
8554 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8555 [(set_attr "type" "load")
8556 (set_attr "us3load_type" "3cycle")])
8558 (define_insn "*tldo_ldub2_sp32"
8559 [(set (match_operand:SI 0 "register_operand" "=r")
8560 (zero_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8561 (match_operand 3 "tld_symbolic_operand" "")]
8563 (match_operand:SI 1 "register_operand" "r")))))]
8564 "TARGET_TLS && TARGET_ARCH32"
8565 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8566 [(set_attr "type" "load")
8567 (set_attr "us3load_type" "3cycle")])
8569 (define_insn "*tldo_ldsb1_sp32"
8570 [(set (match_operand:HI 0 "register_operand" "=r")
8571 (sign_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8572 (match_operand 3 "tld_symbolic_operand" "")]
8574 (match_operand:SI 1 "register_operand" "r")))))]
8575 "TARGET_TLS && TARGET_ARCH32"
8576 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
8577 [(set_attr "type" "sload")
8578 (set_attr "us3load_type" "3cycle")])
8580 (define_insn "*tldo_ldsb2_sp32"
8581 [(set (match_operand:SI 0 "register_operand" "=r")
8582 (sign_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8583 (match_operand 3 "tld_symbolic_operand" "")]
8585 (match_operand:SI 1 "register_operand" "r")))))]
8586 "TARGET_TLS && TARGET_ARCH32"
8587 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
8588 [(set_attr "type" "sload")
8589 (set_attr "us3load_type" "3cycle")])
8591 (define_insn "*tldo_ldub_sp64"
8592 [(set (match_operand:QI 0 "register_operand" "=r")
8593 (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8594 (match_operand 3 "tld_symbolic_operand" "")]
8596 (match_operand:DI 1 "register_operand" "r"))))]
8597 "TARGET_TLS && TARGET_ARCH64"
8598 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8599 [(set_attr "type" "load")
8600 (set_attr "us3load_type" "3cycle")])
8602 (define_insn "*tldo_ldub1_sp64"
8603 [(set (match_operand:HI 0 "register_operand" "=r")
8604 (zero_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8605 (match_operand 3 "tld_symbolic_operand" "")]
8607 (match_operand:DI 1 "register_operand" "r")))))]
8608 "TARGET_TLS && TARGET_ARCH64"
8609 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8610 [(set_attr "type" "load")
8611 (set_attr "us3load_type" "3cycle")])
8613 (define_insn "*tldo_ldub2_sp64"
8614 [(set (match_operand:SI 0 "register_operand" "=r")
8615 (zero_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8616 (match_operand 3 "tld_symbolic_operand" "")]
8618 (match_operand:DI 1 "register_operand" "r")))))]
8619 "TARGET_TLS && TARGET_ARCH64"
8620 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8621 [(set_attr "type" "load")
8622 (set_attr "us3load_type" "3cycle")])
8624 (define_insn "*tldo_ldub3_sp64"
8625 [(set (match_operand:DI 0 "register_operand" "=r")
8626 (zero_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8627 (match_operand 3 "tld_symbolic_operand" "")]
8629 (match_operand:DI 1 "register_operand" "r")))))]
8630 "TARGET_TLS && TARGET_ARCH64"
8631 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8632 [(set_attr "type" "load")
8633 (set_attr "us3load_type" "3cycle")])
8635 (define_insn "*tldo_ldsb1_sp64"
8636 [(set (match_operand:HI 0 "register_operand" "=r")
8637 (sign_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8638 (match_operand 3 "tld_symbolic_operand" "")]
8640 (match_operand:DI 1 "register_operand" "r")))))]
8641 "TARGET_TLS && TARGET_ARCH64"
8642 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
8643 [(set_attr "type" "sload")
8644 (set_attr "us3load_type" "3cycle")])
8646 (define_insn "*tldo_ldsb2_sp64"
8647 [(set (match_operand:SI 0 "register_operand" "=r")
8648 (sign_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8649 (match_operand 3 "tld_symbolic_operand" "")]
8651 (match_operand:DI 1 "register_operand" "r")))))]
8652 "TARGET_TLS && TARGET_ARCH64"
8653 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
8654 [(set_attr "type" "sload")
8655 (set_attr "us3load_type" "3cycle")])
8657 (define_insn "*tldo_ldsb3_sp64"
8658 [(set (match_operand:DI 0 "register_operand" "=r")
8659 (sign_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8660 (match_operand 3 "tld_symbolic_operand" "")]
8662 (match_operand:DI 1 "register_operand" "r")))))]
8663 "TARGET_TLS && TARGET_ARCH64"
8664 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
8665 [(set_attr "type" "sload")
8666 (set_attr "us3load_type" "3cycle")])
8668 (define_insn "*tldo_lduh_sp32"
8669 [(set (match_operand:HI 0 "register_operand" "=r")
8670 (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8671 (match_operand 3 "tld_symbolic_operand" "")]
8673 (match_operand:SI 1 "register_operand" "r"))))]
8674 "TARGET_TLS && TARGET_ARCH32"
8675 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
8676 [(set_attr "type" "load")
8677 (set_attr "us3load_type" "3cycle")])
8679 (define_insn "*tldo_lduh1_sp32"
8680 [(set (match_operand:SI 0 "register_operand" "=r")
8681 (zero_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8682 (match_operand 3 "tld_symbolic_operand" "")]
8684 (match_operand:SI 1 "register_operand" "r")))))]
8685 "TARGET_TLS && TARGET_ARCH32"
8686 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
8687 [(set_attr "type" "load")
8688 (set_attr "us3load_type" "3cycle")])
8690 (define_insn "*tldo_ldsh1_sp32"
8691 [(set (match_operand:SI 0 "register_operand" "=r")
8692 (sign_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8693 (match_operand 3 "tld_symbolic_operand" "")]
8695 (match_operand:SI 1 "register_operand" "r")))))]
8696 "TARGET_TLS && TARGET_ARCH32"
8697 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
8698 [(set_attr "type" "sload")
8699 (set_attr "us3load_type" "3cycle")])
8701 (define_insn "*tldo_lduh_sp64"
8702 [(set (match_operand:HI 0 "register_operand" "=r")
8703 (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8704 (match_operand 3 "tld_symbolic_operand" "")]
8706 (match_operand:DI 1 "register_operand" "r"))))]
8707 "TARGET_TLS && TARGET_ARCH64"
8708 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
8709 [(set_attr "type" "load")
8710 (set_attr "us3load_type" "3cycle")])
8712 (define_insn "*tldo_lduh1_sp64"
8713 [(set (match_operand:SI 0 "register_operand" "=r")
8714 (zero_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8715 (match_operand 3 "tld_symbolic_operand" "")]
8717 (match_operand:DI 1 "register_operand" "r")))))]
8718 "TARGET_TLS && TARGET_ARCH64"
8719 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
8720 [(set_attr "type" "load")
8721 (set_attr "us3load_type" "3cycle")])
8723 (define_insn "*tldo_lduh2_sp64"
8724 [(set (match_operand:DI 0 "register_operand" "=r")
8725 (zero_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8726 (match_operand 3 "tld_symbolic_operand" "")]
8728 (match_operand:DI 1 "register_operand" "r")))))]
8729 "TARGET_TLS && TARGET_ARCH64"
8730 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
8731 [(set_attr "type" "load")
8732 (set_attr "us3load_type" "3cycle")])
8734 (define_insn "*tldo_ldsh1_sp64"
8735 [(set (match_operand:SI 0 "register_operand" "=r")
8736 (sign_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8737 (match_operand 3 "tld_symbolic_operand" "")]
8739 (match_operand:DI 1 "register_operand" "r")))))]
8740 "TARGET_TLS && TARGET_ARCH64"
8741 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
8742 [(set_attr "type" "sload")
8743 (set_attr "us3load_type" "3cycle")])
8745 (define_insn "*tldo_ldsh2_sp64"
8746 [(set (match_operand:DI 0 "register_operand" "=r")
8747 (sign_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8748 (match_operand 3 "tld_symbolic_operand" "")]
8750 (match_operand:DI 1 "register_operand" "r")))))]
8751 "TARGET_TLS && TARGET_ARCH64"
8752 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
8753 [(set_attr "type" "sload")
8754 (set_attr "us3load_type" "3cycle")])
8756 (define_insn "*tldo_lduw_sp32"
8757 [(set (match_operand:SI 0 "register_operand" "=r")
8758 (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8759 (match_operand 3 "tld_symbolic_operand" "")]
8761 (match_operand:SI 1 "register_operand" "r"))))]
8762 "TARGET_TLS && TARGET_ARCH32"
8763 "ld\t[%1 + %2], %0, %%tldo_add(%3)"
8764 [(set_attr "type" "load")])
8766 (define_insn "*tldo_lduw_sp64"
8767 [(set (match_operand:SI 0 "register_operand" "=r")
8768 (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8769 (match_operand 3 "tld_symbolic_operand" "")]
8771 (match_operand:DI 1 "register_operand" "r"))))]
8772 "TARGET_TLS && TARGET_ARCH64"
8773 "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
8774 [(set_attr "type" "load")])
8776 (define_insn "*tldo_lduw1_sp64"
8777 [(set (match_operand:DI 0 "register_operand" "=r")
8778 (zero_extend:DI (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8779 (match_operand 3 "tld_symbolic_operand" "")]
8781 (match_operand:DI 1 "register_operand" "r")))))]
8782 "TARGET_TLS && TARGET_ARCH64"
8783 "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
8784 [(set_attr "type" "load")])
8786 (define_insn "*tldo_ldsw1_sp64"
8787 [(set (match_operand:DI 0 "register_operand" "=r")
8788 (sign_extend:DI (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8789 (match_operand 3 "tld_symbolic_operand" "")]
8791 (match_operand:DI 1 "register_operand" "r")))))]
8792 "TARGET_TLS && TARGET_ARCH64"
8793 "ldsw\t[%1 + %2], %0, %%tldo_add(%3)"
8794 [(set_attr "type" "sload")
8795 (set_attr "us3load_type" "3cycle")])
8797 (define_insn "*tldo_ldx_sp64"
8798 [(set (match_operand:DI 0 "register_operand" "=r")
8799 (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8800 (match_operand 3 "tld_symbolic_operand" "")]
8802 (match_operand:DI 1 "register_operand" "r"))))]
8803 "TARGET_TLS && TARGET_ARCH64"
8804 "ldx\t[%1 + %2], %0, %%tldo_add(%3)"
8805 [(set_attr "type" "load")])
8807 (define_insn "*tldo_stb_sp32"
8808 [(set (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8809 (match_operand 3 "tld_symbolic_operand" "")]
8811 (match_operand:SI 1 "register_operand" "r")))
8812 (match_operand:QI 0 "register_operand" "=r"))]
8813 "TARGET_TLS && TARGET_ARCH32"
8814 "stb\t%0, [%1 + %2], %%tldo_add(%3)"
8815 [(set_attr "type" "store")])
8817 (define_insn "*tldo_stb_sp64"
8818 [(set (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8819 (match_operand 3 "tld_symbolic_operand" "")]
8821 (match_operand:DI 1 "register_operand" "r")))
8822 (match_operand:QI 0 "register_operand" "=r"))]
8823 "TARGET_TLS && TARGET_ARCH64"
8824 "stb\t%0, [%1 + %2], %%tldo_add(%3)"
8825 [(set_attr "type" "store")])
8827 (define_insn "*tldo_sth_sp32"
8828 [(set (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8829 (match_operand 3 "tld_symbolic_operand" "")]
8831 (match_operand:SI 1 "register_operand" "r")))
8832 (match_operand:HI 0 "register_operand" "=r"))]
8833 "TARGET_TLS && TARGET_ARCH32"
8834 "sth\t%0, [%1 + %2], %%tldo_add(%3)"
8835 [(set_attr "type" "store")])
8837 (define_insn "*tldo_sth_sp64"
8838 [(set (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8839 (match_operand 3 "tld_symbolic_operand" "")]
8841 (match_operand:DI 1 "register_operand" "r")))
8842 (match_operand:HI 0 "register_operand" "=r"))]
8843 "TARGET_TLS && TARGET_ARCH64"
8844 "sth\t%0, [%1 + %2], %%tldo_add(%3)"
8845 [(set_attr "type" "store")])
8847 (define_insn "*tldo_stw_sp32"
8848 [(set (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8849 (match_operand 3 "tld_symbolic_operand" "")]
8851 (match_operand:SI 1 "register_operand" "r")))
8852 (match_operand:SI 0 "register_operand" "=r"))]
8853 "TARGET_TLS && TARGET_ARCH32"
8854 "st\t%0, [%1 + %2], %%tldo_add(%3)"
8855 [(set_attr "type" "store")])
8857 (define_insn "*tldo_stw_sp64"
8858 [(set (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8859 (match_operand 3 "tld_symbolic_operand" "")]
8861 (match_operand:DI 1 "register_operand" "r")))
8862 (match_operand:SI 0 "register_operand" "=r"))]
8863 "TARGET_TLS && TARGET_ARCH64"
8864 "stw\t%0, [%1 + %2], %%tldo_add(%3)"
8865 [(set_attr "type" "store")])
8867 (define_insn "*tldo_stx_sp64"
8868 [(set (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8869 (match_operand 3 "tld_symbolic_operand" "")]
8871 (match_operand:DI 1 "register_operand" "r")))
8872 (match_operand:DI 0 "register_operand" "=r"))]
8873 "TARGET_TLS && TARGET_ARCH64"
8874 "stx\t%0, [%1 + %2], %%tldo_add(%3)"
8875 [(set_attr "type" "store")])
8877 ;; Vector instructions.
8879 (define_insn "addv2si3"
8880 [(set (match_operand:V2SI 0 "register_operand" "=e")
8881 (plus:V2SI (match_operand:V2SI 1 "register_operand" "e")
8882 (match_operand:V2SI 2 "register_operand" "e")))]
8884 "fpadd32\t%1, %2, %0"
8885 [(set_attr "type" "fga")
8886 (set_attr "fptype" "double")])
8888 (define_insn "addv4hi3"
8889 [(set (match_operand:V4HI 0 "register_operand" "=e")
8890 (plus:V4HI (match_operand:V4HI 1 "register_operand" "e")
8891 (match_operand:V4HI 2 "register_operand" "e")))]
8893 "fpadd16\t%1, %2, %0"
8894 [(set_attr "type" "fga")
8895 (set_attr "fptype" "double")])
8897 ;; fpadd32s is emitted by the addsi3 pattern.
8899 (define_insn "addv2hi3"
8900 [(set (match_operand:V2HI 0 "register_operand" "=f")
8901 (plus:V2HI (match_operand:V2HI 1 "register_operand" "f")
8902 (match_operand:V2HI 2 "register_operand" "f")))]
8904 "fpadd16s\t%1, %2, %0"
8905 [(set_attr "type" "fga")
8906 (set_attr "fptype" "single")])
8908 (define_insn "subv2si3"
8909 [(set (match_operand:V2SI 0 "register_operand" "=e")
8910 (minus:V2SI (match_operand:V2SI 1 "register_operand" "e")
8911 (match_operand:V2SI 2 "register_operand" "e")))]
8913 "fpsub32\t%1, %2, %0"
8914 [(set_attr "type" "fga")
8915 (set_attr "fptype" "double")])
8917 (define_insn "subv4hi3"
8918 [(set (match_operand:V4HI 0 "register_operand" "=e")
8919 (minus:V4HI (match_operand:V4HI 1 "register_operand" "e")
8920 (match_operand:V4HI 2 "register_operand" "e")))]
8922 "fpsub16\t%1, %2, %0"
8923 [(set_attr "type" "fga")
8924 (set_attr "fptype" "double")])
8926 ;; fpsub32s is emitted by the subsi3 pattern.
8928 (define_insn "subv2hi3"
8929 [(set (match_operand:V2HI 0 "register_operand" "=f")
8930 (minus:V2HI (match_operand:V2HI 1 "register_operand" "f")
8931 (match_operand:V2HI 2 "register_operand" "f")))]
8933 "fpsub16s\t%1, %2, %0"
8934 [(set_attr "type" "fga")
8935 (set_attr "fptype" "single")])
8937 ;; All other logical instructions have integer equivalents so they
8938 ;; are defined together.
8940 ;; (ior (not (op1)) (not (op2))) is the canonical form of NAND.
8942 (define_insn "*nand<V64mode>_vis"
8943 [(set (match_operand:V64 0 "register_operand" "=e")
8944 (ior:V64 (not:V64 (match_operand:V64 1 "register_operand" "e"))
8945 (not:V64 (match_operand:V64 2 "register_operand" "e"))))]
8948 [(set_attr "type" "fga")
8949 (set_attr "fptype" "double")])
8951 (define_insn "*nand<V32mode>_vis"
8952 [(set (match_operand:V32 0 "register_operand" "=f")
8953 (ior:V32 (not:V32 (match_operand:V32 1 "register_operand" "f"))
8954 (not:V32 (match_operand:V32 2 "register_operand" "f"))))]
8956 "fnands\t%1, %2, %0"
8957 [(set_attr "type" "fga")
8958 (set_attr "fptype" "single")])
8960 ;; Hard to generate VIS instructions. We have builtins for these.
8962 (define_insn "fpack16_vis"
8963 [(set (match_operand:V4QI 0 "register_operand" "=f")
8964 (unspec:V4QI [(match_operand:V4HI 1 "register_operand" "e")]
8968 [(set_attr "type" "fga")
8969 (set_attr "fptype" "double")])
8971 (define_insn "fpackfix_vis"
8972 [(set (match_operand:V2HI 0 "register_operand" "=f")
8973 (unspec:V2HI [(match_operand:V2SI 1 "register_operand" "e")]
8977 [(set_attr "type" "fga")
8978 (set_attr "fptype" "double")])
8980 (define_insn "fpack32_vis"
8981 [(set (match_operand:V8QI 0 "register_operand" "=e")
8982 (unspec:V8QI [(match_operand:V2SI 1 "register_operand" "e")
8983 (match_operand:V8QI 2 "register_operand" "e")]
8986 "fpack32\t%1, %2, %0"
8987 [(set_attr "type" "fga")
8988 (set_attr "fptype" "double")])
8990 (define_insn "fexpand_vis"
8991 [(set (match_operand:V4HI 0 "register_operand" "=e")
8992 (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")]
8996 [(set_attr "type" "fga")
8997 (set_attr "fptype" "double")])
8999 ;; It may be possible to describe this operation as (1 indexed):
9000 ;; (vec_select (vec_duplicate (vec_duplicate (vec_concat 1 2)))
9001 ;; 1,5,10,14,19,23,28,32)
9002 ;; Note that (vec_merge:V8QI [(V4QI) (V4QI)] (10101010 = 170) doesn't work
9003 ;; because vec_merge expects all the operands to be of the same type.
9004 (define_insn "fpmerge_vis"
9005 [(set (match_operand:V8QI 0 "register_operand" "=e")
9006 (unspec:V8QI [(match_operand:V4QI 1 "register_operand" "f")
9007 (match_operand:V4QI 2 "register_operand" "f")]
9010 "fpmerge\t%1, %2, %0"
9011 [(set_attr "type" "fga")
9012 (set_attr "fptype" "double")])
9014 ;; Partitioned multiply instructions
9015 (define_insn "fmul8x16_vis"
9016 [(set (match_operand:V4HI 0 "register_operand" "=e")
9017 (mult:V4HI (match_operand:V4QI 1 "register_operand" "f")
9018 (match_operand:V4HI 2 "register_operand" "e")))]
9020 "fmul8x16\t%1, %2, %0"
9021 [(set_attr "type" "fpmul")
9022 (set_attr "fptype" "double")])
9024 ;; Only one of the following two insns can be a multiply.
9025 (define_insn "fmul8x16au_vis"
9026 [(set (match_operand:V4HI 0 "register_operand" "=e")
9027 (mult:V4HI (match_operand:V4QI 1 "register_operand" "f")
9028 (match_operand:V2HI 2 "register_operand" "f")))]
9030 "fmul8x16au\t%1, %2, %0"
9031 [(set_attr "type" "fpmul")
9032 (set_attr "fptype" "double")])
9034 (define_insn "fmul8x16al_vis"
9035 [(set (match_operand:V4HI 0 "register_operand" "=e")
9036 (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")
9037 (match_operand:V2HI 2 "register_operand" "f")]
9040 "fmul8x16al\t%1, %2, %0"
9041 [(set_attr "type" "fpmul")
9042 (set_attr "fptype" "double")])
9044 ;; Only one of the following two insns can be a multiply.
9045 (define_insn "fmul8sux16_vis"
9046 [(set (match_operand:V4HI 0 "register_operand" "=e")
9047 (mult:V4HI (match_operand:V8QI 1 "register_operand" "e")
9048 (match_operand:V4HI 2 "register_operand" "e")))]
9050 "fmul8sux16\t%1, %2, %0"
9051 [(set_attr "type" "fpmul")
9052 (set_attr "fptype" "double")])
9054 (define_insn "fmul8ulx16_vis"
9055 [(set (match_operand:V4HI 0 "register_operand" "=e")
9056 (unspec:V4HI [(match_operand:V8QI 1 "register_operand" "e")
9057 (match_operand:V4HI 2 "register_operand" "e")]
9060 "fmul8ulx16\t%1, %2, %0"
9061 [(set_attr "type" "fpmul")
9062 (set_attr "fptype" "double")])
9064 ;; Only one of the following two insns can be a multiply.
9065 (define_insn "fmuld8sux16_vis"
9066 [(set (match_operand:V2SI 0 "register_operand" "=e")
9067 (mult:V2SI (match_operand:V4QI 1 "register_operand" "f")
9068 (match_operand:V2HI 2 "register_operand" "f")))]
9070 "fmuld8sux16\t%1, %2, %0"
9071 [(set_attr "type" "fpmul")
9072 (set_attr "fptype" "double")])
9074 (define_insn "fmuld8ulx16_vis"
9075 [(set (match_operand:V2SI 0 "register_operand" "=e")
9076 (unspec:V2SI [(match_operand:V4QI 1 "register_operand" "f")
9077 (match_operand:V2HI 2 "register_operand" "f")]
9080 "fmuld8ulx16\t%1, %2, %0"
9081 [(set_attr "type" "fpmul")
9082 (set_attr "fptype" "double")])
9084 ;; Using faligndata only makes sense after an alignaddr since the choice of
9085 ;; bytes to take out of each operand is dependant on the results of the last
9087 (define_insn "faligndata<V64I:mode>_vis"
9088 [(set (match_operand:V64I 0 "register_operand" "=e")
9089 (unspec:V64I [(match_operand:V64I 1 "register_operand" "e")
9090 (match_operand:V64I 2 "register_operand" "e")]
9093 "faligndata\t%1, %2, %0"
9094 [(set_attr "type" "fga")
9095 (set_attr "fptype" "double")])
9097 (define_insn "alignaddr<P:mode>_vis"
9098 [(set (match_operand:P 0 "register_operand" "=r")
9099 (unspec:P [(match_operand:P 1 "reg_or_0_operand" "rJ")
9100 (match_operand:P 2 "reg_or_0_operand" "rJ")]
9103 "alignaddr\t%r1, %r2, %0")
9105 (define_insn "pdist_vis"
9106 [(set (match_operand:DI 0 "register_operand" "=e")
9107 (unspec:DI [(match_operand:V8QI 1 "register_operand" "e")
9108 (match_operand:V8QI 2 "register_operand" "e")
9109 (match_operand:DI 3 "register_operand" "0")]
9113 [(set_attr "type" "fga")
9114 (set_attr "fptype" "double")])