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,2006 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, 51 Franklin Street, Fifth Floor,
23 ;; Boston, MA 02110-1301, 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)
78 ;; The upper 32 fp regs on the v9 can't hold SFmode values. To deal with this
79 ;; a second register class, EXTRA_FP_REGS, exists for the v9 chip. The name
80 ;; is a bit of a misnomer as it covers all 64 fp regs. The corresponding
81 ;; constraint letter is 'e'. To avoid any confusion, 'e' is used instead of
82 ;; 'f' for all DF/TFmode values, including those that are specific to the v8.
85 ;; Attribute for cpu type.
86 ;; These must match the values for enum processor_type in sparc.h.
93 hypersparc,sparclite86x,
99 (const (symbol_ref "sparc_cpu_attr")))
101 ;; Attribute for the instruction set.
102 ;; At present we only need to distinguish v9/!v9, but for clarity we
103 ;; test TARGET_V8 too.
104 (define_attr "isa" "v7,v8,v9,sparclet"
106 (cond [(symbol_ref "TARGET_V9") (const_string "v9")
107 (symbol_ref "TARGET_V8") (const_string "v8")
108 (symbol_ref "TARGET_SPARCLET") (const_string "sparclet")]
109 (const_string "v7"))))
115 uncond_branch,branch,call,sibcall,call_no_delay_slot,return,
123 fga,fgm_pack,fgm_mul,fgm_pdist,fgm_cmp,
126 multi,savew,flushw,iflush,trap"
127 (const_string "ialu"))
129 ;; True if branch/call has empty delay slot and will emit a nop in it
130 (define_attr "empty_delay_slot" "false,true"
131 (symbol_ref "empty_delay_slot (insn)"))
133 (define_attr "branch_type" "none,icc,fcc,reg"
134 (const_string "none"))
136 (define_attr "pic" "false,true"
137 (symbol_ref "flag_pic != 0"))
139 (define_attr "calls_alloca" "false,true"
140 (symbol_ref "current_function_calls_alloca != 0"))
142 (define_attr "calls_eh_return" "false,true"
143 (symbol_ref "current_function_calls_eh_return !=0 "))
145 (define_attr "leaf_function" "false,true"
146 (symbol_ref "current_function_uses_only_leaf_regs != 0"))
148 (define_attr "delayed_branch" "false,true"
149 (symbol_ref "flag_delayed_branch != 0"))
151 ;; Length (in # of insns).
152 ;; Beware that setting a length greater or equal to 3 for conditional branches
153 ;; has a side-effect (see output_cbranch and output_v9branch).
154 (define_attr "length" ""
155 (cond [(eq_attr "type" "uncond_branch,call")
156 (if_then_else (eq_attr "empty_delay_slot" "true")
159 (eq_attr "type" "sibcall")
160 (if_then_else (eq_attr "leaf_function" "true")
161 (if_then_else (eq_attr "empty_delay_slot" "true")
164 (if_then_else (eq_attr "empty_delay_slot" "true")
167 (eq_attr "branch_type" "icc")
168 (if_then_else (match_operand 0 "noov_compare64_operator" "")
169 (if_then_else (lt (pc) (match_dup 1))
170 (if_then_else (lt (minus (match_dup 1) (pc)) (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 (lt (minus (pc) (match_dup 1)) (const_int 260000))
178 (if_then_else (eq_attr "empty_delay_slot" "true")
181 (if_then_else (eq_attr "empty_delay_slot" "true")
184 (if_then_else (eq_attr "empty_delay_slot" "true")
187 (eq_attr "branch_type" "fcc")
188 (if_then_else (match_operand 0 "fcc0_register_operand" "")
189 (if_then_else (eq_attr "empty_delay_slot" "true")
190 (if_then_else (eq (symbol_ref "TARGET_V9") (const_int 0))
193 (if_then_else (eq (symbol_ref "TARGET_V9") (const_int 0))
196 (if_then_else (lt (pc) (match_dup 2))
197 (if_then_else (lt (minus (match_dup 2) (pc)) (const_int 260000))
198 (if_then_else (eq_attr "empty_delay_slot" "true")
201 (if_then_else (eq_attr "empty_delay_slot" "true")
204 (if_then_else (lt (minus (pc) (match_dup 2)) (const_int 260000))
205 (if_then_else (eq_attr "empty_delay_slot" "true")
208 (if_then_else (eq_attr "empty_delay_slot" "true")
211 (eq_attr "branch_type" "reg")
212 (if_then_else (lt (pc) (match_dup 2))
213 (if_then_else (lt (minus (match_dup 2) (pc)) (const_int 32000))
214 (if_then_else (eq_attr "empty_delay_slot" "true")
217 (if_then_else (eq_attr "empty_delay_slot" "true")
220 (if_then_else (lt (minus (pc) (match_dup 2)) (const_int 32000))
221 (if_then_else (eq_attr "empty_delay_slot" "true")
224 (if_then_else (eq_attr "empty_delay_slot" "true")
230 (define_attr "fptype" "single,double"
231 (const_string "single"))
233 ;; UltraSPARC-III integer load type.
234 (define_attr "us3load_type" "2cycle,3cycle"
235 (const_string "2cycle"))
237 (define_asm_attributes
238 [(set_attr "length" "2")
239 (set_attr "type" "multi")])
241 ;; Attributes for instruction and branch scheduling
242 (define_attr "tls_call_delay" "false,true"
243 (symbol_ref "tls_call_delay (insn)"))
245 (define_attr "in_call_delay" "false,true"
246 (cond [(eq_attr "type" "uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
247 (const_string "false")
248 (eq_attr "type" "load,fpload,store,fpstore")
249 (if_then_else (eq_attr "length" "1")
250 (const_string "true")
251 (const_string "false"))]
252 (if_then_else (and (eq_attr "length" "1")
253 (eq_attr "tls_call_delay" "true"))
254 (const_string "true")
255 (const_string "false"))))
257 (define_attr "eligible_for_sibcall_delay" "false,true"
258 (symbol_ref "eligible_for_sibcall_delay (insn)"))
260 (define_attr "eligible_for_return_delay" "false,true"
261 (symbol_ref "eligible_for_return_delay (insn)"))
263 ;; ??? !v9: Should implement the notion of predelay slots for floating-point
264 ;; branches. This would allow us to remove the nop always inserted before
265 ;; a floating point branch.
267 ;; ??? It is OK for fill_simple_delay_slots to put load/store instructions
268 ;; in a delay slot, but it is not OK for fill_eager_delay_slots to do so.
269 ;; This is because doing so will add several pipeline stalls to the path
270 ;; that the load/store did not come from. Unfortunately, there is no way
271 ;; to prevent fill_eager_delay_slots from using load/store without completely
272 ;; disabling them. For the SPEC benchmark set, this is a serious lose,
273 ;; because it prevents us from moving back the final store of inner loops.
275 (define_attr "in_branch_delay" "false,true"
276 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
277 (eq_attr "length" "1"))
278 (const_string "true")
279 (const_string "false")))
281 (define_attr "in_uncond_branch_delay" "false,true"
282 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
283 (eq_attr "length" "1"))
284 (const_string "true")
285 (const_string "false")))
287 (define_attr "in_annul_branch_delay" "false,true"
288 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
289 (eq_attr "length" "1"))
290 (const_string "true")
291 (const_string "false")))
293 (define_delay (eq_attr "type" "call")
294 [(eq_attr "in_call_delay" "true") (nil) (nil)])
296 (define_delay (eq_attr "type" "sibcall")
297 [(eq_attr "eligible_for_sibcall_delay" "true") (nil) (nil)])
299 (define_delay (eq_attr "type" "branch")
300 [(eq_attr "in_branch_delay" "true")
301 (nil) (eq_attr "in_annul_branch_delay" "true")])
303 (define_delay (eq_attr "type" "uncond_branch")
304 [(eq_attr "in_uncond_branch_delay" "true")
307 (define_delay (eq_attr "type" "return")
308 [(eq_attr "eligible_for_return_delay" "true") (nil) (nil)])
311 ;; Include SPARC DFA schedulers
313 (include "cypress.md")
314 (include "supersparc.md")
315 (include "hypersparc.md")
316 (include "sparclet.md")
317 (include "ultra1_2.md")
318 (include "ultra3.md")
319 (include "niagara.md")
322 ;; Operand and operator predicates.
324 (include "predicates.md")
327 ;; Compare instructions.
329 ;; We generate RTL for comparisons and branches by having the cmpxx
330 ;; patterns store away the operands. Then, the scc and bcc patterns
331 ;; emit RTL for both the compare and the branch.
333 ;; We do this because we want to generate different code for an sne and
334 ;; seq insn. In those cases, if the second operand of the compare is not
335 ;; const0_rtx, we want to compute the xor of the two operands and test
338 ;; We start with the DEFINE_EXPANDs, then the DEFINE_INSNs to match
339 ;; the patterns. Finally, we have the DEFINE_SPLITs for some of the scc
340 ;; insns that actually require more than one machine instruction.
342 (define_expand "cmpsi"
344 (compare:CC (match_operand:SI 0 "compare_operand" "")
345 (match_operand:SI 1 "arith_operand" "")))]
348 if (GET_CODE (operands[0]) == ZERO_EXTRACT && operands[1] != const0_rtx)
349 operands[0] = force_reg (SImode, operands[0]);
351 sparc_compare_op0 = operands[0];
352 sparc_compare_op1 = operands[1];
356 (define_expand "cmpdi"
358 (compare:CCX (match_operand:DI 0 "compare_operand" "")
359 (match_operand:DI 1 "arith_operand" "")))]
362 if (GET_CODE (operands[0]) == ZERO_EXTRACT && operands[1] != const0_rtx)
363 operands[0] = force_reg (DImode, operands[0]);
365 sparc_compare_op0 = operands[0];
366 sparc_compare_op1 = operands[1];
370 (define_expand "cmpsf"
371 ;; The 96 here isn't ever used by anyone.
373 (compare:CCFP (match_operand:SF 0 "register_operand" "")
374 (match_operand:SF 1 "register_operand" "")))]
377 sparc_compare_op0 = operands[0];
378 sparc_compare_op1 = operands[1];
382 (define_expand "cmpdf"
383 ;; The 96 here isn't ever used by anyone.
385 (compare:CCFP (match_operand:DF 0 "register_operand" "")
386 (match_operand:DF 1 "register_operand" "")))]
389 sparc_compare_op0 = operands[0];
390 sparc_compare_op1 = operands[1];
394 (define_expand "cmptf"
395 ;; The 96 here isn't ever used by anyone.
397 (compare:CCFP (match_operand:TF 0 "register_operand" "")
398 (match_operand:TF 1 "register_operand" "")))]
401 sparc_compare_op0 = operands[0];
402 sparc_compare_op1 = operands[1];
406 ;; Now the compare DEFINE_INSNs.
408 (define_insn "*cmpsi_insn"
410 (compare:CC (match_operand:SI 0 "register_operand" "r")
411 (match_operand:SI 1 "arith_operand" "rI")))]
414 [(set_attr "type" "compare")])
416 (define_insn "*cmpdi_sp64"
418 (compare:CCX (match_operand:DI 0 "register_operand" "r")
419 (match_operand:DI 1 "arith_operand" "rI")))]
422 [(set_attr "type" "compare")])
424 (define_insn "*cmpsf_fpe"
425 [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
426 (compare:CCFPE (match_operand:SF 1 "register_operand" "f")
427 (match_operand:SF 2 "register_operand" "f")))]
431 return "fcmpes\t%0, %1, %2";
432 return "fcmpes\t%1, %2";
434 [(set_attr "type" "fpcmp")])
436 (define_insn "*cmpdf_fpe"
437 [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
438 (compare:CCFPE (match_operand:DF 1 "register_operand" "e")
439 (match_operand:DF 2 "register_operand" "e")))]
443 return "fcmped\t%0, %1, %2";
444 return "fcmped\t%1, %2";
446 [(set_attr "type" "fpcmp")
447 (set_attr "fptype" "double")])
449 (define_insn "*cmptf_fpe"
450 [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
451 (compare:CCFPE (match_operand:TF 1 "register_operand" "e")
452 (match_operand:TF 2 "register_operand" "e")))]
453 "TARGET_FPU && TARGET_HARD_QUAD"
456 return "fcmpeq\t%0, %1, %2";
457 return "fcmpeq\t%1, %2";
459 [(set_attr "type" "fpcmp")])
461 (define_insn "*cmpsf_fp"
462 [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
463 (compare:CCFP (match_operand:SF 1 "register_operand" "f")
464 (match_operand:SF 2 "register_operand" "f")))]
468 return "fcmps\t%0, %1, %2";
469 return "fcmps\t%1, %2";
471 [(set_attr "type" "fpcmp")])
473 (define_insn "*cmpdf_fp"
474 [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
475 (compare:CCFP (match_operand:DF 1 "register_operand" "e")
476 (match_operand:DF 2 "register_operand" "e")))]
480 return "fcmpd\t%0, %1, %2";
481 return "fcmpd\t%1, %2";
483 [(set_attr "type" "fpcmp")
484 (set_attr "fptype" "double")])
486 (define_insn "*cmptf_fp"
487 [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
488 (compare:CCFP (match_operand:TF 1 "register_operand" "e")
489 (match_operand:TF 2 "register_operand" "e")))]
490 "TARGET_FPU && TARGET_HARD_QUAD"
493 return "fcmpq\t%0, %1, %2";
494 return "fcmpq\t%1, %2";
496 [(set_attr "type" "fpcmp")])
498 ;; Next come the scc insns. For seq, sne, sgeu, and sltu, we can do this
499 ;; without jumps using the addx/subx instructions. For seq/sne on v9 we use
500 ;; the same code as v8 (the addx/subx method has more applications). The
501 ;; exception to this is "reg != 0" which can be done in one instruction on v9
502 ;; (so we do it). For the rest, on v9 we use conditional moves; on v8, we do
505 ;; Seq_special[_xxx] and sne_special[_xxx] clobber the CC reg, because they
506 ;; generate addcc/subcc instructions.
508 (define_expand "seqsi_special"
510 (xor:SI (match_operand:SI 1 "register_operand" "")
511 (match_operand:SI 2 "register_operand" "")))
512 (parallel [(set (match_operand:SI 0 "register_operand" "")
513 (eq:SI (match_dup 3) (const_int 0)))
514 (clobber (reg:CC 100))])]
516 { operands[3] = gen_reg_rtx (SImode); })
518 (define_expand "seqdi_special"
520 (xor:DI (match_operand:DI 1 "register_operand" "")
521 (match_operand:DI 2 "register_operand" "")))
522 (set (match_operand:DI 0 "register_operand" "")
523 (eq:DI (match_dup 3) (const_int 0)))]
525 { operands[3] = gen_reg_rtx (DImode); })
527 (define_expand "snesi_special"
529 (xor:SI (match_operand:SI 1 "register_operand" "")
530 (match_operand:SI 2 "register_operand" "")))
531 (parallel [(set (match_operand:SI 0 "register_operand" "")
532 (ne:SI (match_dup 3) (const_int 0)))
533 (clobber (reg:CC 100))])]
535 { operands[3] = gen_reg_rtx (SImode); })
537 (define_expand "snedi_special"
539 (xor:DI (match_operand:DI 1 "register_operand" "")
540 (match_operand:DI 2 "register_operand" "")))
541 (set (match_operand:DI 0 "register_operand" "")
542 (ne:DI (match_dup 3) (const_int 0)))]
544 { operands[3] = gen_reg_rtx (DImode); })
546 (define_expand "seqdi_special_trunc"
548 (xor:DI (match_operand:DI 1 "register_operand" "")
549 (match_operand:DI 2 "register_operand" "")))
550 (set (match_operand:SI 0 "register_operand" "")
551 (eq:SI (match_dup 3) (const_int 0)))]
553 { operands[3] = gen_reg_rtx (DImode); })
555 (define_expand "snedi_special_trunc"
557 (xor:DI (match_operand:DI 1 "register_operand" "")
558 (match_operand:DI 2 "register_operand" "")))
559 (set (match_operand:SI 0 "register_operand" "")
560 (ne:SI (match_dup 3) (const_int 0)))]
562 { operands[3] = gen_reg_rtx (DImode); })
564 (define_expand "seqsi_special_extend"
566 (xor:SI (match_operand:SI 1 "register_operand" "")
567 (match_operand:SI 2 "register_operand" "")))
568 (parallel [(set (match_operand:DI 0 "register_operand" "")
569 (eq:DI (match_dup 3) (const_int 0)))
570 (clobber (reg:CC 100))])]
572 { operands[3] = gen_reg_rtx (SImode); })
574 (define_expand "snesi_special_extend"
576 (xor:SI (match_operand:SI 1 "register_operand" "")
577 (match_operand:SI 2 "register_operand" "")))
578 (parallel [(set (match_operand:DI 0 "register_operand" "")
579 (ne:DI (match_dup 3) (const_int 0)))
580 (clobber (reg:CC 100))])]
582 { operands[3] = gen_reg_rtx (SImode); })
584 ;; ??? v9: Operand 0 needs a mode, so SImode was chosen.
585 ;; However, the code handles both SImode and DImode.
587 [(set (match_operand:SI 0 "int_register_operand" "")
588 (eq:SI (match_dup 1) (const_int 0)))]
591 if (GET_MODE (sparc_compare_op0) == SImode)
595 if (GET_MODE (operands[0]) == SImode)
596 pat = gen_seqsi_special (operands[0], sparc_compare_op0,
598 else if (! TARGET_ARCH64)
601 pat = gen_seqsi_special_extend (operands[0], sparc_compare_op0,
606 else if (GET_MODE (sparc_compare_op0) == DImode)
612 else if (GET_MODE (operands[0]) == SImode)
613 pat = gen_seqdi_special_trunc (operands[0], sparc_compare_op0,
616 pat = gen_seqdi_special (operands[0], sparc_compare_op0,
621 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
623 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, EQ);
624 emit_jump_insn (gen_sne (operands[0]));
629 if (gen_v9_scc (EQ, operands))
636 ;; ??? v9: Operand 0 needs a mode, so SImode was chosen.
637 ;; However, the code handles both SImode and DImode.
639 [(set (match_operand:SI 0 "int_register_operand" "")
640 (ne:SI (match_dup 1) (const_int 0)))]
643 if (GET_MODE (sparc_compare_op0) == SImode)
647 if (GET_MODE (operands[0]) == SImode)
648 pat = gen_snesi_special (operands[0], sparc_compare_op0,
650 else if (! TARGET_ARCH64)
653 pat = gen_snesi_special_extend (operands[0], sparc_compare_op0,
658 else if (GET_MODE (sparc_compare_op0) == DImode)
664 else if (GET_MODE (operands[0]) == SImode)
665 pat = gen_snedi_special_trunc (operands[0], sparc_compare_op0,
668 pat = gen_snedi_special (operands[0], sparc_compare_op0,
673 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
675 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, NE);
676 emit_jump_insn (gen_sne (operands[0]));
681 if (gen_v9_scc (NE, operands))
689 [(set (match_operand:SI 0 "int_register_operand" "")
690 (gt:SI (match_dup 1) (const_int 0)))]
693 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
695 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GT);
696 emit_jump_insn (gen_sne (operands[0]));
701 if (gen_v9_scc (GT, operands))
709 [(set (match_operand:SI 0 "int_register_operand" "")
710 (lt:SI (match_dup 1) (const_int 0)))]
713 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
715 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LT);
716 emit_jump_insn (gen_sne (operands[0]));
721 if (gen_v9_scc (LT, operands))
729 [(set (match_operand:SI 0 "int_register_operand" "")
730 (ge:SI (match_dup 1) (const_int 0)))]
733 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
735 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GE);
736 emit_jump_insn (gen_sne (operands[0]));
741 if (gen_v9_scc (GE, operands))
749 [(set (match_operand:SI 0 "int_register_operand" "")
750 (le:SI (match_dup 1) (const_int 0)))]
753 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
755 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LE);
756 emit_jump_insn (gen_sne (operands[0]));
761 if (gen_v9_scc (LE, operands))
768 (define_expand "sgtu"
769 [(set (match_operand:SI 0 "int_register_operand" "")
770 (gtu:SI (match_dup 1) (const_int 0)))]
777 /* We can do ltu easily, so if both operands are registers, swap them and
779 if ((GET_CODE (sparc_compare_op0) == REG
780 || GET_CODE (sparc_compare_op0) == SUBREG)
781 && (GET_CODE (sparc_compare_op1) == REG
782 || GET_CODE (sparc_compare_op1) == SUBREG))
784 tem = sparc_compare_op0;
785 sparc_compare_op0 = sparc_compare_op1;
786 sparc_compare_op1 = tem;
787 pat = gen_sltu (operands[0]);
796 if (gen_v9_scc (GTU, operands))
802 (define_expand "sltu"
803 [(set (match_operand:SI 0 "int_register_operand" "")
804 (ltu:SI (match_dup 1) (const_int 0)))]
809 if (gen_v9_scc (LTU, operands))
812 operands[1] = gen_compare_reg (LTU);
815 (define_expand "sgeu"
816 [(set (match_operand:SI 0 "int_register_operand" "")
817 (geu:SI (match_dup 1) (const_int 0)))]
822 if (gen_v9_scc (GEU, operands))
825 operands[1] = gen_compare_reg (GEU);
828 (define_expand "sleu"
829 [(set (match_operand:SI 0 "int_register_operand" "")
830 (leu:SI (match_dup 1) (const_int 0)))]
837 /* We can do geu easily, so if both operands are registers, swap them and
839 if ((GET_CODE (sparc_compare_op0) == REG
840 || GET_CODE (sparc_compare_op0) == SUBREG)
841 && (GET_CODE (sparc_compare_op1) == REG
842 || GET_CODE (sparc_compare_op1) == SUBREG))
844 tem = sparc_compare_op0;
845 sparc_compare_op0 = sparc_compare_op1;
846 sparc_compare_op1 = tem;
847 pat = gen_sgeu (operands[0]);
856 if (gen_v9_scc (LEU, operands))
862 ;; Now the DEFINE_INSNs for the scc cases.
864 ;; The SEQ and SNE patterns are special because they can be done
865 ;; without any branching and do not involve a COMPARE. We want
866 ;; them to always use the splits below so the results can be
869 (define_insn_and_split "*snesi_zero"
870 [(set (match_operand:SI 0 "register_operand" "=r")
871 (ne:SI (match_operand:SI 1 "register_operand" "r")
873 (clobber (reg:CC 100))]
877 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
879 (set (match_dup 0) (ltu:SI (reg:CC 100) (const_int 0)))]
881 [(set_attr "length" "2")])
883 (define_insn_and_split "*neg_snesi_zero"
884 [(set (match_operand:SI 0 "register_operand" "=r")
885 (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
887 (clobber (reg:CC 100))]
891 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
893 (set (match_dup 0) (neg:SI (ltu:SI (reg:CC 100) (const_int 0))))]
895 [(set_attr "length" "2")])
897 (define_insn_and_split "*snesi_zero_extend"
898 [(set (match_operand:DI 0 "register_operand" "=r")
899 (ne:DI (match_operand:SI 1 "register_operand" "r")
901 (clobber (reg:CC 100))]
905 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (minus:SI (const_int 0)
908 (set (match_dup 0) (zero_extend:DI (plus:SI (plus:SI (const_int 0)
910 (ltu:SI (reg:CC_NOOV 100)
913 [(set_attr "length" "2")])
915 (define_insn_and_split "*snedi_zero"
916 [(set (match_operand:DI 0 "register_operand" "=&r")
917 (ne:DI (match_operand:DI 1 "register_operand" "r")
921 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
922 [(set (match_dup 0) (const_int 0))
923 (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
928 [(set_attr "length" "2")])
930 (define_insn_and_split "*neg_snedi_zero"
931 [(set (match_operand:DI 0 "register_operand" "=&r")
932 (neg:DI (ne:DI (match_operand:DI 1 "register_operand" "r")
936 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
937 [(set (match_dup 0) (const_int 0))
938 (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
943 [(set_attr "length" "2")])
945 (define_insn_and_split "*snedi_zero_trunc"
946 [(set (match_operand:SI 0 "register_operand" "=&r")
947 (ne:SI (match_operand:DI 1 "register_operand" "r")
951 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
952 [(set (match_dup 0) (const_int 0))
953 (set (match_dup 0) (if_then_else:SI (ne:DI (match_dup 1)
958 [(set_attr "length" "2")])
960 (define_insn_and_split "*seqsi_zero"
961 [(set (match_operand:SI 0 "register_operand" "=r")
962 (eq:SI (match_operand:SI 1 "register_operand" "r")
964 (clobber (reg:CC 100))]
968 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
970 (set (match_dup 0) (geu:SI (reg:CC 100) (const_int 0)))]
972 [(set_attr "length" "2")])
974 (define_insn_and_split "*neg_seqsi_zero"
975 [(set (match_operand:SI 0 "register_operand" "=r")
976 (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
978 (clobber (reg:CC 100))]
982 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
984 (set (match_dup 0) (neg:SI (geu:SI (reg:CC 100) (const_int 0))))]
986 [(set_attr "length" "2")])
988 (define_insn_and_split "*seqsi_zero_extend"
989 [(set (match_operand:DI 0 "register_operand" "=r")
990 (eq:DI (match_operand:SI 1 "register_operand" "r")
992 (clobber (reg:CC 100))]
996 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (minus:SI (const_int 0)
999 (set (match_dup 0) (zero_extend:DI (minus:SI (minus:SI (const_int 0)
1001 (ltu:SI (reg:CC_NOOV 100)
1004 [(set_attr "length" "2")])
1006 (define_insn_and_split "*seqdi_zero"
1007 [(set (match_operand:DI 0 "register_operand" "=&r")
1008 (eq:DI (match_operand:DI 1 "register_operand" "r")
1012 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
1013 [(set (match_dup 0) (const_int 0))
1014 (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
1019 [(set_attr "length" "2")])
1021 (define_insn_and_split "*neg_seqdi_zero"
1022 [(set (match_operand:DI 0 "register_operand" "=&r")
1023 (neg:DI (eq:DI (match_operand:DI 1 "register_operand" "r")
1027 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
1028 [(set (match_dup 0) (const_int 0))
1029 (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
1034 [(set_attr "length" "2")])
1036 (define_insn_and_split "*seqdi_zero_trunc"
1037 [(set (match_operand:SI 0 "register_operand" "=&r")
1038 (eq:SI (match_operand:DI 1 "register_operand" "r")
1042 "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
1043 [(set (match_dup 0) (const_int 0))
1044 (set (match_dup 0) (if_then_else:SI (eq:DI (match_dup 1)
1049 [(set_attr "length" "2")])
1051 ;; We can also do (x + (i == 0)) and related, so put them in.
1052 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1055 (define_insn_and_split "*x_plus_i_ne_0"
1056 [(set (match_operand:SI 0 "register_operand" "=r")
1057 (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
1059 (match_operand:SI 2 "register_operand" "r")))
1060 (clobber (reg:CC 100))]
1064 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1066 (set (match_dup 0) (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1069 [(set_attr "length" "2")])
1071 (define_insn_and_split "*x_minus_i_ne_0"
1072 [(set (match_operand:SI 0 "register_operand" "=r")
1073 (minus:SI (match_operand:SI 2 "register_operand" "r")
1074 (ne:SI (match_operand:SI 1 "register_operand" "r")
1076 (clobber (reg:CC 100))]
1080 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1082 (set (match_dup 0) (minus:SI (match_dup 2)
1083 (ltu:SI (reg:CC 100) (const_int 0))))]
1085 [(set_attr "length" "2")])
1087 (define_insn_and_split "*x_plus_i_eq_0"
1088 [(set (match_operand:SI 0 "register_operand" "=r")
1089 (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
1091 (match_operand:SI 2 "register_operand" "r")))
1092 (clobber (reg:CC 100))]
1096 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1098 (set (match_dup 0) (plus:SI (geu:SI (reg:CC 100) (const_int 0))
1101 [(set_attr "length" "2")])
1103 (define_insn_and_split "*x_minus_i_eq_0"
1104 [(set (match_operand:SI 0 "register_operand" "=r")
1105 (minus:SI (match_operand:SI 2 "register_operand" "r")
1106 (eq:SI (match_operand:SI 1 "register_operand" "r")
1108 (clobber (reg:CC 100))]
1112 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1114 (set (match_dup 0) (minus:SI (match_dup 2)
1115 (geu:SI (reg:CC 100) (const_int 0))))]
1117 [(set_attr "length" "2")])
1119 ;; We can also do GEU and LTU directly, but these operate after a compare.
1120 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1123 (define_insn "*sltu_insn"
1124 [(set (match_operand:SI 0 "register_operand" "=r")
1125 (ltu:SI (reg:CC 100) (const_int 0)))]
1128 [(set_attr "type" "ialuX")])
1130 (define_insn "*neg_sltu_insn"
1131 [(set (match_operand:SI 0 "register_operand" "=r")
1132 (neg:SI (ltu:SI (reg:CC 100) (const_int 0))))]
1135 [(set_attr "type" "ialuX")])
1137 ;; ??? Combine should canonicalize these next two to the same pattern.
1138 (define_insn "*neg_sltu_minus_x"
1139 [(set (match_operand:SI 0 "register_operand" "=r")
1140 (minus:SI (neg: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 "*neg_sltu_plus_x"
1147 [(set (match_operand:SI 0 "register_operand" "=r")
1148 (neg:SI (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1149 (match_operand:SI 1 "arith_operand" "rI"))))]
1151 "subx\t%%g0, %1, %0"
1152 [(set_attr "type" "ialuX")])
1154 (define_insn "*sgeu_insn"
1155 [(set (match_operand:SI 0 "register_operand" "=r")
1156 (geu:SI (reg:CC 100) (const_int 0)))]
1158 "subx\t%%g0, -1, %0"
1159 [(set_attr "type" "ialuX")])
1161 (define_insn "*neg_sgeu_insn"
1162 [(set (match_operand:SI 0 "register_operand" "=r")
1163 (neg:SI (geu:SI (reg:CC 100) (const_int 0))))]
1165 "addx\t%%g0, -1, %0"
1166 [(set_attr "type" "ialuX")])
1168 ;; We can also do (x + ((unsigned) i >= 0)) and related, so put them in.
1169 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1172 (define_insn "*sltu_plus_x"
1173 [(set (match_operand:SI 0 "register_operand" "=r")
1174 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1175 (match_operand:SI 1 "arith_operand" "rI")))]
1177 "addx\t%%g0, %1, %0"
1178 [(set_attr "type" "ialuX")])
1180 (define_insn "*sltu_plus_x_plus_y"
1181 [(set (match_operand:SI 0 "register_operand" "=r")
1182 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1183 (plus:SI (match_operand:SI 1 "arith_operand" "%r")
1184 (match_operand:SI 2 "arith_operand" "rI"))))]
1187 [(set_attr "type" "ialuX")])
1189 (define_insn "*x_minus_sltu"
1190 [(set (match_operand:SI 0 "register_operand" "=r")
1191 (minus:SI (match_operand:SI 1 "register_operand" "r")
1192 (ltu:SI (reg:CC 100) (const_int 0))))]
1195 [(set_attr "type" "ialuX")])
1197 ;; ??? Combine should canonicalize these next two to the same pattern.
1198 (define_insn "*x_minus_y_minus_sltu"
1199 [(set (match_operand:SI 0 "register_operand" "=r")
1200 (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
1201 (match_operand:SI 2 "arith_operand" "rI"))
1202 (ltu:SI (reg:CC 100) (const_int 0))))]
1205 [(set_attr "type" "ialuX")])
1207 (define_insn "*x_minus_sltu_plus_y"
1208 [(set (match_operand:SI 0 "register_operand" "=r")
1209 (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
1210 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1211 (match_operand:SI 2 "arith_operand" "rI"))))]
1214 [(set_attr "type" "ialuX")])
1216 (define_insn "*sgeu_plus_x"
1217 [(set (match_operand:SI 0 "register_operand" "=r")
1218 (plus:SI (geu:SI (reg:CC 100) (const_int 0))
1219 (match_operand:SI 1 "register_operand" "r")))]
1222 [(set_attr "type" "ialuX")])
1224 (define_insn "*x_minus_sgeu"
1225 [(set (match_operand:SI 0 "register_operand" "=r")
1226 (minus:SI (match_operand:SI 1 "register_operand" "r")
1227 (geu:SI (reg:CC 100) (const_int 0))))]
1230 [(set_attr "type" "ialuX")])
1233 [(set (match_operand:SI 0 "register_operand" "")
1234 (match_operator:SI 2 "noov_compare_operator"
1235 [(match_operand 1 "icc_or_fcc_register_operand" "")
1238 && REGNO (operands[1]) == SPARC_ICC_REG
1239 && (GET_MODE (operands[1]) == CCXmode
1240 /* 32 bit LTU/GEU are better implemented using addx/subx. */
1241 || (GET_CODE (operands[2]) != LTU && GET_CODE (operands[2]) != GEU))"
1242 [(set (match_dup 0) (const_int 0))
1244 (if_then_else:SI (match_op_dup:SI 2 [(match_dup 1) (const_int 0)])
1250 ;; These control RTL generation for conditional jump insns
1252 ;; The quad-word fp compare library routines all return nonzero to indicate
1253 ;; true, which is different from the equivalent libgcc routines, so we must
1254 ;; handle them specially here.
1256 (define_expand "beq"
1258 (if_then_else (eq (match_dup 1) (const_int 0))
1259 (label_ref (match_operand 0 "" ""))
1263 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1264 && GET_CODE (sparc_compare_op0) == REG
1265 && GET_MODE (sparc_compare_op0) == DImode)
1267 emit_v9_brxx_insn (EQ, sparc_compare_op0, operands[0]);
1270 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1272 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, EQ);
1273 emit_jump_insn (gen_bne (operands[0]));
1276 operands[1] = gen_compare_reg (EQ);
1279 (define_expand "bne"
1281 (if_then_else (ne (match_dup 1) (const_int 0))
1282 (label_ref (match_operand 0 "" ""))
1286 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1287 && GET_CODE (sparc_compare_op0) == REG
1288 && GET_MODE (sparc_compare_op0) == DImode)
1290 emit_v9_brxx_insn (NE, sparc_compare_op0, operands[0]);
1293 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1295 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, NE);
1296 emit_jump_insn (gen_bne (operands[0]));
1299 operands[1] = gen_compare_reg (NE);
1302 (define_expand "bgt"
1304 (if_then_else (gt (match_dup 1) (const_int 0))
1305 (label_ref (match_operand 0 "" ""))
1309 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1310 && GET_CODE (sparc_compare_op0) == REG
1311 && GET_MODE (sparc_compare_op0) == DImode)
1313 emit_v9_brxx_insn (GT, sparc_compare_op0, operands[0]);
1316 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1318 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GT);
1319 emit_jump_insn (gen_bne (operands[0]));
1322 operands[1] = gen_compare_reg (GT);
1325 (define_expand "bgtu"
1327 (if_then_else (gtu (match_dup 1) (const_int 0))
1328 (label_ref (match_operand 0 "" ""))
1332 operands[1] = gen_compare_reg (GTU);
1335 (define_expand "blt"
1337 (if_then_else (lt (match_dup 1) (const_int 0))
1338 (label_ref (match_operand 0 "" ""))
1342 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1343 && GET_CODE (sparc_compare_op0) == REG
1344 && GET_MODE (sparc_compare_op0) == DImode)
1346 emit_v9_brxx_insn (LT, sparc_compare_op0, operands[0]);
1349 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1351 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LT);
1352 emit_jump_insn (gen_bne (operands[0]));
1355 operands[1] = gen_compare_reg (LT);
1358 (define_expand "bltu"
1360 (if_then_else (ltu (match_dup 1) (const_int 0))
1361 (label_ref (match_operand 0 "" ""))
1365 operands[1] = gen_compare_reg (LTU);
1368 (define_expand "bge"
1370 (if_then_else (ge (match_dup 1) (const_int 0))
1371 (label_ref (match_operand 0 "" ""))
1375 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1376 && GET_CODE (sparc_compare_op0) == REG
1377 && GET_MODE (sparc_compare_op0) == DImode)
1379 emit_v9_brxx_insn (GE, sparc_compare_op0, operands[0]);
1382 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1384 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GE);
1385 emit_jump_insn (gen_bne (operands[0]));
1388 operands[1] = gen_compare_reg (GE);
1391 (define_expand "bgeu"
1393 (if_then_else (geu (match_dup 1) (const_int 0))
1394 (label_ref (match_operand 0 "" ""))
1398 operands[1] = gen_compare_reg (GEU);
1401 (define_expand "ble"
1403 (if_then_else (le (match_dup 1) (const_int 0))
1404 (label_ref (match_operand 0 "" ""))
1408 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1409 && GET_CODE (sparc_compare_op0) == REG
1410 && GET_MODE (sparc_compare_op0) == DImode)
1412 emit_v9_brxx_insn (LE, sparc_compare_op0, operands[0]);
1415 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1417 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LE);
1418 emit_jump_insn (gen_bne (operands[0]));
1421 operands[1] = gen_compare_reg (LE);
1424 (define_expand "bleu"
1426 (if_then_else (leu (match_dup 1) (const_int 0))
1427 (label_ref (match_operand 0 "" ""))
1431 operands[1] = gen_compare_reg (LEU);
1434 (define_expand "bunordered"
1436 (if_then_else (unordered (match_dup 1) (const_int 0))
1437 (label_ref (match_operand 0 "" ""))
1441 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1443 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1,
1445 emit_jump_insn (gen_beq (operands[0]));
1448 operands[1] = gen_compare_reg (UNORDERED);
1451 (define_expand "bordered"
1453 (if_then_else (ordered (match_dup 1) (const_int 0))
1454 (label_ref (match_operand 0 "" ""))
1458 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1460 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, ORDERED);
1461 emit_jump_insn (gen_bne (operands[0]));
1464 operands[1] = gen_compare_reg (ORDERED);
1467 (define_expand "bungt"
1469 (if_then_else (ungt (match_dup 1) (const_int 0))
1470 (label_ref (match_operand 0 "" ""))
1474 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1476 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNGT);
1477 emit_jump_insn (gen_bgt (operands[0]));
1480 operands[1] = gen_compare_reg (UNGT);
1483 (define_expand "bunlt"
1485 (if_then_else (unlt (match_dup 1) (const_int 0))
1486 (label_ref (match_operand 0 "" ""))
1490 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1492 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNLT);
1493 emit_jump_insn (gen_bne (operands[0]));
1496 operands[1] = gen_compare_reg (UNLT);
1499 (define_expand "buneq"
1501 (if_then_else (uneq (match_dup 1) (const_int 0))
1502 (label_ref (match_operand 0 "" ""))
1506 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1508 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNEQ);
1509 emit_jump_insn (gen_beq (operands[0]));
1512 operands[1] = gen_compare_reg (UNEQ);
1515 (define_expand "bunge"
1517 (if_then_else (unge (match_dup 1) (const_int 0))
1518 (label_ref (match_operand 0 "" ""))
1522 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1524 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNGE);
1525 emit_jump_insn (gen_bne (operands[0]));
1528 operands[1] = gen_compare_reg (UNGE);
1531 (define_expand "bunle"
1533 (if_then_else (unle (match_dup 1) (const_int 0))
1534 (label_ref (match_operand 0 "" ""))
1538 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1540 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNLE);
1541 emit_jump_insn (gen_bne (operands[0]));
1544 operands[1] = gen_compare_reg (UNLE);
1547 (define_expand "bltgt"
1549 (if_then_else (ltgt (match_dup 1) (const_int 0))
1550 (label_ref (match_operand 0 "" ""))
1554 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1556 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LTGT);
1557 emit_jump_insn (gen_bne (operands[0]));
1560 operands[1] = gen_compare_reg (LTGT);
1563 ;; Now match both normal and inverted jump.
1565 ;; XXX fpcmp nop braindamage
1566 (define_insn "*normal_branch"
1568 (if_then_else (match_operator 0 "noov_compare_operator"
1569 [(reg 100) (const_int 0)])
1570 (label_ref (match_operand 1 "" ""))
1574 return output_cbranch (operands[0], operands[1], 1, 0,
1575 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1578 [(set_attr "type" "branch")
1579 (set_attr "branch_type" "icc")])
1581 ;; XXX fpcmp nop braindamage
1582 (define_insn "*inverted_branch"
1584 (if_then_else (match_operator 0 "noov_compare_operator"
1585 [(reg 100) (const_int 0)])
1587 (label_ref (match_operand 1 "" ""))))]
1590 return output_cbranch (operands[0], operands[1], 1, 1,
1591 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1594 [(set_attr "type" "branch")
1595 (set_attr "branch_type" "icc")])
1597 ;; XXX fpcmp nop braindamage
1598 (define_insn "*normal_fp_branch"
1600 (if_then_else (match_operator 1 "comparison_operator"
1601 [(match_operand:CCFP 0 "fcc_register_operand" "c")
1603 (label_ref (match_operand 2 "" ""))
1607 return output_cbranch (operands[1], operands[2], 2, 0,
1608 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1611 [(set_attr "type" "branch")
1612 (set_attr "branch_type" "fcc")])
1614 ;; XXX fpcmp nop braindamage
1615 (define_insn "*inverted_fp_branch"
1617 (if_then_else (match_operator 1 "comparison_operator"
1618 [(match_operand:CCFP 0 "fcc_register_operand" "c")
1621 (label_ref (match_operand 2 "" ""))))]
1624 return output_cbranch (operands[1], operands[2], 2, 1,
1625 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1628 [(set_attr "type" "branch")
1629 (set_attr "branch_type" "fcc")])
1631 ;; XXX fpcmp nop braindamage
1632 (define_insn "*normal_fpe_branch"
1634 (if_then_else (match_operator 1 "comparison_operator"
1635 [(match_operand:CCFPE 0 "fcc_register_operand" "c")
1637 (label_ref (match_operand 2 "" ""))
1641 return output_cbranch (operands[1], operands[2], 2, 0,
1642 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1645 [(set_attr "type" "branch")
1646 (set_attr "branch_type" "fcc")])
1648 ;; XXX fpcmp nop braindamage
1649 (define_insn "*inverted_fpe_branch"
1651 (if_then_else (match_operator 1 "comparison_operator"
1652 [(match_operand:CCFPE 0 "fcc_register_operand" "c")
1655 (label_ref (match_operand 2 "" ""))))]
1658 return output_cbranch (operands[1], operands[2], 2, 1,
1659 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1662 [(set_attr "type" "branch")
1663 (set_attr "branch_type" "fcc")])
1665 ;; SPARC V9-specific jump insns. None of these are guaranteed to be
1666 ;; in the architecture.
1668 ;; There are no 32 bit brreg insns.
1671 (define_insn "*normal_int_branch_sp64"
1673 (if_then_else (match_operator 0 "v9_register_compare_operator"
1674 [(match_operand:DI 1 "register_operand" "r")
1676 (label_ref (match_operand 2 "" ""))
1680 return output_v9branch (operands[0], operands[2], 1, 2, 0,
1681 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1684 [(set_attr "type" "branch")
1685 (set_attr "branch_type" "reg")])
1688 (define_insn "*inverted_int_branch_sp64"
1690 (if_then_else (match_operator 0 "v9_register_compare_operator"
1691 [(match_operand:DI 1 "register_operand" "r")
1694 (label_ref (match_operand 2 "" ""))))]
1697 return output_v9branch (operands[0], operands[2], 1, 2, 1,
1698 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1701 [(set_attr "type" "branch")
1702 (set_attr "branch_type" "reg")])
1705 (define_mode_macro P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
1707 ;; Load in operand 0 the (absolute) address of operand 1, which is a symbolic
1708 ;; value subject to a PC-relative relocation. Operand 2 is a helper function
1709 ;; that adds the PC value at the call point to operand 0.
1711 (define_insn "load_pcrel_sym<P:mode>"
1712 [(set (match_operand:P 0 "register_operand" "=r")
1713 (unspec:P [(match_operand:P 1 "symbolic_operand" "")
1714 (match_operand:P 2 "call_address_operand" "")] UNSPEC_LOAD_PCREL_SYM))
1715 (clobber (reg:P 15))]
1718 if (flag_delayed_branch)
1719 return "sethi\t%%hi(%a1-4), %0\n\tcall\t%a2\n\t add\t%0, %%lo(%a1+4), %0";
1721 return "sethi\t%%hi(%a1-8), %0\n\tadd\t%0, %%lo(%a1-4), %0\n\tcall\t%a2\n\t nop";
1723 [(set (attr "type") (const_string "multi"))
1724 (set (attr "length")
1725 (if_then_else (eq_attr "delayed_branch" "true")
1730 ;; Integer move instructions
1732 (define_expand "movqi"
1733 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1734 (match_operand:QI 1 "general_operand" ""))]
1737 if (sparc_expand_move (QImode, operands))
1741 (define_insn "*movqi_insn"
1742 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m")
1743 (match_operand:QI 1 "input_operand" "rI,m,rJ"))]
1744 "(register_operand (operands[0], QImode)
1745 || register_or_zero_operand (operands[1], QImode))"
1750 [(set_attr "type" "*,load,store")
1751 (set_attr "us3load_type" "*,3cycle,*")])
1753 (define_expand "movhi"
1754 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1755 (match_operand:HI 1 "general_operand" ""))]
1758 if (sparc_expand_move (HImode, operands))
1762 (define_insn "*movhi_insn"
1763 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1764 (match_operand:HI 1 "input_operand" "rI,K,m,rJ"))]
1765 "(register_operand (operands[0], HImode)
1766 || register_or_zero_operand (operands[1], HImode))"
1769 sethi\t%%hi(%a1), %0
1772 [(set_attr "type" "*,*,load,store")
1773 (set_attr "us3load_type" "*,*,3cycle,*")])
1775 ;; We always work with constants here.
1776 (define_insn "*movhi_lo_sum"
1777 [(set (match_operand:HI 0 "register_operand" "=r")
1778 (ior:HI (match_operand:HI 1 "register_operand" "%r")
1779 (match_operand:HI 2 "small_int_operand" "I")))]
1783 (define_expand "movsi"
1784 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1785 (match_operand:SI 1 "general_operand" ""))]
1788 if (sparc_expand_move (SImode, operands))
1792 (define_insn "*movsi_insn"
1793 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,m,!f,!f,!m,d")
1794 (match_operand:SI 1 "input_operand" "rI,K,m,rJ,f,m,f,J"))]
1795 "(register_operand (operands[0], SImode)
1796 || register_or_zero_operand (operands[1], SImode))"
1799 sethi\t%%hi(%a1), %0
1806 [(set_attr "type" "*,*,load,store,fpmove,fpload,fpstore,fga")])
1808 (define_insn "*movsi_lo_sum"
1809 [(set (match_operand:SI 0 "register_operand" "=r")
1810 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1811 (match_operand:SI 2 "immediate_operand" "in")))]
1813 "or\t%1, %%lo(%a2), %0")
1815 (define_insn "*movsi_high"
1816 [(set (match_operand:SI 0 "register_operand" "=r")
1817 (high:SI (match_operand:SI 1 "immediate_operand" "in")))]
1819 "sethi\t%%hi(%a1), %0")
1821 ;; The next two patterns must wrap the SYMBOL_REF in an UNSPEC
1822 ;; so that CSE won't optimize the address computation away.
1823 (define_insn "movsi_lo_sum_pic"
1824 [(set (match_operand:SI 0 "register_operand" "=r")
1825 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1826 (unspec:SI [(match_operand:SI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
1828 "or\t%1, %%lo(%a2), %0")
1830 (define_insn "movsi_high_pic"
1831 [(set (match_operand:SI 0 "register_operand" "=r")
1832 (high:SI (unspec:SI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
1833 "flag_pic && check_pic (1)"
1834 "sethi\t%%hi(%a1), %0")
1836 (define_expand "movsi_pic_label_ref"
1837 [(set (match_dup 3) (high:SI
1838 (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
1839 (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1840 (set (match_dup 4) (lo_sum:SI (match_dup 3)
1841 (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1842 (set (match_operand:SI 0 "register_operand" "=r")
1843 (minus:SI (match_dup 5) (match_dup 4)))]
1846 current_function_uses_pic_offset_table = 1;
1847 operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
1850 operands[3] = operands[0];
1851 operands[4] = operands[0];
1855 operands[3] = gen_reg_rtx (SImode);
1856 operands[4] = gen_reg_rtx (SImode);
1858 operands[5] = pic_offset_table_rtx;
1861 (define_insn "*movsi_high_pic_label_ref"
1862 [(set (match_operand:SI 0 "register_operand" "=r")
1864 (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
1865 (match_operand:SI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1867 "sethi\t%%hi(%a2-(%a1-.)), %0")
1869 (define_insn "*movsi_lo_sum_pic_label_ref"
1870 [(set (match_operand:SI 0 "register_operand" "=r")
1871 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1872 (unspec:SI [(match_operand:SI 2 "label_ref_operand" "")
1873 (match_operand:SI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1875 "or\t%1, %%lo(%a3-(%a2-.)), %0")
1877 (define_expand "movdi"
1878 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1879 (match_operand:DI 1 "general_operand" ""))]
1882 if (sparc_expand_move (DImode, operands))
1886 ;; Be careful, fmovd does not exist when !v9.
1887 ;; We match MEM moves directly when we have correct even
1888 ;; numbered registers, but fall into splits otherwise.
1889 ;; The constraint ordering here is really important to
1890 ;; avoid insane problems in reload, especially for patterns
1893 ;; (set (mem:DI (plus:SI (reg:SI 30 %fp)
1894 ;; (const_int -5016)))
1898 (define_insn "*movdi_insn_sp32"
1899 [(set (match_operand:DI 0 "nonimmediate_operand"
1900 "=o,T,U,o,r,r,r,?T,?f,?f,?o,?f")
1901 (match_operand:DI 1 "input_operand"
1902 " J,U,T,r,o,i,r, f, T, o, f, f"))]
1904 && (register_operand (operands[0], DImode)
1905 || register_or_zero_operand (operands[1], DImode))"
1919 [(set_attr "type" "store,store,load,*,*,*,*,fpstore,fpload,*,*,*")
1920 (set_attr "length" "2,*,*,2,2,2,2,*,*,2,2,2")])
1922 (define_insn "*movdi_insn_sp32_v9"
1923 [(set (match_operand:DI 0 "nonimmediate_operand"
1924 "=T,o,T,U,o,r,r,r,?T,?f,?f,?o,?e,?e,?W")
1925 (match_operand:DI 1 "input_operand"
1926 " J,J,U,T,r,o,i,r, f, T, o, f, e, W, e"))]
1929 && (register_operand (operands[0], DImode)
1930 || register_or_zero_operand (operands[1], DImode))"
1947 [(set_attr "type" "store,store,store,load,*,*,*,*,fpstore,fpload,*,*,fpmove,fpload,fpstore")
1948 (set_attr "length" "*,2,*,*,2,2,2,2,*,*,2,2,*,*,*")
1949 (set_attr "fptype" "*,*,*,*,*,*,*,*,*,*,*,*,double,*,*")])
1951 (define_insn "*movdi_insn_sp64"
1952 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,m,?e,?e,?W,b")
1953 (match_operand:DI 1 "input_operand" "rI,N,m,rJ,e,W,e,J"))]
1955 && (register_operand (operands[0], DImode)
1956 || register_or_zero_operand (operands[1], DImode))"
1959 sethi\t%%hi(%a1), %0
1966 [(set_attr "type" "*,*,load,store,fpmove,fpload,fpstore,fga")
1967 (set_attr "fptype" "*,*,*,*,double,*,*,double")])
1969 (define_expand "movdi_pic_label_ref"
1970 [(set (match_dup 3) (high:DI
1971 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
1972 (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1973 (set (match_dup 4) (lo_sum:DI (match_dup 3)
1974 (unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1975 (set (match_operand:DI 0 "register_operand" "=r")
1976 (minus:DI (match_dup 5) (match_dup 4)))]
1977 "TARGET_ARCH64 && flag_pic"
1979 current_function_uses_pic_offset_table = 1;
1980 operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
1983 operands[3] = operands[0];
1984 operands[4] = operands[0];
1988 operands[3] = gen_reg_rtx (DImode);
1989 operands[4] = gen_reg_rtx (DImode);
1991 operands[5] = pic_offset_table_rtx;
1994 (define_insn "*movdi_high_pic_label_ref"
1995 [(set (match_operand:DI 0 "register_operand" "=r")
1997 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
1998 (match_operand:DI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1999 "TARGET_ARCH64 && flag_pic"
2000 "sethi\t%%hi(%a2-(%a1-.)), %0")
2002 (define_insn "*movdi_lo_sum_pic_label_ref"
2003 [(set (match_operand:DI 0 "register_operand" "=r")
2004 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2005 (unspec:DI [(match_operand:DI 2 "label_ref_operand" "")
2006 (match_operand:DI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
2007 "TARGET_ARCH64 && flag_pic"
2008 "or\t%1, %%lo(%a3-(%a2-.)), %0")
2010 ;; SPARC-v9 code model support insns. See sparc_emit_set_symbolic_const64
2011 ;; in sparc.c to see what is going on here... PIC stuff comes first.
2013 (define_insn "movdi_lo_sum_pic"
2014 [(set (match_operand:DI 0 "register_operand" "=r")
2015 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2016 (unspec:DI [(match_operand:DI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
2017 "TARGET_ARCH64 && flag_pic"
2018 "or\t%1, %%lo(%a2), %0")
2020 (define_insn "movdi_high_pic"
2021 [(set (match_operand:DI 0 "register_operand" "=r")
2022 (high:DI (unspec:DI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
2023 "TARGET_ARCH64 && flag_pic && check_pic (1)"
2024 "sethi\t%%hi(%a1), %0")
2026 (define_insn "*sethi_di_medlow_embmedany_pic"
2027 [(set (match_operand:DI 0 "register_operand" "=r")
2028 (high:DI (match_operand:DI 1 "medium_pic_operand" "")))]
2029 "(TARGET_CM_MEDLOW || TARGET_CM_EMBMEDANY) && check_pic (1)"
2030 "sethi\t%%hi(%a1), %0")
2032 (define_insn "*sethi_di_medlow"
2033 [(set (match_operand:DI 0 "register_operand" "=r")
2034 (high:DI (match_operand:DI 1 "symbolic_operand" "")))]
2035 "TARGET_CM_MEDLOW && check_pic (1)"
2036 "sethi\t%%hi(%a1), %0")
2038 (define_insn "*losum_di_medlow"
2039 [(set (match_operand:DI 0 "register_operand" "=r")
2040 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2041 (match_operand:DI 2 "symbolic_operand" "")))]
2043 "or\t%1, %%lo(%a2), %0")
2045 (define_insn "seth44"
2046 [(set (match_operand:DI 0 "register_operand" "=r")
2047 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETH44)))]
2049 "sethi\t%%h44(%a1), %0")
2051 (define_insn "setm44"
2052 [(set (match_operand:DI 0 "register_operand" "=r")
2053 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2054 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_SETM44)))]
2056 "or\t%1, %%m44(%a2), %0")
2058 (define_insn "setl44"
2059 [(set (match_operand:DI 0 "register_operand" "=r")
2060 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2061 (match_operand:DI 2 "symbolic_operand" "")))]
2063 "or\t%1, %%l44(%a2), %0")
2065 (define_insn "sethh"
2066 [(set (match_operand:DI 0 "register_operand" "=r")
2067 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETHH)))]
2069 "sethi\t%%hh(%a1), %0")
2071 (define_insn "setlm"
2072 [(set (match_operand:DI 0 "register_operand" "=r")
2073 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETLM)))]
2075 "sethi\t%%lm(%a1), %0")
2077 (define_insn "sethm"
2078 [(set (match_operand:DI 0 "register_operand" "=r")
2079 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2080 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_EMB_SETHM)))]
2082 "or\t%1, %%hm(%a2), %0")
2084 (define_insn "setlo"
2085 [(set (match_operand:DI 0 "register_operand" "=r")
2086 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2087 (match_operand:DI 2 "symbolic_operand" "")))]
2089 "or\t%1, %%lo(%a2), %0")
2091 (define_insn "embmedany_sethi"
2092 [(set (match_operand:DI 0 "register_operand" "=r")
2093 (high:DI (unspec:DI [(match_operand:DI 1 "data_segment_operand" "")] UNSPEC_EMB_HISUM)))]
2094 "TARGET_CM_EMBMEDANY && check_pic (1)"
2095 "sethi\t%%hi(%a1), %0")
2097 (define_insn "embmedany_losum"
2098 [(set (match_operand:DI 0 "register_operand" "=r")
2099 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2100 (match_operand:DI 2 "data_segment_operand" "")))]
2101 "TARGET_CM_EMBMEDANY"
2102 "add\t%1, %%lo(%a2), %0")
2104 (define_insn "embmedany_brsum"
2105 [(set (match_operand:DI 0 "register_operand" "=r")
2106 (unspec:DI [(match_operand:DI 1 "register_operand" "r")] UNSPEC_EMB_HISUM))]
2107 "TARGET_CM_EMBMEDANY"
2110 (define_insn "embmedany_textuhi"
2111 [(set (match_operand:DI 0 "register_operand" "=r")
2112 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTUHI)))]
2113 "TARGET_CM_EMBMEDANY && check_pic (1)"
2114 "sethi\t%%uhi(%a1), %0")
2116 (define_insn "embmedany_texthi"
2117 [(set (match_operand:DI 0 "register_operand" "=r")
2118 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTHI)))]
2119 "TARGET_CM_EMBMEDANY && check_pic (1)"
2120 "sethi\t%%hi(%a1), %0")
2122 (define_insn "embmedany_textulo"
2123 [(set (match_operand:DI 0 "register_operand" "=r")
2124 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2125 (unspec:DI [(match_operand:DI 2 "text_segment_operand" "")] UNSPEC_EMB_TEXTULO)))]
2126 "TARGET_CM_EMBMEDANY"
2127 "or\t%1, %%ulo(%a2), %0")
2129 (define_insn "embmedany_textlo"
2130 [(set (match_operand:DI 0 "register_operand" "=r")
2131 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2132 (match_operand:DI 2 "text_segment_operand" "")))]
2133 "TARGET_CM_EMBMEDANY"
2134 "or\t%1, %%lo(%a2), %0")
2136 ;; Now some patterns to help reload out a bit.
2137 (define_expand "reload_indi"
2138 [(parallel [(match_operand:DI 0 "register_operand" "=r")
2139 (match_operand:DI 1 "immediate_operand" "")
2140 (match_operand:TI 2 "register_operand" "=&r")])]
2142 || TARGET_CM_EMBMEDANY)
2145 sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
2149 (define_expand "reload_outdi"
2150 [(parallel [(match_operand:DI 0 "register_operand" "=r")
2151 (match_operand:DI 1 "immediate_operand" "")
2152 (match_operand:TI 2 "register_operand" "=&r")])]
2154 || TARGET_CM_EMBMEDANY)
2157 sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
2161 ;; Split up putting CONSTs and REGs into DI regs when !arch64
2163 [(set (match_operand:DI 0 "register_operand" "")
2164 (match_operand:DI 1 "const_int_operand" ""))]
2165 "! TARGET_ARCH64 && reload_completed"
2166 [(clobber (const_int 0))]
2168 #if HOST_BITS_PER_WIDE_INT == 32
2169 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
2170 (INTVAL (operands[1]) < 0) ?
2173 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2176 unsigned int low, high;
2178 low = trunc_int_for_mode (INTVAL (operands[1]), SImode);
2179 high = trunc_int_for_mode (INTVAL (operands[1]) >> 32, SImode);
2180 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), GEN_INT (high)));
2182 /* Slick... but this trick loses if this subreg constant part
2183 can be done in one insn. */
2185 && ! SPARC_SETHI32_P (high)
2186 && ! SPARC_SIMM13_P (high))
2187 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2188 gen_highpart (SImode, operands[0])));
2190 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), GEN_INT (low)));
2196 [(set (match_operand:DI 0 "register_operand" "")
2197 (match_operand:DI 1 "const_double_operand" ""))]
2201 && ((GET_CODE (operands[0]) == REG
2202 && REGNO (operands[0]) < 32)
2203 || (GET_CODE (operands[0]) == SUBREG
2204 && GET_CODE (SUBREG_REG (operands[0])) == REG
2205 && REGNO (SUBREG_REG (operands[0])) < 32))))"
2206 [(clobber (const_int 0))]
2208 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
2209 GEN_INT (CONST_DOUBLE_HIGH (operands[1]))));
2211 /* Slick... but this trick loses if this subreg constant part
2212 can be done in one insn. */
2213 if (CONST_DOUBLE_LOW (operands[1]) == CONST_DOUBLE_HIGH (operands[1])
2214 && ! SPARC_SETHI32_P (CONST_DOUBLE_HIGH (operands[1]))
2215 && ! SPARC_SIMM13_P (CONST_DOUBLE_HIGH (operands[1])))
2217 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2218 gen_highpart (SImode, operands[0])));
2222 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2223 GEN_INT (CONST_DOUBLE_LOW (operands[1]))));
2229 [(set (match_operand:DI 0 "register_operand" "")
2230 (match_operand:DI 1 "register_operand" ""))]
2234 && ((GET_CODE (operands[0]) == REG
2235 && REGNO (operands[0]) < 32)
2236 || (GET_CODE (operands[0]) == SUBREG
2237 && GET_CODE (SUBREG_REG (operands[0])) == REG
2238 && REGNO (SUBREG_REG (operands[0])) < 32))))"
2239 [(clobber (const_int 0))]
2241 rtx set_dest = operands[0];
2242 rtx set_src = operands[1];
2246 dest1 = gen_highpart (SImode, set_dest);
2247 dest2 = gen_lowpart (SImode, set_dest);
2248 src1 = gen_highpart (SImode, set_src);
2249 src2 = gen_lowpart (SImode, set_src);
2251 /* Now emit using the real source and destination we found, swapping
2252 the order if we detect overlap. */
2253 if (reg_overlap_mentioned_p (dest1, src2))
2255 emit_insn (gen_movsi (dest2, src2));
2256 emit_insn (gen_movsi (dest1, src1));
2260 emit_insn (gen_movsi (dest1, src1));
2261 emit_insn (gen_movsi (dest2, src2));
2266 ;; Now handle the cases of memory moves from/to non-even
2267 ;; DI mode register pairs.
2269 [(set (match_operand:DI 0 "register_operand" "")
2270 (match_operand:DI 1 "memory_operand" ""))]
2273 && sparc_splitdi_legitimate (operands[0], operands[1]))"
2274 [(clobber (const_int 0))]
2276 rtx word0 = adjust_address (operands[1], SImode, 0);
2277 rtx word1 = adjust_address (operands[1], SImode, 4);
2278 rtx high_part = gen_highpart (SImode, operands[0]);
2279 rtx low_part = gen_lowpart (SImode, operands[0]);
2281 if (reg_overlap_mentioned_p (high_part, word1))
2283 emit_insn (gen_movsi (low_part, word1));
2284 emit_insn (gen_movsi (high_part, word0));
2288 emit_insn (gen_movsi (high_part, word0));
2289 emit_insn (gen_movsi (low_part, word1));
2295 [(set (match_operand:DI 0 "memory_operand" "")
2296 (match_operand:DI 1 "register_operand" ""))]
2299 && sparc_splitdi_legitimate (operands[1], operands[0]))"
2300 [(clobber (const_int 0))]
2302 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0),
2303 gen_highpart (SImode, operands[1])));
2304 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4),
2305 gen_lowpart (SImode, operands[1])));
2310 [(set (match_operand:DI 0 "memory_operand" "")
2311 (match_operand:DI 1 "const_zero_operand" ""))]
2315 && ! mem_min_alignment (operands[0], 8)))
2316 && offsettable_memref_p (operands[0])"
2317 [(clobber (const_int 0))]
2319 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0), const0_rtx));
2320 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4), const0_rtx));
2325 ;; Floating point and vector move instructions
2327 ;; We don't define V1SI because SI should work just fine.
2328 (define_mode_macro V32 [SF V2HI V4QI])
2330 ;; Yes, you guessed it right, the former movsf expander.
2331 (define_expand "mov<V32:mode>"
2332 [(set (match_operand:V32 0 "nonimmediate_operand" "")
2333 (match_operand:V32 1 "general_operand" ""))]
2334 "<V32:MODE>mode == SFmode || TARGET_VIS"
2336 if (sparc_expand_move (<V32:MODE>mode, operands))
2340 (define_insn "*movsf_insn"
2341 [(set (match_operand:V32 0 "nonimmediate_operand" "=d,f,*r,*r,*r,f,*r,m,m")
2342 (match_operand:V32 1 "input_operand" "GY,f,*rRY,Q,S,m,m,f,*rGY"))]
2344 && (register_operand (operands[0], <V32:MODE>mode)
2345 || register_or_zero_operand (operands[1], <V32:MODE>mode))"
2347 if (GET_CODE (operands[1]) == CONST_DOUBLE
2348 && (which_alternative == 2
2349 || which_alternative == 3
2350 || which_alternative == 4))
2355 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2356 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2357 operands[1] = GEN_INT (i);
2360 switch (which_alternative)
2363 return "fzeros\t%0";
2365 return "fmovs\t%1, %0";
2367 return "mov\t%1, %0";
2369 return "sethi\t%%hi(%a1), %0";
2374 return "ld\t%1, %0";
2377 return "st\t%r1, %0";
2382 [(set_attr "type" "fga,fpmove,*,*,*,fpload,load,fpstore,store")])
2384 ;; Exactly the same as above, except that all `f' cases are deleted.
2385 ;; This is necessary to prevent reload from ever trying to use a `f' reg
2388 (define_insn "*movsf_insn_no_fpu"
2389 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r,r,m")
2390 (match_operand:SF 1 "input_operand" "rR,Q,S,m,rG"))]
2392 && (register_operand (operands[0], SFmode)
2393 || register_or_zero_operand (operands[1], SFmode))"
2395 if (GET_CODE (operands[1]) == CONST_DOUBLE
2396 && (which_alternative == 0
2397 || which_alternative == 1
2398 || which_alternative == 2))
2403 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2404 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2405 operands[1] = GEN_INT (i);
2408 switch (which_alternative)
2411 return "mov\t%1, %0";
2413 return "sethi\t%%hi(%a1), %0";
2417 return "ld\t%1, %0";
2419 return "st\t%r1, %0";
2424 [(set_attr "type" "*,*,*,load,store")])
2426 ;; The following 3 patterns build SFmode constants in integer registers.
2428 (define_insn "*movsf_lo_sum"
2429 [(set (match_operand:SF 0 "register_operand" "=r")
2430 (lo_sum:SF (match_operand:SF 1 "register_operand" "r")
2431 (match_operand:SF 2 "fp_const_high_losum_operand" "S")))]
2437 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[2]);
2438 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2439 operands[2] = GEN_INT (i);
2440 return "or\t%1, %%lo(%a2), %0";
2443 (define_insn "*movsf_high"
2444 [(set (match_operand:SF 0 "register_operand" "=r")
2445 (high:SF (match_operand:SF 1 "fp_const_high_losum_operand" "S")))]
2451 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2452 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2453 operands[1] = GEN_INT (i);
2454 return "sethi\t%%hi(%1), %0";
2458 [(set (match_operand:SF 0 "register_operand" "")
2459 (match_operand:SF 1 "fp_const_high_losum_operand" ""))]
2460 "REG_P (operands[0]) && REGNO (operands[0]) < 32"
2461 [(set (match_dup 0) (high:SF (match_dup 1)))
2462 (set (match_dup 0) (lo_sum:SF (match_dup 0) (match_dup 1)))])
2464 (define_mode_macro V64 [DF V2SI V4HI V8QI])
2466 ;; Yes, you again guessed it right, the former movdf expander.
2467 (define_expand "mov<V64:mode>"
2468 [(set (match_operand:V64 0 "nonimmediate_operand" "")
2469 (match_operand:V64 1 "general_operand" ""))]
2470 "<V64:MODE>mode == DFmode || TARGET_VIS"
2472 if (sparc_expand_move (<V64:MODE>mode, operands))
2476 ;; Be careful, fmovd does not exist when !v9.
2477 (define_insn "*movdf_insn_sp32"
2478 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,W,U,T,o,e,*r,o,e,o")
2479 (match_operand:DF 1 "input_operand" "W#F,e,T,U,G,e,*rFo,*r,o#F,e"))]
2482 && (register_operand (operands[0], DFmode)
2483 || register_or_zero_operand (operands[1], DFmode))"
2495 [(set_attr "type" "fpload,fpstore,load,store,*,*,*,*,*,*")
2496 (set_attr "length" "*,*,*,*,2,2,2,2,2,2")])
2498 (define_insn "*movdf_insn_sp32_no_fpu"
2499 [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,o,r,o")
2500 (match_operand:DF 1 "input_operand" "T,U,G,ro,r"))]
2503 && (register_operand (operands[0], DFmode)
2504 || register_or_zero_operand (operands[1], DFmode))"
2511 [(set_attr "type" "load,store,*,*,*")
2512 (set_attr "length" "*,*,2,2,2")])
2514 ;; We have available v9 double floats but not 64-bit integer registers.
2515 (define_insn "*movdf_insn_sp32_v9"
2516 [(set (match_operand:V64 0 "nonimmediate_operand" "=b,e,e,T,W,U,T,f,*r,o")
2517 (match_operand:V64 1 "input_operand" "GY,e,W#F,GY,e,T,U,o#F,*roGYF,*rGYf"))]
2521 && (register_operand (operands[0], <V64:MODE>mode)
2522 || register_or_zero_operand (operands[1], <V64:MODE>mode))"
2534 [(set_attr "type" "fga,fpmove,load,store,store,load,store,*,*,*")
2535 (set_attr "length" "*,*,*,*,*,*,*,2,2,2")
2536 (set_attr "fptype" "double,double,*,*,*,*,*,*,*,*")])
2538 (define_insn "*movdf_insn_sp32_v9_no_fpu"
2539 [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,T,r,o")
2540 (match_operand:DF 1 "input_operand" "T,U,G,ro,rG"))]
2544 && (register_operand (operands[0], DFmode)
2545 || register_or_zero_operand (operands[1], DFmode))"
2552 [(set_attr "type" "load,store,store,*,*")
2553 (set_attr "length" "*,*,*,2,2")])
2555 ;; We have available both v9 double floats and 64-bit integer registers.
2556 (define_insn "*movdf_insn_sp64"
2557 [(set (match_operand:V64 0 "nonimmediate_operand" "=b,e,e,W,*r,*r,m,*r")
2558 (match_operand:V64 1 "input_operand" "GY,e,W#F,e,*rGY,m,*rGY,F"))]
2561 && (register_operand (operands[0], <V64:MODE>mode)
2562 || register_or_zero_operand (operands[1], <V64:MODE>mode))"
2572 [(set_attr "type" "fga,fpmove,load,store,*,load,store,*")
2573 (set_attr "length" "*,*,*,*,*,*,*,2")
2574 (set_attr "fptype" "double,double,*,*,*,*,*,*")])
2576 (define_insn "*movdf_insn_sp64_no_fpu"
2577 [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m")
2578 (match_operand:DF 1 "input_operand" "r,m,rG"))]
2581 && (register_operand (operands[0], DFmode)
2582 || register_or_zero_operand (operands[1], DFmode))"
2587 [(set_attr "type" "*,load,store")])
2589 ;; This pattern build DFmode constants in integer registers.
2591 [(set (match_operand:DF 0 "register_operand" "")
2592 (match_operand:DF 1 "const_double_operand" ""))]
2594 && (GET_CODE (operands[0]) == REG
2595 && REGNO (operands[0]) < 32)
2596 && ! const_zero_operand(operands[1], DFmode)
2597 && reload_completed"
2598 [(clobber (const_int 0))]
2603 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2604 REAL_VALUE_TO_TARGET_DOUBLE (r, l);
2605 operands[0] = gen_rtx_raw_REG (DImode, REGNO (operands[0]));
2609 #if HOST_BITS_PER_WIDE_INT == 32
2614 val = ((HOST_WIDE_INT)(unsigned long)l[1] |
2615 ((HOST_WIDE_INT)(unsigned long)l[0] << 32));
2616 emit_insn (gen_movdi (operands[0], gen_int_mode (val, DImode)));
2621 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
2622 gen_int_mode (l[0], SImode)));
2624 /* Slick... but this trick loses if this subreg constant part
2625 can be done in one insn. */
2627 && ! SPARC_SETHI32_P (l[0])
2628 && ! SPARC_SIMM13_P (l[0]))
2630 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2631 gen_highpart (SImode, operands[0])));
2635 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2636 gen_int_mode (l[1], SImode)));
2642 ;; Ok, now the splits to handle all the multi insn and
2643 ;; mis-aligned memory address cases.
2644 ;; In these splits please take note that we must be
2645 ;; careful when V9 but not ARCH64 because the integer
2646 ;; register DFmode cases must be handled.
2648 [(set (match_operand:V64 0 "register_operand" "")
2649 (match_operand:V64 1 "register_operand" ""))]
2652 && ((GET_CODE (operands[0]) == REG
2653 && REGNO (operands[0]) < 32)
2654 || (GET_CODE (operands[0]) == SUBREG
2655 && GET_CODE (SUBREG_REG (operands[0])) == REG
2656 && REGNO (SUBREG_REG (operands[0])) < 32))))
2657 && reload_completed"
2658 [(clobber (const_int 0))]
2660 rtx set_dest = operands[0];
2661 rtx set_src = operands[1];
2664 enum machine_mode half_mode;
2666 /* We can be expanded for DFmode or integral vector modes. */
2667 if (<V64:MODE>mode == DFmode)
2672 dest1 = gen_highpart (half_mode, set_dest);
2673 dest2 = gen_lowpart (half_mode, set_dest);
2674 src1 = gen_highpart (half_mode, set_src);
2675 src2 = gen_lowpart (half_mode, set_src);
2677 /* Now emit using the real source and destination we found, swapping
2678 the order if we detect overlap. */
2679 if (reg_overlap_mentioned_p (dest1, src2))
2681 emit_move_insn_1 (dest2, src2);
2682 emit_move_insn_1 (dest1, src1);
2686 emit_move_insn_1 (dest1, src1);
2687 emit_move_insn_1 (dest2, src2);
2693 [(set (match_operand:V64 0 "register_operand" "")
2694 (match_operand:V64 1 "memory_operand" ""))]
2697 && (((REGNO (operands[0]) % 2) != 0)
2698 || ! mem_min_alignment (operands[1], 8))
2699 && offsettable_memref_p (operands[1])"
2700 [(clobber (const_int 0))]
2702 enum machine_mode half_mode;
2705 /* We can be expanded for DFmode or integral vector modes. */
2706 if (<V64:MODE>mode == DFmode)
2711 word0 = adjust_address (operands[1], half_mode, 0);
2712 word1 = adjust_address (operands[1], half_mode, 4);
2714 if (reg_overlap_mentioned_p (gen_highpart (half_mode, operands[0]), word1))
2716 emit_move_insn_1 (gen_lowpart (half_mode, operands[0]), word1);
2717 emit_move_insn_1 (gen_highpart (half_mode, operands[0]), word0);
2721 emit_move_insn_1 (gen_highpart (half_mode, operands[0]), word0);
2722 emit_move_insn_1 (gen_lowpart (half_mode, operands[0]), word1);
2728 [(set (match_operand:V64 0 "memory_operand" "")
2729 (match_operand:V64 1 "register_operand" ""))]
2732 && (((REGNO (operands[1]) % 2) != 0)
2733 || ! mem_min_alignment (operands[0], 8))
2734 && offsettable_memref_p (operands[0])"
2735 [(clobber (const_int 0))]
2737 enum machine_mode half_mode;
2740 /* We can be expanded for DFmode or integral vector modes. */
2741 if (<V64:MODE>mode == DFmode)
2746 word0 = adjust_address (operands[0], half_mode, 0);
2747 word1 = adjust_address (operands[0], half_mode, 4);
2749 emit_move_insn_1 (word0, gen_highpart (half_mode, operands[1]));
2750 emit_move_insn_1 (word1, gen_lowpart (half_mode, operands[1]));
2755 [(set (match_operand:V64 0 "memory_operand" "")
2756 (match_operand:V64 1 "const_zero_operand" ""))]
2760 && ! mem_min_alignment (operands[0], 8)))
2761 && offsettable_memref_p (operands[0])"
2762 [(clobber (const_int 0))]
2764 enum machine_mode half_mode;
2767 /* We can be expanded for DFmode or integral vector modes. */
2768 if (<V64:MODE>mode == DFmode)
2773 dest1 = adjust_address (operands[0], half_mode, 0);
2774 dest2 = adjust_address (operands[0], half_mode, 4);
2776 emit_move_insn_1 (dest1, CONST0_RTX (half_mode));
2777 emit_move_insn_1 (dest2, CONST0_RTX (half_mode));
2782 [(set (match_operand:V64 0 "register_operand" "")
2783 (match_operand:V64 1 "const_zero_operand" ""))]
2786 && ((GET_CODE (operands[0]) == REG
2787 && REGNO (operands[0]) < 32)
2788 || (GET_CODE (operands[0]) == SUBREG
2789 && GET_CODE (SUBREG_REG (operands[0])) == REG
2790 && REGNO (SUBREG_REG (operands[0])) < 32))"
2791 [(clobber (const_int 0))]
2793 enum machine_mode half_mode;
2794 rtx set_dest = operands[0];
2797 /* We can be expanded for DFmode or integral vector modes. */
2798 if (<V64:MODE>mode == DFmode)
2803 dest1 = gen_highpart (half_mode, set_dest);
2804 dest2 = gen_lowpart (half_mode, set_dest);
2805 emit_move_insn_1 (dest1, CONST0_RTX (half_mode));
2806 emit_move_insn_1 (dest2, CONST0_RTX (half_mode));
2810 (define_expand "movtf"
2811 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2812 (match_operand:TF 1 "general_operand" ""))]
2815 if (sparc_expand_move (TFmode, operands))
2819 (define_insn "*movtf_insn_sp32"
2820 [(set (match_operand:TF 0 "nonimmediate_operand" "=b,e,o,U,r")
2821 (match_operand:TF 1 "input_operand" "G,oe,GeUr,o,roG"))]
2824 && (register_operand (operands[0], TFmode)
2825 || register_or_zero_operand (operands[1], TFmode))"
2827 [(set_attr "length" "4")])
2829 ;; Exactly the same as above, except that all `e' cases are deleted.
2830 ;; This is necessary to prevent reload from ever trying to use a `e' reg
2833 (define_insn "*movtf_insn_sp32_no_fpu"
2834 [(set (match_operand:TF 0 "nonimmediate_operand" "=o,U,o,r,o")
2835 (match_operand:TF 1 "input_operand" "G,o,U,roG,r"))]
2838 && (register_operand (operands[0], TFmode)
2839 || register_or_zero_operand (operands[1], TFmode))"
2841 [(set_attr "length" "4")])
2843 (define_insn "*movtf_insn_sp64"
2844 [(set (match_operand:TF 0 "nonimmediate_operand" "=b,e,o,r")
2845 (match_operand:TF 1 "input_operand" "G,oe,Ger,roG"))]
2848 && ! TARGET_HARD_QUAD
2849 && (register_operand (operands[0], TFmode)
2850 || register_or_zero_operand (operands[1], TFmode))"
2852 [(set_attr "length" "2")])
2854 (define_insn "*movtf_insn_sp64_hq"
2855 [(set (match_operand:TF 0 "nonimmediate_operand" "=b,e,e,m,o,r")
2856 (match_operand:TF 1 "input_operand" "G,e,m,e,rG,roG"))]
2860 && (register_operand (operands[0], TFmode)
2861 || register_or_zero_operand (operands[1], TFmode))"
2869 [(set_attr "type" "*,fpmove,fpload,fpstore,*,*")
2870 (set_attr "length" "2,*,*,*,2,2")])
2872 (define_insn "*movtf_insn_sp64_no_fpu"
2873 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o")
2874 (match_operand:TF 1 "input_operand" "orG,rG"))]
2877 && (register_operand (operands[0], TFmode)
2878 || register_or_zero_operand (operands[1], TFmode))"
2880 [(set_attr "length" "2")])
2882 ;; Now all the splits to handle multi-insn TF mode moves.
2884 [(set (match_operand:TF 0 "register_operand" "")
2885 (match_operand:TF 1 "register_operand" ""))]
2889 && ! TARGET_HARD_QUAD)
2890 || ! fp_register_operand (operands[0], TFmode))"
2891 [(clobber (const_int 0))]
2893 rtx set_dest = operands[0];
2894 rtx set_src = operands[1];
2898 dest1 = gen_df_reg (set_dest, 0);
2899 dest2 = gen_df_reg (set_dest, 1);
2900 src1 = gen_df_reg (set_src, 0);
2901 src2 = gen_df_reg (set_src, 1);
2903 /* Now emit using the real source and destination we found, swapping
2904 the order if we detect overlap. */
2905 if (reg_overlap_mentioned_p (dest1, src2))
2907 emit_insn (gen_movdf (dest2, src2));
2908 emit_insn (gen_movdf (dest1, src1));
2912 emit_insn (gen_movdf (dest1, src1));
2913 emit_insn (gen_movdf (dest2, src2));
2919 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2920 (match_operand:TF 1 "const_zero_operand" ""))]
2922 [(clobber (const_int 0))]
2924 rtx set_dest = operands[0];
2927 switch (GET_CODE (set_dest))
2930 dest1 = gen_df_reg (set_dest, 0);
2931 dest2 = gen_df_reg (set_dest, 1);
2934 dest1 = adjust_address (set_dest, DFmode, 0);
2935 dest2 = adjust_address (set_dest, DFmode, 8);
2941 emit_insn (gen_movdf (dest1, CONST0_RTX (DFmode)));
2942 emit_insn (gen_movdf (dest2, CONST0_RTX (DFmode)));
2947 [(set (match_operand:TF 0 "register_operand" "")
2948 (match_operand:TF 1 "memory_operand" ""))]
2950 && offsettable_memref_p (operands[1])
2952 || ! TARGET_HARD_QUAD
2953 || ! fp_register_operand (operands[0], TFmode)))"
2954 [(clobber (const_int 0))]
2956 rtx word0 = adjust_address (operands[1], DFmode, 0);
2957 rtx word1 = adjust_address (operands[1], DFmode, 8);
2958 rtx set_dest, dest1, dest2;
2960 set_dest = operands[0];
2962 dest1 = gen_df_reg (set_dest, 0);
2963 dest2 = gen_df_reg (set_dest, 1);
2965 /* Now output, ordering such that we don't clobber any registers
2966 mentioned in the address. */
2967 if (reg_overlap_mentioned_p (dest1, word1))
2970 emit_insn (gen_movdf (dest2, word1));
2971 emit_insn (gen_movdf (dest1, word0));
2975 emit_insn (gen_movdf (dest1, word0));
2976 emit_insn (gen_movdf (dest2, word1));
2982 [(set (match_operand:TF 0 "memory_operand" "")
2983 (match_operand:TF 1 "register_operand" ""))]
2985 && offsettable_memref_p (operands[0])
2987 || ! TARGET_HARD_QUAD
2988 || ! fp_register_operand (operands[1], TFmode)))"
2989 [(clobber (const_int 0))]
2991 rtx set_src = operands[1];
2993 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 0),
2994 gen_df_reg (set_src, 0)));
2995 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 8),
2996 gen_df_reg (set_src, 1)));
3001 ;; SPARC-V9 conditional move instructions.
3003 ;; We can handle larger constants here for some flavors, but for now we keep
3004 ;; it simple and only allow those constants supported by all flavors.
3005 ;; Note that emit_conditional_move canonicalizes operands 2,3 so that operand
3006 ;; 3 contains the constant if one is present, but we handle either for
3007 ;; generality (sparc.c puts a constant in operand 2).
3009 (define_expand "movqicc"
3010 [(set (match_operand:QI 0 "register_operand" "")
3011 (if_then_else:QI (match_operand 1 "comparison_operator" "")
3012 (match_operand:QI 2 "arith10_operand" "")
3013 (match_operand:QI 3 "arith10_operand" "")))]
3016 enum rtx_code code = GET_CODE (operands[1]);
3018 if (GET_MODE (sparc_compare_op0) == DImode
3022 if (sparc_compare_op1 == const0_rtx
3023 && GET_CODE (sparc_compare_op0) == REG
3024 && GET_MODE (sparc_compare_op0) == DImode
3025 && v9_regcmp_p (code))
3027 operands[1] = gen_rtx_fmt_ee (code, DImode,
3028 sparc_compare_op0, sparc_compare_op1);
3032 rtx cc_reg = gen_compare_reg (code);
3033 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3037 (define_expand "movhicc"
3038 [(set (match_operand:HI 0 "register_operand" "")
3039 (if_then_else:HI (match_operand 1 "comparison_operator" "")
3040 (match_operand:HI 2 "arith10_operand" "")
3041 (match_operand:HI 3 "arith10_operand" "")))]
3044 enum rtx_code code = GET_CODE (operands[1]);
3046 if (GET_MODE (sparc_compare_op0) == DImode
3050 if (sparc_compare_op1 == const0_rtx
3051 && GET_CODE (sparc_compare_op0) == REG
3052 && GET_MODE (sparc_compare_op0) == DImode
3053 && v9_regcmp_p (code))
3055 operands[1] = gen_rtx_fmt_ee (code, DImode,
3056 sparc_compare_op0, sparc_compare_op1);
3060 rtx cc_reg = gen_compare_reg (code);
3061 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3065 (define_expand "movsicc"
3066 [(set (match_operand:SI 0 "register_operand" "")
3067 (if_then_else:SI (match_operand 1 "comparison_operator" "")
3068 (match_operand:SI 2 "arith10_operand" "")
3069 (match_operand:SI 3 "arith10_operand" "")))]
3072 enum rtx_code code = GET_CODE (operands[1]);
3073 enum machine_mode op0_mode = GET_MODE (sparc_compare_op0);
3075 if (sparc_compare_op1 == const0_rtx
3076 && GET_CODE (sparc_compare_op0) == REG
3077 && (TARGET_ARCH64 && op0_mode == DImode && v9_regcmp_p (code)))
3079 operands[1] = gen_rtx_fmt_ee (code, op0_mode,
3080 sparc_compare_op0, sparc_compare_op1);
3084 rtx cc_reg = gen_compare_reg (code);
3085 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg),
3086 cc_reg, const0_rtx);
3090 (define_expand "movdicc"
3091 [(set (match_operand:DI 0 "register_operand" "")
3092 (if_then_else:DI (match_operand 1 "comparison_operator" "")
3093 (match_operand:DI 2 "arith10_operand" "")
3094 (match_operand:DI 3 "arith10_operand" "")))]
3097 enum rtx_code code = GET_CODE (operands[1]);
3099 if (sparc_compare_op1 == const0_rtx
3100 && GET_CODE (sparc_compare_op0) == REG
3101 && GET_MODE (sparc_compare_op0) == DImode
3102 && v9_regcmp_p (code))
3104 operands[1] = gen_rtx_fmt_ee (code, DImode,
3105 sparc_compare_op0, sparc_compare_op1);
3109 rtx cc_reg = gen_compare_reg (code);
3110 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg),
3111 cc_reg, const0_rtx);
3115 (define_expand "movsfcc"
3116 [(set (match_operand:SF 0 "register_operand" "")
3117 (if_then_else:SF (match_operand 1 "comparison_operator" "")
3118 (match_operand:SF 2 "register_operand" "")
3119 (match_operand:SF 3 "register_operand" "")))]
3120 "TARGET_V9 && TARGET_FPU"
3122 enum rtx_code code = GET_CODE (operands[1]);
3124 if (GET_MODE (sparc_compare_op0) == DImode
3128 if (sparc_compare_op1 == const0_rtx
3129 && GET_CODE (sparc_compare_op0) == REG
3130 && GET_MODE (sparc_compare_op0) == DImode
3131 && v9_regcmp_p (code))
3133 operands[1] = gen_rtx_fmt_ee (code, DImode,
3134 sparc_compare_op0, sparc_compare_op1);
3138 rtx cc_reg = gen_compare_reg (code);
3139 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3143 (define_expand "movdfcc"
3144 [(set (match_operand:DF 0 "register_operand" "")
3145 (if_then_else:DF (match_operand 1 "comparison_operator" "")
3146 (match_operand:DF 2 "register_operand" "")
3147 (match_operand:DF 3 "register_operand" "")))]
3148 "TARGET_V9 && TARGET_FPU"
3150 enum rtx_code code = GET_CODE (operands[1]);
3152 if (GET_MODE (sparc_compare_op0) == DImode
3156 if (sparc_compare_op1 == const0_rtx
3157 && GET_CODE (sparc_compare_op0) == REG
3158 && GET_MODE (sparc_compare_op0) == DImode
3159 && v9_regcmp_p (code))
3161 operands[1] = gen_rtx_fmt_ee (code, DImode,
3162 sparc_compare_op0, sparc_compare_op1);
3166 rtx cc_reg = gen_compare_reg (code);
3167 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3171 (define_expand "movtfcc"
3172 [(set (match_operand:TF 0 "register_operand" "")
3173 (if_then_else:TF (match_operand 1 "comparison_operator" "")
3174 (match_operand:TF 2 "register_operand" "")
3175 (match_operand:TF 3 "register_operand" "")))]
3176 "TARGET_V9 && TARGET_FPU"
3178 enum rtx_code code = GET_CODE (operands[1]);
3180 if (GET_MODE (sparc_compare_op0) == DImode
3184 if (sparc_compare_op1 == const0_rtx
3185 && GET_CODE (sparc_compare_op0) == REG
3186 && GET_MODE (sparc_compare_op0) == DImode
3187 && v9_regcmp_p (code))
3189 operands[1] = gen_rtx_fmt_ee (code, DImode,
3190 sparc_compare_op0, sparc_compare_op1);
3194 rtx cc_reg = gen_compare_reg (code);
3195 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3199 ;; Conditional move define_insns.
3201 (define_insn "*movqi_cc_sp64"
3202 [(set (match_operand:QI 0 "register_operand" "=r,r")
3203 (if_then_else:QI (match_operator 1 "comparison_operator"
3204 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
3206 (match_operand:QI 3 "arith11_operand" "rL,0")
3207 (match_operand:QI 4 "arith11_operand" "0,rL")))]
3211 mov%c1\t%x2, %4, %0"
3212 [(set_attr "type" "cmove")])
3214 (define_insn "*movhi_cc_sp64"
3215 [(set (match_operand:HI 0 "register_operand" "=r,r")
3216 (if_then_else:HI (match_operator 1 "comparison_operator"
3217 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
3219 (match_operand:HI 3 "arith11_operand" "rL,0")
3220 (match_operand:HI 4 "arith11_operand" "0,rL")))]
3224 mov%c1\t%x2, %4, %0"
3225 [(set_attr "type" "cmove")])
3227 (define_insn "*movsi_cc_sp64"
3228 [(set (match_operand:SI 0 "register_operand" "=r,r")
3229 (if_then_else:SI (match_operator 1 "comparison_operator"
3230 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
3232 (match_operand:SI 3 "arith11_operand" "rL,0")
3233 (match_operand:SI 4 "arith11_operand" "0,rL")))]
3237 mov%c1\t%x2, %4, %0"
3238 [(set_attr "type" "cmove")])
3240 (define_insn "*movdi_cc_sp64"
3241 [(set (match_operand:DI 0 "register_operand" "=r,r")
3242 (if_then_else:DI (match_operator 1 "comparison_operator"
3243 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
3245 (match_operand:DI 3 "arith11_operand" "rL,0")
3246 (match_operand:DI 4 "arith11_operand" "0,rL")))]
3250 mov%c1\t%x2, %4, %0"
3251 [(set_attr "type" "cmove")])
3253 (define_insn "*movdi_cc_sp64_trunc"
3254 [(set (match_operand:SI 0 "register_operand" "=r,r")
3255 (if_then_else:SI (match_operator 1 "comparison_operator"
3256 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
3258 (match_operand:SI 3 "arith11_operand" "rL,0")
3259 (match_operand:SI 4 "arith11_operand" "0,rL")))]
3263 mov%c1\t%x2, %4, %0"
3264 [(set_attr "type" "cmove")])
3266 (define_insn "*movsf_cc_sp64"
3267 [(set (match_operand:SF 0 "register_operand" "=f,f")
3268 (if_then_else:SF (match_operator 1 "comparison_operator"
3269 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
3271 (match_operand:SF 3 "register_operand" "f,0")
3272 (match_operand:SF 4 "register_operand" "0,f")))]
3273 "TARGET_V9 && TARGET_FPU"
3275 fmovs%C1\t%x2, %3, %0
3276 fmovs%c1\t%x2, %4, %0"
3277 [(set_attr "type" "fpcmove")])
3279 (define_insn "movdf_cc_sp64"
3280 [(set (match_operand:DF 0 "register_operand" "=e,e")
3281 (if_then_else:DF (match_operator 1 "comparison_operator"
3282 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
3284 (match_operand:DF 3 "register_operand" "e,0")
3285 (match_operand:DF 4 "register_operand" "0,e")))]
3286 "TARGET_V9 && TARGET_FPU"
3288 fmovd%C1\t%x2, %3, %0
3289 fmovd%c1\t%x2, %4, %0"
3290 [(set_attr "type" "fpcmove")
3291 (set_attr "fptype" "double")])
3293 (define_insn "*movtf_cc_hq_sp64"
3294 [(set (match_operand:TF 0 "register_operand" "=e,e")
3295 (if_then_else:TF (match_operator 1 "comparison_operator"
3296 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
3298 (match_operand:TF 3 "register_operand" "e,0")
3299 (match_operand:TF 4 "register_operand" "0,e")))]
3300 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
3302 fmovq%C1\t%x2, %3, %0
3303 fmovq%c1\t%x2, %4, %0"
3304 [(set_attr "type" "fpcmove")])
3306 (define_insn_and_split "*movtf_cc_sp64"
3307 [(set (match_operand:TF 0 "register_operand" "=e,e")
3308 (if_then_else:TF (match_operator 1 "comparison_operator"
3309 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
3311 (match_operand:TF 3 "register_operand" "e,0")
3312 (match_operand:TF 4 "register_operand" "0,e")))]
3313 "TARGET_V9 && TARGET_FPU && !TARGET_HARD_QUAD"
3315 "&& reload_completed"
3316 [(clobber (const_int 0))]
3318 rtx set_dest = operands[0];
3319 rtx set_srca = operands[3];
3320 rtx set_srcb = operands[4];
3321 int third = rtx_equal_p (set_dest, set_srca);
3323 rtx srca1, srca2, srcb1, srcb2;
3325 dest1 = gen_df_reg (set_dest, 0);
3326 dest2 = gen_df_reg (set_dest, 1);
3327 srca1 = gen_df_reg (set_srca, 0);
3328 srca2 = gen_df_reg (set_srca, 1);
3329 srcb1 = gen_df_reg (set_srcb, 0);
3330 srcb2 = gen_df_reg (set_srcb, 1);
3332 /* Now emit using the real source and destination we found, swapping
3333 the order if we detect overlap. */
3334 if ((third && reg_overlap_mentioned_p (dest1, srcb2))
3335 || (!third && reg_overlap_mentioned_p (dest1, srca2)))
3337 emit_insn (gen_movdf_cc_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
3338 emit_insn (gen_movdf_cc_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
3342 emit_insn (gen_movdf_cc_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
3343 emit_insn (gen_movdf_cc_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
3347 [(set_attr "length" "2")])
3349 (define_insn "*movqi_cc_reg_sp64"
3350 [(set (match_operand:QI 0 "register_operand" "=r,r")
3351 (if_then_else:QI (match_operator 1 "v9_register_compare_operator"
3352 [(match_operand:DI 2 "register_operand" "r,r")
3354 (match_operand:QI 3 "arith10_operand" "rM,0")
3355 (match_operand:QI 4 "arith10_operand" "0,rM")))]
3358 movr%D1\t%2, %r3, %0
3359 movr%d1\t%2, %r4, %0"
3360 [(set_attr "type" "cmove")])
3362 (define_insn "*movhi_cc_reg_sp64"
3363 [(set (match_operand:HI 0 "register_operand" "=r,r")
3364 (if_then_else:HI (match_operator 1 "v9_register_compare_operator"
3365 [(match_operand:DI 2 "register_operand" "r,r")
3367 (match_operand:HI 3 "arith10_operand" "rM,0")
3368 (match_operand:HI 4 "arith10_operand" "0,rM")))]
3371 movr%D1\t%2, %r3, %0
3372 movr%d1\t%2, %r4, %0"
3373 [(set_attr "type" "cmove")])
3375 (define_insn "*movsi_cc_reg_sp64"
3376 [(set (match_operand:SI 0 "register_operand" "=r,r")
3377 (if_then_else:SI (match_operator 1 "v9_register_compare_operator"
3378 [(match_operand:DI 2 "register_operand" "r,r")
3380 (match_operand:SI 3 "arith10_operand" "rM,0")
3381 (match_operand:SI 4 "arith10_operand" "0,rM")))]
3384 movr%D1\t%2, %r3, %0
3385 movr%d1\t%2, %r4, %0"
3386 [(set_attr "type" "cmove")])
3388 (define_insn "*movdi_cc_reg_sp64"
3389 [(set (match_operand:DI 0 "register_operand" "=r,r")
3390 (if_then_else:DI (match_operator 1 "v9_register_compare_operator"
3391 [(match_operand:DI 2 "register_operand" "r,r")
3393 (match_operand:DI 3 "arith10_operand" "rM,0")
3394 (match_operand:DI 4 "arith10_operand" "0,rM")))]
3397 movr%D1\t%2, %r3, %0
3398 movr%d1\t%2, %r4, %0"
3399 [(set_attr "type" "cmove")])
3401 (define_insn "*movsf_cc_reg_sp64"
3402 [(set (match_operand:SF 0 "register_operand" "=f,f")
3403 (if_then_else:SF (match_operator 1 "v9_register_compare_operator"
3404 [(match_operand:DI 2 "register_operand" "r,r")
3406 (match_operand:SF 3 "register_operand" "f,0")
3407 (match_operand:SF 4 "register_operand" "0,f")))]
3408 "TARGET_ARCH64 && TARGET_FPU"
3410 fmovrs%D1\t%2, %3, %0
3411 fmovrs%d1\t%2, %4, %0"
3412 [(set_attr "type" "fpcrmove")])
3414 (define_insn "movdf_cc_reg_sp64"
3415 [(set (match_operand:DF 0 "register_operand" "=e,e")
3416 (if_then_else:DF (match_operator 1 "v9_register_compare_operator"
3417 [(match_operand:DI 2 "register_operand" "r,r")
3419 (match_operand:DF 3 "register_operand" "e,0")
3420 (match_operand:DF 4 "register_operand" "0,e")))]
3421 "TARGET_ARCH64 && TARGET_FPU"
3423 fmovrd%D1\t%2, %3, %0
3424 fmovrd%d1\t%2, %4, %0"
3425 [(set_attr "type" "fpcrmove")
3426 (set_attr "fptype" "double")])
3428 (define_insn "*movtf_cc_reg_hq_sp64"
3429 [(set (match_operand:TF 0 "register_operand" "=e,e")
3430 (if_then_else:TF (match_operator 1 "v9_register_compare_operator"
3431 [(match_operand:DI 2 "register_operand" "r,r")
3433 (match_operand:TF 3 "register_operand" "e,0")
3434 (match_operand:TF 4 "register_operand" "0,e")))]
3435 "TARGET_ARCH64 && TARGET_FPU && TARGET_HARD_QUAD"
3437 fmovrq%D1\t%2, %3, %0
3438 fmovrq%d1\t%2, %4, %0"
3439 [(set_attr "type" "fpcrmove")])
3441 (define_insn_and_split "*movtf_cc_reg_sp64"
3442 [(set (match_operand:TF 0 "register_operand" "=e,e")
3443 (if_then_else:TF (match_operator 1 "v9_register_compare_operator"
3444 [(match_operand:DI 2 "register_operand" "r,r")
3446 (match_operand:TF 3 "register_operand" "e,0")
3447 (match_operand:TF 4 "register_operand" "0,e")))]
3448 "TARGET_ARCH64 && TARGET_FPU && ! TARGET_HARD_QUAD"
3450 "&& reload_completed"
3451 [(clobber (const_int 0))]
3453 rtx set_dest = operands[0];
3454 rtx set_srca = operands[3];
3455 rtx set_srcb = operands[4];
3456 int third = rtx_equal_p (set_dest, set_srca);
3458 rtx srca1, srca2, srcb1, srcb2;
3460 dest1 = gen_df_reg (set_dest, 0);
3461 dest2 = gen_df_reg (set_dest, 1);
3462 srca1 = gen_df_reg (set_srca, 0);
3463 srca2 = gen_df_reg (set_srca, 1);
3464 srcb1 = gen_df_reg (set_srcb, 0);
3465 srcb2 = gen_df_reg (set_srcb, 1);
3467 /* Now emit using the real source and destination we found, swapping
3468 the order if we detect overlap. */
3469 if ((third && reg_overlap_mentioned_p (dest1, srcb2))
3470 || (!third && reg_overlap_mentioned_p (dest1, srca2)))
3472 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
3473 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
3477 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
3478 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
3482 [(set_attr "length" "2")])
3485 ;; Zero-extension instructions
3487 ;; These patterns originally accepted general_operands, however, slightly
3488 ;; better code is generated by only accepting register_operands, and then
3489 ;; letting combine generate the ldu[hb] insns.
3491 (define_expand "zero_extendhisi2"
3492 [(set (match_operand:SI 0 "register_operand" "")
3493 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
3496 rtx temp = gen_reg_rtx (SImode);
3497 rtx shift_16 = GEN_INT (16);
3498 int op1_subbyte = 0;
3500 if (GET_CODE (operand1) == SUBREG)
3502 op1_subbyte = SUBREG_BYTE (operand1);
3503 op1_subbyte /= GET_MODE_SIZE (SImode);
3504 op1_subbyte *= GET_MODE_SIZE (SImode);
3505 operand1 = XEXP (operand1, 0);
3508 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3510 emit_insn (gen_lshrsi3 (operand0, temp, shift_16));
3514 (define_insn "*zero_extendhisi2_insn"
3515 [(set (match_operand:SI 0 "register_operand" "=r")
3516 (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
3519 [(set_attr "type" "load")
3520 (set_attr "us3load_type" "3cycle")])
3522 (define_expand "zero_extendqihi2"
3523 [(set (match_operand:HI 0 "register_operand" "")
3524 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
3528 (define_insn "*zero_extendqihi2_insn"
3529 [(set (match_operand:HI 0 "register_operand" "=r,r")
3530 (zero_extend:HI (match_operand:QI 1 "input_operand" "r,m")))]
3531 "GET_CODE (operands[1]) != CONST_INT"
3535 [(set_attr "type" "*,load")
3536 (set_attr "us3load_type" "*,3cycle")])
3538 (define_expand "zero_extendqisi2"
3539 [(set (match_operand:SI 0 "register_operand" "")
3540 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
3544 (define_insn "*zero_extendqisi2_insn"
3545 [(set (match_operand:SI 0 "register_operand" "=r,r")
3546 (zero_extend:SI (match_operand:QI 1 "input_operand" "r,m")))]
3547 "GET_CODE (operands[1]) != CONST_INT"
3551 [(set_attr "type" "*,load")
3552 (set_attr "us3load_type" "*,3cycle")])
3554 (define_expand "zero_extendqidi2"
3555 [(set (match_operand:DI 0 "register_operand" "")
3556 (zero_extend:DI (match_operand:QI 1 "register_operand" "")))]
3560 (define_insn "*zero_extendqidi2_insn"
3561 [(set (match_operand:DI 0 "register_operand" "=r,r")
3562 (zero_extend:DI (match_operand:QI 1 "input_operand" "r,m")))]
3563 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
3567 [(set_attr "type" "*,load")
3568 (set_attr "us3load_type" "*,3cycle")])
3570 (define_expand "zero_extendhidi2"
3571 [(set (match_operand:DI 0 "register_operand" "")
3572 (zero_extend:DI (match_operand:HI 1 "register_operand" "")))]
3575 rtx temp = gen_reg_rtx (DImode);
3576 rtx shift_48 = GEN_INT (48);
3577 int op1_subbyte = 0;
3579 if (GET_CODE (operand1) == SUBREG)
3581 op1_subbyte = SUBREG_BYTE (operand1);
3582 op1_subbyte /= GET_MODE_SIZE (DImode);
3583 op1_subbyte *= GET_MODE_SIZE (DImode);
3584 operand1 = XEXP (operand1, 0);
3587 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
3589 emit_insn (gen_lshrdi3 (operand0, temp, shift_48));
3593 (define_insn "*zero_extendhidi2_insn"
3594 [(set (match_operand:DI 0 "register_operand" "=r")
3595 (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
3598 [(set_attr "type" "load")
3599 (set_attr "us3load_type" "3cycle")])
3601 ;; ??? Write truncdisi pattern using sra?
3603 (define_expand "zero_extendsidi2"
3604 [(set (match_operand:DI 0 "register_operand" "")
3605 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
3609 (define_insn "*zero_extendsidi2_insn_sp64"
3610 [(set (match_operand:DI 0 "register_operand" "=r,r")
3611 (zero_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
3612 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
3616 [(set_attr "type" "shift,load")])
3618 (define_insn_and_split "*zero_extendsidi2_insn_sp32"
3619 [(set (match_operand:DI 0 "register_operand" "=r")
3620 (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
3623 "&& reload_completed"
3624 [(set (match_dup 2) (match_dup 3))
3625 (set (match_dup 4) (match_dup 5))]
3629 dest1 = gen_highpart (SImode, operands[0]);
3630 dest2 = gen_lowpart (SImode, operands[0]);
3632 /* Swap the order in case of overlap. */
3633 if (REGNO (dest1) == REGNO (operands[1]))
3635 operands[2] = dest2;
3636 operands[3] = operands[1];
3637 operands[4] = dest1;
3638 operands[5] = const0_rtx;
3642 operands[2] = dest1;
3643 operands[3] = const0_rtx;
3644 operands[4] = dest2;
3645 operands[5] = operands[1];
3648 [(set_attr "length" "2")])
3650 ;; Simplify comparisons of extended values.
3652 (define_insn "*cmp_zero_extendqisi2"
3654 (compare:CC (zero_extend:SI (match_operand:QI 0 "register_operand" "r"))
3657 "andcc\t%0, 0xff, %%g0"
3658 [(set_attr "type" "compare")])
3660 (define_insn "*cmp_zero_qi"
3662 (compare:CC (match_operand:QI 0 "register_operand" "r")
3665 "andcc\t%0, 0xff, %%g0"
3666 [(set_attr "type" "compare")])
3668 (define_insn "*cmp_zero_extendqisi2_set"
3670 (compare:CC (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
3672 (set (match_operand:SI 0 "register_operand" "=r")
3673 (zero_extend:SI (match_dup 1)))]
3675 "andcc\t%1, 0xff, %0"
3676 [(set_attr "type" "compare")])
3678 (define_insn "*cmp_zero_extendqisi2_andcc_set"
3680 (compare:CC (and:SI (match_operand:SI 1 "register_operand" "r")
3683 (set (match_operand:SI 0 "register_operand" "=r")
3684 (zero_extend:SI (subreg:QI (match_dup 1) 0)))]
3686 "andcc\t%1, 0xff, %0"
3687 [(set_attr "type" "compare")])
3689 (define_insn "*cmp_zero_extendqidi2"
3691 (compare:CCX (zero_extend:DI (match_operand:QI 0 "register_operand" "r"))
3694 "andcc\t%0, 0xff, %%g0"
3695 [(set_attr "type" "compare")])
3697 (define_insn "*cmp_zero_qi_sp64"
3699 (compare:CCX (match_operand:QI 0 "register_operand" "r")
3702 "andcc\t%0, 0xff, %%g0"
3703 [(set_attr "type" "compare")])
3705 (define_insn "*cmp_zero_extendqidi2_set"
3707 (compare:CCX (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
3709 (set (match_operand:DI 0 "register_operand" "=r")
3710 (zero_extend:DI (match_dup 1)))]
3712 "andcc\t%1, 0xff, %0"
3713 [(set_attr "type" "compare")])
3715 (define_insn "*cmp_zero_extendqidi2_andcc_set"
3717 (compare:CCX (and:DI (match_operand:DI 1 "register_operand" "r")
3720 (set (match_operand:DI 0 "register_operand" "=r")
3721 (zero_extend:DI (subreg:QI (match_dup 1) 0)))]
3723 "andcc\t%1, 0xff, %0"
3724 [(set_attr "type" "compare")])
3726 ;; Similarly, handle {SI,DI}->QI mode truncation followed by a compare.
3728 (define_insn "*cmp_siqi_trunc"
3730 (compare:CC (subreg:QI (match_operand:SI 0 "register_operand" "r") 3)
3733 "andcc\t%0, 0xff, %%g0"
3734 [(set_attr "type" "compare")])
3736 (define_insn "*cmp_siqi_trunc_set"
3738 (compare:CC (subreg:QI (match_operand:SI 1 "register_operand" "r") 3)
3740 (set (match_operand:QI 0 "register_operand" "=r")
3741 (subreg:QI (match_dup 1) 3))]
3743 "andcc\t%1, 0xff, %0"
3744 [(set_attr "type" "compare")])
3746 (define_insn "*cmp_diqi_trunc"
3748 (compare:CC (subreg:QI (match_operand:DI 0 "register_operand" "r") 7)
3751 "andcc\t%0, 0xff, %%g0"
3752 [(set_attr "type" "compare")])
3754 (define_insn "*cmp_diqi_trunc_set"
3756 (compare:CC (subreg:QI (match_operand:DI 1 "register_operand" "r") 7)
3758 (set (match_operand:QI 0 "register_operand" "=r")
3759 (subreg:QI (match_dup 1) 7))]
3761 "andcc\t%1, 0xff, %0"
3762 [(set_attr "type" "compare")])
3765 ;; Sign-extension instructions
3767 ;; These patterns originally accepted general_operands, however, slightly
3768 ;; better code is generated by only accepting register_operands, and then
3769 ;; letting combine generate the lds[hb] insns.
3771 (define_expand "extendhisi2"
3772 [(set (match_operand:SI 0 "register_operand" "")
3773 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
3776 rtx temp = gen_reg_rtx (SImode);
3777 rtx shift_16 = GEN_INT (16);
3778 int op1_subbyte = 0;
3780 if (GET_CODE (operand1) == SUBREG)
3782 op1_subbyte = SUBREG_BYTE (operand1);
3783 op1_subbyte /= GET_MODE_SIZE (SImode);
3784 op1_subbyte *= GET_MODE_SIZE (SImode);
3785 operand1 = XEXP (operand1, 0);
3788 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3790 emit_insn (gen_ashrsi3 (operand0, temp, shift_16));
3794 (define_insn "*sign_extendhisi2_insn"
3795 [(set (match_operand:SI 0 "register_operand" "=r")
3796 (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
3799 [(set_attr "type" "sload")
3800 (set_attr "us3load_type" "3cycle")])
3802 (define_expand "extendqihi2"
3803 [(set (match_operand:HI 0 "register_operand" "")
3804 (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
3807 rtx temp = gen_reg_rtx (SImode);
3808 rtx shift_24 = GEN_INT (24);
3809 int op1_subbyte = 0;
3810 int op0_subbyte = 0;
3812 if (GET_CODE (operand1) == SUBREG)
3814 op1_subbyte = SUBREG_BYTE (operand1);
3815 op1_subbyte /= GET_MODE_SIZE (SImode);
3816 op1_subbyte *= GET_MODE_SIZE (SImode);
3817 operand1 = XEXP (operand1, 0);
3819 if (GET_CODE (operand0) == SUBREG)
3821 op0_subbyte = SUBREG_BYTE (operand0);
3822 op0_subbyte /= GET_MODE_SIZE (SImode);
3823 op0_subbyte *= GET_MODE_SIZE (SImode);
3824 operand0 = XEXP (operand0, 0);
3826 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3828 if (GET_MODE (operand0) != SImode)
3829 operand0 = gen_rtx_SUBREG (SImode, operand0, op0_subbyte);
3830 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
3834 (define_insn "*sign_extendqihi2_insn"
3835 [(set (match_operand:HI 0 "register_operand" "=r")
3836 (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
3839 [(set_attr "type" "sload")
3840 (set_attr "us3load_type" "3cycle")])
3842 (define_expand "extendqisi2"
3843 [(set (match_operand:SI 0 "register_operand" "")
3844 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
3847 rtx temp = gen_reg_rtx (SImode);
3848 rtx shift_24 = GEN_INT (24);
3849 int op1_subbyte = 0;
3851 if (GET_CODE (operand1) == SUBREG)
3853 op1_subbyte = SUBREG_BYTE (operand1);
3854 op1_subbyte /= GET_MODE_SIZE (SImode);
3855 op1_subbyte *= GET_MODE_SIZE (SImode);
3856 operand1 = XEXP (operand1, 0);
3859 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3861 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
3865 (define_insn "*sign_extendqisi2_insn"
3866 [(set (match_operand:SI 0 "register_operand" "=r")
3867 (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
3870 [(set_attr "type" "sload")
3871 (set_attr "us3load_type" "3cycle")])
3873 (define_expand "extendqidi2"
3874 [(set (match_operand:DI 0 "register_operand" "")
3875 (sign_extend:DI (match_operand:QI 1 "register_operand" "")))]
3878 rtx temp = gen_reg_rtx (DImode);
3879 rtx shift_56 = GEN_INT (56);
3880 int op1_subbyte = 0;
3882 if (GET_CODE (operand1) == SUBREG)
3884 op1_subbyte = SUBREG_BYTE (operand1);
3885 op1_subbyte /= GET_MODE_SIZE (DImode);
3886 op1_subbyte *= GET_MODE_SIZE (DImode);
3887 operand1 = XEXP (operand1, 0);
3890 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
3892 emit_insn (gen_ashrdi3 (operand0, temp, shift_56));
3896 (define_insn "*sign_extendqidi2_insn"
3897 [(set (match_operand:DI 0 "register_operand" "=r")
3898 (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
3901 [(set_attr "type" "sload")
3902 (set_attr "us3load_type" "3cycle")])
3904 (define_expand "extendhidi2"
3905 [(set (match_operand:DI 0 "register_operand" "")
3906 (sign_extend:DI (match_operand:HI 1 "register_operand" "")))]
3909 rtx temp = gen_reg_rtx (DImode);
3910 rtx shift_48 = GEN_INT (48);
3911 int op1_subbyte = 0;
3913 if (GET_CODE (operand1) == SUBREG)
3915 op1_subbyte = SUBREG_BYTE (operand1);
3916 op1_subbyte /= GET_MODE_SIZE (DImode);
3917 op1_subbyte *= GET_MODE_SIZE (DImode);
3918 operand1 = XEXP (operand1, 0);
3921 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
3923 emit_insn (gen_ashrdi3 (operand0, temp, shift_48));
3927 (define_insn "*sign_extendhidi2_insn"
3928 [(set (match_operand:DI 0 "register_operand" "=r")
3929 (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
3932 [(set_attr "type" "sload")
3933 (set_attr "us3load_type" "3cycle")])
3935 (define_expand "extendsidi2"
3936 [(set (match_operand:DI 0 "register_operand" "")
3937 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
3941 (define_insn "*sign_extendsidi2_insn"
3942 [(set (match_operand:DI 0 "register_operand" "=r,r")
3943 (sign_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
3948 [(set_attr "type" "shift,sload")
3949 (set_attr "us3load_type" "*,3cycle")])
3952 ;; Special pattern for optimizing bit-field compares. This is needed
3953 ;; because combine uses this as a canonical form.
3955 (define_insn "*cmp_zero_extract"
3958 (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
3959 (match_operand:SI 1 "small_int_operand" "I")
3960 (match_operand:SI 2 "small_int_operand" "I"))
3962 "INTVAL (operands[2]) > 19"
3964 int len = INTVAL (operands[1]);
3965 int pos = 32 - INTVAL (operands[2]) - len;
3966 HOST_WIDE_INT mask = ((1 << len) - 1) << pos;
3967 operands[1] = GEN_INT (mask);
3968 return "andcc\t%0, %1, %%g0";
3970 [(set_attr "type" "compare")])
3972 (define_insn "*cmp_zero_extract_sp64"
3975 (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
3976 (match_operand:SI 1 "small_int_operand" "I")
3977 (match_operand:SI 2 "small_int_operand" "I"))
3979 "TARGET_ARCH64 && INTVAL (operands[2]) > 51"
3981 int len = INTVAL (operands[1]);
3982 int pos = 64 - INTVAL (operands[2]) - len;
3983 HOST_WIDE_INT mask = (((unsigned HOST_WIDE_INT) 1 << len) - 1) << pos;
3984 operands[1] = GEN_INT (mask);
3985 return "andcc\t%0, %1, %%g0";
3987 [(set_attr "type" "compare")])
3990 ;; Conversions between float, double and long double.
3992 (define_insn "extendsfdf2"
3993 [(set (match_operand:DF 0 "register_operand" "=e")
3995 (match_operand:SF 1 "register_operand" "f")))]
3998 [(set_attr "type" "fp")
3999 (set_attr "fptype" "double")])
4001 (define_expand "extendsftf2"
4002 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4004 (match_operand:SF 1 "register_operand" "")))]
4005 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4006 "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
4008 (define_insn "*extendsftf2_hq"
4009 [(set (match_operand:TF 0 "register_operand" "=e")
4011 (match_operand:SF 1 "register_operand" "f")))]
4012 "TARGET_FPU && TARGET_HARD_QUAD"
4014 [(set_attr "type" "fp")])
4016 (define_expand "extenddftf2"
4017 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4019 (match_operand:DF 1 "register_operand" "")))]
4020 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4021 "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
4023 (define_insn "*extenddftf2_hq"
4024 [(set (match_operand:TF 0 "register_operand" "=e")
4026 (match_operand:DF 1 "register_operand" "e")))]
4027 "TARGET_FPU && TARGET_HARD_QUAD"
4029 [(set_attr "type" "fp")])
4031 (define_insn "truncdfsf2"
4032 [(set (match_operand:SF 0 "register_operand" "=f")
4034 (match_operand:DF 1 "register_operand" "e")))]
4037 [(set_attr "type" "fp")
4038 (set_attr "fptype" "double")])
4040 (define_expand "trunctfsf2"
4041 [(set (match_operand:SF 0 "register_operand" "")
4043 (match_operand:TF 1 "general_operand" "")))]
4044 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4045 "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
4047 (define_insn "*trunctfsf2_hq"
4048 [(set (match_operand:SF 0 "register_operand" "=f")
4050 (match_operand:TF 1 "register_operand" "e")))]
4051 "TARGET_FPU && TARGET_HARD_QUAD"
4053 [(set_attr "type" "fp")])
4055 (define_expand "trunctfdf2"
4056 [(set (match_operand:DF 0 "register_operand" "")
4058 (match_operand:TF 1 "general_operand" "")))]
4059 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4060 "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
4062 (define_insn "*trunctfdf2_hq"
4063 [(set (match_operand:DF 0 "register_operand" "=e")
4065 (match_operand:TF 1 "register_operand" "e")))]
4066 "TARGET_FPU && TARGET_HARD_QUAD"
4068 [(set_attr "type" "fp")])
4071 ;; Conversion between fixed point and floating point.
4073 (define_insn "floatsisf2"
4074 [(set (match_operand:SF 0 "register_operand" "=f")
4075 (float:SF (match_operand:SI 1 "register_operand" "f")))]
4078 [(set_attr "type" "fp")
4079 (set_attr "fptype" "double")])
4081 (define_insn "floatsidf2"
4082 [(set (match_operand:DF 0 "register_operand" "=e")
4083 (float:DF (match_operand:SI 1 "register_operand" "f")))]
4086 [(set_attr "type" "fp")
4087 (set_attr "fptype" "double")])
4089 (define_expand "floatsitf2"
4090 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4091 (float:TF (match_operand:SI 1 "register_operand" "")))]
4092 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4093 "emit_tfmode_cvt (FLOAT, operands); DONE;")
4095 (define_insn "*floatsitf2_hq"
4096 [(set (match_operand:TF 0 "register_operand" "=e")
4097 (float:TF (match_operand:SI 1 "register_operand" "f")))]
4098 "TARGET_FPU && TARGET_HARD_QUAD"
4100 [(set_attr "type" "fp")])
4102 (define_expand "floatunssitf2"
4103 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4104 (unsigned_float:TF (match_operand:SI 1 "register_operand" "")))]
4105 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4106 "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
4108 ;; Now the same for 64 bit sources.
4110 (define_insn "floatdisf2"
4111 [(set (match_operand:SF 0 "register_operand" "=f")
4112 (float:SF (match_operand:DI 1 "register_operand" "e")))]
4113 "TARGET_V9 && TARGET_FPU"
4115 [(set_attr "type" "fp")
4116 (set_attr "fptype" "double")])
4118 (define_expand "floatunsdisf2"
4119 [(use (match_operand:SF 0 "register_operand" ""))
4120 (use (match_operand:DI 1 "general_operand" ""))]
4121 "TARGET_ARCH64 && TARGET_FPU"
4122 "sparc_emit_floatunsdi (operands, SFmode); DONE;")
4124 (define_insn "floatdidf2"
4125 [(set (match_operand:DF 0 "register_operand" "=e")
4126 (float:DF (match_operand:DI 1 "register_operand" "e")))]
4127 "TARGET_V9 && TARGET_FPU"
4129 [(set_attr "type" "fp")
4130 (set_attr "fptype" "double")])
4132 (define_expand "floatunsdidf2"
4133 [(use (match_operand:DF 0 "register_operand" ""))
4134 (use (match_operand:DI 1 "general_operand" ""))]
4135 "TARGET_ARCH64 && TARGET_FPU"
4136 "sparc_emit_floatunsdi (operands, DFmode); DONE;")
4138 (define_expand "floatditf2"
4139 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4140 (float:TF (match_operand:DI 1 "register_operand" "")))]
4141 "TARGET_FPU && TARGET_V9 && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4142 "emit_tfmode_cvt (FLOAT, operands); DONE;")
4144 (define_insn "*floatditf2_hq"
4145 [(set (match_operand:TF 0 "register_operand" "=e")
4146 (float:TF (match_operand:DI 1 "register_operand" "e")))]
4147 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
4149 [(set_attr "type" "fp")])
4151 (define_expand "floatunsditf2"
4152 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4153 (unsigned_float:TF (match_operand:DI 1 "register_operand" "")))]
4154 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4155 "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
4157 ;; Convert a float to an actual integer.
4158 ;; Truncation is performed as part of the conversion.
4160 (define_insn "fix_truncsfsi2"
4161 [(set (match_operand:SI 0 "register_operand" "=f")
4162 (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
4165 [(set_attr "type" "fp")
4166 (set_attr "fptype" "double")])
4168 (define_insn "fix_truncdfsi2"
4169 [(set (match_operand:SI 0 "register_operand" "=f")
4170 (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
4173 [(set_attr "type" "fp")
4174 (set_attr "fptype" "double")])
4176 (define_expand "fix_trunctfsi2"
4177 [(set (match_operand:SI 0 "register_operand" "")
4178 (fix:SI (match_operand:TF 1 "general_operand" "")))]
4179 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4180 "emit_tfmode_cvt (FIX, operands); DONE;")
4182 (define_insn "*fix_trunctfsi2_hq"
4183 [(set (match_operand:SI 0 "register_operand" "=f")
4184 (fix:SI (match_operand:TF 1 "register_operand" "e")))]
4185 "TARGET_FPU && TARGET_HARD_QUAD"
4187 [(set_attr "type" "fp")])
4189 (define_expand "fixuns_trunctfsi2"
4190 [(set (match_operand:SI 0 "register_operand" "")
4191 (unsigned_fix:SI (match_operand:TF 1 "general_operand" "")))]
4192 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4193 "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
4195 ;; Now the same, for V9 targets
4197 (define_insn "fix_truncsfdi2"
4198 [(set (match_operand:DI 0 "register_operand" "=e")
4199 (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
4200 "TARGET_V9 && TARGET_FPU"
4202 [(set_attr "type" "fp")
4203 (set_attr "fptype" "double")])
4205 (define_expand "fixuns_truncsfdi2"
4206 [(use (match_operand:DI 0 "register_operand" ""))
4207 (use (match_operand:SF 1 "general_operand" ""))]
4208 "TARGET_ARCH64 && TARGET_FPU"
4209 "sparc_emit_fixunsdi (operands, SFmode); DONE;")
4211 (define_insn "fix_truncdfdi2"
4212 [(set (match_operand:DI 0 "register_operand" "=e")
4213 (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
4214 "TARGET_V9 && TARGET_FPU"
4216 [(set_attr "type" "fp")
4217 (set_attr "fptype" "double")])
4219 (define_expand "fixuns_truncdfdi2"
4220 [(use (match_operand:DI 0 "register_operand" ""))
4221 (use (match_operand:DF 1 "general_operand" ""))]
4222 "TARGET_ARCH64 && TARGET_FPU"
4223 "sparc_emit_fixunsdi (operands, DFmode); DONE;")
4225 (define_expand "fix_trunctfdi2"
4226 [(set (match_operand:DI 0 "register_operand" "")
4227 (fix:DI (match_operand:TF 1 "general_operand" "")))]
4228 "TARGET_V9 && TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4229 "emit_tfmode_cvt (FIX, operands); DONE;")
4231 (define_insn "*fix_trunctfdi2_hq"
4232 [(set (match_operand:DI 0 "register_operand" "=e")
4233 (fix:DI (match_operand:TF 1 "register_operand" "e")))]
4234 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
4236 [(set_attr "type" "fp")])
4238 (define_expand "fixuns_trunctfdi2"
4239 [(set (match_operand:DI 0 "register_operand" "")
4240 (unsigned_fix:DI (match_operand:TF 1 "general_operand" "")))]
4241 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4242 "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
4245 ;; Integer addition/subtraction instructions.
4247 (define_expand "adddi3"
4248 [(set (match_operand:DI 0 "register_operand" "")
4249 (plus:DI (match_operand:DI 1 "register_operand" "")
4250 (match_operand:DI 2 "arith_double_add_operand" "")))]
4253 if (! TARGET_ARCH64)
4255 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
4256 gen_rtx_SET (VOIDmode, operands[0],
4257 gen_rtx_PLUS (DImode, operands[1],
4259 gen_rtx_CLOBBER (VOIDmode,
4260 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
4265 (define_insn_and_split "adddi3_insn_sp32"
4266 [(set (match_operand:DI 0 "register_operand" "=r")
4267 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
4268 (match_operand:DI 2 "arith_double_operand" "rHI")))
4269 (clobber (reg:CC 100))]
4272 "&& reload_completed"
4273 [(parallel [(set (reg:CC_NOOV 100)
4274 (compare:CC_NOOV (plus:SI (match_dup 4)
4278 (plus:SI (match_dup 4) (match_dup 5)))])
4280 (plus:SI (plus:SI (match_dup 7)
4282 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4284 operands[3] = gen_lowpart (SImode, operands[0]);
4285 operands[4] = gen_lowpart (SImode, operands[1]);
4286 operands[5] = gen_lowpart (SImode, operands[2]);
4287 operands[6] = gen_highpart (SImode, operands[0]);
4288 operands[7] = gen_highpart_mode (SImode, DImode, operands[1]);
4289 #if HOST_BITS_PER_WIDE_INT == 32
4290 if (GET_CODE (operands[2]) == CONST_INT)
4292 if (INTVAL (operands[2]) < 0)
4293 operands[8] = constm1_rtx;
4295 operands[8] = const0_rtx;
4299 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
4301 [(set_attr "length" "2")])
4303 ;; LTU here means "carry set"
4305 [(set (match_operand:SI 0 "register_operand" "=r")
4306 (plus:SI (plus:SI (match_operand:SI 1 "arith_operand" "%r")
4307 (match_operand:SI 2 "arith_operand" "rI"))
4308 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4311 [(set_attr "type" "ialuX")])
4313 (define_insn_and_split "*addx_extend_sp32"
4314 [(set (match_operand:DI 0 "register_operand" "=r")
4315 (zero_extend:DI (plus:SI (plus:SI
4316 (match_operand:SI 1 "register_or_zero_operand" "%rJ")
4317 (match_operand:SI 2 "arith_operand" "rI"))
4318 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4321 "&& reload_completed"
4322 [(set (match_dup 3) (plus:SI (plus:SI (match_dup 1) (match_dup 2))
4323 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
4324 (set (match_dup 4) (const_int 0))]
4325 "operands[3] = gen_lowpart (SImode, operands[0]);
4326 operands[4] = gen_highpart_mode (SImode, DImode, operands[1]);"
4327 [(set_attr "length" "2")])
4329 (define_insn "*addx_extend_sp64"
4330 [(set (match_operand:DI 0 "register_operand" "=r")
4331 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ")
4332 (match_operand:SI 2 "arith_operand" "rI"))
4333 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4336 [(set_attr "type" "ialuX")])
4338 (define_insn_and_split ""
4339 [(set (match_operand:DI 0 "register_operand" "=r")
4340 (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4341 (match_operand:DI 2 "register_operand" "r")))
4342 (clobber (reg:CC 100))]
4345 "&& reload_completed"
4346 [(parallel [(set (reg:CC_NOOV 100)
4347 (compare:CC_NOOV (plus:SI (match_dup 3) (match_dup 1))
4349 (set (match_dup 5) (plus:SI (match_dup 3) (match_dup 1)))])
4351 (plus:SI (plus:SI (match_dup 4) (const_int 0))
4352 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4353 "operands[3] = gen_lowpart (SImode, operands[2]);
4354 operands[4] = gen_highpart (SImode, operands[2]);
4355 operands[5] = gen_lowpart (SImode, operands[0]);
4356 operands[6] = gen_highpart (SImode, operands[0]);"
4357 [(set_attr "length" "2")])
4359 (define_insn "*adddi3_sp64"
4360 [(set (match_operand:DI 0 "register_operand" "=r,r")
4361 (plus:DI (match_operand:DI 1 "register_operand" "%r,r")
4362 (match_operand:DI 2 "arith_add_operand" "rI,O")))]
4368 (define_insn "addsi3"
4369 [(set (match_operand:SI 0 "register_operand" "=r,r,d")
4370 (plus:SI (match_operand:SI 1 "register_operand" "%r,r,d")
4371 (match_operand:SI 2 "arith_add_operand" "rI,O,d")))]
4376 fpadd32s\t%1, %2, %0"
4377 [(set_attr "type" "*,*,fga")
4378 (set_attr "fptype" "*,*,single")])
4380 (define_insn "*cmp_cc_plus"
4381 [(set (reg:CC_NOOV 100)
4382 (compare:CC_NOOV (plus:SI (match_operand:SI 0 "arith_operand" "%r")
4383 (match_operand:SI 1 "arith_operand" "rI"))
4386 "addcc\t%0, %1, %%g0"
4387 [(set_attr "type" "compare")])
4389 (define_insn "*cmp_ccx_plus"
4390 [(set (reg:CCX_NOOV 100)
4391 (compare:CCX_NOOV (plus:DI (match_operand:DI 0 "arith_operand" "%r")
4392 (match_operand:DI 1 "arith_operand" "rI"))
4395 "addcc\t%0, %1, %%g0"
4396 [(set_attr "type" "compare")])
4398 (define_insn "*cmp_cc_plus_set"
4399 [(set (reg:CC_NOOV 100)
4400 (compare:CC_NOOV (plus:SI (match_operand:SI 1 "arith_operand" "%r")
4401 (match_operand:SI 2 "arith_operand" "rI"))
4403 (set (match_operand:SI 0 "register_operand" "=r")
4404 (plus:SI (match_dup 1) (match_dup 2)))]
4407 [(set_attr "type" "compare")])
4409 (define_insn "*cmp_ccx_plus_set"
4410 [(set (reg:CCX_NOOV 100)
4411 (compare:CCX_NOOV (plus:DI (match_operand:DI 1 "arith_operand" "%r")
4412 (match_operand:DI 2 "arith_operand" "rI"))
4414 (set (match_operand:DI 0 "register_operand" "=r")
4415 (plus:DI (match_dup 1) (match_dup 2)))]
4418 [(set_attr "type" "compare")])
4420 (define_expand "subdi3"
4421 [(set (match_operand:DI 0 "register_operand" "")
4422 (minus:DI (match_operand:DI 1 "register_operand" "")
4423 (match_operand:DI 2 "arith_double_add_operand" "")))]
4426 if (! TARGET_ARCH64)
4428 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
4429 gen_rtx_SET (VOIDmode, operands[0],
4430 gen_rtx_MINUS (DImode, operands[1],
4432 gen_rtx_CLOBBER (VOIDmode,
4433 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
4438 (define_insn_and_split "subdi3_insn_sp32"
4439 [(set (match_operand:DI 0 "register_operand" "=r")
4440 (minus:DI (match_operand:DI 1 "register_operand" "r")
4441 (match_operand:DI 2 "arith_double_operand" "rHI")))
4442 (clobber (reg:CC 100))]
4445 "&& reload_completed"
4446 [(parallel [(set (reg:CC_NOOV 100)
4447 (compare:CC_NOOV (minus:SI (match_dup 4)
4451 (minus:SI (match_dup 4) (match_dup 5)))])
4453 (minus:SI (minus:SI (match_dup 7)
4455 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4457 operands[3] = gen_lowpart (SImode, operands[0]);
4458 operands[4] = gen_lowpart (SImode, operands[1]);
4459 operands[5] = gen_lowpart (SImode, operands[2]);
4460 operands[6] = gen_highpart (SImode, operands[0]);
4461 operands[7] = gen_highpart (SImode, operands[1]);
4462 #if HOST_BITS_PER_WIDE_INT == 32
4463 if (GET_CODE (operands[2]) == CONST_INT)
4465 if (INTVAL (operands[2]) < 0)
4466 operands[8] = constm1_rtx;
4468 operands[8] = const0_rtx;
4472 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
4474 [(set_attr "length" "2")])
4476 ;; LTU here means "carry set"
4478 [(set (match_operand:SI 0 "register_operand" "=r")
4479 (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
4480 (match_operand:SI 2 "arith_operand" "rI"))
4481 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4484 [(set_attr "type" "ialuX")])
4486 (define_insn "*subx_extend_sp64"
4487 [(set (match_operand:DI 0 "register_operand" "=r")
4488 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
4489 (match_operand:SI 2 "arith_operand" "rI"))
4490 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4493 [(set_attr "type" "ialuX")])
4495 (define_insn_and_split "*subx_extend"
4496 [(set (match_operand:DI 0 "register_operand" "=r")
4497 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
4498 (match_operand:SI 2 "arith_operand" "rI"))
4499 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4502 "&& reload_completed"
4503 [(set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 2))
4504 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
4505 (set (match_dup 4) (const_int 0))]
4506 "operands[3] = gen_lowpart (SImode, operands[0]);
4507 operands[4] = gen_highpart (SImode, operands[0]);"
4508 [(set_attr "length" "2")])
4510 (define_insn_and_split ""
4511 [(set (match_operand:DI 0 "register_operand" "=r")
4512 (minus:DI (match_operand:DI 1 "register_operand" "r")
4513 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))
4514 (clobber (reg:CC 100))]
4517 "&& reload_completed"
4518 [(parallel [(set (reg:CC_NOOV 100)
4519 (compare:CC_NOOV (minus:SI (match_dup 3) (match_dup 2))
4521 (set (match_dup 5) (minus:SI (match_dup 3) (match_dup 2)))])
4523 (minus:SI (minus:SI (match_dup 4) (const_int 0))
4524 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4525 "operands[3] = gen_lowpart (SImode, operands[1]);
4526 operands[4] = gen_highpart (SImode, operands[1]);
4527 operands[5] = gen_lowpart (SImode, operands[0]);
4528 operands[6] = gen_highpart (SImode, operands[0]);"
4529 [(set_attr "length" "2")])
4531 (define_insn "*subdi3_sp64"
4532 [(set (match_operand:DI 0 "register_operand" "=r,r")
4533 (minus:DI (match_operand:DI 1 "register_operand" "r,r")
4534 (match_operand:DI 2 "arith_add_operand" "rI,O")))]
4540 (define_insn "subsi3"
4541 [(set (match_operand:SI 0 "register_operand" "=r,r,d")
4542 (minus:SI (match_operand:SI 1 "register_operand" "r,r,d")
4543 (match_operand:SI 2 "arith_add_operand" "rI,O,d")))]
4548 fpsub32s\t%1, %2, %0"
4549 [(set_attr "type" "*,*,fga")
4550 (set_attr "fptype" "*,*,single")])
4552 (define_insn "*cmp_minus_cc"
4553 [(set (reg:CC_NOOV 100)
4554 (compare:CC_NOOV (minus:SI (match_operand:SI 0 "register_or_zero_operand" "rJ")
4555 (match_operand:SI 1 "arith_operand" "rI"))
4558 "subcc\t%r0, %1, %%g0"
4559 [(set_attr "type" "compare")])
4561 (define_insn "*cmp_minus_ccx"
4562 [(set (reg:CCX_NOOV 100)
4563 (compare:CCX_NOOV (minus:DI (match_operand:DI 0 "register_operand" "r")
4564 (match_operand:DI 1 "arith_operand" "rI"))
4567 "subcc\t%0, %1, %%g0"
4568 [(set_attr "type" "compare")])
4570 (define_insn "cmp_minus_cc_set"
4571 [(set (reg:CC_NOOV 100)
4572 (compare:CC_NOOV (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
4573 (match_operand:SI 2 "arith_operand" "rI"))
4575 (set (match_operand:SI 0 "register_operand" "=r")
4576 (minus:SI (match_dup 1) (match_dup 2)))]
4578 "subcc\t%r1, %2, %0"
4579 [(set_attr "type" "compare")])
4581 (define_insn "*cmp_minus_ccx_set"
4582 [(set (reg:CCX_NOOV 100)
4583 (compare:CCX_NOOV (minus:DI (match_operand:DI 1 "register_operand" "r")
4584 (match_operand:DI 2 "arith_operand" "rI"))
4586 (set (match_operand:DI 0 "register_operand" "=r")
4587 (minus:DI (match_dup 1) (match_dup 2)))]
4590 [(set_attr "type" "compare")])
4593 ;; Integer multiply/divide instructions.
4595 ;; The 32 bit multiply/divide instructions are deprecated on v9, but at
4596 ;; least in UltraSPARC I, II and IIi it is a win tick-wise.
4598 (define_insn "mulsi3"
4599 [(set (match_operand:SI 0 "register_operand" "=r")
4600 (mult:SI (match_operand:SI 1 "arith_operand" "%r")
4601 (match_operand:SI 2 "arith_operand" "rI")))]
4604 [(set_attr "type" "imul")])
4606 (define_expand "muldi3"
4607 [(set (match_operand:DI 0 "register_operand" "")
4608 (mult:DI (match_operand:DI 1 "arith_operand" "")
4609 (match_operand:DI 2 "arith_operand" "")))]
4610 "TARGET_ARCH64 || TARGET_V8PLUS"
4614 emit_insn (gen_muldi3_v8plus (operands[0], operands[1], operands[2]));
4619 (define_insn "*muldi3_sp64"
4620 [(set (match_operand:DI 0 "register_operand" "=r")
4621 (mult:DI (match_operand:DI 1 "arith_operand" "%r")
4622 (match_operand:DI 2 "arith_operand" "rI")))]
4625 [(set_attr "type" "imul")])
4627 ;; V8plus wide multiply.
4629 (define_insn "muldi3_v8plus"
4630 [(set (match_operand:DI 0 "register_operand" "=r,h")
4631 (mult:DI (match_operand:DI 1 "arith_operand" "%r,0")
4632 (match_operand:DI 2 "arith_operand" "rI,rI")))
4633 (clobber (match_scratch:SI 3 "=&h,X"))
4634 (clobber (match_scratch:SI 4 "=&h,X"))]
4637 if (sparc_check_64 (operands[1], insn) <= 0)
4638 output_asm_insn ("srl\t%L1, 0, %L1", operands);
4639 if (which_alternative == 1)
4640 output_asm_insn ("sllx\t%H1, 32, %H1", operands);
4641 if (GET_CODE (operands[2]) == CONST_INT)
4643 if (which_alternative == 1)
4644 return "or\t%L1, %H1, %H1\n\tmulx\t%H1, %2, %L0\;srlx\t%L0, 32, %H0";
4646 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";
4648 else if (rtx_equal_p (operands[1], operands[2]))
4650 if (which_alternative == 1)
4651 return "or\t%L1, %H1, %H1\n\tmulx\t%H1, %H1, %L0\;srlx\t%L0, 32, %H0";
4653 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";
4655 if (sparc_check_64 (operands[2], insn) <= 0)
4656 output_asm_insn ("srl\t%L2, 0, %L2", operands);
4657 if (which_alternative == 1)
4658 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";
4660 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";
4662 [(set_attr "type" "multi")
4663 (set_attr "length" "9,8")])
4665 (define_insn "*cmp_mul_set"
4667 (compare:CC (mult:SI (match_operand:SI 1 "arith_operand" "%r")
4668 (match_operand:SI 2 "arith_operand" "rI"))
4670 (set (match_operand:SI 0 "register_operand" "=r")
4671 (mult:SI (match_dup 1) (match_dup 2)))]
4672 "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS"
4673 "smulcc\t%1, %2, %0"
4674 [(set_attr "type" "imul")])
4676 (define_expand "mulsidi3"
4677 [(set (match_operand:DI 0 "register_operand" "")
4678 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
4679 (sign_extend:DI (match_operand:SI 2 "arith_operand" ""))))]
4682 if (CONSTANT_P (operands[2]))
4685 emit_insn (gen_const_mulsidi3_v8plus (operands[0], operands[1],
4687 else if (TARGET_ARCH32)
4688 emit_insn (gen_const_mulsidi3_sp32 (operands[0], operands[1],
4691 emit_insn (gen_const_mulsidi3_sp64 (operands[0], operands[1],
4697 emit_insn (gen_mulsidi3_v8plus (operands[0], operands[1], operands[2]));
4702 ;; V9 puts the 64 bit product in a 64 bit register. Only out or global
4703 ;; registers can hold 64 bit values in the V8plus environment.
4705 (define_insn "mulsidi3_v8plus"
4706 [(set (match_operand:DI 0 "register_operand" "=h,r")
4707 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4708 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
4709 (clobber (match_scratch:SI 3 "=X,&h"))]
4712 smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
4713 smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4714 [(set_attr "type" "multi")
4715 (set_attr "length" "2,3")])
4718 (define_insn "const_mulsidi3_v8plus"
4719 [(set (match_operand:DI 0 "register_operand" "=h,r")
4720 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4721 (match_operand:DI 2 "small_int_operand" "I,I")))
4722 (clobber (match_scratch:SI 3 "=X,&h"))]
4725 smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
4726 smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4727 [(set_attr "type" "multi")
4728 (set_attr "length" "2,3")])
4731 (define_insn "*mulsidi3_sp32"
4732 [(set (match_operand:DI 0 "register_operand" "=r")
4733 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4734 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4737 return TARGET_SPARCLET
4738 ? "smuld\t%1, %2, %L0"
4739 : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
4742 (if_then_else (eq_attr "isa" "sparclet")
4743 (const_string "imul") (const_string "multi")))
4744 (set (attr "length")
4745 (if_then_else (eq_attr "isa" "sparclet")
4746 (const_int 1) (const_int 2)))])
4748 (define_insn "*mulsidi3_sp64"
4749 [(set (match_operand:DI 0 "register_operand" "=r")
4750 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4751 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4752 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4754 [(set_attr "type" "imul")])
4756 ;; Extra pattern, because sign_extend of a constant isn't valid.
4759 (define_insn "const_mulsidi3_sp32"
4760 [(set (match_operand:DI 0 "register_operand" "=r")
4761 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4762 (match_operand:DI 2 "small_int_operand" "I")))]
4765 return TARGET_SPARCLET
4766 ? "smuld\t%1, %2, %L0"
4767 : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
4770 (if_then_else (eq_attr "isa" "sparclet")
4771 (const_string "imul") (const_string "multi")))
4772 (set (attr "length")
4773 (if_then_else (eq_attr "isa" "sparclet")
4774 (const_int 1) (const_int 2)))])
4776 (define_insn "const_mulsidi3_sp64"
4777 [(set (match_operand:DI 0 "register_operand" "=r")
4778 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4779 (match_operand:DI 2 "small_int_operand" "I")))]
4780 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4782 [(set_attr "type" "imul")])
4784 (define_expand "smulsi3_highpart"
4785 [(set (match_operand:SI 0 "register_operand" "")
4787 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
4788 (sign_extend:DI (match_operand:SI 2 "arith_operand" "")))
4790 "TARGET_HARD_MUL && TARGET_ARCH32"
4792 if (CONSTANT_P (operands[2]))
4796 emit_insn (gen_const_smulsi3_highpart_v8plus (operands[0],
4802 emit_insn (gen_const_smulsi3_highpart (operands[0], operands[1], operands[2]));
4807 emit_insn (gen_smulsi3_highpart_v8plus (operands[0], operands[1],
4808 operands[2], GEN_INT (32)));
4814 (define_insn "smulsi3_highpart_v8plus"
4815 [(set (match_operand:SI 0 "register_operand" "=h,r")
4817 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4818 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
4819 (match_operand:SI 3 "small_int_operand" "I,I"))))
4820 (clobber (match_scratch:SI 4 "=X,&h"))]
4823 smul\t%1, %2, %0\;srlx\t%0, %3, %0
4824 smul\t%1, %2, %4\;srlx\t%4, %3, %0"
4825 [(set_attr "type" "multi")
4826 (set_attr "length" "2")])
4828 ;; The combiner changes TRUNCATE in the previous pattern to SUBREG.
4831 [(set (match_operand:SI 0 "register_operand" "=h,r")
4834 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4835 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
4836 (match_operand:SI 3 "small_int_operand" "I,I"))
4838 (clobber (match_scratch:SI 4 "=X,&h"))]
4841 smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
4842 smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
4843 [(set_attr "type" "multi")
4844 (set_attr "length" "2")])
4847 (define_insn "const_smulsi3_highpart_v8plus"
4848 [(set (match_operand:SI 0 "register_operand" "=h,r")
4850 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4851 (match_operand:DI 2 "small_int_operand" "I,I"))
4852 (match_operand:SI 3 "small_int_operand" "I,I"))))
4853 (clobber (match_scratch:SI 4 "=X,&h"))]
4856 smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
4857 smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
4858 [(set_attr "type" "multi")
4859 (set_attr "length" "2")])
4862 (define_insn "*smulsi3_highpart_sp32"
4863 [(set (match_operand:SI 0 "register_operand" "=r")
4865 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4866 (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
4869 "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
4870 [(set_attr "type" "multi")
4871 (set_attr "length" "2")])
4874 (define_insn "const_smulsi3_highpart"
4875 [(set (match_operand:SI 0 "register_operand" "=r")
4877 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4878 (match_operand:DI 2 "small_int_operand" "i"))
4881 "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
4882 [(set_attr "type" "multi")
4883 (set_attr "length" "2")])
4885 (define_expand "umulsidi3"
4886 [(set (match_operand:DI 0 "register_operand" "")
4887 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
4888 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" ""))))]
4891 if (CONSTANT_P (operands[2]))
4894 emit_insn (gen_const_umulsidi3_v8plus (operands[0], operands[1],
4896 else if (TARGET_ARCH32)
4897 emit_insn (gen_const_umulsidi3_sp32 (operands[0], operands[1],
4900 emit_insn (gen_const_umulsidi3_sp64 (operands[0], operands[1],
4906 emit_insn (gen_umulsidi3_v8plus (operands[0], operands[1], operands[2]));
4912 (define_insn "umulsidi3_v8plus"
4913 [(set (match_operand:DI 0 "register_operand" "=h,r")
4914 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4915 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
4916 (clobber (match_scratch:SI 3 "=X,&h"))]
4919 umul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
4920 umul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4921 [(set_attr "type" "multi")
4922 (set_attr "length" "2,3")])
4925 (define_insn "*umulsidi3_sp32"
4926 [(set (match_operand:DI 0 "register_operand" "=r")
4927 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4928 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4931 return TARGET_SPARCLET
4932 ? "umuld\t%1, %2, %L0"
4933 : "umul\t%1, %2, %L0\n\trd\t%%y, %H0";
4936 (if_then_else (eq_attr "isa" "sparclet")
4937 (const_string "imul") (const_string "multi")))
4938 (set (attr "length")
4939 (if_then_else (eq_attr "isa" "sparclet")
4940 (const_int 1) (const_int 2)))])
4942 (define_insn "*umulsidi3_sp64"
4943 [(set (match_operand:DI 0 "register_operand" "=r")
4944 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4945 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4946 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4948 [(set_attr "type" "imul")])
4950 ;; Extra pattern, because sign_extend of a constant isn't valid.
4953 (define_insn "const_umulsidi3_sp32"
4954 [(set (match_operand:DI 0 "register_operand" "=r")
4955 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4956 (match_operand:DI 2 "uns_small_int_operand" "")))]
4959 return TARGET_SPARCLET
4960 ? "umuld\t%1, %s2, %L0"
4961 : "umul\t%1, %s2, %L0\n\trd\t%%y, %H0";
4964 (if_then_else (eq_attr "isa" "sparclet")
4965 (const_string "imul") (const_string "multi")))
4966 (set (attr "length")
4967 (if_then_else (eq_attr "isa" "sparclet")
4968 (const_int 1) (const_int 2)))])
4970 (define_insn "const_umulsidi3_sp64"
4971 [(set (match_operand:DI 0 "register_operand" "=r")
4972 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4973 (match_operand:DI 2 "uns_small_int_operand" "")))]
4974 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4976 [(set_attr "type" "imul")])
4979 (define_insn "const_umulsidi3_v8plus"
4980 [(set (match_operand:DI 0 "register_operand" "=h,r")
4981 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4982 (match_operand:DI 2 "uns_small_int_operand" "")))
4983 (clobber (match_scratch:SI 3 "=X,h"))]
4986 umul\t%1, %s2, %L0\n\tsrlx\t%L0, 32, %H0
4987 umul\t%1, %s2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4988 [(set_attr "type" "multi")
4989 (set_attr "length" "2,3")])
4991 (define_expand "umulsi3_highpart"
4992 [(set (match_operand:SI 0 "register_operand" "")
4994 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
4995 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" "")))
4997 "TARGET_HARD_MUL && TARGET_ARCH32"
4999 if (CONSTANT_P (operands[2]))
5003 emit_insn (gen_const_umulsi3_highpart_v8plus (operands[0],
5009 emit_insn (gen_const_umulsi3_highpart (operands[0], operands[1], operands[2]));
5014 emit_insn (gen_umulsi3_highpart_v8plus (operands[0], operands[1],
5015 operands[2], GEN_INT (32)));
5021 (define_insn "umulsi3_highpart_v8plus"
5022 [(set (match_operand:SI 0 "register_operand" "=h,r")
5024 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5025 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
5026 (match_operand:SI 3 "small_int_operand" "I,I"))))
5027 (clobber (match_scratch:SI 4 "=X,h"))]
5030 umul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
5031 umul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
5032 [(set_attr "type" "multi")
5033 (set_attr "length" "2")])
5036 (define_insn "const_umulsi3_highpart_v8plus"
5037 [(set (match_operand:SI 0 "register_operand" "=h,r")
5039 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5040 (match_operand:DI 2 "uns_small_int_operand" ""))
5041 (match_operand:SI 3 "small_int_operand" "I,I"))))
5042 (clobber (match_scratch:SI 4 "=X,h"))]
5045 umul\t%1, %s2, %0\n\tsrlx\t%0, %3, %0
5046 umul\t%1, %s2, %4\n\tsrlx\t%4, %3, %0"
5047 [(set_attr "type" "multi")
5048 (set_attr "length" "2")])
5051 (define_insn "*umulsi3_highpart_sp32"
5052 [(set (match_operand:SI 0 "register_operand" "=r")
5054 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5055 (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
5058 "umul\t%1, %2, %%g0\n\trd\t%%y, %0"
5059 [(set_attr "type" "multi")
5060 (set_attr "length" "2")])
5063 (define_insn "const_umulsi3_highpart"
5064 [(set (match_operand:SI 0 "register_operand" "=r")
5066 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5067 (match_operand:DI 2 "uns_small_int_operand" ""))
5070 "umul\t%1, %s2, %%g0\n\trd\t%%y, %0"
5071 [(set_attr "type" "multi")
5072 (set_attr "length" "2")])
5074 ;; The V8 architecture specifies that there must be 3 instructions between
5075 ;; a Y register write and a use of it for correct results.
5077 (define_expand "divsi3"
5078 [(parallel [(set (match_operand:SI 0 "register_operand" "=r,r")
5079 (div:SI (match_operand:SI 1 "register_operand" "r,r")
5080 (match_operand:SI 2 "input_operand" "rI,m")))
5081 (clobber (match_scratch:SI 3 "=&r,&r"))])]
5082 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
5086 operands[3] = gen_reg_rtx(SImode);
5087 emit_insn (gen_ashrsi3 (operands[3], operands[1], GEN_INT (31)));
5088 emit_insn (gen_divsi3_sp64 (operands[0], operands[1], operands[2],
5094 (define_insn "divsi3_sp32"
5095 [(set (match_operand:SI 0 "register_operand" "=r,r")
5096 (div:SI (match_operand:SI 1 "register_operand" "r,r")
5097 (match_operand:SI 2 "input_operand" "rI,m")))
5098 (clobber (match_scratch:SI 3 "=&r,&r"))]
5099 "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS)
5102 if (which_alternative == 0)
5104 return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tsdiv\t%1, %2, %0";
5106 return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tnop\n\tnop\n\tnop\n\tsdiv\t%1, %2, %0";
5109 return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tld\t%2, %3\n\tsdiv\t%1, %3, %0";
5111 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";
5113 [(set_attr "type" "multi")
5114 (set (attr "length")
5115 (if_then_else (eq_attr "isa" "v9")
5116 (const_int 4) (const_int 6)))])
5118 (define_insn "divsi3_sp64"
5119 [(set (match_operand:SI 0 "register_operand" "=r")
5120 (div:SI (match_operand:SI 1 "register_operand" "r")
5121 (match_operand:SI 2 "input_operand" "rI")))
5122 (use (match_operand:SI 3 "register_operand" "r"))]
5123 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5124 "wr\t%%g0, %3, %%y\n\tsdiv\t%1, %2, %0"
5125 [(set_attr "type" "multi")
5126 (set_attr "length" "2")])
5128 (define_insn "divdi3"
5129 [(set (match_operand:DI 0 "register_operand" "=r")
5130 (div:DI (match_operand:DI 1 "register_operand" "r")
5131 (match_operand:DI 2 "arith_operand" "rI")))]
5134 [(set_attr "type" "idiv")])
5136 (define_insn "*cmp_sdiv_cc_set"
5138 (compare:CC (div:SI (match_operand:SI 1 "register_operand" "r")
5139 (match_operand:SI 2 "arith_operand" "rI"))
5141 (set (match_operand:SI 0 "register_operand" "=r")
5142 (div:SI (match_dup 1) (match_dup 2)))
5143 (clobber (match_scratch:SI 3 "=&r"))]
5144 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
5147 return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tsdivcc\t%1, %2, %0";
5149 return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tnop\n\tnop\n\tnop\n\tsdivcc\t%1, %2, %0";
5151 [(set_attr "type" "multi")
5152 (set (attr "length")
5153 (if_then_else (eq_attr "isa" "v9")
5154 (const_int 3) (const_int 6)))])
5157 (define_expand "udivsi3"
5158 [(set (match_operand:SI 0 "register_operand" "")
5159 (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "")
5160 (match_operand:SI 2 "input_operand" "")))]
5161 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
5164 ;; The V8 architecture specifies that there must be 3 instructions between
5165 ;; a Y register write and a use of it for correct results.
5167 (define_insn "udivsi3_sp32"
5168 [(set (match_operand:SI 0 "register_operand" "=r,&r,&r")
5169 (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "r,r,m")
5170 (match_operand:SI 2 "input_operand" "rI,m,r")))]
5171 "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS)
5174 output_asm_insn ("wr\t%%g0, %%g0, %%y", operands);
5175 switch (which_alternative)
5178 return "nop\n\tnop\n\tnop\n\tudiv\t%1, %2, %0";
5180 return "ld\t%2, %0\n\tnop\n\tnop\n\tudiv\t%1, %0, %0";
5182 return "ld\t%1, %0\n\tnop\n\tnop\n\tudiv\t%0, %2, %0";
5185 [(set_attr "type" "multi")
5186 (set_attr "length" "5")])
5188 (define_insn "udivsi3_sp64"
5189 [(set (match_operand:SI 0 "register_operand" "=r")
5190 (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "r")
5191 (match_operand:SI 2 "input_operand" "rI")))]
5192 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5193 "wr\t%%g0, 0, %%y\n\tudiv\t%1, %2, %0"
5194 [(set_attr "type" "multi")
5195 (set_attr "length" "2")])
5197 (define_insn "udivdi3"
5198 [(set (match_operand:DI 0 "register_operand" "=r")
5199 (udiv:DI (match_operand:DI 1 "register_operand" "r")
5200 (match_operand:DI 2 "arith_operand" "rI")))]
5203 [(set_attr "type" "idiv")])
5205 (define_insn "*cmp_udiv_cc_set"
5207 (compare:CC (udiv:SI (match_operand:SI 1 "register_operand" "r")
5208 (match_operand:SI 2 "arith_operand" "rI"))
5210 (set (match_operand:SI 0 "register_operand" "=r")
5211 (udiv:SI (match_dup 1) (match_dup 2)))]
5213 || TARGET_DEPRECATED_V8_INSNS"
5216 return "wr\t%%g0, %%g0, %%y\n\tudivcc\t%1, %2, %0";
5218 return "wr\t%%g0, %%g0, %%y\n\tnop\n\tnop\n\tnop\n\tudivcc\t%1, %2, %0";
5220 [(set_attr "type" "multi")
5221 (set (attr "length")
5222 (if_then_else (eq_attr "isa" "v9")
5223 (const_int 2) (const_int 5)))])
5225 ; sparclet multiply/accumulate insns
5227 (define_insn "*smacsi"
5228 [(set (match_operand:SI 0 "register_operand" "=r")
5229 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "%r")
5230 (match_operand:SI 2 "arith_operand" "rI"))
5231 (match_operand:SI 3 "register_operand" "0")))]
5234 [(set_attr "type" "imul")])
5236 (define_insn "*smacdi"
5237 [(set (match_operand:DI 0 "register_operand" "=r")
5238 (plus:DI (mult:DI (sign_extend:DI
5239 (match_operand:SI 1 "register_operand" "%r"))
5241 (match_operand:SI 2 "register_operand" "r")))
5242 (match_operand:DI 3 "register_operand" "0")))]
5244 "smacd\t%1, %2, %L0"
5245 [(set_attr "type" "imul")])
5247 (define_insn "*umacdi"
5248 [(set (match_operand:DI 0 "register_operand" "=r")
5249 (plus:DI (mult:DI (zero_extend:DI
5250 (match_operand:SI 1 "register_operand" "%r"))
5252 (match_operand:SI 2 "register_operand" "r")))
5253 (match_operand:DI 3 "register_operand" "0")))]
5255 "umacd\t%1, %2, %L0"
5256 [(set_attr "type" "imul")])
5259 ;; Boolean instructions.
5261 ;; We define DImode `and' so with DImode `not' we can get
5262 ;; DImode `andn'. Other combinations are possible.
5264 (define_mode_macro V64I [DI V2SI V4HI V8QI])
5265 (define_mode_macro V32I [SI V2HI V4QI])
5267 (define_expand "and<V64I:mode>3"
5268 [(set (match_operand:V64I 0 "register_operand" "")
5269 (and:V64I (match_operand:V64I 1 "arith_double_operand" "")
5270 (match_operand:V64I 2 "arith_double_operand" "")))]
5274 (define_insn "*and<V64I:mode>3_sp32"
5275 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5276 (and:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
5277 (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
5282 [(set_attr "type" "*,fga")
5283 (set_attr "length" "2,*")
5284 (set_attr "fptype" "*,double")])
5286 (define_insn "*and<V64I:mode>3_sp64"
5287 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5288 (and:V64I (match_operand:V64I 1 "arith_operand" "%r,b")
5289 (match_operand:V64I 2 "arith_operand" "rI,b")))]
5294 [(set_attr "type" "*,fga")
5295 (set_attr "fptype" "*,double")])
5297 (define_insn "and<V32I:mode>3"
5298 [(set (match_operand:V32I 0 "register_operand" "=r,d")
5299 (and:V32I (match_operand:V32I 1 "arith_operand" "%r,d")
5300 (match_operand:V32I 2 "arith_operand" "rI,d")))]
5305 [(set_attr "type" "*,fga")
5306 (set_attr "fptype" "*,single")])
5309 [(set (match_operand:SI 0 "register_operand" "")
5310 (and:SI (match_operand:SI 1 "register_operand" "")
5311 (match_operand:SI 2 "const_compl_high_operand" "")))
5312 (clobber (match_operand:SI 3 "register_operand" ""))]
5314 [(set (match_dup 3) (match_dup 4))
5315 (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 1)))]
5317 operands[4] = GEN_INT (~INTVAL (operands[2]));
5320 (define_insn_and_split "*and_not_<V64I:mode>_sp32"
5321 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5322 (and:V64I (not:V64I (match_operand:V64I 1 "register_operand" "%r,b"))
5323 (match_operand:V64I 2 "register_operand" "r,b")))]
5327 fandnot1\t%1, %2, %0"
5328 "&& reload_completed
5329 && ((GET_CODE (operands[0]) == REG
5330 && REGNO (operands[0]) < 32)
5331 || (GET_CODE (operands[0]) == SUBREG
5332 && GET_CODE (SUBREG_REG (operands[0])) == REG
5333 && REGNO (SUBREG_REG (operands[0])) < 32))"
5334 [(set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))
5335 (set (match_dup 6) (and:SI (not:SI (match_dup 7)) (match_dup 8)))]
5336 "operands[3] = gen_highpart (SImode, operands[0]);
5337 operands[4] = gen_highpart (SImode, operands[1]);
5338 operands[5] = gen_highpart (SImode, operands[2]);
5339 operands[6] = gen_lowpart (SImode, operands[0]);
5340 operands[7] = gen_lowpart (SImode, operands[1]);
5341 operands[8] = gen_lowpart (SImode, operands[2]);"
5342 [(set_attr "type" "*,fga")
5343 (set_attr "length" "2,*")
5344 (set_attr "fptype" "*,double")])
5346 (define_insn "*and_not_<V64I:mode>_sp64"
5347 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5348 (and:V64I (not:V64I (match_operand:V64I 1 "register_operand" "%r,b"))
5349 (match_operand:V64I 2 "register_operand" "r,b")))]
5353 fandnot1\t%1, %2, %0"
5354 [(set_attr "type" "*,fga")
5355 (set_attr "fptype" "*,double")])
5357 (define_insn "*and_not_<V32I:mode>"
5358 [(set (match_operand:V32I 0 "register_operand" "=r,d")
5359 (and:V32I (not:V32I (match_operand:V32I 1 "register_operand" "%r,d"))
5360 (match_operand:V32I 2 "register_operand" "r,d")))]
5364 fandnot1s\t%1, %2, %0"
5365 [(set_attr "type" "*,fga")
5366 (set_attr "fptype" "*,single")])
5368 (define_expand "ior<V64I:mode>3"
5369 [(set (match_operand:V64I 0 "register_operand" "")
5370 (ior:V64I (match_operand:V64I 1 "arith_double_operand" "")
5371 (match_operand:V64I 2 "arith_double_operand" "")))]
5375 (define_insn "*ior<V64I:mode>3_sp32"
5376 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5377 (ior:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
5378 (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
5383 [(set_attr "type" "*,fga")
5384 (set_attr "length" "2,*")
5385 (set_attr "fptype" "*,double")])
5387 (define_insn "*ior<V64I:mode>3_sp64"
5388 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5389 (ior:V64I (match_operand:V64I 1 "arith_operand" "%r,b")
5390 (match_operand:V64I 2 "arith_operand" "rI,b")))]
5395 [(set_attr "type" "*,fga")
5396 (set_attr "fptype" "*,double")])
5398 (define_insn "ior<V32I:mode>3"
5399 [(set (match_operand:V32I 0 "register_operand" "=r,d")
5400 (ior:V32I (match_operand:V32I 1 "arith_operand" "%r,d")
5401 (match_operand:V32I 2 "arith_operand" "rI,d")))]
5406 [(set_attr "type" "*,fga")
5407 (set_attr "fptype" "*,single")])
5410 [(set (match_operand:SI 0 "register_operand" "")
5411 (ior:SI (match_operand:SI 1 "register_operand" "")
5412 (match_operand:SI 2 "const_compl_high_operand" "")))
5413 (clobber (match_operand:SI 3 "register_operand" ""))]
5415 [(set (match_dup 3) (match_dup 4))
5416 (set (match_dup 0) (ior:SI (not:SI (match_dup 3)) (match_dup 1)))]
5418 operands[4] = GEN_INT (~INTVAL (operands[2]));
5421 (define_insn_and_split "*or_not_<V64I:mode>_sp32"
5422 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5423 (ior:V64I (not:V64I (match_operand:V64I 1 "register_operand" "r,b"))
5424 (match_operand:V64I 2 "register_operand" "r,b")))]
5428 fornot1\t%1, %2, %0"
5429 "&& reload_completed
5430 && ((GET_CODE (operands[0]) == REG
5431 && REGNO (operands[0]) < 32)
5432 || (GET_CODE (operands[0]) == SUBREG
5433 && GET_CODE (SUBREG_REG (operands[0])) == REG
5434 && REGNO (SUBREG_REG (operands[0])) < 32))"
5435 [(set (match_dup 3) (ior:SI (not:SI (match_dup 4)) (match_dup 5)))
5436 (set (match_dup 6) (ior:SI (not:SI (match_dup 7)) (match_dup 8)))]
5437 "operands[3] = gen_highpart (SImode, operands[0]);
5438 operands[4] = gen_highpart (SImode, operands[1]);
5439 operands[5] = gen_highpart (SImode, operands[2]);
5440 operands[6] = gen_lowpart (SImode, operands[0]);
5441 operands[7] = gen_lowpart (SImode, operands[1]);
5442 operands[8] = gen_lowpart (SImode, operands[2]);"
5443 [(set_attr "type" "*,fga")
5444 (set_attr "length" "2,*")
5445 (set_attr "fptype" "*,double")])
5447 (define_insn "*or_not_<V64I:mode>_sp64"
5448 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5449 (ior:V64I (not:V64I (match_operand:V64I 1 "register_operand" "r,b"))
5450 (match_operand:V64I 2 "register_operand" "r,b")))]
5454 fornot1\t%1, %2, %0"
5455 [(set_attr "type" "*,fga")
5456 (set_attr "fptype" "*,double")])
5458 (define_insn "*or_not_<V32I:mode>"
5459 [(set (match_operand:V32I 0 "register_operand" "=r,d")
5460 (ior:V32I (not:V32I (match_operand:V32I 1 "register_operand" "r,d"))
5461 (match_operand:V32I 2 "register_operand" "r,d")))]
5465 fornot1s\t%1, %2, %0"
5466 [(set_attr "type" "*,fga")
5467 (set_attr "fptype" "*,single")])
5469 (define_expand "xor<V64I:mode>3"
5470 [(set (match_operand:V64I 0 "register_operand" "")
5471 (xor:V64I (match_operand:V64I 1 "arith_double_operand" "")
5472 (match_operand:V64I 2 "arith_double_operand" "")))]
5476 (define_insn "*xor<V64I:mode>3_sp32"
5477 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5478 (xor:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
5479 (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
5484 [(set_attr "type" "*,fga")
5485 (set_attr "length" "2,*")
5486 (set_attr "fptype" "*,double")])
5488 (define_insn "*xor<V64I:mode>3_sp64"
5489 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5490 (xor:V64I (match_operand:V64I 1 "arith_operand" "%rJ,b")
5491 (match_operand:V64I 2 "arith_operand" "rI,b")))]
5496 [(set_attr "type" "*,fga")
5497 (set_attr "fptype" "*,double")])
5499 (define_insn "xor<V32I:mode>3"
5500 [(set (match_operand:V32I 0 "register_operand" "=r,d")
5501 (xor:V32I (match_operand:V32I 1 "arith_operand" "%rJ,d")
5502 (match_operand:V32I 2 "arith_operand" "rI,d")))]
5507 [(set_attr "type" "*,fga")
5508 (set_attr "fptype" "*,single")])
5511 [(set (match_operand:SI 0 "register_operand" "")
5512 (xor:SI (match_operand:SI 1 "register_operand" "")
5513 (match_operand:SI 2 "const_compl_high_operand" "")))
5514 (clobber (match_operand:SI 3 "register_operand" ""))]
5516 [(set (match_dup 3) (match_dup 4))
5517 (set (match_dup 0) (not:SI (xor:SI (match_dup 3) (match_dup 1))))]
5519 operands[4] = GEN_INT (~INTVAL (operands[2]));
5523 [(set (match_operand:SI 0 "register_operand" "")
5524 (not:SI (xor:SI (match_operand:SI 1 "register_operand" "")
5525 (match_operand:SI 2 "const_compl_high_operand" ""))))
5526 (clobber (match_operand:SI 3 "register_operand" ""))]
5528 [(set (match_dup 3) (match_dup 4))
5529 (set (match_dup 0) (xor:SI (match_dup 3) (match_dup 1)))]
5531 operands[4] = GEN_INT (~INTVAL (operands[2]));
5534 ;; Split DImode logical operations requiring two instructions.
5536 [(set (match_operand:V64I 0 "register_operand" "")
5537 (match_operator:V64I 1 "cc_arith_operator" ; AND, IOR, XOR
5538 [(match_operand:V64I 2 "register_operand" "")
5539 (match_operand:V64I 3 "arith_double_operand" "")]))]
5542 && ((GET_CODE (operands[0]) == REG
5543 && REGNO (operands[0]) < 32)
5544 || (GET_CODE (operands[0]) == SUBREG
5545 && GET_CODE (SUBREG_REG (operands[0])) == REG
5546 && REGNO (SUBREG_REG (operands[0])) < 32))"
5547 [(set (match_dup 4) (match_op_dup:SI 1 [(match_dup 6) (match_dup 8)]))
5548 (set (match_dup 5) (match_op_dup:SI 1 [(match_dup 7) (match_dup 9)]))]
5550 operands[4] = gen_highpart (SImode, operands[0]);
5551 operands[5] = gen_lowpart (SImode, operands[0]);
5552 operands[6] = gen_highpart (SImode, operands[2]);
5553 operands[7] = gen_lowpart (SImode, operands[2]);
5554 #if HOST_BITS_PER_WIDE_INT == 32
5555 if (GET_CODE (operands[3]) == CONST_INT && <V64I:MODE>mode == DImode)
5557 if (INTVAL (operands[3]) < 0)
5558 operands[8] = constm1_rtx;
5560 operands[8] = const0_rtx;
5564 operands[8] = gen_highpart_mode (SImode, <V64I:MODE>mode, operands[3]);
5565 operands[9] = gen_lowpart (SImode, operands[3]);
5568 ;; xnor patterns. Note that (a ^ ~b) == (~a ^ b) == ~(a ^ b).
5569 ;; Combine now canonicalizes to the rightmost expression.
5570 (define_insn_and_split "*xor_not_<V64I:mode>_sp32"
5571 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5572 (not:V64I (xor:V64I (match_operand:V64I 1 "register_operand" "r,b")
5573 (match_operand:V64I 2 "register_operand" "r,b"))))]
5578 "&& reload_completed
5579 && ((GET_CODE (operands[0]) == REG
5580 && REGNO (operands[0]) < 32)
5581 || (GET_CODE (operands[0]) == SUBREG
5582 && GET_CODE (SUBREG_REG (operands[0])) == REG
5583 && REGNO (SUBREG_REG (operands[0])) < 32))"
5584 [(set (match_dup 3) (not:SI (xor:SI (match_dup 4) (match_dup 5))))
5585 (set (match_dup 6) (not:SI (xor:SI (match_dup 7) (match_dup 8))))]
5586 "operands[3] = gen_highpart (SImode, operands[0]);
5587 operands[4] = gen_highpart (SImode, operands[1]);
5588 operands[5] = gen_highpart (SImode, operands[2]);
5589 operands[6] = gen_lowpart (SImode, operands[0]);
5590 operands[7] = gen_lowpart (SImode, operands[1]);
5591 operands[8] = gen_lowpart (SImode, operands[2]);"
5592 [(set_attr "type" "*,fga")
5593 (set_attr "length" "2,*")
5594 (set_attr "fptype" "*,double")])
5596 (define_insn "*xor_not_<V64I:mode>_sp64"
5597 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5598 (not:V64I (xor:V64I (match_operand:V64I 1 "register_or_zero_operand" "rJ,b")
5599 (match_operand:V64I 2 "arith_operand" "rI,b"))))]
5604 [(set_attr "type" "*,fga")
5605 (set_attr "fptype" "*,double")])
5607 (define_insn "*xor_not_<V32I:mode>"
5608 [(set (match_operand:V32I 0 "register_operand" "=r,d")
5609 (not:V32I (xor:V32I (match_operand:V32I 1 "register_or_zero_operand" "rJ,d")
5610 (match_operand:V32I 2 "arith_operand" "rI,d"))))]
5615 [(set_attr "type" "*,fga")
5616 (set_attr "fptype" "*,single")])
5618 ;; These correspond to the above in the case where we also (or only)
5619 ;; want to set the condition code.
5621 (define_insn "*cmp_cc_arith_op"
5624 (match_operator:SI 2 "cc_arith_operator"
5625 [(match_operand:SI 0 "arith_operand" "%r")
5626 (match_operand:SI 1 "arith_operand" "rI")])
5629 "%A2cc\t%0, %1, %%g0"
5630 [(set_attr "type" "compare")])
5632 (define_insn "*cmp_ccx_arith_op"
5635 (match_operator:DI 2 "cc_arith_operator"
5636 [(match_operand:DI 0 "arith_operand" "%r")
5637 (match_operand:DI 1 "arith_operand" "rI")])
5640 "%A2cc\t%0, %1, %%g0"
5641 [(set_attr "type" "compare")])
5643 (define_insn "*cmp_cc_arith_op_set"
5646 (match_operator:SI 3 "cc_arith_operator"
5647 [(match_operand:SI 1 "arith_operand" "%r")
5648 (match_operand:SI 2 "arith_operand" "rI")])
5650 (set (match_operand:SI 0 "register_operand" "=r")
5651 (match_operator:SI 4 "cc_arith_operator" [(match_dup 1) (match_dup 2)]))]
5652 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
5654 [(set_attr "type" "compare")])
5656 (define_insn "*cmp_ccx_arith_op_set"
5659 (match_operator:DI 3 "cc_arith_operator"
5660 [(match_operand:DI 1 "arith_operand" "%r")
5661 (match_operand:DI 2 "arith_operand" "rI")])
5663 (set (match_operand:DI 0 "register_operand" "=r")
5664 (match_operator:DI 4 "cc_arith_operator" [(match_dup 1) (match_dup 2)]))]
5665 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
5667 [(set_attr "type" "compare")])
5669 (define_insn "*cmp_cc_xor_not"
5672 (not:SI (xor:SI (match_operand:SI 0 "register_or_zero_operand" "%rJ")
5673 (match_operand:SI 1 "arith_operand" "rI")))
5676 "xnorcc\t%r0, %1, %%g0"
5677 [(set_attr "type" "compare")])
5679 (define_insn "*cmp_ccx_xor_not"
5682 (not:DI (xor:DI (match_operand:DI 0 "register_or_zero_operand" "%rJ")
5683 (match_operand:DI 1 "arith_operand" "rI")))
5686 "xnorcc\t%r0, %1, %%g0"
5687 [(set_attr "type" "compare")])
5689 (define_insn "*cmp_cc_xor_not_set"
5692 (not:SI (xor:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ")
5693 (match_operand:SI 2 "arith_operand" "rI")))
5695 (set (match_operand:SI 0 "register_operand" "=r")
5696 (not:SI (xor:SI (match_dup 1) (match_dup 2))))]
5698 "xnorcc\t%r1, %2, %0"
5699 [(set_attr "type" "compare")])
5701 (define_insn "*cmp_ccx_xor_not_set"
5704 (not:DI (xor:DI (match_operand:DI 1 "register_or_zero_operand" "%rJ")
5705 (match_operand:DI 2 "arith_operand" "rI")))
5707 (set (match_operand:DI 0 "register_operand" "=r")
5708 (not:DI (xor:DI (match_dup 1) (match_dup 2))))]
5710 "xnorcc\t%r1, %2, %0"
5711 [(set_attr "type" "compare")])
5713 (define_insn "*cmp_cc_arith_op_not"
5716 (match_operator:SI 2 "cc_arith_not_operator"
5717 [(not:SI (match_operand:SI 0 "arith_operand" "rI"))
5718 (match_operand:SI 1 "register_or_zero_operand" "rJ")])
5721 "%B2cc\t%r1, %0, %%g0"
5722 [(set_attr "type" "compare")])
5724 (define_insn "*cmp_ccx_arith_op_not"
5727 (match_operator:DI 2 "cc_arith_not_operator"
5728 [(not:DI (match_operand:DI 0 "arith_operand" "rI"))
5729 (match_operand:DI 1 "register_or_zero_operand" "rJ")])
5732 "%B2cc\t%r1, %0, %%g0"
5733 [(set_attr "type" "compare")])
5735 (define_insn "*cmp_cc_arith_op_not_set"
5738 (match_operator:SI 3 "cc_arith_not_operator"
5739 [(not:SI (match_operand:SI 1 "arith_operand" "rI"))
5740 (match_operand:SI 2 "register_or_zero_operand" "rJ")])
5742 (set (match_operand:SI 0 "register_operand" "=r")
5743 (match_operator:SI 4 "cc_arith_not_operator"
5744 [(not:SI (match_dup 1)) (match_dup 2)]))]
5745 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
5746 "%B3cc\t%r2, %1, %0"
5747 [(set_attr "type" "compare")])
5749 (define_insn "*cmp_ccx_arith_op_not_set"
5752 (match_operator:DI 3 "cc_arith_not_operator"
5753 [(not:DI (match_operand:DI 1 "arith_operand" "rI"))
5754 (match_operand:DI 2 "register_or_zero_operand" "rJ")])
5756 (set (match_operand:DI 0 "register_operand" "=r")
5757 (match_operator:DI 4 "cc_arith_not_operator"
5758 [(not:DI (match_dup 1)) (match_dup 2)]))]
5759 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
5760 "%B3cc\t%r2, %1, %0"
5761 [(set_attr "type" "compare")])
5763 ;; We cannot use the "neg" pseudo insn because the Sun assembler
5764 ;; does not know how to make it work for constants.
5766 (define_expand "negdi2"
5767 [(set (match_operand:DI 0 "register_operand" "=r")
5768 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
5771 if (! TARGET_ARCH64)
5773 emit_insn (gen_rtx_PARALLEL
5776 gen_rtx_SET (VOIDmode, operand0,
5777 gen_rtx_NEG (DImode, operand1)),
5778 gen_rtx_CLOBBER (VOIDmode,
5779 gen_rtx_REG (CCmode,
5785 (define_insn_and_split "*negdi2_sp32"
5786 [(set (match_operand:DI 0 "register_operand" "=r")
5787 (neg:DI (match_operand:DI 1 "register_operand" "r")))
5788 (clobber (reg:CC 100))]
5791 "&& reload_completed"
5792 [(parallel [(set (reg:CC_NOOV 100)
5793 (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 5))
5795 (set (match_dup 4) (minus:SI (const_int 0) (match_dup 5)))])
5796 (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
5797 (ltu:SI (reg:CC 100) (const_int 0))))]
5798 "operands[2] = gen_highpart (SImode, operands[0]);
5799 operands[3] = gen_highpart (SImode, operands[1]);
5800 operands[4] = gen_lowpart (SImode, operands[0]);
5801 operands[5] = gen_lowpart (SImode, operands[1]);"
5802 [(set_attr "length" "2")])
5804 (define_insn "*negdi2_sp64"
5805 [(set (match_operand:DI 0 "register_operand" "=r")
5806 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
5808 "sub\t%%g0, %1, %0")
5810 (define_insn "negsi2"
5811 [(set (match_operand:SI 0 "register_operand" "=r")
5812 (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
5814 "sub\t%%g0, %1, %0")
5816 (define_insn "*cmp_cc_neg"
5817 [(set (reg:CC_NOOV 100)
5818 (compare:CC_NOOV (neg:SI (match_operand:SI 0 "arith_operand" "rI"))
5821 "subcc\t%%g0, %0, %%g0"
5822 [(set_attr "type" "compare")])
5824 (define_insn "*cmp_ccx_neg"
5825 [(set (reg:CCX_NOOV 100)
5826 (compare:CCX_NOOV (neg:DI (match_operand:DI 0 "arith_operand" "rI"))
5829 "subcc\t%%g0, %0, %%g0"
5830 [(set_attr "type" "compare")])
5832 (define_insn "*cmp_cc_set_neg"
5833 [(set (reg:CC_NOOV 100)
5834 (compare:CC_NOOV (neg:SI (match_operand:SI 1 "arith_operand" "rI"))
5836 (set (match_operand:SI 0 "register_operand" "=r")
5837 (neg:SI (match_dup 1)))]
5839 "subcc\t%%g0, %1, %0"
5840 [(set_attr "type" "compare")])
5842 (define_insn "*cmp_ccx_set_neg"
5843 [(set (reg:CCX_NOOV 100)
5844 (compare:CCX_NOOV (neg:DI (match_operand:DI 1 "arith_operand" "rI"))
5846 (set (match_operand:DI 0 "register_operand" "=r")
5847 (neg:DI (match_dup 1)))]
5849 "subcc\t%%g0, %1, %0"
5850 [(set_attr "type" "compare")])
5852 ;; We cannot use the "not" pseudo insn because the Sun assembler
5853 ;; does not know how to make it work for constants.
5854 (define_expand "one_cmpl<V64I:mode>2"
5855 [(set (match_operand:V64I 0 "register_operand" "")
5856 (not:V64I (match_operand:V64I 1 "register_operand" "")))]
5860 (define_insn_and_split "*one_cmpl<V64I:mode>2_sp32"
5861 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5862 (not:V64I (match_operand:V64I 1 "register_operand" "r,b")))]
5867 "&& reload_completed
5868 && ((GET_CODE (operands[0]) == REG
5869 && REGNO (operands[0]) < 32)
5870 || (GET_CODE (operands[0]) == SUBREG
5871 && GET_CODE (SUBREG_REG (operands[0])) == REG
5872 && REGNO (SUBREG_REG (operands[0])) < 32))"
5873 [(set (match_dup 2) (not:SI (xor:SI (match_dup 3) (const_int 0))))
5874 (set (match_dup 4) (not:SI (xor:SI (match_dup 5) (const_int 0))))]
5875 "operands[2] = gen_highpart (SImode, operands[0]);
5876 operands[3] = gen_highpart (SImode, operands[1]);
5877 operands[4] = gen_lowpart (SImode, operands[0]);
5878 operands[5] = gen_lowpart (SImode, operands[1]);"
5879 [(set_attr "type" "*,fga")
5880 (set_attr "length" "2,*")
5881 (set_attr "fptype" "*,double")])
5883 (define_insn "*one_cmpl<V64I:mode>2_sp64"
5884 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5885 (not:V64I (match_operand:V64I 1 "arith_operand" "rI,b")))]
5890 [(set_attr "type" "*,fga")
5891 (set_attr "fptype" "*,double")])
5893 (define_insn "one_cmpl<V32I:mode>2"
5894 [(set (match_operand:V32I 0 "register_operand" "=r,d")
5895 (not:V32I (match_operand:V32I 1 "arith_operand" "rI,d")))]
5900 [(set_attr "type" "*,fga")
5901 (set_attr "fptype" "*,single")])
5903 (define_insn "*cmp_cc_not"
5905 (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI"))
5908 "xnorcc\t%%g0, %0, %%g0"
5909 [(set_attr "type" "compare")])
5911 (define_insn "*cmp_ccx_not"
5913 (compare:CCX (not:DI (match_operand:DI 0 "arith_operand" "rI"))
5916 "xnorcc\t%%g0, %0, %%g0"
5917 [(set_attr "type" "compare")])
5919 (define_insn "*cmp_cc_set_not"
5921 (compare:CC (not:SI (match_operand:SI 1 "arith_operand" "rI"))
5923 (set (match_operand:SI 0 "register_operand" "=r")
5924 (not:SI (match_dup 1)))]
5926 "xnorcc\t%%g0, %1, %0"
5927 [(set_attr "type" "compare")])
5929 (define_insn "*cmp_ccx_set_not"
5931 (compare:CCX (not:DI (match_operand:DI 1 "arith_operand" "rI"))
5933 (set (match_operand:DI 0 "register_operand" "=r")
5934 (not:DI (match_dup 1)))]
5936 "xnorcc\t%%g0, %1, %0"
5937 [(set_attr "type" "compare")])
5939 (define_insn "*cmp_cc_set"
5940 [(set (match_operand:SI 0 "register_operand" "=r")
5941 (match_operand:SI 1 "register_operand" "r"))
5943 (compare:CC (match_dup 1)
5947 [(set_attr "type" "compare")])
5949 (define_insn "*cmp_ccx_set64"
5950 [(set (match_operand:DI 0 "register_operand" "=r")
5951 (match_operand:DI 1 "register_operand" "r"))
5953 (compare:CCX (match_dup 1)
5957 [(set_attr "type" "compare")])
5960 ;; Floating point arithmetic instructions.
5962 (define_expand "addtf3"
5963 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5964 (plus:TF (match_operand:TF 1 "general_operand" "")
5965 (match_operand:TF 2 "general_operand" "")))]
5966 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5967 "emit_tfmode_binop (PLUS, operands); DONE;")
5969 (define_insn "*addtf3_hq"
5970 [(set (match_operand:TF 0 "register_operand" "=e")
5971 (plus:TF (match_operand:TF 1 "register_operand" "e")
5972 (match_operand:TF 2 "register_operand" "e")))]
5973 "TARGET_FPU && TARGET_HARD_QUAD"
5975 [(set_attr "type" "fp")])
5977 (define_insn "adddf3"
5978 [(set (match_operand:DF 0 "register_operand" "=e")
5979 (plus:DF (match_operand:DF 1 "register_operand" "e")
5980 (match_operand:DF 2 "register_operand" "e")))]
5983 [(set_attr "type" "fp")
5984 (set_attr "fptype" "double")])
5986 (define_insn "addsf3"
5987 [(set (match_operand:SF 0 "register_operand" "=f")
5988 (plus:SF (match_operand:SF 1 "register_operand" "f")
5989 (match_operand:SF 2 "register_operand" "f")))]
5992 [(set_attr "type" "fp")])
5994 (define_expand "subtf3"
5995 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5996 (minus:TF (match_operand:TF 1 "general_operand" "")
5997 (match_operand:TF 2 "general_operand" "")))]
5998 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5999 "emit_tfmode_binop (MINUS, operands); DONE;")
6001 (define_insn "*subtf3_hq"
6002 [(set (match_operand:TF 0 "register_operand" "=e")
6003 (minus:TF (match_operand:TF 1 "register_operand" "e")
6004 (match_operand:TF 2 "register_operand" "e")))]
6005 "TARGET_FPU && TARGET_HARD_QUAD"
6007 [(set_attr "type" "fp")])
6009 (define_insn "subdf3"
6010 [(set (match_operand:DF 0 "register_operand" "=e")
6011 (minus:DF (match_operand:DF 1 "register_operand" "e")
6012 (match_operand:DF 2 "register_operand" "e")))]
6015 [(set_attr "type" "fp")
6016 (set_attr "fptype" "double")])
6018 (define_insn "subsf3"
6019 [(set (match_operand:SF 0 "register_operand" "=f")
6020 (minus:SF (match_operand:SF 1 "register_operand" "f")
6021 (match_operand:SF 2 "register_operand" "f")))]
6024 [(set_attr "type" "fp")])
6026 (define_expand "multf3"
6027 [(set (match_operand:TF 0 "nonimmediate_operand" "")
6028 (mult:TF (match_operand:TF 1 "general_operand" "")
6029 (match_operand:TF 2 "general_operand" "")))]
6030 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6031 "emit_tfmode_binop (MULT, operands); DONE;")
6033 (define_insn "*multf3_hq"
6034 [(set (match_operand:TF 0 "register_operand" "=e")
6035 (mult:TF (match_operand:TF 1 "register_operand" "e")
6036 (match_operand:TF 2 "register_operand" "e")))]
6037 "TARGET_FPU && TARGET_HARD_QUAD"
6039 [(set_attr "type" "fpmul")])
6041 (define_insn "muldf3"
6042 [(set (match_operand:DF 0 "register_operand" "=e")
6043 (mult:DF (match_operand:DF 1 "register_operand" "e")
6044 (match_operand:DF 2 "register_operand" "e")))]
6047 [(set_attr "type" "fpmul")
6048 (set_attr "fptype" "double")])
6050 (define_insn "mulsf3"
6051 [(set (match_operand:SF 0 "register_operand" "=f")
6052 (mult:SF (match_operand:SF 1 "register_operand" "f")
6053 (match_operand:SF 2 "register_operand" "f")))]
6056 [(set_attr "type" "fpmul")])
6058 (define_insn "*muldf3_extend"
6059 [(set (match_operand:DF 0 "register_operand" "=e")
6060 (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "f"))
6061 (float_extend:DF (match_operand:SF 2 "register_operand" "f"))))]
6062 "(TARGET_V8 || TARGET_V9) && TARGET_FPU"
6063 "fsmuld\t%1, %2, %0"
6064 [(set_attr "type" "fpmul")
6065 (set_attr "fptype" "double")])
6067 (define_insn "*multf3_extend"
6068 [(set (match_operand:TF 0 "register_operand" "=e")
6069 (mult:TF (float_extend:TF (match_operand:DF 1 "register_operand" "e"))
6070 (float_extend:TF (match_operand:DF 2 "register_operand" "e"))))]
6071 "(TARGET_V8 || TARGET_V9) && TARGET_FPU && TARGET_HARD_QUAD"
6072 "fdmulq\t%1, %2, %0"
6073 [(set_attr "type" "fpmul")])
6075 (define_expand "divtf3"
6076 [(set (match_operand:TF 0 "nonimmediate_operand" "")
6077 (div:TF (match_operand:TF 1 "general_operand" "")
6078 (match_operand:TF 2 "general_operand" "")))]
6079 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6080 "emit_tfmode_binop (DIV, operands); DONE;")
6082 ;; don't have timing for quad-prec. divide.
6083 (define_insn "*divtf3_hq"
6084 [(set (match_operand:TF 0 "register_operand" "=e")
6085 (div:TF (match_operand:TF 1 "register_operand" "e")
6086 (match_operand:TF 2 "register_operand" "e")))]
6087 "TARGET_FPU && TARGET_HARD_QUAD"
6089 [(set_attr "type" "fpdivd")])
6091 (define_insn "divdf3"
6092 [(set (match_operand:DF 0 "register_operand" "=e")
6093 (div:DF (match_operand:DF 1 "register_operand" "e")
6094 (match_operand:DF 2 "register_operand" "e")))]
6097 [(set_attr "type" "fpdivd")
6098 (set_attr "fptype" "double")])
6100 (define_insn "divsf3"
6101 [(set (match_operand:SF 0 "register_operand" "=f")
6102 (div:SF (match_operand:SF 1 "register_operand" "f")
6103 (match_operand:SF 2 "register_operand" "f")))]
6106 [(set_attr "type" "fpdivs")])
6108 (define_expand "negtf2"
6109 [(set (match_operand:TF 0 "register_operand" "=e,e")
6110 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
6114 (define_insn_and_split "*negtf2_notv9"
6115 [(set (match_operand:TF 0 "register_operand" "=e,e")
6116 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
6117 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
6123 "&& reload_completed
6124 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6125 [(set (match_dup 2) (neg:SF (match_dup 3)))
6126 (set (match_dup 4) (match_dup 5))
6127 (set (match_dup 6) (match_dup 7))]
6128 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6129 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6130 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6131 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
6132 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6133 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6134 [(set_attr "type" "fpmove,*")
6135 (set_attr "length" "*,2")])
6137 (define_insn_and_split "*negtf2_v9"
6138 [(set (match_operand:TF 0 "register_operand" "=e,e")
6139 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
6140 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
6141 "TARGET_FPU && TARGET_V9"
6145 "&& reload_completed
6146 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6147 [(set (match_dup 2) (neg:DF (match_dup 3)))
6148 (set (match_dup 4) (match_dup 5))]
6149 "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
6150 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
6151 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6152 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6153 [(set_attr "type" "fpmove,*")
6154 (set_attr "length" "*,2")
6155 (set_attr "fptype" "double")])
6157 (define_expand "negdf2"
6158 [(set (match_operand:DF 0 "register_operand" "")
6159 (neg:DF (match_operand:DF 1 "register_operand" "")))]
6163 (define_insn_and_split "*negdf2_notv9"
6164 [(set (match_operand:DF 0 "register_operand" "=e,e")
6165 (neg:DF (match_operand:DF 1 "register_operand" "0,e")))]
6166 "TARGET_FPU && ! TARGET_V9"
6170 "&& reload_completed
6171 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6172 [(set (match_dup 2) (neg:SF (match_dup 3)))
6173 (set (match_dup 4) (match_dup 5))]
6174 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6175 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6176 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6177 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);"
6178 [(set_attr "type" "fpmove,*")
6179 (set_attr "length" "*,2")])
6181 (define_insn "*negdf2_v9"
6182 [(set (match_operand:DF 0 "register_operand" "=e")
6183 (neg:DF (match_operand:DF 1 "register_operand" "e")))]
6184 "TARGET_FPU && TARGET_V9"
6186 [(set_attr "type" "fpmove")
6187 (set_attr "fptype" "double")])
6189 (define_insn "negsf2"
6190 [(set (match_operand:SF 0 "register_operand" "=f")
6191 (neg:SF (match_operand:SF 1 "register_operand" "f")))]
6194 [(set_attr "type" "fpmove")])
6196 (define_expand "abstf2"
6197 [(set (match_operand:TF 0 "register_operand" "")
6198 (abs:TF (match_operand:TF 1 "register_operand" "")))]
6202 (define_insn_and_split "*abstf2_notv9"
6203 [(set (match_operand:TF 0 "register_operand" "=e,e")
6204 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6205 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
6206 "TARGET_FPU && ! TARGET_V9"
6210 "&& reload_completed
6211 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6212 [(set (match_dup 2) (abs:SF (match_dup 3)))
6213 (set (match_dup 4) (match_dup 5))
6214 (set (match_dup 6) (match_dup 7))]
6215 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6216 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6217 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6218 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
6219 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6220 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6221 [(set_attr "type" "fpmove,*")
6222 (set_attr "length" "*,2")])
6224 (define_insn "*abstf2_hq_v9"
6225 [(set (match_operand:TF 0 "register_operand" "=e,e")
6226 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6227 "TARGET_FPU && TARGET_V9 && TARGET_HARD_QUAD"
6231 [(set_attr "type" "fpmove")
6232 (set_attr "fptype" "double,*")])
6234 (define_insn_and_split "*abstf2_v9"
6235 [(set (match_operand:TF 0 "register_operand" "=e,e")
6236 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6237 "TARGET_FPU && TARGET_V9 && !TARGET_HARD_QUAD"
6241 "&& reload_completed
6242 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6243 [(set (match_dup 2) (abs:DF (match_dup 3)))
6244 (set (match_dup 4) (match_dup 5))]
6245 "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
6246 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
6247 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6248 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6249 [(set_attr "type" "fpmove,*")
6250 (set_attr "length" "*,2")
6251 (set_attr "fptype" "double,*")])
6253 (define_expand "absdf2"
6254 [(set (match_operand:DF 0 "register_operand" "")
6255 (abs:DF (match_operand:DF 1 "register_operand" "")))]
6259 (define_insn_and_split "*absdf2_notv9"
6260 [(set (match_operand:DF 0 "register_operand" "=e,e")
6261 (abs:DF (match_operand:DF 1 "register_operand" "0,e")))]
6262 "TARGET_FPU && ! TARGET_V9"
6266 "&& reload_completed
6267 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6268 [(set (match_dup 2) (abs:SF (match_dup 3)))
6269 (set (match_dup 4) (match_dup 5))]
6270 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6271 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6272 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6273 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);"
6274 [(set_attr "type" "fpmove,*")
6275 (set_attr "length" "*,2")])
6277 (define_insn "*absdf2_v9"
6278 [(set (match_operand:DF 0 "register_operand" "=e")
6279 (abs:DF (match_operand:DF 1 "register_operand" "e")))]
6280 "TARGET_FPU && TARGET_V9"
6282 [(set_attr "type" "fpmove")
6283 (set_attr "fptype" "double")])
6285 (define_insn "abssf2"
6286 [(set (match_operand:SF 0 "register_operand" "=f")
6287 (abs:SF (match_operand:SF 1 "register_operand" "f")))]
6290 [(set_attr "type" "fpmove")])
6292 (define_expand "sqrttf2"
6293 [(set (match_operand:TF 0 "nonimmediate_operand" "")
6294 (sqrt:TF (match_operand:TF 1 "general_operand" "")))]
6295 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6296 "emit_tfmode_unop (SQRT, operands); DONE;")
6298 (define_insn "*sqrttf2_hq"
6299 [(set (match_operand:TF 0 "register_operand" "=e")
6300 (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
6301 "TARGET_FPU && TARGET_HARD_QUAD"
6303 [(set_attr "type" "fpsqrtd")])
6305 (define_insn "sqrtdf2"
6306 [(set (match_operand:DF 0 "register_operand" "=e")
6307 (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
6310 [(set_attr "type" "fpsqrtd")
6311 (set_attr "fptype" "double")])
6313 (define_insn "sqrtsf2"
6314 [(set (match_operand:SF 0 "register_operand" "=f")
6315 (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
6318 [(set_attr "type" "fpsqrts")])
6321 ;; Arithmetic shift instructions.
6323 (define_insn "ashlsi3"
6324 [(set (match_operand:SI 0 "register_operand" "=r")
6325 (ashift:SI (match_operand:SI 1 "register_operand" "r")
6326 (match_operand:SI 2 "arith_operand" "rI")))]
6329 if (GET_CODE (operands[2]) == CONST_INT)
6330 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6331 return "sll\t%1, %2, %0";
6334 (if_then_else (match_operand 2 "const_one_operand" "")
6335 (const_string "ialu") (const_string "shift")))])
6337 (define_expand "ashldi3"
6338 [(set (match_operand:DI 0 "register_operand" "=r")
6339 (ashift:DI (match_operand:DI 1 "register_operand" "r")
6340 (match_operand:SI 2 "arith_operand" "rI")))]
6341 "TARGET_ARCH64 || TARGET_V8PLUS"
6343 if (! TARGET_ARCH64)
6345 if (GET_CODE (operands[2]) == CONST_INT)
6347 emit_insn (gen_ashldi3_v8plus (operands[0], operands[1], operands[2]));
6352 (define_insn "*ashldi3_sp64"
6353 [(set (match_operand:DI 0 "register_operand" "=r")
6354 (ashift:DI (match_operand:DI 1 "register_operand" "r")
6355 (match_operand:SI 2 "arith_operand" "rI")))]
6358 if (GET_CODE (operands[2]) == CONST_INT)
6359 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
6360 return "sllx\t%1, %2, %0";
6363 (if_then_else (match_operand 2 "const_one_operand" "")
6364 (const_string "ialu") (const_string "shift")))])
6367 (define_insn "ashldi3_v8plus"
6368 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
6369 (ashift:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
6370 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
6371 (clobber (match_scratch:SI 3 "=X,X,&h"))]
6373 "* return output_v8plus_shift (operands, insn, \"sllx\");"
6374 [(set_attr "type" "multi")
6375 (set_attr "length" "5,5,6")])
6377 ;; Optimize (1LL<<x)-1
6378 ;; XXX this also needs to be fixed to handle equal subregs
6379 ;; XXX first before we could re-enable it.
6381 ; [(set (match_operand:DI 0 "register_operand" "=h")
6382 ; (plus:DI (ashift:DI (const_int 1)
6383 ; (match_operand:SI 1 "arith_operand" "rI"))
6385 ; "0 && TARGET_V8PLUS"
6387 ; if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == REGNO (operands[0]))
6388 ; return "mov\t1, %L0\;sllx\t%L0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
6389 ; return "mov\t1, %H0\;sllx\t%H0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
6391 ; [(set_attr "type" "multi")
6392 ; (set_attr "length" "4")])
6394 (define_insn "*cmp_cc_ashift_1"
6395 [(set (reg:CC_NOOV 100)
6396 (compare:CC_NOOV (ashift:SI (match_operand:SI 0 "register_operand" "r")
6400 "addcc\t%0, %0, %%g0"
6401 [(set_attr "type" "compare")])
6403 (define_insn "*cmp_cc_set_ashift_1"
6404 [(set (reg:CC_NOOV 100)
6405 (compare:CC_NOOV (ashift:SI (match_operand:SI 1 "register_operand" "r")
6408 (set (match_operand:SI 0 "register_operand" "=r")
6409 (ashift:SI (match_dup 1) (const_int 1)))]
6412 [(set_attr "type" "compare")])
6414 (define_insn "ashrsi3"
6415 [(set (match_operand:SI 0 "register_operand" "=r")
6416 (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
6417 (match_operand:SI 2 "arith_operand" "rI")))]
6420 if (GET_CODE (operands[2]) == CONST_INT)
6421 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6422 return "sra\t%1, %2, %0";
6424 [(set_attr "type" "shift")])
6426 (define_insn "*ashrsi3_extend"
6427 [(set (match_operand:DI 0 "register_operand" "=r")
6428 (sign_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
6429 (match_operand:SI 2 "arith_operand" "r"))))]
6432 [(set_attr "type" "shift")])
6434 ;; This handles the case as above, but with constant shift instead of
6435 ;; register. Combiner "simplifies" it for us a little bit though.
6436 (define_insn "*ashrsi3_extend2"
6437 [(set (match_operand:DI 0 "register_operand" "=r")
6438 (ashiftrt:DI (ashift:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
6440 (match_operand:SI 2 "small_int_operand" "I")))]
6441 "TARGET_ARCH64 && INTVAL (operands[2]) >= 32 && INTVAL (operands[2]) < 64"
6443 operands[2] = GEN_INT (INTVAL (operands[2]) - 32);
6444 return "sra\t%1, %2, %0";
6446 [(set_attr "type" "shift")])
6448 (define_expand "ashrdi3"
6449 [(set (match_operand:DI 0 "register_operand" "=r")
6450 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
6451 (match_operand:SI 2 "arith_operand" "rI")))]
6452 "TARGET_ARCH64 || TARGET_V8PLUS"
6454 if (! TARGET_ARCH64)
6456 if (GET_CODE (operands[2]) == CONST_INT)
6457 FAIL; /* prefer generic code in this case */
6458 emit_insn (gen_ashrdi3_v8plus (operands[0], operands[1], operands[2]));
6463 (define_insn "*ashrdi3_sp64"
6464 [(set (match_operand:DI 0 "register_operand" "=r")
6465 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
6466 (match_operand:SI 2 "arith_operand" "rI")))]
6470 if (GET_CODE (operands[2]) == CONST_INT)
6471 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
6472 return "srax\t%1, %2, %0";
6474 [(set_attr "type" "shift")])
6477 (define_insn "ashrdi3_v8plus"
6478 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
6479 (ashiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
6480 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
6481 (clobber (match_scratch:SI 3 "=X,X,&h"))]
6483 "* return output_v8plus_shift (operands, insn, \"srax\");"
6484 [(set_attr "type" "multi")
6485 (set_attr "length" "5,5,6")])
6487 (define_insn "lshrsi3"
6488 [(set (match_operand:SI 0 "register_operand" "=r")
6489 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
6490 (match_operand:SI 2 "arith_operand" "rI")))]
6493 if (GET_CODE (operands[2]) == CONST_INT)
6494 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6495 return "srl\t%1, %2, %0";
6497 [(set_attr "type" "shift")])
6499 ;; This handles the case where
6500 ;; (zero_extend:DI (lshiftrt:SI (match_operand:SI) (match_operand:SI))),
6501 ;; but combiner "simplifies" it for us.
6502 (define_insn "*lshrsi3_extend"
6503 [(set (match_operand:DI 0 "register_operand" "=r")
6504 (and:DI (subreg:DI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
6505 (match_operand:SI 2 "arith_operand" "r")) 0)
6506 (match_operand 3 "const_int_operand" "")))]
6507 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) == 0xffffffff"
6509 [(set_attr "type" "shift")])
6511 ;; This handles the case where
6512 ;; (lshiftrt:DI (zero_extend:DI (match_operand:SI)) (const_int >=0 < 32))
6513 ;; but combiner "simplifies" it for us.
6514 (define_insn "*lshrsi3_extend2"
6515 [(set (match_operand:DI 0 "register_operand" "=r")
6516 (zero_extract:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
6517 (match_operand 2 "small_int_operand" "I")
6519 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
6521 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
6522 return "srl\t%1, %2, %0";
6524 [(set_attr "type" "shift")])
6526 (define_expand "lshrdi3"
6527 [(set (match_operand:DI 0 "register_operand" "=r")
6528 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6529 (match_operand:SI 2 "arith_operand" "rI")))]
6530 "TARGET_ARCH64 || TARGET_V8PLUS"
6532 if (! TARGET_ARCH64)
6534 if (GET_CODE (operands[2]) == CONST_INT)
6536 emit_insn (gen_lshrdi3_v8plus (operands[0], operands[1], operands[2]));
6541 (define_insn "*lshrdi3_sp64"
6542 [(set (match_operand:DI 0 "register_operand" "=r")
6543 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6544 (match_operand:SI 2 "arith_operand" "rI")))]
6547 if (GET_CODE (operands[2]) == CONST_INT)
6548 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
6549 return "srlx\t%1, %2, %0";
6551 [(set_attr "type" "shift")])
6554 (define_insn "lshrdi3_v8plus"
6555 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
6556 (lshiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
6557 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
6558 (clobber (match_scratch:SI 3 "=X,X,&h"))]
6560 "* return output_v8plus_shift (operands, insn, \"srlx\");"
6561 [(set_attr "type" "multi")
6562 (set_attr "length" "5,5,6")])
6565 [(set (match_operand:SI 0 "register_operand" "=r")
6566 (ashiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6568 (match_operand:SI 2 "small_int_operand" "I")))]
6569 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
6571 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
6572 return "srax\t%1, %2, %0";
6574 [(set_attr "type" "shift")])
6577 [(set (match_operand:SI 0 "register_operand" "=r")
6578 (lshiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
6580 (match_operand:SI 2 "small_int_operand" "I")))]
6581 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
6583 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
6584 return "srlx\t%1, %2, %0";
6586 [(set_attr "type" "shift")])
6589 [(set (match_operand:SI 0 "register_operand" "=r")
6590 (ashiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
6591 (match_operand:SI 2 "small_int_operand" "I")) 4)
6592 (match_operand:SI 3 "small_int_operand" "I")))]
6594 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
6595 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
6596 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
6598 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
6600 return "srax\t%1, %2, %0";
6602 [(set_attr "type" "shift")])
6605 [(set (match_operand:SI 0 "register_operand" "=r")
6606 (lshiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6607 (match_operand:SI 2 "small_int_operand" "I")) 4)
6608 (match_operand:SI 3 "small_int_operand" "I")))]
6610 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
6611 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
6612 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
6614 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
6616 return "srlx\t%1, %2, %0";
6618 [(set_attr "type" "shift")])
6621 ;; Unconditional and other jump instructions.
6624 [(set (pc) (label_ref (match_operand 0 "" "")))]
6626 "* return output_ubranch (operands[0], 0, insn);"
6627 [(set_attr "type" "uncond_branch")])
6629 (define_expand "tablejump"
6630 [(parallel [(set (pc) (match_operand 0 "register_operand" "r"))
6631 (use (label_ref (match_operand 1 "" "")))])]
6634 gcc_assert (GET_MODE (operands[0]) == CASE_VECTOR_MODE);
6636 /* In pic mode, our address differences are against the base of the
6637 table. Add that base value back in; CSE ought to be able to combine
6638 the two address loads. */
6642 tmp = gen_rtx_LABEL_REF (Pmode, operands[1]);
6644 if (CASE_VECTOR_MODE != Pmode)
6645 tmp2 = gen_rtx_SIGN_EXTEND (Pmode, tmp2);
6646 tmp = gen_rtx_PLUS (Pmode, tmp2, tmp);
6647 operands[0] = memory_address (Pmode, tmp);
6651 (define_insn "*tablejump_sp32"
6652 [(set (pc) (match_operand:SI 0 "address_operand" "p"))
6653 (use (label_ref (match_operand 1 "" "")))]
6656 [(set_attr "type" "uncond_branch")])
6658 (define_insn "*tablejump_sp64"
6659 [(set (pc) (match_operand:DI 0 "address_operand" "p"))
6660 (use (label_ref (match_operand 1 "" "")))]
6663 [(set_attr "type" "uncond_branch")])
6666 ;; Jump to subroutine instructions.
6668 (define_expand "call"
6669 ;; Note that this expression is not used for generating RTL.
6670 ;; All the RTL is generated explicitly below.
6671 [(call (match_operand 0 "call_operand" "")
6672 (match_operand 3 "" "i"))]
6673 ;; operands[2] is next_arg_register
6674 ;; operands[3] is struct_value_size_rtx.
6679 gcc_assert (GET_MODE (operands[0]) == FUNCTION_MODE);
6681 gcc_assert (GET_CODE (operands[3]) == CONST_INT);
6683 if (GET_CODE (XEXP (operands[0], 0)) == LABEL_REF)
6685 /* This is really a PIC sequence. We want to represent
6686 it as a funny jump so its delay slots can be filled.
6688 ??? But if this really *is* a CALL, will not it clobber the
6689 call-clobbered registers? We lose this if it is a JUMP_INSN.
6690 Why cannot we have delay slots filled if it were a CALL? */
6692 /* We accept negative sizes for untyped calls. */
6693 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
6698 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
6700 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
6706 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
6707 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
6711 fn_rtx = operands[0];
6713 /* We accept negative sizes for untyped calls. */
6714 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
6718 gen_rtvec (3, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx),
6720 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
6725 gen_rtvec (2, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx),
6726 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
6733 ;; We can't use the same pattern for these two insns, because then registers
6734 ;; in the address may not be properly reloaded.
6736 (define_insn "*call_address_sp32"
6737 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6738 (match_operand 1 "" ""))
6739 (clobber (reg:SI 15))]
6740 ;;- Do not use operand 1 for most machines.
6743 [(set_attr "type" "call")])
6745 (define_insn "*call_symbolic_sp32"
6746 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6747 (match_operand 1 "" ""))
6748 (clobber (reg:SI 15))]
6749 ;;- Do not use operand 1 for most machines.
6752 [(set_attr "type" "call")])
6754 (define_insn "*call_address_sp64"
6755 [(call (mem:DI (match_operand:DI 0 "address_operand" "p"))
6756 (match_operand 1 "" ""))
6757 (clobber (reg:DI 15))]
6758 ;;- Do not use operand 1 for most machines.
6761 [(set_attr "type" "call")])
6763 (define_insn "*call_symbolic_sp64"
6764 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
6765 (match_operand 1 "" ""))
6766 (clobber (reg:DI 15))]
6767 ;;- Do not use operand 1 for most machines.
6770 [(set_attr "type" "call")])
6772 ;; This is a call that wants a structure value.
6773 ;; There is no such critter for v9 (??? we may need one anyway).
6774 (define_insn "*call_address_struct_value_sp32"
6775 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6776 (match_operand 1 "" ""))
6777 (match_operand 2 "immediate_operand" "")
6778 (clobber (reg:SI 15))]
6779 ;;- Do not use operand 1 for most machines.
6780 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
6782 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xfff);
6783 return "call\t%a0, %1\n\t nop\n\tunimp\t%2";
6785 [(set_attr "type" "call_no_delay_slot")
6786 (set_attr "length" "3")])
6788 ;; This is a call that wants a structure value.
6789 ;; There is no such critter for v9 (??? we may need one anyway).
6790 (define_insn "*call_symbolic_struct_value_sp32"
6791 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6792 (match_operand 1 "" ""))
6793 (match_operand 2 "immediate_operand" "")
6794 (clobber (reg:SI 15))]
6795 ;;- Do not use operand 1 for most machines.
6796 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
6798 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xfff);
6799 return "call\t%a0, %1\n\t nop\n\tunimp\t%2";
6801 [(set_attr "type" "call_no_delay_slot")
6802 (set_attr "length" "3")])
6804 ;; This is a call that may want a structure value. This is used for
6806 (define_insn "*call_address_untyped_struct_value_sp32"
6807 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6808 (match_operand 1 "" ""))
6809 (match_operand 2 "immediate_operand" "")
6810 (clobber (reg:SI 15))]
6811 ;;- Do not use operand 1 for most machines.
6812 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
6813 "call\t%a0, %1\n\t nop\n\tnop"
6814 [(set_attr "type" "call_no_delay_slot")
6815 (set_attr "length" "3")])
6817 ;; This is a call that may want a structure value. This is used for
6819 (define_insn "*call_symbolic_untyped_struct_value_sp32"
6820 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6821 (match_operand 1 "" ""))
6822 (match_operand 2 "immediate_operand" "")
6823 (clobber (reg:SI 15))]
6824 ;;- Do not use operand 1 for most machines.
6825 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
6826 "call\t%a0, %1\n\t nop\n\tnop"
6827 [(set_attr "type" "call_no_delay_slot")
6828 (set_attr "length" "3")])
6830 (define_expand "call_value"
6831 ;; Note that this expression is not used for generating RTL.
6832 ;; All the RTL is generated explicitly below.
6833 [(set (match_operand 0 "register_operand" "=rf")
6834 (call (match_operand 1 "" "")
6835 (match_operand 4 "" "")))]
6836 ;; operand 2 is stack_size_rtx
6837 ;; operand 3 is next_arg_register
6843 gcc_assert (GET_MODE (operands[1]) == FUNCTION_MODE);
6845 fn_rtx = operands[1];
6848 gen_rtx_SET (VOIDmode, operands[0],
6849 gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx)),
6850 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)));
6852 emit_call_insn (gen_rtx_PARALLEL (VOIDmode, vec));
6857 (define_insn "*call_value_address_sp32"
6858 [(set (match_operand 0 "" "=rf")
6859 (call (mem:SI (match_operand:SI 1 "address_operand" "p"))
6860 (match_operand 2 "" "")))
6861 (clobber (reg:SI 15))]
6862 ;;- Do not use operand 2 for most machines.
6865 [(set_attr "type" "call")])
6867 (define_insn "*call_value_symbolic_sp32"
6868 [(set (match_operand 0 "" "=rf")
6869 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
6870 (match_operand 2 "" "")))
6871 (clobber (reg:SI 15))]
6872 ;;- Do not use operand 2 for most machines.
6875 [(set_attr "type" "call")])
6877 (define_insn "*call_value_address_sp64"
6878 [(set (match_operand 0 "" "")
6879 (call (mem:DI (match_operand:DI 1 "address_operand" "p"))
6880 (match_operand 2 "" "")))
6881 (clobber (reg:DI 15))]
6882 ;;- Do not use operand 2 for most machines.
6885 [(set_attr "type" "call")])
6887 (define_insn "*call_value_symbolic_sp64"
6888 [(set (match_operand 0 "" "")
6889 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
6890 (match_operand 2 "" "")))
6891 (clobber (reg:DI 15))]
6892 ;;- Do not use operand 2 for most machines.
6895 [(set_attr "type" "call")])
6897 (define_expand "untyped_call"
6898 [(parallel [(call (match_operand 0 "" "")
6900 (match_operand:BLK 1 "memory_operand" "")
6901 (match_operand 2 "" "")])]
6904 rtx valreg1 = gen_rtx_REG (DImode, 8);
6905 rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
6906 rtx result = operands[1];
6908 /* Pass constm1 to indicate that it may expect a structure value, but
6909 we don't know what size it is. */
6910 emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, constm1_rtx));
6912 /* Save the function value registers. */
6913 emit_move_insn (adjust_address (result, DImode, 0), valreg1);
6914 emit_move_insn (adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8),
6917 /* The optimizer does not know that the call sets the function value
6918 registers we stored in the result block. We avoid problems by
6919 claiming that all hard registers are used and clobbered at this
6921 emit_insn (gen_blockage ());
6926 ;; Tail call instructions.
6928 (define_expand "sibcall"
6929 [(parallel [(call (match_operand 0 "call_operand" "") (const_int 0))
6934 (define_insn "*sibcall_symbolic_sp32"
6935 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6936 (match_operand 1 "" ""))
6939 "* return output_sibcall(insn, operands[0]);"
6940 [(set_attr "type" "sibcall")])
6942 (define_insn "*sibcall_symbolic_sp64"
6943 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
6944 (match_operand 1 "" ""))
6947 "* return output_sibcall(insn, operands[0]);"
6948 [(set_attr "type" "sibcall")])
6950 (define_expand "sibcall_value"
6951 [(parallel [(set (match_operand 0 "register_operand" "=rf")
6952 (call (match_operand 1 "" "") (const_int 0)))
6957 (define_insn "*sibcall_value_symbolic_sp32"
6958 [(set (match_operand 0 "" "=rf")
6959 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
6960 (match_operand 2 "" "")))
6963 "* return output_sibcall(insn, operands[1]);"
6964 [(set_attr "type" "sibcall")])
6966 (define_insn "*sibcall_value_symbolic_sp64"
6967 [(set (match_operand 0 "" "")
6968 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
6969 (match_operand 2 "" "")))
6972 "* return output_sibcall(insn, operands[1]);"
6973 [(set_attr "type" "sibcall")])
6976 ;; Special instructions.
6978 (define_expand "prologue"
6982 sparc_expand_prologue ();
6986 ;; The "save register window" insn is modelled as follows so that the DWARF-2
6987 ;; backend automatically emits the required call frame debugging information
6988 ;; while it is parsing it. Therefore, the pattern should not be modified
6989 ;; without first studying the impact of the changes on the debug info.
6990 ;; [(set (%fp) (%sp))
6991 ;; (set (%sp) (unspec_volatile [(%sp) (-frame_size)] UNSPECV_SAVEW))
6992 ;; (set (%i7) (%o7))]
6994 (define_insn "save_register_window<P:mode>"
6995 [(set (reg:P 30) (reg:P 14))
6996 (set (reg:P 14) (unspec_volatile:P [(reg:P 14)
6997 (match_operand:P 0 "arith_operand" "rI")] UNSPECV_SAVEW))
6998 (set (reg:P 31) (reg:P 15))]
7000 "save\t%%sp, %0, %%sp"
7001 [(set_attr "type" "savew")])
7003 (define_expand "epilogue"
7007 sparc_expand_epilogue ();
7010 (define_expand "sibcall_epilogue"
7014 sparc_expand_epilogue ();
7018 (define_expand "return"
7020 "sparc_can_use_return_insn_p ()"
7023 (define_insn "*return_internal"
7026 "* return output_return (insn);"
7027 [(set_attr "type" "return")
7028 (set (attr "length")
7029 (cond [(eq_attr "leaf_function" "true")
7030 (if_then_else (eq_attr "empty_delay_slot" "true")
7033 (eq_attr "calls_eh_return" "true")
7034 (if_then_else (eq_attr "delayed_branch" "true")
7035 (if_then_else (eq_attr "isa" "v9")
7038 (if_then_else (eq_attr "isa" "v9")
7041 (eq_attr "empty_delay_slot" "true")
7042 (if_then_else (eq_attr "delayed_branch" "true")
7047 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
7048 ;; all of memory. This blocks insns from being moved across this point.
7050 (define_insn "blockage"
7051 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
7054 [(set_attr "length" "0")])
7056 ;; Prepare to return any type including a structure value.
7058 (define_expand "untyped_return"
7059 [(match_operand:BLK 0 "memory_operand" "")
7060 (match_operand 1 "" "")]
7063 rtx valreg1 = gen_rtx_REG (DImode, 24);
7064 rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
7065 rtx result = operands[0];
7067 if (! TARGET_ARCH64)
7069 rtx rtnreg = gen_rtx_REG (SImode, (current_function_uses_only_leaf_regs
7071 rtx value = gen_reg_rtx (SImode);
7073 /* Fetch the instruction where we will return to and see if it's an unimp
7074 instruction (the most significant 10 bits will be zero). If so,
7075 update the return address to skip the unimp instruction. */
7076 emit_move_insn (value,
7077 gen_rtx_MEM (SImode, plus_constant (rtnreg, 8)));
7078 emit_insn (gen_lshrsi3 (value, value, GEN_INT (22)));
7079 emit_insn (gen_update_return (rtnreg, value));
7082 /* Reload the function value registers. */
7083 emit_move_insn (valreg1, adjust_address (result, DImode, 0));
7084 emit_move_insn (valreg2,
7085 adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8));
7087 /* Put USE insns before the return. */
7088 emit_insn (gen_rtx_USE (VOIDmode, valreg1));
7089 emit_insn (gen_rtx_USE (VOIDmode, valreg2));
7091 /* Construct the return. */
7092 expand_naked_return ();
7097 ;; Adjust the return address conditionally. If the value of op1 is equal
7098 ;; to all zero then adjust the return address i.e. op0 = op0 + 4.
7099 ;; This is technically *half* the check required by the 32-bit SPARC
7100 ;; psABI. This check only ensures that an "unimp" insn was written by
7101 ;; the caller, but doesn't check to see if the expected size matches
7102 ;; (this is encoded in the 12 lower bits). This check is obsolete and
7103 ;; only used by the above code "untyped_return".
7105 (define_insn "update_return"
7106 [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
7107 (match_operand:SI 1 "register_operand" "r")] UNSPEC_UPDATE_RETURN)]
7110 if (flag_delayed_branch)
7111 return "cmp\t%1, 0\n\tbe,a\t.+8\n\t add\t%0, 4, %0";
7113 return "cmp\t%1, 0\n\tbne\t.+12\n\t nop\n\tadd\t%0, 4, %0";
7115 [(set (attr "type") (const_string "multi"))
7116 (set (attr "length")
7117 (if_then_else (eq_attr "delayed_branch" "true")
7126 (define_expand "indirect_jump"
7127 [(set (pc) (match_operand 0 "address_operand" "p"))]
7131 (define_insn "*branch_sp32"
7132 [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
7135 [(set_attr "type" "uncond_branch")])
7137 (define_insn "*branch_sp64"
7138 [(set (pc) (match_operand:DI 0 "address_operand" "p"))]
7141 [(set_attr "type" "uncond_branch")])
7143 (define_expand "nonlocal_goto"
7144 [(match_operand:SI 0 "general_operand" "")
7145 (match_operand:SI 1 "general_operand" "")
7146 (match_operand:SI 2 "general_operand" "")
7147 (match_operand:SI 3 "" "")]
7150 rtx lab = operands[1];
7151 rtx stack = operands[2];
7152 rtx fp = operands[3];
7155 /* Trap instruction to flush all the register windows. */
7156 emit_insn (gen_flush_register_windows ());
7158 /* Load the fp value for the containing fn into %fp. This is needed
7159 because STACK refers to %fp. Note that virtual register instantiation
7160 fails if the virtual %fp isn't set from a register. */
7161 if (GET_CODE (fp) != REG)
7162 fp = force_reg (Pmode, fp);
7163 emit_move_insn (virtual_stack_vars_rtx, fp);
7165 /* Find the containing function's current nonlocal goto handler,
7166 which will do any cleanups and then jump to the label. */
7167 labreg = gen_rtx_REG (Pmode, 8);
7168 emit_move_insn (labreg, lab);
7170 /* Restore %fp from stack pointer value for containing function.
7171 The restore insn that follows will move this to %sp,
7172 and reload the appropriate value into %fp. */
7173 emit_move_insn (hard_frame_pointer_rtx, stack);
7175 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
7176 emit_insn (gen_rtx_USE (VOIDmode, static_chain_rtx));
7178 /* ??? The V9-specific version was disabled in rev 1.65. */
7179 emit_jump_insn (gen_goto_handler_and_restore (labreg));
7184 ;; Special trap insn to flush register windows.
7185 (define_insn "flush_register_windows"
7186 [(unspec_volatile [(const_int 0)] UNSPECV_FLUSHW)]
7188 { return TARGET_V9 ? "flushw" : "ta\t3"; }
7189 [(set_attr "type" "flushw")])
7191 (define_insn "goto_handler_and_restore"
7192 [(unspec_volatile [(match_operand 0 "register_operand" "=r")] UNSPECV_GOTO)]
7193 "GET_MODE (operands[0]) == Pmode"
7195 if (flag_delayed_branch)
7196 return "jmp\t%0\n\t restore";
7198 return "mov\t%0,%%g1\n\trestore\n\tjmp\t%%g1\n\t nop";
7200 [(set (attr "type") (const_string "multi"))
7201 (set (attr "length")
7202 (if_then_else (eq_attr "delayed_branch" "true")
7206 ;; For __builtin_setjmp we need to flush register windows iff the function
7207 ;; calls alloca as well, because otherwise the register window might be
7208 ;; saved after %sp adjustment and thus setjmp would crash
7209 (define_expand "builtin_setjmp_setup"
7210 [(match_operand 0 "register_operand" "r")]
7213 emit_insn (gen_do_builtin_setjmp_setup ());
7217 (define_insn "do_builtin_setjmp_setup"
7218 [(unspec_volatile [(const_int 0)] UNSPECV_SETJMP)]
7221 if (! current_function_calls_alloca)
7225 fputs ("\tflushw\n", asm_out_file);
7227 fprintf (asm_out_file, "\tst%c\t%%l7, [%%sp+%d]\n",
7228 TARGET_ARCH64 ? 'x' : 'w',
7229 SPARC_STACK_BIAS + 7 * UNITS_PER_WORD);
7230 fprintf (asm_out_file, "\tst%c\t%%fp, [%%sp+%d]\n",
7231 TARGET_ARCH64 ? 'x' : 'w',
7232 SPARC_STACK_BIAS + 14 * UNITS_PER_WORD);
7233 fprintf (asm_out_file, "\tst%c\t%%i7, [%%sp+%d]\n",
7234 TARGET_ARCH64 ? 'x' : 'w',
7235 SPARC_STACK_BIAS + 15 * UNITS_PER_WORD);
7238 [(set_attr "type" "multi")
7239 (set (attr "length")
7240 (cond [(eq_attr "calls_alloca" "false")
7242 (eq_attr "isa" "!v9")
7244 (eq_attr "pic" "true")
7245 (const_int 4)] (const_int 3)))])
7247 ;; Pattern for use after a setjmp to store FP and the return register
7248 ;; into the stack area.
7250 (define_expand "setjmp"
7256 mem = gen_rtx_MEM (Pmode,
7257 plus_constant (stack_pointer_rtx,
7258 SPARC_STACK_BIAS + 14 * UNITS_PER_WORD));
7259 emit_insn (gen_rtx_SET (VOIDmode, mem, frame_pointer_rtx));
7261 mem = gen_rtx_MEM (Pmode,
7262 plus_constant (stack_pointer_rtx,
7263 SPARC_STACK_BIAS + 15 * UNITS_PER_WORD));
7264 emit_insn (gen_rtx_SET (VOIDmode, mem, gen_rtx_REG (Pmode, 31)));
7268 ;; Special pattern for the FLUSH instruction.
7270 ; We do SImode and DImode versions of this to quiet down genrecog's complaints
7271 ; of the define_insn otherwise missing a mode. We make "flush", aka
7272 ; gen_flush, the default one since sparc_initialize_trampoline uses
7273 ; it on SImode mem values.
7275 (define_insn "flush"
7276 [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")] UNSPECV_FLUSH)]
7278 { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; }
7279 [(set_attr "type" "iflush")])
7281 (define_insn "flushdi"
7282 [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")] UNSPECV_FLUSH)]
7284 { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; }
7285 [(set_attr "type" "iflush")])
7288 ;; Find first set instructions.
7290 ;; The scan instruction searches from the most significant bit while ffs
7291 ;; searches from the least significant bit. The bit index and treatment of
7292 ;; zero also differ. It takes at least 7 instructions to get the proper
7293 ;; result. Here is an obvious 8 instruction sequence.
7296 (define_insn "ffssi2"
7297 [(set (match_operand:SI 0 "register_operand" "=&r")
7298 (ffs:SI (match_operand:SI 1 "register_operand" "r")))
7299 (clobber (match_scratch:SI 2 "=&r"))]
7300 "TARGET_SPARCLITE || TARGET_SPARCLET"
7302 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";
7304 [(set_attr "type" "multi")
7305 (set_attr "length" "8")])
7307 ;; ??? This should be a define expand, so that the extra instruction have
7308 ;; a chance of being optimized away.
7310 ;; Disabled because none of the UltraSPARCs implement popc. The HAL R1
7311 ;; does, but no one uses that and we don't have a switch for it.
7313 ;(define_insn "ffsdi2"
7314 ; [(set (match_operand:DI 0 "register_operand" "=&r")
7315 ; (ffs:DI (match_operand:DI 1 "register_operand" "r")))
7316 ; (clobber (match_scratch:DI 2 "=&r"))]
7318 ; "neg\t%1, %2\;xnor\t%1, %2, %2\;popc\t%2, %0\;movzr\t%1, 0, %0"
7319 ; [(set_attr "type" "multi")
7320 ; (set_attr "length" "4")])
7324 ;; Peepholes go at the end.
7326 ;; Optimize consecutive loads or stores into ldd and std when possible.
7327 ;; The conditions in which we do this are very restricted and are
7328 ;; explained in the code for {registers,memory}_ok_for_ldd functions.
7331 [(set (match_operand:SI 0 "memory_operand" "")
7333 (set (match_operand:SI 1 "memory_operand" "")
7336 && mems_ok_for_ldd_peep (operands[0], operands[1], NULL_RTX)"
7339 "operands[0] = widen_memory_access (operands[0], DImode, 0);")
7342 [(set (match_operand:SI 0 "memory_operand" "")
7344 (set (match_operand:SI 1 "memory_operand" "")
7347 && mems_ok_for_ldd_peep (operands[1], operands[0], NULL_RTX)"
7350 "operands[1] = widen_memory_access (operands[1], DImode, 0);")
7353 [(set (match_operand:SI 0 "register_operand" "")
7354 (match_operand:SI 1 "memory_operand" ""))
7355 (set (match_operand:SI 2 "register_operand" "")
7356 (match_operand:SI 3 "memory_operand" ""))]
7357 "registers_ok_for_ldd_peep (operands[0], operands[2])
7358 && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
7361 "operands[1] = widen_memory_access (operands[1], DImode, 0);
7362 operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));")
7365 [(set (match_operand:SI 0 "memory_operand" "")
7366 (match_operand:SI 1 "register_operand" ""))
7367 (set (match_operand:SI 2 "memory_operand" "")
7368 (match_operand:SI 3 "register_operand" ""))]
7369 "registers_ok_for_ldd_peep (operands[1], operands[3])
7370 && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
7373 "operands[0] = widen_memory_access (operands[0], DImode, 0);
7374 operands[1] = gen_rtx_REG (DImode, REGNO (operands[1]));")
7377 [(set (match_operand:SF 0 "register_operand" "")
7378 (match_operand:SF 1 "memory_operand" ""))
7379 (set (match_operand:SF 2 "register_operand" "")
7380 (match_operand:SF 3 "memory_operand" ""))]
7381 "registers_ok_for_ldd_peep (operands[0], operands[2])
7382 && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
7385 "operands[1] = widen_memory_access (operands[1], DFmode, 0);
7386 operands[0] = gen_rtx_REG (DFmode, REGNO (operands[0]));")
7389 [(set (match_operand:SF 0 "memory_operand" "")
7390 (match_operand:SF 1 "register_operand" ""))
7391 (set (match_operand:SF 2 "memory_operand" "")
7392 (match_operand:SF 3 "register_operand" ""))]
7393 "registers_ok_for_ldd_peep (operands[1], operands[3])
7394 && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
7397 "operands[0] = widen_memory_access (operands[0], DFmode, 0);
7398 operands[1] = gen_rtx_REG (DFmode, REGNO (operands[1]));")
7401 [(set (match_operand:SI 0 "register_operand" "")
7402 (match_operand:SI 1 "memory_operand" ""))
7403 (set (match_operand:SI 2 "register_operand" "")
7404 (match_operand:SI 3 "memory_operand" ""))]
7405 "registers_ok_for_ldd_peep (operands[2], operands[0])
7406 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
7409 "operands[3] = widen_memory_access (operands[3], DImode, 0);
7410 operands[2] = gen_rtx_REG (DImode, REGNO (operands[2]));")
7413 [(set (match_operand:SI 0 "memory_operand" "")
7414 (match_operand:SI 1 "register_operand" ""))
7415 (set (match_operand:SI 2 "memory_operand" "")
7416 (match_operand:SI 3 "register_operand" ""))]
7417 "registers_ok_for_ldd_peep (operands[3], operands[1])
7418 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
7421 "operands[2] = widen_memory_access (operands[2], DImode, 0);
7422 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
7426 [(set (match_operand:SF 0 "register_operand" "")
7427 (match_operand:SF 1 "memory_operand" ""))
7428 (set (match_operand:SF 2 "register_operand" "")
7429 (match_operand:SF 3 "memory_operand" ""))]
7430 "registers_ok_for_ldd_peep (operands[2], operands[0])
7431 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
7434 "operands[3] = widen_memory_access (operands[3], DFmode, 0);
7435 operands[2] = gen_rtx_REG (DFmode, REGNO (operands[2]));")
7438 [(set (match_operand:SF 0 "memory_operand" "")
7439 (match_operand:SF 1 "register_operand" ""))
7440 (set (match_operand:SF 2 "memory_operand" "")
7441 (match_operand:SF 3 "register_operand" ""))]
7442 "registers_ok_for_ldd_peep (operands[3], operands[1])
7443 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
7446 "operands[2] = widen_memory_access (operands[2], DFmode, 0);
7447 operands[3] = gen_rtx_REG (DFmode, REGNO (operands[3]));")
7449 ;; Optimize the case of following a reg-reg move with a test
7450 ;; of reg just moved. Don't allow floating point regs for operand 0 or 1.
7451 ;; This can result from a float to fix conversion.
7454 [(set (match_operand:SI 0 "register_operand" "")
7455 (match_operand:SI 1 "register_operand" ""))
7457 (compare:CC (match_operand:SI 2 "register_operand" "")
7459 "(rtx_equal_p (operands[2], operands[0])
7460 || rtx_equal_p (operands[2], operands[1]))
7461 && ! SPARC_FP_REG_P (REGNO (operands[0]))
7462 && ! SPARC_FP_REG_P (REGNO (operands[1]))"
7463 [(parallel [(set (match_dup 0) (match_dup 1))
7465 (compare:CC (match_dup 1) (const_int 0)))])]
7469 [(set (match_operand:DI 0 "register_operand" "")
7470 (match_operand:DI 1 "register_operand" ""))
7472 (compare:CCX (match_operand:DI 2 "register_operand" "")
7475 && (rtx_equal_p (operands[2], operands[0])
7476 || rtx_equal_p (operands[2], operands[1]))
7477 && ! SPARC_FP_REG_P (REGNO (operands[0]))
7478 && ! SPARC_FP_REG_P (REGNO (operands[1]))"
7479 [(parallel [(set (match_dup 0) (match_dup 1))
7481 (compare:CCX (match_dup 1) (const_int 0)))])]
7485 ;; Prefetch instructions.
7487 ;; ??? UltraSPARC-III note: A memory operation loading into the floating point register
7488 ;; ??? file, if it hits the prefetch cache, has a chance to dual-issue with other memory
7489 ;; ??? operations. With DFA we might be able to model this, but it requires a lot of
7491 (define_expand "prefetch"
7492 [(match_operand 0 "address_operand" "")
7493 (match_operand 1 "const_int_operand" "")
7494 (match_operand 2 "const_int_operand" "")]
7498 emit_insn (gen_prefetch_64 (operands[0], operands[1], operands[2]));
7500 emit_insn (gen_prefetch_32 (operands[0], operands[1], operands[2]));
7504 (define_insn "prefetch_64"
7505 [(prefetch (match_operand:DI 0 "address_operand" "p")
7506 (match_operand:DI 1 "const_int_operand" "n")
7507 (match_operand:DI 2 "const_int_operand" "n"))]
7510 static const char * const prefetch_instr[2][2] = {
7512 "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
7513 "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
7516 "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
7517 "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
7520 int read_or_write = INTVAL (operands[1]);
7521 int locality = INTVAL (operands[2]);
7523 gcc_assert (read_or_write == 0 || read_or_write == 1);
7524 gcc_assert (locality >= 0 && locality < 4);
7525 return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
7527 [(set_attr "type" "load")])
7529 (define_insn "prefetch_32"
7530 [(prefetch (match_operand:SI 0 "address_operand" "p")
7531 (match_operand:SI 1 "const_int_operand" "n")
7532 (match_operand:SI 2 "const_int_operand" "n"))]
7535 static const char * const prefetch_instr[2][2] = {
7537 "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
7538 "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
7541 "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
7542 "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
7545 int read_or_write = INTVAL (operands[1]);
7546 int locality = INTVAL (operands[2]);
7548 gcc_assert (read_or_write == 0 || read_or_write == 1);
7549 gcc_assert (locality >= 0 && locality < 4);
7550 return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
7552 [(set_attr "type" "load")])
7555 ;; Trap instructions.
7558 [(trap_if (const_int 1) (const_int 5))]
7561 [(set_attr "type" "trap")])
7563 (define_expand "conditional_trap"
7564 [(trap_if (match_operator 0 "noov_compare_operator" [(match_dup 2) (match_dup 3)])
7565 (match_operand:SI 1 "arith_operand" ""))]
7567 "operands[2] = gen_compare_reg (GET_CODE (operands[0]));
7568 if (GET_MODE (operands[2]) != CCmode && GET_MODE (operands[2]) != CCXmode)
7570 operands[3] = const0_rtx;")
7573 [(trap_if (match_operator 0 "noov_compare_operator" [(reg:CC 100) (const_int 0)])
7574 (match_operand:SI 1 "arith_operand" "rM"))]
7578 return "t%C0\t%%icc, %1";
7582 [(set_attr "type" "trap")])
7585 [(trap_if (match_operator 0 "noov_compare_operator" [(reg:CCX 100) (const_int 0)])
7586 (match_operand:SI 1 "arith_operand" "rM"))]
7589 [(set_attr "type" "trap")])
7592 ;; TLS support instructions.
7594 (define_insn "tgd_hi22"
7595 [(set (match_operand:SI 0 "register_operand" "=r")
7596 (high:SI (unspec:SI [(match_operand 1 "tgd_symbolic_operand" "")]
7599 "sethi\\t%%tgd_hi22(%a1), %0")
7601 (define_insn "tgd_lo10"
7602 [(set (match_operand:SI 0 "register_operand" "=r")
7603 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7604 (unspec:SI [(match_operand 2 "tgd_symbolic_operand" "")]
7607 "add\\t%1, %%tgd_lo10(%a2), %0")
7609 (define_insn "tgd_add32"
7610 [(set (match_operand:SI 0 "register_operand" "=r")
7611 (plus:SI (match_operand:SI 1 "register_operand" "r")
7612 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7613 (match_operand 3 "tgd_symbolic_operand" "")]
7615 "TARGET_TLS && TARGET_ARCH32"
7616 "add\\t%1, %2, %0, %%tgd_add(%a3)")
7618 (define_insn "tgd_add64"
7619 [(set (match_operand:DI 0 "register_operand" "=r")
7620 (plus:DI (match_operand:DI 1 "register_operand" "r")
7621 (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7622 (match_operand 3 "tgd_symbolic_operand" "")]
7624 "TARGET_TLS && TARGET_ARCH64"
7625 "add\\t%1, %2, %0, %%tgd_add(%a3)")
7627 (define_insn "tgd_call32"
7628 [(set (match_operand 0 "register_operand" "=r")
7629 (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")
7630 (match_operand 2 "tgd_symbolic_operand" "")]
7632 (match_operand 3 "" "")))
7633 (clobber (reg:SI 15))]
7634 "TARGET_TLS && TARGET_ARCH32"
7635 "call\t%a1, %%tgd_call(%a2)%#"
7636 [(set_attr "type" "call")])
7638 (define_insn "tgd_call64"
7639 [(set (match_operand 0 "register_operand" "=r")
7640 (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")
7641 (match_operand 2 "tgd_symbolic_operand" "")]
7643 (match_operand 3 "" "")))
7644 (clobber (reg:DI 15))]
7645 "TARGET_TLS && TARGET_ARCH64"
7646 "call\t%a1, %%tgd_call(%a2)%#"
7647 [(set_attr "type" "call")])
7649 (define_insn "tldm_hi22"
7650 [(set (match_operand:SI 0 "register_operand" "=r")
7651 (high:SI (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
7653 "sethi\\t%%tldm_hi22(%&), %0")
7655 (define_insn "tldm_lo10"
7656 [(set (match_operand:SI 0 "register_operand" "=r")
7657 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7658 (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
7660 "add\\t%1, %%tldm_lo10(%&), %0")
7662 (define_insn "tldm_add32"
7663 [(set (match_operand:SI 0 "register_operand" "=r")
7664 (plus:SI (match_operand:SI 1 "register_operand" "r")
7665 (unspec:SI [(match_operand:SI 2 "register_operand" "r")]
7667 "TARGET_TLS && TARGET_ARCH32"
7668 "add\\t%1, %2, %0, %%tldm_add(%&)")
7670 (define_insn "tldm_add64"
7671 [(set (match_operand:DI 0 "register_operand" "=r")
7672 (plus:DI (match_operand:DI 1 "register_operand" "r")
7673 (unspec:DI [(match_operand:SI 2 "register_operand" "r")]
7675 "TARGET_TLS && TARGET_ARCH64"
7676 "add\\t%1, %2, %0, %%tldm_add(%&)")
7678 (define_insn "tldm_call32"
7679 [(set (match_operand 0 "register_operand" "=r")
7680 (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")]
7682 (match_operand 2 "" "")))
7683 (clobber (reg:SI 15))]
7684 "TARGET_TLS && TARGET_ARCH32"
7685 "call\t%a1, %%tldm_call(%&)%#"
7686 [(set_attr "type" "call")])
7688 (define_insn "tldm_call64"
7689 [(set (match_operand 0 "register_operand" "=r")
7690 (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")]
7692 (match_operand 2 "" "")))
7693 (clobber (reg:DI 15))]
7694 "TARGET_TLS && TARGET_ARCH64"
7695 "call\t%a1, %%tldm_call(%&)%#"
7696 [(set_attr "type" "call")])
7698 (define_insn "tldo_hix22"
7699 [(set (match_operand:SI 0 "register_operand" "=r")
7700 (high:SI (unspec:SI [(match_operand 1 "tld_symbolic_operand" "")]
7703 "sethi\\t%%tldo_hix22(%a1), %0")
7705 (define_insn "tldo_lox10"
7706 [(set (match_operand:SI 0 "register_operand" "=r")
7707 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7708 (unspec:SI [(match_operand 2 "tld_symbolic_operand" "")]
7711 "xor\\t%1, %%tldo_lox10(%a2), %0")
7713 (define_insn "tldo_add32"
7714 [(set (match_operand:SI 0 "register_operand" "=r")
7715 (plus:SI (match_operand:SI 1 "register_operand" "r")
7716 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7717 (match_operand 3 "tld_symbolic_operand" "")]
7719 "TARGET_TLS && TARGET_ARCH32"
7720 "add\\t%1, %2, %0, %%tldo_add(%a3)")
7722 (define_insn "tldo_add64"
7723 [(set (match_operand:DI 0 "register_operand" "=r")
7724 (plus:DI (match_operand:DI 1 "register_operand" "r")
7725 (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7726 (match_operand 3 "tld_symbolic_operand" "")]
7728 "TARGET_TLS && TARGET_ARCH64"
7729 "add\\t%1, %2, %0, %%tldo_add(%a3)")
7731 (define_insn "tie_hi22"
7732 [(set (match_operand:SI 0 "register_operand" "=r")
7733 (high:SI (unspec:SI [(match_operand 1 "tie_symbolic_operand" "")]
7736 "sethi\\t%%tie_hi22(%a1), %0")
7738 (define_insn "tie_lo10"
7739 [(set (match_operand:SI 0 "register_operand" "=r")
7740 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7741 (unspec:SI [(match_operand 2 "tie_symbolic_operand" "")]
7744 "add\\t%1, %%tie_lo10(%a2), %0")
7746 (define_insn "tie_ld32"
7747 [(set (match_operand:SI 0 "register_operand" "=r")
7748 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
7749 (match_operand:SI 2 "register_operand" "r")
7750 (match_operand 3 "tie_symbolic_operand" "")]
7752 "TARGET_TLS && TARGET_ARCH32"
7753 "ld\\t[%1 + %2], %0, %%tie_ld(%a3)"
7754 [(set_attr "type" "load")])
7756 (define_insn "tie_ld64"
7757 [(set (match_operand:DI 0 "register_operand" "=r")
7758 (unspec:DI [(match_operand:DI 1 "register_operand" "r")
7759 (match_operand:SI 2 "register_operand" "r")
7760 (match_operand 3 "tie_symbolic_operand" "")]
7762 "TARGET_TLS && TARGET_ARCH64"
7763 "ldx\\t[%1 + %2], %0, %%tie_ldx(%a3)"
7764 [(set_attr "type" "load")])
7766 (define_insn "tie_add32"
7767 [(set (match_operand:SI 0 "register_operand" "=r")
7768 (plus:SI (match_operand:SI 1 "register_operand" "r")
7769 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7770 (match_operand 3 "tie_symbolic_operand" "")]
7772 "TARGET_SUN_TLS && TARGET_ARCH32"
7773 "add\\t%1, %2, %0, %%tie_add(%a3)")
7775 (define_insn "tie_add64"
7776 [(set (match_operand:DI 0 "register_operand" "=r")
7777 (plus:DI (match_operand:DI 1 "register_operand" "r")
7778 (unspec:DI [(match_operand:DI 2 "register_operand" "r")
7779 (match_operand 3 "tie_symbolic_operand" "")]
7781 "TARGET_SUN_TLS && TARGET_ARCH64"
7782 "add\\t%1, %2, %0, %%tie_add(%a3)")
7784 (define_insn "tle_hix22_sp32"
7785 [(set (match_operand:SI 0 "register_operand" "=r")
7786 (high:SI (unspec:SI [(match_operand 1 "tle_symbolic_operand" "")]
7788 "TARGET_TLS && TARGET_ARCH32"
7789 "sethi\\t%%tle_hix22(%a1), %0")
7791 (define_insn "tle_lox10_sp32"
7792 [(set (match_operand:SI 0 "register_operand" "=r")
7793 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7794 (unspec:SI [(match_operand 2 "tle_symbolic_operand" "")]
7796 "TARGET_TLS && TARGET_ARCH32"
7797 "xor\\t%1, %%tle_lox10(%a2), %0")
7799 (define_insn "tle_hix22_sp64"
7800 [(set (match_operand:DI 0 "register_operand" "=r")
7801 (high:DI (unspec:DI [(match_operand 1 "tle_symbolic_operand" "")]
7803 "TARGET_TLS && TARGET_ARCH64"
7804 "sethi\\t%%tle_hix22(%a1), %0")
7806 (define_insn "tle_lox10_sp64"
7807 [(set (match_operand:DI 0 "register_operand" "=r")
7808 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
7809 (unspec:DI [(match_operand 2 "tle_symbolic_operand" "")]
7811 "TARGET_TLS && TARGET_ARCH64"
7812 "xor\\t%1, %%tle_lox10(%a2), %0")
7814 ;; Now patterns combining tldo_add{32,64} with some integer loads or stores
7815 (define_insn "*tldo_ldub_sp32"
7816 [(set (match_operand:QI 0 "register_operand" "=r")
7817 (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7818 (match_operand 3 "tld_symbolic_operand" "")]
7820 (match_operand:SI 1 "register_operand" "r"))))]
7821 "TARGET_TLS && TARGET_ARCH32"
7822 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7823 [(set_attr "type" "load")
7824 (set_attr "us3load_type" "3cycle")])
7826 (define_insn "*tldo_ldub1_sp32"
7827 [(set (match_operand:HI 0 "register_operand" "=r")
7828 (zero_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7829 (match_operand 3 "tld_symbolic_operand" "")]
7831 (match_operand:SI 1 "register_operand" "r")))))]
7832 "TARGET_TLS && TARGET_ARCH32"
7833 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7834 [(set_attr "type" "load")
7835 (set_attr "us3load_type" "3cycle")])
7837 (define_insn "*tldo_ldub2_sp32"
7838 [(set (match_operand:SI 0 "register_operand" "=r")
7839 (zero_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7840 (match_operand 3 "tld_symbolic_operand" "")]
7842 (match_operand:SI 1 "register_operand" "r")))))]
7843 "TARGET_TLS && TARGET_ARCH32"
7844 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7845 [(set_attr "type" "load")
7846 (set_attr "us3load_type" "3cycle")])
7848 (define_insn "*tldo_ldsb1_sp32"
7849 [(set (match_operand:HI 0 "register_operand" "=r")
7850 (sign_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7851 (match_operand 3 "tld_symbolic_operand" "")]
7853 (match_operand:SI 1 "register_operand" "r")))))]
7854 "TARGET_TLS && TARGET_ARCH32"
7855 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7856 [(set_attr "type" "sload")
7857 (set_attr "us3load_type" "3cycle")])
7859 (define_insn "*tldo_ldsb2_sp32"
7860 [(set (match_operand:SI 0 "register_operand" "=r")
7861 (sign_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7862 (match_operand 3 "tld_symbolic_operand" "")]
7864 (match_operand:SI 1 "register_operand" "r")))))]
7865 "TARGET_TLS && TARGET_ARCH32"
7866 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7867 [(set_attr "type" "sload")
7868 (set_attr "us3load_type" "3cycle")])
7870 (define_insn "*tldo_ldub_sp64"
7871 [(set (match_operand:QI 0 "register_operand" "=r")
7872 (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7873 (match_operand 3 "tld_symbolic_operand" "")]
7875 (match_operand:DI 1 "register_operand" "r"))))]
7876 "TARGET_TLS && TARGET_ARCH64"
7877 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7878 [(set_attr "type" "load")
7879 (set_attr "us3load_type" "3cycle")])
7881 (define_insn "*tldo_ldub1_sp64"
7882 [(set (match_operand:HI 0 "register_operand" "=r")
7883 (zero_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7884 (match_operand 3 "tld_symbolic_operand" "")]
7886 (match_operand:DI 1 "register_operand" "r")))))]
7887 "TARGET_TLS && TARGET_ARCH64"
7888 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7889 [(set_attr "type" "load")
7890 (set_attr "us3load_type" "3cycle")])
7892 (define_insn "*tldo_ldub2_sp64"
7893 [(set (match_operand:SI 0 "register_operand" "=r")
7894 (zero_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7895 (match_operand 3 "tld_symbolic_operand" "")]
7897 (match_operand:DI 1 "register_operand" "r")))))]
7898 "TARGET_TLS && TARGET_ARCH64"
7899 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7900 [(set_attr "type" "load")
7901 (set_attr "us3load_type" "3cycle")])
7903 (define_insn "*tldo_ldub3_sp64"
7904 [(set (match_operand:DI 0 "register_operand" "=r")
7905 (zero_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7906 (match_operand 3 "tld_symbolic_operand" "")]
7908 (match_operand:DI 1 "register_operand" "r")))))]
7909 "TARGET_TLS && TARGET_ARCH64"
7910 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7911 [(set_attr "type" "load")
7912 (set_attr "us3load_type" "3cycle")])
7914 (define_insn "*tldo_ldsb1_sp64"
7915 [(set (match_operand:HI 0 "register_operand" "=r")
7916 (sign_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7917 (match_operand 3 "tld_symbolic_operand" "")]
7919 (match_operand:DI 1 "register_operand" "r")))))]
7920 "TARGET_TLS && TARGET_ARCH64"
7921 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7922 [(set_attr "type" "sload")
7923 (set_attr "us3load_type" "3cycle")])
7925 (define_insn "*tldo_ldsb2_sp64"
7926 [(set (match_operand:SI 0 "register_operand" "=r")
7927 (sign_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7928 (match_operand 3 "tld_symbolic_operand" "")]
7930 (match_operand:DI 1 "register_operand" "r")))))]
7931 "TARGET_TLS && TARGET_ARCH64"
7932 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7933 [(set_attr "type" "sload")
7934 (set_attr "us3load_type" "3cycle")])
7936 (define_insn "*tldo_ldsb3_sp64"
7937 [(set (match_operand:DI 0 "register_operand" "=r")
7938 (sign_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7939 (match_operand 3 "tld_symbolic_operand" "")]
7941 (match_operand:DI 1 "register_operand" "r")))))]
7942 "TARGET_TLS && TARGET_ARCH64"
7943 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7944 [(set_attr "type" "sload")
7945 (set_attr "us3load_type" "3cycle")])
7947 (define_insn "*tldo_lduh_sp32"
7948 [(set (match_operand:HI 0 "register_operand" "=r")
7949 (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7950 (match_operand 3 "tld_symbolic_operand" "")]
7952 (match_operand:SI 1 "register_operand" "r"))))]
7953 "TARGET_TLS && TARGET_ARCH32"
7954 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7955 [(set_attr "type" "load")
7956 (set_attr "us3load_type" "3cycle")])
7958 (define_insn "*tldo_lduh1_sp32"
7959 [(set (match_operand:SI 0 "register_operand" "=r")
7960 (zero_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7961 (match_operand 3 "tld_symbolic_operand" "")]
7963 (match_operand:SI 1 "register_operand" "r")))))]
7964 "TARGET_TLS && TARGET_ARCH32"
7965 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7966 [(set_attr "type" "load")
7967 (set_attr "us3load_type" "3cycle")])
7969 (define_insn "*tldo_ldsh1_sp32"
7970 [(set (match_operand:SI 0 "register_operand" "=r")
7971 (sign_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7972 (match_operand 3 "tld_symbolic_operand" "")]
7974 (match_operand:SI 1 "register_operand" "r")))))]
7975 "TARGET_TLS && TARGET_ARCH32"
7976 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
7977 [(set_attr "type" "sload")
7978 (set_attr "us3load_type" "3cycle")])
7980 (define_insn "*tldo_lduh_sp64"
7981 [(set (match_operand:HI 0 "register_operand" "=r")
7982 (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7983 (match_operand 3 "tld_symbolic_operand" "")]
7985 (match_operand:DI 1 "register_operand" "r"))))]
7986 "TARGET_TLS && TARGET_ARCH64"
7987 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7988 [(set_attr "type" "load")
7989 (set_attr "us3load_type" "3cycle")])
7991 (define_insn "*tldo_lduh1_sp64"
7992 [(set (match_operand:SI 0 "register_operand" "=r")
7993 (zero_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7994 (match_operand 3 "tld_symbolic_operand" "")]
7996 (match_operand:DI 1 "register_operand" "r")))))]
7997 "TARGET_TLS && TARGET_ARCH64"
7998 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7999 [(set_attr "type" "load")
8000 (set_attr "us3load_type" "3cycle")])
8002 (define_insn "*tldo_lduh2_sp64"
8003 [(set (match_operand:DI 0 "register_operand" "=r")
8004 (zero_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8005 (match_operand 3 "tld_symbolic_operand" "")]
8007 (match_operand:DI 1 "register_operand" "r")))))]
8008 "TARGET_TLS && TARGET_ARCH64"
8009 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
8010 [(set_attr "type" "load")
8011 (set_attr "us3load_type" "3cycle")])
8013 (define_insn "*tldo_ldsh1_sp64"
8014 [(set (match_operand:SI 0 "register_operand" "=r")
8015 (sign_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8016 (match_operand 3 "tld_symbolic_operand" "")]
8018 (match_operand:DI 1 "register_operand" "r")))))]
8019 "TARGET_TLS && TARGET_ARCH64"
8020 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
8021 [(set_attr "type" "sload")
8022 (set_attr "us3load_type" "3cycle")])
8024 (define_insn "*tldo_ldsh2_sp64"
8025 [(set (match_operand:DI 0 "register_operand" "=r")
8026 (sign_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8027 (match_operand 3 "tld_symbolic_operand" "")]
8029 (match_operand:DI 1 "register_operand" "r")))))]
8030 "TARGET_TLS && TARGET_ARCH64"
8031 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
8032 [(set_attr "type" "sload")
8033 (set_attr "us3load_type" "3cycle")])
8035 (define_insn "*tldo_lduw_sp32"
8036 [(set (match_operand:SI 0 "register_operand" "=r")
8037 (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8038 (match_operand 3 "tld_symbolic_operand" "")]
8040 (match_operand:SI 1 "register_operand" "r"))))]
8041 "TARGET_TLS && TARGET_ARCH32"
8042 "ld\t[%1 + %2], %0, %%tldo_add(%3)"
8043 [(set_attr "type" "load")])
8045 (define_insn "*tldo_lduw_sp64"
8046 [(set (match_operand:SI 0 "register_operand" "=r")
8047 (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8048 (match_operand 3 "tld_symbolic_operand" "")]
8050 (match_operand:DI 1 "register_operand" "r"))))]
8051 "TARGET_TLS && TARGET_ARCH64"
8052 "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
8053 [(set_attr "type" "load")])
8055 (define_insn "*tldo_lduw1_sp64"
8056 [(set (match_operand:DI 0 "register_operand" "=r")
8057 (zero_extend:DI (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8058 (match_operand 3 "tld_symbolic_operand" "")]
8060 (match_operand:DI 1 "register_operand" "r")))))]
8061 "TARGET_TLS && TARGET_ARCH64"
8062 "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
8063 [(set_attr "type" "load")])
8065 (define_insn "*tldo_ldsw1_sp64"
8066 [(set (match_operand:DI 0 "register_operand" "=r")
8067 (sign_extend:DI (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8068 (match_operand 3 "tld_symbolic_operand" "")]
8070 (match_operand:DI 1 "register_operand" "r")))))]
8071 "TARGET_TLS && TARGET_ARCH64"
8072 "ldsw\t[%1 + %2], %0, %%tldo_add(%3)"
8073 [(set_attr "type" "sload")
8074 (set_attr "us3load_type" "3cycle")])
8076 (define_insn "*tldo_ldx_sp64"
8077 [(set (match_operand:DI 0 "register_operand" "=r")
8078 (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8079 (match_operand 3 "tld_symbolic_operand" "")]
8081 (match_operand:DI 1 "register_operand" "r"))))]
8082 "TARGET_TLS && TARGET_ARCH64"
8083 "ldx\t[%1 + %2], %0, %%tldo_add(%3)"
8084 [(set_attr "type" "load")])
8086 (define_insn "*tldo_stb_sp32"
8087 [(set (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8088 (match_operand 3 "tld_symbolic_operand" "")]
8090 (match_operand:SI 1 "register_operand" "r")))
8091 (match_operand:QI 0 "register_operand" "=r"))]
8092 "TARGET_TLS && TARGET_ARCH32"
8093 "stb\t%0, [%1 + %2], %%tldo_add(%3)"
8094 [(set_attr "type" "store")])
8096 (define_insn "*tldo_stb_sp64"
8097 [(set (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8098 (match_operand 3 "tld_symbolic_operand" "")]
8100 (match_operand:DI 1 "register_operand" "r")))
8101 (match_operand:QI 0 "register_operand" "=r"))]
8102 "TARGET_TLS && TARGET_ARCH64"
8103 "stb\t%0, [%1 + %2], %%tldo_add(%3)"
8104 [(set_attr "type" "store")])
8106 (define_insn "*tldo_sth_sp32"
8107 [(set (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8108 (match_operand 3 "tld_symbolic_operand" "")]
8110 (match_operand:SI 1 "register_operand" "r")))
8111 (match_operand:HI 0 "register_operand" "=r"))]
8112 "TARGET_TLS && TARGET_ARCH32"
8113 "sth\t%0, [%1 + %2], %%tldo_add(%3)"
8114 [(set_attr "type" "store")])
8116 (define_insn "*tldo_sth_sp64"
8117 [(set (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8118 (match_operand 3 "tld_symbolic_operand" "")]
8120 (match_operand:DI 1 "register_operand" "r")))
8121 (match_operand:HI 0 "register_operand" "=r"))]
8122 "TARGET_TLS && TARGET_ARCH64"
8123 "sth\t%0, [%1 + %2], %%tldo_add(%3)"
8124 [(set_attr "type" "store")])
8126 (define_insn "*tldo_stw_sp32"
8127 [(set (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8128 (match_operand 3 "tld_symbolic_operand" "")]
8130 (match_operand:SI 1 "register_operand" "r")))
8131 (match_operand:SI 0 "register_operand" "=r"))]
8132 "TARGET_TLS && TARGET_ARCH32"
8133 "st\t%0, [%1 + %2], %%tldo_add(%3)"
8134 [(set_attr "type" "store")])
8136 (define_insn "*tldo_stw_sp64"
8137 [(set (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8138 (match_operand 3 "tld_symbolic_operand" "")]
8140 (match_operand:DI 1 "register_operand" "r")))
8141 (match_operand:SI 0 "register_operand" "=r"))]
8142 "TARGET_TLS && TARGET_ARCH64"
8143 "stw\t%0, [%1 + %2], %%tldo_add(%3)"
8144 [(set_attr "type" "store")])
8146 (define_insn "*tldo_stx_sp64"
8147 [(set (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8148 (match_operand 3 "tld_symbolic_operand" "")]
8150 (match_operand:DI 1 "register_operand" "r")))
8151 (match_operand:DI 0 "register_operand" "=r"))]
8152 "TARGET_TLS && TARGET_ARCH64"
8153 "stx\t%0, [%1 + %2], %%tldo_add(%3)"
8154 [(set_attr "type" "store")])
8157 ;; Stack protector instructions.
8159 (define_expand "stack_protect_set"
8160 [(match_operand 0 "memory_operand" "")
8161 (match_operand 1 "memory_operand" "")]
8164 #ifdef TARGET_THREAD_SSP_OFFSET
8165 rtx tlsreg = gen_rtx_REG (Pmode, 7);
8166 rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
8167 operands[1] = gen_rtx_MEM (Pmode, addr);
8170 emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
8172 emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
8176 (define_insn "stack_protect_setsi"
8177 [(set (match_operand:SI 0 "memory_operand" "=m")
8178 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
8179 (set (match_scratch:SI 2 "=&r") (const_int 0))]
8181 "ld\t%1, %2\;st\t%2, %0\;mov\t0, %2"
8182 [(set_attr "type" "multi")
8183 (set_attr "length" "3")])
8185 (define_insn "stack_protect_setdi"
8186 [(set (match_operand:DI 0 "memory_operand" "=m")
8187 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
8188 (set (match_scratch:DI 2 "=&r") (const_int 0))]
8190 "ldx\t%1, %2\;stx\t%2, %0\;mov\t0, %2"
8191 [(set_attr "type" "multi")
8192 (set_attr "length" "3")])
8194 (define_expand "stack_protect_test"
8195 [(match_operand 0 "memory_operand" "")
8196 (match_operand 1 "memory_operand" "")
8197 (match_operand 2 "" "")]
8200 #ifdef TARGET_THREAD_SSP_OFFSET
8201 rtx tlsreg = gen_rtx_REG (Pmode, 7);
8202 rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
8203 operands[1] = gen_rtx_MEM (Pmode, addr);
8207 rtx temp = gen_reg_rtx (Pmode);
8208 emit_insn (gen_stack_protect_testdi (temp, operands[0], operands[1]));
8209 sparc_compare_op0 = temp;
8210 sparc_compare_op1 = const0_rtx;
8214 emit_insn (gen_stack_protect_testsi (operands[0], operands[1]));
8215 sparc_compare_op0 = operands[0];
8216 sparc_compare_op1 = operands[1];
8217 sparc_compare_emitted = gen_rtx_REG (CCmode, SPARC_ICC_REG);
8219 emit_jump_insn (gen_beq (operands[2]));
8223 (define_insn "stack_protect_testsi"
8225 (unspec:CC [(match_operand:SI 0 "memory_operand" "m")
8226 (match_operand:SI 1 "memory_operand" "m")]
8228 (set (match_scratch:SI 3 "=r") (const_int 0))
8229 (clobber (match_scratch:SI 2 "=&r"))]
8231 "ld\t%0, %2\;ld\t%1, %3\;xorcc\t%2, %3, %2\;mov\t0, %3"
8232 [(set_attr "type" "multi")
8233 (set_attr "length" "4")])
8235 (define_insn "stack_protect_testdi"
8236 [(set (match_operand:DI 0 "register_operand" "=&r")
8237 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
8238 (match_operand:DI 2 "memory_operand" "m")]
8240 (set (match_scratch:DI 3 "=r") (const_int 0))]
8242 "ldx\t%1, %0\;ldx\t%2, %3\;xor\t%0, %3, %0\;mov\t0, %3"
8243 [(set_attr "type" "multi")
8244 (set_attr "length" "4")])
8247 ;; Vector instructions.
8249 (define_insn "addv2si3"
8250 [(set (match_operand:V2SI 0 "register_operand" "=e")
8251 (plus:V2SI (match_operand:V2SI 1 "register_operand" "e")
8252 (match_operand:V2SI 2 "register_operand" "e")))]
8254 "fpadd32\t%1, %2, %0"
8255 [(set_attr "type" "fga")
8256 (set_attr "fptype" "double")])
8258 (define_insn "addv4hi3"
8259 [(set (match_operand:V4HI 0 "register_operand" "=e")
8260 (plus:V4HI (match_operand:V4HI 1 "register_operand" "e")
8261 (match_operand:V4HI 2 "register_operand" "e")))]
8263 "fpadd16\t%1, %2, %0"
8264 [(set_attr "type" "fga")
8265 (set_attr "fptype" "double")])
8267 ;; fpadd32s is emitted by the addsi3 pattern.
8269 (define_insn "addv2hi3"
8270 [(set (match_operand:V2HI 0 "register_operand" "=f")
8271 (plus:V2HI (match_operand:V2HI 1 "register_operand" "f")
8272 (match_operand:V2HI 2 "register_operand" "f")))]
8274 "fpadd16s\t%1, %2, %0"
8275 [(set_attr "type" "fga")
8276 (set_attr "fptype" "single")])
8278 (define_insn "subv2si3"
8279 [(set (match_operand:V2SI 0 "register_operand" "=e")
8280 (minus:V2SI (match_operand:V2SI 1 "register_operand" "e")
8281 (match_operand:V2SI 2 "register_operand" "e")))]
8283 "fpsub32\t%1, %2, %0"
8284 [(set_attr "type" "fga")
8285 (set_attr "fptype" "double")])
8287 (define_insn "subv4hi3"
8288 [(set (match_operand:V4HI 0 "register_operand" "=e")
8289 (minus:V4HI (match_operand:V4HI 1 "register_operand" "e")
8290 (match_operand:V4HI 2 "register_operand" "e")))]
8292 "fpsub16\t%1, %2, %0"
8293 [(set_attr "type" "fga")
8294 (set_attr "fptype" "double")])
8296 ;; fpsub32s is emitted by the subsi3 pattern.
8298 (define_insn "subv2hi3"
8299 [(set (match_operand:V2HI 0 "register_operand" "=f")
8300 (minus:V2HI (match_operand:V2HI 1 "register_operand" "f")
8301 (match_operand:V2HI 2 "register_operand" "f")))]
8303 "fpsub16s\t%1, %2, %0"
8304 [(set_attr "type" "fga")
8305 (set_attr "fptype" "single")])
8307 ;; All other logical instructions have integer equivalents so they
8308 ;; are defined together.
8310 ;; (ior (not (op1)) (not (op2))) is the canonical form of NAND.
8312 (define_insn "*nand<V64mode>_vis"
8313 [(set (match_operand:V64 0 "register_operand" "=e")
8314 (ior:V64 (not:V64 (match_operand:V64 1 "register_operand" "e"))
8315 (not:V64 (match_operand:V64 2 "register_operand" "e"))))]
8318 [(set_attr "type" "fga")
8319 (set_attr "fptype" "double")])
8321 (define_insn "*nand<V32mode>_vis"
8322 [(set (match_operand:V32 0 "register_operand" "=f")
8323 (ior:V32 (not:V32 (match_operand:V32 1 "register_operand" "f"))
8324 (not:V32 (match_operand:V32 2 "register_operand" "f"))))]
8326 "fnands\t%1, %2, %0"
8327 [(set_attr "type" "fga")
8328 (set_attr "fptype" "single")])
8330 ;; Hard to generate VIS instructions. We have builtins for these.
8332 (define_insn "fpack16_vis"
8333 [(set (match_operand:V4QI 0 "register_operand" "=f")
8334 (unspec:V4QI [(match_operand:V4HI 1 "register_operand" "e")]
8338 [(set_attr "type" "fga")
8339 (set_attr "fptype" "double")])
8341 (define_insn "fpackfix_vis"
8342 [(set (match_operand:V2HI 0 "register_operand" "=f")
8343 (unspec:V2HI [(match_operand:V2SI 1 "register_operand" "e")]
8347 [(set_attr "type" "fga")
8348 (set_attr "fptype" "double")])
8350 (define_insn "fpack32_vis"
8351 [(set (match_operand:V8QI 0 "register_operand" "=e")
8352 (unspec:V8QI [(match_operand:V2SI 1 "register_operand" "e")
8353 (match_operand:V8QI 2 "register_operand" "e")]
8356 "fpack32\t%1, %2, %0"
8357 [(set_attr "type" "fga")
8358 (set_attr "fptype" "double")])
8360 (define_insn "fexpand_vis"
8361 [(set (match_operand:V4HI 0 "register_operand" "=e")
8362 (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")]
8366 [(set_attr "type" "fga")
8367 (set_attr "fptype" "double")])
8369 ;; It may be possible to describe this operation as (1 indexed):
8370 ;; (vec_select (vec_duplicate (vec_duplicate (vec_concat 1 2)))
8371 ;; 1,5,10,14,19,23,28,32)
8372 ;; Note that (vec_merge:V8QI [(V4QI) (V4QI)] (10101010 = 170) doesn't work
8373 ;; because vec_merge expects all the operands to be of the same type.
8374 (define_insn "fpmerge_vis"
8375 [(set (match_operand:V8QI 0 "register_operand" "=e")
8376 (unspec:V8QI [(match_operand:V4QI 1 "register_operand" "f")
8377 (match_operand:V4QI 2 "register_operand" "f")]
8380 "fpmerge\t%1, %2, %0"
8381 [(set_attr "type" "fga")
8382 (set_attr "fptype" "double")])
8384 ;; Partitioned multiply instructions
8385 (define_insn "fmul8x16_vis"
8386 [(set (match_operand:V4HI 0 "register_operand" "=e")
8387 (mult:V4HI (match_operand:V4QI 1 "register_operand" "f")
8388 (match_operand:V4HI 2 "register_operand" "e")))]
8390 "fmul8x16\t%1, %2, %0"
8391 [(set_attr "type" "fpmul")
8392 (set_attr "fptype" "double")])
8394 ;; Only one of the following two insns can be a multiply.
8395 (define_insn "fmul8x16au_vis"
8396 [(set (match_operand:V4HI 0 "register_operand" "=e")
8397 (mult:V4HI (match_operand:V4QI 1 "register_operand" "f")
8398 (match_operand:V2HI 2 "register_operand" "f")))]
8400 "fmul8x16au\t%1, %2, %0"
8401 [(set_attr "type" "fpmul")
8402 (set_attr "fptype" "double")])
8404 (define_insn "fmul8x16al_vis"
8405 [(set (match_operand:V4HI 0 "register_operand" "=e")
8406 (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")
8407 (match_operand:V2HI 2 "register_operand" "f")]
8410 "fmul8x16al\t%1, %2, %0"
8411 [(set_attr "type" "fpmul")
8412 (set_attr "fptype" "double")])
8414 ;; Only one of the following two insns can be a multiply.
8415 (define_insn "fmul8sux16_vis"
8416 [(set (match_operand:V4HI 0 "register_operand" "=e")
8417 (mult:V4HI (match_operand:V8QI 1 "register_operand" "e")
8418 (match_operand:V4HI 2 "register_operand" "e")))]
8420 "fmul8sux16\t%1, %2, %0"
8421 [(set_attr "type" "fpmul")
8422 (set_attr "fptype" "double")])
8424 (define_insn "fmul8ulx16_vis"
8425 [(set (match_operand:V4HI 0 "register_operand" "=e")
8426 (unspec:V4HI [(match_operand:V8QI 1 "register_operand" "e")
8427 (match_operand:V4HI 2 "register_operand" "e")]
8430 "fmul8ulx16\t%1, %2, %0"
8431 [(set_attr "type" "fpmul")
8432 (set_attr "fptype" "double")])
8434 ;; Only one of the following two insns can be a multiply.
8435 (define_insn "fmuld8sux16_vis"
8436 [(set (match_operand:V2SI 0 "register_operand" "=e")
8437 (mult:V2SI (match_operand:V4QI 1 "register_operand" "f")
8438 (match_operand:V2HI 2 "register_operand" "f")))]
8440 "fmuld8sux16\t%1, %2, %0"
8441 [(set_attr "type" "fpmul")
8442 (set_attr "fptype" "double")])
8444 (define_insn "fmuld8ulx16_vis"
8445 [(set (match_operand:V2SI 0 "register_operand" "=e")
8446 (unspec:V2SI [(match_operand:V4QI 1 "register_operand" "f")
8447 (match_operand:V2HI 2 "register_operand" "f")]
8450 "fmuld8ulx16\t%1, %2, %0"
8451 [(set_attr "type" "fpmul")
8452 (set_attr "fptype" "double")])
8454 ;; Using faligndata only makes sense after an alignaddr since the choice of
8455 ;; bytes to take out of each operand is dependent on the results of the last
8457 (define_insn "faligndata<V64I:mode>_vis"
8458 [(set (match_operand:V64I 0 "register_operand" "=e")
8459 (unspec:V64I [(match_operand:V64I 1 "register_operand" "e")
8460 (match_operand:V64I 2 "register_operand" "e")]
8463 "faligndata\t%1, %2, %0"
8464 [(set_attr "type" "fga")
8465 (set_attr "fptype" "double")])
8467 (define_insn "alignaddr<P:mode>_vis"
8468 [(set (match_operand:P 0 "register_operand" "=r")
8469 (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
8470 (match_operand:P 2 "register_or_zero_operand" "rJ")]
8473 "alignaddr\t%r1, %r2, %0")
8475 (define_insn "pdist_vis"
8476 [(set (match_operand:DI 0 "register_operand" "=e")
8477 (unspec:DI [(match_operand:V8QI 1 "register_operand" "e")
8478 (match_operand:V8QI 2 "register_operand" "e")
8479 (match_operand:DI 3 "register_operand" "0")]
8483 [(set_attr "type" "fga")
8484 (set_attr "fptype" "double")])