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_operator" "")
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_register_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")
312 ;; Operand and operator predicates.
314 (include "predicates.md")
317 ;; Compare instructions.
319 ;; We generate RTL for comparisons and branches by having the cmpxx
320 ;; patterns store away the operands. Then, the scc and bcc patterns
321 ;; emit RTL for both the compare and the branch.
323 ;; We do this because we want to generate different code for an sne and
324 ;; seq insn. In those cases, if the second operand of the compare is not
325 ;; const0_rtx, we want to compute the xor of the two operands and test
328 ;; We start with the DEFINE_EXPANDs, then the DEFINE_INSNs to match
329 ;; the patterns. Finally, we have the DEFINE_SPLITs for some of the scc
330 ;; insns that actually require more than one machine instruction.
332 ;; Put cmpsi first among compare insns so it matches two CONST_INT operands.
334 (define_expand "cmpsi"
336 (compare:CC (match_operand:SI 0 "compare_operand" "")
337 (match_operand:SI 1 "arith_operand" "")))]
340 if (GET_CODE (operands[0]) == ZERO_EXTRACT && operands[1] != const0_rtx)
341 operands[0] = force_reg (SImode, operands[0]);
343 sparc_compare_op0 = operands[0];
344 sparc_compare_op1 = operands[1];
348 (define_expand "cmpdi"
350 (compare:CCX (match_operand:DI 0 "compare_operand" "")
351 (match_operand:DI 1 "arith_operand" "")))]
354 if (GET_CODE (operands[0]) == ZERO_EXTRACT && operands[1] != const0_rtx)
355 operands[0] = force_reg (DImode, operands[0]);
357 sparc_compare_op0 = operands[0];
358 sparc_compare_op1 = operands[1];
362 (define_expand "cmpsf"
363 ;; The 96 here isn't ever used by anyone.
365 (compare:CCFP (match_operand:SF 0 "register_operand" "")
366 (match_operand:SF 1 "register_operand" "")))]
369 sparc_compare_op0 = operands[0];
370 sparc_compare_op1 = operands[1];
374 (define_expand "cmpdf"
375 ;; The 96 here isn't ever used by anyone.
377 (compare:CCFP (match_operand:DF 0 "register_operand" "")
378 (match_operand:DF 1 "register_operand" "")))]
381 sparc_compare_op0 = operands[0];
382 sparc_compare_op1 = operands[1];
386 (define_expand "cmptf"
387 ;; The 96 here isn't ever used by anyone.
389 (compare:CCFP (match_operand:TF 0 "register_operand" "")
390 (match_operand:TF 1 "register_operand" "")))]
393 sparc_compare_op0 = operands[0];
394 sparc_compare_op1 = operands[1];
398 ;; Now the compare DEFINE_INSNs.
400 (define_insn "*cmpsi_insn"
402 (compare:CC (match_operand:SI 0 "register_operand" "r")
403 (match_operand:SI 1 "arith_operand" "rI")))]
406 [(set_attr "type" "compare")])
408 (define_insn "*cmpdi_sp64"
410 (compare:CCX (match_operand:DI 0 "register_operand" "r")
411 (match_operand:DI 1 "arith_operand" "rI")))]
414 [(set_attr "type" "compare")])
416 (define_insn "*cmpsf_fpe"
417 [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
418 (compare:CCFPE (match_operand:SF 1 "register_operand" "f")
419 (match_operand:SF 2 "register_operand" "f")))]
423 return "fcmpes\t%0, %1, %2";
424 return "fcmpes\t%1, %2";
426 [(set_attr "type" "fpcmp")])
428 (define_insn "*cmpdf_fpe"
429 [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
430 (compare:CCFPE (match_operand:DF 1 "register_operand" "e")
431 (match_operand:DF 2 "register_operand" "e")))]
435 return "fcmped\t%0, %1, %2";
436 return "fcmped\t%1, %2";
438 [(set_attr "type" "fpcmp")
439 (set_attr "fptype" "double")])
441 (define_insn "*cmptf_fpe"
442 [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
443 (compare:CCFPE (match_operand:TF 1 "register_operand" "e")
444 (match_operand:TF 2 "register_operand" "e")))]
445 "TARGET_FPU && TARGET_HARD_QUAD"
448 return "fcmpeq\t%0, %1, %2";
449 return "fcmpeq\t%1, %2";
451 [(set_attr "type" "fpcmp")])
453 (define_insn "*cmpsf_fp"
454 [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
455 (compare:CCFP (match_operand:SF 1 "register_operand" "f")
456 (match_operand:SF 2 "register_operand" "f")))]
460 return "fcmps\t%0, %1, %2";
461 return "fcmps\t%1, %2";
463 [(set_attr "type" "fpcmp")])
465 (define_insn "*cmpdf_fp"
466 [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
467 (compare:CCFP (match_operand:DF 1 "register_operand" "e")
468 (match_operand:DF 2 "register_operand" "e")))]
472 return "fcmpd\t%0, %1, %2";
473 return "fcmpd\t%1, %2";
475 [(set_attr "type" "fpcmp")
476 (set_attr "fptype" "double")])
478 (define_insn "*cmptf_fp"
479 [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
480 (compare:CCFP (match_operand:TF 1 "register_operand" "e")
481 (match_operand:TF 2 "register_operand" "e")))]
482 "TARGET_FPU && TARGET_HARD_QUAD"
485 return "fcmpq\t%0, %1, %2";
486 return "fcmpq\t%1, %2";
488 [(set_attr "type" "fpcmp")])
490 ;; Next come the scc insns. For seq, sne, sgeu, and sltu, we can do this
491 ;; without jumps using the addx/subx instructions. For seq/sne on v9 we use
492 ;; the same code as v8 (the addx/subx method has more applications). The
493 ;; exception to this is "reg != 0" which can be done in one instruction on v9
494 ;; (so we do it). For the rest, on v9 we use conditional moves; on v8, we do
497 ;; Seq_special[_xxx] and sne_special[_xxx] clobber the CC reg, because they
498 ;; generate addcc/subcc instructions.
500 (define_expand "seqsi_special"
502 (xor:SI (match_operand:SI 1 "register_operand" "")
503 (match_operand:SI 2 "register_operand" "")))
504 (parallel [(set (match_operand:SI 0 "register_operand" "")
505 (eq:SI (match_dup 3) (const_int 0)))
506 (clobber (reg:CC 100))])]
508 { operands[3] = gen_reg_rtx (SImode); })
510 (define_expand "seqdi_special"
512 (xor:DI (match_operand:DI 1 "register_operand" "")
513 (match_operand:DI 2 "register_operand" "")))
514 (set (match_operand:DI 0 "register_operand" "")
515 (eq:DI (match_dup 3) (const_int 0)))]
517 { operands[3] = gen_reg_rtx (DImode); })
519 (define_expand "snesi_special"
521 (xor:SI (match_operand:SI 1 "register_operand" "")
522 (match_operand:SI 2 "register_operand" "")))
523 (parallel [(set (match_operand:SI 0 "register_operand" "")
524 (ne:SI (match_dup 3) (const_int 0)))
525 (clobber (reg:CC 100))])]
527 { operands[3] = gen_reg_rtx (SImode); })
529 (define_expand "snedi_special"
531 (xor:DI (match_operand:DI 1 "register_operand" "")
532 (match_operand:DI 2 "register_operand" "")))
533 (set (match_operand:DI 0 "register_operand" "")
534 (ne:DI (match_dup 3) (const_int 0)))]
536 { operands[3] = gen_reg_rtx (DImode); })
538 (define_expand "seqdi_special_trunc"
540 (xor:DI (match_operand:DI 1 "register_operand" "")
541 (match_operand:DI 2 "register_operand" "")))
542 (set (match_operand:SI 0 "register_operand" "")
543 (eq:SI (match_dup 3) (const_int 0)))]
545 { operands[3] = gen_reg_rtx (DImode); })
547 (define_expand "snedi_special_trunc"
549 (xor:DI (match_operand:DI 1 "register_operand" "")
550 (match_operand:DI 2 "register_operand" "")))
551 (set (match_operand:SI 0 "register_operand" "")
552 (ne:SI (match_dup 3) (const_int 0)))]
554 { operands[3] = gen_reg_rtx (DImode); })
556 (define_expand "seqsi_special_extend"
558 (xor:SI (match_operand:SI 1 "register_operand" "")
559 (match_operand:SI 2 "register_operand" "")))
560 (parallel [(set (match_operand:DI 0 "register_operand" "")
561 (eq:DI (match_dup 3) (const_int 0)))
562 (clobber (reg:CC 100))])]
564 { operands[3] = gen_reg_rtx (SImode); })
566 (define_expand "snesi_special_extend"
568 (xor:SI (match_operand:SI 1 "register_operand" "")
569 (match_operand:SI 2 "register_operand" "")))
570 (parallel [(set (match_operand:DI 0 "register_operand" "")
571 (ne:DI (match_dup 3) (const_int 0)))
572 (clobber (reg:CC 100))])]
574 { operands[3] = gen_reg_rtx (SImode); })
576 ;; ??? v9: Operand 0 needs a mode, so SImode was chosen.
577 ;; However, the code handles both SImode and DImode.
579 [(set (match_operand:SI 0 "int_register_operand" "")
580 (eq:SI (match_dup 1) (const_int 0)))]
583 if (GET_MODE (sparc_compare_op0) == SImode)
587 if (GET_MODE (operands[0]) == SImode)
588 pat = gen_seqsi_special (operands[0], sparc_compare_op0,
590 else if (! TARGET_ARCH64)
593 pat = gen_seqsi_special_extend (operands[0], sparc_compare_op0,
598 else if (GET_MODE (sparc_compare_op0) == DImode)
604 else if (GET_MODE (operands[0]) == SImode)
605 pat = gen_seqdi_special_trunc (operands[0], sparc_compare_op0,
608 pat = gen_seqdi_special (operands[0], sparc_compare_op0,
613 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
615 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, EQ);
616 emit_jump_insn (gen_sne (operands[0]));
621 if (gen_v9_scc (EQ, operands))
628 ;; ??? v9: Operand 0 needs a mode, so SImode was chosen.
629 ;; However, the code handles both SImode and DImode.
631 [(set (match_operand:SI 0 "int_register_operand" "")
632 (ne:SI (match_dup 1) (const_int 0)))]
635 if (GET_MODE (sparc_compare_op0) == SImode)
639 if (GET_MODE (operands[0]) == SImode)
640 pat = gen_snesi_special (operands[0], sparc_compare_op0,
642 else if (! TARGET_ARCH64)
645 pat = gen_snesi_special_extend (operands[0], sparc_compare_op0,
650 else if (GET_MODE (sparc_compare_op0) == DImode)
656 else if (GET_MODE (operands[0]) == SImode)
657 pat = gen_snedi_special_trunc (operands[0], sparc_compare_op0,
660 pat = gen_snedi_special (operands[0], sparc_compare_op0,
665 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
667 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, NE);
668 emit_jump_insn (gen_sne (operands[0]));
673 if (gen_v9_scc (NE, operands))
681 [(set (match_operand:SI 0 "int_register_operand" "")
682 (gt:SI (match_dup 1) (const_int 0)))]
685 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
687 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GT);
688 emit_jump_insn (gen_sne (operands[0]));
693 if (gen_v9_scc (GT, operands))
701 [(set (match_operand:SI 0 "int_register_operand" "")
702 (lt:SI (match_dup 1) (const_int 0)))]
705 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
707 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LT);
708 emit_jump_insn (gen_sne (operands[0]));
713 if (gen_v9_scc (LT, operands))
721 [(set (match_operand:SI 0 "int_register_operand" "")
722 (ge:SI (match_dup 1) (const_int 0)))]
725 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
727 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GE);
728 emit_jump_insn (gen_sne (operands[0]));
733 if (gen_v9_scc (GE, operands))
741 [(set (match_operand:SI 0 "int_register_operand" "")
742 (le:SI (match_dup 1) (const_int 0)))]
745 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
747 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LE);
748 emit_jump_insn (gen_sne (operands[0]));
753 if (gen_v9_scc (LE, operands))
760 (define_expand "sgtu"
761 [(set (match_operand:SI 0 "int_register_operand" "")
762 (gtu:SI (match_dup 1) (const_int 0)))]
769 /* We can do ltu easily, so if both operands are registers, swap them and
771 if ((GET_CODE (sparc_compare_op0) == REG
772 || GET_CODE (sparc_compare_op0) == SUBREG)
773 && (GET_CODE (sparc_compare_op1) == REG
774 || GET_CODE (sparc_compare_op1) == SUBREG))
776 tem = sparc_compare_op0;
777 sparc_compare_op0 = sparc_compare_op1;
778 sparc_compare_op1 = tem;
779 pat = gen_sltu (operands[0]);
788 if (gen_v9_scc (GTU, operands))
794 (define_expand "sltu"
795 [(set (match_operand:SI 0 "int_register_operand" "")
796 (ltu:SI (match_dup 1) (const_int 0)))]
801 if (gen_v9_scc (LTU, operands))
804 operands[1] = gen_compare_reg (LTU, sparc_compare_op0, sparc_compare_op1);
807 (define_expand "sgeu"
808 [(set (match_operand:SI 0 "int_register_operand" "")
809 (geu:SI (match_dup 1) (const_int 0)))]
814 if (gen_v9_scc (GEU, operands))
817 operands[1] = gen_compare_reg (GEU, sparc_compare_op0, sparc_compare_op1);
820 (define_expand "sleu"
821 [(set (match_operand:SI 0 "int_register_operand" "")
822 (leu:SI (match_dup 1) (const_int 0)))]
829 /* We can do geu easily, so if both operands are registers, swap them and
831 if ((GET_CODE (sparc_compare_op0) == REG
832 || GET_CODE (sparc_compare_op0) == SUBREG)
833 && (GET_CODE (sparc_compare_op1) == REG
834 || GET_CODE (sparc_compare_op1) == SUBREG))
836 tem = sparc_compare_op0;
837 sparc_compare_op0 = sparc_compare_op1;
838 sparc_compare_op1 = tem;
839 pat = gen_sgeu (operands[0]);
848 if (gen_v9_scc (LEU, operands))
854 ;; Now the DEFINE_INSNs for the scc cases.
856 ;; The SEQ and SNE patterns are special because they can be done
857 ;; without any branching and do not involve a COMPARE. We want
858 ;; them to always use the splitz below so the results can be
861 (define_insn_and_split "*snesi_zero"
862 [(set (match_operand:SI 0 "register_operand" "=r")
863 (ne:SI (match_operand:SI 1 "register_operand" "r")
865 (clobber (reg:CC 100))]
869 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
871 (set (match_dup 0) (ltu:SI (reg:CC 100) (const_int 0)))]
873 [(set_attr "length" "2")])
875 (define_insn_and_split "*neg_snesi_zero"
876 [(set (match_operand:SI 0 "register_operand" "=r")
877 (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
879 (clobber (reg:CC 100))]
883 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
885 (set (match_dup 0) (neg:SI (ltu:SI (reg:CC 100) (const_int 0))))]
887 [(set_attr "length" "2")])
889 (define_insn_and_split "*snesi_zero_extend"
890 [(set (match_operand:DI 0 "register_operand" "=r")
891 (ne:DI (match_operand:SI 1 "register_operand" "r")
893 (clobber (reg:CC 100))]
897 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (minus:SI (const_int 0)
900 (set (match_dup 0) (zero_extend:DI (plus:SI (plus:SI (const_int 0)
902 (ltu:SI (reg:CC_NOOV 100)
905 [(set_attr "length" "2")])
907 (define_insn_and_split "*snedi_zero"
908 [(set (match_operand:DI 0 "register_operand" "=&r")
909 (ne:DI (match_operand:DI 1 "register_operand" "r")
913 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
914 [(set (match_dup 0) (const_int 0))
915 (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
920 [(set_attr "length" "2")])
922 (define_insn_and_split "*neg_snedi_zero"
923 [(set (match_operand:DI 0 "register_operand" "=&r")
924 (neg:DI (ne:DI (match_operand:DI 1 "register_operand" "r")
928 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
929 [(set (match_dup 0) (const_int 0))
930 (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
935 [(set_attr "length" "2")])
937 (define_insn_and_split "*snedi_zero_trunc"
938 [(set (match_operand:SI 0 "register_operand" "=&r")
939 (ne:SI (match_operand:DI 1 "register_operand" "r")
943 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
944 [(set (match_dup 0) (const_int 0))
945 (set (match_dup 0) (if_then_else:SI (ne:DI (match_dup 1)
950 [(set_attr "length" "2")])
952 (define_insn_and_split "*seqsi_zero"
953 [(set (match_operand:SI 0 "register_operand" "=r")
954 (eq:SI (match_operand:SI 1 "register_operand" "r")
956 (clobber (reg:CC 100))]
960 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
962 (set (match_dup 0) (geu:SI (reg:CC 100) (const_int 0)))]
964 [(set_attr "length" "2")])
966 (define_insn_and_split "*neg_seqsi_zero"
967 [(set (match_operand:SI 0 "register_operand" "=r")
968 (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
970 (clobber (reg:CC 100))]
974 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
976 (set (match_dup 0) (neg:SI (geu:SI (reg:CC 100) (const_int 0))))]
978 [(set_attr "length" "2")])
980 (define_insn_and_split "*seqsi_zero_extend"
981 [(set (match_operand:DI 0 "register_operand" "=r")
982 (eq:DI (match_operand:SI 1 "register_operand" "r")
984 (clobber (reg:CC 100))]
988 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (minus:SI (const_int 0)
991 (set (match_dup 0) (zero_extend:DI (minus:SI (minus:SI (const_int 0)
993 (ltu:SI (reg:CC_NOOV 100)
996 [(set_attr "length" "2")])
998 (define_insn_and_split "*seqdi_zero"
999 [(set (match_operand:DI 0 "register_operand" "=&r")
1000 (eq:DI (match_operand:DI 1 "register_operand" "r")
1004 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
1005 [(set (match_dup 0) (const_int 0))
1006 (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
1011 [(set_attr "length" "2")])
1013 (define_insn_and_split "*neg_seqdi_zero"
1014 [(set (match_operand:DI 0 "register_operand" "=&r")
1015 (neg:DI (eq:DI (match_operand:DI 1 "register_operand" "r")
1019 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
1020 [(set (match_dup 0) (const_int 0))
1021 (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
1026 [(set_attr "length" "2")])
1028 (define_insn_and_split "*seqdi_zero_trunc"
1029 [(set (match_operand:SI 0 "register_operand" "=&r")
1030 (eq:SI (match_operand:DI 1 "register_operand" "r")
1034 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
1035 [(set (match_dup 0) (const_int 0))
1036 (set (match_dup 0) (if_then_else:SI (eq:DI (match_dup 1)
1041 [(set_attr "length" "2")])
1043 ;; We can also do (x + (i == 0)) and related, so put them in.
1044 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1047 (define_insn_and_split "*x_plus_i_ne_0"
1048 [(set (match_operand:SI 0 "register_operand" "=r")
1049 (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
1051 (match_operand:SI 2 "register_operand" "r")))
1052 (clobber (reg:CC 100))]
1056 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1058 (set (match_dup 0) (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1061 [(set_attr "length" "2")])
1063 (define_insn_and_split "*x_minus_i_ne_0"
1064 [(set (match_operand:SI 0 "register_operand" "=r")
1065 (minus:SI (match_operand:SI 2 "register_operand" "r")
1066 (ne:SI (match_operand:SI 1 "register_operand" "r")
1068 (clobber (reg:CC 100))]
1072 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1074 (set (match_dup 0) (minus:SI (match_dup 2)
1075 (ltu:SI (reg:CC 100) (const_int 0))))]
1077 [(set_attr "length" "2")])
1079 (define_insn_and_split "*x_plus_i_eq_0"
1080 [(set (match_operand:SI 0 "register_operand" "=r")
1081 (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
1083 (match_operand:SI 2 "register_operand" "r")))
1084 (clobber (reg:CC 100))]
1088 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1090 (set (match_dup 0) (plus:SI (geu:SI (reg:CC 100) (const_int 0))
1093 [(set_attr "length" "2")])
1095 (define_insn_and_split "*x_minus_i_eq_0"
1096 [(set (match_operand:SI 0 "register_operand" "=r")
1097 (minus:SI (match_operand:SI 2 "register_operand" "r")
1098 (eq:SI (match_operand:SI 1 "register_operand" "r")
1100 (clobber (reg:CC 100))]
1104 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1106 (set (match_dup 0) (minus:SI (match_dup 2)
1107 (geu:SI (reg:CC 100) (const_int 0))))]
1109 [(set_attr "length" "2")])
1111 ;; We can also do GEU and LTU directly, but these operate after a compare.
1112 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1115 (define_insn "*sltu_insn"
1116 [(set (match_operand:SI 0 "register_operand" "=r")
1117 (ltu:SI (reg:CC 100) (const_int 0)))]
1120 [(set_attr "type" "ialuX")])
1122 (define_insn "*neg_sltu_insn"
1123 [(set (match_operand:SI 0 "register_operand" "=r")
1124 (neg:SI (ltu:SI (reg:CC 100) (const_int 0))))]
1127 [(set_attr "type" "ialuX")])
1129 ;; ??? Combine should canonicalize these next two to the same pattern.
1130 (define_insn "*neg_sltu_minus_x"
1131 [(set (match_operand:SI 0 "register_operand" "=r")
1132 (minus:SI (neg:SI (ltu:SI (reg:CC 100) (const_int 0)))
1133 (match_operand:SI 1 "arith_operand" "rI")))]
1135 "subx\t%%g0, %1, %0"
1136 [(set_attr "type" "ialuX")])
1138 (define_insn "*neg_sltu_plus_x"
1139 [(set (match_operand:SI 0 "register_operand" "=r")
1140 (neg:SI (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1141 (match_operand:SI 1 "arith_operand" "rI"))))]
1143 "subx\t%%g0, %1, %0"
1144 [(set_attr "type" "ialuX")])
1146 (define_insn "*sgeu_insn"
1147 [(set (match_operand:SI 0 "register_operand" "=r")
1148 (geu:SI (reg:CC 100) (const_int 0)))]
1150 "subx\t%%g0, -1, %0"
1151 [(set_attr "type" "ialuX")])
1153 (define_insn "*neg_sgeu_insn"
1154 [(set (match_operand:SI 0 "register_operand" "=r")
1155 (neg:SI (geu:SI (reg:CC 100) (const_int 0))))]
1157 "addx\t%%g0, -1, %0"
1158 [(set_attr "type" "ialuX")])
1160 ;; We can also do (x + ((unsigned) i >= 0)) and related, so put them in.
1161 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1164 (define_insn "*sltu_plus_x"
1165 [(set (match_operand:SI 0 "register_operand" "=r")
1166 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1167 (match_operand:SI 1 "arith_operand" "rI")))]
1169 "addx\t%%g0, %1, %0"
1170 [(set_attr "type" "ialuX")])
1172 (define_insn "*sltu_plus_x_plus_y"
1173 [(set (match_operand:SI 0 "register_operand" "=r")
1174 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1175 (plus:SI (match_operand:SI 1 "arith_operand" "%r")
1176 (match_operand:SI 2 "arith_operand" "rI"))))]
1179 [(set_attr "type" "ialuX")])
1181 (define_insn "*x_minus_sltu"
1182 [(set (match_operand:SI 0 "register_operand" "=r")
1183 (minus:SI (match_operand:SI 1 "register_operand" "r")
1184 (ltu:SI (reg:CC 100) (const_int 0))))]
1187 [(set_attr "type" "ialuX")])
1189 ;; ??? Combine should canonicalize these next two to the same pattern.
1190 (define_insn "*x_minus_y_minus_sltu"
1191 [(set (match_operand:SI 0 "register_operand" "=r")
1192 (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
1193 (match_operand:SI 2 "arith_operand" "rI"))
1194 (ltu:SI (reg:CC 100) (const_int 0))))]
1197 [(set_attr "type" "ialuX")])
1199 (define_insn "*x_minus_sltu_plus_y"
1200 [(set (match_operand:SI 0 "register_operand" "=r")
1201 (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
1202 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1203 (match_operand:SI 2 "arith_operand" "rI"))))]
1206 [(set_attr "type" "ialuX")])
1208 (define_insn "*sgeu_plus_x"
1209 [(set (match_operand:SI 0 "register_operand" "=r")
1210 (plus:SI (geu:SI (reg:CC 100) (const_int 0))
1211 (match_operand:SI 1 "register_operand" "r")))]
1214 [(set_attr "type" "ialuX")])
1216 (define_insn "*x_minus_sgeu"
1217 [(set (match_operand:SI 0 "register_operand" "=r")
1218 (minus:SI (match_operand:SI 1 "register_operand" "r")
1219 (geu:SI (reg:CC 100) (const_int 0))))]
1222 [(set_attr "type" "ialuX")])
1225 [(set (match_operand:SI 0 "register_operand" "")
1226 (match_operator:SI 2 "noov_compare_operator"
1227 [(match_operand 1 "icc_or_fcc_register_operand" "")
1230 && REGNO (operands[1]) == SPARC_ICC_REG
1231 && (GET_MODE (operands[1]) == CCXmode
1232 /* 32 bit LTU/GEU are better implemented using addx/subx. */
1233 || (GET_CODE (operands[2]) != LTU && GET_CODE (operands[2]) != GEU))"
1234 [(set (match_dup 0) (const_int 0))
1236 (if_then_else:SI (match_op_dup:SI 2 [(match_dup 1) (const_int 0)])
1242 ;; These control RTL generation for conditional jump insns
1244 ;; The quad-word fp compare library routines all return nonzero to indicate
1245 ;; true, which is different from the equivalent libgcc routines, so we must
1246 ;; handle them specially here.
1248 (define_expand "beq"
1250 (if_then_else (eq (match_dup 1) (const_int 0))
1251 (label_ref (match_operand 0 "" ""))
1255 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1256 && GET_CODE (sparc_compare_op0) == REG
1257 && GET_MODE (sparc_compare_op0) == DImode)
1259 emit_v9_brxx_insn (EQ, sparc_compare_op0, operands[0]);
1262 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1264 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, EQ);
1265 emit_jump_insn (gen_bne (operands[0]));
1268 operands[1] = gen_compare_reg (EQ, sparc_compare_op0, sparc_compare_op1);
1271 (define_expand "bne"
1273 (if_then_else (ne (match_dup 1) (const_int 0))
1274 (label_ref (match_operand 0 "" ""))
1278 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1279 && GET_CODE (sparc_compare_op0) == REG
1280 && GET_MODE (sparc_compare_op0) == DImode)
1282 emit_v9_brxx_insn (NE, sparc_compare_op0, operands[0]);
1285 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1287 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, NE);
1288 emit_jump_insn (gen_bne (operands[0]));
1291 operands[1] = gen_compare_reg (NE, sparc_compare_op0, sparc_compare_op1);
1294 (define_expand "bgt"
1296 (if_then_else (gt (match_dup 1) (const_int 0))
1297 (label_ref (match_operand 0 "" ""))
1301 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1302 && GET_CODE (sparc_compare_op0) == REG
1303 && GET_MODE (sparc_compare_op0) == DImode)
1305 emit_v9_brxx_insn (GT, sparc_compare_op0, operands[0]);
1308 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1310 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GT);
1311 emit_jump_insn (gen_bne (operands[0]));
1314 operands[1] = gen_compare_reg (GT, sparc_compare_op0, sparc_compare_op1);
1317 (define_expand "bgtu"
1319 (if_then_else (gtu (match_dup 1) (const_int 0))
1320 (label_ref (match_operand 0 "" ""))
1324 operands[1] = gen_compare_reg (GTU, sparc_compare_op0, sparc_compare_op1);
1327 (define_expand "blt"
1329 (if_then_else (lt (match_dup 1) (const_int 0))
1330 (label_ref (match_operand 0 "" ""))
1334 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1335 && GET_CODE (sparc_compare_op0) == REG
1336 && GET_MODE (sparc_compare_op0) == DImode)
1338 emit_v9_brxx_insn (LT, sparc_compare_op0, operands[0]);
1341 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1343 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LT);
1344 emit_jump_insn (gen_bne (operands[0]));
1347 operands[1] = gen_compare_reg (LT, sparc_compare_op0, sparc_compare_op1);
1350 (define_expand "bltu"
1352 (if_then_else (ltu (match_dup 1) (const_int 0))
1353 (label_ref (match_operand 0 "" ""))
1357 operands[1] = gen_compare_reg (LTU, sparc_compare_op0, sparc_compare_op1);
1360 (define_expand "bge"
1362 (if_then_else (ge (match_dup 1) (const_int 0))
1363 (label_ref (match_operand 0 "" ""))
1367 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1368 && GET_CODE (sparc_compare_op0) == REG
1369 && GET_MODE (sparc_compare_op0) == DImode)
1371 emit_v9_brxx_insn (GE, sparc_compare_op0, operands[0]);
1374 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1376 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GE);
1377 emit_jump_insn (gen_bne (operands[0]));
1380 operands[1] = gen_compare_reg (GE, sparc_compare_op0, sparc_compare_op1);
1383 (define_expand "bgeu"
1385 (if_then_else (geu (match_dup 1) (const_int 0))
1386 (label_ref (match_operand 0 "" ""))
1390 operands[1] = gen_compare_reg (GEU, sparc_compare_op0, sparc_compare_op1);
1393 (define_expand "ble"
1395 (if_then_else (le (match_dup 1) (const_int 0))
1396 (label_ref (match_operand 0 "" ""))
1400 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1401 && GET_CODE (sparc_compare_op0) == REG
1402 && GET_MODE (sparc_compare_op0) == DImode)
1404 emit_v9_brxx_insn (LE, sparc_compare_op0, operands[0]);
1407 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1409 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LE);
1410 emit_jump_insn (gen_bne (operands[0]));
1413 operands[1] = gen_compare_reg (LE, sparc_compare_op0, sparc_compare_op1);
1416 (define_expand "bleu"
1418 (if_then_else (leu (match_dup 1) (const_int 0))
1419 (label_ref (match_operand 0 "" ""))
1423 operands[1] = gen_compare_reg (LEU, sparc_compare_op0, sparc_compare_op1);
1426 (define_expand "bunordered"
1428 (if_then_else (unordered (match_dup 1) (const_int 0))
1429 (label_ref (match_operand 0 "" ""))
1433 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1435 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1,
1437 emit_jump_insn (gen_beq (operands[0]));
1440 operands[1] = gen_compare_reg (UNORDERED, sparc_compare_op0,
1444 (define_expand "bordered"
1446 (if_then_else (ordered (match_dup 1) (const_int 0))
1447 (label_ref (match_operand 0 "" ""))
1451 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1453 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, ORDERED);
1454 emit_jump_insn (gen_bne (operands[0]));
1457 operands[1] = gen_compare_reg (ORDERED, sparc_compare_op0,
1461 (define_expand "bungt"
1463 (if_then_else (ungt (match_dup 1) (const_int 0))
1464 (label_ref (match_operand 0 "" ""))
1468 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1470 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNGT);
1471 emit_jump_insn (gen_bgt (operands[0]));
1474 operands[1] = gen_compare_reg (UNGT, sparc_compare_op0, sparc_compare_op1);
1477 (define_expand "bunlt"
1479 (if_then_else (unlt (match_dup 1) (const_int 0))
1480 (label_ref (match_operand 0 "" ""))
1484 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1486 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNLT);
1487 emit_jump_insn (gen_bne (operands[0]));
1490 operands[1] = gen_compare_reg (UNLT, sparc_compare_op0, sparc_compare_op1);
1493 (define_expand "buneq"
1495 (if_then_else (uneq (match_dup 1) (const_int 0))
1496 (label_ref (match_operand 0 "" ""))
1500 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1502 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNEQ);
1503 emit_jump_insn (gen_beq (operands[0]));
1506 operands[1] = gen_compare_reg (UNEQ, sparc_compare_op0, sparc_compare_op1);
1509 (define_expand "bunge"
1511 (if_then_else (unge (match_dup 1) (const_int 0))
1512 (label_ref (match_operand 0 "" ""))
1516 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1518 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNGE);
1519 emit_jump_insn (gen_bne (operands[0]));
1522 operands[1] = gen_compare_reg (UNGE, sparc_compare_op0, sparc_compare_op1);
1525 (define_expand "bunle"
1527 (if_then_else (unle (match_dup 1) (const_int 0))
1528 (label_ref (match_operand 0 "" ""))
1532 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1534 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNLE);
1535 emit_jump_insn (gen_bne (operands[0]));
1538 operands[1] = gen_compare_reg (UNLE, sparc_compare_op0, sparc_compare_op1);
1541 (define_expand "bltgt"
1543 (if_then_else (ltgt (match_dup 1) (const_int 0))
1544 (label_ref (match_operand 0 "" ""))
1548 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1550 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LTGT);
1551 emit_jump_insn (gen_bne (operands[0]));
1554 operands[1] = gen_compare_reg (LTGT, sparc_compare_op0, sparc_compare_op1);
1557 ;; Now match both normal and inverted jump.
1559 ;; XXX fpcmp nop braindamage
1560 (define_insn "*normal_branch"
1562 (if_then_else (match_operator 0 "noov_compare_operator"
1563 [(reg 100) (const_int 0)])
1564 (label_ref (match_operand 1 "" ""))
1568 return output_cbranch (operands[0], operands[1], 1, 0,
1569 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1572 [(set_attr "type" "branch")
1573 (set_attr "branch_type" "icc")])
1575 ;; XXX fpcmp nop braindamage
1576 (define_insn "*inverted_branch"
1578 (if_then_else (match_operator 0 "noov_compare_operator"
1579 [(reg 100) (const_int 0)])
1581 (label_ref (match_operand 1 "" ""))))]
1584 return output_cbranch (operands[0], operands[1], 1, 1,
1585 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1588 [(set_attr "type" "branch")
1589 (set_attr "branch_type" "icc")])
1591 ;; XXX fpcmp nop braindamage
1592 (define_insn "*normal_fp_branch"
1594 (if_then_else (match_operator 1 "comparison_operator"
1595 [(match_operand:CCFP 0 "fcc_register_operand" "c")
1597 (label_ref (match_operand 2 "" ""))
1601 return output_cbranch (operands[1], operands[2], 2, 0,
1602 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1605 [(set_attr "type" "branch")
1606 (set_attr "branch_type" "fcc")])
1608 ;; XXX fpcmp nop braindamage
1609 (define_insn "*inverted_fp_branch"
1611 (if_then_else (match_operator 1 "comparison_operator"
1612 [(match_operand:CCFP 0 "fcc_register_operand" "c")
1615 (label_ref (match_operand 2 "" ""))))]
1618 return output_cbranch (operands[1], operands[2], 2, 1,
1619 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1622 [(set_attr "type" "branch")
1623 (set_attr "branch_type" "fcc")])
1625 ;; XXX fpcmp nop braindamage
1626 (define_insn "*normal_fpe_branch"
1628 (if_then_else (match_operator 1 "comparison_operator"
1629 [(match_operand:CCFPE 0 "fcc_register_operand" "c")
1631 (label_ref (match_operand 2 "" ""))
1635 return output_cbranch (operands[1], operands[2], 2, 0,
1636 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1639 [(set_attr "type" "branch")
1640 (set_attr "branch_type" "fcc")])
1642 ;; XXX fpcmp nop braindamage
1643 (define_insn "*inverted_fpe_branch"
1645 (if_then_else (match_operator 1 "comparison_operator"
1646 [(match_operand:CCFPE 0 "fcc_register_operand" "c")
1649 (label_ref (match_operand 2 "" ""))))]
1652 return output_cbranch (operands[1], operands[2], 2, 1,
1653 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1656 [(set_attr "type" "branch")
1657 (set_attr "branch_type" "fcc")])
1659 ;; SPARC V9-specific jump insns. None of these are guaranteed to be
1660 ;; in the architecture.
1662 ;; There are no 32 bit brreg insns.
1665 (define_insn "*normal_int_branch_sp64"
1667 (if_then_else (match_operator 0 "v9_register_compare_operator"
1668 [(match_operand:DI 1 "register_operand" "r")
1670 (label_ref (match_operand 2 "" ""))
1674 return output_v9branch (operands[0], operands[2], 1, 2, 0,
1675 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1678 [(set_attr "type" "branch")
1679 (set_attr "branch_type" "reg")])
1682 (define_insn "*inverted_int_branch_sp64"
1684 (if_then_else (match_operator 0 "v9_register_compare_operator"
1685 [(match_operand:DI 1 "register_operand" "r")
1688 (label_ref (match_operand 2 "" ""))))]
1691 return output_v9branch (operands[0], operands[2], 1, 2, 1,
1692 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1695 [(set_attr "type" "branch")
1696 (set_attr "branch_type" "reg")])
1698 ;; Load in operand 0 the (absolute) address of operand 1, which is a symbolic
1699 ;; value subject to a PC-relative relocation. Operand 2 is a helper function
1700 ;; that adds the PC value at the call point to operand 0.
1702 (define_insn "load_pcrel_sym<P:mode>"
1703 [(set (match_operand:P 0 "register_operand" "=r")
1704 (unspec:P [(match_operand:P 1 "symbolic_operand" "")
1705 (match_operand:P 2 "call_address_operand" "")] UNSPEC_LOAD_PCREL_SYM))
1706 (clobber (reg:P 15))]
1709 if (flag_delayed_branch)
1710 return "sethi\t%%hi(%a1-4), %0\n\tcall\t%a2\n\t add\t%0, %%lo(%a1+4), %0";
1712 return "sethi\t%%hi(%a1-8), %0\n\tadd\t%0, %%lo(%a1-4), %0\n\tcall\t%a2\n\t nop";
1714 [(set (attr "type") (const_string "multi"))
1715 (set (attr "length")
1716 (if_then_else (eq_attr "delayed_branch" "true")
1720 ;; Move instructions
1722 (define_expand "movqi"
1723 [(set (match_operand:QI 0 "general_operand" "")
1724 (match_operand:QI 1 "general_operand" ""))]
1727 /* Working with CONST_INTs is easier, so convert
1728 a double if needed. */
1729 if (GET_CODE (operands[1]) == CONST_DOUBLE)
1731 operands[1] = GEN_INT (trunc_int_for_mode
1732 (CONST_DOUBLE_LOW (operands[1]), QImode));
1735 /* Handle sets of MEM first. */
1736 if (GET_CODE (operands[0]) == MEM)
1738 if (register_or_zero_operand (operands[1], QImode))
1741 if (! reload_in_progress)
1743 operands[0] = validize_mem (operands[0]);
1744 operands[1] = force_reg (QImode, operands[1]);
1748 /* Fixup TLS cases. */
1749 if (tls_symbolic_operand (operands [1]))
1750 operands[1] = legitimize_tls_address (operands[1]);
1752 /* Fixup PIC cases. */
1755 if (CONSTANT_P (operands[1])
1756 && pic_address_needs_scratch (operands[1]))
1757 operands[1] = legitimize_pic_address (operands[1], QImode, 0);
1759 if (symbolic_operand (operands[1], QImode))
1761 operands[1] = legitimize_pic_address (operands[1],
1763 (reload_in_progress ?
1770 /* All QI constants require only one insn, so proceed. */
1776 (define_insn "*movqi_insn"
1777 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m")
1778 (match_operand:QI 1 "input_operand" "rI,m,rJ"))]
1779 "(register_operand (operands[0], QImode)
1780 || register_or_zero_operand (operands[1], QImode))"
1785 [(set_attr "type" "*,load,store")
1786 (set_attr "us3load_type" "*,3cycle,*")])
1788 (define_expand "movhi"
1789 [(set (match_operand:HI 0 "general_operand" "")
1790 (match_operand:HI 1 "general_operand" ""))]
1793 /* Working with CONST_INTs is easier, so convert
1794 a double if needed. */
1795 if (GET_CODE (operands[1]) == CONST_DOUBLE)
1796 operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
1798 /* Handle sets of MEM first. */
1799 if (GET_CODE (operands[0]) == MEM)
1801 if (register_or_zero_operand (operands[1], HImode))
1804 if (! reload_in_progress)
1806 operands[0] = validize_mem (operands[0]);
1807 operands[1] = force_reg (HImode, operands[1]);
1811 /* Fixup TLS cases. */
1812 if (tls_symbolic_operand (operands [1]))
1813 operands[1] = legitimize_tls_address (operands[1]);
1815 /* Fixup PIC cases. */
1818 if (CONSTANT_P (operands[1])
1819 && pic_address_needs_scratch (operands[1]))
1820 operands[1] = legitimize_pic_address (operands[1], HImode, 0);
1822 if (symbolic_operand (operands[1], HImode))
1824 operands[1] = legitimize_pic_address (operands[1],
1826 (reload_in_progress ?
1833 /* This makes sure we will not get rematched due to splittage. */
1834 if (! CONSTANT_P (operands[1]) || input_operand (operands[1], HImode))
1836 else if (CONSTANT_P (operands[1])
1837 && GET_CODE (operands[1]) != HIGH
1838 && GET_CODE (operands[1]) != LO_SUM)
1840 sparc_emit_set_const32 (operands[0], operands[1]);
1847 (define_insn "*movhi_const64_special"
1848 [(set (match_operand:HI 0 "register_operand" "=r")
1849 (match_operand:HI 1 "const_high_operand" "K"))]
1851 "sethi\t%%hi(%a1), %0")
1853 (define_insn "*movhi_insn"
1854 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1855 (match_operand:HI 1 "input_operand" "rI,K,m,rJ"))]
1856 "(register_operand (operands[0], HImode)
1857 || register_or_zero_operand (operands[1], HImode))"
1860 sethi\t%%hi(%a1), %0
1863 [(set_attr "type" "*,*,load,store")
1864 (set_attr "us3load_type" "*,*,3cycle,*")])
1866 ;; We always work with constants here.
1867 (define_insn "*movhi_lo_sum"
1868 [(set (match_operand:HI 0 "register_operand" "=r")
1869 (ior:HI (match_operand:HI 1 "register_operand" "%r")
1870 (match_operand:HI 2 "small_int_operand" "I")))]
1874 (define_expand "movsi"
1875 [(set (match_operand:SI 0 "general_operand" "")
1876 (match_operand:SI 1 "general_operand" ""))]
1879 /* Working with CONST_INTs is easier, so convert
1880 a double if needed. */
1881 if (GET_CODE (operands[1]) == CONST_DOUBLE)
1882 operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
1884 /* Handle sets of MEM first. */
1885 if (GET_CODE (operands[0]) == MEM)
1887 if (register_or_zero_operand (operands[1], SImode))
1890 if (! reload_in_progress)
1892 operands[0] = validize_mem (operands[0]);
1893 operands[1] = force_reg (SImode, operands[1]);
1897 /* Fixup TLS cases. */
1898 if (tls_symbolic_operand (operands [1]))
1899 operands[1] = legitimize_tls_address (operands[1]);
1901 /* Fixup PIC cases. */
1904 if (CONSTANT_P (operands[1])
1905 && pic_address_needs_scratch (operands[1]))
1906 operands[1] = legitimize_pic_address (operands[1], SImode, 0);
1908 if (GET_CODE (operands[1]) == LABEL_REF)
1911 emit_insn (gen_movsi_pic_label_ref (operands[0], operands[1]));
1915 if (symbolic_operand (operands[1], SImode))
1917 operands[1] = legitimize_pic_address (operands[1],
1919 (reload_in_progress ?
1926 /* If we are trying to toss an integer constant into the
1927 FPU registers, force it into memory. */
1928 if (GET_CODE (operands[0]) == REG
1929 && REGNO (operands[0]) >= SPARC_FIRST_FP_REG
1930 && REGNO (operands[0]) <= SPARC_LAST_V9_FP_REG
1931 && CONSTANT_P (operands[1]))
1932 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
1935 /* This makes sure we will not get rematched due to splittage. */
1936 if (! CONSTANT_P (operands[1]) || input_operand (operands[1], SImode))
1938 else if (CONSTANT_P (operands[1])
1939 && GET_CODE (operands[1]) != HIGH
1940 && GET_CODE (operands[1]) != LO_SUM)
1942 sparc_emit_set_const32 (operands[0], operands[1]);
1949 ;; This is needed to show CSE exactly which bits are set
1950 ;; in a 64-bit register by sethi instructions.
1951 (define_insn "*movsi_const64_special"
1952 [(set (match_operand:SI 0 "register_operand" "=r")
1953 (match_operand:SI 1 "const_high_operand" "K"))]
1955 "sethi\t%%hi(%a1), %0")
1957 (define_insn "*movsi_insn"
1958 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,f,r,r,r,f,m,m,d")
1959 (match_operand:SI 1 "input_operand" "rI,!f,K,J,m,!m,rJ,!f,J"))]
1960 "(register_operand (operands[0], SImode)
1961 || register_or_zero_operand (operands[1], SImode))"
1965 sethi\t%%hi(%a1), %0
1972 [(set_attr "type" "*,fpmove,*,*,load,fpload,store,fpstore,fga")])
1974 (define_insn "*movsi_lo_sum"
1975 [(set (match_operand:SI 0 "register_operand" "=r")
1976 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1977 (match_operand:SI 2 "immediate_operand" "in")))]
1979 "or\t%1, %%lo(%a2), %0")
1981 (define_insn "*movsi_high"
1982 [(set (match_operand:SI 0 "register_operand" "=r")
1983 (high:SI (match_operand:SI 1 "immediate_operand" "in")))]
1985 "sethi\t%%hi(%a1), %0")
1987 ;; The next two patterns must wrap the SYMBOL_REF in an UNSPEC
1988 ;; so that CSE won't optimize the address computation away.
1989 (define_insn "movsi_lo_sum_pic"
1990 [(set (match_operand:SI 0 "register_operand" "=r")
1991 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1992 (unspec:SI [(match_operand:SI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
1994 "or\t%1, %%lo(%a2), %0")
1996 (define_insn "movsi_high_pic"
1997 [(set (match_operand:SI 0 "register_operand" "=r")
1998 (high:SI (unspec:SI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
1999 "flag_pic && check_pic (1)"
2000 "sethi\t%%hi(%a1), %0")
2002 (define_expand "movsi_pic_label_ref"
2003 [(set (match_dup 3) (high:SI
2004 (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
2005 (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
2006 (set (match_dup 4) (lo_sum:SI (match_dup 3)
2007 (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
2008 (set (match_operand:SI 0 "register_operand" "=r")
2009 (minus:SI (match_dup 5) (match_dup 4)))]
2012 current_function_uses_pic_offset_table = 1;
2013 operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
2016 operands[3] = operands[0];
2017 operands[4] = operands[0];
2021 operands[3] = gen_reg_rtx (SImode);
2022 operands[4] = gen_reg_rtx (SImode);
2024 operands[5] = pic_offset_table_rtx;
2027 (define_insn "*movsi_high_pic_label_ref"
2028 [(set (match_operand:SI 0 "register_operand" "=r")
2030 (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
2031 (match_operand:SI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
2033 "sethi\t%%hi(%a2-(%a1-.)), %0")
2035 (define_insn "*movsi_lo_sum_pic_label_ref"
2036 [(set (match_operand:SI 0 "register_operand" "=r")
2037 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
2038 (unspec:SI [(match_operand:SI 2 "label_ref_operand" "")
2039 (match_operand:SI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
2041 "or\t%1, %%lo(%a3-(%a2-.)), %0")
2043 (define_expand "movdi"
2044 [(set (match_operand:DI 0 "general_operand" "")
2045 (match_operand:DI 1 "general_operand" ""))]
2048 /* Where possible, convert CONST_DOUBLE into a CONST_INT. */
2049 if (GET_CODE (operands[1]) == CONST_DOUBLE
2050 #if HOST_BITS_PER_WIDE_INT == 32
2051 && ((CONST_DOUBLE_HIGH (operands[1]) == 0
2052 && (CONST_DOUBLE_LOW (operands[1]) & 0x80000000) == 0)
2053 || (CONST_DOUBLE_HIGH (operands[1]) == (HOST_WIDE_INT) 0xffffffff
2054 && (CONST_DOUBLE_LOW (operands[1]) & 0x80000000) != 0))
2057 operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
2059 /* Handle MEM cases first. */
2060 if (GET_CODE (operands[0]) == MEM)
2062 /* If it's a REG, we can always do it.
2063 The const zero case is more complex, on v9
2064 we can always perform it. */
2065 if (register_operand (operands[1], DImode)
2067 && (operands[1] == const0_rtx)))
2070 if (! reload_in_progress)
2072 operands[0] = validize_mem (operands[0]);
2073 operands[1] = force_reg (DImode, operands[1]);
2077 /* Fixup TLS cases. */
2078 if (tls_symbolic_operand (operands [1]))
2079 operands[1] = legitimize_tls_address (operands[1]);
2083 if (CONSTANT_P (operands[1])
2084 && pic_address_needs_scratch (operands[1]))
2085 operands[1] = legitimize_pic_address (operands[1], DImode, 0);
2087 if (GET_CODE (operands[1]) == LABEL_REF)
2089 gcc_assert (TARGET_ARCH64);
2090 emit_insn (gen_movdi_pic_label_ref (operands[0], operands[1]));
2094 if (symbolic_operand (operands[1], DImode))
2096 operands[1] = legitimize_pic_address (operands[1],
2098 (reload_in_progress ?
2105 /* If we are trying to toss an integer constant into the
2106 FPU registers, force it into memory. */
2107 if (GET_CODE (operands[0]) == REG
2108 && REGNO (operands[0]) >= SPARC_FIRST_FP_REG
2109 && REGNO (operands[0]) <= SPARC_LAST_V9_FP_REG
2110 && CONSTANT_P (operands[1]))
2111 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
2114 /* This makes sure we will not get rematched due to splittage. */
2115 if (! CONSTANT_P (operands[1]) || input_operand (operands[1], DImode))
2117 else if (TARGET_ARCH64
2118 && GET_CODE (operands[1]) != HIGH
2119 && GET_CODE (operands[1]) != LO_SUM)
2121 sparc_emit_set_const64 (operands[0], operands[1]);
2129 ;; Be careful, fmovd does not exist when !v9.
2130 ;; We match MEM moves directly when we have correct even
2131 ;; numbered registers, but fall into splits otherwise.
2132 ;; The constraint ordering here is really important to
2133 ;; avoid insane problems in reload, especially for patterns
2136 ;; (set (mem:DI (plus:SI (reg:SI 30 %fp)
2137 ;; (const_int -5016)))
2141 (define_insn "*movdi_insn_sp32_v9"
2142 [(set (match_operand:DI 0 "nonimmediate_operand"
2143 "=T,o,T,U,o,r,r,r,?T,?f,?f,?o,?e,?e,?W")
2144 (match_operand:DI 1 "input_operand"
2145 " J,J,U,T,r,o,i,r, f, T, o, f, e, W, e"))]
2146 "! TARGET_ARCH64 && TARGET_V9
2147 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2164 [(set_attr "type" "store,store,store,load,*,*,*,*,fpstore,fpload,*,*,fpmove,fpload,fpstore")
2165 (set_attr "length" "*,2,*,*,2,2,2,2,*,*,2,2,*,*,*")
2166 (set_attr "fptype" "*,*,*,*,*,*,*,*,*,*,*,*,double,*,*")])
2168 (define_insn "*movdi_insn_sp32"
2169 [(set (match_operand:DI 0 "nonimmediate_operand"
2170 "=o,T,U,o,r,r,r,?T,?f,?f,?o,?f")
2171 (match_operand:DI 1 "input_operand"
2172 " J,U,T,r,o,i,r, f, T, o, f, f"))]
2174 && (register_operand (operands[0], DImode)
2175 || register_operand (operands[1], DImode))"
2189 [(set_attr "type" "store,store,load,*,*,*,*,fpstore,fpload,*,*,*")
2190 (set_attr "length" "2,*,*,2,2,2,2,*,*,2,2,2")])
2192 ;; This is needed to show CSE exactly which bits are set
2193 ;; in a 64-bit register by sethi instructions.
2194 (define_insn "*movdi_const64_special"
2195 [(set (match_operand:DI 0 "register_operand" "=r")
2196 (match_operand:DI 1 "const_high_operand" "N"))]
2198 "sethi\t%%hi(%a1), %0")
2200 (define_insn "*movdi_insn_sp64_novis"
2201 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,m,?e,?e,?W")
2202 (match_operand:DI 1 "input_operand" "rI,N,J,m,rJ,e,W,e"))]
2203 "TARGET_ARCH64 && ! TARGET_VIS
2204 && (register_operand (operands[0], DImode)
2205 || register_or_zero_operand (operands[1], DImode))"
2208 sethi\t%%hi(%a1), %0
2215 [(set_attr "type" "*,*,*,load,store,fpmove,fpload,fpstore")
2216 (set_attr "fptype" "*,*,*,*,*,double,*,*")])
2218 ;; We don't define V1SI because SI should work just fine.
2219 (define_mode_macro V64 [DF V2SI V4HI V8QI])
2220 (define_mode_macro V32 [SF V2HI V4QI])
2222 (define_insn "*movdi_insn_sp64_vis"
2223 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,m,?e,?e,?W,b")
2224 (match_operand:DI 1 "input_operand" "rI,N,J,m,rJ,e,W,e,J"))]
2225 "TARGET_ARCH64 && TARGET_VIS &&
2226 (register_operand (operands[0], DImode)
2227 || register_or_zero_operand (operands[1], DImode))"
2230 sethi\t%%hi(%a1), %0
2238 [(set_attr "type" "*,*,*,load,store,fpmove,fpload,fpstore,fga")
2239 (set_attr "fptype" "*,*,*,*,*,double,*,*,double")])
2241 (define_expand "movdi_pic_label_ref"
2242 [(set (match_dup 3) (high:DI
2243 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
2244 (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
2245 (set (match_dup 4) (lo_sum:DI (match_dup 3)
2246 (unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
2247 (set (match_operand:DI 0 "register_operand" "=r")
2248 (minus:DI (match_dup 5) (match_dup 4)))]
2249 "TARGET_ARCH64 && flag_pic"
2251 current_function_uses_pic_offset_table = 1;
2252 operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
2255 operands[3] = operands[0];
2256 operands[4] = operands[0];
2260 operands[3] = gen_reg_rtx (DImode);
2261 operands[4] = gen_reg_rtx (DImode);
2263 operands[5] = pic_offset_table_rtx;
2266 (define_insn "*movdi_high_pic_label_ref"
2267 [(set (match_operand:DI 0 "register_operand" "=r")
2269 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
2270 (match_operand:DI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
2271 "TARGET_ARCH64 && flag_pic"
2272 "sethi\t%%hi(%a2-(%a1-.)), %0")
2274 (define_insn "*movdi_lo_sum_pic_label_ref"
2275 [(set (match_operand:DI 0 "register_operand" "=r")
2276 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2277 (unspec:DI [(match_operand:DI 2 "label_ref_operand" "")
2278 (match_operand:DI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
2279 "TARGET_ARCH64 && flag_pic"
2280 "or\t%1, %%lo(%a3-(%a2-.)), %0")
2282 ;; SPARC-v9 code model support insns. See sparc_emit_set_symbolic_const64
2283 ;; in sparc.c to see what is going on here... PIC stuff comes first.
2285 (define_insn "movdi_lo_sum_pic"
2286 [(set (match_operand:DI 0 "register_operand" "=r")
2287 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2288 (unspec:DI [(match_operand:DI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
2289 "TARGET_ARCH64 && flag_pic"
2290 "or\t%1, %%lo(%a2), %0")
2292 (define_insn "movdi_high_pic"
2293 [(set (match_operand:DI 0 "register_operand" "=r")
2294 (high:DI (unspec:DI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
2295 "TARGET_ARCH64 && flag_pic && check_pic (1)"
2296 "sethi\t%%hi(%a1), %0")
2298 (define_insn "*sethi_di_medlow_embmedany_pic"
2299 [(set (match_operand:DI 0 "register_operand" "=r")
2300 (high:DI (match_operand:DI 1 "medium_pic_operand" "")))]
2301 "(TARGET_CM_MEDLOW || TARGET_CM_EMBMEDANY) && check_pic (1)"
2302 "sethi\t%%hi(%a1), %0")
2304 (define_insn "*sethi_di_medlow"
2305 [(set (match_operand:DI 0 "register_operand" "=r")
2306 (high:DI (match_operand:DI 1 "symbolic_operand" "")))]
2307 "TARGET_CM_MEDLOW && check_pic (1)"
2308 "sethi\t%%hi(%a1), %0")
2310 (define_insn "*losum_di_medlow"
2311 [(set (match_operand:DI 0 "register_operand" "=r")
2312 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2313 (match_operand:DI 2 "symbolic_operand" "")))]
2315 "or\t%1, %%lo(%a2), %0")
2317 (define_insn "seth44"
2318 [(set (match_operand:DI 0 "register_operand" "=r")
2319 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETH44)))]
2321 "sethi\t%%h44(%a1), %0")
2323 (define_insn "setm44"
2324 [(set (match_operand:DI 0 "register_operand" "=r")
2325 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2326 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_SETM44)))]
2328 "or\t%1, %%m44(%a2), %0")
2330 (define_insn "setl44"
2331 [(set (match_operand:DI 0 "register_operand" "=r")
2332 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2333 (match_operand:DI 2 "symbolic_operand" "")))]
2335 "or\t%1, %%l44(%a2), %0")
2337 (define_insn "sethh"
2338 [(set (match_operand:DI 0 "register_operand" "=r")
2339 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETHH)))]
2341 "sethi\t%%hh(%a1), %0")
2343 (define_insn "setlm"
2344 [(set (match_operand:DI 0 "register_operand" "=r")
2345 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETLM)))]
2347 "sethi\t%%lm(%a1), %0")
2349 (define_insn "sethm"
2350 [(set (match_operand:DI 0 "register_operand" "=r")
2351 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2352 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_EMB_SETHM)))]
2354 "or\t%1, %%hm(%a2), %0")
2356 (define_insn "setlo"
2357 [(set (match_operand:DI 0 "register_operand" "=r")
2358 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2359 (match_operand:DI 2 "symbolic_operand" "")))]
2361 "or\t%1, %%lo(%a2), %0")
2363 (define_insn "embmedany_sethi"
2364 [(set (match_operand:DI 0 "register_operand" "=r")
2365 (high:DI (unspec:DI [(match_operand:DI 1 "data_segment_operand" "")] UNSPEC_EMB_HISUM)))]
2366 "TARGET_CM_EMBMEDANY && check_pic (1)"
2367 "sethi\t%%hi(%a1), %0")
2369 (define_insn "embmedany_losum"
2370 [(set (match_operand:DI 0 "register_operand" "=r")
2371 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2372 (match_operand:DI 2 "data_segment_operand" "")))]
2373 "TARGET_CM_EMBMEDANY"
2374 "add\t%1, %%lo(%a2), %0")
2376 (define_insn "embmedany_brsum"
2377 [(set (match_operand:DI 0 "register_operand" "=r")
2378 (unspec:DI [(match_operand:DI 1 "register_operand" "r")] UNSPEC_EMB_HISUM))]
2379 "TARGET_CM_EMBMEDANY"
2382 (define_insn "embmedany_textuhi"
2383 [(set (match_operand:DI 0 "register_operand" "=r")
2384 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTUHI)))]
2385 "TARGET_CM_EMBMEDANY && check_pic (1)"
2386 "sethi\t%%uhi(%a1), %0")
2388 (define_insn "embmedany_texthi"
2389 [(set (match_operand:DI 0 "register_operand" "=r")
2390 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTHI)))]
2391 "TARGET_CM_EMBMEDANY && check_pic (1)"
2392 "sethi\t%%hi(%a1), %0")
2394 (define_insn "embmedany_textulo"
2395 [(set (match_operand:DI 0 "register_operand" "=r")
2396 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2397 (unspec:DI [(match_operand:DI 2 "text_segment_operand" "")] UNSPEC_EMB_TEXTULO)))]
2398 "TARGET_CM_EMBMEDANY"
2399 "or\t%1, %%ulo(%a2), %0")
2401 (define_insn "embmedany_textlo"
2402 [(set (match_operand:DI 0 "register_operand" "=r")
2403 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2404 (match_operand:DI 2 "text_segment_operand" "")))]
2405 "TARGET_CM_EMBMEDANY"
2406 "or\t%1, %%lo(%a2), %0")
2408 ;; Now some patterns to help reload out a bit.
2409 (define_expand "reload_indi"
2410 [(parallel [(match_operand:DI 0 "register_operand" "=r")
2411 (match_operand:DI 1 "immediate_operand" "")
2412 (match_operand:TI 2 "register_operand" "=&r")])]
2414 || TARGET_CM_EMBMEDANY)
2417 sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
2421 (define_expand "reload_outdi"
2422 [(parallel [(match_operand:DI 0 "register_operand" "=r")
2423 (match_operand:DI 1 "immediate_operand" "")
2424 (match_operand:TI 2 "register_operand" "=&r")])]
2426 || TARGET_CM_EMBMEDANY)
2429 sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
2433 ;; Split up putting CONSTs and REGs into DI regs when !arch64
2435 [(set (match_operand:DI 0 "register_operand" "")
2436 (match_operand:DI 1 "const_int_operand" ""))]
2437 "! TARGET_ARCH64 && reload_completed"
2438 [(clobber (const_int 0))]
2440 #if HOST_BITS_PER_WIDE_INT == 32
2441 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
2442 (INTVAL (operands[1]) < 0) ?
2445 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2448 unsigned int low, high;
2450 low = trunc_int_for_mode (INTVAL (operands[1]), SImode);
2451 high = trunc_int_for_mode (INTVAL (operands[1]) >> 32, SImode);
2452 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), GEN_INT (high)));
2454 /* Slick... but this trick loses if this subreg constant part
2455 can be done in one insn. */
2456 if (low == high && (low & 0x3ff) != 0 && low + 0x1000 >= 0x2000)
2457 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2458 gen_highpart (SImode, operands[0])));
2460 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), GEN_INT (low)));
2466 [(set (match_operand:DI 0 "register_operand" "")
2467 (match_operand:DI 1 "const_double_operand" ""))]
2471 && ((GET_CODE (operands[0]) == REG
2472 && REGNO (operands[0]) < 32)
2473 || (GET_CODE (operands[0]) == SUBREG
2474 && GET_CODE (SUBREG_REG (operands[0])) == REG
2475 && REGNO (SUBREG_REG (operands[0])) < 32))))"
2476 [(clobber (const_int 0))]
2478 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
2479 GEN_INT (CONST_DOUBLE_HIGH (operands[1]))));
2481 /* Slick... but this trick loses if this subreg constant part
2482 can be done in one insn. */
2483 if (CONST_DOUBLE_LOW (operands[1]) == CONST_DOUBLE_HIGH (operands[1])
2484 && !(SPARC_SETHI32_P (CONST_DOUBLE_HIGH (operands[1]))
2485 || SPARC_SIMM13_P (CONST_DOUBLE_HIGH (operands[1]))))
2487 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2488 gen_highpart (SImode, operands[0])));
2492 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2493 GEN_INT (CONST_DOUBLE_LOW (operands[1]))));
2499 [(set (match_operand:DI 0 "register_operand" "")
2500 (match_operand:DI 1 "register_operand" ""))]
2504 && ((GET_CODE (operands[0]) == REG
2505 && REGNO (operands[0]) < 32)
2506 || (GET_CODE (operands[0]) == SUBREG
2507 && GET_CODE (SUBREG_REG (operands[0])) == REG
2508 && REGNO (SUBREG_REG (operands[0])) < 32))))"
2509 [(clobber (const_int 0))]
2511 rtx set_dest = operands[0];
2512 rtx set_src = operands[1];
2516 dest1 = gen_highpart (SImode, set_dest);
2517 dest2 = gen_lowpart (SImode, set_dest);
2518 src1 = gen_highpart (SImode, set_src);
2519 src2 = gen_lowpart (SImode, set_src);
2521 /* Now emit using the real source and destination we found, swapping
2522 the order if we detect overlap. */
2523 if (reg_overlap_mentioned_p (dest1, src2))
2525 emit_insn (gen_movsi (dest2, src2));
2526 emit_insn (gen_movsi (dest1, src1));
2530 emit_insn (gen_movsi (dest1, src1));
2531 emit_insn (gen_movsi (dest2, src2));
2536 ;; Now handle the cases of memory moves from/to non-even
2537 ;; DI mode register pairs.
2539 [(set (match_operand:DI 0 "register_operand" "")
2540 (match_operand:DI 1 "memory_operand" ""))]
2543 && sparc_splitdi_legitimate (operands[0], operands[1]))"
2544 [(clobber (const_int 0))]
2546 rtx word0 = adjust_address (operands[1], SImode, 0);
2547 rtx word1 = adjust_address (operands[1], SImode, 4);
2548 rtx high_part = gen_highpart (SImode, operands[0]);
2549 rtx low_part = gen_lowpart (SImode, operands[0]);
2551 if (reg_overlap_mentioned_p (high_part, word1))
2553 emit_insn (gen_movsi (low_part, word1));
2554 emit_insn (gen_movsi (high_part, word0));
2558 emit_insn (gen_movsi (high_part, word0));
2559 emit_insn (gen_movsi (low_part, word1));
2565 [(set (match_operand:DI 0 "memory_operand" "")
2566 (match_operand:DI 1 "register_operand" ""))]
2569 && sparc_splitdi_legitimate (operands[1], operands[0]))"
2570 [(clobber (const_int 0))]
2572 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0),
2573 gen_highpart (SImode, operands[1])));
2574 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4),
2575 gen_lowpart (SImode, operands[1])));
2580 [(set (match_operand:DI 0 "memory_operand" "")
2585 && ! mem_min_alignment (operands[0], 8)))
2586 && offsettable_memref_p (operands[0])"
2587 [(clobber (const_int 0))]
2589 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0), const0_rtx));
2590 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4), const0_rtx));
2594 ;; Floating point move insns
2596 (define_insn "*movsf_insn_novis"
2597 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,*r,*r,*r,*r,*r,f,m,m")
2598 (match_operand:SF 1 "input_operand" "f,G,Q,*rR,S,m,m,f,*rG"))]
2599 "(TARGET_FPU && ! TARGET_VIS)
2600 && (register_operand (operands[0], SFmode)
2601 || register_operand (operands[1], SFmode)
2602 || const_zero_operand (operands[1], SFmode))"
2604 if (GET_CODE (operands[1]) == CONST_DOUBLE
2605 && (which_alternative == 2
2606 || which_alternative == 3
2607 || which_alternative == 4))
2612 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2613 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2614 operands[1] = GEN_INT (i);
2617 switch (which_alternative)
2620 return "fmovs\t%1, %0";
2624 return "sethi\t%%hi(%a1), %0";
2626 return "mov\t%1, %0";
2631 return "ld\t%1, %0";
2634 return "st\t%r1, %0";
2639 [(set_attr "type" "fpmove,*,*,*,*,load,fpload,fpstore,store")])
2641 (define_insn "*movsf_insn_vis"
2642 [(set (match_operand:V32 0 "nonimmediate_operand" "=f,f,*r,*r,*r,*r,*r,f,m,m")
2643 (match_operand:V32 1 "input_operand" "f,GY,GY,Q,*rR,S,m,m,f,*rGY"))]
2644 "(TARGET_FPU && TARGET_VIS)
2645 && (register_operand (operands[0], <V32:MODE>mode)
2646 || register_operand (operands[1], <V32:MODE>mode)
2647 || const_zero_operand (operands[1], <V32:MODE>mode))"
2649 if (GET_CODE (operands[1]) == CONST_DOUBLE
2650 && (which_alternative == 3
2651 || which_alternative == 4
2652 || which_alternative == 5))
2657 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2658 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2659 operands[1] = GEN_INT (i);
2662 switch (which_alternative)
2665 return "fmovs\t%1, %0";
2667 return "fzeros\t%0";
2671 return "sethi\t%%hi(%a1), %0";
2673 return "mov\t%1, %0";
2678 return "ld\t%1, %0";
2681 return "st\t%r1, %0";
2686 [(set_attr "type" "fpmove,fga,*,*,*,*,load,fpload,fpstore,store")])
2688 ;; Exactly the same as above, except that all `f' cases are deleted.
2689 ;; This is necessary to prevent reload from ever trying to use a `f' reg
2692 (define_insn "*movsf_no_f_insn"
2693 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r,r,r,m")
2694 (match_operand:SF 1 "input_operand" "G,Q,rR,S,m,rG"))]
2696 && (register_operand (operands[0], SFmode)
2697 || register_operand (operands[1], SFmode)
2698 || const_zero_operand (operands[1], SFmode))"
2700 if (GET_CODE (operands[1]) == CONST_DOUBLE
2701 && (which_alternative == 1
2702 || which_alternative == 2
2703 || which_alternative == 3))
2708 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2709 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2710 operands[1] = GEN_INT (i);
2713 switch (which_alternative)
2718 return "sethi\t%%hi(%a1), %0";
2720 return "mov\t%1, %0";
2724 return "ld\t%1, %0";
2726 return "st\t%r1, %0";
2731 [(set_attr "type" "*,*,*,*,load,store")])
2733 ;; The following 3 patterns build SFmode constants in integer registers.
2735 (define_insn "*movsf_lo_sum"
2736 [(set (match_operand:SF 0 "register_operand" "=r")
2737 (lo_sum:SF (match_operand:SF 1 "register_operand" "r")
2738 (match_operand:SF 2 "const_double_operand" "S")))]
2739 "fp_high_losum_p (operands[2])"
2744 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[2]);
2745 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2746 operands[2] = GEN_INT (i);
2747 return "or\t%1, %%lo(%a2), %0";
2750 (define_insn "*movsf_high"
2751 [(set (match_operand:SF 0 "register_operand" "=r")
2752 (high:SF (match_operand:SF 1 "const_double_operand" "S")))]
2753 "fp_high_losum_p (operands[1])"
2758 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2759 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2760 operands[1] = GEN_INT (i);
2761 return "sethi\t%%hi(%1), %0";
2765 [(set (match_operand:SF 0 "register_operand" "")
2766 (match_operand:SF 1 "const_double_operand" ""))]
2767 "fp_high_losum_p (operands[1])
2768 && (GET_CODE (operands[0]) == REG
2769 && REGNO (operands[0]) < 32)"
2770 [(set (match_dup 0) (high:SF (match_dup 1)))
2771 (set (match_dup 0) (lo_sum:SF (match_dup 0) (match_dup 1)))])
2773 ;; Yes, you guessed it right, the former movsf expander.
2774 (define_expand "mov<V32:mode>"
2775 [(set (match_operand:V32 0 "general_operand" "")
2776 (match_operand:V32 1 "general_operand" ""))]
2777 "<V32:MODE>mode == SFmode || TARGET_VIS"
2779 /* Force constants into memory. */
2780 if (GET_CODE (operands[0]) == REG && CONSTANT_P (operands[1]))
2782 /* emit_group_store will send such bogosity to us when it is
2783 not storing directly into memory. So fix this up to avoid
2784 crashes in output_constant_pool. */
2785 if (operands [1] == const0_rtx)
2786 operands[1] = CONST0_RTX (<V32:MODE>mode);
2788 if ((TARGET_VIS || REGNO (operands[0]) < 32)
2789 && const_zero_operand (operands[1], <V32:MODE>mode))
2792 /* We are able to build any SF constant in integer registers
2793 with at most 2 instructions. */
2794 if (REGNO (operands[0]) < 32
2795 && <V32:MODE>mode == SFmode)
2798 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
2802 /* Handle sets of MEM first. */
2803 if (GET_CODE (operands[0]) == MEM)
2805 if (register_operand (operands[1], <V32:MODE>mode)
2806 || const_zero_operand (operands[1], <V32:MODE>mode))
2809 if (! reload_in_progress)
2811 operands[0] = validize_mem (operands[0]);
2812 operands[1] = force_reg (<V32:MODE>mode, operands[1]);
2816 /* Fixup PIC cases. */
2819 if (CONSTANT_P (operands[1])
2820 && pic_address_needs_scratch (operands[1]))
2821 operands[1] = legitimize_pic_address (operands[1], <V32:MODE>mode, 0);
2823 if (symbolic_operand (operands[1], <V32:MODE>mode))
2825 operands[1] = legitimize_pic_address (operands[1],
2827 (reload_in_progress ?
2837 ;; Yes, you again guessed it right, the former movdf expander.
2838 (define_expand "mov<V64:mode>"
2839 [(set (match_operand:V64 0 "general_operand" "")
2840 (match_operand:V64 1 "general_operand" ""))]
2841 "<V64:MODE>mode == DFmode || TARGET_VIS"
2843 /* Force constants into memory. */
2844 if (GET_CODE (operands[0]) == REG && CONSTANT_P (operands[1]))
2846 /* emit_group_store will send such bogosity to us when it is
2847 not storing directly into memory. So fix this up to avoid
2848 crashes in output_constant_pool. */
2849 if (operands [1] == const0_rtx)
2850 operands[1] = CONST0_RTX (<V64:MODE>mode);
2852 if ((TARGET_VIS || REGNO (operands[0]) < 32)
2853 && const_zero_operand (operands[1], <V64:MODE>mode))
2856 /* We are able to build any DF constant in integer registers. */
2857 if (REGNO (operands[0]) < 32
2858 && <V64:MODE>mode == DFmode
2859 && (reload_completed || reload_in_progress))
2862 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
2866 /* Handle MEM cases first. */
2867 if (GET_CODE (operands[0]) == MEM)
2869 if (register_operand (operands[1], <V64:MODE>mode)
2870 || const_zero_operand (operands[1], <V64:MODE>mode))
2873 if (! reload_in_progress)
2875 operands[0] = validize_mem (operands[0]);
2876 operands[1] = force_reg (<V64:MODE>mode, operands[1]);
2880 /* Fixup PIC cases. */
2883 if (CONSTANT_P (operands[1])
2884 && pic_address_needs_scratch (operands[1]))
2885 operands[1] = legitimize_pic_address (operands[1], <V64:MODE>mode, 0);
2887 if (symbolic_operand (operands[1], <V64:MODE>mode))
2889 operands[1] = legitimize_pic_address (operands[1],
2891 (reload_in_progress ?
2901 ;; Be careful, fmovd does not exist when !v9.
2902 (define_insn "*movdf_insn_sp32"
2903 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,W,U,T,o,e,*r,o,e,o")
2904 (match_operand:DF 1 "input_operand" "W#F,e,T,U,G,e,*rFo,*r,o#F,e"))]
2907 && (register_operand (operands[0], DFmode)
2908 || register_operand (operands[1], DFmode)
2909 || const_zero_operand (operands[1], DFmode))"
2921 [(set_attr "type" "fpload,fpstore,load,store,*,*,*,*,*,*")
2922 (set_attr "length" "*,*,*,*,2,2,2,2,2,2")])
2924 (define_insn "*movdf_no_e_insn_sp32"
2925 [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,o,r,o")
2926 (match_operand:DF 1 "input_operand" "T,U,G,ro,r"))]
2930 && (register_operand (operands[0], DFmode)
2931 || register_operand (operands[1], DFmode)
2932 || const_zero_operand (operands[1], DFmode))"
2939 [(set_attr "type" "load,store,*,*,*")
2940 (set_attr "length" "*,*,2,2,2")])
2942 (define_insn "*movdf_no_e_insn_v9_sp32"
2943 [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,T,r,o")
2944 (match_operand:DF 1 "input_operand" "T,U,G,ro,rG"))]
2948 && (register_operand (operands[0], DFmode)
2949 || register_operand (operands[1], DFmode)
2950 || const_zero_operand (operands[1], DFmode))"
2957 [(set_attr "type" "load,store,store,*,*")
2958 (set_attr "length" "*,*,*,2,2")])
2960 ;; We have available v9 double floats but not 64-bit
2961 ;; integer registers and no VIS.
2962 (define_insn "*movdf_insn_v9only_novis"
2963 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,T,W,U,T,f,*r,o")
2964 (match_operand:DF 1 "input_operand" "e,W#F,G,e,T,U,o#F,*roF,*rGf"))]
2969 && (register_operand (operands[0], DFmode)
2970 || register_operand (operands[1], DFmode)
2971 || const_zero_operand (operands[1], DFmode))"
2982 [(set_attr "type" "fpmove,load,store,store,load,store,*,*,*")
2983 (set_attr "length" "*,*,*,*,*,*,2,2,2")
2984 (set_attr "fptype" "double,*,*,*,*,*,*,*,*")])
2986 ;; We have available v9 double floats but not 64-bit
2987 ;; integer registers but we have VIS.
2988 (define_insn "*movdf_insn_v9only_vis"
2989 [(set (match_operand:V64 0 "nonimmediate_operand" "=e,e,e,T,W,U,T,f,*r,o")
2990 (match_operand:V64 1 "input_operand" "GY,e,W#F,GY,e,T,U,o#F,*roGYF,*rGYf"))]
2994 && (register_operand (operands[0], <V64:MODE>mode)
2995 || register_operand (operands[1], <V64:MODE>mode)
2996 || const_zero_operand (operands[1], <V64:MODE>mode))"
3008 [(set_attr "type" "fga,fpmove,load,store,store,load,store,*,*,*")
3009 (set_attr "length" "*,*,*,*,*,*,*,2,2,2")
3010 (set_attr "fptype" "double,double,*,*,*,*,*,*,*,*")])
3012 ;; We have available both v9 double floats and 64-bit
3013 ;; integer registers. No VIS though.
3014 (define_insn "*movdf_insn_sp64_novis"
3015 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,W,*r,*r,m,*r")
3016 (match_operand:DF 1 "input_operand" "e,W#F,e,*rG,m,*rG,F"))]
3020 && (register_operand (operands[0], DFmode)
3021 || register_operand (operands[1], DFmode)
3022 || const_zero_operand (operands[1], DFmode))"
3031 [(set_attr "type" "fpmove,load,store,*,load,store,*")
3032 (set_attr "length" "*,*,*,*,*,*,2")
3033 (set_attr "fptype" "double,*,*,*,*,*,*")])
3035 ;; We have available both v9 double floats and 64-bit
3036 ;; integer registers. And we have VIS.
3037 (define_insn "*movdf_insn_sp64_vis"
3038 [(set (match_operand:V64 0 "nonimmediate_operand" "=e,e,e,W,*r,*r,m,*r")
3039 (match_operand:V64 1 "input_operand" "GY,e,W#F,e,*rGY,m,*rGY,F"))]
3043 && (register_operand (operands[0], <V64:MODE>mode)
3044 || register_operand (operands[1], <V64:MODE>mode)
3045 || const_zero_operand (operands[1], <V64:MODE>mode))"
3055 [(set_attr "type" "fga,fpmove,load,store,*,load,store,*")
3056 (set_attr "length" "*,*,*,*,*,*,*,2")
3057 (set_attr "fptype" "double,double,*,*,*,*,*,*")])
3059 (define_insn "*movdf_no_e_insn_sp64"
3060 [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m")
3061 (match_operand:DF 1 "input_operand" "r,m,rG"))]
3064 && (register_operand (operands[0], DFmode)
3065 || register_operand (operands[1], DFmode)
3066 || const_zero_operand (operands[1], DFmode))"
3071 [(set_attr "type" "*,load,store")])
3073 ;; This pattern build DFmode constants in integer registers.
3075 [(set (match_operand:DF 0 "register_operand" "")
3076 (match_operand:DF 1 "const_double_operand" ""))]
3078 && (GET_CODE (operands[0]) == REG
3079 && REGNO (operands[0]) < 32)
3080 && ! const_zero_operand(operands[1], DFmode)
3081 && reload_completed"
3082 [(clobber (const_int 0))]
3087 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3088 REAL_VALUE_TO_TARGET_DOUBLE (r, l);
3089 operands[0] = gen_rtx_raw_REG (DImode, REGNO (operands[0]));
3093 #if HOST_BITS_PER_WIDE_INT == 64
3096 val = ((HOST_WIDE_INT)(unsigned long)l[1] |
3097 ((HOST_WIDE_INT)(unsigned long)l[0] << 32));
3098 emit_insn (gen_movdi (operands[0], GEN_INT (val)));
3100 emit_insn (gen_movdi (operands[0],
3101 immed_double_const (l[1], l[0], DImode)));
3106 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
3109 /* Slick... but this trick loses if this subreg constant part
3110 can be done in one insn. */
3112 && !(SPARC_SETHI32_P (l[0])
3113 || SPARC_SIMM13_P (l[0])))
3115 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
3116 gen_highpart (SImode, operands[0])));
3120 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
3127 ;; Ok, now the splits to handle all the multi insn and
3128 ;; mis-aligned memory address cases.
3129 ;; In these splits please take note that we must be
3130 ;; careful when V9 but not ARCH64 because the integer
3131 ;; register DFmode cases must be handled.
3133 [(set (match_operand:V64 0 "register_operand" "")
3134 (match_operand:V64 1 "register_operand" ""))]
3137 && ((GET_CODE (operands[0]) == REG
3138 && REGNO (operands[0]) < 32)
3139 || (GET_CODE (operands[0]) == SUBREG
3140 && GET_CODE (SUBREG_REG (operands[0])) == REG
3141 && REGNO (SUBREG_REG (operands[0])) < 32))))
3142 && reload_completed"
3143 [(clobber (const_int 0))]
3145 rtx set_dest = operands[0];
3146 rtx set_src = operands[1];
3149 enum machine_mode half_mode;
3151 /* We can be expanded for DFmode or integral vector modes. */
3152 if (<V64:MODE>mode == DFmode)
3157 dest1 = gen_highpart (half_mode, set_dest);
3158 dest2 = gen_lowpart (half_mode, set_dest);
3159 src1 = gen_highpart (half_mode, set_src);
3160 src2 = gen_lowpart (half_mode, set_src);
3162 /* Now emit using the real source and destination we found, swapping
3163 the order if we detect overlap. */
3164 if (reg_overlap_mentioned_p (dest1, src2))
3166 emit_move_insn_1 (dest2, src2);
3167 emit_move_insn_1 (dest1, src1);
3171 emit_move_insn_1 (dest1, src1);
3172 emit_move_insn_1 (dest2, src2);
3178 [(set (match_operand:V64 0 "register_operand" "")
3179 (match_operand:V64 1 "memory_operand" ""))]
3182 && (((REGNO (operands[0]) % 2) != 0)
3183 || ! mem_min_alignment (operands[1], 8))
3184 && offsettable_memref_p (operands[1])"
3185 [(clobber (const_int 0))]
3187 enum machine_mode half_mode;
3190 /* We can be expanded for DFmode or integral vector modes. */
3191 if (<V64:MODE>mode == DFmode)
3196 word0 = adjust_address (operands[1], half_mode, 0);
3197 word1 = adjust_address (operands[1], half_mode, 4);
3199 if (reg_overlap_mentioned_p (gen_highpart (half_mode, operands[0]), word1))
3201 emit_move_insn_1 (gen_lowpart (half_mode, operands[0]), word1);
3202 emit_move_insn_1 (gen_highpart (half_mode, operands[0]), word0);
3206 emit_move_insn_1 (gen_highpart (half_mode, operands[0]), word0);
3207 emit_move_insn_1 (gen_lowpart (half_mode, operands[0]), word1);
3213 [(set (match_operand:V64 0 "memory_operand" "")
3214 (match_operand:V64 1 "register_operand" ""))]
3217 && (((REGNO (operands[1]) % 2) != 0)
3218 || ! mem_min_alignment (operands[0], 8))
3219 && offsettable_memref_p (operands[0])"
3220 [(clobber (const_int 0))]
3222 enum machine_mode half_mode;
3225 /* We can be expanded for DFmode or integral vector modes. */
3226 if (<V64:MODE>mode == DFmode)
3231 word0 = adjust_address (operands[0], half_mode, 0);
3232 word1 = adjust_address (operands[0], half_mode, 4);
3234 emit_move_insn_1 (word0, gen_highpart (half_mode, operands[1]));
3235 emit_move_insn_1 (word1, gen_lowpart (half_mode, operands[1]));
3240 [(set (match_operand:V64 0 "memory_operand" "")
3241 (match_operand:V64 1 "const_zero_operand" ""))]
3245 && ! mem_min_alignment (operands[0], 8)))
3246 && offsettable_memref_p (operands[0])"
3247 [(clobber (const_int 0))]
3249 enum machine_mode half_mode;
3252 /* We can be expanded for DFmode or integral vector modes. */
3253 if (<V64:MODE>mode == DFmode)
3258 dest1 = adjust_address (operands[0], half_mode, 0);
3259 dest2 = adjust_address (operands[0], half_mode, 4);
3261 emit_move_insn_1 (dest1, CONST0_RTX (half_mode));
3262 emit_move_insn_1 (dest2, CONST0_RTX (half_mode));
3267 [(set (match_operand:V64 0 "register_operand" "")
3268 (match_operand:V64 1 "const_zero_operand" ""))]
3271 && ((GET_CODE (operands[0]) == REG
3272 && REGNO (operands[0]) < 32)
3273 || (GET_CODE (operands[0]) == SUBREG
3274 && GET_CODE (SUBREG_REG (operands[0])) == REG
3275 && REGNO (SUBREG_REG (operands[0])) < 32))"
3276 [(clobber (const_int 0))]
3278 enum machine_mode half_mode;
3279 rtx set_dest = operands[0];
3282 /* We can be expanded for DFmode or integral vector modes. */
3283 if (<V64:MODE>mode == DFmode)
3288 dest1 = gen_highpart (half_mode, set_dest);
3289 dest2 = gen_lowpart (half_mode, set_dest);
3290 emit_move_insn_1 (dest1, CONST0_RTX (half_mode));
3291 emit_move_insn_1 (dest2, CONST0_RTX (half_mode));
3295 (define_expand "movtf"
3296 [(set (match_operand:TF 0 "general_operand" "")
3297 (match_operand:TF 1 "general_operand" ""))]
3300 /* Force TFmode constants into memory. */
3301 if (GET_CODE (operands[0]) == REG
3302 && CONSTANT_P (operands[1]))
3304 /* emit_group_store will send such bogosity to us when it is
3305 not storing directly into memory. So fix this up to avoid
3306 crashes in output_constant_pool. */
3307 if (operands [1] == const0_rtx)
3308 operands[1] = CONST0_RTX (TFmode);
3310 if (TARGET_VIS && const_zero_operand (operands[1], TFmode))
3313 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
3317 /* Handle MEM cases first, note that only v9 guarantees
3318 full 16-byte alignment for quads. */
3319 if (GET_CODE (operands[0]) == MEM)
3321 if (register_operand (operands[1], TFmode)
3322 || const_zero_operand (operands[1], TFmode))
3325 if (! reload_in_progress)
3327 operands[0] = validize_mem (operands[0]);
3328 operands[1] = force_reg (TFmode, operands[1]);
3332 /* Fixup PIC cases. */
3335 if (CONSTANT_P (operands[1])
3336 && pic_address_needs_scratch (operands[1]))
3337 operands[1] = legitimize_pic_address (operands[1], TFmode, 0);
3339 if (symbolic_operand (operands[1], TFmode))
3341 operands[1] = legitimize_pic_address (operands[1],
3343 (reload_in_progress ?
3353 ;; Be careful, fmovq and {st,ld}{x,q} do not exist when !arch64 so
3354 ;; we must split them all. :-(
3355 (define_insn "*movtf_insn_sp32"
3356 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,U,r")
3357 (match_operand:TF 1 "input_operand" "oe,GeUr,o,roG"))]
3361 && (register_operand (operands[0], TFmode)
3362 || register_operand (operands[1], TFmode)
3363 || const_zero_operand (operands[1], TFmode))"
3365 [(set_attr "length" "4")])
3367 (define_insn "*movtf_insn_vis_sp32"
3368 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,U,r")
3369 (match_operand:TF 1 "input_operand" "Goe,GeUr,o,roG"))]
3373 && (register_operand (operands[0], TFmode)
3374 || register_operand (operands[1], TFmode)
3375 || const_zero_operand (operands[1], TFmode))"
3377 [(set_attr "length" "4")])
3379 ;; Exactly the same as above, except that all `e' cases are deleted.
3380 ;; This is necessary to prevent reload from ever trying to use a `e' reg
3383 (define_insn "*movtf_no_e_insn_sp32"
3384 [(set (match_operand:TF 0 "nonimmediate_operand" "=o,U,o,r,o")
3385 (match_operand:TF 1 "input_operand" "G,o,U,roG,r"))]
3388 && (register_operand (operands[0], TFmode)
3389 || register_operand (operands[1], TFmode)
3390 || const_zero_operand (operands[1], TFmode))"
3392 [(set_attr "length" "4")])
3394 ;; Now handle the float reg cases directly when arch64,
3395 ;; hard_quad, and proper reg number alignment are all true.
3396 (define_insn "*movtf_insn_hq_sp64"
3397 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,e,m,o,r")
3398 (match_operand:TF 1 "input_operand" "e,m,e,Gr,roG"))]
3403 && (register_operand (operands[0], TFmode)
3404 || register_operand (operands[1], TFmode)
3405 || const_zero_operand (operands[1], TFmode))"
3412 [(set_attr "type" "fpmove,fpload,fpstore,*,*")
3413 (set_attr "length" "*,*,*,2,2")])
3415 (define_insn "*movtf_insn_hq_vis_sp64"
3416 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,e,m,eo,r,o")
3417 (match_operand:TF 1 "input_operand" "e,m,e,G,roG,r"))]
3422 && (register_operand (operands[0], TFmode)
3423 || register_operand (operands[1], TFmode)
3424 || const_zero_operand (operands[1], TFmode))"
3432 [(set_attr "type" "fpmove,fpload,fpstore,*,*,*")
3433 (set_attr "length" "*,*,*,2,2,2")])
3435 ;; Now we allow the integer register cases even when
3436 ;; only arch64 is true.
3437 (define_insn "*movtf_insn_sp64"
3438 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,r")
3439 (match_operand:TF 1 "input_operand" "oe,Ger,orG"))]
3443 && ! TARGET_HARD_QUAD
3444 && (register_operand (operands[0], TFmode)
3445 || register_operand (operands[1], TFmode)
3446 || const_zero_operand (operands[1], TFmode))"
3448 [(set_attr "length" "2")])
3450 (define_insn "*movtf_insn_vis_sp64"
3451 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,r")
3452 (match_operand:TF 1 "input_operand" "Goe,Ger,orG"))]
3456 && ! TARGET_HARD_QUAD
3457 && (register_operand (operands[0], TFmode)
3458 || register_operand (operands[1], TFmode)
3459 || const_zero_operand (operands[1], TFmode))"
3461 [(set_attr "length" "2")])
3463 (define_insn "*movtf_no_e_insn_sp64"
3464 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o")
3465 (match_operand:TF 1 "input_operand" "orG,rG"))]
3468 && (register_operand (operands[0], TFmode)
3469 || register_operand (operands[1], TFmode)
3470 || const_zero_operand (operands[1], TFmode))"
3472 [(set_attr "length" "2")])
3474 ;; Now all the splits to handle multi-insn TF mode moves.
3476 [(set (match_operand:TF 0 "register_operand" "")
3477 (match_operand:TF 1 "register_operand" ""))]
3481 && ! TARGET_HARD_QUAD)
3482 || ! fp_register_operand (operands[0], TFmode))"
3483 [(clobber (const_int 0))]
3485 rtx set_dest = operands[0];
3486 rtx set_src = operands[1];
3490 dest1 = gen_df_reg (set_dest, 0);
3491 dest2 = gen_df_reg (set_dest, 1);
3492 src1 = gen_df_reg (set_src, 0);
3493 src2 = gen_df_reg (set_src, 1);
3495 /* Now emit using the real source and destination we found, swapping
3496 the order if we detect overlap. */
3497 if (reg_overlap_mentioned_p (dest1, src2))
3499 emit_insn (gen_movdf (dest2, src2));
3500 emit_insn (gen_movdf (dest1, src1));
3504 emit_insn (gen_movdf (dest1, src1));
3505 emit_insn (gen_movdf (dest2, src2));
3511 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3512 (match_operand:TF 1 "const_zero_operand" ""))]
3514 [(clobber (const_int 0))]
3516 rtx set_dest = operands[0];
3519 switch (GET_CODE (set_dest))
3522 dest1 = gen_df_reg (set_dest, 0);
3523 dest2 = gen_df_reg (set_dest, 1);
3526 dest1 = adjust_address (set_dest, DFmode, 0);
3527 dest2 = adjust_address (set_dest, DFmode, 8);
3533 emit_insn (gen_movdf (dest1, CONST0_RTX (DFmode)));
3534 emit_insn (gen_movdf (dest2, CONST0_RTX (DFmode)));
3539 [(set (match_operand:TF 0 "register_operand" "")
3540 (match_operand:TF 1 "memory_operand" ""))]
3542 && offsettable_memref_p (operands[1])
3544 || ! TARGET_HARD_QUAD
3545 || ! fp_register_operand (operands[0], TFmode)))"
3546 [(clobber (const_int 0))]
3548 rtx word0 = adjust_address (operands[1], DFmode, 0);
3549 rtx word1 = adjust_address (operands[1], DFmode, 8);
3550 rtx set_dest, dest1, dest2;
3552 set_dest = operands[0];
3554 dest1 = gen_df_reg (set_dest, 0);
3555 dest2 = gen_df_reg (set_dest, 1);
3557 /* Now output, ordering such that we don't clobber any registers
3558 mentioned in the address. */
3559 if (reg_overlap_mentioned_p (dest1, word1))
3562 emit_insn (gen_movdf (dest2, word1));
3563 emit_insn (gen_movdf (dest1, word0));
3567 emit_insn (gen_movdf (dest1, word0));
3568 emit_insn (gen_movdf (dest2, word1));
3574 [(set (match_operand:TF 0 "memory_operand" "")
3575 (match_operand:TF 1 "register_operand" ""))]
3577 && offsettable_memref_p (operands[0])
3579 || ! TARGET_HARD_QUAD
3580 || ! fp_register_operand (operands[1], TFmode)))"
3581 [(clobber (const_int 0))]
3583 rtx set_src = operands[1];
3585 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 0),
3586 gen_df_reg (set_src, 0)));
3587 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 8),
3588 gen_df_reg (set_src, 1)));
3592 ;; SPARC V9 conditional move instructions.
3594 ;; We can handle larger constants here for some flavors, but for now we keep
3595 ;; it simple and only allow those constants supported by all flavors.
3596 ;; Note that emit_conditional_move canonicalizes operands 2,3 so that operand
3597 ;; 3 contains the constant if one is present, but we handle either for
3598 ;; generality (sparc.c puts a constant in operand 2).
3600 (define_expand "movqicc"
3601 [(set (match_operand:QI 0 "register_operand" "")
3602 (if_then_else:QI (match_operand 1 "comparison_operator" "")
3603 (match_operand:QI 2 "arith10_operand" "")
3604 (match_operand:QI 3 "arith10_operand" "")))]
3607 enum rtx_code code = GET_CODE (operands[1]);
3609 if (GET_MODE (sparc_compare_op0) == DImode
3613 if (sparc_compare_op1 == const0_rtx
3614 && GET_CODE (sparc_compare_op0) == REG
3615 && GET_MODE (sparc_compare_op0) == DImode
3616 && v9_regcmp_p (code))
3618 operands[1] = gen_rtx_fmt_ee (code, DImode,
3619 sparc_compare_op0, sparc_compare_op1);
3623 rtx cc_reg = gen_compare_reg (code,
3624 sparc_compare_op0, sparc_compare_op1);
3625 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3629 (define_expand "movhicc"
3630 [(set (match_operand:HI 0 "register_operand" "")
3631 (if_then_else:HI (match_operand 1 "comparison_operator" "")
3632 (match_operand:HI 2 "arith10_operand" "")
3633 (match_operand:HI 3 "arith10_operand" "")))]
3636 enum rtx_code code = GET_CODE (operands[1]);
3638 if (GET_MODE (sparc_compare_op0) == DImode
3642 if (sparc_compare_op1 == const0_rtx
3643 && GET_CODE (sparc_compare_op0) == REG
3644 && GET_MODE (sparc_compare_op0) == DImode
3645 && v9_regcmp_p (code))
3647 operands[1] = gen_rtx_fmt_ee (code, DImode,
3648 sparc_compare_op0, sparc_compare_op1);
3652 rtx cc_reg = gen_compare_reg (code,
3653 sparc_compare_op0, sparc_compare_op1);
3654 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3658 (define_expand "movsicc"
3659 [(set (match_operand:SI 0 "register_operand" "")
3660 (if_then_else:SI (match_operand 1 "comparison_operator" "")
3661 (match_operand:SI 2 "arith10_operand" "")
3662 (match_operand:SI 3 "arith10_operand" "")))]
3665 enum rtx_code code = GET_CODE (operands[1]);
3666 enum machine_mode op0_mode = GET_MODE (sparc_compare_op0);
3668 if (sparc_compare_op1 == const0_rtx
3669 && GET_CODE (sparc_compare_op0) == REG
3670 && (TARGET_ARCH64 && op0_mode == DImode && v9_regcmp_p (code)))
3672 operands[1] = gen_rtx_fmt_ee (code, op0_mode,
3673 sparc_compare_op0, sparc_compare_op1);
3677 rtx cc_reg = gen_compare_reg (code,
3678 sparc_compare_op0, sparc_compare_op1);
3679 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg),
3680 cc_reg, const0_rtx);
3684 (define_expand "movdicc"
3685 [(set (match_operand:DI 0 "register_operand" "")
3686 (if_then_else:DI (match_operand 1 "comparison_operator" "")
3687 (match_operand:DI 2 "arith10_operand" "")
3688 (match_operand:DI 3 "arith10_operand" "")))]
3691 enum rtx_code code = GET_CODE (operands[1]);
3693 if (sparc_compare_op1 == const0_rtx
3694 && GET_CODE (sparc_compare_op0) == REG
3695 && GET_MODE (sparc_compare_op0) == DImode
3696 && v9_regcmp_p (code))
3698 operands[1] = gen_rtx_fmt_ee (code, DImode,
3699 sparc_compare_op0, sparc_compare_op1);
3703 rtx cc_reg = gen_compare_reg (code,
3704 sparc_compare_op0, sparc_compare_op1);
3705 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg),
3706 cc_reg, const0_rtx);
3710 (define_expand "movsfcc"
3711 [(set (match_operand:SF 0 "register_operand" "")
3712 (if_then_else:SF (match_operand 1 "comparison_operator" "")
3713 (match_operand:SF 2 "register_operand" "")
3714 (match_operand:SF 3 "register_operand" "")))]
3715 "TARGET_V9 && TARGET_FPU"
3717 enum rtx_code code = GET_CODE (operands[1]);
3719 if (GET_MODE (sparc_compare_op0) == DImode
3723 if (sparc_compare_op1 == const0_rtx
3724 && GET_CODE (sparc_compare_op0) == REG
3725 && GET_MODE (sparc_compare_op0) == DImode
3726 && v9_regcmp_p (code))
3728 operands[1] = gen_rtx_fmt_ee (code, DImode,
3729 sparc_compare_op0, sparc_compare_op1);
3733 rtx cc_reg = gen_compare_reg (code,
3734 sparc_compare_op0, sparc_compare_op1);
3735 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3739 (define_expand "movdfcc"
3740 [(set (match_operand:DF 0 "register_operand" "")
3741 (if_then_else:DF (match_operand 1 "comparison_operator" "")
3742 (match_operand:DF 2 "register_operand" "")
3743 (match_operand:DF 3 "register_operand" "")))]
3744 "TARGET_V9 && TARGET_FPU"
3746 enum rtx_code code = GET_CODE (operands[1]);
3748 if (GET_MODE (sparc_compare_op0) == DImode
3752 if (sparc_compare_op1 == const0_rtx
3753 && GET_CODE (sparc_compare_op0) == REG
3754 && GET_MODE (sparc_compare_op0) == DImode
3755 && v9_regcmp_p (code))
3757 operands[1] = gen_rtx_fmt_ee (code, DImode,
3758 sparc_compare_op0, sparc_compare_op1);
3762 rtx cc_reg = gen_compare_reg (code,
3763 sparc_compare_op0, sparc_compare_op1);
3764 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3768 (define_expand "movtfcc"
3769 [(set (match_operand:TF 0 "register_operand" "")
3770 (if_then_else:TF (match_operand 1 "comparison_operator" "")
3771 (match_operand:TF 2 "register_operand" "")
3772 (match_operand:TF 3 "register_operand" "")))]
3773 "TARGET_V9 && TARGET_FPU"
3775 enum rtx_code code = GET_CODE (operands[1]);
3777 if (GET_MODE (sparc_compare_op0) == DImode
3781 if (sparc_compare_op1 == const0_rtx
3782 && GET_CODE (sparc_compare_op0) == REG
3783 && GET_MODE (sparc_compare_op0) == DImode
3784 && v9_regcmp_p (code))
3786 operands[1] = gen_rtx_fmt_ee (code, DImode,
3787 sparc_compare_op0, sparc_compare_op1);
3791 rtx cc_reg = gen_compare_reg (code,
3792 sparc_compare_op0, sparc_compare_op1);
3793 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3797 ;; Conditional move define_insns.
3799 (define_insn "*movqi_cc_sp64"
3800 [(set (match_operand:QI 0 "register_operand" "=r,r")
3801 (if_then_else:QI (match_operator 1 "comparison_operator"
3802 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
3804 (match_operand:QI 3 "arith11_operand" "rL,0")
3805 (match_operand:QI 4 "arith11_operand" "0,rL")))]
3809 mov%c1\t%x2, %4, %0"
3810 [(set_attr "type" "cmove")])
3812 (define_insn "*movhi_cc_sp64"
3813 [(set (match_operand:HI 0 "register_operand" "=r,r")
3814 (if_then_else:HI (match_operator 1 "comparison_operator"
3815 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
3817 (match_operand:HI 3 "arith11_operand" "rL,0")
3818 (match_operand:HI 4 "arith11_operand" "0,rL")))]
3822 mov%c1\t%x2, %4, %0"
3823 [(set_attr "type" "cmove")])
3825 (define_insn "*movsi_cc_sp64"
3826 [(set (match_operand:SI 0 "register_operand" "=r,r")
3827 (if_then_else:SI (match_operator 1 "comparison_operator"
3828 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
3830 (match_operand:SI 3 "arith11_operand" "rL,0")
3831 (match_operand:SI 4 "arith11_operand" "0,rL")))]
3835 mov%c1\t%x2, %4, %0"
3836 [(set_attr "type" "cmove")])
3838 (define_insn "*movdi_cc_sp64"
3839 [(set (match_operand:DI 0 "register_operand" "=r,r")
3840 (if_then_else:DI (match_operator 1 "comparison_operator"
3841 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
3843 (match_operand:DI 3 "arith11_operand" "rL,0")
3844 (match_operand:DI 4 "arith11_operand" "0,rL")))]
3848 mov%c1\t%x2, %4, %0"
3849 [(set_attr "type" "cmove")])
3851 (define_insn "*movdi_cc_sp64_trunc"
3852 [(set (match_operand:SI 0 "register_operand" "=r,r")
3853 (if_then_else:SI (match_operator 1 "comparison_operator"
3854 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
3856 (match_operand:SI 3 "arith11_operand" "rL,0")
3857 (match_operand:SI 4 "arith11_operand" "0,rL")))]
3861 mov%c1\t%x2, %4, %0"
3862 [(set_attr "type" "cmove")])
3864 (define_insn "*movsf_cc_sp64"
3865 [(set (match_operand:SF 0 "register_operand" "=f,f")
3866 (if_then_else:SF (match_operator 1 "comparison_operator"
3867 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
3869 (match_operand:SF 3 "register_operand" "f,0")
3870 (match_operand:SF 4 "register_operand" "0,f")))]
3871 "TARGET_V9 && TARGET_FPU"
3873 fmovs%C1\t%x2, %3, %0
3874 fmovs%c1\t%x2, %4, %0"
3875 [(set_attr "type" "fpcmove")])
3877 (define_insn "movdf_cc_sp64"
3878 [(set (match_operand:DF 0 "register_operand" "=e,e")
3879 (if_then_else:DF (match_operator 1 "comparison_operator"
3880 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
3882 (match_operand:DF 3 "register_operand" "e,0")
3883 (match_operand:DF 4 "register_operand" "0,e")))]
3884 "TARGET_V9 && TARGET_FPU"
3886 fmovd%C1\t%x2, %3, %0
3887 fmovd%c1\t%x2, %4, %0"
3888 [(set_attr "type" "fpcmove")
3889 (set_attr "fptype" "double")])
3891 (define_insn "*movtf_cc_hq_sp64"
3892 [(set (match_operand:TF 0 "register_operand" "=e,e")
3893 (if_then_else:TF (match_operator 1 "comparison_operator"
3894 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
3896 (match_operand:TF 3 "register_operand" "e,0")
3897 (match_operand:TF 4 "register_operand" "0,e")))]
3898 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
3900 fmovq%C1\t%x2, %3, %0
3901 fmovq%c1\t%x2, %4, %0"
3902 [(set_attr "type" "fpcmove")])
3904 (define_insn_and_split "*movtf_cc_sp64"
3905 [(set (match_operand:TF 0 "register_operand" "=e,e")
3906 (if_then_else:TF (match_operator 1 "comparison_operator"
3907 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
3909 (match_operand:TF 3 "register_operand" "e,0")
3910 (match_operand:TF 4 "register_operand" "0,e")))]
3911 "TARGET_V9 && TARGET_FPU && !TARGET_HARD_QUAD"
3913 "&& reload_completed"
3914 [(clobber (const_int 0))]
3916 rtx set_dest = operands[0];
3917 rtx set_srca = operands[3];
3918 rtx set_srcb = operands[4];
3919 int third = rtx_equal_p (set_dest, set_srca);
3921 rtx srca1, srca2, srcb1, srcb2;
3923 dest1 = gen_df_reg (set_dest, 0);
3924 dest2 = gen_df_reg (set_dest, 1);
3925 srca1 = gen_df_reg (set_srca, 0);
3926 srca2 = gen_df_reg (set_srca, 1);
3927 srcb1 = gen_df_reg (set_srcb, 0);
3928 srcb2 = gen_df_reg (set_srcb, 1);
3930 /* Now emit using the real source and destination we found, swapping
3931 the order if we detect overlap. */
3932 if ((third && reg_overlap_mentioned_p (dest1, srcb2))
3933 || (!third && reg_overlap_mentioned_p (dest1, srca2)))
3935 emit_insn (gen_movdf_cc_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
3936 emit_insn (gen_movdf_cc_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
3940 emit_insn (gen_movdf_cc_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
3941 emit_insn (gen_movdf_cc_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
3945 [(set_attr "length" "2")])
3947 (define_insn "*movqi_cc_reg_sp64"
3948 [(set (match_operand:QI 0 "register_operand" "=r,r")
3949 (if_then_else:QI (match_operator 1 "v9_register_compare_operator"
3950 [(match_operand:DI 2 "register_operand" "r,r")
3952 (match_operand:QI 3 "arith10_operand" "rM,0")
3953 (match_operand:QI 4 "arith10_operand" "0,rM")))]
3956 movr%D1\t%2, %r3, %0
3957 movr%d1\t%2, %r4, %0"
3958 [(set_attr "type" "cmove")])
3960 (define_insn "*movhi_cc_reg_sp64"
3961 [(set (match_operand:HI 0 "register_operand" "=r,r")
3962 (if_then_else:HI (match_operator 1 "v9_register_compare_operator"
3963 [(match_operand:DI 2 "register_operand" "r,r")
3965 (match_operand:HI 3 "arith10_operand" "rM,0")
3966 (match_operand:HI 4 "arith10_operand" "0,rM")))]
3969 movr%D1\t%2, %r3, %0
3970 movr%d1\t%2, %r4, %0"
3971 [(set_attr "type" "cmove")])
3973 (define_insn "*movsi_cc_reg_sp64"
3974 [(set (match_operand:SI 0 "register_operand" "=r,r")
3975 (if_then_else:SI (match_operator 1 "v9_register_compare_operator"
3976 [(match_operand:DI 2 "register_operand" "r,r")
3978 (match_operand:SI 3 "arith10_operand" "rM,0")
3979 (match_operand:SI 4 "arith10_operand" "0,rM")))]
3982 movr%D1\t%2, %r3, %0
3983 movr%d1\t%2, %r4, %0"
3984 [(set_attr "type" "cmove")])
3986 (define_insn "*movdi_cc_reg_sp64"
3987 [(set (match_operand:DI 0 "register_operand" "=r,r")
3988 (if_then_else:DI (match_operator 1 "v9_register_compare_operator"
3989 [(match_operand:DI 2 "register_operand" "r,r")
3991 (match_operand:DI 3 "arith10_operand" "rM,0")
3992 (match_operand:DI 4 "arith10_operand" "0,rM")))]
3995 movr%D1\t%2, %r3, %0
3996 movr%d1\t%2, %r4, %0"
3997 [(set_attr "type" "cmove")])
3999 (define_insn "*movsf_cc_reg_sp64"
4000 [(set (match_operand:SF 0 "register_operand" "=f,f")
4001 (if_then_else:SF (match_operator 1 "v9_register_compare_operator"
4002 [(match_operand:DI 2 "register_operand" "r,r")
4004 (match_operand:SF 3 "register_operand" "f,0")
4005 (match_operand:SF 4 "register_operand" "0,f")))]
4006 "TARGET_ARCH64 && TARGET_FPU"
4008 fmovrs%D1\t%2, %3, %0
4009 fmovrs%d1\t%2, %4, %0"
4010 [(set_attr "type" "fpcrmove")])
4012 (define_insn "movdf_cc_reg_sp64"
4013 [(set (match_operand:DF 0 "register_operand" "=e,e")
4014 (if_then_else:DF (match_operator 1 "v9_register_compare_operator"
4015 [(match_operand:DI 2 "register_operand" "r,r")
4017 (match_operand:DF 3 "register_operand" "e,0")
4018 (match_operand:DF 4 "register_operand" "0,e")))]
4019 "TARGET_ARCH64 && TARGET_FPU"
4021 fmovrd%D1\t%2, %3, %0
4022 fmovrd%d1\t%2, %4, %0"
4023 [(set_attr "type" "fpcrmove")
4024 (set_attr "fptype" "double")])
4026 (define_insn "*movtf_cc_reg_hq_sp64"
4027 [(set (match_operand:TF 0 "register_operand" "=e,e")
4028 (if_then_else:TF (match_operator 1 "v9_register_compare_operator"
4029 [(match_operand:DI 2 "register_operand" "r,r")
4031 (match_operand:TF 3 "register_operand" "e,0")
4032 (match_operand:TF 4 "register_operand" "0,e")))]
4033 "TARGET_ARCH64 && TARGET_FPU && TARGET_HARD_QUAD"
4035 fmovrq%D1\t%2, %3, %0
4036 fmovrq%d1\t%2, %4, %0"
4037 [(set_attr "type" "fpcrmove")])
4039 (define_insn_and_split "*movtf_cc_reg_sp64"
4040 [(set (match_operand:TF 0 "register_operand" "=e,e")
4041 (if_then_else:TF (match_operator 1 "v9_register_compare_operator"
4042 [(match_operand:DI 2 "register_operand" "r,r")
4044 (match_operand:TF 3 "register_operand" "e,0")
4045 (match_operand:TF 4 "register_operand" "0,e")))]
4046 "TARGET_ARCH64 && TARGET_FPU && ! TARGET_HARD_QUAD"
4048 "&& reload_completed"
4049 [(clobber (const_int 0))]
4051 rtx set_dest = operands[0];
4052 rtx set_srca = operands[3];
4053 rtx set_srcb = operands[4];
4054 int third = rtx_equal_p (set_dest, set_srca);
4056 rtx srca1, srca2, srcb1, srcb2;
4058 dest1 = gen_df_reg (set_dest, 0);
4059 dest2 = gen_df_reg (set_dest, 1);
4060 srca1 = gen_df_reg (set_srca, 0);
4061 srca2 = gen_df_reg (set_srca, 1);
4062 srcb1 = gen_df_reg (set_srcb, 0);
4063 srcb2 = gen_df_reg (set_srcb, 1);
4065 /* Now emit using the real source and destination we found, swapping
4066 the order if we detect overlap. */
4067 if ((third && reg_overlap_mentioned_p (dest1, srcb2))
4068 || (!third && reg_overlap_mentioned_p (dest1, srca2)))
4070 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
4071 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
4075 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
4076 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
4080 [(set_attr "length" "2")])
4083 ;;- zero extension instructions
4085 ;; These patterns originally accepted general_operands, however, slightly
4086 ;; better code is generated by only accepting register_operands, and then
4087 ;; letting combine generate the ldu[hb] insns.
4089 (define_expand "zero_extendhisi2"
4090 [(set (match_operand:SI 0 "register_operand" "")
4091 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
4094 rtx temp = gen_reg_rtx (SImode);
4095 rtx shift_16 = GEN_INT (16);
4096 int op1_subbyte = 0;
4098 if (GET_CODE (operand1) == SUBREG)
4100 op1_subbyte = SUBREG_BYTE (operand1);
4101 op1_subbyte /= GET_MODE_SIZE (SImode);
4102 op1_subbyte *= GET_MODE_SIZE (SImode);
4103 operand1 = XEXP (operand1, 0);
4106 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4108 emit_insn (gen_lshrsi3 (operand0, temp, shift_16));
4112 (define_insn "*zero_extendhisi2_insn"
4113 [(set (match_operand:SI 0 "register_operand" "=r")
4114 (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
4117 [(set_attr "type" "load")
4118 (set_attr "us3load_type" "3cycle")])
4120 (define_expand "zero_extendqihi2"
4121 [(set (match_operand:HI 0 "register_operand" "")
4122 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
4126 (define_insn "*zero_extendqihi2_insn"
4127 [(set (match_operand:HI 0 "register_operand" "=r,r")
4128 (zero_extend:HI (match_operand:QI 1 "input_operand" "r,m")))]
4129 "GET_CODE (operands[1]) != CONST_INT"
4133 [(set_attr "type" "*,load")
4134 (set_attr "us3load_type" "*,3cycle")])
4136 (define_expand "zero_extendqisi2"
4137 [(set (match_operand:SI 0 "register_operand" "")
4138 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
4142 (define_insn "*zero_extendqisi2_insn"
4143 [(set (match_operand:SI 0 "register_operand" "=r,r")
4144 (zero_extend:SI (match_operand:QI 1 "input_operand" "r,m")))]
4145 "GET_CODE (operands[1]) != CONST_INT"
4149 [(set_attr "type" "*,load")
4150 (set_attr "us3load_type" "*,3cycle")])
4152 (define_expand "zero_extendqidi2"
4153 [(set (match_operand:DI 0 "register_operand" "")
4154 (zero_extend:DI (match_operand:QI 1 "register_operand" "")))]
4158 (define_insn "*zero_extendqidi2_insn"
4159 [(set (match_operand:DI 0 "register_operand" "=r,r")
4160 (zero_extend:DI (match_operand:QI 1 "input_operand" "r,m")))]
4161 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
4165 [(set_attr "type" "*,load")
4166 (set_attr "us3load_type" "*,3cycle")])
4168 (define_expand "zero_extendhidi2"
4169 [(set (match_operand:DI 0 "register_operand" "")
4170 (zero_extend:DI (match_operand:HI 1 "register_operand" "")))]
4173 rtx temp = gen_reg_rtx (DImode);
4174 rtx shift_48 = GEN_INT (48);
4175 int op1_subbyte = 0;
4177 if (GET_CODE (operand1) == SUBREG)
4179 op1_subbyte = SUBREG_BYTE (operand1);
4180 op1_subbyte /= GET_MODE_SIZE (DImode);
4181 op1_subbyte *= GET_MODE_SIZE (DImode);
4182 operand1 = XEXP (operand1, 0);
4185 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
4187 emit_insn (gen_lshrdi3 (operand0, temp, shift_48));
4191 (define_insn "*zero_extendhidi2_insn"
4192 [(set (match_operand:DI 0 "register_operand" "=r")
4193 (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
4196 [(set_attr "type" "load")
4197 (set_attr "us3load_type" "3cycle")])
4200 ;; ??? Write truncdisi pattern using sra?
4202 (define_expand "zero_extendsidi2"
4203 [(set (match_operand:DI 0 "register_operand" "")
4204 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
4208 (define_insn "*zero_extendsidi2_insn_sp64"
4209 [(set (match_operand:DI 0 "register_operand" "=r,r")
4210 (zero_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
4211 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
4215 [(set_attr "type" "shift,load")])
4217 (define_insn_and_split "*zero_extendsidi2_insn_sp32"
4218 [(set (match_operand:DI 0 "register_operand" "=r")
4219 (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
4222 "&& reload_completed"
4223 [(set (match_dup 2) (match_dup 3))
4224 (set (match_dup 4) (match_dup 5))]
4228 dest1 = gen_highpart (SImode, operands[0]);
4229 dest2 = gen_lowpart (SImode, operands[0]);
4231 /* Swap the order in case of overlap. */
4232 if (REGNO (dest1) == REGNO (operands[1]))
4234 operands[2] = dest2;
4235 operands[3] = operands[1];
4236 operands[4] = dest1;
4237 operands[5] = const0_rtx;
4241 operands[2] = dest1;
4242 operands[3] = const0_rtx;
4243 operands[4] = dest2;
4244 operands[5] = operands[1];
4247 [(set_attr "length" "2")])
4249 ;; Simplify comparisons of extended values.
4251 (define_insn "*cmp_zero_extendqisi2"
4253 (compare:CC (zero_extend:SI (match_operand:QI 0 "register_operand" "r"))
4256 "andcc\t%0, 0xff, %%g0"
4257 [(set_attr "type" "compare")])
4259 (define_insn "*cmp_zero_qi"
4261 (compare:CC (match_operand:QI 0 "register_operand" "r")
4264 "andcc\t%0, 0xff, %%g0"
4265 [(set_attr "type" "compare")])
4267 (define_insn "*cmp_zero_extendqisi2_set"
4269 (compare:CC (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
4271 (set (match_operand:SI 0 "register_operand" "=r")
4272 (zero_extend:SI (match_dup 1)))]
4274 "andcc\t%1, 0xff, %0"
4275 [(set_attr "type" "compare")])
4277 (define_insn "*cmp_zero_extendqisi2_andcc_set"
4279 (compare:CC (and:SI (match_operand:SI 1 "register_operand" "r")
4282 (set (match_operand:SI 0 "register_operand" "=r")
4283 (zero_extend:SI (subreg:QI (match_dup 1) 0)))]
4285 "andcc\t%1, 0xff, %0"
4286 [(set_attr "type" "compare")])
4288 (define_insn "*cmp_zero_extendqidi2"
4290 (compare:CCX (zero_extend:DI (match_operand:QI 0 "register_operand" "r"))
4293 "andcc\t%0, 0xff, %%g0"
4294 [(set_attr "type" "compare")])
4296 (define_insn "*cmp_zero_qi_sp64"
4298 (compare:CCX (match_operand:QI 0 "register_operand" "r")
4301 "andcc\t%0, 0xff, %%g0"
4302 [(set_attr "type" "compare")])
4304 (define_insn "*cmp_zero_extendqidi2_set"
4306 (compare:CCX (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
4308 (set (match_operand:DI 0 "register_operand" "=r")
4309 (zero_extend:DI (match_dup 1)))]
4311 "andcc\t%1, 0xff, %0"
4312 [(set_attr "type" "compare")])
4314 (define_insn "*cmp_zero_extendqidi2_andcc_set"
4316 (compare:CCX (and:DI (match_operand:DI 1 "register_operand" "r")
4319 (set (match_operand:DI 0 "register_operand" "=r")
4320 (zero_extend:DI (subreg:QI (match_dup 1) 0)))]
4322 "andcc\t%1, 0xff, %0"
4323 [(set_attr "type" "compare")])
4325 ;; Similarly, handle {SI,DI}->QI mode truncation followed by a compare.
4327 (define_insn "*cmp_siqi_trunc"
4329 (compare:CC (subreg:QI (match_operand:SI 0 "register_operand" "r") 3)
4332 "andcc\t%0, 0xff, %%g0"
4333 [(set_attr "type" "compare")])
4335 (define_insn "*cmp_siqi_trunc_set"
4337 (compare:CC (subreg:QI (match_operand:SI 1 "register_operand" "r") 3)
4339 (set (match_operand:QI 0 "register_operand" "=r")
4340 (subreg:QI (match_dup 1) 3))]
4342 "andcc\t%1, 0xff, %0"
4343 [(set_attr "type" "compare")])
4345 (define_insn "*cmp_diqi_trunc"
4347 (compare:CC (subreg:QI (match_operand:DI 0 "register_operand" "r") 7)
4350 "andcc\t%0, 0xff, %%g0"
4351 [(set_attr "type" "compare")])
4353 (define_insn "*cmp_diqi_trunc_set"
4355 (compare:CC (subreg:QI (match_operand:DI 1 "register_operand" "r") 7)
4357 (set (match_operand:QI 0 "register_operand" "=r")
4358 (subreg:QI (match_dup 1) 7))]
4360 "andcc\t%1, 0xff, %0"
4361 [(set_attr "type" "compare")])
4363 ;;- sign extension instructions
4365 ;; These patterns originally accepted general_operands, however, slightly
4366 ;; better code is generated by only accepting register_operands, and then
4367 ;; letting combine generate the lds[hb] insns.
4369 (define_expand "extendhisi2"
4370 [(set (match_operand:SI 0 "register_operand" "")
4371 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
4374 rtx temp = gen_reg_rtx (SImode);
4375 rtx shift_16 = GEN_INT (16);
4376 int op1_subbyte = 0;
4378 if (GET_CODE (operand1) == SUBREG)
4380 op1_subbyte = SUBREG_BYTE (operand1);
4381 op1_subbyte /= GET_MODE_SIZE (SImode);
4382 op1_subbyte *= GET_MODE_SIZE (SImode);
4383 operand1 = XEXP (operand1, 0);
4386 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4388 emit_insn (gen_ashrsi3 (operand0, temp, shift_16));
4392 (define_insn "*sign_extendhisi2_insn"
4393 [(set (match_operand:SI 0 "register_operand" "=r")
4394 (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
4397 [(set_attr "type" "sload")
4398 (set_attr "us3load_type" "3cycle")])
4400 (define_expand "extendqihi2"
4401 [(set (match_operand:HI 0 "register_operand" "")
4402 (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
4405 rtx temp = gen_reg_rtx (SImode);
4406 rtx shift_24 = GEN_INT (24);
4407 int op1_subbyte = 0;
4408 int op0_subbyte = 0;
4410 if (GET_CODE (operand1) == SUBREG)
4412 op1_subbyte = SUBREG_BYTE (operand1);
4413 op1_subbyte /= GET_MODE_SIZE (SImode);
4414 op1_subbyte *= GET_MODE_SIZE (SImode);
4415 operand1 = XEXP (operand1, 0);
4417 if (GET_CODE (operand0) == SUBREG)
4419 op0_subbyte = SUBREG_BYTE (operand0);
4420 op0_subbyte /= GET_MODE_SIZE (SImode);
4421 op0_subbyte *= GET_MODE_SIZE (SImode);
4422 operand0 = XEXP (operand0, 0);
4424 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4426 if (GET_MODE (operand0) != SImode)
4427 operand0 = gen_rtx_SUBREG (SImode, operand0, op0_subbyte);
4428 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
4432 (define_insn "*sign_extendqihi2_insn"
4433 [(set (match_operand:HI 0 "register_operand" "=r")
4434 (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
4437 [(set_attr "type" "sload")
4438 (set_attr "us3load_type" "3cycle")])
4440 (define_expand "extendqisi2"
4441 [(set (match_operand:SI 0 "register_operand" "")
4442 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
4445 rtx temp = gen_reg_rtx (SImode);
4446 rtx shift_24 = GEN_INT (24);
4447 int op1_subbyte = 0;
4449 if (GET_CODE (operand1) == SUBREG)
4451 op1_subbyte = SUBREG_BYTE (operand1);
4452 op1_subbyte /= GET_MODE_SIZE (SImode);
4453 op1_subbyte *= GET_MODE_SIZE (SImode);
4454 operand1 = XEXP (operand1, 0);
4457 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4459 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
4463 (define_insn "*sign_extendqisi2_insn"
4464 [(set (match_operand:SI 0 "register_operand" "=r")
4465 (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
4468 [(set_attr "type" "sload")
4469 (set_attr "us3load_type" "3cycle")])
4471 (define_expand "extendqidi2"
4472 [(set (match_operand:DI 0 "register_operand" "")
4473 (sign_extend:DI (match_operand:QI 1 "register_operand" "")))]
4476 rtx temp = gen_reg_rtx (DImode);
4477 rtx shift_56 = GEN_INT (56);
4478 int op1_subbyte = 0;
4480 if (GET_CODE (operand1) == SUBREG)
4482 op1_subbyte = SUBREG_BYTE (operand1);
4483 op1_subbyte /= GET_MODE_SIZE (DImode);
4484 op1_subbyte *= GET_MODE_SIZE (DImode);
4485 operand1 = XEXP (operand1, 0);
4488 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
4490 emit_insn (gen_ashrdi3 (operand0, temp, shift_56));
4494 (define_insn "*sign_extendqidi2_insn"
4495 [(set (match_operand:DI 0 "register_operand" "=r")
4496 (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
4499 [(set_attr "type" "sload")
4500 (set_attr "us3load_type" "3cycle")])
4502 (define_expand "extendhidi2"
4503 [(set (match_operand:DI 0 "register_operand" "")
4504 (sign_extend:DI (match_operand:HI 1 "register_operand" "")))]
4507 rtx temp = gen_reg_rtx (DImode);
4508 rtx shift_48 = GEN_INT (48);
4509 int op1_subbyte = 0;
4511 if (GET_CODE (operand1) == SUBREG)
4513 op1_subbyte = SUBREG_BYTE (operand1);
4514 op1_subbyte /= GET_MODE_SIZE (DImode);
4515 op1_subbyte *= GET_MODE_SIZE (DImode);
4516 operand1 = XEXP (operand1, 0);
4519 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
4521 emit_insn (gen_ashrdi3 (operand0, temp, shift_48));
4525 (define_insn "*sign_extendhidi2_insn"
4526 [(set (match_operand:DI 0 "register_operand" "=r")
4527 (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
4530 [(set_attr "type" "sload")
4531 (set_attr "us3load_type" "3cycle")])
4533 (define_expand "extendsidi2"
4534 [(set (match_operand:DI 0 "register_operand" "")
4535 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
4539 (define_insn "*sign_extendsidi2_insn"
4540 [(set (match_operand:DI 0 "register_operand" "=r,r")
4541 (sign_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
4546 [(set_attr "type" "shift,sload")
4547 (set_attr "us3load_type" "*,3cycle")])
4549 ;; Special pattern for optimizing bit-field compares. This is needed
4550 ;; because combine uses this as a canonical form.
4552 (define_insn "*cmp_zero_extract"
4555 (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
4556 (match_operand:SI 1 "small_int_operand" "I")
4557 (match_operand:SI 2 "small_int_operand" "I"))
4559 "INTVAL (operands[2]) > 19"
4561 int len = INTVAL (operands[1]);
4562 int pos = 32 - INTVAL (operands[2]) - len;
4563 HOST_WIDE_INT mask = ((1 << len) - 1) << pos;
4564 operands[1] = GEN_INT (mask);
4565 return "andcc\t%0, %1, %%g0";
4567 [(set_attr "type" "compare")])
4569 (define_insn "*cmp_zero_extract_sp64"
4572 (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
4573 (match_operand:SI 1 "small_int_operand" "I")
4574 (match_operand:SI 2 "small_int_operand" "I"))
4576 "TARGET_ARCH64 && INTVAL (operands[2]) > 51"
4578 int len = INTVAL (operands[1]);
4579 int pos = 64 - INTVAL (operands[2]) - len;
4580 HOST_WIDE_INT mask = (((unsigned HOST_WIDE_INT) 1 << len) - 1) << pos;
4581 operands[1] = GEN_INT (mask);
4582 return "andcc\t%0, %1, %%g0";
4584 [(set_attr "type" "compare")])
4586 ;; Conversions between float, double and long double.
4588 (define_insn "extendsfdf2"
4589 [(set (match_operand:DF 0 "register_operand" "=e")
4591 (match_operand:SF 1 "register_operand" "f")))]
4594 [(set_attr "type" "fp")
4595 (set_attr "fptype" "double")])
4597 (define_expand "extendsftf2"
4598 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4600 (match_operand:SF 1 "register_operand" "")))]
4601 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4602 "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
4604 (define_insn "*extendsftf2_hq"
4605 [(set (match_operand:TF 0 "register_operand" "=e")
4607 (match_operand:SF 1 "register_operand" "f")))]
4608 "TARGET_FPU && TARGET_HARD_QUAD"
4610 [(set_attr "type" "fp")])
4612 (define_expand "extenddftf2"
4613 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4615 (match_operand:DF 1 "register_operand" "")))]
4616 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4617 "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
4619 (define_insn "*extenddftf2_hq"
4620 [(set (match_operand:TF 0 "register_operand" "=e")
4622 (match_operand:DF 1 "register_operand" "e")))]
4623 "TARGET_FPU && TARGET_HARD_QUAD"
4625 [(set_attr "type" "fp")])
4627 (define_insn "truncdfsf2"
4628 [(set (match_operand:SF 0 "register_operand" "=f")
4630 (match_operand:DF 1 "register_operand" "e")))]
4633 [(set_attr "type" "fp")
4634 (set_attr "fptype" "double")])
4636 (define_expand "trunctfsf2"
4637 [(set (match_operand:SF 0 "register_operand" "")
4639 (match_operand:TF 1 "general_operand" "")))]
4640 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4641 "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
4643 (define_insn "*trunctfsf2_hq"
4644 [(set (match_operand:SF 0 "register_operand" "=f")
4646 (match_operand:TF 1 "register_operand" "e")))]
4647 "TARGET_FPU && TARGET_HARD_QUAD"
4649 [(set_attr "type" "fp")])
4651 (define_expand "trunctfdf2"
4652 [(set (match_operand:DF 0 "register_operand" "")
4654 (match_operand:TF 1 "general_operand" "")))]
4655 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4656 "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
4658 (define_insn "*trunctfdf2_hq"
4659 [(set (match_operand:DF 0 "register_operand" "=e")
4661 (match_operand:TF 1 "register_operand" "e")))]
4662 "TARGET_FPU && TARGET_HARD_QUAD"
4664 [(set_attr "type" "fp")])
4666 ;; Conversion between fixed point and floating point.
4668 (define_insn "floatsisf2"
4669 [(set (match_operand:SF 0 "register_operand" "=f")
4670 (float:SF (match_operand:SI 1 "register_operand" "f")))]
4673 [(set_attr "type" "fp")
4674 (set_attr "fptype" "double")])
4676 (define_insn "floatsidf2"
4677 [(set (match_operand:DF 0 "register_operand" "=e")
4678 (float:DF (match_operand:SI 1 "register_operand" "f")))]
4681 [(set_attr "type" "fp")
4682 (set_attr "fptype" "double")])
4684 (define_expand "floatsitf2"
4685 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4686 (float:TF (match_operand:SI 1 "register_operand" "")))]
4687 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4688 "emit_tfmode_cvt (FLOAT, operands); DONE;")
4690 (define_insn "*floatsitf2_hq"
4691 [(set (match_operand:TF 0 "register_operand" "=e")
4692 (float:TF (match_operand:SI 1 "register_operand" "f")))]
4693 "TARGET_FPU && TARGET_HARD_QUAD"
4695 [(set_attr "type" "fp")])
4697 (define_expand "floatunssitf2"
4698 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4699 (unsigned_float:TF (match_operand:SI 1 "register_operand" "")))]
4700 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4701 "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
4703 ;; Now the same for 64 bit sources.
4705 (define_insn "floatdisf2"
4706 [(set (match_operand:SF 0 "register_operand" "=f")
4707 (float:SF (match_operand:DI 1 "register_operand" "e")))]
4708 "TARGET_V9 && TARGET_FPU"
4710 [(set_attr "type" "fp")
4711 (set_attr "fptype" "double")])
4713 (define_expand "floatunsdisf2"
4714 [(use (match_operand:SF 0 "register_operand" ""))
4715 (use (match_operand:DI 1 "general_operand" ""))]
4716 "TARGET_ARCH64 && TARGET_FPU"
4717 "sparc_emit_floatunsdi (operands, SFmode); DONE;")
4719 (define_insn "floatdidf2"
4720 [(set (match_operand:DF 0 "register_operand" "=e")
4721 (float:DF (match_operand:DI 1 "register_operand" "e")))]
4722 "TARGET_V9 && TARGET_FPU"
4724 [(set_attr "type" "fp")
4725 (set_attr "fptype" "double")])
4727 (define_expand "floatunsdidf2"
4728 [(use (match_operand:DF 0 "register_operand" ""))
4729 (use (match_operand:DI 1 "general_operand" ""))]
4730 "TARGET_ARCH64 && TARGET_FPU"
4731 "sparc_emit_floatunsdi (operands, DFmode); DONE;")
4733 (define_expand "floatditf2"
4734 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4735 (float:TF (match_operand:DI 1 "register_operand" "")))]
4736 "TARGET_FPU && TARGET_V9 && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4737 "emit_tfmode_cvt (FLOAT, operands); DONE;")
4739 (define_insn "*floatditf2_hq"
4740 [(set (match_operand:TF 0 "register_operand" "=e")
4741 (float:TF (match_operand:DI 1 "register_operand" "e")))]
4742 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
4744 [(set_attr "type" "fp")])
4746 (define_expand "floatunsditf2"
4747 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4748 (unsigned_float:TF (match_operand:DI 1 "register_operand" "")))]
4749 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4750 "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
4752 ;; Convert a float to an actual integer.
4753 ;; Truncation is performed as part of the conversion.
4755 (define_insn "fix_truncsfsi2"
4756 [(set (match_operand:SI 0 "register_operand" "=f")
4757 (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
4760 [(set_attr "type" "fp")
4761 (set_attr "fptype" "double")])
4763 (define_insn "fix_truncdfsi2"
4764 [(set (match_operand:SI 0 "register_operand" "=f")
4765 (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
4768 [(set_attr "type" "fp")
4769 (set_attr "fptype" "double")])
4771 (define_expand "fix_trunctfsi2"
4772 [(set (match_operand:SI 0 "register_operand" "")
4773 (fix:SI (match_operand:TF 1 "general_operand" "")))]
4774 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4775 "emit_tfmode_cvt (FIX, operands); DONE;")
4777 (define_insn "*fix_trunctfsi2_hq"
4778 [(set (match_operand:SI 0 "register_operand" "=f")
4779 (fix:SI (match_operand:TF 1 "register_operand" "e")))]
4780 "TARGET_FPU && TARGET_HARD_QUAD"
4782 [(set_attr "type" "fp")])
4784 (define_expand "fixuns_trunctfsi2"
4785 [(set (match_operand:SI 0 "register_operand" "")
4786 (unsigned_fix:SI (match_operand:TF 1 "general_operand" "")))]
4787 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4788 "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
4790 ;; Now the same, for V9 targets
4792 (define_insn "fix_truncsfdi2"
4793 [(set (match_operand:DI 0 "register_operand" "=e")
4794 (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
4795 "TARGET_V9 && TARGET_FPU"
4797 [(set_attr "type" "fp")
4798 (set_attr "fptype" "double")])
4800 (define_expand "fixuns_truncsfdi2"
4801 [(use (match_operand:DI 0 "register_operand" ""))
4802 (use (match_operand:SF 1 "general_operand" ""))]
4803 "TARGET_ARCH64 && TARGET_FPU"
4804 "sparc_emit_fixunsdi (operands, SFmode); DONE;")
4806 (define_insn "fix_truncdfdi2"
4807 [(set (match_operand:DI 0 "register_operand" "=e")
4808 (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
4809 "TARGET_V9 && TARGET_FPU"
4811 [(set_attr "type" "fp")
4812 (set_attr "fptype" "double")])
4814 (define_expand "fixuns_truncdfdi2"
4815 [(use (match_operand:DI 0 "register_operand" ""))
4816 (use (match_operand:DF 1 "general_operand" ""))]
4817 "TARGET_ARCH64 && TARGET_FPU"
4818 "sparc_emit_fixunsdi (operands, DFmode); DONE;")
4820 (define_expand "fix_trunctfdi2"
4821 [(set (match_operand:DI 0 "register_operand" "")
4822 (fix:DI (match_operand:TF 1 "general_operand" "")))]
4823 "TARGET_V9 && TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4824 "emit_tfmode_cvt (FIX, operands); DONE;")
4826 (define_insn "*fix_trunctfdi2_hq"
4827 [(set (match_operand:DI 0 "register_operand" "=e")
4828 (fix:DI (match_operand:TF 1 "register_operand" "e")))]
4829 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
4831 [(set_attr "type" "fp")])
4833 (define_expand "fixuns_trunctfdi2"
4834 [(set (match_operand:DI 0 "register_operand" "")
4835 (unsigned_fix:DI (match_operand:TF 1 "general_operand" "")))]
4836 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4837 "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
4839 ;; Integer Addition/Subtraction.
4841 (define_expand "adddi3"
4842 [(set (match_operand:DI 0 "register_operand" "")
4843 (plus:DI (match_operand:DI 1 "register_operand" "")
4844 (match_operand:DI 2 "arith_double_add_operand" "")))]
4847 if (! TARGET_ARCH64)
4849 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
4850 gen_rtx_SET (VOIDmode, operands[0],
4851 gen_rtx_PLUS (DImode, operands[1],
4853 gen_rtx_CLOBBER (VOIDmode,
4854 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
4859 (define_insn_and_split "adddi3_insn_sp32"
4860 [(set (match_operand:DI 0 "register_operand" "=r")
4861 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
4862 (match_operand:DI 2 "arith_double_operand" "rHI")))
4863 (clobber (reg:CC 100))]
4866 "&& reload_completed"
4867 [(parallel [(set (reg:CC_NOOV 100)
4868 (compare:CC_NOOV (plus:SI (match_dup 4)
4872 (plus:SI (match_dup 4) (match_dup 5)))])
4874 (plus:SI (plus:SI (match_dup 7)
4876 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4878 operands[3] = gen_lowpart (SImode, operands[0]);
4879 operands[4] = gen_lowpart (SImode, operands[1]);
4880 operands[5] = gen_lowpart (SImode, operands[2]);
4881 operands[6] = gen_highpart (SImode, operands[0]);
4882 operands[7] = gen_highpart_mode (SImode, DImode, operands[1]);
4883 #if HOST_BITS_PER_WIDE_INT == 32
4884 if (GET_CODE (operands[2]) == CONST_INT)
4886 if (INTVAL (operands[2]) < 0)
4887 operands[8] = constm1_rtx;
4889 operands[8] = const0_rtx;
4893 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
4895 [(set_attr "length" "2")])
4897 ;; LTU here means "carry set"
4899 [(set (match_operand:SI 0 "register_operand" "=r")
4900 (plus:SI (plus:SI (match_operand:SI 1 "arith_operand" "%r")
4901 (match_operand:SI 2 "arith_operand" "rI"))
4902 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4905 [(set_attr "type" "ialuX")])
4907 (define_insn_and_split "*addx_extend_sp32"
4908 [(set (match_operand:DI 0 "register_operand" "=r")
4909 (zero_extend:DI (plus:SI (plus:SI
4910 (match_operand:SI 1 "register_or_zero_operand" "%rJ")
4911 (match_operand:SI 2 "arith_operand" "rI"))
4912 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4915 "&& reload_completed"
4916 [(set (match_dup 3) (plus:SI (plus:SI (match_dup 1) (match_dup 2))
4917 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
4918 (set (match_dup 4) (const_int 0))]
4919 "operands[3] = gen_lowpart (SImode, operands[0]);
4920 operands[4] = gen_highpart_mode (SImode, DImode, operands[1]);"
4921 [(set_attr "length" "2")])
4923 (define_insn "*addx_extend_sp64"
4924 [(set (match_operand:DI 0 "register_operand" "=r")
4925 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ")
4926 (match_operand:SI 2 "arith_operand" "rI"))
4927 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4930 [(set_attr "type" "ialuX")])
4932 (define_insn_and_split ""
4933 [(set (match_operand:DI 0 "register_operand" "=r")
4934 (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4935 (match_operand:DI 2 "register_operand" "r")))
4936 (clobber (reg:CC 100))]
4939 "&& reload_completed"
4940 [(parallel [(set (reg:CC_NOOV 100)
4941 (compare:CC_NOOV (plus:SI (match_dup 3) (match_dup 1))
4943 (set (match_dup 5) (plus:SI (match_dup 3) (match_dup 1)))])
4945 (plus:SI (plus:SI (match_dup 4) (const_int 0))
4946 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4947 "operands[3] = gen_lowpart (SImode, operands[2]);
4948 operands[4] = gen_highpart (SImode, operands[2]);
4949 operands[5] = gen_lowpart (SImode, operands[0]);
4950 operands[6] = gen_highpart (SImode, operands[0]);"
4951 [(set_attr "length" "2")])
4953 (define_insn "*adddi3_sp64"
4954 [(set (match_operand:DI 0 "register_operand" "=r,r")
4955 (plus:DI (match_operand:DI 1 "register_operand" "%r,r")
4956 (match_operand:DI 2 "arith_add_operand" "rI,O")))]
4962 (define_insn "addsi3"
4963 [(set (match_operand:SI 0 "register_operand" "=r,r,d")
4964 (plus:SI (match_operand:SI 1 "register_operand" "%r,r,d")
4965 (match_operand:SI 2 "arith_add_operand" "rI,O,d")))]
4970 fpadd32s\t%1, %2, %0"
4971 [(set_attr "type" "*,*,fga")
4972 (set_attr "fptype" "*,*,single")])
4974 (define_insn "*cmp_cc_plus"
4975 [(set (reg:CC_NOOV 100)
4976 (compare:CC_NOOV (plus:SI (match_operand:SI 0 "arith_operand" "%r")
4977 (match_operand:SI 1 "arith_operand" "rI"))
4980 "addcc\t%0, %1, %%g0"
4981 [(set_attr "type" "compare")])
4983 (define_insn "*cmp_ccx_plus"
4984 [(set (reg:CCX_NOOV 100)
4985 (compare:CCX_NOOV (plus:DI (match_operand:DI 0 "arith_operand" "%r")
4986 (match_operand:DI 1 "arith_operand" "rI"))
4989 "addcc\t%0, %1, %%g0"
4990 [(set_attr "type" "compare")])
4992 (define_insn "*cmp_cc_plus_set"
4993 [(set (reg:CC_NOOV 100)
4994 (compare:CC_NOOV (plus:SI (match_operand:SI 1 "arith_operand" "%r")
4995 (match_operand:SI 2 "arith_operand" "rI"))
4997 (set (match_operand:SI 0 "register_operand" "=r")
4998 (plus:SI (match_dup 1) (match_dup 2)))]
5001 [(set_attr "type" "compare")])
5003 (define_insn "*cmp_ccx_plus_set"
5004 [(set (reg:CCX_NOOV 100)
5005 (compare:CCX_NOOV (plus:DI (match_operand:DI 1 "arith_operand" "%r")
5006 (match_operand:DI 2 "arith_operand" "rI"))
5008 (set (match_operand:DI 0 "register_operand" "=r")
5009 (plus:DI (match_dup 1) (match_dup 2)))]
5012 [(set_attr "type" "compare")])
5014 (define_expand "subdi3"
5015 [(set (match_operand:DI 0 "register_operand" "")
5016 (minus:DI (match_operand:DI 1 "register_operand" "")
5017 (match_operand:DI 2 "arith_double_add_operand" "")))]
5020 if (! TARGET_ARCH64)
5022 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
5023 gen_rtx_SET (VOIDmode, operands[0],
5024 gen_rtx_MINUS (DImode, operands[1],
5026 gen_rtx_CLOBBER (VOIDmode,
5027 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
5032 (define_insn_and_split "subdi3_insn_sp32"
5033 [(set (match_operand:DI 0 "register_operand" "=r")
5034 (minus:DI (match_operand:DI 1 "register_operand" "r")
5035 (match_operand:DI 2 "arith_double_operand" "rHI")))
5036 (clobber (reg:CC 100))]
5039 "&& reload_completed"
5040 [(parallel [(set (reg:CC_NOOV 100)
5041 (compare:CC_NOOV (minus:SI (match_dup 4)
5045 (minus:SI (match_dup 4) (match_dup 5)))])
5047 (minus:SI (minus:SI (match_dup 7)
5049 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5051 operands[3] = gen_lowpart (SImode, operands[0]);
5052 operands[4] = gen_lowpart (SImode, operands[1]);
5053 operands[5] = gen_lowpart (SImode, operands[2]);
5054 operands[6] = gen_highpart (SImode, operands[0]);
5055 operands[7] = gen_highpart (SImode, operands[1]);
5056 #if HOST_BITS_PER_WIDE_INT == 32
5057 if (GET_CODE (operands[2]) == CONST_INT)
5059 if (INTVAL (operands[2]) < 0)
5060 operands[8] = constm1_rtx;
5062 operands[8] = const0_rtx;
5066 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
5068 [(set_attr "length" "2")])
5070 ;; LTU here means "carry set"
5072 [(set (match_operand:SI 0 "register_operand" "=r")
5073 (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
5074 (match_operand:SI 2 "arith_operand" "rI"))
5075 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5078 [(set_attr "type" "ialuX")])
5080 (define_insn "*subx_extend_sp64"
5081 [(set (match_operand:DI 0 "register_operand" "=r")
5082 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
5083 (match_operand:SI 2 "arith_operand" "rI"))
5084 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5087 [(set_attr "type" "ialuX")])
5089 (define_insn_and_split "*subx_extend"
5090 [(set (match_operand:DI 0 "register_operand" "=r")
5091 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
5092 (match_operand:SI 2 "arith_operand" "rI"))
5093 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5096 "&& reload_completed"
5097 [(set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 2))
5098 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
5099 (set (match_dup 4) (const_int 0))]
5100 "operands[3] = gen_lowpart (SImode, operands[0]);
5101 operands[4] = gen_highpart (SImode, operands[0]);"
5102 [(set_attr "length" "2")])
5104 (define_insn_and_split ""
5105 [(set (match_operand:DI 0 "register_operand" "=r")
5106 (minus:DI (match_operand:DI 1 "register_operand" "r")
5107 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))
5108 (clobber (reg:CC 100))]
5111 "&& reload_completed"
5112 [(parallel [(set (reg:CC_NOOV 100)
5113 (compare:CC_NOOV (minus:SI (match_dup 3) (match_dup 2))
5115 (set (match_dup 5) (minus:SI (match_dup 3) (match_dup 2)))])
5117 (minus:SI (minus:SI (match_dup 4) (const_int 0))
5118 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5119 "operands[3] = gen_lowpart (SImode, operands[1]);
5120 operands[4] = gen_highpart (SImode, operands[1]);
5121 operands[5] = gen_lowpart (SImode, operands[0]);
5122 operands[6] = gen_highpart (SImode, operands[0]);"
5123 [(set_attr "length" "2")])
5125 (define_insn "*subdi3_sp64"
5126 [(set (match_operand:DI 0 "register_operand" "=r,r")
5127 (minus:DI (match_operand:DI 1 "register_operand" "r,r")
5128 (match_operand:DI 2 "arith_add_operand" "rI,O")))]
5134 (define_insn "subsi3"
5135 [(set (match_operand:SI 0 "register_operand" "=r,r,d")
5136 (minus:SI (match_operand:SI 1 "register_operand" "r,r,d")
5137 (match_operand:SI 2 "arith_add_operand" "rI,O,d")))]
5142 fpsub32s\t%1, %2, %0"
5143 [(set_attr "type" "*,*,fga")
5144 (set_attr "fptype" "*,*,single")])
5146 (define_insn "*cmp_minus_cc"
5147 [(set (reg:CC_NOOV 100)
5148 (compare:CC_NOOV (minus:SI (match_operand:SI 0 "register_or_zero_operand" "rJ")
5149 (match_operand:SI 1 "arith_operand" "rI"))
5152 "subcc\t%r0, %1, %%g0"
5153 [(set_attr "type" "compare")])
5155 (define_insn "*cmp_minus_ccx"
5156 [(set (reg:CCX_NOOV 100)
5157 (compare:CCX_NOOV (minus:DI (match_operand:DI 0 "register_operand" "r")
5158 (match_operand:DI 1 "arith_operand" "rI"))
5161 "subcc\t%0, %1, %%g0"
5162 [(set_attr "type" "compare")])
5164 (define_insn "cmp_minus_cc_set"
5165 [(set (reg:CC_NOOV 100)
5166 (compare:CC_NOOV (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
5167 (match_operand:SI 2 "arith_operand" "rI"))
5169 (set (match_operand:SI 0 "register_operand" "=r")
5170 (minus:SI (match_dup 1) (match_dup 2)))]
5172 "subcc\t%r1, %2, %0"
5173 [(set_attr "type" "compare")])
5175 (define_insn "*cmp_minus_ccx_set"
5176 [(set (reg:CCX_NOOV 100)
5177 (compare:CCX_NOOV (minus:DI (match_operand:DI 1 "register_operand" "r")
5178 (match_operand:DI 2 "arith_operand" "rI"))
5180 (set (match_operand:DI 0 "register_operand" "=r")
5181 (minus:DI (match_dup 1) (match_dup 2)))]
5184 [(set_attr "type" "compare")])
5186 ;; Integer Multiply/Divide.
5188 ;; The 32 bit multiply/divide instructions are deprecated on v9, but at
5189 ;; least in UltraSPARC I, II and IIi it is a win tick-wise.
5191 (define_insn "mulsi3"
5192 [(set (match_operand:SI 0 "register_operand" "=r")
5193 (mult:SI (match_operand:SI 1 "arith_operand" "%r")
5194 (match_operand:SI 2 "arith_operand" "rI")))]
5197 [(set_attr "type" "imul")])
5199 (define_expand "muldi3"
5200 [(set (match_operand:DI 0 "register_operand" "")
5201 (mult:DI (match_operand:DI 1 "arith_operand" "")
5202 (match_operand:DI 2 "arith_operand" "")))]
5203 "TARGET_ARCH64 || TARGET_V8PLUS"
5207 emit_insn (gen_muldi3_v8plus (operands[0], operands[1], operands[2]));
5212 (define_insn "*muldi3_sp64"
5213 [(set (match_operand:DI 0 "register_operand" "=r")
5214 (mult:DI (match_operand:DI 1 "arith_operand" "%r")
5215 (match_operand:DI 2 "arith_operand" "rI")))]
5218 [(set_attr "type" "imul")])
5220 ;; V8plus wide multiply.
5222 (define_insn "muldi3_v8plus"
5223 [(set (match_operand:DI 0 "register_operand" "=r,h")
5224 (mult:DI (match_operand:DI 1 "arith_operand" "%r,0")
5225 (match_operand:DI 2 "arith_operand" "rI,rI")))
5226 (clobber (match_scratch:SI 3 "=&h,X"))
5227 (clobber (match_scratch:SI 4 "=&h,X"))]
5230 if (sparc_check_64 (operands[1], insn) <= 0)
5231 output_asm_insn ("srl\t%L1, 0, %L1", operands);
5232 if (which_alternative == 1)
5233 output_asm_insn ("sllx\t%H1, 32, %H1", operands);
5234 if (GET_CODE (operands[2]) == CONST_INT)
5236 if (which_alternative == 1)
5237 return "or\t%L1, %H1, %H1\n\tmulx\t%H1, %2, %L0\;srlx\t%L0, 32, %H0";
5239 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";
5241 else if (rtx_equal_p (operands[1], operands[2]))
5243 if (which_alternative == 1)
5244 return "or\t%L1, %H1, %H1\n\tmulx\t%H1, %H1, %L0\;srlx\t%L0, 32, %H0";
5246 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";
5248 if (sparc_check_64 (operands[2], insn) <= 0)
5249 output_asm_insn ("srl\t%L2, 0, %L2", operands);
5250 if (which_alternative == 1)
5251 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";
5253 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";
5255 [(set_attr "type" "multi")
5256 (set_attr "length" "9,8")])
5258 (define_insn "*cmp_mul_set"
5260 (compare:CC (mult:SI (match_operand:SI 1 "arith_operand" "%r")
5261 (match_operand:SI 2 "arith_operand" "rI"))
5263 (set (match_operand:SI 0 "register_operand" "=r")
5264 (mult:SI (match_dup 1) (match_dup 2)))]
5265 "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS"
5266 "smulcc\t%1, %2, %0"
5267 [(set_attr "type" "imul")])
5269 (define_expand "mulsidi3"
5270 [(set (match_operand:DI 0 "register_operand" "")
5271 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
5272 (sign_extend:DI (match_operand:SI 2 "arith_operand" ""))))]
5275 if (CONSTANT_P (operands[2]))
5278 emit_insn (gen_const_mulsidi3_v8plus (operands[0], operands[1],
5280 else if (TARGET_ARCH32)
5281 emit_insn (gen_const_mulsidi3_sp32 (operands[0], operands[1],
5284 emit_insn (gen_const_mulsidi3_sp64 (operands[0], operands[1],
5290 emit_insn (gen_mulsidi3_v8plus (operands[0], operands[1], operands[2]));
5295 ;; V9 puts the 64 bit product in a 64 bit register. Only out or global
5296 ;; registers can hold 64 bit values in the V8plus environment.
5298 (define_insn "mulsidi3_v8plus"
5299 [(set (match_operand:DI 0 "register_operand" "=h,r")
5300 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5301 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
5302 (clobber (match_scratch:SI 3 "=X,&h"))]
5305 smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
5306 smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
5307 [(set_attr "type" "multi")
5308 (set_attr "length" "2,3")])
5311 (define_insn "const_mulsidi3_v8plus"
5312 [(set (match_operand:DI 0 "register_operand" "=h,r")
5313 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5314 (match_operand:DI 2 "small_int_operand" "I,I")))
5315 (clobber (match_scratch:SI 3 "=X,&h"))]
5318 smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
5319 smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
5320 [(set_attr "type" "multi")
5321 (set_attr "length" "2,3")])
5324 (define_insn "*mulsidi3_sp32"
5325 [(set (match_operand:DI 0 "register_operand" "=r")
5326 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5327 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
5330 return TARGET_SPARCLET
5331 ? "smuld\t%1, %2, %L0"
5332 : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
5335 (if_then_else (eq_attr "isa" "sparclet")
5336 (const_string "imul") (const_string "multi")))
5337 (set (attr "length")
5338 (if_then_else (eq_attr "isa" "sparclet")
5339 (const_int 1) (const_int 2)))])
5341 (define_insn "*mulsidi3_sp64"
5342 [(set (match_operand:DI 0 "register_operand" "=r")
5343 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5344 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
5345 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5347 [(set_attr "type" "imul")])
5349 ;; Extra pattern, because sign_extend of a constant isn't valid.
5352 (define_insn "const_mulsidi3_sp32"
5353 [(set (match_operand:DI 0 "register_operand" "=r")
5354 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5355 (match_operand:DI 2 "small_int_operand" "I")))]
5358 return TARGET_SPARCLET
5359 ? "smuld\t%1, %2, %L0"
5360 : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
5363 (if_then_else (eq_attr "isa" "sparclet")
5364 (const_string "imul") (const_string "multi")))
5365 (set (attr "length")
5366 (if_then_else (eq_attr "isa" "sparclet")
5367 (const_int 1) (const_int 2)))])
5369 (define_insn "const_mulsidi3_sp64"
5370 [(set (match_operand:DI 0 "register_operand" "=r")
5371 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5372 (match_operand:DI 2 "small_int_operand" "I")))]
5373 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5375 [(set_attr "type" "imul")])
5377 (define_expand "smulsi3_highpart"
5378 [(set (match_operand:SI 0 "register_operand" "")
5380 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
5381 (sign_extend:DI (match_operand:SI 2 "arith_operand" "")))
5383 "TARGET_HARD_MUL && TARGET_ARCH32"
5385 if (CONSTANT_P (operands[2]))
5389 emit_insn (gen_const_smulsi3_highpart_v8plus (operands[0],
5395 emit_insn (gen_const_smulsi3_highpart (operands[0], operands[1], operands[2]));
5400 emit_insn (gen_smulsi3_highpart_v8plus (operands[0], operands[1],
5401 operands[2], GEN_INT (32)));
5407 (define_insn "smulsi3_highpart_v8plus"
5408 [(set (match_operand:SI 0 "register_operand" "=h,r")
5410 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5411 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
5412 (match_operand:SI 3 "small_int_operand" "I,I"))))
5413 (clobber (match_scratch:SI 4 "=X,&h"))]
5416 smul\t%1, %2, %0\;srlx\t%0, %3, %0
5417 smul\t%1, %2, %4\;srlx\t%4, %3, %0"
5418 [(set_attr "type" "multi")
5419 (set_attr "length" "2")])
5421 ;; The combiner changes TRUNCATE in the previous pattern to SUBREG.
5424 [(set (match_operand:SI 0 "register_operand" "=h,r")
5427 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5428 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
5429 (match_operand:SI 3 "small_int_operand" "I,I"))
5431 (clobber (match_scratch:SI 4 "=X,&h"))]
5434 smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
5435 smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
5436 [(set_attr "type" "multi")
5437 (set_attr "length" "2")])
5440 (define_insn "const_smulsi3_highpart_v8plus"
5441 [(set (match_operand:SI 0 "register_operand" "=h,r")
5443 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5444 (match_operand:DI 2 "small_int_operand" "I,I"))
5445 (match_operand:SI 3 "small_int_operand" "I,I"))))
5446 (clobber (match_scratch:SI 4 "=X,&h"))]
5449 smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
5450 smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
5451 [(set_attr "type" "multi")
5452 (set_attr "length" "2")])
5455 (define_insn "*smulsi3_highpart_sp32"
5456 [(set (match_operand:SI 0 "register_operand" "=r")
5458 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5459 (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
5462 "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
5463 [(set_attr "type" "multi")
5464 (set_attr "length" "2")])
5467 (define_insn "const_smulsi3_highpart"
5468 [(set (match_operand:SI 0 "register_operand" "=r")
5470 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5471 (match_operand:DI 2 "small_int_operand" "i"))
5474 "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
5475 [(set_attr "type" "multi")
5476 (set_attr "length" "2")])
5478 (define_expand "umulsidi3"
5479 [(set (match_operand:DI 0 "register_operand" "")
5480 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
5481 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" ""))))]
5484 if (CONSTANT_P (operands[2]))
5487 emit_insn (gen_const_umulsidi3_v8plus (operands[0], operands[1],
5489 else if (TARGET_ARCH32)
5490 emit_insn (gen_const_umulsidi3_sp32 (operands[0], operands[1],
5493 emit_insn (gen_const_umulsidi3_sp64 (operands[0], operands[1],
5499 emit_insn (gen_umulsidi3_v8plus (operands[0], operands[1], operands[2]));
5505 (define_insn "umulsidi3_v8plus"
5506 [(set (match_operand:DI 0 "register_operand" "=h,r")
5507 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5508 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
5509 (clobber (match_scratch:SI 3 "=X,&h"))]
5512 umul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
5513 umul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
5514 [(set_attr "type" "multi")
5515 (set_attr "length" "2,3")])
5518 (define_insn "*umulsidi3_sp32"
5519 [(set (match_operand:DI 0 "register_operand" "=r")
5520 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5521 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
5524 return TARGET_SPARCLET
5525 ? "umuld\t%1, %2, %L0"
5526 : "umul\t%1, %2, %L0\n\trd\t%%y, %H0";
5529 (if_then_else (eq_attr "isa" "sparclet")
5530 (const_string "imul") (const_string "multi")))
5531 (set (attr "length")
5532 (if_then_else (eq_attr "isa" "sparclet")
5533 (const_int 1) (const_int 2)))])
5535 (define_insn "*umulsidi3_sp64"
5536 [(set (match_operand:DI 0 "register_operand" "=r")
5537 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5538 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
5539 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5541 [(set_attr "type" "imul")])
5543 ;; Extra pattern, because sign_extend of a constant isn't valid.
5546 (define_insn "const_umulsidi3_sp32"
5547 [(set (match_operand:DI 0 "register_operand" "=r")
5548 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5549 (match_operand:DI 2 "uns_small_int_operand" "")))]
5552 return TARGET_SPARCLET
5553 ? "umuld\t%1, %s2, %L0"
5554 : "umul\t%1, %s2, %L0\n\trd\t%%y, %H0";
5557 (if_then_else (eq_attr "isa" "sparclet")
5558 (const_string "imul") (const_string "multi")))
5559 (set (attr "length")
5560 (if_then_else (eq_attr "isa" "sparclet")
5561 (const_int 1) (const_int 2)))])
5563 (define_insn "const_umulsidi3_sp64"
5564 [(set (match_operand:DI 0 "register_operand" "=r")
5565 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5566 (match_operand:DI 2 "uns_small_int_operand" "")))]
5567 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5569 [(set_attr "type" "imul")])
5572 (define_insn "const_umulsidi3_v8plus"
5573 [(set (match_operand:DI 0 "register_operand" "=h,r")
5574 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5575 (match_operand:DI 2 "uns_small_int_operand" "")))
5576 (clobber (match_scratch:SI 3 "=X,h"))]
5579 umul\t%1, %s2, %L0\n\tsrlx\t%L0, 32, %H0
5580 umul\t%1, %s2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
5581 [(set_attr "type" "multi")
5582 (set_attr "length" "2,3")])
5584 (define_expand "umulsi3_highpart"
5585 [(set (match_operand:SI 0 "register_operand" "")
5587 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
5588 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" "")))
5590 "TARGET_HARD_MUL && TARGET_ARCH32"
5592 if (CONSTANT_P (operands[2]))
5596 emit_insn (gen_const_umulsi3_highpart_v8plus (operands[0],
5602 emit_insn (gen_const_umulsi3_highpart (operands[0], operands[1], operands[2]));
5607 emit_insn (gen_umulsi3_highpart_v8plus (operands[0], operands[1],
5608 operands[2], GEN_INT (32)));
5614 (define_insn "umulsi3_highpart_v8plus"
5615 [(set (match_operand:SI 0 "register_operand" "=h,r")
5617 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5618 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
5619 (match_operand:SI 3 "small_int_operand" "I,I"))))
5620 (clobber (match_scratch:SI 4 "=X,h"))]
5623 umul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
5624 umul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
5625 [(set_attr "type" "multi")
5626 (set_attr "length" "2")])
5629 (define_insn "const_umulsi3_highpart_v8plus"
5630 [(set (match_operand:SI 0 "register_operand" "=h,r")
5632 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5633 (match_operand:DI 2 "uns_small_int_operand" ""))
5634 (match_operand:SI 3 "small_int_operand" "I,I"))))
5635 (clobber (match_scratch:SI 4 "=X,h"))]
5638 umul\t%1, %s2, %0\n\tsrlx\t%0, %3, %0
5639 umul\t%1, %s2, %4\n\tsrlx\t%4, %3, %0"
5640 [(set_attr "type" "multi")
5641 (set_attr "length" "2")])
5644 (define_insn "*umulsi3_highpart_sp32"
5645 [(set (match_operand:SI 0 "register_operand" "=r")
5647 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5648 (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
5651 "umul\t%1, %2, %%g0\n\trd\t%%y, %0"
5652 [(set_attr "type" "multi")
5653 (set_attr "length" "2")])
5656 (define_insn "const_umulsi3_highpart"
5657 [(set (match_operand:SI 0 "register_operand" "=r")
5659 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5660 (match_operand:DI 2 "uns_small_int_operand" ""))
5663 "umul\t%1, %s2, %%g0\n\trd\t%%y, %0"
5664 [(set_attr "type" "multi")
5665 (set_attr "length" "2")])
5667 ;; The V8 architecture specifies that there must be 3 instructions between
5668 ;; a Y register write and a use of it for correct results.
5670 (define_expand "divsi3"
5671 [(parallel [(set (match_operand:SI 0 "register_operand" "=r,r")
5672 (div:SI (match_operand:SI 1 "register_operand" "r,r")
5673 (match_operand:SI 2 "input_operand" "rI,m")))
5674 (clobber (match_scratch:SI 3 "=&r,&r"))])]
5675 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
5679 operands[3] = gen_reg_rtx(SImode);
5680 emit_insn (gen_ashrsi3 (operands[3], operands[1], GEN_INT (31)));
5681 emit_insn (gen_divsi3_sp64 (operands[0], operands[1], operands[2],
5687 (define_insn "divsi3_sp32"
5688 [(set (match_operand:SI 0 "register_operand" "=r,r")
5689 (div:SI (match_operand:SI 1 "register_operand" "r,r")
5690 (match_operand:SI 2 "input_operand" "rI,m")))
5691 (clobber (match_scratch:SI 3 "=&r,&r"))]
5692 "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS)
5695 if (which_alternative == 0)
5697 return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tsdiv\t%1, %2, %0";
5699 return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tnop\n\tnop\n\tnop\n\tsdiv\t%1, %2, %0";
5702 return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tld\t%2, %3\n\tsdiv\t%1, %3, %0";
5704 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";
5706 [(set_attr "type" "multi")
5707 (set (attr "length")
5708 (if_then_else (eq_attr "isa" "v9")
5709 (const_int 4) (const_int 6)))])
5711 (define_insn "divsi3_sp64"
5712 [(set (match_operand:SI 0 "register_operand" "=r")
5713 (div:SI (match_operand:SI 1 "register_operand" "r")
5714 (match_operand:SI 2 "input_operand" "rI")))
5715 (use (match_operand:SI 3 "register_operand" "r"))]
5716 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5717 "wr\t%%g0, %3, %%y\n\tsdiv\t%1, %2, %0"
5718 [(set_attr "type" "multi")
5719 (set_attr "length" "2")])
5721 (define_insn "divdi3"
5722 [(set (match_operand:DI 0 "register_operand" "=r")
5723 (div:DI (match_operand:DI 1 "register_operand" "r")
5724 (match_operand:DI 2 "arith_operand" "rI")))]
5727 [(set_attr "type" "idiv")])
5729 (define_insn "*cmp_sdiv_cc_set"
5731 (compare:CC (div:SI (match_operand:SI 1 "register_operand" "r")
5732 (match_operand:SI 2 "arith_operand" "rI"))
5734 (set (match_operand:SI 0 "register_operand" "=r")
5735 (div:SI (match_dup 1) (match_dup 2)))
5736 (clobber (match_scratch:SI 3 "=&r"))]
5737 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
5740 return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tsdivcc\t%1, %2, %0";
5742 return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tnop\n\tnop\n\tnop\n\tsdivcc\t%1, %2, %0";
5744 [(set_attr "type" "multi")
5745 (set (attr "length")
5746 (if_then_else (eq_attr "isa" "v9")
5747 (const_int 3) (const_int 6)))])
5750 (define_expand "udivsi3"
5751 [(set (match_operand:SI 0 "register_operand" "")
5752 (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "")
5753 (match_operand:SI 2 "input_operand" "")))]
5754 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
5757 ;; The V8 architecture specifies that there must be 3 instructions between
5758 ;; a Y register write and a use of it for correct results.
5760 (define_insn "udivsi3_sp32"
5761 [(set (match_operand:SI 0 "register_operand" "=r,&r,&r")
5762 (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "r,r,m")
5763 (match_operand:SI 2 "input_operand" "rI,m,r")))]
5764 "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS)
5767 output_asm_insn ("wr\t%%g0, %%g0, %%y", operands);
5768 switch (which_alternative)
5771 return "nop\n\tnop\n\tnop\n\tudiv\t%1, %2, %0";
5773 return "ld\t%2, %0\n\tnop\n\tnop\n\tudiv\t%1, %0, %0";
5775 return "ld\t%1, %0\n\tnop\n\tnop\n\tudiv\t%0, %2, %0";
5778 [(set_attr "type" "multi")
5779 (set_attr "length" "5")])
5781 (define_insn "udivsi3_sp64"
5782 [(set (match_operand:SI 0 "register_operand" "=r")
5783 (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "r")
5784 (match_operand:SI 2 "input_operand" "rI")))]
5785 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5786 "wr\t%%g0, 0, %%y\n\tudiv\t%1, %2, %0"
5787 [(set_attr "type" "multi")
5788 (set_attr "length" "2")])
5790 (define_insn "udivdi3"
5791 [(set (match_operand:DI 0 "register_operand" "=r")
5792 (udiv:DI (match_operand:DI 1 "register_operand" "r")
5793 (match_operand:DI 2 "arith_operand" "rI")))]
5796 [(set_attr "type" "idiv")])
5798 (define_insn "*cmp_udiv_cc_set"
5800 (compare:CC (udiv:SI (match_operand:SI 1 "register_operand" "r")
5801 (match_operand:SI 2 "arith_operand" "rI"))
5803 (set (match_operand:SI 0 "register_operand" "=r")
5804 (udiv:SI (match_dup 1) (match_dup 2)))]
5806 || TARGET_DEPRECATED_V8_INSNS"
5809 return "wr\t%%g0, %%g0, %%y\n\tudivcc\t%1, %2, %0";
5811 return "wr\t%%g0, %%g0, %%y\n\tnop\n\tnop\n\tnop\n\tudivcc\t%1, %2, %0";
5813 [(set_attr "type" "multi")
5814 (set (attr "length")
5815 (if_then_else (eq_attr "isa" "v9")
5816 (const_int 2) (const_int 5)))])
5818 ; sparclet multiply/accumulate insns
5820 (define_insn "*smacsi"
5821 [(set (match_operand:SI 0 "register_operand" "=r")
5822 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "%r")
5823 (match_operand:SI 2 "arith_operand" "rI"))
5824 (match_operand:SI 3 "register_operand" "0")))]
5827 [(set_attr "type" "imul")])
5829 (define_insn "*smacdi"
5830 [(set (match_operand:DI 0 "register_operand" "=r")
5831 (plus:DI (mult:DI (sign_extend:DI
5832 (match_operand:SI 1 "register_operand" "%r"))
5834 (match_operand:SI 2 "register_operand" "r")))
5835 (match_operand:DI 3 "register_operand" "0")))]
5837 "smacd\t%1, %2, %L0"
5838 [(set_attr "type" "imul")])
5840 (define_insn "*umacdi"
5841 [(set (match_operand:DI 0 "register_operand" "=r")
5842 (plus:DI (mult:DI (zero_extend:DI
5843 (match_operand:SI 1 "register_operand" "%r"))
5845 (match_operand:SI 2 "register_operand" "r")))
5846 (match_operand:DI 3 "register_operand" "0")))]
5848 "umacd\t%1, %2, %L0"
5849 [(set_attr "type" "imul")])
5851 ;;- Boolean instructions
5852 ;; We define DImode `and' so with DImode `not' we can get
5853 ;; DImode `andn'. Other combinations are possible.
5855 (define_mode_macro V64I [DI V2SI V4HI V8QI])
5856 (define_mode_macro V32I [SI V2HI V4QI])
5858 (define_expand "and<V64I:mode>3"
5859 [(set (match_operand:V64I 0 "register_operand" "")
5860 (and:V64I (match_operand:V64I 1 "arith_double_operand" "")
5861 (match_operand:V64I 2 "arith_double_operand" "")))]
5865 (define_insn "*and<V64I:mode>3_sp32"
5866 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5867 (and:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
5868 (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
5873 [(set_attr "type" "*,fga")
5874 (set_attr "length" "2,*")
5875 (set_attr "fptype" "*,double")])
5877 (define_insn "*and<V64I:mode>3_sp64"
5878 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5879 (and:V64I (match_operand:V64I 1 "arith_operand" "%r,b")
5880 (match_operand:V64I 2 "arith_operand" "rI,b")))]
5885 [(set_attr "type" "*,fga")
5886 (set_attr "fptype" "*,double")])
5888 (define_insn "and<V32I:mode>3"
5889 [(set (match_operand:V32I 0 "register_operand" "=r,d")
5890 (and:V32I (match_operand:V32I 1 "arith_operand" "%r,d")
5891 (match_operand:V32I 2 "arith_operand" "rI,d")))]
5896 [(set_attr "type" "*,fga")
5897 (set_attr "fptype" "*,single")])
5900 [(set (match_operand:SI 0 "register_operand" "")
5901 (and:SI (match_operand:SI 1 "register_operand" "")
5902 (match_operand:SI 2 "" "")))
5903 (clobber (match_operand:SI 3 "register_operand" ""))]
5904 "GET_CODE (operands[2]) == CONST_INT
5905 && !SMALL_INT (operands[2])
5906 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
5907 [(set (match_dup 3) (match_dup 4))
5908 (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 1)))]
5910 operands[4] = GEN_INT (~INTVAL (operands[2]));
5913 (define_insn_and_split "*and_not_<V64I:mode>_sp32"
5914 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5915 (and:V64I (not:V64I (match_operand:V64I 1 "register_operand" "%r,b"))
5916 (match_operand:V64I 2 "register_operand" "r,b")))]
5920 fandnot1\t%1, %2, %0"
5921 "&& reload_completed
5922 && ((GET_CODE (operands[0]) == REG
5923 && REGNO (operands[0]) < 32)
5924 || (GET_CODE (operands[0]) == SUBREG
5925 && GET_CODE (SUBREG_REG (operands[0])) == REG
5926 && REGNO (SUBREG_REG (operands[0])) < 32))"
5927 [(set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))
5928 (set (match_dup 6) (and:SI (not:SI (match_dup 7)) (match_dup 8)))]
5929 "operands[3] = gen_highpart (SImode, operands[0]);
5930 operands[4] = gen_highpart (SImode, operands[1]);
5931 operands[5] = gen_highpart (SImode, operands[2]);
5932 operands[6] = gen_lowpart (SImode, operands[0]);
5933 operands[7] = gen_lowpart (SImode, operands[1]);
5934 operands[8] = gen_lowpart (SImode, operands[2]);"
5935 [(set_attr "type" "*,fga")
5936 (set_attr "length" "2,*")
5937 (set_attr "fptype" "*,double")])
5939 (define_insn "*and_not_<V64I:mode>_sp64"
5940 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5941 (and:V64I (not:V64I (match_operand:V64I 1 "register_operand" "%r,b"))
5942 (match_operand:V64I 2 "register_operand" "r,b")))]
5946 fandnot1\t%1, %2, %0"
5947 [(set_attr "type" "*,fga")
5948 (set_attr "fptype" "*,double")])
5950 (define_insn "*and_not_<V32I:mode>"
5951 [(set (match_operand:V32I 0 "register_operand" "=r,d")
5952 (and:V32I (not:V32I (match_operand:V32I 1 "register_operand" "%r,d"))
5953 (match_operand:V32I 2 "register_operand" "r,d")))]
5957 fandnot1s\t%1, %2, %0"
5958 [(set_attr "type" "*,fga")
5959 (set_attr "fptype" "*,single")])
5961 (define_expand "ior<V64I:mode>3"
5962 [(set (match_operand:V64I 0 "register_operand" "")
5963 (ior:V64I (match_operand:V64I 1 "arith_double_operand" "")
5964 (match_operand:V64I 2 "arith_double_operand" "")))]
5968 (define_insn "*ior<V64I:mode>3_sp32"
5969 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5970 (ior: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 "length" "2,*")
5978 (set_attr "fptype" "*,double")])
5980 (define_insn "*ior<V64I:mode>3_sp64"
5981 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5982 (ior:V64I (match_operand:V64I 1 "arith_operand" "%r,b")
5983 (match_operand:V64I 2 "arith_operand" "rI,b")))]
5988 [(set_attr "type" "*,fga")
5989 (set_attr "fptype" "*,double")])
5991 (define_insn "ior<V32I:mode>3"
5992 [(set (match_operand:V32I 0 "register_operand" "=r,d")
5993 (ior:V32I (match_operand:V32I 1 "arith_operand" "%r,d")
5994 (match_operand:V32I 2 "arith_operand" "rI,d")))]
5999 [(set_attr "type" "*,fga")
6000 (set_attr "fptype" "*,single")])
6003 [(set (match_operand:SI 0 "register_operand" "")
6004 (ior:SI (match_operand:SI 1 "register_operand" "")
6005 (match_operand:SI 2 "" "")))
6006 (clobber (match_operand:SI 3 "register_operand" ""))]
6007 "GET_CODE (operands[2]) == CONST_INT
6008 && !SMALL_INT (operands[2])
6009 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6010 [(set (match_dup 3) (match_dup 4))
6011 (set (match_dup 0) (ior:SI (not:SI (match_dup 3)) (match_dup 1)))]
6013 operands[4] = GEN_INT (~INTVAL (operands[2]));
6016 (define_insn_and_split "*or_not_<V64I:mode>_sp32"
6017 [(set (match_operand:V64I 0 "register_operand" "=r,b")
6018 (ior:V64I (not:V64I (match_operand:V64I 1 "register_operand" "r,b"))
6019 (match_operand:V64I 2 "register_operand" "r,b")))]
6023 fornot1\t%1, %2, %0"
6024 "&& reload_completed
6025 && ((GET_CODE (operands[0]) == REG
6026 && REGNO (operands[0]) < 32)
6027 || (GET_CODE (operands[0]) == SUBREG
6028 && GET_CODE (SUBREG_REG (operands[0])) == REG
6029 && REGNO (SUBREG_REG (operands[0])) < 32))"
6030 [(set (match_dup 3) (ior:SI (not:SI (match_dup 4)) (match_dup 5)))
6031 (set (match_dup 6) (ior:SI (not:SI (match_dup 7)) (match_dup 8)))]
6032 "operands[3] = gen_highpart (SImode, operands[0]);
6033 operands[4] = gen_highpart (SImode, operands[1]);
6034 operands[5] = gen_highpart (SImode, operands[2]);
6035 operands[6] = gen_lowpart (SImode, operands[0]);
6036 operands[7] = gen_lowpart (SImode, operands[1]);
6037 operands[8] = gen_lowpart (SImode, operands[2]);"
6038 [(set_attr "type" "*,fga")
6039 (set_attr "length" "2,*")
6040 (set_attr "fptype" "*,double")])
6042 (define_insn "*or_not_<V64I:mode>_sp64"
6043 [(set (match_operand:V64I 0 "register_operand" "=r,b")
6044 (ior:V64I (not:V64I (match_operand:V64I 1 "register_operand" "r,b"))
6045 (match_operand:V64I 2 "register_operand" "r,b")))]
6049 fornot1\t%1, %2, %0"
6050 [(set_attr "type" "*,fga")
6051 (set_attr "fptype" "*,double")])
6053 (define_insn "*or_not_<V32I:mode>"
6054 [(set (match_operand:V32I 0 "register_operand" "=r,d")
6055 (ior:V32I (not:V32I (match_operand:V32I 1 "register_operand" "r,d"))
6056 (match_operand:V32I 2 "register_operand" "r,d")))]
6060 fornot1s\t%1, %2, %0"
6061 [(set_attr "type" "*,fga")
6062 (set_attr "fptype" "*,single")])
6064 (define_expand "xor<V64I:mode>3"
6065 [(set (match_operand:V64I 0 "register_operand" "")
6066 (xor:V64I (match_operand:V64I 1 "arith_double_operand" "")
6067 (match_operand:V64I 2 "arith_double_operand" "")))]
6071 (define_insn "*xor<V64I:mode>3_sp32"
6072 [(set (match_operand:V64I 0 "register_operand" "=r,b")
6073 (xor: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 "length" "2,*")
6081 (set_attr "fptype" "*,double")])
6083 (define_insn "*xor<V64I:mode>3_sp64"
6084 [(set (match_operand:V64I 0 "register_operand" "=r,b")
6085 (xor:V64I (match_operand:V64I 1 "arith_operand" "%rJ,b")
6086 (match_operand:V64I 2 "arith_operand" "rI,b")))]
6091 [(set_attr "type" "*,fga")
6092 (set_attr "fptype" "*,double")])
6094 (define_insn "xor<V32I:mode>3"
6095 [(set (match_operand:V32I 0 "register_operand" "=r,d")
6096 (xor:V32I (match_operand:V32I 1 "arith_operand" "%rJ,d")
6097 (match_operand:V32I 2 "arith_operand" "rI,d")))]
6102 [(set_attr "type" "*,fga")
6103 (set_attr "fptype" "*,single")])
6106 [(set (match_operand:SI 0 "register_operand" "")
6107 (xor:SI (match_operand:SI 1 "register_operand" "")
6108 (match_operand:SI 2 "" "")))
6109 (clobber (match_operand:SI 3 "register_operand" ""))]
6110 "GET_CODE (operands[2]) == CONST_INT
6111 && !SMALL_INT (operands[2])
6112 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6113 [(set (match_dup 3) (match_dup 4))
6114 (set (match_dup 0) (not:SI (xor:SI (match_dup 3) (match_dup 1))))]
6116 operands[4] = GEN_INT (~INTVAL (operands[2]));
6120 [(set (match_operand:SI 0 "register_operand" "")
6121 (not:SI (xor:SI (match_operand:SI 1 "register_operand" "")
6122 (match_operand:SI 2 "" ""))))
6123 (clobber (match_operand:SI 3 "register_operand" ""))]
6124 "GET_CODE (operands[2]) == CONST_INT
6125 && !SMALL_INT (operands[2])
6126 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6127 [(set (match_dup 3) (match_dup 4))
6128 (set (match_dup 0) (xor:SI (match_dup 3) (match_dup 1)))]
6130 operands[4] = GEN_INT (~INTVAL (operands[2]));
6133 ;; Split DImode logical operations requiring two instructions.
6135 [(set (match_operand:V64I 0 "register_operand" "")
6136 (match_operator:V64I 1 "cc_arith_operator" ; AND, IOR, XOR
6137 [(match_operand:V64I 2 "register_operand" "")
6138 (match_operand:V64I 3 "arith_double_operand" "")]))]
6141 && ((GET_CODE (operands[0]) == REG
6142 && REGNO (operands[0]) < 32)
6143 || (GET_CODE (operands[0]) == SUBREG
6144 && GET_CODE (SUBREG_REG (operands[0])) == REG
6145 && REGNO (SUBREG_REG (operands[0])) < 32))"
6146 [(set (match_dup 4) (match_op_dup:SI 1 [(match_dup 6) (match_dup 8)]))
6147 (set (match_dup 5) (match_op_dup:SI 1 [(match_dup 7) (match_dup 9)]))]
6149 operands[4] = gen_highpart (SImode, operands[0]);
6150 operands[5] = gen_lowpart (SImode, operands[0]);
6151 operands[6] = gen_highpart (SImode, operands[2]);
6152 operands[7] = gen_lowpart (SImode, operands[2]);
6153 #if HOST_BITS_PER_WIDE_INT == 32
6154 if (GET_CODE (operands[3]) == CONST_INT && <V64I:MODE>mode == DImode)
6156 if (INTVAL (operands[3]) < 0)
6157 operands[8] = constm1_rtx;
6159 operands[8] = const0_rtx;
6163 operands[8] = gen_highpart_mode (SImode, <V64I:MODE>mode, operands[3]);
6164 operands[9] = gen_lowpart (SImode, operands[3]);
6167 ;; xnor patterns. Note that (a ^ ~b) == (~a ^ b) == ~(a ^ b).
6168 ;; Combine now canonicalizes to the rightmost expression.
6169 (define_insn_and_split "*xor_not_<V64I:mode>_sp32"
6170 [(set (match_operand:V64I 0 "register_operand" "=r,b")
6171 (not:V64I (xor:V64I (match_operand:V64I 1 "register_operand" "r,b")
6172 (match_operand:V64I 2 "register_operand" "r,b"))))]
6177 "&& reload_completed
6178 && ((GET_CODE (operands[0]) == REG
6179 && REGNO (operands[0]) < 32)
6180 || (GET_CODE (operands[0]) == SUBREG
6181 && GET_CODE (SUBREG_REG (operands[0])) == REG
6182 && REGNO (SUBREG_REG (operands[0])) < 32))"
6183 [(set (match_dup 3) (not:SI (xor:SI (match_dup 4) (match_dup 5))))
6184 (set (match_dup 6) (not:SI (xor:SI (match_dup 7) (match_dup 8))))]
6185 "operands[3] = gen_highpart (SImode, operands[0]);
6186 operands[4] = gen_highpart (SImode, operands[1]);
6187 operands[5] = gen_highpart (SImode, operands[2]);
6188 operands[6] = gen_lowpart (SImode, operands[0]);
6189 operands[7] = gen_lowpart (SImode, operands[1]);
6190 operands[8] = gen_lowpart (SImode, operands[2]);"
6191 [(set_attr "type" "*,fga")
6192 (set_attr "length" "2,*")
6193 (set_attr "fptype" "*,double")])
6195 (define_insn "*xor_not_<V64I:mode>_sp64"
6196 [(set (match_operand:V64I 0 "register_operand" "=r,b")
6197 (not:V64I (xor:V64I (match_operand:V64I 1 "register_or_zero_operand" "rJ,b")
6198 (match_operand:V64I 2 "arith_operand" "rI,b"))))]
6203 [(set_attr "type" "*,fga")
6204 (set_attr "fptype" "*,double")])
6206 (define_insn "*xor_not_<V32I:mode>"
6207 [(set (match_operand:V32I 0 "register_operand" "=r,d")
6208 (not:V32I (xor:V32I (match_operand:V32I 1 "register_or_zero_operand" "rJ,d")
6209 (match_operand:V32I 2 "arith_operand" "rI,d"))))]
6214 [(set_attr "type" "*,fga")
6215 (set_attr "fptype" "*,single")])
6217 ;; These correspond to the above in the case where we also (or only)
6218 ;; want to set the condition code.
6220 (define_insn "*cmp_cc_arith_op"
6223 (match_operator:SI 2 "cc_arith_operator"
6224 [(match_operand:SI 0 "arith_operand" "%r")
6225 (match_operand:SI 1 "arith_operand" "rI")])
6228 "%A2cc\t%0, %1, %%g0"
6229 [(set_attr "type" "compare")])
6231 (define_insn "*cmp_ccx_arith_op"
6234 (match_operator:DI 2 "cc_arith_operator"
6235 [(match_operand:DI 0 "arith_operand" "%r")
6236 (match_operand:DI 1 "arith_operand" "rI")])
6239 "%A2cc\t%0, %1, %%g0"
6240 [(set_attr "type" "compare")])
6242 (define_insn "*cmp_cc_arith_op_set"
6245 (match_operator:SI 3 "cc_arith_operator"
6246 [(match_operand:SI 1 "arith_operand" "%r")
6247 (match_operand:SI 2 "arith_operand" "rI")])
6249 (set (match_operand:SI 0 "register_operand" "=r")
6250 (match_operator:SI 4 "cc_arith_operator" [(match_dup 1) (match_dup 2)]))]
6251 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
6253 [(set_attr "type" "compare")])
6255 (define_insn "*cmp_ccx_arith_op_set"
6258 (match_operator:DI 3 "cc_arith_operator"
6259 [(match_operand:DI 1 "arith_operand" "%r")
6260 (match_operand:DI 2 "arith_operand" "rI")])
6262 (set (match_operand:DI 0 "register_operand" "=r")
6263 (match_operator:DI 4 "cc_arith_operator" [(match_dup 1) (match_dup 2)]))]
6264 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
6266 [(set_attr "type" "compare")])
6268 (define_insn "*cmp_cc_xor_not"
6271 (not:SI (xor:SI (match_operand:SI 0 "register_or_zero_operand" "%rJ")
6272 (match_operand:SI 1 "arith_operand" "rI")))
6275 "xnorcc\t%r0, %1, %%g0"
6276 [(set_attr "type" "compare")])
6278 (define_insn "*cmp_ccx_xor_not"
6281 (not:DI (xor:DI (match_operand:DI 0 "register_or_zero_operand" "%rJ")
6282 (match_operand:DI 1 "arith_operand" "rI")))
6285 "xnorcc\t%r0, %1, %%g0"
6286 [(set_attr "type" "compare")])
6288 (define_insn "*cmp_cc_xor_not_set"
6291 (not:SI (xor:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ")
6292 (match_operand:SI 2 "arith_operand" "rI")))
6294 (set (match_operand:SI 0 "register_operand" "=r")
6295 (not:SI (xor:SI (match_dup 1) (match_dup 2))))]
6297 "xnorcc\t%r1, %2, %0"
6298 [(set_attr "type" "compare")])
6300 (define_insn "*cmp_ccx_xor_not_set"
6303 (not:DI (xor:DI (match_operand:DI 1 "register_or_zero_operand" "%rJ")
6304 (match_operand:DI 2 "arith_operand" "rI")))
6306 (set (match_operand:DI 0 "register_operand" "=r")
6307 (not:DI (xor:DI (match_dup 1) (match_dup 2))))]
6309 "xnorcc\t%r1, %2, %0"
6310 [(set_attr "type" "compare")])
6312 (define_insn "*cmp_cc_arith_op_not"
6315 (match_operator:SI 2 "cc_arith_not_operator"
6316 [(not:SI (match_operand:SI 0 "arith_operand" "rI"))
6317 (match_operand:SI 1 "register_or_zero_operand" "rJ")])
6320 "%B2cc\t%r1, %0, %%g0"
6321 [(set_attr "type" "compare")])
6323 (define_insn "*cmp_ccx_arith_op_not"
6326 (match_operator:DI 2 "cc_arith_not_operator"
6327 [(not:DI (match_operand:DI 0 "arith_operand" "rI"))
6328 (match_operand:DI 1 "register_or_zero_operand" "rJ")])
6331 "%B2cc\t%r1, %0, %%g0"
6332 [(set_attr "type" "compare")])
6334 (define_insn "*cmp_cc_arith_op_not_set"
6337 (match_operator:SI 3 "cc_arith_not_operator"
6338 [(not:SI (match_operand:SI 1 "arith_operand" "rI"))
6339 (match_operand:SI 2 "register_or_zero_operand" "rJ")])
6341 (set (match_operand:SI 0 "register_operand" "=r")
6342 (match_operator:SI 4 "cc_arith_not_operator"
6343 [(not:SI (match_dup 1)) (match_dup 2)]))]
6344 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
6345 "%B3cc\t%r2, %1, %0"
6346 [(set_attr "type" "compare")])
6348 (define_insn "*cmp_ccx_arith_op_not_set"
6351 (match_operator:DI 3 "cc_arith_not_operator"
6352 [(not:DI (match_operand:DI 1 "arith_operand" "rI"))
6353 (match_operand:DI 2 "register_or_zero_operand" "rJ")])
6355 (set (match_operand:DI 0 "register_operand" "=r")
6356 (match_operator:DI 4 "cc_arith_not_operator"
6357 [(not:DI (match_dup 1)) (match_dup 2)]))]
6358 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
6359 "%B3cc\t%r2, %1, %0"
6360 [(set_attr "type" "compare")])
6362 ;; We cannot use the "neg" pseudo insn because the Sun assembler
6363 ;; does not know how to make it work for constants.
6365 (define_expand "negdi2"
6366 [(set (match_operand:DI 0 "register_operand" "=r")
6367 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
6370 if (! TARGET_ARCH64)
6372 emit_insn (gen_rtx_PARALLEL
6375 gen_rtx_SET (VOIDmode, operand0,
6376 gen_rtx_NEG (DImode, operand1)),
6377 gen_rtx_CLOBBER (VOIDmode,
6378 gen_rtx_REG (CCmode,
6384 (define_insn_and_split "*negdi2_sp32"
6385 [(set (match_operand:DI 0 "register_operand" "=r")
6386 (neg:DI (match_operand:DI 1 "register_operand" "r")))
6387 (clobber (reg:CC 100))]
6390 "&& reload_completed"
6391 [(parallel [(set (reg:CC_NOOV 100)
6392 (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 5))
6394 (set (match_dup 4) (minus:SI (const_int 0) (match_dup 5)))])
6395 (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
6396 (ltu:SI (reg:CC 100) (const_int 0))))]
6397 "operands[2] = gen_highpart (SImode, operands[0]);
6398 operands[3] = gen_highpart (SImode, operands[1]);
6399 operands[4] = gen_lowpart (SImode, operands[0]);
6400 operands[5] = gen_lowpart (SImode, operands[1]);"
6401 [(set_attr "length" "2")])
6403 (define_insn "*negdi2_sp64"
6404 [(set (match_operand:DI 0 "register_operand" "=r")
6405 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
6407 "sub\t%%g0, %1, %0")
6409 (define_insn "negsi2"
6410 [(set (match_operand:SI 0 "register_operand" "=r")
6411 (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
6413 "sub\t%%g0, %1, %0")
6415 (define_insn "*cmp_cc_neg"
6416 [(set (reg:CC_NOOV 100)
6417 (compare:CC_NOOV (neg:SI (match_operand:SI 0 "arith_operand" "rI"))
6420 "subcc\t%%g0, %0, %%g0"
6421 [(set_attr "type" "compare")])
6423 (define_insn "*cmp_ccx_neg"
6424 [(set (reg:CCX_NOOV 100)
6425 (compare:CCX_NOOV (neg:DI (match_operand:DI 0 "arith_operand" "rI"))
6428 "subcc\t%%g0, %0, %%g0"
6429 [(set_attr "type" "compare")])
6431 (define_insn "*cmp_cc_set_neg"
6432 [(set (reg:CC_NOOV 100)
6433 (compare:CC_NOOV (neg:SI (match_operand:SI 1 "arith_operand" "rI"))
6435 (set (match_operand:SI 0 "register_operand" "=r")
6436 (neg:SI (match_dup 1)))]
6438 "subcc\t%%g0, %1, %0"
6439 [(set_attr "type" "compare")])
6441 (define_insn "*cmp_ccx_set_neg"
6442 [(set (reg:CCX_NOOV 100)
6443 (compare:CCX_NOOV (neg:DI (match_operand:DI 1 "arith_operand" "rI"))
6445 (set (match_operand:DI 0 "register_operand" "=r")
6446 (neg:DI (match_dup 1)))]
6448 "subcc\t%%g0, %1, %0"
6449 [(set_attr "type" "compare")])
6451 ;; We cannot use the "not" pseudo insn because the Sun assembler
6452 ;; does not know how to make it work for constants.
6453 (define_expand "one_cmpl<V64I:mode>2"
6454 [(set (match_operand:V64I 0 "register_operand" "")
6455 (not:V64I (match_operand:V64I 1 "register_operand" "")))]
6459 (define_insn_and_split "*one_cmpl<V64I:mode>2_sp32"
6460 [(set (match_operand:V64I 0 "register_operand" "=r,b")
6461 (not:V64I (match_operand:V64I 1 "register_operand" "r,b")))]
6466 "&& reload_completed
6467 && ((GET_CODE (operands[0]) == REG
6468 && REGNO (operands[0]) < 32)
6469 || (GET_CODE (operands[0]) == SUBREG
6470 && GET_CODE (SUBREG_REG (operands[0])) == REG
6471 && REGNO (SUBREG_REG (operands[0])) < 32))"
6472 [(set (match_dup 2) (not:SI (xor:SI (match_dup 3) (const_int 0))))
6473 (set (match_dup 4) (not:SI (xor:SI (match_dup 5) (const_int 0))))]
6474 "operands[2] = gen_highpart (SImode, operands[0]);
6475 operands[3] = gen_highpart (SImode, operands[1]);
6476 operands[4] = gen_lowpart (SImode, operands[0]);
6477 operands[5] = gen_lowpart (SImode, operands[1]);"
6478 [(set_attr "type" "*,fga")
6479 (set_attr "length" "2,*")
6480 (set_attr "fptype" "*,double")])
6482 (define_insn "*one_cmpl<V64I:mode>2_sp64"
6483 [(set (match_operand:V64I 0 "register_operand" "=r,b")
6484 (not:V64I (match_operand:V64I 1 "arith_operand" "rI,b")))]
6489 [(set_attr "type" "*,fga")
6490 (set_attr "fptype" "*,double")])
6492 (define_insn "one_cmpl<V32I:mode>2"
6493 [(set (match_operand:V32I 0 "register_operand" "=r,d")
6494 (not:V32I (match_operand:V32I 1 "arith_operand" "rI,d")))]
6499 [(set_attr "type" "*,fga")
6500 (set_attr "fptype" "*,single")])
6502 (define_insn "*cmp_cc_not"
6504 (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI"))
6507 "xnorcc\t%%g0, %0, %%g0"
6508 [(set_attr "type" "compare")])
6510 (define_insn "*cmp_ccx_not"
6512 (compare:CCX (not:DI (match_operand:DI 0 "arith_operand" "rI"))
6515 "xnorcc\t%%g0, %0, %%g0"
6516 [(set_attr "type" "compare")])
6518 (define_insn "*cmp_cc_set_not"
6520 (compare:CC (not:SI (match_operand:SI 1 "arith_operand" "rI"))
6522 (set (match_operand:SI 0 "register_operand" "=r")
6523 (not:SI (match_dup 1)))]
6525 "xnorcc\t%%g0, %1, %0"
6526 [(set_attr "type" "compare")])
6528 (define_insn "*cmp_ccx_set_not"
6530 (compare:CCX (not:DI (match_operand:DI 1 "arith_operand" "rI"))
6532 (set (match_operand:DI 0 "register_operand" "=r")
6533 (not:DI (match_dup 1)))]
6535 "xnorcc\t%%g0, %1, %0"
6536 [(set_attr "type" "compare")])
6538 (define_insn "*cmp_cc_set"
6539 [(set (match_operand:SI 0 "register_operand" "=r")
6540 (match_operand:SI 1 "register_operand" "r"))
6542 (compare:CC (match_dup 1)
6546 [(set_attr "type" "compare")])
6548 (define_insn "*cmp_ccx_set64"
6549 [(set (match_operand:DI 0 "register_operand" "=r")
6550 (match_operand:DI 1 "register_operand" "r"))
6552 (compare:CCX (match_dup 1)
6556 [(set_attr "type" "compare")])
6558 ;; Floating point arithmetic instructions.
6560 (define_expand "addtf3"
6561 [(set (match_operand:TF 0 "nonimmediate_operand" "")
6562 (plus:TF (match_operand:TF 1 "general_operand" "")
6563 (match_operand:TF 2 "general_operand" "")))]
6564 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6565 "emit_tfmode_binop (PLUS, operands); DONE;")
6567 (define_insn "*addtf3_hq"
6568 [(set (match_operand:TF 0 "register_operand" "=e")
6569 (plus:TF (match_operand:TF 1 "register_operand" "e")
6570 (match_operand:TF 2 "register_operand" "e")))]
6571 "TARGET_FPU && TARGET_HARD_QUAD"
6573 [(set_attr "type" "fp")])
6575 (define_insn "adddf3"
6576 [(set (match_operand:DF 0 "register_operand" "=e")
6577 (plus:DF (match_operand:DF 1 "register_operand" "e")
6578 (match_operand:DF 2 "register_operand" "e")))]
6581 [(set_attr "type" "fp")
6582 (set_attr "fptype" "double")])
6584 (define_insn "addsf3"
6585 [(set (match_operand:SF 0 "register_operand" "=f")
6586 (plus:SF (match_operand:SF 1 "register_operand" "f")
6587 (match_operand:SF 2 "register_operand" "f")))]
6590 [(set_attr "type" "fp")])
6592 (define_expand "subtf3"
6593 [(set (match_operand:TF 0 "nonimmediate_operand" "")
6594 (minus:TF (match_operand:TF 1 "general_operand" "")
6595 (match_operand:TF 2 "general_operand" "")))]
6596 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6597 "emit_tfmode_binop (MINUS, operands); DONE;")
6599 (define_insn "*subtf3_hq"
6600 [(set (match_operand:TF 0 "register_operand" "=e")
6601 (minus:TF (match_operand:TF 1 "register_operand" "e")
6602 (match_operand:TF 2 "register_operand" "e")))]
6603 "TARGET_FPU && TARGET_HARD_QUAD"
6605 [(set_attr "type" "fp")])
6607 (define_insn "subdf3"
6608 [(set (match_operand:DF 0 "register_operand" "=e")
6609 (minus:DF (match_operand:DF 1 "register_operand" "e")
6610 (match_operand:DF 2 "register_operand" "e")))]
6613 [(set_attr "type" "fp")
6614 (set_attr "fptype" "double")])
6616 (define_insn "subsf3"
6617 [(set (match_operand:SF 0 "register_operand" "=f")
6618 (minus:SF (match_operand:SF 1 "register_operand" "f")
6619 (match_operand:SF 2 "register_operand" "f")))]
6622 [(set_attr "type" "fp")])
6624 (define_expand "multf3"
6625 [(set (match_operand:TF 0 "nonimmediate_operand" "")
6626 (mult:TF (match_operand:TF 1 "general_operand" "")
6627 (match_operand:TF 2 "general_operand" "")))]
6628 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6629 "emit_tfmode_binop (MULT, operands); DONE;")
6631 (define_insn "*multf3_hq"
6632 [(set (match_operand:TF 0 "register_operand" "=e")
6633 (mult:TF (match_operand:TF 1 "register_operand" "e")
6634 (match_operand:TF 2 "register_operand" "e")))]
6635 "TARGET_FPU && TARGET_HARD_QUAD"
6637 [(set_attr "type" "fpmul")])
6639 (define_insn "muldf3"
6640 [(set (match_operand:DF 0 "register_operand" "=e")
6641 (mult:DF (match_operand:DF 1 "register_operand" "e")
6642 (match_operand:DF 2 "register_operand" "e")))]
6645 [(set_attr "type" "fpmul")
6646 (set_attr "fptype" "double")])
6648 (define_insn "mulsf3"
6649 [(set (match_operand:SF 0 "register_operand" "=f")
6650 (mult:SF (match_operand:SF 1 "register_operand" "f")
6651 (match_operand:SF 2 "register_operand" "f")))]
6654 [(set_attr "type" "fpmul")])
6656 (define_insn "*muldf3_extend"
6657 [(set (match_operand:DF 0 "register_operand" "=e")
6658 (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "f"))
6659 (float_extend:DF (match_operand:SF 2 "register_operand" "f"))))]
6660 "(TARGET_V8 || TARGET_V9) && TARGET_FPU"
6661 "fsmuld\t%1, %2, %0"
6662 [(set_attr "type" "fpmul")
6663 (set_attr "fptype" "double")])
6665 (define_insn "*multf3_extend"
6666 [(set (match_operand:TF 0 "register_operand" "=e")
6667 (mult:TF (float_extend:TF (match_operand:DF 1 "register_operand" "e"))
6668 (float_extend:TF (match_operand:DF 2 "register_operand" "e"))))]
6669 "(TARGET_V8 || TARGET_V9) && TARGET_FPU && TARGET_HARD_QUAD"
6670 "fdmulq\t%1, %2, %0"
6671 [(set_attr "type" "fpmul")])
6673 (define_expand "divtf3"
6674 [(set (match_operand:TF 0 "nonimmediate_operand" "")
6675 (div:TF (match_operand:TF 1 "general_operand" "")
6676 (match_operand:TF 2 "general_operand" "")))]
6677 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6678 "emit_tfmode_binop (DIV, operands); DONE;")
6680 ;; don't have timing for quad-prec. divide.
6681 (define_insn "*divtf3_hq"
6682 [(set (match_operand:TF 0 "register_operand" "=e")
6683 (div:TF (match_operand:TF 1 "register_operand" "e")
6684 (match_operand:TF 2 "register_operand" "e")))]
6685 "TARGET_FPU && TARGET_HARD_QUAD"
6687 [(set_attr "type" "fpdivd")])
6689 (define_insn "divdf3"
6690 [(set (match_operand:DF 0 "register_operand" "=e")
6691 (div:DF (match_operand:DF 1 "register_operand" "e")
6692 (match_operand:DF 2 "register_operand" "e")))]
6695 [(set_attr "type" "fpdivd")
6696 (set_attr "fptype" "double")])
6698 (define_insn "divsf3"
6699 [(set (match_operand:SF 0 "register_operand" "=f")
6700 (div:SF (match_operand:SF 1 "register_operand" "f")
6701 (match_operand:SF 2 "register_operand" "f")))]
6704 [(set_attr "type" "fpdivs")])
6706 (define_expand "negtf2"
6707 [(set (match_operand:TF 0 "register_operand" "=e,e")
6708 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
6712 (define_insn_and_split "*negtf2_notv9"
6713 [(set (match_operand:TF 0 "register_operand" "=e,e")
6714 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
6715 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
6721 "&& reload_completed
6722 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6723 [(set (match_dup 2) (neg:SF (match_dup 3)))
6724 (set (match_dup 4) (match_dup 5))
6725 (set (match_dup 6) (match_dup 7))]
6726 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6727 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6728 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6729 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
6730 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6731 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6732 [(set_attr "type" "fpmove,*")
6733 (set_attr "length" "*,2")])
6735 (define_insn_and_split "*negtf2_v9"
6736 [(set (match_operand:TF 0 "register_operand" "=e,e")
6737 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
6738 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
6739 "TARGET_FPU && TARGET_V9"
6743 "&& reload_completed
6744 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6745 [(set (match_dup 2) (neg:DF (match_dup 3)))
6746 (set (match_dup 4) (match_dup 5))]
6747 "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
6748 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
6749 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6750 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6751 [(set_attr "type" "fpmove,*")
6752 (set_attr "length" "*,2")
6753 (set_attr "fptype" "double")])
6755 (define_expand "negdf2"
6756 [(set (match_operand:DF 0 "register_operand" "")
6757 (neg:DF (match_operand:DF 1 "register_operand" "")))]
6761 (define_insn_and_split "*negdf2_notv9"
6762 [(set (match_operand:DF 0 "register_operand" "=e,e")
6763 (neg:DF (match_operand:DF 1 "register_operand" "0,e")))]
6764 "TARGET_FPU && ! TARGET_V9"
6768 "&& reload_completed
6769 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6770 [(set (match_dup 2) (neg:SF (match_dup 3)))
6771 (set (match_dup 4) (match_dup 5))]
6772 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6773 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6774 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6775 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);"
6776 [(set_attr "type" "fpmove,*")
6777 (set_attr "length" "*,2")])
6779 (define_insn "*negdf2_v9"
6780 [(set (match_operand:DF 0 "register_operand" "=e")
6781 (neg:DF (match_operand:DF 1 "register_operand" "e")))]
6782 "TARGET_FPU && TARGET_V9"
6784 [(set_attr "type" "fpmove")
6785 (set_attr "fptype" "double")])
6787 (define_insn "negsf2"
6788 [(set (match_operand:SF 0 "register_operand" "=f")
6789 (neg:SF (match_operand:SF 1 "register_operand" "f")))]
6792 [(set_attr "type" "fpmove")])
6794 (define_expand "abstf2"
6795 [(set (match_operand:TF 0 "register_operand" "")
6796 (abs:TF (match_operand:TF 1 "register_operand" "")))]
6800 (define_insn_and_split "*abstf2_notv9"
6801 [(set (match_operand:TF 0 "register_operand" "=e,e")
6802 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6803 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
6804 "TARGET_FPU && ! TARGET_V9"
6808 "&& reload_completed
6809 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6810 [(set (match_dup 2) (abs:SF (match_dup 3)))
6811 (set (match_dup 4) (match_dup 5))
6812 (set (match_dup 6) (match_dup 7))]
6813 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6814 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6815 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6816 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
6817 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6818 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6819 [(set_attr "type" "fpmove,*")
6820 (set_attr "length" "*,2")])
6822 (define_insn "*abstf2_hq_v9"
6823 [(set (match_operand:TF 0 "register_operand" "=e,e")
6824 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6825 "TARGET_FPU && TARGET_V9 && TARGET_HARD_QUAD"
6829 [(set_attr "type" "fpmove")
6830 (set_attr "fptype" "double,*")])
6832 (define_insn_and_split "*abstf2_v9"
6833 [(set (match_operand:TF 0 "register_operand" "=e,e")
6834 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6835 "TARGET_FPU && TARGET_V9 && !TARGET_HARD_QUAD"
6839 "&& reload_completed
6840 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6841 [(set (match_dup 2) (abs:DF (match_dup 3)))
6842 (set (match_dup 4) (match_dup 5))]
6843 "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
6844 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
6845 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6846 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6847 [(set_attr "type" "fpmove,*")
6848 (set_attr "length" "*,2")
6849 (set_attr "fptype" "double,*")])
6851 (define_expand "absdf2"
6852 [(set (match_operand:DF 0 "register_operand" "")
6853 (abs:DF (match_operand:DF 1 "register_operand" "")))]
6857 (define_insn_and_split "*absdf2_notv9"
6858 [(set (match_operand:DF 0 "register_operand" "=e,e")
6859 (abs:DF (match_operand:DF 1 "register_operand" "0,e")))]
6860 "TARGET_FPU && ! TARGET_V9"
6864 "&& reload_completed
6865 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6866 [(set (match_dup 2) (abs:SF (match_dup 3)))
6867 (set (match_dup 4) (match_dup 5))]
6868 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6869 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6870 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6871 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);"
6872 [(set_attr "type" "fpmove,*")
6873 (set_attr "length" "*,2")])
6875 (define_insn "*absdf2_v9"
6876 [(set (match_operand:DF 0 "register_operand" "=e")
6877 (abs:DF (match_operand:DF 1 "register_operand" "e")))]
6878 "TARGET_FPU && TARGET_V9"
6880 [(set_attr "type" "fpmove")
6881 (set_attr "fptype" "double")])
6883 (define_insn "abssf2"
6884 [(set (match_operand:SF 0 "register_operand" "=f")
6885 (abs:SF (match_operand:SF 1 "register_operand" "f")))]
6888 [(set_attr "type" "fpmove")])
6890 (define_expand "sqrttf2"
6891 [(set (match_operand:TF 0 "nonimmediate_operand" "")
6892 (sqrt:TF (match_operand:TF 1 "general_operand" "")))]
6893 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6894 "emit_tfmode_unop (SQRT, operands); DONE;")
6896 (define_insn "*sqrttf2_hq"
6897 [(set (match_operand:TF 0 "register_operand" "=e")
6898 (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
6899 "TARGET_FPU && TARGET_HARD_QUAD"
6901 [(set_attr "type" "fpsqrtd")])
6903 (define_insn "sqrtdf2"
6904 [(set (match_operand:DF 0 "register_operand" "=e")
6905 (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
6908 [(set_attr "type" "fpsqrtd")
6909 (set_attr "fptype" "double")])
6911 (define_insn "sqrtsf2"
6912 [(set (match_operand:SF 0 "register_operand" "=f")
6913 (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
6916 [(set_attr "type" "fpsqrts")])
6918 ;;- arithmetic shift instructions
6920 (define_insn "ashlsi3"
6921 [(set (match_operand:SI 0 "register_operand" "=r")
6922 (ashift:SI (match_operand:SI 1 "register_operand" "r")
6923 (match_operand:SI 2 "arith_operand" "rI")))]
6926 if (GET_CODE (operands[2]) == CONST_INT)
6927 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6928 return "sll\t%1, %2, %0";
6931 (if_then_else (match_operand 2 "const_one_operand" "")
6932 (const_string "ialu") (const_string "shift")))])
6934 (define_expand "ashldi3"
6935 [(set (match_operand:DI 0 "register_operand" "=r")
6936 (ashift:DI (match_operand:DI 1 "register_operand" "r")
6937 (match_operand:SI 2 "arith_operand" "rI")))]
6938 "TARGET_ARCH64 || TARGET_V8PLUS"
6940 if (! TARGET_ARCH64)
6942 if (GET_CODE (operands[2]) == CONST_INT)
6944 emit_insn (gen_ashldi3_v8plus (operands[0], operands[1], operands[2]));
6949 (define_insn "*ashldi3_sp64"
6950 [(set (match_operand:DI 0 "register_operand" "=r")
6951 (ashift:DI (match_operand:DI 1 "register_operand" "r")
6952 (match_operand:SI 2 "arith_operand" "rI")))]
6955 if (GET_CODE (operands[2]) == CONST_INT)
6956 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
6957 return "sllx\t%1, %2, %0";
6960 (if_then_else (match_operand 2 "const_one_operand" "")
6961 (const_string "ialu") (const_string "shift")))])
6964 (define_insn "ashldi3_v8plus"
6965 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
6966 (ashift:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
6967 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
6968 (clobber (match_scratch:SI 3 "=X,X,&h"))]
6970 "* return output_v8plus_shift (operands, insn, \"sllx\");"
6971 [(set_attr "type" "multi")
6972 (set_attr "length" "5,5,6")])
6974 ;; Optimize (1LL<<x)-1
6975 ;; XXX this also needs to be fixed to handle equal subregs
6976 ;; XXX first before we could re-enable it.
6978 ; [(set (match_operand:DI 0 "register_operand" "=h")
6979 ; (plus:DI (ashift:DI (const_int 1)
6980 ; (match_operand:SI 1 "arith_operand" "rI"))
6982 ; "0 && TARGET_V8PLUS"
6984 ; if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == REGNO (operands[0]))
6985 ; return "mov\t1, %L0\;sllx\t%L0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
6986 ; return "mov\t1, %H0\;sllx\t%H0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
6988 ; [(set_attr "type" "multi")
6989 ; (set_attr "length" "4")])
6991 (define_insn "*cmp_cc_ashift_1"
6992 [(set (reg:CC_NOOV 100)
6993 (compare:CC_NOOV (ashift:SI (match_operand:SI 0 "register_operand" "r")
6997 "addcc\t%0, %0, %%g0"
6998 [(set_attr "type" "compare")])
7000 (define_insn "*cmp_cc_set_ashift_1"
7001 [(set (reg:CC_NOOV 100)
7002 (compare:CC_NOOV (ashift:SI (match_operand:SI 1 "register_operand" "r")
7005 (set (match_operand:SI 0 "register_operand" "=r")
7006 (ashift:SI (match_dup 1) (const_int 1)))]
7009 [(set_attr "type" "compare")])
7011 (define_insn "ashrsi3"
7012 [(set (match_operand:SI 0 "register_operand" "=r")
7013 (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
7014 (match_operand:SI 2 "arith_operand" "rI")))]
7017 if (GET_CODE (operands[2]) == CONST_INT)
7018 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
7019 return "sra\t%1, %2, %0";
7021 [(set_attr "type" "shift")])
7023 (define_insn "*ashrsi3_extend"
7024 [(set (match_operand:DI 0 "register_operand" "=r")
7025 (sign_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
7026 (match_operand:SI 2 "arith_operand" "r"))))]
7029 [(set_attr "type" "shift")])
7031 ;; This handles the case as above, but with constant shift instead of
7032 ;; register. Combiner "simplifies" it for us a little bit though.
7033 (define_insn "*ashrsi3_extend2"
7034 [(set (match_operand:DI 0 "register_operand" "=r")
7035 (ashiftrt:DI (ashift:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
7037 (match_operand:SI 2 "small_int_operand" "I")))]
7038 "TARGET_ARCH64 && INTVAL (operands[2]) >= 32 && INTVAL (operands[2]) < 64"
7040 operands[2] = GEN_INT (INTVAL (operands[2]) - 32);
7041 return "sra\t%1, %2, %0";
7043 [(set_attr "type" "shift")])
7045 (define_expand "ashrdi3"
7046 [(set (match_operand:DI 0 "register_operand" "=r")
7047 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
7048 (match_operand:SI 2 "arith_operand" "rI")))]
7049 "TARGET_ARCH64 || TARGET_V8PLUS"
7051 if (! TARGET_ARCH64)
7053 if (GET_CODE (operands[2]) == CONST_INT)
7054 FAIL; /* prefer generic code in this case */
7055 emit_insn (gen_ashrdi3_v8plus (operands[0], operands[1], operands[2]));
7060 (define_insn "*ashrdi3_sp64"
7061 [(set (match_operand:DI 0 "register_operand" "=r")
7062 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
7063 (match_operand:SI 2 "arith_operand" "rI")))]
7067 if (GET_CODE (operands[2]) == CONST_INT)
7068 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
7069 return "srax\t%1, %2, %0";
7071 [(set_attr "type" "shift")])
7074 (define_insn "ashrdi3_v8plus"
7075 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
7076 (ashiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
7077 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
7078 (clobber (match_scratch:SI 3 "=X,X,&h"))]
7080 "* return output_v8plus_shift (operands, insn, \"srax\");"
7081 [(set_attr "type" "multi")
7082 (set_attr "length" "5,5,6")])
7084 (define_insn "lshrsi3"
7085 [(set (match_operand:SI 0 "register_operand" "=r")
7086 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
7087 (match_operand:SI 2 "arith_operand" "rI")))]
7090 if (GET_CODE (operands[2]) == CONST_INT)
7091 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
7092 return "srl\t%1, %2, %0";
7094 [(set_attr "type" "shift")])
7096 ;; This handles the case where
7097 ;; (zero_extend:DI (lshiftrt:SI (match_operand:SI) (match_operand:SI))),
7098 ;; but combiner "simplifies" it for us.
7099 (define_insn "*lshrsi3_extend"
7100 [(set (match_operand:DI 0 "register_operand" "=r")
7101 (and:DI (subreg:DI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
7102 (match_operand:SI 2 "arith_operand" "r")) 0)
7103 (match_operand 3 "" "")))]
7105 && ((GET_CODE (operands[3]) == CONST_DOUBLE
7106 && CONST_DOUBLE_HIGH (operands[3]) == 0
7107 && CONST_DOUBLE_LOW (operands[3]) == 0xffffffff)
7108 || (HOST_BITS_PER_WIDE_INT >= 64
7109 && GET_CODE (operands[3]) == CONST_INT
7110 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) == 0xffffffff))"
7112 [(set_attr "type" "shift")])
7114 ;; This handles the case where
7115 ;; (lshiftrt:DI (zero_extend:DI (match_operand:SI)) (const_int >=0 < 32))
7116 ;; but combiner "simplifies" it for us.
7117 (define_insn "*lshrsi3_extend2"
7118 [(set (match_operand:DI 0 "register_operand" "=r")
7119 (zero_extract:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
7120 (match_operand 2 "small_int_operand" "I")
7122 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
7124 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
7125 return "srl\t%1, %2, %0";
7127 [(set_attr "type" "shift")])
7129 (define_expand "lshrdi3"
7130 [(set (match_operand:DI 0 "register_operand" "=r")
7131 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
7132 (match_operand:SI 2 "arith_operand" "rI")))]
7133 "TARGET_ARCH64 || TARGET_V8PLUS"
7135 if (! TARGET_ARCH64)
7137 if (GET_CODE (operands[2]) == CONST_INT)
7139 emit_insn (gen_lshrdi3_v8plus (operands[0], operands[1], operands[2]));
7144 (define_insn "*lshrdi3_sp64"
7145 [(set (match_operand:DI 0 "register_operand" "=r")
7146 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
7147 (match_operand:SI 2 "arith_operand" "rI")))]
7150 if (GET_CODE (operands[2]) == CONST_INT)
7151 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
7152 return "srlx\t%1, %2, %0";
7154 [(set_attr "type" "shift")])
7157 (define_insn "lshrdi3_v8plus"
7158 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
7159 (lshiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
7160 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
7161 (clobber (match_scratch:SI 3 "=X,X,&h"))]
7163 "* return output_v8plus_shift (operands, insn, \"srlx\");"
7164 [(set_attr "type" "multi")
7165 (set_attr "length" "5,5,6")])
7168 [(set (match_operand:SI 0 "register_operand" "=r")
7169 (ashiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
7171 (match_operand:SI 2 "small_int_operand" "I")))]
7172 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
7174 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
7175 return "srax\t%1, %2, %0";
7177 [(set_attr "type" "shift")])
7180 [(set (match_operand:SI 0 "register_operand" "=r")
7181 (lshiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
7183 (match_operand:SI 2 "small_int_operand" "I")))]
7184 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
7186 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
7187 return "srlx\t%1, %2, %0";
7189 [(set_attr "type" "shift")])
7192 [(set (match_operand:SI 0 "register_operand" "=r")
7193 (ashiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
7194 (match_operand:SI 2 "small_int_operand" "I")) 4)
7195 (match_operand:SI 3 "small_int_operand" "I")))]
7197 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
7198 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
7199 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
7201 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
7203 return "srax\t%1, %2, %0";
7205 [(set_attr "type" "shift")])
7208 [(set (match_operand:SI 0 "register_operand" "=r")
7209 (lshiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
7210 (match_operand:SI 2 "small_int_operand" "I")) 4)
7211 (match_operand:SI 3 "small_int_operand" "I")))]
7213 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
7214 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
7215 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
7217 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
7219 return "srlx\t%1, %2, %0";
7221 [(set_attr "type" "shift")])
7223 ;; Unconditional and other jump instructions
7225 [(set (pc) (label_ref (match_operand 0 "" "")))]
7227 "* return output_ubranch (operands[0], 0, insn);"
7228 [(set_attr "type" "uncond_branch")])
7230 (define_expand "tablejump"
7231 [(parallel [(set (pc) (match_operand 0 "register_operand" "r"))
7232 (use (label_ref (match_operand 1 "" "")))])]
7235 gcc_assert (GET_MODE (operands[0]) == CASE_VECTOR_MODE);
7237 /* In pic mode, our address differences are against the base of the
7238 table. Add that base value back in; CSE ought to be able to combine
7239 the two address loads. */
7243 tmp = gen_rtx_LABEL_REF (Pmode, operands[1]);
7245 if (CASE_VECTOR_MODE != Pmode)
7246 tmp2 = gen_rtx_SIGN_EXTEND (Pmode, tmp2);
7247 tmp = gen_rtx_PLUS (Pmode, tmp2, tmp);
7248 operands[0] = memory_address (Pmode, tmp);
7252 (define_insn "*tablejump_sp32"
7253 [(set (pc) (match_operand:SI 0 "address_operand" "p"))
7254 (use (label_ref (match_operand 1 "" "")))]
7257 [(set_attr "type" "uncond_branch")])
7259 (define_insn "*tablejump_sp64"
7260 [(set (pc) (match_operand:DI 0 "address_operand" "p"))
7261 (use (label_ref (match_operand 1 "" "")))]
7264 [(set_attr "type" "uncond_branch")])
7266 ;;- jump to subroutine
7267 (define_expand "call"
7268 ;; Note that this expression is not used for generating RTL.
7269 ;; All the RTL is generated explicitly below.
7270 [(call (match_operand 0 "call_operand" "")
7271 (match_operand 3 "" "i"))]
7272 ;; operands[2] is next_arg_register
7273 ;; operands[3] is struct_value_size_rtx.
7278 gcc_assert (GET_MODE (operands[0]) == FUNCTION_MODE);
7280 gcc_assert (GET_CODE (operands[3]) == CONST_INT);
7282 if (GET_CODE (XEXP (operands[0], 0)) == LABEL_REF)
7284 /* This is really a PIC sequence. We want to represent
7285 it as a funny jump so its delay slots can be filled.
7287 ??? But if this really *is* a CALL, will not it clobber the
7288 call-clobbered registers? We lose this if it is a JUMP_INSN.
7289 Why cannot we have delay slots filled if it were a CALL? */
7291 /* We accept negative sizes for untyped calls. */
7292 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
7297 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
7299 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
7305 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
7306 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
7310 fn_rtx = operands[0];
7312 /* We accept negative sizes for untyped calls. */
7313 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
7317 gen_rtvec (3, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx),
7319 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
7324 gen_rtvec (2, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx),
7325 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
7332 ;; We can't use the same pattern for these two insns, because then registers
7333 ;; in the address may not be properly reloaded.
7335 (define_insn "*call_address_sp32"
7336 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
7337 (match_operand 1 "" ""))
7338 (clobber (reg:SI 15))]
7339 ;;- Do not use operand 1 for most machines.
7342 [(set_attr "type" "call")])
7344 (define_insn "*call_symbolic_sp32"
7345 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
7346 (match_operand 1 "" ""))
7347 (clobber (reg:SI 15))]
7348 ;;- Do not use operand 1 for most machines.
7351 [(set_attr "type" "call")])
7353 (define_insn "*call_address_sp64"
7354 [(call (mem:DI (match_operand:DI 0 "address_operand" "p"))
7355 (match_operand 1 "" ""))
7356 (clobber (reg:DI 15))]
7357 ;;- Do not use operand 1 for most machines.
7360 [(set_attr "type" "call")])
7362 (define_insn "*call_symbolic_sp64"
7363 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
7364 (match_operand 1 "" ""))
7365 (clobber (reg:DI 15))]
7366 ;;- Do not use operand 1 for most machines.
7369 [(set_attr "type" "call")])
7371 ;; This is a call that wants a structure value.
7372 ;; There is no such critter for v9 (??? we may need one anyway).
7373 (define_insn "*call_address_struct_value_sp32"
7374 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
7375 (match_operand 1 "" ""))
7376 (match_operand 2 "immediate_operand" "")
7377 (clobber (reg:SI 15))]
7378 ;;- Do not use operand 1 for most machines.
7379 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
7381 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xfff);
7382 return "call\t%a0, %1\n\t nop\n\tunimp\t%2";
7384 [(set_attr "type" "call_no_delay_slot")
7385 (set_attr "length" "3")])
7387 ;; This is a call that wants a structure value.
7388 ;; There is no such critter for v9 (??? we may need one anyway).
7389 (define_insn "*call_symbolic_struct_value_sp32"
7390 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
7391 (match_operand 1 "" ""))
7392 (match_operand 2 "immediate_operand" "")
7393 (clobber (reg:SI 15))]
7394 ;;- Do not use operand 1 for most machines.
7395 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
7397 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xfff);
7398 return "call\t%a0, %1\n\t nop\n\tunimp\t%2";
7400 [(set_attr "type" "call_no_delay_slot")
7401 (set_attr "length" "3")])
7403 ;; This is a call that may want a structure value. This is used for
7405 (define_insn "*call_address_untyped_struct_value_sp32"
7406 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
7407 (match_operand 1 "" ""))
7408 (match_operand 2 "immediate_operand" "")
7409 (clobber (reg:SI 15))]
7410 ;;- Do not use operand 1 for most machines.
7411 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
7412 "call\t%a0, %1\n\t nop\n\tnop"
7413 [(set_attr "type" "call_no_delay_slot")
7414 (set_attr "length" "3")])
7416 ;; This is a call that may want a structure value. This is used for
7418 (define_insn "*call_symbolic_untyped_struct_value_sp32"
7419 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
7420 (match_operand 1 "" ""))
7421 (match_operand 2 "immediate_operand" "")
7422 (clobber (reg:SI 15))]
7423 ;;- Do not use operand 1 for most machines.
7424 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
7425 "call\t%a0, %1\n\t nop\n\tnop"
7426 [(set_attr "type" "call_no_delay_slot")
7427 (set_attr "length" "3")])
7429 (define_expand "call_value"
7430 ;; Note that this expression is not used for generating RTL.
7431 ;; All the RTL is generated explicitly below.
7432 [(set (match_operand 0 "register_operand" "=rf")
7433 (call (match_operand 1 "" "")
7434 (match_operand 4 "" "")))]
7435 ;; operand 2 is stack_size_rtx
7436 ;; operand 3 is next_arg_register
7442 gcc_assert (GET_MODE (operands[1]) == FUNCTION_MODE);
7444 fn_rtx = operands[1];
7447 gen_rtx_SET (VOIDmode, operands[0],
7448 gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx)),
7449 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)));
7451 emit_call_insn (gen_rtx_PARALLEL (VOIDmode, vec));
7456 (define_insn "*call_value_address_sp32"
7457 [(set (match_operand 0 "" "=rf")
7458 (call (mem:SI (match_operand:SI 1 "address_operand" "p"))
7459 (match_operand 2 "" "")))
7460 (clobber (reg:SI 15))]
7461 ;;- Do not use operand 2 for most machines.
7464 [(set_attr "type" "call")])
7466 (define_insn "*call_value_symbolic_sp32"
7467 [(set (match_operand 0 "" "=rf")
7468 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
7469 (match_operand 2 "" "")))
7470 (clobber (reg:SI 15))]
7471 ;;- Do not use operand 2 for most machines.
7474 [(set_attr "type" "call")])
7476 (define_insn "*call_value_address_sp64"
7477 [(set (match_operand 0 "" "")
7478 (call (mem:DI (match_operand:DI 1 "address_operand" "p"))
7479 (match_operand 2 "" "")))
7480 (clobber (reg:DI 15))]
7481 ;;- Do not use operand 2 for most machines.
7484 [(set_attr "type" "call")])
7486 (define_insn "*call_value_symbolic_sp64"
7487 [(set (match_operand 0 "" "")
7488 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
7489 (match_operand 2 "" "")))
7490 (clobber (reg:DI 15))]
7491 ;;- Do not use operand 2 for most machines.
7494 [(set_attr "type" "call")])
7496 (define_expand "untyped_call"
7497 [(parallel [(call (match_operand 0 "" "")
7499 (match_operand:BLK 1 "memory_operand" "")
7500 (match_operand 2 "" "")])]
7503 rtx valreg1 = gen_rtx_REG (DImode, 8);
7504 rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
7505 rtx result = operands[1];
7507 /* Pass constm1 to indicate that it may expect a structure value, but
7508 we don't know what size it is. */
7509 emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, constm1_rtx));
7511 /* Save the function value registers. */
7512 emit_move_insn (adjust_address (result, DImode, 0), valreg1);
7513 emit_move_insn (adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8),
7516 /* The optimizer does not know that the call sets the function value
7517 registers we stored in the result block. We avoid problems by
7518 claiming that all hard registers are used and clobbered at this
7520 emit_insn (gen_blockage ());
7526 (define_expand "sibcall"
7527 [(parallel [(call (match_operand 0 "call_operand" "") (const_int 0))
7532 (define_insn "*sibcall_symbolic_sp32"
7533 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
7534 (match_operand 1 "" ""))
7537 "* return output_sibcall(insn, operands[0]);"
7538 [(set_attr "type" "sibcall")])
7540 (define_insn "*sibcall_symbolic_sp64"
7541 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
7542 (match_operand 1 "" ""))
7545 "* return output_sibcall(insn, operands[0]);"
7546 [(set_attr "type" "sibcall")])
7548 (define_expand "sibcall_value"
7549 [(parallel [(set (match_operand 0 "register_operand" "=rf")
7550 (call (match_operand 1 "" "") (const_int 0)))
7555 (define_insn "*sibcall_value_symbolic_sp32"
7556 [(set (match_operand 0 "" "=rf")
7557 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
7558 (match_operand 2 "" "")))
7561 "* return output_sibcall(insn, operands[1]);"
7562 [(set_attr "type" "sibcall")])
7564 (define_insn "*sibcall_value_symbolic_sp64"
7565 [(set (match_operand 0 "" "")
7566 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
7567 (match_operand 2 "" "")))
7570 "* return output_sibcall(insn, operands[1]);"
7571 [(set_attr "type" "sibcall")])
7573 (define_expand "sibcall_epilogue"
7577 sparc_expand_epilogue ();
7581 (define_expand "prologue"
7585 sparc_expand_prologue ();
7589 ;; The "save register window" insn is modelled as follows so that the DWARF-2
7590 ;; backend automatically emits the required call frame debugging information
7591 ;; while it is parsing it. Therefore, the pattern should not be modified
7592 ;; without first studying the impact of the changes on the debug info.
7593 ;; [(set (%fp) (%sp))
7594 ;; (set (%sp) (unspec_volatile [(%sp) (-frame_size)] UNSPECV_SAVEW))
7595 ;; (set (%i7) (%o7))]
7597 (define_insn "save_register_window<P:mode>"
7598 [(set (reg:P 30) (reg:P 14))
7599 (set (reg:P 14) (unspec_volatile:P [(reg:P 14)
7600 (match_operand:P 0 "arith_operand" "rI")] UNSPECV_SAVEW))
7601 (set (reg:P 31) (reg:P 15))]
7603 "save\t%%sp, %0, %%sp"
7604 [(set_attr "type" "savew")])
7606 (define_expand "epilogue"
7610 sparc_expand_epilogue ();
7613 (define_expand "return"
7615 "sparc_can_use_return_insn_p ()"
7618 (define_insn "*return_internal"
7621 "* return output_return (insn);"
7622 [(set_attr "type" "return")
7623 (set (attr "length")
7624 (cond [(eq_attr "leaf_function" "true")
7625 (if_then_else (eq_attr "empty_delay_slot" "true")
7628 (eq_attr "calls_eh_return" "true")
7629 (if_then_else (eq_attr "delayed_branch" "true")
7630 (if_then_else (eq_attr "isa" "v9")
7633 (if_then_else (eq_attr "isa" "v9")
7636 (eq_attr "empty_delay_slot" "true")
7637 (if_then_else (eq_attr "delayed_branch" "true")
7642 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
7643 ;; all of memory. This blocks insns from being moved across this point.
7645 (define_insn "blockage"
7646 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
7649 [(set_attr "length" "0")])
7651 ;; Prepare to return any type including a structure value.
7653 (define_expand "untyped_return"
7654 [(match_operand:BLK 0 "memory_operand" "")
7655 (match_operand 1 "" "")]
7658 rtx valreg1 = gen_rtx_REG (DImode, 24);
7659 rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
7660 rtx result = operands[0];
7662 if (! TARGET_ARCH64)
7664 rtx rtnreg = gen_rtx_REG (SImode, (current_function_uses_only_leaf_regs
7666 rtx value = gen_reg_rtx (SImode);
7668 /* Fetch the instruction where we will return to and see if it's an unimp
7669 instruction (the most significant 10 bits will be zero). If so,
7670 update the return address to skip the unimp instruction. */
7671 emit_move_insn (value,
7672 gen_rtx_MEM (SImode, plus_constant (rtnreg, 8)));
7673 emit_insn (gen_lshrsi3 (value, value, GEN_INT (22)));
7674 emit_insn (gen_update_return (rtnreg, value));
7677 /* Reload the function value registers. */
7678 emit_move_insn (valreg1, adjust_address (result, DImode, 0));
7679 emit_move_insn (valreg2,
7680 adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8));
7682 /* Put USE insns before the return. */
7683 emit_insn (gen_rtx_USE (VOIDmode, valreg1));
7684 emit_insn (gen_rtx_USE (VOIDmode, valreg2));
7686 /* Construct the return. */
7687 expand_naked_return ();
7692 ;; This is a bit of a hack. We're incrementing a fixed register (%i7),
7693 ;; and parts of the compiler don't want to believe that the add is needed.
7695 (define_insn "update_return"
7696 [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
7697 (match_operand:SI 1 "register_operand" "r")] UNSPEC_UPDATE_RETURN)]
7700 if (flag_delayed_branch)
7701 return "cmp\t%1, 0\n\tbe,a\t.+8\n\t add\t%0, 4, %0";
7703 return "cmp\t%1, 0\n\tbne\t.+12\n\t nop\n\tadd\t%0, 4, %0";
7705 [(set (attr "type") (const_string "multi"))
7706 (set (attr "length")
7707 (if_then_else (eq_attr "delayed_branch" "true")
7716 (define_expand "indirect_jump"
7717 [(set (pc) (match_operand 0 "address_operand" "p"))]
7721 (define_insn "*branch_sp32"
7722 [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
7725 [(set_attr "type" "uncond_branch")])
7727 (define_insn "*branch_sp64"
7728 [(set (pc) (match_operand:DI 0 "address_operand" "p"))]
7731 [(set_attr "type" "uncond_branch")])
7733 (define_expand "nonlocal_goto"
7734 [(match_operand:SI 0 "general_operand" "")
7735 (match_operand:SI 1 "general_operand" "")
7736 (match_operand:SI 2 "general_operand" "")
7737 (match_operand:SI 3 "" "")]
7740 rtx lab = operands[1];
7741 rtx stack = operands[2];
7742 rtx fp = operands[3];
7745 /* Trap instruction to flush all the register windows. */
7746 emit_insn (gen_flush_register_windows ());
7748 /* Load the fp value for the containing fn into %fp. This is needed
7749 because STACK refers to %fp. Note that virtual register instantiation
7750 fails if the virtual %fp isn't set from a register. */
7751 if (GET_CODE (fp) != REG)
7752 fp = force_reg (Pmode, fp);
7753 emit_move_insn (virtual_stack_vars_rtx, fp);
7755 /* Find the containing function's current nonlocal goto handler,
7756 which will do any cleanups and then jump to the label. */
7757 labreg = gen_rtx_REG (Pmode, 8);
7758 emit_move_insn (labreg, lab);
7760 /* Restore %fp from stack pointer value for containing function.
7761 The restore insn that follows will move this to %sp,
7762 and reload the appropriate value into %fp. */
7763 emit_move_insn (hard_frame_pointer_rtx, stack);
7765 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
7766 emit_insn (gen_rtx_USE (VOIDmode, static_chain_rtx));
7768 /* ??? The V9-specific version was disabled in rev 1.65. */
7769 emit_jump_insn (gen_goto_handler_and_restore (labreg));
7774 ;; Special trap insn to flush register windows.
7775 (define_insn "flush_register_windows"
7776 [(unspec_volatile [(const_int 0)] UNSPECV_FLUSHW)]
7778 { return TARGET_V9 ? "flushw" : "ta\t3"; }
7779 [(set_attr "type" "flushw")])
7781 (define_insn "goto_handler_and_restore"
7782 [(unspec_volatile [(match_operand 0 "register_operand" "=r")] UNSPECV_GOTO)]
7783 "GET_MODE (operands[0]) == Pmode"
7785 if (flag_delayed_branch)
7786 return "jmp\t%0\n\t restore";
7788 return "mov\t%0,%%g1\n\trestore\n\tjmp\t%%g1\n\t nop";
7790 [(set (attr "type") (const_string "multi"))
7791 (set (attr "length")
7792 (if_then_else (eq_attr "delayed_branch" "true")
7796 ;; For __builtin_setjmp we need to flush register windows iff the function
7797 ;; calls alloca as well, because otherwise the register window might be
7798 ;; saved after %sp adjustment and thus setjmp would crash
7799 (define_expand "builtin_setjmp_setup"
7800 [(match_operand 0 "register_operand" "r")]
7803 emit_insn (gen_do_builtin_setjmp_setup ());
7807 (define_insn "do_builtin_setjmp_setup"
7808 [(unspec_volatile [(const_int 0)] UNSPECV_SETJMP)]
7811 if (! current_function_calls_alloca)
7815 fputs ("\tflushw\n", asm_out_file);
7817 fprintf (asm_out_file, "\tst%c\t%%l7, [%%sp+%d]\n",
7818 TARGET_ARCH64 ? 'x' : 'w',
7819 SPARC_STACK_BIAS + 7 * UNITS_PER_WORD);
7820 fprintf (asm_out_file, "\tst%c\t%%fp, [%%sp+%d]\n",
7821 TARGET_ARCH64 ? 'x' : 'w',
7822 SPARC_STACK_BIAS + 14 * UNITS_PER_WORD);
7823 fprintf (asm_out_file, "\tst%c\t%%i7, [%%sp+%d]\n",
7824 TARGET_ARCH64 ? 'x' : 'w',
7825 SPARC_STACK_BIAS + 15 * UNITS_PER_WORD);
7828 [(set_attr "type" "multi")
7829 (set (attr "length")
7830 (cond [(eq_attr "calls_alloca" "false")
7832 (eq_attr "isa" "!v9")
7834 (eq_attr "pic" "true")
7835 (const_int 4)] (const_int 3)))])
7837 ;; Pattern for use after a setjmp to store FP and the return register
7838 ;; into the stack area.
7840 (define_expand "setjmp"
7845 emit_insn (gen_setjmp_64 ());
7847 emit_insn (gen_setjmp_32 ());
7851 (define_expand "setjmp_32"
7852 [(set (mem:SI (plus:SI (reg:SI 14) (const_int 56))) (match_dup 0))
7853 (set (mem:SI (plus:SI (reg:SI 14) (const_int 60))) (reg:SI 31))]
7855 { operands[0] = frame_pointer_rtx; })
7857 (define_expand "setjmp_64"
7858 [(set (mem:DI (plus:DI (reg:DI 14) (const_int 112))) (match_dup 0))
7859 (set (mem:DI (plus:DI (reg:DI 14) (const_int 120))) (reg:DI 31))]
7861 { operands[0] = frame_pointer_rtx; })
7863 ;; Special pattern for the FLUSH instruction.
7865 ; We do SImode and DImode versions of this to quiet down genrecog's complaints
7866 ; of the define_insn otherwise missing a mode. We make "flush", aka
7867 ; gen_flush, the default one since sparc_initialize_trampoline uses
7868 ; it on SImode mem values.
7870 (define_insn "flush"
7871 [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")] UNSPECV_FLUSH)]
7873 { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; }
7874 [(set_attr "type" "iflush")])
7876 (define_insn "flushdi"
7877 [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")] UNSPECV_FLUSH)]
7879 { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; }
7880 [(set_attr "type" "iflush")])
7885 ;; The scan instruction searches from the most significant bit while ffs
7886 ;; searches from the least significant bit. The bit index and treatment of
7887 ;; zero also differ. It takes at least 7 instructions to get the proper
7888 ;; result. Here is an obvious 8 instruction sequence.
7891 (define_insn "ffssi2"
7892 [(set (match_operand:SI 0 "register_operand" "=&r")
7893 (ffs:SI (match_operand:SI 1 "register_operand" "r")))
7894 (clobber (match_scratch:SI 2 "=&r"))]
7895 "TARGET_SPARCLITE || TARGET_SPARCLET"
7897 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";
7899 [(set_attr "type" "multi")
7900 (set_attr "length" "8")])
7902 ;; ??? This should be a define expand, so that the extra instruction have
7903 ;; a chance of being optimized away.
7905 ;; Disabled because none of the UltraSPARCs implement popc. The HAL R1
7906 ;; does, but no one uses that and we don't have a switch for it.
7908 ;(define_insn "ffsdi2"
7909 ; [(set (match_operand:DI 0 "register_operand" "=&r")
7910 ; (ffs:DI (match_operand:DI 1 "register_operand" "r")))
7911 ; (clobber (match_scratch:DI 2 "=&r"))]
7913 ; "neg\t%1, %2\;xnor\t%1, %2, %2\;popc\t%2, %0\;movzr\t%1, 0, %0"
7914 ; [(set_attr "type" "multi")
7915 ; (set_attr "length" "4")])
7919 ;; Peepholes go at the end.
7921 ;; Optimize consecutive loads or stores into ldd and std when possible.
7922 ;; The conditions in which we do this are very restricted and are
7923 ;; explained in the code for {registers,memory}_ok_for_ldd functions.
7926 [(set (match_operand:SI 0 "memory_operand" "")
7928 (set (match_operand:SI 1 "memory_operand" "")
7931 && mems_ok_for_ldd_peep (operands[0], operands[1], NULL_RTX)"
7934 "operands[0] = widen_memory_access (operands[0], DImode, 0);")
7937 [(set (match_operand:SI 0 "memory_operand" "")
7939 (set (match_operand:SI 1 "memory_operand" "")
7942 && mems_ok_for_ldd_peep (operands[1], operands[0], NULL_RTX)"
7945 "operands[1] = widen_memory_access (operands[1], DImode, 0);")
7948 [(set (match_operand:SI 0 "register_operand" "")
7949 (match_operand:SI 1 "memory_operand" ""))
7950 (set (match_operand:SI 2 "register_operand" "")
7951 (match_operand:SI 3 "memory_operand" ""))]
7952 "registers_ok_for_ldd_peep (operands[0], operands[2])
7953 && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
7956 "operands[1] = widen_memory_access (operands[1], DImode, 0);
7957 operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));")
7960 [(set (match_operand:SI 0 "memory_operand" "")
7961 (match_operand:SI 1 "register_operand" ""))
7962 (set (match_operand:SI 2 "memory_operand" "")
7963 (match_operand:SI 3 "register_operand" ""))]
7964 "registers_ok_for_ldd_peep (operands[1], operands[3])
7965 && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
7968 "operands[0] = widen_memory_access (operands[0], DImode, 0);
7969 operands[1] = gen_rtx_REG (DImode, REGNO (operands[1]));")
7972 [(set (match_operand:SF 0 "register_operand" "")
7973 (match_operand:SF 1 "memory_operand" ""))
7974 (set (match_operand:SF 2 "register_operand" "")
7975 (match_operand:SF 3 "memory_operand" ""))]
7976 "registers_ok_for_ldd_peep (operands[0], operands[2])
7977 && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
7980 "operands[1] = widen_memory_access (operands[1], DFmode, 0);
7981 operands[0] = gen_rtx_REG (DFmode, REGNO (operands[0]));")
7984 [(set (match_operand:SF 0 "memory_operand" "")
7985 (match_operand:SF 1 "register_operand" ""))
7986 (set (match_operand:SF 2 "memory_operand" "")
7987 (match_operand:SF 3 "register_operand" ""))]
7988 "registers_ok_for_ldd_peep (operands[1], operands[3])
7989 && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
7992 "operands[0] = widen_memory_access (operands[0], DFmode, 0);
7993 operands[1] = gen_rtx_REG (DFmode, REGNO (operands[1]));")
7996 [(set (match_operand:SI 0 "register_operand" "")
7997 (match_operand:SI 1 "memory_operand" ""))
7998 (set (match_operand:SI 2 "register_operand" "")
7999 (match_operand:SI 3 "memory_operand" ""))]
8000 "registers_ok_for_ldd_peep (operands[2], operands[0])
8001 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
8004 "operands[3] = widen_memory_access (operands[3], DImode, 0);
8005 operands[2] = gen_rtx_REG (DImode, REGNO (operands[2]));")
8008 [(set (match_operand:SI 0 "memory_operand" "")
8009 (match_operand:SI 1 "register_operand" ""))
8010 (set (match_operand:SI 2 "memory_operand" "")
8011 (match_operand:SI 3 "register_operand" ""))]
8012 "registers_ok_for_ldd_peep (operands[3], operands[1])
8013 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
8016 "operands[2] = widen_memory_access (operands[2], DImode, 0);
8017 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
8021 [(set (match_operand:SF 0 "register_operand" "")
8022 (match_operand:SF 1 "memory_operand" ""))
8023 (set (match_operand:SF 2 "register_operand" "")
8024 (match_operand:SF 3 "memory_operand" ""))]
8025 "registers_ok_for_ldd_peep (operands[2], operands[0])
8026 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
8029 "operands[3] = widen_memory_access (operands[3], DFmode, 0);
8030 operands[2] = gen_rtx_REG (DFmode, REGNO (operands[2]));")
8033 [(set (match_operand:SF 0 "memory_operand" "")
8034 (match_operand:SF 1 "register_operand" ""))
8035 (set (match_operand:SF 2 "memory_operand" "")
8036 (match_operand:SF 3 "register_operand" ""))]
8037 "registers_ok_for_ldd_peep (operands[3], operands[1])
8038 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
8041 "operands[2] = widen_memory_access (operands[2], DFmode, 0);
8042 operands[3] = gen_rtx_REG (DFmode, REGNO (operands[3]));")
8044 ;; Optimize the case of following a reg-reg move with a test
8045 ;; of reg just moved. Don't allow floating point regs for operand 0 or 1.
8046 ;; This can result from a float to fix conversion.
8049 [(set (match_operand:SI 0 "register_operand" "")
8050 (match_operand:SI 1 "register_operand" ""))
8052 (compare:CC (match_operand:SI 2 "register_operand" "")
8054 "(rtx_equal_p (operands[2], operands[0])
8055 || rtx_equal_p (operands[2], operands[1]))
8056 && ! SPARC_FP_REG_P (REGNO (operands[0]))
8057 && ! SPARC_FP_REG_P (REGNO (operands[1]))"
8058 [(parallel [(set (match_dup 0) (match_dup 1))
8060 (compare:CC (match_dup 1) (const_int 0)))])]
8064 [(set (match_operand:DI 0 "register_operand" "")
8065 (match_operand:DI 1 "register_operand" ""))
8067 (compare:CCX (match_operand:DI 2 "register_operand" "")
8070 && (rtx_equal_p (operands[2], operands[0])
8071 || rtx_equal_p (operands[2], operands[1]))
8072 && ! SPARC_FP_REG_P (REGNO (operands[0]))
8073 && ! SPARC_FP_REG_P (REGNO (operands[1]))"
8074 [(parallel [(set (match_dup 0) (match_dup 1))
8076 (compare:CCX (match_dup 1) (const_int 0)))])]
8079 ;; ??? UltraSPARC-III note: A memory operation loading into the floating point register
8080 ;; ??? file, if it hits the prefetch cache, has a chance to dual-issue with other memory
8081 ;; ??? operations. With DFA we might be able to model this, but it requires a lot of
8083 (define_expand "prefetch"
8084 [(match_operand 0 "address_operand" "")
8085 (match_operand 1 "const_int_operand" "")
8086 (match_operand 2 "const_int_operand" "")]
8090 emit_insn (gen_prefetch_64 (operands[0], operands[1], operands[2]));
8092 emit_insn (gen_prefetch_32 (operands[0], operands[1], operands[2]));
8096 (define_insn "prefetch_64"
8097 [(prefetch (match_operand:DI 0 "address_operand" "p")
8098 (match_operand:DI 1 "const_int_operand" "n")
8099 (match_operand:DI 2 "const_int_operand" "n"))]
8102 static const char * const prefetch_instr[2][2] = {
8104 "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
8105 "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
8108 "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
8109 "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
8112 int read_or_write = INTVAL (operands[1]);
8113 int locality = INTVAL (operands[2]);
8115 gcc_assert (read_or_write == 0 || read_or_write == 1);
8116 gcc_assert (locality >= 0 && locality < 4);
8117 return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
8119 [(set_attr "type" "load")])
8121 (define_insn "prefetch_32"
8122 [(prefetch (match_operand:SI 0 "address_operand" "p")
8123 (match_operand:SI 1 "const_int_operand" "n")
8124 (match_operand:SI 2 "const_int_operand" "n"))]
8127 static const char * const prefetch_instr[2][2] = {
8129 "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
8130 "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
8133 "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
8134 "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
8137 int read_or_write = INTVAL (operands[1]);
8138 int locality = INTVAL (operands[2]);
8140 gcc_assert (read_or_write == 0 || read_or_write == 1);
8141 gcc_assert (locality >= 0 && locality < 4);
8142 return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
8144 [(set_attr "type" "load")])
8147 [(trap_if (const_int 1) (const_int 5))]
8150 [(set_attr "type" "trap")])
8152 (define_expand "conditional_trap"
8153 [(trap_if (match_operator 0 "noov_compare_operator" [(match_dup 2) (match_dup 3)])
8154 (match_operand:SI 1 "arith_operand" ""))]
8156 "operands[2] = gen_compare_reg (GET_CODE (operands[0]),
8157 sparc_compare_op0, sparc_compare_op1);
8158 if (GET_MODE (operands[2]) != CCmode && GET_MODE (operands[2]) != CCXmode)
8160 operands[3] = const0_rtx;")
8163 [(trap_if (match_operator 0 "noov_compare_operator" [(reg:CC 100) (const_int 0)])
8164 (match_operand:SI 1 "arith_operand" "rM"))]
8168 return "t%C0\t%%icc, %1";
8172 [(set_attr "type" "trap")])
8175 [(trap_if (match_operator 0 "noov_compare_operator" [(reg:CCX 100) (const_int 0)])
8176 (match_operand:SI 1 "arith_operand" "rM"))]
8179 [(set_attr "type" "trap")])
8182 (define_insn "tgd_hi22"
8183 [(set (match_operand:SI 0 "register_operand" "=r")
8184 (high:SI (unspec:SI [(match_operand 1 "tgd_symbolic_operand" "")]
8187 "sethi\\t%%tgd_hi22(%a1), %0")
8189 (define_insn "tgd_lo10"
8190 [(set (match_operand:SI 0 "register_operand" "=r")
8191 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
8192 (unspec:SI [(match_operand 2 "tgd_symbolic_operand" "")]
8195 "add\\t%1, %%tgd_lo10(%a2), %0")
8197 (define_insn "tgd_add32"
8198 [(set (match_operand:SI 0 "register_operand" "=r")
8199 (plus:SI (match_operand:SI 1 "register_operand" "r")
8200 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8201 (match_operand 3 "tgd_symbolic_operand" "")]
8203 "TARGET_TLS && TARGET_ARCH32"
8204 "add\\t%1, %2, %0, %%tgd_add(%a3)")
8206 (define_insn "tgd_add64"
8207 [(set (match_operand:DI 0 "register_operand" "=r")
8208 (plus:DI (match_operand:DI 1 "register_operand" "r")
8209 (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8210 (match_operand 3 "tgd_symbolic_operand" "")]
8212 "TARGET_TLS && TARGET_ARCH64"
8213 "add\\t%1, %2, %0, %%tgd_add(%a3)")
8215 (define_insn "tgd_call32"
8216 [(set (match_operand 0 "register_operand" "=r")
8217 (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")
8218 (match_operand 2 "tgd_symbolic_operand" "")]
8220 (match_operand 3 "" "")))
8221 (clobber (reg:SI 15))]
8222 "TARGET_TLS && TARGET_ARCH32"
8223 "call\t%a1, %%tgd_call(%a2)%#"
8224 [(set_attr "type" "call")])
8226 (define_insn "tgd_call64"
8227 [(set (match_operand 0 "register_operand" "=r")
8228 (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")
8229 (match_operand 2 "tgd_symbolic_operand" "")]
8231 (match_operand 3 "" "")))
8232 (clobber (reg:DI 15))]
8233 "TARGET_TLS && TARGET_ARCH64"
8234 "call\t%a1, %%tgd_call(%a2)%#"
8235 [(set_attr "type" "call")])
8237 (define_insn "tldm_hi22"
8238 [(set (match_operand:SI 0 "register_operand" "=r")
8239 (high:SI (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
8241 "sethi\\t%%tldm_hi22(%&), %0")
8243 (define_insn "tldm_lo10"
8244 [(set (match_operand:SI 0 "register_operand" "=r")
8245 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
8246 (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
8248 "add\\t%1, %%tldm_lo10(%&), %0")
8250 (define_insn "tldm_add32"
8251 [(set (match_operand:SI 0 "register_operand" "=r")
8252 (plus:SI (match_operand:SI 1 "register_operand" "r")
8253 (unspec:SI [(match_operand:SI 2 "register_operand" "r")]
8255 "TARGET_TLS && TARGET_ARCH32"
8256 "add\\t%1, %2, %0, %%tldm_add(%&)")
8258 (define_insn "tldm_add64"
8259 [(set (match_operand:DI 0 "register_operand" "=r")
8260 (plus:DI (match_operand:DI 1 "register_operand" "r")
8261 (unspec:DI [(match_operand:SI 2 "register_operand" "r")]
8263 "TARGET_TLS && TARGET_ARCH64"
8264 "add\\t%1, %2, %0, %%tldm_add(%&)")
8266 (define_insn "tldm_call32"
8267 [(set (match_operand 0 "register_operand" "=r")
8268 (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")]
8270 (match_operand 2 "" "")))
8271 (clobber (reg:SI 15))]
8272 "TARGET_TLS && TARGET_ARCH32"
8273 "call\t%a1, %%tldm_call(%&)%#"
8274 [(set_attr "type" "call")])
8276 (define_insn "tldm_call64"
8277 [(set (match_operand 0 "register_operand" "=r")
8278 (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")]
8280 (match_operand 2 "" "")))
8281 (clobber (reg:DI 15))]
8282 "TARGET_TLS && TARGET_ARCH64"
8283 "call\t%a1, %%tldm_call(%&)%#"
8284 [(set_attr "type" "call")])
8286 (define_insn "tldo_hix22"
8287 [(set (match_operand:SI 0 "register_operand" "=r")
8288 (high:SI (unspec:SI [(match_operand 1 "tld_symbolic_operand" "")]
8291 "sethi\\t%%tldo_hix22(%a1), %0")
8293 (define_insn "tldo_lox10"
8294 [(set (match_operand:SI 0 "register_operand" "=r")
8295 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
8296 (unspec:SI [(match_operand 2 "tld_symbolic_operand" "")]
8299 "xor\\t%1, %%tldo_lox10(%a2), %0")
8301 (define_insn "tldo_add32"
8302 [(set (match_operand:SI 0 "register_operand" "=r")
8303 (plus:SI (match_operand:SI 1 "register_operand" "r")
8304 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8305 (match_operand 3 "tld_symbolic_operand" "")]
8307 "TARGET_TLS && TARGET_ARCH32"
8308 "add\\t%1, %2, %0, %%tldo_add(%a3)")
8310 (define_insn "tldo_add64"
8311 [(set (match_operand:DI 0 "register_operand" "=r")
8312 (plus:DI (match_operand:DI 1 "register_operand" "r")
8313 (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8314 (match_operand 3 "tld_symbolic_operand" "")]
8316 "TARGET_TLS && TARGET_ARCH64"
8317 "add\\t%1, %2, %0, %%tldo_add(%a3)")
8319 (define_insn "tie_hi22"
8320 [(set (match_operand:SI 0 "register_operand" "=r")
8321 (high:SI (unspec:SI [(match_operand 1 "tie_symbolic_operand" "")]
8324 "sethi\\t%%tie_hi22(%a1), %0")
8326 (define_insn "tie_lo10"
8327 [(set (match_operand:SI 0 "register_operand" "=r")
8328 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
8329 (unspec:SI [(match_operand 2 "tie_symbolic_operand" "")]
8332 "add\\t%1, %%tie_lo10(%a2), %0")
8334 (define_insn "tie_ld32"
8335 [(set (match_operand:SI 0 "register_operand" "=r")
8336 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
8337 (match_operand:SI 2 "register_operand" "r")
8338 (match_operand 3 "tie_symbolic_operand" "")]
8340 "TARGET_TLS && TARGET_ARCH32"
8341 "ld\\t[%1 + %2], %0, %%tie_ld(%a3)"
8342 [(set_attr "type" "load")])
8344 (define_insn "tie_ld64"
8345 [(set (match_operand:DI 0 "register_operand" "=r")
8346 (unspec:DI [(match_operand:DI 1 "register_operand" "r")
8347 (match_operand:SI 2 "register_operand" "r")
8348 (match_operand 3 "tie_symbolic_operand" "")]
8350 "TARGET_TLS && TARGET_ARCH64"
8351 "ldx\\t[%1 + %2], %0, %%tie_ldx(%a3)"
8352 [(set_attr "type" "load")])
8354 (define_insn "tie_add32"
8355 [(set (match_operand:SI 0 "register_operand" "=r")
8356 (plus:SI (match_operand:SI 1 "register_operand" "r")
8357 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8358 (match_operand 3 "tie_symbolic_operand" "")]
8360 "TARGET_SUN_TLS && TARGET_ARCH32"
8361 "add\\t%1, %2, %0, %%tie_add(%a3)")
8363 (define_insn "tie_add64"
8364 [(set (match_operand:DI 0 "register_operand" "=r")
8365 (plus:DI (match_operand:DI 1 "register_operand" "r")
8366 (unspec:DI [(match_operand:DI 2 "register_operand" "r")
8367 (match_operand 3 "tie_symbolic_operand" "")]
8369 "TARGET_SUN_TLS && TARGET_ARCH64"
8370 "add\\t%1, %2, %0, %%tie_add(%a3)")
8372 (define_insn "tle_hix22_sp32"
8373 [(set (match_operand:SI 0 "register_operand" "=r")
8374 (high:SI (unspec:SI [(match_operand 1 "tle_symbolic_operand" "")]
8376 "TARGET_TLS && TARGET_ARCH32"
8377 "sethi\\t%%tle_hix22(%a1), %0")
8379 (define_insn "tle_lox10_sp32"
8380 [(set (match_operand:SI 0 "register_operand" "=r")
8381 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
8382 (unspec:SI [(match_operand 2 "tle_symbolic_operand" "")]
8384 "TARGET_TLS && TARGET_ARCH32"
8385 "xor\\t%1, %%tle_lox10(%a2), %0")
8387 (define_insn "tle_hix22_sp64"
8388 [(set (match_operand:DI 0 "register_operand" "=r")
8389 (high:DI (unspec:DI [(match_operand 1 "tle_symbolic_operand" "")]
8391 "TARGET_TLS && TARGET_ARCH64"
8392 "sethi\\t%%tle_hix22(%a1), %0")
8394 (define_insn "tle_lox10_sp64"
8395 [(set (match_operand:DI 0 "register_operand" "=r")
8396 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
8397 (unspec:DI [(match_operand 2 "tle_symbolic_operand" "")]
8399 "TARGET_TLS && TARGET_ARCH64"
8400 "xor\\t%1, %%tle_lox10(%a2), %0")
8402 ;; Now patterns combining tldo_add{32,64} with some integer loads or stores
8403 (define_insn "*tldo_ldub_sp32"
8404 [(set (match_operand:QI 0 "register_operand" "=r")
8405 (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8406 (match_operand 3 "tld_symbolic_operand" "")]
8408 (match_operand:SI 1 "register_operand" "r"))))]
8409 "TARGET_TLS && TARGET_ARCH32"
8410 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8411 [(set_attr "type" "load")
8412 (set_attr "us3load_type" "3cycle")])
8414 (define_insn "*tldo_ldub1_sp32"
8415 [(set (match_operand:HI 0 "register_operand" "=r")
8416 (zero_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8417 (match_operand 3 "tld_symbolic_operand" "")]
8419 (match_operand:SI 1 "register_operand" "r")))))]
8420 "TARGET_TLS && TARGET_ARCH32"
8421 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8422 [(set_attr "type" "load")
8423 (set_attr "us3load_type" "3cycle")])
8425 (define_insn "*tldo_ldub2_sp32"
8426 [(set (match_operand:SI 0 "register_operand" "=r")
8427 (zero_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8428 (match_operand 3 "tld_symbolic_operand" "")]
8430 (match_operand:SI 1 "register_operand" "r")))))]
8431 "TARGET_TLS && TARGET_ARCH32"
8432 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8433 [(set_attr "type" "load")
8434 (set_attr "us3load_type" "3cycle")])
8436 (define_insn "*tldo_ldsb1_sp32"
8437 [(set (match_operand:HI 0 "register_operand" "=r")
8438 (sign_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8439 (match_operand 3 "tld_symbolic_operand" "")]
8441 (match_operand:SI 1 "register_operand" "r")))))]
8442 "TARGET_TLS && TARGET_ARCH32"
8443 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
8444 [(set_attr "type" "sload")
8445 (set_attr "us3load_type" "3cycle")])
8447 (define_insn "*tldo_ldsb2_sp32"
8448 [(set (match_operand:SI 0 "register_operand" "=r")
8449 (sign_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8450 (match_operand 3 "tld_symbolic_operand" "")]
8452 (match_operand:SI 1 "register_operand" "r")))))]
8453 "TARGET_TLS && TARGET_ARCH32"
8454 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
8455 [(set_attr "type" "sload")
8456 (set_attr "us3load_type" "3cycle")])
8458 (define_insn "*tldo_ldub_sp64"
8459 [(set (match_operand:QI 0 "register_operand" "=r")
8460 (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8461 (match_operand 3 "tld_symbolic_operand" "")]
8463 (match_operand:DI 1 "register_operand" "r"))))]
8464 "TARGET_TLS && TARGET_ARCH64"
8465 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8466 [(set_attr "type" "load")
8467 (set_attr "us3load_type" "3cycle")])
8469 (define_insn "*tldo_ldub1_sp64"
8470 [(set (match_operand:HI 0 "register_operand" "=r")
8471 (zero_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8472 (match_operand 3 "tld_symbolic_operand" "")]
8474 (match_operand:DI 1 "register_operand" "r")))))]
8475 "TARGET_TLS && TARGET_ARCH64"
8476 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8477 [(set_attr "type" "load")
8478 (set_attr "us3load_type" "3cycle")])
8480 (define_insn "*tldo_ldub2_sp64"
8481 [(set (match_operand:SI 0 "register_operand" "=r")
8482 (zero_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8483 (match_operand 3 "tld_symbolic_operand" "")]
8485 (match_operand:DI 1 "register_operand" "r")))))]
8486 "TARGET_TLS && TARGET_ARCH64"
8487 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8488 [(set_attr "type" "load")
8489 (set_attr "us3load_type" "3cycle")])
8491 (define_insn "*tldo_ldub3_sp64"
8492 [(set (match_operand:DI 0 "register_operand" "=r")
8493 (zero_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8494 (match_operand 3 "tld_symbolic_operand" "")]
8496 (match_operand:DI 1 "register_operand" "r")))))]
8497 "TARGET_TLS && TARGET_ARCH64"
8498 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8499 [(set_attr "type" "load")
8500 (set_attr "us3load_type" "3cycle")])
8502 (define_insn "*tldo_ldsb1_sp64"
8503 [(set (match_operand:HI 0 "register_operand" "=r")
8504 (sign_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8505 (match_operand 3 "tld_symbolic_operand" "")]
8507 (match_operand:DI 1 "register_operand" "r")))))]
8508 "TARGET_TLS && TARGET_ARCH64"
8509 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
8510 [(set_attr "type" "sload")
8511 (set_attr "us3load_type" "3cycle")])
8513 (define_insn "*tldo_ldsb2_sp64"
8514 [(set (match_operand:SI 0 "register_operand" "=r")
8515 (sign_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8516 (match_operand 3 "tld_symbolic_operand" "")]
8518 (match_operand:DI 1 "register_operand" "r")))))]
8519 "TARGET_TLS && TARGET_ARCH64"
8520 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
8521 [(set_attr "type" "sload")
8522 (set_attr "us3load_type" "3cycle")])
8524 (define_insn "*tldo_ldsb3_sp64"
8525 [(set (match_operand:DI 0 "register_operand" "=r")
8526 (sign_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8527 (match_operand 3 "tld_symbolic_operand" "")]
8529 (match_operand:DI 1 "register_operand" "r")))))]
8530 "TARGET_TLS && TARGET_ARCH64"
8531 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
8532 [(set_attr "type" "sload")
8533 (set_attr "us3load_type" "3cycle")])
8535 (define_insn "*tldo_lduh_sp32"
8536 [(set (match_operand:HI 0 "register_operand" "=r")
8537 (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8538 (match_operand 3 "tld_symbolic_operand" "")]
8540 (match_operand:SI 1 "register_operand" "r"))))]
8541 "TARGET_TLS && TARGET_ARCH32"
8542 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
8543 [(set_attr "type" "load")
8544 (set_attr "us3load_type" "3cycle")])
8546 (define_insn "*tldo_lduh1_sp32"
8547 [(set (match_operand:SI 0 "register_operand" "=r")
8548 (zero_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8549 (match_operand 3 "tld_symbolic_operand" "")]
8551 (match_operand:SI 1 "register_operand" "r")))))]
8552 "TARGET_TLS && TARGET_ARCH32"
8553 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
8554 [(set_attr "type" "load")
8555 (set_attr "us3load_type" "3cycle")])
8557 (define_insn "*tldo_ldsh1_sp32"
8558 [(set (match_operand:SI 0 "register_operand" "=r")
8559 (sign_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8560 (match_operand 3 "tld_symbolic_operand" "")]
8562 (match_operand:SI 1 "register_operand" "r")))))]
8563 "TARGET_TLS && TARGET_ARCH32"
8564 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
8565 [(set_attr "type" "sload")
8566 (set_attr "us3load_type" "3cycle")])
8568 (define_insn "*tldo_lduh_sp64"
8569 [(set (match_operand:HI 0 "register_operand" "=r")
8570 (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8571 (match_operand 3 "tld_symbolic_operand" "")]
8573 (match_operand:DI 1 "register_operand" "r"))))]
8574 "TARGET_TLS && TARGET_ARCH64"
8575 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
8576 [(set_attr "type" "load")
8577 (set_attr "us3load_type" "3cycle")])
8579 (define_insn "*tldo_lduh1_sp64"
8580 [(set (match_operand:SI 0 "register_operand" "=r")
8581 (zero_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8582 (match_operand 3 "tld_symbolic_operand" "")]
8584 (match_operand:DI 1 "register_operand" "r")))))]
8585 "TARGET_TLS && TARGET_ARCH64"
8586 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
8587 [(set_attr "type" "load")
8588 (set_attr "us3load_type" "3cycle")])
8590 (define_insn "*tldo_lduh2_sp64"
8591 [(set (match_operand:DI 0 "register_operand" "=r")
8592 (zero_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8593 (match_operand 3 "tld_symbolic_operand" "")]
8595 (match_operand:DI 1 "register_operand" "r")))))]
8596 "TARGET_TLS && TARGET_ARCH64"
8597 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
8598 [(set_attr "type" "load")
8599 (set_attr "us3load_type" "3cycle")])
8601 (define_insn "*tldo_ldsh1_sp64"
8602 [(set (match_operand:SI 0 "register_operand" "=r")
8603 (sign_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8604 (match_operand 3 "tld_symbolic_operand" "")]
8606 (match_operand:DI 1 "register_operand" "r")))))]
8607 "TARGET_TLS && TARGET_ARCH64"
8608 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
8609 [(set_attr "type" "sload")
8610 (set_attr "us3load_type" "3cycle")])
8612 (define_insn "*tldo_ldsh2_sp64"
8613 [(set (match_operand:DI 0 "register_operand" "=r")
8614 (sign_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8615 (match_operand 3 "tld_symbolic_operand" "")]
8617 (match_operand:DI 1 "register_operand" "r")))))]
8618 "TARGET_TLS && TARGET_ARCH64"
8619 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
8620 [(set_attr "type" "sload")
8621 (set_attr "us3load_type" "3cycle")])
8623 (define_insn "*tldo_lduw_sp32"
8624 [(set (match_operand:SI 0 "register_operand" "=r")
8625 (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8626 (match_operand 3 "tld_symbolic_operand" "")]
8628 (match_operand:SI 1 "register_operand" "r"))))]
8629 "TARGET_TLS && TARGET_ARCH32"
8630 "ld\t[%1 + %2], %0, %%tldo_add(%3)"
8631 [(set_attr "type" "load")])
8633 (define_insn "*tldo_lduw_sp64"
8634 [(set (match_operand:SI 0 "register_operand" "=r")
8635 (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8636 (match_operand 3 "tld_symbolic_operand" "")]
8638 (match_operand:DI 1 "register_operand" "r"))))]
8639 "TARGET_TLS && TARGET_ARCH64"
8640 "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
8641 [(set_attr "type" "load")])
8643 (define_insn "*tldo_lduw1_sp64"
8644 [(set (match_operand:DI 0 "register_operand" "=r")
8645 (zero_extend:DI (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8646 (match_operand 3 "tld_symbolic_operand" "")]
8648 (match_operand:DI 1 "register_operand" "r")))))]
8649 "TARGET_TLS && TARGET_ARCH64"
8650 "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
8651 [(set_attr "type" "load")])
8653 (define_insn "*tldo_ldsw1_sp64"
8654 [(set (match_operand:DI 0 "register_operand" "=r")
8655 (sign_extend:DI (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8656 (match_operand 3 "tld_symbolic_operand" "")]
8658 (match_operand:DI 1 "register_operand" "r")))))]
8659 "TARGET_TLS && TARGET_ARCH64"
8660 "ldsw\t[%1 + %2], %0, %%tldo_add(%3)"
8661 [(set_attr "type" "sload")
8662 (set_attr "us3load_type" "3cycle")])
8664 (define_insn "*tldo_ldx_sp64"
8665 [(set (match_operand:DI 0 "register_operand" "=r")
8666 (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8667 (match_operand 3 "tld_symbolic_operand" "")]
8669 (match_operand:DI 1 "register_operand" "r"))))]
8670 "TARGET_TLS && TARGET_ARCH64"
8671 "ldx\t[%1 + %2], %0, %%tldo_add(%3)"
8672 [(set_attr "type" "load")])
8674 (define_insn "*tldo_stb_sp32"
8675 [(set (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8676 (match_operand 3 "tld_symbolic_operand" "")]
8678 (match_operand:SI 1 "register_operand" "r")))
8679 (match_operand:QI 0 "register_operand" "=r"))]
8680 "TARGET_TLS && TARGET_ARCH32"
8681 "stb\t%0, [%1 + %2], %%tldo_add(%3)"
8682 [(set_attr "type" "store")])
8684 (define_insn "*tldo_stb_sp64"
8685 [(set (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8686 (match_operand 3 "tld_symbolic_operand" "")]
8688 (match_operand:DI 1 "register_operand" "r")))
8689 (match_operand:QI 0 "register_operand" "=r"))]
8690 "TARGET_TLS && TARGET_ARCH64"
8691 "stb\t%0, [%1 + %2], %%tldo_add(%3)"
8692 [(set_attr "type" "store")])
8694 (define_insn "*tldo_sth_sp32"
8695 [(set (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8696 (match_operand 3 "tld_symbolic_operand" "")]
8698 (match_operand:SI 1 "register_operand" "r")))
8699 (match_operand:HI 0 "register_operand" "=r"))]
8700 "TARGET_TLS && TARGET_ARCH32"
8701 "sth\t%0, [%1 + %2], %%tldo_add(%3)"
8702 [(set_attr "type" "store")])
8704 (define_insn "*tldo_sth_sp64"
8705 [(set (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8706 (match_operand 3 "tld_symbolic_operand" "")]
8708 (match_operand:DI 1 "register_operand" "r")))
8709 (match_operand:HI 0 "register_operand" "=r"))]
8710 "TARGET_TLS && TARGET_ARCH64"
8711 "sth\t%0, [%1 + %2], %%tldo_add(%3)"
8712 [(set_attr "type" "store")])
8714 (define_insn "*tldo_stw_sp32"
8715 [(set (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8716 (match_operand 3 "tld_symbolic_operand" "")]
8718 (match_operand:SI 1 "register_operand" "r")))
8719 (match_operand:SI 0 "register_operand" "=r"))]
8720 "TARGET_TLS && TARGET_ARCH32"
8721 "st\t%0, [%1 + %2], %%tldo_add(%3)"
8722 [(set_attr "type" "store")])
8724 (define_insn "*tldo_stw_sp64"
8725 [(set (mem:SI (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 (match_operand:SI 0 "register_operand" "=r"))]
8730 "TARGET_TLS && TARGET_ARCH64"
8731 "stw\t%0, [%1 + %2], %%tldo_add(%3)"
8732 [(set_attr "type" "store")])
8734 (define_insn "*tldo_stx_sp64"
8735 [(set (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8736 (match_operand 3 "tld_symbolic_operand" "")]
8738 (match_operand:DI 1 "register_operand" "r")))
8739 (match_operand:DI 0 "register_operand" "=r"))]
8740 "TARGET_TLS && TARGET_ARCH64"
8741 "stx\t%0, [%1 + %2], %%tldo_add(%3)"
8742 [(set_attr "type" "store")])
8744 ;; Vector instructions.
8746 (define_insn "addv2si3"
8747 [(set (match_operand:V2SI 0 "register_operand" "=e")
8748 (plus:V2SI (match_operand:V2SI 1 "register_operand" "e")
8749 (match_operand:V2SI 2 "register_operand" "e")))]
8751 "fpadd32\t%1, %2, %0"
8752 [(set_attr "type" "fga")
8753 (set_attr "fptype" "double")])
8755 (define_insn "addv4hi3"
8756 [(set (match_operand:V4HI 0 "register_operand" "=e")
8757 (plus:V4HI (match_operand:V4HI 1 "register_operand" "e")
8758 (match_operand:V4HI 2 "register_operand" "e")))]
8760 "fpadd16\t%1, %2, %0"
8761 [(set_attr "type" "fga")
8762 (set_attr "fptype" "double")])
8764 ;; fpadd32s is emitted by the addsi3 pattern.
8766 (define_insn "addv2hi3"
8767 [(set (match_operand:V2HI 0 "register_operand" "=f")
8768 (plus:V2HI (match_operand:V2HI 1 "register_operand" "f")
8769 (match_operand:V2HI 2 "register_operand" "f")))]
8771 "fpadd16s\t%1, %2, %0"
8772 [(set_attr "type" "fga")
8773 (set_attr "fptype" "single")])
8775 (define_insn "subv2si3"
8776 [(set (match_operand:V2SI 0 "register_operand" "=e")
8777 (minus:V2SI (match_operand:V2SI 1 "register_operand" "e")
8778 (match_operand:V2SI 2 "register_operand" "e")))]
8780 "fpsub32\t%1, %2, %0"
8781 [(set_attr "type" "fga")
8782 (set_attr "fptype" "double")])
8784 (define_insn "subv4hi3"
8785 [(set (match_operand:V4HI 0 "register_operand" "=e")
8786 (minus:V4HI (match_operand:V4HI 1 "register_operand" "e")
8787 (match_operand:V4HI 2 "register_operand" "e")))]
8789 "fpsub16\t%1, %2, %0"
8790 [(set_attr "type" "fga")
8791 (set_attr "fptype" "double")])
8793 ;; fpsub32s is emitted by the subsi3 pattern.
8795 (define_insn "subv2hi3"
8796 [(set (match_operand:V2HI 0 "register_operand" "=f")
8797 (minus:V2HI (match_operand:V2HI 1 "register_operand" "f")
8798 (match_operand:V2HI 2 "register_operand" "f")))]
8800 "fpsub16s\t%1, %2, %0"
8801 [(set_attr "type" "fga")
8802 (set_attr "fptype" "single")])
8804 ;; All other logical instructions have integer equivalents so they
8805 ;; are defined together.
8807 ;; (ior (not (op1)) (not (op2))) is the canonical form of NAND.
8809 (define_insn "*nand<V64mode>_vis"
8810 [(set (match_operand:V64 0 "register_operand" "=e")
8811 (ior:V64 (not:V64 (match_operand:V64 1 "register_operand" "e"))
8812 (not:V64 (match_operand:V64 2 "register_operand" "e"))))]
8815 [(set_attr "type" "fga")
8816 (set_attr "fptype" "double")])
8818 (define_insn "*nand<V32mode>_vis"
8819 [(set (match_operand:V32 0 "register_operand" "=f")
8820 (ior:V32 (not:V32 (match_operand:V32 1 "register_operand" "f"))
8821 (not:V32 (match_operand:V32 2 "register_operand" "f"))))]
8823 "fnands\t%1, %2, %0"
8824 [(set_attr "type" "fga")
8825 (set_attr "fptype" "single")])
8827 ;; Hard to generate VIS instructions. We have builtins for these.
8829 (define_insn "fpack16_vis"
8830 [(set (match_operand:V4QI 0 "register_operand" "=f")
8831 (unspec:V4QI [(match_operand:V4HI 1 "register_operand" "e")]
8835 [(set_attr "type" "fga")
8836 (set_attr "fptype" "double")])
8838 (define_insn "fpackfix_vis"
8839 [(set (match_operand:V2HI 0 "register_operand" "=f")
8840 (unspec:V2HI [(match_operand:V2SI 1 "register_operand" "e")]
8844 [(set_attr "type" "fga")
8845 (set_attr "fptype" "double")])
8847 (define_insn "fpack32_vis"
8848 [(set (match_operand:V8QI 0 "register_operand" "=e")
8849 (unspec:V8QI [(match_operand:V2SI 1 "register_operand" "e")
8850 (match_operand:V8QI 2 "register_operand" "e")]
8853 "fpack32\t%1, %2, %0"
8854 [(set_attr "type" "fga")
8855 (set_attr "fptype" "double")])
8857 (define_insn "fexpand_vis"
8858 [(set (match_operand:V4HI 0 "register_operand" "=e")
8859 (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")]
8863 [(set_attr "type" "fga")
8864 (set_attr "fptype" "double")])
8866 ;; It may be possible to describe this operation as (1 indexed):
8867 ;; (vec_select (vec_duplicate (vec_duplicate (vec_concat 1 2)))
8868 ;; 1,5,10,14,19,23,28,32)
8869 ;; Note that (vec_merge:V8QI [(V4QI) (V4QI)] (10101010 = 170) doesn't work
8870 ;; because vec_merge expects all the operands to be of the same type.
8871 (define_insn "fpmerge_vis"
8872 [(set (match_operand:V8QI 0 "register_operand" "=e")
8873 (unspec:V8QI [(match_operand:V4QI 1 "register_operand" "f")
8874 (match_operand:V4QI 2 "register_operand" "f")]
8877 "fpmerge\t%1, %2, %0"
8878 [(set_attr "type" "fga")
8879 (set_attr "fptype" "double")])
8881 ;; Partitioned multiply instructions
8882 (define_insn "fmul8x16_vis"
8883 [(set (match_operand:V4HI 0 "register_operand" "=e")
8884 (mult:V4HI (match_operand:V4QI 1 "register_operand" "f")
8885 (match_operand:V4HI 2 "register_operand" "e")))]
8887 "fmul8x16\t%1, %2, %0"
8888 [(set_attr "type" "fpmul")
8889 (set_attr "fptype" "double")])
8891 ;; Only one of the following two insns can be a multiply.
8892 (define_insn "fmul8x16au_vis"
8893 [(set (match_operand:V4HI 0 "register_operand" "=e")
8894 (mult:V4HI (match_operand:V4QI 1 "register_operand" "f")
8895 (match_operand:V2HI 2 "register_operand" "f")))]
8897 "fmul8x16au\t%1, %2, %0"
8898 [(set_attr "type" "fpmul")
8899 (set_attr "fptype" "double")])
8901 (define_insn "fmul8x16al_vis"
8902 [(set (match_operand:V4HI 0 "register_operand" "=e")
8903 (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")
8904 (match_operand:V2HI 2 "register_operand" "f")]
8907 "fmul8x16al\t%1, %2, %0"
8908 [(set_attr "type" "fpmul")
8909 (set_attr "fptype" "double")])
8911 ;; Only one of the following two insns can be a multiply.
8912 (define_insn "fmul8sux16_vis"
8913 [(set (match_operand:V4HI 0 "register_operand" "=e")
8914 (mult:V4HI (match_operand:V8QI 1 "register_operand" "e")
8915 (match_operand:V4HI 2 "register_operand" "e")))]
8917 "fmul8sux16\t%1, %2, %0"
8918 [(set_attr "type" "fpmul")
8919 (set_attr "fptype" "double")])
8921 (define_insn "fmul8ulx16_vis"
8922 [(set (match_operand:V4HI 0 "register_operand" "=e")
8923 (unspec:V4HI [(match_operand:V8QI 1 "register_operand" "e")
8924 (match_operand:V4HI 2 "register_operand" "e")]
8927 "fmul8ulx16\t%1, %2, %0"
8928 [(set_attr "type" "fpmul")
8929 (set_attr "fptype" "double")])
8931 ;; Only one of the following two insns can be a multiply.
8932 (define_insn "fmuld8sux16_vis"
8933 [(set (match_operand:V2SI 0 "register_operand" "=e")
8934 (mult:V2SI (match_operand:V4QI 1 "register_operand" "f")
8935 (match_operand:V2HI 2 "register_operand" "f")))]
8937 "fmuld8sux16\t%1, %2, %0"
8938 [(set_attr "type" "fpmul")
8939 (set_attr "fptype" "double")])
8941 (define_insn "fmuld8ulx16_vis"
8942 [(set (match_operand:V2SI 0 "register_operand" "=e")
8943 (unspec:V2SI [(match_operand:V4QI 1 "register_operand" "f")
8944 (match_operand:V2HI 2 "register_operand" "f")]
8947 "fmuld8ulx16\t%1, %2, %0"
8948 [(set_attr "type" "fpmul")
8949 (set_attr "fptype" "double")])
8951 ;; Using faligndata only makes sense after an alignaddr since the choice of
8952 ;; bytes to take out of each operand is dependant on the results of the last
8954 (define_insn "faligndata<V64I:mode>_vis"
8955 [(set (match_operand:V64I 0 "register_operand" "=e")
8956 (unspec:V64I [(match_operand:V64I 1 "register_operand" "e")
8957 (match_operand:V64I 2 "register_operand" "e")]
8960 "faligndata\t%1, %2, %0"
8961 [(set_attr "type" "fga")
8962 (set_attr "fptype" "double")])
8964 (define_insn "alignaddr<P:mode>_vis"
8965 [(set (match_operand:P 0 "register_operand" "=r")
8966 (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
8967 (match_operand:P 2 "register_or_zero_operand" "rJ")]
8970 "alignaddr\t%r1, %r2, %0")
8972 (define_insn "pdist_vis"
8973 [(set (match_operand:DI 0 "register_operand" "=e")
8974 (unspec:DI [(match_operand:V8QI 1 "register_operand" "e")
8975 (match_operand:V8QI 2 "register_operand" "e")
8976 (match_operand:DI 3 "register_operand" "0")]
8980 [(set_attr "type" "fga")
8981 (set_attr "fptype" "double")])