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_");
1848 if (!can_create_pseudo_p ())
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 ;; Set up the PIC register for VxWorks.
1879 (define_expand "vxworks_load_got"
1881 (high:SI (match_dup 1)))
1883 (mem:SI (lo_sum:SI (match_dup 0) (match_dup 1))))
1885 (mem:SI (lo_sum:SI (match_dup 0) (match_dup 2))))]
1886 "TARGET_VXWORKS_RTP"
1888 operands[0] = pic_offset_table_rtx;
1889 operands[1] = gen_rtx_SYMBOL_REF (SImode, VXWORKS_GOTT_BASE);
1890 operands[2] = gen_rtx_SYMBOL_REF (SImode, VXWORKS_GOTT_INDEX);
1893 (define_expand "movdi"
1894 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1895 (match_operand:DI 1 "general_operand" ""))]
1898 if (sparc_expand_move (DImode, operands))
1902 ;; Be careful, fmovd does not exist when !v9.
1903 ;; We match MEM moves directly when we have correct even
1904 ;; numbered registers, but fall into splits otherwise.
1905 ;; The constraint ordering here is really important to
1906 ;; avoid insane problems in reload, especially for patterns
1909 ;; (set (mem:DI (plus:SI (reg:SI 30 %fp)
1910 ;; (const_int -5016)))
1914 (define_insn "*movdi_insn_sp32"
1915 [(set (match_operand:DI 0 "nonimmediate_operand"
1916 "=o,T,U,o,r,r,r,?T,?f,?f,?o,?f")
1917 (match_operand:DI 1 "input_operand"
1918 " J,U,T,r,o,i,r, f, T, o, f, f"))]
1920 && (register_operand (operands[0], DImode)
1921 || register_or_zero_operand (operands[1], DImode))"
1935 [(set_attr "type" "store,store,load,*,*,*,*,fpstore,fpload,*,*,*")
1936 (set_attr "length" "2,*,*,2,2,2,2,*,*,2,2,2")])
1938 (define_insn "*movdi_insn_sp32_v9"
1939 [(set (match_operand:DI 0 "nonimmediate_operand"
1940 "=T,o,T,U,o,r,r,r,?T,?f,?f,?o,?e,?e,?W")
1941 (match_operand:DI 1 "input_operand"
1942 " J,J,U,T,r,o,i,r, f, T, o, f, e, W, e"))]
1945 && (register_operand (operands[0], DImode)
1946 || register_or_zero_operand (operands[1], DImode))"
1963 [(set_attr "type" "store,store,store,load,*,*,*,*,fpstore,fpload,*,*,fpmove,fpload,fpstore")
1964 (set_attr "length" "*,2,*,*,2,2,2,2,*,*,2,2,*,*,*")
1965 (set_attr "fptype" "*,*,*,*,*,*,*,*,*,*,*,*,double,*,*")])
1967 (define_insn "*movdi_insn_sp64"
1968 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,m,?e,?e,?W,b")
1969 (match_operand:DI 1 "input_operand" "rI,N,m,rJ,e,W,e,J"))]
1971 && (register_operand (operands[0], DImode)
1972 || register_or_zero_operand (operands[1], DImode))"
1975 sethi\t%%hi(%a1), %0
1982 [(set_attr "type" "*,*,load,store,fpmove,fpload,fpstore,fga")
1983 (set_attr "fptype" "*,*,*,*,double,*,*,double")])
1985 (define_expand "movdi_pic_label_ref"
1986 [(set (match_dup 3) (high:DI
1987 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
1988 (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1989 (set (match_dup 4) (lo_sum:DI (match_dup 3)
1990 (unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1991 (set (match_operand:DI 0 "register_operand" "=r")
1992 (minus:DI (match_dup 5) (match_dup 4)))]
1993 "TARGET_ARCH64 && flag_pic"
1995 current_function_uses_pic_offset_table = 1;
1996 operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
1997 if (!can_create_pseudo_p ())
1999 operands[3] = operands[0];
2000 operands[4] = operands[0];
2004 operands[3] = gen_reg_rtx (DImode);
2005 operands[4] = gen_reg_rtx (DImode);
2007 operands[5] = pic_offset_table_rtx;
2010 (define_insn "*movdi_high_pic_label_ref"
2011 [(set (match_operand:DI 0 "register_operand" "=r")
2013 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
2014 (match_operand:DI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
2015 "TARGET_ARCH64 && flag_pic"
2016 "sethi\t%%hi(%a2-(%a1-.)), %0")
2018 (define_insn "*movdi_lo_sum_pic_label_ref"
2019 [(set (match_operand:DI 0 "register_operand" "=r")
2020 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2021 (unspec:DI [(match_operand:DI 2 "label_ref_operand" "")
2022 (match_operand:DI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
2023 "TARGET_ARCH64 && flag_pic"
2024 "or\t%1, %%lo(%a3-(%a2-.)), %0")
2026 ;; SPARC-v9 code model support insns. See sparc_emit_set_symbolic_const64
2027 ;; in sparc.c to see what is going on here... PIC stuff comes first.
2029 (define_insn "movdi_lo_sum_pic"
2030 [(set (match_operand:DI 0 "register_operand" "=r")
2031 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2032 (unspec:DI [(match_operand:DI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
2033 "TARGET_ARCH64 && flag_pic"
2034 "or\t%1, %%lo(%a2), %0")
2036 (define_insn "movdi_high_pic"
2037 [(set (match_operand:DI 0 "register_operand" "=r")
2038 (high:DI (unspec:DI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
2039 "TARGET_ARCH64 && flag_pic && check_pic (1)"
2040 "sethi\t%%hi(%a1), %0")
2042 (define_insn "*sethi_di_medlow_embmedany_pic"
2043 [(set (match_operand:DI 0 "register_operand" "=r")
2044 (high:DI (match_operand:DI 1 "medium_pic_operand" "")))]
2045 "(TARGET_CM_MEDLOW || TARGET_CM_EMBMEDANY) && check_pic (1)"
2046 "sethi\t%%hi(%a1), %0")
2048 (define_insn "*sethi_di_medlow"
2049 [(set (match_operand:DI 0 "register_operand" "=r")
2050 (high:DI (match_operand:DI 1 "symbolic_operand" "")))]
2051 "TARGET_CM_MEDLOW && check_pic (1)"
2052 "sethi\t%%hi(%a1), %0")
2054 (define_insn "*losum_di_medlow"
2055 [(set (match_operand:DI 0 "register_operand" "=r")
2056 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2057 (match_operand:DI 2 "symbolic_operand" "")))]
2059 "or\t%1, %%lo(%a2), %0")
2061 (define_insn "seth44"
2062 [(set (match_operand:DI 0 "register_operand" "=r")
2063 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETH44)))]
2065 "sethi\t%%h44(%a1), %0")
2067 (define_insn "setm44"
2068 [(set (match_operand:DI 0 "register_operand" "=r")
2069 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2070 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_SETM44)))]
2072 "or\t%1, %%m44(%a2), %0")
2074 (define_insn "setl44"
2075 [(set (match_operand:DI 0 "register_operand" "=r")
2076 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2077 (match_operand:DI 2 "symbolic_operand" "")))]
2079 "or\t%1, %%l44(%a2), %0")
2081 (define_insn "sethh"
2082 [(set (match_operand:DI 0 "register_operand" "=r")
2083 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETHH)))]
2085 "sethi\t%%hh(%a1), %0")
2087 (define_insn "setlm"
2088 [(set (match_operand:DI 0 "register_operand" "=r")
2089 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETLM)))]
2091 "sethi\t%%lm(%a1), %0")
2093 (define_insn "sethm"
2094 [(set (match_operand:DI 0 "register_operand" "=r")
2095 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2096 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_EMB_SETHM)))]
2098 "or\t%1, %%hm(%a2), %0")
2100 (define_insn "setlo"
2101 [(set (match_operand:DI 0 "register_operand" "=r")
2102 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2103 (match_operand:DI 2 "symbolic_operand" "")))]
2105 "or\t%1, %%lo(%a2), %0")
2107 (define_insn "embmedany_sethi"
2108 [(set (match_operand:DI 0 "register_operand" "=r")
2109 (high:DI (unspec:DI [(match_operand:DI 1 "data_segment_operand" "")] UNSPEC_EMB_HISUM)))]
2110 "TARGET_CM_EMBMEDANY && check_pic (1)"
2111 "sethi\t%%hi(%a1), %0")
2113 (define_insn "embmedany_losum"
2114 [(set (match_operand:DI 0 "register_operand" "=r")
2115 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2116 (match_operand:DI 2 "data_segment_operand" "")))]
2117 "TARGET_CM_EMBMEDANY"
2118 "add\t%1, %%lo(%a2), %0")
2120 (define_insn "embmedany_brsum"
2121 [(set (match_operand:DI 0 "register_operand" "=r")
2122 (unspec:DI [(match_operand:DI 1 "register_operand" "r")] UNSPEC_EMB_HISUM))]
2123 "TARGET_CM_EMBMEDANY"
2126 (define_insn "embmedany_textuhi"
2127 [(set (match_operand:DI 0 "register_operand" "=r")
2128 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTUHI)))]
2129 "TARGET_CM_EMBMEDANY && check_pic (1)"
2130 "sethi\t%%uhi(%a1), %0")
2132 (define_insn "embmedany_texthi"
2133 [(set (match_operand:DI 0 "register_operand" "=r")
2134 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTHI)))]
2135 "TARGET_CM_EMBMEDANY && check_pic (1)"
2136 "sethi\t%%hi(%a1), %0")
2138 (define_insn "embmedany_textulo"
2139 [(set (match_operand:DI 0 "register_operand" "=r")
2140 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2141 (unspec:DI [(match_operand:DI 2 "text_segment_operand" "")] UNSPEC_EMB_TEXTULO)))]
2142 "TARGET_CM_EMBMEDANY"
2143 "or\t%1, %%ulo(%a2), %0")
2145 (define_insn "embmedany_textlo"
2146 [(set (match_operand:DI 0 "register_operand" "=r")
2147 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2148 (match_operand:DI 2 "text_segment_operand" "")))]
2149 "TARGET_CM_EMBMEDANY"
2150 "or\t%1, %%lo(%a2), %0")
2152 ;; Now some patterns to help reload out a bit.
2153 (define_expand "reload_indi"
2154 [(parallel [(match_operand:DI 0 "register_operand" "=r")
2155 (match_operand:DI 1 "immediate_operand" "")
2156 (match_operand:TI 2 "register_operand" "=&r")])]
2158 || TARGET_CM_EMBMEDANY)
2161 sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
2165 (define_expand "reload_outdi"
2166 [(parallel [(match_operand:DI 0 "register_operand" "=r")
2167 (match_operand:DI 1 "immediate_operand" "")
2168 (match_operand:TI 2 "register_operand" "=&r")])]
2170 || TARGET_CM_EMBMEDANY)
2173 sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
2177 ;; Split up putting CONSTs and REGs into DI regs when !arch64
2179 [(set (match_operand:DI 0 "register_operand" "")
2180 (match_operand:DI 1 "const_int_operand" ""))]
2181 "! TARGET_ARCH64 && reload_completed"
2182 [(clobber (const_int 0))]
2184 #if HOST_BITS_PER_WIDE_INT == 32
2185 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
2186 (INTVAL (operands[1]) < 0) ?
2189 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2192 unsigned int low, high;
2194 low = trunc_int_for_mode (INTVAL (operands[1]), SImode);
2195 high = trunc_int_for_mode (INTVAL (operands[1]) >> 32, SImode);
2196 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), GEN_INT (high)));
2198 /* Slick... but this trick loses if this subreg constant part
2199 can be done in one insn. */
2201 && ! SPARC_SETHI32_P (high)
2202 && ! SPARC_SIMM13_P (high))
2203 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2204 gen_highpart (SImode, operands[0])));
2206 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), GEN_INT (low)));
2212 [(set (match_operand:DI 0 "register_operand" "")
2213 (match_operand:DI 1 "const_double_operand" ""))]
2217 && ((GET_CODE (operands[0]) == REG
2218 && REGNO (operands[0]) < 32)
2219 || (GET_CODE (operands[0]) == SUBREG
2220 && GET_CODE (SUBREG_REG (operands[0])) == REG
2221 && REGNO (SUBREG_REG (operands[0])) < 32))))"
2222 [(clobber (const_int 0))]
2224 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
2225 GEN_INT (CONST_DOUBLE_HIGH (operands[1]))));
2227 /* Slick... but this trick loses if this subreg constant part
2228 can be done in one insn. */
2229 if (CONST_DOUBLE_LOW (operands[1]) == CONST_DOUBLE_HIGH (operands[1])
2230 && ! SPARC_SETHI32_P (CONST_DOUBLE_HIGH (operands[1]))
2231 && ! SPARC_SIMM13_P (CONST_DOUBLE_HIGH (operands[1])))
2233 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2234 gen_highpart (SImode, operands[0])));
2238 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2239 GEN_INT (CONST_DOUBLE_LOW (operands[1]))));
2245 [(set (match_operand:DI 0 "register_operand" "")
2246 (match_operand:DI 1 "register_operand" ""))]
2250 && ((GET_CODE (operands[0]) == REG
2251 && REGNO (operands[0]) < 32)
2252 || (GET_CODE (operands[0]) == SUBREG
2253 && GET_CODE (SUBREG_REG (operands[0])) == REG
2254 && REGNO (SUBREG_REG (operands[0])) < 32))))"
2255 [(clobber (const_int 0))]
2257 rtx set_dest = operands[0];
2258 rtx set_src = operands[1];
2262 dest1 = gen_highpart (SImode, set_dest);
2263 dest2 = gen_lowpart (SImode, set_dest);
2264 src1 = gen_highpart (SImode, set_src);
2265 src2 = gen_lowpart (SImode, set_src);
2267 /* Now emit using the real source and destination we found, swapping
2268 the order if we detect overlap. */
2269 if (reg_overlap_mentioned_p (dest1, src2))
2271 emit_insn (gen_movsi (dest2, src2));
2272 emit_insn (gen_movsi (dest1, src1));
2276 emit_insn (gen_movsi (dest1, src1));
2277 emit_insn (gen_movsi (dest2, src2));
2282 ;; Now handle the cases of memory moves from/to non-even
2283 ;; DI mode register pairs.
2285 [(set (match_operand:DI 0 "register_operand" "")
2286 (match_operand:DI 1 "memory_operand" ""))]
2289 && sparc_splitdi_legitimate (operands[0], operands[1]))"
2290 [(clobber (const_int 0))]
2292 rtx word0 = adjust_address (operands[1], SImode, 0);
2293 rtx word1 = adjust_address (operands[1], SImode, 4);
2294 rtx high_part = gen_highpart (SImode, operands[0]);
2295 rtx low_part = gen_lowpart (SImode, operands[0]);
2297 if (reg_overlap_mentioned_p (high_part, word1))
2299 emit_insn (gen_movsi (low_part, word1));
2300 emit_insn (gen_movsi (high_part, word0));
2304 emit_insn (gen_movsi (high_part, word0));
2305 emit_insn (gen_movsi (low_part, word1));
2311 [(set (match_operand:DI 0 "memory_operand" "")
2312 (match_operand:DI 1 "register_operand" ""))]
2315 && sparc_splitdi_legitimate (operands[1], operands[0]))"
2316 [(clobber (const_int 0))]
2318 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0),
2319 gen_highpart (SImode, operands[1])));
2320 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4),
2321 gen_lowpart (SImode, operands[1])));
2326 [(set (match_operand:DI 0 "memory_operand" "")
2327 (match_operand:DI 1 "const_zero_operand" ""))]
2331 && ! mem_min_alignment (operands[0], 8)))
2332 && offsettable_memref_p (operands[0])"
2333 [(clobber (const_int 0))]
2335 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0), const0_rtx));
2336 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4), const0_rtx));
2341 ;; Floating point and vector move instructions
2343 ;; We don't define V1SI because SI should work just fine.
2344 (define_mode_macro V32 [SF V2HI V4QI])
2346 ;; Yes, you guessed it right, the former movsf expander.
2347 (define_expand "mov<V32:mode>"
2348 [(set (match_operand:V32 0 "nonimmediate_operand" "")
2349 (match_operand:V32 1 "general_operand" ""))]
2350 "<V32:MODE>mode == SFmode || TARGET_VIS"
2352 if (sparc_expand_move (<V32:MODE>mode, operands))
2356 (define_insn "*movsf_insn"
2357 [(set (match_operand:V32 0 "nonimmediate_operand" "=d,f,*r,*r,*r,f,*r,m,m")
2358 (match_operand:V32 1 "input_operand" "GY,f,*rRY,Q,S,m,m,f,*rGY"))]
2360 && (register_operand (operands[0], <V32:MODE>mode)
2361 || register_or_zero_operand (operands[1], <V32:MODE>mode))"
2363 if (GET_CODE (operands[1]) == CONST_DOUBLE
2364 && (which_alternative == 2
2365 || which_alternative == 3
2366 || which_alternative == 4))
2371 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2372 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2373 operands[1] = GEN_INT (i);
2376 switch (which_alternative)
2379 return "fzeros\t%0";
2381 return "fmovs\t%1, %0";
2383 return "mov\t%1, %0";
2385 return "sethi\t%%hi(%a1), %0";
2390 return "ld\t%1, %0";
2393 return "st\t%r1, %0";
2398 [(set_attr "type" "fga,fpmove,*,*,*,fpload,load,fpstore,store")])
2400 ;; Exactly the same as above, except that all `f' cases are deleted.
2401 ;; This is necessary to prevent reload from ever trying to use a `f' reg
2404 (define_insn "*movsf_insn_no_fpu"
2405 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r,r,m")
2406 (match_operand:SF 1 "input_operand" "rR,Q,S,m,rG"))]
2408 && (register_operand (operands[0], SFmode)
2409 || register_or_zero_operand (operands[1], SFmode))"
2411 if (GET_CODE (operands[1]) == CONST_DOUBLE
2412 && (which_alternative == 0
2413 || which_alternative == 1
2414 || which_alternative == 2))
2419 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2420 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2421 operands[1] = GEN_INT (i);
2424 switch (which_alternative)
2427 return "mov\t%1, %0";
2429 return "sethi\t%%hi(%a1), %0";
2433 return "ld\t%1, %0";
2435 return "st\t%r1, %0";
2440 [(set_attr "type" "*,*,*,load,store")])
2442 ;; The following 3 patterns build SFmode constants in integer registers.
2444 (define_insn "*movsf_lo_sum"
2445 [(set (match_operand:SF 0 "register_operand" "=r")
2446 (lo_sum:SF (match_operand:SF 1 "register_operand" "r")
2447 (match_operand:SF 2 "fp_const_high_losum_operand" "S")))]
2453 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[2]);
2454 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2455 operands[2] = GEN_INT (i);
2456 return "or\t%1, %%lo(%a2), %0";
2459 (define_insn "*movsf_high"
2460 [(set (match_operand:SF 0 "register_operand" "=r")
2461 (high:SF (match_operand:SF 1 "fp_const_high_losum_operand" "S")))]
2467 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2468 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2469 operands[1] = GEN_INT (i);
2470 return "sethi\t%%hi(%1), %0";
2474 [(set (match_operand:SF 0 "register_operand" "")
2475 (match_operand:SF 1 "fp_const_high_losum_operand" ""))]
2476 "REG_P (operands[0]) && REGNO (operands[0]) < 32"
2477 [(set (match_dup 0) (high:SF (match_dup 1)))
2478 (set (match_dup 0) (lo_sum:SF (match_dup 0) (match_dup 1)))])
2480 (define_mode_macro V64 [DF V2SI V4HI V8QI])
2482 ;; Yes, you again guessed it right, the former movdf expander.
2483 (define_expand "mov<V64:mode>"
2484 [(set (match_operand:V64 0 "nonimmediate_operand" "")
2485 (match_operand:V64 1 "general_operand" ""))]
2486 "<V64:MODE>mode == DFmode || TARGET_VIS"
2488 if (sparc_expand_move (<V64:MODE>mode, operands))
2492 ;; Be careful, fmovd does not exist when !v9.
2493 (define_insn "*movdf_insn_sp32"
2494 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,W,U,T,o,e,*r,o,e,o")
2495 (match_operand:DF 1 "input_operand" "W#F,e,T,U,G,e,*rFo,*r,o#F,e"))]
2498 && (register_operand (operands[0], DFmode)
2499 || register_or_zero_operand (operands[1], DFmode))"
2511 [(set_attr "type" "fpload,fpstore,load,store,*,*,*,*,*,*")
2512 (set_attr "length" "*,*,*,*,2,2,2,2,2,2")])
2514 (define_insn "*movdf_insn_sp32_no_fpu"
2515 [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,o,r,o")
2516 (match_operand:DF 1 "input_operand" "T,U,G,ro,r"))]
2519 && (register_operand (operands[0], DFmode)
2520 || register_or_zero_operand (operands[1], DFmode))"
2527 [(set_attr "type" "load,store,*,*,*")
2528 (set_attr "length" "*,*,2,2,2")])
2530 ;; We have available v9 double floats but not 64-bit integer registers.
2531 (define_insn "*movdf_insn_sp32_v9"
2532 [(set (match_operand:V64 0 "nonimmediate_operand" "=b,e,e,T,W,U,T,f,*r,o")
2533 (match_operand:V64 1 "input_operand" "GY,e,W#F,GY,e,T,U,o#F,*roGYF,*rGYf"))]
2537 && (register_operand (operands[0], <V64:MODE>mode)
2538 || register_or_zero_operand (operands[1], <V64:MODE>mode))"
2550 [(set_attr "type" "fga,fpmove,load,store,store,load,store,*,*,*")
2551 (set_attr "length" "*,*,*,*,*,*,*,2,2,2")
2552 (set_attr "fptype" "double,double,*,*,*,*,*,*,*,*")])
2554 (define_insn "*movdf_insn_sp32_v9_no_fpu"
2555 [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,T,r,o")
2556 (match_operand:DF 1 "input_operand" "T,U,G,ro,rG"))]
2560 && (register_operand (operands[0], DFmode)
2561 || register_or_zero_operand (operands[1], DFmode))"
2568 [(set_attr "type" "load,store,store,*,*")
2569 (set_attr "length" "*,*,*,2,2")])
2571 ;; We have available both v9 double floats and 64-bit integer registers.
2572 (define_insn "*movdf_insn_sp64"
2573 [(set (match_operand:V64 0 "nonimmediate_operand" "=b,e,e,W,*r,*r,m,*r")
2574 (match_operand:V64 1 "input_operand" "GY,e,W#F,e,*rGY,m,*rGY,F"))]
2577 && (register_operand (operands[0], <V64:MODE>mode)
2578 || register_or_zero_operand (operands[1], <V64:MODE>mode))"
2588 [(set_attr "type" "fga,fpmove,load,store,*,load,store,*")
2589 (set_attr "length" "*,*,*,*,*,*,*,2")
2590 (set_attr "fptype" "double,double,*,*,*,*,*,*")])
2592 (define_insn "*movdf_insn_sp64_no_fpu"
2593 [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m")
2594 (match_operand:DF 1 "input_operand" "r,m,rG"))]
2597 && (register_operand (operands[0], DFmode)
2598 || register_or_zero_operand (operands[1], DFmode))"
2603 [(set_attr "type" "*,load,store")])
2605 ;; This pattern build DFmode constants in integer registers.
2607 [(set (match_operand:DF 0 "register_operand" "")
2608 (match_operand:DF 1 "const_double_operand" ""))]
2610 && (GET_CODE (operands[0]) == REG
2611 && REGNO (operands[0]) < 32)
2612 && ! const_zero_operand(operands[1], DFmode)
2613 && reload_completed"
2614 [(clobber (const_int 0))]
2619 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2620 REAL_VALUE_TO_TARGET_DOUBLE (r, l);
2621 operands[0] = gen_rtx_raw_REG (DImode, REGNO (operands[0]));
2625 #if HOST_BITS_PER_WIDE_INT == 32
2630 val = ((HOST_WIDE_INT)(unsigned long)l[1] |
2631 ((HOST_WIDE_INT)(unsigned long)l[0] << 32));
2632 emit_insn (gen_movdi (operands[0], gen_int_mode (val, DImode)));
2637 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
2638 gen_int_mode (l[0], SImode)));
2640 /* Slick... but this trick loses if this subreg constant part
2641 can be done in one insn. */
2643 && ! SPARC_SETHI32_P (l[0])
2644 && ! SPARC_SIMM13_P (l[0]))
2646 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2647 gen_highpart (SImode, operands[0])));
2651 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2652 gen_int_mode (l[1], SImode)));
2658 ;; Ok, now the splits to handle all the multi insn and
2659 ;; mis-aligned memory address cases.
2660 ;; In these splits please take note that we must be
2661 ;; careful when V9 but not ARCH64 because the integer
2662 ;; register DFmode cases must be handled.
2664 [(set (match_operand:V64 0 "register_operand" "")
2665 (match_operand:V64 1 "register_operand" ""))]
2668 && ((GET_CODE (operands[0]) == REG
2669 && REGNO (operands[0]) < 32)
2670 || (GET_CODE (operands[0]) == SUBREG
2671 && GET_CODE (SUBREG_REG (operands[0])) == REG
2672 && REGNO (SUBREG_REG (operands[0])) < 32))))
2673 && reload_completed"
2674 [(clobber (const_int 0))]
2676 rtx set_dest = operands[0];
2677 rtx set_src = operands[1];
2680 enum machine_mode half_mode;
2682 /* We can be expanded for DFmode or integral vector modes. */
2683 if (<V64:MODE>mode == DFmode)
2688 dest1 = gen_highpart (half_mode, set_dest);
2689 dest2 = gen_lowpart (half_mode, set_dest);
2690 src1 = gen_highpart (half_mode, set_src);
2691 src2 = gen_lowpart (half_mode, set_src);
2693 /* Now emit using the real source and destination we found, swapping
2694 the order if we detect overlap. */
2695 if (reg_overlap_mentioned_p (dest1, src2))
2697 emit_move_insn_1 (dest2, src2);
2698 emit_move_insn_1 (dest1, src1);
2702 emit_move_insn_1 (dest1, src1);
2703 emit_move_insn_1 (dest2, src2);
2709 [(set (match_operand:V64 0 "register_operand" "")
2710 (match_operand:V64 1 "memory_operand" ""))]
2713 && (((REGNO (operands[0]) % 2) != 0)
2714 || ! mem_min_alignment (operands[1], 8))
2715 && offsettable_memref_p (operands[1])"
2716 [(clobber (const_int 0))]
2718 enum machine_mode half_mode;
2721 /* We can be expanded for DFmode or integral vector modes. */
2722 if (<V64:MODE>mode == DFmode)
2727 word0 = adjust_address (operands[1], half_mode, 0);
2728 word1 = adjust_address (operands[1], half_mode, 4);
2730 if (reg_overlap_mentioned_p (gen_highpart (half_mode, operands[0]), word1))
2732 emit_move_insn_1 (gen_lowpart (half_mode, operands[0]), word1);
2733 emit_move_insn_1 (gen_highpart (half_mode, operands[0]), word0);
2737 emit_move_insn_1 (gen_highpart (half_mode, operands[0]), word0);
2738 emit_move_insn_1 (gen_lowpart (half_mode, operands[0]), word1);
2744 [(set (match_operand:V64 0 "memory_operand" "")
2745 (match_operand:V64 1 "register_operand" ""))]
2748 && (((REGNO (operands[1]) % 2) != 0)
2749 || ! mem_min_alignment (operands[0], 8))
2750 && offsettable_memref_p (operands[0])"
2751 [(clobber (const_int 0))]
2753 enum machine_mode half_mode;
2756 /* We can be expanded for DFmode or integral vector modes. */
2757 if (<V64:MODE>mode == DFmode)
2762 word0 = adjust_address (operands[0], half_mode, 0);
2763 word1 = adjust_address (operands[0], half_mode, 4);
2765 emit_move_insn_1 (word0, gen_highpart (half_mode, operands[1]));
2766 emit_move_insn_1 (word1, gen_lowpart (half_mode, operands[1]));
2771 [(set (match_operand:V64 0 "memory_operand" "")
2772 (match_operand:V64 1 "const_zero_operand" ""))]
2776 && ! mem_min_alignment (operands[0], 8)))
2777 && offsettable_memref_p (operands[0])"
2778 [(clobber (const_int 0))]
2780 enum machine_mode half_mode;
2783 /* We can be expanded for DFmode or integral vector modes. */
2784 if (<V64:MODE>mode == DFmode)
2789 dest1 = adjust_address (operands[0], half_mode, 0);
2790 dest2 = adjust_address (operands[0], half_mode, 4);
2792 emit_move_insn_1 (dest1, CONST0_RTX (half_mode));
2793 emit_move_insn_1 (dest2, CONST0_RTX (half_mode));
2798 [(set (match_operand:V64 0 "register_operand" "")
2799 (match_operand:V64 1 "const_zero_operand" ""))]
2802 && ((GET_CODE (operands[0]) == REG
2803 && REGNO (operands[0]) < 32)
2804 || (GET_CODE (operands[0]) == SUBREG
2805 && GET_CODE (SUBREG_REG (operands[0])) == REG
2806 && REGNO (SUBREG_REG (operands[0])) < 32))"
2807 [(clobber (const_int 0))]
2809 enum machine_mode half_mode;
2810 rtx set_dest = operands[0];
2813 /* We can be expanded for DFmode or integral vector modes. */
2814 if (<V64:MODE>mode == DFmode)
2819 dest1 = gen_highpart (half_mode, set_dest);
2820 dest2 = gen_lowpart (half_mode, set_dest);
2821 emit_move_insn_1 (dest1, CONST0_RTX (half_mode));
2822 emit_move_insn_1 (dest2, CONST0_RTX (half_mode));
2826 (define_expand "movtf"
2827 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2828 (match_operand:TF 1 "general_operand" ""))]
2831 if (sparc_expand_move (TFmode, operands))
2835 (define_insn "*movtf_insn_sp32"
2836 [(set (match_operand:TF 0 "nonimmediate_operand" "=b,e,o,U,r")
2837 (match_operand:TF 1 "input_operand" "G,oe,GeUr,o,roG"))]
2840 && (register_operand (operands[0], TFmode)
2841 || register_or_zero_operand (operands[1], TFmode))"
2843 [(set_attr "length" "4")])
2845 ;; Exactly the same as above, except that all `e' cases are deleted.
2846 ;; This is necessary to prevent reload from ever trying to use a `e' reg
2849 (define_insn "*movtf_insn_sp32_no_fpu"
2850 [(set (match_operand:TF 0 "nonimmediate_operand" "=o,U,o,r,o")
2851 (match_operand:TF 1 "input_operand" "G,o,U,roG,r"))]
2854 && (register_operand (operands[0], TFmode)
2855 || register_or_zero_operand (operands[1], TFmode))"
2857 [(set_attr "length" "4")])
2859 (define_insn "*movtf_insn_sp64"
2860 [(set (match_operand:TF 0 "nonimmediate_operand" "=b,e,o,r")
2861 (match_operand:TF 1 "input_operand" "G,oe,Ger,roG"))]
2864 && ! TARGET_HARD_QUAD
2865 && (register_operand (operands[0], TFmode)
2866 || register_or_zero_operand (operands[1], TFmode))"
2868 [(set_attr "length" "2")])
2870 (define_insn "*movtf_insn_sp64_hq"
2871 [(set (match_operand:TF 0 "nonimmediate_operand" "=b,e,e,m,o,r")
2872 (match_operand:TF 1 "input_operand" "G,e,m,e,rG,roG"))]
2876 && (register_operand (operands[0], TFmode)
2877 || register_or_zero_operand (operands[1], TFmode))"
2885 [(set_attr "type" "*,fpmove,fpload,fpstore,*,*")
2886 (set_attr "length" "2,*,*,*,2,2")])
2888 (define_insn "*movtf_insn_sp64_no_fpu"
2889 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o")
2890 (match_operand:TF 1 "input_operand" "orG,rG"))]
2893 && (register_operand (operands[0], TFmode)
2894 || register_or_zero_operand (operands[1], TFmode))"
2896 [(set_attr "length" "2")])
2898 ;; Now all the splits to handle multi-insn TF mode moves.
2900 [(set (match_operand:TF 0 "register_operand" "")
2901 (match_operand:TF 1 "register_operand" ""))]
2905 && ! TARGET_HARD_QUAD)
2906 || ! fp_register_operand (operands[0], TFmode))"
2907 [(clobber (const_int 0))]
2909 rtx set_dest = operands[0];
2910 rtx set_src = operands[1];
2914 dest1 = gen_df_reg (set_dest, 0);
2915 dest2 = gen_df_reg (set_dest, 1);
2916 src1 = gen_df_reg (set_src, 0);
2917 src2 = gen_df_reg (set_src, 1);
2919 /* Now emit using the real source and destination we found, swapping
2920 the order if we detect overlap. */
2921 if (reg_overlap_mentioned_p (dest1, src2))
2923 emit_insn (gen_movdf (dest2, src2));
2924 emit_insn (gen_movdf (dest1, src1));
2928 emit_insn (gen_movdf (dest1, src1));
2929 emit_insn (gen_movdf (dest2, src2));
2935 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2936 (match_operand:TF 1 "const_zero_operand" ""))]
2938 [(clobber (const_int 0))]
2940 rtx set_dest = operands[0];
2943 switch (GET_CODE (set_dest))
2946 dest1 = gen_df_reg (set_dest, 0);
2947 dest2 = gen_df_reg (set_dest, 1);
2950 dest1 = adjust_address (set_dest, DFmode, 0);
2951 dest2 = adjust_address (set_dest, DFmode, 8);
2957 emit_insn (gen_movdf (dest1, CONST0_RTX (DFmode)));
2958 emit_insn (gen_movdf (dest2, CONST0_RTX (DFmode)));
2963 [(set (match_operand:TF 0 "register_operand" "")
2964 (match_operand:TF 1 "memory_operand" ""))]
2966 && offsettable_memref_p (operands[1])
2968 || ! TARGET_HARD_QUAD
2969 || ! fp_register_operand (operands[0], TFmode)))"
2970 [(clobber (const_int 0))]
2972 rtx word0 = adjust_address (operands[1], DFmode, 0);
2973 rtx word1 = adjust_address (operands[1], DFmode, 8);
2974 rtx set_dest, dest1, dest2;
2976 set_dest = operands[0];
2978 dest1 = gen_df_reg (set_dest, 0);
2979 dest2 = gen_df_reg (set_dest, 1);
2981 /* Now output, ordering such that we don't clobber any registers
2982 mentioned in the address. */
2983 if (reg_overlap_mentioned_p (dest1, word1))
2986 emit_insn (gen_movdf (dest2, word1));
2987 emit_insn (gen_movdf (dest1, word0));
2991 emit_insn (gen_movdf (dest1, word0));
2992 emit_insn (gen_movdf (dest2, word1));
2998 [(set (match_operand:TF 0 "memory_operand" "")
2999 (match_operand:TF 1 "register_operand" ""))]
3001 && offsettable_memref_p (operands[0])
3003 || ! TARGET_HARD_QUAD
3004 || ! fp_register_operand (operands[1], TFmode)))"
3005 [(clobber (const_int 0))]
3007 rtx set_src = operands[1];
3009 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 0),
3010 gen_df_reg (set_src, 0)));
3011 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 8),
3012 gen_df_reg (set_src, 1)));
3017 ;; SPARC-V9 conditional move instructions.
3019 ;; We can handle larger constants here for some flavors, but for now we keep
3020 ;; it simple and only allow those constants supported by all flavors.
3021 ;; Note that emit_conditional_move canonicalizes operands 2,3 so that operand
3022 ;; 3 contains the constant if one is present, but we handle either for
3023 ;; generality (sparc.c puts a constant in operand 2).
3025 (define_expand "movqicc"
3026 [(set (match_operand:QI 0 "register_operand" "")
3027 (if_then_else:QI (match_operand 1 "comparison_operator" "")
3028 (match_operand:QI 2 "arith10_operand" "")
3029 (match_operand:QI 3 "arith10_operand" "")))]
3032 enum rtx_code code = GET_CODE (operands[1]);
3034 if (GET_MODE (sparc_compare_op0) == DImode
3038 if (sparc_compare_op1 == const0_rtx
3039 && GET_CODE (sparc_compare_op0) == REG
3040 && GET_MODE (sparc_compare_op0) == DImode
3041 && v9_regcmp_p (code))
3043 operands[1] = gen_rtx_fmt_ee (code, DImode,
3044 sparc_compare_op0, sparc_compare_op1);
3048 rtx cc_reg = gen_compare_reg (code);
3049 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3053 (define_expand "movhicc"
3054 [(set (match_operand:HI 0 "register_operand" "")
3055 (if_then_else:HI (match_operand 1 "comparison_operator" "")
3056 (match_operand:HI 2 "arith10_operand" "")
3057 (match_operand:HI 3 "arith10_operand" "")))]
3060 enum rtx_code code = GET_CODE (operands[1]);
3062 if (GET_MODE (sparc_compare_op0) == DImode
3066 if (sparc_compare_op1 == const0_rtx
3067 && GET_CODE (sparc_compare_op0) == REG
3068 && GET_MODE (sparc_compare_op0) == DImode
3069 && v9_regcmp_p (code))
3071 operands[1] = gen_rtx_fmt_ee (code, DImode,
3072 sparc_compare_op0, sparc_compare_op1);
3076 rtx cc_reg = gen_compare_reg (code);
3077 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3081 (define_expand "movsicc"
3082 [(set (match_operand:SI 0 "register_operand" "")
3083 (if_then_else:SI (match_operand 1 "comparison_operator" "")
3084 (match_operand:SI 2 "arith10_operand" "")
3085 (match_operand:SI 3 "arith10_operand" "")))]
3088 enum rtx_code code = GET_CODE (operands[1]);
3089 enum machine_mode op0_mode = GET_MODE (sparc_compare_op0);
3091 if (sparc_compare_op1 == const0_rtx
3092 && GET_CODE (sparc_compare_op0) == REG
3093 && (TARGET_ARCH64 && op0_mode == DImode && v9_regcmp_p (code)))
3095 operands[1] = gen_rtx_fmt_ee (code, op0_mode,
3096 sparc_compare_op0, sparc_compare_op1);
3100 rtx cc_reg = gen_compare_reg (code);
3101 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg),
3102 cc_reg, const0_rtx);
3106 (define_expand "movdicc"
3107 [(set (match_operand:DI 0 "register_operand" "")
3108 (if_then_else:DI (match_operand 1 "comparison_operator" "")
3109 (match_operand:DI 2 "arith10_operand" "")
3110 (match_operand:DI 3 "arith10_operand" "")))]
3113 enum rtx_code code = GET_CODE (operands[1]);
3115 if (sparc_compare_op1 == const0_rtx
3116 && GET_CODE (sparc_compare_op0) == REG
3117 && GET_MODE (sparc_compare_op0) == DImode
3118 && v9_regcmp_p (code))
3120 operands[1] = gen_rtx_fmt_ee (code, DImode,
3121 sparc_compare_op0, sparc_compare_op1);
3125 rtx cc_reg = gen_compare_reg (code);
3126 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg),
3127 cc_reg, const0_rtx);
3131 (define_expand "movsfcc"
3132 [(set (match_operand:SF 0 "register_operand" "")
3133 (if_then_else:SF (match_operand 1 "comparison_operator" "")
3134 (match_operand:SF 2 "register_operand" "")
3135 (match_operand:SF 3 "register_operand" "")))]
3136 "TARGET_V9 && TARGET_FPU"
3138 enum rtx_code code = GET_CODE (operands[1]);
3140 if (GET_MODE (sparc_compare_op0) == DImode
3144 if (sparc_compare_op1 == const0_rtx
3145 && GET_CODE (sparc_compare_op0) == REG
3146 && GET_MODE (sparc_compare_op0) == DImode
3147 && v9_regcmp_p (code))
3149 operands[1] = gen_rtx_fmt_ee (code, DImode,
3150 sparc_compare_op0, sparc_compare_op1);
3154 rtx cc_reg = gen_compare_reg (code);
3155 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3159 (define_expand "movdfcc"
3160 [(set (match_operand:DF 0 "register_operand" "")
3161 (if_then_else:DF (match_operand 1 "comparison_operator" "")
3162 (match_operand:DF 2 "register_operand" "")
3163 (match_operand:DF 3 "register_operand" "")))]
3164 "TARGET_V9 && TARGET_FPU"
3166 enum rtx_code code = GET_CODE (operands[1]);
3168 if (GET_MODE (sparc_compare_op0) == DImode
3172 if (sparc_compare_op1 == const0_rtx
3173 && GET_CODE (sparc_compare_op0) == REG
3174 && GET_MODE (sparc_compare_op0) == DImode
3175 && v9_regcmp_p (code))
3177 operands[1] = gen_rtx_fmt_ee (code, DImode,
3178 sparc_compare_op0, sparc_compare_op1);
3182 rtx cc_reg = gen_compare_reg (code);
3183 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3187 (define_expand "movtfcc"
3188 [(set (match_operand:TF 0 "register_operand" "")
3189 (if_then_else:TF (match_operand 1 "comparison_operator" "")
3190 (match_operand:TF 2 "register_operand" "")
3191 (match_operand:TF 3 "register_operand" "")))]
3192 "TARGET_V9 && TARGET_FPU"
3194 enum rtx_code code = GET_CODE (operands[1]);
3196 if (GET_MODE (sparc_compare_op0) == DImode
3200 if (sparc_compare_op1 == const0_rtx
3201 && GET_CODE (sparc_compare_op0) == REG
3202 && GET_MODE (sparc_compare_op0) == DImode
3203 && v9_regcmp_p (code))
3205 operands[1] = gen_rtx_fmt_ee (code, DImode,
3206 sparc_compare_op0, sparc_compare_op1);
3210 rtx cc_reg = gen_compare_reg (code);
3211 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3215 ;; Conditional move define_insns.
3217 (define_insn "*movqi_cc_sp64"
3218 [(set (match_operand:QI 0 "register_operand" "=r,r")
3219 (if_then_else:QI (match_operator 1 "comparison_operator"
3220 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
3222 (match_operand:QI 3 "arith11_operand" "rL,0")
3223 (match_operand:QI 4 "arith11_operand" "0,rL")))]
3227 mov%c1\t%x2, %4, %0"
3228 [(set_attr "type" "cmove")])
3230 (define_insn "*movhi_cc_sp64"
3231 [(set (match_operand:HI 0 "register_operand" "=r,r")
3232 (if_then_else:HI (match_operator 1 "comparison_operator"
3233 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
3235 (match_operand:HI 3 "arith11_operand" "rL,0")
3236 (match_operand:HI 4 "arith11_operand" "0,rL")))]
3240 mov%c1\t%x2, %4, %0"
3241 [(set_attr "type" "cmove")])
3243 (define_insn "*movsi_cc_sp64"
3244 [(set (match_operand:SI 0 "register_operand" "=r,r")
3245 (if_then_else:SI (match_operator 1 "comparison_operator"
3246 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
3248 (match_operand:SI 3 "arith11_operand" "rL,0")
3249 (match_operand:SI 4 "arith11_operand" "0,rL")))]
3253 mov%c1\t%x2, %4, %0"
3254 [(set_attr "type" "cmove")])
3256 (define_insn "*movdi_cc_sp64"
3257 [(set (match_operand:DI 0 "register_operand" "=r,r")
3258 (if_then_else:DI (match_operator 1 "comparison_operator"
3259 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
3261 (match_operand:DI 3 "arith11_operand" "rL,0")
3262 (match_operand:DI 4 "arith11_operand" "0,rL")))]
3266 mov%c1\t%x2, %4, %0"
3267 [(set_attr "type" "cmove")])
3269 (define_insn "*movdi_cc_sp64_trunc"
3270 [(set (match_operand:SI 0 "register_operand" "=r,r")
3271 (if_then_else:SI (match_operator 1 "comparison_operator"
3272 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
3274 (match_operand:SI 3 "arith11_operand" "rL,0")
3275 (match_operand:SI 4 "arith11_operand" "0,rL")))]
3279 mov%c1\t%x2, %4, %0"
3280 [(set_attr "type" "cmove")])
3282 (define_insn "*movsf_cc_sp64"
3283 [(set (match_operand:SF 0 "register_operand" "=f,f")
3284 (if_then_else:SF (match_operator 1 "comparison_operator"
3285 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
3287 (match_operand:SF 3 "register_operand" "f,0")
3288 (match_operand:SF 4 "register_operand" "0,f")))]
3289 "TARGET_V9 && TARGET_FPU"
3291 fmovs%C1\t%x2, %3, %0
3292 fmovs%c1\t%x2, %4, %0"
3293 [(set_attr "type" "fpcmove")])
3295 (define_insn "movdf_cc_sp64"
3296 [(set (match_operand:DF 0 "register_operand" "=e,e")
3297 (if_then_else:DF (match_operator 1 "comparison_operator"
3298 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
3300 (match_operand:DF 3 "register_operand" "e,0")
3301 (match_operand:DF 4 "register_operand" "0,e")))]
3302 "TARGET_V9 && TARGET_FPU"
3304 fmovd%C1\t%x2, %3, %0
3305 fmovd%c1\t%x2, %4, %0"
3306 [(set_attr "type" "fpcmove")
3307 (set_attr "fptype" "double")])
3309 (define_insn "*movtf_cc_hq_sp64"
3310 [(set (match_operand:TF 0 "register_operand" "=e,e")
3311 (if_then_else:TF (match_operator 1 "comparison_operator"
3312 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
3314 (match_operand:TF 3 "register_operand" "e,0")
3315 (match_operand:TF 4 "register_operand" "0,e")))]
3316 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
3318 fmovq%C1\t%x2, %3, %0
3319 fmovq%c1\t%x2, %4, %0"
3320 [(set_attr "type" "fpcmove")])
3322 (define_insn_and_split "*movtf_cc_sp64"
3323 [(set (match_operand:TF 0 "register_operand" "=e,e")
3324 (if_then_else:TF (match_operator 1 "comparison_operator"
3325 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
3327 (match_operand:TF 3 "register_operand" "e,0")
3328 (match_operand:TF 4 "register_operand" "0,e")))]
3329 "TARGET_V9 && TARGET_FPU && !TARGET_HARD_QUAD"
3331 "&& reload_completed"
3332 [(clobber (const_int 0))]
3334 rtx set_dest = operands[0];
3335 rtx set_srca = operands[3];
3336 rtx set_srcb = operands[4];
3337 int third = rtx_equal_p (set_dest, set_srca);
3339 rtx srca1, srca2, srcb1, srcb2;
3341 dest1 = gen_df_reg (set_dest, 0);
3342 dest2 = gen_df_reg (set_dest, 1);
3343 srca1 = gen_df_reg (set_srca, 0);
3344 srca2 = gen_df_reg (set_srca, 1);
3345 srcb1 = gen_df_reg (set_srcb, 0);
3346 srcb2 = gen_df_reg (set_srcb, 1);
3348 /* Now emit using the real source and destination we found, swapping
3349 the order if we detect overlap. */
3350 if ((third && reg_overlap_mentioned_p (dest1, srcb2))
3351 || (!third && reg_overlap_mentioned_p (dest1, srca2)))
3353 emit_insn (gen_movdf_cc_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
3354 emit_insn (gen_movdf_cc_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
3358 emit_insn (gen_movdf_cc_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
3359 emit_insn (gen_movdf_cc_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
3363 [(set_attr "length" "2")])
3365 (define_insn "*movqi_cc_reg_sp64"
3366 [(set (match_operand:QI 0 "register_operand" "=r,r")
3367 (if_then_else:QI (match_operator 1 "v9_register_compare_operator"
3368 [(match_operand:DI 2 "register_operand" "r,r")
3370 (match_operand:QI 3 "arith10_operand" "rM,0")
3371 (match_operand:QI 4 "arith10_operand" "0,rM")))]
3374 movr%D1\t%2, %r3, %0
3375 movr%d1\t%2, %r4, %0"
3376 [(set_attr "type" "cmove")])
3378 (define_insn "*movhi_cc_reg_sp64"
3379 [(set (match_operand:HI 0 "register_operand" "=r,r")
3380 (if_then_else:HI (match_operator 1 "v9_register_compare_operator"
3381 [(match_operand:DI 2 "register_operand" "r,r")
3383 (match_operand:HI 3 "arith10_operand" "rM,0")
3384 (match_operand:HI 4 "arith10_operand" "0,rM")))]
3387 movr%D1\t%2, %r3, %0
3388 movr%d1\t%2, %r4, %0"
3389 [(set_attr "type" "cmove")])
3391 (define_insn "*movsi_cc_reg_sp64"
3392 [(set (match_operand:SI 0 "register_operand" "=r,r")
3393 (if_then_else:SI (match_operator 1 "v9_register_compare_operator"
3394 [(match_operand:DI 2 "register_operand" "r,r")
3396 (match_operand:SI 3 "arith10_operand" "rM,0")
3397 (match_operand:SI 4 "arith10_operand" "0,rM")))]
3400 movr%D1\t%2, %r3, %0
3401 movr%d1\t%2, %r4, %0"
3402 [(set_attr "type" "cmove")])
3404 (define_insn "*movdi_cc_reg_sp64"
3405 [(set (match_operand:DI 0 "register_operand" "=r,r")
3406 (if_then_else:DI (match_operator 1 "v9_register_compare_operator"
3407 [(match_operand:DI 2 "register_operand" "r,r")
3409 (match_operand:DI 3 "arith10_operand" "rM,0")
3410 (match_operand:DI 4 "arith10_operand" "0,rM")))]
3413 movr%D1\t%2, %r3, %0
3414 movr%d1\t%2, %r4, %0"
3415 [(set_attr "type" "cmove")])
3417 (define_insn "*movsf_cc_reg_sp64"
3418 [(set (match_operand:SF 0 "register_operand" "=f,f")
3419 (if_then_else:SF (match_operator 1 "v9_register_compare_operator"
3420 [(match_operand:DI 2 "register_operand" "r,r")
3422 (match_operand:SF 3 "register_operand" "f,0")
3423 (match_operand:SF 4 "register_operand" "0,f")))]
3424 "TARGET_ARCH64 && TARGET_FPU"
3426 fmovrs%D1\t%2, %3, %0
3427 fmovrs%d1\t%2, %4, %0"
3428 [(set_attr "type" "fpcrmove")])
3430 (define_insn "movdf_cc_reg_sp64"
3431 [(set (match_operand:DF 0 "register_operand" "=e,e")
3432 (if_then_else:DF (match_operator 1 "v9_register_compare_operator"
3433 [(match_operand:DI 2 "register_operand" "r,r")
3435 (match_operand:DF 3 "register_operand" "e,0")
3436 (match_operand:DF 4 "register_operand" "0,e")))]
3437 "TARGET_ARCH64 && TARGET_FPU"
3439 fmovrd%D1\t%2, %3, %0
3440 fmovrd%d1\t%2, %4, %0"
3441 [(set_attr "type" "fpcrmove")
3442 (set_attr "fptype" "double")])
3444 (define_insn "*movtf_cc_reg_hq_sp64"
3445 [(set (match_operand:TF 0 "register_operand" "=e,e")
3446 (if_then_else:TF (match_operator 1 "v9_register_compare_operator"
3447 [(match_operand:DI 2 "register_operand" "r,r")
3449 (match_operand:TF 3 "register_operand" "e,0")
3450 (match_operand:TF 4 "register_operand" "0,e")))]
3451 "TARGET_ARCH64 && TARGET_FPU && TARGET_HARD_QUAD"
3453 fmovrq%D1\t%2, %3, %0
3454 fmovrq%d1\t%2, %4, %0"
3455 [(set_attr "type" "fpcrmove")])
3457 (define_insn_and_split "*movtf_cc_reg_sp64"
3458 [(set (match_operand:TF 0 "register_operand" "=e,e")
3459 (if_then_else:TF (match_operator 1 "v9_register_compare_operator"
3460 [(match_operand:DI 2 "register_operand" "r,r")
3462 (match_operand:TF 3 "register_operand" "e,0")
3463 (match_operand:TF 4 "register_operand" "0,e")))]
3464 "TARGET_ARCH64 && TARGET_FPU && ! TARGET_HARD_QUAD"
3466 "&& reload_completed"
3467 [(clobber (const_int 0))]
3469 rtx set_dest = operands[0];
3470 rtx set_srca = operands[3];
3471 rtx set_srcb = operands[4];
3472 int third = rtx_equal_p (set_dest, set_srca);
3474 rtx srca1, srca2, srcb1, srcb2;
3476 dest1 = gen_df_reg (set_dest, 0);
3477 dest2 = gen_df_reg (set_dest, 1);
3478 srca1 = gen_df_reg (set_srca, 0);
3479 srca2 = gen_df_reg (set_srca, 1);
3480 srcb1 = gen_df_reg (set_srcb, 0);
3481 srcb2 = gen_df_reg (set_srcb, 1);
3483 /* Now emit using the real source and destination we found, swapping
3484 the order if we detect overlap. */
3485 if ((third && reg_overlap_mentioned_p (dest1, srcb2))
3486 || (!third && reg_overlap_mentioned_p (dest1, srca2)))
3488 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
3489 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
3493 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
3494 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
3498 [(set_attr "length" "2")])
3501 ;; Zero-extension instructions
3503 ;; These patterns originally accepted general_operands, however, slightly
3504 ;; better code is generated by only accepting register_operands, and then
3505 ;; letting combine generate the ldu[hb] insns.
3507 (define_expand "zero_extendhisi2"
3508 [(set (match_operand:SI 0 "register_operand" "")
3509 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
3512 rtx temp = gen_reg_rtx (SImode);
3513 rtx shift_16 = GEN_INT (16);
3514 int op1_subbyte = 0;
3516 if (GET_CODE (operand1) == SUBREG)
3518 op1_subbyte = SUBREG_BYTE (operand1);
3519 op1_subbyte /= GET_MODE_SIZE (SImode);
3520 op1_subbyte *= GET_MODE_SIZE (SImode);
3521 operand1 = XEXP (operand1, 0);
3524 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3526 emit_insn (gen_lshrsi3 (operand0, temp, shift_16));
3530 (define_insn "*zero_extendhisi2_insn"
3531 [(set (match_operand:SI 0 "register_operand" "=r")
3532 (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
3535 [(set_attr "type" "load")
3536 (set_attr "us3load_type" "3cycle")])
3538 (define_expand "zero_extendqihi2"
3539 [(set (match_operand:HI 0 "register_operand" "")
3540 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
3544 (define_insn "*zero_extendqihi2_insn"
3545 [(set (match_operand:HI 0 "register_operand" "=r,r")
3546 (zero_extend:HI (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_extendqisi2"
3555 [(set (match_operand:SI 0 "register_operand" "")
3556 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
3560 (define_insn "*zero_extendqisi2_insn"
3561 [(set (match_operand:SI 0 "register_operand" "=r,r")
3562 (zero_extend:SI (match_operand:QI 1 "input_operand" "r,m")))]
3563 "GET_CODE (operands[1]) != CONST_INT"
3567 [(set_attr "type" "*,load")
3568 (set_attr "us3load_type" "*,3cycle")])
3570 (define_expand "zero_extendqidi2"
3571 [(set (match_operand:DI 0 "register_operand" "")
3572 (zero_extend:DI (match_operand:QI 1 "register_operand" "")))]
3576 (define_insn "*zero_extendqidi2_insn"
3577 [(set (match_operand:DI 0 "register_operand" "=r,r")
3578 (zero_extend:DI (match_operand:QI 1 "input_operand" "r,m")))]
3579 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
3583 [(set_attr "type" "*,load")
3584 (set_attr "us3load_type" "*,3cycle")])
3586 (define_expand "zero_extendhidi2"
3587 [(set (match_operand:DI 0 "register_operand" "")
3588 (zero_extend:DI (match_operand:HI 1 "register_operand" "")))]
3591 rtx temp = gen_reg_rtx (DImode);
3592 rtx shift_48 = GEN_INT (48);
3593 int op1_subbyte = 0;
3595 if (GET_CODE (operand1) == SUBREG)
3597 op1_subbyte = SUBREG_BYTE (operand1);
3598 op1_subbyte /= GET_MODE_SIZE (DImode);
3599 op1_subbyte *= GET_MODE_SIZE (DImode);
3600 operand1 = XEXP (operand1, 0);
3603 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
3605 emit_insn (gen_lshrdi3 (operand0, temp, shift_48));
3609 (define_insn "*zero_extendhidi2_insn"
3610 [(set (match_operand:DI 0 "register_operand" "=r")
3611 (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
3614 [(set_attr "type" "load")
3615 (set_attr "us3load_type" "3cycle")])
3617 ;; ??? Write truncdisi pattern using sra?
3619 (define_expand "zero_extendsidi2"
3620 [(set (match_operand:DI 0 "register_operand" "")
3621 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
3625 (define_insn "*zero_extendsidi2_insn_sp64"
3626 [(set (match_operand:DI 0 "register_operand" "=r,r")
3627 (zero_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
3628 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
3632 [(set_attr "type" "shift,load")])
3634 (define_insn_and_split "*zero_extendsidi2_insn_sp32"
3635 [(set (match_operand:DI 0 "register_operand" "=r")
3636 (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
3639 "&& reload_completed"
3640 [(set (match_dup 2) (match_dup 3))
3641 (set (match_dup 4) (match_dup 5))]
3645 dest1 = gen_highpart (SImode, operands[0]);
3646 dest2 = gen_lowpart (SImode, operands[0]);
3648 /* Swap the order in case of overlap. */
3649 if (REGNO (dest1) == REGNO (operands[1]))
3651 operands[2] = dest2;
3652 operands[3] = operands[1];
3653 operands[4] = dest1;
3654 operands[5] = const0_rtx;
3658 operands[2] = dest1;
3659 operands[3] = const0_rtx;
3660 operands[4] = dest2;
3661 operands[5] = operands[1];
3664 [(set_attr "length" "2")])
3666 ;; Simplify comparisons of extended values.
3668 (define_insn "*cmp_zero_extendqisi2"
3670 (compare:CC (zero_extend:SI (match_operand:QI 0 "register_operand" "r"))
3673 "andcc\t%0, 0xff, %%g0"
3674 [(set_attr "type" "compare")])
3676 (define_insn "*cmp_zero_qi"
3678 (compare:CC (match_operand:QI 0 "register_operand" "r")
3681 "andcc\t%0, 0xff, %%g0"
3682 [(set_attr "type" "compare")])
3684 (define_insn "*cmp_zero_extendqisi2_set"
3686 (compare:CC (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
3688 (set (match_operand:SI 0 "register_operand" "=r")
3689 (zero_extend:SI (match_dup 1)))]
3691 "andcc\t%1, 0xff, %0"
3692 [(set_attr "type" "compare")])
3694 (define_insn "*cmp_zero_extendqisi2_andcc_set"
3696 (compare:CC (and:SI (match_operand:SI 1 "register_operand" "r")
3699 (set (match_operand:SI 0 "register_operand" "=r")
3700 (zero_extend:SI (subreg:QI (match_dup 1) 0)))]
3702 "andcc\t%1, 0xff, %0"
3703 [(set_attr "type" "compare")])
3705 (define_insn "*cmp_zero_extendqidi2"
3707 (compare:CCX (zero_extend:DI (match_operand:QI 0 "register_operand" "r"))
3710 "andcc\t%0, 0xff, %%g0"
3711 [(set_attr "type" "compare")])
3713 (define_insn "*cmp_zero_qi_sp64"
3715 (compare:CCX (match_operand:QI 0 "register_operand" "r")
3718 "andcc\t%0, 0xff, %%g0"
3719 [(set_attr "type" "compare")])
3721 (define_insn "*cmp_zero_extendqidi2_set"
3723 (compare:CCX (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
3725 (set (match_operand:DI 0 "register_operand" "=r")
3726 (zero_extend:DI (match_dup 1)))]
3728 "andcc\t%1, 0xff, %0"
3729 [(set_attr "type" "compare")])
3731 (define_insn "*cmp_zero_extendqidi2_andcc_set"
3733 (compare:CCX (and:DI (match_operand:DI 1 "register_operand" "r")
3736 (set (match_operand:DI 0 "register_operand" "=r")
3737 (zero_extend:DI (subreg:QI (match_dup 1) 0)))]
3739 "andcc\t%1, 0xff, %0"
3740 [(set_attr "type" "compare")])
3742 ;; Similarly, handle {SI,DI}->QI mode truncation followed by a compare.
3744 (define_insn "*cmp_siqi_trunc"
3746 (compare:CC (subreg:QI (match_operand:SI 0 "register_operand" "r") 3)
3749 "andcc\t%0, 0xff, %%g0"
3750 [(set_attr "type" "compare")])
3752 (define_insn "*cmp_siqi_trunc_set"
3754 (compare:CC (subreg:QI (match_operand:SI 1 "register_operand" "r") 3)
3756 (set (match_operand:QI 0 "register_operand" "=r")
3757 (subreg:QI (match_dup 1) 3))]
3759 "andcc\t%1, 0xff, %0"
3760 [(set_attr "type" "compare")])
3762 (define_insn "*cmp_diqi_trunc"
3764 (compare:CC (subreg:QI (match_operand:DI 0 "register_operand" "r") 7)
3767 "andcc\t%0, 0xff, %%g0"
3768 [(set_attr "type" "compare")])
3770 (define_insn "*cmp_diqi_trunc_set"
3772 (compare:CC (subreg:QI (match_operand:DI 1 "register_operand" "r") 7)
3774 (set (match_operand:QI 0 "register_operand" "=r")
3775 (subreg:QI (match_dup 1) 7))]
3777 "andcc\t%1, 0xff, %0"
3778 [(set_attr "type" "compare")])
3781 ;; Sign-extension instructions
3783 ;; These patterns originally accepted general_operands, however, slightly
3784 ;; better code is generated by only accepting register_operands, and then
3785 ;; letting combine generate the lds[hb] insns.
3787 (define_expand "extendhisi2"
3788 [(set (match_operand:SI 0 "register_operand" "")
3789 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
3792 rtx temp = gen_reg_rtx (SImode);
3793 rtx shift_16 = GEN_INT (16);
3794 int op1_subbyte = 0;
3796 if (GET_CODE (operand1) == SUBREG)
3798 op1_subbyte = SUBREG_BYTE (operand1);
3799 op1_subbyte /= GET_MODE_SIZE (SImode);
3800 op1_subbyte *= GET_MODE_SIZE (SImode);
3801 operand1 = XEXP (operand1, 0);
3804 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3806 emit_insn (gen_ashrsi3 (operand0, temp, shift_16));
3810 (define_insn "*sign_extendhisi2_insn"
3811 [(set (match_operand:SI 0 "register_operand" "=r")
3812 (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
3815 [(set_attr "type" "sload")
3816 (set_attr "us3load_type" "3cycle")])
3818 (define_expand "extendqihi2"
3819 [(set (match_operand:HI 0 "register_operand" "")
3820 (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
3823 rtx temp = gen_reg_rtx (SImode);
3824 rtx shift_24 = GEN_INT (24);
3825 int op1_subbyte = 0;
3826 int op0_subbyte = 0;
3828 if (GET_CODE (operand1) == SUBREG)
3830 op1_subbyte = SUBREG_BYTE (operand1);
3831 op1_subbyte /= GET_MODE_SIZE (SImode);
3832 op1_subbyte *= GET_MODE_SIZE (SImode);
3833 operand1 = XEXP (operand1, 0);
3835 if (GET_CODE (operand0) == SUBREG)
3837 op0_subbyte = SUBREG_BYTE (operand0);
3838 op0_subbyte /= GET_MODE_SIZE (SImode);
3839 op0_subbyte *= GET_MODE_SIZE (SImode);
3840 operand0 = XEXP (operand0, 0);
3842 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3844 if (GET_MODE (operand0) != SImode)
3845 operand0 = gen_rtx_SUBREG (SImode, operand0, op0_subbyte);
3846 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
3850 (define_insn "*sign_extendqihi2_insn"
3851 [(set (match_operand:HI 0 "register_operand" "=r")
3852 (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
3855 [(set_attr "type" "sload")
3856 (set_attr "us3load_type" "3cycle")])
3858 (define_expand "extendqisi2"
3859 [(set (match_operand:SI 0 "register_operand" "")
3860 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
3863 rtx temp = gen_reg_rtx (SImode);
3864 rtx shift_24 = GEN_INT (24);
3865 int op1_subbyte = 0;
3867 if (GET_CODE (operand1) == SUBREG)
3869 op1_subbyte = SUBREG_BYTE (operand1);
3870 op1_subbyte /= GET_MODE_SIZE (SImode);
3871 op1_subbyte *= GET_MODE_SIZE (SImode);
3872 operand1 = XEXP (operand1, 0);
3875 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3877 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
3881 (define_insn "*sign_extendqisi2_insn"
3882 [(set (match_operand:SI 0 "register_operand" "=r")
3883 (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
3886 [(set_attr "type" "sload")
3887 (set_attr "us3load_type" "3cycle")])
3889 (define_expand "extendqidi2"
3890 [(set (match_operand:DI 0 "register_operand" "")
3891 (sign_extend:DI (match_operand:QI 1 "register_operand" "")))]
3894 rtx temp = gen_reg_rtx (DImode);
3895 rtx shift_56 = GEN_INT (56);
3896 int op1_subbyte = 0;
3898 if (GET_CODE (operand1) == SUBREG)
3900 op1_subbyte = SUBREG_BYTE (operand1);
3901 op1_subbyte /= GET_MODE_SIZE (DImode);
3902 op1_subbyte *= GET_MODE_SIZE (DImode);
3903 operand1 = XEXP (operand1, 0);
3906 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
3908 emit_insn (gen_ashrdi3 (operand0, temp, shift_56));
3912 (define_insn "*sign_extendqidi2_insn"
3913 [(set (match_operand:DI 0 "register_operand" "=r")
3914 (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
3917 [(set_attr "type" "sload")
3918 (set_attr "us3load_type" "3cycle")])
3920 (define_expand "extendhidi2"
3921 [(set (match_operand:DI 0 "register_operand" "")
3922 (sign_extend:DI (match_operand:HI 1 "register_operand" "")))]
3925 rtx temp = gen_reg_rtx (DImode);
3926 rtx shift_48 = GEN_INT (48);
3927 int op1_subbyte = 0;
3929 if (GET_CODE (operand1) == SUBREG)
3931 op1_subbyte = SUBREG_BYTE (operand1);
3932 op1_subbyte /= GET_MODE_SIZE (DImode);
3933 op1_subbyte *= GET_MODE_SIZE (DImode);
3934 operand1 = XEXP (operand1, 0);
3937 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
3939 emit_insn (gen_ashrdi3 (operand0, temp, shift_48));
3943 (define_insn "*sign_extendhidi2_insn"
3944 [(set (match_operand:DI 0 "register_operand" "=r")
3945 (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
3948 [(set_attr "type" "sload")
3949 (set_attr "us3load_type" "3cycle")])
3951 (define_expand "extendsidi2"
3952 [(set (match_operand:DI 0 "register_operand" "")
3953 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
3957 (define_insn "*sign_extendsidi2_insn"
3958 [(set (match_operand:DI 0 "register_operand" "=r,r")
3959 (sign_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
3964 [(set_attr "type" "shift,sload")
3965 (set_attr "us3load_type" "*,3cycle")])
3968 ;; Special pattern for optimizing bit-field compares. This is needed
3969 ;; because combine uses this as a canonical form.
3971 (define_insn "*cmp_zero_extract"
3974 (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
3975 (match_operand:SI 1 "small_int_operand" "I")
3976 (match_operand:SI 2 "small_int_operand" "I"))
3978 "INTVAL (operands[2]) > 19"
3980 int len = INTVAL (operands[1]);
3981 int pos = 32 - INTVAL (operands[2]) - len;
3982 HOST_WIDE_INT mask = ((1 << len) - 1) << pos;
3983 operands[1] = GEN_INT (mask);
3984 return "andcc\t%0, %1, %%g0";
3986 [(set_attr "type" "compare")])
3988 (define_insn "*cmp_zero_extract_sp64"
3991 (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
3992 (match_operand:SI 1 "small_int_operand" "I")
3993 (match_operand:SI 2 "small_int_operand" "I"))
3995 "TARGET_ARCH64 && INTVAL (operands[2]) > 51"
3997 int len = INTVAL (operands[1]);
3998 int pos = 64 - INTVAL (operands[2]) - len;
3999 HOST_WIDE_INT mask = (((unsigned HOST_WIDE_INT) 1 << len) - 1) << pos;
4000 operands[1] = GEN_INT (mask);
4001 return "andcc\t%0, %1, %%g0";
4003 [(set_attr "type" "compare")])
4006 ;; Conversions between float, double and long double.
4008 (define_insn "extendsfdf2"
4009 [(set (match_operand:DF 0 "register_operand" "=e")
4011 (match_operand:SF 1 "register_operand" "f")))]
4014 [(set_attr "type" "fp")
4015 (set_attr "fptype" "double")])
4017 (define_expand "extendsftf2"
4018 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4020 (match_operand:SF 1 "register_operand" "")))]
4021 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4022 "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
4024 (define_insn "*extendsftf2_hq"
4025 [(set (match_operand:TF 0 "register_operand" "=e")
4027 (match_operand:SF 1 "register_operand" "f")))]
4028 "TARGET_FPU && TARGET_HARD_QUAD"
4030 [(set_attr "type" "fp")])
4032 (define_expand "extenddftf2"
4033 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4035 (match_operand:DF 1 "register_operand" "")))]
4036 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4037 "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
4039 (define_insn "*extenddftf2_hq"
4040 [(set (match_operand:TF 0 "register_operand" "=e")
4042 (match_operand:DF 1 "register_operand" "e")))]
4043 "TARGET_FPU && TARGET_HARD_QUAD"
4045 [(set_attr "type" "fp")])
4047 (define_insn "truncdfsf2"
4048 [(set (match_operand:SF 0 "register_operand" "=f")
4050 (match_operand:DF 1 "register_operand" "e")))]
4053 [(set_attr "type" "fp")
4054 (set_attr "fptype" "double")])
4056 (define_expand "trunctfsf2"
4057 [(set (match_operand:SF 0 "register_operand" "")
4059 (match_operand:TF 1 "general_operand" "")))]
4060 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4061 "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
4063 (define_insn "*trunctfsf2_hq"
4064 [(set (match_operand:SF 0 "register_operand" "=f")
4066 (match_operand:TF 1 "register_operand" "e")))]
4067 "TARGET_FPU && TARGET_HARD_QUAD"
4069 [(set_attr "type" "fp")])
4071 (define_expand "trunctfdf2"
4072 [(set (match_operand:DF 0 "register_operand" "")
4074 (match_operand:TF 1 "general_operand" "")))]
4075 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4076 "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
4078 (define_insn "*trunctfdf2_hq"
4079 [(set (match_operand:DF 0 "register_operand" "=e")
4081 (match_operand:TF 1 "register_operand" "e")))]
4082 "TARGET_FPU && TARGET_HARD_QUAD"
4084 [(set_attr "type" "fp")])
4087 ;; Conversion between fixed point and floating point.
4089 (define_insn "floatsisf2"
4090 [(set (match_operand:SF 0 "register_operand" "=f")
4091 (float:SF (match_operand:SI 1 "register_operand" "f")))]
4094 [(set_attr "type" "fp")
4095 (set_attr "fptype" "double")])
4097 (define_insn "floatsidf2"
4098 [(set (match_operand:DF 0 "register_operand" "=e")
4099 (float:DF (match_operand:SI 1 "register_operand" "f")))]
4102 [(set_attr "type" "fp")
4103 (set_attr "fptype" "double")])
4105 (define_expand "floatsitf2"
4106 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4107 (float:TF (match_operand:SI 1 "register_operand" "")))]
4108 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4109 "emit_tfmode_cvt (FLOAT, operands); DONE;")
4111 (define_insn "*floatsitf2_hq"
4112 [(set (match_operand:TF 0 "register_operand" "=e")
4113 (float:TF (match_operand:SI 1 "register_operand" "f")))]
4114 "TARGET_FPU && TARGET_HARD_QUAD"
4116 [(set_attr "type" "fp")])
4118 (define_expand "floatunssitf2"
4119 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4120 (unsigned_float:TF (match_operand:SI 1 "register_operand" "")))]
4121 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4122 "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
4124 ;; Now the same for 64 bit sources.
4126 (define_insn "floatdisf2"
4127 [(set (match_operand:SF 0 "register_operand" "=f")
4128 (float:SF (match_operand:DI 1 "register_operand" "e")))]
4129 "TARGET_V9 && TARGET_FPU"
4131 [(set_attr "type" "fp")
4132 (set_attr "fptype" "double")])
4134 (define_expand "floatunsdisf2"
4135 [(use (match_operand:SF 0 "register_operand" ""))
4136 (use (match_operand:DI 1 "general_operand" ""))]
4137 "TARGET_ARCH64 && TARGET_FPU"
4138 "sparc_emit_floatunsdi (operands, SFmode); DONE;")
4140 (define_insn "floatdidf2"
4141 [(set (match_operand:DF 0 "register_operand" "=e")
4142 (float:DF (match_operand:DI 1 "register_operand" "e")))]
4143 "TARGET_V9 && TARGET_FPU"
4145 [(set_attr "type" "fp")
4146 (set_attr "fptype" "double")])
4148 (define_expand "floatunsdidf2"
4149 [(use (match_operand:DF 0 "register_operand" ""))
4150 (use (match_operand:DI 1 "general_operand" ""))]
4151 "TARGET_ARCH64 && TARGET_FPU"
4152 "sparc_emit_floatunsdi (operands, DFmode); DONE;")
4154 (define_expand "floatditf2"
4155 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4156 (float:TF (match_operand:DI 1 "register_operand" "")))]
4157 "TARGET_FPU && TARGET_V9 && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4158 "emit_tfmode_cvt (FLOAT, operands); DONE;")
4160 (define_insn "*floatditf2_hq"
4161 [(set (match_operand:TF 0 "register_operand" "=e")
4162 (float:TF (match_operand:DI 1 "register_operand" "e")))]
4163 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
4165 [(set_attr "type" "fp")])
4167 (define_expand "floatunsditf2"
4168 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4169 (unsigned_float:TF (match_operand:DI 1 "register_operand" "")))]
4170 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4171 "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
4173 ;; Convert a float to an actual integer.
4174 ;; Truncation is performed as part of the conversion.
4176 (define_insn "fix_truncsfsi2"
4177 [(set (match_operand:SI 0 "register_operand" "=f")
4178 (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
4181 [(set_attr "type" "fp")
4182 (set_attr "fptype" "double")])
4184 (define_insn "fix_truncdfsi2"
4185 [(set (match_operand:SI 0 "register_operand" "=f")
4186 (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
4189 [(set_attr "type" "fp")
4190 (set_attr "fptype" "double")])
4192 (define_expand "fix_trunctfsi2"
4193 [(set (match_operand:SI 0 "register_operand" "")
4194 (fix:SI (match_operand:TF 1 "general_operand" "")))]
4195 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4196 "emit_tfmode_cvt (FIX, operands); DONE;")
4198 (define_insn "*fix_trunctfsi2_hq"
4199 [(set (match_operand:SI 0 "register_operand" "=f")
4200 (fix:SI (match_operand:TF 1 "register_operand" "e")))]
4201 "TARGET_FPU && TARGET_HARD_QUAD"
4203 [(set_attr "type" "fp")])
4205 (define_expand "fixuns_trunctfsi2"
4206 [(set (match_operand:SI 0 "register_operand" "")
4207 (unsigned_fix:SI (match_operand:TF 1 "general_operand" "")))]
4208 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4209 "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
4211 ;; Now the same, for V9 targets
4213 (define_insn "fix_truncsfdi2"
4214 [(set (match_operand:DI 0 "register_operand" "=e")
4215 (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
4216 "TARGET_V9 && TARGET_FPU"
4218 [(set_attr "type" "fp")
4219 (set_attr "fptype" "double")])
4221 (define_expand "fixuns_truncsfdi2"
4222 [(use (match_operand:DI 0 "register_operand" ""))
4223 (use (match_operand:SF 1 "general_operand" ""))]
4224 "TARGET_ARCH64 && TARGET_FPU"
4225 "sparc_emit_fixunsdi (operands, SFmode); DONE;")
4227 (define_insn "fix_truncdfdi2"
4228 [(set (match_operand:DI 0 "register_operand" "=e")
4229 (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
4230 "TARGET_V9 && TARGET_FPU"
4232 [(set_attr "type" "fp")
4233 (set_attr "fptype" "double")])
4235 (define_expand "fixuns_truncdfdi2"
4236 [(use (match_operand:DI 0 "register_operand" ""))
4237 (use (match_operand:DF 1 "general_operand" ""))]
4238 "TARGET_ARCH64 && TARGET_FPU"
4239 "sparc_emit_fixunsdi (operands, DFmode); DONE;")
4241 (define_expand "fix_trunctfdi2"
4242 [(set (match_operand:DI 0 "register_operand" "")
4243 (fix:DI (match_operand:TF 1 "general_operand" "")))]
4244 "TARGET_V9 && TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4245 "emit_tfmode_cvt (FIX, operands); DONE;")
4247 (define_insn "*fix_trunctfdi2_hq"
4248 [(set (match_operand:DI 0 "register_operand" "=e")
4249 (fix:DI (match_operand:TF 1 "register_operand" "e")))]
4250 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
4252 [(set_attr "type" "fp")])
4254 (define_expand "fixuns_trunctfdi2"
4255 [(set (match_operand:DI 0 "register_operand" "")
4256 (unsigned_fix:DI (match_operand:TF 1 "general_operand" "")))]
4257 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4258 "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
4261 ;; Integer addition/subtraction instructions.
4263 (define_expand "adddi3"
4264 [(set (match_operand:DI 0 "register_operand" "")
4265 (plus:DI (match_operand:DI 1 "register_operand" "")
4266 (match_operand:DI 2 "arith_double_add_operand" "")))]
4269 if (! TARGET_ARCH64)
4271 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
4272 gen_rtx_SET (VOIDmode, operands[0],
4273 gen_rtx_PLUS (DImode, operands[1],
4275 gen_rtx_CLOBBER (VOIDmode,
4276 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
4281 (define_insn_and_split "adddi3_insn_sp32"
4282 [(set (match_operand:DI 0 "register_operand" "=r")
4283 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
4284 (match_operand:DI 2 "arith_double_operand" "rHI")))
4285 (clobber (reg:CC 100))]
4288 "&& reload_completed"
4289 [(parallel [(set (reg:CC_NOOV 100)
4290 (compare:CC_NOOV (plus:SI (match_dup 4)
4294 (plus:SI (match_dup 4) (match_dup 5)))])
4296 (plus:SI (plus:SI (match_dup 7)
4298 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4300 operands[3] = gen_lowpart (SImode, operands[0]);
4301 operands[4] = gen_lowpart (SImode, operands[1]);
4302 operands[5] = gen_lowpart (SImode, operands[2]);
4303 operands[6] = gen_highpart (SImode, operands[0]);
4304 operands[7] = gen_highpart_mode (SImode, DImode, operands[1]);
4305 #if HOST_BITS_PER_WIDE_INT == 32
4306 if (GET_CODE (operands[2]) == CONST_INT)
4308 if (INTVAL (operands[2]) < 0)
4309 operands[8] = constm1_rtx;
4311 operands[8] = const0_rtx;
4315 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
4317 [(set_attr "length" "2")])
4319 ;; LTU here means "carry set"
4321 [(set (match_operand:SI 0 "register_operand" "=r")
4322 (plus:SI (plus:SI (match_operand:SI 1 "arith_operand" "%r")
4323 (match_operand:SI 2 "arith_operand" "rI"))
4324 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4327 [(set_attr "type" "ialuX")])
4329 (define_insn_and_split "*addx_extend_sp32"
4330 [(set (match_operand:DI 0 "register_operand" "=r")
4331 (zero_extend:DI (plus:SI (plus:SI
4332 (match_operand:SI 1 "register_or_zero_operand" "%rJ")
4333 (match_operand:SI 2 "arith_operand" "rI"))
4334 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4337 "&& reload_completed"
4338 [(set (match_dup 3) (plus:SI (plus:SI (match_dup 1) (match_dup 2))
4339 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
4340 (set (match_dup 4) (const_int 0))]
4341 "operands[3] = gen_lowpart (SImode, operands[0]);
4342 operands[4] = gen_highpart_mode (SImode, DImode, operands[1]);"
4343 [(set_attr "length" "2")])
4345 (define_insn "*addx_extend_sp64"
4346 [(set (match_operand:DI 0 "register_operand" "=r")
4347 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ")
4348 (match_operand:SI 2 "arith_operand" "rI"))
4349 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4352 [(set_attr "type" "ialuX")])
4354 (define_insn_and_split ""
4355 [(set (match_operand:DI 0 "register_operand" "=r")
4356 (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4357 (match_operand:DI 2 "register_operand" "r")))
4358 (clobber (reg:CC 100))]
4361 "&& reload_completed"
4362 [(parallel [(set (reg:CC_NOOV 100)
4363 (compare:CC_NOOV (plus:SI (match_dup 3) (match_dup 1))
4365 (set (match_dup 5) (plus:SI (match_dup 3) (match_dup 1)))])
4367 (plus:SI (plus:SI (match_dup 4) (const_int 0))
4368 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4369 "operands[3] = gen_lowpart (SImode, operands[2]);
4370 operands[4] = gen_highpart (SImode, operands[2]);
4371 operands[5] = gen_lowpart (SImode, operands[0]);
4372 operands[6] = gen_highpart (SImode, operands[0]);"
4373 [(set_attr "length" "2")])
4375 (define_insn "*adddi3_sp64"
4376 [(set (match_operand:DI 0 "register_operand" "=r,r")
4377 (plus:DI (match_operand:DI 1 "register_operand" "%r,r")
4378 (match_operand:DI 2 "arith_add_operand" "rI,O")))]
4384 (define_insn "addsi3"
4385 [(set (match_operand:SI 0 "register_operand" "=r,r,d")
4386 (plus:SI (match_operand:SI 1 "register_operand" "%r,r,d")
4387 (match_operand:SI 2 "arith_add_operand" "rI,O,d")))]
4392 fpadd32s\t%1, %2, %0"
4393 [(set_attr "type" "*,*,fga")
4394 (set_attr "fptype" "*,*,single")])
4396 (define_insn "*cmp_cc_plus"
4397 [(set (reg:CC_NOOV 100)
4398 (compare:CC_NOOV (plus:SI (match_operand:SI 0 "arith_operand" "%r")
4399 (match_operand:SI 1 "arith_operand" "rI"))
4402 "addcc\t%0, %1, %%g0"
4403 [(set_attr "type" "compare")])
4405 (define_insn "*cmp_ccx_plus"
4406 [(set (reg:CCX_NOOV 100)
4407 (compare:CCX_NOOV (plus:DI (match_operand:DI 0 "arith_operand" "%r")
4408 (match_operand:DI 1 "arith_operand" "rI"))
4411 "addcc\t%0, %1, %%g0"
4412 [(set_attr "type" "compare")])
4414 (define_insn "*cmp_cc_plus_set"
4415 [(set (reg:CC_NOOV 100)
4416 (compare:CC_NOOV (plus:SI (match_operand:SI 1 "arith_operand" "%r")
4417 (match_operand:SI 2 "arith_operand" "rI"))
4419 (set (match_operand:SI 0 "register_operand" "=r")
4420 (plus:SI (match_dup 1) (match_dup 2)))]
4423 [(set_attr "type" "compare")])
4425 (define_insn "*cmp_ccx_plus_set"
4426 [(set (reg:CCX_NOOV 100)
4427 (compare:CCX_NOOV (plus:DI (match_operand:DI 1 "arith_operand" "%r")
4428 (match_operand:DI 2 "arith_operand" "rI"))
4430 (set (match_operand:DI 0 "register_operand" "=r")
4431 (plus:DI (match_dup 1) (match_dup 2)))]
4434 [(set_attr "type" "compare")])
4436 (define_expand "subdi3"
4437 [(set (match_operand:DI 0 "register_operand" "")
4438 (minus:DI (match_operand:DI 1 "register_operand" "")
4439 (match_operand:DI 2 "arith_double_add_operand" "")))]
4442 if (! TARGET_ARCH64)
4444 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
4445 gen_rtx_SET (VOIDmode, operands[0],
4446 gen_rtx_MINUS (DImode, operands[1],
4448 gen_rtx_CLOBBER (VOIDmode,
4449 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
4454 (define_insn_and_split "subdi3_insn_sp32"
4455 [(set (match_operand:DI 0 "register_operand" "=r")
4456 (minus:DI (match_operand:DI 1 "register_operand" "r")
4457 (match_operand:DI 2 "arith_double_operand" "rHI")))
4458 (clobber (reg:CC 100))]
4461 "&& reload_completed"
4462 [(parallel [(set (reg:CC_NOOV 100)
4463 (compare:CC_NOOV (minus:SI (match_dup 4)
4467 (minus:SI (match_dup 4) (match_dup 5)))])
4469 (minus:SI (minus:SI (match_dup 7)
4471 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4473 operands[3] = gen_lowpart (SImode, operands[0]);
4474 operands[4] = gen_lowpart (SImode, operands[1]);
4475 operands[5] = gen_lowpart (SImode, operands[2]);
4476 operands[6] = gen_highpart (SImode, operands[0]);
4477 operands[7] = gen_highpart (SImode, operands[1]);
4478 #if HOST_BITS_PER_WIDE_INT == 32
4479 if (GET_CODE (operands[2]) == CONST_INT)
4481 if (INTVAL (operands[2]) < 0)
4482 operands[8] = constm1_rtx;
4484 operands[8] = const0_rtx;
4488 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
4490 [(set_attr "length" "2")])
4492 ;; LTU here means "carry set"
4494 [(set (match_operand:SI 0 "register_operand" "=r")
4495 (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
4496 (match_operand:SI 2 "arith_operand" "rI"))
4497 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4500 [(set_attr "type" "ialuX")])
4502 (define_insn "*subx_extend_sp64"
4503 [(set (match_operand:DI 0 "register_operand" "=r")
4504 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
4505 (match_operand:SI 2 "arith_operand" "rI"))
4506 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4509 [(set_attr "type" "ialuX")])
4511 (define_insn_and_split "*subx_extend"
4512 [(set (match_operand:DI 0 "register_operand" "=r")
4513 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
4514 (match_operand:SI 2 "arith_operand" "rI"))
4515 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4518 "&& reload_completed"
4519 [(set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 2))
4520 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
4521 (set (match_dup 4) (const_int 0))]
4522 "operands[3] = gen_lowpart (SImode, operands[0]);
4523 operands[4] = gen_highpart (SImode, operands[0]);"
4524 [(set_attr "length" "2")])
4526 (define_insn_and_split ""
4527 [(set (match_operand:DI 0 "register_operand" "=r")
4528 (minus:DI (match_operand:DI 1 "register_operand" "r")
4529 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))
4530 (clobber (reg:CC 100))]
4533 "&& reload_completed"
4534 [(parallel [(set (reg:CC_NOOV 100)
4535 (compare:CC_NOOV (minus:SI (match_dup 3) (match_dup 2))
4537 (set (match_dup 5) (minus:SI (match_dup 3) (match_dup 2)))])
4539 (minus:SI (minus:SI (match_dup 4) (const_int 0))
4540 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4541 "operands[3] = gen_lowpart (SImode, operands[1]);
4542 operands[4] = gen_highpart (SImode, operands[1]);
4543 operands[5] = gen_lowpart (SImode, operands[0]);
4544 operands[6] = gen_highpart (SImode, operands[0]);"
4545 [(set_attr "length" "2")])
4547 (define_insn "*subdi3_sp64"
4548 [(set (match_operand:DI 0 "register_operand" "=r,r")
4549 (minus:DI (match_operand:DI 1 "register_operand" "r,r")
4550 (match_operand:DI 2 "arith_add_operand" "rI,O")))]
4556 (define_insn "subsi3"
4557 [(set (match_operand:SI 0 "register_operand" "=r,r,d")
4558 (minus:SI (match_operand:SI 1 "register_operand" "r,r,d")
4559 (match_operand:SI 2 "arith_add_operand" "rI,O,d")))]
4564 fpsub32s\t%1, %2, %0"
4565 [(set_attr "type" "*,*,fga")
4566 (set_attr "fptype" "*,*,single")])
4568 (define_insn "*cmp_minus_cc"
4569 [(set (reg:CC_NOOV 100)
4570 (compare:CC_NOOV (minus:SI (match_operand:SI 0 "register_or_zero_operand" "rJ")
4571 (match_operand:SI 1 "arith_operand" "rI"))
4574 "subcc\t%r0, %1, %%g0"
4575 [(set_attr "type" "compare")])
4577 (define_insn "*cmp_minus_ccx"
4578 [(set (reg:CCX_NOOV 100)
4579 (compare:CCX_NOOV (minus:DI (match_operand:DI 0 "register_operand" "r")
4580 (match_operand:DI 1 "arith_operand" "rI"))
4583 "subcc\t%0, %1, %%g0"
4584 [(set_attr "type" "compare")])
4586 (define_insn "cmp_minus_cc_set"
4587 [(set (reg:CC_NOOV 100)
4588 (compare:CC_NOOV (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
4589 (match_operand:SI 2 "arith_operand" "rI"))
4591 (set (match_operand:SI 0 "register_operand" "=r")
4592 (minus:SI (match_dup 1) (match_dup 2)))]
4594 "subcc\t%r1, %2, %0"
4595 [(set_attr "type" "compare")])
4597 (define_insn "*cmp_minus_ccx_set"
4598 [(set (reg:CCX_NOOV 100)
4599 (compare:CCX_NOOV (minus:DI (match_operand:DI 1 "register_operand" "r")
4600 (match_operand:DI 2 "arith_operand" "rI"))
4602 (set (match_operand:DI 0 "register_operand" "=r")
4603 (minus:DI (match_dup 1) (match_dup 2)))]
4606 [(set_attr "type" "compare")])
4609 ;; Integer multiply/divide instructions.
4611 ;; The 32-bit multiply/divide instructions are deprecated on v9, but at
4612 ;; least in UltraSPARC I, II and IIi it is a win tick-wise.
4614 (define_insn "mulsi3"
4615 [(set (match_operand:SI 0 "register_operand" "=r")
4616 (mult:SI (match_operand:SI 1 "arith_operand" "%r")
4617 (match_operand:SI 2 "arith_operand" "rI")))]
4620 [(set_attr "type" "imul")])
4622 (define_expand "muldi3"
4623 [(set (match_operand:DI 0 "register_operand" "")
4624 (mult:DI (match_operand:DI 1 "arith_operand" "")
4625 (match_operand:DI 2 "arith_operand" "")))]
4626 "TARGET_ARCH64 || TARGET_V8PLUS"
4630 emit_insn (gen_muldi3_v8plus (operands[0], operands[1], operands[2]));
4635 (define_insn "*muldi3_sp64"
4636 [(set (match_operand:DI 0 "register_operand" "=r")
4637 (mult:DI (match_operand:DI 1 "arith_operand" "%r")
4638 (match_operand:DI 2 "arith_operand" "rI")))]
4641 [(set_attr "type" "imul")])
4643 ;; V8plus wide multiply.
4645 (define_insn "muldi3_v8plus"
4646 [(set (match_operand:DI 0 "register_operand" "=r,h")
4647 (mult:DI (match_operand:DI 1 "arith_operand" "%r,0")
4648 (match_operand:DI 2 "arith_operand" "rI,rI")))
4649 (clobber (match_scratch:SI 3 "=&h,X"))
4650 (clobber (match_scratch:SI 4 "=&h,X"))]
4653 if (sparc_check_64 (operands[1], insn) <= 0)
4654 output_asm_insn ("srl\t%L1, 0, %L1", operands);
4655 if (which_alternative == 1)
4656 output_asm_insn ("sllx\t%H1, 32, %H1", operands);
4657 if (GET_CODE (operands[2]) == CONST_INT)
4659 if (which_alternative == 1)
4660 return "or\t%L1, %H1, %H1\n\tmulx\t%H1, %2, %L0\;srlx\t%L0, 32, %H0";
4662 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";
4664 else if (rtx_equal_p (operands[1], operands[2]))
4666 if (which_alternative == 1)
4667 return "or\t%L1, %H1, %H1\n\tmulx\t%H1, %H1, %L0\;srlx\t%L0, 32, %H0";
4669 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";
4671 if (sparc_check_64 (operands[2], insn) <= 0)
4672 output_asm_insn ("srl\t%L2, 0, %L2", operands);
4673 if (which_alternative == 1)
4674 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";
4676 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";
4678 [(set_attr "type" "multi")
4679 (set_attr "length" "9,8")])
4681 (define_insn "*cmp_mul_set"
4683 (compare:CC (mult:SI (match_operand:SI 1 "arith_operand" "%r")
4684 (match_operand:SI 2 "arith_operand" "rI"))
4686 (set (match_operand:SI 0 "register_operand" "=r")
4687 (mult:SI (match_dup 1) (match_dup 2)))]
4688 "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS"
4689 "smulcc\t%1, %2, %0"
4690 [(set_attr "type" "imul")])
4692 (define_expand "mulsidi3"
4693 [(set (match_operand:DI 0 "register_operand" "")
4694 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
4695 (sign_extend:DI (match_operand:SI 2 "arith_operand" ""))))]
4698 if (CONSTANT_P (operands[2]))
4701 emit_insn (gen_const_mulsidi3_v8plus (operands[0], operands[1],
4703 else if (TARGET_ARCH32)
4704 emit_insn (gen_const_mulsidi3_sp32 (operands[0], operands[1],
4707 emit_insn (gen_const_mulsidi3_sp64 (operands[0], operands[1],
4713 emit_insn (gen_mulsidi3_v8plus (operands[0], operands[1], operands[2]));
4718 ;; V9 puts the 64-bit product in a 64-bit register. Only out or global
4719 ;; registers can hold 64-bit values in the V8plus environment.
4721 (define_insn "mulsidi3_v8plus"
4722 [(set (match_operand:DI 0 "register_operand" "=h,r")
4723 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4724 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
4725 (clobber (match_scratch:SI 3 "=X,&h"))]
4728 smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
4729 smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4730 [(set_attr "type" "multi")
4731 (set_attr "length" "2,3")])
4734 (define_insn "const_mulsidi3_v8plus"
4735 [(set (match_operand:DI 0 "register_operand" "=h,r")
4736 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4737 (match_operand:DI 2 "small_int_operand" "I,I")))
4738 (clobber (match_scratch:SI 3 "=X,&h"))]
4741 smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
4742 smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4743 [(set_attr "type" "multi")
4744 (set_attr "length" "2,3")])
4747 (define_insn "*mulsidi3_sp32"
4748 [(set (match_operand:DI 0 "register_operand" "=r")
4749 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4750 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4753 return TARGET_SPARCLET
4754 ? "smuld\t%1, %2, %L0"
4755 : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
4758 (if_then_else (eq_attr "isa" "sparclet")
4759 (const_string "imul") (const_string "multi")))
4760 (set (attr "length")
4761 (if_then_else (eq_attr "isa" "sparclet")
4762 (const_int 1) (const_int 2)))])
4764 (define_insn "*mulsidi3_sp64"
4765 [(set (match_operand:DI 0 "register_operand" "=r")
4766 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4767 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4768 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4770 [(set_attr "type" "imul")])
4772 ;; Extra pattern, because sign_extend of a constant isn't valid.
4775 (define_insn "const_mulsidi3_sp32"
4776 [(set (match_operand:DI 0 "register_operand" "=r")
4777 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4778 (match_operand:DI 2 "small_int_operand" "I")))]
4781 return TARGET_SPARCLET
4782 ? "smuld\t%1, %2, %L0"
4783 : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
4786 (if_then_else (eq_attr "isa" "sparclet")
4787 (const_string "imul") (const_string "multi")))
4788 (set (attr "length")
4789 (if_then_else (eq_attr "isa" "sparclet")
4790 (const_int 1) (const_int 2)))])
4792 (define_insn "const_mulsidi3_sp64"
4793 [(set (match_operand:DI 0 "register_operand" "=r")
4794 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4795 (match_operand:DI 2 "small_int_operand" "I")))]
4796 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4798 [(set_attr "type" "imul")])
4800 (define_expand "smulsi3_highpart"
4801 [(set (match_operand:SI 0 "register_operand" "")
4803 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
4804 (sign_extend:DI (match_operand:SI 2 "arith_operand" "")))
4806 "TARGET_HARD_MUL && TARGET_ARCH32"
4808 if (CONSTANT_P (operands[2]))
4812 emit_insn (gen_const_smulsi3_highpart_v8plus (operands[0],
4818 emit_insn (gen_const_smulsi3_highpart (operands[0], operands[1], operands[2]));
4823 emit_insn (gen_smulsi3_highpart_v8plus (operands[0], operands[1],
4824 operands[2], GEN_INT (32)));
4830 (define_insn "smulsi3_highpart_v8plus"
4831 [(set (match_operand:SI 0 "register_operand" "=h,r")
4833 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4834 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
4835 (match_operand:SI 3 "small_int_operand" "I,I"))))
4836 (clobber (match_scratch:SI 4 "=X,&h"))]
4839 smul\t%1, %2, %0\;srlx\t%0, %3, %0
4840 smul\t%1, %2, %4\;srlx\t%4, %3, %0"
4841 [(set_attr "type" "multi")
4842 (set_attr "length" "2")])
4844 ;; The combiner changes TRUNCATE in the previous pattern to SUBREG.
4847 [(set (match_operand:SI 0 "register_operand" "=h,r")
4850 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4851 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
4852 (match_operand:SI 3 "small_int_operand" "I,I"))
4854 (clobber (match_scratch:SI 4 "=X,&h"))]
4857 smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
4858 smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
4859 [(set_attr "type" "multi")
4860 (set_attr "length" "2")])
4863 (define_insn "const_smulsi3_highpart_v8plus"
4864 [(set (match_operand:SI 0 "register_operand" "=h,r")
4866 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4867 (match_operand:DI 2 "small_int_operand" "I,I"))
4868 (match_operand:SI 3 "small_int_operand" "I,I"))))
4869 (clobber (match_scratch:SI 4 "=X,&h"))]
4872 smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
4873 smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
4874 [(set_attr "type" "multi")
4875 (set_attr "length" "2")])
4878 (define_insn "*smulsi3_highpart_sp32"
4879 [(set (match_operand:SI 0 "register_operand" "=r")
4881 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4882 (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
4885 "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
4886 [(set_attr "type" "multi")
4887 (set_attr "length" "2")])
4890 (define_insn "const_smulsi3_highpart"
4891 [(set (match_operand:SI 0 "register_operand" "=r")
4893 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4894 (match_operand:DI 2 "small_int_operand" "i"))
4897 "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
4898 [(set_attr "type" "multi")
4899 (set_attr "length" "2")])
4901 (define_expand "umulsidi3"
4902 [(set (match_operand:DI 0 "register_operand" "")
4903 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
4904 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" ""))))]
4907 if (CONSTANT_P (operands[2]))
4910 emit_insn (gen_const_umulsidi3_v8plus (operands[0], operands[1],
4912 else if (TARGET_ARCH32)
4913 emit_insn (gen_const_umulsidi3_sp32 (operands[0], operands[1],
4916 emit_insn (gen_const_umulsidi3_sp64 (operands[0], operands[1],
4922 emit_insn (gen_umulsidi3_v8plus (operands[0], operands[1], operands[2]));
4928 (define_insn "umulsidi3_v8plus"
4929 [(set (match_operand:DI 0 "register_operand" "=h,r")
4930 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4931 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
4932 (clobber (match_scratch:SI 3 "=X,&h"))]
4935 umul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
4936 umul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4937 [(set_attr "type" "multi")
4938 (set_attr "length" "2,3")])
4941 (define_insn "*umulsidi3_sp32"
4942 [(set (match_operand:DI 0 "register_operand" "=r")
4943 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4944 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4947 return TARGET_SPARCLET
4948 ? "umuld\t%1, %2, %L0"
4949 : "umul\t%1, %2, %L0\n\trd\t%%y, %H0";
4952 (if_then_else (eq_attr "isa" "sparclet")
4953 (const_string "imul") (const_string "multi")))
4954 (set (attr "length")
4955 (if_then_else (eq_attr "isa" "sparclet")
4956 (const_int 1) (const_int 2)))])
4958 (define_insn "*umulsidi3_sp64"
4959 [(set (match_operand:DI 0 "register_operand" "=r")
4960 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4961 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4962 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4964 [(set_attr "type" "imul")])
4966 ;; Extra pattern, because sign_extend of a constant isn't valid.
4969 (define_insn "const_umulsidi3_sp32"
4970 [(set (match_operand:DI 0 "register_operand" "=r")
4971 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4972 (match_operand:DI 2 "uns_small_int_operand" "")))]
4975 return TARGET_SPARCLET
4976 ? "umuld\t%1, %s2, %L0"
4977 : "umul\t%1, %s2, %L0\n\trd\t%%y, %H0";
4980 (if_then_else (eq_attr "isa" "sparclet")
4981 (const_string "imul") (const_string "multi")))
4982 (set (attr "length")
4983 (if_then_else (eq_attr "isa" "sparclet")
4984 (const_int 1) (const_int 2)))])
4986 (define_insn "const_umulsidi3_sp64"
4987 [(set (match_operand:DI 0 "register_operand" "=r")
4988 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4989 (match_operand:DI 2 "uns_small_int_operand" "")))]
4990 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4992 [(set_attr "type" "imul")])
4995 (define_insn "const_umulsidi3_v8plus"
4996 [(set (match_operand:DI 0 "register_operand" "=h,r")
4997 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4998 (match_operand:DI 2 "uns_small_int_operand" "")))
4999 (clobber (match_scratch:SI 3 "=X,h"))]
5002 umul\t%1, %s2, %L0\n\tsrlx\t%L0, 32, %H0
5003 umul\t%1, %s2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
5004 [(set_attr "type" "multi")
5005 (set_attr "length" "2,3")])
5007 (define_expand "umulsi3_highpart"
5008 [(set (match_operand:SI 0 "register_operand" "")
5010 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
5011 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" "")))
5013 "TARGET_HARD_MUL && TARGET_ARCH32"
5015 if (CONSTANT_P (operands[2]))
5019 emit_insn (gen_const_umulsi3_highpart_v8plus (operands[0],
5025 emit_insn (gen_const_umulsi3_highpart (operands[0], operands[1], operands[2]));
5030 emit_insn (gen_umulsi3_highpart_v8plus (operands[0], operands[1],
5031 operands[2], GEN_INT (32)));
5037 (define_insn "umulsi3_highpart_v8plus"
5038 [(set (match_operand:SI 0 "register_operand" "=h,r")
5040 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5041 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
5042 (match_operand:SI 3 "small_int_operand" "I,I"))))
5043 (clobber (match_scratch:SI 4 "=X,h"))]
5046 umul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
5047 umul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
5048 [(set_attr "type" "multi")
5049 (set_attr "length" "2")])
5052 (define_insn "const_umulsi3_highpart_v8plus"
5053 [(set (match_operand:SI 0 "register_operand" "=h,r")
5055 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5056 (match_operand:DI 2 "uns_small_int_operand" ""))
5057 (match_operand:SI 3 "small_int_operand" "I,I"))))
5058 (clobber (match_scratch:SI 4 "=X,h"))]
5061 umul\t%1, %s2, %0\n\tsrlx\t%0, %3, %0
5062 umul\t%1, %s2, %4\n\tsrlx\t%4, %3, %0"
5063 [(set_attr "type" "multi")
5064 (set_attr "length" "2")])
5067 (define_insn "*umulsi3_highpart_sp32"
5068 [(set (match_operand:SI 0 "register_operand" "=r")
5070 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5071 (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
5074 "umul\t%1, %2, %%g0\n\trd\t%%y, %0"
5075 [(set_attr "type" "multi")
5076 (set_attr "length" "2")])
5079 (define_insn "const_umulsi3_highpart"
5080 [(set (match_operand:SI 0 "register_operand" "=r")
5082 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5083 (match_operand:DI 2 "uns_small_int_operand" ""))
5086 "umul\t%1, %s2, %%g0\n\trd\t%%y, %0"
5087 [(set_attr "type" "multi")
5088 (set_attr "length" "2")])
5090 ;; The V8 architecture specifies that there must be 3 instructions between
5091 ;; a Y register write and a use of it for correct results.
5093 (define_expand "divsi3"
5094 [(parallel [(set (match_operand:SI 0 "register_operand" "=r,r")
5095 (div:SI (match_operand:SI 1 "register_operand" "r,r")
5096 (match_operand:SI 2 "input_operand" "rI,m")))
5097 (clobber (match_scratch:SI 3 "=&r,&r"))])]
5098 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
5102 operands[3] = gen_reg_rtx(SImode);
5103 emit_insn (gen_ashrsi3 (operands[3], operands[1], GEN_INT (31)));
5104 emit_insn (gen_divsi3_sp64 (operands[0], operands[1], operands[2],
5110 (define_insn "divsi3_sp32"
5111 [(set (match_operand:SI 0 "register_operand" "=r,r")
5112 (div:SI (match_operand:SI 1 "register_operand" "r,r")
5113 (match_operand:SI 2 "input_operand" "rI,m")))
5114 (clobber (match_scratch:SI 3 "=&r,&r"))]
5115 "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS)
5118 if (which_alternative == 0)
5120 return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tsdiv\t%1, %2, %0";
5122 return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tnop\n\tnop\n\tnop\n\tsdiv\t%1, %2, %0";
5125 return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tld\t%2, %3\n\tsdiv\t%1, %3, %0";
5127 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";
5129 [(set_attr "type" "multi")
5130 (set (attr "length")
5131 (if_then_else (eq_attr "isa" "v9")
5132 (const_int 4) (const_int 6)))])
5134 (define_insn "divsi3_sp64"
5135 [(set (match_operand:SI 0 "register_operand" "=r")
5136 (div:SI (match_operand:SI 1 "register_operand" "r")
5137 (match_operand:SI 2 "input_operand" "rI")))
5138 (use (match_operand:SI 3 "register_operand" "r"))]
5139 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5140 "wr\t%%g0, %3, %%y\n\tsdiv\t%1, %2, %0"
5141 [(set_attr "type" "multi")
5142 (set_attr "length" "2")])
5144 (define_insn "divdi3"
5145 [(set (match_operand:DI 0 "register_operand" "=r")
5146 (div:DI (match_operand:DI 1 "register_operand" "r")
5147 (match_operand:DI 2 "arith_operand" "rI")))]
5150 [(set_attr "type" "idiv")])
5152 (define_insn "*cmp_sdiv_cc_set"
5154 (compare:CC (div:SI (match_operand:SI 1 "register_operand" "r")
5155 (match_operand:SI 2 "arith_operand" "rI"))
5157 (set (match_operand:SI 0 "register_operand" "=r")
5158 (div:SI (match_dup 1) (match_dup 2)))
5159 (clobber (match_scratch:SI 3 "=&r"))]
5160 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
5163 return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tsdivcc\t%1, %2, %0";
5165 return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tnop\n\tnop\n\tnop\n\tsdivcc\t%1, %2, %0";
5167 [(set_attr "type" "multi")
5168 (set (attr "length")
5169 (if_then_else (eq_attr "isa" "v9")
5170 (const_int 3) (const_int 6)))])
5173 (define_expand "udivsi3"
5174 [(set (match_operand:SI 0 "register_operand" "")
5175 (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "")
5176 (match_operand:SI 2 "input_operand" "")))]
5177 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
5180 ;; The V8 architecture specifies that there must be 3 instructions between
5181 ;; a Y register write and a use of it for correct results.
5183 (define_insn "udivsi3_sp32"
5184 [(set (match_operand:SI 0 "register_operand" "=r,&r,&r")
5185 (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "r,r,m")
5186 (match_operand:SI 2 "input_operand" "rI,m,r")))]
5187 "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS)
5190 output_asm_insn ("wr\t%%g0, %%g0, %%y", operands);
5191 switch (which_alternative)
5194 return "nop\n\tnop\n\tnop\n\tudiv\t%1, %2, %0";
5196 return "ld\t%2, %0\n\tnop\n\tnop\n\tudiv\t%1, %0, %0";
5198 return "ld\t%1, %0\n\tnop\n\tnop\n\tudiv\t%0, %2, %0";
5201 [(set_attr "type" "multi")
5202 (set_attr "length" "5")])
5204 (define_insn "udivsi3_sp64"
5205 [(set (match_operand:SI 0 "register_operand" "=r")
5206 (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "r")
5207 (match_operand:SI 2 "input_operand" "rI")))]
5208 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5209 "wr\t%%g0, 0, %%y\n\tudiv\t%1, %2, %0"
5210 [(set_attr "type" "multi")
5211 (set_attr "length" "2")])
5213 (define_insn "udivdi3"
5214 [(set (match_operand:DI 0 "register_operand" "=r")
5215 (udiv:DI (match_operand:DI 1 "register_operand" "r")
5216 (match_operand:DI 2 "arith_operand" "rI")))]
5219 [(set_attr "type" "idiv")])
5221 (define_insn "*cmp_udiv_cc_set"
5223 (compare:CC (udiv:SI (match_operand:SI 1 "register_operand" "r")
5224 (match_operand:SI 2 "arith_operand" "rI"))
5226 (set (match_operand:SI 0 "register_operand" "=r")
5227 (udiv:SI (match_dup 1) (match_dup 2)))]
5229 || TARGET_DEPRECATED_V8_INSNS"
5232 return "wr\t%%g0, %%g0, %%y\n\tudivcc\t%1, %2, %0";
5234 return "wr\t%%g0, %%g0, %%y\n\tnop\n\tnop\n\tnop\n\tudivcc\t%1, %2, %0";
5236 [(set_attr "type" "multi")
5237 (set (attr "length")
5238 (if_then_else (eq_attr "isa" "v9")
5239 (const_int 2) (const_int 5)))])
5241 ; sparclet multiply/accumulate insns
5243 (define_insn "*smacsi"
5244 [(set (match_operand:SI 0 "register_operand" "=r")
5245 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "%r")
5246 (match_operand:SI 2 "arith_operand" "rI"))
5247 (match_operand:SI 3 "register_operand" "0")))]
5250 [(set_attr "type" "imul")])
5252 (define_insn "*smacdi"
5253 [(set (match_operand:DI 0 "register_operand" "=r")
5254 (plus:DI (mult:DI (sign_extend:DI
5255 (match_operand:SI 1 "register_operand" "%r"))
5257 (match_operand:SI 2 "register_operand" "r")))
5258 (match_operand:DI 3 "register_operand" "0")))]
5260 "smacd\t%1, %2, %L0"
5261 [(set_attr "type" "imul")])
5263 (define_insn "*umacdi"
5264 [(set (match_operand:DI 0 "register_operand" "=r")
5265 (plus:DI (mult:DI (zero_extend:DI
5266 (match_operand:SI 1 "register_operand" "%r"))
5268 (match_operand:SI 2 "register_operand" "r")))
5269 (match_operand:DI 3 "register_operand" "0")))]
5271 "umacd\t%1, %2, %L0"
5272 [(set_attr "type" "imul")])
5275 ;; Boolean instructions.
5277 ;; We define DImode `and' so with DImode `not' we can get
5278 ;; DImode `andn'. Other combinations are possible.
5280 (define_mode_macro V64I [DI V2SI V4HI V8QI])
5281 (define_mode_macro V32I [SI V2HI V4QI])
5283 (define_expand "and<V64I:mode>3"
5284 [(set (match_operand:V64I 0 "register_operand" "")
5285 (and:V64I (match_operand:V64I 1 "arith_double_operand" "")
5286 (match_operand:V64I 2 "arith_double_operand" "")))]
5290 (define_insn "*and<V64I:mode>3_sp32"
5291 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5292 (and:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
5293 (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
5298 [(set_attr "type" "*,fga")
5299 (set_attr "length" "2,*")
5300 (set_attr "fptype" "*,double")])
5302 (define_insn "*and<V64I:mode>3_sp64"
5303 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5304 (and:V64I (match_operand:V64I 1 "arith_operand" "%r,b")
5305 (match_operand:V64I 2 "arith_operand" "rI,b")))]
5310 [(set_attr "type" "*,fga")
5311 (set_attr "fptype" "*,double")])
5313 (define_insn "and<V32I:mode>3"
5314 [(set (match_operand:V32I 0 "register_operand" "=r,d")
5315 (and:V32I (match_operand:V32I 1 "arith_operand" "%r,d")
5316 (match_operand:V32I 2 "arith_operand" "rI,d")))]
5321 [(set_attr "type" "*,fga")
5322 (set_attr "fptype" "*,single")])
5325 [(set (match_operand:SI 0 "register_operand" "")
5326 (and:SI (match_operand:SI 1 "register_operand" "")
5327 (match_operand:SI 2 "const_compl_high_operand" "")))
5328 (clobber (match_operand:SI 3 "register_operand" ""))]
5330 [(set (match_dup 3) (match_dup 4))
5331 (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 1)))]
5333 operands[4] = GEN_INT (~INTVAL (operands[2]));
5336 (define_insn_and_split "*and_not_<V64I:mode>_sp32"
5337 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5338 (and:V64I (not:V64I (match_operand:V64I 1 "register_operand" "%r,b"))
5339 (match_operand:V64I 2 "register_operand" "r,b")))]
5343 fandnot1\t%1, %2, %0"
5344 "&& reload_completed
5345 && ((GET_CODE (operands[0]) == REG
5346 && REGNO (operands[0]) < 32)
5347 || (GET_CODE (operands[0]) == SUBREG
5348 && GET_CODE (SUBREG_REG (operands[0])) == REG
5349 && REGNO (SUBREG_REG (operands[0])) < 32))"
5350 [(set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))
5351 (set (match_dup 6) (and:SI (not:SI (match_dup 7)) (match_dup 8)))]
5352 "operands[3] = gen_highpart (SImode, operands[0]);
5353 operands[4] = gen_highpart (SImode, operands[1]);
5354 operands[5] = gen_highpart (SImode, operands[2]);
5355 operands[6] = gen_lowpart (SImode, operands[0]);
5356 operands[7] = gen_lowpart (SImode, operands[1]);
5357 operands[8] = gen_lowpart (SImode, operands[2]);"
5358 [(set_attr "type" "*,fga")
5359 (set_attr "length" "2,*")
5360 (set_attr "fptype" "*,double")])
5362 (define_insn "*and_not_<V64I:mode>_sp64"
5363 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5364 (and:V64I (not:V64I (match_operand:V64I 1 "register_operand" "%r,b"))
5365 (match_operand:V64I 2 "register_operand" "r,b")))]
5369 fandnot1\t%1, %2, %0"
5370 [(set_attr "type" "*,fga")
5371 (set_attr "fptype" "*,double")])
5373 (define_insn "*and_not_<V32I:mode>"
5374 [(set (match_operand:V32I 0 "register_operand" "=r,d")
5375 (and:V32I (not:V32I (match_operand:V32I 1 "register_operand" "%r,d"))
5376 (match_operand:V32I 2 "register_operand" "r,d")))]
5380 fandnot1s\t%1, %2, %0"
5381 [(set_attr "type" "*,fga")
5382 (set_attr "fptype" "*,single")])
5384 (define_expand "ior<V64I:mode>3"
5385 [(set (match_operand:V64I 0 "register_operand" "")
5386 (ior:V64I (match_operand:V64I 1 "arith_double_operand" "")
5387 (match_operand:V64I 2 "arith_double_operand" "")))]
5391 (define_insn "*ior<V64I:mode>3_sp32"
5392 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5393 (ior:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
5394 (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
5399 [(set_attr "type" "*,fga")
5400 (set_attr "length" "2,*")
5401 (set_attr "fptype" "*,double")])
5403 (define_insn "*ior<V64I:mode>3_sp64"
5404 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5405 (ior:V64I (match_operand:V64I 1 "arith_operand" "%r,b")
5406 (match_operand:V64I 2 "arith_operand" "rI,b")))]
5411 [(set_attr "type" "*,fga")
5412 (set_attr "fptype" "*,double")])
5414 (define_insn "ior<V32I:mode>3"
5415 [(set (match_operand:V32I 0 "register_operand" "=r,d")
5416 (ior:V32I (match_operand:V32I 1 "arith_operand" "%r,d")
5417 (match_operand:V32I 2 "arith_operand" "rI,d")))]
5422 [(set_attr "type" "*,fga")
5423 (set_attr "fptype" "*,single")])
5426 [(set (match_operand:SI 0 "register_operand" "")
5427 (ior:SI (match_operand:SI 1 "register_operand" "")
5428 (match_operand:SI 2 "const_compl_high_operand" "")))
5429 (clobber (match_operand:SI 3 "register_operand" ""))]
5431 [(set (match_dup 3) (match_dup 4))
5432 (set (match_dup 0) (ior:SI (not:SI (match_dup 3)) (match_dup 1)))]
5434 operands[4] = GEN_INT (~INTVAL (operands[2]));
5437 (define_insn_and_split "*or_not_<V64I:mode>_sp32"
5438 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5439 (ior:V64I (not:V64I (match_operand:V64I 1 "register_operand" "r,b"))
5440 (match_operand:V64I 2 "register_operand" "r,b")))]
5444 fornot1\t%1, %2, %0"
5445 "&& reload_completed
5446 && ((GET_CODE (operands[0]) == REG
5447 && REGNO (operands[0]) < 32)
5448 || (GET_CODE (operands[0]) == SUBREG
5449 && GET_CODE (SUBREG_REG (operands[0])) == REG
5450 && REGNO (SUBREG_REG (operands[0])) < 32))"
5451 [(set (match_dup 3) (ior:SI (not:SI (match_dup 4)) (match_dup 5)))
5452 (set (match_dup 6) (ior:SI (not:SI (match_dup 7)) (match_dup 8)))]
5453 "operands[3] = gen_highpart (SImode, operands[0]);
5454 operands[4] = gen_highpart (SImode, operands[1]);
5455 operands[5] = gen_highpart (SImode, operands[2]);
5456 operands[6] = gen_lowpart (SImode, operands[0]);
5457 operands[7] = gen_lowpart (SImode, operands[1]);
5458 operands[8] = gen_lowpart (SImode, operands[2]);"
5459 [(set_attr "type" "*,fga")
5460 (set_attr "length" "2,*")
5461 (set_attr "fptype" "*,double")])
5463 (define_insn "*or_not_<V64I:mode>_sp64"
5464 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5465 (ior:V64I (not:V64I (match_operand:V64I 1 "register_operand" "r,b"))
5466 (match_operand:V64I 2 "register_operand" "r,b")))]
5470 fornot1\t%1, %2, %0"
5471 [(set_attr "type" "*,fga")
5472 (set_attr "fptype" "*,double")])
5474 (define_insn "*or_not_<V32I:mode>"
5475 [(set (match_operand:V32I 0 "register_operand" "=r,d")
5476 (ior:V32I (not:V32I (match_operand:V32I 1 "register_operand" "r,d"))
5477 (match_operand:V32I 2 "register_operand" "r,d")))]
5481 fornot1s\t%1, %2, %0"
5482 [(set_attr "type" "*,fga")
5483 (set_attr "fptype" "*,single")])
5485 (define_expand "xor<V64I:mode>3"
5486 [(set (match_operand:V64I 0 "register_operand" "")
5487 (xor:V64I (match_operand:V64I 1 "arith_double_operand" "")
5488 (match_operand:V64I 2 "arith_double_operand" "")))]
5492 (define_insn "*xor<V64I:mode>3_sp32"
5493 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5494 (xor:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
5495 (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
5500 [(set_attr "type" "*,fga")
5501 (set_attr "length" "2,*")
5502 (set_attr "fptype" "*,double")])
5504 (define_insn "*xor<V64I:mode>3_sp64"
5505 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5506 (xor:V64I (match_operand:V64I 1 "arith_operand" "%rJ,b")
5507 (match_operand:V64I 2 "arith_operand" "rI,b")))]
5512 [(set_attr "type" "*,fga")
5513 (set_attr "fptype" "*,double")])
5515 (define_insn "xor<V32I:mode>3"
5516 [(set (match_operand:V32I 0 "register_operand" "=r,d")
5517 (xor:V32I (match_operand:V32I 1 "arith_operand" "%rJ,d")
5518 (match_operand:V32I 2 "arith_operand" "rI,d")))]
5523 [(set_attr "type" "*,fga")
5524 (set_attr "fptype" "*,single")])
5527 [(set (match_operand:SI 0 "register_operand" "")
5528 (xor:SI (match_operand:SI 1 "register_operand" "")
5529 (match_operand:SI 2 "const_compl_high_operand" "")))
5530 (clobber (match_operand:SI 3 "register_operand" ""))]
5532 [(set (match_dup 3) (match_dup 4))
5533 (set (match_dup 0) (not:SI (xor:SI (match_dup 3) (match_dup 1))))]
5535 operands[4] = GEN_INT (~INTVAL (operands[2]));
5539 [(set (match_operand:SI 0 "register_operand" "")
5540 (not:SI (xor:SI (match_operand:SI 1 "register_operand" "")
5541 (match_operand:SI 2 "const_compl_high_operand" ""))))
5542 (clobber (match_operand:SI 3 "register_operand" ""))]
5544 [(set (match_dup 3) (match_dup 4))
5545 (set (match_dup 0) (xor:SI (match_dup 3) (match_dup 1)))]
5547 operands[4] = GEN_INT (~INTVAL (operands[2]));
5550 ;; Split DImode logical operations requiring two instructions.
5552 [(set (match_operand:V64I 0 "register_operand" "")
5553 (match_operator:V64I 1 "cc_arith_operator" ; AND, IOR, XOR
5554 [(match_operand:V64I 2 "register_operand" "")
5555 (match_operand:V64I 3 "arith_double_operand" "")]))]
5558 && ((GET_CODE (operands[0]) == REG
5559 && REGNO (operands[0]) < 32)
5560 || (GET_CODE (operands[0]) == SUBREG
5561 && GET_CODE (SUBREG_REG (operands[0])) == REG
5562 && REGNO (SUBREG_REG (operands[0])) < 32))"
5563 [(set (match_dup 4) (match_op_dup:SI 1 [(match_dup 6) (match_dup 8)]))
5564 (set (match_dup 5) (match_op_dup:SI 1 [(match_dup 7) (match_dup 9)]))]
5566 operands[4] = gen_highpart (SImode, operands[0]);
5567 operands[5] = gen_lowpart (SImode, operands[0]);
5568 operands[6] = gen_highpart (SImode, operands[2]);
5569 operands[7] = gen_lowpart (SImode, operands[2]);
5570 #if HOST_BITS_PER_WIDE_INT == 32
5571 if (GET_CODE (operands[3]) == CONST_INT && <V64I:MODE>mode == DImode)
5573 if (INTVAL (operands[3]) < 0)
5574 operands[8] = constm1_rtx;
5576 operands[8] = const0_rtx;
5580 operands[8] = gen_highpart_mode (SImode, <V64I:MODE>mode, operands[3]);
5581 operands[9] = gen_lowpart (SImode, operands[3]);
5584 ;; xnor patterns. Note that (a ^ ~b) == (~a ^ b) == ~(a ^ b).
5585 ;; Combine now canonicalizes to the rightmost expression.
5586 (define_insn_and_split "*xor_not_<V64I:mode>_sp32"
5587 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5588 (not:V64I (xor:V64I (match_operand:V64I 1 "register_operand" "r,b")
5589 (match_operand:V64I 2 "register_operand" "r,b"))))]
5594 "&& reload_completed
5595 && ((GET_CODE (operands[0]) == REG
5596 && REGNO (operands[0]) < 32)
5597 || (GET_CODE (operands[0]) == SUBREG
5598 && GET_CODE (SUBREG_REG (operands[0])) == REG
5599 && REGNO (SUBREG_REG (operands[0])) < 32))"
5600 [(set (match_dup 3) (not:SI (xor:SI (match_dup 4) (match_dup 5))))
5601 (set (match_dup 6) (not:SI (xor:SI (match_dup 7) (match_dup 8))))]
5602 "operands[3] = gen_highpart (SImode, operands[0]);
5603 operands[4] = gen_highpart (SImode, operands[1]);
5604 operands[5] = gen_highpart (SImode, operands[2]);
5605 operands[6] = gen_lowpart (SImode, operands[0]);
5606 operands[7] = gen_lowpart (SImode, operands[1]);
5607 operands[8] = gen_lowpart (SImode, operands[2]);"
5608 [(set_attr "type" "*,fga")
5609 (set_attr "length" "2,*")
5610 (set_attr "fptype" "*,double")])
5612 (define_insn "*xor_not_<V64I:mode>_sp64"
5613 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5614 (not:V64I (xor:V64I (match_operand:V64I 1 "register_or_zero_operand" "rJ,b")
5615 (match_operand:V64I 2 "arith_operand" "rI,b"))))]
5620 [(set_attr "type" "*,fga")
5621 (set_attr "fptype" "*,double")])
5623 (define_insn "*xor_not_<V32I:mode>"
5624 [(set (match_operand:V32I 0 "register_operand" "=r,d")
5625 (not:V32I (xor:V32I (match_operand:V32I 1 "register_or_zero_operand" "rJ,d")
5626 (match_operand:V32I 2 "arith_operand" "rI,d"))))]
5631 [(set_attr "type" "*,fga")
5632 (set_attr "fptype" "*,single")])
5634 ;; These correspond to the above in the case where we also (or only)
5635 ;; want to set the condition code.
5637 (define_insn "*cmp_cc_arith_op"
5640 (match_operator:SI 2 "cc_arith_operator"
5641 [(match_operand:SI 0 "arith_operand" "%r")
5642 (match_operand:SI 1 "arith_operand" "rI")])
5645 "%A2cc\t%0, %1, %%g0"
5646 [(set_attr "type" "compare")])
5648 (define_insn "*cmp_ccx_arith_op"
5651 (match_operator:DI 2 "cc_arith_operator"
5652 [(match_operand:DI 0 "arith_operand" "%r")
5653 (match_operand:DI 1 "arith_operand" "rI")])
5656 "%A2cc\t%0, %1, %%g0"
5657 [(set_attr "type" "compare")])
5659 (define_insn "*cmp_cc_arith_op_set"
5662 (match_operator:SI 3 "cc_arith_operator"
5663 [(match_operand:SI 1 "arith_operand" "%r")
5664 (match_operand:SI 2 "arith_operand" "rI")])
5666 (set (match_operand:SI 0 "register_operand" "=r")
5667 (match_operator:SI 4 "cc_arith_operator" [(match_dup 1) (match_dup 2)]))]
5668 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
5670 [(set_attr "type" "compare")])
5672 (define_insn "*cmp_ccx_arith_op_set"
5675 (match_operator:DI 3 "cc_arith_operator"
5676 [(match_operand:DI 1 "arith_operand" "%r")
5677 (match_operand:DI 2 "arith_operand" "rI")])
5679 (set (match_operand:DI 0 "register_operand" "=r")
5680 (match_operator:DI 4 "cc_arith_operator" [(match_dup 1) (match_dup 2)]))]
5681 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
5683 [(set_attr "type" "compare")])
5685 (define_insn "*cmp_cc_xor_not"
5688 (not:SI (xor:SI (match_operand:SI 0 "register_or_zero_operand" "%rJ")
5689 (match_operand:SI 1 "arith_operand" "rI")))
5692 "xnorcc\t%r0, %1, %%g0"
5693 [(set_attr "type" "compare")])
5695 (define_insn "*cmp_ccx_xor_not"
5698 (not:DI (xor:DI (match_operand:DI 0 "register_or_zero_operand" "%rJ")
5699 (match_operand:DI 1 "arith_operand" "rI")))
5702 "xnorcc\t%r0, %1, %%g0"
5703 [(set_attr "type" "compare")])
5705 (define_insn "*cmp_cc_xor_not_set"
5708 (not:SI (xor:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ")
5709 (match_operand:SI 2 "arith_operand" "rI")))
5711 (set (match_operand:SI 0 "register_operand" "=r")
5712 (not:SI (xor:SI (match_dup 1) (match_dup 2))))]
5714 "xnorcc\t%r1, %2, %0"
5715 [(set_attr "type" "compare")])
5717 (define_insn "*cmp_ccx_xor_not_set"
5720 (not:DI (xor:DI (match_operand:DI 1 "register_or_zero_operand" "%rJ")
5721 (match_operand:DI 2 "arith_operand" "rI")))
5723 (set (match_operand:DI 0 "register_operand" "=r")
5724 (not:DI (xor:DI (match_dup 1) (match_dup 2))))]
5726 "xnorcc\t%r1, %2, %0"
5727 [(set_attr "type" "compare")])
5729 (define_insn "*cmp_cc_arith_op_not"
5732 (match_operator:SI 2 "cc_arith_not_operator"
5733 [(not:SI (match_operand:SI 0 "arith_operand" "rI"))
5734 (match_operand:SI 1 "register_or_zero_operand" "rJ")])
5737 "%B2cc\t%r1, %0, %%g0"
5738 [(set_attr "type" "compare")])
5740 (define_insn "*cmp_ccx_arith_op_not"
5743 (match_operator:DI 2 "cc_arith_not_operator"
5744 [(not:DI (match_operand:DI 0 "arith_operand" "rI"))
5745 (match_operand:DI 1 "register_or_zero_operand" "rJ")])
5748 "%B2cc\t%r1, %0, %%g0"
5749 [(set_attr "type" "compare")])
5751 (define_insn "*cmp_cc_arith_op_not_set"
5754 (match_operator:SI 3 "cc_arith_not_operator"
5755 [(not:SI (match_operand:SI 1 "arith_operand" "rI"))
5756 (match_operand:SI 2 "register_or_zero_operand" "rJ")])
5758 (set (match_operand:SI 0 "register_operand" "=r")
5759 (match_operator:SI 4 "cc_arith_not_operator"
5760 [(not:SI (match_dup 1)) (match_dup 2)]))]
5761 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
5762 "%B3cc\t%r2, %1, %0"
5763 [(set_attr "type" "compare")])
5765 (define_insn "*cmp_ccx_arith_op_not_set"
5768 (match_operator:DI 3 "cc_arith_not_operator"
5769 [(not:DI (match_operand:DI 1 "arith_operand" "rI"))
5770 (match_operand:DI 2 "register_or_zero_operand" "rJ")])
5772 (set (match_operand:DI 0 "register_operand" "=r")
5773 (match_operator:DI 4 "cc_arith_not_operator"
5774 [(not:DI (match_dup 1)) (match_dup 2)]))]
5775 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
5776 "%B3cc\t%r2, %1, %0"
5777 [(set_attr "type" "compare")])
5779 ;; We cannot use the "neg" pseudo insn because the Sun assembler
5780 ;; does not know how to make it work for constants.
5782 (define_expand "negdi2"
5783 [(set (match_operand:DI 0 "register_operand" "=r")
5784 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
5787 if (! TARGET_ARCH64)
5789 emit_insn (gen_rtx_PARALLEL
5792 gen_rtx_SET (VOIDmode, operand0,
5793 gen_rtx_NEG (DImode, operand1)),
5794 gen_rtx_CLOBBER (VOIDmode,
5795 gen_rtx_REG (CCmode,
5801 (define_insn_and_split "*negdi2_sp32"
5802 [(set (match_operand:DI 0 "register_operand" "=r")
5803 (neg:DI (match_operand:DI 1 "register_operand" "r")))
5804 (clobber (reg:CC 100))]
5807 "&& reload_completed"
5808 [(parallel [(set (reg:CC_NOOV 100)
5809 (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 5))
5811 (set (match_dup 4) (minus:SI (const_int 0) (match_dup 5)))])
5812 (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
5813 (ltu:SI (reg:CC 100) (const_int 0))))]
5814 "operands[2] = gen_highpart (SImode, operands[0]);
5815 operands[3] = gen_highpart (SImode, operands[1]);
5816 operands[4] = gen_lowpart (SImode, operands[0]);
5817 operands[5] = gen_lowpart (SImode, operands[1]);"
5818 [(set_attr "length" "2")])
5820 (define_insn "*negdi2_sp64"
5821 [(set (match_operand:DI 0 "register_operand" "=r")
5822 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
5824 "sub\t%%g0, %1, %0")
5826 (define_insn "negsi2"
5827 [(set (match_operand:SI 0 "register_operand" "=r")
5828 (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
5830 "sub\t%%g0, %1, %0")
5832 (define_insn "*cmp_cc_neg"
5833 [(set (reg:CC_NOOV 100)
5834 (compare:CC_NOOV (neg:SI (match_operand:SI 0 "arith_operand" "rI"))
5837 "subcc\t%%g0, %0, %%g0"
5838 [(set_attr "type" "compare")])
5840 (define_insn "*cmp_ccx_neg"
5841 [(set (reg:CCX_NOOV 100)
5842 (compare:CCX_NOOV (neg:DI (match_operand:DI 0 "arith_operand" "rI"))
5845 "subcc\t%%g0, %0, %%g0"
5846 [(set_attr "type" "compare")])
5848 (define_insn "*cmp_cc_set_neg"
5849 [(set (reg:CC_NOOV 100)
5850 (compare:CC_NOOV (neg:SI (match_operand:SI 1 "arith_operand" "rI"))
5852 (set (match_operand:SI 0 "register_operand" "=r")
5853 (neg:SI (match_dup 1)))]
5855 "subcc\t%%g0, %1, %0"
5856 [(set_attr "type" "compare")])
5858 (define_insn "*cmp_ccx_set_neg"
5859 [(set (reg:CCX_NOOV 100)
5860 (compare:CCX_NOOV (neg:DI (match_operand:DI 1 "arith_operand" "rI"))
5862 (set (match_operand:DI 0 "register_operand" "=r")
5863 (neg:DI (match_dup 1)))]
5865 "subcc\t%%g0, %1, %0"
5866 [(set_attr "type" "compare")])
5868 ;; We cannot use the "not" pseudo insn because the Sun assembler
5869 ;; does not know how to make it work for constants.
5870 (define_expand "one_cmpl<V64I:mode>2"
5871 [(set (match_operand:V64I 0 "register_operand" "")
5872 (not:V64I (match_operand:V64I 1 "register_operand" "")))]
5876 (define_insn_and_split "*one_cmpl<V64I:mode>2_sp32"
5877 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5878 (not:V64I (match_operand:V64I 1 "register_operand" "r,b")))]
5883 "&& reload_completed
5884 && ((GET_CODE (operands[0]) == REG
5885 && REGNO (operands[0]) < 32)
5886 || (GET_CODE (operands[0]) == SUBREG
5887 && GET_CODE (SUBREG_REG (operands[0])) == REG
5888 && REGNO (SUBREG_REG (operands[0])) < 32))"
5889 [(set (match_dup 2) (not:SI (xor:SI (match_dup 3) (const_int 0))))
5890 (set (match_dup 4) (not:SI (xor:SI (match_dup 5) (const_int 0))))]
5891 "operands[2] = gen_highpart (SImode, operands[0]);
5892 operands[3] = gen_highpart (SImode, operands[1]);
5893 operands[4] = gen_lowpart (SImode, operands[0]);
5894 operands[5] = gen_lowpart (SImode, operands[1]);"
5895 [(set_attr "type" "*,fga")
5896 (set_attr "length" "2,*")
5897 (set_attr "fptype" "*,double")])
5899 (define_insn "*one_cmpl<V64I:mode>2_sp64"
5900 [(set (match_operand:V64I 0 "register_operand" "=r,b")
5901 (not:V64I (match_operand:V64I 1 "arith_operand" "rI,b")))]
5906 [(set_attr "type" "*,fga")
5907 (set_attr "fptype" "*,double")])
5909 (define_insn "one_cmpl<V32I:mode>2"
5910 [(set (match_operand:V32I 0 "register_operand" "=r,d")
5911 (not:V32I (match_operand:V32I 1 "arith_operand" "rI,d")))]
5916 [(set_attr "type" "*,fga")
5917 (set_attr "fptype" "*,single")])
5919 (define_insn "*cmp_cc_not"
5921 (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI"))
5924 "xnorcc\t%%g0, %0, %%g0"
5925 [(set_attr "type" "compare")])
5927 (define_insn "*cmp_ccx_not"
5929 (compare:CCX (not:DI (match_operand:DI 0 "arith_operand" "rI"))
5932 "xnorcc\t%%g0, %0, %%g0"
5933 [(set_attr "type" "compare")])
5935 (define_insn "*cmp_cc_set_not"
5937 (compare:CC (not:SI (match_operand:SI 1 "arith_operand" "rI"))
5939 (set (match_operand:SI 0 "register_operand" "=r")
5940 (not:SI (match_dup 1)))]
5942 "xnorcc\t%%g0, %1, %0"
5943 [(set_attr "type" "compare")])
5945 (define_insn "*cmp_ccx_set_not"
5947 (compare:CCX (not:DI (match_operand:DI 1 "arith_operand" "rI"))
5949 (set (match_operand:DI 0 "register_operand" "=r")
5950 (not:DI (match_dup 1)))]
5952 "xnorcc\t%%g0, %1, %0"
5953 [(set_attr "type" "compare")])
5955 (define_insn "*cmp_cc_set"
5956 [(set (match_operand:SI 0 "register_operand" "=r")
5957 (match_operand:SI 1 "register_operand" "r"))
5959 (compare:CC (match_dup 1)
5963 [(set_attr "type" "compare")])
5965 (define_insn "*cmp_ccx_set64"
5966 [(set (match_operand:DI 0 "register_operand" "=r")
5967 (match_operand:DI 1 "register_operand" "r"))
5969 (compare:CCX (match_dup 1)
5973 [(set_attr "type" "compare")])
5976 ;; Floating point arithmetic instructions.
5978 (define_expand "addtf3"
5979 [(set (match_operand:TF 0 "nonimmediate_operand" "")
5980 (plus:TF (match_operand:TF 1 "general_operand" "")
5981 (match_operand:TF 2 "general_operand" "")))]
5982 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5983 "emit_tfmode_binop (PLUS, operands); DONE;")
5985 (define_insn "*addtf3_hq"
5986 [(set (match_operand:TF 0 "register_operand" "=e")
5987 (plus:TF (match_operand:TF 1 "register_operand" "e")
5988 (match_operand:TF 2 "register_operand" "e")))]
5989 "TARGET_FPU && TARGET_HARD_QUAD"
5991 [(set_attr "type" "fp")])
5993 (define_insn "adddf3"
5994 [(set (match_operand:DF 0 "register_operand" "=e")
5995 (plus:DF (match_operand:DF 1 "register_operand" "e")
5996 (match_operand:DF 2 "register_operand" "e")))]
5999 [(set_attr "type" "fp")
6000 (set_attr "fptype" "double")])
6002 (define_insn "addsf3"
6003 [(set (match_operand:SF 0 "register_operand" "=f")
6004 (plus:SF (match_operand:SF 1 "register_operand" "f")
6005 (match_operand:SF 2 "register_operand" "f")))]
6008 [(set_attr "type" "fp")])
6010 (define_expand "subtf3"
6011 [(set (match_operand:TF 0 "nonimmediate_operand" "")
6012 (minus:TF (match_operand:TF 1 "general_operand" "")
6013 (match_operand:TF 2 "general_operand" "")))]
6014 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6015 "emit_tfmode_binop (MINUS, operands); DONE;")
6017 (define_insn "*subtf3_hq"
6018 [(set (match_operand:TF 0 "register_operand" "=e")
6019 (minus:TF (match_operand:TF 1 "register_operand" "e")
6020 (match_operand:TF 2 "register_operand" "e")))]
6021 "TARGET_FPU && TARGET_HARD_QUAD"
6023 [(set_attr "type" "fp")])
6025 (define_insn "subdf3"
6026 [(set (match_operand:DF 0 "register_operand" "=e")
6027 (minus:DF (match_operand:DF 1 "register_operand" "e")
6028 (match_operand:DF 2 "register_operand" "e")))]
6031 [(set_attr "type" "fp")
6032 (set_attr "fptype" "double")])
6034 (define_insn "subsf3"
6035 [(set (match_operand:SF 0 "register_operand" "=f")
6036 (minus:SF (match_operand:SF 1 "register_operand" "f")
6037 (match_operand:SF 2 "register_operand" "f")))]
6040 [(set_attr "type" "fp")])
6042 (define_expand "multf3"
6043 [(set (match_operand:TF 0 "nonimmediate_operand" "")
6044 (mult:TF (match_operand:TF 1 "general_operand" "")
6045 (match_operand:TF 2 "general_operand" "")))]
6046 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6047 "emit_tfmode_binop (MULT, operands); DONE;")
6049 (define_insn "*multf3_hq"
6050 [(set (match_operand:TF 0 "register_operand" "=e")
6051 (mult:TF (match_operand:TF 1 "register_operand" "e")
6052 (match_operand:TF 2 "register_operand" "e")))]
6053 "TARGET_FPU && TARGET_HARD_QUAD"
6055 [(set_attr "type" "fpmul")])
6057 (define_insn "muldf3"
6058 [(set (match_operand:DF 0 "register_operand" "=e")
6059 (mult:DF (match_operand:DF 1 "register_operand" "e")
6060 (match_operand:DF 2 "register_operand" "e")))]
6063 [(set_attr "type" "fpmul")
6064 (set_attr "fptype" "double")])
6066 (define_insn "mulsf3"
6067 [(set (match_operand:SF 0 "register_operand" "=f")
6068 (mult:SF (match_operand:SF 1 "register_operand" "f")
6069 (match_operand:SF 2 "register_operand" "f")))]
6072 [(set_attr "type" "fpmul")])
6074 (define_insn "*muldf3_extend"
6075 [(set (match_operand:DF 0 "register_operand" "=e")
6076 (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "f"))
6077 (float_extend:DF (match_operand:SF 2 "register_operand" "f"))))]
6078 "(TARGET_V8 || TARGET_V9) && TARGET_FPU"
6079 "fsmuld\t%1, %2, %0"
6080 [(set_attr "type" "fpmul")
6081 (set_attr "fptype" "double")])
6083 (define_insn "*multf3_extend"
6084 [(set (match_operand:TF 0 "register_operand" "=e")
6085 (mult:TF (float_extend:TF (match_operand:DF 1 "register_operand" "e"))
6086 (float_extend:TF (match_operand:DF 2 "register_operand" "e"))))]
6087 "(TARGET_V8 || TARGET_V9) && TARGET_FPU && TARGET_HARD_QUAD"
6088 "fdmulq\t%1, %2, %0"
6089 [(set_attr "type" "fpmul")])
6091 (define_expand "divtf3"
6092 [(set (match_operand:TF 0 "nonimmediate_operand" "")
6093 (div:TF (match_operand:TF 1 "general_operand" "")
6094 (match_operand:TF 2 "general_operand" "")))]
6095 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6096 "emit_tfmode_binop (DIV, operands); DONE;")
6098 ;; don't have timing for quad-prec. divide.
6099 (define_insn "*divtf3_hq"
6100 [(set (match_operand:TF 0 "register_operand" "=e")
6101 (div:TF (match_operand:TF 1 "register_operand" "e")
6102 (match_operand:TF 2 "register_operand" "e")))]
6103 "TARGET_FPU && TARGET_HARD_QUAD"
6105 [(set_attr "type" "fpdivd")])
6107 (define_insn "divdf3"
6108 [(set (match_operand:DF 0 "register_operand" "=e")
6109 (div:DF (match_operand:DF 1 "register_operand" "e")
6110 (match_operand:DF 2 "register_operand" "e")))]
6113 [(set_attr "type" "fpdivd")
6114 (set_attr "fptype" "double")])
6116 (define_insn "divsf3"
6117 [(set (match_operand:SF 0 "register_operand" "=f")
6118 (div:SF (match_operand:SF 1 "register_operand" "f")
6119 (match_operand:SF 2 "register_operand" "f")))]
6122 [(set_attr "type" "fpdivs")])
6124 (define_expand "negtf2"
6125 [(set (match_operand:TF 0 "register_operand" "=e,e")
6126 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
6130 (define_insn_and_split "*negtf2_notv9"
6131 [(set (match_operand:TF 0 "register_operand" "=e,e")
6132 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
6133 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
6139 "&& reload_completed
6140 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6141 [(set (match_dup 2) (neg:SF (match_dup 3)))
6142 (set (match_dup 4) (match_dup 5))
6143 (set (match_dup 6) (match_dup 7))]
6144 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6145 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6146 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6147 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
6148 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6149 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6150 [(set_attr "type" "fpmove,*")
6151 (set_attr "length" "*,2")])
6153 (define_insn_and_split "*negtf2_v9"
6154 [(set (match_operand:TF 0 "register_operand" "=e,e")
6155 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
6156 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
6157 "TARGET_FPU && TARGET_V9"
6161 "&& reload_completed
6162 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6163 [(set (match_dup 2) (neg:DF (match_dup 3)))
6164 (set (match_dup 4) (match_dup 5))]
6165 "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
6166 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
6167 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6168 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6169 [(set_attr "type" "fpmove,*")
6170 (set_attr "length" "*,2")
6171 (set_attr "fptype" "double")])
6173 (define_expand "negdf2"
6174 [(set (match_operand:DF 0 "register_operand" "")
6175 (neg:DF (match_operand:DF 1 "register_operand" "")))]
6179 (define_insn_and_split "*negdf2_notv9"
6180 [(set (match_operand:DF 0 "register_operand" "=e,e")
6181 (neg:DF (match_operand:DF 1 "register_operand" "0,e")))]
6182 "TARGET_FPU && ! TARGET_V9"
6186 "&& reload_completed
6187 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6188 [(set (match_dup 2) (neg:SF (match_dup 3)))
6189 (set (match_dup 4) (match_dup 5))]
6190 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6191 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6192 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6193 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);"
6194 [(set_attr "type" "fpmove,*")
6195 (set_attr "length" "*,2")])
6197 (define_insn "*negdf2_v9"
6198 [(set (match_operand:DF 0 "register_operand" "=e")
6199 (neg:DF (match_operand:DF 1 "register_operand" "e")))]
6200 "TARGET_FPU && TARGET_V9"
6202 [(set_attr "type" "fpmove")
6203 (set_attr "fptype" "double")])
6205 (define_insn "negsf2"
6206 [(set (match_operand:SF 0 "register_operand" "=f")
6207 (neg:SF (match_operand:SF 1 "register_operand" "f")))]
6210 [(set_attr "type" "fpmove")])
6212 (define_expand "abstf2"
6213 [(set (match_operand:TF 0 "register_operand" "")
6214 (abs:TF (match_operand:TF 1 "register_operand" "")))]
6218 (define_insn_and_split "*abstf2_notv9"
6219 [(set (match_operand:TF 0 "register_operand" "=e,e")
6220 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6221 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
6222 "TARGET_FPU && ! TARGET_V9"
6226 "&& reload_completed
6227 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6228 [(set (match_dup 2) (abs:SF (match_dup 3)))
6229 (set (match_dup 4) (match_dup 5))
6230 (set (match_dup 6) (match_dup 7))]
6231 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6232 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6233 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6234 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
6235 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6236 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6237 [(set_attr "type" "fpmove,*")
6238 (set_attr "length" "*,2")])
6240 (define_insn "*abstf2_hq_v9"
6241 [(set (match_operand:TF 0 "register_operand" "=e,e")
6242 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6243 "TARGET_FPU && TARGET_V9 && TARGET_HARD_QUAD"
6247 [(set_attr "type" "fpmove")
6248 (set_attr "fptype" "double,*")])
6250 (define_insn_and_split "*abstf2_v9"
6251 [(set (match_operand:TF 0 "register_operand" "=e,e")
6252 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6253 "TARGET_FPU && TARGET_V9 && !TARGET_HARD_QUAD"
6257 "&& reload_completed
6258 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6259 [(set (match_dup 2) (abs:DF (match_dup 3)))
6260 (set (match_dup 4) (match_dup 5))]
6261 "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
6262 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
6263 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6264 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6265 [(set_attr "type" "fpmove,*")
6266 (set_attr "length" "*,2")
6267 (set_attr "fptype" "double,*")])
6269 (define_expand "absdf2"
6270 [(set (match_operand:DF 0 "register_operand" "")
6271 (abs:DF (match_operand:DF 1 "register_operand" "")))]
6275 (define_insn_and_split "*absdf2_notv9"
6276 [(set (match_operand:DF 0 "register_operand" "=e,e")
6277 (abs:DF (match_operand:DF 1 "register_operand" "0,e")))]
6278 "TARGET_FPU && ! TARGET_V9"
6282 "&& reload_completed
6283 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6284 [(set (match_dup 2) (abs:SF (match_dup 3)))
6285 (set (match_dup 4) (match_dup 5))]
6286 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6287 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6288 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6289 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);"
6290 [(set_attr "type" "fpmove,*")
6291 (set_attr "length" "*,2")])
6293 (define_insn "*absdf2_v9"
6294 [(set (match_operand:DF 0 "register_operand" "=e")
6295 (abs:DF (match_operand:DF 1 "register_operand" "e")))]
6296 "TARGET_FPU && TARGET_V9"
6298 [(set_attr "type" "fpmove")
6299 (set_attr "fptype" "double")])
6301 (define_insn "abssf2"
6302 [(set (match_operand:SF 0 "register_operand" "=f")
6303 (abs:SF (match_operand:SF 1 "register_operand" "f")))]
6306 [(set_attr "type" "fpmove")])
6308 (define_expand "sqrttf2"
6309 [(set (match_operand:TF 0 "nonimmediate_operand" "")
6310 (sqrt:TF (match_operand:TF 1 "general_operand" "")))]
6311 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6312 "emit_tfmode_unop (SQRT, operands); DONE;")
6314 (define_insn "*sqrttf2_hq"
6315 [(set (match_operand:TF 0 "register_operand" "=e")
6316 (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
6317 "TARGET_FPU && TARGET_HARD_QUAD"
6319 [(set_attr "type" "fpsqrtd")])
6321 (define_insn "sqrtdf2"
6322 [(set (match_operand:DF 0 "register_operand" "=e")
6323 (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
6326 [(set_attr "type" "fpsqrtd")
6327 (set_attr "fptype" "double")])
6329 (define_insn "sqrtsf2"
6330 [(set (match_operand:SF 0 "register_operand" "=f")
6331 (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
6334 [(set_attr "type" "fpsqrts")])
6337 ;; Arithmetic shift instructions.
6339 (define_insn "ashlsi3"
6340 [(set (match_operand:SI 0 "register_operand" "=r")
6341 (ashift:SI (match_operand:SI 1 "register_operand" "r")
6342 (match_operand:SI 2 "arith_operand" "rI")))]
6345 if (GET_CODE (operands[2]) == CONST_INT)
6346 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6347 return "sll\t%1, %2, %0";
6350 (if_then_else (match_operand 2 "const_one_operand" "")
6351 (const_string "ialu") (const_string "shift")))])
6353 (define_expand "ashldi3"
6354 [(set (match_operand:DI 0 "register_operand" "=r")
6355 (ashift:DI (match_operand:DI 1 "register_operand" "r")
6356 (match_operand:SI 2 "arith_operand" "rI")))]
6357 "TARGET_ARCH64 || TARGET_V8PLUS"
6359 if (! TARGET_ARCH64)
6361 if (GET_CODE (operands[2]) == CONST_INT)
6363 emit_insn (gen_ashldi3_v8plus (operands[0], operands[1], operands[2]));
6368 (define_insn "*ashldi3_sp64"
6369 [(set (match_operand:DI 0 "register_operand" "=r")
6370 (ashift:DI (match_operand:DI 1 "register_operand" "r")
6371 (match_operand:SI 2 "arith_operand" "rI")))]
6374 if (GET_CODE (operands[2]) == CONST_INT)
6375 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
6376 return "sllx\t%1, %2, %0";
6379 (if_then_else (match_operand 2 "const_one_operand" "")
6380 (const_string "ialu") (const_string "shift")))])
6383 (define_insn "ashldi3_v8plus"
6384 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
6385 (ashift:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
6386 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
6387 (clobber (match_scratch:SI 3 "=X,X,&h"))]
6389 "* return output_v8plus_shift (operands, insn, \"sllx\");"
6390 [(set_attr "type" "multi")
6391 (set_attr "length" "5,5,6")])
6393 ;; Optimize (1LL<<x)-1
6394 ;; XXX this also needs to be fixed to handle equal subregs
6395 ;; XXX first before we could re-enable it.
6397 ; [(set (match_operand:DI 0 "register_operand" "=h")
6398 ; (plus:DI (ashift:DI (const_int 1)
6399 ; (match_operand:SI 1 "arith_operand" "rI"))
6401 ; "0 && TARGET_V8PLUS"
6403 ; if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == REGNO (operands[0]))
6404 ; return "mov\t1, %L0\;sllx\t%L0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
6405 ; return "mov\t1, %H0\;sllx\t%H0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
6407 ; [(set_attr "type" "multi")
6408 ; (set_attr "length" "4")])
6410 (define_insn "*cmp_cc_ashift_1"
6411 [(set (reg:CC_NOOV 100)
6412 (compare:CC_NOOV (ashift:SI (match_operand:SI 0 "register_operand" "r")
6416 "addcc\t%0, %0, %%g0"
6417 [(set_attr "type" "compare")])
6419 (define_insn "*cmp_cc_set_ashift_1"
6420 [(set (reg:CC_NOOV 100)
6421 (compare:CC_NOOV (ashift:SI (match_operand:SI 1 "register_operand" "r")
6424 (set (match_operand:SI 0 "register_operand" "=r")
6425 (ashift:SI (match_dup 1) (const_int 1)))]
6428 [(set_attr "type" "compare")])
6430 (define_insn "ashrsi3"
6431 [(set (match_operand:SI 0 "register_operand" "=r")
6432 (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
6433 (match_operand:SI 2 "arith_operand" "rI")))]
6436 if (GET_CODE (operands[2]) == CONST_INT)
6437 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6438 return "sra\t%1, %2, %0";
6440 [(set_attr "type" "shift")])
6442 (define_insn "*ashrsi3_extend"
6443 [(set (match_operand:DI 0 "register_operand" "=r")
6444 (sign_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
6445 (match_operand:SI 2 "arith_operand" "r"))))]
6448 [(set_attr "type" "shift")])
6450 ;; This handles the case as above, but with constant shift instead of
6451 ;; register. Combiner "simplifies" it for us a little bit though.
6452 (define_insn "*ashrsi3_extend2"
6453 [(set (match_operand:DI 0 "register_operand" "=r")
6454 (ashiftrt:DI (ashift:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
6456 (match_operand:SI 2 "small_int_operand" "I")))]
6457 "TARGET_ARCH64 && INTVAL (operands[2]) >= 32 && INTVAL (operands[2]) < 64"
6459 operands[2] = GEN_INT (INTVAL (operands[2]) - 32);
6460 return "sra\t%1, %2, %0";
6462 [(set_attr "type" "shift")])
6464 (define_expand "ashrdi3"
6465 [(set (match_operand:DI 0 "register_operand" "=r")
6466 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
6467 (match_operand:SI 2 "arith_operand" "rI")))]
6468 "TARGET_ARCH64 || TARGET_V8PLUS"
6470 if (! TARGET_ARCH64)
6472 if (GET_CODE (operands[2]) == CONST_INT)
6473 FAIL; /* prefer generic code in this case */
6474 emit_insn (gen_ashrdi3_v8plus (operands[0], operands[1], operands[2]));
6479 (define_insn "*ashrdi3_sp64"
6480 [(set (match_operand:DI 0 "register_operand" "=r")
6481 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
6482 (match_operand:SI 2 "arith_operand" "rI")))]
6486 if (GET_CODE (operands[2]) == CONST_INT)
6487 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
6488 return "srax\t%1, %2, %0";
6490 [(set_attr "type" "shift")])
6493 (define_insn "ashrdi3_v8plus"
6494 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
6495 (ashiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
6496 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
6497 (clobber (match_scratch:SI 3 "=X,X,&h"))]
6499 "* return output_v8plus_shift (operands, insn, \"srax\");"
6500 [(set_attr "type" "multi")
6501 (set_attr "length" "5,5,6")])
6503 (define_insn "lshrsi3"
6504 [(set (match_operand:SI 0 "register_operand" "=r")
6505 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
6506 (match_operand:SI 2 "arith_operand" "rI")))]
6509 if (GET_CODE (operands[2]) == CONST_INT)
6510 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6511 return "srl\t%1, %2, %0";
6513 [(set_attr "type" "shift")])
6515 ;; This handles the case where
6516 ;; (zero_extend:DI (lshiftrt:SI (match_operand:SI) (match_operand:SI))),
6517 ;; but combiner "simplifies" it for us.
6518 (define_insn "*lshrsi3_extend"
6519 [(set (match_operand:DI 0 "register_operand" "=r")
6520 (and:DI (subreg:DI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
6521 (match_operand:SI 2 "arith_operand" "r")) 0)
6522 (match_operand 3 "const_int_operand" "")))]
6523 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) == 0xffffffff"
6525 [(set_attr "type" "shift")])
6527 ;; This handles the case where
6528 ;; (lshiftrt:DI (zero_extend:DI (match_operand:SI)) (const_int >=0 < 32))
6529 ;; but combiner "simplifies" it for us.
6530 (define_insn "*lshrsi3_extend2"
6531 [(set (match_operand:DI 0 "register_operand" "=r")
6532 (zero_extract:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
6533 (match_operand 2 "small_int_operand" "I")
6535 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
6537 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
6538 return "srl\t%1, %2, %0";
6540 [(set_attr "type" "shift")])
6542 (define_expand "lshrdi3"
6543 [(set (match_operand:DI 0 "register_operand" "=r")
6544 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6545 (match_operand:SI 2 "arith_operand" "rI")))]
6546 "TARGET_ARCH64 || TARGET_V8PLUS"
6548 if (! TARGET_ARCH64)
6550 if (GET_CODE (operands[2]) == CONST_INT)
6552 emit_insn (gen_lshrdi3_v8plus (operands[0], operands[1], operands[2]));
6557 (define_insn "*lshrdi3_sp64"
6558 [(set (match_operand:DI 0 "register_operand" "=r")
6559 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6560 (match_operand:SI 2 "arith_operand" "rI")))]
6563 if (GET_CODE (operands[2]) == CONST_INT)
6564 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
6565 return "srlx\t%1, %2, %0";
6567 [(set_attr "type" "shift")])
6570 (define_insn "lshrdi3_v8plus"
6571 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
6572 (lshiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
6573 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
6574 (clobber (match_scratch:SI 3 "=X,X,&h"))]
6576 "* return output_v8plus_shift (operands, insn, \"srlx\");"
6577 [(set_attr "type" "multi")
6578 (set_attr "length" "5,5,6")])
6581 [(set (match_operand:SI 0 "register_operand" "=r")
6582 (ashiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6584 (match_operand:SI 2 "small_int_operand" "I")))]
6585 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
6587 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
6588 return "srax\t%1, %2, %0";
6590 [(set_attr "type" "shift")])
6593 [(set (match_operand:SI 0 "register_operand" "=r")
6594 (lshiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
6596 (match_operand:SI 2 "small_int_operand" "I")))]
6597 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
6599 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
6600 return "srlx\t%1, %2, %0";
6602 [(set_attr "type" "shift")])
6605 [(set (match_operand:SI 0 "register_operand" "=r")
6606 (ashiftrt:SI (subreg:SI (ashiftrt: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 "srax\t%1, %2, %0";
6618 [(set_attr "type" "shift")])
6621 [(set (match_operand:SI 0 "register_operand" "=r")
6622 (lshiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6623 (match_operand:SI 2 "small_int_operand" "I")) 4)
6624 (match_operand:SI 3 "small_int_operand" "I")))]
6626 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
6627 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
6628 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
6630 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
6632 return "srlx\t%1, %2, %0";
6634 [(set_attr "type" "shift")])
6637 ;; Unconditional and other jump instructions.
6640 [(set (pc) (label_ref (match_operand 0 "" "")))]
6642 "* return output_ubranch (operands[0], 0, insn);"
6643 [(set_attr "type" "uncond_branch")])
6645 (define_expand "tablejump"
6646 [(parallel [(set (pc) (match_operand 0 "register_operand" "r"))
6647 (use (label_ref (match_operand 1 "" "")))])]
6650 gcc_assert (GET_MODE (operands[0]) == CASE_VECTOR_MODE);
6652 /* In pic mode, our address differences are against the base of the
6653 table. Add that base value back in; CSE ought to be able to combine
6654 the two address loads. */
6658 tmp = gen_rtx_LABEL_REF (Pmode, operands[1]);
6660 if (CASE_VECTOR_MODE != Pmode)
6661 tmp2 = gen_rtx_SIGN_EXTEND (Pmode, tmp2);
6662 tmp = gen_rtx_PLUS (Pmode, tmp2, tmp);
6663 operands[0] = memory_address (Pmode, tmp);
6667 (define_insn "*tablejump_sp32"
6668 [(set (pc) (match_operand:SI 0 "address_operand" "p"))
6669 (use (label_ref (match_operand 1 "" "")))]
6672 [(set_attr "type" "uncond_branch")])
6674 (define_insn "*tablejump_sp64"
6675 [(set (pc) (match_operand:DI 0 "address_operand" "p"))
6676 (use (label_ref (match_operand 1 "" "")))]
6679 [(set_attr "type" "uncond_branch")])
6682 ;; Jump to subroutine instructions.
6684 (define_expand "call"
6685 ;; Note that this expression is not used for generating RTL.
6686 ;; All the RTL is generated explicitly below.
6687 [(call (match_operand 0 "call_operand" "")
6688 (match_operand 3 "" "i"))]
6689 ;; operands[2] is next_arg_register
6690 ;; operands[3] is struct_value_size_rtx.
6695 gcc_assert (MEM_P (operands[0]) && GET_MODE (operands[0]) == FUNCTION_MODE);
6697 gcc_assert (GET_CODE (operands[3]) == CONST_INT);
6699 if (GET_CODE (XEXP (operands[0], 0)) == LABEL_REF)
6701 /* This is really a PIC sequence. We want to represent
6702 it as a funny jump so its delay slots can be filled.
6704 ??? But if this really *is* a CALL, will not it clobber the
6705 call-clobbered registers? We lose this if it is a JUMP_INSN.
6706 Why cannot we have delay slots filled if it were a CALL? */
6708 /* We accept negative sizes for untyped calls. */
6709 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
6714 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
6716 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
6722 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
6723 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
6727 fn_rtx = operands[0];
6729 /* We accept negative sizes for untyped calls. */
6730 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
6731 sparc_emit_call_insn
6734 gen_rtvec (3, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx),
6736 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))),
6739 sparc_emit_call_insn
6742 gen_rtvec (2, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx),
6743 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))),
6751 ;; We can't use the same pattern for these two insns, because then registers
6752 ;; in the address may not be properly reloaded.
6754 (define_insn "*call_address_sp32"
6755 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6756 (match_operand 1 "" ""))
6757 (clobber (reg:SI 15))]
6758 ;;- Do not use operand 1 for most machines.
6761 [(set_attr "type" "call")])
6763 (define_insn "*call_symbolic_sp32"
6764 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6765 (match_operand 1 "" ""))
6766 (clobber (reg:SI 15))]
6767 ;;- Do not use operand 1 for most machines.
6770 [(set_attr "type" "call")])
6772 (define_insn "*call_address_sp64"
6773 [(call (mem:DI (match_operand:DI 0 "address_operand" "p"))
6774 (match_operand 1 "" ""))
6775 (clobber (reg:DI 15))]
6776 ;;- Do not use operand 1 for most machines.
6779 [(set_attr "type" "call")])
6781 (define_insn "*call_symbolic_sp64"
6782 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
6783 (match_operand 1 "" ""))
6784 (clobber (reg:DI 15))]
6785 ;;- Do not use operand 1 for most machines.
6788 [(set_attr "type" "call")])
6790 ;; This is a call that wants a structure value.
6791 ;; There is no such critter for v9 (??? we may need one anyway).
6792 (define_insn "*call_address_struct_value_sp32"
6793 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6794 (match_operand 1 "" ""))
6795 (match_operand 2 "immediate_operand" "")
6796 (clobber (reg:SI 15))]
6797 ;;- Do not use operand 1 for most machines.
6798 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
6800 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xfff);
6801 return "call\t%a0, %1\n\t nop\n\tunimp\t%2";
6803 [(set_attr "type" "call_no_delay_slot")
6804 (set_attr "length" "3")])
6806 ;; This is a call that wants a structure value.
6807 ;; There is no such critter for v9 (??? we may need one anyway).
6808 (define_insn "*call_symbolic_struct_value_sp32"
6809 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6810 (match_operand 1 "" ""))
6811 (match_operand 2 "immediate_operand" "")
6812 (clobber (reg:SI 15))]
6813 ;;- Do not use operand 1 for most machines.
6814 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
6816 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xfff);
6817 return "call\t%a0, %1\n\t nop\n\tunimp\t%2";
6819 [(set_attr "type" "call_no_delay_slot")
6820 (set_attr "length" "3")])
6822 ;; This is a call that may want a structure value. This is used for
6824 (define_insn "*call_address_untyped_struct_value_sp32"
6825 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6826 (match_operand 1 "" ""))
6827 (match_operand 2 "immediate_operand" "")
6828 (clobber (reg:SI 15))]
6829 ;;- Do not use operand 1 for most machines.
6830 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
6831 "call\t%a0, %1\n\t nop\n\tnop"
6832 [(set_attr "type" "call_no_delay_slot")
6833 (set_attr "length" "3")])
6835 ;; This is a call that may want a structure value. This is used for
6837 (define_insn "*call_symbolic_untyped_struct_value_sp32"
6838 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6839 (match_operand 1 "" ""))
6840 (match_operand 2 "immediate_operand" "")
6841 (clobber (reg:SI 15))]
6842 ;;- Do not use operand 1 for most machines.
6843 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
6844 "call\t%a0, %1\n\t nop\n\tnop"
6845 [(set_attr "type" "call_no_delay_slot")
6846 (set_attr "length" "3")])
6848 (define_expand "call_value"
6849 ;; Note that this expression is not used for generating RTL.
6850 ;; All the RTL is generated explicitly below.
6851 [(set (match_operand 0 "register_operand" "=rf")
6852 (call (match_operand 1 "" "")
6853 (match_operand 4 "" "")))]
6854 ;; operand 2 is stack_size_rtx
6855 ;; operand 3 is next_arg_register
6861 gcc_assert (MEM_P (operands[1]) && GET_MODE (operands[1]) == FUNCTION_MODE);
6863 fn_rtx = operands[1];
6866 gen_rtx_SET (VOIDmode, operands[0],
6867 gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx)),
6868 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)));
6870 sparc_emit_call_insn (gen_rtx_PARALLEL (VOIDmode, vec), XEXP (fn_rtx, 0));
6875 (define_insn "*call_value_address_sp32"
6876 [(set (match_operand 0 "" "=rf")
6877 (call (mem:SI (match_operand:SI 1 "address_operand" "p"))
6878 (match_operand 2 "" "")))
6879 (clobber (reg:SI 15))]
6880 ;;- Do not use operand 2 for most machines.
6883 [(set_attr "type" "call")])
6885 (define_insn "*call_value_symbolic_sp32"
6886 [(set (match_operand 0 "" "=rf")
6887 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
6888 (match_operand 2 "" "")))
6889 (clobber (reg:SI 15))]
6890 ;;- Do not use operand 2 for most machines.
6893 [(set_attr "type" "call")])
6895 (define_insn "*call_value_address_sp64"
6896 [(set (match_operand 0 "" "")
6897 (call (mem:DI (match_operand:DI 1 "address_operand" "p"))
6898 (match_operand 2 "" "")))
6899 (clobber (reg:DI 15))]
6900 ;;- Do not use operand 2 for most machines.
6903 [(set_attr "type" "call")])
6905 (define_insn "*call_value_symbolic_sp64"
6906 [(set (match_operand 0 "" "")
6907 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
6908 (match_operand 2 "" "")))
6909 (clobber (reg:DI 15))]
6910 ;;- Do not use operand 2 for most machines.
6913 [(set_attr "type" "call")])
6915 (define_expand "untyped_call"
6916 [(parallel [(call (match_operand 0 "" "")
6918 (match_operand:BLK 1 "memory_operand" "")
6919 (match_operand 2 "" "")])]
6922 rtx valreg1 = gen_rtx_REG (DImode, 8);
6923 rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
6924 rtx result = operands[1];
6926 /* Pass constm1 to indicate that it may expect a structure value, but
6927 we don't know what size it is. */
6928 emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, constm1_rtx));
6930 /* Save the function value registers. */
6931 emit_move_insn (adjust_address (result, DImode, 0), valreg1);
6932 emit_move_insn (adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8),
6935 /* The optimizer does not know that the call sets the function value
6936 registers we stored in the result block. We avoid problems by
6937 claiming that all hard registers are used and clobbered at this
6939 emit_insn (gen_blockage ());
6944 ;; Tail call instructions.
6946 (define_expand "sibcall"
6947 [(parallel [(call (match_operand 0 "call_operand" "") (const_int 0))
6952 (define_insn "*sibcall_symbolic_sp32"
6953 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6954 (match_operand 1 "" ""))
6957 "* return output_sibcall(insn, operands[0]);"
6958 [(set_attr "type" "sibcall")])
6960 (define_insn "*sibcall_symbolic_sp64"
6961 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
6962 (match_operand 1 "" ""))
6965 "* return output_sibcall(insn, operands[0]);"
6966 [(set_attr "type" "sibcall")])
6968 (define_expand "sibcall_value"
6969 [(parallel [(set (match_operand 0 "register_operand" "=rf")
6970 (call (match_operand 1 "" "") (const_int 0)))
6975 (define_insn "*sibcall_value_symbolic_sp32"
6976 [(set (match_operand 0 "" "=rf")
6977 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
6978 (match_operand 2 "" "")))
6981 "* return output_sibcall(insn, operands[1]);"
6982 [(set_attr "type" "sibcall")])
6984 (define_insn "*sibcall_value_symbolic_sp64"
6985 [(set (match_operand 0 "" "")
6986 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
6987 (match_operand 2 "" "")))
6990 "* return output_sibcall(insn, operands[1]);"
6991 [(set_attr "type" "sibcall")])
6994 ;; Special instructions.
6996 (define_expand "prologue"
7000 sparc_expand_prologue ();
7004 ;; The "save register window" insn is modelled as follows so that the DWARF-2
7005 ;; backend automatically emits the required call frame debugging information
7006 ;; while it is parsing it. Therefore, the pattern should not be modified
7007 ;; without first studying the impact of the changes on the debug info.
7008 ;; [(set (%fp) (%sp))
7009 ;; (set (%sp) (unspec_volatile [(%sp) (-frame_size)] UNSPECV_SAVEW))
7010 ;; (set (%i7) (%o7))]
7012 (define_insn "save_register_window<P:mode>"
7013 [(set (reg:P 30) (reg:P 14))
7014 (set (reg:P 14) (unspec_volatile:P [(reg:P 14)
7015 (match_operand:P 0 "arith_operand" "rI")] UNSPECV_SAVEW))
7016 (set (reg:P 31) (reg:P 15))]
7018 "save\t%%sp, %0, %%sp"
7019 [(set_attr "type" "savew")])
7021 (define_expand "epilogue"
7025 sparc_expand_epilogue ();
7028 (define_expand "sibcall_epilogue"
7032 sparc_expand_epilogue ();
7036 (define_expand "return"
7038 "sparc_can_use_return_insn_p ()"
7041 (define_insn "*return_internal"
7044 "* return output_return (insn);"
7045 [(set_attr "type" "return")
7046 (set (attr "length")
7047 (cond [(eq_attr "leaf_function" "true")
7048 (if_then_else (eq_attr "empty_delay_slot" "true")
7051 (eq_attr "calls_eh_return" "true")
7052 (if_then_else (eq_attr "delayed_branch" "true")
7053 (if_then_else (eq_attr "isa" "v9")
7056 (if_then_else (eq_attr "isa" "v9")
7059 (eq_attr "empty_delay_slot" "true")
7060 (if_then_else (eq_attr "delayed_branch" "true")
7065 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
7066 ;; all of memory. This blocks insns from being moved across this point.
7068 (define_insn "blockage"
7069 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
7072 [(set_attr "length" "0")])
7074 ;; Prepare to return any type including a structure value.
7076 (define_expand "untyped_return"
7077 [(match_operand:BLK 0 "memory_operand" "")
7078 (match_operand 1 "" "")]
7081 rtx valreg1 = gen_rtx_REG (DImode, 24);
7082 rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
7083 rtx result = operands[0];
7085 if (! TARGET_ARCH64)
7087 rtx rtnreg = gen_rtx_REG (SImode, (current_function_uses_only_leaf_regs
7089 rtx value = gen_reg_rtx (SImode);
7091 /* Fetch the instruction where we will return to and see if it's an unimp
7092 instruction (the most significant 10 bits will be zero). If so,
7093 update the return address to skip the unimp instruction. */
7094 emit_move_insn (value,
7095 gen_rtx_MEM (SImode, plus_constant (rtnreg, 8)));
7096 emit_insn (gen_lshrsi3 (value, value, GEN_INT (22)));
7097 emit_insn (gen_update_return (rtnreg, value));
7100 /* Reload the function value registers. */
7101 emit_move_insn (valreg1, adjust_address (result, DImode, 0));
7102 emit_move_insn (valreg2,
7103 adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8));
7105 /* Put USE insns before the return. */
7106 emit_insn (gen_rtx_USE (VOIDmode, valreg1));
7107 emit_insn (gen_rtx_USE (VOIDmode, valreg2));
7109 /* Construct the return. */
7110 expand_naked_return ();
7115 ;; Adjust the return address conditionally. If the value of op1 is equal
7116 ;; to all zero then adjust the return address i.e. op0 = op0 + 4.
7117 ;; This is technically *half* the check required by the 32-bit SPARC
7118 ;; psABI. This check only ensures that an "unimp" insn was written by
7119 ;; the caller, but doesn't check to see if the expected size matches
7120 ;; (this is encoded in the 12 lower bits). This check is obsolete and
7121 ;; only used by the above code "untyped_return".
7123 (define_insn "update_return"
7124 [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
7125 (match_operand:SI 1 "register_operand" "r")] UNSPEC_UPDATE_RETURN)]
7128 if (flag_delayed_branch)
7129 return "cmp\t%1, 0\n\tbe,a\t.+8\n\t add\t%0, 4, %0";
7131 return "cmp\t%1, 0\n\tbne\t.+12\n\t nop\n\tadd\t%0, 4, %0";
7133 [(set (attr "type") (const_string "multi"))
7134 (set (attr "length")
7135 (if_then_else (eq_attr "delayed_branch" "true")
7144 (define_expand "indirect_jump"
7145 [(set (pc) (match_operand 0 "address_operand" "p"))]
7149 (define_insn "*branch_sp32"
7150 [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
7153 [(set_attr "type" "uncond_branch")])
7155 (define_insn "*branch_sp64"
7156 [(set (pc) (match_operand:DI 0 "address_operand" "p"))]
7159 [(set_attr "type" "uncond_branch")])
7161 (define_expand "nonlocal_goto"
7162 [(match_operand:SI 0 "general_operand" "")
7163 (match_operand:SI 1 "general_operand" "")
7164 (match_operand:SI 2 "general_operand" "")
7165 (match_operand:SI 3 "" "")]
7168 rtx lab = operands[1];
7169 rtx stack = operands[2];
7170 rtx fp = operands[3];
7173 /* Trap instruction to flush all the register windows. */
7174 emit_insn (gen_flush_register_windows ());
7176 /* Load the fp value for the containing fn into %fp. This is needed
7177 because STACK refers to %fp. Note that virtual register instantiation
7178 fails if the virtual %fp isn't set from a register. */
7179 if (GET_CODE (fp) != REG)
7180 fp = force_reg (Pmode, fp);
7181 emit_move_insn (virtual_stack_vars_rtx, fp);
7183 /* Find the containing function's current nonlocal goto handler,
7184 which will do any cleanups and then jump to the label. */
7185 labreg = gen_rtx_REG (Pmode, 8);
7186 emit_move_insn (labreg, lab);
7188 /* Restore %fp from stack pointer value for containing function.
7189 The restore insn that follows will move this to %sp,
7190 and reload the appropriate value into %fp. */
7191 emit_move_insn (hard_frame_pointer_rtx, stack);
7193 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
7194 emit_insn (gen_rtx_USE (VOIDmode, static_chain_rtx));
7196 /* ??? The V9-specific version was disabled in rev 1.65. */
7197 emit_jump_insn (gen_goto_handler_and_restore (labreg));
7202 ;; Special trap insn to flush register windows.
7203 (define_insn "flush_register_windows"
7204 [(unspec_volatile [(const_int 0)] UNSPECV_FLUSHW)]
7206 { return TARGET_V9 ? "flushw" : "ta\t3"; }
7207 [(set_attr "type" "flushw")])
7209 (define_insn "goto_handler_and_restore"
7210 [(unspec_volatile [(match_operand 0 "register_operand" "=r")] UNSPECV_GOTO)]
7211 "GET_MODE (operands[0]) == Pmode"
7213 if (flag_delayed_branch)
7214 return "jmp\t%0\n\t restore";
7216 return "mov\t%0,%%g1\n\trestore\n\tjmp\t%%g1\n\t nop";
7218 [(set (attr "type") (const_string "multi"))
7219 (set (attr "length")
7220 (if_then_else (eq_attr "delayed_branch" "true")
7224 ;; For __builtin_setjmp we need to flush register windows iff the function
7225 ;; calls alloca as well, because otherwise the register window might be
7226 ;; saved after %sp adjustment and thus setjmp would crash
7227 (define_expand "builtin_setjmp_setup"
7228 [(match_operand 0 "register_operand" "r")]
7231 emit_insn (gen_do_builtin_setjmp_setup ());
7235 (define_insn "do_builtin_setjmp_setup"
7236 [(unspec_volatile [(const_int 0)] UNSPECV_SETJMP)]
7239 if (! current_function_calls_alloca)
7243 fputs ("\tflushw\n", asm_out_file);
7245 fprintf (asm_out_file, "\tst%c\t%%l7, [%%sp+%d]\n",
7246 TARGET_ARCH64 ? 'x' : 'w',
7247 SPARC_STACK_BIAS + 7 * UNITS_PER_WORD);
7248 fprintf (asm_out_file, "\tst%c\t%%fp, [%%sp+%d]\n",
7249 TARGET_ARCH64 ? 'x' : 'w',
7250 SPARC_STACK_BIAS + 14 * UNITS_PER_WORD);
7251 fprintf (asm_out_file, "\tst%c\t%%i7, [%%sp+%d]\n",
7252 TARGET_ARCH64 ? 'x' : 'w',
7253 SPARC_STACK_BIAS + 15 * UNITS_PER_WORD);
7256 [(set_attr "type" "multi")
7257 (set (attr "length")
7258 (cond [(eq_attr "calls_alloca" "false")
7260 (eq_attr "isa" "!v9")
7262 (eq_attr "pic" "true")
7263 (const_int 4)] (const_int 3)))])
7265 ;; Pattern for use after a setjmp to store FP and the return register
7266 ;; into the stack area.
7268 (define_expand "setjmp"
7274 mem = gen_rtx_MEM (Pmode,
7275 plus_constant (stack_pointer_rtx,
7276 SPARC_STACK_BIAS + 14 * UNITS_PER_WORD));
7277 emit_insn (gen_rtx_SET (VOIDmode, mem, frame_pointer_rtx));
7279 mem = gen_rtx_MEM (Pmode,
7280 plus_constant (stack_pointer_rtx,
7281 SPARC_STACK_BIAS + 15 * UNITS_PER_WORD));
7282 emit_insn (gen_rtx_SET (VOIDmode, mem, gen_rtx_REG (Pmode, 31)));
7286 ;; Special pattern for the FLUSH instruction.
7288 ; We do SImode and DImode versions of this to quiet down genrecog's complaints
7289 ; of the define_insn otherwise missing a mode. We make "flush", aka
7290 ; gen_flush, the default one since sparc_initialize_trampoline uses
7291 ; it on SImode mem values.
7293 (define_insn "flush"
7294 [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")] UNSPECV_FLUSH)]
7296 { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; }
7297 [(set_attr "type" "iflush")])
7299 (define_insn "flushdi"
7300 [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")] UNSPECV_FLUSH)]
7302 { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; }
7303 [(set_attr "type" "iflush")])
7306 ;; Find first set instructions.
7308 ;; The scan instruction searches from the most significant bit while ffs
7309 ;; searches from the least significant bit. The bit index and treatment of
7310 ;; zero also differ. It takes at least 7 instructions to get the proper
7311 ;; result. Here is an obvious 8 instruction sequence.
7314 (define_insn "ffssi2"
7315 [(set (match_operand:SI 0 "register_operand" "=&r")
7316 (ffs:SI (match_operand:SI 1 "register_operand" "r")))
7317 (clobber (match_scratch:SI 2 "=&r"))]
7318 "TARGET_SPARCLITE || TARGET_SPARCLET"
7320 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";
7322 [(set_attr "type" "multi")
7323 (set_attr "length" "8")])
7325 ;; ??? This should be a define expand, so that the extra instruction have
7326 ;; a chance of being optimized away.
7328 ;; Disabled because none of the UltraSPARCs implement popc. The HAL R1
7329 ;; does, but no one uses that and we don't have a switch for it.
7331 ;(define_insn "ffsdi2"
7332 ; [(set (match_operand:DI 0 "register_operand" "=&r")
7333 ; (ffs:DI (match_operand:DI 1 "register_operand" "r")))
7334 ; (clobber (match_scratch:DI 2 "=&r"))]
7336 ; "neg\t%1, %2\;xnor\t%1, %2, %2\;popc\t%2, %0\;movzr\t%1, 0, %0"
7337 ; [(set_attr "type" "multi")
7338 ; (set_attr "length" "4")])
7342 ;; Peepholes go at the end.
7344 ;; Optimize consecutive loads or stores into ldd and std when possible.
7345 ;; The conditions in which we do this are very restricted and are
7346 ;; explained in the code for {registers,memory}_ok_for_ldd functions.
7349 [(set (match_operand:SI 0 "memory_operand" "")
7351 (set (match_operand:SI 1 "memory_operand" "")
7354 && mems_ok_for_ldd_peep (operands[0], operands[1], NULL_RTX)"
7357 "operands[0] = widen_memory_access (operands[0], DImode, 0);")
7360 [(set (match_operand:SI 0 "memory_operand" "")
7362 (set (match_operand:SI 1 "memory_operand" "")
7365 && mems_ok_for_ldd_peep (operands[1], operands[0], NULL_RTX)"
7368 "operands[1] = widen_memory_access (operands[1], DImode, 0);")
7371 [(set (match_operand:SI 0 "register_operand" "")
7372 (match_operand:SI 1 "memory_operand" ""))
7373 (set (match_operand:SI 2 "register_operand" "")
7374 (match_operand:SI 3 "memory_operand" ""))]
7375 "registers_ok_for_ldd_peep (operands[0], operands[2])
7376 && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
7379 "operands[1] = widen_memory_access (operands[1], DImode, 0);
7380 operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));")
7383 [(set (match_operand:SI 0 "memory_operand" "")
7384 (match_operand:SI 1 "register_operand" ""))
7385 (set (match_operand:SI 2 "memory_operand" "")
7386 (match_operand:SI 3 "register_operand" ""))]
7387 "registers_ok_for_ldd_peep (operands[1], operands[3])
7388 && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
7391 "operands[0] = widen_memory_access (operands[0], DImode, 0);
7392 operands[1] = gen_rtx_REG (DImode, REGNO (operands[1]));")
7395 [(set (match_operand:SF 0 "register_operand" "")
7396 (match_operand:SF 1 "memory_operand" ""))
7397 (set (match_operand:SF 2 "register_operand" "")
7398 (match_operand:SF 3 "memory_operand" ""))]
7399 "registers_ok_for_ldd_peep (operands[0], operands[2])
7400 && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
7403 "operands[1] = widen_memory_access (operands[1], DFmode, 0);
7404 operands[0] = gen_rtx_REG (DFmode, REGNO (operands[0]));")
7407 [(set (match_operand:SF 0 "memory_operand" "")
7408 (match_operand:SF 1 "register_operand" ""))
7409 (set (match_operand:SF 2 "memory_operand" "")
7410 (match_operand:SF 3 "register_operand" ""))]
7411 "registers_ok_for_ldd_peep (operands[1], operands[3])
7412 && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
7415 "operands[0] = widen_memory_access (operands[0], DFmode, 0);
7416 operands[1] = gen_rtx_REG (DFmode, REGNO (operands[1]));")
7419 [(set (match_operand:SI 0 "register_operand" "")
7420 (match_operand:SI 1 "memory_operand" ""))
7421 (set (match_operand:SI 2 "register_operand" "")
7422 (match_operand:SI 3 "memory_operand" ""))]
7423 "registers_ok_for_ldd_peep (operands[2], operands[0])
7424 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
7427 "operands[3] = widen_memory_access (operands[3], DImode, 0);
7428 operands[2] = gen_rtx_REG (DImode, REGNO (operands[2]));")
7431 [(set (match_operand:SI 0 "memory_operand" "")
7432 (match_operand:SI 1 "register_operand" ""))
7433 (set (match_operand:SI 2 "memory_operand" "")
7434 (match_operand:SI 3 "register_operand" ""))]
7435 "registers_ok_for_ldd_peep (operands[3], operands[1])
7436 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
7439 "operands[2] = widen_memory_access (operands[2], DImode, 0);
7440 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
7444 [(set (match_operand:SF 0 "register_operand" "")
7445 (match_operand:SF 1 "memory_operand" ""))
7446 (set (match_operand:SF 2 "register_operand" "")
7447 (match_operand:SF 3 "memory_operand" ""))]
7448 "registers_ok_for_ldd_peep (operands[2], operands[0])
7449 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
7452 "operands[3] = widen_memory_access (operands[3], DFmode, 0);
7453 operands[2] = gen_rtx_REG (DFmode, REGNO (operands[2]));")
7456 [(set (match_operand:SF 0 "memory_operand" "")
7457 (match_operand:SF 1 "register_operand" ""))
7458 (set (match_operand:SF 2 "memory_operand" "")
7459 (match_operand:SF 3 "register_operand" ""))]
7460 "registers_ok_for_ldd_peep (operands[3], operands[1])
7461 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
7464 "operands[2] = widen_memory_access (operands[2], DFmode, 0);
7465 operands[3] = gen_rtx_REG (DFmode, REGNO (operands[3]));")
7467 ;; Optimize the case of following a reg-reg move with a test
7468 ;; of reg just moved. Don't allow floating point regs for operand 0 or 1.
7469 ;; This can result from a float to fix conversion.
7472 [(set (match_operand:SI 0 "register_operand" "")
7473 (match_operand:SI 1 "register_operand" ""))
7475 (compare:CC (match_operand:SI 2 "register_operand" "")
7477 "(rtx_equal_p (operands[2], operands[0])
7478 || rtx_equal_p (operands[2], operands[1]))
7479 && ! SPARC_FP_REG_P (REGNO (operands[0]))
7480 && ! SPARC_FP_REG_P (REGNO (operands[1]))"
7481 [(parallel [(set (match_dup 0) (match_dup 1))
7483 (compare:CC (match_dup 1) (const_int 0)))])]
7487 [(set (match_operand:DI 0 "register_operand" "")
7488 (match_operand:DI 1 "register_operand" ""))
7490 (compare:CCX (match_operand:DI 2 "register_operand" "")
7493 && (rtx_equal_p (operands[2], operands[0])
7494 || rtx_equal_p (operands[2], operands[1]))
7495 && ! SPARC_FP_REG_P (REGNO (operands[0]))
7496 && ! SPARC_FP_REG_P (REGNO (operands[1]))"
7497 [(parallel [(set (match_dup 0) (match_dup 1))
7499 (compare:CCX (match_dup 1) (const_int 0)))])]
7503 ;; Prefetch instructions.
7505 ;; ??? UltraSPARC-III note: A memory operation loading into the floating point register
7506 ;; ??? file, if it hits the prefetch cache, has a chance to dual-issue with other memory
7507 ;; ??? operations. With DFA we might be able to model this, but it requires a lot of
7509 (define_expand "prefetch"
7510 [(match_operand 0 "address_operand" "")
7511 (match_operand 1 "const_int_operand" "")
7512 (match_operand 2 "const_int_operand" "")]
7516 emit_insn (gen_prefetch_64 (operands[0], operands[1], operands[2]));
7518 emit_insn (gen_prefetch_32 (operands[0], operands[1], operands[2]));
7522 (define_insn "prefetch_64"
7523 [(prefetch (match_operand:DI 0 "address_operand" "p")
7524 (match_operand:DI 1 "const_int_operand" "n")
7525 (match_operand:DI 2 "const_int_operand" "n"))]
7528 static const char * const prefetch_instr[2][2] = {
7530 "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
7531 "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
7534 "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
7535 "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
7538 int read_or_write = INTVAL (operands[1]);
7539 int locality = INTVAL (operands[2]);
7541 gcc_assert (read_or_write == 0 || read_or_write == 1);
7542 gcc_assert (locality >= 0 && locality < 4);
7543 return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
7545 [(set_attr "type" "load")])
7547 (define_insn "prefetch_32"
7548 [(prefetch (match_operand:SI 0 "address_operand" "p")
7549 (match_operand:SI 1 "const_int_operand" "n")
7550 (match_operand:SI 2 "const_int_operand" "n"))]
7553 static const char * const prefetch_instr[2][2] = {
7555 "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
7556 "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
7559 "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
7560 "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
7563 int read_or_write = INTVAL (operands[1]);
7564 int locality = INTVAL (operands[2]);
7566 gcc_assert (read_or_write == 0 || read_or_write == 1);
7567 gcc_assert (locality >= 0 && locality < 4);
7568 return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
7570 [(set_attr "type" "load")])
7573 ;; Trap instructions.
7576 [(trap_if (const_int 1) (const_int 5))]
7579 [(set_attr "type" "trap")])
7581 (define_expand "conditional_trap"
7582 [(trap_if (match_operator 0 "noov_compare_operator" [(match_dup 2) (match_dup 3)])
7583 (match_operand:SI 1 "arith_operand" ""))]
7585 "operands[2] = gen_compare_reg (GET_CODE (operands[0]));
7586 if (GET_MODE (operands[2]) != CCmode && GET_MODE (operands[2]) != CCXmode)
7588 operands[3] = const0_rtx;")
7591 [(trap_if (match_operator 0 "noov_compare_operator" [(reg:CC 100) (const_int 0)])
7592 (match_operand:SI 1 "arith_operand" "rM"))]
7596 return "t%C0\t%%icc, %1";
7600 [(set_attr "type" "trap")])
7603 [(trap_if (match_operator 0 "noov_compare_operator" [(reg:CCX 100) (const_int 0)])
7604 (match_operand:SI 1 "arith_operand" "rM"))]
7607 [(set_attr "type" "trap")])
7610 ;; TLS support instructions.
7612 (define_insn "tgd_hi22"
7613 [(set (match_operand:SI 0 "register_operand" "=r")
7614 (high:SI (unspec:SI [(match_operand 1 "tgd_symbolic_operand" "")]
7617 "sethi\\t%%tgd_hi22(%a1), %0")
7619 (define_insn "tgd_lo10"
7620 [(set (match_operand:SI 0 "register_operand" "=r")
7621 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7622 (unspec:SI [(match_operand 2 "tgd_symbolic_operand" "")]
7625 "add\\t%1, %%tgd_lo10(%a2), %0")
7627 (define_insn "tgd_add32"
7628 [(set (match_operand:SI 0 "register_operand" "=r")
7629 (plus:SI (match_operand:SI 1 "register_operand" "r")
7630 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7631 (match_operand 3 "tgd_symbolic_operand" "")]
7633 "TARGET_TLS && TARGET_ARCH32"
7634 "add\\t%1, %2, %0, %%tgd_add(%a3)")
7636 (define_insn "tgd_add64"
7637 [(set (match_operand:DI 0 "register_operand" "=r")
7638 (plus:DI (match_operand:DI 1 "register_operand" "r")
7639 (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7640 (match_operand 3 "tgd_symbolic_operand" "")]
7642 "TARGET_TLS && TARGET_ARCH64"
7643 "add\\t%1, %2, %0, %%tgd_add(%a3)")
7645 (define_insn "tgd_call32"
7646 [(set (match_operand 0 "register_operand" "=r")
7647 (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")
7648 (match_operand 2 "tgd_symbolic_operand" "")]
7650 (match_operand 3 "" "")))
7651 (clobber (reg:SI 15))]
7652 "TARGET_TLS && TARGET_ARCH32"
7653 "call\t%a1, %%tgd_call(%a2)%#"
7654 [(set_attr "type" "call")])
7656 (define_insn "tgd_call64"
7657 [(set (match_operand 0 "register_operand" "=r")
7658 (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")
7659 (match_operand 2 "tgd_symbolic_operand" "")]
7661 (match_operand 3 "" "")))
7662 (clobber (reg:DI 15))]
7663 "TARGET_TLS && TARGET_ARCH64"
7664 "call\t%a1, %%tgd_call(%a2)%#"
7665 [(set_attr "type" "call")])
7667 (define_insn "tldm_hi22"
7668 [(set (match_operand:SI 0 "register_operand" "=r")
7669 (high:SI (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
7671 "sethi\\t%%tldm_hi22(%&), %0")
7673 (define_insn "tldm_lo10"
7674 [(set (match_operand:SI 0 "register_operand" "=r")
7675 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7676 (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
7678 "add\\t%1, %%tldm_lo10(%&), %0")
7680 (define_insn "tldm_add32"
7681 [(set (match_operand:SI 0 "register_operand" "=r")
7682 (plus:SI (match_operand:SI 1 "register_operand" "r")
7683 (unspec:SI [(match_operand:SI 2 "register_operand" "r")]
7685 "TARGET_TLS && TARGET_ARCH32"
7686 "add\\t%1, %2, %0, %%tldm_add(%&)")
7688 (define_insn "tldm_add64"
7689 [(set (match_operand:DI 0 "register_operand" "=r")
7690 (plus:DI (match_operand:DI 1 "register_operand" "r")
7691 (unspec:DI [(match_operand:SI 2 "register_operand" "r")]
7693 "TARGET_TLS && TARGET_ARCH64"
7694 "add\\t%1, %2, %0, %%tldm_add(%&)")
7696 (define_insn "tldm_call32"
7697 [(set (match_operand 0 "register_operand" "=r")
7698 (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")]
7700 (match_operand 2 "" "")))
7701 (clobber (reg:SI 15))]
7702 "TARGET_TLS && TARGET_ARCH32"
7703 "call\t%a1, %%tldm_call(%&)%#"
7704 [(set_attr "type" "call")])
7706 (define_insn "tldm_call64"
7707 [(set (match_operand 0 "register_operand" "=r")
7708 (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")]
7710 (match_operand 2 "" "")))
7711 (clobber (reg:DI 15))]
7712 "TARGET_TLS && TARGET_ARCH64"
7713 "call\t%a1, %%tldm_call(%&)%#"
7714 [(set_attr "type" "call")])
7716 (define_insn "tldo_hix22"
7717 [(set (match_operand:SI 0 "register_operand" "=r")
7718 (high:SI (unspec:SI [(match_operand 1 "tld_symbolic_operand" "")]
7721 "sethi\\t%%tldo_hix22(%a1), %0")
7723 (define_insn "tldo_lox10"
7724 [(set (match_operand:SI 0 "register_operand" "=r")
7725 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7726 (unspec:SI [(match_operand 2 "tld_symbolic_operand" "")]
7729 "xor\\t%1, %%tldo_lox10(%a2), %0")
7731 (define_insn "tldo_add32"
7732 [(set (match_operand:SI 0 "register_operand" "=r")
7733 (plus:SI (match_operand:SI 1 "register_operand" "r")
7734 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7735 (match_operand 3 "tld_symbolic_operand" "")]
7737 "TARGET_TLS && TARGET_ARCH32"
7738 "add\\t%1, %2, %0, %%tldo_add(%a3)")
7740 (define_insn "tldo_add64"
7741 [(set (match_operand:DI 0 "register_operand" "=r")
7742 (plus:DI (match_operand:DI 1 "register_operand" "r")
7743 (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7744 (match_operand 3 "tld_symbolic_operand" "")]
7746 "TARGET_TLS && TARGET_ARCH64"
7747 "add\\t%1, %2, %0, %%tldo_add(%a3)")
7749 (define_insn "tie_hi22"
7750 [(set (match_operand:SI 0 "register_operand" "=r")
7751 (high:SI (unspec:SI [(match_operand 1 "tie_symbolic_operand" "")]
7754 "sethi\\t%%tie_hi22(%a1), %0")
7756 (define_insn "tie_lo10"
7757 [(set (match_operand:SI 0 "register_operand" "=r")
7758 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7759 (unspec:SI [(match_operand 2 "tie_symbolic_operand" "")]
7762 "add\\t%1, %%tie_lo10(%a2), %0")
7764 (define_insn "tie_ld32"
7765 [(set (match_operand:SI 0 "register_operand" "=r")
7766 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
7767 (match_operand:SI 2 "register_operand" "r")
7768 (match_operand 3 "tie_symbolic_operand" "")]
7770 "TARGET_TLS && TARGET_ARCH32"
7771 "ld\\t[%1 + %2], %0, %%tie_ld(%a3)"
7772 [(set_attr "type" "load")])
7774 (define_insn "tie_ld64"
7775 [(set (match_operand:DI 0 "register_operand" "=r")
7776 (unspec:DI [(match_operand:DI 1 "register_operand" "r")
7777 (match_operand:SI 2 "register_operand" "r")
7778 (match_operand 3 "tie_symbolic_operand" "")]
7780 "TARGET_TLS && TARGET_ARCH64"
7781 "ldx\\t[%1 + %2], %0, %%tie_ldx(%a3)"
7782 [(set_attr "type" "load")])
7784 (define_insn "tie_add32"
7785 [(set (match_operand:SI 0 "register_operand" "=r")
7786 (plus:SI (match_operand:SI 1 "register_operand" "r")
7787 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7788 (match_operand 3 "tie_symbolic_operand" "")]
7790 "TARGET_SUN_TLS && TARGET_ARCH32"
7791 "add\\t%1, %2, %0, %%tie_add(%a3)")
7793 (define_insn "tie_add64"
7794 [(set (match_operand:DI 0 "register_operand" "=r")
7795 (plus:DI (match_operand:DI 1 "register_operand" "r")
7796 (unspec:DI [(match_operand:DI 2 "register_operand" "r")
7797 (match_operand 3 "tie_symbolic_operand" "")]
7799 "TARGET_SUN_TLS && TARGET_ARCH64"
7800 "add\\t%1, %2, %0, %%tie_add(%a3)")
7802 (define_insn "tle_hix22_sp32"
7803 [(set (match_operand:SI 0 "register_operand" "=r")
7804 (high:SI (unspec:SI [(match_operand 1 "tle_symbolic_operand" "")]
7806 "TARGET_TLS && TARGET_ARCH32"
7807 "sethi\\t%%tle_hix22(%a1), %0")
7809 (define_insn "tle_lox10_sp32"
7810 [(set (match_operand:SI 0 "register_operand" "=r")
7811 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7812 (unspec:SI [(match_operand 2 "tle_symbolic_operand" "")]
7814 "TARGET_TLS && TARGET_ARCH32"
7815 "xor\\t%1, %%tle_lox10(%a2), %0")
7817 (define_insn "tle_hix22_sp64"
7818 [(set (match_operand:DI 0 "register_operand" "=r")
7819 (high:DI (unspec:DI [(match_operand 1 "tle_symbolic_operand" "")]
7821 "TARGET_TLS && TARGET_ARCH64"
7822 "sethi\\t%%tle_hix22(%a1), %0")
7824 (define_insn "tle_lox10_sp64"
7825 [(set (match_operand:DI 0 "register_operand" "=r")
7826 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
7827 (unspec:DI [(match_operand 2 "tle_symbolic_operand" "")]
7829 "TARGET_TLS && TARGET_ARCH64"
7830 "xor\\t%1, %%tle_lox10(%a2), %0")
7832 ;; Now patterns combining tldo_add{32,64} with some integer loads or stores
7833 (define_insn "*tldo_ldub_sp32"
7834 [(set (match_operand:QI 0 "register_operand" "=r")
7835 (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7836 (match_operand 3 "tld_symbolic_operand" "")]
7838 (match_operand:SI 1 "register_operand" "r"))))]
7839 "TARGET_TLS && TARGET_ARCH32"
7840 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7841 [(set_attr "type" "load")
7842 (set_attr "us3load_type" "3cycle")])
7844 (define_insn "*tldo_ldub1_sp32"
7845 [(set (match_operand:HI 0 "register_operand" "=r")
7846 (zero_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7847 (match_operand 3 "tld_symbolic_operand" "")]
7849 (match_operand:SI 1 "register_operand" "r")))))]
7850 "TARGET_TLS && TARGET_ARCH32"
7851 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7852 [(set_attr "type" "load")
7853 (set_attr "us3load_type" "3cycle")])
7855 (define_insn "*tldo_ldub2_sp32"
7856 [(set (match_operand:SI 0 "register_operand" "=r")
7857 (zero_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7858 (match_operand 3 "tld_symbolic_operand" "")]
7860 (match_operand:SI 1 "register_operand" "r")))))]
7861 "TARGET_TLS && TARGET_ARCH32"
7862 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7863 [(set_attr "type" "load")
7864 (set_attr "us3load_type" "3cycle")])
7866 (define_insn "*tldo_ldsb1_sp32"
7867 [(set (match_operand:HI 0 "register_operand" "=r")
7868 (sign_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7869 (match_operand 3 "tld_symbolic_operand" "")]
7871 (match_operand:SI 1 "register_operand" "r")))))]
7872 "TARGET_TLS && TARGET_ARCH32"
7873 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7874 [(set_attr "type" "sload")
7875 (set_attr "us3load_type" "3cycle")])
7877 (define_insn "*tldo_ldsb2_sp32"
7878 [(set (match_operand:SI 0 "register_operand" "=r")
7879 (sign_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7880 (match_operand 3 "tld_symbolic_operand" "")]
7882 (match_operand:SI 1 "register_operand" "r")))))]
7883 "TARGET_TLS && TARGET_ARCH32"
7884 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7885 [(set_attr "type" "sload")
7886 (set_attr "us3load_type" "3cycle")])
7888 (define_insn "*tldo_ldub_sp64"
7889 [(set (match_operand:QI 0 "register_operand" "=r")
7890 (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7891 (match_operand 3 "tld_symbolic_operand" "")]
7893 (match_operand:DI 1 "register_operand" "r"))))]
7894 "TARGET_TLS && TARGET_ARCH64"
7895 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7896 [(set_attr "type" "load")
7897 (set_attr "us3load_type" "3cycle")])
7899 (define_insn "*tldo_ldub1_sp64"
7900 [(set (match_operand:HI 0 "register_operand" "=r")
7901 (zero_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7902 (match_operand 3 "tld_symbolic_operand" "")]
7904 (match_operand:DI 1 "register_operand" "r")))))]
7905 "TARGET_TLS && TARGET_ARCH64"
7906 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7907 [(set_attr "type" "load")
7908 (set_attr "us3load_type" "3cycle")])
7910 (define_insn "*tldo_ldub2_sp64"
7911 [(set (match_operand:SI 0 "register_operand" "=r")
7912 (zero_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7913 (match_operand 3 "tld_symbolic_operand" "")]
7915 (match_operand:DI 1 "register_operand" "r")))))]
7916 "TARGET_TLS && TARGET_ARCH64"
7917 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7918 [(set_attr "type" "load")
7919 (set_attr "us3load_type" "3cycle")])
7921 (define_insn "*tldo_ldub3_sp64"
7922 [(set (match_operand:DI 0 "register_operand" "=r")
7923 (zero_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7924 (match_operand 3 "tld_symbolic_operand" "")]
7926 (match_operand:DI 1 "register_operand" "r")))))]
7927 "TARGET_TLS && TARGET_ARCH64"
7928 "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7929 [(set_attr "type" "load")
7930 (set_attr "us3load_type" "3cycle")])
7932 (define_insn "*tldo_ldsb1_sp64"
7933 [(set (match_operand:HI 0 "register_operand" "=r")
7934 (sign_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7935 (match_operand 3 "tld_symbolic_operand" "")]
7937 (match_operand:DI 1 "register_operand" "r")))))]
7938 "TARGET_TLS && TARGET_ARCH64"
7939 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7940 [(set_attr "type" "sload")
7941 (set_attr "us3load_type" "3cycle")])
7943 (define_insn "*tldo_ldsb2_sp64"
7944 [(set (match_operand:SI 0 "register_operand" "=r")
7945 (sign_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7946 (match_operand 3 "tld_symbolic_operand" "")]
7948 (match_operand:DI 1 "register_operand" "r")))))]
7949 "TARGET_TLS && TARGET_ARCH64"
7950 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7951 [(set_attr "type" "sload")
7952 (set_attr "us3load_type" "3cycle")])
7954 (define_insn "*tldo_ldsb3_sp64"
7955 [(set (match_operand:DI 0 "register_operand" "=r")
7956 (sign_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7957 (match_operand 3 "tld_symbolic_operand" "")]
7959 (match_operand:DI 1 "register_operand" "r")))))]
7960 "TARGET_TLS && TARGET_ARCH64"
7961 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7962 [(set_attr "type" "sload")
7963 (set_attr "us3load_type" "3cycle")])
7965 (define_insn "*tldo_lduh_sp32"
7966 [(set (match_operand:HI 0 "register_operand" "=r")
7967 (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7968 (match_operand 3 "tld_symbolic_operand" "")]
7970 (match_operand:SI 1 "register_operand" "r"))))]
7971 "TARGET_TLS && TARGET_ARCH32"
7972 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7973 [(set_attr "type" "load")
7974 (set_attr "us3load_type" "3cycle")])
7976 (define_insn "*tldo_lduh1_sp32"
7977 [(set (match_operand:SI 0 "register_operand" "=r")
7978 (zero_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7979 (match_operand 3 "tld_symbolic_operand" "")]
7981 (match_operand:SI 1 "register_operand" "r")))))]
7982 "TARGET_TLS && TARGET_ARCH32"
7983 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7984 [(set_attr "type" "load")
7985 (set_attr "us3load_type" "3cycle")])
7987 (define_insn "*tldo_ldsh1_sp32"
7988 [(set (match_operand:SI 0 "register_operand" "=r")
7989 (sign_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7990 (match_operand 3 "tld_symbolic_operand" "")]
7992 (match_operand:SI 1 "register_operand" "r")))))]
7993 "TARGET_TLS && TARGET_ARCH32"
7994 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
7995 [(set_attr "type" "sload")
7996 (set_attr "us3load_type" "3cycle")])
7998 (define_insn "*tldo_lduh_sp64"
7999 [(set (match_operand:HI 0 "register_operand" "=r")
8000 (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8001 (match_operand 3 "tld_symbolic_operand" "")]
8003 (match_operand:DI 1 "register_operand" "r"))))]
8004 "TARGET_TLS && TARGET_ARCH64"
8005 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
8006 [(set_attr "type" "load")
8007 (set_attr "us3load_type" "3cycle")])
8009 (define_insn "*tldo_lduh1_sp64"
8010 [(set (match_operand:SI 0 "register_operand" "=r")
8011 (zero_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8012 (match_operand 3 "tld_symbolic_operand" "")]
8014 (match_operand:DI 1 "register_operand" "r")))))]
8015 "TARGET_TLS && TARGET_ARCH64"
8016 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
8017 [(set_attr "type" "load")
8018 (set_attr "us3load_type" "3cycle")])
8020 (define_insn "*tldo_lduh2_sp64"
8021 [(set (match_operand:DI 0 "register_operand" "=r")
8022 (zero_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8023 (match_operand 3 "tld_symbolic_operand" "")]
8025 (match_operand:DI 1 "register_operand" "r")))))]
8026 "TARGET_TLS && TARGET_ARCH64"
8027 "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
8028 [(set_attr "type" "load")
8029 (set_attr "us3load_type" "3cycle")])
8031 (define_insn "*tldo_ldsh1_sp64"
8032 [(set (match_operand:SI 0 "register_operand" "=r")
8033 (sign_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8034 (match_operand 3 "tld_symbolic_operand" "")]
8036 (match_operand:DI 1 "register_operand" "r")))))]
8037 "TARGET_TLS && TARGET_ARCH64"
8038 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
8039 [(set_attr "type" "sload")
8040 (set_attr "us3load_type" "3cycle")])
8042 (define_insn "*tldo_ldsh2_sp64"
8043 [(set (match_operand:DI 0 "register_operand" "=r")
8044 (sign_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8045 (match_operand 3 "tld_symbolic_operand" "")]
8047 (match_operand:DI 1 "register_operand" "r")))))]
8048 "TARGET_TLS && TARGET_ARCH64"
8049 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
8050 [(set_attr "type" "sload")
8051 (set_attr "us3load_type" "3cycle")])
8053 (define_insn "*tldo_lduw_sp32"
8054 [(set (match_operand:SI 0 "register_operand" "=r")
8055 (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8056 (match_operand 3 "tld_symbolic_operand" "")]
8058 (match_operand:SI 1 "register_operand" "r"))))]
8059 "TARGET_TLS && TARGET_ARCH32"
8060 "ld\t[%1 + %2], %0, %%tldo_add(%3)"
8061 [(set_attr "type" "load")])
8063 (define_insn "*tldo_lduw_sp64"
8064 [(set (match_operand:SI 0 "register_operand" "=r")
8065 (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8066 (match_operand 3 "tld_symbolic_operand" "")]
8068 (match_operand:DI 1 "register_operand" "r"))))]
8069 "TARGET_TLS && TARGET_ARCH64"
8070 "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
8071 [(set_attr "type" "load")])
8073 (define_insn "*tldo_lduw1_sp64"
8074 [(set (match_operand:DI 0 "register_operand" "=r")
8075 (zero_extend:DI (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8076 (match_operand 3 "tld_symbolic_operand" "")]
8078 (match_operand:DI 1 "register_operand" "r")))))]
8079 "TARGET_TLS && TARGET_ARCH64"
8080 "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
8081 [(set_attr "type" "load")])
8083 (define_insn "*tldo_ldsw1_sp64"
8084 [(set (match_operand:DI 0 "register_operand" "=r")
8085 (sign_extend:DI (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8086 (match_operand 3 "tld_symbolic_operand" "")]
8088 (match_operand:DI 1 "register_operand" "r")))))]
8089 "TARGET_TLS && TARGET_ARCH64"
8090 "ldsw\t[%1 + %2], %0, %%tldo_add(%3)"
8091 [(set_attr "type" "sload")
8092 (set_attr "us3load_type" "3cycle")])
8094 (define_insn "*tldo_ldx_sp64"
8095 [(set (match_operand:DI 0 "register_operand" "=r")
8096 (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8097 (match_operand 3 "tld_symbolic_operand" "")]
8099 (match_operand:DI 1 "register_operand" "r"))))]
8100 "TARGET_TLS && TARGET_ARCH64"
8101 "ldx\t[%1 + %2], %0, %%tldo_add(%3)"
8102 [(set_attr "type" "load")])
8104 (define_insn "*tldo_stb_sp32"
8105 [(set (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8106 (match_operand 3 "tld_symbolic_operand" "")]
8108 (match_operand:SI 1 "register_operand" "r")))
8109 (match_operand:QI 0 "register_operand" "=r"))]
8110 "TARGET_TLS && TARGET_ARCH32"
8111 "stb\t%0, [%1 + %2], %%tldo_add(%3)"
8112 [(set_attr "type" "store")])
8114 (define_insn "*tldo_stb_sp64"
8115 [(set (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8116 (match_operand 3 "tld_symbolic_operand" "")]
8118 (match_operand:DI 1 "register_operand" "r")))
8119 (match_operand:QI 0 "register_operand" "=r"))]
8120 "TARGET_TLS && TARGET_ARCH64"
8121 "stb\t%0, [%1 + %2], %%tldo_add(%3)"
8122 [(set_attr "type" "store")])
8124 (define_insn "*tldo_sth_sp32"
8125 [(set (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8126 (match_operand 3 "tld_symbolic_operand" "")]
8128 (match_operand:SI 1 "register_operand" "r")))
8129 (match_operand:HI 0 "register_operand" "=r"))]
8130 "TARGET_TLS && TARGET_ARCH32"
8131 "sth\t%0, [%1 + %2], %%tldo_add(%3)"
8132 [(set_attr "type" "store")])
8134 (define_insn "*tldo_sth_sp64"
8135 [(set (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8136 (match_operand 3 "tld_symbolic_operand" "")]
8138 (match_operand:DI 1 "register_operand" "r")))
8139 (match_operand:HI 0 "register_operand" "=r"))]
8140 "TARGET_TLS && TARGET_ARCH64"
8141 "sth\t%0, [%1 + %2], %%tldo_add(%3)"
8142 [(set_attr "type" "store")])
8144 (define_insn "*tldo_stw_sp32"
8145 [(set (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8146 (match_operand 3 "tld_symbolic_operand" "")]
8148 (match_operand:SI 1 "register_operand" "r")))
8149 (match_operand:SI 0 "register_operand" "=r"))]
8150 "TARGET_TLS && TARGET_ARCH32"
8151 "st\t%0, [%1 + %2], %%tldo_add(%3)"
8152 [(set_attr "type" "store")])
8154 (define_insn "*tldo_stw_sp64"
8155 [(set (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8156 (match_operand 3 "tld_symbolic_operand" "")]
8158 (match_operand:DI 1 "register_operand" "r")))
8159 (match_operand:SI 0 "register_operand" "=r"))]
8160 "TARGET_TLS && TARGET_ARCH64"
8161 "stw\t%0, [%1 + %2], %%tldo_add(%3)"
8162 [(set_attr "type" "store")])
8164 (define_insn "*tldo_stx_sp64"
8165 [(set (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8166 (match_operand 3 "tld_symbolic_operand" "")]
8168 (match_operand:DI 1 "register_operand" "r")))
8169 (match_operand:DI 0 "register_operand" "=r"))]
8170 "TARGET_TLS && TARGET_ARCH64"
8171 "stx\t%0, [%1 + %2], %%tldo_add(%3)"
8172 [(set_attr "type" "store")])
8175 ;; Stack protector instructions.
8177 (define_expand "stack_protect_set"
8178 [(match_operand 0 "memory_operand" "")
8179 (match_operand 1 "memory_operand" "")]
8182 #ifdef TARGET_THREAD_SSP_OFFSET
8183 rtx tlsreg = gen_rtx_REG (Pmode, 7);
8184 rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
8185 operands[1] = gen_rtx_MEM (Pmode, addr);
8188 emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
8190 emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
8194 (define_insn "stack_protect_setsi"
8195 [(set (match_operand:SI 0 "memory_operand" "=m")
8196 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
8197 (set (match_scratch:SI 2 "=&r") (const_int 0))]
8199 "ld\t%1, %2\;st\t%2, %0\;mov\t0, %2"
8200 [(set_attr "type" "multi")
8201 (set_attr "length" "3")])
8203 (define_insn "stack_protect_setdi"
8204 [(set (match_operand:DI 0 "memory_operand" "=m")
8205 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
8206 (set (match_scratch:DI 2 "=&r") (const_int 0))]
8208 "ldx\t%1, %2\;stx\t%2, %0\;mov\t0, %2"
8209 [(set_attr "type" "multi")
8210 (set_attr "length" "3")])
8212 (define_expand "stack_protect_test"
8213 [(match_operand 0 "memory_operand" "")
8214 (match_operand 1 "memory_operand" "")
8215 (match_operand 2 "" "")]
8218 #ifdef TARGET_THREAD_SSP_OFFSET
8219 rtx tlsreg = gen_rtx_REG (Pmode, 7);
8220 rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
8221 operands[1] = gen_rtx_MEM (Pmode, addr);
8225 rtx temp = gen_reg_rtx (Pmode);
8226 emit_insn (gen_stack_protect_testdi (temp, operands[0], operands[1]));
8227 sparc_compare_op0 = temp;
8228 sparc_compare_op1 = const0_rtx;
8232 emit_insn (gen_stack_protect_testsi (operands[0], operands[1]));
8233 sparc_compare_op0 = operands[0];
8234 sparc_compare_op1 = operands[1];
8235 sparc_compare_emitted = gen_rtx_REG (CCmode, SPARC_ICC_REG);
8237 emit_jump_insn (gen_beq (operands[2]));
8241 (define_insn "stack_protect_testsi"
8243 (unspec:CC [(match_operand:SI 0 "memory_operand" "m")
8244 (match_operand:SI 1 "memory_operand" "m")]
8246 (set (match_scratch:SI 3 "=r") (const_int 0))
8247 (clobber (match_scratch:SI 2 "=&r"))]
8249 "ld\t%0, %2\;ld\t%1, %3\;xorcc\t%2, %3, %2\;mov\t0, %3"
8250 [(set_attr "type" "multi")
8251 (set_attr "length" "4")])
8253 (define_insn "stack_protect_testdi"
8254 [(set (match_operand:DI 0 "register_operand" "=&r")
8255 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
8256 (match_operand:DI 2 "memory_operand" "m")]
8258 (set (match_scratch:DI 3 "=r") (const_int 0))]
8260 "ldx\t%1, %0\;ldx\t%2, %3\;xor\t%0, %3, %0\;mov\t0, %3"
8261 [(set_attr "type" "multi")
8262 (set_attr "length" "4")])
8265 ;; Vector instructions.
8267 (define_insn "addv2si3"
8268 [(set (match_operand:V2SI 0 "register_operand" "=e")
8269 (plus:V2SI (match_operand:V2SI 1 "register_operand" "e")
8270 (match_operand:V2SI 2 "register_operand" "e")))]
8272 "fpadd32\t%1, %2, %0"
8273 [(set_attr "type" "fga")
8274 (set_attr "fptype" "double")])
8276 (define_insn "addv4hi3"
8277 [(set (match_operand:V4HI 0 "register_operand" "=e")
8278 (plus:V4HI (match_operand:V4HI 1 "register_operand" "e")
8279 (match_operand:V4HI 2 "register_operand" "e")))]
8281 "fpadd16\t%1, %2, %0"
8282 [(set_attr "type" "fga")
8283 (set_attr "fptype" "double")])
8285 ;; fpadd32s is emitted by the addsi3 pattern.
8287 (define_insn "addv2hi3"
8288 [(set (match_operand:V2HI 0 "register_operand" "=f")
8289 (plus:V2HI (match_operand:V2HI 1 "register_operand" "f")
8290 (match_operand:V2HI 2 "register_operand" "f")))]
8292 "fpadd16s\t%1, %2, %0"
8293 [(set_attr "type" "fga")
8294 (set_attr "fptype" "single")])
8296 (define_insn "subv2si3"
8297 [(set (match_operand:V2SI 0 "register_operand" "=e")
8298 (minus:V2SI (match_operand:V2SI 1 "register_operand" "e")
8299 (match_operand:V2SI 2 "register_operand" "e")))]
8301 "fpsub32\t%1, %2, %0"
8302 [(set_attr "type" "fga")
8303 (set_attr "fptype" "double")])
8305 (define_insn "subv4hi3"
8306 [(set (match_operand:V4HI 0 "register_operand" "=e")
8307 (minus:V4HI (match_operand:V4HI 1 "register_operand" "e")
8308 (match_operand:V4HI 2 "register_operand" "e")))]
8310 "fpsub16\t%1, %2, %0"
8311 [(set_attr "type" "fga")
8312 (set_attr "fptype" "double")])
8314 ;; fpsub32s is emitted by the subsi3 pattern.
8316 (define_insn "subv2hi3"
8317 [(set (match_operand:V2HI 0 "register_operand" "=f")
8318 (minus:V2HI (match_operand:V2HI 1 "register_operand" "f")
8319 (match_operand:V2HI 2 "register_operand" "f")))]
8321 "fpsub16s\t%1, %2, %0"
8322 [(set_attr "type" "fga")
8323 (set_attr "fptype" "single")])
8325 ;; All other logical instructions have integer equivalents so they
8326 ;; are defined together.
8328 ;; (ior (not (op1)) (not (op2))) is the canonical form of NAND.
8330 (define_insn "*nand<V64mode>_vis"
8331 [(set (match_operand:V64 0 "register_operand" "=e")
8332 (ior:V64 (not:V64 (match_operand:V64 1 "register_operand" "e"))
8333 (not:V64 (match_operand:V64 2 "register_operand" "e"))))]
8336 [(set_attr "type" "fga")
8337 (set_attr "fptype" "double")])
8339 (define_insn "*nand<V32mode>_vis"
8340 [(set (match_operand:V32 0 "register_operand" "=f")
8341 (ior:V32 (not:V32 (match_operand:V32 1 "register_operand" "f"))
8342 (not:V32 (match_operand:V32 2 "register_operand" "f"))))]
8344 "fnands\t%1, %2, %0"
8345 [(set_attr "type" "fga")
8346 (set_attr "fptype" "single")])
8348 ;; Hard to generate VIS instructions. We have builtins for these.
8350 (define_insn "fpack16_vis"
8351 [(set (match_operand:V4QI 0 "register_operand" "=f")
8352 (unspec:V4QI [(match_operand:V4HI 1 "register_operand" "e")]
8356 [(set_attr "type" "fga")
8357 (set_attr "fptype" "double")])
8359 (define_insn "fpackfix_vis"
8360 [(set (match_operand:V2HI 0 "register_operand" "=f")
8361 (unspec:V2HI [(match_operand:V2SI 1 "register_operand" "e")]
8365 [(set_attr "type" "fga")
8366 (set_attr "fptype" "double")])
8368 (define_insn "fpack32_vis"
8369 [(set (match_operand:V8QI 0 "register_operand" "=e")
8370 (unspec:V8QI [(match_operand:V2SI 1 "register_operand" "e")
8371 (match_operand:V8QI 2 "register_operand" "e")]
8374 "fpack32\t%1, %2, %0"
8375 [(set_attr "type" "fga")
8376 (set_attr "fptype" "double")])
8378 (define_insn "fexpand_vis"
8379 [(set (match_operand:V4HI 0 "register_operand" "=e")
8380 (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")]
8384 [(set_attr "type" "fga")
8385 (set_attr "fptype" "double")])
8387 ;; It may be possible to describe this operation as (1 indexed):
8388 ;; (vec_select (vec_duplicate (vec_duplicate (vec_concat 1 2)))
8389 ;; 1,5,10,14,19,23,28,32)
8390 ;; Note that (vec_merge:V8QI [(V4QI) (V4QI)] (10101010 = 170) doesn't work
8391 ;; because vec_merge expects all the operands to be of the same type.
8392 (define_insn "fpmerge_vis"
8393 [(set (match_operand:V8QI 0 "register_operand" "=e")
8394 (unspec:V8QI [(match_operand:V4QI 1 "register_operand" "f")
8395 (match_operand:V4QI 2 "register_operand" "f")]
8398 "fpmerge\t%1, %2, %0"
8399 [(set_attr "type" "fga")
8400 (set_attr "fptype" "double")])
8402 ;; Partitioned multiply instructions
8403 (define_insn "fmul8x16_vis"
8404 [(set (match_operand:V4HI 0 "register_operand" "=e")
8405 (mult:V4HI (match_operand:V4QI 1 "register_operand" "f")
8406 (match_operand:V4HI 2 "register_operand" "e")))]
8408 "fmul8x16\t%1, %2, %0"
8409 [(set_attr "type" "fpmul")
8410 (set_attr "fptype" "double")])
8412 ;; Only one of the following two insns can be a multiply.
8413 (define_insn "fmul8x16au_vis"
8414 [(set (match_operand:V4HI 0 "register_operand" "=e")
8415 (mult:V4HI (match_operand:V4QI 1 "register_operand" "f")
8416 (match_operand:V2HI 2 "register_operand" "f")))]
8418 "fmul8x16au\t%1, %2, %0"
8419 [(set_attr "type" "fpmul")
8420 (set_attr "fptype" "double")])
8422 (define_insn "fmul8x16al_vis"
8423 [(set (match_operand:V4HI 0 "register_operand" "=e")
8424 (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")
8425 (match_operand:V2HI 2 "register_operand" "f")]
8428 "fmul8x16al\t%1, %2, %0"
8429 [(set_attr "type" "fpmul")
8430 (set_attr "fptype" "double")])
8432 ;; Only one of the following two insns can be a multiply.
8433 (define_insn "fmul8sux16_vis"
8434 [(set (match_operand:V4HI 0 "register_operand" "=e")
8435 (mult:V4HI (match_operand:V8QI 1 "register_operand" "e")
8436 (match_operand:V4HI 2 "register_operand" "e")))]
8438 "fmul8sux16\t%1, %2, %0"
8439 [(set_attr "type" "fpmul")
8440 (set_attr "fptype" "double")])
8442 (define_insn "fmul8ulx16_vis"
8443 [(set (match_operand:V4HI 0 "register_operand" "=e")
8444 (unspec:V4HI [(match_operand:V8QI 1 "register_operand" "e")
8445 (match_operand:V4HI 2 "register_operand" "e")]
8448 "fmul8ulx16\t%1, %2, %0"
8449 [(set_attr "type" "fpmul")
8450 (set_attr "fptype" "double")])
8452 ;; Only one of the following two insns can be a multiply.
8453 (define_insn "fmuld8sux16_vis"
8454 [(set (match_operand:V2SI 0 "register_operand" "=e")
8455 (mult:V2SI (match_operand:V4QI 1 "register_operand" "f")
8456 (match_operand:V2HI 2 "register_operand" "f")))]
8458 "fmuld8sux16\t%1, %2, %0"
8459 [(set_attr "type" "fpmul")
8460 (set_attr "fptype" "double")])
8462 (define_insn "fmuld8ulx16_vis"
8463 [(set (match_operand:V2SI 0 "register_operand" "=e")
8464 (unspec:V2SI [(match_operand:V4QI 1 "register_operand" "f")
8465 (match_operand:V2HI 2 "register_operand" "f")]
8468 "fmuld8ulx16\t%1, %2, %0"
8469 [(set_attr "type" "fpmul")
8470 (set_attr "fptype" "double")])
8472 ;; Using faligndata only makes sense after an alignaddr since the choice of
8473 ;; bytes to take out of each operand is dependent on the results of the last
8475 (define_insn "faligndata<V64I:mode>_vis"
8476 [(set (match_operand:V64I 0 "register_operand" "=e")
8477 (unspec:V64I [(match_operand:V64I 1 "register_operand" "e")
8478 (match_operand:V64I 2 "register_operand" "e")]
8481 "faligndata\t%1, %2, %0"
8482 [(set_attr "type" "fga")
8483 (set_attr "fptype" "double")])
8485 (define_insn "alignaddr<P:mode>_vis"
8486 [(set (match_operand:P 0 "register_operand" "=r")
8487 (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
8488 (match_operand:P 2 "register_or_zero_operand" "rJ")]
8491 "alignaddr\t%r1, %r2, %0")
8493 (define_insn "pdist_vis"
8494 [(set (match_operand:DI 0 "register_operand" "=e")
8495 (unspec:DI [(match_operand:V8QI 1 "register_operand" "e")
8496 (match_operand:V8QI 2 "register_operand" "e")
8497 (match_operand:DI 3 "register_operand" "0")]
8501 [(set_attr "type" "fga")
8502 (set_attr "fptype" "double")])